@dxos/compute 0.8.4-main.72ec0f3 → 0.8.4-main.74a063c4e0
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/chunk-CPBXT2HX.mjs → neutral/chunk-36MMQLBR.mjs} +30 -40
- package/dist/lib/neutral/chunk-36MMQLBR.mjs.map +7 -0
- package/dist/lib/{browser → neutral}/index.mjs +1 -1
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/{browser → neutral}/testing/index.mjs +6 -5
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/types/src/compute-graph.d.ts +5 -5
- package/dist/types/src/compute-graph.d.ts.map +1 -1
- package/dist/types/src/functions/edge-function.d.ts.map +1 -1
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-runtime.d.ts +2 -2
- package/dist/types/src/testing/test-runtime.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -28
- package/src/compute-graph-registry.test.ts +30 -17
- package/src/compute-graph.test.ts +35 -3
- package/src/compute-graph.ts +32 -36
- package/src/functions/edge-function.ts +13 -14
- package/src/testing/test-builder.ts +0 -1
- package/src/testing/test-runtime.ts +6 -3
- package/dist/lib/browser/chunk-CPBXT2HX.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-D3RM3FQW.mjs +0 -3116
- package/dist/lib/node-esm/chunk-D3RM3FQW.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -56
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -198
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- /package/dist/lib/{browser → neutral}/index.mjs.map +0 -0
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/compute",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.74a063c4e0",
|
|
4
4
|
"description": "Low-level compute API",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/dxos/dxos"
|
|
10
|
+
},
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"author": "DXOS.org",
|
|
9
13
|
"sideEffects": true,
|
|
@@ -12,14 +16,12 @@
|
|
|
12
16
|
".": {
|
|
13
17
|
"source": "./src/index.ts",
|
|
14
18
|
"types": "./dist/types/src/index.d.ts",
|
|
15
|
-
"
|
|
16
|
-
"node": "./dist/lib/node-esm/index.mjs"
|
|
19
|
+
"default": "./dist/lib/neutral/index.mjs"
|
|
17
20
|
},
|
|
18
21
|
"./testing": {
|
|
19
22
|
"source": "./src/testing/index.ts",
|
|
20
23
|
"types": "./dist/types/src/testing/index.d.ts",
|
|
21
|
-
"
|
|
22
|
-
"node": "./dist/lib/node-esm/testing/index.mjs"
|
|
24
|
+
"default": "./dist/lib/neutral/testing/index.mjs"
|
|
23
25
|
}
|
|
24
26
|
},
|
|
25
27
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -35,36 +37,35 @@
|
|
|
35
37
|
"src"
|
|
36
38
|
],
|
|
37
39
|
"dependencies": {
|
|
38
|
-
"
|
|
39
|
-
"effect": "3.18.3",
|
|
40
|
+
"effect": "3.20.0",
|
|
40
41
|
"lodash.defaultsdeep": "^4.6.1",
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/context": "0.8.4-main.
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/functions
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/plugin-automation": "0.8.4-main.
|
|
56
|
-
"@dxos/
|
|
57
|
-
"@dxos/
|
|
42
|
+
"@dxos/ai": "0.8.4-main.74a063c4e0",
|
|
43
|
+
"@dxos/client": "0.8.4-main.74a063c4e0",
|
|
44
|
+
"@dxos/async": "0.8.4-main.74a063c4e0",
|
|
45
|
+
"@dxos/context": "0.8.4-main.74a063c4e0",
|
|
46
|
+
"@dxos/debug": "0.8.4-main.74a063c4e0",
|
|
47
|
+
"@dxos/echo": "0.8.4-main.74a063c4e0",
|
|
48
|
+
"@dxos/functions": "0.8.4-main.74a063c4e0",
|
|
49
|
+
"@dxos/functions-runtime": "0.8.4-main.74a063c4e0",
|
|
50
|
+
"@dxos/invariant": "0.8.4-main.74a063c4e0",
|
|
51
|
+
"@dxos/keys": "0.8.4-main.74a063c4e0",
|
|
52
|
+
"@dxos/log": "0.8.4-main.74a063c4e0",
|
|
53
|
+
"@dxos/operation": "0.8.4-main.74a063c4e0",
|
|
54
|
+
"@dxos/protocols": "0.8.4-main.74a063c4e0",
|
|
55
|
+
"@dxos/schema": "0.8.4-main.74a063c4e0",
|
|
56
|
+
"@dxos/plugin-automation": "0.8.4-main.74a063c4e0",
|
|
57
|
+
"@dxos/util": "0.8.4-main.74a063c4e0",
|
|
58
|
+
"@dxos/vendor-hyperformula": "0.8.4-main.74a063c4e0"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@tldraw/indices": "^2.0.0-alpha.14",
|
|
61
62
|
"@types/lodash.defaultsdeep": "^4.6.6",
|
|
62
|
-
"@dxos/echo": "0.8.4-main.
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
63
|
+
"@dxos/echo-db": "0.8.4-main.74a063c4e0",
|
|
64
|
+
"@dxos/random": "0.8.4-main.74a063c4e0",
|
|
65
|
+
"@dxos/echo": "0.8.4-main.74a063c4e0"
|
|
65
66
|
},
|
|
66
67
|
"peerDependencies": {
|
|
67
|
-
"effect": "
|
|
68
|
+
"effect": "3.20.0"
|
|
68
69
|
},
|
|
69
70
|
"publishConfig": {
|
|
70
71
|
"access": "public"
|
|
@@ -2,32 +2,43 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
5
6
|
import * as Schema from 'effect/Schema';
|
|
6
7
|
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
7
8
|
|
|
8
9
|
import { Trigger } from '@dxos/async';
|
|
9
10
|
import { Obj } from '@dxos/echo';
|
|
10
|
-
import {
|
|
11
|
+
import { Operation, OperationHandlerSet } from '@dxos/operation';
|
|
11
12
|
|
|
12
13
|
import { ComputeGraphRegistry, defaultPlugins } from './compute-graph-registry';
|
|
13
14
|
import { TestBuilder, createMockedComputeRuntimeProvider } from './testing';
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const AddDefinition = Operation.make({
|
|
17
|
+
meta: {
|
|
17
18
|
key: 'add',
|
|
18
19
|
name: 'add',
|
|
19
20
|
description: 'Adds two numbers',
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
},
|
|
22
|
+
input: Schema.Struct({ a: Schema.Number, b: Schema.Number }),
|
|
23
|
+
output: Schema.Number,
|
|
24
|
+
services: [],
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const add = AddDefinition.pipe(
|
|
28
|
+
Operation.withHandler(
|
|
29
|
+
Effect.fn(function* ({ a, b }) {
|
|
30
|
+
return a + b;
|
|
31
|
+
}),
|
|
32
|
+
),
|
|
33
|
+
);
|
|
24
34
|
|
|
35
|
+
describe('ComputeGraphRegistry', () => {
|
|
25
36
|
test('invokes user function through compute graph', async () => {
|
|
26
37
|
const computeRuntime = createMockedComputeRuntimeProvider({
|
|
27
|
-
functions:
|
|
38
|
+
functions: OperationHandlerSet.make(add),
|
|
28
39
|
});
|
|
29
40
|
const testBuilder = new TestBuilder({
|
|
30
|
-
types: [
|
|
41
|
+
types: [Operation.PersistentOperation],
|
|
31
42
|
computeRuntime,
|
|
32
43
|
});
|
|
33
44
|
await testBuilder.open();
|
|
@@ -53,9 +64,10 @@ describe('ComputeGraphRegistry', () => {
|
|
|
53
64
|
await graph.close();
|
|
54
65
|
});
|
|
55
66
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
const functionObj = Operation.serialize(add);
|
|
68
|
+
Obj.change(functionObj, (obj) => {
|
|
69
|
+
obj.binding = 'ADD';
|
|
70
|
+
});
|
|
59
71
|
space.db.add(functionObj);
|
|
60
72
|
|
|
61
73
|
const node = await graph.getOrCreateNode('sheet').open();
|
|
@@ -82,10 +94,10 @@ describe('ComputeGraphRegistry', () => {
|
|
|
82
94
|
|
|
83
95
|
test('adding a function binding updates autocomplete and enables execution', async () => {
|
|
84
96
|
const computeRuntime = createMockedComputeRuntimeProvider({
|
|
85
|
-
functions:
|
|
97
|
+
functions: OperationHandlerSet.make(add),
|
|
86
98
|
});
|
|
87
99
|
const testBuilder = new TestBuilder({
|
|
88
|
-
types: [
|
|
100
|
+
types: [Operation.PersistentOperation],
|
|
89
101
|
computeRuntime,
|
|
90
102
|
});
|
|
91
103
|
await testBuilder.open();
|
|
@@ -122,9 +134,10 @@ describe('ComputeGraphRegistry', () => {
|
|
|
122
134
|
});
|
|
123
135
|
onTestFinished(unsubscribe);
|
|
124
136
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
137
|
+
const functionObj = Operation.serialize(add);
|
|
138
|
+
Obj.change(functionObj, (obj) => {
|
|
139
|
+
obj.binding = 'ADD';
|
|
140
|
+
});
|
|
128
141
|
space.db.add(functionObj);
|
|
129
142
|
|
|
130
143
|
await functionsUpdated.wait();
|
|
@@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
8
|
import { Obj } from '@dxos/echo';
|
|
9
|
-
import {
|
|
9
|
+
import { Operation } from '@dxos/operation';
|
|
10
10
|
import { type CellValue } from '@dxos/vendor-hyperformula';
|
|
11
11
|
import { DetailedCellError } from '@dxos/vendor-hyperformula';
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ import { TestBuilder } from './testing';
|
|
|
15
15
|
describe('ComputeGraph', () => {
|
|
16
16
|
let testBuilder: TestBuilder;
|
|
17
17
|
beforeEach(async () => {
|
|
18
|
-
testBuilder = new TestBuilder({ types: [
|
|
18
|
+
testBuilder = new TestBuilder({ types: [Operation.PersistentOperation] });
|
|
19
19
|
await testBuilder.open();
|
|
20
20
|
});
|
|
21
21
|
afterEach(async () => {
|
|
@@ -30,13 +30,45 @@ describe('ComputeGraph', () => {
|
|
|
30
30
|
// Create script.
|
|
31
31
|
const trigger = new Trigger();
|
|
32
32
|
graph.update.once(() => trigger.wake());
|
|
33
|
-
const functionObject = space.db.add(
|
|
33
|
+
const functionObject = space.db.add(
|
|
34
|
+
Obj.make(Operation.PersistentOperation, { name: 'test', version: '0.0.1', binding: 'TEST' }),
|
|
35
|
+
);
|
|
34
36
|
await trigger.wait();
|
|
35
37
|
const functions = graph.getFunctions({ echo: true });
|
|
36
38
|
expect(functions).to.toHaveLength(1);
|
|
37
39
|
|
|
38
40
|
const id = graph.mapFunctionBindingToId('TEST()');
|
|
39
41
|
expect(id).to.eq(`${Obj.getDXN(functionObject).toString()}()`);
|
|
42
|
+
|
|
43
|
+
const restored = graph.mapFunctionBindingFromId(id);
|
|
44
|
+
expect(restored).to.eq('TEST()');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('map functions roundtrip with args', async () => {
|
|
48
|
+
const space = await testBuilder.client.spaces.create();
|
|
49
|
+
const graph = testBuilder.registry.createGraph(space);
|
|
50
|
+
await graph.open();
|
|
51
|
+
|
|
52
|
+
const trigger = new Trigger();
|
|
53
|
+
graph.update.once(() => trigger.wake());
|
|
54
|
+
space.db.add(Obj.make(Operation.PersistentOperation, { name: 'forex', version: '0.0.1', binding: 'FOREX' }));
|
|
55
|
+
await trigger.wait();
|
|
56
|
+
|
|
57
|
+
const stored = graph.mapFunctionBindingToId('=FOREX(C6,C7)');
|
|
58
|
+
expect(stored).to.include('dxn:echo:');
|
|
59
|
+
expect(stored).not.to.include('FOREX');
|
|
60
|
+
|
|
61
|
+
const restored = graph.mapFunctionBindingFromId(stored);
|
|
62
|
+
expect(restored).to.eq('=FOREX(C6,C7)');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('map functions unknown binding returns undefined', async () => {
|
|
66
|
+
const space = await testBuilder.client.spaces.create();
|
|
67
|
+
const graph = testBuilder.registry.createGraph(space);
|
|
68
|
+
await graph.open();
|
|
69
|
+
|
|
70
|
+
const result = graph.mapFunctionBindingFromId('=dxn:echo:@:01ABCDEF01ABCDEF01ABCDEF01(A1,B1)');
|
|
71
|
+
expect(result).to.be.undefined;
|
|
40
72
|
});
|
|
41
73
|
|
|
42
74
|
test('cross-node references', async () => {
|
package/src/compute-graph.ts
CHANGED
|
@@ -2,19 +2,17 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { effect } from '@preact/signals-core';
|
|
6
5
|
import type * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
7
6
|
|
|
8
7
|
import { Event } from '@dxos/async';
|
|
9
8
|
import { Filter, type Space } from '@dxos/client/echo';
|
|
10
|
-
import { FQ_ID_LENGTH } from '@dxos/client/echo';
|
|
11
9
|
import { Resource } from '@dxos/context';
|
|
12
10
|
import { Obj } from '@dxos/echo';
|
|
13
|
-
import {
|
|
14
|
-
import { Function, type FunctionInvocationService } from '@dxos/functions';
|
|
11
|
+
import { type FunctionInvocationService } from '@dxos/functions';
|
|
15
12
|
import { invariant } from '@dxos/invariant';
|
|
16
13
|
import { PublicKey } from '@dxos/keys';
|
|
17
14
|
import { log } from '@dxos/log';
|
|
15
|
+
import { Operation } from '@dxos/operation';
|
|
18
16
|
import { isNonNullable } from '@dxos/util';
|
|
19
17
|
import type { Listeners } from '@dxos/vendor-hyperformula';
|
|
20
18
|
import { ExportedCellChange, type HyperFormula } from '@dxos/vendor-hyperformula';
|
|
@@ -39,7 +37,7 @@ type ObjectRef = { type: string; id: string };
|
|
|
39
37
|
|
|
40
38
|
/**
|
|
41
39
|
* Marker for sheets that are managed by an ECHO object.
|
|
42
|
-
* Sheet ID: `dxos.
|
|
40
|
+
* Sheet ID: `org.dxos.type.sheet-type@1234`
|
|
43
41
|
*/
|
|
44
42
|
export const createSheetName = ({ type, id }: ObjectRef) => `${type}@${id}`;
|
|
45
43
|
export const parseSheetName = (name: string): Partial<ObjectRef> => {
|
|
@@ -62,7 +60,7 @@ export class ComputeGraph extends Resource {
|
|
|
62
60
|
private readonly _nodes = new Map<number, ComputeNode>();
|
|
63
61
|
|
|
64
62
|
// Cached function objects.
|
|
65
|
-
private _remoteFunctions:
|
|
63
|
+
private _remoteFunctions: Operation.PersistentOperation[] = [];
|
|
66
64
|
|
|
67
65
|
public readonly update = new Event<{ type: ComputeGraphEvent }>();
|
|
68
66
|
|
|
@@ -155,7 +153,7 @@ export class ComputeGraph extends Resource {
|
|
|
155
153
|
formula
|
|
156
154
|
//
|
|
157
155
|
// Map cross-sheet references by name onto sheet stored by ECHO object/model.
|
|
158
|
-
// Example: "Test Sheet"!A0 => "dxos.
|
|
156
|
+
// Example: "Test Sheet"!A0 => "org.dxos.type.sheet-type@1234"!A0
|
|
159
157
|
// https://hyperformula.handsontable.com/guide/cell-references.html#cell-references
|
|
160
158
|
//
|
|
161
159
|
.replace(/['"]?([ \w]+)['"]?!/, (_match, name) => {
|
|
@@ -171,7 +169,7 @@ export class ComputeGraph extends Resource {
|
|
|
171
169
|
|
|
172
170
|
for (const obj of objects) {
|
|
173
171
|
if (obj.name === name) {
|
|
174
|
-
const type = getTypename(obj)!;
|
|
172
|
+
const type = Obj.getTypename(obj)!;
|
|
175
173
|
// NOTE: Names must be single quoted.
|
|
176
174
|
return `'${createSheetName({ type, id: obj.id })}'!`;
|
|
177
175
|
}
|
|
@@ -200,8 +198,8 @@ export class ComputeGraph extends Resource {
|
|
|
200
198
|
}
|
|
201
199
|
|
|
202
200
|
/**
|
|
203
|
-
* Map from binding to fully qualified ECHO
|
|
204
|
-
* E.g., HELLO() => spaceId:objectId()
|
|
201
|
+
* Map from binding to fully qualified ECHO DXN (to store).
|
|
202
|
+
* E.g., HELLO() => dxn:echo:spaceId:objectId()
|
|
205
203
|
*/
|
|
206
204
|
mapFunctionBindingToId(formula: string): string {
|
|
207
205
|
return formula.replace(/(\w+)\((.*)\)/g, (match, binding, args) => {
|
|
@@ -220,23 +218,22 @@ export class ComputeGraph extends Resource {
|
|
|
220
218
|
}
|
|
221
219
|
|
|
222
220
|
/**
|
|
223
|
-
* Map from fully qualified ECHO
|
|
224
|
-
* E.g., spaceId:objectId() => HELLO()
|
|
221
|
+
* Map from fully qualified ECHO DXN to binding (from store).
|
|
222
|
+
* E.g., dxn:echo:spaceId:objectId() => HELLO()
|
|
225
223
|
*/
|
|
226
224
|
mapFunctionBindingFromId(formula: string): string | undefined {
|
|
227
|
-
const binding = formula.replace(
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
});
|
|
225
|
+
const binding = formula.replace(
|
|
226
|
+
/dxn:([^:]+):([^:(]+):([a-zA-Z0-9]+)\((.*)\)/g,
|
|
227
|
+
(_match, kind, spaceTag, objectId, args) => {
|
|
228
|
+
const dxn = `dxn:${kind}:${spaceTag}:${objectId}`;
|
|
229
|
+
const fn = this._remoteFunctions.find((fn) => Obj.getDXN(fn).toString() === dxn);
|
|
230
|
+
if (fn?.binding) {
|
|
231
|
+
return `${fn.binding}(${args})`;
|
|
232
|
+
} else {
|
|
233
|
+
return UNKNOWN_BINDING;
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
);
|
|
240
237
|
|
|
241
238
|
if (binding.startsWith(`=${UNKNOWN_BINDING}`)) {
|
|
242
239
|
return undefined;
|
|
@@ -248,17 +245,16 @@ export class ComputeGraph extends Resource {
|
|
|
248
245
|
protected override async _open(): Promise<void> {
|
|
249
246
|
if (this._space) {
|
|
250
247
|
// Subscribe to remote function definitions.
|
|
251
|
-
const query = this._space.db.query(Filter.type(
|
|
252
|
-
const unsubscribe = query.subscribe(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
});
|
|
248
|
+
const query = this._space.db.query(Filter.type(Operation.PersistentOperation));
|
|
249
|
+
const unsubscribe = query.subscribe(
|
|
250
|
+
() => {
|
|
251
|
+
this._remoteFunctions = query.results.filter((fn) => fn.binding);
|
|
252
|
+
this.update.emit({ type: 'functionsUpdated' });
|
|
253
|
+
},
|
|
254
|
+
{ fire: true },
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
this._ctx.onDispose(unsubscribe);
|
|
262
258
|
}
|
|
263
259
|
}
|
|
264
260
|
|
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { effect } from '@preact/signals-core';
|
|
6
5
|
import * as Effect from 'effect/Effect';
|
|
7
6
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
8
7
|
|
|
9
8
|
import { Filter } from '@dxos/client/echo';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { FunctionDefinition } from '@dxos/functions';
|
|
9
|
+
import { JsonSchema, Obj } from '@dxos/echo';
|
|
10
|
+
import { FunctionInvocationService, TracingService } from '@dxos/functions';
|
|
13
11
|
import { log } from '@dxos/log';
|
|
12
|
+
import { Operation } from '@dxos/operation';
|
|
14
13
|
import { isNonNullable } from '@dxos/util';
|
|
15
14
|
import { type ProcedureAst } from '@dxos/vendor-hyperformula';
|
|
16
15
|
import { type InterpreterState } from '@dxos/vendor-hyperformula';
|
|
@@ -36,33 +35,31 @@ export class EdgeFunctionPlugin extends AsyncFunctionPlugin {
|
|
|
36
35
|
return new CellError(ErrorType.REF, 'Missing space');
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
const {
|
|
40
|
-
objects: [fn],
|
|
41
|
-
} = await space.db.query(Filter.type(Function.Function, { binding })).run();
|
|
38
|
+
const [fn] = await space.db.query(Filter.type(Operation.PersistentOperation, { binding })).run();
|
|
42
39
|
if (!fn) {
|
|
43
40
|
log.info('Function not found', { binding });
|
|
44
41
|
return new CellError(ErrorType.REF, 'Function not found');
|
|
45
42
|
}
|
|
46
43
|
|
|
47
44
|
if (subscribe) {
|
|
48
|
-
const unsubscribe =
|
|
45
|
+
const unsubscribe = Obj.subscribe(fn, () => {
|
|
49
46
|
log('function changed', { fn });
|
|
50
|
-
const _ = fn?.version;
|
|
51
|
-
|
|
52
47
|
// TODO(wittjosiah): `ttl` should be 0 to force a recalculation when a new version is deployed.
|
|
53
48
|
// This needs a ttl to prevent a binding change from causing the function not to be found.
|
|
54
|
-
this.runAsyncFunction(ast, state, handler(false), {
|
|
49
|
+
this.runAsyncFunction(ast, state, handler(false), {
|
|
50
|
+
ttl: FUNCTION_TTL,
|
|
51
|
+
});
|
|
55
52
|
});
|
|
56
53
|
|
|
57
54
|
this.context.createSubscription(ast.procedureName, unsubscribe);
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
const runtime = this.context.runtime;
|
|
61
|
-
const functionDef =
|
|
58
|
+
const functionDef = Operation.deserialize(fn);
|
|
62
59
|
// If input schema exists, construct an object from args using the schema props order, otherwise pass { args }.
|
|
63
60
|
let input: any;
|
|
64
61
|
if (fn.inputSchema) {
|
|
65
|
-
const schema = toEffectSchema(fn.inputSchema);
|
|
62
|
+
const schema = JsonSchema.toEffectSchema(fn.inputSchema);
|
|
66
63
|
const props = SchemaAST.getPropertySignatures(schema.ast);
|
|
67
64
|
input = {} as any;
|
|
68
65
|
props.forEach(({ name }, index) => {
|
|
@@ -79,7 +76,9 @@ export class EdgeFunctionPlugin extends AsyncFunctionPlugin {
|
|
|
79
76
|
return result as any;
|
|
80
77
|
};
|
|
81
78
|
|
|
82
|
-
return this.runAsyncFunction(ast, state, handler(true), {
|
|
79
|
+
return this.runAsyncFunction(ast, state, handler(true), {
|
|
80
|
+
ttl: FUNCTION_TTL,
|
|
81
|
+
});
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
|
|
@@ -7,7 +7,6 @@ import { type Context, Resource } from '@dxos/context';
|
|
|
7
7
|
import { invariant } from '@dxos/invariant';
|
|
8
8
|
|
|
9
9
|
import { type ComputeGraphOptions, ComputeGraphRegistry } from '../compute-graph-registry';
|
|
10
|
-
|
|
11
10
|
import { createMockedComputeRuntimeProvider } from './test-runtime';
|
|
12
11
|
|
|
13
12
|
export type TestBuilderOptions = ClientOptions & Partial<ComputeGraphOptions>;
|
|
@@ -7,8 +7,10 @@ import * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
|
7
7
|
|
|
8
8
|
import { AiService } from '@dxos/ai';
|
|
9
9
|
import { type SpaceId } from '@dxos/client/echo';
|
|
10
|
-
import {
|
|
10
|
+
import { Database, Feed } from '@dxos/echo';
|
|
11
|
+
import { CredentialsService, QueueService } from '@dxos/functions';
|
|
11
12
|
import { FunctionInvocationServiceLayerTest } from '@dxos/functions-runtime/testing';
|
|
13
|
+
import { OperationHandlerSet } from '@dxos/operation';
|
|
12
14
|
|
|
13
15
|
import { type FunctionsRuntimeProvider } from '../compute-graph-registry';
|
|
14
16
|
|
|
@@ -18,15 +20,16 @@ import { type FunctionsRuntimeProvider } from '../compute-graph-registry';
|
|
|
18
20
|
*/
|
|
19
21
|
export const createMockedComputeRuntimeProvider = ({
|
|
20
22
|
functions,
|
|
21
|
-
}: { functions?:
|
|
23
|
+
}: { functions?: OperationHandlerSet.OperationHandlerSet } = {}): FunctionsRuntimeProvider => {
|
|
22
24
|
return {
|
|
23
25
|
getRuntime: (_spaceId: SpaceId) =>
|
|
24
26
|
ManagedRuntime.make(
|
|
25
27
|
FunctionInvocationServiceLayerTest({ functions }).pipe(
|
|
26
28
|
Layer.provide(AiService.notAvailable),
|
|
27
29
|
Layer.provide(CredentialsService.configuredLayer([])),
|
|
28
|
-
Layer.provide(
|
|
30
|
+
Layer.provide(Database.notAvailable),
|
|
29
31
|
Layer.provide(QueueService.notAvailable),
|
|
32
|
+
Layer.provide(Feed.notAvailable),
|
|
30
33
|
),
|
|
31
34
|
),
|
|
32
35
|
};
|