@softov/scena 0.1.2
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 +21 -0
- package/README.md +42 -0
- package/dist/controls/command.d.ts +18 -0
- package/dist/controls/command.js +150 -0
- package/dist/controls/events.d.ts +3 -0
- package/dist/controls/events.js +43 -0
- package/dist/controls/index.d.ts +10 -0
- package/dist/controls/index.js +10 -0
- package/dist/controls/keybinding.d.ts +9 -0
- package/dist/controls/keybinding.js +94 -0
- package/dist/controls/layout.d.ts +16 -0
- package/dist/controls/layout.js +201 -0
- package/dist/controls/manifest.d.ts +21 -0
- package/dist/controls/manifest.js +219 -0
- package/dist/controls/session.d.ts +16 -0
- package/dist/controls/session.js +95 -0
- package/dist/controls/shell.d.ts +8 -0
- package/dist/controls/shell.js +48 -0
- package/dist/controls/storage/layout-local.d.ts +6 -0
- package/dist/controls/storage/layout-local.js +47 -0
- package/dist/controls/storage/session-local.d.ts +5 -0
- package/dist/controls/storage/session-local.js +38 -0
- package/dist/controls/when.d.ts +7 -0
- package/dist/controls/when.js +226 -0
- package/dist/converters/a2ui-v0.10.d.ts +23 -0
- package/dist/converters/a2ui-v0.10.js +136 -0
- package/dist/converters/index.d.ts +1 -0
- package/dist/converters/index.js +1 -0
- package/dist/core/backends/modus-backend.d.ts +13 -0
- package/dist/core/backends/modus-backend.js +115 -0
- package/dist/core/backends/storage-backend.d.ts +7 -0
- package/dist/core/backends/storage-backend.js +73 -0
- package/dist/core/backends/yjs-backend.d.ts +3 -0
- package/dist/core/backends/yjs-backend.js +44 -0
- package/dist/core/binding-resolver.d.ts +7 -0
- package/dist/core/binding-resolver.js +106 -0
- package/dist/core/component-graph.d.ts +6 -0
- package/dist/core/component-graph.js +77 -0
- package/dist/core/component-registry.d.ts +7 -0
- package/dist/core/component-registry.js +87 -0
- package/dist/core/computed-dsl.d.ts +2 -0
- package/dist/core/computed-dsl.js +267 -0
- package/dist/core/converter-registry.d.ts +2 -0
- package/dist/core/converter-registry.js +37 -0
- package/dist/core/disposable.d.ts +3 -0
- package/dist/core/disposable.js +19 -0
- package/dist/core/dynamic-resolver.d.ts +12 -0
- package/dist/core/dynamic-resolver.js +134 -0
- package/dist/core/index.d.ts +44 -0
- package/dist/core/index.js +48 -0
- package/dist/core/label.d.ts +2 -0
- package/dist/core/label.js +14 -0
- package/dist/core/mount-menu.d.ts +2 -0
- package/dist/core/mount-menu.js +23 -0
- package/dist/core/mount-surface.d.ts +15 -0
- package/dist/core/mount-surface.js +214 -0
- package/dist/core/path-resolver.d.ts +14 -0
- package/dist/core/path-resolver.js +169 -0
- package/dist/core/permissions.d.ts +2 -0
- package/dist/core/permissions.js +50 -0
- package/dist/core/reactive-store.d.ts +17 -0
- package/dist/core/reactive-store.js +496 -0
- package/dist/core/scena.d.ts +2 -0
- package/dist/core/scena.js +115 -0
- package/dist/core/surface-presentation.d.ts +6 -0
- package/dist/core/surface-presentation.js +12 -0
- package/dist/i18n/i18n-backend.d.ts +2 -0
- package/dist/i18n/i18n-backend.js +35 -0
- package/dist/i18n/registry.d.ts +32 -0
- package/dist/i18n/registry.js +200 -0
- package/dist/porta/Limen.css +50 -0
- package/dist/porta/Limen.d.ts +16 -0
- package/dist/porta/Limen.js +14 -0
- package/dist/porta/PortaContext.d.ts +10 -0
- package/dist/porta/PortaContext.js +20 -0
- package/dist/porta/PortaLock.css +14 -0
- package/dist/porta/PortaLock.d.ts +10 -0
- package/dist/porta/PortaLock.js +13 -0
- package/dist/porta/SigillumGate.d.ts +8 -0
- package/dist/porta/SigillumGate.js +7 -0
- package/dist/porta/commands.d.ts +3 -0
- package/dist/porta/commands.js +125 -0
- package/dist/porta/index.d.ts +18 -0
- package/dist/porta/index.js +22 -0
- package/dist/porta/login-form.block.d.ts +2 -0
- package/dist/porta/login-form.block.js +7 -0
- package/dist/porta/match.d.ts +2 -0
- package/dist/porta/match.js +20 -0
- package/dist/porta/provider.d.ts +59 -0
- package/dist/porta/provider.js +1 -0
- package/dist/porta/providers/examples/google-oauth.d.ts +6 -0
- package/dist/porta/providers/examples/google-oauth.js +21 -0
- package/dist/porta/providers/examples/index.d.ts +6 -0
- package/dist/porta/providers/examples/index.js +3 -0
- package/dist/porta/providers/examples/magic-link.d.ts +8 -0
- package/dist/porta/providers/examples/magic-link.js +31 -0
- package/dist/porta/providers/examples/sms-otp.d.ts +9 -0
- package/dist/porta/providers/examples/sms-otp.js +31 -0
- package/dist/porta/providers/password.d.ts +12 -0
- package/dist/porta/providers/password.js +46 -0
- package/dist/porta/register-blocks.d.ts +3 -0
- package/dist/porta/register-blocks.js +31 -0
- package/dist/porta/register.d.ts +15 -0
- package/dist/porta/register.js +31 -0
- package/dist/porta/sigillum.d.ts +19 -0
- package/dist/porta/sigillum.js +41 -0
- package/dist/react/DefaultShell.d.ts +1 -0
- package/dist/react/DefaultShell.js +37 -0
- package/dist/react/Scena.d.ts +9 -0
- package/dist/react/Scena.js +20 -0
- package/dist/react/ScenaProvider.d.ts +8 -0
- package/dist/react/ScenaProvider.js +13 -0
- package/dist/react/ShellSplitter.d.ts +13 -0
- package/dist/react/ShellSplitter.js +88 -0
- package/dist/react/SurfaceArea.d.ts +13 -0
- package/dist/react/SurfaceArea.js +75 -0
- package/dist/react/Translate.d.ts +8 -0
- package/dist/react/Translate.js +10 -0
- package/dist/react/ViewMount.d.ts +12 -0
- package/dist/react/ViewMount.js +268 -0
- package/dist/react/core.d.ts +6 -0
- package/dist/react/core.js +10 -0
- package/dist/react/hooks/useCommand.d.ts +1 -0
- package/dist/react/hooks/useCommand.js +6 -0
- package/dist/react/hooks/useI18n.d.ts +9 -0
- package/dist/react/hooks/useI18n.js +16 -0
- package/dist/react/hooks/useLabel.d.ts +2 -0
- package/dist/react/hooks/useLabel.js +19 -0
- package/dist/react/hooks/useLayout.d.ts +2 -0
- package/dist/react/hooks/useLayout.js +10 -0
- package/dist/react/hooks/useMounts.d.ts +2 -0
- package/dist/react/hooks/useMounts.js +17 -0
- package/dist/react/hooks/useStore.d.ts +3 -0
- package/dist/react/hooks/useStore.js +40 -0
- package/dist/react/hooks/useStoreLabel.d.ts +3 -0
- package/dist/react/hooks/useStoreLabel.js +25 -0
- package/dist/react/hooks/useSurfacePresentation.d.ts +4 -0
- package/dist/react/hooks/useSurfacePresentation.js +16 -0
- package/dist/react/index.d.ts +20 -0
- package/dist/react/index.js +20 -0
- package/dist/react/mount-context.d.ts +8 -0
- package/dist/react/mount-context.js +20 -0
- package/dist/react/useSurfaceResize.d.ts +39 -0
- package/dist/react/useSurfaceResize.js +135 -0
- package/dist/runtime/args-schema.d.ts +11 -0
- package/dist/runtime/args-schema.js +45 -0
- package/dist/runtime/builtins.d.ts +3 -0
- package/dist/runtime/builtins.js +193 -0
- package/dist/runtime/client-handlers.d.ts +3 -0
- package/dist/runtime/client-handlers.js +19 -0
- package/dist/runtime/in-memory-socket.d.ts +7 -0
- package/dist/runtime/in-memory-socket.js +53 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/layout-commands.d.ts +5 -0
- package/dist/runtime/layout-commands.js +548 -0
- package/dist/runtime/opener-commands.d.ts +17 -0
- package/dist/runtime/opener-commands.js +96 -0
- package/dist/runtime/surface-bridge.d.ts +15 -0
- package/dist/runtime/surface-bridge.js +116 -0
- package/dist/styles/bar.css +155 -0
- package/dist/styles/base.css +285 -0
- package/dist/styles/geometry.css +32 -0
- package/dist/styles/index.d.ts +29 -0
- package/dist/styles/index.js +109 -0
- package/dist/styles/scrollbar.css +45 -0
- package/dist/styles/surface.css +179 -0
- package/dist/styles/theme.css +3 -0
- package/dist/styles/themes/dark.css +30 -0
- package/dist/styles/themes/light.css +1 -0
- package/dist/styles/themes/tokens.css +222 -0
- package/dist/types/binding-resolver.d.ts +30 -0
- package/dist/types/binding-resolver.js +1 -0
- package/dist/types/colors.d.ts +7 -0
- package/dist/types/colors.js +59 -0
- package/dist/types/command.d.ts +62 -0
- package/dist/types/command.js +1 -0
- package/dist/types/component-graph.d.ts +72 -0
- package/dist/types/component-graph.js +40 -0
- package/dist/types/component-registry.d.ts +70 -0
- package/dist/types/component-registry.js +1 -0
- package/dist/types/converter-registry.d.ts +17 -0
- package/dist/types/converter-registry.js +1 -0
- package/dist/types/disposable.d.ts +3 -0
- package/dist/types/disposable.js +1 -0
- package/dist/types/events.d.ts +75 -0
- package/dist/types/events.js +1 -0
- package/dist/types/host.d.ts +50 -0
- package/dist/types/host.js +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.js +23 -0
- package/dist/types/keybinding.d.ts +36 -0
- package/dist/types/keybinding.js +1 -0
- package/dist/types/label.d.ts +9 -0
- package/dist/types/label.js +1 -0
- package/dist/types/layout.d.ts +117 -0
- package/dist/types/layout.js +1 -0
- package/dist/types/manifest.d.ts +152 -0
- package/dist/types/manifest.js +1 -0
- package/dist/types/mount-menu.d.ts +8 -0
- package/dist/types/mount-menu.js +1 -0
- package/dist/types/mount-surface.d.ts +87 -0
- package/dist/types/mount-surface.js +1 -0
- package/dist/types/permissions.d.ts +18 -0
- package/dist/types/permissions.js +1 -0
- package/dist/types/query.d.ts +34 -0
- package/dist/types/query.js +7 -0
- package/dist/types/reactive-store.d.ts +39 -0
- package/dist/types/reactive-store.js +1 -0
- package/dist/types/scena.d.ts +53 -0
- package/dist/types/scena.js +1 -0
- package/dist/types/scope-backend.d.ts +16 -0
- package/dist/types/scope-backend.js +1 -0
- package/dist/types/session.d.ts +39 -0
- package/dist/types/session.js +1 -0
- package/dist/types/shell.d.ts +21 -0
- package/dist/types/shell.js +1 -0
- package/dist/types/when.d.ts +10 -0
- package/dist/types/when.js +1 -0
- package/dist/ui/_utils.d.ts +8 -0
- package/dist/ui/_utils.js +53 -0
- package/dist/ui/campus/CampusMappa.d.ts +18 -0
- package/dist/ui/campus/CampusMappa.js +106 -0
- package/dist/ui/campus/CampusNodus.d.ts +25 -0
- package/dist/ui/campus/CampusNodus.js +211 -0
- package/dist/ui/campus/CampusStratum.d.ts +13 -0
- package/dist/ui/campus/CampusStratum.js +20 -0
- package/dist/ui/campus/CampusVelum.d.ts +7 -0
- package/dist/ui/campus/CampusVelum.js +12 -0
- package/dist/ui/campus/CampusView.d.ts +27 -0
- package/dist/ui/campus/CampusView.js +420 -0
- package/dist/ui/campus/context.d.ts +13 -0
- package/dist/ui/campus/context.js +12 -0
- package/dist/ui/campus/index.d.ts +14 -0
- package/dist/ui/campus/index.js +11 -0
- package/dist/ui/campus/stratum-context.d.ts +2 -0
- package/dist/ui/campus/stratum-context.js +10 -0
- package/dist/ui/campus/types.d.ts +47 -0
- package/dist/ui/campus/types.js +4 -0
- package/dist/ui/chart/BarChart.css +53 -0
- package/dist/ui/chart/BarChart.d.ts +24 -0
- package/dist/ui/chart/BarChart.js +32 -0
- package/dist/ui/chart/Donut.css +15 -0
- package/dist/ui/chart/Donut.d.ts +15 -0
- package/dist/ui/chart/Donut.js +18 -0
- package/dist/ui/chart/LineChart.css +8 -0
- package/dist/ui/chart/LineChart.d.ts +24 -0
- package/dist/ui/chart/LineChart.js +29 -0
- package/dist/ui/chart/catalog.d.ts +2 -0
- package/dist/ui/chart/catalog.js +7 -0
- package/dist/ui/chart/index.d.ts +6 -0
- package/dist/ui/chart/index.js +4 -0
- package/dist/ui/control/Button.css +7 -0
- package/dist/ui/control/Button.d.ts +17 -0
- package/dist/ui/control/Button.js +17 -0
- package/dist/ui/control/CheckBox.css +16 -0
- package/dist/ui/control/CheckBox.d.ts +15 -0
- package/dist/ui/control/CheckBox.js +23 -0
- package/dist/ui/control/Checks.css +6 -0
- package/dist/ui/control/Checks.d.ts +9 -0
- package/dist/ui/control/Checks.js +10 -0
- package/dist/ui/control/ChoicePicker.css +16 -0
- package/dist/ui/control/ChoicePicker.d.ts +25 -0
- package/dist/ui/control/ChoicePicker.js +38 -0
- package/dist/ui/control/DateTimeInput.css +1 -0
- package/dist/ui/control/DateTimeInput.d.ts +22 -0
- package/dist/ui/control/DateTimeInput.js +41 -0
- package/dist/ui/control/LocaleToggle.css +38 -0
- package/dist/ui/control/LocaleToggle.d.ts +11 -0
- package/dist/ui/control/LocaleToggle.js +23 -0
- package/dist/ui/control/ReloadButton.d.ts +6 -0
- package/dist/ui/control/ReloadButton.js +9 -0
- package/dist/ui/control/Slider.css +2 -0
- package/dist/ui/control/Slider.d.ts +21 -0
- package/dist/ui/control/Slider.js +37 -0
- package/dist/ui/control/TextField.css +0 -0
- package/dist/ui/control/TextField.d.ts +25 -0
- package/dist/ui/control/TextField.js +36 -0
- package/dist/ui/control/_field-parts.css +102 -0
- package/dist/ui/control/_field-parts.d.ts +15 -0
- package/dist/ui/control/_field-parts.js +17 -0
- package/dist/ui/control/catalog.d.ts +2 -0
- package/dist/ui/control/catalog.js +10 -0
- package/dist/ui/control/index.d.ts +13 -0
- package/dist/ui/control/index.js +11 -0
- package/dist/ui/data/DataTable.d.ts +19 -0
- package/dist/ui/data/DataTable.js +20 -0
- package/dist/ui/data/Filter.d.ts +13 -0
- package/dist/ui/data/Filter.js +56 -0
- package/dist/ui/data/List.css +16 -0
- package/dist/ui/data/List.d.ts +15 -0
- package/dist/ui/data/List.js +18 -0
- package/dist/ui/data/Listable.css +245 -0
- package/dist/ui/data/Listable.d.ts +60 -0
- package/dist/ui/data/Listable.js +209 -0
- package/dist/ui/data/Pagination.d.ts +5 -0
- package/dist/ui/data/Pagination.js +43 -0
- package/dist/ui/data/Tree.css +118 -0
- package/dist/ui/data/Tree.d.ts +45 -0
- package/dist/ui/data/Tree.js +170 -0
- package/dist/ui/data/catalog.d.ts +2 -0
- package/dist/ui/data/catalog.js +7 -0
- package/dist/ui/data/index.d.ts +11 -0
- package/dist/ui/data/index.js +7 -0
- package/dist/ui/display/AddPlaceholder.d.ts +6 -0
- package/dist/ui/display/AddPlaceholder.js +24 -0
- package/dist/ui/display/Alert.css +42 -0
- package/dist/ui/display/Alert.d.ts +14 -0
- package/dist/ui/display/Alert.js +13 -0
- package/dist/ui/display/Avatar.css +19 -0
- package/dist/ui/display/Avatar.d.ts +16 -0
- package/dist/ui/display/Avatar.js +52 -0
- package/dist/ui/display/Badge.css +26 -0
- package/dist/ui/display/Badge.d.ts +16 -0
- package/dist/ui/display/Badge.js +9 -0
- package/dist/ui/display/Card.css +15 -0
- package/dist/ui/display/Card.d.ts +11 -0
- package/dist/ui/display/Card.js +8 -0
- package/dist/ui/display/DetailContainer.d.ts +6 -0
- package/dist/ui/display/DetailContainer.js +7 -0
- package/dist/ui/display/DetailHeader.css +53 -0
- package/dist/ui/display/DetailHeader.d.ts +22 -0
- package/dist/ui/display/DetailHeader.js +8 -0
- package/dist/ui/display/DetailList.css +26 -0
- package/dist/ui/display/DetailList.d.ts +13 -0
- package/dist/ui/display/DetailList.js +5 -0
- package/dist/ui/display/DetailNotFound.d.ts +17 -0
- package/dist/ui/display/DetailNotFound.js +39 -0
- package/dist/ui/display/Divider.css +6 -0
- package/dist/ui/display/Divider.d.ts +8 -0
- package/dist/ui/display/Divider.js +16 -0
- package/dist/ui/display/Divisor.css +30 -0
- package/dist/ui/display/Divisor.d.ts +11 -0
- package/dist/ui/display/Divisor.js +43 -0
- package/dist/ui/display/Icon.css +10 -0
- package/dist/ui/display/Icon.d.ts +14 -0
- package/dist/ui/display/Icon.js +144 -0
- package/dist/ui/display/Image.css +1 -0
- package/dist/ui/display/Image.d.ts +16 -0
- package/dist/ui/display/Image.js +19 -0
- package/dist/ui/display/Markdown.css +38 -0
- package/dist/ui/display/Markdown.d.ts +8 -0
- package/dist/ui/display/Markdown.js +140 -0
- package/dist/ui/display/Progress.css +39 -0
- package/dist/ui/display/Progress.d.ts +15 -0
- package/dist/ui/display/Progress.js +17 -0
- package/dist/ui/display/SectionTitle.d.ts +6 -0
- package/dist/ui/display/SectionTitle.js +6 -0
- package/dist/ui/display/Skeleton.css +20 -0
- package/dist/ui/display/Skeleton.d.ts +11 -0
- package/dist/ui/display/Skeleton.js +11 -0
- package/dist/ui/display/Spinner.css +20 -0
- package/dist/ui/display/Spinner.d.ts +12 -0
- package/dist/ui/display/Spinner.js +12 -0
- package/dist/ui/display/Svg.d.ts +13 -0
- package/dist/ui/display/Svg.js +17 -0
- package/dist/ui/display/Text.css +20 -0
- package/dist/ui/display/Text.d.ts +13 -0
- package/dist/ui/display/Text.js +15 -0
- package/dist/ui/display/catalog.d.ts +2 -0
- package/dist/ui/display/catalog.js +12 -0
- package/dist/ui/display/index.d.ts +22 -0
- package/dist/ui/display/index.js +14 -0
- package/dist/ui/embed/HtmlEmbed.d.ts +12 -0
- package/dist/ui/embed/HtmlEmbed.js +16 -0
- package/dist/ui/embed/index.d.ts +2 -0
- package/dist/ui/embed/index.js +1 -0
- package/dist/ui/forms/DangerZone.d.ts +8 -0
- package/dist/ui/forms/DangerZone.js +31 -0
- package/dist/ui/forms/Field.css +15 -0
- package/dist/ui/forms/Field.d.ts +28 -0
- package/dist/ui/forms/Field.js +25 -0
- package/dist/ui/forms/FieldGroup.css +15 -0
- package/dist/ui/forms/FieldGroup.d.ts +7 -0
- package/dist/ui/forms/FieldGroup.js +7 -0
- package/dist/ui/forms/Form.css +14 -0
- package/dist/ui/forms/Form.d.ts +18 -0
- package/dist/ui/forms/Form.js +17 -0
- package/dist/ui/forms/FormActions.css +11 -0
- package/dist/ui/forms/FormActions.d.ts +18 -0
- package/dist/ui/forms/FormActions.js +10 -0
- package/dist/ui/forms/FormSection.css +19 -0
- package/dist/ui/forms/FormSection.d.ts +7 -0
- package/dist/ui/forms/FormSection.js +7 -0
- package/dist/ui/forms/LoginForm.css +105 -0
- package/dist/ui/forms/LoginForm.d.ts +12 -0
- package/dist/ui/forms/LoginForm.js +137 -0
- package/dist/ui/forms/SchemaForm.css +81 -0
- package/dist/ui/forms/SchemaForm.d.ts +26 -0
- package/dist/ui/forms/SchemaForm.js +186 -0
- package/dist/ui/forms/SettingsContainer.d.ts +8 -0
- package/dist/ui/forms/SettingsContainer.js +8 -0
- package/dist/ui/forms/catalog.d.ts +2 -0
- package/dist/ui/forms/catalog.js +11 -0
- package/dist/ui/forms/index.d.ts +19 -0
- package/dist/ui/forms/index.js +12 -0
- package/dist/ui/forms/schema-walk.d.ts +50 -0
- package/dist/ui/forms/schema-walk.js +116 -0
- package/dist/ui/index.d.ts +58 -0
- package/dist/ui/index.js +63 -0
- package/dist/ui/layout/BarLayout.d.ts +2 -0
- package/dist/ui/layout/BarLayout.js +18 -0
- package/dist/ui/layout/Column.css +6 -0
- package/dist/ui/layout/Column.d.ts +12 -0
- package/dist/ui/layout/Column.js +13 -0
- package/dist/ui/layout/FloatingLayout.d.ts +2 -0
- package/dist/ui/layout/FloatingLayout.js +12 -0
- package/dist/ui/layout/Grid.css +5 -0
- package/dist/ui/layout/Grid.d.ts +13 -0
- package/dist/ui/layout/Grid.js +19 -0
- package/dist/ui/layout/InlineLayout.d.ts +2 -0
- package/dist/ui/layout/InlineLayout.js +13 -0
- package/dist/ui/layout/MountTitle.d.ts +12 -0
- package/dist/ui/layout/MountTitle.js +42 -0
- package/dist/ui/layout/RailLayout.d.ts +2 -0
- package/dist/ui/layout/RailLayout.js +38 -0
- package/dist/ui/layout/Row.css +16 -0
- package/dist/ui/layout/Row.d.ts +13 -0
- package/dist/ui/layout/Row.js +21 -0
- package/dist/ui/layout/SectionHeader.d.ts +10 -0
- package/dist/ui/layout/SectionHeader.js +65 -0
- package/dist/ui/layout/SingleLayout.d.ts +2 -0
- package/dist/ui/layout/SingleLayout.js +25 -0
- package/dist/ui/layout/SpatialCard.d.ts +9 -0
- package/dist/ui/layout/SpatialCard.js +30 -0
- package/dist/ui/layout/SpatialLayout.d.ts +2 -0
- package/dist/ui/layout/SpatialLayout.js +446 -0
- package/dist/ui/layout/SplitLayout.d.ts +2 -0
- package/dist/ui/layout/SplitLayout.js +159 -0
- package/dist/ui/layout/Splitter.d.ts +12 -0
- package/dist/ui/layout/Splitter.js +64 -0
- package/dist/ui/layout/StackHeader.d.ts +9 -0
- package/dist/ui/layout/StackHeader.js +87 -0
- package/dist/ui/layout/StackLayout.d.ts +2 -0
- package/dist/ui/layout/StackLayout.js +137 -0
- package/dist/ui/layout/TabLayout.d.ts +2 -0
- package/dist/ui/layout/TabLayout.js +145 -0
- package/dist/ui/layout/TabPanelLayout.d.ts +20 -0
- package/dist/ui/layout/TabPanelLayout.js +615 -0
- package/dist/ui/layout/catalog.d.ts +2 -0
- package/dist/ui/layout/catalog.js +10 -0
- package/dist/ui/layout/index.d.ts +17 -0
- package/dist/ui/layout/index.js +17 -0
- package/dist/ui/layout/register.d.ts +3 -0
- package/dist/ui/layout/register.js +25 -0
- package/dist/ui/media/Audio.css +1 -0
- package/dist/ui/media/Audio.d.ts +12 -0
- package/dist/ui/media/Audio.js +8 -0
- package/dist/ui/media/Video.css +1 -0
- package/dist/ui/media/Video.d.ts +16 -0
- package/dist/ui/media/Video.js +9 -0
- package/dist/ui/media/catalog.d.ts +2 -0
- package/dist/ui/media/catalog.js +5 -0
- package/dist/ui/media/index.d.ts +2 -0
- package/dist/ui/media/index.js +3 -0
- package/dist/ui/menu/ActionList.css +262 -0
- package/dist/ui/menu/ActionList.d.ts +19 -0
- package/dist/ui/menu/ActionList.js +369 -0
- package/dist/ui/menu/ContainerMenu.d.ts +13 -0
- package/dist/ui/menu/ContainerMenu.js +57 -0
- package/dist/ui/menu/ContextMenu.d.ts +27 -0
- package/dist/ui/menu/ContextMenu.js +93 -0
- package/dist/ui/menu/index.d.ts +10 -0
- package/dist/ui/menu/index.js +7 -0
- package/dist/ui/menu/token.d.ts +22 -0
- package/dist/ui/menu/token.js +145 -0
- package/dist/ui/menu/useChatPicker.d.ts +24 -0
- package/dist/ui/menu/useChatPicker.js +210 -0
- package/dist/ui/navigation/Breadcrumb.css +30 -0
- package/dist/ui/navigation/Breadcrumb.d.ts +14 -0
- package/dist/ui/navigation/Breadcrumb.js +12 -0
- package/dist/ui/navigation/Link.css +13 -0
- package/dist/ui/navigation/Link.d.ts +18 -0
- package/dist/ui/navigation/Link.js +43 -0
- package/dist/ui/navigation/Tabs.css +39 -0
- package/dist/ui/navigation/Tabs.d.ts +18 -0
- package/dist/ui/navigation/Tabs.js +55 -0
- package/dist/ui/navigation/Toolbar.css +25 -0
- package/dist/ui/navigation/Toolbar.d.ts +12 -0
- package/dist/ui/navigation/Toolbar.js +21 -0
- package/dist/ui/navigation/catalog.d.ts +2 -0
- package/dist/ui/navigation/catalog.js +5 -0
- package/dist/ui/navigation/index.d.ts +8 -0
- package/dist/ui/navigation/index.js +5 -0
- package/dist/ui/overlay/Modal.css +35 -0
- package/dist/ui/overlay/Modal.d.ts +12 -0
- package/dist/ui/overlay/Modal.js +57 -0
- package/dist/ui/overlay/Popup.d.ts +12 -0
- package/dist/ui/overlay/Popup.js +74 -0
- package/dist/ui/overlay/catalog.d.ts +2 -0
- package/dist/ui/overlay/catalog.js +4 -0
- package/dist/ui/overlay/index.d.ts +1 -0
- package/dist/ui/overlay/index.js +2 -0
- package/dist/ui/register.d.ts +6 -0
- package/dist/ui/register.js +26 -0
- package/package.json +115 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { combineDisposables, disposableFrom } from '../core/disposable.js';
|
|
2
|
+
function tokenize(input) {
|
|
3
|
+
const tokens = [];
|
|
4
|
+
let i = 0;
|
|
5
|
+
while (i < input.length) {
|
|
6
|
+
const ch = input[i];
|
|
7
|
+
if (ch === ' ' || ch === '\t' || ch === '\n') {
|
|
8
|
+
i++;
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
if (ch === '(' || ch === ')') {
|
|
12
|
+
tokens.push({ kind: 'op', value: ch });
|
|
13
|
+
i++;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (ch === '!' && input[i + 1] === '=') {
|
|
17
|
+
tokens.push({ kind: 'op', value: '!=' });
|
|
18
|
+
i += 2;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (ch === '=' && input[i + 1] === '=') {
|
|
22
|
+
tokens.push({ kind: 'op', value: '==' });
|
|
23
|
+
i += 2;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (ch === '&' && input[i + 1] === '&') {
|
|
27
|
+
tokens.push({ kind: 'op', value: '&&' });
|
|
28
|
+
i += 2;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (ch === '|' && input[i + 1] === '|') {
|
|
32
|
+
tokens.push({ kind: 'op', value: '||' });
|
|
33
|
+
i += 2;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (ch === '!') {
|
|
37
|
+
tokens.push({ kind: 'op', value: '!' });
|
|
38
|
+
i++;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (ch === '"' || ch === "'") {
|
|
42
|
+
const quote = ch;
|
|
43
|
+
let j = i + 1;
|
|
44
|
+
let value = '';
|
|
45
|
+
while (j < input.length && input[j] !== quote) {
|
|
46
|
+
if (input[j] === '\\') {
|
|
47
|
+
value += input[j + 1] ?? '';
|
|
48
|
+
j += 2;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
value += input[j];
|
|
52
|
+
j++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
tokens.push({ kind: 'string', value });
|
|
56
|
+
i = j + 1;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Number / identifier / path. Path can include `:` and `.`.
|
|
60
|
+
let j = i;
|
|
61
|
+
while (j < input.length &&
|
|
62
|
+
!' \t\n()!=&|"\''.includes(input[j])) {
|
|
63
|
+
j++;
|
|
64
|
+
}
|
|
65
|
+
const word = input.slice(i, j);
|
|
66
|
+
if (/^-?\d+(\.\d+)?$/.test(word)) {
|
|
67
|
+
tokens.push({ kind: 'number', value: Number(word) });
|
|
68
|
+
}
|
|
69
|
+
else if (word === 'true')
|
|
70
|
+
tokens.push({ kind: 'bool', value: true });
|
|
71
|
+
else if (word === 'false')
|
|
72
|
+
tokens.push({ kind: 'bool', value: false });
|
|
73
|
+
else if (word === 'null')
|
|
74
|
+
tokens.push({ kind: 'null' });
|
|
75
|
+
else
|
|
76
|
+
tokens.push({ kind: 'path', value: word });
|
|
77
|
+
i = j;
|
|
78
|
+
}
|
|
79
|
+
return tokens;
|
|
80
|
+
}
|
|
81
|
+
function parse(tokens) {
|
|
82
|
+
let pos = 0;
|
|
83
|
+
function peek() {
|
|
84
|
+
return tokens[pos];
|
|
85
|
+
}
|
|
86
|
+
function consume() {
|
|
87
|
+
return tokens[pos++];
|
|
88
|
+
}
|
|
89
|
+
function parseExpression() {
|
|
90
|
+
return parseOr();
|
|
91
|
+
}
|
|
92
|
+
function parseOr() {
|
|
93
|
+
let left = parseAnd();
|
|
94
|
+
while (peek()?.kind === 'op' && peek().value === '||') {
|
|
95
|
+
consume();
|
|
96
|
+
left = { kind: 'or', left, right: parseAnd() };
|
|
97
|
+
}
|
|
98
|
+
return left;
|
|
99
|
+
}
|
|
100
|
+
function parseAnd() {
|
|
101
|
+
let left = parseNot();
|
|
102
|
+
while (peek()?.kind === 'op' && peek().value === '&&') {
|
|
103
|
+
consume();
|
|
104
|
+
left = { kind: 'and', left, right: parseNot() };
|
|
105
|
+
}
|
|
106
|
+
return left;
|
|
107
|
+
}
|
|
108
|
+
function parseNot() {
|
|
109
|
+
if (peek()?.kind === 'op' && peek().value === '!') {
|
|
110
|
+
consume();
|
|
111
|
+
return { kind: 'not', expr: parseNot() };
|
|
112
|
+
}
|
|
113
|
+
return parseAtom();
|
|
114
|
+
}
|
|
115
|
+
function parseAtom() {
|
|
116
|
+
const t = consume();
|
|
117
|
+
if (t.kind === 'op' && t.value === '(') {
|
|
118
|
+
const inner = parseExpression();
|
|
119
|
+
const close = consume();
|
|
120
|
+
if (!(close.kind === 'op' && close.value === ')')) {
|
|
121
|
+
throw new Error('when DSL: expected ")"');
|
|
122
|
+
}
|
|
123
|
+
return inner;
|
|
124
|
+
}
|
|
125
|
+
if (t.kind === 'string')
|
|
126
|
+
return { kind: 'literal', value: t.value };
|
|
127
|
+
if (t.kind === 'number')
|
|
128
|
+
return { kind: 'literal', value: t.value };
|
|
129
|
+
if (t.kind === 'bool')
|
|
130
|
+
return { kind: 'literal', value: t.value };
|
|
131
|
+
if (t.kind === 'null')
|
|
132
|
+
return { kind: 'literal', value: null };
|
|
133
|
+
if (t.kind === 'path') {
|
|
134
|
+
const left = { kind: 'path', value: t.value };
|
|
135
|
+
const next = peek();
|
|
136
|
+
if (next?.kind === 'op' && (next.value === '==' || next.value === '!=')) {
|
|
137
|
+
consume();
|
|
138
|
+
const right = parseAtom();
|
|
139
|
+
return { kind: next.value === '==' ? 'eq' : 'neq', left, right };
|
|
140
|
+
}
|
|
141
|
+
return left;
|
|
142
|
+
}
|
|
143
|
+
throw new Error(`when DSL: unexpected token ${JSON.stringify(t)}`);
|
|
144
|
+
}
|
|
145
|
+
return parseExpression();
|
|
146
|
+
}
|
|
147
|
+
function compile(input) {
|
|
148
|
+
return parse(tokenize(input));
|
|
149
|
+
}
|
|
150
|
+
function pathsOf(ast, out) {
|
|
151
|
+
switch (ast.kind) {
|
|
152
|
+
case 'literal':
|
|
153
|
+
return;
|
|
154
|
+
case 'path':
|
|
155
|
+
out.add(ast.value);
|
|
156
|
+
return;
|
|
157
|
+
case 'eq':
|
|
158
|
+
case 'neq':
|
|
159
|
+
case 'and':
|
|
160
|
+
case 'or':
|
|
161
|
+
pathsOf(ast.left, out);
|
|
162
|
+
pathsOf(ast.right, out);
|
|
163
|
+
return;
|
|
164
|
+
case 'not':
|
|
165
|
+
pathsOf(ast.expr, out);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
export function createWhenEngine(deps) {
|
|
170
|
+
const { store } = deps;
|
|
171
|
+
const cache = new Map();
|
|
172
|
+
function astFor(clause) {
|
|
173
|
+
let ast = cache.get(clause);
|
|
174
|
+
if (!ast) {
|
|
175
|
+
ast = compile(clause);
|
|
176
|
+
cache.set(clause, ast);
|
|
177
|
+
}
|
|
178
|
+
return ast;
|
|
179
|
+
}
|
|
180
|
+
function evalAst(ast, ctx) {
|
|
181
|
+
switch (ast.kind) {
|
|
182
|
+
case 'literal':
|
|
183
|
+
return ast.value;
|
|
184
|
+
case 'path':
|
|
185
|
+
return ctx?.[ast.value] ?? store.get(ast.value);
|
|
186
|
+
case 'eq':
|
|
187
|
+
return evalAst(ast.left, ctx) === evalAst(ast.right, ctx);
|
|
188
|
+
case 'neq':
|
|
189
|
+
return evalAst(ast.left, ctx) !== evalAst(ast.right, ctx);
|
|
190
|
+
case 'and':
|
|
191
|
+
return Boolean(evalAst(ast.left, ctx)) && Boolean(evalAst(ast.right, ctx));
|
|
192
|
+
case 'or':
|
|
193
|
+
return Boolean(evalAst(ast.left, ctx)) || Boolean(evalAst(ast.right, ctx));
|
|
194
|
+
case 'not':
|
|
195
|
+
return !evalAst(ast.expr, ctx);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function evaluate(clause, ctx) {
|
|
199
|
+
if (typeof clause === 'function')
|
|
200
|
+
return clause(ctx ?? {});
|
|
201
|
+
return Boolean(evalAst(astFor(clause), ctx));
|
|
202
|
+
}
|
|
203
|
+
function dependencies(clause) {
|
|
204
|
+
if (typeof clause === 'function')
|
|
205
|
+
return [];
|
|
206
|
+
const set = new Set();
|
|
207
|
+
pathsOf(astFor(clause), set);
|
|
208
|
+
return [...set];
|
|
209
|
+
}
|
|
210
|
+
function watch(clause, fn) {
|
|
211
|
+
let last = evaluate(clause);
|
|
212
|
+
fn(last);
|
|
213
|
+
const deps = dependencies(clause);
|
|
214
|
+
if (deps.length === 0)
|
|
215
|
+
return disposableFrom(() => { });
|
|
216
|
+
const subs = deps.map((p) => store.subscribe(p, () => {
|
|
217
|
+
const next = evaluate(clause);
|
|
218
|
+
if (next !== last) {
|
|
219
|
+
last = next;
|
|
220
|
+
fn(next);
|
|
221
|
+
}
|
|
222
|
+
}));
|
|
223
|
+
return combineDisposables(...subs);
|
|
224
|
+
}
|
|
225
|
+
return { evaluate, watch, dependencies };
|
|
226
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Converter } from '../types/converter-registry.js';
|
|
2
|
+
export interface A2uiComponentSpec {
|
|
3
|
+
id: string;
|
|
4
|
+
component: string;
|
|
5
|
+
[k: string]: unknown;
|
|
6
|
+
properties?: Record<string, unknown>;
|
|
7
|
+
child?: string;
|
|
8
|
+
children?: string | string[] | {
|
|
9
|
+
path: string;
|
|
10
|
+
componentId: string;
|
|
11
|
+
} | unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface A2uiCreateSurface {
|
|
14
|
+
components: Record<string, A2uiComponentSpec>;
|
|
15
|
+
root: string;
|
|
16
|
+
dataModel?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface A2uiConverterInput {
|
|
19
|
+
schema: 'a2ui/v0.10';
|
|
20
|
+
surfaceId: string;
|
|
21
|
+
payload: A2uiCreateSurface;
|
|
22
|
+
}
|
|
23
|
+
export declare const a2uiV010Converter: Converter;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
export const a2uiV010Converter = {
|
|
2
|
+
id: 'a2ui-v0.10',
|
|
3
|
+
accepts: { header: 'schema', value: 'a2ui/v0.10' },
|
|
4
|
+
translate(input) {
|
|
5
|
+
const env = input;
|
|
6
|
+
return translateNode(env.payload.root, env);
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
const RESERVED_TOP_LEVEL = new Set(['id', 'component', 'properties', 'child', 'children']);
|
|
10
|
+
function translateNode(id, env) {
|
|
11
|
+
const spec = env.payload.components[id];
|
|
12
|
+
if (!spec) {
|
|
13
|
+
return {
|
|
14
|
+
id,
|
|
15
|
+
component: 'MissingComponent',
|
|
16
|
+
reason: `a2ui component id "${id}" not found`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const node = {
|
|
20
|
+
id,
|
|
21
|
+
component: spec.component,
|
|
22
|
+
$meta: {
|
|
23
|
+
origin: { format: 'a2ui', version: '0.10', sourceNodeId: id },
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
// 1) Spec-first: every top-level key (except the structural ones) is a prop.
|
|
27
|
+
for (const [k, v] of Object.entries(spec)) {
|
|
28
|
+
if (RESERVED_TOP_LEVEL.has(k))
|
|
29
|
+
continue;
|
|
30
|
+
node[k] = translateValue(v);
|
|
31
|
+
}
|
|
32
|
+
// 2) Backward compat: nested `properties` object.
|
|
33
|
+
if (spec.properties && typeof spec.properties === 'object') {
|
|
34
|
+
for (const [k, v] of Object.entries(spec.properties)) {
|
|
35
|
+
node[k] = translateValue(v);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// 3) Singular child id reference.
|
|
39
|
+
if (typeof spec.child === 'string') {
|
|
40
|
+
node.child = translateNode(spec.child, env);
|
|
41
|
+
}
|
|
42
|
+
// 4) Children — id list, single id, dynamic { path, componentId }, or inline.
|
|
43
|
+
if (spec.children !== undefined) {
|
|
44
|
+
node.children = translateChildren(spec.children, env);
|
|
45
|
+
}
|
|
46
|
+
return node;
|
|
47
|
+
}
|
|
48
|
+
function translateChildren(v, env) {
|
|
49
|
+
if (typeof v === 'string') {
|
|
50
|
+
// single id — wrap in array
|
|
51
|
+
return [translateNode(v, env)];
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(v)) {
|
|
54
|
+
// string[] = id list (typical); fall back to translateValue for anything else
|
|
55
|
+
if (v.every((x) => typeof x === 'string')) {
|
|
56
|
+
return v.map((cid) => translateNode(cid, env));
|
|
57
|
+
}
|
|
58
|
+
return v.map(translateValue);
|
|
59
|
+
}
|
|
60
|
+
if (v && typeof v === 'object') {
|
|
61
|
+
const obj = v;
|
|
62
|
+
if (typeof obj.componentId === 'string' && typeof obj.path === 'string') {
|
|
63
|
+
// DynamicChildList → runtime form needs `{ template, path }`.
|
|
64
|
+
const template = translateNode(obj.componentId, env);
|
|
65
|
+
const list = {
|
|
66
|
+
template,
|
|
67
|
+
path: relativePath(obj.path),
|
|
68
|
+
};
|
|
69
|
+
return list;
|
|
70
|
+
}
|
|
71
|
+
if (obj.template && typeof obj.path === 'string') {
|
|
72
|
+
return {
|
|
73
|
+
template: obj.template,
|
|
74
|
+
path: relativePath(obj.path),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return translateValue(v);
|
|
79
|
+
}
|
|
80
|
+
function translateValue(v) {
|
|
81
|
+
if (v === null || typeof v !== 'object')
|
|
82
|
+
return v;
|
|
83
|
+
const obj = v;
|
|
84
|
+
// Old wrapper form: { dataBinding: { path: '...' } }
|
|
85
|
+
if ('dataBinding' in obj) {
|
|
86
|
+
const binding = obj.dataBinding;
|
|
87
|
+
return { path: relativePath(binding.path) };
|
|
88
|
+
}
|
|
89
|
+
// Spec-first DataBinding: { path: '<str>' } directly, often relative ('title').
|
|
90
|
+
// We normalize bare segments to '/title'. Excluded shapes (component/template/
|
|
91
|
+
// componentId) are handled higher up — here we just guard against false hits.
|
|
92
|
+
if (typeof obj.path === 'string' &&
|
|
93
|
+
!('component' in obj) &&
|
|
94
|
+
!('template' in obj) &&
|
|
95
|
+
!('componentId' in obj) &&
|
|
96
|
+
!('call' in obj) &&
|
|
97
|
+
!('event' in obj) &&
|
|
98
|
+
!('functionCall' in obj)) {
|
|
99
|
+
return { path: relativePath(obj.path) };
|
|
100
|
+
}
|
|
101
|
+
if ('action' in obj) {
|
|
102
|
+
const action = obj.action;
|
|
103
|
+
if (action.type === 'event') {
|
|
104
|
+
return {
|
|
105
|
+
event: {
|
|
106
|
+
name: action.name,
|
|
107
|
+
context: action.context,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (action.type === 'functionCall') {
|
|
112
|
+
return {
|
|
113
|
+
functionCall: {
|
|
114
|
+
call: action.name,
|
|
115
|
+
args: action.args,
|
|
116
|
+
callableFrom: action.callableFrom === 'clientOnly' ? 'clientOnly' : undefined,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (Array.isArray(v)) {
|
|
122
|
+
return v.map(translateValue);
|
|
123
|
+
}
|
|
124
|
+
const out = {};
|
|
125
|
+
for (const [k, inner] of Object.entries(obj)) {
|
|
126
|
+
out[k] = translateValue(inner);
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
// Paths like `flightNumber` or `users.0.name` → `/flightNumber` / `/users/0/name`.
|
|
131
|
+
// Absolute (`$/`) and relative (`/`) paths pass through unchanged.
|
|
132
|
+
function relativePath(p) {
|
|
133
|
+
if (p.startsWith('$/') || p.startsWith('/'))
|
|
134
|
+
return p;
|
|
135
|
+
return '/' + p.replace(/\./g, '/');
|
|
136
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { a2uiV010Converter, type A2uiCreateSurface, type A2uiComponentSpec, type A2uiConverterInput, } from './a2ui-v0.10.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { a2uiV010Converter, } from './a2ui-v0.10.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ScopeBackend } from '../../types/scope-backend.js';
|
|
2
|
+
export type ModusClass = 'xsmall' | 'small' | 'medium' | 'large';
|
|
3
|
+
export interface ModusBreakpoints {
|
|
4
|
+
small: number;
|
|
5
|
+
medium: number;
|
|
6
|
+
large: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const DEFAULT_MODUS_BREAKPOINTS: ModusBreakpoints;
|
|
9
|
+
export interface ModusBackendOptions {
|
|
10
|
+
scope?: string;
|
|
11
|
+
breakpoints?: Partial<ModusBreakpoints>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createModusBackend(opts?: ModusBackendOptions): ScopeBackend;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export const DEFAULT_MODUS_BREAKPOINTS = {
|
|
2
|
+
small: 640,
|
|
3
|
+
medium: 1024,
|
|
4
|
+
large: 1440,
|
|
5
|
+
};
|
|
6
|
+
const KEYS = [
|
|
7
|
+
'class',
|
|
8
|
+
'width',
|
|
9
|
+
'height',
|
|
10
|
+
'compact',
|
|
11
|
+
'large',
|
|
12
|
+
'portrait',
|
|
13
|
+
'coarse',
|
|
14
|
+
];
|
|
15
|
+
function classify(width, bp) {
|
|
16
|
+
if (width >= bp.large)
|
|
17
|
+
return 'large';
|
|
18
|
+
if (width >= bp.medium)
|
|
19
|
+
return 'medium';
|
|
20
|
+
if (width >= bp.small)
|
|
21
|
+
return 'small';
|
|
22
|
+
return 'xsmall';
|
|
23
|
+
}
|
|
24
|
+
// Used when there is no DOM (SSR, node test runners). A fixed desktop-ish
|
|
25
|
+
// reading is the honest default: it renders the full shell, which degrades
|
|
26
|
+
// visibly rather than silently hiding surfaces on a server render.
|
|
27
|
+
function staticSnapshot(bp) {
|
|
28
|
+
const width = bp.medium;
|
|
29
|
+
return {
|
|
30
|
+
class: classify(width, bp),
|
|
31
|
+
width,
|
|
32
|
+
height: 768,
|
|
33
|
+
compact: false,
|
|
34
|
+
large: false,
|
|
35
|
+
portrait: false,
|
|
36
|
+
coarse: false,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function readSnapshot(bp) {
|
|
40
|
+
const width = window.innerWidth;
|
|
41
|
+
const height = window.innerHeight;
|
|
42
|
+
const cls = classify(width, bp);
|
|
43
|
+
return {
|
|
44
|
+
class: cls,
|
|
45
|
+
width,
|
|
46
|
+
height,
|
|
47
|
+
compact: cls === 'xsmall' || cls === 'small',
|
|
48
|
+
large: cls === 'large',
|
|
49
|
+
portrait: height > width,
|
|
50
|
+
coarse: window.matchMedia('(pointer: coarse)').matches,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function createModusBackend(opts = {}) {
|
|
54
|
+
const scope = opts.scope ?? 'modus';
|
|
55
|
+
const bp = { ...DEFAULT_MODUS_BREAKPOINTS, ...opts.breakpoints };
|
|
56
|
+
const hasDom = typeof window !== 'undefined' && typeof window.matchMedia === 'function';
|
|
57
|
+
let snapshot = hasDom ? readSnapshot(bp) : staticSnapshot(bp);
|
|
58
|
+
// Only keys that have actually been read are re-emitted, so a shell that
|
|
59
|
+
// binds `class` alone stays quiet through a resize that changes `width`
|
|
60
|
+
// every frame.
|
|
61
|
+
const accessed = new Set();
|
|
62
|
+
return {
|
|
63
|
+
get(segments) {
|
|
64
|
+
if (segments.length !== 1)
|
|
65
|
+
return { hasValue: false, value: undefined };
|
|
66
|
+
const key = segments[0];
|
|
67
|
+
if (!KEYS.includes(key)) {
|
|
68
|
+
return { hasValue: false, value: undefined };
|
|
69
|
+
}
|
|
70
|
+
accessed.add(key);
|
|
71
|
+
return { hasValue: true, value: snapshot[key] };
|
|
72
|
+
},
|
|
73
|
+
set() {
|
|
74
|
+
/* derived from the environment; not writable through the store */
|
|
75
|
+
},
|
|
76
|
+
delete() { },
|
|
77
|
+
clear() { },
|
|
78
|
+
attach(emit) {
|
|
79
|
+
if (!hasDom)
|
|
80
|
+
return { dispose: () => { } };
|
|
81
|
+
let frame = null;
|
|
82
|
+
function recompute() {
|
|
83
|
+
const next = readSnapshot(bp);
|
|
84
|
+
const prev = snapshot;
|
|
85
|
+
snapshot = next;
|
|
86
|
+
for (const key of accessed) {
|
|
87
|
+
if (prev[key] !== next[key]) {
|
|
88
|
+
emit(`$/${scope}/${key}`, next[key]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// resize fires per frame during a drag; coalesce so subscribers see at
|
|
93
|
+
// most one notification per frame, and none at all when nothing changed.
|
|
94
|
+
function onResize() {
|
|
95
|
+
if (frame !== null)
|
|
96
|
+
return;
|
|
97
|
+
frame = requestAnimationFrame(() => {
|
|
98
|
+
frame = null;
|
|
99
|
+
recompute();
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const pointer = window.matchMedia('(pointer: coarse)');
|
|
103
|
+
window.addEventListener('resize', onResize);
|
|
104
|
+
pointer.addEventListener('change', recompute);
|
|
105
|
+
return {
|
|
106
|
+
dispose() {
|
|
107
|
+
if (frame !== null)
|
|
108
|
+
cancelAnimationFrame(frame);
|
|
109
|
+
window.removeEventListener('resize', onResize);
|
|
110
|
+
pointer.removeEventListener('change', recompute);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ScopeBackend } from '../../types/scope-backend.js';
|
|
2
|
+
export interface BackendStorage {
|
|
3
|
+
load(): Record<string, unknown> | null;
|
|
4
|
+
save(data: Record<string, unknown>): void;
|
|
5
|
+
}
|
|
6
|
+
export declare function createLocalStorageStorage(key: string): BackendStorage;
|
|
7
|
+
export declare function createStorageBackend(scope: string, storage: BackendStorage): ScopeBackend;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// localStorage-backed adapter (browser / dev). No-op outside a window.
|
|
2
|
+
export function createLocalStorageStorage(key) {
|
|
3
|
+
return {
|
|
4
|
+
load() {
|
|
5
|
+
if (typeof window === 'undefined')
|
|
6
|
+
return null;
|
|
7
|
+
const raw = window.localStorage.getItem(key);
|
|
8
|
+
if (!raw)
|
|
9
|
+
return null;
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(raw);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
save(data) {
|
|
18
|
+
if (typeof window === 'undefined')
|
|
19
|
+
return;
|
|
20
|
+
window.localStorage.setItem(key, JSON.stringify(data));
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// A ScopeBackend that persists its scope's values through a BackendStorage.
|
|
25
|
+
// Values live in an in-memory snapshot keyed by the segment-joined sub-path;
|
|
26
|
+
// writes are coalesced to one save per microtask. attach() hydrates from
|
|
27
|
+
// storage and emits each loaded path so live subscribers refresh.
|
|
28
|
+
export function createStorageBackend(scope, storage) {
|
|
29
|
+
const data = {};
|
|
30
|
+
let saveScheduled = false;
|
|
31
|
+
const key = (segs) => segs.join('/');
|
|
32
|
+
const abs = (subKey) => `$/${scope}/${subKey}`;
|
|
33
|
+
function scheduleSave() {
|
|
34
|
+
if (saveScheduled)
|
|
35
|
+
return;
|
|
36
|
+
saveScheduled = true;
|
|
37
|
+
queueMicrotask(() => {
|
|
38
|
+
saveScheduled = false;
|
|
39
|
+
storage.save({ ...data });
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
get(segs) {
|
|
44
|
+
const k = key(segs);
|
|
45
|
+
return Object.prototype.hasOwnProperty.call(data, k)
|
|
46
|
+
? { hasValue: true, value: data[k] }
|
|
47
|
+
: { hasValue: false, value: undefined };
|
|
48
|
+
},
|
|
49
|
+
set(segs, value) {
|
|
50
|
+
data[key(segs)] = value;
|
|
51
|
+
scheduleSave();
|
|
52
|
+
},
|
|
53
|
+
delete(segs) {
|
|
54
|
+
delete data[key(segs)];
|
|
55
|
+
scheduleSave();
|
|
56
|
+
},
|
|
57
|
+
clear() {
|
|
58
|
+
for (const k of Object.keys(data))
|
|
59
|
+
delete data[k];
|
|
60
|
+
scheduleSave();
|
|
61
|
+
},
|
|
62
|
+
attach(emit) {
|
|
63
|
+
const loaded = storage.load();
|
|
64
|
+
if (loaded) {
|
|
65
|
+
for (const [k, v] of Object.entries(loaded)) {
|
|
66
|
+
data[k] = v;
|
|
67
|
+
emit(abs(k), v);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { dispose() { } };
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ScopeBackend backed by a Yjs Y.Map (flat sub-path key -> value). Stores that
|
|
2
|
+
// share a Y.Doc (or synced docs) converge; external Yjs updates push through
|
|
3
|
+
// attach()'s observer into the store's notification layer. Intended for $/page
|
|
4
|
+
// (Tela collaboration) and node tests.
|
|
5
|
+
//
|
|
6
|
+
// `yjs` is imported TYPE-ONLY here, so the scena core carries no runtime
|
|
7
|
+
// dependency on it — only callers that actually construct a backend (passing a
|
|
8
|
+
// Y.Doc) need `yjs` installed.
|
|
9
|
+
export function createYjsBackend(scope, doc, mapName = 'scena') {
|
|
10
|
+
const map = doc.getMap(mapName);
|
|
11
|
+
const key = (segs) => segs.join('/');
|
|
12
|
+
const abs = (k) => `$/${scope}/${k}`;
|
|
13
|
+
return {
|
|
14
|
+
get(segs) {
|
|
15
|
+
const k = key(segs);
|
|
16
|
+
return map.has(k)
|
|
17
|
+
? { hasValue: true, value: map.get(k) }
|
|
18
|
+
: { hasValue: false, value: undefined };
|
|
19
|
+
},
|
|
20
|
+
set(segs, value) {
|
|
21
|
+
map.set(key(segs), value);
|
|
22
|
+
},
|
|
23
|
+
delete(segs) {
|
|
24
|
+
map.delete(key(segs));
|
|
25
|
+
},
|
|
26
|
+
clear() {
|
|
27
|
+
map.clear();
|
|
28
|
+
},
|
|
29
|
+
attach(emit) {
|
|
30
|
+
const observer = (event) => {
|
|
31
|
+
event.changes.keys.forEach((_change, k) => {
|
|
32
|
+
emit(abs(k), map.has(k) ? map.get(k) : undefined);
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
map.observe(observer);
|
|
36
|
+
const disposable = {
|
|
37
|
+
dispose() {
|
|
38
|
+
map.unobserve(observer);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
return disposable;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BindingResolver } from '../types/binding-resolver.js';
|
|
2
|
+
import type { ReactiveStore } from '../types/reactive-store.js';
|
|
3
|
+
interface Deps {
|
|
4
|
+
store: ReactiveStore;
|
|
5
|
+
}
|
|
6
|
+
export declare function createBindingResolver(deps: Deps): BindingResolver;
|
|
7
|
+
export {};
|