@dxos/functions 0.5.3-main.5a4243f → 0.5.3-main.f752aaa

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,7 +29,7 @@ var subscriptionHandler = (handler) => {
29
29
  event
30
30
  }, {
31
31
  F: __dxlog_file,
32
- L: 61,
32
+ L: 68,
33
33
  S: void 0,
34
34
  C: (f, a) => f(...a)
35
35
  });
@@ -39,7 +39,7 @@ var subscriptionHandler = (handler) => {
39
39
  objects: objects?.length
40
40
  }, {
41
41
  F: __dxlog_file,
42
- L: 63,
42
+ L: 70,
43
43
  S: void 0,
44
44
  C: (f, a) => f(...a)
45
45
  });
@@ -265,9 +265,11 @@ var DevServer = class {
265
265
 
266
266
  // packages/core/functions/src/runtime/scheduler.ts
267
267
  import { CronJob } from "cron";
268
+ import http from "@dxos/node-std/http";
269
+ import WebSocket from "ws";
268
270
  import { TextV0Type } from "@braneframe/types";
269
- import { debounce, DeferredTask } from "@dxos/async";
270
- import { Filter, createSubscription, getAutomergeObjectCore } from "@dxos/client/echo";
271
+ import { debounce, DeferredTask, sleep, Trigger as Trigger2 } from "@dxos/async";
272
+ import { createSubscription, Filter, getAutomergeObjectCore } from "@dxos/client/echo";
271
273
  import { Context } from "@dxos/context";
272
274
  import { invariant as invariant2 } from "@dxos/invariant";
273
275
  import { log as log3 } from "@dxos/log";
@@ -303,7 +305,7 @@ var Scheduler = class {
303
305
  const def = this._manifest.functions.find((config) => config.id === trigger.function);
304
306
  invariant2(def, `Function not found: ${trigger.function}`, {
305
307
  F: __dxlog_file3,
306
- L: 63,
308
+ L: 72,
307
309
  S: this,
308
310
  A: [
309
311
  "def",
@@ -321,18 +323,24 @@ var Scheduler = class {
321
323
  trigger
322
324
  }, {
323
325
  F: __dxlog_file3,
324
- L: 69,
326
+ L: 78,
325
327
  S: this,
326
328
  C: (f, a) => f(...a)
327
329
  });
328
330
  if (ctx.disposed) {
329
331
  return;
330
332
  }
331
- if (trigger.schedule) {
332
- this._createTimer(ctx, space, def, trigger);
333
+ if (trigger.timer) {
334
+ await this._createTimer(ctx, space, def, trigger.timer);
333
335
  }
334
- for (const triggerSubscription of trigger.subscriptions ?? []) {
335
- this._createSubscription(ctx, space, def, triggerSubscription);
336
+ if (trigger.webhook) {
337
+ await this._createWebhook(ctx, space, def, trigger.webhook);
338
+ }
339
+ if (trigger.websocket) {
340
+ await this._createWebsocket(ctx, space, def, trigger.websocket);
341
+ }
342
+ if (trigger.subscription) {
343
+ await this._createSubscription(ctx, space, def, trigger.subscription);
336
344
  }
337
345
  }
338
346
  }
@@ -347,25 +355,75 @@ var Scheduler = class {
347
355
  await ctx.dispose();
348
356
  }
349
357
  }
350
- _createTimer(ctx, space, def, trigger) {
358
+ // TODO(burdon): Pass in Space key (common context).
359
+ async _execFunction(def, data) {
360
+ try {
361
+ log3.info("exec", {
362
+ function: def.id
363
+ }, {
364
+ F: __dxlog_file3,
365
+ L: 117,
366
+ S: this,
367
+ C: (f, a) => f(...a)
368
+ });
369
+ const { endpoint, callback } = this._options;
370
+ if (endpoint) {
371
+ await fetch(`${this._options.endpoint}/${def.name}`, {
372
+ method: "POST",
373
+ headers: {
374
+ "Content-Type": "application/json"
375
+ },
376
+ body: JSON.stringify(data)
377
+ });
378
+ } else if (callback) {
379
+ await callback(data);
380
+ }
381
+ log3.info("done", {
382
+ function: def.id
383
+ }, {
384
+ F: __dxlog_file3,
385
+ L: 133,
386
+ S: this,
387
+ C: (f, a) => f(...a)
388
+ });
389
+ } catch (err) {
390
+ log3.error("error", {
391
+ function: def.id,
392
+ error: err.message
393
+ }, {
394
+ F: __dxlog_file3,
395
+ L: 135,
396
+ S: this,
397
+ C: (f, a) => f(...a)
398
+ });
399
+ }
400
+ }
401
+ //
402
+ // Triggers
403
+ //
404
+ /**
405
+ * Cron timer.
406
+ */
407
+ async _createTimer(ctx, space, def, trigger) {
408
+ log3.info("timer", {
409
+ space: space.key,
410
+ trigger
411
+ }, {
412
+ F: __dxlog_file3,
413
+ L: 147,
414
+ S: this,
415
+ C: (f, a) => f(...a)
416
+ });
417
+ const { cron } = trigger;
351
418
  const task = new DeferredTask(ctx, async () => {
352
419
  await this._execFunction(def, {
353
420
  space: space.key
354
421
  });
355
422
  });
356
- invariant2(trigger.schedule, void 0, {
357
- F: __dxlog_file3,
358
- L: 102,
359
- S: this,
360
- A: [
361
- "trigger.schedule",
362
- ""
363
- ]
364
- });
365
423
  let last = 0;
366
424
  let run = 0;
367
425
  const job = CronJob.from({
368
- cronTime: trigger.schedule,
426
+ cronTime: cron,
369
427
  runOnInit: false,
370
428
  onTick: () => {
371
429
  const now = Date.now();
@@ -378,7 +436,7 @@ var Scheduler = class {
378
436
  delta
379
437
  }, {
380
438
  F: __dxlog_file3,
381
- L: 116,
439
+ L: 167,
382
440
  S: this,
383
441
  C: (f, a) => f(...a)
384
442
  });
@@ -388,13 +446,147 @@ var Scheduler = class {
388
446
  job.start();
389
447
  ctx.onDispose(() => job.stop());
390
448
  }
391
- _createSubscription(ctx, space, def, triggerSubscription) {
449
+ /**
450
+ * Webhook.
451
+ */
452
+ async _createWebhook(ctx, space, def, trigger) {
453
+ log3.info("webhook", {
454
+ space: space.key,
455
+ trigger
456
+ }, {
457
+ F: __dxlog_file3,
458
+ L: 180,
459
+ S: this,
460
+ C: (f, a) => f(...a)
461
+ });
462
+ const { port } = trigger;
463
+ const server = http.createServer(async (req, res) => {
464
+ await this._execFunction(def, {
465
+ space: space.key
466
+ });
467
+ });
468
+ server.listen(port, () => {
469
+ log3.info("started webhook", {
470
+ port
471
+ }, {
472
+ F: __dxlog_file3,
473
+ L: 189,
474
+ S: this,
475
+ C: (f, a) => f(...a)
476
+ });
477
+ });
478
+ ctx.onDispose(() => {
479
+ server.close();
480
+ });
481
+ }
482
+ /**
483
+ * Websocket.
484
+ */
485
+ async _createWebsocket(ctx, space, def, trigger, options = {
486
+ retryDelay: 2,
487
+ maxAttempts: 5
488
+ }) {
489
+ log3.info("websocket", {
490
+ space: space.key,
491
+ trigger
492
+ }, {
493
+ F: __dxlog_file3,
494
+ L: 213,
495
+ S: this,
496
+ C: (f, a) => f(...a)
497
+ });
498
+ const { url } = trigger;
499
+ let ws;
500
+ for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
501
+ const open = new Trigger2();
502
+ ws = new WebSocket(url);
503
+ Object.assign(ws, {
504
+ onopen: () => {
505
+ log3.info("opened", {
506
+ url
507
+ }, {
508
+ F: __dxlog_file3,
509
+ L: 223,
510
+ S: this,
511
+ C: (f, a) => f(...a)
512
+ });
513
+ if (trigger.init) {
514
+ ws.send(new TextEncoder().encode(JSON.stringify(trigger.init)));
515
+ }
516
+ open.wake(true);
517
+ },
518
+ onclose: () => {
519
+ log3.info("closed", {
520
+ url
521
+ }, {
522
+ F: __dxlog_file3,
523
+ L: 232,
524
+ S: this,
525
+ C: (f, a) => f(...a)
526
+ });
527
+ open.wake(false);
528
+ },
529
+ onerror: (event) => {
530
+ log3.catch(event.error, {
531
+ url
532
+ }, {
533
+ F: __dxlog_file3,
534
+ L: 237,
535
+ S: this,
536
+ C: (f, a) => f(...a)
537
+ });
538
+ },
539
+ onmessage: async (event) => {
540
+ try {
541
+ const data = JSON.parse(new TextDecoder().decode(event.data));
542
+ await this._execFunction(def, {
543
+ space: space.key,
544
+ data
545
+ });
546
+ } catch (err) {
547
+ log3.catch(err, {
548
+ url
549
+ }, {
550
+ F: __dxlog_file3,
551
+ L: 245,
552
+ S: this,
553
+ C: (f, a) => f(...a)
554
+ });
555
+ }
556
+ }
557
+ });
558
+ const isOpen = await open.wait();
559
+ if (isOpen) {
560
+ break;
561
+ } else {
562
+ const wait = Math.pow(attempt, 2) * options.retryDelay;
563
+ if (attempt < options.maxAttempts) {
564
+ log3.warn(`failed to connect; trying again in ${wait}s`, {
565
+ attempt
566
+ }, {
567
+ F: __dxlog_file3,
568
+ L: 256,
569
+ S: this,
570
+ C: (f, a) => f(...a)
571
+ });
572
+ await sleep(wait * 1e3);
573
+ }
574
+ }
575
+ }
576
+ ctx.onDispose(() => {
577
+ ws?.close();
578
+ });
579
+ }
580
+ /**
581
+ * ECHO subscription.
582
+ */
583
+ async _createSubscription(ctx, space, def, trigger) {
392
584
  log3.info("subscription", {
393
585
  space: space.key,
394
- triggerSubscription
586
+ trigger
395
587
  }, {
396
588
  F: __dxlog_file3,
397
- L: 126,
589
+ L: 271,
398
590
  S: this,
399
591
  C: (f, a) => f(...a)
400
592
  });
@@ -412,7 +604,7 @@ var Scheduler = class {
412
604
  updated: updated.length
413
605
  }, {
414
606
  F: __dxlog_file3,
415
- L: 139,
607
+ L: 281,
416
608
  S: this,
417
609
  C: (f, a) => f(...a)
418
610
  });
@@ -425,17 +617,15 @@ var Scheduler = class {
425
617
  task.schedule();
426
618
  });
427
619
  subscriptions.push(() => subscription.unsubscribe());
428
- const { type, props, deep, delay } = triggerSubscription;
620
+ const { filter, options: { deep, delay } = {} } = trigger;
429
621
  const update = ({ objects }) => {
430
622
  subscription.update(objects);
431
623
  if (deep) {
432
624
  log3.info("update", {
433
- type,
434
- deep,
435
625
  objects: objects.length
436
626
  }, {
437
627
  F: __dxlog_file3,
438
- L: 159,
628
+ L: 301,
439
629
  S: this,
440
630
  C: (f, a) => f(...a)
441
631
  });
@@ -449,60 +639,61 @@ var Scheduler = class {
449
639
  }
450
640
  }
451
641
  };
452
- const query = space.db.query(Filter.typename(type, props));
453
- subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1e3) : update));
642
+ const query = space.db.query(Filter.or(filter.map(({ type, props }) => Filter.typename(type, props))));
643
+ subscriptions.push(query.subscribe(delay ? debounce(update, delay) : update));
454
644
  ctx.onDispose(() => {
455
645
  subscriptions.forEach((unsubscribe) => unsubscribe());
456
646
  });
457
647
  }
458
- async _execFunction(def, data) {
459
- try {
460
- log3("request", {
461
- function: def.id
462
- }, {
463
- F: __dxlog_file3,
464
- L: 183,
465
- S: this,
466
- C: (f, a) => f(...a)
467
- });
468
- const { endpoint, callback } = this._options;
469
- let status = 0;
470
- if (endpoint) {
471
- const response = await fetch(`${this._options.endpoint}/${def.name}`, {
472
- method: "POST",
473
- headers: {
474
- "Content-Type": "application/json"
475
- },
476
- body: JSON.stringify(data)
477
- });
478
- status = response.status;
479
- } else if (callback) {
480
- status = await callback(data);
481
- }
482
- log3("result", {
483
- function: def.id,
484
- result: status
485
- }, {
486
- F: __dxlog_file3,
487
- L: 202,
488
- S: this,
489
- C: (f, a) => f(...a)
490
- });
491
- } catch (err) {
492
- log3.error("error", {
493
- function: def.id,
494
- error: err.message
495
- }, {
496
- F: __dxlog_file3,
497
- L: 204,
498
- S: this,
499
- C: (f, a) => f(...a)
500
- });
501
- }
502
- }
503
648
  };
649
+
650
+ // packages/core/functions/src/types.ts
651
+ import * as S from "@effect/schema/Schema";
652
+ var TimerTriggerSchema = S.struct({
653
+ cron: S.string
654
+ });
655
+ var WebhookTriggerSchema = S.struct({
656
+ port: S.number
657
+ });
658
+ var WebsocketTriggerSchema = S.struct({
659
+ url: S.string,
660
+ init: S.optional(S.record(S.string, S.any))
661
+ });
662
+ var SubscriptionTriggerSchema = S.struct({
663
+ spaceKey: S.optional(S.string),
664
+ // TODO(burdon): Define query DSL.
665
+ filter: S.array(S.struct({
666
+ type: S.string,
667
+ props: S.optional(S.record(S.string, S.any))
668
+ })),
669
+ options: S.optional(S.struct({
670
+ // Watch changes to object (not just creation).
671
+ deep: S.optional(S.boolean),
672
+ // Debounce changes (delay in ms).
673
+ delay: S.optional(S.number)
674
+ }))
675
+ });
676
+ var FunctionTriggerSchema = S.struct({
677
+ function: S.string.pipe(S.description("Function ID/URI.")),
678
+ timer: S.optional(TimerTriggerSchema),
679
+ webhook: S.optional(WebhookTriggerSchema),
680
+ websocket: S.optional(WebsocketTriggerSchema),
681
+ subscription: S.optional(SubscriptionTriggerSchema)
682
+ });
683
+ var FunctionDefSchema = S.struct({
684
+ id: S.string,
685
+ description: S.optional(S.string),
686
+ name: S.string,
687
+ // TODO(burdon): NPM/GitHub URL?
688
+ handler: S.string
689
+ });
690
+ var FunctionManifestSchema = S.struct({
691
+ functions: S.mutable(S.array(FunctionDefSchema)),
692
+ triggers: S.mutable(S.array(FunctionTriggerSchema))
693
+ });
504
694
  export {
505
695
  DevServer,
696
+ FunctionManifestSchema,
506
697
  Scheduler,
507
698
  subscriptionHandler
508
699
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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 { type EchoReactiveObject } from '@dxos/echo-schema';\nimport { log } from '@dxos/log';\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?: EchoReactiveObject<any>[];\n};\n\n/**\n * Handler wrapper for subscription events; extracts space and objects.\n *\n * To test:\n * ```\n * curl -s -X POST -H \"Content-Type: application/json\" --data '{\"space\": \"0446...1cbb\"}' http://localhost:7100/dev/email-extractor\n * ```\n *\n * NOTE: Get space key from devtools or `dx space list --json`\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?.map<EchoReactiveObject<any> | undefined>((id) => space!.db.getObjectById(id)).filter(nonNullable);\n\n if (!!event.space && !space) {\n log.warn('invalid space', { event });\n } else {\n log.info('handler', { space: space?.key.truncate(), objects: objects?.length });\n }\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 log.info('calling', { name });\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 { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, Filter, createSubscription, type Query, getAutomergeObjectCore } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\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 invariant(trigger.schedule);\n let last = 0;\n let run = 0;\n // https://www.npmjs.com/package/cron#constructor\n const job = CronJob.from({\n cronTime: trigger.schedule,\n runOnInit: false,\n onTick: () => {\n // TODO(burdon): Check greater than 30s (use cron-parser).\n const now = Date.now();\n const delta = last ? now - last : 0;\n last = now;\n\n run++;\n log.info('tick', { space: space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n private _createSubscription(ctx: Context, space: Space, def: FunctionDef, triggerSubscription: TriggerSubscription) {\n log.info('subscription', { space: space.key, 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): Don't fire initially.\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n log.info('updated', { added: added.length, updated: updated.length });\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 // TODO(burdon): Create queue. Only allow one invocation per trigger at a time?\n // TODO(burdon): Disable trigger if keeps failing.\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 TextV0Type) {\n subscriptions.push(\n getAutomergeObjectCore(content).updates.on(debounce(() => subscription.update([object]), 1_000)),\n );\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": "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",
6
- "names": ["PublicKey", "log", "nonNullable", "subscriptionHandler", "handler", "event", "context", "rest", "client", "space", "spaces", "get", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "warn", "info", "key", "truncate", "length", "express", "getPort", "join", "Trigger", "invariant", "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", "info", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "_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", "dataDir", "response", "status", "code", "duration", "CronJob", "TextV0Type", "debounce", "DeferredTask", "Filter", "createSubscription", "getAutomergeObjectCore", "Context", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "id", "spaceKey", "toHex", "start", "spaces", "subscribe", "space", "waitUntilReady", "trigger", "triggers", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "def", "functions", "find", "config", "exists", "get", "set", "disposed", "schedule", "_createTimer", "triggerSubscription", "subscriptions", "_createSubscription", "delete", "dispose", "task", "_execFunction", "last", "run", "job", "from", "cronTime", "runOnInit", "onTick", "now", "Date", "delta", "info", "truncate", "count", "onDispose", "objectIds", "Set", "objects", "Array", "subscription", "added", "updated", "length", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "content", "updates", "on", "query", "db", "typename", "forEach", "data", "endpoint", "callback", "status", "response", "fetch", "name", "method", "headers", "body", "JSON", "stringify", "result", "err", "error", "message"]
3
+ "sources": ["../../../src/handler.ts", "../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts", "../../../src/types.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 { type EchoReactiveObject } from '@dxos/echo-schema';\nimport { log } from '@dxos/log';\nimport { nonNullable } from '@dxos/util';\n\n// TODO(burdon): Context?\n// Lambda-like function definitions.\n// See: https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml/#functions\n// https://www.npmjs.com/package/aws-lambda\n// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html\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\n// TODO(burdon): ???\nexport type FunctionSubscriptionEvent2 = {\n space?: Space;\n objects?: EchoReactiveObject<any>[];\n};\n\n/**\n * Handler wrapper for subscription events; extracts space and objects.\n *\n * To test:\n * ```\n * curl -s -X POST -H \"Content-Type: application/json\" --data '{\"space\": \"0446...1cbb\"}' http://localhost:7100/dev/email-extractor\n * ```\n *\n * NOTE: Get space key from devtools or `dx space list --json`\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?.map<EchoReactiveObject<any> | undefined>((id) => space!.db.getObjectById(id)).filter(nonNullable);\n\n if (!!event.space && !space) {\n log.warn('invalid space', { event });\n } else {\n log.info('handler', { space: space?.key.truncate(), objects: objects?.length });\n }\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 '../types';\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 log.info('calling', { name });\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';\nimport http from 'node:http';\nimport WebSocket from 'ws';\n\nimport { TextV0Type } from '@braneframe/types';\nimport { debounce, DeferredTask, sleep, Trigger } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { createSubscription, Filter, getAutomergeObjectCore, type Query, type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionSubscriptionEvent } from '../handler';\nimport {\n type FunctionDef,\n type FunctionManifest,\n type FunctionTrigger,\n type SubscriptionTrigger,\n type TimerTrigger,\n type WebhookTrigger,\n type WebsocketTrigger,\n} from '../types';\n\ntype Callback = (data: FunctionSubscriptionEvent) => Promise<void>;\n\nexport type SchedulerOptions = {\n endpoint?: string;\n callback?: Callback;\n};\n\n/**\n * The scheduler triggers function exectuion based on various triggers.\n */\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 // TODO(burdon): 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 //\n // Triggers types.\n //\n\n if (trigger.timer) {\n await this._createTimer(ctx, space, def, trigger.timer);\n }\n\n if (trigger.webhook) {\n await this._createWebhook(ctx, space, def, trigger.webhook);\n }\n\n if (trigger.websocket) {\n await this._createWebsocket(ctx, space, def, trigger.websocket);\n }\n\n if (trigger.subscription) {\n await this._createSubscription(ctx, space, def, trigger.subscription);\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 // TODO(burdon): Pass in Space key (common context).\n private async _execFunction(def: FunctionDef, data: any) {\n try {\n log.info('exec', { function: def.id });\n const { endpoint, callback } = this._options;\n if (endpoint) {\n // TODO(burdon): Move out of scheduler (generalize as callback).\n 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 } else if (callback) {\n await callback(data);\n }\n\n // const result = await response.json();\n log.info('done', { function: def.id });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n\n //\n // Triggers\n //\n\n /**\n * Cron timer.\n */\n private async _createTimer(ctx: Context, space: Space, def: FunctionDef, trigger: TimerTrigger) {\n log.info('timer', { space: space.key, trigger });\n const { cron } = trigger;\n\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, { space: space.key });\n });\n\n let last = 0;\n let run = 0;\n // https://www.npmjs.com/package/cron#constructor\n const job = CronJob.from({\n cronTime: cron,\n runOnInit: false,\n onTick: () => {\n // TODO(burdon): Check greater than 30s (use cron-parser).\n const now = Date.now();\n const delta = last ? now - last : 0;\n last = now;\n\n run++;\n log.info('tick', { space: space.key.truncate(), count: run, delta });\n task.schedule();\n },\n });\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n /**\n * Webhook.\n */\n private async _createWebhook(ctx: Context, space: Space, def: FunctionDef, trigger: WebhookTrigger) {\n log.info('webhook', { space: space.key, trigger });\n const { port } = trigger;\n\n // TODO(burdon): POST JSON.\n const server = http.createServer(async (req, res) => {\n await this._execFunction(def, { space: space.key });\n });\n\n server.listen(port, () => {\n log.info('started webhook', { port });\n });\n\n ctx.onDispose(() => {\n server.close();\n });\n }\n\n /**\n * Websocket.\n */\n private async _createWebsocket(\n ctx: Context,\n space: Space,\n def: FunctionDef,\n trigger: WebsocketTrigger,\n options: {\n retryDelay: number;\n maxAttempts: number;\n } = {\n retryDelay: 2,\n maxAttempts: 5,\n },\n ) {\n log.info('websocket', { space: space.key, trigger });\n const { url } = trigger;\n\n let ws: WebSocket;\n for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {\n const open = new Trigger<boolean>();\n\n ws = new WebSocket(url);\n Object.assign(ws, {\n onopen: () => {\n log.info('opened', { url });\n if (trigger.init) {\n ws.send(new TextEncoder().encode(JSON.stringify(trigger.init)));\n }\n\n open.wake(true);\n },\n\n onclose: () => {\n log.info('closed', { url });\n open.wake(false);\n },\n\n onerror: (event) => {\n log.catch(event.error, { url });\n },\n\n onmessage: async (event) => {\n try {\n const data = JSON.parse(new TextDecoder().decode(event.data as Uint8Array));\n await this._execFunction(def, { space: space.key, data });\n } catch (err) {\n log.catch(err, { url });\n }\n },\n } satisfies Partial<WebSocket>);\n\n const isOpen = await open.wait();\n if (isOpen) {\n break;\n } else {\n const wait = Math.pow(attempt, 2) * options.retryDelay;\n if (attempt < options.maxAttempts) {\n log.warn(`failed to connect; trying again in ${wait}s`, { attempt });\n await sleep(wait * 1_000);\n }\n }\n }\n\n ctx.onDispose(() => {\n ws?.close();\n });\n }\n\n /**\n * ECHO subscription.\n */\n private async _createSubscription(ctx: Context, space: Space, def: FunctionDef, trigger: SubscriptionTrigger) {\n log.info('subscription', { space: space.key, trigger });\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, { space: space.key, objects: Array.from(objectIds) });\n });\n\n // TODO(burdon): Don't fire initially.\n // TODO(burdon): Subscription is called THREE times.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n log.info('updated', { added: added.length, updated: updated.length });\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 // TODO(burdon): Create queue. Only allow one invocation per trigger at a time?\n // TODO(burdon): Disable trigger if keeps failing.\n const { filter, options: { deep, delay } = {} } = trigger;\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', { objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextV0Type) {\n subscriptions.push(\n getAutomergeObjectCore(content).updates.on(debounce(() => subscription.update([object]), 1_000)),\n );\n }\n }\n }\n };\n\n // TODO(burdon): Is Filter.or implemented?\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.or(filter.map(({ type, props }) => Filter.typename(type, props))));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport * as S from '@effect/schema/Schema';\n\nconst TimerTriggerSchema = S.struct({\n cron: S.string,\n});\n\nconst WebhookTriggerSchema = S.struct({\n port: S.number,\n});\n\nconst WebsocketTriggerSchema = S.struct({\n url: S.string,\n init: S.optional(S.record(S.string, S.any)),\n});\n\nconst SubscriptionTriggerSchema = S.struct({\n spaceKey: S.optional(S.string),\n // TODO(burdon): Define query DSL.\n filter: S.array(\n S.struct({\n type: S.string,\n props: S.optional(S.record(S.string, S.any)),\n }),\n ),\n options: S.optional(\n S.struct({\n // Watch changes to object (not just creation).\n deep: S.optional(S.boolean),\n // Debounce changes (delay in ms).\n delay: S.optional(S.number),\n }),\n ),\n});\n\nconst FunctionTriggerSchema = S.struct({\n function: S.string.pipe(S.description('Function ID/URI.')),\n\n timer: S.optional(TimerTriggerSchema),\n webhook: S.optional(WebhookTriggerSchema),\n websocket: S.optional(WebsocketTriggerSchema),\n subscription: S.optional(SubscriptionTriggerSchema),\n});\n\nexport type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;\nexport type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;\nexport type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;\nexport type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;\nexport type FunctionTrigger = S.Schema.Type<typeof FunctionTriggerSchema>;\n\n/**\n * Function definition.\n */\n// TODO(burdon): Name vs. path?\nconst FunctionDefSchema = S.struct({\n id: S.string,\n description: S.optional(S.string),\n name: S.string,\n // TODO(burdon): NPM/GitHub URL?\n handler: S.string,\n});\n\nexport type FunctionDef = S.Schema.Type<typeof FunctionDefSchema>;\n\n/**\n * Function manifest file.\n */\nexport const FunctionManifestSchema = S.struct({\n functions: S.mutable(S.array(FunctionDefSchema)),\n triggers: S.mutable(S.array(FunctionTriggerSchema)),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\n"],
5
+ "mappings": "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",
6
+ "names": ["PublicKey", "log", "nonNullable", "subscriptionHandler", "handler", "event", "context", "rest", "client", "space", "spaces", "get", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "warn", "info", "key", "truncate", "length", "express", "getPort", "join", "Trigger", "invariant", "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", "info", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "_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", "dataDir", "response", "status", "code", "duration", "CronJob", "http", "WebSocket", "TextV0Type", "debounce", "DeferredTask", "sleep", "Trigger", "createSubscription", "Filter", "getAutomergeObjectCore", "Context", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "id", "spaceKey", "toHex", "start", "spaces", "subscribe", "space", "waitUntilReady", "trigger", "triggers", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "def", "functions", "find", "config", "exists", "get", "set", "disposed", "timer", "_createTimer", "webhook", "_createWebhook", "websocket", "_createWebsocket", "subscription", "_createSubscription", "delete", "dispose", "_execFunction", "data", "info", "endpoint", "callback", "fetch", "name", "method", "headers", "body", "JSON", "stringify", "err", "error", "message", "cron", "task", "last", "run", "job", "from", "cronTime", "runOnInit", "onTick", "now", "Date", "delta", "truncate", "count", "schedule", "onDispose", "port", "server", "createServer", "req", "res", "listen", "close", "options", "retryDelay", "maxAttempts", "url", "ws", "attempt", "open", "Object", "assign", "onopen", "init", "send", "TextEncoder", "encode", "wake", "onclose", "onerror", "event", "catch", "onmessage", "parse", "TextDecoder", "decode", "isOpen", "wait", "Math", "pow", "warn", "objectIds", "Set", "objects", "Array", "subscriptions", "added", "updated", "length", "object", "add", "push", "unsubscribe", "filter", "deep", "delay", "update", "content", "updates", "on", "query", "db", "or", "map", "type", "props", "typename", "forEach", "S", "TimerTriggerSchema", "struct", "cron", "string", "WebhookTriggerSchema", "port", "number", "WebsocketTriggerSchema", "url", "init", "optional", "record", "any", "SubscriptionTriggerSchema", "spaceKey", "filter", "array", "type", "props", "options", "deep", "boolean", "delay", "FunctionTriggerSchema", "function", "pipe", "description", "timer", "webhook", "websocket", "subscription", "FunctionDefSchema", "id", "name", "handler", "FunctionManifestSchema", "functions", "mutable", "triggers"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/handler.ts":{"bytes":5873,"imports":[{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1910,"imports":[{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":19229,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/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":"@inject-globals","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":25793,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@braneframe/types","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/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","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"},{"path":"@inject-globals","kind":"import-statement","external":true}],"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"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":24107},"packages/core/functions/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/log","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":"@dxos/node-std/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":"@braneframe/types","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/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":{"inject-globals:@inject-globals":{"bytesInOutput":90},"packages/core/functions/src/handler.ts":{"bytesInOutput":1057},"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4993},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":6345}},"bytes":13167}}}
1
+ {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/handler.ts":{"bytes":6277,"imports":[{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":19225,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/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":"@inject-globals","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":37601,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"ws","kind":"import-statement","external":true},{"path":"@braneframe/types","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/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","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"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/types.ts":{"bytes":6957,"imports":[{"path":"@effect/schema/Schema","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":630,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"},{"path":"packages/core/functions/src/types.ts","kind":"import-statement","original":"./types"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":33218},"packages/core/functions/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"@dxos/client","kind":"import-statement","external":true},{"path":"@dxos/log","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":"@dxos/node-std/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/node-std/http","kind":"import-statement","external":true},{"path":"ws","kind":"import-statement","external":true},{"path":"@braneframe/types","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/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@effect/schema/Schema","kind":"import-statement","external":true}],"exports":["DevServer","FunctionManifestSchema","Scheduler","subscriptionHandler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":90},"packages/core/functions/src/handler.ts":{"bytesInOutput":1057},"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4993},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":9717},"packages/core/functions/src/types.ts":{"bytesInOutput":1294}},"bytes":17900}}}