@ferricstore/ferricstore 0.11.8 → 0.11.10
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 +43 -3
- package/dist/index.cjs +1001 -157
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -2
- package/dist/index.d.ts +42 -2
- package/dist/index.js +991 -150
- package/dist/index.js.map +1 -1
- package/docs/api/assets/hierarchy.js +1 -1
- package/docs/api/assets/highlight.css +1 -1
- package/docs/api/assets/main.js +1 -1
- package/docs/api/assets/navigation.js +1 -1
- package/docs/api/assets/search.js +1 -1
- package/docs/api/assets/style.css +18 -3
- package/docs/api/classes/BitmapStore.html +192 -3
- package/docs/api/classes/BloomFilterStore.html +197 -3
- package/docs/api/classes/ClaimHydrationError.html +202 -7
- package/docs/api/classes/ConnectionClosedError.html +193 -8
- package/docs/api/classes/CountMinSketchStore.html +171 -3
- package/docs/api/classes/CuckooFilterStore.html +196 -3
- package/docs/api/classes/FerricStoreClient.html +2888 -7
- package/docs/api/classes/FerricStoreError.html +197 -7
- package/docs/api/classes/FlowAlreadyExistsError.html +185 -7
- package/docs/api/classes/FlowBatchError.html +204 -8
- package/docs/api/classes/FlowNotFoundError.html +185 -7
- package/docs/api/classes/FlowQueryError.html +204 -7
- package/docs/api/classes/FlowWrongStateError.html +185 -7
- package/docs/api/classes/GeoStore.html +188 -3
- package/docs/api/classes/HTTPAdapter.html +144 -0
- package/docs/api/classes/HTTPTransportError.html +222 -0
- package/docs/api/classes/HashStore.html +493 -3
- package/docs/api/classes/HyperLogLogStore.html +148 -3
- package/docs/api/classes/InvalidCommandError.html +185 -7
- package/docs/api/classes/JsonCodec.html +104 -3
- package/docs/api/classes/KeyValueStore.html +794 -3
- package/docs/api/classes/LeaseRenewalError.html +157 -8
- package/docs/api/classes/ListStore.html +451 -3
- package/docs/api/classes/LockHeldError.html +185 -7
- package/docs/api/classes/LockNotOwnedError.html +185 -7
- package/docs/api/classes/NativeAdapter.html +135 -3
- package/docs/api/classes/OverloadedError.html +190 -7
- package/docs/api/classes/Queue.html +141 -4
- package/docs/api/classes/QueueClient.html +97 -4
- package/docs/api/classes/QueueCompletionError.html +163 -8
- package/docs/api/classes/QueueWorker.html +153 -4
- package/docs/api/classes/RawCodec.html +96 -3
- package/docs/api/classes/ReconnectingExecutor.html +180 -5
- package/docs/api/classes/RequestTimeoutError.html +199 -8
- package/docs/api/classes/RerouteError.html +188 -8
- package/docs/api/classes/RoutingTopology.html +125 -3
- package/docs/api/classes/SetStore.html +363 -3
- package/docs/api/classes/SortedSetStore.html +369 -3
- package/docs/api/classes/StaleLeaseError.html +185 -7
- package/docs/api/classes/StalePolicyGenerationError.html +188 -8
- package/docs/api/classes/StreamStore.html +259 -3
- package/docs/api/classes/TDigestStore.html +348 -3
- package/docs/api/classes/TopKStore.html +229 -3
- package/docs/api/classes/TopologyNativeAdapterPool.html +180 -5
- package/docs/api/classes/Workflow.html +266 -4
- package/docs/api/classes/WorkflowClient.html +97 -4
- package/docs/api/classes/WorkflowContext.html +293 -5
- package/docs/api/classes/WorkflowFlowCommands.html +251 -3
- package/docs/api/classes/WorkflowWorker.html +108 -4
- package/docs/api/functions/classifyServerError.html +44 -1
- package/docs/api/functions/complete.html +41 -1
- package/docs/api/functions/fail.html +41 -1
- package/docs/api/functions/httpCommandDisposition.html +41 -0
- package/docs/api/functions/isOutcome.html +41 -1
- package/docs/api/functions/isReconnectableClosedConnectionError.html +41 -1
- package/docs/api/functions/mapException.html +41 -1
- package/docs/api/functions/projectFlowQuery.html +43 -1
- package/docs/api/functions/retry.html +41 -1
- package/docs/api/functions/transition.html +42 -1
- package/docs/api/hierarchy.html +112 -1
- package/docs/api/index.html +78 -5
- package/docs/api/interfaces/AdminListOptions.html +70 -2
- package/docs/api/interfaces/ApprovalListOptions.html +74 -2
- package/docs/api/interfaces/ApprovalRequestOptions.html +99 -2
- package/docs/api/interfaces/AttributeQueryOptions.html +69 -2
- package/docs/api/interfaces/AutoBatchOptions.html +72 -3
- package/docs/api/interfaces/BackpressurePolicy.html +69 -2
- package/docs/api/interfaces/BudgetCommitOptions.html +59 -2
- package/docs/api/interfaces/BudgetReserveOptions.html +69 -2
- package/docs/api/interfaces/CancelOptions.html +135 -2
- package/docs/api/interfaces/ChildSpec.html +79 -2
- package/docs/api/interfaces/CircuitOpenOptions.html +64 -2
- package/docs/api/interfaces/ClaimDueOptions.html +146 -3
- package/docs/api/interfaces/ClaimHydrationItem.html +59 -2
- package/docs/api/interfaces/ClaimedItem.html +100 -3
- package/docs/api/interfaces/Codec.html +84 -2
- package/docs/api/interfaces/CommandExecutor.html +145 -4
- package/docs/api/interfaces/CompleteJobsAndClaimJobsResult.html +84 -7
- package/docs/api/interfaces/CompleteManyOptions.html +114 -2
- package/docs/api/interfaces/CompleteOptions.html +143 -2
- package/docs/api/interfaces/CompleteOutcome.html +117 -2
- package/docs/api/interfaces/CountMinMergeOptions.html +54 -2
- package/docs/api/interfaces/CreateItem.html +84 -2
- package/docs/api/interfaces/CreateManyOptions.html +173 -6
- package/docs/api/interfaces/CreateOptions.html +143 -4
- package/docs/api/interfaces/EffectCompensateOptions.html +89 -2
- package/docs/api/interfaces/EffectConfirmOptions.html +89 -2
- package/docs/api/interfaces/EffectFailOptions.html +94 -2
- package/docs/api/interfaces/EffectReserveOptions.html +84 -2
- package/docs/api/interfaces/EffectStatusOptions.html +77 -2
- package/docs/api/interfaces/ExecutePipelineOptions.html +68 -4
- package/docs/api/interfaces/ExtendLeaseOptions.html +79 -2
- package/docs/api/interfaces/FailOptions.html +143 -2
- package/docs/api/interfaces/FailOutcome.html +117 -2
- package/docs/api/interfaces/FencedItem.html +69 -2
- package/docs/api/interfaces/FerricStoreClientFromUrlOptions.html +105 -4
- package/docs/api/interfaces/FerricStoreClientOptions.html +84 -4
- package/docs/api/interfaces/FetchOrComputeComputeResult.html +83 -4
- package/docs/api/interfaces/FetchOrComputeHitResult.html +78 -2
- package/docs/api/interfaces/FlowBatchCompletedItem.html +59 -2
- package/docs/api/interfaces/FlowEventProjectionField.html +64 -2
- package/docs/api/interfaces/FlowExplainCapabilities.html +69 -2
- package/docs/api/interfaces/FlowExplainResult.html +124 -2
- package/docs/api/interfaces/FlowMaxActiveFailure.html +59 -2
- package/docs/api/interfaces/FlowPolicyBackoffSnapshot.html +69 -2
- package/docs/api/interfaces/FlowPolicyOptions.html +107 -6
- package/docs/api/interfaces/FlowPolicyRetentionSnapshot.html +59 -2
- package/docs/api/interfaces/FlowPolicyRetrySnapshot.html +64 -2
- package/docs/api/interfaces/FlowPolicySnapshot.html +121 -5
- package/docs/api/interfaces/FlowPolicyStateSnapshot.html +74 -2
- package/docs/api/interfaces/FlowQueryCountResult.html +89 -2
- package/docs/api/interfaces/FlowQueryErrorPosition.html +64 -2
- package/docs/api/interfaces/FlowQueryIndex.html +134 -2
- package/docs/api/interfaces/FlowQueryIndexBuild.html +106 -2
- package/docs/api/interfaces/FlowQueryIndexCoverage.html +69 -2
- package/docs/api/interfaces/FlowQueryIndexField.html +69 -2
- package/docs/api/interfaces/FlowQueryIndexFormat.html +79 -2
- package/docs/api/interfaces/FlowQueryIndexProgress.html +86 -2
- package/docs/api/interfaces/FlowQueryIndexRegistry.html +59 -2
- package/docs/api/interfaces/FlowQueryIndexRetirement.html +94 -2
- package/docs/api/interfaces/FlowQueryIndexServices.html +74 -2
- package/docs/api/interfaces/FlowQueryIndexStatistics.html +99 -2
- package/docs/api/interfaces/FlowQueryIndexStatus.html +84 -2
- package/docs/api/interfaces/FlowQueryIndexValidation.html +121 -2
- package/docs/api/interfaces/FlowQueryPage.html +59 -2
- package/docs/api/interfaces/FlowQueryQuality.html +69 -2
- package/docs/api/interfaces/FlowQueryRecordsResult.html +94 -2
- package/docs/api/interfaces/FlowQueryUsage.html +104 -2
- package/docs/api/interfaces/FlowRecord.html +173 -2
- package/docs/api/interfaces/FlowRunProjectionField.html +64 -2
- package/docs/api/interfaces/FlowStatePolicy.html +59 -2
- package/docs/api/interfaces/FlowStatsOptions.html +74 -2
- package/docs/api/interfaces/GeoMember.html +64 -2
- package/docs/api/interfaces/GovernanceLedgerOptions.html +74 -2
- package/docs/api/interfaces/HTTPAdapterOptions.html +124 -0
- package/docs/api/interfaces/HistoryOptions.html +124 -2
- package/docs/api/interfaces/InvocationCreateOptions.html +71 -2
- package/docs/api/interfaces/KeyInfo.html +79 -2
- package/docs/api/interfaces/LeaseMutationOptions.html +136 -2
- package/docs/api/interfaces/LimitAmountOptions.html +64 -2
- package/docs/api/interfaces/LimitLeaseOptions.html +74 -2
- package/docs/api/interfaces/LimitListOptions.html +78 -2
- package/docs/api/interfaces/LimitReleaseOptions.html +64 -2
- package/docs/api/interfaces/MutateOptions.html +110 -2
- package/docs/api/interfaces/NamedValueMutation.html +93 -2
- package/docs/api/interfaces/NativeAdapterOptions.html +175 -12
- package/docs/api/interfaces/NativeClientOptions.html +249 -16
- package/docs/api/interfaces/NativeProtocolEvent.html +69 -2
- package/docs/api/interfaces/ProtocolCommand.html +69 -2
- package/docs/api/interfaces/QueueOptions.html +64 -2
- package/docs/api/interfaces/QueueWorkerResult.html +69 -2
- package/docs/api/interfaces/RangeLimit.html +59 -2
- package/docs/api/interfaces/RateLimitResult.html +74 -2
- package/docs/api/interfaces/ReadOptions.html +107 -3
- package/docs/api/interfaces/ReclaimOptions.html +140 -3
- package/docs/api/interfaces/ReconnectOptions.html +75 -5
- package/docs/api/interfaces/RequestContext.html +64 -2
- package/docs/api/interfaces/RequestContextOptions.html +60 -2
- package/docs/api/interfaces/RetryOptions.html +143 -2
- package/docs/api/interfaces/RetryOutcome.html +117 -2
- package/docs/api/interfaces/RetryPolicy.html +79 -2
- package/docs/api/interfaces/RoutingEndpoint.html +69 -2
- package/docs/api/interfaces/RoutingRoute.html +79 -2
- package/docs/api/interfaces/RunStepsItem.html +59 -2
- package/docs/api/interfaces/RunStepsManyOptions.html +99 -2
- package/docs/api/interfaces/ScanOptions.html +66 -3
- package/docs/api/interfaces/ScheduleFireDueOptions.html +74 -2
- package/docs/api/interfaces/ScheduleFireOptions.html +59 -2
- package/docs/api/interfaces/ScheduleListOptions.html +89 -2
- package/docs/api/interfaces/ScheduleOptions.html +131 -3
- package/docs/api/interfaces/SearchOptions.html +122 -3
- package/docs/api/interfaces/StartAndClaimOptions.html +136 -3
- package/docs/api/interfaces/StateOptions.html +94 -2
- package/docs/api/interfaces/StateRegistration.html +104 -2
- package/docs/api/interfaces/StepContinueOptions.html +159 -3
- package/docs/api/interfaces/StoreCommandClient.html +89 -3
- package/docs/api/interfaces/TDigestCreateOptions.html +60 -2
- package/docs/api/interfaces/TDigestMergeOptions.html +66 -2
- package/docs/api/interfaces/TopologyNativeAdapterOptions.html +228 -15
- package/docs/api/interfaces/TransitionOptions.html +153 -2
- package/docs/api/interfaces/TransitionOutcome.html +122 -2
- package/docs/api/interfaces/ValueConfig.html +59 -2
- package/docs/api/interfaces/WorkerConfig.html +230 -15
- package/docs/api/interfaces/WorkflowOptions.html +69 -2
- package/docs/api/interfaces/WorkflowWorkerResult.html +69 -2
- package/docs/api/interfaces/XReadStream.html +59 -2
- package/docs/api/interfaces/ZAddMember.html +59 -2
- package/docs/api/modules.html +51 -1
- package/docs/api/types/BackoffKind.html +32 -1
- package/docs/api/types/CollectionScanOptions.html +34 -2
- package/docs/api/types/Command.html +32 -1
- package/docs/api/types/CommandArgument.html +32 -1
- package/docs/api/types/ConnectionRequestDisposition.html +36 -2
- package/docs/api/types/EndpointPolicy.html +34 -2
- package/docs/api/types/ExceptionPolicy.html +32 -1
- package/docs/api/types/ExpiryCondition.html +32 -1
- package/docs/api/types/FencingToken.html +34 -2
- package/docs/api/types/FetchOrComputeFencedResult.html +32 -1
- package/docs/api/types/FetchOrComputeResult.html +36 -1
- package/docs/api/types/FlowAdminRecord.html +32 -1
- package/docs/api/types/FlowPolicyBackoffKind.html +32 -1
- package/docs/api/types/FlowProjectionField.html +32 -1
- package/docs/api/types/FlowProjectionShape.html +32 -1
- package/docs/api/types/FlowQueryIndexServiceState.html +32 -1
- package/docs/api/types/FlowQueryInteger.html +32 -1
- package/docs/api/types/FlowQueryParameter.html +32 -1
- package/docs/api/types/FlowQueryParameters.html +32 -1
- package/docs/api/types/FlowQueryRecord.html +32 -1
- package/docs/api/types/FlowQueryResult.html +32 -1
- package/docs/api/types/FlowStateMode.html +32 -1
- package/docs/api/types/FlowStatePolicyLike.html +32 -1
- package/docs/api/types/GeoAddOptions.html +34 -2
- package/docs/api/types/GetExOptions.html +34 -2
- package/docs/api/types/HTTPCommandDisposition.html +32 -0
- package/docs/api/types/HashScanResult.html +38 -2
- package/docs/api/types/IntegerReply.html +34 -2
- package/docs/api/types/ManagementPairs.html +32 -1
- package/docs/api/types/MaxActiveMs.html +32 -1
- package/docs/api/types/Outcome.html +32 -1
- package/docs/api/types/QueueBatchHandler.html +44 -1
- package/docs/api/types/QueueHandler.html +44 -1
- package/docs/api/types/QueueJob.html +32 -1
- package/docs/api/types/RequestDisposition.html +32 -1
- package/docs/api/types/ScheduleCatchupPolicy.html +34 -2
- package/docs/api/types/ScheduleFireDueResult.html +55 -3
- package/docs/api/types/ScheduleFireResult.html +34 -2
- package/docs/api/types/ScheduleKind.html +32 -1
- package/docs/api/types/ScheduleOverlapPolicy.html +32 -1
- package/docs/api/types/ScheduleRecord.html +95 -12
- package/docs/api/types/ScheduleState.html +32 -1
- package/docs/api/types/SearchStateMeta.html +32 -1
- package/docs/api/types/SetOptions.html +34 -2
- package/docs/api/types/SetScanResult.html +38 -2
- package/docs/api/types/SortedSetScanResult.html +38 -2
- package/docs/api/types/StateMeta.html +32 -1
- package/docs/api/types/StateMetaValue.html +32 -1
- package/docs/api/types/TopKReserveOptions.html +32 -1
- package/docs/api/types/WorkerProfile.html +32 -1
- package/docs/api/types/WorkerRefillStrategy.html +32 -1
- package/docs/api/types/WorkflowHandler.html +44 -1
- package/docs/api/types/ZAddOptions.html +34 -2
- package/docs/api/variables/COMMAND_OPCODES.html +297 -1
- package/docs/api/variables/FERRICSTORE_MINIMUM_SERVER_VERSION.html +34 -2
- package/docs/api/variables/FERRICSTORE_NATIVE_PROTOCOL_VERSION.html +34 -2
- package/docs/api/variables/FERRICSTORE_SDK_VERSION.html +34 -2
- package/docs/api/variables/FlowProjection.html +32 -1
- package/docs/api/variables/MAX_FLOW_POLICY_GENERATION.html +32 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -28,6 +28,14 @@ var FerricStoreError = class extends Error {
|
|
|
28
28
|
this.retryAfterMs = options.retryAfterMs ?? structuredIntegerField(options.raw, "retry_after_ms");
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
+
var HTTPTransportError = class extends FerricStoreError {
|
|
32
|
+
code = "http_transport";
|
|
33
|
+
statusCode;
|
|
34
|
+
constructor(message, options = {}) {
|
|
35
|
+
super(message, options);
|
|
36
|
+
this.statusCode = options.statusCode;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
31
39
|
var ConnectionClosedError = class extends FerricStoreError {
|
|
32
40
|
code = "connection_closed";
|
|
33
41
|
requestDisposition;
|
|
@@ -1448,6 +1456,7 @@ var neverAutoBatchCommandPrefixes = /* @__PURE__ */ new Set([
|
|
|
1448
1456
|
"BLPOP",
|
|
1449
1457
|
"BRPOP",
|
|
1450
1458
|
"BRPOPLPUSH",
|
|
1459
|
+
"BZMPOP",
|
|
1451
1460
|
"BZPOPMAX",
|
|
1452
1461
|
"BZPOPMIN",
|
|
1453
1462
|
"CLIENT",
|
|
@@ -1559,6 +1568,9 @@ var connectionBlockingCommands = /* @__PURE__ */ new Set([
|
|
|
1559
1568
|
"BLPOP",
|
|
1560
1569
|
"BRPOP",
|
|
1561
1570
|
"BRPOPLPUSH",
|
|
1571
|
+
"BZMPOP",
|
|
1572
|
+
"BZPOPMAX",
|
|
1573
|
+
"BZPOPMIN",
|
|
1562
1574
|
"XREAD",
|
|
1563
1575
|
"XREADGROUP"
|
|
1564
1576
|
]);
|
|
@@ -2427,8 +2439,10 @@ function serverBlockMetadata(args) {
|
|
|
2427
2439
|
serverBlockMs = blockDurationMs(args[3], 1e3);
|
|
2428
2440
|
} else if (command === "BLMOVE" && args.length >= 6) {
|
|
2429
2441
|
serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
|
|
2430
|
-
} else if (command === "BLMPOP" && args.length >= 2) {
|
|
2442
|
+
} else if ((command === "BLMPOP" || command === "BZMPOP") && args.length >= 2) {
|
|
2431
2443
|
serverBlockMs = blockDurationMs(args[1], 1e3);
|
|
2444
|
+
} else if ((command === "BZPOPMAX" || command === "BZPOPMIN") && args.length >= 3) {
|
|
2445
|
+
serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
|
|
2432
2446
|
} else if (command === "XREAD" || command === "XREADGROUP") {
|
|
2433
2447
|
serverBlockMs = optionBlockDurationMs(args, ["BLOCK"], "STREAMS");
|
|
2434
2448
|
} else if (command === "WAIT" && args.length === 3) {
|
|
@@ -7488,6 +7502,24 @@ async function executeIndividually(host, commands, laneId, options) {
|
|
|
7488
7502
|
}, commands, options);
|
|
7489
7503
|
}
|
|
7490
7504
|
|
|
7505
|
+
// src/server-response-timeout.ts
|
|
7506
|
+
function serverResponseTimeoutMs(requestTimeoutMs, serverBlockMs) {
|
|
7507
|
+
if (serverBlockMs == null) return requestTimeoutMs;
|
|
7508
|
+
if (serverBlockMs === 0) return void 0;
|
|
7509
|
+
return saturatingAdd(requestTimeoutMs, serverBlockMs);
|
|
7510
|
+
}
|
|
7511
|
+
function combinedServerBlockMs(values) {
|
|
7512
|
+
let total;
|
|
7513
|
+
for (const value of values) {
|
|
7514
|
+
if (value === 0) return 0;
|
|
7515
|
+
if (value != null) total = saturatingAdd(total ?? 0, value);
|
|
7516
|
+
}
|
|
7517
|
+
return total;
|
|
7518
|
+
}
|
|
7519
|
+
function saturatingAdd(left, right) {
|
|
7520
|
+
return Math.min(Number.MAX_SAFE_INTEGER, left + right);
|
|
7521
|
+
}
|
|
7522
|
+
|
|
7491
7523
|
// src/native-pending-timeout.ts
|
|
7492
7524
|
function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
|
|
7493
7525
|
const pending = operations.getPending(requestId);
|
|
@@ -7516,10 +7548,7 @@ function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
|
|
|
7516
7548
|
pending.reject(new RequestTimeoutError(timeoutMs, "possibly_sent"));
|
|
7517
7549
|
}
|
|
7518
7550
|
function nativeResponseTimeoutMs(command, requestTimeoutMs) {
|
|
7519
|
-
|
|
7520
|
-
if (blockMs == null) return requestTimeoutMs;
|
|
7521
|
-
if (blockMs === 0) return void 0;
|
|
7522
|
-
return Math.min(Number.MAX_SAFE_INTEGER, requestTimeoutMs + blockMs);
|
|
7551
|
+
return serverResponseTimeoutMs(requestTimeoutMs, command.serverBlockMs);
|
|
7523
7552
|
}
|
|
7524
7553
|
|
|
7525
7554
|
// src/native-chunk-assembler.ts
|
|
@@ -8546,6 +8575,800 @@ var NativeAdapter = class _NativeAdapter {
|
|
|
8546
8575
|
}
|
|
8547
8576
|
};
|
|
8548
8577
|
|
|
8578
|
+
// src/http-command-policy.ts
|
|
8579
|
+
import { Buffer as Buffer33 } from "buffer";
|
|
8580
|
+
var nativeOnlyCommands = /* @__PURE__ */ new Set([
|
|
8581
|
+
"AUTH",
|
|
8582
|
+
"BACKPRESSURE",
|
|
8583
|
+
"CLIENT",
|
|
8584
|
+
"CLIENT.INFO",
|
|
8585
|
+
"CLIENT.SETNAME",
|
|
8586
|
+
"COMMAND_EXEC",
|
|
8587
|
+
"EVENT",
|
|
8588
|
+
"GOAWAY",
|
|
8589
|
+
"HELLO",
|
|
8590
|
+
"OPTIONS",
|
|
8591
|
+
"PIPELINE",
|
|
8592
|
+
"QUIT",
|
|
8593
|
+
"ROUTE",
|
|
8594
|
+
"ROUTE_BATCH",
|
|
8595
|
+
"SHARDS",
|
|
8596
|
+
"STARTUP",
|
|
8597
|
+
"SUBSCRIBE_EVENTS",
|
|
8598
|
+
"UNSUBSCRIBE_EVENTS",
|
|
8599
|
+
"WINDOW_UPDATE"
|
|
8600
|
+
]);
|
|
8601
|
+
var sessionOnlyCommands = /* @__PURE__ */ new Set([
|
|
8602
|
+
"ASKING",
|
|
8603
|
+
"AUTH",
|
|
8604
|
+
"CLIENT",
|
|
8605
|
+
"DISCARD",
|
|
8606
|
+
"EXEC",
|
|
8607
|
+
"HELLO",
|
|
8608
|
+
"MONITOR",
|
|
8609
|
+
"MULTI",
|
|
8610
|
+
"PSUBSCRIBE",
|
|
8611
|
+
"PSYNC",
|
|
8612
|
+
"PUNSUBSCRIBE",
|
|
8613
|
+
"QUIT",
|
|
8614
|
+
"READONLY",
|
|
8615
|
+
"READWRITE",
|
|
8616
|
+
"REPLCONF",
|
|
8617
|
+
"RESET",
|
|
8618
|
+
"SANDBOX",
|
|
8619
|
+
"SELECT",
|
|
8620
|
+
"SSUBSCRIBE",
|
|
8621
|
+
"SUBSCRIBE",
|
|
8622
|
+
"SUNSUBSCRIBE",
|
|
8623
|
+
"SYNC",
|
|
8624
|
+
"UNSUBSCRIBE",
|
|
8625
|
+
"UNWATCH",
|
|
8626
|
+
"WATCH"
|
|
8627
|
+
]);
|
|
8628
|
+
function httpCommandDisposition(name) {
|
|
8629
|
+
const normalized = name.toUpperCase();
|
|
8630
|
+
return nativeOnlyCommands.has(normalized) || sessionOnlyCommands.has(normalized) ? "native_only" : "supported";
|
|
8631
|
+
}
|
|
8632
|
+
function assertHTTPCommandSupported(name) {
|
|
8633
|
+
const normalized = normalizedCommandName(name);
|
|
8634
|
+
if (normalized == null || normalized === "") throw new TypeError("HTTP command must have a name");
|
|
8635
|
+
if (sessionOnlyCommands.has(normalized)) {
|
|
8636
|
+
throw new InvalidCommandError(`${normalized} requires a persistent native TCP session`);
|
|
8637
|
+
}
|
|
8638
|
+
if (nativeOnlyCommands.has(normalized)) {
|
|
8639
|
+
throw new InvalidCommandError(`${normalized} is a native TCP transport control command`);
|
|
8640
|
+
}
|
|
8641
|
+
}
|
|
8642
|
+
function normalizedCommandName(value) {
|
|
8643
|
+
if (typeof value === "string") return value.toUpperCase();
|
|
8644
|
+
if (Buffer33.isBuffer(value) || value instanceof Uint8Array) {
|
|
8645
|
+
return Buffer33.from(value).toString("utf8").toUpperCase();
|
|
8646
|
+
}
|
|
8647
|
+
return void 0;
|
|
8648
|
+
}
|
|
8649
|
+
|
|
8650
|
+
// src/http-envelope.ts
|
|
8651
|
+
import { Buffer as Buffer34 } from "buffer";
|
|
8652
|
+
var encoding = "ferricstore-json-v1";
|
|
8653
|
+
var bytesMarker = "$ferricstore_bytes";
|
|
8654
|
+
var mapMarker = "$ferricstore_map";
|
|
8655
|
+
var maxDepth = 64;
|
|
8656
|
+
var bytesMarkerBaseBytes = Buffer34.byteLength(bytesMarker) + 7;
|
|
8657
|
+
var mapMarkerBaseBytes = Buffer34.byteLength(mapMarker) + 7;
|
|
8658
|
+
function encodeHTTPCommands(commands, maxBytes = Number.MAX_SAFE_INTEGER) {
|
|
8659
|
+
const budget = { remaining: maxBytes };
|
|
8660
|
+
return Buffer34.from(JSON.stringify({
|
|
8661
|
+
encoding,
|
|
8662
|
+
commands: commands.map((command) => encodeValue(command, 0, budget))
|
|
8663
|
+
}));
|
|
8664
|
+
}
|
|
8665
|
+
function decodeHTTPEnvelope(source) {
|
|
8666
|
+
let parsed;
|
|
8667
|
+
try {
|
|
8668
|
+
parsed = JSON.parse(source.toString("utf8"));
|
|
8669
|
+
} catch (error) {
|
|
8670
|
+
throw new TypeError("invalid HTTP command response JSON", { cause: error });
|
|
8671
|
+
}
|
|
8672
|
+
if (!isRecord(parsed)) throw new TypeError("HTTP command response must be an object");
|
|
8673
|
+
return decodePlainRecord(parsed, 0);
|
|
8674
|
+
}
|
|
8675
|
+
function encodeValue(value, depth, budget) {
|
|
8676
|
+
if (depth > maxDepth) throw new TypeError("HTTP command value exceeds maximum depth");
|
|
8677
|
+
if (value == null) {
|
|
8678
|
+
consumeBudget(budget, 1);
|
|
8679
|
+
return value;
|
|
8680
|
+
}
|
|
8681
|
+
if (typeof value === "string") {
|
|
8682
|
+
consumeBudget(budget, Buffer34.byteLength(value) + 2);
|
|
8683
|
+
return value;
|
|
8684
|
+
}
|
|
8685
|
+
if (typeof value === "boolean") {
|
|
8686
|
+
consumeBudget(budget, 1);
|
|
8687
|
+
return value;
|
|
8688
|
+
}
|
|
8689
|
+
if (Buffer34.isBuffer(value) || value instanceof Uint8Array) {
|
|
8690
|
+
consumeBudget(budget, bytesMarkerBaseBytes + 4 * Math.ceil(value.byteLength / 3));
|
|
8691
|
+
return { [bytesMarker]: Buffer34.from(value).toString("base64") };
|
|
8692
|
+
}
|
|
8693
|
+
if (typeof value === "number") {
|
|
8694
|
+
if (!Number.isFinite(value)) throw new TypeError("HTTP command numbers must be finite");
|
|
8695
|
+
consumeBudget(budget, 1);
|
|
8696
|
+
return value;
|
|
8697
|
+
}
|
|
8698
|
+
if (typeof value === "bigint") {
|
|
8699
|
+
const encoded = value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value.toString();
|
|
8700
|
+
consumeBudget(budget, typeof encoded === "number" ? 1 : Buffer34.byteLength(encoded) + 2);
|
|
8701
|
+
return encoded;
|
|
8702
|
+
}
|
|
8703
|
+
if (Array.isArray(value)) {
|
|
8704
|
+
consumeBudget(budget, 2 + Math.max(0, value.length - 1));
|
|
8705
|
+
return denseArray(value, depth + 1, (item, itemDepth) => encodeValue(item, itemDepth, budget));
|
|
8706
|
+
}
|
|
8707
|
+
if (value instanceof Map) {
|
|
8708
|
+
consumeBudget(budget, mapMarkerBaseBytes + value.size);
|
|
8709
|
+
const pairs = [];
|
|
8710
|
+
for (const [key, item] of value.entries()) {
|
|
8711
|
+
pairs.push([
|
|
8712
|
+
encodeValue(key, depth + 1, budget),
|
|
8713
|
+
encodeValue(item, depth + 1, budget)
|
|
8714
|
+
]);
|
|
8715
|
+
}
|
|
8716
|
+
return { [mapMarker]: pairs };
|
|
8717
|
+
}
|
|
8718
|
+
if (isRecord(value)) {
|
|
8719
|
+
const keys = Object.keys(value);
|
|
8720
|
+
consumeBudget(budget, mapMarkerBaseBytes + keys.length);
|
|
8721
|
+
return { [mapMarker]: keys.map((key) => [
|
|
8722
|
+
encodeValue(key, depth + 1, budget),
|
|
8723
|
+
encodeValue(value[key], depth + 1, budget)
|
|
8724
|
+
]) };
|
|
8725
|
+
}
|
|
8726
|
+
throw new TypeError(`unsupported HTTP command value: ${typeof value}`);
|
|
8727
|
+
}
|
|
8728
|
+
function decodeValue2(value, depth) {
|
|
8729
|
+
if (depth > maxDepth) throw new TypeError("HTTP response value exceeds maximum depth");
|
|
8730
|
+
if (Array.isArray(value)) return denseArray(value, depth + 1, decodeValue2);
|
|
8731
|
+
if (!isRecord(value)) return value;
|
|
8732
|
+
if (Object.keys(value).length === 1 && typeof value[bytesMarker] === "string") {
|
|
8733
|
+
return decodeBase64(value[bytesMarker]);
|
|
8734
|
+
}
|
|
8735
|
+
if (Object.keys(value).length === 1 && Array.isArray(value[mapMarker])) {
|
|
8736
|
+
const result = /* @__PURE__ */ new Map();
|
|
8737
|
+
for (const pair of value[mapMarker]) {
|
|
8738
|
+
if (!Array.isArray(pair) || pair.length !== 2) throw new TypeError("invalid HTTP map marker");
|
|
8739
|
+
result.set(decodeValue2(pair[0], depth + 1), decodeValue2(pair[1], depth + 1));
|
|
8740
|
+
}
|
|
8741
|
+
return result;
|
|
8742
|
+
}
|
|
8743
|
+
return decodePlainRecord(value, depth + 1);
|
|
8744
|
+
}
|
|
8745
|
+
function decodeBase64(value) {
|
|
8746
|
+
if (value.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) {
|
|
8747
|
+
throw new TypeError("invalid HTTP bytes marker");
|
|
8748
|
+
}
|
|
8749
|
+
const decoded = Buffer34.from(value, "base64");
|
|
8750
|
+
if (decoded.toString("base64") !== value) throw new TypeError("invalid HTTP bytes marker");
|
|
8751
|
+
return decoded;
|
|
8752
|
+
}
|
|
8753
|
+
function decodePlainRecord(value, depth) {
|
|
8754
|
+
const result = {};
|
|
8755
|
+
for (const [key, item] of Object.entries(value)) {
|
|
8756
|
+
Object.defineProperty(result, key, {
|
|
8757
|
+
configurable: true,
|
|
8758
|
+
enumerable: true,
|
|
8759
|
+
value: decodeValue2(item, depth),
|
|
8760
|
+
writable: true
|
|
8761
|
+
});
|
|
8762
|
+
}
|
|
8763
|
+
return result;
|
|
8764
|
+
}
|
|
8765
|
+
function consumeBudget(budget, amount) {
|
|
8766
|
+
if (amount > budget.remaining) {
|
|
8767
|
+
throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
|
|
8768
|
+
}
|
|
8769
|
+
budget.remaining -= amount;
|
|
8770
|
+
}
|
|
8771
|
+
function denseArray(values, depth, transform) {
|
|
8772
|
+
const result = new Array(values.length);
|
|
8773
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
8774
|
+
if (!Object.hasOwn(values, index)) throw new TypeError("HTTP command arrays must be dense");
|
|
8775
|
+
result[index] = transform(values[index], depth);
|
|
8776
|
+
}
|
|
8777
|
+
return result;
|
|
8778
|
+
}
|
|
8779
|
+
function isRecord(value) {
|
|
8780
|
+
return typeof value === "object" && value != null && !Array.isArray(value) && !Buffer34.isBuffer(value);
|
|
8781
|
+
}
|
|
8782
|
+
|
|
8783
|
+
// src/http-options.ts
|
|
8784
|
+
import { Buffer as Buffer35 } from "buffer";
|
|
8785
|
+
import { validateHeaderName, validateHeaderValue } from "http";
|
|
8786
|
+
function normalizeHTTPOptions(value, options) {
|
|
8787
|
+
const url = new URL(value);
|
|
8788
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
8789
|
+
throw new TypeError(`unsupported HTTP URL scheme: ${url.protocol}`);
|
|
8790
|
+
}
|
|
8791
|
+
if (url.username !== "" || url.password !== "") throw new TypeError("HTTP URL userinfo is not allowed");
|
|
8792
|
+
if (url.search !== "" || url.hash !== "") throw new TypeError("HTTP base URL cannot contain query or fragment");
|
|
8793
|
+
const headers = normalizedHeaders(options.headers ?? {});
|
|
8794
|
+
const authorization = authorizationHeader(url, options, headers.authorization);
|
|
8795
|
+
if (authorization != null) headers.authorization = authorization;
|
|
8796
|
+
url.pathname = `${url.pathname.replace(/\/$/u, "")}/v1/commands`;
|
|
8797
|
+
return Object.freeze({
|
|
8798
|
+
commandUrl: url,
|
|
8799
|
+
headers: Object.freeze(headers),
|
|
8800
|
+
http2: booleanOption(options.http2, false, "http2"),
|
|
8801
|
+
maxBatchItems: positiveInteger(options.maxBatchItems, 1e3, "maxBatchItems"),
|
|
8802
|
+
maxConnections: positiveInteger(options.maxConnections, 100, "maxConnections"),
|
|
8803
|
+
maxRedirects: nonNegativeInteger(options.maxRedirects, 20, "maxRedirects"),
|
|
8804
|
+
maxRequestBytes: positiveInteger(options.maxRequestBytes, 1024 * 1024, "maxRequestBytes"),
|
|
8805
|
+
maxResponseBytes: positiveInteger(options.maxResponseBytes, 16 * 1024 * 1024, "maxResponseBytes"),
|
|
8806
|
+
timeoutMs: positiveInteger(options.timeoutMs, 3e4, "timeoutMs"),
|
|
8807
|
+
tlsOptions: Object.freeze({ ...options.tlsOptions ?? {} })
|
|
8808
|
+
});
|
|
8809
|
+
}
|
|
8810
|
+
function normalizedHeaders(source) {
|
|
8811
|
+
const headers = /* @__PURE__ */ Object.create(null);
|
|
8812
|
+
for (const [rawName, value] of Object.entries(source)) {
|
|
8813
|
+
const name = rawName.toLowerCase();
|
|
8814
|
+
if (typeof value !== "string" || !validHeader(name, value)) {
|
|
8815
|
+
throw new TypeError(`invalid HTTP header: ${rawName}`);
|
|
8816
|
+
}
|
|
8817
|
+
headers[name] = value;
|
|
8818
|
+
}
|
|
8819
|
+
return headers;
|
|
8820
|
+
}
|
|
8821
|
+
function authorizationHeader(url, options, custom) {
|
|
8822
|
+
const basic = options.username != null || options.password != null;
|
|
8823
|
+
const count = Number(custom != null) + Number(options.bearerToken != null) + Number(basic);
|
|
8824
|
+
if (count > 1) throw new TypeError("HTTP credentials are mutually exclusive");
|
|
8825
|
+
if (options.bearerToken != null) {
|
|
8826
|
+
if (options.bearerToken === "" || !validHeader("authorization", `Bearer ${options.bearerToken}`)) {
|
|
8827
|
+
throw new TypeError("invalid bearer token");
|
|
8828
|
+
}
|
|
8829
|
+
return `Bearer ${options.bearerToken}`;
|
|
8830
|
+
}
|
|
8831
|
+
if (!basic) return custom;
|
|
8832
|
+
if (url.protocol !== "https:") throw new TypeError("Basic authentication requires HTTPS");
|
|
8833
|
+
if (typeof options.password !== "string") throw new TypeError("Basic authentication requires a password");
|
|
8834
|
+
const username = options.username ?? "default";
|
|
8835
|
+
if (username === "" || username.includes(":") || !safeHeader(username) || !safeHeader(options.password)) {
|
|
8836
|
+
throw new TypeError("invalid Basic authentication credentials");
|
|
8837
|
+
}
|
|
8838
|
+
return `Basic ${Buffer35.from(`${username}:${options.password}`).toString("base64")}`;
|
|
8839
|
+
}
|
|
8840
|
+
function positiveInteger(value, fallback, name) {
|
|
8841
|
+
const result = value ?? fallback;
|
|
8842
|
+
if (!Number.isSafeInteger(result) || result <= 0) throw new TypeError(`${name} must be a positive integer`);
|
|
8843
|
+
return result;
|
|
8844
|
+
}
|
|
8845
|
+
function nonNegativeInteger(value, fallback, name) {
|
|
8846
|
+
const result = value ?? fallback;
|
|
8847
|
+
if (!Number.isSafeInteger(result) || result < 0) throw new TypeError(`${name} must be a non-negative integer`);
|
|
8848
|
+
return result;
|
|
8849
|
+
}
|
|
8850
|
+
function booleanOption(value, fallback, name) {
|
|
8851
|
+
const result = value ?? fallback;
|
|
8852
|
+
if (typeof result !== "boolean") throw new TypeError(`${name} must be a boolean`);
|
|
8853
|
+
return result;
|
|
8854
|
+
}
|
|
8855
|
+
function safeHeader(value) {
|
|
8856
|
+
return !value.includes("\r") && !value.includes("\n");
|
|
8857
|
+
}
|
|
8858
|
+
function validHeader(name, value) {
|
|
8859
|
+
try {
|
|
8860
|
+
validateHeaderName(name);
|
|
8861
|
+
validateHeaderValue(name, value);
|
|
8862
|
+
return true;
|
|
8863
|
+
} catch {
|
|
8864
|
+
return false;
|
|
8865
|
+
}
|
|
8866
|
+
}
|
|
8867
|
+
|
|
8868
|
+
// src/http-transport.ts
|
|
8869
|
+
import http from "http";
|
|
8870
|
+
import http2 from "http2";
|
|
8871
|
+
import https from "https";
|
|
8872
|
+
import { Buffer as Buffer36 } from "buffer";
|
|
8873
|
+
|
|
8874
|
+
// src/http2-slot-pool.ts
|
|
8875
|
+
var HTTP2SessionRetiredError = class extends Error {
|
|
8876
|
+
constructor(message, cause) {
|
|
8877
|
+
super(message, { cause });
|
|
8878
|
+
this.name = "HTTP2SessionRetiredError";
|
|
8879
|
+
}
|
|
8880
|
+
};
|
|
8881
|
+
var HTTP2SlotPool = class {
|
|
8882
|
+
active = 0;
|
|
8883
|
+
idleCallback;
|
|
8884
|
+
limit;
|
|
8885
|
+
retiredError;
|
|
8886
|
+
waiterHead;
|
|
8887
|
+
waiterTail;
|
|
8888
|
+
acquire(signal) {
|
|
8889
|
+
if (signal.aborted) return Promise.reject(signalAbortError(signal));
|
|
8890
|
+
if (this.retiredError != null) return Promise.reject(this.retiredError);
|
|
8891
|
+
if (this.limit != null && this.active < this.limit) {
|
|
8892
|
+
this.active += 1;
|
|
8893
|
+
return Promise.resolve(this.releaseOnce());
|
|
8894
|
+
}
|
|
8895
|
+
return new Promise((resolve, reject) => {
|
|
8896
|
+
const waiter = {
|
|
8897
|
+
abort: () => {
|
|
8898
|
+
if (waiter.settled) return;
|
|
8899
|
+
waiter.settled = true;
|
|
8900
|
+
this.removeWaiter(waiter);
|
|
8901
|
+
reject(signalAbortError(signal));
|
|
8902
|
+
},
|
|
8903
|
+
queued: true,
|
|
8904
|
+
reject,
|
|
8905
|
+
resolve,
|
|
8906
|
+
settled: false,
|
|
8907
|
+
signal
|
|
8908
|
+
};
|
|
8909
|
+
this.enqueueWaiter(waiter);
|
|
8910
|
+
signal.addEventListener("abort", waiter.abort, { once: true });
|
|
8911
|
+
});
|
|
8912
|
+
}
|
|
8913
|
+
updateLimit(limit) {
|
|
8914
|
+
if (this.retiredError != null) return;
|
|
8915
|
+
this.limit = limit;
|
|
8916
|
+
this.drain();
|
|
8917
|
+
}
|
|
8918
|
+
retire(error) {
|
|
8919
|
+
if (this.retiredError != null) return;
|
|
8920
|
+
this.retiredError = error;
|
|
8921
|
+
while (this.waiterHead != null) {
|
|
8922
|
+
const waiter = this.waiterHead;
|
|
8923
|
+
this.removeWaiter(waiter);
|
|
8924
|
+
if (waiter.settled) continue;
|
|
8925
|
+
waiter.settled = true;
|
|
8926
|
+
waiter.signal.removeEventListener("abort", waiter.abort);
|
|
8927
|
+
waiter.reject(error);
|
|
8928
|
+
}
|
|
8929
|
+
}
|
|
8930
|
+
whenIdle(callback) {
|
|
8931
|
+
if (this.active === 0) callback();
|
|
8932
|
+
else this.idleCallback = callback;
|
|
8933
|
+
}
|
|
8934
|
+
drain() {
|
|
8935
|
+
while (this.retiredError == null && this.limit != null && this.active < this.limit) {
|
|
8936
|
+
const waiter = this.waiterHead;
|
|
8937
|
+
if (waiter == null) return;
|
|
8938
|
+
this.removeWaiter(waiter);
|
|
8939
|
+
if (waiter.settled) continue;
|
|
8940
|
+
waiter.settled = true;
|
|
8941
|
+
waiter.signal.removeEventListener("abort", waiter.abort);
|
|
8942
|
+
this.active += 1;
|
|
8943
|
+
waiter.resolve(this.releaseOnce());
|
|
8944
|
+
}
|
|
8945
|
+
}
|
|
8946
|
+
enqueueWaiter(waiter) {
|
|
8947
|
+
waiter.previous = this.waiterTail;
|
|
8948
|
+
if (this.waiterTail == null) this.waiterHead = waiter;
|
|
8949
|
+
else this.waiterTail.next = waiter;
|
|
8950
|
+
this.waiterTail = waiter;
|
|
8951
|
+
}
|
|
8952
|
+
removeWaiter(waiter) {
|
|
8953
|
+
if (!waiter.queued) return;
|
|
8954
|
+
if (waiter.previous == null) this.waiterHead = waiter.next;
|
|
8955
|
+
else waiter.previous.next = waiter.next;
|
|
8956
|
+
if (waiter.next == null) this.waiterTail = waiter.previous;
|
|
8957
|
+
else waiter.next.previous = waiter.previous;
|
|
8958
|
+
waiter.next = void 0;
|
|
8959
|
+
waiter.previous = void 0;
|
|
8960
|
+
waiter.queued = false;
|
|
8961
|
+
}
|
|
8962
|
+
releaseOnce() {
|
|
8963
|
+
let released = false;
|
|
8964
|
+
return () => {
|
|
8965
|
+
if (released) return;
|
|
8966
|
+
released = true;
|
|
8967
|
+
this.active -= 1;
|
|
8968
|
+
this.drain();
|
|
8969
|
+
if (this.active === 0) {
|
|
8970
|
+
const callback = this.idleCallback;
|
|
8971
|
+
this.idleCallback = void 0;
|
|
8972
|
+
callback?.();
|
|
8973
|
+
}
|
|
8974
|
+
};
|
|
8975
|
+
}
|
|
8976
|
+
};
|
|
8977
|
+
function signalAbortError(signal) {
|
|
8978
|
+
return signal.reason instanceof Error ? signal.reason : new HTTPTransportError("HTTP request was aborted", { raw: signal.reason });
|
|
8979
|
+
}
|
|
8980
|
+
|
|
8981
|
+
// src/http-transport.ts
|
|
8982
|
+
var HTTPTransport = class {
|
|
8983
|
+
constructor(config) {
|
|
8984
|
+
this.config = config;
|
|
8985
|
+
this.#httpAgent = new http.Agent({
|
|
8986
|
+
keepAlive: true,
|
|
8987
|
+
maxFreeSockets: config.maxConnections,
|
|
8988
|
+
maxSockets: config.maxConnections,
|
|
8989
|
+
maxTotalSockets: config.maxConnections
|
|
8990
|
+
});
|
|
8991
|
+
this.#httpsAgent = new https.Agent({
|
|
8992
|
+
...config.tlsOptions,
|
|
8993
|
+
keepAlive: true,
|
|
8994
|
+
maxFreeSockets: config.maxConnections,
|
|
8995
|
+
maxSockets: config.maxConnections,
|
|
8996
|
+
maxTotalSockets: config.maxConnections
|
|
8997
|
+
});
|
|
8998
|
+
}
|
|
8999
|
+
config;
|
|
9000
|
+
#httpAgent;
|
|
9001
|
+
#httpsAgent;
|
|
9002
|
+
#allSessions = /* @__PURE__ */ new Set();
|
|
9003
|
+
#sessions = /* @__PURE__ */ new Map();
|
|
9004
|
+
#sessionSlots = /* @__PURE__ */ new WeakMap();
|
|
9005
|
+
#requests = /* @__PURE__ */ new Set();
|
|
9006
|
+
#closed = false;
|
|
9007
|
+
async post(body, timeoutMs) {
|
|
9008
|
+
if (this.#closed) throw new HTTPTransportError("HTTP transport is closed");
|
|
9009
|
+
const controller = new AbortController();
|
|
9010
|
+
this.#requests.add(controller);
|
|
9011
|
+
const timer = timeoutMs == null ? void 0 : setLongTimeout(() => controller.abort(requestTimeoutReason), timeoutMs);
|
|
9012
|
+
timer?.unref();
|
|
9013
|
+
try {
|
|
9014
|
+
return await this.request(this.config.commandUrl, "POST", body, 0, controller.signal);
|
|
9015
|
+
} catch (error) {
|
|
9016
|
+
if (controller.signal.aborted) {
|
|
9017
|
+
if (controller.signal.reason instanceof HTTPTransportError) throw controller.signal.reason;
|
|
9018
|
+
throw new RequestTimeoutError(timeoutMs ?? this.config.timeoutMs, "possibly_sent", {
|
|
9019
|
+
cause: error,
|
|
9020
|
+
raw: { retryable: true, safe_to_retry: false }
|
|
9021
|
+
});
|
|
9022
|
+
}
|
|
9023
|
+
if (error instanceof HTTPTransportError || error instanceof RequestTimeoutError) throw error;
|
|
9024
|
+
throw new HTTPTransportError("HTTP command request failed", {
|
|
9025
|
+
cause: error,
|
|
9026
|
+
retryable: true,
|
|
9027
|
+
safeToRetry: false
|
|
9028
|
+
});
|
|
9029
|
+
} finally {
|
|
9030
|
+
timer?.cancel();
|
|
9031
|
+
this.#requests.delete(controller);
|
|
9032
|
+
}
|
|
9033
|
+
}
|
|
9034
|
+
async close() {
|
|
9035
|
+
if (this.#closed) return;
|
|
9036
|
+
this.#closed = true;
|
|
9037
|
+
const error = new HTTPTransportError("HTTP transport is closed");
|
|
9038
|
+
for (const controller of this.#requests) controller.abort(error);
|
|
9039
|
+
this.#httpAgent.destroy();
|
|
9040
|
+
this.#httpsAgent.destroy();
|
|
9041
|
+
for (const session of this.#allSessions) session.destroy();
|
|
9042
|
+
this.#allSessions.clear();
|
|
9043
|
+
this.#sessions.clear();
|
|
9044
|
+
}
|
|
9045
|
+
async request(url, method, body, redirects, signal) {
|
|
9046
|
+
const response = this.config.http2 ? await this.http2Request(url, method, body, signal) : await this.http1Request(url, method, body, signal);
|
|
9047
|
+
if (![301, 302, 303, 307, 308].includes(response.status)) return response;
|
|
9048
|
+
if (redirects >= this.config.maxRedirects) throw new HTTPTransportError("too many HTTP redirects");
|
|
9049
|
+
const location = response.headers.location;
|
|
9050
|
+
if (location == null || location === "") throw new HTTPTransportError("HTTP redirect has no location");
|
|
9051
|
+
const target = new URL(location, url);
|
|
9052
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") {
|
|
9053
|
+
throw new HTTPTransportError("HTTP redirect has an unsupported scheme");
|
|
9054
|
+
}
|
|
9055
|
+
const switchToGet = [301, 302, 303].includes(response.status);
|
|
9056
|
+
return await this.request(
|
|
9057
|
+
target,
|
|
9058
|
+
switchToGet ? "GET" : method,
|
|
9059
|
+
switchToGet ? void 0 : body,
|
|
9060
|
+
redirects + 1,
|
|
9061
|
+
signal
|
|
9062
|
+
);
|
|
9063
|
+
}
|
|
9064
|
+
async http1Request(url, method, body, signal) {
|
|
9065
|
+
const request = url.protocol === "https:" ? https.request : http.request;
|
|
9066
|
+
const agent = url.protocol === "https:" ? this.#httpsAgent : this.#httpAgent;
|
|
9067
|
+
const headers = this.requestHeaders(body);
|
|
9068
|
+
return await new Promise((resolve, reject) => {
|
|
9069
|
+
const outgoing = request(url, { agent, headers, method, signal }, (response) => {
|
|
9070
|
+
void this.collectHttp1(response).then(resolve, reject);
|
|
9071
|
+
});
|
|
9072
|
+
outgoing.once("error", reject);
|
|
9073
|
+
outgoing.end(body);
|
|
9074
|
+
});
|
|
9075
|
+
}
|
|
9076
|
+
async collectHttp1(response) {
|
|
9077
|
+
const declared = headerValue(response.headers["content-length"]);
|
|
9078
|
+
if (declared != null && Number(declared) > this.config.maxResponseBytes) {
|
|
9079
|
+
response.destroy();
|
|
9080
|
+
throw new HTTPTransportError("HTTP response exceeds maxResponseBytes");
|
|
9081
|
+
}
|
|
9082
|
+
return await collectBody(
|
|
9083
|
+
response,
|
|
9084
|
+
response.statusCode ?? 0,
|
|
9085
|
+
normalizeHeaders(response.headers),
|
|
9086
|
+
this.config.maxResponseBytes
|
|
9087
|
+
);
|
|
9088
|
+
}
|
|
9089
|
+
async http2Request(url, method, body, signal) {
|
|
9090
|
+
const headers = {
|
|
9091
|
+
...this.requestHeaders(body),
|
|
9092
|
+
":authority": url.host,
|
|
9093
|
+
":method": method,
|
|
9094
|
+
":path": `${url.pathname}${url.search}`,
|
|
9095
|
+
":scheme": url.protocol.slice(0, -1)
|
|
9096
|
+
};
|
|
9097
|
+
if (signal.aborted) throw signalAbortError(signal);
|
|
9098
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
9099
|
+
const session = this.session(url);
|
|
9100
|
+
let release;
|
|
9101
|
+
try {
|
|
9102
|
+
release = await this.slotPool(session).acquire(signal);
|
|
9103
|
+
} catch (error) {
|
|
9104
|
+
if (attempt === 0 && error instanceof HTTP2SessionRetiredError && !signal.aborted) continue;
|
|
9105
|
+
throw error;
|
|
9106
|
+
}
|
|
9107
|
+
try {
|
|
9108
|
+
let stream;
|
|
9109
|
+
try {
|
|
9110
|
+
stream = session.request(headers);
|
|
9111
|
+
} catch (error) {
|
|
9112
|
+
if (attempt === 0 && retryableSessionOpenError(error) && !signal.aborted) {
|
|
9113
|
+
this.retireSession(url.origin, session, true, error);
|
|
9114
|
+
continue;
|
|
9115
|
+
}
|
|
9116
|
+
throw error;
|
|
9117
|
+
}
|
|
9118
|
+
try {
|
|
9119
|
+
return await this.collectHttp2(stream, body, signal);
|
|
9120
|
+
} catch (error) {
|
|
9121
|
+
if (attempt === 0 && refusedStreamError(error) && !signal.aborted) continue;
|
|
9122
|
+
throw error;
|
|
9123
|
+
}
|
|
9124
|
+
} finally {
|
|
9125
|
+
release();
|
|
9126
|
+
}
|
|
9127
|
+
}
|
|
9128
|
+
throw new HTTPTransportError("HTTP/2 session could not accept the request");
|
|
9129
|
+
}
|
|
9130
|
+
async collectHttp2(stream, body, signal) {
|
|
9131
|
+
return await new Promise((resolve, reject) => {
|
|
9132
|
+
let responseHeaders = {};
|
|
9133
|
+
const abort = () => stream.close(http2.constants.NGHTTP2_CANCEL);
|
|
9134
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
9135
|
+
stream.once("response", (value) => responseHeaders = value);
|
|
9136
|
+
stream.once("error", reject);
|
|
9137
|
+
void collectBody(stream, 0, {}, this.config.maxResponseBytes).then((response) => {
|
|
9138
|
+
const status = Number(responseHeaders[":status"] ?? 0);
|
|
9139
|
+
resolve({ body: response.body, headers: normalizeHeaders(responseHeaders), status });
|
|
9140
|
+
}, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
9141
|
+
if (signal.aborted) abort();
|
|
9142
|
+
else stream.end(body);
|
|
9143
|
+
});
|
|
9144
|
+
}
|
|
9145
|
+
session(url) {
|
|
9146
|
+
const origin = url.origin;
|
|
9147
|
+
const current = this.#sessions.get(origin);
|
|
9148
|
+
if (current != null && !current.closed && !current.destroyed) return current;
|
|
9149
|
+
const session = http2.connect(origin, {
|
|
9150
|
+
...this.config.tlsOptions,
|
|
9151
|
+
settings: { enablePush: false }
|
|
9152
|
+
});
|
|
9153
|
+
const slots = new HTTP2SlotPool();
|
|
9154
|
+
this.#allSessions.add(session);
|
|
9155
|
+
this.#sessionSlots.set(session, slots);
|
|
9156
|
+
session.on("remoteSettings", (settings) => {
|
|
9157
|
+
const remoteLimit = settings.maxConcurrentStreams;
|
|
9158
|
+
const limit = typeof remoteLimit === "number" && Number.isFinite(remoteLimit) ? Math.max(0, Math.floor(remoteLimit)) : this.config.maxConnections;
|
|
9159
|
+
slots.updateLimit(Math.min(this.config.maxConnections, limit));
|
|
9160
|
+
});
|
|
9161
|
+
session.on("error", (error) => this.retireSession(origin, session, true, error));
|
|
9162
|
+
session.once("goaway", () => {
|
|
9163
|
+
this.retireSession(
|
|
9164
|
+
origin,
|
|
9165
|
+
session,
|
|
9166
|
+
"when_idle",
|
|
9167
|
+
new HTTP2SessionRetiredError("HTTP/2 session received GOAWAY")
|
|
9168
|
+
);
|
|
9169
|
+
});
|
|
9170
|
+
session.once("close", () => {
|
|
9171
|
+
if (session.destroyed) this.#allSessions.delete(session);
|
|
9172
|
+
this.retireSession(origin, session);
|
|
9173
|
+
});
|
|
9174
|
+
this.#sessions.set(origin, session);
|
|
9175
|
+
return session;
|
|
9176
|
+
}
|
|
9177
|
+
retireSession(origin, session, destroy = false, cause) {
|
|
9178
|
+
if (this.#sessions.get(origin) === session) this.#sessions.delete(origin);
|
|
9179
|
+
const slots = this.#sessionSlots.get(session);
|
|
9180
|
+
slots?.retire(
|
|
9181
|
+
cause instanceof HTTP2SessionRetiredError ? cause : new HTTP2SessionRetiredError("HTTP/2 session is unavailable", cause)
|
|
9182
|
+
);
|
|
9183
|
+
if (destroy === true && !session.destroyed) session.destroy();
|
|
9184
|
+
else if (destroy === "when_idle") {
|
|
9185
|
+
slots?.whenIdle(() => {
|
|
9186
|
+
if (!session.destroyed) session.destroy();
|
|
9187
|
+
});
|
|
9188
|
+
}
|
|
9189
|
+
}
|
|
9190
|
+
slotPool(session) {
|
|
9191
|
+
const slots = this.#sessionSlots.get(session);
|
|
9192
|
+
if (slots == null) throw new HTTP2SessionRetiredError("HTTP/2 session is unavailable");
|
|
9193
|
+
return slots;
|
|
9194
|
+
}
|
|
9195
|
+
requestHeaders(body) {
|
|
9196
|
+
const headers = { ...this.config.headers };
|
|
9197
|
+
delete headers["content-length"];
|
|
9198
|
+
delete headers["content-type"];
|
|
9199
|
+
return {
|
|
9200
|
+
...headers,
|
|
9201
|
+
accept: "application/json",
|
|
9202
|
+
...body == null ? {} : { "content-length": body.byteLength, "content-type": "application/json" }
|
|
9203
|
+
};
|
|
9204
|
+
}
|
|
9205
|
+
};
|
|
9206
|
+
var requestTimeoutReason = /* @__PURE__ */ Symbol("ferricstore-http-request-timeout");
|
|
9207
|
+
function retryableSessionOpenError(error) {
|
|
9208
|
+
if (typeof error !== "object" || error == null || !("code" in error)) return false;
|
|
9209
|
+
const code = error.code;
|
|
9210
|
+
return code === "ERR_HTTP2_GOAWAY_SESSION" || code === "ERR_HTTP2_INVALID_SESSION";
|
|
9211
|
+
}
|
|
9212
|
+
function refusedStreamError(error) {
|
|
9213
|
+
if (!(error instanceof Error)) return false;
|
|
9214
|
+
return error.code === "ERR_HTTP2_STREAM_ERROR" && error.message.includes("NGHTTP2_REFUSED_STREAM");
|
|
9215
|
+
}
|
|
9216
|
+
async function collectBody(source, status, headers, maximum) {
|
|
9217
|
+
const chunks = [];
|
|
9218
|
+
let size = 0;
|
|
9219
|
+
for await (const chunk of source) {
|
|
9220
|
+
const bytes2 = Buffer36.from(chunk);
|
|
9221
|
+
size += bytes2.byteLength;
|
|
9222
|
+
if (size > maximum) {
|
|
9223
|
+
const destroy = source.destroy;
|
|
9224
|
+
if (destroy != null) destroy.call(source);
|
|
9225
|
+
throw new HTTPTransportError("HTTP response exceeds maxResponseBytes");
|
|
9226
|
+
}
|
|
9227
|
+
chunks.push(bytes2);
|
|
9228
|
+
}
|
|
9229
|
+
return { body: Buffer36.concat(chunks, size), headers, status };
|
|
9230
|
+
}
|
|
9231
|
+
function normalizeHeaders(headers) {
|
|
9232
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
9233
|
+
for (const [name, raw] of Object.entries(headers)) {
|
|
9234
|
+
const value = headerValue(raw);
|
|
9235
|
+
if (value != null) result[name.toLowerCase()] = value;
|
|
9236
|
+
}
|
|
9237
|
+
return result;
|
|
9238
|
+
}
|
|
9239
|
+
function headerValue(value) {
|
|
9240
|
+
if (Array.isArray(value)) return value.join(", ");
|
|
9241
|
+
return value == null ? void 0 : String(value);
|
|
9242
|
+
}
|
|
9243
|
+
|
|
9244
|
+
// src/http-adapter.ts
|
|
9245
|
+
var HTTPAdapter = class _HTTPAdapter {
|
|
9246
|
+
#config;
|
|
9247
|
+
#transport;
|
|
9248
|
+
static async fromUrl(url, options = {}) {
|
|
9249
|
+
return new _HTTPAdapter(normalizeHTTPOptions(url, options));
|
|
9250
|
+
}
|
|
9251
|
+
constructor(config) {
|
|
9252
|
+
this.#config = config;
|
|
9253
|
+
this.#transport = new HTTPTransport(config);
|
|
9254
|
+
}
|
|
9255
|
+
async executeCommand(...args) {
|
|
9256
|
+
return await this.executeCommandArgs(args);
|
|
9257
|
+
}
|
|
9258
|
+
async executeCommandArgs(args) {
|
|
9259
|
+
const [result] = await this.executeBatch([args]);
|
|
9260
|
+
if (result == null) throw new HTTPTransportError("HTTP response omitted a command result");
|
|
9261
|
+
if (result.status === "error") throw commandError(result.error);
|
|
9262
|
+
return result.value;
|
|
9263
|
+
}
|
|
9264
|
+
async executePipeline(commands, options = {}) {
|
|
9265
|
+
const results = await this.executeBatch(commands);
|
|
9266
|
+
const values = results.map((result) => result.status === "ok" ? result.value : commandError(result.error));
|
|
9267
|
+
if (options.throwOnItemError !== false) {
|
|
9268
|
+
const failure = values.find((value) => value instanceof Error);
|
|
9269
|
+
if (failure instanceof Error) throw failure;
|
|
9270
|
+
}
|
|
9271
|
+
return values;
|
|
9272
|
+
}
|
|
9273
|
+
async executeFusedPipeline(commands, options = {}) {
|
|
9274
|
+
return await this.executePipeline(commands, options);
|
|
9275
|
+
}
|
|
9276
|
+
async close() {
|
|
9277
|
+
await this.#transport.close();
|
|
9278
|
+
}
|
|
9279
|
+
async executeBatch(commands) {
|
|
9280
|
+
if (commands.length > this.#config.maxBatchItems) {
|
|
9281
|
+
throw new HTTPTransportError("HTTP command batch exceeds maxBatchItems");
|
|
9282
|
+
}
|
|
9283
|
+
for (const command of commands) assertHTTPCommandSupported(command[0]);
|
|
9284
|
+
const prepared = commands.map((command) => prepareHTTPCommand(command, this.#config.maxRequestBytes));
|
|
9285
|
+
const body = encodeHTTPCommands(prepared.map((command) => command.encoded), this.#config.maxRequestBytes);
|
|
9286
|
+
if (body.byteLength > this.#config.maxRequestBytes) {
|
|
9287
|
+
throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
|
|
9288
|
+
}
|
|
9289
|
+
const serverBlockMs = combinedServerBlockMs(prepared.map((command) => command.serverBlockMs));
|
|
9290
|
+
const response = await this.#transport.post(
|
|
9291
|
+
body,
|
|
9292
|
+
serverResponseTimeoutMs(this.#config.timeoutMs, serverBlockMs)
|
|
9293
|
+
);
|
|
9294
|
+
let envelope = {};
|
|
9295
|
+
try {
|
|
9296
|
+
if (response.body.byteLength > 0) envelope = decodeHTTPEnvelope(response.body);
|
|
9297
|
+
} catch (error) {
|
|
9298
|
+
if (response.status >= 200 && response.status < 300) throw error;
|
|
9299
|
+
}
|
|
9300
|
+
if (response.status < 200 || response.status >= 300) throw topLevelError(
|
|
9301
|
+
response.status,
|
|
9302
|
+
envelope,
|
|
9303
|
+
response.headers["retry-after"]
|
|
9304
|
+
);
|
|
9305
|
+
if (envelope.encoding !== "ferricstore-json-v1") {
|
|
9306
|
+
throw new HTTPTransportError("HTTP response has an unsupported encoding");
|
|
9307
|
+
}
|
|
9308
|
+
if (!Array.isArray(envelope.results) || envelope.results.length !== commands.length) {
|
|
9309
|
+
throw new HTTPTransportError("HTTP response result count does not match the command batch");
|
|
9310
|
+
}
|
|
9311
|
+
return envelope.results.map((result) => validatedResult(result));
|
|
9312
|
+
}
|
|
9313
|
+
};
|
|
9314
|
+
var commandNamesByOpcode = new Map(
|
|
9315
|
+
Object.entries(COMMAND_OPCODES).map(([name, opcode]) => [opcode, name])
|
|
9316
|
+
);
|
|
9317
|
+
function prepareHTTPCommand(command, maxRequestBytes) {
|
|
9318
|
+
const protocol = buildProtocolCommand(command, maxRequestBytes, false);
|
|
9319
|
+
if (protocol.opcode === OPCODES.commandExec) {
|
|
9320
|
+
return { encoded: command, serverBlockMs: protocol.serverBlockMs };
|
|
9321
|
+
}
|
|
9322
|
+
const name = commandNamesByOpcode.get(protocol.opcode);
|
|
9323
|
+
if (name == null) throw new HTTPTransportError(`HTTP command has unknown opcode ${protocol.opcode}`);
|
|
9324
|
+
return {
|
|
9325
|
+
encoded: { command: name, opcode: protocol.opcode, payload: protocol.payload ?? {} },
|
|
9326
|
+
serverBlockMs: protocol.serverBlockMs
|
|
9327
|
+
};
|
|
9328
|
+
}
|
|
9329
|
+
function validatedResult(value) {
|
|
9330
|
+
if (!isRecord2(value)) throw new HTTPTransportError("HTTP response has an invalid result item");
|
|
9331
|
+
if (value.status === "ok" && Object.hasOwn(value, "value")) {
|
|
9332
|
+
return { status: "ok", value: value.value };
|
|
9333
|
+
}
|
|
9334
|
+
if (value.status === "error" && isRecord2(value.error)) {
|
|
9335
|
+
return { error: value.error, status: "error" };
|
|
9336
|
+
}
|
|
9337
|
+
throw new HTTPTransportError("HTTP response has an invalid result item");
|
|
9338
|
+
}
|
|
9339
|
+
function commandError(value) {
|
|
9340
|
+
const message = isRecord2(value) && typeof value.message === "string" ? value.message : "FerricStore command failed";
|
|
9341
|
+
const code = isRecord2(value) && typeof value.code === "string" ? value.code : void 0;
|
|
9342
|
+
return classifyServerError(message, value, void 0, code);
|
|
9343
|
+
}
|
|
9344
|
+
function topLevelError(status, envelope, retryAfter) {
|
|
9345
|
+
const details = isRecord2(envelope.error) ? envelope.error : {};
|
|
9346
|
+
const message = typeof details.message === "string" ? details.message : `HTTP command request failed with status ${status}`;
|
|
9347
|
+
const retryAfterMs2 = retryAfterMilliseconds(retryAfter);
|
|
9348
|
+
return new HTTPTransportError(message, {
|
|
9349
|
+
raw: details,
|
|
9350
|
+
retryable: status === 408 || status === 425 || status === 429 || status >= 500,
|
|
9351
|
+
retryAfterMs: retryAfterMs2,
|
|
9352
|
+
safeToRetry: false,
|
|
9353
|
+
statusCode: status
|
|
9354
|
+
});
|
|
9355
|
+
}
|
|
9356
|
+
function retryAfterMilliseconds(value) {
|
|
9357
|
+
if (value == null) return void 0;
|
|
9358
|
+
if (/^\d+$/u.test(value)) {
|
|
9359
|
+
const seconds = Number.parseInt(value, 10);
|
|
9360
|
+
const milliseconds2 = seconds * 1e3;
|
|
9361
|
+
return Number.isSafeInteger(milliseconds2) ? milliseconds2 : void 0;
|
|
9362
|
+
}
|
|
9363
|
+
const deadline = Date.parse(value);
|
|
9364
|
+
if (!Number.isFinite(deadline)) return void 0;
|
|
9365
|
+
const milliseconds = Math.max(0, deadline - Date.now());
|
|
9366
|
+
return Number.isSafeInteger(milliseconds) ? milliseconds : void 0;
|
|
9367
|
+
}
|
|
9368
|
+
function isRecord2(value) {
|
|
9369
|
+
return typeof value === "object" && value != null && !Array.isArray(value);
|
|
9370
|
+
}
|
|
9371
|
+
|
|
8549
9372
|
// src/adapters.ts
|
|
8550
9373
|
function executeCommandArgs(executor, args) {
|
|
8551
9374
|
if (executor.executeCommandArgs != null) return executor.executeCommandArgs(args);
|
|
@@ -8557,7 +9380,7 @@ function executeCommandArgs(executor, args) {
|
|
|
8557
9380
|
import "buffer";
|
|
8558
9381
|
|
|
8559
9382
|
// src/command-retry-policy.ts
|
|
8560
|
-
import { Buffer as
|
|
9383
|
+
import { Buffer as Buffer37 } from "buffer";
|
|
8561
9384
|
function isCasMutation(args) {
|
|
8562
9385
|
const offset = commandName2(args[0]) === "COMMAND_EXEC" ? 1 : 0;
|
|
8563
9386
|
const name = commandName2(args[offset]);
|
|
@@ -8571,8 +9394,8 @@ function isCasMutation(args) {
|
|
|
8571
9394
|
}
|
|
8572
9395
|
function commandName2(value) {
|
|
8573
9396
|
if (typeof value === "string") return value.toUpperCase();
|
|
8574
|
-
if (
|
|
8575
|
-
return
|
|
9397
|
+
if (Buffer37.isBuffer(value) || value instanceof Uint8Array) {
|
|
9398
|
+
return Buffer37.from(value).toString("utf8").toUpperCase();
|
|
8576
9399
|
}
|
|
8577
9400
|
return void 0;
|
|
8578
9401
|
}
|
|
@@ -8787,12 +9610,12 @@ function normalizeNonNegativeInteger2(value, fallback) {
|
|
|
8787
9610
|
import "buffer";
|
|
8788
9611
|
|
|
8789
9612
|
// src/topology-routing.ts
|
|
8790
|
-
import { Buffer as
|
|
9613
|
+
import { Buffer as Buffer40 } from "buffer";
|
|
8791
9614
|
|
|
8792
9615
|
// src/flow-partition-route-cache.ts
|
|
8793
|
-
import { Buffer as
|
|
9616
|
+
import { Buffer as Buffer39 } from "buffer";
|
|
8794
9617
|
import { createHash } from "crypto";
|
|
8795
|
-
var AUTO_PREFIX =
|
|
9618
|
+
var AUTO_PREFIX = Buffer39.from("__flow_auto__:", "ascii");
|
|
8796
9619
|
var MAX_CACHEABLE_PARTITION_BYTES = 4 * 1024;
|
|
8797
9620
|
var MAX_CACHE_BYTES = 1 * 1024 * 1024;
|
|
8798
9621
|
var MAX_CACHE_ENTRIES = 1024;
|
|
@@ -8802,10 +9625,10 @@ var cacheBytes = 0;
|
|
|
8802
9625
|
var cacheHits = 0;
|
|
8803
9626
|
var cacheMisses = 0;
|
|
8804
9627
|
function flowLogicalPartitionRoutingKey(value) {
|
|
8805
|
-
if (typeof value !== "string" && !
|
|
9628
|
+
if (typeof value !== "string" && !Buffer39.isBuffer(value)) return void 0;
|
|
8806
9629
|
const autoBucket = flowAutoBucket(value);
|
|
8807
9630
|
if (autoBucket != null) return `{fa:${autoBucket}}`;
|
|
8808
|
-
const bytes2 =
|
|
9631
|
+
const bytes2 = Buffer39.isBuffer(value) ? value : Buffer39.from(value);
|
|
8809
9632
|
if (bytes2.byteLength > MAX_CACHEABLE_PARTITION_BYTES) return hashRoute(bytes2);
|
|
8810
9633
|
const cacheKey = bytes2.toString("base64");
|
|
8811
9634
|
const cached = routeCache.get(cacheKey);
|
|
@@ -8879,7 +9702,7 @@ function routingKeyFromProtocolPayload(name, command) {
|
|
|
8879
9702
|
"scope"
|
|
8880
9703
|
]) {
|
|
8881
9704
|
const value = getField(command.payload, field3);
|
|
8882
|
-
if (typeof value === "string" ||
|
|
9705
|
+
if (typeof value === "string" || Buffer40.isBuffer(value)) {
|
|
8883
9706
|
return value;
|
|
8884
9707
|
}
|
|
8885
9708
|
}
|
|
@@ -8927,7 +9750,7 @@ function flowRoutingData(name, args) {
|
|
|
8927
9750
|
if (typeof partition === "string" && partition.toUpperCase() !== "AUTO" && partition.toUpperCase() !== "MIXED") {
|
|
8928
9751
|
return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
|
|
8929
9752
|
}
|
|
8930
|
-
if (
|
|
9753
|
+
if (Buffer40.isBuffer(partition)) {
|
|
8931
9754
|
const text3 = partition.toString("utf8").toUpperCase();
|
|
8932
9755
|
if (text3 !== "AUTO" && text3 !== "MIXED") {
|
|
8933
9756
|
return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
|
|
@@ -9018,17 +9841,17 @@ function flowPartitionRoutingKeyFromCommand(command, claim) {
|
|
|
9018
9841
|
return { handled: false };
|
|
9019
9842
|
}
|
|
9020
9843
|
function isRoutingKey(value) {
|
|
9021
|
-
return typeof value === "string" ||
|
|
9844
|
+
return typeof value === "string" || Buffer40.isBuffer(value);
|
|
9022
9845
|
}
|
|
9023
9846
|
function flowAutoIdRoutingKey(value) {
|
|
9024
|
-
if (typeof value !== "string" && !
|
|
9847
|
+
if (typeof value !== "string" && !Buffer40.isBuffer(value)) {
|
|
9025
9848
|
return void 0;
|
|
9026
9849
|
}
|
|
9027
|
-
const bucket = (
|
|
9850
|
+
const bucket = (Buffer40.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
|
|
9028
9851
|
return `{fa:${bucket}}`;
|
|
9029
9852
|
}
|
|
9030
9853
|
function flowClaimLogicalPartitionRoutingKey(value) {
|
|
9031
|
-
if (typeof value !== "string" && !
|
|
9854
|
+
if (typeof value !== "string" && !Buffer40.isBuffer(value)) return void 0;
|
|
9032
9855
|
const selector = commandPart(value);
|
|
9033
9856
|
if (selector === "AUTO" || selector === "ANY") return void 0;
|
|
9034
9857
|
if (selector === "GLOBAL") return "{f}";
|
|
@@ -9043,7 +9866,7 @@ function singleShardFlowClaimPartitionKey(values) {
|
|
|
9043
9866
|
return keys.some((key) => key == null) ? void 0 : singleShardKey(keys);
|
|
9044
9867
|
}
|
|
9045
9868
|
function singleShardKey(keys) {
|
|
9046
|
-
if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !
|
|
9869
|
+
if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !Buffer40.isBuffer(key))) {
|
|
9047
9870
|
return void 0;
|
|
9048
9871
|
}
|
|
9049
9872
|
const usable = keys;
|
|
@@ -9076,7 +9899,7 @@ function routedKeyGroups(keys, routeKey) {
|
|
|
9076
9899
|
const groups = /* @__PURE__ */ new Map();
|
|
9077
9900
|
for (let index = 0; index < keys.length; index += 1) {
|
|
9078
9901
|
const key = keys[index];
|
|
9079
|
-
if (typeof key !== "string" && !
|
|
9902
|
+
if (typeof key !== "string" && !Buffer40.isBuffer(key)) return void 0;
|
|
9080
9903
|
const route = routeKey(key);
|
|
9081
9904
|
const groupKey = `${route.endpointKey}\0${route.laneId}`;
|
|
9082
9905
|
const group = groups.get(groupKey);
|
|
@@ -10165,7 +10988,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
10165
10988
|
};
|
|
10166
10989
|
|
|
10167
10990
|
// src/response-map-preservation.ts
|
|
10168
|
-
import { Buffer as
|
|
10991
|
+
import { Buffer as Buffer42 } from "buffer";
|
|
10169
10992
|
function toStringKeyMapPreservingValues(value) {
|
|
10170
10993
|
if (value == null) return void 0;
|
|
10171
10994
|
const result = {};
|
|
@@ -10175,7 +10998,7 @@ function toStringKeyMapPreservingValues(value) {
|
|
|
10175
10998
|
}
|
|
10176
10999
|
return result;
|
|
10177
11000
|
}
|
|
10178
|
-
if (typeof value === "object" && !Array.isArray(value) && !
|
|
11001
|
+
if (typeof value === "object" && !Array.isArray(value) && !Buffer42.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
10179
11002
|
for (const [key, item] of Object.entries(value)) {
|
|
10180
11003
|
setOwnValue(result, text(key), normalizeMapStructurePreservingBytes(item));
|
|
10181
11004
|
}
|
|
@@ -10184,7 +11007,7 @@ function toStringKeyMapPreservingValues(value) {
|
|
|
10184
11007
|
return void 0;
|
|
10185
11008
|
}
|
|
10186
11009
|
function normalizeMapStructurePreservingBytes(value) {
|
|
10187
|
-
if (
|
|
11010
|
+
if (Buffer42.isBuffer(value) || value instanceof Uint8Array) return value;
|
|
10188
11011
|
if (value instanceof Map) {
|
|
10189
11012
|
const result = {};
|
|
10190
11013
|
for (const [key, item] of value.entries()) {
|
|
@@ -10206,7 +11029,7 @@ function normalizeMapStructurePreservingBytes(value) {
|
|
|
10206
11029
|
}
|
|
10207
11030
|
|
|
10208
11031
|
// src/native-kv-responses.ts
|
|
10209
|
-
import { Buffer as
|
|
11032
|
+
import { Buffer as Buffer43 } from "buffer";
|
|
10210
11033
|
function rateLimitResultFromResp(value) {
|
|
10211
11034
|
if (!Array.isArray(value) || value.length !== 4) {
|
|
10212
11035
|
throw new TypeError("RATELIMIT.ADD returned an unexpected response");
|
|
@@ -10263,13 +11086,13 @@ function fetchOrComputeResultFromResp(value, codec) {
|
|
|
10263
11086
|
}
|
|
10264
11087
|
function decodePayload(codec, value) {
|
|
10265
11088
|
if (value == null) return null;
|
|
10266
|
-
if (
|
|
10267
|
-
if (value instanceof Uint8Array) return codec.decode(
|
|
10268
|
-
if (typeof value === "string") return codec.decode(
|
|
11089
|
+
if (Buffer43.isBuffer(value)) return codec.decode(value);
|
|
11090
|
+
if (value instanceof Uint8Array) return codec.decode(Buffer43.from(value));
|
|
11091
|
+
if (typeof value === "string") return codec.decode(Buffer43.from(value));
|
|
10269
11092
|
return normalizeRefMeta(value);
|
|
10270
11093
|
}
|
|
10271
11094
|
function requiredResponseString(value, context) {
|
|
10272
|
-
if (typeof value !== "string" && !
|
|
11095
|
+
if (typeof value !== "string" && !Buffer43.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
10273
11096
|
throw new TypeError(`${context} returned an unexpected response`);
|
|
10274
11097
|
}
|
|
10275
11098
|
const result = text(value);
|
|
@@ -10286,7 +11109,7 @@ function requiredNonNegativeInteger(value, context) {
|
|
|
10286
11109
|
return result;
|
|
10287
11110
|
}
|
|
10288
11111
|
function responseBytes(value, context) {
|
|
10289
|
-
if (typeof value !== "string" && !
|
|
11112
|
+
if (typeof value !== "string" && !Buffer43.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
10290
11113
|
throw new TypeError(`${context} returned an unexpected response`);
|
|
10291
11114
|
}
|
|
10292
11115
|
return bytes(value);
|
|
@@ -10969,7 +11792,7 @@ function groupAutoPartitionItems(items) {
|
|
|
10969
11792
|
}
|
|
10970
11793
|
|
|
10971
11794
|
// src/client-values.ts
|
|
10972
|
-
import { Buffer as
|
|
11795
|
+
import { Buffer as Buffer44 } from "buffer";
|
|
10973
11796
|
async function valueMGetEntries(client, refs, options = {}) {
|
|
10974
11797
|
const refCount = refs.length;
|
|
10975
11798
|
if (refCount === 0) {
|
|
@@ -11004,12 +11827,12 @@ async function valueMGetEntries(client, refs, options = {}) {
|
|
|
11004
11827
|
const item = response[index];
|
|
11005
11828
|
if (item == null) {
|
|
11006
11829
|
entries[index] = { found: false };
|
|
11007
|
-
} else if (
|
|
11830
|
+
} else if (Buffer44.isBuffer(item)) {
|
|
11008
11831
|
entries[index] = { found: true, value: client.codec.decode(item) };
|
|
11009
11832
|
} else if (item instanceof Uint8Array) {
|
|
11010
|
-
entries[index] = { found: true, value: client.codec.decode(
|
|
11833
|
+
entries[index] = { found: true, value: client.codec.decode(Buffer44.from(item)) };
|
|
11011
11834
|
} else if (typeof item === "string") {
|
|
11012
|
-
entries[index] = { found: true, value: client.codec.decode(
|
|
11835
|
+
entries[index] = { found: true, value: client.codec.decode(Buffer44.from(item)) };
|
|
11013
11836
|
} else {
|
|
11014
11837
|
entries[index] = { found: true, value: item };
|
|
11015
11838
|
}
|
|
@@ -11021,7 +11844,7 @@ async function valueMGetEntries(client, refs, options = {}) {
|
|
|
11021
11844
|
import "buffer";
|
|
11022
11845
|
|
|
11023
11846
|
// src/auto-batch-ordering.ts
|
|
11024
|
-
import { Buffer as
|
|
11847
|
+
import { Buffer as Buffer45 } from "buffer";
|
|
11025
11848
|
function autoBatchOrderingPlan(batch) {
|
|
11026
11849
|
const accesses = /* @__PURE__ */ new Map();
|
|
11027
11850
|
const fallbackDependencies = [];
|
|
@@ -11136,13 +11959,13 @@ function flowManyAutoBatchIds(command, name) {
|
|
|
11136
11959
|
return fixedFlowItemIds(
|
|
11137
11960
|
command,
|
|
11138
11961
|
mixed ? 4 : 3,
|
|
11139
|
-
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) &&
|
|
11962
|
+
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) && Buffer45.isBuffer(command[itemIndex + (mixed ? 3 : 2)])
|
|
11140
11963
|
);
|
|
11141
11964
|
}
|
|
11142
11965
|
return fixedFlowItemIds(
|
|
11143
11966
|
command,
|
|
11144
11967
|
mixed ? 4 : 3,
|
|
11145
|
-
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) &&
|
|
11968
|
+
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && Buffer45.isBuffer(command[itemIndex + (mixed ? 2 : 1)]) && isFencingToken(command[itemIndex + (mixed ? 3 : 2)])
|
|
11146
11969
|
);
|
|
11147
11970
|
}
|
|
11148
11971
|
function createManyAutoBatchIds(command) {
|
|
@@ -11155,7 +11978,7 @@ function createManyAutoBatchIds(command) {
|
|
|
11155
11978
|
const ids = fixedFlowItemIds(
|
|
11156
11979
|
command,
|
|
11157
11980
|
width,
|
|
11158
|
-
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) &&
|
|
11981
|
+
(itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && Buffer45.isBuffer(command[itemIndex + width - 1]),
|
|
11159
11982
|
markerIndex
|
|
11160
11983
|
);
|
|
11161
11984
|
if (ids != null) return ids;
|
|
@@ -11173,7 +11996,7 @@ function extendedCreateManyAutoBatchIds(command, markerIndex) {
|
|
|
11173
11996
|
let cursor = markerIndex + 2;
|
|
11174
11997
|
for (let itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
|
|
11175
11998
|
const id = command[cursor];
|
|
11176
|
-
if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !
|
|
11999
|
+
if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !Buffer45.isBuffer(command[cursor + 2])) return void 0;
|
|
11177
12000
|
ids.push(id);
|
|
11178
12001
|
cursor += 3;
|
|
11179
12002
|
const afterValues = skipExtendedNamedItems(command, cursor, true);
|
|
@@ -11192,7 +12015,7 @@ function skipExtendedNamedItems(command, countIndex, encodedValues) {
|
|
|
11192
12015
|
for (let index = 0; index < count; index += 1) {
|
|
11193
12016
|
const name = command[firstItem + index * 2];
|
|
11194
12017
|
const value = command[firstItem + index * 2 + 1];
|
|
11195
|
-
if (!isAutoBatchResourceValue(name) || (encodedValues ? !
|
|
12018
|
+
if (!isAutoBatchResourceValue(name) || (encodedValues ? !Buffer45.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
|
|
11196
12019
|
}
|
|
11197
12020
|
return firstItem + count * 2;
|
|
11198
12021
|
}
|
|
@@ -11207,7 +12030,7 @@ function runStepsManyAutoBatchIds(command) {
|
|
|
11207
12030
|
ids.push(item);
|
|
11208
12031
|
continue;
|
|
11209
12032
|
}
|
|
11210
|
-
if (typeof item !== "object" || item == null || Array.isArray(item) ||
|
|
12033
|
+
if (typeof item !== "object" || item == null || Array.isArray(item) || Buffer45.isBuffer(item)) return void 0;
|
|
11211
12034
|
const id = item.id;
|
|
11212
12035
|
if (!isAutoBatchResourceValue(id)) return void 0;
|
|
11213
12036
|
ids.push(id);
|
|
@@ -11248,7 +12071,7 @@ function flowValuePutOwner(command, start) {
|
|
|
11248
12071
|
}
|
|
11249
12072
|
var flowValuePutOptionTokens = /* @__PURE__ */ new Set(["NAME", "NOW", "OVERRIDE", "OWNER_FLOW_ID", "PARTITION", "TTL", "TTL_MS"]);
|
|
11250
12073
|
function isAutoBatchResourceValue(value) {
|
|
11251
|
-
return typeof value === "string" ||
|
|
12074
|
+
return typeof value === "string" || Buffer45.isBuffer(value);
|
|
11252
12075
|
}
|
|
11253
12076
|
function isFencingToken(value) {
|
|
11254
12077
|
return typeof value === "number" && Number.isSafeInteger(value) || typeof value === "bigint";
|
|
@@ -11257,7 +12080,7 @@ function nonNegativeItemCount(value) {
|
|
|
11257
12080
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
11258
12081
|
}
|
|
11259
12082
|
function autoBatchResourceKey(namespace, value) {
|
|
11260
|
-
return `${namespace}:${
|
|
12083
|
+
return `${namespace}:${Buffer45.from(value).toString("base64")}`;
|
|
11261
12084
|
}
|
|
11262
12085
|
function autoBatchCommandName(command) {
|
|
11263
12086
|
return commandView(command).name ?? null;
|
|
@@ -11669,10 +12492,10 @@ function claimFailure(error) {
|
|
|
11669
12492
|
import "buffer";
|
|
11670
12493
|
|
|
11671
12494
|
// src/flow-query-builder.ts
|
|
11672
|
-
import { Buffer as
|
|
12495
|
+
import { Buffer as Buffer48 } from "buffer";
|
|
11673
12496
|
|
|
11674
12497
|
// src/flow-query-metadata.ts
|
|
11675
|
-
import { Buffer as
|
|
12498
|
+
import { Buffer as Buffer47 } from "buffer";
|
|
11676
12499
|
var MAX_FLOW_QUERY_METADATA_KEY_BYTES = 64;
|
|
11677
12500
|
function normalizeStateMeta(value, state) {
|
|
11678
12501
|
if (value == null) return {};
|
|
@@ -11697,7 +12520,7 @@ function normalizeStateMeta(value, state) {
|
|
|
11697
12520
|
function metadataEntries(value, context) {
|
|
11698
12521
|
const entries = objectEntries(value ?? {}, context).map(([rawName, item]) => {
|
|
11699
12522
|
const name = rawName.trim();
|
|
11700
|
-
const size =
|
|
12523
|
+
const size = Buffer47.byteLength(name, "utf8");
|
|
11701
12524
|
if (size === 0 || size > MAX_FLOW_QUERY_METADATA_KEY_BYTES || name.startsWith("__")) {
|
|
11702
12525
|
throw new TypeError(`${context} key is invalid or reserved`);
|
|
11703
12526
|
}
|
|
@@ -11721,7 +12544,7 @@ function objectEntries(value, context) {
|
|
|
11721
12544
|
return keys.map((key) => [key, value[key]]);
|
|
11722
12545
|
}
|
|
11723
12546
|
function isPlainRecord(value) {
|
|
11724
|
-
if (typeof value !== "object" || value == null || Array.isArray(value) ||
|
|
12547
|
+
if (typeof value !== "object" || value == null || Array.isArray(value) || Buffer47.isBuffer(value)) {
|
|
11725
12548
|
return false;
|
|
11726
12549
|
}
|
|
11727
12550
|
const prototype = Object.getPrototypeOf(value);
|
|
@@ -11791,7 +12614,7 @@ var FlowCollectionQuery = class {
|
|
|
11791
12614
|
const states = /* @__PURE__ */ new Set();
|
|
11792
12615
|
for (const [rawState, metadata] of objectEntries(values, "stateMeta")) {
|
|
11793
12616
|
const state = requiredText(rawState, "stateMeta state").trim();
|
|
11794
|
-
const stateBytes =
|
|
12617
|
+
const stateBytes = Buffer48.byteLength(state, "utf8");
|
|
11795
12618
|
if (stateBytes === 0 || stateBytes > MAX_FLOW_QUERY_STATE_BYTES) {
|
|
11796
12619
|
throw new TypeError(
|
|
11797
12620
|
`stateMeta state names must be 1..${MAX_FLOW_QUERY_STATE_BYTES} bytes`
|
|
@@ -11970,7 +12793,7 @@ function requiredPartition(value) {
|
|
|
11970
12793
|
"FLOW.QUERY convenience methods require a partition key"
|
|
11971
12794
|
);
|
|
11972
12795
|
}
|
|
11973
|
-
const size =
|
|
12796
|
+
const size = Buffer48.byteLength(value, "utf8");
|
|
11974
12797
|
if (size === 0 || size > MAX_FLOW_QUERY_PARTITION_BYTES) {
|
|
11975
12798
|
throw new TypeError(
|
|
11976
12799
|
`FLOW.QUERY partition key must be 1..${MAX_FLOW_QUERY_PARTITION_BYTES} bytes`
|
|
@@ -12018,23 +12841,23 @@ function requiredText(value, context) {
|
|
|
12018
12841
|
return value;
|
|
12019
12842
|
}
|
|
12020
12843
|
function queryParameter(value, context) {
|
|
12021
|
-
if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" ||
|
|
12844
|
+
if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || Buffer48.isBuffer(value)) {
|
|
12022
12845
|
return value;
|
|
12023
12846
|
}
|
|
12024
12847
|
throw new TypeError(`${context} must be a scalar FLOW.QUERY parameter`);
|
|
12025
12848
|
}
|
|
12026
12849
|
|
|
12027
12850
|
// src/flow-query-response.ts
|
|
12028
|
-
import { Buffer as
|
|
12851
|
+
import { Buffer as Buffer52 } from "buffer";
|
|
12029
12852
|
|
|
12030
12853
|
// src/flow-query-diagnostic-response.ts
|
|
12031
|
-
import { Buffer as
|
|
12854
|
+
import { Buffer as Buffer50 } from "buffer";
|
|
12032
12855
|
|
|
12033
12856
|
// src/flow-query-response-validation.ts
|
|
12034
|
-
import { Buffer as
|
|
12857
|
+
import { Buffer as Buffer49 } from "buffer";
|
|
12035
12858
|
function requiredMap2(value, context) {
|
|
12036
12859
|
if (value instanceof Map) return value;
|
|
12037
|
-
if (typeof value !== "object" || value == null || Array.isArray(value) ||
|
|
12860
|
+
if (typeof value !== "object" || value == null || Array.isArray(value) || Buffer49.isBuffer(value) || value instanceof Uint8Array) {
|
|
12038
12861
|
throw decodeError(`${context} must be a map`, value);
|
|
12039
12862
|
}
|
|
12040
12863
|
return value;
|
|
@@ -12091,7 +12914,7 @@ function normalizeMetadataValue(value, context, budget, ancestors, depth) {
|
|
|
12091
12914
|
if (!value.isWellFormed()) throw decodeError(`${context} contains invalid text`, value);
|
|
12092
12915
|
return value;
|
|
12093
12916
|
}
|
|
12094
|
-
if (
|
|
12917
|
+
if (Buffer49.isBuffer(value) || value instanceof Uint8Array) {
|
|
12095
12918
|
const decoded = strictText2(value);
|
|
12096
12919
|
if (decoded == null) throw decodeError(`${context} contains invalid UTF-8`, value);
|
|
12097
12920
|
return decoded;
|
|
@@ -12170,7 +12993,7 @@ function optionalText2(mapping2, name, context) {
|
|
|
12170
12993
|
}
|
|
12171
12994
|
function requiredBoundedText2(mapping2, name, context, maximumBytes) {
|
|
12172
12995
|
const value = requiredText2(mapping2, name, context);
|
|
12173
|
-
if (
|
|
12996
|
+
if (Buffer49.byteLength(value, "utf8") > maximumBytes) {
|
|
12174
12997
|
throw decodeError(
|
|
12175
12998
|
`${context} ${name} exceeds ${maximumBytes} bytes`,
|
|
12176
12999
|
mapping2
|
|
@@ -12183,7 +13006,7 @@ function boundedText(value, context, maximumBytes) {
|
|
|
12183
13006
|
if (decoded == null || decoded.length === 0) {
|
|
12184
13007
|
throw decodeError(`${context} must be non-empty text`, value);
|
|
12185
13008
|
}
|
|
12186
|
-
if (
|
|
13009
|
+
if (Buffer49.byteLength(decoded, "utf8") > maximumBytes) {
|
|
12187
13010
|
throw decodeError(`${context} exceeds ${maximumBytes} bytes`, value);
|
|
12188
13011
|
}
|
|
12189
13012
|
return decoded;
|
|
@@ -12195,7 +13018,7 @@ function requiredBoolean(mapping2, name, context) {
|
|
|
12195
13018
|
}
|
|
12196
13019
|
return value;
|
|
12197
13020
|
}
|
|
12198
|
-
function
|
|
13021
|
+
function nonNegativeInteger2(value, context) {
|
|
12199
13022
|
if (typeof value === "bigint") {
|
|
12200
13023
|
if (value >= 0n && value <= BigInt(Number.MAX_SAFE_INTEGER))
|
|
12201
13024
|
return Number(value);
|
|
@@ -12204,8 +13027,8 @@ function nonNegativeInteger(value, context) {
|
|
|
12204
13027
|
}
|
|
12205
13028
|
throw decodeError(`${context} must be a non-negative safe integer`, value);
|
|
12206
13029
|
}
|
|
12207
|
-
function
|
|
12208
|
-
const parsed =
|
|
13030
|
+
function positiveInteger2(value, context) {
|
|
13031
|
+
const parsed = nonNegativeInteger2(value, context);
|
|
12209
13032
|
if (parsed === 0) throw decodeError(`${context} must be positive`, value);
|
|
12210
13033
|
return parsed;
|
|
12211
13034
|
}
|
|
@@ -12237,10 +13060,10 @@ function positiveBoundedInteger(value, maximum, context) {
|
|
|
12237
13060
|
function hasKey(mapping2, name) {
|
|
12238
13061
|
if (!(mapping2 instanceof Map)) return Object.hasOwn(mapping2, name);
|
|
12239
13062
|
if (mapping2.has(name)) return true;
|
|
12240
|
-
const binaryName =
|
|
13063
|
+
const binaryName = Buffer49.from(name);
|
|
12241
13064
|
for (const key of mapping2.keys()) {
|
|
12242
|
-
if (
|
|
12243
|
-
if (key instanceof Uint8Array &&
|
|
13065
|
+
if (Buffer49.isBuffer(key) && key.equals(binaryName)) return true;
|
|
13066
|
+
if (key instanceof Uint8Array && Buffer49.from(key).equals(binaryName))
|
|
12244
13067
|
return true;
|
|
12245
13068
|
}
|
|
12246
13069
|
return false;
|
|
@@ -12251,7 +13074,7 @@ function decodeError(message, raw) {
|
|
|
12251
13074
|
function strictText2(value) {
|
|
12252
13075
|
if (typeof value === "string")
|
|
12253
13076
|
return value.isWellFormed() ? value : void 0;
|
|
12254
|
-
if (
|
|
13077
|
+
if (Buffer49.isBuffer(value) || value instanceof Uint8Array) {
|
|
12255
13078
|
try {
|
|
12256
13079
|
return new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
12257
13080
|
} catch {
|
|
@@ -12315,7 +13138,7 @@ function tryDecodeFlowQueryError(value, cause) {
|
|
|
12315
13138
|
hint: optionalDiagnosticText(mapping2, "hint"),
|
|
12316
13139
|
retryable: requiredBoolean(mapping2, "retryable", "FLOW.QUERY diagnostic"),
|
|
12317
13140
|
safeToRetry: requiredBoolean(mapping2, "safe_to_retry", "FLOW.QUERY diagnostic"),
|
|
12318
|
-
retryAfterMs:
|
|
13141
|
+
retryAfterMs: nonNegativeInteger2(
|
|
12319
13142
|
field(mapping2, "retry_after_ms"),
|
|
12320
13143
|
"FLOW.QUERY diagnostic retry_after_ms"
|
|
12321
13144
|
),
|
|
@@ -12331,7 +13154,7 @@ function tryDecodeFlowQueryError(value, cause) {
|
|
|
12331
13154
|
}
|
|
12332
13155
|
function optionalDiagnosticText(mapping2, name) {
|
|
12333
13156
|
const value = optionalText2(mapping2, name, "FLOW.QUERY diagnostic");
|
|
12334
|
-
if (value != null &&
|
|
13157
|
+
if (value != null && Buffer50.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
|
|
12335
13158
|
throw decodeError(
|
|
12336
13159
|
`FLOW.QUERY diagnostic ${name} exceeds ${DIAGNOSTIC_TEXT_BYTES} bytes`,
|
|
12337
13160
|
mapping2
|
|
@@ -12366,7 +13189,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
|
|
|
12366
13189
|
}
|
|
12367
13190
|
const text3 = diagnosticContextText(value);
|
|
12368
13191
|
if (text3 != null) {
|
|
12369
|
-
if (
|
|
13192
|
+
if (Buffer50.byteLength(text3, "utf8") <= DIAGNOSTIC_TEXT_BYTES) return;
|
|
12370
13193
|
throw decodeError("FLOW.QUERY diagnostic context contains oversized text", value);
|
|
12371
13194
|
}
|
|
12372
13195
|
if (depth <= 0) {
|
|
@@ -12392,7 +13215,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
|
|
|
12392
13215
|
}
|
|
12393
13216
|
for (const [rawKey, item] of entries) {
|
|
12394
13217
|
const key = diagnosticContextText(rawKey);
|
|
12395
|
-
if (key == null || key.length === 0 ||
|
|
13218
|
+
if (key == null || key.length === 0 || Buffer50.byteLength(key, "utf8") > DIAGNOSTIC_CONTEXT_KEY_BYTES) {
|
|
12396
13219
|
throw decodeError("FLOW.QUERY diagnostic context contains an invalid key", value);
|
|
12397
13220
|
}
|
|
12398
13221
|
validateDiagnosticContextValue(item, depth - 1, budget);
|
|
@@ -12409,7 +13232,7 @@ function consumeDiagnosticContextNode(value, budget) {
|
|
|
12409
13232
|
}
|
|
12410
13233
|
function diagnosticContextText(value) {
|
|
12411
13234
|
if (typeof value === "string") return value.isWellFormed() ? value : void 0;
|
|
12412
|
-
if (!
|
|
13235
|
+
if (!Buffer50.isBuffer(value) && !(value instanceof Uint8Array)) return void 0;
|
|
12413
13236
|
try {
|
|
12414
13237
|
return new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
12415
13238
|
} catch {
|
|
@@ -12425,9 +13248,9 @@ function decodePosition(value) {
|
|
|
12425
13248
|
if (value == null) return void 0;
|
|
12426
13249
|
const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic position");
|
|
12427
13250
|
return Object.freeze({
|
|
12428
|
-
byte:
|
|
12429
|
-
line:
|
|
12430
|
-
column:
|
|
13251
|
+
byte: positiveInteger2(field(mapping2, "byte"), "FLOW.QUERY diagnostic position byte"),
|
|
13252
|
+
line: positiveInteger2(field(mapping2, "line"), "FLOW.QUERY diagnostic position line"),
|
|
13253
|
+
column: positiveInteger2(
|
|
12431
13254
|
field(mapping2, "column"),
|
|
12432
13255
|
"FLOW.QUERY diagnostic position column"
|
|
12433
13256
|
)
|
|
@@ -12435,7 +13258,7 @@ function decodePosition(value) {
|
|
|
12435
13258
|
}
|
|
12436
13259
|
|
|
12437
13260
|
// src/flow-query-index-contract.ts
|
|
12438
|
-
import { Buffer as
|
|
13261
|
+
import { Buffer as Buffer51 } from "buffer";
|
|
12439
13262
|
var FLOW_QUERY_BUILD_PHASES = ["pending", "snapshot", "backfill", "done"];
|
|
12440
13263
|
var FLOW_QUERY_VALIDATION_PHASES = [
|
|
12441
13264
|
"pending",
|
|
@@ -12681,10 +13504,10 @@ function fieldKind(name) {
|
|
|
12681
13504
|
return void 0;
|
|
12682
13505
|
}
|
|
12683
13506
|
function validUnquoted(value) {
|
|
12684
|
-
return !value.startsWith("__") && UNQUOTED_METADATA.test(value) &&
|
|
13507
|
+
return !value.startsWith("__") && UNQUOTED_METADATA.test(value) && Buffer51.byteLength(value, "ascii") <= 64;
|
|
12685
13508
|
}
|
|
12686
13509
|
function validMetadata(value, rejectReserved) {
|
|
12687
|
-
return value.length > 0 &&
|
|
13510
|
+
return value.length > 0 && Buffer51.byteLength(value, "utf8") <= 64 && (!rejectReserved || !value.startsWith("__"));
|
|
12688
13511
|
}
|
|
12689
13512
|
function externalSelector(root, ...segments) {
|
|
12690
13513
|
return segments.every(validUnquoted) ? [root, ...segments].join(".") : root + segments.map((segment) => `['${segment.replaceAll("'", "''")}']`).join("");
|
|
@@ -13194,7 +14017,7 @@ function decodeCountPrefixes(value, fieldCount) {
|
|
|
13194
14017
|
if (!Object.hasOwn(value, index)) {
|
|
13195
14018
|
throw decodeError(`${context} must be dense`, value);
|
|
13196
14019
|
}
|
|
13197
|
-
const prefix =
|
|
14020
|
+
const prefix = positiveInteger2(value[index], `${context} entry`);
|
|
13198
14021
|
if (prefix > fieldCount || prefix <= previous) {
|
|
13199
14022
|
throw decodeError(`${context} are invalid`, value);
|
|
13200
14023
|
}
|
|
@@ -13576,7 +14399,7 @@ function decodeUsage(value) {
|
|
|
13576
14399
|
const mapping2 = requiredMap2(value, "FLOW.QUERY usage");
|
|
13577
14400
|
const usage = /* @__PURE__ */ Object.create(null);
|
|
13578
14401
|
for (const [wireName, property] of USAGE_FIELDS2) {
|
|
13579
|
-
usage[property] =
|
|
14402
|
+
usage[property] = nonNegativeInteger2(
|
|
13580
14403
|
field(mapping2, wireName),
|
|
13581
14404
|
`FLOW.QUERY usage ${wireName}`
|
|
13582
14405
|
);
|
|
@@ -13591,7 +14414,7 @@ function decodePage(value) {
|
|
|
13591
14414
|
const mapping2 = requiredMap2(value, "FLOW.QUERY page");
|
|
13592
14415
|
const hasMore = requiredBoolean(mapping2, "has_more", "FLOW.QUERY page");
|
|
13593
14416
|
const cursor = optionalText2(mapping2, "cursor", "FLOW.QUERY page");
|
|
13594
|
-
if (cursor != null && (!cursor.startsWith("fqc1_") ||
|
|
14417
|
+
if (cursor != null && (!cursor.startsWith("fqc1_") || Buffer52.byteLength(cursor) < 16 || Buffer52.byteLength(cursor) > 4096)) {
|
|
13595
14418
|
throw decodeError("FLOW.QUERY page cursor is invalid", value);
|
|
13596
14419
|
}
|
|
13597
14420
|
if (hasMore !== (cursor != null)) {
|
|
@@ -13604,9 +14427,9 @@ function decodePage(value) {
|
|
|
13604
14427
|
import "buffer";
|
|
13605
14428
|
|
|
13606
14429
|
// src/client-core-helpers.ts
|
|
13607
|
-
import { Buffer as
|
|
14430
|
+
import { Buffer as Buffer53 } from "buffer";
|
|
13608
14431
|
function bgsaveResponse(response) {
|
|
13609
|
-
if ((typeof response === "string" ||
|
|
14432
|
+
if ((typeof response === "string" || Buffer53.isBuffer(response) || response instanceof Uint8Array) && text(response) === "Background saving started") {
|
|
13610
14433
|
return true;
|
|
13611
14434
|
}
|
|
13612
14435
|
return okResponse(response);
|
|
@@ -13620,7 +14443,7 @@ function fetchOrComputeCompletionToken(options) {
|
|
|
13620
14443
|
"fetch-or-compute completion requires computeToken"
|
|
13621
14444
|
);
|
|
13622
14445
|
}
|
|
13623
|
-
if (!
|
|
14446
|
+
if (!Buffer53.isBuffer(options.computeToken)) {
|
|
13624
14447
|
throw new TypeError("fetch-or-compute computeToken must be a Buffer");
|
|
13625
14448
|
}
|
|
13626
14449
|
return options.computeToken;
|
|
@@ -13711,7 +14534,14 @@ function snapshotClientOptions(options) {
|
|
|
13711
14534
|
...own2,
|
|
13712
14535
|
...typeof own2.autoBatch === "object" && own2.autoBatch != null ? { autoBatch: Object.freeze({ ...own2.autoBatch }) } : {},
|
|
13713
14536
|
...own2.backpressure == null ? {} : { backpressure: Object.freeze({ ...own2.backpressure }) },
|
|
13714
|
-
...typeof own2.reconnect === "object" && own2.reconnect != null ? { reconnect: Object.freeze({ ...own2.reconnect }) } : {}
|
|
14537
|
+
...typeof own2.reconnect === "object" && own2.reconnect != null ? { reconnect: Object.freeze({ ...own2.reconnect }) } : {},
|
|
14538
|
+
...own2.httpOptions == null ? {} : {
|
|
14539
|
+
httpOptions: Object.freeze({
|
|
14540
|
+
...own2.httpOptions,
|
|
14541
|
+
...own2.httpOptions.headers == null ? {} : { headers: Object.freeze({ ...own2.httpOptions.headers }) },
|
|
14542
|
+
...own2.httpOptions.tlsOptions == null ? {} : { tlsOptions: Object.freeze({ ...own2.httpOptions.tlsOptions }) }
|
|
14543
|
+
})
|
|
14544
|
+
}
|
|
13715
14545
|
};
|
|
13716
14546
|
return Object.freeze(snapshot);
|
|
13717
14547
|
}
|
|
@@ -13980,14 +14810,14 @@ var FerricStoreAdministrationClient = class extends FerricStoreClientBase {
|
|
|
13980
14810
|
};
|
|
13981
14811
|
|
|
13982
14812
|
// src/store-utilities.ts
|
|
13983
|
-
import { Buffer as
|
|
14813
|
+
import { Buffer as Buffer56 } from "buffer";
|
|
13984
14814
|
function encode(codec, value) {
|
|
13985
14815
|
return codec.encode(value);
|
|
13986
14816
|
}
|
|
13987
14817
|
function decode(codec, value) {
|
|
13988
14818
|
if (value == null) return null;
|
|
13989
|
-
if (
|
|
13990
|
-
if (value instanceof Uint8Array) return codec.decode(
|
|
14819
|
+
if (Buffer56.isBuffer(value)) return codec.decode(value);
|
|
14820
|
+
if (value instanceof Uint8Array) return codec.decode(Buffer56.from(value));
|
|
13991
14821
|
return value;
|
|
13992
14822
|
}
|
|
13993
14823
|
function number(value) {
|
|
@@ -14008,7 +14838,7 @@ function array(value, expectedItems, command) {
|
|
|
14008
14838
|
}
|
|
14009
14839
|
return value;
|
|
14010
14840
|
}
|
|
14011
|
-
function
|
|
14841
|
+
function denseArray2(value, command) {
|
|
14012
14842
|
return assertDenseArray(array(value), command);
|
|
14013
14843
|
}
|
|
14014
14844
|
function denseArrayResponse(value, expectedItems, command) {
|
|
@@ -14296,7 +15126,7 @@ var BloomFilterStore = class {
|
|
|
14296
15126
|
return integerReply(await this.client.command("BF.CARD", key));
|
|
14297
15127
|
}
|
|
14298
15128
|
async info(key) {
|
|
14299
|
-
return
|
|
15129
|
+
return denseArray2(await this.client.command("BF.INFO", key), "BF.INFO");
|
|
14300
15130
|
}
|
|
14301
15131
|
};
|
|
14302
15132
|
var CuckooFilterStore = class {
|
|
@@ -14335,7 +15165,7 @@ var CuckooFilterStore = class {
|
|
|
14335
15165
|
return integerReply(await this.client.command("CF.COUNT", key, encode(this.client.codec, element)));
|
|
14336
15166
|
}
|
|
14337
15167
|
async info(key) {
|
|
14338
|
-
return
|
|
15168
|
+
return denseArray2(await this.client.command("CF.INFO", key), "CF.INFO");
|
|
14339
15169
|
}
|
|
14340
15170
|
};
|
|
14341
15171
|
var CountMinSketchStore = class {
|
|
@@ -14380,7 +15210,7 @@ var CountMinSketchStore = class {
|
|
|
14380
15210
|
return okResponse(await commandArgs(this.client, args));
|
|
14381
15211
|
}
|
|
14382
15212
|
async info(key) {
|
|
14383
|
-
return
|
|
15213
|
+
return denseArray2(await this.client.command("CMS.INFO", key), "CMS.INFO");
|
|
14384
15214
|
}
|
|
14385
15215
|
};
|
|
14386
15216
|
var TopKStore = class {
|
|
@@ -14463,7 +15293,7 @@ var TopKStore = class {
|
|
|
14463
15293
|
);
|
|
14464
15294
|
}
|
|
14465
15295
|
async info(key) {
|
|
14466
|
-
return
|
|
15296
|
+
return denseArray2(await this.client.command("TOPK.INFO", key), "TOPK.INFO");
|
|
14467
15297
|
}
|
|
14468
15298
|
};
|
|
14469
15299
|
var TDigestStore = class {
|
|
@@ -14554,7 +15384,7 @@ var TDigestStore = class {
|
|
|
14554
15384
|
return string(await this.client.command("TDIGEST.MAX", key));
|
|
14555
15385
|
}
|
|
14556
15386
|
async info(key) {
|
|
14557
|
-
return
|
|
15387
|
+
return denseArray2(await this.client.command("TDIGEST.INFO", key), "TDIGEST.INFO");
|
|
14558
15388
|
}
|
|
14559
15389
|
async merge(destination, sources, options = {}) {
|
|
14560
15390
|
requireNonEmpty(sources, "TDIGEST.MERGE", "source");
|
|
@@ -14946,7 +15776,7 @@ var KeyValueStore = class {
|
|
|
14946
15776
|
return response == null ? null : string(response);
|
|
14947
15777
|
}
|
|
14948
15778
|
async objectHelp() {
|
|
14949
|
-
return
|
|
15779
|
+
return denseArray2(await this.client.command("OBJECT", "HELP"), "OBJECT HELP");
|
|
14950
15780
|
}
|
|
14951
15781
|
async objectFreq(key) {
|
|
14952
15782
|
return number(await this.client.command("OBJECT", "FREQ", key));
|
|
@@ -15954,14 +16784,14 @@ function validateScheduleCreate(id, options) {
|
|
|
15954
16784
|
validateTiming(kind, options);
|
|
15955
16785
|
const recurring = RECURRING_KINDS.has(kind);
|
|
15956
16786
|
validateTarget(options.target, recurring);
|
|
15957
|
-
|
|
15958
|
-
|
|
15959
|
-
|
|
15960
|
-
|
|
15961
|
-
|
|
15962
|
-
|
|
15963
|
-
|
|
15964
|
-
|
|
16787
|
+
nonNegativeInteger3(options.atMs, "at_ms");
|
|
16788
|
+
nonNegativeInteger3(options.delayMs, "delay_ms");
|
|
16789
|
+
nonNegativeInteger3(options.startAtMs, "start_at_ms");
|
|
16790
|
+
positiveInteger3(options.everyMs, "every_ms");
|
|
16791
|
+
positiveInteger3(options.overlapRetryMs, "overlap_retry_ms");
|
|
16792
|
+
positiveInteger3(options.maxFires, "max_fires");
|
|
16793
|
+
nonNegativeInteger3(options.endAtMs, "end_at_ms");
|
|
16794
|
+
nonNegativeInteger3(options.nowMs, "now_ms");
|
|
15965
16795
|
optionalBoolean(options.overwrite, "overwrite");
|
|
15966
16796
|
if (kind === "delay") {
|
|
15967
16797
|
if (options.delayMs == null) throw new TypeError("delay_ms is required for delay schedules");
|
|
@@ -16018,20 +16848,20 @@ function validateScheduleID(id) {
|
|
|
16018
16848
|
}
|
|
16019
16849
|
function validateScheduleFire(id, options) {
|
|
16020
16850
|
validateScheduleID(id);
|
|
16021
|
-
|
|
16022
|
-
|
|
16851
|
+
nonNegativeInteger3(options.fireAtMs, "fire_at_ms");
|
|
16852
|
+
nonNegativeInteger3(options.nowMs, "now_ms");
|
|
16023
16853
|
}
|
|
16024
16854
|
function validateScheduleStatus(id, nowMs2) {
|
|
16025
16855
|
validateScheduleID(id);
|
|
16026
|
-
|
|
16856
|
+
nonNegativeInteger3(nowMs2, "now_ms");
|
|
16027
16857
|
}
|
|
16028
16858
|
function validateScheduleFireDue(options) {
|
|
16029
16859
|
if (!mapping(options)) throw new TypeError("schedule fire-due options must be a mapping");
|
|
16030
|
-
|
|
16860
|
+
nonNegativeInteger3(options.nowMs, "now_ms");
|
|
16031
16861
|
optionalText3(options.worker, "worker");
|
|
16032
|
-
|
|
16033
|
-
|
|
16034
|
-
|
|
16862
|
+
positiveInteger3(options.leaseMs, "lease_ms");
|
|
16863
|
+
nonNegativeInteger3(options.blockMs, "block_ms");
|
|
16864
|
+
positiveInteger3(options.limit, "limit");
|
|
16035
16865
|
const leaseMs = options.leaseMs ?? 3e4;
|
|
16036
16866
|
if (options.nowMs != null && options.nowMs > MAX_EXACT_INTEGER - leaseMs) {
|
|
16037
16867
|
throw new TypeError("now_ms plus lease_ms exceeds the exact integer range");
|
|
@@ -16047,12 +16877,12 @@ function validateScheduleList(options) {
|
|
|
16047
16877
|
}
|
|
16048
16878
|
optionalText3(options.timezone, "timezone");
|
|
16049
16879
|
optionalText3(options.targetType, "target_type");
|
|
16050
|
-
|
|
16051
|
-
|
|
16880
|
+
nonNegativeInteger3(options.fromMs, "from_ms");
|
|
16881
|
+
nonNegativeInteger3(options.toMs, "to_ms");
|
|
16052
16882
|
if (options.fromMs != null && options.toMs != null && options.fromMs > options.toMs) {
|
|
16053
16883
|
throw new TypeError("from_ms must not exceed to_ms");
|
|
16054
16884
|
}
|
|
16055
|
-
|
|
16885
|
+
positiveInteger3(options.count, "count");
|
|
16056
16886
|
optionalBoolean(options.rev, "rev");
|
|
16057
16887
|
}
|
|
16058
16888
|
function effectiveKind(options) {
|
|
@@ -16110,7 +16940,7 @@ function validateTarget(value, recurring) {
|
|
|
16110
16940
|
if (typeof idPrefix === "string" && idPrefix.startsWith(INTERNAL_SCHEDULE_ID_PREFIX)) {
|
|
16111
16941
|
throw new TypeError("target id_prefix is reserved for internal use");
|
|
16112
16942
|
}
|
|
16113
|
-
|
|
16943
|
+
nonNegativeInteger3(own(target, "run_at_ms"), "target run_at_ms");
|
|
16114
16944
|
const priority = own(target, "priority");
|
|
16115
16945
|
if (priority != null && (typeof priority !== "number" || !Number.isSafeInteger(priority) || priority < 0 || priority > 2)) {
|
|
16116
16946
|
throw new TypeError("target priority must be an integer between 0 and 2");
|
|
@@ -16132,12 +16962,12 @@ function requiredText3(value, name) {
|
|
|
16132
16962
|
function optionalText3(value, name) {
|
|
16133
16963
|
if (value != null) requiredText3(value, name);
|
|
16134
16964
|
}
|
|
16135
|
-
function
|
|
16965
|
+
function nonNegativeInteger3(value, name) {
|
|
16136
16966
|
if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)) {
|
|
16137
16967
|
throw new TypeError(`${name} must be a non-negative exact integer`);
|
|
16138
16968
|
}
|
|
16139
16969
|
}
|
|
16140
|
-
function
|
|
16970
|
+
function positiveInteger3(value, name) {
|
|
16141
16971
|
if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0)) {
|
|
16142
16972
|
throw new TypeError(`${name} must be a positive exact integer`);
|
|
16143
16973
|
}
|
|
@@ -16843,7 +17673,7 @@ function throwIfClosed(signal) {
|
|
|
16843
17673
|
}
|
|
16844
17674
|
|
|
16845
17675
|
// src/flow-policy.ts
|
|
16846
|
-
import { Buffer as
|
|
17676
|
+
import { Buffer as Buffer58 } from "buffer";
|
|
16847
17677
|
var MAX_FLOW_POLICY_GENERATION = Number.MAX_SAFE_INTEGER;
|
|
16848
17678
|
function assertFlowPolicyGeneration(value) {
|
|
16849
17679
|
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
|
|
@@ -16861,7 +17691,7 @@ function flowPolicySnapshotFromResp(value) {
|
|
|
16861
17691
|
const states = optionalStates(field(policy, "states"));
|
|
16862
17692
|
return {
|
|
16863
17693
|
type: requiredText4(field(policy, "type"), "type"),
|
|
16864
|
-
generation:
|
|
17694
|
+
generation: nonNegativeInteger4(field(policy, "generation"), "generation"),
|
|
16865
17695
|
...state == null ? {} : { state },
|
|
16866
17696
|
...version == null ? {} : { version },
|
|
16867
17697
|
...mode == null ? {} : { mode },
|
|
@@ -16879,12 +17709,12 @@ function retrySnapshot(value, context) {
|
|
|
16879
17709
|
const retry2 = requiredRecord(value, `FLOW policy ${context}`);
|
|
16880
17710
|
const backoff = requiredRecord(field(retry2, "backoff"), `FLOW policy ${context}.backoff`);
|
|
16881
17711
|
return {
|
|
16882
|
-
maxRetries:
|
|
17712
|
+
maxRetries: nonNegativeInteger4(field(retry2, "max_retries"), `${context}.max_retries`),
|
|
16883
17713
|
backoff: {
|
|
16884
17714
|
kind: backoffKind(field(backoff, "kind"), `${context}.backoff.kind`),
|
|
16885
|
-
baseMs:
|
|
16886
|
-
maxMs:
|
|
16887
|
-
jitterPct:
|
|
17715
|
+
baseMs: nonNegativeInteger4(field(backoff, "base_ms"), `${context}.backoff.base_ms`),
|
|
17716
|
+
maxMs: nonNegativeInteger4(field(backoff, "max_ms"), `${context}.backoff.max_ms`),
|
|
17717
|
+
jitterPct: nonNegativeInteger4(field(backoff, "jitter_pct"), `${context}.backoff.jitter_pct`)
|
|
16888
17718
|
},
|
|
16889
17719
|
exhaustedTo: requiredText4(field(retry2, "exhausted_to"), `${context}.exhausted_to`)
|
|
16890
17720
|
};
|
|
@@ -16892,8 +17722,8 @@ function retrySnapshot(value, context) {
|
|
|
16892
17722
|
function retentionSnapshot(value, context) {
|
|
16893
17723
|
const retention = requiredRecord(value, `FLOW policy ${context}`);
|
|
16894
17724
|
return {
|
|
16895
|
-
ttlMs:
|
|
16896
|
-
historyMaxEvents:
|
|
17725
|
+
ttlMs: nonNegativeInteger4(field(retention, "ttl_ms"), `${context}.ttl_ms`),
|
|
17726
|
+
historyMaxEvents: nonNegativeInteger4(
|
|
16897
17727
|
field(retention, "history_max_events"),
|
|
16898
17728
|
`${context}.history_max_events`
|
|
16899
17729
|
)
|
|
@@ -16933,7 +17763,7 @@ function requiredRecord(value, context) {
|
|
|
16933
17763
|
}
|
|
16934
17764
|
return result;
|
|
16935
17765
|
}
|
|
16936
|
-
if (typeof value === "object" && value != null && !Array.isArray(value) && !
|
|
17766
|
+
if (typeof value === "object" && value != null && !Array.isArray(value) && !Buffer58.isBuffer(value) && !(value instanceof Uint8Array)) return value;
|
|
16937
17767
|
throw new TypeError(`${context} returned an unexpected response`);
|
|
16938
17768
|
}
|
|
16939
17769
|
function optionalRecord(value, context) {
|
|
@@ -16954,15 +17784,15 @@ function stringArray(value, context) {
|
|
|
16954
17784
|
}
|
|
16955
17785
|
function requiredText4(value, context) {
|
|
16956
17786
|
if (typeof value === "string") return value;
|
|
16957
|
-
if (
|
|
16958
|
-
return
|
|
17787
|
+
if (Buffer58.isBuffer(value) || value instanceof Uint8Array) {
|
|
17788
|
+
return Buffer58.from(value).toString("utf8");
|
|
16959
17789
|
}
|
|
16960
17790
|
throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
16961
17791
|
}
|
|
16962
17792
|
function optionalText4(value, context) {
|
|
16963
17793
|
return value == null ? void 0 : requiredText4(value, context);
|
|
16964
17794
|
}
|
|
16965
|
-
function
|
|
17795
|
+
function nonNegativeInteger4(value, context) {
|
|
16966
17796
|
let parsed;
|
|
16967
17797
|
try {
|
|
16968
17798
|
parsed = integer(value);
|
|
@@ -16974,14 +17804,14 @@ function nonNegativeInteger3(value, context) {
|
|
|
16974
17804
|
}
|
|
16975
17805
|
function optionalPositiveInteger(value, context) {
|
|
16976
17806
|
if (value == null) return void 0;
|
|
16977
|
-
const parsed =
|
|
17807
|
+
const parsed = nonNegativeInteger4(value, context);
|
|
16978
17808
|
if (parsed === 0) throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
|
|
16979
17809
|
return parsed;
|
|
16980
17810
|
}
|
|
16981
17811
|
function optionalVersion(value) {
|
|
16982
17812
|
if (value == null) return void 0;
|
|
16983
17813
|
if (typeof value === "number" || typeof value === "bigint") {
|
|
16984
|
-
return
|
|
17814
|
+
return nonNegativeInteger4(value, "version");
|
|
16985
17815
|
}
|
|
16986
17816
|
return requiredText4(value, "version");
|
|
16987
17817
|
}
|
|
@@ -17211,7 +18041,7 @@ var FerricStoreFlowSupportClient = class extends FerricStoreFlowQueryClient {
|
|
|
17211
18041
|
};
|
|
17212
18042
|
|
|
17213
18043
|
// src/flow-many-snapshot.ts
|
|
17214
|
-
import { Buffer as
|
|
18044
|
+
import { Buffer as Buffer60 } from "buffer";
|
|
17215
18045
|
var encodedOptionFields = ["error", "payload", "reason", "result"];
|
|
17216
18046
|
function snapshotCreateItem(item, codec) {
|
|
17217
18047
|
const snapshot = {
|
|
@@ -17251,7 +18081,7 @@ function snapshotFlowManyOptions(options, codec) {
|
|
|
17251
18081
|
}
|
|
17252
18082
|
function snapshotClaimedItem(item) {
|
|
17253
18083
|
const wire = item[CLAIMED_ITEM_WIRE];
|
|
17254
|
-
const leaseToken =
|
|
18084
|
+
const leaseToken = Buffer60.from(wire?.leaseToken ?? item.leaseToken);
|
|
17255
18085
|
const snapshot = {
|
|
17256
18086
|
...item,
|
|
17257
18087
|
fencingToken: wire?.fencingToken ?? item.fencingToken,
|
|
@@ -17268,15 +18098,15 @@ function snapshotClaimedItem(item) {
|
|
|
17268
18098
|
function snapshotFencedItem(item) {
|
|
17269
18099
|
return Object.freeze({
|
|
17270
18100
|
...item,
|
|
17271
|
-
...item.leaseToken == null ? {} : { leaseToken:
|
|
18101
|
+
...item.leaseToken == null ? {} : { leaseToken: Buffer60.from(item.leaseToken) }
|
|
17272
18102
|
});
|
|
17273
18103
|
}
|
|
17274
18104
|
function snapshotClaimedItemWire(wire, leaseToken) {
|
|
17275
18105
|
return Object.freeze({
|
|
17276
18106
|
fencingToken: wire.fencingToken,
|
|
17277
|
-
id:
|
|
18107
|
+
id: Buffer60.from(wire.id),
|
|
17278
18108
|
leaseToken,
|
|
17279
|
-
partitionKey: wire.partitionKey == null ? wire.partitionKey :
|
|
18109
|
+
partitionKey: wire.partitionKey == null ? wire.partitionKey : Buffer60.from(wire.partitionKey)
|
|
17280
18110
|
});
|
|
17281
18111
|
}
|
|
17282
18112
|
function snapshotArray(values) {
|
|
@@ -17287,7 +18117,7 @@ function snapshotArray(values) {
|
|
|
17287
18117
|
return Object.freeze(snapshot);
|
|
17288
18118
|
}
|
|
17289
18119
|
function snapshotStateMeta(stateMeta) {
|
|
17290
|
-
return snapshotRecord(stateMeta, (value) =>
|
|
18120
|
+
return snapshotRecord(stateMeta, (value) => Buffer60.isBuffer(value) ? Buffer60.from(value) : value);
|
|
17291
18121
|
}
|
|
17292
18122
|
function snapshotCommandRecord(values) {
|
|
17293
18123
|
const seen = /* @__PURE__ */ new WeakMap();
|
|
@@ -17305,7 +18135,7 @@ function snapshotRecord(values, capture) {
|
|
|
17305
18135
|
}
|
|
17306
18136
|
function snapshotCommandArgument(value, seen) {
|
|
17307
18137
|
if (typeof value !== "object" || value == null) return value;
|
|
17308
|
-
if (
|
|
18138
|
+
if (Buffer60.isBuffer(value) || value instanceof Uint8Array) return Buffer60.from(value);
|
|
17309
18139
|
const objectValue = value;
|
|
17310
18140
|
const existing = seen.get(objectValue);
|
|
17311
18141
|
if (existing != null) return existing;
|
|
@@ -18070,6 +18900,14 @@ var FerricStoreProducerClient = class extends FerricStoreClaimClient {
|
|
|
18070
18900
|
var FerricStoreClient = class _FerricStoreClient extends FerricStoreProducerClient {
|
|
18071
18901
|
static async fromUrl(url, options = {}) {
|
|
18072
18902
|
const clientOptions = snapshotClientOptions(options);
|
|
18903
|
+
const scheme = new URL(url).protocol;
|
|
18904
|
+
if (scheme === "http:" || scheme === "https:") {
|
|
18905
|
+
if (clientOptions.nativeOptions != null) {
|
|
18906
|
+
throw new TypeError("nativeOptions are not valid for an HTTP FerricStore URL");
|
|
18907
|
+
}
|
|
18908
|
+
const executor2 = await HTTPAdapter.fromUrl(url, clientOptions.httpOptions);
|
|
18909
|
+
return new _FerricStoreClient(executor2, clientOptions);
|
|
18910
|
+
}
|
|
18073
18911
|
const nativeOptions = snapshotNativeClientOptions(clientOptions.nativeOptions ?? {});
|
|
18074
18912
|
const reconnectOptions = clientOptions.reconnect ?? nativeOptions.autoReconnect ?? true;
|
|
18075
18913
|
const seeds = nativeOptions.seeds ?? [];
|
|
@@ -18293,7 +19131,7 @@ function nativeOptionsForBootstrap(options, signal) {
|
|
|
18293
19131
|
}
|
|
18294
19132
|
|
|
18295
19133
|
// src/flow-query-projection.ts
|
|
18296
|
-
import { Buffer as
|
|
19134
|
+
import { Buffer as Buffer61 } from "buffer";
|
|
18297
19135
|
var MAX_PROJECTION_FIELDS = 32;
|
|
18298
19136
|
var MAX_DYNAMIC_NAME_BYTES = 64;
|
|
18299
19137
|
var FIELD_BRAND = /* @__PURE__ */ Symbol("FerricStoreFlowProjectionField");
|
|
@@ -18363,7 +19201,7 @@ function projectFlowQuery(query, shape, ...fields) {
|
|
|
18363
19201
|
}
|
|
18364
19202
|
const base = stripOptionalTerminator(query);
|
|
18365
19203
|
const result = `${base} RETURN ${shape.toUpperCase()} (${selectors.join(", ")})`;
|
|
18366
|
-
if (
|
|
19204
|
+
if (Buffer61.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
|
|
18367
19205
|
throw new TypeError(`FLOW.QUERY query exceeds ${FLOW_QUERY_MAX_BYTES} bytes`);
|
|
18368
19206
|
}
|
|
18369
19207
|
return result;
|
|
@@ -18423,7 +19261,7 @@ function quoteName(value, allowPrivate) {
|
|
|
18423
19261
|
throw new TypeError("Flow query projection metadata name must be text");
|
|
18424
19262
|
}
|
|
18425
19263
|
validateUnicodeScalarText2(value);
|
|
18426
|
-
const size =
|
|
19264
|
+
const size = Buffer61.byteLength(value, "utf8");
|
|
18427
19265
|
if (size === 0 || size > MAX_DYNAMIC_NAME_BYTES || !allowPrivate && value.startsWith("__")) {
|
|
18428
19266
|
throw new TypeError(
|
|
18429
19267
|
`Flow query projection metadata names must be 1..${MAX_DYNAMIC_NAME_BYTES} UTF-8 bytes`
|
|
@@ -18525,7 +19363,7 @@ var LeaseRenewalGuard = class {
|
|
|
18525
19363
|
if (options.leaseRenewal === false) {
|
|
18526
19364
|
return;
|
|
18527
19365
|
}
|
|
18528
|
-
const intervalMs =
|
|
19366
|
+
const intervalMs = positiveInteger4(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
|
|
18529
19367
|
this.timer = setLongInterval(() => this.renew(), intervalMs);
|
|
18530
19368
|
this.timer.unref();
|
|
18531
19369
|
}
|
|
@@ -18597,7 +19435,7 @@ function snapshotLeasedJob(job) {
|
|
|
18597
19435
|
return snapshot;
|
|
18598
19436
|
}
|
|
18599
19437
|
function workerConcurrency(options) {
|
|
18600
|
-
return
|
|
19438
|
+
return positiveInteger4(options.concurrency ?? options.workers, 1);
|
|
18601
19439
|
}
|
|
18602
19440
|
function workerRefillStrategy(options) {
|
|
18603
19441
|
return options.refillStrategy === "wave" ? "wave" : "continuous";
|
|
@@ -18640,18 +19478,18 @@ function workerErrorPayload(error, options, codec) {
|
|
|
18640
19478
|
}
|
|
18641
19479
|
function workerBatchSize(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
|
|
18642
19480
|
return Math.min(
|
|
18643
|
-
|
|
18644
|
-
|
|
19481
|
+
positiveInteger4(options.batchSize, 10),
|
|
19482
|
+
positiveInteger4(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
|
|
18645
19483
|
);
|
|
18646
19484
|
}
|
|
18647
19485
|
function workerClaimLimit(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
|
|
18648
19486
|
return Math.min(workerBatchSize(options, flowManyBatchLimit), workerConcurrency(options));
|
|
18649
19487
|
}
|
|
18650
19488
|
function workerDrainBatches(options) {
|
|
18651
|
-
return
|
|
19489
|
+
return positiveInteger4(options.claimDrainBatches, 1);
|
|
18652
19490
|
}
|
|
18653
19491
|
function workerLeaseMs(options, fallback = 3e4) {
|
|
18654
|
-
return
|
|
19492
|
+
return positiveInteger4(options.leaseMs, positiveInteger4(fallback, 3e4));
|
|
18655
19493
|
}
|
|
18656
19494
|
function workerIdleSleepMs(options) {
|
|
18657
19495
|
return nonNegativeDuration(options.idleSleepMs, 250);
|
|
@@ -18663,7 +19501,7 @@ function workerClaimBlockMs(options, useBlocking) {
|
|
|
18663
19501
|
if (options.signal == null || !Number.isFinite(options.blockMs) || options.blockMs < 0) {
|
|
18664
19502
|
return options.blockMs;
|
|
18665
19503
|
}
|
|
18666
|
-
const abortPollMs =
|
|
19504
|
+
const abortPollMs = positiveInteger4(options.abortPollMs, 1e3);
|
|
18667
19505
|
return options.blockMs === 0 ? abortPollMs : Math.min(Math.trunc(options.blockMs), abortPollMs);
|
|
18668
19506
|
}
|
|
18669
19507
|
function workerMaxIdleSleepMs(options, idleSleepMs = workerIdleSleepMs(options)) {
|
|
@@ -18674,14 +19512,14 @@ function nextWorkerIdleSleepMs(currentIdleSleepMs, maxIdleSleepMs) {
|
|
|
18674
19512
|
return Math.min(maxIdleSleepMs, Math.max(1, currentIdleSleepMs * 2));
|
|
18675
19513
|
}
|
|
18676
19514
|
async function runContinuousWorkerPool(options) {
|
|
18677
|
-
const concurrency =
|
|
18678
|
-
const maxClaimSize =
|
|
19515
|
+
const concurrency = positiveInteger4(options.concurrency, 1);
|
|
19516
|
+
const maxClaimSize = positiveInteger4(options.maxClaimSize, concurrency);
|
|
18679
19517
|
const initialIdleSleepMs = nonNegativeDuration(options.idleSleepMs, 250);
|
|
18680
19518
|
const maxIdleSleepMs = Math.max(
|
|
18681
19519
|
initialIdleSleepMs,
|
|
18682
19520
|
nonNegativeDuration(options.maxIdleSleepMs, 5e3)
|
|
18683
19521
|
);
|
|
18684
|
-
const refillDelayMs =
|
|
19522
|
+
const refillDelayMs = nonNegativeInteger5(options.refillDelayMs, 0);
|
|
18685
19523
|
const active = /* @__PURE__ */ new Set();
|
|
18686
19524
|
const pending = [];
|
|
18687
19525
|
let pendingIndex = 0;
|
|
@@ -18797,10 +19635,10 @@ function normalizeWorkflowWorkerConfig(options) {
|
|
|
18797
19635
|
...captured
|
|
18798
19636
|
});
|
|
18799
19637
|
}
|
|
18800
|
-
function
|
|
19638
|
+
function positiveInteger4(value, fallback) {
|
|
18801
19639
|
return value == null || !Number.isFinite(value) ? fallback : Math.max(1, Math.trunc(value));
|
|
18802
19640
|
}
|
|
18803
|
-
function
|
|
19641
|
+
function nonNegativeInteger5(value, fallback) {
|
|
18804
19642
|
return value == null || !Number.isFinite(value) ? fallback : Math.max(0, Math.trunc(value));
|
|
18805
19643
|
}
|
|
18806
19644
|
function nonNegativeDuration(value, fallback) {
|
|
@@ -20429,7 +21267,7 @@ var WorkflowWorker = class {
|
|
|
20429
21267
|
};
|
|
20430
21268
|
|
|
20431
21269
|
// src/version.ts
|
|
20432
|
-
var FERRICSTORE_SDK_VERSION = "0.11.
|
|
21270
|
+
var FERRICSTORE_SDK_VERSION = "0.11.10";
|
|
20433
21271
|
var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
|
|
20434
21272
|
var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
20435
21273
|
export {
|
|
@@ -20452,6 +21290,8 @@ export {
|
|
|
20452
21290
|
FlowQueryError,
|
|
20453
21291
|
FlowWrongStateError,
|
|
20454
21292
|
GeoStore,
|
|
21293
|
+
HTTPAdapter,
|
|
21294
|
+
HTTPTransportError,
|
|
20455
21295
|
HashStore,
|
|
20456
21296
|
HyperLogLogStore,
|
|
20457
21297
|
InvalidCommandError,
|
|
@@ -20489,6 +21329,7 @@ export {
|
|
|
20489
21329
|
classifyServerError,
|
|
20490
21330
|
complete,
|
|
20491
21331
|
fail2 as fail,
|
|
21332
|
+
httpCommandDisposition,
|
|
20492
21333
|
isOutcome,
|
|
20493
21334
|
isReconnectableClosedConnectionError,
|
|
20494
21335
|
mapException,
|