mythik 0.0.1 → 0.1.0
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/LICENSE +201 -0
- package/NOTICE +4 -0
- package/README.md +97 -2
- package/dist/actions/dispatcher.d.ts +46 -0
- package/dist/actions/dispatcher.d.ts.map +1 -0
- package/dist/actions/dispatcher.js +366 -0
- package/dist/actions/dispatcher.js.map +1 -0
- package/dist/actions/middleware.d.ts +27 -0
- package/dist/actions/middleware.d.ts.map +1 -0
- package/dist/actions/middleware.js +37 -0
- package/dist/actions/middleware.js.map +1 -0
- package/dist/actions/transaction-engine.d.ts +13 -0
- package/dist/actions/transaction-engine.d.ts.map +1 -0
- package/dist/actions/transaction-engine.js +96 -0
- package/dist/actions/transaction-engine.js.map +1 -0
- package/dist/app/app-engine.d.ts +106 -0
- package/dist/app/app-engine.d.ts.map +1 -0
- package/dist/app/app-engine.js +413 -0
- package/dist/app/app-engine.js.map +1 -0
- package/dist/auth/cross-tab.d.ts +24 -0
- package/dist/auth/cross-tab.d.ts.map +1 -0
- package/dist/auth/cross-tab.js +117 -0
- package/dist/auth/cross-tab.js.map +1 -0
- package/dist/auth/engine.d.ts +16 -0
- package/dist/auth/engine.d.ts.map +1 -0
- package/dist/auth/engine.js +225 -0
- package/dist/auth/engine.js.map +1 -0
- package/dist/auth/persistence.d.ts +21 -0
- package/dist/auth/persistence.d.ts.map +1 -0
- package/dist/auth/persistence.js +97 -0
- package/dist/auth/persistence.js.map +1 -0
- package/dist/auth/providers/custom-jwt.d.ts +41 -0
- package/dist/auth/providers/custom-jwt.d.ts.map +1 -0
- package/dist/auth/providers/custom-jwt.js +165 -0
- package/dist/auth/providers/custom-jwt.js.map +1 -0
- package/dist/auth/providers/mock.d.ts +7 -0
- package/dist/auth/providers/mock.d.ts.map +1 -0
- package/dist/auth/providers/mock.js +52 -0
- package/dist/auth/providers/mock.js.map +1 -0
- package/dist/auth/providers/supabase.d.ts +90 -0
- package/dist/auth/providers/supabase.d.ts.map +1 -0
- package/dist/auth/providers/supabase.js +102 -0
- package/dist/auth/providers/supabase.js.map +1 -0
- package/dist/auth/rate-limiter.d.ts +29 -0
- package/dist/auth/rate-limiter.d.ts.map +1 -0
- package/dist/auth/rate-limiter.js +67 -0
- package/dist/auth/rate-limiter.js.map +1 -0
- package/dist/auth/refresh-engine.d.ts +25 -0
- package/dist/auth/refresh-engine.d.ts.map +1 -0
- package/dist/auth/refresh-engine.js +59 -0
- package/dist/auth/refresh-engine.js.map +1 -0
- package/dist/auth/types.d.ts +89 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/contract/endpoint-map.d.ts +20 -0
- package/dist/contract/endpoint-map.d.ts.map +1 -0
- package/dist/contract/endpoint-map.js +57 -0
- package/dist/contract/endpoint-map.js.map +1 -0
- package/dist/contract/engine.d.ts +12 -0
- package/dist/contract/engine.d.ts.map +1 -0
- package/dist/contract/engine.js +80 -0
- package/dist/contract/engine.js.map +1 -0
- package/dist/contract/extractor.d.ts +7 -0
- package/dist/contract/extractor.d.ts.map +1 -0
- package/dist/contract/extractor.js +133 -0
- package/dist/contract/extractor.js.map +1 -0
- package/dist/contract/index.d.ts +4 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +2 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/matcher.d.ts +13 -0
- package/dist/contract/matcher.d.ts.map +1 -0
- package/dist/contract/matcher.js +57 -0
- package/dist/contract/matcher.js.map +1 -0
- package/dist/contract/rules/endpoints-exist.d.ts +3 -0
- package/dist/contract/rules/endpoints-exist.d.ts.map +1 -0
- package/dist/contract/rules/endpoints-exist.js +29 -0
- package/dist/contract/rules/endpoints-exist.js.map +1 -0
- package/dist/contract/rules/fields-valid.d.ts +3 -0
- package/dist/contract/rules/fields-valid.d.ts.map +1 -0
- package/dist/contract/rules/fields-valid.js +39 -0
- package/dist/contract/rules/fields-valid.js.map +1 -0
- package/dist/contract/rules/params-match.d.ts +3 -0
- package/dist/contract/rules/params-match.d.ts.map +1 -0
- package/dist/contract/rules/params-match.js +40 -0
- package/dist/contract/rules/params-match.js.map +1 -0
- package/dist/contract/rules/permissions-consistent.d.ts +3 -0
- package/dist/contract/rules/permissions-consistent.d.ts.map +1 -0
- package/dist/contract/rules/permissions-consistent.js +52 -0
- package/dist/contract/rules/permissions-consistent.js.map +1 -0
- package/dist/contract/types.d.ts +66 -0
- package/dist/contract/types.d.ts.map +1 -0
- package/dist/contract/types.js +2 -0
- package/dist/contract/types.js.map +1 -0
- package/dist/data/data-sources.d.ts +26 -0
- package/dist/data/data-sources.d.ts.map +1 -0
- package/dist/data/data-sources.js +218 -0
- package/dist/data/data-sources.js.map +1 -0
- package/dist/data/fetch.d.ts +29 -0
- package/dist/data/fetch.d.ts.map +1 -0
- package/dist/data/fetch.js +63 -0
- package/dist/data/fetch.js.map +1 -0
- package/dist/data/offline.d.ts +29 -0
- package/dist/data/offline.d.ts.map +1 -0
- package/dist/data/offline.js +48 -0
- package/dist/data/offline.js.map +1 -0
- package/dist/data/realtime.d.ts +21 -0
- package/dist/data/realtime.d.ts.map +1 -0
- package/dist/data/realtime.js +40 -0
- package/dist/data/realtime.js.map +1 -0
- package/dist/derive/evaluator.d.ts +19 -0
- package/dist/derive/evaluator.d.ts.map +1 -0
- package/dist/derive/evaluator.js +59 -0
- package/dist/derive/evaluator.js.map +1 -0
- package/dist/derive/topo-sort.d.ts +10 -0
- package/dist/derive/topo-sort.d.ts.map +1 -0
- package/dist/derive/topo-sort.js +36 -0
- package/dist/derive/topo-sort.js.map +1 -0
- package/dist/design/animation/cascade-types.d.ts +23 -0
- package/dist/design/animation/cascade-types.d.ts.map +1 -0
- package/dist/design/animation/cascade-types.js +2 -0
- package/dist/design/animation/cascade-types.js.map +1 -0
- package/dist/design/animation/cascade.d.ts +4 -0
- package/dist/design/animation/cascade.d.ts.map +1 -0
- package/dist/design/animation/cascade.js +73 -0
- package/dist/design/animation/cascade.js.map +1 -0
- package/dist/design/animation/css-keyframes.d.ts +8 -0
- package/dist/design/animation/css-keyframes.d.ts.map +1 -0
- package/dist/design/animation/css-keyframes.js +72 -0
- package/dist/design/animation/css-keyframes.js.map +1 -0
- package/dist/design/animation/index.d.ts +14 -0
- package/dist/design/animation/index.d.ts.map +1 -0
- package/dist/design/animation/index.js +9 -0
- package/dist/design/animation/index.js.map +1 -0
- package/dist/design/animation/keyframes-builder.d.ts +40 -0
- package/dist/design/animation/keyframes-builder.d.ts.map +1 -0
- package/dist/design/animation/keyframes-builder.js +140 -0
- package/dist/design/animation/keyframes-builder.js.map +1 -0
- package/dist/design/animation/reanimated-spec.d.ts +16 -0
- package/dist/design/animation/reanimated-spec.d.ts.map +1 -0
- package/dist/design/animation/reanimated-spec.js +162 -0
- package/dist/design/animation/reanimated-spec.js.map +1 -0
- package/dist/design/animation/reduced-motion.d.ts +3 -0
- package/dist/design/animation/reduced-motion.d.ts.map +1 -0
- package/dist/design/animation/reduced-motion.js +54 -0
- package/dist/design/animation/reduced-motion.js.map +1 -0
- package/dist/design/animation/resolver.d.ts +3 -0
- package/dist/design/animation/resolver.d.ts.map +1 -0
- package/dist/design/animation/resolver.js +86 -0
- package/dist/design/animation/resolver.js.map +1 -0
- package/dist/design/animation/types.d.ts +109 -0
- package/dist/design/animation/types.d.ts.map +1 -0
- package/dist/design/animation/types.js +7 -0
- package/dist/design/animation/types.js.map +1 -0
- package/dist/design/animation/validator.d.ts +44 -0
- package/dist/design/animation/validator.d.ts.map +1 -0
- package/dist/design/animation/validator.js +169 -0
- package/dist/design/animation/validator.js.map +1 -0
- package/dist/design/background/blobs/catalog.d.ts +10 -0
- package/dist/design/background/blobs/catalog.d.ts.map +1 -0
- package/dist/design/background/blobs/catalog.js +63 -0
- package/dist/design/background/blobs/catalog.js.map +1 -0
- package/dist/design/background/blobs/index.d.ts +4 -0
- package/dist/design/background/blobs/index.d.ts.map +1 -0
- package/dist/design/background/blobs/index.js +5 -0
- package/dist/design/background/blobs/index.js.map +1 -0
- package/dist/design/background/blobs/resolver.d.ts +16 -0
- package/dist/design/background/blobs/resolver.d.ts.map +1 -0
- package/dist/design/background/blobs/resolver.js +301 -0
- package/dist/design/background/blobs/resolver.js.map +1 -0
- package/dist/design/background/blobs/types.d.ts +112 -0
- package/dist/design/background/blobs/types.d.ts.map +1 -0
- package/dist/design/background/blobs/types.js +27 -0
- package/dist/design/background/blobs/types.js.map +1 -0
- package/dist/design/background/grain.d.ts +3 -0
- package/dist/design/background/grain.d.ts.map +1 -0
- package/dist/design/background/grain.js +23 -0
- package/dist/design/background/grain.js.map +1 -0
- package/dist/design/background/index.d.ts +8 -0
- package/dist/design/background/index.d.ts.map +1 -0
- package/dist/design/background/index.js +8 -0
- package/dist/design/background/index.js.map +1 -0
- package/dist/design/background/layers.d.ts +3 -0
- package/dist/design/background/layers.d.ts.map +1 -0
- package/dist/design/background/layers.js +23 -0
- package/dist/design/background/layers.js.map +1 -0
- package/dist/design/background/patterns/chevron.d.ts +8 -0
- package/dist/design/background/patterns/chevron.d.ts.map +1 -0
- package/dist/design/background/patterns/chevron.js +10 -0
- package/dist/design/background/patterns/chevron.js.map +1 -0
- package/dist/design/background/patterns/crosshatch.d.ts +8 -0
- package/dist/design/background/patterns/crosshatch.d.ts.map +1 -0
- package/dist/design/background/patterns/crosshatch.js +12 -0
- package/dist/design/background/patterns/crosshatch.js.map +1 -0
- package/dist/design/background/patterns/diagonal.d.ts +8 -0
- package/dist/design/background/patterns/diagonal.d.ts.map +1 -0
- package/dist/design/background/patterns/diagonal.js +7 -0
- package/dist/design/background/patterns/diagonal.js.map +1 -0
- package/dist/design/background/patterns/dots.d.ts +7 -0
- package/dist/design/background/patterns/dots.d.ts.map +1 -0
- package/dist/design/background/patterns/dots.js +9 -0
- package/dist/design/background/patterns/dots.js.map +1 -0
- package/dist/design/background/patterns/grid.d.ts +7 -0
- package/dist/design/background/patterns/grid.d.ts.map +1 -0
- package/dist/design/background/patterns/grid.js +8 -0
- package/dist/design/background/patterns/grid.js.map +1 -0
- package/dist/design/background/patterns/index.d.ts +8 -0
- package/dist/design/background/patterns/index.d.ts.map +1 -0
- package/dist/design/background/patterns/index.js +8 -0
- package/dist/design/background/patterns/index.js.map +1 -0
- package/dist/design/background/patterns/iso.d.ts +7 -0
- package/dist/design/background/patterns/iso.d.ts.map +1 -0
- package/dist/design/background/patterns/iso.js +11 -0
- package/dist/design/background/patterns/iso.js.map +1 -0
- package/dist/design/background/patterns/resolver.d.ts +3 -0
- package/dist/design/background/patterns/resolver.d.ts.map +1 -0
- package/dist/design/background/patterns/resolver.js +56 -0
- package/dist/design/background/patterns/resolver.js.map +1 -0
- package/dist/design/background/primitives/gradient.d.ts +3 -0
- package/dist/design/background/primitives/gradient.d.ts.map +1 -0
- package/dist/design/background/primitives/gradient.js +68 -0
- package/dist/design/background/primitives/gradient.js.map +1 -0
- package/dist/design/background/primitives/image.d.ts +3 -0
- package/dist/design/background/primitives/image.d.ts.map +1 -0
- package/dist/design/background/primitives/image.js +12 -0
- package/dist/design/background/primitives/image.js.map +1 -0
- package/dist/design/background/primitives/index.d.ts +4 -0
- package/dist/design/background/primitives/index.d.ts.map +1 -0
- package/dist/design/background/primitives/index.js +4 -0
- package/dist/design/background/primitives/index.js.map +1 -0
- package/dist/design/background/primitives/solid.d.ts +8 -0
- package/dist/design/background/primitives/solid.d.ts.map +1 -0
- package/dist/design/background/primitives/solid.js +15 -0
- package/dist/design/background/primitives/solid.js.map +1 -0
- package/dist/design/background/resolver.d.ts +3 -0
- package/dist/design/background/resolver.d.ts.map +1 -0
- package/dist/design/background/resolver.js +20 -0
- package/dist/design/background/resolver.js.map +1 -0
- package/dist/design/background/sanitizer.d.ts +2 -0
- package/dist/design/background/sanitizer.d.ts.map +1 -0
- package/dist/design/background/sanitizer.js +54 -0
- package/dist/design/background/sanitizer.js.map +1 -0
- package/dist/design/deep-tokens.d.ts +125 -0
- package/dist/design/deep-tokens.d.ts.map +1 -0
- package/dist/design/deep-tokens.js +115 -0
- package/dist/design/deep-tokens.js.map +1 -0
- package/dist/design/dna.d.ts +7 -0
- package/dist/design/dna.d.ts.map +1 -0
- package/dist/design/dna.js +210 -0
- package/dist/design/dna.js.map +1 -0
- package/dist/design/identity/color.d.ts +8 -0
- package/dist/design/identity/color.d.ts.map +1 -0
- package/dist/design/identity/color.js +64 -0
- package/dist/design/identity/color.js.map +1 -0
- package/dist/design/identity/elevation.d.ts +8 -0
- package/dist/design/identity/elevation.d.ts.map +1 -0
- package/dist/design/identity/elevation.js +31 -0
- package/dist/design/identity/elevation.js.map +1 -0
- package/dist/design/identity/index.d.ts +12 -0
- package/dist/design/identity/index.d.ts.map +1 -0
- package/dist/design/identity/index.js +14 -0
- package/dist/design/identity/index.js.map +1 -0
- package/dist/design/identity/shape.d.ts +4 -0
- package/dist/design/identity/shape.d.ts.map +1 -0
- package/dist/design/identity/shape.js +23 -0
- package/dist/design/identity/shape.js.map +1 -0
- package/dist/design/identity/surface.d.ts +18 -0
- package/dist/design/identity/surface.d.ts.map +1 -0
- package/dist/design/identity/surface.js +125 -0
- package/dist/design/identity/surface.js.map +1 -0
- package/dist/design/identity/types.d.ts +280 -0
- package/dist/design/identity/types.d.ts.map +1 -0
- package/dist/design/identity/types.js +21 -0
- package/dist/design/identity/types.js.map +1 -0
- package/dist/design/identity/typography.d.ts +7 -0
- package/dist/design/identity/typography.d.ts.map +1 -0
- package/dist/design/identity/typography.js +42 -0
- package/dist/design/identity/typography.js.map +1 -0
- package/dist/design/identity-resolver.d.ts +15 -0
- package/dist/design/identity-resolver.d.ts.map +1 -0
- package/dist/design/identity-resolver.js +52 -0
- package/dist/design/identity-resolver.js.map +1 -0
- package/dist/design/oklch.d.ts +10 -0
- package/dist/design/oklch.d.ts.map +1 -0
- package/dist/design/oklch.js +61 -0
- package/dist/design/oklch.js.map +1 -0
- package/dist/design/palette.d.ts +26 -0
- package/dist/design/palette.d.ts.map +1 -0
- package/dist/design/palette.js +73 -0
- package/dist/design/palette.js.map +1 -0
- package/dist/design/presets.d.ts +18 -0
- package/dist/design/presets.d.ts.map +1 -0
- package/dist/design/presets.js +2 -0
- package/dist/design/presets.js.map +1 -0
- package/dist/design/recipes/animations.d.ts +11 -0
- package/dist/design/recipes/animations.d.ts.map +1 -0
- package/dist/design/recipes/animations.js +180 -0
- package/dist/design/recipes/animations.js.map +1 -0
- package/dist/design/recipes/backgrounds.d.ts +3 -0
- package/dist/design/recipes/backgrounds.d.ts.map +1 -0
- package/dist/design/recipes/backgrounds.js +152 -0
- package/dist/design/recipes/backgrounds.js.map +1 -0
- package/dist/design/recipes/index.d.ts +2 -0
- package/dist/design/recipes/index.d.ts.map +1 -0
- package/dist/design/recipes/index.js +2 -0
- package/dist/design/recipes/index.js.map +1 -0
- package/dist/design/surface-to-css.d.ts +57 -0
- package/dist/design/surface-to-css.d.ts.map +1 -0
- package/dist/design/surface-to-css.js +130 -0
- package/dist/design/surface-to-css.js.map +1 -0
- package/dist/design/surface-to-rn.d.ts +57 -0
- package/dist/design/surface-to-rn.d.ts.map +1 -0
- package/dist/design/surface-to-rn.js +133 -0
- package/dist/design/surface-to-rn.js.map +1 -0
- package/dist/design/tokens.d.ts +67 -0
- package/dist/design/tokens.d.ts.map +1 -0
- package/dist/design/tokens.js +36 -0
- package/dist/design/tokens.js.map +1 -0
- package/dist/device/context.d.ts +13 -0
- package/dist/device/context.d.ts.map +1 -0
- package/dist/device/context.js +2 -0
- package/dist/device/context.js.map +1 -0
- package/dist/editor-session/clone.d.ts +4 -0
- package/dist/editor-session/clone.d.ts.map +1 -0
- package/dist/editor-session/clone.js +55 -0
- package/dist/editor-session/clone.js.map +1 -0
- package/dist/editor-session/engine.d.ts +21 -0
- package/dist/editor-session/engine.d.ts.map +1 -0
- package/dist/editor-session/engine.js +375 -0
- package/dist/editor-session/engine.js.map +1 -0
- package/dist/editor-session/persistence.d.ts +8 -0
- package/dist/editor-session/persistence.d.ts.map +1 -0
- package/dist/editor-session/persistence.js +89 -0
- package/dist/editor-session/persistence.js.map +1 -0
- package/dist/editor-session/types.d.ts +90 -0
- package/dist/editor-session/types.d.ts.map +1 -0
- package/dist/editor-session/types.js +2 -0
- package/dist/editor-session/types.js.map +1 -0
- package/dist/editor-session/validators.d.ts +5 -0
- package/dist/editor-session/validators.d.ts.map +1 -0
- package/dist/editor-session/validators.js +106 -0
- package/dist/editor-session/validators.js.map +1 -0
- package/dist/elements/composer.d.ts +109 -0
- package/dist/elements/composer.d.ts.map +1 -0
- package/dist/elements/composer.js +129 -0
- package/dist/elements/composer.js.map +1 -0
- package/dist/export/csv.d.ts +3 -0
- package/dist/export/csv.d.ts.map +1 -0
- package/dist/export/csv.js +16 -0
- package/dist/export/csv.js.map +1 -0
- package/dist/export/download.d.ts +2 -0
- package/dist/export/download.d.ts.map +1 -0
- package/dist/export/download.js +13 -0
- package/dist/export/download.js.map +1 -0
- package/dist/export/format.d.ts +3 -0
- package/dist/export/format.d.ts.map +1 -0
- package/dist/export/format.js +43 -0
- package/dist/export/format.js.map +1 -0
- package/dist/export/types.d.ts +22 -0
- package/dist/export/types.d.ts.map +1 -0
- package/dist/export/types.js +2 -0
- package/dist/export/types.js.map +1 -0
- package/dist/expressions/deep-resolve.d.ts +4 -0
- package/dist/expressions/deep-resolve.d.ts.map +1 -0
- package/dist/expressions/deep-resolve.js +20 -0
- package/dist/expressions/deep-resolve.js.map +1 -0
- package/dist/expressions/handlers/array.d.ts +19 -0
- package/dist/expressions/handlers/array.d.ts.map +1 -0
- package/dist/expressions/handlers/array.js +161 -0
- package/dist/expressions/handlers/array.js.map +1 -0
- package/dist/expressions/handlers/auth.d.ts +13 -0
- package/dist/expressions/handlers/auth.d.ts.map +1 -0
- package/dist/expressions/handlers/auth.js +90 -0
- package/dist/expressions/handlers/auth.js.map +1 -0
- package/dist/expressions/handlers/bind.d.ts +22 -0
- package/dist/expressions/handlers/bind.d.ts.map +1 -0
- package/dist/expressions/handlers/bind.js +57 -0
- package/dist/expressions/handlers/bind.js.map +1 -0
- package/dist/expressions/handlers/breakpoint.d.ts +10 -0
- package/dist/expressions/handlers/breakpoint.d.ts.map +1 -0
- package/dist/expressions/handlers/breakpoint.js +39 -0
- package/dist/expressions/handlers/breakpoint.js.map +1 -0
- package/dist/expressions/handlers/computed.d.ts +3 -0
- package/dist/expressions/handlers/computed.d.ts.map +1 -0
- package/dist/expressions/handlers/computed.js +20 -0
- package/dist/expressions/handlers/computed.js.map +1 -0
- package/dist/expressions/handlers/cond.d.ts +3 -0
- package/dist/expressions/handlers/cond.d.ts.map +1 -0
- package/dist/expressions/handlers/cond.js +57 -0
- package/dist/expressions/handlers/cond.js.map +1 -0
- package/dist/expressions/handlers/date.d.ts +14 -0
- package/dist/expressions/handlers/date.d.ts.map +1 -0
- package/dist/expressions/handlers/date.js +95 -0
- package/dist/expressions/handlers/date.js.map +1 -0
- package/dist/expressions/handlers/format.d.ts +19 -0
- package/dist/expressions/handlers/format.d.ts.map +1 -0
- package/dist/expressions/handlers/format.js +93 -0
- package/dist/expressions/handlers/format.js.map +1 -0
- package/dist/expressions/handlers/group.d.ts +25 -0
- package/dist/expressions/handlers/group.d.ts.map +1 -0
- package/dist/expressions/handlers/group.js +85 -0
- package/dist/expressions/handlers/group.js.map +1 -0
- package/dist/expressions/handlers/i18n.d.ts +8 -0
- package/dist/expressions/handlers/i18n.d.ts.map +1 -0
- package/dist/expressions/handlers/i18n.js +35 -0
- package/dist/expressions/handlers/i18n.js.map +1 -0
- package/dist/expressions/handlers/index.d.ts +4 -0
- package/dist/expressions/handlers/index.d.ts.map +1 -0
- package/dist/expressions/handlers/index.js +52 -0
- package/dist/expressions/handlers/index.js.map +1 -0
- package/dist/expressions/handlers/let.d.ts +4 -0
- package/dist/expressions/handlers/let.d.ts.map +1 -0
- package/dist/expressions/handlers/let.js +36 -0
- package/dist/expressions/handlers/let.js.map +1 -0
- package/dist/expressions/handlers/logic.d.ts +27 -0
- package/dist/expressions/handlers/logic.d.ts.map +1 -0
- package/dist/expressions/handlers/logic.js +52 -0
- package/dist/expressions/handlers/logic.js.map +1 -0
- package/dist/expressions/handlers/math.d.ts +13 -0
- package/dist/expressions/handlers/math.d.ts.map +1 -0
- package/dist/expressions/handlers/math.js +58 -0
- package/dist/expressions/handlers/math.js.map +1 -0
- package/dist/expressions/handlers/platform.d.ts +13 -0
- package/dist/expressions/handlers/platform.d.ts.map +1 -0
- package/dist/expressions/handlers/platform.js +37 -0
- package/dist/expressions/handlers/platform.js.map +1 -0
- package/dist/expressions/handlers/prop.d.ts +10 -0
- package/dist/expressions/handlers/prop.d.ts.map +1 -0
- package/dist/expressions/handlers/prop.js +18 -0
- package/dist/expressions/handlers/prop.js.map +1 -0
- package/dist/expressions/handlers/selection.d.ts +10 -0
- package/dist/expressions/handlers/selection.d.ts.map +1 -0
- package/dist/expressions/handlers/selection.js +33 -0
- package/dist/expressions/handlers/selection.js.map +1 -0
- package/dist/expressions/handlers/state.d.ts +3 -0
- package/dist/expressions/handlers/state.d.ts.map +1 -0
- package/dist/expressions/handlers/state.js +8 -0
- package/dist/expressions/handlers/state.js.map +1 -0
- package/dist/expressions/handlers/switch.d.ts +15 -0
- package/dist/expressions/handlers/switch.d.ts.map +1 -0
- package/dist/expressions/handlers/switch.js +31 -0
- package/dist/expressions/handlers/switch.js.map +1 -0
- package/dist/expressions/handlers/template.d.ts +3 -0
- package/dist/expressions/handlers/template.d.ts.map +1 -0
- package/dist/expressions/handlers/template.js +23 -0
- package/dist/expressions/handlers/template.js.map +1 -0
- package/dist/expressions/handlers/token.d.ts +3 -0
- package/dist/expressions/handlers/token.d.ts.map +1 -0
- package/dist/expressions/handlers/token.js +40 -0
- package/dist/expressions/handlers/token.js.map +1 -0
- package/dist/expressions/handlers/unique-id.d.ts +11 -0
- package/dist/expressions/handlers/unique-id.d.ts.map +1 -0
- package/dist/expressions/handlers/unique-id.js +52 -0
- package/dist/expressions/handlers/unique-id.js.map +1 -0
- package/dist/expressions/registry.d.ts +8 -0
- package/dist/expressions/registry.d.ts.map +1 -0
- package/dist/expressions/registry.js +35 -0
- package/dist/expressions/registry.js.map +1 -0
- package/dist/expressions/resolver.d.ts +15 -0
- package/dist/expressions/resolver.d.ts.map +1 -0
- package/dist/expressions/resolver.js +56 -0
- package/dist/expressions/resolver.js.map +1 -0
- package/dist/factory.d.ts +56 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +265 -0
- package/dist/factory.js.map +1 -0
- package/dist/fetch/framework-fetch.d.ts +12 -0
- package/dist/fetch/framework-fetch.d.ts.map +1 -0
- package/dist/fetch/framework-fetch.js +36 -0
- package/dist/fetch/framework-fetch.js.map +1 -0
- package/dist/fetch/interceptors/auth.d.ts +19 -0
- package/dist/fetch/interceptors/auth.d.ts.map +1 -0
- package/dist/fetch/interceptors/auth.js +66 -0
- package/dist/fetch/interceptors/auth.js.map +1 -0
- package/dist/fetch/interceptors/logging.d.ts +8 -0
- package/dist/fetch/interceptors/logging.d.ts.map +1 -0
- package/dist/fetch/interceptors/logging.js +40 -0
- package/dist/fetch/interceptors/logging.js.map +1 -0
- package/dist/fetch/interceptors/retry.d.ts +20 -0
- package/dist/fetch/interceptors/retry.d.ts.map +1 -0
- package/dist/fetch/interceptors/retry.js +34 -0
- package/dist/fetch/interceptors/retry.js.map +1 -0
- package/dist/fetch/interceptors/timeout.d.ts +7 -0
- package/dist/fetch/interceptors/timeout.d.ts.map +1 -0
- package/dist/fetch/interceptors/timeout.js +20 -0
- package/dist/fetch/interceptors/timeout.js.map +1 -0
- package/dist/fetch/types.d.ts +30 -0
- package/dist/fetch/types.d.ts.map +1 -0
- package/dist/fetch/types.js +2 -0
- package/dist/fetch/types.js.map +1 -0
- package/dist/forms/engine.d.ts +3 -0
- package/dist/forms/engine.d.ts.map +1 -0
- package/dist/forms/engine.js +167 -0
- package/dist/forms/engine.js.map +1 -0
- package/dist/forms/types.d.ts +30 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/types.js +2 -0
- package/dist/forms/types.js.map +1 -0
- package/dist/i18n/engine.d.ts +15 -0
- package/dist/i18n/engine.d.ts.map +1 -0
- package/dist/i18n/engine.js +61 -0
- package/dist/i18n/engine.js.map +1 -0
- package/dist/index.d.ts +161 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions/data-operations.d.ts +51 -0
- package/dist/interactions/data-operations.d.ts.map +1 -0
- package/dist/interactions/data-operations.js +64 -0
- package/dist/interactions/data-operations.js.map +1 -0
- package/dist/interactions/drag-drop.d.ts +14 -0
- package/dist/interactions/drag-drop.d.ts.map +1 -0
- package/dist/interactions/drag-drop.js +35 -0
- package/dist/interactions/drag-drop.js.map +1 -0
- package/dist/interactions/export.d.ts +24 -0
- package/dist/interactions/export.d.ts.map +1 -0
- package/dist/interactions/export.js +44 -0
- package/dist/interactions/export.js.map +1 -0
- package/dist/interactions/history.d.ts +16 -0
- package/dist/interactions/history.d.ts.map +1 -0
- package/dist/interactions/history.js +52 -0
- package/dist/interactions/history.js.map +1 -0
- package/dist/motion/engine.d.ts +47 -0
- package/dist/motion/engine.d.ts.map +1 -0
- package/dist/motion/engine.js +81 -0
- package/dist/motion/engine.js.map +1 -0
- package/dist/navigation/router.d.ts +36 -0
- package/dist/navigation/router.d.ts.map +1 -0
- package/dist/navigation/router.js +51 -0
- package/dist/navigation/router.js.map +1 -0
- package/dist/permissions/evaluator.d.ts +15 -0
- package/dist/permissions/evaluator.d.ts.map +1 -0
- package/dist/permissions/evaluator.js +32 -0
- package/dist/permissions/evaluator.js.map +1 -0
- package/dist/plugins/loader.d.ts +30 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +87 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/reference/generator.d.ts +25 -0
- package/dist/reference/generator.d.ts.map +1 -0
- package/dist/reference/generator.js +808 -0
- package/dist/reference/generator.js.map +1 -0
- package/dist/renderer/deps.d.ts +24 -0
- package/dist/renderer/deps.d.ts.map +1 -0
- package/dist/renderer/deps.js +150 -0
- package/dist/renderer/deps.js.map +1 -0
- package/dist/renderer/engine.d.ts +15 -0
- package/dist/renderer/engine.d.ts.map +1 -0
- package/dist/renderer/engine.js +1097 -0
- package/dist/renderer/engine.js.map +1 -0
- package/dist/renderer/lazy-paths.d.ts +14 -0
- package/dist/renderer/lazy-paths.d.ts.map +1 -0
- package/dist/renderer/lazy-paths.js +63 -0
- package/dist/renderer/lazy-paths.js.map +1 -0
- package/dist/renderer/prop-schemas.d.ts +17 -0
- package/dist/renderer/prop-schemas.d.ts.map +1 -0
- package/dist/renderer/prop-schemas.js +81 -0
- package/dist/renderer/prop-schemas.js.map +1 -0
- package/dist/renderer/registry.d.ts +10 -0
- package/dist/renderer/registry.d.ts.map +1 -0
- package/dist/renderer/registry.js +22 -0
- package/dist/renderer/registry.js.map +1 -0
- package/dist/renderer/variants.d.ts +54 -0
- package/dist/renderer/variants.d.ts.map +1 -0
- package/dist/renderer/variants.js +105 -0
- package/dist/renderer/variants.js.map +1 -0
- package/dist/runtime/mount-spec-runtime.d.ts +59 -0
- package/dist/runtime/mount-spec-runtime.d.ts.map +1 -0
- package/dist/runtime/mount-spec-runtime.js +73 -0
- package/dist/runtime/mount-spec-runtime.js.map +1 -0
- package/dist/security/api-spec-validator.d.ts +13 -0
- package/dist/security/api-spec-validator.d.ts.map +1 -0
- package/dist/security/api-spec-validator.js +347 -0
- package/dist/security/api-spec-validator.js.map +1 -0
- package/dist/security/app-spec-validator.d.ts +4 -0
- package/dist/security/app-spec-validator.d.ts.map +1 -0
- package/dist/security/app-spec-validator.js +200 -0
- package/dist/security/app-spec-validator.js.map +1 -0
- package/dist/security/identifier-guard.d.ts +3 -0
- package/dist/security/identifier-guard.d.ts.map +1 -0
- package/dist/security/identifier-guard.js +15 -0
- package/dist/security/identifier-guard.js.map +1 -0
- package/dist/security/identity-token-validator.d.ts +3 -0
- package/dist/security/identity-token-validator.d.ts.map +1 -0
- package/dist/security/identity-token-validator.js +121 -0
- package/dist/security/identity-token-validator.js.map +1 -0
- package/dist/security/index.d.ts +14 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +8 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/protection-registry.d.ts +24 -0
- package/dist/security/protection-registry.d.ts.map +1 -0
- package/dist/security/protection-registry.js +35 -0
- package/dist/security/protection-registry.js.map +1 -0
- package/dist/security/rate-limiter.d.ts +23 -0
- package/dist/security/rate-limiter.d.ts.map +1 -0
- package/dist/security/rate-limiter.js +44 -0
- package/dist/security/rate-limiter.js.map +1 -0
- package/dist/security/spec-signing.d.ts +23 -0
- package/dist/security/spec-signing.d.ts.map +1 -0
- package/dist/security/spec-signing.js +62 -0
- package/dist/security/spec-signing.js.map +1 -0
- package/dist/security/spec-validator.d.ts +60 -0
- package/dist/security/spec-validator.d.ts.map +1 -0
- package/dist/security/spec-validator.js +903 -0
- package/dist/security/spec-validator.js.map +1 -0
- package/dist/security/state-protection.d.ts +23 -0
- package/dist/security/state-protection.d.ts.map +1 -0
- package/dist/security/state-protection.js +49 -0
- package/dist/security/state-protection.js.map +1 -0
- package/dist/security/url-whitelist.d.ts +14 -0
- package/dist/security/url-whitelist.d.ts.map +1 -0
- package/dist/security/url-whitelist.js +37 -0
- package/dist/security/url-whitelist.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -0
- package/dist/spec-engine/app-elements.d.ts +5 -0
- package/dist/spec-engine/app-elements.d.ts.map +1 -0
- package/dist/spec-engine/app-elements.js +36 -0
- package/dist/spec-engine/app-elements.js.map +1 -0
- package/dist/spec-engine/app-manifest.d.ts +3 -0
- package/dist/spec-engine/app-manifest.d.ts.map +1 -0
- package/dist/spec-engine/app-manifest.js +132 -0
- package/dist/spec-engine/app-manifest.js.map +1 -0
- package/dist/spec-engine/elements.d.ts +8 -0
- package/dist/spec-engine/elements.d.ts.map +1 -0
- package/dist/spec-engine/elements.js +18 -0
- package/dist/spec-engine/elements.js.map +1 -0
- package/dist/spec-engine/engine.d.ts +3 -0
- package/dist/spec-engine/engine.d.ts.map +1 -0
- package/dist/spec-engine/engine.js +76 -0
- package/dist/spec-engine/engine.js.map +1 -0
- package/dist/spec-engine/handlers/api-handler.d.ts +5 -0
- package/dist/spec-engine/handlers/api-handler.d.ts.map +1 -0
- package/dist/spec-engine/handlers/api-handler.js +111 -0
- package/dist/spec-engine/handlers/api-handler.js.map +1 -0
- package/dist/spec-engine/handlers/app-handler.d.ts +4 -0
- package/dist/spec-engine/handlers/app-handler.d.ts.map +1 -0
- package/dist/spec-engine/handlers/app-handler.js +41 -0
- package/dist/spec-engine/handlers/app-handler.js.map +1 -0
- package/dist/spec-engine/handlers/index.d.ts +8 -0
- package/dist/spec-engine/handlers/index.d.ts.map +1 -0
- package/dist/spec-engine/handlers/index.js +17 -0
- package/dist/spec-engine/handlers/index.js.map +1 -0
- package/dist/spec-engine/handlers/screen-handler.d.ts +4 -0
- package/dist/spec-engine/handlers/screen-handler.d.ts.map +1 -0
- package/dist/spec-engine/handlers/screen-handler.js +34 -0
- package/dist/spec-engine/handlers/screen-handler.js.map +1 -0
- package/dist/spec-engine/manifest.d.ts +11 -0
- package/dist/spec-engine/manifest.d.ts.map +1 -0
- package/dist/spec-engine/manifest.js +76 -0
- package/dist/spec-engine/manifest.js.map +1 -0
- package/dist/spec-engine/types.d.ts +61 -0
- package/dist/spec-engine/types.d.ts.map +1 -0
- package/dist/spec-engine/types.js +2 -0
- package/dist/spec-engine/types.js.map +1 -0
- package/dist/spec-stores/file.d.ts +12 -0
- package/dist/spec-stores/file.d.ts.map +1 -0
- package/dist/spec-stores/file.js +32 -0
- package/dist/spec-stores/file.js.map +1 -0
- package/dist/spec-stores/memory-versioned.d.ts +22 -0
- package/dist/spec-stores/memory-versioned.d.ts.map +1 -0
- package/dist/spec-stores/memory-versioned.js +125 -0
- package/dist/spec-stores/memory-versioned.js.map +1 -0
- package/dist/spec-stores/memory.d.ts +10 -0
- package/dist/spec-stores/memory.d.ts.map +1 -0
- package/dist/spec-stores/memory.js +31 -0
- package/dist/spec-stores/memory.js.map +1 -0
- package/dist/spec-stores/sqlserver-versioned.d.ts +44 -0
- package/dist/spec-stores/sqlserver-versioned.d.ts.map +1 -0
- package/dist/spec-stores/sqlserver-versioned.js +253 -0
- package/dist/spec-stores/sqlserver-versioned.js.map +1 -0
- package/dist/spec-stores/sqlserver.d.ts +27 -0
- package/dist/spec-stores/sqlserver.d.ts.map +1 -0
- package/dist/spec-stores/sqlserver.js +78 -0
- package/dist/spec-stores/sqlserver.js.map +1 -0
- package/dist/spec-stores/supabase-versioned.d.ts +38 -0
- package/dist/spec-stores/supabase-versioned.d.ts.map +1 -0
- package/dist/spec-stores/supabase-versioned.js +197 -0
- package/dist/spec-stores/supabase-versioned.js.map +1 -0
- package/dist/spec-stores/supabase.d.ts +18 -0
- package/dist/spec-stores/supabase.d.ts.map +1 -0
- package/dist/spec-stores/supabase.js +68 -0
- package/dist/spec-stores/supabase.js.map +1 -0
- package/dist/state/reserved-paths.d.ts +41 -0
- package/dist/state/reserved-paths.d.ts.map +1 -0
- package/dist/state/reserved-paths.js +40 -0
- package/dist/state/reserved-paths.js.map +1 -0
- package/dist/state/store.d.ts +18 -0
- package/dist/state/store.d.ts.map +1 -0
- package/dist/state/store.js +114 -0
- package/dist/state/store.js.map +1 -0
- package/dist/storage/supabase.d.ts +37 -0
- package/dist/storage/supabase.d.ts.map +1 -0
- package/dist/storage/supabase.js +22 -0
- package/dist/storage/supabase.js.map +1 -0
- package/dist/storage/types.d.ts +22 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/upload-action.d.ts +22 -0
- package/dist/storage/upload-action.d.ts.map +1 -0
- package/dist/storage/upload-action.js +117 -0
- package/dist/storage/upload-action.js.map +1 -0
- package/dist/storage/url.d.ts +17 -0
- package/dist/storage/url.d.ts.map +1 -0
- package/dist/storage/url.js +48 -0
- package/dist/storage/url.js.map +1 -0
- package/dist/streaming/compiler.d.ts +26 -0
- package/dist/streaming/compiler.d.ts.map +1 -0
- package/dist/streaming/compiler.js +54 -0
- package/dist/streaming/compiler.js.map +1 -0
- package/dist/streaming/patch.d.ts +19 -0
- package/dist/streaming/patch.d.ts.map +1 -0
- package/dist/streaming/patch.js +139 -0
- package/dist/streaming/patch.js.map +1 -0
- package/dist/types.d.ts +443 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/util/to-array.d.ts +2 -0
- package/dist/util/to-array.d.ts.map +1 -0
- package/dist/util/to-array.js +14 -0
- package/dist/util/to-array.js.map +1 -0
- package/dist/utils/levenshtein.d.ts +3 -0
- package/dist/utils/levenshtein.d.ts.map +1 -0
- package/dist/utils/levenshtein.js +29 -0
- package/dist/utils/levenshtein.js.map +1 -0
- package/dist/validation/validators.d.ts +20 -0
- package/dist/validation/validators.d.ts.map +1 -0
- package/dist/validation/validators.js +138 -0
- package/dist/validation/validators.js.map +1 -0
- package/dist/versioning/compute-patches.d.ts +7 -0
- package/dist/versioning/compute-patches.d.ts.map +1 -0
- package/dist/versioning/compute-patches.js +62 -0
- package/dist/versioning/compute-patches.js.map +1 -0
- package/dist/versioning/index.d.ts +12 -0
- package/dist/versioning/index.d.ts.map +1 -0
- package/dist/versioning/index.js +7 -0
- package/dist/versioning/index.js.map +1 -0
- package/dist/versioning/promote-gate.d.ts +12 -0
- package/dist/versioning/promote-gate.d.ts.map +1 -0
- package/dist/versioning/promote-gate.js +166 -0
- package/dist/versioning/promote-gate.js.map +1 -0
- package/dist/versioning/rollback.d.ts +26 -0
- package/dist/versioning/rollback.d.ts.map +1 -0
- package/dist/versioning/rollback.js +67 -0
- package/dist/versioning/rollback.js.map +1 -0
- package/dist/versioning/structural-diff.d.ts +8 -0
- package/dist/versioning/structural-diff.d.ts.map +1 -0
- package/dist/versioning/structural-diff.js +287 -0
- package/dist/versioning/structural-diff.js.map +1 -0
- package/dist/versioning/types.d.ts +90 -0
- package/dist/versioning/types.d.ts.map +1 -0
- package/dist/versioning/types.js +2 -0
- package/dist/versioning/types.js.map +1 -0
- package/dist/visibility/evaluator.d.ts +12 -0
- package/dist/visibility/evaluator.d.ts.map +1 -0
- package/dist/visibility/evaluator.js +76 -0
- package/dist/visibility/evaluator.js.map +1 -0
- package/dist/watchers/engine.d.ts +19 -0
- package/dist/watchers/engine.d.ts.map +1 -0
- package/dist/watchers/engine.js +24 -0
- package/dist/watchers/engine.js.map +1 -0
- package/docs/consumer/README.md +44 -0
- package/docs/consumer/WHERE-TO-LOOK.md +94 -0
- package/docs/consumer/ai-context-api.md +195 -0
- package/docs/consumer/ai-context-custom-elements.md +249 -0
- package/docs/consumer/ai-context-patterns.md +254 -0
- package/docs/consumer/ai-context-primitives.md +839 -0
- package/docs/consumer/ai-context-runtime-semantics.md +1075 -0
- package/docs/consumer/ai-context.md +1374 -0
- package/docs/consumer/reference-doc.md +3201 -0
- package/docs/llms.txt +17 -0
- package/docs/wiki/compiled/README.md +33 -0
- package/docs/wiki/compiled/_gaps.md +52 -0
- package/docs/wiki/compiled/_index.md +354 -0
- package/docs/wiki/compiled/_inventory.md +2986 -0
- package/docs/wiki/compiled/_lint.md +66 -0
- package/docs/wiki/compiled/_unmapped.md +3 -0
- package/docs/wiki/compiled/action-apply-preset.md +63 -0
- package/docs/wiki/compiled/action-copy-clipboard.md +45 -0
- package/docs/wiki/compiled/action-drawer.md +50 -0
- package/docs/wiki/compiled/action-export.md +66 -0
- package/docs/wiki/compiled/action-fetch.md +87 -0
- package/docs/wiki/compiled/action-form-control.md +55 -0
- package/docs/wiki/compiled/action-login.md +71 -0
- package/docs/wiki/compiled/action-modal.md +61 -0
- package/docs/wiki/compiled/action-navigate.md +72 -0
- package/docs/wiki/compiled/action-open-url.md +38 -0
- package/docs/wiki/compiled/action-refresh-data-source.md +51 -0
- package/docs/wiki/compiled/action-selection.md +55 -0
- package/docs/wiki/compiled/action-set-locale.md +44 -0
- package/docs/wiki/compiled/action-set-state.md +61 -0
- package/docs/wiki/compiled/action-show-notification.md +65 -0
- package/docs/wiki/compiled/action-submit-form.md +69 -0
- package/docs/wiki/compiled/action-toggle-theme.md +50 -0
- package/docs/wiki/compiled/action-update-tokens.md +63 -0
- package/docs/wiki/compiled/action-upload-file.md +87 -0
- package/docs/wiki/compiled/antipattern-action-chain-no-stop.md +49 -0
- package/docs/wiki/compiled/antipattern-all-filter-wildcard.md +59 -0
- package/docs/wiki/compiled/antipattern-auth-domains-port.md +47 -0
- package/docs/wiki/compiled/antipattern-background-blobs-prop.md +62 -0
- package/docs/wiki/compiled/antipattern-background-css-token.md +53 -0
- package/docs/wiki/compiled/antipattern-checkbox-toggle-value.md +42 -0
- package/docs/wiki/compiled/antipattern-crud-id-collision.md +66 -0
- package/docs/wiki/compiled/antipattern-derive-server-pagination.md +58 -0
- package/docs/wiki/compiled/antipattern-element-variant-top-level.md +57 -0
- package/docs/wiki/compiled/antipattern-event-expression.md +55 -0
- package/docs/wiki/compiled/antipattern-input-type-name.md +43 -0
- package/docs/wiki/compiled/antipattern-mix-fetch-and-datasources.md +48 -0
- package/docs/wiki/compiled/antipattern-modal-drawer-visible.md +57 -0
- package/docs/wiki/compiled/antipattern-motion-entrance-token.md +53 -0
- package/docs/wiki/compiled/antipattern-overflow-hidden-with-shadow.md +50 -0
- package/docs/wiki/compiled/antipattern-required-if-equals.md +59 -0
- package/docs/wiki/compiled/antipattern-row-literal.md +70 -0
- package/docs/wiki/compiled/antipattern-row-template-capture.md +42 -0
- package/docs/wiki/compiled/antipattern-store-save-bypass.md +72 -0
- package/docs/wiki/compiled/antipattern-style-block-duplication.md +56 -0
- package/docs/wiki/compiled/antipattern-submit-form-in-tx-confirm.md +56 -0
- package/docs/wiki/compiled/cli-app-spec.md +53 -0
- package/docs/wiki/compiled/cli-config.md +46 -0
- package/docs/wiki/compiled/cli-contract.md +73 -0
- package/docs/wiki/compiled/cli-delete.md +37 -0
- package/docs/wiki/compiled/cli-docs.md +44 -0
- package/docs/wiki/compiled/cli-elements.md +39 -0
- package/docs/wiki/compiled/cli-existing-spec-edit-loop.md +24 -0
- package/docs/wiki/compiled/cli-history.md +38 -0
- package/docs/wiki/compiled/cli-lint.md +77 -0
- package/docs/wiki/compiled/cli-manifest.md +43 -0
- package/docs/wiki/compiled/cli-overview.md +77 -0
- package/docs/wiki/compiled/cli-patch.md +85 -0
- package/docs/wiki/compiled/cli-programmatic-api.md +73 -0
- package/docs/wiki/compiled/cli-pull.md +39 -0
- package/docs/wiki/compiled/cli-push.md +91 -0
- package/docs/wiki/compiled/cli-tokens.md +38 -0
- package/docs/wiki/compiled/cli-toon.md +44 -0
- package/docs/wiki/compiled/cli-validate.md +52 -0
- package/docs/wiki/compiled/cli-versioning-author.md +58 -0
- package/docs/wiki/compiled/concept-action-chains.md +65 -0
- package/docs/wiki/compiled/concept-action-middleware.md +55 -0
- package/docs/wiki/compiled/concept-animation-build-css.md +43 -0
- package/docs/wiki/compiled/concept-animation-build-rn.md +44 -0
- package/docs/wiki/compiled/concept-animation-caps.md +38 -0
- package/docs/wiki/compiled/concept-animation-cascade.md +89 -0
- package/docs/wiki/compiled/concept-animation-null-semantics.md +55 -0
- package/docs/wiki/compiled/concept-animation-recipes.md +67 -0
- package/docs/wiki/compiled/concept-animation-triggers.md +54 -0
- package/docs/wiki/compiled/concept-animations-engine.md +78 -0
- package/docs/wiki/compiled/concept-api-audit.md +67 -0
- package/docs/wiki/compiled/concept-api-auth.md +67 -0
- package/docs/wiki/compiled/concept-api-catalogs.md +44 -0
- package/docs/wiki/compiled/concept-api-crud-endpoint.md +90 -0
- package/docs/wiki/compiled/concept-api-endpoint-properties.md +40 -0
- package/docs/wiki/compiled/concept-api-endpoints-overview.md +57 -0
- package/docs/wiki/compiled/concept-api-handler-endpoint.md +56 -0
- package/docs/wiki/compiled/concept-api-login-body-contract.md +47 -0
- package/docs/wiki/compiled/concept-api-param-properties.md +44 -0
- package/docs/wiki/compiled/concept-api-public-endpoint.md +33 -0
- package/docs/wiki/compiled/concept-api-query-endpoint.md +53 -0
- package/docs/wiki/compiled/concept-api-scope-filter.md +59 -0
- package/docs/wiki/compiled/concept-api-spec.md +70 -0
- package/docs/wiki/compiled/concept-app-auto-state-paths.md +59 -0
- package/docs/wiki/compiled/concept-app-spec.md +89 -0
- package/docs/wiki/compiled/concept-auth-config.md +71 -0
- package/docs/wiki/compiled/concept-auth-domains.md +55 -0
- package/docs/wiki/compiled/concept-auth-security.md +58 -0
- package/docs/wiki/compiled/concept-auth-state-paths.md +48 -0
- package/docs/wiki/compiled/concept-auto-dark-mode.md +55 -0
- package/docs/wiki/compiled/concept-background-caps.md +42 -0
- package/docs/wiki/compiled/concept-background-layer-kinds.md +80 -0
- package/docs/wiki/compiled/concept-background-recipes.md +53 -0
- package/docs/wiki/compiled/concept-background-stack.md +55 -0
- package/docs/wiki/compiled/concept-blob-layer.md +92 -0
- package/docs/wiki/compiled/concept-blob-motion.md +58 -0
- package/docs/wiki/compiled/concept-blob-shapes-catalog.md +45 -0
- package/docs/wiki/compiled/concept-cli-tokens-inspect.md +38 -0
- package/docs/wiki/compiled/concept-component-variants.md +89 -0
- package/docs/wiki/compiled/concept-cross-tab-sync.md +35 -0
- package/docs/wiki/compiled/concept-css-vs-motion.md +46 -0
- package/docs/wiki/compiled/concept-custom-detection-pattern.md +49 -0
- package/docs/wiki/compiled/concept-custom-element-action-props.md +81 -0
- package/docs/wiki/compiled/concept-custom-element-black-box.md +56 -0
- package/docs/wiki/compiled/concept-custom-element-cache.md +39 -0
- package/docs/wiki/compiled/concept-custom-element-error-boundary.md +33 -0
- package/docs/wiki/compiled/concept-custom-element-prop-cascade.md +60 -0
- package/docs/wiki/compiled/concept-custom-element-repeat.md +53 -0
- package/docs/wiki/compiled/concept-custom-elements.md +71 -0
- package/docs/wiki/compiled/concept-custom-jwt-provider.md +63 -0
- package/docs/wiki/compiled/concept-customize-action.md +33 -0
- package/docs/wiki/compiled/concept-customize-cli-lint-rule.md +30 -0
- package/docs/wiki/compiled/concept-customize-expression-handler.md +30 -0
- package/docs/wiki/compiled/concept-customize-plugin.md +43 -0
- package/docs/wiki/compiled/concept-customize-server-middleware.md +36 -0
- package/docs/wiki/compiled/concept-customize-spec-store.md +42 -0
- package/docs/wiki/compiled/concept-customize-validator-rule.md +35 -0
- package/docs/wiki/compiled/concept-customize-versioned-store.md +37 -0
- package/docs/wiki/compiled/concept-data-sources-lifecycle.md +61 -0
- package/docs/wiki/compiled/concept-data-sources.md +96 -0
- package/docs/wiki/compiled/concept-debugging-runtime-pointers.md +45 -0
- package/docs/wiki/compiled/concept-derive-datasources-mount-order.md +72 -0
- package/docs/wiki/compiled/concept-derive.md +67 -0
- package/docs/wiki/compiled/concept-dna-seeds.md +79 -0
- package/docs/wiki/compiled/concept-editor-commit.md +37 -0
- package/docs/wiki/compiled/concept-editor-save.md +18 -0
- package/docs/wiki/compiled/concept-editor-sessions.md +23 -0
- package/docs/wiki/compiled/concept-element-children-slot.md +54 -0
- package/docs/wiki/compiled/concept-element-definition.md +60 -0
- package/docs/wiki/compiled/concept-element-key.md +56 -0
- package/docs/wiki/compiled/concept-element-prop-definition.md +54 -0
- package/docs/wiki/compiled/concept-element-properties.md +81 -0
- package/docs/wiki/compiled/concept-element-render-node.md +62 -0
- package/docs/wiki/compiled/concept-element-variants.md +67 -0
- package/docs/wiki/compiled/concept-environment-store.md +46 -0
- package/docs/wiki/compiled/concept-export-action.md +56 -0
- package/docs/wiki/compiled/concept-expression-contexts.md +56 -0
- package/docs/wiki/compiled/concept-expression-timing.md +56 -0
- package/docs/wiki/compiled/concept-fetch-interceptors.md +49 -0
- package/docs/wiki/compiled/concept-file-upload-overview.md +55 -0
- package/docs/wiki/compiled/concept-fire-and-forget.md +45 -0
- package/docs/wiki/compiled/concept-font-loading.md +52 -0
- package/docs/wiki/compiled/concept-form-state-paths.md +55 -0
- package/docs/wiki/compiled/concept-forms.md +89 -0
- package/docs/wiki/compiled/concept-identity-accent-application.md +48 -0
- package/docs/wiki/compiled/concept-identity-animations.md +48 -0
- package/docs/wiki/compiled/concept-identity-border-elevation-override.md +56 -0
- package/docs/wiki/compiled/concept-identity-color-scheme.md +74 -0
- package/docs/wiki/compiled/concept-identity-color-weight.md +50 -0
- package/docs/wiki/compiled/concept-identity-glass-rn.md +46 -0
- package/docs/wiki/compiled/concept-identity-gradients.md +56 -0
- package/docs/wiki/compiled/concept-identity-heading-color.md +40 -0
- package/docs/wiki/compiled/concept-identity-helpers.md +61 -0
- package/docs/wiki/compiled/concept-identity-icons.md +46 -0
- package/docs/wiki/compiled/concept-identity-images.md +36 -0
- package/docs/wiki/compiled/concept-identity-label-style.md +36 -0
- package/docs/wiki/compiled/concept-identity-overview.md +72 -0
- package/docs/wiki/compiled/concept-identity-radius-pattern.md +39 -0
- package/docs/wiki/compiled/concept-identity-surface.md +62 -0
- package/docs/wiki/compiled/concept-identity-text-decoration.md +48 -0
- package/docs/wiki/compiled/concept-identity-typography-hierarchy.md +40 -0
- package/docs/wiki/compiled/concept-initial-actions.md +82 -0
- package/docs/wiki/compiled/concept-interactive-states.md +72 -0
- package/docs/wiki/compiled/concept-keyframe-snapshot.md +52 -0
- package/docs/wiki/compiled/concept-layer-background.md +80 -0
- package/docs/wiki/compiled/concept-motion-field.md +77 -0
- package/docs/wiki/compiled/concept-mount-spec-runtime.md +47 -0
- package/docs/wiki/compiled/concept-mythik-renderer.md +76 -0
- package/docs/wiki/compiled/concept-navigation-dirty-guard.md +23 -0
- package/docs/wiki/compiled/concept-navigation.md +75 -0
- package/docs/wiki/compiled/concept-package-layout.md +35 -0
- package/docs/wiki/compiled/concept-path-references.md +53 -0
- package/docs/wiki/compiled/concept-pattern-primitives.md +54 -0
- package/docs/wiki/compiled/concept-preset-dropdown-pattern.md +52 -0
- package/docs/wiki/compiled/concept-presets.md +49 -0
- package/docs/wiki/compiled/concept-primitive-prop-schemas.md +53 -0
- package/docs/wiki/compiled/concept-primitives-overview.md +49 -0
- package/docs/wiki/compiled/concept-promote-gate.md +47 -0
- package/docs/wiki/compiled/concept-prop-cascade.md +76 -0
- package/docs/wiki/compiled/concept-public-package-names.md +33 -0
- package/docs/wiki/compiled/concept-query-envelope.md +55 -0
- package/docs/wiki/compiled/concept-reduced-motion.md +38 -0
- package/docs/wiki/compiled/concept-register-presets.md +44 -0
- package/docs/wiki/compiled/concept-render-error-visibility.md +57 -0
- package/docs/wiki/compiled/concept-repeat-grouped.md +72 -0
- package/docs/wiki/compiled/concept-repeat-selection.md +61 -0
- package/docs/wiki/compiled/concept-repeat.md +81 -0
- package/docs/wiki/compiled/concept-role-access.md +61 -0
- package/docs/wiki/compiled/concept-rollback.md +36 -0
- package/docs/wiki/compiled/concept-rules-catalog.md +49 -0
- package/docs/wiki/compiled/concept-screen-definition.md +51 -0
- package/docs/wiki/compiled/concept-screen-outlet.md +46 -0
- package/docs/wiki/compiled/concept-session-persistence.md +41 -0
- package/docs/wiki/compiled/concept-shape-animations.md +66 -0
- package/docs/wiki/compiled/concept-skeleton-auto.md +58 -0
- package/docs/wiki/compiled/concept-skeleton-manual.md +47 -0
- package/docs/wiki/compiled/concept-source-of-truth-references.md +37 -0
- package/docs/wiki/compiled/concept-source-reading-misleading.md +37 -0
- package/docs/wiki/compiled/concept-spatial-map-editor.md +22 -0
- package/docs/wiki/compiled/concept-spatial-map-zones.md +18 -0
- package/docs/wiki/compiled/concept-spec-engine.md +47 -0
- package/docs/wiki/compiled/concept-spec-store-interface.md +59 -0
- package/docs/wiki/compiled/concept-spec-store-layering.md +51 -0
- package/docs/wiki/compiled/concept-spec-stores-catalog.md +66 -0
- package/docs/wiki/compiled/concept-spec-structure.md +94 -0
- package/docs/wiki/compiled/concept-spec-types.md +76 -0
- package/docs/wiki/compiled/concept-state-change-animation.md +73 -0
- package/docs/wiki/compiled/concept-state-policies.md +44 -0
- package/docs/wiki/compiled/concept-state-protection.md +51 -0
- package/docs/wiki/compiled/concept-storage-adapter.md +69 -0
- package/docs/wiki/compiled/concept-storage-custom-names.md +69 -0
- package/docs/wiki/compiled/concept-storage-evolution.md +32 -0
- package/docs/wiki/compiled/concept-storage-idempotency.md +35 -0
- package/docs/wiki/compiled/concept-storage-overview.md +81 -0
- package/docs/wiki/compiled/concept-storage-postgres-jsonb.md +53 -0
- package/docs/wiki/compiled/concept-storage-postgres-triggers.md +60 -0
- package/docs/wiki/compiled/concept-storage-table-environments.md +40 -0
- package/docs/wiki/compiled/concept-storage-table-screens.md +44 -0
- package/docs/wiki/compiled/concept-storage-table-versions.md +50 -0
- package/docs/wiki/compiled/concept-storage-verification.md +57 -0
- package/docs/wiki/compiled/concept-template-children-marker.md +56 -0
- package/docs/wiki/compiled/concept-template-interpolation.md +60 -0
- package/docs/wiki/compiled/concept-templates-vs-variants.md +80 -0
- package/docs/wiki/compiled/concept-templates.md +93 -0
- package/docs/wiki/compiled/concept-token-categories.md +58 -0
- package/docs/wiki/compiled/concept-token-system.md +61 -0
- package/docs/wiki/compiled/concept-transaction-phase-timing.md +47 -0
- package/docs/wiki/compiled/concept-transaction-rollback.md +38 -0
- package/docs/wiki/compiled/concept-transaction-snapshot.md +37 -0
- package/docs/wiki/compiled/concept-transactions.md +72 -0
- package/docs/wiki/compiled/concept-validation-checks.md +63 -0
- package/docs/wiki/compiled/concept-validators-catalog.md +76 -0
- package/docs/wiki/compiled/concept-versioned-store.md +65 -0
- package/docs/wiki/compiled/concept-versioning-snapshots-patches.md +61 -0
- package/docs/wiki/compiled/concept-visibility.md +55 -0
- package/docs/wiki/compiled/concept-web-only-recipes.md +37 -0
- package/docs/wiki/compiled/concept-where-to-look.md +78 -0
- package/docs/wiki/compiled/expression-and-or-not.md +68 -0
- package/docs/wiki/compiled/expression-array.md +111 -0
- package/docs/wiki/compiled/expression-auth.md +83 -0
- package/docs/wiki/compiled/expression-binditem.md +52 -0
- package/docs/wiki/compiled/expression-bindstate.md +63 -0
- package/docs/wiki/compiled/expression-breakpoint.md +71 -0
- package/docs/wiki/compiled/expression-computed.md +52 -0
- package/docs/wiki/compiled/expression-cond.md +78 -0
- package/docs/wiki/compiled/expression-date.md +66 -0
- package/docs/wiki/compiled/expression-format.md +79 -0
- package/docs/wiki/compiled/expression-group.md +84 -0
- package/docs/wiki/compiled/expression-i18n.md +53 -0
- package/docs/wiki/compiled/expression-item-index.md +72 -0
- package/docs/wiki/compiled/expression-let-ref.md +87 -0
- package/docs/wiki/compiled/expression-math.md +67 -0
- package/docs/wiki/compiled/expression-platform.md +68 -0
- package/docs/wiki/compiled/expression-prop.md +89 -0
- package/docs/wiki/compiled/expression-selection.md +58 -0
- package/docs/wiki/compiled/expression-state.md +70 -0
- package/docs/wiki/compiled/expression-switch.md +68 -0
- package/docs/wiki/compiled/expression-template.md +71 -0
- package/docs/wiki/compiled/expression-token.md +67 -0
- package/docs/wiki/compiled/path-app-screens.md +55 -0
- package/docs/wiki/compiled/path-data-source-paths.md +44 -0
- package/docs/wiki/compiled/path-forms.md +38 -0
- package/docs/wiki/compiled/path-login.md +57 -0
- package/docs/wiki/compiled/path-navigation.md +62 -0
- package/docs/wiki/compiled/path-presets-available.md +44 -0
- package/docs/wiki/compiled/path-tokens.md +56 -0
- package/docs/wiki/compiled/path-tx-result-error.md +56 -0
- package/docs/wiki/compiled/path-ui-device.md +53 -0
- package/docs/wiki/compiled/path-ui-loading-error.md +40 -0
- package/docs/wiki/compiled/path-ui-modals-drawers.md +46 -0
- package/docs/wiki/compiled/path-ui-selected-row.md +92 -0
- package/docs/wiki/compiled/path-uploads.md +32 -0
- package/docs/wiki/compiled/pattern-cross-screen-data-flow.md +83 -0
- package/docs/wiki/compiled/pattern-fetch-vs-datasources.md +63 -0
- package/docs/wiki/compiled/pattern-file-upload-auto.md +61 -0
- package/docs/wiki/compiled/pattern-file-upload-manual.md +59 -0
- package/docs/wiki/compiled/pattern-form-validation-cross-field.md +58 -0
- package/docs/wiki/compiled/pattern-form-validation.md +58 -0
- package/docs/wiki/compiled/pattern-fullstack-coherence.md +49 -0
- package/docs/wiki/compiled/pattern-git-vs-db-versioning.md +55 -0
- package/docs/wiki/compiled/pattern-identity-aware-spec.md +70 -0
- package/docs/wiki/compiled/pattern-loading-content-empty.md +66 -0
- package/docs/wiki/compiled/pattern-login-body-template.md +47 -0
- package/docs/wiki/compiled/pattern-login-screen.md +83 -0
- package/docs/wiki/compiled/pattern-push-vs-patch.md +54 -0
- package/docs/wiki/compiled/pattern-reusable-components.md +67 -0
- package/docs/wiki/compiled/pattern-tx-create.md +76 -0
- package/docs/wiki/compiled/pattern-tx-delete.md +50 -0
- package/docs/wiki/compiled/pattern-tx-toggle.md +45 -0
- package/docs/wiki/compiled/pattern-tx-update.md +68 -0
- package/docs/wiki/compiled/primitive-accordion.md +46 -0
- package/docs/wiki/compiled/primitive-area-chart.md +35 -0
- package/docs/wiki/compiled/primitive-audio-player.md +27 -0
- package/docs/wiki/compiled/primitive-bar-chart.md +34 -0
- package/docs/wiki/compiled/primitive-box.md +58 -0
- package/docs/wiki/compiled/primitive-button.md +55 -0
- package/docs/wiki/compiled/primitive-camera.md +39 -0
- package/docs/wiki/compiled/primitive-checkbox.md +62 -0
- package/docs/wiki/compiled/primitive-divider.md +31 -0
- package/docs/wiki/compiled/primitive-drawer.md +44 -0
- package/docs/wiki/compiled/primitive-file-upload.md +65 -0
- package/docs/wiki/compiled/primitive-grid.md +48 -0
- package/docs/wiki/compiled/primitive-icon.md +106 -0
- package/docs/wiki/compiled/primitive-image.md +49 -0
- package/docs/wiki/compiled/primitive-input.md +81 -0
- package/docs/wiki/compiled/primitive-kanban-board.md +30 -0
- package/docs/wiki/compiled/primitive-line-chart.md +33 -0
- package/docs/wiki/compiled/primitive-list.md +34 -0
- package/docs/wiki/compiled/primitive-modal.md +51 -0
- package/docs/wiki/compiled/primitive-pie-chart.md +32 -0
- package/docs/wiki/compiled/primitive-screen-outlet.md +42 -0
- package/docs/wiki/compiled/primitive-screen.md +43 -0
- package/docs/wiki/compiled/primitive-scroll.md +33 -0
- package/docs/wiki/compiled/primitive-select.md +76 -0
- package/docs/wiki/compiled/primitive-signature.md +40 -0
- package/docs/wiki/compiled/primitive-skeleton.md +48 -0
- package/docs/wiki/compiled/primitive-slider.md +47 -0
- package/docs/wiki/compiled/primitive-spacer.md +33 -0
- package/docs/wiki/compiled/primitive-spatial-map.md +26 -0
- package/docs/wiki/compiled/primitive-stack.md +46 -0
- package/docs/wiki/compiled/primitive-table.md +127 -0
- package/docs/wiki/compiled/primitive-tabs.md +52 -0
- package/docs/wiki/compiled/primitive-text.md +59 -0
- package/docs/wiki/compiled/primitive-textarea.md +44 -0
- package/docs/wiki/compiled/primitive-toast-container.md +44 -0
- package/docs/wiki/compiled/primitive-toggle.md +46 -0
- package/docs/wiki/compiled/primitive-touchable.md +40 -0
- package/docs/wiki/compiled/primitive-wizard.md +43 -0
- package/package.json +58 -8
|
@@ -0,0 +1,1097 @@
|
|
|
1
|
+
import { evaluateVisibility } from '../visibility/evaluator.js';
|
|
2
|
+
import { expandElementToSpec, resolveElementProps } from '../elements/composer.js';
|
|
3
|
+
import { resolveTokens } from '../design/tokens.js';
|
|
4
|
+
import { scanDeps, createRenderCache } from './deps.js';
|
|
5
|
+
import { isOnLazyPath, getParsedLazyPaths } from './lazy-paths.js';
|
|
6
|
+
import { PRIMITIVE_PROP_SCHEMAS } from './prop-schemas.js';
|
|
7
|
+
import { resolveVariant } from './variants.js';
|
|
8
|
+
import { mergeElementAnimations } from '../design/animation/cascade.js';
|
|
9
|
+
export function createRenderEngine(config) {
|
|
10
|
+
const { resolver, primitiveRegistry, tokens, elementRegistry } = config;
|
|
11
|
+
// Selective re-render: dependency-tracked prop cache
|
|
12
|
+
const renderCache = createRenderCache();
|
|
13
|
+
let activeChangedPaths;
|
|
14
|
+
// Task 19: Cache of previous mergedProps per custom-element instance (by elementId).
|
|
15
|
+
// On each dispatch, diff with current mergedProps; for each changed key, add
|
|
16
|
+
// /__prop/<name> to the active changed-paths set so inner-primitive caches
|
|
17
|
+
// (which track $prop refs via scanDeps sentinels) invalidate.
|
|
18
|
+
//
|
|
19
|
+
// Diff uses SHALLOW reference equality — `prev[k] !== curr[k]`. This is
|
|
20
|
+
// correct for scalar props (string/number/boolean). For object/array props
|
|
21
|
+
// sourced from $state that produce new references each render, the diff
|
|
22
|
+
// will over-invalidate (invalidate every render even when contents are
|
|
23
|
+
// equal). A future deep-equality pass could narrow this, but the cost of
|
|
24
|
+
// running structural comparisons on every dispatch may outweigh the benefit;
|
|
25
|
+
// leave as shallow for now and revisit if profiling shows regressions.
|
|
26
|
+
//
|
|
27
|
+
// Eviction: cleared when handleInvisible fires for the elementId (the
|
|
28
|
+
// element becomes hidden). Entry is rebuilt on the next visible render.
|
|
29
|
+
const instancePropsCache = new Map();
|
|
30
|
+
// Track elements that returned null (hidden) in the previous render.
|
|
31
|
+
// When they become visible again, their cache must be invalidated
|
|
32
|
+
// because state may have changed while they were hidden.
|
|
33
|
+
const hiddenElements = new Set();
|
|
34
|
+
// Selection context propagated from repeat.selection to child elements.
|
|
35
|
+
// Set when entering a repeat with selection config, available to $selection expressions.
|
|
36
|
+
let activeSelectionContext;
|
|
37
|
+
/** Resolve tokens with active theme mode (reads /preferences/theme from state) */
|
|
38
|
+
function getActiveTokens() {
|
|
39
|
+
if (!tokens)
|
|
40
|
+
return undefined;
|
|
41
|
+
const theme = resolver.resolve({ $state: '/preferences/theme' });
|
|
42
|
+
if (theme && tokens.modes?.[theme]) {
|
|
43
|
+
return resolveTokens(tokens, theme);
|
|
44
|
+
}
|
|
45
|
+
return tokens;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the identity-level animations for the cascade's top tier (plan
|
|
49
|
+
* 3 Task 15). Reads `tokens.identity.animations` from the theme-active
|
|
50
|
+
* token tree. Returns `undefined` when tokens are absent, identity is
|
|
51
|
+
* absent, or the animations field is absent — all of which are
|
|
52
|
+
* inheritance-neutral to the cascade (pass-through).
|
|
53
|
+
*
|
|
54
|
+
* Whole-field `null` coercion (M1 review fix): when
|
|
55
|
+
* `tokens.identity.animations === null`, we coerce to `undefined` so the
|
|
56
|
+
* cascade treats identity as not-participating (matches the decision
|
|
57
|
+
* table's "whole-field null = inheritance-neutral" contract). Per-trigger
|
|
58
|
+
* null inside a non-null object is preserved — those DO disable.
|
|
59
|
+
*/
|
|
60
|
+
function getIdentityAnimations() {
|
|
61
|
+
const activeTokens = getActiveTokens();
|
|
62
|
+
if (!activeTokens)
|
|
63
|
+
return undefined;
|
|
64
|
+
const identity = activeTokens.identity;
|
|
65
|
+
if (!identity)
|
|
66
|
+
return undefined;
|
|
67
|
+
if (identity.animations === null)
|
|
68
|
+
return undefined;
|
|
69
|
+
return identity.animations;
|
|
70
|
+
}
|
|
71
|
+
/** Track $bindState paths found during prop resolution */
|
|
72
|
+
const bindings = new Map(); // propName → statePath
|
|
73
|
+
let activeLazyPaths = [];
|
|
74
|
+
/**
|
|
75
|
+
* Deep resolver for expression trees. Single unified resolver that
|
|
76
|
+
* collapsed what used to be three variants (resolveDeep +
|
|
77
|
+
* resolveDeepWithContext + resolveDeepWithProps).
|
|
78
|
+
*
|
|
79
|
+
* Signature: `(value, propName?, propContext?, item?, index?)`.
|
|
80
|
+
*
|
|
81
|
+
* - `propName`: set only at top-level prop keys (drives $bindState
|
|
82
|
+
* tracking). Undefined for recursive/array positions.
|
|
83
|
+
* - `propContext`: the mergedProps of the nearest enclosing custom
|
|
84
|
+
* element expansion, threaded so $prop expressions inside inner
|
|
85
|
+
* primitives resolve against the correct scope. Undefined outside
|
|
86
|
+
* any custom-element expansion.
|
|
87
|
+
* - `item` / `index`: repeat context forwarded to $item / $index
|
|
88
|
+
* expressions.
|
|
89
|
+
*
|
|
90
|
+
* Param order is legacy from the pre-unification resolveDeep signature
|
|
91
|
+
* (propName came first). A frequency-first reorder has been considered
|
|
92
|
+
* but deferred — the current callers are stable and the noise is bounded.
|
|
93
|
+
*/
|
|
94
|
+
function resolveDeep(value, propName, propContext, item, index, currentPath = []) {
|
|
95
|
+
if (value === null || value === undefined)
|
|
96
|
+
return value;
|
|
97
|
+
if (typeof value !== 'object')
|
|
98
|
+
return value;
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
return value.map((v, i) => {
|
|
101
|
+
const nextPath = [...currentPath, i];
|
|
102
|
+
if (isOnLazyPath(nextPath, activeLazyPaths))
|
|
103
|
+
return v;
|
|
104
|
+
return resolveDeep(v, undefined, propContext, item, index, nextPath);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const obj = value;
|
|
108
|
+
// Detect $bindState and track the binding path
|
|
109
|
+
if ('$bindState' in obj && propName) {
|
|
110
|
+
bindings.set(propName, obj.$bindState);
|
|
111
|
+
}
|
|
112
|
+
// If it has a $-key, it's an expression — resolve it with full context.
|
|
113
|
+
const hasExprKey = Object.keys(obj).some((k) => k.startsWith('$'));
|
|
114
|
+
if (hasExprKey) {
|
|
115
|
+
return resolver.resolve(value, {
|
|
116
|
+
item,
|
|
117
|
+
index,
|
|
118
|
+
props: propContext,
|
|
119
|
+
selection: activeSelectionContext,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// Otherwise, recurse
|
|
123
|
+
const resolved = {};
|
|
124
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
125
|
+
const nextPath = [...currentPath, k];
|
|
126
|
+
if (isOnLazyPath(nextPath, activeLazyPaths)) {
|
|
127
|
+
resolved[k] = v; // raw passthrough — dispatcher resolves at press time
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
resolved[k] = resolveDeep(v, undefined, propContext, item, index, nextPath);
|
|
131
|
+
}
|
|
132
|
+
return resolved;
|
|
133
|
+
}
|
|
134
|
+
function isVisible(element, item, index, propContext) {
|
|
135
|
+
if (item !== undefined || propContext !== undefined) {
|
|
136
|
+
return evaluateVisibility(element.visible, (expr) => resolver.resolve(expr, {
|
|
137
|
+
item,
|
|
138
|
+
index,
|
|
139
|
+
props: propContext,
|
|
140
|
+
selection: activeSelectionContext,
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
return evaluateVisibility(element.visible, (expr) => resolver.resolve(expr));
|
|
144
|
+
}
|
|
145
|
+
function resolvePropsWithContext(props, item, index, propContext, lazyPaths = []) {
|
|
146
|
+
if (!props)
|
|
147
|
+
return {};
|
|
148
|
+
bindings.clear();
|
|
149
|
+
activeLazyPaths = lazyPaths;
|
|
150
|
+
const resolved = {};
|
|
151
|
+
for (const [key, value] of Object.entries(props)) {
|
|
152
|
+
if (value && typeof value === 'object' && '$bindState' in value) {
|
|
153
|
+
bindings.set(key, value.$bindState);
|
|
154
|
+
}
|
|
155
|
+
const nextPath = [key];
|
|
156
|
+
if (isOnLazyPath(nextPath, activeLazyPaths)) {
|
|
157
|
+
resolved[key] = value;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
resolved[key] = resolveDeep(value, key, propContext, item, index, nextPath);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
activeLazyPaths = [];
|
|
164
|
+
if (bindings.size > 0)
|
|
165
|
+
resolved._bindings = Object.fromEntries(bindings);
|
|
166
|
+
const activeTokens = getActiveTokens();
|
|
167
|
+
if (activeTokens)
|
|
168
|
+
resolved._tokens = activeTokens;
|
|
169
|
+
return resolved;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Handle invisible elements. If the element has motion.exit or motion.layoutId,
|
|
173
|
+
* return an _exiting RenderNode so the renderer can use AnimatePresence.
|
|
174
|
+
* Otherwise return null (instant unmount, current behavior).
|
|
175
|
+
*/
|
|
176
|
+
function handleInvisible(elementId, element, _spec, itemContext, _indexContext) {
|
|
177
|
+
hiddenElements.add(elementId);
|
|
178
|
+
// Task 19: clear instancePropsCache entry so next render re-diffs from scratch
|
|
179
|
+
// when the element becomes visible again.
|
|
180
|
+
instancePropsCache.delete(elementId);
|
|
181
|
+
const hasExitMotion = element.motion?.exit || element.motion?.layoutId;
|
|
182
|
+
if (!hasExitMotion)
|
|
183
|
+
return null;
|
|
184
|
+
if (!primitiveRegistry.has(element.type))
|
|
185
|
+
return null;
|
|
186
|
+
// Minimal props for exiting node — just enough for the exit animation
|
|
187
|
+
const resolvedProps = {
|
|
188
|
+
_exiting: true,
|
|
189
|
+
};
|
|
190
|
+
// Copy motion config directly (exit values are literals, not expressions)
|
|
191
|
+
if (element.motion) {
|
|
192
|
+
const motionResolved = {};
|
|
193
|
+
if (element.motion.initial)
|
|
194
|
+
motionResolved.initial = element.motion.initial;
|
|
195
|
+
if (element.motion.animate)
|
|
196
|
+
motionResolved.animate = element.motion.animate;
|
|
197
|
+
if (element.motion.exit)
|
|
198
|
+
motionResolved.exit = element.motion.exit;
|
|
199
|
+
if (element.motion.transition)
|
|
200
|
+
motionResolved.transition = element.motion.transition;
|
|
201
|
+
if (element.motion.layoutId)
|
|
202
|
+
motionResolved.layoutId = element.motion.layoutId;
|
|
203
|
+
resolvedProps._motion = motionResolved;
|
|
204
|
+
}
|
|
205
|
+
const primitiveRenderer = primitiveRegistry.get(element.type);
|
|
206
|
+
return primitiveRenderer(resolvedProps, []);
|
|
207
|
+
}
|
|
208
|
+
function renderElement(elementId, spec, itemContext, indexContext, propContext, outerOverride) {
|
|
209
|
+
const element = spec.elements[elementId];
|
|
210
|
+
if (!element)
|
|
211
|
+
return null; // Missing element — skip silently
|
|
212
|
+
try {
|
|
213
|
+
return renderElementInner(elementId, element, spec, itemContext, indexContext, propContext, outerOverride);
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
return {
|
|
217
|
+
type: '_error',
|
|
218
|
+
props: {
|
|
219
|
+
elementId,
|
|
220
|
+
error: err instanceof Error ? err.message : String(err),
|
|
221
|
+
originalType: element.type,
|
|
222
|
+
},
|
|
223
|
+
children: [],
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function renderElementInner(elementId, element, spec, itemContext, indexContext, propContext, outerOverride) {
|
|
228
|
+
// Auto-visibility for modals/drawers: if no explicit visible condition,
|
|
229
|
+
// bind to /ui/modals/{id} or /ui/drawers/{id} automatically.
|
|
230
|
+
// Skip for root elements (test cases may use modal/drawer as root).
|
|
231
|
+
if (element.visible === undefined && elementId !== spec.root) {
|
|
232
|
+
if (element.type === 'modal') {
|
|
233
|
+
const modalState = resolver.resolve({ $state: `/ui/modals/${elementId}` });
|
|
234
|
+
if (!modalState)
|
|
235
|
+
return handleInvisible(elementId, element, spec, itemContext, indexContext);
|
|
236
|
+
}
|
|
237
|
+
else if (element.type === 'drawer') {
|
|
238
|
+
const drawerState = resolver.resolve({ $state: `/ui/drawers/${elementId}` });
|
|
239
|
+
if (!drawerState)
|
|
240
|
+
return handleInvisible(elementId, element, spec, itemContext, indexContext);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Apply outerOverride.visible: consumer's instance-level visibility gates the entire instance.
|
|
244
|
+
// When outerOverride has visible defined, it wins over element.visible for this root call.
|
|
245
|
+
const effectiveVisibleSource = outerOverride?.visible !== undefined
|
|
246
|
+
? { ...element, visible: outerOverride.visible }
|
|
247
|
+
: element;
|
|
248
|
+
if (!isVisible(effectiveVisibleSource, itemContext, indexContext, propContext)) {
|
|
249
|
+
return handleInvisible(elementId, effectiveVisibleSource, spec, itemContext, indexContext);
|
|
250
|
+
}
|
|
251
|
+
// Element is visible — if it was previously hidden, invalidate cache
|
|
252
|
+
// so stale props (resolved with old state) are not reused.
|
|
253
|
+
if (hiddenElements.has(elementId)) {
|
|
254
|
+
hiddenElements.delete(elementId);
|
|
255
|
+
renderCache.clear(elementId);
|
|
256
|
+
}
|
|
257
|
+
// --- Handle repeat (applies to all element types: primitives, custom elements, templates) ---
|
|
258
|
+
// When an element has repeat, we render it once per item.
|
|
259
|
+
// Returns a wrapper node whose children are the repeated items.
|
|
260
|
+
// Each item gets its own render with $item/$index context.
|
|
261
|
+
// Check this BEFORE custom element/template dispatch so repeat works uniformly.
|
|
262
|
+
if (element.repeat && itemContext === undefined) {
|
|
263
|
+
const repeat = element.repeat;
|
|
264
|
+
let items = [];
|
|
265
|
+
if (repeat.source) {
|
|
266
|
+
const data = resolver.resolve(repeat.source);
|
|
267
|
+
items = Array.isArray(data) ? data : [];
|
|
268
|
+
}
|
|
269
|
+
else if (repeat.statePath) {
|
|
270
|
+
const data = resolver.resolve({ $state: repeat.statePath });
|
|
271
|
+
items = Array.isArray(data) ? data : [];
|
|
272
|
+
}
|
|
273
|
+
else if (repeat.count) {
|
|
274
|
+
const count = resolver.resolve(repeat.count);
|
|
275
|
+
items = Array.from({ length: count }, (_, i) => i);
|
|
276
|
+
}
|
|
277
|
+
const isClientGroupBy = typeof repeat.groupBy === 'string' && !repeat.groupKey;
|
|
278
|
+
const isPreGrouped = typeof repeat.groupKey === 'string' && typeof repeat.groupItems === 'string';
|
|
279
|
+
// --- GroupBy modes ---
|
|
280
|
+
if (isClientGroupBy || isPreGrouped) {
|
|
281
|
+
const allNodes = [];
|
|
282
|
+
const groups = [];
|
|
283
|
+
if (isClientGroupBy) {
|
|
284
|
+
// Client-side grouping: group flat items by field value
|
|
285
|
+
const groupField = repeat.groupBy;
|
|
286
|
+
const groupMap = new Map();
|
|
287
|
+
const groupOrder = [];
|
|
288
|
+
for (const item of items) {
|
|
289
|
+
const keyVal = String(item[groupField] ?? '');
|
|
290
|
+
if (!groupMap.has(keyVal)) {
|
|
291
|
+
groupMap.set(keyVal, []);
|
|
292
|
+
groupOrder.push(keyVal);
|
|
293
|
+
}
|
|
294
|
+
groupMap.get(keyVal).push(item);
|
|
295
|
+
}
|
|
296
|
+
for (const keyVal of groupOrder) {
|
|
297
|
+
groups.push({ key: keyVal, items: groupMap.get(keyVal) });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
// Pre-grouped: each item in source IS a group object
|
|
302
|
+
const groupKeyField = repeat.groupKey;
|
|
303
|
+
const groupItemsField = repeat.groupItems;
|
|
304
|
+
for (const groupObj of items) {
|
|
305
|
+
const rec = groupObj;
|
|
306
|
+
const key = rec[groupKeyField];
|
|
307
|
+
const groupItems = Array.isArray(rec[groupItemsField]) ? rec[groupItemsField] : [];
|
|
308
|
+
groups.push({ key, items: groupItems, raw: groupObj });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// Render each group
|
|
312
|
+
for (let gi = 0; gi < groups.length; gi++) {
|
|
313
|
+
const group = groups[gi];
|
|
314
|
+
const groupCtx = { key: group.key, items: group.items, index: gi, raw: group.raw };
|
|
315
|
+
// Group header elements
|
|
316
|
+
if (repeat.groupHeader) {
|
|
317
|
+
for (const headerId of repeat.groupHeader) {
|
|
318
|
+
const headerNode = renderElementWithGroup(headerId, spec, groupCtx);
|
|
319
|
+
if (headerNode) {
|
|
320
|
+
headerNode.key = `group-${gi}-header-${headerId}`;
|
|
321
|
+
allNodes.push(headerNode);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Iterate items with $item/$index context
|
|
326
|
+
const children = element.children ?? [];
|
|
327
|
+
for (let ii = 0; ii < group.items.length; ii++) {
|
|
328
|
+
for (const childId of children) {
|
|
329
|
+
const childNode = renderElement(childId, spec, group.items[ii], ii, propContext);
|
|
330
|
+
if (childNode) {
|
|
331
|
+
childNode.key = repeat.key
|
|
332
|
+
? `group-${gi}-${String(group.items[ii]?.[repeat.key] ?? ii)}`
|
|
333
|
+
: `group-${gi}-item-${ii}`;
|
|
334
|
+
allNodes.push(childNode);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Group footer elements
|
|
339
|
+
if (repeat.groupFooter) {
|
|
340
|
+
for (const footerId of repeat.groupFooter) {
|
|
341
|
+
const footerNode = renderElementWithGroup(footerId, spec, groupCtx);
|
|
342
|
+
if (footerNode) {
|
|
343
|
+
footerNode.key = `group-${gi}-footer-${footerId}`;
|
|
344
|
+
allNodes.push(footerNode);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// Global footer (after all groups)
|
|
350
|
+
if (repeat.footer) {
|
|
351
|
+
for (const footerId of repeat.footer) {
|
|
352
|
+
const footerNode = renderElement(footerId, spec, undefined, undefined, propContext);
|
|
353
|
+
if (footerNode) {
|
|
354
|
+
footerNode.key = `global-footer-${footerId}`;
|
|
355
|
+
allNodes.push(footerNode);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const stackRenderer = primitiveRegistry.get('stack');
|
|
360
|
+
const activeTokens4 = getActiveTokens();
|
|
361
|
+
return stackRenderer({ direction: 'vertical', ...(activeTokens4 ? { _tokens: activeTokens4 } : {}) }, allNodes);
|
|
362
|
+
}
|
|
363
|
+
// --- Standard flat repeat (no groupBy) ---
|
|
364
|
+
// Activate selection context for child elements if repeat has selection config
|
|
365
|
+
const prevSelection = activeSelectionContext;
|
|
366
|
+
if (repeat.selection) {
|
|
367
|
+
activeSelectionContext = repeat.selection;
|
|
368
|
+
}
|
|
369
|
+
const repeatedNodes = [];
|
|
370
|
+
for (let i = 0; i < items.length; i++) {
|
|
371
|
+
const node = renderElement(elementId, spec, items[i], i, propContext);
|
|
372
|
+
if (node) {
|
|
373
|
+
node.key = repeat.key
|
|
374
|
+
? String(items[i]?.[repeat.key] ?? i)
|
|
375
|
+
: String(i);
|
|
376
|
+
repeatedNodes.push(node);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// Restore previous selection context
|
|
380
|
+
activeSelectionContext = prevSelection;
|
|
381
|
+
const stackRenderer = primitiveRegistry.get('stack');
|
|
382
|
+
const activeTokens4 = getActiveTokens();
|
|
383
|
+
return stackRenderer({ direction: 'vertical', ...(activeTokens4 ? { _tokens: activeTokens4 } : {}) }, repeatedNodes);
|
|
384
|
+
}
|
|
385
|
+
// --- Handle custom elements (Layer 3) ---
|
|
386
|
+
// Dispatch a custom element type to the main render path via delegation
|
|
387
|
+
// (plan custom-element-cascade Task 11).
|
|
388
|
+
//
|
|
389
|
+
// Pipeline:
|
|
390
|
+
// 1. Resolve consumer props against the enclosing propContext (so nested
|
|
391
|
+
// custom elements can thread $prop references through).
|
|
392
|
+
// 2. Look up variant: ElementDefinition.variants first, tokens.components
|
|
393
|
+
// as theme-level fallback.
|
|
394
|
+
// 3. Merge variant.props + definition defaults + consumer props →
|
|
395
|
+
// mergedProps (consumer wins last).
|
|
396
|
+
// 4. Expand the render tree to a flat spec, slotting consumer children
|
|
397
|
+
// at $children markers. Consumer children's original IDs appear in
|
|
398
|
+
// the expansion; merge the consumer child elements into the expanded
|
|
399
|
+
// spec so renderElement can find them during recursion. (Simplification
|
|
400
|
+
// note: consumer children render with mergedProps as propContext
|
|
401
|
+
// rather than the enclosing scope. This matters only when a consumer
|
|
402
|
+
// child uses $prop — uncommon enough to accept for Task 11 MVP.)
|
|
403
|
+
// 5. Construct outerOverride carrying the consumer's instance-level fields
|
|
404
|
+
// (animations, interaction states, style, visible, key) + the variant's
|
|
405
|
+
// animations for the cascade's variant slot.
|
|
406
|
+
// 6. Delegate to renderElement with propContext = mergedProps + outerOverride.
|
|
407
|
+
if (!primitiveRegistry.has(element.type) && elementRegistry?.has(element.type)) {
|
|
408
|
+
const definition = elementRegistry.get(element.type);
|
|
409
|
+
const consumerRawProps = element.props ?? {};
|
|
410
|
+
// 1. Resolve consumer props against enclosing propContext.
|
|
411
|
+
const resolvedConsumerProps = resolvePropsWithContext(consumerRawProps, itemContext, indexContext, propContext);
|
|
412
|
+
const { _bindings: _b, _tokens: _t, ...cleanConsumerProps } = resolvedConsumerProps;
|
|
413
|
+
// 2. Variant lookup: ElementDefinition first, tokens.components fallback.
|
|
414
|
+
const variantName = cleanConsumerProps.variant;
|
|
415
|
+
let variant;
|
|
416
|
+
if (variantName) {
|
|
417
|
+
const defVariant = definition.variants?.[variantName];
|
|
418
|
+
const activeTokens = getActiveTokens();
|
|
419
|
+
const themeVariant = activeTokens?.components?.[definition.type]?.variants?.[variantName];
|
|
420
|
+
variant = defVariant ?? themeVariant;
|
|
421
|
+
if (!variant && activeTokens) {
|
|
422
|
+
console.warn(`[Mythik] Variant "${variantName}" not found for custom element "${definition.type}" (neither ElementDefinition.variants nor tokens.components)`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// 3. Merge: variant.props → definition defaults → consumer props (later wins).
|
|
426
|
+
const propsWithVariant = {
|
|
427
|
+
...(variant?.props ?? {}),
|
|
428
|
+
...cleanConsumerProps,
|
|
429
|
+
};
|
|
430
|
+
const mergedProps = resolveElementProps(definition, propsWithVariant);
|
|
431
|
+
// 4. Expand, slotting consumer children.
|
|
432
|
+
const consumerChildrenIds = element.children ?? [];
|
|
433
|
+
const expandedSpec = expandElementToSpec(definition, mergedProps, `${elementId}_el`, consumerChildrenIds);
|
|
434
|
+
// Propagate spec.templates so template types used INSIDE a custom element's
|
|
435
|
+
// render tree still resolve via the main template dispatch. Templates live at
|
|
436
|
+
// spec scope, not custom-element scope — no shadowing concerns.
|
|
437
|
+
if (spec.templates) {
|
|
438
|
+
expandedSpec.templates = spec.templates;
|
|
439
|
+
}
|
|
440
|
+
// Propagate spec.elements (non-conflicting) so that:
|
|
441
|
+
// - Consumer children IDs ($children marker slotted) resolve via the
|
|
442
|
+
// unified render path.
|
|
443
|
+
// - Spec-level elements referenced by template children arrays
|
|
444
|
+
// (e.g. template.children: ['myId']) are findable during recursion.
|
|
445
|
+
// expandedSpec.elements keys take priority — custom-element internals win
|
|
446
|
+
// over any same-named spec element (avoids ID collision regressions).
|
|
447
|
+
for (const [id, el] of Object.entries(spec.elements)) {
|
|
448
|
+
if (!expandedSpec.elements[id]) {
|
|
449
|
+
expandedSpec.elements[id] = el;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// 5. Construct outerOverride for the expansion's root primitive.
|
|
453
|
+
const outerOverride = {
|
|
454
|
+
animations: element.animations,
|
|
455
|
+
variantAnimations: variant?.animations,
|
|
456
|
+
hover: element.hover ?? variant?.hover,
|
|
457
|
+
active: element.active ?? variant?.active,
|
|
458
|
+
focus: element.focus ?? variant?.focus,
|
|
459
|
+
transition: (element.transition ?? variant?.transition),
|
|
460
|
+
motion: element.motion,
|
|
461
|
+
style: element.style ?? variant?.style,
|
|
462
|
+
visible: element.visible,
|
|
463
|
+
key: element.key,
|
|
464
|
+
};
|
|
465
|
+
// 6. Task 19: diff consumer props and inject /__prop/<name> sentinels
|
|
466
|
+
// into activeChangedPaths so inner primitives with $prop deps invalidate.
|
|
467
|
+
const prevMergedProps = instancePropsCache.get(elementId);
|
|
468
|
+
let expandedChangedPaths;
|
|
469
|
+
if (prevMergedProps) {
|
|
470
|
+
const propChanged = new Set();
|
|
471
|
+
const allKeys = new Set([...Object.keys(prevMergedProps), ...Object.keys(mergedProps)]);
|
|
472
|
+
for (const k of allKeys) {
|
|
473
|
+
if (prevMergedProps[k] !== mergedProps[k]) {
|
|
474
|
+
propChanged.add(`/__prop/${k}`);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
if (propChanged.size > 0) {
|
|
478
|
+
expandedChangedPaths = new Set([...(activeChangedPaths ?? []), ...propChanged]);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
instancePropsCache.set(elementId, mergedProps);
|
|
482
|
+
// Temporarily swap activeChangedPaths during the expansion render so
|
|
483
|
+
// inner primitives see the augmented set.
|
|
484
|
+
const prevActiveChangedPaths = activeChangedPaths;
|
|
485
|
+
if (expandedChangedPaths)
|
|
486
|
+
activeChangedPaths = expandedChangedPaths;
|
|
487
|
+
try {
|
|
488
|
+
return renderElement(expandedSpec.root, expandedSpec, itemContext, indexContext, mergedProps, outerOverride);
|
|
489
|
+
}
|
|
490
|
+
finally {
|
|
491
|
+
activeChangedPaths = prevActiveChangedPaths;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
// --- Handle spec-level templates (C.1) ---
|
|
495
|
+
// If type is not a primitive and not a custom element, check spec.templates.
|
|
496
|
+
// Templates are inline reusable element definitions with $prop parameterization.
|
|
497
|
+
if (!primitiveRegistry.has(element.type) && spec.templates?.[element.type]) {
|
|
498
|
+
const template = spec.templates[element.type];
|
|
499
|
+
const consumerProps = element.props ?? {};
|
|
500
|
+
// Resolve consumer props (they may contain $state, $item, etc.)
|
|
501
|
+
const resolvedConsumerProps = resolvePropsWithContext(consumerProps, itemContext, indexContext, propContext);
|
|
502
|
+
const { _bindings: _b, _tokens: _t, ...cleanConsumerProps } = resolvedConsumerProps;
|
|
503
|
+
// Merge: consumer props override template defaults
|
|
504
|
+
const mergedProps = { ...(template.defaults ?? {}), ...cleanConsumerProps };
|
|
505
|
+
// Resolve template props with $prop context
|
|
506
|
+
const templateProps = template.props ?? {};
|
|
507
|
+
const resolvedTemplateProps = {};
|
|
508
|
+
for (const [key, value] of Object.entries(templateProps)) {
|
|
509
|
+
resolvedTemplateProps[key] = resolveDeep(value, undefined, mergedProps, itemContext, indexContext);
|
|
510
|
+
}
|
|
511
|
+
// Resolve template style with $prop context
|
|
512
|
+
if (template.style) {
|
|
513
|
+
const resolvedStyle = {};
|
|
514
|
+
for (const [key, value] of Object.entries(template.style)) {
|
|
515
|
+
resolvedStyle[key] = resolveDeep(value, undefined, mergedProps, itemContext, indexContext);
|
|
516
|
+
}
|
|
517
|
+
resolvedTemplateProps.style = resolvedStyle;
|
|
518
|
+
}
|
|
519
|
+
// Resolve template.animations with $prop context (plan 3 Task 13).
|
|
520
|
+
// Three-branch semantics:
|
|
521
|
+
// - undefined (field absent): don't emit `animations` on the rendered
|
|
522
|
+
// props at all — cascade treats `undefined` as inheritance-neutral
|
|
523
|
+
// (pass-through from prior levels).
|
|
524
|
+
// - null (whole-field null): forwarded verbatim — cascade treats
|
|
525
|
+
// whole-field null as "this level contributes nothing", which is
|
|
526
|
+
// the cascade-neutral result. Preserving null here lets consumers
|
|
527
|
+
// distinguish "template explicitly null'd it" (for documentation
|
|
528
|
+
// intent) from "field absent" (inheritance) if they ever need to.
|
|
529
|
+
// - object: recurse via resolveDeep(propContext=mergedProps) so `$prop.X` inside
|
|
530
|
+
// recipe/duration/etc. is interpolated against mergedProps before
|
|
531
|
+
// the cascade merges across levels. Per-trigger `null` values are
|
|
532
|
+
// preserved through traversal (resolveDeep short-circuits on null).
|
|
533
|
+
if ('animations' in template) {
|
|
534
|
+
const anims = template.animations;
|
|
535
|
+
if (anims === null) {
|
|
536
|
+
resolvedTemplateProps.animations = null;
|
|
537
|
+
}
|
|
538
|
+
else if (anims !== undefined) {
|
|
539
|
+
resolvedTemplateProps.animations = resolveDeep(anims, undefined, mergedProps, itemContext, indexContext);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// Cascade merge for the template branch (plan 3 Task 15): layer
|
|
543
|
+
// identity.animations UNDER template.animations if identity is set.
|
|
544
|
+
// Variant + element levels don't apply here — templates replace the
|
|
545
|
+
// element.type at dispatch so there's no element.animations in-scope,
|
|
546
|
+
// and variants are resolved in the regular (non-template) branch only.
|
|
547
|
+
// A future task can extend this model to support variant+element on
|
|
548
|
+
// template-based elements; for now, identity→template is the MVP.
|
|
549
|
+
const identityAnimationsT = getIdentityAnimations();
|
|
550
|
+
const templateAnimationsT = resolvedTemplateProps.animations;
|
|
551
|
+
// I2 review fix: also read element.animations on template-typed
|
|
552
|
+
// elements. The consumer can declare a per-trigger override on the
|
|
553
|
+
// element itself (e.g. `{ type: 'hero-card', animations: { hover:
|
|
554
|
+
// null } }`), and per the cascade's decision table element wins over
|
|
555
|
+
// template. Resolve expressions the same way the regular branch does.
|
|
556
|
+
const rawElementAnimationsT = element.animations;
|
|
557
|
+
const elementAnimationsT = rawElementAnimationsT === null || rawElementAnimationsT === undefined
|
|
558
|
+
? rawElementAnimationsT
|
|
559
|
+
: resolveDeep(rawElementAnimationsT, undefined, propContext, itemContext, indexContext);
|
|
560
|
+
const cascadeTemplateHasAny = identityAnimationsT !== undefined ||
|
|
561
|
+
templateAnimationsT !== undefined ||
|
|
562
|
+
elementAnimationsT !== undefined;
|
|
563
|
+
if (cascadeTemplateHasAny) {
|
|
564
|
+
const mergedT = mergeElementAnimations({
|
|
565
|
+
identity: identityAnimationsT,
|
|
566
|
+
template: templateAnimationsT,
|
|
567
|
+
element: elementAnimationsT,
|
|
568
|
+
});
|
|
569
|
+
// Emit merge result (object OR null) whenever at least one cascade
|
|
570
|
+
// level contributed — matches the regular-branch emission rule for
|
|
571
|
+
// cross-branch consistency.
|
|
572
|
+
resolvedTemplateProps.animations = mergedT;
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
delete resolvedTemplateProps.animations;
|
|
576
|
+
}
|
|
577
|
+
const activeTokensT = getActiveTokens();
|
|
578
|
+
if (activeTokensT)
|
|
579
|
+
resolvedTemplateProps._tokens = activeTokensT;
|
|
580
|
+
// Resolve children: handle $children marker
|
|
581
|
+
const templateChildren = template.children ?? [];
|
|
582
|
+
const childNodes = [];
|
|
583
|
+
for (const childId of templateChildren) {
|
|
584
|
+
if (childId === '$children') {
|
|
585
|
+
// Replace with the consuming element's actual children
|
|
586
|
+
const consumerChildren = element.children ?? [];
|
|
587
|
+
for (const ccId of consumerChildren) {
|
|
588
|
+
const ccNode = renderElement(ccId, spec, itemContext, indexContext, propContext);
|
|
589
|
+
if (ccNode)
|
|
590
|
+
childNodes.push(ccNode);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
// Pass template's mergedProps as propContext so $prop references inside
|
|
595
|
+
// child elements (e.g. { content: { $prop: 'heading' } }) resolve
|
|
596
|
+
// against the template's own prop values rather than the outer scope.
|
|
597
|
+
const childNode = renderElement(childId, spec, itemContext, indexContext, mergedProps);
|
|
598
|
+
if (childNode)
|
|
599
|
+
childNodes.push(childNode);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
// If template has no children array but consuming element does, render consumer children
|
|
603
|
+
if (templateChildren.length === 0 && element.children) {
|
|
604
|
+
for (const ccId of element.children) {
|
|
605
|
+
const ccNode = renderElement(ccId, spec, itemContext, indexContext, propContext);
|
|
606
|
+
if (ccNode)
|
|
607
|
+
childNodes.push(ccNode);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
// Render using the template's underlying primitive type
|
|
611
|
+
if (!primitiveRegistry.has(template.type)) {
|
|
612
|
+
return {
|
|
613
|
+
type: '_error',
|
|
614
|
+
props: { elementId, error: `Template "${element.type}" references unknown primitive "${template.type}"`, originalType: element.type },
|
|
615
|
+
children: [],
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
const templateRenderer = primitiveRegistry.get(template.type);
|
|
619
|
+
return templateRenderer(resolvedTemplateProps, childNodes);
|
|
620
|
+
}
|
|
621
|
+
if (!primitiveRegistry.has(element.type)) {
|
|
622
|
+
return {
|
|
623
|
+
type: '_error',
|
|
624
|
+
props: { elementId, error: `No primitive registered for type "${element.type}"`, originalType: element.type },
|
|
625
|
+
children: [],
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
// --- Standard render (or repeat iteration with item context) ---
|
|
629
|
+
// Skip caching for elements inside repeat — their props depend on item context
|
|
630
|
+
// which changes whenever the repeat source array changes.
|
|
631
|
+
const skipCache = itemContext !== undefined;
|
|
632
|
+
const cacheKey = skipCache ? '' : elementId;
|
|
633
|
+
let resolvedProps;
|
|
634
|
+
if (!skipCache && activeChangedPaths && renderCache.get(cacheKey)) {
|
|
635
|
+
if (!renderCache.isDirtyForPaths(cacheKey, activeChangedPaths)) {
|
|
636
|
+
// Element is clean — reuse cached props (same object reference)
|
|
637
|
+
resolvedProps = renderCache.get(cacheKey);
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
// Element is dirty — re-resolve and update cache
|
|
641
|
+
const schema = PRIMITIVE_PROP_SCHEMAS[element.type];
|
|
642
|
+
const lazyPaths = getParsedLazyPaths(element.type, schema?.lazyActionPaths);
|
|
643
|
+
resolvedProps = resolvePropsWithContext(element.props, itemContext, indexContext, propContext, lazyPaths);
|
|
644
|
+
const deps = scanDeps(element.props, lazyPaths);
|
|
645
|
+
if (element.style)
|
|
646
|
+
for (const d of scanDeps(element.style))
|
|
647
|
+
deps.add(d);
|
|
648
|
+
if (element.visible !== undefined && element.visible !== true && element.visible !== false) {
|
|
649
|
+
for (const d of scanDeps({ _vis: element.visible }))
|
|
650
|
+
deps.add(d);
|
|
651
|
+
}
|
|
652
|
+
// Scan interaction fields for state/token dependencies
|
|
653
|
+
if (element.hover)
|
|
654
|
+
for (const d of scanDeps(element.hover))
|
|
655
|
+
deps.add(d);
|
|
656
|
+
if (element.active)
|
|
657
|
+
for (const d of scanDeps(element.active))
|
|
658
|
+
deps.add(d);
|
|
659
|
+
if (element.focus)
|
|
660
|
+
for (const d of scanDeps(element.focus))
|
|
661
|
+
deps.add(d);
|
|
662
|
+
if (element.transition)
|
|
663
|
+
for (const d of scanDeps(element.transition))
|
|
664
|
+
deps.add(d);
|
|
665
|
+
if (element.motion)
|
|
666
|
+
for (const d of scanDeps(element.motion))
|
|
667
|
+
deps.add(d);
|
|
668
|
+
// I1 review fix: animations field may contain $state/$cond/$token
|
|
669
|
+
// expressions; without this scan, state changes deep inside an
|
|
670
|
+
// animation config wouldn't dirty the render cache and the cascade
|
|
671
|
+
// would re-merge stale resolved values.
|
|
672
|
+
if (element.animations)
|
|
673
|
+
for (const d of scanDeps(element.animations))
|
|
674
|
+
deps.add(d);
|
|
675
|
+
renderCache.set(cacheKey, resolvedProps, deps);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
// Full render (first render or no changedPaths) — resolve and cache
|
|
680
|
+
const schema = PRIMITIVE_PROP_SCHEMAS[element.type];
|
|
681
|
+
const lazyPaths = getParsedLazyPaths(element.type, schema?.lazyActionPaths);
|
|
682
|
+
resolvedProps = resolvePropsWithContext(element.props, itemContext, indexContext, propContext, lazyPaths);
|
|
683
|
+
if (!skipCache) {
|
|
684
|
+
const deps = scanDeps(element.props, lazyPaths);
|
|
685
|
+
if (element.style)
|
|
686
|
+
for (const d of scanDeps(element.style))
|
|
687
|
+
deps.add(d);
|
|
688
|
+
if (element.visible !== undefined && element.visible !== true && element.visible !== false) {
|
|
689
|
+
for (const d of scanDeps({ _vis: element.visible }))
|
|
690
|
+
deps.add(d);
|
|
691
|
+
}
|
|
692
|
+
// Scan interaction fields for state/token dependencies
|
|
693
|
+
if (element.hover)
|
|
694
|
+
for (const d of scanDeps(element.hover))
|
|
695
|
+
deps.add(d);
|
|
696
|
+
if (element.active)
|
|
697
|
+
for (const d of scanDeps(element.active))
|
|
698
|
+
deps.add(d);
|
|
699
|
+
if (element.focus)
|
|
700
|
+
for (const d of scanDeps(element.focus))
|
|
701
|
+
deps.add(d);
|
|
702
|
+
if (element.transition)
|
|
703
|
+
for (const d of scanDeps(element.transition))
|
|
704
|
+
deps.add(d);
|
|
705
|
+
if (element.motion)
|
|
706
|
+
for (const d of scanDeps(element.motion))
|
|
707
|
+
deps.add(d);
|
|
708
|
+
if (element.animations)
|
|
709
|
+
for (const d of scanDeps(element.animations))
|
|
710
|
+
deps.add(d);
|
|
711
|
+
renderCache.set(cacheKey, resolvedProps, deps);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
// Resolve element-level style (separate from props.style)
|
|
715
|
+
// Element.style may contain $token, $state, $cond expressions that need resolution.
|
|
716
|
+
if (element.style) {
|
|
717
|
+
const resolvedStyle = {};
|
|
718
|
+
for (const [sk, sv] of Object.entries(element.style)) {
|
|
719
|
+
resolvedStyle[sk] = resolveDeep(sv, undefined, propContext, itemContext, indexContext);
|
|
720
|
+
}
|
|
721
|
+
resolvedProps.style = resolvedStyle;
|
|
722
|
+
}
|
|
723
|
+
// Apply outerOverride.style: merges on top of element.style (consumer wins last).
|
|
724
|
+
if (outerOverride?.style) {
|
|
725
|
+
resolvedProps.style = { ...(resolvedProps.style ?? {}), ...outerOverride.style };
|
|
726
|
+
}
|
|
727
|
+
// --- Variant resolution ---
|
|
728
|
+
// If element has props.variant, look up variant definition in tokens.components
|
|
729
|
+
// and merge as base (element-level definitions override)
|
|
730
|
+
const variantName = resolvedProps.variant;
|
|
731
|
+
let variantHoverBase;
|
|
732
|
+
let variantActiveBase;
|
|
733
|
+
let variantFocusBase;
|
|
734
|
+
let variantTransitionBase;
|
|
735
|
+
// Cascade animation levels (plan 3 Task 15): capture what the variant
|
|
736
|
+
// contributes so the post-variant cascade-merge block can consume it.
|
|
737
|
+
// Distinguished from resolvedProps.* because animation cascade is its
|
|
738
|
+
// own merge strategy (per-trigger null semantics) — NOT the simple
|
|
739
|
+
// base-then-override that style/hover use.
|
|
740
|
+
let variantAnimations = undefined;
|
|
741
|
+
let variantAnimationsSet = false;
|
|
742
|
+
if (variantName) {
|
|
743
|
+
const activeTokens = getActiveTokens();
|
|
744
|
+
const variant = resolveVariant(element.type, variantName, activeTokens);
|
|
745
|
+
if (variant) {
|
|
746
|
+
if ('animations' in variant) {
|
|
747
|
+
variantAnimations = variant.animations;
|
|
748
|
+
variantAnimationsSet = true;
|
|
749
|
+
}
|
|
750
|
+
// Style: variant is base, element overrides
|
|
751
|
+
if (variant.style) {
|
|
752
|
+
resolvedProps.style = { ...variant.style, ...(resolvedProps.style ?? {}) };
|
|
753
|
+
}
|
|
754
|
+
// Store variant interaction bases for merging after element-level resolution
|
|
755
|
+
if (variant.hover) {
|
|
756
|
+
if (element.hover) {
|
|
757
|
+
variantHoverBase = variant.hover;
|
|
758
|
+
}
|
|
759
|
+
else {
|
|
760
|
+
resolvedProps._hover = variant.hover;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
if (variant.active) {
|
|
764
|
+
if (element.active) {
|
|
765
|
+
variantActiveBase = variant.active;
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
resolvedProps._active = variant.active;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
if (variant.focus) {
|
|
772
|
+
if (element.focus) {
|
|
773
|
+
variantFocusBase = variant.focus;
|
|
774
|
+
}
|
|
775
|
+
else {
|
|
776
|
+
resolvedProps._focus = variant.focus;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
if (variant.transition) {
|
|
780
|
+
if (element.transition) {
|
|
781
|
+
variantTransitionBase = variant.transition;
|
|
782
|
+
}
|
|
783
|
+
else {
|
|
784
|
+
resolvedProps._transition = variant.transition;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
else if (activeTokens && activeTokens.components) {
|
|
789
|
+
console.warn(`[Mythik] Variant "${variantName}" not found for type "${element.type}" in tokens.components`);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
// --- Animation cascade merge (plan 3 Task 15 + custom-element-cascade Task 10) ---
|
|
793
|
+
// Merge identity.animations + variant.animations + elementDef.animations + element.animations
|
|
794
|
+
// (template.animations is handled in the separate template branch above,
|
|
795
|
+
// where this same merge is layered into `resolvedTemplateProps`).
|
|
796
|
+
//
|
|
797
|
+
// Merge semantics are the cascade's per-trigger null-semantics (NOT the
|
|
798
|
+
// simple base-then-override of style/hover). See mergeElementAnimations
|
|
799
|
+
// + cascade test suite for the decision table.
|
|
800
|
+
//
|
|
801
|
+
// Expression resolution (C1/I1 review fix): element.animations is
|
|
802
|
+
// resolved via resolveDeep (unified helper) BEFORE the cascade
|
|
803
|
+
// merge so `$state`/`$cond`/`$token`/`$prop` expressions inside the
|
|
804
|
+
// animation tree resolve to concrete values. Without this the raw
|
|
805
|
+
// expression objects would flow to the animation engine which can't
|
|
806
|
+
// interpret them, silently producing broken specs. Matches Task 13's
|
|
807
|
+
// template-path handling.
|
|
808
|
+
//
|
|
809
|
+
// Emission rule: always set (or clear) resolvedProps.animations. When
|
|
810
|
+
// any cascade level contributed non-undefined, emit the merge result.
|
|
811
|
+
// When NO level contributed, DELETE the key — this is the I4 cache-
|
|
812
|
+
// leak fix: the cached `resolvedProps` could otherwise retain an old
|
|
813
|
+
// render's animations after a theme/spec change that removed every
|
|
814
|
+
// contribution.
|
|
815
|
+
//
|
|
816
|
+
// Task 10 cascade semantics:
|
|
817
|
+
// When rendering INSIDE a custom element expansion (propContext defined):
|
|
818
|
+
// - element.animations came from the author's render-tree declaration → elementDef slot.
|
|
819
|
+
// - outerOverride.animations (if set) is the consumer's instance-level override → element slot.
|
|
820
|
+
// - outerOverride.variantAnimations (if set) is the custom-element's variant → variant slot.
|
|
821
|
+
// When rendering OUTSIDE any custom element expansion (propContext undefined):
|
|
822
|
+
// - element.animations is the consumer's spec-level declaration → element slot.
|
|
823
|
+
// - variant slot comes from resolveVariant (variantAnimations variable — existing behavior).
|
|
824
|
+
// - elementDef slot stays undefined (no custom element expansion active).
|
|
825
|
+
const isExpandedInCustomElement = propContext !== undefined;
|
|
826
|
+
const identityAnimations = getIdentityAnimations();
|
|
827
|
+
const rawElementAnimations = element.animations;
|
|
828
|
+
const resolvedElementAnimations = rawElementAnimations === null || rawElementAnimations === undefined
|
|
829
|
+
? rawElementAnimations
|
|
830
|
+
: resolveDeep(rawElementAnimations, undefined, propContext, itemContext, indexContext);
|
|
831
|
+
const elementDefLevel = isExpandedInCustomElement ? resolvedElementAnimations : undefined;
|
|
832
|
+
const elementLevel = isExpandedInCustomElement
|
|
833
|
+
? outerOverride?.animations
|
|
834
|
+
: resolvedElementAnimations;
|
|
835
|
+
const variantLevel = isExpandedInCustomElement && outerOverride?.variantAnimations !== undefined
|
|
836
|
+
? outerOverride.variantAnimations
|
|
837
|
+
: variantAnimations;
|
|
838
|
+
const cascadeHasAnyLevel = identityAnimations !== undefined ||
|
|
839
|
+
variantAnimationsSet ||
|
|
840
|
+
variantLevel !== undefined ||
|
|
841
|
+
elementDefLevel !== undefined ||
|
|
842
|
+
elementLevel !== undefined;
|
|
843
|
+
if (cascadeHasAnyLevel) {
|
|
844
|
+
const merged = mergeElementAnimations({
|
|
845
|
+
identity: identityAnimations,
|
|
846
|
+
variant: variantLevel,
|
|
847
|
+
elementDef: elementDefLevel,
|
|
848
|
+
element: elementLevel,
|
|
849
|
+
});
|
|
850
|
+
resolvedProps.animations = merged;
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
delete resolvedProps.animations;
|
|
854
|
+
}
|
|
855
|
+
// Resolve interactive states (hover, active, focus, transition, motion)
|
|
856
|
+
// These are passed to the renderer which wraps in Motion components.
|
|
857
|
+
// Use resolveDeep (not resolvePropsWithContext) to avoid injecting _tokens/_bindings metadata.
|
|
858
|
+
function resolveInteractionField(field) {
|
|
859
|
+
const result = {};
|
|
860
|
+
for (const [k, v] of Object.entries(field)) {
|
|
861
|
+
result[k] = resolveDeep(v, undefined, propContext, itemContext, indexContext);
|
|
862
|
+
}
|
|
863
|
+
return result;
|
|
864
|
+
}
|
|
865
|
+
// Interaction field resolution — consumer outerOverride merges ON TOP (consumer wins last).
|
|
866
|
+
if (element.hover || outerOverride?.hover) {
|
|
867
|
+
const base = element.hover ? resolveInteractionField(element.hover) : {};
|
|
868
|
+
const withVariant = variantHoverBase ? { ...variantHoverBase, ...base } : base;
|
|
869
|
+
resolvedProps._hover = outerOverride?.hover
|
|
870
|
+
? { ...withVariant, ...outerOverride.hover }
|
|
871
|
+
: withVariant;
|
|
872
|
+
}
|
|
873
|
+
if (element.active || outerOverride?.active) {
|
|
874
|
+
const base = element.active ? resolveInteractionField(element.active) : {};
|
|
875
|
+
const withVariant = variantActiveBase ? { ...variantActiveBase, ...base } : base;
|
|
876
|
+
resolvedProps._active = outerOverride?.active
|
|
877
|
+
? { ...withVariant, ...outerOverride.active }
|
|
878
|
+
: withVariant;
|
|
879
|
+
}
|
|
880
|
+
if (element.focus || outerOverride?.focus) {
|
|
881
|
+
const base = element.focus ? resolveInteractionField(element.focus) : {};
|
|
882
|
+
const withVariant = variantFocusBase ? { ...variantFocusBase, ...base } : base;
|
|
883
|
+
resolvedProps._focus = outerOverride?.focus
|
|
884
|
+
? { ...withVariant, ...outerOverride.focus }
|
|
885
|
+
: withVariant;
|
|
886
|
+
}
|
|
887
|
+
if (element.transition || outerOverride?.transition) {
|
|
888
|
+
const base = element.transition ? resolveInteractionField(element.transition) : {};
|
|
889
|
+
const withVariant = variantTransitionBase ? { ...variantTransitionBase, ...base } : base;
|
|
890
|
+
resolvedProps._transition = outerOverride?.transition
|
|
891
|
+
? { ...withVariant, ...outerOverride.transition }
|
|
892
|
+
: withVariant;
|
|
893
|
+
}
|
|
894
|
+
if (element.motion || outerOverride?.motion) {
|
|
895
|
+
const motionResolved = {};
|
|
896
|
+
if (element.motion) {
|
|
897
|
+
if (element.motion.initial)
|
|
898
|
+
motionResolved.initial = resolveInteractionField(element.motion.initial);
|
|
899
|
+
if (element.motion.animate)
|
|
900
|
+
motionResolved.animate = resolveInteractionField(element.motion.animate);
|
|
901
|
+
if (element.motion.exit)
|
|
902
|
+
motionResolved.exit = resolveInteractionField(element.motion.exit);
|
|
903
|
+
if (element.motion.transition)
|
|
904
|
+
motionResolved.transition = resolveInteractionField(element.motion.transition);
|
|
905
|
+
if (element.motion.layoutId)
|
|
906
|
+
motionResolved.layoutId = element.motion.layoutId;
|
|
907
|
+
}
|
|
908
|
+
// Consumer overrides each sub-field if specified — consumer wins last.
|
|
909
|
+
if (outerOverride?.motion) {
|
|
910
|
+
if (outerOverride.motion.initial)
|
|
911
|
+
motionResolved.initial = outerOverride.motion.initial;
|
|
912
|
+
if (outerOverride.motion.animate)
|
|
913
|
+
motionResolved.animate = outerOverride.motion.animate;
|
|
914
|
+
if (outerOverride.motion.exit)
|
|
915
|
+
motionResolved.exit = outerOverride.motion.exit;
|
|
916
|
+
if (outerOverride.motion.transition)
|
|
917
|
+
motionResolved.transition = outerOverride.motion.transition;
|
|
918
|
+
if (outerOverride.motion.layoutId)
|
|
919
|
+
motionResolved.layoutId = outerOverride.motion.layoutId;
|
|
920
|
+
}
|
|
921
|
+
resolvedProps._motion = motionResolved;
|
|
922
|
+
}
|
|
923
|
+
// Resolve event bindings. Two concerns:
|
|
924
|
+
// 1. A binding can itself be a `$prop` expression (custom-element render
|
|
925
|
+
// trees passing consumer-supplied action chains). Resolve ONLY that
|
|
926
|
+
// outer shape — inner $state/$template stay lazy for press-time.
|
|
927
|
+
// 2. When inside a repeat, inner action params referencing `$item` must
|
|
928
|
+
// resolve eagerly with the row's item context.
|
|
929
|
+
if (element.on) {
|
|
930
|
+
const needsItemResolution = itemContext !== undefined;
|
|
931
|
+
const resolvedOn = {};
|
|
932
|
+
for (const [event, rawBinding] of Object.entries(element.on)) {
|
|
933
|
+
// Step 1: if the binding itself is a $prop expression, resolve it now.
|
|
934
|
+
// Anything else (plain object, array of actions, transaction)
|
|
935
|
+
// is passed through — the action dispatcher / transaction
|
|
936
|
+
// engine handle inner $state/$template at press time.
|
|
937
|
+
const isPropBinding = rawBinding !== null &&
|
|
938
|
+
typeof rawBinding === 'object' &&
|
|
939
|
+
!Array.isArray(rawBinding) &&
|
|
940
|
+
'$prop' in rawBinding;
|
|
941
|
+
const binding = isPropBinding
|
|
942
|
+
? resolveDeep(rawBinding, undefined, propContext, itemContext, indexContext)
|
|
943
|
+
: rawBinding;
|
|
944
|
+
// TransactionBinding: pass through as-is (resolved by transaction engine).
|
|
945
|
+
if (binding && typeof binding === 'object' && !Array.isArray(binding) && 'transaction' in binding) {
|
|
946
|
+
resolvedOn[event] = binding;
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
// Outside a repeat: zero-cost passthrough. The action dispatcher
|
|
950
|
+
// resolves inner expressions at press time.
|
|
951
|
+
if (!needsItemResolution) {
|
|
952
|
+
resolvedOn[event] = binding;
|
|
953
|
+
continue;
|
|
954
|
+
}
|
|
955
|
+
// Inside a repeat: resolve each action's params eagerly so `$item`
|
|
956
|
+
// binds to the row's data. Preserve ALL binding properties
|
|
957
|
+
// (fireAndForget, etc.) — only params are re-resolved.
|
|
958
|
+
const bindings = Array.isArray(binding) ? binding : [binding];
|
|
959
|
+
resolvedOn[event] = bindings.map((b) => {
|
|
960
|
+
if (!b.params || typeof b.params !== 'object')
|
|
961
|
+
return b;
|
|
962
|
+
return {
|
|
963
|
+
...b,
|
|
964
|
+
params: Object.fromEntries(Object.entries(b.params).map(([k, v]) => [k, resolveDeep(v, undefined, propContext, itemContext, indexContext)])),
|
|
965
|
+
};
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
resolvedProps._eventBindings = resolvedOn;
|
|
969
|
+
}
|
|
970
|
+
const children = [];
|
|
971
|
+
if (element.children) {
|
|
972
|
+
for (const childId of element.children) {
|
|
973
|
+
const childElement = spec.elements[childId];
|
|
974
|
+
// If child has repeat, let it handle its own iteration
|
|
975
|
+
if (childElement?.repeat) {
|
|
976
|
+
const childNode = renderElement(childId, spec, undefined, undefined, propContext);
|
|
977
|
+
if (childNode)
|
|
978
|
+
children.push(childNode);
|
|
979
|
+
}
|
|
980
|
+
else if (itemContext !== undefined) {
|
|
981
|
+
// Pass item context down to children
|
|
982
|
+
const childNode = renderElement(childId, spec, itemContext, indexContext, propContext);
|
|
983
|
+
if (childNode)
|
|
984
|
+
children.push(childNode);
|
|
985
|
+
}
|
|
986
|
+
else {
|
|
987
|
+
const childNode = renderElement(childId, spec, undefined, undefined, propContext);
|
|
988
|
+
if (childNode)
|
|
989
|
+
children.push(childNode);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
// Pass elementId for CSS className generation (unique per element)
|
|
994
|
+
resolvedProps._elementId = elementId;
|
|
995
|
+
const primitiveRenderer = primitiveRegistry.get(element.type);
|
|
996
|
+
const node = primitiveRenderer(resolvedProps, children);
|
|
997
|
+
// Propagate element-level key (supports expressions like $template, $state, $prop)
|
|
998
|
+
if (element.key !== undefined) {
|
|
999
|
+
const resolvedKey = resolveDeep(element.key, undefined, propContext, itemContext, indexContext);
|
|
1000
|
+
if (resolvedKey !== undefined && resolvedKey !== null) {
|
|
1001
|
+
node.key = String(resolvedKey);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
// Apply outerOverride.key: consumer's instance-level key wins over element.key.
|
|
1005
|
+
if (outerOverride?.key !== undefined) {
|
|
1006
|
+
const resolvedOverrideKey = resolveDeep(outerOverride.key, undefined, propContext, itemContext, indexContext);
|
|
1007
|
+
if (resolvedOverrideKey !== undefined && resolvedOverrideKey !== null) {
|
|
1008
|
+
node.key = String(resolvedOverrideKey);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
return node;
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Render an element with $group context (for groupBy headers/footers).
|
|
1015
|
+
* Resolves all expressions with group context available.
|
|
1016
|
+
*/
|
|
1017
|
+
function renderElementWithGroup(elementId, spec, groupCtx) {
|
|
1018
|
+
const element = spec.elements[elementId];
|
|
1019
|
+
if (!element)
|
|
1020
|
+
return null;
|
|
1021
|
+
if (!primitiveRegistry.has(element.type))
|
|
1022
|
+
return null;
|
|
1023
|
+
// Resolve props with group context
|
|
1024
|
+
const props = element.props ?? {};
|
|
1025
|
+
const resolved = {};
|
|
1026
|
+
for (const [key, value] of Object.entries(props)) {
|
|
1027
|
+
if (value && typeof value === 'object') {
|
|
1028
|
+
const hasExprKey = Object.keys(value).some((k) => k.startsWith('$'));
|
|
1029
|
+
if (hasExprKey) {
|
|
1030
|
+
resolved[key] = resolver.resolve(value, { group: groupCtx });
|
|
1031
|
+
}
|
|
1032
|
+
else {
|
|
1033
|
+
// Recurse into nested objects
|
|
1034
|
+
const inner = {};
|
|
1035
|
+
for (const [ik, iv] of Object.entries(value)) {
|
|
1036
|
+
if (iv && typeof iv === 'object') {
|
|
1037
|
+
const hasInnerExpr = Object.keys(iv).some((k) => k.startsWith('$'));
|
|
1038
|
+
inner[ik] = hasInnerExpr ? resolver.resolve(iv, { group: groupCtx }) : iv;
|
|
1039
|
+
}
|
|
1040
|
+
else {
|
|
1041
|
+
inner[ik] = iv;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
resolved[key] = inner;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
else {
|
|
1048
|
+
resolved[key] = value;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
// Resolve style with group context
|
|
1052
|
+
if (element.style) {
|
|
1053
|
+
const resolvedStyle = {};
|
|
1054
|
+
for (const [sk, sv] of Object.entries(element.style)) {
|
|
1055
|
+
if (sv && typeof sv === 'object') {
|
|
1056
|
+
const hasExprKey = Object.keys(sv).some((k) => k.startsWith('$'));
|
|
1057
|
+
resolvedStyle[sk] = hasExprKey ? resolver.resolve(sv, { group: groupCtx }) : sv;
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
resolvedStyle[sk] = sv;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
resolved.style = resolvedStyle;
|
|
1064
|
+
}
|
|
1065
|
+
else if (element.style === undefined && props.style === undefined) {
|
|
1066
|
+
// No style
|
|
1067
|
+
}
|
|
1068
|
+
const activeTokens5 = getActiveTokens();
|
|
1069
|
+
if (activeTokens5)
|
|
1070
|
+
resolved._tokens = activeTokens5;
|
|
1071
|
+
// Render children
|
|
1072
|
+
const children = [];
|
|
1073
|
+
if (element.children) {
|
|
1074
|
+
for (const childId of element.children) {
|
|
1075
|
+
const childNode = renderElementWithGroup(childId, spec, groupCtx);
|
|
1076
|
+
if (childNode)
|
|
1077
|
+
children.push(childNode);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
const primitiveRenderer = primitiveRegistry.get(element.type);
|
|
1081
|
+
return primitiveRenderer(resolved, children);
|
|
1082
|
+
}
|
|
1083
|
+
function render(spec, changedPaths) {
|
|
1084
|
+
if (!spec.elements[spec.root]) {
|
|
1085
|
+
throw new Error(`Root element "${spec.root}" not found in spec`);
|
|
1086
|
+
}
|
|
1087
|
+
activeChangedPaths = changedPaths;
|
|
1088
|
+
const result = renderElement(spec.root, spec);
|
|
1089
|
+
activeChangedPaths = undefined;
|
|
1090
|
+
if (result === null) {
|
|
1091
|
+
throw new Error(`Root element "${spec.root}" is hidden — cannot render`);
|
|
1092
|
+
}
|
|
1093
|
+
return result;
|
|
1094
|
+
}
|
|
1095
|
+
return { render };
|
|
1096
|
+
}
|
|
1097
|
+
//# sourceMappingURL=engine.js.map
|