@dxos/functions 0.3.8-next.f4e0086 → 0.3.9-main.03b62b6
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 +2 -2
- package/dist/lib/browser/index.mjs +229 -165
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +242 -177
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/handler.d.ts +3 -6
- package/dist/types/src/handler.d.ts.map +1 -1
- package/dist/types/src/manifest.d.ts +5 -3
- package/dist/types/src/manifest.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.d.ts +15 -2
- package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
- package/dist/types/src/runtime/index.d.ts +1 -1
- package/dist/types/src/runtime/index.d.ts.map +1 -1
- package/dist/types/src/runtime/{trigger-manager.d.ts → scheduler.d.ts} +9 -7
- package/dist/types/src/runtime/scheduler.d.ts.map +1 -0
- package/package.json +13 -10
- package/src/handler.ts +8 -8
- package/src/manifest.ts +11 -5
- package/src/runtime/dev-server.ts +93 -58
- package/src/runtime/index.ts +1 -1
- package/src/runtime/scheduler.ts +162 -0
- package/dist/types/src/runtime/trigger-manager.d.ts.map +0 -1
- package/src/runtime/trigger-manager.ts +0 -140
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ runtime:
|
|
|
50
50
|
Start functions in dev mode (from the related package):
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
dx function dev
|
|
53
|
+
dx function dev -r ts-node/register --verbose
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
> NOTE: `-r ts-node/register` configures native TypesScript support.
|
|
@@ -61,7 +61,7 @@ Install `nodemon` to support live reloading:
|
|
|
61
61
|
npm i -g nodemon
|
|
62
62
|
|
|
63
63
|
nodemon -w ./src -e ts --exec $(git rev-parse --show-toplevel)/packages/devtools/cli/bin/dev \
|
|
64
|
-
function dev
|
|
64
|
+
function dev -r ts-node/register --verbose
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
## Invoking functions
|
|
@@ -9,53 +9,46 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
9
9
|
|
|
10
10
|
// packages/core/functions/src/runtime/dev-server.ts
|
|
11
11
|
import express from "express";
|
|
12
|
+
import { getPort } from "get-port-please";
|
|
12
13
|
import { join } from "@dxos/node-std/path";
|
|
13
|
-
import { getPortPromise } from "portfinder";
|
|
14
14
|
import { Trigger } from "@dxos/async";
|
|
15
|
+
import { invariant } from "@dxos/invariant";
|
|
15
16
|
import { log } from "@dxos/log";
|
|
16
17
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
|
|
17
|
-
var DEFAULT_PORT = 7001;
|
|
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
23
|
this._handlers = {};
|
|
24
|
-
|
|
25
|
-
get port() {
|
|
26
|
-
return this._port;
|
|
24
|
+
this._seq = 0;
|
|
27
25
|
}
|
|
28
26
|
get endpoint() {
|
|
29
|
-
|
|
27
|
+
invariant(this._port, void 0, {
|
|
28
|
+
F: __dxlog_file,
|
|
29
|
+
L: 46,
|
|
30
|
+
S: this,
|
|
31
|
+
A: [
|
|
32
|
+
"this._port",
|
|
33
|
+
""
|
|
34
|
+
]
|
|
35
|
+
});
|
|
36
|
+
return `http://localhost:${this._port}`;
|
|
37
|
+
}
|
|
38
|
+
get proxy() {
|
|
39
|
+
return this._proxy;
|
|
30
40
|
}
|
|
31
41
|
get functions() {
|
|
32
42
|
return Object.values(this._handlers);
|
|
33
43
|
}
|
|
34
44
|
async initialize() {
|
|
35
45
|
for (const def of this._options.manifest.functions) {
|
|
36
|
-
const { id, endpoint, handler: path } = def;
|
|
37
46
|
try {
|
|
38
|
-
|
|
39
|
-
const handler = module.default;
|
|
40
|
-
if (typeof handler !== "function") {
|
|
41
|
-
throw new Error(`Handler must export default function: ${id}`);
|
|
42
|
-
}
|
|
43
|
-
if (this._handlers[endpoint]) {
|
|
44
|
-
log.warn(`Function already registered: ${id}`, void 0, {
|
|
45
|
-
F: __dxlog_file,
|
|
46
|
-
L: 64,
|
|
47
|
-
S: this,
|
|
48
|
-
C: (f, a) => f(...a)
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
this._handlers[endpoint] = {
|
|
52
|
-
def,
|
|
53
|
-
handler
|
|
54
|
-
};
|
|
47
|
+
await this._load(def);
|
|
55
48
|
} catch (err) {
|
|
56
49
|
log.error("parsing function (check manifest)", err, {
|
|
57
50
|
F: __dxlog_file,
|
|
58
|
-
L:
|
|
51
|
+
L: 63,
|
|
59
52
|
S: this,
|
|
60
53
|
C: (f, a) => f(...a)
|
|
61
54
|
});
|
|
@@ -65,66 +58,56 @@ var DevServer = class {
|
|
|
65
58
|
async start() {
|
|
66
59
|
const app = express();
|
|
67
60
|
app.use(express.json());
|
|
68
|
-
app.post("/:
|
|
69
|
-
const {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
},
|
|
75
|
-
succeed: (result = {}) => {
|
|
76
|
-
res.end(JSON.stringify(result));
|
|
77
|
-
return response;
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
const context = {
|
|
81
|
-
client: this._client,
|
|
82
|
-
status: response.status.bind(response)
|
|
83
|
-
};
|
|
84
|
-
void (async () => {
|
|
85
|
-
try {
|
|
86
|
-
log("invoking", {
|
|
87
|
-
endpoint
|
|
88
|
-
}, {
|
|
89
|
-
F: __dxlog_file,
|
|
90
|
-
L: 100,
|
|
91
|
-
S: this,
|
|
92
|
-
C: (f, a) => f(...a)
|
|
93
|
-
});
|
|
94
|
-
const { handler } = this._handlers[endpoint];
|
|
95
|
-
const response2 = await handler({
|
|
96
|
-
context,
|
|
97
|
-
event: req.body
|
|
98
|
-
});
|
|
99
|
-
log("done", {
|
|
100
|
-
response: response2
|
|
101
|
-
}, {
|
|
102
|
-
F: __dxlog_file,
|
|
103
|
-
L: 103,
|
|
104
|
-
S: this,
|
|
105
|
-
C: (f, a) => f(...a)
|
|
106
|
-
});
|
|
107
|
-
} catch (err) {
|
|
108
|
-
res.statusCode = 500;
|
|
109
|
-
res.end(err.message);
|
|
61
|
+
app.post("/:name", async (req, res) => {
|
|
62
|
+
const { name } = req.params;
|
|
63
|
+
try {
|
|
64
|
+
if (this._options.reload) {
|
|
65
|
+
const { def } = this._handlers[name];
|
|
66
|
+
await this._load(def, true);
|
|
110
67
|
}
|
|
111
|
-
|
|
68
|
+
res.statusCode = await this._invoke(name, req.body);
|
|
69
|
+
res.end();
|
|
70
|
+
} catch (err) {
|
|
71
|
+
log.catch(err, void 0, {
|
|
72
|
+
F: __dxlog_file,
|
|
73
|
+
L: 83,
|
|
74
|
+
S: this,
|
|
75
|
+
C: (f, a) => f(...a)
|
|
76
|
+
});
|
|
77
|
+
res.statusCode = 500;
|
|
78
|
+
res.end();
|
|
79
|
+
}
|
|
112
80
|
});
|
|
113
|
-
this._port = await
|
|
114
|
-
|
|
81
|
+
this._port = await getPort({
|
|
82
|
+
host: "localhost",
|
|
83
|
+
port: 7200,
|
|
84
|
+
portRange: [
|
|
85
|
+
7200,
|
|
86
|
+
7299
|
|
87
|
+
]
|
|
115
88
|
});
|
|
116
89
|
this._server = app.listen(this._port);
|
|
117
90
|
try {
|
|
118
|
-
const { registrationId } = await this._client.services.services.FunctionRegistryService.register({
|
|
91
|
+
const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService.register({
|
|
119
92
|
endpoint: this.endpoint,
|
|
120
|
-
functions: this.functions.map(({ def: {
|
|
121
|
-
name
|
|
93
|
+
functions: this.functions.map(({ def: { name } }) => ({
|
|
94
|
+
name
|
|
122
95
|
}))
|
|
123
96
|
});
|
|
97
|
+
log.info("registered", {
|
|
98
|
+
registrationId,
|
|
99
|
+
endpoint
|
|
100
|
+
}, {
|
|
101
|
+
F: __dxlog_file,
|
|
102
|
+
L: 99,
|
|
103
|
+
S: this,
|
|
104
|
+
C: (f, a) => f(...a)
|
|
105
|
+
});
|
|
124
106
|
this._registrationId = registrationId;
|
|
107
|
+
this._proxy = endpoint;
|
|
125
108
|
} catch (err) {
|
|
126
109
|
await this.stop();
|
|
127
|
-
throw new Error("FunctionRegistryService not available
|
|
110
|
+
throw new Error("FunctionRegistryService not available (check plugin is configured).");
|
|
128
111
|
}
|
|
129
112
|
}
|
|
130
113
|
async stop() {
|
|
@@ -134,31 +117,112 @@ var DevServer = class {
|
|
|
134
117
|
await this._client.services.services.FunctionRegistryService.unregister({
|
|
135
118
|
registrationId: this._registrationId
|
|
136
119
|
});
|
|
120
|
+
log.info("unregistered", {
|
|
121
|
+
registrationId: this._registrationId
|
|
122
|
+
}, {
|
|
123
|
+
F: __dxlog_file,
|
|
124
|
+
L: 116,
|
|
125
|
+
S: this,
|
|
126
|
+
C: (f, a) => f(...a)
|
|
127
|
+
});
|
|
137
128
|
this._registrationId = void 0;
|
|
129
|
+
this._proxy = void 0;
|
|
138
130
|
}
|
|
139
131
|
trigger.wake();
|
|
140
132
|
});
|
|
141
133
|
await trigger.wait();
|
|
142
|
-
this._server = void 0;
|
|
143
134
|
this._port = void 0;
|
|
135
|
+
this._server = void 0;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Load function.
|
|
139
|
+
*/
|
|
140
|
+
async _load(def, flush = false) {
|
|
141
|
+
const { id, name, handler } = def;
|
|
142
|
+
const path = join(this._options.directory, handler);
|
|
143
|
+
log.info("loading", {
|
|
144
|
+
id
|
|
145
|
+
}, {
|
|
146
|
+
F: __dxlog_file,
|
|
147
|
+
L: 135,
|
|
148
|
+
S: this,
|
|
149
|
+
C: (f, a) => f(...a)
|
|
150
|
+
});
|
|
151
|
+
if (flush) {
|
|
152
|
+
Object.keys(__require.cache).filter((key) => key.startsWith(path)).forEach((key) => delete __require.cache[key]);
|
|
153
|
+
}
|
|
154
|
+
const module = __require(path);
|
|
155
|
+
if (typeof module.default !== "function") {
|
|
156
|
+
throw new Error(`Handler must export default function: ${id}`);
|
|
157
|
+
}
|
|
158
|
+
this._handlers[name] = {
|
|
159
|
+
def,
|
|
160
|
+
handler: module.default
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Invoke function handler.
|
|
165
|
+
*/
|
|
166
|
+
async _invoke(name, event) {
|
|
167
|
+
const seq = ++this._seq;
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
log.info("req", {
|
|
170
|
+
seq,
|
|
171
|
+
name
|
|
172
|
+
}, {
|
|
173
|
+
F: __dxlog_file,
|
|
174
|
+
L: 160,
|
|
175
|
+
S: this,
|
|
176
|
+
C: (f, a) => f(...a)
|
|
177
|
+
});
|
|
178
|
+
const { handler } = this._handlers[name];
|
|
179
|
+
const context = {
|
|
180
|
+
client: this._client,
|
|
181
|
+
dataDir: this._options.dataDir
|
|
182
|
+
};
|
|
183
|
+
let statusCode = 200;
|
|
184
|
+
const response = {
|
|
185
|
+
status: (code) => {
|
|
186
|
+
statusCode = code;
|
|
187
|
+
return response;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
await handler({
|
|
191
|
+
context,
|
|
192
|
+
event,
|
|
193
|
+
response
|
|
194
|
+
});
|
|
195
|
+
log.info("res", {
|
|
196
|
+
seq,
|
|
197
|
+
name,
|
|
198
|
+
statusCode,
|
|
199
|
+
duration: Date.now() - now
|
|
200
|
+
}, {
|
|
201
|
+
F: __dxlog_file,
|
|
202
|
+
L: 177,
|
|
203
|
+
S: this,
|
|
204
|
+
C: (f, a) => f(...a)
|
|
205
|
+
});
|
|
206
|
+
return statusCode;
|
|
144
207
|
}
|
|
145
208
|
};
|
|
146
209
|
|
|
147
|
-
// packages/core/functions/src/runtime/
|
|
148
|
-
import {
|
|
210
|
+
// packages/core/functions/src/runtime/scheduler.ts
|
|
211
|
+
import { CronJob } from "cron";
|
|
212
|
+
import { debounce, DeferredTask } from "@dxos/async";
|
|
213
|
+
import { TextObject } from "@dxos/client/echo";
|
|
149
214
|
import { Context } from "@dxos/context";
|
|
150
|
-
import { Filter, createSubscription } from "@dxos/echo-schema";
|
|
151
|
-
import { invariant } from "@dxos/invariant";
|
|
215
|
+
import { Filter, createSubscription, subscribe } from "@dxos/echo-schema";
|
|
216
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
152
217
|
import { log as log2 } from "@dxos/log";
|
|
153
218
|
import { ComplexMap } from "@dxos/util";
|
|
154
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/
|
|
155
|
-
var
|
|
156
|
-
constructor(_client, _manifest,
|
|
219
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/scheduler.ts";
|
|
220
|
+
var Scheduler = class {
|
|
221
|
+
constructor(_client, _manifest, _options) {
|
|
157
222
|
this._client = _client;
|
|
158
223
|
this._manifest = _manifest;
|
|
159
|
-
this.
|
|
160
|
-
this._mounts = new ComplexMap(({
|
|
161
|
-
this._queries = /* @__PURE__ */ new Set();
|
|
224
|
+
this._options = _options;
|
|
225
|
+
this._mounts = new ComplexMap(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);
|
|
162
226
|
}
|
|
163
227
|
async start() {
|
|
164
228
|
this._client.spaces.subscribe(async (spaces) => {
|
|
@@ -171,22 +235,22 @@ var TriggerManager = class {
|
|
|
171
235
|
});
|
|
172
236
|
}
|
|
173
237
|
async stop() {
|
|
174
|
-
for (const {
|
|
175
|
-
await this.unmount(
|
|
238
|
+
for (const { id, spaceKey } of this._mounts.keys()) {
|
|
239
|
+
await this.unmount(id, spaceKey);
|
|
176
240
|
}
|
|
177
241
|
}
|
|
178
242
|
async mount(ctx, space, trigger) {
|
|
179
243
|
const key = {
|
|
180
|
-
|
|
244
|
+
id: trigger.function,
|
|
181
245
|
spaceKey: space.key
|
|
182
246
|
};
|
|
183
|
-
const
|
|
184
|
-
|
|
247
|
+
const def = this._manifest.functions.find((config) => config.id === trigger.function);
|
|
248
|
+
invariant2(def, `Function not found: ${trigger.function}`, {
|
|
185
249
|
F: __dxlog_file2,
|
|
186
|
-
L:
|
|
250
|
+
L: 59,
|
|
187
251
|
S: this,
|
|
188
252
|
A: [
|
|
189
|
-
"
|
|
253
|
+
"def",
|
|
190
254
|
"`Function not found: ${trigger.function}`"
|
|
191
255
|
]
|
|
192
256
|
});
|
|
@@ -201,57 +265,77 @@ var TriggerManager = class {
|
|
|
201
265
|
trigger
|
|
202
266
|
}, {
|
|
203
267
|
F: __dxlog_file2,
|
|
204
|
-
L:
|
|
268
|
+
L: 64,
|
|
205
269
|
S: this,
|
|
206
270
|
C: (f, a) => f(...a)
|
|
207
271
|
});
|
|
208
272
|
if (ctx.disposed) {
|
|
209
273
|
return;
|
|
210
274
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
275
|
+
if (trigger.schedule) {
|
|
276
|
+
const task = new DeferredTask(ctx, async () => {
|
|
277
|
+
await this.execFunction(def, {
|
|
278
|
+
space: space.key
|
|
279
|
+
});
|
|
216
280
|
});
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
space: space.key,
|
|
229
|
-
objects: objectIds.size,
|
|
230
|
-
count
|
|
231
|
-
}, {
|
|
232
|
-
F: __dxlog_file2,
|
|
233
|
-
L: 85,
|
|
234
|
-
S: this,
|
|
235
|
-
C: (f, a) => f(...a)
|
|
281
|
+
const job = new CronJob(trigger.schedule, () => task.schedule());
|
|
282
|
+
job.start();
|
|
283
|
+
ctx.onDispose(() => job.stop());
|
|
284
|
+
}
|
|
285
|
+
if (trigger.subscription) {
|
|
286
|
+
const objectIds = /* @__PURE__ */ new Set();
|
|
287
|
+
const task = new DeferredTask(ctx, async () => {
|
|
288
|
+
await this.execFunction(def, {
|
|
289
|
+
space: space.key,
|
|
290
|
+
objects: Array.from(objectIds)
|
|
291
|
+
});
|
|
236
292
|
});
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
unsubscribe();
|
|
248
|
-
|
|
249
|
-
|
|
293
|
+
const subscriptions = [];
|
|
294
|
+
const subscription = createSubscription(({ added, updated }) => {
|
|
295
|
+
for (const object of added) {
|
|
296
|
+
objectIds.add(object.id);
|
|
297
|
+
}
|
|
298
|
+
for (const object of updated) {
|
|
299
|
+
objectIds.add(object.id);
|
|
300
|
+
}
|
|
301
|
+
task.schedule();
|
|
302
|
+
});
|
|
303
|
+
subscriptions.push(() => subscription.unsubscribe());
|
|
304
|
+
const { type, props, deep, delay } = trigger.subscription;
|
|
305
|
+
const update = ({ objects }) => {
|
|
306
|
+
subscription.update(objects);
|
|
307
|
+
if (deep) {
|
|
308
|
+
log2.info("update", {
|
|
309
|
+
type,
|
|
310
|
+
deep,
|
|
311
|
+
objects: objects.length
|
|
312
|
+
}, {
|
|
313
|
+
F: __dxlog_file2,
|
|
314
|
+
L: 114,
|
|
315
|
+
S: this,
|
|
316
|
+
C: (f, a) => f(...a)
|
|
317
|
+
});
|
|
318
|
+
for (const object of objects) {
|
|
319
|
+
const content = object.content;
|
|
320
|
+
if (content instanceof TextObject) {
|
|
321
|
+
subscriptions.push(content[subscribe](debounce(() => subscription.update([
|
|
322
|
+
object
|
|
323
|
+
]), 1e3)));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
const query = space.db.query(Filter.typename(type, props));
|
|
329
|
+
subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1e3) : update));
|
|
330
|
+
ctx.onDispose(() => {
|
|
331
|
+
subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
332
|
+
});
|
|
333
|
+
}
|
|
250
334
|
}
|
|
251
335
|
}
|
|
252
|
-
async unmount(
|
|
336
|
+
async unmount(id, spaceKey) {
|
|
253
337
|
const key = {
|
|
254
|
-
|
|
338
|
+
id,
|
|
255
339
|
spaceKey
|
|
256
340
|
};
|
|
257
341
|
const { ctx } = this._mounts.get(key) ?? {};
|
|
@@ -260,59 +344,39 @@ var TriggerManager = class {
|
|
|
260
344
|
await ctx.dispose();
|
|
261
345
|
}
|
|
262
346
|
}
|
|
263
|
-
async execFunction(
|
|
264
|
-
const { endpoint, runtime } = options;
|
|
265
|
-
invariant(endpoint, "Missing endpoint", {
|
|
266
|
-
F: __dxlog_file2,
|
|
267
|
-
L: 121,
|
|
268
|
-
S: this,
|
|
269
|
-
A: [
|
|
270
|
-
"endpoint",
|
|
271
|
-
"'Missing endpoint'"
|
|
272
|
-
]
|
|
273
|
-
});
|
|
274
|
-
invariant(runtime, "Missing runtime", {
|
|
275
|
-
F: __dxlog_file2,
|
|
276
|
-
L: 122,
|
|
277
|
-
S: this,
|
|
278
|
-
A: [
|
|
279
|
-
"runtime",
|
|
280
|
-
"'Missing runtime'"
|
|
281
|
-
]
|
|
282
|
-
});
|
|
347
|
+
async execFunction(def, data) {
|
|
283
348
|
try {
|
|
284
|
-
log2("
|
|
285
|
-
function:
|
|
349
|
+
log2("request", {
|
|
350
|
+
function: def.id
|
|
286
351
|
}, {
|
|
287
352
|
F: __dxlog_file2,
|
|
288
|
-
L:
|
|
353
|
+
L: 147,
|
|
289
354
|
S: this,
|
|
290
355
|
C: (f, a) => f(...a)
|
|
291
356
|
});
|
|
292
|
-
const
|
|
293
|
-
const res = await fetch(url, {
|
|
357
|
+
const response = await fetch(`${this._options.endpoint}/${def.name}`, {
|
|
294
358
|
method: "POST",
|
|
295
|
-
body: JSON.stringify(data),
|
|
296
359
|
headers: {
|
|
297
360
|
"Content-Type": "application/json"
|
|
298
|
-
}
|
|
361
|
+
},
|
|
362
|
+
body: JSON.stringify(data)
|
|
299
363
|
});
|
|
300
364
|
log2("result", {
|
|
301
|
-
function:
|
|
302
|
-
result:
|
|
365
|
+
function: def.id,
|
|
366
|
+
result: response.status
|
|
303
367
|
}, {
|
|
304
368
|
F: __dxlog_file2,
|
|
305
|
-
L:
|
|
369
|
+
L: 157,
|
|
306
370
|
S: this,
|
|
307
371
|
C: (f, a) => f(...a)
|
|
308
372
|
});
|
|
309
373
|
} catch (err) {
|
|
310
374
|
log2.error("error", {
|
|
311
|
-
function:
|
|
375
|
+
function: def.id,
|
|
312
376
|
error: err.message
|
|
313
377
|
}, {
|
|
314
378
|
F: __dxlog_file2,
|
|
315
|
-
L:
|
|
379
|
+
L: 159,
|
|
316
380
|
S: this,
|
|
317
381
|
C: (f, a) => f(...a)
|
|
318
382
|
});
|
|
@@ -321,6 +385,6 @@ var TriggerManager = class {
|
|
|
321
385
|
};
|
|
322
386
|
export {
|
|
323
387
|
DevServer,
|
|
324
|
-
|
|
388
|
+
Scheduler
|
|
325
389
|
};
|
|
326
390
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/runtime/dev-server.ts", "../../../src/runtime/
|
|
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 Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nconst DEFAULT_PORT = 7001;\n\nexport type DevServerOptions = {\n directory: string;\n manifest: FunctionManifest;\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, { def: FunctionDef; handler: 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.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n const { id, endpoint, handler: path } = def;\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(join(this._options.directory, path));\n const handler = module.default;\n if (typeof handler !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n if (this._handlers[endpoint]) {\n log.warn(`Function already registered: ${id}`);\n }\n\n this._handlers[endpoint] = { def, handler };\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:endpoint', async (req, res) => {\n const { endpoint } = req.params;\n\n const response: Response = {\n status: (code: number) => {\n res.statusCode = code;\n return response;\n },\n\n succeed: (result = {}) => {\n res.end(JSON.stringify(result));\n return response;\n },\n };\n\n const context: FunctionContext = {\n client: this._client,\n status: response.status.bind(response),\n };\n\n void (async () => {\n try {\n log('invoking', { endpoint });\n const { handler } = this._handlers[endpoint];\n const response = await handler({ context, event: req.body });\n log('done', { response });\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(({ def: { endpoint } }) => ({ name: endpoint })), // TODO(burdon): Change proto name => id.\n });\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 FunctionManifest, type FunctionTrigger } from '../manifest';\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 _manifest: FunctionManifest,\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._manifest.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 config = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(config, `Function not found: ${trigger.function}`);\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // 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.execFunction(this._invokeOptions, config.endpoint, {\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 execFunction(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": ";;;;;;;;;;AAIA,OAAOA,aAAa;
|
|
6
|
-
"names": ["express", "
|
|
3
|
+
"sources": ["../../../src/runtime/dev-server.ts", "../../../src/runtime/scheduler.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport express from 'express';\nimport { getPort } from 'get-port-please';\nimport type http from 'http';\nimport { join } from 'node:path';\n\nimport { Trigger } from '@dxos/async';\nimport { type Client } from '@dxos/client';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type FunctionContext, type FunctionHandler, type Response } from '../handler';\nimport { type FunctionDef, type FunctionManifest } from '../manifest';\n\nexport type DevServerOptions = {\n port?: number;\n directory: string;\n manifest: FunctionManifest;\n reload?: boolean;\n dataDir?: string;\n};\n\n/**\n * Functions dev server provides a local HTTP server for testing functions.\n */\nexport class DevServer {\n // Function handlers indexed by name (URL path).\n private readonly _handlers: Record<string, { def: FunctionDef; handler: FunctionHandler<any> }> = {};\n\n private _server?: http.Server;\n private _port?: number;\n private _registrationId?: string;\n private _proxy?: string;\n private _seq = 0;\n\n // prettier-ignore\n constructor(\n private readonly _client: Client,\n private readonly _options: DevServerOptions,\n ) {}\n\n get endpoint() {\n invariant(this._port);\n return `http://localhost:${this._port}`;\n }\n\n get proxy() {\n return this._proxy;\n }\n\n get functions() {\n return Object.values(this._handlers);\n }\n\n async initialize() {\n for (const def of this._options.manifest.functions) {\n try {\n await this._load(def);\n } catch (err) {\n log.error('parsing function (check manifest)', err);\n }\n }\n }\n\n async start() {\n const app = express();\n app.use(express.json());\n\n app.post('/:name', async (req, res) => {\n const { name } = req.params;\n try {\n if (this._options.reload) {\n const { def } = this._handlers[name];\n await this._load(def, true);\n }\n\n res.statusCode = await this._invoke(name, req.body);\n res.end();\n } catch (err: any) {\n log.catch(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ host: 'localhost', port: 7200, portRange: [7200, 7299] });\n this._server = app.listen(this._port);\n\n try {\n // Register functions.\n const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService!.register({\n endpoint: this.endpoint,\n functions: this.functions.map(({ def: { name } }) => ({ name })),\n });\n\n log.info('registered', { registrationId, endpoint });\n this._registrationId = registrationId;\n this._proxy = endpoint;\n } catch (err: any) {\n await this.stop();\n throw new Error('FunctionRegistryService not available (check plugin is configured).');\n }\n }\n\n async stop() {\n const trigger = new Trigger();\n this._server?.close(async () => {\n if (this._registrationId) {\n await this._client.services.services.FunctionRegistryService!.unregister({\n registrationId: this._registrationId,\n });\n\n log.info('unregistered', { registrationId: this._registrationId });\n this._registrationId = undefined;\n this._proxy = undefined;\n }\n\n trigger.wake();\n });\n\n await trigger.wait();\n this._port = undefined;\n this._server = undefined;\n }\n\n /**\n * Load function.\n */\n private async _load(def: FunctionDef, flush = false) {\n const { id, name, handler } = def;\n const path = join(this._options.directory, handler);\n log.info('loading', { id });\n\n // Remove from cache.\n if (flush) {\n Object.keys(require.cache)\n .filter((key) => key.startsWith(path))\n .forEach((key) => delete require.cache[key]);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const module = require(path);\n if (typeof module.default !== 'function') {\n throw new Error(`Handler must export default function: ${id}`);\n }\n\n this._handlers[name] = { def, handler: module.default };\n }\n\n /**\n * Invoke function handler.\n */\n private async _invoke(name: string, event: any) {\n const seq = ++this._seq;\n const now = Date.now();\n\n log.info('req', { seq, name });\n const { handler } = this._handlers[name];\n\n const context: FunctionContext = {\n client: this._client,\n dataDir: this._options.dataDir,\n };\n\n let statusCode = 200;\n const response: Response = {\n status: (code: number) => {\n statusCode = code;\n return response;\n },\n };\n\n await handler({ context, event, response });\n log.info('res', { seq, name, statusCode, duration: Date.now() - now });\n\n return statusCode;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CronJob } from 'cron';\n\nimport { debounce, DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space, TextObject } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription, type Query, subscribe } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type FunctionDef, type FunctionManifest, type FunctionTrigger } from '../manifest';\n\ntype SchedulerOptions = {\n endpoint: string;\n};\n\n/**\n * Functions scheduler.\n */\n// TODO(burdon): Create tests.\nexport class Scheduler {\n // Map of mounted functions.\n private readonly _mounts = new ComplexMap<\n { id: string; spaceKey: PublicKey },\n { ctx: Context; trigger: FunctionTrigger }\n >(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);\n\n constructor(\n private readonly _client: Client,\n private readonly _manifest: FunctionManifest,\n private readonly _options: SchedulerOptions,\n ) {}\n\n async start() {\n this._client.spaces.subscribe(async (spaces) => {\n for (const space of spaces) {\n await space.waitUntilReady();\n for (const trigger of this._manifest.triggers ?? []) {\n await this.mount(new Context(), space, trigger);\n }\n }\n });\n }\n\n async stop() {\n for (const { id, spaceKey } of this._mounts.keys()) {\n await this.unmount(id, spaceKey);\n }\n }\n\n private async mount(ctx: Context, space: Space, trigger: FunctionTrigger) {\n const key = { id: trigger.function, spaceKey: space.key };\n const def = this._manifest.functions.find((config) => config.id === trigger.function);\n invariant(def, `Function not found: ${trigger.function}`);\n\n const exists = this._mounts.get(key);\n if (!exists) {\n this._mounts.set(key, { ctx, trigger });\n log('mount', { space: space.key, trigger });\n if (ctx.disposed) {\n return;\n }\n\n // Cron schedule.\n if (trigger.schedule) {\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n });\n });\n\n // TODO(burdon): Check greater than 30s min (use cron-parser).\n const job = new CronJob(trigger.schedule, () => task.schedule());\n\n job.start();\n ctx.onDispose(() => job.stop());\n }\n\n // ECHO subscription.\n if (trigger.subscription) {\n const objectIds = new Set<string>();\n const task = new DeferredTask(ctx, async () => {\n await this.execFunction(def, {\n space: space.key,\n objects: Array.from(objectIds),\n });\n });\n\n // TODO(burdon): Standardize subscription handles.\n const subscriptions: (() => void)[] = [];\n const subscription = createSubscription(({ added, updated }) => {\n for (const object of added) {\n objectIds.add(object.id);\n }\n for (const object of updated) {\n objectIds.add(object.id);\n }\n\n task.schedule();\n });\n subscriptions.push(() => subscription.unsubscribe());\n\n const { type, props, deep, delay } = trigger.subscription;\n const update = ({ objects }: Query) => {\n subscription.update(objects);\n\n // TODO(burdon): Hack to monitor changes to Document's text object.\n if (deep) {\n log.info('update', { type, deep, objects: objects.length });\n for (const object of objects) {\n const content = object.content;\n if (content instanceof TextObject) {\n subscriptions.push(content[subscribe](debounce(() => subscription.update([object]), 1_000)));\n }\n }\n }\n };\n\n // TODO(burdon): [Bug]: all callbacks are fired on the first mutation.\n // TODO(burdon): [Bug]: not updated when document is deleted (either top or hierarchically).\n const query = space.db.query(Filter.typename(type, props));\n subscriptions.push(query.subscribe(delay ? debounce(update, delay * 1_000) : update));\n\n ctx.onDispose(() => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n });\n }\n }\n }\n\n private async unmount(id: string, spaceKey: PublicKey) {\n const key = { id, spaceKey };\n const { ctx } = this._mounts.get(key) ?? {};\n if (ctx) {\n this._mounts.delete(key);\n await ctx.dispose();\n }\n }\n\n private async execFunction(def: FunctionDef, data: any) {\n try {\n log('request', { function: def.id });\n const response = await fetch(`${this._options.endpoint}/${def.name}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n // const result = await response.json();\n log('result', { function: def.id, result: response.status });\n } catch (err: any) {\n log.error('error', { function: def.id, error: err.message });\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["express", "getPort", "join", "Trigger", "invariant", "log", "DevServer", "constructor", "_client", "_options", "_handlers", "_seq", "endpoint", "invariant", "_port", "proxy", "_proxy", "functions", "Object", "values", "initialize", "def", "manifest", "_load", "err", "log", "error", "start", "app", "express", "use", "json", "post", "req", "res", "name", "params", "reload", "statusCode", "_invoke", "body", "end", "catch", "getPort", "host", "port", "portRange", "_server", "listen", "registrationId", "services", "FunctionRegistryService", "register", "map", "info", "_registrationId", "stop", "Error", "trigger", "Trigger", "close", "unregister", "undefined", "wake", "wait", "flush", "id", "handler", "path", "join", "directory", "keys", "require", "cache", "filter", "key", "startsWith", "forEach", "module", "default", "event", "seq", "now", "Date", "context", "client", "dataDir", "response", "status", "code", "duration", "CronJob", "debounce", "DeferredTask", "TextObject", "Context", "Filter", "createSubscription", "subscribe", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "id", "spaceKey", "toHex", "start", "spaces", "space", "waitUntilReady", "trigger", "triggers", "mount", "stop", "keys", "unmount", "ctx", "key", "function", "def", "functions", "find", "config", "exists", "get", "set", "disposed", "schedule", "task", "execFunction", "job", "onDispose", "subscription", "objectIds", "Set", "objects", "Array", "from", "subscriptions", "added", "updated", "object", "add", "push", "unsubscribe", "type", "props", "deep", "delay", "update", "info", "length", "content", "query", "db", "typename", "forEach", "delete", "dispose", "data", "response", "fetch", "endpoint", "name", "method", "headers", "body", "JSON", "stringify", "result", "status", "err", "error", "message"]
|
|
7
7
|
}
|