@dxos/functions 0.3.4 → 0.3.5-main.1429e83
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 +27 -25
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +26 -24
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/function.d.ts +2 -1
- package/dist/types/src/function.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.d.ts +1 -1
- package/dist/types/src/runtime/dev-server.d.ts.map +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/function.ts +3 -2
- package/src/runtime/dev-server.ts +7 -8
- package/src/runtime/trigger-manager.ts +12 -11
|
@@ -13,14 +13,14 @@ import { join } from "@dxos/node-std/path";
|
|
|
13
13
|
import { getPortPromise } from "portfinder";
|
|
14
14
|
import { Trigger } from "@dxos/async";
|
|
15
15
|
import { log } from "@dxos/log";
|
|
16
|
-
var __dxlog_file = "/home/
|
|
16
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
|
|
17
17
|
var DEFAULT_PORT = 7e3;
|
|
18
18
|
var DevServer = class {
|
|
19
19
|
// prettier-ignore
|
|
20
20
|
constructor(_client, _options) {
|
|
21
21
|
this._client = _client;
|
|
22
22
|
this._options = _options;
|
|
23
|
-
this.
|
|
23
|
+
this._handlers = {};
|
|
24
24
|
}
|
|
25
25
|
get port() {
|
|
26
26
|
return this._port;
|
|
@@ -29,21 +29,21 @@ var DevServer = class {
|
|
|
29
29
|
return this._port ? `http://localhost:${this._port}` : void 0;
|
|
30
30
|
}
|
|
31
31
|
get functions() {
|
|
32
|
-
return Object.keys(this.
|
|
32
|
+
return Object.keys(this._handlers);
|
|
33
33
|
}
|
|
34
34
|
async initialize() {
|
|
35
|
-
for (const
|
|
35
|
+
for (const { id } of this._options.manifest.functions) {
|
|
36
36
|
try {
|
|
37
|
-
const module = __require(join(this._options.directory,
|
|
37
|
+
const module = __require(join(this._options.directory, id));
|
|
38
38
|
const handler = module.default;
|
|
39
39
|
if (typeof handler !== "function") {
|
|
40
|
-
throw new Error(`Handler must export default function: ${
|
|
40
|
+
throw new Error(`Handler must export default function: ${id}`);
|
|
41
41
|
}
|
|
42
|
-
this.
|
|
42
|
+
this._handlers[id] = handler;
|
|
43
43
|
} catch (err) {
|
|
44
44
|
log.error("parsing function (check functions.yml manifest)", err, {
|
|
45
45
|
F: __dxlog_file,
|
|
46
|
-
L:
|
|
46
|
+
L: 63,
|
|
47
47
|
S: this,
|
|
48
48
|
C: (f, a) => f(...a)
|
|
49
49
|
});
|
|
@@ -60,7 +60,7 @@ var DevServer = class {
|
|
|
60
60
|
data: req.body
|
|
61
61
|
}, {
|
|
62
62
|
F: __dxlog_file,
|
|
63
|
-
L:
|
|
63
|
+
L: 74,
|
|
64
64
|
S: this,
|
|
65
65
|
C: (f, a) => f(...a)
|
|
66
66
|
});
|
|
@@ -80,7 +80,7 @@ var DevServer = class {
|
|
|
80
80
|
};
|
|
81
81
|
void (async () => {
|
|
82
82
|
try {
|
|
83
|
-
await this.
|
|
83
|
+
await this._handlers[functionName]({
|
|
84
84
|
event: req.body,
|
|
85
85
|
context
|
|
86
86
|
});
|
|
@@ -127,17 +127,18 @@ var DevServer = class {
|
|
|
127
127
|
// packages/core/functions/src/runtime/trigger-manager.ts
|
|
128
128
|
import { DeferredTask } from "@dxos/async";
|
|
129
129
|
import { Context } from "@dxos/context";
|
|
130
|
-
import { createSubscription } from "@dxos/echo-schema";
|
|
130
|
+
import { Filter, createSubscription } from "@dxos/echo-schema";
|
|
131
131
|
import { invariant } from "@dxos/invariant";
|
|
132
132
|
import { log as log2 } from "@dxos/log";
|
|
133
133
|
import { ComplexMap } from "@dxos/util";
|
|
134
|
-
var __dxlog_file2 = "/home/
|
|
134
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/trigger-manager.ts";
|
|
135
135
|
var TriggerManager = class {
|
|
136
136
|
constructor(_client, _triggers, _invokeOptions) {
|
|
137
137
|
this._client = _client;
|
|
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,22 +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
|
-
|
|
210
|
-
|
|
211
|
-
"@type": trigger.subscription.type,
|
|
212
|
-
...trigger.subscription.props
|
|
213
|
-
});
|
|
210
|
+
const query = space.db.query(Filter.typename(trigger.subscription.type, trigger.subscription.props));
|
|
211
|
+
this._queries.add(query);
|
|
214
212
|
const unsubscribe = query.subscribe(({ objects }) => {
|
|
215
213
|
subscription.update(objects);
|
|
214
|
+
}, true);
|
|
215
|
+
ctx.onDispose(() => {
|
|
216
|
+
subscription.unsubscribe();
|
|
217
|
+
unsubscribe();
|
|
218
|
+
this._queries.delete(query);
|
|
216
219
|
});
|
|
217
|
-
ctx.onDispose(() => unsubscribe());
|
|
218
220
|
}
|
|
219
221
|
}
|
|
220
222
|
async unmount(name, spaceKey) {
|
|
@@ -232,7 +234,7 @@ var TriggerManager = class {
|
|
|
232
234
|
const { endpoint, runtime } = options;
|
|
233
235
|
invariant(endpoint, "Missing endpoint", {
|
|
234
236
|
F: __dxlog_file2,
|
|
235
|
-
L:
|
|
237
|
+
L: 120,
|
|
236
238
|
S: this,
|
|
237
239
|
A: [
|
|
238
240
|
"endpoint",
|
|
@@ -241,7 +243,7 @@ var TriggerManager = class {
|
|
|
241
243
|
});
|
|
242
244
|
invariant(runtime, "Missing runtime", {
|
|
243
245
|
F: __dxlog_file2,
|
|
244
|
-
L:
|
|
246
|
+
L: 121,
|
|
245
247
|
S: this,
|
|
246
248
|
A: [
|
|
247
249
|
"runtime",
|
|
@@ -253,7 +255,7 @@ var TriggerManager = class {
|
|
|
253
255
|
function: functionName
|
|
254
256
|
}, {
|
|
255
257
|
F: __dxlog_file2,
|
|
256
|
-
L:
|
|
258
|
+
L: 124,
|
|
257
259
|
S: this,
|
|
258
260
|
C: (f, a) => f(...a)
|
|
259
261
|
});
|
|
@@ -270,7 +272,7 @@ var TriggerManager = class {
|
|
|
270
272
|
result: await res.json()
|
|
271
273
|
}, {
|
|
272
274
|
F: __dxlog_file2,
|
|
273
|
-
L:
|
|
275
|
+
L: 134,
|
|
274
276
|
S: this,
|
|
275
277
|
C: (f, a) => f(...a)
|
|
276
278
|
});
|
|
@@ -280,7 +282,7 @@ var TriggerManager = class {
|
|
|
280
282
|
error: err.message
|
|
281
283
|
}, {
|
|
282
284
|
F: __dxlog_file2,
|
|
283
|
-
L:
|
|
285
|
+
L: 136,
|
|
284
286
|
S: this,
|
|
285
287
|
C: (f, a) => f(...a)
|
|
286
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 */\
|
|
5
|
-
"mappings": ";;;;;;;;;;AAIA,OAAOA,aAAa;AAEpB,SAASC,YAAY;AACrB,SAASC,sBAAsB;AAE/B,SAASC,eAAe;AAExB,SAASC,WAAW;;AAIpB,IAAMC,eAAe;
|
|
6
|
-
"names": ["express", "join", "getPortPromise", "Trigger", "log", "DEFAULT_PORT", "DevServer", "constructor", "_client", "_options", "
|
|
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 */\nexport class DevServer {\n private readonly _handlers: 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._handlers);\n }\n\n async initialize() {\n for (const { id } of this._options.manifest.functions) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(join(this._options.directory, id));\n const handler = module.default;\n if (typeof handler !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[id] = 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._handlers[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", "_handlers", "port", "_port", "endpoint", "undefined", "functions", "Object", "keys", "initialize", "id", "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", "name", "_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":
|
|
1
|
+
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1782,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":14045,"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":14517},"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":3247},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytesInOutput":4320}},"bytes":8159}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -41,14 +41,14 @@ var import_node_path = require("node:path");
|
|
|
41
41
|
var import_portfinder = require("portfinder");
|
|
42
42
|
var import_async = require("@dxos/async");
|
|
43
43
|
var import_log = require("@dxos/log");
|
|
44
|
-
var __dxlog_file = "/home/
|
|
44
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
|
|
45
45
|
var DEFAULT_PORT = 7e3;
|
|
46
46
|
var DevServer = class {
|
|
47
47
|
// prettier-ignore
|
|
48
48
|
constructor(_client, _options) {
|
|
49
49
|
this._client = _client;
|
|
50
50
|
this._options = _options;
|
|
51
|
-
this.
|
|
51
|
+
this._handlers = {};
|
|
52
52
|
}
|
|
53
53
|
get port() {
|
|
54
54
|
return this._port;
|
|
@@ -57,21 +57,21 @@ var DevServer = class {
|
|
|
57
57
|
return this._port ? `http://localhost:${this._port}` : void 0;
|
|
58
58
|
}
|
|
59
59
|
get functions() {
|
|
60
|
-
return Object.keys(this.
|
|
60
|
+
return Object.keys(this._handlers);
|
|
61
61
|
}
|
|
62
62
|
async initialize() {
|
|
63
|
-
for (const
|
|
63
|
+
for (const { id } of this._options.manifest.functions) {
|
|
64
64
|
try {
|
|
65
|
-
const module2 = require((0, import_node_path.join)(this._options.directory,
|
|
65
|
+
const module2 = require((0, import_node_path.join)(this._options.directory, id));
|
|
66
66
|
const handler = module2.default;
|
|
67
67
|
if (typeof handler !== "function") {
|
|
68
|
-
throw new Error(`Handler must export default function: ${
|
|
68
|
+
throw new Error(`Handler must export default function: ${id}`);
|
|
69
69
|
}
|
|
70
|
-
this.
|
|
70
|
+
this._handlers[id] = handler;
|
|
71
71
|
} catch (err) {
|
|
72
72
|
import_log.log.error("parsing function (check functions.yml manifest)", err, {
|
|
73
73
|
F: __dxlog_file,
|
|
74
|
-
L:
|
|
74
|
+
L: 63,
|
|
75
75
|
S: this,
|
|
76
76
|
C: (f, a) => f(...a)
|
|
77
77
|
});
|
|
@@ -88,7 +88,7 @@ var DevServer = class {
|
|
|
88
88
|
data: req.body
|
|
89
89
|
}, {
|
|
90
90
|
F: __dxlog_file,
|
|
91
|
-
L:
|
|
91
|
+
L: 74,
|
|
92
92
|
S: this,
|
|
93
93
|
C: (f, a) => f(...a)
|
|
94
94
|
});
|
|
@@ -108,7 +108,7 @@ var DevServer = class {
|
|
|
108
108
|
};
|
|
109
109
|
void (async () => {
|
|
110
110
|
try {
|
|
111
|
-
await this.
|
|
111
|
+
await this._handlers[functionName]({
|
|
112
112
|
event: req.body,
|
|
113
113
|
context
|
|
114
114
|
});
|
|
@@ -159,13 +159,14 @@ var import_echo_schema = require("@dxos/echo-schema");
|
|
|
159
159
|
var import_invariant = require("@dxos/invariant");
|
|
160
160
|
var import_log2 = require("@dxos/log");
|
|
161
161
|
var import_util = require("@dxos/util");
|
|
162
|
-
var __dxlog_file2 = "/home/
|
|
162
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/trigger-manager.ts";
|
|
163
163
|
var TriggerManager = class {
|
|
164
164
|
constructor(_client, _triggers, _invokeOptions) {
|
|
165
165
|
this._client = _client;
|
|
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,22 +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
|
-
|
|
238
|
-
|
|
239
|
-
"@type": trigger.subscription.type,
|
|
240
|
-
...trigger.subscription.props
|
|
241
|
-
});
|
|
238
|
+
const query = space.db.query(import_echo_schema.Filter.typename(trigger.subscription.type, trigger.subscription.props));
|
|
239
|
+
this._queries.add(query);
|
|
242
240
|
const unsubscribe = query.subscribe(({ objects }) => {
|
|
243
241
|
subscription.update(objects);
|
|
242
|
+
}, true);
|
|
243
|
+
ctx.onDispose(() => {
|
|
244
|
+
subscription.unsubscribe();
|
|
245
|
+
unsubscribe();
|
|
246
|
+
this._queries.delete(query);
|
|
244
247
|
});
|
|
245
|
-
ctx.onDispose(() => unsubscribe());
|
|
246
248
|
}
|
|
247
249
|
}
|
|
248
250
|
async unmount(name, spaceKey) {
|
|
@@ -260,7 +262,7 @@ var TriggerManager = class {
|
|
|
260
262
|
const { endpoint, runtime } = options;
|
|
261
263
|
(0, import_invariant.invariant)(endpoint, "Missing endpoint", {
|
|
262
264
|
F: __dxlog_file2,
|
|
263
|
-
L:
|
|
265
|
+
L: 120,
|
|
264
266
|
S: this,
|
|
265
267
|
A: [
|
|
266
268
|
"endpoint",
|
|
@@ -269,7 +271,7 @@ var TriggerManager = class {
|
|
|
269
271
|
});
|
|
270
272
|
(0, import_invariant.invariant)(runtime, "Missing runtime", {
|
|
271
273
|
F: __dxlog_file2,
|
|
272
|
-
L:
|
|
274
|
+
L: 121,
|
|
273
275
|
S: this,
|
|
274
276
|
A: [
|
|
275
277
|
"runtime",
|
|
@@ -281,7 +283,7 @@ var TriggerManager = class {
|
|
|
281
283
|
function: functionName
|
|
282
284
|
}, {
|
|
283
285
|
F: __dxlog_file2,
|
|
284
|
-
L:
|
|
286
|
+
L: 124,
|
|
285
287
|
S: this,
|
|
286
288
|
C: (f, a) => f(...a)
|
|
287
289
|
});
|
|
@@ -298,7 +300,7 @@ var TriggerManager = class {
|
|
|
298
300
|
result: await res.json()
|
|
299
301
|
}, {
|
|
300
302
|
F: __dxlog_file2,
|
|
301
|
-
L:
|
|
303
|
+
L: 134,
|
|
302
304
|
S: this,
|
|
303
305
|
C: (f, a) => f(...a)
|
|
304
306
|
});
|
|
@@ -308,7 +310,7 @@ var TriggerManager = class {
|
|
|
308
310
|
error: err.message
|
|
309
311
|
}, {
|
|
310
312
|
F: __dxlog_file2,
|
|
311
|
-
L:
|
|
313
|
+
L: 136,
|
|
312
314
|
S: this,
|
|
313
315
|
C: (f, a) => f(...a)
|
|
314
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 */\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;ACIA,qBAAoB;AAEpB,uBAAqB;AACrB,wBAA+B;AAE/B,mBAAwB;AAExB,iBAAoB;;AAIpB,IAAMA,eAAe;
|
|
6
|
-
"names": ["DEFAULT_PORT", "DevServer", "constructor", "_client", "_options", "
|
|
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 */\nexport class DevServer {\n private readonly _handlers: 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._handlers);\n }\n\n async initialize() {\n for (const { id } of this._options.manifest.functions) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(join(this._options.directory, id));\n const handler = module.default;\n if (typeof handler !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[id] = 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._handlers[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", "_handlers", "port", "_port", "endpoint", "undefined", "functions", "Object", "keys", "initialize", "id", "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", "name", "_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":
|
|
1
|
+
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1782,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":14045,"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":14580},"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":3399},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytesInOutput":4525}},"bytes":9793}}}
|
|
@@ -16,10 +16,11 @@ export type FunctionHandler<T extends {}> = (params: {
|
|
|
16
16
|
context: FunctionContext;
|
|
17
17
|
}) => Promise<Response | void>;
|
|
18
18
|
export type FunctionsManifest = {
|
|
19
|
-
functions:
|
|
19
|
+
functions: FunctionConfig[];
|
|
20
20
|
triggers: FunctionTrigger[];
|
|
21
21
|
};
|
|
22
22
|
export type FunctionConfig = {
|
|
23
|
+
id: string;
|
|
23
24
|
description?: string;
|
|
24
25
|
};
|
|
25
26
|
export type FunctionTrigger = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../../../src/function.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC;AAMD,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,EAAE,eAAe,CAAC;CAC1B,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAE/B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../../../src/function.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC;AAMD,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,EAAE,eAAe,CAAC;CAC1B,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAE/B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,mBAAmB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC"}
|
|
@@ -10,7 +10,7 @@ export type DevServerOptions = {
|
|
|
10
10
|
export declare class DevServer {
|
|
11
11
|
private readonly _client;
|
|
12
12
|
private readonly _options;
|
|
13
|
-
private readonly
|
|
13
|
+
private readonly _handlers;
|
|
14
14
|
private _server?;
|
|
15
15
|
private _port?;
|
|
16
16
|
private _registrationId?;
|
|
@@ -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;AAG3C,OAAO,EAA8C,KAAK,iBAAiB,EAAiB,MAAM,aAAa,CAAC;AAIhH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AAEF;;GAEG;
|
|
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;AAG3C,OAAO,EAA8C,KAAK,iBAAiB,EAAiB,MAAM,aAAa,CAAC;AAIhH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IASlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IAEtE,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,eAAe,CAAC,CAAS;gBAId,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,gBAAgB;IAG7C,IAAI,IAAI,uBAEP;IAED,IAAI,QAAQ,uBAEX;IAED,IAAI,SAAS,aAEZ;IAEK,UAAU;IAiBV,KAAK;IAoDL,IAAI;CAiBX"}
|
|
@@ -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.
|
|
3
|
+
"version": "0.3.5-main.1429e83",
|
|
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/
|
|
25
|
-
"@dxos/
|
|
26
|
-
"@dxos/
|
|
27
|
-
"@dxos/
|
|
28
|
-
"@dxos/invariant": "0.3.
|
|
29
|
-
"@dxos/log": "0.3.
|
|
30
|
-
"@dxos/node-std": "0.3.
|
|
31
|
-
"@dxos/util": "0.3.
|
|
24
|
+
"@dxos/context": "0.3.5-main.1429e83",
|
|
25
|
+
"@dxos/echo-schema": "0.3.5-main.1429e83",
|
|
26
|
+
"@dxos/async": "0.3.5-main.1429e83",
|
|
27
|
+
"@dxos/client": "0.3.5-main.1429e83",
|
|
28
|
+
"@dxos/invariant": "0.3.5-main.1429e83",
|
|
29
|
+
"@dxos/log": "0.3.5-main.1429e83",
|
|
30
|
+
"@dxos/node-std": "0.3.5-main.1429e83",
|
|
31
|
+
"@dxos/util": "0.3.5-main.1429e83"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/express": "^4.17.17"
|
package/src/function.ts
CHANGED
|
@@ -14,8 +14,8 @@ export interface FunctionContext {
|
|
|
14
14
|
status(code: number): Response;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html
|
|
18
17
|
// https://www.npmjs.com/package/aws-lambda
|
|
18
|
+
// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html
|
|
19
19
|
|
|
20
20
|
// TODO(burdon): Types.
|
|
21
21
|
export type FunctionSubscriptionEvent = {
|
|
@@ -29,11 +29,12 @@ export type FunctionHandler<T extends {}> = (params: {
|
|
|
29
29
|
}) => Promise<Response | void>;
|
|
30
30
|
|
|
31
31
|
export type FunctionsManifest = {
|
|
32
|
-
functions:
|
|
32
|
+
functions: FunctionConfig[];
|
|
33
33
|
triggers: FunctionTrigger[];
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export type FunctionConfig = {
|
|
37
|
+
id: string;
|
|
37
38
|
description?: string;
|
|
38
39
|
};
|
|
39
40
|
|
|
@@ -23,9 +23,8 @@ export type DevServerOptions = {
|
|
|
23
23
|
/**
|
|
24
24
|
* Functions dev server provides a local HTTP server for testing functions.
|
|
25
25
|
*/
|
|
26
|
-
// TODO(burdon): Not secure.
|
|
27
26
|
export class DevServer {
|
|
28
|
-
private readonly
|
|
27
|
+
private readonly _handlers: Record<string, FunctionHandler<any>> = {};
|
|
29
28
|
|
|
30
29
|
private _server?: http.Server;
|
|
31
30
|
private _port?: number;
|
|
@@ -46,20 +45,20 @@ export class DevServer {
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
get functions() {
|
|
49
|
-
return Object.keys(this.
|
|
48
|
+
return Object.keys(this._handlers);
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
async initialize() {
|
|
53
|
-
for (const
|
|
52
|
+
for (const { id } of this._options.manifest.functions) {
|
|
54
53
|
try {
|
|
55
54
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
56
|
-
const module = require(join(this._options.directory,
|
|
55
|
+
const module = require(join(this._options.directory, id));
|
|
57
56
|
const handler = module.default;
|
|
58
57
|
if (typeof handler !== 'function') {
|
|
59
|
-
throw new Error(`Handler must export default function: ${
|
|
58
|
+
throw new Error(`Handler must export default function: ${id}`);
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
this.
|
|
61
|
+
this._handlers[id] = handler;
|
|
63
62
|
} catch (err) {
|
|
64
63
|
log.error('parsing function (check functions.yml manifest)', err);
|
|
65
64
|
}
|
|
@@ -93,7 +92,7 @@ export class DevServer {
|
|
|
93
92
|
void (async () => {
|
|
94
93
|
try {
|
|
95
94
|
// TODO(burdon): Typed event handler.
|
|
96
|
-
await this.
|
|
95
|
+
await this._handlers[functionName]({ event: req.body, context });
|
|
97
96
|
} catch (err: any) {
|
|
98
97
|
res.statusCode = 500;
|
|
99
98
|
res.end(err.message);
|
|
@@ -4,9 +4,9 @@
|
|
|
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
|
-
import { createSubscription } from '@dxos/echo-schema';
|
|
9
|
+
import { Filter, createSubscription } from '@dxos/echo-schema';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { ComplexMap } from '@dxos/util';
|
|
@@ -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
|
-
const query = space.db.query(
|
|
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
|
|