@dxos/functions 0.5.3-main.3b535c7 → 0.5.3-main.3c6700b
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 +281 -126
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +280 -125
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/handler.d.ts +33 -12
- package/dist/types/src/handler.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.d.ts +11 -5
- package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.test.d.ts +2 -0
- package/dist/types/src/runtime/dev-server.test.d.ts.map +1 -0
- package/dist/types/src/runtime/scheduler.d.ts +38 -4
- package/dist/types/src/runtime/scheduler.d.ts.map +1 -1
- package/dist/types/src/testing/test/handler.d.ts +3 -0
- package/dist/types/src/testing/test/handler.d.ts.map +1 -0
- package/dist/types/src/testing/test/index.d.ts +3 -0
- package/dist/types/src/testing/test/index.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +52 -30
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +15 -13
- package/schema/functions.json +18 -5
- package/src/handler.ts +54 -31
- package/src/runtime/dev-server.test.ts +80 -0
- package/src/runtime/dev-server.ts +73 -39
- package/src/runtime/scheduler.test.ts +13 -9
- package/src/runtime/scheduler.ts +95 -47
- package/src/testing/test/handler.ts +9 -0
- package/src/testing/test/index.ts +7 -0
- package/src/types.ts +18 -7
|
@@ -20,16 +20,16 @@ import { log } from "@dxos/log";
|
|
|
20
20
|
import { nonNullable } from "@dxos/util";
|
|
21
21
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/handler.ts";
|
|
22
22
|
var subscriptionHandler = (handler) => {
|
|
23
|
-
return ({ event, context, ...rest }) => {
|
|
23
|
+
return ({ event: { data }, context, ...rest }) => {
|
|
24
24
|
const { client } = context;
|
|
25
|
-
const space =
|
|
26
|
-
const objects = space
|
|
27
|
-
if (!!
|
|
25
|
+
const space = data.spaceKey ? client.spaces.get(PublicKey.from(data.spaceKey)) : void 0;
|
|
26
|
+
const objects = space ? data.objects?.map((id) => space.db.getObjectById(id)).filter(nonNullable) : [];
|
|
27
|
+
if (!!data.spaceKey && !space) {
|
|
28
28
|
log.warn("invalid space", {
|
|
29
|
-
|
|
29
|
+
data
|
|
30
30
|
}, {
|
|
31
31
|
F: __dxlog_file,
|
|
32
|
-
L:
|
|
32
|
+
L: 91,
|
|
33
33
|
S: void 0,
|
|
34
34
|
C: (f, a) => f(...a)
|
|
35
35
|
});
|
|
@@ -39,15 +39,18 @@ var subscriptionHandler = (handler) => {
|
|
|
39
39
|
objects: objects?.length
|
|
40
40
|
}, {
|
|
41
41
|
F: __dxlog_file,
|
|
42
|
-
L:
|
|
42
|
+
L: 93,
|
|
43
43
|
S: void 0,
|
|
44
44
|
C: (f, a) => f(...a)
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
return handler({
|
|
48
48
|
event: {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
data: {
|
|
50
|
+
...data,
|
|
51
|
+
space,
|
|
52
|
+
objects
|
|
53
|
+
}
|
|
51
54
|
},
|
|
52
55
|
context,
|
|
53
56
|
...rest
|
|
@@ -59,7 +62,7 @@ var subscriptionHandler = (handler) => {
|
|
|
59
62
|
import express from "express";
|
|
60
63
|
import { getPort } from "get-port-please";
|
|
61
64
|
import { join } from "@dxos/node-std/path";
|
|
62
|
-
import { Trigger } from "@dxos/async";
|
|
65
|
+
import { Event, Trigger } from "@dxos/async";
|
|
63
66
|
import { invariant } from "@dxos/invariant";
|
|
64
67
|
import { log as log2 } from "@dxos/log";
|
|
65
68
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
|
|
@@ -70,11 +73,17 @@ var DevServer = class {
|
|
|
70
73
|
this._options = _options;
|
|
71
74
|
this._handlers = {};
|
|
72
75
|
this._seq = 0;
|
|
76
|
+
this.update = new Event();
|
|
77
|
+
}
|
|
78
|
+
get stats() {
|
|
79
|
+
return {
|
|
80
|
+
seq: this._seq
|
|
81
|
+
};
|
|
73
82
|
}
|
|
74
83
|
get endpoint() {
|
|
75
84
|
invariant(this._port, void 0, {
|
|
76
85
|
F: __dxlog_file2,
|
|
77
|
-
L:
|
|
86
|
+
L: 54,
|
|
78
87
|
S: this,
|
|
79
88
|
A: [
|
|
80
89
|
"this._port",
|
|
@@ -96,7 +105,7 @@ var DevServer = class {
|
|
|
96
105
|
} catch (err) {
|
|
97
106
|
log2.error("parsing function (check manifest)", err, {
|
|
98
107
|
F: __dxlog_file2,
|
|
99
|
-
L:
|
|
108
|
+
L: 71,
|
|
100
109
|
S: this,
|
|
101
110
|
C: (f, a) => f(...a)
|
|
102
111
|
});
|
|
@@ -104,29 +113,44 @@ var DevServer = class {
|
|
|
104
113
|
}
|
|
105
114
|
}
|
|
106
115
|
async start() {
|
|
116
|
+
invariant(!this._server, void 0, {
|
|
117
|
+
F: __dxlog_file2,
|
|
118
|
+
L: 77,
|
|
119
|
+
S: this,
|
|
120
|
+
A: [
|
|
121
|
+
"!this._server",
|
|
122
|
+
""
|
|
123
|
+
]
|
|
124
|
+
});
|
|
125
|
+
log2.info("starting...", void 0, {
|
|
126
|
+
F: __dxlog_file2,
|
|
127
|
+
L: 78,
|
|
128
|
+
S: this,
|
|
129
|
+
C: (f, a) => f(...a)
|
|
130
|
+
});
|
|
107
131
|
const app = express();
|
|
108
132
|
app.use(express.json());
|
|
109
|
-
app.post("/:
|
|
110
|
-
const {
|
|
133
|
+
app.post("/:path", async (req, res) => {
|
|
134
|
+
const { path: path2 } = req.params;
|
|
111
135
|
try {
|
|
112
136
|
log2.info("calling", {
|
|
113
|
-
|
|
137
|
+
path: path2
|
|
114
138
|
}, {
|
|
115
139
|
F: __dxlog_file2,
|
|
116
|
-
L:
|
|
140
|
+
L: 87,
|
|
117
141
|
S: this,
|
|
118
142
|
C: (f, a) => f(...a)
|
|
119
143
|
});
|
|
120
144
|
if (this._options.reload) {
|
|
121
|
-
const { def } = this._handlers[
|
|
145
|
+
const { def } = this._handlers["/" + path2];
|
|
122
146
|
await this._load(def, true);
|
|
123
147
|
}
|
|
124
|
-
res.statusCode = await this.
|
|
148
|
+
res.statusCode = await this.invoke("/" + path2, req.body);
|
|
125
149
|
res.end();
|
|
126
150
|
} catch (err) {
|
|
127
151
|
log2.catch(err, void 0, {
|
|
128
152
|
F: __dxlog_file2,
|
|
129
|
-
L:
|
|
153
|
+
L: 97,
|
|
130
154
|
S: this,
|
|
131
155
|
C: (f, a) => f(...a)
|
|
132
156
|
});
|
|
@@ -146,92 +170,170 @@ var DevServer = class {
|
|
|
146
170
|
try {
|
|
147
171
|
const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService.register({
|
|
148
172
|
endpoint: this.endpoint,
|
|
149
|
-
functions: this.functions.map(({ def: {
|
|
150
|
-
|
|
173
|
+
functions: this.functions.map(({ def: { id, path: path2 } }) => ({
|
|
174
|
+
id,
|
|
175
|
+
path: path2
|
|
151
176
|
}))
|
|
152
177
|
});
|
|
153
178
|
log2.info("registered", {
|
|
154
|
-
registrationId,
|
|
155
179
|
endpoint
|
|
156
180
|
}, {
|
|
157
181
|
F: __dxlog_file2,
|
|
158
|
-
L:
|
|
182
|
+
L: 113,
|
|
159
183
|
S: this,
|
|
160
184
|
C: (f, a) => f(...a)
|
|
161
185
|
});
|
|
162
|
-
this._registrationId = registrationId;
|
|
163
186
|
this._proxy = endpoint;
|
|
187
|
+
this._functionServiceRegistration = registrationId;
|
|
164
188
|
} catch (err) {
|
|
165
189
|
await this.stop();
|
|
166
190
|
throw new Error("FunctionRegistryService not available (check plugin is configured).");
|
|
167
191
|
}
|
|
192
|
+
log2.info("started", {
|
|
193
|
+
port: this._port
|
|
194
|
+
}, {
|
|
195
|
+
F: __dxlog_file2,
|
|
196
|
+
L: 121,
|
|
197
|
+
S: this,
|
|
198
|
+
C: (f, a) => f(...a)
|
|
199
|
+
});
|
|
168
200
|
}
|
|
169
201
|
async stop() {
|
|
202
|
+
invariant(this._server, void 0, {
|
|
203
|
+
F: __dxlog_file2,
|
|
204
|
+
L: 125,
|
|
205
|
+
S: this,
|
|
206
|
+
A: [
|
|
207
|
+
"this._server",
|
|
208
|
+
""
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
log2.info("stopping...", void 0, {
|
|
212
|
+
F: __dxlog_file2,
|
|
213
|
+
L: 126,
|
|
214
|
+
S: this,
|
|
215
|
+
C: (f, a) => f(...a)
|
|
216
|
+
});
|
|
170
217
|
const trigger = new Trigger();
|
|
171
|
-
this._server
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
218
|
+
this._server.close(async () => {
|
|
219
|
+
log2.info("server stopped", void 0, {
|
|
220
|
+
F: __dxlog_file2,
|
|
221
|
+
L: 130,
|
|
222
|
+
S: this,
|
|
223
|
+
C: (f, a) => f(...a)
|
|
224
|
+
});
|
|
225
|
+
try {
|
|
226
|
+
if (this._functionServiceRegistration) {
|
|
227
|
+
invariant(this._client.services.services.FunctionRegistryService, void 0, {
|
|
228
|
+
F: __dxlog_file2,
|
|
229
|
+
L: 133,
|
|
230
|
+
S: this,
|
|
231
|
+
A: [
|
|
232
|
+
"this._client.services.services.FunctionRegistryService",
|
|
233
|
+
""
|
|
234
|
+
]
|
|
235
|
+
});
|
|
236
|
+
await this._client.services.services.FunctionRegistryService.unregister({
|
|
237
|
+
registrationId: this._functionServiceRegistration
|
|
238
|
+
});
|
|
239
|
+
log2.info("unregistered", {
|
|
240
|
+
registrationId: this._functionServiceRegistration
|
|
241
|
+
}, {
|
|
242
|
+
F: __dxlog_file2,
|
|
243
|
+
L: 138,
|
|
244
|
+
S: this,
|
|
245
|
+
C: (f, a) => f(...a)
|
|
246
|
+
});
|
|
247
|
+
this._functionServiceRegistration = void 0;
|
|
248
|
+
this._proxy = void 0;
|
|
249
|
+
}
|
|
250
|
+
trigger.wake();
|
|
251
|
+
} catch (err) {
|
|
252
|
+
trigger.throw(err);
|
|
186
253
|
}
|
|
187
|
-
trigger.wake();
|
|
188
254
|
});
|
|
189
255
|
await trigger.wait();
|
|
190
256
|
this._port = void 0;
|
|
191
257
|
this._server = void 0;
|
|
258
|
+
log2.info("stopped", void 0, {
|
|
259
|
+
F: __dxlog_file2,
|
|
260
|
+
L: 152,
|
|
261
|
+
S: this,
|
|
262
|
+
C: (f, a) => f(...a)
|
|
263
|
+
});
|
|
192
264
|
}
|
|
193
265
|
/**
|
|
194
266
|
* Load function.
|
|
195
267
|
*/
|
|
196
|
-
async _load(def,
|
|
197
|
-
const { id,
|
|
198
|
-
const
|
|
268
|
+
async _load(def, force = false) {
|
|
269
|
+
const { id, path: path2, handler } = def;
|
|
270
|
+
const filePath = join(this._options.baseDir, handler);
|
|
199
271
|
log2.info("loading", {
|
|
200
|
-
id
|
|
272
|
+
id,
|
|
273
|
+
force
|
|
201
274
|
}, {
|
|
202
275
|
F: __dxlog_file2,
|
|
203
|
-
L:
|
|
276
|
+
L: 161,
|
|
204
277
|
S: this,
|
|
205
278
|
C: (f, a) => f(...a)
|
|
206
279
|
});
|
|
207
|
-
if (
|
|
208
|
-
Object.keys(__require.cache).filter((key) => key.startsWith(
|
|
280
|
+
if (force) {
|
|
281
|
+
Object.keys(__require.cache).filter((key) => key.startsWith(filePath)).forEach((key) => {
|
|
282
|
+
delete __require.cache[key];
|
|
283
|
+
});
|
|
209
284
|
}
|
|
210
|
-
const module = __require(
|
|
285
|
+
const module = __require(filePath);
|
|
211
286
|
if (typeof module.default !== "function") {
|
|
212
287
|
throw new Error(`Handler must export default function: ${id}`);
|
|
213
288
|
}
|
|
214
|
-
this._handlers[
|
|
289
|
+
this._handlers[path2] = {
|
|
215
290
|
def,
|
|
216
291
|
handler: module.default
|
|
217
292
|
};
|
|
218
293
|
}
|
|
219
294
|
/**
|
|
220
|
-
* Invoke function
|
|
295
|
+
* Invoke function.
|
|
221
296
|
*/
|
|
222
|
-
async
|
|
297
|
+
async invoke(path2, data) {
|
|
223
298
|
const seq = ++this._seq;
|
|
224
299
|
const now = Date.now();
|
|
225
300
|
log2.info("req", {
|
|
226
301
|
seq,
|
|
227
|
-
|
|
302
|
+
path: path2
|
|
228
303
|
}, {
|
|
229
304
|
F: __dxlog_file2,
|
|
230
|
-
L:
|
|
305
|
+
L: 188,
|
|
306
|
+
S: this,
|
|
307
|
+
C: (f, a) => f(...a)
|
|
308
|
+
});
|
|
309
|
+
const statusCode = await this._invoke(path2, {
|
|
310
|
+
data
|
|
311
|
+
});
|
|
312
|
+
log2.info("res", {
|
|
313
|
+
seq,
|
|
314
|
+
path: path2,
|
|
315
|
+
statusCode,
|
|
316
|
+
duration: Date.now() - now
|
|
317
|
+
}, {
|
|
318
|
+
F: __dxlog_file2,
|
|
319
|
+
L: 191,
|
|
231
320
|
S: this,
|
|
232
321
|
C: (f, a) => f(...a)
|
|
233
322
|
});
|
|
234
|
-
|
|
323
|
+
this.update.emit(statusCode);
|
|
324
|
+
return statusCode;
|
|
325
|
+
}
|
|
326
|
+
async _invoke(path2, event) {
|
|
327
|
+
const { handler } = this._handlers[path2] ?? {};
|
|
328
|
+
invariant(handler, `invalid path: ${path2}`, {
|
|
329
|
+
F: __dxlog_file2,
|
|
330
|
+
L: 198,
|
|
331
|
+
S: this,
|
|
332
|
+
A: [
|
|
333
|
+
"handler",
|
|
334
|
+
"`invalid path: ${path}`"
|
|
335
|
+
]
|
|
336
|
+
});
|
|
235
337
|
const context = {
|
|
236
338
|
client: this._client,
|
|
237
339
|
dataDir: this._options.dataDir
|
|
@@ -248,24 +350,15 @@ var DevServer = class {
|
|
|
248
350
|
event,
|
|
249
351
|
response
|
|
250
352
|
});
|
|
251
|
-
log2.info("res", {
|
|
252
|
-
seq,
|
|
253
|
-
name,
|
|
254
|
-
statusCode,
|
|
255
|
-
duration: Date.now() - now
|
|
256
|
-
}, {
|
|
257
|
-
F: __dxlog_file2,
|
|
258
|
-
L: 178,
|
|
259
|
-
S: this,
|
|
260
|
-
C: (f, a) => f(...a)
|
|
261
|
-
});
|
|
262
353
|
return statusCode;
|
|
263
354
|
}
|
|
264
355
|
};
|
|
265
356
|
|
|
266
357
|
// packages/core/functions/src/runtime/scheduler.ts
|
|
267
358
|
import { CronJob } from "cron";
|
|
359
|
+
import { getPort as getPort2 } from "get-port-please";
|
|
268
360
|
import http from "@dxos/node-std/http";
|
|
361
|
+
import path from "@dxos/node-std/path";
|
|
269
362
|
import WebSocket from "ws";
|
|
270
363
|
import { TextV0Type } from "@braneframe/types";
|
|
271
364
|
import { debounce, DeferredTask, sleep, Trigger as Trigger2 } from "@dxos/async";
|
|
@@ -280,7 +373,13 @@ var Scheduler = class {
|
|
|
280
373
|
this._client = _client;
|
|
281
374
|
this._manifest = _manifest;
|
|
282
375
|
this._options = _options;
|
|
283
|
-
this._mounts = new ComplexMap(({
|
|
376
|
+
this._mounts = new ComplexMap(({ spaceKey, id }) => `${spaceKey.toHex()}:${id}`);
|
|
377
|
+
}
|
|
378
|
+
get mounts() {
|
|
379
|
+
return Array.from(this._mounts.values()).reduce((acc, { trigger }) => {
|
|
380
|
+
acc.push(trigger);
|
|
381
|
+
return acc;
|
|
382
|
+
}, []);
|
|
284
383
|
}
|
|
285
384
|
async start() {
|
|
286
385
|
this._client.spaces.subscribe(async (spaces) => {
|
|
@@ -297,15 +396,18 @@ var Scheduler = class {
|
|
|
297
396
|
await this.unmount(id, spaceKey);
|
|
298
397
|
}
|
|
299
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Mount trigger.
|
|
401
|
+
*/
|
|
300
402
|
async mount(ctx, space, trigger) {
|
|
301
403
|
const key = {
|
|
302
|
-
|
|
303
|
-
|
|
404
|
+
spaceKey: space.key,
|
|
405
|
+
id: trigger.function
|
|
304
406
|
};
|
|
305
407
|
const def = this._manifest.functions.find((config) => config.id === trigger.function);
|
|
306
408
|
invariant2(def, `Function not found: ${trigger.function}`, {
|
|
307
409
|
F: __dxlog_file3,
|
|
308
|
-
L:
|
|
410
|
+
L: 76,
|
|
309
411
|
S: this,
|
|
310
412
|
A: [
|
|
311
413
|
"def",
|
|
@@ -323,7 +425,7 @@ var Scheduler = class {
|
|
|
323
425
|
trigger
|
|
324
426
|
}, {
|
|
325
427
|
F: __dxlog_file3,
|
|
326
|
-
L:
|
|
428
|
+
L: 82,
|
|
327
429
|
S: this,
|
|
328
430
|
C: (f, a) => f(...a)
|
|
329
431
|
});
|
|
@@ -331,16 +433,16 @@ var Scheduler = class {
|
|
|
331
433
|
return;
|
|
332
434
|
}
|
|
333
435
|
if (trigger.timer) {
|
|
334
|
-
await this._createTimer(ctx, space, def, trigger
|
|
436
|
+
await this._createTimer(ctx, space, def, trigger);
|
|
335
437
|
}
|
|
336
438
|
if (trigger.webhook) {
|
|
337
|
-
await this._createWebhook(ctx, space, def, trigger
|
|
439
|
+
await this._createWebhook(ctx, space, def, trigger);
|
|
338
440
|
}
|
|
339
441
|
if (trigger.websocket) {
|
|
340
|
-
await this._createWebsocket(ctx, space, def, trigger
|
|
442
|
+
await this._createWebsocket(ctx, space, def, trigger);
|
|
341
443
|
}
|
|
342
444
|
if (trigger.subscription) {
|
|
343
|
-
await this._createSubscription(ctx, space, def, trigger
|
|
445
|
+
await this._createSubscription(ctx, space, def, trigger);
|
|
344
446
|
}
|
|
345
447
|
}
|
|
346
448
|
}
|
|
@@ -355,34 +457,52 @@ var Scheduler = class {
|
|
|
355
457
|
await ctx.dispose();
|
|
356
458
|
}
|
|
357
459
|
}
|
|
358
|
-
|
|
359
|
-
|
|
460
|
+
async _execFunction(def, trigger, data) {
|
|
461
|
+
let status = 0;
|
|
360
462
|
try {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
},
|
|
364
|
-
F: __dxlog_file3,
|
|
365
|
-
L: 117,
|
|
366
|
-
S: this,
|
|
367
|
-
C: (f, a) => f(...a)
|
|
368
|
-
});
|
|
463
|
+
const payload = Object.assign({}, {
|
|
464
|
+
meta: trigger.meta
|
|
465
|
+
}, data);
|
|
369
466
|
const { endpoint, callback } = this._options;
|
|
370
467
|
if (endpoint) {
|
|
371
|
-
|
|
468
|
+
const url = path.join(endpoint, def.path);
|
|
469
|
+
log3.info("exec", {
|
|
470
|
+
function: def.id,
|
|
471
|
+
url
|
|
472
|
+
}, {
|
|
473
|
+
F: __dxlog_file3,
|
|
474
|
+
L: 128,
|
|
475
|
+
S: this,
|
|
476
|
+
C: (f, a) => f(...a)
|
|
477
|
+
});
|
|
478
|
+
const response = await fetch(url, {
|
|
372
479
|
method: "POST",
|
|
373
480
|
headers: {
|
|
374
481
|
"Content-Type": "application/json"
|
|
375
482
|
},
|
|
376
|
-
body: JSON.stringify(
|
|
483
|
+
body: JSON.stringify(payload)
|
|
377
484
|
});
|
|
485
|
+
status = response.status;
|
|
378
486
|
} else if (callback) {
|
|
379
|
-
|
|
487
|
+
log3.info("exec", {
|
|
488
|
+
function: def.id
|
|
489
|
+
}, {
|
|
490
|
+
F: __dxlog_file3,
|
|
491
|
+
L: 139,
|
|
492
|
+
S: this,
|
|
493
|
+
C: (f, a) => f(...a)
|
|
494
|
+
});
|
|
495
|
+
status = await callback(payload) ?? 200;
|
|
496
|
+
}
|
|
497
|
+
if (status && status >= 400) {
|
|
498
|
+
throw new Error(`Response: ${status}`);
|
|
380
499
|
}
|
|
381
500
|
log3.info("done", {
|
|
382
|
-
function: def.id
|
|
501
|
+
function: def.id,
|
|
502
|
+
status
|
|
383
503
|
}, {
|
|
384
504
|
F: __dxlog_file3,
|
|
385
|
-
L:
|
|
505
|
+
L: 149,
|
|
386
506
|
S: this,
|
|
387
507
|
C: (f, a) => f(...a)
|
|
388
508
|
});
|
|
@@ -392,11 +512,13 @@ var Scheduler = class {
|
|
|
392
512
|
error: err.message
|
|
393
513
|
}, {
|
|
394
514
|
F: __dxlog_file3,
|
|
395
|
-
L:
|
|
515
|
+
L: 151,
|
|
396
516
|
S: this,
|
|
397
517
|
C: (f, a) => f(...a)
|
|
398
518
|
});
|
|
519
|
+
status = 500;
|
|
399
520
|
}
|
|
521
|
+
return status;
|
|
400
522
|
}
|
|
401
523
|
//
|
|
402
524
|
// Triggers
|
|
@@ -410,20 +532,20 @@ var Scheduler = class {
|
|
|
410
532
|
trigger
|
|
411
533
|
}, {
|
|
412
534
|
F: __dxlog_file3,
|
|
413
|
-
L:
|
|
535
|
+
L: 166,
|
|
414
536
|
S: this,
|
|
415
537
|
C: (f, a) => f(...a)
|
|
416
538
|
});
|
|
417
|
-
const
|
|
539
|
+
const spec = trigger.timer;
|
|
418
540
|
const task = new DeferredTask(ctx, async () => {
|
|
419
|
-
await this._execFunction(def, {
|
|
420
|
-
|
|
541
|
+
await this._execFunction(def, trigger, {
|
|
542
|
+
spaceKey: space.key
|
|
421
543
|
});
|
|
422
544
|
});
|
|
423
545
|
let last = 0;
|
|
424
546
|
let run = 0;
|
|
425
547
|
const job = CronJob.from({
|
|
426
|
-
cronTime: cron,
|
|
548
|
+
cronTime: spec.cron,
|
|
427
549
|
runOnInit: false,
|
|
428
550
|
onTick: () => {
|
|
429
551
|
const now = Date.now();
|
|
@@ -436,7 +558,7 @@ var Scheduler = class {
|
|
|
436
558
|
delta
|
|
437
559
|
}, {
|
|
438
560
|
F: __dxlog_file3,
|
|
439
|
-
L:
|
|
561
|
+
L: 186,
|
|
440
562
|
S: this,
|
|
441
563
|
C: (f, a) => f(...a)
|
|
442
564
|
});
|
|
@@ -455,25 +577,34 @@ var Scheduler = class {
|
|
|
455
577
|
trigger
|
|
456
578
|
}, {
|
|
457
579
|
F: __dxlog_file3,
|
|
458
|
-
L:
|
|
580
|
+
L: 199,
|
|
459
581
|
S: this,
|
|
460
582
|
C: (f, a) => f(...a)
|
|
461
583
|
});
|
|
462
|
-
const
|
|
584
|
+
const spec = trigger.webhook;
|
|
463
585
|
const server = http.createServer(async (req, res) => {
|
|
464
|
-
|
|
465
|
-
|
|
586
|
+
if (req.method !== spec.method) {
|
|
587
|
+
res.statusCode = 405;
|
|
588
|
+
return res.end();
|
|
589
|
+
}
|
|
590
|
+
res.statusCode = await this._execFunction(def, trigger, {
|
|
591
|
+
spaceKey: space.key
|
|
466
592
|
});
|
|
593
|
+
res.end();
|
|
594
|
+
});
|
|
595
|
+
const port = await getPort2({
|
|
596
|
+
random: true
|
|
467
597
|
});
|
|
468
598
|
server.listen(port, () => {
|
|
469
599
|
log3.info("started webhook", {
|
|
470
600
|
port
|
|
471
601
|
}, {
|
|
472
602
|
F: __dxlog_file3,
|
|
473
|
-
L:
|
|
603
|
+
L: 223,
|
|
474
604
|
S: this,
|
|
475
605
|
C: (f, a) => f(...a)
|
|
476
606
|
});
|
|
607
|
+
spec.port = port;
|
|
477
608
|
});
|
|
478
609
|
ctx.onDispose(() => {
|
|
479
610
|
server.close();
|
|
@@ -481,6 +612,7 @@ var Scheduler = class {
|
|
|
481
612
|
}
|
|
482
613
|
/**
|
|
483
614
|
* Websocket.
|
|
615
|
+
* NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.
|
|
484
616
|
*/
|
|
485
617
|
async _createWebsocket(ctx, space, def, trigger, options = {
|
|
486
618
|
retryDelay: 2,
|
|
@@ -491,11 +623,12 @@ var Scheduler = class {
|
|
|
491
623
|
trigger
|
|
492
624
|
}, {
|
|
493
625
|
F: __dxlog_file3,
|
|
494
|
-
L:
|
|
626
|
+
L: 249,
|
|
495
627
|
S: this,
|
|
496
628
|
C: (f, a) => f(...a)
|
|
497
629
|
});
|
|
498
|
-
const
|
|
630
|
+
const spec = trigger.websocket;
|
|
631
|
+
const { url, init } = spec;
|
|
499
632
|
let ws;
|
|
500
633
|
for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
|
|
501
634
|
const open = new Trigger2();
|
|
@@ -506,24 +639,38 @@ var Scheduler = class {
|
|
|
506
639
|
url
|
|
507
640
|
}, {
|
|
508
641
|
F: __dxlog_file3,
|
|
509
|
-
L:
|
|
642
|
+
L: 260,
|
|
510
643
|
S: this,
|
|
511
644
|
C: (f, a) => f(...a)
|
|
512
645
|
});
|
|
513
|
-
if (
|
|
514
|
-
ws.send(new TextEncoder().encode(JSON.stringify(
|
|
646
|
+
if (spec.init) {
|
|
647
|
+
ws.send(new TextEncoder().encode(JSON.stringify(init)));
|
|
515
648
|
}
|
|
516
649
|
open.wake(true);
|
|
517
650
|
},
|
|
518
|
-
onclose: () => {
|
|
651
|
+
onclose: (event) => {
|
|
519
652
|
log3.info("closed", {
|
|
520
|
-
url
|
|
653
|
+
url,
|
|
654
|
+
code: event.code
|
|
521
655
|
}, {
|
|
522
656
|
F: __dxlog_file3,
|
|
523
|
-
L:
|
|
657
|
+
L: 269,
|
|
524
658
|
S: this,
|
|
525
659
|
C: (f, a) => f(...a)
|
|
526
660
|
});
|
|
661
|
+
if (event.code === 1006) {
|
|
662
|
+
setTimeout(async () => {
|
|
663
|
+
log3.info(`reconnecting in ${options.retryDelay}s...`, {
|
|
664
|
+
url
|
|
665
|
+
}, {
|
|
666
|
+
F: __dxlog_file3,
|
|
667
|
+
L: 274,
|
|
668
|
+
S: this,
|
|
669
|
+
C: (f, a) => f(...a)
|
|
670
|
+
});
|
|
671
|
+
await this._createWebsocket(ctx, space, def, trigger, options);
|
|
672
|
+
}, options.retryDelay * 1e3);
|
|
673
|
+
}
|
|
527
674
|
open.wake(false);
|
|
528
675
|
},
|
|
529
676
|
onerror: (event) => {
|
|
@@ -531,7 +678,7 @@ var Scheduler = class {
|
|
|
531
678
|
url
|
|
532
679
|
}, {
|
|
533
680
|
F: __dxlog_file3,
|
|
534
|
-
L:
|
|
681
|
+
L: 283,
|
|
535
682
|
S: this,
|
|
536
683
|
C: (f, a) => f(...a)
|
|
537
684
|
});
|
|
@@ -539,8 +686,8 @@ var Scheduler = class {
|
|
|
539
686
|
onmessage: async (event) => {
|
|
540
687
|
try {
|
|
541
688
|
const data = JSON.parse(new TextDecoder().decode(event.data));
|
|
542
|
-
await this._execFunction(def, {
|
|
543
|
-
|
|
689
|
+
await this._execFunction(def, trigger, {
|
|
690
|
+
spaceKey: space.key,
|
|
544
691
|
data
|
|
545
692
|
});
|
|
546
693
|
} catch (err) {
|
|
@@ -548,7 +695,7 @@ var Scheduler = class {
|
|
|
548
695
|
url
|
|
549
696
|
}, {
|
|
550
697
|
F: __dxlog_file3,
|
|
551
|
-
L:
|
|
698
|
+
L: 291,
|
|
552
699
|
S: this,
|
|
553
700
|
C: (f, a) => f(...a)
|
|
554
701
|
});
|
|
@@ -565,7 +712,7 @@ var Scheduler = class {
|
|
|
565
712
|
attempt
|
|
566
713
|
}, {
|
|
567
714
|
F: __dxlog_file3,
|
|
568
|
-
L:
|
|
715
|
+
L: 302,
|
|
569
716
|
S: this,
|
|
570
717
|
C: (f, a) => f(...a)
|
|
571
718
|
});
|
|
@@ -586,14 +733,15 @@ var Scheduler = class {
|
|
|
586
733
|
trigger
|
|
587
734
|
}, {
|
|
588
735
|
F: __dxlog_file3,
|
|
589
|
-
L:
|
|
736
|
+
L: 317,
|
|
590
737
|
S: this,
|
|
591
738
|
C: (f, a) => f(...a)
|
|
592
739
|
});
|
|
740
|
+
const spec = trigger.subscription;
|
|
593
741
|
const objectIds = /* @__PURE__ */ new Set();
|
|
594
742
|
const task = new DeferredTask(ctx, async () => {
|
|
595
|
-
await this._execFunction(def, {
|
|
596
|
-
|
|
743
|
+
await this._execFunction(def, trigger, {
|
|
744
|
+
spaceKey: space.key,
|
|
597
745
|
objects: Array.from(objectIds)
|
|
598
746
|
});
|
|
599
747
|
});
|
|
@@ -604,7 +752,7 @@ var Scheduler = class {
|
|
|
604
752
|
updated: updated.length
|
|
605
753
|
}, {
|
|
606
754
|
F: __dxlog_file3,
|
|
607
|
-
L:
|
|
755
|
+
L: 329,
|
|
608
756
|
S: this,
|
|
609
757
|
C: (f, a) => f(...a)
|
|
610
758
|
});
|
|
@@ -617,7 +765,7 @@ var Scheduler = class {
|
|
|
617
765
|
task.schedule();
|
|
618
766
|
});
|
|
619
767
|
subscriptions.push(() => subscription.unsubscribe());
|
|
620
|
-
const { filter, options: { deep, delay } = {} } =
|
|
768
|
+
const { filter, options: { deep, delay } = {} } = spec;
|
|
621
769
|
const update = ({ objects }) => {
|
|
622
770
|
subscription.update(objects);
|
|
623
771
|
if (deep) {
|
|
@@ -625,7 +773,7 @@ var Scheduler = class {
|
|
|
625
773
|
objects: objects.length
|
|
626
774
|
}, {
|
|
627
775
|
F: __dxlog_file3,
|
|
628
|
-
L:
|
|
776
|
+
L: 349,
|
|
629
777
|
S: this,
|
|
630
778
|
C: (f, a) => f(...a)
|
|
631
779
|
});
|
|
@@ -652,9 +800,11 @@ import * as S from "@effect/schema/Schema";
|
|
|
652
800
|
var TimerTriggerSchema = S.struct({
|
|
653
801
|
cron: S.string
|
|
654
802
|
});
|
|
655
|
-
var WebhookTriggerSchema = S.struct({
|
|
656
|
-
|
|
657
|
-
|
|
803
|
+
var WebhookTriggerSchema = S.mutable(S.struct({
|
|
804
|
+
method: S.string,
|
|
805
|
+
// Assigned port.
|
|
806
|
+
port: S.optional(S.number)
|
|
807
|
+
}));
|
|
658
808
|
var WebsocketTriggerSchema = S.struct({
|
|
659
809
|
url: S.string,
|
|
660
810
|
init: S.optional(S.record(S.string, S.any))
|
|
@@ -675,6 +825,9 @@ var SubscriptionTriggerSchema = S.struct({
|
|
|
675
825
|
});
|
|
676
826
|
var FunctionTriggerSchema = S.struct({
|
|
677
827
|
function: S.string.pipe(S.description("Function ID/URI.")),
|
|
828
|
+
// Context passed to function.
|
|
829
|
+
meta: S.optional(S.record(S.string, S.any)),
|
|
830
|
+
// Triggers.
|
|
678
831
|
timer: S.optional(TimerTriggerSchema),
|
|
679
832
|
webhook: S.optional(WebhookTriggerSchema),
|
|
680
833
|
websocket: S.optional(WebsocketTriggerSchema),
|
|
@@ -682,14 +835,16 @@ var FunctionTriggerSchema = S.struct({
|
|
|
682
835
|
});
|
|
683
836
|
var FunctionDefSchema = S.struct({
|
|
684
837
|
id: S.string,
|
|
838
|
+
// name: S.string,
|
|
685
839
|
description: S.optional(S.string),
|
|
686
|
-
|
|
687
|
-
|
|
840
|
+
// TODO(burdon): Rename route?
|
|
841
|
+
path: S.string,
|
|
842
|
+
// TODO(burdon): NPM/GitHub/Docker/CF URL?
|
|
688
843
|
handler: S.string
|
|
689
844
|
});
|
|
690
845
|
var FunctionManifestSchema = S.struct({
|
|
691
846
|
functions: S.mutable(S.array(FunctionDefSchema)),
|
|
692
|
-
triggers: S.mutable(S.array(FunctionTriggerSchema))
|
|
847
|
+
triggers: S.optional(S.mutable(S.array(FunctionTriggerSchema)))
|
|
693
848
|
});
|
|
694
849
|
export {
|
|
695
850
|
DevServer,
|