@ferricstore/ferricstore 0.13.0 → 0.13.2
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 +53 -1
- package/dist/index.cjs +230 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -6
- package/dist/index.d.ts +30 -6
- package/dist/index.js +229 -82
- package/dist/index.js.map +1 -1
- package/dist/langgraph.cjs.map +1 -1
- package/dist/langgraph.js.map +1 -1
- package/dist/openai-agents.cjs.map +1 -1
- package/dist/openai-agents.js.map +1 -1
- package/docs/api/assets/hierarchy.js +1 -1
- package/docs/api/assets/highlight.css +9 -2
- package/docs/api/assets/navigation.js +1 -1
- package/docs/api/assets/search.js +1 -1
- package/docs/api/classes/ConnectionClosedError.html +4 -4
- package/docs/api/classes/FerricStoreClient.html +13 -13
- package/docs/api/classes/FerricStoreError.html +1 -0
- package/docs/api/classes/FlowAlreadyExistsError.html +3 -3
- package/docs/api/classes/FlowNotFoundError.html +3 -3
- package/docs/api/classes/FlowWrongStateError.html +3 -3
- package/docs/api/classes/HTTPTransportError.html +13 -7
- package/docs/api/classes/InvalidCommandError.html +3 -3
- package/docs/api/classes/LeaseRenewalError.html +1 -1
- package/docs/api/classes/LockHeldError.html +3 -3
- package/docs/api/classes/LockNotOwnedError.html +3 -3
- package/docs/api/classes/NativeAdapter.html +3 -3
- package/docs/api/classes/OverloadedError.html +5 -5
- package/docs/api/classes/QueueCompletionError.html +1 -1
- package/docs/api/classes/RequestNotSentError.html +225 -0
- package/docs/api/classes/RequestTimeoutError.html +6 -6
- package/docs/api/classes/RerouteError.html +3 -3
- package/docs/api/classes/StaleLeaseError.html +3 -3
- package/docs/api/classes/StalePolicyGenerationError.html +3 -3
- package/docs/api/classes/WorkflowContext.html +7 -9
- package/docs/api/functions/classifyServerError.html +1 -1
- package/docs/api/functions/mapException.html +1 -1
- package/docs/api/hierarchy.html +21 -20
- package/docs/api/index.html +38 -2
- package/docs/api/interfaces/AdvanceOptions.html +9 -5
- package/docs/api/interfaces/AlreadyAppliedOutcome.html +1 -1
- package/docs/api/interfaces/AppliedStepOutcome.html +1 -1
- package/docs/api/interfaces/CancelOptions.html +12 -8
- package/docs/api/interfaces/CompleteOptions.html +12 -8
- package/docs/api/interfaces/CompleteOutcome.html +1 -1
- package/docs/api/interfaces/ExtendLeaseOptions.html +10 -8
- package/docs/api/interfaces/FailOptions.html +12 -8
- package/docs/api/interfaces/FailOutcome.html +1 -1
- package/docs/api/interfaces/HistoryOptions.html +16 -16
- package/docs/api/interfaces/LeaseMutationOptions.html +10 -6
- package/docs/api/interfaces/MutateOptions.html +7 -3
- package/docs/api/interfaces/NamedValueMutation.html +1 -1
- package/docs/api/interfaces/ReadOptions.html +11 -11
- package/docs/api/interfaces/RetryOptions.html +12 -8
- package/docs/api/interfaces/RetryOutcome.html +1 -1
- package/docs/api/interfaces/RunStepsItem.html +3 -3
- package/docs/api/interfaces/RunStepsManyOptions.html +11 -11
- package/docs/api/interfaces/SearchOptions.html +12 -12
- package/docs/api/interfaces/StepContinueOptions.html +15 -11
- package/docs/api/interfaces/StepOptions.html +15 -8
- package/docs/api/interfaces/StepResult.html +3 -3
- package/docs/api/interfaces/TDigestCreateOptions.html +1 -1
- package/docs/api/interfaces/TDigestMergeOptions.html +1 -1
- package/docs/api/interfaces/TransitionOptions.html +14 -10
- package/docs/api/interfaces/TransitionOutcome.html +1 -1
- package/docs/api/media/design.md +22 -1
- package/docs/api/modules.html +2 -2
- package/docs/api/types/ConnectionRequestDisposition.html +1 -1
- package/docs/api/types/ManagementPairs.html +1 -1
- package/docs/api/types/RequestDisposition.html +1 -1
- package/docs/api/types/SearchStateMeta.html +1 -1
- package/docs/api/variables/FERRICSTORE_SDK_VERSION.html +1 -1
- package/docs/design.md +22 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -69,6 +69,7 @@ __export(index_exports, {
|
|
|
69
69
|
QueueWorker: () => QueueWorker,
|
|
70
70
|
RawCodec: () => RawCodec,
|
|
71
71
|
ReconnectingExecutor: () => ReconnectingExecutor,
|
|
72
|
+
RequestNotSentError: () => RequestNotSentError,
|
|
72
73
|
RequestTimeoutError: () => RequestTimeoutError,
|
|
73
74
|
RerouteError: () => RerouteError,
|
|
74
75
|
RoutingTopology: () => RoutingTopology,
|
|
@@ -131,9 +132,16 @@ var FerricStoreError = class extends Error {
|
|
|
131
132
|
};
|
|
132
133
|
var HTTPTransportError = class extends FerricStoreError {
|
|
133
134
|
code = "http_transport";
|
|
135
|
+
requestDisposition;
|
|
134
136
|
statusCode;
|
|
135
137
|
constructor(message, options = {}) {
|
|
136
|
-
|
|
138
|
+
const disposition = options.requestDisposition;
|
|
139
|
+
super(message, {
|
|
140
|
+
...options,
|
|
141
|
+
retryable: options.retryable ?? (disposition === "unsent" ? false : void 0),
|
|
142
|
+
safeToRetry: options.safeToRetry ?? (disposition === "unsent" ? true : disposition === "possibly_sent" ? false : void 0)
|
|
143
|
+
});
|
|
144
|
+
this.requestDisposition = disposition;
|
|
137
145
|
this.statusCode = options.statusCode;
|
|
138
146
|
}
|
|
139
147
|
};
|
|
@@ -158,6 +166,20 @@ var RequestTimeoutError = class extends FerricStoreError {
|
|
|
158
166
|
this.timeoutMs = timeoutMs;
|
|
159
167
|
}
|
|
160
168
|
};
|
|
169
|
+
var RequestNotSentError = class extends FerricStoreError {
|
|
170
|
+
code = "request_not_sent";
|
|
171
|
+
requestDisposition = "unsent";
|
|
172
|
+
constructor(message, options = {}) {
|
|
173
|
+
super(message, { ...options, retryable: false, safeToRetry: true });
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
function requestNotSentError(error, message) {
|
|
177
|
+
if (error instanceof RequestNotSentError) return error;
|
|
178
|
+
return new RequestNotSentError(
|
|
179
|
+
message ?? (error instanceof Error ? error.message : String(error)),
|
|
180
|
+
{ cause: error, raw: error }
|
|
181
|
+
);
|
|
182
|
+
}
|
|
161
183
|
var FlowNotFoundError = class extends FerricStoreError {
|
|
162
184
|
code = "flow_not_found";
|
|
163
185
|
};
|
|
@@ -6416,7 +6438,10 @@ function decodeCompactPipeline(data, budget, claimModes) {
|
|
|
6416
6438
|
);
|
|
6417
6439
|
offset = read.offset;
|
|
6418
6440
|
} else {
|
|
6419
|
-
throw new FerricStoreError(
|
|
6441
|
+
throw new FerricStoreError(`unknown compact pipeline status ${status}`, {
|
|
6442
|
+
retryable: false,
|
|
6443
|
+
safeToRetry: false
|
|
6444
|
+
});
|
|
6420
6445
|
}
|
|
6421
6446
|
}
|
|
6422
6447
|
if (offset !== data.byteLength) throw new FerricStoreError("trailing compact pipeline bytes");
|
|
@@ -6586,6 +6611,7 @@ var COUNTED_COMPACT_TAGS = /* @__PURE__ */ new Set([
|
|
|
6586
6611
|
]);
|
|
6587
6612
|
|
|
6588
6613
|
// src/protocol-response.ts
|
|
6614
|
+
var KNOWN_NATIVE_RESPONSE_STATUSES = /* @__PURE__ */ new Set([0, 1, 2, 3, 4, 5, 6]);
|
|
6589
6615
|
function decodeResponse(frame, expectedOpcode, hints = {}) {
|
|
6590
6616
|
if (frame.opcode !== expectedOpcode) {
|
|
6591
6617
|
throw new FerricStoreError(
|
|
@@ -6610,6 +6636,13 @@ function decodeResponse(frame, expectedOpcode, hints = {}) {
|
|
|
6610
6636
|
customPayload
|
|
6611
6637
|
);
|
|
6612
6638
|
if (status === STATUS_OK) return value;
|
|
6639
|
+
if (!KNOWN_NATIVE_RESPONSE_STATUSES.has(status)) {
|
|
6640
|
+
throw new FerricStoreError(`unknown native response status ${status}`, {
|
|
6641
|
+
raw: value,
|
|
6642
|
+
retryable: false,
|
|
6643
|
+
safeToRetry: false
|
|
6644
|
+
});
|
|
6645
|
+
}
|
|
6613
6646
|
const message = protocolErrorMessage(status, value);
|
|
6614
6647
|
throw classifyServerError(message, value, void 0, status);
|
|
6615
6648
|
}
|
|
@@ -6649,7 +6682,7 @@ function unwrapPipelineResponse(value, options = {}, expectedItems) {
|
|
|
6649
6682
|
continue;
|
|
6650
6683
|
}
|
|
6651
6684
|
const error = classifyServerError(
|
|
6652
|
-
protocolErrorMessage(status
|
|
6685
|
+
protocolErrorMessage(pipelineStatusCode(status), payload),
|
|
6653
6686
|
payload,
|
|
6654
6687
|
void 0,
|
|
6655
6688
|
status
|
|
@@ -6658,15 +6691,46 @@ function unwrapPipelineResponse(value, options = {}, expectedItems) {
|
|
|
6658
6691
|
out[index] = error;
|
|
6659
6692
|
continue;
|
|
6660
6693
|
}
|
|
6694
|
+
if (pipelineStatusToken(item[0]) != null) {
|
|
6695
|
+
const unknown = pipelineStatusToken(item[0]) ?? "unknown";
|
|
6696
|
+
const error = new FerricStoreError(`unknown native pipeline status ${JSON.stringify(unknown)}`, {
|
|
6697
|
+
raw: item,
|
|
6698
|
+
retryable: false,
|
|
6699
|
+
safeToRetry: false
|
|
6700
|
+
});
|
|
6701
|
+
if (options.throwOnItemError !== false) throw error;
|
|
6702
|
+
out[index] = error;
|
|
6703
|
+
continue;
|
|
6704
|
+
}
|
|
6661
6705
|
}
|
|
6662
6706
|
out[index] = item;
|
|
6663
6707
|
}
|
|
6664
6708
|
return out;
|
|
6665
6709
|
}
|
|
6666
6710
|
function pipelineStatus(value) {
|
|
6711
|
+
const status = pipelineStatusToken(value);
|
|
6712
|
+
if (status == null) return null;
|
|
6713
|
+
return status === "ok" || status === "error" || status === "auth" || status === "noperm" || status === "busy" || status === "reroute" || status === "bad_request" ? status : null;
|
|
6714
|
+
}
|
|
6715
|
+
function pipelineStatusToken(value) {
|
|
6667
6716
|
if (typeof value !== "string" && !import_node_buffer26.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return null;
|
|
6668
|
-
|
|
6669
|
-
|
|
6717
|
+
return asText(value).toLowerCase();
|
|
6718
|
+
}
|
|
6719
|
+
function pipelineStatusCode(status) {
|
|
6720
|
+
switch (status) {
|
|
6721
|
+
case "error":
|
|
6722
|
+
return 1;
|
|
6723
|
+
case "auth":
|
|
6724
|
+
return 2;
|
|
6725
|
+
case "noperm":
|
|
6726
|
+
return 3;
|
|
6727
|
+
case "busy":
|
|
6728
|
+
return 4;
|
|
6729
|
+
case "reroute":
|
|
6730
|
+
return 5;
|
|
6731
|
+
case "bad_request":
|
|
6732
|
+
return 6;
|
|
6733
|
+
}
|
|
6670
6734
|
}
|
|
6671
6735
|
function decodeResponseValue(opcode, body, hints, allowCompact, customPayload) {
|
|
6672
6736
|
if (customPayload && allowCompact) {
|
|
@@ -8326,6 +8390,22 @@ function plainRecord(value) {
|
|
|
8326
8390
|
return value;
|
|
8327
8391
|
}
|
|
8328
8392
|
|
|
8393
|
+
// src/native-command-preparation.ts
|
|
8394
|
+
function prepareNativeCommand(args, maxFrameBytes) {
|
|
8395
|
+
try {
|
|
8396
|
+
return buildProtocolCommand(args, maxFrameBytes);
|
|
8397
|
+
} catch (error) {
|
|
8398
|
+
throw requestNotSentError(error);
|
|
8399
|
+
}
|
|
8400
|
+
}
|
|
8401
|
+
function encodeNativeRequest(command, requestId, maxFrameBytes) {
|
|
8402
|
+
try {
|
|
8403
|
+
return encodeRequest(command, requestId, maxFrameBytes);
|
|
8404
|
+
} catch (error) {
|
|
8405
|
+
throw requestNotSentError(error);
|
|
8406
|
+
}
|
|
8407
|
+
}
|
|
8408
|
+
|
|
8329
8409
|
// src/native-adapter.ts
|
|
8330
8410
|
var NativeAdapter = class _NativeAdapter {
|
|
8331
8411
|
socket;
|
|
@@ -8433,15 +8513,13 @@ var NativeAdapter = class _NativeAdapter {
|
|
|
8433
8513
|
return await this.executeCommandArgs(args);
|
|
8434
8514
|
}
|
|
8435
8515
|
async executeCommandArgs(args) {
|
|
8436
|
-
const command =
|
|
8516
|
+
const command = prepareNativeCommand(args, this.capabilities.requestFrameBytes);
|
|
8437
8517
|
return await this.request(command);
|
|
8438
8518
|
}
|
|
8439
8519
|
/** @internal Execute raw command arguments on a topology-selected lane. */
|
|
8440
8520
|
async executeCommandOnLane(args, laneId) {
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
laneId
|
|
8444
|
-
);
|
|
8521
|
+
const command = prepareNativeCommand(args, this.capabilities.requestFrameBytes);
|
|
8522
|
+
return await this.executeProtocolCommand(command, laneId);
|
|
8445
8523
|
}
|
|
8446
8524
|
async executeProtocolCommand(command, laneId) {
|
|
8447
8525
|
return await this.request(laneId == null ? command : { ...command, laneId });
|
|
@@ -8535,14 +8613,14 @@ var NativeAdapter = class _NativeAdapter {
|
|
|
8535
8613
|
let frame;
|
|
8536
8614
|
try {
|
|
8537
8615
|
requestId = this.requestScheduler.nextRequestId();
|
|
8538
|
-
frame =
|
|
8616
|
+
frame = encodeNativeRequest(
|
|
8539
8617
|
withFlowQueryDeadline(command, timeoutMs),
|
|
8540
8618
|
requestId,
|
|
8541
8619
|
this.capabilities.requestFrameBytes
|
|
8542
8620
|
);
|
|
8543
8621
|
} catch (error) {
|
|
8544
8622
|
if (hasFlowControlCredit) this.flowControl.release(laneId);
|
|
8545
|
-
return Promise.reject(error instanceof Error ? error :
|
|
8623
|
+
return Promise.reject(error instanceof Error ? error : requestNotSentError(error));
|
|
8546
8624
|
}
|
|
8547
8625
|
return new Promise((resolve, reject) => {
|
|
8548
8626
|
const timer = timeoutMs == null ? void 0 : setLongTimeout(() => {
|
|
@@ -9117,7 +9195,9 @@ var HTTPTransport = class {
|
|
|
9117
9195
|
#requests = /* @__PURE__ */ new Set();
|
|
9118
9196
|
#closed = false;
|
|
9119
9197
|
async post(body, timeoutMs) {
|
|
9120
|
-
if (this.#closed)
|
|
9198
|
+
if (this.#closed) {
|
|
9199
|
+
throw new HTTPTransportError("HTTP transport is closed", { requestDisposition: "unsent" });
|
|
9200
|
+
}
|
|
9121
9201
|
const controller = new AbortController();
|
|
9122
9202
|
this.#requests.add(controller);
|
|
9123
9203
|
const timer = timeoutMs == null ? void 0 : setLongTimeout(() => controller.abort(requestTimeoutReason), timeoutMs);
|
|
@@ -9134,9 +9214,22 @@ var HTTPTransport = class {
|
|
|
9134
9214
|
raw: { retryable: true, safe_to_retry: false }
|
|
9135
9215
|
});
|
|
9136
9216
|
}
|
|
9137
|
-
if (error instanceof
|
|
9217
|
+
if (error instanceof RequestTimeoutError) throw error;
|
|
9218
|
+
if (error instanceof HTTPTransportError) {
|
|
9219
|
+
if (error.requestDisposition != null) throw error;
|
|
9220
|
+
throw new HTTPTransportError(error.message, {
|
|
9221
|
+
cause: error.cause ?? error,
|
|
9222
|
+
raw: error.raw,
|
|
9223
|
+
requestDisposition: "possibly_sent",
|
|
9224
|
+
retryAfterMs: error.retryAfterMs,
|
|
9225
|
+
retryable: error.retryable,
|
|
9226
|
+
safeToRetry: false,
|
|
9227
|
+
statusCode: error.statusCode
|
|
9228
|
+
});
|
|
9229
|
+
}
|
|
9138
9230
|
throw new HTTPTransportError("HTTP command request failed", {
|
|
9139
9231
|
cause: error,
|
|
9232
|
+
requestDisposition: "possibly_sent",
|
|
9140
9233
|
retryable: true,
|
|
9141
9234
|
safeToRetry: false
|
|
9142
9235
|
});
|
|
@@ -9148,7 +9241,9 @@ var HTTPTransport = class {
|
|
|
9148
9241
|
async close() {
|
|
9149
9242
|
if (this.#closed) return;
|
|
9150
9243
|
this.#closed = true;
|
|
9151
|
-
const error = new HTTPTransportError("HTTP transport is closed"
|
|
9244
|
+
const error = new HTTPTransportError("HTTP transport is closed", {
|
|
9245
|
+
requestDisposition: "possibly_sent"
|
|
9246
|
+
});
|
|
9152
9247
|
for (const controller of this.#requests) controller.abort(error);
|
|
9153
9248
|
this.#httpAgent.destroy();
|
|
9154
9249
|
this.#httpsAgent.destroy();
|
|
@@ -9391,16 +9486,22 @@ var HTTPAdapter = class _HTTPAdapter {
|
|
|
9391
9486
|
await this.#transport.close();
|
|
9392
9487
|
}
|
|
9393
9488
|
async executeBatch(commands) {
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9489
|
+
let body;
|
|
9490
|
+
let serverBlockMs;
|
|
9491
|
+
try {
|
|
9492
|
+
if (commands.length > this.#config.maxBatchItems) {
|
|
9493
|
+
throw new HTTPTransportError("HTTP command batch exceeds maxBatchItems");
|
|
9494
|
+
}
|
|
9495
|
+
for (const command of commands) assertHTTPCommandSupported(command[0]);
|
|
9496
|
+
const prepared = commands.map((command) => prepareHTTPCommand(command, this.#config.maxRequestBytes));
|
|
9497
|
+
body = encodeHTTPCommands(prepared.map((command) => command.encoded), this.#config.maxRequestBytes);
|
|
9498
|
+
if (body.byteLength > this.#config.maxRequestBytes) {
|
|
9499
|
+
throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
|
|
9500
|
+
}
|
|
9501
|
+
serverBlockMs = combinedServerBlockMs(prepared.map((command) => command.serverBlockMs));
|
|
9502
|
+
} catch (error) {
|
|
9503
|
+
throw unsentHTTPError(error);
|
|
9402
9504
|
}
|
|
9403
|
-
const serverBlockMs = combinedServerBlockMs(prepared.map((command) => command.serverBlockMs));
|
|
9404
9505
|
const response = await this.#transport.post(
|
|
9405
9506
|
body,
|
|
9406
9507
|
serverResponseTimeoutMs(this.#config.timeoutMs, serverBlockMs)
|
|
@@ -9457,16 +9558,32 @@ function commandError(value) {
|
|
|
9457
9558
|
}
|
|
9458
9559
|
function topLevelError(status, envelope, retryAfter) {
|
|
9459
9560
|
const details = isRecord2(envelope.error) ? envelope.error : {};
|
|
9561
|
+
const code = typeof details.code === "string" ? details.code.toLowerCase() : void 0;
|
|
9460
9562
|
const message = typeof details.message === "string" ? details.message : `HTTP command request failed with status ${status}`;
|
|
9461
9563
|
const retryAfterMs2 = retryAfterMilliseconds(retryAfter);
|
|
9564
|
+
const ambiguousTimeout = status === 408 || code === "request_timeout";
|
|
9565
|
+
const safeToRetry = !ambiguousTimeout && (details.safe_to_retry === true || definitelyRejectedHTTPStatus(status));
|
|
9462
9566
|
return new HTTPTransportError(message, {
|
|
9463
9567
|
raw: details,
|
|
9464
9568
|
retryable: status === 408 || status === 425 || status === 429 || status >= 500,
|
|
9465
9569
|
retryAfterMs: retryAfterMs2,
|
|
9466
|
-
|
|
9570
|
+
requestDisposition: "possibly_sent",
|
|
9571
|
+
safeToRetry,
|
|
9467
9572
|
statusCode: status
|
|
9468
9573
|
});
|
|
9469
9574
|
}
|
|
9575
|
+
function definitelyRejectedHTTPStatus(status) {
|
|
9576
|
+
return status === 400 || status === 401 || status === 403 || status === 404 || status === 405 || status === 406 || status === 411 || status === 413 || status === 414 || status === 415 || status === 422 || status === 426 || status === 431;
|
|
9577
|
+
}
|
|
9578
|
+
function unsentHTTPError(error) {
|
|
9579
|
+
if (error instanceof HTTPTransportError && error.requestDisposition === "unsent") return error;
|
|
9580
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
9581
|
+
return new HTTPTransportError(message, {
|
|
9582
|
+
cause: error,
|
|
9583
|
+
raw: error instanceof FerricStoreError ? error.raw ?? error : error,
|
|
9584
|
+
requestDisposition: "unsent"
|
|
9585
|
+
});
|
|
9586
|
+
}
|
|
9470
9587
|
function retryAfterMilliseconds(value) {
|
|
9471
9588
|
if (value == null) return void 0;
|
|
9472
9589
|
if (/^\d+$/u.test(value)) {
|
|
@@ -9559,9 +9676,9 @@ var ReconnectingExecutor = class {
|
|
|
9559
9676
|
const snapshot = snapshotPipelineCommands(commands);
|
|
9560
9677
|
const snapshotOptions = snapshotPipelineOptions(options) ?? {};
|
|
9561
9678
|
for (const command of snapshot) assertCommandHasStableConnectionState(command);
|
|
9562
|
-
if (this.closed) throw new
|
|
9679
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9563
9680
|
const initialExecutor = await this.executorPromise;
|
|
9564
|
-
if (this.closed) throw new
|
|
9681
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9565
9682
|
if (initialExecutor.executePipeline == null) {
|
|
9566
9683
|
return await executeCommandArraysIndividually(
|
|
9567
9684
|
async (command) => await this.executeCommandArgs(command),
|
|
@@ -9582,9 +9699,9 @@ var ReconnectingExecutor = class {
|
|
|
9582
9699
|
const snapshot = snapshotPipelineCommands(commands);
|
|
9583
9700
|
const snapshotOptions = snapshotPipelineOptions(options) ?? {};
|
|
9584
9701
|
for (const command of snapshot) assertCommandHasStableConnectionState(command);
|
|
9585
|
-
if (this.closed) throw new
|
|
9702
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9586
9703
|
const initialExecutor = await this.executorPromise;
|
|
9587
|
-
if (this.closed) throw new
|
|
9704
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9588
9705
|
if (initialExecutor.executeFusedPipeline == null) return void 0;
|
|
9589
9706
|
try {
|
|
9590
9707
|
return await initialExecutor.executeFusedPipeline(snapshot, snapshotOptions);
|
|
@@ -9617,7 +9734,7 @@ var ReconnectingExecutor = class {
|
|
|
9617
9734
|
return;
|
|
9618
9735
|
}
|
|
9619
9736
|
this.closed = true;
|
|
9620
|
-
this.retryAbortController.abort(new
|
|
9737
|
+
this.retryAbortController.abort(new RequestNotSentError("FerricStore client is closed"));
|
|
9621
9738
|
const executorPromise = this.executorPromise;
|
|
9622
9739
|
const reconnectPromise = this.reconnectPromise;
|
|
9623
9740
|
this.closePromise = (async () => {
|
|
@@ -9639,7 +9756,7 @@ var ReconnectingExecutor = class {
|
|
|
9639
9756
|
let executor = await this.executorPromise;
|
|
9640
9757
|
let retries = 0;
|
|
9641
9758
|
for (; ; ) {
|
|
9642
|
-
if (this.closed) throw new
|
|
9759
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9643
9760
|
try {
|
|
9644
9761
|
return await operation(executor);
|
|
9645
9762
|
} catch (error) {
|
|
@@ -9668,17 +9785,17 @@ var ReconnectingExecutor = class {
|
|
|
9668
9785
|
try {
|
|
9669
9786
|
await sleep(Math.min(this.maxDelayMs, base + jitter), this.retryAbortController.signal);
|
|
9670
9787
|
} catch (error) {
|
|
9671
|
-
if (this.closed) throw new
|
|
9788
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed", { cause: error });
|
|
9672
9789
|
throw error;
|
|
9673
9790
|
}
|
|
9674
9791
|
}
|
|
9675
9792
|
async reconnect(staleExecutor) {
|
|
9676
|
-
if (this.closed) throw new
|
|
9793
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9677
9794
|
const competingReconnect = this.reconnectPromise;
|
|
9678
9795
|
if (competingReconnect != null) return await competingReconnect;
|
|
9679
9796
|
const observedExecutorPromise = this.executorPromise;
|
|
9680
9797
|
const currentExecutor = await observedExecutorPromise.catch(() => void 0);
|
|
9681
|
-
if (this.closed) throw new
|
|
9798
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9682
9799
|
if (this.reconnectPromise != null) return await this.reconnectPromise;
|
|
9683
9800
|
if (this.executorPromise !== observedExecutorPromise) return await this.executorPromise;
|
|
9684
9801
|
if (currentExecutor != null && currentExecutor !== staleExecutor) return currentExecutor;
|
|
@@ -9687,7 +9804,7 @@ var ReconnectingExecutor = class {
|
|
|
9687
9804
|
const nextExecutor = await this.createExecutor(this.retryAbortController.signal);
|
|
9688
9805
|
if (this.closed) {
|
|
9689
9806
|
await Promise.resolve(nextExecutor.close?.()).catch(() => void 0);
|
|
9690
|
-
throw new
|
|
9807
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
9691
9808
|
}
|
|
9692
9809
|
this.executorPromise = Promise.resolve(nextExecutor);
|
|
9693
9810
|
return nextExecutor;
|
|
@@ -11097,7 +11214,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
11097
11214
|
);
|
|
11098
11215
|
}
|
|
11099
11216
|
assertOpen() {
|
|
11100
|
-
if (this.closed) throw new
|
|
11217
|
+
if (this.closed) throw new RequestNotSentError("FerricStore topology adapter pool is closed");
|
|
11101
11218
|
}
|
|
11102
11219
|
};
|
|
11103
11220
|
|
|
@@ -12223,7 +12340,7 @@ var AutoBatchExecutor = class {
|
|
|
12223
12340
|
}
|
|
12224
12341
|
async executeCommandArgs(args) {
|
|
12225
12342
|
if (this.closed) {
|
|
12226
|
-
throw new
|
|
12343
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12227
12344
|
}
|
|
12228
12345
|
const command = snapshotCommandArguments(args);
|
|
12229
12346
|
if (this.executor.executePipeline == null) {
|
|
@@ -12243,7 +12360,7 @@ var AutoBatchExecutor = class {
|
|
|
12243
12360
|
if (orderingBarrier != null) {
|
|
12244
12361
|
await orderingBarrier;
|
|
12245
12362
|
if (this.closed) {
|
|
12246
|
-
throw new
|
|
12363
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12247
12364
|
}
|
|
12248
12365
|
}
|
|
12249
12366
|
return await new Promise((resolve, reject) => {
|
|
@@ -12257,7 +12374,7 @@ var AutoBatchExecutor = class {
|
|
|
12257
12374
|
}
|
|
12258
12375
|
async executePipeline(commands, options) {
|
|
12259
12376
|
if (this.closed) {
|
|
12260
|
-
throw new
|
|
12377
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12261
12378
|
}
|
|
12262
12379
|
const snapshot = snapshotPipelineCommands(commands);
|
|
12263
12380
|
const snapshotOptions = snapshotPipelineOptions(options);
|
|
@@ -12274,7 +12391,7 @@ var AutoBatchExecutor = class {
|
|
|
12274
12391
|
}
|
|
12275
12392
|
async executeFusedPipeline(commands, options) {
|
|
12276
12393
|
if (this.closed) {
|
|
12277
|
-
throw new
|
|
12394
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12278
12395
|
}
|
|
12279
12396
|
if (this.executor.executeFusedPipeline == null) return void 0;
|
|
12280
12397
|
const snapshot = snapshotPipelineCommands(commands);
|
|
@@ -12285,7 +12402,7 @@ var AutoBatchExecutor = class {
|
|
|
12285
12402
|
}
|
|
12286
12403
|
async refreshTopology() {
|
|
12287
12404
|
if (this.closed) {
|
|
12288
|
-
throw new
|
|
12405
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12289
12406
|
}
|
|
12290
12407
|
const refreshTopology = this.executor.refreshTopology?.bind(this.executor);
|
|
12291
12408
|
if (refreshTopology == null) {
|
|
@@ -12295,7 +12412,7 @@ var AutoBatchExecutor = class {
|
|
|
12295
12412
|
}
|
|
12296
12413
|
async route(key) {
|
|
12297
12414
|
if (this.closed) {
|
|
12298
|
-
throw new
|
|
12415
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12299
12416
|
}
|
|
12300
12417
|
const route = this.executor.route?.bind(this.executor);
|
|
12301
12418
|
if (route == null) {
|
|
@@ -12315,7 +12432,7 @@ var AutoBatchExecutor = class {
|
|
|
12315
12432
|
this.timer.cancel();
|
|
12316
12433
|
this.timer = void 0;
|
|
12317
12434
|
}
|
|
12318
|
-
this.failPending(new
|
|
12435
|
+
this.failPending(new RequestNotSentError("FerricStore client closed before auto-batch flush"));
|
|
12319
12436
|
await this.orderingBarrier;
|
|
12320
12437
|
await this.waitForInFlightBatches();
|
|
12321
12438
|
await Promise.allSettled([...this.inFlightHelpers]);
|
|
@@ -12325,7 +12442,7 @@ var AutoBatchExecutor = class {
|
|
|
12325
12442
|
}
|
|
12326
12443
|
async executeAfterPendingBatches(operation) {
|
|
12327
12444
|
if (this.closed) {
|
|
12328
|
-
throw new
|
|
12445
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12329
12446
|
}
|
|
12330
12447
|
const previousBarrier = this.orderingBarrier;
|
|
12331
12448
|
let releaseBarrier;
|
|
@@ -12346,7 +12463,7 @@ var AutoBatchExecutor = class {
|
|
|
12346
12463
|
}
|
|
12347
12464
|
executeHelper(operation) {
|
|
12348
12465
|
if (this.closed) {
|
|
12349
|
-
return Promise.reject(new
|
|
12466
|
+
return Promise.reject(new RequestNotSentError("FerricStore client is closed"));
|
|
12350
12467
|
}
|
|
12351
12468
|
const task = Promise.resolve().then(operation);
|
|
12352
12469
|
this.inFlightHelpers.add(task);
|
|
@@ -12368,7 +12485,7 @@ var AutoBatchExecutor = class {
|
|
|
12368
12485
|
await previousBarrier;
|
|
12369
12486
|
await this.flushNow();
|
|
12370
12487
|
if (this.closed) {
|
|
12371
|
-
throw new
|
|
12488
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12372
12489
|
}
|
|
12373
12490
|
dispatched = operation();
|
|
12374
12491
|
} finally {
|
|
@@ -14707,7 +14824,7 @@ var FerricStoreClientBase = class {
|
|
|
14707
14824
|
return validatePipelineResponse(results, snapshot.length);
|
|
14708
14825
|
}
|
|
14709
14826
|
async close() {
|
|
14710
|
-
this.closeAbortController.abort(new
|
|
14827
|
+
this.closeAbortController.abort(new RequestNotSentError("FerricStore client is closed"));
|
|
14711
14828
|
this.closePromise ??= (async () => await this.executor.close?.())();
|
|
14712
14829
|
await this.closePromise;
|
|
14713
14830
|
}
|
|
@@ -17783,7 +17900,7 @@ async function executeProducerWriteWithBackpressure(execute, policy, signal) {
|
|
|
17783
17900
|
function throwIfClosed(signal) {
|
|
17784
17901
|
if (!signal.aborted) return;
|
|
17785
17902
|
if (signal.reason instanceof Error) throw signal.reason;
|
|
17786
|
-
throw new
|
|
17903
|
+
throw new RequestNotSentError("FerricStore client is closed", { raw: signal.reason });
|
|
17787
17904
|
}
|
|
17788
17905
|
|
|
17789
17906
|
// src/flow-policy.ts
|
|
@@ -19100,6 +19217,8 @@ async function runDurableStep(client, job, options, hooks = {}) {
|
|
|
19100
19217
|
const run2 = options.run;
|
|
19101
19218
|
const continuation = snapshotAdvanceOptions(options);
|
|
19102
19219
|
assertNonEmptyString(name, "name");
|
|
19220
|
+
if (name.trim().length === 0) throw new TypeError("name must not be blank");
|
|
19221
|
+
if (!name.isWellFormed()) throw new TypeError("name must contain valid Unicode");
|
|
19103
19222
|
assertNonEmptyString(continuation.toState, "toState");
|
|
19104
19223
|
if (typeof run2 !== "function") throw new TypeError("run must be a function");
|
|
19105
19224
|
const resultName = durableStepValueName(name);
|
|
@@ -19127,7 +19246,7 @@ async function runDurableStep(client, job, options, hooks = {}) {
|
|
|
19127
19246
|
throw new FerricStoreError("committed durable step result is missing");
|
|
19128
19247
|
}
|
|
19129
19248
|
const replayedJob = claimedItemFromRecord(validated);
|
|
19130
|
-
hooks.replayed
|
|
19249
|
+
notifyWithoutReplacingOutcome(hooks.replayed, replayedJob);
|
|
19131
19250
|
return { job: replayedJob, result: entry.value };
|
|
19132
19251
|
}
|
|
19133
19252
|
const result = normalizeStepResult(client, await run2());
|
|
@@ -19140,12 +19259,18 @@ async function runDurableStep(client, job, options, hooks = {}) {
|
|
|
19140
19259
|
values: { ...continuation.values, [resultName]: result }
|
|
19141
19260
|
});
|
|
19142
19261
|
} catch (error) {
|
|
19143
|
-
hooks.commitFailed
|
|
19262
|
+
notifyWithoutReplacingOutcome(hooks.commitFailed, error);
|
|
19144
19263
|
throw error;
|
|
19145
19264
|
}
|
|
19146
|
-
hooks.committed
|
|
19265
|
+
notifyWithoutReplacingOutcome(hooks.committed, refreshed);
|
|
19147
19266
|
return { job: refreshed, result };
|
|
19148
19267
|
}
|
|
19268
|
+
function notifyWithoutReplacingOutcome(callback, value) {
|
|
19269
|
+
try {
|
|
19270
|
+
callback?.(value);
|
|
19271
|
+
} catch {
|
|
19272
|
+
}
|
|
19273
|
+
}
|
|
19149
19274
|
function normalizeStepResult(client, value) {
|
|
19150
19275
|
return client.codec.decode(client.codec.encode(value));
|
|
19151
19276
|
}
|
|
@@ -19266,6 +19391,35 @@ function claimedItemFromRecord(record) {
|
|
|
19266
19391
|
};
|
|
19267
19392
|
}
|
|
19268
19393
|
|
|
19394
|
+
// src/client-step-continue.ts
|
|
19395
|
+
function stepContinueArguments(id, options, codec) {
|
|
19396
|
+
try {
|
|
19397
|
+
const args = [
|
|
19398
|
+
"FLOW.STEP_CONTINUE",
|
|
19399
|
+
id,
|
|
19400
|
+
options.leaseToken,
|
|
19401
|
+
options.fromState,
|
|
19402
|
+
options.toState,
|
|
19403
|
+
"FENCING",
|
|
19404
|
+
options.fencingToken,
|
|
19405
|
+
"LEASE_MS",
|
|
19406
|
+
options.leaseMs ?? 3e4,
|
|
19407
|
+
"NOW",
|
|
19408
|
+
options.nowMs ?? nowMs()
|
|
19409
|
+
];
|
|
19410
|
+
append(args, "PARTITION", options.partitionKey);
|
|
19411
|
+
append(args, "WORKER", options.worker);
|
|
19412
|
+
appendEncoded(args, "PAYLOAD", codec, options.payload);
|
|
19413
|
+
if (options.returnJob === true) args.push("RETURN", "JOBS_COMPACT");
|
|
19414
|
+
appendStateMeta(args, options.stateMeta);
|
|
19415
|
+
appendNamedValues(args, codec, options);
|
|
19416
|
+
appendAttributeMutations(args, options);
|
|
19417
|
+
return args;
|
|
19418
|
+
} catch (error) {
|
|
19419
|
+
throw requestNotSentError(error);
|
|
19420
|
+
}
|
|
19421
|
+
}
|
|
19422
|
+
|
|
19269
19423
|
// src/client.ts
|
|
19270
19424
|
var FerricStoreClient = class _FerricStoreClient extends FerricStoreProducerClient {
|
|
19271
19425
|
static async fromUrl(url, options = {}) {
|
|
@@ -19388,26 +19542,7 @@ var FerricStoreClient = class _FerricStoreClient extends FerricStoreProducerClie
|
|
|
19388
19542
|
const partitionKey = options.partitionKey;
|
|
19389
19543
|
const returnJob = options.returnJob === true;
|
|
19390
19544
|
const type = options.type;
|
|
19391
|
-
const args =
|
|
19392
|
-
"FLOW.STEP_CONTINUE",
|
|
19393
|
-
id,
|
|
19394
|
-
options.leaseToken,
|
|
19395
|
-
options.fromState,
|
|
19396
|
-
options.toState,
|
|
19397
|
-
"FENCING",
|
|
19398
|
-
options.fencingToken,
|
|
19399
|
-
"LEASE_MS",
|
|
19400
|
-
options.leaseMs ?? 3e4,
|
|
19401
|
-
"NOW",
|
|
19402
|
-
options.nowMs ?? nowMs()
|
|
19403
|
-
];
|
|
19404
|
-
append(args, "PARTITION", partitionKey);
|
|
19405
|
-
append(args, "WORKER", options.worker);
|
|
19406
|
-
appendEncoded(args, "PAYLOAD", this.codec, options.payload);
|
|
19407
|
-
if (returnJob) args.push("RETURN", "JOBS_COMPACT");
|
|
19408
|
-
appendStateMeta(args, options.stateMeta);
|
|
19409
|
-
appendNamedValues(args, this.codec, options);
|
|
19410
|
-
appendAttributeMutations(args, options);
|
|
19545
|
+
const args = stepContinueArguments(id, options, this.codec);
|
|
19411
19546
|
const response = await this.commandArgs(args);
|
|
19412
19547
|
return returnJob ? claimedItemFromResp(response, this.codec, { type }) : await this.recordOrGet(response, id, partitionKey);
|
|
19413
19548
|
}
|
|
@@ -21046,15 +21181,6 @@ function createWorkflowStateRegistration(name, handler, options, defaultValueMax
|
|
|
21046
21181
|
// src/workflow-context.ts
|
|
21047
21182
|
var MISSING_VALUE = /* @__PURE__ */ Symbol("ferricstore.missingValue");
|
|
21048
21183
|
var WorkflowContext = class {
|
|
21049
|
-
constructor(workflow, job, stateName, leaseJob = job, mutationCoordinator) {
|
|
21050
|
-
this.mutationCoordinator = mutationCoordinator;
|
|
21051
|
-
this.workflow = workflow;
|
|
21052
|
-
this.job = job;
|
|
21053
|
-
this.leaseJob = leaseJob;
|
|
21054
|
-
this.currentStateName = stateName;
|
|
21055
|
-
this.flow = new WorkflowFlowCommands(this);
|
|
21056
|
-
}
|
|
21057
|
-
mutationCoordinator;
|
|
21058
21184
|
workflow;
|
|
21059
21185
|
job;
|
|
21060
21186
|
flow;
|
|
@@ -21063,7 +21189,20 @@ var WorkflowContext = class {
|
|
|
21063
21189
|
leaseJob;
|
|
21064
21190
|
mutationFailure;
|
|
21065
21191
|
mutationPhase = "idle";
|
|
21192
|
+
mutationCoordinator;
|
|
21066
21193
|
valueCache = /* @__PURE__ */ new Map();
|
|
21194
|
+
constructor(workflow, job, stateName) {
|
|
21195
|
+
this.workflow = workflow;
|
|
21196
|
+
this.job = job;
|
|
21197
|
+
this.leaseJob = job;
|
|
21198
|
+
this.currentStateName = stateName;
|
|
21199
|
+
this.flow = new WorkflowFlowCommands(this);
|
|
21200
|
+
}
|
|
21201
|
+
/** @internal */
|
|
21202
|
+
configureWorkerMutation(leaseJob, coordinator) {
|
|
21203
|
+
this.leaseJob = leaseJob;
|
|
21204
|
+
this.mutationCoordinator = coordinator;
|
|
21205
|
+
}
|
|
21067
21206
|
get client() {
|
|
21068
21207
|
return this.workflow.client;
|
|
21069
21208
|
}
|
|
@@ -21487,10 +21626,18 @@ async function applyFail(client, ctx, outcome, returnRecord) {
|
|
|
21487
21626
|
});
|
|
21488
21627
|
}
|
|
21489
21628
|
|
|
21629
|
+
// src/workflow-worker-context.ts
|
|
21630
|
+
var WorkerWorkflowContext = class extends WorkflowContext {
|
|
21631
|
+
constructor(workflow, job, stateName, leaseJob, mutationCoordinator) {
|
|
21632
|
+
super(workflow, job, stateName);
|
|
21633
|
+
this.configureWorkerMutation(leaseJob, mutationCoordinator);
|
|
21634
|
+
}
|
|
21635
|
+
};
|
|
21636
|
+
|
|
21490
21637
|
// src/workflow-job-execution.ts
|
|
21491
21638
|
async function executeWorkflowJob(workflow, workerOptions, job, registration, guard) {
|
|
21492
21639
|
guard.assertActive();
|
|
21493
|
-
const ctx = new
|
|
21640
|
+
const ctx = new WorkerWorkflowContext(workflow, job, registration.name, guard.job, {
|
|
21494
21641
|
pause: async () => await guard.pauseForLeaseMutation(),
|
|
21495
21642
|
resume: (refreshed) => guard.resumeWith(refreshed)
|
|
21496
21643
|
});
|
|
@@ -21835,7 +21982,7 @@ function throwError(value) {
|
|
|
21835
21982
|
}
|
|
21836
21983
|
|
|
21837
21984
|
// src/version.ts
|
|
21838
|
-
var FERRICSTORE_SDK_VERSION = "0.
|
|
21985
|
+
var FERRICSTORE_SDK_VERSION = "0.13.2";
|
|
21839
21986
|
var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
|
|
21840
21987
|
var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
21841
21988
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -21879,6 +22026,7 @@ var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
|
21879
22026
|
QueueWorker,
|
|
21880
22027
|
RawCodec,
|
|
21881
22028
|
ReconnectingExecutor,
|
|
22029
|
+
RequestNotSentError,
|
|
21882
22030
|
RequestTimeoutError,
|
|
21883
22031
|
RerouteError,
|
|
21884
22032
|
RoutingTopology,
|