@dxos/plugin-debug 0.7.5-main.9d2a38b → 0.7.5-main.b19bfc8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{DebugSpace-4JHYA7FG.mjs → DebugSpace-BTMTVZ6C.mjs} +2 -2
- package/dist/lib/browser/SpaceGenerator-BPZGOSH4.mjs +1238 -0
- package/dist/lib/browser/SpaceGenerator-BPZGOSH4.mjs.map +7 -0
- package/dist/lib/browser/app-graph-builder-BZFZ6UG6.mjs +533 -0
- package/dist/lib/browser/app-graph-builder-BZFZ6UG6.mjs.map +7 -0
- package/dist/lib/browser/chunk-EF3UVAVI.mjs +21 -0
- package/dist/lib/browser/chunk-EF3UVAVI.mjs.map +7 -0
- package/dist/lib/browser/chunk-UASI2CRI.mjs +72 -0
- package/dist/lib/browser/chunk-UASI2CRI.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +40 -10
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-context-TCD3MNIT.mjs +16 -0
- package/dist/lib/browser/react-context-TCD3MNIT.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-5GNO6NWP.mjs → react-surface-W6QLG4YJ.mjs} +258 -85
- package/dist/lib/browser/react-surface-W6QLG4YJ.mjs.map +7 -0
- package/dist/lib/browser/{settings-JCZUA643.mjs → settings-INPXR64L.mjs} +6 -7
- package/dist/lib/browser/{settings-JCZUA643.mjs.map → settings-INPXR64L.mjs.map} +3 -3
- package/dist/types/src/DebugPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +110 -110
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +116 -116
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-context.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts.map +1 -1
- package/dist/types/src/components/Container.d.ts +2 -2
- package/dist/types/src/components/Container.d.ts.map +1 -1
- package/dist/types/src/components/DebugObjectPanel.d.ts +1 -2
- package/dist/types/src/components/DebugObjectPanel.d.ts.map +1 -1
- package/dist/types/src/components/DebugSettings.d.ts +1 -2
- package/dist/types/src/components/DebugSettings.d.ts.map +1 -1
- package/dist/types/src/components/DebugSpace/ObjectCreator.d.ts +1 -2
- package/dist/types/src/components/DebugSpace/ObjectCreator.d.ts.map +1 -1
- package/dist/types/src/components/DebugStatus.d.ts +1 -2
- package/dist/types/src/components/DebugStatus.d.ts.map +1 -1
- package/dist/types/src/components/SpaceGenerator/ObjectGenerator.d.ts.map +1 -1
- package/dist/types/src/components/SpaceGenerator/SchemaTable.d.ts +1 -2
- package/dist/types/src/components/SpaceGenerator/SchemaTable.d.ts.map +1 -1
- package/dist/types/src/components/SpaceGenerator/SpaceGenerator.d.ts +1 -2
- package/dist/types/src/components/SpaceGenerator/SpaceGenerator.d.ts.map +1 -1
- package/dist/types/src/components/SpaceGenerator/presets.d.ts +22 -0
- package/dist/types/src/components/SpaceGenerator/presets.d.ts.map +1 -0
- package/dist/types/src/components/Wireframe.d.ts +1 -2
- package/dist/types/src/components/Wireframe.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +4 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +28 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +44 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +50 -43
- package/src/DebugPlugin.tsx +6 -3
- package/src/capabilities/app-graph-builder.ts +297 -89
- package/src/capabilities/react-context.tsx +3 -25
- package/src/capabilities/react-surface.tsx +202 -33
- package/src/capabilities/settings.ts +0 -1
- package/src/components/DebugObjectPanel.tsx +17 -5
- package/src/components/DebugSettings.tsx +7 -12
- package/src/components/DebugStatus.tsx +17 -21
- package/src/components/SpaceGenerator/ObjectGenerator.tsx +31 -4
- package/src/components/SpaceGenerator/SpaceGenerator.tsx +75 -6
- package/src/components/SpaceGenerator/presets.ts +563 -0
- package/src/meta.ts +3 -1
- package/src/translations.ts +28 -0
- package/src/types.ts +52 -1
- package/dist/lib/browser/SpaceGenerator-NJCG57CU.mjs +0 -279
- package/dist/lib/browser/SpaceGenerator-NJCG57CU.mjs.map +0 -7
- package/dist/lib/browser/app-graph-builder-FXELWOFS.mjs +0 -177
- package/dist/lib/browser/app-graph-builder-FXELWOFS.mjs.map +0 -7
- package/dist/lib/browser/chunk-I3ON45JK.mjs +0 -18
- package/dist/lib/browser/chunk-I3ON45JK.mjs.map +0 -7
- package/dist/lib/browser/chunk-P7GHHMDB.mjs +0 -21
- package/dist/lib/browser/chunk-P7GHHMDB.mjs.map +0 -7
- package/dist/lib/browser/react-context-OZU6J7G3.mjs +0 -37
- package/dist/lib/browser/react-context-OZU6J7G3.mjs.map +0 -7
- package/dist/lib/browser/react-surface-5GNO6NWP.mjs.map +0 -7
- /package/dist/lib/browser/{DebugSpace-4JHYA7FG.mjs.map → DebugSpace-BTMTVZ6C.mjs.map} +0 -0
|
@@ -4,19 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useMemo, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
+
import { ComputeGraph } from '@dxos/conductor';
|
|
9
|
+
import { toEffectSchema } from '@dxos/echo-schema';
|
|
10
|
+
import { create, type ReactiveObject } from '@dxos/live-object';
|
|
11
|
+
import { log } from '@dxos/log';
|
|
8
12
|
import { DocumentType } from '@dxos/plugin-markdown/types';
|
|
9
13
|
import { SheetType } from '@dxos/plugin-sheet/types';
|
|
10
14
|
import { DiagramType } from '@dxos/plugin-sketch/types';
|
|
15
|
+
import { SpaceAction } from '@dxos/plugin-space/types';
|
|
11
16
|
import { useClient } from '@dxos/react-client';
|
|
12
17
|
import { getTypename, type Space } from '@dxos/react-client/echo';
|
|
13
18
|
import { IconButton, Input, Toolbar, useAsyncEffect } from '@dxos/react-ui';
|
|
14
19
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
20
|
+
import { initializeTable, TableType } from '@dxos/react-ui-table';
|
|
15
21
|
import { Testing } from '@dxos/schema/testing';
|
|
16
22
|
import { jsonKeyReplacer, sortKeys } from '@dxos/util';
|
|
17
23
|
|
|
18
24
|
import { type ObjectGenerator, createGenerator, staticGenerators } from './ObjectGenerator';
|
|
19
25
|
import { SchemaTable } from './SchemaTable';
|
|
26
|
+
import { presets } from './presets';
|
|
20
27
|
|
|
21
28
|
export type SpaceGeneratorProps = {
|
|
22
29
|
space: Space;
|
|
@@ -24,20 +31,27 @@ export type SpaceGeneratorProps = {
|
|
|
24
31
|
};
|
|
25
32
|
|
|
26
33
|
export const SpaceGenerator = ({ space, onCreateObjects }: SpaceGeneratorProps) => {
|
|
34
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
27
35
|
const client = useClient();
|
|
28
|
-
const staticTypes = [DocumentType, DiagramType, SheetType]; // TODO(burdon): Make extensible.
|
|
29
|
-
const mutableTypes = [
|
|
36
|
+
const staticTypes = [DocumentType, DiagramType, SheetType, ComputeGraph]; // TODO(burdon): Make extensible.
|
|
37
|
+
const mutableTypes = [
|
|
38
|
+
Testing.OrgType,
|
|
39
|
+
Testing.ProjectType,
|
|
40
|
+
Testing.ContactType,
|
|
41
|
+
Testing.EmailType,
|
|
42
|
+
Testing.MessageType,
|
|
43
|
+
];
|
|
30
44
|
const [count, setCount] = useState(1);
|
|
31
45
|
const [info, setInfo] = useState<any>({});
|
|
32
46
|
|
|
33
47
|
// Create type generators.
|
|
34
48
|
const typeMap = useMemo(() => {
|
|
35
|
-
client.addTypes(staticTypes);
|
|
49
|
+
client.addTypes([...staticTypes, ...presets.schemas]);
|
|
36
50
|
const mutableGenerators = new Map<string, ObjectGenerator<any>>(
|
|
37
|
-
mutableTypes.map((type) => [type.typename, createGenerator(type)]),
|
|
51
|
+
mutableTypes.map((type) => [type.typename, createGenerator(type as any)]),
|
|
38
52
|
);
|
|
39
53
|
|
|
40
|
-
return new Map([...staticGenerators, ...mutableGenerators]);
|
|
54
|
+
return new Map([...staticGenerators, ...presets.items, ...mutableGenerators]);
|
|
41
55
|
}, [client, mutableTypes]);
|
|
42
56
|
|
|
43
57
|
// Query space to get info.
|
|
@@ -82,10 +96,64 @@ export const SpaceGenerator = ({ space, onCreateObjects }: SpaceGeneratorProps)
|
|
|
82
96
|
[typeMap, count],
|
|
83
97
|
);
|
|
84
98
|
|
|
99
|
+
// TODO(wittjosiah): Remove. Replace with proper echo import.
|
|
100
|
+
const handleLoadTables = useCallback(async () => {
|
|
101
|
+
const input = document.createElement('input');
|
|
102
|
+
input.type = 'file';
|
|
103
|
+
input.accept = '.json';
|
|
104
|
+
|
|
105
|
+
input.onchange = async (e) => {
|
|
106
|
+
const file = (e.target as HTMLInputElement).files?.[0];
|
|
107
|
+
if (!file) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const content = await file.text();
|
|
113
|
+
const data = JSON.parse(content);
|
|
114
|
+
const schemas = await space.db.schemaRegistry.register(data.schemas.map(toEffectSchema));
|
|
115
|
+
// TODO(wittjosiah): If the schema is already registered this should skip.
|
|
116
|
+
await Promise.all(
|
|
117
|
+
schemas.map(async (schema) => {
|
|
118
|
+
const parts = schema.typename.split('/');
|
|
119
|
+
const name = parts[parts.length - 1];
|
|
120
|
+
const table = create(TableType, { name, threads: [] });
|
|
121
|
+
await initializeTable({ space, table, initialSchema: schema.typename });
|
|
122
|
+
await dispatch(createIntent(SpaceAction.AddObject, { target: space, object: table }));
|
|
123
|
+
return table;
|
|
124
|
+
}),
|
|
125
|
+
);
|
|
126
|
+
// TODO(wittjosiah): This should query the space for schemas.
|
|
127
|
+
await Promise.all(
|
|
128
|
+
data.objects.map(async ({ id, '@type': typename, ...fields }: any) => {
|
|
129
|
+
const schema = schemas.find((s) => `dxn:type:${s.typename}:${s.version}` === typename);
|
|
130
|
+
if (!schema) {
|
|
131
|
+
log.warn('Missing schema for object', { id, typename });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const object = create(schema, fields);
|
|
135
|
+
space.db.add(object);
|
|
136
|
+
return object;
|
|
137
|
+
}),
|
|
138
|
+
);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
log.catch(err);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
input.click();
|
|
145
|
+
}, []);
|
|
146
|
+
|
|
85
147
|
return (
|
|
86
148
|
<div role='none' className='flex flex-col divide-y divide-separator'>
|
|
87
149
|
<Toolbar.Root classNames='p-1'>
|
|
88
150
|
<IconButton icon='ph--arrow-clockwise--regular' iconOnly label='Refresh' onClick={updateInfo} />
|
|
151
|
+
<IconButton
|
|
152
|
+
icon='ph--file-arrow-up--regular'
|
|
153
|
+
iconOnly
|
|
154
|
+
label='Load tables from JSON'
|
|
155
|
+
onClick={handleLoadTables}
|
|
156
|
+
/>
|
|
89
157
|
<Toolbar.Separator variant='gap' />
|
|
90
158
|
<div className='flex'>
|
|
91
159
|
<Input.Root>
|
|
@@ -104,6 +172,7 @@ export const SpaceGenerator = ({ space, onCreateObjects }: SpaceGeneratorProps)
|
|
|
104
172
|
|
|
105
173
|
<SchemaTable types={staticTypes} objects={info.objects} label='Static Types' onClick={handleCreateData} />
|
|
106
174
|
<SchemaTable types={mutableTypes} objects={info.objects} label='Mutable Types' onClick={handleCreateData} />
|
|
175
|
+
<SchemaTable types={presets.types} objects={info.objects} label='Presets' onClick={handleCreateData} />
|
|
107
176
|
|
|
108
177
|
<SyntaxHighlighter classNames='flex text-xs' language='json'>
|
|
109
178
|
{JSON.stringify({ space, ...info }, jsonKeyReplacer({ truncate: true }), 2)}
|
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComputeGraphModel, EmailTriggerOutput, NODE_INPUT } from '@dxos/conductor';
|
|
6
|
+
import { AST, ObjectId, S, toJsonSchema } from '@dxos/echo-schema';
|
|
7
|
+
import { FunctionTrigger, TriggerKind, type TriggerType } from '@dxos/functions/types';
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
9
|
+
import { DXN } from '@dxos/keys';
|
|
10
|
+
import { create, makeRef } from '@dxos/live-object';
|
|
11
|
+
import { Filter, type Space } from '@dxos/react-client/echo';
|
|
12
|
+
import {
|
|
13
|
+
type ComputeShape,
|
|
14
|
+
createAppend,
|
|
15
|
+
createChat,
|
|
16
|
+
createComputeGraph,
|
|
17
|
+
createConstant,
|
|
18
|
+
createFunction,
|
|
19
|
+
createGpt,
|
|
20
|
+
createQueue,
|
|
21
|
+
createSurface,
|
|
22
|
+
createRandom,
|
|
23
|
+
createTemplate,
|
|
24
|
+
createText,
|
|
25
|
+
createTrigger,
|
|
26
|
+
} from '@dxos/react-ui-canvas-compute';
|
|
27
|
+
import {
|
|
28
|
+
CanvasBoardType,
|
|
29
|
+
CanvasGraphModel,
|
|
30
|
+
pointMultiply,
|
|
31
|
+
pointsToRect,
|
|
32
|
+
rectToPoints,
|
|
33
|
+
} from '@dxos/react-ui-canvas-editor';
|
|
34
|
+
import { TableType } from '@dxos/react-ui-table';
|
|
35
|
+
import { range } from '@dxos/util';
|
|
36
|
+
|
|
37
|
+
import { type ObjectGenerator } from './ObjectGenerator';
|
|
38
|
+
|
|
39
|
+
export enum PresetName {
|
|
40
|
+
EMAIL_TABLE = 'email-table',
|
|
41
|
+
GPT_QUEUE = 'webhook-gpt-queue',
|
|
42
|
+
CHAT_GPT = 'chat-gpt-text',
|
|
43
|
+
EMAIL_WITH_SUMMARY = 'email-gptSummary-table',
|
|
44
|
+
OBJECT_CHANGE_QUEUE = 'objectChange-queue',
|
|
45
|
+
FOREX_FUNCTION_CALL = 'forex-function-call',
|
|
46
|
+
TIMER_TICK_QUEUE = 'timerTick-queue',
|
|
47
|
+
DISCORD_MESSAGES = 'discord-messages',
|
|
48
|
+
KANBAN_QUEUE = 'kanban-queue',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const presets = {
|
|
52
|
+
schemas: [CanvasBoardType, FunctionTrigger],
|
|
53
|
+
types: Object.values(PresetName).map((name) => ({ typename: name })),
|
|
54
|
+
items: [
|
|
55
|
+
[
|
|
56
|
+
PresetName.GPT_QUEUE,
|
|
57
|
+
async (space, n, cb) => {
|
|
58
|
+
const objects = range(n, () => {
|
|
59
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
60
|
+
|
|
61
|
+
let functionTrigger: FunctionTrigger | undefined;
|
|
62
|
+
canvasModel.builder.call((builder) => {
|
|
63
|
+
const gpt = canvasModel.createNode(createGpt(position({ x: 0, y: -14 })));
|
|
64
|
+
const triggerShape = createTrigger({
|
|
65
|
+
spaceId: space.id,
|
|
66
|
+
triggerKind: TriggerKind.Webhook,
|
|
67
|
+
...position({ x: -18, y: -2 }),
|
|
68
|
+
});
|
|
69
|
+
const trigger = canvasModel.createNode(triggerShape);
|
|
70
|
+
const text = canvasModel.createNode(createText(position({ x: 19, y: 3, width: 10, height: 10 })));
|
|
71
|
+
const { queueId } = setupQueue(space, canvasModel);
|
|
72
|
+
const append = canvasModel.createNode(createAppend(position({ x: 10, y: 6 })));
|
|
73
|
+
|
|
74
|
+
builder
|
|
75
|
+
.createEdge({ source: trigger.id, target: gpt.id, input: 'prompt', output: 'bodyText' })
|
|
76
|
+
.createEdge({ source: gpt.id, target: text.id, output: 'text' })
|
|
77
|
+
.createEdge({ source: queueId.id, target: append.id, input: 'id' })
|
|
78
|
+
.createEdge({ source: gpt.id, target: append.id, output: 'messages', input: 'items' });
|
|
79
|
+
|
|
80
|
+
functionTrigger = triggerShape.functionTrigger!.target!;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
84
|
+
|
|
85
|
+
attachTrigger(functionTrigger, computeModel);
|
|
86
|
+
|
|
87
|
+
return addToSpace(PresetName.GPT_QUEUE, space, canvasModel, computeModel);
|
|
88
|
+
});
|
|
89
|
+
cb?.(objects);
|
|
90
|
+
return objects;
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
|
|
94
|
+
[
|
|
95
|
+
PresetName.OBJECT_CHANGE_QUEUE,
|
|
96
|
+
async (space, n, cb) => {
|
|
97
|
+
const objects = range(n, () => {
|
|
98
|
+
const { canvasModel, computeModel } = createQueueSinkPreset(
|
|
99
|
+
space,
|
|
100
|
+
TriggerKind.Subscription,
|
|
101
|
+
(triggerSpec) => (triggerSpec.filter = { type: 'dxn:type:dxos.org/type/Chess' }),
|
|
102
|
+
'type',
|
|
103
|
+
);
|
|
104
|
+
return addToSpace(PresetName.OBJECT_CHANGE_QUEUE, space, canvasModel, computeModel);
|
|
105
|
+
});
|
|
106
|
+
cb?.(objects);
|
|
107
|
+
return objects;
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
|
|
111
|
+
[
|
|
112
|
+
PresetName.TIMER_TICK_QUEUE,
|
|
113
|
+
async (space, n, cb) => {
|
|
114
|
+
const objects = range(n, () => {
|
|
115
|
+
const { canvasModel, computeModel } = createQueueSinkPreset(
|
|
116
|
+
space,
|
|
117
|
+
TriggerKind.Timer,
|
|
118
|
+
(triggerSpec) => (triggerSpec.cron = '*/5 * * * * *'),
|
|
119
|
+
'result',
|
|
120
|
+
);
|
|
121
|
+
return addToSpace(PresetName.TIMER_TICK_QUEUE, space, canvasModel, computeModel);
|
|
122
|
+
});
|
|
123
|
+
cb?.(objects);
|
|
124
|
+
return objects;
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
|
|
128
|
+
[
|
|
129
|
+
PresetName.EMAIL_TABLE,
|
|
130
|
+
async (space, n, cb) => {
|
|
131
|
+
const objects = range(n, () => {
|
|
132
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
133
|
+
|
|
134
|
+
const results = space.db.query(Filter.schema(TableType)).runSync();
|
|
135
|
+
const emailTable = results.find((r) => r.object?.view?.target?.query?.type?.endsWith('Email'));
|
|
136
|
+
invariant(emailTable, 'Email table not found.');
|
|
137
|
+
|
|
138
|
+
const template = canvasModel.createNode(
|
|
139
|
+
createTemplate({
|
|
140
|
+
valueType: 'object',
|
|
141
|
+
...rawPosition({ centerX: -80, centerY: -64, width: 320, height: 320 }),
|
|
142
|
+
}),
|
|
143
|
+
);
|
|
144
|
+
const templateContent = ['{'];
|
|
145
|
+
|
|
146
|
+
let functionTrigger: FunctionTrigger | undefined;
|
|
147
|
+
canvasModel.builder.call((builder) => {
|
|
148
|
+
const triggerShape = createTrigger({
|
|
149
|
+
spaceId: space.id,
|
|
150
|
+
triggerKind: TriggerKind.Email,
|
|
151
|
+
...position({ x: -18, y: -2 }),
|
|
152
|
+
});
|
|
153
|
+
const trigger = canvasModel.createNode(triggerShape);
|
|
154
|
+
|
|
155
|
+
const tableId = canvasModel.createNode(
|
|
156
|
+
createConstant({
|
|
157
|
+
value: DXN.fromLocalObjectId(emailTable.id).toString(),
|
|
158
|
+
...position({ x: -18, y: 5, width: 8, height: 6 }),
|
|
159
|
+
}),
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const appendToTable = canvasModel.createNode(createAppend(position({ x: 10, y: 6 })));
|
|
163
|
+
|
|
164
|
+
const properties = AST.getPropertySignatures(EmailTriggerOutput.ast);
|
|
165
|
+
for (let i = 0; i < properties.length; i++) {
|
|
166
|
+
const propName = properties[i].name.toString();
|
|
167
|
+
builder.createEdge({ source: trigger.id, target: template.id, input: propName, output: propName });
|
|
168
|
+
templateContent.push(` "${propName}": "{{${propName}}}"` + (i === properties.length - 1 ? '' : ','));
|
|
169
|
+
}
|
|
170
|
+
templateContent.push('}');
|
|
171
|
+
|
|
172
|
+
builder
|
|
173
|
+
.createEdge({ source: tableId.id, target: appendToTable.id, input: 'id' })
|
|
174
|
+
.createEdge({ source: template.id, target: appendToTable.id, input: 'items' });
|
|
175
|
+
|
|
176
|
+
functionTrigger = triggerShape.functionTrigger!.target!;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
180
|
+
|
|
181
|
+
const templateComputeNode = computeModel.nodes.find((n) => n.id === template.node);
|
|
182
|
+
invariant(templateComputeNode, 'Template compute node was not created.');
|
|
183
|
+
templateComputeNode.value = templateContent.join('\n');
|
|
184
|
+
templateComputeNode.inputSchema = toJsonSchema(EmailTriggerOutput);
|
|
185
|
+
|
|
186
|
+
attachTrigger(functionTrigger, computeModel);
|
|
187
|
+
|
|
188
|
+
return addToSpace(PresetName.EMAIL_TABLE, space, canvasModel, computeModel);
|
|
189
|
+
});
|
|
190
|
+
cb?.(objects);
|
|
191
|
+
return objects;
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
|
|
195
|
+
[
|
|
196
|
+
PresetName.CHAT_GPT,
|
|
197
|
+
async (space, n, cb) => {
|
|
198
|
+
const objects = range(n, () => {
|
|
199
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
200
|
+
|
|
201
|
+
canvasModel.builder.call((builder) => {
|
|
202
|
+
const gpt = canvasModel.createNode(createGpt(position({ x: 0, y: -14 })));
|
|
203
|
+
const chat = canvasModel.createNode(createChat(position({ x: -18, y: -2 })));
|
|
204
|
+
const text = canvasModel.createNode(createText(position({ x: 19, y: 3, width: 10, height: 10 })));
|
|
205
|
+
const { queueId } = setupQueue(space, canvasModel);
|
|
206
|
+
|
|
207
|
+
const append = canvasModel.createNode(createAppend(position({ x: 10, y: 6 })));
|
|
208
|
+
|
|
209
|
+
builder
|
|
210
|
+
.createEdge({ source: chat.id, target: gpt.id, input: 'prompt' })
|
|
211
|
+
.createEdge({ source: gpt.id, target: text.id, output: 'text' })
|
|
212
|
+
.createEdge({ source: queueId.id, target: append.id, input: 'id' })
|
|
213
|
+
.createEdge({ source: gpt.id, target: append.id, output: 'messages', input: 'items' });
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
217
|
+
|
|
218
|
+
return addToSpace(PresetName.CHAT_GPT, space, canvasModel, computeModel);
|
|
219
|
+
});
|
|
220
|
+
cb?.(objects);
|
|
221
|
+
return objects;
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
|
|
225
|
+
[
|
|
226
|
+
PresetName.EMAIL_WITH_SUMMARY,
|
|
227
|
+
async (space, n, cb) => {
|
|
228
|
+
const objects = range(n, () => {
|
|
229
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
230
|
+
|
|
231
|
+
const results = space.db.query(Filter.schema(TableType)).runSync();
|
|
232
|
+
const emailTable = results.find((r) => r.object?.view?.target?.query?.type?.endsWith('Email'));
|
|
233
|
+
invariant(emailTable, 'Email table not found.');
|
|
234
|
+
|
|
235
|
+
const template = canvasModel.createNode(
|
|
236
|
+
createTemplate({
|
|
237
|
+
valueType: 'object',
|
|
238
|
+
...rawPosition({ centerX: 192, centerY: -176, width: 320, height: 320 }),
|
|
239
|
+
}),
|
|
240
|
+
);
|
|
241
|
+
const templateContent = ['{'];
|
|
242
|
+
|
|
243
|
+
let functionTrigger: FunctionTrigger | undefined;
|
|
244
|
+
canvasModel.builder.call((builder) => {
|
|
245
|
+
const gpt = canvasModel.createNode(
|
|
246
|
+
createGpt(rawPosition({ centerX: -400, centerY: -112, width: 256, height: 202 })),
|
|
247
|
+
);
|
|
248
|
+
const systemPrompt = canvasModel.createNode(
|
|
249
|
+
createConstant({
|
|
250
|
+
value: "use one word to describe content category. don't write anything else",
|
|
251
|
+
...rawPosition({ centerX: -800, centerY: -160, width: 192, height: 128 }),
|
|
252
|
+
}),
|
|
253
|
+
);
|
|
254
|
+
const triggerShape = createTrigger({
|
|
255
|
+
spaceId: space.id,
|
|
256
|
+
triggerKind: TriggerKind.Email,
|
|
257
|
+
...rawPosition({ centerX: -736, centerY: -384, width: 182, height: 192 }),
|
|
258
|
+
});
|
|
259
|
+
const trigger = canvasModel.createNode(triggerShape);
|
|
260
|
+
|
|
261
|
+
const { queueId } = setupQueue(space, canvasModel, {
|
|
262
|
+
idPosition: { centerX: -720, centerY: 224, width: 192, height: 256 },
|
|
263
|
+
queuePosition: { centerX: -144, centerY: 416, width: 320, height: 448 },
|
|
264
|
+
});
|
|
265
|
+
const appendToQueue = canvasModel.createNode(
|
|
266
|
+
createAppend(rawPosition({ centerX: -80, centerY: 96, width: 122, height: 128 })),
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
const tableId = canvasModel.createNode(
|
|
270
|
+
createConstant({
|
|
271
|
+
value: DXN.fromLocalObjectId(emailTable.id).toString(),
|
|
272
|
+
...rawPosition({ centerX: -112, centerY: -544, width: 192, height: 256 }),
|
|
273
|
+
}),
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const appendToTable = canvasModel.createNode(
|
|
277
|
+
createAppend(rawPosition({ centerX: 560, centerY: -416, width: 128, height: 122 })),
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
templateContent.push(' "category": "{{text}}",');
|
|
281
|
+
builder.createEdge({ source: gpt.id, target: template.id, input: 'text', output: 'text' });
|
|
282
|
+
|
|
283
|
+
const properties = AST.getPropertySignatures(EmailTriggerOutput.ast);
|
|
284
|
+
for (let i = 0; i < properties.length; i++) {
|
|
285
|
+
const propName = properties[i].name.toString();
|
|
286
|
+
builder.createEdge({ source: trigger.id, target: template.id, input: propName, output: propName });
|
|
287
|
+
templateContent.push(` "${propName}": "{{${propName}}}"` + (i === properties.length - 1 ? '' : ','));
|
|
288
|
+
}
|
|
289
|
+
templateContent.push('}');
|
|
290
|
+
|
|
291
|
+
builder
|
|
292
|
+
.createEdge({ source: tableId.id, target: appendToTable.id, input: 'id' })
|
|
293
|
+
.createEdge({ source: queueId.id, target: appendToQueue.id, input: 'id' })
|
|
294
|
+
.createEdge({ source: gpt.id, target: appendToQueue.id, output: 'messages', input: 'items' })
|
|
295
|
+
.createEdge({ source: systemPrompt.id, target: gpt.id, input: 'systemPrompt' })
|
|
296
|
+
.createEdge({ source: trigger.id, target: gpt.id, input: 'prompt', output: 'body' })
|
|
297
|
+
.createEdge({ source: template.id, target: appendToTable.id, input: 'items' });
|
|
298
|
+
|
|
299
|
+
functionTrigger = triggerShape.functionTrigger!.target!;
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
303
|
+
|
|
304
|
+
const templateComputeNode = computeModel.nodes.find((n) => n.id === template.node);
|
|
305
|
+
invariant(templateComputeNode, 'Template compute node was not created.');
|
|
306
|
+
templateComputeNode.value = templateContent.join('\n');
|
|
307
|
+
const extendedSchema = S.extend(EmailTriggerOutput, S.Struct({ text: S.String }));
|
|
308
|
+
templateComputeNode.inputSchema = toJsonSchema(extendedSchema);
|
|
309
|
+
|
|
310
|
+
attachTrigger(functionTrigger, computeModel);
|
|
311
|
+
|
|
312
|
+
return addToSpace(PresetName.EMAIL_WITH_SUMMARY, space, canvasModel, computeModel);
|
|
313
|
+
});
|
|
314
|
+
cb?.(objects);
|
|
315
|
+
return objects;
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
|
|
319
|
+
[
|
|
320
|
+
PresetName.FOREX_FUNCTION_CALL,
|
|
321
|
+
async (space, n, cb) => {
|
|
322
|
+
const objects = range(n, () => {
|
|
323
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
324
|
+
|
|
325
|
+
canvasModel.builder.call((builder) => {
|
|
326
|
+
const sourceCurrency = canvasModel.createNode(
|
|
327
|
+
createConstant({ value: 'USD', ...position({ x: -10, y: -5 }) }),
|
|
328
|
+
);
|
|
329
|
+
const targetCurrency = canvasModel.createNode(
|
|
330
|
+
createConstant({ value: 'EUR', ...position({ x: -10, y: 5 }) }),
|
|
331
|
+
);
|
|
332
|
+
const converter = canvasModel.createNode(createFunction(position({ x: 0, y: 0 })));
|
|
333
|
+
const view = canvasModel.createNode(createSurface(position({ x: 12, y: 0 })));
|
|
334
|
+
|
|
335
|
+
builder
|
|
336
|
+
.createEdge({ source: sourceCurrency.id, target: converter.id, input: 'from' })
|
|
337
|
+
.createEdge({ source: targetCurrency.id, target: converter.id, input: 'to' })
|
|
338
|
+
.createEdge({ source: converter.id, target: view.id, output: 'rate' });
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
342
|
+
|
|
343
|
+
return addToSpace(PresetName.FOREX_FUNCTION_CALL, space, canvasModel, computeModel);
|
|
344
|
+
});
|
|
345
|
+
cb?.(objects);
|
|
346
|
+
return objects;
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
|
|
350
|
+
[
|
|
351
|
+
PresetName.DISCORD_MESSAGES,
|
|
352
|
+
async (space, n, cb) => {
|
|
353
|
+
const objects = range(n, () => {
|
|
354
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
355
|
+
|
|
356
|
+
let functionTrigger: FunctionTrigger | undefined;
|
|
357
|
+
canvasModel.builder.call((builder) => {
|
|
358
|
+
const triggerShape = createTrigger({
|
|
359
|
+
spaceId: space.id,
|
|
360
|
+
triggerKind: TriggerKind.Timer,
|
|
361
|
+
...position({ x: -10, y: -5 }),
|
|
362
|
+
});
|
|
363
|
+
const trigger = canvasModel.createNode(triggerShape);
|
|
364
|
+
// DXOS dev-null channel.
|
|
365
|
+
const channelId = canvasModel.createNode(
|
|
366
|
+
createConstant({ value: '1088569858767212554', ...position({ x: -10, y: 0 }) }),
|
|
367
|
+
);
|
|
368
|
+
const queueId = canvasModel.createNode(
|
|
369
|
+
createConstant({
|
|
370
|
+
value: new DXN(DXN.kind.QUEUE, ['data', space.id, ObjectId.random()]).toString(),
|
|
371
|
+
...position({ x: -10, y: 5 }),
|
|
372
|
+
}),
|
|
373
|
+
);
|
|
374
|
+
const converter = canvasModel.createNode(createFunction(position({ x: 0, y: 0 })));
|
|
375
|
+
const view = canvasModel.createNode(createText(position({ x: 12, y: 0 })));
|
|
376
|
+
const queue = canvasModel.createNode(createQueue(position({ x: 0, y: 12 })));
|
|
377
|
+
|
|
378
|
+
builder
|
|
379
|
+
.createEdge({ source: trigger.id, target: converter.id, input: 'tick' })
|
|
380
|
+
.createEdge({ source: channelId.id, target: converter.id, input: 'channelId' })
|
|
381
|
+
.createEdge({ source: queueId.id, target: converter.id, input: 'queueId' })
|
|
382
|
+
.createEdge({ source: converter.id, target: view.id, output: 'newMessages' })
|
|
383
|
+
.createEdge({ source: queueId.id, target: queue.id, input: 'input' });
|
|
384
|
+
|
|
385
|
+
functionTrigger = triggerShape.functionTrigger!.target!;
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
389
|
+
attachTrigger(functionTrigger, computeModel);
|
|
390
|
+
|
|
391
|
+
return addToSpace(PresetName.DISCORD_MESSAGES, space, canvasModel, computeModel);
|
|
392
|
+
});
|
|
393
|
+
cb?.(objects);
|
|
394
|
+
return objects;
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
|
|
398
|
+
[
|
|
399
|
+
PresetName.KANBAN_QUEUE,
|
|
400
|
+
async (space, n, cb) => {
|
|
401
|
+
const objects = range(n, () => {
|
|
402
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
403
|
+
|
|
404
|
+
// TODO(wittjosiah): Integrate directly w/ Kanban.
|
|
405
|
+
// const results = space.db.query(Filter.schema(KanbanType)).runSync();
|
|
406
|
+
// const kanban = results.find((r) => r.object?.cardView?.target?.query?.type?.endsWith('Message'));
|
|
407
|
+
// invariant(kanban, 'Kanban not found.');
|
|
408
|
+
|
|
409
|
+
const results = space.db.query(Filter.schema(TableType)).runSync();
|
|
410
|
+
const messages = results.find((r) => r.object?.view?.target?.query?.type?.endsWith('Message'));
|
|
411
|
+
invariant(messages, 'Table not found.');
|
|
412
|
+
|
|
413
|
+
let functionTrigger: FunctionTrigger | undefined;
|
|
414
|
+
canvasModel.builder.call((builder) => {
|
|
415
|
+
const triggerShape = createTrigger({
|
|
416
|
+
spaceId: space.id,
|
|
417
|
+
triggerKind: TriggerKind.Queue,
|
|
418
|
+
...position({ x: -10, y: -5 }),
|
|
419
|
+
});
|
|
420
|
+
const trigger = canvasModel.createNode(triggerShape);
|
|
421
|
+
|
|
422
|
+
const tableId = canvasModel.createNode(
|
|
423
|
+
createConstant({
|
|
424
|
+
value: DXN.fromLocalObjectId(messages.id).toString(),
|
|
425
|
+
...position({ x: -10, y: 5 }),
|
|
426
|
+
}),
|
|
427
|
+
);
|
|
428
|
+
const appendToTable = canvasModel.createNode(createAppend(position({ x: 10, y: 0 })));
|
|
429
|
+
|
|
430
|
+
builder
|
|
431
|
+
.createEdge({ source: tableId.id, target: appendToTable.id, input: 'id' })
|
|
432
|
+
.createEdge({ source: trigger.id, target: appendToTable.id, input: 'items', output: 'item' });
|
|
433
|
+
|
|
434
|
+
functionTrigger = triggerShape.functionTrigger!.target!;
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
438
|
+
attachTrigger(functionTrigger, computeModel);
|
|
439
|
+
|
|
440
|
+
return addToSpace(PresetName.KANBAN_QUEUE, space, canvasModel, computeModel);
|
|
441
|
+
});
|
|
442
|
+
cb?.(objects);
|
|
443
|
+
return objects;
|
|
444
|
+
},
|
|
445
|
+
],
|
|
446
|
+
] as [PresetName, ObjectGenerator<any>][],
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const createQueueSinkPreset = <SpecType extends TriggerKind>(
|
|
450
|
+
space: Space,
|
|
451
|
+
triggerKind: SpecType,
|
|
452
|
+
initSpec: (spec: Extract<TriggerType, { type: SpecType }>) => void,
|
|
453
|
+
triggerOutputName: string,
|
|
454
|
+
) => {
|
|
455
|
+
const canvasModel = CanvasGraphModel.create<ComputeShape>();
|
|
456
|
+
|
|
457
|
+
const template = canvasModel.createNode(
|
|
458
|
+
createTemplate({
|
|
459
|
+
valueType: 'object',
|
|
460
|
+
...rawPosition({ centerX: -64, centerY: -79, width: 320, height: 320 }),
|
|
461
|
+
}),
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
let functionTrigger: FunctionTrigger | undefined;
|
|
465
|
+
canvasModel.builder.call((builder) => {
|
|
466
|
+
const triggerShape = createTrigger({
|
|
467
|
+
spaceId: space.id,
|
|
468
|
+
triggerKind,
|
|
469
|
+
...rawPosition({ centerX: -578, centerY: -187, height: 320, width: 320 }),
|
|
470
|
+
});
|
|
471
|
+
const trigger = canvasModel.createNode(triggerShape);
|
|
472
|
+
const { queueId } = setupQueue(space, canvasModel, {
|
|
473
|
+
queuePosition: { centerX: -80, centerY: 378, width: 320, height: 448 },
|
|
474
|
+
});
|
|
475
|
+
const append = canvasModel.createNode(
|
|
476
|
+
createAppend(rawPosition({ centerX: 320, centerY: 192, width: 128, height: 122 })),
|
|
477
|
+
);
|
|
478
|
+
const random = canvasModel.createNode(
|
|
479
|
+
createRandom(rawPosition({ centerX: -509, centerY: -30, width: 64, height: 64 })),
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
builder
|
|
483
|
+
.createEdge({ source: queueId.id, target: append.id, input: 'id' })
|
|
484
|
+
.createEdge({ source: template.id, target: append.id, input: 'items' })
|
|
485
|
+
.createEdge({ source: trigger.id, target: template.id, output: triggerOutputName, input: 'type' })
|
|
486
|
+
.createEdge({
|
|
487
|
+
source: random.id,
|
|
488
|
+
target: template.id,
|
|
489
|
+
input: 'changeId',
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
functionTrigger = triggerShape.functionTrigger!.target!;
|
|
493
|
+
const triggerSpec = functionTrigger.spec;
|
|
494
|
+
invariant(triggerSpec && triggerSpec.type === triggerKind, 'No trigger spec.');
|
|
495
|
+
initSpec(triggerSpec as any);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
const computeModel = createComputeGraph(canvasModel);
|
|
499
|
+
|
|
500
|
+
const templateComputeNode = computeModel.nodes.find((n) => n.id === template.node);
|
|
501
|
+
invariant(templateComputeNode, 'Template compute node was not created.');
|
|
502
|
+
templateComputeNode.value = ['{', ' "@type": "{{type}}",', ' "id": "@{{changeId}}"', '}'].join('\n');
|
|
503
|
+
templateComputeNode.inputSchema = toJsonSchema(S.Struct({ type: S.String, changeId: S.String }));
|
|
504
|
+
|
|
505
|
+
attachTrigger(functionTrigger, computeModel);
|
|
506
|
+
|
|
507
|
+
return { canvasModel, computeModel };
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
const addToSpace = (name: string, space: Space, canvas: CanvasGraphModel, compute: ComputeGraphModel) => {
|
|
511
|
+
return space.db.add(
|
|
512
|
+
create(CanvasBoardType, {
|
|
513
|
+
name,
|
|
514
|
+
computeGraph: makeRef(compute.root),
|
|
515
|
+
layout: canvas.graph,
|
|
516
|
+
}),
|
|
517
|
+
);
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
const setupQueue = (
|
|
521
|
+
space: Space,
|
|
522
|
+
canvasModel: CanvasGraphModel,
|
|
523
|
+
args?: { idPosition?: RawPositionInput; queuePosition?: RawPositionInput },
|
|
524
|
+
) => {
|
|
525
|
+
const queueId = canvasModel.createNode(
|
|
526
|
+
createConstant({
|
|
527
|
+
value: new DXN(DXN.kind.QUEUE, ['data', space.id, ObjectId.random()]).toString(),
|
|
528
|
+
...(args?.idPosition ? rawPosition(args.idPosition) : position({ x: -18, y: 5, width: 8, height: 6 })),
|
|
529
|
+
}),
|
|
530
|
+
);
|
|
531
|
+
const queue = canvasModel.createNode(
|
|
532
|
+
createQueue(
|
|
533
|
+
args?.queuePosition ? rawPosition(args.queuePosition) : position({ x: -3, y: 3, width: 14, height: 10 }),
|
|
534
|
+
),
|
|
535
|
+
);
|
|
536
|
+
canvasModel.createEdge({ source: queueId.id, target: queue.id });
|
|
537
|
+
return { queue, queueId };
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
const attachTrigger = (functionTrigger: FunctionTrigger | undefined, computeModel: ComputeGraphModel) => {
|
|
541
|
+
invariant(functionTrigger);
|
|
542
|
+
functionTrigger.function = DXN.fromLocalObjectId(computeModel.root.id).toString();
|
|
543
|
+
functionTrigger.meta ??= {};
|
|
544
|
+
const inputNode = computeModel.nodes.find((node) => node.type === NODE_INPUT)!;
|
|
545
|
+
functionTrigger.meta.computeNodeId = inputNode.id;
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
type RawPositionInput = { centerX: number; centerY: number; width: number; height: number };
|
|
549
|
+
|
|
550
|
+
const rawPosition = (args: RawPositionInput) => {
|
|
551
|
+
return { center: { x: args.centerX, y: args.centerY }, size: { width: args.width, height: args.height } };
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
const position = (rect: { x: number; y: number; width?: number; height?: number }) => {
|
|
555
|
+
const snap = 32;
|
|
556
|
+
const [center, size] = rectToPoints({ width: 0, height: 0, ...rect });
|
|
557
|
+
const { x, y, width, height } = pointsToRect([pointMultiply(center, snap), pointMultiply(size, snap)]);
|
|
558
|
+
if (width && height) {
|
|
559
|
+
return { center: { x, y }, size: width && height ? { width, height } : undefined };
|
|
560
|
+
} else {
|
|
561
|
+
return { center: { x, y } };
|
|
562
|
+
}
|
|
563
|
+
};
|