@dxos/functions 0.5.3-main.79e0565 → 0.5.3-main.7cd4303

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 (48) hide show
  1. package/dist/lib/browser/index.mjs +238 -285
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +240 -285
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/types/src/index.d.ts +1 -1
  8. package/dist/types/src/index.d.ts.map +1 -1
  9. package/dist/types/src/{function → registry}/function-registry.d.ts +4 -4
  10. package/dist/types/src/registry/function-registry.d.ts.map +1 -0
  11. package/dist/types/src/registry/function-registry.test.d.ts.map +1 -0
  12. package/dist/types/src/registry/index.d.ts.map +1 -0
  13. package/dist/types/src/runtime/dev-server.d.ts +1 -1
  14. package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
  15. package/dist/types/src/runtime/scheduler.d.ts +1 -2
  16. package/dist/types/src/runtime/scheduler.d.ts.map +1 -1
  17. package/dist/types/src/trigger/trigger-registry.d.ts.map +1 -1
  18. package/dist/types/src/trigger/type/subscription-trigger.d.ts.map +1 -1
  19. package/dist/types/src/types.d.ts +19 -33
  20. package/dist/types/src/types.d.ts.map +1 -1
  21. package/package.json +16 -15
  22. package/schema/functions.json +9 -18
  23. package/src/index.ts +1 -1
  24. package/src/{function → registry}/function-registry.test.ts +10 -10
  25. package/src/registry/function-registry.ts +84 -0
  26. package/src/runtime/dev-server.test.ts +2 -2
  27. package/src/runtime/dev-server.ts +5 -4
  28. package/src/runtime/scheduler.test.ts +1 -1
  29. package/src/runtime/scheduler.ts +8 -16
  30. package/src/testing/functions-integration.test.ts +1 -1
  31. package/src/testing/setup.ts +1 -1
  32. package/src/trigger/trigger-registry.test.ts +34 -60
  33. package/src/trigger/trigger-registry.ts +6 -19
  34. package/src/trigger/type/subscription-trigger.ts +10 -17
  35. package/src/types.ts +10 -12
  36. package/dist/types/src/function/function-registry.d.ts.map +0 -1
  37. package/dist/types/src/function/function-registry.test.d.ts.map +0 -1
  38. package/dist/types/src/function/index.d.ts.map +0 -1
  39. package/dist/types/src/util.d.ts +0 -15
  40. package/dist/types/src/util.d.ts.map +0 -1
  41. package/dist/types/src/util.test.d.ts +0 -2
  42. package/dist/types/src/util.test.d.ts.map +0 -1
  43. package/src/function/function-registry.ts +0 -90
  44. package/src/util.test.ts +0 -43
  45. package/src/util.ts +0 -48
  46. /package/dist/types/src/{function → registry}/function-registry.test.d.ts +0 -0
  47. /package/dist/types/src/{function → registry}/index.d.ts +0 -0
  48. /package/src/{function → registry}/index.ts +0 -0
@@ -62,7 +62,9 @@ export declare class FunctionDef extends FunctionDef_base {
62
62
  }
63
63
  declare const FunctionTrigger_base: import("@dxos/echo-schema").EchoSchemaClass<{
64
64
  function: string;
65
- meta?: object | undefined;
65
+ meta?: {
66
+ readonly [x: string]: any;
67
+ } | undefined;
66
68
  spec: {
67
69
  readonly filter: readonly {
68
70
  readonly type: string;
@@ -98,34 +100,26 @@ export declare class FunctionTrigger extends FunctionTrigger_base {
98
100
  * Function manifest file.
99
101
  */
100
102
  export declare const FunctionManifestSchema: S.struct<{
101
- functions: S.PropertySignature<"?:", ({
103
+ functions: S.PropertySignature<"?:", Omit<{
102
104
  handler: string;
103
105
  uri: string;
104
106
  description?: string | undefined;
105
107
  route: string;
106
108
  } & {
107
- "@meta"?: {
108
- readonly keys: {
109
- readonly id: string;
110
- readonly source: string;
111
- }[];
112
- } | undefined;
113
- })[] | undefined, never, "?:", ({
109
+ id: string;
110
+ }, "id">[] | undefined, never, "?:", Omit<{
114
111
  handler: string;
115
112
  uri: string;
116
113
  description?: string | undefined;
117
114
  route: string;
118
115
  } & {
119
- "@meta"?: {
120
- readonly keys: {
121
- readonly id: string;
122
- readonly source: string;
123
- }[];
124
- } | undefined;
125
- })[] | undefined, never>;
126
- triggers: S.PropertySignature<"?:", ({
116
+ id: string;
117
+ }, "id">[] | undefined, never>;
118
+ triggers: S.PropertySignature<"?:", Omit<{
127
119
  function: string;
128
- meta?: object | undefined;
120
+ meta?: {
121
+ readonly [x: string]: any;
122
+ } | undefined;
129
123
  spec: {
130
124
  readonly filter: readonly {
131
125
  readonly type: string;
@@ -153,15 +147,12 @@ export declare const FunctionManifestSchema: S.struct<{
153
147
  } | undefined;
154
148
  };
155
149
  } & {
156
- "@meta"?: {
157
- readonly keys: {
158
- readonly id: string;
159
- readonly source: string;
160
- }[];
161
- } | undefined;
162
- })[] | undefined, never, "?:", ({
150
+ id: string;
151
+ }, "id">[] | undefined, never, "?:", Omit<{
163
152
  function: string;
164
- meta?: object | undefined;
153
+ meta?: {
154
+ readonly [x: string]: any;
155
+ } | undefined;
165
156
  spec: {
166
157
  readonly filter: readonly {
167
158
  readonly type: string;
@@ -189,13 +180,8 @@ export declare const FunctionManifestSchema: S.struct<{
189
180
  } | undefined;
190
181
  };
191
182
  } & {
192
- "@meta"?: {
193
- readonly keys: {
194
- readonly id: string;
195
- readonly source: string;
196
- }[];
197
- } | undefined;
198
- })[] | undefined, never>;
183
+ id: string;
184
+ }, "id">[] | undefined, never>;
199
185
  }>;
200
186
  export type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;
201
187
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAa,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAErF,QAAA,MAAM,yBAAyB;;;;;;;;;;;;;;;;;EAiB7B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElF,QAAA,MAAM,kBAAkB;;;EAGtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,QAAA,MAAM,oBAAoB;;;;GAOzB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,QAAA,MAAM,sBAAsB;;;;;;;;EAI1B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAS5E,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;;;;;;;;;AAEjG;;GAEG;AACH,qBAAa,WAAY,SAAQ,gBAS/B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEL,qBAAa,eAAgB,SAAQ,oBAQnC;CAAG;AAEL;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAO,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAKxD;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAErF,QAAA,MAAM,yBAAyB;;;;;;;;;;;;;;;;;EAiB7B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElF,QAAA,MAAM,kBAAkB;;;EAGtB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,QAAA,MAAM,oBAAoB;;;;GAOzB,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,QAAA,MAAM,sBAAsB;;;;;;;;EAI1B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAQ5E,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;;;;;;;;;AAEjG;;GAEG;AACH,qBAAa,WAAY,SAAQ,gBAS/B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEL,qBAAa,eAAgB,SAAQ,oBAQnC;CAAG;AAEL;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/functions",
3
- "version": "0.5.3-main.79e0565",
3
+ "version": "0.5.3-main.7cd4303",
4
4
  "description": "Functions SDK and runtime.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -26,28 +26,29 @@
26
26
  "express": "^4.19.2",
27
27
  "get-port-please": "^3.1.1",
28
28
  "ws": "^8.14.2",
29
- "@braneframe/types": "0.5.3-main.79e0565",
30
- "@dxos/async": "0.5.3-main.79e0565",
31
- "@dxos/client": "0.5.3-main.79e0565",
32
- "@dxos/context": "0.5.3-main.79e0565",
33
- "@dxos/echo-db": "0.5.3-main.79e0565",
34
- "@dxos/invariant": "0.5.3-main.79e0565",
35
- "@dxos/echo-schema": "0.5.3-main.79e0565",
36
- "@dxos/keys": "0.5.3-main.79e0565",
37
- "@dxos/node-std": "0.5.3-main.79e0565",
38
- "@dxos/util": "0.5.3-main.79e0565",
39
- "@dxos/protocols": "0.5.3-main.79e0565",
40
- "@dxos/log": "0.5.3-main.79e0565"
29
+ "@braneframe/types": "0.5.3-main.7cd4303",
30
+ "@dxos/async": "0.5.3-main.7cd4303",
31
+ "@dxos/context": "0.5.3-main.7cd4303",
32
+ "@dxos/echo-db": "0.5.3-main.7cd4303",
33
+ "@dxos/client": "0.5.3-main.7cd4303",
34
+ "@dxos/echo-schema": "0.5.3-main.7cd4303",
35
+ "@dxos/invariant": "0.5.3-main.7cd4303",
36
+ "@dxos/keys": "0.5.3-main.7cd4303",
37
+ "@dxos/node-std": "0.5.3-main.7cd4303",
38
+ "@dxos/log": "0.5.3-main.7cd4303",
39
+ "@dxos/protocols": "0.5.3-main.7cd4303",
40
+ "@dxos/util": "0.5.3-main.7cd4303"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/express": "^4.17.17",
44
44
  "@types/ws": "^7.4.0",
45
- "@dxos/agent": "0.5.3-main.79e0565"
45
+ "@dxos/agent": "0.5.3-main.7cd4303"
46
46
  },
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
50
  "scripts": {
51
- "gen-schema": "ts-node ./tools/schema.ts"
51
+ "gen-schema": "ts-node ./tools/schema.ts",
52
+ "prebuild": "pnpm gen-schema"
52
53
  }
53
54
  }
@@ -48,11 +48,17 @@
48
48
  "properties": {
49
49
  "function": {
50
50
  "type": "string",
51
- "description": "Function URI.",
51
+ "description": "Function ID/URI.",
52
52
  "title": "string"
53
53
  },
54
54
  "meta": {
55
- "$ref": "#/$defs/object"
55
+ "type": "object",
56
+ "required": [],
57
+ "properties": {},
58
+ "additionalProperties": {
59
+ "$id": "/schemas/any",
60
+ "title": "any"
61
+ }
56
62
  },
57
63
  "spec": {
58
64
  "anyOf": [
@@ -187,20 +193,5 @@
187
193
  }
188
194
  }
189
195
  },
190
- "additionalProperties": false,
191
- "$defs": {
192
- "object": {
193
- "$id": "/schemas/object",
194
- "oneOf": [
195
- {
196
- "type": "object"
197
- },
198
- {
199
- "type": "array"
200
- }
201
- ],
202
- "description": "an object in the TypeScript meaning, i.e. the `object` type",
203
- "title": "object"
204
- }
205
- }
196
+ "additionalProperties": false
206
197
  }
package/src/index.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './function';
6
5
  export * from './handler';
6
+ export * from './registry';
7
7
  export * from './runtime';
8
8
  export * from './trigger';
9
9
  export * from './types';
@@ -44,7 +44,7 @@ describe('function registry', () => {
44
44
  const client = (await createInitializedClients(testBuilder))[0];
45
45
  const registry = createRegistry(client);
46
46
  const space = await client.spaces.create();
47
- await registry.register(space, testManifest.functions);
47
+ await registry.register(space, testManifest);
48
48
  const { objects: definitions } = await space.db.query(Filter.schema(FunctionDef)).run();
49
49
  expect(definitions.length).to.eq(1);
50
50
  expect(definitions[0].uri).to.eq(testManifest.functions?.[0]?.uri);
@@ -54,8 +54,8 @@ describe('function registry', () => {
54
54
  const client = (await createInitializedClients(testBuilder))[0];
55
55
  const registry = createRegistry(client);
56
56
  const space = await client.spaces.create();
57
- const existing = space.db.add(create(FunctionDef, testManifest.functions![0]));
58
- await registry.register(space, testManifest.functions);
57
+ const existing = space.db.add(create(FunctionDef, { ...testManifest.functions![0] }));
58
+ await registry.register(space, testManifest);
59
59
  const { objects: definitions } = await space.db.query(Filter.schema(FunctionDef)).run();
60
60
  expect(definitions.length).to.eq(1);
61
61
  expect(definitions[0].uri).to.eq(existing.uri);
@@ -67,12 +67,12 @@ describe('function registry', () => {
67
67
  const client = (await createInitializedClients(testBuilder))[0];
68
68
  const registry = createRegistry(client);
69
69
  const space = await client.spaces.create();
70
- const definitions = range(3, () => create(FunctionDef, testManifest.functions![0]));
70
+ const definitions = range(3, () => create(FunctionDef, { ...testManifest.functions![0] }));
71
71
  definitions.forEach((def) => space.db.add(def));
72
72
 
73
73
  const functionRegistered = new Trigger<FunctionDef[]>();
74
- registry.registered.on((fn) => {
75
- functionRegistered.wake(fn.added);
74
+ registry.onFunctionsRegistered.on((fn) => {
75
+ functionRegistered.wake(fn.newFunctions);
76
76
  });
77
77
  void registry.open(ctx);
78
78
  const functions = await functionRegistered.wait();
@@ -86,12 +86,12 @@ describe('function registry', () => {
86
86
  const space = await client.spaces.create();
87
87
 
88
88
  const functionRegistered = new Trigger<FunctionDef>();
89
- registry.registered.on((fn) => {
90
- expect(fn.added.length).to.eq(1);
91
- functionRegistered.wake(fn.added[0]);
89
+ registry.onFunctionsRegistered.on((fn) => {
90
+ expect(fn.newFunctions.length).to.eq(1);
91
+ functionRegistered.wake(fn.newFunctions[0]);
92
92
  });
93
93
  await registry.open(ctx);
94
- await registry.register(space, testManifest.functions);
94
+ await registry.register(space, testManifest);
95
95
  const registered = await functionRegistered.wait();
96
96
  expect(registered.uri).to.eq(testManifest.functions![0].uri);
97
97
  });
@@ -0,0 +1,84 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Event } from '@dxos/async';
6
+ import { type Client } from '@dxos/client';
7
+ import { create, Filter, type Space } from '@dxos/client/echo';
8
+ import { type Context, Resource } from '@dxos/context';
9
+ import { PublicKey } from '@dxos/keys';
10
+ import { ComplexMap } from '@dxos/util';
11
+
12
+ import { FunctionDef, type FunctionManifest } from '../types';
13
+
14
+ export type FunctionsRegisteredEvent = {
15
+ space: Space;
16
+ newFunctions: FunctionDef[];
17
+ };
18
+
19
+ export class FunctionRegistry extends Resource {
20
+ private readonly _functionBySpaceKey = new ComplexMap<PublicKey, FunctionDef[]>(PublicKey.hash);
21
+
22
+ public readonly onFunctionsRegistered = new Event<FunctionsRegisteredEvent>();
23
+
24
+ constructor(private readonly _client: Client) {
25
+ super();
26
+ }
27
+
28
+ public getFunctions(space: Space): FunctionDef[] {
29
+ return this._functionBySpaceKey.get(space.key) ?? [];
30
+ }
31
+
32
+ /**
33
+ * The method loads function definitions from the manifest into the space.
34
+ * We first load all the definitions from the space to deduplicate by functionId.
35
+ */
36
+ // TODO(burdon): This should not be space specific (they are static for the agent).
37
+ public async register(space: Space, manifest: FunctionManifest): Promise<void> {
38
+ if (!manifest.functions?.length) {
39
+ return;
40
+ }
41
+ if (!space.db.graph.runtimeSchemaRegistry.isSchemaRegistered(FunctionDef)) {
42
+ space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);
43
+ }
44
+
45
+ const { objects: existingDefinitions } = await space.db.query(Filter.schema(FunctionDef)).run();
46
+ const newDefinitions = getNewDefinitions(manifest.functions, existingDefinitions);
47
+ const reactiveObjects = newDefinitions.map((template) => create(FunctionDef, { ...template }));
48
+ reactiveObjects.forEach((obj) => space.db.add(obj));
49
+ }
50
+
51
+ protected override async _open(): Promise<void> {
52
+ const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {
53
+ for (const space of spaces) {
54
+ if (this._functionBySpaceKey.has(space.key)) {
55
+ continue;
56
+ }
57
+ const registered: FunctionDef[] = [];
58
+ this._functionBySpaceKey.set(space.key, registered);
59
+ await space.waitUntilReady();
60
+ if (this._ctx.disposed) {
61
+ break;
62
+ }
63
+
64
+ const functionsSubscription = space.db.query(Filter.schema(FunctionDef)).subscribe((definitions) => {
65
+ const newFunctions = getNewDefinitions(definitions.objects, registered);
66
+ if (newFunctions.length > 0) {
67
+ registered.push(...newFunctions);
68
+ this.onFunctionsRegistered.emit({ space, newFunctions });
69
+ }
70
+ });
71
+ this._ctx.onDispose(functionsSubscription);
72
+ }
73
+ });
74
+ this._ctx.onDispose(() => spaceListSubscription.unsubscribe());
75
+ }
76
+
77
+ protected override async _close(_: Context): Promise<void> {
78
+ this._functionBySpaceKey.clear();
79
+ }
80
+ }
81
+
82
+ const getNewDefinitions = <T extends { uri: string }>(candidateList: T[], existing: FunctionDef[]): T[] => {
83
+ return candidateList.filter((candidate) => existing.find((def) => def.uri === candidate.uri) == null);
84
+ };
@@ -11,7 +11,7 @@ import { TestBuilder } from '@dxos/client/testing';
11
11
  import { describe, test } from '@dxos/test';
12
12
 
13
13
  import { DevServer } from './dev-server';
14
- import { FunctionRegistry } from '../function';
14
+ import { FunctionRegistry } from '../registry';
15
15
  import { createFunctionRuntime } from '../testing';
16
16
  import { type FunctionManifest } from '../types';
17
17
 
@@ -44,7 +44,7 @@ describe('dev server', () => {
44
44
  baseDir: path.join(__dirname, '../testing'),
45
45
  });
46
46
  const space = await client.spaces.create();
47
- await registry.register(space, manifest.functions);
47
+ await registry.register(space, manifest);
48
48
  await server.start();
49
49
 
50
50
  // TODO(burdon): Doesn't shut down cleanly.
@@ -13,8 +13,8 @@ import { Context } from '@dxos/context';
13
13
  import { invariant } from '@dxos/invariant';
14
14
  import { log } from '@dxos/log';
15
15
 
16
- import { type FunctionRegistry } from '../function';
17
16
  import { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';
17
+ import { type FunctionRegistry } from '../registry';
18
18
  import { type FunctionDef } from '../types';
19
19
 
20
20
  export type DevServerOptions = {
@@ -41,15 +41,16 @@ export class DevServer {
41
41
 
42
42
  public readonly update = new Event<number>();
43
43
 
44
+ // prettier-ignore
44
45
  constructor(
45
46
  private readonly _client: Client,
46
47
  private readonly _functionsRegistry: FunctionRegistry,
47
48
  private readonly _options: DevServerOptions,
48
49
  ) {
49
- this._functionsRegistry.registered.on(async ({ added }) => {
50
- added.forEach((def) => this._load(def));
50
+ this._functionsRegistry.onFunctionsRegistered.on(async ({ newFunctions }) => {
51
+ newFunctions.forEach((def) => this._load(def));
51
52
  await this._safeUpdateRegistration();
52
- log('new functions loaded', { added });
53
+ log('new functions loaded', { newFunctions });
53
54
  });
54
55
  }
55
56
 
@@ -12,7 +12,7 @@ import { create } from '@dxos/echo-schema';
12
12
  import { describe, test } from '@dxos/test';
13
13
 
14
14
  import { Scheduler, type SchedulerOptions } from './scheduler';
15
- import { FunctionRegistry } from '../function';
15
+ import { FunctionRegistry } from '../registry';
16
16
  import { createInitializedClients, TestType, triggerWebhook } from '../testing';
17
17
  import { TriggerRegistry } from '../trigger';
18
18
  import { type FunctionManifest } from '../types';
@@ -4,13 +4,12 @@
4
4
 
5
5
  import path from 'node:path';
6
6
 
7
- import { Mutex } from '@dxos/async';
8
7
  import { type Space } from '@dxos/client/echo';
9
8
  import { Context } from '@dxos/context';
10
9
  import { log } from '@dxos/log';
11
10
 
12
- import { type FunctionRegistry } from '../function';
13
11
  import { type FunctionEventMeta } from '../handler';
12
+ import { type FunctionRegistry } from '../registry';
14
13
  import { type TriggerRegistry } from '../trigger';
15
14
  import { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../types';
16
15
 
@@ -27,15 +26,13 @@ export type SchedulerOptions = {
27
26
  export class Scheduler {
28
27
  private _ctx = createContext();
29
28
 
30
- private readonly _callMutex = new Mutex();
31
-
32
29
  constructor(
33
30
  public readonly functions: FunctionRegistry,
34
31
  public readonly triggers: TriggerRegistry,
35
32
  private readonly _options: SchedulerOptions = {},
36
33
  ) {
37
- this.functions.registered.on(async ({ space, added }) => {
38
- await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), added);
34
+ this.functions.onFunctionsRegistered.on(async ({ space, newFunctions }) => {
35
+ await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), newFunctions);
39
36
  });
40
37
  this.triggers.registered.on(async ({ space, triggers }) => {
41
38
  await this._safeActivateTriggers(space, triggers, this.functions.getFunctions(space));
@@ -55,9 +52,8 @@ export class Scheduler {
55
52
  await this.triggers.close();
56
53
  }
57
54
 
58
- // TODO(burdon): Remove and update registries directly.
59
55
  public async register(space: Space, manifest: FunctionManifest) {
60
- await this.functions.register(space, manifest.functions);
56
+ await this.functions.register(space, manifest);
61
57
  await this.triggers.register(space, manifest);
62
58
  }
63
59
 
@@ -80,20 +76,16 @@ export class Scheduler {
80
76
  }
81
77
 
82
78
  await this.triggers.activate({ space }, fnTrigger, async (args) => {
83
- return this._callMutex.executeSynchronized(() => {
84
- return this._execFunction(definition, fnTrigger, {
85
- meta: fnTrigger.meta,
86
- data: { ...args, spaceKey: space.key },
87
- });
79
+ return this._execFunction(definition, {
80
+ meta: fnTrigger.meta,
81
+ data: { ...args, spaceKey: space.key },
88
82
  });
89
83
  });
90
-
91
84
  log('activated trigger', { space: space.key, trigger: fnTrigger });
92
85
  }
93
86
 
94
87
  private async _execFunction<TData, TMeta>(
95
88
  def: FunctionDef,
96
- trigger: FunctionTrigger,
97
89
  { data, meta }: { data: TData; meta?: TMeta },
98
90
  ): Promise<number> {
99
91
  let status = 0;
@@ -105,7 +97,7 @@ export class Scheduler {
105
97
  if (endpoint) {
106
98
  // TODO(burdon): Move out of scheduler (generalize as callback).
107
99
  const url = path.join(endpoint, def.route);
108
- log.info('exec', { function: def.uri, url, triggerType: trigger.spec.type });
100
+ log.info('exec', { function: def.uri, url });
109
101
  const response = await fetch(url, {
110
102
  method: 'POST',
111
103
  headers: {
@@ -13,7 +13,7 @@ import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
13
13
  import { describe, test } from '@dxos/test';
14
14
 
15
15
  import { setTestCallHandler } from './test/handler';
16
- import { FunctionRegistry } from '../function';
16
+ import { FunctionRegistry } from '../registry';
17
17
  import { DevServer, Scheduler } from '../runtime';
18
18
  import { createFunctionRuntime, createInitializedClients, TestType } from '../testing';
19
19
  import { TriggerRegistry } from '../trigger';
@@ -10,7 +10,7 @@ import { range } from '@dxos/util';
10
10
  import { TestType } from './types';
11
11
  import { FunctionDef, FunctionTrigger } from '../types';
12
12
 
13
- // TODO(burdon): Create new or extend existing TestBuilder.
13
+ // TODO(burdon): Create TestBuilder.
14
14
 
15
15
  export const createInitializedClients = async (testBuilder: TestBuilder, count: number = 1, config?: Config) => {
16
16
  const clients = range(count).map(() => new Client({ config, services: testBuilder.createLocalClientServices() }));