@dxos/functions 0.3.7 → 0.3.8-main.0ab6c73
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 +213 -144
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +228 -158
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/handler.d.ts +17 -0
- package/dist/types/src/handler.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +2 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/manifest.d.ts +25 -0
- package/dist/types/src/manifest.d.ts.map +1 -0
- package/dist/types/src/runtime/dev-server.d.ts +21 -5
- 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/scheduler.d.ts +22 -0
- package/dist/types/src/runtime/scheduler.d.ts.map +1 -0
- package/package.json +11 -10
- package/src/handler.ts +28 -0
- package/src/index.ts +2 -1
- package/src/manifest.ts +40 -0
- package/src/runtime/dev-server.ts +99 -57
- package/src/runtime/index.ts +1 -1
- package/src/runtime/scheduler.ts +145 -0
- package/dist/types/src/function.d.ts +0 -36
- package/dist/types/src/function.d.ts.map +0 -1
- package/dist/types/src/runtime/trigger-manager.d.ts +0 -20
- package/dist/types/src/runtime/trigger-manager.d.ts.map +0 -1
- package/src/function.ts +0 -51
- package/src/runtime/trigger-manager.ts +0 -139
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,41 +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
|
-
var __dxlog_file = "/home/
|
|
17
|
-
var DEFAULT_PORT = 7e3;
|
|
17
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
|
|
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: 45,
|
|
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
|
-
return Object.
|
|
42
|
+
return Object.values(this._handlers);
|
|
33
43
|
}
|
|
34
44
|
async initialize() {
|
|
35
|
-
for (const
|
|
45
|
+
for (const def of this._options.manifest.functions) {
|
|
36
46
|
try {
|
|
37
|
-
|
|
38
|
-
const handler = module.default;
|
|
39
|
-
if (typeof handler !== "function") {
|
|
40
|
-
throw new Error(`Handler must export default function: ${id}`);
|
|
41
|
-
}
|
|
42
|
-
this._handlers[id] = handler;
|
|
47
|
+
await this._load(def);
|
|
43
48
|
} catch (err) {
|
|
44
|
-
log.error("parsing function (check
|
|
49
|
+
log.error("parsing function (check manifest)", err, {
|
|
45
50
|
F: __dxlog_file,
|
|
46
|
-
L:
|
|
51
|
+
L: 62,
|
|
47
52
|
S: this,
|
|
48
53
|
C: (f, a) => f(...a)
|
|
49
54
|
});
|
|
@@ -53,58 +58,55 @@ var DevServer = class {
|
|
|
53
58
|
async start() {
|
|
54
59
|
const app = express();
|
|
55
60
|
app.use(express.json());
|
|
56
|
-
app.post("/:
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
F: __dxlog_file,
|
|
63
|
-
L: 74,
|
|
64
|
-
S: this,
|
|
65
|
-
C: (f, a) => f(...a)
|
|
66
|
-
});
|
|
67
|
-
const builder = {
|
|
68
|
-
status: (code) => {
|
|
69
|
-
res.statusCode = code;
|
|
70
|
-
return builder;
|
|
71
|
-
},
|
|
72
|
-
succeed: (result = {}) => {
|
|
73
|
-
res.end(JSON.stringify(result));
|
|
74
|
-
return builder;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
const context = {
|
|
78
|
-
client: this._client,
|
|
79
|
-
status: builder.status.bind(builder)
|
|
80
|
-
};
|
|
81
|
-
void (async () => {
|
|
82
|
-
try {
|
|
83
|
-
await this._handlers[functionName]({
|
|
84
|
-
event: req.body,
|
|
85
|
-
context
|
|
86
|
-
});
|
|
87
|
-
} catch (err) {
|
|
88
|
-
res.statusCode = 500;
|
|
89
|
-
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);
|
|
90
67
|
}
|
|
91
|
-
|
|
68
|
+
res.statusCode = await this._invoke(name, req.body);
|
|
69
|
+
res.end();
|
|
70
|
+
} catch (err) {
|
|
71
|
+
log.error(err, void 0, {
|
|
72
|
+
F: __dxlog_file,
|
|
73
|
+
L: 82,
|
|
74
|
+
S: this,
|
|
75
|
+
C: (f, a) => f(...a)
|
|
76
|
+
});
|
|
77
|
+
res.statusCode = 500;
|
|
78
|
+
res.end();
|
|
79
|
+
}
|
|
92
80
|
});
|
|
93
|
-
this._port = await
|
|
94
|
-
|
|
81
|
+
this._port = await getPort({
|
|
82
|
+
port: 7200,
|
|
83
|
+
portRange: [
|
|
84
|
+
7200,
|
|
85
|
+
7299
|
|
86
|
+
]
|
|
95
87
|
});
|
|
96
88
|
this._server = app.listen(this._port);
|
|
97
89
|
try {
|
|
98
|
-
const { registrationId } = await this._client.services.services.FunctionRegistryService.register({
|
|
90
|
+
const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService.register({
|
|
99
91
|
endpoint: this.endpoint,
|
|
100
|
-
functions: this.functions.map((name) => ({
|
|
92
|
+
functions: this.functions.map(({ def: { name } }) => ({
|
|
101
93
|
name
|
|
102
94
|
}))
|
|
103
95
|
});
|
|
96
|
+
log.info("registered", {
|
|
97
|
+
registrationId,
|
|
98
|
+
endpoint
|
|
99
|
+
}, {
|
|
100
|
+
F: __dxlog_file,
|
|
101
|
+
L: 98,
|
|
102
|
+
S: this,
|
|
103
|
+
C: (f, a) => f(...a)
|
|
104
|
+
});
|
|
104
105
|
this._registrationId = registrationId;
|
|
106
|
+
this._proxy = endpoint;
|
|
105
107
|
} catch (err) {
|
|
106
108
|
await this.stop();
|
|
107
|
-
throw new Error("FunctionRegistryService not available
|
|
109
|
+
throw new Error("FunctionRegistryService not available (check plugin is configured).");
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
async stop() {
|
|
@@ -114,52 +116,141 @@ var DevServer = class {
|
|
|
114
116
|
await this._client.services.services.FunctionRegistryService.unregister({
|
|
115
117
|
registrationId: this._registrationId
|
|
116
118
|
});
|
|
119
|
+
log.info("unregistered", {
|
|
120
|
+
registrationId: this._registrationId
|
|
121
|
+
}, {
|
|
122
|
+
F: __dxlog_file,
|
|
123
|
+
L: 115,
|
|
124
|
+
S: this,
|
|
125
|
+
C: (f, a) => f(...a)
|
|
126
|
+
});
|
|
117
127
|
this._registrationId = void 0;
|
|
128
|
+
this._proxy = void 0;
|
|
118
129
|
}
|
|
119
130
|
trigger.wake();
|
|
120
131
|
});
|
|
121
132
|
await trigger.wait();
|
|
122
|
-
this._server = void 0;
|
|
123
133
|
this._port = void 0;
|
|
134
|
+
this._server = void 0;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Load function.
|
|
138
|
+
*/
|
|
139
|
+
async _load(def, flush = false) {
|
|
140
|
+
const { id, name, handler } = def;
|
|
141
|
+
const path = join(this._options.directory, handler);
|
|
142
|
+
log.info("loading", {
|
|
143
|
+
id
|
|
144
|
+
}, {
|
|
145
|
+
F: __dxlog_file,
|
|
146
|
+
L: 134,
|
|
147
|
+
S: this,
|
|
148
|
+
C: (f, a) => f(...a)
|
|
149
|
+
});
|
|
150
|
+
if (flush) {
|
|
151
|
+
Object.keys(__require.cache).filter((key) => key.startsWith(path)).forEach((key) => delete __require.cache[key]);
|
|
152
|
+
}
|
|
153
|
+
const module = __require(path);
|
|
154
|
+
if (typeof module.default !== "function") {
|
|
155
|
+
throw new Error(`Handler must export default function: ${id}`);
|
|
156
|
+
}
|
|
157
|
+
this._handlers[name] = {
|
|
158
|
+
def,
|
|
159
|
+
handler: module.default
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Invoke function handler.
|
|
164
|
+
*/
|
|
165
|
+
async _invoke(name, event) {
|
|
166
|
+
const seq = ++this._seq;
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
log.info("req", {
|
|
169
|
+
seq,
|
|
170
|
+
name
|
|
171
|
+
}, {
|
|
172
|
+
F: __dxlog_file,
|
|
173
|
+
L: 159,
|
|
174
|
+
S: this,
|
|
175
|
+
C: (f, a) => f(...a)
|
|
176
|
+
});
|
|
177
|
+
const { handler } = this._handlers[name];
|
|
178
|
+
const context = {
|
|
179
|
+
client: this._client
|
|
180
|
+
};
|
|
181
|
+
let statusCode = 200;
|
|
182
|
+
const response = {
|
|
183
|
+
status: (code) => {
|
|
184
|
+
statusCode = code;
|
|
185
|
+
return response;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
await handler({
|
|
189
|
+
context,
|
|
190
|
+
event,
|
|
191
|
+
response
|
|
192
|
+
});
|
|
193
|
+
log.info("res", {
|
|
194
|
+
seq,
|
|
195
|
+
name,
|
|
196
|
+
statusCode,
|
|
197
|
+
duration: Date.now() - now
|
|
198
|
+
}, {
|
|
199
|
+
F: __dxlog_file,
|
|
200
|
+
L: 175,
|
|
201
|
+
S: this,
|
|
202
|
+
C: (f, a) => f(...a)
|
|
203
|
+
});
|
|
204
|
+
return statusCode;
|
|
124
205
|
}
|
|
125
206
|
};
|
|
126
207
|
|
|
127
|
-
// packages/core/functions/src/runtime/
|
|
208
|
+
// packages/core/functions/src/runtime/scheduler.ts
|
|
209
|
+
import { CronJob } from "cron";
|
|
128
210
|
import { DeferredTask } from "@dxos/async";
|
|
129
211
|
import { Context } from "@dxos/context";
|
|
130
212
|
import { Filter, createSubscription } from "@dxos/echo-schema";
|
|
131
|
-
import { invariant } from "@dxos/invariant";
|
|
213
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
132
214
|
import { log as log2 } from "@dxos/log";
|
|
133
215
|
import { ComplexMap } from "@dxos/util";
|
|
134
|
-
var __dxlog_file2 = "/home/
|
|
135
|
-
var
|
|
136
|
-
constructor(_client,
|
|
216
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/scheduler.ts";
|
|
217
|
+
var Scheduler = class {
|
|
218
|
+
constructor(_client, _manifest, _options) {
|
|
137
219
|
this._client = _client;
|
|
138
|
-
this.
|
|
139
|
-
this.
|
|
140
|
-
this._mounts = new ComplexMap(({
|
|
141
|
-
this._queries = /* @__PURE__ */ new Set();
|
|
220
|
+
this._manifest = _manifest;
|
|
221
|
+
this._options = _options;
|
|
222
|
+
this._mounts = new ComplexMap(({ id, spaceKey }) => `${spaceKey.toHex()}:${id}`);
|
|
142
223
|
}
|
|
143
224
|
async start() {
|
|
144
225
|
this._client.spaces.subscribe(async (spaces) => {
|
|
145
226
|
for (const space of spaces) {
|
|
146
227
|
await space.waitUntilReady();
|
|
147
|
-
for (const trigger of this.
|
|
228
|
+
for (const trigger of this._manifest.triggers ?? []) {
|
|
148
229
|
await this.mount(new Context(), space, trigger);
|
|
149
230
|
}
|
|
150
231
|
}
|
|
151
232
|
});
|
|
152
233
|
}
|
|
153
234
|
async stop() {
|
|
154
|
-
for (const {
|
|
155
|
-
await this.unmount(
|
|
235
|
+
for (const { id, spaceKey } of this._mounts.keys()) {
|
|
236
|
+
await this.unmount(id, spaceKey);
|
|
156
237
|
}
|
|
157
238
|
}
|
|
158
239
|
async mount(ctx, space, trigger) {
|
|
159
240
|
const key = {
|
|
160
|
-
|
|
241
|
+
id: trigger.function,
|
|
161
242
|
spaceKey: space.key
|
|
162
243
|
};
|
|
244
|
+
const def = this._manifest.functions.find((config) => config.id === trigger.function);
|
|
245
|
+
invariant2(def, `Function not found: ${trigger.function}`, {
|
|
246
|
+
F: __dxlog_file2,
|
|
247
|
+
L: 59,
|
|
248
|
+
S: this,
|
|
249
|
+
A: [
|
|
250
|
+
"def",
|
|
251
|
+
"`Function not found: ${trigger.function}`"
|
|
252
|
+
]
|
|
253
|
+
});
|
|
163
254
|
const exists = this._mounts.get(key);
|
|
164
255
|
if (!exists) {
|
|
165
256
|
this._mounts.set(key, {
|
|
@@ -171,57 +262,55 @@ var TriggerManager = class {
|
|
|
171
262
|
trigger
|
|
172
263
|
}, {
|
|
173
264
|
F: __dxlog_file2,
|
|
174
|
-
L:
|
|
265
|
+
L: 64,
|
|
175
266
|
S: this,
|
|
176
267
|
C: (f, a) => f(...a)
|
|
177
268
|
});
|
|
178
269
|
if (ctx.disposed) {
|
|
179
270
|
return;
|
|
180
271
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
272
|
+
if (trigger.schedule) {
|
|
273
|
+
const task = new DeferredTask(ctx, async () => {
|
|
274
|
+
await this.execFunction(def, {
|
|
275
|
+
space: space.key
|
|
276
|
+
});
|
|
186
277
|
});
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
space: space.key,
|
|
199
|
-
objects: objectIds.size,
|
|
200
|
-
count
|
|
201
|
-
}, {
|
|
202
|
-
F: __dxlog_file2,
|
|
203
|
-
L: 84,
|
|
204
|
-
S: this,
|
|
205
|
-
C: (f, a) => f(...a)
|
|
278
|
+
const job = new CronJob(trigger.schedule, () => task.schedule());
|
|
279
|
+
job.start();
|
|
280
|
+
ctx.onDispose(() => job.stop());
|
|
281
|
+
}
|
|
282
|
+
if (trigger.subscription) {
|
|
283
|
+
const objectIds = /* @__PURE__ */ new Set();
|
|
284
|
+
const task = new DeferredTask(ctx, async () => {
|
|
285
|
+
await this.execFunction(def, {
|
|
286
|
+
space: space.key,
|
|
287
|
+
objects: Array.from(objectIds)
|
|
288
|
+
});
|
|
206
289
|
});
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
subscription
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
290
|
+
const subscription = createSubscription(({ added, updated }) => {
|
|
291
|
+
for (const object of added) {
|
|
292
|
+
objectIds.add(object.id);
|
|
293
|
+
}
|
|
294
|
+
for (const object of updated) {
|
|
295
|
+
objectIds.add(object.id);
|
|
296
|
+
}
|
|
297
|
+
task.schedule();
|
|
298
|
+
});
|
|
299
|
+
const { type, props } = trigger.subscription;
|
|
300
|
+
const query = space.db.query(Filter.typename(type, props));
|
|
301
|
+
const unsubscribe = query.subscribe(({ objects }) => {
|
|
302
|
+
subscription.update(objects);
|
|
303
|
+
}, true);
|
|
304
|
+
ctx.onDispose(() => {
|
|
305
|
+
subscription.unsubscribe();
|
|
306
|
+
unsubscribe();
|
|
307
|
+
});
|
|
308
|
+
}
|
|
220
309
|
}
|
|
221
310
|
}
|
|
222
|
-
async unmount(
|
|
311
|
+
async unmount(id, spaceKey) {
|
|
223
312
|
const key = {
|
|
224
|
-
|
|
313
|
+
id,
|
|
225
314
|
spaceKey
|
|
226
315
|
};
|
|
227
316
|
const { ctx } = this._mounts.get(key) ?? {};
|
|
@@ -230,59 +319,39 @@ var TriggerManager = class {
|
|
|
230
319
|
await ctx.dispose();
|
|
231
320
|
}
|
|
232
321
|
}
|
|
233
|
-
async
|
|
234
|
-
const { endpoint, runtime } = options;
|
|
235
|
-
invariant(endpoint, "Missing endpoint", {
|
|
236
|
-
F: __dxlog_file2,
|
|
237
|
-
L: 120,
|
|
238
|
-
S: this,
|
|
239
|
-
A: [
|
|
240
|
-
"endpoint",
|
|
241
|
-
"'Missing endpoint'"
|
|
242
|
-
]
|
|
243
|
-
});
|
|
244
|
-
invariant(runtime, "Missing runtime", {
|
|
245
|
-
F: __dxlog_file2,
|
|
246
|
-
L: 121,
|
|
247
|
-
S: this,
|
|
248
|
-
A: [
|
|
249
|
-
"runtime",
|
|
250
|
-
"'Missing runtime'"
|
|
251
|
-
]
|
|
252
|
-
});
|
|
322
|
+
async execFunction(def, data) {
|
|
253
323
|
try {
|
|
254
|
-
log2("
|
|
255
|
-
function:
|
|
324
|
+
log2("request", {
|
|
325
|
+
function: def.id
|
|
256
326
|
}, {
|
|
257
327
|
F: __dxlog_file2,
|
|
258
|
-
L:
|
|
328
|
+
L: 130,
|
|
259
329
|
S: this,
|
|
260
330
|
C: (f, a) => f(...a)
|
|
261
331
|
});
|
|
262
|
-
const
|
|
263
|
-
const res = await fetch(url, {
|
|
332
|
+
const response = await fetch(`${this._options.endpoint}/${def.name}`, {
|
|
264
333
|
method: "POST",
|
|
265
|
-
body: JSON.stringify(data),
|
|
266
334
|
headers: {
|
|
267
335
|
"Content-Type": "application/json"
|
|
268
|
-
}
|
|
336
|
+
},
|
|
337
|
+
body: JSON.stringify(data)
|
|
269
338
|
});
|
|
270
339
|
log2("result", {
|
|
271
|
-
function:
|
|
272
|
-
result:
|
|
340
|
+
function: def.id,
|
|
341
|
+
result: response.status
|
|
273
342
|
}, {
|
|
274
343
|
F: __dxlog_file2,
|
|
275
|
-
L:
|
|
344
|
+
L: 140,
|
|
276
345
|
S: this,
|
|
277
346
|
C: (f, a) => f(...a)
|
|
278
347
|
});
|
|
279
348
|
} catch (err) {
|
|
280
349
|
log2.error("error", {
|
|
281
|
-
function:
|
|
350
|
+
function: def.id,
|
|
282
351
|
error: err.message
|
|
283
352
|
}, {
|
|
284
353
|
F: __dxlog_file2,
|
|
285
|
-
L:
|
|
354
|
+
L: 142,
|
|
286
355
|
S: this,
|
|
287
356
|
C: (f, a) => f(...a)
|
|
288
357
|
});
|
|
@@ -291,6 +360,6 @@ var TriggerManager = class {
|
|
|
291
360
|
};
|
|
292
361
|
export {
|
|
293
362
|
DevServer,
|
|
294
|
-
|
|
363
|
+
Scheduler
|
|
295
364
|
};
|
|
296
365
|
//# 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 {
|
|
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};\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.error(err);\n res.statusCode = 500;\n res.end();\n }\n });\n\n this._port = await getPort({ 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 };\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 { DeferredTask } from '@dxos/async';\nimport { type Client, type PublicKey } from '@dxos/client';\nimport { type Space } from '@dxos/client/echo';\nimport { Context } from '@dxos/context';\nimport { Filter, createSubscription } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type 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 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\n const { type, props } = trigger.subscription;\n const query = space.db.query(Filter.typename(type, props));\n const unsubscribe = query.subscribe(({ objects }) => {\n subscription.update(objects);\n }, true);\n\n ctx.onDispose(() => {\n subscription.unsubscribe();\n 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", "getPort", "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", "response", "status", "code", "duration", "CronJob", "DeferredTask", "Context", "Filter", "createSubscription", "invariant", "log", "ComplexMap", "Scheduler", "constructor", "_client", "_manifest", "_options", "_mounts", "id", "spaceKey", "toHex", "start", "spaces", "subscribe", "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", "added", "updated", "object", "add", "type", "props", "query", "db", "typename", "unsubscribe", "update", "delete", "dispose", "data", "response", "fetch", "endpoint", "name", "method", "headers", "body", "JSON", "stringify", "result", "status", "err", "error", "message"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/core/functions/src/
|
|
1
|
+
{"inputs":{"packages/core/functions/src/handler.ts":{"bytes":1313,"imports":[],"format":"esm"},"packages/core/functions/src/manifest.ts":{"bytes":1735,"imports":[],"format":"esm"},"packages/core/functions/src/runtime/dev-server.ts":{"bytes":18553,"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","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/scheduler.ts":{"bytes":16641,"imports":[{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/functions/src/runtime/index.ts":{"bytes":566,"imports":[{"path":"packages/core/functions/src/runtime/dev-server.ts","kind":"import-statement","original":"./dev-server"},{"path":"packages/core/functions/src/runtime/scheduler.ts","kind":"import-statement","original":"./scheduler"}],"format":"esm"},"packages/core/functions/src/index.ts":{"bytes":637,"imports":[{"path":"packages/core/functions/src/handler.ts","kind":"import-statement","original":"./handler"},{"path":"packages/core/functions/src/manifest.ts","kind":"import-statement","original":"./manifest"},{"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":16609},"packages/core/functions/dist/lib/browser/index.mjs":{"imports":[{"path":"express","kind":"import-statement","external":true},{"path":"get-port-please","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"cron","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["DevServer","Scheduler"],"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":4739},"packages/core/functions/src/runtime/index.ts":{"bytesInOutput":0},"packages/core/functions/src/runtime/scheduler.ts":{"bytesInOutput":4189}},"bytes":9509}}}
|