Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
443 commits
Select commit Hold shift + click to select a range
9c1367c
start fixing fields
rvion Mar 17, 2025
3ec0e81
misc type alias fix
rvion Mar 17, 2025
be96674
misc react 19 ref fixes
rvion Mar 17, 2025
dfc9158
Field_prompt > add `.set()` and `.getSetvalue()`
rvion Mar 17, 2025
d5508a5
misc field cleanups
rvion Mar 17, 2025
05809c3
misc fixes
rvion Mar 17, 2025
498a82d
Node Graph: Add quicker way to deselect for testing
birdddev Mar 17, 2025
d8f26a7
Prompting: Add choice to AST grammar
birdddev Mar 17, 2025
f677a56
Prompting: Add initial Choice grammar/functionality
birdddev Mar 17, 2025
4270a41
Prompting: Choice now supports wildcards, styling changes
birdddev Mar 17, 2025
8b51dc8
UY: Have Layout.Col/Row apply theme roundness by default
birdddev Mar 17, 2025
880ecbf
Panel (Prompting): Add a shelf, add choice selection to shelf
birdddev Mar 17, 2025
fd941eb
misc fixes
rvion Mar 17, 2025
2b0f708
Prompting: Add naming to Choices AST
birdddev Mar 17, 2025
feb4ed3
misc fixes
rvion Mar 17, 2025
34917a3
make sure experimental decorators are off
rvion Mar 17, 2025
9cd73cd
fix import
rvion Mar 17, 2025
d5dbb12
fix icon
rvion Mar 17, 2025
ac2cc01
fix BlenderLikeListUI size (local to widget rather than stored on field)
rvion Mar 17, 2025
5ec2145
Field_board > fix
rvion Mar 17, 2025
f94fd58
Field_list > misc api improvements
rvion Mar 17, 2025
46b6aec
misc fixes
rvion Mar 17, 2025
ec33bcb
Prompting/AST: Add Index to Wildcards. Example `?color[2]`
birdddev Mar 17, 2025
5a28a2d
misc fixes
rvion Mar 17, 2025
aab4c1b
misc locomotive compat
rvion Mar 17, 2025
997bbcb
remove config.ui => config.uiui for now
rvion Mar 17, 2025
d598d06
Prompting: <choice> is now ?> (in-lined wildcards), various tweaks, n…
birdddev Mar 18, 2025
f464373
tsconfig > add "skipDefaultLibCheck": true
rvion Mar 18, 2025
4be3a08
deps > add @types/penner to fix some node_modules internal error
rvion Mar 18, 2025
efc3b35
patch > hacky fix for @uiw/react-json-view typings
rvion Mar 18, 2025
2924858
BoxUIProps > add back `onDoubleClick`
rvion Mar 18, 2025
2f11d27
Field_list > `.duplicateItemAtIndex(ix)` now returns the added item
rvion Mar 18, 2025
9aec880
FieldConfig > fix variance by forcing covariance via type hack
rvion Mar 18, 2025
9da64f9
fix > fix ShapeSchema type so it can be used as setValue for board f…
rvion Mar 18, 2025
a11ee5e
fix > add missing import
rvion Mar 18, 2025
5128777
ShellMobile > remove code tied to legacy field config that have been …
rvion Mar 18, 2025
97eb913
SimpleReactNode > exclude string to allow for type level litteral as …
rvion Mar 18, 2025
3a42b8c
SimpleReactComponent > make them covariant via type hack (sad)
rvion Mar 18, 2025
f621b85
comment out WidgetButtonUI
rvion Mar 18, 2025
96357a3
misc > convert some `interface merging` to `declare` within class ins…
rvion Mar 18, 2025
9a487b6
patch pixi having wrong typings using `~/` instead of relative paths
rvion Mar 18, 2025
89cabf7
Field_button > add shims that mimmic previous api since its removal
rvion Mar 18, 2025
2a4ef18
patch vite typings
rvion Mar 18, 2025
c1b4f1c
Field_choice > add back temporarilly `tab2` appearance
rvion Mar 18, 2025
8e7ed12
JSON > fix JSON type by adding null as possible value
rvion Mar 18, 2025
0d483a4
misc Board fix
rvion Mar 18, 2025
0a07c90
react 19 > fix refs now requiring null in type param
rvion Mar 18, 2025
79bf868
CSchema fix
rvion Mar 18, 2025
5f8c588
Field_group > make summary covariant (hack)
rvion Mar 18, 2025
91bb76f
Field > remove legacy `build: 'new'`
rvion Mar 18, 2025
3b2bcec
misc
rvion Mar 18, 2025
b2dfe09
bump electron
rvion Mar 18, 2025
8f92c23
bump mobx
rvion Mar 18, 2025
1f0fa9a
Color Picker: Fix bug in oklch string that caused --KLR to break. Whi…
birdddev Mar 19, 2025
06528ab
Prompting: Minor cleanup for inlined wildcards
birdddev Mar 19, 2025
9b23ba4
fix for useDefineForClassFields
rvion Mar 19, 2025
16c96ca
remove `declare`
rvion Mar 19, 2025
21d22bc
icons > convert aliases to real JSON syntax to fix JSON.parse crash
rvion Mar 19, 2025
dba381f
remove more declare
rvion Mar 19, 2025
444733e
tsconfig: target: ES2023 + useDefineForClassFields": true
rvion Mar 19, 2025
f954437
setup IKONS properly at startup
rvion Mar 19, 2025
d613dad
misc
rvion Mar 19, 2025
f7a4e85
useDefineForClassFields > misc fixes
rvion Mar 19, 2025
bb9f8ad
remove more declare
rvion Mar 19, 2025
8ade5a2
pixi.js patch > prevent console.error overriding
rvion Mar 19, 2025
7b58531
backport > add _once decorator
rvion Mar 19, 2025
f847179
vite.config > update babel-plugin-decorator from `2023-05` to `2023-11`
rvion Mar 19, 2025
8f901cc
Field_size > make aspect_ratio work when fields are unset
rvion Mar 19, 2025
3964a72
fix > galleryConf now use value_unchecked to support unset fields
rvion Mar 19, 2025
d2bc729
field > recover from empty object given as serial
rvion Mar 19, 2025
12132fb
eslint > attempt to prevent non-action global eventListener
rvion Mar 19, 2025
383c815
add a few missing runInAction
rvion Mar 19, 2025
3037dcb
updater > desperate attempt to fix the git indicator
rvion Mar 19, 2025
f272eef
PanelOutputUI > cleanup
rvion Mar 19, 2025
cd7e03d
models > start adding back various mobx annotations since we remove m…
rvion Mar 19, 2025
771879c
add catalog entry + rule for enum field
rvion Mar 19, 2025
1558989
field_number > make uncheck_value be number | null, not string
rvion Mar 19, 2025
3bd30dc
fix observable issue
rvion Mar 19, 2025
983b083
add more ui rules
rvion Mar 19, 2025
5113962
add more stable simple functions
rvion Mar 19, 2025
72178a6
selectors > add `:has` and `:not`
rvion Mar 19, 2025
8a964b0
field > avoid saving serial multiple times (one per root child) when …
rvion Mar 19, 2025
ea7a5ff
fix related to useDefineForClassFields
rvion Mar 19, 2025
4181482
namespace Z > add Field aliases
rvion Mar 19, 2025
f009b45
misc
rvion Mar 19, 2025
afae6b0
backport > schema builder properly jumpable with f2
rvion Mar 21, 2025
360e00f
Field > add fast hash to field "value" (uid based on memory ptr of se…
rvion Mar 21, 2025
ddb19e1
better selectors
rvion Mar 21, 2025
95586e0
fix tests
rvion Mar 21, 2025
405d159
fix all tests
rvion Mar 21, 2025
d39e8e2
fix > do not generate error on startup due to `cushy` beeing accessed…
rvion Mar 21, 2025
967dcb2
selectors > simplify implementation (just change iteration order and …
rvion Mar 22, 2025
8b61700
graph UI > add a badly needed `@action` to fix the multiple sequentia…
rvion Mar 22, 2025
0867c04
DI > make it possible to extends fields without having to import them
rvion Mar 22, 2025
ec09821
library > cleanup
rvion Mar 22, 2025
f89346f
react > fix key error
rvion Mar 22, 2025
751bbc2
fix a few types
rvion Mar 22, 2025
5c11154
catalog > register more widgets in catalog
rvion Mar 22, 2025
f9752da
chore > misc cleanup
rvion Mar 22, 2025
d1a0bf0
blenderList > basic fix + support both horizontal + vertical mode
rvion Mar 22, 2025
31fc33b
draft > debounce saving (finally, lol)
rvion Mar 22, 2025
9eccb6e
Renderer > massive overhaul
rvion Mar 22, 2025
3c63560
Renderer > add `Before` and `After` slots
rvion Mar 22, 2025
3d62ed2
CushyScript > misc cleanup
rvion Mar 22, 2025
e767250
✨ remove Field_link
rvion Mar 22, 2025
77a5bdb
misc fixes
rvion Mar 22, 2025
ce3533e
✨ UI > polish API + add `config` to shell algebra
rvion Mar 22, 2025
8822434
Prompting: Fix overflows
birdddev Mar 22, 2025
8cecf2c
Prompting: Clean up
birdddev Mar 22, 2025
1aa7910
Prompting: Make nested choices appear nested-ly
birdddev Mar 22, 2025
0804bf9
Codemirror: (Poorly) Allow auto-complete within Prompt_String
birdddev Mar 22, 2025
2628890
Revert "Codemirror: (Poorly) Allow auto-complete within Prompt_String"
birdddev Mar 22, 2025
943565c
Prompting: Add syntax error ui in shelf
birdddev Mar 22, 2025
73638d5
misc
rvion Mar 22, 2025
d9682fe
misc shortcuts
rvion Mar 22, 2025
b392559
Prompting: Make nested choices easier to distinguish
birdddev Mar 22, 2025
2ba9a4d
UI > drastically simplify UI system
rvion Mar 22, 2025
e8dfd11
uiui works
rvion Mar 23, 2025
c8790b4
remove some `🔴test` lying around somewhere
rvion Mar 23, 2025
2c508d3
UI > it's happening, it's becoming functional and good and pleasant t…
rvion Mar 23, 2025
c887776
selector > add `*` (noop, but makes expressions clearer)
rvion Mar 23, 2025
e9ca5c1
remove builder tupple alias
rvion Mar 23, 2025
f9d1444
selector mixin > better matches impl
rvion Mar 23, 2025
20e5f4c
fixup
rvion Mar 23, 2025
816f921
fix all remaining type error + plug app UI properly
rvion Mar 24, 2025
100e464
prefab_latent > fix uiui config
rvion Mar 25, 2025
942966e
CSchema > "fix" `defaultSerial` by beeing a big less agressive on the…
rvion Mar 25, 2025
7ffa2ef
BuilderString > fix `uuidV4`, fix `nanoid`, and add more `uuidV...` …
rvion Mar 25, 2025
231732a
Field_UUID > add validation
rvion Mar 25, 2025
3279147
selector > fix index selector in `match` mode
rvion Mar 25, 2025
181a284
FieldConfig > add `tags` property (similar to html classes; handy wit…
rvion Mar 25, 2025
4f13fba
selectors: add `&` (nesting), `%<tag>` (hasTag), `#<uid>` (hasId)
rvion Mar 25, 2025
a1f4735
catalog > big cleanup and reorg
rvion Mar 25, 2025
a4f7279
simple is not easy; but simple is beautiful
rvion Mar 26, 2025
dff3243
csuite > add various missing @computed related to `hasChanges`
rvion Mar 26, 2025
cf5fb24
uiui: make strings regular string again
rvion Mar 26, 2025
3b9410d
backport > eslint rules
rvion Mar 26, 2025
6f337b1
reveal > backport changes
rvion Mar 26, 2025
e9117cc
select > backport changes + tweaks
rvion Mar 26, 2025
821f79e
SelectUI > split component
rvion Mar 26, 2025
8a3e77c
booruloader > minor tweak / cleanup
rvion Mar 26, 2025
e15f903
replace a few `writeFileSync` by `writeFileAsync`
rvion Mar 26, 2025
92ec614
minor cleanup
rvion Mar 26, 2025
8a161d2
fixup SelectUI
rvion Mar 26, 2025
d2ed97f
🔥 observer => obs
rvion Mar 26, 2025
103c94b
misc
rvion Mar 26, 2025
d37283b
🤪 insanity ?
rvion Mar 27, 2025
11ee223
app: pass field as 4th param (temporary)
rvion Mar 27, 2025
90d9638
eslint > fix boolean checks (missing `!= null`)
rvion Mar 27, 2025
691f631
🤪
rvion Mar 27, 2025
9929047
misc
rvion Mar 27, 2025
7eeb31c
🤪
rvion Mar 27, 2025
4ca755d
Field: remove various pub/sub -related proxies to schema methods
rvion Mar 27, 2025
856c5a9
🤪
rvion Mar 27, 2025
40c31ae
touch fixup
rvion Mar 27, 2025
a1d5721
🤪
rvion Mar 27, 2025
5051c6d
misc
rvion Mar 27, 2025
3aed74b
just trying to help
rvion Mar 27, 2025
bdde9d1
big cleanup
rvion Apr 2, 2025
f2aaa41
allow tests to run with the new global `obs()`
rvion Apr 2, 2025
0842627
eslint warnings
rvion Apr 2, 2025
b90f7b3
selector > minor cleanup
rvion Apr 2, 2025
1aa5b06
remove now useless `, null` when using custom classes
rvion Apr 2, 2025
a72e06b
cleanup
rvion Apr 2, 2025
468acd5
update upfront diffing script
rvion Apr 2, 2025
29b87b6
misc
rvion Apr 2, 2025
39705a6
FieldString > minor observability fix
rvion Apr 2, 2025
d9bee9c
FString > minor cleanup
rvion Apr 2, 2025
21767c8
remove declare
rvion Apr 2, 2025
d5c30ce
Widget string tweaks
rvion Apr 2, 2025
b943835
toasts > improve capabilities
rvion Apr 2, 2025
3a149ba
better schema traversals
rvion Apr 2, 2025
4c75ffa
rawInts
rvion Apr 2, 2025
6aab761
builder DI
rvion Apr 2, 2025
5734900
isLeafSchema
rvion Apr 2, 2025
d9997e9
better traversals
rvion Apr 2, 2025
6c12595
reveal improvements
rvion Apr 2, 2025
e377da5
field Date fix
rvion Apr 2, 2025
d040044
FString.clear()
rvion Apr 2, 2025
05e2455
MarkdownUI > accept extra markdown props
rvion Apr 2, 2025
53c39f4
useObservableRef > make deps mandatory
rvion Apr 2, 2025
46963c3
rawInt fixup
rvion Apr 2, 2025
044cdb9
reveal > add 'screen-cover' placement
rvion Apr 2, 2025
d600c81
reveal > react to window resize
rvion Apr 2, 2025
52416dc
toasts
rvion Apr 2, 2025
ba5f2f3
group > stabler set
rvion Apr 2, 2025
d9dedcb
cleanup
rvion Apr 2, 2025
64ea81c
remove last utf8 char
rvion Apr 2, 2025
f8814c0
remove useless `[]` around fields properties
rvion Apr 2, 2025
71de2f5
:: => z$
rvion Apr 2, 2025
0b907ca
fix completion order
rvion Apr 2, 2025
5fab8d3
fix wrong underscore
rvion Apr 2, 2025
2606bf5
misc
rvion Apr 5, 2025
45b6ed6
field: setup reactions
rvion Apr 5, 2025
1027b36
stabler/simpler lists
rvion Apr 5, 2025
8801d1b
work on FieldIds
rvion Apr 5, 2025
36496e2
less crash with FieldList
rvion Apr 5, 2025
f2ce06f
better GenerateSerial
rvion Apr 5, 2025
827ad02
fixup
rvion Apr 5, 2025
e5c6c78
remove legacy FieldCustom
rvion Apr 5, 2025
3f2a3fa
misc backports
rvion Apr 5, 2025
8b25268
FieldSelectMany set value
rvion Apr 5, 2025
4c9fe6c
remove useless @since
rvion Apr 5, 2025
87ff478
misc
rvion Apr 5, 2025
aeab195
misc backport / cleanup
rvion Apr 5, 2025
a7e32cb
cleanups
rvion Apr 5, 2025
4d7cbe1
remove transaction tower
rvion Apr 5, 2025
9bcd507
fixup
rvion Apr 5, 2025
88ca2d7
misc stuff
rvion Apr 5, 2025
da24089
misc
rvion Apr 5, 2025
21062d1
minor cleanup
rvion Apr 5, 2025
75c7d1e
misc
rvion Apr 5, 2025
e3f493a
remove valueOrFail
rvion Apr 5, 2025
c188418
fixup
rvion Apr 5, 2025
b420e63
lol - make bun have experimental support for decorators though weird …
rvion Apr 5, 2025
b39a2ee
bump most packages
rvion Apr 5, 2025
3c5f556
run `npm audit fix`
rvion Apr 5, 2025
b2eef93
bump patch
rvion Apr 5, 2025
7e3fbd2
MERGE bird_d's work
rvion Apr 5, 2025
12be5d9
csuite UI > stop using `AnimatedSizeUI` in shells
rvion Apr 6, 2025
0464907
fixup
rvion Apr 6, 2025
4819586
jsx-dev-runtime > remove my shitty magic '🔘' injection code
rvion Apr 6, 2025
9d9cb41
minor rename
rvion Apr 6, 2025
5c2901e
tweak WidgetListBody
rvion Apr 6, 2025
29f8107
wip keybindings
rvion Apr 6, 2025
f9b4b88
fix remaining type errors
rvion Apr 6, 2025
eaecef8
bun stuff
rvion Apr 7, 2025
d5c87c1
selectors: support quoted mount key
rvion Apr 7, 2025
4c8c8be
misc
rvion Apr 10, 2025
c9352c9
better get/set values
rvion Apr 10, 2025
c3a207b
misc fixes
rvion Apr 11, 2025
c2f3b14
make cushy run again
rvion Apr 12, 2025
977cde3
minor rename
rvion Apr 12, 2025
3ee1472
BlenderList > selected child should grow
rvion Apr 12, 2025
14cca69
BlenderList > show "no title" when no text
rvion Apr 12, 2025
5b214af
field: add zPathNice that render list items with indexes
rvion Apr 12, 2025
d938cb2
BlenderList > minimum size for items
rvion Apr 12, 2025
f22466d
PanelIcon rename
rvion Apr 16, 2025
aeafae6
csuite > field select many > add a few methods
rvion Apr 16, 2025
903d421
minor cleanups
rvion Apr 16, 2025
0c569c1
reveal > all programmatic access without refs via global store of laz…
rvion Apr 16, 2025
fc585e2
fix react key error
rvion Apr 16, 2025
a5d244c
RENDERER
rvion Apr 20, 2025
7ac7f14
misc
rvion Apr 20, 2025
64b8132
match shapes
rvion Apr 21, 2025
242f81e
hacky-fix for app not reloading
rvion Apr 22, 2025
fb3b633
misc
rvion Apr 24, 2025
cc0cb1d
misc
rvion Apr 24, 2025
f902abe
misc
rvion Apr 24, 2025
6bf3367
misc
rvion Apr 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ outputs/*

# keep .schema folder
schema/globa.d.ts

schema/hosts/*
!schema/hosts/virtual-base
!schema/hosts/virtual-full
!schema/hosts/standard
!schema/hosts/standard/.gitkeep
!schema/hosts/.gitkeep

cushy.db
cushy*.db
Expand Down Expand Up @@ -106,3 +110,6 @@ eslint.config.debug.json

autotype.summary.txt
src/theme/twin.css

bunPlugin.cache
bunPlugin.reload.ts
9 changes: 8 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ src/manager/model-list/KnownModel_Name.ts
src/manager/model-list/KnownModel_SavePath.ts
src/manager/model-list/KnownModel_Type.ts

src/FlexLayout/
src/FlexLayout/*
src/FlexLayout/**/*

# files generated by lezer (npm run gen-lezer)
src/prompt/grammar/grammar.parser.terms.ts
src/prompt/grammar/grammar.parser.ts


# files code-generated
# schema/global.d.ts
# schema/global.d.ts

# import order matters here
src/setup.ts
6 changes: 3 additions & 3 deletions .vscode/misc.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"scope": "typescript",
"prefix": "tst",
"body": [
"import { describe, expect, it } from 'bun:test'",
"import { describe, expect, it } from 'vitest'",
"",
"describe('$1', () => {",
" it('${2:work}', () => {",
Expand All @@ -16,7 +16,7 @@
"create new observable react component": {
"scope": "typescriptreact",
"prefix": "ocomp",
"body": ["export const $1UI = observer(function $1UI_(p: { $2 }){", "return (<div>", "$3", "</div>)", "})"],
"body": ["export const $1UI = obs(function $1UI_(p: { $2 }){", "return (<div>", "$3", "</div>)", "})"],
"description": "scaffold a new React functional component"
},
"app": {
Expand All @@ -41,7 +41,7 @@
"create new observable react component with st": {
"scope": "typescriptreact",
"prefix": "ocompst",
"body": ["export const $1UI = observer(function $1UI_(p: { $2 }){", "return (<div>", "$3", "</div>)", "})"],
"body": ["export const $1UI = obs(function $1UI_(p: { $2 }){", "return (<div>", "$3", "</div>)", "})"],
"description": "scaffold a new React functional component"
},
"uist": {
Expand Down
11 changes: 6 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@

"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.svn": false,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/Thumbs.db": true
"**/Thumbs.db": true,
"**/CVS": true
},

"pasteImage.path": "site/assets",
Expand Down Expand Up @@ -97,8 +97,9 @@
// minimap
"editor.minimap.maxColumn": 60,
"editor.minimap.scale": 2,
"editor.minimap.sectionHeaderFontSize": 13
// "typescript.tsserver.nodePath": ".cushy/node/v20.14.0-darwin-arm64/bin/node",
"editor.minimap.sectionHeaderFontSize": 13,
"explorerExclude.backup": {}
// "typescript.tsserver.nodePath": ".cushy/node/v22.14.0-darwin-arm64/bin/node",
// "editor.inlayHints.enabled": "off"
// "editor.semanticHighlighting.enabled": false,

Expand Down
4 changes: 3 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
SHORT TERM TODO:

☐ need to build a tree of all selectors
☐ Shell Fluid.
☐ give you a way to have multiple built-in perspectives
☐ add a stop run button in the steps panel
☐ paths: switche to / instead of .
Expand Down Expand Up @@ -40,7 +42,7 @@ SHORT TERM TODO:
✔ we need to fork select once forall; @done(24-12-10 23:12)
✔ I don't want to add those p-input-2, ... classes @done(24-12-10 23:12)
✔ need other name in 20241115_144643_gggdomi_d6cd16e_rename-configtostring @done(24-12-10 23:12)
✔ toString => ❌toString_, but 🟢 toSummary?, toText?, ... @done(24-12-10 23:12)
✔ toString => ❌toString_, but 🟢 toString_?, toText?, ... @done(24-12-10 23:12)
✔ .... @done(24-12-10 23:12)
✔ skip: 20241128_000225_gggdomi_d6cfc25_choice-widget-via-type-subfield @done(24-12-10 23:12)

Expand Down
4 changes: 2 additions & 2 deletions _mac-linux-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Exec=/usr/bin/bash -c 'cd \"$SCRIPTPATH\" && \"$SCRIPTPATH/_mac-linux-start-dev.
esac
echo "Node.js architecture: $NODE_ARCH"

NODE_VERSION="v20.14.0"
NODE_VERSION="v22.14.0"
echo "Node.js version: $NODE_VERSION"

# Define the download URL ------------------------------------------------------------
Expand Down Expand Up @@ -147,7 +147,7 @@ echo "Node binary path: $NODE_BIN_PATH"

# Install dependencies with npm
echo "Installing dependencies..."
$NPM_BIN_PATH install --legacy-peer-deps=false
$NPM_BIN_PATH install --legacy-peer-deps=false --force

# ensuring binary dependencies are correctly linked across installed
./node_modules/.bin/electron-builder install-app-deps
Expand Down
2 changes: 1 addition & 1 deletion _windows-install.bat
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ echo [===================================================]
echo Ensuring Node version...

rem --------------------------------------------------------------------------------
set "NODE_VERSION=v20.14.0"
set "NODE_VERSION=v22.14.0"
set "NODE_ARCH=win-x64"
set "CWD=%CD%"
set "EXTRACT_DIR=%CWD%\.cushy\node\%NODE_VERSION%-%NODE_ARCH%"
Expand Down
2 changes: 1 addition & 1 deletion _windows-start-dev.bat
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set "errorlevel="
set "CUSHY_RUN_MODE=dev"

rem --------------------------------------------------------------------------------
set "NODE_VERSION=v20.14.0"
set "NODE_VERSION=v22.14.0"
set "NODE_ARCH=win-x64"
set "CWD=%CD%"
set "EXTRACT_DIR=%CWD%\.cushy\node\%NODE_VERSION%-%NODE_ARCH%"
Expand Down
2 changes: 1 addition & 1 deletion _windows-start.bat
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set "errorlevel="
set "CUSHY_RUN_MODE=dist"

rem --------------------------------------------------------------------------------
set "NODE_VERSION=v20.14.0"
set "NODE_VERSION=v22.14.0"
set "NODE_ARCH=win-x64"
set "CWD=%CD%"
set "EXTRACT_DIR=%CWD%\.cushy\node\%NODE_VERSION%-%NODE_ARCH%"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ You may probably want to wrap them in `observer` wrapper:
```tsx
import { observer } from "mobx-react-lite";

export const IconUI = observer(function IconUI_(p: { icon: string }): JSX.Element {
export const IconUI = obs(function IconUI_(p: { icon: string }): React.JSX.Element {
return (
<span>
{p.icon}
Expand All @@ -38,7 +38,7 @@ Why ?
```tsx
import {IconUI} from './IconUI'

const ExpensiveComponent = observer(function ExpensiveComponent() {
const ExpensiveComponent = obs(function ExpensiveComponent() {
const store = useStore()
return (
<div>
Expand Down
166 changes: 166 additions & 0 deletions bunPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// @ts-nocheck
import './src/setup'

// todo: add back @bun/types later when bun types do not conflict with node types
import * as babel from '@babel/core'
import { plugin } from 'bun'
import chalk from 'chalk'
import fs from 'fs'
import debounce from 'lodash/debounce'

// 0. minor setup
let totalTimeSpentTranspiling = 0
const RELOAD_HACK_FILENAME = 'bunPlugin.reload.ts'

const startSetup = Date.now()
const log = (str: string): void => console.log(chalk.dim(`[bun] ${str}`))
log(`evaluating plugin module`)

plugin({
name: 'typescript-with-native-decorators',
setup(build): void {
// 1. watch files manually since --watch is broken when using bun plugin 🥲
const folderToWatch = import.meta.dir + '/src/'
log(`manually watching ${folderToWatch}`)
const watchFileSet = new Set<string | null>()
fs.watch(folderToWatch, { recursive: true }, (event, filename) => {
const needestart = watchFileSet.has(filename)
log(`file ${filename} changed (in set: ${watchFileSet.has(filename)})`) // ${[...watchFileSet.values()]}
if (needestart) void Bun.file(`./${RELOAD_HACK_FILENAME}`).write(`// '${Math.random()})\n`)
})

// 2. change how .ts and .tsx files are loaded
log(`setup took ${Date.now() - startSetup}ms`)

const filter = /\.(ts|tsx)$/
build.onLoad({ filter }, async (args): Promise<{ loader: 'js'; contents: string }> => {
try {
watchFileSet.add(args.path.replace(folderToWatch, ''))
const codeTs = await Bun.file(args.path).text()
const startTranspiling = performance.now()
let codeJS = await transpileFile(args.path, codeTs)

const relPathXX = '../'.repeat(args.path.replace(folderToWatch, '').split('/').length)
// console.log(`[🤠] `, folderToWatch)
// console.log(`[🤠] `, args.path)
// console.log(`[🤠] `, relPathXX)
// 3. inject a dependency on a file that do NOT go though the plugin
if (!args.path.endsWith('bunPlugin.reload.ts'))
if (!codeJS.startsWith(`import '${RELOAD_HACK_FILENAME}'`))
codeJS = `import '${relPathXX}${RELOAD_HACK_FILENAME}'\n${codeJS}`

totalTimeSpentTranspiling += performance.now() - startTranspiling
addToCache(codeTs, codeJS)
return { loader: 'js', contents: codeJS }
} catch (e) {
console.log(`[🔴] `, e)
return { contents: '', loader: 'js' }
}
})
},
})

// 4. cache system
const oldCache: Map<string, string> = (await Bun.file('./bunPlugin.cache').exists())
? new Map(JSON.parse((await Bun.file('./bunPlugin.cache').text()) || '[]'))
: new Map()

const cache = new Map<string, string>()
log(`restoring module with ${oldCache.size} entries`)

export const getFromCache = (content: string): string | undefined => {
if (cache.has(content)) return cache.get(content)
if (oldCache.has(content)) {
const value = oldCache.get(content)
if (value) cache.set(content, value)
return value
}
return
}
const saveCacheImpl = debounce(() => {
log(`saving cache with ${cache.size} entries (spent ${totalTimeSpentTranspiling.toFixed(2)}ms transpiling)`) // prettier-ignore
void Bun.file('./bunPlugin.cache').write(JSON.stringify([...cache.entries()]))
}, 50)

export const addToCache = (codeTS: string, codeJS: string): void => {
cache.set(codeTS, codeJS)
saveCacheImpl()
}

const MODE: 'babel' | 'esbuild' | 'typescript' = 'babel'

async function transpileFile(name: string, codeTs: string): Promise<string> {
// 1. try to return the cached version
const cache = getFromCache(codeTs)
if (cache) return cache

// or transpile a new
const codeJs = await transpileFileForReal(name, codeTs)
addToCache(codeTs, codeJs)
return codeJs
}

async function transpileFileForReal(name: string, codeTS: string): Promise<string> {
if (MODE === 'babel') return transpileFileWithBabel(name, codeTS)
if (MODE === 'esbuild') return transpileFileWithEsbuild(name, codeTS)
if (MODE === 'typescript') return transpileFileWithTypescript(name, codeTS)
throw new Error(`MODE ${MODE} is ont supported`)
}

// alt 1. babel -------------------------------------------------------------------------
async function transpileFileWithBabel(name: string, codeTS: string): Promise<string> {
const res = await babel.transformAsync(codeTS, {
filename: name,
plugins: [
['@babel/plugin-proposal-decorators', { version: '2023-05' }],
'@babel/plugin-syntax-import-attributes',
],
presets: [
['@babel/preset-typescript', { allowDeclareFields: true }],
['@babel/preset-react', { runtime: 'automatic' }],
],
})
const codeJS = res?.code ?? ''
return name.endsWith('.test.ts') || name.endsWith('.test.tsx')
? autoConvertVitestToBunTest(codeJS)
: codeJS
}

// alt 2. esbuild ------------------------------------------------------------------------
async function transpileFileWithEsbuild(name: string, file: string): Promise<string> {
const esbuild = (await import('esbuild')).default
const result = await esbuild.transform(file, {
loader: 'ts',
target: 'chrome110',
})
return result.code
}

// alt 3. esbuild ------------------------------------------------------------------------
async function transpileFileWithTypescript(name: string, file: string): Promise<string> {
const typescript = (await import('typescript')).default
const codeJS = typescript.transpileModule(file, {
compilerOptions: {
module: typescript.ModuleKind.ESNext,
target: typescript.ScriptTarget.ESNext,
jsx: typescript.JsxEmit.React,
decorators: true,
importAttributes: true,
},
})
return codeJS.outputText
}

// bonus for those who use vitest --------------------------------------------------------
function autoConvertVitestToBunTest(finalCode_: string): string {
return (
finalCode_
.replaceAll(`from 'vitest'`, `from 'bun:test'`)
.replaceAll('vitest.spyOn', `require('bun:test').spyOn`)
.replaceAll('vitest.mock', `require('bun:test').mock`)
.replaceAll('vi.spyOn', `require('bun:test').spyOn`)
.replaceAll('vi.mock', `require('bun:test').mock`)
// https://bun.sh/docs/test/mocks#restore-all-function-mocks-to-their-original-values-with-mock-restore
.replaceAll('vitest.restoreAllMocks()', `require('bun:test').mock.restore()`)
)
}
3 changes: 3 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
preload = ["./bunPlugin.ts"]
[test]
preload = ["./bunPlugin.ts"]
10 changes: 10 additions & 0 deletions docs/going-further/contribution/render.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@


Every selector step should be cacheable / mergeable.

```tsx
<doc.Foo.UI.Header />
```


#
4 changes: 2 additions & 2 deletions docs/going-further/creating-apps/prefabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ export type UI_Mask = X.XChoice<{
// and add explit return type to your function
// VVVVV
export function ui_mask(): UI_Mask {
const form: Builder = getCurrentForm()
const form: Builder = getBuilder()
return form.choice({
appearance: 'tab',
icon: 'mdiDominoMask',
icon: IKONS.mdiDominoMask,
label: 'Mask',
default: 'noMask',
// box: { base: { hue: 20, chroma: 0.03 } },
Expand Down
Loading