@cadenza.io/service 2.3.16 → 2.4.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/dist/index.d.mts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +518 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +518 -93
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -329,12 +329,11 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
329
329
|
deleted
|
|
330
330
|
} = serviceInstance;
|
|
331
331
|
if (uuid4 === this.serviceInstanceId) return;
|
|
332
|
-
console.log("service instance", serviceName, uuid4, address);
|
|
333
332
|
if (deleted) {
|
|
334
|
-
this.instances.get(serviceName)?.
|
|
335
|
-
|
|
336
|
-
1
|
|
337
|
-
|
|
333
|
+
const indexToDelete = this.instances.get(serviceName)?.findIndex((i) => i.uuid === uuid4) ?? -1;
|
|
334
|
+
if (indexToDelete >= 0) {
|
|
335
|
+
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
336
|
+
}
|
|
338
337
|
if (this.instances.get(serviceName)?.length === 0) {
|
|
339
338
|
this.instances.delete(serviceName);
|
|
340
339
|
} else if (this.instances.get(serviceName)?.filter((i) => i.address === address && i.port === port).length === 0) {
|
|
@@ -377,7 +376,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
377
376
|
communicationTypes
|
|
378
377
|
});
|
|
379
378
|
instances?.filter(
|
|
380
|
-
(i) => i.address === address && i.port === port && i.
|
|
379
|
+
(i) => i.address === address && i.port === port && i.isActive
|
|
381
380
|
).forEach((i) => {
|
|
382
381
|
i.clientCreated = true;
|
|
383
382
|
});
|
|
@@ -409,7 +408,6 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
409
408
|
this.handleGlobalSignalRegistrationTask = CadenzaService.createMetaTask(
|
|
410
409
|
"Handle global Signal Registration",
|
|
411
410
|
(ctx) => {
|
|
412
|
-
console.log("Handling global signal registration...");
|
|
413
411
|
const { signalToTaskMaps } = ctx;
|
|
414
412
|
const sortedSignalToTaskMap = signalToTaskMaps.sort(
|
|
415
413
|
(a, b) => {
|
|
@@ -418,9 +416,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
418
416
|
return 0;
|
|
419
417
|
}
|
|
420
418
|
);
|
|
421
|
-
console.log(sortedSignalToTaskMap);
|
|
422
419
|
const locallyEmittedSignals = CadenzaService.signalBroker.listEmittedSignals().filter((s) => s.startsWith("global."));
|
|
423
|
-
console.log(locallyEmittedSignals);
|
|
424
420
|
for (const map of sortedSignalToTaskMap) {
|
|
425
421
|
if (map.deleted) {
|
|
426
422
|
this.remoteSignals.get(map.serviceName)?.delete(map.signalName);
|
|
@@ -437,9 +433,6 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
437
433
|
this.remoteSignals.set(map.serviceName, /* @__PURE__ */ new Set());
|
|
438
434
|
}
|
|
439
435
|
if (!this.remoteSignals.get(map.serviceName)?.has(map.signalName)) {
|
|
440
|
-
console.log(
|
|
441
|
-
`Creating signal transmission task for: ${map.signalName} to ${map.serviceName}`
|
|
442
|
-
);
|
|
443
436
|
CadenzaService.createSignalTransmissionTask(
|
|
444
437
|
map.signalName,
|
|
445
438
|
map.serviceName
|
|
@@ -487,7 +480,12 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
487
480
|
return true;
|
|
488
481
|
},
|
|
489
482
|
"Handles service not responding"
|
|
490
|
-
).doOn(
|
|
483
|
+
).doOn(
|
|
484
|
+
"meta.fetch.handshake_failed",
|
|
485
|
+
"meta.fetch.handshake_failed.*",
|
|
486
|
+
"meta.socket_client.disconnected",
|
|
487
|
+
"meta.socket_client.disconnected.*"
|
|
488
|
+
).attachSignal("global.meta.service_registry.service_not_responding");
|
|
491
489
|
this.handleServiceHandshakeTask = CadenzaService.createMetaTask(
|
|
492
490
|
"Handle service handshake",
|
|
493
491
|
(ctx, emit) => {
|
|
@@ -514,7 +512,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
514
512
|
(i) => i.uuid !== serviceInstanceId && i.address === serviceAddress && i.port === servicePort
|
|
515
513
|
);
|
|
516
514
|
for (const i of instancesToDelete ?? []) {
|
|
517
|
-
this.instances.get(serviceName)?.
|
|
515
|
+
const indexToDelete = this.instances.get(serviceName)?.indexOf(i) ?? -1;
|
|
516
|
+
if (indexToDelete >= 0) {
|
|
517
|
+
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
518
|
+
}
|
|
518
519
|
emit("global.meta.service_registry.deleted", {
|
|
519
520
|
data: {
|
|
520
521
|
isActive: false,
|
|
@@ -551,23 +552,14 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
551
552
|
const mergeSyncDataTask = CadenzaService.createUniqueMetaTask(
|
|
552
553
|
"Merge sync data",
|
|
553
554
|
(ctx) => {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
console.log("merging contexts of full sync...", joinedContext);
|
|
560
|
-
return joinedContext;
|
|
561
|
-
} catch (e) {
|
|
562
|
-
console.log("Error", e.message, ctx);
|
|
563
|
-
return false;
|
|
564
|
-
}
|
|
555
|
+
let joinedContext = {};
|
|
556
|
+
ctx.joinedContexts.forEach((ctx2) => {
|
|
557
|
+
joinedContext = { ...joinedContext, ...ctx2 };
|
|
558
|
+
});
|
|
559
|
+
return joinedContext;
|
|
565
560
|
}
|
|
566
561
|
).emits("meta.service_registry.initial_sync_complete").then(this.handleGlobalSignalRegistrationTask);
|
|
567
562
|
this.fullSyncTask = CadenzaService.createMetaRoutine("Full sync", [
|
|
568
|
-
CadenzaService.createTask("Confirm full sync", () => {
|
|
569
|
-
console.log("Confirming full sync...");
|
|
570
|
-
}),
|
|
571
563
|
CadenzaService.createCadenzaDBQueryTask("signal_to_task_map", {
|
|
572
564
|
filter: {
|
|
573
565
|
isGlobal: true
|
|
@@ -683,8 +675,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
683
675
|
}
|
|
684
676
|
if (__broadcast || instances[0].isFrontend) {
|
|
685
677
|
for (const instance of instances) {
|
|
678
|
+
const socketKey = instance.isFrontend ? instance.address : `${instance.address}_${instance.port}`;
|
|
686
679
|
emit(
|
|
687
|
-
`meta.service_registry.selected_instance_for_socket:${
|
|
680
|
+
`meta.service_registry.selected_instance_for_socket:${socketKey}`,
|
|
688
681
|
context
|
|
689
682
|
);
|
|
690
683
|
}
|
|
@@ -1675,6 +1668,46 @@ var RestController = class _RestController {
|
|
|
1675
1668
|
var import_socket = require("socket.io");
|
|
1676
1669
|
var import_rate_limiter_flexible2 = require("rate-limiter-flexible");
|
|
1677
1670
|
var import_socket2 = require("socket.io-client");
|
|
1671
|
+
|
|
1672
|
+
// src/network/socketClientUtils.ts
|
|
1673
|
+
var waitForSocketConnection = async (socket, timeoutMs, createError) => {
|
|
1674
|
+
if (!socket) {
|
|
1675
|
+
return { ok: false, error: createError("disconnected") };
|
|
1676
|
+
}
|
|
1677
|
+
if (socket.connected) {
|
|
1678
|
+
return { ok: true };
|
|
1679
|
+
}
|
|
1680
|
+
return new Promise((resolve) => {
|
|
1681
|
+
let timer = null;
|
|
1682
|
+
let settled = false;
|
|
1683
|
+
const cleanup = () => {
|
|
1684
|
+
if (timer) {
|
|
1685
|
+
clearTimeout(timer);
|
|
1686
|
+
timer = null;
|
|
1687
|
+
}
|
|
1688
|
+
socket.off("connect", onConnect);
|
|
1689
|
+
socket.off("connect_error", onConnectError);
|
|
1690
|
+
socket.off("disconnect", onDisconnect);
|
|
1691
|
+
};
|
|
1692
|
+
const settle = (outcome) => {
|
|
1693
|
+
if (settled) return;
|
|
1694
|
+
settled = true;
|
|
1695
|
+
cleanup();
|
|
1696
|
+
resolve(outcome);
|
|
1697
|
+
};
|
|
1698
|
+
const onConnect = () => settle({ ok: true });
|
|
1699
|
+
const onConnectError = (error) => settle({ ok: false, error: createError("connect_error", error) });
|
|
1700
|
+
const onDisconnect = () => settle({ ok: false, error: createError("disconnected") });
|
|
1701
|
+
socket.once("connect", onConnect);
|
|
1702
|
+
socket.once("connect_error", onConnectError);
|
|
1703
|
+
socket.once("disconnect", onDisconnect);
|
|
1704
|
+
timer = setTimeout(() => {
|
|
1705
|
+
settle({ ok: false, error: createError("connect_timeout") });
|
|
1706
|
+
}, timeoutMs);
|
|
1707
|
+
});
|
|
1708
|
+
};
|
|
1709
|
+
|
|
1710
|
+
// src/network/SocketController.ts
|
|
1678
1711
|
var SocketController = class _SocketController {
|
|
1679
1712
|
static get instance() {
|
|
1680
1713
|
if (!this._instance) this._instance = new _SocketController();
|
|
@@ -1811,10 +1844,6 @@ var SocketController = class _SocketController {
|
|
|
1811
1844
|
"delegation",
|
|
1812
1845
|
(ctx2, callback) => {
|
|
1813
1846
|
const deputyExecId = ctx2.__metadata.__deputyExecId;
|
|
1814
|
-
console.log(
|
|
1815
|
-
"Delegation request received:",
|
|
1816
|
-
ctx2.__localTaskName
|
|
1817
|
-
);
|
|
1818
1847
|
CadenzaService.createEphemeralMetaTask(
|
|
1819
1848
|
"Resolve delegation",
|
|
1820
1849
|
(ctx3) => {
|
|
@@ -1849,7 +1878,6 @@ var SocketController = class _SocketController {
|
|
|
1849
1878
|
"signal",
|
|
1850
1879
|
(ctx2, callback) => {
|
|
1851
1880
|
if (CadenzaService.signalBroker.listObservedSignals().includes(ctx2.__signalName)) {
|
|
1852
|
-
console.log("Signal received:", ctx2.__signalName);
|
|
1853
1881
|
callback({
|
|
1854
1882
|
__status: "success",
|
|
1855
1883
|
__signalName: ctx2.__signalName
|
|
@@ -1955,35 +1983,71 @@ var SocketController = class _SocketController {
|
|
|
1955
1983
|
});
|
|
1956
1984
|
emitWhenReady = (event, data, timeoutMs = 6e4, ack) => {
|
|
1957
1985
|
return new Promise((resolve) => {
|
|
1958
|
-
const
|
|
1959
|
-
|
|
1960
|
-
|
|
1986
|
+
const resolveWithError = (errorMessage, fallbackError) => {
|
|
1987
|
+
resolve({
|
|
1988
|
+
...data,
|
|
1989
|
+
errored: true,
|
|
1990
|
+
__error: errorMessage,
|
|
1991
|
+
error: fallbackError instanceof Error ? fallbackError.message : errorMessage,
|
|
1992
|
+
socketId: socket?.id,
|
|
1993
|
+
serviceName,
|
|
1994
|
+
URL
|
|
1995
|
+
});
|
|
1996
|
+
};
|
|
1997
|
+
const tryEmit = async () => {
|
|
1998
|
+
const waitTimeoutMs = timeoutMs > 0 ? timeoutMs + 10 : 1e4;
|
|
1999
|
+
const waitResult = await waitForSocketConnection(
|
|
2000
|
+
socket,
|
|
2001
|
+
waitTimeoutMs,
|
|
2002
|
+
(reason, error) => {
|
|
2003
|
+
if (reason === "connect_timeout") {
|
|
2004
|
+
return `Socket connect timed out before '${event}'`;
|
|
2005
|
+
}
|
|
2006
|
+
if (reason === "connect_error") {
|
|
2007
|
+
const errMessage = error instanceof Error ? error.message : String(error);
|
|
2008
|
+
return `Socket connect error before '${event}': ${errMessage}`;
|
|
2009
|
+
}
|
|
2010
|
+
return `Socket disconnected before '${event}'`;
|
|
2011
|
+
}
|
|
2012
|
+
);
|
|
2013
|
+
if (!waitResult.ok) {
|
|
2014
|
+
CadenzaService.log(
|
|
2015
|
+
waitResult.error,
|
|
2016
|
+
{ socketId: socket?.id, serviceName, URL, event },
|
|
2017
|
+
"error"
|
|
2018
|
+
);
|
|
2019
|
+
resolveWithError(waitResult.error);
|
|
1961
2020
|
return;
|
|
1962
2021
|
}
|
|
1963
|
-
let timer;
|
|
2022
|
+
let timer = null;
|
|
1964
2023
|
if (timeoutMs !== 0) {
|
|
1965
2024
|
timer = setTimeout(() => {
|
|
2025
|
+
if (timer) {
|
|
2026
|
+
pendingTimers.delete(timer);
|
|
2027
|
+
timer = null;
|
|
2028
|
+
}
|
|
1966
2029
|
CadenzaService.log(
|
|
1967
2030
|
`Socket event '${event}' timed out`,
|
|
1968
2031
|
{ socketId: socket?.id, serviceName, URL },
|
|
1969
2032
|
"error"
|
|
1970
2033
|
);
|
|
1971
|
-
|
|
1972
|
-
...data,
|
|
1973
|
-
errored: true,
|
|
1974
|
-
__error: `Socket event '${event}' timed out`,
|
|
1975
|
-
error: `Socket event '${event}' timed out`,
|
|
1976
|
-
socketId: socket?.id,
|
|
1977
|
-
serviceName,
|
|
1978
|
-
URL
|
|
1979
|
-
});
|
|
2034
|
+
resolveWithError(`Socket event '${event}' timed out`);
|
|
1980
2035
|
}, timeoutMs + 10);
|
|
1981
2036
|
pendingTimers.add(timer);
|
|
1982
2037
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
2038
|
+
const connectedSocket = socket;
|
|
2039
|
+
if (!connectedSocket) {
|
|
2040
|
+
resolveWithError(
|
|
2041
|
+
`Socket unavailable before emitting '${event}'`
|
|
2042
|
+
);
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
connectedSocket.timeout(timeoutMs).emit(event, data, (err, response) => {
|
|
2046
|
+
if (timer) {
|
|
2047
|
+
clearTimeout(timer);
|
|
2048
|
+
pendingTimers.delete(timer);
|
|
2049
|
+
timer = null;
|
|
2050
|
+
}
|
|
1987
2051
|
if (err) {
|
|
1988
2052
|
CadenzaService.log(
|
|
1989
2053
|
"Socket timeout.",
|
|
@@ -2006,11 +2070,7 @@ var SocketController = class _SocketController {
|
|
|
2006
2070
|
resolve(response);
|
|
2007
2071
|
});
|
|
2008
2072
|
};
|
|
2009
|
-
|
|
2010
|
-
tryEmit();
|
|
2011
|
-
} else {
|
|
2012
|
-
socket?.once("connect", tryEmit);
|
|
2013
|
-
}
|
|
2073
|
+
void tryEmit();
|
|
2014
2074
|
});
|
|
2015
2075
|
};
|
|
2016
2076
|
socket.on("connect", () => {
|
|
@@ -2126,7 +2186,6 @@ var SocketController = class _SocketController {
|
|
|
2126
2186
|
delete ctx2.__broadcast;
|
|
2127
2187
|
const requestSentAt = Date.now();
|
|
2128
2188
|
pendingDelegationIds.add(ctx2.__metadata.__deputyExecId);
|
|
2129
|
-
console.log("Delegating task:", ctx2.__remoteRoutineName);
|
|
2130
2189
|
emitWhenReady?.(
|
|
2131
2190
|
"delegation",
|
|
2132
2191
|
ctx2,
|
|
@@ -2135,12 +2194,6 @@ var SocketController = class _SocketController {
|
|
|
2135
2194
|
const requestDuration = Date.now() - requestSentAt;
|
|
2136
2195
|
const metadata = resultContext.__metadata;
|
|
2137
2196
|
delete resultContext.__metadata;
|
|
2138
|
-
console.log(
|
|
2139
|
-
"Delegation response received:",
|
|
2140
|
-
ctx2.__remoteRoutineName,
|
|
2141
|
-
"Duration:",
|
|
2142
|
-
requestDuration
|
|
2143
|
-
);
|
|
2144
2197
|
emit(
|
|
2145
2198
|
`meta.socket_client.delegated:${ctx2.__metadata.__deputyExecId}`,
|
|
2146
2199
|
{
|
|
@@ -2168,7 +2221,6 @@ var SocketController = class _SocketController {
|
|
|
2168
2221
|
}
|
|
2169
2222
|
return new Promise((resolve) => {
|
|
2170
2223
|
delete ctx2.__broadcast;
|
|
2171
|
-
console.log("Transmitting signal:", ctx2.__signalName);
|
|
2172
2224
|
emitWhenReady?.("signal", ctx2, 5e3, (response) => {
|
|
2173
2225
|
if (ctx2.__routineExecId) {
|
|
2174
2226
|
emit(
|
|
@@ -2335,14 +2387,25 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2335
2387
|
return {
|
|
2336
2388
|
data: {
|
|
2337
2389
|
...ctx.data,
|
|
2338
|
-
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2390
|
+
serviceName: CadenzaService.serviceRegistry.serviceName,
|
|
2391
|
+
inputContextSchemaId: ctx.data.inputContextSchemaId ? {
|
|
2392
|
+
subOperation: "insert",
|
|
2393
|
+
table: "context_schema",
|
|
2394
|
+
data: {
|
|
2395
|
+
...ctx.data.inputContextSchemaId
|
|
2396
|
+
},
|
|
2397
|
+
return: "uuid"
|
|
2398
|
+
} : null,
|
|
2399
|
+
outputContextSchemaId: ctx.data.outputContextSchemaId ? {
|
|
2400
|
+
subOperation: "insert",
|
|
2401
|
+
table: "context_schema",
|
|
2402
|
+
data: {
|
|
2403
|
+
...ctx.data.outputContextSchemaId
|
|
2404
|
+
},
|
|
2405
|
+
return: "uuid"
|
|
2406
|
+
} : null
|
|
2407
|
+
},
|
|
2408
|
+
transaction: true
|
|
2346
2409
|
};
|
|
2347
2410
|
}).doOn("meta.task.created").emits("global.meta.graph_metadata.task_created");
|
|
2348
2411
|
CadenzaService.createMetaTask("Handle task update", (ctx) => {
|
|
@@ -2474,7 +2537,7 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2474
2537
|
data: {
|
|
2475
2538
|
...ctx.data,
|
|
2476
2539
|
serviceName: CadenzaService.serviceRegistry.serviceName,
|
|
2477
|
-
|
|
2540
|
+
serviceInstanceId: CadenzaService.serviceRegistry.serviceInstanceId
|
|
2478
2541
|
},
|
|
2479
2542
|
filter: {
|
|
2480
2543
|
...ctx.filter
|
|
@@ -3002,7 +3065,6 @@ var DatabaseController = class _DatabaseController {
|
|
|
3002
3065
|
if (ddl && ddl.length > 0) {
|
|
3003
3066
|
for (const sql of ddl) {
|
|
3004
3067
|
try {
|
|
3005
|
-
console.log("Executing DDL", sql);
|
|
3006
3068
|
await this.dbClient.query(sql);
|
|
3007
3069
|
} catch (error) {
|
|
3008
3070
|
console.error(
|
|
@@ -3651,9 +3713,9 @@ var DatabaseController = class _DatabaseController {
|
|
|
3651
3713
|
createDatabaseTask(op, tableName, table, queryFunction, options) {
|
|
3652
3714
|
const opAction = op === "query" ? "queried" : op === "insert" ? "inserted" : op === "update" ? "updated" : op === "delete" ? "deleted" : "";
|
|
3653
3715
|
const defaultSignal = `global.${options.isMeta ? "meta." : ""}${tableName}.${opAction}`;
|
|
3654
|
-
const
|
|
3655
|
-
const
|
|
3656
|
-
CadenzaService.createThrottledTask(
|
|
3716
|
+
const taskName = `${op.charAt(0).toUpperCase() + op.slice(1)} ${tableName}`;
|
|
3717
|
+
const schema = this.getInputSchema(op, tableName, table);
|
|
3718
|
+
const task = CadenzaService.createThrottledTask(
|
|
3657
3719
|
taskName,
|
|
3658
3720
|
async (context, emit) => {
|
|
3659
3721
|
for (const action of Object.keys(table.customSignals?.triggers ?? {})) {
|
|
@@ -3748,17 +3810,8 @@ var DatabaseController = class _DatabaseController {
|
|
|
3748
3810
|
{
|
|
3749
3811
|
isMeta: options.isMeta,
|
|
3750
3812
|
isSubMeta: options.isMeta,
|
|
3751
|
-
validateInputContext:
|
|
3752
|
-
|
|
3753
|
-
inputSchema: {
|
|
3754
|
-
// TODO
|
|
3755
|
-
type: "object",
|
|
3756
|
-
properties: {
|
|
3757
|
-
filter: {
|
|
3758
|
-
type: "object"
|
|
3759
|
-
}
|
|
3760
|
-
}
|
|
3761
|
-
}
|
|
3813
|
+
validateInputContext: options.securityProfile !== "low",
|
|
3814
|
+
inputSchema: schema
|
|
3762
3815
|
}
|
|
3763
3816
|
).doOn(
|
|
3764
3817
|
...table.customSignals?.triggers?.[op]?.map((signal) => {
|
|
@@ -3769,8 +3822,382 @@ var DatabaseController = class _DatabaseController {
|
|
|
3769
3822
|
return typeof signal === "string" ? signal : signal.signal;
|
|
3770
3823
|
}) ?? []
|
|
3771
3824
|
);
|
|
3825
|
+
if (op === "query") {
|
|
3826
|
+
const intentName = `query-${CadenzaService.serviceRegistry.serviceName}-${tableName}`;
|
|
3827
|
+
CadenzaService.defineIntent({
|
|
3828
|
+
name: intentName,
|
|
3829
|
+
description: `Perform a query operation on the ${tableName} table`,
|
|
3830
|
+
input: schema
|
|
3831
|
+
});
|
|
3832
|
+
task.respondsTo(intentName);
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
getInputSchema(op, tableName, table) {
|
|
3836
|
+
const inputSchema = {
|
|
3837
|
+
type: "object",
|
|
3838
|
+
properties: {
|
|
3839
|
+
queryData: {
|
|
3840
|
+
type: "object",
|
|
3841
|
+
properties: {},
|
|
3842
|
+
strict: true
|
|
3843
|
+
}
|
|
3844
|
+
},
|
|
3845
|
+
strict: true
|
|
3846
|
+
};
|
|
3847
|
+
if (!inputSchema.properties) {
|
|
3848
|
+
return inputSchema;
|
|
3849
|
+
}
|
|
3850
|
+
inputSchema.properties.transaction = getTransactionSchema();
|
|
3851
|
+
inputSchema.properties.queryData.properties.transaction = inputSchema.properties.transaction;
|
|
3852
|
+
switch (op) {
|
|
3853
|
+
case "insert":
|
|
3854
|
+
inputSchema.properties.data = getInsertDataSchemaFromTable(
|
|
3855
|
+
table,
|
|
3856
|
+
tableName
|
|
3857
|
+
);
|
|
3858
|
+
inputSchema.properties.queryData.properties.data = inputSchema.properties.data;
|
|
3859
|
+
inputSchema.properties.batch = getQueryBatchSchemaFromTable();
|
|
3860
|
+
inputSchema.properties.queryData.properties.batch = inputSchema.properties.batch;
|
|
3861
|
+
inputSchema.properties.onConflict = getQueryOnConflictSchemaFromTable(
|
|
3862
|
+
table,
|
|
3863
|
+
tableName
|
|
3864
|
+
);
|
|
3865
|
+
inputSchema.properties.queryData.properties.onConflict = inputSchema.properties.onConflict;
|
|
3866
|
+
break;
|
|
3867
|
+
case "query":
|
|
3868
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3869
|
+
table,
|
|
3870
|
+
tableName
|
|
3871
|
+
);
|
|
3872
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3873
|
+
inputSchema.properties.fields = getQueryFieldsSchemaFromTable(
|
|
3874
|
+
table,
|
|
3875
|
+
tableName
|
|
3876
|
+
);
|
|
3877
|
+
inputSchema.properties.queryData.properties.fields = inputSchema.properties.fields;
|
|
3878
|
+
inputSchema.properties.joins = getQueryJoinsSchemaFromTable(
|
|
3879
|
+
table,
|
|
3880
|
+
tableName
|
|
3881
|
+
);
|
|
3882
|
+
inputSchema.properties.queryData.properties.joins = inputSchema.properties.joins;
|
|
3883
|
+
inputSchema.properties.sort = getQuerySortSchemaFromTable(
|
|
3884
|
+
table,
|
|
3885
|
+
tableName
|
|
3886
|
+
);
|
|
3887
|
+
inputSchema.properties.queryData.properties.sort = inputSchema.properties.sort;
|
|
3888
|
+
inputSchema.properties.limit = getQueryLimitSchemaFromTable();
|
|
3889
|
+
inputSchema.properties.queryData.properties.limit = inputSchema.properties.limit;
|
|
3890
|
+
inputSchema.properties.offset = getQueryOffsetSchemaFromTable();
|
|
3891
|
+
inputSchema.properties.queryData.properties.offset = inputSchema.properties.offset;
|
|
3892
|
+
break;
|
|
3893
|
+
case "update":
|
|
3894
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3895
|
+
table,
|
|
3896
|
+
tableName
|
|
3897
|
+
);
|
|
3898
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3899
|
+
inputSchema.properties.fields = getQueryFieldsSchemaFromTable(
|
|
3900
|
+
table,
|
|
3901
|
+
tableName
|
|
3902
|
+
);
|
|
3903
|
+
inputSchema.properties.queryData.properties.fields = inputSchema.properties.fields;
|
|
3904
|
+
break;
|
|
3905
|
+
case "delete":
|
|
3906
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3907
|
+
table,
|
|
3908
|
+
tableName
|
|
3909
|
+
);
|
|
3910
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3911
|
+
break;
|
|
3912
|
+
}
|
|
3913
|
+
return inputSchema;
|
|
3772
3914
|
}
|
|
3773
3915
|
};
|
|
3916
|
+
function getInsertDataSchemaFromTable(table, tableName) {
|
|
3917
|
+
const dataSchema = {
|
|
3918
|
+
type: "object",
|
|
3919
|
+
properties: {
|
|
3920
|
+
...Object.fromEntries(
|
|
3921
|
+
Object.entries(table.fields).map((field) => {
|
|
3922
|
+
return [
|
|
3923
|
+
field[0],
|
|
3924
|
+
[
|
|
3925
|
+
{
|
|
3926
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3927
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3928
|
+
},
|
|
3929
|
+
{
|
|
3930
|
+
type: "string",
|
|
3931
|
+
constraints: {
|
|
3932
|
+
oneOf: ["increment", "decrement", "set"]
|
|
3933
|
+
}
|
|
3934
|
+
},
|
|
3935
|
+
{
|
|
3936
|
+
type: "object",
|
|
3937
|
+
properties: {
|
|
3938
|
+
subOperation: {
|
|
3939
|
+
type: "string",
|
|
3940
|
+
enum: ["insert", "query"]
|
|
3941
|
+
},
|
|
3942
|
+
table: {
|
|
3943
|
+
type: "string"
|
|
3944
|
+
},
|
|
3945
|
+
data: [
|
|
3946
|
+
{
|
|
3947
|
+
type: "object"
|
|
3948
|
+
},
|
|
3949
|
+
{
|
|
3950
|
+
type: "array",
|
|
3951
|
+
items: {
|
|
3952
|
+
type: "object"
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
],
|
|
3956
|
+
filter: {
|
|
3957
|
+
type: "object"
|
|
3958
|
+
},
|
|
3959
|
+
fields: {
|
|
3960
|
+
type: "array",
|
|
3961
|
+
items: {
|
|
3962
|
+
type: "string"
|
|
3963
|
+
}
|
|
3964
|
+
},
|
|
3965
|
+
return: {
|
|
3966
|
+
type: "string"
|
|
3967
|
+
}
|
|
3968
|
+
},
|
|
3969
|
+
required: ["subOperation", "table"]
|
|
3970
|
+
}
|
|
3971
|
+
]
|
|
3972
|
+
];
|
|
3973
|
+
})
|
|
3974
|
+
)
|
|
3975
|
+
},
|
|
3976
|
+
required: Object.entries(table.fields).filter((field) => field[1].required || field[1].primary).map((field) => field[0]),
|
|
3977
|
+
strict: true
|
|
3978
|
+
};
|
|
3979
|
+
return [
|
|
3980
|
+
dataSchema,
|
|
3981
|
+
{
|
|
3982
|
+
type: "array",
|
|
3983
|
+
items: dataSchema
|
|
3984
|
+
}
|
|
3985
|
+
];
|
|
3986
|
+
}
|
|
3987
|
+
function getQueryFilterSchemaFromTable(table, tableName) {
|
|
3988
|
+
return {
|
|
3989
|
+
type: "object",
|
|
3990
|
+
properties: {
|
|
3991
|
+
...Object.fromEntries(
|
|
3992
|
+
Object.entries(table.fields).map((field) => {
|
|
3993
|
+
return [
|
|
3994
|
+
field[0],
|
|
3995
|
+
[
|
|
3996
|
+
{
|
|
3997
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3998
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3999
|
+
},
|
|
4000
|
+
{
|
|
4001
|
+
type: "array",
|
|
4002
|
+
items: {
|
|
4003
|
+
type: tableFieldTypeToSchemaType(field[1].type)
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
]
|
|
4007
|
+
];
|
|
4008
|
+
})
|
|
4009
|
+
)
|
|
4010
|
+
},
|
|
4011
|
+
strict: true,
|
|
4012
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4013
|
+
};
|
|
4014
|
+
}
|
|
4015
|
+
function getQueryFieldsSchemaFromTable(table, tableName) {
|
|
4016
|
+
return {
|
|
4017
|
+
type: "array",
|
|
4018
|
+
items: {
|
|
4019
|
+
type: "string",
|
|
4020
|
+
constraints: {
|
|
4021
|
+
oneOf: Object.keys(table.fields)
|
|
4022
|
+
}
|
|
4023
|
+
},
|
|
4024
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4025
|
+
};
|
|
4026
|
+
}
|
|
4027
|
+
function getQueryJoinsSchemaFromTable(table, tableName) {
|
|
4028
|
+
return {
|
|
4029
|
+
type: "object",
|
|
4030
|
+
properties: {
|
|
4031
|
+
...Object.fromEntries(
|
|
4032
|
+
Object.entries(table.fields).map((field) => {
|
|
4033
|
+
return [
|
|
4034
|
+
field[0],
|
|
4035
|
+
{
|
|
4036
|
+
type: "object",
|
|
4037
|
+
properties: {
|
|
4038
|
+
on: {
|
|
4039
|
+
type: "string"
|
|
4040
|
+
},
|
|
4041
|
+
fields: {
|
|
4042
|
+
type: "array",
|
|
4043
|
+
items: {
|
|
4044
|
+
type: "string"
|
|
4045
|
+
}
|
|
4046
|
+
},
|
|
4047
|
+
filter: {
|
|
4048
|
+
type: "object"
|
|
4049
|
+
},
|
|
4050
|
+
returnAs: {
|
|
4051
|
+
type: "string",
|
|
4052
|
+
constraints: {
|
|
4053
|
+
oneOf: ["array", "object"]
|
|
4054
|
+
}
|
|
4055
|
+
},
|
|
4056
|
+
alias: {
|
|
4057
|
+
type: "string"
|
|
4058
|
+
},
|
|
4059
|
+
joins: {
|
|
4060
|
+
type: "object"
|
|
4061
|
+
}
|
|
4062
|
+
},
|
|
4063
|
+
required: ["on", "fields"],
|
|
4064
|
+
strict: true
|
|
4065
|
+
}
|
|
4066
|
+
];
|
|
4067
|
+
})
|
|
4068
|
+
)
|
|
4069
|
+
},
|
|
4070
|
+
strict: true,
|
|
4071
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4072
|
+
};
|
|
4073
|
+
}
|
|
4074
|
+
function getQuerySortSchemaFromTable(table, tableName) {
|
|
4075
|
+
return {
|
|
4076
|
+
type: "object",
|
|
4077
|
+
properties: {
|
|
4078
|
+
...Object.fromEntries(
|
|
4079
|
+
Object.entries(table.fields).map((field) => {
|
|
4080
|
+
return [
|
|
4081
|
+
field[0],
|
|
4082
|
+
{
|
|
4083
|
+
type: "string",
|
|
4084
|
+
constraints: {
|
|
4085
|
+
oneOf: ["asc", "desc"]
|
|
4086
|
+
}
|
|
4087
|
+
}
|
|
4088
|
+
];
|
|
4089
|
+
})
|
|
4090
|
+
)
|
|
4091
|
+
},
|
|
4092
|
+
strict: true,
|
|
4093
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4094
|
+
};
|
|
4095
|
+
}
|
|
4096
|
+
function getQueryLimitSchemaFromTable() {
|
|
4097
|
+
return {
|
|
4098
|
+
type: "number",
|
|
4099
|
+
constraints: {
|
|
4100
|
+
min: 1
|
|
4101
|
+
},
|
|
4102
|
+
description: "Limit for query results"
|
|
4103
|
+
};
|
|
4104
|
+
}
|
|
4105
|
+
function getQueryOffsetSchemaFromTable() {
|
|
4106
|
+
return {
|
|
4107
|
+
type: "number",
|
|
4108
|
+
constraints: {
|
|
4109
|
+
min: 0
|
|
4110
|
+
},
|
|
4111
|
+
description: "Offset for query results"
|
|
4112
|
+
};
|
|
4113
|
+
}
|
|
4114
|
+
function getTransactionSchema() {
|
|
4115
|
+
return {
|
|
4116
|
+
type: "boolean",
|
|
4117
|
+
description: "Whether to run the query in a transaction"
|
|
4118
|
+
};
|
|
4119
|
+
}
|
|
4120
|
+
function getQueryBatchSchemaFromTable() {
|
|
4121
|
+
return {
|
|
4122
|
+
type: "boolean",
|
|
4123
|
+
description: "Whether to run the query in batch mode"
|
|
4124
|
+
};
|
|
4125
|
+
}
|
|
4126
|
+
function getQueryOnConflictSchemaFromTable(table, tableName) {
|
|
4127
|
+
return {
|
|
4128
|
+
type: "object",
|
|
4129
|
+
properties: {
|
|
4130
|
+
target: {
|
|
4131
|
+
type: "array",
|
|
4132
|
+
items: {
|
|
4133
|
+
type: "string",
|
|
4134
|
+
constraints: {
|
|
4135
|
+
oneOf: Object.keys(table.fields)
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
},
|
|
4139
|
+
action: {
|
|
4140
|
+
type: "object",
|
|
4141
|
+
properties: {
|
|
4142
|
+
do: {
|
|
4143
|
+
type: "string",
|
|
4144
|
+
constraints: {
|
|
4145
|
+
oneOf: ["nothing", "update"]
|
|
4146
|
+
}
|
|
4147
|
+
},
|
|
4148
|
+
set: {
|
|
4149
|
+
type: "object",
|
|
4150
|
+
properties: {
|
|
4151
|
+
...Object.fromEntries(
|
|
4152
|
+
Object.entries(table.fields).map((field) => {
|
|
4153
|
+
return [
|
|
4154
|
+
field[0],
|
|
4155
|
+
[
|
|
4156
|
+
{
|
|
4157
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
4158
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
4159
|
+
}
|
|
4160
|
+
]
|
|
4161
|
+
];
|
|
4162
|
+
})
|
|
4163
|
+
)
|
|
4164
|
+
}
|
|
4165
|
+
},
|
|
4166
|
+
where: {
|
|
4167
|
+
type: "string"
|
|
4168
|
+
}
|
|
4169
|
+
},
|
|
4170
|
+
required: ["do"]
|
|
4171
|
+
}
|
|
4172
|
+
},
|
|
4173
|
+
required: ["target", "action"],
|
|
4174
|
+
strict: true
|
|
4175
|
+
};
|
|
4176
|
+
}
|
|
4177
|
+
function tableFieldTypeToSchemaType(type) {
|
|
4178
|
+
switch (type) {
|
|
4179
|
+
case "varchar":
|
|
4180
|
+
case "text":
|
|
4181
|
+
case "jsonb":
|
|
4182
|
+
case "uuid":
|
|
4183
|
+
case "date":
|
|
4184
|
+
case "geo_point":
|
|
4185
|
+
case "bytea":
|
|
4186
|
+
return "string";
|
|
4187
|
+
case "int":
|
|
4188
|
+
case "bigint":
|
|
4189
|
+
case "decimal":
|
|
4190
|
+
case "timestamp":
|
|
4191
|
+
return "number";
|
|
4192
|
+
case "boolean":
|
|
4193
|
+
return "boolean";
|
|
4194
|
+
case "array":
|
|
4195
|
+
return "array";
|
|
4196
|
+
case "object":
|
|
4197
|
+
return "object";
|
|
4198
|
+
}
|
|
4199
|
+
return "any";
|
|
4200
|
+
}
|
|
3774
4201
|
|
|
3775
4202
|
// src/Cadenza.ts
|
|
3776
4203
|
var import_uuid3 = require("uuid");
|
|
@@ -4242,7 +4669,6 @@ var GraphSyncController = class _GraphSyncController {
|
|
|
4242
4669
|
);
|
|
4243
4670
|
CadenzaService.schedule("meta.sync_requested", { __syncing: true }, 2e3);
|
|
4244
4671
|
}
|
|
4245
|
-
console.log("Syncing initiated", this.isCadenzaDBReady);
|
|
4246
4672
|
}
|
|
4247
4673
|
};
|
|
4248
4674
|
|
|
@@ -4645,10 +5071,9 @@ var CadenzaService = class {
|
|
|
4645
5071
|
this.bootstrap();
|
|
4646
5072
|
this.validateName(tableName);
|
|
4647
5073
|
this.validateName(operation);
|
|
4648
|
-
const tableNameFormatted = tableName.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
4649
5074
|
const name = `${operation.charAt(0).toUpperCase() + operation.slice(1)} ${tableName} in ${databaseServiceName ?? "default database service"}`;
|
|
4650
5075
|
const description = `Executes a ${operation} on table ${tableName} in ${databaseServiceName ?? "default database service"}`;
|
|
4651
|
-
const taskName =
|
|
5076
|
+
const taskName = `${operation.charAt(0).toUpperCase() + operation.slice(1)} ${tableName}`;
|
|
4652
5077
|
options = {
|
|
4653
5078
|
concurrency: 100,
|
|
4654
5079
|
timeout: 0,
|
|
@@ -4910,7 +5335,7 @@ var CadenzaService = class {
|
|
|
4910
5335
|
* This method is not supported in a browser environment and will log a warning if called in such an environment.
|
|
4911
5336
|
*
|
|
4912
5337
|
* @param {string} name - The name of the database service to be created.
|
|
4913
|
-
* @param {
|
|
5338
|
+
* @param {DatabaseSchemaDefinition} schema - The schema definition for the database service.
|
|
4914
5339
|
* @param {string} [description=""] - An optional description of the database service.
|
|
4915
5340
|
* @param {ServerOptions & DatabaseOptions} [options={}] - Optional configuration settings for the database and server.
|
|
4916
5341
|
* @return {void} This method does not return a value.
|
|
@@ -4974,7 +5399,7 @@ var CadenzaService = class {
|
|
|
4974
5399
|
* Creates a meta database service with the specified configuration.
|
|
4975
5400
|
*
|
|
4976
5401
|
* @param {string} name - The name of the database service to be created.
|
|
4977
|
-
* @param {
|
|
5402
|
+
* @param {DatabaseSchemaDefinition} schema - The schema definition for the database.
|
|
4978
5403
|
* @param {string} [description=""] - An optional description of the database service.
|
|
4979
5404
|
* @param {ServerOptions & DatabaseOptions} [options={}] - Optional server and database configuration options. The `isMeta` flag will be automatically set to true.
|
|
4980
5405
|
* @return {void} - This method does not return a value.
|