steel-frame 7.0.1 → 7.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/babel-plugin/css-transformer.js +4 -1
- package/package.json +4 -3
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -7
- package/.idea/steel-frame.iml +0 -13
- package/.idea/vcs.xml +0 -6
- package/.prettierignore +0 -1
- package/.prettierrc +0 -21
- package/StartUp.md +0 -526
- package/coverage/lcov-report/abort.ts.html +0 -580
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/call.ts.html +0 -829
- package/coverage/lcov-report/css-transformer.ts.html +0 -1180
- package/coverage/lcov-report/expression.ts.html +0 -2347
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/field-reference.ts.html +0 -550
- package/coverage/lcov-report/index.html +0 -356
- package/coverage/lcov-report/index.ts.html +0 -286
- package/coverage/lcov-report/internal.ts.html +0 -946
- package/coverage/lcov-report/jsx-detect.ts.html +0 -127
- package/coverage/lcov-report/jsx.ts.html +0 -3550
- package/coverage/lcov-report/lib.ts.html +0 -1381
- package/coverage/lcov-report/mesh.ts.html +0 -5860
- package/coverage/lcov-report/operators.ts.html +0 -322
- package/coverage/lcov-report/order-check.ts.html +0 -805
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/process-types.ts.html +0 -475
- package/coverage/lcov-report/router.ts.html +0 -292
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov-report/transformer.ts.html +0 -1951
- package/coverage/lcov-report/utils.ts.html +0 -139
- package/coverage/lcov.info +0 -5285
- package/jest.config.js +0 -23
- package/src/babel-plugin/abort.ts +0 -165
- package/src/babel-plugin/call.ts +0 -248
- package/src/babel-plugin/communication.ts +0 -13
- package/src/babel-plugin/css-transformer.ts +0 -365
- package/src/babel-plugin/expression.ts +0 -754
- package/src/babel-plugin/field-reference.ts +0 -155
- package/src/babel-plugin/index.ts +0 -67
- package/src/babel-plugin/internal.ts +0 -287
- package/src/babel-plugin/jsx-detect.ts +0 -14
- package/src/babel-plugin/jsx.ts +0 -1155
- package/src/babel-plugin/lib.ts +0 -432
- package/src/babel-plugin/mesh.ts +0 -1925
- package/src/babel-plugin/operators.ts +0 -79
- package/src/babel-plugin/order-check.ts +0 -240
- package/src/babel-plugin/process-types.ts +0 -130
- package/src/babel-plugin/router.ts +0 -69
- package/src/babel-plugin/transformer.ts +0 -622
- package/src/babel-plugin/utils.ts +0 -18
- package/src/cli/app-index/create-index.ts +0 -28
- package/src/cli/app-index/create-ssg-index.ts +0 -23
- package/src/cli/app-index/find-routes.ts +0 -63
- package/src/cli/lib/compile-lib.ts +0 -169
- package/src/cli/lib/fs.ts +0 -17
- package/src/cli/lib/process-args.ts +0 -99
- package/src/cli/lib/resolve.ts +0 -22
- package/src/cli/lib/watch-folder.ts +0 -22
- package/src/cli/lib/working-dirs.ts +0 -10
- package/src/cli/node-hooks/index.doc.vasille.js +0 -6
- package/src/cli/node-hooks/index.md.vasille.js +0 -6
- package/src/cli/node-hooks/index.vasille.js +0 -30
- package/src/cli/node-hooks/jsx.vasille.js +0 -80
- package/src/cli/proxy/dev-proxy.ts +0 -30
- package/src/cli/run.ts +0 -230
- package/src/cli/sf.ts +0 -2
- package/src/cli/vite-plugins/compress.ts +0 -16
- package/src/cli/vite-plugins/index.vasille.ts +0 -54
- package/src/cli/vite-plugins/jsx.ts +0 -33
- package/src/cli/vite-plugins/vasille-web.ts +0 -18
- package/src/export/index.ts +0 -483
- package/src/export/jsx-runtime.ts +0 -1
- package/test/bridge/array-item-set.js +0 -3
- package/test/bridge/array-item-set.ts +0 -4
- package/test/bridge/bind.js +0 -8
- package/test/bridge/bind.ts +0 -9
- package/test/bridge/bridge.test.ts +0 -74
- package/test/bridge/err-before-mount-arg.ts +0 -6
- package/test/bridge/err-bind-in-object.ts +0 -10
- package/test/bridge/err-field-renaming-2.ts +0 -5
- package/test/bridge/err-field-renaming.ts +0 -7
- package/test/bridge/err-non-reactive-module-var.ts +0 -1
- package/test/bridge/err-prop-not-reactive.ts +0 -3
- package/test/bridge/err-raw-no-args.ts +0 -4
- package/test/bridge/err-router-in-store-1.ts +0 -7
- package/test/bridge/err-router-in-store-2.ts +0 -9
- package/test/bridge/err-router-in-store-3.ts +0 -12
- package/test/bridge/err-router.ts +0 -5
- package/test/bridge/global-import.js +0 -13
- package/test/bridge/global-import.ts +0 -16
- package/test/bridge/module-level-reactivity.js +0 -11
- package/test/bridge/module-level-reactivity.ts +0 -18
- package/test/bridge/object-property-match.js +0 -5
- package/test/bridge/object-property-match.ts +0 -6
- package/test/bridge/router.js +0 -13
- package/test/bridge/router.ts +0 -17
- package/test/build/build.test.ts +0 -22
- package/test/build/ssg-no-extra-tags.js +0 -4
- package/test/build/ssg-no-extra-tags.tsx +0 -9
- package/test/build/ssg.js +0 -14
- package/test/build/ssg.tsx +0 -9
- package/test/call/call.test.ts +0 -26
- package/test/call/constant.js +0 -7
- package/test/call/constant.ts +0 -7
- package/test/call/css.js +0 -7
- package/test/call/css.ts +0 -11
- package/test/call/err-awaited-not-arr.ts +0 -5
- package/test/call/require-context.js +0 -9
- package/test/call/require-context.ts +0 -13
- package/test/call/string-literal.js +0 -7
- package/test/call/string-literal.ts +0 -6
- package/test/compose/component.js +0 -19
- package/test/compose/component.ts +0 -22
- package/test/compose/compose.js +0 -18
- package/test/compose/compose.test.ts +0 -38
- package/test/compose/compose.ts +0 -21
- package/test/compose/modal.js +0 -9
- package/test/compose/modal.ts +0 -13
- package/test/compose/model.js +0 -22
- package/test/compose/model.ts +0 -21
- package/test/compose/prompt.js +0 -20
- package/test/compose/prompt.ts +0 -25
- package/test/compose/screen.js +0 -15
- package/test/compose/screen.ts +0 -13
- package/test/compose/store.js +0 -8
- package/test/compose/store.ts +0 -9
- package/test/compose/view.js +0 -34
- package/test/compose/view.ts +0 -39
- package/test/css/autoremove-key.js +0 -11
- package/test/css/autoremove-key.tsx +0 -12
- package/test/css/computed-key.js +0 -9
- package/test/css/computed-key.ts +0 -12
- package/test/css/css.test.ts +0 -82
- package/test/css/err-arg-not-object.ts +0 -4
- package/test/css/err-arg-wrong-key.ts +0 -6
- package/test/css/err-arg-wrong-object.ts +0 -6
- package/test/css/err-arg-wrong-value.ts +0 -10
- package/test/css/err-array-spread-element.ts +0 -11
- package/test/css/err-incompatible-key.ts +0 -13
- package/test/css/err-media-not-object.ts +0 -12
- package/test/css/err-nested-media-queries.ts +0 -13
- package/test/css/err-nested-pseudos.ts +0 -13
- package/test/css/err-no-args.ts +0 -4
- package/test/css/err-object-method.ts +0 -11
- package/test/css/err-object-spread-element.ts +0 -12
- package/test/css/err-pseudo-not-object.ts +0 -12
- package/test/css/err-theme-not-string.ts +0 -11
- package/test/css/err-wrong-array-value.ts +0 -12
- package/test/css/err-wrong-value.ts +0 -12
- package/test/css/style.js +0 -13
- package/test/css/style.ts +0 -61
- package/test/dev/array-model.js +0 -5
- package/test/dev/array-model.ts +0 -5
- package/test/dev/awaited-2.js +0 -7
- package/test/dev/awaited-2.ts +0 -7
- package/test/dev/awaited.js +0 -7
- package/test/dev/awaited.ts +0 -7
- package/test/dev/bind-2.js +0 -6
- package/test/dev/bind-2.ts +0 -6
- package/test/dev/bind.js +0 -6
- package/test/dev/bind.ts +0 -6
- package/test/dev/calculate.js +0 -8
- package/test/dev/calculate.ts +0 -8
- package/test/dev/child.js +0 -16
- package/test/dev/child.tsx +0 -11
- package/test/dev/component.js +0 -5
- package/test/dev/component.ts +0 -5
- package/test/dev/custom-model.js +0 -6
- package/test/dev/custom-model.ts +0 -7
- package/test/dev/dev.test.ts +0 -106
- package/test/dev/ensure.js +0 -9
- package/test/dev/ensure.ts +0 -7
- package/test/dev/function-wrap.js +0 -59
- package/test/dev/function-wrap.ts +0 -43
- package/test/dev/map-model.js +0 -5
- package/test/dev/map-model.ts +0 -5
- package/test/dev/match.js +0 -11
- package/test/dev/module-level-reactivity.js +0 -6
- package/test/dev/module-level-reactivity.ts +0 -7
- package/test/dev/object.js +0 -8
- package/test/dev/object.ts +0 -8
- package/test/dev/page.js +0 -5
- package/test/dev/page.ts +0 -5
- package/test/dev/prompt.js +0 -13
- package/test/dev/prompt.tsx +0 -7
- package/test/dev/ref-no-args.js +0 -5
- package/test/dev/ref-no-args.ts +0 -5
- package/test/dev/ref.js +0 -5
- package/test/dev/ref.ts +0 -5
- package/test/dev/safe.js +0 -36
- package/test/dev/safe.tsx +0 -19
- package/test/dev/set-model.js +0 -5
- package/test/dev/set-model.ts +0 -5
- package/test/dev/set-value.js +0 -8
- package/test/dev/set-value.ts +0 -9
- package/test/dev/tag.js +0 -7
- package/test/dev/tag.tsx +0 -5
- package/test/dev/text-2.js +0 -6
- package/test/dev/text-2.tsx +0 -7
- package/test/dev/text.js +0 -5
- package/test/dev/text.tsx +0 -5
- package/test/dev/value-assignment.js +0 -30
- package/test/dev/value-assignment.ts +0 -24
- package/test/expression/check-expression.js +0 -58
- package/test/expression/check-expression.ts +0 -58
- package/test/expression/check-node.js +0 -12
- package/test/expression/check-node.ts +0 -10
- package/test/expression/check-statement.js +0 -45
- package/test/expression/check-statement.ts +0 -55
- package/test/expression/deep-reactive-object.js +0 -15
- package/test/expression/deep-reactive-object.ts +0 -16
- package/test/expression/dependency.js +0 -7
- package/test/expression/dependency.ts +0 -9
- package/test/expression/err-function-name.ts +0 -11
- package/test/expression/err-jsx-element.tsx +0 -9
- package/test/expression/err-jsx-fragment.tsx +0 -9
- package/test/expression/err-local-observable.ts +0 -12
- package/test/expression/err-nested-observable-in-object.ts +0 -6
- package/test/expression/err-nested-observable.ts +0 -11
- package/test/expression/err-nested-reactivity-2.ts +0 -7
- package/test/expression/err-nested-reactivity.ts +0 -11
- package/test/expression/err-restricted-hint.ts +0 -9
- package/test/expression/expression.test.ts +0 -74
- package/test/expression/mesh-lvalue.js +0 -21
- package/test/expression/mesh-lvalue.ts +0 -22
- package/test/expression/reactive-field-set.js +0 -23
- package/test/expression/reactive-field-set.ts +0 -28
- package/test/expression/stringify.js +0 -15
- package/test/expression/stringify.ts +0 -17
- package/test/extras/SlotTest.js +0 -75
- package/test/extras/SlotTest.tsx +0 -65
- package/test/extras/calculate.js +0 -25
- package/test/extras/calculate.tsx +0 -22
- package/test/extras/err.tsx +0 -23
- package/test/extras/extras.test.ts +0 -68
- package/test/extras/function-assigment-pattern.js +0 -15
- package/test/extras/function-assigment-pattern.ts +0 -11
- package/test/extras/set-model.js +0 -29
- package/test/extras/set-model.tsx +0 -26
- package/test/import/err-override-by-fn-expr.ts +0 -10
- package/test/import/global.js +0 -7
- package/test/import/global.ts +0 -6
- package/test/import/import.test.ts +0 -34
- package/test/import/override-by-function.js +0 -9
- package/test/import/override-by-function.ts +0 -10
- package/test/import/override-by-let.js +0 -6
- package/test/import/override-by-let.ts +0 -8
- package/test/import/override-global.js +0 -9
- package/test/import/override-global.ts +0 -10
- package/test/import/selective.js +0 -7
- package/test/import/selective.ts +0 -6
- package/test/jsx/attr.js +0 -13
- package/test/jsx/attr.tsx +0 -8
- package/test/jsx/bind.js +0 -41
- package/test/jsx/bind.tsx +0 -15
- package/test/jsx/callback.js +0 -9
- package/test/jsx/callback.tsx +0 -11
- package/test/jsx/children.js +0 -11
- package/test/jsx/children.tsx +0 -11
- package/test/jsx/class.js +0 -50
- package/test/jsx/class.tsx +0 -21
- package/test/jsx/conditional-binary.js +0 -16
- package/test/jsx/conditional-binary.tsx +0 -10
- package/test/jsx/conditional-mixed.js +0 -40
- package/test/jsx/conditional-mixed.tsx +0 -19
- package/test/jsx/conditional-ternary.js +0 -18
- package/test/jsx/conditional-ternary.tsx +0 -10
- package/test/jsx/conditions.js +0 -80
- package/test/jsx/conditions.tsx +0 -40
- package/test/jsx/default-prop.js +0 -8
- package/test/jsx/default-prop.tsx +0 -7
- package/test/jsx/err-conditions-else-if.tsx +0 -5
- package/test/jsx/err-conditions-else.tsx +0 -5
- package/test/jsx/err-conditions-spread.tsx +0 -5
- package/test/jsx/err-expected-event-handler.tsx +0 -6
- package/test/jsx/err-method-style-object.tsx +0 -6
- package/test/jsx/err-namespace-props.tsx +0 -10
- package/test/jsx/err-namespaced-name.tsx +0 -6
- package/test/jsx/err-spread-child.tsx +0 -5
- package/test/jsx/err-tag-spread-attr.tsx +0 -5
- package/test/jsx/err-wrong-namespace.tsx +0 -6
- package/test/jsx/events.js +0 -16
- package/test/jsx/events.tsx +0 -17
- package/test/jsx/fragment.js +0 -9
- package/test/jsx/fragment.tsx +0 -15
- package/test/jsx/jsx.test.ts +0 -120
- package/test/jsx/loop.js +0 -19
- package/test/jsx/loop.tsx +0 -21
- package/test/jsx/nested-slots.js +0 -39
- package/test/jsx/nested-slots.tsx +0 -36
- package/test/jsx/nested.js +0 -42
- package/test/jsx/nested.tsx +0 -35
- package/test/jsx/style.js +0 -36
- package/test/jsx/style.tsx +0 -20
- package/test/jsx-detect/has-jsx.js +0 -30
- package/test/jsx-detect/has-jsx.tsx +0 -26
- package/test/jsx-detect/jsx-detect.test.ts +0 -14
- package/test/jsx-detect/release-mode.js +0 -14
- package/test/jsx-detect/release-mode.tsx +0 -18
- package/test/lib/FileStructure.js +0 -7
- package/test/lib/FileStructure.ts +0 -21
- package/test/lib/err-arg-not-func.ts +0 -6
- package/test/lib/err-file-structure-class.ts +0 -11
- package/test/lib/err-file-structure-helper-before-export.ts +0 -5
- package/test/lib/err-file-structure-import-after.ts +0 -5
- package/test/lib/err-file-structure-stylesheet-not-last.ts +0 -7
- package/test/lib/err-incorrect-args-number.ts +0 -6
- package/test/lib/err-incorrect-props-number.ts +0 -8
- package/test/lib/err-malformed-component.ts +0 -7
- package/test/lib/lib.test.ts +0 -42
- package/test/mesh/class.js +0 -48
- package/test/mesh/class.ts +0 -55
- package/test/mesh/compose.js +0 -51
- package/test/mesh/compose.tsx +0 -35
- package/test/mesh/default-class.js +0 -8
- package/test/mesh/default-class.ts +0 -10
- package/test/mesh/default-expr.js +0 -2
- package/test/mesh/default-expr.ts +0 -3
- package/test/mesh/default-fn.js +0 -4
- package/test/mesh/default-fn.ts +0 -5
- package/test/mesh/double-mesh-bug.js +0 -17
- package/test/mesh/double-mesh-bug.tsx +0 -17
- package/test/mesh/err-array-model-const.ts +0 -5
- package/test/mesh/err-calculate-call.ts +0 -6
- package/test/mesh/err-class-name-expression.ts +0 -1
- package/test/mesh/err-class-name.ts +0 -1
- package/test/mesh/err-compose-arg-number.tsx +0 -13
- package/test/mesh/err-compose-nested-destruction.ts +0 -13
- package/test/mesh/err-computed-property-in-destruction.ts +0 -7
- package/test/mesh/err-function-name.ts +0 -3
- package/test/mesh/err-invalid-compose-call.ts +0 -4
- package/test/mesh/err-jsx-element.tsx +0 -5
- package/test/mesh/err-jsx-fragment.tsx +0 -5
- package/test/mesh/err-map-model-const.ts +0 -5
- package/test/mesh/err-param-name-destruction.ts +0 -1
- package/test/mesh/err-param-name-rest.ts +0 -1
- package/test/mesh/err-param-name-with-default-value.ts +0 -1
- package/test/mesh/err-param-name.ts +0 -1
- package/test/mesh/err-prompt.ts +0 -5
- package/test/mesh/err-run-on-destroy.ts +0 -9
- package/test/mesh/err-set-model-const.ts +0 -5
- package/test/mesh/err-store-jsx.tsx +0 -7
- package/test/mesh/err-store-not-reactive-value-2.ts +0 -11
- package/test/mesh/err-store-not-reactive-value.ts +0 -11
- package/test/mesh/err-store-reactive-value.ts +0 -7
- package/test/mesh/err-store-share-dependency.ts +0 -6
- package/test/mesh/err-style-hint.ts +0 -4
- package/test/mesh/mesh-expression.js +0 -56
- package/test/mesh/mesh-expression.ts +0 -57
- package/test/mesh/mesh-statement.js +0 -46
- package/test/mesh/mesh-statement.ts +0 -61
- package/test/mesh/mesh.test.ts +0 -170
- package/test/mesh/object-computed-property.js +0 -11
- package/test/mesh/object-computed-property.ts +0 -10
- package/test/mesh/object-read-property.js +0 -12
- package/test/mesh/object-read-property.ts +0 -15
- package/test/mesh/object-reference.js +0 -11
- package/test/mesh/object-reference.ts +0 -13
- package/test/mesh/reactive-field-copy.js +0 -14
- package/test/mesh/reactive-field-copy.ts +0 -24
- package/test/mesh/reactive-field-set.js +0 -15
- package/test/mesh/reactive-field-set.ts +0 -19
- package/test/mesh/reactive-object.js +0 -39
- package/test/mesh/reactive-object.tsx +0 -38
- package/test/mesh/run-on-destroy.js +0 -6
- package/test/mesh/run-on-destroy.ts +0 -7
- package/test/mesh/store.js +0 -79
- package/test/mesh/store.tsx +0 -83
- package/test/naming/err-component-not-uppercase.ts +0 -3
- package/test/naming/err-components-folder.ts +0 -3
- package/test/naming/err-export.ts +0 -3
- package/test/naming/err-modal-missing-suffix.ts +0 -3
- package/test/naming/err-modal-not-uppercase.ts +0 -3
- package/test/naming/err-modals-folder.ts +0 -3
- package/test/naming/err-model-missing-suffix.ts +0 -3
- package/test/naming/err-model-not-lowercase.ts +0 -3
- package/test/naming/err-models-folder.ts +0 -3
- package/test/naming/err-page.ts +0 -3
- package/test/naming/err-prompt-missing-prefix.ts +0 -3
- package/test/naming/err-prompts-folder.ts +0 -3
- package/test/naming/err-screen-missing-suffix.ts +0 -3
- package/test/naming/err-screens-folder.ts +0 -3
- package/test/naming/err-store-missing-suffix.ts +0 -3
- package/test/naming/err-store-not-lowercase.ts +0 -3
- package/test/naming/err-stores-folder.ts +0 -3
- package/test/naming/err-view-missing-suffix.ts +0 -3
- package/test/naming/err-view-not-uppercase.ts +0 -3
- package/test/naming/err-views-folder.ts +0 -3
- package/test/naming/naming.test.ts +0 -130
- package/test/pages/(dynamical).js +0 -6
- package/test/pages/(dynamical).tsx +0 -5
- package/test/pages/err-static.ts +0 -3
- package/test/pages/page/(number).js +0 -6
- package/test/pages/page/(number).tsx +0 -5
- package/test/pages/page/list.js +0 -4
- package/test/pages/page/list.tsx +0 -5
- package/test/pages/pages.test.ts +0 -26
- package/test/pages/static.js +0 -4
- package/test/pages/static.tsx +0 -5
- package/test/reference/awaited.js +0 -6
- package/test/reference/awaited.ts +0 -8
- package/test/reference/const.js +0 -4
- package/test/reference/const.ts +0 -5
- package/test/reference/expr-const-optional.js +0 -8
- package/test/reference/expr-const-optional.ts +0 -10
- package/test/reference/expr-const.js +0 -7
- package/test/reference/expr-const.ts +0 -9
- package/test/reference/expr-let.js +0 -10
- package/test/reference/expr-let.ts +0 -13
- package/test/reference/expr-meta.js +0 -15
- package/test/reference/expr-meta.ts +0 -17
- package/test/reference/let-update.js +0 -9
- package/test/reference/let-update.ts +0 -11
- package/test/reference/let.js +0 -5
- package/test/reference/let.ts +0 -6
- package/test/reference/local-reactive.js +0 -11
- package/test/reference/local-reactive.ts +0 -6
- package/test/reference/models.js +0 -24
- package/test/reference/models.ts +0 -27
- package/test/reference/reference.test.ts +0 -50
- package/test/reference/watch.js +0 -9
- package/test/reference/watch.ts +0 -11
- package/test/run-test.ts +0 -65
- package/test/shadow/Error.tsx +0 -3
- package/test/shadow/InterfaceTest.js +0 -4
- package/test/shadow/InterfaceTest.ts +0 -7
- package/test/shadow/LocalComponent.js +0 -38
- package/test/shadow/LocalComponent.tsx +0 -27
- package/test/shadow/MissingGlyph.tsx +0 -5
- package/test/shadow/MissingType.tsx +0 -4
- package/test/shadow/NoType.tsx +0 -3
- package/test/shadow/ParameterTest.js +0 -4
- package/test/shadow/ParameterTest.ts +0 -7
- package/test/shadow/PropsTest.js +0 -11
- package/test/shadow/PropsTest.ts +0 -13
- package/test/shadow/SlotTest.js +0 -44
- package/test/shadow/SlotTest.tsx +0 -22
- package/test/shadow/TypeTest.js +0 -4
- package/test/shadow/TypeTest.ts +0 -7
- package/test/shadow/UnionTest.js +0 -11
- package/test/shadow/UnionTest.ts +0 -14
- package/test/shadow/shadow.test.ts +0 -59
- package/test/transformer/no-import.js +0 -3
- package/test/transformer/no-import.ts +0 -3
- package/test/transformer/transformer.test.ts +0 -18
- package/test/transformer/web-global.js +0 -4
- package/test/transformer/web-global.ts +0 -5
- package/test/transformer/web-partial.js +0 -7
- package/test/transformer/web-partial.ts +0 -11
- package/test/tsconfig.json +0 -21
- package/test/tsconfig.tsbuildinfo +0 -1
- package/test/v5/array-index.js +0 -11
- package/test/v5/array-index.ts +0 -12
- package/test/v5/assign-operator.js +0 -11
- package/test/v5/assign-operator.ts +0 -18
- package/test/v5/context.js +0 -16
- package/test/v5/context.ts +0 -14
- package/test/v5/di.js +0 -10
- package/test/v5/di.tsx +0 -5
- package/test/v5/err-di-discover.ts +0 -6
- package/test/v5/err-receive-in-wrapper.ts +0 -5
- package/test/v5/spaces-in-jsx.js +0 -22
- package/test/v5/spaces-in-jsx.tsx +0 -14
- package/test/v5/v5.test.ts +0 -49
- package/test/v6/err-foreach-no-slot.tsx +0 -6
- package/test/v6/err-iterate-params-number.tsx +0 -5
- package/test/v6/err-model-view-no-slot.tsx +0 -6
- package/test/v6/err-reactive-destruction.tsx +0 -6
- package/test/v6/err-too-much-params.tsx +0 -6
- package/test/v6/if-test.js +0 -20
- package/test/v6/if-test.tsx +0 -14
- package/test/v6/iterate-destructure.js +0 -22
- package/test/v6/iterate-destructure.tsx +0 -20
- package/test/v6/iterate-map.js +0 -9
- package/test/v6/iterate-map.tsx +0 -12
- package/test/v6/iterate.js +0 -15
- package/test/v6/iterate.tsx +0 -19
- package/test/v6/model-view.js +0 -40
- package/test/v6/model-view.tsx +0 -46
- package/test/v6/v6.test.ts +0 -51
- package/test/v7/DependencyReexport.js +0 -2
- package/test/v7/DependencyReexport.tsx +0 -2
- package/test/v7/DependencyStart.js +0 -6
- package/test/v7/DependencyStart.tsx +0 -7
- package/test/v7/Hmr.js +0 -16
- package/test/v7/Hmr.ts +0 -8
- package/test/v7/abort-signal.js +0 -15
- package/test/v7/abort-signal.tsx +0 -15
- package/test/v7/array-model-map.js +0 -16
- package/test/v7/array-model-map.tsx +0 -11
- package/test/v7/async-composing.js +0 -8
- package/test/v7/async-composing.tsx +0 -11
- package/test/v7/auto-safe.js +0 -40
- package/test/v7/auto-safe.tsx +0 -24
- package/test/v7/await-with-dependency.js +0 -14
- package/test/v7/await-with-dependency.ts +0 -13
- package/test/v7/bypass-write-restriction.js +0 -8
- package/test/v7/bypass-write-restriction.ts +0 -10
- package/test/v7/callback.js +0 -27
- package/test/v7/callback.tsx +0 -30
- package/test/v7/debounce-dev.js +0 -8
- package/test/v7/debounce-dev.ts +0 -6
- package/test/v7/debounce.js +0 -5
- package/test/v7/debounce.ts +0 -6
- package/test/v7/declared-function.js +0 -11
- package/test/v7/declared-function.ts +0 -11
- package/test/v7/discard-awaited.js +0 -59
- package/test/v7/discard-awaited.ts +0 -60
- package/test/v7/discard-less-awaited.js +0 -45
- package/test/v7/discard-less-awaited.ts +0 -58
- package/test/v7/err-array-model-map.tsx +0 -11
- package/test/v7/err-autounwrap.tsx +0 -7
- package/test/v7/err-bypass-to-readonly.ts +0 -10
- package/test/v7/err-computed-property.ts +0 -6
- package/test/v7/err-debounce-wrong-args.ts +0 -5
- package/test/v7/err-declared-function-calculate.ts +0 -9
- package/test/v7/err-declared-function-call.ts +0 -12
- package/test/v7/err-declared-function-effect.ts +0 -14
- package/test/v7/err-declared-function.ts +0 -9
- package/test/v7/err-dependency-reexport-check.tsx +0 -6
- package/test/v7/err-destruction-extracts-reactive.ts +0 -7
- package/test/v7/err-destruction-missing-renaming.ts +0 -6
- package/test/v7/err-destruction-of-slot-props.tsx +0 -7
- package/test/v7/err-expr-has-double-breakpoint.ts +0 -7
- package/test/v7/err-field-ref-double-breakpoint.ts +0 -7
- package/test/v7/err-field-ref-has-double-breakpoint.ts +0 -7
- package/test/v7/err-field-ref-no-arg.ts +0 -5
- package/test/v7/err-field-ref-no-breakpoint.ts +0 -6
- package/test/v7/err-field-ref-v7-naming.tsx +0 -13
- package/test/v7/err-field-ref-with-private-name.ts +0 -11
- package/test/v7/err-function-expr-in-live-declaration.ts +0 -8
- package/test/v7/err-function-expr-in-state-declaration.ts +0 -8
- package/test/v7/err-function-expr-in-var-declaration.ts +0 -8
- package/test/v7/err-local-dependency-flow.tsx +0 -16
- package/test/v7/err-no-deps-in-effect.ts +0 -7
- package/test/v7/err-page-with-global-dependency.tsx +0 -8
- package/test/v7/err-reactivity-break-2.ts +0 -9
- package/test/v7/err-reactivity-break.ts +0 -10
- package/test/v7/err-rest-in-internal-slot.tsx +0 -7
- package/test/v7/err-rest-in-reactive-destruction.ts +0 -6
- package/test/v7/err-rest-in-ref.ts +0 -6
- package/test/v7/err-restricted-member-access.ts +0 -8
- package/test/v7/err-restricted-ref-in-object-2.ts +0 -6
- package/test/v7/err-restricted-ref-in-object.ts +0 -7
- package/test/v7/err-router-go-to.ts +0 -8
- package/test/v7/err-router-load.ts +0 -8
- package/test/v7/err-safe-init-no-args.ts +0 -6
- package/test/v7/err-static-live-value.ts +0 -5
- package/test/v7/err-wrong-path-in-jsx.tsx +0 -18
- package/test/v7/field-ref-v7-naming.js +0 -35
- package/test/v7/field-ref-v7-naming.tsx +0 -27
- package/test/v7/field-ref.js +0 -31
- package/test/v7/field-ref.tsx +0 -26
- package/test/v7/let-with-function-expression.js +0 -6
- package/test/v7/let-with-function-expression.ts +0 -7
- package/test/v7/object-destruction.js +0 -10
- package/test/v7/object-destruction.tsx +0 -8
- package/test/v7/provide-global-dependency.js +0 -4
- package/test/v7/provide-global-dependency.tsx +0 -5
- package/test/v7/router-path-in-jsx.js +0 -18
- package/test/v7/router-path-in-jsx.tsx +0 -18
- package/test/v7/router.js +0 -22
- package/test/v7/router.ts +0 -25
- package/test/v7/safe.js +0 -32
- package/test/v7/safe.tsx +0 -26
- package/test/v7/string-event.js +0 -9
- package/test/v7/string-event.tsx +0 -6
- package/test/v7/v7.test.ts +0 -326
- package/test/v7-new-naming/err-assign-to-readonly.ts +0 -7
- package/test/v7-new-naming/err-constructor-reactivity-missmatch.ts +0 -14
- package/test/v7-new-naming/err-let-debounced.ts +0 -6
- package/test/v7-new-naming/err-reactive-field-in-obj.ts +0 -12
- package/test/v7-new-naming/err-reactive-writable-in-obj.ts +0 -7
- package/test/v7-new-naming/err-readonly-explicit-ref.ts +0 -5
- package/test/v7-new-naming/err-readonly-field.ts +0 -6
- package/test/v7-new-naming/err-readonly-ref.ts +0 -5
- package/test/v7-new-naming/err-readonly-to-writable-prop.ts +0 -12
- package/test/v7-new-naming/err-readonly-to-writable-prop.tsx +0 -10
- package/test/v7-new-naming/err-writable-debounced.ts +0 -6
- package/test/v7-new-naming/err-writable-explicit-expr.ts +0 -6
- package/test/v7-new-naming/err-writable-expr.ts +0 -6
- package/test/v7-new-naming/naming.js +0 -26
- package/test/v7-new-naming/naming.tsx +0 -27
- package/test/v7-new-naming/v7-new-naming.test.ts +0 -70
- package/tsconfig.json +0 -19
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -2,6 +2,7 @@ import * as t from "@babel/types";
|
|
|
2
2
|
import { calledFn, calls, styleOnly } from "./call.js";
|
|
3
3
|
import { err, Errors } from "./lib.js";
|
|
4
4
|
import { stringify } from "./utils.js";
|
|
5
|
+
import { nodeToStaticPosition } from "./transformer.js";
|
|
5
6
|
const pureNumbersProperties = new Set([
|
|
6
7
|
"opacity",
|
|
7
8
|
"flex",
|
|
@@ -249,7 +250,9 @@ export function findStyleInNode(path, internal) {
|
|
|
249
250
|
}
|
|
250
251
|
}
|
|
251
252
|
}
|
|
252
|
-
valuePath.replaceWith(
|
|
253
|
+
valuePath.replaceWith(internal.devLayer
|
|
254
|
+
? t.arrayExpression([t.arrayExpression(expressions), nodeToStaticPosition(path.node)])
|
|
255
|
+
: t.arrayExpression(expressions));
|
|
253
256
|
}
|
|
254
257
|
return true;
|
|
255
258
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "steel-frame",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.3",
|
|
4
4
|
"description": "SteelFrame: Build Fault-Tolerant Web Applications Effortlessly.",
|
|
5
5
|
"main": "build/cli/run.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -55,17 +55,18 @@
|
|
|
55
55
|
},
|
|
56
56
|
"homepage": "https://github.com/vasille-js/steel-frame#readme",
|
|
57
57
|
"dependencies": {
|
|
58
|
+
"@babel/plugin-syntax-jsx": "^7.29.7",
|
|
59
|
+
"@babel/plugin-transform-typescript": "^7.29.9",
|
|
58
60
|
"@inquirer/select": "^5.2.6",
|
|
59
61
|
"csstype": "^3.1.3",
|
|
60
62
|
"esbuild": "^0.28.2",
|
|
61
|
-
"vasille-web": "7.0.
|
|
63
|
+
"vasille-web": "7.0.1",
|
|
62
64
|
"vite": "^8.3.4",
|
|
63
65
|
"vite-plugin-babel": "^1.7.3",
|
|
64
66
|
"vite-plugin-inspect": "^12.1.0",
|
|
65
67
|
"ws": "^8.22.0"
|
|
66
68
|
},
|
|
67
69
|
"devDependencies": {
|
|
68
|
-
"@babel/plugin-transform-typescript": "^7.29.9",
|
|
69
70
|
"@types/jest": "^30.0.0",
|
|
70
71
|
"@types/node": "^24.3.0",
|
|
71
72
|
"@types/web": "^0.0.256",
|
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/steel-frame.iml" filepath="$PROJECT_DIR$/.idea/steel-frame.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
package/.idea/prettier.xml
DELETED
package/.idea/steel-frame.iml
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="WEB_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager">
|
|
4
|
-
<content url="file://$MODULE_DIR$">
|
|
5
|
-
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
|
6
|
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
8
|
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
9
|
-
</content>
|
|
10
|
-
<orderEntry type="inheritedJdk" />
|
|
11
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
12
|
-
</component>
|
|
13
|
-
</module>
|
package/.idea/vcs.xml
DELETED
package/.prettierignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
test/**/*.js
|
package/.prettierrc
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"tabWidth": 4,
|
|
3
|
-
"printWidth": 120,
|
|
4
|
-
"useTabs": false,
|
|
5
|
-
"semi": true,
|
|
6
|
-
"singleQuote": false,
|
|
7
|
-
"jsxSingleQuote": false,
|
|
8
|
-
"trailingComma": "all",
|
|
9
|
-
"bracketSpacing": true,
|
|
10
|
-
"bracketSameLine": true,
|
|
11
|
-
"arrowParens": "avoid",
|
|
12
|
-
"overrides": [
|
|
13
|
-
{
|
|
14
|
-
"files": ["*.mts", "*.cts", "*.ts"],
|
|
15
|
-
"options": {
|
|
16
|
-
"parser": "typescript"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
],
|
|
20
|
-
"singleAttributePerLine": false
|
|
21
|
-
}
|
package/StartUp.md
DELETED
|
@@ -1,526 +0,0 @@
|
|
|
1
|
-
# Getting Started with Steel Frame
|
|
2
|
-
|
|
3
|
-
`SteelFrameKit` is a front-end development kit designed to build **fault-tolerant web applications**. Code is compiled by a Babel plugin: your components are plain functions with JSX, and reactivity is expressed through variable naming conventions — no hooks, no virtual DOM, no asynchronous rendering.
|
|
4
|
-
|
|
5
|
-
## Table of Content
|
|
6
|
-
|
|
7
|
-
- [Create a Project](#create-a-project)
|
|
8
|
-
- [CLI Commands](#cli-commands)
|
|
9
|
-
- [Project Structure](#project-structure)
|
|
10
|
-
- [Your First Component](#your-first-component)
|
|
11
|
-
- [Reactivity](#reactivity)
|
|
12
|
-
- [Conditional Rendering](#conditional-rendering)
|
|
13
|
-
- [Loops](#loops)
|
|
14
|
-
- [Components, Props & Slots](#components-props--slots)
|
|
15
|
-
- [Pages & Routing](#pages--routing)
|
|
16
|
-
- [Screens (SPA only)](#screens-spa-only)
|
|
17
|
-
- [Models & Stores](#models--stores)
|
|
18
|
-
- [Modals & Prompts](#modals--prompts)
|
|
19
|
-
- [Styling](#styling)
|
|
20
|
-
- [Lifecycle & Effects](#lifecycle--effects)
|
|
21
|
-
- [Dependency Injection](#dependency-injection)
|
|
22
|
-
- [Fault Tolerance Helpers](#fault-tolerance-helpers)
|
|
23
|
-
|
|
24
|
-
## Create a Project
|
|
25
|
-
|
|
26
|
-
The fastest way to start is the official project generator:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm create steel-frame
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
It scaffolds a starting project with everything configured. Then:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
cd my-app
|
|
36
|
-
npm install
|
|
37
|
-
npx web dev
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
If you add Steel Frame to an existing project manually:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
npm install steel-frame --save
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
And configure `tsconfig.json` to use the Steel Frame JSX runtime:
|
|
47
|
-
|
|
48
|
-
```json
|
|
49
|
-
{
|
|
50
|
-
"compilerOptions": {
|
|
51
|
-
"jsx": "preserve",
|
|
52
|
-
"jsxImportSource": "steel-frame",
|
|
53
|
-
"module": "Node16",
|
|
54
|
-
"moduleResolution": "node16",
|
|
55
|
-
"strictNullChecks": true,
|
|
56
|
-
"lib": ["ES2024", "DOM"]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## CLI Commands
|
|
62
|
-
|
|
63
|
-
Steel Frame ships a CLI binary named `web`. Running `npx web` without arguments opens an interactive menu.
|
|
64
|
-
|
|
65
|
-
| Command | Description |
|
|
66
|
-
| ---------------------- | --------------------------------------------------------------- |
|
|
67
|
-
| `web dev` | Start a hot-reload development server (Vite based) |
|
|
68
|
-
| `web dev+lib` | Development server for a component library |
|
|
69
|
-
| `web build spa` | Build a Single Page Application with the built-in router |
|
|
70
|
-
| `web build html` | Build a static HTML site (SSG) |
|
|
71
|
-
| `web build md` | Build a static Markdown site (LLM dedicated) |
|
|
72
|
-
| `web build md+html` | Build documentation for git (Markdown with inline HTML) |
|
|
73
|
-
| `web build lib` | Build a component library usable in SPA or SSG |
|
|
74
|
-
| `web build components` | Build a web components library usable in any frontend framework |
|
|
75
|
-
|
|
76
|
-
Build output goes to `dist/` (`dist/spa`, `dist/html`, `dist/md`, `dist/lib`, `dist/components`).
|
|
77
|
-
|
|
78
|
-
## Project Structure
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
my-app/
|
|
82
|
-
├── src/
|
|
83
|
-
│ ├── pages/ # file-based routes (universal: SPA, SSG, planned SSR)
|
|
84
|
-
│ │ ├── index.tsx # route "/"
|
|
85
|
-
│ │ ├── about.tsx # route "/about"
|
|
86
|
-
│ │ └── (id).tsx # dynamic route "/:id"
|
|
87
|
-
│ ├── router/ # optional router customization
|
|
88
|
-
│ │ ├── fallbackScreen.tsx
|
|
89
|
-
│ │ ├── errorScreen.tsx
|
|
90
|
-
│ │ ├── loadingScreen.tsx
|
|
91
|
-
│ │ └── loadingOverlay.tsx
|
|
92
|
-
│ ├── components/ # components (name: UpperCase)
|
|
93
|
-
│ ├── views/ # views (name: UpperCase + `View` suffix)
|
|
94
|
-
│ ├── screens/ # screens (name: `Screen` suffix, SPA only)
|
|
95
|
-
│ ├── modals/ # modals (name: UpperCase + `Modal` suffix)
|
|
96
|
-
│ ├── prompts/ # prompts (name: `prompt` prefix)
|
|
97
|
-
│ ├── models/ # models (name: lowercase + `Model` suffix)
|
|
98
|
-
│ └── stores/ # stores (name: lowercase + `Store` suffix)
|
|
99
|
-
├── tsconfig.json
|
|
100
|
-
└── package.json
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Naming conventions are enforced at compile time: each entity kind must live in its dedicated folder and respect its naming pattern. The `@` import alias points to `src/`.
|
|
104
|
-
|
|
105
|
-
## Your First Component
|
|
106
|
-
|
|
107
|
-
```tsx
|
|
108
|
-
import { component, mount } from "steel-frame";
|
|
109
|
-
|
|
110
|
-
const App = component(() => {
|
|
111
|
-
<p>Hello world</p>;
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
mount(document.body, App, {});
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
No `return` of JSX is needed — JSX statements render in place, synchronously. When a line of code has executed, the DOM is already in sync.
|
|
118
|
-
|
|
119
|
-
## Reactivity
|
|
120
|
-
|
|
121
|
-
Reactivity is declared through **name prefixes** (reactivity marks):
|
|
122
|
-
|
|
123
|
-
| Prefix | Meaning | Declared with |
|
|
124
|
-
| ------ | --------------------------------------------- | ----------------------- |
|
|
125
|
-
| `wr_` | **writable reactive** value (state) | `let wr_x = ...` |
|
|
126
|
-
| `r_` | **readonly reactive** value (derived/expression) | `const r_y = wr_x + 1` |
|
|
127
|
-
|
|
128
|
-
> The `$` prefix is a legacy mark from older versions. Do not use it in new code.
|
|
129
|
-
|
|
130
|
-
```tsx
|
|
131
|
-
import { component, state, live, field, debounced, effect, unwrap } from "steel-frame";
|
|
132
|
-
|
|
133
|
-
const Counter = component(() => {
|
|
134
|
-
// writable state: `let` + `wr_` prefix
|
|
135
|
-
let wr_count = 0; // implicit state
|
|
136
|
-
let wr_other = state(2); // explicit state constructor
|
|
137
|
-
|
|
138
|
-
// readonly derived values: `const` + `r_` prefix
|
|
139
|
-
const r_double = wr_count * 2; // implicit computed
|
|
140
|
-
const r_label = live(`Count: ${wr_count}`); // explicit computed
|
|
141
|
-
|
|
142
|
-
// reactive reference to an object field
|
|
143
|
-
let wr_obj = { a: { b: 1 } };
|
|
144
|
-
const wr_b = field(wr_obj.a.b);
|
|
145
|
-
|
|
146
|
-
// debounced readonly projection of a state
|
|
147
|
-
const r_debounced = debounced(wr_count, 100);
|
|
148
|
-
|
|
149
|
-
// effect: re-runs when a dependency changes
|
|
150
|
-
effect(() => {
|
|
151
|
-
console.log("count is", wr_count);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// unwrap() reads the raw value without creating a dependency
|
|
155
|
-
const initial = unwrap(wr_count);
|
|
156
|
-
|
|
157
|
-
<div>
|
|
158
|
-
<p>{r_label}</p>
|
|
159
|
-
<button onclick={() => (wr_count += 1)}>+1</button>
|
|
160
|
-
</div>;
|
|
161
|
-
});
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Rules enforced by the compiler:
|
|
165
|
-
|
|
166
|
-
- Assigning to an `r_` value is forbidden (`Writing to readonly reactive values is forbidden`).
|
|
167
|
-
- `const r_ = state(..)` is rejected — a state is writable, so it needs the `wr_` mark.
|
|
168
|
-
- `let wr_ = live(..)` or `wr_ = debounced(..)` is rejected — derived values are readonly, so they need the `r_` mark.
|
|
169
|
-
- A readonly value cannot be passed where a component expects a writable (`wr_`) prop.
|
|
170
|
-
- Inside `effect`, states cannot be written directly (escape hatch: `bypassWriteRestriction`, deprecated — report such cases).
|
|
171
|
-
|
|
172
|
-
### Reactive Collections
|
|
173
|
-
|
|
174
|
-
Plain arrays/sets/maps are not implicitly reactive. Use models:
|
|
175
|
-
|
|
176
|
-
```tsx
|
|
177
|
-
import { arrayModel, setModel, mapModel } from "steel-frame";
|
|
178
|
-
|
|
179
|
-
const items = arrayModel([1, 2, 3]); // push/splice/... trigger updates
|
|
180
|
-
const tags = setModel(["a", "b"]); // add/delete trigger updates
|
|
181
|
-
const dict = mapModel([["k", 1]]); // set/delete trigger updates
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Async Data
|
|
185
|
-
|
|
186
|
-
```tsx
|
|
187
|
-
import { component, awaited, abortSignal } from "steel-frame";
|
|
188
|
-
|
|
189
|
-
const UserCard = component(() => {
|
|
190
|
-
// awaited: async data in a sync component
|
|
191
|
-
const [r_err, r_user] = awaited(signal => fetch("/api/user", { signal }).then(r => r.json()));
|
|
192
|
-
|
|
193
|
-
// abortSignal(): cancels requests/timers when the component is destroyed
|
|
194
|
-
const signal = abortSignal();
|
|
195
|
-
});
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## Conditional Rendering
|
|
199
|
-
|
|
200
|
-
```tsx
|
|
201
|
-
import { component, If, ElseIf, Else } from "steel-frame";
|
|
202
|
-
|
|
203
|
-
const Status = component((props: { wr_value: number }) => {
|
|
204
|
-
<>
|
|
205
|
-
<If $condition={props.wr_value > 10}>big</If>
|
|
206
|
-
<ElseIf $condition={props.wr_value > 5}>medium</ElseIf>
|
|
207
|
-
<Else>small</Else>
|
|
208
|
-
|
|
209
|
-
{/* inline forms are also reactive */}
|
|
210
|
-
{props.wr_value > 0 ? <>positive</> : <>non-positive</>}
|
|
211
|
-
{props.wr_value && <>non-zero</>}
|
|
212
|
-
</>;
|
|
213
|
-
});
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Loops
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
import { component, For, ArrayView, ArrayModelView, arrayModel } from "steel-frame";
|
|
220
|
-
|
|
221
|
-
const List = component(() => {
|
|
222
|
-
const items = arrayModel(["a", "b", "c"]);
|
|
223
|
-
|
|
224
|
-
<>
|
|
225
|
-
{/* static-ish iteration over array/set/map */}
|
|
226
|
-
<For of={items} slot={value => <li>{value}</li>} />
|
|
227
|
-
|
|
228
|
-
{/* reactive array with diff algorithm (keyed) */}
|
|
229
|
-
<ArrayView $of={items} key={v => v} slot={(r_value, r_index) => <li>{r_value}</li>} />
|
|
230
|
-
|
|
231
|
-
{/* fine-grained model views */}
|
|
232
|
-
<ArrayModelView of={items} slot={(value, r_index) => <li>{value}</li>} />
|
|
233
|
-
</>;
|
|
234
|
-
});
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
Also available: `MapModelView`, `SetModelView`, `Iterate`, `ForEach`, `Watch`, `Delay`, `QueuedRender` (non-blocking rendering queue), and `Zombie` (keeps HTML elements alive for a while after destruction).
|
|
238
|
-
|
|
239
|
-
## Components, Props & Slots
|
|
240
|
-
|
|
241
|
-
```tsx
|
|
242
|
-
import { component, Slot } from "steel-frame";
|
|
243
|
-
|
|
244
|
-
interface Props {
|
|
245
|
-
// reactivity marks work in props too:
|
|
246
|
-
wr_value: number; // writable reactive prop (2-way binding)
|
|
247
|
-
r_label: string; // readonly reactive prop
|
|
248
|
-
max: number; // static prop
|
|
249
|
-
slot?: () => void; // slot
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const Field = component((props: Props) => {
|
|
253
|
-
<div>
|
|
254
|
-
<span>{props.r_label}</span>
|
|
255
|
-
<input oninput={ev => (props.wr_value = Number(ev.currentTarget.value))} />
|
|
256
|
-
<Slot model={props.slot} />
|
|
257
|
-
</div>;
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
const Form = component(() => {
|
|
261
|
-
let wr_age = 18;
|
|
262
|
-
const r_title = "Age";
|
|
263
|
-
|
|
264
|
-
<Field wr_value={wr_age} r_label={r_title} max={100}>
|
|
265
|
-
<small>Required field</small>
|
|
266
|
-
</Field>;
|
|
267
|
-
});
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
A component can expose data to its parent via `return` + the `callback` prop:
|
|
271
|
-
|
|
272
|
-
```tsx
|
|
273
|
-
const Exposing = component(() => {
|
|
274
|
-
let wr_x = 1;
|
|
275
|
-
return { wr_x };
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
const Parent = component(() => {
|
|
279
|
-
<Exposing callback={data => console.log(data.wr_x)} />;
|
|
280
|
-
});
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
DOM references and lifecycle per element use `callback` on tags (the returned function runs on element destruction):
|
|
284
|
-
|
|
285
|
-
```tsx
|
|
286
|
-
<div
|
|
287
|
-
callback={div => {
|
|
288
|
-
div.style.display = "none";
|
|
289
|
-
return () => (div.style.display = "block");
|
|
290
|
-
}}
|
|
291
|
-
/>;
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
## Pages & Routing
|
|
295
|
-
|
|
296
|
-
**`page` is the universal composition for application pages** — it works with SPA, SSG (static site generation), and planned SSR. It is available starting with v5.
|
|
297
|
-
|
|
298
|
-
Pages live in `src/pages/` and use file-based routing. Each page file **default-exports** a `page`, and its route type parameter must match the file path:
|
|
299
|
-
|
|
300
|
-
```tsx
|
|
301
|
-
// src/pages/index.tsx → route "/"
|
|
302
|
-
import { page } from "steel-frame";
|
|
303
|
-
|
|
304
|
-
export default page<"/">(async props => {
|
|
305
|
-
<h1>Home</h1>;
|
|
306
|
-
});
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
```tsx
|
|
310
|
-
// src/pages/about.tsx → route "/about"
|
|
311
|
-
import { page } from "steel-frame";
|
|
312
|
-
|
|
313
|
-
export default page<"/about">(async props => {
|
|
314
|
-
<h1>About — {props.path}</h1>;
|
|
315
|
-
});
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
Dynamic segments use parentheses in the file name:
|
|
319
|
-
|
|
320
|
-
```tsx
|
|
321
|
-
// src/pages/(id).tsx → route "/:id"
|
|
322
|
-
import { page } from "steel-frame";
|
|
323
|
-
|
|
324
|
-
export default page<"/(id)">(async ({ params }) => {
|
|
325
|
-
<h1>Item {params.id}</h1>;
|
|
326
|
-
});
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
Folders nest routes: `src/pages/blog/(slug).tsx` → `/blog/:slug`. An `index.tsx` inside a folder maps to the folder path itself.
|
|
330
|
-
|
|
331
|
-
Page props include `path`, `params`, `query`, `url` and `hash` — all strongly typed from the route string.
|
|
332
|
-
|
|
333
|
-
Navigation is done through the current router:
|
|
334
|
-
|
|
335
|
-
```tsx
|
|
336
|
-
import { component, beforeMount, router } from "steel-frame";
|
|
337
|
-
|
|
338
|
-
const Nav = component(() => {
|
|
339
|
-
<button onclick={() => router()?.goTo("/about")}>About</button>;
|
|
340
|
-
});
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
Router behavior can be customized by placing files in `src/router/`: `fallbackScreen` (not-found / no-access), `errorScreen`, `loadingScreen`, `loadingOverlay`, and `checkAccess` (access levels).
|
|
344
|
-
|
|
345
|
-
## Screens (SPA only)
|
|
346
|
-
|
|
347
|
-
**`screen` is compatible with SPA only.** Use it when you build a pure Single Page Application with the programmatic router instead of (or alongside) file-based pages:
|
|
348
|
-
|
|
349
|
-
```tsx
|
|
350
|
-
import { screen, routerApp } from "steel-frame";
|
|
351
|
-
|
|
352
|
-
const MainScreen = screen<"/">(async props => {
|
|
353
|
-
<h1>Main</h1>;
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
const ItemScreen = screen<"/item/(id)">(async ({ params }) => {
|
|
357
|
-
<h1>Item {params.id}</h1>;
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
routerApp({
|
|
361
|
-
routes: {
|
|
362
|
-
"/": { screen: MainScreen },
|
|
363
|
-
"/item/(id)": { screen: ItemScreen, minAccessLevel: 1 },
|
|
364
|
-
},
|
|
365
|
-
getAccessLevel: async () => 1,
|
|
366
|
-
fallbackScreen: ({ cause }) => {
|
|
367
|
-
<p>{cause === "not-found" ? "404" : "403"}</p>;
|
|
368
|
-
},
|
|
369
|
-
});
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
If you target SSG or future SSR, prefer `page` — screens will not be rendered statically.
|
|
373
|
-
|
|
374
|
-
## Models & Stores
|
|
375
|
-
|
|
376
|
-
A **model** is a reusable reactive state constructor; a **store** is a singleton state kept in memory:
|
|
377
|
-
|
|
378
|
-
```tsx
|
|
379
|
-
// src/models/counterModel.ts
|
|
380
|
-
import { model, createModel, component, beforeMount } from "steel-frame";
|
|
381
|
-
|
|
382
|
-
export const counterModel = model((props: { start: number }) => {
|
|
383
|
-
let wr_count = props.start;
|
|
384
|
-
return { wr_count };
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// usage inside a component
|
|
388
|
-
const Counter = component(() => {
|
|
389
|
-
const counter = createModel(counterModel, { start: 0 });
|
|
390
|
-
|
|
391
|
-
<button onclick={() => (counter.wr_count += 1)}>{counter.wr_count}</button>;
|
|
392
|
-
});
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
```tsx
|
|
396
|
-
// src/stores/userStore.ts
|
|
397
|
-
import { store } from "steel-frame";
|
|
398
|
-
|
|
399
|
-
export const userStore = store(() => {
|
|
400
|
-
let wr_name = "guest";
|
|
401
|
-
return { wr_name };
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
// anywhere: userStore.wr_name (readonly state view from outside)
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
## Modals & Prompts
|
|
408
|
-
|
|
409
|
-
```tsx
|
|
410
|
-
// src/modals/ConfirmModal.tsx
|
|
411
|
-
import { modal } from "steel-frame";
|
|
412
|
-
|
|
413
|
-
export const ConfirmModal = modal((props: { wr_open: boolean }) => {
|
|
414
|
-
<If $condition={props.wr_open}>
|
|
415
|
-
<div class="overlay">...</div>
|
|
416
|
-
</If>;
|
|
417
|
-
});
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
Prompts are modals that resolve a value, shown imperatively:
|
|
421
|
-
|
|
422
|
-
```tsx
|
|
423
|
-
// src/prompts/promptName.tsx
|
|
424
|
-
import { prompt, showPrompt, component } from "steel-frame";
|
|
425
|
-
|
|
426
|
-
export const promptName = prompt<string>(props => {
|
|
427
|
-
<div>
|
|
428
|
-
<input onchange={ev => props.resolve(ev.currentTarget.value)} />
|
|
429
|
-
<button onclick={() => props.reject(new Error("cancelled"))}>Cancel</button>
|
|
430
|
-
</div>;
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
const C = component(() => {
|
|
434
|
-
<button onclick={async () => console.log(await showPrompt(promptName, {}))}>Ask name</button>;
|
|
435
|
-
});
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
## Styling
|
|
439
|
-
|
|
440
|
-
Local stylesheets with themes and responsive helpers:
|
|
441
|
-
|
|
442
|
-
```tsx
|
|
443
|
-
import { styleSheet, dark, light, mobile, tablet, laptop, theme, prefersDark } from "steel-frame";
|
|
444
|
-
|
|
445
|
-
const styles = styleSheet({
|
|
446
|
-
card: {
|
|
447
|
-
padding: [10, 5],
|
|
448
|
-
display: "block",
|
|
449
|
-
margin: [laptop(40), tablet(20), mobile(10)],
|
|
450
|
-
color: ["#222", dark("#eee")],
|
|
451
|
-
background: [theme("red", "#f00"), theme("blue", "#00f")],
|
|
452
|
-
":hover": { opacity: 0.8 },
|
|
453
|
-
"@media (max-width: 600px)": { padding: 4 },
|
|
454
|
-
},
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
const Card = component(() => {
|
|
458
|
-
<div class={styles.card}>...</div>;
|
|
459
|
-
});
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
Breakpoints are configurable with `setMobileMaxWidth`, `setTabletMaxWidth`, `setLaptopMaxWidth`.
|
|
463
|
-
|
|
464
|
-
## Lifecycle & Effects
|
|
465
|
-
|
|
466
|
-
```tsx
|
|
467
|
-
import { component, beforeMount, afterMount, beforeDestroy, effect } from "steel-frame";
|
|
468
|
-
|
|
469
|
-
const C = component(() => {
|
|
470
|
-
beforeMount(() => { /* before DOM mount, may be async */ });
|
|
471
|
-
afterMount(() => { /* after DOM mount, may be async */ });
|
|
472
|
-
beforeDestroy(() => { /* cleanup */ });
|
|
473
|
-
|
|
474
|
-
effect(() => { /* re-runs when reactive dependencies change */ });
|
|
475
|
-
});
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
## Dependency Injection
|
|
479
|
-
|
|
480
|
-
Share values down the component tree:
|
|
481
|
-
|
|
482
|
-
```tsx
|
|
483
|
-
import { component, context, share, receive, receiveOptional, impute } from "steel-frame";
|
|
484
|
-
|
|
485
|
-
const themeCtx = context((name: string) => ({ name }));
|
|
486
|
-
|
|
487
|
-
const Parent = component(() => {
|
|
488
|
-
share(themeCtx, "dark"); // share a context
|
|
489
|
-
share("api-url", "/api"); // share a setting
|
|
490
|
-
share(MyService, new MyService()); // share a class instance
|
|
491
|
-
|
|
492
|
-
<Child />;
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
const Child = component(() => {
|
|
496
|
-
const theme = receive(themeCtx); // required
|
|
497
|
-
const apiUrl = receiveOptional("api-url"); // optional
|
|
498
|
-
const svc = impute(MyService, () => new MyService()); // create when missing
|
|
499
|
-
});
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
## Fault Tolerance Helpers
|
|
503
|
-
|
|
504
|
-
Errors are contained, not propagated — a failing component does not crash the app:
|
|
505
|
-
|
|
506
|
-
```tsx
|
|
507
|
-
import { setErrorHandler, safe, safeInit, safeState, safeLive } from "steel-frame";
|
|
508
|
-
|
|
509
|
-
setErrorHandler(e => reportToServer(e));
|
|
510
|
-
|
|
511
|
-
const C = component(() => {
|
|
512
|
-
const a = safeInit(mayThrow()); // undefined on failure
|
|
513
|
-
const wr_b = safeState(mayThrow()); // undefined state on failure
|
|
514
|
-
const r_c = safeLive(wr_b ?? 0 + mayThrow()); // undefined computed on failure
|
|
515
|
-
});
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
JSX attribute and child expressions are automatically made safe by the compiler; errors are reported through the configured handler.
|
|
519
|
-
|
|
520
|
-
---
|
|
521
|
-
|
|
522
|
-
**Next steps:**
|
|
523
|
-
|
|
524
|
-
- Run `npm create steel-frame` and explore the generated project.
|
|
525
|
-
- Start the dev server with `npx web dev`.
|
|
526
|
-
- Ship with `npx web build spa` or `npx web build html`.
|