@dxos/plugin-script 0.7.2-main.f1adc9f → 0.7.2

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 (52) hide show
  1. package/dist/lib/browser/{AutomationPanel-ELXXAKW4.mjs → AutomationPanel-BZCRRLOQ.mjs} +9 -14
  2. package/dist/lib/browser/AutomationPanel-BZCRRLOQ.mjs.map +7 -0
  3. package/dist/lib/browser/{ScriptContainer-IC67ILI2.mjs → ScriptContainer-GQ2KJ5BM.mjs} +3 -3
  4. package/dist/lib/browser/{chunk-KSIPC365.mjs → chunk-5GGRYRS4.mjs} +6 -17
  5. package/dist/lib/browser/{chunk-KSIPC365.mjs.map → chunk-5GGRYRS4.mjs.map} +3 -3
  6. package/dist/lib/browser/{chunk-K7KY6YMG.mjs → chunk-NCZUJKJE.mjs} +10 -14
  7. package/dist/lib/browser/chunk-NCZUJKJE.mjs.map +7 -0
  8. package/dist/lib/browser/edge/index.mjs +1 -1
  9. package/dist/lib/browser/index.mjs +3 -3
  10. package/dist/lib/browser/meta.json +1 -1
  11. package/dist/lib/node/{AutomationPanel-RCEBTDK7.cjs → AutomationPanel-VNLNP3EE.cjs} +13 -16
  12. package/dist/lib/node/AutomationPanel-VNLNP3EE.cjs.map +7 -0
  13. package/dist/lib/node/{ScriptContainer-MRZXOY42.cjs → ScriptContainer-K67ZWCKL.cjs} +14 -14
  14. package/dist/lib/node/{chunk-4INUJLXL.cjs → chunk-BJ4WIWCP.cjs} +12 -16
  15. package/dist/lib/node/chunk-BJ4WIWCP.cjs.map +7 -0
  16. package/dist/lib/node/{chunk-2WF3LLHC.cjs → chunk-XS6GEYYH.cjs} +9 -20
  17. package/dist/lib/node/{chunk-2WF3LLHC.cjs.map → chunk-XS6GEYYH.cjs.map} +3 -3
  18. package/dist/lib/node/edge/index.cjs +10 -10
  19. package/dist/lib/node/edge/index.cjs.map +1 -1
  20. package/dist/lib/node/index.cjs +5 -5
  21. package/dist/lib/node/meta.json +1 -1
  22. package/dist/lib/node-esm/{AutomationPanel-QFKOZXLO.mjs → AutomationPanel-NWE2QCOE.mjs} +9 -14
  23. package/dist/lib/node-esm/AutomationPanel-NWE2QCOE.mjs.map +7 -0
  24. package/dist/lib/node-esm/{ScriptContainer-A4A663FM.mjs → ScriptContainer-BVDYLJZI.mjs} +3 -3
  25. package/dist/lib/node-esm/{chunk-OFYGBUNI.mjs → chunk-DXWSRDEN.mjs} +10 -14
  26. package/dist/lib/node-esm/chunk-DXWSRDEN.mjs.map +7 -0
  27. package/dist/lib/node-esm/{chunk-4QWC64VN.mjs → chunk-V74XKPLC.mjs} +6 -17
  28. package/dist/lib/node-esm/{chunk-4QWC64VN.mjs.map → chunk-V74XKPLC.mjs.map} +3 -3
  29. package/dist/lib/node-esm/edge/index.mjs +1 -1
  30. package/dist/lib/node-esm/index.mjs +3 -3
  31. package/dist/lib/node-esm/meta.json +1 -1
  32. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
  33. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +1 -1
  34. package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts +5 -1
  35. package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts.map +1 -1
  36. package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts.map +1 -1
  37. package/dist/types/src/edge/functions.d.ts.map +1 -1
  38. package/package.json +36 -35
  39. package/src/components/AutomationPanel/AutomationPanel.tsx +4 -7
  40. package/src/components/DebugPanel/DebugPanel.tsx +30 -41
  41. package/src/components/ScriptBlock/ScriptBlock.stories.tsx +25 -5
  42. package/src/components/ScriptBlock/ScriptBlock.tsx +8 -3
  43. package/src/edge/functions.ts +1 -12
  44. package/dist/lib/browser/AutomationPanel-ELXXAKW4.mjs.map +0 -7
  45. package/dist/lib/browser/chunk-K7KY6YMG.mjs.map +0 -7
  46. package/dist/lib/node/AutomationPanel-RCEBTDK7.cjs.map +0 -7
  47. package/dist/lib/node/chunk-4INUJLXL.cjs.map +0 -7
  48. package/dist/lib/node-esm/AutomationPanel-QFKOZXLO.mjs.map +0 -7
  49. package/dist/lib/node-esm/chunk-OFYGBUNI.mjs.map +0 -7
  50. /package/dist/lib/browser/{ScriptContainer-IC67ILI2.mjs.map → ScriptContainer-GQ2KJ5BM.mjs.map} +0 -0
  51. /package/dist/lib/node/{ScriptContainer-MRZXOY42.cjs.map → ScriptContainer-K67ZWCKL.cjs.map} +0 -0
  52. /package/dist/lib/node-esm/{ScriptContainer-A4A663FM.mjs.map → ScriptContainer-BVDYLJZI.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-script",
3
- "version": "0.7.2-main.f1adc9f",
3
+ "version": "0.7.2",
4
4
  "description": "Braneframe notebook plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -67,32 +67,32 @@
67
67
  "prettier": "^3.2.4",
68
68
  "react-syntax-highlighter": "^15.5.0",
69
69
  "typescript": "^5.6.2",
70
- "@dxos/app-framework": "0.7.2-main.f1adc9f",
71
- "@dxos/async": "0.7.2-main.f1adc9f",
72
- "@dxos/client": "0.7.2-main.f1adc9f",
73
- "@dxos/client-protocol": "0.7.2-main.f1adc9f",
74
- "@dxos/crypto": "0.7.2-main.f1adc9f",
75
- "@dxos/echo-schema": "0.7.2-main.f1adc9f",
76
- "@dxos/keys": "0.7.2-main.f1adc9f",
77
- "@dxos/debug": "0.7.2-main.f1adc9f",
78
- "@dxos/invariant": "0.7.2-main.f1adc9f",
79
- "@dxos/log": "0.7.2-main.f1adc9f",
80
- "@dxos/plugin-client": "0.7.2-main.f1adc9f",
81
- "@dxos/plugin-markdown": "0.7.2-main.f1adc9f",
82
- "@dxos/plugin-graph": "0.7.2-main.f1adc9f",
83
- "@dxos/plugin-explorer": "0.7.2-main.f1adc9f",
84
- "@dxos/plugin-space": "0.7.2-main.f1adc9f",
85
- "@dxos/plugin-stack": "0.7.2-main.f1adc9f",
86
- "@dxos/plugin-theme": "0.7.2-main.f1adc9f",
87
- "@dxos/protocols": "0.7.2-main.f1adc9f",
88
- "@dxos/react-client": "0.7.2-main.f1adc9f",
89
- "@dxos/react-ui-editor": "0.7.2-main.f1adc9f",
90
- "@dxos/react-ui-attention": "0.7.2-main.f1adc9f",
91
- "@dxos/react-ui-form": "0.7.2-main.f1adc9f",
92
- "@dxos/rpc": "0.7.2-main.f1adc9f",
93
- "@dxos/rpc-tunnel": "0.7.2-main.f1adc9f",
94
- "@dxos/react-ui-syntax-highlighter": "0.7.2-main.f1adc9f",
95
- "@dxos/util": "0.7.2-main.f1adc9f"
70
+ "@dxos/app-framework": "0.7.2",
71
+ "@dxos/async": "0.7.2",
72
+ "@dxos/client": "0.7.2",
73
+ "@dxos/client-protocol": "0.7.2",
74
+ "@dxos/debug": "0.7.2",
75
+ "@dxos/crypto": "0.7.2",
76
+ "@dxos/echo-schema": "0.7.2",
77
+ "@dxos/invariant": "0.7.2",
78
+ "@dxos/keys": "0.7.2",
79
+ "@dxos/log": "0.7.2",
80
+ "@dxos/plugin-client": "0.7.2",
81
+ "@dxos/plugin-explorer": "0.7.2",
82
+ "@dxos/plugin-graph": "0.7.2",
83
+ "@dxos/plugin-markdown": "0.7.2",
84
+ "@dxos/plugin-stack": "0.7.2",
85
+ "@dxos/plugin-space": "0.7.2",
86
+ "@dxos/plugin-theme": "0.7.2",
87
+ "@dxos/protocols": "0.7.2",
88
+ "@dxos/react-client": "0.7.2",
89
+ "@dxos/react-ui-attention": "0.7.2",
90
+ "@dxos/react-ui-syntax-highlighter": "0.7.2",
91
+ "@dxos/react-ui-editor": "0.7.2",
92
+ "@dxos/react-ui-form": "0.7.2",
93
+ "@dxos/rpc": "0.7.2",
94
+ "@dxos/util": "0.7.2",
95
+ "@dxos/rpc-tunnel": "0.7.2"
96
96
  },
97
97
  "devDependencies": {
98
98
  "@phosphor-icons/react": "^2.1.5",
@@ -102,19 +102,20 @@
102
102
  "react": "~18.2.0",
103
103
  "react-dom": "~18.2.0",
104
104
  "vite": "5.4.7",
105
- "@dxos/random": "0.7.2-main.f1adc9f",
106
- "@dxos/react-ui": "0.7.2-main.f1adc9f",
107
- "@dxos/react-ui-mosaic": "0.7.2-main.f1adc9f",
108
- "@dxos/react-ui-theme": "0.7.2-main.f1adc9f",
109
- "@dxos/storybook-utils": "0.7.2-main.f1adc9f"
105
+ "@dxos/echo-generator": "0.7.2",
106
+ "@dxos/random": "0.7.2",
107
+ "@dxos/react-ui": "0.7.2",
108
+ "@dxos/react-ui-mosaic": "0.7.2",
109
+ "@dxos/react-ui-theme": "0.7.2",
110
+ "@dxos/storybook-utils": "0.7.2"
110
111
  },
111
112
  "peerDependencies": {
112
113
  "@phosphor-icons/react": "^2.1.5",
113
114
  "react": "~18.2.0",
114
115
  "react-dom": "~18.2.0",
115
- "@dxos/react-ui": "0.7.2-main.f1adc9f",
116
- "@dxos/react-ui-theme": "0.7.2-main.f1adc9f",
117
- "@dxos/react-ui-mosaic": "0.7.2-main.f1adc9f"
116
+ "@dxos/react-ui": "0.7.2",
117
+ "@dxos/react-ui-theme": "0.7.2",
118
+ "@dxos/react-ui-mosaic": "0.7.2"
118
119
  },
119
120
  "publishConfig": {
120
121
  "access": "public"
@@ -8,10 +8,9 @@ import { type ReactiveEchoObject } from '@dxos/client/echo';
8
8
  import { failUndefined } from '@dxos/debug';
9
9
  import { useClient } from '@dxos/react-client';
10
10
  import { Filter, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';
11
- import { Select, useTranslation } from '@dxos/react-ui';
11
+ import { Select } from '@dxos/react-ui';
12
12
 
13
13
  import { getInvocationUrl, getUserFunctionUrlInMetadata } from '../../edge';
14
- import { SCRIPT_PLUGIN } from '../../meta';
15
14
  import { FunctionType, ScriptType } from '../../types';
16
15
  import { DebugPanel } from '../DebugPanel';
17
16
 
@@ -20,7 +19,6 @@ export interface AutomationPanelProps {
20
19
  }
21
20
 
22
21
  export const AutomationPanel = ({ subject }: AutomationPanelProps) => {
23
- const { t } = useTranslation(SCRIPT_PLUGIN);
24
22
  const space = getSpace(subject);
25
23
 
26
24
  // TODO(dmaretskyi): Parametric query.
@@ -30,9 +28,8 @@ export const AutomationPanel = ({ subject }: AutomationPanelProps) => {
30
28
  {},
31
29
  [subject],
32
30
  );
33
-
34
31
  const [selectedFunction, setSelectedFunction] = useState<FunctionType | null>(null);
35
- const chatFunction = subject instanceof ScriptType ? functions[0] : selectedFunction;
32
+ const functionToChatWith = subject instanceof ScriptType ? functions[0] : selectedFunction;
36
33
 
37
34
  return (
38
35
  <div className='h-full flex flex-col'>
@@ -43,8 +40,8 @@ export const AutomationPanel = ({ subject }: AutomationPanelProps) => {
43
40
  functions={functions}
44
41
  />
45
42
  )}
46
- {chatFunction && <ChatPanel fn={chatFunction} subject={subject} />}
47
- {subject instanceof ScriptType && functions.length === 0 && <div className='p-1'>{t('not deployed')}</div>}
43
+ {functionToChatWith && <ChatPanel fn={functionToChatWith} subject={subject} />}
44
+ {subject instanceof ScriptType && functions.length === 0 && <p>Deploy function to interact with it.</p>}
48
45
  </div>
49
46
  );
50
47
  };
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { forwardRef, useEffect, useRef, useState } from 'react';
5
+ import React, { useEffect, useRef, useState } from 'react';
6
6
 
7
7
  import { log } from '@dxos/log';
8
8
  import { Avatar, Icon, Input, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';
@@ -159,10 +159,12 @@ export const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {
159
159
 
160
160
  return (
161
161
  <div className={mx('flex flex-col h-full overflow-hidden', classNames)}>
162
- {/* TODO(burdon): Replace with Thread. */}
163
- <MessageThread ref={scrollerRef} state={state} result={result} history={history} />
162
+ {/* TODO(burdon): Replace with Thread? */}
163
+ <div ref={scrollerRef} className='flex flex-col gap-6 h-full p-2 overflow-x-hidden overflow-y-auto'>
164
+ <MessageThread state={state} result={result} history={history} />
165
+ </div>
164
166
 
165
- <Toolbar.Root classNames='p-1'>
167
+ <Toolbar.Root classNames='p-2'>
166
168
  <Input.Root>
167
169
  <Input.TextInput
168
170
  ref={inputRef}
@@ -187,45 +189,32 @@ export const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {
187
189
  // TODO(burdon): Replace with thread?
188
190
  // TODO(burdon): Button to delete individual messages.
189
191
  // TODO(burdon): Button to edit/re-run question.
190
- type MessageThreadProps = {
191
- state: State | null;
192
- history: Message[];
193
- result: string;
194
- };
195
-
196
- const MessageThread = forwardRef<HTMLDivElement, MessageThreadProps>(
197
- ({ state, history, result }: MessageThreadProps, forwardedRef) => {
198
- if (!history.length && !result.length) {
199
- return null;
200
- }
201
-
202
- return (
203
- <div ref={forwardedRef} className='flex flex-col gap-6 h-full p-2 overflow-x-hidden overflow-y-auto'>
204
- {history.map((message, i) => (
205
- <div key={i} className='grid grid-cols-[2rem_1fr_2rem]'>
206
- <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>
207
- <div className='overflow-auto'>
208
- <MessageItem message={message} />
209
- </div>
192
+ const MessageThread = ({ state, result, history }: { state: State | null; result: string; history: Message[] }) => {
193
+ return (
194
+ <>
195
+ {history.map((message, i) => (
196
+ <div key={i} className='grid grid-cols-[2rem_1fr_2rem]'>
197
+ <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>
198
+ <div className='overflow-auto'>
199
+ <MessageItem message={message} />
210
200
  </div>
211
- ))}
212
-
213
- {result?.length > 0 && (
214
- <div className='grid grid-cols-[2rem_1fr_2rem]'>
215
- <div className='p-1'>
216
- {(state === 'pending' && <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin' />) || (
217
- <Icon icon='ph--robot--regular' size={6} classNames='animate-[pulse_1s_ease-in-out_infinite]' />
218
- )}
219
- </div>
220
- <div className='overflow-auto'>
221
- <MessageItem message={{ type: 'response', text: result }} />
222
- </div>
201
+ </div>
202
+ ))}
203
+ {result?.length > 0 && (
204
+ <div className='grid grid-cols-[2rem_1fr_2rem]'>
205
+ <div className='p-1'>
206
+ {(state === 'pending' && <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin' />) || (
207
+ <Icon icon='ph--robot--regular' size={6} classNames='animate-[pulse_1s_ease-in-out_infinite]' />
208
+ )}
223
209
  </div>
224
- )}
225
- </div>
226
- );
227
- },
228
- );
210
+ <div className='overflow-auto'>
211
+ <MessageItem message={{ type: 'response', text: result }} />
212
+ </div>
213
+ </div>
214
+ )}
215
+ </>
216
+ );
217
+ };
229
218
 
230
219
  const MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message }>) => {
231
220
  const { type, text, data, error } = message;
@@ -5,10 +5,12 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta } from '@storybook/react';
8
- import React, { useMemo } from 'react';
8
+ import React, { useEffect, useMemo } from 'react';
9
9
 
10
+ import { createSpaceObjectGenerator, TestSchemaType } from '@dxos/echo-generator';
10
11
  import { TextType } from '@dxos/plugin-markdown/types';
11
- import { create, createObject } from '@dxos/react-client/echo';
12
+ import { useClient } from '@dxos/react-client';
13
+ import { create, createObject, useSpaces } from '@dxos/react-client/echo';
12
14
  import { withClientProvider } from '@dxos/react-client/testing';
13
15
  import { withLayout, withTheme } from '@dxos/storybook-utils';
14
16
 
@@ -17,8 +19,6 @@ import { ScriptType } from '../../types';
17
19
  // @ts-ignore
18
20
  import mainUrl from '../FrameContainer/frame?url';
19
21
 
20
- const typename = 'example.com/type/contact';
21
-
22
22
  const code = [
23
23
  "import { Filter, useQuery, useSpaces} from '@dxos/react-client/echo';",
24
24
  "import { Chart, Explorer, Globe } from '@dxos/plugin-explorer';",
@@ -26,12 +26,32 @@ const code = [
26
26
  'export default () => {',
27
27
  ' const spaces = useSpaces();',
28
28
  ' const space = spaces[1]',
29
- ` const objects = useQuery(space, Filter.typename('${typename}'));`,
29
+ " const objects = useQuery(space, Filter.typename('example.com/type/contact'));",
30
30
  ' return <Chart items={objects} accessor={object => ({ x: object.lat, y: object.lng })} />',
31
31
  '}',
32
32
  ].join('\n');
33
33
 
34
34
  const DefaultStory = () => {
35
+ const client = useClient();
36
+ const spaces = useSpaces();
37
+ console.log(spaces.length);
38
+
39
+ useEffect(() => {
40
+ try {
41
+ // TODO(burdon): Default not set.
42
+ const generator = createSpaceObjectGenerator(client.spaces.default);
43
+ generator.addSchemas();
44
+ void generator
45
+ .createObjects({
46
+ [TestSchemaType.organization]: 20,
47
+ [TestSchemaType.contact]: 50,
48
+ })
49
+ .catch(() => {});
50
+ } catch (err) {
51
+ console.log(err);
52
+ }
53
+ }, [client]);
54
+
35
55
  // TODO(burdon): Review what's the right way to create automerge-backed objects.
36
56
  const object = useMemo(() => createObject(create(ScriptType, { source: create(TextType, { content: code }) })), []);
37
57
 
@@ -8,6 +8,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
8
8
 
9
9
  import { createDocAccessor, DocAccessor } from '@dxos/react-client/echo';
10
10
  import { Toolbar, Button, Icon } from '@dxos/react-ui';
11
+ import { mx } from '@dxos/react-ui-theme';
11
12
 
12
13
  import { Bundler, type BundlerResult, initializeBundler } from '../../bundler';
13
14
  import { type ScriptType } from '../../types';
@@ -27,6 +28,10 @@ const PROVIDED_MODULES = [
27
28
  export type ScriptBlockProps = {
28
29
  script: ScriptType;
29
30
  hideSelector?: boolean;
31
+ classes?: {
32
+ root?: string;
33
+ toolbar?: string;
34
+ };
30
35
 
31
36
  // Url to the page used to host the script in the iframe.
32
37
  containerUrl: string;
@@ -36,7 +41,7 @@ export type ScriptBlockProps = {
36
41
  * @deprecated
37
42
  */
38
43
  // TODO(burdon): Cache compiled results in context.
39
- export const ScriptBlock = ({ script, hideSelector, containerUrl }: ScriptBlockProps) => {
44
+ export const ScriptBlock = ({ script, hideSelector, classes, containerUrl }: ScriptBlockProps) => {
40
45
  const source = useMemo(() => script.source && createDocAccessor(script.source, ['content']), [script.source]);
41
46
  const [result, setResult] = useState<BundlerResult>();
42
47
  const bundler = useMemo(
@@ -73,9 +78,9 @@ export const ScriptBlock = ({ script, hideSelector, containerUrl }: ScriptBlockP
73
78
  );
74
79
 
75
80
  return (
76
- <div className='flex flex-col grow overflow-hidden'>
81
+ <div className={mx('flex flex-col grow overflow-hidden', classes?.root)}>
77
82
  {!hideSelector && (
78
- <Toolbar.Root>
83
+ <Toolbar.Root classNames={mx('mb-2', classes?.toolbar)}>
79
84
  <div className='grow' />
80
85
  {result?.bundle && !result?.error && (
81
86
  <div title={String(result.error)}>
@@ -48,18 +48,7 @@ const defaultUserFunctionsBaseUrl = 'https://edge-main.dxos.workers.dev/function
48
48
  const getBaseUrl = (config: Config) => {
49
49
  if (config.values.runtime?.services?.edge?.url) {
50
50
  const url = new URL('/functions', config.values.runtime?.services?.edge?.url);
51
- switch (url.protocol) {
52
- case 'http:':
53
- case 'ws:':
54
- url.protocol = 'http';
55
- break;
56
- case 'https:':
57
- case 'wss:':
58
- url.protocol = 'https';
59
- break;
60
- default:
61
- throw new Error(`Invalid protocol: ${url.protocol}`);
62
- }
51
+ url.protocol = 'https';
63
52
  return url.toString();
64
53
  } else {
65
54
  return defaultUserFunctionsBaseUrl;
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/AutomationPanel/AutomationPanel.tsx", "../../../src/components/AutomationPanel/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useMemo, useState } from 'react';\n\nimport { type ReactiveEchoObject } from '@dxos/client/echo';\nimport { failUndefined } from '@dxos/debug';\nimport { useClient } from '@dxos/react-client';\nimport { Filter, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';\nimport { Select, useTranslation } from '@dxos/react-ui';\n\nimport { getInvocationUrl, getUserFunctionUrlInMetadata } from '../../edge';\nimport { SCRIPT_PLUGIN } from '../../meta';\nimport { FunctionType, ScriptType } from '../../types';\nimport { DebugPanel } from '../DebugPanel';\n\nexport interface AutomationPanelProps {\n subject: ReactiveEchoObject<any>;\n}\n\nexport const AutomationPanel = ({ subject }: AutomationPanelProps) => {\n const { t } = useTranslation(SCRIPT_PLUGIN);\n const space = getSpace(subject);\n\n // TODO(dmaretskyi): Parametric query.\n const functions = useQuery(\n space ?? undefined,\n Filter.schema(FunctionType, (fn) => (subject instanceof ScriptType ? fn.source === subject : fn.binding != null)),\n {},\n [subject],\n );\n\n const [selectedFunction, setSelectedFunction] = useState<FunctionType | null>(null);\n const chatFunction = subject instanceof ScriptType ? functions[0] : selectedFunction;\n\n return (\n <div className='h-full flex flex-col'>\n {!(subject instanceof ScriptType) && (\n <BindingSelect\n selectedFunction={selectedFunction}\n setSelectedFunction={setSelectedFunction}\n functions={functions}\n />\n )}\n {chatFunction && <ChatPanel fn={chatFunction} subject={subject} />}\n {subject instanceof ScriptType && functions.length === 0 && <div className='p-1'>{t('not deployed')}</div>}\n </div>\n );\n};\n\nexport interface ChatPanelProps {\n fn: FunctionType;\n subject: ReactiveEchoObject<any>;\n}\n\nconst ChatPanel = ({ fn, subject }: ChatPanelProps) => {\n const client = useClient();\n const space = getSpace(fn);\n const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));\n const functionUrl = useMemo(() => {\n if (!existingFunctionUrl) {\n return;\n }\n\n return getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? '', {\n spaceId: space?.id,\n subjectId: subject?.id,\n });\n }, [existingFunctionUrl, space, subject]);\n\n return <DebugPanel functionUrl={functionUrl} classNames='flex-1' />;\n};\n\nexport interface BindingSelectProps {\n selectedFunction: FunctionType | null;\n setSelectedFunction: (fn: FunctionType) => void;\n functions: FunctionType[];\n}\n\nconst BindingSelect = ({ selectedFunction, setSelectedFunction, functions }: BindingSelectProps) => {\n return (\n <Select.Root\n value={selectedFunction?.id}\n onValueChange={(id) => setSelectedFunction(functions.find((fn) => fn.id === id) ?? failUndefined())}\n >\n <Select.TriggerButton placeholder='Select value' />\n <Select.Portal>\n <Select.Content>\n <Select.ScrollUpButton />\n <Select.Viewport>\n {functions.map(({ id, binding }) => (\n <Select.Option key={id} value={id}>\n {binding}\n </Select.Option>\n ))}\n </Select.Viewport>\n <Select.ScrollDownButton />\n <Select.Arrow />\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AutomationPanel } from './AutomationPanel';\n\nexport * from './AutomationPanel';\n\nexport default AutomationPanel;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;AAIA,OAAOA,SAASC,SAASC,gBAAgB;AAGzC,SAASC,qBAAqB;AAC9B,SAASC,iBAAiB;AAC1B,SAASC,QAAQC,SAASC,UAAUC,gBAAgB;AACpD,SAASC,QAAQC,sBAAsB;AAWhC,IAAMC,kBAAkB,CAAC,EAAEC,QAAO,MAAwB;AAC/D,QAAM,EAAEC,EAAC,IAAKC,eAAeC,aAAAA;AAC7B,QAAMC,QAAQC,SAASL,OAAAA;AAGvB,QAAMM,YAAYC,SAChBH,SAASI,QACTC,OAAOC,OAAOC,cAAc,CAACC,OAAQZ,mBAAmBa,aAAaD,GAAGE,WAAWd,UAAUY,GAAGG,WAAW,IAAA,GAC3G,CAAC,GACD;IAACf;GAAQ;AAGX,QAAM,CAACgB,kBAAkBC,mBAAAA,IAAuBC,SAA8B,IAAA;AAC9E,QAAMC,eAAenB,mBAAmBa,aAAaP,UAAU,CAAA,IAAKU;AAEpE,SACE,sBAAA,cAACI,OAAAA;IAAIC,WAAU;KACZ,EAAErB,mBAAmBa,eACpB,sBAAA,cAACS,eAAAA;IACCN;IACAC;IACAX;MAGHa,gBAAgB,sBAAA,cAACI,WAAAA;IAAUX,IAAIO;IAAcnB;MAC7CA,mBAAmBa,cAAcP,UAAUkB,WAAW,KAAK,sBAAA,cAACJ,OAAAA;IAAIC,WAAU;KAAOpB,EAAE,cAAA,CAAA,CAAA;AAG1F;AAOA,IAAMsB,YAAY,CAAC,EAAEX,IAAIZ,QAAO,MAAkB;AAChD,QAAMyB,SAASC,UAAAA;AACf,QAAMtB,QAAQC,SAASO,EAAAA;AACvB,QAAMe,sBAAsBC,6BAA6BC,QAAQjB,EAAAA,CAAAA;AACjE,QAAMkB,cAAcC,QAAQ,MAAA;AAC1B,QAAI,CAACJ,qBAAqB;AACxB;IACF;AAEA,WAAOK,iBAAiBL,qBAAqBF,OAAOQ,OAAOC,OAAOC,SAASC,UAAUC,MAAMC,OAAO,IAAI;MACpGC,SAASnC,OAAOoC;MAChBC,WAAWzC,SAASwC;IACtB,CAAA;EACF,GAAG;IAACb;IAAqBvB;IAAOJ;GAAQ;AAExC,SAAO,sBAAA,cAAC0C,YAAAA;IAAWZ;IAA0Ba,YAAW;;AAC1D;AAQA,IAAMrB,gBAAgB,CAAC,EAAEN,kBAAkBC,qBAAqBX,UAAS,MAAsB;AAC7F,SACE,sBAAA,cAACsC,OAAOC,MAAI;IACVC,OAAO9B,kBAAkBwB;IACzBO,eAAe,CAACP,OAAOvB,oBAAoBX,UAAU0C,KAAK,CAACpC,OAAOA,GAAG4B,OAAOA,EAAAA,KAAOS,cAAAA,CAAAA;KAEnF,sBAAA,cAACL,OAAOM,eAAa;IAACC,aAAY;MAClC,sBAAA,cAACP,OAAOQ,QAAM,MACZ,sBAAA,cAACR,OAAOS,SAAO,MACb,sBAAA,cAACT,OAAOU,gBAAc,IAAA,GACtB,sBAAA,cAACV,OAAOW,UAAQ,MACbjD,UAAUkD,IAAI,CAAC,EAAEhB,IAAIzB,QAAO,MAC3B,sBAAA,cAAC6B,OAAOa,QAAM;IAACC,KAAKlB;IAAIM,OAAON;KAC5BzB,OAAAA,CAAAA,CAAAA,GAIP,sBAAA,cAAC6B,OAAOe,kBAAgB,IAAA,GACxB,sBAAA,cAACf,OAAOgB,OAAK,IAAA,CAAA,CAAA,CAAA;AAKvB;;;AC/FA,IAAA,0BAAeC;",
6
- "names": ["React", "useMemo", "useState", "failUndefined", "useClient", "Filter", "getMeta", "getSpace", "useQuery", "Select", "useTranslation", "AutomationPanel", "subject", "t", "useTranslation", "SCRIPT_PLUGIN", "space", "getSpace", "functions", "useQuery", "undefined", "Filter", "schema", "FunctionType", "fn", "ScriptType", "source", "binding", "selectedFunction", "setSelectedFunction", "useState", "chatFunction", "div", "className", "BindingSelect", "ChatPanel", "length", "client", "useClient", "existingFunctionUrl", "getUserFunctionUrlInMetadata", "getMeta", "functionUrl", "useMemo", "getInvocationUrl", "config", "values", "runtime", "services", "edge", "url", "spaceId", "id", "subjectId", "DebugPanel", "classNames", "Select", "Root", "value", "onValueChange", "find", "failUndefined", "TriggerButton", "placeholder", "Portal", "Content", "ScrollUpButton", "Viewport", "map", "Option", "key", "ScrollDownButton", "Arrow", "AutomationPanel"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/DebugPanel/DebugPanel.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useEffect, useRef, useState } from 'react';\n\nimport { log } from '@dxos/log';\nimport { Avatar, Icon, Input, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';\nimport { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { SCRIPT_PLUGIN } from '../../meta';\n\ntype State = 'pending' | 'responding';\n\n/**\n * Request or response.\n */\ntype Message = { type: 'request' | 'response'; text?: string; data?: any; error?: Error };\n\nexport type DebugPanelProps = ThemedClassName<{\n functionUrl?: string;\n}>;\n\nexport const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {\n const { t } = useTranslation(SCRIPT_PLUGIN);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [input, setInput] = useState('');\n const [result, setResult] = useState('');\n const [state, setState] = useState<State | null>(null);\n\n // TODO(burdon): Persistent history -- at least for session (non-space ECHO data?)\n const [history, setHistory] = useState<Message[]>([]);\n\n const scrollerRef = useRef<HTMLDivElement>(null);\n const handleScroll = () => {\n if (scrollerRef.current) {\n scrollerRef.current.scrollTop = scrollerRef.current.scrollHeight;\n }\n };\n\n const controller = useRef<AbortController>();\n useEffect(() => {\n return () => {\n handleStop();\n };\n }, []);\n\n const handleStop = () => {\n controller.current?.abort('stop');\n controller.current = undefined;\n };\n\n const handleClear = () => {\n handleStop();\n setInput('');\n setResult('');\n setHistory([]);\n inputRef.current?.focus();\n };\n\n const handleResponse = ({ text, data, error }: { text?: string; data?: any; error?: Error } = {}) => {\n controller.current = undefined;\n setHistory((history) => [...history, { type: 'response', text, data, error } satisfies Message]);\n setResult('');\n setState(null);\n handleScroll();\n };\n\n const handleRequest = async (input: string) => {\n // Returns a promise that resolves when a value has been received.\n try {\n setState('pending');\n\n let data = null;\n // Detect JSON input.\n if (input.charAt(0) === '{') {\n try {\n const validJsonString = input.replace(/'/g, '\"').replace(/([{,]\\s*)([a-zA-Z0-9_]+)(\\s*:)/g, '$1\"$2\"$3');\n data = JSON.parse(validJsonString);\n input = JSON.stringify(data, null, 2);\n } catch (err) {\n inputRef.current?.focus();\n return;\n }\n }\n\n setInput('');\n setResult('');\n setHistory((history) => [...history, { type: 'request', text: input }]);\n setTimeout(() => {\n handleScroll();\n });\n\n // Throws DOMException when aborted.\n controller.current = new AbortController();\n const response = await fetch(functionUrl!, {\n signal: controller.current.signal,\n method: 'POST',\n body: input,\n headers: {\n 'Content-Type': data ? 'application/json' : 'text/plain',\n },\n });\n\n // Check for error.\n if (!response.ok) {\n const text = await response.text();\n handleResponse({ error: new Error(text || response.statusText || String(response.status)) });\n return;\n }\n\n // Check for JSON.\n const contentType = response.headers.get('content-type');\n if (contentType === 'application/json') {\n const data = await response.json();\n handleResponse({ data });\n return;\n }\n\n // Text (including streaming).\n setState('responding');\n let text = '';\n const reader = response.body!.getReader();\n const pump = async ({ done, value }: ReadableStreamReadResult<Uint8Array>): Promise<void> => {\n text = text + new TextDecoder().decode(value);\n if (!controller.current || done) {\n handleResponse({ text });\n return;\n }\n\n setResult(text);\n setTimeout(() => {\n handleScroll();\n });\n\n return reader.read().then(pump);\n };\n\n void reader\n .read()\n .then(pump)\n .catch((err) => {\n if (err.name !== 'AbortError') {\n log.catch(err);\n }\n });\n } catch (err: any) {\n if (err !== 'stop') {\n const error = err instanceof Error ? err : new Error(err);\n handleResponse({ error });\n log.catch(err);\n } else {\n handleResponse();\n }\n }\n };\n\n return (\n <div className={mx('flex flex-col h-full overflow-hidden', classNames)}>\n {/* TODO(burdon): Replace with Thread. */}\n <MessageThread ref={scrollerRef} state={state} result={result} history={history} />\n\n <Toolbar.Root classNames='p-1'>\n <Input.Root>\n <Input.TextInput\n ref={inputRef}\n autoFocus\n placeholder={t('function request placeholder')}\n value={input}\n onChange={(ev) => setInput(ev.target.value)}\n onKeyDown={(ev) => ev.key === 'Enter' && handleRequest(input)}\n />\n </Input.Root>\n <Toolbar.Button onClick={() => handleRequest(input)}>\n <Icon icon='ph--play--regular' size={4} />\n </Toolbar.Button>\n <Toolbar.Button onClick={() => (state ? handleStop() : handleClear())}>\n <Icon icon={state ? 'ph--stop--regular' : 'ph--trash--regular'} size={4} />\n </Toolbar.Button>\n </Toolbar.Root>\n </div>\n );\n};\n\n// TODO(burdon): Replace with thread?\n// TODO(burdon): Button to delete individual messages.\n// TODO(burdon): Button to edit/re-run question.\ntype MessageThreadProps = {\n state: State | null;\n history: Message[];\n result: string;\n};\n\nconst MessageThread = forwardRef<HTMLDivElement, MessageThreadProps>(\n ({ state, history, result }: MessageThreadProps, forwardedRef) => {\n if (!history.length && !result.length) {\n return null;\n }\n\n return (\n <div ref={forwardedRef} className='flex flex-col gap-6 h-full p-2 overflow-x-hidden overflow-y-auto'>\n {history.map((message, i) => (\n <div key={i} className='grid grid-cols-[2rem_1fr_2rem]'>\n <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>\n <div className='overflow-auto'>\n <MessageItem message={message} />\n </div>\n </div>\n ))}\n\n {result?.length > 0 && (\n <div className='grid grid-cols-[2rem_1fr_2rem]'>\n <div className='p-1'>\n {(state === 'pending' && <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin' />) || (\n <Icon icon='ph--robot--regular' size={6} classNames='animate-[pulse_1s_ease-in-out_infinite]' />\n )}\n </div>\n <div className='overflow-auto'>\n <MessageItem message={{ type: 'response', text: result }} />\n </div>\n </div>\n )}\n </div>\n );\n },\n);\n\nconst MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message }>) => {\n const { type, text, data, error } = message;\n const wrapper = 'p-1 px-2 rounded-lg bg-hoverSurface overflow-auto';\n return (\n <div className={mx('flex', type === 'request' ? 'ml-[1rem] justify-end' : 'mr-[1rem]', classNames)}>\n {error && <div className={mx(wrapper, 'whitespace-pre text-error')}>{String(error)}</div>}\n\n {text !== undefined && (\n <div className={mx(wrapper, type === 'request' && 'bg-primary-400 dark:bg-primary-600')}>\n {text || '\\u00D8'}\n </div>\n )}\n\n {data && (\n <SyntaxHighlighter language='json' className={mx(wrapper, 'px-8 py-2 text-xs')}>\n {JSON.stringify(data, null, 2)}\n </SyntaxHighlighter>\n )}\n </div>\n );\n};\n\nconst RobotAvatar = () => (\n <Avatar.Root size={6} variant='circle'>\n <Avatar.Frame>\n <Avatar.Icon icon='ph--robot--regular' />\n </Avatar.Frame>\n </Avatar.Root>\n);\n"],
5
- "mappings": "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",
6
- "names": ["React", "forwardRef", "useEffect", "useRef", "useState", "log", "Avatar", "Icon", "Input", "Toolbar", "useTranslation", "SyntaxHighlighter", "mx", "DebugPanel", "classNames", "functionUrl", "t", "useTranslation", "SCRIPT_PLUGIN", "inputRef", "useRef", "input", "setInput", "useState", "result", "setResult", "state", "setState", "history", "setHistory", "scrollerRef", "handleScroll", "current", "scrollTop", "scrollHeight", "controller", "useEffect", "handleStop", "abort", "undefined", "handleClear", "focus", "handleResponse", "text", "data", "error", "type", "handleRequest", "charAt", "validJsonString", "replace", "JSON", "parse", "stringify", "err", "setTimeout", "AbortController", "response", "fetch", "signal", "method", "body", "headers", "ok", "Error", "statusText", "String", "status", "contentType", "get", "json", "reader", "getReader", "pump", "done", "value", "TextDecoder", "decode", "read", "then", "catch", "name", "log", "div", "className", "mx", "MessageThread", "ref", "Toolbar", "Root", "Input", "TextInput", "autoFocus", "placeholder", "onChange", "ev", "target", "onKeyDown", "key", "Button", "onClick", "Icon", "icon", "size", "forwardRef", "forwardedRef", "length", "map", "message", "i", "RobotAvatar", "MessageItem", "wrapper", "SyntaxHighlighter", "language", "Avatar", "variant", "Frame"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/AutomationPanel/AutomationPanel.tsx", "../../../src/components/AutomationPanel/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useMemo, useState } from 'react';\n\nimport { type ReactiveEchoObject } from '@dxos/client/echo';\nimport { failUndefined } from '@dxos/debug';\nimport { useClient } from '@dxos/react-client';\nimport { Filter, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';\nimport { Select, useTranslation } from '@dxos/react-ui';\n\nimport { getInvocationUrl, getUserFunctionUrlInMetadata } from '../../edge';\nimport { SCRIPT_PLUGIN } from '../../meta';\nimport { FunctionType, ScriptType } from '../../types';\nimport { DebugPanel } from '../DebugPanel';\n\nexport interface AutomationPanelProps {\n subject: ReactiveEchoObject<any>;\n}\n\nexport const AutomationPanel = ({ subject }: AutomationPanelProps) => {\n const { t } = useTranslation(SCRIPT_PLUGIN);\n const space = getSpace(subject);\n\n // TODO(dmaretskyi): Parametric query.\n const functions = useQuery(\n space ?? undefined,\n Filter.schema(FunctionType, (fn) => (subject instanceof ScriptType ? fn.source === subject : fn.binding != null)),\n {},\n [subject],\n );\n\n const [selectedFunction, setSelectedFunction] = useState<FunctionType | null>(null);\n const chatFunction = subject instanceof ScriptType ? functions[0] : selectedFunction;\n\n return (\n <div className='h-full flex flex-col'>\n {!(subject instanceof ScriptType) && (\n <BindingSelect\n selectedFunction={selectedFunction}\n setSelectedFunction={setSelectedFunction}\n functions={functions}\n />\n )}\n {chatFunction && <ChatPanel fn={chatFunction} subject={subject} />}\n {subject instanceof ScriptType && functions.length === 0 && <div className='p-1'>{t('not deployed')}</div>}\n </div>\n );\n};\n\nexport interface ChatPanelProps {\n fn: FunctionType;\n subject: ReactiveEchoObject<any>;\n}\n\nconst ChatPanel = ({ fn, subject }: ChatPanelProps) => {\n const client = useClient();\n const space = getSpace(fn);\n const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));\n const functionUrl = useMemo(() => {\n if (!existingFunctionUrl) {\n return;\n }\n\n return getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? '', {\n spaceId: space?.id,\n subjectId: subject?.id,\n });\n }, [existingFunctionUrl, space, subject]);\n\n return <DebugPanel functionUrl={functionUrl} classNames='flex-1' />;\n};\n\nexport interface BindingSelectProps {\n selectedFunction: FunctionType | null;\n setSelectedFunction: (fn: FunctionType) => void;\n functions: FunctionType[];\n}\n\nconst BindingSelect = ({ selectedFunction, setSelectedFunction, functions }: BindingSelectProps) => {\n return (\n <Select.Root\n value={selectedFunction?.id}\n onValueChange={(id) => setSelectedFunction(functions.find((fn) => fn.id === id) ?? failUndefined())}\n >\n <Select.TriggerButton placeholder='Select value' />\n <Select.Portal>\n <Select.Content>\n <Select.ScrollUpButton />\n <Select.Viewport>\n {functions.map(({ id, binding }) => (\n <Select.Option key={id} value={id}>\n {binding}\n </Select.Option>\n ))}\n </Select.Viewport>\n <Select.ScrollDownButton />\n <Select.Arrow />\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AutomationPanel } from './AutomationPanel';\n\nexport * from './AutomationPanel';\n\nexport default AutomationPanel;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mBAAyC;AAGzC,mBAA8B;AAC9B,0BAA0B;AAC1B,kBAAoD;AACpD,sBAAuC;AAWhC,IAAMA,kBAAkB,CAAC,EAAEC,QAAO,MAAwB;AAC/D,QAAM,EAAEC,EAAC,QAAKC,gCAAeC,mCAAAA;AAC7B,QAAMC,YAAQC,sBAASL,OAAAA;AAGvB,QAAMM,gBAAYC,sBAChBH,SAASI,QACTC,mBAAOC,OAAOC,oCAAc,CAACC,OAAQZ,mBAAmBa,mCAAaD,GAAGE,WAAWd,UAAUY,GAAGG,WAAW,IAAA,GAC3G,CAAC,GACD;IAACf;GAAQ;AAGX,QAAM,CAACgB,kBAAkBC,mBAAAA,QAAuBC,uBAA8B,IAAA;AAC9E,QAAMC,eAAenB,mBAAmBa,mCAAaP,UAAU,CAAA,IAAKU;AAEpE,SACE,6BAAAI,QAAA,cAACC,OAAAA;IAAIC,WAAU;KACZ,EAAEtB,mBAAmBa,qCACpB,6BAAAO,QAAA,cAACG,eAAAA;IACCP;IACAC;IACAX;MAGHa,gBAAgB,6BAAAC,QAAA,cAACI,WAAAA;IAAUZ,IAAIO;IAAcnB;MAC7CA,mBAAmBa,oCAAcP,UAAUmB,WAAW,KAAK,6BAAAL,QAAA,cAACC,OAAAA;IAAIC,WAAU;KAAOrB,EAAE,cAAA,CAAA,CAAA;AAG1F;AAOA,IAAMuB,YAAY,CAAC,EAAEZ,IAAIZ,QAAO,MAAkB;AAChD,QAAM0B,aAASC,+BAAAA;AACf,QAAMvB,YAAQC,sBAASO,EAAAA;AACvB,QAAMgB,0BAAsBC,wDAA6BC,qBAAQlB,EAAAA,CAAAA;AACjE,QAAMmB,kBAAcC,sBAAQ,MAAA;AAC1B,QAAI,CAACJ,qBAAqB;AACxB;IACF;AAEA,eAAOK,wCAAiBL,qBAAqBF,OAAOQ,OAAOC,OAAOC,SAASC,UAAUC,MAAMC,OAAO,IAAI;MACpGC,SAASpC,OAAOqC;MAChBC,WAAW1C,SAASyC;IACtB,CAAA;EACF,GAAG;IAACb;IAAqBxB;IAAOJ;GAAQ;AAExC,SAAO,6BAAAoB,QAAA,cAACuB,kCAAAA;IAAWZ;IAA0Ba,YAAW;;AAC1D;AAQA,IAAMrB,gBAAgB,CAAC,EAAEP,kBAAkBC,qBAAqBX,UAAS,MAAsB;AAC7F,SACE,6BAAAc,QAAA,cAACyB,uBAAOC,MAAI;IACVC,OAAO/B,kBAAkByB;IACzBO,eAAe,CAACP,OAAOxB,oBAAoBX,UAAU2C,KAAK,CAACrC,OAAOA,GAAG6B,OAAOA,EAAAA,SAAOS,4BAAAA,CAAAA;KAEnF,6BAAA9B,QAAA,cAACyB,uBAAOM,eAAa;IAACC,aAAY;MAClC,6BAAAhC,QAAA,cAACyB,uBAAOQ,QAAM,MACZ,6BAAAjC,QAAA,cAACyB,uBAAOS,SAAO,MACb,6BAAAlC,QAAA,cAACyB,uBAAOU,gBAAc,IAAA,GACtB,6BAAAnC,QAAA,cAACyB,uBAAOW,UAAQ,MACblD,UAAUmD,IAAI,CAAC,EAAEhB,IAAI1B,QAAO,MAC3B,6BAAAK,QAAA,cAACyB,uBAAOa,QAAM;IAACC,KAAKlB;IAAIM,OAAON;KAC5B1B,OAAAA,CAAAA,CAAAA,GAIP,6BAAAK,QAAA,cAACyB,uBAAOe,kBAAgB,IAAA,GACxB,6BAAAxC,QAAA,cAACyB,uBAAOgB,OAAK,IAAA,CAAA,CAAA,CAAA;AAKvB;AC/FA,IAAA,0BAAe9D;",
6
- "names": ["AutomationPanel", "subject", "t", "useTranslation", "SCRIPT_PLUGIN", "space", "getSpace", "functions", "useQuery", "undefined", "Filter", "schema", "FunctionType", "fn", "ScriptType", "source", "binding", "selectedFunction", "setSelectedFunction", "useState", "chatFunction", "React", "div", "className", "BindingSelect", "ChatPanel", "length", "client", "useClient", "existingFunctionUrl", "getUserFunctionUrlInMetadata", "getMeta", "functionUrl", "useMemo", "getInvocationUrl", "config", "values", "runtime", "services", "edge", "url", "spaceId", "id", "subjectId", "DebugPanel", "classNames", "Select", "Root", "value", "onValueChange", "find", "failUndefined", "TriggerButton", "placeholder", "Portal", "Content", "ScrollUpButton", "Viewport", "map", "Option", "key", "ScrollDownButton", "Arrow"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/DebugPanel/DebugPanel.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useEffect, useRef, useState } from 'react';\n\nimport { log } from '@dxos/log';\nimport { Avatar, Icon, Input, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';\nimport { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { SCRIPT_PLUGIN } from '../../meta';\n\ntype State = 'pending' | 'responding';\n\n/**\n * Request or response.\n */\ntype Message = { type: 'request' | 'response'; text?: string; data?: any; error?: Error };\n\nexport type DebugPanelProps = ThemedClassName<{\n functionUrl?: string;\n}>;\n\nexport const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {\n const { t } = useTranslation(SCRIPT_PLUGIN);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [input, setInput] = useState('');\n const [result, setResult] = useState('');\n const [state, setState] = useState<State | null>(null);\n\n // TODO(burdon): Persistent history -- at least for session (non-space ECHO data?)\n const [history, setHistory] = useState<Message[]>([]);\n\n const scrollerRef = useRef<HTMLDivElement>(null);\n const handleScroll = () => {\n if (scrollerRef.current) {\n scrollerRef.current.scrollTop = scrollerRef.current.scrollHeight;\n }\n };\n\n const controller = useRef<AbortController>();\n useEffect(() => {\n return () => {\n handleStop();\n };\n }, []);\n\n const handleStop = () => {\n controller.current?.abort('stop');\n controller.current = undefined;\n };\n\n const handleClear = () => {\n handleStop();\n setInput('');\n setResult('');\n setHistory([]);\n inputRef.current?.focus();\n };\n\n const handleResponse = ({ text, data, error }: { text?: string; data?: any; error?: Error } = {}) => {\n controller.current = undefined;\n setHistory((history) => [...history, { type: 'response', text, data, error } satisfies Message]);\n setResult('');\n setState(null);\n handleScroll();\n };\n\n const handleRequest = async (input: string) => {\n // Returns a promise that resolves when a value has been received.\n try {\n setState('pending');\n\n let data = null;\n // Detect JSON input.\n if (input.charAt(0) === '{') {\n try {\n const validJsonString = input.replace(/'/g, '\"').replace(/([{,]\\s*)([a-zA-Z0-9_]+)(\\s*:)/g, '$1\"$2\"$3');\n data = JSON.parse(validJsonString);\n input = JSON.stringify(data, null, 2);\n } catch (err) {\n inputRef.current?.focus();\n return;\n }\n }\n\n setInput('');\n setResult('');\n setHistory((history) => [...history, { type: 'request', text: input }]);\n setTimeout(() => {\n handleScroll();\n });\n\n // Throws DOMException when aborted.\n controller.current = new AbortController();\n const response = await fetch(functionUrl!, {\n signal: controller.current.signal,\n method: 'POST',\n body: input,\n headers: {\n 'Content-Type': data ? 'application/json' : 'text/plain',\n },\n });\n\n // Check for error.\n if (!response.ok) {\n const text = await response.text();\n handleResponse({ error: new Error(text || response.statusText || String(response.status)) });\n return;\n }\n\n // Check for JSON.\n const contentType = response.headers.get('content-type');\n if (contentType === 'application/json') {\n const data = await response.json();\n handleResponse({ data });\n return;\n }\n\n // Text (including streaming).\n setState('responding');\n let text = '';\n const reader = response.body!.getReader();\n const pump = async ({ done, value }: ReadableStreamReadResult<Uint8Array>): Promise<void> => {\n text = text + new TextDecoder().decode(value);\n if (!controller.current || done) {\n handleResponse({ text });\n return;\n }\n\n setResult(text);\n setTimeout(() => {\n handleScroll();\n });\n\n return reader.read().then(pump);\n };\n\n void reader\n .read()\n .then(pump)\n .catch((err) => {\n if (err.name !== 'AbortError') {\n log.catch(err);\n }\n });\n } catch (err: any) {\n if (err !== 'stop') {\n const error = err instanceof Error ? err : new Error(err);\n handleResponse({ error });\n log.catch(err);\n } else {\n handleResponse();\n }\n }\n };\n\n return (\n <div className={mx('flex flex-col h-full overflow-hidden', classNames)}>\n {/* TODO(burdon): Replace with Thread. */}\n <MessageThread ref={scrollerRef} state={state} result={result} history={history} />\n\n <Toolbar.Root classNames='p-1'>\n <Input.Root>\n <Input.TextInput\n ref={inputRef}\n autoFocus\n placeholder={t('function request placeholder')}\n value={input}\n onChange={(ev) => setInput(ev.target.value)}\n onKeyDown={(ev) => ev.key === 'Enter' && handleRequest(input)}\n />\n </Input.Root>\n <Toolbar.Button onClick={() => handleRequest(input)}>\n <Icon icon='ph--play--regular' size={4} />\n </Toolbar.Button>\n <Toolbar.Button onClick={() => (state ? handleStop() : handleClear())}>\n <Icon icon={state ? 'ph--stop--regular' : 'ph--trash--regular'} size={4} />\n </Toolbar.Button>\n </Toolbar.Root>\n </div>\n );\n};\n\n// TODO(burdon): Replace with thread?\n// TODO(burdon): Button to delete individual messages.\n// TODO(burdon): Button to edit/re-run question.\ntype MessageThreadProps = {\n state: State | null;\n history: Message[];\n result: string;\n};\n\nconst MessageThread = forwardRef<HTMLDivElement, MessageThreadProps>(\n ({ state, history, result }: MessageThreadProps, forwardedRef) => {\n if (!history.length && !result.length) {\n return null;\n }\n\n return (\n <div ref={forwardedRef} className='flex flex-col gap-6 h-full p-2 overflow-x-hidden overflow-y-auto'>\n {history.map((message, i) => (\n <div key={i} className='grid grid-cols-[2rem_1fr_2rem]'>\n <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>\n <div className='overflow-auto'>\n <MessageItem message={message} />\n </div>\n </div>\n ))}\n\n {result?.length > 0 && (\n <div className='grid grid-cols-[2rem_1fr_2rem]'>\n <div className='p-1'>\n {(state === 'pending' && <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin' />) || (\n <Icon icon='ph--robot--regular' size={6} classNames='animate-[pulse_1s_ease-in-out_infinite]' />\n )}\n </div>\n <div className='overflow-auto'>\n <MessageItem message={{ type: 'response', text: result }} />\n </div>\n </div>\n )}\n </div>\n );\n },\n);\n\nconst MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message }>) => {\n const { type, text, data, error } = message;\n const wrapper = 'p-1 px-2 rounded-lg bg-hoverSurface overflow-auto';\n return (\n <div className={mx('flex', type === 'request' ? 'ml-[1rem] justify-end' : 'mr-[1rem]', classNames)}>\n {error && <div className={mx(wrapper, 'whitespace-pre text-error')}>{String(error)}</div>}\n\n {text !== undefined && (\n <div className={mx(wrapper, type === 'request' && 'bg-primary-400 dark:bg-primary-600')}>\n {text || '\\u00D8'}\n </div>\n )}\n\n {data && (\n <SyntaxHighlighter language='json' className={mx(wrapper, 'px-8 py-2 text-xs')}>\n {JSON.stringify(data, null, 2)}\n </SyntaxHighlighter>\n )}\n </div>\n );\n};\n\nconst RobotAvatar = () => (\n <Avatar.Root size={6} variant='circle'>\n <Avatar.Frame>\n <Avatar.Icon icon='ph--robot--regular' />\n </Avatar.Frame>\n </Avatar.Root>\n);\n"],
5
- "mappings": "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",
6
- "names": ["DebugPanel", "classNames", "functionUrl", "t", "useTranslation", "SCRIPT_PLUGIN", "inputRef", "useRef", "input", "setInput", "useState", "result", "setResult", "state", "setState", "history", "setHistory", "scrollerRef", "handleScroll", "current", "scrollTop", "scrollHeight", "controller", "useEffect", "handleStop", "abort", "undefined", "handleClear", "focus", "handleResponse", "text", "data", "error", "type", "handleRequest", "charAt", "validJsonString", "replace", "JSON", "parse", "stringify", "err", "setTimeout", "AbortController", "response", "fetch", "signal", "method", "body", "headers", "ok", "Error", "statusText", "String", "status", "contentType", "get", "json", "reader", "getReader", "pump", "done", "value", "TextDecoder", "decode", "read", "then", "catch", "name", "log", "React", "div", "className", "mx", "MessageThread", "ref", "Toolbar", "Root", "Input", "TextInput", "autoFocus", "placeholder", "onChange", "ev", "target", "onKeyDown", "key", "Button", "onClick", "Icon", "icon", "size", "forwardRef", "forwardedRef", "length", "map", "message", "i", "RobotAvatar", "MessageItem", "wrapper", "SyntaxHighlighter", "language", "Avatar", "variant", "Frame"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/AutomationPanel/AutomationPanel.tsx", "../../../src/components/AutomationPanel/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useMemo, useState } from 'react';\n\nimport { type ReactiveEchoObject } from '@dxos/client/echo';\nimport { failUndefined } from '@dxos/debug';\nimport { useClient } from '@dxos/react-client';\nimport { Filter, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';\nimport { Select, useTranslation } from '@dxos/react-ui';\n\nimport { getInvocationUrl, getUserFunctionUrlInMetadata } from '../../edge';\nimport { SCRIPT_PLUGIN } from '../../meta';\nimport { FunctionType, ScriptType } from '../../types';\nimport { DebugPanel } from '../DebugPanel';\n\nexport interface AutomationPanelProps {\n subject: ReactiveEchoObject<any>;\n}\n\nexport const AutomationPanel = ({ subject }: AutomationPanelProps) => {\n const { t } = useTranslation(SCRIPT_PLUGIN);\n const space = getSpace(subject);\n\n // TODO(dmaretskyi): Parametric query.\n const functions = useQuery(\n space ?? undefined,\n Filter.schema(FunctionType, (fn) => (subject instanceof ScriptType ? fn.source === subject : fn.binding != null)),\n {},\n [subject],\n );\n\n const [selectedFunction, setSelectedFunction] = useState<FunctionType | null>(null);\n const chatFunction = subject instanceof ScriptType ? functions[0] : selectedFunction;\n\n return (\n <div className='h-full flex flex-col'>\n {!(subject instanceof ScriptType) && (\n <BindingSelect\n selectedFunction={selectedFunction}\n setSelectedFunction={setSelectedFunction}\n functions={functions}\n />\n )}\n {chatFunction && <ChatPanel fn={chatFunction} subject={subject} />}\n {subject instanceof ScriptType && functions.length === 0 && <div className='p-1'>{t('not deployed')}</div>}\n </div>\n );\n};\n\nexport interface ChatPanelProps {\n fn: FunctionType;\n subject: ReactiveEchoObject<any>;\n}\n\nconst ChatPanel = ({ fn, subject }: ChatPanelProps) => {\n const client = useClient();\n const space = getSpace(fn);\n const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));\n const functionUrl = useMemo(() => {\n if (!existingFunctionUrl) {\n return;\n }\n\n return getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? '', {\n spaceId: space?.id,\n subjectId: subject?.id,\n });\n }, [existingFunctionUrl, space, subject]);\n\n return <DebugPanel functionUrl={functionUrl} classNames='flex-1' />;\n};\n\nexport interface BindingSelectProps {\n selectedFunction: FunctionType | null;\n setSelectedFunction: (fn: FunctionType) => void;\n functions: FunctionType[];\n}\n\nconst BindingSelect = ({ selectedFunction, setSelectedFunction, functions }: BindingSelectProps) => {\n return (\n <Select.Root\n value={selectedFunction?.id}\n onValueChange={(id) => setSelectedFunction(functions.find((fn) => fn.id === id) ?? failUndefined())}\n >\n <Select.TriggerButton placeholder='Select value' />\n <Select.Portal>\n <Select.Content>\n <Select.ScrollUpButton />\n <Select.Viewport>\n {functions.map(({ id, binding }) => (\n <Select.Option key={id} value={id}>\n {binding}\n </Select.Option>\n ))}\n </Select.Viewport>\n <Select.ScrollDownButton />\n <Select.Arrow />\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AutomationPanel } from './AutomationPanel';\n\nexport * from './AutomationPanel';\n\nexport default AutomationPanel;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAIA,OAAOA,SAASC,SAASC,gBAAgB;AAGzC,SAASC,qBAAqB;AAC9B,SAASC,iBAAiB;AAC1B,SAASC,QAAQC,SAASC,UAAUC,gBAAgB;AACpD,SAASC,QAAQC,sBAAsB;AAWhC,IAAMC,kBAAkB,CAAC,EAAEC,QAAO,MAAwB;AAC/D,QAAM,EAAEC,EAAC,IAAKC,eAAeC,aAAAA;AAC7B,QAAMC,QAAQC,SAASL,OAAAA;AAGvB,QAAMM,YAAYC,SAChBH,SAASI,QACTC,OAAOC,OAAOC,cAAc,CAACC,OAAQZ,mBAAmBa,aAAaD,GAAGE,WAAWd,UAAUY,GAAGG,WAAW,IAAA,GAC3G,CAAC,GACD;IAACf;GAAQ;AAGX,QAAM,CAACgB,kBAAkBC,mBAAAA,IAAuBC,SAA8B,IAAA;AAC9E,QAAMC,eAAenB,mBAAmBa,aAAaP,UAAU,CAAA,IAAKU;AAEpE,SACE,sBAAA,cAACI,OAAAA;IAAIC,WAAU;KACZ,EAAErB,mBAAmBa,eACpB,sBAAA,cAACS,eAAAA;IACCN;IACAC;IACAX;MAGHa,gBAAgB,sBAAA,cAACI,WAAAA;IAAUX,IAAIO;IAAcnB;MAC7CA,mBAAmBa,cAAcP,UAAUkB,WAAW,KAAK,sBAAA,cAACJ,OAAAA;IAAIC,WAAU;KAAOpB,EAAE,cAAA,CAAA,CAAA;AAG1F;AAOA,IAAMsB,YAAY,CAAC,EAAEX,IAAIZ,QAAO,MAAkB;AAChD,QAAMyB,SAASC,UAAAA;AACf,QAAMtB,QAAQC,SAASO,EAAAA;AACvB,QAAMe,sBAAsBC,6BAA6BC,QAAQjB,EAAAA,CAAAA;AACjE,QAAMkB,cAAcC,QAAQ,MAAA;AAC1B,QAAI,CAACJ,qBAAqB;AACxB;IACF;AAEA,WAAOK,iBAAiBL,qBAAqBF,OAAOQ,OAAOC,OAAOC,SAASC,UAAUC,MAAMC,OAAO,IAAI;MACpGC,SAASnC,OAAOoC;MAChBC,WAAWzC,SAASwC;IACtB,CAAA;EACF,GAAG;IAACb;IAAqBvB;IAAOJ;GAAQ;AAExC,SAAO,sBAAA,cAAC0C,YAAAA;IAAWZ;IAA0Ba,YAAW;;AAC1D;AAQA,IAAMrB,gBAAgB,CAAC,EAAEN,kBAAkBC,qBAAqBX,UAAS,MAAsB;AAC7F,SACE,sBAAA,cAACsC,OAAOC,MAAI;IACVC,OAAO9B,kBAAkBwB;IACzBO,eAAe,CAACP,OAAOvB,oBAAoBX,UAAU0C,KAAK,CAACpC,OAAOA,GAAG4B,OAAOA,EAAAA,KAAOS,cAAAA,CAAAA;KAEnF,sBAAA,cAACL,OAAOM,eAAa;IAACC,aAAY;MAClC,sBAAA,cAACP,OAAOQ,QAAM,MACZ,sBAAA,cAACR,OAAOS,SAAO,MACb,sBAAA,cAACT,OAAOU,gBAAc,IAAA,GACtB,sBAAA,cAACV,OAAOW,UAAQ,MACbjD,UAAUkD,IAAI,CAAC,EAAEhB,IAAIzB,QAAO,MAC3B,sBAAA,cAAC6B,OAAOa,QAAM;IAACC,KAAKlB;IAAIM,OAAON;KAC5BzB,OAAAA,CAAAA,CAAAA,GAIP,sBAAA,cAAC6B,OAAOe,kBAAgB,IAAA,GACxB,sBAAA,cAACf,OAAOgB,OAAK,IAAA,CAAA,CAAA,CAAA;AAKvB;;;AC/FA,IAAA,0BAAeC;",
6
- "names": ["React", "useMemo", "useState", "failUndefined", "useClient", "Filter", "getMeta", "getSpace", "useQuery", "Select", "useTranslation", "AutomationPanel", "subject", "t", "useTranslation", "SCRIPT_PLUGIN", "space", "getSpace", "functions", "useQuery", "undefined", "Filter", "schema", "FunctionType", "fn", "ScriptType", "source", "binding", "selectedFunction", "setSelectedFunction", "useState", "chatFunction", "div", "className", "BindingSelect", "ChatPanel", "length", "client", "useClient", "existingFunctionUrl", "getUserFunctionUrlInMetadata", "getMeta", "functionUrl", "useMemo", "getInvocationUrl", "config", "values", "runtime", "services", "edge", "url", "spaceId", "id", "subjectId", "DebugPanel", "classNames", "Select", "Root", "value", "onValueChange", "find", "failUndefined", "TriggerButton", "placeholder", "Portal", "Content", "ScrollUpButton", "Viewport", "map", "Option", "key", "ScrollDownButton", "Arrow", "AutomationPanel"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/DebugPanel/DebugPanel.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useEffect, useRef, useState } from 'react';\n\nimport { log } from '@dxos/log';\nimport { Avatar, Icon, Input, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';\nimport { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { SCRIPT_PLUGIN } from '../../meta';\n\ntype State = 'pending' | 'responding';\n\n/**\n * Request or response.\n */\ntype Message = { type: 'request' | 'response'; text?: string; data?: any; error?: Error };\n\nexport type DebugPanelProps = ThemedClassName<{\n functionUrl?: string;\n}>;\n\nexport const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {\n const { t } = useTranslation(SCRIPT_PLUGIN);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [input, setInput] = useState('');\n const [result, setResult] = useState('');\n const [state, setState] = useState<State | null>(null);\n\n // TODO(burdon): Persistent history -- at least for session (non-space ECHO data?)\n const [history, setHistory] = useState<Message[]>([]);\n\n const scrollerRef = useRef<HTMLDivElement>(null);\n const handleScroll = () => {\n if (scrollerRef.current) {\n scrollerRef.current.scrollTop = scrollerRef.current.scrollHeight;\n }\n };\n\n const controller = useRef<AbortController>();\n useEffect(() => {\n return () => {\n handleStop();\n };\n }, []);\n\n const handleStop = () => {\n controller.current?.abort('stop');\n controller.current = undefined;\n };\n\n const handleClear = () => {\n handleStop();\n setInput('');\n setResult('');\n setHistory([]);\n inputRef.current?.focus();\n };\n\n const handleResponse = ({ text, data, error }: { text?: string; data?: any; error?: Error } = {}) => {\n controller.current = undefined;\n setHistory((history) => [...history, { type: 'response', text, data, error } satisfies Message]);\n setResult('');\n setState(null);\n handleScroll();\n };\n\n const handleRequest = async (input: string) => {\n // Returns a promise that resolves when a value has been received.\n try {\n setState('pending');\n\n let data = null;\n // Detect JSON input.\n if (input.charAt(0) === '{') {\n try {\n const validJsonString = input.replace(/'/g, '\"').replace(/([{,]\\s*)([a-zA-Z0-9_]+)(\\s*:)/g, '$1\"$2\"$3');\n data = JSON.parse(validJsonString);\n input = JSON.stringify(data, null, 2);\n } catch (err) {\n inputRef.current?.focus();\n return;\n }\n }\n\n setInput('');\n setResult('');\n setHistory((history) => [...history, { type: 'request', text: input }]);\n setTimeout(() => {\n handleScroll();\n });\n\n // Throws DOMException when aborted.\n controller.current = new AbortController();\n const response = await fetch(functionUrl!, {\n signal: controller.current.signal,\n method: 'POST',\n body: input,\n headers: {\n 'Content-Type': data ? 'application/json' : 'text/plain',\n },\n });\n\n // Check for error.\n if (!response.ok) {\n const text = await response.text();\n handleResponse({ error: new Error(text || response.statusText || String(response.status)) });\n return;\n }\n\n // Check for JSON.\n const contentType = response.headers.get('content-type');\n if (contentType === 'application/json') {\n const data = await response.json();\n handleResponse({ data });\n return;\n }\n\n // Text (including streaming).\n setState('responding');\n let text = '';\n const reader = response.body!.getReader();\n const pump = async ({ done, value }: ReadableStreamReadResult<Uint8Array>): Promise<void> => {\n text = text + new TextDecoder().decode(value);\n if (!controller.current || done) {\n handleResponse({ text });\n return;\n }\n\n setResult(text);\n setTimeout(() => {\n handleScroll();\n });\n\n return reader.read().then(pump);\n };\n\n void reader\n .read()\n .then(pump)\n .catch((err) => {\n if (err.name !== 'AbortError') {\n log.catch(err);\n }\n });\n } catch (err: any) {\n if (err !== 'stop') {\n const error = err instanceof Error ? err : new Error(err);\n handleResponse({ error });\n log.catch(err);\n } else {\n handleResponse();\n }\n }\n };\n\n return (\n <div className={mx('flex flex-col h-full overflow-hidden', classNames)}>\n {/* TODO(burdon): Replace with Thread. */}\n <MessageThread ref={scrollerRef} state={state} result={result} history={history} />\n\n <Toolbar.Root classNames='p-1'>\n <Input.Root>\n <Input.TextInput\n ref={inputRef}\n autoFocus\n placeholder={t('function request placeholder')}\n value={input}\n onChange={(ev) => setInput(ev.target.value)}\n onKeyDown={(ev) => ev.key === 'Enter' && handleRequest(input)}\n />\n </Input.Root>\n <Toolbar.Button onClick={() => handleRequest(input)}>\n <Icon icon='ph--play--regular' size={4} />\n </Toolbar.Button>\n <Toolbar.Button onClick={() => (state ? handleStop() : handleClear())}>\n <Icon icon={state ? 'ph--stop--regular' : 'ph--trash--regular'} size={4} />\n </Toolbar.Button>\n </Toolbar.Root>\n </div>\n );\n};\n\n// TODO(burdon): Replace with thread?\n// TODO(burdon): Button to delete individual messages.\n// TODO(burdon): Button to edit/re-run question.\ntype MessageThreadProps = {\n state: State | null;\n history: Message[];\n result: string;\n};\n\nconst MessageThread = forwardRef<HTMLDivElement, MessageThreadProps>(\n ({ state, history, result }: MessageThreadProps, forwardedRef) => {\n if (!history.length && !result.length) {\n return null;\n }\n\n return (\n <div ref={forwardedRef} className='flex flex-col gap-6 h-full p-2 overflow-x-hidden overflow-y-auto'>\n {history.map((message, i) => (\n <div key={i} className='grid grid-cols-[2rem_1fr_2rem]'>\n <div className='p-1'>{message.type === 'response' && <RobotAvatar />}</div>\n <div className='overflow-auto'>\n <MessageItem message={message} />\n </div>\n </div>\n ))}\n\n {result?.length > 0 && (\n <div className='grid grid-cols-[2rem_1fr_2rem]'>\n <div className='p-1'>\n {(state === 'pending' && <Icon icon='ph--spinner--regular' size={6} classNames='animate-spin' />) || (\n <Icon icon='ph--robot--regular' size={6} classNames='animate-[pulse_1s_ease-in-out_infinite]' />\n )}\n </div>\n <div className='overflow-auto'>\n <MessageItem message={{ type: 'response', text: result }} />\n </div>\n </div>\n )}\n </div>\n );\n },\n);\n\nconst MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message }>) => {\n const { type, text, data, error } = message;\n const wrapper = 'p-1 px-2 rounded-lg bg-hoverSurface overflow-auto';\n return (\n <div className={mx('flex', type === 'request' ? 'ml-[1rem] justify-end' : 'mr-[1rem]', classNames)}>\n {error && <div className={mx(wrapper, 'whitespace-pre text-error')}>{String(error)}</div>}\n\n {text !== undefined && (\n <div className={mx(wrapper, type === 'request' && 'bg-primary-400 dark:bg-primary-600')}>\n {text || '\\u00D8'}\n </div>\n )}\n\n {data && (\n <SyntaxHighlighter language='json' className={mx(wrapper, 'px-8 py-2 text-xs')}>\n {JSON.stringify(data, null, 2)}\n </SyntaxHighlighter>\n )}\n </div>\n );\n};\n\nconst RobotAvatar = () => (\n <Avatar.Root size={6} variant='circle'>\n <Avatar.Frame>\n <Avatar.Icon icon='ph--robot--regular' />\n </Avatar.Frame>\n </Avatar.Root>\n);\n"],
5
- "mappings": "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",
6
- "names": ["React", "forwardRef", "useEffect", "useRef", "useState", "log", "Avatar", "Icon", "Input", "Toolbar", "useTranslation", "SyntaxHighlighter", "mx", "DebugPanel", "classNames", "functionUrl", "t", "useTranslation", "SCRIPT_PLUGIN", "inputRef", "useRef", "input", "setInput", "useState", "result", "setResult", "state", "setState", "history", "setHistory", "scrollerRef", "handleScroll", "current", "scrollTop", "scrollHeight", "controller", "useEffect", "handleStop", "abort", "undefined", "handleClear", "focus", "handleResponse", "text", "data", "error", "type", "handleRequest", "charAt", "validJsonString", "replace", "JSON", "parse", "stringify", "err", "setTimeout", "AbortController", "response", "fetch", "signal", "method", "body", "headers", "ok", "Error", "statusText", "String", "status", "contentType", "get", "json", "reader", "getReader", "pump", "done", "value", "TextDecoder", "decode", "read", "then", "catch", "name", "log", "div", "className", "mx", "MessageThread", "ref", "Toolbar", "Root", "Input", "TextInput", "autoFocus", "placeholder", "onChange", "ev", "target", "onKeyDown", "key", "Button", "onClick", "Icon", "icon", "size", "forwardRef", "forwardedRef", "length", "map", "message", "i", "RobotAvatar", "MessageItem", "wrapper", "SyntaxHighlighter", "language", "Avatar", "variant", "Frame"]
7
- }