@dxos/compute 0.8.4-main.f5c0578 → 0.8.4-main.fcfe5033a5
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-X2FWMHD4.mjs → neutral/chunk-JRV42MW3.mjs} +88 -94
- package/dist/lib/neutral/chunk-JRV42MW3.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 +49 -6
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/types/src/compute-graph-registry.d.ts +9 -6
- package/dist/types/src/compute-graph-registry.d.ts.map +1 -1
- package/dist/types/src/compute-graph-registry.test.d.ts +2 -0
- package/dist/types/src/compute-graph-registry.test.d.ts.map +1 -0
- package/dist/types/src/compute-graph.d.ts +10 -7
- package/dist/types/src/compute-graph.d.ts.map +1 -1
- package/dist/types/src/compute-node.d.ts +1 -2
- package/dist/types/src/compute-node.d.ts.map +1 -1
- package/dist/types/src/functions/async-function.d.ts +13 -11
- package/dist/types/src/functions/async-function.d.ts.map +1 -1
- package/dist/types/src/functions/edge-function.d.ts +3 -3
- package/dist/types/src/functions/edge-function.d.ts.map +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-builder.d.ts +1 -1
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-plugin.d.ts +4 -5
- package/dist/types/src/testing/test-plugin.d.ts.map +1 -1
- package/dist/types/src/testing/test-runtime.d.ts +10 -0
- package/dist/types/src/testing/test-runtime.d.ts.map +1 -0
- package/dist/types/src/types/hyperformula.d.ts +3 -6
- package/dist/types/src/types/hyperformula.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -34
- package/src/compute-graph-registry.test.ts +167 -0
- package/src/compute-graph-registry.ts +19 -13
- package/src/compute-graph.test.ts +63 -13
- package/src/compute-graph.ts +41 -36
- package/src/compute-node.ts +2 -5
- package/src/functions/async-function.ts +20 -15
- package/src/functions/edge-function.ts +28 -32
- package/src/hyperformula.test.ts +1 -1
- package/src/index.ts +0 -27
- package/src/testing/index.ts +1 -0
- package/src/testing/test-builder.ts +7 -2
- package/src/testing/test-plugin.ts +2 -5
- package/src/testing/test-runtime.ts +53 -0
- package/src/testing/util.ts +1 -1
- package/src/types/hyperformula.ts +8 -8
- package/dist/lib/browser/chunk-X2FWMHD4.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-RP7HSSCA.mjs +0 -3109
- package/dist/lib/node-esm/chunk-RP7HSSCA.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 -177
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/vendor/hyperformula.mjs +0 -36400
- /package/dist/lib/{browser → neutral}/index.mjs.map +0 -0
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import { type InterpreterState } from 'hyperformula/typings/interpreter/InterpreterState';
|
|
7
|
-
import { type InterpreterValue } from 'hyperformula/typings/interpreter/InterpreterValue';
|
|
8
|
-
import { type ProcedureAst } from 'hyperformula/typings/parser';
|
|
5
|
+
import type * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
9
6
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
10
7
|
|
|
11
8
|
import { type CleanupFn, debounce } from '@dxos/async';
|
|
12
|
-
import {
|
|
9
|
+
import type { Space } from '@dxos/client/echo';
|
|
13
10
|
import { log } from '@dxos/log';
|
|
14
|
-
|
|
15
|
-
import {
|
|
11
|
+
import type { Operation } from '@dxos/operation';
|
|
12
|
+
import type { RawInterpreterValue, SimpleCellAddress } from '@dxos/vendor-hyperformula';
|
|
13
|
+
import type { InterpreterState } from '@dxos/vendor-hyperformula';
|
|
14
|
+
import type { InterpreterValue } from '@dxos/vendor-hyperformula';
|
|
15
|
+
import type { ProcedureAst } from '@dxos/vendor-hyperformula';
|
|
16
|
+
import { CellError, EmptyValue, ErrorType, FunctionPlugin, type HyperFormula } from '@dxos/vendor-hyperformula';
|
|
16
17
|
|
|
17
18
|
// TODO(burdon): Create API gateways:
|
|
18
19
|
// https://publicapis.io
|
|
@@ -34,14 +35,12 @@ export type FunctionOptions = {
|
|
|
34
35
|
export type FunctionContextOptions = {
|
|
35
36
|
defaultTtl: number;
|
|
36
37
|
debounceDelay: number;
|
|
37
|
-
remoteFunctionUrl: string;
|
|
38
38
|
onUpdate?: (update: FunctionUpdateEvent) => void;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
export const defaultFunctionContextOptions: FunctionContextOptions = {
|
|
41
|
+
export const defaultFunctionContextOptions: Pick<FunctionContextOptions, 'defaultTtl' | 'debounceDelay'> = {
|
|
42
42
|
defaultTtl: 5_000,
|
|
43
43
|
debounceDelay: 200,
|
|
44
|
-
remoteFunctionUrl: 'https://edge.dxos.workers.dev/functions', // TODO(burdon): Config.
|
|
45
44
|
};
|
|
46
45
|
|
|
47
46
|
/**
|
|
@@ -78,6 +77,7 @@ export class FunctionContext {
|
|
|
78
77
|
|
|
79
78
|
constructor(
|
|
80
79
|
private readonly _hf: HyperFormula,
|
|
80
|
+
private readonly _runtime: ManagedRuntime.ManagedRuntime<Operation.Service, never>,
|
|
81
81
|
private readonly _space: Space | undefined,
|
|
82
82
|
_options?: Partial<FunctionContextOptions>,
|
|
83
83
|
) {
|
|
@@ -94,14 +94,14 @@ export class FunctionContext {
|
|
|
94
94
|
return this._space;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
get remoteFunctionUrl() {
|
|
98
|
-
return this._options.remoteFunctionUrl;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
97
|
get info() {
|
|
102
98
|
return { cache: this._cache.size, invocations: this._invocations };
|
|
103
99
|
}
|
|
104
100
|
|
|
101
|
+
get runtime() {
|
|
102
|
+
return this._runtime;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
105
|
flush(): void {
|
|
106
106
|
this._cache.clear();
|
|
107
107
|
this._invocations = {};
|
|
@@ -169,7 +169,12 @@ export class AsyncFunctionPlugin extends FunctionPlugin {
|
|
|
169
169
|
/**
|
|
170
170
|
* Immediately returns cached value then runs the async function.
|
|
171
171
|
*/
|
|
172
|
-
protected runAsyncFunction(
|
|
172
|
+
protected runAsyncFunction(
|
|
173
|
+
ast: ProcedureAst,
|
|
174
|
+
state: InterpreterState,
|
|
175
|
+
cb: AsyncFunction,
|
|
176
|
+
options?: FunctionOptions,
|
|
177
|
+
): RawInterpreterValue {
|
|
173
178
|
const { procedureName } = ast;
|
|
174
179
|
const metadata = this.metadata(procedureName);
|
|
175
180
|
return this.runFunction(ast.args, state, metadata, (...args: any) => {
|
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { type InterpreterState } from 'hyperformula/typings/interpreter/InterpreterState';
|
|
8
|
-
import { type ProcedureAst } from 'hyperformula/typings/parser';
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as SchemaAST from 'effect/SchemaAST';
|
|
9
7
|
|
|
10
|
-
import { Filter
|
|
11
|
-
import {
|
|
12
|
-
import { FunctionType, getUserFunctionUrlInMetadata } from '@dxos/functions';
|
|
8
|
+
import { Filter } from '@dxos/client/echo';
|
|
9
|
+
import { JsonSchema, Obj } from '@dxos/echo';
|
|
13
10
|
import { log } from '@dxos/log';
|
|
11
|
+
import { Operation } from '@dxos/operation';
|
|
14
12
|
import { isNonNullable } from '@dxos/util';
|
|
15
|
-
|
|
16
|
-
import {
|
|
13
|
+
import { type ProcedureAst } from '@dxos/vendor-hyperformula';
|
|
14
|
+
import { type InterpreterState } from '@dxos/vendor-hyperformula';
|
|
15
|
+
import { CellError, ErrorType, FunctionArgumentType } from '@dxos/vendor-hyperformula';
|
|
17
16
|
|
|
18
17
|
import { type AsyncFunction, AsyncFunctionPlugin } from './async-function';
|
|
19
18
|
|
|
@@ -35,49 +34,46 @@ export class EdgeFunctionPlugin extends AsyncFunctionPlugin {
|
|
|
35
34
|
return new CellError(ErrorType.REF, 'Missing space');
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
const {
|
|
39
|
-
objects: [fn],
|
|
40
|
-
} = await space.db.query(Filter.type(FunctionType, { binding })).run();
|
|
37
|
+
const [fn] = await space.db.query(Filter.type(Operation.PersistentOperation, { binding })).run();
|
|
41
38
|
if (!fn) {
|
|
42
39
|
log.info('Function not found', { binding });
|
|
43
40
|
return new CellError(ErrorType.REF, 'Function not found');
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
if (subscribe) {
|
|
47
|
-
const unsubscribe =
|
|
44
|
+
const unsubscribe = Obj.subscribe(fn, () => {
|
|
48
45
|
log('function changed', { fn });
|
|
49
|
-
const _ = fn?.version;
|
|
50
|
-
|
|
51
46
|
// TODO(wittjosiah): `ttl` should be 0 to force a recalculation when a new version is deployed.
|
|
52
47
|
// This needs a ttl to prevent a binding change from causing the function not to be found.
|
|
53
|
-
this.runAsyncFunction(ast, state, handler(false), {
|
|
48
|
+
this.runAsyncFunction(ast, state, handler(false), {
|
|
49
|
+
ttl: FUNCTION_TTL,
|
|
50
|
+
});
|
|
54
51
|
});
|
|
55
52
|
|
|
56
53
|
this.context.createSubscription(ast.procedureName, unsubscribe);
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
const
|
|
56
|
+
const runtime = this.context.runtime;
|
|
57
|
+
const functionDef = Operation.deserialize(fn);
|
|
58
|
+
// If input schema exists, construct an object from args using the schema props order, otherwise pass { args }.
|
|
59
|
+
let input: any;
|
|
60
60
|
if (fn.inputSchema) {
|
|
61
|
-
const schema = toEffectSchema(fn.inputSchema);
|
|
62
|
-
SchemaAST.getPropertySignatures(schema.ast)
|
|
63
|
-
|
|
61
|
+
const schema = JsonSchema.toEffectSchema(fn.inputSchema);
|
|
62
|
+
const props = SchemaAST.getPropertySignatures(schema.ast);
|
|
63
|
+
input = {} as any;
|
|
64
|
+
props.forEach(({ name }, index) => {
|
|
65
|
+
input[name.toString()] = args[index];
|
|
64
66
|
});
|
|
65
67
|
} else {
|
|
66
|
-
|
|
68
|
+
input = { args: args.filter(isNonNullable) };
|
|
67
69
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
method: 'POST',
|
|
71
|
-
headers: { 'Content-Type': 'application/json' },
|
|
72
|
-
body: JSON.stringify(body),
|
|
73
|
-
});
|
|
74
|
-
const result = await response.text();
|
|
75
|
-
log('function executed', { result });
|
|
76
|
-
|
|
77
|
-
return result;
|
|
70
|
+
const result = runtime.runPromise(Operation.invoke(functionDef, input).pipe(Effect.orDie));
|
|
71
|
+
return result as any;
|
|
78
72
|
};
|
|
79
73
|
|
|
80
|
-
return this.runAsyncFunction(ast, state, handler(true), {
|
|
74
|
+
return this.runAsyncFunction(ast, state, handler(true), {
|
|
75
|
+
ttl: FUNCTION_TTL,
|
|
76
|
+
});
|
|
81
77
|
}
|
|
82
78
|
}
|
|
83
79
|
|
package/src/hyperformula.test.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,33 +2,6 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
// TODO(burdon): Separate hyperformula (client compute) from remote/edge functions.
|
|
6
|
-
|
|
7
|
-
// TODO(burdon): Reconcile: types.
|
|
8
|
-
// - dxos/graph
|
|
9
|
-
// - dxos/compute
|
|
10
|
-
// - dxos/functions
|
|
11
|
-
// - dxos/assistant
|
|
12
|
-
// - dxos/plugin-automation
|
|
13
|
-
// - dxos/plugin-script
|
|
14
|
-
// - dxos/plugin-sheet
|
|
15
|
-
|
|
16
|
-
// TODO(burdon): Tech debt.
|
|
17
|
-
// - move hyperformula defs from sheet to compute.
|
|
18
|
-
// - standard from ./types exports for plugins.
|
|
19
|
-
// - dxos/agent
|
|
20
|
-
// - dxos/agent-functions
|
|
21
|
-
// - dxos/mosaic, dxos-card
|
|
22
|
-
|
|
23
|
-
// TODO(burdon): Reconcile UX.
|
|
24
|
-
// - dxos/plugin-explorer
|
|
25
|
-
// - dxos/plugin-canvas
|
|
26
|
-
// - dxos/gem-*
|
|
27
|
-
|
|
28
|
-
// TODO(burdon): Next
|
|
29
|
-
// - dxos/plugin-search
|
|
30
|
-
// - dxos/plugin-threads
|
|
31
|
-
|
|
32
5
|
export * from './compute-graph';
|
|
33
6
|
export * from './compute-graph-registry';
|
|
34
7
|
export * from './compute-node';
|
package/src/testing/index.ts
CHANGED
|
@@ -7,8 +7,9 @@ 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
|
+
import { createMockedComputeRuntimeProvider } from './test-runtime';
|
|
10
11
|
|
|
11
|
-
export type TestBuilderOptions = ClientOptions & ComputeGraphOptions
|
|
12
|
+
export type TestBuilderOptions = ClientOptions & Partial<ComputeGraphOptions>;
|
|
12
13
|
|
|
13
14
|
// TODO(burdon): Reconcile with @dxos/client/testing.
|
|
14
15
|
export class TestBuilder extends Resource {
|
|
@@ -43,7 +44,11 @@ export class TestBuilder extends Resource {
|
|
|
43
44
|
this._client = undefined;
|
|
44
45
|
});
|
|
45
46
|
|
|
46
|
-
const registry = new ComputeGraphRegistry(
|
|
47
|
+
const registry = new ComputeGraphRegistry({
|
|
48
|
+
...this._options,
|
|
49
|
+
// Provide a default runtime provider for tests if not supplied.
|
|
50
|
+
computeRuntime: this._options.computeRuntime ?? createMockedComputeRuntimeProvider(),
|
|
51
|
+
});
|
|
47
52
|
await registry.open();
|
|
48
53
|
this._registry = registry;
|
|
49
54
|
this._ctx.onDispose(async () => {
|
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type InterpreterState } from 'hyperformula/typings/interpreter/InterpreterState';
|
|
6
|
-
import { type ProcedureAst } from 'hyperformula/typings/parser';
|
|
7
|
-
|
|
8
5
|
import { getDeep } from '@dxos/util';
|
|
9
|
-
|
|
10
|
-
import { FunctionArgumentType } from '
|
|
6
|
+
import { type InterpreterState, type ProcedureAst } from '@dxos/vendor-hyperformula';
|
|
7
|
+
import { FunctionArgumentType } from '@dxos/vendor-hyperformula';
|
|
11
8
|
|
|
12
9
|
import { type ComputeGraphPlugin } from '../compute-graph-registry';
|
|
13
10
|
import { type AsyncFunction, AsyncFunctionPlugin } from '../functions';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Layer from 'effect/Layer';
|
|
7
|
+
import * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
8
|
+
|
|
9
|
+
import { type SpaceId } from '@dxos/client/echo';
|
|
10
|
+
import { Operation, OperationHandlerSet } from '@dxos/operation';
|
|
11
|
+
|
|
12
|
+
import { type FunctionsRuntimeProvider } from '../compute-graph-registry';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Minimal compute runtime provider for tests and Storybook.
|
|
16
|
+
* Will cause errors if used for actual runtime.
|
|
17
|
+
*/
|
|
18
|
+
export const createMockedComputeRuntimeProvider = ({
|
|
19
|
+
functions,
|
|
20
|
+
}: { functions?: OperationHandlerSet.OperationHandlerSet } = {}): FunctionsRuntimeProvider => {
|
|
21
|
+
return {
|
|
22
|
+
getRuntime: (_spaceId: SpaceId) =>
|
|
23
|
+
ManagedRuntime.make(
|
|
24
|
+
functions
|
|
25
|
+
? Layer.effect(
|
|
26
|
+
Operation.Service,
|
|
27
|
+
Effect.gen(function* () {
|
|
28
|
+
const handlers = yield* functions.handlers;
|
|
29
|
+
return {
|
|
30
|
+
invoke: (op: any, ...args: any[]) => {
|
|
31
|
+
const handler = handlers.find((h: any) => h.meta.key === op.meta.key);
|
|
32
|
+
if (!handler) {
|
|
33
|
+
return Effect.die(`No handler found for operation: ${op.meta.key}`);
|
|
34
|
+
}
|
|
35
|
+
const result = handler.handler(args[0]);
|
|
36
|
+
if (Effect.isEffect(result)) {
|
|
37
|
+
return result as Effect.Effect<unknown>;
|
|
38
|
+
}
|
|
39
|
+
return Effect.promise(() => Promise.resolve(result));
|
|
40
|
+
},
|
|
41
|
+
schedule: () => Effect.void,
|
|
42
|
+
invokePromise: async () => ({ error: new Error('Not implemented in test runtime') }),
|
|
43
|
+
} as Operation.OperationService;
|
|
44
|
+
}),
|
|
45
|
+
)
|
|
46
|
+
: Layer.succeed(Operation.Service, {
|
|
47
|
+
invoke: () => Effect.die('Operation.Service not available in test.'),
|
|
48
|
+
schedule: () => Effect.die('Operation.Service not available in test.'),
|
|
49
|
+
invokePromise: async () => ({ error: new Error('Not available') }),
|
|
50
|
+
} as any),
|
|
51
|
+
),
|
|
52
|
+
};
|
|
53
|
+
};
|
package/src/testing/util.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { HyperFormula } from 'hyperformula';
|
|
5
|
+
import { HyperFormula } from '@dxos/vendor-hyperformula';
|
|
6
6
|
|
|
7
7
|
export const getRegisteredFunctionNames = () => {
|
|
8
8
|
return HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' }).getRegisteredFunctionNames();
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
import {
|
|
6
|
+
type SimpleCellAddress,
|
|
7
|
+
type SimpleCellRange,
|
|
8
|
+
type SimpleDate,
|
|
9
|
+
type SimpleDateTime,
|
|
10
|
+
} from '@dxos/vendor-hyperformula';
|
|
11
|
+
import { DetailedCellError, ExportedCellChange } from '@dxos/vendor-hyperformula';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
-
* so we pre-bundle hyperformula and place it in the vendor directory of this package.
|
|
14
|
+
* Re-exported from vendored hyperformula package.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
export { DetailedCellError, ExportedCellChange };
|