@dfosco/storyboard 0.5.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commandpalette.config.json +152 -0
- package/dist/storyboard-ui.css +1 -0
- package/dist/storyboard-ui.js +21328 -0
- package/dist/storyboard-ui.js.map +1 -0
- package/dist/tailwind.css +2 -0
- package/dist/tiny-canvas.css +1 -0
- package/dist/tiny-canvas.js +389 -0
- package/package.json +121 -0
- package/paste.config.json +67 -0
- package/scaffold/AGENTS.md +432 -0
- package/scaffold/agents/prompt-agent.agent.md +181 -0
- package/scaffold/agents/terminal-agent.agent.md +351 -0
- package/scaffold/codex/config.toml +246 -0
- package/scaffold/deploy.yml +103 -0
- package/scaffold/githooks/pre-push +114 -0
- package/scaffold/gitignore +64 -0
- package/scaffold/manifest.json +56 -0
- package/scaffold/preview.yml +181 -0
- package/scaffold/scripts/link.sh +26 -0
- package/scaffold/scripts/unlink.sh +10 -0
- package/scaffold/skills/agent-browser/SKILL.md +260 -0
- package/scaffold/skills/canvas/SKILL.md +364 -0
- package/scaffold/skills/create/SKILL.md +501 -0
- package/scaffold/skills/ship/SKILL.md +237 -0
- package/scaffold/skills/storyboard/SKILL.md +360 -0
- package/scaffold/skills/update-storyboard/SKILL.md +16 -0
- package/scaffold/skills/update-storyboard/update-storyboard-packages.sh +26 -0
- package/scaffold/skills/vitest/GENERATION.md +5 -0
- package/scaffold/skills/vitest/SKILL.md +52 -0
- package/scaffold/skills/vitest/references/advanced-environments.md +264 -0
- package/scaffold/skills/vitest/references/advanced-projects.md +300 -0
- package/scaffold/skills/vitest/references/advanced-type-testing.md +237 -0
- package/scaffold/skills/vitest/references/advanced-vi.md +249 -0
- package/scaffold/skills/vitest/references/core-cli.md +166 -0
- package/scaffold/skills/vitest/references/core-config.md +174 -0
- package/scaffold/skills/vitest/references/core-describe.md +193 -0
- package/scaffold/skills/vitest/references/core-expect.md +219 -0
- package/scaffold/skills/vitest/references/core-hooks.md +244 -0
- package/scaffold/skills/vitest/references/core-test-api.md +233 -0
- package/scaffold/skills/vitest/references/features-concurrency.md +250 -0
- package/scaffold/skills/vitest/references/features-context.md +238 -0
- package/scaffold/skills/vitest/references/features-coverage.md +207 -0
- package/scaffold/skills/vitest/references/features-filtering.md +211 -0
- package/scaffold/skills/vitest/references/features-mocking.md +265 -0
- package/scaffold/skills/vitest/references/features-snapshots.md +207 -0
- package/scaffold/skills/worktree/SKILL.md +93 -0
- package/scaffold/storyboard.config.json +44 -0
- package/src/canvas/Canvas.jsx +78 -0
- package/src/canvas/Draggable.jsx +235 -0
- package/src/canvas/index.d.ts +41 -0
- package/src/canvas/index.js +6 -0
- package/src/canvas/style.css +118 -0
- package/src/canvas/useResetCanvas.js +17 -0
- package/src/canvas/utils.js +136 -0
- package/src/core/assets/fonts/IoskeleyMono-Bold.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-Italic.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-Medium.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-Regular.woff2 +0 -0
- package/src/core/assets/fonts/IoskeleyMono-SemiBold.woff2 +0 -0
- package/src/core/autosync/server.js +714 -0
- package/src/core/autosync/server.test.js +158 -0
- package/src/core/canvas/__tests__/agent-integration.test.js +596 -0
- package/src/core/canvas/__tests__/helpers/browser.js +95 -0
- package/src/core/canvas/__tests__/helpers/canvas-api.js +129 -0
- package/src/core/canvas/__tests__/helpers/perf.js +118 -0
- package/src/core/canvas/__tests__/helpers/setup.js +176 -0
- package/src/core/canvas/__tests__/helpers/tmux.js +130 -0
- package/src/core/canvas/__tests__/helpers/transcript.js +132 -0
- package/src/core/canvas/__tests__/terminal-integration.test.js +177 -0
- package/src/core/canvas/collision.js +292 -0
- package/src/core/canvas/collision.test.js +371 -0
- package/src/core/canvas/compact.js +83 -0
- package/src/core/canvas/deriveCanvasId.test.js +40 -0
- package/src/core/canvas/githubEmbeds.js +527 -0
- package/src/core/canvas/githubEmbeds.test.js +302 -0
- package/src/core/canvas/hot-pool.js +766 -0
- package/src/core/canvas/identity.js +107 -0
- package/src/core/canvas/identity.test.js +100 -0
- package/src/core/canvas/materializer.js +259 -0
- package/src/core/canvas/materializer.test.js +356 -0
- package/src/core/canvas/selectedWidgets.js +270 -0
- package/src/core/canvas/selectedWidgets.test.js +321 -0
- package/src/core/canvas/server.js +3134 -0
- package/src/core/canvas/server.test.js +379 -0
- package/src/core/canvas/terminal-config.js +330 -0
- package/src/core/canvas/terminal-registry.js +465 -0
- package/src/core/canvas/terminal-server.js +1436 -0
- package/src/core/canvas/writeGuard.js +53 -0
- package/src/core/cli/agent.js +85 -0
- package/src/core/cli/branch.js +386 -0
- package/src/core/cli/canvasAdd.js +241 -0
- package/src/core/cli/canvasBatch.js +98 -0
- package/src/core/cli/canvasBounds.js +160 -0
- package/src/core/cli/canvasRead.js +236 -0
- package/src/core/cli/canvasUpdate.js +179 -0
- package/src/core/cli/code.js +67 -0
- package/src/core/cli/compact.js +62 -0
- package/src/core/cli/create.js +674 -0
- package/src/core/cli/dev-helpers.js +53 -0
- package/src/core/cli/dev-helpers.test.js +53 -0
- package/src/core/cli/dev.js +430 -0
- package/src/core/cli/exit.js +38 -0
- package/src/core/cli/flags.js +174 -0
- package/src/core/cli/flags.test.js +155 -0
- package/src/core/cli/index.js +233 -0
- package/src/core/cli/intro.js +37 -0
- package/src/core/cli/proxy.js +319 -0
- package/src/core/cli/proxy.test.js +63 -0
- package/src/core/cli/schemas.js +223 -0
- package/src/core/cli/server.js +192 -0
- package/src/core/cli/serverUrl.js +61 -0
- package/src/core/cli/sessions.js +459 -0
- package/src/core/cli/setup.js +404 -0
- package/src/core/cli/terminal-commands.js +287 -0
- package/src/core/cli/terminal-messaging.js +231 -0
- package/src/core/cli/terminal-welcome.js +515 -0
- package/src/core/cli/updateVersion.js +124 -0
- package/src/core/comments/api.js +284 -0
- package/src/core/comments/api.test.js +282 -0
- package/src/core/comments/auth.js +151 -0
- package/src/core/comments/auth.test.js +167 -0
- package/src/core/comments/commentCache.js +109 -0
- package/src/core/comments/commentCache.test.js +48 -0
- package/src/core/comments/commentDrafts.js +68 -0
- package/src/core/comments/commentMode.js +63 -0
- package/src/core/comments/commentMode.test.js +90 -0
- package/src/core/comments/config.js +47 -0
- package/src/core/comments/config.test.js +77 -0
- package/src/core/comments/graphql.js +65 -0
- package/src/core/comments/graphql.test.js +95 -0
- package/src/core/comments/index.js +42 -0
- package/src/core/comments/metadata.js +52 -0
- package/src/core/comments/metadata.test.js +110 -0
- package/src/core/comments/queries.js +245 -0
- package/src/core/comments/ui/AuthModal.jsx +114 -0
- package/src/core/comments/ui/CommentOverlay.js +52 -0
- package/src/core/comments/ui/CommentWindow.jsx +329 -0
- package/src/core/comments/ui/CommentsDrawer.jsx +102 -0
- package/src/core/comments/ui/Composer.jsx +64 -0
- package/src/core/comments/ui/authModal.js +66 -0
- package/src/core/comments/ui/authModal.test.js +76 -0
- package/src/core/comments/ui/comment-cursor-dark.svg +1 -0
- package/src/core/comments/ui/comment-cursor.svg +1 -0
- package/src/core/comments/ui/comment-layout.css +142 -0
- package/src/core/comments/ui/commentWindow.js +121 -0
- package/src/core/comments/ui/comments.css +242 -0
- package/src/core/comments/ui/commentsDrawer.js +84 -0
- package/src/core/comments/ui/composer.js +136 -0
- package/src/core/comments/ui/index.js +14 -0
- package/src/core/comments/ui/mount.js +687 -0
- package/src/core/comments/ui/mount.test.js +336 -0
- package/src/core/data/dotPath.js +53 -0
- package/src/core/data/dotPath.test.js +114 -0
- package/src/core/data/loader.js +409 -0
- package/src/core/data/loader.test.js +599 -0
- package/src/core/data/viewfinder.js +363 -0
- package/src/core/data/viewfinder.test.js +456 -0
- package/src/core/devtools/devtools-consumer.js +28 -0
- package/src/core/devtools/devtools.js +144 -0
- package/src/core/devtools/devtools.test.js +75 -0
- package/src/core/devtools/sceneDebug.js +112 -0
- package/src/core/devtools/sceneDebug.test.js +141 -0
- package/src/core/index.js +124 -0
- package/src/core/inspector/fiberWalker.js +239 -0
- package/src/core/inspector/highlighter.js +275 -0
- package/src/core/inspector/mouseMode.js +259 -0
- package/src/core/lib/components/ui/alert/alert-action.jsx +11 -0
- package/src/core/lib/components/ui/alert/alert-description.jsx +11 -0
- package/src/core/lib/components/ui/alert/alert-title.jsx +11 -0
- package/src/core/lib/components/ui/alert/alert.jsx +25 -0
- package/src/core/lib/components/ui/alert/index.js +17 -0
- package/src/core/lib/components/ui/avatar/avatar-badge.jsx +22 -0
- package/src/core/lib/components/ui/avatar/avatar-fallback.jsx +18 -0
- package/src/core/lib/components/ui/avatar/avatar-group-count.jsx +19 -0
- package/src/core/lib/components/ui/avatar/avatar-group.jsx +19 -0
- package/src/core/lib/components/ui/avatar/avatar-image.jsx +15 -0
- package/src/core/lib/components/ui/avatar/avatar.jsx +19 -0
- package/src/core/lib/components/ui/avatar/index.js +22 -0
- package/src/core/lib/components/ui/badge/badge.jsx +31 -0
- package/src/core/lib/components/ui/badge/index.js +2 -0
- package/src/core/lib/components/ui/button/button.jsx +100 -0
- package/src/core/lib/components/ui/button/index.js +12 -0
- package/src/core/lib/components/ui/card/card-action.jsx +11 -0
- package/src/core/lib/components/ui/card/card-content.jsx +11 -0
- package/src/core/lib/components/ui/card/card-description.jsx +11 -0
- package/src/core/lib/components/ui/card/card-footer.jsx +11 -0
- package/src/core/lib/components/ui/card/card-header.jsx +19 -0
- package/src/core/lib/components/ui/card/card-title.jsx +11 -0
- package/src/core/lib/components/ui/card/card.jsx +17 -0
- package/src/core/lib/components/ui/card/index.js +25 -0
- package/src/core/lib/components/ui/checkbox/checkbox.jsx +29 -0
- package/src/core/lib/components/ui/checkbox/index.js +6 -0
- package/src/core/lib/components/ui/collapsible/collapsible-content.jsx +7 -0
- package/src/core/lib/components/ui/collapsible/collapsible-trigger.jsx +7 -0
- package/src/core/lib/components/ui/collapsible/collapsible.jsx +7 -0
- package/src/core/lib/components/ui/collapsible/index.js +13 -0
- package/src/core/lib/components/ui/dialog/dialog-close.jsx +7 -0
- package/src/core/lib/components/ui/dialog/dialog-content.jsx +34 -0
- package/src/core/lib/components/ui/dialog/dialog-description.jsx +15 -0
- package/src/core/lib/components/ui/dialog/dialog-footer.jsx +23 -0
- package/src/core/lib/components/ui/dialog/dialog-header.jsx +11 -0
- package/src/core/lib/components/ui/dialog/dialog-overlay.jsx +15 -0
- package/src/core/lib/components/ui/dialog/dialog-portal.jsx +4 -0
- package/src/core/lib/components/ui/dialog/dialog-title.jsx +15 -0
- package/src/core/lib/components/ui/dialog/dialog-trigger.jsx +7 -0
- package/src/core/lib/components/ui/dialog/dialog.jsx +4 -0
- package/src/core/lib/components/ui/dialog/index.js +34 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.jsx +8 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.jsx +30 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-content.jsx +22 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.jsx +16 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-group.jsx +7 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-item.jsx +20 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-label.jsx +17 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-portal.jsx +4 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.jsx +7 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.jsx +29 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-separator.jsx +15 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.jsx +16 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.jsx +15 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.jsx +23 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-sub.jsx +4 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu-trigger.jsx +7 -0
- package/src/core/lib/components/ui/dropdown-menu/dropdown-menu.jsx +4 -0
- package/src/core/lib/components/ui/dropdown-menu/index.js +54 -0
- package/src/core/lib/components/ui/input/index.js +7 -0
- package/src/core/lib/components/ui/input/input.jsx +19 -0
- package/src/core/lib/components/ui/label/index.js +7 -0
- package/src/core/lib/components/ui/label/label.jsx +19 -0
- package/src/core/lib/components/ui/panel/index.js +24 -0
- package/src/core/lib/components/ui/panel/panel-body.jsx +11 -0
- package/src/core/lib/components/ui/panel/panel-close.jsx +16 -0
- package/src/core/lib/components/ui/panel/panel-content.jsx +29 -0
- package/src/core/lib/components/ui/panel/panel-footer.jsx +11 -0
- package/src/core/lib/components/ui/panel/panel-header.jsx +11 -0
- package/src/core/lib/components/ui/panel/panel-title.jsx +12 -0
- package/src/core/lib/components/ui/panel/panel.jsx +4 -0
- package/src/core/lib/components/ui/popover/index.js +28 -0
- package/src/core/lib/components/ui/popover/popover-close.jsx +7 -0
- package/src/core/lib/components/ui/popover/popover-content.jsx +22 -0
- package/src/core/lib/components/ui/popover/popover-description.jsx +11 -0
- package/src/core/lib/components/ui/popover/popover-header.jsx +11 -0
- package/src/core/lib/components/ui/popover/popover-portal.jsx +4 -0
- package/src/core/lib/components/ui/popover/popover-title.jsx +11 -0
- package/src/core/lib/components/ui/popover/popover-trigger.jsx +8 -0
- package/src/core/lib/components/ui/popover/popover.jsx +4 -0
- package/src/core/lib/components/ui/searchable-list.jsx +160 -0
- package/src/core/lib/components/ui/select/index.js +37 -0
- package/src/core/lib/components/ui/select/select-content.jsx +30 -0
- package/src/core/lib/components/ui/select/select-group-heading.jsx +17 -0
- package/src/core/lib/components/ui/select/select-group.jsx +15 -0
- package/src/core/lib/components/ui/select/select-item.jsx +26 -0
- package/src/core/lib/components/ui/select/select-label.jsx +11 -0
- package/src/core/lib/components/ui/select/select-portal.jsx +4 -0
- package/src/core/lib/components/ui/select/select-scroll-down-button.jsx +18 -0
- package/src/core/lib/components/ui/select/select-scroll-up-button.jsx +18 -0
- package/src/core/lib/components/ui/select/select-separator.jsx +15 -0
- package/src/core/lib/components/ui/select/select-trigger.jsx +25 -0
- package/src/core/lib/components/ui/select/select.jsx +4 -0
- package/src/core/lib/components/ui/separator/index.js +7 -0
- package/src/core/lib/components/ui/separator/separator.jsx +22 -0
- package/src/core/lib/components/ui/sheet/index.js +34 -0
- package/src/core/lib/components/ui/sheet/sheet-close.jsx +7 -0
- package/src/core/lib/components/ui/sheet/sheet-content.jsx +35 -0
- package/src/core/lib/components/ui/sheet/sheet-description.jsx +15 -0
- package/src/core/lib/components/ui/sheet/sheet-footer.jsx +11 -0
- package/src/core/lib/components/ui/sheet/sheet-header.jsx +11 -0
- package/src/core/lib/components/ui/sheet/sheet-overlay.jsx +15 -0
- package/src/core/lib/components/ui/sheet/sheet-portal.jsx +4 -0
- package/src/core/lib/components/ui/sheet/sheet-title.jsx +15 -0
- package/src/core/lib/components/ui/sheet/sheet-trigger.jsx +7 -0
- package/src/core/lib/components/ui/sheet/sheet.jsx +4 -0
- package/src/core/lib/components/ui/textarea/index.js +7 -0
- package/src/core/lib/components/ui/textarea/textarea.jsx +18 -0
- package/src/core/lib/components/ui/toggle/index.js +8 -0
- package/src/core/lib/components/ui/toggle/toggle.jsx +36 -0
- package/src/core/lib/components/ui/toggle-group/index.js +10 -0
- package/src/core/lib/components/ui/toggle-group/toggle-group-item.jsx +29 -0
- package/src/core/lib/components/ui/toggle-group/toggle-group.jsx +43 -0
- package/src/core/lib/components/ui/tooltip/index.js +3 -0
- package/src/core/lib/components/ui/tooltip/tooltip-content.jsx +21 -0
- package/src/core/lib/components/ui/tooltip/tooltip-trigger.jsx +23 -0
- package/src/core/lib/components/ui/tooltip/tooltip.jsx +11 -0
- package/src/core/lib/components/ui/trigger-button/index.js +6 -0
- package/src/core/lib/components/ui/trigger-button/trigger-button.css +38 -0
- package/src/core/lib/components/ui/trigger-button/trigger-button.jsx +63 -0
- package/src/core/lib/utils/index.js +6 -0
- package/src/core/logger/devLogger.js +238 -0
- package/src/core/logger/devLogger.test.js +193 -0
- package/src/core/modes/modes.css +98 -0
- package/src/core/modes/modes.js +492 -0
- package/src/core/modes/modes.test.js +562 -0
- package/src/core/mountStoryboardCore.js +478 -0
- package/src/core/rename-watcher/config.json +23 -0
- package/src/core/rename-watcher/watcher.js +531 -0
- package/src/core/scaffold.js +100 -0
- package/src/core/server/index.js +391 -0
- package/src/core/session/bodyClasses.js +128 -0
- package/src/core/session/bodyClasses.test.js +192 -0
- package/src/core/session/hashSubscribe.js +19 -0
- package/src/core/session/hashSubscribe.test.js +62 -0
- package/src/core/session/hideMode.js +424 -0
- package/src/core/session/hideMode.test.js +268 -0
- package/src/core/session/interceptHideParams.js +35 -0
- package/src/core/session/interceptHideParams.test.js +90 -0
- package/src/core/session/localStorage.js +134 -0
- package/src/core/session/localStorage.test.js +148 -0
- package/src/core/session/session.js +76 -0
- package/src/core/session/session.test.js +91 -0
- package/src/core/stores/canvasConfig.js +134 -0
- package/src/core/stores/canvasConfig.test.js +120 -0
- package/src/core/stores/commandActions.js +284 -0
- package/src/core/stores/commandPaletteConfig.js +31 -0
- package/src/core/stores/configSchema.js +232 -0
- package/src/core/stores/configSchema.test.js +72 -0
- package/src/core/stores/configStore.js +161 -0
- package/src/core/stores/customerModeConfig.js +30 -0
- package/src/core/stores/featureFlags.js +127 -0
- package/src/core/stores/paletteProviders.js +360 -0
- package/src/core/stores/paletteProviders.test.js +186 -0
- package/src/core/stores/plugins.js +40 -0
- package/src/core/stores/plugins.test.js +68 -0
- package/src/core/stores/recentArtifacts.js +68 -0
- package/src/core/stores/recentArtifacts.test.js +71 -0
- package/src/core/stores/sidePanelStore.ts +143 -0
- package/src/core/stores/themeStore.ts +291 -0
- package/src/core/stores/toolRegistry.js +227 -0
- package/src/core/stores/toolStateStore.js +183 -0
- package/src/core/stores/toolStateStore.test.js +220 -0
- package/src/core/stores/toolbarConfigStore.js +165 -0
- package/src/core/stores/uiConfig.js +64 -0
- package/src/core/stores/uiConfig.test.js +63 -0
- package/src/core/styles/tailwind.css +204 -0
- package/src/core/tools/handlers/autosync.js +12 -0
- package/src/core/tools/handlers/canvasAddWidget.js +11 -0
- package/src/core/tools/handlers/canvasAgents.js +20 -0
- package/src/core/tools/handlers/canvasToolbar.js +56 -0
- package/src/core/tools/handlers/commandPalette.js +9 -0
- package/src/core/tools/handlers/comments.js +16 -0
- package/src/core/tools/handlers/create.js +39 -0
- package/src/core/tools/handlers/devtools.js +122 -0
- package/src/core/tools/handlers/devtools.test.js +87 -0
- package/src/core/tools/handlers/featureFlags.js +21 -0
- package/src/core/tools/handlers/flows.js +68 -0
- package/src/core/tools/handlers/hideChrome.js +9 -0
- package/src/core/tools/handlers/hideToolbars.js +25 -0
- package/src/core/tools/handlers/inspector.js +19 -0
- package/src/core/tools/handlers/paletteTheme.js +35 -0
- package/src/core/tools/handlers/theme.js +9 -0
- package/src/core/tools/registry.js +26 -0
- package/src/core/tools/surfaces/canvasToolbar.js +10 -0
- package/src/core/tools/surfaces/commandList.js +10 -0
- package/src/core/tools/surfaces/mainToolbar.js +11 -0
- package/src/core/tools/surfaces/registry.js +19 -0
- package/src/core/ui/ActionMenuButton.jsx +114 -0
- package/src/core/ui/AutosyncMenuButton.css +67 -0
- package/src/core/ui/AutosyncMenuButton.jsx +242 -0
- package/src/core/ui/BranchSelect.jsx +29 -0
- package/src/core/ui/BranchSelect.module.css +30 -0
- package/src/core/ui/CanvasAgentsMenu.jsx +89 -0
- package/src/core/ui/CanvasCreateMenu.jsx +611 -0
- package/src/core/ui/CanvasSnap.css +27 -0
- package/src/core/ui/CanvasSnap.jsx +51 -0
- package/src/core/ui/CanvasUndoRedo.css +36 -0
- package/src/core/ui/CanvasUndoRedo.jsx +62 -0
- package/src/core/ui/CanvasZoomControl.css +53 -0
- package/src/core/ui/CanvasZoomControl.jsx +49 -0
- package/src/core/ui/CanvasZoomToFit.css +18 -0
- package/src/core/ui/CanvasZoomToFit.jsx +26 -0
- package/src/core/ui/CommandMenu.css +8 -0
- package/src/core/ui/CommandMenu.jsx +287 -0
- package/src/core/ui/CommandPalette.jsx +35 -0
- package/src/core/ui/CommandPaletteTrigger.jsx +25 -0
- package/src/core/ui/CommentsMenuButton.jsx +40 -0
- package/src/core/ui/CoreUIBar.css +47 -0
- package/src/core/ui/CoreUIBar.jsx +905 -0
- package/src/core/ui/CreateMenuButton.jsx +117 -0
- package/src/core/ui/HideChromeTrigger.jsx +48 -0
- package/src/core/ui/Icon.jsx +279 -0
- package/src/core/ui/InspectorPanel.css +109 -0
- package/src/core/ui/InspectorPanel.jsx +632 -0
- package/src/core/ui/PwaInstallBanner.css +42 -0
- package/src/core/ui/PwaInstallBanner.jsx +124 -0
- package/src/core/ui/SidePanel.jsx +261 -0
- package/src/core/ui/ThemeMenuButton.jsx +139 -0
- package/src/core/ui/core-ui-colors.css +129 -0
- package/src/core/ui/design-modes.ts +7 -0
- package/src/core/ui/sidepanel.css +301 -0
- package/src/core/ui/viewfinder.ts +7 -0
- package/src/core/ui-entry.js +30 -0
- package/src/core/utils/fuzzySearch.js +117 -0
- package/src/core/utils/fuzzySearch.test.js +119 -0
- package/src/core/utils/mobileViewport.js +57 -0
- package/src/core/utils/mobileViewport.test.js +68 -0
- package/src/core/utils/prodMode.js +38 -0
- package/src/core/utils/smoothCorners.js +20 -0
- package/src/core/vite/docs-handler.js +155 -0
- package/src/core/vite/server-plugin.js +797 -0
- package/src/core/workshop/features/createCanvas/CreateCanvasForm.jsx +260 -0
- package/src/core/workshop/features/createCanvas/index.js +14 -0
- package/src/core/workshop/features/createFlow/CreateFlowForm.jsx +334 -0
- package/src/core/workshop/features/createFlow/index.js +19 -0
- package/src/core/workshop/features/createFlow/server.js +663 -0
- package/src/core/workshop/features/createPage/CreatePageForm.jsx +304 -0
- package/src/core/workshop/features/createPage/index.js +11 -0
- package/src/core/workshop/features/createPrototype/CreatePrototypeForm.jsx +289 -0
- package/src/core/workshop/features/createPrototype/index.js +19 -0
- package/src/core/workshop/features/createPrototype/server.js +433 -0
- package/src/core/workshop/features/createStory/CreateStoryForm.jsx +208 -0
- package/src/core/workshop/features/createStory/index.js +14 -0
- package/src/core/workshop/features/registry-server.js +22 -0
- package/src/core/workshop/features/registry.js +28 -0
- package/src/core/workshop/features/templateIndex.js +155 -0
- package/src/core/workshop/ui/WorkshopPanel.jsx +98 -0
- package/src/core/workshop/ui/mount.ts +6 -0
- package/src/core/worktree/port.js +268 -0
- package/src/core/worktree/port.test.js +222 -0
- package/src/core/worktree/serverRegistry.js +120 -0
- package/src/internals/AuthModal/AuthModal.jsx +132 -0
- package/src/internals/AuthModal/AuthModal.module.css +221 -0
- package/src/internals/BranchBar/BranchBar.jsx +87 -0
- package/src/internals/BranchBar/BranchBar.module.css +247 -0
- package/src/internals/BranchBar/useBranches.js +93 -0
- package/src/internals/BranchBar/useBranches.test.js +68 -0
- package/src/internals/CommandPalette/CommandPalette.jsx +1361 -0
- package/src/internals/CommandPalette/CreateDialog.jsx +219 -0
- package/src/internals/CommandPalette/command-palette.css +180 -0
- package/src/internals/FlowError.module.css +30 -0
- package/src/internals/Icon.jsx +279 -0
- package/src/internals/StoryboardContext.js +3 -0
- package/src/internals/Viewfinder.jsx +1479 -0
- package/src/internals/Viewfinder.module.css +1540 -0
- package/src/internals/Workspace.jsx +7 -0
- package/src/internals/__mocks__/virtual-storyboard-data-index.js +4 -0
- package/src/internals/canvas/CanvasControls.jsx +112 -0
- package/src/internals/canvas/CanvasControls.module.css +135 -0
- package/src/internals/canvas/CanvasPage.bridge.test.jsx +387 -0
- package/src/internals/canvas/CanvasPage.dragdrop.test.jsx +350 -0
- package/src/internals/canvas/CanvasPage.jsx +3092 -0
- package/src/internals/canvas/CanvasPage.module.css +187 -0
- package/src/internals/canvas/CanvasPage.multiselect.test.jsx +358 -0
- package/src/internals/canvas/CanvasToolbar.jsx +73 -0
- package/src/internals/canvas/CanvasToolbar.module.css +92 -0
- package/src/internals/canvas/ComponentErrorBoundary.jsx +50 -0
- package/src/internals/canvas/ConnectorLayer.jsx +208 -0
- package/src/internals/canvas/ConnectorLayer.module.css +129 -0
- package/src/internals/canvas/MarqueeOverlay.jsx +20 -0
- package/src/internals/canvas/PageSelector.jsx +587 -0
- package/src/internals/canvas/PageSelector.module.css +261 -0
- package/src/internals/canvas/PageSelector.test.jsx +113 -0
- package/src/internals/canvas/WebGLContextPool.jsx +292 -0
- package/src/internals/canvas/WebGLContextPool.test.jsx +165 -0
- package/src/internals/canvas/canvasApi.js +164 -0
- package/src/internals/canvas/canvasReloadGuard.js +37 -0
- package/src/internals/canvas/canvasReloadGuard.test.js +27 -0
- package/src/internals/canvas/canvasTheme.js +118 -0
- package/src/internals/canvas/componentIsolate.jsx +165 -0
- package/src/internals/canvas/componentSetIsolate.jsx +257 -0
- package/src/internals/canvas/computeCanvasBounds.test.js +121 -0
- package/src/internals/canvas/connectorGeometry.js +132 -0
- package/src/internals/canvas/hotPoolDevLogs.js +25 -0
- package/src/internals/canvas/textSelection.js +10 -0
- package/src/internals/canvas/textSelection.test.js +26 -0
- package/src/internals/canvas/useCanvas.js +126 -0
- package/src/internals/canvas/useCanvas.test.js +26 -0
- package/src/internals/canvas/useMarqueeSelect.js +213 -0
- package/src/internals/canvas/useMarqueeSelect.test.js +78 -0
- package/src/internals/canvas/useUndoRedo.js +86 -0
- package/src/internals/canvas/useUndoRedo.test.js +231 -0
- package/src/internals/canvas/widgets/CodePenEmbed.jsx +293 -0
- package/src/internals/canvas/widgets/CodePenEmbed.module.css +161 -0
- package/src/internals/canvas/widgets/ComponentSetWidget.jsx +2 -0
- package/src/internals/canvas/widgets/ComponentSetWidget.module.css +89 -0
- package/src/internals/canvas/widgets/ComponentWidget.jsx +14 -0
- package/src/internals/canvas/widgets/ComponentWidget.module.css +0 -0
- package/src/internals/canvas/widgets/CropOverlay.jsx +179 -0
- package/src/internals/canvas/widgets/CropOverlay.module.css +154 -0
- package/src/internals/canvas/widgets/ExpandedPane.jsx +474 -0
- package/src/internals/canvas/widgets/ExpandedPane.module.css +179 -0
- package/src/internals/canvas/widgets/ExpandedPane.test.jsx +240 -0
- package/src/internals/canvas/widgets/ExpandedPaneTopBar.jsx +111 -0
- package/src/internals/canvas/widgets/ExpandedPaneTopBar.module.css +59 -0
- package/src/internals/canvas/widgets/ExpandedPaneTopBar.test.jsx +45 -0
- package/src/internals/canvas/widgets/FigmaEmbed.jsx +296 -0
- package/src/internals/canvas/widgets/FigmaEmbed.module.css +222 -0
- package/src/internals/canvas/widgets/FrozenTerminalOverlay.jsx +151 -0
- package/src/internals/canvas/widgets/FrozenTerminalOverlay.module.css +83 -0
- package/src/internals/canvas/widgets/ImageWidget.jsx +287 -0
- package/src/internals/canvas/widgets/ImageWidget.module.css +81 -0
- package/src/internals/canvas/widgets/LinkPreview.jsx +439 -0
- package/src/internals/canvas/widgets/LinkPreview.module.css +585 -0
- package/src/internals/canvas/widgets/LinkPreview.test.jsx +193 -0
- package/src/internals/canvas/widgets/MarkdownBlock.jsx +354 -0
- package/src/internals/canvas/widgets/MarkdownBlock.module.css +377 -0
- package/src/internals/canvas/widgets/MarkdownBlock.test.jsx +92 -0
- package/src/internals/canvas/widgets/PromptWidget.jsx +428 -0
- package/src/internals/canvas/widgets/PromptWidget.module.css +273 -0
- package/src/internals/canvas/widgets/PrototypeEmbed.jsx +463 -0
- package/src/internals/canvas/widgets/PrototypeEmbed.module.css +579 -0
- package/src/internals/canvas/widgets/PrototypeEmbed.test.jsx +10 -0
- package/src/internals/canvas/widgets/ResizeHandle.jsx +67 -0
- package/src/internals/canvas/widgets/ResizeHandle.module.css +29 -0
- package/src/internals/canvas/widgets/StickyNote.jsx +92 -0
- package/src/internals/canvas/widgets/StickyNote.module.css +70 -0
- package/src/internals/canvas/widgets/StickyNote.test.jsx +116 -0
- package/src/internals/canvas/widgets/StorySetWidget.jsx +208 -0
- package/src/internals/canvas/widgets/StorySetWidget.module.css +89 -0
- package/src/internals/canvas/widgets/StoryWidget.jsx +334 -0
- package/src/internals/canvas/widgets/StoryWidget.module.css +211 -0
- package/src/internals/canvas/widgets/TerminalReadWidget.jsx +146 -0
- package/src/internals/canvas/widgets/TerminalReadWidget.module.css +94 -0
- package/src/internals/canvas/widgets/TerminalWidget.jsx +704 -0
- package/src/internals/canvas/widgets/TerminalWidget.module.css +444 -0
- package/src/internals/canvas/widgets/TilesWidget.jsx +300 -0
- package/src/internals/canvas/widgets/TilesWidget.module.css +133 -0
- package/src/internals/canvas/widgets/WidgetChrome.jsx +580 -0
- package/src/internals/canvas/widgets/WidgetChrome.module.css +421 -0
- package/src/internals/canvas/widgets/WidgetWrapper.jsx +15 -0
- package/src/internals/canvas/widgets/WidgetWrapper.module.css +25 -0
- package/src/internals/canvas/widgets/codepenUrl.js +75 -0
- package/src/internals/canvas/widgets/codepenUrl.test.js +76 -0
- package/src/internals/canvas/widgets/embedInteraction.test.jsx +173 -0
- package/src/internals/canvas/widgets/embedOverlay.module.css +35 -0
- package/src/internals/canvas/widgets/embedTheme.js +148 -0
- package/src/internals/canvas/widgets/expandUtils.js +559 -0
- package/src/internals/canvas/widgets/expandUtils.test.js +155 -0
- package/src/internals/canvas/widgets/figmaUrl.js +118 -0
- package/src/internals/canvas/widgets/figmaUrl.test.js +139 -0
- package/src/internals/canvas/widgets/githubUrl.js +82 -0
- package/src/internals/canvas/widgets/githubUrl.test.js +74 -0
- package/src/internals/canvas/widgets/iframeDevLogs.js +49 -0
- package/src/internals/canvas/widgets/iframeDevLogs.test.jsx +81 -0
- package/src/internals/canvas/widgets/index.js +42 -0
- package/src/internals/canvas/widgets/pasteRules.js +295 -0
- package/src/internals/canvas/widgets/pasteRules.test.js +474 -0
- package/src/internals/canvas/widgets/snapshotDisplay.test.jsx +211 -0
- package/src/internals/canvas/widgets/tilePool.js +23 -0
- package/src/internals/canvas/widgets/tiles/diagonal-bl.png +0 -0
- package/src/internals/canvas/widgets/tiles/diagonal-br.png +0 -0
- package/src/internals/canvas/widgets/tiles/diagonal-tl.png +0 -0
- package/src/internals/canvas/widgets/tiles/leaf.png +0 -0
- package/src/internals/canvas/widgets/tiles/quarter-tl.png +0 -0
- package/src/internals/canvas/widgets/tiles/quarter-tr.png +0 -0
- package/src/internals/canvas/widgets/tiles/solid-a.png +0 -0
- package/src/internals/canvas/widgets/tiles/solid-b.png +0 -0
- package/src/internals/canvas/widgets/widgetConfig.js +291 -0
- package/src/internals/canvas/widgets/widgetConfig.test.js +68 -0
- package/src/internals/canvas/widgets/widgetIcons.jsx +190 -0
- package/src/internals/canvas/widgets/widgetProps.js +133 -0
- package/src/internals/context/FormContext.js +13 -0
- package/src/internals/context/FormContext.test.js +48 -0
- package/src/internals/context.jsx +481 -0
- package/src/internals/context.test.jsx +296 -0
- package/src/internals/hashPreserver.js +73 -0
- package/src/internals/hashPreserver.test.js +107 -0
- package/src/internals/hooks/useConfig.js +14 -0
- package/src/internals/hooks/useFeatureFlag.js +14 -0
- package/src/internals/hooks/useFlows.js +50 -0
- package/src/internals/hooks/useFlows.test.js +134 -0
- package/src/internals/hooks/useHideMode.js +31 -0
- package/src/internals/hooks/useHideMode.test.js +43 -0
- package/src/internals/hooks/useLocalStorage.js +57 -0
- package/src/internals/hooks/useLocalStorage.test.js +75 -0
- package/src/internals/hooks/useMode.js +43 -0
- package/src/internals/hooks/useObject.js +101 -0
- package/src/internals/hooks/useObject.test.js +74 -0
- package/src/internals/hooks/useOverride.js +84 -0
- package/src/internals/hooks/useOverride.test.js +71 -0
- package/src/internals/hooks/usePrototypeReloadGuard.js +64 -0
- package/src/internals/hooks/useRecord.js +158 -0
- package/src/internals/hooks/useRecord.test.js +221 -0
- package/src/internals/hooks/useScene.js +38 -0
- package/src/internals/hooks/useScene.test.js +66 -0
- package/src/internals/hooks/useSceneData.js +108 -0
- package/src/internals/hooks/useSceneData.test.js +136 -0
- package/src/internals/hooks/useSession.js +4 -0
- package/src/internals/hooks/useSession.test.js +8 -0
- package/src/internals/hooks/useThemeState.js +61 -0
- package/src/internals/hooks/useThemeState.test.js +66 -0
- package/src/internals/hooks/useUndoRedo.js +28 -0
- package/src/internals/hooks/useUndoRedo.test.js +64 -0
- package/src/internals/index.js +58 -0
- package/src/internals/story/ComponentSetPage.jsx +198 -0
- package/src/internals/story/ComponentSetPage.module.css +129 -0
- package/src/internals/story/StoryPage.jsx +147 -0
- package/src/internals/story/StoryPage.module.css +18 -0
- package/src/internals/test-utils.js +45 -0
- package/src/internals/vite/data-plugin.js +1508 -0
- package/src/internals/vite/data-plugin.test.js +1223 -0
- package/src/test-utils.js +44 -0
- package/toolbar.config.json +271 -0
- package/widgets.config.json +1537 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep merges two objects. Source values take priority over target.
|
|
3
|
+
* Arrays are replaced, not concatenated.
|
|
4
|
+
*/
|
|
5
|
+
function deepMerge(target, source) {
|
|
6
|
+
const result = { ...target }
|
|
7
|
+
|
|
8
|
+
for (const key of Object.keys(source)) {
|
|
9
|
+
const sourceValue = source[key]
|
|
10
|
+
const targetValue = target[key]
|
|
11
|
+
|
|
12
|
+
if (
|
|
13
|
+
sourceValue !== null &&
|
|
14
|
+
typeof sourceValue === 'object' &&
|
|
15
|
+
!Array.isArray(sourceValue) &&
|
|
16
|
+
targetValue !== null &&
|
|
17
|
+
typeof targetValue === 'object' &&
|
|
18
|
+
!Array.isArray(targetValue)
|
|
19
|
+
) {
|
|
20
|
+
result[key] = deepMerge(targetValue, sourceValue)
|
|
21
|
+
} else {
|
|
22
|
+
result[key] = sourceValue
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return result
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Module-level data index, seeded by init().
|
|
31
|
+
* Shape: { flows: {}, objects: {}, records: {} }
|
|
32
|
+
*/
|
|
33
|
+
let dataIndex = { flows: {}, objects: {}, records: {}, prototypes: {}, folders: {}, canvases: {}, stories: {} }
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Seed the data index. Call once at app startup before any load functions.
|
|
37
|
+
* The Vite data plugin calls this automatically via the generated virtual module.
|
|
38
|
+
*
|
|
39
|
+
* @param {{ flows?: object, scenes?: object, objects: object, records: object, prototypes?: object, folders?: object, canvases?: object, stories?: object }} index
|
|
40
|
+
*/
|
|
41
|
+
export function init(index) {
|
|
42
|
+
if (!index || typeof index !== 'object') {
|
|
43
|
+
throw new Error('[storyboard-core] init() requires { flows, objects, records }')
|
|
44
|
+
}
|
|
45
|
+
dataIndex = {
|
|
46
|
+
flows: index.flows || index.scenes || {},
|
|
47
|
+
objects: index.objects || {},
|
|
48
|
+
records: index.records || {},
|
|
49
|
+
prototypes: index.prototypes || {},
|
|
50
|
+
folders: index.folders || {},
|
|
51
|
+
canvases: index.canvases || {},
|
|
52
|
+
stories: index.stories || {},
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Loads a data file by name and type from the data index.
|
|
58
|
+
* Data is pre-parsed at build time — returns a deep clone to prevent mutation.
|
|
59
|
+
* @param {string} name - Data file name (e.g., "jane-doe", "default")
|
|
60
|
+
* @param {string} [type] - Data type: "scenes", "objects", or "records". If omitted, searches all types.
|
|
61
|
+
* @returns {object} Parsed file contents
|
|
62
|
+
*/
|
|
63
|
+
function loadDataFile(name, type) {
|
|
64
|
+
if (type && dataIndex[type]?.[name] != null) {
|
|
65
|
+
return dataIndex[type][name]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Search all types if no specific type given
|
|
69
|
+
if (!type) {
|
|
70
|
+
for (const t of ['flows', 'objects', 'records']) {
|
|
71
|
+
if (dataIndex[t]?.[name] != null) {
|
|
72
|
+
return dataIndex[t][name]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Case-insensitive fallback for flows
|
|
78
|
+
if (type === 'flows' || !type) {
|
|
79
|
+
const lower = name.toLowerCase()
|
|
80
|
+
for (const key of Object.keys(dataIndex.flows)) {
|
|
81
|
+
if (key.toLowerCase() === lower) {
|
|
82
|
+
return dataIndex.flows[key]
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const available = Object.keys(dataIndex[type] || {})
|
|
88
|
+
const scopedHints = available.filter(k => k.includes('/')).slice(0, 5)
|
|
89
|
+
const hint = scopedHints.length > 0
|
|
90
|
+
? `\n Scoped names in index: ${scopedHints.join(', ')}`
|
|
91
|
+
: ''
|
|
92
|
+
throw new Error(`Data file not found: ${name}${type ? ` (type: ${type})` : ''}${hint}`)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Recursively resolves $ref objects within data.
|
|
97
|
+
* A $ref is a name resolved from the data index (objects first, then any type).
|
|
98
|
+
*
|
|
99
|
+
* @param {*} node - Current data node
|
|
100
|
+
* @param {Set} seen - Tracks visited names to prevent circular refs
|
|
101
|
+
* @returns {*} Resolved data
|
|
102
|
+
*/
|
|
103
|
+
function resolveRefs(node, seen = new Set(), scope = null) {
|
|
104
|
+
if (node === null || typeof node !== 'object') return node
|
|
105
|
+
if (Array.isArray(node)) {
|
|
106
|
+
return node.map((item) => resolveRefs(item, seen, scope))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Handle $ref replacement
|
|
110
|
+
if (node.$ref && typeof node.$ref === 'string') {
|
|
111
|
+
const refName = node.$ref
|
|
112
|
+
const resolvedRef = scope ? resolveObjectName(scope, refName) : refName
|
|
113
|
+
if (seen.has(resolvedRef)) {
|
|
114
|
+
throw new Error(`Circular $ref detected: ${refName}`)
|
|
115
|
+
}
|
|
116
|
+
seen.add(resolvedRef)
|
|
117
|
+
const refData = loadDataFile(resolvedRef, 'objects')
|
|
118
|
+
return resolveRefs(refData, seen, scope)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Recurse into object values
|
|
122
|
+
const result = {}
|
|
123
|
+
for (const [key, value] of Object.entries(node)) {
|
|
124
|
+
result[key] = resolveRefs(value, seen, scope)
|
|
125
|
+
}
|
|
126
|
+
return result
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Returns the names of all registered flows.
|
|
131
|
+
* @returns {string[]}
|
|
132
|
+
*/
|
|
133
|
+
export function listFlows() {
|
|
134
|
+
return Object.keys(dataIndex.flows)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** @deprecated Use listFlows() */
|
|
138
|
+
export const listScenes = listFlows
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Returns flows scoped to a specific prototype, with resolved metadata.
|
|
142
|
+
*
|
|
143
|
+
* @param {string} prototypeName - e.g., "Signup", "Dashboard"
|
|
144
|
+
* @returns {Array<{ key: string, name: string, meta: object|null }>}
|
|
145
|
+
*/
|
|
146
|
+
export function getFlowsForPrototype(prototypeName) {
|
|
147
|
+
if (!prototypeName) return []
|
|
148
|
+
const prefix = prototypeName + '/'
|
|
149
|
+
return Object.keys(dataIndex.flows)
|
|
150
|
+
.filter(key => key.startsWith(prefix))
|
|
151
|
+
.map(key => ({
|
|
152
|
+
key,
|
|
153
|
+
name: key.substring(prefix.length),
|
|
154
|
+
meta: null,
|
|
155
|
+
}))
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Checks whether a flow file exists for the given name.
|
|
160
|
+
* @param {string} flowName - e.g., "Overview"
|
|
161
|
+
* @returns {boolean}
|
|
162
|
+
*/
|
|
163
|
+
export function flowExists(flowName) {
|
|
164
|
+
if (dataIndex.flows[flowName] != null) return true
|
|
165
|
+
const lower = flowName.toLowerCase()
|
|
166
|
+
for (const key of Object.keys(dataIndex.flows)) {
|
|
167
|
+
if (key.toLowerCase() === lower) return true
|
|
168
|
+
}
|
|
169
|
+
return false
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** @deprecated Use flowExists() */
|
|
173
|
+
export const sceneExists = flowExists
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Loads a flow file and resolves $global and $ref references.
|
|
177
|
+
*
|
|
178
|
+
* - $global: array of data names merged into root (flow wins on conflicts)
|
|
179
|
+
* - $ref: inline object replacement at any nesting level
|
|
180
|
+
*
|
|
181
|
+
* @param {string} flowName - Name of the flow (e.g., "default")
|
|
182
|
+
* @returns {object} Resolved flow data
|
|
183
|
+
*/
|
|
184
|
+
export function loadFlow(flowName = 'default') {
|
|
185
|
+
let flowData
|
|
186
|
+
|
|
187
|
+
// Extract prototype scope from the flow name (e.g. "Dashboard/default" → "Dashboard")
|
|
188
|
+
const scope = flowName.includes('/') ? flowName.split('/')[0] : null
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
flowData = structuredClone(loadDataFile(flowName, 'flows'))
|
|
192
|
+
} catch {
|
|
193
|
+
const available = listFlows()
|
|
194
|
+
const related = available.filter(k =>
|
|
195
|
+
k.endsWith('/' + flowName) || k.startsWith(flowName + '/')
|
|
196
|
+
)
|
|
197
|
+
const hint = related.length > 0
|
|
198
|
+
? ` Did you mean: ${related.join(', ')}?`
|
|
199
|
+
: ''
|
|
200
|
+
throw new Error(`Failed to load flow: ${flowName}.${hint}`)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Handle $global: root-level merge from referenced data files
|
|
204
|
+
if (Array.isArray(flowData.$global)) {
|
|
205
|
+
const globalNames = flowData.$global
|
|
206
|
+
delete flowData.$global
|
|
207
|
+
|
|
208
|
+
let mergedGlobals = {}
|
|
209
|
+
for (const name of globalNames) {
|
|
210
|
+
try {
|
|
211
|
+
const resolvedName = scope ? resolveObjectName(scope, name) : name
|
|
212
|
+
let globalData = loadDataFile(resolvedName)
|
|
213
|
+
globalData = resolveRefs(globalData, new Set(), scope)
|
|
214
|
+
mergedGlobals = deepMerge(mergedGlobals, globalData)
|
|
215
|
+
} catch (err) {
|
|
216
|
+
console.warn(`Failed to load $global: ${name}`, err)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
flowData = deepMerge(mergedGlobals, flowData)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
flowData = resolveRefs(flowData, new Set(), scope)
|
|
224
|
+
|
|
225
|
+
// Single clone at the boundary — resolveRefs builds new objects internally,
|
|
226
|
+
// so the index data is safe. Clone here to prevent consumer mutation.
|
|
227
|
+
return structuredClone(flowData)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** @deprecated Use loadFlow() */
|
|
231
|
+
export const loadScene = loadFlow
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Loads a record collection by name.
|
|
235
|
+
* @param {string} recordName - Name of the record file (e.g., "posts")
|
|
236
|
+
* @returns {Array} Parsed record collection
|
|
237
|
+
*/
|
|
238
|
+
export function loadRecord(recordName) {
|
|
239
|
+
const data = dataIndex.records[recordName]
|
|
240
|
+
if (data == null) {
|
|
241
|
+
const available = Object.keys(dataIndex.records)
|
|
242
|
+
const related = available.filter(k =>
|
|
243
|
+
k.endsWith('/' + recordName) || k.startsWith(recordName + '/')
|
|
244
|
+
)
|
|
245
|
+
const hint = related.length > 0
|
|
246
|
+
? ` Did you mean: ${related.join(', ')}?`
|
|
247
|
+
: ''
|
|
248
|
+
throw new Error(`Record not found: ${recordName}.${hint}`)
|
|
249
|
+
}
|
|
250
|
+
if (!Array.isArray(data)) {
|
|
251
|
+
throw new Error(`Record "${recordName}" must be an array, got ${typeof data}`)
|
|
252
|
+
}
|
|
253
|
+
return structuredClone(data)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Finds a single record entry by id within a collection.
|
|
258
|
+
* @param {string} recordName - Record collection name (e.g., "posts")
|
|
259
|
+
* @param {string} id - The id to match
|
|
260
|
+
* @returns {object|null} The matched entry, or null
|
|
261
|
+
*/
|
|
262
|
+
export function findRecord(recordName, id) {
|
|
263
|
+
const records = loadRecord(recordName)
|
|
264
|
+
return records.find((entry) => entry.id === id) ?? null
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Loads an object data file by name, resolves any nested $ref references,
|
|
269
|
+
* and returns a deep clone.
|
|
270
|
+
*
|
|
271
|
+
* @param {string} objectName - Name of the object file (e.g., "jane-doe")
|
|
272
|
+
* @param {string|null} [scope] - Optional prototype scope for name resolution
|
|
273
|
+
* @returns {object|Array} Resolved object data
|
|
274
|
+
*/
|
|
275
|
+
export function loadObject(objectName, scope) {
|
|
276
|
+
const resolved = scope ? resolveObjectName(scope, objectName) : objectName
|
|
277
|
+
const data = loadDataFile(resolved, 'objects')
|
|
278
|
+
return resolveRefs(structuredClone(data), new Set(), scope)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Resolve a flow name within a prototype scope.
|
|
283
|
+
* Tries the scoped name first ({scope}/{name}), then falls back to the plain name.
|
|
284
|
+
*
|
|
285
|
+
* @param {string|null} scope - Prototype name (e.g. "Dashboard"), or null for global-only
|
|
286
|
+
* @param {string} name - Flow name (e.g. "default" or "Dashboard/signup")
|
|
287
|
+
* @returns {string} The resolved flow name that exists in the index
|
|
288
|
+
*/
|
|
289
|
+
export function resolveFlowName(scope, name) {
|
|
290
|
+
if (scope) {
|
|
291
|
+
const scoped = `${scope}/${name}`
|
|
292
|
+
if (flowExists(scoped)) return scoped
|
|
293
|
+
}
|
|
294
|
+
if (flowExists(name)) return name
|
|
295
|
+
// Return the scoped name for better error messages even if it doesn't exist
|
|
296
|
+
return scope ? `${scope}/${name}` : name
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Resolve a record name within a prototype scope.
|
|
301
|
+
* Tries the scoped name first ({scope}/{name}), then falls back to the plain name.
|
|
302
|
+
*
|
|
303
|
+
* @param {string|null} scope - Prototype name (e.g. "Dashboard"), or null for global-only
|
|
304
|
+
* @param {string} name - Record name (e.g. "posts")
|
|
305
|
+
* @returns {string} The resolved record name that exists in the index
|
|
306
|
+
*/
|
|
307
|
+
export function resolveRecordName(scope, name) {
|
|
308
|
+
if (scope) {
|
|
309
|
+
const scoped = `${scope}/${name}`
|
|
310
|
+
if (dataIndex.records[scoped] != null) return scoped
|
|
311
|
+
}
|
|
312
|
+
if (dataIndex.records[name] != null) return name
|
|
313
|
+
return scope ? `${scope}/${name}` : name
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Resolve an object name within a prototype scope.
|
|
318
|
+
* Tries the scoped name first ({scope}/{name}), then falls back to the plain name.
|
|
319
|
+
*
|
|
320
|
+
* @param {string|null} scope - Prototype name (e.g. "Dashboard"), or null for global-only
|
|
321
|
+
* @param {string} name - Object name (e.g. "jane-doe")
|
|
322
|
+
* @returns {string} The resolved object name that exists in the index
|
|
323
|
+
*/
|
|
324
|
+
export function resolveObjectName(scope, name) {
|
|
325
|
+
if (scope) {
|
|
326
|
+
const scoped = `${scope}/${name}`
|
|
327
|
+
if (dataIndex.objects[scoped] != null) return scoped
|
|
328
|
+
}
|
|
329
|
+
if (dataIndex.objects[name] != null) return name
|
|
330
|
+
return scope ? `${scope}/${name}` : name
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Returns the names of all registered prototypes.
|
|
335
|
+
* @returns {string[]}
|
|
336
|
+
*/
|
|
337
|
+
export function listPrototypes() {
|
|
338
|
+
return Object.keys(dataIndex.prototypes)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Returns prototype metadata by name.
|
|
343
|
+
* @param {string} name - Prototype name (e.g. "Example")
|
|
344
|
+
* @returns {object|null} Metadata from the .prototype.json file, or null
|
|
345
|
+
*/
|
|
346
|
+
export function getPrototypeMetadata(name) {
|
|
347
|
+
return dataIndex.prototypes[name] ?? null
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Returns the names of all registered folders.
|
|
352
|
+
* @returns {string[]}
|
|
353
|
+
*/
|
|
354
|
+
export function listFolders() {
|
|
355
|
+
return Object.keys(dataIndex.folders)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Returns folder metadata by name.
|
|
360
|
+
* @param {string} name - Folder name (e.g. "Getting Started")
|
|
361
|
+
* @returns {object|null} Metadata from the .folder.json file, or null
|
|
362
|
+
*/
|
|
363
|
+
export function getFolderMetadata(name) {
|
|
364
|
+
return dataIndex.folders[name] ?? null
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Returns the names of all registered canvases.
|
|
369
|
+
* @returns {string[]}
|
|
370
|
+
*/
|
|
371
|
+
export function listCanvases() {
|
|
372
|
+
return Object.keys(dataIndex.canvases)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Returns canvas data by name.
|
|
377
|
+
* @param {string} name - Canvas name (e.g. "design-overview")
|
|
378
|
+
* @returns {object|null} Data from the .canvas.json file, or null
|
|
379
|
+
*/
|
|
380
|
+
export function getCanvasData(name) {
|
|
381
|
+
return dataIndex.canvases[name] ?? null
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Returns the names of all registered stories.
|
|
386
|
+
* @returns {string[]}
|
|
387
|
+
*/
|
|
388
|
+
export function listStories() {
|
|
389
|
+
return Object.keys(dataIndex.stories)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Returns story data by name.
|
|
394
|
+
* Story entries include `_storyModule` (path) and `_storyImport` (dynamic import function).
|
|
395
|
+
* Accepts both flat names ("product-card") and scoped names ("folder/product-card") —
|
|
396
|
+
* if an exact match isn't found and the name contains a slash, tries the basename.
|
|
397
|
+
* @param {string} name - Story name (e.g. "button-patterns" or "explorations/button-patterns")
|
|
398
|
+
* @returns {object|null} Story data with import function, or null
|
|
399
|
+
*/
|
|
400
|
+
export function getStoryData(name) {
|
|
401
|
+
if (dataIndex.stories[name]) return dataIndex.stories[name]
|
|
402
|
+
if (name && name.includes('/')) {
|
|
403
|
+
const basename = name.split('/').pop()
|
|
404
|
+
if (dataIndex.stories[basename]) return dataIndex.stories[basename]
|
|
405
|
+
}
|
|
406
|
+
return null
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export { deepMerge }
|