@dxos/functions 0.5.3-main.bc67fdb → 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.
@@ -20,16 +20,16 @@ import { log } from "@dxos/log";
20
20
  import { nonNullable } from "@dxos/util";
21
21
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/handler.ts";
22
22
  var subscriptionHandler = (handler) => {
23
- return ({ event: { data }, context, ...rest }) => {
23
+ return ({ event, context, ...rest }) => {
24
24
  const { client } = context;
25
- const space = data.spaceKey ? client.spaces.get(PublicKey.from(data.spaceKey)) : void 0;
26
- const objects = space ? data.objects?.map((id) => space.db.getObjectById(id)).filter(nonNullable) : [];
27
- if (!!data.spaceKey && !space) {
25
+ const space = event.spaceKey ? client.spaces.get(PublicKey.from(event.spaceKey)) : void 0;
26
+ const objects = space && event.objects?.map((id) => space.db.getObjectById(id)).filter(nonNullable);
27
+ if (!!event.spaceKey && !space) {
28
28
  log.warn("invalid space", {
29
- data
29
+ event
30
30
  }, {
31
31
  F: __dxlog_file,
32
- L: 91,
32
+ L: 68,
33
33
  S: void 0,
34
34
  C: (f, a) => f(...a)
35
35
  });
@@ -39,18 +39,15 @@ var subscriptionHandler = (handler) => {
39
39
  objects: objects?.length
40
40
  }, {
41
41
  F: __dxlog_file,
42
- L: 93,
42
+ L: 70,
43
43
  S: void 0,
44
44
  C: (f, a) => f(...a)
45
45
  });
46
46
  }
47
47
  return handler({
48
48
  event: {
49
- data: {
50
- ...data,
51
- space,
52
- objects
53
- }
49
+ space,
50
+ objects
54
51
  },
55
52
  context,
56
53
  ...rest
@@ -306,9 +303,7 @@ var DevServer = class {
306
303
  S: this,
307
304
  C: (f, a) => f(...a)
308
305
  });
309
- const statusCode = await this._invoke(path2, {
310
- data
311
- });
306
+ const statusCode = await this._invoke(path2, data);
312
307
  log2.info("res", {
313
308
  seq,
314
309
  path: path2,
@@ -407,7 +402,7 @@ var Scheduler = class {
407
402
  const def = this._manifest.functions.find((config) => config.id === trigger.function);
408
403
  invariant2(def, `Function not found: ${trigger.function}`, {
409
404
  F: __dxlog_file3,
410
- L: 76,
405
+ L: 83,
411
406
  S: this,
412
407
  A: [
413
408
  "def",
@@ -425,7 +420,7 @@ var Scheduler = class {
425
420
  trigger
426
421
  }, {
427
422
  F: __dxlog_file3,
428
- L: 82,
423
+ L: 89,
429
424
  S: this,
430
425
  C: (f, a) => f(...a)
431
426
  });
@@ -433,16 +428,16 @@ var Scheduler = class {
433
428
  return;
434
429
  }
435
430
  if (trigger.timer) {
436
- await this._createTimer(ctx, space, def, trigger);
431
+ await this._createTimer(ctx, space, def, trigger.timer);
437
432
  }
438
433
  if (trigger.webhook) {
439
- await this._createWebhook(ctx, space, def, trigger);
434
+ await this._createWebhook(ctx, space, def, trigger.webhook);
440
435
  }
441
436
  if (trigger.websocket) {
442
- await this._createWebsocket(ctx, space, def, trigger);
437
+ await this._createWebsocket(ctx, space, def, trigger.websocket);
443
438
  }
444
439
  if (trigger.subscription) {
445
- await this._createSubscription(ctx, space, def, trigger);
440
+ await this._createSubscription(ctx, space, def, trigger.subscription);
446
441
  }
447
442
  }
448
443
  }
@@ -457,12 +452,10 @@ var Scheduler = class {
457
452
  await ctx.dispose();
458
453
  }
459
454
  }
460
- async _execFunction(def, trigger, data) {
461
- let status = 0;
455
+ // TODO(burdon): Pass in Space key (common context).
456
+ async _execFunction(def, data) {
462
457
  try {
463
- const payload = Object.assign({}, {
464
- meta: trigger.meta
465
- }, data);
458
+ let status = 0;
466
459
  const { endpoint, callback } = this._options;
467
460
  if (endpoint) {
468
461
  const url = path.join(endpoint, def.path);
@@ -471,7 +464,7 @@ var Scheduler = class {
471
464
  url
472
465
  }, {
473
466
  F: __dxlog_file3,
474
- L: 128,
467
+ L: 133,
475
468
  S: this,
476
469
  C: (f, a) => f(...a)
477
470
  });
@@ -480,7 +473,7 @@ var Scheduler = class {
480
473
  headers: {
481
474
  "Content-Type": "application/json"
482
475
  },
483
- body: JSON.stringify(payload)
476
+ body: JSON.stringify(data)
484
477
  });
485
478
  status = response.status;
486
479
  } else if (callback) {
@@ -488,11 +481,11 @@ var Scheduler = class {
488
481
  function: def.id
489
482
  }, {
490
483
  F: __dxlog_file3,
491
- L: 139,
484
+ L: 144,
492
485
  S: this,
493
486
  C: (f, a) => f(...a)
494
487
  });
495
- status = await callback(payload) ?? 200;
488
+ status = await callback(data) ?? 200;
496
489
  }
497
490
  if (status && status >= 400) {
498
491
  throw new Error(`Response: ${status}`);
@@ -502,23 +495,23 @@ var Scheduler = class {
502
495
  status
503
496
  }, {
504
497
  F: __dxlog_file3,
505
- L: 149,
498
+ L: 154,
506
499
  S: this,
507
500
  C: (f, a) => f(...a)
508
501
  });
502
+ return status;
509
503
  } catch (err) {
510
504
  log3.error("error", {
511
505
  function: def.id,
512
506
  error: err.message
513
507
  }, {
514
508
  F: __dxlog_file3,
515
- L: 151,
509
+ L: 157,
516
510
  S: this,
517
511
  C: (f, a) => f(...a)
518
512
  });
519
- status = 500;
513
+ return 500;
520
514
  }
521
- return status;
522
515
  }
523
516
  //
524
517
  // Triggers
@@ -532,20 +525,20 @@ var Scheduler = class {
532
525
  trigger
533
526
  }, {
534
527
  F: __dxlog_file3,
535
- L: 166,
528
+ L: 170,
536
529
  S: this,
537
530
  C: (f, a) => f(...a)
538
531
  });
539
- const spec = trigger.timer;
532
+ const { cron } = trigger;
540
533
  const task = new DeferredTask(ctx, async () => {
541
- await this._execFunction(def, trigger, {
534
+ await this._execFunction(def, {
542
535
  spaceKey: space.key
543
536
  });
544
537
  });
545
538
  let last = 0;
546
539
  let run = 0;
547
540
  const job = CronJob.from({
548
- cronTime: spec.cron,
541
+ cronTime: cron,
549
542
  runOnInit: false,
550
543
  onTick: () => {
551
544
  const now = Date.now();
@@ -558,7 +551,7 @@ var Scheduler = class {
558
551
  delta
559
552
  }, {
560
553
  F: __dxlog_file3,
561
- L: 186,
554
+ L: 190,
562
555
  S: this,
563
556
  C: (f, a) => f(...a)
564
557
  });
@@ -577,17 +570,16 @@ var Scheduler = class {
577
570
  trigger
578
571
  }, {
579
572
  F: __dxlog_file3,
580
- L: 199,
573
+ L: 203,
581
574
  S: this,
582
575
  C: (f, a) => f(...a)
583
576
  });
584
- const spec = trigger.webhook;
585
577
  const server = http.createServer(async (req, res) => {
586
- if (req.method !== spec.method) {
578
+ if (req.method !== trigger.method) {
587
579
  res.statusCode = 405;
588
580
  return res.end();
589
581
  }
590
- res.statusCode = await this._execFunction(def, trigger, {
582
+ res.statusCode = await this._execFunction(def, {
591
583
  spaceKey: space.key
592
584
  });
593
585
  res.end();
@@ -600,11 +592,11 @@ var Scheduler = class {
600
592
  port
601
593
  }, {
602
594
  F: __dxlog_file3,
603
- L: 223,
595
+ L: 226,
604
596
  S: this,
605
597
  C: (f, a) => f(...a)
606
598
  });
607
- spec.port = port;
599
+ trigger.port = port;
608
600
  });
609
601
  ctx.onDispose(() => {
610
602
  server.close();
@@ -623,12 +615,11 @@ var Scheduler = class {
623
615
  trigger
624
616
  }, {
625
617
  F: __dxlog_file3,
626
- L: 249,
618
+ L: 252,
627
619
  S: this,
628
620
  C: (f, a) => f(...a)
629
621
  });
630
- const spec = trigger.websocket;
631
- const { url, init } = spec;
622
+ const { url } = trigger;
632
623
  let ws;
633
624
  for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
634
625
  const open = new Trigger2();
@@ -639,38 +630,26 @@ var Scheduler = class {
639
630
  url
640
631
  }, {
641
632
  F: __dxlog_file3,
642
- L: 260,
633
+ L: 262,
643
634
  S: this,
644
635
  C: (f, a) => f(...a)
645
636
  });
646
- if (spec.init) {
647
- ws.send(new TextEncoder().encode(JSON.stringify(init)));
637
+ if (trigger.init) {
638
+ ws.send(new TextEncoder().encode(JSON.stringify(trigger.init)));
648
639
  }
649
640
  open.wake(true);
650
641
  },
642
+ // TODO(burdon): Config retry if server closes?
651
643
  onclose: (event) => {
652
644
  log3.info("closed", {
653
645
  url,
654
646
  code: event.code
655
647
  }, {
656
648
  F: __dxlog_file3,
657
- L: 269,
649
+ L: 272,
658
650
  S: this,
659
651
  C: (f, a) => f(...a)
660
652
  });
661
- if (event.code === 1006) {
662
- setTimeout(async () => {
663
- log3.info(`reconnecting in ${options.retryDelay}s...`, {
664
- url
665
- }, {
666
- F: __dxlog_file3,
667
- L: 274,
668
- S: this,
669
- C: (f, a) => f(...a)
670
- });
671
- await this._createWebsocket(ctx, space, def, trigger, options);
672
- }, options.retryDelay * 1e3);
673
- }
674
653
  open.wake(false);
675
654
  },
676
655
  onerror: (event) => {
@@ -678,7 +657,7 @@ var Scheduler = class {
678
657
  url
679
658
  }, {
680
659
  F: __dxlog_file3,
681
- L: 283,
660
+ L: 277,
682
661
  S: this,
683
662
  C: (f, a) => f(...a)
684
663
  });
@@ -686,7 +665,7 @@ var Scheduler = class {
686
665
  onmessage: async (event) => {
687
666
  try {
688
667
  const data = JSON.parse(new TextDecoder().decode(event.data));
689
- await this._execFunction(def, trigger, {
668
+ await this._execFunction(def, {
690
669
  spaceKey: space.key,
691
670
  data
692
671
  });
@@ -695,7 +674,7 @@ var Scheduler = class {
695
674
  url
696
675
  }, {
697
676
  F: __dxlog_file3,
698
- L: 291,
677
+ L: 285,
699
678
  S: this,
700
679
  C: (f, a) => f(...a)
701
680
  });
@@ -712,7 +691,7 @@ var Scheduler = class {
712
691
  attempt
713
692
  }, {
714
693
  F: __dxlog_file3,
715
- L: 302,
694
+ L: 296,
716
695
  S: this,
717
696
  C: (f, a) => f(...a)
718
697
  });
@@ -733,14 +712,13 @@ var Scheduler = class {
733
712
  trigger
734
713
  }, {
735
714
  F: __dxlog_file3,
736
- L: 317,
715
+ L: 311,
737
716
  S: this,
738
717
  C: (f, a) => f(...a)
739
718
  });
740
- const spec = trigger.subscription;
741
719
  const objectIds = /* @__PURE__ */ new Set();
742
720
  const task = new DeferredTask(ctx, async () => {
743
- await this._execFunction(def, trigger, {
721
+ await this._execFunction(def, {
744
722
  spaceKey: space.key,
745
723
  objects: Array.from(objectIds)
746
724
  });
@@ -752,7 +730,7 @@ var Scheduler = class {
752
730
  updated: updated.length
753
731
  }, {
754
732
  F: __dxlog_file3,
755
- L: 329,
733
+ L: 321,
756
734
  S: this,
757
735
  C: (f, a) => f(...a)
758
736
  });
@@ -765,7 +743,7 @@ var Scheduler = class {
765
743
  task.schedule();
766
744
  });
767
745
  subscriptions.push(() => subscription.unsubscribe());
768
- const { filter, options: { deep, delay } = {} } = spec;
746
+ const { filter, options: { deep, delay } = {} } = trigger;
769
747
  const update = ({ objects }) => {
770
748
  subscription.update(objects);
771
749
  if (deep) {
@@ -773,7 +751,7 @@ var Scheduler = class {
773
751
  objects: objects.length
774
752
  }, {
775
753
  F: __dxlog_file3,
776
- L: 349,
754
+ L: 342,
777
755
  S: this,
778
756
  C: (f, a) => f(...a)
779
757
  });
@@ -826,7 +804,7 @@ var SubscriptionTriggerSchema = S.struct({
826
804
  var FunctionTriggerSchema = S.struct({
827
805
  function: S.string.pipe(S.description("Function ID/URI.")),
828
806
  // Context passed to function.
829
- meta: S.optional(S.record(S.string, S.any)),
807
+ context: S.optional(S.record(S.string, S.any)),
830
808
  // Triggers.
831
809
  timer: S.optional(TimerTriggerSchema),
832
810
  webhook: S.optional(WebhookTriggerSchema),
@@ -837,7 +815,6 @@ var FunctionDefSchema = S.struct({
837
815
  id: S.string,
838
816
  // name: S.string,
839
817
  description: S.optional(S.string),
840
- // TODO(burdon): Rename route?
841
818
  path: S.string,
842
819
  // TODO(burdon): NPM/GitHub/Docker/CF URL?
843
820
  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": ["PublicKey", "log", "nonNullable", "subscriptionHandler", "handler", "event", "data", "context", "rest", "client", "space", "spaceKey", "spaces", "get", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "warn", "info", "key", "truncate", "length", "express", "getPort", "join", "Event", "Trigger", "invariant", "log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "update", "Event", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "_server", "info", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "statusCode", "invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "id", "_functionServiceRegistration", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "throw", "wait", "force", "handler", "filePath", "join", "baseDir", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "data", "now", "Date", "_invoke", "duration", "emit", "event", "context", "client", "dataDir", "response", "status", "code", "CronJob", "getPort", "http", "path", "WebSocket", "TextV0Type", "debounce", "DeferredTask", "sleep", "Trigger", "createSubscription", "Filter", "getAutomergeObjectCore", "Context", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "spaceKey", "id", "toHex", "mounts", "Array", "from", "values", "reduce", "acc", "trigger", "push", "start", "spaces", "subscribe", "space", "waitUntilReady", "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", "status", "payload", "Object", "assign", "meta", "endpoint", "callback", "url", "join", "info", "response", "fetch", "method", "headers", "body", "JSON", "stringify", "Error", "err", "error", "message", "spec", "task", "last", "run", "job", "cronTime", "cron", "runOnInit", "onTick", "now", "Date", "delta", "truncate", "count", "schedule", "onDispose", "server", "createServer", "req", "res", "statusCode", "end", "port", "random", "listen", "close", "options", "retryDelay", "maxAttempts", "init", "ws", "attempt", "open", "onopen", "send", "TextEncoder", "encode", "wake", "onclose", "event", "code", "setTimeout", "onerror", "catch", "onmessage", "parse", "TextDecoder", "decode", "isOpen", "wait", "Math", "pow", "warn", "objectIds", "Set", "objects", "subscriptions", "added", "updated", "length", "object", "add", "unsubscribe", "filter", "deep", "delay", "update", "content", "updates", "on", "query", "db", "or", "map", "type", "props", "typename", "forEach", "S", "TimerTriggerSchema", "struct", "cron", "string", "WebhookTriggerSchema", "mutable", "method", "port", "optional", "number", "WebsocketTriggerSchema", "url", "init", "record", "any", "SubscriptionTriggerSchema", "spaceKey", "filter", "array", "type", "props", "options", "deep", "boolean", "delay", "FunctionTriggerSchema", "function", "pipe", "description", "meta", "timer", "webhook", "websocket", "subscription", "FunctionDefSchema", "id", "path", "handler", "FunctionManifestSchema", "functions", "triggers"]
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": "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",
6
+ "names": ["PublicKey", "log", "nonNullable", "subscriptionHandler", "handler", "event", "context", "rest", "client", "space", "spaceKey", "spaces", "get", "from", "undefined", "objects", "map", "id", "db", "getObjectById", "filter", "warn", "info", "key", "truncate", "length", "express", "getPort", "join", "Event", "Trigger", "invariant", "log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "update", "Event", "stats", "seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "_server", "info", "app", "express", "use", "json", "post", "req", "res", "path", "params", "reload", "statusCode", "invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "id", "_functionServiceRegistration", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "throw", "wait", "force", "handler", "filePath", "join", "baseDir", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "data", "now", "Date", "_invoke", "duration", "emit", "event", "context", "client", "dataDir", "response", "status", "code", "CronJob", "getPort", "http", "path", "WebSocket", "TextV0Type", "debounce", "DeferredTask", "sleep", "Trigger", "createSubscription", "Filter", "getAutomergeObjectCore", "Context", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "spaceKey", "id", "toHex", "mounts", "Array", "from", "values", "reduce", "acc", "trigger", "push", "start", "spaces", "subscribe", "space", "waitUntilReady", "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", "status", "endpoint", "callback", "url", "join", "info", "response", "fetch", "method", "headers", "body", "JSON", "stringify", "Error", "err", "error", "message", "cron", "task", "last", "run", "job", "cronTime", "runOnInit", "onTick", "now", "Date", "delta", "truncate", "count", "schedule", "onDispose", "server", "createServer", "req", "res", "statusCode", "end", "port", "random", "listen", "close", "options", "retryDelay", "maxAttempts", "ws", "attempt", "open", "Object", "assign", "onopen", "init", "send", "TextEncoder", "encode", "wake", "onclose", "event", "code", "onerror", "catch", "onmessage", "parse", "TextDecoder", "decode", "isOpen", "wait", "Math", "pow", "warn", "objectIds", "Set", "objects", "subscriptions", "added", "updated", "length", "object", "add", "unsubscribe", "filter", "deep", "delay", "update", "content", "updates", "on", "query", "db", "or", "map", "type", "props", "typename", "forEach", "S", "TimerTriggerSchema", "struct", "cron", "string", "WebhookTriggerSchema", "mutable", "method", "port", "optional", "number", "WebsocketTriggerSchema", "url", "init", "record", "any", "SubscriptionTriggerSchema", "spaceKey", "filter", "array", "type", "props", "options", "deep", "boolean", "delay", "FunctionTriggerSchema", "function", "pipe", "description", "context", "timer", "webhook", "websocket", "subscription", "FunctionDefSchema", "id", "path", "handler", "FunctionManifestSchema", "functions", "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":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},{"path":"@inject-globals","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":"@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":44375,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/node-std/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":"@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":7861,"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":38894},"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":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/node-std/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":{"inject-globals:@inject-globals":{"bytesInOutput":90},"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":6965},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":11382},"packages/core/functions/src/types.ts":{"bytesInOutput":1528}},"bytes":21838}}}
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":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},{"path":"@inject-globals","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":"@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":42172,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/node-std/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":"@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":7769,"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":37436},"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":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/http","kind":"import-statement","external":true},{"path":"@dxos/node-std/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":{"inject-globals:@inject-globals":{"bytesInOutput":90},"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":6951},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":10843},"packages/core/functions/src/types.ts":{"bytesInOutput":1498}},"bytes":21197}}}