@dxos/plugin-script 0.6.11 → 0.6.12-main.15a606f

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.
Files changed (179) hide show
  1. package/dist/lib/browser/{ScriptEditor-5Y3EROG3.mjs → ScriptContainer-7DE7USCY.mjs} +257 -106
  2. package/dist/lib/browser/ScriptContainer-7DE7USCY.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-O4LWBX6A.mjs → chunk-CAEANETO.mjs} +2 -2
  4. package/dist/lib/browser/{chunk-O4LWBX6A.mjs.map → chunk-CAEANETO.mjs.map} +2 -2
  5. package/dist/lib/browser/{chunk-DL5XQRQM.mjs → chunk-G6FWCTGT.mjs} +7 -5
  6. package/dist/lib/browser/chunk-G6FWCTGT.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-RHEZ5LUU.mjs → chunk-G6H56WFS.mjs} +51 -2
  8. package/dist/lib/browser/{chunk-RHEZ5LUU.mjs.map → chunk-G6H56WFS.mjs.map} +4 -4
  9. package/dist/lib/browser/{chunk-JBACGDOJ.mjs → chunk-MDX7ACIK.mjs} +3 -6
  10. package/dist/lib/browser/chunk-MDX7ACIK.mjs.map +7 -0
  11. package/dist/lib/browser/edge/index.mjs +3 -1
  12. package/dist/lib/browser/index.mjs +80 -61
  13. package/dist/lib/browser/index.mjs.map +4 -4
  14. package/dist/lib/browser/meta.json +1 -1
  15. package/dist/lib/browser/meta.mjs +1 -1
  16. package/dist/lib/browser/types/index.mjs +2 -2
  17. package/dist/lib/node/ScriptContainer-J76LKPAM.cjs +667 -0
  18. package/dist/lib/node/ScriptContainer-J76LKPAM.cjs.map +7 -0
  19. package/dist/lib/node/{chunk-5RBVXKXT.cjs → chunk-2PZKJXNP.cjs} +6 -6
  20. package/dist/lib/node/{chunk-5RBVXKXT.cjs.map → chunk-2PZKJXNP.cjs.map} +2 -2
  21. package/dist/lib/node/{chunk-4GTXIELQ.cjs → chunk-ACLCRWDB.cjs} +44 -6
  22. package/dist/lib/node/chunk-ACLCRWDB.cjs.map +7 -0
  23. package/dist/lib/node/{TypescriptEditor-M3WWFIP2.cjs → chunk-OJ77BZRH.cjs} +19 -8
  24. package/dist/lib/node/chunk-OJ77BZRH.cjs.map +7 -0
  25. package/dist/lib/node/{chunk-PFH3ROEH.cjs → chunk-UZ3ZXEBF.cjs} +11 -8
  26. package/dist/lib/node/chunk-UZ3ZXEBF.cjs.map +7 -0
  27. package/dist/lib/node/edge/index.cjs +10 -8
  28. package/dist/lib/node/edge/index.cjs.map +2 -2
  29. package/dist/lib/node/index.cjs +93 -79
  30. package/dist/lib/node/index.cjs.map +4 -4
  31. package/dist/lib/node/meta.cjs +3 -3
  32. package/dist/lib/node/meta.cjs.map +1 -1
  33. package/dist/lib/node/meta.json +1 -1
  34. package/dist/lib/node/types/index.cjs +5 -5
  35. package/dist/lib/node/types/index.cjs.map +1 -1
  36. package/dist/lib/node-esm/ScriptContainer-F6ACEA63.mjs +665 -0
  37. package/dist/lib/node-esm/ScriptContainer-F6ACEA63.mjs.map +7 -0
  38. package/dist/lib/node-esm/chunk-2NX3HWPM.mjs +245 -0
  39. package/dist/lib/node-esm/chunk-2NX3HWPM.mjs.map +7 -0
  40. package/dist/lib/node-esm/chunk-7BZDZF7Z.mjs +47 -0
  41. package/dist/lib/node-esm/chunk-7BZDZF7Z.mjs.map +7 -0
  42. package/dist/lib/node-esm/chunk-LDLNTVAK.mjs +280 -0
  43. package/dist/lib/node-esm/chunk-LDLNTVAK.mjs.map +7 -0
  44. package/dist/lib/node-esm/chunk-TZ3Z4SII.mjs +20 -0
  45. package/dist/lib/node-esm/chunk-TZ3Z4SII.mjs.map +7 -0
  46. package/dist/lib/node-esm/edge/index.mjs +22 -0
  47. package/dist/lib/node-esm/index.mjs +311 -0
  48. package/dist/lib/node-esm/index.mjs.map +7 -0
  49. package/dist/lib/node-esm/meta.json +1 -0
  50. package/dist/lib/node-esm/meta.mjs +10 -0
  51. package/dist/lib/node-esm/meta.mjs.map +7 -0
  52. package/dist/lib/node-esm/types/index.mjs +13 -0
  53. package/dist/lib/node-esm/types/index.mjs.map +7 -0
  54. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  55. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +1 -0
  56. package/dist/types/src/components/DebugPanel/index.d.ts +2 -0
  57. package/dist/types/src/components/DebugPanel/index.d.ts.map +1 -0
  58. package/dist/types/src/components/{ScriptBlock/FrameContainer → FrameContainer}/FrameContainer.d.ts +1 -1
  59. package/dist/types/src/components/FrameContainer/FrameContainer.d.ts.map +1 -0
  60. package/dist/types/src/components/FrameContainer/frame.d.ts.map +1 -0
  61. package/dist/types/src/components/FrameContainer/index.d.ts.map +1 -0
  62. package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts +1 -3
  63. package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts.map +1 -1
  64. package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts +1 -1
  65. package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts.map +1 -1
  66. package/dist/types/src/components/ScriptContainer.d.ts +5 -0
  67. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -0
  68. package/dist/types/src/components/ScriptEditor.d.ts +4 -5
  69. package/dist/types/src/components/ScriptEditor.d.ts.map +1 -1
  70. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts +6 -0
  71. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +1 -0
  72. package/dist/types/src/components/ScriptSettings/index.d.ts +2 -0
  73. package/dist/types/src/components/ScriptSettings/index.d.ts.map +1 -0
  74. package/dist/types/src/components/Toolbar/Toolbar.d.ts +23 -0
  75. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -0
  76. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +17 -0
  77. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -0
  78. package/dist/types/src/components/Toolbar/index.d.ts +2 -0
  79. package/dist/types/src/components/Toolbar/index.d.ts.map +1 -0
  80. package/dist/types/src/components/{TypescriptEditor.d.ts → TypescriptEditor/TypescriptEditor.d.ts} +1 -2
  81. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -0
  82. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts +10 -0
  83. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +1 -0
  84. package/dist/types/src/components/TypescriptEditor/index.d.ts +2 -0
  85. package/dist/types/src/components/TypescriptEditor/index.d.ts.map +1 -0
  86. package/dist/types/src/components/index.d.ts +2 -2
  87. package/dist/types/src/components/index.d.ts.map +1 -1
  88. package/dist/types/src/edge/functions.d.ts +1 -0
  89. package/dist/types/src/edge/functions.d.ts.map +1 -1
  90. package/dist/types/src/meta.d.ts +1 -4
  91. package/dist/types/src/meta.d.ts.map +1 -1
  92. package/dist/types/src/templates/chat.d.ts +6 -0
  93. package/dist/types/src/templates/chat.d.ts.map +1 -0
  94. package/dist/types/src/templates/chess.d.ts +6 -0
  95. package/dist/types/src/templates/chess.d.ts.map +1 -0
  96. package/dist/types/src/templates/echo.d.ts +6 -0
  97. package/dist/types/src/templates/echo.d.ts.map +1 -0
  98. package/dist/types/src/templates/email.d.ts +6 -0
  99. package/dist/types/src/templates/email.d.ts.map +1 -0
  100. package/dist/types/src/templates/forex.d.ts +6 -0
  101. package/dist/types/src/templates/forex.d.ts.map +1 -0
  102. package/dist/types/src/templates.d.ts +8 -0
  103. package/dist/types/src/templates.d.ts.map +1 -0
  104. package/dist/types/src/translations.d.ts +2 -0
  105. package/dist/types/src/translations.d.ts.map +1 -1
  106. package/dist/types/src/types/script.d.ts +4 -4
  107. package/dist/types/src/types/types.d.ts +4 -3
  108. package/dist/types/src/types/types.d.ts.map +1 -1
  109. package/package.json +54 -49
  110. package/src/ScriptPlugin.tsx +21 -36
  111. package/src/bundler/bundler.test.ts +12 -2
  112. package/src/components/{DebugPanel.tsx → DebugPanel/DebugPanel.tsx} +48 -41
  113. package/src/components/DebugPanel/index.ts +5 -0
  114. package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/FrameContainer.tsx +1 -1
  115. package/src/components/ScriptBlock/ScriptBlock.stories.tsx +4 -3
  116. package/src/components/ScriptBlock/ScriptBlock.tsx +10 -36
  117. package/src/components/ScriptContainer.tsx +22 -0
  118. package/src/components/ScriptEditor.tsx +47 -46
  119. package/src/components/ScriptSettings/ScriptSettings.tsx +47 -0
  120. package/src/components/ScriptSettings/index.ts +5 -0
  121. package/src/components/{Toolbar.stories.tsx → Toolbar/Toolbar.stories.tsx} +10 -1
  122. package/src/components/Toolbar/Toolbar.tsx +180 -0
  123. package/src/components/{ScriptBlock/Splitter → Toolbar}/index.ts +1 -1
  124. package/src/components/{TypescriptEditor.stories.tsx → TypescriptEditor/TypescriptEditor.stories.tsx} +7 -28
  125. package/src/components/{TypescriptEditor.tsx → TypescriptEditor/TypescriptEditor.tsx} +1 -3
  126. package/src/components/TypescriptEditor/index.ts +5 -0
  127. package/src/components/index.ts +3 -2
  128. package/src/edge/functions.ts +1 -0
  129. package/src/meta.tsx +2 -6
  130. package/src/templates/chat.ts +102 -0
  131. package/src/templates/chess.ts +41 -0
  132. package/src/templates/echo.ts +15 -0
  133. package/src/templates/email.ts +38 -0
  134. package/src/templates/forex.ts +21 -0
  135. package/src/templates.ts +54 -0
  136. package/src/translations.ts +2 -0
  137. package/src/types/types.ts +9 -5
  138. package/dist/lib/browser/ScriptEditor-5Y3EROG3.mjs.map +0 -7
  139. package/dist/lib/browser/TypescriptEditor-GPE72Y6I.mjs +0 -9
  140. package/dist/lib/browser/chunk-DL5XQRQM.mjs.map +0 -7
  141. package/dist/lib/browser/chunk-JBACGDOJ.mjs.map +0 -7
  142. package/dist/lib/browser/chunk-MRGOT5RF.mjs +0 -78
  143. package/dist/lib/browser/chunk-MRGOT5RF.mjs.map +0 -7
  144. package/dist/lib/node/ScriptEditor-YCUQFWQM.cjs +0 -526
  145. package/dist/lib/node/ScriptEditor-YCUQFWQM.cjs.map +0 -7
  146. package/dist/lib/node/TypescriptEditor-M3WWFIP2.cjs.map +0 -7
  147. package/dist/lib/node/chunk-4GTXIELQ.cjs.map +0 -7
  148. package/dist/lib/node/chunk-4VMNBXWU.cjs +0 -54
  149. package/dist/lib/node/chunk-4VMNBXWU.cjs.map +0 -7
  150. package/dist/lib/node/chunk-IMLDKD5Y.cjs +0 -111
  151. package/dist/lib/node/chunk-IMLDKD5Y.cjs.map +0 -7
  152. package/dist/lib/node/chunk-PFH3ROEH.cjs.map +0 -7
  153. package/dist/types/src/components/DebugPanel.d.ts.map +0 -1
  154. package/dist/types/src/components/ScriptBlock/FrameContainer/FrameContainer.d.ts.map +0 -1
  155. package/dist/types/src/components/ScriptBlock/FrameContainer/frame.d.ts.map +0 -1
  156. package/dist/types/src/components/ScriptBlock/FrameContainer/index.d.ts.map +0 -1
  157. package/dist/types/src/components/ScriptBlock/Splitter/Splitter.d.ts +0 -15
  158. package/dist/types/src/components/ScriptBlock/Splitter/Splitter.d.ts.map +0 -1
  159. package/dist/types/src/components/ScriptBlock/Splitter/Splitter.stories.d.ts +0 -13
  160. package/dist/types/src/components/ScriptBlock/Splitter/Splitter.stories.d.ts.map +0 -1
  161. package/dist/types/src/components/ScriptBlock/Splitter/index.d.ts +0 -2
  162. package/dist/types/src/components/ScriptBlock/Splitter/index.d.ts.map +0 -1
  163. package/dist/types/src/components/Toolbar.d.ts +0 -13
  164. package/dist/types/src/components/Toolbar.d.ts.map +0 -1
  165. package/dist/types/src/components/Toolbar.stories.d.ts +0 -14
  166. package/dist/types/src/components/Toolbar.stories.d.ts.map +0 -1
  167. package/dist/types/src/components/TypescriptEditor.d.ts.map +0 -1
  168. package/dist/types/src/components/TypescriptEditor.stories.d.ts +0 -10
  169. package/dist/types/src/components/TypescriptEditor.stories.d.ts.map +0 -1
  170. package/src/components/ScriptBlock/Splitter/Splitter.stories.tsx +0 -37
  171. package/src/components/ScriptBlock/Splitter/Splitter.tsx +0 -52
  172. package/src/components/Toolbar.tsx +0 -147
  173. /package/dist/lib/{browser/TypescriptEditor-GPE72Y6I.mjs.map → node-esm/edge/index.mjs.map} +0 -0
  174. /package/dist/types/src/components/{DebugPanel.d.ts → DebugPanel/DebugPanel.d.ts} +0 -0
  175. /package/dist/types/src/components/{ScriptBlock/FrameContainer → FrameContainer}/frame.d.ts +0 -0
  176. /package/dist/types/src/components/{ScriptBlock/FrameContainer → FrameContainer}/index.d.ts +0 -0
  177. /package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/frame.html +0 -0
  178. /package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/frame.tsx +0 -0
  179. /package/src/components/{ScriptBlock/FrameContainer → FrameContainer}/index.ts +0 -0
@@ -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 '../meta';
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 (non-space ECHO data?)
50
+ // TODO(burdon): Persistent history -- at least for session (non-space ECHO data?)
51
51
  const [history, setHistory] = useState<Message[]>([]);
52
52
 
53
53
  const scrollerRef = useRef<HTMLDivElement>(null);
@@ -215,55 +215,62 @@ 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
-
241
218
  // TODO(burdon): Replace with thread?
242
219
  // TODO(burdon): Button to delete individual messages.
243
- // TODO(burdon): Button to re-run question.
220
+ // TODO(burdon): Button to edit/re-run question.
244
221
  const MessageThread = ({ state, result, history }: { state: State | null; result: string; history: Message[] }) => {
245
222
  return (
246
223
  <>
247
224
  {history.map((message, i) => (
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
- />
225
+ <div key={i} className='grid grid-cols-[3rem_1fr_3rem]'>
226
+ <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>
227
+ <div className='overflow-auto'>
228
+ <MessageItem message={message} />
255
229
  </div>
256
230
  </div>
257
231
  ))}
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 />)}
262
- </div>
263
- <div>
264
- <span>{result}</span>
232
+ {result?.length > 0 && (
233
+ <div className='grid grid-cols-[3rem_1fr_3rem]'>
234
+ <div className='p-1'>
235
+ {(state === 'pending' && <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin' />) || (
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>
265
242
  </div>
266
- </div>
243
+ )}
267
244
  </>
268
245
  );
269
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'}
258
+ </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>
267
+ );
268
+ };
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
+ );
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './DebugPanel';
@@ -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 '../../../bundler';
14
+ import { type BundlerResult } from '../../bundler';
15
15
 
16
16
  export type FrameContainerProps = {
17
17
  containerUrl: string;
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  import '@dxos-theme';
6
+
6
7
  import React, { useEffect, useMemo } from 'react';
7
8
 
8
9
  import { createSpaceObjectGenerator, TestSchemaType } from '@dxos/echo-generator';
@@ -12,10 +13,10 @@ import { create, createEchoObject, useSpaces } from '@dxos/react-client/echo';
12
13
  import { withClientProvider } from '@dxos/react-client/testing';
13
14
  import { withLayout, withTheme } from '@dxos/storybook-utils';
14
15
 
15
- // @ts-ignore
16
- import mainUrl from './FrameContainer/frame?url';
17
16
  import { ScriptBlock } from './ScriptBlock';
18
17
  import { ScriptType } from '../../types';
18
+ // @ts-ignore
19
+ import mainUrl from '../FrameContainer/frame?url';
19
20
 
20
21
  const code = [
21
22
  "import { Filter, useQuery, useSpaces} from '@dxos/react-client/echo';",
@@ -64,7 +65,7 @@ const Story = () => {
64
65
  export default {
65
66
  title: 'plugin-script/ScriptBlock',
66
67
  component: ScriptBlock,
67
- decorators: [withTheme, withLayout({ fullscreen: true, tooltips: true }), withClientProvider({ createSpace: true })],
68
+ decorators: [withClientProvider({ createSpace: true }), withTheme, withLayout({ fullscreen: true, tooltips: true })],
68
69
  render: Story,
69
70
  };
70
71
 
@@ -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, getSize } from '@dxos/react-ui-theme';
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, view],
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
- <Check className={mx(getSize(5), 'text-green-500')} />
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
- <Warning className={mx(getSize(5), 'text-orange-500')} />
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
- <Play className={getSize(5)} />
97
+ <Icon icon='ph--play--regular' size={5} />
124
98
  </Button>
125
99
  </Toolbar.Root>
126
100
  </DensityProvider>
127
101
  )}
128
102
 
129
- <Splitter view={view}>
103
+ <div className='flex'>
130
104
  <ScriptEditor script={script} />
131
105
  {result && <FrameContainer key={script.id} result={result} containerUrl={containerUrl} />}
132
- </Splitter>
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 { useHasAttention } 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 hasAttention = useHasAttention(fullyQualifiedId(script));
15
+ return (
16
+ <div role='none' className={mx('flex row-span-2 w-full overflow-hidden', hasAttention && 'attention-surface')}>
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
- role?: string;
44
- } & Pick<TypescriptEditorProps, 'env'>;
36
+ }> &
37
+ Pick<TypescriptEditorProps, 'env'>;
45
38
 
46
- export const ScriptEditor = ({ env, script, role }: ScriptEditorProps) => {
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 [showPanel, setShowPanel] = useState(false);
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
- showPanel={showPanel}
180
+ view={view}
181
+ templates={templates}
190
182
  onDeploy={handleDeploy}
191
183
  onFormat={handleFormat}
192
- onTogglePanel={async () => setShowPanel((showDetails) => !showDetails)}
184
+ onViewChange={setView}
185
+ onTemplateSelect={handleTemplateChange}
193
186
  />
194
187
 
195
- {showPanel && (
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
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './ScriptSettings';
@@ -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 = { args: { binding: 'example', deployed: true } };
18
+ export const Default = {
19
+ args: {
20
+ binding: 'example',
21
+ deployed: true,
22
+ templates,
23
+ onFormat: () => console.log('Format'),
24
+ onTogglePanel: () => {},
25
+ },
26
+ };