@aouda/client 0.1.14 → 0.1.15
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/cli/index.cjs +346 -73
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +346 -73
- package/dist/cli/index.js.map +1 -1
- package/dist/{client-BCMP-Fge.d.cts → client-CXfjcF61.d.cts} +99 -21
- package/dist/{client-BCMP-Fge.d.ts → client-CXfjcF61.d.ts} +99 -21
- package/dist/index.cjs +351 -72
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +348 -72
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,7 @@ __export(index_exports, {
|
|
|
60
60
|
MaterializedQueriesApi: () => MaterializedQueriesApi,
|
|
61
61
|
MaterializedQueryState: () => MaterializedQueryState,
|
|
62
62
|
MaterializedQueryType: () => MaterializedQueryType,
|
|
63
|
+
MemoryConsistencyTokenStore: () => MemoryConsistencyTokenStore,
|
|
63
64
|
MetricsAdminApi: () => MetricsAdminApi,
|
|
64
65
|
NamedMutationsApi: () => NamedMutationsApi,
|
|
65
66
|
NamedQueriesApi: () => NamedQueriesApi,
|
|
@@ -75,10 +76,12 @@ __export(index_exports, {
|
|
|
75
76
|
applyLocalNetworkAccess: () => applyLocalNetworkAccess,
|
|
76
77
|
coerceColumnarValue: () => coerceColumnarValue,
|
|
77
78
|
columnarToRows: () => columnarToRows,
|
|
79
|
+
compareOrdinal: () => compareOrdinal,
|
|
78
80
|
createAoudaClient: () => createAoudaClient,
|
|
79
81
|
createAoudaClusterMcpToolSet: () => createAoudaClusterMcpToolSet,
|
|
80
82
|
installLocalNetworkFetch: () => installLocalNetworkFetch,
|
|
81
83
|
localNetworkFetch: () => localNetworkFetch,
|
|
84
|
+
maxToken: () => maxToken,
|
|
82
85
|
resolveTargetAddressSpace: () => resolveTargetAddressSpace,
|
|
83
86
|
version: () => version
|
|
84
87
|
});
|
|
@@ -87,7 +90,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
87
90
|
// package.json
|
|
88
91
|
var package_default = {
|
|
89
92
|
name: "@aouda/client",
|
|
90
|
-
version: "0.1.
|
|
93
|
+
version: "0.1.15",
|
|
91
94
|
description: "Official TypeScript/JavaScript client library for Aouda",
|
|
92
95
|
type: "module",
|
|
93
96
|
main: "./dist/index.cjs",
|
|
@@ -219,43 +222,44 @@ var AoudaResponseError = class extends AoudaError {
|
|
|
219
222
|
}
|
|
220
223
|
};
|
|
221
224
|
var AoudaApiError = class extends AoudaError {
|
|
222
|
-
constructor(message, code, statusCode, details, requestId, retryAfterSeconds) {
|
|
225
|
+
constructor(message, code, statusCode, details, requestId, retryAfterSeconds, token) {
|
|
223
226
|
super(message);
|
|
224
227
|
this.code = code;
|
|
225
228
|
this.statusCode = statusCode;
|
|
226
229
|
this.details = details;
|
|
227
230
|
this.requestId = requestId;
|
|
228
231
|
this.retryAfterSeconds = retryAfterSeconds;
|
|
232
|
+
this.token = token;
|
|
229
233
|
this.name = "AoudaApiError";
|
|
230
234
|
}
|
|
231
235
|
};
|
|
232
236
|
var AoudaNotFoundError = class extends AoudaApiError {
|
|
233
|
-
constructor(message, code, statusCode, details, requestId) {
|
|
234
|
-
super(message, code, statusCode, details, requestId);
|
|
237
|
+
constructor(message, code, statusCode, details, requestId, retryAfterSeconds, token) {
|
|
238
|
+
super(message, code, statusCode, details, requestId, retryAfterSeconds, token);
|
|
235
239
|
this.name = "AoudaNotFoundError";
|
|
236
240
|
}
|
|
237
241
|
};
|
|
238
242
|
var AoudaConflictError = class extends AoudaApiError {
|
|
239
|
-
constructor(message, code, statusCode, details, requestId) {
|
|
240
|
-
super(message, code, statusCode, details, requestId);
|
|
243
|
+
constructor(message, code, statusCode, details, requestId, retryAfterSeconds, token) {
|
|
244
|
+
super(message, code, statusCode, details, requestId, retryAfterSeconds, token);
|
|
241
245
|
this.name = "AoudaConflictError";
|
|
242
246
|
}
|
|
243
247
|
};
|
|
244
248
|
var AoudaValidationError = class extends AoudaApiError {
|
|
245
|
-
constructor(message, code, statusCode, details, requestId) {
|
|
246
|
-
super(message, code, statusCode, details, requestId);
|
|
249
|
+
constructor(message, code, statusCode, details, requestId, retryAfterSeconds, token) {
|
|
250
|
+
super(message, code, statusCode, details, requestId, retryAfterSeconds, token);
|
|
247
251
|
this.name = "AoudaValidationError";
|
|
248
252
|
}
|
|
249
253
|
};
|
|
250
254
|
var AoudaServerError = class extends AoudaApiError {
|
|
251
|
-
constructor(message, code, statusCode, details, requestId, retryAfterSeconds) {
|
|
252
|
-
super(message, code, statusCode, details, requestId, retryAfterSeconds);
|
|
255
|
+
constructor(message, code, statusCode, details, requestId, retryAfterSeconds, token) {
|
|
256
|
+
super(message, code, statusCode, details, requestId, retryAfterSeconds, token);
|
|
253
257
|
this.name = "AoudaServerError";
|
|
254
258
|
}
|
|
255
259
|
};
|
|
256
260
|
var AoudaAuthenticationError = class extends AoudaApiError {
|
|
257
|
-
constructor(message, code, statusCode, details, requestId) {
|
|
258
|
-
super(message, code, statusCode, details, requestId);
|
|
261
|
+
constructor(message, code, statusCode, details, requestId, retryAfterSeconds, token) {
|
|
262
|
+
super(message, code, statusCode, details, requestId, retryAfterSeconds, token);
|
|
259
263
|
this.name = "AoudaAuthenticationError";
|
|
260
264
|
}
|
|
261
265
|
};
|
|
@@ -1067,7 +1071,7 @@ function buildHandle(jobId, commitResp, wasResumed, transport, database, signal)
|
|
|
1067
1071
|
rowsDurablyCommitted: commitResp.rowsLoaded,
|
|
1068
1072
|
segmentsCreated: commitResp.segmentsCreated,
|
|
1069
1073
|
committedAtUtc: commitResp.committedAtUtc,
|
|
1070
|
-
|
|
1074
|
+
token: commitResp.token,
|
|
1071
1075
|
writeConcernSatisfied: commitResp.writeConcernAchieved ?? "acknowledged",
|
|
1072
1076
|
writeConcernTimedOut: commitResp.writeConcernTimedOut,
|
|
1073
1077
|
wasResumed,
|
|
@@ -1193,6 +1197,7 @@ var PROTOCOL_VERSION_HEADER = "X-Aouda-Protocol-Version";
|
|
|
1193
1197
|
var PROTOCOL_VERSION = "1";
|
|
1194
1198
|
var CONTENT_TYPE_JSON2 = "application/json";
|
|
1195
1199
|
var REQUEST_ID_HEADER2 = "X-Request-Id";
|
|
1200
|
+
var TOKEN_HEADER = "X-Aouda-Token";
|
|
1196
1201
|
var ERROR_CODE_MAP = {
|
|
1197
1202
|
TABLE_NOT_FOUND: AoudaNotFoundError,
|
|
1198
1203
|
COLUMN_NOT_FOUND: AoudaNotFoundError,
|
|
@@ -1232,7 +1237,12 @@ var ERROR_CODE_MAP = {
|
|
|
1232
1237
|
AUTH_IDENTITY_INVALID: AoudaValidationError,
|
|
1233
1238
|
AUTH_IDENTITY_NOT_FOUND: AoudaValidationError,
|
|
1234
1239
|
BULK_LOAD_TRANSFORM_INTENT_REQUIRED: AoudaValidationError,
|
|
1235
|
-
BULK_LOAD_TRANSFORM_INTENT_CONFLICT: AoudaValidationError
|
|
1240
|
+
BULK_LOAD_TRANSFORM_INTENT_CONFLICT: AoudaValidationError,
|
|
1241
|
+
TOKEN_MALFORMED: AoudaValidationError,
|
|
1242
|
+
TOKEN_FOREIGN_DATABASE: AoudaValidationError,
|
|
1243
|
+
TOKEN_EPOCH_SUPERSEDED: AoudaConflictError,
|
|
1244
|
+
TOKEN_UNSATISFIED: AoudaConflictError,
|
|
1245
|
+
TOKEN_FETCH_PRIMARY: AoudaApiError
|
|
1236
1246
|
};
|
|
1237
1247
|
function createComposedAbortController(...signals) {
|
|
1238
1248
|
const controller = new AbortController();
|
|
@@ -1269,7 +1279,7 @@ function createApiError(statusCode, statusText, body, retryAfterHeader) {
|
|
|
1269
1279
|
const requestId = body.requestId;
|
|
1270
1280
|
const retryAfterSeconds = parseRetryAfterSeconds(retryAfterHeader ?? null);
|
|
1271
1281
|
const Ctor = ERROR_CODE_MAP[code] ?? AoudaApiError;
|
|
1272
|
-
return new Ctor(message, code, statusCode, details, requestId, retryAfterSeconds);
|
|
1282
|
+
return new Ctor(message, code, statusCode, details, requestId, retryAfterSeconds, body.token);
|
|
1273
1283
|
}
|
|
1274
1284
|
var HttpTransport = class {
|
|
1275
1285
|
constructor(options) {
|
|
@@ -1281,6 +1291,29 @@ var HttpTransport = class {
|
|
|
1281
1291
|
...options.defaultHeaders
|
|
1282
1292
|
};
|
|
1283
1293
|
this.abortController = new AbortController();
|
|
1294
|
+
this.database = options.database;
|
|
1295
|
+
this.store = options.consistencyTokenStore;
|
|
1296
|
+
}
|
|
1297
|
+
presentTokenHeaders(path, headers) {
|
|
1298
|
+
if (this.store == null || this.database == null || isAuthPath(path)) {
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
const token = this.store.get(this.database);
|
|
1302
|
+
if (token != null && token.length > 0) {
|
|
1303
|
+
headers[TOKEN_HEADER] = token;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
observeResponse(_path, response, bodyText, errorCode) {
|
|
1307
|
+
if (this.store == null || this.database == null) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
if (errorCode === "TOKEN_MALFORMED" || errorCode === "TOKEN_FOREIGN_DATABASE") {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
const header = response.headers.get(TOKEN_HEADER);
|
|
1314
|
+
const bodyToken = readBodyToken(bodyText);
|
|
1315
|
+
const token = header != null && header.trim().length > 0 ? header : bodyToken;
|
|
1316
|
+
this.store.observe(this.database, token);
|
|
1284
1317
|
}
|
|
1285
1318
|
/**
|
|
1286
1319
|
* Abort all in-flight and future requests (e.g. on client disconnect).
|
|
@@ -1318,6 +1351,7 @@ var HttpTransport = class {
|
|
|
1318
1351
|
...this.defaultHeaders,
|
|
1319
1352
|
...config.headers
|
|
1320
1353
|
};
|
|
1354
|
+
this.presentTokenHeaders(config.path, headers);
|
|
1321
1355
|
if (config.body !== void 0 && config.body !== null) {
|
|
1322
1356
|
headers["Content-Type"] = CONTENT_TYPE_JSON2;
|
|
1323
1357
|
}
|
|
@@ -1337,6 +1371,7 @@ var HttpTransport = class {
|
|
|
1337
1371
|
const text = await response.text();
|
|
1338
1372
|
if (config.allowStatuses?.includes(response.status) && text) {
|
|
1339
1373
|
try {
|
|
1374
|
+
this.observeResponse(config.path, response, text);
|
|
1340
1375
|
return JSON.parse(text);
|
|
1341
1376
|
} catch {
|
|
1342
1377
|
}
|
|
@@ -1350,15 +1385,19 @@ var HttpTransport = class {
|
|
|
1350
1385
|
}
|
|
1351
1386
|
if (response.status === 401) {
|
|
1352
1387
|
const code = errorBody?.code ?? "AUTH_TOKEN_MISSING";
|
|
1388
|
+
this.observeResponse(config.path, response, text, code);
|
|
1353
1389
|
throw new AoudaAuthenticationError(
|
|
1354
1390
|
errorBody?.error ?? "Unauthorized",
|
|
1355
1391
|
code,
|
|
1356
1392
|
401,
|
|
1357
1393
|
errorBody?.details,
|
|
1358
|
-
errorBody?.requestId
|
|
1394
|
+
errorBody?.requestId,
|
|
1395
|
+
void 0,
|
|
1396
|
+
errorBody?.token
|
|
1359
1397
|
);
|
|
1360
1398
|
}
|
|
1361
1399
|
if (errorBody?.code != null) {
|
|
1400
|
+
this.observeResponse(config.path, response, text, errorBody.code);
|
|
1362
1401
|
throw createApiError(
|
|
1363
1402
|
response.status,
|
|
1364
1403
|
response.statusText,
|
|
@@ -1366,6 +1405,7 @@ var HttpTransport = class {
|
|
|
1366
1405
|
response.headers.get("Retry-After")
|
|
1367
1406
|
);
|
|
1368
1407
|
}
|
|
1408
|
+
this.observeResponse(config.path, response, text);
|
|
1369
1409
|
throw new AoudaResponseError(
|
|
1370
1410
|
errorBody?.error ?? `${response.status} ${response.statusText}`,
|
|
1371
1411
|
response.status,
|
|
@@ -1373,6 +1413,7 @@ var HttpTransport = class {
|
|
|
1373
1413
|
);
|
|
1374
1414
|
}
|
|
1375
1415
|
const responseText = await response.text();
|
|
1416
|
+
this.observeResponse(config.path, response, responseText);
|
|
1376
1417
|
if (config.rawText) {
|
|
1377
1418
|
return responseText;
|
|
1378
1419
|
}
|
|
@@ -1433,6 +1474,7 @@ var HttpTransport = class {
|
|
|
1433
1474
|
...this.defaultHeaders,
|
|
1434
1475
|
...config.headers
|
|
1435
1476
|
};
|
|
1477
|
+
this.presentTokenHeaders(config.path, headers);
|
|
1436
1478
|
if (config.rawBodyStr === void 0 && config.body !== void 0 && config.body !== null) {
|
|
1437
1479
|
headers["Content-Type"] = CONTENT_TYPE_JSON2;
|
|
1438
1480
|
}
|
|
@@ -1449,6 +1491,7 @@ var HttpTransport = class {
|
|
|
1449
1491
|
try {
|
|
1450
1492
|
const response = await localNetworkFetch(url, init);
|
|
1451
1493
|
if (response.ok || config.allowStatuses?.includes(response.status)) {
|
|
1494
|
+
this.observeResponse(config.path, response, void 0);
|
|
1452
1495
|
return response;
|
|
1453
1496
|
}
|
|
1454
1497
|
const text = await response.text();
|
|
@@ -1461,15 +1504,19 @@ var HttpTransport = class {
|
|
|
1461
1504
|
}
|
|
1462
1505
|
if (response.status === 401) {
|
|
1463
1506
|
const code = errorBody?.code ?? "AUTH_TOKEN_MISSING";
|
|
1507
|
+
this.observeResponse(config.path, response, text, code);
|
|
1464
1508
|
throw new AoudaAuthenticationError(
|
|
1465
1509
|
errorBody?.error ?? "Unauthorized",
|
|
1466
1510
|
code,
|
|
1467
1511
|
401,
|
|
1468
1512
|
errorBody?.details,
|
|
1469
|
-
errorBody?.requestId
|
|
1513
|
+
errorBody?.requestId,
|
|
1514
|
+
void 0,
|
|
1515
|
+
errorBody?.token
|
|
1470
1516
|
);
|
|
1471
1517
|
}
|
|
1472
1518
|
if (errorBody?.code != null) {
|
|
1519
|
+
this.observeResponse(config.path, response, text, errorBody.code);
|
|
1473
1520
|
throw createApiError(
|
|
1474
1521
|
response.status,
|
|
1475
1522
|
response.statusText,
|
|
@@ -1477,6 +1524,7 @@ var HttpTransport = class {
|
|
|
1477
1524
|
response.headers.get("Retry-After")
|
|
1478
1525
|
);
|
|
1479
1526
|
}
|
|
1527
|
+
this.observeResponse(config.path, response, text);
|
|
1480
1528
|
throw new AoudaResponseError(
|
|
1481
1529
|
errorBody?.error ?? `${response.status} ${response.statusText}`,
|
|
1482
1530
|
response.status,
|
|
@@ -1631,6 +1679,47 @@ var HttpTransport = class {
|
|
|
1631
1679
|
});
|
|
1632
1680
|
}
|
|
1633
1681
|
};
|
|
1682
|
+
function isAuthPath(path) {
|
|
1683
|
+
let p = path;
|
|
1684
|
+
const q = p.indexOf("?");
|
|
1685
|
+
if (q >= 0) {
|
|
1686
|
+
p = p.slice(0, q);
|
|
1687
|
+
}
|
|
1688
|
+
if (/^https?:\/\//i.test(p)) {
|
|
1689
|
+
try {
|
|
1690
|
+
p = new URL(p).pathname;
|
|
1691
|
+
} catch {
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
const lower = p.toLowerCase();
|
|
1695
|
+
if (lower === "/api/auth" || lower.startsWith("/api/auth/")) {
|
|
1696
|
+
return true;
|
|
1697
|
+
}
|
|
1698
|
+
const prefix = "/api/databases/";
|
|
1699
|
+
if (!lower.startsWith(prefix)) {
|
|
1700
|
+
return false;
|
|
1701
|
+
}
|
|
1702
|
+
const rest = lower.slice(prefix.length);
|
|
1703
|
+
const slash = rest.indexOf("/");
|
|
1704
|
+
if (slash < 0) {
|
|
1705
|
+
return false;
|
|
1706
|
+
}
|
|
1707
|
+
const afterDb = rest.slice(slash + 1);
|
|
1708
|
+
return afterDb === "auth" || afterDb.startsWith("auth/");
|
|
1709
|
+
}
|
|
1710
|
+
function readBodyToken(bodyText) {
|
|
1711
|
+
if (bodyText == null || bodyText.trim().length === 0) {
|
|
1712
|
+
return void 0;
|
|
1713
|
+
}
|
|
1714
|
+
try {
|
|
1715
|
+
const parsed = JSON.parse(bodyText);
|
|
1716
|
+
if (parsed !== null && typeof parsed === "object" && "token" in parsed && typeof parsed.token === "string") {
|
|
1717
|
+
return parsed.token;
|
|
1718
|
+
}
|
|
1719
|
+
} catch {
|
|
1720
|
+
}
|
|
1721
|
+
return void 0;
|
|
1722
|
+
}
|
|
1634
1723
|
|
|
1635
1724
|
// src/resilience/retry.ts
|
|
1636
1725
|
var DEFAULT_MAX_RETRIES = 3;
|
|
@@ -2063,6 +2152,48 @@ function databasePath2(db) {
|
|
|
2063
2152
|
return `/api/databases/${encodeURIComponent(db)}`;
|
|
2064
2153
|
}
|
|
2065
2154
|
|
|
2155
|
+
// src/consistency-token-store.ts
|
|
2156
|
+
var MemoryConsistencyTokenStore = class {
|
|
2157
|
+
constructor() {
|
|
2158
|
+
this.tokens = /* @__PURE__ */ new Map();
|
|
2159
|
+
}
|
|
2160
|
+
get(database) {
|
|
2161
|
+
if (typeof database !== "string" || database.trim().length === 0) {
|
|
2162
|
+
throw new Error("database must be a non-empty string");
|
|
2163
|
+
}
|
|
2164
|
+
return this.tokens.get(normalizeKey(database));
|
|
2165
|
+
}
|
|
2166
|
+
observe(database, token) {
|
|
2167
|
+
if (typeof database !== "string" || database.trim().length === 0) {
|
|
2168
|
+
throw new Error("database must be a non-empty string");
|
|
2169
|
+
}
|
|
2170
|
+
if (token == null || token.trim().length === 0) {
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
const key = normalizeKey(database);
|
|
2174
|
+
const stored = this.tokens.get(key);
|
|
2175
|
+
if (stored === void 0 || compareOrdinal(token, stored) > 0) {
|
|
2176
|
+
this.tokens.set(key, token);
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
};
|
|
2180
|
+
function compareOrdinal(left, right) {
|
|
2181
|
+
if (left === right) return 0;
|
|
2182
|
+
return left < right ? -1 : 1;
|
|
2183
|
+
}
|
|
2184
|
+
function maxToken(left, right) {
|
|
2185
|
+
if (left == null || left.length === 0) {
|
|
2186
|
+
return right == null || right.length === 0 ? void 0 : right;
|
|
2187
|
+
}
|
|
2188
|
+
if (right == null || right.length === 0) {
|
|
2189
|
+
return left;
|
|
2190
|
+
}
|
|
2191
|
+
return compareOrdinal(left, right) >= 0 ? left : right;
|
|
2192
|
+
}
|
|
2193
|
+
function normalizeKey(database) {
|
|
2194
|
+
return database.toLowerCase();
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2066
2197
|
// src/streaming/subscription.ts
|
|
2067
2198
|
var AsyncEventQueue = class {
|
|
2068
2199
|
constructor() {
|
|
@@ -2119,7 +2250,7 @@ var AsyncEventQueue = class {
|
|
|
2119
2250
|
}
|
|
2120
2251
|
};
|
|
2121
2252
|
var TableSubscription = class {
|
|
2122
|
-
constructor(transport, identity, options = {}, onWarnings) {
|
|
2253
|
+
constructor(transport, identity, options = {}, onWarnings, store, database) {
|
|
2123
2254
|
this._queue = new AsyncEventQueue();
|
|
2124
2255
|
this._active = true;
|
|
2125
2256
|
this._started = false;
|
|
@@ -2135,6 +2266,11 @@ var TableSubscription = class {
|
|
|
2135
2266
|
this._onError = options.onError;
|
|
2136
2267
|
this._onWarnings = onWarnings;
|
|
2137
2268
|
this._conflate = options.conflate;
|
|
2269
|
+
this._atLeast = options.atLeast;
|
|
2270
|
+
this._waitMs = options.waitMs;
|
|
2271
|
+
this._onExceeded = options.onExceeded;
|
|
2272
|
+
this._store = store;
|
|
2273
|
+
this._database = database;
|
|
2138
2274
|
this._reconnectHandlerKey = `${this.id}::reconnect`;
|
|
2139
2275
|
}
|
|
2140
2276
|
get lastVersion() {
|
|
@@ -2199,7 +2335,7 @@ var TableSubscription = class {
|
|
|
2199
2335
|
id: this.id
|
|
2200
2336
|
};
|
|
2201
2337
|
if (this._identity.kind === "named") {
|
|
2202
|
-
message.
|
|
2338
|
+
message.name = this._identity.name;
|
|
2203
2339
|
if (this._identity.args !== void 0) {
|
|
2204
2340
|
message.args = this._identity.args;
|
|
2205
2341
|
}
|
|
@@ -2218,8 +2354,30 @@ var TableSubscription = class {
|
|
|
2218
2354
|
if (this._conflate !== void 0) {
|
|
2219
2355
|
message.conflate = this._conflate;
|
|
2220
2356
|
}
|
|
2357
|
+
const pin = this._resolvePin();
|
|
2358
|
+
if (pin !== void 0) {
|
|
2359
|
+
message.at_least = pin;
|
|
2360
|
+
}
|
|
2361
|
+
if (this._waitMs !== void 0) {
|
|
2362
|
+
message.wait_ms = this._waitMs;
|
|
2363
|
+
}
|
|
2364
|
+
if (this._onExceeded !== void 0) {
|
|
2365
|
+
message.on_exceeded = this._onExceeded;
|
|
2366
|
+
}
|
|
2221
2367
|
await this._transport.send(message);
|
|
2222
2368
|
}
|
|
2369
|
+
_resolvePin() {
|
|
2370
|
+
if (this._atLeast !== void 0 && this._store != null && this._database != null) {
|
|
2371
|
+
this._store.observe(this._database, this._atLeast);
|
|
2372
|
+
}
|
|
2373
|
+
const stored = this._store != null && this._database != null ? this._store.get(this._database) : void 0;
|
|
2374
|
+
return maxToken(this._atLeast, stored);
|
|
2375
|
+
}
|
|
2376
|
+
_observeToken(token) {
|
|
2377
|
+
if (token !== void 0 && this._store != null && this._database != null) {
|
|
2378
|
+
this._store.observe(this._database, token);
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2223
2381
|
_handleMessage(message) {
|
|
2224
2382
|
if (!this._active) {
|
|
2225
2383
|
return;
|
|
@@ -2246,6 +2404,7 @@ var TableSubscription = class {
|
|
|
2246
2404
|
}
|
|
2247
2405
|
_handleSnapshotPage(message) {
|
|
2248
2406
|
this._pendingSnapshotRows.push(...message.rows);
|
|
2407
|
+
this._observeToken(message.token);
|
|
2249
2408
|
}
|
|
2250
2409
|
_handleSnapshotComplete(message) {
|
|
2251
2410
|
this._lastVersion = message.version;
|
|
@@ -2263,6 +2422,10 @@ var TableSubscription = class {
|
|
|
2263
2422
|
if (message.total_matches !== void 0) {
|
|
2264
2423
|
snapshot.totalMatches = message.total_matches;
|
|
2265
2424
|
}
|
|
2425
|
+
if (message.token !== void 0) {
|
|
2426
|
+
snapshot.token = message.token;
|
|
2427
|
+
this._observeToken(message.token);
|
|
2428
|
+
}
|
|
2266
2429
|
this._queue.push(snapshot);
|
|
2267
2430
|
}
|
|
2268
2431
|
async _handleGap(message) {
|
|
@@ -2288,6 +2451,10 @@ var TableSubscription = class {
|
|
|
2288
2451
|
if (message.values_skipped !== void 0) {
|
|
2289
2452
|
event.values_skipped = message.values_skipped;
|
|
2290
2453
|
}
|
|
2454
|
+
if (message.token !== void 0) {
|
|
2455
|
+
event.token = message.token;
|
|
2456
|
+
this._observeToken(message.token);
|
|
2457
|
+
}
|
|
2291
2458
|
this._onChange?.(event);
|
|
2292
2459
|
this._queue.push(event);
|
|
2293
2460
|
}
|
|
@@ -2632,11 +2799,12 @@ var TableQuery = class _TableQuery {
|
|
|
2632
2799
|
* @param state - Optional initial state (used for immutable chaining).
|
|
2633
2800
|
* @internal Use `client.table()` to create queries.
|
|
2634
2801
|
*/
|
|
2635
|
-
constructor(transport, tableName, database, state, getWebSocketTransport) {
|
|
2802
|
+
constructor(transport, tableName, database, state, getWebSocketTransport, store) {
|
|
2636
2803
|
this.transport = transport;
|
|
2637
2804
|
this.tableName = tableName;
|
|
2638
2805
|
this.database = database;
|
|
2639
2806
|
this.getWebSocketTransport = getWebSocketTransport;
|
|
2807
|
+
this.store = store;
|
|
2640
2808
|
this.state = state ?? {
|
|
2641
2809
|
predicates: [],
|
|
2642
2810
|
groupClauses: [],
|
|
@@ -2652,6 +2820,16 @@ var TableQuery = class _TableQuery {
|
|
|
2652
2820
|
isDistinct: false
|
|
2653
2821
|
};
|
|
2654
2822
|
}
|
|
2823
|
+
withState(state) {
|
|
2824
|
+
return new _TableQuery(
|
|
2825
|
+
this.transport,
|
|
2826
|
+
this.tableName,
|
|
2827
|
+
this.database,
|
|
2828
|
+
state,
|
|
2829
|
+
this.getWebSocketTransport,
|
|
2830
|
+
this.store
|
|
2831
|
+
);
|
|
2832
|
+
}
|
|
2655
2833
|
where(column, operator, value) {
|
|
2656
2834
|
const newPredicates = buildWherePredicates(column, operator, value);
|
|
2657
2835
|
return new _TableQuery(
|
|
@@ -2662,7 +2840,8 @@ var TableQuery = class _TableQuery {
|
|
|
2662
2840
|
...this.state,
|
|
2663
2841
|
predicates: [...this.state.predicates, ...newPredicates]
|
|
2664
2842
|
},
|
|
2665
|
-
this.getWebSocketTransport
|
|
2843
|
+
this.getWebSocketTransport,
|
|
2844
|
+
this.store
|
|
2666
2845
|
);
|
|
2667
2846
|
}
|
|
2668
2847
|
/**
|
|
@@ -2681,7 +2860,7 @@ var TableQuery = class _TableQuery {
|
|
|
2681
2860
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2682
2861
|
...this.state,
|
|
2683
2862
|
groupClauses: [...this.state.groupClauses, sub]
|
|
2684
|
-
}, this.getWebSocketTransport);
|
|
2863
|
+
}, this.getWebSocketTransport, this.store);
|
|
2685
2864
|
}
|
|
2686
2865
|
/**
|
|
2687
2866
|
* Sets the primary sort column for the query.
|
|
@@ -2706,7 +2885,7 @@ var TableQuery = class _TableQuery {
|
|
|
2706
2885
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2707
2886
|
...this.state,
|
|
2708
2887
|
orderByClauses: [orderByClause]
|
|
2709
|
-
}, this.getWebSocketTransport);
|
|
2888
|
+
}, this.getWebSocketTransport, this.store);
|
|
2710
2889
|
}
|
|
2711
2890
|
/**
|
|
2712
2891
|
* Sets the primary sort column to descending order.
|
|
@@ -2752,7 +2931,7 @@ var TableQuery = class _TableQuery {
|
|
|
2752
2931
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2753
2932
|
...this.state,
|
|
2754
2933
|
orderByClauses: [...this.state.orderByClauses, orderByClause]
|
|
2755
|
-
}, this.getWebSocketTransport);
|
|
2934
|
+
}, this.getWebSocketTransport, this.store);
|
|
2756
2935
|
}
|
|
2757
2936
|
/**
|
|
2758
2937
|
* Sets the maximum number of rows to return.
|
|
@@ -2769,7 +2948,7 @@ var TableQuery = class _TableQuery {
|
|
|
2769
2948
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2770
2949
|
...this.state,
|
|
2771
2950
|
limitValue: count
|
|
2772
|
-
}, this.getWebSocketTransport);
|
|
2951
|
+
}, this.getWebSocketTransport, this.store);
|
|
2773
2952
|
}
|
|
2774
2953
|
/**
|
|
2775
2954
|
* Sets the number of rows to skip.
|
|
@@ -2786,7 +2965,7 @@ var TableQuery = class _TableQuery {
|
|
|
2786
2965
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2787
2966
|
...this.state,
|
|
2788
2967
|
offsetValue: count
|
|
2789
|
-
}, this.getWebSocketTransport);
|
|
2968
|
+
}, this.getWebSocketTransport, this.store);
|
|
2790
2969
|
}
|
|
2791
2970
|
/**
|
|
2792
2971
|
* Requests cross-partition access for this query.
|
|
@@ -2801,10 +2980,21 @@ var TableQuery = class _TableQuery {
|
|
|
2801
2980
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2802
2981
|
...this.state,
|
|
2803
2982
|
crossPartitionAccess: true
|
|
2804
|
-
}, this.getWebSocketTransport);
|
|
2983
|
+
}, this.getWebSocketTransport, this.store);
|
|
2805
2984
|
}
|
|
2806
2985
|
/**
|
|
2807
|
-
*
|
|
2986
|
+
* Pin this query at at least this C-1 token. Observes the token into the
|
|
2987
|
+
* client store (I3, sticky) and presents it on execute via `X-Aouda-Token`.
|
|
2988
|
+
*/
|
|
2989
|
+
atLeast(token) {
|
|
2990
|
+
if (typeof token !== "string" || token.trim().length === 0) {
|
|
2991
|
+
throw new Error("atLeast() requires a non-empty token");
|
|
2992
|
+
}
|
|
2993
|
+
this.store?.observe(this.database, token);
|
|
2994
|
+
return this.withState({ ...this.state, atLeast: token });
|
|
2995
|
+
}
|
|
2996
|
+
/**
|
|
2997
|
+
* Selects specific columns to return.
|
|
2808
2998
|
* If not called, all columns are returned.
|
|
2809
2999
|
*
|
|
2810
3000
|
* When T is a specific row type, only keys of T are accepted as column names.
|
|
@@ -2826,7 +3016,7 @@ var TableQuery = class _TableQuery {
|
|
|
2826
3016
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2827
3017
|
...this.state,
|
|
2828
3018
|
selectColumns: columns.length > 0 ? columns : null
|
|
2829
|
-
}, this.getWebSocketTransport);
|
|
3019
|
+
}, this.getWebSocketTransport, this.store);
|
|
2830
3020
|
}
|
|
2831
3021
|
/**
|
|
2832
3022
|
* Return only distinct (de-duplicated) rows for the given columns — SQL `SELECT DISTINCT`.
|
|
@@ -2856,7 +3046,7 @@ var TableQuery = class _TableQuery {
|
|
|
2856
3046
|
...this.state,
|
|
2857
3047
|
selectColumns: columns,
|
|
2858
3048
|
isDistinct: true
|
|
2859
|
-
}, this.getWebSocketTransport);
|
|
3049
|
+
}, this.getWebSocketTransport, this.store);
|
|
2860
3050
|
}
|
|
2861
3051
|
/**
|
|
2862
3052
|
* Adds server-side computed columns to the query result.
|
|
@@ -2885,7 +3075,7 @@ var TableQuery = class _TableQuery {
|
|
|
2885
3075
|
return new _TableQuery(this.transport, this.tableName, this.database, {
|
|
2886
3076
|
...this.state,
|
|
2887
3077
|
selectExprs: projections
|
|
2888
|
-
}, this.getWebSocketTransport);
|
|
3078
|
+
}, this.getWebSocketTransport, this.store);
|
|
2889
3079
|
}
|
|
2890
3080
|
join(rightTable, leftColumnOrColumns, rightColumnOrColumns) {
|
|
2891
3081
|
return this.addJoinClause(
|
|
@@ -2943,7 +3133,8 @@ var TableQuery = class _TableQuery {
|
|
|
2943
3133
|
}
|
|
2944
3134
|
]
|
|
2945
3135
|
},
|
|
2946
|
-
this.getWebSocketTransport
|
|
3136
|
+
this.getWebSocketTransport,
|
|
3137
|
+
this.store
|
|
2947
3138
|
);
|
|
2948
3139
|
}
|
|
2949
3140
|
/**
|
|
@@ -2979,7 +3170,8 @@ var TableQuery = class _TableQuery {
|
|
|
2979
3170
|
...this.state,
|
|
2980
3171
|
groupByColumns: [...columns]
|
|
2981
3172
|
},
|
|
2982
|
-
this.getWebSocketTransport
|
|
3173
|
+
this.getWebSocketTransport,
|
|
3174
|
+
this.store
|
|
2983
3175
|
);
|
|
2984
3176
|
}
|
|
2985
3177
|
/**
|
|
@@ -3013,8 +3205,11 @@ var TableQuery = class _TableQuery {
|
|
|
3013
3205
|
onSnapshot: options.onSnapshot,
|
|
3014
3206
|
onChange: options.onChange,
|
|
3015
3207
|
onError: options.onError,
|
|
3016
|
-
conflate: options.conflate
|
|
3017
|
-
|
|
3208
|
+
conflate: options.conflate,
|
|
3209
|
+
atLeast: options.atLeast ?? this.state.atLeast,
|
|
3210
|
+
waitMs: options.waitMs,
|
|
3211
|
+
onExceeded: options.onExceeded
|
|
3212
|
+
}, void 0, this.store, this.database);
|
|
3018
3213
|
subscription.start();
|
|
3019
3214
|
return subscription;
|
|
3020
3215
|
}
|
|
@@ -3129,7 +3324,8 @@ var TableQuery = class _TableQuery {
|
|
|
3129
3324
|
...this.state,
|
|
3130
3325
|
joinClauses: [...this.state.joinClauses, joinClause]
|
|
3131
3326
|
},
|
|
3132
|
-
this.getWebSocketTransport
|
|
3327
|
+
this.getWebSocketTransport,
|
|
3328
|
+
this.store
|
|
3133
3329
|
);
|
|
3134
3330
|
}
|
|
3135
3331
|
addAggregate(op, column) {
|
|
@@ -3150,7 +3346,8 @@ var TableQuery = class _TableQuery {
|
|
|
3150
3346
|
}
|
|
3151
3347
|
]
|
|
3152
3348
|
},
|
|
3153
|
-
this.getWebSocketTransport
|
|
3349
|
+
this.getWebSocketTransport,
|
|
3350
|
+
this.store
|
|
3154
3351
|
);
|
|
3155
3352
|
}
|
|
3156
3353
|
requireWebSocketTransport() {
|
|
@@ -3180,17 +3377,23 @@ var TableQuery = class _TableQuery {
|
|
|
3180
3377
|
* ```
|
|
3181
3378
|
*/
|
|
3182
3379
|
async execute() {
|
|
3380
|
+
if (this.state.atLeast) {
|
|
3381
|
+
this.store?.observe(this.database, this.state.atLeast);
|
|
3382
|
+
}
|
|
3183
3383
|
const request = this.buildRequest();
|
|
3184
3384
|
const path = `${databasePath2(this.database)}/query`;
|
|
3185
3385
|
const response = await this.transport.post(path, request);
|
|
3186
3386
|
const rows = columnarToRows(response);
|
|
3187
3387
|
const stats = response.stats;
|
|
3188
|
-
return { rows, stats };
|
|
3388
|
+
return { rows, stats, token: response.token };
|
|
3189
3389
|
}
|
|
3190
3390
|
/**
|
|
3191
3391
|
* Executes the query and returns the raw columnar JSON payload (no row-object conversion).
|
|
3192
3392
|
*/
|
|
3193
3393
|
async toColumnar() {
|
|
3394
|
+
if (this.state.atLeast) {
|
|
3395
|
+
this.store?.observe(this.database, this.state.atLeast);
|
|
3396
|
+
}
|
|
3194
3397
|
const request = this.buildRequest();
|
|
3195
3398
|
const path = `${databasePath2(this.database)}/query`;
|
|
3196
3399
|
return this.transport.post(path, request);
|
|
@@ -3220,8 +3423,12 @@ var TableQuery = class _TableQuery {
|
|
|
3220
3423
|
limitValue: 0,
|
|
3221
3424
|
selectColumns: []
|
|
3222
3425
|
},
|
|
3223
|
-
this.getWebSocketTransport
|
|
3426
|
+
this.getWebSocketTransport,
|
|
3427
|
+
this.store
|
|
3224
3428
|
);
|
|
3429
|
+
if (this.state.atLeast) {
|
|
3430
|
+
this.store?.observe(this.database, this.state.atLeast);
|
|
3431
|
+
}
|
|
3225
3432
|
const request = countQuery.buildRequest();
|
|
3226
3433
|
const path = `${databasePath2(this.database)}/query`;
|
|
3227
3434
|
const response = await this.transport.post(path, request);
|
|
@@ -3268,7 +3475,8 @@ var TableQuery = class _TableQuery {
|
|
|
3268
3475
|
const response = await this.transport.post(path, body);
|
|
3269
3476
|
const result = {
|
|
3270
3477
|
rowsInserted: response.rowsInserted,
|
|
3271
|
-
executionMs: response.executionMs
|
|
3478
|
+
executionMs: response.executionMs,
|
|
3479
|
+
token: response.token
|
|
3272
3480
|
};
|
|
3273
3481
|
if (response.generatedValues !== void 0) {
|
|
3274
3482
|
result.generatedValues = response.generatedValues;
|
|
@@ -3318,7 +3526,8 @@ var TableQuery = class _TableQuery {
|
|
|
3318
3526
|
const response = await this.transport.post(path, body);
|
|
3319
3527
|
const result = {
|
|
3320
3528
|
rowsInserted: response.rowsInserted,
|
|
3321
|
-
executionMs: response.executionMs
|
|
3529
|
+
executionMs: response.executionMs,
|
|
3530
|
+
token: response.token
|
|
3322
3531
|
};
|
|
3323
3532
|
if (response.generatedValues !== void 0) {
|
|
3324
3533
|
result.generatedValues = response.generatedValues;
|
|
@@ -3370,6 +3579,7 @@ var TableQuery = class _TableQuery {
|
|
|
3370
3579
|
return {
|
|
3371
3580
|
rowsAffected: response.rowsUpdated,
|
|
3372
3581
|
executionMs: response.executionMs,
|
|
3582
|
+
token: response.token,
|
|
3373
3583
|
...response.rows ? { rows: columnarToRows(response.rows) } : {},
|
|
3374
3584
|
...response.rowsTruncated ? { rowsTruncated: true } : {}
|
|
3375
3585
|
};
|
|
@@ -3420,6 +3630,7 @@ var TableQuery = class _TableQuery {
|
|
|
3420
3630
|
rowsAffected: response.rowsDeleted,
|
|
3421
3631
|
executionMs: response.executionMs,
|
|
3422
3632
|
hasMore: response.hasMore,
|
|
3633
|
+
token: response.token,
|
|
3423
3634
|
...response.rows ? { rows: columnarToRows(response.rows) } : {},
|
|
3424
3635
|
...response.rowsTruncated ? { rowsTruncated: true } : {}
|
|
3425
3636
|
};
|
|
@@ -3439,7 +3650,8 @@ var TableQuery = class _TableQuery {
|
|
|
3439
3650
|
return {
|
|
3440
3651
|
rowsAffected: response.rowsDeleted,
|
|
3441
3652
|
executionMs: response.executionMs,
|
|
3442
|
-
hasMore: false
|
|
3653
|
+
hasMore: false,
|
|
3654
|
+
token: response.token
|
|
3443
3655
|
};
|
|
3444
3656
|
}
|
|
3445
3657
|
/**
|
|
@@ -3452,7 +3664,14 @@ var TableQuery = class _TableQuery {
|
|
|
3452
3664
|
throw new Error("batch() requires a non-empty operations array");
|
|
3453
3665
|
}
|
|
3454
3666
|
const wireOperations = operations.map((op, index) => {
|
|
3455
|
-
const base = new _TableQuery(
|
|
3667
|
+
const base = new _TableQuery(
|
|
3668
|
+
this.transport,
|
|
3669
|
+
this.tableName,
|
|
3670
|
+
this.database,
|
|
3671
|
+
void 0,
|
|
3672
|
+
this.getWebSocketTransport,
|
|
3673
|
+
this.store
|
|
3674
|
+
);
|
|
3456
3675
|
const scoped = op.where(base);
|
|
3457
3676
|
const where = scoped.buildWhereClause();
|
|
3458
3677
|
if (!where) {
|
|
@@ -4820,12 +5039,12 @@ function raiseDeprecationWarnings(sink, warnings) {
|
|
|
4820
5039
|
continue;
|
|
4821
5040
|
}
|
|
4822
5041
|
const sunset = warning.sunsetAt != null ? ` sunsetAt=${warning.sunsetAt}` : "";
|
|
4823
|
-
const
|
|
5042
|
+
const name = warning.name != null && warning.name.length > 0 ? ` name=${warning.name}` : "";
|
|
4824
5043
|
sink({
|
|
4825
5044
|
code: warning.code,
|
|
4826
|
-
|
|
5045
|
+
name: warning.name,
|
|
4827
5046
|
sunsetAt: warning.sunsetAt,
|
|
4828
|
-
message: `${warning.code}:${
|
|
5047
|
+
message: `${warning.code}:${name}${sunset}`.trim()
|
|
4829
5048
|
});
|
|
4830
5049
|
}
|
|
4831
5050
|
}
|
|
@@ -4838,24 +5057,28 @@ function emptyStats() {
|
|
|
4838
5057
|
};
|
|
4839
5058
|
}
|
|
4840
5059
|
var NamedQueriesApi = class {
|
|
4841
|
-
constructor(transport, database, onWarning, getStreamingTransport) {
|
|
5060
|
+
constructor(transport, database, onWarning, getStreamingTransport, store) {
|
|
4842
5061
|
this.transport = transport;
|
|
4843
5062
|
this.database = database;
|
|
4844
5063
|
this.onWarning = onWarning;
|
|
4845
5064
|
this.getStreamingTransport = getStreamingTransport;
|
|
5065
|
+
this.store = store;
|
|
4846
5066
|
}
|
|
4847
|
-
async execute(
|
|
4848
|
-
if (typeof
|
|
4849
|
-
throw new Error("Named query
|
|
5067
|
+
async execute(name, args, options) {
|
|
5068
|
+
if (typeof name !== "string" || name.trim().length === 0) {
|
|
5069
|
+
throw new Error("Named query name must be a non-empty string");
|
|
4850
5070
|
}
|
|
4851
5071
|
const prefix = databasePath2(this.database);
|
|
4852
|
-
const path = `${prefix}/named-queries/${encodeURIComponent(
|
|
5072
|
+
const path = `${prefix}/named-queries/${encodeURIComponent(name)}/query?format=columnar`;
|
|
4853
5073
|
const body = {
|
|
4854
5074
|
args: args ?? {}
|
|
4855
5075
|
};
|
|
4856
5076
|
if (options?.orderByIndex !== void 0) {
|
|
4857
5077
|
body.orderByIndex = options.orderByIndex;
|
|
4858
5078
|
}
|
|
5079
|
+
if (options?.atLeast !== void 0) {
|
|
5080
|
+
this.store?.observe(this.database, options.atLeast);
|
|
5081
|
+
}
|
|
4859
5082
|
const response = await this.transport.post(
|
|
4860
5083
|
path,
|
|
4861
5084
|
body,
|
|
@@ -4867,7 +5090,8 @@ var NamedQueriesApi = class {
|
|
|
4867
5090
|
rows,
|
|
4868
5091
|
stats: response.stats,
|
|
4869
5092
|
warnings: response.warnings,
|
|
4870
|
-
totalMatches: response.totalMatches
|
|
5093
|
+
totalMatches: response.totalMatches,
|
|
5094
|
+
token: response.token
|
|
4871
5095
|
};
|
|
4872
5096
|
}
|
|
4873
5097
|
async batch(items, options) {
|
|
@@ -4885,6 +5109,9 @@ var NamedQueriesApi = class {
|
|
|
4885
5109
|
400
|
|
4886
5110
|
);
|
|
4887
5111
|
}
|
|
5112
|
+
if (options?.atLeast !== void 0) {
|
|
5113
|
+
this.store?.observe(this.database, options.atLeast);
|
|
5114
|
+
}
|
|
4888
5115
|
const prefix = databasePath2(this.database);
|
|
4889
5116
|
const path = `${prefix}/named-queries/batch?format=columnar`;
|
|
4890
5117
|
const envelope = await this.transport.post(
|
|
@@ -4907,34 +5134,41 @@ var NamedQueriesApi = class {
|
|
|
4907
5134
|
rowCount: slot.rowCount ?? 0,
|
|
4908
5135
|
stats: slot.stats ?? emptyStats(),
|
|
4909
5136
|
warnings: slot.warnings,
|
|
4910
|
-
totalMatches: slot.totalMatches
|
|
5137
|
+
totalMatches: slot.totalMatches,
|
|
5138
|
+
token: slot.token
|
|
4911
5139
|
};
|
|
4912
5140
|
const result = {
|
|
4913
5141
|
rows: columnarToRows(columnar),
|
|
4914
5142
|
stats: columnar.stats,
|
|
4915
5143
|
warnings: slot.warnings,
|
|
4916
|
-
totalMatches: slot.totalMatches
|
|
5144
|
+
totalMatches: slot.totalMatches,
|
|
5145
|
+
token: slot.token
|
|
4917
5146
|
};
|
|
4918
5147
|
raiseDeprecationWarnings(this.onWarning, slot.warnings);
|
|
4919
5148
|
return { isError: false, result };
|
|
4920
5149
|
});
|
|
4921
5150
|
}
|
|
4922
|
-
subscribe(
|
|
4923
|
-
if (typeof
|
|
4924
|
-
throw new Error("Named query
|
|
5151
|
+
subscribe(name, args, options = {}) {
|
|
5152
|
+
if (typeof name !== "string" || name.trim().length === 0) {
|
|
5153
|
+
throw new Error("Named query name must be a non-empty string");
|
|
4925
5154
|
}
|
|
4926
5155
|
const subscription = new TableSubscription(
|
|
4927
5156
|
this.getStreamingTransport(),
|
|
4928
|
-
{ kind: "named",
|
|
5157
|
+
{ kind: "named", name, args, orderByIndex: options.orderByIndex },
|
|
4929
5158
|
{
|
|
4930
5159
|
onSnapshot: options.onSnapshot,
|
|
4931
5160
|
onChange: options.onChange,
|
|
4932
5161
|
onError: options.onError,
|
|
4933
|
-
conflate: options.conflate
|
|
5162
|
+
conflate: options.conflate,
|
|
5163
|
+
atLeast: options.atLeast,
|
|
5164
|
+
waitMs: options.waitMs,
|
|
5165
|
+
onExceeded: options.onExceeded
|
|
4934
5166
|
},
|
|
4935
5167
|
(warnings) => {
|
|
4936
5168
|
raiseDeprecationWarnings(this.onWarning, warnings);
|
|
4937
|
-
}
|
|
5169
|
+
},
|
|
5170
|
+
this.store,
|
|
5171
|
+
this.database
|
|
4938
5172
|
);
|
|
4939
5173
|
subscription.start();
|
|
4940
5174
|
return subscription;
|
|
@@ -4946,12 +5180,12 @@ var NamedMutationsApi = class {
|
|
|
4946
5180
|
this.database = database;
|
|
4947
5181
|
this.onWarning = onWarning;
|
|
4948
5182
|
}
|
|
4949
|
-
async execute(
|
|
4950
|
-
if (typeof
|
|
4951
|
-
throw new Error("Named mutation
|
|
5183
|
+
async execute(name, args) {
|
|
5184
|
+
if (typeof name !== "string" || name.trim().length === 0) {
|
|
5185
|
+
throw new Error("Named mutation name must be a non-empty string");
|
|
4952
5186
|
}
|
|
4953
5187
|
const prefix = databasePath2(this.database);
|
|
4954
|
-
const path = `${prefix}/named-mutations/${encodeURIComponent(
|
|
5188
|
+
const path = `${prefix}/named-mutations/${encodeURIComponent(name)}/execute`;
|
|
4955
5189
|
const wire = await this.transport.post(path, {
|
|
4956
5190
|
args: args ?? {}
|
|
4957
5191
|
});
|
|
@@ -5012,6 +5246,7 @@ var WebSocketTransport = class {
|
|
|
5012
5246
|
// Serialized-send queue: each send appends to this tail.
|
|
5013
5247
|
this._sendTail = Promise.resolve();
|
|
5014
5248
|
this._lastVersion = 0;
|
|
5249
|
+
this._lastToken = null;
|
|
5015
5250
|
this._reconnectAttempt = 0;
|
|
5016
5251
|
this._disposed = false;
|
|
5017
5252
|
this._missedPings = 0;
|
|
@@ -5029,6 +5264,7 @@ var WebSocketTransport = class {
|
|
|
5029
5264
|
this._pingIntervalMs = options.pingIntervalMs ?? DEFAULT_PING_INTERVAL_MS;
|
|
5030
5265
|
this._maxMissedHeartbeats = options.maxMissedHeartbeats ?? DEFAULT_MAX_MISSED_HEARTBEATS;
|
|
5031
5266
|
this._enableCompression = options.enableCompression ?? true;
|
|
5267
|
+
this._store = options.consistencyTokenStore;
|
|
5032
5268
|
this._wireMode = options.wireMode ?? "json";
|
|
5033
5269
|
this._authHandler?.setOnAccessTokenRefreshed((token) => {
|
|
5034
5270
|
if (this._handshakeComplete && this._ws?.readyState === WS_READY_STATE_OPEN) {
|
|
@@ -5037,10 +5273,14 @@ var WebSocketTransport = class {
|
|
|
5037
5273
|
});
|
|
5038
5274
|
}
|
|
5039
5275
|
// ─── Public API ────────────────────────────────────────────────────────────
|
|
5040
|
-
/** Latest
|
|
5276
|
+
/** Latest change-event sequence from the most recent server `heartbeat` message. */
|
|
5041
5277
|
get lastVersion() {
|
|
5042
5278
|
return this._lastVersion;
|
|
5043
5279
|
}
|
|
5280
|
+
/** Consistency token from the most recent server `heartbeat` (ADR 0042 D-13). */
|
|
5281
|
+
get lastToken() {
|
|
5282
|
+
return this._lastToken;
|
|
5283
|
+
}
|
|
5044
5284
|
/**
|
|
5045
5285
|
* Registers a handler for incoming server messages with the given channel id.
|
|
5046
5286
|
* Use `"__global__"` to receive broadcast messages that carry no `id`.
|
|
@@ -5228,6 +5468,10 @@ var WebSocketTransport = class {
|
|
|
5228
5468
|
}
|
|
5229
5469
|
case "heartbeat":
|
|
5230
5470
|
this._lastVersion = msg.version;
|
|
5471
|
+
this._lastToken = msg.token ?? null;
|
|
5472
|
+
if (this._lastToken != null && this._lastToken.length > 0) {
|
|
5473
|
+
this._store?.observe(this._database, this._lastToken);
|
|
5474
|
+
}
|
|
5231
5475
|
break;
|
|
5232
5476
|
case "pong":
|
|
5233
5477
|
this._missedPings = 0;
|
|
@@ -5393,16 +5637,21 @@ var LongPollTransport = class {
|
|
|
5393
5637
|
this._connected = false;
|
|
5394
5638
|
this._pollTask = null;
|
|
5395
5639
|
this._lastVersion = 0;
|
|
5640
|
+
this._lastToken = null;
|
|
5396
5641
|
this._serverUrl = serverUrl;
|
|
5397
5642
|
this._database = database;
|
|
5398
5643
|
this._authHandler = options.authHandler;
|
|
5399
5644
|
this._onReconnected = options.onReconnected;
|
|
5400
5645
|
this._waitMs = Math.max(1, options.waitMs ?? DEFAULT_WAIT_MS);
|
|
5401
5646
|
this._fetch = options.fetchImpl ?? localNetworkFetch;
|
|
5647
|
+
this._store = options.consistencyTokenStore;
|
|
5402
5648
|
}
|
|
5403
5649
|
get lastVersion() {
|
|
5404
5650
|
return this._lastVersion;
|
|
5405
5651
|
}
|
|
5652
|
+
get lastToken() {
|
|
5653
|
+
return this._lastToken;
|
|
5654
|
+
}
|
|
5406
5655
|
registerHandler(id, handler) {
|
|
5407
5656
|
this._handlers.set(id, handler);
|
|
5408
5657
|
}
|
|
@@ -5525,6 +5774,10 @@ var LongPollTransport = class {
|
|
|
5525
5774
|
for (const msg of payload.messages) {
|
|
5526
5775
|
if (msg.type === "heartbeat") {
|
|
5527
5776
|
this._lastVersion = msg.version;
|
|
5777
|
+
this._lastToken = msg.token ?? null;
|
|
5778
|
+
if (this._lastToken != null && this._lastToken.length > 0) {
|
|
5779
|
+
this._store?.observe(this._database, this._lastToken);
|
|
5780
|
+
}
|
|
5528
5781
|
}
|
|
5529
5782
|
const id = "id" in msg ? msg.id : void 0;
|
|
5530
5783
|
if (id !== void 0 && id !== null) {
|
|
@@ -5604,6 +5857,9 @@ var FallbackStreamingTransport = class {
|
|
|
5604
5857
|
get lastVersion() {
|
|
5605
5858
|
return this._active.lastVersion;
|
|
5606
5859
|
}
|
|
5860
|
+
get lastToken() {
|
|
5861
|
+
return this._active.lastToken;
|
|
5862
|
+
}
|
|
5607
5863
|
registerHandler(id, handler) {
|
|
5608
5864
|
this._handlers.set(id, handler);
|
|
5609
5865
|
this._active.registerHandler(id, handler);
|
|
@@ -5683,6 +5939,7 @@ var AoudaClient = class {
|
|
|
5683
5939
|
this.baseUrl = normalizeBaseUrl(options.serverUrl);
|
|
5684
5940
|
this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
5685
5941
|
this.database = options.database.trim();
|
|
5942
|
+
this._store = options.consistencyTokenStore ?? new MemoryConsistencyTokenStore();
|
|
5686
5943
|
if (!Number.isFinite(this.timeout) || this.timeout <= 0) {
|
|
5687
5944
|
throw new Error("timeout must be a finite positive number");
|
|
5688
5945
|
}
|
|
@@ -5717,7 +5974,9 @@ var AoudaClient = class {
|
|
|
5717
5974
|
}
|
|
5718
5975
|
const httpTransport = new HttpTransport({
|
|
5719
5976
|
baseUrl: this.baseUrl,
|
|
5720
|
-
timeout: this.timeout
|
|
5977
|
+
timeout: this.timeout,
|
|
5978
|
+
database: this.database,
|
|
5979
|
+
consistencyTokenStore: this._store
|
|
5721
5980
|
});
|
|
5722
5981
|
const activeAuth = options.serverAuth ?? options.appAuth;
|
|
5723
5982
|
if (activeAuth) {
|
|
@@ -5777,7 +6036,8 @@ var AoudaClient = class {
|
|
|
5777
6036
|
this.transport,
|
|
5778
6037
|
this.database,
|
|
5779
6038
|
onNamedArtifactWarning,
|
|
5780
|
-
() => this._getOrCreateWebSocketTransport()
|
|
6039
|
+
() => this._getOrCreateWebSocketTransport(),
|
|
6040
|
+
this._store
|
|
5781
6041
|
);
|
|
5782
6042
|
this._namedMutations = new NamedMutationsApi(
|
|
5783
6043
|
this.transport,
|
|
@@ -5876,7 +6136,8 @@ var AoudaClient = class {
|
|
|
5876
6136
|
name,
|
|
5877
6137
|
this.database,
|
|
5878
6138
|
void 0,
|
|
5879
|
-
() => this._getOrCreateWebSocketTransport()
|
|
6139
|
+
() => this._getOrCreateWebSocketTransport(),
|
|
6140
|
+
this._store
|
|
5880
6141
|
);
|
|
5881
6142
|
}
|
|
5882
6143
|
/**
|
|
@@ -5928,13 +6189,26 @@ var AoudaClient = class {
|
|
|
5928
6189
|
return this._materializedQueries;
|
|
5929
6190
|
}
|
|
5930
6191
|
/**
|
|
5931
|
-
*
|
|
6192
|
+
* Named-query execute, read-only batch, and subscribe by unique schema name.
|
|
5932
6193
|
*/
|
|
5933
6194
|
get namedQueries() {
|
|
5934
6195
|
return this._namedQueries;
|
|
5935
6196
|
}
|
|
6197
|
+
observeConsistencyToken(token) {
|
|
6198
|
+
this._store.observe(this.database, token);
|
|
6199
|
+
}
|
|
6200
|
+
getObservedConsistencyToken() {
|
|
6201
|
+
return this._store.get(this.database);
|
|
6202
|
+
}
|
|
6203
|
+
async getConsistencyToken() {
|
|
6204
|
+
const body = await this.transport.get(
|
|
6205
|
+
`/api/databases/${encodeURIComponent(this.database)}/token`
|
|
6206
|
+
);
|
|
6207
|
+
this._store.observe(this.database, body.token);
|
|
6208
|
+
return this._store.get(this.database) ?? body.token;
|
|
6209
|
+
}
|
|
5936
6210
|
/**
|
|
5937
|
-
*
|
|
6211
|
+
* Named-mutation execute by unique schema name. No batch.
|
|
5938
6212
|
*/
|
|
5939
6213
|
get namedMutations() {
|
|
5940
6214
|
return this._namedMutations;
|
|
@@ -6061,13 +6335,15 @@ var AoudaClient = class {
|
|
|
6061
6335
|
const primary = new WebSocketTransport(this.baseUrl, this.database, {
|
|
6062
6336
|
authHandler: this._authHandler,
|
|
6063
6337
|
enableCompression: this._streamingEnableCompression,
|
|
6064
|
-
wireMode: this._streamingWireMode
|
|
6338
|
+
wireMode: this._streamingWireMode,
|
|
6339
|
+
consistencyTokenStore: this._store
|
|
6065
6340
|
});
|
|
6066
6341
|
if (this._streamingEnableLongPollFallback) {
|
|
6067
6342
|
this._wsTransport = new FallbackStreamingTransport(primary, () => {
|
|
6068
6343
|
return new LongPollTransport(this.baseUrl, this.database, {
|
|
6069
6344
|
authHandler: this._authHandler,
|
|
6070
|
-
waitMs: this._streamingLongPollWaitMs
|
|
6345
|
+
waitMs: this._streamingLongPollWaitMs,
|
|
6346
|
+
consistencyTokenStore: this._store
|
|
6071
6347
|
});
|
|
6072
6348
|
});
|
|
6073
6349
|
} else {
|
|
@@ -6365,6 +6641,7 @@ var version = package_default.version;
|
|
|
6365
6641
|
MaterializedQueriesApi,
|
|
6366
6642
|
MaterializedQueryState,
|
|
6367
6643
|
MaterializedQueryType,
|
|
6644
|
+
MemoryConsistencyTokenStore,
|
|
6368
6645
|
MetricsAdminApi,
|
|
6369
6646
|
NamedMutationsApi,
|
|
6370
6647
|
NamedQueriesApi,
|
|
@@ -6380,10 +6657,12 @@ var version = package_default.version;
|
|
|
6380
6657
|
applyLocalNetworkAccess,
|
|
6381
6658
|
coerceColumnarValue,
|
|
6382
6659
|
columnarToRows,
|
|
6660
|
+
compareOrdinal,
|
|
6383
6661
|
createAoudaClient,
|
|
6384
6662
|
createAoudaClusterMcpToolSet,
|
|
6385
6663
|
installLocalNetworkFetch,
|
|
6386
6664
|
localNetworkFetch,
|
|
6665
|
+
maxToken,
|
|
6387
6666
|
resolveTargetAddressSpace,
|
|
6388
6667
|
version
|
|
6389
6668
|
});
|