@dxos/plugin-script 0.6.12 → 0.6.13-main.09887cd
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/{ScriptEditor-5Y3EROG3.mjs → ScriptContainer-M4MDQTBU.mjs} +258 -106
- package/dist/lib/browser/ScriptContainer-M4MDQTBU.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DL5XQRQM.mjs → chunk-G6FWCTGT.mjs} +7 -5
- package/dist/lib/browser/chunk-G6FWCTGT.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-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 +3 -1
- package/dist/lib/browser/index.mjs +80 -62
- 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/ScriptContainer-KMIPKT3H.cjs +668 -0
- package/dist/lib/node/ScriptContainer-KMIPKT3H.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-UZ3ZXEBF.cjs} +11 -8
- package/dist/lib/node/chunk-UZ3ZXEBF.cjs.map +7 -0
- package/dist/lib/node/edge/index.cjs +10 -8
- package/dist/lib/node/edge/index.cjs.map +2 -2
- package/dist/lib/node/index.cjs +95 -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/ScriptContainer-EAE6L5JV.mjs +666 -0
- package/dist/lib/node-esm/ScriptContainer-EAE6L5JV.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-2NX3HWPM.mjs +245 -0
- package/dist/lib/node-esm/chunk-2NX3HWPM.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/edge/index.mjs +22 -0
- package/dist/lib/node-esm/index.mjs +310 -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/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 +1 -1
- 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 +17 -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 +10 -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 +2 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/edge/functions.d.ts +1 -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 +22 -38
- package/src/bundler/bundler.test.ts +12 -2
- package/src/components/{DebugPanel.tsx → DebugPanel/DebugPanel.tsx} +48 -41
- 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 +4 -3
- package/src/components/ScriptBlock/ScriptBlock.tsx +10 -36
- package/src/components/ScriptContainer.tsx +22 -0
- package/src/components/ScriptEditor.tsx +47 -46
- package/src/components/ScriptSettings/ScriptSettings.tsx +47 -0
- package/src/components/ScriptSettings/index.ts +5 -0
- package/src/components/{Toolbar.stories.tsx → Toolbar/Toolbar.stories.tsx} +10 -1
- package/src/components/Toolbar/Toolbar.tsx +180 -0
- package/src/components/{ScriptBlock/Splitter → Toolbar}/index.ts +1 -1
- package/src/components/{TypescriptEditor.stories.tsx → TypescriptEditor/TypescriptEditor.stories.tsx} +7 -28
- package/src/components/{TypescriptEditor.tsx → TypescriptEditor/TypescriptEditor.tsx} +1 -3
- package/src/components/TypescriptEditor/index.ts +5 -0
- package/src/components/index.ts +3 -2
- package/src/edge/functions.ts +1 -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.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.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/{DebugPanel.d.ts → DebugPanel/DebugPanel.d.ts} +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 { DensityProvider, Toolbar, Button } from '@dxos/react-ui';
|
|
12
|
-
import { mx
|
|
10
|
+
import { DensityProvider, 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,11 +73,8 @@ 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 (
|
|
@@ -107,29 +82,28 @@ export const ScriptBlock = ({
|
|
|
107
82
|
{!hideSelector && (
|
|
108
83
|
<DensityProvider density='fine'>
|
|
109
84
|
<Toolbar.Root classNames={mx('mb-2', classes?.toolbar)}>
|
|
110
|
-
<SplitterSelector view={view} onChange={handleSetView} />
|
|
111
85
|
<div className='grow' />
|
|
112
86
|
{result?.bundle && !result?.error && (
|
|
113
87
|
<div title={String(result.error)}>
|
|
114
|
-
<
|
|
88
|
+
<Icon icon='ph--check--regular' size={5} classNames='text-green-500' />
|
|
115
89
|
</div>
|
|
116
90
|
)}
|
|
117
91
|
{result?.error && (
|
|
118
92
|
<div title={String(result.error)}>
|
|
119
|
-
<
|
|
93
|
+
<Icon icon='ph--warning--regular' size={5} classNames='text-orange-500' />
|
|
120
94
|
</div>
|
|
121
95
|
)}
|
|
122
96
|
<Button variant='ghost' onClick={() => handleExec()}>
|
|
123
|
-
<
|
|
97
|
+
<Icon icon='ph--play--regular' size={5} />
|
|
124
98
|
</Button>
|
|
125
99
|
</Toolbar.Root>
|
|
126
100
|
</DensityProvider>
|
|
127
101
|
)}
|
|
128
102
|
|
|
129
|
-
<
|
|
103
|
+
<div className='flex'>
|
|
130
104
|
<ScriptEditor script={script} />
|
|
131
105
|
{result && <FrameContainer key={script.id} result={result} containerUrl={containerUrl} />}
|
|
132
|
-
</
|
|
106
|
+
</div>
|
|
133
107
|
</div>
|
|
134
108
|
);
|
|
135
109
|
};
|
|
@@ -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,23 +10,14 @@ 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 {
|
|
@@ -34,18 +25,19 @@ import {
|
|
|
34
25
|
publicKeyToDid,
|
|
35
26
|
setUserFunctionUrlInMetadata,
|
|
36
27
|
uploadWorkerFunction,
|
|
28
|
+
USERFUNCTIONS_PRESET_META_KEY,
|
|
37
29
|
} from '../edge';
|
|
38
30
|
import { SCRIPT_PLUGIN } from '../meta';
|
|
31
|
+
import { templates } from '../templates';
|
|
39
32
|
import { FunctionType, type ScriptType } from '../types';
|
|
40
33
|
|
|
41
|
-
export type ScriptEditorProps = {
|
|
34
|
+
export type ScriptEditorProps = ThemedClassName<{
|
|
42
35
|
script: ScriptType;
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
}> &
|
|
37
|
+
Pick<TypescriptEditorProps, 'env'>;
|
|
45
38
|
|
|
46
|
-
export const ScriptEditor = ({
|
|
39
|
+
export const ScriptEditor = ({ classNames, script, env }: ScriptEditorProps) => {
|
|
47
40
|
const { t } = useTranslation(SCRIPT_PLUGIN);
|
|
48
|
-
const hasAttention = useHasAttention(fullyQualifiedId(script));
|
|
49
41
|
const client = useClient();
|
|
50
42
|
const identity = useIdentity();
|
|
51
43
|
const space = getSpace(script);
|
|
@@ -73,7 +65,7 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
73
65
|
[script, script.source, space, identity],
|
|
74
66
|
);
|
|
75
67
|
|
|
76
|
-
const [
|
|
68
|
+
const [view, setView] = useState<ViewType>('editor');
|
|
77
69
|
const initialValue = useMemo(() => script.source?.content, [script.source]);
|
|
78
70
|
const existingFunctionUrl = fn && getUserFunctionUrlInMetadata(getMeta(fn));
|
|
79
71
|
const [error, setError] = useState<string>();
|
|
@@ -103,6 +95,22 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
103
95
|
}
|
|
104
96
|
}, [script.source]);
|
|
105
97
|
|
|
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
|
+
|
|
106
114
|
const handleDeploy = useCallback(async () => {
|
|
107
115
|
if (!script.source || !identity || !space) {
|
|
108
116
|
return;
|
|
@@ -114,11 +122,7 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
114
122
|
const existingFunctionId = existingFunctionUrl?.split('/').at(-1);
|
|
115
123
|
const ownerDid = (existingFunctionUrl?.split('/').at(-2) as DID) ?? publicKeyToDid(identity.identityKey);
|
|
116
124
|
|
|
117
|
-
const bundler = new Bundler({
|
|
118
|
-
platform: 'browser',
|
|
119
|
-
sandboxedModules: [],
|
|
120
|
-
remoteModules: {},
|
|
121
|
-
});
|
|
125
|
+
const bundler = new Bundler({ platform: 'browser', sandboxedModules: [], remoteModules: {} });
|
|
122
126
|
const buildResult = await bundler.bundle(script.source.content);
|
|
123
127
|
if (buildResult.error || !buildResult.bundle) {
|
|
124
128
|
throw buildResult.error;
|
|
@@ -134,15 +138,18 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
134
138
|
if (result !== 'success' || functionId === undefined || functionVersionNumber === undefined) {
|
|
135
139
|
throw new Error(errorMessage);
|
|
136
140
|
}
|
|
141
|
+
|
|
137
142
|
log.info('function uploaded', { functionId, functionVersionNumber });
|
|
138
143
|
if (fn) {
|
|
139
144
|
fn.version = functionVersionNumber;
|
|
140
145
|
}
|
|
146
|
+
|
|
141
147
|
const deployedFunction =
|
|
142
148
|
fn ?? space.db.add(create(FunctionType, { version: functionVersionNumber, source: script }));
|
|
143
149
|
const meta = getMeta(deployedFunction);
|
|
144
|
-
setUserFunctionUrlInMetadata(meta, `/${ownerDid}/${functionId}`);
|
|
145
150
|
script.changed = false;
|
|
151
|
+
setUserFunctionUrlInMetadata(meta, `/${ownerDid}/${functionId}`);
|
|
152
|
+
setView('split');
|
|
146
153
|
} catch (err: any) {
|
|
147
154
|
log.catch(err);
|
|
148
155
|
setError(t('upload failed label'));
|
|
@@ -165,38 +172,32 @@ export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
|
|
|
165
172
|
}, [existingFunctionUrl, space]);
|
|
166
173
|
|
|
167
174
|
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
|
-
|
|
175
|
+
<div role='none' className={mx('flex flex-col w-full overflow-hidden divide-y divide-separator', classNames)}>
|
|
184
176
|
<Toolbar
|
|
185
|
-
classNames='border-t border-separator'
|
|
186
177
|
deployed={Boolean(existingFunctionUrl) && !script.changed}
|
|
187
178
|
functionUrl={functionUrl}
|
|
188
179
|
error={error}
|
|
189
|
-
|
|
180
|
+
view={view}
|
|
181
|
+
templates={templates}
|
|
190
182
|
onDeploy={handleDeploy}
|
|
191
183
|
onFormat={handleFormat}
|
|
192
|
-
|
|
184
|
+
onViewChange={setView}
|
|
185
|
+
onTemplateSelect={handleTemplateChange}
|
|
193
186
|
/>
|
|
194
187
|
|
|
195
|
-
{
|
|
188
|
+
{view !== 'preview' && (
|
|
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' && (
|
|
196
199
|
<DebugPanel functionUrl={functionUrl} binding={fn?.binding} onBindingChange={handleBindingChange} />
|
|
197
200
|
)}
|
|
198
201
|
</div>
|
|
199
202
|
);
|
|
200
203
|
};
|
|
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
|
+
};
|
|
@@ -7,6 +7,7 @@ import '@dxos-theme';
|
|
|
7
7
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
8
8
|
|
|
9
9
|
import { Toolbar } from './Toolbar';
|
|
10
|
+
import { templates } from '../../templates';
|
|
10
11
|
|
|
11
12
|
export default {
|
|
12
13
|
title: 'plugin-script/Toolbar',
|
|
@@ -14,4 +15,12 @@ export default {
|
|
|
14
15
|
decorators: [withTheme, withLayout({ tooltips: true })],
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
export const Default = {
|
|
18
|
+
export const Default = {
|
|
19
|
+
args: {
|
|
20
|
+
binding: 'example',
|
|
21
|
+
deployed: true,
|
|
22
|
+
templates,
|
|
23
|
+
onFormat: () => console.log('Format'),
|
|
24
|
+
onTogglePanel: () => {},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
DensityProvider,
|
|
9
|
+
ElevationProvider,
|
|
10
|
+
Icon,
|
|
11
|
+
Select,
|
|
12
|
+
type ThemedClassName,
|
|
13
|
+
ToggleGroup,
|
|
14
|
+
ToggleGroupItem,
|
|
15
|
+
type ToolbarButtonProps,
|
|
16
|
+
Toolbar as NaturalToolbar,
|
|
17
|
+
Tooltip,
|
|
18
|
+
useTranslation,
|
|
19
|
+
} from '@dxos/react-ui';
|
|
20
|
+
|
|
21
|
+
import { SCRIPT_PLUGIN } from '../../meta';
|
|
22
|
+
import { type Template } from '../../templates';
|
|
23
|
+
|
|
24
|
+
export type ToolbarProps = ThemedClassName<
|
|
25
|
+
{
|
|
26
|
+
deployed?: boolean;
|
|
27
|
+
error?: string;
|
|
28
|
+
functionUrl?: string;
|
|
29
|
+
onDeploy?: () => Promise<void>;
|
|
30
|
+
onFormat?: () => Promise<void>;
|
|
31
|
+
} & TemplateSelectProps &
|
|
32
|
+
ViewSelectorProps
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
export const Toolbar = ({
|
|
36
|
+
classNames,
|
|
37
|
+
deployed,
|
|
38
|
+
error,
|
|
39
|
+
functionUrl,
|
|
40
|
+
view,
|
|
41
|
+
templates,
|
|
42
|
+
onDeploy,
|
|
43
|
+
onFormat,
|
|
44
|
+
onViewChange,
|
|
45
|
+
onTemplateSelect,
|
|
46
|
+
}: ToolbarProps) => {
|
|
47
|
+
const { t } = useTranslation(SCRIPT_PLUGIN);
|
|
48
|
+
const [pending, setPending] = useState(false);
|
|
49
|
+
|
|
50
|
+
const handleCopyLink = async () => {
|
|
51
|
+
if (!functionUrl) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await navigator.clipboard.writeText(functionUrl);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const handleDeploy = async () => {
|
|
59
|
+
if (!pending) {
|
|
60
|
+
setPending(true);
|
|
61
|
+
await onDeploy?.();
|
|
62
|
+
setPending(false);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// TODO(burdon): Factor out common toolbar components with sheet/editor?
|
|
67
|
+
return (
|
|
68
|
+
<DensityProvider density='fine'>
|
|
69
|
+
<ElevationProvider elevation='chrome'>
|
|
70
|
+
<NaturalToolbar.Root classNames={['p-1', classNames]} style={{ contain: 'layout' }}>
|
|
71
|
+
{templates && <TemplateSelect templates={templates} onTemplateSelect={onTemplateSelect} />}
|
|
72
|
+
{onFormat && <ToolbarIconButton icon='ph--magic-wand--regular' text={t('format label')} onClick={onFormat} />}
|
|
73
|
+
|
|
74
|
+
<div role='separator' className='grow' />
|
|
75
|
+
|
|
76
|
+
{error ? (
|
|
77
|
+
<Tooltip.Root>
|
|
78
|
+
<Tooltip.Trigger>
|
|
79
|
+
<Icon icon='ph--warning-circle--regular' size={4} />
|
|
80
|
+
</Tooltip.Trigger>
|
|
81
|
+
<Tooltip.Portal>
|
|
82
|
+
<Tooltip.Content>
|
|
83
|
+
<Tooltip.Arrow />
|
|
84
|
+
{error}
|
|
85
|
+
</Tooltip.Content>
|
|
86
|
+
</Tooltip.Portal>
|
|
87
|
+
</Tooltip.Root>
|
|
88
|
+
) : null}
|
|
89
|
+
|
|
90
|
+
{functionUrl && deployed && (
|
|
91
|
+
<ToolbarIconButton icon='ph--link--regular' text={t('copy link label')} onClick={handleCopyLink} />
|
|
92
|
+
)}
|
|
93
|
+
|
|
94
|
+
{onDeploy && (
|
|
95
|
+
<ToolbarIconButton
|
|
96
|
+
icon={pending ? 'ph--spinner-gap--regular' : 'ph--cloud-arrow-up--regular'}
|
|
97
|
+
classNames={[pending && 'animate-spin']}
|
|
98
|
+
text={pending ? t('pending label') : t('deploy label')}
|
|
99
|
+
onClick={handleDeploy}
|
|
100
|
+
/>
|
|
101
|
+
)}
|
|
102
|
+
|
|
103
|
+
<ViewSelector view={view} onViewChange={onViewChange} />
|
|
104
|
+
</NaturalToolbar.Root>
|
|
105
|
+
</ElevationProvider>
|
|
106
|
+
</DensityProvider>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const ToolbarIconButton = ({
|
|
111
|
+
icon,
|
|
112
|
+
text,
|
|
113
|
+
classNames,
|
|
114
|
+
disabled,
|
|
115
|
+
onClick,
|
|
116
|
+
}: { icon: string; text: string } & Pick<ToolbarButtonProps, 'classNames' | 'disabled' | 'onClick'>) => {
|
|
117
|
+
return (
|
|
118
|
+
<Tooltip.Root>
|
|
119
|
+
<Tooltip.Trigger asChild>
|
|
120
|
+
<NaturalToolbar.Button variant='ghost' disabled={disabled} onClick={onClick}>
|
|
121
|
+
<Icon icon={icon} size={4} classNames={classNames} />
|
|
122
|
+
</NaturalToolbar.Button>
|
|
123
|
+
</Tooltip.Trigger>
|
|
124
|
+
<Tooltip.Portal>
|
|
125
|
+
<Tooltip.Content>
|
|
126
|
+
<Tooltip.Arrow />
|
|
127
|
+
{text}
|
|
128
|
+
</Tooltip.Content>
|
|
129
|
+
</Tooltip.Portal>
|
|
130
|
+
</Tooltip.Root>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export type ViewType = 'editor' | 'split' | 'preview';
|
|
135
|
+
|
|
136
|
+
export type TemplateSelectProps = {
|
|
137
|
+
templates?: Template[];
|
|
138
|
+
onTemplateSelect?: (id: string) => void;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const TemplateSelect = ({ templates = [], onTemplateSelect }: TemplateSelectProps) => {
|
|
142
|
+
return (
|
|
143
|
+
<Select.Root value={''} onValueChange={onTemplateSelect}>
|
|
144
|
+
<Select.TriggerButton />
|
|
145
|
+
<Select.Portal>
|
|
146
|
+
<Select.Content>
|
|
147
|
+
<Select.Viewport>
|
|
148
|
+
<Select.Option value={''}>Template</Select.Option>
|
|
149
|
+
{templates.map(({ id, name }) => (
|
|
150
|
+
<Select.Option key={id} value={id}>
|
|
151
|
+
{name}
|
|
152
|
+
</Select.Option>
|
|
153
|
+
))}
|
|
154
|
+
</Select.Viewport>
|
|
155
|
+
</Select.Content>
|
|
156
|
+
</Select.Portal>
|
|
157
|
+
</Select.Root>
|
|
158
|
+
);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export type ViewSelectorProps = {
|
|
162
|
+
view?: ViewType;
|
|
163
|
+
onViewChange?: (view: ViewType) => void;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const ViewSelector = ({ view, onViewChange }: ViewSelectorProps) => {
|
|
167
|
+
return (
|
|
168
|
+
<ToggleGroup type='single' value={view} onValueChange={(value) => onViewChange?.(value as ViewType)}>
|
|
169
|
+
<ToggleGroupItem value='editor' classNames='bg-transparent text-subdued'>
|
|
170
|
+
<Icon icon='ph--code--regular' size={4} />
|
|
171
|
+
</ToggleGroupItem>
|
|
172
|
+
<ToggleGroupItem value='split' classNames='bg-transparent text-subdued'>
|
|
173
|
+
<Icon icon='ph--square-split-vertical--regular' size={4} />
|
|
174
|
+
</ToggleGroupItem>
|
|
175
|
+
<ToggleGroupItem value='preview' classNames='bg-transparent text-subdued'>
|
|
176
|
+
<Icon icon='ph--eye--regular' size={4} />
|
|
177
|
+
</ToggleGroupItem>
|
|
178
|
+
</ToggleGroup>
|
|
179
|
+
);
|
|
180
|
+
};
|
|
@@ -10,45 +10,24 @@ import { createDocAccessor, createEchoObject } from '@dxos/react-client/echo';
|
|
|
10
10
|
import { createDataExtensions } from '@dxos/react-ui-editor';
|
|
11
11
|
|
|
12
12
|
import { TypescriptEditor } from './TypescriptEditor';
|
|
13
|
+
import { templates } from '../../templates';
|
|
13
14
|
|
|
14
|
-
// TODO(burdon):
|
|
15
|
-
// TODO(burdon): Effect schema.
|
|
16
|
-
// TODO(burdon): JSX.
|
|
17
|
-
// TODO(burdon): react-buddy for storybook?
|
|
18
|
-
|
|
19
|
-
// Marijn
|
|
15
|
+
// TODO(burdon): Features:
|
|
20
16
|
// - language support for S
|
|
21
17
|
// - hierarchical editor (DND)
|
|
22
18
|
// - virtual document image rendering
|
|
23
19
|
// - mobile rendering error
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'export default function() {',
|
|
29
|
-
' const value = 100',
|
|
30
|
-
' return <div>{value}</div>;',
|
|
31
|
-
'}',
|
|
32
|
-
].join('\n'),
|
|
33
|
-
[
|
|
34
|
-
'// Example schema.',
|
|
35
|
-
'S.Struct({',
|
|
36
|
-
' timestamp: S.Date,',
|
|
37
|
-
' title: S.String,',
|
|
38
|
-
' content: R.Text,',
|
|
39
|
-
"}).pipe(S.identifier('dxos.org/schema/Test'))",
|
|
40
|
-
'',
|
|
41
|
-
].join('\n'),
|
|
42
|
-
];
|
|
21
|
+
// TODO(burdon): JSX.
|
|
22
|
+
// TODO(burdon): Effect schema.
|
|
23
|
+
// TODO(burdon): react-buddy for storybook?
|
|
43
24
|
|
|
44
25
|
const Story = () => {
|
|
45
|
-
const object = useMemo(() => createEchoObject({ content:
|
|
26
|
+
const object = useMemo(() => createEchoObject({ content: templates[0].source }), []);
|
|
46
27
|
const initialValue = useMemo(() => object.content, [object]);
|
|
47
28
|
const accessor = useMemo(() => createDocAccessor(object, ['content']), [object]);
|
|
48
29
|
const extensions = useMemo(() => [createDataExtensions({ id: object.id, text: accessor })], [object.id, accessor]);
|
|
49
|
-
|
|
50
|
-
// TODO(wittjosiah): Scroll past end breaks the editor.
|
|
51
|
-
return <TypescriptEditor id='test' initialValue={initialValue} extensions={extensions} scrollPastEnd={false} />;
|
|
30
|
+
return <TypescriptEditor id='test' initialValue={initialValue} extensions={extensions} />;
|
|
52
31
|
};
|
|
53
32
|
|
|
54
33
|
export default {
|
|
@@ -23,13 +23,11 @@ import { nonNullable } from '@dxos/util';
|
|
|
23
23
|
|
|
24
24
|
export type TypescriptEditorProps = {
|
|
25
25
|
id: string;
|
|
26
|
-
scrollPastEnd?: boolean;
|
|
27
26
|
env?: VirtualTypeScriptEnvironment;
|
|
28
27
|
} & Pick<UseTextEditorProps, 'className' | 'initialValue' | 'extensions' | 'scrollTo' | 'selection'>;
|
|
29
28
|
|
|
30
29
|
export const TypescriptEditor = ({
|
|
31
30
|
id,
|
|
32
|
-
scrollPastEnd,
|
|
33
31
|
env,
|
|
34
32
|
className,
|
|
35
33
|
initialValue,
|
|
@@ -49,7 +47,7 @@ export const TypescriptEditor = ({
|
|
|
49
47
|
indentWithTab: true,
|
|
50
48
|
lineNumbers: true,
|
|
51
49
|
lineWrapping: false,
|
|
52
|
-
scrollPastEnd,
|
|
50
|
+
scrollPastEnd: true,
|
|
53
51
|
}),
|
|
54
52
|
createThemeExtensions({
|
|
55
53
|
themeMode,
|
package/src/components/index.ts
CHANGED
|
@@ -4,5 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
export
|
|
8
|
-
|
|
7
|
+
export * from './ScriptSettings';
|
|
8
|
+
|
|
9
|
+
export const ScriptContainer = React.lazy(() => import('./ScriptContainer'));
|
package/src/edge/functions.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { matchServiceCredential } from './hub-protocol';
|
|
|
17
17
|
|
|
18
18
|
// TODO: use URL scheme for source?
|
|
19
19
|
const USERFUNCTIONS_META_KEY = 'dxos.org/service/function';
|
|
20
|
+
export const USERFUNCTIONS_PRESET_META_KEY = 'dxos.org/service/function-preset';
|
|
20
21
|
const USERFUNCTIONS_CREDENTIAL_CAPABILITY = 'composer:beta';
|
|
21
22
|
|
|
22
23
|
// TODO: Synchronize API types with server
|