@dxos/plugin-script 0.6.13-main.ed424a1 → 0.6.13-staging.1e988a3
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/README.md +1 -1
- package/dist/lib/browser/{ScriptContainer-M4MDQTBU.mjs → ScriptEditor-5Y3EROG3.mjs} +106 -258
- package/dist/lib/browser/ScriptEditor-5Y3EROG3.mjs.map +7 -0
- package/dist/lib/browser/TypescriptEditor-GPE72Y6I.mjs +9 -0
- package/dist/lib/browser/{chunk-G6FWCTGT.mjs → chunk-DL5XQRQM.mjs} +5 -7
- package/dist/lib/browser/chunk-DL5XQRQM.mjs.map +7 -0
- package/dist/lib/browser/chunk-JBACGDOJ.mjs +21 -0
- package/dist/lib/browser/chunk-JBACGDOJ.mjs.map +7 -0
- package/dist/lib/browser/chunk-MRGOT5RF.mjs +78 -0
- package/dist/lib/browser/chunk-MRGOT5RF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-KXVQPS4Y.mjs → chunk-O4LWBX6A.mjs} +2 -2
- package/dist/lib/browser/{chunk-KXVQPS4Y.mjs.map → chunk-O4LWBX6A.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-G6H56WFS.mjs → chunk-RHEZ5LUU.mjs} +2 -51
- package/dist/lib/browser/{chunk-G6H56WFS.mjs.map → chunk-RHEZ5LUU.mjs.map} +4 -4
- package/dist/lib/browser/edge/index.mjs +1 -3
- package/dist/lib/browser/index.mjs +62 -80
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/browser/types/index.mjs +2 -2
- package/dist/lib/node/ScriptEditor-YCUQFWQM.cjs +526 -0
- package/dist/lib/node/ScriptEditor-YCUQFWQM.cjs.map +7 -0
- package/dist/lib/node/{chunk-EJC55SDD.cjs → TypescriptEditor-M3WWFIP2.cjs} +8 -18
- package/dist/lib/node/TypescriptEditor-M3WWFIP2.cjs.map +7 -0
- package/dist/lib/node/{chunk-ACLCRWDB.cjs → chunk-4GTXIELQ.cjs} +6 -44
- package/dist/lib/node/chunk-4GTXIELQ.cjs.map +7 -0
- package/dist/lib/node/chunk-4VMNBXWU.cjs +54 -0
- package/dist/lib/node/chunk-4VMNBXWU.cjs.map +7 -0
- package/dist/lib/node/{chunk-25PQE7FL.cjs → chunk-5RBVXKXT.cjs} +6 -6
- package/dist/lib/node/{chunk-25PQE7FL.cjs.map → chunk-5RBVXKXT.cjs.map} +2 -2
- package/dist/lib/node/chunk-IMLDKD5Y.cjs +111 -0
- package/dist/lib/node/chunk-IMLDKD5Y.cjs.map +7 -0
- package/dist/lib/node/{chunk-UZ3ZXEBF.cjs → chunk-PFH3ROEH.cjs} +8 -11
- package/dist/lib/node/chunk-PFH3ROEH.cjs.map +7 -0
- package/dist/lib/node/edge/index.cjs +8 -10
- package/dist/lib/node/edge/index.cjs.map +2 -2
- package/dist/lib/node/index.cjs +82 -95
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.cjs +3 -3
- package/dist/lib/node/meta.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types/index.cjs +5 -5
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
- package/dist/types/src/components/DebugPanel.d.ts.map +1 -0
- package/dist/types/src/components/{FrameContainer → ScriptBlock/FrameContainer}/FrameContainer.d.ts +1 -1
- package/dist/types/src/components/ScriptBlock/FrameContainer/FrameContainer.d.ts.map +1 -0
- package/dist/types/src/components/ScriptBlock/FrameContainer/frame.d.ts.map +1 -0
- package/dist/types/src/components/ScriptBlock/FrameContainer/index.d.ts.map +1 -0
- package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts +3 -1
- package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts.map +1 -1
- package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts +1 -1
- package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.d.ts +15 -0
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.d.ts.map +1 -0
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.stories.d.ts +13 -0
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.stories.d.ts.map +1 -0
- package/dist/types/src/components/ScriptBlock/Splitter/index.d.ts +2 -0
- package/dist/types/src/components/ScriptBlock/Splitter/index.d.ts.map +1 -0
- package/dist/types/src/components/ScriptEditor.d.ts +5 -4
- package/dist/types/src/components/ScriptEditor.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar.d.ts +13 -0
- package/dist/types/src/components/Toolbar.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar.stories.d.ts +14 -0
- package/dist/types/src/components/Toolbar.stories.d.ts.map +1 -0
- package/dist/types/src/components/{TypescriptEditor/TypescriptEditor.d.ts → TypescriptEditor.d.ts} +2 -1
- package/dist/types/src/components/TypescriptEditor.d.ts.map +1 -0
- package/dist/types/src/components/TypescriptEditor.stories.d.ts +10 -0
- package/dist/types/src/components/TypescriptEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +2 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/edge/functions.d.ts +0 -1
- package/dist/types/src/edge/functions.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +9 -4
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +0 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/script.d.ts +4 -4
- package/dist/types/src/types/types.d.ts +3 -4
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/package.json +55 -61
- package/src/ScriptPlugin.tsx +38 -22
- package/src/bundler/bundler.test.ts +2 -12
- package/src/components/{DebugPanel/DebugPanel.tsx → DebugPanel.tsx} +41 -48
- package/src/components/{FrameContainer → ScriptBlock/FrameContainer}/FrameContainer.tsx +1 -1
- package/src/components/ScriptBlock/ScriptBlock.stories.tsx +8 -6
- package/src/components/ScriptBlock/ScriptBlock.tsx +36 -10
- package/src/components/ScriptBlock/Splitter/Splitter.stories.tsx +37 -0
- package/src/components/ScriptBlock/Splitter/Splitter.tsx +52 -0
- package/src/components/{Toolbar → ScriptBlock/Splitter}/index.ts +1 -1
- package/src/components/ScriptEditor.tsx +46 -47
- package/src/components/{Toolbar/Toolbar.stories.tsx → Toolbar.stories.tsx} +1 -10
- package/src/components/Toolbar.tsx +147 -0
- package/src/components/{TypescriptEditor/TypescriptEditor.stories.tsx → TypescriptEditor.stories.tsx} +29 -8
- package/src/components/{TypescriptEditor/TypescriptEditor.tsx → TypescriptEditor.tsx} +3 -1
- package/src/components/index.ts +2 -3
- package/src/edge/functions.ts +0 -1
- package/src/meta.tsx +19 -0
- package/src/translations.ts +0 -2
- package/src/types/types.ts +5 -9
- package/dist/lib/browser/ScriptContainer-M4MDQTBU.mjs.map +0 -7
- package/dist/lib/browser/chunk-G6FWCTGT.mjs.map +0 -7
- package/dist/lib/browser/chunk-SGQHRB4P.mjs +0 -17
- package/dist/lib/browser/chunk-SGQHRB4P.mjs.map +0 -7
- package/dist/lib/node/ScriptContainer-KMIPKT3H.cjs +0 -668
- package/dist/lib/node/ScriptContainer-KMIPKT3H.cjs.map +0 -7
- package/dist/lib/node/chunk-ACLCRWDB.cjs.map +0 -7
- package/dist/lib/node/chunk-EJC55SDD.cjs.map +0 -7
- package/dist/lib/node/chunk-UZ3ZXEBF.cjs.map +0 -7
- package/dist/lib/node-esm/ScriptContainer-EAE6L5JV.mjs +0 -666
- package/dist/lib/node-esm/ScriptContainer-EAE6L5JV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2NX3HWPM.mjs +0 -245
- package/dist/lib/node-esm/chunk-2NX3HWPM.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-7EDYDVQH.mjs +0 -47
- package/dist/lib/node-esm/chunk-7EDYDVQH.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GO7HYFM5.mjs +0 -19
- package/dist/lib/node-esm/chunk-GO7HYFM5.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-LDLNTVAK.mjs +0 -280
- package/dist/lib/node-esm/chunk-LDLNTVAK.mjs.map +0 -7
- package/dist/lib/node-esm/edge/index.mjs +0 -22
- package/dist/lib/node-esm/index.mjs +0 -310
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/meta.mjs +0 -10
- package/dist/lib/node-esm/meta.mjs.map +0 -7
- package/dist/lib/node-esm/types/index.mjs +0 -13
- package/dist/lib/node-esm/types/index.mjs.map +0 -7
- package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +0 -1
- package/dist/types/src/components/DebugPanel/index.d.ts +0 -2
- package/dist/types/src/components/DebugPanel/index.d.ts.map +0 -1
- package/dist/types/src/components/FrameContainer/FrameContainer.d.ts.map +0 -1
- package/dist/types/src/components/FrameContainer/frame.d.ts.map +0 -1
- package/dist/types/src/components/FrameContainer/index.d.ts.map +0 -1
- package/dist/types/src/components/ScriptContainer.d.ts +0 -5
- package/dist/types/src/components/ScriptContainer.d.ts.map +0 -1
- package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts +0 -6
- package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +0 -1
- package/dist/types/src/components/ScriptSettings/index.d.ts +0 -2
- package/dist/types/src/components/ScriptSettings/index.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -23
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +0 -17
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/index.d.ts +0 -2
- package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +0 -1
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts +0 -10
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +0 -1
- package/dist/types/src/components/TypescriptEditor/index.d.ts +0 -2
- package/dist/types/src/components/TypescriptEditor/index.d.ts.map +0 -1
- package/dist/types/src/templates/chat.d.ts +0 -6
- package/dist/types/src/templates/chat.d.ts.map +0 -1
- package/dist/types/src/templates/chess.d.ts +0 -6
- package/dist/types/src/templates/chess.d.ts.map +0 -1
- package/dist/types/src/templates/echo.d.ts +0 -6
- package/dist/types/src/templates/echo.d.ts.map +0 -1
- package/dist/types/src/templates/email.d.ts +0 -6
- package/dist/types/src/templates/email.d.ts.map +0 -1
- package/dist/types/src/templates/forex.d.ts +0 -6
- package/dist/types/src/templates/forex.d.ts.map +0 -1
- package/dist/types/src/templates.d.ts +0 -8
- package/dist/types/src/templates.d.ts.map +0 -1
- package/src/components/DebugPanel/index.ts +0 -5
- package/src/components/ScriptContainer.tsx +0 -22
- package/src/components/ScriptSettings/ScriptSettings.tsx +0 -47
- package/src/components/ScriptSettings/index.ts +0 -5
- package/src/components/Toolbar/Toolbar.tsx +0 -180
- package/src/components/TypescriptEditor/index.ts +0 -5
- package/src/meta.ts +0 -15
- package/src/templates/chat.ts +0 -102
- package/src/templates/chess.ts +0 -41
- package/src/templates/echo.ts +0 -15
- package/src/templates/email.ts +0 -38
- package/src/templates/forex.ts +0 -21
- package/src/templates.ts +0 -54
- /package/dist/lib/{node-esm/edge/index.mjs.map → browser/TypescriptEditor-GPE72Y6I.mjs.map} +0 -0
- /package/dist/types/src/components/{DebugPanel/DebugPanel.d.ts → DebugPanel.d.ts} +0 -0
- /package/dist/types/src/components/{FrameContainer → ScriptBlock/FrameContainer}/frame.d.ts +0 -0
- /package/dist/types/src/components/{FrameContainer → ScriptBlock/FrameContainer}/index.d.ts +0 -0
- /package/src/components/{FrameContainer → ScriptBlock/FrameContainer}/frame.html +0 -0
- /package/src/components/{FrameContainer → ScriptBlock/FrameContainer}/frame.tsx +0 -0
- /package/src/components/{FrameContainer → ScriptBlock/FrameContainer}/index.ts +0 -0
package/src/ScriptPlugin.tsx
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Code, type IconProps } from '@phosphor-icons/react';
|
|
5
6
|
// @ts-ignore
|
|
6
7
|
import wasmUrl from 'esbuild-wasm/esbuild.wasm?url';
|
|
7
8
|
import React from 'react';
|
|
@@ -16,9 +17,8 @@ import { loadObjectReferences } from '@dxos/react-client/echo';
|
|
|
16
17
|
|
|
17
18
|
import { initializeBundler } from './bundler';
|
|
18
19
|
import { Compiler } from './compiler';
|
|
19
|
-
import {
|
|
20
|
+
import { ScriptEditor } from './components';
|
|
20
21
|
import meta, { SCRIPT_PLUGIN } from './meta';
|
|
21
|
-
import { templates } from './templates';
|
|
22
22
|
import translations from './translations';
|
|
23
23
|
import { FunctionType, ScriptType } from './types';
|
|
24
24
|
import { ScriptAction, type ScriptPluginProvides } from './types';
|
|
@@ -45,12 +45,12 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
45
45
|
await initializeBundler({ wasmUrl });
|
|
46
46
|
},
|
|
47
47
|
provides: {
|
|
48
|
-
settings: {},
|
|
49
48
|
metadata: {
|
|
50
49
|
records: {
|
|
51
50
|
[ScriptType.typename]: {
|
|
52
51
|
placeholder: ['object title placeholder', { ns: SCRIPT_PLUGIN }],
|
|
53
|
-
icon:
|
|
52
|
+
icon: (props: IconProps) => <Code {...props} />,
|
|
53
|
+
iconSymbol: 'ph--code--regular',
|
|
54
54
|
// TODO(wittjosiah): Move out of metadata.
|
|
55
55
|
loadReferences: (script: ScriptType) => loadObjectReferences(script, (script) => [script.source]),
|
|
56
56
|
},
|
|
@@ -60,12 +60,6 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
60
60
|
echo: {
|
|
61
61
|
schema: [ScriptType, FunctionType],
|
|
62
62
|
},
|
|
63
|
-
space: {
|
|
64
|
-
onSpaceCreate: {
|
|
65
|
-
label: ['create object label', { ns: SCRIPT_PLUGIN }],
|
|
66
|
-
action: ScriptAction.CREATE,
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
63
|
graph: {
|
|
70
64
|
builder: (plugins) => {
|
|
71
65
|
const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
|
|
@@ -99,7 +93,8 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
99
93
|
},
|
|
100
94
|
properties: {
|
|
101
95
|
label: ['create object label', { ns: SCRIPT_PLUGIN }],
|
|
102
|
-
icon:
|
|
96
|
+
icon: (props: IconProps) => <Code {...props} />,
|
|
97
|
+
iconSymbol: 'ph--code--regular',
|
|
103
98
|
testId: 'scriptPlugin.createObject',
|
|
104
99
|
},
|
|
105
100
|
},
|
|
@@ -108,19 +103,29 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
108
103
|
});
|
|
109
104
|
},
|
|
110
105
|
},
|
|
106
|
+
stack: {
|
|
107
|
+
creators: [
|
|
108
|
+
{
|
|
109
|
+
id: 'create-stack-section-script',
|
|
110
|
+
testId: 'scriptPlugin.createSection',
|
|
111
|
+
type: ['plugin name', { ns: SCRIPT_PLUGIN }],
|
|
112
|
+
label: ['create stack section label', { ns: SCRIPT_PLUGIN }],
|
|
113
|
+
icon: (props: any) => <Code {...props} />,
|
|
114
|
+
intent: {
|
|
115
|
+
plugin: SCRIPT_PLUGIN,
|
|
116
|
+
action: ScriptAction.CREATE,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
111
121
|
surface: {
|
|
112
122
|
component: ({ data, role }) => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
123
|
+
if (role && !['article', 'section'].includes(role)) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
117
126
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return <ScriptContainer script={data.object} env={compiler.environment} />;
|
|
121
|
-
}
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
127
|
+
if (data.object instanceof ScriptType) {
|
|
128
|
+
return <ScriptEditor env={compiler.environment} script={data.object} role={role} />;
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
return null;
|
|
@@ -130,7 +135,7 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
130
135
|
resolver: (intent) => {
|
|
131
136
|
switch (intent.action) {
|
|
132
137
|
case ScriptAction.CREATE: {
|
|
133
|
-
return { data: create(ScriptType, { source: create(TextType, { content:
|
|
138
|
+
return { data: create(ScriptType, { source: create(TextType, { content: example }) }) };
|
|
134
139
|
}
|
|
135
140
|
}
|
|
136
141
|
},
|
|
@@ -138,3 +143,14 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
138
143
|
},
|
|
139
144
|
};
|
|
140
145
|
};
|
|
146
|
+
|
|
147
|
+
// TODO(burdon): Import.
|
|
148
|
+
const example = [
|
|
149
|
+
'export default async ({ ',
|
|
150
|
+
' event: { data: { request } },',
|
|
151
|
+
' context: { space, ai } ',
|
|
152
|
+
'}: any) => {',
|
|
153
|
+
" return new Response('Hello DXOS!');",
|
|
154
|
+
'};',
|
|
155
|
+
'',
|
|
156
|
+
].join('\n');
|
|
@@ -2,21 +2,11 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
import wasmUrl from 'esbuild-wasm/esbuild.wasm?url';
|
|
7
|
-
import { beforeAll, describe, expect, test } from 'vitest';
|
|
5
|
+
import { describe, expect, test } from 'vitest';
|
|
8
6
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
import { Bundler, initializeBundler } from './bundler';
|
|
7
|
+
import { Bundler } from './bundler';
|
|
12
8
|
|
|
13
9
|
describe('Bundler', () => {
|
|
14
|
-
beforeAll(async () => {
|
|
15
|
-
if (!isNode()) {
|
|
16
|
-
await initializeBundler({ wasmUrl });
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
10
|
test('Basic', async () => {
|
|
21
11
|
const bundler = new Bundler({ platform: 'node', sandboxedModules: [], remoteModules: {} });
|
|
22
12
|
const result = await bundler.bundle('const x = 100'); // TODO(burdon): Test import.
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
19
19
|
import { mx } from '@dxos/react-ui-theme';
|
|
20
20
|
|
|
21
|
-
import { SCRIPT_PLUGIN } from '
|
|
21
|
+
import { SCRIPT_PLUGIN } from '../meta';
|
|
22
22
|
|
|
23
23
|
type State = 'pending' | 'responding';
|
|
24
24
|
|
|
@@ -47,7 +47,7 @@ export const DebugPanel = ({ classNames, functionUrl, binding: _binding, onBindi
|
|
|
47
47
|
const [result, setResult] = useState('');
|
|
48
48
|
const [state, setState] = useState<State | null>(null);
|
|
49
49
|
|
|
50
|
-
// TODO(burdon): Persistent history
|
|
50
|
+
// TODO(burdon): Persistent history (non-space ECHO data?)
|
|
51
51
|
const [history, setHistory] = useState<Message[]>([]);
|
|
52
52
|
|
|
53
53
|
const scrollerRef = useRef<HTMLDivElement>(null);
|
|
@@ -215,62 +215,55 @@ export const DebugPanel = ({ classNames, functionUrl, binding: _binding, onBindi
|
|
|
215
215
|
);
|
|
216
216
|
};
|
|
217
217
|
|
|
218
|
+
const RobotAvatar = () => (
|
|
219
|
+
<Avatar.Root size={6} variant='circle'>
|
|
220
|
+
<Avatar.Frame>
|
|
221
|
+
<Avatar.Icon icon='ph--robot--regular' />
|
|
222
|
+
</Avatar.Frame>
|
|
223
|
+
</Avatar.Root>
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message }>) => {
|
|
227
|
+
const { text, data, error } = message;
|
|
228
|
+
if (error) {
|
|
229
|
+
return <span className={mx(classNames, 'whitespace-pre text-error')}>{String(error)}</span>;
|
|
230
|
+
} else if (data) {
|
|
231
|
+
return (
|
|
232
|
+
<SyntaxHighlighter language='json' className={mx('text-xs', classNames)}>
|
|
233
|
+
{JSON.stringify(data, null, 2)}
|
|
234
|
+
</SyntaxHighlighter>
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return <span className={mx(classNames)}>{text || '\u00D8'}</span>;
|
|
239
|
+
};
|
|
240
|
+
|
|
218
241
|
// TODO(burdon): Replace with thread?
|
|
219
242
|
// TODO(burdon): Button to delete individual messages.
|
|
220
|
-
// TODO(burdon): Button to
|
|
243
|
+
// TODO(burdon): Button to re-run question.
|
|
221
244
|
const MessageThread = ({ state, result, history }: { state: State | null; result: string; history: Message[] }) => {
|
|
222
245
|
return (
|
|
223
246
|
<>
|
|
224
247
|
{history.map((message, i) => (
|
|
225
|
-
<div key={i} className='grid grid-cols-[
|
|
226
|
-
<div
|
|
227
|
-
<div className='
|
|
228
|
-
<MessageItem
|
|
248
|
+
<div key={i} className='grid grid-cols-[3rem_1fr]'>
|
|
249
|
+
<div>{message.type === 'response' && <RobotAvatar />}</div>
|
|
250
|
+
<div className={mx('flex', message.type === 'request' && 'justify-end')}>
|
|
251
|
+
<MessageItem
|
|
252
|
+
classNames={[message.type === 'request' && 'p-1 px-2 rounded-lg bg-hoverSurface']}
|
|
253
|
+
message={message}
|
|
254
|
+
/>
|
|
229
255
|
</div>
|
|
230
256
|
</div>
|
|
231
257
|
))}
|
|
232
|
-
|
|
233
|
-
<div
|
|
234
|
-
<
|
|
235
|
-
|
|
236
|
-
<Icon icon='ph--robot--regular' size={6} classNames='animate-[pulse_1s_ease-in-out_infinite]' />
|
|
237
|
-
)}
|
|
238
|
-
</div>
|
|
239
|
-
<div className='overflow-auto'>
|
|
240
|
-
<MessageItem message={{ type: 'response', text: result }} />
|
|
241
|
-
</div>
|
|
258
|
+
<div className='grid grid-cols-[3rem_1fr]'>
|
|
259
|
+
<div>
|
|
260
|
+
{(state === 'pending' && <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin-slow' />) ||
|
|
261
|
+
(result.length > 0 && <RobotAvatar />)}
|
|
242
262
|
</div>
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
);
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
const MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message }>) => {
|
|
249
|
-
const { type, text, data, error } = message;
|
|
250
|
-
const wrapper = 'p-1 px-2 rounded-lg bg-hoverSurface overflow-auto';
|
|
251
|
-
return (
|
|
252
|
-
<div className={mx('flex', type === 'request' ? 'ml-[8rem] justify-end' : 'mr-[8rem]', classNames)}>
|
|
253
|
-
{error && <div className={mx(wrapper, 'whitespace-pre text-error')}>{String(error)}</div>}
|
|
254
|
-
|
|
255
|
-
{text !== undefined && (
|
|
256
|
-
<div className={mx(wrapper, type === 'request' && 'bg-primary-400 dark:bg-primary-600')}>
|
|
257
|
-
{text || '\u00D8'}
|
|
263
|
+
<div>
|
|
264
|
+
<span>{result}</span>
|
|
258
265
|
</div>
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
{data && (
|
|
262
|
-
<SyntaxHighlighter language='json' className={mx(wrapper, 'px-8 py-2 text-xs')}>
|
|
263
|
-
{JSON.stringify(data, null, 2)}
|
|
264
|
-
</SyntaxHighlighter>
|
|
265
|
-
)}
|
|
266
|
-
</div>
|
|
266
|
+
</div>
|
|
267
|
+
</>
|
|
267
268
|
);
|
|
268
269
|
};
|
|
269
|
-
|
|
270
|
-
const RobotAvatar = () => (
|
|
271
|
-
<Avatar.Root size={6} variant='circle'>
|
|
272
|
-
<Avatar.Frame>
|
|
273
|
-
<Avatar.Icon icon='ph--robot--regular' />
|
|
274
|
-
</Avatar.Frame>
|
|
275
|
-
</Avatar.Root>
|
|
276
|
-
);
|
|
@@ -11,7 +11,7 @@ import { baseSurface, mx } from '@dxos/react-ui-theme';
|
|
|
11
11
|
import { createProtoRpcPeer } from '@dxos/rpc';
|
|
12
12
|
import { createIFramePort } from '@dxos/rpc-tunnel';
|
|
13
13
|
|
|
14
|
-
import { type BundlerResult } from '
|
|
14
|
+
import { type BundlerResult } from '../../../bundler';
|
|
15
15
|
|
|
16
16
|
export type FrameContainerProps = {
|
|
17
17
|
containerUrl: string;
|
|
@@ -3,20 +3,19 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
|
-
|
|
7
6
|
import React, { useEffect, useMemo } from 'react';
|
|
8
7
|
|
|
9
8
|
import { createSpaceObjectGenerator, TestSchemaType } from '@dxos/echo-generator';
|
|
10
9
|
import { TextType } from '@dxos/plugin-markdown/types';
|
|
11
10
|
import { useClient } from '@dxos/react-client';
|
|
12
|
-
import { create,
|
|
11
|
+
import { create, createEchoObject, useSpaces } from '@dxos/react-client/echo';
|
|
13
12
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
14
13
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
15
14
|
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
import mainUrl from './FrameContainer/frame?url';
|
|
16
17
|
import { ScriptBlock } from './ScriptBlock';
|
|
17
18
|
import { ScriptType } from '../../types';
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
import mainUrl from '../FrameContainer/frame?url';
|
|
20
19
|
|
|
21
20
|
const code = [
|
|
22
21
|
"import { Filter, useQuery, useSpaces} from '@dxos/react-client/echo';",
|
|
@@ -52,7 +51,10 @@ const Story = () => {
|
|
|
52
51
|
}, [client]);
|
|
53
52
|
|
|
54
53
|
// TODO(burdon): Review what's the right way to create automerge-backed objects.
|
|
55
|
-
const object = useMemo(
|
|
54
|
+
const object = useMemo(
|
|
55
|
+
() => createEchoObject(create(ScriptType, { source: create(TextType, { content: code }) })),
|
|
56
|
+
[],
|
|
57
|
+
);
|
|
56
58
|
|
|
57
59
|
// TODO(dmaretskyi): Not sure how to provide `containerUrl` here since the html now lives in composer-app.
|
|
58
60
|
// TODO(burdon): Normalize html/frame.tsx with composer-app to test locally.
|
|
@@ -62,7 +64,7 @@ const Story = () => {
|
|
|
62
64
|
export default {
|
|
63
65
|
title: 'plugin-script/ScriptBlock',
|
|
64
66
|
component: ScriptBlock,
|
|
65
|
-
decorators: [
|
|
67
|
+
decorators: [withTheme, withLayout({ fullscreen: true, tooltips: true }), withClientProvider({ createSpace: true })],
|
|
66
68
|
render: Story,
|
|
67
69
|
};
|
|
68
70
|
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Check, Play, Warning } from '@phosphor-icons/react';
|
|
5
6
|
// @ts-ignore
|
|
6
7
|
import wasmUrl from 'esbuild-wasm/esbuild.wasm?url';
|
|
7
8
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
8
9
|
|
|
9
10
|
import { createDocAccessor, DocAccessor } from '@dxos/react-client/echo';
|
|
10
|
-
import { DensityProvider, Toolbar, Button
|
|
11
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
11
|
+
import { DensityProvider, Toolbar, Button } from '@dxos/react-ui';
|
|
12
|
+
import { mx, getSize } from '@dxos/react-ui-theme';
|
|
12
13
|
|
|
14
|
+
import { FrameContainer } from './FrameContainer';
|
|
15
|
+
import { Splitter, SplitterSelector, type View } from './Splitter';
|
|
13
16
|
import { Bundler, type BundlerResult, initializeBundler } from '../../bundler';
|
|
14
17
|
import { type ScriptType } from '../../types';
|
|
15
|
-
import { FrameContainer } from '../FrameContainer';
|
|
16
18
|
import { ScriptEditor } from '../ScriptEditor';
|
|
17
19
|
|
|
18
20
|
// Keep in sync with packages/apps/composer-app/script-frame/main.tsx .
|
|
@@ -27,6 +29,7 @@ const PROVIDED_MODULES = [
|
|
|
27
29
|
|
|
28
30
|
export type ScriptBlockProps = {
|
|
29
31
|
script: ScriptType;
|
|
32
|
+
view?: View;
|
|
30
33
|
hideSelector?: boolean;
|
|
31
34
|
classes?: {
|
|
32
35
|
root?: string;
|
|
@@ -41,8 +44,17 @@ export type ScriptBlockProps = {
|
|
|
41
44
|
* @deprecated
|
|
42
45
|
*/
|
|
43
46
|
// TODO(burdon): Cache compiled results in context.
|
|
44
|
-
export const ScriptBlock = ({
|
|
47
|
+
export const ScriptBlock = ({
|
|
48
|
+
script,
|
|
49
|
+
view: controlledView,
|
|
50
|
+
hideSelector,
|
|
51
|
+
classes,
|
|
52
|
+
containerUrl,
|
|
53
|
+
}: ScriptBlockProps) => {
|
|
45
54
|
const source = useMemo(() => script.source && createDocAccessor(script.source, ['content']), [script.source]);
|
|
55
|
+
const [view, setView] = useState<View>(controlledView ?? 'editor');
|
|
56
|
+
useEffect(() => handleSetView(controlledView ?? 'editor'), [controlledView]);
|
|
57
|
+
|
|
46
58
|
const [result, setResult] = useState<BundlerResult>();
|
|
47
59
|
const bundler = useMemo(
|
|
48
60
|
() => new Bundler({ platform: 'browser', sandboxedModules: PROVIDED_MODULES, remoteModules: {} }),
|
|
@@ -66,6 +78,16 @@ export const ScriptBlock = ({ script, hideSelector, classes, containerUrl }: Scr
|
|
|
66
78
|
return () => clearTimeout(t);
|
|
67
79
|
}, [source]);
|
|
68
80
|
|
|
81
|
+
const handleSetView = useCallback(
|
|
82
|
+
(view: View) => {
|
|
83
|
+
setView(view);
|
|
84
|
+
if (!result && view !== 'editor') {
|
|
85
|
+
void handleExec(false);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
[result],
|
|
89
|
+
);
|
|
90
|
+
|
|
69
91
|
const handleExec = useCallback(
|
|
70
92
|
async (auto = true) => {
|
|
71
93
|
if (!source) {
|
|
@@ -73,8 +95,11 @@ export const ScriptBlock = ({ script, hideSelector, classes, containerUrl }: Scr
|
|
|
73
95
|
}
|
|
74
96
|
const result = await bundler.bundle(DocAccessor.getValue(source));
|
|
75
97
|
setResult(result);
|
|
98
|
+
if (auto && view === 'editor') {
|
|
99
|
+
setView('preview');
|
|
100
|
+
}
|
|
76
101
|
},
|
|
77
|
-
[source],
|
|
102
|
+
[source, view],
|
|
78
103
|
);
|
|
79
104
|
|
|
80
105
|
return (
|
|
@@ -82,28 +107,29 @@ export const ScriptBlock = ({ script, hideSelector, classes, containerUrl }: Scr
|
|
|
82
107
|
{!hideSelector && (
|
|
83
108
|
<DensityProvider density='fine'>
|
|
84
109
|
<Toolbar.Root classNames={mx('mb-2', classes?.toolbar)}>
|
|
110
|
+
<SplitterSelector view={view} onChange={handleSetView} />
|
|
85
111
|
<div className='grow' />
|
|
86
112
|
{result?.bundle && !result?.error && (
|
|
87
113
|
<div title={String(result.error)}>
|
|
88
|
-
<
|
|
114
|
+
<Check className={mx(getSize(5), 'text-green-500')} />
|
|
89
115
|
</div>
|
|
90
116
|
)}
|
|
91
117
|
{result?.error && (
|
|
92
118
|
<div title={String(result.error)}>
|
|
93
|
-
<
|
|
119
|
+
<Warning className={mx(getSize(5), 'text-orange-500')} />
|
|
94
120
|
</div>
|
|
95
121
|
)}
|
|
96
122
|
<Button variant='ghost' onClick={() => handleExec()}>
|
|
97
|
-
<
|
|
123
|
+
<Play className={getSize(5)} />
|
|
98
124
|
</Button>
|
|
99
125
|
</Toolbar.Root>
|
|
100
126
|
</DensityProvider>
|
|
101
127
|
)}
|
|
102
128
|
|
|
103
|
-
<
|
|
129
|
+
<Splitter view={view}>
|
|
104
130
|
<ScriptEditor script={script} />
|
|
105
131
|
{result && <FrameContainer key={script.id} result={result} containerUrl={containerUrl} />}
|
|
106
|
-
</
|
|
132
|
+
</Splitter>
|
|
107
133
|
</div>
|
|
108
134
|
);
|
|
109
135
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import React, { useState } from 'react';
|
|
8
|
+
|
|
9
|
+
import { DensityProvider } from '@dxos/react-ui';
|
|
10
|
+
|
|
11
|
+
import { Splitter, SplitterSelector, type View } from './Splitter';
|
|
12
|
+
|
|
13
|
+
const Story = () => {
|
|
14
|
+
const [view, setView] = useState<View>();
|
|
15
|
+
return (
|
|
16
|
+
<div>
|
|
17
|
+
<DensityProvider density='fine'>
|
|
18
|
+
<SplitterSelector view={view} onChange={setView} />
|
|
19
|
+
</DensityProvider>
|
|
20
|
+
<Splitter view={view}>
|
|
21
|
+
<div>1</div>
|
|
22
|
+
<div>2</div>
|
|
23
|
+
</Splitter>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default {
|
|
29
|
+
title: 'plugin-script/Splitter',
|
|
30
|
+
component: Splitter,
|
|
31
|
+
render: Story,
|
|
32
|
+
parameters: {
|
|
33
|
+
layout: 'fullscreen',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const Default = {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Code, SquareSplitHorizontal, Eye } from '@phosphor-icons/react';
|
|
6
|
+
import React, { type ReactNode } from 'react';
|
|
7
|
+
|
|
8
|
+
import { ToggleGroup, ToggleGroupItem, Toolbar } from '@dxos/react-ui';
|
|
9
|
+
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
10
|
+
|
|
11
|
+
export type View = 'editor' | 'preview' | 'split';
|
|
12
|
+
|
|
13
|
+
export type SplitterProps = {
|
|
14
|
+
view?: View;
|
|
15
|
+
className?: string;
|
|
16
|
+
children?: ReactNode[];
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// TODO(burdon): Surfaces?
|
|
20
|
+
export const Splitter = ({ view = 'split', className, children = [] }: SplitterProps) => {
|
|
21
|
+
const [left, right] = children;
|
|
22
|
+
return (
|
|
23
|
+
<div className={mx('flex overflow-hidden grow', className)}>
|
|
24
|
+
{left && view !== 'preview' && <div className='flex flex-1 shrink-0 overflow-hidden'>{left}</div>}
|
|
25
|
+
{right && view !== 'editor' && <div className='flex flex-1 shrink-0 overflow-hidden'>{right}</div>}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type SplitterSelectorProps = {
|
|
31
|
+
view?: View;
|
|
32
|
+
onChange?: (view: View) => void;
|
|
33
|
+
className?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const SplitterSelector = ({ view, onChange, className }: SplitterSelectorProps) => {
|
|
37
|
+
return (
|
|
38
|
+
<Toolbar.Root classNames={className}>
|
|
39
|
+
<ToggleGroup type='single' value={view} onValueChange={(value) => onChange?.(value as View)}>
|
|
40
|
+
<ToggleGroupItem value='editor'>
|
|
41
|
+
<Code className={getSize(5)} />
|
|
42
|
+
</ToggleGroupItem>
|
|
43
|
+
<ToggleGroupItem value='split'>
|
|
44
|
+
<SquareSplitHorizontal className={getSize(5)} />
|
|
45
|
+
</ToggleGroupItem>
|
|
46
|
+
<ToggleGroupItem value='preview'>
|
|
47
|
+
<Eye className={getSize(5)} />
|
|
48
|
+
</ToggleGroupItem>
|
|
49
|
+
</ToggleGroup>
|
|
50
|
+
</Toolbar.Root>
|
|
51
|
+
);
|
|
52
|
+
};
|