@dxos/functions 0.5.5-next.7ae47fc → 0.5.5-next.8e7c8c8

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 (30) hide show
  1. package/dist/lib/browser/{chunk-4D4I3YMJ.mjs → chunk-ERWZ4JUZ.mjs} +31 -31
  2. package/dist/lib/browser/{chunk-4D4I3YMJ.mjs.map → chunk-ERWZ4JUZ.mjs.map} +2 -2
  3. package/dist/lib/browser/{chunk-ERL6PHMU.mjs → chunk-SXZ5DYJG.mjs} +26 -21
  4. package/dist/lib/browser/{chunk-ERL6PHMU.mjs.map → chunk-SXZ5DYJG.mjs.map} +3 -3
  5. package/dist/lib/browser/index.mjs +2 -2
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/testing/index.mjs +8 -5
  8. package/dist/lib/browser/testing/index.mjs.map +3 -3
  9. package/dist/lib/browser/types.mjs +1 -1
  10. package/dist/lib/node/{chunk-3UYUR5N5.cjs → chunk-BLLSDTKZ.cjs} +34 -34
  11. package/dist/lib/node/{chunk-3UYUR5N5.cjs.map → chunk-BLLSDTKZ.cjs.map} +2 -2
  12. package/dist/lib/node/{chunk-INM6XAL7.cjs → chunk-RPHL3ORN.cjs} +42 -37
  13. package/dist/lib/node/{chunk-INM6XAL7.cjs.map → chunk-RPHL3ORN.cjs.map} +3 -3
  14. package/dist/lib/node/index.cjs +10 -10
  15. package/dist/lib/node/meta.json +1 -1
  16. package/dist/lib/node/testing/index.cjs +14 -11
  17. package/dist/lib/node/testing/index.cjs.map +3 -3
  18. package/dist/lib/node/types.cjs +5 -5
  19. package/dist/lib/node/types.cjs.map +1 -1
  20. package/dist/types/src/testing/setup.d.ts.map +1 -1
  21. package/dist/types/src/trigger/type/websocket-trigger.d.ts.map +1 -1
  22. package/dist/types/src/types.d.ts +27 -38
  23. package/dist/types/src/types.d.ts.map +1 -1
  24. package/package.json +15 -15
  25. package/src/runtime/dev-server.test.ts +2 -2
  26. package/src/runtime/scheduler.test.ts +4 -2
  27. package/src/testing/setup.ts +5 -3
  28. package/src/testing/types.ts +1 -1
  29. package/src/trigger/type/websocket-trigger.ts +12 -8
  30. package/src/types.ts +31 -31
@@ -18,13 +18,13 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var types_exports = {};
20
20
  __export(types_exports, {
21
- FUNCTION_SCHEMA: () => import_chunk_3UYUR5N5.FUNCTION_SCHEMA,
22
- FunctionDef: () => import_chunk_3UYUR5N5.FunctionDef,
23
- FunctionManifestSchema: () => import_chunk_3UYUR5N5.FunctionManifestSchema,
24
- FunctionTrigger: () => import_chunk_3UYUR5N5.FunctionTrigger
21
+ FUNCTION_SCHEMA: () => import_chunk_BLLSDTKZ.FUNCTION_SCHEMA,
22
+ FunctionDef: () => import_chunk_BLLSDTKZ.FunctionDef,
23
+ FunctionManifestSchema: () => import_chunk_BLLSDTKZ.FunctionManifestSchema,
24
+ FunctionTrigger: () => import_chunk_BLLSDTKZ.FunctionTrigger
25
25
  });
26
26
  module.exports = __toCommonJS(types_exports);
27
- var import_chunk_3UYUR5N5 = require("./chunk-3UYUR5N5.cjs");
27
+ var import_chunk_BLLSDTKZ = require("./chunk-BLLSDTKZ.cjs");
28
28
  // Annotate the CommonJS export names for ESM import in node:
29
29
  0 && (module.exports = {
30
30
  FUNCTION_SCHEMA,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["types.cjs"],
4
- "sourcesContent": ["import {\n FUNCTION_SCHEMA,\n FunctionDef,\n FunctionManifestSchema,\n FunctionTrigger\n} from \"./chunk-3UYUR5N5.cjs\";\nexport {\n FUNCTION_SCHEMA,\n FunctionDef,\n FunctionManifestSchema,\n FunctionTrigger\n};\n//# sourceMappingURL=types.cjs.map\n"],
4
+ "sourcesContent": ["import {\n FUNCTION_SCHEMA,\n FunctionDef,\n FunctionManifestSchema,\n FunctionTrigger\n} from \"./chunk-BLLSDTKZ.cjs\";\nexport {\n FUNCTION_SCHEMA,\n FunctionDef,\n FunctionManifestSchema,\n FunctionTrigger\n};\n//# sourceMappingURL=types.cjs.map\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKO;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/testing/setup.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAKxD,OAAO,EAAa,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMzE,MAAM,MAAM,0BAA0B,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAAC;AAIrG,eAAO,MAAM,wBAAwB,gBAAuB,WAAW,UAAS,MAAM,WAAe,MAAM,sBAW1G,CAAC;AAEF,eAAO,MAAM,qBAAqB,gBACnB,WAAW,qBACL,0BAA0B,KAC5C,QAAQ,MAAM,CAahB,CAAC;AAEF,eAAO,MAAM,kBAAkB,gBAChB,WAAW,qBACL,0BAA0B,YACnC,gBAAgB;;;mCASa,KAAK;EAI7C,CAAC"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/testing/setup.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAKxD,OAAO,EAAa,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIzE,MAAM,MAAM,0BAA0B,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAAC;AAIrG,eAAO,MAAM,wBAAwB,gBAAuB,WAAW,UAAS,MAAM,WAAe,MAAM,sBAY1G,CAAC;AAEF,eAAO,MAAM,qBAAqB,gBACnB,WAAW,qBACL,0BAA0B,KAC5C,QAAQ,MAAM,CAchB,CAAC;AAEF,eAAO,MAAM,kBAAkB,gBAChB,WAAW,qBACL,0BAA0B,YACnC,gBAAgB;;;mCASa,KAAK;EAI7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/websocket-trigger.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEhF,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,cAAc,CAAC,gBAAgB,EAAE,uBAAuB,CAoE5F,CAAC"}
1
+ {"version":3,"file":"websocket-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/websocket-trigger.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEhF,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,cAAc,CAAC,gBAAgB,EAAE,uBAAuB,CAwE5F,CAAC"}
@@ -6,44 +6,33 @@ import { S } from '@dxos/echo-schema';
6
6
  * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions
7
7
  */
8
8
  export type FunctionTriggerType = 'subscription' | 'timer' | 'webhook' | 'websocket';
9
- declare const SubscriptionTriggerSchema: S.mutable<S.struct<{
10
- type: S.literal<["subscription"]>;
11
- filter: S.array<S.struct<{
12
- type: S.$string;
13
- props: S.PropertySignature<"?:", {
14
- readonly [x: string]: any;
15
- } | undefined, never, "?:", {
16
- readonly [x: string]: any;
17
- } | undefined, never>;
9
+ declare const SubscriptionTriggerSchema: S.mutable<S.Struct<{
10
+ type: S.Literal<["subscription"]>;
11
+ filter: S.Array$<S.Struct<{
12
+ type: typeof S.String;
13
+ props: S.optional<S.Record$<typeof S.String, typeof S.Any>>;
14
+ }>>;
15
+ options: S.optional<S.Struct<{
16
+ deep: S.optional<typeof S.Boolean>;
17
+ delay: S.optional<typeof S.Number>;
18
18
  }>>;
19
- options: S.PropertySignature<"?:", {
20
- readonly deep?: boolean | undefined;
21
- readonly delay?: number | undefined;
22
- } | undefined, never, "?:", {
23
- readonly deep?: boolean | undefined;
24
- readonly delay?: number | undefined;
25
- } | undefined, never>;
26
19
  }>>;
27
20
  export type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;
28
- declare const TimerTriggerSchema: S.mutable<S.struct<{
29
- type: S.literal<["timer"]>;
30
- cron: S.$string;
21
+ declare const TimerTriggerSchema: S.mutable<S.Struct<{
22
+ type: S.Literal<["timer"]>;
23
+ cron: typeof S.String;
31
24
  }>>;
32
25
  export type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;
33
- declare const WebhookTriggerSchema: S.mutable<S.struct<{
34
- type: S.literal<["webhook"]>;
35
- method: S.$string;
36
- port: S.PropertySignature<"?:", number | undefined, never, "?:", number | undefined, never>;
26
+ declare const WebhookTriggerSchema: S.mutable<S.Struct<{
27
+ type: S.Literal<["webhook"]>;
28
+ method: typeof S.String;
29
+ port: S.optional<typeof S.Number>;
37
30
  }>>;
38
31
  export type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;
39
- declare const WebsocketTriggerSchema: S.mutable<S.struct<{
40
- type: S.literal<["websocket"]>;
41
- url: S.$string;
42
- init: S.PropertySignature<"?:", {
43
- readonly [x: string]: any;
44
- } | undefined, never, "?:", {
45
- readonly [x: string]: any;
46
- } | undefined, never>;
32
+ declare const WebsocketTriggerSchema: S.mutable<S.Struct<{
33
+ type: S.Literal<["websocket"]>;
34
+ url: typeof S.String;
35
+ init: S.optional<S.Record$<typeof S.String, typeof S.Any>>;
47
36
  }>>;
48
37
  export type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;
49
38
  export type TriggerSpec = TimerTrigger | WebhookTrigger | WebsocketTrigger | SubscriptionTrigger;
@@ -103,8 +92,8 @@ export declare class FunctionTrigger extends FunctionTrigger_base {
103
92
  /**
104
93
  * Function manifest file.
105
94
  */
106
- export declare const FunctionManifestSchema: S.struct<{
107
- functions: S.PropertySignature<"?:", ({
95
+ export declare const FunctionManifestSchema: S.Struct<{
96
+ functions: S.optional<S.mutable<S.Array$<S.Schema<{
108
97
  handler: string;
109
98
  uri: string;
110
99
  description?: string | undefined;
@@ -116,7 +105,7 @@ export declare const FunctionManifestSchema: S.struct<{
116
105
  readonly source: string;
117
106
  }[];
118
107
  } | undefined;
119
- })[] | undefined, never, "?:", ({
108
+ }, {
120
109
  handler: string;
121
110
  uri: string;
122
111
  description?: string | undefined;
@@ -128,8 +117,8 @@ export declare const FunctionManifestSchema: S.struct<{
128
117
  readonly source: string;
129
118
  }[];
130
119
  } | undefined;
131
- })[] | undefined, never>;
132
- triggers: S.PropertySignature<"?:", ({
120
+ }, never>>>>;
121
+ triggers: S.optional<S.mutable<S.Array$<S.Schema<{
133
122
  function: string;
134
123
  enabled?: boolean | undefined;
135
124
  meta?: {
@@ -168,7 +157,7 @@ export declare const FunctionManifestSchema: S.struct<{
168
157
  readonly source: string;
169
158
  }[];
170
159
  } | undefined;
171
- })[] | undefined, never, "?:", ({
160
+ }, {
172
161
  function: string;
173
162
  enabled?: boolean | undefined;
174
163
  meta?: {
@@ -207,7 +196,7 @@ export declare const FunctionManifestSchema: S.struct<{
207
196
  readonly source: string;
208
197
  }[];
209
198
  } | undefined;
210
- })[] | undefined, never>;
199
+ }, never>>>>;
211
200
  }>;
212
201
  export type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;
213
202
  export declare const FUNCTION_SCHEMA: (typeof FunctionDef | typeof FunctionTrigger)[];
@@ -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;;;;;;;;;;;;;;;;;GAmB9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElF,QAAA,MAAM,kBAAkB;;;GAKvB,CAAC;AAEF,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;;;;;;;;GAM3B,CAAC;AAEF,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,gBAQ/B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEL;;GAEG;AACH,qBAAa,eAAgB,SAAQ,oBASnC;CAAG;AAEL;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAG5E,eAAO,MAAM,eAAe,iDAAiC,CAAC"}
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;;;;;;;;;;GAmB9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElF,QAAA,MAAM,kBAAkB;;;GAKvB,CAAC;AAEF,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;;;;GAM3B,CAAC;AAEF,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,gBAQ/B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEL;;GAEG;AACH,qBAAa,eAAgB,SAAQ,oBASnC;CAAG;AAEL;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAG5E,eAAO,MAAM,eAAe,iDAAiC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/functions",
3
- "version": "0.5.5-next.7ae47fc",
3
+ "version": "0.5.5-next.8e7c8c8",
4
4
  "description": "Functions API and runtime.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -45,27 +45,27 @@
45
45
  "dependencies": {
46
46
  "@preact/signals-core": "^1.6.0",
47
47
  "cron": "^3.1.6",
48
- "effect": "^2.4.19",
48
+ "effect": "^3.2.7",
49
49
  "express": "^4.19.2",
50
50
  "get-port-please": "^3.1.1",
51
51
  "ws": "^8.14.2",
52
- "@braneframe/types": "0.5.5-next.7ae47fc",
53
- "@dxos/async": "0.5.5-next.7ae47fc",
54
- "@dxos/client": "0.5.5-next.7ae47fc",
55
- "@dxos/context": "0.5.5-next.7ae47fc",
56
- "@dxos/echo-db": "0.5.5-next.7ae47fc",
57
- "@dxos/echo-schema": "0.5.5-next.7ae47fc",
58
- "@dxos/invariant": "0.5.5-next.7ae47fc",
59
- "@dxos/keys": "0.5.5-next.7ae47fc",
60
- "@dxos/log": "0.5.5-next.7ae47fc",
61
- "@dxos/node-std": "0.5.5-next.7ae47fc",
62
- "@dxos/util": "0.5.5-next.7ae47fc",
63
- "@dxos/protocols": "0.5.5-next.7ae47fc"
52
+ "@braneframe/types": "0.5.5-next.8e7c8c8",
53
+ "@dxos/async": "0.5.5-next.8e7c8c8",
54
+ "@dxos/context": "0.5.5-next.8e7c8c8",
55
+ "@dxos/echo-db": "0.5.5-next.8e7c8c8",
56
+ "@dxos/echo-schema": "0.5.5-next.8e7c8c8",
57
+ "@dxos/client": "0.5.5-next.8e7c8c8",
58
+ "@dxos/invariant": "0.5.5-next.8e7c8c8",
59
+ "@dxos/log": "0.5.5-next.8e7c8c8",
60
+ "@dxos/node-std": "0.5.5-next.8e7c8c8",
61
+ "@dxos/keys": "0.5.5-next.8e7c8c8",
62
+ "@dxos/util": "0.5.5-next.8e7c8c8",
63
+ "@dxos/protocols": "0.5.5-next.8e7c8c8"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@types/express": "^4.17.17",
67
67
  "@types/ws": "^7.4.0",
68
- "@dxos/agent": "0.5.5-next.7ae47fc"
68
+ "@dxos/agent": "0.5.5-next.8e7c8c8"
69
69
  },
70
70
  "publishConfig": {
71
71
  "access": "public"
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  import { expect } from 'chai';
6
+ import { getRandomPort } from 'get-port-please';
6
7
  import path from 'path';
7
8
 
8
9
  import { sleep, waitForCondition } from '@dxos/async';
@@ -16,7 +17,6 @@ import { createFunctionRuntime, testFunctionManifest } from '../testing';
16
17
  import { initFunctionsPlugin } from '../testing/plugin-init';
17
18
 
18
19
  describe('dev server', () => {
19
- let port = 7201;
20
20
  let client: Client;
21
21
  let testBuilder: TestBuilder;
22
22
  before(async () => {
@@ -67,7 +67,7 @@ describe('dev server', () => {
67
67
  const registry = new FunctionRegistry(client);
68
68
  const server = new DevServer(client, registry, {
69
69
  baseDir: path.join(__dirname, '../testing'),
70
- port: port++,
70
+ port: await getRandomPort('127.0.0.1'),
71
71
  });
72
72
  const space = await client.spaces.create();
73
73
  // TODO(burdon): Doesn't shut down cleanly.
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  import { expect } from 'chai';
6
+ import { getRandomPort } from 'get-port-please';
6
7
  import WebSocket from 'ws';
7
8
 
8
9
  import { Trigger } from '@dxos/async';
@@ -108,6 +109,7 @@ describe('scheduler', () => {
108
109
  });
109
110
 
110
111
  test('websocket', async () => {
112
+ const port = await getRandomPort('127.0.0.1');
111
113
  const manifest: FunctionManifest = {
112
114
  functions: [
113
115
  {
@@ -123,7 +125,7 @@ describe('scheduler', () => {
123
125
  spec: {
124
126
  type: 'websocket',
125
127
  // url: 'https://hub.dxos.network/api/mailbox/test',
126
- url: 'http://localhost:8081',
128
+ url: `http://localhost:${port}`,
127
129
  init: {
128
130
  type: 'sync',
129
131
  },
@@ -141,7 +143,7 @@ describe('scheduler', () => {
141
143
 
142
144
  // Test server.
143
145
  setTimeout(() => {
144
- const wss = new WebSocket.Server({ port: 8081 });
146
+ const wss = new WebSocket.Server({ port });
145
147
  wss.on('connection', (ws: WebSocket) => {
146
148
  ws.on('message', (data) => {
147
149
  const info = JSON.parse(new TextDecoder().decode(data as ArrayBuffer));
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { getRandomPort } from 'get-port-please';
5
6
  import path from 'node:path';
6
7
 
7
8
  import { waitForCondition } from '@dxos/async';
@@ -16,8 +17,6 @@ import { DevServer, type DevServerOptions, Scheduler } from '../runtime';
16
17
  import { TriggerRegistry } from '../trigger';
17
18
  import { FunctionDef, FunctionTrigger } from '../types';
18
19
 
19
- let functionsPort = 8081;
20
-
21
20
  export type FunctionsPluginInitializer = (client: Client) => Promise<{ close: () => Promise<void> }>;
22
21
 
23
22
  // TODO(burdon): Extend/wrap TestBuilder.
@@ -29,6 +28,7 @@ export const createInitializedClients = async (testBuilder: TestBuilder, count:
29
28
  clients.map(async (client, index) => {
30
29
  await client.initialize();
31
30
  await client.halo.createIdentity({ displayName: `Peer ${index}` });
31
+ await client.spaces.isReady;
32
32
  client.addSchema(FunctionDef, FunctionTrigger, TestType);
33
33
  return client;
34
34
  }),
@@ -39,10 +39,11 @@ export const createFunctionRuntime = async (
39
39
  testBuilder: TestBuilder,
40
40
  pluginInitializer: FunctionsPluginInitializer,
41
41
  ): Promise<Client> => {
42
+ const functionsPort = await getRandomPort('127.0.0.1');
42
43
  const config = new Config({
43
44
  runtime: {
44
45
  agent: {
45
- plugins: [{ id: 'dxos.org/agent/plugin/functions', config: { port: functionsPort++ } }],
46
+ plugins: [{ id: 'dxos.org/agent/plugin/functions', config: { port: functionsPort } }],
46
47
  },
47
48
  },
48
49
  });
@@ -92,6 +93,7 @@ const startDevServer = async (
92
93
  ) => {
93
94
  const server = new DevServer(client, functionRegistry, {
94
95
  baseDir: path.join(__dirname, '../testing'),
96
+ port: await getRandomPort('127.0.0.1'),
95
97
  ...options,
96
98
  });
97
99
  await server.start();
@@ -5,5 +5,5 @@
5
5
  import { S, TypedObject } from '@dxos/echo-schema';
6
6
 
7
7
  export class TestType extends TypedObject({ typename: 'example.com/type/Test', version: '0.1.0' })({
8
- title: S.string,
8
+ title: S.String,
9
9
  }) {}
@@ -30,6 +30,7 @@ export const createWebsocketTrigger: TriggerFactory<WebsocketTrigger, WebsocketT
30
30
  ) => {
31
31
  const { url, init } = spec;
32
32
 
33
+ let wasOpen = false;
33
34
  let ws: WebSocket;
34
35
  for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
35
36
  const open = new Trigger<boolean>();
@@ -49,18 +50,18 @@ export const createWebsocketTrigger: TriggerFactory<WebsocketTrigger, WebsocketT
49
50
  log.info('closed', { url, code: event.code });
50
51
  // Reconnect if server closes (e.g., CF restart).
51
52
  // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
52
- if (event.code === 1006) {
53
+ if (event.code === 1006 && wasOpen && !ctx.disposed) {
53
54
  setTimeout(async () => {
54
55
  log.info(`reconnecting in ${options.retryDelay}s...`, { url });
55
56
  await createWebsocketTrigger(ctx, space, spec, callback, options);
56
57
  }, options.retryDelay * 1_000);
57
58
  }
58
-
59
59
  open.wake(false);
60
60
  },
61
61
 
62
62
  onerror: (event) => {
63
63
  log.catch(event.error, { url });
64
+ open.wake(false);
64
65
  },
65
66
 
66
67
  onmessage: async (event) => {
@@ -75,14 +76,17 @@ export const createWebsocketTrigger: TriggerFactory<WebsocketTrigger, WebsocketT
75
76
  } satisfies Partial<WebSocket>);
76
77
 
77
78
  const isOpen = await open.wait();
79
+ if (ctx.disposed) {
80
+ break;
81
+ }
78
82
  if (isOpen) {
83
+ wasOpen = true;
79
84
  break;
80
- } else {
81
- const wait = Math.pow(attempt, 2) * options.retryDelay;
82
- if (attempt < options.maxAttempts) {
83
- log.warn(`failed to connect; trying again in ${wait}s`, { attempt });
84
- await sleep(wait * 1_000);
85
- }
85
+ }
86
+ const wait = Math.pow(attempt, 2) * options.retryDelay;
87
+ if (attempt < options.maxAttempts) {
88
+ log.warn(`failed to connect; trying again in ${wait}s`, { attempt });
89
+ await sleep(wait * 1_000);
86
90
  }
87
91
  }
88
92
 
package/src/types.ts CHANGED
@@ -13,21 +13,21 @@ import { RawObject, S, TypedObject } from '@dxos/echo-schema';
13
13
  export type FunctionTriggerType = 'subscription' | 'timer' | 'webhook' | 'websocket';
14
14
 
15
15
  const SubscriptionTriggerSchema = S.mutable(
16
- S.struct({
17
- type: S.literal('subscription'),
16
+ S.Struct({
17
+ type: S.Literal('subscription'),
18
18
  // TODO(burdon): Define query DSL (from ECHO).
19
- filter: S.array(
20
- S.struct({
21
- type: S.string,
22
- props: S.optional(S.record(S.string, S.any)),
19
+ filter: S.Array(
20
+ S.Struct({
21
+ type: S.String,
22
+ props: S.optional(S.Record(S.String, S.Any)),
23
23
  }),
24
24
  ),
25
25
  options: S.optional(
26
- S.struct({
26
+ S.Struct({
27
27
  // Watch changes to object (not just creation).
28
- deep: S.optional(S.boolean),
28
+ deep: S.optional(S.Boolean),
29
29
  // Debounce changes (delay in ms).
30
- delay: S.optional(S.number),
30
+ delay: S.optional(S.Number),
31
31
  }),
32
32
  ),
33
33
  }),
@@ -36,36 +36,36 @@ const SubscriptionTriggerSchema = S.mutable(
36
36
  export type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;
37
37
 
38
38
  const TimerTriggerSchema = S.mutable(
39
- S.struct({
40
- type: S.literal('timer'),
41
- cron: S.string,
39
+ S.Struct({
40
+ type: S.Literal('timer'),
41
+ cron: S.String,
42
42
  }),
43
43
  );
44
44
 
45
45
  export type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;
46
46
 
47
47
  const WebhookTriggerSchema = S.mutable(
48
- S.struct({
49
- type: S.literal('webhook'),
50
- method: S.string,
48
+ S.Struct({
49
+ type: S.Literal('webhook'),
50
+ method: S.String,
51
51
  // Assigned port.
52
- port: S.optional(S.number),
52
+ port: S.optional(S.Number),
53
53
  }),
54
54
  );
55
55
 
56
56
  export type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;
57
57
 
58
58
  const WebsocketTriggerSchema = S.mutable(
59
- S.struct({
60
- type: S.literal('websocket'),
61
- url: S.string,
62
- init: S.optional(S.record(S.string, S.any)),
59
+ S.Struct({
60
+ type: S.Literal('websocket'),
61
+ url: S.String,
62
+ init: S.optional(S.Record(S.String, S.Any)),
63
63
  }),
64
64
  );
65
65
 
66
66
  export type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;
67
67
 
68
- const TriggerSpecSchema = S.union(
68
+ const TriggerSpecSchema = S.Union(
69
69
  TimerTriggerSchema,
70
70
  WebhookTriggerSchema,
71
71
  WebsocketTriggerSchema,
@@ -81,10 +81,10 @@ export class FunctionDef extends TypedObject({
81
81
  typename: 'dxos.org/type/FunctionDef',
82
82
  version: '0.1.0',
83
83
  })({
84
- uri: S.string,
85
- description: S.optional(S.string),
86
- route: S.string,
87
- handler: S.string,
84
+ uri: S.String,
85
+ description: S.optional(S.String),
86
+ route: S.String,
87
+ handler: S.String,
88
88
  }) {}
89
89
 
90
90
  /**
@@ -94,19 +94,19 @@ export class FunctionTrigger extends TypedObject({
94
94
  typename: 'dxos.org/type/FunctionTrigger',
95
95
  version: '0.1.0',
96
96
  })({
97
- enabled: S.optional(S.boolean),
98
- function: S.string.pipe(S.description('Function URI.')),
97
+ enabled: S.optional(S.Boolean),
98
+ function: S.String.pipe(S.description('Function URI.')),
99
99
  // The `meta` property is merged into the event data passed to the function.
100
- meta: S.optional(S.mutable(S.any)),
100
+ meta: S.optional(S.mutable(S.Any)),
101
101
  spec: TriggerSpecSchema,
102
102
  }) {}
103
103
 
104
104
  /**
105
105
  * Function manifest file.
106
106
  */
107
- export const FunctionManifestSchema = S.struct({
108
- functions: S.optional(S.mutable(S.array(RawObject(FunctionDef)))),
109
- triggers: S.optional(S.mutable(S.array(RawObject(FunctionTrigger)))),
107
+ export const FunctionManifestSchema = S.Struct({
108
+ functions: S.optional(S.mutable(S.Array(RawObject(FunctionDef)))),
109
+ triggers: S.optional(S.mutable(S.Array(RawObject(FunctionTrigger)))),
110
110
  });
111
111
 
112
112
  export type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;