@dxos/functions 0.5.3-main.61bbff4 → 0.5.3-main.64035f0
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 +424 -642
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +421 -627
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/index.d.ts +0 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.d.ts +10 -7
- package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
- package/dist/types/src/runtime/scheduler.d.ts +59 -10
- package/dist/types/src/runtime/scheduler.d.ts.map +1 -1
- package/dist/types/src/testing/test/handler.d.ts +0 -1
- package/dist/types/src/testing/test/handler.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +112 -118
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +13 -16
- package/schema/functions.json +107 -121
- package/src/index.ts +0 -2
- package/src/runtime/dev-server.test.ts +35 -15
- package/src/runtime/dev-server.ts +18 -36
- package/src/runtime/scheduler.test.ts +75 -54
- package/src/runtime/scheduler.ts +298 -58
- package/src/testing/test/handler.ts +2 -8
- package/src/types.ts +42 -56
- package/dist/types/src/registry/function-registry.d.ts +0 -24
- package/dist/types/src/registry/function-registry.d.ts.map +0 -1
- package/dist/types/src/registry/function-registry.test.d.ts +0 -2
- package/dist/types/src/registry/function-registry.test.d.ts.map +0 -1
- package/dist/types/src/registry/index.d.ts +0 -2
- package/dist/types/src/registry/index.d.ts.map +0 -1
- package/dist/types/src/testing/functions-integration.test.d.ts +0 -2
- package/dist/types/src/testing/functions-integration.test.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts +0 -4
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/dist/types/src/testing/setup.d.ts +0 -5
- package/dist/types/src/testing/setup.d.ts.map +0 -1
- package/dist/types/src/testing/types.d.ts +0 -9
- package/dist/types/src/testing/types.d.ts.map +0 -1
- package/dist/types/src/testing/util.d.ts +0 -3
- package/dist/types/src/testing/util.d.ts.map +0 -1
- package/dist/types/src/trigger/index.d.ts +0 -2
- package/dist/types/src/trigger/index.d.ts.map +0 -1
- package/dist/types/src/trigger/trigger-registry.d.ts +0 -40
- package/dist/types/src/trigger/trigger-registry.d.ts.map +0 -1
- package/dist/types/src/trigger/trigger-registry.test.d.ts +0 -2
- package/dist/types/src/trigger/trigger-registry.test.d.ts.map +0 -1
- package/dist/types/src/trigger/type/index.d.ts +0 -5
- package/dist/types/src/trigger/type/index.d.ts.map +0 -1
- package/dist/types/src/trigger/type/subscription-trigger.d.ts +0 -4
- package/dist/types/src/trigger/type/subscription-trigger.d.ts.map +0 -1
- package/dist/types/src/trigger/type/timer-trigger.d.ts +0 -4
- package/dist/types/src/trigger/type/timer-trigger.d.ts.map +0 -1
- package/dist/types/src/trigger/type/webhook-trigger.d.ts +0 -4
- package/dist/types/src/trigger/type/webhook-trigger.d.ts.map +0 -1
- package/dist/types/src/trigger/type/websocket-trigger.d.ts +0 -13
- package/dist/types/src/trigger/type/websocket-trigger.d.ts.map +0 -1
- package/src/registry/function-registry.test.ts +0 -105
- package/src/registry/function-registry.ts +0 -84
- package/src/registry/index.ts +0 -5
- package/src/testing/functions-integration.test.ts +0 -99
- package/src/testing/index.ts +0 -7
- package/src/testing/setup.ts +0 -45
- package/src/testing/types.ts +0 -9
- package/src/testing/util.ts +0 -16
- package/src/trigger/index.ts +0 -5
- package/src/trigger/trigger-registry.test.ts +0 -229
- package/src/trigger/trigger-registry.ts +0 -176
- package/src/trigger/type/index.ts +0 -8
- package/src/trigger/type/subscription-trigger.ts +0 -73
- package/src/trigger/type/timer-trigger.ts +0 -44
- package/src/trigger/type/webhook-trigger.ts +0 -47
- package/src/trigger/type/websocket-trigger.ts +0 -91
package/dist/lib/node/index.cjs
CHANGED
|
@@ -29,54 +29,33 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var node_exports = {};
|
|
30
30
|
__export(node_exports, {
|
|
31
31
|
DevServer: () => DevServer,
|
|
32
|
-
FunctionDef: () => FunctionDef,
|
|
33
32
|
FunctionManifestSchema: () => FunctionManifestSchema,
|
|
34
|
-
FunctionRegistry: () => FunctionRegistry,
|
|
35
|
-
FunctionTrigger: () => FunctionTrigger,
|
|
36
33
|
Scheduler: () => Scheduler,
|
|
37
|
-
TriggerRegistry: () => TriggerRegistry,
|
|
38
34
|
subscriptionHandler: () => subscriptionHandler
|
|
39
35
|
});
|
|
40
36
|
module.exports = __toCommonJS(node_exports);
|
|
41
37
|
var import_client = require("@dxos/client");
|
|
42
38
|
var import_log = require("@dxos/log");
|
|
43
39
|
var import_util = require("@dxos/util");
|
|
44
|
-
var import_async = require("@dxos/async");
|
|
45
|
-
var import_echo = require("@dxos/client/echo");
|
|
46
|
-
var import_context = require("@dxos/context");
|
|
47
|
-
var import_keys = require("@dxos/keys");
|
|
48
|
-
var import_util2 = require("@dxos/util");
|
|
49
|
-
var import_echo_schema = require("@dxos/echo-schema");
|
|
50
40
|
var import_express = __toESM(require("express"));
|
|
51
41
|
var import_get_port_please = require("get-port-please");
|
|
52
42
|
var import_node_path = require("node:path");
|
|
53
|
-
var
|
|
54
|
-
var import_context2 = require("@dxos/context");
|
|
43
|
+
var import_async = require("@dxos/async");
|
|
55
44
|
var import_invariant = require("@dxos/invariant");
|
|
56
45
|
var import_log2 = require("@dxos/log");
|
|
57
|
-
var import_node_path2 = __toESM(require("node:path"));
|
|
58
|
-
var import_context3 = require("@dxos/context");
|
|
59
|
-
var import_log3 = require("@dxos/log");
|
|
60
|
-
var import_async3 = require("@dxos/async");
|
|
61
|
-
var import_echo2 = require("@dxos/client/echo");
|
|
62
|
-
var import_context4 = require("@dxos/context");
|
|
63
|
-
var import_invariant2 = require("@dxos/invariant");
|
|
64
|
-
var import_keys2 = require("@dxos/keys");
|
|
65
|
-
var import_log4 = require("@dxos/log");
|
|
66
|
-
var import_util3 = require("@dxos/util");
|
|
67
|
-
var import_types = require("@braneframe/types");
|
|
68
|
-
var import_async4 = require("@dxos/async");
|
|
69
|
-
var import_echo_db = require("@dxos/echo-db");
|
|
70
|
-
var import_log5 = require("@dxos/log");
|
|
71
46
|
var import_cron = require("cron");
|
|
72
|
-
var import_async5 = require("@dxos/async");
|
|
73
|
-
var import_log6 = require("@dxos/log");
|
|
74
47
|
var import_get_port_please2 = require("get-port-please");
|
|
75
48
|
var import_node_http = __toESM(require("node:http"));
|
|
76
|
-
var
|
|
49
|
+
var import_node_path2 = __toESM(require("node:path"));
|
|
77
50
|
var import_ws = __toESM(require("ws"));
|
|
78
|
-
var
|
|
79
|
-
var
|
|
51
|
+
var import_types = require("@braneframe/types");
|
|
52
|
+
var import_async2 = require("@dxos/async");
|
|
53
|
+
var import_echo = require("@dxos/client/echo");
|
|
54
|
+
var import_context = require("@dxos/context");
|
|
55
|
+
var import_invariant2 = require("@dxos/invariant");
|
|
56
|
+
var import_log3 = require("@dxos/log");
|
|
57
|
+
var import_util2 = require("@dxos/util");
|
|
58
|
+
var S = __toESM(require("@effect/schema/Schema"));
|
|
80
59
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
81
60
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
82
61
|
}) : x)(function(x) {
|
|
@@ -123,150 +102,15 @@ var subscriptionHandler = (handler) => {
|
|
|
123
102
|
});
|
|
124
103
|
};
|
|
125
104
|
};
|
|
126
|
-
var omitEchoId = (schema) => import_echo_schema.S.make(import_echo_schema.AST.omit(schema.ast, [
|
|
127
|
-
"id"
|
|
128
|
-
]));
|
|
129
|
-
var SubscriptionTriggerSchema = import_echo_schema.S.struct({
|
|
130
|
-
type: import_echo_schema.S.literal("subscription"),
|
|
131
|
-
// TODO(burdon): Define query DSL.
|
|
132
|
-
filter: import_echo_schema.S.array(import_echo_schema.S.struct({
|
|
133
|
-
type: import_echo_schema.S.string,
|
|
134
|
-
props: import_echo_schema.S.optional(import_echo_schema.S.record(import_echo_schema.S.string, import_echo_schema.S.any))
|
|
135
|
-
})),
|
|
136
|
-
options: import_echo_schema.S.optional(import_echo_schema.S.struct({
|
|
137
|
-
// Watch changes to object (not just creation).
|
|
138
|
-
deep: import_echo_schema.S.optional(import_echo_schema.S.boolean),
|
|
139
|
-
// Debounce changes (delay in ms).
|
|
140
|
-
delay: import_echo_schema.S.optional(import_echo_schema.S.number)
|
|
141
|
-
}))
|
|
142
|
-
});
|
|
143
|
-
var TimerTriggerSchema = import_echo_schema.S.struct({
|
|
144
|
-
type: import_echo_schema.S.literal("timer"),
|
|
145
|
-
cron: import_echo_schema.S.string
|
|
146
|
-
});
|
|
147
|
-
var WebhookTriggerSchema = import_echo_schema.S.mutable(import_echo_schema.S.struct({
|
|
148
|
-
type: import_echo_schema.S.literal("webhook"),
|
|
149
|
-
method: import_echo_schema.S.string,
|
|
150
|
-
// Assigned port.
|
|
151
|
-
port: import_echo_schema.S.optional(import_echo_schema.S.number)
|
|
152
|
-
}));
|
|
153
|
-
var WebsocketTriggerSchema = import_echo_schema.S.struct({
|
|
154
|
-
type: import_echo_schema.S.literal("websocket"),
|
|
155
|
-
url: import_echo_schema.S.string,
|
|
156
|
-
init: import_echo_schema.S.optional(import_echo_schema.S.record(import_echo_schema.S.string, import_echo_schema.S.any))
|
|
157
|
-
});
|
|
158
|
-
var TriggerSpecSchema = import_echo_schema.S.union(TimerTriggerSchema, WebhookTriggerSchema, WebsocketTriggerSchema, SubscriptionTriggerSchema);
|
|
159
|
-
var FunctionDef = class extends (0, import_echo_schema.TypedObject)({
|
|
160
|
-
typename: "dxos.org/type/FunctionDef",
|
|
161
|
-
version: "0.1.0"
|
|
162
|
-
})({
|
|
163
|
-
uri: import_echo_schema.S.string,
|
|
164
|
-
description: import_echo_schema.S.optional(import_echo_schema.S.string),
|
|
165
|
-
route: import_echo_schema.S.string,
|
|
166
|
-
// TODO(burdon): NPM/GitHub/Docker/CF URL?
|
|
167
|
-
handler: import_echo_schema.S.string
|
|
168
|
-
}) {
|
|
169
|
-
};
|
|
170
|
-
var FunctionTrigger = class extends (0, import_echo_schema.TypedObject)({
|
|
171
|
-
typename: "dxos.org/type/FunctionTrigger",
|
|
172
|
-
version: "0.1.0"
|
|
173
|
-
})({
|
|
174
|
-
function: import_echo_schema.S.string.pipe(import_echo_schema.S.description("Function ID/URI.")),
|
|
175
|
-
// Context passed to a function.
|
|
176
|
-
meta: import_echo_schema.S.optional(import_echo_schema.S.record(import_echo_schema.S.string, import_echo_schema.S.any)),
|
|
177
|
-
spec: TriggerSpecSchema
|
|
178
|
-
}) {
|
|
179
|
-
};
|
|
180
|
-
var FunctionManifestSchema = import_echo_schema.S.struct({
|
|
181
|
-
functions: import_echo_schema.S.optional(import_echo_schema.S.mutable(import_echo_schema.S.array(omitEchoId(FunctionDef)))),
|
|
182
|
-
triggers: import_echo_schema.S.optional(import_echo_schema.S.mutable(import_echo_schema.S.array(omitEchoId(FunctionTrigger))))
|
|
183
|
-
});
|
|
184
|
-
var FunctionRegistry = class extends import_context.Resource {
|
|
185
|
-
constructor(_client) {
|
|
186
|
-
super();
|
|
187
|
-
this._client = _client;
|
|
188
|
-
this._functionBySpaceKey = new import_util2.ComplexMap(import_keys.PublicKey.hash);
|
|
189
|
-
this.onFunctionsRegistered = new import_async.Event();
|
|
190
|
-
}
|
|
191
|
-
getFunctions(space) {
|
|
192
|
-
return this._functionBySpaceKey.get(space.key) ?? [];
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* The method loads function definitions from the manifest into the space.
|
|
196
|
-
* We first load all the definitions from the space to deduplicate by functionId.
|
|
197
|
-
*/
|
|
198
|
-
// TODO(burdon): This should not be space specific (they are static for the agent).
|
|
199
|
-
async register(space, manifest) {
|
|
200
|
-
if (!manifest.functions?.length) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (!space.db.graph.runtimeSchemaRegistry.hasSchema(FunctionDef)) {
|
|
204
|
-
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);
|
|
205
|
-
}
|
|
206
|
-
const { objects: existingDefinitions } = await space.db.query(import_echo.Filter.schema(FunctionDef)).run();
|
|
207
|
-
const newDefinitions = getNewDefinitions(manifest.functions, existingDefinitions);
|
|
208
|
-
const reactiveObjects = newDefinitions.map((template) => (0, import_echo.create)(FunctionDef, {
|
|
209
|
-
...template
|
|
210
|
-
}));
|
|
211
|
-
reactiveObjects.forEach((obj) => space.db.add(obj));
|
|
212
|
-
}
|
|
213
|
-
async _open() {
|
|
214
|
-
const spaceListSubscription = this._client.spaces.subscribe(async (spaces) => {
|
|
215
|
-
for (const space of spaces) {
|
|
216
|
-
if (this._functionBySpaceKey.has(space.key)) {
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
const registered = [];
|
|
220
|
-
this._functionBySpaceKey.set(space.key, registered);
|
|
221
|
-
await space.waitUntilReady();
|
|
222
|
-
if (this._ctx.disposed) {
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
const functionsSubscription = space.db.query(import_echo.Filter.schema(FunctionDef)).subscribe((definitions) => {
|
|
226
|
-
const newFunctions = getNewDefinitions(definitions.objects, registered);
|
|
227
|
-
if (newFunctions.length > 0) {
|
|
228
|
-
registered.push(...newFunctions);
|
|
229
|
-
this.onFunctionsRegistered.emit({
|
|
230
|
-
space,
|
|
231
|
-
newFunctions
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
this._ctx.onDispose(functionsSubscription);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
this._ctx.onDispose(() => spaceListSubscription.unsubscribe());
|
|
239
|
-
}
|
|
240
|
-
async _close(_) {
|
|
241
|
-
this._functionBySpaceKey.clear();
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
var getNewDefinitions = (candidateList, existing) => {
|
|
245
|
-
return candidateList.filter((candidate) => existing.find((def) => def.uri === candidate.uri) == null);
|
|
246
|
-
};
|
|
247
105
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/dev-server.ts";
|
|
248
106
|
var DevServer = class {
|
|
249
107
|
// prettier-ignore
|
|
250
|
-
constructor(_client,
|
|
108
|
+
constructor(_client, _options) {
|
|
251
109
|
this._client = _client;
|
|
252
|
-
this._functionsRegistry = _functionsRegistry;
|
|
253
110
|
this._options = _options;
|
|
254
|
-
this._ctx = createContext();
|
|
255
111
|
this._handlers = {};
|
|
256
112
|
this._seq = 0;
|
|
257
|
-
this.update = new
|
|
258
|
-
this._functionsRegistry.onFunctionsRegistered.on(async ({ newFunctions }) => {
|
|
259
|
-
newFunctions.forEach((def) => this._load(def));
|
|
260
|
-
await this._safeUpdateRegistration();
|
|
261
|
-
(0, import_log2.log)("new functions loaded", {
|
|
262
|
-
newFunctions
|
|
263
|
-
}, {
|
|
264
|
-
F: __dxlog_file2,
|
|
265
|
-
L: 53,
|
|
266
|
-
S: this,
|
|
267
|
-
C: (f, a) => f(...a)
|
|
268
|
-
});
|
|
269
|
-
});
|
|
113
|
+
this.update = new import_async.Event();
|
|
270
114
|
}
|
|
271
115
|
get stats() {
|
|
272
116
|
return {
|
|
@@ -276,7 +120,7 @@ var DevServer = class {
|
|
|
276
120
|
get endpoint() {
|
|
277
121
|
(0, import_invariant.invariant)(this._port, void 0, {
|
|
278
122
|
F: __dxlog_file2,
|
|
279
|
-
L:
|
|
123
|
+
L: 54,
|
|
280
124
|
S: this,
|
|
281
125
|
A: [
|
|
282
126
|
"this._port",
|
|
@@ -291,6 +135,20 @@ var DevServer = class {
|
|
|
291
135
|
get functions() {
|
|
292
136
|
return Object.values(this._handlers);
|
|
293
137
|
}
|
|
138
|
+
async initialize() {
|
|
139
|
+
for (const def of this._options.manifest.functions) {
|
|
140
|
+
try {
|
|
141
|
+
await this._load(def);
|
|
142
|
+
} catch (err) {
|
|
143
|
+
import_log2.log.error("parsing function (check manifest)", err, {
|
|
144
|
+
F: __dxlog_file2,
|
|
145
|
+
L: 71,
|
|
146
|
+
S: this,
|
|
147
|
+
C: (f, a) => f(...a)
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
294
152
|
async start() {
|
|
295
153
|
(0, import_invariant.invariant)(!this._server, void 0, {
|
|
296
154
|
F: __dxlog_file2,
|
|
@@ -307,7 +165,6 @@ var DevServer = class {
|
|
|
307
165
|
S: this,
|
|
308
166
|
C: (f, a) => f(...a)
|
|
309
167
|
});
|
|
310
|
-
this._ctx = createContext();
|
|
311
168
|
const app = (0, import_express.default)();
|
|
312
169
|
app.use(import_express.default.json());
|
|
313
170
|
app.post("/:path", async (req, res) => {
|
|
@@ -317,7 +174,7 @@ var DevServer = class {
|
|
|
317
174
|
path: path2
|
|
318
175
|
}, {
|
|
319
176
|
F: __dxlog_file2,
|
|
320
|
-
L:
|
|
177
|
+
L: 87,
|
|
321
178
|
S: this,
|
|
322
179
|
C: (f, a) => f(...a)
|
|
323
180
|
});
|
|
@@ -330,7 +187,7 @@ var DevServer = class {
|
|
|
330
187
|
} catch (err) {
|
|
331
188
|
import_log2.log.catch(err, void 0, {
|
|
332
189
|
F: __dxlog_file2,
|
|
333
|
-
L:
|
|
190
|
+
L: 97,
|
|
334
191
|
S: this,
|
|
335
192
|
C: (f, a) => f(...a)
|
|
336
193
|
});
|
|
@@ -349,7 +206,11 @@ var DevServer = class {
|
|
|
349
206
|
this._server = app.listen(this._port);
|
|
350
207
|
try {
|
|
351
208
|
const { registrationId, endpoint } = await this._client.services.services.FunctionRegistryService.register({
|
|
352
|
-
endpoint: this.endpoint
|
|
209
|
+
endpoint: this.endpoint,
|
|
210
|
+
functions: this.functions.map(({ def: { id, path: path2 } }) => ({
|
|
211
|
+
id,
|
|
212
|
+
path: path2
|
|
213
|
+
}))
|
|
353
214
|
});
|
|
354
215
|
import_log2.log.info("registered", {
|
|
355
216
|
endpoint
|
|
@@ -361,7 +222,6 @@ var DevServer = class {
|
|
|
361
222
|
});
|
|
362
223
|
this._proxy = endpoint;
|
|
363
224
|
this._functionServiceRegistration = registrationId;
|
|
364
|
-
await this._functionsRegistry.open(this._ctx);
|
|
365
225
|
} catch (err) {
|
|
366
226
|
await this.stop();
|
|
367
227
|
throw new Error("FunctionRegistryService not available (check plugin is configured).");
|
|
@@ -370,7 +230,7 @@ var DevServer = class {
|
|
|
370
230
|
port: this._port
|
|
371
231
|
}, {
|
|
372
232
|
F: __dxlog_file2,
|
|
373
|
-
L:
|
|
233
|
+
L: 121,
|
|
374
234
|
S: this,
|
|
375
235
|
C: (f, a) => f(...a)
|
|
376
236
|
});
|
|
@@ -378,7 +238,7 @@ var DevServer = class {
|
|
|
378
238
|
async stop() {
|
|
379
239
|
(0, import_invariant.invariant)(this._server, void 0, {
|
|
380
240
|
F: __dxlog_file2,
|
|
381
|
-
L:
|
|
241
|
+
L: 125,
|
|
382
242
|
S: this,
|
|
383
243
|
A: [
|
|
384
244
|
"this._server",
|
|
@@ -387,15 +247,15 @@ var DevServer = class {
|
|
|
387
247
|
});
|
|
388
248
|
import_log2.log.info("stopping...", void 0, {
|
|
389
249
|
F: __dxlog_file2,
|
|
390
|
-
L:
|
|
250
|
+
L: 126,
|
|
391
251
|
S: this,
|
|
392
252
|
C: (f, a) => f(...a)
|
|
393
253
|
});
|
|
394
|
-
const trigger = new
|
|
254
|
+
const trigger = new import_async.Trigger();
|
|
395
255
|
this._server.close(async () => {
|
|
396
256
|
import_log2.log.info("server stopped", void 0, {
|
|
397
257
|
F: __dxlog_file2,
|
|
398
|
-
L:
|
|
258
|
+
L: 130,
|
|
399
259
|
S: this,
|
|
400
260
|
C: (f, a) => f(...a)
|
|
401
261
|
});
|
|
@@ -403,7 +263,7 @@ var DevServer = class {
|
|
|
403
263
|
if (this._functionServiceRegistration) {
|
|
404
264
|
(0, import_invariant.invariant)(this._client.services.services.FunctionRegistryService, void 0, {
|
|
405
265
|
F: __dxlog_file2,
|
|
406
|
-
L:
|
|
266
|
+
L: 133,
|
|
407
267
|
S: this,
|
|
408
268
|
A: [
|
|
409
269
|
"this._client.services.services.FunctionRegistryService",
|
|
@@ -417,7 +277,7 @@ var DevServer = class {
|
|
|
417
277
|
registrationId: this._functionServiceRegistration
|
|
418
278
|
}, {
|
|
419
279
|
F: __dxlog_file2,
|
|
420
|
-
L:
|
|
280
|
+
L: 138,
|
|
421
281
|
S: this,
|
|
422
282
|
C: (f, a) => f(...a)
|
|
423
283
|
});
|
|
@@ -434,7 +294,7 @@ var DevServer = class {
|
|
|
434
294
|
this._server = void 0;
|
|
435
295
|
import_log2.log.info("stopped", void 0, {
|
|
436
296
|
F: __dxlog_file2,
|
|
437
|
-
L:
|
|
297
|
+
L: 152,
|
|
438
298
|
S: this,
|
|
439
299
|
C: (f, a) => f(...a)
|
|
440
300
|
});
|
|
@@ -443,14 +303,14 @@ var DevServer = class {
|
|
|
443
303
|
* Load function.
|
|
444
304
|
*/
|
|
445
305
|
async _load(def, force = false) {
|
|
446
|
-
const {
|
|
306
|
+
const { id, path: path2, handler } = def;
|
|
447
307
|
const filePath = (0, import_node_path.join)(this._options.baseDir, handler);
|
|
448
308
|
import_log2.log.info("loading", {
|
|
449
|
-
|
|
309
|
+
id,
|
|
450
310
|
force
|
|
451
311
|
}, {
|
|
452
312
|
F: __dxlog_file2,
|
|
453
|
-
L:
|
|
313
|
+
L: 161,
|
|
454
314
|
S: this,
|
|
455
315
|
C: (f, a) => f(...a)
|
|
456
316
|
});
|
|
@@ -461,40 +321,13 @@ var DevServer = class {
|
|
|
461
321
|
}
|
|
462
322
|
const module2 = __require(filePath);
|
|
463
323
|
if (typeof module2.default !== "function") {
|
|
464
|
-
throw new Error(`Handler must export default function: ${
|
|
324
|
+
throw new Error(`Handler must export default function: ${id}`);
|
|
465
325
|
}
|
|
466
|
-
this._handlers[
|
|
326
|
+
this._handlers[path2] = {
|
|
467
327
|
def,
|
|
468
328
|
handler: module2.default
|
|
469
329
|
};
|
|
470
330
|
}
|
|
471
|
-
async _safeUpdateRegistration() {
|
|
472
|
-
(0, import_invariant.invariant)(this._functionServiceRegistration, void 0, {
|
|
473
|
-
F: __dxlog_file2,
|
|
474
|
-
L: 186,
|
|
475
|
-
S: this,
|
|
476
|
-
A: [
|
|
477
|
-
"this._functionServiceRegistration",
|
|
478
|
-
""
|
|
479
|
-
]
|
|
480
|
-
});
|
|
481
|
-
try {
|
|
482
|
-
await this._client.services.services.FunctionRegistryService.updateRegistration({
|
|
483
|
-
registrationId: this._functionServiceRegistration,
|
|
484
|
-
functions: this.functions.map(({ def: { id, route } }) => ({
|
|
485
|
-
id,
|
|
486
|
-
route
|
|
487
|
-
}))
|
|
488
|
-
});
|
|
489
|
-
} catch (e) {
|
|
490
|
-
import_log2.log.catch(e, void 0, {
|
|
491
|
-
F: __dxlog_file2,
|
|
492
|
-
L: 193,
|
|
493
|
-
S: this,
|
|
494
|
-
C: (f, a) => f(...a)
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
331
|
/**
|
|
499
332
|
* Invoke function.
|
|
500
333
|
*/
|
|
@@ -506,7 +339,7 @@ var DevServer = class {
|
|
|
506
339
|
path: path2
|
|
507
340
|
}, {
|
|
508
341
|
F: __dxlog_file2,
|
|
509
|
-
L:
|
|
342
|
+
L: 188,
|
|
510
343
|
S: this,
|
|
511
344
|
C: (f, a) => f(...a)
|
|
512
345
|
});
|
|
@@ -520,7 +353,7 @@ var DevServer = class {
|
|
|
520
353
|
duration: Date.now() - now
|
|
521
354
|
}, {
|
|
522
355
|
F: __dxlog_file2,
|
|
523
|
-
L:
|
|
356
|
+
L: 191,
|
|
524
357
|
S: this,
|
|
525
358
|
C: (f, a) => f(...a)
|
|
526
359
|
});
|
|
@@ -531,7 +364,7 @@ var DevServer = class {
|
|
|
531
364
|
const { handler } = this._handlers[path2] ?? {};
|
|
532
365
|
(0, import_invariant.invariant)(handler, `invalid path: ${path2}`, {
|
|
533
366
|
F: __dxlog_file2,
|
|
534
|
-
L:
|
|
367
|
+
L: 198,
|
|
535
368
|
S: this,
|
|
536
369
|
A: [
|
|
537
370
|
"handler",
|
|
@@ -557,93 +390,111 @@ var DevServer = class {
|
|
|
557
390
|
return statusCode;
|
|
558
391
|
}
|
|
559
392
|
};
|
|
560
|
-
var createContext = () => new import_context2.Context({
|
|
561
|
-
name: "DevServer"
|
|
562
|
-
});
|
|
563
393
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/functions/src/runtime/scheduler.ts";
|
|
564
394
|
var Scheduler = class {
|
|
565
|
-
constructor(
|
|
566
|
-
this.
|
|
567
|
-
this.
|
|
395
|
+
constructor(_client, _manifest, _options = {}) {
|
|
396
|
+
this._client = _client;
|
|
397
|
+
this._manifest = _manifest;
|
|
568
398
|
this._options = _options;
|
|
569
|
-
this.
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
})
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
});
|
|
399
|
+
this._mounts = new import_util2.ComplexMap(({ spaceKey, id }) => `${spaceKey.toHex()}:${id}`);
|
|
400
|
+
}
|
|
401
|
+
get mounts() {
|
|
402
|
+
return Array.from(this._mounts.values()).reduce((acc, { trigger }) => {
|
|
403
|
+
acc.push(trigger);
|
|
404
|
+
return acc;
|
|
405
|
+
}, []);
|
|
576
406
|
}
|
|
577
407
|
async start() {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
408
|
+
this._client.spaces.subscribe(async (spaces) => {
|
|
409
|
+
for (const space of spaces) {
|
|
410
|
+
await space.waitUntilReady();
|
|
411
|
+
for (const trigger of this._manifest.triggers ?? []) {
|
|
412
|
+
await this.mount(new import_context.Context(), space, trigger);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
582
416
|
}
|
|
583
417
|
async stop() {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
}
|
|
588
|
-
async register(space, manifest) {
|
|
589
|
-
await this.functions.register(space, manifest);
|
|
590
|
-
await this.triggers.register(space, manifest);
|
|
418
|
+
for (const { id, spaceKey } of this._mounts.keys()) {
|
|
419
|
+
await this.unmount(id, spaceKey);
|
|
420
|
+
}
|
|
591
421
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
422
|
+
/**
|
|
423
|
+
* Mount trigger.
|
|
424
|
+
*/
|
|
425
|
+
async mount(ctx, space, trigger) {
|
|
426
|
+
const key = {
|
|
427
|
+
spaceKey: space.key,
|
|
428
|
+
id: trigger.function
|
|
429
|
+
};
|
|
430
|
+
const def = this._manifest.functions.find((config) => config.id === trigger.function);
|
|
431
|
+
(0, import_invariant2.invariant)(def, `Function not found: ${trigger.function}`, {
|
|
432
|
+
F: __dxlog_file3,
|
|
433
|
+
L: 76,
|
|
434
|
+
S: this,
|
|
435
|
+
A: [
|
|
436
|
+
"def",
|
|
437
|
+
"`Function not found: ${trigger.function}`"
|
|
438
|
+
]
|
|
595
439
|
});
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
440
|
+
const exists = this._mounts.get(key);
|
|
441
|
+
if (!exists) {
|
|
442
|
+
this._mounts.set(key, {
|
|
443
|
+
ctx,
|
|
444
|
+
trigger
|
|
445
|
+
});
|
|
446
|
+
(0, import_log3.log)("mount", {
|
|
447
|
+
space: space.key,
|
|
448
|
+
trigger
|
|
603
449
|
}, {
|
|
604
450
|
F: __dxlog_file3,
|
|
605
|
-
L:
|
|
451
|
+
L: 82,
|
|
606
452
|
S: this,
|
|
607
453
|
C: (f, a) => f(...a)
|
|
608
454
|
});
|
|
609
|
-
|
|
455
|
+
if (ctx.disposed) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (trigger.timer) {
|
|
459
|
+
await this._createTimer(ctx, space, def, trigger);
|
|
460
|
+
}
|
|
461
|
+
if (trigger.webhook) {
|
|
462
|
+
await this._createWebhook(ctx, space, def, trigger);
|
|
463
|
+
}
|
|
464
|
+
if (trigger.websocket) {
|
|
465
|
+
await this._createWebsocket(ctx, space, def, trigger);
|
|
466
|
+
}
|
|
467
|
+
if (trigger.subscription) {
|
|
468
|
+
await this._createSubscription(ctx, space, def, trigger);
|
|
469
|
+
}
|
|
610
470
|
}
|
|
611
|
-
await this.triggers.activate({
|
|
612
|
-
space
|
|
613
|
-
}, fnTrigger, async (args) => {
|
|
614
|
-
return this._execFunction(definition, {
|
|
615
|
-
meta: fnTrigger.meta,
|
|
616
|
-
data: {
|
|
617
|
-
...args,
|
|
618
|
-
spaceKey: space.key
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
});
|
|
622
|
-
(0, import_log3.log)("activated trigger", {
|
|
623
|
-
space: space.key,
|
|
624
|
-
trigger: fnTrigger
|
|
625
|
-
}, {
|
|
626
|
-
F: __dxlog_file3,
|
|
627
|
-
L: 84,
|
|
628
|
-
S: this,
|
|
629
|
-
C: (f, a) => f(...a)
|
|
630
|
-
});
|
|
631
471
|
}
|
|
632
|
-
async
|
|
472
|
+
async unmount(id, spaceKey) {
|
|
473
|
+
const key = {
|
|
474
|
+
id,
|
|
475
|
+
spaceKey
|
|
476
|
+
};
|
|
477
|
+
const { ctx } = this._mounts.get(key) ?? {};
|
|
478
|
+
if (ctx) {
|
|
479
|
+
this._mounts.delete(key);
|
|
480
|
+
await ctx.dispose();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
async _execFunction(def, trigger, data) {
|
|
633
484
|
let status = 0;
|
|
634
485
|
try {
|
|
635
|
-
const payload = Object.assign({},
|
|
636
|
-
meta
|
|
486
|
+
const payload = Object.assign({}, {
|
|
487
|
+
meta: trigger.meta
|
|
637
488
|
}, data);
|
|
638
489
|
const { endpoint, callback } = this._options;
|
|
639
490
|
if (endpoint) {
|
|
640
|
-
const url = import_node_path2.default.join(endpoint, def.
|
|
491
|
+
const url = import_node_path2.default.join(endpoint, def.path);
|
|
641
492
|
import_log3.log.info("exec", {
|
|
642
|
-
function: def.
|
|
493
|
+
function: def.id,
|
|
643
494
|
url
|
|
644
495
|
}, {
|
|
645
496
|
F: __dxlog_file3,
|
|
646
|
-
L:
|
|
497
|
+
L: 128,
|
|
647
498
|
S: this,
|
|
648
499
|
C: (f, a) => f(...a)
|
|
649
500
|
});
|
|
@@ -657,10 +508,10 @@ var Scheduler = class {
|
|
|
657
508
|
status = response.status;
|
|
658
509
|
} else if (callback) {
|
|
659
510
|
import_log3.log.info("exec", {
|
|
660
|
-
function: def.
|
|
511
|
+
function: def.id
|
|
661
512
|
}, {
|
|
662
513
|
F: __dxlog_file3,
|
|
663
|
-
L:
|
|
514
|
+
L: 139,
|
|
664
515
|
S: this,
|
|
665
516
|
C: (f, a) => f(...a)
|
|
666
517
|
});
|
|
@@ -670,21 +521,21 @@ var Scheduler = class {
|
|
|
670
521
|
throw new Error(`Response: ${status}`);
|
|
671
522
|
}
|
|
672
523
|
import_log3.log.info("done", {
|
|
673
|
-
function: def.
|
|
524
|
+
function: def.id,
|
|
674
525
|
status
|
|
675
526
|
}, {
|
|
676
527
|
F: __dxlog_file3,
|
|
677
|
-
L:
|
|
528
|
+
L: 149,
|
|
678
529
|
S: this,
|
|
679
530
|
C: (f, a) => f(...a)
|
|
680
531
|
});
|
|
681
532
|
} catch (err) {
|
|
682
533
|
import_log3.log.error("error", {
|
|
683
|
-
function: def.
|
|
534
|
+
function: def.id,
|
|
684
535
|
error: err.message
|
|
685
536
|
}, {
|
|
686
537
|
F: __dxlog_file3,
|
|
687
|
-
L:
|
|
538
|
+
L: 151,
|
|
688
539
|
S: this,
|
|
689
540
|
C: (f, a) => f(...a)
|
|
690
541
|
});
|
|
@@ -692,391 +543,334 @@ var Scheduler = class {
|
|
|
692
543
|
}
|
|
693
544
|
return status;
|
|
694
545
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
objects: Array.from(objectIds)
|
|
706
|
-
});
|
|
707
|
-
objectIds.clear();
|
|
708
|
-
}
|
|
709
|
-
});
|
|
710
|
-
const subscriptions = [];
|
|
711
|
-
const subscription = (0, import_echo_db.createSubscription)(({ added, updated }) => {
|
|
712
|
-
import_log5.log.info("updated", {
|
|
713
|
-
added: added.length,
|
|
714
|
-
updated: updated.length
|
|
546
|
+
//
|
|
547
|
+
// Triggers
|
|
548
|
+
//
|
|
549
|
+
/**
|
|
550
|
+
* Cron timer.
|
|
551
|
+
*/
|
|
552
|
+
async _createTimer(ctx, space, def, trigger) {
|
|
553
|
+
import_log3.log.info("timer", {
|
|
554
|
+
space: space.key,
|
|
555
|
+
trigger
|
|
715
556
|
}, {
|
|
716
|
-
F:
|
|
717
|
-
L:
|
|
718
|
-
S:
|
|
557
|
+
F: __dxlog_file3,
|
|
558
|
+
L: 166,
|
|
559
|
+
S: this,
|
|
719
560
|
C: (f, a) => f(...a)
|
|
720
561
|
});
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
objectIds.add(object.id);
|
|
726
|
-
}
|
|
727
|
-
task.schedule();
|
|
728
|
-
});
|
|
729
|
-
subscriptions.push(() => subscription.unsubscribe());
|
|
730
|
-
const { filter, options: { deep, delay } = {} } = spec;
|
|
731
|
-
const update = ({ objects }) => {
|
|
732
|
-
subscription.update(objects);
|
|
733
|
-
if (deep) {
|
|
734
|
-
import_log5.log.info("update", {
|
|
735
|
-
objects: objects.length
|
|
736
|
-
}, {
|
|
737
|
-
F: __dxlog_file4,
|
|
738
|
-
L: 52,
|
|
739
|
-
S: void 0,
|
|
740
|
-
C: (f, a) => f(...a)
|
|
741
|
-
});
|
|
742
|
-
for (const object of objects) {
|
|
743
|
-
const content = object.content;
|
|
744
|
-
if (content instanceof import_types.TextV0Type) {
|
|
745
|
-
subscriptions.push((0, import_echo_db.getAutomergeObjectCore)(content).updates.on((0, import_async4.debounce)(() => subscription.update([
|
|
746
|
-
object
|
|
747
|
-
]), 1e3)));
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
};
|
|
752
|
-
const query = triggerCtx.space.db.query(import_echo_db.Filter.or(filter.map(({ type, props }) => import_echo_db.Filter.typename(type, props))));
|
|
753
|
-
subscriptions.push(query.subscribe(delay ? (0, import_async4.debounce)(update, delay) : update));
|
|
754
|
-
ctx.onDispose(() => {
|
|
755
|
-
subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
756
|
-
});
|
|
757
|
-
};
|
|
758
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/functions/src/trigger/type/timer-trigger.ts";
|
|
759
|
-
var createTimerTrigger = async (ctx, triggerContext, spec, callback) => {
|
|
760
|
-
const task = new import_async5.DeferredTask(ctx, async () => {
|
|
761
|
-
await callback({});
|
|
762
|
-
});
|
|
763
|
-
let last = 0;
|
|
764
|
-
let run = 0;
|
|
765
|
-
const job = import_cron.CronJob.from({
|
|
766
|
-
cronTime: spec.cron,
|
|
767
|
-
runOnInit: false,
|
|
768
|
-
onTick: () => {
|
|
769
|
-
const now = Date.now();
|
|
770
|
-
const delta = last ? now - last : 0;
|
|
771
|
-
last = now;
|
|
772
|
-
run++;
|
|
773
|
-
import_log6.log.info("tick", {
|
|
774
|
-
space: triggerContext.space.key.truncate(),
|
|
775
|
-
count: run,
|
|
776
|
-
delta
|
|
777
|
-
}, {
|
|
778
|
-
F: __dxlog_file5,
|
|
779
|
-
L: 37,
|
|
780
|
-
S: void 0,
|
|
781
|
-
C: (f, a) => f(...a)
|
|
562
|
+
const spec = trigger.timer;
|
|
563
|
+
const task = new import_async2.DeferredTask(ctx, async () => {
|
|
564
|
+
await this._execFunction(def, trigger, {
|
|
565
|
+
spaceKey: space.key
|
|
782
566
|
});
|
|
783
|
-
task.schedule();
|
|
784
|
-
}
|
|
785
|
-
});
|
|
786
|
-
job.start();
|
|
787
|
-
ctx.onDispose(() => job.stop());
|
|
788
|
-
};
|
|
789
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/functions/src/trigger/type/webhook-trigger.ts";
|
|
790
|
-
var createWebhookTrigger = async (ctx, _, spec, callback) => {
|
|
791
|
-
const server = import_node_http.default.createServer(async (req, res) => {
|
|
792
|
-
if (req.method !== spec.method) {
|
|
793
|
-
res.statusCode = 405;
|
|
794
|
-
return res.end();
|
|
795
|
-
}
|
|
796
|
-
res.statusCode = await callback({});
|
|
797
|
-
res.end();
|
|
798
|
-
});
|
|
799
|
-
const port = await (0, import_get_port_please2.getPort)({
|
|
800
|
-
random: true
|
|
801
|
-
});
|
|
802
|
-
server.listen(port, () => {
|
|
803
|
-
import_log7.log.info("started webhook", {
|
|
804
|
-
port
|
|
805
|
-
}, {
|
|
806
|
-
F: __dxlog_file6,
|
|
807
|
-
L: 40,
|
|
808
|
-
S: void 0,
|
|
809
|
-
C: (f, a) => f(...a)
|
|
810
567
|
});
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
const open = new import_async6.Trigger();
|
|
826
|
-
ws = new import_ws.default(url);
|
|
827
|
-
Object.assign(ws, {
|
|
828
|
-
onopen: () => {
|
|
829
|
-
import_log8.log.info("opened", {
|
|
830
|
-
url
|
|
831
|
-
}, {
|
|
832
|
-
F: __dxlog_file7,
|
|
833
|
-
L: 39,
|
|
834
|
-
S: void 0,
|
|
835
|
-
C: (f, a) => f(...a)
|
|
836
|
-
});
|
|
837
|
-
if (spec.init) {
|
|
838
|
-
ws.send(new TextEncoder().encode(JSON.stringify(init)));
|
|
839
|
-
}
|
|
840
|
-
open.wake(true);
|
|
841
|
-
},
|
|
842
|
-
onclose: (event) => {
|
|
843
|
-
import_log8.log.info("closed", {
|
|
844
|
-
url,
|
|
845
|
-
code: event.code
|
|
568
|
+
let last = 0;
|
|
569
|
+
let run = 0;
|
|
570
|
+
const job = import_cron.CronJob.from({
|
|
571
|
+
cronTime: spec.cron,
|
|
572
|
+
runOnInit: false,
|
|
573
|
+
onTick: () => {
|
|
574
|
+
const now = Date.now();
|
|
575
|
+
const delta = last ? now - last : 0;
|
|
576
|
+
last = now;
|
|
577
|
+
run++;
|
|
578
|
+
import_log3.log.info("tick", {
|
|
579
|
+
space: space.key.truncate(),
|
|
580
|
+
count: run,
|
|
581
|
+
delta
|
|
846
582
|
}, {
|
|
847
|
-
F:
|
|
848
|
-
L:
|
|
849
|
-
S:
|
|
850
|
-
C: (f, a) => f(...a)
|
|
851
|
-
});
|
|
852
|
-
if (event.code === 1006) {
|
|
853
|
-
setTimeout(async () => {
|
|
854
|
-
import_log8.log.info(`reconnecting in ${options.retryDelay}s...`, {
|
|
855
|
-
url
|
|
856
|
-
}, {
|
|
857
|
-
F: __dxlog_file7,
|
|
858
|
-
L: 53,
|
|
859
|
-
S: void 0,
|
|
860
|
-
C: (f, a) => f(...a)
|
|
861
|
-
});
|
|
862
|
-
await createWebsocketTrigger(ctx, triggerCtx, spec, callback, options);
|
|
863
|
-
}, options.retryDelay * 1e3);
|
|
864
|
-
}
|
|
865
|
-
open.wake(false);
|
|
866
|
-
},
|
|
867
|
-
onerror: (event) => {
|
|
868
|
-
import_log8.log.catch(event.error, {
|
|
869
|
-
url
|
|
870
|
-
}, {
|
|
871
|
-
F: __dxlog_file7,
|
|
872
|
-
L: 62,
|
|
873
|
-
S: void 0,
|
|
583
|
+
F: __dxlog_file3,
|
|
584
|
+
L: 186,
|
|
585
|
+
S: this,
|
|
874
586
|
C: (f, a) => f(...a)
|
|
875
587
|
});
|
|
876
|
-
|
|
877
|
-
onmessage: async (event) => {
|
|
878
|
-
try {
|
|
879
|
-
import_log8.log.info("message", void 0, {
|
|
880
|
-
F: __dxlog_file7,
|
|
881
|
-
L: 67,
|
|
882
|
-
S: void 0,
|
|
883
|
-
C: (f, a) => f(...a)
|
|
884
|
-
});
|
|
885
|
-
const data = JSON.parse(new TextDecoder().decode(event.data));
|
|
886
|
-
await callback({
|
|
887
|
-
data
|
|
888
|
-
});
|
|
889
|
-
} catch (err) {
|
|
890
|
-
import_log8.log.catch(err, {
|
|
891
|
-
url
|
|
892
|
-
}, {
|
|
893
|
-
F: __dxlog_file7,
|
|
894
|
-
L: 71,
|
|
895
|
-
S: void 0,
|
|
896
|
-
C: (f, a) => f(...a)
|
|
897
|
-
});
|
|
898
|
-
}
|
|
588
|
+
task.schedule();
|
|
899
589
|
}
|
|
900
590
|
});
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
break;
|
|
904
|
-
} else {
|
|
905
|
-
const wait = Math.pow(attempt, 2) * options.retryDelay;
|
|
906
|
-
if (attempt < options.maxAttempts) {
|
|
907
|
-
import_log8.log.warn(`failed to connect; trying again in ${wait}s`, {
|
|
908
|
-
attempt
|
|
909
|
-
}, {
|
|
910
|
-
F: __dxlog_file7,
|
|
911
|
-
L: 82,
|
|
912
|
-
S: void 0,
|
|
913
|
-
C: (f, a) => f(...a)
|
|
914
|
-
});
|
|
915
|
-
await (0, import_async6.sleep)(wait * 1e3);
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
ctx.onDispose(() => {
|
|
920
|
-
ws?.close();
|
|
921
|
-
});
|
|
922
|
-
};
|
|
923
|
-
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/core/functions/src/trigger/trigger-registry.ts";
|
|
924
|
-
var triggerHandlers = {
|
|
925
|
-
subscription: createSubscriptionTrigger,
|
|
926
|
-
timer: createTimerTrigger,
|
|
927
|
-
webhook: createWebhookTrigger,
|
|
928
|
-
websocket: createWebsocketTrigger
|
|
929
|
-
};
|
|
930
|
-
var TriggerRegistry = class extends import_context4.Resource {
|
|
931
|
-
constructor(_client, _options) {
|
|
932
|
-
super();
|
|
933
|
-
this._client = _client;
|
|
934
|
-
this._options = _options;
|
|
935
|
-
this._triggersBySpaceKey = new import_util3.ComplexMap(import_keys2.PublicKey.hash);
|
|
936
|
-
this.registered = new import_async3.Event();
|
|
937
|
-
this.removed = new import_async3.Event();
|
|
938
|
-
}
|
|
939
|
-
getActiveTriggers(space) {
|
|
940
|
-
return this._getTriggers(space, (t) => t.activationCtx != null);
|
|
591
|
+
job.start();
|
|
592
|
+
ctx.onDispose(() => job.stop());
|
|
941
593
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
async
|
|
946
|
-
|
|
947
|
-
space:
|
|
594
|
+
/**
|
|
595
|
+
* Webhook.
|
|
596
|
+
*/
|
|
597
|
+
async _createWebhook(ctx, space, def, trigger) {
|
|
598
|
+
import_log3.log.info("webhook", {
|
|
599
|
+
space: space.key,
|
|
948
600
|
trigger
|
|
949
601
|
}, {
|
|
950
|
-
F:
|
|
951
|
-
L:
|
|
602
|
+
F: __dxlog_file3,
|
|
603
|
+
L: 199,
|
|
952
604
|
S: this,
|
|
953
605
|
C: (f, a) => f(...a)
|
|
954
606
|
});
|
|
955
|
-
const
|
|
956
|
-
|
|
607
|
+
const spec = trigger.webhook;
|
|
608
|
+
const server = import_node_http.default.createServer(async (req, res) => {
|
|
609
|
+
if (req.method !== spec.method) {
|
|
610
|
+
res.statusCode = 405;
|
|
611
|
+
return res.end();
|
|
612
|
+
}
|
|
613
|
+
res.statusCode = await this._execFunction(def, trigger, {
|
|
614
|
+
spaceKey: space.key
|
|
615
|
+
});
|
|
616
|
+
res.end();
|
|
957
617
|
});
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
618
|
+
const port = await (0, import_get_port_please2.getPort)({
|
|
619
|
+
random: true
|
|
620
|
+
});
|
|
621
|
+
server.listen(port, () => {
|
|
622
|
+
import_log3.log.info("started webhook", {
|
|
623
|
+
port
|
|
624
|
+
}, {
|
|
625
|
+
F: __dxlog_file3,
|
|
626
|
+
L: 223,
|
|
627
|
+
S: this,
|
|
628
|
+
C: (f, a) => f(...a)
|
|
629
|
+
});
|
|
630
|
+
spec.port = port;
|
|
631
|
+
});
|
|
632
|
+
ctx.onDispose(() => {
|
|
633
|
+
server.close();
|
|
968
634
|
});
|
|
969
|
-
registeredTrigger.activationCtx = activationCtx;
|
|
970
|
-
try {
|
|
971
|
-
const options = this._options?.[trigger.spec.type];
|
|
972
|
-
await triggerHandlers[trigger.spec.type](activationCtx, triggerCtx, trigger.spec, callback, options);
|
|
973
|
-
} catch (err) {
|
|
974
|
-
delete registeredTrigger.activationCtx;
|
|
975
|
-
throw err;
|
|
976
|
-
}
|
|
977
635
|
}
|
|
978
636
|
/**
|
|
979
|
-
*
|
|
637
|
+
* Websocket.
|
|
638
|
+
* NOTE: The port must be unique, so the same hook cannot be used for multiple spaces.
|
|
980
639
|
*/
|
|
981
|
-
async
|
|
982
|
-
|
|
983
|
-
|
|
640
|
+
async _createWebsocket(ctx, space, def, trigger, options = {
|
|
641
|
+
retryDelay: 2,
|
|
642
|
+
maxAttempts: 5
|
|
643
|
+
}) {
|
|
644
|
+
import_log3.log.info("websocket", {
|
|
645
|
+
space: space.key,
|
|
646
|
+
trigger
|
|
984
647
|
}, {
|
|
985
|
-
F:
|
|
986
|
-
L:
|
|
648
|
+
F: __dxlog_file3,
|
|
649
|
+
L: 249,
|
|
987
650
|
S: this,
|
|
988
651
|
C: (f, a) => f(...a)
|
|
989
652
|
});
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
653
|
+
const spec = trigger.websocket;
|
|
654
|
+
const { url, init } = spec;
|
|
655
|
+
let ws;
|
|
656
|
+
for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
|
|
657
|
+
const open = new import_async2.Trigger();
|
|
658
|
+
ws = new import_ws.default(url);
|
|
659
|
+
Object.assign(ws, {
|
|
660
|
+
onopen: () => {
|
|
661
|
+
import_log3.log.info("opened", {
|
|
662
|
+
url
|
|
663
|
+
}, {
|
|
664
|
+
F: __dxlog_file3,
|
|
665
|
+
L: 260,
|
|
666
|
+
S: this,
|
|
667
|
+
C: (f, a) => f(...a)
|
|
668
|
+
});
|
|
669
|
+
if (spec.init) {
|
|
670
|
+
ws.send(new TextEncoder().encode(JSON.stringify(init)));
|
|
671
|
+
}
|
|
672
|
+
open.wake(true);
|
|
673
|
+
},
|
|
674
|
+
onclose: (event) => {
|
|
675
|
+
import_log3.log.info("closed", {
|
|
676
|
+
url,
|
|
677
|
+
code: event.code
|
|
678
|
+
}, {
|
|
679
|
+
F: __dxlog_file3,
|
|
680
|
+
L: 269,
|
|
681
|
+
S: this,
|
|
682
|
+
C: (f, a) => f(...a)
|
|
683
|
+
});
|
|
684
|
+
if (event.code === 1006) {
|
|
685
|
+
setTimeout(async () => {
|
|
686
|
+
import_log3.log.info(`reconnecting in ${options.retryDelay}s...`, {
|
|
687
|
+
url
|
|
688
|
+
}, {
|
|
689
|
+
F: __dxlog_file3,
|
|
690
|
+
L: 274,
|
|
691
|
+
S: this,
|
|
692
|
+
C: (f, a) => f(...a)
|
|
693
|
+
});
|
|
694
|
+
await this._createWebsocket(ctx, space, def, trigger, options);
|
|
695
|
+
}, options.retryDelay * 1e3);
|
|
696
|
+
}
|
|
697
|
+
open.wake(false);
|
|
698
|
+
},
|
|
699
|
+
onerror: (event) => {
|
|
700
|
+
import_log3.log.catch(event.error, {
|
|
701
|
+
url
|
|
702
|
+
}, {
|
|
703
|
+
F: __dxlog_file3,
|
|
704
|
+
L: 283,
|
|
705
|
+
S: this,
|
|
706
|
+
C: (f, a) => f(...a)
|
|
707
|
+
});
|
|
708
|
+
},
|
|
709
|
+
onmessage: async (event) => {
|
|
710
|
+
try {
|
|
711
|
+
const data = JSON.parse(new TextDecoder().decode(event.data));
|
|
712
|
+
await this._execFunction(def, trigger, {
|
|
713
|
+
spaceKey: space.key,
|
|
714
|
+
data
|
|
715
|
+
});
|
|
716
|
+
} catch (err) {
|
|
717
|
+
import_log3.log.catch(err, {
|
|
718
|
+
url
|
|
719
|
+
}, {
|
|
720
|
+
F: __dxlog_file3,
|
|
721
|
+
L: 291,
|
|
722
|
+
S: this,
|
|
723
|
+
C: (f, a) => f(...a)
|
|
724
|
+
});
|
|
725
|
+
}
|
|
1006
726
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
727
|
+
});
|
|
728
|
+
const isOpen = await open.wait();
|
|
729
|
+
if (isOpen) {
|
|
730
|
+
break;
|
|
731
|
+
} else {
|
|
732
|
+
const wait = Math.pow(attempt, 2) * options.retryDelay;
|
|
733
|
+
if (attempt < options.maxAttempts) {
|
|
734
|
+
import_log3.log.warn(`failed to connect; trying again in ${wait}s`, {
|
|
735
|
+
attempt
|
|
736
|
+
}, {
|
|
737
|
+
F: __dxlog_file3,
|
|
738
|
+
L: 302,
|
|
739
|
+
S: this,
|
|
740
|
+
C: (f, a) => f(...a)
|
|
741
|
+
});
|
|
742
|
+
await (0, import_async2.sleep)(wait * 1e3);
|
|
1012
743
|
}
|
|
1013
|
-
const functionsSubscription = space.db.query(import_echo2.Filter.schema(FunctionTrigger)).subscribe(async (triggers) => {
|
|
1014
|
-
await this._handleRemovedTriggers(space, triggers.objects, registered);
|
|
1015
|
-
this._handleNewTriggers(space, triggers.objects, registered);
|
|
1016
|
-
});
|
|
1017
|
-
this._ctx.onDispose(functionsSubscription);
|
|
1018
744
|
}
|
|
745
|
+
}
|
|
746
|
+
ctx.onDispose(() => {
|
|
747
|
+
ws?.close();
|
|
1019
748
|
});
|
|
1020
|
-
this._ctx.onDispose(() => spaceListSubscription.unsubscribe());
|
|
1021
749
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
750
|
+
/**
|
|
751
|
+
* ECHO subscription.
|
|
752
|
+
*/
|
|
753
|
+
async _createSubscription(ctx, space, def, trigger) {
|
|
754
|
+
import_log3.log.info("subscription", {
|
|
755
|
+
space: space.key,
|
|
756
|
+
trigger
|
|
757
|
+
}, {
|
|
758
|
+
F: __dxlog_file3,
|
|
759
|
+
L: 317,
|
|
760
|
+
S: this,
|
|
761
|
+
C: (f, a) => f(...a)
|
|
1028
762
|
});
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
registered.push(...newRegisteredTriggers);
|
|
1034
|
-
(0, import_log4.log)("registered new triggers", () => ({
|
|
763
|
+
const spec = trigger.subscription;
|
|
764
|
+
const objectIds = /* @__PURE__ */ new Set();
|
|
765
|
+
const task = new import_async2.DeferredTask(ctx, async () => {
|
|
766
|
+
await this._execFunction(def, trigger, {
|
|
1035
767
|
spaceKey: space.key,
|
|
1036
|
-
|
|
1037
|
-
})
|
|
1038
|
-
|
|
1039
|
-
|
|
768
|
+
objects: Array.from(objectIds)
|
|
769
|
+
});
|
|
770
|
+
});
|
|
771
|
+
const subscriptions = [];
|
|
772
|
+
const subscription = (0, import_echo.createSubscription)(({ added, updated }) => {
|
|
773
|
+
import_log3.log.info("updated", {
|
|
774
|
+
added: added.length,
|
|
775
|
+
updated: updated.length
|
|
776
|
+
}, {
|
|
777
|
+
F: __dxlog_file3,
|
|
778
|
+
L: 329,
|
|
1040
779
|
S: this,
|
|
1041
780
|
C: (f, a) => f(...a)
|
|
1042
781
|
});
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
triggers: newTriggers
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
async _handleRemovedTriggers(space, allTriggers, registered) {
|
|
1050
|
-
const removed = [];
|
|
1051
|
-
for (let i = registered.length - 1; i >= 0; i--) {
|
|
1052
|
-
const wasRemoved = allTriggers.find((trigger) => trigger.id === registered[i].trigger.id) == null;
|
|
1053
|
-
if (wasRemoved) {
|
|
1054
|
-
const unregistered = registered.splice(i, 1)[0];
|
|
1055
|
-
await unregistered.activationCtx?.dispose();
|
|
1056
|
-
removed.push(unregistered.trigger);
|
|
782
|
+
for (const object of added) {
|
|
783
|
+
objectIds.add(object.id);
|
|
1057
784
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
785
|
+
for (const object of updated) {
|
|
786
|
+
objectIds.add(object.id);
|
|
787
|
+
}
|
|
788
|
+
task.schedule();
|
|
789
|
+
});
|
|
790
|
+
subscriptions.push(() => subscription.unsubscribe());
|
|
791
|
+
const { filter, options: { deep, delay } = {} } = spec;
|
|
792
|
+
const update = ({ objects }) => {
|
|
793
|
+
subscription.update(objects);
|
|
794
|
+
if (deep) {
|
|
795
|
+
import_log3.log.info("update", {
|
|
796
|
+
objects: objects.length
|
|
797
|
+
}, {
|
|
798
|
+
F: __dxlog_file3,
|
|
799
|
+
L: 349,
|
|
800
|
+
S: this,
|
|
801
|
+
C: (f, a) => f(...a)
|
|
802
|
+
});
|
|
803
|
+
for (const object of objects) {
|
|
804
|
+
const content = object.content;
|
|
805
|
+
if (content instanceof import_types.TextV0Type) {
|
|
806
|
+
subscriptions.push((0, import_echo.getAutomergeObjectCore)(content).updates.on((0, import_async2.debounce)(() => subscription.update([
|
|
807
|
+
object
|
|
808
|
+
]), 1e3)));
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
const query = space.db.query(import_echo.Filter.or(filter.map(({ type, props }) => import_echo.Filter.typename(type, props))));
|
|
814
|
+
subscriptions.push(query.subscribe(delay ? (0, import_async2.debounce)(update, delay) : update));
|
|
815
|
+
ctx.onDispose(() => {
|
|
816
|
+
subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
817
|
+
});
|
|
1069
818
|
}
|
|
1070
819
|
};
|
|
820
|
+
var TimerTriggerSchema = S.struct({
|
|
821
|
+
cron: S.string
|
|
822
|
+
});
|
|
823
|
+
var WebhookTriggerSchema = S.mutable(S.struct({
|
|
824
|
+
method: S.string,
|
|
825
|
+
// Assigned port.
|
|
826
|
+
port: S.optional(S.number)
|
|
827
|
+
}));
|
|
828
|
+
var WebsocketTriggerSchema = S.struct({
|
|
829
|
+
url: S.string,
|
|
830
|
+
init: S.optional(S.record(S.string, S.any))
|
|
831
|
+
});
|
|
832
|
+
var SubscriptionTriggerSchema = S.struct({
|
|
833
|
+
spaceKey: S.optional(S.string),
|
|
834
|
+
// TODO(burdon): Define query DSL.
|
|
835
|
+
filter: S.array(S.struct({
|
|
836
|
+
type: S.string,
|
|
837
|
+
props: S.optional(S.record(S.string, S.any))
|
|
838
|
+
})),
|
|
839
|
+
options: S.optional(S.struct({
|
|
840
|
+
// Watch changes to object (not just creation).
|
|
841
|
+
deep: S.optional(S.boolean),
|
|
842
|
+
// Debounce changes (delay in ms).
|
|
843
|
+
delay: S.optional(S.number)
|
|
844
|
+
}))
|
|
845
|
+
});
|
|
846
|
+
var FunctionTriggerSchema = S.struct({
|
|
847
|
+
function: S.string.pipe(S.description("Function ID/URI.")),
|
|
848
|
+
// Context passed to function.
|
|
849
|
+
meta: S.optional(S.record(S.string, S.any)),
|
|
850
|
+
// Triggers.
|
|
851
|
+
timer: S.optional(TimerTriggerSchema),
|
|
852
|
+
webhook: S.optional(WebhookTriggerSchema),
|
|
853
|
+
websocket: S.optional(WebsocketTriggerSchema),
|
|
854
|
+
subscription: S.optional(SubscriptionTriggerSchema)
|
|
855
|
+
});
|
|
856
|
+
var FunctionDefSchema = S.struct({
|
|
857
|
+
id: S.string,
|
|
858
|
+
// name: S.string,
|
|
859
|
+
description: S.optional(S.string),
|
|
860
|
+
// TODO(burdon): Rename route?
|
|
861
|
+
path: S.string,
|
|
862
|
+
// TODO(burdon): NPM/GitHub/Docker/CF URL?
|
|
863
|
+
handler: S.string
|
|
864
|
+
});
|
|
865
|
+
var FunctionManifestSchema = S.struct({
|
|
866
|
+
functions: S.mutable(S.array(FunctionDefSchema)),
|
|
867
|
+
triggers: S.optional(S.mutable(S.array(FunctionTriggerSchema)))
|
|
868
|
+
});
|
|
1071
869
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1072
870
|
0 && (module.exports = {
|
|
1073
871
|
DevServer,
|
|
1074
|
-
FunctionDef,
|
|
1075
872
|
FunctionManifestSchema,
|
|
1076
|
-
FunctionRegistry,
|
|
1077
|
-
FunctionTrigger,
|
|
1078
873
|
Scheduler,
|
|
1079
|
-
TriggerRegistry,
|
|
1080
874
|
subscriptionHandler
|
|
1081
875
|
});
|
|
1082
876
|
//# sourceMappingURL=index.cjs.map
|