@dxos/plugin-script 0.6.13-staging.1e988a3 → 0.6.14-main.7bd9c89
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/AutomationPanel-LJD3HE2U.mjs +78 -0
- package/dist/lib/browser/AutomationPanel-LJD3HE2U.mjs.map +7 -0
- package/dist/lib/browser/ScriptContainer-B3CPWXRE.mjs +423 -0
- package/dist/lib/browser/ScriptContainer-B3CPWXRE.mjs.map +7 -0
- package/dist/lib/browser/chunk-G66MXS4T.mjs +248 -0
- package/dist/lib/browser/chunk-G66MXS4T.mjs.map +7 -0
- package/dist/lib/browser/{chunk-RHEZ5LUU.mjs → chunk-G6H56WFS.mjs} +51 -2
- package/dist/lib/browser/{chunk-RHEZ5LUU.mjs.map → chunk-G6H56WFS.mjs.map} +4 -4
- package/dist/lib/browser/{chunk-DL5XQRQM.mjs → chunk-KHNN3F7J.mjs} +18 -6
- package/dist/lib/browser/chunk-KHNN3F7J.mjs.map +7 -0
- package/dist/lib/browser/{chunk-O4LWBX6A.mjs → chunk-KXVQPS4Y.mjs} +2 -2
- package/dist/lib/browser/{chunk-O4LWBX6A.mjs.map → chunk-KXVQPS4Y.mjs.map} +2 -2
- package/dist/lib/browser/chunk-SGQHRB4P.mjs +17 -0
- package/dist/lib/browser/chunk-SGQHRB4P.mjs.map +7 -0
- package/dist/lib/browser/edge/index.mjs +5 -1
- package/dist/lib/browser/index.mjs +86 -61
- 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/AutomationPanel-2U3LW3J4.cjs +100 -0
- package/dist/lib/node/AutomationPanel-2U3LW3J4.cjs.map +7 -0
- package/dist/lib/node/ScriptContainer-BV7HMUY5.cjs +425 -0
- package/dist/lib/node/ScriptContainer-BV7HMUY5.cjs.map +7 -0
- package/dist/lib/node/{chunk-5RBVXKXT.cjs → chunk-25PQE7FL.cjs} +6 -6
- package/dist/lib/node/{chunk-5RBVXKXT.cjs.map → chunk-25PQE7FL.cjs.map} +2 -2
- package/dist/lib/node/{chunk-4GTXIELQ.cjs → chunk-ACLCRWDB.cjs} +44 -6
- package/dist/lib/node/chunk-ACLCRWDB.cjs.map +7 -0
- package/dist/lib/node/{TypescriptEditor-M3WWFIP2.cjs → chunk-EJC55SDD.cjs} +18 -8
- package/dist/lib/node/chunk-EJC55SDD.cjs.map +7 -0
- package/dist/lib/node/{chunk-PFH3ROEH.cjs → chunk-FY5KKL5N.cjs} +22 -8
- package/dist/lib/node/chunk-FY5KKL5N.cjs.map +7 -0
- package/dist/lib/node/chunk-JWKMTYYH.cjs +277 -0
- package/dist/lib/node/chunk-JWKMTYYH.cjs.map +7 -0
- package/dist/lib/node/edge/index.cjs +12 -8
- package/dist/lib/node/edge/index.cjs.map +2 -2
- package/dist/lib/node/index.cjs +103 -82
- 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/lib/node-esm/AutomationPanel-FS47OF3I.mjs +79 -0
- package/dist/lib/node-esm/AutomationPanel-FS47OF3I.mjs.map +7 -0
- package/dist/lib/node-esm/ScriptContainer-HSIOGVP3.mjs +424 -0
- package/dist/lib/node-esm/ScriptContainer-HSIOGVP3.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-3QHVR4VV.mjs +249 -0
- package/dist/lib/node-esm/chunk-3QHVR4VV.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-7EDYDVQH.mjs +47 -0
- package/dist/lib/node-esm/chunk-7EDYDVQH.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-GO7HYFM5.mjs +19 -0
- package/dist/lib/node-esm/chunk-GO7HYFM5.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-LDLNTVAK.mjs +280 -0
- package/dist/lib/node-esm/chunk-LDLNTVAK.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-QMTTZYLF.mjs +255 -0
- package/dist/lib/node-esm/chunk-QMTTZYLF.mjs.map +7 -0
- package/dist/lib/node-esm/edge/index.mjs +24 -0
- package/dist/lib/node-esm/index.mjs +317 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/meta.mjs +10 -0
- package/dist/lib/node-esm/meta.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +13 -0
- package/dist/lib/node-esm/types/index.mjs.map +7 -0
- package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +17 -0
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -0
- package/dist/types/src/components/AutomationPanel/index.d.ts +4 -0
- package/dist/types/src/components/AutomationPanel/index.d.ts.map +1 -0
- package/dist/types/src/components/{DebugPanel.d.ts → DebugPanel/DebugPanel.d.ts} +2 -1
- package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +1 -0
- package/dist/types/src/components/DebugPanel/index.d.ts +2 -0
- package/dist/types/src/components/DebugPanel/index.d.ts.map +1 -0
- package/dist/types/src/components/{ScriptBlock/FrameContainer → FrameContainer}/FrameContainer.d.ts +1 -1
- package/dist/types/src/components/FrameContainer/FrameContainer.d.ts.map +1 -0
- package/dist/types/src/components/FrameContainer/frame.d.ts.map +1 -0
- package/dist/types/src/components/FrameContainer/index.d.ts.map +1 -0
- package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts +1 -3
- package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts.map +1 -1
- package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts +3 -8
- package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScriptContainer.d.ts +5 -0
- package/dist/types/src/components/ScriptContainer.d.ts.map +1 -0
- package/dist/types/src/components/ScriptEditor.d.ts +4 -5
- package/dist/types/src/components/ScriptEditor.d.ts.map +1 -1
- package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts +6 -0
- package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +1 -0
- package/dist/types/src/components/ScriptSettings/index.d.ts +2 -0
- package/dist/types/src/components/ScriptSettings/index.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +23 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +14 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/index.d.ts +2 -0
- package/dist/types/src/components/Toolbar/index.d.ts.map +1 -0
- package/dist/types/src/components/{TypescriptEditor.d.ts → TypescriptEditor/TypescriptEditor.d.ts} +1 -2
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -0
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts +6 -0
- package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/TypescriptEditor/index.d.ts +2 -0
- package/dist/types/src/components/TypescriptEditor/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +3 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/edge/functions.d.ts +7 -0
- package/dist/types/src/edge/functions.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +4 -9
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/templates/chat.d.ts +6 -0
- package/dist/types/src/templates/chat.d.ts.map +1 -0
- package/dist/types/src/templates/chess.d.ts +6 -0
- package/dist/types/src/templates/chess.d.ts.map +1 -0
- package/dist/types/src/templates/echo.d.ts +6 -0
- package/dist/types/src/templates/echo.d.ts.map +1 -0
- package/dist/types/src/templates/email.d.ts +6 -0
- package/dist/types/src/templates/email.d.ts.map +1 -0
- package/dist/types/src/templates/forex.d.ts +6 -0
- package/dist/types/src/templates/forex.d.ts.map +1 -0
- package/dist/types/src/templates.d.ts +8 -0
- package/dist/types/src/templates.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +2 -0
- 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 +4 -3
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/package.json +61 -55
- package/src/ScriptPlugin.tsx +26 -39
- package/src/bundler/bundler.test.ts +12 -2
- package/src/components/AutomationPanel/AutomationPanel.tsx +101 -0
- package/src/components/AutomationPanel/index.ts +9 -0
- package/src/components/{DebugPanel.tsx → DebugPanel/DebugPanel.tsx} +83 -78
- package/src/components/DebugPanel/index.ts +5 -0
- package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/FrameContainer.tsx +1 -1
- package/src/components/ScriptBlock/ScriptBlock.stories.tsx +14 -13
- package/src/components/ScriptBlock/ScriptBlock.tsx +23 -51
- package/src/components/ScriptContainer.tsx +22 -0
- package/src/components/ScriptEditor.tsx +58 -55
- package/src/components/ScriptSettings/ScriptSettings.tsx +47 -0
- package/src/components/ScriptSettings/index.ts +5 -0
- package/src/components/Toolbar/Toolbar.stories.tsx +30 -0
- package/src/components/Toolbar/Toolbar.tsx +177 -0
- package/src/components/{ScriptBlock/Splitter → Toolbar}/index.ts +1 -1
- package/src/components/{TypescriptEditor.stories.tsx → TypescriptEditor/TypescriptEditor.stories.tsx} +17 -35
- package/src/components/{TypescriptEditor.tsx → TypescriptEditor/TypescriptEditor.tsx} +1 -3
- package/src/components/TypescriptEditor/index.ts +5 -0
- package/src/components/index.ts +5 -3
- package/src/edge/functions.ts +19 -0
- package/src/meta.ts +15 -0
- package/src/templates/chat.ts +102 -0
- package/src/templates/chess.ts +41 -0
- package/src/templates/echo.ts +15 -0
- package/src/templates/email.ts +38 -0
- package/src/templates/forex.ts +21 -0
- package/src/templates.ts +54 -0
- package/src/translations.ts +2 -0
- package/src/types/types.ts +9 -5
- package/dist/lib/browser/ScriptEditor-5Y3EROG3.mjs +0 -513
- package/dist/lib/browser/ScriptEditor-5Y3EROG3.mjs.map +0 -7
- package/dist/lib/browser/TypescriptEditor-GPE72Y6I.mjs +0 -9
- package/dist/lib/browser/chunk-DL5XQRQM.mjs.map +0 -7
- package/dist/lib/browser/chunk-JBACGDOJ.mjs +0 -21
- package/dist/lib/browser/chunk-JBACGDOJ.mjs.map +0 -7
- package/dist/lib/browser/chunk-MRGOT5RF.mjs +0 -78
- package/dist/lib/browser/chunk-MRGOT5RF.mjs.map +0 -7
- package/dist/lib/node/ScriptEditor-YCUQFWQM.cjs +0 -526
- package/dist/lib/node/ScriptEditor-YCUQFWQM.cjs.map +0 -7
- package/dist/lib/node/TypescriptEditor-M3WWFIP2.cjs.map +0 -7
- package/dist/lib/node/chunk-4GTXIELQ.cjs.map +0 -7
- package/dist/lib/node/chunk-4VMNBXWU.cjs +0 -54
- package/dist/lib/node/chunk-4VMNBXWU.cjs.map +0 -7
- package/dist/lib/node/chunk-IMLDKD5Y.cjs +0 -111
- package/dist/lib/node/chunk-IMLDKD5Y.cjs.map +0 -7
- package/dist/lib/node/chunk-PFH3ROEH.cjs.map +0 -7
- package/dist/types/src/components/DebugPanel.d.ts.map +0 -1
- package/dist/types/src/components/ScriptBlock/FrameContainer/FrameContainer.d.ts.map +0 -1
- package/dist/types/src/components/ScriptBlock/FrameContainer/frame.d.ts.map +0 -1
- package/dist/types/src/components/ScriptBlock/FrameContainer/index.d.ts.map +0 -1
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.d.ts +0 -15
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.d.ts.map +0 -1
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.stories.d.ts +0 -13
- package/dist/types/src/components/ScriptBlock/Splitter/Splitter.stories.d.ts.map +0 -1
- package/dist/types/src/components/ScriptBlock/Splitter/index.d.ts +0 -2
- package/dist/types/src/components/ScriptBlock/Splitter/index.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar.d.ts +0 -13
- package/dist/types/src/components/Toolbar.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar.stories.d.ts +0 -14
- package/dist/types/src/components/Toolbar.stories.d.ts.map +0 -1
- package/dist/types/src/components/TypescriptEditor.d.ts.map +0 -1
- package/dist/types/src/components/TypescriptEditor.stories.d.ts +0 -10
- package/dist/types/src/components/TypescriptEditor.stories.d.ts.map +0 -1
- package/src/components/ScriptBlock/Splitter/Splitter.stories.tsx +0 -37
- package/src/components/ScriptBlock/Splitter/Splitter.tsx +0 -52
- package/src/components/Toolbar.stories.tsx +0 -17
- package/src/components/Toolbar.tsx +0 -147
- package/src/meta.tsx +0 -19
- /package/dist/lib/{browser/TypescriptEditor-GPE72Y6I.mjs.map → node-esm/edge/index.mjs.map} +0 -0
- /package/dist/types/src/components/{ScriptBlock/FrameContainer → FrameContainer}/frame.d.ts +0 -0
- /package/dist/types/src/components/{ScriptBlock/FrameContainer → FrameContainer}/index.d.ts +0 -0
- /package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/frame.html +0 -0
- /package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/frame.tsx +0 -0
- /package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/index.ts +0 -0
|
@@ -2,19 +2,17 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Check, Play, Warning } from '@phosphor-icons/react';
|
|
6
5
|
// @ts-ignore
|
|
7
6
|
import wasmUrl from 'esbuild-wasm/esbuild.wasm?url';
|
|
8
7
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
9
8
|
|
|
10
9
|
import { createDocAccessor, DocAccessor } from '@dxos/react-client/echo';
|
|
11
|
-
import {
|
|
12
|
-
import { mx
|
|
10
|
+
import { Toolbar, Button, Icon } from '@dxos/react-ui';
|
|
11
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
13
12
|
|
|
14
|
-
import { FrameContainer } from './FrameContainer';
|
|
15
|
-
import { Splitter, SplitterSelector, type View } from './Splitter';
|
|
16
13
|
import { Bundler, type BundlerResult, initializeBundler } from '../../bundler';
|
|
17
14
|
import { type ScriptType } from '../../types';
|
|
15
|
+
import { FrameContainer } from '../FrameContainer';
|
|
18
16
|
import { ScriptEditor } from '../ScriptEditor';
|
|
19
17
|
|
|
20
18
|
// Keep in sync with packages/apps/composer-app/script-frame/main.tsx .
|
|
@@ -29,7 +27,6 @@ const PROVIDED_MODULES = [
|
|
|
29
27
|
|
|
30
28
|
export type ScriptBlockProps = {
|
|
31
29
|
script: ScriptType;
|
|
32
|
-
view?: View;
|
|
33
30
|
hideSelector?: boolean;
|
|
34
31
|
classes?: {
|
|
35
32
|
root?: string;
|
|
@@ -44,17 +41,8 @@ export type ScriptBlockProps = {
|
|
|
44
41
|
* @deprecated
|
|
45
42
|
*/
|
|
46
43
|
// TODO(burdon): Cache compiled results in context.
|
|
47
|
-
export const ScriptBlock = ({
|
|
48
|
-
script,
|
|
49
|
-
view: controlledView,
|
|
50
|
-
hideSelector,
|
|
51
|
-
classes,
|
|
52
|
-
containerUrl,
|
|
53
|
-
}: ScriptBlockProps) => {
|
|
44
|
+
export const ScriptBlock = ({ script, hideSelector, classes, containerUrl }: ScriptBlockProps) => {
|
|
54
45
|
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
|
-
|
|
58
46
|
const [result, setResult] = useState<BundlerResult>();
|
|
59
47
|
const bundler = useMemo(
|
|
60
48
|
() => new Bundler({ platform: 'browser', sandboxedModules: PROVIDED_MODULES, remoteModules: {} }),
|
|
@@ -78,16 +66,6 @@ export const ScriptBlock = ({
|
|
|
78
66
|
return () => clearTimeout(t);
|
|
79
67
|
}, [source]);
|
|
80
68
|
|
|
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
|
-
|
|
91
69
|
const handleExec = useCallback(
|
|
92
70
|
async (auto = true) => {
|
|
93
71
|
if (!source) {
|
|
@@ -95,41 +73,35 @@ export const ScriptBlock = ({
|
|
|
95
73
|
}
|
|
96
74
|
const result = await bundler.bundle(DocAccessor.getValue(source));
|
|
97
75
|
setResult(result);
|
|
98
|
-
if (auto && view === 'editor') {
|
|
99
|
-
setView('preview');
|
|
100
|
-
}
|
|
101
76
|
},
|
|
102
|
-
[source
|
|
77
|
+
[source],
|
|
103
78
|
);
|
|
104
79
|
|
|
105
80
|
return (
|
|
106
81
|
<div className={mx('flex flex-col grow overflow-hidden', classes?.root)}>
|
|
107
82
|
{!hideSelector && (
|
|
108
|
-
<
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
<div
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
</Button>
|
|
125
|
-
</Toolbar.Root>
|
|
126
|
-
</DensityProvider>
|
|
83
|
+
<Toolbar.Root classNames={mx('mb-2', classes?.toolbar)}>
|
|
84
|
+
<div className='grow' />
|
|
85
|
+
{result?.bundle && !result?.error && (
|
|
86
|
+
<div title={String(result.error)}>
|
|
87
|
+
<Icon icon='ph--check--regular' size={5} classNames='text-green-500' />
|
|
88
|
+
</div>
|
|
89
|
+
)}
|
|
90
|
+
{result?.error && (
|
|
91
|
+
<div title={String(result.error)}>
|
|
92
|
+
<Icon icon='ph--warning--regular' size={5} classNames='text-orange-500' />
|
|
93
|
+
</div>
|
|
94
|
+
)}
|
|
95
|
+
<Button variant='ghost' onClick={() => handleExec()}>
|
|
96
|
+
<Icon icon='ph--play--regular' size={5} />
|
|
97
|
+
</Button>
|
|
98
|
+
</Toolbar.Root>
|
|
127
99
|
)}
|
|
128
100
|
|
|
129
|
-
<
|
|
101
|
+
<div className='flex'>
|
|
130
102
|
<ScriptEditor script={script} />
|
|
131
103
|
{result && <FrameContainer key={script.id} result={result} containerUrl={containerUrl} />}
|
|
132
|
-
</
|
|
104
|
+
</div>
|
|
133
105
|
</div>
|
|
134
106
|
);
|
|
135
107
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
8
|
+
import { useAttendableAttributes } from '@dxos/react-ui-attention';
|
|
9
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
10
|
+
|
|
11
|
+
import { ScriptEditor, type ScriptEditorProps } from './ScriptEditor';
|
|
12
|
+
|
|
13
|
+
const ScriptContainer = ({ script, ...props }: ScriptEditorProps) => {
|
|
14
|
+
const attendableAttrs = useAttendableAttributes(fullyQualifiedId(script));
|
|
15
|
+
return (
|
|
16
|
+
<div role='none' className={mx('flex row-span-2 w-full overflow-hidden attention-surface')} {...attendableAttrs}>
|
|
17
|
+
<ScriptEditor {...props} script={script} />
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default ScriptContainer;
|
|
@@ -10,45 +10,39 @@ 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 {
|
|
14
|
-
create,
|
|
15
|
-
createDocAccessor,
|
|
16
|
-
Filter,
|
|
17
|
-
fullyQualifiedId,
|
|
18
|
-
getMeta,
|
|
19
|
-
getSpace,
|
|
20
|
-
useQuery,
|
|
21
|
-
} from '@dxos/react-client/echo';
|
|
13
|
+
import { create, createDocAccessor, Filter, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';
|
|
22
14
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
23
|
-
import { useTranslation } from '@dxos/react-ui';
|
|
24
|
-
import { useHasAttention } from '@dxos/react-ui-attention';
|
|
15
|
+
import { useTranslation, type ThemedClassName } from '@dxos/react-ui';
|
|
25
16
|
import { createDataExtensions, listener } from '@dxos/react-ui-editor';
|
|
26
17
|
import { mx } from '@dxos/react-ui-theme';
|
|
27
18
|
|
|
28
19
|
import { DebugPanel } from './DebugPanel';
|
|
29
|
-
import { Toolbar } from './Toolbar';
|
|
20
|
+
import { type TemplateSelectProps, Toolbar, type ViewType } from './Toolbar';
|
|
30
21
|
import { TypescriptEditor, type TypescriptEditorProps } from './TypescriptEditor';
|
|
31
22
|
import { Bundler } from '../bundler';
|
|
32
23
|
import {
|
|
24
|
+
getInvocationUrl,
|
|
33
25
|
getUserFunctionUrlInMetadata,
|
|
34
26
|
publicKeyToDid,
|
|
35
27
|
setUserFunctionUrlInMetadata,
|
|
36
28
|
uploadWorkerFunction,
|
|
29
|
+
USERFUNCTIONS_PRESET_META_KEY,
|
|
37
30
|
} from '../edge';
|
|
38
31
|
import { SCRIPT_PLUGIN } from '../meta';
|
|
32
|
+
import { templates } from '../templates';
|
|
39
33
|
import { FunctionType, type ScriptType } from '../types';
|
|
40
34
|
|
|
41
|
-
export type ScriptEditorProps = {
|
|
35
|
+
export type ScriptEditorProps = ThemedClassName<{
|
|
42
36
|
script: ScriptType;
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
}> &
|
|
38
|
+
Pick<TypescriptEditorProps, 'env'>;
|
|
45
39
|
|
|
46
|
-
export const ScriptEditor = ({
|
|
40
|
+
export const ScriptEditor = ({ classNames, script, env }: ScriptEditorProps) => {
|
|
47
41
|
const { t } = useTranslation(SCRIPT_PLUGIN);
|
|
48
|
-
const hasAttention = useHasAttention(fullyQualifiedId(script));
|
|
49
42
|
const client = useClient();
|
|
50
43
|
const identity = useIdentity();
|
|
51
44
|
const space = getSpace(script);
|
|
45
|
+
// TODO(dmaretskyi): Parametric query.
|
|
52
46
|
const [fn] = useQuery(
|
|
53
47
|
space,
|
|
54
48
|
Filter.schema(FunctionType, (fn) => fn.source === script),
|
|
@@ -73,7 +67,7 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
73
67
|
[script, script.source, space, identity],
|
|
74
68
|
);
|
|
75
69
|
|
|
76
|
-
const [
|
|
70
|
+
const [view, setView] = useState<ViewType>('editor');
|
|
77
71
|
const initialValue = useMemo(() => script.source?.content, [script.source]);
|
|
78
72
|
const existingFunctionUrl = fn && getUserFunctionUrlInMetadata(getMeta(fn));
|
|
79
73
|
const [error, setError] = useState<string>();
|
|
@@ -103,6 +97,22 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
103
97
|
}
|
|
104
98
|
}, [script.source]);
|
|
105
99
|
|
|
100
|
+
const handleTemplateChange: TemplateSelectProps['onTemplateSelect'] = (id) => {
|
|
101
|
+
const template = templates.find((template) => template.id === id);
|
|
102
|
+
if (template) {
|
|
103
|
+
script.name = template.name;
|
|
104
|
+
script.source!.content = template.source;
|
|
105
|
+
const metaKeys = getMeta(script).keys;
|
|
106
|
+
const oldPresetIndex = metaKeys.findIndex((key) => key.source === USERFUNCTIONS_PRESET_META_KEY);
|
|
107
|
+
if (oldPresetIndex >= 0) {
|
|
108
|
+
metaKeys.splice(oldPresetIndex, 1);
|
|
109
|
+
}
|
|
110
|
+
if (template.presetId) {
|
|
111
|
+
metaKeys.push({ source: USERFUNCTIONS_PRESET_META_KEY, id: template.presetId });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
106
116
|
const handleDeploy = useCallback(async () => {
|
|
107
117
|
if (!script.source || !identity || !space) {
|
|
108
118
|
return;
|
|
@@ -114,11 +124,7 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
114
124
|
const existingFunctionId = existingFunctionUrl?.split('/').at(-1);
|
|
115
125
|
const ownerDid = (existingFunctionUrl?.split('/').at(-2) as DID) ?? publicKeyToDid(identity.identityKey);
|
|
116
126
|
|
|
117
|
-
const bundler = new Bundler({
|
|
118
|
-
platform: 'browser',
|
|
119
|
-
sandboxedModules: [],
|
|
120
|
-
remoteModules: {},
|
|
121
|
-
});
|
|
127
|
+
const bundler = new Bundler({ platform: 'browser', sandboxedModules: [], remoteModules: {} });
|
|
122
128
|
const buildResult = await bundler.bundle(script.source.content);
|
|
123
129
|
if (buildResult.error || !buildResult.bundle) {
|
|
124
130
|
throw buildResult.error;
|
|
@@ -134,15 +140,18 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
134
140
|
if (result !== 'success' || functionId === undefined || functionVersionNumber === undefined) {
|
|
135
141
|
throw new Error(errorMessage);
|
|
136
142
|
}
|
|
143
|
+
|
|
137
144
|
log.info('function uploaded', { functionId, functionVersionNumber });
|
|
138
145
|
if (fn) {
|
|
139
146
|
fn.version = functionVersionNumber;
|
|
140
147
|
}
|
|
148
|
+
|
|
141
149
|
const deployedFunction =
|
|
142
150
|
fn ?? space.db.add(create(FunctionType, { version: functionVersionNumber, source: script }));
|
|
143
151
|
const meta = getMeta(deployedFunction);
|
|
144
|
-
setUserFunctionUrlInMetadata(meta, `/${ownerDid}/${functionId}`);
|
|
145
152
|
script.changed = false;
|
|
153
|
+
setUserFunctionUrlInMetadata(meta, `/${ownerDid}/${functionId}`);
|
|
154
|
+
setView('split');
|
|
146
155
|
} catch (err: any) {
|
|
147
156
|
log.catch(err);
|
|
148
157
|
setError(t('upload failed label'));
|
|
@@ -154,49 +163,43 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
154
163
|
return;
|
|
155
164
|
}
|
|
156
165
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const relativeUrl = existingFunctionUrl.replace(/^\//, '');
|
|
161
|
-
const url = new URL(`./${relativeUrl}`, baseUrl.toString());
|
|
162
|
-
space && url.searchParams.set('spaceId', space.id);
|
|
163
|
-
url.protocol = 'https';
|
|
164
|
-
return url.toString();
|
|
166
|
+
return getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? '', {
|
|
167
|
+
spaceId: space?.id,
|
|
168
|
+
});
|
|
165
169
|
}, [existingFunctionUrl, space]);
|
|
166
170
|
|
|
167
171
|
return (
|
|
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
|
-
|
|
172
|
+
<div role='none' className={mx('flex flex-col w-full overflow-hidden divide-y divide-separator', classNames)}>
|
|
184
173
|
<Toolbar
|
|
185
|
-
classNames='border-t border-separator'
|
|
186
174
|
deployed={Boolean(existingFunctionUrl) && !script.changed}
|
|
187
175
|
functionUrl={functionUrl}
|
|
188
176
|
error={error}
|
|
189
|
-
|
|
177
|
+
view={view}
|
|
178
|
+
templates={templates}
|
|
190
179
|
onDeploy={handleDeploy}
|
|
191
180
|
onFormat={handleFormat}
|
|
192
|
-
|
|
181
|
+
onViewChange={setView}
|
|
182
|
+
onTemplateSelect={handleTemplateChange}
|
|
193
183
|
/>
|
|
194
184
|
|
|
195
|
-
{
|
|
196
|
-
<
|
|
185
|
+
{view !== 'preview' && (
|
|
186
|
+
<TypescriptEditor
|
|
187
|
+
id={script.id}
|
|
188
|
+
env={env}
|
|
189
|
+
initialValue={initialValue}
|
|
190
|
+
extensions={extensions}
|
|
191
|
+
className='flex is-full bs-full overflow-hidden ch-focus-ring-inset-over-all'
|
|
192
|
+
/>
|
|
193
|
+
)}
|
|
194
|
+
|
|
195
|
+
{view !== 'editor' && (
|
|
196
|
+
<DebugPanel
|
|
197
|
+
functionUrl={functionUrl}
|
|
198
|
+
showBindingConfig
|
|
199
|
+
binding={fn?.binding}
|
|
200
|
+
onBindingChange={handleBindingChange}
|
|
201
|
+
/>
|
|
197
202
|
)}
|
|
198
203
|
</div>
|
|
199
204
|
);
|
|
200
205
|
};
|
|
201
|
-
|
|
202
|
-
export default ScriptEditor;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { SettingsValue } from '@dxos/plugin-settings';
|
|
8
|
+
import { type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
9
|
+
import { useClient } from '@dxos/react-client';
|
|
10
|
+
import { Button, useTranslation } from '@dxos/react-ui';
|
|
11
|
+
|
|
12
|
+
import { SCRIPT_PLUGIN } from '../../meta';
|
|
13
|
+
import { type ScriptSettingsProps } from '../../types';
|
|
14
|
+
|
|
15
|
+
export const ScriptSettings = ({ settings }: { settings: ScriptSettingsProps }) => {
|
|
16
|
+
const { t } = useTranslation(SCRIPT_PLUGIN);
|
|
17
|
+
const client = useClient();
|
|
18
|
+
|
|
19
|
+
// TODO(burdon): Check token.
|
|
20
|
+
const handleAuthenticate = async () => {
|
|
21
|
+
const { identityKey } = client.halo.identity.get()!;
|
|
22
|
+
await client.halo.writeCredentials([
|
|
23
|
+
{
|
|
24
|
+
issuer: identityKey,
|
|
25
|
+
issuanceDate: new Date(),
|
|
26
|
+
subject: {
|
|
27
|
+
id: identityKey,
|
|
28
|
+
assertion: {
|
|
29
|
+
'@type': 'dxos.halo.credentials.ServiceAccess',
|
|
30
|
+
serverName: 'hub.dxos.network',
|
|
31
|
+
serverKey: identityKey,
|
|
32
|
+
identityKey,
|
|
33
|
+
capabilities: ['composer:beta'],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
} satisfies Credential,
|
|
37
|
+
]);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<>
|
|
42
|
+
<SettingsValue label={t('authenticate action label')}>
|
|
43
|
+
<Button onClick={handleAuthenticate}>{t('authenticate button label')}</Button>
|
|
44
|
+
</SettingsValue>
|
|
45
|
+
</>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { type Meta } from '@storybook/react';
|
|
8
|
+
|
|
9
|
+
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
10
|
+
|
|
11
|
+
import { Toolbar } from './Toolbar';
|
|
12
|
+
import { templates } from '../../templates';
|
|
13
|
+
|
|
14
|
+
export const Default = {
|
|
15
|
+
args: {
|
|
16
|
+
binding: 'example',
|
|
17
|
+
deployed: true,
|
|
18
|
+
templates,
|
|
19
|
+
onFormat: () => console.log('Format'),
|
|
20
|
+
onTogglePanel: () => {},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const meta: Meta = {
|
|
25
|
+
title: 'plugins/plugin-script/Toolbar',
|
|
26
|
+
component: Toolbar,
|
|
27
|
+
decorators: [withTheme, withLayout({ tooltips: true })],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default meta;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
ElevationProvider,
|
|
9
|
+
Icon,
|
|
10
|
+
Select,
|
|
11
|
+
type ThemedClassName,
|
|
12
|
+
ToggleGroup,
|
|
13
|
+
ToggleGroupItem,
|
|
14
|
+
type ToolbarButtonProps,
|
|
15
|
+
Toolbar as NaturalToolbar,
|
|
16
|
+
Tooltip,
|
|
17
|
+
useTranslation,
|
|
18
|
+
} from '@dxos/react-ui';
|
|
19
|
+
|
|
20
|
+
import { SCRIPT_PLUGIN } from '../../meta';
|
|
21
|
+
import { type Template } from '../../templates';
|
|
22
|
+
|
|
23
|
+
export type ToolbarProps = ThemedClassName<
|
|
24
|
+
{
|
|
25
|
+
deployed?: boolean;
|
|
26
|
+
error?: string;
|
|
27
|
+
functionUrl?: string;
|
|
28
|
+
onDeploy?: () => Promise<void>;
|
|
29
|
+
onFormat?: () => Promise<void>;
|
|
30
|
+
} & TemplateSelectProps &
|
|
31
|
+
ViewSelectorProps
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
export const Toolbar = ({
|
|
35
|
+
classNames,
|
|
36
|
+
deployed,
|
|
37
|
+
error,
|
|
38
|
+
functionUrl,
|
|
39
|
+
view,
|
|
40
|
+
templates,
|
|
41
|
+
onDeploy,
|
|
42
|
+
onFormat,
|
|
43
|
+
onViewChange,
|
|
44
|
+
onTemplateSelect,
|
|
45
|
+
}: ToolbarProps) => {
|
|
46
|
+
const { t } = useTranslation(SCRIPT_PLUGIN);
|
|
47
|
+
const [pending, setPending] = useState(false);
|
|
48
|
+
|
|
49
|
+
const handleCopyLink = async () => {
|
|
50
|
+
if (!functionUrl) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
await navigator.clipboard.writeText(functionUrl);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const handleDeploy = async () => {
|
|
58
|
+
if (!pending) {
|
|
59
|
+
setPending(true);
|
|
60
|
+
await onDeploy?.();
|
|
61
|
+
setPending(false);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// TODO(burdon): Factor out common toolbar components with sheet/editor?
|
|
66
|
+
return (
|
|
67
|
+
<ElevationProvider elevation='chrome'>
|
|
68
|
+
<NaturalToolbar.Root classNames={['p-1', classNames]} style={{ contain: 'layout' }}>
|
|
69
|
+
{templates && <TemplateSelect templates={templates} onTemplateSelect={onTemplateSelect} />}
|
|
70
|
+
{onFormat && <ToolbarIconButton icon='ph--magic-wand--regular' text={t('format label')} onClick={onFormat} />}
|
|
71
|
+
|
|
72
|
+
<div role='separator' className='grow' />
|
|
73
|
+
|
|
74
|
+
{error ? (
|
|
75
|
+
<Tooltip.Root>
|
|
76
|
+
<Tooltip.Trigger>
|
|
77
|
+
<Icon icon='ph--warning-circle--regular' size={4} />
|
|
78
|
+
</Tooltip.Trigger>
|
|
79
|
+
<Tooltip.Portal>
|
|
80
|
+
<Tooltip.Content>
|
|
81
|
+
<Tooltip.Arrow />
|
|
82
|
+
{error}
|
|
83
|
+
</Tooltip.Content>
|
|
84
|
+
</Tooltip.Portal>
|
|
85
|
+
</Tooltip.Root>
|
|
86
|
+
) : null}
|
|
87
|
+
|
|
88
|
+
{functionUrl && deployed && (
|
|
89
|
+
<ToolbarIconButton icon='ph--link--regular' text={t('copy link label')} onClick={handleCopyLink} />
|
|
90
|
+
)}
|
|
91
|
+
|
|
92
|
+
{onDeploy && (
|
|
93
|
+
<ToolbarIconButton
|
|
94
|
+
icon={pending ? 'ph--spinner-gap--regular' : 'ph--cloud-arrow-up--regular'}
|
|
95
|
+
classNames={[pending && 'animate-spin']}
|
|
96
|
+
text={pending ? t('pending label') : t('deploy label')}
|
|
97
|
+
onClick={handleDeploy}
|
|
98
|
+
/>
|
|
99
|
+
)}
|
|
100
|
+
|
|
101
|
+
<ViewSelector view={view} onViewChange={onViewChange} />
|
|
102
|
+
</NaturalToolbar.Root>
|
|
103
|
+
</ElevationProvider>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const ToolbarIconButton = ({
|
|
108
|
+
icon,
|
|
109
|
+
text,
|
|
110
|
+
classNames,
|
|
111
|
+
disabled,
|
|
112
|
+
onClick,
|
|
113
|
+
}: { icon: string; text: string } & Pick<ToolbarButtonProps, 'classNames' | 'disabled' | 'onClick'>) => {
|
|
114
|
+
return (
|
|
115
|
+
<Tooltip.Root>
|
|
116
|
+
<Tooltip.Trigger asChild>
|
|
117
|
+
<NaturalToolbar.Button variant='ghost' disabled={disabled} onClick={onClick}>
|
|
118
|
+
<Icon icon={icon} size={4} classNames={classNames} />
|
|
119
|
+
</NaturalToolbar.Button>
|
|
120
|
+
</Tooltip.Trigger>
|
|
121
|
+
<Tooltip.Portal>
|
|
122
|
+
<Tooltip.Content>
|
|
123
|
+
<Tooltip.Arrow />
|
|
124
|
+
{text}
|
|
125
|
+
</Tooltip.Content>
|
|
126
|
+
</Tooltip.Portal>
|
|
127
|
+
</Tooltip.Root>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export type ViewType = 'editor' | 'split' | 'preview';
|
|
132
|
+
|
|
133
|
+
export type TemplateSelectProps = {
|
|
134
|
+
templates?: Template[];
|
|
135
|
+
onTemplateSelect?: (id: string) => void;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const TemplateSelect = ({ templates = [], onTemplateSelect }: TemplateSelectProps) => {
|
|
139
|
+
return (
|
|
140
|
+
<Select.Root value={''} onValueChange={onTemplateSelect}>
|
|
141
|
+
<Select.TriggerButton />
|
|
142
|
+
<Select.Portal>
|
|
143
|
+
<Select.Content>
|
|
144
|
+
<Select.Viewport>
|
|
145
|
+
<Select.Option value={''}>Template</Select.Option>
|
|
146
|
+
{templates.map(({ id, name }) => (
|
|
147
|
+
<Select.Option key={id} value={id}>
|
|
148
|
+
{name}
|
|
149
|
+
</Select.Option>
|
|
150
|
+
))}
|
|
151
|
+
</Select.Viewport>
|
|
152
|
+
</Select.Content>
|
|
153
|
+
</Select.Portal>
|
|
154
|
+
</Select.Root>
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export type ViewSelectorProps = {
|
|
159
|
+
view?: ViewType;
|
|
160
|
+
onViewChange?: (view: ViewType) => void;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const ViewSelector = ({ view, onViewChange }: ViewSelectorProps) => {
|
|
164
|
+
return (
|
|
165
|
+
<ToggleGroup type='single' value={view} onValueChange={(value) => onViewChange?.(value as ViewType)}>
|
|
166
|
+
<ToggleGroupItem value='editor' classNames='bg-transparent text-subdued'>
|
|
167
|
+
<Icon icon='ph--code--regular' size={4} />
|
|
168
|
+
</ToggleGroupItem>
|
|
169
|
+
<ToggleGroupItem value='split' classNames='bg-transparent text-subdued'>
|
|
170
|
+
<Icon icon='ph--square-split-vertical--regular' size={4} />
|
|
171
|
+
</ToggleGroupItem>
|
|
172
|
+
<ToggleGroupItem value='preview' classNames='bg-transparent text-subdued'>
|
|
173
|
+
<Icon icon='ph--eye--regular' size={4} />
|
|
174
|
+
</ToggleGroupItem>
|
|
175
|
+
</ToggleGroup>
|
|
176
|
+
);
|
|
177
|
+
};
|