@dxos/functions 0.3.9-main.14901ff → 0.3.9-main.26defc6

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.
@@ -26,7 +26,7 @@ var DevServer = class {
26
26
  get endpoint() {
27
27
  invariant(this._port, void 0, {
28
28
  F: __dxlog_file,
29
- L: 45,
29
+ L: 46,
30
30
  S: this,
31
31
  A: [
32
32
  "this._port",
@@ -48,7 +48,7 @@ var DevServer = class {
48
48
  } catch (err) {
49
49
  log.error("parsing function (check manifest)", err, {
50
50
  F: __dxlog_file,
51
- L: 62,
51
+ L: 63,
52
52
  S: this,
53
53
  C: (f, a) => f(...a)
54
54
  });
@@ -70,7 +70,7 @@ var DevServer = class {
70
70
  } catch (err) {
71
71
  log.catch(err, void 0, {
72
72
  F: __dxlog_file,
73
- L: 82,
73
+ L: 83,
74
74
  S: this,
75
75
  C: (f, a) => f(...a)
76
76
  });
@@ -98,7 +98,7 @@ var DevServer = class {
98
98
  endpoint
99
99
  }, {
100
100
  F: __dxlog_file,
101
- L: 98,
101
+ L: 99,
102
102
  S: this,
103
103
  C: (f, a) => f(...a)
104
104
  });
@@ -120,7 +120,7 @@ var DevServer = class {
120
120
  registrationId: this._registrationId
121
121
  }, {
122
122
  F: __dxlog_file,
123
- L: 115,
123
+ L: 116,
124
124
  S: this,
125
125
  C: (f, a) => f(...a)
126
126
  });
@@ -143,7 +143,7 @@ var DevServer = class {
143
143
  id
144
144
  }, {
145
145
  F: __dxlog_file,
146
- L: 134,
146
+ L: 135,
147
147
  S: this,
148
148
  C: (f, a) => f(...a)
149
149
  });
@@ -170,13 +170,14 @@ var DevServer = class {
170
170
  name
171
171
  }, {
172
172
  F: __dxlog_file,
173
- L: 159,
173
+ L: 160,
174
174
  S: this,
175
175
  C: (f, a) => f(...a)
176
176
  });
177
177
  const { handler } = this._handlers[name];
178
178
  const context = {
179
- client: this._client
179
+ client: this._client,
180
+ dataDir: this._options.dataDir
180
181
  };
181
182
  let statusCode = 200;
182
183
  const response = {
@@ -197,7 +198,7 @@ var DevServer = class {
197
198
  duration: Date.now() - now
198
199
  }, {
199
200
  F: __dxlog_file,
200
- L: 175,
201
+ L: 177,
201
202
  S: this,
202
203
  C: (f, a) => f(...a)
203
204
  });
@@ -258,7 +259,7 @@ var Scheduler = class {
258
259
  ctx,
259
260
  trigger
260
261
  });
261
- log2.info("mount", {
262
+ log2("mount", {
262
263
  space: space.key,
263
264
  trigger
264
265
  }, {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ port: 7200, portRange: [7200, 7299] });\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, TextObject } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription, type Query, subscribe } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../manifest';\n\ntype SchedulerOptions = {\n endpoint: string;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions,\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log.info('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Cron schedule.\n if (trigger.schedule) {\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n });\n });\n\n // TODO(burdon): Check greater than 30s min (use cron-parser).\n const job = new CronJob(trigger.schedule, () => task.schedule());\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n // ECHO subscription.\n if (trigger.subscription) {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n const { type, props, deep, delay } = trigger.subscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextObject) {\n subscriptions.push(content[subscribe](debounce(() => subscription.update([object]), 1_000)));\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private async execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n // const result = await response.json();\n log('result', { function: def.id, result: response.status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["express", "getPort", "join", "Trigger", "invariant", "log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "name", "params", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "info", "_registrationId", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "wait", "flush", "id", "handler", "path", "join", "directory", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "event", "seq", "now", "Date", "context", "client", "response", "status", "code", "duration", "CronJob", "debounce", "DeferredTask", "TextObject", "Context", "Filter", "createSubscription", "subscribe", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "id", "spaceKey", "toHex", "start", "spaces", "space", "waitUntilReady", "trigger", "triggers", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "def", "functions", "find", "config", "exists", "get", "set", "info", "disposed", "schedule", "task", "execFunction", "job", "onDispose", "subscription", "objectIds", "Set", "objects", "Array", "from", "subscriptions", "added", "updated", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "length", "content", "query", "db", "typename", "forEach", "delete", "dispose", "data", "response", "fetch", "endpoint", "name", "method", "headers", "body", "JSON", "stringify", "result", "status", "err", "error", "message"]
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ port: 7200, portRange: [7200, 7299] });\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, TextObject } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription, type Query, subscribe } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../manifest';\n\ntype SchedulerOptions = {\n endpoint: string;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions,\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Cron schedule.\n if (trigger.schedule) {\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n });\n });\n\n // TODO(burdon): Check greater than 30s min (use cron-parser).\n const job = new CronJob(trigger.schedule, () => task.schedule());\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n // ECHO subscription.\n if (trigger.subscription) {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n const { type, props, deep, delay } = trigger.subscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextObject) {\n subscriptions.push(content[subscribe](debounce(() => subscription.update([object]), 1_000)));\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private async execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n // const result = await response.json();\n log('result', { function: def.id, result: response.status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;AAIA,OAAOA,aAAa;AACpB,SAASC,eAAe;AAExB,SAASC,YAAY;AAErB,SAASC,eAAe;AAExB,SAASC,iBAAiB;AAC1B,SAASC,WAAW;;AAgBb,IAAMC,YAAN,MAAMA;;EAWXC,YACmBC,SACAC,UACjB;mBAFiBD;oBACAC;SAXFC,YAAiF,CAAC;SAM3FC,OAAO;EAMZ;EAEH,IAAIC,WAAW;AACbC,cAAU,KAAKC,OAAK,QAAA;;;;;;;;;AACpB,WAAO,oBAAoB,KAAKA,KAAK;EACvC;EAEA,IAAIC,QAAQ;AACV,WAAO,KAAKC;EACd;EAEA,IAAIC,YAAY;AACd,WAAOC,OAAOC,OAAO,KAAKT,SAAS;EACrC;EAEA,MAAMU,aAAa;AACjB,eAAWC,OAAO,KAAKZ,SAASa,SAASL,WAAW;AAClD,UAAI;AACF,cAAM,KAAKM,MAAMF,GAAAA;MACnB,SAASG,KAAK;AACZC,YAAIC,MAAM,qCAAqCF,KAAAA;;;;;;MACjD;IACF;EACF;EAEA,MAAMG,QAAQ;AACZ,UAAMC,MAAMC,QAAAA;AACZD,QAAIE,IAAID,QAAQE,KAAI,CAAA;AAEpBH,QAAII,KAAK,UAAU,OAAOC,KAAKC,QAAAA;AAC7B,YAAM,EAAEC,KAAI,IAAKF,IAAIG;AACrB,UAAI;AACF,YAAI,KAAK3B,SAAS4B,QAAQ;AACxB,gBAAM,EAAEhB,IAAG,IAAK,KAAKX,UAAUyB,IAAAA;AAC/B,gBAAM,KAAKZ,MAAMF,KAAK,IAAA;QACxB;AAEAa,YAAII,aAAa,MAAM,KAAKC,QAAQJ,MAAMF,IAAIO,IAAI;AAClDN,YAAIO,IAAG;MACT,SAASjB,KAAU;AACjBC,YAAIiB,MAAMlB,KAAAA,QAAAA;;;;;;AACVU,YAAII,aAAa;AACjBJ,YAAIO,IAAG;MACT;IACF,CAAA;AAEA,SAAK3B,QAAQ,MAAM6B,QAAQ;MAAEC,MAAM;MAAMC,WAAW;QAAC;QAAM;;IAAM,CAAA;AACjE,SAAKC,UAAUlB,IAAImB,OAAO,KAAKjC,KAAK;AAEpC,QAAI;AAEF,YAAM,EAAEkC,gBAAgBpC,SAAQ,IAAK,MAAM,KAAKJ,QAAQyC,SAASA,SAASC,wBAAyBC,SAAS;QAC1GvC,UAAU,KAAKA;QACfK,WAAW,KAAKA,UAAUmC,IAAI,CAAC,EAAE/B,KAAK,EAAEc,KAAI,EAAE,OAAQ;UAAEA;QAAK,EAAA;MAC/D,CAAA;AAEAV,UAAI4B,KAAK,cAAc;QAAEL;QAAgBpC;MAAS,GAAA;;;;;;AAClD,WAAK0C,kBAAkBN;AACvB,WAAKhC,SAASJ;IAChB,SAASY,KAAU;AACjB,YAAM,KAAK+B,KAAI;AACf,YAAM,IAAIC,MAAM,qEAAA;IAClB;EACF;EAEA,MAAMD,OAAO;AACX,UAAME,UAAU,IAAIC,QAAAA;AACpB,SAAKZ,SAASa,MAAM,YAAA;AAClB,UAAI,KAAKL,iBAAiB;AACxB,cAAM,KAAK9C,QAAQyC,SAASA,SAASC,wBAAyBU,WAAW;UACvEZ,gBAAgB,KAAKM;QACvB,CAAA;AAEA7B,YAAI4B,KAAK,gBAAgB;UAAEL,gBAAgB,KAAKM;QAAgB,GAAA;;;;;;AAChE,aAAKA,kBAAkBO;AACvB,aAAK7C,SAAS6C;MAChB;AAEAJ,cAAQK,KAAI;IACd,CAAA;AAEA,UAAML,QAAQM,KAAI;AAClB,SAAKjD,QAAQ+C;AACb,SAAKf,UAAUe;EACjB;;;;EAKA,MAActC,MAAMF,KAAkB2C,QAAQ,OAAO;AACnD,UAAM,EAAEC,IAAI9B,MAAM+B,QAAO,IAAK7C;AAC9B,UAAM8C,OAAOC,KAAK,KAAK3D,SAAS4D,WAAWH,OAAAA;AAC3CzC,QAAI4B,KAAK,WAAW;MAAEY;IAAG,GAAA;;;;;;AAGzB,QAAID,OAAO;AACT9C,aAAOoD,KAAKC,UAAQC,KAAK,EACtBC,OAAO,CAACC,QAAQA,IAAIC,WAAWR,IAAAA,CAAAA,EAC/BS,QAAQ,CAACF,QAAQ,OAAOH,UAAQC,MAAME,GAAAA,CAAI;IAC/C;AAGA,UAAMG,SAASN,UAAQJ,IAAAA;AACvB,QAAI,OAAOU,OAAOC,YAAY,YAAY;AACxC,YAAM,IAAItB,MAAM,yCAAyCS,EAAAA,EAAI;IAC/D;AAEA,SAAKvD,UAAUyB,IAAAA,IAAQ;MAAEd;MAAK6C,SAASW,OAAOC;IAAQ;EACxD;;;;EAKA,MAAcvC,QAAQJ,MAAc4C,OAAY;AAC9C,UAAMC,MAAM,EAAE,KAAKrE;AACnB,UAAMsE,MAAMC,KAAKD,IAAG;AAEpBxD,QAAI4B,KAAK,OAAO;MAAE2B;MAAK7C;IAAK,GAAA;;;;;;AAC5B,UAAM,EAAE+B,QAAO,IAAK,KAAKxD,UAAUyB,IAAAA;AAEnC,UAAMgD,UAA2B;MAC/BC,QAAQ,KAAK5E;MACb6E,SAAS,KAAK5E,SAAS4E;IACzB;AAEA,QAAI/C,aAAa;AACjB,UAAMgD,WAAqB;MACzBC,QAAQ,CAACC,SAAAA;AACPlD,qBAAakD;AACb,eAAOF;MACT;IACF;AAEA,UAAMpB,QAAQ;MAAEiB;MAASJ;MAAOO;IAAS,CAAA;AACzC7D,QAAI4B,KAAK,OAAO;MAAE2B;MAAK7C;MAAMG;MAAYmD,UAAUP,KAAKD,IAAG,IAAKA;IAAI,GAAA;;;;;;AAEpE,WAAO3C;EACT;AACF;;;AChLA,SAASoD,eAAe;AAExB,SAASC,UAAUC,oBAAoB;AAEvC,SAAqBC,kBAAkB;AACvC,SAASC,eAAe;AACxB,SAASC,QAAQC,oBAAgCC,iBAAiB;AAClE,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,kBAAkB;;AAYpB,IAAMC,YAAN,MAAMA;EAOXC,YACmBC,SACAC,WACAC,UACjB;mBAHiBF;qBACAC;oBACAC;SARFC,UAAU,IAAIN,WAG7B,CAAC,EAAEO,IAAIC,SAAQ,MAAO,GAAGA,SAASC,MAAK,CAAA,IAAMF,EAAAA,EAAI;EAMhD;EAEH,MAAMG,QAAQ;AACZ,SAAKP,QAAQQ,OAAOd,UAAU,OAAOc,WAAAA;AACnC,iBAAWC,SAASD,QAAQ;AAC1B,cAAMC,MAAMC,eAAc;AAC1B,mBAAWC,WAAW,KAAKV,UAAUW,YAAY,CAAA,GAAI;AACnD,gBAAM,KAAKC,MAAM,IAAItB,QAAAA,GAAWkB,OAAOE,OAAAA;QACzC;MACF;IACF,CAAA;EACF;EAEA,MAAMG,OAAO;AACX,eAAW,EAAEV,IAAIC,SAAQ,KAAM,KAAKF,QAAQY,KAAI,GAAI;AAClD,YAAM,KAAKC,QAAQZ,IAAIC,QAAAA;IACzB;EACF;EAEA,MAAcQ,MAAMI,KAAcR,OAAcE,SAA0B;AACxE,UAAMO,MAAM;MAAEd,IAAIO,QAAQQ;MAAUd,UAAUI,MAAMS;IAAI;AACxD,UAAME,MAAM,KAAKnB,UAAUoB,UAAUC,KAAK,CAACC,WAAWA,OAAOnB,OAAOO,QAAQQ,QAAQ;AACpFxB,IAAAA,WAAUyB,KAAK,uBAAuBT,QAAQQ,QAAQ,IAAE;;;;;;;;;AAExD,UAAMK,SAAS,KAAKrB,QAAQsB,IAAIP,GAAAA;AAChC,QAAI,CAACM,QAAQ;AACX,WAAKrB,QAAQuB,IAAIR,KAAK;QAAED;QAAKN;MAAQ,CAAA;AACrCf,MAAAA,KAAI,SAAS;QAAEa,OAAOA,MAAMS;QAAKP;MAAQ,GAAA;;;;;;AACzC,UAAIM,IAAIU,UAAU;AAChB;MACF;AAGA,UAAIhB,QAAQiB,UAAU;AACpB,cAAMC,OAAO,IAAIxC,aAAa4B,KAAK,YAAA;AACjC,gBAAM,KAAKa,aAAaV,KAAK;YAC3BX,OAAOA,MAAMS;UACf,CAAA;QACF,CAAA;AAGA,cAAMa,MAAM,IAAI5C,QAAQwB,QAAQiB,UAAU,MAAMC,KAAKD,SAAQ,CAAA;AAE7DG,YAAIxB,MAAK;AACTU,YAAIe,UAAU,MAAMD,IAAIjB,KAAI,CAAA;MAC9B;AAGA,UAAIH,QAAQsB,cAAc;AACxB,cAAMC,YAAY,oBAAIC,IAAAA;AACtB,cAAMN,OAAO,IAAIxC,aAAa4B,KAAK,YAAA;AACjC,gBAAM,KAAKa,aAAaV,KAAK;YAC3BX,OAAOA,MAAMS;YACbkB,SAASC,MAAMC,KAAKJ,SAAAA;UACtB,CAAA;QACF,CAAA;AAGA,cAAMK,gBAAgC,CAAA;AACtC,cAAMN,eAAexC,mBAAmB,CAAC,EAAE+C,OAAOC,QAAO,MAAE;AACzD,qBAAWC,UAAUF,OAAO;AAC1BN,sBAAUS,IAAID,OAAOtC,EAAE;UACzB;AACA,qBAAWsC,UAAUD,SAAS;AAC5BP,sBAAUS,IAAID,OAAOtC,EAAE;UACzB;AAEAyB,eAAKD,SAAQ;QACf,CAAA;AACAW,sBAAcK,KAAK,MAAMX,aAAaY,YAAW,CAAA;AAEjD,cAAM,EAAEC,MAAMC,OAAOC,MAAMC,MAAK,IAAKtC,QAAQsB;AAC7C,cAAMiB,SAAS,CAAC,EAAEd,QAAO,MAAS;AAChCH,uBAAaiB,OAAOd,OAAAA;AAGpB,cAAIY,MAAM;AACRpD,YAAAA,KAAIuD,KAAK,UAAU;cAAEL;cAAME;cAAMZ,SAASA,QAAQgB;YAAO,GAAA;;;;;;AACzD,uBAAWV,UAAUN,SAAS;AAC5B,oBAAMiB,UAAUX,OAAOW;AACvB,kBAAIA,mBAAmB/D,YAAY;AACjCiD,8BAAcK,KAAKS,QAAQ3D,SAAAA,EAAWN,SAAS,MAAM6C,aAAaiB,OAAO;kBAACR;iBAAO,GAAG,GAAA,CAAA,CAAA;cACtF;YACF;UACF;QACF;AAIA,cAAMY,QAAQ7C,MAAM8C,GAAGD,MAAM9D,OAAOgE,SAASV,MAAMC,KAAAA,CAAAA;AACnDR,sBAAcK,KAAKU,MAAM5D,UAAUuD,QAAQ7D,SAAS8D,QAAQD,QAAQ,GAAA,IAASC,MAAAA,CAAAA;AAE7EjC,YAAIe,UAAU,MAAA;AACZO,wBAAckB,QAAQ,CAACZ,gBAAgBA,YAAAA,CAAAA;QACzC,CAAA;MACF;IACF;EACF;EAEA,MAAc7B,QAAQZ,IAAYC,UAAqB;AACrD,UAAMa,MAAM;MAAEd;MAAIC;IAAS;AAC3B,UAAM,EAAEY,IAAG,IAAK,KAAKd,QAAQsB,IAAIP,GAAAA,KAAQ,CAAC;AAC1C,QAAID,KAAK;AACP,WAAKd,QAAQuD,OAAOxC,GAAAA;AACpB,YAAMD,IAAI0C,QAAO;IACnB;EACF;EAEA,MAAc7B,aAAaV,KAAkBwC,MAAW;AACtD,QAAI;AACFhE,MAAAA,KAAI,WAAW;QAAEuB,UAAUC,IAAIhB;MAAG,GAAA;;;;;;AAClC,YAAMyD,WAAW,MAAMC,MAAM,GAAG,KAAK5D,SAAS6D,QAAQ,IAAI3C,IAAI4C,IAAI,IAAI;QACpEC,QAAQ;QACRC,SAAS;UACP,gBAAgB;QAClB;QACAC,MAAMC,KAAKC,UAAUT,IAAAA;MACvB,CAAA;AAGAhE,MAAAA,KAAI,UAAU;QAAEuB,UAAUC,IAAIhB;QAAIkE,QAAQT,SAASU;MAAO,GAAA;;;;;;IAC5D,SAASC,KAAU;AACjB5E,MAAAA,KAAI6E,MAAM,SAAS;QAAEtD,UAAUC,IAAIhB;QAAIqE,OAAOD,IAAIE;MAAQ,GAAA;;;;;;IAC5D;EACF;AACF;",
6
+ "names": ["express", "getPort", "join", "Trigger", "invariant", "log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "name", "params", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "info", "_registrationId", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "wait", "flush", "id", "handler", "path", "join", "directory", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "event", "seq", "now", "Date", "context", "client", "dataDir", "response", "status", "code", "duration", "CronJob", "debounce", "DeferredTask", "TextObject", "Context", "Filter", "createSubscription", "subscribe", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "id", "spaceKey", "toHex", "start", "spaces", "space", "waitUntilReady", "trigger", "triggers", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "def", "functions", "find", "config", "exists", "get", "set", "disposed", "schedule", "task", "execFunction", "job", "onDispose", "subscription", "objectIds", "Set", "objects", "Array", "from", "subscriptions", "added", "updated", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "info", "length", "content", "query", "db", "typename", "forEach", "delete", "dispose", "data", "response", "fetch", "endpoint", "name", "method", "headers", "body", "JSON", "stringify", "result", "status", "err", "error", "message"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":1313,"imports":[],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1795,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":18569,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@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":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":20325,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":637,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/manifest.ts","kind":"import-statement","original":"./manifest"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18178},"packages/core/functions/dist/lib/browser/index.mjs":{"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":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["DevServer","Scheduler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4739},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":5045}},"bytes":10365}}}
1
+ {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":1341,"imports":[],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1795,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":18761,"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":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":20292,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":637,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/manifest.ts","kind":"import-statement","original":"./manifest"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18262},"packages/core/functions/dist/lib/browser/index.mjs":{"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":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["DevServer","Scheduler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4777},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":5040}},"bytes":10398}}}
@@ -65,7 +65,7 @@ var DevServer = class {
65
65
  get endpoint() {
66
66
  (0, import_invariant.invariant)(this._port, void 0, {
67
67
  F: __dxlog_file,
68
- L: 45,
68
+ L: 46,
69
69
  S: this,
70
70
  A: [
71
71
  "this._port",
@@ -87,7 +87,7 @@ var DevServer = class {
87
87
  } catch (err) {
88
88
  import_log.log.error("parsing function (check manifest)", err, {
89
89
  F: __dxlog_file,
90
- L: 62,
90
+ L: 63,
91
91
  S: this,
92
92
  C: (f, a) => f(...a)
93
93
  });
@@ -109,7 +109,7 @@ var DevServer = class {
109
109
  } catch (err) {
110
110
  import_log.log.catch(err, void 0, {
111
111
  F: __dxlog_file,
112
- L: 82,
112
+ L: 83,
113
113
  S: this,
114
114
  C: (f, a) => f(...a)
115
115
  });
@@ -137,7 +137,7 @@ var DevServer = class {
137
137
  endpoint
138
138
  }, {
139
139
  F: __dxlog_file,
140
- L: 98,
140
+ L: 99,
141
141
  S: this,
142
142
  C: (f, a) => f(...a)
143
143
  });
@@ -159,7 +159,7 @@ var DevServer = class {
159
159
  registrationId: this._registrationId
160
160
  }, {
161
161
  F: __dxlog_file,
162
- L: 115,
162
+ L: 116,
163
163
  S: this,
164
164
  C: (f, a) => f(...a)
165
165
  });
@@ -182,7 +182,7 @@ var DevServer = class {
182
182
  id
183
183
  }, {
184
184
  F: __dxlog_file,
185
- L: 134,
185
+ L: 135,
186
186
  S: this,
187
187
  C: (f, a) => f(...a)
188
188
  });
@@ -209,13 +209,14 @@ var DevServer = class {
209
209
  name
210
210
  }, {
211
211
  F: __dxlog_file,
212
- L: 159,
212
+ L: 160,
213
213
  S: this,
214
214
  C: (f, a) => f(...a)
215
215
  });
216
216
  const { handler } = this._handlers[name];
217
217
  const context = {
218
- client: this._client
218
+ client: this._client,
219
+ dataDir: this._options.dataDir
219
220
  };
220
221
  let statusCode = 200;
221
222
  const response = {
@@ -236,7 +237,7 @@ var DevServer = class {
236
237
  duration: Date.now() - now
237
238
  }, {
238
239
  F: __dxlog_file,
239
- L: 175,
240
+ L: 177,
240
241
  S: this,
241
242
  C: (f, a) => f(...a)
242
243
  });
@@ -287,7 +288,7 @@ var Scheduler = class {
287
288
  ctx,
288
289
  trigger
289
290
  });
290
- import_log2.log.info("mount", {
291
+ (0, import_log2.log)("mount", {
291
292
  space: space.key,
292
293
  trigger
293
294
  }, {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ port: 7200, portRange: [7200, 7299] });\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, TextObject } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription, type Query, subscribe } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../manifest';\n\ntype SchedulerOptions = {\n endpoint: string;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions,\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log.info('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Cron schedule.\n if (trigger.schedule) {\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n });\n });\n\n // TODO(burdon): Check greater than 30s min (use cron-parser).\n const job = new CronJob(trigger.schedule, () => task.schedule());\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n // ECHO subscription.\n if (trigger.subscription) {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n const { type, props, deep, delay } = trigger.subscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextObject) {\n subscriptions.push(content[subscribe](debounce(() => subscription.update([object]), 1_000)));\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private async execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n // const result = await response.json();\n log('result', { function: def.id, result: response.status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,qBAAoB;AACpB,6BAAwB;AAExB,uBAAqB;AAErB,mBAAwB;AAExB,uBAA0B;AAC1B,iBAAoB;ACRpB,kBAAwB;AAExB,IAAAA,gBAAuC;AAEvC,kBAAuC;AACvC,qBAAwB;AACxB,yBAAkE;AAClE,IAAAC,oBAA0B;AAC1B,IAAAC,cAAoB;AACpB,kBAA2B;;;;;;;;;ADcpB,IAAMC,YAAN,MAAMA;;EAWXC,YACmBC,SACAC,UACjB;mBAFiBD;oBACAC;SAXFC,YAAiF,CAAC;SAM3FC,OAAO;EAMZ;EAEH,IAAIC,WAAW;AACbC,oCAAU,KAAKC,OAAK,QAAA;;;;;;;;;AACpB,WAAO,oBAAoB,KAAKA,KAAK;EACvC;EAEA,IAAIC,QAAQ;AACV,WAAO,KAAKC;EACd;EAEA,IAAIC,YAAY;AACd,WAAOC,OAAOC,OAAO,KAAKT,SAAS;EACrC;EAEA,MAAMU,aAAa;AACjB,eAAWC,OAAO,KAAKZ,SAASa,SAASL,WAAW;AAClD,UAAI;AACF,cAAM,KAAKM,MAAMF,GAAAA;MACnB,SAASG,KAAK;AACZC,uBAAIC,MAAM,qCAAqCF,KAAAA;;;;;;MACjD;IACF;EACF;EAEA,MAAMG,QAAQ;AACZ,UAAMC,UAAMC,eAAAA,SAAAA;AACZD,QAAIE,IAAID,eAAAA,QAAQE,KAAI,CAAA;AAEpBH,QAAII,KAAK,UAAU,OAAOC,KAAKC,QAAAA;AAC7B,YAAM,EAAEC,KAAI,IAAKF,IAAIG;AACrB,UAAI;AACF,YAAI,KAAK3B,SAAS4B,QAAQ;AACxB,gBAAM,EAAEhB,IAAG,IAAK,KAAKX,UAAUyB,IAAAA;AAC/B,gBAAM,KAAKZ,MAAMF,KAAK,IAAA;QACxB;AAEAa,YAAII,aAAa,MAAM,KAAKC,QAAQJ,MAAMF,IAAIO,IAAI;AAClDN,YAAIO,IAAG;MACT,SAASjB,KAAU;AACjBC,uBAAIiB,MAAMlB,KAAAA,QAAAA;;;;;;AACVU,YAAII,aAAa;AACjBJ,YAAIO,IAAG;MACT;IACF,CAAA;AAEA,SAAK3B,QAAQ,UAAM6B,gCAAQ;MAAEC,MAAM;MAAMC,WAAW;QAAC;QAAM;;IAAM,CAAA;AACjE,SAAKC,UAAUlB,IAAImB,OAAO,KAAKjC,KAAK;AAEpC,QAAI;AAEF,YAAM,EAAEkC,gBAAgBpC,SAAQ,IAAK,MAAM,KAAKJ,QAAQyC,SAASA,SAASC,wBAAyBC,SAAS;QAC1GvC,UAAU,KAAKA;QACfK,WAAW,KAAKA,UAAUmC,IAAI,CAAC,EAAE/B,KAAK,EAAEc,KAAI,EAAE,OAAQ;UAAEA;QAAK,EAAA;MAC/D,CAAA;AAEAV,qBAAI4B,KAAK,cAAc;QAAEL;QAAgBpC;MAAS,GAAA;;;;;;AAClD,WAAK0C,kBAAkBN;AACvB,WAAKhC,SAASJ;IAChB,SAASY,KAAU;AACjB,YAAM,KAAK+B,KAAI;AACf,YAAM,IAAIC,MAAM,qEAAA;IAClB;EACF;EAEA,MAAMD,OAAO;AACX,UAAME,UAAU,IAAIC,qBAAAA;AACpB,SAAKZ,SAASa,MAAM,YAAA;AAClB,UAAI,KAAKL,iBAAiB;AACxB,cAAM,KAAK9C,QAAQyC,SAASA,SAASC,wBAAyBU,WAAW;UACvEZ,gBAAgB,KAAKM;QACvB,CAAA;AAEA7B,uBAAI4B,KAAK,gBAAgB;UAAEL,gBAAgB,KAAKM;QAAgB,GAAA;;;;;;AAChE,aAAKA,kBAAkBO;AACvB,aAAK7C,SAAS6C;MAChB;AAEAJ,cAAQK,KAAI;IACd,CAAA;AAEA,UAAML,QAAQM,KAAI;AAClB,SAAKjD,QAAQ+C;AACb,SAAKf,UAAUe;EACjB;;;;EAKA,MAActC,MAAMF,KAAkB2C,QAAQ,OAAO;AACnD,UAAM,EAAEC,IAAI9B,MAAM+B,QAAO,IAAK7C;AAC9B,UAAM8C,WAAOC,uBAAK,KAAK3D,SAAS4D,WAAWH,OAAAA;AAC3CzC,mBAAI4B,KAAK,WAAW;MAAEY;IAAG,GAAA;;;;;;AAGzB,QAAID,OAAO;AACT9C,aAAOoD,KAAKC,UAAQC,KAAK,EACtBC,OAAO,CAACC,QAAQA,IAAIC,WAAWR,IAAAA,CAAAA,EAC/BS,QAAQ,CAACF,QAAQ,OAAOH,UAAQC,MAAME,GAAAA,CAAI;IAC/C;AAGA,UAAMG,UAASN,UAAQJ,IAAAA;AACvB,QAAI,OAAOU,QAAOC,YAAY,YAAY;AACxC,YAAM,IAAItB,MAAM,yCAAyCS,EAAAA,EAAI;IAC/D;AAEA,SAAKvD,UAAUyB,IAAAA,IAAQ;MAAEd;MAAK6C,SAASW,QAAOC;IAAQ;EACxD;;;;EAKA,MAAcvC,QAAQJ,MAAc4C,OAAY;AAC9C,UAAMC,MAAM,EAAE,KAAKrE;AACnB,UAAMsE,MAAMC,KAAKD,IAAG;AAEpBxD,mBAAI4B,KAAK,OAAO;MAAE2B;MAAK7C;IAAK,GAAA;;;;;;AAC5B,UAAM,EAAE+B,QAAO,IAAK,KAAKxD,UAAUyB,IAAAA;AAEnC,UAAMgD,UAA2B;MAC/BC,QAAQ,KAAK5E;IACf;AAEA,QAAI8B,aAAa;AACjB,UAAM+C,WAAqB;MACzBC,QAAQ,CAACC,SAAAA;AACPjD,qBAAaiD;AACb,eAAOF;MACT;IACF;AAEA,UAAMnB,QAAQ;MAAEiB;MAASJ;MAAOM;IAAS,CAAA;AACzC5D,mBAAI4B,KAAK,OAAO;MAAE2B;MAAK7C;MAAMG;MAAYkD,UAAUN,KAAKD,IAAG,IAAKA;IAAI,GAAA;;;;;;AAEpE,WAAO3C;EACT;AACF;;ACzJO,IAAMmD,YAAN,MAAMA;EAOXlF,YACmBC,SACAkF,WACAjF,UACjB;mBAHiBD;qBACAkF;oBACAjF;SARFkF,UAAU,IAAIC,uBAG7B,CAAC,EAAE3B,IAAI4B,SAAQ,MAAO,GAAGA,SAASC,MAAK,CAAA,IAAM7B,EAAAA,EAAI;EAMhD;EAEH,MAAMtC,QAAQ;AACZ,SAAKnB,QAAQuF,OAAOC,UAAU,OAAOD,WAAAA;AACnC,iBAAWE,SAASF,QAAQ;AAC1B,cAAME,MAAMC,eAAc;AAC1B,mBAAWzC,WAAW,KAAKiC,UAAUS,YAAY,CAAA,GAAI;AACnD,gBAAM,KAAKC,MAAM,IAAIC,uBAAAA,GAAWJ,OAAOxC,OAAAA;QACzC;MACF;IACF,CAAA;EACF;EAEA,MAAMF,OAAO;AACX,eAAW,EAAEU,IAAI4B,SAAQ,KAAM,KAAKF,QAAQrB,KAAI,GAAI;AAClD,YAAM,KAAKgC,QAAQrC,IAAI4B,QAAAA;IACzB;EACF;EAEA,MAAcO,MAAMG,KAAcN,OAAcxC,SAA0B;AACxE,UAAMiB,MAAM;MAAET,IAAIR,QAAQ+C;MAAUX,UAAUI,MAAMvB;IAAI;AACxD,UAAMrD,MAAM,KAAKqE,UAAUzE,UAAUwF,KAAK,CAACC,WAAWA,OAAOzC,OAAOR,QAAQ+C,QAAQ;AACpF3F,0BAAAA,WAAUQ,KAAK,uBAAuBoC,QAAQ+C,QAAQ,IAAE;;;;;;;;;AAExD,UAAMG,SAAS,KAAKhB,QAAQiB,IAAIlC,GAAAA;AAChC,QAAI,CAACiC,QAAQ;AACX,WAAKhB,QAAQkB,IAAInC,KAAK;QAAE6B;QAAK9C;MAAQ,CAAA;AACrChC,kBAAAA,IAAI4B,KAAK,SAAS;QAAE4C,OAAOA,MAAMvB;QAAKjB;MAAQ,GAAA;;;;;;AAC9C,UAAI8C,IAAIO,UAAU;AAChB;MACF;AAGA,UAAIrD,QAAQsD,UAAU;AACpB,cAAMC,OAAO,IAAIC,2BAAaV,KAAK,YAAA;AACjC,gBAAM,KAAKW,aAAa7F,KAAK;YAC3B4E,OAAOA,MAAMvB;UACf,CAAA;QACF,CAAA;AAGA,cAAMyC,MAAM,IAAIC,oBAAQ3D,QAAQsD,UAAU,MAAMC,KAAKD,SAAQ,CAAA;AAE7DI,YAAIxF,MAAK;AACT4E,YAAIc,UAAU,MAAMF,IAAI5D,KAAI,CAAA;MAC9B;AAGA,UAAIE,QAAQ6D,cAAc;AACxB,cAAMC,YAAY,oBAAIC,IAAAA;AACtB,cAAMR,OAAO,IAAIC,2BAAaV,KAAK,YAAA;AACjC,gBAAM,KAAKW,aAAa7F,KAAK;YAC3B4E,OAAOA,MAAMvB;YACb+C,SAASC,MAAMC,KAAKJ,SAAAA;UACtB,CAAA;QACF,CAAA;AAGA,cAAMK,gBAAgC,CAAA;AACtC,cAAMN,mBAAeO,uCAAmB,CAAC,EAAEC,OAAOC,QAAO,MAAE;AACzD,qBAAWC,UAAUF,OAAO;AAC1BP,sBAAUU,IAAID,OAAO/D,EAAE;UACzB;AACA,qBAAW+D,UAAUD,SAAS;AAC5BR,sBAAUU,IAAID,OAAO/D,EAAE;UACzB;AAEA+C,eAAKD,SAAQ;QACf,CAAA;AACAa,sBAAcM,KAAK,MAAMZ,aAAaa,YAAW,CAAA;AAEjD,cAAM,EAAEC,MAAMC,OAAOC,MAAMC,MAAK,IAAK9E,QAAQ6D;AAC7C,cAAMkB,SAAS,CAAC,EAAEf,QAAO,MAAS;AAChCH,uBAAakB,OAAOf,OAAAA;AAGpB,cAAIa,MAAM;AACR7G,wBAAAA,IAAI4B,KAAK,UAAU;cAAE+E;cAAME;cAAMb,SAASA,QAAQgB;YAAO,GAAA;;;;;;AACzD,uBAAWT,UAAUP,SAAS;AAC5B,oBAAMiB,UAAUV,OAAOU;AACvB,kBAAIA,mBAAmBC,wBAAY;AACjCf,8BAAcM,KAAKQ,QAAQ1C,4BAAAA,MAAW4C,wBAAS,MAAMtB,aAAakB,OAAO;kBAACR;iBAAO,GAAG,GAAA,CAAA,CAAA;cACtF;YACF;UACF;QACF;AAIA,cAAMa,QAAQ5C,MAAM6C,GAAGD,MAAME,0BAAOC,SAASZ,MAAMC,KAAAA,CAAAA;AACnDT,sBAAcM,KAAKW,MAAM7C,UAAUuC,YAAQK,wBAASJ,QAAQD,QAAQ,GAAA,IAASC,MAAAA,CAAAA;AAE7EjC,YAAIc,UAAU,MAAA;AACZO,wBAAchD,QAAQ,CAACuD,gBAAgBA,YAAAA,CAAAA;QACzC,CAAA;MACF;IACF;EACF;EAEA,MAAc7B,QAAQrC,IAAY4B,UAAqB;AACrD,UAAMnB,MAAM;MAAET;MAAI4B;IAAS;AAC3B,UAAM,EAAEU,IAAG,IAAK,KAAKZ,QAAQiB,IAAIlC,GAAAA,KAAQ,CAAC;AAC1C,QAAI6B,KAAK;AACP,WAAKZ,QAAQsD,OAAOvE,GAAAA;AACpB,YAAM6B,IAAI2C,QAAO;IACnB;EACF;EAEA,MAAchC,aAAa7F,KAAkB8H,MAAW;AACtD,QAAI;AACF1H,sBAAAA,KAAI,WAAW;QAAE+E,UAAUnF,IAAI4C;MAAG,GAAA;;;;;;AAClC,YAAMoB,WAAW,MAAM+D,MAAM,GAAG,KAAK3I,SAASG,QAAQ,IAAIS,IAAIc,IAAI,IAAI;QACpEkH,QAAQ;QACRC,SAAS;UACP,gBAAgB;QAClB;QACA9G,MAAM+G,KAAKC,UAAUL,IAAAA;MACvB,CAAA;AAGA1H,sBAAAA,KAAI,UAAU;QAAE+E,UAAUnF,IAAI4C;QAAIwF,QAAQpE,SAASC;MAAO,GAAA;;;;;;IAC5D,SAAS9D,KAAU;AACjBC,kBAAAA,IAAIC,MAAM,SAAS;QAAE8E,UAAUnF,IAAI4C;QAAIvC,OAAOF,IAAIkI;MAAQ,GAAA;;;;;;IAC5D;EACF;AACF;",
6
- "names": ["import_async", "import_invariant", "import_log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "name", "params", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "info", "_registrationId", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "wait", "flush", "id", "handler", "path", "join", "directory", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "event", "seq", "now", "Date", "context", "client", "response", "status", "code", "duration", "Scheduler", "_manifest", "_mounts", "ComplexMap", "spaceKey", "toHex", "spaces", "subscribe", "space", "waitUntilReady", "triggers", "mount", "Context", "unmount", "ctx", "function", "find", "config", "exists", "get", "set", "disposed", "schedule", "task", "DeferredTask", "execFunction", "job", "CronJob", "onDispose", "subscription", "objectIds", "Set", "objects", "Array", "from", "subscriptions", "createSubscription", "added", "updated", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "length", "content", "TextObject", "debounce", "query", "db", "Filter", "typename", "delete", "dispose", "data", "fetch", "method", "headers", "JSON", "stringify", "result", "message"]
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ port: 7200, portRange: [7200, 7299] });\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, TextObject } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription, type Query, subscribe } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../manifest';\n\ntype SchedulerOptions = {\n endpoint: string;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions,\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Cron schedule.\n if (trigger.schedule) {\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n });\n });\n\n // TODO(burdon): Check greater than 30s min (use cron-parser).\n const job = new CronJob(trigger.schedule, () => task.schedule());\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n // ECHO subscription.\n if (trigger.subscription) {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n const { type, props, deep, delay } = trigger.subscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextObject) {\n subscriptions.push(content[subscribe](debounce(() => subscription.update([object]), 1_000)));\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private async execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n // const result = await response.json();\n log('result', { function: def.id, result: response.status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_async", "import_invariant", "import_log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "name", "params", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "info", "_registrationId", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "wait", "flush", "id", "handler", "path", "join", "directory", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "event", "seq", "now", "Date", "context", "client", "dataDir", "response", "status", "code", "duration", "Scheduler", "_manifest", "_mounts", "ComplexMap", "spaceKey", "toHex", "spaces", "subscribe", "space", "waitUntilReady", "triggers", "mount", "Context", "unmount", "ctx", "function", "find", "config", "exists", "get", "set", "disposed", "schedule", "task", "DeferredTask", "execFunction", "job", "CronJob", "onDispose", "subscription", "objectIds", "Set", "objects", "Array", "from", "subscriptions", "createSubscription", "added", "updated", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "length", "content", "TextObject", "debounce", "query", "db", "Filter", "typename", "delete", "dispose", "data", "fetch", "method", "headers", "JSON", "stringify", "result", "message"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":1313,"imports":[],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1795,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":18569,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/scheduler.ts":{"bytes":20325,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":637,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/manifest.ts","kind":"import-statement","original":"./manifest"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18177},"packages/core/functions/dist/lib/node/index.cjs":{"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["DevServer","Scheduler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4729},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":5045}},"bytes":10322}}}
1
+ {"inputs":{"packages/core/functions/src/handler.ts":{"bytes":1341,"imports":[],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1795,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":18761,"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":20292,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":637,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/manifest.ts","kind":"import-statement","original":"./manifest"},{"path":"packages/core/functions/src/runtime/index.ts","kind":"import-statement","original":"./runtime"}],"format":"esm"}},"outputs":{"packages/core/functions/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18261},"packages/core/functions/dist/lib/node/index.cjs":{"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["DevServer","Scheduler"],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":4767},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":5040}},"bytes":10355}}}
@@ -4,6 +4,7 @@ export interface Response {
4
4
  }
5
5
  export interface FunctionContext {
6
6
  client: Client;
7
+ dataDir?: string;
7
8
  }
8
9
  export type FunctionHandler<T extends {}> = (params: {
9
10
  event: T;
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/handler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC;AAGD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAE/B,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/handler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC;AAGD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAE/B,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC"}
@@ -6,6 +6,7 @@ export type DevServerOptions = {
6
6
  directory: string;
7
7
  manifest: FunctionManifest;
8
8
  reload?: boolean;
9
+ dataDir?: string;
9
10
  };
10
11
  /**
11
12
  * Functions dev server provides a local HTTP server for testing functions.
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/dev-server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EAAwB,KAAK,eAAe,EAAiB,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IAYlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2E;IAErG,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAK;gBAIE,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,gBAAgB;IAG7C,IAAI,QAAQ,WAGX;IAED,IAAI,KAAK,uBAER;IAED,IAAI,SAAS;;;QAEZ;IAEK,UAAU;IAUV,KAAK;IAwCL,IAAI;IAqBV;;OAEG;YACW,KAAK;IAqBnB;;OAEG;YACW,OAAO;CAwBtB"}
1
+ {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/dev-server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EAAwB,KAAK,eAAe,EAAiB,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IAYlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2E;IAErG,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAK;gBAIE,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,gBAAgB;IAG7C,IAAI,QAAQ,WAGX;IAED,IAAI,KAAK,uBAER;IAED,IAAI,SAAS;;;QAEZ;IAEK,UAAU;IAUV,KAAK;IAwCL,IAAI;IAqBV;;OAEG;YACW,KAAK;IAqBnB;;OAEG;YACW,OAAO;CAyBtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/functions",
3
- "version": "0.3.9-main.14901ff",
3
+ "version": "0.3.9-main.26defc6",
4
4
  "description": "Functions SDK and runtime.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -24,14 +24,14 @@
24
24
  "deepsignal": "1.4.0-shallow.0",
25
25
  "express": "^4.17.1",
26
26
  "get-port-please": "^3.1.1",
27
- "@dxos/async": "0.3.9-main.14901ff",
28
- "@dxos/client": "0.3.9-main.14901ff",
29
- "@dxos/context": "0.3.9-main.14901ff",
30
- "@dxos/echo-schema": "0.3.9-main.14901ff",
31
- "@dxos/log": "0.3.9-main.14901ff",
32
- "@dxos/invariant": "0.3.9-main.14901ff",
33
- "@dxos/util": "0.3.9-main.14901ff",
34
- "@dxos/node-std": "0.3.9-main.14901ff"
27
+ "@dxos/async": "0.3.9-main.26defc6",
28
+ "@dxos/client": "0.3.9-main.26defc6",
29
+ "@dxos/context": "0.3.9-main.26defc6",
30
+ "@dxos/invariant": "0.3.9-main.26defc6",
31
+ "@dxos/echo-schema": "0.3.9-main.26defc6",
32
+ "@dxos/log": "0.3.9-main.26defc6",
33
+ "@dxos/util": "0.3.9-main.26defc6",
34
+ "@dxos/node-std": "0.3.9-main.26defc6"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/express": "^4.17.17"
package/src/handler.ts CHANGED
@@ -12,6 +12,7 @@ export interface Response {
12
12
  // TODO(burdon): Limit access to individual space?
13
13
  export interface FunctionContext {
14
14
  client: Client;
15
+ dataDir?: string;
15
16
  }
16
17
 
17
18
  // TODO(burdon): Model after http request. Ref Lambda/OpenFaaS.
@@ -20,6 +20,7 @@ export type DevServerOptions = {
20
20
  directory: string;
21
21
  manifest: FunctionManifest;
22
22
  reload?: boolean;
23
+ dataDir?: string;
23
24
  };
24
25
 
25
26
  /**
@@ -161,6 +162,7 @@ export class DevServer {
161
162
 
162
163
  const context: FunctionContext = {
163
164
  client: this._client,
165
+ dataDir: this._options.dataDir,
164
166
  };
165
167
 
166
168
  let statusCode = 200;
@@ -61,7 +61,7 @@ export class Scheduler {
61
61
  const exists = this._mounts.get(key);
62
62
  if (!exists) {
63
63
  this._mounts.set(key, { ctx, trigger });
64
- log.info('mount', { space: space.key, trigger });
64
+ log('mount', { space: space.key, trigger });
65
65
  if (ctx.disposed) {
66
66
  return;
67
67
  }