@dxos/plugin-script 0.6.12-main.ed7cda7 → 0.6.12-staging.0b4bb48
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/dist/lib/browser/{ScriptContainer-7DE7USCY.mjs → ScriptEditor-5Y3EROG3.mjs} +106 -257
- 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-MDX7ACIK.mjs → chunk-JBACGDOJ.mjs} +6 -3
- 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-CAEANETO.mjs → chunk-O4LWBX6A.mjs} +2 -2
- package/dist/lib/browser/{chunk-CAEANETO.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 +61 -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-OJ77BZRH.cjs → TypescriptEditor-M3WWFIP2.cjs} +8 -19
- 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-2PZKJXNP.cjs → chunk-5RBVXKXT.cjs} +6 -6
- package/dist/lib/node/{chunk-2PZKJXNP.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 +79 -93
- 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 +4 -1
- 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 +49 -54
- package/src/ScriptPlugin.tsx +36 -21
- 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 +3 -4
- 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} +28 -7
- 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 +6 -2
- package/src/translations.ts +0 -2
- package/src/types/types.ts +5 -9
- package/dist/lib/browser/ScriptContainer-7DE7USCY.mjs.map +0 -7
- package/dist/lib/browser/chunk-G6FWCTGT.mjs.map +0 -7
- package/dist/lib/browser/chunk-MDX7ACIK.mjs.map +0 -7
- package/dist/lib/node/ScriptContainer-J76LKPAM.cjs +0 -667
- package/dist/lib/node/ScriptContainer-J76LKPAM.cjs.map +0 -7
- package/dist/lib/node/chunk-ACLCRWDB.cjs.map +0 -7
- package/dist/lib/node/chunk-OJ77BZRH.cjs.map +0 -7
- package/dist/lib/node/chunk-UZ3ZXEBF.cjs.map +0 -7
- package/dist/lib/node-esm/ScriptContainer-F6ACEA63.mjs +0 -665
- package/dist/lib/node-esm/ScriptContainer-F6ACEA63.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-7BZDZF7Z.mjs +0 -47
- package/dist/lib/node-esm/chunk-7BZDZF7Z.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/chunk-TZ3Z4SII.mjs +0 -20
- package/dist/lib/node-esm/chunk-TZ3Z4SII.mjs.map +0 -7
- package/dist/lib/node-esm/edge/index.mjs +0 -22
- package/dist/lib/node-esm/index.mjs +0 -311
- 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/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
|
@@ -17,9 +17,8 @@ import { loadObjectReferences } from '@dxos/react-client/echo';
|
|
|
17
17
|
|
|
18
18
|
import { initializeBundler } from './bundler';
|
|
19
19
|
import { Compiler } from './compiler';
|
|
20
|
-
import {
|
|
20
|
+
import { ScriptEditor } from './components';
|
|
21
21
|
import meta, { SCRIPT_PLUGIN } from './meta';
|
|
22
|
-
import { templates } from './templates';
|
|
23
22
|
import translations from './translations';
|
|
24
23
|
import { FunctionType, ScriptType } from './types';
|
|
25
24
|
import { ScriptAction, type ScriptPluginProvides } from './types';
|
|
@@ -46,12 +45,12 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
46
45
|
await initializeBundler({ wasmUrl });
|
|
47
46
|
},
|
|
48
47
|
provides: {
|
|
49
|
-
settings: {},
|
|
50
48
|
metadata: {
|
|
51
49
|
records: {
|
|
52
50
|
[ScriptType.typename]: {
|
|
53
51
|
placeholder: ['object title placeholder', { ns: SCRIPT_PLUGIN }],
|
|
54
52
|
icon: (props: IconProps) => <Code {...props} />,
|
|
53
|
+
iconSymbol: 'ph--code--regular',
|
|
55
54
|
// TODO(wittjosiah): Move out of metadata.
|
|
56
55
|
loadReferences: (script: ScriptType) => loadObjectReferences(script, (script) => [script.source]),
|
|
57
56
|
},
|
|
@@ -61,12 +60,6 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
61
60
|
echo: {
|
|
62
61
|
schema: [ScriptType, FunctionType],
|
|
63
62
|
},
|
|
64
|
-
space: {
|
|
65
|
-
onSpaceCreate: {
|
|
66
|
-
label: ['create object label', { ns: SCRIPT_PLUGIN }],
|
|
67
|
-
action: ScriptAction.CREATE,
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
63
|
graph: {
|
|
71
64
|
builder: (plugins) => {
|
|
72
65
|
const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
|
|
@@ -100,7 +93,8 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
100
93
|
},
|
|
101
94
|
properties: {
|
|
102
95
|
label: ['create object label', { ns: SCRIPT_PLUGIN }],
|
|
103
|
-
icon:
|
|
96
|
+
icon: (props: IconProps) => <Code {...props} />,
|
|
97
|
+
iconSymbol: 'ph--code--regular',
|
|
104
98
|
testId: 'scriptPlugin.createObject',
|
|
105
99
|
},
|
|
106
100
|
},
|
|
@@ -109,19 +103,29 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
109
103
|
});
|
|
110
104
|
},
|
|
111
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
|
+
},
|
|
112
121
|
surface: {
|
|
113
122
|
component: ({ data, role }) => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
123
|
+
if (role && !['article', 'section'].includes(role)) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
118
126
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return <ScriptContainer script={data.object} env={compiler.environment} />;
|
|
122
|
-
}
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
127
|
+
if (data.object instanceof ScriptType) {
|
|
128
|
+
return <ScriptEditor env={compiler.environment} script={data.object} role={role} />;
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
return null;
|
|
@@ -131,7 +135,7 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
131
135
|
resolver: (intent) => {
|
|
132
136
|
switch (intent.action) {
|
|
133
137
|
case ScriptAction.CREATE: {
|
|
134
|
-
return { data: create(ScriptType, { source: create(TextType, { content:
|
|
138
|
+
return { data: create(ScriptType, { source: create(TextType, { content: example }) }) };
|
|
135
139
|
}
|
|
136
140
|
}
|
|
137
141
|
},
|
|
@@ -139,3 +143,14 @@ export const ScriptPlugin = (): PluginDefinition<ScriptPluginProvides> => {
|
|
|
139
143
|
},
|
|
140
144
|
};
|
|
141
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,7 +3,6 @@
|
|
|
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';
|
|
@@ -13,10 +12,10 @@ 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';",
|
|
@@ -65,7 +64,7 @@ const Story = () => {
|
|
|
65
64
|
export default {
|
|
66
65
|
title: 'plugin-script/ScriptBlock',
|
|
67
66
|
component: ScriptBlock,
|
|
68
|
-
decorators: [
|
|
67
|
+
decorators: [withTheme, withLayout({ fullscreen: true, tooltips: true }), withClientProvider({ createSpace: true })],
|
|
69
68
|
render: Story,
|
|
70
69
|
};
|
|
71
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
|
+
};
|
|
@@ -10,14 +10,23 @@ import React, { useCallback, useMemo, useState } from 'react';
|
|
|
10
10
|
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { useClient } from '@dxos/react-client';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
create,
|
|
15
|
+
createDocAccessor,
|
|
16
|
+
Filter,
|
|
17
|
+
fullyQualifiedId,
|
|
18
|
+
getMeta,
|
|
19
|
+
getSpace,
|
|
20
|
+
useQuery,
|
|
21
|
+
} from '@dxos/react-client/echo';
|
|
14
22
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
15
|
-
import { useTranslation
|
|
23
|
+
import { useTranslation } from '@dxos/react-ui';
|
|
24
|
+
import { useHasAttention } from '@dxos/react-ui-attention';
|
|
16
25
|
import { createDataExtensions, listener } from '@dxos/react-ui-editor';
|
|
17
26
|
import { mx } from '@dxos/react-ui-theme';
|
|
18
27
|
|
|
19
28
|
import { DebugPanel } from './DebugPanel';
|
|
20
|
-
import {
|
|
29
|
+
import { Toolbar } from './Toolbar';
|
|
21
30
|
import { TypescriptEditor, type TypescriptEditorProps } from './TypescriptEditor';
|
|
22
31
|
import { Bundler } from '../bundler';
|
|
23
32
|
import {
|
|
@@ -25,19 +34,18 @@ import {
|
|
|
25
34
|
publicKeyToDid,
|
|
26
35
|
setUserFunctionUrlInMetadata,
|
|
27
36
|
uploadWorkerFunction,
|
|
28
|
-
USERFUNCTIONS_PRESET_META_KEY,
|
|
29
37
|
} from '../edge';
|
|
30
38
|
import { SCRIPT_PLUGIN } from '../meta';
|
|
31
|
-
import { templates } from '../templates';
|
|
32
39
|
import { FunctionType, type ScriptType } from '../types';
|
|
33
40
|
|
|
34
|
-
export type ScriptEditorProps =
|
|
41
|
+
export type ScriptEditorProps = {
|
|
35
42
|
script: ScriptType;
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
role?: string;
|
|
44
|
+
} & Pick<TypescriptEditorProps, 'env'>;
|
|
38
45
|
|
|
39
|
-
export const ScriptEditor = ({
|
|
46
|
+
export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
40
47
|
const { t } = useTranslation(SCRIPT_PLUGIN);
|
|
48
|
+
const hasAttention = useHasAttention(fullyQualifiedId(script));
|
|
41
49
|
const client = useClient();
|
|
42
50
|
const identity = useIdentity();
|
|
43
51
|
const space = getSpace(script);
|
|
@@ -65,7 +73,7 @@ export const ScriptEditor = ({ classNames, script, env }: ScriptEditorProps) =>
|
|
|
65
73
|
[script, script.source, space, identity],
|
|
66
74
|
);
|
|
67
75
|
|
|
68
|
-
const [
|
|
76
|
+
const [showPanel, setShowPanel] = useState(false);
|
|
69
77
|
const initialValue = useMemo(() => script.source?.content, [script.source]);
|
|
70
78
|
const existingFunctionUrl = fn && getUserFunctionUrlInMetadata(getMeta(fn));
|
|
71
79
|
const [error, setError] = useState<string>();
|
|
@@ -95,22 +103,6 @@ export const ScriptEditor = ({ classNames, script, env }: ScriptEditorProps) =>
|
|
|
95
103
|
}
|
|
96
104
|
}, [script.source]);
|
|
97
105
|
|
|
98
|
-
const handleTemplateChange: TemplateSelectProps['onTemplateSelect'] = (id) => {
|
|
99
|
-
const template = templates.find((template) => template.id === id);
|
|
100
|
-
if (template) {
|
|
101
|
-
script.name = template.name;
|
|
102
|
-
script.source!.content = template.source;
|
|
103
|
-
const metaKeys = getMeta(script).keys;
|
|
104
|
-
const oldPresetIndex = metaKeys.findIndex((key) => key.source === USERFUNCTIONS_PRESET_META_KEY);
|
|
105
|
-
if (oldPresetIndex >= 0) {
|
|
106
|
-
metaKeys.splice(oldPresetIndex, 1);
|
|
107
|
-
}
|
|
108
|
-
if (template.presetId) {
|
|
109
|
-
metaKeys.push({ source: USERFUNCTIONS_PRESET_META_KEY, id: template.presetId });
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
106
|
const handleDeploy = useCallback(async () => {
|
|
115
107
|
if (!script.source || !identity || !space) {
|
|
116
108
|
return;
|
|
@@ -122,7 +114,11 @@ export const ScriptEditor = ({ classNames, script, env }: ScriptEditorProps) =>
|
|
|
122
114
|
const existingFunctionId = existingFunctionUrl?.split('/').at(-1);
|
|
123
115
|
const ownerDid = (existingFunctionUrl?.split('/').at(-2) as DID) ?? publicKeyToDid(identity.identityKey);
|
|
124
116
|
|
|
125
|
-
const bundler = new Bundler({
|
|
117
|
+
const bundler = new Bundler({
|
|
118
|
+
platform: 'browser',
|
|
119
|
+
sandboxedModules: [],
|
|
120
|
+
remoteModules: {},
|
|
121
|
+
});
|
|
126
122
|
const buildResult = await bundler.bundle(script.source.content);
|
|
127
123
|
if (buildResult.error || !buildResult.bundle) {
|
|
128
124
|
throw buildResult.error;
|
|
@@ -138,18 +134,15 @@ export const ScriptEditor = ({ classNames, script, env }: ScriptEditorProps) =>
|
|
|
138
134
|
if (result !== 'success' || functionId === undefined || functionVersionNumber === undefined) {
|
|
139
135
|
throw new Error(errorMessage);
|
|
140
136
|
}
|
|
141
|
-
|
|
142
137
|
log.info('function uploaded', { functionId, functionVersionNumber });
|
|
143
138
|
if (fn) {
|
|
144
139
|
fn.version = functionVersionNumber;
|
|
145
140
|
}
|
|
146
|
-
|
|
147
141
|
const deployedFunction =
|
|
148
142
|
fn ?? space.db.add(create(FunctionType, { version: functionVersionNumber, source: script }));
|
|
149
143
|
const meta = getMeta(deployedFunction);
|
|
150
|
-
script.changed = false;
|
|
151
144
|
setUserFunctionUrlInMetadata(meta, `/${ownerDid}/${functionId}`);
|
|
152
|
-
|
|
145
|
+
script.changed = false;
|
|
153
146
|
} catch (err: any) {
|
|
154
147
|
log.catch(err);
|
|
155
148
|
setError(t('upload failed label'));
|
|
@@ -172,32 +165,38 @@ export const ScriptEditor = ({ classNames, script, env }: ScriptEditorProps) =>
|
|
|
172
165
|
}, [existingFunctionUrl, space]);
|
|
173
166
|
|
|
174
167
|
return (
|
|
175
|
-
<div
|
|
168
|
+
<div
|
|
169
|
+
role='none'
|
|
170
|
+
className={mx(
|
|
171
|
+
'flex flex-col is-full bs-full overflow-hidden',
|
|
172
|
+
role === 'article' && 'row-span-2',
|
|
173
|
+
hasAttention && 'attention-surface',
|
|
174
|
+
)}
|
|
175
|
+
>
|
|
176
|
+
<TypescriptEditor
|
|
177
|
+
id={script.id}
|
|
178
|
+
env={env}
|
|
179
|
+
initialValue={initialValue}
|
|
180
|
+
extensions={extensions}
|
|
181
|
+
className='flex is-full bs-full overflow-hidden ch-focus-ring-inset-over-all'
|
|
182
|
+
/>
|
|
183
|
+
|
|
176
184
|
<Toolbar
|
|
185
|
+
classNames='border-t border-separator'
|
|
177
186
|
deployed={Boolean(existingFunctionUrl) && !script.changed}
|
|
178
187
|
functionUrl={functionUrl}
|
|
179
188
|
error={error}
|
|
180
|
-
|
|
181
|
-
templates={templates}
|
|
189
|
+
showPanel={showPanel}
|
|
182
190
|
onDeploy={handleDeploy}
|
|
183
191
|
onFormat={handleFormat}
|
|
184
|
-
|
|
185
|
-
onTemplateSelect={handleTemplateChange}
|
|
192
|
+
onTogglePanel={async () => setShowPanel((showDetails) => !showDetails)}
|
|
186
193
|
/>
|
|
187
194
|
|
|
188
|
-
{
|
|
189
|
-
<TypescriptEditor
|
|
190
|
-
id={script.id}
|
|
191
|
-
env={env}
|
|
192
|
-
initialValue={initialValue}
|
|
193
|
-
extensions={extensions}
|
|
194
|
-
className='flex is-full bs-full overflow-hidden ch-focus-ring-inset-over-all'
|
|
195
|
-
/>
|
|
196
|
-
)}
|
|
197
|
-
|
|
198
|
-
{view !== 'editor' && (
|
|
195
|
+
{showPanel && (
|
|
199
196
|
<DebugPanel functionUrl={functionUrl} binding={fn?.binding} onBindingChange={handleBindingChange} />
|
|
200
197
|
)}
|
|
201
198
|
</div>
|
|
202
199
|
);
|
|
203
200
|
};
|
|
201
|
+
|
|
202
|
+
export default ScriptEditor;
|