@dxos/functions 0.6.10 → 0.6.11-staging.32b42e4

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 (44) hide show
  1. package/dist/lib/browser/{chunk-YSDC6YCF.mjs → chunk-2I75VGHZ.mjs} +3 -3
  2. package/dist/lib/browser/{chunk-YSDC6YCF.mjs.map → chunk-2I75VGHZ.mjs.map} +3 -3
  3. package/dist/lib/browser/chunk-CRAAIWU6.mjs +590 -0
  4. package/dist/lib/browser/chunk-CRAAIWU6.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +9 -7
  6. package/dist/lib/browser/index.mjs.map +1 -1
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/testing/index.mjs +522 -11
  9. package/dist/lib/browser/testing/index.mjs.map +4 -4
  10. package/dist/lib/browser/types.mjs +1 -1
  11. package/dist/lib/node/{chunk-3E6PY6JH.cjs → chunk-JV3VNH5X.cjs} +6 -6
  12. package/dist/lib/node/{chunk-3E6PY6JH.cjs.map → chunk-JV3VNH5X.cjs.map} +3 -3
  13. package/dist/lib/node/chunk-OGLDVNFE.cjs +613 -0
  14. package/dist/lib/node/chunk-OGLDVNFE.cjs.map +7 -0
  15. package/dist/lib/node/index.cjs +14 -12
  16. package/dist/lib/node/index.cjs.map +1 -1
  17. package/dist/lib/node/meta.json +1 -1
  18. package/dist/lib/node/testing/index.cjs +521 -13
  19. package/dist/lib/node/testing/index.cjs.map +4 -4
  20. package/dist/lib/node/types.cjs +5 -5
  21. package/dist/lib/node/types.cjs.map +1 -1
  22. package/dist/types/src/index.d.ts +0 -1
  23. package/dist/types/src/index.d.ts.map +1 -1
  24. package/dist/types/src/runtime/scheduler.d.ts.map +1 -1
  25. package/dist/types/src/trigger/index.d.ts +1 -0
  26. package/dist/types/src/trigger/index.d.ts.map +1 -1
  27. package/dist/types/src/trigger/trigger-registry.d.ts +5 -4
  28. package/dist/types/src/trigger/trigger-registry.d.ts.map +1 -1
  29. package/dist/types/src/trigger/type/index.d.ts +0 -1
  30. package/dist/types/src/trigger/type/index.d.ts.map +1 -1
  31. package/dist/types/src/types.d.ts +4 -0
  32. package/dist/types/src/types.d.ts.map +1 -1
  33. package/package.json +14 -14
  34. package/src/index.ts +1 -1
  35. package/src/runtime/scheduler.ts +6 -3
  36. package/src/trigger/index.ts +1 -0
  37. package/src/trigger/trigger-registry.test.ts +2 -1
  38. package/src/trigger/trigger-registry.ts +15 -7
  39. package/src/trigger/type/index.ts +1 -1
  40. package/src/types.ts +1 -0
  41. package/dist/lib/browser/chunk-OERXFETS.mjs +0 -1120
  42. package/dist/lib/browser/chunk-OERXFETS.mjs.map +0 -7
  43. package/dist/lib/node/chunk-ITQU6E54.cjs +0 -1133
  44. package/dist/lib/node/chunk-ITQU6E54.cjs.map +0 -7
@@ -1,18 +1,17 @@
1
1
  import "@dxos/node-std/globals";
2
2
  import {
3
- DevServer,
4
3
  FunctionRegistry,
5
- Scheduler,
6
4
  TriggerRegistry
7
- } from "../chunk-OERXFETS.mjs";
5
+ } from "../chunk-CRAAIWU6.mjs";
8
6
  import {
9
7
  FunctionDef,
10
- FunctionTrigger
11
- } from "../chunk-YSDC6YCF.mjs";
8
+ FunctionTrigger,
9
+ __require
10
+ } from "../chunk-2I75VGHZ.mjs";
12
11
 
13
12
  // packages/core/functions/src/testing/setup.ts
14
13
  import { getRandomPort } from "get-port-please";
15
- import path from "@dxos/node-std/path";
14
+ import path2 from "@dxos/node-std/path";
16
15
  import { waitForCondition } from "@dxos/async";
17
16
  import { Client, Config } from "@dxos/client";
18
17
  import { range } from "@dxos/util";
@@ -27,6 +26,518 @@ var TestType = class extends TypedObject({
27
26
  }) {
28
27
  };
29
28
 
29
+ // packages/core/functions/src/runtime/dev-server.ts
30
+ import express from "express";
31
+ import { getPort } from "get-port-please";
32
+ import { join } from "@dxos/node-std/path";
33
+ import { asyncTimeout, Event, Trigger } from "@dxos/async";
34
+ import { Context } from "@dxos/context";
35
+ import { invariant } from "@dxos/invariant";
36
+ import { log } from "@dxos/log";
37
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
38
+ var FN_TIMEOUT = 2e4;
39
+ var DevServer = class {
40
+ constructor(_client, _functionsRegistry, _options) {
41
+ this._client = _client;
42
+ this._functionsRegistry = _functionsRegistry;
43
+ this._options = _options;
44
+ this._ctx = createContext();
45
+ this._handlers = {};
46
+ this._seq = 0;
47
+ this.update = new Event();
48
+ }
49
+ get stats() {
50
+ return {
51
+ seq: this._seq
52
+ };
53
+ }
54
+ get endpoint() {
55
+ invariant(this._port, void 0, {
56
+ F: __dxlog_file,
57
+ L: 60,
58
+ S: this,
59
+ A: [
60
+ "this._port",
61
+ ""
62
+ ]
63
+ });
64
+ return `http://localhost:${this._port}`;
65
+ }
66
+ get proxy() {
67
+ return this._proxy;
68
+ }
69
+ get functions() {
70
+ return Object.values(this._handlers);
71
+ }
72
+ async start() {
73
+ invariant(!this._server, void 0, {
74
+ F: __dxlog_file,
75
+ L: 73,
76
+ S: this,
77
+ A: [
78
+ "!this._server",
79
+ ""
80
+ ]
81
+ });
82
+ log.info("starting...", void 0, {
83
+ F: __dxlog_file,
84
+ L: 74,
85
+ S: this,
86
+ C: (f, a) => f(...a)
87
+ });
88
+ this._ctx = createContext();
89
+ const app = express();
90
+ app.use(express.json());
91
+ app.post("/:path", async (req, res) => {
92
+ const { path: path3 } = req.params;
93
+ try {
94
+ log.info("calling", {
95
+ path: path3
96
+ }, {
97
+ F: __dxlog_file,
98
+ L: 84,
99
+ S: this,
100
+ C: (f, a) => f(...a)
101
+ });
102
+ if (this._options.reload) {
103
+ const { def } = this._handlers["/" + path3];
104
+ await this._load(def, true);
105
+ }
106
+ res.statusCode = await asyncTimeout(this.invoke("/" + path3, req.body), FN_TIMEOUT);
107
+ res.end();
108
+ } catch (err) {
109
+ log.catch(err, void 0, {
110
+ F: __dxlog_file,
111
+ L: 94,
112
+ S: this,
113
+ C: (f, a) => f(...a)
114
+ });
115
+ res.statusCode = 500;
116
+ res.end();
117
+ }
118
+ });
119
+ this._port = this._options.port ?? await getPort({
120
+ host: "localhost",
121
+ port: 7200,
122
+ portRange: [
123
+ 7200,
124
+ 7299
125
+ ]
126
+ });
127
+ this._server = app.listen(this._port);
128
+ try {
129
+ const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService.register({
130
+ endpoint: this.endpoint
131
+ });
132
+ log.info("registered", {
133
+ endpoint
134
+ }, {
135
+ F: __dxlog_file,
136
+ L: 109,
137
+ S: this,
138
+ C: (f, a) => f(...a)
139
+ });
140
+ this._proxy = endpoint;
141
+ this._functionServiceRegistration = registrationId;
142
+ await this._handleNewFunctions(this._functionsRegistry.getUniqueByUri());
143
+ this._ctx.onDispose(this._functionsRegistry.registered.on(({ added }) => this._handleNewFunctions(added)));
144
+ } catch (err) {
145
+ await this.stop();
146
+ throw new Error("FunctionRegistryService not available (check plugin is configured).");
147
+ }
148
+ log.info("started", {
149
+ port: this._port
150
+ }, {
151
+ F: __dxlog_file,
152
+ L: 121,
153
+ S: this,
154
+ C: (f, a) => f(...a)
155
+ });
156
+ }
157
+ async stop() {
158
+ if (!this._server) {
159
+ return;
160
+ }
161
+ log.info("stopping...", void 0, {
162
+ F: __dxlog_file,
163
+ L: 129,
164
+ S: this,
165
+ C: (f, a) => f(...a)
166
+ });
167
+ await this._ctx.dispose();
168
+ const trigger = new Trigger();
169
+ this._server.close(async () => {
170
+ log.info("server stopped", void 0, {
171
+ F: __dxlog_file,
172
+ L: 134,
173
+ S: this,
174
+ C: (f, a) => f(...a)
175
+ });
176
+ try {
177
+ if (this._functionServiceRegistration) {
178
+ invariant(this._client.services.services.FunctionRegistryService, void 0, {
179
+ F: __dxlog_file,
180
+ L: 137,
181
+ S: this,
182
+ A: [
183
+ "this._client.services.services.FunctionRegistryService",
184
+ ""
185
+ ]
186
+ });
187
+ await this._client.services.services.FunctionRegistryService.unregister({
188
+ registrationId: this._functionServiceRegistration
189
+ });
190
+ log.info("unregistered", {
191
+ registrationId: this._functionServiceRegistration
192
+ }, {
193
+ F: __dxlog_file,
194
+ L: 142,
195
+ S: this,
196
+ C: (f, a) => f(...a)
197
+ });
198
+ this._functionServiceRegistration = void 0;
199
+ this._proxy = void 0;
200
+ }
201
+ trigger.wake();
202
+ } catch (err) {
203
+ trigger.throw(err);
204
+ }
205
+ });
206
+ await trigger.wait();
207
+ this._port = void 0;
208
+ this._server = void 0;
209
+ log.info("stopped", void 0, {
210
+ F: __dxlog_file,
211
+ L: 156,
212
+ S: this,
213
+ C: (f, a) => f(...a)
214
+ });
215
+ }
216
+ async _handleNewFunctions(newFunctions) {
217
+ newFunctions.forEach((def) => this._load(def));
218
+ await this._safeUpdateRegistration();
219
+ log("new functions loaded", {
220
+ newFunctions
221
+ }, {
222
+ F: __dxlog_file,
223
+ L: 162,
224
+ S: this,
225
+ C: (f, a) => f(...a)
226
+ });
227
+ }
228
+ /**
229
+ * Load function.
230
+ */
231
+ async _load(def, force) {
232
+ const { uri, route, handler } = def;
233
+ const filePath = join(this._options.baseDir, handler);
234
+ log.info("loading", {
235
+ uri,
236
+ force
237
+ }, {
238
+ F: __dxlog_file,
239
+ L: 171,
240
+ S: this,
241
+ C: (f, a) => f(...a)
242
+ });
243
+ if (force) {
244
+ Object.keys(__require.cache).filter((key) => key.startsWith(filePath)).forEach((key) => {
245
+ delete __require.cache[key];
246
+ });
247
+ }
248
+ const module = __require(filePath);
249
+ if (typeof module.default !== "function") {
250
+ throw new Error(`Handler must export default function: ${uri}`);
251
+ }
252
+ this._handlers[route] = {
253
+ def,
254
+ handler: module.default
255
+ };
256
+ }
257
+ async _safeUpdateRegistration() {
258
+ invariant(this._functionServiceRegistration, void 0, {
259
+ F: __dxlog_file,
260
+ L: 193,
261
+ S: this,
262
+ A: [
263
+ "this._functionServiceRegistration",
264
+ ""
265
+ ]
266
+ });
267
+ try {
268
+ await this._client.services.services.FunctionRegistryService.updateRegistration({
269
+ registrationId: this._functionServiceRegistration,
270
+ functions: this.functions.map(({ def: { id, route } }) => ({
271
+ id,
272
+ route
273
+ }))
274
+ });
275
+ } catch (err) {
276
+ log.catch(err, void 0, {
277
+ F: __dxlog_file,
278
+ L: 200,
279
+ S: this,
280
+ C: (f, a) => f(...a)
281
+ });
282
+ }
283
+ }
284
+ /**
285
+ * Invoke function.
286
+ */
287
+ async invoke(path3, data) {
288
+ const seq = ++this._seq;
289
+ const now = Date.now();
290
+ log.info("req", {
291
+ seq,
292
+ path: path3
293
+ }, {
294
+ F: __dxlog_file,
295
+ L: 211,
296
+ S: this,
297
+ C: (f, a) => f(...a)
298
+ });
299
+ const statusCode = await this._invoke(path3, {
300
+ data
301
+ });
302
+ log.info("res", {
303
+ seq,
304
+ path: path3,
305
+ statusCode,
306
+ duration: Date.now() - now
307
+ }, {
308
+ F: __dxlog_file,
309
+ L: 214,
310
+ S: this,
311
+ C: (f, a) => f(...a)
312
+ });
313
+ this.update.emit(statusCode);
314
+ return statusCode;
315
+ }
316
+ async _invoke(path3, event) {
317
+ const { handler } = this._handlers[path3] ?? {};
318
+ invariant(handler, `invalid path: ${path3}`, {
319
+ F: __dxlog_file,
320
+ L: 221,
321
+ S: this,
322
+ A: [
323
+ "handler",
324
+ "`invalid path: ${path}`"
325
+ ]
326
+ });
327
+ const context = {
328
+ client: this._client,
329
+ dataDir: this._options.dataDir
330
+ };
331
+ let statusCode = 200;
332
+ const response = {
333
+ status: (code) => {
334
+ statusCode = code;
335
+ return response;
336
+ }
337
+ };
338
+ await handler({
339
+ context,
340
+ event,
341
+ response
342
+ });
343
+ return statusCode;
344
+ }
345
+ };
346
+ var createContext = () => new Context({
347
+ name: "DevServer"
348
+ }, {
349
+ F: __dxlog_file,
350
+ L: 240
351
+ });
352
+
353
+ // packages/core/functions/src/runtime/scheduler.ts
354
+ import path from "@dxos/node-std/path";
355
+ import { Mutex } from "@dxos/async";
356
+ import { loadObjectReferences } from "@dxos/client/echo";
357
+ import { Context as Context2 } from "@dxos/context";
358
+ import { Reference } from "@dxos/echo-protocol";
359
+ import { log as log2 } from "@dxos/log";
360
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/scheduler.ts";
361
+ var Scheduler = class {
362
+ constructor(functions, triggers, _options = {}) {
363
+ this.functions = functions;
364
+ this.triggers = triggers;
365
+ this._options = _options;
366
+ this._ctx = createContext2();
367
+ this._functionUriToCallMutex = /* @__PURE__ */ new Map();
368
+ this.functions.registered.on(async ({ space, added }) => {
369
+ await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), added);
370
+ });
371
+ this.triggers.registered.on(async ({ space, triggers: triggers2 }) => {
372
+ await this._safeActivateTriggers(space, triggers2, this.functions.getFunctions(space));
373
+ });
374
+ }
375
+ async start() {
376
+ await this._ctx.dispose();
377
+ this._ctx = createContext2();
378
+ await this.functions.open(this._ctx);
379
+ await this.triggers.open(this._ctx);
380
+ }
381
+ async stop() {
382
+ await this._ctx.dispose();
383
+ await this.functions.close();
384
+ await this.triggers.close();
385
+ }
386
+ // TODO(burdon): Remove and update registries directly?
387
+ async register(space, manifest) {
388
+ await this.functions.register(space, manifest.functions);
389
+ await this.triggers.register(space, manifest);
390
+ }
391
+ async _safeActivateTriggers(space, triggers, functions) {
392
+ const mountTasks = triggers.map((trigger) => {
393
+ return this.activate(space, functions, trigger);
394
+ });
395
+ await Promise.all(mountTasks).catch(log2.catch);
396
+ }
397
+ /**
398
+ * Activate trigger.
399
+ */
400
+ // TODO(burdon): How are triggers deactivated?
401
+ async activate(space, functions, trigger) {
402
+ const definition = functions.find((def) => def.uri === trigger.function);
403
+ if (!definition) {
404
+ log2.info("function is not found for trigger", {
405
+ trigger
406
+ }, {
407
+ F: __dxlog_file2,
408
+ L: 85,
409
+ S: this,
410
+ C: (f, a) => f(...a)
411
+ });
412
+ return;
413
+ }
414
+ const execFunction = async (args) => {
415
+ const mutex = this._functionUriToCallMutex.get(definition.uri) ?? new Mutex();
416
+ this._functionUriToCallMutex.set(definition.uri, mutex);
417
+ log2.info("function triggered, waiting for mutex", {
418
+ uri: definition.uri
419
+ }, {
420
+ F: __dxlog_file2,
421
+ L: 93,
422
+ S: this,
423
+ C: (f, a) => f(...a)
424
+ });
425
+ return mutex.executeSynchronized(async () => {
426
+ log2.info("mutex acquired", {
427
+ uri: definition.uri
428
+ }, {
429
+ F: __dxlog_file2,
430
+ L: 95,
431
+ S: this,
432
+ C: (f, a) => f(...a)
433
+ });
434
+ await loadObjectReferences(trigger, (t) => Object.values(t.meta ?? {}));
435
+ const meta = {};
436
+ for (const [key, value] of Object.entries(trigger.meta ?? {})) {
437
+ if (value instanceof Reference) {
438
+ const object = await space.db.loadObjectById(value.objectId);
439
+ if (object) {
440
+ meta[key] = object;
441
+ }
442
+ } else {
443
+ meta[key] = value;
444
+ }
445
+ }
446
+ return this._execFunction(definition, trigger, {
447
+ meta,
448
+ data: {
449
+ ...args,
450
+ spaceKey: space.key
451
+ }
452
+ });
453
+ });
454
+ };
455
+ await this.triggers.activate(space, trigger, execFunction);
456
+ log2("activated trigger", {
457
+ space: space.key,
458
+ trigger
459
+ }, {
460
+ F: __dxlog_file2,
461
+ L: 119,
462
+ S: this,
463
+ C: (f, a) => f(...a)
464
+ });
465
+ }
466
+ /**
467
+ * Invoke function RPC.
468
+ */
469
+ async _execFunction(def, trigger, { meta, data }) {
470
+ let status = 0;
471
+ try {
472
+ const payload = Object.assign({}, meta && {
473
+ meta
474
+ }, data);
475
+ const { endpoint, callback } = this._options;
476
+ if (endpoint) {
477
+ const url = path.join(endpoint, def.route);
478
+ log2.info("exec", {
479
+ function: def.uri,
480
+ url,
481
+ triggerType: trigger.spec.type
482
+ }, {
483
+ F: __dxlog_file2,
484
+ L: 139,
485
+ S: this,
486
+ C: (f, a) => f(...a)
487
+ });
488
+ const response = await fetch(url, {
489
+ method: "POST",
490
+ headers: {
491
+ "Content-Type": "application/json"
492
+ },
493
+ body: JSON.stringify(payload)
494
+ });
495
+ status = response.status;
496
+ } else if (callback) {
497
+ log2.info("exec", {
498
+ function: def.uri
499
+ }, {
500
+ F: __dxlog_file2,
501
+ L: 150,
502
+ S: this,
503
+ C: (f, a) => f(...a)
504
+ });
505
+ status = await callback(payload) ?? 200;
506
+ }
507
+ if (status && status >= 400) {
508
+ throw new Error(`Response: ${status}`);
509
+ }
510
+ log2.info("done", {
511
+ function: def.uri,
512
+ status
513
+ }, {
514
+ F: __dxlog_file2,
515
+ L: 160,
516
+ S: this,
517
+ C: (f, a) => f(...a)
518
+ });
519
+ } catch (err) {
520
+ log2.error("error", {
521
+ function: def.uri,
522
+ error: err.message
523
+ }, {
524
+ F: __dxlog_file2,
525
+ L: 162,
526
+ S: this,
527
+ C: (f, a) => f(...a)
528
+ });
529
+ status = 500;
530
+ }
531
+ return status;
532
+ }
533
+ };
534
+ var createContext2 = () => new Context2({
535
+ name: "FunctionScheduler"
536
+ }, {
537
+ F: __dxlog_file2,
538
+ L: 170
539
+ });
540
+
30
541
  // packages/core/functions/src/testing/setup.ts
31
542
  var createInitializedClients = async (testBuilder, count = 1, config) => {
32
543
  const clients = range(count).map(() => new Client({
@@ -95,7 +606,7 @@ var startScheduler = async (testBuilder, client, devServer, functionRegistry) =>
95
606
  };
96
607
  var startDevServer = async (testBuilder, client, functionRegistry, options) => {
97
608
  const server = new DevServer(client, functionRegistry, {
98
- baseDir: path.join(__dirname, "../testing"),
609
+ baseDir: path2.join(__dirname, "../testing"),
99
610
  port: await getRandomPort("127.0.0.1"),
100
611
  ...options
101
612
  });
@@ -107,13 +618,13 @@ var startDevServer = async (testBuilder, client, functionRegistry, options) => {
107
618
  // packages/core/functions/src/testing/util.ts
108
619
  import { Filter } from "@dxos/client/echo";
109
620
  import { performInvitation } from "@dxos/client/testing";
110
- import { invariant } from "@dxos/invariant";
621
+ import { invariant as invariant2 } from "@dxos/invariant";
111
622
  import { Invitation } from "@dxos/protocols/proto/dxos/client/services";
112
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/testing/util.ts";
623
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/functions/src/testing/util.ts";
113
624
  var triggerWebhook = async (space, uri) => {
114
625
  const trigger = (await space.db.query(Filter.schema(FunctionTrigger, (t) => t.function === uri)).run()).objects[0];
115
- invariant(trigger.spec.type === "webhook", void 0, {
116
- F: __dxlog_file,
626
+ invariant2(trigger.spec.type === "webhook", void 0, {
627
+ F: __dxlog_file3,
117
628
  L: 17,
118
629
  S: void 0,
119
630
  A: [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../src/testing/setup.ts", "../../../../src/testing/types.ts", "../../../../src/testing/util.ts", "../../../../src/testing/manifest.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { getRandomPort } from 'get-port-please';\nimport path from 'node:path';\n\nimport { waitForCondition } from '@dxos/async';\nimport { Client, Config } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { type TestBuilder } from '@dxos/client/testing';\nimport { range } from '@dxos/util';\n\nimport { TestType } from './types';\nimport { FunctionRegistry } from '../function';\nimport { DevServer, type DevServerOptions, Scheduler } from '../runtime';\nimport { TriggerRegistry } from '../trigger';\nimport { FunctionDef, FunctionTrigger } from '../types';\n\nexport type FunctionsPluginInitializer = (client: Client) => Promise<{ close: () => Promise<void> }>;\n\n// TODO(burdon): Extend/wrap TestBuilder.\n\nexport const createInitializedClients = async (testBuilder: TestBuilder, count: number = 1, config?: Config) => {\n const clients = range(count).map(() => new Client({ config, services: testBuilder.createLocalClientServices() }));\n testBuilder.ctx.onDispose(() => Promise.all(clients.map((client) => client.destroy())));\n return Promise.all(\n clients.map(async (client, index) => {\n await client.initialize();\n await client.halo.createIdentity({ displayName: `Peer ${index}` });\n await client.spaces.isReady.wait();\n client.addTypes([FunctionDef, FunctionTrigger, TestType]);\n return client;\n }),\n );\n};\n\nexport const createFunctionRuntime = async (\n testBuilder: TestBuilder,\n pluginInitializer: FunctionsPluginInitializer,\n): Promise<Client> => {\n const functionsPort = await getRandomPort('127.0.0.1');\n const config = new Config({\n runtime: {\n agent: {\n plugins: [{ id: 'dxos.org/agent/plugin/functions', config: { port: functionsPort } }],\n },\n },\n });\n\n const [client] = await createInitializedClients(testBuilder, 1, config);\n const plugin = await pluginInitializer(client);\n testBuilder.ctx.onDispose(() => plugin.close());\n return client;\n};\n\nexport const startFunctionsHost = async (\n testBuilder: TestBuilder,\n pluginInitializer: FunctionsPluginInitializer,\n options?: DevServerOptions,\n) => {\n const functionRuntime = await createFunctionRuntime(testBuilder, pluginInitializer);\n const functionsRegistry = new FunctionRegistry(functionRuntime);\n const devServer = await startDevServer(testBuilder, functionRuntime, functionsRegistry, options);\n const scheduler = await startScheduler(testBuilder, functionRuntime, devServer, functionsRegistry);\n return {\n scheduler,\n client: functionRuntime,\n waitForActiveTriggers: async (space: Space) => {\n await waitForCondition({ condition: () => scheduler.triggers.getActiveTriggers(space).length > 0 });\n },\n };\n};\n\nconst startScheduler = async (\n testBuilder: TestBuilder,\n client: Client,\n devServer: DevServer,\n functionRegistry: FunctionRegistry,\n) => {\n const triggerRegistry = new TriggerRegistry(client);\n const scheduler = new Scheduler(functionRegistry, triggerRegistry, { endpoint: devServer.endpoint });\n await scheduler.start();\n testBuilder.ctx.onDispose(() => scheduler.stop());\n return scheduler;\n};\n\nconst startDevServer = async (\n testBuilder: TestBuilder,\n client: Client,\n functionRegistry: FunctionRegistry,\n options?: { baseDir?: string },\n) => {\n const server = new DevServer(client, functionRegistry, {\n baseDir: path.join(__dirname, '../testing'),\n port: await getRandomPort('127.0.0.1'),\n ...options,\n });\n await server.start();\n testBuilder.ctx.onDispose(() => server.stop());\n return server;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { S, TypedObject } from '@dxos/echo-schema';\n\nexport class TestType extends TypedObject({ typename: 'example.com/type/Test', version: '0.1.0' })({\n title: S.String,\n}) {}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { Client } from '@dxos/client';\nimport { Filter, type Space } from '@dxos/client/echo';\nimport { performInvitation } from '@dxos/client/testing';\nimport { invariant } from '@dxos/invariant';\nimport { Invitation } from '@dxos/protocols/proto/dxos/client/services';\n\nimport { FunctionTrigger } from '../types';\n\nexport const triggerWebhook = async (space: Space, uri: string) => {\n const trigger = (\n await space.db.query(Filter.schema(FunctionTrigger, (t: FunctionTrigger) => t.function === uri)).run()\n ).objects[0];\n invariant(trigger.spec.type === 'webhook');\n void fetch(`http://localhost:${trigger.spec.port}`);\n};\n\nexport const inviteMember = async (host: Space, guest: Client) => {\n const [{ invitation: hostInvitation }] = await Promise.all(performInvitation({ host, guest: guest.spaces }));\n if (hostInvitation?.state !== Invitation.State.SUCCESS) {\n throw new Error(`Expected ${hostInvitation?.state} to be ${Invitation.State.SUCCESS}.`);\n }\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { FunctionManifest } from '../types';\n\nexport const testFunctionManifest: FunctionManifest = {\n functions: [\n {\n uri: 'example.com/function/test',\n route: 'test',\n handler: 'test',\n },\n ],\n};\n"],
5
- "mappings": "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",
6
- "names": ["getRandomPort", "path", "waitForCondition", "Client", "Config", "range", "S", "TypedObject", "TestType", "TypedObject", "typename", "version", "title", "S", "String", "createInitializedClients", "testBuilder", "count", "config", "clients", "range", "map", "Client", "services", "createLocalClientServices", "ctx", "onDispose", "Promise", "all", "client", "destroy", "index", "initialize", "halo", "createIdentity", "displayName", "spaces", "isReady", "wait", "addTypes", "FunctionDef", "FunctionTrigger", "TestType", "createFunctionRuntime", "pluginInitializer", "functionsPort", "getRandomPort", "Config", "runtime", "agent", "plugins", "id", "port", "plugin", "close", "startFunctionsHost", "options", "functionRuntime", "functionsRegistry", "FunctionRegistry", "devServer", "startDevServer", "scheduler", "startScheduler", "waitForActiveTriggers", "space", "waitForCondition", "condition", "triggers", "getActiveTriggers", "length", "functionRegistry", "triggerRegistry", "TriggerRegistry", "Scheduler", "endpoint", "start", "stop", "server", "DevServer", "baseDir", "path", "join", "__dirname", "Filter", "performInvitation", "invariant", "Invitation", "triggerWebhook", "space", "uri", "trigger", "db", "query", "Filter", "schema", "FunctionTrigger", "t", "function", "run", "objects", "invariant", "spec", "type", "fetch", "port", "inviteMember", "host", "guest", "invitation", "hostInvitation", "Promise", "all", "performInvitation", "spaces", "state", "Invitation", "State", "SUCCESS", "Error", "testFunctionManifest", "functions", "uri", "route", "handler"]
3
+ "sources": ["../../../../src/testing/setup.ts", "../../../../src/testing/types.ts", "../../../../src/runtime/dev-server.ts", "../../../../src/runtime/scheduler.ts", "../../../../src/testing/util.ts", "../../../../src/testing/manifest.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { getRandomPort } from 'get-port-please';\nimport path from 'node:path';\n\nimport { waitForCondition } from '@dxos/async';\nimport { Client, Config } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { type TestBuilder } from '@dxos/client/testing';\nimport { range } from '@dxos/util';\n\nimport { TestType } from './types';\nimport { FunctionRegistry } from '../function';\nimport { DevServer, type DevServerOptions, Scheduler } from '../runtime';\nimport { TriggerRegistry } from '../trigger';\nimport { FunctionDef, FunctionTrigger } from '../types';\n\nexport type FunctionsPluginInitializer = (client: Client) => Promise<{ close: () => Promise<void> }>;\n\n// TODO(burdon): Extend/wrap TestBuilder.\n\nexport const createInitializedClients = async (testBuilder: TestBuilder, count: number = 1, config?: Config) => {\n const clients = range(count).map(() => new Client({ config, services: testBuilder.createLocalClientServices() }));\n testBuilder.ctx.onDispose(() => Promise.all(clients.map((client) => client.destroy())));\n return Promise.all(\n clients.map(async (client, index) => {\n await client.initialize();\n await client.halo.createIdentity({ displayName: `Peer ${index}` });\n await client.spaces.isReady.wait();\n client.addTypes([FunctionDef, FunctionTrigger, TestType]);\n return client;\n }),\n );\n};\n\nexport const createFunctionRuntime = async (\n testBuilder: TestBuilder,\n pluginInitializer: FunctionsPluginInitializer,\n): Promise<Client> => {\n const functionsPort = await getRandomPort('127.0.0.1');\n const config = new Config({\n runtime: {\n agent: {\n plugins: [{ id: 'dxos.org/agent/plugin/functions', config: { port: functionsPort } }],\n },\n },\n });\n\n const [client] = await createInitializedClients(testBuilder, 1, config);\n const plugin = await pluginInitializer(client);\n testBuilder.ctx.onDispose(() => plugin.close());\n return client;\n};\n\nexport const startFunctionsHost = async (\n testBuilder: TestBuilder,\n pluginInitializer: FunctionsPluginInitializer,\n options?: DevServerOptions,\n) => {\n const functionRuntime = await createFunctionRuntime(testBuilder, pluginInitializer);\n const functionsRegistry = new FunctionRegistry(functionRuntime);\n const devServer = await startDevServer(testBuilder, functionRuntime, functionsRegistry, options);\n const scheduler = await startScheduler(testBuilder, functionRuntime, devServer, functionsRegistry);\n return {\n scheduler,\n client: functionRuntime,\n waitForActiveTriggers: async (space: Space) => {\n await waitForCondition({ condition: () => scheduler.triggers.getActiveTriggers(space).length > 0 });\n },\n };\n};\n\nconst startScheduler = async (\n testBuilder: TestBuilder,\n client: Client,\n devServer: DevServer,\n functionRegistry: FunctionRegistry,\n) => {\n const triggerRegistry = new TriggerRegistry(client);\n const scheduler = new Scheduler(functionRegistry, triggerRegistry, { endpoint: devServer.endpoint });\n await scheduler.start();\n testBuilder.ctx.onDispose(() => scheduler.stop());\n return scheduler;\n};\n\nconst startDevServer = async (\n testBuilder: TestBuilder,\n client: Client,\n functionRegistry: FunctionRegistry,\n options?: { baseDir?: string },\n) => {\n const server = new DevServer(client, functionRegistry, {\n baseDir: path.join(__dirname, '../testing'),\n port: await getRandomPort('127.0.0.1'),\n ...options,\n });\n await server.start();\n testBuilder.ctx.onDispose(() => server.stop());\n return server;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { S, TypedObject } from '@dxos/echo-schema';\n\nexport class TestType extends TypedObject({ typename: 'example.com/type/Test', version: '0.1.0' })({\n title: S.String,\n}) {}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { asyncTimeout, Event, Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionRegistry } from '../function';\nimport { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';\nimport { type FunctionDef } from '../types';\n\nconst FN_TIMEOUT = 20_000;\n\nexport type DevServerOptions = {\n baseDir: string;\n port?: number;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for loading and invoking functions.\n * Functions are executed in the context of an authenticated client.\n */\nexport class DevServer {\n private _ctx = createContext();\n\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _functionServiceRegistration?: string;\n private _proxy?: string;\n private _seq = 0;\n\n public readonly update = new Event<number>();\n\n constructor(\n private readonly _client: Client,\n private readonly _functionsRegistry: FunctionRegistry,\n private readonly _options: DevServerOptions,\n ) {}\n\n get stats() {\n return {\n seq: this._seq,\n };\n }\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async start() {\n invariant(!this._server);\n log.info('starting...');\n this._ctx = createContext();\n\n // TODO(burdon): Change to hono.\n const app = express();\n app.use(express.json());\n\n app.post('/:path', async (req, res) => {\n const { path } = req.params;\n try {\n log.info('calling', { path });\n if (this._options.reload) {\n const { def } = this._handlers['/' + path];\n await this._load(def, true);\n }\n\n // TODO(burdon): Get function context.\n res.statusCode = await asyncTimeout(this.invoke('/' + path, req.body), FN_TIMEOUT);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = this._options.port ?? (await getPort({ host: 'localhost', port: 7200, portRange: [7200, 7299] }));\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n\n // Open after registration, so that it can be updated with the list of function definitions.\n await this._handleNewFunctions(this._functionsRegistry.getUniqueByUri());\n this._ctx.onDispose(this._functionsRegistry.registered.on(({ added }) => this._handleNewFunctions(added)));\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n\n log.info('started', { port: this._port });\n }\n\n async stop() {\n if (!this._server) {\n return;\n }\n\n log.info('stopping...');\n await this._ctx.dispose();\n\n const trigger = new Trigger();\n this._server.close(async () => {\n log.info('server stopped');\n try {\n if (this._functionServiceRegistration) {\n invariant(this._client.services.services.FunctionRegistryService);\n await this._client.services.services.FunctionRegistryService.unregister({\n registrationId: this._functionServiceRegistration,\n });\n\n log.info('unregistered', { registrationId: this._functionServiceRegistration });\n this._functionServiceRegistration = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n } catch (err) {\n trigger.throw(err as Error);\n }\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n log.info('stopped');\n }\n\n private async _handleNewFunctions(newFunctions: FunctionDef[]) {\n newFunctions.forEach((def) => this._load(def));\n await this._safeUpdateRegistration();\n log('new functions loaded', { newFunctions });\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, force?: boolean | undefined) {\n const { uri, route, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { uri, force });\n\n // Remove from cache.\n if (force) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(filePath))\n .forEach((key) => {\n delete require.cache[key];\n });\n }\n\n // TODO(burdon): Import types.\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(filePath);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${uri}`);\n }\n\n this._handlers[route] = { def, handler: module.default };\n }\n\n private async _safeUpdateRegistration(): Promise<void> {\n invariant(this._functionServiceRegistration);\n try {\n await this._client.services.services.FunctionRegistryService!.updateRegistration({\n registrationId: this._functionServiceRegistration,\n functions: this.functions.map(({ def: { id, route } }) => ({ id, route })),\n });\n } catch (err) {\n log.catch(err);\n }\n }\n\n /**\n * Invoke function.\n */\n public async invoke(path: string, data: any): Promise<number> {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, path });\n const statusCode = await this._invoke(path, { data });\n\n log.info('res', { seq, path, statusCode, duration: Date.now() - now });\n this.update.emit(statusCode);\n return statusCode;\n }\n\n private async _invoke(path: string, event: FunctionEvent) {\n const { handler } = this._handlers[path] ?? {};\n invariant(handler, `invalid path: ${path}`);\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n } as any;\n\n let statusCode = 200;\n const response: FunctionResponse = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n return statusCode;\n }\n}\n\nconst createContext = () => new Context({ name: 'DevServer' });\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { Mutex } from '@dxos/async';\nimport { loadObjectReferences, type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Reference } from '@dxos/echo-protocol';\nimport { log } from '@dxos/log';\n\nimport { type FunctionRegistry } from '../function';\nimport { type FunctionEventMeta } from '../handler';\nimport { type TriggerCallback, type TriggerRegistry } from '../trigger';\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../types';\n\nexport type Callback = (data: any) => Promise<void | number>;\n\nexport type SchedulerOptions = {\n endpoint?: string;\n callback?: Callback;\n};\n\n/**\n * The scheduler triggers function execution based on various trigger configurations.\n * Functions are scheduled within the context of a specific space.\n */\nexport class Scheduler {\n private _ctx = createContext();\n\n private readonly _functionUriToCallMutex = new Map<string, Mutex>();\n\n constructor(\n public readonly functions: FunctionRegistry,\n public readonly triggers: TriggerRegistry,\n private readonly _options: SchedulerOptions = {},\n ) {\n this.functions.registered.on(async ({ space, added }) => {\n await this._safeActivateTriggers(space, this.triggers.getInactiveTriggers(space), added);\n });\n this.triggers.registered.on(async ({ space, triggers }) => {\n await this._safeActivateTriggers(space, triggers, this.functions.getFunctions(space));\n });\n }\n\n async start() {\n await this._ctx.dispose();\n this._ctx = createContext();\n await this.functions.open(this._ctx);\n await this.triggers.open(this._ctx);\n }\n\n async stop() {\n await this._ctx.dispose();\n await this.functions.close();\n await this.triggers.close();\n }\n\n // TODO(burdon): Remove and update registries directly?\n public async register(space: Space, manifest: FunctionManifest) {\n await this.functions.register(space, manifest.functions);\n await this.triggers.register(space, manifest);\n }\n\n private async _safeActivateTriggers(\n space: Space,\n triggers: FunctionTrigger[],\n functions: FunctionDef[],\n ): Promise<void> {\n const mountTasks = triggers.map((trigger) => {\n return this.activate(space, functions, trigger);\n });\n\n await Promise.all(mountTasks).catch(log.catch);\n }\n\n /**\n * Activate trigger.\n */\n // TODO(burdon): How are triggers deactivated?\n private async activate(space: Space, functions: FunctionDef[], trigger: FunctionTrigger) {\n const definition = functions.find((def) => def.uri === trigger.function);\n if (!definition) {\n log.info('function is not found for trigger', { trigger });\n return;\n }\n\n const execFunction: TriggerCallback = async (args) => {\n const mutex = this._functionUriToCallMutex.get(definition.uri) ?? new Mutex();\n this._functionUriToCallMutex.set(definition.uri, mutex);\n\n log.info('function triggered, waiting for mutex', { uri: definition.uri });\n return mutex.executeSynchronized(async () => {\n log.info('mutex acquired', { uri: definition.uri });\n\n // Load potential references in meta properties to serialize.\n await loadObjectReferences(trigger, (t) => Object.values(t.meta ?? {}));\n const meta: FunctionTrigger['meta'] = {};\n for (const [key, value] of Object.entries(trigger.meta ?? {})) {\n if (value instanceof Reference) {\n const object = await space.db.loadObjectById(value.objectId);\n if (object) {\n meta[key] = object;\n }\n } else {\n meta[key] = value;\n }\n }\n\n return this._execFunction(definition, trigger, {\n meta,\n data: { ...args, spaceKey: space.key },\n });\n });\n };\n\n await this.triggers.activate(space, trigger, execFunction);\n log('activated trigger', { space: space.key, trigger });\n }\n\n /**\n * Invoke function RPC.\n */\n private async _execFunction<TData, TMeta>(\n def: FunctionDef,\n trigger: FunctionTrigger,\n { meta, data }: { meta?: TMeta; data: TData },\n ): Promise<number> {\n let status = 0;\n try {\n // TODO(burdon): Pass in Space key (common context)?\n const payload = Object.assign({}, meta && ({ meta } satisfies FunctionEventMeta<TMeta>), data);\n\n const { endpoint, callback } = this._options;\n if (endpoint) {\n // TODO(burdon): Move out of scheduler (generalize as callback).\n const url = path.join(endpoint, def.route);\n log.info('exec', { function: def.uri, url, triggerType: trigger.spec.type });\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n status = response.status;\n } else if (callback) {\n log.info('exec', { function: def.uri });\n status = (await callback(payload)) ?? 200;\n }\n\n // Check errors.\n if (status && status >= 400) {\n throw new Error(`Response: ${status}`);\n }\n\n // const result = await response.json();\n log.info('done', { function: def.uri, status });\n } catch (err: any) {\n log.error('error', { function: def.uri, error: err.message });\n status = 500;\n }\n\n return status;\n }\n}\n\nconst createContext = () => new Context({ name: 'FunctionScheduler' });\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { Client } from '@dxos/client';\nimport { Filter, type Space } from '@dxos/client/echo';\nimport { performInvitation } from '@dxos/client/testing';\nimport { invariant } from '@dxos/invariant';\nimport { Invitation } from '@dxos/protocols/proto/dxos/client/services';\n\nimport { FunctionTrigger } from '../types';\n\nexport const triggerWebhook = async (space: Space, uri: string) => {\n const trigger = (\n await space.db.query(Filter.schema(FunctionTrigger, (t: FunctionTrigger) => t.function === uri)).run()\n ).objects[0];\n invariant(trigger.spec.type === 'webhook');\n void fetch(`http://localhost:${trigger.spec.port}`);\n};\n\nexport const inviteMember = async (host: Space, guest: Client) => {\n const [{ invitation: hostInvitation }] = await Promise.all(performInvitation({ host, guest: guest.spaces }));\n if (hostInvitation?.state !== Invitation.State.SUCCESS) {\n throw new Error(`Expected ${hostInvitation?.state} to be ${Invitation.State.SUCCESS}.`);\n }\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { FunctionManifest } from '../types';\n\nexport const testFunctionManifest: FunctionManifest = {\n functions: [\n {\n uri: 'example.com/function/test',\n route: 'test',\n handler: 'test',\n },\n ],\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["getRandomPort", "path", "waitForCondition", "Client", "Config", "range", "S", "TypedObject", "TestType", "TypedObject", "typename", "version", "title", "S", "String", "express", "getPort", "join", "asyncTimeout", "Event", "Trigger", "Context", "invariant", "log", "FN_TIMEOUT", "DevServer", "constructor", "_client", "_functionsRegistry", "_options", "_ctx", "createContext", "_handlers", "_seq", "update", "Event", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "start", "_server", "log", "info", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "def", "_load", "statusCode", "asyncTimeout", "invoke", "body", "end", "err", "catch", "port", "getPort", "host", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "register", "_functionServiceRegistration", "_handleNewFunctions", "getUniqueByUri", "onDispose", "registered", "on", "added", "stop", "Error", "dispose", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "throw", "wait", "newFunctions", "forEach", "_safeUpdateRegistration", "force", "uri", "route", "handler", "filePath", "join", "baseDir", "keys", "require", "cache", "filter", "key", "startsWith", "module", "default", "updateRegistration", "map", "id", "data", "now", "Date", "_invoke", "duration", "emit", "event", "context", "client", "dataDir", "response", "status", "code", "Context", "name", "path", "Mutex", "loadObjectReferences", "Context", "Reference", "log", "Scheduler", "constructor", "functions", "triggers", "_options", "_ctx", "createContext", "_functionUriToCallMutex", "Map", "registered", "on", "space", "added", "_safeActivateTriggers", "getInactiveTriggers", "getFunctions", "start", "dispose", "open", "stop", "close", "register", "manifest", "mountTasks", "map", "trigger", "activate", "Promise", "all", "catch", "definition", "find", "def", "uri", "function", "info", "execFunction", "args", "mutex", "get", "set", "executeSynchronized", "t", "Object", "values", "meta", "key", "value", "entries", "object", "db", "loadObjectById", "objectId", "_execFunction", "data", "spaceKey", "status", "payload", "assign", "endpoint", "callback", "url", "join", "route", "triggerType", "spec", "type", "response", "fetch", "method", "headers", "body", "JSON", "stringify", "Error", "err", "error", "message", "name", "createInitializedClients", "testBuilder", "count", "config", "clients", "range", "map", "Client", "services", "createLocalClientServices", "ctx", "onDispose", "Promise", "all", "client", "destroy", "index", "initialize", "halo", "createIdentity", "displayName", "spaces", "isReady", "wait", "addTypes", "FunctionDef", "FunctionTrigger", "TestType", "createFunctionRuntime", "pluginInitializer", "functionsPort", "getRandomPort", "Config", "runtime", "agent", "plugins", "id", "port", "plugin", "close", "startFunctionsHost", "options", "functionRuntime", "functionsRegistry", "FunctionRegistry", "devServer", "startDevServer", "scheduler", "startScheduler", "waitForActiveTriggers", "space", "waitForCondition", "condition", "triggers", "getActiveTriggers", "length", "functionRegistry", "triggerRegistry", "TriggerRegistry", "Scheduler", "endpoint", "start", "stop", "server", "DevServer", "baseDir", "path", "join", "__dirname", "Filter", "performInvitation", "invariant", "Invitation", "triggerWebhook", "space", "uri", "trigger", "db", "query", "Filter", "schema", "FunctionTrigger", "t", "function", "run", "objects", "invariant", "spec", "type", "fetch", "port", "inviteMember", "host", "guest", "invitation", "hostInvitation", "Promise", "all", "performInvitation", "spaces", "state", "Invitation", "State", "SUCCESS", "Error", "testFunctionManifest", "functions", "uri", "route", "handler"]
7
7
  }