@dxos/functions 0.3.9-main.e6215fc → 0.3.9-main.ef334cd

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.
@@ -29,9 +29,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var node_exports = {};
30
30
  __export(node_exports, {
31
31
  DevServer: () => DevServer,
32
- Scheduler: () => Scheduler
32
+ Scheduler: () => Scheduler,
33
+ subscriptionHandler: () => subscriptionHandler
33
34
  });
34
35
  module.exports = __toCommonJS(node_exports);
36
+ var import_client = require("@dxos/client");
37
+ var import_echo_schema = require("@dxos/echo-schema");
38
+ var import_util = require("@dxos/util");
35
39
  var import_express = __toESM(require("express"));
36
40
  var import_get_port_please = require("get-port-please");
37
41
  var import_node_path = require("node:path");
@@ -42,10 +46,10 @@ var import_cron = require("cron");
42
46
  var import_async2 = require("@dxos/async");
43
47
  var import_echo = require("@dxos/client/echo");
44
48
  var import_context = require("@dxos/context");
45
- var import_echo_schema = require("@dxos/echo-schema");
49
+ var import_echo_schema2 = require("@dxos/echo-schema");
46
50
  var import_invariant2 = require("@dxos/invariant");
47
51
  var import_log2 = require("@dxos/log");
48
- var import_util = require("@dxos/util");
52
+ var import_util2 = require("@dxos/util");
49
53
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
50
54
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
51
55
  }) : x)(function(x) {
@@ -53,6 +57,21 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
53
57
  return require.apply(this, arguments);
54
58
  throw Error('Dynamic require of "' + x + '" is not supported');
55
59
  });
60
+ var subscriptionHandler = (handler) => {
61
+ return ({ event, context, ...rest }) => {
62
+ const { client } = context;
63
+ const space = event.space ? client.spaces.get(import_client.PublicKey.from(event.space)) : void 0;
64
+ const objects = space && event.objects?.map((id) => space.db.getObjectById(id)).filter(import_util.nonNullable).filter(import_echo_schema.isTypedObject);
65
+ return handler({
66
+ event: {
67
+ space,
68
+ objects
69
+ },
70
+ context,
71
+ ...rest
72
+ });
73
+ };
74
+ };
56
75
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
57
76
  var DevServer = class {
58
77
  // prettier-ignore
@@ -65,7 +84,7 @@ var DevServer = class {
65
84
  get endpoint() {
66
85
  (0, import_invariant.invariant)(this._port, void 0, {
67
86
  F: __dxlog_file,
68
- L: 45,
87
+ L: 46,
69
88
  S: this,
70
89
  A: [
71
90
  "this._port",
@@ -87,7 +106,7 @@ var DevServer = class {
87
106
  } catch (err) {
88
107
  import_log.log.error("parsing function (check manifest)", err, {
89
108
  F: __dxlog_file,
90
- L: 62,
109
+ L: 63,
91
110
  S: this,
92
111
  C: (f, a) => f(...a)
93
112
  });
@@ -109,7 +128,7 @@ var DevServer = class {
109
128
  } catch (err) {
110
129
  import_log.log.catch(err, void 0, {
111
130
  F: __dxlog_file,
112
- L: 82,
131
+ L: 83,
113
132
  S: this,
114
133
  C: (f, a) => f(...a)
115
134
  });
@@ -118,6 +137,7 @@ var DevServer = class {
118
137
  }
119
138
  });
120
139
  this._port = await (0, import_get_port_please.getPort)({
140
+ host: "localhost",
121
141
  port: 7200,
122
142
  portRange: [
123
143
  7200,
@@ -137,7 +157,7 @@ var DevServer = class {
137
157
  endpoint
138
158
  }, {
139
159
  F: __dxlog_file,
140
- L: 98,
160
+ L: 99,
141
161
  S: this,
142
162
  C: (f, a) => f(...a)
143
163
  });
@@ -159,7 +179,7 @@ var DevServer = class {
159
179
  registrationId: this._registrationId
160
180
  }, {
161
181
  F: __dxlog_file,
162
- L: 115,
182
+ L: 116,
163
183
  S: this,
164
184
  C: (f, a) => f(...a)
165
185
  });
@@ -182,7 +202,7 @@ var DevServer = class {
182
202
  id
183
203
  }, {
184
204
  F: __dxlog_file,
185
- L: 134,
205
+ L: 135,
186
206
  S: this,
187
207
  C: (f, a) => f(...a)
188
208
  });
@@ -209,13 +229,14 @@ var DevServer = class {
209
229
  name
210
230
  }, {
211
231
  F: __dxlog_file,
212
- L: 159,
232
+ L: 160,
213
233
  S: this,
214
234
  C: (f, a) => f(...a)
215
235
  });
216
236
  const { handler } = this._handlers[name];
217
237
  const context = {
218
- client: this._client
238
+ client: this._client,
239
+ dataDir: this._options.dataDir
219
240
  };
220
241
  let statusCode = 200;
221
242
  const response = {
@@ -236,7 +257,7 @@ var DevServer = class {
236
257
  duration: Date.now() - now
237
258
  }, {
238
259
  F: __dxlog_file,
239
- L: 175,
260
+ L: 177,
240
261
  S: this,
241
262
  C: (f, a) => f(...a)
242
263
  });
@@ -245,11 +266,11 @@ var DevServer = class {
245
266
  };
246
267
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/scheduler.ts";
247
268
  var Scheduler = class {
248
- constructor(_client, _manifest, _options) {
269
+ constructor(_client, _manifest, _options = {}) {
249
270
  this._client = _client;
250
271
  this._manifest = _manifest;
251
272
  this._options = _options;
252
- this._mounts = new import_util.ComplexMap(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);
273
+ this._mounts = new import_util2.ComplexMap(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);
253
274
  }
254
275
  async start() {
255
276
  this._client.spaces.subscribe(async (spaces) => {
@@ -274,7 +295,7 @@ var Scheduler = class {
274
295
  const def = this._manifest.functions.find((config) => config.id === trigger.function);
275
296
  (0, import_invariant2.invariant)(def, `Function not found: ${trigger.function}`, {
276
297
  F: __dxlog_file2,
277
- L: 59,
298
+ L: 63,
278
299
  S: this,
279
300
  A: [
280
301
  "def",
@@ -287,12 +308,12 @@ var Scheduler = class {
287
308
  ctx,
288
309
  trigger
289
310
  });
290
- import_log2.log.info("mount", {
311
+ (0, import_log2.log)("mount", {
291
312
  space: space.key,
292
313
  trigger
293
314
  }, {
294
315
  F: __dxlog_file2,
295
- L: 64,
316
+ L: 69,
296
317
  S: this,
297
318
  C: (f, a) => f(...a)
298
319
  });
@@ -300,63 +321,10 @@ var Scheduler = class {
300
321
  return;
301
322
  }
302
323
  if (trigger.schedule) {
303
- const task = new import_async2.DeferredTask(ctx, async () => {
304
- await this.execFunction(def, {
305
- space: space.key
306
- });
307
- });
308
- const job = new import_cron.CronJob(trigger.schedule, () => task.schedule());
309
- job.start();
310
- ctx.onDispose(() => job.stop());
324
+ this._createTimer(ctx, space, def, trigger);
311
325
  }
312
- if (trigger.subscription) {
313
- const objectIds = /* @__PURE__ */ new Set();
314
- const task = new import_async2.DeferredTask(ctx, async () => {
315
- await this.execFunction(def, {
316
- space: space.key,
317
- objects: Array.from(objectIds)
318
- });
319
- });
320
- const subscriptions = [];
321
- const subscription = (0, import_echo_schema.createSubscription)(({ added, updated }) => {
322
- for (const object of added) {
323
- objectIds.add(object.id);
324
- }
325
- for (const object of updated) {
326
- objectIds.add(object.id);
327
- }
328
- task.schedule();
329
- });
330
- subscriptions.push(() => subscription.unsubscribe());
331
- const { type, props, deep, delay } = trigger.subscription;
332
- const update = ({ objects }) => {
333
- subscription.update(objects);
334
- if (deep) {
335
- import_log2.log.info("update", {
336
- type,
337
- deep,
338
- objects: objects.length
339
- }, {
340
- F: __dxlog_file2,
341
- L: 114,
342
- S: this,
343
- C: (f, a) => f(...a)
344
- });
345
- for (const object of objects) {
346
- const content = object.content;
347
- if (content instanceof import_echo.TextObject) {
348
- subscriptions.push(content[import_echo_schema.subscribe]((0, import_async2.debounce)(() => subscription.update([
349
- object
350
- ]), 1e3)));
351
- }
352
- }
353
- }
354
- };
355
- const query = space.db.query(import_echo_schema.Filter.typename(type, props));
356
- subscriptions.push(query.subscribe(delay ? (0, import_async2.debounce)(update, delay * 1e3) : update));
357
- ctx.onDispose(() => {
358
- subscriptions.forEach((unsubscribe) => unsubscribe());
359
- });
326
+ for (const triggerSubscription of trigger.subscriptions ?? []) {
327
+ this._createSubscription(ctx, space, def, triggerSubscription);
360
328
  }
361
329
  }
362
330
  }
@@ -371,29 +339,104 @@ var Scheduler = class {
371
339
  await ctx.dispose();
372
340
  }
373
341
  }
374
- async execFunction(def, data) {
342
+ _createTimer(ctx, space, def, trigger) {
343
+ const task = new import_async2.DeferredTask(ctx, async () => {
344
+ await this._execFunction(def, {
345
+ space: space.key
346
+ });
347
+ });
348
+ (0, import_invariant2.invariant)(trigger.schedule, void 0, {
349
+ F: __dxlog_file2,
350
+ L: 103,
351
+ S: this,
352
+ A: [
353
+ "trigger.schedule",
354
+ ""
355
+ ]
356
+ });
357
+ const job = new import_cron.CronJob(trigger.schedule, () => task.schedule());
358
+ job.start();
359
+ ctx.onDispose(() => job.stop());
360
+ }
361
+ _createSubscription(ctx, space, def, triggerSubscription) {
362
+ const objectIds = /* @__PURE__ */ new Set();
363
+ const task = new import_async2.DeferredTask(ctx, async () => {
364
+ await this._execFunction(def, {
365
+ space: space.key,
366
+ objects: Array.from(objectIds)
367
+ });
368
+ });
369
+ const subscriptions = [];
370
+ const subscription = (0, import_echo_schema2.createSubscription)(({ added, updated }) => {
371
+ for (const object of added) {
372
+ objectIds.add(object.id);
373
+ }
374
+ for (const object of updated) {
375
+ objectIds.add(object.id);
376
+ }
377
+ task.schedule();
378
+ });
379
+ subscriptions.push(() => subscription.unsubscribe());
380
+ const { type, props, deep, delay } = triggerSubscription;
381
+ const update = ({ objects }) => {
382
+ subscription.update(objects);
383
+ if (deep) {
384
+ import_log2.log.info("update", {
385
+ type,
386
+ deep,
387
+ objects: objects.length
388
+ }, {
389
+ F: __dxlog_file2,
390
+ L: 139,
391
+ S: this,
392
+ C: (f, a) => f(...a)
393
+ });
394
+ for (const object of objects) {
395
+ const content = object.content;
396
+ if (content instanceof import_echo.TextObject) {
397
+ subscriptions.push(content[import_echo_schema2.subscribe]((0, import_async2.debounce)(() => subscription.update([
398
+ object
399
+ ]), 1e3)));
400
+ }
401
+ }
402
+ }
403
+ };
404
+ const query = space.db.query(import_echo_schema2.Filter.typename(type, props));
405
+ subscriptions.push(query.subscribe(delay ? (0, import_async2.debounce)(update, delay * 1e3) : update));
406
+ ctx.onDispose(() => {
407
+ subscriptions.forEach((unsubscribe) => unsubscribe());
408
+ });
409
+ }
410
+ async _execFunction(def, data) {
375
411
  try {
376
412
  (0, import_log2.log)("request", {
377
413
  function: def.id
378
414
  }, {
379
415
  F: __dxlog_file2,
380
- L: 147,
416
+ L: 161,
381
417
  S: this,
382
418
  C: (f, a) => f(...a)
383
419
  });
384
- const response = await fetch(`${this._options.endpoint}/${def.name}`, {
385
- method: "POST",
386
- headers: {
387
- "Content-Type": "application/json"
388
- },
389
- body: JSON.stringify(data)
390
- });
420
+ const { endpoint, callback } = this._options;
421
+ let status = 0;
422
+ if (endpoint) {
423
+ const response = await fetch(`${this._options.endpoint}/${def.name}`, {
424
+ method: "POST",
425
+ headers: {
426
+ "Content-Type": "application/json"
427
+ },
428
+ body: JSON.stringify(data)
429
+ });
430
+ status = response.status;
431
+ } else if (callback) {
432
+ status = await callback(data);
433
+ }
391
434
  (0, import_log2.log)("result", {
392
435
  function: def.id,
393
- result: response.status
436
+ result: status
394
437
  }, {
395
438
  F: __dxlog_file2,
396
- L: 157,
439
+ L: 180,
397
440
  S: this,
398
441
  C: (f, a) => f(...a)
399
442
  });
@@ -403,7 +446,7 @@ var Scheduler = class {
403
446
  error: err.message
404
447
  }, {
405
448
  F: __dxlog_file2,
406
- L: 159,
449
+ L: 182,
407
450
  S: this,
408
451
  C: (f, a) => f(...a)
409
452
  });
@@ -413,6 +456,7 @@ var Scheduler = class {
413
456
  // Annotate the CommonJS export names for ESM import in node:
414
457
  0 && (module.exports = {
415
458
  DevServer,
416
- Scheduler
459
+ Scheduler,
460
+ subscriptionHandler
417
461
  });
418
462
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts"],
4
- "sourcesContent": ["//\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 { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\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 _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\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 initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ 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 functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, TextObject } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription, type Query, subscribe } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../manifest';\n\ntype SchedulerOptions = {\n endpoint: string;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions,\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log.info('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Cron schedule.\n if (trigger.schedule) {\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n });\n });\n\n // TODO(burdon): Check greater than 30s min (use cron-parser).\n const job = new CronJob(trigger.schedule, () => task.schedule());\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n // ECHO subscription.\n if (trigger.subscription) {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n const { type, props, deep, delay } = trigger.subscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextObject) {\n subscriptions.push(content[subscribe](debounce(() => subscription.update([object]), 1_000)));\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private async execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n // const result = await response.json();\n log('result', { function: def.id, result: response.status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_async", "import_invariant", "import_log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "name", "params", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "info", "_registrationId", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "wait", "flush", "id", "handler", "path", "join", "directory", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "event", "seq", "now", "Date", "context", "client", "response", "status", "code", "duration", "Scheduler", "_manifest", "_mounts", "ComplexMap", "spaceKey", "toHex", "spaces", "subscribe", "space", "waitUntilReady", "triggers", "mount", "Context", "unmount", "ctx", "function", "find", "config", "exists", "get", "set", "disposed", "schedule", "task", "DeferredTask", "execFunction", "job", "CronJob", "onDispose", "subscription", "objectIds", "Set", "objects", "Array", "from", "subscriptions", "createSubscription", "added", "updated", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "length", "content", "TextObject", "debounce", "query", "db", "Filter", "typename", "delete", "dispose", "data", "fetch", "method", "headers", "JSON", "stringify", "result", "message"]
3
+ "sources": ["../../../src/handler.ts", "../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Client, PublicKey } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { isTypedObject, type TypedObject } from '@dxos/echo-schema';\nimport { nonNullable } from '@dxos/util';\n\n// TODO(burdon): No response?\nexport interface Response {\n status(code: number): Response;\n}\n\n// TODO(burdon): Limit access to individual space?\nexport interface FunctionContext {\n client: Client;\n dataDir?: string;\n}\n\n// TODO(burdon): Model after http request. Ref Lambda/OpenFaaS.\n// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html\nexport type FunctionHandler<T extends {}> = (params: {\n event: T;\n context: FunctionContext;\n response: Response;\n}) => Promise<Response | void>;\n\nexport type FunctionSubscriptionEvent = {\n space?: string; // TODO(burdon): Convert to PublicKey.\n objects?: string[];\n};\n\nexport type FunctionSubscriptionEvent2 = {\n space?: Space;\n objects?: TypedObject[];\n};\n\nexport const subscriptionHandler = (\n handler: FunctionHandler<FunctionSubscriptionEvent2>,\n): FunctionHandler<FunctionSubscriptionEvent> => {\n return ({ event, context, ...rest }) => {\n const { client } = context;\n const space = event.space ? client.spaces.get(PublicKey.from(event.space)) : undefined;\n const objects =\n space &&\n event.objects\n ?.map<TypedObject | undefined>((id) => space!.db.getObjectById(id))\n .filter(nonNullable)\n .filter(isTypedObject);\n\n return handler({ event: { space, objects }, context, ...rest });\n };\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 { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\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 _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\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 initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._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 functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, TextObject } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription, type Query, subscribe } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionSubscriptionEvent } from '../handler';\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger, type TriggerSubscription } from '../manifest';\n\ntype Callback = (data: FunctionSubscriptionEvent) => Promise<number>;\n\ntype SchedulerOptions = {\n endpoint?: string;\n callback?: Callback;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions = {},\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n // Currently supports only one trigger declaration per function.\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Timer.\n if (trigger.schedule) {\n this._createTimer(ctx, space, def, trigger);\n }\n\n // Subscription.\n for (const triggerSubscription of trigger.subscriptions ?? []) {\n this._createSubscription(ctx, space, def, triggerSubscription);\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private _createTimer(ctx: Context, space: Space, def: FunctionDef, trigger: FunctionTrigger) {\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, {\n space: space.key,\n });\n });\n\n // TODO(burdon): Check greater than 30s min (use cron-parser).\n invariant(trigger.schedule);\n const job = new CronJob(trigger.schedule, () => task.schedule());\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n private _createSubscription(ctx: Context, space: Space, def: FunctionDef, triggerSubscription: TriggerSubscription) {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n const { type, props, deep, delay } = triggerSubscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextObject) {\n subscriptions.push(content[subscribe](debounce(() => subscription.update([object]), 1_000)));\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n\n private async _execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const { endpoint, callback } = this._options;\n let status = 0;\n if (endpoint) {\n // TODO(burdon): Move out of scheduler (generalize as callback).\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n status = response.status;\n } else if (callback) {\n status = await callback(data);\n }\n\n // const result = await response.json();\n log('result', { function: def.id, result: status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,oBAAuC;AAEvC,yBAAgD;AAChD,kBAA4B;ACH5B,qBAAoB;AACpB,6BAAwB;AAExB,uBAAqB;AAErB,mBAAwB;AAExB,uBAA0B;AAC1B,iBAAoB;ACRpB,kBAAwB;AAExB,IAAAA,gBAAuC;AAEvC,kBAAuC;AACvC,qBAAwB;AACxB,IAAAC,sBAAkE;AAClE,IAAAC,oBAA0B;AAC1B,IAAAC,cAAoB;AACpB,IAAAC,eAA2B;;;;;;;;AFyBpB,IAAMC,sBAAsB,CACjCC,YAAAA;AAEA,SAAO,CAAC,EAAEC,OAAOC,SAAS,GAAGC,KAAAA,MAAM;AACjC,UAAM,EAAEC,OAAM,IAAKF;AACnB,UAAMG,QAAQJ,MAAMI,QAAQD,OAAOE,OAAOC,IAAIC,wBAAUC,KAAKR,MAAMI,KAAK,CAAA,IAAKK;AAC7E,UAAMC,UACJN,SACAJ,MAAMU,SACFC,IAA6B,CAACC,OAAOR,MAAOS,GAAGC,cAAcF,EAAAA,CAAAA,EAC9DG,OAAOC,uBAAAA,EACPD,OAAOE,gCAAAA;AAEZ,WAAOlB,QAAQ;MAAEC,OAAO;QAAEI;QAAOM;MAAQ;MAAGT;MAAS,GAAGC;IAAK,CAAA;EAC/D;AACF;;ACzBO,IAAMgB,YAAN,MAAMA;;EAWXC,YACmBC,SACAC,UACjB;mBAFiBD;oBACAC;SAXFC,YAAiF,CAAC;SAM3FC,OAAO;EAMZ;EAEH,IAAIC,WAAW;AACbC,oCAAU,KAAKC,OAAK,QAAA;;;;;;;;;AACpB,WAAO,oBAAoB,KAAKA,KAAK;EACvC;EAEA,IAAIC,QAAQ;AACV,WAAO,KAAKC;EACd;EAEA,IAAIC,YAAY;AACd,WAAOC,OAAOC,OAAO,KAAKT,SAAS;EACrC;EAEA,MAAMU,aAAa;AACjB,eAAWC,OAAO,KAAKZ,SAASa,SAASL,WAAW;AAClD,UAAI;AACF,cAAM,KAAKM,MAAMF,GAAAA;MACnB,SAASG,KAAK;AACZC,uBAAIC,MAAM,qCAAqCF,KAAAA;;;;;;MACjD;IACF;EACF;EAEA,MAAMG,QAAQ;AACZ,UAAMC,UAAMC,eAAAA,SAAAA;AACZD,QAAIE,IAAID,eAAAA,QAAQE,KAAI,CAAA;AAEpBH,QAAII,KAAK,UAAU,OAAOC,KAAKC,QAAAA;AAC7B,YAAM,EAAEC,KAAI,IAAKF,IAAIG;AACrB,UAAI;AACF,YAAI,KAAK3B,SAAS4B,QAAQ;AACxB,gBAAM,EAAEhB,IAAG,IAAK,KAAKX,UAAUyB,IAAAA;AAC/B,gBAAM,KAAKZ,MAAMF,KAAK,IAAA;QACxB;AAEAa,YAAII,aAAa,MAAM,KAAKC,QAAQJ,MAAMF,IAAIO,IAAI;AAClDN,YAAIO,IAAG;MACT,SAASjB,KAAU;AACjBC,uBAAIiB,MAAMlB,KAAAA,QAAAA;;;;;;AACVU,YAAII,aAAa;AACjBJ,YAAIO,IAAG;MACT;IACF,CAAA;AAEA,SAAK3B,QAAQ,UAAM6B,gCAAQ;MAAEC,MAAM;MAAaC,MAAM;MAAMC,WAAW;QAAC;QAAM;;IAAM,CAAA;AACpF,SAAKC,UAAUnB,IAAIoB,OAAO,KAAKlC,KAAK;AAEpC,QAAI;AAEF,YAAM,EAAEmC,gBAAgBrC,SAAQ,IAAK,MAAM,KAAKJ,QAAQ0C,SAASA,SAASC,wBAAyBC,SAAS;QAC1GxC,UAAU,KAAKA;QACfK,WAAW,KAAKA,UAAUlB,IAAI,CAAC,EAAEsB,KAAK,EAAEc,KAAI,EAAE,OAAQ;UAAEA;QAAK,EAAA;MAC/D,CAAA;AAEAV,qBAAI4B,KAAK,cAAc;QAAEJ;QAAgBrC;MAAS,GAAA;;;;;;AAClD,WAAK0C,kBAAkBL;AACvB,WAAKjC,SAASJ;IAChB,SAASY,KAAU;AACjB,YAAM,KAAK+B,KAAI;AACf,YAAM,IAAIC,MAAM,qEAAA;IAClB;EACF;EAEA,MAAMD,OAAO;AACX,UAAME,UAAU,IAAIC,qBAAAA;AACpB,SAAKX,SAASY,MAAM,YAAA;AAClB,UAAI,KAAKL,iBAAiB;AACxB,cAAM,KAAK9C,QAAQ0C,SAASA,SAASC,wBAAyBS,WAAW;UACvEX,gBAAgB,KAAKK;QACvB,CAAA;AAEA7B,uBAAI4B,KAAK,gBAAgB;UAAEJ,gBAAgB,KAAKK;QAAgB,GAAA;;;;;;AAChE,aAAKA,kBAAkBzD;AACvB,aAAKmB,SAASnB;MAChB;AAEA4D,cAAQI,KAAI;IACd,CAAA;AAEA,UAAMJ,QAAQK,KAAI;AAClB,SAAKhD,QAAQjB;AACb,SAAKkD,UAAUlD;EACjB;;;;EAKA,MAAc0B,MAAMF,KAAkB0C,QAAQ,OAAO;AACnD,UAAM,EAAE/D,IAAImC,MAAMhD,QAAO,IAAKkC;AAC9B,UAAM2C,WAAOC,uBAAK,KAAKxD,SAASyD,WAAW/E,OAAAA;AAC3CsC,mBAAI4B,KAAK,WAAW;MAAErD;IAAG,GAAA;;;;;;AAGzB,QAAI+D,OAAO;AACT7C,aAAOiD,KAAKC,UAAQC,KAAK,EACtBlE,OAAO,CAACmE,QAAQA,IAAIC,WAAWP,IAAAA,CAAAA,EAC/BQ,QAAQ,CAACF,QAAQ,OAAOF,UAAQC,MAAMC,GAAAA,CAAI;IAC/C;AAGA,UAAMG,UAASL,UAAQJ,IAAAA;AACvB,QAAI,OAAOS,QAAOC,YAAY,YAAY;AACxC,YAAM,IAAIlB,MAAM,yCAAyCxD,EAAAA,EAAI;IAC/D;AAEA,SAAKU,UAAUyB,IAAAA,IAAQ;MAAEd;MAAKlC,SAASsF,QAAOC;IAAQ;EACxD;;;;EAKA,MAAcnC,QAAQJ,MAAc/C,OAAY;AAC9C,UAAMuF,MAAM,EAAE,KAAKhE;AACnB,UAAMiE,MAAMC,KAAKD,IAAG;AAEpBnD,mBAAI4B,KAAK,OAAO;MAAEsB;MAAKxC;IAAK,GAAA;;;;;;AAC5B,UAAM,EAAEhD,QAAO,IAAK,KAAKuB,UAAUyB,IAAAA;AAEnC,UAAM9C,UAA2B;MAC/BE,QAAQ,KAAKiB;MACbsE,SAAS,KAAKrE,SAASqE;IACzB;AAEA,QAAIxC,aAAa;AACjB,UAAMyC,WAAqB;MACzBC,QAAQ,CAACC,SAAAA;AACP3C,qBAAa2C;AACb,eAAOF;MACT;IACF;AAEA,UAAM5F,QAAQ;MAAEE;MAASD;MAAO2F;IAAS,CAAA;AACzCtD,mBAAI4B,KAAK,OAAO;MAAEsB;MAAKxC;MAAMG;MAAY4C,UAAUL,KAAKD,IAAG,IAAKA;IAAI,GAAA;;;;;;AAEpE,WAAOtC;EACT;AACF;;ACvJO,IAAM6C,YAAN,MAAMA;EAOX5E,YACmBC,SACA4E,WACA3E,WAA6B,CAAC,GAC/C;mBAHiBD;qBACA4E;oBACA3E;SARF4E,UAAU,IAAIC,wBAG7B,CAAC,EAAEtF,IAAIuF,SAAQ,MAAO,GAAGA,SAASC,MAAK,CAAA,IAAMxF,EAAAA,EAAI;EAMhD;EAEH,MAAM2B,QAAQ;AACZ,SAAKnB,QAAQf,OAAOgG,UAAU,OAAOhG,WAAAA;AACnC,iBAAWD,SAASC,QAAQ;AAC1B,cAAMD,MAAMkG,eAAc;AAC1B,mBAAWjC,WAAW,KAAK2B,UAAUO,YAAY,CAAA,GAAI;AACnD,gBAAM,KAAKC,MAAM,IAAIC,uBAAAA,GAAWrG,OAAOiE,OAAAA;QACzC;MACF;IACF,CAAA;EACF;EAEA,MAAMF,OAAO;AACX,eAAW,EAAEvD,IAAIuF,SAAQ,KAAM,KAAKF,QAAQlB,KAAI,GAAI;AAClD,YAAM,KAAK2B,QAAQ9F,IAAIuF,QAAAA;IACzB;EACF;EAEA,MAAcK,MAAMG,KAAcvG,OAAciE,SAA0B;AACxE,UAAMa,MAAM;MAAEtE,IAAIyD,QAAQuC;MAAUT,UAAU/F,MAAM8E;IAAI;AACxD,UAAMjD,MAAM,KAAK+D,UAAUnE,UAAUgF,KAAK,CAACC,WAAWA,OAAOlG,OAAOyD,QAAQuC,QAAQ;AACpFnF,0BAAAA,WAAUQ,KAAK,uBAAuBoC,QAAQuC,QAAQ,IAAE;;;;;;;;;AAGxD,UAAMG,SAAS,KAAKd,QAAQ3F,IAAI4E,GAAAA;AAChC,QAAI,CAAC6B,QAAQ;AACX,WAAKd,QAAQe,IAAI9B,KAAK;QAAEyB;QAAKtC;MAAQ,CAAA;AACrChC,sBAAAA,KAAI,SAAS;QAAEjC,OAAOA,MAAM8E;QAAKb;MAAQ,GAAA;;;;;;AACzC,UAAIsC,IAAIM,UAAU;AAChB;MACF;AAGA,UAAI5C,QAAQ6C,UAAU;AACpB,aAAKC,aAAaR,KAAKvG,OAAO6B,KAAKoC,OAAAA;MACrC;AAGA,iBAAW+C,uBAAuB/C,QAAQgD,iBAAiB,CAAA,GAAI;AAC7D,aAAKC,oBAAoBX,KAAKvG,OAAO6B,KAAKmF,mBAAAA;MAC5C;IACF;EACF;EAEA,MAAcV,QAAQ9F,IAAYuF,UAAqB;AACrD,UAAMjB,MAAM;MAAEtE;MAAIuF;IAAS;AAC3B,UAAM,EAAEQ,IAAG,IAAK,KAAKV,QAAQ3F,IAAI4E,GAAAA,KAAQ,CAAC;AAC1C,QAAIyB,KAAK;AACP,WAAKV,QAAQsB,OAAOrC,GAAAA;AACpB,YAAMyB,IAAIa,QAAO;IACnB;EACF;EAEQL,aAAaR,KAAcvG,OAAc6B,KAAkBoC,SAA0B;AAC3F,UAAMoD,OAAO,IAAIC,2BAAaf,KAAK,YAAA;AACjC,YAAM,KAAKgB,cAAc1F,KAAK;QAC5B7B,OAAOA,MAAM8E;MACf,CAAA;IACF,CAAA;AAGAzD,0BAAAA,WAAU4C,QAAQ6C,UAAQ,QAAA;;;;;;;;;AAC1B,UAAMU,MAAM,IAAIC,oBAAQxD,QAAQ6C,UAAU,MAAMO,KAAKP,SAAQ,CAAA;AAE7DU,QAAIrF,MAAK;AACToE,QAAImB,UAAU,MAAMF,IAAIzD,KAAI,CAAA;EAC9B;EAEQmD,oBAAoBX,KAAcvG,OAAc6B,KAAkBmF,qBAA0C;AAClH,UAAMW,YAAY,oBAAIC,IAAAA;AACtB,UAAMP,OAAO,IAAIC,2BAAaf,KAAK,YAAA;AACjC,YAAM,KAAKgB,cAAc1F,KAAK;QAC5B7B,OAAOA,MAAM8E;QACbxE,SAASuH,MAAMzH,KAAKuH,SAAAA;MACtB,CAAA;IACF,CAAA;AAGA,UAAMV,gBAAgC,CAAA;AACtC,UAAMa,mBAAeC,wCAAmB,CAAC,EAAEC,OAAOC,QAAO,MAAE;AACzD,iBAAWC,UAAUF,OAAO;AAC1BL,kBAAUQ,IAAID,OAAO1H,EAAE;MACzB;AACA,iBAAW0H,UAAUD,SAAS;AAC5BN,kBAAUQ,IAAID,OAAO1H,EAAE;MACzB;AAEA6G,WAAKP,SAAQ;IACf,CAAA;AACAG,kBAAcmB,KAAK,MAAMN,aAAaO,YAAW,CAAA;AAEjD,UAAM,EAAEC,MAAMC,OAAOC,MAAMC,MAAK,IAAKzB;AACrC,UAAM0B,SAAS,CAAC,EAAEpI,QAAO,MAAS;AAChCwH,mBAAaY,OAAOpI,OAAAA;AAGpB,UAAIkI,MAAM;AACRvG,oBAAAA,IAAI4B,KAAK,UAAU;UAAEyE;UAAME;UAAMlI,SAASA,QAAQqI;QAAO,GAAA;;;;;;AACzD,mBAAWT,UAAU5H,SAAS;AAC5B,gBAAMsI,UAAUV,OAAOU;AACvB,cAAIA,mBAAmBC,wBAAY;AACjC5B,0BAAcmB,KAAKQ,QAAQ3C,6BAAAA,MAAW6C,wBAAS,MAAMhB,aAAaY,OAAO;cAACR;aAAO,GAAG,GAAA,CAAA,CAAA;UACtF;QACF;MACF;IACF;AAIA,UAAMa,QAAQ/I,MAAMS,GAAGsI,MAAMC,2BAAOC,SAASX,MAAMC,KAAAA,CAAAA;AACnDtB,kBAAcmB,KAAKW,MAAM9C,UAAUwC,YAAQK,wBAASJ,QAAQD,QAAQ,GAAA,IAASC,MAAAA,CAAAA;AAE7EnC,QAAImB,UAAU,MAAA;AACZT,oBAAcjC,QAAQ,CAACqD,gBAAgBA,YAAAA,CAAAA;IACzC,CAAA;EACF;EAEA,MAAcd,cAAc1F,KAAkBqH,MAAW;AACvD,QAAI;AACFjH,sBAAAA,KAAI,WAAW;QAAEuE,UAAU3E,IAAIrB;MAAG,GAAA;;;;;;AAClC,YAAM,EAAEY,UAAU+H,SAAQ,IAAK,KAAKlI;AACpC,UAAIuE,SAAS;AACb,UAAIpE,UAAU;AAEZ,cAAMmE,WAAW,MAAM6D,MAAM,GAAG,KAAKnI,SAASG,QAAQ,IAAIS,IAAIc,IAAI,IAAI;UACpE0G,QAAQ;UACRC,SAAS;YACP,gBAAgB;UAClB;UACAtG,MAAMuG,KAAKC,UAAUN,IAAAA;QACvB,CAAA;AAEA1D,iBAASD,SAASC;MACpB,WAAW2D,UAAU;AACnB3D,iBAAS,MAAM2D,SAASD,IAAAA;MAC1B;AAGAjH,sBAAAA,KAAI,UAAU;QAAEuE,UAAU3E,IAAIrB;QAAIiJ,QAAQjE;MAAO,GAAA;;;;;;IACnD,SAASxD,KAAU;AACjBC,kBAAAA,IAAIC,MAAM,SAAS;QAAEsE,UAAU3E,IAAIrB;QAAI0B,OAAOF,IAAI0H;MAAQ,GAAA;;;;;;IAC5D;EACF;AACF;",
6
+ "names": ["import_async", "import_echo_schema", "import_invariant", "import_log", "import_util", "subscriptionHandler", "handler", "event", "context", "rest", "client", "space", "spaces", "get", "PublicKey", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "nonNullable", "isTypedObject", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "name", "params", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "info", "_registrationId", "stop", "Error", "trigger", "Trigger", "close", "unregister", "wake", "wait", "flush", "path", "join", "directory", "keys", "require", "cache", "key", "startsWith", "forEach", "module", "default", "seq", "now", "Date", "dataDir", "response", "status", "code", "duration", "Scheduler", "_manifest", "_mounts", "ComplexMap", "spaceKey", "toHex", "subscribe", "waitUntilReady", "triggers", "mount", "Context", "unmount", "ctx", "function", "find", "config", "exists", "set", "disposed", "schedule", "_createTimer", "triggerSubscription", "subscriptions", "_createSubscription", "delete", "dispose", "task", "DeferredTask", "_execFunction", "job", "CronJob", "onDispose", "objectIds", "Set", "Array", "subscription", "createSubscription", "added", "updated", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "length", "content", "TextObject", "debounce", "query", "Filter", "typename", "data", "callback", "fetch", "method", "headers", "JSON", "stringify", "result", "message"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":1313,"imports":[],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1795,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":18569,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":20325,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":637,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/manifest.ts","kind":"import-statement","original":"./manifest"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18177},"packages/core/functions/dist/lib/node/index.cjs":{"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["DevServer","Scheduler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4729},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":5045}},"bytes":10322}}}
1
+ {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":4072,"imports":[{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1863,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":18840,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":22471,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":637,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/manifest.ts","kind":"import-statement","original":"./manifest"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":21909},"packages/core/functions/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["DevServer","Scheduler","subscriptionHandler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/handler.ts":{"bytesInOutput":589},"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4792},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":5475}},"bytes":11470}}}
@@ -1,9 +1,12 @@
1
1
  import { type Client } from '@dxos/client';
2
+ import { type Space } from '@dxos/client/echo';
3
+ import { type TypedObject } from '@dxos/echo-schema';
2
4
  export interface Response {
3
5
  status(code: number): Response;
4
6
  }
5
7
  export interface FunctionContext {
6
8
  client: Client;
9
+ dataDir?: string;
7
10
  }
8
11
  export type FunctionHandler<T extends {}> = (params: {
9
12
  event: T;
@@ -11,7 +14,12 @@ export type FunctionHandler<T extends {}> = (params: {
11
14
  response: Response;
12
15
  }) => Promise<Response | void>;
13
16
  export type FunctionSubscriptionEvent = {
14
- space: string;
15
- objects: string[];
17
+ space?: string;
18
+ objects?: string[];
16
19
  };
20
+ export type FunctionSubscriptionEvent2 = {
21
+ space?: Space;
22
+ objects?: TypedObject[];
23
+ };
24
+ export declare const subscriptionHandler: (handler: FunctionHandler<FunctionSubscriptionEvent2>) => FunctionHandler<FunctionSubscriptionEvent>;
17
25
  //# sourceMappingURL=handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/handler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC;AAGD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAE/B,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/handler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAa,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIpE,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC;AAGD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAE/B,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,YACrB,gBAAgB,0BAA0B,CAAC,KACnD,gBAAgB,yBAAyB,CAa3C,CAAC"}
@@ -14,7 +14,7 @@ export type TriggerSubscription = {
14
14
  export type FunctionTrigger = {
15
15
  function: string;
16
16
  schedule?: string;
17
- subscription?: TriggerSubscription;
17
+ subscriptions?: TriggerSubscription[];
18
18
  };
19
19
  /**
20
20
  * Function manifest file.
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/manifest.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,WAAW,GAAG;IAExB,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/manifest.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,WAAW,GAAG;IAExB,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACvC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC"}
@@ -6,6 +6,7 @@ export type DevServerOptions = {
6
6
  directory: string;
7
7
  manifest: FunctionManifest;
8
8
  reload?: boolean;
9
+ dataDir?: string;
9
10
  };
10
11
  /**
11
12
  * Functions dev server provides a local HTTP server for testing functions.
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/dev-server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EAAwB,KAAK,eAAe,EAAiB,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IAYlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2E;IAErG,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAK;gBAIE,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,gBAAgB;IAG7C,IAAI,QAAQ,WAGX;IAED,IAAI,KAAK,uBAER;IAED,IAAI,SAAS;;;QAEZ;IAEK,UAAU;IAUV,KAAK;IAwCL,IAAI;IAqBV;;OAEG;YACW,KAAK;IAqBnB;;OAEG;YACW,OAAO;CAwBtB"}
1
+ {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/dev-server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EAAwB,KAAK,eAAe,EAAiB,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IAYlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2E;IAErG,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAK;gBAIE,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,gBAAgB;IAG7C,IAAI,QAAQ,WAGX;IAED,IAAI,KAAK,uBAER;IAED,IAAI,SAAS;;;QAEZ;IAEK,UAAU;IAUV,KAAK;IAwCL,IAAI;IAqBV;;OAEG;YACW,KAAK;IAqBnB;;OAEG;YACW,OAAO;CAyBtB"}
@@ -1,7 +1,10 @@
1
1
  import { type Client } from '@dxos/client';
2
+ import { type FunctionSubscriptionEvent } from '../handler';
2
3
  import { type FunctionManifest } from '../manifest';
4
+ type Callback = (data: FunctionSubscriptionEvent) => Promise<number>;
3
5
  type SchedulerOptions = {
4
- endpoint: string;
6
+ endpoint?: string;
7
+ callback?: Callback;
5
8
  };
6
9
  /**
7
10
  * Functions scheduler.
@@ -11,12 +14,14 @@ export declare class Scheduler {
11
14
  private readonly _manifest;
12
15
  private readonly _options;
13
16
  private readonly _mounts;
14
- constructor(_client: Client, _manifest: FunctionManifest, _options: SchedulerOptions);
17
+ constructor(_client: Client, _manifest: FunctionManifest, _options?: SchedulerOptions);
15
18
  start(): Promise<void>;
16
19
  stop(): Promise<void>;
17
20
  private mount;
18
21
  private unmount;
19
- private execFunction;
22
+ private _createTimer;
23
+ private _createSubscription;
24
+ private _execFunction;
20
25
  }
21
26
  export {};
22
27
  //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../../src/runtime/scheduler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,MAAM,EAAkB,MAAM,cAAc,CAAC;AAQ3D,OAAO,EAAoB,KAAK,gBAAgB,EAAwB,MAAM,aAAa,CAAC;AAE5F,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;GAEG;AAEH,qBAAa,SAAS;IAQlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAG6B;gBAGlC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,gBAAgB;IAGvC,KAAK;IAWL,IAAI;YAMI,KAAK;YAgFL,OAAO;YASP,YAAY;CAiB3B"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../../src/runtime/scheduler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,MAAM,EAAkB,MAAM,cAAc,CAAC;AAQ3D,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAoB,KAAK,gBAAgB,EAAkD,MAAM,aAAa,CAAC;AAEtH,KAAK,QAAQ,GAAG,CAAC,IAAI,EAAE,yBAAyB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAErE,KAAK,gBAAgB,GAAG;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF;;GAEG;AAEH,qBAAa,SAAS;IAQlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAG6B;gBAGlC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,GAAE,gBAAqB;IAG5C,KAAK;IAWL,IAAI;YAMI,KAAK;YA0BL,OAAO;IASrB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,mBAAmB;YAiDb,aAAa;CA0B5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scheduler.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime/scheduler.test.ts"],"names":[],"mappings":""}