@dxos/functions 0.5.3-main.b41a319 → 0.5.3-main.c3feabc

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.
@@ -65,16 +65,16 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
65
65
  });
66
66
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/handler.ts";
67
67
  var subscriptionHandler = (handler) => {
68
- return ({ event: { data }, context, ...rest }) => {
68
+ return ({ event, context, ...rest }) => {
69
69
  const { client } = context;
70
- const space = data.spaceKey ? client.spaces.get(import_client.PublicKey.from(data.spaceKey)) : void 0;
71
- const objects = space ? data.objects?.map((id) => space.db.getObjectById(id)).filter(import_util.nonNullable) : [];
72
- if (!!data.spaceKey && !space) {
70
+ const space = event.spaceKey ? client.spaces.get(import_client.PublicKey.from(event.spaceKey)) : void 0;
71
+ const objects = space && event.objects?.map((id) => space.db.getObjectById(id)).filter(import_util.nonNullable);
72
+ if (!!event.spaceKey && !space) {
73
73
  import_log.log.warn("invalid space", {
74
- data
74
+ event
75
75
  }, {
76
76
  F: __dxlog_file,
77
- L: 91,
77
+ L: 68,
78
78
  S: void 0,
79
79
  C: (f, a) => f(...a)
80
80
  });
@@ -84,18 +84,15 @@ var subscriptionHandler = (handler) => {
84
84
  objects: objects?.length
85
85
  }, {
86
86
  F: __dxlog_file,
87
- L: 93,
87
+ L: 70,
88
88
  S: void 0,
89
89
  C: (f, a) => f(...a)
90
90
  });
91
91
  }
92
92
  return handler({
93
93
  event: {
94
- data: {
95
- ...data,
96
- space,
97
- objects
98
- }
94
+ space,
95
+ objects
99
96
  },
100
97
  context,
101
98
  ...rest
@@ -343,9 +340,7 @@ var DevServer = class {
343
340
  S: this,
344
341
  C: (f, a) => f(...a)
345
342
  });
346
- const statusCode = await this._invoke(path2, {
347
- data
348
- });
343
+ const statusCode = await this._invoke(path2, data);
349
344
  import_log2.log.info("res", {
350
345
  seq,
351
346
  path: path2,
@@ -430,7 +425,7 @@ var Scheduler = class {
430
425
  const def = this._manifest.functions.find((config) => config.id === trigger.function);
431
426
  (0, import_invariant2.invariant)(def, `Function not found: ${trigger.function}`, {
432
427
  F: __dxlog_file3,
433
- L: 76,
428
+ L: 83,
434
429
  S: this,
435
430
  A: [
436
431
  "def",
@@ -448,7 +443,7 @@ var Scheduler = class {
448
443
  trigger
449
444
  }, {
450
445
  F: __dxlog_file3,
451
- L: 82,
446
+ L: 89,
452
447
  S: this,
453
448
  C: (f, a) => f(...a)
454
449
  });
@@ -456,16 +451,16 @@ var Scheduler = class {
456
451
  return;
457
452
  }
458
453
  if (trigger.timer) {
459
- await this._createTimer(ctx, space, def, trigger);
454
+ await this._createTimer(ctx, space, def, trigger.timer);
460
455
  }
461
456
  if (trigger.webhook) {
462
- await this._createWebhook(ctx, space, def, trigger);
457
+ await this._createWebhook(ctx, space, def, trigger.webhook);
463
458
  }
464
459
  if (trigger.websocket) {
465
- await this._createWebsocket(ctx, space, def, trigger);
460
+ await this._createWebsocket(ctx, space, def, trigger.websocket);
466
461
  }
467
462
  if (trigger.subscription) {
468
- await this._createSubscription(ctx, space, def, trigger);
463
+ await this._createSubscription(ctx, space, def, trigger.subscription);
469
464
  }
470
465
  }
471
466
  }
@@ -480,12 +475,10 @@ var Scheduler = class {
480
475
  await ctx.dispose();
481
476
  }
482
477
  }
483
- async _execFunction(def, trigger, data) {
484
- let status = 0;
478
+ // TODO(burdon): Pass in Space key (common context).
479
+ async _execFunction(def, data) {
485
480
  try {
486
- const payload = Object.assign({}, {
487
- meta: trigger.meta
488
- }, data);
481
+ let status = 0;
489
482
  const { endpoint, callback } = this._options;
490
483
  if (endpoint) {
491
484
  const url = import_node_path2.default.join(endpoint, def.path);
@@ -494,7 +487,7 @@ var Scheduler = class {
494
487
  url
495
488
  }, {
496
489
  F: __dxlog_file3,
497
- L: 128,
490
+ L: 133,
498
491
  S: this,
499
492
  C: (f, a) => f(...a)
500
493
  });
@@ -503,7 +496,7 @@ var Scheduler = class {
503
496
  headers: {
504
497
  "Content-Type": "application/json"
505
498
  },
506
- body: JSON.stringify(payload)
499
+ body: JSON.stringify(data)
507
500
  });
508
501
  status = response.status;
509
502
  } else if (callback) {
@@ -511,11 +504,11 @@ var Scheduler = class {
511
504
  function: def.id
512
505
  }, {
513
506
  F: __dxlog_file3,
514
- L: 139,
507
+ L: 144,
515
508
  S: this,
516
509
  C: (f, a) => f(...a)
517
510
  });
518
- status = await callback(payload) ?? 200;
511
+ status = await callback(data) ?? 200;
519
512
  }
520
513
  if (status && status >= 400) {
521
514
  throw new Error(`Response: ${status}`);
@@ -525,23 +518,23 @@ var Scheduler = class {
525
518
  status
526
519
  }, {
527
520
  F: __dxlog_file3,
528
- L: 149,
521
+ L: 154,
529
522
  S: this,
530
523
  C: (f, a) => f(...a)
531
524
  });
525
+ return status;
532
526
  } catch (err) {
533
527
  import_log3.log.error("error", {
534
528
  function: def.id,
535
529
  error: err.message
536
530
  }, {
537
531
  F: __dxlog_file3,
538
- L: 151,
532
+ L: 157,
539
533
  S: this,
540
534
  C: (f, a) => f(...a)
541
535
  });
542
- status = 500;
536
+ return 500;
543
537
  }
544
- return status;
545
538
  }
546
539
  //
547
540
  // Triggers
@@ -555,20 +548,20 @@ var Scheduler = class {
555
548
  trigger
556
549
  }, {
557
550
  F: __dxlog_file3,
558
- L: 166,
551
+ L: 170,
559
552
  S: this,
560
553
  C: (f, a) => f(...a)
561
554
  });
562
- const spec = trigger.timer;
555
+ const { cron } = trigger;
563
556
  const task = new import_async2.DeferredTask(ctx, async () => {
564
- await this._execFunction(def, trigger, {
557
+ await this._execFunction(def, {
565
558
  spaceKey: space.key
566
559
  });
567
560
  });
568
561
  let last = 0;
569
562
  let run = 0;
570
563
  const job = import_cron.CronJob.from({
571
- cronTime: spec.cron,
564
+ cronTime: cron,
572
565
  runOnInit: false,
573
566
  onTick: () => {
574
567
  const now = Date.now();
@@ -581,7 +574,7 @@ var Scheduler = class {
581
574
  delta
582
575
  }, {
583
576
  F: __dxlog_file3,
584
- L: 186,
577
+ L: 190,
585
578
  S: this,
586
579
  C: (f, a) => f(...a)
587
580
  });
@@ -600,17 +593,16 @@ var Scheduler = class {
600
593
  trigger
601
594
  }, {
602
595
  F: __dxlog_file3,
603
- L: 199,
596
+ L: 203,
604
597
  S: this,
605
598
  C: (f, a) => f(...a)
606
599
  });
607
- const spec = trigger.webhook;
608
600
  const server = import_node_http.default.createServer(async (req, res) => {
609
- if (req.method !== spec.method) {
601
+ if (req.method !== trigger.method) {
610
602
  res.statusCode = 405;
611
603
  return res.end();
612
604
  }
613
- res.statusCode = await this._execFunction(def, trigger, {
605
+ res.statusCode = await this._execFunction(def, {
614
606
  spaceKey: space.key
615
607
  });
616
608
  res.end();
@@ -623,11 +615,11 @@ var Scheduler = class {
623
615
  port
624
616
  }, {
625
617
  F: __dxlog_file3,
626
- L: 223,
618
+ L: 226,
627
619
  S: this,
628
620
  C: (f, a) => f(...a)
629
621
  });
630
- spec.port = port;
622
+ trigger.port = port;
631
623
  });
632
624
  ctx.onDispose(() => {
633
625
  server.close();
@@ -646,12 +638,11 @@ var Scheduler = class {
646
638
  trigger
647
639
  }, {
648
640
  F: __dxlog_file3,
649
- L: 249,
641
+ L: 252,
650
642
  S: this,
651
643
  C: (f, a) => f(...a)
652
644
  });
653
- const spec = trigger.websocket;
654
- const { url, init } = spec;
645
+ const { url } = trigger;
655
646
  let ws;
656
647
  for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
657
648
  const open = new import_async2.Trigger();
@@ -662,38 +653,26 @@ var Scheduler = class {
662
653
  url
663
654
  }, {
664
655
  F: __dxlog_file3,
665
- L: 260,
656
+ L: 262,
666
657
  S: this,
667
658
  C: (f, a) => f(...a)
668
659
  });
669
- if (spec.init) {
670
- ws.send(new TextEncoder().encode(JSON.stringify(init)));
660
+ if (trigger.init) {
661
+ ws.send(new TextEncoder().encode(JSON.stringify(trigger.init)));
671
662
  }
672
663
  open.wake(true);
673
664
  },
665
+ // TODO(burdon): Config retry if server closes?
674
666
  onclose: (event) => {
675
667
  import_log3.log.info("closed", {
676
668
  url,
677
669
  code: event.code
678
670
  }, {
679
671
  F: __dxlog_file3,
680
- L: 269,
672
+ L: 272,
681
673
  S: this,
682
674
  C: (f, a) => f(...a)
683
675
  });
684
- if (event.code === 1006) {
685
- setTimeout(async () => {
686
- import_log3.log.info(`reconnecting in ${options.retryDelay}s...`, {
687
- url
688
- }, {
689
- F: __dxlog_file3,
690
- L: 274,
691
- S: this,
692
- C: (f, a) => f(...a)
693
- });
694
- await this._createWebsocket(ctx, space, def, trigger, options);
695
- }, options.retryDelay * 1e3);
696
- }
697
676
  open.wake(false);
698
677
  },
699
678
  onerror: (event) => {
@@ -701,7 +680,7 @@ var Scheduler = class {
701
680
  url
702
681
  }, {
703
682
  F: __dxlog_file3,
704
- L: 283,
683
+ L: 277,
705
684
  S: this,
706
685
  C: (f, a) => f(...a)
707
686
  });
@@ -709,7 +688,7 @@ var Scheduler = class {
709
688
  onmessage: async (event) => {
710
689
  try {
711
690
  const data = JSON.parse(new TextDecoder().decode(event.data));
712
- await this._execFunction(def, trigger, {
691
+ await this._execFunction(def, {
713
692
  spaceKey: space.key,
714
693
  data
715
694
  });
@@ -718,7 +697,7 @@ var Scheduler = class {
718
697
  url
719
698
  }, {
720
699
  F: __dxlog_file3,
721
- L: 291,
700
+ L: 285,
722
701
  S: this,
723
702
  C: (f, a) => f(...a)
724
703
  });
@@ -735,7 +714,7 @@ var Scheduler = class {
735
714
  attempt
736
715
  }, {
737
716
  F: __dxlog_file3,
738
- L: 302,
717
+ L: 296,
739
718
  S: this,
740
719
  C: (f, a) => f(...a)
741
720
  });
@@ -756,14 +735,13 @@ var Scheduler = class {
756
735
  trigger
757
736
  }, {
758
737
  F: __dxlog_file3,
759
- L: 317,
738
+ L: 311,
760
739
  S: this,
761
740
  C: (f, a) => f(...a)
762
741
  });
763
- const spec = trigger.subscription;
764
742
  const objectIds = /* @__PURE__ */ new Set();
765
743
  const task = new import_async2.DeferredTask(ctx, async () => {
766
- await this._execFunction(def, trigger, {
744
+ await this._execFunction(def, {
767
745
  spaceKey: space.key,
768
746
  objects: Array.from(objectIds)
769
747
  });
@@ -775,7 +753,7 @@ var Scheduler = class {
775
753
  updated: updated.length
776
754
  }, {
777
755
  F: __dxlog_file3,
778
- L: 329,
756
+ L: 321,
779
757
  S: this,
780
758
  C: (f, a) => f(...a)
781
759
  });
@@ -788,7 +766,7 @@ var Scheduler = class {
788
766
  task.schedule();
789
767
  });
790
768
  subscriptions.push(() => subscription.unsubscribe());
791
- const { filter, options: { deep, delay } = {} } = spec;
769
+ const { filter, options: { deep, delay } = {} } = trigger;
792
770
  const update = ({ objects }) => {
793
771
  subscription.update(objects);
794
772
  if (deep) {
@@ -796,7 +774,7 @@ var Scheduler = class {
796
774
  objects: objects.length
797
775
  }, {
798
776
  F: __dxlog_file3,
799
- L: 349,
777
+ L: 342,
800
778
  S: this,
801
779
  C: (f, a) => f(...a)
802
780
  });
@@ -846,7 +824,7 @@ var SubscriptionTriggerSchema = S.struct({
846
824
  var FunctionTriggerSchema = S.struct({
847
825
  function: S.string.pipe(S.description("Function ID/URI.")),
848
826
  // Context passed to function.
849
- meta: S.optional(S.record(S.string, S.any)),
827
+ context: S.optional(S.record(S.string, S.any)),
850
828
  // Triggers.
851
829
  timer: S.optional(TimerTriggerSchema),
852
830
  webhook: S.optional(WebhookTriggerSchema),
@@ -857,7 +835,6 @@ var FunctionDefSchema = S.struct({
857
835
  id: S.string,
858
836
  // name: S.string,
859
837
  description: S.optional(S.string),
860
- // TODO(burdon): Rename route?
861
838
  path: S.string,
862
839
  // TODO(burdon): NPM/GitHub/Docker/CF URL?
863
840
  handler: S.string
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
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): Model after http request. Ref Lambda/OpenFaaS.\n// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html\n// https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml/#functions\n// https://www.npmjs.com/package/aws-lambda\n\n/**\n * Function handler.\n */\nexport type FunctionHandler<TData = {}, TMeta = {}> = (params: {\n context: FunctionContext;\n event: FunctionEvent<TData, TMeta>;\n response: FunctionResponse;\n}) => Promise<FunctionResponse | void>;\n\n/**\n * Function context.\n */\nexport interface FunctionContext {\n // TODO(burdon): Limit access to individual space.\n client: Client;\n // TODO(burdon): Replace with storage service abstraction.\n dataDir?: string;\n}\n\n/**\n * Event payload.\n */\nexport type FunctionEvent<TData = {}, TMeta = {}> = {\n data: FunctionEventMeta<TMeta> & TData;\n};\n\n/**\n * Metadata from trigger.\n */\nexport type FunctionEventMeta<TMeta = {}> = {\n meta: TMeta;\n};\n\n/**\n * Function response.\n */\nexport interface FunctionResponse {\n status(code: number): FunctionResponse;\n}\n\n//\n// Subscription utils.\n//\n\nexport type RawSubscriptionData = {\n spaceKey?: string;\n objects?: string[];\n};\n\nexport type SubscriptionData = {\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 = <TMeta>(\n handler: FunctionHandler<SubscriptionData, TMeta>,\n): FunctionHandler<RawSubscriptionData, TMeta> => {\n return ({ event: { data }, context, ...rest }) => {\n const { client } = context;\n const space = data.spaceKey ? client.spaces.get(PublicKey.from(data.spaceKey)) : undefined;\n const objects = space\n ? data.objects?.map<EchoReactiveObject<any> | undefined>((id) => space!.db.getObjectById(id)).filter(nonNullable)\n : [];\n\n if (!!data.spaceKey && !space) {\n log.warn('invalid space', { data });\n } else {\n log.info('handler', { space: space?.key.truncate(), objects: objects?.length });\n }\n\n return handler({ event: { data: { ...data, 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 { Event, 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 FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../types';\n\nexport type DevServerOptions = {\n manifest: FunctionManifest;\n baseDir: string;\n port?: number;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for 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 _functionServiceRegistration?: string;\n private _proxy?: string;\n private _seq = 0;\n\n public readonly update = new Event<number>();\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get stats() {\n return {\n seq: this._seq,\n };\n }\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async 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 invariant(!this._server);\n log.info('starting...');\n\n // TODO(burdon): Move to hono.\n const app = express();\n app.use(express.json());\n\n app.post('/:path', async (req, res) => {\n const { path } = req.params;\n try {\n log.info('calling', { path });\n if (this._options.reload) {\n const { def } = this._handlers['/' + path];\n await this._load(def, true);\n }\n\n // TODO(burdon): Get function context.\n res.statusCode = await this.invoke('/' + path, 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: { id, path } }) => ({ id, path })),\n });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n\n log.info('started', { port: this._port });\n }\n\n async stop() {\n invariant(this._server);\n log.info('stopping...');\n\n const trigger = new Trigger();\n this._server.close(async () => {\n log.info('server stopped');\n try {\n if (this._functionServiceRegistration) {\n invariant(this._client.services.services.FunctionRegistryService);\n await this._client.services.services.FunctionRegistryService.unregister({\n registrationId: this._functionServiceRegistration,\n });\n\n log.info('unregistered', { registrationId: this._functionServiceRegistration });\n this._functionServiceRegistration = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n } catch (err) {\n trigger.throw(err as Error);\n }\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n log.info('stopped');\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, force = false) {\n const { id, path, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { id, force });\n\n // Remove from cache.\n if (force) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(filePath))\n .forEach((key) => {\n delete require.cache[key];\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(filePath);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[path] = { def, handler: module.default };\n }\n\n /**\n * Invoke function.\n */\n public async invoke(path: string, data: any): Promise<number> {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, path });\n const statusCode = await this._invoke(path, { data });\n\n log.info('res', { seq, path, statusCode, duration: Date.now() - now });\n this.update.emit(statusCode);\n return statusCode;\n }\n\n private async _invoke(path: string, event: FunctionEvent) {\n const { handler } = this._handlers[path] ?? {};\n invariant(handler, `invalid path: ${path}`);\n\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n };\n\n let statusCode = 200;\n const response: FunctionResponse = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\nimport { getPort } from 'get-port-please';\nimport http from 'node:http';\nimport path from 'node:path';\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 FunctionEventMeta } from '../handler';\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../types';\n\nexport type Callback = (data: any) => Promise<void | number>;\n\nexport type SchedulerOptions = {\n endpoint?: string;\n callback?: Callback;\n};\n\n/**\n * The scheduler triggers function execution based on various triggers.\n */\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { spaceKey: PublicKey; id: string },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ spaceKey, id }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions = {},\n ) {}\n\n get mounts() {\n return Array.from(this._mounts.values()).reduce<FunctionTrigger[]>((acc, { trigger }) => {\n acc.push(trigger);\n return acc;\n }, []);\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 /**\n * Mount trigger.\n */\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { spaceKey: space.key, id: trigger.function };\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);\n }\n\n if (trigger.webhook) {\n await this._createWebhook(ctx, space, def, trigger);\n }\n\n if (trigger.websocket) {\n await this._createWebsocket(ctx, space, def, trigger);\n }\n\n if (trigger.subscription) {\n await this._createSubscription(ctx, space, def, trigger);\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<TData, TMeta>(def: FunctionDef, trigger: FunctionTrigger, data: TData): Promise<number> {\n let status = 0;\n try {\n // TODO(burdon): Pass in Space key (common context)?\n const payload = Object.assign({}, { meta: trigger.meta as TMeta } satisfies FunctionEventMeta<TMeta>, data);\n\n const { endpoint, callback } = this._options;\n if (endpoint) {\n // TODO(burdon): Move out of scheduler (generalize as callback).\n const url = path.join(endpoint, def.path);\n log.info('exec', { function: def.id, url });\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n status = response.status;\n } else if (callback) {\n log.info('exec', { function: def.id });\n status = (await callback(payload)) ?? 200;\n }\n\n // Check errors.\n if (status && status >= 400) {\n throw new Error(`Response: ${status}`);\n }\n\n // const result = await response.json();\n log.info('done', { function: def.id, status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n status = 500;\n }\n\n return status;\n }\n\n //\n // Triggers\n //\n\n /**\n * Cron timer.\n */\n private async _createTimer(ctx: Context, space: Space, def: FunctionDef, trigger: FunctionTrigger) {\n log.info('timer', { space: space.key, trigger });\n const spec = trigger.timer!;\n\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, trigger, { spaceKey: 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: spec.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: FunctionTrigger) {\n log.info('webhook', { space: space.key, trigger });\n const spec = trigger.webhook!;\n\n // TODO(burdon): Enable POST hook with payload.\n const server = http.createServer(async (req, res) => {\n if (req.method !== spec.method) {\n res.statusCode = 405;\n return res.end();\n }\n\n res.statusCode = await this._execFunction(def, trigger, { spaceKey: space.key });\n res.end();\n });\n\n // TODO(burdon): Not used.\n // const DEF_PORT_RANGE = { min: 7500, max: 7599 };\n // const portRange = Object.assign({}, trigger.port, DEF_PORT_RANGE) as WebhookTrigger['port'];\n const port = await getPort({\n random: true,\n // portRange: [portRange!.min, portRange!.max],\n });\n\n // TODO(burdon): Update trigger object with actual port.\n server.listen(port, () => {\n log.info('started webhook', { port });\n spec.port = port;\n });\n\n ctx.onDispose(() => {\n server.close();\n });\n }\n\n /**\n * Websocket.\n * NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.\n */\n private async _createWebsocket(\n ctx: Context,\n space: Space,\n def: FunctionDef,\n trigger: FunctionTrigger,\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 spec = trigger.websocket!;\n const { url, init } = spec;\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 (spec.init) {\n ws.send(new TextEncoder().encode(JSON.stringify(init)));\n }\n\n open.wake(true);\n },\n\n onclose: (event) => {\n log.info('closed', { url, code: event.code });\n // Reconnect if server closes (e.g., CF restart).\n // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code\n if (event.code === 1006) {\n setTimeout(async () => {\n log.info(`reconnecting in ${options.retryDelay}s...`, { url });\n await this._createWebsocket(ctx, space, def, trigger, options);\n }, options.retryDelay * 1_000);\n }\n\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, trigger, { spaceKey: 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: FunctionTrigger) {\n log.info('subscription', { space: space.key, trigger });\n const spec = trigger.subscription!;\n\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this._execFunction(def, trigger, { spaceKey: space.key, objects: Array.from(objectIds) });\n });\n\n // TODO(burdon): Don't fire initially?\n // TODO(burdon): Create queue. Only allow one invocation per trigger at a time?\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\n subscriptions.push(() => subscription.unsubscribe());\n\n // TODO(burdon): Disable trigger if keeps failing.\n const { filter, options: { deep, delay } = {} } = spec;\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.mutable(\n S.struct({\n method: S.string,\n // Assigned port.\n port: S.optional(S.number),\n }),\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 // Context passed to function.\n meta: S.optional(S.record(S.string, S.any)),\n\n // Triggers.\n timer: S.optional(TimerTriggerSchema),\n webhook: S.optional(WebhookTriggerSchema),\n websocket: S.optional(WebsocketTriggerSchema),\n subscription: S.optional(SubscriptionTriggerSchema),\n});\n\nexport type FunctionTrigger = S.Schema.Type<typeof FunctionTriggerSchema>;\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>;\n\n/**\n * Function definition.\n */\n// TODO(burdon): Name vs. path?\nconst FunctionDefSchema = S.struct({\n id: S.string,\n // name: S.string,\n description: S.optional(S.string),\n // TODO(burdon): Rename route?\n path: S.string,\n // TODO(burdon): NPM/GitHub/Docker/CF 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.optional(S.mutable(S.array(FunctionTriggerSchema))),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\n"],
5
- "mappings": "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",
6
- "names": ["import_log", "import_get_port_please", "import_node_path", "import_async", "import_invariant", "import_util", "subscriptionHandler", "handler", "event", "data", "context", "rest", "client", "space", "spaceKey", "spaces", "get", "PublicKey", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "nonNullable", "log", "warn", "info", "key", "truncate", "length", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "update", "Event", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "error", "start", "_server", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "statusCode", "invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "register", "_functionServiceRegistration", "stop", "Error", "trigger", "Trigger", "close", "unregister", "wake", "throw", "wait", "force", "filePath", "join", "baseDir", "keys", "require", "cache", "startsWith", "forEach", "module", "default", "now", "Date", "_invoke", "duration", "emit", "dataDir", "response", "status", "code", "Scheduler", "_manifest", "_mounts", "ComplexMap", "toHex", "mounts", "Array", "reduce", "acc", "push", "subscribe", "waitUntilReady", "triggers", "mount", "Context", "unmount", "ctx", "function", "find", "config", "exists", "set", "disposed", "timer", "_createTimer", "webhook", "_createWebhook", "websocket", "_createWebsocket", "subscription", "_createSubscription", "delete", "dispose", "_execFunction", "payload", "assign", "meta", "callback", "url", "fetch", "method", "headers", "JSON", "stringify", "message", "spec", "task", "DeferredTask", "last", "run", "job", "CronJob", "cronTime", "cron", "runOnInit", "onTick", "delta", "count", "schedule", "onDispose", "server", "http", "createServer", "random", "options", "retryDelay", "maxAttempts", "init", "ws", "attempt", "open", "WebSocket", "onopen", "send", "TextEncoder", "encode", "onclose", "setTimeout", "onerror", "onmessage", "parse", "TextDecoder", "decode", "isOpen", "Math", "pow", "sleep", "objectIds", "Set", "subscriptions", "createSubscription", "added", "updated", "object", "add", "unsubscribe", "deep", "delay", "content", "TextV0Type", "getAutomergeObjectCore", "updates", "on", "debounce", "query", "Filter", "or", "type", "props", "typename", "TimerTriggerSchema", "struct", "string", "WebhookTriggerSchema", "mutable", "optional", "number", "WebsocketTriggerSchema", "record", "any", "SubscriptionTriggerSchema", "array", "boolean", "FunctionTriggerSchema", "pipe", "description", "FunctionDefSchema", "FunctionManifestSchema"]
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// Lambda-like function definitions.\n// 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\nexport interface FunctionContext {\n // TODO(burdon): Limit access to individual space.\n client: Client;\n // TODO(burdon): Replace with storage service abstraction.\n dataDir?: string;\n // Data passed to function invocation.\n data?: any;\n}\n\n// TODO(burdon): Model after http request. Ref Lambda/OpenFaaS.\nexport type FunctionHandler<T extends {}> = (params: {\n event: T;\n context: FunctionContext;\n response: Response;\n}) => Promise<Response | void>;\n\nexport type RawSubscriptionEvent = {\n spaceKey?: string;\n objects?: string[];\n};\n\nexport type SubscriptionEvent = {\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<SubscriptionEvent>,\n): FunctionHandler<RawSubscriptionEvent> => {\n return ({ event, context, ...rest }) => {\n const { client } = context;\n const space = event.spaceKey ? client.spaces.get(PublicKey.from(event.spaceKey)) : undefined;\n const objects =\n space &&\n event.objects?.map<EchoReactiveObject<any> | undefined>((id) => space!.db.getObjectById(id)).filter(nonNullable);\n\n if (!!event.spaceKey && !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 { Event, 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 manifest: FunctionManifest;\n baseDir: string;\n port?: number;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for 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 _functionServiceRegistration?: string;\n private _proxy?: string;\n private _seq = 0;\n\n public readonly update = new Event<number>();\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get stats() {\n return {\n seq: this._seq,\n };\n }\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async 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 invariant(!this._server);\n log.info('starting...');\n\n // TODO(burdon): Move to hono.\n const app = express();\n app.use(express.json());\n\n app.post('/:path', async (req, res) => {\n const { path } = req.params;\n try {\n log.info('calling', { path });\n if (this._options.reload) {\n const { def } = this._handlers['/' + path];\n await this._load(def, true);\n }\n\n // TODO(burdon): Get function context.\n res.statusCode = await this.invoke('/' + path, 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: { id, path } }) => ({ id, path })),\n });\n\n log.info('registered', { endpoint });\n this._proxy = endpoint;\n this._functionServiceRegistration = registrationId;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n\n log.info('started', { port: this._port });\n }\n\n async stop() {\n invariant(this._server);\n log.info('stopping...');\n\n const trigger = new Trigger();\n this._server.close(async () => {\n log.info('server stopped');\n try {\n if (this._functionServiceRegistration) {\n invariant(this._client.services.services.FunctionRegistryService);\n await this._client.services.services.FunctionRegistryService.unregister({\n registrationId: this._functionServiceRegistration,\n });\n\n log.info('unregistered', { registrationId: this._functionServiceRegistration });\n this._functionServiceRegistration = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n } catch (err) {\n trigger.throw(err as Error);\n }\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n log.info('stopped');\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, force = false) {\n const { id, path, handler } = def;\n const filePath = join(this._options.baseDir, handler);\n log.info('loading', { id, force });\n\n // Remove from cache.\n if (force) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(filePath))\n .forEach((key) => {\n delete require.cache[key];\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(filePath);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[path] = { def, handler: module.default };\n }\n\n /**\n * Invoke function.\n */\n public async invoke(path: string, data: any): Promise<number> {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, path });\n const statusCode = await this._invoke(path, data);\n\n log.info('res', { seq, path, statusCode, duration: Date.now() - now });\n this.update.emit(statusCode);\n return statusCode;\n }\n\n private async _invoke(path: string, event: any) {\n const { handler } = this._handlers[path] ?? {};\n invariant(handler, `invalid path: ${path}`);\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 return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\nimport { getPort } from 'get-port-please';\nimport http from 'node:http';\nimport path from 'node:path';\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 {\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\nexport type Callback = (data: any) => Promise<void | number>;\n\nexport type SchedulerOptions = {\n endpoint?: string;\n callback?: Callback;\n};\n\n/**\n * The scheduler triggers function execution based on various triggers.\n */\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { spaceKey: PublicKey; id: string },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ spaceKey, id }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions = {},\n ) {}\n\n get mounts() {\n return Array.from(this._mounts.values()).reduce<FunctionTrigger[]>((acc, { trigger }) => {\n acc.push(trigger);\n return acc;\n }, []);\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 /**\n * Mount trigger.\n */\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { spaceKey: space.key, id: trigger.function };\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): Promise<number> {\n try {\n let status = 0;\n const { endpoint, callback } = this._options;\n if (endpoint) {\n // TODO(burdon): Move out of scheduler (generalize as callback).\n const url = path.join(endpoint, def.path);\n log.info('exec', { function: def.id, url });\n const response = await fetch(url, {\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 log.info('exec', { function: def.id });\n status = (await callback(data)) ?? 200;\n }\n\n // Check errors.\n if (status && status >= 400) {\n throw new Error(`Response: ${status}`);\n }\n\n // const result = await response.json();\n log.info('done', { function: def.id, status });\n return status;\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n return 500;\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, { spaceKey: 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\n // TODO(burdon): Enable POST hook with payload.\n const server = http.createServer(async (req, res) => {\n if (req.method !== trigger.method) {\n res.statusCode = 405;\n return res.end();\n }\n\n res.statusCode = await this._execFunction(def, { spaceKey: space.key });\n res.end();\n });\n\n // TODO(burdon): Not used.\n // const DEF_PORT_RANGE = { min: 7500, max: 7599 };\n // const portRange = Object.assign({}, trigger.port, DEF_PORT_RANGE) as WebhookTrigger['port'];\n const port = await getPort({\n random: true,\n // portRange: [portRange!.min, portRange!.max],\n });\n\n // TODO(burdon): Update trigger object with actual port.\n server.listen(port, () => {\n log.info('started webhook', { port });\n trigger.port = port;\n });\n\n ctx.onDispose(() => {\n server.close();\n });\n }\n\n /**\n * Websocket.\n * NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.\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 // TODO(burdon): Config retry if server closes?\n onclose: (event) => {\n log.info('closed', { url, code: event.code });\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, { spaceKey: 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, { spaceKey: 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\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.mutable(\n S.struct({\n method: S.string,\n // Assigned port.\n port: S.optional(S.number),\n }),\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 // Context passed to function.\n context: S.optional(S.record(S.string, S.any)),\n\n // Triggers.\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 // name: S.string,\n description: S.optional(S.string),\n path: S.string,\n // TODO(burdon): NPM/GitHub/Docker/CF 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.optional(S.mutable(S.array(FunctionTriggerSchema))),\n});\n\nexport type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,oBAAuC;AAGvC,iBAAoB;AACpB,kBAA4B;ACJ5B,qBAAoB;AACpB,6BAAwB;AAExB,uBAAqB;AAErB,mBAA+B;AAE/B,uBAA0B;AAC1B,IAAAA,cAAoB;ACRpB,kBAAwB;AACxB,IAAAC,0BAAwB;AACxB,uBAAiB;AACjB,IAAAC,oBAAiB;AACjB,gBAAsB;AAEtB,mBAA2B;AAC3B,IAAAC,gBAAuD;AAEvD,kBAA2F;AAC3F,qBAAwB;AACxB,IAAAC,oBAA0B;AAC1B,IAAAJ,cAAoB;AACpB,IAAAK,eAA2B;ACb3B,QAAmB;;;;;;;;;AHoDZ,IAAMC,sBAAsB,CACjCC,YAAAA;AAEA,SAAO,CAAC,EAAEC,OAAOC,SAAS,GAAGC,KAAAA,MAAM;AACjC,UAAM,EAAEC,OAAM,IAAKF;AACnB,UAAMG,QAAQJ,MAAMK,WAAWF,OAAOG,OAAOC,IAAIC,wBAAUC,KAAKT,MAAMK,QAAQ,CAAA,IAAKK;AACnF,UAAMC,UACJP,SACAJ,MAAMW,SAASC,IAAyC,CAACC,OAAOT,MAAOU,GAAGC,cAAcF,EAAAA,CAAAA,EAAKG,OAAOC,uBAAAA;AAEtG,QAAI,CAAC,CAACjB,MAAMK,YAAY,CAACD,OAAO;AAC9Bc,qBAAIC,KAAK,iBAAiB;QAAEnB;MAAM,GAAA;;;;;;IACpC,OAAO;AACLkB,qBAAIE,KAAK,WAAW;QAAEhB,OAAOA,OAAOiB,IAAIC,SAAAA;QAAYX,SAASA,SAASY;MAAO,GAAA;;;;;;IAC/E;AAEA,WAAOxB,QAAQ;MAAEC,OAAO;QAAEI;QAAOO;MAAQ;MAAGV;MAAS,GAAGC;IAAK,CAAA;EAC/D;AACF;;AC9CO,IAAMsB,YAAN,MAAMA;;EAaXC,YACmBC,SACAC,UACjB;SAFiBD,UAAAA;SACAC,WAAAA;SAbFC,YAAiF,CAAC;SAM3FC,OAAO;SAECC,SAAS,IAAIC,mBAAAA;EAM1B;EAEH,IAAIC,QAAQ;AACV,WAAO;MACLC,KAAK,KAAKJ;IACZ;EACF;EAEA,IAAIK,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,KAAKb,SAAS;EACrC;EAEA,MAAMc,aAAa;AACjB,eAAWC,OAAO,KAAKhB,SAASiB,SAASL,WAAW;AAClD,UAAI;AACF,cAAM,KAAKM,MAAMF,GAAAA;MACnB,SAASG,KAAK;AACZ5B,oBAAAA,IAAI6B,MAAM,qCAAqCD,KAAAA;;;;;;MACjD;IACF;EACF;EAEA,MAAME,QAAQ;AACZb,oCAAU,CAAC,KAAKc,SAAO,QAAA;;;;;;;;;AACvB/B,gBAAAA,IAAIE,KAAK,eAAA,QAAA;;;;;;AAGT,UAAM8B,UAAMC,eAAAA,SAAAA;AACZD,QAAIE,IAAID,eAAAA,QAAQE,KAAI,CAAA;AAEpBH,QAAII,KAAK,UAAU,OAAOC,KAAKC,QAAAA;AAC7B,YAAM,EAAEC,MAAAA,MAAI,IAAKF,IAAIG;AACrB,UAAI;AACFxC,oBAAAA,IAAIE,KAAK,WAAW;UAAEqC,MAAAA;QAAK,GAAA;;;;;;AAC3B,YAAI,KAAK9B,SAASgC,QAAQ;AACxB,gBAAM,EAAEhB,IAAG,IAAK,KAAKf,UAAU,MAAM6B,KAAAA;AACrC,gBAAM,KAAKZ,MAAMF,KAAK,IAAA;QACxB;AAGAa,YAAII,aAAa,MAAM,KAAKC,OAAO,MAAMJ,OAAMF,IAAIO,IAAI;AACvDN,YAAIO,IAAG;MACT,SAASjB,KAAU;AACjB5B,oBAAAA,IAAI8C,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,SAAKnB,UAAUC,IAAImB,OAAO,KAAKjC,KAAK;AAEpC,QAAI;AAEF,YAAM,EAAEkC,gBAAgBpC,SAAQ,IAAK,MAAM,KAAKR,QAAQ6C,SAASA,SAASC,wBAAyBC,SAAS;QAC1GvC,UAAU,KAAKA;QACfK,WAAW,KAAKA,UAAU3B,IAAI,CAAC,EAAE+B,KAAK,EAAE9B,IAAI4C,MAAAA,MAAI,EAAE,OAAQ;UAAE5C;UAAI4C,MAAAA;QAAK,EAAA;MACvE,CAAA;AAEAvC,kBAAAA,IAAIE,KAAK,cAAc;QAAEc;MAAS,GAAA;;;;;;AAClC,WAAKI,SAASJ;AACd,WAAKwC,+BAA+BJ;IACtC,SAASxB,KAAU;AACjB,YAAM,KAAK6B,KAAI;AACf,YAAM,IAAIC,MAAM,qEAAA;IAClB;AAEA1D,gBAAAA,IAAIE,KAAK,WAAW;MAAE+C,MAAM,KAAK/B;IAAM,GAAA;;;;;;EACzC;EAEA,MAAMuC,OAAO;AACXxC,oCAAU,KAAKc,SAAO,QAAA;;;;;;;;;AACtB/B,gBAAAA,IAAIE,KAAK,eAAA,QAAA;;;;;;AAET,UAAMyD,UAAU,IAAIC,qBAAAA;AACpB,SAAK7B,QAAQ8B,MAAM,YAAA;AACjB7D,kBAAAA,IAAIE,KAAK,kBAAA,QAAA;;;;;;AACT,UAAI;AACF,YAAI,KAAKsD,8BAA8B;AACrCvC,0CAAU,KAAKT,QAAQ6C,SAASA,SAASC,yBAAuB,QAAA;;;;;;;;;AAChE,gBAAM,KAAK9C,QAAQ6C,SAASA,SAASC,wBAAwBQ,WAAW;YACtEV,gBAAgB,KAAKI;UACvB,CAAA;AAEAxD,sBAAAA,IAAIE,KAAK,gBAAgB;YAAEkD,gBAAgB,KAAKI;UAA6B,GAAA;;;;;;AAC7E,eAAKA,+BAA+BhE;AACpC,eAAK4B,SAAS5B;QAChB;AAEAmE,gBAAQI,KAAI;MACd,SAASnC,KAAK;AACZ+B,gBAAQK,MAAMpC,GAAAA;MAChB;IACF,CAAA;AAEA,UAAM+B,QAAQM,KAAI;AAClB,SAAK/C,QAAQ1B;AACb,SAAKuC,UAAUvC;AACfQ,gBAAAA,IAAIE,KAAK,WAAA,QAAA;;;;;;EACX;;;;EAKA,MAAcyB,MAAMF,KAAkByC,QAAQ,OAAO;AACnD,UAAM,EAAEvE,IAAI4C,MAAAA,OAAM1D,QAAO,IAAK4C;AAC9B,UAAM0C,eAAWC,uBAAK,KAAK3D,SAAS4D,SAASxF,OAAAA;AAC7CmB,gBAAAA,IAAIE,KAAK,WAAW;MAAEP;MAAIuE;IAAM,GAAA;;;;;;AAGhC,QAAIA,OAAO;AACT5C,aAAOgD,KAAKC,UAAQC,KAAK,EACtB1E,OAAO,CAACK,QAAQA,IAAIsE,WAAWN,QAAAA,CAAAA,EAC/BO,QAAQ,CAACvE,QAAAA;AACR,eAAOoE,UAAQC,MAAMrE,GAAAA;MACvB,CAAA;IACJ;AAGA,UAAMwE,UAASJ,UAAQJ,QAAAA;AACvB,QAAI,OAAOQ,QAAOC,YAAY,YAAY;AACxC,YAAM,IAAIlB,MAAM,yCAAyC/D,EAAAA,EAAI;IAC/D;AAEA,SAAKe,UAAU6B,KAAAA,IAAQ;MAAEd;MAAK5C,SAAS8F,QAAOC;IAAQ;EACxD;;;;EAKA,MAAajC,OAAOJ,OAAcsC,MAA4B;AAC5D,UAAM9D,MAAM,EAAE,KAAKJ;AACnB,UAAMmE,MAAMC,KAAKD,IAAG;AAEpB9E,gBAAAA,IAAIE,KAAK,OAAO;MAAEa;MAAKwB,MAAAA;IAAK,GAAA;;;;;;AAC5B,UAAMG,aAAa,MAAM,KAAKsC,QAAQzC,OAAMsC,IAAAA;AAE5C7E,gBAAAA,IAAIE,KAAK,OAAO;MAAEa;MAAKwB,MAAAA;MAAMG;MAAYuC,UAAUF,KAAKD,IAAG,IAAKA;IAAI,GAAA;;;;;;AACpE,SAAKlE,OAAOsE,KAAKxC,UAAAA;AACjB,WAAOA;EACT;EAEA,MAAcsC,QAAQzC,OAAczD,OAAY;AAC9C,UAAM,EAAED,QAAO,IAAK,KAAK6B,UAAU6B,KAAAA,KAAS,CAAC;AAC7CtB,oCAAUpC,SAAS,iBAAiB0D,KAAAA,IAAM;;;;;;;;;AAE1C,UAAMxD,UAA2B;MAC/BE,QAAQ,KAAKuB;MACb2E,SAAS,KAAK1E,SAAS0E;IACzB;AAEA,QAAIzC,aAAa;AACjB,UAAM0C,WAAqB;MACzBC,QAAQ,CAACC,SAAAA;AACP5C,qBAAa4C;AACb,eAAOF;MACT;IACF;AAEA,UAAMvG,QAAQ;MAAEE;MAASD;MAAOsG;IAAS,CAAA;AACzC,WAAO1C;EACT;AACF;;AChLO,IAAM6C,YAAN,MAAMA;EAOXhF,YACmBC,SACAgF,WACA/E,WAA6B,CAAC,GAC/C;SAHiBD,UAAAA;SACAgF,YAAAA;SACA/E,WAAAA;SARFgF,UAAU,IAAIC,wBAG7B,CAAC,EAAEvG,UAAUQ,GAAE,MAAO,GAAGR,SAASwG,MAAK,CAAA,IAAMhG,EAAAA,EAAI;EAMhD;EAEH,IAAIiG,SAAS;AACX,WAAOC,MAAMtG,KAAK,KAAKkG,QAAQlE,OAAM,CAAA,EAAIuE,OAA0B,CAACC,KAAK,EAAEpC,QAAO,MAAE;AAClFoC,UAAIC,KAAKrC,OAAAA;AACT,aAAOoC;IACT,GAAG,CAAA,CAAE;EACP;EAEA,MAAMjE,QAAQ;AACZ,SAAKtB,QAAQpB,OAAO6G,UAAU,OAAO7G,WAAAA;AACnC,iBAAWF,SAASE,QAAQ;AAC1B,cAAMF,MAAMgH,eAAc;AAC1B,mBAAWvC,WAAW,KAAK6B,UAAUW,YAAY,CAAA,GAAI;AACnD,gBAAM,KAAKC,MAAM,IAAIC,uBAAAA,GAAWnH,OAAOyE,OAAAA;QACzC;MACF;IACF,CAAA;EACF;EAEA,MAAMF,OAAO;AACX,eAAW,EAAE9D,IAAIR,SAAQ,KAAM,KAAKsG,QAAQnB,KAAI,GAAI;AAClD,YAAM,KAAKgC,QAAQ3G,IAAIR,QAAAA;IACzB;EACF;;;;EAKA,MAAciH,MAAMG,KAAcrH,OAAcyE,SAA0B;AACxE,UAAMxD,MAAM;MAAEhB,UAAUD,MAAMiB;MAAKR,IAAIgE,QAAQ6C;IAAS;AACxD,UAAM/E,MAAM,KAAK+D,UAAUnE,UAAUoF,KAAK,CAACC,WAAWA,OAAO/G,OAAOgE,QAAQ6C,QAAQ;AACpFvF,0BAAAA,WAAUQ,KAAK,uBAAuBkC,QAAQ6C,QAAQ,IAAE;;;;;;;;;AAGxD,UAAMG,SAAS,KAAKlB,QAAQpG,IAAIc,GAAAA;AAChC,QAAI,CAACwG,QAAQ;AACX,WAAKlB,QAAQmB,IAAIzG,KAAK;QAAEoG;QAAK5C;MAAQ,CAAA;AACrC3D,sBAAAA,KAAI,SAAS;QAAEd,OAAOA,MAAMiB;QAAKwD;MAAQ,GAAA;;;;;;AACzC,UAAI4C,IAAIM,UAAU;AAChB;MACF;AAMA,UAAIlD,QAAQmD,OAAO;AACjB,cAAM,KAAKC,aAAaR,KAAKrH,OAAOuC,KAAKkC,QAAQmD,KAAK;MACxD;AAEA,UAAInD,QAAQqD,SAAS;AACnB,cAAM,KAAKC,eAAeV,KAAKrH,OAAOuC,KAAKkC,QAAQqD,OAAO;MAC5D;AAEA,UAAIrD,QAAQuD,WAAW;AACrB,cAAM,KAAKC,iBAAiBZ,KAAKrH,OAAOuC,KAAKkC,QAAQuD,SAAS;MAChE;AAEA,UAAIvD,QAAQyD,cAAc;AACxB,cAAM,KAAKC,oBAAoBd,KAAKrH,OAAOuC,KAAKkC,QAAQyD,YAAY;MACtE;IACF;EACF;EAEA,MAAcd,QAAQ3G,IAAYR,UAAqB;AACrD,UAAMgB,MAAM;MAAER;MAAIR;IAAS;AAC3B,UAAM,EAAEoH,IAAG,IAAK,KAAKd,QAAQpG,IAAIc,GAAAA,KAAQ,CAAC;AAC1C,QAAIoG,KAAK;AACP,WAAKd,QAAQ6B,OAAOnH,GAAAA;AACpB,YAAMoG,IAAIgB,QAAO;IACnB;EACF;;EAGA,MAAcC,cAAc/F,KAAkBoD,MAA4B;AACxE,QAAI;AACF,UAAIQ,SAAS;AACb,YAAM,EAAErE,UAAUyG,SAAQ,IAAK,KAAKhH;AACpC,UAAIO,UAAU;AAEZ,cAAM0G,MAAMnF,kBAAAA,QAAK6B,KAAKpD,UAAUS,IAAIc,IAAI;AACxCvC,oBAAAA,IAAIE,KAAK,QAAQ;UAAEsG,UAAU/E,IAAI9B;UAAI+H;QAAI,GAAA;;;;;;AACzC,cAAMtC,WAAW,MAAMuC,MAAMD,KAAK;UAChCE,QAAQ;UACRC,SAAS;YACP,gBAAgB;UAClB;UACAjF,MAAMkF,KAAKC,UAAUlD,IAAAA;QACvB,CAAA;AAEAQ,iBAASD,SAASC;MACpB,WAAWoC,UAAU;AACnBzH,oBAAAA,IAAIE,KAAK,QAAQ;UAAEsG,UAAU/E,IAAI9B;QAAG,GAAA;;;;;;AACpC0F,iBAAU,MAAMoC,SAAS5C,IAAAA,KAAU;MACrC;AAGA,UAAIQ,UAAUA,UAAU,KAAK;AAC3B,cAAM,IAAI3B,MAAM,aAAa2B,MAAAA,EAAQ;MACvC;AAGArF,kBAAAA,IAAIE,KAAK,QAAQ;QAAEsG,UAAU/E,IAAI9B;QAAI0F;MAAO,GAAA;;;;;;AAC5C,aAAOA;IACT,SAASzD,KAAU;AACjB5B,kBAAAA,IAAI6B,MAAM,SAAS;QAAE2E,UAAU/E,IAAI9B;QAAIkC,OAAOD,IAAIoG;MAAQ,GAAA;;;;;;AAC1D,aAAO;IACT;EACF;;;;;;;EASA,MAAcjB,aAAaR,KAAcrH,OAAcuC,KAAkBkC,SAAuB;AAC9F3D,gBAAAA,IAAIE,KAAK,SAAS;MAAEhB,OAAOA,MAAMiB;MAAKwD;IAAQ,GAAA;;;;;;AAC9C,UAAM,EAAEsE,KAAI,IAAKtE;AAEjB,UAAMuE,OAAO,IAAIC,2BAAa5B,KAAK,YAAA;AACjC,YAAM,KAAKiB,cAAc/F,KAAK;QAAEtC,UAAUD,MAAMiB;MAAI,CAAA;IACtD,CAAA;AAEA,QAAIiI,OAAO;AACX,QAAIC,MAAM;AAEV,UAAMC,MAAMC,oBAAQhJ,KAAK;MACvBiJ,UAAUP;MACVQ,WAAW;MACXC,QAAQ,MAAA;AAEN,cAAM5D,MAAMC,KAAKD,IAAG;AACpB,cAAM6D,QAAQP,OAAOtD,MAAMsD,OAAO;AAClCA,eAAOtD;AAEPuD;AACArI,oBAAAA,IAAIE,KAAK,QAAQ;UAAEhB,OAAOA,MAAMiB,IAAIC,SAAQ;UAAIwI,OAAOP;UAAKM;QAAM,GAAA;;;;;;AAClET,aAAKW,SAAQ;MACf;IACF,CAAA;AAEAP,QAAIxG,MAAK;AACTyE,QAAIuC,UAAU,MAAMR,IAAI7E,KAAI,CAAA;EAC9B;;;;EAKA,MAAcwD,eAAeV,KAAcrH,OAAcuC,KAAkBkC,SAAyB;AAClG3D,gBAAAA,IAAIE,KAAK,WAAW;MAAEhB,OAAOA,MAAMiB;MAAKwD;IAAQ,GAAA;;;;;;AAGhD,UAAMoF,SAASC,iBAAAA,QAAKC,aAAa,OAAO5G,KAAKC,QAAAA;AAC3C,UAAID,IAAIuF,WAAWjE,QAAQiE,QAAQ;AACjCtF,YAAII,aAAa;AACjB,eAAOJ,IAAIO,IAAG;MAChB;AAEAP,UAAII,aAAa,MAAM,KAAK8E,cAAc/F,KAAK;QAAEtC,UAAUD,MAAMiB;MAAI,CAAA;AACrEmC,UAAIO,IAAG;IACT,CAAA;AAKA,UAAMI,OAAO,UAAMF,wBAAAA,SAAQ;MACzBmG,QAAQ;IAEV,CAAA;AAGAH,WAAO5F,OAAOF,MAAM,MAAA;AAClBjD,kBAAAA,IAAIE,KAAK,mBAAmB;QAAE+C;MAAK,GAAA;;;;;;AACnCU,cAAQV,OAAOA;IACjB,CAAA;AAEAsD,QAAIuC,UAAU,MAAA;AACZC,aAAOlF,MAAK;IACd,CAAA;EACF;;;;;EAMA,MAAcsD,iBACZZ,KACArH,OACAuC,KACAkC,SACAwF,UAGI;IACFC,YAAY;IACZC,aAAa;EACf,GACA;AACArJ,gBAAAA,IAAIE,KAAK,aAAa;MAAEhB,OAAOA,MAAMiB;MAAKwD;IAAQ,GAAA;;;;;;AAClD,UAAM,EAAE+D,IAAG,IAAK/D;AAEhB,QAAI2F;AACJ,aAASC,UAAU,GAAGA,WAAWJ,QAAQE,aAAaE,WAAW;AAC/D,YAAMC,OAAO,IAAI5F,cAAAA,QAAAA;AAEjB0F,WAAK,IAAIG,UAAAA,QAAU/B,GAAAA;AACnBpG,aAAOoI,OAAOJ,IAAI;QAChBK,QAAQ,MAAA;AACN3J,sBAAAA,IAAIE,KAAK,UAAU;YAAEwH;UAAI,GAAA;;;;;;AACzB,cAAI/D,QAAQiG,MAAM;AAChBN,eAAGO,KAAK,IAAIC,YAAAA,EAAcC,OAAOjC,KAAKC,UAAUpE,QAAQiG,IAAI,CAAA,CAAA;UAC9D;AAEAJ,eAAKzF,KAAK,IAAA;QACZ;;QAGAiG,SAAS,CAAClL,UAAAA;AACRkB,sBAAAA,IAAIE,KAAK,UAAU;YAAEwH;YAAKpC,MAAMxG,MAAMwG;UAAK,GAAA;;;;;;AAC3CkE,eAAKzF,KAAK,KAAA;QACZ;QAEAkG,SAAS,CAACnL,UAAAA;AACRkB,sBAAAA,IAAI8C,MAAMhE,MAAM+C,OAAO;YAAE6F;UAAI,GAAA;;;;;;QAC/B;QAEAwC,WAAW,OAAOpL,UAAAA;AAChB,cAAI;AACF,kBAAM+F,OAAOiD,KAAKqC,MAAM,IAAIC,YAAAA,EAAcC,OAAOvL,MAAM+F,IAAI,CAAA;AAC3D,kBAAM,KAAK2C,cAAc/F,KAAK;cAAEtC,UAAUD,MAAMiB;cAAK0E;YAAK,CAAA;UAC5D,SAASjD,KAAK;AACZ5B,wBAAAA,IAAI8C,MAAMlB,KAAK;cAAE8F;YAAI,GAAA;;;;;;UACvB;QACF;MACF,CAAA;AAEA,YAAM4C,SAAS,MAAMd,KAAKvF,KAAI;AAC9B,UAAIqG,QAAQ;AACV;MACF,OAAO;AACL,cAAMrG,OAAOsG,KAAKC,IAAIjB,SAAS,CAAA,IAAKJ,QAAQC;AAC5C,YAAIG,UAAUJ,QAAQE,aAAa;AACjCrJ,sBAAAA,IAAIC,KAAK,sCAAsCgE,IAAAA,KAAS;YAAEsF;UAAQ,GAAA;;;;;;AAClE,oBAAMkB,qBAAMxG,OAAO,GAAA;QACrB;MACF;IACF;AAEAsC,QAAIuC,UAAU,MAAA;AACZQ,UAAIzF,MAAAA;IACN,CAAA;EACF;;;;EAKA,MAAcwD,oBAAoBd,KAAcrH,OAAcuC,KAAkBkC,SAA8B;AAC5G3D,gBAAAA,IAAIE,KAAK,gBAAgB;MAAEhB,OAAOA,MAAMiB;MAAKwD;IAAQ,GAAA;;;;;;AACrD,UAAM+G,YAAY,oBAAIC,IAAAA;AACtB,UAAMzC,OAAO,IAAIC,2BAAa5B,KAAK,YAAA;AACjC,YAAM,KAAKiB,cAAc/F,KAAK;QAAEtC,UAAUD,MAAMiB;QAAKV,SAASoG,MAAMtG,KAAKmL,SAAAA;MAAW,CAAA;IACtF,CAAA;AAIA,UAAME,gBAAgC,CAAA;AACtC,UAAMxD,mBAAeyD,gCAAmB,CAAC,EAAEC,OAAOC,QAAO,MAAE;AACzD/K,kBAAAA,IAAIE,KAAK,WAAW;QAAE4K,OAAOA,MAAMzK;QAAQ0K,SAASA,QAAQ1K;MAAO,GAAA;;;;;;AACnE,iBAAW2K,UAAUF,OAAO;AAC1BJ,kBAAUO,IAAID,OAAOrL,EAAE;MACzB;AACA,iBAAWqL,UAAUD,SAAS;AAC5BL,kBAAUO,IAAID,OAAOrL,EAAE;MACzB;AAEAuI,WAAKW,SAAQ;IACf,CAAA;AAEA+B,kBAAc5E,KAAK,MAAMoB,aAAa8D,YAAW,CAAA;AAIjD,UAAM,EAAEpL,QAAQqJ,SAAS,EAAEgC,MAAMC,MAAK,IAAK,CAAC,EAAC,IAAKzH;AAClD,UAAM/C,SAAS,CAAC,EAAEnB,QAAO,MAAS;AAChC2H,mBAAaxG,OAAOnB,OAAAA;AAGpB,UAAI0L,MAAM;AACRnL,oBAAAA,IAAIE,KAAK,UAAU;UAAET,SAASA,QAAQY;QAAO,GAAA;;;;;;AAC7C,mBAAW2K,UAAUvL,SAAS;AAC5B,gBAAM4L,UAAUL,OAAOK;AACvB,cAAIA,mBAAmBC,yBAAY;AACjCV,0BAAc5E,SACZuF,oCAAuBF,OAAAA,EAASG,QAAQC,OAAGC,wBAAS,MAAMtE,aAAaxG,OAAO;cAACoK;aAAO,GAAG,GAAA,CAAA,CAAA;UAE7F;QACF;MACF;IACF;AAKA,UAAMW,QAAQzM,MAAMU,GAAG+L,MAAMC,mBAAOC,GAAG/L,OAAOJ,IAAI,CAAC,EAAEoM,MAAMC,MAAK,MAAOH,mBAAOI,SAASF,MAAMC,KAAAA,CAAAA,CAAAA,CAAAA;AAC7FnB,kBAAc5E,KAAK2F,MAAM1F,UAAUmF,YAAQM,wBAAS9K,QAAQwK,KAAAA,IAASxK,MAAAA,CAAAA;AAErE2F,QAAIuC,UAAU,MAAA;AACZ8B,oBAAclG,QAAQ,CAACwG,gBAAgBA,YAAAA,CAAAA;IACzC,CAAA;EACF;AACF;ACrWA,IAAMe,qBAAuBC,EAAAA,OAAO;EAClCjE,MAAQkE,EAAAA;AACV,CAAA;AAEA,IAAMC,uBAAyBC,EAAAA,QAC3BH,EAAAA,OAAO;EACPtE,QAAUuE,EAAAA;;EAEVlJ,MAAQqJ,EAAAA,SAAWC,EAAAA,MAAM;AAC3B,CAAA,CAAA;AAGF,IAAMC,yBAA2BN,EAAAA,OAAO;EACtCxE,KAAOyE,EAAAA;EACPvC,MAAQ0C,EAAAA,SAAWG,EAAAA,OAASN,EAAAA,QAAUO,EAAAA,GAAG,CAAA;AAC3C,CAAA;AAEA,IAAMC,4BAA8BT,EAAAA,OAAO;EACzC/M,UAAYmN,EAAAA,SAAWH,EAAAA,MAAM;;EAE7BrM,QAAU8M,EAAAA,MACNV,EAAAA,OAAO;IACPJ,MAAQK,EAAAA;IACRJ,OAASO,EAAAA,SAAWG,EAAAA,OAASN,EAAAA,QAAUO,EAAAA,GAAG,CAAA;EAC5C,CAAA,CAAA;EAEFvD,SAAWmD,EAAAA,SACPJ,EAAAA,OAAO;;IAEPf,MAAQmB,EAAAA,SAAWO,EAAAA,OAAO;;IAE1BzB,OAASkB,EAAAA,SAAWC,EAAAA,MAAM;EAC5B,CAAA,CAAA;AAEJ,CAAA;AAEA,IAAMO,wBAA0BZ,EAAAA,OAAO;EACrC1F,UAAY2F,EAAAA,OAAOY,KAAOC,EAAAA,YAAY,kBAAA,CAAA;;EAGtCjO,SAAWuN,EAAAA,SAAWG,EAAAA,OAASN,EAAAA,QAAUO,EAAAA,GAAG,CAAA;;EAG5C5F,OAASwF,EAAAA,SAASL,kBAAAA;EAClBjF,SAAWsF,EAAAA,SAASF,oBAAAA;EACpBlF,WAAaoF,EAAAA,SAASE,sBAAAA;EACtBpF,cAAgBkF,EAAAA,SAASK,yBAAAA;AAC3B,CAAA;AAYA,IAAMM,oBAAsBf,EAAAA,OAAO;EACjCvM,IAAMwM,EAAAA;;EAENa,aAAeV,EAAAA,SAAWH,EAAAA,MAAM;EAChC5J,MAAQ4J,EAAAA;;EAERtN,SAAWsN,EAAAA;AACb,CAAA;AAOO,IAAMe,yBAA2BhB,EAAAA,OAAO;EAC7C7K,WAAagL,EAAAA,QAAUO,EAAAA,MAAMK,iBAAAA,CAAAA;EAC7B9G,UAAYmG,EAAAA,SAAWD,EAAAA,QAAUO,EAAAA,MAAME,qBAAAA,CAAAA,CAAAA;AACzC,CAAA;",
6
+ "names": ["import_log", "import_get_port_please", "import_node_path", "import_async", "import_invariant", "import_util", "subscriptionHandler", "handler", "event", "context", "rest", "client", "space", "spaceKey", "spaces", "get", "PublicKey", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "nonNullable", "log", "warn", "info", "key", "truncate", "length", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "update", "Event", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "error", "start", "_server", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "statusCode", "invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "register", "_functionServiceRegistration", "stop", "Error", "trigger", "Trigger", "close", "unregister", "wake", "throw", "wait", "force", "filePath", "join", "baseDir", "keys", "require", "cache", "startsWith", "forEach", "module", "default", "data", "now", "Date", "_invoke", "duration", "emit", "dataDir", "response", "status", "code", "Scheduler", "_manifest", "_mounts", "ComplexMap", "toHex", "mounts", "Array", "reduce", "acc", "push", "subscribe", "waitUntilReady", "triggers", "mount", "Context", "unmount", "ctx", "function", "find", "config", "exists", "set", "disposed", "timer", "_createTimer", "webhook", "_createWebhook", "websocket", "_createWebsocket", "subscription", "_createSubscription", "delete", "dispose", "_execFunction", "callback", "url", "fetch", "method", "headers", "JSON", "stringify", "message", "cron", "task", "DeferredTask", "last", "run", "job", "CronJob", "cronTime", "runOnInit", "onTick", "delta", "count", "schedule", "onDispose", "server", "http", "createServer", "random", "options", "retryDelay", "maxAttempts", "ws", "attempt", "open", "WebSocket", "assign", "onopen", "init", "send", "TextEncoder", "encode", "onclose", "onerror", "onmessage", "parse", "TextDecoder", "decode", "isOpen", "Math", "pow", "sleep", "objectIds", "Set", "subscriptions", "createSubscription", "added", "updated", "object", "add", "unsubscribe", "deep", "delay", "content", "TextV0Type", "getAutomergeObjectCore", "updates", "on", "debounce", "query", "Filter", "or", "type", "props", "typename", "TimerTriggerSchema", "struct", "string", "WebhookTriggerSchema", "mutable", "optional", "number", "WebsocketTriggerSchema", "record", "any", "SubscriptionTriggerSchema", "array", "boolean", "FunctionTriggerSchema", "pipe", "description", "FunctionDefSchema", "FunctionManifestSchema"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":6874,"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}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":24379,"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":44375,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"node:path","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}],"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/types.ts":{"bytes":7861,"imports":[{"path":"@effect/schema/Schema","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"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":38886},"packages/core/functions/dist/lib/node/index.cjs":{"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":"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":"get-port-please","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"node:path","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":{"packages/core/functions/src/handler.ts":{"bytesInOutput":1124},"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":6955},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":11362},"packages/core/functions/src/types.ts":{"bytesInOutput":1528}},"bytes":21650}}}
1
+ {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":6222,"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}],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":24275,"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":42172,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"node:path","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}],"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/types.ts":{"bytes":7769,"imports":[{"path":"@effect/schema/Schema","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"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":37428},"packages/core/functions/dist/lib/node/index.cjs":{"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":"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":"get-port-please","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"node:path","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":{"packages/core/functions/src/handler.ts":{"bytesInOutput":1066},"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":6941},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":10823},"packages/core/functions/src/types.ts":{"bytesInOutput":1498}},"bytes":21009}}}