@dxos/functions 0.1.53-main.75474bf → 0.1.53-main.8f662cd
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/README.md +3 -11
- package/dist/lib/browser/index.mjs +39 -15
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +39 -15
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
- package/dist/types/src/runtime/trigger-manager.d.ts +0 -7
- package/dist/types/src/runtime/trigger-manager.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/runtime/dev-server.ts +3 -0
- package/src/runtime/trigger-manager.ts +26 -19
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ export default (event: any, context: FunctionContext) => {
|
|
|
35
35
|
};
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
## Running functions with dev
|
|
38
|
+
## Running functions with the dev server:
|
|
39
39
|
|
|
40
40
|
Configure the agent to run functions on a given port:
|
|
41
41
|
|
|
@@ -50,26 +50,18 @@ runtime:
|
|
|
50
50
|
Start functions in dev mode (from the related package):
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
dx function dev -r ts-node/register
|
|
53
|
+
dx function dev-server -r ts-node/register
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
> NOTE: `-r ts-node/register` configures native TypesScript support.
|
|
57
57
|
|
|
58
|
-
TODO(burdon): Specify additional options to import dependencies:
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
export NODE_PATH=$(git rev-parse --show-toplevel)/packages/experimental/kai-bots/node_modules
|
|
62
|
-
|
|
63
|
-
dx function dev -r ts-node/register -r chess.js
|
|
64
|
-
```
|
|
65
|
-
|
|
66
58
|
Install `nodemon` to support live reloading:
|
|
67
59
|
|
|
68
60
|
```bash
|
|
69
61
|
npm i -g nodemon
|
|
70
62
|
export DXOS_ROOT=$(git rev-parse --show-toplevel)
|
|
71
63
|
|
|
72
|
-
nodemon -w ./src -e ts --exec $DXOS_ROOT/packages/devtools/cli/bin/dev function dev -r ts-node/register
|
|
64
|
+
nodemon -w ./src -e ts --exec $DXOS_ROOT/packages/devtools/cli/bin/dev function dev-server -r ts-node/register
|
|
73
65
|
```
|
|
74
66
|
|
|
75
67
|
## Invoking functions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "@dxos/node-std/globals"
|
|
1
|
+
import "@dxos/node-std/globals";
|
|
2
2
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
3
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
4
|
}) : x)(function(x) {
|
|
@@ -54,6 +54,15 @@ var DevServer = class {
|
|
|
54
54
|
app.use(express.json());
|
|
55
55
|
app.post("/:functionName", async (req, res) => {
|
|
56
56
|
const functionName = req.params.functionName;
|
|
57
|
+
log("invoke", {
|
|
58
|
+
function: functionName,
|
|
59
|
+
data: req.body
|
|
60
|
+
}, {
|
|
61
|
+
file: "dev-server.ts",
|
|
62
|
+
line: 74,
|
|
63
|
+
scope: this,
|
|
64
|
+
callSite: (f, a) => f(...a)
|
|
65
|
+
});
|
|
57
66
|
const builder = {
|
|
58
67
|
status: (code) => {
|
|
59
68
|
res.statusCode = code;
|
|
@@ -111,8 +120,8 @@ var DevServer = class {
|
|
|
111
120
|
import assert from "@dxos/node-std/assert";
|
|
112
121
|
import { DeferredTask } from "@dxos/async";
|
|
113
122
|
import { Context } from "@dxos/context";
|
|
123
|
+
import { createSubscription } from "@dxos/echo-schema";
|
|
114
124
|
import { log as log2 } from "@dxos/log";
|
|
115
|
-
import { createSubscription } from "@dxos/observable-object";
|
|
116
125
|
import { ComplexMap } from "@dxos/util";
|
|
117
126
|
var TriggerManager = class {
|
|
118
127
|
constructor(_client, _triggers, _invokeOptions) {
|
|
@@ -150,10 +159,11 @@ var TriggerManager = class {
|
|
|
150
159
|
if (ctx.disposed) {
|
|
151
160
|
return;
|
|
152
161
|
}
|
|
153
|
-
|
|
162
|
+
let count = 0;
|
|
163
|
+
const objectIds = /* @__PURE__ */ new Set();
|
|
154
164
|
const task = new DeferredTask(ctx, async () => {
|
|
155
|
-
const updatedObjects = Array.from(
|
|
156
|
-
|
|
165
|
+
const updatedObjects = Array.from(objectIds);
|
|
166
|
+
objectIds.clear();
|
|
157
167
|
await this.invokeFunction(this._invokeOptions, trigger.function, {
|
|
158
168
|
space: space.key,
|
|
159
169
|
objects: updatedObjects
|
|
@@ -161,12 +171,26 @@ var TriggerManager = class {
|
|
|
161
171
|
});
|
|
162
172
|
const selection = createSubscription(({ added, updated }) => {
|
|
163
173
|
for (const object of added) {
|
|
164
|
-
|
|
174
|
+
objectIds.add(object.id);
|
|
165
175
|
}
|
|
166
176
|
for (const object1 of updated) {
|
|
167
|
-
|
|
177
|
+
objectIds.add(object1.id);
|
|
178
|
+
}
|
|
179
|
+
log2.info("updated", {
|
|
180
|
+
space: space.key,
|
|
181
|
+
objects: objectIds.size,
|
|
182
|
+
added: added.length,
|
|
183
|
+
updated: updated.length,
|
|
184
|
+
count
|
|
185
|
+
}, {
|
|
186
|
+
file: "trigger-manager.ts",
|
|
187
|
+
line: 86,
|
|
188
|
+
scope: this,
|
|
189
|
+
callSite: (f, a) => f(...a)
|
|
190
|
+
});
|
|
191
|
+
if (count++) {
|
|
192
|
+
task.schedule();
|
|
168
193
|
}
|
|
169
|
-
task.schedule();
|
|
170
194
|
});
|
|
171
195
|
ctx.onDispose(() => selection.unsubscribe());
|
|
172
196
|
const query = space.db.query({
|
|
@@ -176,13 +200,13 @@ var TriggerManager = class {
|
|
|
176
200
|
const unsubscribe = query.subscribe(({ objects }) => {
|
|
177
201
|
selection.update(objects);
|
|
178
202
|
});
|
|
179
|
-
selection.update(query.objects);
|
|
180
203
|
ctx.onDispose(unsubscribe);
|
|
181
|
-
log2("mounted", {
|
|
204
|
+
log2.info("mounted", {
|
|
205
|
+
space: space.key,
|
|
182
206
|
trigger
|
|
183
207
|
}, {
|
|
184
208
|
file: "trigger-manager.ts",
|
|
185
|
-
line:
|
|
209
|
+
line: 110,
|
|
186
210
|
scope: this,
|
|
187
211
|
callSite: (f, a) => f(...a)
|
|
188
212
|
});
|
|
@@ -209,7 +233,7 @@ var TriggerManager = class {
|
|
|
209
233
|
function: functionName
|
|
210
234
|
}, {
|
|
211
235
|
file: "trigger-manager.ts",
|
|
212
|
-
line:
|
|
236
|
+
line: 129,
|
|
213
237
|
scope: this,
|
|
214
238
|
callSite: (f, a) => f(...a)
|
|
215
239
|
});
|
|
@@ -226,17 +250,17 @@ var TriggerManager = class {
|
|
|
226
250
|
result: await res.json()
|
|
227
251
|
}, {
|
|
228
252
|
file: "trigger-manager.ts",
|
|
229
|
-
line:
|
|
253
|
+
line: 139,
|
|
230
254
|
scope: this,
|
|
231
255
|
callSite: (f, a) => f(...a)
|
|
232
256
|
});
|
|
233
257
|
} catch (err) {
|
|
234
|
-
log2("error", {
|
|
258
|
+
log2.error("error", {
|
|
235
259
|
function: functionName,
|
|
236
260
|
error: err.message
|
|
237
261
|
}, {
|
|
238
262
|
file: "trigger-manager.ts",
|
|
239
|
-
line:
|
|
263
|
+
line: 141,
|
|
240
264
|
scope: this,
|
|
241
265
|
callSite: (f, a) => f(...a)
|
|
242
266
|
});
|
|
@@ -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 http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { FunctionContext, FunctionHandler, FunctionsManifest, 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 _functionHandlers: Record<string, FunctionHandler> = {};\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\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 await this._functionHandlers[functionName](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 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 }\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 assert from 'node:assert';\n\nimport { DeferredTask } from '@dxos/async';\nimport { Client, PublicKey
|
|
5
|
-
"mappings": ";;;;;;;;;;AAIA,OAAOA,aAAa;AAEpB,SAASC,YAAY;AACrB,SAASC,sBAAsB;AAE/B,SAASC,eAAe;AAExB,SAASC,WAAW;AAIpB,IAAMC,eAAe;AAUd,IAAMC,YAAN,MAAMA;;EAQXC,YACmBC,SACAC,UACjB;mBAFiBD;oBACAC;SATFC,oBAAqD,CAAC;EAUpE;EAEH,IAAIC,OAAO;AACT,WAAO,KAAKC;EACd;EAEA,IAAIC,WAAW;AACb,WAAO,KAAKD,QAAQ,oBAAoB,KAAKA,UAAUE;EACzD;EAEA,IAAIC,YAAY;AACd,WAAOC,OAAOC,KAAK,KAAKP,iBAAiB;EAC3C;EAEA,MAAMQ,aAAa;AACjB,eAAW,CAACC,MAAMC,CAAAA,KAAMJ,OAAOK,QAAQ,KAAKZ,SAASa,SAASP,SAAS,GAAG;AACxE,UAAI;AAEF,cAAMQ,SAASC,UAAQC,KAAK,KAAKhB,SAASiB,WAAWP,IAAAA,CAAAA;AACrD,cAAMQ,UAAUJ,OAAOK;AACvB,YAAI,OAAOD,YAAY,YAAY;AACjC,gBAAM,IAAIE,MAAM,yCAAyCV,MAAM;QACjE;AAEA,aAAKT,kBAAkBS,IAAAA,IAAQQ;MACjC,SAASG,KAAP;AACAC,YAAIC,MAAM,mDAAmDF,KAAAA;;;;;;MAC/D;IACF;EACF;EAEA,MAAMG,QAAQ;AACZ,UAAMC,MAAMC,QAAAA;AACZD,QAAIE,IAAID,QAAQE,KAAI,CAAA;AAEpBH,QAAII,KAAK,kBAAkB,OAAOC,KAAKC,QAAQ;AAC7C,YAAMC,eAAeF,IAAIG,OAAOD;
|
|
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", "builder", "status", "code", "statusCode", "succeed", "result", "end", "JSON", "stringify", "context", "client", "bind", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { FunctionContext, FunctionHandler, FunctionsManifest, 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 _functionHandlers: Record<string, FunctionHandler> = {};\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 await this._functionHandlers[functionName](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 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 }\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 assert from 'node:assert';\n\nimport { DeferredTask } from '@dxos/async';\nimport { Client, PublicKey } from '@dxos/client';\nimport type { Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { createSubscription } from '@dxos/echo-schema';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { 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(), trigger, space);\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, trigger: FunctionTrigger, space: Space) {\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 if (ctx.disposed) {\n return;\n }\n\n // TODO(burdon): Factor out subscription/result delta.\n\n let count = 0;\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n const updatedObjects = Array.from(objectIds);\n objectIds.clear();\n\n await this.invokeFunction(this._invokeOptions, trigger.function, {\n space: space.key,\n objects: updatedObjects,\n });\n });\n\n // TODO(burdon): Removed?\n const selection = 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.info('updated', {\n space: space.key,\n objects: objectIds.size,\n added: added.length,\n updated: updated.length,\n count,\n });\n if (count++) {\n task.schedule();\n }\n });\n\n ctx.onDispose(() => selection.unsubscribe());\n\n const query = space.db.query({ ...trigger.subscription.props, '@type': trigger.subscription.type });\n const unsubscribe = query.subscribe(({ objects }) => {\n selection.update(objects);\n });\n\n // Trigger first update, but don't schedule task.\n // selection.update(query.objects);\n\n ctx.onDispose(unsubscribe);\n\n log.info('mounted', { space: space.key, trigger });\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 assert(endpoint, 'Missing endpoint');\n assert(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", "message", "getPortPromise", "startPort", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "_registrationId", "stop", "trigger", "Trigger", "close", "unregister", "wake", "wait", "assert", "DeferredTask", "Context", "createSubscription", "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", "count", "objectIds", "Set", "task", "updatedObjects", "Array", "from", "clear", "invokeFunction", "objects", "selection", "added", "updated", "object", "add", "id", "info", "size", "length", "schedule", "onDispose", "unsubscribe", "query", "db", "subscription", "props", "type", "update", "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":1332,"imports":[]},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1332,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":13165,"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":16187,"imports":[{"path":"@dxos/node-std/assert","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/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":489,"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":463,"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":14207},"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/node-std/assert","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/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":3059},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytesInOutput":4128}},"bytes":7783}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -82,6 +82,15 @@ var DevServer = class {
|
|
|
82
82
|
app.use(import_express.default.json());
|
|
83
83
|
app.post("/:functionName", async (req, res) => {
|
|
84
84
|
const functionName = req.params.functionName;
|
|
85
|
+
(0, import_log.log)("invoke", {
|
|
86
|
+
function: functionName,
|
|
87
|
+
data: req.body
|
|
88
|
+
}, {
|
|
89
|
+
file: "dev-server.ts",
|
|
90
|
+
line: 74,
|
|
91
|
+
scope: this,
|
|
92
|
+
callSite: (f, a) => f(...a)
|
|
93
|
+
});
|
|
85
94
|
const builder = {
|
|
86
95
|
status: (code) => {
|
|
87
96
|
res.statusCode = code;
|
|
@@ -139,8 +148,8 @@ var DevServer = class {
|
|
|
139
148
|
var import_node_assert = __toESM(require("node:assert"));
|
|
140
149
|
var import_async2 = require("@dxos/async");
|
|
141
150
|
var import_context = require("@dxos/context");
|
|
151
|
+
var import_echo_schema = require("@dxos/echo-schema");
|
|
142
152
|
var import_log2 = require("@dxos/log");
|
|
143
|
-
var import_observable_object = require("@dxos/observable-object");
|
|
144
153
|
var import_util = require("@dxos/util");
|
|
145
154
|
var TriggerManager = class {
|
|
146
155
|
constructor(_client, _triggers, _invokeOptions) {
|
|
@@ -178,23 +187,38 @@ var TriggerManager = class {
|
|
|
178
187
|
if (ctx.disposed) {
|
|
179
188
|
return;
|
|
180
189
|
}
|
|
181
|
-
|
|
190
|
+
let count = 0;
|
|
191
|
+
const objectIds = /* @__PURE__ */ new Set();
|
|
182
192
|
const task = new import_async2.DeferredTask(ctx, async () => {
|
|
183
|
-
const updatedObjects = Array.from(
|
|
184
|
-
|
|
193
|
+
const updatedObjects = Array.from(objectIds);
|
|
194
|
+
objectIds.clear();
|
|
185
195
|
await this.invokeFunction(this._invokeOptions, trigger.function, {
|
|
186
196
|
space: space.key,
|
|
187
197
|
objects: updatedObjects
|
|
188
198
|
});
|
|
189
199
|
});
|
|
190
|
-
const selection = (0,
|
|
200
|
+
const selection = (0, import_echo_schema.createSubscription)(({ added, updated }) => {
|
|
191
201
|
for (const object of added) {
|
|
192
|
-
|
|
202
|
+
objectIds.add(object.id);
|
|
193
203
|
}
|
|
194
204
|
for (const object1 of updated) {
|
|
195
|
-
|
|
205
|
+
objectIds.add(object1.id);
|
|
206
|
+
}
|
|
207
|
+
import_log2.log.info("updated", {
|
|
208
|
+
space: space.key,
|
|
209
|
+
objects: objectIds.size,
|
|
210
|
+
added: added.length,
|
|
211
|
+
updated: updated.length,
|
|
212
|
+
count
|
|
213
|
+
}, {
|
|
214
|
+
file: "trigger-manager.ts",
|
|
215
|
+
line: 86,
|
|
216
|
+
scope: this,
|
|
217
|
+
callSite: (f, a) => f(...a)
|
|
218
|
+
});
|
|
219
|
+
if (count++) {
|
|
220
|
+
task.schedule();
|
|
196
221
|
}
|
|
197
|
-
task.schedule();
|
|
198
222
|
});
|
|
199
223
|
ctx.onDispose(() => selection.unsubscribe());
|
|
200
224
|
const query = space.db.query({
|
|
@@ -204,13 +228,13 @@ var TriggerManager = class {
|
|
|
204
228
|
const unsubscribe = query.subscribe(({ objects }) => {
|
|
205
229
|
selection.update(objects);
|
|
206
230
|
});
|
|
207
|
-
selection.update(query.objects);
|
|
208
231
|
ctx.onDispose(unsubscribe);
|
|
209
|
-
|
|
232
|
+
import_log2.log.info("mounted", {
|
|
233
|
+
space: space.key,
|
|
210
234
|
trigger
|
|
211
235
|
}, {
|
|
212
236
|
file: "trigger-manager.ts",
|
|
213
|
-
line:
|
|
237
|
+
line: 110,
|
|
214
238
|
scope: this,
|
|
215
239
|
callSite: (f, a) => f(...a)
|
|
216
240
|
});
|
|
@@ -237,7 +261,7 @@ var TriggerManager = class {
|
|
|
237
261
|
function: functionName
|
|
238
262
|
}, {
|
|
239
263
|
file: "trigger-manager.ts",
|
|
240
|
-
line:
|
|
264
|
+
line: 129,
|
|
241
265
|
scope: this,
|
|
242
266
|
callSite: (f, a) => f(...a)
|
|
243
267
|
});
|
|
@@ -254,17 +278,17 @@ var TriggerManager = class {
|
|
|
254
278
|
result: await res.json()
|
|
255
279
|
}, {
|
|
256
280
|
file: "trigger-manager.ts",
|
|
257
|
-
line:
|
|
281
|
+
line: 139,
|
|
258
282
|
scope: this,
|
|
259
283
|
callSite: (f, a) => f(...a)
|
|
260
284
|
});
|
|
261
285
|
} catch (err) {
|
|
262
|
-
|
|
286
|
+
import_log2.log.error("error", {
|
|
263
287
|
function: functionName,
|
|
264
288
|
error: err.message
|
|
265
289
|
}, {
|
|
266
290
|
file: "trigger-manager.ts",
|
|
267
|
-
line:
|
|
291
|
+
line: 141,
|
|
268
292
|
scope: this,
|
|
269
293
|
callSite: (f, a) => f(...a)
|
|
270
294
|
});
|
|
@@ -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 http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { FunctionContext, FunctionHandler, FunctionsManifest, 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 _functionHandlers: Record<string, FunctionHandler> = {};\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\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 await this._functionHandlers[functionName](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 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 }\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 assert from 'node:assert';\n\nimport { DeferredTask } from '@dxos/async';\nimport { Client, PublicKey
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;ACIA,qBAAoB;AAEpB,uBAAqB;AACrB,wBAA+B;AAE/B,mBAAwB;AAExB,iBAAoB;AAIpB,IAAMA,eAAe;AAUd,IAAMC,YAAN,MAAMA;;EAQXC,YACmBC,SACAC,UACjB;mBAFiBD;oBACAC;SATFC,oBAAqD,CAAC;EAUpE;EAEH,IAAIC,OAAO;AACT,WAAO,KAAKC;EACd;EAEA,IAAIC,WAAW;AACb,WAAO,KAAKD,QAAQ,oBAAoB,KAAKA,UAAUE;EACzD;EAEA,IAAIC,YAAY;AACd,WAAOC,OAAOC,KAAK,KAAKP,iBAAiB;EAC3C;EAEA,MAAMQ,aAAa;AACjB,eAAW,CAACC,MAAMC,CAAAA,KAAMJ,OAAOK,QAAQ,KAAKZ,SAASa,SAASP,SAAS,GAAG;AACxE,UAAI;AAEF,cAAMQ,UAASC,YAAQC,uBAAK,KAAKhB,SAASiB,WAAWP,IAAAA,CAAAA;AACrD,cAAMQ,UAAUJ,QAAOK;AACvB,YAAI,OAAOD,YAAY,YAAY;AACjC,gBAAM,IAAIE,MAAM,yCAAyCV,MAAM;QACjE;AAEA,aAAKT,kBAAkBS,IAAAA,IAAQQ;MACjC,SAASG,KAAP;AACAC,uBAAIC,MAAM,mDAAmDF,KAAAA;;;;;;MAC/D;IACF;EACF;EAEA,MAAMG,QAAQ;AACZ,UAAMC,UAAMC,eAAAA,SAAAA;AACZD,QAAIE,IAAID,eAAAA,QAAQE,KAAI,CAAA;AAEpBH,QAAII,KAAK,kBAAkB,OAAOC,KAAKC,QAAQ;AAC7C,YAAMC,eAAeF,IAAIG,OAAOD;
|
|
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", "builder", "status", "code", "statusCode", "succeed", "result", "end", "JSON", "stringify", "context", "client", "bind", "
|
|
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 http from 'http';\nimport { join } from 'node:path';\nimport { getPortPromise } from 'portfinder';\n\nimport { Trigger } from '@dxos/async';\nimport { Client } from '@dxos/client';\nimport { log } from '@dxos/log';\n\nimport { FunctionContext, FunctionHandler, FunctionsManifest, 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 _functionHandlers: Record<string, FunctionHandler> = {};\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 await this._functionHandlers[functionName](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 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 }\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 assert from 'node:assert';\n\nimport { DeferredTask } from '@dxos/async';\nimport { Client, PublicKey } from '@dxos/client';\nimport type { Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { createSubscription } from '@dxos/echo-schema';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { 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(), trigger, space);\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, trigger: FunctionTrigger, space: Space) {\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 if (ctx.disposed) {\n return;\n }\n\n // TODO(burdon): Factor out subscription/result delta.\n\n let count = 0;\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n const updatedObjects = Array.from(objectIds);\n objectIds.clear();\n\n await this.invokeFunction(this._invokeOptions, trigger.function, {\n space: space.key,\n objects: updatedObjects,\n });\n });\n\n // TODO(burdon): Removed?\n const selection = 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.info('updated', {\n space: space.key,\n objects: objectIds.size,\n added: added.length,\n updated: updated.length,\n count,\n });\n if (count++) {\n task.schedule();\n }\n });\n\n ctx.onDispose(() => selection.unsubscribe());\n\n const query = space.db.query({ ...trigger.subscription.props, '@type': trigger.subscription.type });\n const unsubscribe = query.subscribe(({ objects }) => {\n selection.update(objects);\n });\n\n // Trigger first update, but don't schedule task.\n // selection.update(query.objects);\n\n ctx.onDispose(unsubscribe);\n\n log.info('mounted', { space: space.key, trigger });\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 assert(endpoint, 'Missing endpoint');\n assert(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", "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", "disposed", "count", "objectIds", "Set", "task", "DeferredTask", "updatedObjects", "Array", "from", "clear", "invokeFunction", "objects", "selection", "createSubscription", "added", "updated", "object", "add", "id", "log", "info", "size", "length", "schedule", "onDispose", "unsubscribe", "query", "db", "subscription", "props", "type", "update", "delete", "dispose", "options", "functionName", "data", "endpoint", "runtime", "assert", "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":1332,"imports":[]},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/functions/src/function.ts":{"bytes":1332,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":13165,"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":16187,"imports":[{"path":"node:assert","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/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":489,"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":463,"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":14292},"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":"node:assert","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/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":3211},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/trigger-manager.ts":{"bytesInOutput":4326}},"bytes":9406}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/dev-server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,OAAO,EAAoC,iBAAiB,EAAY,MAAM,aAAa,CAAC;AAI5F,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,iBAAiB,CAAuC;IAEzE,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;
|
|
1
|
+
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/dev-server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,OAAO,EAAoC,iBAAiB,EAAY,MAAM,aAAa,CAAC;AAI5F,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,iBAAiB,CAAuC;IAEzE,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;IA8CL,IAAI;CAiBX"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Client } from '@dxos/client';
|
|
2
|
-
import { Context } from '@dxos/context';
|
|
3
2
|
import { FunctionTrigger } from '../function';
|
|
4
3
|
export type InvokeOptions = {
|
|
5
4
|
endpoint: string;
|
|
@@ -17,10 +16,4 @@ export declare class TriggerManager {
|
|
|
17
16
|
private unmount;
|
|
18
17
|
private invokeFunction;
|
|
19
18
|
}
|
|
20
|
-
export type MountTriggerParams = {
|
|
21
|
-
ctx: Context;
|
|
22
|
-
client: Client;
|
|
23
|
-
trigger: FunctionTrigger;
|
|
24
|
-
invokeOptions: InvokeOptions;
|
|
25
|
-
};
|
|
26
19
|
//# sourceMappingURL=trigger-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trigger-manager.d.ts","sourceRoot":"","sources":["../../../../src/runtime/trigger-manager.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"trigger-manager.d.ts","sourceRoot":"","sources":["../../../../src/runtime/trigger-manager.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAa,MAAM,cAAc,CAAC;AAOjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,cAAc;IAOvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IARjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGiC;gBAGtC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,eAAe,EAAE,EAC5B,cAAc,EAAE,aAAa;IAG1C,KAAK;IAaL,IAAI;YAMI,KAAK;YA4DL,OAAO;YASP,cAAc;CAqB7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/functions",
|
|
3
|
-
"version": "0.1.53-main.
|
|
3
|
+
"version": "0.1.53-main.8f662cd",
|
|
4
4
|
"description": "Functions SDK and runtime.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"express": "4.17.1",
|
|
23
23
|
"portfinder": "^1.0.32",
|
|
24
|
-
"@dxos/async": "0.1.53-main.
|
|
25
|
-
"@dxos/client": "0.1.53-main.
|
|
26
|
-
"@dxos/context": "0.1.53-main.
|
|
27
|
-
"@dxos/
|
|
28
|
-
"@dxos/
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/util": "0.1.53-main.
|
|
24
|
+
"@dxos/async": "0.1.53-main.8f662cd",
|
|
25
|
+
"@dxos/client": "0.1.53-main.8f662cd",
|
|
26
|
+
"@dxos/context": "0.1.53-main.8f662cd",
|
|
27
|
+
"@dxos/echo-schema": "0.1.53-main.8f662cd",
|
|
28
|
+
"@dxos/log": "0.1.53-main.8f662cd",
|
|
29
|
+
"@dxos/node-std": "0.1.53-main.8f662cd",
|
|
30
|
+
"@dxos/util": "0.1.53-main.8f662cd"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/express": "^4.17.17"
|
|
@@ -71,6 +71,7 @@ export class DevServer {
|
|
|
71
71
|
|
|
72
72
|
app.post('/:functionName', async (req, res) => {
|
|
73
73
|
const functionName = req.params.functionName;
|
|
74
|
+
log('invoke', { function: functionName, data: req.body });
|
|
74
75
|
|
|
75
76
|
const builder: Response = {
|
|
76
77
|
status: (code: number) => {
|
|
@@ -101,6 +102,8 @@ export class DevServer {
|
|
|
101
102
|
this._port = await getPortPromise({ startPort: DEFAULT_PORT });
|
|
102
103
|
this._server = app.listen(this._port);
|
|
103
104
|
|
|
105
|
+
// TODO(burdon): Check plugin is registered.
|
|
106
|
+
// TypeError: Cannot read properties of undefined (reading 'register')
|
|
104
107
|
const { registrationId } = await this._client.services.services.FunctionRegistryService!.register({
|
|
105
108
|
endpoint: this.endpoint!,
|
|
106
109
|
functions: this.functions.map((name) => ({ name })),
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
|
|
7
7
|
import { DeferredTask } from '@dxos/async';
|
|
8
|
-
import { Client, PublicKey
|
|
8
|
+
import { Client, PublicKey } from '@dxos/client';
|
|
9
|
+
import type { Space } from '@dxos/client/echo';
|
|
9
10
|
import { Context } from '@dxos/context';
|
|
11
|
+
import { createSubscription } from '@dxos/echo-schema';
|
|
10
12
|
import { log } from '@dxos/log';
|
|
11
|
-
import { createSubscription } from '@dxos/observable-object';
|
|
12
13
|
import { ComplexMap } from '@dxos/util';
|
|
13
14
|
|
|
14
15
|
import { FunctionTrigger } from '../function';
|
|
@@ -59,10 +60,13 @@ export class TriggerManager {
|
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
// TODO(burdon): Factor out subscription/result delta.
|
|
64
|
+
|
|
65
|
+
let count = 0;
|
|
66
|
+
const objectIds = new Set<string>();
|
|
63
67
|
const task = new DeferredTask(ctx, async () => {
|
|
64
|
-
const updatedObjects = Array.from(
|
|
65
|
-
|
|
68
|
+
const updatedObjects = Array.from(objectIds);
|
|
69
|
+
objectIds.clear();
|
|
66
70
|
|
|
67
71
|
await this.invokeFunction(this._invokeOptions, trigger.function, {
|
|
68
72
|
space: space.key,
|
|
@@ -70,15 +74,25 @@ export class TriggerManager {
|
|
|
70
74
|
});
|
|
71
75
|
});
|
|
72
76
|
|
|
77
|
+
// TODO(burdon): Removed?
|
|
73
78
|
const selection = createSubscription(({ added, updated }) => {
|
|
74
79
|
for (const object of added) {
|
|
75
|
-
|
|
80
|
+
objectIds.add(object.id);
|
|
76
81
|
}
|
|
77
82
|
for (const object of updated) {
|
|
78
|
-
|
|
83
|
+
objectIds.add(object.id);
|
|
79
84
|
}
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
log.info('updated', {
|
|
87
|
+
space: space.key,
|
|
88
|
+
objects: objectIds.size,
|
|
89
|
+
added: added.length,
|
|
90
|
+
updated: updated.length,
|
|
91
|
+
count,
|
|
92
|
+
});
|
|
93
|
+
if (count++) {
|
|
94
|
+
task.schedule();
|
|
95
|
+
}
|
|
82
96
|
});
|
|
83
97
|
|
|
84
98
|
ctx.onDispose(() => selection.unsubscribe());
|
|
@@ -88,12 +102,12 @@ export class TriggerManager {
|
|
|
88
102
|
selection.update(objects);
|
|
89
103
|
});
|
|
90
104
|
|
|
91
|
-
//
|
|
92
|
-
selection.update(query.objects);
|
|
105
|
+
// Trigger first update, but don't schedule task.
|
|
106
|
+
// selection.update(query.objects);
|
|
93
107
|
|
|
94
108
|
ctx.onDispose(unsubscribe);
|
|
95
109
|
|
|
96
|
-
log('mounted', { trigger });
|
|
110
|
+
log.info('mounted', { space: space.key, trigger });
|
|
97
111
|
}
|
|
98
112
|
}
|
|
99
113
|
|
|
@@ -124,14 +138,7 @@ export class TriggerManager {
|
|
|
124
138
|
|
|
125
139
|
log('result', { function: functionName, result: await res.json() });
|
|
126
140
|
} catch (err: any) {
|
|
127
|
-
log('error', { function: functionName, error: err.message });
|
|
141
|
+
log.error('error', { function: functionName, error: err.message });
|
|
128
142
|
}
|
|
129
143
|
}
|
|
130
144
|
}
|
|
131
|
-
|
|
132
|
-
export type MountTriggerParams = {
|
|
133
|
-
ctx: Context;
|
|
134
|
-
client: Client;
|
|
135
|
-
trigger: FunctionTrigger;
|
|
136
|
-
invokeOptions: InvokeOptions;
|
|
137
|
-
};
|