@ferricstore/ferricstore 0.13.0 → 0.13.1
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 -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 +30 -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 +12 -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 +12 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30,9 +30,16 @@ var FerricStoreError = class extends Error {
|
|
|
30
30
|
};
|
|
31
31
|
var HTTPTransportError = class extends FerricStoreError {
|
|
32
32
|
code = "http_transport";
|
|
33
|
+
requestDisposition;
|
|
33
34
|
statusCode;
|
|
34
35
|
constructor(message, options = {}) {
|
|
35
|
-
|
|
36
|
+
const disposition = options.requestDisposition;
|
|
37
|
+
super(message, {
|
|
38
|
+
...options,
|
|
39
|
+
retryable: options.retryable ?? (disposition === "unsent" ? false : void 0),
|
|
40
|
+
safeToRetry: options.safeToRetry ?? (disposition === "unsent" ? true : disposition === "possibly_sent" ? false : void 0)
|
|
41
|
+
});
|
|
42
|
+
this.requestDisposition = disposition;
|
|
36
43
|
this.statusCode = options.statusCode;
|
|
37
44
|
}
|
|
38
45
|
};
|
|
@@ -57,6 +64,20 @@ var RequestTimeoutError = class extends FerricStoreError {
|
|
|
57
64
|
this.timeoutMs = timeoutMs;
|
|
58
65
|
}
|
|
59
66
|
};
|
|
67
|
+
var RequestNotSentError = class extends FerricStoreError {
|
|
68
|
+
code = "request_not_sent";
|
|
69
|
+
requestDisposition = "unsent";
|
|
70
|
+
constructor(message, options = {}) {
|
|
71
|
+
super(message, { ...options, retryable: false, safeToRetry: true });
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
function requestNotSentError(error, message) {
|
|
75
|
+
if (error instanceof RequestNotSentError) return error;
|
|
76
|
+
return new RequestNotSentError(
|
|
77
|
+
message ?? (error instanceof Error ? error.message : String(error)),
|
|
78
|
+
{ cause: error, raw: error }
|
|
79
|
+
);
|
|
80
|
+
}
|
|
60
81
|
var FlowNotFoundError = class extends FerricStoreError {
|
|
61
82
|
code = "flow_not_found";
|
|
62
83
|
};
|
|
@@ -6315,7 +6336,10 @@ function decodeCompactPipeline(data, budget, claimModes) {
|
|
|
6315
6336
|
);
|
|
6316
6337
|
offset = read.offset;
|
|
6317
6338
|
} else {
|
|
6318
|
-
throw new FerricStoreError(
|
|
6339
|
+
throw new FerricStoreError(`unknown compact pipeline status ${status}`, {
|
|
6340
|
+
retryable: false,
|
|
6341
|
+
safeToRetry: false
|
|
6342
|
+
});
|
|
6319
6343
|
}
|
|
6320
6344
|
}
|
|
6321
6345
|
if (offset !== data.byteLength) throw new FerricStoreError("trailing compact pipeline bytes");
|
|
@@ -6485,6 +6509,7 @@ var COUNTED_COMPACT_TAGS = /* @__PURE__ */ new Set([
|
|
|
6485
6509
|
]);
|
|
6486
6510
|
|
|
6487
6511
|
// src/protocol-response.ts
|
|
6512
|
+
var KNOWN_NATIVE_RESPONSE_STATUSES = /* @__PURE__ */ new Set([0, 1, 2, 3, 4, 5, 6]);
|
|
6488
6513
|
function decodeResponse(frame, expectedOpcode, hints = {}) {
|
|
6489
6514
|
if (frame.opcode !== expectedOpcode) {
|
|
6490
6515
|
throw new FerricStoreError(
|
|
@@ -6509,6 +6534,13 @@ function decodeResponse(frame, expectedOpcode, hints = {}) {
|
|
|
6509
6534
|
customPayload
|
|
6510
6535
|
);
|
|
6511
6536
|
if (status === STATUS_OK) return value;
|
|
6537
|
+
if (!KNOWN_NATIVE_RESPONSE_STATUSES.has(status)) {
|
|
6538
|
+
throw new FerricStoreError(`unknown native response status ${status}`, {
|
|
6539
|
+
raw: value,
|
|
6540
|
+
retryable: false,
|
|
6541
|
+
safeToRetry: false
|
|
6542
|
+
});
|
|
6543
|
+
}
|
|
6512
6544
|
const message = protocolErrorMessage(status, value);
|
|
6513
6545
|
throw classifyServerError(message, value, void 0, status);
|
|
6514
6546
|
}
|
|
@@ -6548,7 +6580,7 @@ function unwrapPipelineResponse(value, options = {}, expectedItems) {
|
|
|
6548
6580
|
continue;
|
|
6549
6581
|
}
|
|
6550
6582
|
const error = classifyServerError(
|
|
6551
|
-
protocolErrorMessage(status
|
|
6583
|
+
protocolErrorMessage(pipelineStatusCode(status), payload),
|
|
6552
6584
|
payload,
|
|
6553
6585
|
void 0,
|
|
6554
6586
|
status
|
|
@@ -6557,15 +6589,46 @@ function unwrapPipelineResponse(value, options = {}, expectedItems) {
|
|
|
6557
6589
|
out[index] = error;
|
|
6558
6590
|
continue;
|
|
6559
6591
|
}
|
|
6592
|
+
if (pipelineStatusToken(item[0]) != null) {
|
|
6593
|
+
const unknown = pipelineStatusToken(item[0]) ?? "unknown";
|
|
6594
|
+
const error = new FerricStoreError(`unknown native pipeline status ${JSON.stringify(unknown)}`, {
|
|
6595
|
+
raw: item,
|
|
6596
|
+
retryable: false,
|
|
6597
|
+
safeToRetry: false
|
|
6598
|
+
});
|
|
6599
|
+
if (options.throwOnItemError !== false) throw error;
|
|
6600
|
+
out[index] = error;
|
|
6601
|
+
continue;
|
|
6602
|
+
}
|
|
6560
6603
|
}
|
|
6561
6604
|
out[index] = item;
|
|
6562
6605
|
}
|
|
6563
6606
|
return out;
|
|
6564
6607
|
}
|
|
6565
6608
|
function pipelineStatus(value) {
|
|
6609
|
+
const status = pipelineStatusToken(value);
|
|
6610
|
+
if (status == null) return null;
|
|
6611
|
+
return status === "ok" || status === "error" || status === "auth" || status === "noperm" || status === "busy" || status === "reroute" || status === "bad_request" ? status : null;
|
|
6612
|
+
}
|
|
6613
|
+
function pipelineStatusToken(value) {
|
|
6566
6614
|
if (typeof value !== "string" && !Buffer26.isBuffer(value) && !(value instanceof Uint8Array)) return null;
|
|
6567
|
-
|
|
6568
|
-
|
|
6615
|
+
return asText(value).toLowerCase();
|
|
6616
|
+
}
|
|
6617
|
+
function pipelineStatusCode(status) {
|
|
6618
|
+
switch (status) {
|
|
6619
|
+
case "error":
|
|
6620
|
+
return 1;
|
|
6621
|
+
case "auth":
|
|
6622
|
+
return 2;
|
|
6623
|
+
case "noperm":
|
|
6624
|
+
return 3;
|
|
6625
|
+
case "busy":
|
|
6626
|
+
return 4;
|
|
6627
|
+
case "reroute":
|
|
6628
|
+
return 5;
|
|
6629
|
+
case "bad_request":
|
|
6630
|
+
return 6;
|
|
6631
|
+
}
|
|
6569
6632
|
}
|
|
6570
6633
|
function decodeResponseValue(opcode, body, hints, allowCompact, customPayload) {
|
|
6571
6634
|
if (customPayload && allowCompact) {
|
|
@@ -8225,6 +8288,22 @@ function plainRecord(value) {
|
|
|
8225
8288
|
return value;
|
|
8226
8289
|
}
|
|
8227
8290
|
|
|
8291
|
+
// src/native-command-preparation.ts
|
|
8292
|
+
function prepareNativeCommand(args, maxFrameBytes) {
|
|
8293
|
+
try {
|
|
8294
|
+
return buildProtocolCommand(args, maxFrameBytes);
|
|
8295
|
+
} catch (error) {
|
|
8296
|
+
throw requestNotSentError(error);
|
|
8297
|
+
}
|
|
8298
|
+
}
|
|
8299
|
+
function encodeNativeRequest(command, requestId, maxFrameBytes) {
|
|
8300
|
+
try {
|
|
8301
|
+
return encodeRequest(command, requestId, maxFrameBytes);
|
|
8302
|
+
} catch (error) {
|
|
8303
|
+
throw requestNotSentError(error);
|
|
8304
|
+
}
|
|
8305
|
+
}
|
|
8306
|
+
|
|
8228
8307
|
// src/native-adapter.ts
|
|
8229
8308
|
var NativeAdapter = class _NativeAdapter {
|
|
8230
8309
|
socket;
|
|
@@ -8332,15 +8411,13 @@ var NativeAdapter = class _NativeAdapter {
|
|
|
8332
8411
|
return await this.executeCommandArgs(args);
|
|
8333
8412
|
}
|
|
8334
8413
|
async executeCommandArgs(args) {
|
|
8335
|
-
const command =
|
|
8414
|
+
const command = prepareNativeCommand(args, this.capabilities.requestFrameBytes);
|
|
8336
8415
|
return await this.request(command);
|
|
8337
8416
|
}
|
|
8338
8417
|
/** @internal Execute raw command arguments on a topology-selected lane. */
|
|
8339
8418
|
async executeCommandOnLane(args, laneId) {
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
laneId
|
|
8343
|
-
);
|
|
8419
|
+
const command = prepareNativeCommand(args, this.capabilities.requestFrameBytes);
|
|
8420
|
+
return await this.executeProtocolCommand(command, laneId);
|
|
8344
8421
|
}
|
|
8345
8422
|
async executeProtocolCommand(command, laneId) {
|
|
8346
8423
|
return await this.request(laneId == null ? command : { ...command, laneId });
|
|
@@ -8434,14 +8511,14 @@ var NativeAdapter = class _NativeAdapter {
|
|
|
8434
8511
|
let frame;
|
|
8435
8512
|
try {
|
|
8436
8513
|
requestId = this.requestScheduler.nextRequestId();
|
|
8437
|
-
frame =
|
|
8514
|
+
frame = encodeNativeRequest(
|
|
8438
8515
|
withFlowQueryDeadline(command, timeoutMs),
|
|
8439
8516
|
requestId,
|
|
8440
8517
|
this.capabilities.requestFrameBytes
|
|
8441
8518
|
);
|
|
8442
8519
|
} catch (error) {
|
|
8443
8520
|
if (hasFlowControlCredit) this.flowControl.release(laneId);
|
|
8444
|
-
return Promise.reject(error instanceof Error ? error :
|
|
8521
|
+
return Promise.reject(error instanceof Error ? error : requestNotSentError(error));
|
|
8445
8522
|
}
|
|
8446
8523
|
return new Promise((resolve, reject) => {
|
|
8447
8524
|
const timer = timeoutMs == null ? void 0 : setLongTimeout(() => {
|
|
@@ -9016,7 +9093,9 @@ var HTTPTransport = class {
|
|
|
9016
9093
|
#requests = /* @__PURE__ */ new Set();
|
|
9017
9094
|
#closed = false;
|
|
9018
9095
|
async post(body, timeoutMs) {
|
|
9019
|
-
if (this.#closed)
|
|
9096
|
+
if (this.#closed) {
|
|
9097
|
+
throw new HTTPTransportError("HTTP transport is closed", { requestDisposition: "unsent" });
|
|
9098
|
+
}
|
|
9020
9099
|
const controller = new AbortController();
|
|
9021
9100
|
this.#requests.add(controller);
|
|
9022
9101
|
const timer = timeoutMs == null ? void 0 : setLongTimeout(() => controller.abort(requestTimeoutReason), timeoutMs);
|
|
@@ -9033,9 +9112,22 @@ var HTTPTransport = class {
|
|
|
9033
9112
|
raw: { retryable: true, safe_to_retry: false }
|
|
9034
9113
|
});
|
|
9035
9114
|
}
|
|
9036
|
-
if (error instanceof
|
|
9115
|
+
if (error instanceof RequestTimeoutError) throw error;
|
|
9116
|
+
if (error instanceof HTTPTransportError) {
|
|
9117
|
+
if (error.requestDisposition != null) throw error;
|
|
9118
|
+
throw new HTTPTransportError(error.message, {
|
|
9119
|
+
cause: error.cause ?? error,
|
|
9120
|
+
raw: error.raw,
|
|
9121
|
+
requestDisposition: "possibly_sent",
|
|
9122
|
+
retryAfterMs: error.retryAfterMs,
|
|
9123
|
+
retryable: error.retryable,
|
|
9124
|
+
safeToRetry: false,
|
|
9125
|
+
statusCode: error.statusCode
|
|
9126
|
+
});
|
|
9127
|
+
}
|
|
9037
9128
|
throw new HTTPTransportError("HTTP command request failed", {
|
|
9038
9129
|
cause: error,
|
|
9130
|
+
requestDisposition: "possibly_sent",
|
|
9039
9131
|
retryable: true,
|
|
9040
9132
|
safeToRetry: false
|
|
9041
9133
|
});
|
|
@@ -9047,7 +9139,9 @@ var HTTPTransport = class {
|
|
|
9047
9139
|
async close() {
|
|
9048
9140
|
if (this.#closed) return;
|
|
9049
9141
|
this.#closed = true;
|
|
9050
|
-
const error = new HTTPTransportError("HTTP transport is closed"
|
|
9142
|
+
const error = new HTTPTransportError("HTTP transport is closed", {
|
|
9143
|
+
requestDisposition: "possibly_sent"
|
|
9144
|
+
});
|
|
9051
9145
|
for (const controller of this.#requests) controller.abort(error);
|
|
9052
9146
|
this.#httpAgent.destroy();
|
|
9053
9147
|
this.#httpsAgent.destroy();
|
|
@@ -9290,16 +9384,22 @@ var HTTPAdapter = class _HTTPAdapter {
|
|
|
9290
9384
|
await this.#transport.close();
|
|
9291
9385
|
}
|
|
9292
9386
|
async executeBatch(commands) {
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9387
|
+
let body;
|
|
9388
|
+
let serverBlockMs;
|
|
9389
|
+
try {
|
|
9390
|
+
if (commands.length > this.#config.maxBatchItems) {
|
|
9391
|
+
throw new HTTPTransportError("HTTP command batch exceeds maxBatchItems");
|
|
9392
|
+
}
|
|
9393
|
+
for (const command of commands) assertHTTPCommandSupported(command[0]);
|
|
9394
|
+
const prepared = commands.map((command) => prepareHTTPCommand(command, this.#config.maxRequestBytes));
|
|
9395
|
+
body = encodeHTTPCommands(prepared.map((command) => command.encoded), this.#config.maxRequestBytes);
|
|
9396
|
+
if (body.byteLength > this.#config.maxRequestBytes) {
|
|
9397
|
+
throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
|
|
9398
|
+
}
|
|
9399
|
+
serverBlockMs = combinedServerBlockMs(prepared.map((command) => command.serverBlockMs));
|
|
9400
|
+
} catch (error) {
|
|
9401
|
+
throw unsentHTTPError(error);
|
|
9301
9402
|
}
|
|
9302
|
-
const serverBlockMs = combinedServerBlockMs(prepared.map((command) => command.serverBlockMs));
|
|
9303
9403
|
const response = await this.#transport.post(
|
|
9304
9404
|
body,
|
|
9305
9405
|
serverResponseTimeoutMs(this.#config.timeoutMs, serverBlockMs)
|
|
@@ -9356,16 +9456,32 @@ function commandError(value) {
|
|
|
9356
9456
|
}
|
|
9357
9457
|
function topLevelError(status, envelope, retryAfter) {
|
|
9358
9458
|
const details = isRecord2(envelope.error) ? envelope.error : {};
|
|
9459
|
+
const code = typeof details.code === "string" ? details.code.toLowerCase() : void 0;
|
|
9359
9460
|
const message = typeof details.message === "string" ? details.message : `HTTP command request failed with status ${status}`;
|
|
9360
9461
|
const retryAfterMs2 = retryAfterMilliseconds(retryAfter);
|
|
9462
|
+
const ambiguousTimeout = status === 408 || code === "request_timeout";
|
|
9463
|
+
const safeToRetry = !ambiguousTimeout && (details.safe_to_retry === true || definitelyRejectedHTTPStatus(status));
|
|
9361
9464
|
return new HTTPTransportError(message, {
|
|
9362
9465
|
raw: details,
|
|
9363
9466
|
retryable: status === 408 || status === 425 || status === 429 || status >= 500,
|
|
9364
9467
|
retryAfterMs: retryAfterMs2,
|
|
9365
|
-
|
|
9468
|
+
requestDisposition: "possibly_sent",
|
|
9469
|
+
safeToRetry,
|
|
9366
9470
|
statusCode: status
|
|
9367
9471
|
});
|
|
9368
9472
|
}
|
|
9473
|
+
function definitelyRejectedHTTPStatus(status) {
|
|
9474
|
+
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;
|
|
9475
|
+
}
|
|
9476
|
+
function unsentHTTPError(error) {
|
|
9477
|
+
if (error instanceof HTTPTransportError && error.requestDisposition === "unsent") return error;
|
|
9478
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
9479
|
+
return new HTTPTransportError(message, {
|
|
9480
|
+
cause: error,
|
|
9481
|
+
raw: error instanceof FerricStoreError ? error.raw ?? error : error,
|
|
9482
|
+
requestDisposition: "unsent"
|
|
9483
|
+
});
|
|
9484
|
+
}
|
|
9369
9485
|
function retryAfterMilliseconds(value) {
|
|
9370
9486
|
if (value == null) return void 0;
|
|
9371
9487
|
if (/^\d+$/u.test(value)) {
|
|
@@ -9458,9 +9574,9 @@ var ReconnectingExecutor = class {
|
|
|
9458
9574
|
const snapshot = snapshotPipelineCommands(commands);
|
|
9459
9575
|
const snapshotOptions = snapshotPipelineOptions(options) ?? {};
|
|
9460
9576
|
for (const command of snapshot) assertCommandHasStableConnectionState(command);
|
|
9461
|
-
if (this.closed) throw new
|
|
9577
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9462
9578
|
const initialExecutor = await this.executorPromise;
|
|
9463
|
-
if (this.closed) throw new
|
|
9579
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9464
9580
|
if (initialExecutor.executePipeline == null) {
|
|
9465
9581
|
return await executeCommandArraysIndividually(
|
|
9466
9582
|
async (command) => await this.executeCommandArgs(command),
|
|
@@ -9481,9 +9597,9 @@ var ReconnectingExecutor = class {
|
|
|
9481
9597
|
const snapshot = snapshotPipelineCommands(commands);
|
|
9482
9598
|
const snapshotOptions = snapshotPipelineOptions(options) ?? {};
|
|
9483
9599
|
for (const command of snapshot) assertCommandHasStableConnectionState(command);
|
|
9484
|
-
if (this.closed) throw new
|
|
9600
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9485
9601
|
const initialExecutor = await this.executorPromise;
|
|
9486
|
-
if (this.closed) throw new
|
|
9602
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9487
9603
|
if (initialExecutor.executeFusedPipeline == null) return void 0;
|
|
9488
9604
|
try {
|
|
9489
9605
|
return await initialExecutor.executeFusedPipeline(snapshot, snapshotOptions);
|
|
@@ -9516,7 +9632,7 @@ var ReconnectingExecutor = class {
|
|
|
9516
9632
|
return;
|
|
9517
9633
|
}
|
|
9518
9634
|
this.closed = true;
|
|
9519
|
-
this.retryAbortController.abort(new
|
|
9635
|
+
this.retryAbortController.abort(new RequestNotSentError("FerricStore client is closed"));
|
|
9520
9636
|
const executorPromise = this.executorPromise;
|
|
9521
9637
|
const reconnectPromise = this.reconnectPromise;
|
|
9522
9638
|
this.closePromise = (async () => {
|
|
@@ -9538,7 +9654,7 @@ var ReconnectingExecutor = class {
|
|
|
9538
9654
|
let executor = await this.executorPromise;
|
|
9539
9655
|
let retries = 0;
|
|
9540
9656
|
for (; ; ) {
|
|
9541
|
-
if (this.closed) throw new
|
|
9657
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9542
9658
|
try {
|
|
9543
9659
|
return await operation(executor);
|
|
9544
9660
|
} catch (error) {
|
|
@@ -9567,17 +9683,17 @@ var ReconnectingExecutor = class {
|
|
|
9567
9683
|
try {
|
|
9568
9684
|
await sleep(Math.min(this.maxDelayMs, base + jitter), this.retryAbortController.signal);
|
|
9569
9685
|
} catch (error) {
|
|
9570
|
-
if (this.closed) throw new
|
|
9686
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed", { cause: error });
|
|
9571
9687
|
throw error;
|
|
9572
9688
|
}
|
|
9573
9689
|
}
|
|
9574
9690
|
async reconnect(staleExecutor) {
|
|
9575
|
-
if (this.closed) throw new
|
|
9691
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9576
9692
|
const competingReconnect = this.reconnectPromise;
|
|
9577
9693
|
if (competingReconnect != null) return await competingReconnect;
|
|
9578
9694
|
const observedExecutorPromise = this.executorPromise;
|
|
9579
9695
|
const currentExecutor = await observedExecutorPromise.catch(() => void 0);
|
|
9580
|
-
if (this.closed) throw new
|
|
9696
|
+
if (this.closed) throw new RequestNotSentError("FerricStore client is closed");
|
|
9581
9697
|
if (this.reconnectPromise != null) return await this.reconnectPromise;
|
|
9582
9698
|
if (this.executorPromise !== observedExecutorPromise) return await this.executorPromise;
|
|
9583
9699
|
if (currentExecutor != null && currentExecutor !== staleExecutor) return currentExecutor;
|
|
@@ -9586,7 +9702,7 @@ var ReconnectingExecutor = class {
|
|
|
9586
9702
|
const nextExecutor = await this.createExecutor(this.retryAbortController.signal);
|
|
9587
9703
|
if (this.closed) {
|
|
9588
9704
|
await Promise.resolve(nextExecutor.close?.()).catch(() => void 0);
|
|
9589
|
-
throw new
|
|
9705
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
9590
9706
|
}
|
|
9591
9707
|
this.executorPromise = Promise.resolve(nextExecutor);
|
|
9592
9708
|
return nextExecutor;
|
|
@@ -10996,7 +11112,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
|
|
|
10996
11112
|
);
|
|
10997
11113
|
}
|
|
10998
11114
|
assertOpen() {
|
|
10999
|
-
if (this.closed) throw new
|
|
11115
|
+
if (this.closed) throw new RequestNotSentError("FerricStore topology adapter pool is closed");
|
|
11000
11116
|
}
|
|
11001
11117
|
};
|
|
11002
11118
|
|
|
@@ -12122,7 +12238,7 @@ var AutoBatchExecutor = class {
|
|
|
12122
12238
|
}
|
|
12123
12239
|
async executeCommandArgs(args) {
|
|
12124
12240
|
if (this.closed) {
|
|
12125
|
-
throw new
|
|
12241
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12126
12242
|
}
|
|
12127
12243
|
const command = snapshotCommandArguments(args);
|
|
12128
12244
|
if (this.executor.executePipeline == null) {
|
|
@@ -12142,7 +12258,7 @@ var AutoBatchExecutor = class {
|
|
|
12142
12258
|
if (orderingBarrier != null) {
|
|
12143
12259
|
await orderingBarrier;
|
|
12144
12260
|
if (this.closed) {
|
|
12145
|
-
throw new
|
|
12261
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12146
12262
|
}
|
|
12147
12263
|
}
|
|
12148
12264
|
return await new Promise((resolve, reject) => {
|
|
@@ -12156,7 +12272,7 @@ var AutoBatchExecutor = class {
|
|
|
12156
12272
|
}
|
|
12157
12273
|
async executePipeline(commands, options) {
|
|
12158
12274
|
if (this.closed) {
|
|
12159
|
-
throw new
|
|
12275
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12160
12276
|
}
|
|
12161
12277
|
const snapshot = snapshotPipelineCommands(commands);
|
|
12162
12278
|
const snapshotOptions = snapshotPipelineOptions(options);
|
|
@@ -12173,7 +12289,7 @@ var AutoBatchExecutor = class {
|
|
|
12173
12289
|
}
|
|
12174
12290
|
async executeFusedPipeline(commands, options) {
|
|
12175
12291
|
if (this.closed) {
|
|
12176
|
-
throw new
|
|
12292
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12177
12293
|
}
|
|
12178
12294
|
if (this.executor.executeFusedPipeline == null) return void 0;
|
|
12179
12295
|
const snapshot = snapshotPipelineCommands(commands);
|
|
@@ -12184,7 +12300,7 @@ var AutoBatchExecutor = class {
|
|
|
12184
12300
|
}
|
|
12185
12301
|
async refreshTopology() {
|
|
12186
12302
|
if (this.closed) {
|
|
12187
|
-
throw new
|
|
12303
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12188
12304
|
}
|
|
12189
12305
|
const refreshTopology = this.executor.refreshTopology?.bind(this.executor);
|
|
12190
12306
|
if (refreshTopology == null) {
|
|
@@ -12194,7 +12310,7 @@ var AutoBatchExecutor = class {
|
|
|
12194
12310
|
}
|
|
12195
12311
|
async route(key) {
|
|
12196
12312
|
if (this.closed) {
|
|
12197
|
-
throw new
|
|
12313
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12198
12314
|
}
|
|
12199
12315
|
const route = this.executor.route?.bind(this.executor);
|
|
12200
12316
|
if (route == null) {
|
|
@@ -12214,7 +12330,7 @@ var AutoBatchExecutor = class {
|
|
|
12214
12330
|
this.timer.cancel();
|
|
12215
12331
|
this.timer = void 0;
|
|
12216
12332
|
}
|
|
12217
|
-
this.failPending(new
|
|
12333
|
+
this.failPending(new RequestNotSentError("FerricStore client closed before auto-batch flush"));
|
|
12218
12334
|
await this.orderingBarrier;
|
|
12219
12335
|
await this.waitForInFlightBatches();
|
|
12220
12336
|
await Promise.allSettled([...this.inFlightHelpers]);
|
|
@@ -12224,7 +12340,7 @@ var AutoBatchExecutor = class {
|
|
|
12224
12340
|
}
|
|
12225
12341
|
async executeAfterPendingBatches(operation) {
|
|
12226
12342
|
if (this.closed) {
|
|
12227
|
-
throw new
|
|
12343
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12228
12344
|
}
|
|
12229
12345
|
const previousBarrier = this.orderingBarrier;
|
|
12230
12346
|
let releaseBarrier;
|
|
@@ -12245,7 +12361,7 @@ var AutoBatchExecutor = class {
|
|
|
12245
12361
|
}
|
|
12246
12362
|
executeHelper(operation) {
|
|
12247
12363
|
if (this.closed) {
|
|
12248
|
-
return Promise.reject(new
|
|
12364
|
+
return Promise.reject(new RequestNotSentError("FerricStore client is closed"));
|
|
12249
12365
|
}
|
|
12250
12366
|
const task = Promise.resolve().then(operation);
|
|
12251
12367
|
this.inFlightHelpers.add(task);
|
|
@@ -12267,7 +12383,7 @@ var AutoBatchExecutor = class {
|
|
|
12267
12383
|
await previousBarrier;
|
|
12268
12384
|
await this.flushNow();
|
|
12269
12385
|
if (this.closed) {
|
|
12270
|
-
throw new
|
|
12386
|
+
throw new RequestNotSentError("FerricStore client is closed");
|
|
12271
12387
|
}
|
|
12272
12388
|
dispatched = operation();
|
|
12273
12389
|
} finally {
|
|
@@ -14606,7 +14722,7 @@ var FerricStoreClientBase = class {
|
|
|
14606
14722
|
return validatePipelineResponse(results, snapshot.length);
|
|
14607
14723
|
}
|
|
14608
14724
|
async close() {
|
|
14609
|
-
this.closeAbortController.abort(new
|
|
14725
|
+
this.closeAbortController.abort(new RequestNotSentError("FerricStore client is closed"));
|
|
14610
14726
|
this.closePromise ??= (async () => await this.executor.close?.())();
|
|
14611
14727
|
await this.closePromise;
|
|
14612
14728
|
}
|
|
@@ -17682,7 +17798,7 @@ async function executeProducerWriteWithBackpressure(execute, policy, signal) {
|
|
|
17682
17798
|
function throwIfClosed(signal) {
|
|
17683
17799
|
if (!signal.aborted) return;
|
|
17684
17800
|
if (signal.reason instanceof Error) throw signal.reason;
|
|
17685
|
-
throw new
|
|
17801
|
+
throw new RequestNotSentError("FerricStore client is closed", { raw: signal.reason });
|
|
17686
17802
|
}
|
|
17687
17803
|
|
|
17688
17804
|
// src/flow-policy.ts
|
|
@@ -18999,6 +19115,8 @@ async function runDurableStep(client, job, options, hooks = {}) {
|
|
|
18999
19115
|
const run2 = options.run;
|
|
19000
19116
|
const continuation = snapshotAdvanceOptions(options);
|
|
19001
19117
|
assertNonEmptyString(name, "name");
|
|
19118
|
+
if (name.trim().length === 0) throw new TypeError("name must not be blank");
|
|
19119
|
+
if (!name.isWellFormed()) throw new TypeError("name must contain valid Unicode");
|
|
19002
19120
|
assertNonEmptyString(continuation.toState, "toState");
|
|
19003
19121
|
if (typeof run2 !== "function") throw new TypeError("run must be a function");
|
|
19004
19122
|
const resultName = durableStepValueName(name);
|
|
@@ -19026,7 +19144,7 @@ async function runDurableStep(client, job, options, hooks = {}) {
|
|
|
19026
19144
|
throw new FerricStoreError("committed durable step result is missing");
|
|
19027
19145
|
}
|
|
19028
19146
|
const replayedJob = claimedItemFromRecord(validated);
|
|
19029
|
-
hooks.replayed
|
|
19147
|
+
notifyWithoutReplacingOutcome(hooks.replayed, replayedJob);
|
|
19030
19148
|
return { job: replayedJob, result: entry.value };
|
|
19031
19149
|
}
|
|
19032
19150
|
const result = normalizeStepResult(client, await run2());
|
|
@@ -19039,12 +19157,18 @@ async function runDurableStep(client, job, options, hooks = {}) {
|
|
|
19039
19157
|
values: { ...continuation.values, [resultName]: result }
|
|
19040
19158
|
});
|
|
19041
19159
|
} catch (error) {
|
|
19042
|
-
hooks.commitFailed
|
|
19160
|
+
notifyWithoutReplacingOutcome(hooks.commitFailed, error);
|
|
19043
19161
|
throw error;
|
|
19044
19162
|
}
|
|
19045
|
-
hooks.committed
|
|
19163
|
+
notifyWithoutReplacingOutcome(hooks.committed, refreshed);
|
|
19046
19164
|
return { job: refreshed, result };
|
|
19047
19165
|
}
|
|
19166
|
+
function notifyWithoutReplacingOutcome(callback, value) {
|
|
19167
|
+
try {
|
|
19168
|
+
callback?.(value);
|
|
19169
|
+
} catch {
|
|
19170
|
+
}
|
|
19171
|
+
}
|
|
19048
19172
|
function normalizeStepResult(client, value) {
|
|
19049
19173
|
return client.codec.decode(client.codec.encode(value));
|
|
19050
19174
|
}
|
|
@@ -19165,6 +19289,35 @@ function claimedItemFromRecord(record) {
|
|
|
19165
19289
|
};
|
|
19166
19290
|
}
|
|
19167
19291
|
|
|
19292
|
+
// src/client-step-continue.ts
|
|
19293
|
+
function stepContinueArguments(id, options, codec) {
|
|
19294
|
+
try {
|
|
19295
|
+
const args = [
|
|
19296
|
+
"FLOW.STEP_CONTINUE",
|
|
19297
|
+
id,
|
|
19298
|
+
options.leaseToken,
|
|
19299
|
+
options.fromState,
|
|
19300
|
+
options.toState,
|
|
19301
|
+
"FENCING",
|
|
19302
|
+
options.fencingToken,
|
|
19303
|
+
"LEASE_MS",
|
|
19304
|
+
options.leaseMs ?? 3e4,
|
|
19305
|
+
"NOW",
|
|
19306
|
+
options.nowMs ?? nowMs()
|
|
19307
|
+
];
|
|
19308
|
+
append(args, "PARTITION", options.partitionKey);
|
|
19309
|
+
append(args, "WORKER", options.worker);
|
|
19310
|
+
appendEncoded(args, "PAYLOAD", codec, options.payload);
|
|
19311
|
+
if (options.returnJob === true) args.push("RETURN", "JOBS_COMPACT");
|
|
19312
|
+
appendStateMeta(args, options.stateMeta);
|
|
19313
|
+
appendNamedValues(args, codec, options);
|
|
19314
|
+
appendAttributeMutations(args, options);
|
|
19315
|
+
return args;
|
|
19316
|
+
} catch (error) {
|
|
19317
|
+
throw requestNotSentError(error);
|
|
19318
|
+
}
|
|
19319
|
+
}
|
|
19320
|
+
|
|
19168
19321
|
// src/client.ts
|
|
19169
19322
|
var FerricStoreClient = class _FerricStoreClient extends FerricStoreProducerClient {
|
|
19170
19323
|
static async fromUrl(url, options = {}) {
|
|
@@ -19287,26 +19440,7 @@ var FerricStoreClient = class _FerricStoreClient extends FerricStoreProducerClie
|
|
|
19287
19440
|
const partitionKey = options.partitionKey;
|
|
19288
19441
|
const returnJob = options.returnJob === true;
|
|
19289
19442
|
const type = options.type;
|
|
19290
|
-
const args =
|
|
19291
|
-
"FLOW.STEP_CONTINUE",
|
|
19292
|
-
id,
|
|
19293
|
-
options.leaseToken,
|
|
19294
|
-
options.fromState,
|
|
19295
|
-
options.toState,
|
|
19296
|
-
"FENCING",
|
|
19297
|
-
options.fencingToken,
|
|
19298
|
-
"LEASE_MS",
|
|
19299
|
-
options.leaseMs ?? 3e4,
|
|
19300
|
-
"NOW",
|
|
19301
|
-
options.nowMs ?? nowMs()
|
|
19302
|
-
];
|
|
19303
|
-
append(args, "PARTITION", partitionKey);
|
|
19304
|
-
append(args, "WORKER", options.worker);
|
|
19305
|
-
appendEncoded(args, "PAYLOAD", this.codec, options.payload);
|
|
19306
|
-
if (returnJob) args.push("RETURN", "JOBS_COMPACT");
|
|
19307
|
-
appendStateMeta(args, options.stateMeta);
|
|
19308
|
-
appendNamedValues(args, this.codec, options);
|
|
19309
|
-
appendAttributeMutations(args, options);
|
|
19443
|
+
const args = stepContinueArguments(id, options, this.codec);
|
|
19310
19444
|
const response = await this.commandArgs(args);
|
|
19311
19445
|
return returnJob ? claimedItemFromResp(response, this.codec, { type }) : await this.recordOrGet(response, id, partitionKey);
|
|
19312
19446
|
}
|
|
@@ -20945,15 +21079,6 @@ function createWorkflowStateRegistration(name, handler, options, defaultValueMax
|
|
|
20945
21079
|
// src/workflow-context.ts
|
|
20946
21080
|
var MISSING_VALUE = /* @__PURE__ */ Symbol("ferricstore.missingValue");
|
|
20947
21081
|
var WorkflowContext = class {
|
|
20948
|
-
constructor(workflow, job, stateName, leaseJob = job, mutationCoordinator) {
|
|
20949
|
-
this.mutationCoordinator = mutationCoordinator;
|
|
20950
|
-
this.workflow = workflow;
|
|
20951
|
-
this.job = job;
|
|
20952
|
-
this.leaseJob = leaseJob;
|
|
20953
|
-
this.currentStateName = stateName;
|
|
20954
|
-
this.flow = new WorkflowFlowCommands(this);
|
|
20955
|
-
}
|
|
20956
|
-
mutationCoordinator;
|
|
20957
21082
|
workflow;
|
|
20958
21083
|
job;
|
|
20959
21084
|
flow;
|
|
@@ -20962,7 +21087,20 @@ var WorkflowContext = class {
|
|
|
20962
21087
|
leaseJob;
|
|
20963
21088
|
mutationFailure;
|
|
20964
21089
|
mutationPhase = "idle";
|
|
21090
|
+
mutationCoordinator;
|
|
20965
21091
|
valueCache = /* @__PURE__ */ new Map();
|
|
21092
|
+
constructor(workflow, job, stateName) {
|
|
21093
|
+
this.workflow = workflow;
|
|
21094
|
+
this.job = job;
|
|
21095
|
+
this.leaseJob = job;
|
|
21096
|
+
this.currentStateName = stateName;
|
|
21097
|
+
this.flow = new WorkflowFlowCommands(this);
|
|
21098
|
+
}
|
|
21099
|
+
/** @internal */
|
|
21100
|
+
configureWorkerMutation(leaseJob, coordinator) {
|
|
21101
|
+
this.leaseJob = leaseJob;
|
|
21102
|
+
this.mutationCoordinator = coordinator;
|
|
21103
|
+
}
|
|
20966
21104
|
get client() {
|
|
20967
21105
|
return this.workflow.client;
|
|
20968
21106
|
}
|
|
@@ -21386,10 +21524,18 @@ async function applyFail(client, ctx, outcome, returnRecord) {
|
|
|
21386
21524
|
});
|
|
21387
21525
|
}
|
|
21388
21526
|
|
|
21527
|
+
// src/workflow-worker-context.ts
|
|
21528
|
+
var WorkerWorkflowContext = class extends WorkflowContext {
|
|
21529
|
+
constructor(workflow, job, stateName, leaseJob, mutationCoordinator) {
|
|
21530
|
+
super(workflow, job, stateName);
|
|
21531
|
+
this.configureWorkerMutation(leaseJob, mutationCoordinator);
|
|
21532
|
+
}
|
|
21533
|
+
};
|
|
21534
|
+
|
|
21389
21535
|
// src/workflow-job-execution.ts
|
|
21390
21536
|
async function executeWorkflowJob(workflow, workerOptions, job, registration, guard) {
|
|
21391
21537
|
guard.assertActive();
|
|
21392
|
-
const ctx = new
|
|
21538
|
+
const ctx = new WorkerWorkflowContext(workflow, job, registration.name, guard.job, {
|
|
21393
21539
|
pause: async () => await guard.pauseForLeaseMutation(),
|
|
21394
21540
|
resume: (refreshed) => guard.resumeWith(refreshed)
|
|
21395
21541
|
});
|
|
@@ -21734,7 +21880,7 @@ function throwError(value) {
|
|
|
21734
21880
|
}
|
|
21735
21881
|
|
|
21736
21882
|
// src/version.ts
|
|
21737
|
-
var FERRICSTORE_SDK_VERSION = "0.
|
|
21883
|
+
var FERRICSTORE_SDK_VERSION = "0.13.1";
|
|
21738
21884
|
var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
|
|
21739
21885
|
var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
|
|
21740
21886
|
export {
|
|
@@ -21777,6 +21923,7 @@ export {
|
|
|
21777
21923
|
QueueWorker,
|
|
21778
21924
|
RawCodec,
|
|
21779
21925
|
ReconnectingExecutor,
|
|
21926
|
+
RequestNotSentError,
|
|
21780
21927
|
RequestTimeoutError,
|
|
21781
21928
|
RerouteError,
|
|
21782
21929
|
RoutingTopology,
|