@dxos/functions 0.3.5-main.7cc908e → 0.3.5-main.87eff54
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.
- package/dist/lib/browser/index.mjs +14 -9
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +14 -9
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/runtime/trigger-manager.d.ts +1 -0
- package/dist/types/src/runtime/trigger-manager.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/runtime/trigger-manager.ts +10 -9
|
@@ -138,6 +138,7 @@ var TriggerManager = class {
|
|
|
138
138
|
this._triggers = _triggers;
|
|
139
139
|
this._invokeOptions = _invokeOptions;
|
|
140
140
|
this._mounts = new ComplexMap(({ name, spaceKey }) => `${spaceKey.toHex()}:${name}`);
|
|
141
|
+
this._queries = /* @__PURE__ */ new Set();
|
|
141
142
|
}
|
|
142
143
|
async start() {
|
|
143
144
|
this._client.spaces.subscribe(async (spaces) => {
|
|
@@ -170,7 +171,7 @@ var TriggerManager = class {
|
|
|
170
171
|
trigger
|
|
171
172
|
}, {
|
|
172
173
|
F: __dxlog_file2,
|
|
173
|
-
L:
|
|
174
|
+
L: 60,
|
|
174
175
|
S: this,
|
|
175
176
|
C: (f, a) => f(...a)
|
|
176
177
|
});
|
|
@@ -199,19 +200,23 @@ var TriggerManager = class {
|
|
|
199
200
|
count
|
|
200
201
|
}, {
|
|
201
202
|
F: __dxlog_file2,
|
|
202
|
-
L:
|
|
203
|
+
L: 84,
|
|
203
204
|
S: this,
|
|
204
205
|
C: (f, a) => f(...a)
|
|
205
206
|
});
|
|
206
207
|
task.schedule();
|
|
207
208
|
count++;
|
|
208
209
|
});
|
|
209
|
-
ctx.onDispose(() => subscription.unsubscribe());
|
|
210
210
|
const query = space.db.query(Filter.typename(trigger.subscription.type, trigger.subscription.props));
|
|
211
|
+
this._queries.add(query);
|
|
211
212
|
const unsubscribe = query.subscribe(({ objects }) => {
|
|
212
213
|
subscription.update(objects);
|
|
214
|
+
}, true);
|
|
215
|
+
ctx.onDispose(() => {
|
|
216
|
+
subscription.unsubscribe();
|
|
217
|
+
unsubscribe();
|
|
218
|
+
this._queries.delete(query);
|
|
213
219
|
});
|
|
214
|
-
ctx.onDispose(() => unsubscribe());
|
|
215
220
|
}
|
|
216
221
|
}
|
|
217
222
|
async unmount(name, spaceKey) {
|
|
@@ -229,7 +234,7 @@ var TriggerManager = class {
|
|
|
229
234
|
const { endpoint, runtime } = options;
|
|
230
235
|
invariant(endpoint, "Missing endpoint", {
|
|
231
236
|
F: __dxlog_file2,
|
|
232
|
-
L:
|
|
237
|
+
L: 120,
|
|
233
238
|
S: this,
|
|
234
239
|
A: [
|
|
235
240
|
"endpoint",
|
|
@@ -238,7 +243,7 @@ var TriggerManager = class {
|
|
|
238
243
|
});
|
|
239
244
|
invariant(runtime, "Missing runtime", {
|
|
240
245
|
F: __dxlog_file2,
|
|
241
|
-
L:
|
|
246
|
+
L: 121,
|
|
242
247
|
S: this,
|
|
243
248
|
A: [
|
|
244
249
|
"runtime",
|
|
@@ -250,7 +255,7 @@ var TriggerManager = class {
|
|
|
250
255
|
function: functionName
|
|
251
256
|
}, {
|
|
252
257
|
F: __dxlog_file2,
|
|
253
|
-
L:
|
|
258
|
+
L: 124,
|
|
254
259
|
S: this,
|
|
255
260
|
C: (f, a) => f(...a)
|
|
256
261
|
});
|
|
@@ -267,7 +272,7 @@ var TriggerManager = class {
|
|
|
267
272
|
result: await res.json()
|
|
268
273
|
}, {
|
|
269
274
|
F: __dxlog_file2,
|
|
270
|
-
L:
|
|
275
|
+
L: 134,
|
|
271
276
|
S: this,
|
|
272
277
|
C: (f, a) => f(...a)
|
|
273
278
|
});
|
|
@@ -277,7 +282,7 @@ var TriggerManager = class {
|
|
|
277
282
|
error: err.message
|
|
278
283
|
}, {
|
|
279
284
|
F: __dxlog_file2,
|
|
280
|
-
L:
|
|
285
|
+
L: 136,
|
|
281
286
|
S: this,
|
|
282
287
|
C: (f, a) => f(...a)
|
|
283
288
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/runtime/dev-server.ts", "../../../src/runtime/trigger-manager.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport type http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type FunctionsManifest, type Response } from '../function';\n\nconst DEFAULT_PORT = 7000;\n\nexport type DevServerOptions = {\n directory: string;\n manifest: FunctionsManifest;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\n// TODO(burdon): Not secure.\nexport class DevServer {\n private readonly _functionHandlers: Record<string, FunctionHandler<any>> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get port() {\n return this._port;\n }\n\n get endpoint() {\n return this._port ? `http://localhost:${this._port}` : undefined;\n }\n\n get functions() {\n return Object.keys(this._functionHandlers);\n }\n\n async initialize() {\n for (const [name, _] of Object.entries(this._options.manifest.functions)) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(join(this._options.directory, name));\n const handler = module.default;\n if (typeof handler !== 'function') {\n throw new Error(`Handler must export default function: ${name}`);\n }\n\n this._functionHandlers[name] = handler;\n } catch (err) {\n log.error('parsing function (check functions.yml manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:functionName', async (req, res) => {\n const functionName = req.params.functionName;\n log('invoke', { function: functionName, data: req.body });\n\n const builder: Response = {\n status: (code: number) => {\n res.statusCode = code;\n return builder;\n },\n succeed: (result = {}) => {\n res.end(JSON.stringify(result));\n return builder;\n },\n };\n\n const context: FunctionContext = {\n client: this._client,\n status: builder.status.bind(builder),\n };\n\n void (async () => {\n try {\n // TODO(burdon): Typed event handler.\n await this._functionHandlers[functionName]({ event: req.body, context });\n } catch (err: any) {\n res.statusCode = 500;\n res.end(err.message);\n }\n })();\n });\n\n this._port = await getPortPromise({ startPort: DEFAULT_PORT });\n this._server = app.listen(this._port);\n\n // TODO(burdon): Check plugin is registered.\n // TypeError: Cannot read properties of undefined (reading 'register')\n try {\n const { registrationId } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint!,\n functions: this.functions.map((name) => ({ name })),\n });\n this._registrationId = registrationId;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available; check config (agent.plugins.functions).');\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 this._registrationId = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._server = undefined;\n this._port = undefined;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport type { Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionTrigger } from '../function';\n\n// TODO(burdon): Rename.\nexport type InvokeOptions = {\n endpoint: string;\n runtime: string;\n};\n\nexport class TriggerManager {\n private readonly _mounts = new ComplexMap<\n { name: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ name, spaceKey }) => `${spaceKey.toHex()}:${name}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _triggers: FunctionTrigger[],\n private readonly _invokeOptions: InvokeOptions,\n ) {}\n\n async start() {\n // TODO(burdon): Make runtime configurable (via CLI)?\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._triggers) {\n // TODO(burdon): New context? Shared?\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { name, spaceKey } of this._mounts.keys()) {\n await this.unmount(name, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { name: trigger.function, spaceKey: space.key };\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 // TODO(burdon): Trigger binding.\n // TODO(burdon): Why DeferredTask? How to pass objectIds to function?\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.invokeFunction(this._invokeOptions, trigger.function, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n let count = 0;\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 log('updated', {\n trigger,\n space: space.key,\n objects: objectIds.size,\n count,\n });\n\n task.schedule();\n count++;\n });\n
|
|
5
|
-
"mappings": "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
|
|
6
|
-
"names": ["express", "join", "getPortPromise", "Trigger", "log", "DEFAULT_PORT", "DevServer", "constructor", "_client", "_options", "_functionHandlers", "port", "_port", "endpoint", "undefined", "functions", "Object", "keys", "initialize", "name", "_", "entries", "manifest", "module", "require", "join", "directory", "handler", "default", "Error", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "functionName", "params", "function", "data", "body", "builder", "status", "code", "statusCode", "succeed", "result", "end", "JSON", "stringify", "context", "client", "bind", "event", "message", "getPortPromise", "startPort", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "_registrationId", "stop", "trigger", "Trigger", "close", "unregister", "wake", "wait", "DeferredTask", "Context", "Filter", "createSubscription", "invariant", "log", "ComplexMap", "TriggerManager", "constructor", "_client", "_triggers", "_invokeOptions", "_mounts", "name", "spaceKey", "toHex", "start", "spaces", "subscribe", "space", "waitUntilReady", "trigger", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "exists", "get", "set", "disposed", "objectIds", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport type http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type FunctionsManifest, type Response } from '../function';\n\nconst DEFAULT_PORT = 7000;\n\nexport type DevServerOptions = {\n directory: string;\n manifest: FunctionsManifest;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\n// TODO(burdon): Not secure.\nexport class DevServer {\n private readonly _functionHandlers: Record<string, FunctionHandler<any>> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get port() {\n return this._port;\n }\n\n get endpoint() {\n return this._port ? `http://localhost:${this._port}` : undefined;\n }\n\n get functions() {\n return Object.keys(this._functionHandlers);\n }\n\n async initialize() {\n for (const [name, _] of Object.entries(this._options.manifest.functions)) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(join(this._options.directory, name));\n const handler = module.default;\n if (typeof handler !== 'function') {\n throw new Error(`Handler must export default function: ${name}`);\n }\n\n this._functionHandlers[name] = handler;\n } catch (err) {\n log.error('parsing function (check functions.yml manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:functionName', async (req, res) => {\n const functionName = req.params.functionName;\n log('invoke', { function: functionName, data: req.body });\n\n const builder: Response = {\n status: (code: number) => {\n res.statusCode = code;\n return builder;\n },\n succeed: (result = {}) => {\n res.end(JSON.stringify(result));\n return builder;\n },\n };\n\n const context: FunctionContext = {\n client: this._client,\n status: builder.status.bind(builder),\n };\n\n void (async () => {\n try {\n // TODO(burdon): Typed event handler.\n await this._functionHandlers[functionName]({ event: req.body, context });\n } catch (err: any) {\n res.statusCode = 500;\n res.end(err.message);\n }\n })();\n });\n\n this._port = await getPortPromise({ startPort: DEFAULT_PORT });\n this._server = app.listen(this._port);\n\n // TODO(burdon): Check plugin is registered.\n // TypeError: Cannot read properties of undefined (reading 'register')\n try {\n const { registrationId } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint!,\n functions: this.functions.map((name) => ({ name })),\n });\n this._registrationId = registrationId;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available; check config (agent.plugins.functions).');\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 this._registrationId = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._server = undefined;\n this._port = undefined;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport type { Query, Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionTrigger } from '../function';\n\n// TODO(burdon): Rename.\nexport type InvokeOptions = {\n endpoint: string;\n runtime: string;\n};\n\nexport class TriggerManager {\n private readonly _mounts = new ComplexMap<\n { name: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ name, spaceKey }) => `${spaceKey.toHex()}:${name}`);\n\n private readonly _queries = new Set<Query>();\n\n constructor(\n private readonly _client: Client,\n private readonly _triggers: FunctionTrigger[],\n private readonly _invokeOptions: InvokeOptions,\n ) {}\n\n async start() {\n // TODO(burdon): Make runtime configurable (via CLI)?\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._triggers) {\n // TODO(burdon): New context? Shared?\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { name, spaceKey } of this._mounts.keys()) {\n await this.unmount(name, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { name: trigger.function, spaceKey: space.key };\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 // TODO(burdon): Trigger binding.\n // TODO(burdon): Why DeferredTask? How to pass objectIds to function?\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.invokeFunction(this._invokeOptions, trigger.function, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n let count = 0;\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 log('updated', {\n trigger,\n space: space.key,\n objects: objectIds.size,\n count,\n });\n\n task.schedule();\n count++;\n });\n // TODO(burdon): DSL for query (replace props).\n const query = space.db.query(Filter.typename(trigger.subscription.type, trigger.subscription.props));\n this._queries.add(query);\n const unsubscribe = query.subscribe(({ objects }) => {\n subscription.update(objects);\n }, true);\n\n ctx.onDispose(() => {\n subscription.unsubscribe();\n unsubscribe();\n this._queries.delete(query);\n });\n }\n }\n\n private async unmount(name: string, spaceKey: PublicKey) {\n const key = { name, 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 invokeFunction(options: InvokeOptions, functionName: string, data: any) {\n const { endpoint, runtime } = options;\n invariant(endpoint, 'Missing endpoint');\n invariant(runtime, 'Missing runtime');\n\n try {\n log('invoke', { function: functionName });\n const url = `${endpoint}/${runtime}/${functionName}`;\n const res = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n log('result', { function: functionName, result: await res.json() });\n } catch (err: any) {\n log.error('error', { function: functionName, error: err.message });\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["express", "join", "getPortPromise", "Trigger", "log", "DEFAULT_PORT", "DevServer", "constructor", "_client", "_options", "_functionHandlers", "port", "_port", "endpoint", "undefined", "functions", "Object", "keys", "initialize", "name", "_", "entries", "manifest", "module", "require", "join", "directory", "handler", "default", "Error", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "functionName", "params", "function", "data", "body", "builder", "status", "code", "statusCode", "succeed", "result", "end", "JSON", "stringify", "context", "client", "bind", "event", "message", "getPortPromise", "startPort", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "_registrationId", "stop", "trigger", "Trigger", "close", "unregister", "wake", "wait", "DeferredTask", "Context", "Filter", "createSubscription", "invariant", "log", "ComplexMap", "TriggerManager", "constructor", "_client", "_triggers", "_invokeOptions", "_mounts", "name", "spaceKey", "toHex", "_queries", "Set", "start", "spaces", "subscribe", "space", "waitUntilReady", "trigger", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "exists", "get", "set", "disposed", "objectIds", "task", "invokeFunction", "objects", "Array", "from", "count", "subscription", "added", "updated", "object", "add", "id", "size", "schedule", "query", "db", "typename", "type", "props", "unsubscribe", "update", "onDispose", "delete", "dispose", "options", "functionName", "data", "endpoint", "runtime", "url", "res", "fetch", "method", "body", "JSON", "stringify", "headers", "result", "json", "err", "error", "message"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1782,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":14331,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"portfinder","kind":"import-statement","external":true},{"path":"@dxos/async","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/trigger-manager.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1782,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":14331,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"portfinder","kind":"import-statement","external":true},{"path":"@dxos/async","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/trigger-manager.ts":{"bytes":16478,"imports":[{"path":"@dxos/async","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":584,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/trigger-manager.ts","kind":"import-statement","original":"./trigger-manager"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":550,"imports":[{"path":"packages/core/functions/src/function.ts","kind":"import-statement","original":"./function"},{"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":14657},"packages/core/functions/dist/lib/browser/index.mjs":{"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"portfinder","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/async","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","TriggerManager"],"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":3304},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytesInOutput":4320}},"bytes":8216}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -166,6 +166,7 @@ var TriggerManager = class {
|
|
|
166
166
|
this._triggers = _triggers;
|
|
167
167
|
this._invokeOptions = _invokeOptions;
|
|
168
168
|
this._mounts = new import_util.ComplexMap(({ name, spaceKey }) => `${spaceKey.toHex()}:${name}`);
|
|
169
|
+
this._queries = /* @__PURE__ */ new Set();
|
|
169
170
|
}
|
|
170
171
|
async start() {
|
|
171
172
|
this._client.spaces.subscribe(async (spaces) => {
|
|
@@ -198,7 +199,7 @@ var TriggerManager = class {
|
|
|
198
199
|
trigger
|
|
199
200
|
}, {
|
|
200
201
|
F: __dxlog_file2,
|
|
201
|
-
L:
|
|
202
|
+
L: 60,
|
|
202
203
|
S: this,
|
|
203
204
|
C: (f, a) => f(...a)
|
|
204
205
|
});
|
|
@@ -227,19 +228,23 @@ var TriggerManager = class {
|
|
|
227
228
|
count
|
|
228
229
|
}, {
|
|
229
230
|
F: __dxlog_file2,
|
|
230
|
-
L:
|
|
231
|
+
L: 84,
|
|
231
232
|
S: this,
|
|
232
233
|
C: (f, a) => f(...a)
|
|
233
234
|
});
|
|
234
235
|
task.schedule();
|
|
235
236
|
count++;
|
|
236
237
|
});
|
|
237
|
-
ctx.onDispose(() => subscription.unsubscribe());
|
|
238
238
|
const query = space.db.query(import_echo_schema.Filter.typename(trigger.subscription.type, trigger.subscription.props));
|
|
239
|
+
this._queries.add(query);
|
|
239
240
|
const unsubscribe = query.subscribe(({ objects }) => {
|
|
240
241
|
subscription.update(objects);
|
|
242
|
+
}, true);
|
|
243
|
+
ctx.onDispose(() => {
|
|
244
|
+
subscription.unsubscribe();
|
|
245
|
+
unsubscribe();
|
|
246
|
+
this._queries.delete(query);
|
|
241
247
|
});
|
|
242
|
-
ctx.onDispose(() => unsubscribe());
|
|
243
248
|
}
|
|
244
249
|
}
|
|
245
250
|
async unmount(name, spaceKey) {
|
|
@@ -257,7 +262,7 @@ var TriggerManager = class {
|
|
|
257
262
|
const { endpoint, runtime } = options;
|
|
258
263
|
(0, import_invariant.invariant)(endpoint, "Missing endpoint", {
|
|
259
264
|
F: __dxlog_file2,
|
|
260
|
-
L:
|
|
265
|
+
L: 120,
|
|
261
266
|
S: this,
|
|
262
267
|
A: [
|
|
263
268
|
"endpoint",
|
|
@@ -266,7 +271,7 @@ var TriggerManager = class {
|
|
|
266
271
|
});
|
|
267
272
|
(0, import_invariant.invariant)(runtime, "Missing runtime", {
|
|
268
273
|
F: __dxlog_file2,
|
|
269
|
-
L:
|
|
274
|
+
L: 121,
|
|
270
275
|
S: this,
|
|
271
276
|
A: [
|
|
272
277
|
"runtime",
|
|
@@ -278,7 +283,7 @@ var TriggerManager = class {
|
|
|
278
283
|
function: functionName
|
|
279
284
|
}, {
|
|
280
285
|
F: __dxlog_file2,
|
|
281
|
-
L:
|
|
286
|
+
L: 124,
|
|
282
287
|
S: this,
|
|
283
288
|
C: (f, a) => f(...a)
|
|
284
289
|
});
|
|
@@ -295,7 +300,7 @@ var TriggerManager = class {
|
|
|
295
300
|
result: await res.json()
|
|
296
301
|
}, {
|
|
297
302
|
F: __dxlog_file2,
|
|
298
|
-
L:
|
|
303
|
+
L: 134,
|
|
299
304
|
S: this,
|
|
300
305
|
C: (f, a) => f(...a)
|
|
301
306
|
});
|
|
@@ -305,7 +310,7 @@ var TriggerManager = class {
|
|
|
305
310
|
error: err.message
|
|
306
311
|
}, {
|
|
307
312
|
F: __dxlog_file2,
|
|
308
|
-
L:
|
|
313
|
+
L: 136,
|
|
309
314
|
S: this,
|
|
310
315
|
C: (f, a) => f(...a)
|
|
311
316
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts", "../../../src/runtime/dev-server.ts", "../../../src/runtime/trigger-manager.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nexport * from './function';\nexport * from './runtime';\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport type http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type FunctionsManifest, type Response } from '../function';\n\nconst DEFAULT_PORT = 7000;\n\nexport type DevServerOptions = {\n directory: string;\n manifest: FunctionsManifest;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\n// TODO(burdon): Not secure.\nexport class DevServer {\n private readonly _functionHandlers: Record<string, FunctionHandler<any>> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get port() {\n return this._port;\n }\n\n get endpoint() {\n return this._port ? `http://localhost:${this._port}` : undefined;\n }\n\n get functions() {\n return Object.keys(this._functionHandlers);\n }\n\n async initialize() {\n for (const [name, _] of Object.entries(this._options.manifest.functions)) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(join(this._options.directory, name));\n const handler = module.default;\n if (typeof handler !== 'function') {\n throw new Error(`Handler must export default function: ${name}`);\n }\n\n this._functionHandlers[name] = handler;\n } catch (err) {\n log.error('parsing function (check functions.yml manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:functionName', async (req, res) => {\n const functionName = req.params.functionName;\n log('invoke', { function: functionName, data: req.body });\n\n const builder: Response = {\n status: (code: number) => {\n res.statusCode = code;\n return builder;\n },\n succeed: (result = {}) => {\n res.end(JSON.stringify(result));\n return builder;\n },\n };\n\n const context: FunctionContext = {\n client: this._client,\n status: builder.status.bind(builder),\n };\n\n void (async () => {\n try {\n // TODO(burdon): Typed event handler.\n await this._functionHandlers[functionName]({ event: req.body, context });\n } catch (err: any) {\n res.statusCode = 500;\n res.end(err.message);\n }\n })();\n });\n\n this._port = await getPortPromise({ startPort: DEFAULT_PORT });\n this._server = app.listen(this._port);\n\n // TODO(burdon): Check plugin is registered.\n // TypeError: Cannot read properties of undefined (reading 'register')\n try {\n const { registrationId } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint!,\n functions: this.functions.map((name) => ({ name })),\n });\n this._registrationId = registrationId;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available; check config (agent.plugins.functions).');\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 this._registrationId = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._server = undefined;\n this._port = undefined;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport type { Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionTrigger } from '../function';\n\n// TODO(burdon): Rename.\nexport type InvokeOptions = {\n endpoint: string;\n runtime: string;\n};\n\nexport class TriggerManager {\n private readonly _mounts = new ComplexMap<\n { name: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ name, spaceKey }) => `${spaceKey.toHex()}:${name}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _triggers: FunctionTrigger[],\n private readonly _invokeOptions: InvokeOptions,\n ) {}\n\n async start() {\n // TODO(burdon): Make runtime configurable (via CLI)?\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._triggers) {\n // TODO(burdon): New context? Shared?\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { name, spaceKey } of this._mounts.keys()) {\n await this.unmount(name, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { name: trigger.function, spaceKey: space.key };\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 // TODO(burdon): Trigger binding.\n // TODO(burdon): Why DeferredTask? How to pass objectIds to function?\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.invokeFunction(this._invokeOptions, trigger.function, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n let count = 0;\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 log('updated', {\n trigger,\n space: space.key,\n objects: objectIds.size,\n count,\n });\n\n task.schedule();\n count++;\n });\n
|
|
5
|
-
"mappings": "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
|
|
6
|
-
"names": ["DEFAULT_PORT", "DevServer", "constructor", "_client", "_options", "_functionHandlers", "port", "_port", "endpoint", "undefined", "functions", "Object", "keys", "initialize", "name", "_", "entries", "manifest", "module", "require", "join", "directory", "handler", "default", "Error", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "functionName", "params", "function", "data", "body", "builder", "status", "code", "statusCode", "succeed", "result", "end", "JSON", "stringify", "context", "client", "bind", "event", "message", "getPortPromise", "startPort", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "_registrationId", "stop", "trigger", "Trigger", "close", "unregister", "wake", "wait", "import_async", "import_log", "TriggerManager", "constructor", "_client", "_triggers", "_invokeOptions", "_mounts", "ComplexMap", "name", "spaceKey", "toHex", "start", "spaces", "subscribe", "space", "waitUntilReady", "trigger", "mount", "Context", "stop", "keys", "unmount", "ctx", "key", "function", "exists", "get", "set", "log", "disposed", "objectIds", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nexport * from './function';\nexport * from './runtime';\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport type http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type FunctionsManifest, type Response } from '../function';\n\nconst DEFAULT_PORT = 7000;\n\nexport type DevServerOptions = {\n directory: string;\n manifest: FunctionsManifest;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\n// TODO(burdon): Not secure.\nexport class DevServer {\n private readonly _functionHandlers: Record<string, FunctionHandler<any>> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get port() {\n return this._port;\n }\n\n get endpoint() {\n return this._port ? `http://localhost:${this._port}` : undefined;\n }\n\n get functions() {\n return Object.keys(this._functionHandlers);\n }\n\n async initialize() {\n for (const [name, _] of Object.entries(this._options.manifest.functions)) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(join(this._options.directory, name));\n const handler = module.default;\n if (typeof handler !== 'function') {\n throw new Error(`Handler must export default function: ${name}`);\n }\n\n this._functionHandlers[name] = handler;\n } catch (err) {\n log.error('parsing function (check functions.yml manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:functionName', async (req, res) => {\n const functionName = req.params.functionName;\n log('invoke', { function: functionName, data: req.body });\n\n const builder: Response = {\n status: (code: number) => {\n res.statusCode = code;\n return builder;\n },\n succeed: (result = {}) => {\n res.end(JSON.stringify(result));\n return builder;\n },\n };\n\n const context: FunctionContext = {\n client: this._client,\n status: builder.status.bind(builder),\n };\n\n void (async () => {\n try {\n // TODO(burdon): Typed event handler.\n await this._functionHandlers[functionName]({ event: req.body, context });\n } catch (err: any) {\n res.statusCode = 500;\n res.end(err.message);\n }\n })();\n });\n\n this._port = await getPortPromise({ startPort: DEFAULT_PORT });\n this._server = app.listen(this._port);\n\n // TODO(burdon): Check plugin is registered.\n // TypeError: Cannot read properties of undefined (reading 'register')\n try {\n const { registrationId } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint!,\n functions: this.functions.map((name) => ({ name })),\n });\n this._registrationId = registrationId;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available; check config (agent.plugins.functions).');\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 this._registrationId = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._server = undefined;\n this._port = undefined;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport type { Query, Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionTrigger } from '../function';\n\n// TODO(burdon): Rename.\nexport type InvokeOptions = {\n endpoint: string;\n runtime: string;\n};\n\nexport class TriggerManager {\n private readonly _mounts = new ComplexMap<\n { name: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ name, spaceKey }) => `${spaceKey.toHex()}:${name}`);\n\n private readonly _queries = new Set<Query>();\n\n constructor(\n private readonly _client: Client,\n private readonly _triggers: FunctionTrigger[],\n private readonly _invokeOptions: InvokeOptions,\n ) {}\n\n async start() {\n // TODO(burdon): Make runtime configurable (via CLI)?\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._triggers) {\n // TODO(burdon): New context? Shared?\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { name, spaceKey } of this._mounts.keys()) {\n await this.unmount(name, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { name: trigger.function, spaceKey: space.key };\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 // TODO(burdon): Trigger binding.\n // TODO(burdon): Why DeferredTask? How to pass objectIds to function?\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.invokeFunction(this._invokeOptions, trigger.function, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n let count = 0;\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 log('updated', {\n trigger,\n space: space.key,\n objects: objectIds.size,\n count,\n });\n\n task.schedule();\n count++;\n });\n // TODO(burdon): DSL for query (replace props).\n const query = space.db.query(Filter.typename(trigger.subscription.type, trigger.subscription.props));\n this._queries.add(query);\n const unsubscribe = query.subscribe(({ objects }) => {\n subscription.update(objects);\n }, true);\n\n ctx.onDispose(() => {\n subscription.unsubscribe();\n unsubscribe();\n this._queries.delete(query);\n });\n }\n }\n\n private async unmount(name: string, spaceKey: PublicKey) {\n const key = { name, 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 invokeFunction(options: InvokeOptions, functionName: string, data: any) {\n const { endpoint, runtime } = options;\n invariant(endpoint, 'Missing endpoint');\n invariant(runtime, 'Missing runtime');\n\n try {\n log('invoke', { function: functionName });\n const url = `${endpoint}/${runtime}/${functionName}`;\n const res = await fetch(url, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n log('result', { function: functionName, result: await res.json() });\n } catch (err: any) {\n log.error('error', { function: functionName, error: err.message });\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["DEFAULT_PORT", "DevServer", "constructor", "_client", "_options", "_functionHandlers", "port", "_port", "endpoint", "undefined", "functions", "Object", "keys", "initialize", "name", "_", "entries", "manifest", "module", "require", "join", "directory", "handler", "default", "Error", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "functionName", "params", "function", "data", "body", "builder", "status", "code", "statusCode", "succeed", "result", "end", "JSON", "stringify", "context", "client", "bind", "event", "message", "getPortPromise", "startPort", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "_registrationId", "stop", "trigger", "Trigger", "close", "unregister", "wake", "wait", "import_async", "import_log", "TriggerManager", "constructor", "_client", "_triggers", "_invokeOptions", "_mounts", "ComplexMap", "name", "spaceKey", "toHex", "_queries", "Set", "start", "spaces", "subscribe", "space", "waitUntilReady", "trigger", "mount", "Context", "stop", "keys", "unmount", "ctx", "key", "function", "exists", "get", "set", "log", "disposed", "objectIds", "task", "DeferredTask", "invokeFunction", "objects", "Array", "from", "count", "subscription", "createSubscription", "added", "updated", "object", "add", "id", "size", "schedule", "query", "db", "Filter", "typename", "type", "props", "unsubscribe", "update", "onDispose", "delete", "dispose", "options", "functionName", "data", "endpoint", "runtime", "invariant", "url", "res", "fetch", "method", "body", "JSON", "stringify", "headers", "result", "json", "err", "error", "message"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1782,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":14331,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"portfinder","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1782,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":14331,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"portfinder","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytes":16478,"imports":[{"path":"@dxos/async","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":584,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/trigger-manager.ts","kind":"import-statement","original":"./trigger-manager"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":550,"imports":[{"path":"packages/core/functions/src/function.ts","kind":"import-statement","original":"./function"},{"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":14720},"packages/core/functions/dist/lib/node/index.cjs":{"imports":[{"path":"express","kind":"require-call","external":true},{"path":"node:path","kind":"require-call","external":true},{"path":"portfinder","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/context","kind":"require-call","external":true},{"path":"@dxos/echo-schema","kind":"require-call","external":true},{"path":"@dxos/invariant","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/util","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/core/functions/src/index.ts","inputs":{"packages/core/functions/src/index.ts":{"bytesInOutput":163},"packages/core/functions/src/runtime/dev-server.ts":{"bytesInOutput":3456},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytesInOutput":4525}},"bytes":9850}}}
|
|
@@ -9,6 +9,7 @@ export declare class TriggerManager {
|
|
|
9
9
|
private readonly _triggers;
|
|
10
10
|
private readonly _invokeOptions;
|
|
11
11
|
private readonly _mounts;
|
|
12
|
+
private readonly _queries;
|
|
12
13
|
constructor(_client: Client, _triggers: FunctionTrigger[], _invokeOptions: InvokeOptions);
|
|
13
14
|
start(): Promise<void>;
|
|
14
15
|
stop(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trigger-manager.d.ts","sourceRoot":"","sources":["../../../../src/runtime/trigger-manager.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,MAAM,EAAkB,MAAM,cAAc,CAAC;AAQ3D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,cAAc;
|
|
1
|
+
{"version":3,"file":"trigger-manager.d.ts","sourceRoot":"","sources":["../../../../src/runtime/trigger-manager.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,MAAM,EAAkB,MAAM,cAAc,CAAC;AAQ3D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,cAAc;IASvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAVjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGiC;IAEzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;gBAG1B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,eAAe,EAAE,EAC5B,cAAc,EAAE,aAAa;IAG1C,KAAK;IAaL,IAAI;YAMI,KAAK;YAsDL,OAAO;YASP,cAAc;CAqB7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/functions",
|
|
3
|
-
"version": "0.3.5-main.
|
|
3
|
+
"version": "0.3.5-main.87eff54",
|
|
4
4
|
"description": "Functions SDK and runtime.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"express": "^4.17.1",
|
|
23
23
|
"portfinder": "^1.0.32",
|
|
24
|
-
"@dxos/async": "0.3.5-main.
|
|
25
|
-
"@dxos/client": "0.3.5-main.
|
|
26
|
-
"@dxos/context": "0.3.5-main.
|
|
27
|
-
"@dxos/echo-schema": "0.3.5-main.
|
|
28
|
-
"@dxos/invariant": "0.3.5-main.
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
24
|
+
"@dxos/async": "0.3.5-main.87eff54",
|
|
25
|
+
"@dxos/client": "0.3.5-main.87eff54",
|
|
26
|
+
"@dxos/context": "0.3.5-main.87eff54",
|
|
27
|
+
"@dxos/echo-schema": "0.3.5-main.87eff54",
|
|
28
|
+
"@dxos/invariant": "0.3.5-main.87eff54",
|
|
29
|
+
"@dxos/log": "0.3.5-main.87eff54",
|
|
30
|
+
"@dxos/node-std": "0.3.5-main.87eff54",
|
|
31
|
+
"@dxos/util": "0.3.5-main.87eff54"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/express": "^4.17.17"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { DeferredTask } from '@dxos/async';
|
|
6
6
|
import { type Client, type PublicKey } from '@dxos/client';
|
|
7
|
-
import type { Space } from '@dxos/client/echo';
|
|
7
|
+
import type { Query, Space } from '@dxos/client/echo';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { Filter, createSubscription } from '@dxos/echo-schema';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
@@ -25,6 +25,8 @@ export class TriggerManager {
|
|
|
25
25
|
{ ctx: Context; trigger: FunctionTrigger }
|
|
26
26
|
>(({ name, spaceKey }) => `${spaceKey.toHex()}:${name}`);
|
|
27
27
|
|
|
28
|
+
private readonly _queries = new Set<Query>();
|
|
29
|
+
|
|
28
30
|
constructor(
|
|
29
31
|
private readonly _client: Client,
|
|
30
32
|
private readonly _triggers: FunctionTrigger[],
|
|
@@ -89,19 +91,18 @@ export class TriggerManager {
|
|
|
89
91
|
task.schedule();
|
|
90
92
|
count++;
|
|
91
93
|
});
|
|
92
|
-
|
|
93
|
-
ctx.onDispose(() => subscription.unsubscribe());
|
|
94
|
-
|
|
95
94
|
// TODO(burdon): DSL for query (replace props).
|
|
96
95
|
const query = space.db.query(Filter.typename(trigger.subscription.type, trigger.subscription.props));
|
|
96
|
+
this._queries.add(query);
|
|
97
97
|
const unsubscribe = query.subscribe(({ objects }) => {
|
|
98
98
|
subscription.update(objects);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// TODO(burdon): Option to trigger on first subscription.
|
|
102
|
-
// TODO(burdon): After restart not triggered.
|
|
99
|
+
}, true);
|
|
103
100
|
|
|
104
|
-
ctx.onDispose(() =>
|
|
101
|
+
ctx.onDispose(() => {
|
|
102
|
+
subscription.unsubscribe();
|
|
103
|
+
unsubscribe();
|
|
104
|
+
this._queries.delete(query);
|
|
105
|
+
});
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
|