@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,20 @@
|
|
|
1
|
+
import { createContext, useCallback, useContext } from 'react';
|
|
2
|
+
// Active mount key — used by useStore to rewrite `$/local/<rest>` paths to
|
|
3
|
+
// `$/local/<mountKey>/<rest>`. Set by MountWrapper around each rendered mount.
|
|
4
|
+
export const MountContext = createContext(null);
|
|
5
|
+
export function useCurrentMountKey() {
|
|
6
|
+
return useContext(MountContext);
|
|
7
|
+
}
|
|
8
|
+
// Data context — absolute path string that anchors all `/...` relative paths
|
|
9
|
+
// inside a mount or template instance. Defaults to undefined (no data context).
|
|
10
|
+
export const DataContextContext = createContext(undefined);
|
|
11
|
+
export function useDataContext() {
|
|
12
|
+
return useContext(DataContextContext);
|
|
13
|
+
}
|
|
14
|
+
export const WriteContext = createContext(null);
|
|
15
|
+
export function useWriteBack(propName) {
|
|
16
|
+
const write = useContext(WriteContext);
|
|
17
|
+
return useCallback((next) => {
|
|
18
|
+
write?.(propName, next);
|
|
19
|
+
}, [write, propName]);
|
|
20
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type PointerEvent as ReactPointerEvent } from 'react';
|
|
2
|
+
import type { SurfaceName } from '../types/mount-surface.js';
|
|
3
|
+
import type { SurfacePresentation } from '../types/layout.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resizing a surface by its own edge, with no handle in the layout.
|
|
6
|
+
*
|
|
7
|
+
* The alternative to `ShellSplitter`, and a different model rather than a
|
|
8
|
+
* restyle of it. A splitter is a real element the shell has to place between two
|
|
9
|
+
* surfaces; it takes part in flex, it has to be conditionally rendered next to
|
|
10
|
+
* whichever surfaces happen to be visible, and its hit area is its width. Here
|
|
11
|
+
* the grip is a `::after` on the surface, so it costs the layout nothing, it
|
|
12
|
+
* cannot be rendered in the wrong place, and the hit zone is 10px while the line
|
|
13
|
+
* stays 1px.
|
|
14
|
+
*
|
|
15
|
+
* It also self-disables. A surface that is floating, sheeted or reduced to a bar
|
|
16
|
+
* has no dock boundary to drag, and the grip disappears with the presentation
|
|
17
|
+
* rather than the shell having to remember to stop rendering a splitter.
|
|
18
|
+
*/
|
|
19
|
+
export interface SurfaceResizeSpec {
|
|
20
|
+
/**
|
|
21
|
+
* Which of the surface's own edges carries the grip.
|
|
22
|
+
*
|
|
23
|
+
* The edge is the side that moves: a left sidebar is resized by its `right`
|
|
24
|
+
* edge, a right sidebar by its `left`, a bottom panel by its `top`.
|
|
25
|
+
*/
|
|
26
|
+
edge: 'left' | 'right' | 'top' | 'bottom';
|
|
27
|
+
min?: number;
|
|
28
|
+
max?: number;
|
|
29
|
+
/** Hit zone in px. The visible line is 1px regardless. Default 10. */
|
|
30
|
+
grip?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface SurfaceResizeBinding {
|
|
33
|
+
ref: (node: HTMLDivElement | null) => void;
|
|
34
|
+
'data-resize'?: string;
|
|
35
|
+
onPointerMove?: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
36
|
+
onPointerLeave?: () => void;
|
|
37
|
+
onPointerDown?: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
38
|
+
}
|
|
39
|
+
export declare function useSurfaceResize(surface: SurfaceName, presentation: SurfacePresentation, spec: SurfaceResizeSpec | undefined): SurfaceResizeBinding;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
|
2
|
+
import { useScena } from './ScenaProvider.js';
|
|
3
|
+
/** Only a docked surface has a boundary worth dragging. */
|
|
4
|
+
function resizableIn(presentation) {
|
|
5
|
+
return presentation === 'docked';
|
|
6
|
+
}
|
|
7
|
+
function withinGrip(element, edge, clientX, clientY, grip) {
|
|
8
|
+
const rect = element.getBoundingClientRect();
|
|
9
|
+
if (edge === 'right')
|
|
10
|
+
return clientX >= rect.right - grip && clientX <= rect.right;
|
|
11
|
+
if (edge === 'left')
|
|
12
|
+
return clientX <= rect.left + grip && clientX >= rect.left;
|
|
13
|
+
if (edge === 'top')
|
|
14
|
+
return clientY <= rect.top + grip && clientY >= rect.top;
|
|
15
|
+
return clientY >= rect.bottom - grip && clientY <= rect.bottom;
|
|
16
|
+
}
|
|
17
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
18
|
+
export function useSurfaceResize(surface, presentation, spec) {
|
|
19
|
+
const scena = useScena();
|
|
20
|
+
const elementRef = useRef(null);
|
|
21
|
+
const draggingRef = useRef(false);
|
|
22
|
+
const rafRef = useRef(null);
|
|
23
|
+
// Separate from the frame handle. The handle is assigned *after*
|
|
24
|
+
// requestAnimationFrame returns, so a callback that runs before that (a
|
|
25
|
+
// synchronous or already-due frame) has its `null` overwritten by the
|
|
26
|
+
// assignment and no further frame is ever scheduled.
|
|
27
|
+
const scheduledRef = useRef(false);
|
|
28
|
+
const pendingRef = useRef(null);
|
|
29
|
+
const ref = useCallback((node) => {
|
|
30
|
+
elementRef.current = node;
|
|
31
|
+
}, []);
|
|
32
|
+
const active = spec !== undefined && resizableIn(presentation);
|
|
33
|
+
const edge = spec?.edge ?? 'right';
|
|
34
|
+
const grip = spec?.grip ?? 10;
|
|
35
|
+
const min = spec?.min ?? 100;
|
|
36
|
+
const max = spec?.max ?? 800;
|
|
37
|
+
const vertical = edge === 'left' || edge === 'right';
|
|
38
|
+
// `data-resize-state` is written straight to the node rather than held in
|
|
39
|
+
// state: it changes on every pointermove across the surface, and a re-render
|
|
40
|
+
// per mouse move is exactly the cost this whole model is avoiding.
|
|
41
|
+
const mark = useCallback((state) => {
|
|
42
|
+
elementRef.current?.setAttribute('data-resize-state', state);
|
|
43
|
+
}, []);
|
|
44
|
+
const commit = useCallback((transient) => {
|
|
45
|
+
scheduledRef.current = false;
|
|
46
|
+
if (pendingRef.current !== null) {
|
|
47
|
+
scena.layout.setSurface(surface, { size: pendingRef.current }, { transient });
|
|
48
|
+
pendingRef.current = null;
|
|
49
|
+
}
|
|
50
|
+
}, [scena, surface]);
|
|
51
|
+
const onPointerMove = useCallback((event) => {
|
|
52
|
+
const element = elementRef.current;
|
|
53
|
+
if (element === null || !active)
|
|
54
|
+
return;
|
|
55
|
+
if (draggingRef.current)
|
|
56
|
+
return;
|
|
57
|
+
mark(withinGrip(element, edge, event.clientX, event.clientY, grip) ? 'hot' : 'idle');
|
|
58
|
+
}, [active, edge, grip, mark]);
|
|
59
|
+
const onPointerLeave = useCallback(() => {
|
|
60
|
+
if (!draggingRef.current)
|
|
61
|
+
mark('idle');
|
|
62
|
+
}, [mark]);
|
|
63
|
+
const onPointerDown = useCallback((event) => {
|
|
64
|
+
const element = elementRef.current;
|
|
65
|
+
if (element === null || !active)
|
|
66
|
+
return;
|
|
67
|
+
if (!withinGrip(element, edge, event.clientX, event.clientY, grip))
|
|
68
|
+
return;
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
const rect = element.getBoundingClientRect();
|
|
71
|
+
// Measured, not read from layout state: a surface whose size has never
|
|
72
|
+
// been set still has a real width, and the drag should start from it
|
|
73
|
+
// rather than from a default that would make it jump on the first pixel.
|
|
74
|
+
const startSize = vertical ? rect.width : rect.height;
|
|
75
|
+
const startPos = vertical ? event.clientX : event.clientY;
|
|
76
|
+
// The edge that moves toward the surface's origin grows it as the pointer
|
|
77
|
+
// travels backwards, so the delta is inverted for `left` and `top`.
|
|
78
|
+
const sign = edge === 'right' || edge === 'bottom' ? 1 : -1;
|
|
79
|
+
draggingRef.current = true;
|
|
80
|
+
mark('active');
|
|
81
|
+
document.documentElement.classList.add('oo-resizing');
|
|
82
|
+
document.documentElement.style.cursor = vertical ? 'ew-resize' : 'ns-resize';
|
|
83
|
+
element.setPointerCapture(event.pointerId);
|
|
84
|
+
const move = (moveEvent) => {
|
|
85
|
+
const pos = vertical ? moveEvent.clientX : moveEvent.clientY;
|
|
86
|
+
pendingRef.current = clamp(startSize + sign * (pos - startPos), min, max);
|
|
87
|
+
if (!scheduledRef.current) {
|
|
88
|
+
scheduledRef.current = true;
|
|
89
|
+
rafRef.current = requestAnimationFrame(() => commit(true));
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const end = (endEvent) => {
|
|
93
|
+
element.removeEventListener('pointermove', move);
|
|
94
|
+
element.removeEventListener('pointerup', end);
|
|
95
|
+
element.removeEventListener('pointercancel', end);
|
|
96
|
+
if (rafRef.current !== null) {
|
|
97
|
+
cancelAnimationFrame(rafRef.current);
|
|
98
|
+
rafRef.current = null;
|
|
99
|
+
}
|
|
100
|
+
scheduledRef.current = false;
|
|
101
|
+
// The settled write. Everything during the drag was transient, so
|
|
102
|
+
// without this the size never reaches the store or storage.
|
|
103
|
+
//
|
|
104
|
+
// The fallback is the *live* size, not the size the drag started from:
|
|
105
|
+
// by here the last transient frame has usually already been applied and
|
|
106
|
+
// cleared `pending`, so starting over from `startSize` would end the
|
|
107
|
+
// gesture by committing the width the user just spent it changing.
|
|
108
|
+
pendingRef.current ??=
|
|
109
|
+
scena.layout.get().surfaces[surface]?.size ?? startSize;
|
|
110
|
+
commit(false);
|
|
111
|
+
draggingRef.current = false;
|
|
112
|
+
mark('idle');
|
|
113
|
+
document.documentElement.classList.remove('oo-resizing');
|
|
114
|
+
document.documentElement.style.cursor = '';
|
|
115
|
+
if (element.hasPointerCapture(endEvent.pointerId)) {
|
|
116
|
+
element.releasePointerCapture(endEvent.pointerId);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
// Listened on the element, not the document: the pointer is captured, so
|
|
120
|
+
// every move is delivered here until release, and nothing else on the page
|
|
121
|
+
// has to be told a drag is in progress.
|
|
122
|
+
element.addEventListener('pointermove', move);
|
|
123
|
+
element.addEventListener('pointerup', end);
|
|
124
|
+
element.addEventListener('pointercancel', end);
|
|
125
|
+
}, [active, edge, grip, vertical, min, max, mark, commit, scena, surface]);
|
|
126
|
+
if (!active)
|
|
127
|
+
return { ref };
|
|
128
|
+
return {
|
|
129
|
+
ref,
|
|
130
|
+
'data-resize': edge,
|
|
131
|
+
onPointerMove,
|
|
132
|
+
onPointerLeave,
|
|
133
|
+
onPointerDown,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ArgsSchema, ArgType } from '../types/command.js';
|
|
2
|
+
export type ValidateArgsResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
value: Record<string, unknown>;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
errors: string[];
|
|
8
|
+
};
|
|
9
|
+
export declare function validateArgs(schema: ArgsSchema | undefined, input: unknown): ValidateArgsResult;
|
|
10
|
+
export declare function isPermissionPath(path: string): boolean;
|
|
11
|
+
export type { ArgsSchema, ArgType };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function validateArgs(schema, input) {
|
|
2
|
+
if (!schema) {
|
|
3
|
+
return {
|
|
4
|
+
ok: true,
|
|
5
|
+
value: input ?? {},
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
const obj = (input ?? {});
|
|
9
|
+
const value = {};
|
|
10
|
+
const errors = [];
|
|
11
|
+
for (const [key, type] of Object.entries(schema)) {
|
|
12
|
+
const v = obj[key];
|
|
13
|
+
if (Array.isArray(type)) {
|
|
14
|
+
if (v === undefined) {
|
|
15
|
+
errors.push(`${key}: required (enum: ${type.join(' | ')})`);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (typeof v !== 'string' || !type.includes(v)) {
|
|
19
|
+
errors.push(`${key}: expected one of ${type.join(' | ')}`);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
value[key] = v;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const typeStr = type;
|
|
26
|
+
const optional = typeStr.endsWith('?');
|
|
27
|
+
const base = (optional ? typeStr.slice(0, -1) : typeStr);
|
|
28
|
+
if (v === undefined || v === null) {
|
|
29
|
+
if (!optional)
|
|
30
|
+
errors.push(`${key}: required (${base})`);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (typeof v !== base) {
|
|
34
|
+
errors.push(`${key}: expected ${base}, got ${typeof v}`);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
value[key] = v;
|
|
38
|
+
}
|
|
39
|
+
return errors.length > 0 ? { ok: false, errors } : { ok: true, value };
|
|
40
|
+
}
|
|
41
|
+
// `$/scope/seg/seg`-style absolute path. Trailing `/*` allowed for prefix
|
|
42
|
+
// permissions; segments may contain alphanumerics, `_`, `-`, `.`, `:`.
|
|
43
|
+
export function isPermissionPath(path) {
|
|
44
|
+
return /^\$\/[A-Za-z][\w:.-]*(\/[\w:.*-]+)*$/.test(path);
|
|
45
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { combineDisposables } from '../core/disposable.js';
|
|
2
|
+
// The 14 a2ui v0.10 basic-catalog functions, registered as commands at
|
|
3
|
+
// createScena() time. All declare callableFrom: 'clientOnly' semantics
|
|
4
|
+
// (dispatch: 'client' here — they don't round-trip through the socket).
|
|
5
|
+
function arg(args, key) {
|
|
6
|
+
if (!args || typeof args !== 'object')
|
|
7
|
+
return undefined;
|
|
8
|
+
return args[key];
|
|
9
|
+
}
|
|
10
|
+
function toStr(v) {
|
|
11
|
+
return v === null || v === undefined ? '' : String(v);
|
|
12
|
+
}
|
|
13
|
+
function toNum(v) {
|
|
14
|
+
if (typeof v === 'number')
|
|
15
|
+
return v;
|
|
16
|
+
if (typeof v === 'string' && v.trim() !== '') {
|
|
17
|
+
const n = Number(v);
|
|
18
|
+
if (!Number.isNaN(n))
|
|
19
|
+
return n;
|
|
20
|
+
}
|
|
21
|
+
return Number.NaN;
|
|
22
|
+
}
|
|
23
|
+
const validation = (scena) => {
|
|
24
|
+
return combineDisposables(scena.commands.register({
|
|
25
|
+
id: 'required',
|
|
26
|
+
title: 'required',
|
|
27
|
+
dispatch: 'client',
|
|
28
|
+
run: (_ctx, a) => {
|
|
29
|
+
const v = arg(a, 'value');
|
|
30
|
+
return v !== undefined && v !== null && v !== '';
|
|
31
|
+
},
|
|
32
|
+
}), scena.commands.register({
|
|
33
|
+
id: 'regex',
|
|
34
|
+
title: 'regex',
|
|
35
|
+
dispatch: 'client',
|
|
36
|
+
run: (_ctx, a) => {
|
|
37
|
+
const value = toStr(arg(a, 'value'));
|
|
38
|
+
const pattern = toStr(arg(a, 'pattern'));
|
|
39
|
+
const flags = toStr(arg(a, 'flags'));
|
|
40
|
+
if (!pattern)
|
|
41
|
+
return true;
|
|
42
|
+
try {
|
|
43
|
+
return new RegExp(pattern, flags || undefined).test(value);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
}), scena.commands.register({
|
|
50
|
+
id: 'length',
|
|
51
|
+
title: 'length',
|
|
52
|
+
dispatch: 'client',
|
|
53
|
+
run: (_ctx, a) => {
|
|
54
|
+
const value = toStr(arg(a, 'value'));
|
|
55
|
+
const min = arg(a, 'min');
|
|
56
|
+
const max = arg(a, 'max');
|
|
57
|
+
if (min !== undefined && value.length < min)
|
|
58
|
+
return false;
|
|
59
|
+
if (max !== undefined && value.length > max)
|
|
60
|
+
return false;
|
|
61
|
+
return true;
|
|
62
|
+
},
|
|
63
|
+
}), scena.commands.register({
|
|
64
|
+
id: 'numeric',
|
|
65
|
+
title: 'numeric',
|
|
66
|
+
dispatch: 'client',
|
|
67
|
+
run: (_ctx, a) => {
|
|
68
|
+
const n = toNum(arg(a, 'value'));
|
|
69
|
+
return !Number.isNaN(n);
|
|
70
|
+
},
|
|
71
|
+
}), scena.commands.register({
|
|
72
|
+
id: 'email',
|
|
73
|
+
title: 'email',
|
|
74
|
+
dispatch: 'client',
|
|
75
|
+
run: (_ctx, a) => {
|
|
76
|
+
const v = toStr(arg(a, 'value'));
|
|
77
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
80
|
+
};
|
|
81
|
+
const format = (scena) => {
|
|
82
|
+
return combineDisposables(scena.commands.register({
|
|
83
|
+
id: 'formatString',
|
|
84
|
+
title: 'formatString',
|
|
85
|
+
dispatch: 'client',
|
|
86
|
+
run: (_ctx, a) => {
|
|
87
|
+
const template = toStr(arg(a, 'template'));
|
|
88
|
+
const values = (arg(a, 'values') ?? {});
|
|
89
|
+
return template.replace(/\{([^}]+)\}/g, (_, k) => toStr(values[k]));
|
|
90
|
+
},
|
|
91
|
+
}), scena.commands.register({
|
|
92
|
+
id: 'formatNumber',
|
|
93
|
+
title: 'formatNumber',
|
|
94
|
+
dispatch: 'client',
|
|
95
|
+
run: (_ctx, a) => {
|
|
96
|
+
const n = toNum(arg(a, 'value'));
|
|
97
|
+
if (Number.isNaN(n))
|
|
98
|
+
return '';
|
|
99
|
+
const locale = arg(a, 'locale');
|
|
100
|
+
const minimumFractionDigits = arg(a, 'minimumFractionDigits');
|
|
101
|
+
const maximumFractionDigits = arg(a, 'maximumFractionDigits');
|
|
102
|
+
return new Intl.NumberFormat(locale, {
|
|
103
|
+
minimumFractionDigits,
|
|
104
|
+
maximumFractionDigits,
|
|
105
|
+
}).format(n);
|
|
106
|
+
},
|
|
107
|
+
}), scena.commands.register({
|
|
108
|
+
id: 'formatCurrency',
|
|
109
|
+
title: 'formatCurrency',
|
|
110
|
+
dispatch: 'client',
|
|
111
|
+
run: (_ctx, a) => {
|
|
112
|
+
const n = toNum(arg(a, 'value'));
|
|
113
|
+
if (Number.isNaN(n))
|
|
114
|
+
return '';
|
|
115
|
+
const currency = toStr(arg(a, 'currency')) || 'USD';
|
|
116
|
+
const locale = arg(a, 'locale');
|
|
117
|
+
return new Intl.NumberFormat(locale, {
|
|
118
|
+
style: 'currency',
|
|
119
|
+
currency,
|
|
120
|
+
}).format(n);
|
|
121
|
+
},
|
|
122
|
+
}), scena.commands.register({
|
|
123
|
+
id: 'formatDate',
|
|
124
|
+
title: 'formatDate',
|
|
125
|
+
dispatch: 'client',
|
|
126
|
+
run: (_ctx, a) => {
|
|
127
|
+
const v = arg(a, 'value');
|
|
128
|
+
if (v === undefined || v === null || v === '')
|
|
129
|
+
return '';
|
|
130
|
+
const d = v instanceof Date ? v : new Date(v);
|
|
131
|
+
if (Number.isNaN(d.getTime()))
|
|
132
|
+
return '';
|
|
133
|
+
const locale = arg(a, 'locale');
|
|
134
|
+
const options = arg(a, 'options');
|
|
135
|
+
return new Intl.DateTimeFormat(locale, options).format(d);
|
|
136
|
+
},
|
|
137
|
+
}), scena.commands.register({
|
|
138
|
+
id: 'pluralize',
|
|
139
|
+
title: 'pluralize',
|
|
140
|
+
dispatch: 'client',
|
|
141
|
+
run: (_ctx, a) => {
|
|
142
|
+
const count = toNum(arg(a, 'count'));
|
|
143
|
+
const one = toStr(arg(a, 'one'));
|
|
144
|
+
const other = toStr(arg(a, 'other'));
|
|
145
|
+
return count === 1 ? one : other;
|
|
146
|
+
},
|
|
147
|
+
}));
|
|
148
|
+
};
|
|
149
|
+
const navigation = (scena) => {
|
|
150
|
+
return scena.commands.register({
|
|
151
|
+
id: 'openUrl',
|
|
152
|
+
title: 'openUrl',
|
|
153
|
+
dispatch: 'client',
|
|
154
|
+
run: (_ctx, a) => {
|
|
155
|
+
const url = toStr(arg(a, 'url'));
|
|
156
|
+
if (!url)
|
|
157
|
+
return;
|
|
158
|
+
if (typeof window !== 'undefined') {
|
|
159
|
+
const target = toStr(arg(a, 'target')) || '_blank';
|
|
160
|
+
window.open(url, target);
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
const logic = (scena) => {
|
|
166
|
+
return combineDisposables(scena.commands.register({
|
|
167
|
+
id: 'and',
|
|
168
|
+
title: 'and',
|
|
169
|
+
dispatch: 'client',
|
|
170
|
+
run: (_ctx, a) => {
|
|
171
|
+
const values = arg(a, 'values') ?? [];
|
|
172
|
+
return values.every(Boolean);
|
|
173
|
+
},
|
|
174
|
+
}), scena.commands.register({
|
|
175
|
+
id: 'or',
|
|
176
|
+
title: 'or',
|
|
177
|
+
dispatch: 'client',
|
|
178
|
+
run: (_ctx, a) => {
|
|
179
|
+
const values = arg(a, 'values') ?? [];
|
|
180
|
+
return values.some(Boolean);
|
|
181
|
+
},
|
|
182
|
+
}), scena.commands.register({
|
|
183
|
+
id: 'not',
|
|
184
|
+
title: 'not',
|
|
185
|
+
dispatch: 'client',
|
|
186
|
+
run: (_ctx, a) => {
|
|
187
|
+
return !arg(a, 'value');
|
|
188
|
+
},
|
|
189
|
+
}));
|
|
190
|
+
};
|
|
191
|
+
export function registerBuiltinFunctions(scena) {
|
|
192
|
+
return combineDisposables(validation(scena), format(scena), navigation(scena), logic(scena));
|
|
193
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Disposable } from '../types/disposable.js';
|
|
2
|
+
export declare function registerClientHandler(name: string, handler: (args: Record<string, unknown>) => unknown | Promise<unknown>): Disposable;
|
|
3
|
+
export declare function getClientHandler(name: string): ((args: Record<string, unknown>) => unknown | Promise<unknown>) | undefined;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Plugin-side client handlers for FunctionCall ids that need an inline JS
|
|
2
|
+
// implementation (typically declared with `callableFrom: 'clientOnly'`).
|
|
3
|
+
//
|
|
4
|
+
// Scena itself does not consult this registry; it is a parking lot plugin
|
|
5
|
+
// authors can use to expose handlers that other plugin code (or a custom
|
|
6
|
+
// dynamic-resolver bridge) looks up at call time.
|
|
7
|
+
const clientHandlers = new Map();
|
|
8
|
+
export function registerClientHandler(name, handler) {
|
|
9
|
+
clientHandlers.set(name, handler);
|
|
10
|
+
return {
|
|
11
|
+
dispose() {
|
|
12
|
+
if (clientHandlers.get(name) === handler)
|
|
13
|
+
clientHandlers.delete(name);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function getClientHandler(name) {
|
|
18
|
+
return clientHandlers.get(name);
|
|
19
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Disposable } from '../types/disposable.js';
|
|
2
|
+
import type { SocketBridge } from '../types/reactive-store.js';
|
|
3
|
+
export interface InMemorySocket extends SocketBridge {
|
|
4
|
+
dispatch(event: string, payload?: unknown): void;
|
|
5
|
+
onOutgoing(event: string, fn: (payload: unknown) => void): Disposable;
|
|
6
|
+
}
|
|
7
|
+
export declare function createInMemorySocket(): InMemorySocket;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function createInMemorySocket() {
|
|
2
|
+
const incoming = new Map();
|
|
3
|
+
const outgoing = new Map();
|
|
4
|
+
function add(map, event, fn) {
|
|
5
|
+
let set = map.get(event);
|
|
6
|
+
if (!set) {
|
|
7
|
+
set = new Set();
|
|
8
|
+
map.set(event, set);
|
|
9
|
+
}
|
|
10
|
+
set.add(fn);
|
|
11
|
+
return {
|
|
12
|
+
dispose() {
|
|
13
|
+
set.delete(fn);
|
|
14
|
+
if (set.size === 0)
|
|
15
|
+
map.delete(event);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function fire(map, event, payload) {
|
|
20
|
+
const set = map.get(event);
|
|
21
|
+
if (!set)
|
|
22
|
+
return;
|
|
23
|
+
for (const fn of [...set]) {
|
|
24
|
+
try {
|
|
25
|
+
fn(payload);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(`[in-memory-socket] listener for "${event}" threw:`, err);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
on(event, fn) {
|
|
34
|
+
return add(incoming, event, fn);
|
|
35
|
+
},
|
|
36
|
+
off(event, fn) {
|
|
37
|
+
incoming.get(event)?.delete(fn);
|
|
38
|
+
},
|
|
39
|
+
offAll(events) {
|
|
40
|
+
for (const e of events)
|
|
41
|
+
incoming.delete(e);
|
|
42
|
+
},
|
|
43
|
+
emit(event, payload) {
|
|
44
|
+
fire(outgoing, event, payload);
|
|
45
|
+
},
|
|
46
|
+
dispatch(event, payload) {
|
|
47
|
+
fire(incoming, event, payload);
|
|
48
|
+
},
|
|
49
|
+
onOutgoing(event, fn) {
|
|
50
|
+
return add(outgoing, event, fn);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { validateArgs, isPermissionPath } from './args-schema.js';
|
|
2
|
+
export type { ValidateArgsResult } from './args-schema.js';
|
|
3
|
+
export { createSurfaceBridge } from './surface-bridge.js';
|
|
4
|
+
export { registerClientHandler, getClientHandler, } from './client-handlers.js';
|
|
5
|
+
export { createInMemorySocket } from './in-memory-socket.js';
|
|
6
|
+
export type { InMemorySocket } from './in-memory-socket.js';
|
|
7
|
+
export { registerBuiltinFunctions } from './builtins.js';
|
|
8
|
+
export { registerLayoutCommands } from './layout-commands.js';
|
|
9
|
+
export { registerOpenerCommands } from './opener-commands.js';
|
|
10
|
+
export type { RegisterOpenerCommandsOptions } from './opener-commands.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { validateArgs, isPermissionPath } from './args-schema.js';
|
|
2
|
+
export { createSurfaceBridge } from './surface-bridge.js';
|
|
3
|
+
export { registerClientHandler, getClientHandler, } from './client-handlers.js';
|
|
4
|
+
export { createInMemorySocket } from './in-memory-socket.js';
|
|
5
|
+
export { registerBuiltinFunctions } from './builtins.js';
|
|
6
|
+
export { registerLayoutCommands } from './layout-commands.js';
|
|
7
|
+
export { registerOpenerCommands } from './opener-commands.js';
|