@ferricstore/ferricstore 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -3
- package/dist/index.cjs +2618 -554
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +247 -33
- package/dist/index.d.ts +247 -33
- package/dist/index.js +2621 -562
- package/dist/index.js.map +1 -1
- package/docs/api/assets/hierarchy.js +1 -1
- package/docs/api/assets/navigation.js +1 -1
- package/docs/api/assets/search.js +1 -1
- package/docs/api/classes/ClaimHydrationError.html +5 -5
- package/docs/api/classes/ConnectionClosedError.html +5 -5
- package/docs/api/classes/FerricStoreClient.html +7 -3
- package/docs/api/classes/FerricStoreError.html +5 -5
- package/docs/api/classes/FlowAlreadyExistsError.html +5 -5
- package/docs/api/classes/FlowBatchError.html +5 -5
- package/docs/api/classes/FlowNotFoundError.html +5 -5
- package/docs/api/classes/FlowQueryError.html +42 -0
- package/docs/api/classes/FlowWrongStateError.html +5 -5
- package/docs/api/classes/InvalidCommandError.html +5 -5
- package/docs/api/classes/LeaseRenewalError.html +5 -5
- package/docs/api/classes/LockHeldError.html +5 -5
- package/docs/api/classes/LockNotOwnedError.html +5 -5
- package/docs/api/classes/NativeAdapter.html +3 -3
- package/docs/api/classes/OverloadedError.html +5 -5
- package/docs/api/classes/QueueCompletionError.html +5 -5
- package/docs/api/classes/ReconnectingExecutor.html +4 -4
- package/docs/api/classes/RequestTimeoutError.html +5 -5
- package/docs/api/classes/RerouteError.html +5 -5
- package/docs/api/classes/StaleLeaseError.html +5 -5
- package/docs/api/classes/StalePolicyGenerationError.html +39 -0
- package/docs/api/classes/TopologyNativeAdapterPool.html +3 -3
- package/docs/api/classes/Workflow.html +1 -1
- package/docs/api/classes/WorkflowWorker.html +2 -2
- package/docs/api/functions/classifyServerError.html +1 -1
- package/docs/api/functions/isReconnectableClosedConnectionError.html +1 -1
- package/docs/api/functions/mapException.html +1 -1
- package/docs/api/functions/projectFlowQuery.html +1 -0
- package/docs/api/hierarchy.html +1 -1
- package/docs/api/index.html +36 -5
- package/docs/api/interfaces/AdminListOptions.html +1 -1
- package/docs/api/interfaces/CancelOptions.html +2 -2
- package/docs/api/interfaces/CompleteOptions.html +2 -2
- package/docs/api/interfaces/CompleteOutcome.html +1 -1
- package/docs/api/interfaces/CreateManyOptions.html +1 -1
- package/docs/api/interfaces/EffectCompensateOptions.html +1 -1
- package/docs/api/interfaces/EffectConfirmOptions.html +1 -1
- package/docs/api/interfaces/EffectFailOptions.html +1 -1
- package/docs/api/interfaces/EffectStatusOptions.html +1 -1
- package/docs/api/interfaces/ExtendLeaseOptions.html +2 -2
- package/docs/api/interfaces/FailOptions.html +2 -2
- package/docs/api/interfaces/FailOutcome.html +1 -1
- package/docs/api/interfaces/FerricStoreClientFromUrlOptions.html +1 -1
- package/docs/api/interfaces/FerricStoreClientOptions.html +1 -1
- package/docs/api/interfaces/FlowEventProjectionField.html +4 -0
- package/docs/api/interfaces/FlowExplainResult.html +10 -0
- package/docs/api/interfaces/FlowPolicyBackoffSnapshot.html +5 -0
- package/docs/api/interfaces/FlowPolicyOptions.html +8 -4
- package/docs/api/interfaces/FlowPolicyRetentionSnapshot.html +3 -0
- package/docs/api/interfaces/FlowPolicyRetrySnapshot.html +4 -0
- package/docs/api/interfaces/FlowPolicySnapshot.html +17 -0
- package/docs/api/interfaces/FlowPolicyStateSnapshot.html +6 -0
- package/docs/api/interfaces/FlowQueryCountResult.html +7 -0
- package/docs/api/interfaces/FlowQueryErrorPosition.html +4 -0
- package/docs/api/interfaces/FlowQueryIndex.html +9 -0
- package/docs/api/interfaces/FlowQueryIndexFormat.html +7 -0
- package/docs/api/interfaces/FlowQueryIndexRegistry.html +3 -0
- package/docs/api/interfaces/FlowQueryIndexStatus.html +8 -0
- package/docs/api/interfaces/FlowQueryPage.html +3 -0
- package/docs/api/interfaces/FlowQueryQuality.html +5 -0
- package/docs/api/interfaces/FlowQueryRecordsResult.html +8 -0
- package/docs/api/interfaces/FlowQueryUsage.html +12 -0
- package/docs/api/interfaces/FlowRunProjectionField.html +4 -0
- package/docs/api/interfaces/HistoryOptions.html +2 -2
- package/docs/api/interfaces/InvocationCreateOptions.html +2 -2
- package/docs/api/interfaces/LeaseMutationOptions.html +2 -2
- package/docs/api/interfaces/LimitListOptions.html +1 -1
- package/docs/api/interfaces/MutateOptions.html +2 -2
- package/docs/api/interfaces/NamedValueMutation.html +1 -1
- package/docs/api/interfaces/ProtocolCommand.html +2 -2
- package/docs/api/interfaces/ReadOptions.html +5 -3
- package/docs/api/interfaces/ReclaimOptions.html +1 -1
- package/docs/api/interfaces/RequestContext.html +2 -2
- package/docs/api/interfaces/RequestContextOptions.html +2 -2
- package/docs/api/interfaces/RetryOptions.html +2 -2
- package/docs/api/interfaces/RetryOutcome.html +1 -1
- package/docs/api/interfaces/RunStepsItem.html +2 -2
- package/docs/api/interfaces/RunStepsManyOptions.html +2 -2
- package/docs/api/interfaces/SearchOptions.html +4 -3
- package/docs/api/interfaces/StepContinueOptions.html +3 -3
- package/docs/api/interfaces/TDigestCreateOptions.html +1 -1
- package/docs/api/interfaces/TDigestMergeOptions.html +1 -1
- package/docs/api/interfaces/TransitionOptions.html +2 -2
- package/docs/api/interfaces/TransitionOutcome.html +1 -1
- package/docs/api/modules.html +1 -1
- package/docs/api/types/ConnectionRequestDisposition.html +1 -1
- package/docs/api/types/FlowPolicyBackoffKind.html +1 -0
- package/docs/api/types/FlowProjectionField.html +1 -0
- package/docs/api/types/FlowProjectionShape.html +1 -0
- package/docs/api/types/FlowQueryInteger.html +1 -0
- package/docs/api/types/FlowQueryParameter.html +1 -0
- package/docs/api/types/FlowQueryParameters.html +1 -0
- package/docs/api/types/FlowQueryRecord.html +1 -0
- package/docs/api/types/FlowQueryResult.html +1 -0
- package/docs/api/types/ManagementPairs.html +1 -1
- package/docs/api/types/SearchStateMeta.html +1 -1
- package/docs/api/variables/COMMAND_OPCODES.html +1 -1
- package/docs/api/variables/FERRICSTORE_MINIMUM_SERVER_VERSION.html +1 -1
- package/docs/api/variables/FERRICSTORE_NATIVE_PROTOCOL_VERSION.html +1 -1
- package/docs/api/variables/FERRICSTORE_SDK_VERSION.html +1 -1
- package/docs/api/variables/FlowProjection.html +1 -0
- package/docs/api/variables/MAX_FLOW_POLICY_GENERATION.html +1 -0
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,8 @@ __export(index_exports, {
|
|
|
45
45
|
FlowAlreadyExistsError: () => FlowAlreadyExistsError,
|
|
46
46
|
FlowBatchError: () => FlowBatchError,
|
|
47
47
|
FlowNotFoundError: () => FlowNotFoundError,
|
|
48
|
+
FlowProjection: () => FlowProjection,
|
|
49
|
+
FlowQueryError: () => FlowQueryError,
|
|
48
50
|
FlowWrongStateError: () => FlowWrongStateError,
|
|
49
51
|
GeoStore: () => GeoStore,
|
|
50
52
|
HashStore: () => HashStore,
|
|
@@ -56,6 +58,7 @@ __export(index_exports, {
|
|
|
56
58
|
ListStore: () => ListStore,
|
|
57
59
|
LockHeldError: () => LockHeldError,
|
|
58
60
|
LockNotOwnedError: () => LockNotOwnedError,
|
|
61
|
+
MAX_FLOW_POLICY_GENERATION: () => MAX_FLOW_POLICY_GENERATION,
|
|
59
62
|
NativeAdapter: () => NativeAdapter,
|
|
60
63
|
OverloadedError: () => OverloadedError,
|
|
61
64
|
Queue: () => Queue,
|
|
@@ -70,6 +73,7 @@ __export(index_exports, {
|
|
|
70
73
|
SetStore: () => SetStore,
|
|
71
74
|
SortedSetStore: () => SortedSetStore,
|
|
72
75
|
StaleLeaseError: () => StaleLeaseError,
|
|
76
|
+
StalePolicyGenerationError: () => StalePolicyGenerationError,
|
|
73
77
|
StreamStore: () => StreamStore,
|
|
74
78
|
TDigestStore: () => TDigestStore,
|
|
75
79
|
TopKStore: () => TopKStore,
|
|
@@ -85,6 +89,7 @@ __export(index_exports, {
|
|
|
85
89
|
isOutcome: () => isOutcome,
|
|
86
90
|
isReconnectableClosedConnectionError: () => isReconnectableClosedConnectionError,
|
|
87
91
|
mapException: () => mapException,
|
|
92
|
+
projectFlowQuery: () => projectFlowQuery,
|
|
88
93
|
retry: () => retry,
|
|
89
94
|
transition: () => transition
|
|
90
95
|
});
|
|
@@ -102,7 +107,7 @@ function assertSafeVariadicDispatch(argumentCount, arrayCapability) {
|
|
|
102
107
|
// src/native-adapter.ts
|
|
103
108
|
var import_node_net3 = require("net");
|
|
104
109
|
var import_node_tls3 = require("tls");
|
|
105
|
-
var
|
|
110
|
+
var import_node_buffer31 = require("buffer");
|
|
106
111
|
|
|
107
112
|
// src/errors.ts
|
|
108
113
|
var FerricStoreError = class extends Error {
|
|
@@ -150,6 +155,9 @@ var FlowWrongStateError = class extends FerricStoreError {
|
|
|
150
155
|
var StaleLeaseError = class extends FerricStoreError {
|
|
151
156
|
code = "stale_lease";
|
|
152
157
|
};
|
|
158
|
+
var StalePolicyGenerationError = class extends FerricStoreError {
|
|
159
|
+
code = "stale_policy_generation";
|
|
160
|
+
};
|
|
153
161
|
var FlowAlreadyExistsError = class extends FerricStoreError {
|
|
154
162
|
code = "flow_already_exists";
|
|
155
163
|
};
|
|
@@ -215,6 +223,9 @@ function classifyServerError(message, raw, cause, status) {
|
|
|
215
223
|
if (code === "stale_lease" || code === "stale_flow_lease" || lower.includes("stale flow lease") || lower.includes("stale lease") || lower.includes("stale token")) {
|
|
216
224
|
return new StaleLeaseError(message, { cause, raw });
|
|
217
225
|
}
|
|
226
|
+
if (code === "stale_generation" || code === "stale_policy_generation" || code === "stale_flow_policy_generation" || lower.includes("stale flow policy generation") || lower.includes("stale policy generation")) {
|
|
227
|
+
return new StalePolicyGenerationError(message, { cause, raw });
|
|
228
|
+
}
|
|
218
229
|
if (code === "flow_not_found" || lower.includes("flow") && (lower.includes("not found") || lower.includes("does not exist"))) {
|
|
219
230
|
return new FlowNotFoundError(message, { cause, raw });
|
|
220
231
|
}
|
|
@@ -1268,10 +1279,151 @@ var NativeHeartbeat = class {
|
|
|
1268
1279
|
};
|
|
1269
1280
|
|
|
1270
1281
|
// src/protocol.ts
|
|
1271
|
-
var
|
|
1282
|
+
var import_node_buffer27 = require("buffer");
|
|
1272
1283
|
|
|
1273
|
-
// src/
|
|
1284
|
+
// src/flow-query-request.ts
|
|
1274
1285
|
var import_node_buffer3 = require("buffer");
|
|
1286
|
+
var FLOW_QUERY_LANGUAGE_VERSION = "FQL1";
|
|
1287
|
+
var FLOW_QUERY_MAX_BYTES = 16 * 1024;
|
|
1288
|
+
var FLOW_QUERY_MAX_PARAMETERS = 64;
|
|
1289
|
+
var FLOW_QUERY_MAX_PARAMETER_NAME_BYTES = 128;
|
|
1290
|
+
var MIN_I64 = -(1n << 63n);
|
|
1291
|
+
var MAX_I64 = (1n << 63n) - 1n;
|
|
1292
|
+
var INDEX_ID = /^[A-Za-z0-9_.:-]{1,64}$/u;
|
|
1293
|
+
function flowQueryArgs(query, params = {}) {
|
|
1294
|
+
validateFlowQueryText(query);
|
|
1295
|
+
const entries = flowQueryParameterEntries(params);
|
|
1296
|
+
const args = ["FLOW.QUERY", FLOW_QUERY_LANGUAGE_VERSION, query];
|
|
1297
|
+
for (const [name, value] of entries) args.push(name, value);
|
|
1298
|
+
return args;
|
|
1299
|
+
}
|
|
1300
|
+
function flowQueryPayload(args) {
|
|
1301
|
+
if (args.length < 2) throw new TypeError("FLOW.QUERY requires version and query");
|
|
1302
|
+
if ((args.length - 2) % 2 !== 0) {
|
|
1303
|
+
throw new TypeError("FLOW.QUERY parameters must be name/value pairs");
|
|
1304
|
+
}
|
|
1305
|
+
const version = commandText(args[0], "FLOW.QUERY version");
|
|
1306
|
+
if (version !== FLOW_QUERY_LANGUAGE_VERSION) {
|
|
1307
|
+
throw new TypeError(`FLOW.QUERY requires version ${FLOW_QUERY_LANGUAGE_VERSION}`);
|
|
1308
|
+
}
|
|
1309
|
+
const query = commandText(args[1], "FLOW.QUERY query");
|
|
1310
|
+
validateFlowQueryText(query);
|
|
1311
|
+
const parameterCount = (args.length - 2) / 2;
|
|
1312
|
+
if (parameterCount > FLOW_QUERY_MAX_PARAMETERS) {
|
|
1313
|
+
throw new TypeError(`FLOW.QUERY accepts at most ${FLOW_QUERY_MAX_PARAMETERS} named parameters`);
|
|
1314
|
+
}
|
|
1315
|
+
const params = /* @__PURE__ */ Object.create(null);
|
|
1316
|
+
for (let index = 2; index < args.length; index += 2) {
|
|
1317
|
+
const name = commandText(args[index], "FLOW.QUERY parameter name");
|
|
1318
|
+
validateFlowQueryParameterName(name);
|
|
1319
|
+
if (Object.hasOwn(params, name)) {
|
|
1320
|
+
throw new TypeError(`FLOW.QUERY parameter ${JSON.stringify(name)} is duplicated`);
|
|
1321
|
+
}
|
|
1322
|
+
params[name] = normalizeFlowQueryParameter(args[index + 1], name);
|
|
1323
|
+
}
|
|
1324
|
+
return {
|
|
1325
|
+
version,
|
|
1326
|
+
query,
|
|
1327
|
+
...parameterCount === 0 ? {} : { params }
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
function validateFlowQueryText(query) {
|
|
1331
|
+
if (typeof query !== "string") throw new TypeError("FLOW.QUERY query must be text");
|
|
1332
|
+
if (query.trim().length === 0) throw new TypeError("FLOW.QUERY query must not be empty");
|
|
1333
|
+
validateUnicodeScalarText(query, "FLOW.QUERY query");
|
|
1334
|
+
if (import_node_buffer3.Buffer.byteLength(query, "utf8") > FLOW_QUERY_MAX_BYTES) {
|
|
1335
|
+
throw new TypeError(`FLOW.QUERY query exceeds ${FLOW_QUERY_MAX_BYTES} bytes`);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
function validateFlowQueryIndexId(indexId) {
|
|
1339
|
+
if (typeof indexId !== "string" || !INDEX_ID.test(indexId)) {
|
|
1340
|
+
throw new TypeError(
|
|
1341
|
+
"query index id must be 1..64 ASCII letters, digits, '_', '-', ':', or '.'"
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
function hasFlowExplainPrefix(query) {
|
|
1346
|
+
const source = query.trimStart();
|
|
1347
|
+
const prefix = source.slice(0, 7);
|
|
1348
|
+
return prefix.toUpperCase() === "EXPLAIN" && (source.length === 7 || /[\t\n\r ]/u.test(source[7] ?? ""));
|
|
1349
|
+
}
|
|
1350
|
+
function flowQueryParameterEntries(params) {
|
|
1351
|
+
if (typeof params !== "object" || params == null || Array.isArray(params)) {
|
|
1352
|
+
throw new TypeError("FLOW.QUERY params must be a plain object");
|
|
1353
|
+
}
|
|
1354
|
+
const prototype = Object.getPrototypeOf(params);
|
|
1355
|
+
if (prototype !== null && prototype !== Object.prototype) {
|
|
1356
|
+
throw new TypeError("FLOW.QUERY params must be a plain object");
|
|
1357
|
+
}
|
|
1358
|
+
const keys = Reflect.ownKeys(params);
|
|
1359
|
+
if (keys.some((key) => typeof key !== "string")) {
|
|
1360
|
+
throw new TypeError("FLOW.QUERY parameter names must be strings");
|
|
1361
|
+
}
|
|
1362
|
+
if (keys.length > FLOW_QUERY_MAX_PARAMETERS) {
|
|
1363
|
+
throw new TypeError(`FLOW.QUERY accepts at most ${FLOW_QUERY_MAX_PARAMETERS} named parameters`);
|
|
1364
|
+
}
|
|
1365
|
+
const names = keys.sort();
|
|
1366
|
+
return names.map((name) => {
|
|
1367
|
+
validateFlowQueryParameterName(name);
|
|
1368
|
+
return [name, normalizeFlowQueryParameter(params[name], name)];
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
function validateFlowQueryParameterName(name) {
|
|
1372
|
+
validateUnicodeScalarText(name, "FLOW.QUERY parameter name");
|
|
1373
|
+
const size = import_node_buffer3.Buffer.byteLength(name, "utf8");
|
|
1374
|
+
if (size === 0 || size > FLOW_QUERY_MAX_PARAMETER_NAME_BYTES) {
|
|
1375
|
+
throw new TypeError(
|
|
1376
|
+
`FLOW.QUERY parameter names must be 1..${FLOW_QUERY_MAX_PARAMETER_NAME_BYTES} bytes`
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
function normalizeFlowQueryParameter(value, name) {
|
|
1381
|
+
if (typeof value === "string") {
|
|
1382
|
+
validateUnicodeScalarText(value, `FLOW.QUERY parameter ${JSON.stringify(name)}`);
|
|
1383
|
+
return value;
|
|
1384
|
+
}
|
|
1385
|
+
if (import_node_buffer3.Buffer.isBuffer(value)) return value;
|
|
1386
|
+
if (value instanceof Uint8Array) return import_node_buffer3.Buffer.from(value);
|
|
1387
|
+
if (typeof value === "boolean") return value;
|
|
1388
|
+
if (typeof value === "bigint" && value >= MIN_I64 && value <= MAX_I64) return value;
|
|
1389
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1390
|
+
if (!Number.isInteger(value) || Number.isSafeInteger(value)) return value;
|
|
1391
|
+
}
|
|
1392
|
+
throw new TypeError(
|
|
1393
|
+
`FLOW.QUERY parameter ${JSON.stringify(name)} must be text, bytes, boolean, a finite float, or a signed 64-bit integer`
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
function commandText(value, context) {
|
|
1397
|
+
if (typeof value === "string") {
|
|
1398
|
+
validateUnicodeScalarText(value, context);
|
|
1399
|
+
return value;
|
|
1400
|
+
}
|
|
1401
|
+
if (import_node_buffer3.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
1402
|
+
try {
|
|
1403
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
1404
|
+
} catch (error) {
|
|
1405
|
+
throw new TypeError(`${context} must be valid UTF-8`, { cause: error });
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
throw new TypeError(`${context} must be text`);
|
|
1409
|
+
}
|
|
1410
|
+
function validateUnicodeScalarText(value, context) {
|
|
1411
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1412
|
+
const code = value.charCodeAt(index);
|
|
1413
|
+
if (code >= 55296 && code <= 56319) {
|
|
1414
|
+
const low = value.charCodeAt(index + 1);
|
|
1415
|
+
if (!(low >= 56320 && low <= 57343)) {
|
|
1416
|
+
throw new TypeError(`${context} must be valid UTF-8`);
|
|
1417
|
+
}
|
|
1418
|
+
index += 1;
|
|
1419
|
+
} else if (code >= 56320 && code <= 57343) {
|
|
1420
|
+
throw new TypeError(`${context} must be valid UTF-8`);
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// src/command-grammar.ts
|
|
1426
|
+
var import_node_buffer4 = require("buffer");
|
|
1275
1427
|
|
|
1276
1428
|
// src/command-metadata-flow.ts
|
|
1277
1429
|
var flowStateIdCommands = /* @__PURE__ */ new Set([
|
|
@@ -1662,20 +1814,15 @@ var typeScopedFlowCommands = /* @__PURE__ */ new Set([
|
|
|
1662
1814
|
"FLOW.ATTRIBUTE_VALUES",
|
|
1663
1815
|
"FLOW.ATTRIBUTES",
|
|
1664
1816
|
"FLOW.BUDGET.LIST",
|
|
1665
|
-
"FLOW.FAILURES",
|
|
1666
1817
|
"FLOW.GOVERNANCE.OVERVIEW",
|
|
1667
1818
|
"FLOW.INFO",
|
|
1668
1819
|
"FLOW.LIMIT.LIST",
|
|
1669
|
-
"FLOW.LIST",
|
|
1670
1820
|
"FLOW.POLICY.GET",
|
|
1671
1821
|
"FLOW.POLICY.SET",
|
|
1672
1822
|
"FLOW.RETENTION_CLEANUP",
|
|
1673
1823
|
"FLOW.SCHEDULE.FIRE_DUE",
|
|
1674
1824
|
"FLOW.SCHEDULE.LIST",
|
|
1675
|
-
"FLOW.
|
|
1676
|
-
"FLOW.STATS",
|
|
1677
|
-
"FLOW.STUCK",
|
|
1678
|
-
"FLOW.TERMINALS"
|
|
1825
|
+
"FLOW.STATS"
|
|
1679
1826
|
]);
|
|
1680
1827
|
var flowScheduleCommands = /* @__PURE__ */ new Set([
|
|
1681
1828
|
"FLOW.SCHEDULE.CREATE",
|
|
@@ -1718,8 +1865,8 @@ var secondKeySubcommands = /* @__PURE__ */ new Map([
|
|
|
1718
1865
|
]);
|
|
1719
1866
|
function commandToken(value) {
|
|
1720
1867
|
if (typeof value === "string") return value.toUpperCase();
|
|
1721
|
-
if (
|
|
1722
|
-
return
|
|
1868
|
+
if (import_node_buffer4.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
1869
|
+
return import_node_buffer4.Buffer.from(value).toString("utf8").toUpperCase();
|
|
1723
1870
|
}
|
|
1724
1871
|
return void 0;
|
|
1725
1872
|
}
|
|
@@ -1822,7 +1969,7 @@ function safeIntegerArgument(value) {
|
|
|
1822
1969
|
if (typeof value === "bigint") {
|
|
1823
1970
|
return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : void 0;
|
|
1824
1971
|
}
|
|
1825
|
-
const source = typeof value === "string" ? value :
|
|
1972
|
+
const source = typeof value === "string" ? value : import_node_buffer4.Buffer.isBuffer(value) || value instanceof Uint8Array ? import_node_buffer4.Buffer.from(value).toString("utf8") : void 0;
|
|
1826
1973
|
if (source == null || !/^[+-]?\d+$/u.test(source)) return void 0;
|
|
1827
1974
|
const parsed = BigInt(source);
|
|
1828
1975
|
return parsed >= BigInt(Number.MIN_SAFE_INTEGER) && parsed <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(parsed) : void 0;
|
|
@@ -1875,10 +2022,10 @@ function hasOwnCommandArgument(args, index, end, section) {
|
|
|
1875
2022
|
}
|
|
1876
2023
|
|
|
1877
2024
|
// src/protocol-core.ts
|
|
1878
|
-
var
|
|
2025
|
+
var import_node_buffer8 = require("buffer");
|
|
1879
2026
|
|
|
1880
2027
|
// src/protocol-constants.ts
|
|
1881
|
-
var
|
|
2028
|
+
var import_node_buffer5 = require("buffer");
|
|
1882
2029
|
|
|
1883
2030
|
// src/native-protocol-manifest.json
|
|
1884
2031
|
var native_protocol_manifest_default = {
|
|
@@ -1973,7 +2120,6 @@ var COMMAND_OPCODES = {
|
|
|
1973
2120
|
"FLOW.VALUE.PUT": 523,
|
|
1974
2121
|
"FLOW.VALUE.MGET": 524,
|
|
1975
2122
|
"FLOW.SIGNAL": 525,
|
|
1976
|
-
"FLOW.LIST": 526,
|
|
1977
2123
|
"FLOW.CREATE_MANY": 527,
|
|
1978
2124
|
"FLOW.COMPLETE_MANY": 528,
|
|
1979
2125
|
"FLOW.TRANSITION_MANY": 529,
|
|
@@ -1982,13 +2128,7 @@ var COMMAND_OPCODES = {
|
|
|
1982
2128
|
"FLOW.CANCEL_MANY": 532,
|
|
1983
2129
|
"FLOW.RECLAIM": 533,
|
|
1984
2130
|
"FLOW.REWIND": 534,
|
|
1985
|
-
"FLOW.TERMINALS": 535,
|
|
1986
|
-
"FLOW.FAILURES": 536,
|
|
1987
|
-
"FLOW.BY_PARENT": 537,
|
|
1988
|
-
"FLOW.BY_ROOT": 538,
|
|
1989
|
-
"FLOW.BY_CORRELATION": 539,
|
|
1990
2131
|
"FLOW.INFO": 540,
|
|
1991
|
-
"FLOW.STUCK": 541,
|
|
1992
2132
|
"FLOW.POLICY.SET": 542,
|
|
1993
2133
|
"FLOW.POLICY.GET": 543,
|
|
1994
2134
|
"FLOW.SPAWN_CHILDREN": 544,
|
|
@@ -2007,7 +2147,7 @@ var COMMAND_OPCODES = {
|
|
|
2007
2147
|
"FLOW.STATS": 557,
|
|
2008
2148
|
"FLOW.ATTRIBUTES": 558,
|
|
2009
2149
|
"FLOW.ATTRIBUTE_VALUES": 559,
|
|
2010
|
-
"FLOW.
|
|
2150
|
+
"FLOW.QUERY": 561,
|
|
2011
2151
|
"FLOW.EFFECT.RESERVE": 576,
|
|
2012
2152
|
"FLOW.EFFECT.CONFIRM": 577,
|
|
2013
2153
|
"FLOW.EFFECT.FAIL": 578,
|
|
@@ -2090,11 +2230,13 @@ var OPCODES = {
|
|
|
2090
2230
|
flowRetryMany: COMMAND_OPCODES["FLOW.RETRY_MANY"],
|
|
2091
2231
|
flowFailMany: COMMAND_OPCODES["FLOW.FAIL_MANY"],
|
|
2092
2232
|
flowReclaim: COMMAND_OPCODES["FLOW.RECLAIM"],
|
|
2233
|
+
flowPolicySet: COMMAND_OPCODES["FLOW.POLICY.SET"],
|
|
2234
|
+
flowPolicyGet: COMMAND_OPCODES["FLOW.POLICY.GET"],
|
|
2093
2235
|
flowSpawnChildren: COMMAND_OPCODES["FLOW.SPAWN_CHILDREN"],
|
|
2094
2236
|
flowStepContinue: COMMAND_OPCODES["FLOW.STEP_CONTINUE"],
|
|
2095
2237
|
flowStartAndClaim: COMMAND_OPCODES["FLOW.START_AND_CLAIM"],
|
|
2096
2238
|
flowRunStepsMany: COMMAND_OPCODES["FLOW.RUN_STEPS_MANY"],
|
|
2097
|
-
|
|
2239
|
+
flowQuery: COMMAND_OPCODES["FLOW.QUERY"]
|
|
2098
2240
|
};
|
|
2099
2241
|
var COMPACT_FLOW_CLAIM_JOBS = 128;
|
|
2100
2242
|
var COMPACT_OK_LIST = 129;
|
|
@@ -2121,11 +2263,12 @@ var COMPACT_FLOW_TRANSITION_MANY_REQUEST = 155;
|
|
|
2121
2263
|
var COMPACT_FLOW_TRANSITION_MANY_OK_REQUEST = 156;
|
|
2122
2264
|
var COMPACT_FLOW_VALUE_MGET_REQUEST = 157;
|
|
2123
2265
|
var COMPACT_FLOW_CREATE_MANY_MIXED_REQUEST = 158;
|
|
2124
|
-
var
|
|
2266
|
+
var COMPACT_FLOW_QUERY_RESULT = 160;
|
|
2125
2267
|
var COMPACT_PIPELINE_DECODED = /* @__PURE__ */ Symbol("ferricstore.compactPipelineDecoded");
|
|
2126
2268
|
var NULL_U32 = 4294967295;
|
|
2127
|
-
var
|
|
2128
|
-
var
|
|
2269
|
+
var MIN_I642 = -9223372036854775808n;
|
|
2270
|
+
var MAX_I642 = 9223372036854775807n;
|
|
2271
|
+
var MAX_U64 = 18446744073709551615n;
|
|
2129
2272
|
var MAX_SAFE_INTEGER_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
2130
2273
|
var MIN_SAFE_INTEGER_BIGINT = BigInt(Number.MIN_SAFE_INTEGER);
|
|
2131
2274
|
var FLOW_RECORD_FIELD_KEYS = [
|
|
@@ -2174,16 +2317,16 @@ var FLOW_RECORD_FIELD_KEYS = [
|
|
|
2174
2317
|
];
|
|
2175
2318
|
|
|
2176
2319
|
// src/protocol-text.ts
|
|
2177
|
-
var
|
|
2320
|
+
var import_node_buffer6 = require("buffer");
|
|
2178
2321
|
function toBuffer(value) {
|
|
2179
|
-
if (
|
|
2180
|
-
if (value instanceof Uint8Array) return
|
|
2181
|
-
if (typeof value === "string") return
|
|
2322
|
+
if (import_node_buffer6.Buffer.isBuffer(value)) return value;
|
|
2323
|
+
if (value instanceof Uint8Array) return import_node_buffer6.Buffer.from(value);
|
|
2324
|
+
if (typeof value === "string") return import_node_buffer6.Buffer.from(value);
|
|
2182
2325
|
if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
|
|
2183
|
-
return
|
|
2326
|
+
return import_node_buffer6.Buffer.from(String(value));
|
|
2184
2327
|
}
|
|
2185
|
-
if (typeof value === "symbol") return
|
|
2186
|
-
if (value == null) return
|
|
2328
|
+
if (typeof value === "symbol") return import_node_buffer6.Buffer.from(value.description ?? value.toString());
|
|
2329
|
+
if (value == null) return import_node_buffer6.Buffer.alloc(0);
|
|
2187
2330
|
throw new FerricStoreError(`unsupported binary command argument type: ${typeof value}`);
|
|
2188
2331
|
}
|
|
2189
2332
|
function asText(value) {
|
|
@@ -2191,14 +2334,14 @@ function asText(value) {
|
|
|
2191
2334
|
}
|
|
2192
2335
|
function optionalText(value) {
|
|
2193
2336
|
if (value == null || value === "") return void 0;
|
|
2194
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean" ||
|
|
2337
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean" || import_node_buffer6.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
2195
2338
|
return asText(value);
|
|
2196
2339
|
}
|
|
2197
2340
|
return void 0;
|
|
2198
2341
|
}
|
|
2199
2342
|
function commandTokenIs(value, expected) {
|
|
2200
2343
|
if (typeof value === "string") return value.toUpperCase() === expected;
|
|
2201
|
-
if (
|
|
2344
|
+
if (import_node_buffer6.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
2202
2345
|
return asText(value).toUpperCase() === expected;
|
|
2203
2346
|
}
|
|
2204
2347
|
return false;
|
|
@@ -2212,7 +2355,7 @@ function commandNameIs(value, expected) {
|
|
|
2212
2355
|
}
|
|
2213
2356
|
|
|
2214
2357
|
// src/request-context.ts
|
|
2215
|
-
var
|
|
2358
|
+
var import_node_buffer7 = require("buffer");
|
|
2216
2359
|
var requestContextCommands = /* @__PURE__ */ new Set([
|
|
2217
2360
|
"INVOCATION.CREATE",
|
|
2218
2361
|
"INVOCATION.DEFINITION.GET",
|
|
@@ -2267,9 +2410,9 @@ function requestContextCommandToken(value) {
|
|
|
2267
2410
|
const upper = value.toUpperCase();
|
|
2268
2411
|
return isRequestContextCommand(upper) ? upper : void 0;
|
|
2269
2412
|
}
|
|
2270
|
-
if (
|
|
2413
|
+
if (import_node_buffer7.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
2271
2414
|
if (value[0] !== 73 && value[0] !== 105) return void 0;
|
|
2272
|
-
const command =
|
|
2415
|
+
const command = import_node_buffer7.Buffer.from(value).toString("utf8").toUpperCase();
|
|
2273
2416
|
return isRequestContextCommand(command) ? command : void 0;
|
|
2274
2417
|
}
|
|
2275
2418
|
return void 0;
|
|
@@ -2300,12 +2443,12 @@ function requestContextText(context, fieldName) {
|
|
|
2300
2443
|
return value;
|
|
2301
2444
|
}
|
|
2302
2445
|
function isPlainObject(value) {
|
|
2303
|
-
return typeof value === "object" && value != null && !Array.isArray(value) && !
|
|
2446
|
+
return typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer7.Buffer.isBuffer(value) && !(value instanceof Uint8Array);
|
|
2304
2447
|
}
|
|
2305
2448
|
function commandToken2(value) {
|
|
2306
2449
|
if (typeof value === "string") return value.toUpperCase();
|
|
2307
|
-
if (
|
|
2308
|
-
return
|
|
2450
|
+
if (import_node_buffer7.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
2451
|
+
return import_node_buffer7.Buffer.from(value).toString("utf8").toUpperCase();
|
|
2309
2452
|
}
|
|
2310
2453
|
return "";
|
|
2311
2454
|
}
|
|
@@ -2395,17 +2538,17 @@ function requestFrameTooLarge(maxBytes) {
|
|
|
2395
2538
|
);
|
|
2396
2539
|
}
|
|
2397
2540
|
function binaryValueByteLength(value) {
|
|
2398
|
-
if (
|
|
2399
|
-
if (typeof value === "string") return
|
|
2541
|
+
if (import_node_buffer8.Buffer.isBuffer(value) || value instanceof Uint8Array) return value.byteLength;
|
|
2542
|
+
if (typeof value === "string") return import_node_buffer8.Buffer.byteLength(value);
|
|
2400
2543
|
if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
|
|
2401
|
-
return
|
|
2544
|
+
return import_node_buffer8.Buffer.byteLength(String(value));
|
|
2402
2545
|
}
|
|
2403
|
-
if (typeof value === "symbol") return
|
|
2546
|
+
if (typeof value === "symbol") return import_node_buffer8.Buffer.byteLength(value.description ?? value.toString());
|
|
2404
2547
|
if (value == null) return 0;
|
|
2405
2548
|
return toBuffer(value).byteLength;
|
|
2406
2549
|
}
|
|
2407
2550
|
function writeCustomPayload(output, offset, value, knownByteLength) {
|
|
2408
|
-
if (
|
|
2551
|
+
if (import_node_buffer8.Buffer.isBuffer(value)) {
|
|
2409
2552
|
value.copy(output, offset);
|
|
2410
2553
|
return;
|
|
2411
2554
|
}
|
|
@@ -2424,7 +2567,7 @@ function writeCustomPayload(output, offset, value, knownByteLength) {
|
|
|
2424
2567
|
} else {
|
|
2425
2568
|
throw new FerricStoreError(`unsupported binary command argument type: ${typeof value}`);
|
|
2426
2569
|
}
|
|
2427
|
-
output.write(text3, offset, knownByteLength ??
|
|
2570
|
+
output.write(text3, offset, knownByteLength ?? import_node_buffer8.Buffer.byteLength(text3), "utf8");
|
|
2428
2571
|
}
|
|
2429
2572
|
function compactBinaryEncodedLength(value) {
|
|
2430
2573
|
return 4 + compactBinaryByteLength(value);
|
|
@@ -2437,10 +2580,10 @@ function compactBinaryByteLength(value) {
|
|
|
2437
2580
|
return byteLength;
|
|
2438
2581
|
}
|
|
2439
2582
|
function isCompactBinaryArgument(value) {
|
|
2440
|
-
return typeof value === "string" ||
|
|
2583
|
+
return typeof value === "string" || import_node_buffer8.Buffer.isBuffer(value) || value instanceof Uint8Array;
|
|
2441
2584
|
}
|
|
2442
2585
|
function isCompactBinaryScalar(value) {
|
|
2443
|
-
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean" || typeof value === "symbol" ||
|
|
2586
|
+
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean" || typeof value === "symbol" || import_node_buffer8.Buffer.isBuffer(value) || value instanceof Uint8Array;
|
|
2444
2587
|
}
|
|
2445
2588
|
function compactOptionalBinaryEncodedLength(value) {
|
|
2446
2589
|
return value == null ? 4 : compactBinaryEncodedLength(value);
|
|
@@ -2506,7 +2649,7 @@ function integerArg(value) {
|
|
|
2506
2649
|
throw new FerricStoreError("integer command argument must be an integer");
|
|
2507
2650
|
}
|
|
2508
2651
|
const integer2 = BigInt(source);
|
|
2509
|
-
if (integer2 <
|
|
2652
|
+
if (integer2 < MIN_I642 || integer2 > MAX_I642) {
|
|
2510
2653
|
throw new FerricStoreError("integer command argument exceeds the signed 64-bit range");
|
|
2511
2654
|
}
|
|
2512
2655
|
return integer2 >= MIN_SAFE_INTEGER_BIGINT && integer2 <= MAX_SAFE_INTEGER_BIGINT ? Number(integer2) : integer2;
|
|
@@ -2537,7 +2680,7 @@ function independentMode(value) {
|
|
|
2537
2680
|
return 0;
|
|
2538
2681
|
}
|
|
2539
2682
|
function optionalI64(value) {
|
|
2540
|
-
return typeof value === "number" ? BigInt(value) :
|
|
2683
|
+
return typeof value === "number" ? BigInt(value) : MIN_I642;
|
|
2541
2684
|
}
|
|
2542
2685
|
function compactClaimReturnMode(value) {
|
|
2543
2686
|
const mode = value == null ? "" : asText(value).toUpperCase();
|
|
@@ -2571,18 +2714,18 @@ function setOwnValue2(target, key, value) {
|
|
|
2571
2714
|
}
|
|
2572
2715
|
|
|
2573
2716
|
// src/protocol-flow-options.ts
|
|
2574
|
-
var
|
|
2717
|
+
var import_node_buffer9 = require("buffer");
|
|
2575
2718
|
|
|
2576
2719
|
// src/protocol-flow-option-value.ts
|
|
2577
|
-
function setFlowOptionValue(payload,
|
|
2578
|
-
if (!repeat || !Object.hasOwn(payload,
|
|
2579
|
-
setOwnValue2(payload,
|
|
2720
|
+
function setFlowOptionValue(payload, field3, value, repeat) {
|
|
2721
|
+
if (!repeat || !Object.hasOwn(payload, field3)) {
|
|
2722
|
+
setOwnValue2(payload, field3, value);
|
|
2580
2723
|
return;
|
|
2581
2724
|
}
|
|
2582
|
-
const previous = payload[
|
|
2725
|
+
const previous = payload[field3];
|
|
2583
2726
|
setOwnValue2(
|
|
2584
2727
|
payload,
|
|
2585
|
-
|
|
2728
|
+
field3,
|
|
2586
2729
|
Array.isArray(previous) ? [...previous, value] : [previous, value]
|
|
2587
2730
|
);
|
|
2588
2731
|
}
|
|
@@ -2625,44 +2768,30 @@ function optionMap(args) {
|
|
|
2625
2768
|
index += 3;
|
|
2626
2769
|
continue;
|
|
2627
2770
|
}
|
|
2628
|
-
const
|
|
2771
|
+
const field3 = OPTION_FIELDS[token] ?? token.toLowerCase();
|
|
2629
2772
|
if (!hasOwnCommandArgument(args, index + 1, args.length, "Flow options")) {
|
|
2630
2773
|
throw new FerricStoreError(`${token} requires a value`);
|
|
2631
2774
|
}
|
|
2632
2775
|
const value = args[index + 1];
|
|
2633
|
-
if (BOOL_OPTION_FIELDS.has(
|
|
2776
|
+
if (BOOL_OPTION_FIELDS.has(field3) && !isBoolToken(value)) {
|
|
2634
2777
|
return void 0;
|
|
2635
2778
|
}
|
|
2636
|
-
setOwnValue2(payload,
|
|
2779
|
+
setOwnValue2(payload, field3, BOOL_OPTION_FIELDS.has(field3) ? boolArg(value) : value);
|
|
2637
2780
|
index += 2;
|
|
2638
2781
|
}
|
|
2639
2782
|
return payload;
|
|
2640
2783
|
}
|
|
2641
|
-
function ensureObjectField(payload,
|
|
2642
|
-
const value = payload[
|
|
2784
|
+
function ensureObjectField(payload, field3) {
|
|
2785
|
+
const value = payload[field3];
|
|
2643
2786
|
if (isPlainObject2(value)) {
|
|
2644
2787
|
return value;
|
|
2645
2788
|
}
|
|
2646
2789
|
const next = {};
|
|
2647
|
-
setOwnValue2(payload,
|
|
2790
|
+
setOwnValue2(payload, field3, next);
|
|
2648
2791
|
return next;
|
|
2649
2792
|
}
|
|
2650
|
-
function normalizeFlowSearchStateMeta(payload) {
|
|
2651
|
-
const stateMeta = payload.state_meta;
|
|
2652
|
-
if (!isPlainObject2(stateMeta) || Object.keys(stateMeta).length === 0) {
|
|
2653
|
-
return;
|
|
2654
|
-
}
|
|
2655
|
-
if (Object.values(stateMeta).every(isPlainObject2)) {
|
|
2656
|
-
return;
|
|
2657
|
-
}
|
|
2658
|
-
const state = payload.state;
|
|
2659
|
-
if (state == null) {
|
|
2660
|
-
throw new FerricStoreError("FLOW.SEARCH STATE_META filters require STATE or nested state metadata");
|
|
2661
|
-
}
|
|
2662
|
-
payload.state_meta = { [asText(state)]: stateMeta };
|
|
2663
|
-
}
|
|
2664
2793
|
function isPlainObject2(value) {
|
|
2665
|
-
return typeof value === "object" && value != null && !Array.isArray(value) && !
|
|
2794
|
+
return typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer9.Buffer.isBuffer(value) && !(value instanceof Uint8Array);
|
|
2666
2795
|
}
|
|
2667
2796
|
function parseFlowOptions(args, start, end, config) {
|
|
2668
2797
|
const payload = {};
|
|
@@ -2756,9 +2885,9 @@ function parseFlowOptions(args, start, end, config) {
|
|
|
2756
2885
|
case "TRANSITION_TO":
|
|
2757
2886
|
case "TO_EVENT":
|
|
2758
2887
|
case "EXPECT_STATE": {
|
|
2759
|
-
const
|
|
2888
|
+
const field3 = token === "IDEMPOTENCY" ? "idempotency_key" : token.toLowerCase();
|
|
2760
2889
|
if (!hasOwnCommandArgument(args, index + 1, end, "Flow options")) return void 0;
|
|
2761
|
-
setFlowOptionValue(payload,
|
|
2890
|
+
setFlowOptionValue(payload, field3, args[index + 1], token === "IF_STATE");
|
|
2762
2891
|
index += 2;
|
|
2763
2892
|
break;
|
|
2764
2893
|
}
|
|
@@ -2766,8 +2895,8 @@ function parseFlowOptions(args, start, end, config) {
|
|
|
2766
2895
|
case "RESULT":
|
|
2767
2896
|
case "ERROR":
|
|
2768
2897
|
case "REASON": {
|
|
2769
|
-
const
|
|
2770
|
-
if (!putScalar(payload,
|
|
2898
|
+
const field3 = token === "LEASE_TOKEN" ? "lease_token" : token.toLowerCase();
|
|
2899
|
+
if (!putScalar(payload, field3, args, index + 1, end)) return void 0;
|
|
2771
2900
|
index += 2;
|
|
2772
2901
|
break;
|
|
2773
2902
|
}
|
|
@@ -2789,8 +2918,8 @@ function parseFlowOptions(args, start, end, config) {
|
|
|
2789
2918
|
case "VALUE_REF":
|
|
2790
2919
|
case "STATE_META": {
|
|
2791
2920
|
if (!hasOwnCommandArgument(args, index + 1, end, "Flow options") || !hasOwnCommandArgument(args, index + 2, end, "Flow options")) return void 0;
|
|
2792
|
-
const
|
|
2793
|
-
const values = ensureObjectField(payload,
|
|
2921
|
+
const field3 = token === "ATTRIBUTE" ? "attributes" : token === "ATTRIBUTE_MERGE" ? "attributes_merge" : token === "VALUE_REF" ? "value_refs" : "state_meta";
|
|
2922
|
+
const values = ensureObjectField(payload, field3);
|
|
2794
2923
|
setOwnValue2(values, asText(args[index + 1]), args[index + 2]);
|
|
2795
2924
|
index += 3;
|
|
2796
2925
|
break;
|
|
@@ -2799,8 +2928,8 @@ function parseFlowOptions(args, start, end, config) {
|
|
|
2799
2928
|
case "OVERRIDE_VALUE":
|
|
2800
2929
|
case "ATTRIBUTE_DELETE": {
|
|
2801
2930
|
if (!hasOwnCommandArgument(args, index + 1, end, "Flow options")) return void 0;
|
|
2802
|
-
const
|
|
2803
|
-
const values = ensureArrayField(payload,
|
|
2931
|
+
const field3 = token === "DROP_VALUE" ? "drop_values" : token === "OVERRIDE_VALUE" ? "override_values" : "attributes_delete";
|
|
2932
|
+
const values = ensureArrayField(payload, field3);
|
|
2804
2933
|
values.push(args[index + 1]);
|
|
2805
2934
|
index += 2;
|
|
2806
2935
|
break;
|
|
@@ -2917,13 +3046,13 @@ function putScalar(payload, key, args, index, end) {
|
|
|
2917
3046
|
setOwnValue2(payload, key, args[index]);
|
|
2918
3047
|
return true;
|
|
2919
3048
|
}
|
|
2920
|
-
function ensureArrayField(payload,
|
|
2921
|
-
const value = payload[
|
|
3049
|
+
function ensureArrayField(payload, field3) {
|
|
3050
|
+
const value = payload[field3];
|
|
2922
3051
|
if (Array.isArray(value)) {
|
|
2923
3052
|
return value;
|
|
2924
3053
|
}
|
|
2925
3054
|
const next = [];
|
|
2926
|
-
setOwnValue2(payload,
|
|
3055
|
+
setOwnValue2(payload, field3, next);
|
|
2927
3056
|
return next;
|
|
2928
3057
|
}
|
|
2929
3058
|
function putNumber(payload, key, args, index, end) {
|
|
@@ -3144,8 +3273,8 @@ function flowHistoryPayload(args) {
|
|
|
3144
3273
|
case "CONSISTENT_PROJECTION":
|
|
3145
3274
|
case "VALUES": {
|
|
3146
3275
|
if (!isBoolToken(value)) return void 0;
|
|
3147
|
-
const
|
|
3148
|
-
payload[
|
|
3276
|
+
const field3 = token === "REV" ? "rev" : token === "INCLUDE_COLD" ? "include_cold" : token === "CONSISTENT_PROJECTION" ? "consistent_projection" : "values";
|
|
3277
|
+
payload[field3] = boolArg(value);
|
|
3149
3278
|
break;
|
|
3150
3279
|
}
|
|
3151
3280
|
default:
|
|
@@ -3157,9 +3286,9 @@ function flowHistoryPayload(args) {
|
|
|
3157
3286
|
function flowAdminPayload(opcode, args, leadingFields = []) {
|
|
3158
3287
|
if (args.length < leadingFields.length) return void 0;
|
|
3159
3288
|
const payload = {};
|
|
3160
|
-
for (const [index,
|
|
3289
|
+
for (const [index, field3] of leadingFields.entries()) {
|
|
3161
3290
|
hasOwnCommandArgument(args, index, args.length, "Flow admin arguments");
|
|
3162
|
-
setOwnValue2(payload,
|
|
3291
|
+
setOwnValue2(payload, field3, args[index]);
|
|
3163
3292
|
}
|
|
3164
3293
|
for (let index = leadingFields.length; index < args.length; ) {
|
|
3165
3294
|
hasOwnCommandArgument(args, index, args.length, "Flow admin arguments");
|
|
@@ -3167,15 +3296,15 @@ function flowAdminPayload(opcode, args, leadingFields = []) {
|
|
|
3167
3296
|
if (token == null) return void 0;
|
|
3168
3297
|
if (["ATTRIBUTE", "ATTRIBUTE_MERGE", "STATE_META", "VALUE", "VALUE_REF"].includes(token)) {
|
|
3169
3298
|
if (!hasOwnCommandArgument(args, index + 1, args.length, "Flow admin arguments") || !hasOwnCommandArgument(args, index + 2, args.length, "Flow admin arguments")) return void 0;
|
|
3170
|
-
const
|
|
3171
|
-
setOwnValue2(ensureObjectField(payload,
|
|
3299
|
+
const field4 = token === "ATTRIBUTE" ? "attributes" : token === "ATTRIBUTE_MERGE" ? "attributes_merge" : token === "STATE_META" ? "state_meta" : token === "VALUE" ? "values" : "value_refs";
|
|
3300
|
+
setOwnValue2(ensureObjectField(payload, field4), asText(args[index + 1]), args[index + 2]);
|
|
3172
3301
|
index += 3;
|
|
3173
3302
|
continue;
|
|
3174
3303
|
}
|
|
3175
3304
|
if (token === "ATTRIBUTE_DELETE" || token === "DROP_VALUE" || token === "OVERRIDE_VALUE") {
|
|
3176
3305
|
if (!hasOwnCommandArgument(args, index + 1, args.length, "Flow admin arguments")) return void 0;
|
|
3177
|
-
const
|
|
3178
|
-
ensureArrayField(payload,
|
|
3306
|
+
const field4 = token === "ATTRIBUTE_DELETE" ? "attributes_delete" : token === "DROP_VALUE" ? "drop_values" : "override_values";
|
|
3307
|
+
ensureArrayField(payload, field4).push(args[index + 1]);
|
|
3179
3308
|
index += 2;
|
|
3180
3309
|
continue;
|
|
3181
3310
|
}
|
|
@@ -3194,13 +3323,13 @@ function flowAdminPayload(opcode, args, leadingFields = []) {
|
|
|
3194
3323
|
index += 2 + count;
|
|
3195
3324
|
continue;
|
|
3196
3325
|
}
|
|
3197
|
-
const
|
|
3198
|
-
if (
|
|
3326
|
+
const field3 = FLOW_ADMIN_FIELDS[token];
|
|
3327
|
+
if (field3 == null || !hasOwnCommandArgument(args, index + 1, args.length, "Flow admin arguments")) {
|
|
3199
3328
|
return void 0;
|
|
3200
3329
|
}
|
|
3201
3330
|
const rawValue = args[index + 1];
|
|
3202
|
-
if (FLOW_ADMIN_BOOLEAN_FIELDS.has(
|
|
3203
|
-
setOwnValue2(payload,
|
|
3331
|
+
if (FLOW_ADMIN_BOOLEAN_FIELDS.has(field3) && !isBoolToken(rawValue)) return void 0;
|
|
3332
|
+
setOwnValue2(payload, field3, FLOW_ADMIN_BOOLEAN_FIELDS.has(field3) ? boolArg(rawValue) : rawValue);
|
|
3204
3333
|
index += 2;
|
|
3205
3334
|
}
|
|
3206
3335
|
const serverBlockMs = opcode === COMMAND_OPCODES["FLOW.SCHEDULE.FIRE_DUE"] && payload.block_ms != null ? blockDurationMs(payload.block_ms, 1) : void 0;
|
|
@@ -3208,7 +3337,7 @@ function flowAdminPayload(opcode, args, leadingFields = []) {
|
|
|
3208
3337
|
}
|
|
3209
3338
|
|
|
3210
3339
|
// src/protocol-flow-compact.ts
|
|
3211
|
-
var
|
|
3340
|
+
var import_node_buffer11 = require("buffer");
|
|
3212
3341
|
|
|
3213
3342
|
// src/protocol-flow-compact-common.ts
|
|
3214
3343
|
function compactManyRequestTag(value, regularTag, okOnSuccessTag) {
|
|
@@ -3317,7 +3446,7 @@ function parseNamedCountMap(values, start) {
|
|
|
3317
3446
|
}
|
|
3318
3447
|
|
|
3319
3448
|
// src/protocol-flow-compact-transition.ts
|
|
3320
|
-
var
|
|
3449
|
+
var import_node_buffer10 = require("buffer");
|
|
3321
3450
|
function compactFlowTransitionManyPayload(partition, fromState, toState, rawItems, mixed, options, maxBodyBytes) {
|
|
3322
3451
|
if ("payload" in options || "priority" in options || "state_meta" in options || "values" in options || "value_refs" in options || "drop_values" in options || "override_values" in options || "attributes_merge" in options || "attributes_delete" in options || typeof options.now_ms !== "number" || !Number.isSafeInteger(options.now_ms) || options.now_ms < 0) {
|
|
3323
3452
|
return void 0;
|
|
@@ -3369,7 +3498,7 @@ function compactFlowTransitionManyPayload(partition, fromState, toState, rawItem
|
|
|
3369
3498
|
total += 4 + idLength + 4 + itemPartitionLength + 8 + 4 + leaseLength;
|
|
3370
3499
|
}
|
|
3371
3500
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3372
|
-
const out =
|
|
3501
|
+
const out = import_node_buffer10.Buffer.allocUnsafe(total);
|
|
3373
3502
|
let offset = 0;
|
|
3374
3503
|
out.writeUInt8(tag, offset);
|
|
3375
3504
|
offset += 1;
|
|
@@ -3427,7 +3556,7 @@ function compactFlowCreateManyPayload(partition, rawItems, mixed, auto, options,
|
|
|
3427
3556
|
}
|
|
3428
3557
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3429
3558
|
const tag = mixed ? COMPACT_FLOW_CREATE_MANY_MIXED_REQUEST : auto ? COMPACT_FLOW_CREATE_MANY_REQUEST : COMPACT_FLOW_CREATE_MANY_PARTITION_REQUEST;
|
|
3430
|
-
const out =
|
|
3559
|
+
const out = import_node_buffer11.Buffer.allocUnsafe(total);
|
|
3431
3560
|
let offset = 0;
|
|
3432
3561
|
out.writeUInt8(tag, offset++);
|
|
3433
3562
|
offset = writeBinary(out, offset, toBuffer(options.type));
|
|
@@ -3472,7 +3601,7 @@ function compactFlowClaimDuePayload(type, options, maxBodyBytes) {
|
|
|
3472
3601
|
total += 1;
|
|
3473
3602
|
}
|
|
3474
3603
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3475
|
-
const out =
|
|
3604
|
+
const out = import_node_buffer11.Buffer.allocUnsafe(total);
|
|
3476
3605
|
let offset = 0;
|
|
3477
3606
|
out.writeUInt8(COMPACT_FLOW_CLAIM_DUE_REQUEST, offset++);
|
|
3478
3607
|
offset = writeBinary(out, offset, toBuffer(type));
|
|
@@ -3526,7 +3655,7 @@ function compactFlowCompleteManyPayload(opcode, partition, rawItems, mixed, auto
|
|
|
3526
3655
|
total += compactBinaryEncodedLength(rawItems[rawIndex]) + compactOptionalBinaryEncodedLength(mixed ? rawItems[rawIndex + 1] : null) + compactBinaryEncodedLength(rawItems[rawIndex + width - 2]) + 8;
|
|
3527
3656
|
}
|
|
3528
3657
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3529
|
-
const out =
|
|
3658
|
+
const out = import_node_buffer11.Buffer.allocUnsafe(total);
|
|
3530
3659
|
let offset = 0;
|
|
3531
3660
|
out.writeUInt8(
|
|
3532
3661
|
returnMode === "OK_ON_SUCCESS" ? COMPACT_FLOW_COMPLETE_MANY_OK_REQUEST : COMPACT_FLOW_COMPLETE_MANY_REQUEST,
|
|
@@ -3573,7 +3702,7 @@ function compactFlowRetryManyPayload(partition, rawItems, mixed, auto, options,
|
|
|
3573
3702
|
total += compactBinaryEncodedLength(rawItems[rawIndex]) + compactOptionalBinaryEncodedLength(mixed ? rawItems[rawIndex + 1] : null) + compactBinaryEncodedLength(rawItems[rawIndex + width - 2]) + 8;
|
|
3574
3703
|
}
|
|
3575
3704
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3576
|
-
const out =
|
|
3705
|
+
const out = import_node_buffer11.Buffer.allocUnsafe(total);
|
|
3577
3706
|
let offset = 0;
|
|
3578
3707
|
out.writeUInt8(
|
|
3579
3708
|
returnMode === "OK_ON_SUCCESS" ? COMPACT_FLOW_RETRY_MANY_OK_REQUEST : COMPACT_FLOW_RETRY_MANY_REQUEST,
|
|
@@ -3661,7 +3790,7 @@ function compactFlowCancelManyPayload(args, maxBodyBytes) {
|
|
|
3661
3790
|
total += 4 + idLength + 4 + itemPartitionLength + 8;
|
|
3662
3791
|
}
|
|
3663
3792
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3664
|
-
const out =
|
|
3793
|
+
const out = import_node_buffer11.Buffer.allocUnsafe(total);
|
|
3665
3794
|
let offset = 0;
|
|
3666
3795
|
out.writeUInt8(tag, offset);
|
|
3667
3796
|
offset += 1;
|
|
@@ -3684,6 +3813,7 @@ function compactFlowCancelManyPayload(args, maxBodyBytes) {
|
|
|
3684
3813
|
offset += 8;
|
|
3685
3814
|
}
|
|
3686
3815
|
return {
|
|
3816
|
+
compactResponseItems: count,
|
|
3687
3817
|
flags: FLAG_CUSTOM_PAYLOAD,
|
|
3688
3818
|
opcode: COMMAND_OPCODES["FLOW.CANCEL_MANY"],
|
|
3689
3819
|
payload: out
|
|
@@ -3697,7 +3827,7 @@ function isOptionalSafeIntegerNumber(value) {
|
|
|
3697
3827
|
}
|
|
3698
3828
|
|
|
3699
3829
|
// src/protocol-flow-compact-single.ts
|
|
3700
|
-
var
|
|
3830
|
+
var import_node_buffer12 = require("buffer");
|
|
3701
3831
|
function compactFlowValueMGetPayload(refs, maxBytes, maxBodyBytes) {
|
|
3702
3832
|
if (refs.length > 4294967295 || maxBytes != null && (typeof maxBytes !== "number" || !Number.isSafeInteger(maxBytes) || maxBytes < 0)) return void 0;
|
|
3703
3833
|
const minimum = 13 + refs.length * 4;
|
|
@@ -3714,7 +3844,7 @@ function compactFlowValueMGetPayload(refs, maxBytes, maxBodyBytes) {
|
|
|
3714
3844
|
total += 4 + byteLength;
|
|
3715
3845
|
}
|
|
3716
3846
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3717
|
-
const out =
|
|
3847
|
+
const out = import_node_buffer12.Buffer.allocUnsafe(total);
|
|
3718
3848
|
let offset = 0;
|
|
3719
3849
|
out.writeUInt8(COMPACT_FLOW_VALUE_MGET_REQUEST, offset);
|
|
3720
3850
|
offset += 1;
|
|
@@ -3727,47 +3857,6 @@ function compactFlowValueMGetPayload(refs, maxBytes, maxBodyBytes) {
|
|
|
3727
3857
|
}
|
|
3728
3858
|
return { flags: FLAG_CUSTOM_PAYLOAD, opcode: OPCODES.flowValueMGet, payload: out };
|
|
3729
3859
|
}
|
|
3730
|
-
function compactFlowListPayload(args, maxBodyBytes) {
|
|
3731
|
-
const type = args[0];
|
|
3732
|
-
if (!isCompactBinaryArgument(type)) return void 0;
|
|
3733
|
-
let state;
|
|
3734
|
-
let count = 100;
|
|
3735
|
-
let returnMode = 0;
|
|
3736
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3737
|
-
for (let index = 1; index < args.length; index += 2) {
|
|
3738
|
-
if (index + 1 >= args.length) return void 0;
|
|
3739
|
-
const token = asText(args[index]).toUpperCase();
|
|
3740
|
-
if (seen.has(token)) return void 0;
|
|
3741
|
-
seen.add(token);
|
|
3742
|
-
if (token === "STATE") {
|
|
3743
|
-
if (!isCompactBinaryArgument(args[index + 1])) return void 0;
|
|
3744
|
-
state = args[index + 1];
|
|
3745
|
-
} else if (token === "COUNT") {
|
|
3746
|
-
const value = safeIntegerNumberArg(args[index + 1]);
|
|
3747
|
-
if (value <= 0) return void 0;
|
|
3748
|
-
count = value;
|
|
3749
|
-
} else if (token === "RETURN") {
|
|
3750
|
-
if (!commandTokenIs(args[index + 1], "META")) return void 0;
|
|
3751
|
-
returnMode = 1;
|
|
3752
|
-
} else {
|
|
3753
|
-
return void 0;
|
|
3754
|
-
}
|
|
3755
|
-
}
|
|
3756
|
-
const typeLength = compactBinaryByteLength(type);
|
|
3757
|
-
const stateLength = state == null ? 0 : compactBinaryByteLength(state);
|
|
3758
|
-
const total = 1 + 4 + typeLength + 4 + stateLength + 8 + 1;
|
|
3759
|
-
assertCompactPayloadFits(total, maxBodyBytes);
|
|
3760
|
-
const out = import_node_buffer11.Buffer.allocUnsafe(total);
|
|
3761
|
-
let offset = 0;
|
|
3762
|
-
out.writeUInt8(COMPACT_FLOW_LIST_REQUEST, offset);
|
|
3763
|
-
offset += 1;
|
|
3764
|
-
offset = writeBinaryValue(out, offset, type, typeLength);
|
|
3765
|
-
offset = writeOptionalBinaryValue(out, offset, state, stateLength);
|
|
3766
|
-
out.writeBigInt64BE(BigInt(count), offset);
|
|
3767
|
-
offset += 8;
|
|
3768
|
-
out.writeUInt8(returnMode, offset);
|
|
3769
|
-
return { flags: FLAG_CUSTOM_PAYLOAD, opcode: COMMAND_OPCODES["FLOW.LIST"], payload: out };
|
|
3770
|
-
}
|
|
3771
3860
|
|
|
3772
3861
|
// src/protocol-flow-routing.ts
|
|
3773
3862
|
function withFlowPartitionRouting(command, payload) {
|
|
@@ -3816,15 +3905,6 @@ function expandFlowClaimStates(args) {
|
|
|
3816
3905
|
}
|
|
3817
3906
|
|
|
3818
3907
|
// src/protocol-flow.ts
|
|
3819
|
-
function hasFlowCommandOnlyOption(command, args) {
|
|
3820
|
-
if (command !== "FLOW.SEARCH") return false;
|
|
3821
|
-
for (let index = 1; index < args.length; ) {
|
|
3822
|
-
const token = asText(args[index]).toUpperCase();
|
|
3823
|
-
if (token === "INDEXED_STATE_META") return true;
|
|
3824
|
-
index += token === "ATTRIBUTE" || token === "STATE_META" ? 3 : 2;
|
|
3825
|
-
}
|
|
3826
|
-
return false;
|
|
3827
|
-
}
|
|
3828
3908
|
function flowCreatePayload(args) {
|
|
3829
3909
|
if (args.length < 7) return void 0;
|
|
3830
3910
|
const id = args[0];
|
|
@@ -3881,9 +3961,9 @@ function flowValueMGetPayload(args, maxBodyBytes, allowCompact) {
|
|
|
3881
3961
|
}
|
|
3882
3962
|
if (allowCompact) {
|
|
3883
3963
|
const compact = compactFlowValueMGetPayload(refs, payload.max_bytes, maxBodyBytes);
|
|
3884
|
-
if (compact != null) return compact;
|
|
3964
|
+
if (compact != null) return { ...compact, compactResponseItems: refs.length };
|
|
3885
3965
|
}
|
|
3886
|
-
return { opcode: OPCODES.flowValueMGet, payload };
|
|
3966
|
+
return { compactResponseItems: refs.length, opcode: OPCODES.flowValueMGet, payload };
|
|
3887
3967
|
}
|
|
3888
3968
|
function flowCreateManyPayload(args, maxBodyBytes, allowCompact) {
|
|
3889
3969
|
if (args.length < 2) return void 0;
|
|
@@ -3919,7 +3999,7 @@ function flowCreateManyPayload(args, maxBodyBytes, allowCompact) {
|
|
|
3919
3999
|
if (items2 == null) return void 0;
|
|
3920
4000
|
const payload2 = { ...options, items: items2 };
|
|
3921
4001
|
if (!auto && !mixed) payload2.partition_key = partition;
|
|
3922
|
-
return { opcode: OPCODES.flowCreateMany, payload: payload2 };
|
|
4002
|
+
return { compactResponseItems: items2.length, opcode: OPCODES.flowCreateMany, payload: payload2 };
|
|
3923
4003
|
}
|
|
3924
4004
|
const rawItems = denseCommandArgumentTail(args, itemsIndex + 1, "ITEMS");
|
|
3925
4005
|
const width = mixed ? 3 : 2;
|
|
@@ -3933,7 +4013,9 @@ function flowCreateManyPayload(args, maxBodyBytes, allowCompact) {
|
|
|
3933
4013
|
options,
|
|
3934
4014
|
maxBodyBytes
|
|
3935
4015
|
);
|
|
3936
|
-
if (compact != null)
|
|
4016
|
+
if (compact != null) {
|
|
4017
|
+
return { ...compact, compactResponseItems: rawItems.length / width };
|
|
4018
|
+
}
|
|
3937
4019
|
}
|
|
3938
4020
|
const items = [];
|
|
3939
4021
|
for (let index = 0; index < rawItems.length; index += width) {
|
|
@@ -3945,7 +4027,7 @@ function flowCreateManyPayload(args, maxBodyBytes, allowCompact) {
|
|
|
3945
4027
|
}
|
|
3946
4028
|
const payload = { ...options, items };
|
|
3947
4029
|
if (!auto && !mixed) payload.partition_key = partition;
|
|
3948
|
-
return { opcode: OPCODES.flowCreateMany, payload };
|
|
4030
|
+
return { compactResponseItems: items.length, opcode: OPCODES.flowCreateMany, payload };
|
|
3949
4031
|
}
|
|
3950
4032
|
function flowClaimDuePayload(args, maxBodyBytes, allowCompact) {
|
|
3951
4033
|
if (args.length < 1) return void 0;
|
|
@@ -4108,7 +4190,9 @@ function flowClaimedManyPayload(command, opcode, args, maxBodyBytes = Number.MAX
|
|
|
4108
4190
|
if (rawItems.length === 0 || rawItems.length % width !== 0) return void 0;
|
|
4109
4191
|
if (allowCompact) {
|
|
4110
4192
|
const compact = command === "FLOW.RETRY_MANY" ? compactFlowRetryManyPayload(partition, rawItems, mixed, auto, options, maxBodyBytes) : compactFlowCompleteManyPayload(opcode, partition, rawItems, mixed, auto, options, maxBodyBytes);
|
|
4111
|
-
if (compact != null)
|
|
4193
|
+
if (compact != null) {
|
|
4194
|
+
return { ...compact, compactResponseItems: rawItems.length / width };
|
|
4195
|
+
}
|
|
4112
4196
|
}
|
|
4113
4197
|
const items = [];
|
|
4114
4198
|
for (let index = 0; index < rawItems.length; index += width) {
|
|
@@ -4120,7 +4204,7 @@ function flowClaimedManyPayload(command, opcode, args, maxBodyBytes = Number.MAX
|
|
|
4120
4204
|
}
|
|
4121
4205
|
const payload = { ...options, items };
|
|
4122
4206
|
if (!auto && !mixed) payload.partition_key = partition;
|
|
4123
|
-
return { opcode, payload };
|
|
4207
|
+
return { compactResponseItems: items.length, opcode, payload };
|
|
4124
4208
|
}
|
|
4125
4209
|
function flowTransitionManyPayload(args, maxBodyBytes, allowCompact) {
|
|
4126
4210
|
if (args.length < 4) return void 0;
|
|
@@ -4160,7 +4244,9 @@ function flowTransitionManyPayload(args, maxBodyBytes, allowCompact) {
|
|
|
4160
4244
|
options,
|
|
4161
4245
|
maxBodyBytes
|
|
4162
4246
|
) : void 0;
|
|
4163
|
-
if (compact != null)
|
|
4247
|
+
if (compact != null) {
|
|
4248
|
+
return { ...compact, compactResponseItems: rawItems.length / width };
|
|
4249
|
+
}
|
|
4164
4250
|
}
|
|
4165
4251
|
const items = [];
|
|
4166
4252
|
for (let index = 0; index < rawItems.length; index += width) {
|
|
@@ -4180,7 +4266,11 @@ function flowTransitionManyPayload(args, maxBodyBytes, allowCompact) {
|
|
|
4180
4266
|
items
|
|
4181
4267
|
};
|
|
4182
4268
|
if (!mixed) payload.partition_key = args[0];
|
|
4183
|
-
return {
|
|
4269
|
+
return {
|
|
4270
|
+
compactResponseItems: items.length,
|
|
4271
|
+
opcode: OPCODES.flowTransitionMany,
|
|
4272
|
+
payload
|
|
4273
|
+
};
|
|
4184
4274
|
}
|
|
4185
4275
|
function flowSpawnChildrenPayload(args) {
|
|
4186
4276
|
if (args.length < 2) return void 0;
|
|
@@ -4223,13 +4313,6 @@ function flowSpawnChildrenPayload(args) {
|
|
|
4223
4313
|
payload: { id: args[0], ...options, children }
|
|
4224
4314
|
};
|
|
4225
4315
|
}
|
|
4226
|
-
function flowSearchPayload(args) {
|
|
4227
|
-
if (args.length < 1) return void 0;
|
|
4228
|
-
const payload = optionMap(args.slice(1));
|
|
4229
|
-
if (payload == null) return void 0;
|
|
4230
|
-
normalizeFlowSearchStateMeta(payload);
|
|
4231
|
-
return { opcode: OPCODES.flowSearch, payload: { type: args[0], ...payload } };
|
|
4232
|
-
}
|
|
4233
4316
|
|
|
4234
4317
|
// src/protocol-flow-signal.ts
|
|
4235
4318
|
function flowSignalPayload(args) {
|
|
@@ -4254,6 +4337,162 @@ function flowSignalPayload(args) {
|
|
|
4254
4337
|
return { opcode: OPCODES.flowSignal, payload: { id: args[0], ...options } };
|
|
4255
4338
|
}
|
|
4256
4339
|
|
|
4340
|
+
// src/protocol-flow-policy.ts
|
|
4341
|
+
var import_node_buffer13 = require("buffer");
|
|
4342
|
+
var BACKOFF_FIELDS = {
|
|
4343
|
+
BASE_MS: "base_ms",
|
|
4344
|
+
MAX_MS: "max_ms",
|
|
4345
|
+
JITTER_PCT: "jitter_pct"
|
|
4346
|
+
};
|
|
4347
|
+
var RETENTION_FIELDS = {
|
|
4348
|
+
RETENTION_TTL: "ttl_ms",
|
|
4349
|
+
RETENTION_TTL_MS: "ttl_ms",
|
|
4350
|
+
HISTORY_MAX_EVENTS: "history_max_events"
|
|
4351
|
+
};
|
|
4352
|
+
function flowPolicySetPayload(args) {
|
|
4353
|
+
if (!hasOwnCommandArgument(args, 0, args.length, "Flow policy arguments")) return void 0;
|
|
4354
|
+
if (!isBinaryArgument(args[0])) return void 0;
|
|
4355
|
+
const payload = { type: args[0] };
|
|
4356
|
+
const states = {};
|
|
4357
|
+
let target = payload;
|
|
4358
|
+
for (let index = 1; index < args.length; index += 2) {
|
|
4359
|
+
if (!hasOwnCommandArgument(args, index, args.length, "Flow policy arguments") || !hasOwnCommandArgument(args, index + 1, args.length, "Flow policy arguments")) return void 0;
|
|
4360
|
+
const token = optionalText(args[index])?.toUpperCase();
|
|
4361
|
+
const value = args[index + 1];
|
|
4362
|
+
if (token == null || value == null) return void 0;
|
|
4363
|
+
if (token === "STATE") {
|
|
4364
|
+
if (!isBinaryArgument(value)) return void 0;
|
|
4365
|
+
const state = asText(value);
|
|
4366
|
+
target = {};
|
|
4367
|
+
setOwnValue2(states, state, target);
|
|
4368
|
+
setOwnValue2(payload, "states", states);
|
|
4369
|
+
continue;
|
|
4370
|
+
}
|
|
4371
|
+
if (token === "MODE") {
|
|
4372
|
+
if (!isBinaryArgument(value)) return void 0;
|
|
4373
|
+
const mode = optionalText(value)?.toLowerCase();
|
|
4374
|
+
if (target === payload || mode !== "fifo" && mode !== "parallel") return void 0;
|
|
4375
|
+
setOwnValue2(target, "mode", mode);
|
|
4376
|
+
continue;
|
|
4377
|
+
}
|
|
4378
|
+
if (token === "EXPECTED_GENERATION") {
|
|
4379
|
+
if (target !== payload) return void 0;
|
|
4380
|
+
const generation = integerOption(value);
|
|
4381
|
+
if (generation == null || generation < 0) return void 0;
|
|
4382
|
+
setOwnValue2(payload, "expected_generation", generation);
|
|
4383
|
+
continue;
|
|
4384
|
+
}
|
|
4385
|
+
if (token === "REPLACE") {
|
|
4386
|
+
if (target !== payload || !isBoolToken(value)) return void 0;
|
|
4387
|
+
setOwnValue2(payload, "replace", boolArg(value));
|
|
4388
|
+
continue;
|
|
4389
|
+
}
|
|
4390
|
+
if (token === "MAX_ACTIVE_MS") {
|
|
4391
|
+
if (target !== payload) return void 0;
|
|
4392
|
+
const maxActiveMs = maxActiveOption(value);
|
|
4393
|
+
if (maxActiveMs == null) return void 0;
|
|
4394
|
+
setOwnValue2(payload, "max_active_ms", maxActiveMs);
|
|
4395
|
+
continue;
|
|
4396
|
+
}
|
|
4397
|
+
if (token === "INDEXED_STATE_META") {
|
|
4398
|
+
if (target !== payload || !isBinaryArgument(value)) return void 0;
|
|
4399
|
+
setOwnValue2(payload, "indexed_state_meta", value);
|
|
4400
|
+
continue;
|
|
4401
|
+
}
|
|
4402
|
+
if (token === "INDEXED_ATTRIBUTES") {
|
|
4403
|
+
if (target !== payload) return void 0;
|
|
4404
|
+
const names = indexedAttributes(value);
|
|
4405
|
+
if (names == null) return void 0;
|
|
4406
|
+
setOwnValue2(payload, "indexed_attributes", names);
|
|
4407
|
+
continue;
|
|
4408
|
+
}
|
|
4409
|
+
if (token === "MAX_RETRIES") {
|
|
4410
|
+
const parsed = integerOption(value);
|
|
4411
|
+
if (parsed == null) return void 0;
|
|
4412
|
+
setOwnValue2(objectField(target, "retry"), "max_retries", parsed);
|
|
4413
|
+
continue;
|
|
4414
|
+
}
|
|
4415
|
+
if (token === "EXHAUSTED_TO") {
|
|
4416
|
+
if (!isBinaryArgument(value)) return void 0;
|
|
4417
|
+
setOwnValue2(objectField(target, "retry"), "exhausted_to", value);
|
|
4418
|
+
continue;
|
|
4419
|
+
}
|
|
4420
|
+
const backoffField = BACKOFF_FIELDS[token];
|
|
4421
|
+
if (backoffField != null) {
|
|
4422
|
+
const parsed = integerOption(value);
|
|
4423
|
+
if (parsed == null) return void 0;
|
|
4424
|
+
setOwnValue2(objectField(objectField(target, "retry"), "backoff"), backoffField, parsed);
|
|
4425
|
+
continue;
|
|
4426
|
+
}
|
|
4427
|
+
if (token === "BACKOFF") {
|
|
4428
|
+
if (!isBinaryArgument(value)) return void 0;
|
|
4429
|
+
const kind = optionalText(value)?.toLowerCase();
|
|
4430
|
+
if (kind == null) return void 0;
|
|
4431
|
+
setOwnValue2(objectField(objectField(target, "retry"), "backoff"), "kind", kind);
|
|
4432
|
+
continue;
|
|
4433
|
+
}
|
|
4434
|
+
const retentionField = RETENTION_FIELDS[token];
|
|
4435
|
+
if (retentionField != null) {
|
|
4436
|
+
if (target === payload) return void 0;
|
|
4437
|
+
const parsed = integerOption(value);
|
|
4438
|
+
if (parsed == null) return void 0;
|
|
4439
|
+
setOwnValue2(objectField(target, "retention"), retentionField, parsed);
|
|
4440
|
+
continue;
|
|
4441
|
+
}
|
|
4442
|
+
return void 0;
|
|
4443
|
+
}
|
|
4444
|
+
return { opcode: OPCODES.flowPolicySet, payload };
|
|
4445
|
+
}
|
|
4446
|
+
function flowPolicyGetPayload(args) {
|
|
4447
|
+
if (!hasOwnCommandArgument(args, 0, args.length, "Flow policy arguments")) return void 0;
|
|
4448
|
+
if (!isBinaryArgument(args[0])) return void 0;
|
|
4449
|
+
if (args.length !== 1 && args.length !== 3) return void 0;
|
|
4450
|
+
const payload = { type: args[0] };
|
|
4451
|
+
if (args.length === 3) {
|
|
4452
|
+
if (!hasOwnCommandArgument(args, 1, args.length, "Flow policy arguments") || !hasOwnCommandArgument(args, 2, args.length, "Flow policy arguments") || optionalText(args[1])?.toUpperCase() !== "STATE" || !isBinaryArgument(args[2])) return void 0;
|
|
4453
|
+
setOwnValue2(payload, "state", args[2]);
|
|
4454
|
+
}
|
|
4455
|
+
return { opcode: OPCODES.flowPolicyGet, payload };
|
|
4456
|
+
}
|
|
4457
|
+
function integerOption(value) {
|
|
4458
|
+
try {
|
|
4459
|
+
return safeIntegerNumberArg(value);
|
|
4460
|
+
} catch {
|
|
4461
|
+
return void 0;
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4464
|
+
function maxActiveOption(value) {
|
|
4465
|
+
if (isBinaryArgument(value) && asText(value).toLowerCase() === "infinity") {
|
|
4466
|
+
return "infinity";
|
|
4467
|
+
}
|
|
4468
|
+
return integerOption(value);
|
|
4469
|
+
}
|
|
4470
|
+
function isBinaryArgument(value) {
|
|
4471
|
+
return typeof value === "string" || import_node_buffer13.Buffer.isBuffer(value) || value instanceof Uint8Array;
|
|
4472
|
+
}
|
|
4473
|
+
function objectField(target, name) {
|
|
4474
|
+
const existing = Object.hasOwn(target, name) ? target[name] : void 0;
|
|
4475
|
+
if (typeof existing === "object" && existing != null && !Array.isArray(existing)) {
|
|
4476
|
+
return existing;
|
|
4477
|
+
}
|
|
4478
|
+
const value = {};
|
|
4479
|
+
setOwnValue2(target, name, value);
|
|
4480
|
+
return value;
|
|
4481
|
+
}
|
|
4482
|
+
function indexedAttributes(value) {
|
|
4483
|
+
if (Array.isArray(value)) {
|
|
4484
|
+
return value.every((item) => typeof item === "string") ? value : void 0;
|
|
4485
|
+
}
|
|
4486
|
+
const source = optionalText(value);
|
|
4487
|
+
if (source == null) return void 0;
|
|
4488
|
+
try {
|
|
4489
|
+
const parsed = JSON.parse(source);
|
|
4490
|
+
return Array.isArray(parsed) && parsed.every((item) => typeof item === "string") ? parsed : void 0;
|
|
4491
|
+
} catch {
|
|
4492
|
+
return void 0;
|
|
4493
|
+
}
|
|
4494
|
+
}
|
|
4495
|
+
|
|
4257
4496
|
// src/protocol-connection-policy.ts
|
|
4258
4497
|
function assertCommandDoesNotRequirePinnedConnection(args) {
|
|
4259
4498
|
const outer = commandName(args[0]);
|
|
@@ -4301,7 +4540,7 @@ function commandRequiresOrderedPipelineExecution(args) {
|
|
|
4301
4540
|
}
|
|
4302
4541
|
|
|
4303
4542
|
// src/protocol-compact-request.ts
|
|
4304
|
-
var
|
|
4543
|
+
var import_node_buffer14 = require("buffer");
|
|
4305
4544
|
function compactMsetPayload(args, maxBodyBytes) {
|
|
4306
4545
|
if (args.length % 2 !== 0) throw new FerricStoreError("MSET requires key/value pairs");
|
|
4307
4546
|
const minimum = 6 + args.length * 4;
|
|
@@ -4320,7 +4559,7 @@ function compactMsetPayload(args, maxBodyBytes) {
|
|
|
4320
4559
|
total += 4 + byteLength;
|
|
4321
4560
|
}
|
|
4322
4561
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
4323
|
-
const out =
|
|
4562
|
+
const out = import_node_buffer14.Buffer.allocUnsafe(total);
|
|
4324
4563
|
let offset = writeCompactPipelineHeader(out, 1, args.length / 2);
|
|
4325
4564
|
for (let index = 0; index < args.length; index += 1) {
|
|
4326
4565
|
offset = writeBinaryValue(out, offset, args[index], byteLengths[index] ?? 0);
|
|
@@ -4344,7 +4583,7 @@ function compactKeyPipelinePayload(opcode, args, mode, maxBodyBytes) {
|
|
|
4344
4583
|
total += 4 + byteLength;
|
|
4345
4584
|
}
|
|
4346
4585
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
4347
|
-
const out =
|
|
4586
|
+
const out = import_node_buffer14.Buffer.allocUnsafe(total);
|
|
4348
4587
|
let offset = writeCompactPipelineHeader(out, mode, args.length);
|
|
4349
4588
|
for (let index = 0; index < args.length; index += 1) {
|
|
4350
4589
|
offset = writeBinaryValue(out, offset, args[index], byteLengths[index] ?? 0);
|
|
@@ -4354,7 +4593,7 @@ function compactKeyPipelinePayload(opcode, args, mode, maxBodyBytes) {
|
|
|
4354
4593
|
function compactPipelinePayload(commands, maxBodyBytes) {
|
|
4355
4594
|
if (commands.length === 0) {
|
|
4356
4595
|
assertCompactPayloadFits(6, maxBodyBytes);
|
|
4357
|
-
const out =
|
|
4596
|
+
const out = import_node_buffer14.Buffer.allocUnsafe(6);
|
|
4358
4597
|
writeCompactPipelineHeader(out, 128 | 2, 0);
|
|
4359
4598
|
return out;
|
|
4360
4599
|
}
|
|
@@ -4396,7 +4635,7 @@ function compactSetPipelinePayload(commands, maxBodyBytes) {
|
|
|
4396
4635
|
total += 8 + keyByteLength + valueByteLength;
|
|
4397
4636
|
}
|
|
4398
4637
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
4399
|
-
const out =
|
|
4638
|
+
const out = import_node_buffer14.Buffer.allocUnsafe(total);
|
|
4400
4639
|
let offset = writeCompactPipelineHeader(out, 128 | 1, commands.length);
|
|
4401
4640
|
for (let index = 0; index < commands.length; index += 1) {
|
|
4402
4641
|
offset = writeBinaryValue(out, offset, argumentValues[index * 2], argumentByteLengths[index * 2] ?? 0);
|
|
@@ -4431,7 +4670,7 @@ function compactGetPipelinePayload(commands, maxBodyBytes) {
|
|
|
4431
4670
|
total += 4 + keyByteLength;
|
|
4432
4671
|
}
|
|
4433
4672
|
assertCompactPayloadFits(total, maxBodyBytes);
|
|
4434
|
-
const out =
|
|
4673
|
+
const out = import_node_buffer14.Buffer.allocUnsafe(total);
|
|
4435
4674
|
let offset = writeCompactPipelineHeader(out, 128 | 2, commands.length);
|
|
4436
4675
|
for (let index = 0; index < commands.length; index += 1) {
|
|
4437
4676
|
offset = writeBinaryValue(out, offset, keys[index], keyByteLengths[index] ?? 0);
|
|
@@ -4445,7 +4684,7 @@ function compactArgumentsEligible(args, sparseMessage) {
|
|
|
4445
4684
|
}
|
|
4446
4685
|
return true;
|
|
4447
4686
|
}
|
|
4448
|
-
function compactPipelineEligible(commands,
|
|
4687
|
+
function compactPipelineEligible(commands, commandName5, argumentCount) {
|
|
4449
4688
|
for (let index = 0; index < commands.length; index += 1) {
|
|
4450
4689
|
const command = commands[index];
|
|
4451
4690
|
if (!Object.hasOwn(commands, index) || !Array.isArray(command)) {
|
|
@@ -4457,7 +4696,7 @@ function compactPipelineEligible(commands, commandName4, argumentCount) {
|
|
|
4457
4696
|
throw new TypeError("pipeline command arguments must be dense");
|
|
4458
4697
|
}
|
|
4459
4698
|
}
|
|
4460
|
-
if (!commandNameIs(command[0],
|
|
4699
|
+
if (!commandNameIs(command[0], commandName5)) return false;
|
|
4461
4700
|
for (let argumentIndex = 1; argumentIndex < argumentCount; argumentIndex += 1) {
|
|
4462
4701
|
if (!isCompactBinaryScalar(command[argumentIndex])) return false;
|
|
4463
4702
|
}
|
|
@@ -4472,7 +4711,7 @@ function writeCompactPipelineHeader(out, mode, count) {
|
|
|
4472
4711
|
}
|
|
4473
4712
|
|
|
4474
4713
|
// src/protocol-kv.ts
|
|
4475
|
-
var
|
|
4714
|
+
var import_node_buffer15 = require("buffer");
|
|
4476
4715
|
function collectionProtocolCommand(command, args) {
|
|
4477
4716
|
switch (command) {
|
|
4478
4717
|
case "CAS":
|
|
@@ -4543,8 +4782,8 @@ function stringSetPayload(args) {
|
|
|
4543
4782
|
if (value == null || token === "EX" && value > Math.floor(Number.MAX_SAFE_INTEGER / 1e3)) {
|
|
4544
4783
|
return void 0;
|
|
4545
4784
|
}
|
|
4546
|
-
const
|
|
4547
|
-
setOwnValue2(payload,
|
|
4785
|
+
const field3 = token === "EX" || token === "PX" ? "ttl" : token.toLowerCase();
|
|
4786
|
+
setOwnValue2(payload, field3, token === "EX" ? value * 1e3 : value);
|
|
4548
4787
|
expirySeen = true;
|
|
4549
4788
|
index += 2;
|
|
4550
4789
|
} else if (token === "NX") {
|
|
@@ -4643,25 +4882,25 @@ function hashSetCommand(args) {
|
|
|
4643
4882
|
if (!isBinaryCommandArgument(args[0]) || args.length < 3 || args.length % 2 !== 1) return void 0;
|
|
4644
4883
|
const fields = /* @__PURE__ */ Object.create(null);
|
|
4645
4884
|
for (let index = 1; index < args.length; index += 2) {
|
|
4646
|
-
const
|
|
4885
|
+
const field3 = args[index];
|
|
4647
4886
|
const value = args[index + 1];
|
|
4648
|
-
if (typeof
|
|
4649
|
-
setOwnValue2(fields,
|
|
4887
|
+
if (typeof field3 !== "string" || !isBinaryCommandArgument(value)) return void 0;
|
|
4888
|
+
setOwnValue2(fields, field3, value);
|
|
4650
4889
|
}
|
|
4651
4890
|
return { opcode: COMMAND_OPCODES.HSET, payload: { fields, key: args[0] } };
|
|
4652
4891
|
}
|
|
4653
4892
|
function keyOnlyCommand(opcode, args) {
|
|
4654
4893
|
return args.length === 1 && isBinaryCommandArgument(args[0]) ? { opcode, payload: { key: args[0] } } : void 0;
|
|
4655
4894
|
}
|
|
4656
|
-
function binaryFieldsCommand(opcode, args,
|
|
4895
|
+
function binaryFieldsCommand(opcode, args, field3, length) {
|
|
4657
4896
|
if (args.length !== length || !isBinaryCommandArgument(args[0]) || !isBinaryCommandArgument(args[1])) return void 0;
|
|
4658
|
-
return { opcode, payload: { [
|
|
4897
|
+
return { opcode, payload: { [field3]: args[1], key: args[0] } };
|
|
4659
4898
|
}
|
|
4660
|
-
function binaryListCommand(opcode, args,
|
|
4899
|
+
function binaryListCommand(opcode, args, field3) {
|
|
4661
4900
|
if (!isBinaryCommandArgument(args[0]) || args.length < 2) return void 0;
|
|
4662
4901
|
const values = args.slice(1);
|
|
4663
4902
|
if (!values.every(isBinaryCommandArgument)) return void 0;
|
|
4664
|
-
return { opcode, payload: { [
|
|
4903
|
+
return { opcode, payload: { [field3]: values, key: args[0] } };
|
|
4665
4904
|
}
|
|
4666
4905
|
function listPopCommand(opcode, args) {
|
|
4667
4906
|
if (!isBinaryCommandArgument(args[0]) || args.length !== 1 && args.length !== 2) return void 0;
|
|
@@ -4719,17 +4958,35 @@ function parsedNumber(value) {
|
|
|
4719
4958
|
}
|
|
4720
4959
|
}
|
|
4721
4960
|
function isBinaryCommandArgument(value) {
|
|
4722
|
-
return typeof value === "string" ||
|
|
4961
|
+
return typeof value === "string" || import_node_buffer15.Buffer.isBuffer(value);
|
|
4723
4962
|
}
|
|
4724
4963
|
function isDirectKvValueArgument(value) {
|
|
4725
4964
|
return isBinaryCommandArgument(value) || typeof value === "object" && value != null;
|
|
4726
4965
|
}
|
|
4727
4966
|
function binaryToken(value) {
|
|
4728
|
-
return typeof value === "string" ? value.toUpperCase() :
|
|
4967
|
+
return typeof value === "string" ? value.toUpperCase() : import_node_buffer15.Buffer.isBuffer(value) ? value.toString("utf8").toUpperCase() : void 0;
|
|
4968
|
+
}
|
|
4969
|
+
|
|
4970
|
+
// src/protocol-value.ts
|
|
4971
|
+
var import_node_buffer17 = require("buffer");
|
|
4972
|
+
|
|
4973
|
+
// src/protocol-map-key.ts
|
|
4974
|
+
var import_node_buffer16 = require("buffer");
|
|
4975
|
+
function setProtocolMapEntry(target, encodedKey, value) {
|
|
4976
|
+
if (typeof encodedKey === "string" && !encodedKey.isWellFormed()) {
|
|
4977
|
+
throw new FerricStoreError("native protocol map key must be valid UTF-8");
|
|
4978
|
+
}
|
|
4979
|
+
if (typeof encodedKey !== "string" && !(0, import_node_buffer16.isUtf8)(encodedKey)) {
|
|
4980
|
+
throw new FerricStoreError("native protocol map key must be valid UTF-8");
|
|
4981
|
+
}
|
|
4982
|
+
const key = typeof encodedKey === "string" ? encodedKey : encodedKey.toString("utf8");
|
|
4983
|
+
if (Object.hasOwn(target, key)) {
|
|
4984
|
+
throw new FerricStoreError(`native protocol response contains duplicate map key ${JSON.stringify(key)}`);
|
|
4985
|
+
}
|
|
4986
|
+
setOwnValue2(target, key, value);
|
|
4729
4987
|
}
|
|
4730
4988
|
|
|
4731
4989
|
// src/protocol-value.ts
|
|
4732
|
-
var import_node_buffer14 = require("buffer");
|
|
4733
4990
|
function planValueWithLimit(value, maxBytes) {
|
|
4734
4991
|
const budget = {
|
|
4735
4992
|
maxBytes,
|
|
@@ -4784,7 +5041,7 @@ function planContainerValue(value, budget, ancestors, depth) {
|
|
|
4784
5041
|
let byteLength = 5;
|
|
4785
5042
|
let index = 0;
|
|
4786
5043
|
for (const [key, item] of entries) {
|
|
4787
|
-
const keyByteLength =
|
|
5044
|
+
const keyByteLength = import_node_buffer17.Buffer.byteLength(key);
|
|
4788
5045
|
consumeEncodeBytes(budget, 4 + keyByteLength);
|
|
4789
5046
|
const valuePlan = planValueAt(item, budget, ancestors, depth + 1);
|
|
4790
5047
|
entryPlans[index] = { key, keyByteLength, value: valuePlan };
|
|
@@ -4823,17 +5080,21 @@ function planScalarValue(value, budget) {
|
|
|
4823
5080
|
return { byteLength: 9, tag: 3, value: BigInt(value) };
|
|
4824
5081
|
}
|
|
4825
5082
|
if (typeof value === "bigint") {
|
|
4826
|
-
if (value
|
|
4827
|
-
|
|
5083
|
+
if (value >= MIN_I642 && value <= MAX_I642) {
|
|
5084
|
+
consumeEncodeBytes(budget, 9);
|
|
5085
|
+
return { byteLength: 9, tag: 3, value };
|
|
4828
5086
|
}
|
|
4829
|
-
|
|
4830
|
-
|
|
5087
|
+
if (value > MAX_I642 && value <= MAX_U64) {
|
|
5088
|
+
consumeEncodeBytes(budget, 9);
|
|
5089
|
+
return { byteLength: 9, tag: 8, value };
|
|
5090
|
+
}
|
|
5091
|
+
throw new FerricStoreError("integer exceeds the signed or unsigned 64-bit native range");
|
|
4831
5092
|
}
|
|
4832
5093
|
if (typeof value === "number") {
|
|
4833
5094
|
consumeEncodeBytes(budget, 9);
|
|
4834
5095
|
return { byteLength: 9, tag: 7, value };
|
|
4835
5096
|
}
|
|
4836
|
-
if (typeof value === "string" ||
|
|
5097
|
+
if (typeof value === "string" || import_node_buffer17.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
4837
5098
|
const valueByteLength = binaryValueByteLength(value);
|
|
4838
5099
|
const byteLength = 5 + valueByteLength;
|
|
4839
5100
|
consumeEncodeBytes(budget, byteLength);
|
|
@@ -4857,7 +5118,7 @@ function writeValuePlan(output, start, plan) {
|
|
|
4857
5118
|
offset += 4;
|
|
4858
5119
|
if (typeof plan.value === "string") {
|
|
4859
5120
|
output.write(plan.value, offset, plan.valueByteLength, "utf8");
|
|
4860
|
-
} else if (
|
|
5121
|
+
} else if (import_node_buffer17.Buffer.isBuffer(plan.value)) {
|
|
4861
5122
|
plan.value.copy(output, offset);
|
|
4862
5123
|
} else {
|
|
4863
5124
|
output.set(plan.value, offset);
|
|
@@ -4882,6 +5143,9 @@ function writeValuePlan(output, start, plan) {
|
|
|
4882
5143
|
case 7:
|
|
4883
5144
|
output.writeDoubleBE(plan.value, offset);
|
|
4884
5145
|
return offset + 8;
|
|
5146
|
+
case 8:
|
|
5147
|
+
output.writeBigUInt64BE(plan.value, offset);
|
|
5148
|
+
return offset + 8;
|
|
4885
5149
|
}
|
|
4886
5150
|
}
|
|
4887
5151
|
function consumeEncodeBytes(budget, bytes2) {
|
|
@@ -4939,7 +5203,7 @@ function decodeValueAt(data, offset, limits, budget, depth) {
|
|
|
4939
5203
|
const key = readBinary(data, offset);
|
|
4940
5204
|
offset = key.offset;
|
|
4941
5205
|
const item = decodeValueAt(data, offset, limits, budget, depth + 1);
|
|
4942
|
-
|
|
5206
|
+
setProtocolMapEntry(value, key.value, item.value);
|
|
4943
5207
|
offset = item.offset;
|
|
4944
5208
|
}
|
|
4945
5209
|
return { value, offset };
|
|
@@ -4948,6 +5212,14 @@ function decodeValueAt(data, offset, limits, budget, depth) {
|
|
|
4948
5212
|
requireAvailable(data, offset, 8);
|
|
4949
5213
|
return { value: data.readDoubleBE(offset), offset: offset + 8 };
|
|
4950
5214
|
}
|
|
5215
|
+
if (tag === 8) {
|
|
5216
|
+
requireAvailable(data, offset, 8);
|
|
5217
|
+
const integer2 = data.readBigUInt64BE(offset);
|
|
5218
|
+
return {
|
|
5219
|
+
value: integer2 <= MAX_SAFE_INTEGER_BIGINT ? Number(integer2) : integer2,
|
|
5220
|
+
offset: offset + 8
|
|
5221
|
+
};
|
|
5222
|
+
}
|
|
4951
5223
|
throw new FerricStoreError(`unknown protocol value tag ${tag}`);
|
|
4952
5224
|
}
|
|
4953
5225
|
function decodeValueWithBudget(data, offset, budget) {
|
|
@@ -4991,20 +5263,20 @@ function requireAvailable(data, offset, size) {
|
|
|
4991
5263
|
}
|
|
4992
5264
|
|
|
4993
5265
|
// src/key-slot-validation.ts
|
|
4994
|
-
var
|
|
5266
|
+
var import_node_buffer19 = require("buffer");
|
|
4995
5267
|
|
|
4996
5268
|
// src/topology-utilities.ts
|
|
4997
|
-
var
|
|
5269
|
+
var import_node_buffer18 = require("buffer");
|
|
4998
5270
|
function isPlainObject3(value) {
|
|
4999
|
-
return typeof value === "object" && value != null && !Array.isArray(value) && !
|
|
5271
|
+
return typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer18.Buffer.isBuffer(value);
|
|
5000
5272
|
}
|
|
5001
5273
|
function getField(source, ...keys) {
|
|
5002
5274
|
if (source instanceof Map) {
|
|
5003
5275
|
for (const key of keys) {
|
|
5004
5276
|
if (source.has(key)) return source.get(key);
|
|
5005
|
-
const bufferKey =
|
|
5277
|
+
const bufferKey = import_node_buffer18.Buffer.from(key);
|
|
5006
5278
|
for (const [itemKey, value] of source.entries()) {
|
|
5007
|
-
if (
|
|
5279
|
+
if (import_node_buffer18.Buffer.isBuffer(itemKey) && itemKey.equals(bufferKey)) return value;
|
|
5008
5280
|
}
|
|
5009
5281
|
}
|
|
5010
5282
|
return void 0;
|
|
@@ -5018,14 +5290,14 @@ function getField(source, ...keys) {
|
|
|
5018
5290
|
}
|
|
5019
5291
|
function textOrUndefined(value) {
|
|
5020
5292
|
if (typeof value === "string") return value;
|
|
5021
|
-
if (
|
|
5293
|
+
if (import_node_buffer18.Buffer.isBuffer(value)) return value.toString("utf8");
|
|
5022
5294
|
return void 0;
|
|
5023
5295
|
}
|
|
5024
5296
|
function numberOrUndefined(value) {
|
|
5025
5297
|
return typeof value === "number" && Number.isSafeInteger(value) ? value : void 0;
|
|
5026
5298
|
}
|
|
5027
|
-
function nativeEventName(
|
|
5028
|
-
return textOrUndefined(getField(
|
|
5299
|
+
function nativeEventName(event2) {
|
|
5300
|
+
return textOrUndefined(getField(event2.value, "event"))?.toUpperCase();
|
|
5029
5301
|
}
|
|
5030
5302
|
function endpointFromRange(item) {
|
|
5031
5303
|
const endpointValue = getField(item, "endpoint");
|
|
@@ -5193,7 +5465,7 @@ function stringHashRange(key) {
|
|
|
5193
5465
|
var validatedCommands = /* @__PURE__ */ new WeakSet();
|
|
5194
5466
|
function assertAtomicKeyValueCommandSharesSlot(args) {
|
|
5195
5467
|
const value = args[0];
|
|
5196
|
-
const command = (typeof value === "string" ? value :
|
|
5468
|
+
const command = (typeof value === "string" ? value : import_node_buffer19.Buffer.isBuffer(value) ? value.toString("utf8") : "").toUpperCase();
|
|
5197
5469
|
if (command === "MSET" || command === "MSETNX") {
|
|
5198
5470
|
assertKeyValueCommandSharesSlot(args, command);
|
|
5199
5471
|
}
|
|
@@ -5203,7 +5475,7 @@ function assertKeyValueCommandSharesSlot(args, command) {
|
|
|
5203
5475
|
let expectedSlot;
|
|
5204
5476
|
for (let index = 1; index < args.length; index += 2) {
|
|
5205
5477
|
const key = args[index];
|
|
5206
|
-
if (typeof key !== "string" && !
|
|
5478
|
+
if (typeof key !== "string" && !import_node_buffer19.Buffer.isBuffer(key)) return;
|
|
5207
5479
|
const slot = routingSlotForKey(key);
|
|
5208
5480
|
expectedSlot ??= slot;
|
|
5209
5481
|
if (slot !== expectedSlot) {
|
|
@@ -5214,62 +5486,202 @@ function assertKeyValueCommandSharesSlot(args, command) {
|
|
|
5214
5486
|
}
|
|
5215
5487
|
|
|
5216
5488
|
// src/protocol-response.ts
|
|
5217
|
-
var
|
|
5489
|
+
var import_node_buffer26 = require("buffer");
|
|
5218
5490
|
|
|
5219
5491
|
// src/protocol-compact-response.ts
|
|
5220
|
-
var
|
|
5492
|
+
var import_node_buffer25 = require("buffer");
|
|
5221
5493
|
|
|
5222
5494
|
// src/native-negotiation.ts
|
|
5223
|
-
var
|
|
5495
|
+
var import_node_buffer20 = require("buffer");
|
|
5224
5496
|
var EMPTY_COMPACT_RESPONSE_OPCODES = /* @__PURE__ */ new Map();
|
|
5225
5497
|
function nativeNegotiation(value) {
|
|
5226
5498
|
const capabilities = field(value, "capabilities") ?? value;
|
|
5227
5499
|
const limits = field(capabilities, "limits");
|
|
5228
|
-
const
|
|
5500
|
+
const rawResponseCodecs = field(capabilities, "response_codecs");
|
|
5501
|
+
const responseCodecs = rawResponseCodecs == null ? void 0 : requiredMap(rawResponseCodecs, "HELLO response_codecs");
|
|
5502
|
+
const schemas = requiredMap(field(capabilities, "schemas"), "HELLO schemas");
|
|
5229
5503
|
const maxResponseBytes = positiveSafeInteger3(field(limits, "max_response_bytes"));
|
|
5230
5504
|
return {
|
|
5231
5505
|
compactResponseOpcodes: parseCompactResponseOpcodes(
|
|
5232
5506
|
field(responseCodecs, "compact_response_opcodes")
|
|
5233
5507
|
),
|
|
5508
|
+
flowQuery: parseFlowQueryNegotiation(capabilities, schemas),
|
|
5234
5509
|
...maxResponseBytes == null ? {} : { maxResponseBytes }
|
|
5235
5510
|
};
|
|
5236
5511
|
}
|
|
5512
|
+
var REQUIRED_FLOW_QUERY_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
5513
|
+
"flow_query_v1",
|
|
5514
|
+
"flow_query_result_projection_v1",
|
|
5515
|
+
"flow_explain_v1",
|
|
5516
|
+
"flow_explain_analyze_v1",
|
|
5517
|
+
"flow_composite_index_v1",
|
|
5518
|
+
"flow_query_index_status_v1"
|
|
5519
|
+
]);
|
|
5520
|
+
var REQUIRED_FLOW_QUERY_SHAPES = /* @__PURE__ */ new Set([
|
|
5521
|
+
"runs_by_run_id_record",
|
|
5522
|
+
"runs_by_partition_and_run_id_record",
|
|
5523
|
+
"runs_by_partition_predicates_ordered_records",
|
|
5524
|
+
"runs_by_partition_type_state_ordered_records",
|
|
5525
|
+
"runs_by_partition_type_terminals_ordered_records",
|
|
5526
|
+
"runs_by_partition_metadata_ordered_records",
|
|
5527
|
+
"runs_by_partition_type_running_lease_deadline_ordered_records",
|
|
5528
|
+
"runs_by_partition_parent_ordered_records",
|
|
5529
|
+
"runs_by_partition_root_ordered_records",
|
|
5530
|
+
"runs_by_partition_correlation_ordered_records",
|
|
5531
|
+
"runs_by_partition_predicates_count",
|
|
5532
|
+
"events_by_run_id_ordered_records"
|
|
5533
|
+
]);
|
|
5534
|
+
function parseFlowQueryNegotiation(capabilities, schemas) {
|
|
5535
|
+
const manifest = requiredMap(field(capabilities, "flow_query"), "HELLO flow_query");
|
|
5536
|
+
const requestContract = requiredBoundedText(manifest, "request_contract");
|
|
5537
|
+
const resultContract = requiredBoundedText(manifest, "result_contract");
|
|
5538
|
+
const explainContract = requiredBoundedText(manifest, "explain_contract");
|
|
5539
|
+
const indexStatusContract = requiredBoundedText(manifest, "index_status_contract");
|
|
5540
|
+
requireEqual(requestContract, "ferric.flow.query.request/v1", "flow_query request_contract");
|
|
5541
|
+
requireEqual(resultContract, "ferric.flow.query.result/v1", "flow_query result_contract");
|
|
5542
|
+
requireEqual(explainContract, "ferric.flow.explain/v1", "flow_query explain_contract");
|
|
5543
|
+
requireEqual(
|
|
5544
|
+
indexStatusContract,
|
|
5545
|
+
"ferric.flow.query.indexes/v1",
|
|
5546
|
+
"flow_query index_status_contract"
|
|
5547
|
+
);
|
|
5548
|
+
const queryCapabilities = boundedTextSet(manifest, "capabilities", 64);
|
|
5549
|
+
const languageVersions = boundedTextSet(manifest, "language_versions", 16);
|
|
5550
|
+
const shapes = boundedTextSet(manifest, "shapes", 128);
|
|
5551
|
+
requireMembers(queryCapabilities, REQUIRED_FLOW_QUERY_CAPABILITIES, "flow_query capability");
|
|
5552
|
+
requireMembers(languageVersions, /* @__PURE__ */ new Set(["FQL1"]), "flow_query language");
|
|
5553
|
+
requireMembers(shapes, REQUIRED_FLOW_QUERY_SHAPES, "flow_query shape");
|
|
5554
|
+
const schema = requiredMap(field(schemas, "FLOW.QUERY"), "HELLO FLOW.QUERY schema");
|
|
5555
|
+
const fields = boundedTextSet(schema, "fields", 64);
|
|
5556
|
+
requireMembers(
|
|
5557
|
+
fields,
|
|
5558
|
+
/* @__PURE__ */ new Set(["version", "query", "params", "deadline_ms"]),
|
|
5559
|
+
"FLOW.QUERY schema field"
|
|
5560
|
+
);
|
|
5561
|
+
const required = boundedTextSet(schema, "required", 16);
|
|
5562
|
+
if (required.size !== 2 || !required.has("version") || !required.has("query")) {
|
|
5563
|
+
throw incompatibleServer("FLOW.QUERY schema must require exactly version and query");
|
|
5564
|
+
}
|
|
5565
|
+
return {
|
|
5566
|
+
requestContract: "ferric.flow.query.request/v1",
|
|
5567
|
+
resultContract: "ferric.flow.query.result/v1",
|
|
5568
|
+
explainContract: "ferric.flow.explain/v1",
|
|
5569
|
+
indexStatusContract: "ferric.flow.query.indexes/v1",
|
|
5570
|
+
capabilities: queryCapabilities,
|
|
5571
|
+
languageVersions,
|
|
5572
|
+
shapes
|
|
5573
|
+
};
|
|
5574
|
+
}
|
|
5575
|
+
function requiredMap(value, context) {
|
|
5576
|
+
if (value instanceof Map) return value;
|
|
5577
|
+
if (typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer20.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
5578
|
+
return value;
|
|
5579
|
+
}
|
|
5580
|
+
throw incompatibleServer(`${context} is missing or invalid`);
|
|
5581
|
+
}
|
|
5582
|
+
function requiredBoundedText(mapping, name) {
|
|
5583
|
+
const value = strictText(field(mapping, name));
|
|
5584
|
+
if (value == null || value.length === 0 || import_node_buffer20.Buffer.byteLength(value) > 256) {
|
|
5585
|
+
throw incompatibleServer(`HELLO flow_query ${name} must be bounded non-empty text`);
|
|
5586
|
+
}
|
|
5587
|
+
return value;
|
|
5588
|
+
}
|
|
5589
|
+
function boundedTextSet(mapping, name, maximum) {
|
|
5590
|
+
const raw = field(mapping, name);
|
|
5591
|
+
if (!Array.isArray(raw) || raw.length < 1 || raw.length > maximum) {
|
|
5592
|
+
throw incompatibleServer(`HELLO ${name} must contain 1..${maximum} entries`);
|
|
5593
|
+
}
|
|
5594
|
+
const result = /* @__PURE__ */ new Set();
|
|
5595
|
+
for (let index = 0; index < raw.length; index += 1) {
|
|
5596
|
+
if (!Object.hasOwn(raw, index)) throw incompatibleServer(`HELLO ${name} must be dense`);
|
|
5597
|
+
const item = strictText(raw[index]);
|
|
5598
|
+
if (item == null || item.length === 0 || import_node_buffer20.Buffer.byteLength(item) > 256) {
|
|
5599
|
+
throw incompatibleServer(`HELLO ${name} contains invalid text`);
|
|
5600
|
+
}
|
|
5601
|
+
if (result.has(item)) throw incompatibleServer(`HELLO ${name} contains duplicate ${item}`);
|
|
5602
|
+
result.add(item);
|
|
5603
|
+
}
|
|
5604
|
+
return result;
|
|
5605
|
+
}
|
|
5606
|
+
function requireMembers(actual, required, context) {
|
|
5607
|
+
for (const item of required) {
|
|
5608
|
+
if (!actual.has(item)) throw incompatibleServer(`missing ${context} ${JSON.stringify(item)}`);
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
function requireEqual(actual, expected, context) {
|
|
5612
|
+
if (actual !== expected) throw incompatibleServer(`${context} must be ${JSON.stringify(expected)}`);
|
|
5613
|
+
}
|
|
5614
|
+
function strictText(value) {
|
|
5615
|
+
if (typeof value === "string") return value;
|
|
5616
|
+
if (import_node_buffer20.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
5617
|
+
try {
|
|
5618
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
5619
|
+
} catch {
|
|
5620
|
+
return void 0;
|
|
5621
|
+
}
|
|
5622
|
+
}
|
|
5623
|
+
return void 0;
|
|
5624
|
+
}
|
|
5625
|
+
function incompatibleServer(message) {
|
|
5626
|
+
return new FerricStoreError(`incompatible FerricStore server: ${message}`);
|
|
5627
|
+
}
|
|
5237
5628
|
function compactResponseOpcodeSupports(capabilities, codec, opcode) {
|
|
5238
5629
|
return capabilities?.get(codec)?.has(opcode) === true;
|
|
5239
5630
|
}
|
|
5240
5631
|
function parseCompactResponseOpcodes(value) {
|
|
5632
|
+
if (value == null) return EMPTY_COMPACT_RESPONSE_OPCODES;
|
|
5241
5633
|
const entries = mapEntries(value);
|
|
5242
|
-
if (entries == null)
|
|
5634
|
+
if (entries == null) {
|
|
5635
|
+
throw incompatibleServer("HELLO compact_response_opcodes must be a map");
|
|
5636
|
+
}
|
|
5637
|
+
if (entries.length > 32) {
|
|
5638
|
+
throw incompatibleServer("HELLO compact_response_opcodes supports at most 32 codecs");
|
|
5639
|
+
}
|
|
5243
5640
|
const result = /* @__PURE__ */ new Map();
|
|
5641
|
+
let totalOpcodes = 0;
|
|
5244
5642
|
for (const [rawName, rawOpcodes] of entries) {
|
|
5245
|
-
const name =
|
|
5246
|
-
if (name == null || name.length === 0 ||
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5643
|
+
const name = strictText(rawName);
|
|
5644
|
+
if (name == null || name.length === 0 || import_node_buffer20.Buffer.byteLength(name) > 128) {
|
|
5645
|
+
throw incompatibleServer("HELLO compact_response_opcodes contains an invalid codec name");
|
|
5646
|
+
}
|
|
5647
|
+
if (result.has(name)) {
|
|
5648
|
+
throw incompatibleServer(`HELLO compact_response_opcodes contains duplicate codec ${name}`);
|
|
5649
|
+
}
|
|
5650
|
+
if (!Array.isArray(rawOpcodes)) {
|
|
5651
|
+
throw incompatibleServer(`HELLO compact_response_opcodes codec ${name} must be an array`);
|
|
5652
|
+
}
|
|
5653
|
+
totalOpcodes += rawOpcodes.length;
|
|
5654
|
+
if (totalOpcodes > 1024) {
|
|
5655
|
+
throw incompatibleServer("HELLO compact_response_opcodes supports at most 1024 opcodes");
|
|
5656
|
+
}
|
|
5657
|
+
const opcodes = /* @__PURE__ */ new Set();
|
|
5658
|
+
for (let index = 0; index < rawOpcodes.length; index += 1) {
|
|
5250
5659
|
if (!Object.hasOwn(rawOpcodes, index)) {
|
|
5251
|
-
|
|
5252
|
-
break;
|
|
5660
|
+
throw incompatibleServer(`HELLO compact_response_opcodes codec ${name} must be dense`);
|
|
5253
5661
|
}
|
|
5254
|
-
const opcode =
|
|
5662
|
+
const opcode = strictUnsigned16(rawOpcodes[index]);
|
|
5255
5663
|
if (opcode == null) {
|
|
5256
|
-
|
|
5257
|
-
|
|
5664
|
+
throw incompatibleServer(`HELLO compact_response_opcodes codec ${name} has invalid opcode`);
|
|
5665
|
+
}
|
|
5666
|
+
if (opcodes.has(opcode)) {
|
|
5667
|
+
throw incompatibleServer(`HELLO compact_response_opcodes codec ${name} has duplicate opcode`);
|
|
5258
5668
|
}
|
|
5259
5669
|
opcodes.add(opcode);
|
|
5260
5670
|
}
|
|
5261
|
-
|
|
5671
|
+
result.set(name, opcodes);
|
|
5262
5672
|
}
|
|
5263
5673
|
return result;
|
|
5264
5674
|
}
|
|
5265
5675
|
function mapEntries(value) {
|
|
5266
5676
|
if (value instanceof Map) return [...value.entries()];
|
|
5267
|
-
if (typeof value !== "object" || value == null || Array.isArray(value)) return void 0;
|
|
5677
|
+
if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer20.Buffer.isBuffer(value) || value instanceof Uint8Array) return void 0;
|
|
5268
5678
|
return Object.entries(value);
|
|
5269
5679
|
}
|
|
5270
|
-
function
|
|
5271
|
-
|
|
5272
|
-
|
|
5680
|
+
function strictUnsigned16(value) {
|
|
5681
|
+
if (typeof value === "bigint") {
|
|
5682
|
+
return value >= 0n && value <= 0xffffn ? Number(value) : void 0;
|
|
5683
|
+
}
|
|
5684
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 65535 ? value : void 0;
|
|
5273
5685
|
}
|
|
5274
5686
|
function positiveSafeInteger3(value) {
|
|
5275
5687
|
const parsed = nonNegativeSafeInteger2(value);
|
|
@@ -5288,14 +5700,14 @@ function nonNegativeSafeInteger2(value) {
|
|
|
5288
5700
|
}
|
|
5289
5701
|
function text2(value) {
|
|
5290
5702
|
if (typeof value === "string") return value;
|
|
5291
|
-
if (
|
|
5292
|
-
return
|
|
5703
|
+
if (import_node_buffer20.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
5704
|
+
return import_node_buffer20.Buffer.from(value).toString("utf8");
|
|
5293
5705
|
}
|
|
5294
5706
|
return void 0;
|
|
5295
5707
|
}
|
|
5296
5708
|
|
|
5297
5709
|
// src/protocol-compact-collections.ts
|
|
5298
|
-
var
|
|
5710
|
+
var import_node_buffer21 = require("buffer");
|
|
5299
5711
|
function decodeCompactIntegerList(data, budget) {
|
|
5300
5712
|
requireAvailable(data, 0, 5);
|
|
5301
5713
|
const count = data.readUInt32BE(1);
|
|
@@ -5360,7 +5772,7 @@ function readCompactBinaryMap(data, offset, budget) {
|
|
|
5360
5772
|
for (let index = 0; index < count; index += 1) {
|
|
5361
5773
|
const key = readBinary(data, offset);
|
|
5362
5774
|
const value = readBinary(data, key.offset);
|
|
5363
|
-
|
|
5775
|
+
setProtocolMapEntry(values, key.value, value.value);
|
|
5364
5776
|
offset = value.offset;
|
|
5365
5777
|
}
|
|
5366
5778
|
return { value: values, offset };
|
|
@@ -5376,11 +5788,246 @@ function requireCompactContainer(count, budget) {
|
|
|
5376
5788
|
consumeDecodeItems(count, budget);
|
|
5377
5789
|
}
|
|
5378
5790
|
|
|
5791
|
+
// src/protocol-error-message.ts
|
|
5792
|
+
var import_node_buffer22 = require("buffer");
|
|
5793
|
+
var MAX_ERROR_MESSAGE_CHARS = 4096;
|
|
5794
|
+
var MAX_ERROR_TEXT_BYTES = MAX_ERROR_MESSAGE_CHARS * 4;
|
|
5795
|
+
function protocolErrorMessage(status, value) {
|
|
5796
|
+
const direct = errorText(value);
|
|
5797
|
+
if (direct != null) return truncate(direct);
|
|
5798
|
+
return truncate(`ERR native request failed status=${status}: ${errorDescription(value)}`);
|
|
5799
|
+
}
|
|
5800
|
+
function errorText(value) {
|
|
5801
|
+
if (typeof value === "string") return value;
|
|
5802
|
+
if (import_node_buffer22.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
5803
|
+
return boundedBinaryText(value);
|
|
5804
|
+
}
|
|
5805
|
+
if (typeof value === "object" && value != null && Object.hasOwn(value, "message")) {
|
|
5806
|
+
const message = value.message;
|
|
5807
|
+
if (typeof message === "string") return message;
|
|
5808
|
+
if (import_node_buffer22.Buffer.isBuffer(message) || message instanceof Uint8Array) {
|
|
5809
|
+
return boundedBinaryText(message);
|
|
5810
|
+
}
|
|
5811
|
+
if (message == null || typeof message !== "object") return String(message);
|
|
5812
|
+
}
|
|
5813
|
+
return void 0;
|
|
5814
|
+
}
|
|
5815
|
+
function boundedBinaryText(value) {
|
|
5816
|
+
const bytes2 = import_node_buffer22.Buffer.isBuffer(value) ? value : import_node_buffer22.Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
5817
|
+
return bytes2.subarray(0, MAX_ERROR_TEXT_BYTES).toString("utf8");
|
|
5818
|
+
}
|
|
5819
|
+
function errorDescription(value) {
|
|
5820
|
+
if (Array.isArray(value)) return `[array length=${value.length}]`;
|
|
5821
|
+
if (value instanceof Map) return `[map size=${value.size}]`;
|
|
5822
|
+
if (typeof value === "object" && value != null) return "[object]";
|
|
5823
|
+
return String(value);
|
|
5824
|
+
}
|
|
5825
|
+
function truncate(value) {
|
|
5826
|
+
return value.length <= MAX_ERROR_MESSAGE_CHARS ? value : `${value.slice(0, MAX_ERROR_MESSAGE_CHARS - 1)}\u2026`;
|
|
5827
|
+
}
|
|
5828
|
+
|
|
5829
|
+
// src/protocol-flow-query-result.ts
|
|
5830
|
+
var import_node_buffer24 = require("buffer");
|
|
5831
|
+
|
|
5832
|
+
// src/protocol-binary-detacher.ts
|
|
5833
|
+
var import_node_buffer23 = require("buffer");
|
|
5834
|
+
var MIN_PINNED_BACKING_BYTES = 64;
|
|
5835
|
+
function detachDecodedBinary(value, backingBytes) {
|
|
5836
|
+
if (import_node_buffer23.Buffer.isBuffer(value)) return detachBuffer(value, backingBytes);
|
|
5837
|
+
if (Array.isArray(value)) {
|
|
5838
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
5839
|
+
value[index] = detachDecodedBinary(value[index], backingBytes);
|
|
5840
|
+
}
|
|
5841
|
+
return value;
|
|
5842
|
+
}
|
|
5843
|
+
if (!isDecodedRecord(value)) return value;
|
|
5844
|
+
for (const key of Object.keys(value)) {
|
|
5845
|
+
setOwnValue2(value, key, detachDecodedBinary(value[key], backingBytes));
|
|
5846
|
+
}
|
|
5847
|
+
return value;
|
|
5848
|
+
}
|
|
5849
|
+
function detachBuffer(value, backingBytes) {
|
|
5850
|
+
if (backingBytes <= Math.max(MIN_PINNED_BACKING_BYTES, value.byteLength * 2)) {
|
|
5851
|
+
return value;
|
|
5852
|
+
}
|
|
5853
|
+
if (value.byteLength === 0) return import_node_buffer23.Buffer.alloc(0);
|
|
5854
|
+
const detached = import_node_buffer23.Buffer.allocUnsafeSlow(value.byteLength);
|
|
5855
|
+
value.copy(detached);
|
|
5856
|
+
return detached;
|
|
5857
|
+
}
|
|
5858
|
+
function isDecodedRecord(value) {
|
|
5859
|
+
if (typeof value !== "object" || value == null) return false;
|
|
5860
|
+
const prototype = Object.getPrototypeOf(value);
|
|
5861
|
+
return prototype === Object.prototype || prototype === null;
|
|
5862
|
+
}
|
|
5863
|
+
|
|
5864
|
+
// src/protocol-flow-query-result.ts
|
|
5865
|
+
var CONTRACT = "ferric.flow.query.result/v1";
|
|
5866
|
+
var MAX_RECORDS = 100;
|
|
5867
|
+
var MAX_CURSOR_BYTES = 4096;
|
|
5868
|
+
var RECORD_FIELDS = [
|
|
5869
|
+
"id",
|
|
5870
|
+
"type",
|
|
5871
|
+
"state",
|
|
5872
|
+
"version",
|
|
5873
|
+
"priority",
|
|
5874
|
+
"partition_key",
|
|
5875
|
+
"created_at_ms",
|
|
5876
|
+
"updated_at_ms",
|
|
5877
|
+
"next_run_at_ms",
|
|
5878
|
+
"lease_deadline_ms",
|
|
5879
|
+
"attempts",
|
|
5880
|
+
"run_state",
|
|
5881
|
+
"max_active_ms",
|
|
5882
|
+
"parent_flow_id",
|
|
5883
|
+
"root_flow_id",
|
|
5884
|
+
"correlation_id",
|
|
5885
|
+
"attributes",
|
|
5886
|
+
"state_meta",
|
|
5887
|
+
"event_id",
|
|
5888
|
+
"fields"
|
|
5889
|
+
];
|
|
5890
|
+
var RECORD_FIELD_MASK = (1 << RECORD_FIELDS.length) - 1;
|
|
5891
|
+
var QUALITY_VALUES = [
|
|
5892
|
+
["authoritative", "projected_exact", "exact", "not_applicable"],
|
|
5893
|
+
["current", "projection_watermark", "not_applicable"],
|
|
5894
|
+
["complete", "unavailable"],
|
|
5895
|
+
["none", "complete", "authenticated_seek", "live_seek"]
|
|
5896
|
+
];
|
|
5897
|
+
var QUALITY_FIELDS = ["exactness", "freshness", "coverage", "pagination"];
|
|
5898
|
+
var USAGE_FIELDS = [
|
|
5899
|
+
"range_seeks",
|
|
5900
|
+
"range_pages",
|
|
5901
|
+
"scanned_entries",
|
|
5902
|
+
"scanned_bytes",
|
|
5903
|
+
"hydrated_records",
|
|
5904
|
+
"residual_checks",
|
|
5905
|
+
"duplicate_entries",
|
|
5906
|
+
"result_records",
|
|
5907
|
+
"response_bytes",
|
|
5908
|
+
"memory_high_water_bytes",
|
|
5909
|
+
"wall_time_us"
|
|
5910
|
+
];
|
|
5911
|
+
function decodeCompactFlowQueryResult(data, budget) {
|
|
5912
|
+
requireAvailable(data, 0, 2 + QUALITY_FIELDS.length + USAGE_FIELDS.length * 8);
|
|
5913
|
+
if (data.readUInt8(0) !== COMPACT_FLOW_QUERY_RESULT) {
|
|
5914
|
+
throw new FerricStoreError("expected compact FLOW.QUERY result");
|
|
5915
|
+
}
|
|
5916
|
+
const kind = data.readUInt8(1);
|
|
5917
|
+
let offset = 2;
|
|
5918
|
+
const quality = {};
|
|
5919
|
+
for (let index = 0; index < QUALITY_FIELDS.length; index += 1) {
|
|
5920
|
+
const field3 = QUALITY_FIELDS[index];
|
|
5921
|
+
const values = QUALITY_VALUES[index];
|
|
5922
|
+
if (field3 == null || values == null) throw new FerricStoreError("invalid compact FLOW.QUERY quality schema");
|
|
5923
|
+
const value = values[data.readUInt8(offset)];
|
|
5924
|
+
if (value == null) throw new FerricStoreError("invalid compact FLOW.QUERY quality code");
|
|
5925
|
+
quality[field3] = import_node_buffer24.Buffer.from(value);
|
|
5926
|
+
offset += 1;
|
|
5927
|
+
}
|
|
5928
|
+
const usage = {};
|
|
5929
|
+
for (const field3 of USAGE_FIELDS) {
|
|
5930
|
+
const read = readU64(data, offset);
|
|
5931
|
+
usage[field3] = read.value;
|
|
5932
|
+
offset = read.offset;
|
|
5933
|
+
}
|
|
5934
|
+
let result;
|
|
5935
|
+
if (kind === 0) {
|
|
5936
|
+
const page = readPage(data, offset);
|
|
5937
|
+
offset = page.offset;
|
|
5938
|
+
requireAvailable(data, offset, 4);
|
|
5939
|
+
const count = data.readUInt32BE(offset);
|
|
5940
|
+
offset += 4;
|
|
5941
|
+
if (count > MAX_RECORDS) throw new FerricStoreError("compact FLOW.QUERY page exceeds 100 records");
|
|
5942
|
+
consumeDecodeItems(count, budget);
|
|
5943
|
+
const records = new Array(count);
|
|
5944
|
+
for (let index = 0; index < count; index += 1) {
|
|
5945
|
+
const read = readRecord(data, offset, budget);
|
|
5946
|
+
records[index] = read.value;
|
|
5947
|
+
offset = read.offset;
|
|
5948
|
+
}
|
|
5949
|
+
result = { version: import_node_buffer24.Buffer.from(CONTRACT), records, page: page.value, quality, usage };
|
|
5950
|
+
} else if (kind === 1) {
|
|
5951
|
+
const count = readU64(data, offset);
|
|
5952
|
+
offset = count.offset;
|
|
5953
|
+
result = {
|
|
5954
|
+
version: import_node_buffer24.Buffer.from(CONTRACT),
|
|
5955
|
+
result: { kind: import_node_buffer24.Buffer.from("count"), value: count.value },
|
|
5956
|
+
quality,
|
|
5957
|
+
usage
|
|
5958
|
+
};
|
|
5959
|
+
} else {
|
|
5960
|
+
throw new FerricStoreError(`unsupported compact FLOW.QUERY result kind ${kind}`);
|
|
5961
|
+
}
|
|
5962
|
+
if (offset !== data.byteLength) throw new FerricStoreError("trailing compact FLOW.QUERY result bytes");
|
|
5963
|
+
if (BigInt(usage.response_bytes) !== BigInt(data.byteLength)) {
|
|
5964
|
+
throw new FerricStoreError("compact FLOW.QUERY response_bytes does not match its payload");
|
|
5965
|
+
}
|
|
5966
|
+
return result;
|
|
5967
|
+
}
|
|
5968
|
+
function readPage(data, offset) {
|
|
5969
|
+
requireAvailable(data, offset, 5);
|
|
5970
|
+
const hasMoreCode = data.readUInt8(offset);
|
|
5971
|
+
const size = data.readUInt32BE(offset + 1);
|
|
5972
|
+
offset += 5;
|
|
5973
|
+
if (hasMoreCode === 0 && size === NULL_U32) {
|
|
5974
|
+
return { value: { has_more: false, cursor: null }, offset };
|
|
5975
|
+
}
|
|
5976
|
+
if (hasMoreCode !== 1 || size === 0 || size === NULL_U32 || size > MAX_CURSOR_BYTES) {
|
|
5977
|
+
throw new FerricStoreError("invalid compact FLOW.QUERY page cursor");
|
|
5978
|
+
}
|
|
5979
|
+
requireAvailable(data, offset, size);
|
|
5980
|
+
return {
|
|
5981
|
+
value: {
|
|
5982
|
+
has_more: true,
|
|
5983
|
+
cursor: detachDecodedBinary(data.subarray(offset, offset + size), data.byteLength)
|
|
5984
|
+
},
|
|
5985
|
+
offset: offset + size
|
|
5986
|
+
};
|
|
5987
|
+
}
|
|
5988
|
+
function readRecord(data, offset, budget) {
|
|
5989
|
+
requireAvailable(data, offset, 4);
|
|
5990
|
+
const bitmap = data.readUInt32BE(offset);
|
|
5991
|
+
offset += 4;
|
|
5992
|
+
if ((bitmap & ~RECORD_FIELD_MASK) !== 0) {
|
|
5993
|
+
throw new FerricStoreError("compact FLOW.QUERY record contains reserved fields");
|
|
5994
|
+
}
|
|
5995
|
+
consumeDecodeItems(populationCount(bitmap), budget);
|
|
5996
|
+
const record = {};
|
|
5997
|
+
for (let index = 0; index < RECORD_FIELDS.length; index += 1) {
|
|
5998
|
+
if ((bitmap & 1 << index) === 0) continue;
|
|
5999
|
+
const field3 = RECORD_FIELDS[index];
|
|
6000
|
+
if (field3 == null) throw new FerricStoreError("invalid compact FLOW.QUERY record schema");
|
|
6001
|
+
const read = decodeValueWithBudget(data, offset, budget);
|
|
6002
|
+
setOwnValue2(record, field3, detachDecodedBinary(read.value, data.byteLength));
|
|
6003
|
+
offset = read.offset;
|
|
6004
|
+
}
|
|
6005
|
+
return { value: record, offset };
|
|
6006
|
+
}
|
|
6007
|
+
function readU64(data, offset) {
|
|
6008
|
+
requireAvailable(data, offset, 8);
|
|
6009
|
+
const value = data.readBigUInt64BE(offset);
|
|
6010
|
+
return {
|
|
6011
|
+
value: value <= MAX_SAFE_INTEGER_BIGINT ? Number(value) : value,
|
|
6012
|
+
offset: offset + 8
|
|
6013
|
+
};
|
|
6014
|
+
}
|
|
6015
|
+
function populationCount(value) {
|
|
6016
|
+
let remaining = value >>> 0;
|
|
6017
|
+
let count = 0;
|
|
6018
|
+
while (remaining !== 0) {
|
|
6019
|
+
remaining &= remaining - 1;
|
|
6020
|
+
count += 1;
|
|
6021
|
+
}
|
|
6022
|
+
return count;
|
|
6023
|
+
}
|
|
6024
|
+
|
|
5379
6025
|
// src/protocol-compact-response.ts
|
|
5380
6026
|
function tryDecodeCompactResponse(opcode, body, hints) {
|
|
5381
6027
|
if (body.byteLength === 0) return { found: false, value: void 0 };
|
|
5382
6028
|
const budget = { remainingItems: DEFAULT_MAX_VALUE_ITEMS };
|
|
5383
6029
|
const tag = body.readUInt8(0);
|
|
6030
|
+
validateCompactResponseItems(tag, opcode, body, hints);
|
|
5384
6031
|
const pipelineValues = opcode === OPCODES.pipeline && supports(hints, "pipeline_v1", opcode);
|
|
5385
6032
|
if (tag === COMPACT_OK_LIST && (supports(hints, "ok_list_v1", opcode) || pipelineValues)) {
|
|
5386
6033
|
const values = decodeCompactOkList(body, budget);
|
|
@@ -5431,6 +6078,9 @@ function tryDecodeCompactResponse(opcode, body, hints) {
|
|
|
5431
6078
|
value: opcode === OPCODES.pipeline ? markCompactPipelineDecoded(read.value) : read.value
|
|
5432
6079
|
};
|
|
5433
6080
|
}
|
|
6081
|
+
if (tag === COMPACT_FLOW_QUERY_RESULT && supports(hints, "flow_query_result_v1", opcode)) {
|
|
6082
|
+
return { found: true, value: decodeCompactFlowQueryResult(body, budget) };
|
|
6083
|
+
}
|
|
5434
6084
|
return { found: false, value: void 0 };
|
|
5435
6085
|
}
|
|
5436
6086
|
function supports(hints, codec, opcode) {
|
|
@@ -5441,7 +6091,7 @@ function decodeCompactOkList(data, budget) {
|
|
|
5441
6091
|
const count = data.readUInt32BE(1);
|
|
5442
6092
|
requireCompactContainer2(count, budget);
|
|
5443
6093
|
if (data.byteLength !== 5) throw new FerricStoreError("invalid compact OK list response");
|
|
5444
|
-
return Array.from({ length: count }, () =>
|
|
6094
|
+
return Array.from({ length: count }, () => import_node_buffer25.Buffer.from("OK"));
|
|
5445
6095
|
}
|
|
5446
6096
|
function decodeCompactKvGet(data) {
|
|
5447
6097
|
requireAvailable(data, 0, 2);
|
|
@@ -5487,7 +6137,7 @@ function decodeCompactMgetFixed(data, budget) {
|
|
|
5487
6137
|
if (size === NULL_U32 || data.byteLength !== expected) {
|
|
5488
6138
|
throw new FerricStoreError("invalid compact fixed MGET response");
|
|
5489
6139
|
}
|
|
5490
|
-
if (size === 0) return new Array(count).fill(
|
|
6140
|
+
if (size === 0) return new Array(count).fill(import_node_buffer25.Buffer.alloc(0));
|
|
5491
6141
|
const values = new Array(count);
|
|
5492
6142
|
for (let index = 0, offset = 9; index < count; index += 1, offset += size) {
|
|
5493
6143
|
values[index] = data.subarray(offset, offset + size);
|
|
@@ -5548,7 +6198,7 @@ function decodeCompactPipeline(data, budget, claimModes) {
|
|
|
5548
6198
|
const read = readBinary(data, offset);
|
|
5549
6199
|
const errorStatus = status === 1 ? "busy" : "error";
|
|
5550
6200
|
values[index] = classifyServerError(
|
|
5551
|
-
|
|
6201
|
+
protocolErrorMessage(status === 1 ? 4 : 1, read.value),
|
|
5552
6202
|
read.value,
|
|
5553
6203
|
void 0,
|
|
5554
6204
|
errorStatus
|
|
@@ -5658,13 +6308,13 @@ function readCompactFlowRecord(data, offset, budget = { remainingItems: DEFAULT_
|
|
|
5658
6308
|
let key;
|
|
5659
6309
|
if (keyId === 0) {
|
|
5660
6310
|
const read2 = readBinary(data, offset);
|
|
5661
|
-
key = read2.value
|
|
6311
|
+
key = read2.value;
|
|
5662
6312
|
offset = read2.offset;
|
|
5663
6313
|
} else {
|
|
5664
6314
|
key = FLOW_RECORD_FIELD_KEYS[keyId] ?? `field_${keyId}`;
|
|
5665
6315
|
}
|
|
5666
6316
|
const read = decodeValueWithBudget(data, offset, budget);
|
|
5667
|
-
|
|
6317
|
+
setProtocolMapEntry(record, key, read.value);
|
|
5668
6318
|
offset = read.offset;
|
|
5669
6319
|
}
|
|
5670
6320
|
return { value: record, offset };
|
|
@@ -5700,15 +6350,29 @@ function requireCompactContainer2(count, budget) {
|
|
|
5700
6350
|
}
|
|
5701
6351
|
consumeDecodeItems(count, budget);
|
|
5702
6352
|
}
|
|
5703
|
-
function
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
if (
|
|
5707
|
-
|
|
5708
|
-
|
|
6353
|
+
function validateCompactResponseItems(tag, opcode, data, hints) {
|
|
6354
|
+
const scalarItems = opcode === OPCODES.set || opcode === OPCODES.mset ? 1 : void 0;
|
|
6355
|
+
const expected = scalarItems ?? hints.compactResponseItems;
|
|
6356
|
+
if (expected == null || !COUNTED_COMPACT_TAGS.has(tag)) return;
|
|
6357
|
+
requireAvailable(data, 0, 5);
|
|
6358
|
+
const actual = data.readUInt32BE(1);
|
|
6359
|
+
if (actual !== expected) {
|
|
6360
|
+
throw new FerricStoreError(
|
|
6361
|
+
`compact response returned ${actual} items; expected ${expected} items`
|
|
6362
|
+
);
|
|
5709
6363
|
}
|
|
5710
|
-
return `ERR native request failed status=${status}: ${String(value)}`;
|
|
5711
6364
|
}
|
|
6365
|
+
var COUNTED_COMPACT_TAGS = /* @__PURE__ */ new Set([
|
|
6366
|
+
COMPACT_FLOW_CLAIM_JOBS,
|
|
6367
|
+
COMPACT_OK_LIST,
|
|
6368
|
+
COMPACT_KV_MGET,
|
|
6369
|
+
COMPACT_FLOW_RECORD_LIST,
|
|
6370
|
+
COMPACT_BINARY_LIST_LIST,
|
|
6371
|
+
COMPACT_BINARY_MAP_LIST,
|
|
6372
|
+
COMPACT_INTEGER_LIST,
|
|
6373
|
+
COMPACT_KV_MGET_FIXED,
|
|
6374
|
+
COMPACT_PIPELINE_RESPONSE
|
|
6375
|
+
]);
|
|
5712
6376
|
|
|
5713
6377
|
// src/protocol-response.ts
|
|
5714
6378
|
function decodeResponse(frame, expectedOpcode, hints = {}) {
|
|
@@ -5726,9 +6390,16 @@ function decodeResponse(frame, expectedOpcode, hints = {}) {
|
|
|
5726
6390
|
}
|
|
5727
6391
|
const status = frame.body.readUInt16BE(0);
|
|
5728
6392
|
const body = frame.body.subarray(2);
|
|
5729
|
-
const
|
|
6393
|
+
const customPayload = (frame.flags & FLAG_CUSTOM_PAYLOAD) !== 0;
|
|
6394
|
+
const value = decodeResponseValue(
|
|
6395
|
+
frame.opcode,
|
|
6396
|
+
body,
|
|
6397
|
+
hints,
|
|
6398
|
+
status === STATUS_OK,
|
|
6399
|
+
customPayload
|
|
6400
|
+
);
|
|
5730
6401
|
if (status === STATUS_OK) return value;
|
|
5731
|
-
const message =
|
|
6402
|
+
const message = protocolErrorMessage(status, value);
|
|
5732
6403
|
throw classifyServerError(message, value, void 0, status);
|
|
5733
6404
|
}
|
|
5734
6405
|
function unwrapPipelineResponse(value, options = {}, expectedItems) {
|
|
@@ -5767,7 +6438,7 @@ function unwrapPipelineResponse(value, options = {}, expectedItems) {
|
|
|
5767
6438
|
continue;
|
|
5768
6439
|
}
|
|
5769
6440
|
const error = classifyServerError(
|
|
5770
|
-
|
|
6441
|
+
protocolErrorMessage(status === "busy" ? 4 : 1, payload),
|
|
5771
6442
|
payload,
|
|
5772
6443
|
void 0,
|
|
5773
6444
|
status
|
|
@@ -5782,28 +6453,24 @@ function unwrapPipelineResponse(value, options = {}, expectedItems) {
|
|
|
5782
6453
|
return out;
|
|
5783
6454
|
}
|
|
5784
6455
|
function pipelineStatus(value) {
|
|
5785
|
-
if (typeof value !== "string" && !
|
|
6456
|
+
if (typeof value !== "string" && !import_node_buffer26.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return null;
|
|
5786
6457
|
const status = asText(value).toLowerCase();
|
|
5787
6458
|
return status === "ok" || status === "busy" || status === "error" ? status : null;
|
|
5788
6459
|
}
|
|
5789
|
-
function decodeResponseValue(opcode, body, hints) {
|
|
5790
|
-
|
|
5791
|
-
|
|
6460
|
+
function decodeResponseValue(opcode, body, hints, allowCompact, customPayload) {
|
|
6461
|
+
if (customPayload && allowCompact) {
|
|
6462
|
+
const compact = tryDecodeCompactResponse(opcode, body, hints);
|
|
6463
|
+
if (compact.found) return compact.value;
|
|
6464
|
+
}
|
|
6465
|
+
if (customPayload) {
|
|
6466
|
+
throw new FerricStoreError("unsupported or malformed custom protocol response", { raw: body });
|
|
6467
|
+
}
|
|
5792
6468
|
const decoded = decodeValue(body);
|
|
5793
6469
|
if (decoded.offset !== body.byteLength) {
|
|
5794
6470
|
throw new FerricStoreError("native protocol response has trailing bytes", { raw: body });
|
|
5795
6471
|
}
|
|
5796
6472
|
return decoded.value;
|
|
5797
6473
|
}
|
|
5798
|
-
function errorMessage2(status, value) {
|
|
5799
|
-
if (typeof value === "string") return value;
|
|
5800
|
-
if (import_node_buffer20.Buffer.isBuffer(value)) return value.toString("utf8");
|
|
5801
|
-
if (typeof value === "object" && value != null && Object.hasOwn(value, "message")) {
|
|
5802
|
-
const message = value.message;
|
|
5803
|
-
return typeof message === "string" ? message : String(message);
|
|
5804
|
-
}
|
|
5805
|
-
return `ERR native request failed status=${status}: ${String(value)}`;
|
|
5806
|
-
}
|
|
5807
6474
|
|
|
5808
6475
|
// src/protocol.ts
|
|
5809
6476
|
function encodeRequest(command, requestId, maxBodyBytes = Number.MAX_SAFE_INTEGER) {
|
|
@@ -5813,7 +6480,7 @@ function encodeRequest(command, requestId, maxBodyBytes = Number.MAX_SAFE_INTEGE
|
|
|
5813
6480
|
const bodyLength = customPayload ? binaryValueByteLength(command.payload) : plan?.byteLength ?? 0;
|
|
5814
6481
|
if (bodyLength > bodyLimit) throw requestFrameTooLarge(bodyLimit);
|
|
5815
6482
|
const flags = command.flags ?? 0;
|
|
5816
|
-
const frame =
|
|
6483
|
+
const frame = import_node_buffer27.Buffer.allocUnsafe(HEADER_SIZE + bodyLength);
|
|
5817
6484
|
frame.write(MAGIC, 0, "ascii");
|
|
5818
6485
|
frame.writeUInt8(REQUEST_VERSION, 4);
|
|
5819
6486
|
frame.writeUInt8(flags, 5);
|
|
@@ -5914,18 +6581,18 @@ function buildProtocolCommand(args, maxBodyBytes = Number.MAX_SAFE_INTEGER, allo
|
|
|
5914
6581
|
}
|
|
5915
6582
|
if (command === "SET" && commandArgs2.length >= 2) {
|
|
5916
6583
|
const payload = stringSetPayload(commandArgs2);
|
|
5917
|
-
return payload == null ? commandExec(args) : { opcode: OPCODES.set, payload };
|
|
6584
|
+
return payload == null ? commandExec(args) : { compactResponseItems: 1, opcode: OPCODES.set, payload };
|
|
5918
6585
|
}
|
|
5919
6586
|
if (command === "MGET" && commandArgs2.length > 0) {
|
|
5920
6587
|
const compact = allowCustomPayload ? compactKeyPipelinePayload(OPCODES.mget, commandArgs2, 2, maxBodyBytes) : void 0;
|
|
5921
|
-
if (compact != null) return compact;
|
|
5922
|
-
return commandArgs2.every(isBinaryCommandArgument) ? { opcode: OPCODES.mget, payload: { keys: commandArgs2 } } : commandExec(args);
|
|
6588
|
+
if (compact != null) return { ...compact, compactResponseItems: commandArgs2.length };
|
|
6589
|
+
return commandArgs2.every(isBinaryCommandArgument) ? { compactResponseItems: commandArgs2.length, opcode: OPCODES.mget, payload: { keys: commandArgs2 } } : commandExec(args);
|
|
5923
6590
|
}
|
|
5924
6591
|
if (command === "MSET" && commandArgs2.length >= 2 && commandArgs2.length % 2 === 0) {
|
|
5925
6592
|
const compact = allowCustomPayload ? compactMsetPayload(commandArgs2, maxBodyBytes) : void 0;
|
|
5926
|
-
if (compact != null) return compact;
|
|
6593
|
+
if (compact != null) return { ...compact, compactResponseItems: 1 };
|
|
5927
6594
|
const pairs = typedKeyValuePairs(commandArgs2);
|
|
5928
|
-
return pairs == null ? commandExec(args) : { opcode: OPCODES.mset, payload: { pairs } };
|
|
6595
|
+
return pairs == null ? commandExec(args) : { compactResponseItems: 1, opcode: OPCODES.mset, payload: { pairs } };
|
|
5929
6596
|
}
|
|
5930
6597
|
if (command === "DEL" && commandArgs2.length > 0) {
|
|
5931
6598
|
return commandArgs2.every(isBinaryCommandArgument) ? { opcode: OPCODES.del, payload: { keys: commandArgs2 } } : commandExec(args);
|
|
@@ -5935,8 +6602,14 @@ function buildProtocolCommand(args, maxBodyBytes = Number.MAX_SAFE_INTEGER, allo
|
|
|
5935
6602
|
if (command === "FLOW.HISTORY") {
|
|
5936
6603
|
return flowHistoryPayload(commandArgs2) ?? commandExec(args);
|
|
5937
6604
|
}
|
|
5938
|
-
if (command === "FLOW.
|
|
5939
|
-
return
|
|
6605
|
+
if (command === "FLOW.QUERY") {
|
|
6606
|
+
return { opcode: OPCODES.flowQuery, payload: flowQueryPayload(commandArgs2) };
|
|
6607
|
+
}
|
|
6608
|
+
if (command === "FLOW.POLICY.SET") {
|
|
6609
|
+
return flowPolicySetPayload(commandArgs2) ?? commandExec(args);
|
|
6610
|
+
}
|
|
6611
|
+
if (command === "FLOW.POLICY.GET") {
|
|
6612
|
+
return flowPolicyGetPayload(commandArgs2) ?? commandExec(args);
|
|
5940
6613
|
}
|
|
5941
6614
|
const flowAdmin = FLOW_ADMIN_COMMANDS[command];
|
|
5942
6615
|
if (flowAdmin != null) {
|
|
@@ -6089,24 +6762,17 @@ function buildProtocolCommand(args, maxBodyBytes = Number.MAX_SAFE_INTEGER, allo
|
|
|
6089
6762
|
if (command === "FLOW.RUN_STEPS_MANY") {
|
|
6090
6763
|
return flowAdminPayload(OPCODES.flowRunStepsMany, commandArgs2) ?? commandExec(args);
|
|
6091
6764
|
}
|
|
6092
|
-
if (command === "FLOW.SEARCH") {
|
|
6093
|
-
if (hasFlowCommandOnlyOption(command, commandArgs2)) {
|
|
6094
|
-
const fallback = commandExec(args);
|
|
6095
|
-
try {
|
|
6096
|
-
const parsed = flowSearchPayload(commandArgs2);
|
|
6097
|
-
return parsed == null ? fallback : withFlowPartitionRouting(fallback, parsed.payload);
|
|
6098
|
-
} catch {
|
|
6099
|
-
return fallback;
|
|
6100
|
-
}
|
|
6101
|
-
}
|
|
6102
|
-
return flowSearchPayload(commandArgs2) ?? commandExec(args);
|
|
6103
|
-
}
|
|
6104
6765
|
return commandExec(args);
|
|
6105
6766
|
}
|
|
6106
6767
|
function tryPipelineCommand(commands, maxBodyBytes = Number.MAX_SAFE_INTEGER) {
|
|
6107
6768
|
const compact = compactPipelinePayload(commands, maxBodyBytes);
|
|
6108
6769
|
if (compact != null) {
|
|
6109
|
-
return {
|
|
6770
|
+
return {
|
|
6771
|
+
compactResponseItems: commands.length,
|
|
6772
|
+
flags: FLAG_CUSTOM_PAYLOAD,
|
|
6773
|
+
opcode: OPCODES.pipeline,
|
|
6774
|
+
payload: compact
|
|
6775
|
+
};
|
|
6110
6776
|
}
|
|
6111
6777
|
const protocols = new Array(commands.length);
|
|
6112
6778
|
for (let index = 0; index < commands.length; index += 1) {
|
|
@@ -6145,6 +6811,7 @@ function tryPipelineCommand(commands, maxBodyBytes = Number.MAX_SAFE_INTEGER) {
|
|
|
6145
6811
|
const pipelineClaimModes = pipelineProtocols.map((protocol) => protocol.compactClaimMode);
|
|
6146
6812
|
const hasPipelineClaimMode = pipelineClaimModes.some((mode) => mode != null);
|
|
6147
6813
|
return {
|
|
6814
|
+
compactResponseItems: commands.length,
|
|
6148
6815
|
opcode: OPCODES.pipeline,
|
|
6149
6816
|
payload: {
|
|
6150
6817
|
atomicity: "none",
|
|
@@ -6193,7 +6860,7 @@ var import_node_net2 = require("net");
|
|
|
6193
6860
|
var import_node_tls2 = require("tls");
|
|
6194
6861
|
|
|
6195
6862
|
// src/client-native-options.ts
|
|
6196
|
-
var
|
|
6863
|
+
var import_node_buffer28 = require("buffer");
|
|
6197
6864
|
|
|
6198
6865
|
// src/string-array-snapshot.ts
|
|
6199
6866
|
function snapshotOwnStringArray(values, name) {
|
|
@@ -6276,7 +6943,7 @@ function snapshotTlsOptions(options) {
|
|
|
6276
6943
|
return Object.freeze(snapshot);
|
|
6277
6944
|
}
|
|
6278
6945
|
function snapshotTlsValue(value, name) {
|
|
6279
|
-
if (
|
|
6946
|
+
if (import_node_buffer28.Buffer.isBuffer(value)) return import_node_buffer28.Buffer.from(value);
|
|
6280
6947
|
if (value instanceof Uint8Array) return value.slice();
|
|
6281
6948
|
if (Array.isArray(value)) {
|
|
6282
6949
|
const snapshot = new Array(value.length);
|
|
@@ -6831,7 +7498,7 @@ var NativeChunkAssembler = class {
|
|
|
6831
7498
|
};
|
|
6832
7499
|
|
|
6833
7500
|
// src/native-response-handler.ts
|
|
6834
|
-
var
|
|
7501
|
+
var import_node_buffer29 = require("buffer");
|
|
6835
7502
|
|
|
6836
7503
|
// src/native-receive-buffer.ts
|
|
6837
7504
|
var FRAME_ASSEMBLY_PAGE_BYTES = 64 * 1024;
|
|
@@ -7131,7 +7798,7 @@ var NativeResponseHandler = class {
|
|
|
7131
7798
|
compactResponseOpcodes: this.options.compactResponseOpcodes?.() ?? EMPTY_COMPACT_RESPONSE_OPCODES
|
|
7132
7799
|
});
|
|
7133
7800
|
if (frame.opcode === OPCODES.windowUpdate) this.options.applyFlowControlLimits(value);
|
|
7134
|
-
const
|
|
7801
|
+
const event2 = {
|
|
7135
7802
|
flags: frame.flags,
|
|
7136
7803
|
laneId: frame.laneId,
|
|
7137
7804
|
opcode: frame.opcode,
|
|
@@ -7139,7 +7806,7 @@ var NativeResponseHandler = class {
|
|
|
7139
7806
|
};
|
|
7140
7807
|
if (frame.opcode === OPCODES.goaway) this.options.beginDraining();
|
|
7141
7808
|
try {
|
|
7142
|
-
const callback = this.options.onEvent?.(
|
|
7809
|
+
const callback = this.options.onEvent?.(event2);
|
|
7143
7810
|
if (callback != null) void Promise.resolve(callback).catch(() => void 0);
|
|
7144
7811
|
} catch {
|
|
7145
7812
|
}
|
|
@@ -7166,7 +7833,7 @@ var NativeRequestScheduler = class {
|
|
|
7166
7833
|
};
|
|
7167
7834
|
|
|
7168
7835
|
// src/native-write-queue.ts
|
|
7169
|
-
var
|
|
7836
|
+
var import_node_buffer30 = require("buffer");
|
|
7170
7837
|
var NativeWriteQueue = class {
|
|
7171
7838
|
constructor(socket, maxQueuedWriteBytes, isClosed, hasPending, rejectPending) {
|
|
7172
7839
|
this.socket = socket;
|
|
@@ -7303,12 +7970,14 @@ var NativeConnectionCapabilities = class {
|
|
|
7303
7970
|
}
|
|
7304
7971
|
configuredRequestFrameBytes;
|
|
7305
7972
|
compactResponseOpcodes = EMPTY_COMPACT_RESPONSE_OPCODES;
|
|
7973
|
+
flowQuery;
|
|
7306
7974
|
requestFrameBytes;
|
|
7307
7975
|
negotiatedRequestFrameBytes;
|
|
7308
7976
|
apply(value) {
|
|
7309
7977
|
const limits = startupLimits(value);
|
|
7310
7978
|
const negotiation = nativeNegotiation(value);
|
|
7311
7979
|
this.compactResponseOpcodes = negotiation.compactResponseOpcodes;
|
|
7980
|
+
this.flowQuery = negotiation.flowQuery;
|
|
7312
7981
|
if (limits.frameBytes != null) {
|
|
7313
7982
|
this.negotiatedRequestFrameBytes = Math.min(
|
|
7314
7983
|
this.configuredRequestFrameBytes,
|
|
@@ -7328,6 +7997,19 @@ var NativeConnectionCapabilities = class {
|
|
|
7328
7997
|
}
|
|
7329
7998
|
};
|
|
7330
7999
|
|
|
8000
|
+
// src/native-startup-payload.ts
|
|
8001
|
+
function nativeStartupPayload(clientName, events) {
|
|
8002
|
+
const name = clientName ?? "ferricstore-typescript";
|
|
8003
|
+
return {
|
|
8004
|
+
client_name: name,
|
|
8005
|
+
compact_flow_responses: true,
|
|
8006
|
+
compact_response_codecs: ["flow_query_result_v1"],
|
|
8007
|
+
compression: "none",
|
|
8008
|
+
driver_name: name,
|
|
8009
|
+
...events == null || events.length === 0 ? {} : { events: [...events] }
|
|
8010
|
+
};
|
|
8011
|
+
}
|
|
8012
|
+
|
|
7331
8013
|
// src/native-adapter.ts
|
|
7332
8014
|
var NativeAdapter = class _NativeAdapter {
|
|
7333
8015
|
socket;
|
|
@@ -7486,13 +8168,7 @@ var NativeAdapter = class _NativeAdapter {
|
|
|
7486
8168
|
const response = await this.request({
|
|
7487
8169
|
laneId: 0,
|
|
7488
8170
|
opcode: OPCODES.startup,
|
|
7489
|
-
payload:
|
|
7490
|
-
client_name: clientName ?? "ferricstore-typescript",
|
|
7491
|
-
compact_flow_responses: true,
|
|
7492
|
-
compression: "none",
|
|
7493
|
-
driver_name: clientName ?? "ferricstore-typescript",
|
|
7494
|
-
...events == null || events.length === 0 ? {} : { events: [...events] }
|
|
7495
|
-
}
|
|
8171
|
+
payload: nativeStartupPayload(clientName, events)
|
|
7496
8172
|
});
|
|
7497
8173
|
this.applyStartupLimits(response);
|
|
7498
8174
|
const authRequired = field(response, "auth_required");
|
|
@@ -7552,6 +8228,7 @@ var NativeAdapter = class _NativeAdapter {
|
|
|
7552
8228
|
if (!hasFlowControlCredit) this.pendingControlRequests += 1;
|
|
7553
8229
|
this.pending.set(requestId, {
|
|
7554
8230
|
...command.compactClaimMode == null ? {} : { compactClaimMode: command.compactClaimMode },
|
|
8231
|
+
...command.compactResponseItems == null ? {} : { compactResponseItems: command.compactResponseItems },
|
|
7555
8232
|
hasFlowControlCredit,
|
|
7556
8233
|
indefinite: timeoutMs == null,
|
|
7557
8234
|
laneId,
|
|
@@ -7683,7 +8360,30 @@ function executeCommandArgs(executor, args) {
|
|
|
7683
8360
|
}
|
|
7684
8361
|
|
|
7685
8362
|
// src/reconnecting-executor.ts
|
|
7686
|
-
var
|
|
8363
|
+
var import_node_buffer33 = require("buffer");
|
|
8364
|
+
|
|
8365
|
+
// src/command-retry-policy.ts
|
|
8366
|
+
var import_node_buffer32 = require("buffer");
|
|
8367
|
+
function isCasMutation(args) {
|
|
8368
|
+
const offset = commandName2(args[0]) === "COMMAND_EXEC" ? 1 : 0;
|
|
8369
|
+
const name = commandName2(args[offset]);
|
|
8370
|
+
if (name === "CAS") return true;
|
|
8371
|
+
if (name !== "FLOW.POLICY.SET") return false;
|
|
8372
|
+
for (let index = offset + 2; index < args.length; index += 2) {
|
|
8373
|
+
if (!Object.hasOwn(args, index)) return false;
|
|
8374
|
+
if (commandName2(args[index]) === "EXPECTED_GENERATION") return true;
|
|
8375
|
+
}
|
|
8376
|
+
return false;
|
|
8377
|
+
}
|
|
8378
|
+
function commandName2(value) {
|
|
8379
|
+
if (typeof value === "string") return value.toUpperCase();
|
|
8380
|
+
if (import_node_buffer32.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
8381
|
+
return import_node_buffer32.Buffer.from(value).toString("utf8").toUpperCase();
|
|
8382
|
+
}
|
|
8383
|
+
return void 0;
|
|
8384
|
+
}
|
|
8385
|
+
|
|
8386
|
+
// src/reconnecting-executor.ts
|
|
7687
8387
|
var ReconnectingExecutor = class {
|
|
7688
8388
|
constructor(createExecutor, options = {}) {
|
|
7689
8389
|
this.createExecutor = createExecutor;
|
|
@@ -7714,7 +8414,12 @@ var ReconnectingExecutor = class {
|
|
|
7714
8414
|
async executeCommandArgs(args) {
|
|
7715
8415
|
const snapshot = snapshotCommandArguments(args);
|
|
7716
8416
|
assertCommandHasStableConnectionState(snapshot);
|
|
7717
|
-
|
|
8417
|
+
const casMutation = isCasMutation(snapshot);
|
|
8418
|
+
return await this.withReconnect(
|
|
8419
|
+
(executor) => executeCommandArgs(executor, snapshot),
|
|
8420
|
+
casMutation ? isClosedConnectionError : isReconnectableClosedConnectionError,
|
|
8421
|
+
!casMutation
|
|
8422
|
+
);
|
|
7718
8423
|
}
|
|
7719
8424
|
async ready() {
|
|
7720
8425
|
await this.executorPromise;
|
|
@@ -7799,7 +8504,7 @@ var ReconnectingExecutor = class {
|
|
|
7799
8504
|
})();
|
|
7800
8505
|
await this.closePromise;
|
|
7801
8506
|
}
|
|
7802
|
-
async withReconnect(operation, reconnectable = isReconnectableClosedConnectionError) {
|
|
8507
|
+
async withReconnect(operation, reconnectable = isReconnectableClosedConnectionError, replayAllowed = true) {
|
|
7803
8508
|
let executor = await this.executorPromise;
|
|
7804
8509
|
let retries = 0;
|
|
7805
8510
|
for (; ; ) {
|
|
@@ -7808,6 +8513,10 @@ var ReconnectingExecutor = class {
|
|
|
7808
8513
|
return await operation(executor);
|
|
7809
8514
|
} catch (error) {
|
|
7810
8515
|
if (this.closed || retries >= this.maxRetries || !reconnectable(error)) throw error;
|
|
8516
|
+
if (!replayAllowed) {
|
|
8517
|
+
await this.reconnect(executor).catch(() => void 0);
|
|
8518
|
+
throw error;
|
|
8519
|
+
}
|
|
7811
8520
|
for (; ; ) {
|
|
7812
8521
|
retries += 1;
|
|
7813
8522
|
try {
|
|
@@ -7860,6 +8569,9 @@ var ReconnectingExecutor = class {
|
|
|
7860
8569
|
function isReconnectableClosedConnectionError(error) {
|
|
7861
8570
|
return error instanceof ConnectionClosedError && error.requestDisposition === "unsent";
|
|
7862
8571
|
}
|
|
8572
|
+
function isClosedConnectionError(error) {
|
|
8573
|
+
return error instanceof ConnectionClosedError;
|
|
8574
|
+
}
|
|
7863
8575
|
function isReadOnlyReconnectableClosedConnectionError(error) {
|
|
7864
8576
|
const pending = [error];
|
|
7865
8577
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -7878,19 +8590,91 @@ function normalizeNonNegativeInteger2(value, fallback) {
|
|
|
7878
8590
|
}
|
|
7879
8591
|
|
|
7880
8592
|
// src/topology.ts
|
|
7881
|
-
var
|
|
8593
|
+
var import_node_buffer36 = require("buffer");
|
|
7882
8594
|
|
|
7883
8595
|
// src/topology-routing.ts
|
|
7884
|
-
var
|
|
8596
|
+
var import_node_buffer35 = require("buffer");
|
|
8597
|
+
|
|
8598
|
+
// src/flow-partition-route-cache.ts
|
|
8599
|
+
var import_node_buffer34 = require("buffer");
|
|
7885
8600
|
var import_node_crypto = require("crypto");
|
|
7886
|
-
var
|
|
7887
|
-
var
|
|
8601
|
+
var AUTO_PREFIX = import_node_buffer34.Buffer.from("__flow_auto__:", "ascii");
|
|
8602
|
+
var MAX_CACHEABLE_PARTITION_BYTES = 4 * 1024;
|
|
8603
|
+
var MAX_CACHE_BYTES = 1 * 1024 * 1024;
|
|
8604
|
+
var MAX_CACHE_ENTRIES = 1024;
|
|
8605
|
+
var CACHE_ENTRY_OVERHEAD_BYTES = 96;
|
|
8606
|
+
var routeCache = /* @__PURE__ */ new Map();
|
|
8607
|
+
var cacheBytes = 0;
|
|
8608
|
+
var cacheHits = 0;
|
|
8609
|
+
var cacheMisses = 0;
|
|
8610
|
+
function flowLogicalPartitionRoutingKey(value) {
|
|
8611
|
+
if (typeof value !== "string" && !import_node_buffer34.Buffer.isBuffer(value)) return void 0;
|
|
8612
|
+
const autoBucket = flowAutoBucket(value);
|
|
8613
|
+
if (autoBucket != null) return `{fa:${autoBucket}}`;
|
|
8614
|
+
const bytes2 = import_node_buffer34.Buffer.isBuffer(value) ? value : import_node_buffer34.Buffer.from(value);
|
|
8615
|
+
if (bytes2.byteLength > MAX_CACHEABLE_PARTITION_BYTES) return hashRoute(bytes2);
|
|
8616
|
+
const cacheKey = bytes2.toString("base64");
|
|
8617
|
+
const cached = routeCache.get(cacheKey);
|
|
8618
|
+
if (cached != null) {
|
|
8619
|
+
cacheHits += 1;
|
|
8620
|
+
routeCache.delete(cacheKey);
|
|
8621
|
+
routeCache.set(cacheKey, cached);
|
|
8622
|
+
return cached.routeKey;
|
|
8623
|
+
}
|
|
8624
|
+
cacheMisses += 1;
|
|
8625
|
+
const routeKey = hashRoute(bytes2);
|
|
8626
|
+
const entryBytes = estimatedEntryBytes(cacheKey, routeKey);
|
|
8627
|
+
while (routeCache.size >= MAX_CACHE_ENTRIES || routeCache.size > 0 && cacheBytes + entryBytes > MAX_CACHE_BYTES) {
|
|
8628
|
+
evictOldest();
|
|
8629
|
+
}
|
|
8630
|
+
if (entryBytes <= MAX_CACHE_BYTES) {
|
|
8631
|
+
routeCache.set(cacheKey, { bytes: entryBytes, routeKey });
|
|
8632
|
+
cacheBytes += entryBytes;
|
|
8633
|
+
}
|
|
8634
|
+
return routeKey;
|
|
8635
|
+
}
|
|
8636
|
+
function flowAutoBucket(value) {
|
|
8637
|
+
if (typeof value === "string") {
|
|
8638
|
+
const match = /^__flow_auto__:(0|[1-9]\d{0,2})$/u.exec(value);
|
|
8639
|
+
if (match?.[1] == null) return void 0;
|
|
8640
|
+
const bucket2 = Number(match[1]);
|
|
8641
|
+
return bucket2 < 256 ? bucket2 : void 0;
|
|
8642
|
+
}
|
|
8643
|
+
const digitCount = value.byteLength - AUTO_PREFIX.byteLength;
|
|
8644
|
+
if (digitCount < 1 || digitCount > 3) return void 0;
|
|
8645
|
+
for (let index = 0; index < AUTO_PREFIX.byteLength; index += 1) {
|
|
8646
|
+
if (value[index] !== AUTO_PREFIX[index]) return void 0;
|
|
8647
|
+
}
|
|
8648
|
+
if (digitCount > 1 && value[AUTO_PREFIX.byteLength] === 48) return void 0;
|
|
8649
|
+
let bucket = 0;
|
|
8650
|
+
for (let index = AUTO_PREFIX.byteLength; index < value.byteLength; index += 1) {
|
|
8651
|
+
const digit = value[index];
|
|
8652
|
+
if (digit == null || digit < 48 || digit > 57) return void 0;
|
|
8653
|
+
bucket = bucket * 10 + digit - 48;
|
|
8654
|
+
}
|
|
8655
|
+
return bucket < 256 ? bucket : void 0;
|
|
8656
|
+
}
|
|
8657
|
+
function hashRoute(value) {
|
|
8658
|
+
const digest = (0, import_node_crypto.createHash)("sha256").update(value).digest("base64url");
|
|
8659
|
+
return `{f:${digest}}`;
|
|
8660
|
+
}
|
|
8661
|
+
function estimatedEntryBytes(cacheKey, routeKey) {
|
|
8662
|
+
return CACHE_ENTRY_OVERHEAD_BYTES + 2 * (cacheKey.length + routeKey.length);
|
|
8663
|
+
}
|
|
8664
|
+
function evictOldest() {
|
|
8665
|
+
const oldest = routeCache.entries().next().value;
|
|
8666
|
+
if (oldest == null) return;
|
|
8667
|
+
routeCache.delete(oldest[0]);
|
|
8668
|
+
cacheBytes -= oldest[1].bytes;
|
|
8669
|
+
}
|
|
8670
|
+
|
|
8671
|
+
// src/topology-routing.ts
|
|
7888
8672
|
function routingKeyFromProtocolPayload(name, command) {
|
|
7889
8673
|
if (command.opcode < 256 || name === "CLUSTER.KEYSLOT" || name === "SHARDS" || name === "ROUTE") {
|
|
7890
8674
|
return void 0;
|
|
7891
8675
|
}
|
|
7892
8676
|
if (isPlainObject3(command.payload)) {
|
|
7893
|
-
for (const
|
|
8677
|
+
for (const field3 of [
|
|
7894
8678
|
"key",
|
|
7895
8679
|
"partition_key",
|
|
7896
8680
|
"id",
|
|
@@ -7900,8 +8684,8 @@ function routingKeyFromProtocolPayload(name, command) {
|
|
|
7900
8684
|
"correlation_id",
|
|
7901
8685
|
"scope"
|
|
7902
8686
|
]) {
|
|
7903
|
-
const value = getField(command.payload,
|
|
7904
|
-
if (typeof value === "string" ||
|
|
8687
|
+
const value = getField(command.payload, field3);
|
|
8688
|
+
if (typeof value === "string" || import_node_buffer35.Buffer.isBuffer(value)) {
|
|
7905
8689
|
return value;
|
|
7906
8690
|
}
|
|
7907
8691
|
}
|
|
@@ -7935,6 +8719,7 @@ function flowRoutingData(name, args) {
|
|
|
7935
8719
|
if (flowScheduleCommands.has(name)) {
|
|
7936
8720
|
return void 0;
|
|
7937
8721
|
}
|
|
8722
|
+
if (name === "FLOW.QUERY") return void 0;
|
|
7938
8723
|
if (flowApprovalIdCommands.has(name)) {
|
|
7939
8724
|
const id = flowArgs[0];
|
|
7940
8725
|
return flowRoutingResult(flowLogicalPartitionRoutingKey(id));
|
|
@@ -7948,7 +8733,7 @@ function flowRoutingData(name, args) {
|
|
|
7948
8733
|
if (typeof partition === "string" && partition.toUpperCase() !== "AUTO" && partition.toUpperCase() !== "MIXED") {
|
|
7949
8734
|
return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
|
|
7950
8735
|
}
|
|
7951
|
-
if (
|
|
8736
|
+
if (import_node_buffer35.Buffer.isBuffer(partition)) {
|
|
7952
8737
|
const text3 = partition.toString("utf8").toUpperCase();
|
|
7953
8738
|
if (text3 !== "AUTO" && text3 !== "MIXED") {
|
|
7954
8739
|
return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
|
|
@@ -8039,46 +8824,17 @@ function flowPartitionRoutingKeyFromCommand(command, claim) {
|
|
|
8039
8824
|
return { handled: false };
|
|
8040
8825
|
}
|
|
8041
8826
|
function isRoutingKey(value) {
|
|
8042
|
-
return typeof value === "string" ||
|
|
8043
|
-
}
|
|
8044
|
-
function flowLogicalPartitionRoutingKey(value) {
|
|
8045
|
-
if (typeof value !== "string" && !import_node_buffer27.Buffer.isBuffer(value)) {
|
|
8046
|
-
return void 0;
|
|
8047
|
-
}
|
|
8048
|
-
const bytes2 = import_node_buffer27.Buffer.isBuffer(value) ? value : import_node_buffer27.Buffer.from(value);
|
|
8049
|
-
const text3 = bytes2.toString("utf8");
|
|
8050
|
-
const autoMatch = /^__flow_auto__:(0|[1-9]\d{0,2})$/u.exec(text3);
|
|
8051
|
-
if (autoMatch != null) {
|
|
8052
|
-
const bucket = Number(autoMatch[1]);
|
|
8053
|
-
if (bucket < 256) {
|
|
8054
|
-
return `{fa:${bucket}}`;
|
|
8055
|
-
}
|
|
8056
|
-
}
|
|
8057
|
-
const cacheKey = `${import_node_buffer27.Buffer.isBuffer(value) ? "b" : "s"}:${bytes2.toString("base64")}`;
|
|
8058
|
-
const cached = flowPartitionRouteCache.get(cacheKey);
|
|
8059
|
-
if (cached != null) {
|
|
8060
|
-
flowPartitionRouteCache.delete(cacheKey);
|
|
8061
|
-
flowPartitionRouteCache.set(cacheKey, cached);
|
|
8062
|
-
return cached;
|
|
8063
|
-
}
|
|
8064
|
-
const digest = (0, import_node_crypto.createHash)("sha256").update(bytes2).digest("base64url");
|
|
8065
|
-
const routeKey = `{f:${digest}}`;
|
|
8066
|
-
if (flowPartitionRouteCache.size >= FLOW_PARTITION_ROUTE_CACHE_MAX) {
|
|
8067
|
-
const oldest = flowPartitionRouteCache.keys().next().value;
|
|
8068
|
-
if (oldest != null) flowPartitionRouteCache.delete(oldest);
|
|
8069
|
-
}
|
|
8070
|
-
flowPartitionRouteCache.set(cacheKey, routeKey);
|
|
8071
|
-
return routeKey;
|
|
8827
|
+
return typeof value === "string" || import_node_buffer35.Buffer.isBuffer(value);
|
|
8072
8828
|
}
|
|
8073
8829
|
function flowAutoIdRoutingKey(value) {
|
|
8074
|
-
if (typeof value !== "string" && !
|
|
8830
|
+
if (typeof value !== "string" && !import_node_buffer35.Buffer.isBuffer(value)) {
|
|
8075
8831
|
return void 0;
|
|
8076
8832
|
}
|
|
8077
|
-
const bucket = (
|
|
8833
|
+
const bucket = (import_node_buffer35.Buffer.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
|
|
8078
8834
|
return `{fa:${bucket}}`;
|
|
8079
8835
|
}
|
|
8080
8836
|
function flowClaimLogicalPartitionRoutingKey(value) {
|
|
8081
|
-
if (typeof value !== "string" && !
|
|
8837
|
+
if (typeof value !== "string" && !import_node_buffer35.Buffer.isBuffer(value)) return void 0;
|
|
8082
8838
|
const selector = commandPart(value);
|
|
8083
8839
|
if (selector === "AUTO" || selector === "ANY") return void 0;
|
|
8084
8840
|
if (selector === "GLOBAL") return "{f}";
|
|
@@ -8093,7 +8849,7 @@ function singleShardFlowClaimPartitionKey(values) {
|
|
|
8093
8849
|
return keys.some((key) => key == null) ? void 0 : singleShardKey(keys);
|
|
8094
8850
|
}
|
|
8095
8851
|
function singleShardKey(keys) {
|
|
8096
|
-
if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !
|
|
8852
|
+
if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !import_node_buffer35.Buffer.isBuffer(key))) {
|
|
8097
8853
|
return void 0;
|
|
8098
8854
|
}
|
|
8099
8855
|
const usable = keys;
|
|
@@ -8104,7 +8860,7 @@ function singleShardKey(keys) {
|
|
|
8104
8860
|
const firstSlot = routingSlotForKey(first);
|
|
8105
8861
|
return usable.every((key) => routingSlotForKey(key) === firstSlot) ? first : void 0;
|
|
8106
8862
|
}
|
|
8107
|
-
function
|
|
8863
|
+
function commandName3(args) {
|
|
8108
8864
|
return commandView(args).name;
|
|
8109
8865
|
}
|
|
8110
8866
|
var commandPart = commandToken;
|
|
@@ -8126,7 +8882,7 @@ function routedKeyGroups(keys, routeKey) {
|
|
|
8126
8882
|
const groups = /* @__PURE__ */ new Map();
|
|
8127
8883
|
for (let index = 0; index < keys.length; index += 1) {
|
|
8128
8884
|
const key = keys[index];
|
|
8129
|
-
if (typeof key !== "string" && !
|
|
8885
|
+
if (typeof key !== "string" && !import_node_buffer35.Buffer.isBuffer(key)) return void 0;
|
|
8130
8886
|
const route = routeKey(key);
|
|
8131
8887
|
const groupKey = `${route.endpointKey}\0${route.laneId}`;
|
|
8132
8888
|
const group = groups.get(groupKey);
|
|
@@ -8518,7 +9274,7 @@ var TopologyPipelineExecutor = class {
|
|
|
8518
9274
|
commands.forEach((command, index) => {
|
|
8519
9275
|
const routed = this.context.routeData(command);
|
|
8520
9276
|
if (routed == null) {
|
|
8521
|
-
if (decomposableCommandNames.has(
|
|
9277
|
+
if (decomposableCommandNames.has(commandName3(command) ?? "")) standalone.push({ command, index });
|
|
8522
9278
|
else {
|
|
8523
9279
|
controlCommands.push(command);
|
|
8524
9280
|
controlIndices.push(index);
|
|
@@ -8734,7 +9490,7 @@ function topologyRouteIsCurrent(topology, route) {
|
|
|
8734
9490
|
// src/topology-route-planner.ts
|
|
8735
9491
|
function topologyRouteData(args, route) {
|
|
8736
9492
|
if (args.length === 0) return void 0;
|
|
8737
|
-
const name =
|
|
9493
|
+
const name = commandName3(args);
|
|
8738
9494
|
if (name?.startsWith("FLOW.") === true) {
|
|
8739
9495
|
const routed = flowRoutingData(name, args);
|
|
8740
9496
|
return routed == null ? void 0 : {
|
|
@@ -8763,7 +9519,7 @@ var TopologyScatterExecutor = class {
|
|
|
8763
9519
|
}
|
|
8764
9520
|
dependencies;
|
|
8765
9521
|
async execute(args) {
|
|
8766
|
-
const name =
|
|
9522
|
+
const name = commandName3(args);
|
|
8767
9523
|
if (name === "MGET") {
|
|
8768
9524
|
const value = await this.scatterArray(name, args.slice(1));
|
|
8769
9525
|
return value == null ? { handled: false } : { handled: true, value };
|
|
@@ -8845,6 +9601,18 @@ var TopologyScatterExecutor = class {
|
|
|
8845
9601
|
}
|
|
8846
9602
|
};
|
|
8847
9603
|
|
|
9604
|
+
// src/topology-reroute-retry.ts
|
|
9605
|
+
async function canRetrySafeReroute(error, attempt, retryAllowed, refresh, assertOpen) {
|
|
9606
|
+
if (attempt !== 0 || !isRetryableRouteError(error)) return false;
|
|
9607
|
+
const refreshed = await refresh().then(
|
|
9608
|
+
() => true,
|
|
9609
|
+
() => false
|
|
9610
|
+
);
|
|
9611
|
+
if (!refreshed || !retryAllowed || !await waitForExplicitlySafeReroute(error)) return false;
|
|
9612
|
+
assertOpen();
|
|
9613
|
+
return true;
|
|
9614
|
+
}
|
|
9615
|
+
|
|
8848
9616
|
// src/topology.ts
|
|
8849
9617
|
var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
8850
9618
|
adapterOptions;
|
|
@@ -8886,15 +9654,15 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
8886
9654
|
this.adapterOptions = {
|
|
8887
9655
|
...adapterOptions,
|
|
8888
9656
|
events: [.../* @__PURE__ */ new Set([...adapterOptions.events ?? [], "TOPOLOGY_CHANGED"])],
|
|
8889
|
-
onEvent: (
|
|
9657
|
+
onEvent: (event2) => {
|
|
8890
9658
|
try {
|
|
8891
|
-
const callback = userOnEvent?.(
|
|
9659
|
+
const callback = userOnEvent?.(event2);
|
|
8892
9660
|
if (callback != null) {
|
|
8893
9661
|
void Promise.resolve(callback).catch(() => void 0);
|
|
8894
9662
|
}
|
|
8895
9663
|
} catch {
|
|
8896
9664
|
}
|
|
8897
|
-
if (!this.closed && nativeEventName(
|
|
9665
|
+
if (!this.closed && nativeEventName(event2) === "TOPOLOGY_CHANGED") {
|
|
8898
9666
|
this.requestTopologyRefresh();
|
|
8899
9667
|
}
|
|
8900
9668
|
}
|
|
@@ -9030,6 +9798,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
9030
9798
|
this.assertOpen();
|
|
9031
9799
|
const snapshot = snapshotCommandArguments(args);
|
|
9032
9800
|
assertCommandHasStableConnectionState(snapshot);
|
|
9801
|
+
const casMutation = isCasMutation(snapshot);
|
|
9033
9802
|
let rerouteAttempt = 0;
|
|
9034
9803
|
for (let planningAttempt = 0; planningAttempt < MAX_TOPOLOGY_PLANNING_ATTEMPTS; planningAttempt += 1) {
|
|
9035
9804
|
const routed = this.routeData(snapshot);
|
|
@@ -9045,7 +9814,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
9045
9814
|
try {
|
|
9046
9815
|
return routed.command == null ? await adapter.executeCommandOnLane(snapshot, routed.route.laneId) : await adapter.executeProtocolCommand(routed.command, routed.route.laneId);
|
|
9047
9816
|
} catch (error) {
|
|
9048
|
-
if (await this.refreshAndCanRetrySafeReroute(error, rerouteAttempt)) {
|
|
9817
|
+
if (await this.refreshAndCanRetrySafeReroute(error, rerouteAttempt, !casMutation)) {
|
|
9049
9818
|
rerouteAttempt += 1;
|
|
9050
9819
|
continue;
|
|
9051
9820
|
}
|
|
@@ -9087,6 +9856,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
9087
9856
|
assertCommandHasStableConnectionState(command);
|
|
9088
9857
|
}
|
|
9089
9858
|
let rerouteAttempt = 0;
|
|
9859
|
+
const containsCasMutation = snapshot.some(isCasMutation);
|
|
9090
9860
|
for (let planningAttempt = 0; planningAttempt < MAX_TOPOLOGY_PLANNING_ATTEMPTS; planningAttempt += 1) {
|
|
9091
9861
|
const route = singleRouteForCommands(snapshot, (command) => this.routeData(command));
|
|
9092
9862
|
if (route == null) return void 0;
|
|
@@ -9095,7 +9865,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
9095
9865
|
try {
|
|
9096
9866
|
return await adapter.executeFusedPipelineOnLane(snapshot, route.laneId, snapshotOptions);
|
|
9097
9867
|
} catch (error) {
|
|
9098
|
-
if (await this.refreshAndCanRetrySafeReroute(error, rerouteAttempt)) {
|
|
9868
|
+
if (await this.refreshAndCanRetrySafeReroute(error, rerouteAttempt, !containsCasMutation)) {
|
|
9099
9869
|
rerouteAttempt += 1;
|
|
9100
9870
|
continue;
|
|
9101
9871
|
}
|
|
@@ -9104,15 +9874,14 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
9104
9874
|
}
|
|
9105
9875
|
throw new StaleTopologyRouteError();
|
|
9106
9876
|
}
|
|
9107
|
-
async refreshAndCanRetrySafeReroute(error, attempt) {
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9877
|
+
async refreshAndCanRetrySafeReroute(error, attempt, retryAllowed = true) {
|
|
9878
|
+
return await canRetrySafeReroute(
|
|
9879
|
+
error,
|
|
9880
|
+
attempt,
|
|
9881
|
+
retryAllowed,
|
|
9882
|
+
async () => await this.refreshTopology(),
|
|
9883
|
+
() => this.assertOpen()
|
|
9112
9884
|
);
|
|
9113
|
-
if (!refreshed || !await waitForExplicitlySafeReroute(error)) return false;
|
|
9114
|
-
this.assertOpen();
|
|
9115
|
-
return true;
|
|
9116
9885
|
}
|
|
9117
9886
|
async executePipelineOnRoute(commands, route, options) {
|
|
9118
9887
|
const adapter = await this.adapterForCurrentRoute(route);
|
|
@@ -9202,7 +9971,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
9202
9971
|
};
|
|
9203
9972
|
|
|
9204
9973
|
// src/response-map-preservation.ts
|
|
9205
|
-
var
|
|
9974
|
+
var import_node_buffer37 = require("buffer");
|
|
9206
9975
|
function toStringKeyMapPreservingValues(value) {
|
|
9207
9976
|
if (value == null) return void 0;
|
|
9208
9977
|
const result = {};
|
|
@@ -9212,7 +9981,7 @@ function toStringKeyMapPreservingValues(value) {
|
|
|
9212
9981
|
}
|
|
9213
9982
|
return result;
|
|
9214
9983
|
}
|
|
9215
|
-
if (typeof value === "object" && !Array.isArray(value) && !
|
|
9984
|
+
if (typeof value === "object" && !Array.isArray(value) && !import_node_buffer37.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
9216
9985
|
for (const [key, item] of Object.entries(value)) {
|
|
9217
9986
|
setOwnValue(result, text(key), normalizeMapStructurePreservingBytes(item));
|
|
9218
9987
|
}
|
|
@@ -9221,7 +9990,7 @@ function toStringKeyMapPreservingValues(value) {
|
|
|
9221
9990
|
return void 0;
|
|
9222
9991
|
}
|
|
9223
9992
|
function normalizeMapStructurePreservingBytes(value) {
|
|
9224
|
-
if (
|
|
9993
|
+
if (import_node_buffer37.Buffer.isBuffer(value) || value instanceof Uint8Array) return value;
|
|
9225
9994
|
if (value instanceof Map) {
|
|
9226
9995
|
const result = {};
|
|
9227
9996
|
for (const [key, item] of value.entries()) {
|
|
@@ -9243,7 +10012,7 @@ function normalizeMapStructurePreservingBytes(value) {
|
|
|
9243
10012
|
}
|
|
9244
10013
|
|
|
9245
10014
|
// src/native-kv-responses.ts
|
|
9246
|
-
var
|
|
10015
|
+
var import_node_buffer38 = require("buffer");
|
|
9247
10016
|
function rateLimitResultFromResp(value) {
|
|
9248
10017
|
if (!Array.isArray(value) || value.length !== 4) {
|
|
9249
10018
|
throw new TypeError("RATELIMIT.ADD returned an unexpected response");
|
|
@@ -9300,13 +10069,13 @@ function fetchOrComputeResultFromResp(value, codec) {
|
|
|
9300
10069
|
}
|
|
9301
10070
|
function decodePayload(codec, value) {
|
|
9302
10071
|
if (value == null) return null;
|
|
9303
|
-
if (
|
|
9304
|
-
if (value instanceof Uint8Array) return codec.decode(
|
|
9305
|
-
if (typeof value === "string") return codec.decode(
|
|
10072
|
+
if (import_node_buffer38.Buffer.isBuffer(value)) return codec.decode(value);
|
|
10073
|
+
if (value instanceof Uint8Array) return codec.decode(import_node_buffer38.Buffer.from(value));
|
|
10074
|
+
if (typeof value === "string") return codec.decode(import_node_buffer38.Buffer.from(value));
|
|
9306
10075
|
return normalizeRefMeta(value);
|
|
9307
10076
|
}
|
|
9308
10077
|
function requiredResponseString(value, context) {
|
|
9309
|
-
if (typeof value !== "string" && !
|
|
10078
|
+
if (typeof value !== "string" && !import_node_buffer38.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
9310
10079
|
throw new TypeError(`${context} returned an unexpected response`);
|
|
9311
10080
|
}
|
|
9312
10081
|
const result = text(value);
|
|
@@ -9323,7 +10092,7 @@ function requiredNonNegativeInteger(value, context) {
|
|
|
9323
10092
|
return result;
|
|
9324
10093
|
}
|
|
9325
10094
|
function responseBytes(value, context) {
|
|
9326
|
-
if (typeof value !== "string" && !
|
|
10095
|
+
if (typeof value !== "string" && !import_node_buffer38.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
9327
10096
|
throw new TypeError(`${context} returned an unexpected response`);
|
|
9328
10097
|
}
|
|
9329
10098
|
return bytes(value);
|
|
@@ -9646,17 +10415,6 @@ function finiteNonNegativeInteger(value, fallback) {
|
|
|
9646
10415
|
function finiteNonNegativeNumber(value, fallback) {
|
|
9647
10416
|
return value == null || !Number.isFinite(value) ? fallback : Math.max(0, value);
|
|
9648
10417
|
}
|
|
9649
|
-
function appendReadOptions(args, options) {
|
|
9650
|
-
append(args, "COUNT", options.count);
|
|
9651
|
-
append(args, "PARTITION", options.partitionKey);
|
|
9652
|
-
append(args, "FROM_MS", options.fromMs);
|
|
9653
|
-
append(args, "TO_MS", options.toMs);
|
|
9654
|
-
appendBool(args, "REV", options.rev);
|
|
9655
|
-
append(args, "STATE", options.state);
|
|
9656
|
-
appendBool(args, "TERMINAL_ONLY", options.terminalOnly);
|
|
9657
|
-
appendBool(args, "INCLUDE_COLD", options.includeCold);
|
|
9658
|
-
appendBool(args, "CONSISTENT_PROJECTION", options.consistentProjection);
|
|
9659
|
-
}
|
|
9660
10418
|
function appendAttributeQueryOptions(args, options) {
|
|
9661
10419
|
append(args, "STATE", options.state);
|
|
9662
10420
|
append(args, "PARTITION", options.partitionKey);
|
|
@@ -9710,22 +10468,6 @@ function appendAttributes(args, attributes) {
|
|
|
9710
10468
|
args.push("ATTRIBUTE", name, value);
|
|
9711
10469
|
}
|
|
9712
10470
|
}
|
|
9713
|
-
function appendSearchStateMeta(args, state, stateMeta) {
|
|
9714
|
-
const entries = Object.entries(stateMeta ?? {});
|
|
9715
|
-
if (entries.length === 0) {
|
|
9716
|
-
return;
|
|
9717
|
-
}
|
|
9718
|
-
if (entries.every(([, value]) => isPlainObject5(value))) {
|
|
9719
|
-
for (const [metaState, values] of entries) {
|
|
9720
|
-
args.push("STATE_META", metaState, values);
|
|
9721
|
-
}
|
|
9722
|
-
return;
|
|
9723
|
-
}
|
|
9724
|
-
if (state == null) {
|
|
9725
|
-
throw new Error("search stateMeta filters require state or nested state metadata");
|
|
9726
|
-
}
|
|
9727
|
-
args.push("STATE_META", state, stateMeta);
|
|
9728
|
-
}
|
|
9729
10471
|
function normalizeAdminResponse(value) {
|
|
9730
10472
|
return normalizeRefMeta(value);
|
|
9731
10473
|
}
|
|
@@ -10033,7 +10775,7 @@ function groupAutoPartitionItems(items) {
|
|
|
10033
10775
|
}
|
|
10034
10776
|
|
|
10035
10777
|
// src/client-values.ts
|
|
10036
|
-
var
|
|
10778
|
+
var import_node_buffer39 = require("buffer");
|
|
10037
10779
|
async function valueMGetEntries(client, refs, options = {}) {
|
|
10038
10780
|
const refCount = refs.length;
|
|
10039
10781
|
if (refCount === 0) {
|
|
@@ -10068,12 +10810,12 @@ async function valueMGetEntries(client, refs, options = {}) {
|
|
|
10068
10810
|
const item = response[index];
|
|
10069
10811
|
if (item == null) {
|
|
10070
10812
|
entries[index] = { found: false };
|
|
10071
|
-
} else if (
|
|
10813
|
+
} else if (import_node_buffer39.Buffer.isBuffer(item)) {
|
|
10072
10814
|
entries[index] = { found: true, value: client.codec.decode(item) };
|
|
10073
10815
|
} else if (item instanceof Uint8Array) {
|
|
10074
|
-
entries[index] = { found: true, value: client.codec.decode(
|
|
10816
|
+
entries[index] = { found: true, value: client.codec.decode(import_node_buffer39.Buffer.from(item)) };
|
|
10075
10817
|
} else if (typeof item === "string") {
|
|
10076
|
-
entries[index] = { found: true, value: client.codec.decode(
|
|
10818
|
+
entries[index] = { found: true, value: client.codec.decode(import_node_buffer39.Buffer.from(item)) };
|
|
10077
10819
|
} else {
|
|
10078
10820
|
entries[index] = { found: true, value: item };
|
|
10079
10821
|
}
|
|
@@ -10082,10 +10824,10 @@ async function valueMGetEntries(client, refs, options = {}) {
|
|
|
10082
10824
|
}
|
|
10083
10825
|
|
|
10084
10826
|
// src/auto-batch.ts
|
|
10085
|
-
var
|
|
10827
|
+
var import_node_buffer41 = require("buffer");
|
|
10086
10828
|
|
|
10087
10829
|
// src/auto-batch-ordering.ts
|
|
10088
|
-
var
|
|
10830
|
+
var import_node_buffer40 = require("buffer");
|
|
10089
10831
|
function autoBatchOrderingPlan(batch) {
|
|
10090
10832
|
const accesses = /* @__PURE__ */ new Map();
|
|
10091
10833
|
const fallbackDependencies = [];
|
|
@@ -10200,13 +10942,13 @@ function flowManyAutoBatchIds(command, name) {
|
|
|
10200
10942
|
return fixedFlowItemIds(
|
|
10201
10943
|
command,
|
|
10202
10944
|
mixed ? 4 : 3,
|
|
10203
|
-
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) &&
|
|
10945
|
+
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) && import_node_buffer40.Buffer.isBuffer(command[itemIndex + (mixed ? 3 : 2)])
|
|
10204
10946
|
);
|
|
10205
10947
|
}
|
|
10206
10948
|
return fixedFlowItemIds(
|
|
10207
10949
|
command,
|
|
10208
10950
|
mixed ? 4 : 3,
|
|
10209
|
-
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) &&
|
|
10951
|
+
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer40.Buffer.isBuffer(command[itemIndex + (mixed ? 2 : 1)]) && isFencingToken(command[itemIndex + (mixed ? 3 : 2)])
|
|
10210
10952
|
);
|
|
10211
10953
|
}
|
|
10212
10954
|
function createManyAutoBatchIds(command) {
|
|
@@ -10219,7 +10961,7 @@ function createManyAutoBatchIds(command) {
|
|
|
10219
10961
|
const ids = fixedFlowItemIds(
|
|
10220
10962
|
command,
|
|
10221
10963
|
width,
|
|
10222
|
-
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) &&
|
|
10964
|
+
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer40.Buffer.isBuffer(command[itemIndex + width - 1]),
|
|
10223
10965
|
markerIndex
|
|
10224
10966
|
);
|
|
10225
10967
|
if (ids != null) return ids;
|
|
@@ -10237,7 +10979,7 @@ function extendedCreateManyAutoBatchIds(command, markerIndex) {
|
|
|
10237
10979
|
let cursor = markerIndex + 2;
|
|
10238
10980
|
for (let itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
|
|
10239
10981
|
const id = command[cursor];
|
|
10240
|
-
if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !
|
|
10982
|
+
if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !import_node_buffer40.Buffer.isBuffer(command[cursor + 2])) return void 0;
|
|
10241
10983
|
ids.push(id);
|
|
10242
10984
|
cursor += 3;
|
|
10243
10985
|
const afterValues = skipExtendedNamedItems(command, cursor, true);
|
|
@@ -10256,7 +10998,7 @@ function skipExtendedNamedItems(command, countIndex, encodedValues) {
|
|
|
10256
10998
|
for (let index = 0; index < count; index += 1) {
|
|
10257
10999
|
const name = command[firstItem + index * 2];
|
|
10258
11000
|
const value = command[firstItem + index * 2 + 1];
|
|
10259
|
-
if (!isAutoBatchResourceValue(name) || (encodedValues ? !
|
|
11001
|
+
if (!isAutoBatchResourceValue(name) || (encodedValues ? !import_node_buffer40.Buffer.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
|
|
10260
11002
|
}
|
|
10261
11003
|
return firstItem + count * 2;
|
|
10262
11004
|
}
|
|
@@ -10271,7 +11013,7 @@ function runStepsManyAutoBatchIds(command) {
|
|
|
10271
11013
|
ids.push(item);
|
|
10272
11014
|
continue;
|
|
10273
11015
|
}
|
|
10274
|
-
if (typeof item !== "object" || item == null || Array.isArray(item) ||
|
|
11016
|
+
if (typeof item !== "object" || item == null || Array.isArray(item) || import_node_buffer40.Buffer.isBuffer(item)) return void 0;
|
|
10275
11017
|
const id = item.id;
|
|
10276
11018
|
if (!isAutoBatchResourceValue(id)) return void 0;
|
|
10277
11019
|
ids.push(id);
|
|
@@ -10312,7 +11054,7 @@ function flowValuePutOwner(command, start) {
|
|
|
10312
11054
|
}
|
|
10313
11055
|
var flowValuePutOptionTokens = /* @__PURE__ */ new Set(["NAME", "NOW", "OVERRIDE", "OWNER_FLOW_ID", "PARTITION", "TTL", "TTL_MS"]);
|
|
10314
11056
|
function isAutoBatchResourceValue(value) {
|
|
10315
|
-
return typeof value === "string" ||
|
|
11057
|
+
return typeof value === "string" || import_node_buffer40.Buffer.isBuffer(value);
|
|
10316
11058
|
}
|
|
10317
11059
|
function isFencingToken(value) {
|
|
10318
11060
|
return typeof value === "number" && Number.isSafeInteger(value) || typeof value === "bigint";
|
|
@@ -10321,7 +11063,7 @@ function nonNegativeItemCount(value) {
|
|
|
10321
11063
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
10322
11064
|
}
|
|
10323
11065
|
function autoBatchResourceKey(namespace, value) {
|
|
10324
|
-
return `${namespace}:${
|
|
11066
|
+
return `${namespace}:${import_node_buffer40.Buffer.from(value).toString("base64")}`;
|
|
10325
11067
|
}
|
|
10326
11068
|
function autoBatchCommandName(command) {
|
|
10327
11069
|
return commandView(command).name ?? null;
|
|
@@ -10697,7 +11439,7 @@ async function hydrateClaimedRecords(claimed, concurrency, hydrate) {
|
|
|
10697
11439
|
const results = new Array(claimed.length);
|
|
10698
11440
|
let cursor = 0;
|
|
10699
11441
|
let failure;
|
|
10700
|
-
const
|
|
11442
|
+
const run2 = async () => {
|
|
10701
11443
|
while (failure == null) {
|
|
10702
11444
|
const index = cursor;
|
|
10703
11445
|
cursor += 1;
|
|
@@ -10710,7 +11452,7 @@ async function hydrateClaimedRecords(claimed, concurrency, hydrate) {
|
|
|
10710
11452
|
}
|
|
10711
11453
|
}
|
|
10712
11454
|
};
|
|
10713
|
-
await Promise.all(Array.from({ length: Math.min(concurrency, claimed.length) },
|
|
11455
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, claimed.length) }, run2));
|
|
10714
11456
|
if (failure != null) {
|
|
10715
11457
|
const hydratedItems = [];
|
|
10716
11458
|
for (let index = 0; index < results.length; index += 1) {
|
|
@@ -10730,55 +11472,1023 @@ function claimFailure(error) {
|
|
|
10730
11472
|
}
|
|
10731
11473
|
|
|
10732
11474
|
// src/client-flow-support.ts
|
|
10733
|
-
var
|
|
11475
|
+
var import_node_buffer52 = require("buffer");
|
|
10734
11476
|
|
|
10735
|
-
// src/
|
|
10736
|
-
var
|
|
11477
|
+
// src/flow-query-builder.ts
|
|
11478
|
+
var import_node_buffer43 = require("buffer");
|
|
10737
11479
|
|
|
10738
|
-
// src/
|
|
10739
|
-
var
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
11480
|
+
// src/flow-query-metadata.ts
|
|
11481
|
+
var import_node_buffer42 = require("buffer");
|
|
11482
|
+
var MAX_FLOW_QUERY_METADATA_KEY_BYTES = 64;
|
|
11483
|
+
function normalizeStateMeta(value, state) {
|
|
11484
|
+
if (value == null) return {};
|
|
11485
|
+
const entries = objectEntries(value, "stateMeta");
|
|
11486
|
+
if (entries.length === 0) return {};
|
|
11487
|
+
const nested = entries.map(([, item]) => isPlainRecord(item));
|
|
11488
|
+
if (nested.every(Boolean)) {
|
|
11489
|
+
return value;
|
|
10743
11490
|
}
|
|
10744
|
-
|
|
10745
|
-
}
|
|
10746
|
-
function clientNameResponse(response) {
|
|
10747
|
-
return response == null ? null : textResponse(response, "CLIENT GETNAME");
|
|
10748
|
-
}
|
|
10749
|
-
function fetchOrComputeCompletionToken(options) {
|
|
10750
|
-
if (options == null || !Object.hasOwn(options, "computeToken") || options.computeToken === void 0) {
|
|
11491
|
+
if (nested.some(Boolean)) {
|
|
10751
11492
|
throw new TypeError(
|
|
10752
|
-
"
|
|
11493
|
+
"stateMeta must be entirely flat or entirely nested by state"
|
|
10753
11494
|
);
|
|
10754
11495
|
}
|
|
10755
|
-
if (
|
|
10756
|
-
throw new TypeError(
|
|
11496
|
+
if (state == null || state === "" || state === "any") {
|
|
11497
|
+
throw new TypeError(
|
|
11498
|
+
"FLOW.QUERY stateMeta filters require state; a concrete state is required"
|
|
11499
|
+
);
|
|
10757
11500
|
}
|
|
10758
|
-
return
|
|
11501
|
+
return { [state]: value };
|
|
10759
11502
|
}
|
|
10760
|
-
function
|
|
10761
|
-
const
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
11503
|
+
function metadataEntries(value, context) {
|
|
11504
|
+
const entries = objectEntries(value ?? {}, context).map(([rawName, item]) => {
|
|
11505
|
+
const name = rawName.trim();
|
|
11506
|
+
const size = import_node_buffer42.Buffer.byteLength(name, "utf8");
|
|
11507
|
+
if (size === 0 || size > MAX_FLOW_QUERY_METADATA_KEY_BYTES || name.startsWith("__")) {
|
|
11508
|
+
throw new TypeError(`${context} key is invalid or reserved`);
|
|
11509
|
+
}
|
|
11510
|
+
return [name, item];
|
|
11511
|
+
});
|
|
11512
|
+
entries.sort(([left], [right]) => compareUnicodeScalars(left, right));
|
|
11513
|
+
for (let index = 1; index < entries.length; index += 1) {
|
|
11514
|
+
if (entries[index - 1]?.[0] === entries[index]?.[0]) {
|
|
11515
|
+
throw new TypeError(`${context} key is duplicated after normalization`);
|
|
11516
|
+
}
|
|
10765
11517
|
}
|
|
10766
|
-
return
|
|
11518
|
+
return entries;
|
|
10767
11519
|
}
|
|
10768
|
-
function
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
);
|
|
11520
|
+
function objectEntries(value, context) {
|
|
11521
|
+
if (!isPlainRecord(value))
|
|
11522
|
+
throw new TypeError(`${context} must be a plain object`);
|
|
11523
|
+
const keys = Reflect.ownKeys(value);
|
|
11524
|
+
if (keys.some((key) => typeof key !== "string")) {
|
|
11525
|
+
throw new TypeError(`${context} keys must be strings`);
|
|
11526
|
+
}
|
|
11527
|
+
return keys.map((key) => [key, value[key]]);
|
|
10772
11528
|
}
|
|
10773
|
-
function
|
|
10774
|
-
|
|
11529
|
+
function isPlainRecord(value) {
|
|
11530
|
+
if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer42.Buffer.isBuffer(value)) {
|
|
11531
|
+
return false;
|
|
11532
|
+
}
|
|
11533
|
+
const prototype = Object.getPrototypeOf(value);
|
|
11534
|
+
return prototype === null || prototype === Object.prototype;
|
|
11535
|
+
}
|
|
11536
|
+
function metadataSelector(root, ...names) {
|
|
11537
|
+
return root + names.map((name) => `['${name.replaceAll("'", "''")}']`).join("");
|
|
11538
|
+
}
|
|
11539
|
+
function compareUnicodeScalars(left, right) {
|
|
11540
|
+
let leftOffset = 0;
|
|
11541
|
+
let rightOffset = 0;
|
|
11542
|
+
while (leftOffset < left.length && rightOffset < right.length) {
|
|
11543
|
+
const leftCodePoint = left.codePointAt(leftOffset);
|
|
11544
|
+
const rightCodePoint = right.codePointAt(rightOffset);
|
|
11545
|
+
if (leftCodePoint == null || rightCodePoint == null) break;
|
|
11546
|
+
if (leftCodePoint !== rightCodePoint)
|
|
11547
|
+
return leftCodePoint < rightCodePoint ? -1 : 1;
|
|
11548
|
+
leftOffset += leftCodePoint > 65535 ? 2 : 1;
|
|
11549
|
+
rightOffset += rightCodePoint > 65535 ? 2 : 1;
|
|
11550
|
+
}
|
|
11551
|
+
return left.length === right.length ? 0 : leftOffset === left.length ? -1 : 1;
|
|
11552
|
+
}
|
|
11553
|
+
|
|
11554
|
+
// src/flow-query-builder.ts
|
|
11555
|
+
var MAX_FLOW_QUERY_RESULTS = 100;
|
|
11556
|
+
var MAX_FLOW_QUERY_PARTITION_BYTES = 65535;
|
|
11557
|
+
var MAX_FLOW_QUERY_TIME = Number.MAX_SAFE_INTEGER;
|
|
11558
|
+
var MAX_FLOW_QUERY_STATE_BYTES = 64;
|
|
11559
|
+
var FlowCollectionQuery = class {
|
|
11560
|
+
constructor(partitionKey, limit, reverse) {
|
|
11561
|
+
this.limit = limit;
|
|
11562
|
+
this.reverse = reverse;
|
|
11563
|
+
this.params.partition_key = partitionKey;
|
|
11564
|
+
}
|
|
11565
|
+
limit;
|
|
11566
|
+
reverse;
|
|
11567
|
+
params = /* @__PURE__ */ Object.create(null);
|
|
11568
|
+
predicates = ["partition_key = @partition_key"];
|
|
11569
|
+
orderField = "updated_at_ms";
|
|
11570
|
+
equality(selector, parameter, value) {
|
|
11571
|
+
this.params[parameter] = queryParameter(value, parameter);
|
|
11572
|
+
this.predicates.push(`${selector} = @${parameter}`);
|
|
11573
|
+
}
|
|
11574
|
+
window(fromMs, toMs) {
|
|
11575
|
+
if (fromMs == null && toMs == null) return;
|
|
11576
|
+
const lower = fromMs == null ? 0 : boundedTime(fromMs, "fromMs");
|
|
11577
|
+
const upper = toMs == null ? MAX_FLOW_QUERY_TIME : boundedTime(toMs, "toMs");
|
|
11578
|
+
if (lower > upper) throw new TypeError("fromMs must not exceed toMs");
|
|
11579
|
+
this.predicates.push("updated_at_ms BETWEEN @from_ms AND @to_ms");
|
|
11580
|
+
this.params.from_ms = lower;
|
|
11581
|
+
this.params.to_ms = upper;
|
|
11582
|
+
}
|
|
11583
|
+
metadata(root, values) {
|
|
11584
|
+
const entries = metadataEntries(values, root);
|
|
11585
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
11586
|
+
const entry = entries[index];
|
|
11587
|
+
if (entry == null) throw new TypeError("metadata entries must be dense");
|
|
11588
|
+
this.equality(
|
|
11589
|
+
metadataSelector(root, entry[0]),
|
|
11590
|
+
`${root}_${index}`,
|
|
11591
|
+
entry[1]
|
|
11592
|
+
);
|
|
11593
|
+
}
|
|
11594
|
+
}
|
|
11595
|
+
stateMetadata(values) {
|
|
11596
|
+
const entries = [];
|
|
11597
|
+
const states = /* @__PURE__ */ new Set();
|
|
11598
|
+
for (const [rawState, metadata] of objectEntries(values, "stateMeta")) {
|
|
11599
|
+
const state = requiredText(rawState, "stateMeta state").trim();
|
|
11600
|
+
const stateBytes = import_node_buffer43.Buffer.byteLength(state, "utf8");
|
|
11601
|
+
if (stateBytes === 0 || stateBytes > MAX_FLOW_QUERY_STATE_BYTES) {
|
|
11602
|
+
throw new TypeError(
|
|
11603
|
+
`stateMeta state names must be 1..${MAX_FLOW_QUERY_STATE_BYTES} bytes`
|
|
11604
|
+
);
|
|
11605
|
+
}
|
|
11606
|
+
if (states.has(state)) {
|
|
11607
|
+
throw new TypeError(
|
|
11608
|
+
"stateMeta state is duplicated after normalization"
|
|
11609
|
+
);
|
|
11610
|
+
}
|
|
11611
|
+
states.add(state);
|
|
11612
|
+
if (!isPlainRecord(metadata))
|
|
11613
|
+
throw new TypeError("stateMeta values must be metadata maps");
|
|
11614
|
+
for (const [name, value] of metadataEntries(metadata, "stateMeta")) {
|
|
11615
|
+
entries.push([state, name, value]);
|
|
11616
|
+
}
|
|
11617
|
+
}
|
|
11618
|
+
entries.sort(
|
|
11619
|
+
([leftState, leftName], [rightState, rightName]) => compareUnicodeScalars(leftState, rightState) || compareUnicodeScalars(leftName, rightName)
|
|
11620
|
+
);
|
|
11621
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
11622
|
+
const entry = entries[index];
|
|
11623
|
+
if (entry == null) throw new TypeError("stateMeta entries must be dense");
|
|
11624
|
+
this.equality(
|
|
11625
|
+
metadataSelector("state_meta", entry[0], entry[1]),
|
|
11626
|
+
`state_meta_${index}`,
|
|
11627
|
+
entry[2]
|
|
11628
|
+
);
|
|
11629
|
+
}
|
|
11630
|
+
}
|
|
11631
|
+
build() {
|
|
11632
|
+
if (this.predicates.length > 12) {
|
|
11633
|
+
throw new TypeError("FLOW.QUERY accepts at most 12 predicates");
|
|
11634
|
+
}
|
|
11635
|
+
const direction = this.reverse ? "DESC" : "ASC";
|
|
11636
|
+
const query = `FROM runs WHERE ${this.predicates.join(" AND ")} ORDER BY ${this.orderField} ${direction} LIMIT ${this.limit} RETURN RECORDS`;
|
|
11637
|
+
validateFlowQueryText(query);
|
|
11638
|
+
return { query, params: this.params };
|
|
11639
|
+
}
|
|
11640
|
+
};
|
|
11641
|
+
function buildFlowListQuery(type, options) {
|
|
11642
|
+
const attributeCount = Object.keys(options.attributes ?? {}).length;
|
|
11643
|
+
if (type === "any" && attributeCount === 0) {
|
|
11644
|
+
throw new TypeError(
|
|
11645
|
+
"FLOW.QUERY list requires a concrete flow type or an attribute predicate"
|
|
11646
|
+
);
|
|
11647
|
+
}
|
|
11648
|
+
if (options.terminalOnly !== true && options.state === "any" && attributeCount === 0) {
|
|
11649
|
+
throw new TypeError(
|
|
11650
|
+
"FLOW.QUERY list state any requires an attribute predicate"
|
|
11651
|
+
);
|
|
11652
|
+
}
|
|
11653
|
+
const builder = queryBuilder(options);
|
|
11654
|
+
addType(builder, type);
|
|
11655
|
+
if (options.terminalOnly === true) {
|
|
11656
|
+
addTerminalState(builder, options.state);
|
|
11657
|
+
} else if (options.state == null || options.state === "") {
|
|
11658
|
+
builder.equality("state", "state", "queued");
|
|
11659
|
+
} else if (options.state !== "any") {
|
|
11660
|
+
builder.equality("state", "state", requiredText(options.state, "state"));
|
|
11661
|
+
}
|
|
11662
|
+
builder.metadata("attribute", options.attributes);
|
|
11663
|
+
builder.window(options.fromMs, options.toMs);
|
|
11664
|
+
return builder.build();
|
|
11665
|
+
}
|
|
11666
|
+
function buildFlowSearchQuery(type, options) {
|
|
11667
|
+
const stateMeta = normalizeStateMeta(options.stateMeta, options.state);
|
|
11668
|
+
if (Object.keys(options.attributes ?? {}).length === 0 && Object.keys(stateMeta).length === 0) {
|
|
11669
|
+
throw new TypeError(
|
|
11670
|
+
"FLOW.QUERY search requires an attribute or stateMeta predicate"
|
|
11671
|
+
);
|
|
11672
|
+
}
|
|
11673
|
+
if ((type === "" || type === "any") && Object.keys(stateMeta).length > 0) {
|
|
11674
|
+
throw new TypeError(
|
|
11675
|
+
"FLOW.QUERY stateMeta predicates require a concrete flow type"
|
|
11676
|
+
);
|
|
11677
|
+
}
|
|
11678
|
+
const builder = queryBuilder(options);
|
|
11679
|
+
if (type !== "" && type !== "any")
|
|
11680
|
+
builder.equality("type", "type", requiredText(type, "type"));
|
|
11681
|
+
if (options.terminalOnly === true) {
|
|
11682
|
+
addTerminalState(builder, options.state);
|
|
11683
|
+
} else if (options.state != null && options.state !== "" && options.state !== "any") {
|
|
11684
|
+
builder.equality("state", "state", requiredText(options.state, "state"));
|
|
11685
|
+
}
|
|
11686
|
+
builder.metadata("attribute", options.attributes);
|
|
11687
|
+
builder.stateMetadata(stateMeta);
|
|
11688
|
+
builder.window(options.fromMs, options.toMs);
|
|
11689
|
+
return builder.build();
|
|
11690
|
+
}
|
|
11691
|
+
function buildFlowTerminalQuery(type, options) {
|
|
11692
|
+
if (requiredText(type, "type") === "any") {
|
|
11693
|
+
throw new TypeError("FLOW.QUERY terminals require a concrete flow type");
|
|
11694
|
+
}
|
|
11695
|
+
if (metadataEntries(options.attributes, "attribute").length > 0) {
|
|
11696
|
+
throw new TypeError(
|
|
11697
|
+
"FLOW.QUERY terminals do not support attribute predicates"
|
|
11698
|
+
);
|
|
11699
|
+
}
|
|
11700
|
+
const builder = queryBuilder(options);
|
|
11701
|
+
addType(builder, type);
|
|
11702
|
+
addTerminalState(builder, options.state);
|
|
11703
|
+
builder.window(options.fromMs, options.toMs);
|
|
11704
|
+
return builder.build();
|
|
11705
|
+
}
|
|
11706
|
+
function buildFlowFailureQuery(type, options) {
|
|
11707
|
+
if (options.state != null && options.state !== "" && options.state !== "any" && options.state !== "failed") {
|
|
11708
|
+
throw new TypeError("FLOW failures state must be failed or any");
|
|
11709
|
+
}
|
|
11710
|
+
return buildFlowListQuery(type, {
|
|
11711
|
+
...options,
|
|
11712
|
+
state: "failed",
|
|
11713
|
+
terminalOnly: false
|
|
11714
|
+
});
|
|
11715
|
+
}
|
|
11716
|
+
function buildFlowLineageQuery(selector, id, options) {
|
|
11717
|
+
if (options.terminalOnly === true) {
|
|
11718
|
+
throw new TypeError("terminalOnly cannot be combined with a lineage query");
|
|
11719
|
+
}
|
|
11720
|
+
if (metadataEntries(options.attributes, "attribute").length > 0) {
|
|
11721
|
+
throw new TypeError(
|
|
11722
|
+
"FLOW.QUERY lineage does not support attribute predicates"
|
|
11723
|
+
);
|
|
11724
|
+
}
|
|
11725
|
+
const builder = queryBuilder(options);
|
|
11726
|
+
builder.equality(selector, "lineage_id", requiredText(id, "lineage id"));
|
|
11727
|
+
if (options.state != null && options.state !== "" && options.state !== "any") {
|
|
11728
|
+
builder.equality("state", "state", requiredText(options.state, "state"));
|
|
11729
|
+
}
|
|
11730
|
+
builder.metadata("attribute", options.attributes);
|
|
11731
|
+
builder.window(options.fromMs, options.toMs);
|
|
11732
|
+
return builder.build();
|
|
11733
|
+
}
|
|
11734
|
+
function buildFlowStuckQuery(type, options) {
|
|
11735
|
+
const concreteType = requiredText(type, "type");
|
|
11736
|
+
if (concreteType === "any") {
|
|
11737
|
+
throw new TypeError("FLOW.QUERY stuck requires a concrete flow type");
|
|
11738
|
+
}
|
|
11739
|
+
const now = options.nowMs == null ? Date.now() : boundedTime(options.nowMs, "nowMs");
|
|
11740
|
+
const older = options.olderThanMs == null ? 0 : boundedTime(options.olderThanMs, "olderThanMs");
|
|
11741
|
+
const cutoff = now - older;
|
|
11742
|
+
if (cutoff < 0) throw new TypeError("olderThanMs must not exceed nowMs");
|
|
11743
|
+
const builder = new FlowCollectionQuery(
|
|
11744
|
+
requiredPartition(options.partitionKey),
|
|
11745
|
+
boundedCount(options.count),
|
|
11746
|
+
false
|
|
11747
|
+
);
|
|
11748
|
+
builder.orderField = "lease_deadline_ms";
|
|
11749
|
+
builder.equality("type", "type", concreteType);
|
|
11750
|
+
builder.equality("state", "state", "running");
|
|
11751
|
+
builder.predicates.push(
|
|
11752
|
+
"lease_deadline_ms BETWEEN @lease_from_ms AND @lease_to_ms"
|
|
11753
|
+
);
|
|
11754
|
+
builder.params.lease_from_ms = 0;
|
|
11755
|
+
builder.params.lease_to_ms = cutoff;
|
|
11756
|
+
return builder.build();
|
|
11757
|
+
}
|
|
11758
|
+
function queryBuilder(options) {
|
|
11759
|
+
if (options.includeCold === true)
|
|
11760
|
+
throw new TypeError("FLOW.QUERY does not expose includeCold");
|
|
11761
|
+
if (options.consistentProjection === true) {
|
|
11762
|
+
throw new TypeError("FLOW.QUERY does not expose consistentProjection");
|
|
11763
|
+
}
|
|
11764
|
+
if (options.rev != null && typeof options.rev !== "boolean") {
|
|
11765
|
+
throw new TypeError("rev must be boolean");
|
|
11766
|
+
}
|
|
11767
|
+
return new FlowCollectionQuery(
|
|
11768
|
+
requiredPartition(options.partitionKey),
|
|
11769
|
+
boundedCount(options.count),
|
|
11770
|
+
options.rev !== false
|
|
11771
|
+
);
|
|
11772
|
+
}
|
|
11773
|
+
function requiredPartition(value) {
|
|
11774
|
+
if (typeof value !== "string") {
|
|
11775
|
+
throw new TypeError(
|
|
11776
|
+
"FLOW.QUERY convenience methods require a partition key"
|
|
11777
|
+
);
|
|
11778
|
+
}
|
|
11779
|
+
const size = import_node_buffer43.Buffer.byteLength(value, "utf8");
|
|
11780
|
+
if (size === 0 || size > MAX_FLOW_QUERY_PARTITION_BYTES) {
|
|
11781
|
+
throw new TypeError(
|
|
11782
|
+
`FLOW.QUERY partition key must be 1..${MAX_FLOW_QUERY_PARTITION_BYTES} bytes`
|
|
11783
|
+
);
|
|
11784
|
+
}
|
|
11785
|
+
return value;
|
|
11786
|
+
}
|
|
11787
|
+
function boundedCount(value) {
|
|
11788
|
+
if (value == null) return MAX_FLOW_QUERY_RESULTS;
|
|
11789
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_FLOW_QUERY_RESULTS) {
|
|
11790
|
+
throw new TypeError(
|
|
11791
|
+
`FLOW.QUERY limit must be between 1 and ${MAX_FLOW_QUERY_RESULTS}`
|
|
11792
|
+
);
|
|
11793
|
+
}
|
|
11794
|
+
return value;
|
|
11795
|
+
}
|
|
11796
|
+
function boundedTime(value, name) {
|
|
11797
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > MAX_FLOW_QUERY_TIME) {
|
|
11798
|
+
throw new TypeError(`${name} must be a non-negative safe integer`);
|
|
11799
|
+
}
|
|
11800
|
+
return value;
|
|
11801
|
+
}
|
|
11802
|
+
function addType(builder, type) {
|
|
11803
|
+
const normalized = requiredText(type, "type");
|
|
11804
|
+
if (normalized !== "any") builder.equality("type", "type", normalized);
|
|
11805
|
+
}
|
|
11806
|
+
function addTerminalState(builder, state) {
|
|
11807
|
+
if (state == null || state === "" || state === "any") {
|
|
11808
|
+
builder.predicates.push("state IN (@terminal_0, @terminal_1, @terminal_2)");
|
|
11809
|
+
builder.params.terminal_0 = "completed";
|
|
11810
|
+
builder.params.terminal_1 = "failed";
|
|
11811
|
+
builder.params.terminal_2 = "cancelled";
|
|
11812
|
+
} else if (state === "completed" || state === "failed" || state === "cancelled") {
|
|
11813
|
+
builder.equality("state", "state", state);
|
|
11814
|
+
} else {
|
|
11815
|
+
throw new TypeError(
|
|
11816
|
+
"terminal state must be completed, failed, cancelled, or any"
|
|
11817
|
+
);
|
|
11818
|
+
}
|
|
11819
|
+
}
|
|
11820
|
+
function requiredText(value, context) {
|
|
11821
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
11822
|
+
throw new TypeError(`${context} must be non-empty text`);
|
|
11823
|
+
}
|
|
11824
|
+
return value;
|
|
11825
|
+
}
|
|
11826
|
+
function queryParameter(value, context) {
|
|
11827
|
+
if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || import_node_buffer43.Buffer.isBuffer(value)) {
|
|
11828
|
+
return value;
|
|
11829
|
+
}
|
|
11830
|
+
throw new TypeError(`${context} must be a scalar FLOW.QUERY parameter`);
|
|
11831
|
+
}
|
|
11832
|
+
|
|
11833
|
+
// src/flow-query-response.ts
|
|
11834
|
+
var import_node_buffer45 = require("buffer");
|
|
11835
|
+
|
|
11836
|
+
// src/flow-query-response-validation.ts
|
|
11837
|
+
var import_node_buffer44 = require("buffer");
|
|
11838
|
+
function requiredMap2(value, context) {
|
|
11839
|
+
if (value instanceof Map) return value;
|
|
11840
|
+
if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer44.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
11841
|
+
throw decodeError(`${context} must be a map`, value);
|
|
11842
|
+
}
|
|
11843
|
+
return value;
|
|
11844
|
+
}
|
|
11845
|
+
function freezeMap(value) {
|
|
11846
|
+
const output = /* @__PURE__ */ Object.create(null);
|
|
11847
|
+
const entries = value instanceof Map ? value.entries() : Object.entries(value);
|
|
11848
|
+
for (const [rawKey, item] of entries) {
|
|
11849
|
+
const key = strictText2(rawKey);
|
|
11850
|
+
if (key == null || Object.hasOwn(output, key)) {
|
|
11851
|
+
throw decodeError(
|
|
11852
|
+
"server response map contains an invalid or duplicate key",
|
|
11853
|
+
value
|
|
11854
|
+
);
|
|
11855
|
+
}
|
|
11856
|
+
output[key] = item;
|
|
11857
|
+
}
|
|
11858
|
+
return Object.freeze(output);
|
|
11859
|
+
}
|
|
11860
|
+
function freezeMetadataMap(value, context) {
|
|
11861
|
+
return normalizeMetadataMap(
|
|
11862
|
+
value,
|
|
11863
|
+
context,
|
|
11864
|
+
{ remaining: DEFAULT_MAX_VALUE_ITEMS },
|
|
11865
|
+
/* @__PURE__ */ new Set(),
|
|
11866
|
+
0
|
|
11867
|
+
);
|
|
11868
|
+
}
|
|
11869
|
+
function normalizeMetadataMap(value, context, budget, ancestors, depth) {
|
|
11870
|
+
enterMetadataContainer(value, context, budget, ancestors, depth);
|
|
11871
|
+
try {
|
|
11872
|
+
const output = /* @__PURE__ */ Object.create(null);
|
|
11873
|
+
const entries = value instanceof Map ? value.entries() : Object.entries(value);
|
|
11874
|
+
for (const [rawKey, item] of entries) {
|
|
11875
|
+
const key = strictText2(rawKey);
|
|
11876
|
+
if (key == null || Object.hasOwn(output, key)) {
|
|
11877
|
+
throw decodeError(`${context} contains an invalid or duplicate key`, value);
|
|
11878
|
+
}
|
|
11879
|
+
output[key] = normalizeMetadataValue(
|
|
11880
|
+
item,
|
|
11881
|
+
`${context}.${key}`,
|
|
11882
|
+
budget,
|
|
11883
|
+
ancestors,
|
|
11884
|
+
depth + 1
|
|
11885
|
+
);
|
|
11886
|
+
}
|
|
11887
|
+
return Object.freeze(output);
|
|
11888
|
+
} finally {
|
|
11889
|
+
ancestors.delete(value);
|
|
11890
|
+
}
|
|
11891
|
+
}
|
|
11892
|
+
function normalizeMetadataValue(value, context, budget, ancestors, depth) {
|
|
11893
|
+
if (typeof value === "string") {
|
|
11894
|
+
if (!value.isWellFormed()) throw decodeError(`${context} contains invalid text`, value);
|
|
11895
|
+
return value;
|
|
11896
|
+
}
|
|
11897
|
+
if (import_node_buffer44.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
11898
|
+
const decoded = strictText2(value);
|
|
11899
|
+
if (decoded == null) throw decodeError(`${context} contains invalid UTF-8`, value);
|
|
11900
|
+
return decoded;
|
|
11901
|
+
}
|
|
11902
|
+
if (value == null || typeof value === "boolean" || typeof value === "number" || typeof value === "bigint") {
|
|
11903
|
+
return value;
|
|
11904
|
+
}
|
|
11905
|
+
if (Array.isArray(value)) {
|
|
11906
|
+
enterMetadataContainer(value, context, budget, ancestors, depth);
|
|
11907
|
+
try {
|
|
11908
|
+
const output = new Array(value.length);
|
|
11909
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
11910
|
+
if (!Object.hasOwn(value, index)) {
|
|
11911
|
+
throw decodeError(`${context} must be a dense array`, value);
|
|
11912
|
+
}
|
|
11913
|
+
output[index] = normalizeMetadataValue(
|
|
11914
|
+
value[index],
|
|
11915
|
+
`${context}[${index}]`,
|
|
11916
|
+
budget,
|
|
11917
|
+
ancestors,
|
|
11918
|
+
depth + 1
|
|
11919
|
+
);
|
|
11920
|
+
}
|
|
11921
|
+
return Object.freeze(output);
|
|
11922
|
+
} finally {
|
|
11923
|
+
ancestors.delete(value);
|
|
11924
|
+
}
|
|
11925
|
+
}
|
|
11926
|
+
if (value instanceof Map) {
|
|
11927
|
+
return normalizeMetadataMap(value, context, budget, ancestors, depth);
|
|
11928
|
+
}
|
|
11929
|
+
if (isPlainObject6(value)) {
|
|
11930
|
+
return normalizeMetadataMap(value, context, budget, ancestors, depth);
|
|
11931
|
+
}
|
|
11932
|
+
throw decodeError(`${context} contains an unsupported value`, value);
|
|
11933
|
+
}
|
|
11934
|
+
function enterMetadataContainer(value, context, budget, ancestors, depth) {
|
|
11935
|
+
if (depth >= DEFAULT_MAX_VALUE_DEPTH) {
|
|
11936
|
+
throw decodeError(`${context} exceeds the maximum metadata depth`, value);
|
|
11937
|
+
}
|
|
11938
|
+
if (ancestors.has(value)) throw decodeError(`${context} contains a cycle`, value);
|
|
11939
|
+
const size = Array.isArray(value) ? value.length : value instanceof Map ? value.size : Object.keys(value).length;
|
|
11940
|
+
if (size > budget.remaining) {
|
|
11941
|
+
throw decodeError(`${context} exceeds the maximum metadata items`, value);
|
|
11942
|
+
}
|
|
11943
|
+
budget.remaining -= size;
|
|
11944
|
+
ancestors.add(value);
|
|
11945
|
+
}
|
|
11946
|
+
function isPlainObject6(value) {
|
|
11947
|
+
const prototype = Object.getPrototypeOf(value);
|
|
11948
|
+
return prototype === Object.prototype || prototype === null;
|
|
11949
|
+
}
|
|
11950
|
+
function requireContract(mapping, name, expected, context) {
|
|
11951
|
+
const actual = requiredText2(mapping, name, context);
|
|
11952
|
+
if (actual !== expected) {
|
|
11953
|
+
throw decodeError(
|
|
11954
|
+
`${context} has unsupported contract ${JSON.stringify(actual)}`,
|
|
11955
|
+
mapping
|
|
11956
|
+
);
|
|
11957
|
+
}
|
|
11958
|
+
}
|
|
11959
|
+
function requiredText2(mapping, name, context) {
|
|
11960
|
+
const value = strictText2(field(mapping, name));
|
|
11961
|
+
if (value == null || value.length === 0) {
|
|
11962
|
+
throw decodeError(`${context} ${name} must be non-empty text`, mapping);
|
|
11963
|
+
}
|
|
11964
|
+
return value;
|
|
11965
|
+
}
|
|
11966
|
+
function optionalText2(mapping, name, context) {
|
|
11967
|
+
const raw = field(mapping, name);
|
|
11968
|
+
if (raw == null) return void 0;
|
|
11969
|
+
const value = strictText2(raw);
|
|
11970
|
+
if (value == null)
|
|
11971
|
+
throw decodeError(`${context} ${name} must be text`, mapping);
|
|
11972
|
+
return value;
|
|
11973
|
+
}
|
|
11974
|
+
function requiredBoundedText2(mapping, name, context, maximumBytes) {
|
|
11975
|
+
const value = requiredText2(mapping, name, context);
|
|
11976
|
+
if (import_node_buffer44.Buffer.byteLength(value, "utf8") > maximumBytes) {
|
|
11977
|
+
throw decodeError(
|
|
11978
|
+
`${context} ${name} exceeds ${maximumBytes} bytes`,
|
|
11979
|
+
mapping
|
|
11980
|
+
);
|
|
11981
|
+
}
|
|
11982
|
+
return value;
|
|
11983
|
+
}
|
|
11984
|
+
function boundedText(value, context, maximumBytes) {
|
|
11985
|
+
const decoded = strictText2(value);
|
|
11986
|
+
if (decoded == null || decoded.length === 0) {
|
|
11987
|
+
throw decodeError(`${context} must be non-empty text`, value);
|
|
11988
|
+
}
|
|
11989
|
+
if (import_node_buffer44.Buffer.byteLength(decoded, "utf8") > maximumBytes) {
|
|
11990
|
+
throw decodeError(`${context} exceeds ${maximumBytes} bytes`, value);
|
|
11991
|
+
}
|
|
11992
|
+
return decoded;
|
|
11993
|
+
}
|
|
11994
|
+
function requiredBoolean(mapping, name, context) {
|
|
11995
|
+
const value = field(mapping, name);
|
|
11996
|
+
if (typeof value !== "boolean") {
|
|
11997
|
+
throw decodeError(`${context} ${name} must be boolean`, mapping);
|
|
11998
|
+
}
|
|
11999
|
+
return value;
|
|
12000
|
+
}
|
|
12001
|
+
function nonNegativeInteger(value, context) {
|
|
12002
|
+
if (typeof value === "bigint") {
|
|
12003
|
+
if (value >= 0n && value <= BigInt(Number.MAX_SAFE_INTEGER))
|
|
12004
|
+
return Number(value);
|
|
12005
|
+
} else if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) {
|
|
12006
|
+
return value;
|
|
12007
|
+
}
|
|
12008
|
+
throw decodeError(`${context} must be a non-negative safe integer`, value);
|
|
12009
|
+
}
|
|
12010
|
+
function positiveInteger(value, context) {
|
|
12011
|
+
const parsed = nonNegativeInteger(value, context);
|
|
12012
|
+
if (parsed === 0) throw decodeError(`${context} must be positive`, value);
|
|
12013
|
+
return parsed;
|
|
12014
|
+
}
|
|
12015
|
+
function boundedInteger(value, maximum, context) {
|
|
12016
|
+
let parsed;
|
|
12017
|
+
if (typeof value === "bigint") {
|
|
12018
|
+
parsed = value;
|
|
12019
|
+
} else if (typeof value === "number" && Number.isSafeInteger(value)) {
|
|
12020
|
+
parsed = BigInt(value);
|
|
12021
|
+
} else {
|
|
12022
|
+
throw decodeError(
|
|
12023
|
+
`${context} must be a lossless non-negative integer`,
|
|
12024
|
+
value
|
|
12025
|
+
);
|
|
12026
|
+
}
|
|
12027
|
+
if (parsed < 0n || parsed > maximum) {
|
|
12028
|
+
throw decodeError(
|
|
12029
|
+
`${context} is outside its supported integer range`,
|
|
12030
|
+
value
|
|
12031
|
+
);
|
|
12032
|
+
}
|
|
12033
|
+
return parsed <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(parsed) : parsed;
|
|
12034
|
+
}
|
|
12035
|
+
function positiveBoundedInteger(value, maximum, context) {
|
|
12036
|
+
const parsed = boundedInteger(value, maximum, context);
|
|
12037
|
+
if (parsed === 0) throw decodeError(`${context} must be positive`, value);
|
|
12038
|
+
return parsed;
|
|
12039
|
+
}
|
|
12040
|
+
function hasKey(mapping, name) {
|
|
12041
|
+
if (!(mapping instanceof Map)) return Object.hasOwn(mapping, name);
|
|
12042
|
+
if (mapping.has(name)) return true;
|
|
12043
|
+
const binaryName = import_node_buffer44.Buffer.from(name);
|
|
12044
|
+
for (const key of mapping.keys()) {
|
|
12045
|
+
if (import_node_buffer44.Buffer.isBuffer(key) && key.equals(binaryName)) return true;
|
|
12046
|
+
if (key instanceof Uint8Array && import_node_buffer44.Buffer.from(key).equals(binaryName))
|
|
12047
|
+
return true;
|
|
12048
|
+
}
|
|
12049
|
+
return false;
|
|
12050
|
+
}
|
|
12051
|
+
function decodeError(message, raw) {
|
|
12052
|
+
return new FerricStoreError(`invalid server response: ${message}`, { raw });
|
|
12053
|
+
}
|
|
12054
|
+
function strictText2(value) {
|
|
12055
|
+
if (typeof value === "string")
|
|
12056
|
+
return value.isWellFormed() ? value : void 0;
|
|
12057
|
+
if (import_node_buffer44.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
12058
|
+
try {
|
|
12059
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
12060
|
+
} catch {
|
|
12061
|
+
return void 0;
|
|
12062
|
+
}
|
|
12063
|
+
}
|
|
12064
|
+
return void 0;
|
|
12065
|
+
}
|
|
12066
|
+
|
|
12067
|
+
// src/flow-query-types.ts
|
|
12068
|
+
var FlowQueryError = class extends FerricStoreError {
|
|
12069
|
+
code;
|
|
12070
|
+
detail;
|
|
12071
|
+
hint;
|
|
12072
|
+
position;
|
|
12073
|
+
context;
|
|
12074
|
+
constructor(options) {
|
|
12075
|
+
super(options.message, {
|
|
12076
|
+
cause: options.cause,
|
|
12077
|
+
raw: options.raw,
|
|
12078
|
+
retryable: options.retryable,
|
|
12079
|
+
safeToRetry: options.safeToRetry,
|
|
12080
|
+
retryAfterMs: options.retryAfterMs
|
|
12081
|
+
});
|
|
12082
|
+
this.code = options.code;
|
|
12083
|
+
this.detail = options.detail;
|
|
12084
|
+
this.hint = options.hint;
|
|
12085
|
+
this.position = options.position;
|
|
12086
|
+
this.context = options.context;
|
|
12087
|
+
}
|
|
12088
|
+
};
|
|
12089
|
+
|
|
12090
|
+
// src/flow-query-response.ts
|
|
12091
|
+
var FLOW_QUERY_RESULT_CONTRACT = "ferric.flow.query.result/v1";
|
|
12092
|
+
var FLOW_EXPLAIN_CONTRACT = "ferric.flow.explain/v1";
|
|
12093
|
+
var FLOW_QUERY_INDEXES_CONTRACT = "ferric.flow.query.indexes/v1";
|
|
12094
|
+
var USAGE_FIELDS2 = [
|
|
12095
|
+
["range_seeks", "rangeSeeks"],
|
|
12096
|
+
["range_pages", "rangePages"],
|
|
12097
|
+
["scanned_entries", "scannedEntries"],
|
|
12098
|
+
["scanned_bytes", "scannedBytes"],
|
|
12099
|
+
["hydrated_records", "hydratedRecords"],
|
|
12100
|
+
["residual_checks", "residualChecks"],
|
|
12101
|
+
["duplicate_entries", "duplicateEntries"],
|
|
12102
|
+
["result_records", "resultRecords"],
|
|
12103
|
+
["response_bytes", "responseBytes"],
|
|
12104
|
+
["memory_high_water_bytes", "memoryHighWaterBytes"],
|
|
12105
|
+
["wall_time_us", "wallTimeUs"]
|
|
12106
|
+
];
|
|
12107
|
+
var MAX_SIGNED_64 = (1n << 63n) - 1n;
|
|
12108
|
+
var MAX_UNSIGNED_64 = (1n << 64n) - 1n;
|
|
12109
|
+
function decodeFlowQueryResult(value) {
|
|
12110
|
+
const result = decodeFlowQueryResponse(value, (mapping) => freezeMap(mapping));
|
|
12111
|
+
if (result.kind === "records") {
|
|
12112
|
+
return Object.freeze({
|
|
12113
|
+
kind: "records",
|
|
12114
|
+
version: FLOW_QUERY_RESULT_CONTRACT,
|
|
12115
|
+
records: Object.freeze(result.records),
|
|
12116
|
+
page: result.page,
|
|
12117
|
+
quality: result.quality,
|
|
12118
|
+
usage: result.usage,
|
|
12119
|
+
raw: result.raw
|
|
12120
|
+
});
|
|
12121
|
+
}
|
|
12122
|
+
return Object.freeze({
|
|
12123
|
+
kind: "count",
|
|
12124
|
+
version: FLOW_QUERY_RESULT_CONTRACT,
|
|
12125
|
+
count: result.count,
|
|
12126
|
+
quality: result.quality,
|
|
12127
|
+
usage: result.usage,
|
|
12128
|
+
raw: result.raw
|
|
12129
|
+
});
|
|
12130
|
+
}
|
|
12131
|
+
function decodeFlowQueryRecords(value, decodeRecord) {
|
|
12132
|
+
const result = decodeFlowQueryResponse(
|
|
12133
|
+
value,
|
|
12134
|
+
(mapping, index) => decodeRecord(mapping instanceof Map ? freezeMap(mapping) : mapping, index)
|
|
12135
|
+
);
|
|
12136
|
+
if (result.kind === "count") {
|
|
12137
|
+
throw new FerricStoreError("Flow record convenience query returned a count result", {
|
|
12138
|
+
raw: result.raw
|
|
12139
|
+
});
|
|
12140
|
+
}
|
|
12141
|
+
return result.records;
|
|
12142
|
+
}
|
|
12143
|
+
function decodeFlowQueryResponse(value, decodeRecord) {
|
|
12144
|
+
const mapping = requiredMap2(value, "FLOW.QUERY result");
|
|
12145
|
+
requireContract(mapping, "version", FLOW_QUERY_RESULT_CONTRACT, "FLOW.QUERY result");
|
|
12146
|
+
const quality = decodeQuality(field(mapping, "quality"));
|
|
12147
|
+
const usage = decodeUsage(field(mapping, "usage"));
|
|
12148
|
+
const hasRecords = hasKey(mapping, "records");
|
|
12149
|
+
const hasCount = hasKey(mapping, "result");
|
|
12150
|
+
if (hasRecords === hasCount) {
|
|
12151
|
+
throw decodeError("FLOW.QUERY result must contain exactly one records or count shape", value);
|
|
12152
|
+
}
|
|
12153
|
+
const raw = freezeMap(mapping);
|
|
12154
|
+
if (hasRecords) {
|
|
12155
|
+
const rawRecords = field(mapping, "records");
|
|
12156
|
+
if (!Array.isArray(rawRecords) || rawRecords.length > 100) {
|
|
12157
|
+
throw decodeError("FLOW.QUERY records must be an array of at most 100 maps", value);
|
|
12158
|
+
}
|
|
12159
|
+
const records = new Array(rawRecords.length);
|
|
12160
|
+
for (let index = 0; index < rawRecords.length; index += 1) {
|
|
12161
|
+
if (!Object.hasOwn(rawRecords, index)) {
|
|
12162
|
+
throw decodeError("FLOW.QUERY records must be a dense array", value);
|
|
12163
|
+
}
|
|
12164
|
+
records[index] = decodeRecord(
|
|
12165
|
+
requiredMap2(rawRecords[index], `FLOW.QUERY record ${index}`),
|
|
12166
|
+
index
|
|
12167
|
+
);
|
|
12168
|
+
}
|
|
12169
|
+
if (usage.resultRecords !== records.length) {
|
|
12170
|
+
throw decodeError("FLOW.QUERY usage result_records does not match records", value);
|
|
12171
|
+
}
|
|
12172
|
+
return {
|
|
12173
|
+
kind: "records",
|
|
12174
|
+
records,
|
|
12175
|
+
page: decodePage(field(mapping, "page")),
|
|
12176
|
+
quality,
|
|
12177
|
+
usage,
|
|
12178
|
+
raw
|
|
12179
|
+
};
|
|
12180
|
+
}
|
|
12181
|
+
if (hasKey(mapping, "page")) {
|
|
12182
|
+
throw decodeError("FLOW.QUERY count result contains an unexpected page", value);
|
|
12183
|
+
}
|
|
12184
|
+
const countResult = requiredMap2(field(mapping, "result"), "FLOW.QUERY count result");
|
|
12185
|
+
if (requiredText2(countResult, "kind", "FLOW.QUERY count result") !== "count") {
|
|
12186
|
+
throw decodeError("FLOW.QUERY count result kind must be count", value);
|
|
12187
|
+
}
|
|
12188
|
+
const count = boundedInteger(
|
|
12189
|
+
field(countResult, "value"),
|
|
12190
|
+
MAX_SIGNED_64,
|
|
12191
|
+
"FLOW.QUERY count value"
|
|
12192
|
+
);
|
|
12193
|
+
if (usage.resultRecords !== 1) {
|
|
12194
|
+
throw decodeError("FLOW.QUERY count usage result_records must be 1", value);
|
|
12195
|
+
}
|
|
12196
|
+
return {
|
|
12197
|
+
kind: "count",
|
|
12198
|
+
count,
|
|
12199
|
+
quality,
|
|
12200
|
+
usage,
|
|
12201
|
+
raw
|
|
12202
|
+
};
|
|
12203
|
+
}
|
|
12204
|
+
function decodeFlowExplainResult(value) {
|
|
12205
|
+
const mapping = requiredMap2(value, "FLOW.QUERY explain");
|
|
12206
|
+
requireContract(mapping, "version", FLOW_EXPLAIN_CONTRACT, "FLOW.QUERY explain");
|
|
12207
|
+
const queryFingerprint = requiredText2(mapping, "query_fingerprint", "FLOW.QUERY explain");
|
|
12208
|
+
if (!/^[0-9a-f]{64}$/iu.test(queryFingerprint)) {
|
|
12209
|
+
throw decodeError("FLOW.QUERY explain query_fingerprint is invalid", value);
|
|
12210
|
+
}
|
|
12211
|
+
const status = requiredText2(mapping, "status", "FLOW.QUERY explain");
|
|
12212
|
+
if (status !== "planned" && status !== "rejected" && status !== "executed") {
|
|
12213
|
+
throw decodeError(`FLOW.QUERY explain status ${JSON.stringify(status)} is unsupported`, value);
|
|
12214
|
+
}
|
|
12215
|
+
const plan = freezeMetadataMap(
|
|
12216
|
+
requiredMap2(field(mapping, "plan"), "FLOW.QUERY explain plan"),
|
|
12217
|
+
"FLOW.QUERY explain plan"
|
|
12218
|
+
);
|
|
12219
|
+
const estimate = freezeMetadataMap(
|
|
12220
|
+
requiredMap2(field(mapping, "estimate"), "FLOW.QUERY explain estimate"),
|
|
12221
|
+
"FLOW.QUERY explain estimate"
|
|
12222
|
+
);
|
|
12223
|
+
const bounds = freezeMetadataMap(
|
|
12224
|
+
requiredMap2(field(mapping, "bounds"), "FLOW.QUERY explain bounds"),
|
|
12225
|
+
"FLOW.QUERY explain bounds"
|
|
12226
|
+
);
|
|
12227
|
+
const actualValue = field(mapping, "actual");
|
|
12228
|
+
let actual;
|
|
12229
|
+
if (status === "executed") {
|
|
12230
|
+
if (actualValue == null) {
|
|
12231
|
+
throw decodeError("FLOW.QUERY executed explain is missing actual usage", value);
|
|
12232
|
+
}
|
|
12233
|
+
actual = decodeUsage(actualValue);
|
|
12234
|
+
} else if (actualValue != null) {
|
|
12235
|
+
throw decodeError("FLOW.QUERY non-executed explain contains actual usage", value);
|
|
12236
|
+
}
|
|
12237
|
+
const diagnosticValue = field(mapping, "diagnostic");
|
|
12238
|
+
let diagnostic;
|
|
12239
|
+
if (status === "rejected") {
|
|
12240
|
+
diagnostic = tryDecodeFlowQueryError(diagnosticValue);
|
|
12241
|
+
if (diagnostic == null) {
|
|
12242
|
+
throw decodeError("FLOW.QUERY rejected explain has an invalid diagnostic", value);
|
|
12243
|
+
}
|
|
12244
|
+
} else if (diagnosticValue != null) {
|
|
12245
|
+
throw decodeError("FLOW.QUERY non-rejected explain contains a diagnostic", value);
|
|
12246
|
+
}
|
|
12247
|
+
return Object.freeze({
|
|
12248
|
+
version: FLOW_EXPLAIN_CONTRACT,
|
|
12249
|
+
queryFingerprint,
|
|
12250
|
+
status,
|
|
12251
|
+
plan,
|
|
12252
|
+
estimate,
|
|
12253
|
+
bounds,
|
|
12254
|
+
actual,
|
|
12255
|
+
diagnostic,
|
|
12256
|
+
raw: freezeMap(mapping)
|
|
12257
|
+
});
|
|
12258
|
+
}
|
|
12259
|
+
function tryDecodeFlowQueryError(value, cause) {
|
|
12260
|
+
try {
|
|
12261
|
+
const mapping = requiredMap2(value, "FLOW.QUERY diagnostic");
|
|
12262
|
+
const contextValue = field(mapping, "context");
|
|
12263
|
+
const context = contextValue == null ? void 0 : freezeMetadataMap(
|
|
12264
|
+
requiredMap2(contextValue, "FLOW.QUERY diagnostic context"),
|
|
12265
|
+
"FLOW.QUERY diagnostic context"
|
|
12266
|
+
);
|
|
12267
|
+
const position = decodePosition(field(mapping, "position"));
|
|
12268
|
+
return new FlowQueryError({
|
|
12269
|
+
code: requiredText2(mapping, "code", "FLOW.QUERY diagnostic"),
|
|
12270
|
+
message: requiredText2(mapping, "message", "FLOW.QUERY diagnostic"),
|
|
12271
|
+
detail: optionalText2(mapping, "detail", "FLOW.QUERY diagnostic"),
|
|
12272
|
+
hint: optionalText2(mapping, "hint", "FLOW.QUERY diagnostic"),
|
|
12273
|
+
retryable: requiredBoolean(mapping, "retryable", "FLOW.QUERY diagnostic"),
|
|
12274
|
+
safeToRetry: requiredBoolean(mapping, "safe_to_retry", "FLOW.QUERY diagnostic"),
|
|
12275
|
+
retryAfterMs: nonNegativeInteger(
|
|
12276
|
+
field(mapping, "retry_after_ms"),
|
|
12277
|
+
"FLOW.QUERY diagnostic retry_after_ms"
|
|
12278
|
+
),
|
|
12279
|
+
position,
|
|
12280
|
+
context,
|
|
12281
|
+
raw: value,
|
|
12282
|
+
cause
|
|
12283
|
+
});
|
|
12284
|
+
} catch (error) {
|
|
12285
|
+
if (error instanceof FerricStoreError) return void 0;
|
|
12286
|
+
throw error;
|
|
12287
|
+
}
|
|
12288
|
+
}
|
|
12289
|
+
function decodeFlowQueryIndexStatus(value) {
|
|
12290
|
+
const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES");
|
|
12291
|
+
requireContract(
|
|
12292
|
+
mapping,
|
|
12293
|
+
"contract_version",
|
|
12294
|
+
FLOW_QUERY_INDEXES_CONTRACT,
|
|
12295
|
+
"FLOW.QUERY.INDEXES"
|
|
12296
|
+
);
|
|
12297
|
+
const registry = requiredMap2(field(mapping, "registry"), "FLOW.QUERY.INDEXES registry");
|
|
12298
|
+
const services = freezeMetadataMap(
|
|
12299
|
+
requiredMap2(field(mapping, "services"), "FLOW.QUERY.INDEXES services"),
|
|
12300
|
+
"FLOW.QUERY.INDEXES services"
|
|
12301
|
+
);
|
|
12302
|
+
const rawIndexes = field(mapping, "indexes");
|
|
12303
|
+
if (!Array.isArray(rawIndexes) || rawIndexes.length > 32) {
|
|
12304
|
+
throw decodeError("FLOW.QUERY.INDEXES indexes must contain at most 32 entries", value);
|
|
12305
|
+
}
|
|
12306
|
+
const indexes = new Array(rawIndexes.length);
|
|
12307
|
+
for (let index = 0; index < rawIndexes.length; index += 1) {
|
|
12308
|
+
if (!Object.hasOwn(rawIndexes, index)) {
|
|
12309
|
+
throw decodeError("FLOW.QUERY.INDEXES indexes must be a dense array", value);
|
|
12310
|
+
}
|
|
12311
|
+
indexes[index] = decodeIndex(rawIndexes[index], index);
|
|
12312
|
+
}
|
|
12313
|
+
return Object.freeze({
|
|
12314
|
+
contractVersion: FLOW_QUERY_INDEXES_CONTRACT,
|
|
12315
|
+
observedAtMs: nonNegativeInteger(
|
|
12316
|
+
field(mapping, "observed_at_ms"),
|
|
12317
|
+
"FLOW.QUERY.INDEXES observed_at_ms"
|
|
12318
|
+
),
|
|
12319
|
+
statisticsMaxAgeMs: nonNegativeInteger(
|
|
12320
|
+
field(mapping, "statistics_max_age_ms"),
|
|
12321
|
+
"FLOW.QUERY.INDEXES statistics_max_age_ms"
|
|
12322
|
+
),
|
|
12323
|
+
registry: Object.freeze({
|
|
12324
|
+
epoch: boundedInteger(
|
|
12325
|
+
field(registry, "epoch"),
|
|
12326
|
+
MAX_UNSIGNED_64,
|
|
12327
|
+
"FLOW.QUERY.INDEXES epoch"
|
|
12328
|
+
),
|
|
12329
|
+
catalogVersion: positiveBoundedInteger(
|
|
12330
|
+
field(registry, "catalog_version"),
|
|
12331
|
+
MAX_UNSIGNED_64,
|
|
12332
|
+
"FLOW.QUERY.INDEXES catalog_version"
|
|
12333
|
+
)
|
|
12334
|
+
}),
|
|
12335
|
+
services,
|
|
12336
|
+
indexes: Object.freeze(indexes),
|
|
12337
|
+
raw: freezeMap(mapping)
|
|
12338
|
+
});
|
|
12339
|
+
}
|
|
12340
|
+
function decodeIndex(value, index) {
|
|
12341
|
+
const mapping = requiredMap2(value, `FLOW.QUERY.INDEXES index ${index}`);
|
|
12342
|
+
return Object.freeze({
|
|
12343
|
+
id: requiredText2(mapping, "id", "FLOW.QUERY.INDEXES index"),
|
|
12344
|
+
version: positiveBoundedInteger(
|
|
12345
|
+
field(mapping, "version"),
|
|
12346
|
+
MAX_UNSIGNED_64,
|
|
12347
|
+
"FLOW.QUERY.INDEXES index version"
|
|
12348
|
+
),
|
|
12349
|
+
buildId: requiredText2(mapping, "build_id", "FLOW.QUERY.INDEXES index"),
|
|
12350
|
+
state: requiredText2(mapping, "state", "FLOW.QUERY.INDEXES index"),
|
|
12351
|
+
queryable: requiredBoolean(mapping, "queryable", "FLOW.QUERY.INDEXES index"),
|
|
12352
|
+
coveringFields: decodeCoveringFields(mapping),
|
|
12353
|
+
format: decodeIndexFormat(mapping),
|
|
12354
|
+
raw: freezeMap(mapping)
|
|
12355
|
+
});
|
|
12356
|
+
}
|
|
12357
|
+
function decodeCoveringFields(mapping) {
|
|
12358
|
+
const raw = field(mapping, "covering_fields");
|
|
12359
|
+
if (!Array.isArray(raw) || raw.length > 32) {
|
|
12360
|
+
throw decodeError(
|
|
12361
|
+
"FLOW.QUERY.INDEXES index covering_fields must contain at most 32 entries",
|
|
12362
|
+
raw
|
|
12363
|
+
);
|
|
12364
|
+
}
|
|
12365
|
+
const fields = new Array(raw.length);
|
|
12366
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12367
|
+
for (let index = 0; index < raw.length; index += 1) {
|
|
12368
|
+
if (!Object.hasOwn(raw, index)) {
|
|
12369
|
+
throw decodeError("FLOW.QUERY.INDEXES index covering_fields must be dense", raw);
|
|
12370
|
+
}
|
|
12371
|
+
const value = boundedText(
|
|
12372
|
+
raw[index],
|
|
12373
|
+
`FLOW.QUERY.INDEXES index covering_fields entry ${index}`,
|
|
12374
|
+
512
|
|
12375
|
+
);
|
|
12376
|
+
if (seen.has(value)) {
|
|
12377
|
+
throw decodeError("FLOW.QUERY.INDEXES index covering_fields contains duplicates", raw);
|
|
12378
|
+
}
|
|
12379
|
+
seen.add(value);
|
|
12380
|
+
fields[index] = value;
|
|
12381
|
+
}
|
|
12382
|
+
return Object.freeze(fields);
|
|
12383
|
+
}
|
|
12384
|
+
function decodeIndexFormat(mapping) {
|
|
12385
|
+
const raw = requiredMap2(field(mapping, "format"), "FLOW.QUERY.INDEXES index format");
|
|
12386
|
+
if (!hasKey(raw, "counter")) {
|
|
12387
|
+
throw decodeError("FLOW.QUERY.INDEXES index format counter is missing", raw);
|
|
12388
|
+
}
|
|
12389
|
+
const counterValue = field(raw, "counter");
|
|
12390
|
+
const counter = counterValue === null ? void 0 : boundedText(counterValue, "FLOW.QUERY.INDEXES index format counter", 128);
|
|
12391
|
+
return Object.freeze({
|
|
12392
|
+
queryRow: requiredBoundedText2(raw, "query_row", "FLOW.QUERY.INDEXES index format", 128),
|
|
12393
|
+
key: requiredBoundedText2(raw, "key", "FLOW.QUERY.INDEXES index format", 128),
|
|
12394
|
+
entry: requiredBoundedText2(raw, "entry", "FLOW.QUERY.INDEXES index format", 128),
|
|
12395
|
+
reverse: requiredBoundedText2(raw, "reverse", "FLOW.QUERY.INDEXES index format", 128),
|
|
12396
|
+
counter,
|
|
12397
|
+
raw: freezeMap(raw)
|
|
12398
|
+
});
|
|
12399
|
+
}
|
|
12400
|
+
function decodeQuality(value) {
|
|
12401
|
+
const mapping = requiredMap2(value, "FLOW.QUERY quality");
|
|
12402
|
+
return Object.freeze({
|
|
12403
|
+
exactness: requiredBoundedText2(mapping, "exactness", "FLOW.QUERY quality", 64),
|
|
12404
|
+
freshness: requiredBoundedText2(mapping, "freshness", "FLOW.QUERY quality", 64),
|
|
12405
|
+
coverage: requiredBoundedText2(mapping, "coverage", "FLOW.QUERY quality", 64),
|
|
12406
|
+
pagination: requiredBoundedText2(mapping, "pagination", "FLOW.QUERY quality", 64)
|
|
12407
|
+
});
|
|
12408
|
+
}
|
|
12409
|
+
function decodeUsage(value) {
|
|
12410
|
+
const mapping = requiredMap2(value, "FLOW.QUERY usage");
|
|
12411
|
+
const usage = /* @__PURE__ */ Object.create(null);
|
|
12412
|
+
for (const [wireName, property] of USAGE_FIELDS2) {
|
|
12413
|
+
usage[property] = nonNegativeInteger(
|
|
12414
|
+
field(mapping, wireName),
|
|
12415
|
+
`FLOW.QUERY usage ${wireName}`
|
|
12416
|
+
);
|
|
12417
|
+
}
|
|
12418
|
+
return Object.freeze(usage);
|
|
12419
|
+
}
|
|
12420
|
+
function decodePage(value) {
|
|
12421
|
+
const mapping = requiredMap2(value, "FLOW.QUERY page");
|
|
12422
|
+
const hasMore = requiredBoolean(mapping, "has_more", "FLOW.QUERY page");
|
|
12423
|
+
const cursor = optionalText2(mapping, "cursor", "FLOW.QUERY page");
|
|
12424
|
+
if (cursor != null && (!cursor.startsWith("fqc1_") || import_node_buffer45.Buffer.byteLength(cursor) > 4096)) {
|
|
12425
|
+
throw decodeError("FLOW.QUERY page cursor is invalid", value);
|
|
12426
|
+
}
|
|
12427
|
+
if (hasMore !== (cursor != null)) {
|
|
12428
|
+
throw decodeError("FLOW.QUERY page has_more and cursor are inconsistent", value);
|
|
12429
|
+
}
|
|
12430
|
+
return Object.freeze({ hasMore, ...cursor == null ? {} : { cursor } });
|
|
12431
|
+
}
|
|
12432
|
+
function decodePosition(value) {
|
|
12433
|
+
if (value == null) return void 0;
|
|
12434
|
+
const mapping = requiredMap2(value, "FLOW.QUERY diagnostic position");
|
|
12435
|
+
return Object.freeze({
|
|
12436
|
+
byte: positiveInteger(field(mapping, "byte"), "FLOW.QUERY diagnostic position byte"),
|
|
12437
|
+
line: positiveInteger(field(mapping, "line"), "FLOW.QUERY diagnostic position line"),
|
|
12438
|
+
column: positiveInteger(
|
|
12439
|
+
field(mapping, "column"),
|
|
12440
|
+
"FLOW.QUERY diagnostic position column"
|
|
12441
|
+
)
|
|
12442
|
+
});
|
|
12443
|
+
}
|
|
12444
|
+
|
|
12445
|
+
// src/client-core.ts
|
|
12446
|
+
var import_node_buffer50 = require("buffer");
|
|
12447
|
+
|
|
12448
|
+
// src/client-core-helpers.ts
|
|
12449
|
+
var import_node_buffer46 = require("buffer");
|
|
12450
|
+
function bgsaveResponse(response) {
|
|
12451
|
+
if ((typeof response === "string" || import_node_buffer46.Buffer.isBuffer(response) || response instanceof Uint8Array) && text(response) === "Background saving started") {
|
|
12452
|
+
return true;
|
|
12453
|
+
}
|
|
12454
|
+
return okResponse(response);
|
|
12455
|
+
}
|
|
12456
|
+
function clientNameResponse(response) {
|
|
12457
|
+
return response == null ? null : textResponse(response, "CLIENT GETNAME");
|
|
12458
|
+
}
|
|
12459
|
+
function fetchOrComputeCompletionToken(options) {
|
|
12460
|
+
if (options == null || !Object.hasOwn(options, "computeToken") || options.computeToken === void 0) {
|
|
12461
|
+
throw new TypeError(
|
|
12462
|
+
"fetch-or-compute completion requires computeToken"
|
|
12463
|
+
);
|
|
12464
|
+
}
|
|
12465
|
+
if (!import_node_buffer46.Buffer.isBuffer(options.computeToken)) {
|
|
12466
|
+
throw new TypeError("fetch-or-compute computeToken must be a Buffer");
|
|
12467
|
+
}
|
|
12468
|
+
return options.computeToken;
|
|
12469
|
+
}
|
|
12470
|
+
function concatCommandArgs(prefix, suffix) {
|
|
12471
|
+
const args = new Array(prefix.length + suffix.length);
|
|
12472
|
+
for (let index = 0; index < prefix.length; index += 1) args[index] = prefix[index];
|
|
12473
|
+
for (let index = 0; index < suffix.length; index += 1) {
|
|
12474
|
+
args[prefix.length + index] = suffix[index];
|
|
12475
|
+
}
|
|
12476
|
+
return args;
|
|
12477
|
+
}
|
|
12478
|
+
function unsupportedClientTracking() {
|
|
12479
|
+
throw new InvalidCommandError(
|
|
12480
|
+
"CLIENT TRACKING is not supported by the FerricStore native protocol; use native event subscriptions"
|
|
12481
|
+
);
|
|
12482
|
+
}
|
|
12483
|
+
function unsupportedClientCaching() {
|
|
12484
|
+
throw new InvalidCommandError("CLIENT CACHING is not supported by the FerricStore native protocol");
|
|
10775
12485
|
}
|
|
10776
12486
|
|
|
10777
12487
|
// src/client-base.ts
|
|
10778
|
-
var
|
|
12488
|
+
var import_node_buffer48 = require("buffer");
|
|
10779
12489
|
|
|
10780
12490
|
// src/client-executor.ts
|
|
10781
|
-
var
|
|
12491
|
+
var import_node_buffer47 = require("buffer");
|
|
10782
12492
|
var ErrorMappingExecutor = class {
|
|
10783
12493
|
constructor(executor) {
|
|
10784
12494
|
this.executor = executor;
|
|
@@ -11112,14 +12822,14 @@ var FerricStoreAdministrationClient = class extends FerricStoreClientBase {
|
|
|
11112
12822
|
};
|
|
11113
12823
|
|
|
11114
12824
|
// src/store-utilities.ts
|
|
11115
|
-
var
|
|
12825
|
+
var import_node_buffer49 = require("buffer");
|
|
11116
12826
|
function encode(codec, value) {
|
|
11117
12827
|
return codec.encode(value);
|
|
11118
12828
|
}
|
|
11119
12829
|
function decode(codec, value) {
|
|
11120
12830
|
if (value == null) return null;
|
|
11121
|
-
if (
|
|
11122
|
-
if (value instanceof Uint8Array) return codec.decode(
|
|
12831
|
+
if (import_node_buffer49.Buffer.isBuffer(value)) return codec.decode(value);
|
|
12832
|
+
if (value instanceof Uint8Array) return codec.decode(import_node_buffer49.Buffer.from(value));
|
|
11123
12833
|
return value;
|
|
11124
12834
|
}
|
|
11125
12835
|
function number(value) {
|
|
@@ -11180,7 +12890,7 @@ function requireNonEmpty(values, command, noun = "argument") {
|
|
|
11180
12890
|
if (values.length === 0) throw new TypeError(`${command} requires at least one ${noun}`);
|
|
11181
12891
|
return values;
|
|
11182
12892
|
}
|
|
11183
|
-
function
|
|
12893
|
+
function commandName4(args) {
|
|
11184
12894
|
return typeof args[0] === "string" ? args[0] : "command";
|
|
11185
12895
|
}
|
|
11186
12896
|
function commandArgs(client, args) {
|
|
@@ -11195,7 +12905,7 @@ function arrayOrRest(values) {
|
|
|
11195
12905
|
function appendXReadStreams(args, streams) {
|
|
11196
12906
|
const offset = args.length;
|
|
11197
12907
|
const streamCount = streams.length;
|
|
11198
|
-
requireNonEmpty(streams,
|
|
12908
|
+
requireNonEmpty(streams, commandName4(args), "stream");
|
|
11199
12909
|
args.length = offset + 1 + streamCount * 2;
|
|
11200
12910
|
args[offset] = "STREAMS";
|
|
11201
12911
|
for (let index = 0; index < streamCount; index += 1) {
|
|
@@ -11205,7 +12915,7 @@ function appendXReadStreams(args, streams) {
|
|
|
11205
12915
|
const stream = streams[index];
|
|
11206
12916
|
if (stream == null) throw new TypeError("XREAD streams must contain only stream descriptors");
|
|
11207
12917
|
if (!Object.hasOwn(stream, "key") || !Object.hasOwn(stream, "id")) {
|
|
11208
|
-
throw new TypeError(`${
|
|
12918
|
+
throw new TypeError(`${commandName4(args)} streams require own key and id fields`);
|
|
11209
12919
|
}
|
|
11210
12920
|
args[offset + 1 + index] = stream.key;
|
|
11211
12921
|
args[offset + 1 + streamCount + index] = stream.id;
|
|
@@ -11227,7 +12937,7 @@ function concatArgs(...parts) {
|
|
|
11227
12937
|
return args;
|
|
11228
12938
|
}
|
|
11229
12939
|
function encodedArgs(prefix, codec, values, allowEmpty = false) {
|
|
11230
|
-
if (!allowEmpty) requireNonEmpty(values,
|
|
12940
|
+
if (!allowEmpty) requireNonEmpty(values, commandName4(prefix));
|
|
11231
12941
|
const args = new Array(prefix.length + values.length);
|
|
11232
12942
|
for (let index = 0; index < prefix.length; index += 1) args[index] = prefix[index];
|
|
11233
12943
|
for (let index = 0; index < values.length; index += 1) {
|
|
@@ -11241,7 +12951,7 @@ function encodedArgs(prefix, codec, values, allowEmpty = false) {
|
|
|
11241
12951
|
function keyValueArgs(prefix, codec, entries) {
|
|
11242
12952
|
const validateTuples = Array.isArray(entries);
|
|
11243
12953
|
const pairs = validateTuples ? entries : Object.entries(entries);
|
|
11244
|
-
requireNonEmpty(pairs,
|
|
12954
|
+
requireNonEmpty(pairs, commandName4(prefix), "entry");
|
|
11245
12955
|
const args = new Array(prefix.length + pairs.length * 2);
|
|
11246
12956
|
for (let index = 0; index < prefix.length; index += 1) args[index] = prefix[index];
|
|
11247
12957
|
for (let index = 0; index < pairs.length; index += 1) {
|
|
@@ -11255,7 +12965,7 @@ function keyValueArgs(prefix, codec, entries) {
|
|
|
11255
12965
|
return args;
|
|
11256
12966
|
}
|
|
11257
12967
|
function encodedEntryArgs(prefix, codec, entries) {
|
|
11258
|
-
requireNonEmpty(entries,
|
|
12968
|
+
requireNonEmpty(entries, commandName4(prefix), "entry");
|
|
11259
12969
|
const args = new Array(prefix.length + entries.length * 2);
|
|
11260
12970
|
for (let index = 0; index < prefix.length; index += 1) args[index] = prefix[index];
|
|
11261
12971
|
for (let index = 0; index < entries.length; index += 1) {
|
|
@@ -11709,15 +13419,15 @@ function compressionOptions(options) {
|
|
|
11709
13419
|
// src/store-decoders.ts
|
|
11710
13420
|
function decodeHashRecord(codec, value) {
|
|
11711
13421
|
const result = {};
|
|
11712
|
-
for (const [
|
|
11713
|
-
setOwnValue(result, textToken(
|
|
13422
|
+
for (const [field3, item] of hashPairs(value)) {
|
|
13423
|
+
setOwnValue(result, textToken(field3), decode(codec, item));
|
|
11714
13424
|
}
|
|
11715
13425
|
return result;
|
|
11716
13426
|
}
|
|
11717
13427
|
function decodeHashFlatPairs(codec, value) {
|
|
11718
13428
|
const result = [];
|
|
11719
|
-
for (const [
|
|
11720
|
-
result.push(textToken(
|
|
13429
|
+
for (const [field3, item] of hashPairs(value)) {
|
|
13430
|
+
result.push(textToken(field3), decode(codec, item));
|
|
11721
13431
|
}
|
|
11722
13432
|
return result;
|
|
11723
13433
|
}
|
|
@@ -11837,7 +13547,7 @@ function requiredPair(value, message) {
|
|
|
11837
13547
|
}
|
|
11838
13548
|
function decodeStreamFieldValues(codec, value) {
|
|
11839
13549
|
const result = [];
|
|
11840
|
-
for (const [
|
|
13550
|
+
for (const [field3, item] of hashPairs(value)) result.push(textToken(field3), decode(codec, item));
|
|
11841
13551
|
return result;
|
|
11842
13552
|
}
|
|
11843
13553
|
var geoSearchMetadataTokens = /* @__PURE__ */ new Set(["WITHCOORD", "WITHDIST", "WITHHASH"]);
|
|
@@ -12651,8 +14361,8 @@ var HashStore = class {
|
|
|
12651
14361
|
async hset(key, entries) {
|
|
12652
14362
|
return number(await commandArgs(this.client, keyValueArgs(["HSET", key], this.client.codec, entries)));
|
|
12653
14363
|
}
|
|
12654
|
-
async hget(key,
|
|
12655
|
-
return decode(this.client.codec, await this.client.command("HGET", key,
|
|
14364
|
+
async hget(key, field3) {
|
|
14365
|
+
return decode(this.client.codec, await this.client.command("HGET", key, field3));
|
|
12656
14366
|
}
|
|
12657
14367
|
async hdel(key, ...fieldsOrArray) {
|
|
12658
14368
|
const fields = requireNonEmpty(arrayOrRest(fieldsOrArray), "HDEL", "field");
|
|
@@ -12671,8 +14381,8 @@ var HashStore = class {
|
|
|
12671
14381
|
async hgetall(key) {
|
|
12672
14382
|
return decodeHashRecord(this.client.codec, await this.client.command("HGETALL", key));
|
|
12673
14383
|
}
|
|
12674
|
-
async hexists(key,
|
|
12675
|
-
return binaryBooleanResponse(await this.client.command("HEXISTS", key,
|
|
14384
|
+
async hexists(key, field3) {
|
|
14385
|
+
return binaryBooleanResponse(await this.client.command("HEXISTS", key, field3));
|
|
12676
14386
|
}
|
|
12677
14387
|
async hkeys(key) {
|
|
12678
14388
|
return mapArray(await this.client.command("HKEYS", key), "HKEYS", textToken);
|
|
@@ -12687,17 +14397,17 @@ var HashStore = class {
|
|
|
12687
14397
|
async hlen(key) {
|
|
12688
14398
|
return number(await this.client.command("HLEN", key));
|
|
12689
14399
|
}
|
|
12690
|
-
async hincrby(key,
|
|
12691
|
-
return integerReply(await this.client.command("HINCRBY", key,
|
|
14400
|
+
async hincrby(key, field3, increment) {
|
|
14401
|
+
return integerReply(await this.client.command("HINCRBY", key, field3, increment));
|
|
12692
14402
|
}
|
|
12693
|
-
async hincrbyfloat(key,
|
|
12694
|
-
return string(await this.client.command("HINCRBYFLOAT", key,
|
|
14403
|
+
async hincrbyfloat(key, field3, increment) {
|
|
14404
|
+
return string(await this.client.command("HINCRBYFLOAT", key, field3, increment));
|
|
12695
14405
|
}
|
|
12696
|
-
async hsetnx(key,
|
|
12697
|
-
return binaryBooleanResponse(await this.client.command("HSETNX", key,
|
|
14406
|
+
async hsetnx(key, field3, value) {
|
|
14407
|
+
return binaryBooleanResponse(await this.client.command("HSETNX", key, field3, encode(this.client.codec, value)));
|
|
12698
14408
|
}
|
|
12699
|
-
async hstrlen(key,
|
|
12700
|
-
return number(await this.client.command("HSTRLEN", key,
|
|
14409
|
+
async hstrlen(key, field3) {
|
|
14410
|
+
return number(await this.client.command("HSTRLEN", key, field3));
|
|
12701
14411
|
}
|
|
12702
14412
|
async hrandfield(key, count, withValues = false) {
|
|
12703
14413
|
if (withValues && count == null) {
|
|
@@ -13333,6 +15043,100 @@ var FerricStoreManagementClient = class extends FerricStoreClientCore {
|
|
|
13333
15043
|
}
|
|
13334
15044
|
};
|
|
13335
15045
|
|
|
15046
|
+
// src/client-flow-query.ts
|
|
15047
|
+
var FerricStoreFlowQueryClient = class extends FerricStoreManagementClient {
|
|
15048
|
+
async query(query, params = {}) {
|
|
15049
|
+
if (hasFlowExplainPrefix(query)) {
|
|
15050
|
+
throw new TypeError("query does not accept EXPLAIN; use explain or explainAnalyze");
|
|
15051
|
+
}
|
|
15052
|
+
return decodeFlowQueryResult(await this.executeFlowQuery(query, params));
|
|
15053
|
+
}
|
|
15054
|
+
async explain(query, params = {}) {
|
|
15055
|
+
return await this.executeExplain("EXPLAIN ", query, params);
|
|
15056
|
+
}
|
|
15057
|
+
async explainAnalyze(query, params = {}) {
|
|
15058
|
+
return await this.executeExplain("EXPLAIN ANALYZE ", query, params);
|
|
15059
|
+
}
|
|
15060
|
+
async queryIndexes(indexId) {
|
|
15061
|
+
const args = ["FLOW.QUERY.INDEXES"];
|
|
15062
|
+
if (indexId != null) {
|
|
15063
|
+
validateFlowQueryIndexId(indexId);
|
|
15064
|
+
args.push(indexId);
|
|
15065
|
+
}
|
|
15066
|
+
try {
|
|
15067
|
+
return decodeFlowQueryIndexStatus(await this.commandArgs(args));
|
|
15068
|
+
} catch (error) {
|
|
15069
|
+
this.throwFlowQueryError(error);
|
|
15070
|
+
}
|
|
15071
|
+
}
|
|
15072
|
+
async list(type, options) {
|
|
15073
|
+
return await this.executeFlowRecordQuery(buildFlowListQuery(type, options));
|
|
15074
|
+
}
|
|
15075
|
+
async search(type, options) {
|
|
15076
|
+
return await this.executeFlowRecordQuery(buildFlowSearchQuery(type, options));
|
|
15077
|
+
}
|
|
15078
|
+
async terminals(type, options) {
|
|
15079
|
+
return await this.executeFlowRecordQuery(buildFlowTerminalQuery(type, options));
|
|
15080
|
+
}
|
|
15081
|
+
async failures(type, options) {
|
|
15082
|
+
return await this.executeFlowRecordQuery(buildFlowFailureQuery(type, options));
|
|
15083
|
+
}
|
|
15084
|
+
async byParent(parentFlowId, options) {
|
|
15085
|
+
return await this.executeFlowRecordQuery(
|
|
15086
|
+
buildFlowLineageQuery("parent_flow_id", parentFlowId, options)
|
|
15087
|
+
);
|
|
15088
|
+
}
|
|
15089
|
+
async byRoot(rootFlowId, options) {
|
|
15090
|
+
return await this.executeFlowRecordQuery(
|
|
15091
|
+
buildFlowLineageQuery("root_flow_id", rootFlowId, options)
|
|
15092
|
+
);
|
|
15093
|
+
}
|
|
15094
|
+
async byCorrelation(correlationId, options) {
|
|
15095
|
+
return await this.executeFlowRecordQuery(
|
|
15096
|
+
buildFlowLineageQuery("correlation_id", correlationId, options)
|
|
15097
|
+
);
|
|
15098
|
+
}
|
|
15099
|
+
async stuck(type, options) {
|
|
15100
|
+
return await this.executeFlowRecordQuery(buildFlowStuckQuery(type, options));
|
|
15101
|
+
}
|
|
15102
|
+
records(values) {
|
|
15103
|
+
const records = new Array(values.length);
|
|
15104
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
15105
|
+
if (!Object.hasOwn(values, index)) {
|
|
15106
|
+
throw new TypeError(`Flow record response item ${index} is missing`);
|
|
15107
|
+
}
|
|
15108
|
+
records[index] = flowRecordFromResp(values[index], this.codec);
|
|
15109
|
+
}
|
|
15110
|
+
return records;
|
|
15111
|
+
}
|
|
15112
|
+
async executeFlowQuery(query, params) {
|
|
15113
|
+
const args = flowQueryArgs(query, params);
|
|
15114
|
+
try {
|
|
15115
|
+
return await this.commandArgs(args);
|
|
15116
|
+
} catch (error) {
|
|
15117
|
+
this.throwFlowQueryError(error);
|
|
15118
|
+
}
|
|
15119
|
+
}
|
|
15120
|
+
async executeFlowRecordQuery(request) {
|
|
15121
|
+
const response = await this.executeFlowQuery(request.query, request.params);
|
|
15122
|
+
return decodeFlowQueryRecords(response, (value) => flowRecordFromResp(value, this.codec));
|
|
15123
|
+
}
|
|
15124
|
+
async executeExplain(prefix, query, params) {
|
|
15125
|
+
validateFlowQueryText(query);
|
|
15126
|
+
if (hasFlowExplainPrefix(query)) {
|
|
15127
|
+
throw new TypeError("query already contains an EXPLAIN prefix");
|
|
15128
|
+
}
|
|
15129
|
+
return decodeFlowExplainResult(await this.executeFlowQuery(prefix + query.trim(), params));
|
|
15130
|
+
}
|
|
15131
|
+
throwFlowQueryError(error) {
|
|
15132
|
+
if (error instanceof FerricStoreError) {
|
|
15133
|
+
const diagnostic = tryDecodeFlowQueryError(error.raw, error);
|
|
15134
|
+
if (diagnostic != null) throw diagnostic;
|
|
15135
|
+
}
|
|
15136
|
+
throw error;
|
|
15137
|
+
}
|
|
15138
|
+
};
|
|
15139
|
+
|
|
13336
15140
|
// src/producer-backpressure.ts
|
|
13337
15141
|
async function executeProducerWriteWithBackpressure(execute, policy, signal) {
|
|
13338
15142
|
for (let attempt = 0; ; attempt += 1) {
|
|
@@ -13354,8 +15158,167 @@ function throwIfClosed(signal) {
|
|
|
13354
15158
|
throw new FerricStoreError("FerricStore client is closed", { raw: signal.reason });
|
|
13355
15159
|
}
|
|
13356
15160
|
|
|
15161
|
+
// src/flow-policy.ts
|
|
15162
|
+
var import_node_buffer51 = require("buffer");
|
|
15163
|
+
var MAX_FLOW_POLICY_GENERATION = Number.MAX_SAFE_INTEGER;
|
|
15164
|
+
function assertFlowPolicyGeneration(value) {
|
|
15165
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
|
|
15166
|
+
throw new TypeError("expectedGeneration must be a nonnegative safe integer");
|
|
15167
|
+
}
|
|
15168
|
+
}
|
|
15169
|
+
function flowPolicySnapshotFromResp(value) {
|
|
15170
|
+
const policy = requiredRecord(value, "FLOW policy snapshot");
|
|
15171
|
+
const maxActiveMs = optionalPositiveInteger(field(policy, "max_active_ms"), "max_active_ms");
|
|
15172
|
+
const state = optionalText3(field(policy, "state"), "state");
|
|
15173
|
+
const mode = optionalMode(field(policy, "mode"), "mode");
|
|
15174
|
+
const version = optionalVersion(field(policy, "version"));
|
|
15175
|
+
const indexedStateMeta = optionalText3(field(policy, "indexed_state_meta"), "indexed_state_meta");
|
|
15176
|
+
const governance = optionalRecord(field(policy, "governance"), "governance");
|
|
15177
|
+
const states = optionalStates(field(policy, "states"));
|
|
15178
|
+
return {
|
|
15179
|
+
type: requiredText3(field(policy, "type"), "type"),
|
|
15180
|
+
generation: nonNegativeInteger2(field(policy, "generation"), "generation"),
|
|
15181
|
+
...state == null ? {} : { state },
|
|
15182
|
+
...version == null ? {} : { version },
|
|
15183
|
+
...mode == null ? {} : { mode },
|
|
15184
|
+
...maxActiveMs == null ? {} : { maxActiveMs },
|
|
15185
|
+
retry: retrySnapshot(field(policy, "retry"), "retry"),
|
|
15186
|
+
retention: retentionSnapshot(field(policy, "retention"), "retention"),
|
|
15187
|
+
indexedAttributes: stringArray(field(policy, "indexed_attributes"), "indexed_attributes"),
|
|
15188
|
+
...indexedStateMeta == null ? {} : { indexedStateMeta },
|
|
15189
|
+
...governance == null ? {} : { governance },
|
|
15190
|
+
...states == null ? {} : { states },
|
|
15191
|
+
raw: value
|
|
15192
|
+
};
|
|
15193
|
+
}
|
|
15194
|
+
function retrySnapshot(value, context) {
|
|
15195
|
+
const retry2 = requiredRecord(value, `FLOW policy ${context}`);
|
|
15196
|
+
const backoff = requiredRecord(field(retry2, "backoff"), `FLOW policy ${context}.backoff`);
|
|
15197
|
+
return {
|
|
15198
|
+
maxRetries: nonNegativeInteger2(field(retry2, "max_retries"), `${context}.max_retries`),
|
|
15199
|
+
backoff: {
|
|
15200
|
+
kind: backoffKind(field(backoff, "kind"), `${context}.backoff.kind`),
|
|
15201
|
+
baseMs: nonNegativeInteger2(field(backoff, "base_ms"), `${context}.backoff.base_ms`),
|
|
15202
|
+
maxMs: nonNegativeInteger2(field(backoff, "max_ms"), `${context}.backoff.max_ms`),
|
|
15203
|
+
jitterPct: nonNegativeInteger2(field(backoff, "jitter_pct"), `${context}.backoff.jitter_pct`)
|
|
15204
|
+
},
|
|
15205
|
+
exhaustedTo: requiredText3(field(retry2, "exhausted_to"), `${context}.exhausted_to`)
|
|
15206
|
+
};
|
|
15207
|
+
}
|
|
15208
|
+
function retentionSnapshot(value, context) {
|
|
15209
|
+
const retention = requiredRecord(value, `FLOW policy ${context}`);
|
|
15210
|
+
return {
|
|
15211
|
+
ttlMs: nonNegativeInteger2(field(retention, "ttl_ms"), `${context}.ttl_ms`),
|
|
15212
|
+
historyMaxEvents: nonNegativeInteger2(
|
|
15213
|
+
field(retention, "history_max_events"),
|
|
15214
|
+
`${context}.history_max_events`
|
|
15215
|
+
)
|
|
15216
|
+
};
|
|
15217
|
+
}
|
|
15218
|
+
function optionalStates(value) {
|
|
15219
|
+
if (value == null) return void 0;
|
|
15220
|
+
const source = requiredRecord(value, "FLOW policy states");
|
|
15221
|
+
const result = {};
|
|
15222
|
+
for (const [state, raw] of Object.entries(source)) {
|
|
15223
|
+
const policy = requiredRecord(raw, `FLOW policy state ${state}`);
|
|
15224
|
+
const maxActiveMs = optionalPositiveInteger(
|
|
15225
|
+
field(policy, "max_active_ms"),
|
|
15226
|
+
`states.${state}.max_active_ms`
|
|
15227
|
+
);
|
|
15228
|
+
const governance = optionalRecord(field(policy, "governance"), `states.${state}.governance`);
|
|
15229
|
+
Object.defineProperty(result, state, {
|
|
15230
|
+
configurable: true,
|
|
15231
|
+
enumerable: true,
|
|
15232
|
+
value: {
|
|
15233
|
+
mode: requiredMode(field(policy, "mode"), `states.${state}.mode`),
|
|
15234
|
+
...maxActiveMs == null ? {} : { maxActiveMs },
|
|
15235
|
+
retry: retrySnapshot(field(policy, "retry"), `states.${state}.retry`),
|
|
15236
|
+
retention: retentionSnapshot(field(policy, "retention"), `states.${state}.retention`),
|
|
15237
|
+
...governance == null ? {} : { governance }
|
|
15238
|
+
},
|
|
15239
|
+
writable: true
|
|
15240
|
+
});
|
|
15241
|
+
}
|
|
15242
|
+
return result;
|
|
15243
|
+
}
|
|
15244
|
+
function requiredRecord(value, context) {
|
|
15245
|
+
if (value instanceof Map) {
|
|
15246
|
+
const result = {};
|
|
15247
|
+
for (const [key, item] of value.entries()) {
|
|
15248
|
+
setOwnValue(result, requiredText3(key, `${context} key`), item);
|
|
15249
|
+
}
|
|
15250
|
+
return result;
|
|
15251
|
+
}
|
|
15252
|
+
if (typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer51.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return value;
|
|
15253
|
+
throw new TypeError(`${context} returned an unexpected response`);
|
|
15254
|
+
}
|
|
15255
|
+
function optionalRecord(value, context) {
|
|
15256
|
+
return value == null ? void 0 : requiredRecord(value, `FLOW policy ${context}`);
|
|
15257
|
+
}
|
|
15258
|
+
function stringArray(value, context) {
|
|
15259
|
+
if (!Array.isArray(value)) {
|
|
15260
|
+
throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15261
|
+
}
|
|
15262
|
+
const result = new Array(value.length);
|
|
15263
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
15264
|
+
if (!Object.hasOwn(value, index)) {
|
|
15265
|
+
throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15266
|
+
}
|
|
15267
|
+
result[index] = requiredText3(value[index], `${context}[${index}]`);
|
|
15268
|
+
}
|
|
15269
|
+
return result;
|
|
15270
|
+
}
|
|
15271
|
+
function requiredText3(value, context) {
|
|
15272
|
+
if (typeof value === "string") return value;
|
|
15273
|
+
if (import_node_buffer51.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
|
15274
|
+
return import_node_buffer51.Buffer.from(value).toString("utf8");
|
|
15275
|
+
}
|
|
15276
|
+
throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15277
|
+
}
|
|
15278
|
+
function optionalText3(value, context) {
|
|
15279
|
+
return value == null ? void 0 : requiredText3(value, context);
|
|
15280
|
+
}
|
|
15281
|
+
function nonNegativeInteger2(value, context) {
|
|
15282
|
+
let parsed;
|
|
15283
|
+
try {
|
|
15284
|
+
parsed = integer(value);
|
|
15285
|
+
} catch {
|
|
15286
|
+
throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15287
|
+
}
|
|
15288
|
+
if (parsed < 0) throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15289
|
+
return parsed;
|
|
15290
|
+
}
|
|
15291
|
+
function optionalPositiveInteger(value, context) {
|
|
15292
|
+
if (value == null) return void 0;
|
|
15293
|
+
const parsed = nonNegativeInteger2(value, context);
|
|
15294
|
+
if (parsed === 0) throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15295
|
+
return parsed;
|
|
15296
|
+
}
|
|
15297
|
+
function optionalVersion(value) {
|
|
15298
|
+
if (value == null) return void 0;
|
|
15299
|
+
if (typeof value === "number" || typeof value === "bigint") {
|
|
15300
|
+
return nonNegativeInteger2(value, "version");
|
|
15301
|
+
}
|
|
15302
|
+
return requiredText3(value, "version");
|
|
15303
|
+
}
|
|
15304
|
+
function backoffKind(value, context) {
|
|
15305
|
+
const kind = requiredText3(value, context).toLowerCase();
|
|
15306
|
+
if (kind === "none" || kind === "fixed" || kind === "linear" || kind === "exponential") {
|
|
15307
|
+
return kind;
|
|
15308
|
+
}
|
|
15309
|
+
throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15310
|
+
}
|
|
15311
|
+
function requiredMode(value, context) {
|
|
15312
|
+
const mode = requiredText3(value, context).toLowerCase();
|
|
15313
|
+
if (mode === "fifo" || mode === "parallel") return mode;
|
|
15314
|
+
throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
15315
|
+
}
|
|
15316
|
+
function optionalMode(value, context) {
|
|
15317
|
+
return value == null ? void 0 : requiredMode(value, context);
|
|
15318
|
+
}
|
|
15319
|
+
|
|
13357
15320
|
// src/client-flow-support.ts
|
|
13358
|
-
var FerricStoreFlowSupportClient = class extends
|
|
15321
|
+
var FerricStoreFlowSupportClient = class extends FerricStoreFlowQueryClient {
|
|
13359
15322
|
async rewind(id, options = {}) {
|
|
13360
15323
|
const partitionKey = options.partitionKey;
|
|
13361
15324
|
const returnRecord = options.returnRecord === true;
|
|
@@ -13381,43 +15344,9 @@ var FerricStoreFlowSupportClient = class extends FerricStoreManagementClient {
|
|
|
13381
15344
|
}
|
|
13382
15345
|
return flowRecordFromResp(response, this.codec);
|
|
13383
15346
|
}
|
|
13384
|
-
async list(type, options = {}) {
|
|
13385
|
-
return await this.indexQuery("FLOW.LIST", type, options);
|
|
13386
|
-
}
|
|
13387
|
-
async search(type, options = {}) {
|
|
13388
|
-
const args = ["FLOW.SEARCH", type];
|
|
13389
|
-
appendReadOptions(args, options);
|
|
13390
|
-
appendAttributes(args, options.attributes);
|
|
13391
|
-
appendSearchStateMeta(args, options.state, options.stateMeta);
|
|
13392
|
-
const response = await this.commandArgs(args);
|
|
13393
|
-
return this.records(requiredArrayResponse(response, "FLOW.SEARCH"));
|
|
13394
|
-
}
|
|
13395
|
-
async terminals(type, options = {}) {
|
|
13396
|
-
return await this.indexQuery("FLOW.TERMINALS", type, options);
|
|
13397
|
-
}
|
|
13398
|
-
async failures(type, options = {}) {
|
|
13399
|
-
return await this.indexQuery("FLOW.FAILURES", type, options);
|
|
13400
|
-
}
|
|
13401
|
-
async byParent(parentFlowId, options = {}) {
|
|
13402
|
-
return await this.indexQuery("FLOW.BY_PARENT", parentFlowId, options);
|
|
13403
|
-
}
|
|
13404
|
-
async byRoot(rootFlowId, options = {}) {
|
|
13405
|
-
return await this.indexQuery("FLOW.BY_ROOT", rootFlowId, options);
|
|
13406
|
-
}
|
|
13407
|
-
async byCorrelation(correlationId, options = {}) {
|
|
13408
|
-
return await this.indexQuery("FLOW.BY_CORRELATION", correlationId, options);
|
|
13409
|
-
}
|
|
13410
15347
|
async info(type) {
|
|
13411
15348
|
return parseKvResponse(await this.command("FLOW.INFO", type));
|
|
13412
15349
|
}
|
|
13413
|
-
async stuck(type, options = {}) {
|
|
13414
|
-
const args = ["FLOW.STUCK", type];
|
|
13415
|
-
append(args, "PARTITION", options.partitionKey);
|
|
13416
|
-
append(args, "COUNT", options.count);
|
|
13417
|
-
append(args, "OLDER_THAN", options.olderThanMs);
|
|
13418
|
-
append(args, "NOW", options.nowMs);
|
|
13419
|
-
return this.records(arrayResponse(await this.commandArgs(args)));
|
|
13420
|
-
}
|
|
13421
15350
|
async history(id, options = {}) {
|
|
13422
15351
|
const args = ["FLOW.HISTORY", id];
|
|
13423
15352
|
append(args, "PARTITION", options.partitionKey);
|
|
@@ -13496,27 +15425,36 @@ var FerricStoreFlowSupportClient = class extends FerricStoreManagementClient {
|
|
|
13496
15425
|
}
|
|
13497
15426
|
async installPolicy(type, options = {}) {
|
|
13498
15427
|
const args = ["FLOW.POLICY.SET", type];
|
|
15428
|
+
const expectedGeneration = Object.hasOwn(options, "expectedGeneration") ? options.expectedGeneration : void 0;
|
|
15429
|
+
const replace = Object.hasOwn(options, "replace") ? options.replace : void 0;
|
|
15430
|
+
if (expectedGeneration != null) assertFlowPolicyGeneration(expectedGeneration);
|
|
15431
|
+
if (replace != null && typeof replace !== "boolean") {
|
|
15432
|
+
throw new TypeError("replace must be a boolean");
|
|
15433
|
+
}
|
|
15434
|
+
append(args, "EXPECTED_GENERATION", expectedGeneration);
|
|
15435
|
+
appendBool(args, "REPLACE", replace);
|
|
13499
15436
|
if (options.indexedAttributes != null) {
|
|
13500
15437
|
args.push("INDEXED_ATTRIBUTES", JSON.stringify(options.indexedAttributes));
|
|
13501
15438
|
}
|
|
13502
15439
|
append(args, "INDEXED_STATE_META", options.indexedStateMeta);
|
|
13503
15440
|
append(args, "MAX_ACTIVE_MS", options.maxActiveMs);
|
|
15441
|
+
if (options.state == null) append(args, "RETENTION_TTL_MS", options.retentionTtlMs);
|
|
13504
15442
|
append(args, "STATE", options.state);
|
|
13505
15443
|
appendPolicyMode(args, options.state, options.mode);
|
|
13506
15444
|
if (options.retry != null) {
|
|
13507
15445
|
appendRetryPolicy(args, options.retry);
|
|
13508
15446
|
}
|
|
15447
|
+
if (options.state != null) append(args, "RETENTION_TTL_MS", options.retentionTtlMs);
|
|
13509
15448
|
for (const [state, policy] of Object.entries(options.states ?? {})) {
|
|
13510
15449
|
args.push("STATE", state);
|
|
13511
15450
|
appendFlowStatePolicy(args, policy);
|
|
13512
15451
|
}
|
|
13513
|
-
|
|
13514
|
-
return await this.commandArgs(args);
|
|
15452
|
+
return flowPolicySnapshotFromResp(await this.commandArgs(args));
|
|
13515
15453
|
}
|
|
13516
15454
|
async policyGet(type, options = {}) {
|
|
13517
15455
|
const args = ["FLOW.POLICY.GET", type];
|
|
13518
15456
|
append(args, "STATE", options.state);
|
|
13519
|
-
return
|
|
15457
|
+
return flowPolicySnapshotFromResp(await this.commandArgs(args));
|
|
13520
15458
|
}
|
|
13521
15459
|
async retentionCleanup() {
|
|
13522
15460
|
return parseKvResponse(await this.command("FLOW.RETENTION_CLEANUP"));
|
|
@@ -13538,16 +15476,6 @@ var FerricStoreFlowSupportClient = class extends FerricStoreManagementClient {
|
|
|
13538
15476
|
}
|
|
13539
15477
|
return record;
|
|
13540
15478
|
}
|
|
13541
|
-
records(values) {
|
|
13542
|
-
const records = new Array(values.length);
|
|
13543
|
-
for (let index = 0; index < values.length; index += 1) {
|
|
13544
|
-
if (!Object.hasOwn(values, index)) {
|
|
13545
|
-
throw new TypeError(`Flow record response item ${index} is missing`);
|
|
13546
|
-
}
|
|
13547
|
-
records[index] = flowRecordFromResp(values[index], this.codec);
|
|
13548
|
-
}
|
|
13549
|
-
return records;
|
|
13550
|
-
}
|
|
13551
15479
|
recordsOrResponse(value) {
|
|
13552
15480
|
if (Array.isArray(value) && value.every(isRecordLike)) {
|
|
13553
15481
|
return this.records(value);
|
|
@@ -13577,12 +15505,6 @@ var FerricStoreFlowSupportClient = class extends FerricStoreManagementClient {
|
|
|
13577
15505
|
}
|
|
13578
15506
|
return results;
|
|
13579
15507
|
}
|
|
13580
|
-
async indexQuery(command, key, options) {
|
|
13581
|
-
const args = [command, key];
|
|
13582
|
-
appendReadOptions(args, options);
|
|
13583
|
-
const response = await this.commandArgs(args);
|
|
13584
|
-
return this.records(requiredArrayResponse(response, command));
|
|
13585
|
-
}
|
|
13586
15508
|
appendPartitionOptions(args, options) {
|
|
13587
15509
|
if (options.partitionKey != null && options.partitionKeys != null) {
|
|
13588
15510
|
throw new Error("partitionKey and partitionKeys are mutually exclusive");
|
|
@@ -13605,7 +15527,7 @@ var FerricStoreFlowSupportClient = class extends FerricStoreManagementClient {
|
|
|
13605
15527
|
};
|
|
13606
15528
|
|
|
13607
15529
|
// src/flow-many-snapshot.ts
|
|
13608
|
-
var
|
|
15530
|
+
var import_node_buffer53 = require("buffer");
|
|
13609
15531
|
var encodedOptionFields = ["error", "payload", "reason", "result"];
|
|
13610
15532
|
function snapshotCreateItem(item, codec) {
|
|
13611
15533
|
const snapshot = {
|
|
@@ -13623,9 +15545,9 @@ function snapshotCreateItem(item, codec) {
|
|
|
13623
15545
|
function snapshotFlowManyOptions(options, codec) {
|
|
13624
15546
|
const snapshot = { ...options };
|
|
13625
15547
|
const mutable = snapshot;
|
|
13626
|
-
for (const
|
|
13627
|
-
const value = options[
|
|
13628
|
-
if (value != null) mutable[
|
|
15548
|
+
for (const field3 of encodedOptionFields) {
|
|
15549
|
+
const value = options[field3];
|
|
15550
|
+
if (value != null) mutable[field3] = snapshotFlowValue(codec, value);
|
|
13629
15551
|
}
|
|
13630
15552
|
if (options.attributes != null) mutable.attributes = snapshotCommandRecord(options.attributes);
|
|
13631
15553
|
if (options.attributesMerge != null) {
|
|
@@ -13645,7 +15567,7 @@ function snapshotFlowManyOptions(options, codec) {
|
|
|
13645
15567
|
}
|
|
13646
15568
|
function snapshotClaimedItem(item) {
|
|
13647
15569
|
const wire = item[CLAIMED_ITEM_WIRE];
|
|
13648
|
-
const leaseToken =
|
|
15570
|
+
const leaseToken = import_node_buffer53.Buffer.from(wire?.leaseToken ?? item.leaseToken);
|
|
13649
15571
|
const snapshot = {
|
|
13650
15572
|
...item,
|
|
13651
15573
|
fencingToken: wire?.fencingToken ?? item.fencingToken,
|
|
@@ -13662,15 +15584,15 @@ function snapshotClaimedItem(item) {
|
|
|
13662
15584
|
function snapshotFencedItem(item) {
|
|
13663
15585
|
return Object.freeze({
|
|
13664
15586
|
...item,
|
|
13665
|
-
...item.leaseToken == null ? {} : { leaseToken:
|
|
15587
|
+
...item.leaseToken == null ? {} : { leaseToken: import_node_buffer53.Buffer.from(item.leaseToken) }
|
|
13666
15588
|
});
|
|
13667
15589
|
}
|
|
13668
15590
|
function snapshotClaimedItemWire(wire, leaseToken) {
|
|
13669
15591
|
return Object.freeze({
|
|
13670
15592
|
fencingToken: wire.fencingToken,
|
|
13671
|
-
id:
|
|
15593
|
+
id: import_node_buffer53.Buffer.from(wire.id),
|
|
13672
15594
|
leaseToken,
|
|
13673
|
-
partitionKey: wire.partitionKey == null ? wire.partitionKey :
|
|
15595
|
+
partitionKey: wire.partitionKey == null ? wire.partitionKey : import_node_buffer53.Buffer.from(wire.partitionKey)
|
|
13674
15596
|
});
|
|
13675
15597
|
}
|
|
13676
15598
|
function snapshotArray(values) {
|
|
@@ -13681,7 +15603,7 @@ function snapshotArray(values) {
|
|
|
13681
15603
|
return Object.freeze(snapshot);
|
|
13682
15604
|
}
|
|
13683
15605
|
function snapshotStateMeta(stateMeta) {
|
|
13684
|
-
return snapshotRecord(stateMeta, (value) =>
|
|
15606
|
+
return snapshotRecord(stateMeta, (value) => import_node_buffer53.Buffer.isBuffer(value) ? import_node_buffer53.Buffer.from(value) : value);
|
|
13685
15607
|
}
|
|
13686
15608
|
function snapshotCommandRecord(values) {
|
|
13687
15609
|
const seen = /* @__PURE__ */ new WeakMap();
|
|
@@ -13699,7 +15621,7 @@ function snapshotRecord(values, capture) {
|
|
|
13699
15621
|
}
|
|
13700
15622
|
function snapshotCommandArgument(value, seen) {
|
|
13701
15623
|
if (typeof value !== "object" || value == null) return value;
|
|
13702
|
-
if (
|
|
15624
|
+
if (import_node_buffer53.Buffer.isBuffer(value) || value instanceof Uint8Array) return import_node_buffer53.Buffer.from(value);
|
|
13703
15625
|
const objectValue = value;
|
|
13704
15626
|
const existing = seen.get(objectValue);
|
|
13705
15627
|
if (existing != null) return existing;
|
|
@@ -14686,6 +16608,142 @@ function nativeOptionsForBootstrap(options, signal) {
|
|
|
14686
16608
|
};
|
|
14687
16609
|
}
|
|
14688
16610
|
|
|
16611
|
+
// src/flow-query-projection.ts
|
|
16612
|
+
var import_node_buffer54 = require("buffer");
|
|
16613
|
+
var MAX_PROJECTION_FIELDS = 32;
|
|
16614
|
+
var MAX_DYNAMIC_NAME_BYTES = 64;
|
|
16615
|
+
var FIELD_BRAND = /* @__PURE__ */ Symbol("FerricStoreFlowProjectionField");
|
|
16616
|
+
function field2(source, selector) {
|
|
16617
|
+
return Object.freeze({ source, selector, [FIELD_BRAND]: true });
|
|
16618
|
+
}
|
|
16619
|
+
var run = Object.freeze({
|
|
16620
|
+
id: field2("runs", "run_id"),
|
|
16621
|
+
type: field2("runs", "type"),
|
|
16622
|
+
state: field2("runs", "state"),
|
|
16623
|
+
version: field2("runs", "version"),
|
|
16624
|
+
priority: field2("runs", "priority"),
|
|
16625
|
+
partitionKey: field2("runs", "partition_key"),
|
|
16626
|
+
createdAtMs: field2("runs", "created_at_ms"),
|
|
16627
|
+
updatedAtMs: field2("runs", "updated_at_ms"),
|
|
16628
|
+
nextRunAtMs: field2("runs", "next_run_at_ms"),
|
|
16629
|
+
leaseDeadlineMs: field2("runs", "lease_deadline_ms"),
|
|
16630
|
+
attempts: field2("runs", "attempts"),
|
|
16631
|
+
runState: field2("runs", "run_state"),
|
|
16632
|
+
maxActiveMs: field2("runs", "max_active_ms"),
|
|
16633
|
+
parentFlowId: field2("runs", "parent_flow_id"),
|
|
16634
|
+
rootFlowId: field2("runs", "root_flow_id"),
|
|
16635
|
+
correlationId: field2("runs", "correlation_id"),
|
|
16636
|
+
attributes: field2("runs", "attributes"),
|
|
16637
|
+
stateMetadata: field2("runs", "state_meta"),
|
|
16638
|
+
attribute(name) {
|
|
16639
|
+
return field2("runs", `attribute[${quoteName(name, false)}]`);
|
|
16640
|
+
},
|
|
16641
|
+
stateMeta(state, name) {
|
|
16642
|
+
return field2(
|
|
16643
|
+
"runs",
|
|
16644
|
+
`state_meta[${quoteName(state, true)}][${quoteName(name, false)}]`
|
|
16645
|
+
);
|
|
16646
|
+
}
|
|
16647
|
+
});
|
|
16648
|
+
var event = Object.freeze({
|
|
16649
|
+
id: field2("events", "event_id"),
|
|
16650
|
+
fields: field2("events", "fields"),
|
|
16651
|
+
field(name) {
|
|
16652
|
+
return field2("events", `fields[${quoteName(name, false)}]`);
|
|
16653
|
+
}
|
|
16654
|
+
});
|
|
16655
|
+
var FlowProjection = Object.freeze({ run, event });
|
|
16656
|
+
function projectFlowQuery(query, shape, ...fields) {
|
|
16657
|
+
validateFlowQueryText(query);
|
|
16658
|
+
if (shape !== "record" && shape !== "records") {
|
|
16659
|
+
throw new TypeError("Flow query projection shape must be record or records");
|
|
16660
|
+
}
|
|
16661
|
+
if (fields.length === 0 || fields.length > MAX_PROJECTION_FIELDS) {
|
|
16662
|
+
throw new TypeError(
|
|
16663
|
+
`Flow query projection must contain 1..${MAX_PROJECTION_FIELDS} fields`
|
|
16664
|
+
);
|
|
16665
|
+
}
|
|
16666
|
+
if (!fields.every((item) => item?.[FIELD_BRAND])) {
|
|
16667
|
+
throw new TypeError("Flow query projection accepts only FlowProjection fields");
|
|
16668
|
+
}
|
|
16669
|
+
const source = querySource(query);
|
|
16670
|
+
if (fields.some((item) => item.source !== source)) {
|
|
16671
|
+
throw new TypeError(`Flow query projection fields must belong to ${source}`);
|
|
16672
|
+
}
|
|
16673
|
+
const selectors = fields.map((item) => item.selector);
|
|
16674
|
+
if (new Set(selectors).size !== selectors.length) {
|
|
16675
|
+
throw new TypeError("Flow query projection contains a duplicate field");
|
|
16676
|
+
}
|
|
16677
|
+
if (containsReturnKeyword(query)) {
|
|
16678
|
+
throw new TypeError("Flow query already contains a RETURN clause");
|
|
16679
|
+
}
|
|
16680
|
+
const trimmed = query.trim();
|
|
16681
|
+
const base = trimmed.endsWith(";") ? trimmed.slice(0, -1).trimEnd() : trimmed;
|
|
16682
|
+
const result = `${base} RETURN ${shape.toUpperCase()} (${selectors.join(", ")})`;
|
|
16683
|
+
if (import_node_buffer54.Buffer.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
|
|
16684
|
+
throw new TypeError(`FLOW.QUERY query exceeds ${FLOW_QUERY_MAX_BYTES} bytes`);
|
|
16685
|
+
}
|
|
16686
|
+
return result;
|
|
16687
|
+
}
|
|
16688
|
+
function querySource(query) {
|
|
16689
|
+
const match = /^\s*FROM\s+(runs|events)\b/iu.exec(query);
|
|
16690
|
+
if (match?.[1] == null) {
|
|
16691
|
+
throw new TypeError("Projected Flow query must start with FROM runs or FROM events");
|
|
16692
|
+
}
|
|
16693
|
+
return match[1].toLowerCase();
|
|
16694
|
+
}
|
|
16695
|
+
function containsReturnKeyword(query) {
|
|
16696
|
+
let quoted = false;
|
|
16697
|
+
for (let index = 0; index < query.length; ) {
|
|
16698
|
+
const character = query.charAt(index);
|
|
16699
|
+
if (character === "'") {
|
|
16700
|
+
if (quoted && query[index + 1] === "'") {
|
|
16701
|
+
index += 2;
|
|
16702
|
+
continue;
|
|
16703
|
+
}
|
|
16704
|
+
quoted = !quoted;
|
|
16705
|
+
index += 1;
|
|
16706
|
+
continue;
|
|
16707
|
+
}
|
|
16708
|
+
if (!quoted && /[A-Za-z_]/u.test(character)) {
|
|
16709
|
+
let end = index + 1;
|
|
16710
|
+
while (end < query.length && /[A-Za-z0-9_]/u.test(query.charAt(end))) end += 1;
|
|
16711
|
+
if (query.slice(index, end).toUpperCase() === "RETURN") return true;
|
|
16712
|
+
index = end;
|
|
16713
|
+
continue;
|
|
16714
|
+
}
|
|
16715
|
+
index += 1;
|
|
16716
|
+
}
|
|
16717
|
+
return false;
|
|
16718
|
+
}
|
|
16719
|
+
function quoteName(value, allowPrivate) {
|
|
16720
|
+
if (typeof value !== "string") {
|
|
16721
|
+
throw new TypeError("Flow query projection metadata name must be text");
|
|
16722
|
+
}
|
|
16723
|
+
validateUnicodeScalarText2(value);
|
|
16724
|
+
const size = import_node_buffer54.Buffer.byteLength(value, "utf8");
|
|
16725
|
+
if (size === 0 || size > MAX_DYNAMIC_NAME_BYTES || !allowPrivate && value.startsWith("__")) {
|
|
16726
|
+
throw new TypeError(
|
|
16727
|
+
`Flow query projection metadata names must be 1..${MAX_DYNAMIC_NAME_BYTES} UTF-8 bytes`
|
|
16728
|
+
);
|
|
16729
|
+
}
|
|
16730
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
16731
|
+
}
|
|
16732
|
+
function validateUnicodeScalarText2(value) {
|
|
16733
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
16734
|
+
const code = value.charCodeAt(index);
|
|
16735
|
+
if (code >= 55296 && code <= 56319) {
|
|
16736
|
+
const low = value.charCodeAt(index + 1);
|
|
16737
|
+
if (!(low >= 56320 && low <= 57343)) {
|
|
16738
|
+
throw new TypeError("Flow query projection metadata name must be valid UTF-8");
|
|
16739
|
+
}
|
|
16740
|
+
index += 1;
|
|
16741
|
+
} else if (code >= 56320 && code <= 57343) {
|
|
16742
|
+
throw new TypeError("Flow query projection metadata name must be valid UTF-8");
|
|
16743
|
+
}
|
|
16744
|
+
}
|
|
16745
|
+
}
|
|
16746
|
+
|
|
14689
16747
|
// src/outcomes.ts
|
|
14690
16748
|
var OUTCOME_BRAND = /* @__PURE__ */ Symbol("ferricstore.outcome");
|
|
14691
16749
|
function transition(toState, options = {}) {
|
|
@@ -14765,7 +16823,7 @@ var LeaseRenewalGuard = class {
|
|
|
14765
16823
|
if (options.leaseRenewal === false) {
|
|
14766
16824
|
return;
|
|
14767
16825
|
}
|
|
14768
|
-
const intervalMs =
|
|
16826
|
+
const intervalMs = positiveInteger2(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
|
|
14769
16827
|
this.timer = setLongInterval(() => this.renew(), intervalMs);
|
|
14770
16828
|
this.timer.unref();
|
|
14771
16829
|
}
|
|
@@ -14837,7 +16895,7 @@ function snapshotLeasedJob(job) {
|
|
|
14837
16895
|
return snapshot;
|
|
14838
16896
|
}
|
|
14839
16897
|
function workerConcurrency(options) {
|
|
14840
|
-
return
|
|
16898
|
+
return positiveInteger2(options.concurrency ?? options.workers, 1);
|
|
14841
16899
|
}
|
|
14842
16900
|
function workerRefillStrategy(options) {
|
|
14843
16901
|
return options.refillStrategy === "wave" ? "wave" : "continuous";
|
|
@@ -14880,18 +16938,18 @@ function workerErrorPayload(error, options, codec) {
|
|
|
14880
16938
|
}
|
|
14881
16939
|
function workerBatchSize(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
|
|
14882
16940
|
return Math.min(
|
|
14883
|
-
|
|
14884
|
-
|
|
16941
|
+
positiveInteger2(options.batchSize, 10),
|
|
16942
|
+
positiveInteger2(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
|
|
14885
16943
|
);
|
|
14886
16944
|
}
|
|
14887
16945
|
function workerClaimLimit(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
|
|
14888
16946
|
return Math.min(workerBatchSize(options, flowManyBatchLimit), workerConcurrency(options));
|
|
14889
16947
|
}
|
|
14890
16948
|
function workerDrainBatches(options) {
|
|
14891
|
-
return
|
|
16949
|
+
return positiveInteger2(options.claimDrainBatches, 1);
|
|
14892
16950
|
}
|
|
14893
16951
|
function workerLeaseMs(options, fallback = 3e4) {
|
|
14894
|
-
return
|
|
16952
|
+
return positiveInteger2(options.leaseMs, positiveInteger2(fallback, 3e4));
|
|
14895
16953
|
}
|
|
14896
16954
|
function workerIdleSleepMs(options) {
|
|
14897
16955
|
return nonNegativeDuration(options.idleSleepMs, 250);
|
|
@@ -14903,7 +16961,7 @@ function workerClaimBlockMs(options, useBlocking) {
|
|
|
14903
16961
|
if (options.signal == null || !Number.isFinite(options.blockMs) || options.blockMs < 0) {
|
|
14904
16962
|
return options.blockMs;
|
|
14905
16963
|
}
|
|
14906
|
-
const abortPollMs =
|
|
16964
|
+
const abortPollMs = positiveInteger2(options.abortPollMs, 1e3);
|
|
14907
16965
|
return options.blockMs === 0 ? abortPollMs : Math.min(Math.trunc(options.blockMs), abortPollMs);
|
|
14908
16966
|
}
|
|
14909
16967
|
function workerMaxIdleSleepMs(options, idleSleepMs = workerIdleSleepMs(options)) {
|
|
@@ -14914,14 +16972,14 @@ function nextWorkerIdleSleepMs(currentIdleSleepMs, maxIdleSleepMs) {
|
|
|
14914
16972
|
return Math.min(maxIdleSleepMs, Math.max(1, currentIdleSleepMs * 2));
|
|
14915
16973
|
}
|
|
14916
16974
|
async function runContinuousWorkerPool(options) {
|
|
14917
|
-
const concurrency =
|
|
14918
|
-
const maxClaimSize =
|
|
16975
|
+
const concurrency = positiveInteger2(options.concurrency, 1);
|
|
16976
|
+
const maxClaimSize = positiveInteger2(options.maxClaimSize, concurrency);
|
|
14919
16977
|
const initialIdleSleepMs = nonNegativeDuration(options.idleSleepMs, 250);
|
|
14920
16978
|
const maxIdleSleepMs = Math.max(
|
|
14921
16979
|
initialIdleSleepMs,
|
|
14922
16980
|
nonNegativeDuration(options.maxIdleSleepMs, 5e3)
|
|
14923
16981
|
);
|
|
14924
|
-
const refillDelayMs =
|
|
16982
|
+
const refillDelayMs = nonNegativeInteger3(options.refillDelayMs, 0);
|
|
14925
16983
|
const active = /* @__PURE__ */ new Set();
|
|
14926
16984
|
const pending = [];
|
|
14927
16985
|
let pendingIndex = 0;
|
|
@@ -15037,10 +17095,10 @@ function normalizeWorkflowWorkerConfig(options) {
|
|
|
15037
17095
|
...captured
|
|
15038
17096
|
});
|
|
15039
17097
|
}
|
|
15040
|
-
function
|
|
17098
|
+
function positiveInteger2(value, fallback) {
|
|
15041
17099
|
return value == null || !Number.isFinite(value) ? fallback : Math.max(1, Math.trunc(value));
|
|
15042
17100
|
}
|
|
15043
|
-
function
|
|
17101
|
+
function nonNegativeInteger3(value, fallback) {
|
|
15044
17102
|
return value == null || !Number.isFinite(value) ? fallback : Math.max(0, Math.trunc(value));
|
|
15045
17103
|
}
|
|
15046
17104
|
function nonNegativeDuration(value, fallback) {
|
|
@@ -16456,6 +18514,7 @@ var Workflow = class {
|
|
|
16456
18514
|
}
|
|
16457
18515
|
return await this.client.installPolicy(this.type, {
|
|
16458
18516
|
...options,
|
|
18517
|
+
replace: Object.hasOwn(options, "replace") ? options.replace ?? true : true,
|
|
16459
18518
|
states
|
|
16460
18519
|
});
|
|
16461
18520
|
}
|
|
@@ -16668,8 +18727,8 @@ var WorkflowWorker = class {
|
|
|
16668
18727
|
};
|
|
16669
18728
|
|
|
16670
18729
|
// src/version.ts
|
|
16671
|
-
var FERRICSTORE_SDK_VERSION = "0.
|
|
16672
|
-
var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.
|
|
18730
|
+
var FERRICSTORE_SDK_VERSION = "0.5.0";
|
|
18731
|
+
var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.0";
|
|
16673
18732
|
var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
16674
18733
|
// Annotate the CommonJS export names for ESM import in node:
|
|
16675
18734
|
0 && (module.exports = {
|
|
@@ -16688,6 +18747,8 @@ var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
|
16688
18747
|
FlowAlreadyExistsError,
|
|
16689
18748
|
FlowBatchError,
|
|
16690
18749
|
FlowNotFoundError,
|
|
18750
|
+
FlowProjection,
|
|
18751
|
+
FlowQueryError,
|
|
16691
18752
|
FlowWrongStateError,
|
|
16692
18753
|
GeoStore,
|
|
16693
18754
|
HashStore,
|
|
@@ -16699,6 +18760,7 @@ var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
|
16699
18760
|
ListStore,
|
|
16700
18761
|
LockHeldError,
|
|
16701
18762
|
LockNotOwnedError,
|
|
18763
|
+
MAX_FLOW_POLICY_GENERATION,
|
|
16702
18764
|
NativeAdapter,
|
|
16703
18765
|
OverloadedError,
|
|
16704
18766
|
Queue,
|
|
@@ -16713,6 +18775,7 @@ var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
|
16713
18775
|
SetStore,
|
|
16714
18776
|
SortedSetStore,
|
|
16715
18777
|
StaleLeaseError,
|
|
18778
|
+
StalePolicyGenerationError,
|
|
16716
18779
|
StreamStore,
|
|
16717
18780
|
TDigestStore,
|
|
16718
18781
|
TopKStore,
|
|
@@ -16728,6 +18791,7 @@ var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
|
16728
18791
|
isOutcome,
|
|
16729
18792
|
isReconnectableClosedConnectionError,
|
|
16730
18793
|
mapException,
|
|
18794
|
+
projectFlowQuery,
|
|
16731
18795
|
retry,
|
|
16732
18796
|
transition
|
|
16733
18797
|
});
|