@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.mjs
CHANGED
|
@@ -281,12 +281,11 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
281
281
|
deleted
|
|
282
282
|
} = serviceInstance;
|
|
283
283
|
if (uuid4 === this.serviceInstanceId) return;
|
|
284
|
-
console.log("service instance", serviceName, uuid4, address);
|
|
285
284
|
if (deleted) {
|
|
286
|
-
this.instances.get(serviceName)?.
|
|
287
|
-
|
|
288
|
-
1
|
|
289
|
-
|
|
285
|
+
const indexToDelete = this.instances.get(serviceName)?.findIndex((i) => i.uuid === uuid4) ?? -1;
|
|
286
|
+
if (indexToDelete >= 0) {
|
|
287
|
+
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
288
|
+
}
|
|
290
289
|
if (this.instances.get(serviceName)?.length === 0) {
|
|
291
290
|
this.instances.delete(serviceName);
|
|
292
291
|
} else if (this.instances.get(serviceName)?.filter((i) => i.address === address && i.port === port).length === 0) {
|
|
@@ -329,7 +328,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
329
328
|
communicationTypes
|
|
330
329
|
});
|
|
331
330
|
instances?.filter(
|
|
332
|
-
(i) => i.address === address && i.port === port && i.
|
|
331
|
+
(i) => i.address === address && i.port === port && i.isActive
|
|
333
332
|
).forEach((i) => {
|
|
334
333
|
i.clientCreated = true;
|
|
335
334
|
});
|
|
@@ -361,7 +360,6 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
361
360
|
this.handleGlobalSignalRegistrationTask = CadenzaService.createMetaTask(
|
|
362
361
|
"Handle global Signal Registration",
|
|
363
362
|
(ctx) => {
|
|
364
|
-
console.log("Handling global signal registration...");
|
|
365
363
|
const { signalToTaskMaps } = ctx;
|
|
366
364
|
const sortedSignalToTaskMap = signalToTaskMaps.sort(
|
|
367
365
|
(a, b) => {
|
|
@@ -370,9 +368,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
370
368
|
return 0;
|
|
371
369
|
}
|
|
372
370
|
);
|
|
373
|
-
console.log(sortedSignalToTaskMap);
|
|
374
371
|
const locallyEmittedSignals = CadenzaService.signalBroker.listEmittedSignals().filter((s) => s.startsWith("global."));
|
|
375
|
-
console.log(locallyEmittedSignals);
|
|
376
372
|
for (const map of sortedSignalToTaskMap) {
|
|
377
373
|
if (map.deleted) {
|
|
378
374
|
this.remoteSignals.get(map.serviceName)?.delete(map.signalName);
|
|
@@ -389,9 +385,6 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
389
385
|
this.remoteSignals.set(map.serviceName, /* @__PURE__ */ new Set());
|
|
390
386
|
}
|
|
391
387
|
if (!this.remoteSignals.get(map.serviceName)?.has(map.signalName)) {
|
|
392
|
-
console.log(
|
|
393
|
-
`Creating signal transmission task for: ${map.signalName} to ${map.serviceName}`
|
|
394
|
-
);
|
|
395
388
|
CadenzaService.createSignalTransmissionTask(
|
|
396
389
|
map.signalName,
|
|
397
390
|
map.serviceName
|
|
@@ -439,7 +432,12 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
439
432
|
return true;
|
|
440
433
|
},
|
|
441
434
|
"Handles service not responding"
|
|
442
|
-
).doOn(
|
|
435
|
+
).doOn(
|
|
436
|
+
"meta.fetch.handshake_failed",
|
|
437
|
+
"meta.fetch.handshake_failed.*",
|
|
438
|
+
"meta.socket_client.disconnected",
|
|
439
|
+
"meta.socket_client.disconnected.*"
|
|
440
|
+
).attachSignal("global.meta.service_registry.service_not_responding");
|
|
443
441
|
this.handleServiceHandshakeTask = CadenzaService.createMetaTask(
|
|
444
442
|
"Handle service handshake",
|
|
445
443
|
(ctx, emit) => {
|
|
@@ -466,7 +464,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
466
464
|
(i) => i.uuid !== serviceInstanceId && i.address === serviceAddress && i.port === servicePort
|
|
467
465
|
);
|
|
468
466
|
for (const i of instancesToDelete ?? []) {
|
|
469
|
-
this.instances.get(serviceName)?.
|
|
467
|
+
const indexToDelete = this.instances.get(serviceName)?.indexOf(i) ?? -1;
|
|
468
|
+
if (indexToDelete >= 0) {
|
|
469
|
+
this.instances.get(serviceName)?.splice(indexToDelete, 1);
|
|
470
|
+
}
|
|
470
471
|
emit("global.meta.service_registry.deleted", {
|
|
471
472
|
data: {
|
|
472
473
|
isActive: false,
|
|
@@ -503,23 +504,14 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
503
504
|
const mergeSyncDataTask = CadenzaService.createUniqueMetaTask(
|
|
504
505
|
"Merge sync data",
|
|
505
506
|
(ctx) => {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
console.log("merging contexts of full sync...", joinedContext);
|
|
512
|
-
return joinedContext;
|
|
513
|
-
} catch (e) {
|
|
514
|
-
console.log("Error", e.message, ctx);
|
|
515
|
-
return false;
|
|
516
|
-
}
|
|
507
|
+
let joinedContext = {};
|
|
508
|
+
ctx.joinedContexts.forEach((ctx2) => {
|
|
509
|
+
joinedContext = { ...joinedContext, ...ctx2 };
|
|
510
|
+
});
|
|
511
|
+
return joinedContext;
|
|
517
512
|
}
|
|
518
513
|
).emits("meta.service_registry.initial_sync_complete").then(this.handleGlobalSignalRegistrationTask);
|
|
519
514
|
this.fullSyncTask = CadenzaService.createMetaRoutine("Full sync", [
|
|
520
|
-
CadenzaService.createTask("Confirm full sync", () => {
|
|
521
|
-
console.log("Confirming full sync...");
|
|
522
|
-
}),
|
|
523
515
|
CadenzaService.createCadenzaDBQueryTask("signal_to_task_map", {
|
|
524
516
|
filter: {
|
|
525
517
|
isGlobal: true
|
|
@@ -635,8 +627,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
635
627
|
}
|
|
636
628
|
if (__broadcast || instances[0].isFrontend) {
|
|
637
629
|
for (const instance of instances) {
|
|
630
|
+
const socketKey = instance.isFrontend ? instance.address : `${instance.address}_${instance.port}`;
|
|
638
631
|
emit(
|
|
639
|
-
`meta.service_registry.selected_instance_for_socket:${
|
|
632
|
+
`meta.service_registry.selected_instance_for_socket:${socketKey}`,
|
|
640
633
|
context
|
|
641
634
|
);
|
|
642
635
|
}
|
|
@@ -1627,6 +1620,46 @@ var RestController = class _RestController {
|
|
|
1627
1620
|
import { Server } from "socket.io";
|
|
1628
1621
|
import { RateLimiterMemory as RateLimiterMemory2 } from "rate-limiter-flexible";
|
|
1629
1622
|
import { io } from "socket.io-client";
|
|
1623
|
+
|
|
1624
|
+
// src/network/socketClientUtils.ts
|
|
1625
|
+
var waitForSocketConnection = async (socket, timeoutMs, createError) => {
|
|
1626
|
+
if (!socket) {
|
|
1627
|
+
return { ok: false, error: createError("disconnected") };
|
|
1628
|
+
}
|
|
1629
|
+
if (socket.connected) {
|
|
1630
|
+
return { ok: true };
|
|
1631
|
+
}
|
|
1632
|
+
return new Promise((resolve) => {
|
|
1633
|
+
let timer = null;
|
|
1634
|
+
let settled = false;
|
|
1635
|
+
const cleanup = () => {
|
|
1636
|
+
if (timer) {
|
|
1637
|
+
clearTimeout(timer);
|
|
1638
|
+
timer = null;
|
|
1639
|
+
}
|
|
1640
|
+
socket.off("connect", onConnect);
|
|
1641
|
+
socket.off("connect_error", onConnectError);
|
|
1642
|
+
socket.off("disconnect", onDisconnect);
|
|
1643
|
+
};
|
|
1644
|
+
const settle = (outcome) => {
|
|
1645
|
+
if (settled) return;
|
|
1646
|
+
settled = true;
|
|
1647
|
+
cleanup();
|
|
1648
|
+
resolve(outcome);
|
|
1649
|
+
};
|
|
1650
|
+
const onConnect = () => settle({ ok: true });
|
|
1651
|
+
const onConnectError = (error) => settle({ ok: false, error: createError("connect_error", error) });
|
|
1652
|
+
const onDisconnect = () => settle({ ok: false, error: createError("disconnected") });
|
|
1653
|
+
socket.once("connect", onConnect);
|
|
1654
|
+
socket.once("connect_error", onConnectError);
|
|
1655
|
+
socket.once("disconnect", onDisconnect);
|
|
1656
|
+
timer = setTimeout(() => {
|
|
1657
|
+
settle({ ok: false, error: createError("connect_timeout") });
|
|
1658
|
+
}, timeoutMs);
|
|
1659
|
+
});
|
|
1660
|
+
};
|
|
1661
|
+
|
|
1662
|
+
// src/network/SocketController.ts
|
|
1630
1663
|
var SocketController = class _SocketController {
|
|
1631
1664
|
static get instance() {
|
|
1632
1665
|
if (!this._instance) this._instance = new _SocketController();
|
|
@@ -1763,10 +1796,6 @@ var SocketController = class _SocketController {
|
|
|
1763
1796
|
"delegation",
|
|
1764
1797
|
(ctx2, callback) => {
|
|
1765
1798
|
const deputyExecId = ctx2.__metadata.__deputyExecId;
|
|
1766
|
-
console.log(
|
|
1767
|
-
"Delegation request received:",
|
|
1768
|
-
ctx2.__localTaskName
|
|
1769
|
-
);
|
|
1770
1799
|
CadenzaService.createEphemeralMetaTask(
|
|
1771
1800
|
"Resolve delegation",
|
|
1772
1801
|
(ctx3) => {
|
|
@@ -1801,7 +1830,6 @@ var SocketController = class _SocketController {
|
|
|
1801
1830
|
"signal",
|
|
1802
1831
|
(ctx2, callback) => {
|
|
1803
1832
|
if (CadenzaService.signalBroker.listObservedSignals().includes(ctx2.__signalName)) {
|
|
1804
|
-
console.log("Signal received:", ctx2.__signalName);
|
|
1805
1833
|
callback({
|
|
1806
1834
|
__status: "success",
|
|
1807
1835
|
__signalName: ctx2.__signalName
|
|
@@ -1907,35 +1935,71 @@ var SocketController = class _SocketController {
|
|
|
1907
1935
|
});
|
|
1908
1936
|
emitWhenReady = (event, data, timeoutMs = 6e4, ack) => {
|
|
1909
1937
|
return new Promise((resolve) => {
|
|
1910
|
-
const
|
|
1911
|
-
|
|
1912
|
-
|
|
1938
|
+
const resolveWithError = (errorMessage, fallbackError) => {
|
|
1939
|
+
resolve({
|
|
1940
|
+
...data,
|
|
1941
|
+
errored: true,
|
|
1942
|
+
__error: errorMessage,
|
|
1943
|
+
error: fallbackError instanceof Error ? fallbackError.message : errorMessage,
|
|
1944
|
+
socketId: socket?.id,
|
|
1945
|
+
serviceName,
|
|
1946
|
+
URL
|
|
1947
|
+
});
|
|
1948
|
+
};
|
|
1949
|
+
const tryEmit = async () => {
|
|
1950
|
+
const waitTimeoutMs = timeoutMs > 0 ? timeoutMs + 10 : 1e4;
|
|
1951
|
+
const waitResult = await waitForSocketConnection(
|
|
1952
|
+
socket,
|
|
1953
|
+
waitTimeoutMs,
|
|
1954
|
+
(reason, error) => {
|
|
1955
|
+
if (reason === "connect_timeout") {
|
|
1956
|
+
return `Socket connect timed out before '${event}'`;
|
|
1957
|
+
}
|
|
1958
|
+
if (reason === "connect_error") {
|
|
1959
|
+
const errMessage = error instanceof Error ? error.message : String(error);
|
|
1960
|
+
return `Socket connect error before '${event}': ${errMessage}`;
|
|
1961
|
+
}
|
|
1962
|
+
return `Socket disconnected before '${event}'`;
|
|
1963
|
+
}
|
|
1964
|
+
);
|
|
1965
|
+
if (!waitResult.ok) {
|
|
1966
|
+
CadenzaService.log(
|
|
1967
|
+
waitResult.error,
|
|
1968
|
+
{ socketId: socket?.id, serviceName, URL, event },
|
|
1969
|
+
"error"
|
|
1970
|
+
);
|
|
1971
|
+
resolveWithError(waitResult.error);
|
|
1913
1972
|
return;
|
|
1914
1973
|
}
|
|
1915
|
-
let timer;
|
|
1974
|
+
let timer = null;
|
|
1916
1975
|
if (timeoutMs !== 0) {
|
|
1917
1976
|
timer = setTimeout(() => {
|
|
1977
|
+
if (timer) {
|
|
1978
|
+
pendingTimers.delete(timer);
|
|
1979
|
+
timer = null;
|
|
1980
|
+
}
|
|
1918
1981
|
CadenzaService.log(
|
|
1919
1982
|
`Socket event '${event}' timed out`,
|
|
1920
1983
|
{ socketId: socket?.id, serviceName, URL },
|
|
1921
1984
|
"error"
|
|
1922
1985
|
);
|
|
1923
|
-
|
|
1924
|
-
...data,
|
|
1925
|
-
errored: true,
|
|
1926
|
-
__error: `Socket event '${event}' timed out`,
|
|
1927
|
-
error: `Socket event '${event}' timed out`,
|
|
1928
|
-
socketId: socket?.id,
|
|
1929
|
-
serviceName,
|
|
1930
|
-
URL
|
|
1931
|
-
});
|
|
1986
|
+
resolveWithError(`Socket event '${event}' timed out`);
|
|
1932
1987
|
}, timeoutMs + 10);
|
|
1933
1988
|
pendingTimers.add(timer);
|
|
1934
1989
|
}
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1990
|
+
const connectedSocket = socket;
|
|
1991
|
+
if (!connectedSocket) {
|
|
1992
|
+
resolveWithError(
|
|
1993
|
+
`Socket unavailable before emitting '${event}'`
|
|
1994
|
+
);
|
|
1995
|
+
return;
|
|
1996
|
+
}
|
|
1997
|
+
connectedSocket.timeout(timeoutMs).emit(event, data, (err, response) => {
|
|
1998
|
+
if (timer) {
|
|
1999
|
+
clearTimeout(timer);
|
|
2000
|
+
pendingTimers.delete(timer);
|
|
2001
|
+
timer = null;
|
|
2002
|
+
}
|
|
1939
2003
|
if (err) {
|
|
1940
2004
|
CadenzaService.log(
|
|
1941
2005
|
"Socket timeout.",
|
|
@@ -1958,11 +2022,7 @@ var SocketController = class _SocketController {
|
|
|
1958
2022
|
resolve(response);
|
|
1959
2023
|
});
|
|
1960
2024
|
};
|
|
1961
|
-
|
|
1962
|
-
tryEmit();
|
|
1963
|
-
} else {
|
|
1964
|
-
socket?.once("connect", tryEmit);
|
|
1965
|
-
}
|
|
2025
|
+
void tryEmit();
|
|
1966
2026
|
});
|
|
1967
2027
|
};
|
|
1968
2028
|
socket.on("connect", () => {
|
|
@@ -2078,7 +2138,6 @@ var SocketController = class _SocketController {
|
|
|
2078
2138
|
delete ctx2.__broadcast;
|
|
2079
2139
|
const requestSentAt = Date.now();
|
|
2080
2140
|
pendingDelegationIds.add(ctx2.__metadata.__deputyExecId);
|
|
2081
|
-
console.log("Delegating task:", ctx2.__remoteRoutineName);
|
|
2082
2141
|
emitWhenReady?.(
|
|
2083
2142
|
"delegation",
|
|
2084
2143
|
ctx2,
|
|
@@ -2087,12 +2146,6 @@ var SocketController = class _SocketController {
|
|
|
2087
2146
|
const requestDuration = Date.now() - requestSentAt;
|
|
2088
2147
|
const metadata = resultContext.__metadata;
|
|
2089
2148
|
delete resultContext.__metadata;
|
|
2090
|
-
console.log(
|
|
2091
|
-
"Delegation response received:",
|
|
2092
|
-
ctx2.__remoteRoutineName,
|
|
2093
|
-
"Duration:",
|
|
2094
|
-
requestDuration
|
|
2095
|
-
);
|
|
2096
2149
|
emit(
|
|
2097
2150
|
`meta.socket_client.delegated:${ctx2.__metadata.__deputyExecId}`,
|
|
2098
2151
|
{
|
|
@@ -2120,7 +2173,6 @@ var SocketController = class _SocketController {
|
|
|
2120
2173
|
}
|
|
2121
2174
|
return new Promise((resolve) => {
|
|
2122
2175
|
delete ctx2.__broadcast;
|
|
2123
|
-
console.log("Transmitting signal:", ctx2.__signalName);
|
|
2124
2176
|
emitWhenReady?.("signal", ctx2, 5e3, (response) => {
|
|
2125
2177
|
if (ctx2.__routineExecId) {
|
|
2126
2178
|
emit(
|
|
@@ -2287,14 +2339,25 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2287
2339
|
return {
|
|
2288
2340
|
data: {
|
|
2289
2341
|
...ctx.data,
|
|
2290
|
-
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2342
|
+
serviceName: CadenzaService.serviceRegistry.serviceName,
|
|
2343
|
+
inputContextSchemaId: ctx.data.inputContextSchemaId ? {
|
|
2344
|
+
subOperation: "insert",
|
|
2345
|
+
table: "context_schema",
|
|
2346
|
+
data: {
|
|
2347
|
+
...ctx.data.inputContextSchemaId
|
|
2348
|
+
},
|
|
2349
|
+
return: "uuid"
|
|
2350
|
+
} : null,
|
|
2351
|
+
outputContextSchemaId: ctx.data.outputContextSchemaId ? {
|
|
2352
|
+
subOperation: "insert",
|
|
2353
|
+
table: "context_schema",
|
|
2354
|
+
data: {
|
|
2355
|
+
...ctx.data.outputContextSchemaId
|
|
2356
|
+
},
|
|
2357
|
+
return: "uuid"
|
|
2358
|
+
} : null
|
|
2359
|
+
},
|
|
2360
|
+
transaction: true
|
|
2298
2361
|
};
|
|
2299
2362
|
}).doOn("meta.task.created").emits("global.meta.graph_metadata.task_created");
|
|
2300
2363
|
CadenzaService.createMetaTask("Handle task update", (ctx) => {
|
|
@@ -2426,7 +2489,7 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2426
2489
|
data: {
|
|
2427
2490
|
...ctx.data,
|
|
2428
2491
|
serviceName: CadenzaService.serviceRegistry.serviceName,
|
|
2429
|
-
|
|
2492
|
+
serviceInstanceId: CadenzaService.serviceRegistry.serviceInstanceId
|
|
2430
2493
|
},
|
|
2431
2494
|
filter: {
|
|
2432
2495
|
...ctx.filter
|
|
@@ -2954,7 +3017,6 @@ var DatabaseController = class _DatabaseController {
|
|
|
2954
3017
|
if (ddl && ddl.length > 0) {
|
|
2955
3018
|
for (const sql of ddl) {
|
|
2956
3019
|
try {
|
|
2957
|
-
console.log("Executing DDL", sql);
|
|
2958
3020
|
await this.dbClient.query(sql);
|
|
2959
3021
|
} catch (error) {
|
|
2960
3022
|
console.error(
|
|
@@ -3603,9 +3665,9 @@ var DatabaseController = class _DatabaseController {
|
|
|
3603
3665
|
createDatabaseTask(op, tableName, table, queryFunction, options) {
|
|
3604
3666
|
const opAction = op === "query" ? "queried" : op === "insert" ? "inserted" : op === "update" ? "updated" : op === "delete" ? "deleted" : "";
|
|
3605
3667
|
const defaultSignal = `global.${options.isMeta ? "meta." : ""}${tableName}.${opAction}`;
|
|
3606
|
-
const
|
|
3607
|
-
const
|
|
3608
|
-
CadenzaService.createThrottledTask(
|
|
3668
|
+
const taskName = `${op.charAt(0).toUpperCase() + op.slice(1)} ${tableName}`;
|
|
3669
|
+
const schema = this.getInputSchema(op, tableName, table);
|
|
3670
|
+
const task = CadenzaService.createThrottledTask(
|
|
3609
3671
|
taskName,
|
|
3610
3672
|
async (context, emit) => {
|
|
3611
3673
|
for (const action of Object.keys(table.customSignals?.triggers ?? {})) {
|
|
@@ -3700,17 +3762,8 @@ var DatabaseController = class _DatabaseController {
|
|
|
3700
3762
|
{
|
|
3701
3763
|
isMeta: options.isMeta,
|
|
3702
3764
|
isSubMeta: options.isMeta,
|
|
3703
|
-
validateInputContext:
|
|
3704
|
-
|
|
3705
|
-
inputSchema: {
|
|
3706
|
-
// TODO
|
|
3707
|
-
type: "object",
|
|
3708
|
-
properties: {
|
|
3709
|
-
filter: {
|
|
3710
|
-
type: "object"
|
|
3711
|
-
}
|
|
3712
|
-
}
|
|
3713
|
-
}
|
|
3765
|
+
validateInputContext: options.securityProfile !== "low",
|
|
3766
|
+
inputSchema: schema
|
|
3714
3767
|
}
|
|
3715
3768
|
).doOn(
|
|
3716
3769
|
...table.customSignals?.triggers?.[op]?.map((signal) => {
|
|
@@ -3721,8 +3774,382 @@ var DatabaseController = class _DatabaseController {
|
|
|
3721
3774
|
return typeof signal === "string" ? signal : signal.signal;
|
|
3722
3775
|
}) ?? []
|
|
3723
3776
|
);
|
|
3777
|
+
if (op === "query") {
|
|
3778
|
+
const intentName = `query-${CadenzaService.serviceRegistry.serviceName}-${tableName}`;
|
|
3779
|
+
CadenzaService.defineIntent({
|
|
3780
|
+
name: intentName,
|
|
3781
|
+
description: `Perform a query operation on the ${tableName} table`,
|
|
3782
|
+
input: schema
|
|
3783
|
+
});
|
|
3784
|
+
task.respondsTo(intentName);
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
getInputSchema(op, tableName, table) {
|
|
3788
|
+
const inputSchema = {
|
|
3789
|
+
type: "object",
|
|
3790
|
+
properties: {
|
|
3791
|
+
queryData: {
|
|
3792
|
+
type: "object",
|
|
3793
|
+
properties: {},
|
|
3794
|
+
strict: true
|
|
3795
|
+
}
|
|
3796
|
+
},
|
|
3797
|
+
strict: true
|
|
3798
|
+
};
|
|
3799
|
+
if (!inputSchema.properties) {
|
|
3800
|
+
return inputSchema;
|
|
3801
|
+
}
|
|
3802
|
+
inputSchema.properties.transaction = getTransactionSchema();
|
|
3803
|
+
inputSchema.properties.queryData.properties.transaction = inputSchema.properties.transaction;
|
|
3804
|
+
switch (op) {
|
|
3805
|
+
case "insert":
|
|
3806
|
+
inputSchema.properties.data = getInsertDataSchemaFromTable(
|
|
3807
|
+
table,
|
|
3808
|
+
tableName
|
|
3809
|
+
);
|
|
3810
|
+
inputSchema.properties.queryData.properties.data = inputSchema.properties.data;
|
|
3811
|
+
inputSchema.properties.batch = getQueryBatchSchemaFromTable();
|
|
3812
|
+
inputSchema.properties.queryData.properties.batch = inputSchema.properties.batch;
|
|
3813
|
+
inputSchema.properties.onConflict = getQueryOnConflictSchemaFromTable(
|
|
3814
|
+
table,
|
|
3815
|
+
tableName
|
|
3816
|
+
);
|
|
3817
|
+
inputSchema.properties.queryData.properties.onConflict = inputSchema.properties.onConflict;
|
|
3818
|
+
break;
|
|
3819
|
+
case "query":
|
|
3820
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3821
|
+
table,
|
|
3822
|
+
tableName
|
|
3823
|
+
);
|
|
3824
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3825
|
+
inputSchema.properties.fields = getQueryFieldsSchemaFromTable(
|
|
3826
|
+
table,
|
|
3827
|
+
tableName
|
|
3828
|
+
);
|
|
3829
|
+
inputSchema.properties.queryData.properties.fields = inputSchema.properties.fields;
|
|
3830
|
+
inputSchema.properties.joins = getQueryJoinsSchemaFromTable(
|
|
3831
|
+
table,
|
|
3832
|
+
tableName
|
|
3833
|
+
);
|
|
3834
|
+
inputSchema.properties.queryData.properties.joins = inputSchema.properties.joins;
|
|
3835
|
+
inputSchema.properties.sort = getQuerySortSchemaFromTable(
|
|
3836
|
+
table,
|
|
3837
|
+
tableName
|
|
3838
|
+
);
|
|
3839
|
+
inputSchema.properties.queryData.properties.sort = inputSchema.properties.sort;
|
|
3840
|
+
inputSchema.properties.limit = getQueryLimitSchemaFromTable();
|
|
3841
|
+
inputSchema.properties.queryData.properties.limit = inputSchema.properties.limit;
|
|
3842
|
+
inputSchema.properties.offset = getQueryOffsetSchemaFromTable();
|
|
3843
|
+
inputSchema.properties.queryData.properties.offset = inputSchema.properties.offset;
|
|
3844
|
+
break;
|
|
3845
|
+
case "update":
|
|
3846
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3847
|
+
table,
|
|
3848
|
+
tableName
|
|
3849
|
+
);
|
|
3850
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3851
|
+
inputSchema.properties.fields = getQueryFieldsSchemaFromTable(
|
|
3852
|
+
table,
|
|
3853
|
+
tableName
|
|
3854
|
+
);
|
|
3855
|
+
inputSchema.properties.queryData.properties.fields = inputSchema.properties.fields;
|
|
3856
|
+
break;
|
|
3857
|
+
case "delete":
|
|
3858
|
+
inputSchema.properties.filter = getQueryFilterSchemaFromTable(
|
|
3859
|
+
table,
|
|
3860
|
+
tableName
|
|
3861
|
+
);
|
|
3862
|
+
inputSchema.properties.queryData.properties.filter = inputSchema.properties.filter;
|
|
3863
|
+
break;
|
|
3864
|
+
}
|
|
3865
|
+
return inputSchema;
|
|
3724
3866
|
}
|
|
3725
3867
|
};
|
|
3868
|
+
function getInsertDataSchemaFromTable(table, tableName) {
|
|
3869
|
+
const dataSchema = {
|
|
3870
|
+
type: "object",
|
|
3871
|
+
properties: {
|
|
3872
|
+
...Object.fromEntries(
|
|
3873
|
+
Object.entries(table.fields).map((field) => {
|
|
3874
|
+
return [
|
|
3875
|
+
field[0],
|
|
3876
|
+
[
|
|
3877
|
+
{
|
|
3878
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3879
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3880
|
+
},
|
|
3881
|
+
{
|
|
3882
|
+
type: "string",
|
|
3883
|
+
constraints: {
|
|
3884
|
+
oneOf: ["increment", "decrement", "set"]
|
|
3885
|
+
}
|
|
3886
|
+
},
|
|
3887
|
+
{
|
|
3888
|
+
type: "object",
|
|
3889
|
+
properties: {
|
|
3890
|
+
subOperation: {
|
|
3891
|
+
type: "string",
|
|
3892
|
+
enum: ["insert", "query"]
|
|
3893
|
+
},
|
|
3894
|
+
table: {
|
|
3895
|
+
type: "string"
|
|
3896
|
+
},
|
|
3897
|
+
data: [
|
|
3898
|
+
{
|
|
3899
|
+
type: "object"
|
|
3900
|
+
},
|
|
3901
|
+
{
|
|
3902
|
+
type: "array",
|
|
3903
|
+
items: {
|
|
3904
|
+
type: "object"
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
],
|
|
3908
|
+
filter: {
|
|
3909
|
+
type: "object"
|
|
3910
|
+
},
|
|
3911
|
+
fields: {
|
|
3912
|
+
type: "array",
|
|
3913
|
+
items: {
|
|
3914
|
+
type: "string"
|
|
3915
|
+
}
|
|
3916
|
+
},
|
|
3917
|
+
return: {
|
|
3918
|
+
type: "string"
|
|
3919
|
+
}
|
|
3920
|
+
},
|
|
3921
|
+
required: ["subOperation", "table"]
|
|
3922
|
+
}
|
|
3923
|
+
]
|
|
3924
|
+
];
|
|
3925
|
+
})
|
|
3926
|
+
)
|
|
3927
|
+
},
|
|
3928
|
+
required: Object.entries(table.fields).filter((field) => field[1].required || field[1].primary).map((field) => field[0]),
|
|
3929
|
+
strict: true
|
|
3930
|
+
};
|
|
3931
|
+
return [
|
|
3932
|
+
dataSchema,
|
|
3933
|
+
{
|
|
3934
|
+
type: "array",
|
|
3935
|
+
items: dataSchema
|
|
3936
|
+
}
|
|
3937
|
+
];
|
|
3938
|
+
}
|
|
3939
|
+
function getQueryFilterSchemaFromTable(table, tableName) {
|
|
3940
|
+
return {
|
|
3941
|
+
type: "object",
|
|
3942
|
+
properties: {
|
|
3943
|
+
...Object.fromEntries(
|
|
3944
|
+
Object.entries(table.fields).map((field) => {
|
|
3945
|
+
return [
|
|
3946
|
+
field[0],
|
|
3947
|
+
[
|
|
3948
|
+
{
|
|
3949
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3950
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3951
|
+
},
|
|
3952
|
+
{
|
|
3953
|
+
type: "array",
|
|
3954
|
+
items: {
|
|
3955
|
+
type: tableFieldTypeToSchemaType(field[1].type)
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
]
|
|
3959
|
+
];
|
|
3960
|
+
})
|
|
3961
|
+
)
|
|
3962
|
+
},
|
|
3963
|
+
strict: true,
|
|
3964
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
3965
|
+
};
|
|
3966
|
+
}
|
|
3967
|
+
function getQueryFieldsSchemaFromTable(table, tableName) {
|
|
3968
|
+
return {
|
|
3969
|
+
type: "array",
|
|
3970
|
+
items: {
|
|
3971
|
+
type: "string",
|
|
3972
|
+
constraints: {
|
|
3973
|
+
oneOf: Object.keys(table.fields)
|
|
3974
|
+
}
|
|
3975
|
+
},
|
|
3976
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
3977
|
+
};
|
|
3978
|
+
}
|
|
3979
|
+
function getQueryJoinsSchemaFromTable(table, tableName) {
|
|
3980
|
+
return {
|
|
3981
|
+
type: "object",
|
|
3982
|
+
properties: {
|
|
3983
|
+
...Object.fromEntries(
|
|
3984
|
+
Object.entries(table.fields).map((field) => {
|
|
3985
|
+
return [
|
|
3986
|
+
field[0],
|
|
3987
|
+
{
|
|
3988
|
+
type: "object",
|
|
3989
|
+
properties: {
|
|
3990
|
+
on: {
|
|
3991
|
+
type: "string"
|
|
3992
|
+
},
|
|
3993
|
+
fields: {
|
|
3994
|
+
type: "array",
|
|
3995
|
+
items: {
|
|
3996
|
+
type: "string"
|
|
3997
|
+
}
|
|
3998
|
+
},
|
|
3999
|
+
filter: {
|
|
4000
|
+
type: "object"
|
|
4001
|
+
},
|
|
4002
|
+
returnAs: {
|
|
4003
|
+
type: "string",
|
|
4004
|
+
constraints: {
|
|
4005
|
+
oneOf: ["array", "object"]
|
|
4006
|
+
}
|
|
4007
|
+
},
|
|
4008
|
+
alias: {
|
|
4009
|
+
type: "string"
|
|
4010
|
+
},
|
|
4011
|
+
joins: {
|
|
4012
|
+
type: "object"
|
|
4013
|
+
}
|
|
4014
|
+
},
|
|
4015
|
+
required: ["on", "fields"],
|
|
4016
|
+
strict: true
|
|
4017
|
+
}
|
|
4018
|
+
];
|
|
4019
|
+
})
|
|
4020
|
+
)
|
|
4021
|
+
},
|
|
4022
|
+
strict: true,
|
|
4023
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4024
|
+
};
|
|
4025
|
+
}
|
|
4026
|
+
function getQuerySortSchemaFromTable(table, tableName) {
|
|
4027
|
+
return {
|
|
4028
|
+
type: "object",
|
|
4029
|
+
properties: {
|
|
4030
|
+
...Object.fromEntries(
|
|
4031
|
+
Object.entries(table.fields).map((field) => {
|
|
4032
|
+
return [
|
|
4033
|
+
field[0],
|
|
4034
|
+
{
|
|
4035
|
+
type: "string",
|
|
4036
|
+
constraints: {
|
|
4037
|
+
oneOf: ["asc", "desc"]
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4040
|
+
];
|
|
4041
|
+
})
|
|
4042
|
+
)
|
|
4043
|
+
},
|
|
4044
|
+
strict: true,
|
|
4045
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry.serviceName}.`
|
|
4046
|
+
};
|
|
4047
|
+
}
|
|
4048
|
+
function getQueryLimitSchemaFromTable() {
|
|
4049
|
+
return {
|
|
4050
|
+
type: "number",
|
|
4051
|
+
constraints: {
|
|
4052
|
+
min: 1
|
|
4053
|
+
},
|
|
4054
|
+
description: "Limit for query results"
|
|
4055
|
+
};
|
|
4056
|
+
}
|
|
4057
|
+
function getQueryOffsetSchemaFromTable() {
|
|
4058
|
+
return {
|
|
4059
|
+
type: "number",
|
|
4060
|
+
constraints: {
|
|
4061
|
+
min: 0
|
|
4062
|
+
},
|
|
4063
|
+
description: "Offset for query results"
|
|
4064
|
+
};
|
|
4065
|
+
}
|
|
4066
|
+
function getTransactionSchema() {
|
|
4067
|
+
return {
|
|
4068
|
+
type: "boolean",
|
|
4069
|
+
description: "Whether to run the query in a transaction"
|
|
4070
|
+
};
|
|
4071
|
+
}
|
|
4072
|
+
function getQueryBatchSchemaFromTable() {
|
|
4073
|
+
return {
|
|
4074
|
+
type: "boolean",
|
|
4075
|
+
description: "Whether to run the query in batch mode"
|
|
4076
|
+
};
|
|
4077
|
+
}
|
|
4078
|
+
function getQueryOnConflictSchemaFromTable(table, tableName) {
|
|
4079
|
+
return {
|
|
4080
|
+
type: "object",
|
|
4081
|
+
properties: {
|
|
4082
|
+
target: {
|
|
4083
|
+
type: "array",
|
|
4084
|
+
items: {
|
|
4085
|
+
type: "string",
|
|
4086
|
+
constraints: {
|
|
4087
|
+
oneOf: Object.keys(table.fields)
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
},
|
|
4091
|
+
action: {
|
|
4092
|
+
type: "object",
|
|
4093
|
+
properties: {
|
|
4094
|
+
do: {
|
|
4095
|
+
type: "string",
|
|
4096
|
+
constraints: {
|
|
4097
|
+
oneOf: ["nothing", "update"]
|
|
4098
|
+
}
|
|
4099
|
+
},
|
|
4100
|
+
set: {
|
|
4101
|
+
type: "object",
|
|
4102
|
+
properties: {
|
|
4103
|
+
...Object.fromEntries(
|
|
4104
|
+
Object.entries(table.fields).map((field) => {
|
|
4105
|
+
return [
|
|
4106
|
+
field[0],
|
|
4107
|
+
[
|
|
4108
|
+
{
|
|
4109
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
4110
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
4111
|
+
}
|
|
4112
|
+
]
|
|
4113
|
+
];
|
|
4114
|
+
})
|
|
4115
|
+
)
|
|
4116
|
+
}
|
|
4117
|
+
},
|
|
4118
|
+
where: {
|
|
4119
|
+
type: "string"
|
|
4120
|
+
}
|
|
4121
|
+
},
|
|
4122
|
+
required: ["do"]
|
|
4123
|
+
}
|
|
4124
|
+
},
|
|
4125
|
+
required: ["target", "action"],
|
|
4126
|
+
strict: true
|
|
4127
|
+
};
|
|
4128
|
+
}
|
|
4129
|
+
function tableFieldTypeToSchemaType(type) {
|
|
4130
|
+
switch (type) {
|
|
4131
|
+
case "varchar":
|
|
4132
|
+
case "text":
|
|
4133
|
+
case "jsonb":
|
|
4134
|
+
case "uuid":
|
|
4135
|
+
case "date":
|
|
4136
|
+
case "geo_point":
|
|
4137
|
+
case "bytea":
|
|
4138
|
+
return "string";
|
|
4139
|
+
case "int":
|
|
4140
|
+
case "bigint":
|
|
4141
|
+
case "decimal":
|
|
4142
|
+
case "timestamp":
|
|
4143
|
+
return "number";
|
|
4144
|
+
case "boolean":
|
|
4145
|
+
return "boolean";
|
|
4146
|
+
case "array":
|
|
4147
|
+
return "array";
|
|
4148
|
+
case "object":
|
|
4149
|
+
return "object";
|
|
4150
|
+
}
|
|
4151
|
+
return "any";
|
|
4152
|
+
}
|
|
3726
4153
|
|
|
3727
4154
|
// src/Cadenza.ts
|
|
3728
4155
|
import { v4 as uuid3 } from "uuid";
|
|
@@ -4194,7 +4621,6 @@ var GraphSyncController = class _GraphSyncController {
|
|
|
4194
4621
|
);
|
|
4195
4622
|
CadenzaService.schedule("meta.sync_requested", { __syncing: true }, 2e3);
|
|
4196
4623
|
}
|
|
4197
|
-
console.log("Syncing initiated", this.isCadenzaDBReady);
|
|
4198
4624
|
}
|
|
4199
4625
|
};
|
|
4200
4626
|
|
|
@@ -4597,10 +5023,9 @@ var CadenzaService = class {
|
|
|
4597
5023
|
this.bootstrap();
|
|
4598
5024
|
this.validateName(tableName);
|
|
4599
5025
|
this.validateName(operation);
|
|
4600
|
-
const tableNameFormatted = tableName.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
4601
5026
|
const name = `${operation.charAt(0).toUpperCase() + operation.slice(1)} ${tableName} in ${databaseServiceName ?? "default database service"}`;
|
|
4602
5027
|
const description = `Executes a ${operation} on table ${tableName} in ${databaseServiceName ?? "default database service"}`;
|
|
4603
|
-
const taskName =
|
|
5028
|
+
const taskName = `${operation.charAt(0).toUpperCase() + operation.slice(1)} ${tableName}`;
|
|
4604
5029
|
options = {
|
|
4605
5030
|
concurrency: 100,
|
|
4606
5031
|
timeout: 0,
|
|
@@ -4862,7 +5287,7 @@ var CadenzaService = class {
|
|
|
4862
5287
|
* This method is not supported in a browser environment and will log a warning if called in such an environment.
|
|
4863
5288
|
*
|
|
4864
5289
|
* @param {string} name - The name of the database service to be created.
|
|
4865
|
-
* @param {
|
|
5290
|
+
* @param {DatabaseSchemaDefinition} schema - The schema definition for the database service.
|
|
4866
5291
|
* @param {string} [description=""] - An optional description of the database service.
|
|
4867
5292
|
* @param {ServerOptions & DatabaseOptions} [options={}] - Optional configuration settings for the database and server.
|
|
4868
5293
|
* @return {void} This method does not return a value.
|
|
@@ -4926,7 +5351,7 @@ var CadenzaService = class {
|
|
|
4926
5351
|
* Creates a meta database service with the specified configuration.
|
|
4927
5352
|
*
|
|
4928
5353
|
* @param {string} name - The name of the database service to be created.
|
|
4929
|
-
* @param {
|
|
5354
|
+
* @param {DatabaseSchemaDefinition} schema - The schema definition for the database.
|
|
4930
5355
|
* @param {string} [description=""] - An optional description of the database service.
|
|
4931
5356
|
* @param {ServerOptions & DatabaseOptions} [options={}] - Optional server and database configuration options. The `isMeta` flag will be automatically set to true.
|
|
4932
5357
|
* @return {void} - This method does not return a value.
|