@nice-code/action 0.5.1 → 0.5.3
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/build/devtools/browser/index.js +4 -1
- package/build/devtools/server/index.js +246 -0
- package/build/index.js +2548 -206
- package/package.json +4 -4
package/build/index.js
CHANGED
|
@@ -1,246 +1,2588 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
// src/ActionDefinition/Action/Core/ActionCore.ts
|
|
2
|
+
import { nanoid } from "nanoid";
|
|
3
|
+
|
|
4
|
+
// src/nice_action.static.ts
|
|
5
|
+
var DEFAULT_TRANSPORT_TIMEOUT = 1e4;
|
|
6
|
+
var UNSET_RUNTIME_ENV_ID = "_unset_";
|
|
7
|
+
|
|
8
|
+
// src/ActionRuntime/utils/runtimeCoordinateToStringIds.ts
|
|
9
|
+
function runtimeCoordinateToStringIds(coordinate) {
|
|
10
|
+
return [
|
|
11
|
+
`envId[${coordinate.envId}]perId[${coordinate.perId ?? "_"}]:insId[${coordinate.insId ?? "_"}]`,
|
|
12
|
+
`envId[${coordinate.envId}]perId[${coordinate.perId ?? "_"}]:insId[_]`,
|
|
13
|
+
`envId[${coordinate.envId}]perId[_]:insId[_]`
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/ActionRuntime/RuntimeCoordinate.ts
|
|
18
|
+
class RuntimeCoordinate {
|
|
19
|
+
envId;
|
|
20
|
+
perId;
|
|
21
|
+
insId;
|
|
22
|
+
static get unknown() {
|
|
23
|
+
return new RuntimeCoordinate({
|
|
24
|
+
envId: UNSET_RUNTIME_ENV_ID
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
static env(envId) {
|
|
28
|
+
return new RuntimeCoordinate({
|
|
29
|
+
envId
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
withPersistentId(perId) {
|
|
33
|
+
return this.specify({ perId });
|
|
34
|
+
}
|
|
35
|
+
constructor({ envId, perId, insId }) {
|
|
36
|
+
this.envId = envId;
|
|
37
|
+
this.perId = perId;
|
|
38
|
+
this.insId = insId;
|
|
39
|
+
}
|
|
40
|
+
specify(specifics) {
|
|
41
|
+
return new RuntimeCoordinate({
|
|
42
|
+
envId: this.envId,
|
|
43
|
+
perId: this.perId,
|
|
44
|
+
insId: this.insId,
|
|
45
|
+
...specifics
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
specifyIfUnset(specifics) {
|
|
49
|
+
return new RuntimeCoordinate({
|
|
50
|
+
envId: this.envId,
|
|
51
|
+
perId: this.perId ?? specifics.perId,
|
|
52
|
+
insId: this.insId ?? specifics.insId
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
toJsonObject() {
|
|
56
|
+
return {
|
|
57
|
+
envId: this.envId,
|
|
58
|
+
perId: this.perId,
|
|
59
|
+
insId: this.insId
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
isExactlySame(other) {
|
|
63
|
+
return this.envId === other.envId && this.perId === other.perId && this.insId === other.insId;
|
|
64
|
+
}
|
|
65
|
+
isSameFor(other) {
|
|
66
|
+
return {
|
|
67
|
+
id: this.envId === other.envId,
|
|
68
|
+
perId: this.envId === other.envId && this.perId === other.perId,
|
|
69
|
+
insId: this.envId === other.envId && this.perId === other.perId && this.insId === other.insId
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
similarityLevel(other) {
|
|
73
|
+
const sameFor = this.isSameFor(other);
|
|
74
|
+
if (sameFor.insId)
|
|
75
|
+
return 3;
|
|
76
|
+
if (sameFor.perId)
|
|
77
|
+
return 2;
|
|
78
|
+
if (sameFor.id)
|
|
79
|
+
return 1;
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
get stringId() {
|
|
83
|
+
return `envId[${this.envId}]perId[${this.perId ?? "_"}]:insId[${this.insId ?? "_"}]`;
|
|
84
|
+
}
|
|
85
|
+
toStringIds() {
|
|
86
|
+
return runtimeCoordinateToStringIds(this);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/ActionDefinition/Action/ActionBase.ts
|
|
91
|
+
class ActionBase {
|
|
92
|
+
form;
|
|
93
|
+
_domain;
|
|
94
|
+
id;
|
|
95
|
+
domain;
|
|
96
|
+
allDomains;
|
|
97
|
+
schema;
|
|
98
|
+
constructor(form, _domain, id) {
|
|
99
|
+
this.form = form;
|
|
100
|
+
this._domain = _domain;
|
|
101
|
+
this.id = id;
|
|
102
|
+
this.domain = _domain.domain;
|
|
103
|
+
this.allDomains = _domain.allDomains;
|
|
104
|
+
this.schema = _domain.actionSchema[id];
|
|
105
|
+
}
|
|
106
|
+
toJsonObject() {
|
|
107
|
+
return {
|
|
108
|
+
form: this.form,
|
|
109
|
+
domain: this.domain,
|
|
110
|
+
allDomains: this.allDomains,
|
|
111
|
+
id: this.id
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
toJsonString() {
|
|
115
|
+
return JSON.stringify(this.toJsonObject());
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/ActionDefinition/Action/Context/ActionContext.ts
|
|
120
|
+
class ActionContext extends ActionBase {
|
|
121
|
+
_domain;
|
|
122
|
+
form = "context" /* context */;
|
|
123
|
+
_routing;
|
|
124
|
+
timeCreated;
|
|
125
|
+
cuid;
|
|
126
|
+
originClient;
|
|
127
|
+
constructor(_domain, id, hydrationData) {
|
|
128
|
+
super("context" /* context */, _domain, id);
|
|
129
|
+
this._domain = _domain;
|
|
130
|
+
this.timeCreated = hydrationData.timeCreated;
|
|
131
|
+
this.cuid = hydrationData.cuid;
|
|
132
|
+
this._routing = hydrationData.routing;
|
|
133
|
+
this.originClient = hydrationData.originClient;
|
|
134
|
+
}
|
|
135
|
+
_setOriginClient(client) {
|
|
136
|
+
this.originClient = client;
|
|
137
|
+
}
|
|
138
|
+
toJsonString() {
|
|
139
|
+
return JSON.stringify(this.toJsonObject());
|
|
140
|
+
}
|
|
141
|
+
toContextDataJsonObject() {
|
|
142
|
+
return {
|
|
143
|
+
timeCreated: this.timeCreated,
|
|
144
|
+
cuid: this.cuid,
|
|
145
|
+
routing: this.routing.map((item) => ({
|
|
146
|
+
runtime: item.runtime.toJsonObject(),
|
|
147
|
+
handler: item.handler,
|
|
148
|
+
time: item.time
|
|
149
|
+
})),
|
|
150
|
+
originClient: this.originClient.toJsonObject()
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
toJsonObject() {
|
|
154
|
+
return {
|
|
155
|
+
...super.toJsonObject(),
|
|
156
|
+
...this.toContextDataJsonObject()
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
get routing() {
|
|
160
|
+
return this._routing;
|
|
161
|
+
}
|
|
162
|
+
addRouteItem(item) {
|
|
163
|
+
this._routing.push(item);
|
|
164
|
+
}
|
|
165
|
+
deserializeInput(serialized) {
|
|
166
|
+
return this.schema.deserializeInput(serialized);
|
|
167
|
+
}
|
|
168
|
+
serializeInput(raw) {
|
|
169
|
+
return this.schema.serializeInput(raw);
|
|
170
|
+
}
|
|
171
|
+
validateInput(input) {
|
|
172
|
+
return this.schema.validateInput(input, {
|
|
173
|
+
domain: this.domain,
|
|
174
|
+
actionId: this.id
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
validateOutput(output) {
|
|
178
|
+
return this.schema.validateOutput(output, {
|
|
179
|
+
domain: this.domain,
|
|
180
|
+
actionId: this.id
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/ActionDefinition/Action/Payload/ActionPayload.ts
|
|
186
|
+
class ActionPayload extends ActionBase {
|
|
187
|
+
form = "data" /* data */;
|
|
188
|
+
type;
|
|
189
|
+
context;
|
|
190
|
+
time;
|
|
191
|
+
constructor(context, type, data) {
|
|
192
|
+
super("data" /* data */, context._domain, context.id);
|
|
193
|
+
this.context = context;
|
|
194
|
+
this.type = type;
|
|
195
|
+
this.time = data.time;
|
|
196
|
+
}
|
|
197
|
+
toBaseJsonObject() {
|
|
198
|
+
return {
|
|
199
|
+
...super.toJsonObject(),
|
|
200
|
+
type: this.type,
|
|
201
|
+
context: this.context.toContextDataJsonObject(),
|
|
202
|
+
time: this.time
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// src/utils/hashPayloadData.ts
|
|
208
|
+
function stableStringify(value) {
|
|
209
|
+
if (value === null || value === undefined)
|
|
210
|
+
return String(value);
|
|
211
|
+
if (typeof value !== "object")
|
|
212
|
+
return JSON.stringify(value) ?? "undefined";
|
|
213
|
+
if (Array.isArray(value))
|
|
214
|
+
return `[${value.map(stableStringify).join(",")}]`;
|
|
215
|
+
const keys = Object.keys(value).sort();
|
|
216
|
+
return "{" + keys.map((k) => `${JSON.stringify(k)}:${stableStringify(value[k])}`).join(",") + "}";
|
|
217
|
+
}
|
|
218
|
+
function fnv1a32(str) {
|
|
219
|
+
let hash = 2166136261;
|
|
220
|
+
for (let i = 0;i < str.length; i++) {
|
|
221
|
+
hash = (hash ^ str.charCodeAt(i)) * 16777619 >>> 0;
|
|
222
|
+
}
|
|
223
|
+
return hash.toString(16).padStart(8, "0");
|
|
224
|
+
}
|
|
225
|
+
function hashPayloadData(data) {
|
|
226
|
+
return fnv1a32(stableStringify(data));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// src/ActionDefinition/Action/Payload/ActionPayload.types.ts
|
|
230
|
+
var EActionPayloadType;
|
|
231
|
+
((EActionPayloadType2) => {
|
|
232
|
+
EActionPayloadType2["request"] = "request";
|
|
233
|
+
EActionPayloadType2["progress"] = "progress";
|
|
234
|
+
EActionPayloadType2["result"] = "result";
|
|
235
|
+
EActionPayloadType2["stream"] = "stream";
|
|
236
|
+
EActionPayloadType2["push"] = "push";
|
|
237
|
+
})(EActionPayloadType ||= {});
|
|
238
|
+
var EActionProgressType;
|
|
239
|
+
((EActionProgressType2) => {
|
|
240
|
+
EActionProgressType2["none"] = "none";
|
|
241
|
+
EActionProgressType2["percentage"] = "percentage";
|
|
242
|
+
EActionProgressType2["custom"] = "custom";
|
|
243
|
+
})(EActionProgressType ||= {});
|
|
244
|
+
|
|
245
|
+
// src/ActionDefinition/Action/Payload/ActionPayload_Progress.ts
|
|
246
|
+
class ActionPayload_Progress extends ActionPayload {
|
|
247
|
+
progress;
|
|
248
|
+
constructor(params, progress, data) {
|
|
249
|
+
super(params.context, "progress" /* progress */, data);
|
|
250
|
+
this.progress = progress;
|
|
251
|
+
}
|
|
252
|
+
toJsonObject() {
|
|
253
|
+
return {
|
|
254
|
+
...this.toBaseJsonObject(),
|
|
255
|
+
progress: this.progress
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
toJsonString() {
|
|
259
|
+
return JSON.stringify(this.toJsonObject());
|
|
260
|
+
}
|
|
261
|
+
toHttpResponse() {
|
|
262
|
+
return new Response(this.toJsonString(), {
|
|
263
|
+
status: 200,
|
|
264
|
+
headers: { "Content-Type": "application/json" }
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/ActionDefinition/Action/Payload/ActionPayload_Result.ts
|
|
270
|
+
class ActionPayload_Result extends ActionPayload {
|
|
271
|
+
result;
|
|
272
|
+
outputHash;
|
|
273
|
+
constructor(params, result, data) {
|
|
274
|
+
super(params.context, "result" /* result */, data);
|
|
275
|
+
this.result = result;
|
|
276
|
+
this.outputHash = result.ok ? hashPayloadData(this.context.schema.serializeOutput(result.output)) : hashPayloadData(result.error.message);
|
|
277
|
+
}
|
|
278
|
+
toJsonObject() {
|
|
279
|
+
const wireResult = this.result.ok ? { ok: true, output: this.context.schema.serializeOutput(this.result.output) } : this.result;
|
|
280
|
+
return {
|
|
281
|
+
...this.toBaseJsonObject(),
|
|
282
|
+
result: wireResult,
|
|
283
|
+
outputHash: this.outputHash
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
toJsonString() {
|
|
287
|
+
return JSON.stringify(this.toJsonObject());
|
|
288
|
+
}
|
|
289
|
+
toHttpResponse({ useErrorStatus = true } = {}) {
|
|
290
|
+
return new Response(this.toJsonString(), {
|
|
291
|
+
status: this.result.ok ? 200 : useErrorStatus ? this.result.error.httpStatusCode : 500,
|
|
292
|
+
headers: { "Content-Type": "application/json" }
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// src/ActionDefinition/Action/Payload/ActionPayload_Request.ts
|
|
298
|
+
class ActionPayload_Request extends ActionPayload {
|
|
299
|
+
input;
|
|
300
|
+
inputHash;
|
|
301
|
+
_callSite;
|
|
302
|
+
constructor(params, input, data) {
|
|
303
|
+
super(params.context, "request" /* request */, data);
|
|
304
|
+
this.input = input;
|
|
305
|
+
this.inputHash = hashPayloadData(this.context.schema.serializeInput(input));
|
|
306
|
+
}
|
|
307
|
+
successResult(...args) {
|
|
308
|
+
const output = args[0];
|
|
309
|
+
const finalOutput = this.context.schema.validateOutput(output, {
|
|
310
|
+
domain: this.domain,
|
|
311
|
+
actionId: this.id
|
|
312
|
+
});
|
|
313
|
+
return new ActionPayload_Result(this, { ok: true, output: finalOutput }, { time: Date.now() });
|
|
314
|
+
}
|
|
315
|
+
errorResult(err) {
|
|
316
|
+
return new ActionPayload_Result(this, { ok: false, error: err }, { time: Date.now() });
|
|
317
|
+
}
|
|
318
|
+
progress(progress) {
|
|
319
|
+
return new ActionPayload_Progress(this, progress, { time: Date.now() });
|
|
320
|
+
}
|
|
321
|
+
toJsonObject() {
|
|
322
|
+
return {
|
|
323
|
+
...super.toBaseJsonObject(),
|
|
324
|
+
input: this.context.schema.serializeInput(this.input),
|
|
325
|
+
inputHash: this.inputHash
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
toJsonString() {
|
|
329
|
+
return JSON.stringify(this.toJsonObject());
|
|
330
|
+
}
|
|
331
|
+
async runToOutput(options) {
|
|
332
|
+
const running = await this.run(options);
|
|
333
|
+
const result = await running.waitForResultPayload();
|
|
334
|
+
if (result.result.ok)
|
|
335
|
+
return result.result.output;
|
|
336
|
+
throw result.result.error;
|
|
337
|
+
}
|
|
338
|
+
async runToResultPayload(options) {
|
|
339
|
+
const value = await this.run(options);
|
|
340
|
+
return value.waitForResultPayload();
|
|
341
|
+
}
|
|
342
|
+
async run(options) {
|
|
343
|
+
if (this._callSite == null) {
|
|
344
|
+
this._callSite = new Error().stack;
|
|
345
|
+
}
|
|
346
|
+
return this._domain.runAction(this, options);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/ActionDefinition/Action/Core/ActionCore.ts
|
|
351
|
+
class ActionCore extends ActionBase {
|
|
352
|
+
_domain;
|
|
353
|
+
form = "core" /* core */;
|
|
354
|
+
constructor(_domain, id) {
|
|
355
|
+
super("core" /* core */, _domain, id);
|
|
356
|
+
this._domain = _domain;
|
|
357
|
+
}
|
|
358
|
+
is(action) {
|
|
359
|
+
return action instanceof ActionPayload && action.domain === this.domain && action.id === this.id;
|
|
360
|
+
}
|
|
361
|
+
toJsonObject() {
|
|
362
|
+
return {
|
|
363
|
+
id: this.id,
|
|
364
|
+
form: this.form,
|
|
365
|
+
domain: this.domain,
|
|
366
|
+
allDomains: this.allDomains
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
request(...args) {
|
|
370
|
+
const input = args[0];
|
|
371
|
+
const validatedInput = this.schema.validateInput(input, {
|
|
372
|
+
actionId: this.id,
|
|
373
|
+
domain: this.domain
|
|
374
|
+
});
|
|
375
|
+
const context = new ActionContext(this._domain, this.id, {
|
|
376
|
+
cuid: nanoid(),
|
|
377
|
+
timeCreated: Date.now(),
|
|
378
|
+
routing: [],
|
|
379
|
+
originClient: RuntimeCoordinate.unknown
|
|
380
|
+
});
|
|
381
|
+
return new ActionPayload_Request({ context }, validatedInput, {
|
|
382
|
+
time: Date.now()
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
deserializeInput(serialized) {
|
|
386
|
+
return this.schema.deserializeInput(serialized);
|
|
387
|
+
}
|
|
388
|
+
serializeInput(raw) {
|
|
389
|
+
return this.schema.serializeInput(raw);
|
|
390
|
+
}
|
|
391
|
+
validateInput(input) {
|
|
392
|
+
return this.schema.validateInput(input, {
|
|
393
|
+
domain: this.domain,
|
|
394
|
+
actionId: this.id
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
validateOutput(output) {
|
|
398
|
+
return this.schema.validateOutput(output, {
|
|
399
|
+
domain: this.domain,
|
|
400
|
+
actionId: this.id
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
// src/ActionDefinition/Action/RunningAction.types.ts
|
|
405
|
+
var ERunningActionState;
|
|
406
|
+
((ERunningActionState2) => {
|
|
407
|
+
ERunningActionState2["running"] = "running";
|
|
408
|
+
ERunningActionState2["completed"] = "completed";
|
|
409
|
+
})(ERunningActionState ||= {});
|
|
410
|
+
var ERunningActionUpdateType;
|
|
411
|
+
((ERunningActionUpdateType2) => {
|
|
412
|
+
ERunningActionUpdateType2["started"] = "started";
|
|
413
|
+
ERunningActionUpdateType2["progress"] = "progress";
|
|
414
|
+
ERunningActionUpdateType2["finished"] = "finished";
|
|
415
|
+
})(ERunningActionUpdateType ||= {});
|
|
416
|
+
var ERunningActionFinishedType;
|
|
417
|
+
((ERunningActionFinishedType2) => {
|
|
418
|
+
ERunningActionFinishedType2["aborted"] = "aborted";
|
|
419
|
+
ERunningActionFinishedType2["failed"] = "failed";
|
|
420
|
+
ERunningActionFinishedType2["success"] = "success";
|
|
421
|
+
})(ERunningActionFinishedType ||= {});
|
|
422
|
+
|
|
423
|
+
// src/ActionDefinition/Action/RunningAction.ts
|
|
424
|
+
class RunningAction {
|
|
425
|
+
_state;
|
|
426
|
+
context;
|
|
427
|
+
cuid;
|
|
428
|
+
id;
|
|
429
|
+
_domain;
|
|
430
|
+
domain;
|
|
431
|
+
allDomains;
|
|
432
|
+
parentCuid;
|
|
433
|
+
callSite;
|
|
434
|
+
_resultPayloadPromise;
|
|
435
|
+
_resolveResult;
|
|
436
|
+
_rejectResult;
|
|
437
|
+
_isAborted = false;
|
|
438
|
+
_updates = [];
|
|
439
|
+
_updateListeners = [];
|
|
440
|
+
constructor(initialState) {
|
|
441
|
+
this.context = initialState.context;
|
|
442
|
+
this.cuid = initialState.context.cuid;
|
|
443
|
+
this.id = initialState.context.id;
|
|
444
|
+
this.domain = initialState.context.domain;
|
|
445
|
+
this.allDomains = initialState.context.allDomains;
|
|
446
|
+
this._domain = initialState.context._domain;
|
|
447
|
+
this.parentCuid = initialState.parentCuid;
|
|
448
|
+
this.callSite = initialState.callSite;
|
|
449
|
+
this._resultPayloadPromise = new Promise((resolve, reject) => {
|
|
450
|
+
this._resolveResult = resolve;
|
|
451
|
+
this._rejectResult = reject;
|
|
452
|
+
});
|
|
453
|
+
this._resultPayloadPromise.catch(() => {});
|
|
454
|
+
this._state = {
|
|
455
|
+
request: initialState.request,
|
|
456
|
+
progress: initialState.progress ?? [],
|
|
457
|
+
result: initialState.result
|
|
458
|
+
};
|
|
459
|
+
this._sendUpdate({
|
|
460
|
+
type: "started" /* started */,
|
|
461
|
+
runningAction: this,
|
|
462
|
+
time: Date.now()
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
get state() {
|
|
466
|
+
return this._state;
|
|
467
|
+
}
|
|
468
|
+
abort(reason) {
|
|
469
|
+
this._abort(reason);
|
|
470
|
+
}
|
|
471
|
+
addUpdateListeners(listeners) {
|
|
472
|
+
this._updateListeners.push(...listeners);
|
|
473
|
+
for (const event of this._updates) {
|
|
474
|
+
for (const listener of listeners) {
|
|
475
|
+
listener(event);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return () => {
|
|
479
|
+
for (const listener of listeners) {
|
|
480
|
+
const i = this._updateListeners.indexOf(listener);
|
|
481
|
+
if (i !== -1)
|
|
482
|
+
this._updateListeners.splice(i, 1);
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
async* iterateUpdates() {
|
|
487
|
+
const queue = [];
|
|
488
|
+
let resolveWaiter = null;
|
|
489
|
+
const unsubscribe = this.addUpdateListeners([
|
|
490
|
+
(event) => {
|
|
491
|
+
queue.push(event);
|
|
492
|
+
if (resolveWaiter) {
|
|
493
|
+
resolveWaiter();
|
|
494
|
+
resolveWaiter = null;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
]);
|
|
498
|
+
try {
|
|
499
|
+
while (true) {
|
|
500
|
+
if (queue.length === 0) {
|
|
501
|
+
await new Promise((resolve) => {
|
|
502
|
+
resolveWaiter = resolve;
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
const event = queue.shift();
|
|
506
|
+
yield event;
|
|
507
|
+
if (event.type === "finished" /* finished */) {
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
} finally {
|
|
512
|
+
unsubscribe();
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
_sendUpdate(update) {
|
|
516
|
+
this._updates.push(update);
|
|
517
|
+
for (const listener of this._updateListeners)
|
|
518
|
+
listener(update);
|
|
519
|
+
}
|
|
520
|
+
_completeWithResult(result) {
|
|
521
|
+
if (this._state.result != null || this._isAborted)
|
|
522
|
+
return false;
|
|
523
|
+
this._state = {
|
|
524
|
+
request: this._state.request,
|
|
525
|
+
progress: this._state.progress,
|
|
526
|
+
result
|
|
527
|
+
};
|
|
528
|
+
this._resolveResult(result);
|
|
529
|
+
this._sendUpdate({
|
|
530
|
+
type: "finished" /* finished */,
|
|
531
|
+
finishType: "success" /* success */,
|
|
532
|
+
runningAction: this,
|
|
533
|
+
time: Date.now(),
|
|
534
|
+
response: result
|
|
535
|
+
});
|
|
536
|
+
return true;
|
|
537
|
+
}
|
|
538
|
+
_abort(reason) {
|
|
539
|
+
if (this._state.result != null || this._isAborted)
|
|
540
|
+
return false;
|
|
541
|
+
this._isAborted = true;
|
|
542
|
+
this._rejectResult(reason);
|
|
543
|
+
this._sendUpdate({
|
|
544
|
+
type: "finished" /* finished */,
|
|
545
|
+
finishType: "aborted" /* aborted */,
|
|
546
|
+
runningAction: this,
|
|
547
|
+
time: Date.now(),
|
|
548
|
+
reason
|
|
549
|
+
});
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
_failWithError(error) {
|
|
553
|
+
if (this._state.result != null || this._isAborted)
|
|
554
|
+
return false;
|
|
555
|
+
this._isAborted = true;
|
|
556
|
+
this._rejectResult(error);
|
|
557
|
+
this._sendUpdate({
|
|
558
|
+
type: "finished" /* finished */,
|
|
559
|
+
finishType: "failed" /* failed */,
|
|
560
|
+
runningAction: this,
|
|
561
|
+
time: Date.now(),
|
|
562
|
+
error
|
|
563
|
+
});
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
_updateProgress(progress) {
|
|
567
|
+
if (this._state.result != null || this._isAborted)
|
|
568
|
+
return;
|
|
569
|
+
this._state.progress.push(progress);
|
|
570
|
+
this._sendUpdate({
|
|
571
|
+
type: "progress" /* progress */,
|
|
572
|
+
runningAction: this,
|
|
573
|
+
time: Date.now(),
|
|
574
|
+
progress: progress.progress
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
waitForResultPayload() {
|
|
578
|
+
return this._resultPayloadPromise;
|
|
579
|
+
}
|
|
580
|
+
_resolveFromJson(resultJson) {
|
|
581
|
+
if (this._state.result != null || this._isAborted)
|
|
582
|
+
return false;
|
|
583
|
+
const result = this._domain.hydrateResultPayload(resultJson);
|
|
584
|
+
return this._completeWithResult(result);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
// src/ActionRuntime/Handler/Local/ActionLocalHandler.ts
|
|
588
|
+
import { castNiceError as castNiceError2, isNiceErrorObject, NiceError } from "@nice-code/error";
|
|
589
|
+
|
|
590
|
+
// src/errors/err_nice_action.ts
|
|
591
|
+
import { err, err_nice } from "@nice-code/error";
|
|
592
|
+
var EErrId_NiceAction;
|
|
593
|
+
((EErrId_NiceAction2) => {
|
|
594
|
+
EErrId_NiceAction2["not_implemented"] = "not_implemented";
|
|
595
|
+
EErrId_NiceAction2["action_id_not_in_domain"] = "action_id_not_in_domain";
|
|
596
|
+
EErrId_NiceAction2["domain_already_exists_in_hierarchy"] = "domain_already_exists_in_hierarchy";
|
|
597
|
+
EErrId_NiceAction2["domain_no_handler"] = "domain_no_handler";
|
|
598
|
+
EErrId_NiceAction2["hydration_domain_mismatch"] = "hydration_domain_mismatch";
|
|
599
|
+
EErrId_NiceAction2["hydration_action_state_mismatch"] = "hydration_action_state_mismatch";
|
|
600
|
+
EErrId_NiceAction2["hydration_action_id_not_found"] = "hydration_action_id_not_found";
|
|
601
|
+
EErrId_NiceAction2["no_action_execution_handler"] = "no_action_execution_handler";
|
|
602
|
+
EErrId_NiceAction2["wire_action_not_payload"] = "wire_action_not_payload";
|
|
603
|
+
EErrId_NiceAction2["wire_not_action_data"] = "wire_not_action_data";
|
|
604
|
+
EErrId_NiceAction2["client_runtime_already_registered"] = "client_runtime_already_registered";
|
|
605
|
+
EErrId_NiceAction2["client_runtime_not_registered"] = "client_runtime_not_registered";
|
|
606
|
+
EErrId_NiceAction2["runtime_reset"] = "runtime_reset";
|
|
607
|
+
EErrId_NiceAction2["no_client_runtimes_registered"] = "no_client_runtimes_registered";
|
|
608
|
+
EErrId_NiceAction2["action_input_validation_failed"] = "action_input_validation_failed";
|
|
609
|
+
EErrId_NiceAction2["action_input_validation_promise"] = "action_input_validation_promise";
|
|
610
|
+
EErrId_NiceAction2["action_output_validation_failed"] = "action_output_validation_failed";
|
|
611
|
+
EErrId_NiceAction2["action_output_validation_promise"] = "action_output_validation_promise";
|
|
612
|
+
})(EErrId_NiceAction ||= {});
|
|
613
|
+
var err_nice_action = err_nice.createChildDomain({
|
|
614
|
+
domain: "err_nice_action",
|
|
615
|
+
defaultHttpStatusCode: 500,
|
|
616
|
+
schema: {
|
|
617
|
+
["not_implemented" /* not_implemented */]: err({
|
|
618
|
+
message: ({ label }) => `The "${label}" functionality is not implemented yet.`
|
|
619
|
+
}),
|
|
620
|
+
["action_id_not_in_domain" /* action_id_not_in_domain */]: err({
|
|
621
|
+
message: ({ actionId, domain }) => `Action with id "${actionId}" does not exist in domain "${domain}".`
|
|
622
|
+
}),
|
|
623
|
+
["domain_already_exists_in_hierarchy" /* domain_already_exists_in_hierarchy */]: err({
|
|
624
|
+
message: ({ domain, allParentDomains, parentDomain }) => `Domain "${domain}" already exists in the hierarchy under the parent "${parentDomain}". All parent domains ["${allParentDomains.join(", ")}"]`
|
|
625
|
+
}),
|
|
626
|
+
["domain_no_handler" /* domain_no_handler */]: err({
|
|
627
|
+
message: ({ domain }) => `Domain "${domain}" has no action handler registered.`
|
|
628
|
+
}),
|
|
629
|
+
["hydration_domain_mismatch" /* hydration_domain_mismatch */]: err({
|
|
630
|
+
message: ({ expected, received }) => `Cannot hydrate action: domain mismatch. Expected "${expected}", got "${received}".`
|
|
631
|
+
}),
|
|
632
|
+
["hydration_action_state_mismatch" /* hydration_action_state_mismatch */]: err({
|
|
633
|
+
message: ({ expected, received }) => `Cannot hydrate action: action state type mismatch. Expected "${expected}", got "${received}".`
|
|
634
|
+
}),
|
|
635
|
+
["hydration_action_id_not_found" /* hydration_action_id_not_found */]: err({
|
|
636
|
+
message: ({ domain, actionId }) => `Cannot hydrate action: id "${actionId}" does not exist in domain "${domain}".`
|
|
637
|
+
}),
|
|
638
|
+
["no_action_execution_handler" /* no_action_execution_handler */]: err({
|
|
639
|
+
message: ({ domain, actionId, specifiedClient }) => `${specifiedClient ? ` The targeted client runtime [${specifiedClient.stringId}] has no` : "No"} action handler registered for "${actionId}" in domain "${domain}".`
|
|
640
|
+
}),
|
|
641
|
+
["wire_action_not_payload" /* wire_action_not_payload */]: err({
|
|
642
|
+
message: ({ domain, actionId, actionState }) => `Cannot handle wire for action "${actionId}" in domain "${domain}": expected action form of "${"data" /* data */}" and type of "${"request" /* request */}", "${"progress" /* progress */}" or "${"result" /* result */}", got "${actionState}".`
|
|
643
|
+
}),
|
|
644
|
+
["wire_not_action_data" /* wire_not_action_data */]: err({
|
|
645
|
+
message: () => `Cannot handle wire for action: expected an object with a "domain" property of type string, a "form" property of "${"data" /* data */}" and a "type" property of "${"request" /* request */}", "${"progress" /* progress */}" or "${"result" /* result */}".`
|
|
646
|
+
}),
|
|
647
|
+
["runtime_reset" /* runtime_reset */]: err({
|
|
648
|
+
message: () => `Runtime has been reset.`
|
|
649
|
+
}),
|
|
650
|
+
["client_runtime_already_registered" /* client_runtime_already_registered */]: err({
|
|
651
|
+
message: ({ context, client }) => `Environment is already registered${context?.domain ? ` on domain "${context.domain}"` : ""} for client [${client.stringId}]. Each client specifier (exact match on all properties) may only be registered once.`
|
|
652
|
+
}),
|
|
653
|
+
["client_runtime_not_registered" /* client_runtime_not_registered */]: err({
|
|
654
|
+
message: ({ context, clientStringId }) => `No runtime registered${context?.domain ? ` on domain "${context.domain}"` : ""} for client [${clientStringId}].`
|
|
655
|
+
}),
|
|
656
|
+
["no_client_runtimes_registered" /* no_client_runtimes_registered */]: err({
|
|
657
|
+
message: ({ context }) => `No runtimes registered${context?.domain ? ` on domain "${context.domain}"` : ""}. Add handlers to a runtime via runtime.addHandlers([handler]) before executing actions.`
|
|
658
|
+
}),
|
|
659
|
+
["action_input_validation_failed" /* action_input_validation_failed */]: err({
|
|
660
|
+
message: ({ domain, actionId, validationMessage }) => `Input validation failed for action "${actionId}" in domain "${domain}":
|
|
661
|
+
${validationMessage}`,
|
|
662
|
+
httpStatusCode: 400
|
|
663
|
+
}),
|
|
664
|
+
["action_input_validation_promise" /* action_input_validation_promise */]: err({
|
|
665
|
+
message: ({ domain, actionId }) => `Input validation for action "${actionId}" in domain "${domain}" returned a promise, which is not supported.`,
|
|
666
|
+
httpStatusCode: 400
|
|
667
|
+
}),
|
|
668
|
+
["action_output_validation_failed" /* action_output_validation_failed */]: err({
|
|
669
|
+
message: ({ domain, actionId, validationMessage }) => `Output validation failed for action "${actionId}" in domain "${domain}":
|
|
670
|
+
${validationMessage}`,
|
|
671
|
+
httpStatusCode: 500
|
|
672
|
+
}),
|
|
673
|
+
["action_output_validation_promise" /* action_output_validation_promise */]: err({
|
|
674
|
+
message: ({ domain, actionId }) => `Output validation for action "${actionId}" in domain "${domain}" returned a promise, which is not supported.`,
|
|
675
|
+
httpStatusCode: 500
|
|
676
|
+
})
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
// src/utils/isAction_Base_JsonObject.ts
|
|
681
|
+
var isAction_Base_JsonObject = (obj) => {
|
|
682
|
+
return typeof obj === "object" && obj !== null && typeof obj.domain === "string" && typeof obj.id === "string" && typeof obj.form === "string";
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
// src/utils/isActionPayload_Result_JsonObject.ts
|
|
686
|
+
var isActionPayload_Result_JsonObject = (obj) => {
|
|
687
|
+
return isAction_Base_JsonObject(obj) && obj.result != null && obj.form === "data" /* data */ && obj.type === "result" /* result */;
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
// src/ActionRuntime/ActionRuntime.ts
|
|
691
|
+
import { castNiceError } from "@nice-code/error";
|
|
692
|
+
import { nanoid as nanoid2 } from "nanoid";
|
|
693
|
+
|
|
694
|
+
// src/utils/getAssumedRuntimeEnvironment.ts
|
|
695
|
+
import { runtime } from "std-env";
|
|
696
|
+
var getAssumedRuntimeInfo = () => {
|
|
697
|
+
return {
|
|
698
|
+
assumed: true,
|
|
699
|
+
runtimeName: runtime
|
|
700
|
+
};
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
// src/utils/isActionPayload_Progress_JsonObject.ts
|
|
704
|
+
var isActionPayload_Progress_JsonObject = (obj) => {
|
|
705
|
+
return isAction_Base_JsonObject(obj) && "progress" in obj && obj.form === "data" /* data */ && obj.type === "progress" /* progress */;
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
// src/utils/isActionPayload_Request_JsonObject.ts
|
|
709
|
+
var isActionPayload_Request_JsonObject = (obj) => {
|
|
710
|
+
return isAction_Base_JsonObject(obj) && "input" in obj && obj.form === "data" /* data */ && obj.type === "request" /* request */;
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// src/utils/isActionPayload_Any_JsonObject.ts
|
|
714
|
+
function isActionPayload_Any_JsonObject(obj) {
|
|
715
|
+
return isActionPayload_Request_JsonObject(obj) || isActionPayload_Result_JsonObject(obj) || isActionPayload_Progress_JsonObject(obj);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// src/ActionRuntime/ActionDomainManager.ts
|
|
719
|
+
class ActionDomainManager {
|
|
720
|
+
_domains = new Map;
|
|
721
|
+
addDomain(domain) {
|
|
722
|
+
this._domains.set(domain.domain, domain);
|
|
723
|
+
}
|
|
724
|
+
getDomains() {
|
|
725
|
+
return [...this._domains.values()];
|
|
726
|
+
}
|
|
727
|
+
verifyIsActionJson(action) {
|
|
728
|
+
if (typeof action.domain !== "string" || typeof action.id !== "string") {
|
|
729
|
+
throw err_nice_action.fromId("wire_not_action_data" /* wire_not_action_data */);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
getActionDomain(action) {
|
|
733
|
+
this.verifyIsActionJson(action);
|
|
734
|
+
const domain = this._domains.get(action.domain);
|
|
735
|
+
if (!domain) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
return domain;
|
|
739
|
+
}
|
|
740
|
+
getActionDomainOrThrow(action) {
|
|
741
|
+
this.verifyIsActionJson(action);
|
|
742
|
+
const domain = this._domains.get(action.domain);
|
|
743
|
+
if (!domain) {
|
|
744
|
+
throw err_nice_action.fromId("domain_no_handler" /* domain_no_handler */, {
|
|
745
|
+
domain: action.domain
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
return domain;
|
|
749
|
+
}
|
|
750
|
+
hydrateActionPayload(actionJson) {
|
|
751
|
+
const domain = this.getActionDomainOrThrow(actionJson);
|
|
752
|
+
return domain.hydrateAnyAction(actionJson);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// src/ActionRuntime/Routing/ActionRouter.ts
|
|
757
|
+
class ActionRouter {
|
|
758
|
+
domainManager = new ActionDomainManager;
|
|
759
|
+
actionRouteData = new Map;
|
|
760
|
+
_context;
|
|
761
|
+
constructor(context) {
|
|
762
|
+
this._context = context;
|
|
763
|
+
}
|
|
764
|
+
mergeRouter(actionRouter) {
|
|
765
|
+
for (const domain of actionRouter.getDomains()) {
|
|
766
|
+
this.domainManager.addDomain(domain);
|
|
767
|
+
}
|
|
768
|
+
for (const [matchKey, routeDataEntries] of actionRouter.actionRouteData.entries()) {
|
|
769
|
+
this.actionRouteData.set(matchKey, [...routeDataEntries]);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
addDomainsFromOther(actionRouter) {
|
|
773
|
+
for (const domain of actionRouter.getDomains()) {
|
|
774
|
+
this.domainManager.addDomain(domain);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
getRouteDataEntriesForAction(action) {
|
|
778
|
+
const idKey = `dom[${action.domain}]id[${action.id}]`;
|
|
779
|
+
const domKey = `dom[${action.domain}]id[_]`;
|
|
780
|
+
return [
|
|
781
|
+
...this.actionRouteData.get(idKey) ?? [],
|
|
782
|
+
...this.actionRouteData.get(domKey) ?? []
|
|
783
|
+
];
|
|
784
|
+
}
|
|
785
|
+
getRouteDataForAction(action) {
|
|
786
|
+
return this.getRouteDataEntriesForAction(action)[0];
|
|
787
|
+
}
|
|
788
|
+
throwNoHandlerForAction(action, context) {
|
|
789
|
+
if (this._context.contextType === "handler_route" /* handler_route */) {
|
|
790
|
+
throw err_nice_action.fromId("no_action_execution_handler" /* no_action_execution_handler */, {
|
|
791
|
+
domain: action.domain,
|
|
792
|
+
actionId: action.id,
|
|
793
|
+
specifiedClient: context.targetLocalRuntime?.coordinate
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
if (this._context.contextType === "runtime_to_handler" /* runtime_to_handler */) {
|
|
797
|
+
throw err_nice_action.fromId("no_action_execution_handler" /* no_action_execution_handler */, {
|
|
798
|
+
domain: action.domain,
|
|
799
|
+
actionId: action.id,
|
|
800
|
+
specifiedClient: this._context.runtime.coordinate
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
throw err_nice_action.fromId("no_action_execution_handler" /* no_action_execution_handler */, {
|
|
804
|
+
domain: action.domain,
|
|
805
|
+
actionId: action.id
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
getRouteDataEntriesForActionOrThrow(action, context) {
|
|
809
|
+
const entries = this.getRouteDataEntriesForAction(action);
|
|
810
|
+
if (entries.length === 0) {
|
|
811
|
+
this.throwNoHandlerForAction(action, context);
|
|
812
|
+
}
|
|
813
|
+
return entries;
|
|
814
|
+
}
|
|
815
|
+
getRouteDataForActionOrThrow(action, context) {
|
|
816
|
+
const routeData = this.getRouteDataForAction(action);
|
|
817
|
+
if (!routeData) {
|
|
818
|
+
this.throwNoHandlerForAction(action, context);
|
|
819
|
+
}
|
|
820
|
+
return routeData;
|
|
821
|
+
}
|
|
822
|
+
getForKey(key) {
|
|
823
|
+
return this.actionRouteData.get(key) ?? [];
|
|
824
|
+
}
|
|
825
|
+
getRegisteredKeys() {
|
|
826
|
+
return [...this.actionRouteData.keys()];
|
|
827
|
+
}
|
|
828
|
+
getDomains() {
|
|
829
|
+
return this.domainManager.getDomains();
|
|
830
|
+
}
|
|
831
|
+
forDomain(domain, routeData) {
|
|
832
|
+
this.domainManager.addDomain(domain);
|
|
833
|
+
this.actionRouteData.set(`dom[${domain.domain}]id[_]`, [routeData]);
|
|
834
|
+
return this;
|
|
835
|
+
}
|
|
836
|
+
forAction(action, routeData) {
|
|
837
|
+
return this.forActionId(action._domain, action.id, routeData);
|
|
838
|
+
}
|
|
839
|
+
forActionId(domain, id, routeData) {
|
|
840
|
+
this.domainManager.addDomain(domain);
|
|
841
|
+
this.actionRouteData.set(`dom[${domain.domain}]id[${id}]`, [routeData]);
|
|
842
|
+
return this;
|
|
843
|
+
}
|
|
844
|
+
forActionIds(domain, ids, routeData) {
|
|
845
|
+
this.domainManager.addDomain(domain);
|
|
846
|
+
for (const id of ids) {
|
|
847
|
+
this.forActionId(domain, id, routeData);
|
|
848
|
+
}
|
|
849
|
+
return this;
|
|
850
|
+
}
|
|
851
|
+
forDomainActionCases(domain, cases) {
|
|
852
|
+
this.domainManager.addDomain(domain);
|
|
853
|
+
for (const id of Object.keys(cases)) {
|
|
854
|
+
const routeData = cases[id];
|
|
855
|
+
if (routeData != null) {
|
|
856
|
+
this.actionRouteData.set(`dom[${domain.domain}]id[${id}]`, [routeData]);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return this;
|
|
860
|
+
}
|
|
861
|
+
addForDomain(domain, routeData) {
|
|
862
|
+
this.domainManager.addDomain(domain);
|
|
863
|
+
this._push(`dom[${domain.domain}]id[_]`, routeData);
|
|
864
|
+
return this;
|
|
865
|
+
}
|
|
866
|
+
addForAction(domain, id, routeData) {
|
|
867
|
+
this.domainManager.addDomain(domain);
|
|
868
|
+
this._push(`dom[${domain.domain}]id[${id}]`, routeData);
|
|
869
|
+
return this;
|
|
870
|
+
}
|
|
871
|
+
addForActionIds(domain, ids, routeData) {
|
|
872
|
+
this.domainManager.addDomain(domain);
|
|
873
|
+
for (const id of ids) {
|
|
874
|
+
this.addForAction(domain, id, routeData);
|
|
875
|
+
}
|
|
876
|
+
return this;
|
|
877
|
+
}
|
|
878
|
+
addForDomainActionCases(domain, cases) {
|
|
879
|
+
this.domainManager.addDomain(domain);
|
|
880
|
+
for (const id of Object.keys(cases)) {
|
|
881
|
+
const routeData = cases[id];
|
|
882
|
+
if (routeData != null) {
|
|
883
|
+
this._push(`dom[${domain.domain}]id[${id}]`, routeData);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return this;
|
|
887
|
+
}
|
|
888
|
+
addForKey(key, routeData) {
|
|
889
|
+
this._push(key, routeData);
|
|
890
|
+
return this;
|
|
891
|
+
}
|
|
892
|
+
_push(key, routeData) {
|
|
893
|
+
const existing = this.actionRouteData.get(key);
|
|
894
|
+
if (existing != null) {
|
|
895
|
+
existing.push(routeData);
|
|
896
|
+
} else {
|
|
897
|
+
this.actionRouteData.set(key, [routeData]);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/ActionRuntime/ActionRuntime.ts
|
|
903
|
+
class ActionRuntime {
|
|
904
|
+
_coordinate;
|
|
905
|
+
timeCreated;
|
|
906
|
+
runtimeInfo = getAssumedRuntimeInfo();
|
|
907
|
+
actionRouter;
|
|
908
|
+
_pendingRunningActions = new Map;
|
|
909
|
+
_registeredExternalHandlers = [];
|
|
910
|
+
_applied = false;
|
|
911
|
+
static getDefault() {
|
|
912
|
+
return getDefaultActionRuntime();
|
|
913
|
+
}
|
|
914
|
+
constructor(coordinate) {
|
|
915
|
+
this._coordinate = coordinate.specifyIfUnset({
|
|
916
|
+
insId: nanoid2(14)
|
|
917
|
+
});
|
|
918
|
+
this.timeCreated = Date.now();
|
|
919
|
+
this.actionRouter = new ActionRouter({
|
|
920
|
+
contextType: "runtime_to_handler" /* runtime_to_handler */,
|
|
921
|
+
runtime: this
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
get coordinate() {
|
|
925
|
+
return this._coordinate;
|
|
926
|
+
}
|
|
927
|
+
specifyRuntimeCoordinate(specifics) {
|
|
928
|
+
if (specifics.envId != null && this._coordinate.envId !== specifics.envId) {
|
|
929
|
+
throw err_nice_action.fromId("not_implemented" /* not_implemented */, {
|
|
930
|
+
label: `updating RuntimeCoordinate with a different "envId" ("${this._coordinate.envId}" → "${specifics.envId}")`
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
this._coordinate = this._coordinate.specify(specifics);
|
|
934
|
+
this.apply();
|
|
935
|
+
}
|
|
936
|
+
registerRunningAction(ra) {
|
|
937
|
+
this._pendingRunningActions.set(ra.cuid, ra);
|
|
938
|
+
ra.addUpdateListeners([
|
|
939
|
+
(update) => {
|
|
940
|
+
if (update.type === "finished" /* finished */) {
|
|
941
|
+
this._pendingRunningActions.delete(ra.cuid);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
]);
|
|
945
|
+
}
|
|
946
|
+
resolveIncomingActionPayload(json) {
|
|
947
|
+
if (json.type === "request" /* request */) {
|
|
948
|
+
this.handleActionPayloadWire(json).catch((err2) => {
|
|
949
|
+
console.error(`[ActionRuntime] Incoming action [${json.domain}:${json.id}:${json.form}:${json.type}] unhandled:`, err2);
|
|
950
|
+
});
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
this._pendingRunningActions.get(json.context.cuid)?._resolveFromJson(json);
|
|
954
|
+
}
|
|
955
|
+
async handleActionPayloadWire(wire) {
|
|
956
|
+
let action;
|
|
957
|
+
if (isActionPayload_Any_JsonObject(wire)) {
|
|
958
|
+
const domain = this.actionRouter.domainManager.getActionDomainOrThrow(wire);
|
|
959
|
+
action = domain.hydrateAnyAction(wire);
|
|
960
|
+
}
|
|
961
|
+
if (action == null) {
|
|
962
|
+
throw err_nice_action.fromId("wire_not_action_data" /* wire_not_action_data */);
|
|
963
|
+
}
|
|
964
|
+
return this.handleActionPayload(action);
|
|
965
|
+
}
|
|
966
|
+
async handleActionPayload(action, options) {
|
|
967
|
+
if (action.type === "request" /* request */) {
|
|
968
|
+
let handlerForAction;
|
|
969
|
+
try {
|
|
970
|
+
handlerForAction = this.getHandlerForActionOrThrow(action, options);
|
|
971
|
+
} catch (err2) {
|
|
972
|
+
const runningAction2 = new RunningAction({
|
|
973
|
+
context: action.context,
|
|
974
|
+
request: action
|
|
975
|
+
});
|
|
976
|
+
runningAction2._completeWithResult(action.errorResult(castNiceError(err2)));
|
|
977
|
+
return runningAction2;
|
|
978
|
+
}
|
|
979
|
+
const runningAction = await handlerForAction.handleActionRequest(action, {
|
|
980
|
+
...options,
|
|
981
|
+
targetLocalRuntime: this
|
|
982
|
+
});
|
|
983
|
+
this._trySetupReturnDispatch(runningAction);
|
|
984
|
+
return runningAction;
|
|
985
|
+
}
|
|
986
|
+
throw err_nice_action.fromId("not_implemented" /* not_implemented */, {
|
|
987
|
+
label: `Handling incoming action payloads of type "${action.type}"`
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
_getHandlerForAction(action, options) {
|
|
991
|
+
const handlers = this.actionRouter.getRouteDataEntriesForAction(action);
|
|
992
|
+
const targetExternalClient = options?.targetExternalClient;
|
|
993
|
+
const possibleHandlers = handlers.filter((handler2) => {
|
|
994
|
+
if (handler2.handlerType === "external" /* external */) {
|
|
995
|
+
if (targetExternalClient && !targetExternalClient.isSameFor(handler2.externalClient).id) {
|
|
996
|
+
return false;
|
|
997
|
+
}
|
|
998
|
+
return true;
|
|
999
|
+
}
|
|
1000
|
+
if (targetExternalClient != null) {
|
|
1001
|
+
return false;
|
|
1002
|
+
}
|
|
1003
|
+
if (action.type === "request" /* request */) {
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
return false;
|
|
1007
|
+
});
|
|
1008
|
+
if (possibleHandlers.length === 0) {
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
const scoringExternalClient = targetExternalClient ?? RuntimeCoordinate.unknown;
|
|
1012
|
+
let handlerScore = -1;
|
|
1013
|
+
let handler;
|
|
1014
|
+
for (const possibleHandler of possibleHandlers) {
|
|
1015
|
+
if (possibleHandler.handlerType === "local" /* local */ && handler == null) {
|
|
1016
|
+
return possibleHandler;
|
|
1017
|
+
}
|
|
1018
|
+
if (possibleHandler.handlerType === "external" /* external */) {
|
|
1019
|
+
const score = scoringExternalClient.similarityLevel(possibleHandler.externalClient);
|
|
1020
|
+
if (score > handlerScore) {
|
|
1021
|
+
handlerScore = score;
|
|
1022
|
+
handler = possibleHandler;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
return handler;
|
|
1027
|
+
}
|
|
1028
|
+
getHandlerForActionOrThrow(action, options) {
|
|
1029
|
+
const handler = this._getHandlerForAction(action, options);
|
|
1030
|
+
if (handler == null) {
|
|
1031
|
+
throw err_nice_action.fromId("no_action_execution_handler" /* no_action_execution_handler */, {
|
|
1032
|
+
actionId: action.id,
|
|
1033
|
+
domain: action.domain,
|
|
1034
|
+
specifiedClient: options?.targetExternalClient
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
return handler;
|
|
1038
|
+
}
|
|
1039
|
+
addHandlers(handlers) {
|
|
1040
|
+
for (const handler of handlers) {
|
|
1041
|
+
if (handler.handlerType === "external" /* external */) {
|
|
1042
|
+
handler._setIncomingActionDataListener((json) => this.resolveIncomingActionPayload(json));
|
|
1043
|
+
this._registeredExternalHandlers.push(handler);
|
|
1044
|
+
}
|
|
1045
|
+
const handlerRouter = handler.getActionRouter();
|
|
1046
|
+
this.actionRouter.addDomainsFromOther(handlerRouter);
|
|
1047
|
+
if (this._applied) {
|
|
1048
|
+
this.apply();
|
|
1049
|
+
}
|
|
1050
|
+
for (const key of handlerRouter.getRegisteredKeys()) {
|
|
1051
|
+
const alreadyRegistered = this.actionRouter.getForKey(key).some((h) => h.cuid === handler.cuid);
|
|
1052
|
+
if (!alreadyRegistered) {
|
|
1053
|
+
this.actionRouter.addForKey(key, handler);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
return this;
|
|
1058
|
+
}
|
|
1059
|
+
applyRuntimeForDomain(domain) {
|
|
1060
|
+
const rootDomain = domain.rootDomain;
|
|
1061
|
+
if (!rootDomain._hasRuntime(this)) {
|
|
1062
|
+
rootDomain._registerRuntime(this);
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
apply() {
|
|
1066
|
+
this._applied = true;
|
|
1067
|
+
for (const domain of this.actionRouter.getDomains()) {
|
|
1068
|
+
this.applyRuntimeForDomain(domain);
|
|
1069
|
+
}
|
|
1070
|
+
return this;
|
|
1071
|
+
}
|
|
1072
|
+
getReturnHandlerForOrigin(originClient) {
|
|
1073
|
+
if (originClient.envId === UNSET_RUNTIME_ENV_ID)
|
|
1074
|
+
return;
|
|
1075
|
+
let bestScore = -1;
|
|
1076
|
+
let bestHandler;
|
|
1077
|
+
for (const handler of this._registeredExternalHandlers) {
|
|
1078
|
+
const score = originClient.similarityLevel(handler.externalClient);
|
|
1079
|
+
if (score > bestScore) {
|
|
1080
|
+
bestScore = score;
|
|
1081
|
+
bestHandler = handler;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
return bestScore > 0 ? bestHandler : undefined;
|
|
1085
|
+
}
|
|
1086
|
+
resetRuntime() {
|
|
1087
|
+
for (const ra of this._pendingRunningActions.values()) {
|
|
1088
|
+
ra._abort(err_nice_action.fromId("runtime_reset" /* runtime_reset */));
|
|
1089
|
+
}
|
|
1090
|
+
for (const handler of this._registeredExternalHandlers) {
|
|
1091
|
+
handler.clearTransportCache();
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
_trySetupReturnDispatch(runningAction) {
|
|
1095
|
+
const originClient = runningAction.context.originClient;
|
|
1096
|
+
if (originClient.envId === UNSET_RUNTIME_ENV_ID || originClient.isSameFor(this._coordinate).id) {
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
runningAction.addUpdateListeners([
|
|
1100
|
+
(update) => {
|
|
1101
|
+
if (update.type === "finished" /* finished */ && update.finishType === "success" /* success */) {
|
|
1102
|
+
const returnHandler = this.getReturnHandlerForOrigin(originClient);
|
|
1103
|
+
returnHandler?.sendReturnPayload(update.response, { targetLocalRuntime: this }).catch(() => {});
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
]);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
var runtimeState = {
|
|
1110
|
+
defaultLocalRuntime: undefined,
|
|
1111
|
+
assumedRuntimeInfo: undefined
|
|
1112
|
+
};
|
|
1113
|
+
function getDefaultActionRuntime() {
|
|
1114
|
+
if (runtimeState.assumedRuntimeInfo == null) {
|
|
1115
|
+
runtimeState.assumedRuntimeInfo = getAssumedRuntimeInfo();
|
|
1116
|
+
}
|
|
1117
|
+
if (runtimeState.defaultLocalRuntime == null) {
|
|
1118
|
+
runtimeState.defaultLocalRuntime = new ActionRuntime(RuntimeCoordinate.unknown.specify({
|
|
1119
|
+
perId: `${runtimeState.assumedRuntimeInfo?.runtimeName ?? "unknown"}-runtime`
|
|
1120
|
+
}));
|
|
1121
|
+
}
|
|
1122
|
+
return runtimeState.defaultLocalRuntime;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
// src/ActionRuntime/HandlerCallStack.ts
|
|
1126
|
+
var _stack = [];
|
|
1127
|
+
function pushHandlerCuid(cuid) {
|
|
1128
|
+
_stack.push(cuid);
|
|
1129
|
+
}
|
|
1130
|
+
function popHandlerCuid() {
|
|
1131
|
+
_stack.pop();
|
|
1132
|
+
}
|
|
1133
|
+
function peekHandlerCuid() {
|
|
1134
|
+
return _stack[_stack.length - 1];
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
// src/ActionRuntime/Handler/ActionHandler.ts
|
|
1138
|
+
import { nanoid as nanoid3 } from "nanoid";
|
|
1139
|
+
|
|
1140
|
+
class ActionHandler {
|
|
1141
|
+
cuid;
|
|
1142
|
+
constructor() {
|
|
1143
|
+
this.cuid = nanoid3();
|
|
1144
|
+
}
|
|
1145
|
+
getActionRouter() {
|
|
1146
|
+
return this.actionRouter;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// src/ActionRuntime/Handler/Local/ActionLocalHandler.ts
|
|
1151
|
+
class ActionLocalHandler extends ActionHandler {
|
|
1152
|
+
handlerType = "local" /* local */;
|
|
1153
|
+
actionRouter = new ActionRouter({
|
|
1154
|
+
contextType: "handler_route" /* handler_route */,
|
|
1155
|
+
handler: this
|
|
1156
|
+
});
|
|
1157
|
+
constructor() {
|
|
1158
|
+
super();
|
|
1159
|
+
}
|
|
1160
|
+
forDomain(domain, handler) {
|
|
1161
|
+
this.actionRouter.forDomain(domain, handler);
|
|
1162
|
+
return this;
|
|
1163
|
+
}
|
|
1164
|
+
forAction(action, handler) {
|
|
1165
|
+
this.actionRouter.forAction(action, handler);
|
|
1166
|
+
return this;
|
|
1167
|
+
}
|
|
1168
|
+
forActionIds(domain, ids, handler) {
|
|
1169
|
+
this.actionRouter.forActionIds(domain, ids, handler);
|
|
1170
|
+
return this;
|
|
1171
|
+
}
|
|
1172
|
+
forDomainActionCases(domain, cases) {
|
|
1173
|
+
this.actionRouter.forDomainActionCases(domain, cases);
|
|
1174
|
+
return this;
|
|
1175
|
+
}
|
|
1176
|
+
async handleActionRequest(action, config) {
|
|
1177
|
+
const targetLocalRuntime = config?.targetLocalRuntime ?? ActionRuntime.getDefault();
|
|
1178
|
+
const handler = this.actionRouter.getRouteDataForActionOrThrow(action, {
|
|
1179
|
+
targetLocalRuntime
|
|
1180
|
+
});
|
|
1181
|
+
action.context.addRouteItem({
|
|
1182
|
+
runtime: targetLocalRuntime.coordinate,
|
|
1183
|
+
handler: this.toHandlerRouteItem(),
|
|
1184
|
+
time: Date.now()
|
|
1185
|
+
});
|
|
1186
|
+
const runningAction = new RunningAction({
|
|
1187
|
+
context: action.context,
|
|
1188
|
+
request: action,
|
|
1189
|
+
parentCuid: peekHandlerCuid(),
|
|
1190
|
+
callSite: action._callSite ?? new Error().stack
|
|
1191
|
+
});
|
|
1192
|
+
this._handleRunningAction(handler, runningAction).catch((err2) => {
|
|
1193
|
+
if (err2 instanceof NiceError) {
|
|
1194
|
+
runningAction._completeWithResult(action.errorResult(err2));
|
|
1195
|
+
} else if (isNiceErrorObject(err2)) {
|
|
1196
|
+
runningAction._completeWithResult(action.errorResult(castNiceError2(err2)));
|
|
1197
|
+
} else {
|
|
1198
|
+
runningAction._abort(err2);
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
return runningAction;
|
|
1202
|
+
}
|
|
1203
|
+
async _handleRunningAction(handler, runningAction) {
|
|
1204
|
+
const state = runningAction.state;
|
|
1205
|
+
if (state.result != null) {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
await Promise.resolve();
|
|
1209
|
+
pushHandlerCuid(runningAction.cuid);
|
|
1210
|
+
try {
|
|
1211
|
+
const rawResult = await handler(state.request);
|
|
1212
|
+
let result;
|
|
1213
|
+
if (rawResult instanceof ActionPayload_Result) {
|
|
1214
|
+
result = rawResult;
|
|
1215
|
+
} else if (rawResult != null && isActionPayload_Result_JsonObject(rawResult)) {
|
|
1216
|
+
const domain = this.actionRouter.domainManager.getActionDomainOrThrow(state.request);
|
|
1217
|
+
result = domain.hydrateResultPayload(rawResult);
|
|
1218
|
+
} else {
|
|
1219
|
+
result = state.request.successResult(rawResult);
|
|
1220
|
+
}
|
|
1221
|
+
runningAction._completeWithResult(result);
|
|
1222
|
+
} finally {
|
|
1223
|
+
popHandlerCuid();
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
async handlePayloadWireOrThrow(wire, config) {
|
|
1227
|
+
const hydratedAction = this.actionRouter.domainManager.hydrateActionPayload(wire);
|
|
1228
|
+
if (!(hydratedAction instanceof ActionPayload_Request)) {
|
|
1229
|
+
throw err_nice_action.fromId("wire_action_not_payload" /* wire_action_not_payload */, {
|
|
1230
|
+
domain: hydratedAction.domain,
|
|
1231
|
+
actionId: hydratedAction.id,
|
|
1232
|
+
actionState: hydratedAction.type ?? hydratedAction.form
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
return await this.handleActionRequest(hydratedAction, config);
|
|
1236
|
+
}
|
|
1237
|
+
toJsonObject() {
|
|
1238
|
+
return {
|
|
1239
|
+
type: this.handlerType
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
toHandlerRouteItem() {
|
|
1243
|
+
return {
|
|
1244
|
+
type: this.handlerType
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
var createLocalHandler = () => {
|
|
1249
|
+
return new ActionLocalHandler;
|
|
1250
|
+
};
|
|
1251
|
+
|
|
1252
|
+
// src/utils/isAction_Context_JsonObject.ts
|
|
1253
|
+
var isAction_Context_JsonObject = (obj) => {
|
|
1254
|
+
return isAction_Base_JsonObject(obj) && obj.form === "context" /* context */;
|
|
1255
|
+
};
|
|
1256
|
+
|
|
1257
|
+
// src/utils/isAction_Core_JsonObject.ts
|
|
1258
|
+
var isAction_Core_JsonObject = (obj) => {
|
|
1259
|
+
return isAction_Base_JsonObject(obj) && obj.form === "core" /* core */;
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
// src/utils/isAction_Any_JsonObject.ts
|
|
1263
|
+
function isAction_Any_JsonObject(obj) {
|
|
1264
|
+
return isActionPayload_Any_JsonObject(obj) || isAction_Context_JsonObject(obj) || isAction_Core_JsonObject(obj);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// src/utils/assertIsActionJson.ts
|
|
1268
|
+
function assertIsActionJson(obj) {
|
|
1269
|
+
if (!isAction_Any_JsonObject(obj)) {
|
|
1270
|
+
throw err_nice_action.fromId("wire_not_action_data" /* wire_not_action_data */);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
// src/utils/isAction_Any_Instance.ts
|
|
1275
|
+
function isAction_Any_Instance(value) {
|
|
1276
|
+
return value instanceof ActionCore || value instanceof ActionPayload || value instanceof ActionContext;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
// src/ActionDefinition/Domain/ActionDomainBase.ts
|
|
1280
|
+
class ActionDomainBase {
|
|
1281
|
+
domain;
|
|
1282
|
+
allDomains;
|
|
1283
|
+
actionSchema;
|
|
1284
|
+
_listeners = [];
|
|
1285
|
+
constructor(definition) {
|
|
1286
|
+
this.domain = definition.domain;
|
|
1287
|
+
this.allDomains = definition.allDomains;
|
|
1288
|
+
this.actionSchema = definition.actionSchema;
|
|
1289
|
+
}
|
|
1290
|
+
addActionListener(listener) {
|
|
1291
|
+
this._listeners.push(listener);
|
|
1292
|
+
return () => {
|
|
1293
|
+
this._listeners = this._listeners.filter((l) => l !== listener);
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// src/ActionDefinition/Domain/ActionDomain.ts
|
|
1299
|
+
class ActionDomain extends ActionDomainBase {
|
|
1300
|
+
_rootDomain;
|
|
1301
|
+
_actionMap;
|
|
1302
|
+
constructor(definition, {
|
|
1303
|
+
rootDomain
|
|
1304
|
+
}) {
|
|
1305
|
+
super(definition);
|
|
1306
|
+
this._rootDomain = rootDomain;
|
|
1307
|
+
this._actionMap = this.createActionMap();
|
|
1308
|
+
}
|
|
1309
|
+
get rootDomain() {
|
|
1310
|
+
return this._rootDomain;
|
|
1311
|
+
}
|
|
1312
|
+
_registerRuntime(runtime2) {
|
|
1313
|
+
this._rootDomain._registerRuntime(runtime2);
|
|
1314
|
+
}
|
|
1315
|
+
createChildDomain(subDomainDef) {
|
|
1316
|
+
if (this.allDomains.includes(subDomainDef.domain)) {
|
|
1317
|
+
throw err_nice_action.fromId("domain_already_exists_in_hierarchy" /* domain_already_exists_in_hierarchy */, {
|
|
1318
|
+
domain: subDomainDef.domain,
|
|
1319
|
+
allParentDomains: this.allDomains,
|
|
1320
|
+
parentDomain: this.domain
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
return new ActionDomain({
|
|
1324
|
+
allDomains: [...this.allDomains, subDomainDef.domain],
|
|
1325
|
+
domain: subDomainDef.domain,
|
|
1326
|
+
actionSchema: subDomainDef.actions
|
|
1327
|
+
}, { rootDomain: this._rootDomain });
|
|
1328
|
+
}
|
|
1329
|
+
get action() {
|
|
1330
|
+
return this._actionMap;
|
|
1331
|
+
}
|
|
1332
|
+
actionsMap() {
|
|
1333
|
+
return this._actionMap;
|
|
1334
|
+
}
|
|
1335
|
+
actionForId(id) {
|
|
1336
|
+
const actionSchema = this.actionSchema[id];
|
|
1337
|
+
if (!actionSchema) {
|
|
1338
|
+
throw err_nice_action.fromId("action_id_not_in_domain" /* action_id_not_in_domain */, {
|
|
1339
|
+
domain: this.domain,
|
|
1340
|
+
actionId: id
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
return new ActionCore(this, id);
|
|
1344
|
+
}
|
|
1345
|
+
wrapAsPartialLocalHandler(wrappedActionExecutor) {
|
|
1346
|
+
const _handler = new ActionLocalHandler;
|
|
1347
|
+
const executor = wrappedActionExecutor;
|
|
1348
|
+
for (const actionKey in wrappedActionExecutor) {
|
|
1349
|
+
if (!this.actionSchema[actionKey]) {
|
|
1350
|
+
continue;
|
|
1351
|
+
}
|
|
1352
|
+
_handler.forAction(this.actionForId(actionKey), (request) => executor[request.id](request.input));
|
|
1353
|
+
}
|
|
1354
|
+
return _handler;
|
|
1355
|
+
}
|
|
1356
|
+
wrapAsLocalHandler(wrappedActionExecutor) {
|
|
1357
|
+
const _handler = new ActionLocalHandler;
|
|
1358
|
+
const executor = wrappedActionExecutor;
|
|
1359
|
+
return _handler.forDomain(this, (request) => executor[request.id](request.input));
|
|
1360
|
+
}
|
|
1361
|
+
hydrateContext(id, contextData) {
|
|
1362
|
+
return new ActionContext(this, id, {
|
|
1363
|
+
timeCreated: contextData.timeCreated,
|
|
1364
|
+
cuid: contextData.cuid,
|
|
1365
|
+
routing: contextData.routing.map((item) => {
|
|
1366
|
+
return {
|
|
1367
|
+
runtime: new RuntimeCoordinate(item.runtime),
|
|
1368
|
+
handler: item.handler,
|
|
1369
|
+
time: item.time
|
|
1370
|
+
};
|
|
1371
|
+
}),
|
|
1372
|
+
originClient: contextData.originClient ? new RuntimeCoordinate(contextData.originClient) : RuntimeCoordinate.unknown
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
isDomainAction(action) {
|
|
1376
|
+
return isAction_Any_Instance(action) && action.domain === this.domain;
|
|
1377
|
+
}
|
|
1378
|
+
hydrateRequestPayload(serialized) {
|
|
1379
|
+
if (serialized.type !== "request" /* request */) {
|
|
1380
|
+
throw err_nice_action.fromId("hydration_action_state_mismatch" /* hydration_action_state_mismatch */, {
|
|
1381
|
+
expected: "request" /* request */,
|
|
1382
|
+
received: serialized.type
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
if (serialized.domain !== this.domain) {
|
|
1386
|
+
throw err_nice_action.fromId("hydration_domain_mismatch" /* hydration_domain_mismatch */, {
|
|
1387
|
+
expected: this.domain,
|
|
1388
|
+
received: serialized.domain
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
const id = serialized.id;
|
|
1392
|
+
if (!this.actionSchema[id]) {
|
|
1393
|
+
throw err_nice_action.fromId("hydration_action_id_not_found" /* hydration_action_id_not_found */, {
|
|
1394
|
+
domain: this.domain,
|
|
1395
|
+
actionId: serialized.id
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
const contextAction = this.hydrateContext(id, serialized.context);
|
|
1399
|
+
return new ActionPayload_Request({ context: contextAction }, contextAction.deserializeInput(serialized.input), {
|
|
1400
|
+
time: serialized.time
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
hydrateResultPayload(serialized) {
|
|
1404
|
+
if (serialized.type !== "result" /* result */) {
|
|
1405
|
+
throw err_nice_action.fromId("hydration_action_state_mismatch" /* hydration_action_state_mismatch */, {
|
|
1406
|
+
expected: "result" /* result */,
|
|
1407
|
+
received: serialized.type
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
if (serialized.domain !== this.domain) {
|
|
1411
|
+
throw err_nice_action.fromId("hydration_domain_mismatch" /* hydration_domain_mismatch */, {
|
|
1412
|
+
expected: this.domain,
|
|
1413
|
+
received: serialized.domain
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
const id = serialized.id;
|
|
1417
|
+
if (!this.actionSchema[id]) {
|
|
1418
|
+
throw err_nice_action.fromId("hydration_action_id_not_found" /* hydration_action_id_not_found */, {
|
|
1419
|
+
domain: this.domain,
|
|
1420
|
+
actionId: serialized.id
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1423
|
+
const contextAction = this.hydrateContext(id, serialized.context);
|
|
1424
|
+
const result = serialized.result.ok ? {
|
|
1425
|
+
ok: true,
|
|
1426
|
+
output: contextAction.schema.deserializeOutput(serialized.result.output)
|
|
1427
|
+
} : serialized.result;
|
|
1428
|
+
return new ActionPayload_Result({ context: contextAction }, result, {
|
|
1429
|
+
time: serialized.time
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
hydrateAnyAction(actionJson) {
|
|
1433
|
+
assertIsActionJson(actionJson);
|
|
1434
|
+
if (actionJson.form === "data" /* data */) {
|
|
1435
|
+
if (actionJson.type === "request" /* request */) {
|
|
1436
|
+
return this.hydrateRequestPayload(actionJson);
|
|
1437
|
+
}
|
|
1438
|
+
if (actionJson.type === "result" /* result */) {
|
|
1439
|
+
return this.hydrateResultPayload(actionJson);
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
return this.actionForId(actionJson.id);
|
|
1443
|
+
}
|
|
1444
|
+
async runAction(request, options) {
|
|
1445
|
+
const allListeners = [
|
|
1446
|
+
...options?.listeners ?? [],
|
|
1447
|
+
...this._listeners
|
|
1448
|
+
];
|
|
1449
|
+
return this._rootDomain._runAction(request, {
|
|
1450
|
+
...options,
|
|
1451
|
+
listeners: allListeners
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
createActionMap() {
|
|
1455
|
+
const map = {};
|
|
1456
|
+
for (const id in this.actionSchema) {
|
|
1457
|
+
map[id] = new ActionCore(this, id);
|
|
1458
|
+
}
|
|
1459
|
+
return map;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
// src/ActionRuntime/ActionRuntimeManager.ts
|
|
1463
|
+
class ActionRuntimeManager {
|
|
1464
|
+
_runtimes = new Map;
|
|
1465
|
+
_preferredRuntimeClientId = null;
|
|
1466
|
+
_context;
|
|
1467
|
+
constructor(context) {
|
|
1468
|
+
this._context = context ?? {};
|
|
1469
|
+
}
|
|
1470
|
+
registerRuntime(runtime2) {
|
|
1471
|
+
const runtimeId = runtime2.coordinate.stringId;
|
|
1472
|
+
if (this._runtimes.has(runtimeId)) {
|
|
1473
|
+
throw err_nice_action.fromId("client_runtime_already_registered" /* client_runtime_already_registered */, {
|
|
1474
|
+
context: this._context,
|
|
1475
|
+
client: runtime2.coordinate
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
for (const id of runtime2.coordinate.toStringIds()) {
|
|
1479
|
+
if (this._runtimes.has(id)) {
|
|
1480
|
+
continue;
|
|
1481
|
+
}
|
|
1482
|
+
this._runtimes.set(id, runtime2);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
getRuntimeAndHandlerForAction(action, options, throwOnIssue) {
|
|
1486
|
+
const localRuntime = options?.targetLocalRuntime;
|
|
1487
|
+
if (localRuntime != null) {
|
|
1488
|
+
const runtime2 = throwOnIssue ? this.getBestRuntimeOrThrow(options?.targetLocalRuntime?.coordinate) : this.getBestRuntime(options?.targetLocalRuntime?.coordinate);
|
|
1489
|
+
if (runtime2 == null) {
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
const handler = runtime2._getHandlerForAction(action, options);
|
|
1493
|
+
if (handler != null) {
|
|
1494
|
+
return { handler, runtime: runtime2 };
|
|
1495
|
+
}
|
|
1496
|
+
if (throwOnIssue) {
|
|
1497
|
+
throw err_nice_action.fromId("no_action_execution_handler" /* no_action_execution_handler */, {
|
|
1498
|
+
domain: action.domain,
|
|
1499
|
+
actionId: action.id,
|
|
1500
|
+
specifiedClient: localRuntime.coordinate
|
|
25
1501
|
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
for (const runtime2 of this._runtimes.values()) {
|
|
1505
|
+
const handler = runtime2._getHandlerForAction(action);
|
|
1506
|
+
if (handler) {
|
|
1507
|
+
return { handler, runtime: runtime2 };
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
if (throwOnIssue) {
|
|
1511
|
+
throw err_nice_action.fromId("no_action_execution_handler" /* no_action_execution_handler */, {
|
|
1512
|
+
domain: action.domain,
|
|
1513
|
+
actionId: action.id,
|
|
1514
|
+
specifiedClient: options?.targetLocalRuntime?.coordinate
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
getRuntimeAndHandlerForActionOrThrow(action, options) {
|
|
1519
|
+
return this.getRuntimeAndHandlerForAction(action, options, true);
|
|
1520
|
+
}
|
|
1521
|
+
setPreferredRuntime(runtime2) {
|
|
1522
|
+
const runtimeId = runtime2.coordinate.stringId;
|
|
1523
|
+
this._preferredRuntimeClientId = runtimeId;
|
|
1524
|
+
}
|
|
1525
|
+
getPreferredRuntime() {
|
|
1526
|
+
if (this._preferredRuntimeClientId) {
|
|
1527
|
+
const runtime2 = this._runtimes.get(this._preferredRuntimeClientId);
|
|
1528
|
+
if (runtime2) {
|
|
1529
|
+
return runtime2;
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
return this._runtimes.values().next().value;
|
|
1533
|
+
}
|
|
1534
|
+
getBestRuntimeForSpecifier(clientSpecifier) {
|
|
1535
|
+
const actionClient = new RuntimeCoordinate(clientSpecifier);
|
|
1536
|
+
const ids = actionClient.toStringIds();
|
|
1537
|
+
for (const id of ids) {
|
|
1538
|
+
const runtime2 = this._runtimes.get(id);
|
|
1539
|
+
if (runtime2) {
|
|
1540
|
+
return runtime2;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
getBestRuntime(clientSpecifier) {
|
|
1545
|
+
return clientSpecifier != null ? this.getBestRuntimeForSpecifier(clientSpecifier) : this.getPreferredRuntime();
|
|
1546
|
+
}
|
|
1547
|
+
hasRuntime(runtime2) {
|
|
1548
|
+
return this._runtimes.has(runtime2.coordinate.stringId);
|
|
1549
|
+
}
|
|
1550
|
+
getBestRuntimeOrThrow(specifier) {
|
|
1551
|
+
const runtime2 = this.getBestRuntime(specifier);
|
|
1552
|
+
if (!runtime2) {
|
|
1553
|
+
if (specifier == null) {
|
|
1554
|
+
throw err_nice_action.fromId("no_client_runtimes_registered" /* no_client_runtimes_registered */, {
|
|
1555
|
+
context: this._context
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
throw err_nice_action.fromId("client_runtime_not_registered" /* client_runtime_not_registered */, {
|
|
1559
|
+
context: this._context,
|
|
1560
|
+
clientStringId: runtimeCoordinateToStringIds(specifier)[0]
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
return runtime2;
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
// src/ActionDefinition/Domain/ActionRootDomain.ts
|
|
1568
|
+
class ActionRootDomain extends ActionDomainBase {
|
|
1569
|
+
domainDefinition;
|
|
1570
|
+
_actionRuntimeManager;
|
|
1571
|
+
constructor(domainDefinition) {
|
|
1572
|
+
const domainId = domainDefinition.domain;
|
|
1573
|
+
super({
|
|
1574
|
+
domain: domainId,
|
|
1575
|
+
allDomains: [domainId],
|
|
1576
|
+
actionSchema: {}
|
|
1577
|
+
});
|
|
1578
|
+
this.domainDefinition = domainDefinition;
|
|
1579
|
+
this._actionRuntimeManager = new ActionRuntimeManager({ domain: domainId });
|
|
1580
|
+
}
|
|
1581
|
+
createChildDomain(subDomainDef) {
|
|
1582
|
+
if (this.allDomains.includes(subDomainDef.domain)) {
|
|
1583
|
+
throw err_nice_action.fromId("domain_already_exists_in_hierarchy" /* domain_already_exists_in_hierarchy */, {
|
|
1584
|
+
domain: subDomainDef.domain,
|
|
1585
|
+
allParentDomains: this.allDomains,
|
|
1586
|
+
parentDomain: this.domain
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
return new ActionDomain({
|
|
1590
|
+
allDomains: [...this.allDomains, subDomainDef.domain],
|
|
1591
|
+
domain: subDomainDef.domain,
|
|
1592
|
+
actionSchema: subDomainDef.actions
|
|
1593
|
+
}, { rootDomain: this });
|
|
1594
|
+
}
|
|
1595
|
+
_registerRuntime(runtime2) {
|
|
1596
|
+
this._actionRuntimeManager.registerRuntime(runtime2);
|
|
1597
|
+
}
|
|
1598
|
+
_hasRuntime(runtime2) {
|
|
1599
|
+
return this._actionRuntimeManager.hasRuntime(runtime2);
|
|
1600
|
+
}
|
|
1601
|
+
getRuntime(clientSpecifier) {
|
|
1602
|
+
return this._actionRuntimeManager.getBestRuntimeForSpecifier(clientSpecifier);
|
|
1603
|
+
}
|
|
1604
|
+
async _runAction(actionPayload, options) {
|
|
1605
|
+
const allListeners = [...this._listeners, ...options?.listeners ?? []];
|
|
1606
|
+
let handlerAndRuntime;
|
|
1607
|
+
try {
|
|
1608
|
+
handlerAndRuntime = this._actionRuntimeManager.getRuntimeAndHandlerForActionOrThrow(actionPayload, options);
|
|
1609
|
+
} catch (err2) {
|
|
1610
|
+
const runningAction2 = new RunningAction({
|
|
1611
|
+
context: actionPayload.context,
|
|
1612
|
+
request: actionPayload,
|
|
1613
|
+
callSite: actionPayload._callSite
|
|
1614
|
+
});
|
|
1615
|
+
runningAction2.addUpdateListeners(allListeners);
|
|
1616
|
+
runningAction2._failWithError(err2);
|
|
1617
|
+
throw err2;
|
|
1618
|
+
}
|
|
1619
|
+
const { handler, runtime: runtime2 } = handlerAndRuntime;
|
|
1620
|
+
actionPayload.context._setOriginClient(runtime2.coordinate);
|
|
1621
|
+
const runningAction = await handler.handleActionRequest(actionPayload, {
|
|
1622
|
+
targetLocalRuntime: runtime2
|
|
1623
|
+
});
|
|
1624
|
+
runningAction.addUpdateListeners(allListeners);
|
|
1625
|
+
return runningAction;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
// src/ActionDefinition/Domain/helpers/createRootActionDomain.ts
|
|
1629
|
+
var createActionRootDomain = (definition) => {
|
|
1630
|
+
return new ActionRootDomain(definition);
|
|
1631
|
+
};
|
|
1632
|
+
// src/ActionDefinition/Schema/ActionSchema.ts
|
|
1633
|
+
import { extractMessageFromStandardSchema } from "@nice-code/common-errors";
|
|
1634
|
+
class ActionSchema {
|
|
1635
|
+
_errorDeclarations = [];
|
|
1636
|
+
inputOptions;
|
|
1637
|
+
outputOptions;
|
|
1638
|
+
get inputSchema() {
|
|
1639
|
+
return this.inputOptions?.schema;
|
|
1640
|
+
}
|
|
1641
|
+
get outputSchema() {
|
|
1642
|
+
return this.outputOptions?.schema;
|
|
1643
|
+
}
|
|
1644
|
+
input(options) {
|
|
1645
|
+
this.inputOptions = options;
|
|
1646
|
+
return this;
|
|
1647
|
+
}
|
|
1648
|
+
output(options) {
|
|
1649
|
+
this.outputOptions = options;
|
|
1650
|
+
return this;
|
|
1651
|
+
}
|
|
1652
|
+
throws(domain, ids) {
|
|
1653
|
+
this._errorDeclarations.push({ _domain: domain, _ids: ids });
|
|
1654
|
+
return this;
|
|
1655
|
+
}
|
|
1656
|
+
serializeInput(rawInput) {
|
|
1657
|
+
if (this.inputOptions?.serialization) {
|
|
1658
|
+
return this.inputOptions.serialization.serialize(rawInput);
|
|
1659
|
+
}
|
|
1660
|
+
return rawInput;
|
|
1661
|
+
}
|
|
1662
|
+
deserializeInput(serialized) {
|
|
1663
|
+
if (this.inputOptions?.serialization) {
|
|
1664
|
+
return this.inputOptions.serialization.deserialize(serialized);
|
|
1665
|
+
}
|
|
1666
|
+
return serialized;
|
|
1667
|
+
}
|
|
1668
|
+
validateInput(value, meta) {
|
|
1669
|
+
if (this.inputOptions?.schema == null) {
|
|
1670
|
+
return value;
|
|
1671
|
+
}
|
|
1672
|
+
const result = this.inputOptions.schema["~standard"].validate(value);
|
|
1673
|
+
if (result instanceof Promise) {
|
|
1674
|
+
throw err_nice_action.fromId("action_input_validation_promise" /* action_input_validation_promise */, {
|
|
1675
|
+
domain: meta.domain,
|
|
1676
|
+
actionId: meta.actionId
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
if (result.issues != null) {
|
|
1680
|
+
throw err_nice_action.fromId("action_input_validation_failed" /* action_input_validation_failed */, {
|
|
1681
|
+
domain: meta.domain,
|
|
1682
|
+
actionId: meta.actionId,
|
|
1683
|
+
validationMessage: extractMessageFromStandardSchema(result)
|
|
1684
|
+
});
|
|
1685
|
+
}
|
|
1686
|
+
return result.value;
|
|
1687
|
+
}
|
|
1688
|
+
validateOutput(value, meta) {
|
|
1689
|
+
if (this.outputOptions?.schema == null) {
|
|
1690
|
+
return value;
|
|
1691
|
+
}
|
|
1692
|
+
const result = this.outputOptions.schema["~standard"].validate(value);
|
|
1693
|
+
if (result instanceof Promise) {
|
|
1694
|
+
throw err_nice_action.fromId("action_output_validation_promise" /* action_output_validation_promise */, {
|
|
1695
|
+
domain: meta.domain,
|
|
1696
|
+
actionId: meta.actionId
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
if (result.issues != null) {
|
|
1700
|
+
throw err_nice_action.fromId("action_output_validation_failed" /* action_output_validation_failed */, {
|
|
1701
|
+
domain: meta.domain,
|
|
1702
|
+
actionId: meta.actionId,
|
|
1703
|
+
validationMessage: extractMessageFromStandardSchema(result)
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
return result.value;
|
|
1707
|
+
}
|
|
1708
|
+
serializeOutput(rawOutput) {
|
|
1709
|
+
if (this.outputOptions?.serialization) {
|
|
1710
|
+
return this.outputOptions.serialization.serialize(rawOutput);
|
|
1711
|
+
}
|
|
1712
|
+
return rawOutput;
|
|
1713
|
+
}
|
|
1714
|
+
deserializeOutput(serialized) {
|
|
1715
|
+
if (this.outputOptions?.serialization) {
|
|
1716
|
+
return this.outputOptions.serialization.deserialize(serialized);
|
|
1717
|
+
}
|
|
1718
|
+
return serialized;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
var actionSchema = () => {
|
|
1722
|
+
return new ActionSchema;
|
|
1723
|
+
};
|
|
1724
|
+
// src/ActionRuntime/Handler/ExternalClient/ActionExternalClientHandler.ts
|
|
1725
|
+
import { nanoid as nanoid4 } from "nanoid";
|
|
1726
|
+
|
|
1727
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/err_nice_transport.ts
|
|
1728
|
+
import { err as err2 } from "@nice-code/error";
|
|
1729
|
+
|
|
1730
|
+
// src/ActionRuntime/Handler/ExternalClient/err_nice_external_client.ts
|
|
1731
|
+
var err_nice_external_client = err_nice_action.createChildDomain({
|
|
1732
|
+
domain: "err_nice_external_client",
|
|
1733
|
+
schema: {}
|
|
1734
|
+
});
|
|
1735
|
+
|
|
1736
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/err_nice_transport.ts
|
|
1737
|
+
var EErrId_NiceTransport;
|
|
1738
|
+
((EErrId_NiceTransport2) => {
|
|
1739
|
+
EErrId_NiceTransport2["timeout"] = "timeout";
|
|
1740
|
+
EErrId_NiceTransport2["not_found"] = "not_found";
|
|
1741
|
+
EErrId_NiceTransport2["unsupported"] = "unsupported";
|
|
1742
|
+
EErrId_NiceTransport2["initialization_failed"] = "initialization_failed";
|
|
1743
|
+
EErrId_NiceTransport2["send_failed"] = "send_failed";
|
|
1744
|
+
EErrId_NiceTransport2["invalid_action_response"] = "invalid_action_response";
|
|
1745
|
+
})(EErrId_NiceTransport ||= {});
|
|
1746
|
+
var err_nice_transport = err_nice_external_client.createChildDomain({
|
|
1747
|
+
domain: "err_nice_transport",
|
|
1748
|
+
schema: {
|
|
1749
|
+
["timeout" /* timeout */]: err2({
|
|
1750
|
+
message: ({ timeout }) => `ActionConnect transport timed out after ${timeout}ms.`
|
|
1751
|
+
}),
|
|
1752
|
+
["not_found" /* not_found */]: err2({
|
|
1753
|
+
message: ({ actionId }) => `No connected transport found for action "${actionId}".`
|
|
1754
|
+
}),
|
|
1755
|
+
["unsupported" /* unsupported */]: err2({
|
|
1756
|
+
message: ({ transportTypes }) => `${transportTypes.length} Transport(s) [${transportTypes.join(", ")}] found but returned "unsupported" status.`
|
|
1757
|
+
}),
|
|
1758
|
+
["initialization_failed" /* initialization_failed */]: err2({
|
|
1759
|
+
message: ({ actionId }) => `Transports found for action "${actionId}", but none are ready.`
|
|
1760
|
+
}),
|
|
1761
|
+
["send_failed" /* send_failed */]: err2({
|
|
1762
|
+
message: ({ actionId, httpStatusCode, message }) => `Failed to send action "${actionId}" [${httpStatusCode ?? "Unknown status"}]: ${message ?? "Unknown error"}.`,
|
|
1763
|
+
httpStatusCode: ({ httpStatusCode }) => httpStatusCode ?? 500
|
|
1764
|
+
}),
|
|
1765
|
+
["invalid_action_response" /* invalid_action_response */]: err2({
|
|
1766
|
+
message: ({ actionId }) => `Invalid action response JSON structure for action "${actionId}"`
|
|
1767
|
+
})
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1770
|
+
|
|
1771
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/Transport.types.ts
|
|
1772
|
+
var ETransportType;
|
|
1773
|
+
((ETransportType2) => {
|
|
1774
|
+
ETransportType2["ws"] = "ws";
|
|
1775
|
+
ETransportType2["http"] = "http";
|
|
1776
|
+
ETransportType2["custom"] = "custom";
|
|
1777
|
+
})(ETransportType ||= {});
|
|
1778
|
+
var ETransportStatus;
|
|
1779
|
+
((ETransportStatus2) => {
|
|
1780
|
+
ETransportStatus2["uninitialized"] = "uninitialized";
|
|
1781
|
+
ETransportStatus2["unsupported"] = "unsupported";
|
|
1782
|
+
ETransportStatus2["initializing"] = "initializing";
|
|
1783
|
+
ETransportStatus2["ready"] = "ready";
|
|
1784
|
+
ETransportStatus2["failed"] = "failed";
|
|
1785
|
+
})(ETransportStatus ||= {});
|
|
1786
|
+
|
|
1787
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/ConnectionTransportManager.ts
|
|
1788
|
+
class ConnectionTransportManager {
|
|
1789
|
+
_cache;
|
|
1790
|
+
_transports = [];
|
|
1791
|
+
constructor(_cache) {
|
|
1792
|
+
this._cache = _cache;
|
|
1793
|
+
}
|
|
1794
|
+
addTransport(transport) {
|
|
1795
|
+
this._transports.push(transport);
|
|
1796
|
+
}
|
|
1797
|
+
async getReadyTransport(routeActionParams) {
|
|
1798
|
+
const initializingWaiters = [];
|
|
1799
|
+
const unavailableTransports = [];
|
|
1800
|
+
const action = routeActionParams.action;
|
|
1801
|
+
for (const transport of this._transports) {
|
|
1802
|
+
const cacheKey = transport.getCacheKey(routeActionParams);
|
|
1803
|
+
if (cacheKey != null) {
|
|
1804
|
+
const cached = this._cache.get(cacheKey);
|
|
1805
|
+
if (cached != null) {
|
|
1806
|
+
if (cached instanceof Promise) {
|
|
1807
|
+
initializingWaiters.push(cached);
|
|
1808
|
+
continue;
|
|
1809
|
+
}
|
|
1810
|
+
return { ...cached, transport };
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
const statusInfo = transport.getTransport(routeActionParams);
|
|
1814
|
+
if (statusInfo.status === "ready" /* ready */) {
|
|
1815
|
+
const readyData = statusInfo.readyData;
|
|
1816
|
+
if (cacheKey != null) {
|
|
1817
|
+
this._cache.set(cacheKey, { methods: readyData, transport });
|
|
1818
|
+
readyData.addOnDisconnectListener?.(() => this._cache.delete(cacheKey));
|
|
1819
|
+
}
|
|
1820
|
+
return { methods: readyData, transport };
|
|
1821
|
+
}
|
|
1822
|
+
if (statusInfo.status === "unsupported" /* unsupported */) {
|
|
1823
|
+
unavailableTransports.push(transport);
|
|
1824
|
+
continue;
|
|
1825
|
+
}
|
|
1826
|
+
if (statusInfo.status === "initializing" /* initializing */) {
|
|
1827
|
+
const promise = statusInfo.initializationPromise.then((info) => {
|
|
1828
|
+
if (info.status === "failed" /* failed */) {
|
|
1829
|
+
throw info.error;
|
|
1830
|
+
}
|
|
1831
|
+
if (info.status === "unsupported" /* unsupported */) {
|
|
1832
|
+
throw err_nice_transport.fromId("unsupported" /* unsupported */, {
|
|
1833
|
+
transportTypes: [transport.type]
|
|
44
1834
|
});
|
|
45
1835
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
1836
|
+
const readyData = info.readyData;
|
|
1837
|
+
if (cacheKey != null) {
|
|
1838
|
+
this._cache.set(cacheKey, { methods: readyData, transport });
|
|
1839
|
+
readyData.addOnDisconnectListener?.(() => this._cache.delete(cacheKey));
|
|
1840
|
+
}
|
|
1841
|
+
return { methods: readyData, transport };
|
|
1842
|
+
}).catch((e) => {
|
|
1843
|
+
if (cacheKey != null)
|
|
1844
|
+
this._cache.delete(cacheKey);
|
|
1845
|
+
throw e;
|
|
1846
|
+
});
|
|
1847
|
+
if (cacheKey != null) {
|
|
1848
|
+
this._cache.set(cacheKey, promise);
|
|
56
1849
|
}
|
|
1850
|
+
initializingWaiters.push(promise);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
if (initializingWaiters.length === 0) {
|
|
1854
|
+
if (unavailableTransports.length > 0) {
|
|
1855
|
+
throw err_nice_transport.fromId("unsupported" /* unsupported */, {
|
|
1856
|
+
transportTypes: unavailableTransports.map((t) => t.type)
|
|
1857
|
+
});
|
|
57
1858
|
}
|
|
1859
|
+
throw err_nice_transport.fromId("not_found" /* not_found */, {
|
|
1860
|
+
actionId: action.id
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
try {
|
|
1864
|
+
return await Promise.any(initializingWaiters).then();
|
|
1865
|
+
} catch (e) {
|
|
1866
|
+
throw err_nice_transport.fromId("initialization_failed" /* initialization_failed */, {
|
|
1867
|
+
actionId: action.id
|
|
1868
|
+
}).withOriginError(e);
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
// src/ActionRuntime/Handler/ExternalClient/ActionExternalClientHandler.ts
|
|
1874
|
+
class ActionExternalClientHandler extends ActionHandler {
|
|
1875
|
+
externalClient;
|
|
1876
|
+
handlerType = "external" /* external */;
|
|
1877
|
+
cuid;
|
|
1878
|
+
_defaultTimeout;
|
|
1879
|
+
_transportCache = new Map;
|
|
1880
|
+
transportManager = new ConnectionTransportManager(this._transportCache);
|
|
1881
|
+
_incomingActionDataListeners = [];
|
|
1882
|
+
actionRouter = new ActionRouter({
|
|
1883
|
+
contextType: "handler_route" /* handler_route */,
|
|
1884
|
+
handler: this
|
|
1885
|
+
});
|
|
1886
|
+
constructor({
|
|
1887
|
+
runtimeCoordinate: externalClientSpecifier,
|
|
1888
|
+
transports,
|
|
1889
|
+
defaultTimeout
|
|
1890
|
+
}) {
|
|
1891
|
+
super();
|
|
1892
|
+
this.externalClient = externalClientSpecifier;
|
|
1893
|
+
this.cuid = nanoid4();
|
|
1894
|
+
this._defaultTimeout = defaultTimeout ?? DEFAULT_TRANSPORT_TIMEOUT;
|
|
1895
|
+
for (const transport of transports) {
|
|
1896
|
+
const connection = transport._createConnection({
|
|
1897
|
+
resolvers: {
|
|
1898
|
+
onIncomingActionDataJson: (json) => {
|
|
1899
|
+
for (const l of this._incomingActionDataListeners)
|
|
1900
|
+
l(json);
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1904
|
+
connection.definition = transport;
|
|
1905
|
+
this.transportManager.addTransport(connection);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
forDomain(domain) {
|
|
1909
|
+
this.actionRouter.forDomain(domain, true);
|
|
1910
|
+
return this;
|
|
1911
|
+
}
|
|
1912
|
+
forAction(action) {
|
|
1913
|
+
this.actionRouter.forAction(action, true);
|
|
1914
|
+
return this;
|
|
1915
|
+
}
|
|
1916
|
+
forActionIds(domain, ids) {
|
|
1917
|
+
this.actionRouter.forActionIds(domain, ids, true);
|
|
1918
|
+
return this;
|
|
1919
|
+
}
|
|
1920
|
+
_setIncomingActionDataListener(listener) {
|
|
1921
|
+
this._incomingActionDataListeners.push(listener);
|
|
1922
|
+
}
|
|
1923
|
+
async handleActionRequest(action, config) {
|
|
1924
|
+
const localRuntime = config?.targetLocalRuntime ?? ActionRuntime.getDefault();
|
|
1925
|
+
const localClient = localRuntime.coordinate;
|
|
1926
|
+
const incomingTimeout = config?.timeout ?? this._defaultTimeout;
|
|
1927
|
+
const parentCuid = peekHandlerCuid();
|
|
1928
|
+
const callSite = action._callSite ?? new Error().stack;
|
|
1929
|
+
const { methods, transport } = await this.transportManager.getReadyTransport({
|
|
1930
|
+
action,
|
|
1931
|
+
localClient,
|
|
1932
|
+
externalClient: this.externalClient
|
|
1933
|
+
});
|
|
1934
|
+
action.context.addRouteItem({
|
|
1935
|
+
runtime: localClient,
|
|
1936
|
+
handler: this.toHandlerRouteItem(transport, {
|
|
1937
|
+
action,
|
|
1938
|
+
localClient,
|
|
1939
|
+
externalClient: this.externalClient
|
|
1940
|
+
}),
|
|
1941
|
+
time: Date.now()
|
|
58
1942
|
});
|
|
1943
|
+
const runningAction = new RunningAction({
|
|
1944
|
+
context: action.context,
|
|
1945
|
+
request: action,
|
|
1946
|
+
parentCuid,
|
|
1947
|
+
callSite
|
|
1948
|
+
});
|
|
1949
|
+
localRuntime.registerRunningAction(runningAction);
|
|
1950
|
+
const routeActionParams = {
|
|
1951
|
+
action,
|
|
1952
|
+
runningAction,
|
|
1953
|
+
localClient,
|
|
1954
|
+
externalClient: this.externalClient,
|
|
1955
|
+
timeout: incomingTimeout
|
|
1956
|
+
};
|
|
1957
|
+
if (action.type === "request" /* request */ && methods.updateRunConfig != null) {
|
|
1958
|
+
const runConfig = methods.updateRunConfig(routeActionParams);
|
|
1959
|
+
routeActionParams.timeout = runConfig?.timeout ?? incomingTimeout;
|
|
1960
|
+
}
|
|
1961
|
+
try {
|
|
1962
|
+
methods.sendActionData(routeActionParams);
|
|
1963
|
+
} catch (err3) {
|
|
1964
|
+
runningAction._abort(err3);
|
|
1965
|
+
}
|
|
1966
|
+
return runningAction;
|
|
59
1967
|
}
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1968
|
+
async sendReturnPayload(payload, config) {
|
|
1969
|
+
const localClient = config.targetLocalRuntime.coordinate;
|
|
1970
|
+
try {
|
|
1971
|
+
const { methods } = await this.transportManager.getReadyTransport({
|
|
1972
|
+
action: payload,
|
|
1973
|
+
localClient,
|
|
1974
|
+
externalClient: this.externalClient
|
|
1975
|
+
});
|
|
1976
|
+
if (methods.sendReturnData == null)
|
|
1977
|
+
return false;
|
|
1978
|
+
methods.sendReturnData(payload);
|
|
1979
|
+
return true;
|
|
1980
|
+
} catch {
|
|
1981
|
+
return false;
|
|
65
1982
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1983
|
+
}
|
|
1984
|
+
toJsonObject() {
|
|
1985
|
+
return {
|
|
1986
|
+
type: this.handlerType,
|
|
1987
|
+
client: this.externalClient
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
toHandlerRouteItem(transport, input) {
|
|
1991
|
+
return {
|
|
1992
|
+
type: this.handlerType,
|
|
1993
|
+
client: this.externalClient,
|
|
1994
|
+
transOrd: transport.transOrd,
|
|
1995
|
+
transType: transport.type,
|
|
1996
|
+
transInfo: transport.getRouteInfo(input)
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
clearTransportCache() {
|
|
2000
|
+
this._transportCache.clear();
|
|
69
2001
|
}
|
|
70
2002
|
}
|
|
71
|
-
var
|
|
72
|
-
|
|
73
|
-
progress: "[nice-action] ",
|
|
74
|
-
success: "[nice-action] ✓",
|
|
75
|
-
failed: "[nice-action] ✗",
|
|
76
|
-
aborted: "[nice-action] ○"
|
|
2003
|
+
var createExternalClientHandler = (config) => {
|
|
2004
|
+
return new ActionExternalClientHandler(config);
|
|
77
2005
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return JSON.stringify(value);
|
|
90
|
-
} catch {
|
|
91
|
-
return String(value);
|
|
2006
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/Transport.ts
|
|
2007
|
+
class Transport {
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/helpers/addTransportStatusMetadata.ts
|
|
2011
|
+
function addTransportStatusMetadata(transportStatus) {
|
|
2012
|
+
if (transportStatus.status === "ready" /* ready */) {
|
|
2013
|
+
return {
|
|
2014
|
+
status: "ready" /* ready */,
|
|
2015
|
+
readyData: transportStatus.readyData
|
|
2016
|
+
};
|
|
92
2017
|
}
|
|
2018
|
+
if (transportStatus.status === "initializing" /* initializing */) {
|
|
2019
|
+
return {
|
|
2020
|
+
status: "initializing" /* initializing */,
|
|
2021
|
+
initializationPromise: transportStatus.initializationPromise,
|
|
2022
|
+
timeStarted: Date.now()
|
|
2023
|
+
};
|
|
2024
|
+
}
|
|
2025
|
+
if (transportStatus.status === "failed" /* failed */) {
|
|
2026
|
+
return {
|
|
2027
|
+
status: "failed" /* failed */,
|
|
2028
|
+
error: transportStatus.error,
|
|
2029
|
+
timeFailed: Date.now()
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
if (transportStatus.status === "unsupported" /* unsupported */) {
|
|
2033
|
+
return {
|
|
2034
|
+
status: "unsupported" /* unsupported */
|
|
2035
|
+
};
|
|
2036
|
+
}
|
|
2037
|
+
return {
|
|
2038
|
+
status: "uninitialized" /* uninitialized */
|
|
2039
|
+
};
|
|
93
2040
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
2041
|
+
|
|
2042
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/TransportConnection.ts
|
|
2043
|
+
var transportOrd = 0;
|
|
2044
|
+
|
|
2045
|
+
class TransportConnection {
|
|
2046
|
+
def;
|
|
2047
|
+
transOrd = transportOrd++;
|
|
2048
|
+
type;
|
|
2049
|
+
initialized;
|
|
2050
|
+
definition;
|
|
2051
|
+
constructor(def) {
|
|
2052
|
+
this.def = def;
|
|
2053
|
+
this.type = def.type;
|
|
2054
|
+
this.initialized = def.initialize();
|
|
2055
|
+
}
|
|
2056
|
+
getRouteInfo(input) {
|
|
2057
|
+
return this.definition?.getRouteInfo(input);
|
|
2058
|
+
}
|
|
2059
|
+
_getCacheKey(input) {
|
|
2060
|
+
const parts = this.initialized.getTransportCacheKey?.(input);
|
|
2061
|
+
if (parts == null)
|
|
2062
|
+
return null;
|
|
2063
|
+
return parts.join("\x00");
|
|
2064
|
+
}
|
|
2065
|
+
getCacheKey(input) {
|
|
2066
|
+
const inner = this._getCacheKey(input);
|
|
2067
|
+
if (inner == null)
|
|
2068
|
+
return null;
|
|
2069
|
+
return `${this.transOrd}:${inner}`;
|
|
2070
|
+
}
|
|
2071
|
+
getTransport(input) {
|
|
2072
|
+
return this._processTransportStatus(input);
|
|
2073
|
+
}
|
|
2074
|
+
_processTransportStatus(input) {
|
|
2075
|
+
const transportStatusInfo = addTransportStatusMetadata(this.initialized.getTransport(input));
|
|
2076
|
+
if (transportStatusInfo.status !== "initializing" /* initializing */ && transportStatusInfo.status !== "ready" /* ready */) {
|
|
2077
|
+
return transportStatusInfo;
|
|
104
2078
|
}
|
|
2079
|
+
if (transportStatusInfo.status === "initializing" /* initializing */) {
|
|
2080
|
+
const promiseForReadyData = transportStatusInfo.initializationPromise.then((result) => {
|
|
2081
|
+
if (result.status === "ready" /* ready */) {
|
|
2082
|
+
return {
|
|
2083
|
+
status: "ready" /* ready */,
|
|
2084
|
+
readyData: this._finalizeTransportMethods(result.readyData)
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
return result;
|
|
2088
|
+
});
|
|
2089
|
+
return {
|
|
2090
|
+
status: "initializing" /* initializing */,
|
|
2091
|
+
timeStarted: transportStatusInfo.timeStarted,
|
|
2092
|
+
initializationPromise: promiseForReadyData
|
|
2093
|
+
};
|
|
2094
|
+
}
|
|
2095
|
+
return {
|
|
2096
|
+
status: "ready" /* ready */,
|
|
2097
|
+
readyData: this._finalizeTransportMethods(transportStatusInfo.readyData)
|
|
2098
|
+
};
|
|
105
2099
|
}
|
|
106
|
-
return err;
|
|
107
2100
|
}
|
|
108
|
-
|
|
109
|
-
|
|
2101
|
+
|
|
2102
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/Custom/CustomConnection.ts
|
|
2103
|
+
class CustomConnection extends TransportConnection {
|
|
2104
|
+
constructor(def) {
|
|
2105
|
+
super({
|
|
2106
|
+
...def,
|
|
2107
|
+
type: "custom" /* custom */
|
|
2108
|
+
});
|
|
2109
|
+
}
|
|
2110
|
+
_finalizeTransportMethods(inputs) {
|
|
2111
|
+
return {
|
|
2112
|
+
sendActionData: inputs.sendActionData,
|
|
2113
|
+
sendReturnData: inputs.sendReturnData,
|
|
2114
|
+
updateRunConfig: inputs.updateRunConfig
|
|
2115
|
+
};
|
|
2116
|
+
}
|
|
110
2117
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
2118
|
+
|
|
2119
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/Custom/CustomTransport.ts
|
|
2120
|
+
class CustomTransport extends Transport {
|
|
2121
|
+
options;
|
|
2122
|
+
type = "custom" /* custom */;
|
|
2123
|
+
constructor(options) {
|
|
2124
|
+
super();
|
|
2125
|
+
this.options = options;
|
|
2126
|
+
}
|
|
2127
|
+
static create(options) {
|
|
2128
|
+
return new CustomTransport({ ...options, mode: "send" });
|
|
2129
|
+
}
|
|
2130
|
+
static createAdvanced(options) {
|
|
2131
|
+
return new CustomTransport({ ...options, mode: "advanced" });
|
|
2132
|
+
}
|
|
2133
|
+
_createConnection(_ctx) {
|
|
2134
|
+
const options = this.options;
|
|
2135
|
+
let getTransport;
|
|
2136
|
+
if (options.mode === "advanced") {
|
|
2137
|
+
getTransport = options.getTransport;
|
|
2138
|
+
} else {
|
|
2139
|
+
getTransport = () => ({
|
|
2140
|
+
status: "ready" /* ready */,
|
|
2141
|
+
readyData: {
|
|
2142
|
+
sendActionData: options.sendActionData,
|
|
2143
|
+
sendReturnData: options.sendReturnData,
|
|
2144
|
+
updateRunConfig: options.updateRunConfig,
|
|
2145
|
+
closeTransport: options.closeTransport ?? (() => {})
|
|
2146
|
+
}
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
return new CustomConnection({
|
|
2150
|
+
initialize: () => ({
|
|
2151
|
+
getTransportCacheKey: options.getTransportCacheKey,
|
|
2152
|
+
getTransport
|
|
2153
|
+
})
|
|
2154
|
+
});
|
|
2155
|
+
}
|
|
2156
|
+
getRouteInfo(input) {
|
|
2157
|
+
if (this.options.getRouteInfo != null)
|
|
2158
|
+
return this.options.getRouteInfo(input);
|
|
2159
|
+
return {
|
|
2160
|
+
type: "custom" /* custom */,
|
|
2161
|
+
summary: this.options.label ?? "custom"
|
|
2162
|
+
};
|
|
115
2163
|
}
|
|
116
|
-
return error;
|
|
117
2164
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
2165
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/err_nice_transport_ws.ts
|
|
2166
|
+
import { err as err3 } from "@nice-code/error";
|
|
2167
|
+
var EErrId_NiceTransport_WebSocket;
|
|
2168
|
+
((EErrId_NiceTransport_WebSocket2) => {
|
|
2169
|
+
EErrId_NiceTransport_WebSocket2["ws_disconnected"] = "ws_disconnected";
|
|
2170
|
+
EErrId_NiceTransport_WebSocket2["ws_create_failed"] = "ws_create_failed";
|
|
2171
|
+
EErrId_NiceTransport_WebSocket2["ws_error"] = "ws_error";
|
|
2172
|
+
})(EErrId_NiceTransport_WebSocket ||= {});
|
|
2173
|
+
var err_nice_transport_ws = err_nice_transport.createChildDomain({
|
|
2174
|
+
domain: "ws_transport",
|
|
2175
|
+
schema: {
|
|
2176
|
+
["ws_disconnected" /* ws_disconnected */]: err3({
|
|
2177
|
+
message: () => `WebSocket transport disconnected.`
|
|
2178
|
+
}),
|
|
2179
|
+
["ws_create_failed" /* ws_create_failed */]: err3({
|
|
2180
|
+
message: ({ originalError }) => `Failed to create WebSocket transport.${originalError ? ` Original error: ${originalError.message}` : ""}`
|
|
2181
|
+
}),
|
|
2182
|
+
["ws_error" /* ws_error */]: err3({
|
|
2183
|
+
message: ({ originalError }) => `WebSocket transport error.${originalError ? ` Original error: ${originalError.message}` : ""}`
|
|
2184
|
+
})
|
|
2185
|
+
}
|
|
2186
|
+
});
|
|
2187
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/Http/HttpConnection.ts
|
|
2188
|
+
import { castNiceError as castNiceError3, isNiceErrorObject as isNiceErrorObject2, NiceError as NiceError2 } from "@nice-code/error";
|
|
2189
|
+
class HttpConnection extends TransportConnection {
|
|
2190
|
+
constructor(def) {
|
|
2191
|
+
super({
|
|
2192
|
+
...def,
|
|
2193
|
+
type: "http" /* http */
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
_finalizeTransportMethods(methods) {
|
|
122
2197
|
return {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
insId: item.runtime?.insId
|
|
2198
|
+
sendActionData: (input) => {
|
|
2199
|
+
const request = methods.createRequest(input);
|
|
2200
|
+
this.send({ ...input, params: { request }, runningAction: input.runningAction }).catch((err4) => input.runningAction._abort(err4));
|
|
127
2201
|
},
|
|
128
|
-
|
|
129
|
-
handlerClient: isExternal && handler.client != null ? {
|
|
130
|
-
envId: handler.client.envId ?? "unknown",
|
|
131
|
-
perId: handler.client.perId,
|
|
132
|
-
insId: handler.client.insId
|
|
133
|
-
} : undefined,
|
|
134
|
-
transport: isExternal ? handler.transType : undefined,
|
|
135
|
-
transportSummary: isExternal ? handler.transInfo?.summary : undefined,
|
|
136
|
-
transportUrl: isExternal ? handler.transInfo?.url : undefined,
|
|
137
|
-
time: item.time
|
|
2202
|
+
updateRunConfig: methods.updateRunConfig
|
|
138
2203
|
};
|
|
139
|
-
}
|
|
2204
|
+
}
|
|
2205
|
+
async send(input) {
|
|
2206
|
+
const {
|
|
2207
|
+
action,
|
|
2208
|
+
runningAction,
|
|
2209
|
+
timeout,
|
|
2210
|
+
params: { request }
|
|
2211
|
+
} = input;
|
|
2212
|
+
const wire = action.toJsonObject();
|
|
2213
|
+
const ac = new AbortController;
|
|
2214
|
+
let timedOut = false;
|
|
2215
|
+
const timeoutId = setTimeout(() => {
|
|
2216
|
+
timedOut = true;
|
|
2217
|
+
ac.abort();
|
|
2218
|
+
}, timeout);
|
|
2219
|
+
const unsubscribe = input.runningAction.addUpdateListeners([
|
|
2220
|
+
(update) => {
|
|
2221
|
+
if (update.type === "finished" /* finished */) {
|
|
2222
|
+
clearTimeout(timeoutId);
|
|
2223
|
+
ac.abort();
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
]);
|
|
2227
|
+
try {
|
|
2228
|
+
const res = await fetch(request.url, {
|
|
2229
|
+
method: "POST",
|
|
2230
|
+
headers: { "Content-Type": "application/json", ...request.headers },
|
|
2231
|
+
body: request.body ?? JSON.stringify(wire),
|
|
2232
|
+
signal: ac.signal
|
|
2233
|
+
});
|
|
2234
|
+
if (!res.ok) {
|
|
2235
|
+
if (action.type === "request" /* request */) {
|
|
2236
|
+
try {
|
|
2237
|
+
const jsonData = await res.json();
|
|
2238
|
+
if (isActionPayload_Result_JsonObject(jsonData)) {
|
|
2239
|
+
runningAction._completeWithResult(action._domain.hydrateResultPayload(jsonData));
|
|
2240
|
+
} else if (isNiceErrorObject2(jsonData)) {
|
|
2241
|
+
runningAction._completeWithResult(action.errorResult(castNiceError3(jsonData)));
|
|
2242
|
+
} else {
|
|
2243
|
+
runningAction._completeWithResult(action.errorResult(err_nice_transport.fromId("invalid_action_response" /* invalid_action_response */, {
|
|
2244
|
+
actionId: action.id
|
|
2245
|
+
})));
|
|
2246
|
+
}
|
|
2247
|
+
} catch (e) {
|
|
2248
|
+
throw err_nice_transport.fromId("send_failed" /* send_failed */, {
|
|
2249
|
+
actionState: action.type,
|
|
2250
|
+
actionId: action.id,
|
|
2251
|
+
httpStatusCode: res.status,
|
|
2252
|
+
message: e.message
|
|
2253
|
+
}).withOriginError(e);
|
|
2254
|
+
}
|
|
2255
|
+
} else {
|
|
2256
|
+
let text;
|
|
2257
|
+
try {
|
|
2258
|
+
text = await res.text();
|
|
2259
|
+
} catch (e) {
|
|
2260
|
+
console.warn(`Failed to read error response body for failed HTTP request in HttpConnection:`, e);
|
|
2261
|
+
}
|
|
2262
|
+
throw err_nice_transport.fromId("send_failed" /* send_failed */, {
|
|
2263
|
+
actionState: action.type,
|
|
2264
|
+
actionId: action.id,
|
|
2265
|
+
httpStatusCode: res.status,
|
|
2266
|
+
message: text ?? `HTTP error with status ${res.status}`
|
|
2267
|
+
});
|
|
2268
|
+
}
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
2271
|
+
if (action.type === "request" /* request */) {
|
|
2272
|
+
const json = await res.json();
|
|
2273
|
+
if (!isActionPayload_Result_JsonObject(json)) {
|
|
2274
|
+
throw err_nice_transport.fromId("invalid_action_response" /* invalid_action_response */, {
|
|
2275
|
+
actionId: action.id
|
|
2276
|
+
});
|
|
2277
|
+
}
|
|
2278
|
+
runningAction._completeWithResult(action._domain.hydrateResultPayload(json));
|
|
2279
|
+
}
|
|
2280
|
+
} catch (err4) {
|
|
2281
|
+
if (timedOut) {
|
|
2282
|
+
throw err_nice_transport.fromId("timeout" /* timeout */, { timeout });
|
|
2283
|
+
}
|
|
2284
|
+
if (err4 instanceof NiceError2) {
|
|
2285
|
+
throw err4;
|
|
2286
|
+
}
|
|
2287
|
+
throw err_nice_transport.fromId("send_failed" /* send_failed */, {
|
|
2288
|
+
actionState: action.type,
|
|
2289
|
+
actionId: action.id,
|
|
2290
|
+
message: err4 instanceof Error ? err4.message : String(err4)
|
|
2291
|
+
}).withOriginError(err4 instanceof Error ? err4 : undefined);
|
|
2292
|
+
} finally {
|
|
2293
|
+
clearTimeout(timeoutId);
|
|
2294
|
+
unsubscribe();
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
140
2297
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
2298
|
+
|
|
2299
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/Http/HttpTransport.ts
|
|
2300
|
+
function shortPath(url) {
|
|
2301
|
+
try {
|
|
2302
|
+
return new URL(url).pathname || url;
|
|
2303
|
+
} catch {
|
|
2304
|
+
return url;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
class HttpTransport extends Transport {
|
|
2309
|
+
options;
|
|
2310
|
+
type = "http" /* http */;
|
|
2311
|
+
constructor(options) {
|
|
2312
|
+
super();
|
|
2313
|
+
this.options = options;
|
|
2314
|
+
}
|
|
2315
|
+
static create(options) {
|
|
2316
|
+
return new HttpTransport(options);
|
|
2317
|
+
}
|
|
2318
|
+
_createConnection(_ctx) {
|
|
2319
|
+
return new HttpConnection({
|
|
2320
|
+
initialize: () => ({
|
|
2321
|
+
getTransportCacheKey: this.options.getTransportCacheKey,
|
|
2322
|
+
getTransport: () => ({
|
|
2323
|
+
status: "ready" /* ready */,
|
|
2324
|
+
readyData: {
|
|
2325
|
+
createRequest: this.options.createRequest,
|
|
2326
|
+
updateRunConfig: this.options.updateRunConfig
|
|
2327
|
+
}
|
|
2328
|
+
})
|
|
2329
|
+
})
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2332
|
+
getRouteInfo(input) {
|
|
2333
|
+
const { url } = this.options.createRequest(input);
|
|
2334
|
+
return {
|
|
2335
|
+
type: "http" /* http */,
|
|
2336
|
+
method: "POST",
|
|
2337
|
+
url,
|
|
2338
|
+
summary: `POST ${shortPath(url)}`
|
|
2339
|
+
};
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/helpers/createUnsetTransportResolvers.ts
|
|
2343
|
+
var createUnsetTransportResolvers = (type) => ({
|
|
2344
|
+
onIncomingActionDataJson: (json) => {
|
|
2345
|
+
console.warn(`Received incoming action JSON [${json.domain}:${json.id}] on Transport [${type}] but no incoming data listener has been set.`);
|
|
2346
|
+
}
|
|
2347
|
+
});
|
|
2348
|
+
|
|
2349
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/ws_util.ts
|
|
2350
|
+
function shortWs(url) {
|
|
2351
|
+
try {
|
|
2352
|
+
const u = new URL(url);
|
|
2353
|
+
return `${u.host}${u.pathname}`;
|
|
2354
|
+
} catch {
|
|
2355
|
+
return url;
|
|
2356
|
+
}
|
|
151
2357
|
}
|
|
152
2358
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
2359
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/WebSocketConnection.ts
|
|
2360
|
+
class WebSocketConnection extends TransportConnection {
|
|
2361
|
+
resolvers;
|
|
2362
|
+
_abortSet = new Set;
|
|
2363
|
+
_liveSocketUrl;
|
|
2364
|
+
constructor(def, resolvers) {
|
|
2365
|
+
super({ ...def, type: "ws" /* ws */ });
|
|
2366
|
+
this.resolvers = resolvers ?? createUnsetTransportResolvers("ws" /* ws */);
|
|
2367
|
+
}
|
|
2368
|
+
_getCacheKey(_input) {
|
|
2369
|
+
return this.initialized.getTransportCacheKey?.(_input).join("\x00") ?? "";
|
|
2370
|
+
}
|
|
2371
|
+
_processTransportStatus(input) {
|
|
2372
|
+
const transportStatusInfo = addTransportStatusMetadata(this.initialized.getTransport(input));
|
|
2373
|
+
if (transportStatusInfo.status !== "initializing" /* initializing */ && transportStatusInfo.status !== "ready" /* ready */) {
|
|
2374
|
+
return transportStatusInfo;
|
|
2375
|
+
}
|
|
2376
|
+
if (transportStatusInfo.status === "ready" /* ready */) {
|
|
2377
|
+
const ws = transportStatusInfo.readyData.ws;
|
|
2378
|
+
if (ws.readyState !== WebSocket.OPEN) {
|
|
2379
|
+
const initialization = async () => {
|
|
2380
|
+
await new Promise((resolve, reject) => {
|
|
2381
|
+
ws.addEventListener("open", () => resolve(), { once: true });
|
|
2382
|
+
ws.addEventListener("error", (event) => reject(event), { once: true });
|
|
2383
|
+
ws.addEventListener("close", (event) => reject(new Error(`WebSocket closed before open: code=${event.code}`)), { once: true });
|
|
2384
|
+
});
|
|
2385
|
+
return {
|
|
2386
|
+
status: "ready" /* ready */,
|
|
2387
|
+
readyData: this._finalizeTransportMethods(transportStatusInfo.readyData)
|
|
2388
|
+
};
|
|
174
2389
|
};
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
2390
|
+
return {
|
|
2391
|
+
status: "initializing" /* initializing */,
|
|
2392
|
+
timeStarted: Date.now(),
|
|
2393
|
+
initializationPromise: initialization()
|
|
2394
|
+
};
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
if (transportStatusInfo.status === "initializing" /* initializing */) {
|
|
2398
|
+
const promiseForReadyData = transportStatusInfo.initializationPromise.then(async (result) => {
|
|
2399
|
+
if (result.status === "ready" /* ready */) {
|
|
2400
|
+
const ws = result.readyData.ws;
|
|
2401
|
+
await new Promise((resolve, reject) => {
|
|
2402
|
+
ws.addEventListener("open", () => resolve(), { once: true });
|
|
2403
|
+
ws.addEventListener("error", (event) => reject(event), { once: true });
|
|
2404
|
+
ws.addEventListener("close", (event) => reject(new Error(`WebSocket closed before open: code=${event.code}`)), { once: true });
|
|
2405
|
+
});
|
|
2406
|
+
return {
|
|
2407
|
+
status: "ready" /* ready */,
|
|
2408
|
+
readyData: this._finalizeTransportMethods(result.readyData)
|
|
189
2409
|
};
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
2410
|
+
}
|
|
2411
|
+
return result;
|
|
2412
|
+
});
|
|
2413
|
+
return {
|
|
2414
|
+
status: "initializing" /* initializing */,
|
|
2415
|
+
initializationPromise: promiseForReadyData,
|
|
2416
|
+
timeStarted: transportStatusInfo.timeStarted
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
return {
|
|
2420
|
+
status: "ready" /* ready */,
|
|
2421
|
+
readyData: this._finalizeTransportMethods(transportStatusInfo.readyData)
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2424
|
+
getRouteInfo(input) {
|
|
2425
|
+
const base = this.definition?.getRouteInfo(input);
|
|
2426
|
+
if (base?.url != null || this._liveSocketUrl == null)
|
|
2427
|
+
return base;
|
|
2428
|
+
return {
|
|
2429
|
+
type: "ws" /* ws */,
|
|
2430
|
+
...base,
|
|
2431
|
+
url: this._liveSocketUrl,
|
|
2432
|
+
summary: `ws ${shortWs(this._liveSocketUrl)}`
|
|
2433
|
+
};
|
|
2434
|
+
}
|
|
2435
|
+
_finalizeTransportMethods(wsData) {
|
|
2436
|
+
const ws = wsData.ws;
|
|
2437
|
+
const disconnectListeners = [];
|
|
2438
|
+
if (ws.url != null && ws.url !== "")
|
|
2439
|
+
this._liveSocketUrl = ws.url;
|
|
2440
|
+
const sendActionData = (inputs) => {
|
|
2441
|
+
const { action, runningAction, timeout } = inputs;
|
|
2442
|
+
if (action.type === "request" /* request */) {
|
|
2443
|
+
this._abortSet.add(runningAction);
|
|
2444
|
+
const timeoutId = setTimeout(() => {
|
|
2445
|
+
runningAction._abort(err_nice_transport.fromId("timeout" /* timeout */, { timeout }));
|
|
2446
|
+
}, timeout);
|
|
2447
|
+
runningAction.addUpdateListeners([
|
|
2448
|
+
(update) => {
|
|
2449
|
+
if (update.type === "finished" /* finished */) {
|
|
2450
|
+
clearTimeout(timeoutId);
|
|
2451
|
+
this._abortSet.delete(runningAction);
|
|
204
2452
|
}
|
|
205
|
-
return { ...base, status: "success", output: result?.output, outputHash };
|
|
206
2453
|
}
|
|
207
|
-
|
|
208
|
-
const rawError = update.error;
|
|
209
|
-
const errorStack2 = rawError instanceof Error ? rawError.stack : undefined;
|
|
210
|
-
return { ...base, status: "failed", error: serializeErrorForDisplay(rawError), errorStack: errorStack2 };
|
|
211
|
-
}
|
|
212
|
-
const abortReason = update.reason;
|
|
213
|
-
const errorStack = abortReason instanceof Error ? abortReason.stack : undefined;
|
|
214
|
-
return { ...base, status: "aborted", abortReason: serializeErrorForDisplay(abortReason), errorStack };
|
|
215
|
-
});
|
|
2454
|
+
]);
|
|
216
2455
|
}
|
|
2456
|
+
ws.send(wsData.formatMessage?.outgoing(inputs) ?? JSON.stringify(inputs.action.toJsonObject()));
|
|
2457
|
+
};
|
|
2458
|
+
ws.addEventListener("message", (event) => {
|
|
2459
|
+
if (typeof event.data === "string") {
|
|
2460
|
+
const rawJson = wsData.formatMessage?.incoming?.(event.data) ?? this._parseActionMessage(event.data);
|
|
2461
|
+
if (rawJson != null && isActionPayload_Any_JsonObject(rawJson)) {
|
|
2462
|
+
this.resolvers.onIncomingActionDataJson(rawJson);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
});
|
|
2466
|
+
ws.addEventListener("close", (event) => {
|
|
2467
|
+
console.error("WebSocket closed:", event);
|
|
2468
|
+
for (const cb of disconnectListeners)
|
|
2469
|
+
cb();
|
|
2470
|
+
this._abortAll(err_nice_transport_ws.fromId("ws_disconnected" /* ws_disconnected */));
|
|
217
2471
|
});
|
|
2472
|
+
ws.addEventListener("error", (event) => {
|
|
2473
|
+
console.error("WebSocket error:", event);
|
|
2474
|
+
for (const cb of disconnectListeners)
|
|
2475
|
+
cb();
|
|
2476
|
+
this._abortAll(err_nice_transport_ws.fromId("ws_error" /* ws_error */, {
|
|
2477
|
+
originalError: event instanceof Error ? event : undefined
|
|
2478
|
+
}));
|
|
2479
|
+
});
|
|
2480
|
+
return {
|
|
2481
|
+
sendActionData,
|
|
2482
|
+
updateRunConfig: wsData.updateRunConfig,
|
|
2483
|
+
addOnDisconnectListener: (cb) => {
|
|
2484
|
+
disconnectListeners.push(cb);
|
|
2485
|
+
},
|
|
2486
|
+
sendReturnData: (payload) => {
|
|
2487
|
+
ws.send(JSON.stringify(payload.toJsonObject()));
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
218
2490
|
}
|
|
219
|
-
|
|
220
|
-
|
|
2491
|
+
_parseActionMessage(message) {
|
|
2492
|
+
let json;
|
|
2493
|
+
try {
|
|
2494
|
+
json = JSON.parse(message);
|
|
2495
|
+
} catch {
|
|
2496
|
+
return;
|
|
2497
|
+
}
|
|
2498
|
+
return isActionPayload_Any_JsonObject(json) ? json : undefined;
|
|
221
2499
|
}
|
|
222
|
-
|
|
223
|
-
this.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
};
|
|
2500
|
+
_abortAll(error) {
|
|
2501
|
+
const snapshot = [...this._abortSet];
|
|
2502
|
+
for (const ra of snapshot) {
|
|
2503
|
+
ra._abort(error);
|
|
2504
|
+
}
|
|
228
2505
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
// src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/WebSocketTransport.ts
|
|
2509
|
+
class WebSocketTransport extends Transport {
|
|
2510
|
+
options;
|
|
2511
|
+
type = "ws" /* ws */;
|
|
2512
|
+
constructor(options) {
|
|
2513
|
+
super();
|
|
2514
|
+
this.options = options;
|
|
2515
|
+
}
|
|
2516
|
+
static create(options) {
|
|
2517
|
+
return new WebSocketTransport({ ...options, mode: "socket" });
|
|
2518
|
+
}
|
|
2519
|
+
static createAdvanced(options) {
|
|
2520
|
+
return new WebSocketTransport({ ...options, mode: "advanced" });
|
|
232
2521
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
2522
|
+
_createConnection(ctx) {
|
|
2523
|
+
const options = this.options;
|
|
2524
|
+
let getTransport;
|
|
2525
|
+
if (options.mode === "advanced") {
|
|
2526
|
+
getTransport = options.getTransport;
|
|
2527
|
+
} else {
|
|
2528
|
+
getTransport = (input) => ({
|
|
2529
|
+
status: "ready" /* ready */,
|
|
2530
|
+
readyData: {
|
|
2531
|
+
ws: options.createWebSocket(input),
|
|
2532
|
+
formatMessage: options.formatMessage,
|
|
2533
|
+
updateRunConfig: options.updateRunConfig
|
|
2534
|
+
}
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
return new WebSocketConnection({
|
|
2538
|
+
initialize: () => ({
|
|
2539
|
+
getTransportCacheKey: options.getTransportCacheKey,
|
|
2540
|
+
getTransport
|
|
2541
|
+
})
|
|
2542
|
+
}, ctx.resolvers);
|
|
236
2543
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
2544
|
+
getRouteInfo(input) {
|
|
2545
|
+
if (this.options.getRouteInfo != null)
|
|
2546
|
+
return this.options.getRouteInfo(input);
|
|
2547
|
+
return {
|
|
2548
|
+
type: "ws" /* ws */,
|
|
2549
|
+
summary: "ws"
|
|
2550
|
+
};
|
|
241
2551
|
}
|
|
242
2552
|
}
|
|
243
2553
|
export {
|
|
244
|
-
|
|
245
|
-
|
|
2554
|
+
isActionPayload_Result_JsonObject,
|
|
2555
|
+
isActionPayload_Request_JsonObject,
|
|
2556
|
+
isActionPayload_Any_JsonObject,
|
|
2557
|
+
err_nice_transport_ws,
|
|
2558
|
+
err_nice_transport,
|
|
2559
|
+
err_nice_external_client,
|
|
2560
|
+
err_nice_action,
|
|
2561
|
+
createLocalHandler,
|
|
2562
|
+
createExternalClientHandler,
|
|
2563
|
+
createActionRootDomain,
|
|
2564
|
+
actionSchema,
|
|
2565
|
+
WebSocketTransport,
|
|
2566
|
+
Transport,
|
|
2567
|
+
RuntimeCoordinate,
|
|
2568
|
+
RunningAction,
|
|
2569
|
+
HttpTransport,
|
|
2570
|
+
ETransportType,
|
|
2571
|
+
ETransportStatus,
|
|
2572
|
+
ERunningActionUpdateType,
|
|
2573
|
+
ERunningActionState,
|
|
2574
|
+
ERunningActionFinishedType,
|
|
2575
|
+
EErrId_NiceTransport_WebSocket,
|
|
2576
|
+
EErrId_NiceTransport,
|
|
2577
|
+
EErrId_NiceAction,
|
|
2578
|
+
EActionProgressType,
|
|
2579
|
+
EActionPayloadType,
|
|
2580
|
+
CustomTransport,
|
|
2581
|
+
ActionSchema,
|
|
2582
|
+
ActionRuntime,
|
|
2583
|
+
ActionRootDomain,
|
|
2584
|
+
ActionLocalHandler,
|
|
2585
|
+
ActionExternalClientHandler,
|
|
2586
|
+
ActionDomain,
|
|
2587
|
+
ActionCore
|
|
246
2588
|
};
|