@cadenza.io/service 2.15.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/dist/browser/index.js +8005 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/index.mjs +7978 -0
- package/dist/browser/index.mjs.map +1 -0
- package/dist/index.d.mts +196 -22
- package/dist/index.d.ts +196 -22
- package/dist/index.js +1489 -468
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1483 -464
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -38,7 +38,7 @@ var DeputyTask = class extends Task {
|
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
40
|
if (context.__metadata.__skipRemoteExecution) {
|
|
41
|
-
resolve(
|
|
41
|
+
resolve(context);
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
const processId = uuid();
|
|
@@ -141,6 +141,8 @@ var DeputyTask = class extends Task {
|
|
|
141
141
|
__executionTraceId: metadata.__executionTraceId ?? null,
|
|
142
142
|
__metadata: {
|
|
143
143
|
...metadata,
|
|
144
|
+
__skipRemoteExecution: metadata.__skipRemoteExecution ?? ctx.__skipRemoteExecution ?? false,
|
|
145
|
+
__blockRemoteExecution: metadata.__blockRemoteExecution ?? ctx.__blockRemoteExecution ?? false,
|
|
144
146
|
__deputyTaskName: this.name
|
|
145
147
|
},
|
|
146
148
|
...ctx
|
|
@@ -219,6 +221,7 @@ var DatabaseTask = class extends DeputyTask {
|
|
|
219
221
|
const dynamicQueryData = ctx.queryData ?? {};
|
|
220
222
|
delete ctx.queryData;
|
|
221
223
|
const deputyContext = {
|
|
224
|
+
...ctx,
|
|
222
225
|
__localTaskName: this.name,
|
|
223
226
|
__localTaskVersion: this.version,
|
|
224
227
|
__localServiceName: CadenzaService.serviceRegistry.serviceName,
|
|
@@ -229,6 +232,8 @@ var DatabaseTask = class extends DeputyTask {
|
|
|
229
232
|
__localRoutineExecId: metadata.__routineExecId ?? metadata.__metadata?.__routineExecId,
|
|
230
233
|
__metadata: {
|
|
231
234
|
...metadata,
|
|
235
|
+
__skipRemoteExecution: metadata.__skipRemoteExecution ?? ctx.__skipRemoteExecution ?? false,
|
|
236
|
+
__blockRemoteExecution: metadata.__blockRemoteExecution ?? ctx.__blockRemoteExecution ?? false,
|
|
232
237
|
__deputyTaskName: this.name
|
|
233
238
|
},
|
|
234
239
|
queryData: {
|
|
@@ -315,6 +320,167 @@ function summarizeResponderStatuses(statuses) {
|
|
|
315
320
|
return { responded, failed, timedOut, pending };
|
|
316
321
|
}
|
|
317
322
|
|
|
323
|
+
// src/utils/transport.ts
|
|
324
|
+
var DEFAULT_PROTOCOLS = ["rest", "socket"];
|
|
325
|
+
function normalizeString(value) {
|
|
326
|
+
return typeof value === "string" ? value.trim() : "";
|
|
327
|
+
}
|
|
328
|
+
function normalizeTransportProtocols(value) {
|
|
329
|
+
const rawValues = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
|
|
330
|
+
const normalized = rawValues.map((entry) => normalizeString(entry)).filter(
|
|
331
|
+
(entry) => entry === "rest" || entry === "socket"
|
|
332
|
+
);
|
|
333
|
+
return Array.from(new Set(normalized));
|
|
334
|
+
}
|
|
335
|
+
function normalizeTransportOrigin(origin) {
|
|
336
|
+
const raw = normalizeString(origin);
|
|
337
|
+
if (!raw) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
let parsed;
|
|
341
|
+
try {
|
|
342
|
+
parsed = new URL(raw);
|
|
343
|
+
} catch {
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
if (parsed.pathname && parsed.pathname !== "/") {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
if (parsed.search || parsed.hash) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
return parsed.origin;
|
|
356
|
+
}
|
|
357
|
+
function normalizeSecurityProfile(value) {
|
|
358
|
+
const normalized = normalizeString(value);
|
|
359
|
+
if (normalized === "low" || normalized === "medium" || normalized === "high") {
|
|
360
|
+
return normalized;
|
|
361
|
+
}
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
function normalizeServiceTransportConfig(value) {
|
|
365
|
+
const raw = value ?? {};
|
|
366
|
+
const role = normalizeString(raw.role);
|
|
367
|
+
const origin = normalizeTransportOrigin(raw.origin);
|
|
368
|
+
const protocols = normalizeTransportProtocols(raw.protocols);
|
|
369
|
+
if (!origin) {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
if (role !== "internal" && role !== "public") {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
role,
|
|
377
|
+
origin,
|
|
378
|
+
protocols: protocols.length > 0 ? protocols : [...DEFAULT_PROTOCOLS],
|
|
379
|
+
securityProfile: normalizeSecurityProfile(raw.securityProfile),
|
|
380
|
+
authStrategy: normalizeString(raw.authStrategy) || null
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function normalizeServiceTransportDescriptor(value) {
|
|
384
|
+
const raw = value ?? {};
|
|
385
|
+
const uuid5 = normalizeString(raw.uuid);
|
|
386
|
+
const serviceInstanceId = normalizeString(
|
|
387
|
+
raw.serviceInstanceId ?? raw.service_instance_id
|
|
388
|
+
);
|
|
389
|
+
const config = normalizeServiceTransportConfig(raw);
|
|
390
|
+
if (!uuid5 || !serviceInstanceId || !config) {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
uuid: uuid5,
|
|
395
|
+
serviceInstanceId,
|
|
396
|
+
role: config.role,
|
|
397
|
+
origin: config.origin,
|
|
398
|
+
protocols: config.protocols ?? [...DEFAULT_PROTOCOLS],
|
|
399
|
+
securityProfile: config.securityProfile ?? null,
|
|
400
|
+
authStrategy: config.authStrategy ?? null,
|
|
401
|
+
deleted: Boolean(raw.deleted),
|
|
402
|
+
clientCreated: Boolean(raw.clientCreated ?? raw.client_created ?? false)
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function transportSupportsProtocol(transport, protocol) {
|
|
406
|
+
return !!transport && transport.protocols.includes(protocol);
|
|
407
|
+
}
|
|
408
|
+
function selectTransportForRole(transports, role, protocol) {
|
|
409
|
+
const filtered = transports.filter(
|
|
410
|
+
(transport) => !transport.deleted && transport.role === role && (!protocol || transportSupportsProtocol(transport, protocol))
|
|
411
|
+
);
|
|
412
|
+
return filtered[0];
|
|
413
|
+
}
|
|
414
|
+
function buildTransportClientKey(transport) {
|
|
415
|
+
return transport.uuid;
|
|
416
|
+
}
|
|
417
|
+
function parseTransportOrigin(origin) {
|
|
418
|
+
const normalized = normalizeTransportOrigin(origin);
|
|
419
|
+
if (!normalized) {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
const parsed = new URL(normalized);
|
|
423
|
+
const protocol = parsed.protocol === "https:" ? "https" : "http";
|
|
424
|
+
const port = parsed.port ? Number(parsed.port) : protocol === "https" ? 443 : 80;
|
|
425
|
+
return {
|
|
426
|
+
protocol,
|
|
427
|
+
hostname: parsed.hostname,
|
|
428
|
+
port
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// src/utils/serviceInstance.ts
|
|
433
|
+
function normalizeString2(value) {
|
|
434
|
+
return typeof value === "string" ? value.trim() : "";
|
|
435
|
+
}
|
|
436
|
+
function normalizeTransportArray(value, serviceInstanceId) {
|
|
437
|
+
if (!Array.isArray(value)) {
|
|
438
|
+
return [];
|
|
439
|
+
}
|
|
440
|
+
return value.map(
|
|
441
|
+
(entry) => normalizeServiceTransportDescriptor({
|
|
442
|
+
...entry ?? {},
|
|
443
|
+
service_instance_id: entry?.service_instance_id ?? entry?.serviceInstanceId ?? serviceInstanceId
|
|
444
|
+
})
|
|
445
|
+
).filter((transport) => !!transport).sort((left, right) => left.origin.localeCompare(right.origin));
|
|
446
|
+
}
|
|
447
|
+
function normalizeServiceInstanceDescriptor(value) {
|
|
448
|
+
const raw = value ?? {};
|
|
449
|
+
const uuid5 = normalizeString2(raw.uuid);
|
|
450
|
+
const serviceName = normalizeString2(raw.serviceName ?? raw.service_name);
|
|
451
|
+
if (!uuid5 || !serviceName) {
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
const transports = normalizeTransportArray(raw.transports, uuid5);
|
|
455
|
+
return {
|
|
456
|
+
uuid: uuid5,
|
|
457
|
+
serviceName,
|
|
458
|
+
numberOfRunningGraphs: Math.max(
|
|
459
|
+
0,
|
|
460
|
+
Math.trunc(
|
|
461
|
+
Number(raw.numberOfRunningGraphs ?? raw.number_of_running_graphs ?? 0) || 0
|
|
462
|
+
)
|
|
463
|
+
),
|
|
464
|
+
isPrimary: Boolean(raw.isPrimary ?? raw.is_primary ?? false),
|
|
465
|
+
isActive: Boolean(raw.isActive ?? raw.is_active ?? true),
|
|
466
|
+
isNonResponsive: Boolean(
|
|
467
|
+
raw.isNonResponsive ?? raw.is_non_responsive ?? false
|
|
468
|
+
),
|
|
469
|
+
isBlocked: Boolean(raw.isBlocked ?? raw.is_blocked ?? false),
|
|
470
|
+
runtimeState: raw.runtimeState === "healthy" || raw.runtimeState === "degraded" || raw.runtimeState === "overloaded" || raw.runtimeState === "unavailable" ? raw.runtimeState : void 0,
|
|
471
|
+
acceptingWork: typeof raw.acceptingWork === "boolean" ? raw.acceptingWork : void 0,
|
|
472
|
+
reportedAt: typeof raw.reportedAt === "string" ? raw.reportedAt : typeof raw.reported_at === "string" ? raw.reported_at : void 0,
|
|
473
|
+
health: raw.health ?? {},
|
|
474
|
+
isFrontend: Boolean(raw.isFrontend ?? raw.is_frontend ?? false),
|
|
475
|
+
isDatabase: Boolean(raw.isDatabase ?? raw.is_database ?? false),
|
|
476
|
+
transports,
|
|
477
|
+
clientCreatedTransportIds: Array.isArray(raw.clientCreatedTransportIds) ? raw.clientCreatedTransportIds.map((entry) => normalizeString2(entry)).filter((entry) => entry.length > 0) : void 0
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
function getRouteableTransport(instance, role, protocol) {
|
|
481
|
+
return selectTransportForRole(instance.transports ?? [], role, protocol);
|
|
482
|
+
}
|
|
483
|
+
|
|
318
484
|
// src/utils/readiness.ts
|
|
319
485
|
function evaluateDependencyReadiness(input) {
|
|
320
486
|
const missedHeartbeats = Math.max(
|
|
@@ -561,6 +727,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
561
727
|
this.numberOfRunningGraphs = 0;
|
|
562
728
|
this.useSocket = false;
|
|
563
729
|
this.retryCount = 3;
|
|
730
|
+
this.isFrontend = false;
|
|
564
731
|
CadenzaService.defineIntent({
|
|
565
732
|
name: META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT,
|
|
566
733
|
description: "Gather transport diagnostics across all services and communication clients.",
|
|
@@ -708,57 +875,60 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
708
875
|
this.handleInstanceUpdateTask = CadenzaService.createMetaTask(
|
|
709
876
|
"Handle Instance Update",
|
|
710
877
|
(ctx, emit) => {
|
|
711
|
-
const serviceInstance =
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
if (!serviceInstance
|
|
878
|
+
const serviceInstance = normalizeServiceInstanceDescriptor(
|
|
879
|
+
ctx.serviceInstance ?? ctx.data ?? ctx.queryData?.data ?? (ctx.__serviceInstanceId || ctx.serviceInstanceId ? {
|
|
880
|
+
uuid: ctx.__serviceInstanceId ?? ctx.serviceInstanceId,
|
|
881
|
+
serviceName: ctx.__serviceName ?? ctx.serviceName,
|
|
882
|
+
isFrontend: !!ctx.isFrontend,
|
|
883
|
+
isActive: typeof ctx.isActive === "boolean" ? ctx.isActive : typeof ctx.__active === "boolean" ? ctx.__active : true,
|
|
884
|
+
isNonResponsive: !!ctx.isNonResponsive,
|
|
885
|
+
isBlocked: !!ctx.isBlocked,
|
|
886
|
+
health: ctx.health ?? ctx.__health ?? {},
|
|
887
|
+
numberOfRunningGraphs: ctx.numberOfRunningGraphs ?? ctx.__numberOfRunningGraphs ?? 0,
|
|
888
|
+
isPrimary: false,
|
|
889
|
+
transports: ctx.transports ?? []
|
|
890
|
+
} : void 0)
|
|
891
|
+
);
|
|
892
|
+
if (!serviceInstance) {
|
|
726
893
|
return false;
|
|
727
894
|
}
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
isFrontend,
|
|
735
|
-
deleted
|
|
736
|
-
} = serviceInstance;
|
|
737
|
-
if (uuid4 === this.serviceInstanceId) return;
|
|
895
|
+
const uuid5 = serviceInstance.uuid;
|
|
896
|
+
const serviceName = serviceInstance.serviceName;
|
|
897
|
+
const deleted = Boolean(
|
|
898
|
+
ctx.deleted ?? ctx.serviceInstance?.deleted ?? ctx.data?.deleted
|
|
899
|
+
);
|
|
900
|
+
if (uuid5 === this.serviceInstanceId) return;
|
|
738
901
|
if (deleted) {
|
|
739
|
-
const
|
|
740
|
-
|
|
902
|
+
const existingInstance = this.instances.get(serviceName)?.find((instance) => instance.uuid === uuid5);
|
|
903
|
+
const indexToDelete = this.instances.get(serviceName)?.findIndex((i) => i.uuid === uuid5) ?? -1;
|
|
904
|
+
if (indexToDelete >= 0 && existingInstance) {
|
|
741
905
|
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
906
|
+
for (const transport of existingInstance.transports) {
|
|
907
|
+
const transportKey = buildTransportClientKey(transport);
|
|
908
|
+
emit(`meta.socket_shutdown_requested:${transportKey}`, {});
|
|
909
|
+
emit(`meta.fetch.destroy_requested:${transportKey}`, {});
|
|
910
|
+
}
|
|
742
911
|
}
|
|
743
912
|
if (this.instances.get(serviceName)?.length === 0) {
|
|
744
913
|
this.instances.delete(serviceName);
|
|
745
|
-
} else if (this.instances.get(serviceName)?.filter((i) => i.address === address && i.port === port).length === 0) {
|
|
746
|
-
emit(`meta.socket_shutdown_requested:${address}_${port}`, {});
|
|
747
|
-
emit(`meta.fetch.destroy_requested:${address}_${port}`, {});
|
|
748
914
|
}
|
|
749
|
-
this.unregisterDependee(
|
|
915
|
+
this.unregisterDependee(uuid5, serviceName);
|
|
750
916
|
return;
|
|
751
917
|
}
|
|
752
918
|
if (!this.instances.has(serviceName))
|
|
753
919
|
this.instances.set(serviceName, []);
|
|
754
920
|
const instances = this.instances.get(serviceName);
|
|
755
|
-
const existing = instances.find((i) => i.uuid ===
|
|
921
|
+
const existing = instances.find((i) => i.uuid === uuid5);
|
|
756
922
|
if (existing) {
|
|
757
|
-
Object.assign(existing,
|
|
923
|
+
Object.assign(existing, {
|
|
924
|
+
...serviceInstance,
|
|
925
|
+
transports: serviceInstance.transports.length > 0 ? serviceInstance.transports : existing.transports,
|
|
926
|
+
clientCreatedTransportIds: existing.clientCreatedTransportIds ?? []
|
|
927
|
+
});
|
|
758
928
|
} else {
|
|
759
929
|
instances.push(serviceInstance);
|
|
760
930
|
}
|
|
761
|
-
const trackedInstance = existing ?? instances.find((instance) => instance.uuid ===
|
|
931
|
+
const trackedInstance = existing ?? instances.find((instance) => instance.uuid === uuid5);
|
|
762
932
|
if (trackedInstance) {
|
|
763
933
|
const snapshot = this.resolveRuntimeStatusSnapshot(
|
|
764
934
|
trackedInstance.numberOfRunningGraphs ?? 0,
|
|
@@ -773,31 +943,44 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
773
943
|
if (this.serviceName === serviceName) {
|
|
774
944
|
return false;
|
|
775
945
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
946
|
+
const trackedTransport = this.getRouteableTransport(
|
|
947
|
+
trackedInstance,
|
|
948
|
+
this.useSocket ? "socket" : "rest"
|
|
949
|
+
);
|
|
950
|
+
if (!serviceInstance.isFrontend && (this.deputies.has(serviceName) || this.remoteIntents.has(serviceName)) || this.remoteSignals.has(serviceName)) {
|
|
951
|
+
const communicationTypes = Array.from(
|
|
952
|
+
new Set(
|
|
953
|
+
this.deputies.get(serviceName)?.map((d) => d.communicationType) ?? []
|
|
954
|
+
)
|
|
779
955
|
);
|
|
780
|
-
if (!
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
956
|
+
if (!communicationTypes.includes("signal") && this.remoteSignals.has(serviceName)) {
|
|
957
|
+
communicationTypes.push("signal");
|
|
958
|
+
}
|
|
959
|
+
if (trackedTransport) {
|
|
960
|
+
const clientCreated = this.hasTransportClientCreated(
|
|
961
|
+
trackedInstance,
|
|
962
|
+
trackedTransport.uuid
|
|
785
963
|
);
|
|
786
|
-
if (!
|
|
787
|
-
|
|
964
|
+
if (!clientCreated) {
|
|
965
|
+
emit("meta.service_registry.dependee_registered", {
|
|
966
|
+
serviceName,
|
|
967
|
+
serviceInstanceId: uuid5,
|
|
968
|
+
serviceTransportId: trackedTransport.uuid,
|
|
969
|
+
serviceOrigin: trackedTransport.origin,
|
|
970
|
+
transportProtocols: trackedTransport.protocols,
|
|
971
|
+
communicationTypes
|
|
972
|
+
});
|
|
973
|
+
this.markTransportClientCreated(
|
|
974
|
+
trackedInstance,
|
|
975
|
+
trackedTransport.uuid
|
|
976
|
+
);
|
|
788
977
|
}
|
|
789
|
-
|
|
978
|
+
} else {
|
|
979
|
+
emit("meta.service_registry.routeable_transport_missing", {
|
|
790
980
|
serviceName,
|
|
791
|
-
serviceInstanceId:
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
protocol: exposed ? "https" : "http",
|
|
795
|
-
communicationTypes
|
|
796
|
-
});
|
|
797
|
-
instances?.filter(
|
|
798
|
-
(i) => i.address === address && i.port === port && i.isActive
|
|
799
|
-
).forEach((i) => {
|
|
800
|
-
i.clientCreated = true;
|
|
981
|
+
serviceInstanceId: uuid5,
|
|
982
|
+
requiredRole: this.getRoutingTransportRole(),
|
|
983
|
+
isFrontend: this.isFrontend
|
|
801
984
|
});
|
|
802
985
|
}
|
|
803
986
|
}
|
|
@@ -815,6 +998,81 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
815
998
|
"meta.socket_shutdown_requested",
|
|
816
999
|
"meta.fetch.destroy_requested"
|
|
817
1000
|
);
|
|
1001
|
+
this.handleTransportUpdateTask = CadenzaService.createMetaTask(
|
|
1002
|
+
"Handle Transport Update",
|
|
1003
|
+
(ctx, emit) => {
|
|
1004
|
+
const transport = normalizeServiceTransportDescriptor(
|
|
1005
|
+
ctx.serviceTransport ?? ctx.data ?? ctx.queryData?.data ?? ctx
|
|
1006
|
+
);
|
|
1007
|
+
if (!transport) {
|
|
1008
|
+
return false;
|
|
1009
|
+
}
|
|
1010
|
+
let ownerInstance;
|
|
1011
|
+
for (const instances of this.instances.values()) {
|
|
1012
|
+
ownerInstance = instances.find(
|
|
1013
|
+
(instance) => instance.uuid === transport.serviceInstanceId
|
|
1014
|
+
);
|
|
1015
|
+
if (ownerInstance) {
|
|
1016
|
+
break;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
if (!ownerInstance) {
|
|
1020
|
+
return false;
|
|
1021
|
+
}
|
|
1022
|
+
if (transport.deleted) {
|
|
1023
|
+
ownerInstance.transports = ownerInstance.transports.filter(
|
|
1024
|
+
(existingTransport2) => existingTransport2.uuid !== transport.uuid
|
|
1025
|
+
);
|
|
1026
|
+
const transportKey = buildTransportClientKey(transport);
|
|
1027
|
+
emit(`meta.socket_shutdown_requested:${transportKey}`, {});
|
|
1028
|
+
emit(`meta.fetch.destroy_requested:${transportKey}`, {});
|
|
1029
|
+
return true;
|
|
1030
|
+
}
|
|
1031
|
+
const existingTransport = this.getTransportById(ownerInstance, transport.uuid);
|
|
1032
|
+
if (existingTransport) {
|
|
1033
|
+
Object.assign(existingTransport, transport);
|
|
1034
|
+
} else {
|
|
1035
|
+
ownerInstance.transports.push(transport);
|
|
1036
|
+
}
|
|
1037
|
+
if (ownerInstance.uuid === this.serviceInstanceId) {
|
|
1038
|
+
return true;
|
|
1039
|
+
}
|
|
1040
|
+
const hasRemoteInterest = (!ownerInstance.isFrontend && (this.deputies.has(ownerInstance.serviceName) || this.remoteIntents.has(ownerInstance.serviceName)) || this.remoteSignals.has(ownerInstance.serviceName)) && transport.role === this.getRoutingTransportRole();
|
|
1041
|
+
if (!hasRemoteInterest) {
|
|
1042
|
+
return true;
|
|
1043
|
+
}
|
|
1044
|
+
if (!this.hasTransportClientCreated(ownerInstance, transport.uuid)) {
|
|
1045
|
+
const communicationTypes = Array.from(
|
|
1046
|
+
new Set(
|
|
1047
|
+
this.deputies.get(ownerInstance.serviceName)?.map((descriptor) => descriptor.communicationType) ?? []
|
|
1048
|
+
)
|
|
1049
|
+
);
|
|
1050
|
+
if (!communicationTypes.includes("signal") && this.remoteSignals.has(ownerInstance.serviceName)) {
|
|
1051
|
+
communicationTypes.push("signal");
|
|
1052
|
+
}
|
|
1053
|
+
emit("meta.service_registry.dependee_registered", {
|
|
1054
|
+
serviceName: ownerInstance.serviceName,
|
|
1055
|
+
serviceInstanceId: ownerInstance.uuid,
|
|
1056
|
+
serviceTransportId: transport.uuid,
|
|
1057
|
+
serviceOrigin: transport.origin,
|
|
1058
|
+
transportProtocols: transport.protocols,
|
|
1059
|
+
communicationTypes
|
|
1060
|
+
});
|
|
1061
|
+
this.markTransportClientCreated(ownerInstance, transport.uuid);
|
|
1062
|
+
}
|
|
1063
|
+
return true;
|
|
1064
|
+
},
|
|
1065
|
+
"Handles service transport updates independently from instance rows."
|
|
1066
|
+
).doOn(
|
|
1067
|
+
"global.meta.service_instance_transport.inserted",
|
|
1068
|
+
"global.meta.service_instance_transport.updated",
|
|
1069
|
+
"meta.service_instance_transport.inserted",
|
|
1070
|
+
"meta.service_instance_transport.updated"
|
|
1071
|
+
).attachSignal(
|
|
1072
|
+
"meta.service_registry.dependee_registered",
|
|
1073
|
+
"meta.socket_shutdown_requested",
|
|
1074
|
+
"meta.fetch.destroy_requested"
|
|
1075
|
+
);
|
|
818
1076
|
CadenzaService.createMetaTask(
|
|
819
1077
|
"Track dependee registration",
|
|
820
1078
|
(ctx) => {
|
|
@@ -910,17 +1168,25 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
910
1168
|
this.handleServiceNotRespondingTask = CadenzaService.createMetaTask(
|
|
911
1169
|
"Handle service not responding",
|
|
912
1170
|
(ctx, emit) => {
|
|
913
|
-
const { serviceName,
|
|
1171
|
+
const { serviceName, serviceInstanceId, serviceTransportId } = ctx;
|
|
914
1172
|
const serviceInstances = this.instances.get(serviceName);
|
|
915
|
-
const instances = serviceInstances?.filter(
|
|
916
|
-
(
|
|
917
|
-
|
|
1173
|
+
const instances = serviceInstances?.filter((instance) => {
|
|
1174
|
+
if (serviceInstanceId && instance.uuid === serviceInstanceId) {
|
|
1175
|
+
return true;
|
|
1176
|
+
}
|
|
1177
|
+
if (serviceTransportId) {
|
|
1178
|
+
return instance.transports.some(
|
|
1179
|
+
(transport) => transport.uuid === serviceTransportId
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
return false;
|
|
1183
|
+
});
|
|
918
1184
|
CadenzaService.log(
|
|
919
1185
|
"Service not responding.",
|
|
920
1186
|
{
|
|
921
1187
|
serviceName,
|
|
922
|
-
|
|
923
|
-
|
|
1188
|
+
serviceInstanceId,
|
|
1189
|
+
serviceTransportId,
|
|
924
1190
|
instances
|
|
925
1191
|
},
|
|
926
1192
|
"warning",
|
|
@@ -961,7 +1227,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
961
1227
|
this.handleServiceHandshakeTask = CadenzaService.createMetaTask(
|
|
962
1228
|
"Handle service handshake",
|
|
963
1229
|
(ctx, emit) => {
|
|
964
|
-
const { serviceName, serviceInstanceId
|
|
1230
|
+
const { serviceName, serviceInstanceId } = ctx;
|
|
965
1231
|
const serviceInstances = this.instances.get(serviceName);
|
|
966
1232
|
const instance = serviceInstances?.find(
|
|
967
1233
|
(i) => i.uuid === serviceInstanceId
|
|
@@ -989,26 +1255,6 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
989
1255
|
uuid: instance.uuid
|
|
990
1256
|
}
|
|
991
1257
|
});
|
|
992
|
-
const instancesToDelete = serviceInstances?.filter(
|
|
993
|
-
(i) => i.uuid !== serviceInstanceId && i.address === serviceAddress && i.port === servicePort
|
|
994
|
-
);
|
|
995
|
-
for (const i of instancesToDelete ?? []) {
|
|
996
|
-
const indexToDelete = this.instances.get(serviceName)?.indexOf(i) ?? -1;
|
|
997
|
-
if (indexToDelete >= 0) {
|
|
998
|
-
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
999
|
-
}
|
|
1000
|
-
this.unregisterDependee(i.uuid, serviceName);
|
|
1001
|
-
emit("global.meta.service_registry.deleted", {
|
|
1002
|
-
data: {
|
|
1003
|
-
isActive: false,
|
|
1004
|
-
isNonResponsive: false,
|
|
1005
|
-
deleted: true
|
|
1006
|
-
},
|
|
1007
|
-
filter: {
|
|
1008
|
-
uuid: i.uuid
|
|
1009
|
-
}
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1012
1258
|
return true;
|
|
1013
1259
|
},
|
|
1014
1260
|
"Handles service handshake"
|
|
@@ -1027,16 +1273,13 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1027
1273
|
return false;
|
|
1028
1274
|
}
|
|
1029
1275
|
let applied = this.applyRuntimeStatusReport(report);
|
|
1030
|
-
if (!applied && report.
|
|
1276
|
+
if (!applied && report.transportId && report.transportOrigin) {
|
|
1031
1277
|
if (!this.instances.has(report.serviceName)) {
|
|
1032
1278
|
this.instances.set(report.serviceName, []);
|
|
1033
1279
|
}
|
|
1034
1280
|
this.instances.get(report.serviceName).push({
|
|
1035
1281
|
uuid: report.serviceInstanceId,
|
|
1036
1282
|
serviceName: report.serviceName,
|
|
1037
|
-
address: report.serviceAddress,
|
|
1038
|
-
port: report.servicePort,
|
|
1039
|
-
exposed: !!report.exposed,
|
|
1040
1283
|
isFrontend: !!report.isFrontend,
|
|
1041
1284
|
isActive: report.isActive,
|
|
1042
1285
|
isNonResponsive: report.isNonResponsive,
|
|
@@ -1046,7 +1289,18 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1046
1289
|
acceptingWork: report.acceptingWork,
|
|
1047
1290
|
reportedAt: report.reportedAt,
|
|
1048
1291
|
health: report.health ?? {},
|
|
1049
|
-
isPrimary: false
|
|
1292
|
+
isPrimary: false,
|
|
1293
|
+
transports: [
|
|
1294
|
+
{
|
|
1295
|
+
uuid: report.transportId,
|
|
1296
|
+
serviceInstanceId: report.serviceInstanceId,
|
|
1297
|
+
role: this.getRoutingTransportRole(),
|
|
1298
|
+
origin: report.transportOrigin,
|
|
1299
|
+
protocols: report.transportProtocols && report.transportProtocols.length > 0 ? report.transportProtocols : ["rest", "socket"],
|
|
1300
|
+
securityProfile: null,
|
|
1301
|
+
authStrategy: null
|
|
1302
|
+
}
|
|
1303
|
+
]
|
|
1050
1304
|
});
|
|
1051
1305
|
applied = true;
|
|
1052
1306
|
}
|
|
@@ -1087,21 +1341,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1087
1341
|
deleted: !!m.deleted
|
|
1088
1342
|
})
|
|
1089
1343
|
);
|
|
1090
|
-
const serviceInstances = (inquiryResult.serviceInstances ?? []).filter(
|
|
1091
|
-
(instance) =>
|
|
1092
|
-
)
|
|
1093
|
-
uuid: instance.uuid,
|
|
1094
|
-
address: instance.address,
|
|
1095
|
-
port: instance.port,
|
|
1096
|
-
serviceName: instance.serviceName,
|
|
1097
|
-
isActive: !!instance.isActive,
|
|
1098
|
-
isNonResponsive: !!instance.isNonResponsive,
|
|
1099
|
-
isBlocked: !!instance.isBlocked,
|
|
1100
|
-
health: instance.health ?? {},
|
|
1101
|
-
exposed: !!instance.exposed,
|
|
1102
|
-
created: instance.created,
|
|
1103
|
-
isFrontend: !!instance.isFrontend
|
|
1104
|
-
}));
|
|
1344
|
+
const serviceInstances = (inquiryResult.serviceInstances ?? []).map((instance) => normalizeServiceInstanceDescriptor(instance)).filter(
|
|
1345
|
+
(instance) => !!instance && !!instance.isActive && !instance.isNonResponsive && !instance.isBlocked
|
|
1346
|
+
);
|
|
1105
1347
|
return {
|
|
1106
1348
|
...ctx,
|
|
1107
1349
|
signalToTaskMaps,
|
|
@@ -1188,7 +1430,19 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1188
1430
|
const { __serviceName, __triedInstances, __retries, __broadcast } = context;
|
|
1189
1431
|
let retries = __retries ?? 0;
|
|
1190
1432
|
let triedInstances = __triedInstances ?? [];
|
|
1191
|
-
const
|
|
1433
|
+
const preferredRole = this.getRoutingTransportRole();
|
|
1434
|
+
const instances = this.instances.get(__serviceName)?.filter((instance) => {
|
|
1435
|
+
if (!instance.isActive || instance.isNonResponsive || instance.isBlocked) {
|
|
1436
|
+
return false;
|
|
1437
|
+
}
|
|
1438
|
+
return Boolean(
|
|
1439
|
+
this.getRouteableTransport(
|
|
1440
|
+
instance,
|
|
1441
|
+
this.useSocket ? "socket" : "rest",
|
|
1442
|
+
preferredRole
|
|
1443
|
+
) ?? this.getRouteableTransport(instance, "rest", preferredRole)
|
|
1444
|
+
);
|
|
1445
|
+
}).sort((a, b) => {
|
|
1192
1446
|
const leftStatus = this.resolveRuntimeStatusSnapshot(
|
|
1193
1447
|
a.numberOfRunningGraphs ?? 0,
|
|
1194
1448
|
a.isActive,
|
|
@@ -1209,9 +1463,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1209
1463
|
});
|
|
1210
1464
|
if (!instances || instances.length === 0 || retries > this.retryCount) {
|
|
1211
1465
|
context.errored = true;
|
|
1212
|
-
context.__error = `No
|
|
1213
|
-
__serviceName
|
|
1214
|
-
)}`;
|
|
1466
|
+
context.__error = this.isFrontend && preferredRole === "public" ? `No public transport available for ${__serviceName}.` : `No routeable ${preferredRole} transport available for ${__serviceName}. Retries: ${retries}.`;
|
|
1215
1467
|
emit(
|
|
1216
1468
|
`meta.service_registry.load_balance_failed:${context.__metadata.__deputyExecId}`,
|
|
1217
1469
|
context
|
|
@@ -1220,10 +1472,21 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1220
1472
|
}
|
|
1221
1473
|
if (__broadcast || instances[0].isFrontend) {
|
|
1222
1474
|
for (const instance of instances) {
|
|
1223
|
-
const
|
|
1475
|
+
const selectedTransport2 = this.getRouteableTransport(instance, "socket", preferredRole) ?? this.getRouteableTransport(instance, "rest", preferredRole);
|
|
1476
|
+
if (!selectedTransport2) {
|
|
1477
|
+
continue;
|
|
1478
|
+
}
|
|
1479
|
+
const transportKey = buildTransportClientKey(selectedTransport2);
|
|
1224
1480
|
emit(
|
|
1225
|
-
|
|
1226
|
-
|
|
1481
|
+
`${this.useSocket && transportSupportsProtocol(selectedTransport2, "socket") ? "meta.service_registry.selected_instance_for_socket" : "meta.service_registry.selected_instance_for_fetch"}:${transportKey}`,
|
|
1482
|
+
{
|
|
1483
|
+
...context,
|
|
1484
|
+
__instance: instance.uuid,
|
|
1485
|
+
__transportId: selectedTransport2.uuid,
|
|
1486
|
+
__transportOrigin: selectedTransport2.origin,
|
|
1487
|
+
__transportProtocols: selectedTransport2.protocols,
|
|
1488
|
+
__fetchId: transportKey
|
|
1489
|
+
}
|
|
1227
1490
|
);
|
|
1228
1491
|
}
|
|
1229
1492
|
return context;
|
|
@@ -1246,12 +1509,25 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1246
1509
|
if (retries > 0) {
|
|
1247
1510
|
selected = instancesToTry[Math.floor(Math.random() * instancesToTry.length)];
|
|
1248
1511
|
}
|
|
1512
|
+
const selectedTransport = this.getRouteableTransport(selected, "socket", preferredRole) ?? this.getRouteableTransport(selected, "rest", preferredRole);
|
|
1513
|
+
if (!selectedTransport) {
|
|
1514
|
+
context.errored = true;
|
|
1515
|
+
context.__error = `No routeable ${preferredRole} transport available for ${selected.serviceName}/${selected.uuid}.`;
|
|
1516
|
+
emit(
|
|
1517
|
+
`meta.service_registry.load_balance_failed:${context.__metadata.__deputyExecId}`,
|
|
1518
|
+
context
|
|
1519
|
+
);
|
|
1520
|
+
return context;
|
|
1521
|
+
}
|
|
1249
1522
|
context.__instance = selected.uuid;
|
|
1250
|
-
context.
|
|
1523
|
+
context.__transportId = selectedTransport.uuid;
|
|
1524
|
+
context.__transportOrigin = selectedTransport.origin;
|
|
1525
|
+
context.__transportProtocols = selectedTransport.protocols;
|
|
1526
|
+
context.__fetchId = buildTransportClientKey(selectedTransport);
|
|
1251
1527
|
context.__triedInstances = triedInstances;
|
|
1252
1528
|
context.__triedInstances.push(selected.uuid);
|
|
1253
1529
|
context.__retries = retries;
|
|
1254
|
-
if (this.useSocket) {
|
|
1530
|
+
if (this.useSocket && transportSupportsProtocol(selectedTransport, "socket")) {
|
|
1255
1531
|
emit(
|
|
1256
1532
|
`meta.service_registry.selected_instance_for_socket:${context.__fetchId}`,
|
|
1257
1533
|
context
|
|
@@ -1443,9 +1719,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1443
1719
|
__active: report.isActive,
|
|
1444
1720
|
serviceName: report.serviceName,
|
|
1445
1721
|
serviceInstanceId: report.serviceInstanceId,
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1722
|
+
transportId: report.transportId,
|
|
1723
|
+
transportOrigin: report.transportOrigin,
|
|
1724
|
+
transportProtocols: report.transportProtocols,
|
|
1449
1725
|
isFrontend: report.isFrontend,
|
|
1450
1726
|
reportedAt: report.reportedAt,
|
|
1451
1727
|
numberOfRunningGraphs: report.numberOfRunningGraphs,
|
|
@@ -1488,12 +1764,17 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1488
1764
|
continue;
|
|
1489
1765
|
}
|
|
1490
1766
|
this.runtimeStatusFallbackInFlightByInstance.add(serviceInstanceId);
|
|
1767
|
+
const transport = this.getRouteableTransport(
|
|
1768
|
+
instance,
|
|
1769
|
+
this.useSocket ? "socket" : "rest"
|
|
1770
|
+
);
|
|
1491
1771
|
emit("meta.service_registry.runtime_status_fallback_requested", {
|
|
1492
1772
|
...ctx,
|
|
1493
1773
|
serviceName,
|
|
1494
1774
|
serviceInstanceId,
|
|
1495
|
-
|
|
1496
|
-
|
|
1775
|
+
serviceTransportId: transport?.uuid,
|
|
1776
|
+
serviceOrigin: transport?.origin,
|
|
1777
|
+
transportProtocols: transport?.protocols
|
|
1497
1778
|
});
|
|
1498
1779
|
}
|
|
1499
1780
|
}
|
|
@@ -1527,6 +1808,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1527
1808
|
};
|
|
1528
1809
|
} catch (error) {
|
|
1529
1810
|
const instance = this.getInstance(serviceName, serviceInstanceId);
|
|
1811
|
+
const transport = instance ? this.getRouteableTransport(
|
|
1812
|
+
instance,
|
|
1813
|
+
this.useSocket ? "socket" : "rest"
|
|
1814
|
+
) : void 0;
|
|
1530
1815
|
const message = error instanceof Error ? error.message : String(error);
|
|
1531
1816
|
CadenzaService.log(
|
|
1532
1817
|
"Runtime status fallback inquiry failed.",
|
|
@@ -1541,8 +1826,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1541
1826
|
...ctx,
|
|
1542
1827
|
serviceName,
|
|
1543
1828
|
serviceInstanceId,
|
|
1544
|
-
|
|
1545
|
-
|
|
1829
|
+
serviceTransportId: transport?.uuid ?? ctx.serviceTransportId,
|
|
1830
|
+
serviceOrigin: transport?.origin ?? ctx.serviceOrigin,
|
|
1831
|
+
transportProtocols: transport?.protocols ?? ctx.transportProtocols,
|
|
1546
1832
|
__error: message,
|
|
1547
1833
|
errored: true
|
|
1548
1834
|
});
|
|
@@ -1655,85 +1941,185 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1655
1941
|
inputSchema: {
|
|
1656
1942
|
type: "object",
|
|
1657
1943
|
properties: {
|
|
1658
|
-
|
|
1659
|
-
type: "
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1944
|
+
data: {
|
|
1945
|
+
type: "object",
|
|
1946
|
+
properties: {
|
|
1947
|
+
uuid: {
|
|
1948
|
+
type: "string"
|
|
1949
|
+
},
|
|
1950
|
+
process_pid: {
|
|
1951
|
+
type: "number"
|
|
1952
|
+
},
|
|
1953
|
+
is_primary: {
|
|
1954
|
+
type: "boolean"
|
|
1955
|
+
},
|
|
1956
|
+
service_name: {
|
|
1957
|
+
type: "string"
|
|
1958
|
+
},
|
|
1959
|
+
is_active: {
|
|
1960
|
+
type: "boolean"
|
|
1961
|
+
},
|
|
1962
|
+
is_frontend: {
|
|
1963
|
+
type: "boolean"
|
|
1964
|
+
},
|
|
1965
|
+
is_database: {
|
|
1966
|
+
type: "boolean"
|
|
1967
|
+
},
|
|
1968
|
+
is_non_responsive: {
|
|
1969
|
+
type: "boolean"
|
|
1970
|
+
},
|
|
1971
|
+
is_blocked: {
|
|
1972
|
+
type: "boolean"
|
|
1973
|
+
},
|
|
1974
|
+
health: {
|
|
1975
|
+
type: "object"
|
|
1976
|
+
}
|
|
1977
|
+
},
|
|
1978
|
+
required: ["uuid", "process_pid", "service_name"]
|
|
1687
1979
|
}
|
|
1688
1980
|
},
|
|
1689
|
-
required: [
|
|
1690
|
-
"id",
|
|
1691
|
-
"address",
|
|
1692
|
-
"port",
|
|
1693
|
-
"process_pid",
|
|
1694
|
-
"service_name",
|
|
1695
|
-
"exposed"
|
|
1696
|
-
]
|
|
1981
|
+
required: ["data"]
|
|
1697
1982
|
},
|
|
1698
|
-
// validateInputContext: true,
|
|
1699
1983
|
outputSchema: {
|
|
1700
1984
|
type: "object",
|
|
1701
1985
|
properties: {
|
|
1702
|
-
|
|
1986
|
+
uuid: {
|
|
1703
1987
|
type: "string"
|
|
1704
1988
|
}
|
|
1705
1989
|
},
|
|
1706
|
-
required: ["
|
|
1990
|
+
required: ["uuid"]
|
|
1707
1991
|
},
|
|
1708
|
-
// validateOutputContext: true,
|
|
1709
1992
|
retryCount: 5,
|
|
1710
1993
|
retryDelay: 1e3
|
|
1711
1994
|
}
|
|
1712
|
-
).doOn("
|
|
1995
|
+
).doOn("meta.service_registry.instance_registration_requested").then(
|
|
1713
1996
|
CadenzaService.createMetaTask(
|
|
1714
1997
|
"Setup service",
|
|
1715
1998
|
(ctx) => {
|
|
1716
|
-
const {
|
|
1717
|
-
|
|
1999
|
+
const {
|
|
2000
|
+
serviceInstance,
|
|
2001
|
+
data,
|
|
2002
|
+
queryData,
|
|
2003
|
+
__useSocket,
|
|
2004
|
+
__retryCount,
|
|
2005
|
+
__isFrontend
|
|
2006
|
+
} = ctx;
|
|
2007
|
+
const normalizedLocalInstance = normalizeServiceInstanceDescriptor({
|
|
2008
|
+
...serviceInstance ?? data ?? queryData?.data ?? {},
|
|
2009
|
+
transports: ctx.transportData ?? []
|
|
2010
|
+
});
|
|
2011
|
+
if (!normalizedLocalInstance?.uuid || !normalizedLocalInstance.serviceName) {
|
|
2012
|
+
return false;
|
|
2013
|
+
}
|
|
2014
|
+
this.serviceInstanceId = normalizedLocalInstance.uuid;
|
|
1718
2015
|
this.instances.set(
|
|
1719
|
-
|
|
1720
|
-
[{ ...
|
|
2016
|
+
normalizedLocalInstance.serviceName,
|
|
2017
|
+
[{ ...normalizedLocalInstance }]
|
|
1721
2018
|
);
|
|
1722
2019
|
this.useSocket = __useSocket;
|
|
1723
2020
|
this.retryCount = __retryCount;
|
|
2021
|
+
this.isFrontend = typeof __isFrontend === "boolean" ? __isFrontend : !!normalizedLocalInstance.isFrontend;
|
|
1724
2022
|
console.log("SETUP SERVICE", this.serviceInstanceId);
|
|
1725
2023
|
return true;
|
|
1726
2024
|
},
|
|
1727
2025
|
"Sets service instance id after insertion"
|
|
1728
|
-
).emits("meta.service_registry.instance_inserted")
|
|
2026
|
+
).emits("meta.service_registry.instance_inserted").then(
|
|
2027
|
+
CadenzaService.createMetaTask(
|
|
2028
|
+
"Prepare service transport inserts",
|
|
2029
|
+
function* (ctx, emit) {
|
|
2030
|
+
const transportData = Array.isArray(ctx.transportData) ? ctx.transportData : [];
|
|
2031
|
+
for (const transport of transportData) {
|
|
2032
|
+
const transportContext = {
|
|
2033
|
+
...ctx,
|
|
2034
|
+
data: {
|
|
2035
|
+
...transport,
|
|
2036
|
+
service_instance_id: transport.service_instance_id ?? ctx.__serviceInstanceId
|
|
2037
|
+
}
|
|
2038
|
+
};
|
|
2039
|
+
emit(
|
|
2040
|
+
"meta.service_registry.transport_registration_requested",
|
|
2041
|
+
transportContext
|
|
2042
|
+
);
|
|
2043
|
+
yield transportContext;
|
|
2044
|
+
}
|
|
2045
|
+
},
|
|
2046
|
+
"Splits declared service transports into individual insert payloads."
|
|
2047
|
+
).attachSignal("meta.service_registry.transport_registration_requested")
|
|
2048
|
+
)
|
|
1729
2049
|
);
|
|
2050
|
+
this.insertServiceTransportTask = CadenzaService.createCadenzaDBInsertTask(
|
|
2051
|
+
"service_instance_transport",
|
|
2052
|
+
{
|
|
2053
|
+
onConflict: {
|
|
2054
|
+
target: ["service_instance_id", "role", "origin"],
|
|
2055
|
+
action: {
|
|
2056
|
+
do: "update",
|
|
2057
|
+
set: {
|
|
2058
|
+
protocols: "excluded",
|
|
2059
|
+
security_profile: "excluded",
|
|
2060
|
+
auth_strategy: "excluded",
|
|
2061
|
+
deleted: "false"
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
},
|
|
2066
|
+
{
|
|
2067
|
+
inputSchema: {
|
|
2068
|
+
type: "object",
|
|
2069
|
+
properties: {
|
|
2070
|
+
data: {
|
|
2071
|
+
type: "object",
|
|
2072
|
+
properties: {
|
|
2073
|
+
uuid: {
|
|
2074
|
+
type: "string"
|
|
2075
|
+
},
|
|
2076
|
+
service_instance_id: {
|
|
2077
|
+
type: "string"
|
|
2078
|
+
},
|
|
2079
|
+
role: {
|
|
2080
|
+
type: "string"
|
|
2081
|
+
},
|
|
2082
|
+
origin: {
|
|
2083
|
+
type: "string"
|
|
2084
|
+
},
|
|
2085
|
+
protocols: {
|
|
2086
|
+
type: "array",
|
|
2087
|
+
items: {
|
|
2088
|
+
type: "string"
|
|
2089
|
+
}
|
|
2090
|
+
},
|
|
2091
|
+
security_profile: {
|
|
2092
|
+
type: "string"
|
|
2093
|
+
},
|
|
2094
|
+
auth_strategy: {
|
|
2095
|
+
type: "string"
|
|
2096
|
+
}
|
|
2097
|
+
},
|
|
2098
|
+
required: ["uuid", "service_instance_id", "role", "origin"]
|
|
2099
|
+
}
|
|
2100
|
+
},
|
|
2101
|
+
required: ["data"]
|
|
2102
|
+
},
|
|
2103
|
+
outputSchema: {
|
|
2104
|
+
type: "object",
|
|
2105
|
+
properties: {
|
|
2106
|
+
uuid: {
|
|
2107
|
+
type: "string"
|
|
2108
|
+
}
|
|
2109
|
+
},
|
|
2110
|
+
required: ["uuid"]
|
|
2111
|
+
},
|
|
2112
|
+
retryCount: 5,
|
|
2113
|
+
retryDelay: 1e3
|
|
2114
|
+
}
|
|
2115
|
+
).doOn("meta.service_registry.transport_registration_requested").emits("meta.service_registry.transport_registered").emitsOnFail("meta.service_registry.transport_registration_failed");
|
|
1730
2116
|
CadenzaService.createMetaTask(
|
|
1731
2117
|
"Handle service creation",
|
|
1732
2118
|
(ctx) => {
|
|
1733
2119
|
if (!ctx.__cadenzaDBConnect) {
|
|
1734
2120
|
ctx.__skipRemoteExecution = true;
|
|
1735
2121
|
}
|
|
1736
|
-
if (isBrowser) {
|
|
2122
|
+
if (isBrowser || ctx.__isFrontend) {
|
|
1737
2123
|
CadenzaService.createMetaTask("Prepare for signal sync", () => {
|
|
1738
2124
|
return {};
|
|
1739
2125
|
}).then(
|
|
@@ -1766,28 +2152,24 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1766
2152
|
for (const service of services) {
|
|
1767
2153
|
const instances = this.instances.get(service).filter((i) => i.isActive);
|
|
1768
2154
|
for (const instance of instances) {
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
const clientCreated = instances?.some(
|
|
1773
|
-
(i) => i.address === address && i.port === port && i.clientCreated && i.isActive
|
|
2155
|
+
const transport = this.getRouteableTransport(
|
|
2156
|
+
instance,
|
|
2157
|
+
this.useSocket ? "socket" : "rest"
|
|
1774
2158
|
);
|
|
1775
|
-
if (!
|
|
2159
|
+
if (!transport) {
|
|
2160
|
+
continue;
|
|
2161
|
+
}
|
|
2162
|
+
if (!this.hasTransportClientCreated(instance, transport.uuid)) {
|
|
1776
2163
|
emit("meta.service_registry.dependee_registered", {
|
|
1777
2164
|
serviceName: service,
|
|
1778
2165
|
serviceInstanceId: instance.uuid,
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
2166
|
+
serviceTransportId: transport.uuid,
|
|
2167
|
+
serviceOrigin: transport.origin,
|
|
2168
|
+
transportProtocols: transport.protocols,
|
|
1782
2169
|
communicationTypes: ["signal"]
|
|
1783
2170
|
});
|
|
2171
|
+
this.markTransportClientCreated(instance, transport.uuid);
|
|
1784
2172
|
}
|
|
1785
|
-
instance.clientCreated = true;
|
|
1786
|
-
instances.forEach((i) => {
|
|
1787
|
-
if (i.address === address && i.port === port) {
|
|
1788
|
-
i.clientCreated = true;
|
|
1789
|
-
}
|
|
1790
|
-
});
|
|
1791
2173
|
}
|
|
1792
2174
|
}
|
|
1793
2175
|
return {};
|
|
@@ -1926,6 +2308,33 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1926
2308
|
}
|
|
1927
2309
|
return this.getInstance(this.serviceName, this.serviceInstanceId);
|
|
1928
2310
|
}
|
|
2311
|
+
getRoutingTransportRole() {
|
|
2312
|
+
return this.isFrontend ? "public" : "internal";
|
|
2313
|
+
}
|
|
2314
|
+
getTransportById(instance, transportId) {
|
|
2315
|
+
return instance.transports.find((transport) => transport.uuid === transportId);
|
|
2316
|
+
}
|
|
2317
|
+
getRouteableTransport(instance, protocol, role = this.getRoutingTransportRole()) {
|
|
2318
|
+
return getRouteableTransport(instance, role, protocol);
|
|
2319
|
+
}
|
|
2320
|
+
getTransportClientKey(instance, protocol, role = this.getRoutingTransportRole()) {
|
|
2321
|
+
const transport = this.getRouteableTransport(instance, protocol, role);
|
|
2322
|
+
if (!transport) {
|
|
2323
|
+
return null;
|
|
2324
|
+
}
|
|
2325
|
+
return buildTransportClientKey(transport);
|
|
2326
|
+
}
|
|
2327
|
+
hasTransportClientCreated(instance, transportId) {
|
|
2328
|
+
return (instance.clientCreatedTransportIds ?? []).includes(transportId);
|
|
2329
|
+
}
|
|
2330
|
+
markTransportClientCreated(instance, transportId) {
|
|
2331
|
+
if (!instance.clientCreatedTransportIds) {
|
|
2332
|
+
instance.clientCreatedTransportIds = [];
|
|
2333
|
+
}
|
|
2334
|
+
if (!instance.clientCreatedTransportIds.includes(transportId)) {
|
|
2335
|
+
instance.clientCreatedTransportIds.push(transportId);
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
1929
2338
|
registerDependee(serviceName, serviceInstanceId, options = {}) {
|
|
1930
2339
|
if (!serviceName || !serviceInstanceId) {
|
|
1931
2340
|
return;
|
|
@@ -2003,7 +2412,13 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2003
2412
|
if (!serviceName || !serviceInstanceId) {
|
|
2004
2413
|
return null;
|
|
2005
2414
|
}
|
|
2006
|
-
const
|
|
2415
|
+
const transportId = ctx.transportId ?? ctx.serviceTransportId ?? ctx.serviceTransport?.uuid ?? void 0;
|
|
2416
|
+
const transportOrigin = ctx.transportOrigin ?? ctx.serviceOrigin ?? ctx.serviceTransport?.origin ?? void 0;
|
|
2417
|
+
const transportProtocols = Array.isArray(
|
|
2418
|
+
ctx.transportProtocols ?? ctx.serviceTransport?.protocols
|
|
2419
|
+
) ? (ctx.transportProtocols ?? ctx.serviceTransport?.protocols).map((entry) => String(entry)).filter(
|
|
2420
|
+
(entry) => entry === "rest" || entry === "socket"
|
|
2421
|
+
) : void 0;
|
|
2007
2422
|
const numberOfRunningGraphs = Math.max(
|
|
2008
2423
|
0,
|
|
2009
2424
|
Math.trunc(
|
|
@@ -2022,9 +2437,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2022
2437
|
return {
|
|
2023
2438
|
serviceName,
|
|
2024
2439
|
serviceInstanceId,
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2440
|
+
transportId: typeof transportId === "string" && transportId.trim().length > 0 ? transportId : void 0,
|
|
2441
|
+
transportOrigin: typeof transportOrigin === "string" && transportOrigin.trim().length > 0 ? transportOrigin : void 0,
|
|
2442
|
+
transportProtocols: transportProtocols && transportProtocols.length > 0 ? Array.from(new Set(transportProtocols)) : void 0,
|
|
2028
2443
|
isFrontend: typeof ctx.isFrontend === "boolean" ? ctx.isFrontend : typeof ctx.serviceInstance?.isFrontend === "boolean" ? ctx.serviceInstance.isFrontend : void 0,
|
|
2029
2444
|
reportedAt: ctx.reportedAt ?? (typeof ctx.__reportedAt === "string" ? ctx.__reportedAt : void 0) ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
2030
2445
|
state: ctx.state === "healthy" || ctx.state === "degraded" || ctx.state === "overloaded" || ctx.state === "unavailable" ? ctx.state : resolved.state,
|
|
@@ -2041,14 +2456,23 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2041
2456
|
if (!instance) {
|
|
2042
2457
|
return false;
|
|
2043
2458
|
}
|
|
2044
|
-
if (report.
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2459
|
+
if (report.transportId && report.transportOrigin) {
|
|
2460
|
+
const protocols = report.transportProtocols && report.transportProtocols.length > 0 ? report.transportProtocols : ["rest", "socket"];
|
|
2461
|
+
const existingTransport = this.getTransportById(instance, report.transportId);
|
|
2462
|
+
if (existingTransport) {
|
|
2463
|
+
existingTransport.origin = report.transportOrigin;
|
|
2464
|
+
existingTransport.protocols = protocols;
|
|
2465
|
+
} else {
|
|
2466
|
+
instance.transports.push({
|
|
2467
|
+
uuid: report.transportId,
|
|
2468
|
+
serviceInstanceId: report.serviceInstanceId,
|
|
2469
|
+
role: this.getRoutingTransportRole(),
|
|
2470
|
+
origin: report.transportOrigin,
|
|
2471
|
+
protocols,
|
|
2472
|
+
securityProfile: null,
|
|
2473
|
+
authStrategy: null
|
|
2474
|
+
});
|
|
2475
|
+
}
|
|
2052
2476
|
}
|
|
2053
2477
|
if (typeof report.isFrontend === "boolean") {
|
|
2054
2478
|
instance.isFrontend = report.isFrontend;
|
|
@@ -2091,9 +2515,21 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2091
2515
|
const report = {
|
|
2092
2516
|
serviceName: this.serviceName,
|
|
2093
2517
|
serviceInstanceId: this.serviceInstanceId,
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2518
|
+
transportId: this.getRouteableTransport(
|
|
2519
|
+
localInstance,
|
|
2520
|
+
this.useSocket ? "socket" : "rest",
|
|
2521
|
+
"internal"
|
|
2522
|
+
)?.uuid ?? void 0,
|
|
2523
|
+
transportOrigin: this.getRouteableTransport(
|
|
2524
|
+
localInstance,
|
|
2525
|
+
this.useSocket ? "socket" : "rest",
|
|
2526
|
+
"internal"
|
|
2527
|
+
)?.origin ?? void 0,
|
|
2528
|
+
transportProtocols: this.getRouteableTransport(
|
|
2529
|
+
localInstance,
|
|
2530
|
+
this.useSocket ? "socket" : "rest",
|
|
2531
|
+
"internal"
|
|
2532
|
+
)?.protocols ?? void 0,
|
|
2097
2533
|
isFrontend: localInstance.isFrontend,
|
|
2098
2534
|
reportedAt,
|
|
2099
2535
|
state: snapshot.state,
|
|
@@ -2308,6 +2744,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2308
2744
|
this.numberOfRunningGraphs = 0;
|
|
2309
2745
|
this.runtimeStatusHeartbeatStarted = false;
|
|
2310
2746
|
this.lastRuntimeStatusSnapshot = null;
|
|
2747
|
+
this.isFrontend = false;
|
|
2311
2748
|
}
|
|
2312
2749
|
};
|
|
2313
2750
|
|
|
@@ -2479,13 +2916,10 @@ var RestController = class _RestController {
|
|
|
2479
2916
|
CadenzaService.createMetaTask(
|
|
2480
2917
|
"Setup Express app security",
|
|
2481
2918
|
(ctx, emit) => {
|
|
2482
|
-
if (isBrowser) {
|
|
2483
|
-
emit("meta.
|
|
2919
|
+
if (isBrowser || ctx.__isFrontend) {
|
|
2920
|
+
emit("meta.service_registry.instance_registration_requested", {
|
|
2484
2921
|
data: {
|
|
2485
2922
|
uuid: ctx.__serviceInstanceId,
|
|
2486
|
-
address: `browser:${ctx.__serviceInstanceId}`,
|
|
2487
|
-
port: 0,
|
|
2488
|
-
exposed: false,
|
|
2489
2923
|
process_pid: 1,
|
|
2490
2924
|
service_name: ctx.__serviceName,
|
|
2491
2925
|
is_frontend: true,
|
|
@@ -2494,6 +2928,7 @@ var RestController = class _RestController {
|
|
|
2494
2928
|
is_blocked: false,
|
|
2495
2929
|
health: {}
|
|
2496
2930
|
},
|
|
2931
|
+
transportData: [],
|
|
2497
2932
|
...ctx
|
|
2498
2933
|
});
|
|
2499
2934
|
return;
|
|
@@ -2566,7 +3001,7 @@ var RestController = class _RestController {
|
|
|
2566
3001
|
return { ...ctx, __app: app };
|
|
2567
3002
|
},
|
|
2568
3003
|
"Sets up the Express server according to the security profile"
|
|
2569
|
-
).attachSignal("meta.
|
|
3004
|
+
).attachSignal("meta.service_registry.instance_registration_requested").then(
|
|
2570
3005
|
CadenzaService.createMetaTask(
|
|
2571
3006
|
"Define RestServer",
|
|
2572
3007
|
(ctx) => {
|
|
@@ -2686,28 +3121,32 @@ var RestController = class _RestController {
|
|
|
2686
3121
|
CadenzaService.createMetaTask(
|
|
2687
3122
|
"Configure network",
|
|
2688
3123
|
async (ctx) => {
|
|
2689
|
-
let
|
|
2690
|
-
let
|
|
2691
|
-
|
|
3124
|
+
let httpOrigin = null;
|
|
3125
|
+
let httpsOrigin = null;
|
|
3126
|
+
const resolveBoundAddress = (server) => {
|
|
3127
|
+
if (typeof server?.address() === "string") {
|
|
3128
|
+
return server.address();
|
|
3129
|
+
}
|
|
3130
|
+
if (server?.address()?.address === "::") {
|
|
3131
|
+
if (process.env.NODE_ENV === "development") {
|
|
3132
|
+
return "localhost";
|
|
3133
|
+
}
|
|
3134
|
+
if (process.env.IS_DOCKER === "true") {
|
|
3135
|
+
return process.env.CADENZA_SERVER_URL || "localhost";
|
|
3136
|
+
}
|
|
3137
|
+
}
|
|
3138
|
+
return server?.address()?.address || "localhost";
|
|
3139
|
+
};
|
|
2692
3140
|
const createHttpServer = async (ctx2) => {
|
|
2693
3141
|
await new Promise((resolve) => {
|
|
2694
3142
|
const server = http.createServer(ctx2.__app);
|
|
2695
3143
|
ctx2.httpServer = server;
|
|
2696
3144
|
server.listen(ctx2.__port, () => {
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
} else if (process.env.IS_DOCKER === "true") {
|
|
2703
|
-
address = process.env.CADENZA_SERVER_URL || "localhost";
|
|
2704
|
-
}
|
|
2705
|
-
} else {
|
|
2706
|
-
address = server?.address()?.address || "undefined";
|
|
2707
|
-
}
|
|
2708
|
-
console.log(
|
|
2709
|
-
`Server is running on ${address}:${port}`
|
|
2710
|
-
);
|
|
3145
|
+
const addressInfo = server.address();
|
|
3146
|
+
const address = resolveBoundAddress(server);
|
|
3147
|
+
const port = typeof addressInfo === "object" && addressInfo ? addressInfo.port || ctx2.__port : ctx2.__port;
|
|
3148
|
+
httpOrigin = `http://${address}:${port}`;
|
|
3149
|
+
console.log(`Server is running on ${httpOrigin}`);
|
|
2711
3150
|
resolve(address);
|
|
2712
3151
|
});
|
|
2713
3152
|
CadenzaService.createMetaTask(
|
|
@@ -2733,22 +3172,12 @@ var RestController = class _RestController {
|
|
|
2733
3172
|
ctx2.__app
|
|
2734
3173
|
);
|
|
2735
3174
|
ctx2.httpsServer = httpsServer;
|
|
2736
|
-
ctx2.__port = 443;
|
|
2737
|
-
port = 443;
|
|
2738
3175
|
httpsServer.listen(443, () => {
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
}
|
|
2745
|
-
} else {
|
|
2746
|
-
address = httpsServer?.address()?.address || "";
|
|
2747
|
-
}
|
|
2748
|
-
exposed = true;
|
|
2749
|
-
console.log(
|
|
2750
|
-
`HTTPS Server is running on ${address}:443`
|
|
2751
|
-
);
|
|
3176
|
+
const addressInfo = httpsServer.address();
|
|
3177
|
+
const address = resolveBoundAddress(httpsServer);
|
|
3178
|
+
const port = typeof addressInfo === "object" && addressInfo ? addressInfo.port || 443 : 443;
|
|
3179
|
+
httpsOrigin = `https://${address}:${port}`;
|
|
3180
|
+
console.log(`HTTPS Server is running on ${httpsOrigin}`);
|
|
2752
3181
|
resolve(address);
|
|
2753
3182
|
});
|
|
2754
3183
|
CadenzaService.createMetaTask(
|
|
@@ -2768,11 +3197,34 @@ var RestController = class _RestController {
|
|
|
2768
3197
|
} else if (ctx.__networkMode === "auto") {
|
|
2769
3198
|
await createHttpServer(ctx);
|
|
2770
3199
|
}
|
|
3200
|
+
const declaredTransports = Array.isArray(ctx.__declaredTransports) ? ctx.__declaredTransports : [];
|
|
3201
|
+
const hasExplicitInternalTransport = declaredTransports.some(
|
|
3202
|
+
(transport) => transport.role === "internal"
|
|
3203
|
+
);
|
|
3204
|
+
const transportData = declaredTransports.map((transport) => ({
|
|
3205
|
+
uuid: transport.uuid,
|
|
3206
|
+
service_instance_id: ctx.__serviceInstanceId,
|
|
3207
|
+
role: transport.role,
|
|
3208
|
+
origin: transport.origin,
|
|
3209
|
+
protocols: transport.protocols ?? ["rest", "socket"],
|
|
3210
|
+
...transport.securityProfile ? { security_profile: transport.securityProfile } : {},
|
|
3211
|
+
...transport.authStrategy ? { auth_strategy: transport.authStrategy } : {}
|
|
3212
|
+
}));
|
|
3213
|
+
if (!hasExplicitInternalTransport) {
|
|
3214
|
+
const internalOrigin = httpOrigin ?? httpsOrigin;
|
|
3215
|
+
if (internalOrigin) {
|
|
3216
|
+
transportData.unshift({
|
|
3217
|
+
uuid: `${ctx.__serviceInstanceId}-internal-auto`,
|
|
3218
|
+
service_instance_id: ctx.__serviceInstanceId,
|
|
3219
|
+
role: "internal",
|
|
3220
|
+
origin: internalOrigin,
|
|
3221
|
+
protocols: ["rest", "socket"],
|
|
3222
|
+
...ctx.__securityProfile ? { security_profile: ctx.__securityProfile } : {}
|
|
3223
|
+
});
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
2771
3226
|
ctx.data = {
|
|
2772
3227
|
uuid: ctx.__serviceInstanceId,
|
|
2773
|
-
address,
|
|
2774
|
-
port,
|
|
2775
|
-
exposed,
|
|
2776
3228
|
process_pid: process.pid,
|
|
2777
3229
|
service_name: ctx.__serviceName,
|
|
2778
3230
|
is_active: true,
|
|
@@ -2781,7 +3233,12 @@ var RestController = class _RestController {
|
|
|
2781
3233
|
is_blocked: false,
|
|
2782
3234
|
health: {}
|
|
2783
3235
|
};
|
|
3236
|
+
ctx.transportData = transportData;
|
|
2784
3237
|
delete ctx.__app;
|
|
3238
|
+
CadenzaService.emit(
|
|
3239
|
+
"meta.service_registry.instance_registration_requested",
|
|
3240
|
+
ctx
|
|
3241
|
+
);
|
|
2785
3242
|
return ctx;
|
|
2786
3243
|
},
|
|
2787
3244
|
"Configures network mode"
|
|
@@ -2831,10 +3288,12 @@ var RestController = class _RestController {
|
|
|
2831
3288
|
CadenzaService.createMetaTask(
|
|
2832
3289
|
"Setup fetch client",
|
|
2833
3290
|
(ctx) => {
|
|
2834
|
-
const
|
|
2835
|
-
const
|
|
2836
|
-
const
|
|
2837
|
-
|
|
3291
|
+
const serviceName = String(ctx.serviceName ?? "");
|
|
3292
|
+
const URL2 = String(ctx.serviceOrigin ?? "");
|
|
3293
|
+
const fetchId = String(ctx.serviceTransportId ?? "");
|
|
3294
|
+
if (!serviceName || !URL2 || !fetchId) {
|
|
3295
|
+
return false;
|
|
3296
|
+
}
|
|
2838
3297
|
const fetchDiagnostics = this.ensureFetchClientDiagnostics(
|
|
2839
3298
|
fetchId,
|
|
2840
3299
|
serviceName,
|
|
@@ -3086,18 +3545,18 @@ var RestController = class _RestController {
|
|
|
3086
3545
|
serviceName,
|
|
3087
3546
|
serviceInstanceId,
|
|
3088
3547
|
communicationTypes,
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3548
|
+
serviceTransportId,
|
|
3549
|
+
serviceOrigin,
|
|
3550
|
+
transportProtocols
|
|
3092
3551
|
} = ctx;
|
|
3093
|
-
const fetchId =
|
|
3552
|
+
const fetchId = String(serviceTransportId ?? "");
|
|
3094
3553
|
emit(`meta.fetch.handshake_requested:${fetchId}`, {
|
|
3095
3554
|
serviceInstanceId,
|
|
3096
3555
|
serviceName,
|
|
3097
3556
|
communicationTypes,
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3557
|
+
serviceTransportId,
|
|
3558
|
+
serviceOrigin,
|
|
3559
|
+
transportProtocols,
|
|
3101
3560
|
handshakeData: {
|
|
3102
3561
|
instanceId: CadenzaService.serviceRegistry.serviceInstanceId,
|
|
3103
3562
|
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
@@ -3280,7 +3739,6 @@ var RestController = class _RestController {
|
|
|
3280
3739
|
};
|
|
3281
3740
|
|
|
3282
3741
|
// src/network/SocketController.ts
|
|
3283
|
-
import { Server } from "socket.io";
|
|
3284
3742
|
import { RateLimiterMemory as RateLimiterMemory2 } from "rate-limiter-flexible";
|
|
3285
3743
|
import { io } from "socket.io-client";
|
|
3286
3744
|
|
|
@@ -3323,6 +3781,13 @@ var waitForSocketConnection = async (socket, timeoutMs, createError) => {
|
|
|
3323
3781
|
};
|
|
3324
3782
|
|
|
3325
3783
|
// src/network/SocketController.ts
|
|
3784
|
+
var dynamicImport = new Function(
|
|
3785
|
+
"specifier",
|
|
3786
|
+
"return import(specifier);"
|
|
3787
|
+
);
|
|
3788
|
+
async function importNodeModule(specifier) {
|
|
3789
|
+
return dynamicImport(specifier);
|
|
3790
|
+
}
|
|
3326
3791
|
var SocketController = class _SocketController {
|
|
3327
3792
|
constructor() {
|
|
3328
3793
|
this.diagnosticsErrorHistoryLimit = 100;
|
|
@@ -3347,9 +3812,9 @@ var SocketController = class _SocketController {
|
|
|
3347
3812
|
serviceInstanceId: "",
|
|
3348
3813
|
communicationTypes: [],
|
|
3349
3814
|
serviceName: "",
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3815
|
+
serviceTransportId: "",
|
|
3816
|
+
serviceOrigin: "",
|
|
3817
|
+
transportProtocols: [],
|
|
3353
3818
|
url: "",
|
|
3354
3819
|
socketId: null,
|
|
3355
3820
|
connected: false,
|
|
@@ -3522,7 +3987,7 @@ var SocketController = class _SocketController {
|
|
|
3522
3987
|
const setupSocketServerTask = CadenzaService.createMetaTask(
|
|
3523
3988
|
"Setup SocketServer",
|
|
3524
3989
|
this.socketServerActor.task(
|
|
3525
|
-
({ state, runtimeState, input, actor, setState, setRuntimeState, emit }) => {
|
|
3990
|
+
async ({ state, runtimeState, input, actor, setState, setRuntimeState, emit }) => {
|
|
3526
3991
|
const serverKey = this.resolveSocketServerKey(input) ?? actor.key ?? this.socketServerDefaultKey;
|
|
3527
3992
|
const shouldUseSocket = Boolean(input.__useSocket);
|
|
3528
3993
|
if (!shouldUseSocket) {
|
|
@@ -3541,7 +4006,9 @@ var SocketController = class _SocketController {
|
|
|
3541
4006
|
}
|
|
3542
4007
|
let runtimeHandle = runtimeState;
|
|
3543
4008
|
if (!runtimeHandle) {
|
|
3544
|
-
runtimeHandle = this.createSocketServerRuntimeHandleFromContext(
|
|
4009
|
+
runtimeHandle = await this.createSocketServerRuntimeHandleFromContext(
|
|
4010
|
+
input
|
|
4011
|
+
);
|
|
3545
4012
|
setRuntimeState(runtimeHandle);
|
|
3546
4013
|
}
|
|
3547
4014
|
const profile = String(input.__securityProfile ?? state.securityProfile ?? "medium");
|
|
@@ -3799,21 +4266,21 @@ var SocketController = class _SocketController {
|
|
|
3799
4266
|
if (input.serviceName !== void 0) {
|
|
3800
4267
|
next.serviceName = String(input.serviceName);
|
|
3801
4268
|
}
|
|
3802
|
-
if (input.
|
|
3803
|
-
next.
|
|
4269
|
+
if (input.serviceTransportId !== void 0) {
|
|
4270
|
+
next.serviceTransportId = String(input.serviceTransportId);
|
|
3804
4271
|
}
|
|
3805
4272
|
if (input.serviceInstanceId !== void 0) {
|
|
3806
4273
|
next.serviceInstanceId = String(input.serviceInstanceId);
|
|
3807
4274
|
}
|
|
3808
|
-
if (input.
|
|
3809
|
-
next.
|
|
4275
|
+
if (input.serviceOrigin !== void 0) {
|
|
4276
|
+
next.serviceOrigin = String(input.serviceOrigin);
|
|
4277
|
+
}
|
|
4278
|
+
if (input.transportProtocols !== void 0) {
|
|
4279
|
+
next.transportProtocols = Array.isArray(input.transportProtocols) ? input.transportProtocols.map((entry) => String(entry)) : [];
|
|
3810
4280
|
}
|
|
3811
4281
|
if (input.url !== void 0) {
|
|
3812
4282
|
next.url = String(input.url);
|
|
3813
4283
|
}
|
|
3814
|
-
if (input.servicePort !== void 0) {
|
|
3815
|
-
next.servicePort = Number(input.servicePort);
|
|
3816
|
-
}
|
|
3817
4284
|
if (input.fetchId !== void 0) {
|
|
3818
4285
|
next.fetchId = String(input.fetchId);
|
|
3819
4286
|
}
|
|
@@ -3857,25 +4324,24 @@ var SocketController = class _SocketController {
|
|
|
3857
4324
|
input.communicationTypes
|
|
3858
4325
|
);
|
|
3859
4326
|
const serviceName = String(input.serviceName ?? "");
|
|
3860
|
-
const
|
|
3861
|
-
const
|
|
3862
|
-
const
|
|
3863
|
-
if (!
|
|
4327
|
+
const serviceTransportId = String(input.serviceTransportId ?? "");
|
|
4328
|
+
const serviceOrigin = String(input.serviceOrigin ?? "");
|
|
4329
|
+
const parsedOrigin = parseTransportOrigin(serviceOrigin);
|
|
4330
|
+
if (!serviceTransportId || !serviceOrigin || !parsedOrigin) {
|
|
3864
4331
|
CadenzaService.log(
|
|
3865
|
-
"Socket client setup skipped due to missing
|
|
4332
|
+
"Socket client setup skipped due to missing transport origin",
|
|
3866
4333
|
{
|
|
3867
4334
|
serviceName,
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
protocol
|
|
4335
|
+
serviceTransportId,
|
|
4336
|
+
serviceOrigin
|
|
3871
4337
|
},
|
|
3872
4338
|
"warning"
|
|
3873
4339
|
);
|
|
3874
4340
|
return false;
|
|
3875
4341
|
}
|
|
3876
|
-
const socketProtocol = protocol === "https" ? "wss" : "ws";
|
|
3877
|
-
const url = `${socketProtocol}://${
|
|
3878
|
-
const fetchId =
|
|
4342
|
+
const socketProtocol = parsedOrigin.protocol === "https" ? "wss" : "ws";
|
|
4343
|
+
const url = `${socketProtocol}://${parsedOrigin.hostname}:${parsedOrigin.port}`;
|
|
4344
|
+
const fetchId = serviceTransportId;
|
|
3879
4345
|
const applySessionOperation = (operation, patch = {}) => {
|
|
3880
4346
|
CadenzaService.emit("meta.socket_client.session_operation_requested", {
|
|
3881
4347
|
fetchId,
|
|
@@ -3884,9 +4350,9 @@ var SocketController = class _SocketController {
|
|
|
3884
4350
|
serviceInstanceId,
|
|
3885
4351
|
communicationTypes,
|
|
3886
4352
|
serviceName,
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
4353
|
+
serviceTransportId,
|
|
4354
|
+
serviceOrigin,
|
|
4355
|
+
transportProtocols: input.transportProtocols,
|
|
3890
4356
|
url
|
|
3891
4357
|
});
|
|
3892
4358
|
};
|
|
@@ -3905,9 +4371,9 @@ var SocketController = class _SocketController {
|
|
|
3905
4371
|
serviceInstanceId,
|
|
3906
4372
|
communicationTypes,
|
|
3907
4373
|
serviceName,
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
4374
|
+
serviceTransportId,
|
|
4375
|
+
serviceOrigin,
|
|
4376
|
+
transportProtocols: Array.isArray(input.transportProtocols) ? input.transportProtocols.map((entry) => String(entry)) : [],
|
|
3911
4377
|
url,
|
|
3912
4378
|
destroyed: false,
|
|
3913
4379
|
updatedAt: Date.now()
|
|
@@ -4235,8 +4701,8 @@ var SocketController = class _SocketController {
|
|
|
4235
4701
|
);
|
|
4236
4702
|
CadenzaService.emit(`meta.socket_client.disconnected:${fetchId}`, {
|
|
4237
4703
|
serviceName,
|
|
4238
|
-
|
|
4239
|
-
|
|
4704
|
+
serviceTransportId,
|
|
4705
|
+
serviceOrigin
|
|
4240
4706
|
});
|
|
4241
4707
|
runtimeHandle.handshake = false;
|
|
4242
4708
|
});
|
|
@@ -4257,7 +4723,7 @@ var SocketController = class _SocketController {
|
|
|
4257
4723
|
{
|
|
4258
4724
|
serviceInstanceId: CadenzaService.serviceRegistry.serviceInstanceId,
|
|
4259
4725
|
serviceName: CadenzaService.serviceRegistry.serviceName,
|
|
4260
|
-
isFrontend: isBrowser,
|
|
4726
|
+
isFrontend: CadenzaService.serviceRegistry.isFrontend || isBrowser,
|
|
4261
4727
|
__status: "success"
|
|
4262
4728
|
},
|
|
4263
4729
|
1e4,
|
|
@@ -4435,9 +4901,9 @@ var SocketController = class _SocketController {
|
|
|
4435
4901
|
serviceInstanceId,
|
|
4436
4902
|
serviceName,
|
|
4437
4903
|
communicationTypes,
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4904
|
+
serviceTransportId,
|
|
4905
|
+
serviceOrigin,
|
|
4906
|
+
transportProtocols: input.transportProtocols,
|
|
4441
4907
|
handshakeData: {
|
|
4442
4908
|
instanceId: CadenzaService.serviceRegistry.serviceInstanceId,
|
|
4443
4909
|
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
@@ -4476,31 +4942,20 @@ var SocketController = class _SocketController {
|
|
|
4476
4942
|
if (explicitFetchId) {
|
|
4477
4943
|
return explicitFetchId;
|
|
4478
4944
|
}
|
|
4479
|
-
const
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
return void 0;
|
|
4484
|
-
}
|
|
4485
|
-
return `${serviceAddress}_${port}`;
|
|
4486
|
-
}
|
|
4487
|
-
resolveServicePort(protocol, rawPort) {
|
|
4488
|
-
if (protocol === "https") {
|
|
4489
|
-
return 443;
|
|
4490
|
-
}
|
|
4491
|
-
const parsed = Number(rawPort);
|
|
4492
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
4493
|
-
return void 0;
|
|
4494
|
-
}
|
|
4495
|
-
return Math.trunc(parsed);
|
|
4945
|
+
const transportId = String(
|
|
4946
|
+
input.serviceTransportId ?? input.transportId ?? ""
|
|
4947
|
+
).trim();
|
|
4948
|
+
return transportId || void 0;
|
|
4496
4949
|
}
|
|
4497
|
-
createSocketServerRuntimeHandleFromContext(context) {
|
|
4950
|
+
async createSocketServerRuntimeHandleFromContext(context) {
|
|
4498
4951
|
const baseServer = context.httpsServer ?? context.httpServer;
|
|
4499
4952
|
if (!baseServer) {
|
|
4500
4953
|
throw new Error(
|
|
4501
4954
|
"Socket server runtime setup requires either httpsServer or httpServer"
|
|
4502
4955
|
);
|
|
4503
4956
|
}
|
|
4957
|
+
const socketServerModule = await importNodeModule("socket.io");
|
|
4958
|
+
const Server = socketServerModule.Server;
|
|
4504
4959
|
const server = new Server(baseServer, {
|
|
4505
4960
|
pingInterval: 3e4,
|
|
4506
4961
|
pingTimeout: 2e4,
|
|
@@ -4791,16 +5246,140 @@ var SignalController = class _SignalController {
|
|
|
4791
5246
|
service_name: CadenzaService.serviceRegistry.serviceName,
|
|
4792
5247
|
service_instance_id: CadenzaService.serviceRegistry.serviceInstanceId
|
|
4793
5248
|
}
|
|
4794
|
-
};
|
|
4795
|
-
},
|
|
4796
|
-
"",
|
|
4797
|
-
{ isSubMeta: true, concurrency: 100 }
|
|
4798
|
-
).doOn("sub_meta.signal_broker.emitting_signal").emits("global.sub_meta.signal_controller.signal_emitted");
|
|
4799
|
-
}
|
|
4800
|
-
};
|
|
5249
|
+
};
|
|
5250
|
+
},
|
|
5251
|
+
"",
|
|
5252
|
+
{ isSubMeta: true, concurrency: 100 }
|
|
5253
|
+
).doOn("sub_meta.signal_broker.emitting_signal").emits("global.sub_meta.signal_controller.signal_emitted");
|
|
5254
|
+
}
|
|
5255
|
+
};
|
|
5256
|
+
|
|
5257
|
+
// src/graph/controllers/registerActorSessionPersistence.ts
|
|
5258
|
+
import { META_ACTOR_SESSION_STATE_PERSIST_INTENT } from "@cadenza.io/core";
|
|
5259
|
+
function registerActorSessionPersistenceTasks() {
|
|
5260
|
+
if (CadenzaService.get("Persist actor session state")) {
|
|
5261
|
+
return;
|
|
5262
|
+
}
|
|
5263
|
+
const actorSessionStateInsertTask = CadenzaService.get("dbInsertActorSessionState") ?? CadenzaService.get("Insert actor_session_state in CadenzaDB") ?? CadenzaService.createCadenzaDBInsertTask(
|
|
5264
|
+
"actor_session_state",
|
|
5265
|
+
{},
|
|
5266
|
+
{ concurrency: 100, isSubMeta: true }
|
|
5267
|
+
);
|
|
5268
|
+
const validateActorSessionStatePersistenceTask = CadenzaService.createMetaTask(
|
|
5269
|
+
"Validate actor session state persistence",
|
|
5270
|
+
(ctx) => {
|
|
5271
|
+
if (ctx.errored || ctx.failed || ctx.__success !== true) {
|
|
5272
|
+
throw new Error(
|
|
5273
|
+
String(
|
|
5274
|
+
ctx.__error ?? ctx.error ?? "actor_session_state persistence query failed"
|
|
5275
|
+
)
|
|
5276
|
+
);
|
|
5277
|
+
}
|
|
5278
|
+
const rowCount = Number(ctx.rowCount ?? 0);
|
|
5279
|
+
if (!Number.isFinite(rowCount) || rowCount <= 0) {
|
|
5280
|
+
throw new Error(
|
|
5281
|
+
"actor_session_state persistence did not affect any rows (possible stale durable_version)"
|
|
5282
|
+
);
|
|
5283
|
+
}
|
|
5284
|
+
return {
|
|
5285
|
+
__success: true,
|
|
5286
|
+
persisted: true,
|
|
5287
|
+
actor_name: ctx.actor_name,
|
|
5288
|
+
actor_version: ctx.actor_version,
|
|
5289
|
+
actor_key: ctx.actor_key,
|
|
5290
|
+
service_name: ctx.service_name,
|
|
5291
|
+
durable_version: ctx.durable_version
|
|
5292
|
+
};
|
|
5293
|
+
},
|
|
5294
|
+
"Enforces strict actor session persistence success contract.",
|
|
5295
|
+
{ isSubMeta: true, concurrency: 100 }
|
|
5296
|
+
);
|
|
5297
|
+
const insertAndValidateActorSessionStateTask = actorSessionStateInsertTask.then(
|
|
5298
|
+
validateActorSessionStatePersistenceTask
|
|
5299
|
+
);
|
|
5300
|
+
CadenzaService.createMetaTask(
|
|
5301
|
+
"Persist actor session state",
|
|
5302
|
+
(ctx) => {
|
|
5303
|
+
const actorName = typeof ctx.actor_name === "string" ? ctx.actor_name.trim() : "";
|
|
5304
|
+
const actorKey = typeof ctx.actor_key === "string" ? ctx.actor_key.trim() : "";
|
|
5305
|
+
const actorVersion = Number(ctx.actor_version ?? 1);
|
|
5306
|
+
const durableVersion = Number(ctx.durable_version);
|
|
5307
|
+
if (!actorName) {
|
|
5308
|
+
throw new Error("actor_name is required for actor session persistence");
|
|
5309
|
+
}
|
|
5310
|
+
if (!actorKey) {
|
|
5311
|
+
throw new Error("actor_key is required for actor session persistence");
|
|
5312
|
+
}
|
|
5313
|
+
if (!Number.isInteger(actorVersion) || actorVersion < 1) {
|
|
5314
|
+
throw new Error("actor_version must be a positive integer");
|
|
5315
|
+
}
|
|
5316
|
+
if (!Number.isInteger(durableVersion) || durableVersion < 0) {
|
|
5317
|
+
throw new Error("durable_version must be a non-negative integer");
|
|
5318
|
+
}
|
|
5319
|
+
if (typeof ctx.durable_state !== "object" || ctx.durable_state === null || Array.isArray(ctx.durable_state)) {
|
|
5320
|
+
throw new Error("durable_state must be a non-null object");
|
|
5321
|
+
}
|
|
5322
|
+
const serviceName = CadenzaService.serviceRegistry.serviceName;
|
|
5323
|
+
if (!serviceName) {
|
|
5324
|
+
throw new Error("service_name is not available for actor session persistence");
|
|
5325
|
+
}
|
|
5326
|
+
let expiresAt = null;
|
|
5327
|
+
if (ctx.expires_at !== void 0 && ctx.expires_at !== null) {
|
|
5328
|
+
if (ctx.expires_at instanceof Date) {
|
|
5329
|
+
expiresAt = ctx.expires_at.toISOString();
|
|
5330
|
+
} else if (typeof ctx.expires_at === "string" && ctx.expires_at.trim().length > 0) {
|
|
5331
|
+
expiresAt = ctx.expires_at;
|
|
5332
|
+
} else {
|
|
5333
|
+
throw new Error("expires_at must be null, Date, or non-empty string");
|
|
5334
|
+
}
|
|
5335
|
+
}
|
|
5336
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5337
|
+
return {
|
|
5338
|
+
...ctx,
|
|
5339
|
+
actor_name: actorName,
|
|
5340
|
+
actor_key: actorKey,
|
|
5341
|
+
actor_version: actorVersion,
|
|
5342
|
+
durable_version: durableVersion,
|
|
5343
|
+
expires_at: expiresAt,
|
|
5344
|
+
service_name: serviceName,
|
|
5345
|
+
queryData: {
|
|
5346
|
+
data: {
|
|
5347
|
+
actor_name: actorName,
|
|
5348
|
+
actor_version: actorVersion,
|
|
5349
|
+
actor_key: actorKey,
|
|
5350
|
+
service_name: serviceName,
|
|
5351
|
+
durable_state: ctx.durable_state,
|
|
5352
|
+
durable_version: durableVersion,
|
|
5353
|
+
expires_at: expiresAt,
|
|
5354
|
+
updated: updatedAt
|
|
5355
|
+
},
|
|
5356
|
+
onConflict: {
|
|
5357
|
+
target: [
|
|
5358
|
+
"actor_name",
|
|
5359
|
+
"actor_version",
|
|
5360
|
+
"actor_key",
|
|
5361
|
+
"service_name"
|
|
5362
|
+
],
|
|
5363
|
+
action: {
|
|
5364
|
+
do: "update",
|
|
5365
|
+
set: {
|
|
5366
|
+
durable_state: "excluded",
|
|
5367
|
+
durable_version: "excluded",
|
|
5368
|
+
expires_at: "excluded",
|
|
5369
|
+
updated: "excluded"
|
|
5370
|
+
},
|
|
5371
|
+
where: "actor_session_state.durable_version <= excluded.durable_version"
|
|
5372
|
+
}
|
|
5373
|
+
}
|
|
5374
|
+
}
|
|
5375
|
+
};
|
|
5376
|
+
},
|
|
5377
|
+
"Validates and prepares actor_session_state payload for strict write-through persistence.",
|
|
5378
|
+
{ isSubMeta: true, concurrency: 100 }
|
|
5379
|
+
).then(insertAndValidateActorSessionStateTask).respondsTo(META_ACTOR_SESSION_STATE_PERSIST_INTENT);
|
|
5380
|
+
}
|
|
4801
5381
|
|
|
4802
5382
|
// src/graph/controllers/GraphMetadataController.ts
|
|
4803
|
-
import { META_ACTOR_SESSION_STATE_PERSIST_INTENT } from "@cadenza.io/core";
|
|
4804
5383
|
var GraphMetadataController = class _GraphMetadataController {
|
|
4805
5384
|
static get instance() {
|
|
4806
5385
|
if (!this._instance) this._instance = new _GraphMetadataController();
|
|
@@ -5034,123 +5613,7 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
5034
5613
|
}
|
|
5035
5614
|
};
|
|
5036
5615
|
}).doOn("meta.actor.task_associated").emits("global.meta.graph_metadata.actor_task_associated");
|
|
5037
|
-
|
|
5038
|
-
"actor_session_state",
|
|
5039
|
-
{},
|
|
5040
|
-
{ concurrency: 100, isSubMeta: true }
|
|
5041
|
-
);
|
|
5042
|
-
const validateActorSessionStatePersistenceTask = CadenzaService.createMetaTask(
|
|
5043
|
-
"Validate actor session state persistence",
|
|
5044
|
-
(ctx) => {
|
|
5045
|
-
if (ctx.errored || ctx.failed || ctx.__success !== true) {
|
|
5046
|
-
throw new Error(
|
|
5047
|
-
String(
|
|
5048
|
-
ctx.__error ?? ctx.error ?? "actor_session_state persistence query failed"
|
|
5049
|
-
)
|
|
5050
|
-
);
|
|
5051
|
-
}
|
|
5052
|
-
const rowCount = Number(ctx.rowCount ?? 0);
|
|
5053
|
-
if (!Number.isFinite(rowCount) || rowCount <= 0) {
|
|
5054
|
-
throw new Error(
|
|
5055
|
-
"actor_session_state persistence did not affect any rows (possible stale durable_version)"
|
|
5056
|
-
);
|
|
5057
|
-
}
|
|
5058
|
-
return {
|
|
5059
|
-
__success: true,
|
|
5060
|
-
persisted: true,
|
|
5061
|
-
actor_name: ctx.actor_name,
|
|
5062
|
-
actor_version: ctx.actor_version,
|
|
5063
|
-
actor_key: ctx.actor_key,
|
|
5064
|
-
service_name: ctx.service_name,
|
|
5065
|
-
durable_version: ctx.durable_version
|
|
5066
|
-
};
|
|
5067
|
-
},
|
|
5068
|
-
"Enforces strict actor session persistence success contract.",
|
|
5069
|
-
{ isSubMeta: true, concurrency: 100 }
|
|
5070
|
-
);
|
|
5071
|
-
const insertAndValidateActorSessionStateTask = actorSessionStateInsertTask.then(
|
|
5072
|
-
validateActorSessionStatePersistenceTask
|
|
5073
|
-
);
|
|
5074
|
-
CadenzaService.createMetaTask(
|
|
5075
|
-
"Persist actor session state",
|
|
5076
|
-
(ctx) => {
|
|
5077
|
-
const actorName = typeof ctx.actor_name === "string" ? ctx.actor_name.trim() : "";
|
|
5078
|
-
const actorKey = typeof ctx.actor_key === "string" ? ctx.actor_key.trim() : "";
|
|
5079
|
-
const actorVersion = Number(ctx.actor_version ?? 1);
|
|
5080
|
-
const durableVersion = Number(ctx.durable_version);
|
|
5081
|
-
if (!actorName) {
|
|
5082
|
-
throw new Error("actor_name is required for actor session persistence");
|
|
5083
|
-
}
|
|
5084
|
-
if (!actorKey) {
|
|
5085
|
-
throw new Error("actor_key is required for actor session persistence");
|
|
5086
|
-
}
|
|
5087
|
-
if (!Number.isInteger(actorVersion) || actorVersion < 1) {
|
|
5088
|
-
throw new Error("actor_version must be a positive integer");
|
|
5089
|
-
}
|
|
5090
|
-
if (!Number.isInteger(durableVersion) || durableVersion < 0) {
|
|
5091
|
-
throw new Error("durable_version must be a non-negative integer");
|
|
5092
|
-
}
|
|
5093
|
-
if (typeof ctx.durable_state !== "object" || ctx.durable_state === null || Array.isArray(ctx.durable_state)) {
|
|
5094
|
-
throw new Error("durable_state must be a non-null object");
|
|
5095
|
-
}
|
|
5096
|
-
const serviceName = CadenzaService.serviceRegistry.serviceName;
|
|
5097
|
-
if (!serviceName) {
|
|
5098
|
-
throw new Error("service_name is not available for actor session persistence");
|
|
5099
|
-
}
|
|
5100
|
-
let expiresAt = null;
|
|
5101
|
-
if (ctx.expires_at !== void 0 && ctx.expires_at !== null) {
|
|
5102
|
-
if (ctx.expires_at instanceof Date) {
|
|
5103
|
-
expiresAt = ctx.expires_at.toISOString();
|
|
5104
|
-
} else if (typeof ctx.expires_at === "string" && ctx.expires_at.trim().length > 0) {
|
|
5105
|
-
expiresAt = ctx.expires_at;
|
|
5106
|
-
} else {
|
|
5107
|
-
throw new Error("expires_at must be null, Date, or non-empty string");
|
|
5108
|
-
}
|
|
5109
|
-
}
|
|
5110
|
-
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5111
|
-
return {
|
|
5112
|
-
...ctx,
|
|
5113
|
-
actor_name: actorName,
|
|
5114
|
-
actor_key: actorKey,
|
|
5115
|
-
actor_version: actorVersion,
|
|
5116
|
-
durable_version: durableVersion,
|
|
5117
|
-
expires_at: expiresAt,
|
|
5118
|
-
service_name: serviceName,
|
|
5119
|
-
queryData: {
|
|
5120
|
-
data: {
|
|
5121
|
-
actor_name: actorName,
|
|
5122
|
-
actor_version: actorVersion,
|
|
5123
|
-
actor_key: actorKey,
|
|
5124
|
-
service_name: serviceName,
|
|
5125
|
-
durable_state: ctx.durable_state,
|
|
5126
|
-
durable_version: durableVersion,
|
|
5127
|
-
expires_at: expiresAt,
|
|
5128
|
-
updated: updatedAt
|
|
5129
|
-
},
|
|
5130
|
-
onConflict: {
|
|
5131
|
-
target: [
|
|
5132
|
-
"actor_name",
|
|
5133
|
-
"actor_version",
|
|
5134
|
-
"actor_key",
|
|
5135
|
-
"service_name"
|
|
5136
|
-
],
|
|
5137
|
-
action: {
|
|
5138
|
-
do: "update",
|
|
5139
|
-
set: {
|
|
5140
|
-
durable_state: "excluded",
|
|
5141
|
-
durable_version: "excluded",
|
|
5142
|
-
expires_at: "excluded",
|
|
5143
|
-
updated: "excluded"
|
|
5144
|
-
},
|
|
5145
|
-
where: "actor_session_state.durable_version <= excluded.durable_version"
|
|
5146
|
-
}
|
|
5147
|
-
}
|
|
5148
|
-
}
|
|
5149
|
-
};
|
|
5150
|
-
},
|
|
5151
|
-
"Validates and prepares actor_session_state payload for strict write-through persistence.",
|
|
5152
|
-
{ isSubMeta: true, concurrency: 100 }
|
|
5153
|
-
).then(insertAndValidateActorSessionStateTask).respondsTo(META_ACTOR_SESSION_STATE_PERSIST_INTENT);
|
|
5616
|
+
registerActorSessionPersistenceTasks();
|
|
5154
5617
|
CadenzaService.createMetaTask("Handle Intent Creation", (ctx) => {
|
|
5155
5618
|
const intentName = ctx.data?.name;
|
|
5156
5619
|
return {
|
|
@@ -7786,6 +8249,165 @@ var GraphSyncController = class _GraphSyncController {
|
|
|
7786
8249
|
}
|
|
7787
8250
|
};
|
|
7788
8251
|
|
|
8252
|
+
// src/utils/bootstrap.ts
|
|
8253
|
+
var DEFAULT_BOOTSTRAP_GLOBAL_KEY = "__CADENZA_RUNTIME__";
|
|
8254
|
+
function normalizeString3(value) {
|
|
8255
|
+
if (typeof value !== "string") {
|
|
8256
|
+
return void 0;
|
|
8257
|
+
}
|
|
8258
|
+
const normalized = value.trim();
|
|
8259
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
8260
|
+
}
|
|
8261
|
+
function readEnvString(name) {
|
|
8262
|
+
if (typeof process === "undefined") {
|
|
8263
|
+
return void 0;
|
|
8264
|
+
}
|
|
8265
|
+
return normalizeString3(process.env?.[name]);
|
|
8266
|
+
}
|
|
8267
|
+
function readConfiguredPort(value) {
|
|
8268
|
+
if (value === void 0 || value === null || value === "") {
|
|
8269
|
+
return void 0;
|
|
8270
|
+
}
|
|
8271
|
+
const parsed = Number(value);
|
|
8272
|
+
if (!Number.isFinite(parsed)) {
|
|
8273
|
+
throw new Error(`Invalid port value: ${String(value)}`);
|
|
8274
|
+
}
|
|
8275
|
+
const normalized = Math.trunc(parsed);
|
|
8276
|
+
if (normalized <= 0) {
|
|
8277
|
+
throw new Error(`Port must be a positive integer: ${String(value)}`);
|
|
8278
|
+
}
|
|
8279
|
+
return normalized;
|
|
8280
|
+
}
|
|
8281
|
+
function buildBootstrapUrl(protocol, address, port) {
|
|
8282
|
+
return `${protocol}://${address}:${port}`;
|
|
8283
|
+
}
|
|
8284
|
+
function resolveInjectedBootstrapUrl(injectedGlobalKey) {
|
|
8285
|
+
if (typeof globalThis === "undefined") {
|
|
8286
|
+
return void 0;
|
|
8287
|
+
}
|
|
8288
|
+
const runtimeConfig = globalThis[injectedGlobalKey];
|
|
8289
|
+
return normalizeString3(runtimeConfig?.bootstrapUrl);
|
|
8290
|
+
}
|
|
8291
|
+
function resolveExplicitBootstrapValue(options) {
|
|
8292
|
+
const injectedGlobalKey = normalizeString3(options.bootstrap?.injectedGlobalKey) ?? DEFAULT_BOOTSTRAP_GLOBAL_KEY;
|
|
8293
|
+
const explicitBootstrapUrl = normalizeString3(options.bootstrap?.url);
|
|
8294
|
+
if (explicitBootstrapUrl) {
|
|
8295
|
+
return {
|
|
8296
|
+
value: explicitBootstrapUrl,
|
|
8297
|
+
port: readConfiguredPort(options.cadenzaDB?.port),
|
|
8298
|
+
injectedGlobalKey
|
|
8299
|
+
};
|
|
8300
|
+
}
|
|
8301
|
+
if (options.runtime === "browser") {
|
|
8302
|
+
const injected = resolveInjectedBootstrapUrl(injectedGlobalKey);
|
|
8303
|
+
if (injected) {
|
|
8304
|
+
return {
|
|
8305
|
+
value: injected,
|
|
8306
|
+
port: readConfiguredPort(options.cadenzaDB?.port),
|
|
8307
|
+
injectedGlobalKey
|
|
8308
|
+
};
|
|
8309
|
+
}
|
|
8310
|
+
}
|
|
8311
|
+
const explicitAddress = normalizeString3(options.cadenzaDB?.address);
|
|
8312
|
+
if (explicitAddress) {
|
|
8313
|
+
return {
|
|
8314
|
+
value: explicitAddress,
|
|
8315
|
+
port: readConfiguredPort(options.cadenzaDB?.port),
|
|
8316
|
+
injectedGlobalKey
|
|
8317
|
+
};
|
|
8318
|
+
}
|
|
8319
|
+
const envAddress = readEnvString("CADENZA_DB_ADDRESS");
|
|
8320
|
+
return {
|
|
8321
|
+
value: envAddress,
|
|
8322
|
+
port: readConfiguredPort(options.cadenzaDB?.port ?? readEnvString("CADENZA_DB_PORT")),
|
|
8323
|
+
injectedGlobalKey
|
|
8324
|
+
};
|
|
8325
|
+
}
|
|
8326
|
+
function readIntegerEnv(name, fallback) {
|
|
8327
|
+
const raw = readEnvString(name);
|
|
8328
|
+
if (!raw) {
|
|
8329
|
+
return fallback;
|
|
8330
|
+
}
|
|
8331
|
+
const parsed = Number(raw);
|
|
8332
|
+
if (!Number.isFinite(parsed)) {
|
|
8333
|
+
return fallback;
|
|
8334
|
+
}
|
|
8335
|
+
const normalized = Math.trunc(parsed);
|
|
8336
|
+
if (normalized <= 0) {
|
|
8337
|
+
return fallback;
|
|
8338
|
+
}
|
|
8339
|
+
return normalized;
|
|
8340
|
+
}
|
|
8341
|
+
function readStringEnv(name) {
|
|
8342
|
+
return readEnvString(name);
|
|
8343
|
+
}
|
|
8344
|
+
function readListEnv(name) {
|
|
8345
|
+
const raw = readEnvString(name);
|
|
8346
|
+
if (!raw) {
|
|
8347
|
+
return [];
|
|
8348
|
+
}
|
|
8349
|
+
return raw.split("|").map((entry) => entry.trim()).filter((entry) => entry.length > 0).map((entry) => entry.split(",").map((part) => part.trim()));
|
|
8350
|
+
}
|
|
8351
|
+
function resolveBootstrapEndpoint(options) {
|
|
8352
|
+
const { value, port: fallbackPort, injectedGlobalKey } = resolveExplicitBootstrapValue(options);
|
|
8353
|
+
if (!value) {
|
|
8354
|
+
throw new Error(
|
|
8355
|
+
options.runtime === "browser" ? `No bootstrap URL available. Pass bootstrap.url or inject globalThis.${injectedGlobalKey}.bootstrapUrl.` : "No bootstrap URL available. Set CADENZA_DB_ADDRESS or pass bootstrap.url."
|
|
8356
|
+
);
|
|
8357
|
+
}
|
|
8358
|
+
const raw = value.trim();
|
|
8359
|
+
if (raw.length === 0) {
|
|
8360
|
+
throw new Error("Bootstrap URL cannot be empty");
|
|
8361
|
+
}
|
|
8362
|
+
if (raw.includes("://")) {
|
|
8363
|
+
const parsed2 = new URL(raw);
|
|
8364
|
+
const protocol2 = parsed2.protocol.replace(":", "");
|
|
8365
|
+
if (protocol2 !== "http" && protocol2 !== "https") {
|
|
8366
|
+
throw new Error(`Unsupported bootstrap protocol: ${parsed2.protocol}`);
|
|
8367
|
+
}
|
|
8368
|
+
if (parsed2.pathname && parsed2.pathname !== "/" && parsed2.pathname.trim().length > 0) {
|
|
8369
|
+
throw new Error(
|
|
8370
|
+
"Bootstrap URL must be an origin without a path component."
|
|
8371
|
+
);
|
|
8372
|
+
}
|
|
8373
|
+
const port2 = parsed2.port ? readConfiguredPort(parsed2.port) : fallbackPort;
|
|
8374
|
+
if (!port2) {
|
|
8375
|
+
throw new Error(
|
|
8376
|
+
"Bootstrap URL must include a port or CADENZA_DB_PORT must be provided."
|
|
8377
|
+
);
|
|
8378
|
+
}
|
|
8379
|
+
return {
|
|
8380
|
+
url: buildBootstrapUrl(protocol2, parsed2.hostname, port2),
|
|
8381
|
+
protocol: protocol2,
|
|
8382
|
+
address: parsed2.hostname,
|
|
8383
|
+
port: port2,
|
|
8384
|
+
exposed: protocol2 === "https",
|
|
8385
|
+
injectedGlobalKey
|
|
8386
|
+
};
|
|
8387
|
+
}
|
|
8388
|
+
if (raw.includes("/") || raw.includes("?") || raw.includes("#")) {
|
|
8389
|
+
throw new Error(
|
|
8390
|
+
"Bootstrap address without protocol must not include a path, query, or hash."
|
|
8391
|
+
);
|
|
8392
|
+
}
|
|
8393
|
+
const parsed = new URL(`http://${raw}`);
|
|
8394
|
+
const protocol = "http";
|
|
8395
|
+
const port = parsed.port ? readConfiguredPort(parsed.port) : fallbackPort;
|
|
8396
|
+
if (!port) {
|
|
8397
|
+
throw new Error(
|
|
8398
|
+
"Bootstrap address must include a port or CADENZA_DB_PORT must be provided."
|
|
8399
|
+
);
|
|
8400
|
+
}
|
|
8401
|
+
return {
|
|
8402
|
+
url: buildBootstrapUrl(protocol, parsed.hostname, port),
|
|
8403
|
+
protocol,
|
|
8404
|
+
address: parsed.hostname,
|
|
8405
|
+
port,
|
|
8406
|
+
exposed: false,
|
|
8407
|
+
injectedGlobalKey
|
|
8408
|
+
};
|
|
8409
|
+
}
|
|
8410
|
+
|
|
7789
8411
|
// src/Cadenza.ts
|
|
7790
8412
|
var CadenzaService = class {
|
|
7791
8413
|
/**
|
|
@@ -7804,11 +8426,60 @@ var CadenzaService = class {
|
|
|
7804
8426
|
this.metaRunner = Cadenza.metaRunner;
|
|
7805
8427
|
this.registry = Cadenza.registry;
|
|
7806
8428
|
this.serviceRegistry = ServiceRegistry.instance;
|
|
7807
|
-
SignalController.instance;
|
|
7808
8429
|
RestController.instance;
|
|
7809
8430
|
SocketController.instance;
|
|
7810
8431
|
console.log("BOOTSTRAPPED");
|
|
7811
8432
|
}
|
|
8433
|
+
static ensureTransportControllers(isFrontend) {
|
|
8434
|
+
if (!isFrontend) {
|
|
8435
|
+
SignalController.instance;
|
|
8436
|
+
}
|
|
8437
|
+
}
|
|
8438
|
+
static setHydrationResults(hydration) {
|
|
8439
|
+
this.hydratedInquiryResults = /* @__PURE__ */ new Map();
|
|
8440
|
+
const initialInquiryResults = hydration?.initialInquiryResults ?? {};
|
|
8441
|
+
for (const [key, value] of Object.entries(initialInquiryResults)) {
|
|
8442
|
+
this.hydratedInquiryResults.set(key, value);
|
|
8443
|
+
}
|
|
8444
|
+
}
|
|
8445
|
+
static consumeHydratedInquiryResult(hydrationKey) {
|
|
8446
|
+
if (!hydrationKey) {
|
|
8447
|
+
return void 0;
|
|
8448
|
+
}
|
|
8449
|
+
const result = this.hydratedInquiryResults.get(hydrationKey);
|
|
8450
|
+
if (result === void 0) {
|
|
8451
|
+
return void 0;
|
|
8452
|
+
}
|
|
8453
|
+
this.hydratedInquiryResults.delete(hydrationKey);
|
|
8454
|
+
return result;
|
|
8455
|
+
}
|
|
8456
|
+
static ensureFrontendSyncLoop() {
|
|
8457
|
+
if (this.frontendSyncScheduled) {
|
|
8458
|
+
return;
|
|
8459
|
+
}
|
|
8460
|
+
this.frontendSyncScheduled = true;
|
|
8461
|
+
Cadenza.interval("meta.sync_requested", { __syncing: false }, 18e4);
|
|
8462
|
+
Cadenza.schedule("meta.sync_requested", { __syncing: false }, 250);
|
|
8463
|
+
}
|
|
8464
|
+
static normalizeDeclaredTransports(transports, serviceId) {
|
|
8465
|
+
return (transports ?? []).map((transport) => normalizeServiceTransportConfig(transport)).filter(
|
|
8466
|
+
(transport) => !!transport
|
|
8467
|
+
).map((transport, index) => ({
|
|
8468
|
+
...transport,
|
|
8469
|
+
uuid: `${serviceId}-transport-${index + 1}`
|
|
8470
|
+
}));
|
|
8471
|
+
}
|
|
8472
|
+
static createBootstrapTransport(serviceInstanceId, role, endpoint) {
|
|
8473
|
+
return {
|
|
8474
|
+
uuid: `${serviceInstanceId}-${role}-bootstrap`,
|
|
8475
|
+
service_instance_id: serviceInstanceId,
|
|
8476
|
+
role,
|
|
8477
|
+
origin: endpoint.url,
|
|
8478
|
+
protocols: ["rest", "socket"],
|
|
8479
|
+
security_profile: null,
|
|
8480
|
+
auth_strategy: null
|
|
8481
|
+
};
|
|
8482
|
+
}
|
|
7812
8483
|
/**
|
|
7813
8484
|
* Validates the provided service name based on specific rules.
|
|
7814
8485
|
*
|
|
@@ -7921,6 +8592,12 @@ var CadenzaService = class {
|
|
|
7921
8592
|
}
|
|
7922
8593
|
static async inquire(inquiry, context, options = {}) {
|
|
7923
8594
|
this.bootstrap();
|
|
8595
|
+
const hydratedResult = this.consumeHydratedInquiryResult(
|
|
8596
|
+
options.hydrationKey
|
|
8597
|
+
);
|
|
8598
|
+
if (hydratedResult !== void 0) {
|
|
8599
|
+
return hydratedResult;
|
|
8600
|
+
}
|
|
7924
8601
|
const observer = this.inquiryBroker?.inquiryObservers.get(inquiry);
|
|
7925
8602
|
const allResponders = observer ? Array.from(observer.tasks).map((task) => ({
|
|
7926
8603
|
task,
|
|
@@ -8525,58 +9202,97 @@ var CadenzaService = class {
|
|
|
8525
9202
|
const serviceId = options.customServiceId ?? uuid3();
|
|
8526
9203
|
this.serviceRegistry.serviceName = serviceName;
|
|
8527
9204
|
this.serviceRegistry.serviceInstanceId = serviceId;
|
|
9205
|
+
this.setHydrationResults(options.hydration);
|
|
9206
|
+
const explicitFrontendMode = options.isFrontend;
|
|
8528
9207
|
options = {
|
|
8529
9208
|
loadBalance: true,
|
|
8530
9209
|
useSocket: true,
|
|
8531
9210
|
displayName: void 0,
|
|
8532
9211
|
isMeta: false,
|
|
8533
|
-
port:
|
|
8534
|
-
securityProfile:
|
|
8535
|
-
networkMode:
|
|
9212
|
+
port: readIntegerEnv("HTTP_PORT", 3e3),
|
|
9213
|
+
securityProfile: readStringEnv("SECURITY_PROFILE") ?? "medium",
|
|
9214
|
+
networkMode: readStringEnv("NETWORK_MODE") ?? "dev",
|
|
8536
9215
|
retryCount: 3,
|
|
8537
9216
|
cadenzaDB: {
|
|
8538
|
-
connect: true
|
|
8539
|
-
address: process.env.CADENZA_DB_ADDRESS ?? "localhost",
|
|
8540
|
-
port: parseInt(process.env.CADENZA_DB_PORT ?? "5000")
|
|
9217
|
+
connect: true
|
|
8541
9218
|
},
|
|
8542
|
-
relatedServices:
|
|
8543
|
-
|
|
8544
|
-
) : [],
|
|
8545
|
-
isFrontend: isBrowser,
|
|
9219
|
+
relatedServices: readListEnv("RELATED_SERVICES"),
|
|
9220
|
+
isFrontend: typeof explicitFrontendMode === "boolean" ? explicitFrontendMode : isBrowser,
|
|
8546
9221
|
...options
|
|
8547
9222
|
};
|
|
9223
|
+
const isFrontend = !!options.isFrontend;
|
|
9224
|
+
const declaredTransports = this.normalizeDeclaredTransports(
|
|
9225
|
+
options.transports,
|
|
9226
|
+
serviceId
|
|
9227
|
+
);
|
|
9228
|
+
this.serviceRegistry.isFrontend = isFrontend;
|
|
9229
|
+
this.serviceRegistry.useSocket = !!options.useSocket;
|
|
9230
|
+
this.serviceRegistry.retryCount = options.retryCount ?? 3;
|
|
9231
|
+
this.ensureTransportControllers(isFrontend);
|
|
9232
|
+
const resolvedBootstrapEndpoint = options.cadenzaDB?.connect ? resolveBootstrapEndpoint({
|
|
9233
|
+
runtime: isFrontend ? "browser" : "server",
|
|
9234
|
+
bootstrap: options.bootstrap,
|
|
9235
|
+
cadenzaDB: options.cadenzaDB
|
|
9236
|
+
}) : void 0;
|
|
9237
|
+
if (resolvedBootstrapEndpoint) {
|
|
9238
|
+
options.cadenzaDB = {
|
|
9239
|
+
...options.cadenzaDB,
|
|
9240
|
+
connect: true,
|
|
9241
|
+
address: resolvedBootstrapEndpoint.address,
|
|
9242
|
+
port: resolvedBootstrapEndpoint.port
|
|
9243
|
+
};
|
|
9244
|
+
}
|
|
8548
9245
|
if (options.cadenzaDB?.connect) {
|
|
8549
9246
|
this.emit("meta.initializing_service", {
|
|
8550
9247
|
// Seed the CadenzaDB
|
|
8551
9248
|
serviceInstance: {
|
|
8552
9249
|
uuid: "cadenza-db",
|
|
8553
9250
|
serviceName: "CadenzaDB",
|
|
8554
|
-
address: options.cadenzaDB?.address,
|
|
8555
|
-
port: options.cadenzaDB?.port,
|
|
8556
|
-
exposed: options.networkMode !== "dev",
|
|
8557
9251
|
numberOfRunningGraphs: 0,
|
|
8558
9252
|
isActive: true,
|
|
8559
9253
|
// Assume it is deployed
|
|
8560
9254
|
isNonResponsive: false,
|
|
8561
9255
|
isBlocked: false,
|
|
8562
|
-
health: {}
|
|
9256
|
+
health: {},
|
|
9257
|
+
isFrontend: false,
|
|
9258
|
+
transports: resolvedBootstrapEndpoint ? [
|
|
9259
|
+
this.createBootstrapTransport(
|
|
9260
|
+
"cadenza-db",
|
|
9261
|
+
isFrontend ? "public" : "internal",
|
|
9262
|
+
resolvedBootstrapEndpoint
|
|
9263
|
+
)
|
|
9264
|
+
] : []
|
|
8563
9265
|
}
|
|
8564
9266
|
});
|
|
8565
9267
|
}
|
|
8566
9268
|
options.relatedServices?.forEach((service) => {
|
|
9269
|
+
const relatedTransport = normalizeServiceTransportConfig({
|
|
9270
|
+
role: isFrontend ? "public" : "internal",
|
|
9271
|
+
origin: service[2].includes("://") ? service[2] : `http://${service[2]}`,
|
|
9272
|
+
protocols: ["rest", "socket"]
|
|
9273
|
+
});
|
|
8567
9274
|
this.emit("meta.initializing_service", {
|
|
8568
9275
|
serviceInstance: {
|
|
8569
9276
|
uuid: service[0],
|
|
8570
9277
|
serviceName: service[1],
|
|
8571
|
-
address: service[2].split(":")[0],
|
|
8572
|
-
port: service[2].split(":")[1] ?? 3e3,
|
|
8573
|
-
exposed: options.networkMode !== "dev",
|
|
8574
9278
|
numberOfRunningGraphs: 0,
|
|
8575
9279
|
isActive: true,
|
|
8576
9280
|
// Assume it is deployed
|
|
8577
9281
|
isNonResponsive: false,
|
|
8578
9282
|
isBlocked: false,
|
|
8579
|
-
health: {}
|
|
9283
|
+
health: {},
|
|
9284
|
+
isFrontend: false,
|
|
9285
|
+
transports: relatedTransport ? [
|
|
9286
|
+
{
|
|
9287
|
+
uuid: `${service[0]}-${relatedTransport.role}`,
|
|
9288
|
+
service_instance_id: service[0],
|
|
9289
|
+
role: relatedTransport.role,
|
|
9290
|
+
origin: relatedTransport.origin,
|
|
9291
|
+
protocols: relatedTransport.protocols ?? ["rest", "socket"],
|
|
9292
|
+
security_profile: relatedTransport.securityProfile ?? null,
|
|
9293
|
+
auth_strategy: relatedTransport.authStrategy ?? null
|
|
9294
|
+
}
|
|
9295
|
+
] : []
|
|
8580
9296
|
}
|
|
8581
9297
|
});
|
|
8582
9298
|
});
|
|
@@ -8597,7 +9313,9 @@ var CadenzaService = class {
|
|
|
8597
9313
|
__networkMode: options.networkMode,
|
|
8598
9314
|
__retryCount: options.retryCount,
|
|
8599
9315
|
__cadenzaDBConnect: options.cadenzaDB?.connect,
|
|
8600
|
-
__isDatabase: options.isDatabase
|
|
9316
|
+
__isDatabase: options.isDatabase,
|
|
9317
|
+
__isFrontend: isFrontend,
|
|
9318
|
+
__declaredTransports: declaredTransports
|
|
8601
9319
|
};
|
|
8602
9320
|
if (options.cadenzaDB?.connect) {
|
|
8603
9321
|
this.createEphemeralMetaTask("Create service", async (context, emit) => {
|
|
@@ -8613,12 +9331,42 @@ var CadenzaService = class {
|
|
|
8613
9331
|
}).doOn("meta.rest.handshake");
|
|
8614
9332
|
}
|
|
8615
9333
|
this.createMetaTask("Handle service setup completion", () => {
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
9334
|
+
if (isFrontend) {
|
|
9335
|
+
registerActorSessionPersistenceTasks();
|
|
9336
|
+
this.ensureFrontendSyncLoop();
|
|
9337
|
+
} else {
|
|
9338
|
+
GraphMetadataController.instance;
|
|
9339
|
+
GraphSyncController.instance.isCadenzaDBReady = !!options.cadenzaDB?.connect;
|
|
9340
|
+
GraphSyncController.instance.init();
|
|
9341
|
+
}
|
|
8619
9342
|
this.log("Service created.");
|
|
8620
9343
|
return true;
|
|
8621
9344
|
}).doOn("meta.service_registry.instance_inserted");
|
|
9345
|
+
if (!options.cadenzaDB?.connect && isFrontend) {
|
|
9346
|
+
Cadenza.schedule(
|
|
9347
|
+
"meta.service_registry.instance_registration_requested",
|
|
9348
|
+
{
|
|
9349
|
+
data: {
|
|
9350
|
+
uuid: serviceId,
|
|
9351
|
+
process_pid: 1,
|
|
9352
|
+
service_name: serviceName,
|
|
9353
|
+
is_frontend: true,
|
|
9354
|
+
is_active: true,
|
|
9355
|
+
is_non_responsive: false,
|
|
9356
|
+
is_blocked: false,
|
|
9357
|
+
health: {}
|
|
9358
|
+
},
|
|
9359
|
+
transportData: [],
|
|
9360
|
+
__serviceName: serviceName,
|
|
9361
|
+
__serviceInstanceId: serviceId,
|
|
9362
|
+
__useSocket: options.useSocket,
|
|
9363
|
+
__retryCount: options.retryCount,
|
|
9364
|
+
__isFrontend: true,
|
|
9365
|
+
__skipRemoteExecution: true
|
|
9366
|
+
},
|
|
9367
|
+
0
|
|
9368
|
+
);
|
|
9369
|
+
}
|
|
8622
9370
|
this.serviceCreated = true;
|
|
8623
9371
|
}
|
|
8624
9372
|
/**
|
|
@@ -8644,9 +9392,9 @@ var CadenzaService = class {
|
|
|
8644
9392
|
* @return {void}
|
|
8645
9393
|
*/
|
|
8646
9394
|
static createPostgresActor(name, schema, description = "", options = {}) {
|
|
8647
|
-
if (isBrowser) {
|
|
9395
|
+
if (isBrowser || options.isFrontend) {
|
|
8648
9396
|
console.warn(
|
|
8649
|
-
"PostgresActor creation is not supported in
|
|
9397
|
+
"PostgresActor creation is not supported in frontend mode."
|
|
8650
9398
|
);
|
|
8651
9399
|
return;
|
|
8652
9400
|
}
|
|
@@ -8691,9 +9439,9 @@ var CadenzaService = class {
|
|
|
8691
9439
|
* Creates a dedicated database service by composing a PostgresActor and a Cadenza service.
|
|
8692
9440
|
*/
|
|
8693
9441
|
static createDatabaseService(name, schema, description = "", options = {}) {
|
|
8694
|
-
if (isBrowser) {
|
|
9442
|
+
if (isBrowser || options.isFrontend) {
|
|
8695
9443
|
console.warn(
|
|
8696
|
-
"Database service creation is not supported in
|
|
9444
|
+
"Database service creation is not supported in frontend mode. Use the CadenzaDB service instead."
|
|
8697
9445
|
);
|
|
8698
9446
|
return;
|
|
8699
9447
|
}
|
|
@@ -8788,7 +9536,7 @@ var CadenzaService = class {
|
|
|
8788
9536
|
retryCount: 3,
|
|
8789
9537
|
databaseType: "postgres",
|
|
8790
9538
|
databaseName: snakeCase2(name),
|
|
8791
|
-
poolSize:
|
|
9539
|
+
poolSize: readIntegerEnv("DATABASE_POOL_SIZE", 10),
|
|
8792
9540
|
ownerServiceName: options.ownerServiceName ?? this.serviceRegistry?.serviceName ?? null,
|
|
8793
9541
|
...options
|
|
8794
9542
|
};
|
|
@@ -8799,18 +9547,16 @@ var CadenzaService = class {
|
|
|
8799
9547
|
useSocket: true,
|
|
8800
9548
|
displayName: void 0,
|
|
8801
9549
|
isMeta: false,
|
|
8802
|
-
port:
|
|
8803
|
-
securityProfile:
|
|
8804
|
-
networkMode:
|
|
9550
|
+
port: readIntegerEnv("HTTP_PORT", 3e3),
|
|
9551
|
+
securityProfile: readStringEnv("SECURITY_PROFILE") ?? "medium",
|
|
9552
|
+
networkMode: readStringEnv("NETWORK_MODE") ?? "dev",
|
|
8805
9553
|
retryCount: 3,
|
|
8806
9554
|
cadenzaDB: {
|
|
8807
|
-
connect: true
|
|
8808
|
-
address: process.env.CADENZA_DB_ADDRESS ?? "localhost",
|
|
8809
|
-
port: parseInt(process.env.CADENZA_DB_PORT ?? "5000")
|
|
9555
|
+
connect: true
|
|
8810
9556
|
},
|
|
8811
9557
|
databaseType: "postgres",
|
|
8812
9558
|
databaseName: snakeCase2(name),
|
|
8813
|
-
poolSize:
|
|
9559
|
+
poolSize: readIntegerEnv("DATABASE_POOL_SIZE", 10),
|
|
8814
9560
|
isDatabase: true,
|
|
8815
9561
|
ownerServiceName: options.ownerServiceName ?? name,
|
|
8816
9562
|
...options
|
|
@@ -9258,12 +10004,19 @@ var CadenzaService = class {
|
|
|
9258
10004
|
}
|
|
9259
10005
|
static reset() {
|
|
9260
10006
|
Cadenza.reset();
|
|
9261
|
-
this.serviceRegistry
|
|
10007
|
+
this.serviceRegistry?.reset();
|
|
10008
|
+
this.isBootstrapped = false;
|
|
10009
|
+
this.serviceCreated = false;
|
|
10010
|
+
this.warnedInvalidMetaIntentResponderKeys = /* @__PURE__ */ new Set();
|
|
10011
|
+
this.hydratedInquiryResults = /* @__PURE__ */ new Map();
|
|
10012
|
+
this.frontendSyncScheduled = false;
|
|
9262
10013
|
}
|
|
9263
10014
|
};
|
|
9264
10015
|
CadenzaService.isBootstrapped = false;
|
|
9265
10016
|
CadenzaService.serviceCreated = false;
|
|
9266
10017
|
CadenzaService.warnedInvalidMetaIntentResponderKeys = /* @__PURE__ */ new Set();
|
|
10018
|
+
CadenzaService.hydratedInquiryResults = /* @__PURE__ */ new Map();
|
|
10019
|
+
CadenzaService.frontendSyncScheduled = false;
|
|
9267
10020
|
|
|
9268
10021
|
// src/index.ts
|
|
9269
10022
|
import {
|
|
@@ -9273,9 +10026,274 @@ import {
|
|
|
9273
10026
|
GraphRoutine as GraphRoutine2,
|
|
9274
10027
|
Task as Task4
|
|
9275
10028
|
} from "@cadenza.io/core";
|
|
10029
|
+
|
|
10030
|
+
// src/ssr/createSSRInquiryBridge.ts
|
|
10031
|
+
import { v4 as uuid4 } from "uuid";
|
|
10032
|
+
function ensureFetch() {
|
|
10033
|
+
if (typeof globalThis.fetch !== "function") {
|
|
10034
|
+
throw new Error("SSR inquiry bridge requires global fetch support.");
|
|
10035
|
+
}
|
|
10036
|
+
return globalThis.fetch.bind(globalThis);
|
|
10037
|
+
}
|
|
10038
|
+
function normalizeArrayResponse(value, keys) {
|
|
10039
|
+
for (const key of keys) {
|
|
10040
|
+
if (Array.isArray(value?.[key])) {
|
|
10041
|
+
return value[key];
|
|
10042
|
+
}
|
|
10043
|
+
}
|
|
10044
|
+
if (Array.isArray(value?.rows)) {
|
|
10045
|
+
return value.rows;
|
|
10046
|
+
}
|
|
10047
|
+
if (Array.isArray(value?.data)) {
|
|
10048
|
+
return value.data;
|
|
10049
|
+
}
|
|
10050
|
+
return [];
|
|
10051
|
+
}
|
|
10052
|
+
function normalizeIntentMap(raw) {
|
|
10053
|
+
const intentName = String(raw.intentName ?? raw.intent_name ?? "").trim();
|
|
10054
|
+
const serviceName = String(raw.serviceName ?? raw.service_name ?? "").trim();
|
|
10055
|
+
const taskName = String(raw.taskName ?? raw.task_name ?? "").trim();
|
|
10056
|
+
const taskVersion = Math.max(
|
|
10057
|
+
1,
|
|
10058
|
+
Math.trunc(Number(raw.taskVersion ?? raw.task_version ?? 1) || 1)
|
|
10059
|
+
);
|
|
10060
|
+
if (!intentName || !serviceName || !taskName) {
|
|
10061
|
+
return null;
|
|
10062
|
+
}
|
|
10063
|
+
return {
|
|
10064
|
+
intentName,
|
|
10065
|
+
serviceName,
|
|
10066
|
+
taskName,
|
|
10067
|
+
taskVersion,
|
|
10068
|
+
deleted: Boolean(raw.deleted)
|
|
10069
|
+
};
|
|
10070
|
+
}
|
|
10071
|
+
function buildInquiryMeta(inquiry, startedAt, statuses) {
|
|
10072
|
+
const counts = summarizeResponderStatuses(statuses);
|
|
10073
|
+
return {
|
|
10074
|
+
inquiry,
|
|
10075
|
+
isMetaInquiry: isMetaIntentName(inquiry),
|
|
10076
|
+
totalResponders: statuses.length,
|
|
10077
|
+
eligibleResponders: statuses.length,
|
|
10078
|
+
filteredOutResponders: 0,
|
|
10079
|
+
responded: counts.responded,
|
|
10080
|
+
failed: counts.failed,
|
|
10081
|
+
timedOut: counts.timedOut,
|
|
10082
|
+
pending: counts.pending,
|
|
10083
|
+
durationMs: Date.now() - startedAt,
|
|
10084
|
+
responders: statuses
|
|
10085
|
+
};
|
|
10086
|
+
}
|
|
10087
|
+
function createSSRInquiryBridge(options = {}) {
|
|
10088
|
+
const bootstrapEndpoint = resolveBootstrapEndpoint({
|
|
10089
|
+
runtime: "server",
|
|
10090
|
+
bootstrap: options.bootstrap,
|
|
10091
|
+
cadenzaDB: options.cadenzaDB
|
|
10092
|
+
});
|
|
10093
|
+
const fetchImplementation = ensureFetch();
|
|
10094
|
+
const initialInquiryResults = {};
|
|
10095
|
+
const postDelegation = async (targetUrl, remoteRoutineName, context, timeoutMs) => {
|
|
10096
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
10097
|
+
const response = await fetchImplementation(`${targetUrl}/delegation`, {
|
|
10098
|
+
method: "POST",
|
|
10099
|
+
headers: {
|
|
10100
|
+
"Content-Type": "application/json"
|
|
10101
|
+
},
|
|
10102
|
+
body: JSON.stringify({
|
|
10103
|
+
...context,
|
|
10104
|
+
__remoteRoutineName: remoteRoutineName,
|
|
10105
|
+
__metadata: {
|
|
10106
|
+
...context.__metadata ?? {},
|
|
10107
|
+
__deputyExecId: uuid4()
|
|
10108
|
+
}
|
|
10109
|
+
}),
|
|
10110
|
+
signal
|
|
10111
|
+
});
|
|
10112
|
+
return await response.json();
|
|
10113
|
+
};
|
|
10114
|
+
const queryTable = async (tableName, queryData, timeoutMs) => {
|
|
10115
|
+
const response = await postDelegation(
|
|
10116
|
+
bootstrapEndpoint.url,
|
|
10117
|
+
`Query ${tableName}`,
|
|
10118
|
+
{ queryData },
|
|
10119
|
+
timeoutMs
|
|
10120
|
+
);
|
|
10121
|
+
return normalizeArrayResponse(response, [
|
|
10122
|
+
`${tableName}Rows`,
|
|
10123
|
+
`${tableName}s`,
|
|
10124
|
+
tableName,
|
|
10125
|
+
tableName.replace(/_([a-z])/g, (_match, char) => char.toUpperCase())
|
|
10126
|
+
]);
|
|
10127
|
+
};
|
|
10128
|
+
return {
|
|
10129
|
+
async inquire(inquiry, context = {}, inquiryOptions = {}) {
|
|
10130
|
+
const startedAt = Date.now();
|
|
10131
|
+
const overallTimeoutMs = inquiryOptions.overallTimeoutMs ?? inquiryOptions.timeout ?? 3e4;
|
|
10132
|
+
const perResponderTimeoutMs = inquiryOptions.perResponderTimeoutMs ?? overallTimeoutMs;
|
|
10133
|
+
const intentMaps = (await queryTable(
|
|
10134
|
+
"intent_to_task_map",
|
|
10135
|
+
{
|
|
10136
|
+
filter: {
|
|
10137
|
+
intent_name: inquiry
|
|
10138
|
+
}
|
|
10139
|
+
},
|
|
10140
|
+
overallTimeoutMs
|
|
10141
|
+
)).map(normalizeIntentMap).filter(
|
|
10142
|
+
(item) => !!item && item.intentName === inquiry && !item.deleted
|
|
10143
|
+
);
|
|
10144
|
+
if (intentMaps.length === 0) {
|
|
10145
|
+
return {
|
|
10146
|
+
__inquiryMeta: buildInquiryMeta(inquiry, startedAt, [])
|
|
10147
|
+
};
|
|
10148
|
+
}
|
|
10149
|
+
const relevantServiceNames = Array.from(
|
|
10150
|
+
new Set(intentMaps.map((item) => item.serviceName))
|
|
10151
|
+
);
|
|
10152
|
+
const rawServiceInstances = await queryTable(
|
|
10153
|
+
"service_instance",
|
|
10154
|
+
{
|
|
10155
|
+
filter: {
|
|
10156
|
+
service_name: relevantServiceNames
|
|
10157
|
+
}
|
|
10158
|
+
},
|
|
10159
|
+
overallTimeoutMs
|
|
10160
|
+
);
|
|
10161
|
+
const rawServiceTransports = await queryTable(
|
|
10162
|
+
"service_instance_transport",
|
|
10163
|
+
{
|
|
10164
|
+
filter: {
|
|
10165
|
+
deleted: false
|
|
10166
|
+
}
|
|
10167
|
+
},
|
|
10168
|
+
overallTimeoutMs
|
|
10169
|
+
);
|
|
10170
|
+
const transportsByInstance = /* @__PURE__ */ new Map();
|
|
10171
|
+
for (const transport of rawServiceTransports) {
|
|
10172
|
+
const serviceInstanceId = String(
|
|
10173
|
+
transport.serviceInstanceId ?? transport.service_instance_id ?? ""
|
|
10174
|
+
).trim();
|
|
10175
|
+
if (!serviceInstanceId) {
|
|
10176
|
+
continue;
|
|
10177
|
+
}
|
|
10178
|
+
if (!transportsByInstance.has(serviceInstanceId)) {
|
|
10179
|
+
transportsByInstance.set(serviceInstanceId, []);
|
|
10180
|
+
}
|
|
10181
|
+
transportsByInstance.get(serviceInstanceId).push(transport);
|
|
10182
|
+
}
|
|
10183
|
+
const serviceInstances = rawServiceInstances.map(
|
|
10184
|
+
(instance) => normalizeServiceInstanceDescriptor({
|
|
10185
|
+
...instance,
|
|
10186
|
+
transports: transportsByInstance.get(String(instance.uuid ?? "").trim()) ?? []
|
|
10187
|
+
})
|
|
10188
|
+
).filter(
|
|
10189
|
+
(item) => !!item && relevantServiceNames.includes(item.serviceName) && item.isActive && !item.isNonResponsive && !item.isBlocked
|
|
10190
|
+
).sort((left, right) => {
|
|
10191
|
+
if (left.serviceName !== right.serviceName) {
|
|
10192
|
+
return left.serviceName.localeCompare(right.serviceName);
|
|
10193
|
+
}
|
|
10194
|
+
if (left.isPrimary !== right.isPrimary) {
|
|
10195
|
+
return left.isPrimary ? -1 : 1;
|
|
10196
|
+
}
|
|
10197
|
+
return (left.numberOfRunningGraphs ?? 0) - (right.numberOfRunningGraphs ?? 0);
|
|
10198
|
+
});
|
|
10199
|
+
const statuses = intentMaps.map((map) => ({
|
|
10200
|
+
isRemote: true,
|
|
10201
|
+
serviceName: map.serviceName,
|
|
10202
|
+
taskName: map.taskName,
|
|
10203
|
+
taskVersion: map.taskVersion,
|
|
10204
|
+
localTaskName: `SSR inquiry via ${map.serviceName} (${map.taskName} v${map.taskVersion})`,
|
|
10205
|
+
status: "timed_out",
|
|
10206
|
+
durationMs: 0
|
|
10207
|
+
}));
|
|
10208
|
+
const fulfilledContexts = await Promise.all(
|
|
10209
|
+
intentMaps.map(async (map, index) => {
|
|
10210
|
+
const status = statuses[index];
|
|
10211
|
+
const startedAtForResponder = Date.now();
|
|
10212
|
+
const selectedInstance = serviceInstances.find(
|
|
10213
|
+
(instance) => instance.serviceName === map.serviceName
|
|
10214
|
+
);
|
|
10215
|
+
if (!selectedInstance) {
|
|
10216
|
+
status.status = "failed";
|
|
10217
|
+
status.error = `No active instances for ${map.serviceName}`;
|
|
10218
|
+
status.durationMs = Date.now() - startedAtForResponder;
|
|
10219
|
+
return null;
|
|
10220
|
+
}
|
|
10221
|
+
const targetTransport = selectTransportForRole(
|
|
10222
|
+
selectedInstance.transports,
|
|
10223
|
+
"internal",
|
|
10224
|
+
"rest"
|
|
10225
|
+
);
|
|
10226
|
+
if (!targetTransport) {
|
|
10227
|
+
status.status = "failed";
|
|
10228
|
+
status.error = `No internal transport for ${selectedInstance.serviceName}/${selectedInstance.uuid}`;
|
|
10229
|
+
status.durationMs = Date.now() - startedAtForResponder;
|
|
10230
|
+
return null;
|
|
10231
|
+
}
|
|
10232
|
+
const targetUrl = targetTransport.origin;
|
|
10233
|
+
try {
|
|
10234
|
+
const result = await postDelegation(
|
|
10235
|
+
targetUrl,
|
|
10236
|
+
map.taskName,
|
|
10237
|
+
context,
|
|
10238
|
+
perResponderTimeoutMs
|
|
10239
|
+
);
|
|
10240
|
+
status.durationMs = Date.now() - startedAtForResponder;
|
|
10241
|
+
if (result?.errored || result?.failed) {
|
|
10242
|
+
status.status = "failed";
|
|
10243
|
+
status.error = String(
|
|
10244
|
+
result?.__error ?? result?.error ?? "Remote inquiry failed"
|
|
10245
|
+
);
|
|
10246
|
+
return null;
|
|
10247
|
+
}
|
|
10248
|
+
status.status = "fulfilled";
|
|
10249
|
+
return result;
|
|
10250
|
+
} catch (error) {
|
|
10251
|
+
status.durationMs = Date.now() - startedAtForResponder;
|
|
10252
|
+
if (error instanceof Error && (error.name === "AbortError" || /timed out/i.test(error.message))) {
|
|
10253
|
+
status.status = "timed_out";
|
|
10254
|
+
status.error = error.message;
|
|
10255
|
+
return null;
|
|
10256
|
+
}
|
|
10257
|
+
status.status = "failed";
|
|
10258
|
+
status.error = error instanceof Error ? error.message : String(error);
|
|
10259
|
+
return null;
|
|
10260
|
+
}
|
|
10261
|
+
})
|
|
10262
|
+
);
|
|
10263
|
+
const mergedContext = mergeInquiryContexts(
|
|
10264
|
+
fulfilledContexts.filter(
|
|
10265
|
+
(item) => item !== null
|
|
10266
|
+
)
|
|
10267
|
+
);
|
|
10268
|
+
const responseContext = {
|
|
10269
|
+
...mergedContext,
|
|
10270
|
+
__inquiryMeta: buildInquiryMeta(inquiry, startedAt, statuses)
|
|
10271
|
+
};
|
|
10272
|
+
if (inquiryOptions.hydrationKey) {
|
|
10273
|
+
initialInquiryResults[inquiryOptions.hydrationKey] = responseContext;
|
|
10274
|
+
}
|
|
10275
|
+
if (inquiryOptions.requireComplete && statuses.some((status) => status.status !== "fulfilled")) {
|
|
10276
|
+
throw {
|
|
10277
|
+
...responseContext,
|
|
10278
|
+
__error: `Inquiry '${inquiry}' did not complete successfully`,
|
|
10279
|
+
errored: true
|
|
10280
|
+
};
|
|
10281
|
+
}
|
|
10282
|
+
return responseContext;
|
|
10283
|
+
},
|
|
10284
|
+
dehydrate() {
|
|
10285
|
+
return {
|
|
10286
|
+
initialInquiryResults: { ...initialInquiryResults }
|
|
10287
|
+
};
|
|
10288
|
+
}
|
|
10289
|
+
};
|
|
10290
|
+
}
|
|
10291
|
+
|
|
10292
|
+
// src/index.ts
|
|
9276
10293
|
var index_default = CadenzaService;
|
|
9277
10294
|
export {
|
|
9278
10295
|
Actor2 as Actor,
|
|
10296
|
+
DatabaseController,
|
|
9279
10297
|
DatabaseTask,
|
|
9280
10298
|
DebounceTask2 as DebounceTask,
|
|
9281
10299
|
DeputyTask,
|
|
@@ -9288,6 +10306,7 @@ export {
|
|
|
9288
10306
|
SignalTransmissionTask,
|
|
9289
10307
|
SocketController,
|
|
9290
10308
|
Task4 as Task,
|
|
10309
|
+
createSSRInquiryBridge,
|
|
9291
10310
|
index_default as default
|
|
9292
10311
|
};
|
|
9293
10312
|
//# sourceMappingURL=index.mjs.map
|