@dxos/plugin-script 0.12.0-next-73daef452f1464b62efdbca75fb0067c1066f264 → 0.13.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/PLUGIN.mdl +93 -17
- package/README.md +1 -1
- package/dist/lib/Notebook.mjs +4 -5
- package/dist/lib/Notebook.mjs.map +1 -1
- package/dist/lib/ScriptCapabilities.mjs.map +1 -1
- package/dist/lib/ScriptOperation.mjs +1 -1
- package/dist/lib/ScriptOperation.mjs.map +1 -1
- package/dist/lib/ScriptOperationHandlerSet.mjs.map +1 -1
- package/dist/lib/ScriptSkill.mjs +1 -1
- package/dist/lib/ScriptSkill.mjs.map +1 -1
- package/dist/lib/capabilities.browser.mjs +51 -0
- package/dist/lib/capabilities.browser.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +17 -7
- package/dist/lib/capabilities.mjs.map +1 -1
- package/dist/lib/capabilities.node.mjs +16 -4
- package/dist/lib/capabilities.node.mjs.map +1 -1
- package/dist/lib/capabilities.tauri.mjs +51 -0
- package/dist/lib/capabilities.tauri.mjs.map +1 -0
- package/dist/lib/capabilities.workerd.mjs +1 -1
- package/dist/lib/capabilities.workerd.mjs.map +1 -1
- package/dist/lib/chunk-DeploymentDialog.mjs +12 -9
- package/dist/lib/chunk-DeploymentDialog.mjs.map +1 -1
- package/dist/lib/chunk-NotebookArticle.mjs +37 -36
- package/dist/lib/chunk-NotebookArticle.mjs.map +1 -1
- package/dist/lib/chunk-PLUGIN.mjs +6 -0
- package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
- package/dist/lib/chunk-ScriptArticle.mjs +14 -15
- package/dist/lib/chunk-ScriptArticle.mjs.map +1 -1
- package/dist/lib/chunk-ScriptProperties.mjs +91 -94
- package/dist/lib/chunk-ScriptProperties.mjs.map +1 -1
- package/dist/lib/chunk-ScriptSettings.mjs +11 -8
- package/dist/lib/chunk-ScriptSettings.mjs.map +1 -1
- package/dist/lib/chunk-TestContainer.mjs +5 -5
- package/dist/lib/chunk-TestContainer.mjs.map +1 -1
- package/dist/lib/chunk-app-graph-builder.mjs +2 -0
- package/dist/lib/chunk-app-graph-builder.mjs.map +1 -1
- package/dist/lib/chunk-compiler.mjs +87 -4
- package/dist/lib/chunk-compiler.mjs.map +1 -1
- package/dist/lib/chunk-create-object.mjs +1 -1
- package/dist/lib/chunk-create-script.mjs.map +1 -1
- package/dist/lib/chunk-create.mjs +4 -4
- package/dist/lib/chunk-create.mjs.map +1 -1
- package/dist/lib/chunk-definitions.mjs +246 -0
- package/dist/lib/chunk-definitions.mjs.map +1 -0
- package/dist/lib/chunk-delete.mjs +2 -2
- package/dist/lib/chunk-delete.mjs.map +1 -1
- package/dist/lib/chunk-deploy.mjs +16 -12
- package/dist/lib/chunk-deploy.mjs.map +1 -1
- package/dist/lib/chunk-errors.mjs +8 -0
- package/dist/lib/chunk-errors.mjs.map +1 -0
- package/dist/lib/chunk-functions.mjs +66 -246
- package/dist/lib/chunk-functions.mjs.map +1 -1
- package/dist/lib/chunk-inspect-invocations.mjs +3 -3
- package/dist/lib/chunk-inspect-invocations.mjs.map +1 -1
- package/dist/lib/chunk-install-function.mjs +11 -11
- package/dist/lib/chunk-install-function.mjs.map +1 -1
- package/dist/lib/chunk-invoke.mjs +6 -6
- package/dist/lib/chunk-invoke.mjs.map +1 -1
- package/dist/lib/chunk-operation-handler.mjs +16 -2
- package/dist/lib/chunk-operation-handler.mjs.map +1 -1
- package/dist/lib/chunk-query-deployed-functions.mjs +5 -6
- package/dist/lib/chunk-query-deployed-functions.mjs.map +1 -1
- package/dist/lib/chunk-react-surface.mjs +14 -10
- package/dist/lib/chunk-react-surface.mjs.map +1 -1
- package/dist/lib/chunk-read.mjs +4 -3
- package/dist/lib/chunk-read.mjs.map +1 -1
- package/dist/lib/chunk-settings.mjs +2 -2
- package/dist/lib/chunk-settings.mjs.map +1 -1
- package/dist/lib/chunk-skill-definition.mjs +1 -1
- package/dist/lib/chunk-templates.mjs +3 -3
- package/dist/lib/chunk-update.mjs +4 -3
- package/dist/lib/chunk-update.mjs.map +1 -1
- package/dist/lib/components.mjs +114 -123
- package/dist/lib/components.mjs.map +1 -1
- package/dist/lib/containers.mjs.map +1 -1
- package/dist/lib/hooks.mjs +96 -16
- package/dist/lib/hooks.mjs.map +1 -1
- package/dist/lib/index.mjs +5 -3
- package/dist/lib/meta.mjs.map +1 -1
- package/dist/lib/ns/ScriptFunction.mjs +12 -0
- package/dist/lib/ns/ScriptFunction.mjs.map +1 -0
- package/dist/lib/ns/Templates.mjs +11 -0
- package/dist/lib/ns/Templates.mjs.map +1 -0
- package/dist/lib/testing.mjs +1 -1
- package/dist/lib/translations.mjs +2 -1
- package/dist/lib/translations.mjs.map +1 -1
- package/dist/types/src/ScriptFunction.d.ts +2 -0
- package/dist/types/src/ScriptFunction.d.ts.map +1 -0
- package/dist/types/src/Templates.d.ts +2 -0
- package/dist/types/src/Templates.d.ts.map +1 -0
- package/dist/types/src/capabilities/ScriptSurfaces.d.ts.map +1 -1
- package/dist/types/src/capabilities/compiler.d.ts +2 -1
- package/dist/types/src/capabilities/compiler.d.ts.map +1 -1
- package/dist/types/src/capabilities/errors.d.ts +33 -0
- package/dist/types/src/capabilities/errors.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/browser.d.ts +12 -0
- package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/node.d.ts.map +1 -1
- package/dist/types/src/capabilities/gen/tauri.d.ts +12 -0
- package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/compiler/index.d.ts +1 -1
- package/dist/types/src/compiler/index.d.ts.map +1 -1
- package/dist/types/src/components/NotebookStack/NotebookCell.d.ts +3 -3
- package/dist/types/src/components/NotebookStack/NotebookCell.d.ts.map +1 -1
- package/dist/types/src/components/NotebookStack/NotebookMenu.d.ts.map +1 -1
- package/dist/types/src/components/NotebookStack/NotebookStack.d.ts +4 -4
- package/dist/types/src/components/NotebookStack/NotebookStack.d.ts.map +1 -1
- package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts +10 -0
- package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts.map +1 -1
- package/dist/types/src/components/NotebookStack/index.d.ts +2 -2
- package/dist/types/src/components/NotebookStack/index.d.ts.map +1 -1
- package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts +2 -2
- package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
- package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts +10 -0
- package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScriptToolbar/index.d.ts +1 -1
- package/dist/types/src/components/ScriptToolbar/index.d.ts.map +1 -1
- package/dist/types/src/components/TestPanel/TestPanel.d.ts +2 -2
- package/dist/types/src/components/TestPanel/TestPanel.d.ts.map +1 -1
- package/dist/types/src/components/TestPanel/index.d.ts +1 -1
- package/dist/types/src/components/TestPanel/index.d.ts.map +1 -1
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts +2 -2
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -1
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts +1 -1
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TypescriptEditor/index.d.ts +1 -1
- package/dist/types/src/components/TypescriptEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +4 -5
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/DeploymentDialog/DeploymentDialog.d.ts +1 -1
- package/dist/types/src/containers/DeploymentDialog/DeploymentDialog.d.ts.map +1 -1
- package/dist/types/src/containers/DeploymentDialog/DeploymentDialog.stories.d.ts +10 -0
- package/dist/types/src/containers/DeploymentDialog/DeploymentDialog.stories.d.ts.map +1 -1
- package/dist/types/src/containers/DeploymentDialog/index.d.ts +1 -1
- package/dist/types/src/containers/DeploymentDialog/index.d.ts.map +1 -1
- package/dist/types/src/containers/NotebookArticle/NotebookArticle.d.ts +1 -1
- package/dist/types/src/containers/NotebookArticle/NotebookArticle.d.ts.map +1 -1
- package/dist/types/src/containers/NotebookArticle/NotebookArticle.stories.d.ts +1 -1
- package/dist/types/src/containers/NotebookArticle/NotebookArticle.stories.d.ts.map +1 -1
- package/dist/types/src/containers/NotebookArticle/index.d.ts +1 -1
- package/dist/types/src/containers/NotebookArticle/index.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptArticle/ScriptArticle.d.ts +1 -1
- package/dist/types/src/containers/ScriptArticle/ScriptArticle.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptArticle/ScriptArticle.stories.d.ts +10 -0
- package/dist/types/src/containers/ScriptArticle/ScriptArticle.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptArticle/index.d.ts +1 -1
- package/dist/types/src/containers/ScriptArticle/index.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptProperties/FunctionBinding.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptProperties/FunctionPublishing.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptProperties/ScriptProperties.d.ts +1 -1
- package/dist/types/src/containers/ScriptProperties/ScriptProperties.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptProperties/ScriptProperties.stories.d.ts +10 -0
- package/dist/types/src/containers/ScriptProperties/ScriptProperties.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptProperties/SkillEditor.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptProperties/index.d.ts +1 -1
- package/dist/types/src/containers/ScriptProperties/index.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptSettings/ScriptSettings.d.ts +2 -2
- package/dist/types/src/containers/ScriptSettings/ScriptSettings.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptSettings/ScriptSettings.stories.d.ts +11 -1
- package/dist/types/src/containers/ScriptSettings/ScriptSettings.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ScriptSettings/index.d.ts +1 -1
- package/dist/types/src/containers/ScriptSettings/index.d.ts.map +1 -1
- package/dist/types/src/containers/TestContainer/index.d.ts +1 -1
- package/dist/types/src/containers/TestContainer/index.d.ts.map +1 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/hooks/deploy.d.ts +3 -3
- package/dist/types/src/hooks/deploy.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +6 -6
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useCompiler.d.ts +1 -1
- package/dist/types/src/hooks/useCompiler.d.ts.map +1 -1
- package/dist/types/src/hooks/useCreateAndDeployScriptTemplates.d.ts +1 -1
- package/dist/types/src/hooks/useCreateAndDeployScriptTemplates.d.ts.map +1 -1
- package/dist/types/src/hooks/useToolbarState.d.ts +2 -2
- package/dist/types/src/hooks/useToolbarState.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +5 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/notebook/compute-graph.d.ts +3 -3
- package/dist/types/src/notebook/compute-graph.d.ts.map +1 -1
- package/dist/types/src/notebook/index.d.ts +1 -1
- package/dist/types/src/notebook/index.d.ts.map +1 -1
- package/dist/types/src/operations/ScriptOperationHandlerSet.d.ts.map +1 -1
- package/dist/types/src/operations/index.d.ts +1 -1
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/skills/ScriptSkill.d.ts.map +1 -1
- package/dist/types/src/skills/functions/definitions.d.ts +8 -6
- package/dist/types/src/skills/functions/definitions.d.ts.map +1 -1
- package/dist/types/src/skills/functions/deploy.d.ts +4 -2
- package/dist/types/src/skills/functions/deploy.d.ts.map +1 -1
- package/dist/types/src/skills/functions/errors.d.ts +33 -0
- package/dist/types/src/skills/functions/errors.d.ts.map +1 -0
- package/dist/types/src/skills/functions/index.d.ts +1 -1
- package/dist/types/src/skills/functions/index.d.ts.map +1 -1
- package/dist/types/src/skills/functions/install-function.d.ts +3 -2
- package/dist/types/src/skills/functions/install-function.d.ts.map +1 -1
- package/dist/types/src/skills/functions/invoke.d.ts +2 -2
- package/dist/types/src/skills/functions/invoke.d.ts.map +1 -1
- package/dist/types/src/skills/functions/query-deployed-functions.d.ts +2 -2
- package/dist/types/src/skills/functions/query-deployed-functions.d.ts.map +1 -1
- package/dist/types/src/skills/index.d.ts +1 -1
- package/dist/types/src/skills/index.d.ts.map +1 -1
- package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +2 -2
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +10 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/Notebook.d.ts.map +1 -1
- package/dist/types/src/types/ScriptCapabilities.d.ts +3 -3
- package/dist/types/src/types/ScriptCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +5 -5
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/util/deploy.d.ts +6 -3
- package/dist/types/src/util/deploy.d.ts.map +1 -1
- package/dist/types/src/util/functions.d.ts +1 -1
- package/dist/types/src/util/functions.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +2 -2
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +106 -96
- package/src/ScriptFunction.ts +7 -0
- package/src/Templates.ts +7 -0
- package/src/capabilities/ScriptSurfaces.tsx +19 -10
- package/src/capabilities/app-graph-builder.ts +2 -0
- package/src/capabilities/compiler.ts +6 -5
- package/src/capabilities/errors.ts +8 -0
- package/src/capabilities/gen/browser.ts +62 -0
- package/src/capabilities/gen/node.ts +10 -10
- package/src/capabilities/gen/tauri.ts +62 -0
- package/src/capabilities/gen/workerd.ts +4 -4
- package/src/capabilities/index.ts +11 -11
- package/src/capabilities/operation-handler.ts +1 -1
- package/src/capabilities/react-surface.ts +4 -4
- package/src/capabilities/settings.ts +2 -2
- package/src/compiler/compiler.browser.test.ts +1 -1
- package/src/compiler/index.ts +1 -1
- package/src/components/NotebookStack/NotebookCell.tsx +35 -29
- package/src/components/NotebookStack/NotebookMenu.tsx +27 -26
- package/src/components/NotebookStack/NotebookStack.stories.tsx +3 -3
- package/src/components/NotebookStack/NotebookStack.tsx +20 -17
- package/src/components/NotebookStack/index.ts +2 -2
- package/src/components/ScriptToolbar/ScriptToolbar.stories.tsx +5 -5
- package/src/components/ScriptToolbar/ScriptToolbar.tsx +14 -15
- package/src/components/ScriptToolbar/index.ts +1 -1
- package/src/components/TestPanel/TestPanel.tsx +29 -23
- package/src/components/TestPanel/index.ts +1 -1
- package/src/components/TypescriptEditor/TypescriptEditor.stories.tsx +10 -8
- package/src/components/TypescriptEditor/TypescriptEditor.tsx +11 -7
- package/src/components/TypescriptEditor/index.ts +1 -1
- package/src/components/index.ts +4 -5
- package/src/containers/DeploymentDialog/DeploymentDialog.stories.tsx +5 -7
- package/src/containers/DeploymentDialog/DeploymentDialog.tsx +18 -15
- package/src/containers/DeploymentDialog/index.ts +1 -1
- package/src/containers/NotebookArticle/NotebookArticle.stories.tsx +6 -6
- package/src/containers/NotebookArticle/NotebookArticle.tsx +25 -21
- package/src/containers/NotebookArticle/index.ts +1 -1
- package/src/containers/ScriptArticle/ScriptArticle.stories.tsx +3 -3
- package/src/containers/ScriptArticle/ScriptArticle.tsx +13 -11
- package/src/containers/ScriptArticle/index.ts +1 -1
- package/src/containers/ScriptProperties/FunctionBinding.tsx +18 -18
- package/src/containers/ScriptProperties/FunctionPublishing.tsx +22 -22
- package/src/containers/ScriptProperties/ScriptProperties.stories.tsx +3 -3
- package/src/containers/ScriptProperties/ScriptProperties.tsx +10 -10
- package/src/containers/ScriptProperties/SkillEditor.tsx +16 -14
- package/src/containers/ScriptProperties/index.ts +1 -1
- package/src/containers/ScriptSettings/ScriptSettings.stories.tsx +1 -1
- package/src/containers/ScriptSettings/ScriptSettings.tsx +16 -11
- package/src/containers/ScriptSettings/index.ts +1 -1
- package/src/containers/TestContainer/TestContainer.tsx +4 -4
- package/src/containers/TestContainer/index.ts +1 -1
- package/src/containers/index.ts +6 -6
- package/src/e2e/ai.test.ts +1 -1
- package/src/hooks/deploy.ts +12 -5
- package/src/hooks/index.ts +6 -6
- package/src/hooks/template.ts +1 -1
- package/src/hooks/useCompiler.ts +8 -7
- package/src/hooks/useCreateAndDeployScriptTemplates.ts +10 -5
- package/src/hooks/useToolbarState.ts +4 -4
- package/src/index.ts +5 -3
- package/src/meta.ts +1 -1
- package/src/notebook/compute-graph.test.ts +2 -2
- package/src/notebook/compute-graph.ts +4 -4
- package/src/notebook/index.ts +1 -1
- package/src/notebook/vfs-parser.test.ts +1 -1
- package/src/notebook/vfs-parser.ts +1 -1
- package/src/operations/ScriptOperationHandlerSet.ts +3 -1
- package/src/operations/create-script.ts +1 -1
- package/src/operations/index.ts +1 -1
- package/src/plugin.test.ts +2 -2
- package/src/skills/ScriptSkill.ts +3 -1
- package/src/skills/functions/create.ts +4 -4
- package/src/skills/functions/definitions.ts +8 -6
- package/src/skills/functions/delete.ts +1 -1
- package/src/skills/functions/deploy.ts +13 -9
- package/src/skills/functions/errors.ts +8 -0
- package/src/skills/functions/index.ts +11 -11
- package/src/skills/functions/inspect-invocations.ts +1 -1
- package/src/skills/functions/install-function.ts +11 -14
- package/src/skills/functions/invoke.ts +5 -5
- package/src/skills/functions/query-deployed-functions.ts +3 -4
- package/src/skills/functions/read.ts +3 -2
- package/src/skills/functions/update.ts +3 -2
- package/src/skills/index.ts +1 -1
- package/src/templates/anthropic.ts +2 -2
- package/src/templates/commentary.ts +1 -1
- package/src/templates/forex-effect.ts +7 -4
- package/src/testing/index.ts +2 -2
- package/src/translations.ts +4 -2
- package/src/types/Notebook.ts +6 -4
- package/src/types/ScriptCapabilities.ts +3 -3
- package/src/types/ScriptOperation.ts +1 -1
- package/src/types/index.ts +5 -5
- package/src/util/deploy.ts +10 -7
- package/src/util/functions.ts +24 -15
- package/src/util/index.ts +2 -2
- package/dist/lib/chunk-compiler2.mjs +0 -76
- package/dist/lib/chunk-compiler2.mjs.map +0 -1
- package/dist/lib/chunk-util.mjs +0 -146
- package/dist/lib/chunk-util.mjs.map +0 -1
- package/dist/types/src/components/QueryEditor/QueryEditor.d.ts +0 -5
- package/dist/types/src/components/QueryEditor/QueryEditor.d.ts.map +0 -1
- package/dist/types/src/components/QueryEditor/QueryEditor.stories.d.ts +0 -14
- package/dist/types/src/components/QueryEditor/QueryEditor.stories.d.ts.map +0 -1
- package/dist/types/src/components/QueryEditor/index.d.ts +0 -2
- package/dist/types/src/components/QueryEditor/index.d.ts.map +0 -1
- package/src/components/QueryEditor/QueryEditor.stories.tsx +0 -91
- package/src/components/QueryEditor/QueryEditor.tsx +0 -50
- package/src/components/QueryEditor/index.ts +0 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.mjs","names":[],"sources":["../../src/components/NotebookStack/NotebookMenu.tsx","../../src/components/TypescriptEditor/TypescriptEditor.tsx","../../src/components/NotebookStack/NotebookCell.tsx","../../src/components/NotebookStack/NotebookStack.tsx","../../src/components/QueryEditor/QueryEditor.tsx","../../src/components/ScriptToolbar/ScriptToolbar.tsx","../../src/components/TestPanel/TestPanel.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { DropdownMenu, useTranslation } from '@dxos/react-ui';\n\nimport { meta } from '#meta';\nimport { Notebook } from '#types';\n\nexport type NotebookMenuProps = {\n cell?: Notebook.Cell;\n onCellInsert?: (type: Notebook.CellType, after: string | undefined) => void;\n onCellDelete?: (id: string) => void;\n};\n\n// TODO(burdon): Better way to organize menu?\nexport const NotebookMenu = ({ cell, onCellInsert, onCellDelete }: NotebookMenuProps) => {\n const { t } = useTranslation(meta.profile.key);\n return (\n <DropdownMenu.Portal>\n <DropdownMenu.Content>\n <DropdownMenu.Viewport>\n <DropdownMenu.Item onClick={() => onCellInsert?.('script', cell?.id)}>\n {t('notebook-cell-insert-script.label')}\n </DropdownMenu.Item>\n <DropdownMenu.Item onClick={() => onCellInsert?.('prompt', cell?.id)}>\n {t('notebook-cell-insert-prompt.label')}\n </DropdownMenu.Item>\n <DropdownMenu.Item onClick={() => onCellInsert?.('query', cell?.id)}>\n {t('notebook-cell-insert-query.label')}\n </DropdownMenu.Item>\n <DropdownMenu.Item onClick={() => onCellInsert?.('markdown', cell?.id)}>\n {t('notebook-cell-insert-markdown.label')}\n </DropdownMenu.Item>\n {cell && onCellDelete && (\n <DropdownMenu.Item onClick={() => onCellDelete?.(cell.id)}>\n {t('notebook-cell-delete.label')}\n </DropdownMenu.Item>\n )}\n </DropdownMenu.Viewport>\n <DropdownMenu.Arrow />\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { autocompletion, completionKeymap } from '@codemirror/autocomplete';\nimport { javascript } from '@codemirror/lang-javascript';\nimport { HighlightStyle } from '@codemirror/language';\nimport { lintKeymap } from '@codemirror/lint';\nimport { Prec } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport { tags } from '@lezer/highlight';\nimport { composeRefs } from '@radix-ui/react-compose-refs';\nimport { type VirtualTypeScriptEnvironment } from '@typescript/vfs';\nimport { continueKeymap } from '@valtown/codemirror-continue';\nimport { type HoverInfo, tsAutocomplete, tsFacet, tsHover, tsLinter, tsSync } from '@valtown/codemirror-ts';\nimport React from 'react';\n\nimport { type ThemedClassName, type ThemeMode, useThemeContext } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { type UseTextEditorProps, useTextEditor } from '@dxos/react-ui-editor';\nimport { Domino } from '@dxos/ui';\nimport {\n type BasicExtensionsOptions,\n InputModeExtensions,\n createBasicExtensions,\n createThemeExtensions,\n defaultStyles,\n} from '@dxos/ui-editor';\nimport { type EditorInputMode } from '@dxos/ui-editor/types';\nimport { isNonNullable } from '@dxos/util';\n\nexport type TypescriptEditorProps = ThemedClassName<\n {\n id: string;\n role?: string;\n inputMode?: EditorInputMode;\n toolbar?: boolean;\n env?: VirtualTypeScriptEnvironment;\n options?: BasicExtensionsOptions;\n } & Pick<UseTextEditorProps, 'initialValue' | 'extensions' | 'scrollTo' | 'selection'>\n>;\n\nexport const TypescriptEditor = composable<HTMLDivElement, TypescriptEditorProps>(\n (\n {\n classNames,\n id,\n role = 'article',\n inputMode = 'vscode',\n env,\n options,\n initialValue,\n extensions,\n scrollTo,\n selection,\n ...props\n },\n forwardedRef,\n ) => {\n const { themeMode } = useThemeContext();\n const { parentRef, focusAttributes } = useTextEditor(\n () => ({\n id,\n initialValue,\n selection,\n scrollTo,\n extensions: [\n extensions,\n createThemeExtensions({\n monospace: true,\n themeMode,\n syntaxHighlighting: true,\n }),\n createBasicExtensions({\n highlightActiveLine: true,\n indentWithTab: true,\n lineNumbers: true,\n lineWrapping: false,\n scrollPastEnd: role === 'article',\n search: true,\n ...options,\n }),\n\n InputModeExtensions[inputMode],\n javascript({ typescript: true }),\n autocompletion({ override: env ? [tsAutocomplete()] : undefined }),\n\n // Continues block comments when pressing Enter.\n Prec.high(keymap.of(continueKeymap)),\n keymap.of(completionKeymap),\n keymap.of(lintKeymap),\n\n // https://github.com/val-town/codemirror-ts\n env && [\n // TODO(burdon): Fix type.\n tsFacet.of({ env: env as any, path: `./src/${id}.ts` }),\n tsSync(),\n tsLinter(),\n tsHover({ renderTooltip: createTooltipRenderer(themeMode) }),\n ],\n ].filter(isNonNullable),\n }),\n [themeMode, id, extensions, inputMode, selection, scrollTo, env],\n );\n\n return (\n <div {...composableProps(props, { classNames, ...focusAttributes })} ref={composeRefs(parentRef, forwardedRef)} />\n );\n },\n);\n\n// TODO(burdon): Factor out (react-ui-editor).\nconst createTooltipRenderer = (themeMode: ThemeMode) => {\n const theme = HighlightStyle.define(themeMode === 'dark' ? defaultStyles.dark : defaultStyles.light);\n\n const classFromKind = (_kind: string) => {\n // E.g., localName, methodName, parameterName, etc.\n const kind = _kind.endsWith('Name') ? 'name' : _kind;\n const validTag = kind in tags;\n if (!validTag) {\n return '';\n }\n\n const tag = tags[kind as keyof typeof tags];\n if (typeof tag === 'function') {\n return '';\n }\n\n return theme.style([tag]) ?? '';\n };\n\n return (info: HoverInfo) => {\n const children =\n info.quickInfo?.displayParts?.map(({ kind, text }) =>\n Domino.of('span').classNames(classFromKind(kind)).text(text),\n ) ?? [];\n return {\n dom: Domino.of('div')\n .classNames('xs:max-w-80 max-w-lg p-1 dx-base-surface rounded-sm border border-separator')\n .append(...children).root,\n };\n };\n};\n\nexport default TypescriptEditor;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useMemo } from 'react';\n\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { type Database, Obj } from '@dxos/echo';\nimport { Doc } from '@dxos/echo-doc';\nimport { invariant } from '@dxos/invariant';\nimport { TemplateEditor } from '@dxos/plugin-routine/components';\nimport { useThemeContext, useTranslation } from '@dxos/react-ui';\nimport { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';\nimport { Editor, type EditorViewProps } from '@dxos/react-ui-editor';\nimport {\n type BasicExtensionsOptions,\n createBasicExtensions,\n createDataExtensions,\n createMarkdownExtensions,\n createThemeExtensions,\n decorateMarkdown,\n} from '@dxos/ui-editor';\nimport { mx } from '@dxos/ui-theme';\nimport { isNonNullable } from '@dxos/util';\n\nimport { meta } from '#meta';\nimport { Notebook } from '#types';\n\nimport { type ComputeGraph } from '../../notebook';\nimport { TypescriptEditor, type TypescriptEditorProps } from '../TypescriptEditor';\nimport { type NotebookMenuProps } from './NotebookMenu';\n\nconst editorStyles = 'p-2 ps-3';\nconst valueStyles = 'p-1 ps-3';\n\nexport type NotebookCellProps = {\n db?: Database.Database;\n graph?: ComputeGraph;\n dragging?: boolean;\n cell: Notebook.Cell;\n promptResults?: Record<string, string>;\n} & (Pick<NotebookMenuProps, 'onCellInsert' | 'onCellDelete'> & Pick<TypescriptEditorProps, 'env'>);\n\n// TODO(burdon): Show evaluation errors.\nexport const NotebookCell = ({ db, graph, dragging, cell, promptResults, env }: NotebookCellProps) => {\n const { t } = useTranslation(meta.profile.key);\n\n const extensions = useMemo(() => {\n return cell.source?.target\n ? [createDataExtensions({ id: cell.id, text: Doc.createAccessor(cell.source.target, ['content']) })]\n : [];\n }, [cell.source?.target]);\n\n const explorerGraph = cell.graph?.target;\n\n const handleQueryChange = useCallback<NonNullable<QueryEditorProps['onChange']>>(\n (value: string) => {\n invariant(cell.source?.target);\n Obj.update(cell.source.target, (obj) => {\n obj.content = value;\n });\n },\n [cell],\n );\n\n switch (cell.type) {\n case 'markdown':\n if (!cell.source?.target) {\n return null;\n }\n\n return (\n <NotebookTextEditor\n id={cell.id}\n classNames={editorStyles}\n initialValue={cell.source.target.content}\n extensions={extensions}\n />\n );\n\n case 'script':\n if (!cell.source?.target) {\n return null;\n }\n\n return (\n <div className='flex flex-col divide-y divide-subdued-separator'>\n <TypescriptEditor\n id={cell.id}\n role='section'\n classNames={editorStyles}\n initialValue={cell.source.target.content}\n extensions={extensions}\n env={env}\n options={{\n placeholder: t('notebook-cell.placeholder'),\n highlightActiveLine: false,\n lineNumbers: false,\n }}\n />\n <NotebookCellValue cell={cell} graph={graph} />\n </div>\n );\n\n case 'query':\n if (!cell.source?.target) {\n return null;\n }\n\n // TODO(burdon): Remove app-framework deps (via render prop).\n return (\n <div className={mx('h-full overflow-hidden grid', explorerGraph && !dragging && 'grid-rows-[min-content_1fr]')}>\n <QueryEditor\n id={cell.id}\n classNames={editorStyles}\n db={db}\n value={cell.source.target.content}\n onChange={handleQueryChange}\n />\n {explorerGraph && !dragging && (\n <Surface.Surface\n type={AppSurface.Section}\n limit={1}\n data={{ subject: explorerGraph, attendableId: cell.id }}\n />\n )}\n </div>\n );\n\n // TODO(burdon): Use streaming response from Chat.\n case 'prompt':\n if (!cell.prompt?.target) {\n return null;\n }\n\n return (\n <>\n <TemplateEditor id={cell.id} source={cell.prompt.target.text} lineNumbers={false} classNames={editorStyles} />\n <NotebookPromptResult cell={cell} promptResults={promptResults} />\n </>\n );\n\n default:\n return null;\n }\n};\n\nconst NotebookCellValue = ({ cell, graph }: NotebookCellProps) => {\n const name = graph?.getExpressions()[cell.id]?.name;\n const value = graph?.getValue(cell.id);\n if (value == null) {\n return null;\n }\n\n return (\n <div className={mx('flex w-full bg-group-surface text-description font-mono', valueStyles)}>\n {name && (\n <>\n <span className='text-success-text'>{name}</span>\n <span className='text-description'> = </span>\n </>\n )}\n <span>{value}</span>\n </div>\n );\n};\n\nconst NotebookPromptResult = ({ cell, promptResults }: NotebookCellProps) => {\n if (!cell.prompt) {\n return null;\n }\n\n const value = promptResults?.[cell.prompt.uri];\n if (value == null) {\n return null;\n }\n\n return (\n <div className={mx('flex w-full dx-group-surface text-description border-y border-subdued-separator', valueStyles)}>\n <NotebookTextEditor readOnly value={value} />\n </div>\n );\n};\n\nconst NotebookTextEditor = ({\n classNames,\n extensions: extensionsProp,\n readOnly,\n ...props\n}: EditorViewProps & Pick<BasicExtensionsOptions, 'readOnly'>) => {\n const { t } = useTranslation(meta.profile.key);\n const { themeMode } = useThemeContext();\n const extensions = useMemo(() => {\n return [\n createThemeExtensions({ themeMode, syntaxHighlighting: true }),\n createBasicExtensions({ placeholder: t('notebook-markdown.placeholder'), readOnly }),\n createMarkdownExtensions(),\n decorateMarkdown(),\n extensionsProp,\n ].filter(isNonNullable);\n }, [extensionsProp, readOnly, themeMode, t]);\n\n return (\n <Editor.Root>\n {/* Focused-cell affordance: Editor.View no longer applies a focus border by default. */}\n <Editor.View\n {...props}\n classNames={mx('border focus-within:border-focus-ring-subtle', classNames)}\n extensions={extensions}\n selectionEnd\n />\n </Editor.Root>\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useId, useMemo, useState } from 'react';\n\nimport { Obj } from '@dxos/echo';\nimport { DropdownMenu, IconButton, ScrollArea, type ThemedClassName, useTranslation } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { type DndContainerHandler } from '@dxos/react-ui-dnd';\nimport { Mosaic, type MosaicTileProps } from '@dxos/react-ui-mosaic';\nimport { mx } from '@dxos/ui-theme';\nimport { arrayMove } from '@dxos/util';\n\nimport { meta } from '#meta';\nimport { Notebook } from '#types';\n\nimport { type TypescriptEditorProps } from '../TypescriptEditor';\nimport { NotebookCell, type NotebookCellProps } from './NotebookCell';\nimport { NotebookMenu } from './NotebookMenu';\n\nconst minSectionHeight = 'min-h-[16rem]';\n\nconst getCellId = (cell: Notebook.Cell) => cell.id;\n\nexport type NotebookStackProps = ThemedClassName<\n {\n notebook?: Notebook.Notebook;\n } & (Pick<NotebookSectionProps, 'db' | 'graph' | 'promptResults' | 'onCellInsert' | 'onCellDelete'> &\n Pick<TypescriptEditorProps, 'env'>)\n>;\n\nexport const NotebookStack = composable<HTMLDivElement, NotebookStackProps>(\n ({ notebook, db, graph, promptResults, onCellInsert, onCellDelete, env, ...props }, forwardedRef) => {\n const [viewport, setViewport] = useState<HTMLElement | null>(null);\n\n // Stable Tile identity: an inline component is a new type each render, so Mosaic would unmount and\n // remount every cell (losing editor state) whenever this component re-renders.\n const Tile = useCallback(\n (tileProps: MosaicTileProps<Notebook.Cell>) => (\n <NotebookSection\n {...tileProps}\n db={db}\n graph={graph}\n promptResults={promptResults}\n onCellInsert={onCellInsert}\n onCellDelete={onCellDelete}\n env={env}\n />\n ),\n [db, graph, promptResults, onCellInsert, onCellDelete, env],\n );\n\n // Per-instance discriminator so the same notebook opened twice doesn't collide in the Mosaic registry.\n const instanceId = useId();\n\n // Reorder cells in place; placeholder/tile locations are 1-based with half-step placeholders between\n // tiles, so the floor of the drop location is the destination array index (see Mosaic.Stack).\n const eventHandler = useMemo<DndContainerHandler<Notebook.Cell>>(\n () => ({\n id: `notebook:${notebook?.id ?? 'anon'}:${instanceId}`,\n // Only the notebook's own cells are droppable; onDrop only reorders within this notebook.\n canDrop: ({ source }) => !!notebook && notebook.cells.some((cell) => cell.id === source.id),\n onDrop: ({ source, target }) => {\n if (!notebook || !target) {\n return;\n }\n\n const to =\n target.type === 'tile' || target.type === 'placeholder'\n ? target.location\n : target.type === 'container'\n ? notebook.cells.length\n : -1;\n const insertIndex = typeof to === 'number' && to >= 0 ? Math.floor(to) : -1;\n if (insertIndex < 0) {\n return;\n }\n\n Obj.update(notebook, (notebook) => {\n const from = notebook.cells.findIndex((cell) => cell.id === source.id);\n if (from !== -1) {\n arrayMove(notebook.cells, from, insertIndex);\n }\n });\n },\n }),\n [notebook, instanceId],\n );\n\n return (\n <Mosaic.Container\n asChild\n orientation='vertical'\n autoScroll={viewport}\n eventHandler={eventHandler}\n ref={forwardedRef}\n >\n <ScrollArea.Root orientation='vertical' padding {...composableProps(props)}>\n <ScrollArea.Viewport ref={setViewport}>\n <Mosaic.Stack orientation='vertical' items={notebook?.cells ?? []} getId={getCellId} Tile={Tile} />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Mosaic.Container>\n );\n },\n);\n\ntype NotebookSectionProps = MosaicTileProps<Notebook.Cell> &\n Pick<NotebookCellProps, 'db' | 'graph' | 'promptResults' | 'onCellInsert' | 'onCellDelete' | 'env'>;\n\n// TODO(burdon): Option for narrow rail (with compact buttons that align with first button in toolbar).\n// TODO(burdon): Reinstate a Mosaic-native resize affordance for query cells (currently a fixed min-height).\nconst NotebookSection = ({\n data: cell,\n db,\n env,\n graph,\n promptResults,\n onCellInsert,\n onCellDelete,\n ...tileProps\n}: NotebookSectionProps) => {\n const { t } = useTranslation(meta.profile.key);\n const resizable = cell.type === 'query';\n const [dragHandle, setDragHandle] = useState<HTMLButtonElement | null>(null);\n\n return (\n <Mosaic.Tile\n {...tileProps}\n data={cell}\n dragHandle={dragHandle}\n classNames={mx(\n 'grid grid-cols-[min-content_1fr] overflow-visible border border-subdued-separator',\n resizable && minSectionHeight,\n )}\n >\n {/* Side rail */}\n <div className='flex flex-col p-1 border-e border-subdued-separator dx-attention-surface'>\n <IconButton\n ref={setDragHandle}\n variant='ghost'\n icon='ph--dots-six-vertical--regular'\n iconOnly\n label='Drag handle'\n />\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <IconButton\n variant='ghost'\n icon='ph--dots-three--regular'\n iconOnly\n label={t('notebook-cell-insert.label')}\n />\n </DropdownMenu.Trigger>\n <NotebookMenu cell={cell} onCellInsert={onCellInsert} onCellDelete={onCellDelete} />\n </DropdownMenu.Root>\n </div>\n\n <NotebookCell db={db} cell={cell} env={env} graph={graph} promptResults={promptResults} />\n </Mosaic.Tile>\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { ModuleResolutionKind, ScriptTarget } from '@typescript/typescript6';\nimport React, { useState } from 'react';\n\n// TODO(burdon): Document.\nimport queryApi from '@dxos/echo-query/api.d.ts?raw';\nimport { useAsyncEffect } from '@dxos/react-ui';\n\nimport { Compiler } from '../../compiler';\nimport { TypescriptEditor, type TypescriptEditorProps } from '../TypescriptEditor';\n\nconst GLOBALS = `\n namespace QueryAPI {\n ${queryApi}\n }\n\n declare global {\n const Query: typeof QueryAPI.Query;\n const Filter: typeof QueryAPI.Filter;\n const Order: typeof QueryAPI.Order;\n }\n\n export {};\n`;\n\nexport type QueryEditorProps = Omit<TypescriptEditorProps, 'env'>;\n\nexport const QueryEditor = (props: QueryEditorProps) => {\n const [compiler, setCompiler] = useState<Compiler>();\n\n useAsyncEffect(async () => {\n const compiler = new Compiler({\n lib: ['ES5'],\n target: ScriptTarget.ES2022,\n // Avoid `@typescript/vfs`'s deprecated `node10` default (rejected by TS 6).\n moduleResolution: ModuleResolutionKind.Bundler,\n });\n await compiler.initialize(GLOBALS);\n setCompiler(compiler);\n }, []);\n\n if (!compiler) {\n return null;\n }\n\n return <TypescriptEditor {...props} env={compiler.environment} />;\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Atom from 'effect/unstable/reactivity/Atom';\nimport React, { useMemo } from 'react';\n\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport type * as Script from '@dxos/compute/Script';\nimport { ElevationProvider, useTranslation } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { type ActionGraphProps, Menu, MenuRootProps, createGapSeparator, useMenuActions } from '@dxos/react-ui-menu';\n\nimport {\n type CreateDeployOptions,\n type ScriptToolbarStateStore,\n createDeploy,\n createFormat,\n createTemplateSelect,\n useDeployDeps,\n} from '#hooks';\nimport { meta } from '#meta';\n\nexport type ScriptToolbarProps = Pick<MenuRootProps, 'attendableId'> & {\n script: Script.Script;\n state: ScriptToolbarStateStore;\n};\n\nexport const ScriptToolbar = composable<HTMLDivElement, ScriptToolbarProps>(\n ({ script, attendableId, role, state, ...props }, forwardedRef) => {\n const { t } = useTranslation(meta.profile.key);\n const options = useDeployDeps({ script });\n const menuCreator = useMemo(\n () => createToolbarActions({ state, script, t, ...options }),\n [state, script, options, t],\n );\n const menuActions = useMenuActions(menuCreator);\n\n return (\n <ElevationProvider elevation={role === AppSurface.Section.role ? 'positioned' : 'base'}>\n <Menu.Root {...menuActions} attendableId={attendableId}>\n <Menu.Toolbar {...composableProps(props)} ref={forwardedRef}>\n <Menu.Items />\n </Menu.Toolbar>\n </Menu.Root>\n </ElevationProvider>\n );\n },\n);\n\nconst createToolbarActions = ({ state, script, ...options }: CreateDeployOptions): Atom.Atom<ActionGraphProps> =>\n Atom.make((get) => {\n // Subscribe to state changes.\n get(state.atom);\n const templateSelect = createTemplateSelect(script);\n const format = createFormat(script);\n const gap = createGapSeparator();\n const deploy = createDeploy({ state, script, ...options });\n return {\n nodes: [...templateSelect.nodes, ...format.nodes, ...gap.nodes, ...deploy.nodes],\n edges: [...templateSelect.edges, ...format.edges, ...gap.edges, ...deploy.edges],\n };\n });\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useRef, useState } from 'react';\n\nimport { log } from '@dxos/log';\nimport { Avatar, Icon, Input, ScrollArea, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';\nimport { mx } from '@dxos/ui-theme';\n\nimport { meta } from '#meta';\n\ntype State = 'pending';\n\n/**\n * Request or response.\n */\ntype Message = {\n type: 'request' | 'response';\n text?: string;\n data?: any;\n error?: Error;\n};\n\nexport type TestPanelProps = ThemedClassName<{\n onInvoke?: (input: unknown) => Promise<unknown>;\n}>;\n\n// TODO(burdon): Need persistent history (currently lost when switching tabs).\nexport const TestPanel = composable<HTMLDivElement, TestPanelProps>(\n ({ classNames, onInvoke, ...props }, forwardedRef) => {\n const { t } = useTranslation(meta.profile.key);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [input, setInput] = useState('');\n const [state, setState] = useState<State | null>(null);\n\n // TODO(burdon): Persistent history (thread).\n const [history, setHistory] = useState<Message[]>([]);\n\n const scrollerRef = useRef<HTMLDivElement>(null);\n const handleScroll = () => {\n if (scrollerRef.current) {\n scrollerRef.current.scrollTop = scrollerRef.current.scrollHeight;\n }\n };\n\n const handleClear = () => {\n setInput('');\n setHistory([]);\n inputRef.current?.focus();\n };\n\n const handleResponse = ({\n text,\n data,\n error,\n }: {\n text?: string;\n data?: any;\n error?: Error;\n } = {}) => {\n setHistory((history) => [...history, { type: 'response', text, data, error } satisfies Message]);\n setState(null);\n handleScroll();\n };\n\n const handleRequest = async (input: string) => {\n if (!onInvoke) {\n handleResponse({ error: new Error('Function not deployed') });\n return;\n }\n\n let data: unknown = input;\n let displayText = input;\n if (input.charAt(0) === '{') {\n try {\n const validJsonString = input.replace(/'/g, '\"').replace(/([{,]\\s*)([a-zA-Z0-9_]+)(\\s*:)/g, '$1\"$2\"$3');\n data = JSON.parse(validJsonString);\n displayText = JSON.stringify(data, null, 2);\n } catch (err) {\n handleResponse({ error: new Error('Invalid JSON input') });\n return;\n }\n }\n\n try {\n setState('pending');\n setInput('');\n setHistory((history) => [...history, { type: 'request', text: displayText }]);\n setTimeout(handleScroll);\n\n const result = await onInvoke(data);\n\n if (typeof result === 'string') {\n handleResponse({ text: result });\n } else {\n handleResponse({ data: result });\n }\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error(String(err));\n handleResponse({ error });\n log.catch(err);\n }\n };\n\n return (\n <div\n {...composableProps(props, { classNames: ['flex flex-col h-full overflow-hidden', classNames] })}\n ref={forwardedRef}\n >\n {/* TODO(burdon): Replace with Thread. */}\n <MessageThread ref={scrollerRef} state={state} history={history} />\n {/* TODO(burdon): Replace with Form based on the function's input schema. */}\n <Toolbar.Root>\n <Input.Root>\n <Input.TextInput\n ref={inputRef}\n autoFocus\n placeholder={t('function-request.placeholder')}\n value={input}\n onChange={(ev) => setInput(ev.target.value)}\n onKeyDown={(ev) => ev.key === 'Enter' && handleRequest(input)}\n />\n </Input.Root>\n <Toolbar.IconButton icon='ph--play--regular' label='Execute' iconOnly onClick={() => handleRequest(input)} />\n <Toolbar.IconButton icon='ph--trash--regular' label='Clear' iconOnly onClick={handleClear} />\n </Toolbar.Root>\n </div>\n );\n },\n);\n\n// TODO(burdon): Replace with thread?\n// TODO(burdon): Button to edit/re-run question.\ntype MessageThreadProps = {\n state: State | null;\n history: Message[];\n};\n\nconst MessageThread = forwardRef<HTMLDivElement, MessageThreadProps>(\n ({ state, history }: MessageThreadProps, forwardedRef) => {\n return (\n <ScrollArea.Root orientation='vertical' classNames='h-full' ref={forwardedRef}>\n <ScrollArea.Viewport classNames='gap-6 p-2'>\n {history.map((message, i) => (\n <div key={i} className='grid grid-cols-[var(--dx-rail-item)_1fr_var(--dx-rail-item)]'>\n <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>\n <div className='overflow-auto'>\n <MessageItem message={message} />\n </div>\n </div>\n ))}\n\n {state === 'pending' && (\n <div className='grid grid-cols-[var(--dx-rail-item)_1fr_var(--dx-rail-item)]'>\n <div className='p-1'>\n <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin' />\n </div>\n </div>\n )}\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n );\n },\n);\n\nconst MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message }>) => {\n const { type, text, data, error } = message;\n const wrapper = 'p-1 px-2 rounded-md bg-hover-surface overflow-auto';\n return (\n <div className={mx('flex', type === 'request' ? 'ml-[1rem] justify-end' : 'mr-[1rem]', classNames)}>\n {error && <div className={mx(wrapper, 'whitespace-pre text-error-text')}>{String(error)}</div>}\n\n {text !== undefined && (\n <div className={mx(wrapper, type === 'request' && 'bg-primary-500 dark:bg-primary-600')}>\n {text || '\\u00D8'}\n </div>\n )}\n\n {data && <JsonHighlighter data={data} classNames={mx(wrapper, 'text-xs')} />}\n </div>\n );\n};\n\nconst RobotAvatar = () => (\n <Avatar.Root>\n <Avatar.Content size={6} variant='circle' icon='ph--drone--regular' />\n </Avatar.Root>\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"components.mjs","names":[],"sources":["../../src/components/NotebookStack/NotebookMenu.tsx","../../src/components/TypescriptEditor/TypescriptEditor.tsx","../../src/components/NotebookStack/NotebookCell.tsx","../../src/components/NotebookStack/NotebookStack.tsx","../../src/components/ScriptToolbar/ScriptToolbar.tsx","../../src/components/TestPanel/TestPanel.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Menu from '@dxos/react-ui/Menu';\n\nimport { meta } from '#meta';\nimport { Notebook } from '#types';\n\nexport type NotebookMenuProps = {\n cell?: Notebook.Cell;\n onCellInsert?: (type: Notebook.CellType, after: string | undefined) => void;\n onCellDelete?: (id: string) => void;\n};\n\n// TODO(burdon): Better way to organize menu?\nexport const NotebookMenu = ({ cell, onCellInsert, onCellDelete }: NotebookMenuProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return (\n <Menu.Content>\n <Menu.Item\n onClick={() => onCellInsert?.('script', cell?.id)}\n item={{ value: t('notebook-cell-insert-script.label'), label: t('notebook-cell-insert-script.label') }}\n />\n <Menu.Item\n onClick={() => onCellInsert?.('prompt', cell?.id)}\n item={{ value: t('notebook-cell-insert-prompt.label'), label: t('notebook-cell-insert-prompt.label') }}\n />\n <Menu.Item\n onClick={() => onCellInsert?.('query', cell?.id)}\n item={{ value: t('notebook-cell-insert-query.label'), label: t('notebook-cell-insert-query.label') }}\n />\n <Menu.Item\n onClick={() => onCellInsert?.('markdown', cell?.id)}\n item={{ value: t('notebook-cell-insert-markdown.label'), label: t('notebook-cell-insert-markdown.label') }}\n />\n {cell && onCellDelete && (\n <Menu.Item\n onClick={() => onCellDelete?.(cell.id)}\n item={{ value: t('notebook-cell-delete.label'), label: t('notebook-cell-delete.label') }}\n />\n )}\n </Menu.Content>\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { autocompletion, completionKeymap } from '@codemirror/autocomplete';\nimport { javascript } from '@codemirror/lang-javascript';\nimport { HighlightStyle } from '@codemirror/language';\nimport { lintKeymap } from '@codemirror/lint';\nimport { Prec } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport { tags } from '@lezer/highlight';\nimport { type VirtualTypeScriptEnvironment } from '@typescript/vfs';\nimport { continueKeymap } from '@valtown/codemirror-continue';\nimport { type HoverInfo, tsAutocomplete, tsFacet, tsHover, tsLinter, tsSync } from '@valtown/codemirror-ts';\nimport React from 'react';\n\nimport { composeRefs } from '@dxos/react-hooks';\nimport { type UseTextEditorProps, useTextEditor } from '@dxos/react-ui-editor';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Util from '@dxos/react-ui/Util';\nimport { Domino } from '@dxos/ui';\nimport {\n type BasicExtensionsOptions,\n InputModeExtensions,\n createBasicExtensions,\n createThemeExtensions,\n defaultStyles,\n} from '@dxos/ui-editor';\nimport { type EditorInputMode } from '@dxos/ui-editor/types';\nimport { type ThemeMode } from '@dxos/ui-types';\nimport { isNonNullable } from '@dxos/util';\n\nexport type TypescriptEditorProps = Util.ThemedClassName<\n {\n id: string;\n role?: string;\n inputMode?: EditorInputMode;\n toolbar?: boolean;\n env?: VirtualTypeScriptEnvironment;\n options?: BasicExtensionsOptions;\n } & Pick<UseTextEditorProps, 'initialValue' | 'extensions' | 'scrollTo' | 'selection'>\n>;\n\nexport const TypescriptEditor = Util.composable<HTMLDivElement, TypescriptEditorProps>(\n (\n {\n classNames,\n id,\n role = 'article',\n inputMode = 'vscode',\n env,\n options,\n initialValue,\n extensions,\n scrollTo,\n selection,\n ...props\n },\n forwardedRef,\n ) => {\n const themeMode = Hooks.useThemeMode();\n const { parentRef, focusAttributes } = useTextEditor(\n () => ({\n id,\n initialValue,\n selection,\n scrollTo,\n extensions: [\n extensions,\n createThemeExtensions({\n monospace: true,\n themeMode,\n syntaxHighlighting: true,\n }),\n createBasicExtensions({\n highlightActiveLine: true,\n indentWithTab: true,\n lineNumbers: true,\n lineWrapping: false,\n scrollPastEnd: role === 'article',\n search: true,\n ...options,\n }),\n\n InputModeExtensions[inputMode],\n javascript({ typescript: true }),\n autocompletion({ override: env ? [tsAutocomplete()] : undefined }),\n\n // Continues block comments when pressing Enter.\n Prec.high(keymap.of(continueKeymap)),\n keymap.of(completionKeymap),\n keymap.of(lintKeymap),\n\n // https://github.com/val-town/codemirror-ts\n env && [\n // TODO(burdon): Fix type.\n tsFacet.of({ env: env as any, path: `./src/${id}.ts` }),\n tsSync(),\n tsLinter(),\n tsHover({ renderTooltip: createTooltipRenderer(themeMode) }),\n ],\n ].filter(isNonNullable),\n }),\n [themeMode, id, extensions, inputMode, selection, scrollTo, env],\n );\n\n return (\n <div\n {...Util.composableProps(props, { classNames, ...focusAttributes })}\n ref={composeRefs(parentRef, forwardedRef)}\n />\n );\n },\n);\n\n// TODO(burdon): Factor out (react-ui-editor).\nconst createTooltipRenderer = (themeMode: ThemeMode) => {\n const theme = HighlightStyle.define(themeMode === 'dark' ? defaultStyles.dark : defaultStyles.light);\n\n const classFromKind = (_kind: string) => {\n // E.g., localName, methodName, parameterName, etc.\n const kind = _kind.endsWith('Name') ? 'name' : _kind;\n const validTag = kind in tags;\n if (!validTag) {\n return '';\n }\n\n const tag = tags[kind as keyof typeof tags];\n if (typeof tag === 'function') {\n return '';\n }\n\n return theme.style([tag]) ?? '';\n };\n\n return (info: HoverInfo) => {\n const children =\n info.quickInfo?.displayParts?.map(({ kind, text }) =>\n Domino.of('span').classNames(classFromKind(kind)).text(text),\n ) ?? [];\n return {\n dom: Domino.of('div')\n .classNames('xs:max-w-80 max-w-lg p-1 dx-base-surface rounded-sm border border-separator')\n .append(...children).root,\n };\n };\n};\n\nexport default TypescriptEditor;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useMemo } from 'react';\n\nimport * as Surface from '@dxos/app-framework/Surface';\nimport * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport { type Database, Obj } from '@dxos/echo';\nimport { Doc } from '@dxos/echo-doc';\nimport { useResolveRef } from '@dxos/echo-react';\nimport { invariant } from '@dxos/invariant';\nimport * as TemplateEditor from '@dxos/plugin-routine/TemplateEditor';\nimport { Editor, type EditorViewProps } from '@dxos/react-ui-editor';\nimport { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-query';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport {\n type BasicExtensionsOptions,\n createBasicExtensions,\n createDataExtensions,\n createMarkdownExtensions,\n createThemeExtensions,\n decorateMarkdown,\n} from '@dxos/ui-editor';\nimport { mx } from '@dxos/ui-theme';\nimport { isNonNullable } from '@dxos/util';\n\nimport { meta } from '#meta';\nimport { Notebook } from '#types';\n\nimport { type ComputeGraph } from '../../notebook/index.ts';\nimport { TypescriptEditor, type TypescriptEditorProps } from '../TypescriptEditor/index.ts';\nimport { type NotebookMenuProps } from './NotebookMenu.tsx';\n\nconst editorStyles = 'p-2 ps-3';\nconst valueStyles = 'p-1 ps-3';\n\nexport type NotebookCellProps = {\n db?: Database.Database;\n graph?: ComputeGraph;\n dragging?: boolean;\n cell: Notebook.Cell;\n promptResults?: Record<string, string>;\n} & (Pick<NotebookMenuProps, 'onCellInsert' | 'onCellDelete'> & Pick<TypescriptEditorProps, 'env'>);\n\n// TODO(burdon): Show evaluation errors.\nexport const NotebookCell = ({ db, graph, dragging, cell, promptResults, env }: NotebookCellProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n const source = useResolveRef(cell.source);\n const prompt = useResolveRef(cell.prompt);\n const explorerGraph = useResolveRef(cell.graph);\n\n const extensions = useMemo(() => {\n return source ? [createDataExtensions({ id: cell.id, text: Doc.createAccessor(source, ['content']) })] : [];\n }, [source]);\n\n const handleQueryChange = useCallback<NonNullable<QueryEditorProps['onChange']>>(\n (value: string) => {\n invariant(cell.source?.target);\n Obj.update(cell.source.target, (obj) => {\n obj.content = value;\n });\n },\n [cell],\n );\n\n switch (cell.type) {\n case 'markdown':\n if (!source) {\n return null;\n }\n\n return (\n <NotebookTextEditor\n id={cell.id}\n classNames={editorStyles}\n initialValue={source.content}\n extensions={extensions}\n />\n );\n\n case 'script':\n if (!source) {\n return null;\n }\n\n return (\n <div className='flex flex-col divide-y divide-separator-subtle'>\n <TypescriptEditor\n id={cell.id}\n role='section'\n classNames={editorStyles}\n initialValue={source.content}\n extensions={extensions}\n env={env}\n options={{\n placeholder: t('notebook-cell.placeholder'),\n highlightActiveLine: false,\n lineNumbers: false,\n }}\n />\n <NotebookCellValue cell={cell} graph={graph} />\n </div>\n );\n\n case 'query':\n if (!source) {\n return null;\n }\n\n // TODO(burdon): Remove app-framework deps (via render prop).\n return (\n <div className={mx('h-full overflow-hidden grid', explorerGraph && !dragging && 'grid-rows-[min-content_1fr]')}>\n <QueryEditor\n id={cell.id}\n classNames={editorStyles}\n db={db}\n value={source.content}\n onChange={handleQueryChange}\n />\n {explorerGraph && !dragging && (\n <Surface.Surface\n type={AppSurface.Section}\n limit={1}\n data={{ subject: explorerGraph, attendableId: cell.id }}\n />\n )}\n </div>\n );\n\n // TODO(burdon): Use streaming response from Chat.\n case 'prompt':\n if (!prompt) {\n return null;\n }\n\n return (\n <>\n <TemplateEditor.TemplateEditor\n id={cell.id}\n source={prompt.text}\n lineNumbers={false}\n classNames={editorStyles}\n />\n <NotebookPromptResult cell={cell} promptResults={promptResults} />\n </>\n );\n\n default:\n return null;\n }\n};\n\nconst NotebookCellValue = ({ cell, graph }: NotebookCellProps) => {\n const name = graph?.getExpressions()[cell.id]?.name;\n const value = graph?.getValue(cell.id);\n if (value == null) {\n return null;\n }\n\n return (\n <div className={mx('flex w-full bg-group-surface text-fg-muted font-mono', valueStyles)}>\n {name && (\n <>\n <span className='text-success-text'>{name}</span>\n <span className='text-fg-muted'> = </span>\n </>\n )}\n <span>{value}</span>\n </div>\n );\n};\n\nconst NotebookPromptResult = ({ cell, promptResults }: NotebookCellProps) => {\n if (!cell.prompt) {\n return null;\n }\n\n const value = promptResults?.[cell.prompt.uri];\n if (value == null) {\n return null;\n }\n\n return (\n <div className={mx('flex w-full dx-group-surface text-fg-muted border-y border-separator-subtle', valueStyles)}>\n <NotebookTextEditor readOnly value={value} />\n </div>\n );\n};\n\nconst NotebookTextEditor = ({\n classNames,\n extensions: extensionsProp,\n readOnly,\n ...props\n}: EditorViewProps & Pick<BasicExtensionsOptions, 'readOnly'>) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const themeMode = Hooks.useThemeMode();\n const extensions = useMemo(() => {\n return [\n createThemeExtensions({ themeMode, syntaxHighlighting: true }),\n createBasicExtensions({ placeholder: t('notebook-markdown.placeholder'), readOnly }),\n createMarkdownExtensions(),\n decorateMarkdown(),\n extensionsProp,\n ].filter(isNonNullable);\n }, [extensionsProp, readOnly, themeMode, t]);\n\n return (\n <Editor.Root>\n {/* Focused-cell affordance: Editor.View no longer applies a focus border by default. */}\n <Editor.View\n {...props}\n classNames={mx('border focus-within:border-focus-ring-subtle', classNames)}\n extensions={extensions}\n selectionEnd\n />\n </Editor.Root>\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useId, useMemo, useState } from 'react';\n\nimport { Obj } from '@dxos/echo';\nimport { type DndContainerHandler } from '@dxos/react-ui-dnd';\nimport { Mosaic, type MosaicTileProps } from '@dxos/react-ui-mosaic';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Menu from '@dxos/react-ui/Menu';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as Util from '@dxos/react-ui/Util';\nimport { mx } from '@dxos/ui-theme';\nimport { arrayMove } from '@dxos/util';\n\nimport { meta } from '#meta';\nimport { Notebook } from '#types';\n\nimport { type TypescriptEditorProps } from '../TypescriptEditor/index.ts';\nimport { NotebookCell, type NotebookCellProps } from './NotebookCell.tsx';\nimport { NotebookMenu } from './NotebookMenu.tsx';\n\nconst minSectionHeight = 'min-h-[16rem]';\n\nconst getCellId = (cell: Notebook.Cell) => cell.id;\n\nexport type NotebookStackProps = Util.ThemedClassName<\n {\n notebook?: Notebook.Notebook;\n } & (Pick<NotebookSectionProps, 'db' | 'graph' | 'promptResults' | 'onCellInsert' | 'onCellDelete'> &\n Pick<TypescriptEditorProps, 'env'>)\n>;\n\nexport const NotebookStack = Util.composable<HTMLDivElement, NotebookStackProps>(\n ({ notebook, db, graph, promptResults, onCellInsert, onCellDelete, env, ...props }, forwardedRef) => {\n const [viewport, setViewport] = useState<HTMLElement | null>(null);\n\n // Stable Tile identity: an inline component is a new type each render, so Mosaic would unmount and\n // remount every cell (losing editor state) whenever this component re-renders.\n const Tile = useCallback(\n (tileProps: MosaicTileProps<Notebook.Cell>) => (\n <NotebookSection\n {...tileProps}\n db={db}\n graph={graph}\n promptResults={promptResults}\n onCellInsert={onCellInsert}\n onCellDelete={onCellDelete}\n env={env}\n />\n ),\n [db, graph, promptResults, onCellInsert, onCellDelete, env],\n );\n\n // Per-instance discriminator so the same notebook opened twice doesn't collide in the Mosaic registry.\n const instanceId = useId();\n\n // Reorder cells in place; placeholder/tile locations are 1-based with half-step placeholders between\n // tiles, so the floor of the drop location is the destination array index (see Mosaic.Stack).\n const eventHandler = useMemo<DndContainerHandler<Notebook.Cell>>(\n () => ({\n id: `notebook:${notebook?.id ?? 'anon'}:${instanceId}`,\n // Only the notebook's own cells are droppable; onDrop only reorders within this notebook.\n canDrop: ({ source }) => !!notebook && notebook.cells.some((cell) => cell.id === source.id),\n onDrop: ({ source, target }) => {\n if (!notebook || !target) {\n return;\n }\n\n const to =\n target.type === 'tile' || target.type === 'placeholder'\n ? target.location\n : target.type === 'container'\n ? notebook.cells.length\n : -1;\n const insertIndex = typeof to === 'number' && to >= 0 ? Math.floor(to) : -1;\n if (insertIndex < 0) {\n return;\n }\n\n Obj.update(notebook, (notebook) => {\n const from = notebook.cells.findIndex((cell) => cell.id === source.id);\n if (from !== -1) {\n arrayMove(notebook.cells, from, insertIndex);\n }\n });\n },\n }),\n [notebook, instanceId],\n );\n\n return (\n <Mosaic.Container\n asChild\n orientation='vertical'\n autoScroll={viewport}\n eventHandler={eventHandler}\n ref={forwardedRef}\n >\n <ScrollArea.Root orientation='vertical' {...Util.composableProps(props)}>\n <ScrollArea.Viewport ref={setViewport}>\n <Mosaic.Stack orientation='vertical' items={notebook?.cells ?? []} getId={getCellId} Tile={Tile} />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Mosaic.Container>\n );\n },\n);\n\ntype NotebookSectionProps = MosaicTileProps<Notebook.Cell> &\n Pick<NotebookCellProps, 'db' | 'graph' | 'promptResults' | 'onCellInsert' | 'onCellDelete' | 'env'>;\n\n// TODO(burdon): Option for narrow rail (with compact buttons that align with first button in toolbar).\n// TODO(burdon): Reinstate a Mosaic-native resize affordance for query cells (currently a fixed min-height).\nconst NotebookSection = ({\n data: cell,\n db,\n env,\n graph,\n promptResults,\n onCellInsert,\n onCellDelete,\n ...tileProps\n}: NotebookSectionProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const resizable = cell.type === 'query';\n const [dragHandle, setDragHandle] = useState<HTMLButtonElement | null>(null);\n\n return (\n <Mosaic.Tile\n {...tileProps}\n data={cell}\n dragHandle={dragHandle}\n classNames={mx(\n 'grid grid-cols-[min-content_1fr] overflow-visible border border-separator-subtle',\n resizable && minSectionHeight,\n )}\n >\n {/* Side rail */}\n <div className='flex flex-col p-1 border-e border-separator-subtle dx-attention-surface'>\n <Button.Root\n ref={setDragHandle}\n variant='ghost'\n icon='ph--dots-six-vertical--regular'\n iconOnly\n label='Drag handle'\n />\n <Menu.Root>\n <Menu.Trigger asChild>\n <Button.Root\n variant='ghost'\n icon='ph--dots-three--regular'\n iconOnly\n label={t('notebook-cell-insert.label')}\n />\n </Menu.Trigger>\n <NotebookMenu cell={cell} onCellInsert={onCellInsert} onCellDelete={onCellDelete} />\n </Menu.Root>\n </div>\n\n <NotebookCell db={db} cell={cell} env={env} graph={graph} promptResults={promptResults} />\n </Mosaic.Tile>\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Atom from 'effect/reactivity/Atom';\nimport React, { useMemo } from 'react';\n\nimport type * as Script from '@dxos/compute/Script';\nimport {\n type ActionGraphProps,\n ActionToolbar,\n type ActionToolbarProps,\n createGapSeparator,\n useMenuActions,\n} from '@dxos/react-ui-menu';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport {\n type CreateDeployOptions,\n type ScriptToolbarStateStore,\n createDeploy,\n createFormat,\n createTemplateSelect,\n useDeployDeps,\n} from '#hooks';\nimport { meta } from '#meta';\n\nexport type ScriptToolbarProps = Pick<ActionToolbarProps, 'attendableId'> & {\n script: Script.Script;\n state: ScriptToolbarStateStore;\n};\n\nexport const ScriptToolbar = Util.composable<HTMLDivElement, ScriptToolbarProps>(\n ({ script, attendableId, role, state, ...props }, forwardedRef) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const options = useDeployDeps({ script });\n const menuCreator = useMemo(\n () => createToolbarActions({ state, script, t, ...options }),\n [state, script, options, t],\n );\n const menuActions = useMenuActions(menuCreator);\n\n return (\n <ActionToolbar {...menuActions} attendableId={attendableId} {...Util.composableProps(props)} ref={forwardedRef} />\n );\n },\n);\n\nconst createToolbarActions = ({ state, script, ...options }: CreateDeployOptions): Atom.Atom<ActionGraphProps> =>\n Atom.make((get) => {\n // Subscribe to state changes.\n get(state.atom);\n const templateSelect = createTemplateSelect(script);\n const format = createFormat(script);\n const gap = createGapSeparator();\n const deploy = createDeploy({ state, script, ...options });\n return {\n nodes: [...templateSelect.nodes, ...format.nodes, ...gap.nodes, ...deploy.nodes],\n edges: [...templateSelect.edges, ...format.edges, ...gap.edges, ...deploy.edges],\n };\n });\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useRef, useState } from 'react';\n\nimport { log } from '@dxos/log';\nimport { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';\nimport * as Avatar from '@dxos/react-ui/Avatar';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as Toolbar from '@dxos/react-ui/Toolbar';\nimport * as Util from '@dxos/react-ui/Util';\nimport { mx } from '@dxos/ui-theme';\n\nimport { meta } from '#meta';\n\ntype State = 'pending';\n\n/**\n * Request or response.\n */\ntype Message = {\n type: 'request' | 'response';\n text?: string;\n data?: any;\n error?: Error;\n};\n\nexport type TestPanelProps = Util.ThemedClassName<{\n onInvoke?: (input: unknown) => Promise<unknown>;\n}>;\n\n// TODO(burdon): Need persistent history (currently lost when switching tabs).\nexport const TestPanel = Util.composable<HTMLDivElement, TestPanelProps>(\n ({ classNames, onInvoke, ...props }, forwardedRef) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [input, setInput] = useState('');\n const [state, setState] = useState<State | null>(null);\n\n // TODO(burdon): Persistent history (thread).\n const [history, setHistory] = useState<Message[]>([]);\n\n const scrollerRef = useRef<HTMLDivElement>(null);\n const handleScroll = () => {\n if (scrollerRef.current) {\n scrollerRef.current.scrollTop = scrollerRef.current.scrollHeight;\n }\n };\n\n const handleClear = () => {\n setInput('');\n setHistory([]);\n inputRef.current?.focus();\n };\n\n const handleResponse = ({\n text,\n data,\n error,\n }: {\n text?: string;\n data?: any;\n error?: Error;\n } = {}) => {\n setHistory((history) => [...history, { type: 'response', text, data, error } satisfies Message]);\n setState(null);\n handleScroll();\n };\n\n const handleRequest = async (input: string) => {\n if (!onInvoke) {\n handleResponse({ error: new Error('Function not deployed') });\n return;\n }\n\n let data: unknown = input;\n let displayText = input;\n if (input.charAt(0) === '{') {\n try {\n const validJsonString = input.replace(/'/g, '\"').replace(/([{,]\\s*)([a-zA-Z0-9_]+)(\\s*:)/g, '$1\"$2\"$3');\n data = JSON.parse(validJsonString);\n displayText = JSON.stringify(data, null, 2);\n } catch (err) {\n handleResponse({ error: new Error('Invalid JSON input') });\n return;\n }\n }\n\n try {\n setState('pending');\n setInput('');\n setHistory((history) => [...history, { type: 'request', text: displayText }]);\n setTimeout(handleScroll);\n\n const result = await onInvoke(data);\n\n if (typeof result === 'string') {\n handleResponse({ text: result });\n } else {\n handleResponse({ data: result });\n }\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error(String(err));\n handleResponse({ error });\n log.catch(err);\n }\n };\n\n return (\n <div\n {...Util.composableProps(props, { classNames: ['flex flex-col h-full overflow-hidden', classNames] })}\n ref={forwardedRef}\n >\n {/* TODO(burdon): Replace with Thread. */}\n <MessageThread ref={scrollerRef} state={state} history={history} />\n {/* TODO(burdon): Replace with Form based on the function's input schema. */}\n <Toolbar.Root>\n <Field.Root>\n <Input.Root\n ref={inputRef}\n autoFocus\n placeholder={t('function-request.placeholder')}\n value={input}\n onChange={(ev) => setInput(ev.target.value)}\n onKeyDown={(ev) => ev.key === 'Enter' && handleRequest(input)}\n />\n </Field.Root>\n <Button.Root icon='ph--play--regular' label='Execute' iconOnly onClick={() => handleRequest(input)} />\n <Button.Root icon='ph--trash--regular' label='Clear' iconOnly onClick={handleClear} />\n </Toolbar.Root>\n </div>\n );\n },\n);\n\n// TODO(burdon): Replace with thread?\n// TODO(burdon): Button to edit/re-run question.\ntype MessageThreadProps = {\n state: State | null;\n history: Message[];\n};\n\nconst MESSAGE_COLS = ['var(--dx-rail-item)', 'fill', 'var(--dx-rail-item)'] as const;\n\nconst MessageThread = forwardRef<HTMLDivElement, MessageThreadProps>(\n ({ state, history }: MessageThreadProps, forwardedRef) => {\n return (\n <ScrollArea.Root orientation='vertical' classNames='h-full' ref={forwardedRef}>\n <ScrollArea.Viewport classNames='gap-6 p-2'>\n {history.map((message, i) => (\n <Layout.Grid key={i} cols={MESSAGE_COLS}>\n <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>\n <div className='overflow-auto'>\n <MessageItem message={message} />\n </div>\n </Layout.Grid>\n ))}\n\n {state === 'pending' && (\n <Layout.Grid cols={MESSAGE_COLS}>\n <div className='p-1'>\n <Icon.Icon icon='ph--spinner--regular' size='xl' spin />\n </div>\n </Layout.Grid>\n )}\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n );\n },\n);\n\nconst MessageItem = ({ classNames, message }: Util.ThemedClassName<{ message: Message }>) => {\n const { type, text, data, error } = message;\n const wrapper = 'p-1 px-2 rounded-md bg-hover-surface';\n return (\n <div className={mx('flex', type === 'request' ? 'ml-[1rem] justify-end' : 'mr-[1rem]', classNames)}>\n {error && <div className={mx(wrapper, 'whitespace-pre text-error-text')}>{String(error)}</div>}\n\n {text !== undefined && (\n <div className={mx(wrapper, type === 'request' && 'bg-primary-500 dark:bg-primary-600')}>\n {text || '\\u00D8'}\n </div>\n )}\n\n {data && <JsonHighlighter data={data} classNames={mx(wrapper, 'text-xs')} />}\n </div>\n );\n};\n\nconst RobotAvatar = () => <Avatar.Root size='sm' variant='circle' icon='ph--drone--regular' />;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containers.mjs","names":[],"sources":["../../src/containers/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type ComponentType, lazy } from 'react';\n\nexport const DeploymentDialog: ComponentType<any> = lazy(() => import('./DeploymentDialog'));\nexport const NotebookArticle: ComponentType<any> = lazy(() => import('./NotebookArticle'));\nexport const ScriptArticle: ComponentType<any> = lazy(() => import('./ScriptArticle'));\nexport const ScriptProperties: ComponentType<any> = lazy(() => import('./ScriptProperties'));\nexport const ScriptSettings: ComponentType<any> = lazy(() => import('./ScriptSettings'));\nexport const TestContainer: ComponentType<any> = lazy(() => import('./TestContainer'));\n"],"mappings":";;AAMA,IAAa,mBAAuC,WAAW,OAAO,+
|
|
1
|
+
{"version":3,"file":"containers.mjs","names":[],"sources":["../../src/containers/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type ComponentType, lazy } from 'react';\n\nexport const DeploymentDialog: ComponentType<any> = lazy(() => import('./DeploymentDialog/index.ts'));\nexport const NotebookArticle: ComponentType<any> = lazy(() => import('./NotebookArticle/index.ts'));\nexport const ScriptArticle: ComponentType<any> = lazy(() => import('./ScriptArticle/index.ts'));\nexport const ScriptProperties: ComponentType<any> = lazy(() => import('./ScriptProperties/index.ts'));\nexport const ScriptSettings: ComponentType<any> = lazy(() => import('./ScriptSettings/index.ts'));\nexport const TestContainer: ComponentType<any> = lazy(() => import('./TestContainer/index.ts'));\n"],"mappings":";;AAMA,IAAa,mBAAuC,WAAW,OAAO,+BAA8B;AACpG,IAAa,kBAAsC,WAAW,OAAO,8BAA6B;AAClG,IAAa,gBAAoC,WAAW,OAAO,4BAA2B;AAC9F,IAAa,mBAAuC,WAAW,OAAO,+BAA8B;AACpG,IAAa,iBAAqC,WAAW,OAAO,6BAA4B;AAChG,IAAa,gBAAoC,WAAW,OAAO,4BAA2B"}
|
package/dist/lib/hooks.mjs
CHANGED
|
@@ -1,27 +1,105 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as getFunctionUrl } from "./chunk-functions.mjs";
|
|
2
2
|
import { t as templates } from "./chunk-templates.mjs";
|
|
3
3
|
import { ScriptCapabilities, ScriptEvents, ScriptOperation } from "#types";
|
|
4
4
|
import { meta } from "#meta";
|
|
5
|
-
import * as Operation from "@dxos/compute/Operation";
|
|
6
|
-
import { Obj, Query, Ref } from "@dxos/echo";
|
|
7
5
|
import { FUNCTIONS_PRESET_META_KEY, getUserFunctionIdInMetadata } from "@dxos/compute-runtime";
|
|
6
|
+
import { Obj, Query, Ref } from "@dxos/echo";
|
|
8
7
|
import { log } from "@dxos/log";
|
|
8
|
+
import * as Operation from "@dxos/compute/Operation";
|
|
9
9
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
10
|
-
import
|
|
10
|
+
import * as UiHooks from "@dxos/react-ui/Hooks";
|
|
11
11
|
import { messageValence } from "@dxos/ui-theme";
|
|
12
|
-
import {
|
|
12
|
+
import { useQuery } from "@dxos/echo-react";
|
|
13
13
|
import { invariant } from "@dxos/invariant";
|
|
14
|
-
import * as Atom from "effect/
|
|
14
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
15
15
|
import { createMenuAction } from "@dxos/react-ui-menu";
|
|
16
|
-
import { useQuery } from "@dxos/echo-react";
|
|
17
16
|
import { useClient } from "@dxos/react-client";
|
|
17
|
+
import { Context } from "@dxos/context";
|
|
18
|
+
import { FunctionsServiceClient, incrementSemverPatch } from "@dxos/edge-compute";
|
|
19
|
+
import { bundleFunction } from "@dxos/edge-compute/bundler";
|
|
20
|
+
import { FunctionRuntimeKind } from "@dxos/protocols";
|
|
18
21
|
import { format } from "prettier";
|
|
19
22
|
import prettierPluginEstree from "prettier/plugins/estree";
|
|
20
23
|
import prettierPluginTypescript from "prettier/plugins/typescript";
|
|
24
|
+
import * as Hooks from "@dxos/app-framework/Hooks";
|
|
21
25
|
import * as Script from "@dxos/compute/Script";
|
|
22
26
|
import * as SpaceOperation from "@dxos/plugin-space/SpaceOperation";
|
|
23
27
|
import * as Capabilities from "@dxos/app-framework/Capabilities";
|
|
24
|
-
import
|
|
28
|
+
import * as PluginManagerProvider from "@dxos/app-framework/PluginManagerProvider";
|
|
29
|
+
import * as EffectEx from "@dxos/effect/EffectEx";
|
|
30
|
+
//#region src/util/deploy.ts
|
|
31
|
+
var __dxlog_file$3 = "/__w/dxos/dxos/packages/plugins/plugin-script/src/util/deploy.ts";
|
|
32
|
+
var isScriptDeployed = ({ script, fn }) => {
|
|
33
|
+
const existingFunctionId = fn && getUserFunctionIdInMetadata(Obj.getMeta(fn));
|
|
34
|
+
return Boolean(existingFunctionId) && !script.changed;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Deploy a script to a space, handling bundling and uploading to the FaaS infrastructure.
|
|
38
|
+
*/
|
|
39
|
+
var deployScript = async ({ script, getEdgeHttpClient, ownerDid, db, fn, existingFunctionId }) => {
|
|
40
|
+
const validationError = validateDeployInputs(script, db);
|
|
41
|
+
if (validationError) return {
|
|
42
|
+
success: false,
|
|
43
|
+
error: validationError
|
|
44
|
+
};
|
|
45
|
+
if (!ownerDid) return {
|
|
46
|
+
success: false,
|
|
47
|
+
error: /* @__PURE__ */ new Error("Identity not available.")
|
|
48
|
+
};
|
|
49
|
+
try {
|
|
50
|
+
const buildResult = await bundleFunction({ source: script.source.target.content });
|
|
51
|
+
if ("error" in buildResult) throw buildResult.error || /* @__PURE__ */ new Error("Bundle creation failed");
|
|
52
|
+
const storedFunction = createOrUpdateFunction(db, fn, script, await new FunctionsServiceClient(getEdgeHttpClient()).deploy(Context.default(void 0, {
|
|
53
|
+
"~LogMeta": "~LogMeta",
|
|
54
|
+
F: __dxlog_file$3,
|
|
55
|
+
L: 63
|
|
56
|
+
}), {
|
|
57
|
+
ownerUri: ownerDid,
|
|
58
|
+
version: fn ? incrementSemverPatch(Obj.getMeta(fn).version ?? "0.0.0") : "0.0.1",
|
|
59
|
+
functionId: existingFunctionId,
|
|
60
|
+
entryPoint: buildResult.entryPoint,
|
|
61
|
+
assets: buildResult.assets,
|
|
62
|
+
runtime: FunctionRuntimeKind.enums.WORKER_LOADER
|
|
63
|
+
}));
|
|
64
|
+
Obj.update(script, (script) => {
|
|
65
|
+
script.changed = false;
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
functionId: getUserFunctionIdInMetadata(Obj.getMeta(storedFunction))
|
|
70
|
+
};
|
|
71
|
+
} catch (err) {
|
|
72
|
+
log.catch(err, void 0, {
|
|
73
|
+
"~LogMeta": "~LogMeta",
|
|
74
|
+
F: __dxlog_file$3,
|
|
75
|
+
L: 79,
|
|
76
|
+
S: void 0
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
error: err
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Validate inputs for script deployment.
|
|
86
|
+
*/
|
|
87
|
+
var validateDeployInputs = (script, db) => {
|
|
88
|
+
if (!script.source || !db) return /* @__PURE__ */ new Error("Script source or database not available");
|
|
89
|
+
return null;
|
|
90
|
+
};
|
|
91
|
+
var createOrUpdateFunction = (db, fn, script, newFunction) => {
|
|
92
|
+
if (fn) {
|
|
93
|
+
Operation.setFrom(fn, newFunction);
|
|
94
|
+
return fn;
|
|
95
|
+
} else {
|
|
96
|
+
Obj.update(newFunction, (newFunction) => {
|
|
97
|
+
newFunction.source = Ref.make(script);
|
|
98
|
+
});
|
|
99
|
+
return db.add(newFunction);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
//#endregion
|
|
25
103
|
//#region src/hooks/deploy.ts
|
|
26
104
|
var __dxlog_file$2 = "/__w/dxos/dxos/packages/plugins/plugin-script/src/hooks/deploy.ts";
|
|
27
105
|
var createDeploy = ({ state, script, db, fn, client, existingFunctionId, t }) => {
|
|
@@ -40,7 +118,8 @@ var createDeploy = ({ state, script, db, fn, client, existingFunctionId, t }) =>
|
|
|
40
118
|
state.set("deploying", true);
|
|
41
119
|
const result = await deployScript({
|
|
42
120
|
script,
|
|
43
|
-
client,
|
|
121
|
+
getEdgeHttpClient: () => client.edge.http,
|
|
122
|
+
ownerDid: client.halo.identity.get()?.did,
|
|
44
123
|
db,
|
|
45
124
|
fn,
|
|
46
125
|
existingFunctionId
|
|
@@ -49,7 +128,7 @@ var createDeploy = ({ state, script, db, fn, client, existingFunctionId, t }) =>
|
|
|
49
128
|
log.catch(result.error, void 0, {
|
|
50
129
|
"~LogMeta": "~LogMeta",
|
|
51
130
|
F: __dxlog_file$2,
|
|
52
|
-
L:
|
|
131
|
+
L: 82,
|
|
53
132
|
S: void 0
|
|
54
133
|
});
|
|
55
134
|
state.set("error", t("upload-failed.label"));
|
|
@@ -218,7 +297,7 @@ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-script/src/hooks/useC
|
|
|
218
297
|
* All creation / deployment operations run concurrently for improved performance.
|
|
219
298
|
*/
|
|
220
299
|
var useCreateAndDeployScriptTemplates = (db, scriptTemplates) => {
|
|
221
|
-
const { invokePromise } = useOperationInvoker();
|
|
300
|
+
const { invokePromise } = Hooks.useOperationInvoker();
|
|
222
301
|
const client = useClient();
|
|
223
302
|
const [status, setStatus] = useState("idle");
|
|
224
303
|
const [error, setError] = useState(void 0);
|
|
@@ -248,7 +327,8 @@ var useCreateAndDeployScriptTemplates = (db, scriptTemplates) => {
|
|
|
248
327
|
await invokePromise(SpaceOperation.AddObject, { object: createResult.data.object }, { spaceId: db.spaceId });
|
|
249
328
|
return deployScript({
|
|
250
329
|
db,
|
|
251
|
-
client,
|
|
330
|
+
getEdgeHttpClient: () => client.edge.http,
|
|
331
|
+
ownerDid: client.halo.identity.get()?.did,
|
|
252
332
|
script: createResult.data.object
|
|
253
333
|
});
|
|
254
334
|
}))).some((result) => !result.success);
|
|
@@ -266,7 +346,7 @@ var useCreateAndDeployScriptTemplates = (db, scriptTemplates) => {
|
|
|
266
346
|
//#endregion
|
|
267
347
|
//#region src/hooks/useToolbarState.ts
|
|
268
348
|
var useToolbarState = (initialState = {}) => {
|
|
269
|
-
const registry = useCapability(Capabilities.AtomRegistry);
|
|
349
|
+
const registry = Hooks.useCapability(Capabilities.AtomRegistry);
|
|
270
350
|
const atom = useMemo(() => Atom.make(initialState), []);
|
|
271
351
|
return useMemo(() => ({
|
|
272
352
|
atom,
|
|
@@ -291,11 +371,11 @@ var useToolbarState = (initialState = {}) => {
|
|
|
291
371
|
* @returns The compiler instance or undefined if it is not ready.
|
|
292
372
|
*/
|
|
293
373
|
var useCompiler = () => {
|
|
294
|
-
const manager = usePluginManager();
|
|
295
|
-
useAsyncEffect(async () => {
|
|
374
|
+
const manager = PluginManagerProvider.usePluginManager();
|
|
375
|
+
UiHooks.useAsyncEffect(async () => {
|
|
296
376
|
await manager.activate(ScriptEvents.SetupCompiler).pipe(EffectEx.runAndForwardErrors);
|
|
297
377
|
}, [manager]);
|
|
298
|
-
const [compiler] = useCapabilities(ScriptCapabilities.Compiler);
|
|
378
|
+
const [compiler] = Hooks.useCapabilities(ScriptCapabilities.Compiler);
|
|
299
379
|
return compiler;
|
|
300
380
|
};
|
|
301
381
|
//#endregion
|
package/dist/lib/hooks.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../src/hooks/deploy.ts","../../src/hooks/format.ts","../../src/hooks/template.ts","../../src/hooks/useCreateAndDeployScriptTemplates.ts","../../src/hooks/useToolbarState.ts","../../src/hooks/useCompiler.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useMemo } from 'react';\n\nimport { getUserFunctionIdInMetadata } from '@dxos/compute-runtime';\nimport * as Operation from '@dxos/compute/Operation';\nimport * as Script from '@dxos/compute/Script';\nimport { type Database, Obj, Query, Ref } from '@dxos/echo';\nimport { useQuery } from '@dxos/echo-react';\nimport { log } from '@dxos/log';\nimport { type Client, useClient } from '@dxos/react-client';\nimport { type TFunction } from '@dxos/react-ui';\nimport { type ActionGraphProps, createMenuAction } from '@dxos/react-ui-menu';\nimport { messageValence } from '@dxos/ui-theme';\n\nimport { meta } from '#meta';\n\nimport { deployScript, getFunctionUrl, isScriptDeployed } from '../util';\n\nexport type DeployActionProperties = { type: 'deploy' } | { type: 'copy' };\n\nexport type DeployState = {\n deploying: boolean;\n deployed: boolean;\n functionUrl: string;\n error: string;\n};\n\nimport { type ScriptToolbarStateStore } from './useToolbarState';\n\nexport type CreateDeployOptions = {\n state: ScriptToolbarStateStore;\n script: Script.Script;\n fn: Operation.PersistentOperation;\n db?: Database.Database;\n existingFunctionId?: string;\n client: Client;\n t: TFunction;\n};\n\nexport const createDeploy = ({\n state,\n script,\n db,\n fn,\n client,\n existingFunctionId,\n t,\n}: CreateDeployOptions): ActionGraphProps => {\n const { value } = state;\n\n // TODO(wittjosiah): Should this be an action?\n const errorItem = createMenuAction('error', () => {}, {\n label: value.error ?? ['no-error.label', { ns: meta.profile.key }],\n icon: 'ph--warning-circle--regular',\n hidden: !value.error,\n classNames: value.error && messageValence('error'),\n });\n\n const deployAction = createMenuAction<DeployActionProperties>(\n 'deploy',\n async () => {\n if (!script.source || !db) {\n return;\n }\n\n state.set('error', undefined);\n state.set('deploying', true);\n\n const result = await deployScript({ script, client, db, fn, existingFunctionId });\n\n if (!result.success) {\n log.catch(result.error);\n state.set('error', t('upload-failed.label'));\n }\n\n state.set('deploying', false);\n },\n {\n type: 'deploy',\n label: [value.deploying ? 'publishing.label' : 'deploy.label', { ns: meta.profile.key }],\n icon: value.deploying ? 'ph--spinner-gap--regular' : 'ph--cloud-arrow-up--regular',\n disabled: value.deploying,\n classNames: value.deploying ? '[&_svg]:animate-spin' : '',\n },\n );\n\n const copyAction = createMenuAction<DeployActionProperties>(\n 'copy',\n async () => {\n if (value.functionUrl) {\n await navigator.clipboard.writeText(value.functionUrl);\n }\n },\n {\n type: 'copy',\n label: ['copy-link.label', { ns: meta.profile.key }],\n icon: 'ph--link--regular',\n disabled: !value.functionUrl,\n },\n );\n\n return {\n nodes: [errorItem, deployAction, copyAction],\n edges: [\n { source: 'root', target: 'error', relation: 'child' },\n { source: 'root', target: 'deploy', relation: 'child' },\n { source: 'root', target: 'copy', relation: 'child' },\n ],\n };\n};\n\nexport const useDeployState = ({ state, script }: { state: ScriptToolbarStateStore; script: Script.Script }) => {\n const { db, client, fn, existingFunctionId } = useDeployDeps({ script });\n useEffect(() => {\n if (!existingFunctionId) {\n return;\n }\n\n state.set(\n 'functionUrl',\n getFunctionUrl({\n script,\n fn,\n edgeUrl: client.config.values.runtime?.services?.edge?.url ?? '',\n }),\n );\n }, [existingFunctionId, db, fn, script, client.config.values.runtime?.services?.edge?.url, state]);\n\n useEffect(() => {\n state.set('deployed', isScriptDeployed({ script, fn }));\n }, [script.changed, existingFunctionId, fn, script, state]);\n};\n\nexport const useDeployDeps = ({ script }: { script: Script.Script }) => {\n const client = useClient();\n const db = Obj.getDatabase(script);\n const [fn] = useQuery(db, Query.type(Operation.PersistentOperation, { source: Ref.make(script) }));\n const existingFunctionId = useMemo(() => fn && getUserFunctionIdInMetadata(Obj.getMeta(fn)), [fn]);\n return { client, db, fn, existingFunctionId };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { format } from 'prettier';\nimport prettierPluginEstree from 'prettier/plugins/estree';\nimport prettierPluginTypescript from 'prettier/plugins/typescript';\n\nimport type * as Script from '@dxos/compute/Script';\nimport { Obj } from '@dxos/echo';\nimport { log } from '@dxos/log';\nimport { type ActionGraphProps, createMenuAction } from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\n\nexport type FormatActionProperties = { type: 'format' };\n\nexport const createFormat = (script: Script.Script): ActionGraphProps => {\n const formatAction = createMenuAction(\n 'format',\n async () => {\n if (!script.source) {\n return;\n }\n\n try {\n const formatted = await format(script.source.target!.content, {\n parser: 'typescript',\n plugins: [prettierPluginEstree, prettierPluginTypescript],\n semi: true,\n singleQuote: true,\n });\n Obj.update(script.source.target!, (obj) => {\n obj.content = formatted;\n });\n } catch (err: any) {\n // TODO(wittjosiah): Show error in UI.\n log.catch(err);\n }\n },\n {\n label: ['format.label', { ns: meta.profile.key }],\n icon: 'ph--magic-wand--regular',\n },\n );\n\n return {\n nodes: [formatAction],\n edges: [\n {\n source: 'root',\n target: 'format',\n relation: 'child',\n },\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { FUNCTIONS_PRESET_META_KEY } from '@dxos/compute-runtime';\nimport * as Script from '@dxos/compute/Script';\nimport { Obj } from '@dxos/echo';\nimport { type ActionGraphProps, createMenuAction } from '@dxos/react-ui-menu';\n\nimport { templates } from '../templates';\n\nexport type TemplateActionProperties = { type: 'template'; value: string };\n\nconst createTemplateSelectActions = (script: Script.Script) => {\n return templates.map((template) => {\n return createMenuAction<TemplateActionProperties>(\n `template--${template.id}`,\n () => {\n Obj.update(script, (script) => {\n script.name = template.name;\n const meta = Obj.getMeta(script);\n const oldPresetIndex = meta.keys.findIndex((key) => key.source === FUNCTIONS_PRESET_META_KEY);\n if (oldPresetIndex >= 0) {\n meta.keys.splice(oldPresetIndex, 1);\n }\n if ('presetId' in template) {\n meta.keys.push({ source: FUNCTIONS_PRESET_META_KEY, id: template.presetId });\n }\n });\n if (script.source?.target) {\n Obj.update(script.source.target, (obj) => {\n obj.content = template.source;\n });\n }\n },\n {\n label: template.name,\n value: template.id,\n type: 'template',\n },\n );\n });\n};\n\nexport const createTemplateSelect = (script: Script.Script): ActionGraphProps => {\n const templateSelectActions = createTemplateSelectActions(script);\n return {\n nodes: [...templateSelectActions],\n edges: [\n { source: 'root', target: 'template-select', relation: 'child' },\n ...templateSelectActions.map((action) => ({ source: 'template-select', target: action.id, relation: 'child' })),\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback, useState } from 'react';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\nimport * as Script from '@dxos/compute/Script';\nimport { type Database, Obj } from '@dxos/echo';\nimport { invariant } from '@dxos/invariant';\nimport * as SpaceOperation from '@dxos/plugin-space/SpaceOperation';\nimport { useClient } from '@dxos/react-client';\n\nimport { ScriptOperation } from '#types';\n\nimport { type Template } from '../templates';\nimport { deployScript } from '../util';\n\ntype DeploymentStatus = 'idle' | 'pending' | 'success' | 'error';\n\n/**\n * Hook for creating and deploying multiple script templates concurrently.\n *\n * Takes a database and an array of script template IDs, then provides a callback\n * function that creates each script from its template and deploys it to that space.\n * All creation / deployment operations run concurrently for improved performance.\n */\nexport const useCreateAndDeployScriptTemplates = (db: Database.Database | undefined, scriptTemplates: Template[]) => {\n const { invokePromise } = useOperationInvoker();\n const client = useClient();\n const [status, setStatus] = useState<DeploymentStatus>('idle');\n const [error, setError] = useState<Error | undefined>(undefined);\n\n const handleCreateAndDeployScripts = useCallback(async () => {\n invariant(db);\n setStatus('pending');\n setError(undefined);\n\n const deploymentResults = await Promise.all(\n scriptTemplates.map(async (template) => {\n const createResult = await invokePromise(ScriptOperation.CreateScript, {\n db,\n initialTemplateId: template.id as any,\n });\n invariant(Obj.instanceOf(Script.Script, createResult.data?.object));\n await invokePromise(SpaceOperation.AddObject, { object: createResult.data.object }, { spaceId: db.spaceId });\n\n return deployScript({ db, client, script: createResult.data.object });\n }),\n );\n\n const hasErrors = deploymentResults.some((result) => !result.success);\n setStatus(hasErrors ? 'error' : 'success');\n }, [db, invokePromise, client, scriptTemplates]);\n\n // TODO(burdon): Return onCreateAndDeployScripts.\n return { handleCreateAndDeployScripts, status, error };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Atom from 'effect/unstable/reactivity/Atom';\nimport { useMemo } from 'react';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport { useCapability } from '@dxos/app-framework/ui';\n\nimport { type DeployState } from './deploy';\n\nexport type ScriptToolbarState = Partial<DeployState>;\n\nexport type ScriptToolbarStateStore = {\n atom: Atom.Writable<ScriptToolbarState>;\n get value(): ScriptToolbarState;\n update: (updater: (current: ScriptToolbarState) => ScriptToolbarState) => void;\n set: <K extends keyof ScriptToolbarState>(key: K, value: ScriptToolbarState[K]) => void;\n};\n\nexport const useToolbarState = (initialState: ScriptToolbarState = {}): ScriptToolbarStateStore => {\n const registry = useCapability(Capabilities.AtomRegistry);\n const atom = useMemo(() => Atom.make<ScriptToolbarState>(initialState), []);\n\n return useMemo(\n () => ({\n atom,\n get value() {\n return registry.get(atom);\n },\n update: (updater: (current: ScriptToolbarState) => ScriptToolbarState) => {\n registry.set(atom, updater(registry.get(atom)));\n },\n set: <K extends keyof ScriptToolbarState>(key: K, v: ScriptToolbarState[K]) => {\n registry.set(atom, { ...registry.get(atom), [key]: v });\n },\n }),\n [atom, registry],\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCapabilities, usePluginManager } from '@dxos/app-framework/ui';\nimport { EffectEx } from '@dxos/effect';\nimport { useAsyncEffect } from '@dxos/react-ui';\n\nimport { ScriptCapabilities, ScriptEvents } from '#types';\n\nimport type { Compiler } from '../compiler';\n\n/**\n * Asynchronously sets up the compiler and returns it.\n * @returns The compiler instance or undefined if it is not ready.\n */\nexport const useCompiler = (): Compiler | undefined => {\n const manager = usePluginManager();\n useAsyncEffect(async () => {\n await manager.activate(ScriptEvents.SetupCompiler).pipe(EffectEx.runAndForwardErrors);\n }, [manager]);\n const [compiler] = useCapabilities(ScriptCapabilities.Compiler);\n return compiler;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../src/util/deploy.ts","../../src/hooks/deploy.ts","../../src/hooks/format.ts","../../src/hooks/template.ts","../../src/hooks/useCreateAndDeployScriptTemplates.ts","../../src/hooks/useToolbarState.ts","../../src/hooks/useCompiler.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { getUserFunctionIdInMetadata } from '@dxos/compute-runtime';\nimport * as Operation from '@dxos/compute/Operation';\nimport * as Script from '@dxos/compute/Script';\nimport { Context } from '@dxos/context';\nimport { type Database, Obj, Ref } from '@dxos/echo';\nimport { type EdgeHttpClient } from '@dxos/edge-client';\nimport { FunctionsServiceClient, incrementSemverPatch } from '@dxos/edge-compute';\nimport { bundleFunction } from '@dxos/edge-compute/bundler';\nimport { log } from '@dxos/log';\nimport { FunctionRuntimeKind } from '@dxos/protocols';\n\nexport const isScriptDeployed = ({ script, fn }: { script: Script.Script; fn: any }): boolean => {\n const existingFunctionId = fn && getUserFunctionIdInMetadata(Obj.getMeta(fn));\n return Boolean(existingFunctionId) && !script.changed;\n};\n\ntype DeployScriptProps = {\n script: Script.Script;\n /** Identity-bound EDGE HTTP client, read inside the deploy so a missing EDGE URL fails it rather than throwing. */\n getEdgeHttpClient: () => EdgeHttpClient;\n /** Owner identity DID (`did:halo:…`); deployment fails without one. */\n ownerDid?: string;\n db: Database.Database;\n fn?: Operation.PersistentOperation;\n existingFunctionId?: string;\n};\n\ntype DeployScriptResult = { success: boolean; error?: Error; functionId?: string };\n\n/**\n * Deploy a script to a space, handling bundling and uploading to the FaaS infrastructure.\n */\nexport const deployScript = async ({\n script,\n getEdgeHttpClient,\n ownerDid,\n db,\n fn,\n existingFunctionId,\n}: DeployScriptProps): Promise<DeployScriptResult> => {\n const validationError = validateDeployInputs(script, db);\n if (validationError) {\n return { success: false, error: validationError };\n }\n\n if (!ownerDid) {\n return { success: false, error: new Error('Identity not available.') };\n }\n\n try {\n const buildResult = await bundleFunction({\n source: script.source!.target!.content,\n });\n if ('error' in buildResult) {\n throw buildResult.error || new Error('Bundle creation failed');\n }\n\n const functionsServiceClient = new FunctionsServiceClient(getEdgeHttpClient());\n const newFunction = await functionsServiceClient.deploy(Context.default(), {\n ownerUri: ownerDid,\n version: fn ? incrementSemverPatch(Obj.getMeta(fn).version ?? '0.0.0') : '0.0.1',\n functionId: existingFunctionId,\n entryPoint: buildResult.entryPoint,\n assets: buildResult.assets,\n runtime: FunctionRuntimeKind.enums.WORKER_LOADER,\n });\n\n const storedFunction = createOrUpdateFunction(db, fn, script, newFunction);\n Obj.update(script, (script) => {\n script.changed = false;\n });\n\n return { success: true, functionId: getUserFunctionIdInMetadata(Obj.getMeta(storedFunction)) };\n } catch (err: any) {\n log.catch(err);\n return { success: false, error: err };\n }\n};\n\n/**\n * Validate inputs for script deployment.\n */\nconst validateDeployInputs = (script: Script.Script, db: Database.Database): Error | null => {\n if (!script.source || !db) {\n return new Error('Script source or database not available');\n }\n return null;\n};\n\nconst createOrUpdateFunction = (\n db: Database.Database,\n fn: Operation.PersistentOperation | undefined,\n script: Script.Script,\n newFunction: Operation.PersistentOperation,\n): Operation.PersistentOperation => {\n if (fn) {\n Operation.setFrom(fn, newFunction);\n return fn;\n } else {\n Obj.update(newFunction, (newFunction) => {\n newFunction.source = Ref.make(script);\n });\n return db.add(newFunction);\n }\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useMemo } from 'react';\n\nimport { getUserFunctionIdInMetadata } from '@dxos/compute-runtime';\nimport * as Operation from '@dxos/compute/Operation';\nimport * as Script from '@dxos/compute/Script';\nimport { type Database, Obj, Query, Ref } from '@dxos/echo';\nimport { useQuery } from '@dxos/echo-react';\nimport { log } from '@dxos/log';\nimport { type Client, useClient } from '@dxos/react-client';\nimport { type ActionGraphProps, createMenuAction } from '@dxos/react-ui-menu';\nimport type * as Theme from '@dxos/react-ui/Theme';\nimport { messageValence } from '@dxos/ui-theme';\n\nimport { meta } from '#meta';\n\nimport { deployScript, getFunctionUrl, isScriptDeployed } from '../util/index.ts';\n\nexport type DeployActionProperties = { type: 'deploy' } | { type: 'copy' };\n\nexport type DeployState = {\n deploying: boolean;\n deployed: boolean;\n functionUrl: string;\n error: string;\n};\n\nimport { type ScriptToolbarStateStore } from './useToolbarState.ts';\n\nexport type CreateDeployOptions = {\n state: ScriptToolbarStateStore;\n script: Script.Script;\n fn: Operation.PersistentOperation;\n db?: Database.Database;\n existingFunctionId?: string;\n client: Client;\n t: Theme.TFunction;\n};\n\nexport const createDeploy = ({\n state,\n script,\n db,\n fn,\n client,\n existingFunctionId,\n t,\n}: CreateDeployOptions): ActionGraphProps => {\n const { value } = state;\n\n // TODO(wittjosiah): Should this be an action?\n const errorItem = createMenuAction('error', () => {}, {\n label: value.error ?? ['no-error.label', { ns: meta.profile.key }],\n icon: 'ph--warning-circle--regular',\n hidden: !value.error,\n classNames: value.error && messageValence('error'),\n });\n\n const deployAction = createMenuAction<DeployActionProperties>(\n 'deploy',\n async () => {\n if (!script.source || !db) {\n return;\n }\n\n state.set('error', undefined);\n state.set('deploying', true);\n\n const result = await deployScript({\n script,\n getEdgeHttpClient: () => client.edge.http,\n ownerDid: client.halo.identity.get()?.did,\n db,\n fn,\n existingFunctionId,\n });\n\n if (!result.success) {\n log.catch(result.error);\n state.set('error', t('upload-failed.label'));\n }\n\n state.set('deploying', false);\n },\n {\n type: 'deploy',\n label: [value.deploying ? 'publishing.label' : 'deploy.label', { ns: meta.profile.key }],\n icon: value.deploying ? 'ph--spinner-gap--regular' : 'ph--cloud-arrow-up--regular',\n disabled: value.deploying,\n classNames: value.deploying ? '[&_svg]:animate-spin' : '',\n },\n );\n\n const copyAction = createMenuAction<DeployActionProperties>(\n 'copy',\n async () => {\n if (value.functionUrl) {\n await navigator.clipboard.writeText(value.functionUrl);\n }\n },\n {\n type: 'copy',\n label: ['copy-link.label', { ns: meta.profile.key }],\n icon: 'ph--link--regular',\n disabled: !value.functionUrl,\n },\n );\n\n return {\n nodes: [errorItem, deployAction, copyAction],\n edges: [\n { source: 'root', target: 'error', relation: 'child' },\n { source: 'root', target: 'deploy', relation: 'child' },\n { source: 'root', target: 'copy', relation: 'child' },\n ],\n };\n};\n\nexport const useDeployState = ({ state, script }: { state: ScriptToolbarStateStore; script: Script.Script }) => {\n const { db, client, fn, existingFunctionId } = useDeployDeps({ script });\n useEffect(() => {\n if (!existingFunctionId) {\n return;\n }\n\n state.set(\n 'functionUrl',\n getFunctionUrl({\n script,\n fn,\n edgeUrl: client.config.values.runtime?.services?.edge?.url ?? '',\n }),\n );\n }, [existingFunctionId, db, fn, script, client.config.values.runtime?.services?.edge?.url, state]);\n\n useEffect(() => {\n state.set('deployed', isScriptDeployed({ script, fn }));\n }, [script.changed, existingFunctionId, fn, script, state]);\n};\n\nexport const useDeployDeps = ({ script }: { script: Script.Script }) => {\n const client = useClient();\n const db = Obj.getDatabase(script);\n const [fn] = useQuery(db, Query.type(Operation.PersistentOperation, { source: Ref.make(script) }));\n const existingFunctionId = useMemo(() => fn && getUserFunctionIdInMetadata(Obj.getMeta(fn)), [fn]);\n return { client, db, fn, existingFunctionId };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { format } from 'prettier';\nimport prettierPluginEstree from 'prettier/plugins/estree';\nimport prettierPluginTypescript from 'prettier/plugins/typescript';\n\nimport type * as Script from '@dxos/compute/Script';\nimport { Obj } from '@dxos/echo';\nimport { log } from '@dxos/log';\nimport { type ActionGraphProps, createMenuAction } from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\n\nexport type FormatActionProperties = { type: 'format' };\n\nexport const createFormat = (script: Script.Script): ActionGraphProps => {\n const formatAction = createMenuAction(\n 'format',\n async () => {\n if (!script.source) {\n return;\n }\n\n try {\n const formatted = await format(script.source.target!.content, {\n parser: 'typescript',\n plugins: [prettierPluginEstree, prettierPluginTypescript],\n semi: true,\n singleQuote: true,\n });\n Obj.update(script.source.target!, (obj) => {\n obj.content = formatted;\n });\n } catch (err: any) {\n // TODO(wittjosiah): Show error in UI.\n log.catch(err);\n }\n },\n {\n label: ['format.label', { ns: meta.profile.key }],\n icon: 'ph--magic-wand--regular',\n },\n );\n\n return {\n nodes: [formatAction],\n edges: [\n {\n source: 'root',\n target: 'format',\n relation: 'child',\n },\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { FUNCTIONS_PRESET_META_KEY } from '@dxos/compute-runtime';\nimport * as Script from '@dxos/compute/Script';\nimport { Obj } from '@dxos/echo';\nimport { type ActionGraphProps, createMenuAction } from '@dxos/react-ui-menu';\n\nimport { templates } from '../templates/index.ts';\n\nexport type TemplateActionProperties = { type: 'template'; value: string };\n\nconst createTemplateSelectActions = (script: Script.Script) => {\n return templates.map((template) => {\n return createMenuAction<TemplateActionProperties>(\n `template--${template.id}`,\n () => {\n Obj.update(script, (script) => {\n script.name = template.name;\n const meta = Obj.getMeta(script);\n const oldPresetIndex = meta.keys.findIndex((key) => key.source === FUNCTIONS_PRESET_META_KEY);\n if (oldPresetIndex >= 0) {\n meta.keys.splice(oldPresetIndex, 1);\n }\n if ('presetId' in template) {\n meta.keys.push({ source: FUNCTIONS_PRESET_META_KEY, id: template.presetId });\n }\n });\n if (script.source?.target) {\n Obj.update(script.source.target, (obj) => {\n obj.content = template.source;\n });\n }\n },\n {\n label: template.name,\n value: template.id,\n type: 'template',\n },\n );\n });\n};\n\nexport const createTemplateSelect = (script: Script.Script): ActionGraphProps => {\n const templateSelectActions = createTemplateSelectActions(script);\n return {\n nodes: [...templateSelectActions],\n edges: [\n { source: 'root', target: 'template-select', relation: 'child' },\n ...templateSelectActions.map((action) => ({ source: 'template-select', target: action.id, relation: 'child' })),\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as Script from '@dxos/compute/Script';\nimport { type Database, Obj } from '@dxos/echo';\nimport { invariant } from '@dxos/invariant';\nimport * as SpaceOperation from '@dxos/plugin-space/SpaceOperation';\nimport { useClient } from '@dxos/react-client';\n\nimport { ScriptOperation } from '#types';\n\nimport { type Template } from '../templates/index.ts';\nimport { deployScript } from '../util/index.ts';\n\ntype DeploymentStatus = 'idle' | 'pending' | 'success' | 'error';\n\n/**\n * Hook for creating and deploying multiple script templates concurrently.\n *\n * Takes a database and an array of script template IDs, then provides a callback\n * function that creates each script from its template and deploys it to that space.\n * All creation / deployment operations run concurrently for improved performance.\n */\nexport const useCreateAndDeployScriptTemplates = (db: Database.Database | undefined, scriptTemplates: Template[]) => {\n const { invokePromise } = Hooks.useOperationInvoker();\n const client = useClient();\n const [status, setStatus] = useState<DeploymentStatus>('idle');\n const [error, setError] = useState<Error | undefined>(undefined);\n\n const handleCreateAndDeployScripts = useCallback(async () => {\n invariant(db);\n setStatus('pending');\n setError(undefined);\n\n const deploymentResults = await Promise.all(\n scriptTemplates.map(async (template) => {\n const createResult = await invokePromise(ScriptOperation.CreateScript, {\n db,\n initialTemplateId: template.id as any,\n });\n invariant(Obj.instanceOf(Script.Script, createResult.data?.object));\n await invokePromise(SpaceOperation.AddObject, { object: createResult.data.object }, { spaceId: db.spaceId });\n\n return deployScript({\n db,\n getEdgeHttpClient: () => client.edge.http,\n ownerDid: client.halo.identity.get()?.did,\n script: createResult.data.object,\n });\n }),\n );\n\n const hasErrors = deploymentResults.some((result) => !result.success);\n setStatus(hasErrors ? 'error' : 'success');\n }, [db, invokePromise, client, scriptTemplates]);\n\n // TODO(burdon): Return onCreateAndDeployScripts.\n return { handleCreateAndDeployScripts, status, error };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Atom from 'effect/reactivity/Atom';\nimport { useMemo } from 'react';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\n\nimport { type DeployState } from './deploy.ts';\n\nexport type ScriptToolbarState = Partial<DeployState>;\n\nexport type ScriptToolbarStateStore = {\n atom: Atom.Writable<ScriptToolbarState>;\n get value(): ScriptToolbarState;\n update: (updater: (current: ScriptToolbarState) => ScriptToolbarState) => void;\n set: <K extends keyof ScriptToolbarState>(key: K, value: ScriptToolbarState[K]) => void;\n};\n\nexport const useToolbarState = (initialState: ScriptToolbarState = {}): ScriptToolbarStateStore => {\n const registry = Hooks.useCapability(Capabilities.AtomRegistry);\n const atom = useMemo(() => Atom.make<ScriptToolbarState>(initialState), []);\n\n return useMemo(\n () => ({\n atom,\n get value() {\n return registry.get(atom);\n },\n update: (updater: (current: ScriptToolbarState) => ScriptToolbarState) => {\n registry.set(atom, updater(registry.get(atom)));\n },\n set: <K extends keyof ScriptToolbarState>(key: K, v: ScriptToolbarState[K]) => {\n registry.set(atom, { ...registry.get(atom), [key]: v });\n },\n }),\n [atom, registry],\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as PluginManagerProvider from '@dxos/app-framework/PluginManagerProvider';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\n\nimport { ScriptCapabilities, ScriptEvents } from '#types';\n\nimport type { Compiler } from '../compiler/index.ts';\n\n/**\n * Asynchronously sets up the compiler and returns it.\n * @returns The compiler instance or undefined if it is not ready.\n */\nexport const useCompiler = (): Compiler | undefined => {\n const manager = PluginManagerProvider.usePluginManager();\n UiHooks.useAsyncEffect(async () => {\n await manager.activate(ScriptEvents.SetupCompiler).pipe(EffectEx.runAndForwardErrors);\n }, [manager]);\n const [compiler] = Hooks.useCapabilities(ScriptCapabilities.Compiler);\n return compiler;\n};\n"],"mappings":"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"}
|
package/dist/lib/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { t as ScriptFunction_exports } from "./ns/ScriptFunction.mjs";
|
|
2
|
+
import { t as Templates_exports } from "./ns/Templates.mjs";
|
|
1
3
|
import { t as ScriptPlugin_exports } from "./ScriptPlugin.mjs";
|
|
2
|
-
import { a as isScriptDeployed, i as deployScript, n as getFunctionUrl, r as updateFunctionMetadata, t as getAccessCredential } from "./chunk-util.mjs";
|
|
3
4
|
export * from "#types";
|
|
4
|
-
export * from "#
|
|
5
|
-
export
|
|
5
|
+
export * from "#operations";
|
|
6
|
+
export * from "#skills";
|
|
7
|
+
export { ScriptFunction_exports as ScriptFunction, ScriptPlugin_exports as ScriptPlugin, Templates_exports as Templates };
|
package/dist/lib/meta.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.script',\n name: 'Scripts',\n author: 'DXOS',\n description: trim`\n Write, deploy, and run custom TypeScript functions as ECHO objects directly inside your Composer spaces.\n Scripts execute on the Cloudflare Workers-based EDGE runtime and have access to the full DXOS SDK,\n Effect-TS, and a curated set of third-party libraries including HTTP, JSON, CSV, and date utilities.\n An AI Script assistant wires CRUD, deploy, invoke, and invocation-inspection operations as tools\n so an agent can scaffold, iterate, and test functions entirely within a chat session.\n `,\n icon: { key: 'ph--code--regular', hue: 'sky' },\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',\n spec: 'PLUGIN.mdl',\n tags: ['labs'],\n screenshots: [{ dark: 'https://media.dxos.network/plugin-details-scripts-dark.png' }],\n },\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\nimport { DXN } from '@dxos/keys';\n\nimport config from '../dx.config';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n\n// TODO(ZaymonFC): Configure by scopes?\nexport const defaultScriptsForIntegration: Record<string, string[]> = {\n // TODO(wittjosiah): Also include content extraction scripts in the default set.\n 'gmail.com': [DXN.make('org.dxos.script.gmail')],\n};\n"],"mappings":";;;;;AAOA,IAAA,oBAAe,QAAQ,KAAK,EAC1B,QAAQ;CACN,KAAK;CACL,MAAM;CACN,QAAQ;CACR,aAAa,IAAI;;;;;;;CAOjB,MAAM;EAAE,KAAK;EAAqB,KAAK;CAAM;CAC7C,QAAQ;CACR,MAAM;CACN,MAAM,CAAC,MAAM;CACb,aAAa,CAAC,EAAE,MAAM,6DAA6D,CAAC;AACtF,EACF,CAAC;;;AChBD,IAAa,OAAO,OAAO,kBAAkB,iBAAM;AAGnD,IAAa,+BAAyD,EAEpE,aAAa,CAAC,IAAI,KAAK,uBAAuB,CAAC,EACjD"}
|
|
1
|
+
{"version":3,"file":"meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.script',\n name: 'Scripts',\n author: 'DXOS',\n description: trim`\n Write, deploy, and run custom TypeScript functions as ECHO objects directly inside your Composer spaces.\n Scripts execute on the Cloudflare Workers-based EDGE runtime and have access to the full DXOS SDK,\n Effect-TS, and a curated set of third-party libraries including HTTP, JSON, CSV, and date utilities.\n An AI Script assistant wires CRUD, deploy, invoke, and invocation-inspection operations as tools\n so an agent can scaffold, iterate, and test functions entirely within a chat session.\n `,\n icon: { key: 'ph--code--regular', hue: 'sky' },\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',\n spec: 'PLUGIN.mdl',\n tags: ['labs'],\n screenshots: [{ dark: 'https://media.dxos.network/plugin-details-scripts-dark.png' }],\n },\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\nimport { DXN } from '@dxos/keys';\n\nimport config from '../dx.config.ts';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n\n// TODO(ZaymonFC): Configure by scopes?\nexport const defaultScriptsForIntegration: Record<string, string[]> = {\n // TODO(wittjosiah): Also include content extraction scripts in the default set.\n 'gmail.com': [DXN.make('org.dxos.script.gmail')],\n};\n"],"mappings":";;;;;AAOA,IAAA,oBAAe,QAAQ,KAAK,EAC1B,QAAQ;CACN,KAAK;CACL,MAAM;CACN,QAAQ;CACR,aAAa,IAAI;;;;;;;CAOjB,MAAM;EAAE,KAAK;EAAqB,KAAK;CAAM;CAC7C,QAAQ;CACR,MAAM;CACN,MAAM,CAAC,MAAM;CACb,aAAa,CAAC,EAAE,MAAM,6DAA6D,CAAC;AACtF,EACF,CAAC;;;AChBD,IAAa,OAAO,OAAO,kBAAkB,iBAAM;AAGnD,IAAa,+BAAyD,EAEpE,aAAa,CAAC,IAAI,KAAK,uBAAuB,CAAC,EACjD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { t as __exportAll } from "../chunk-rolldown-runtime.mjs";
|
|
2
|
+
import { n as getFunctionUrl, r as updateFunctionMetadata, t as getAccessCredential } from "../chunk-functions.mjs";
|
|
3
|
+
//#region src/ScriptFunction.ts
|
|
4
|
+
var ScriptFunction_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
getAccessCredential: () => getAccessCredential,
|
|
6
|
+
getFunctionUrl: () => getFunctionUrl,
|
|
7
|
+
updateFunctionMetadata: () => updateFunctionMetadata
|
|
8
|
+
});
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getAccessCredential, getFunctionUrl, ScriptFunction_exports as t, updateFunctionMetadata };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=ScriptFunction.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScriptFunction.mjs","names":[],"sources":["../../../src/ScriptFunction.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nexport * from './util/functions.ts';\n"],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { t as __exportAll } from "../chunk-rolldown-runtime.mjs";
|
|
2
|
+
import { n as data_generator_default, t as templates } from "../chunk-templates.mjs";
|
|
3
|
+
//#region src/Templates.ts
|
|
4
|
+
var Templates_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
dataGenerator: () => data_generator_default,
|
|
6
|
+
templates: () => templates
|
|
7
|
+
});
|
|
8
|
+
//#endregion
|
|
9
|
+
export { data_generator_default as dataGenerator, Templates_exports as t, templates };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=Templates.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Templates.mjs","names":[],"sources":["../../../src/Templates.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nexport * from './templates/index.ts';\n"],"mappings":""}
|
package/dist/lib/testing.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Notebook } from "#types";
|
|
2
|
-
import * as Operation from "@dxos/compute/Operation";
|
|
3
2
|
import { Obj, Ref, Type } from "@dxos/echo";
|
|
3
|
+
import * as Operation from "@dxos/compute/Operation";
|
|
4
4
|
import * as Script from "@dxos/compute/Script";
|
|
5
5
|
import { PublicKey } from "@dxos/keys";
|
|
6
6
|
import * as Instructions from "@dxos/compute/Instructions";
|
|
@@ -2,8 +2,9 @@ import { Notebook } from "#types";
|
|
|
2
2
|
import { meta } from "#meta";
|
|
3
3
|
import { Type } from "@dxos/echo";
|
|
4
4
|
import * as Script from "@dxos/compute/Script";
|
|
5
|
+
import { translations as translations$1 } from "@dxos/react-ui-query/translations";
|
|
5
6
|
//#region src/translations.ts
|
|
6
|
-
var translations = [{ "en-US": {
|
|
7
|
+
var translations = [...translations$1, { "en-US": {
|
|
7
8
|
[Type.getTypename(Script.Script)]: {
|
|
8
9
|
"typename.label": "Script",
|
|
9
10
|
"typename.label_zero": "Scripts",
|