@zapier/kitcore 0.17.2 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/dist/index.cjs +47 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +58 -6
- package/dist/index.d.ts +58 -6
- package/dist/index.mjs +45 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @zapier/kitcore
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1ec9410: Added `RetryHttpRequestOptions.onRetry` and exported `RetryHttpRequestAttempt` for observing retries scheduled by `retryHttpRequestPlugin`. The callback runs before the retry wait and receives the request, operation ID, failed attempt number, selected delay, and response or error. Promise results are not awaited, and thrown errors or rejected promises do not cancel the retry. When a response is present, read only its status and headers.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 1ec9410: `retryHttpRequestPlugin` now waits at least 100 milliseconds before retrying when generated backoff is capped by a zero or near-zero `maxDelayMilliseconds`. Use `maxAttempts: 1` to disable retries.
|
|
12
|
+
|
|
13
|
+
## 0.18.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 2c8ea56: **Added `httpFetchPluginRef` (`kitcore/httpFetch`), the function
|
|
18
|
+
`dispatchHttpRequest` calls to reach the network.** Provide it and the default
|
|
19
|
+
dispatch stage calls that function instead of the ambient `fetch` — a
|
|
20
|
+
debug-wrapped fetch, a test double, a polyfill. Provide nothing and the stage
|
|
21
|
+
behaves as before.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
const httpFetch = defineProperty({
|
|
25
|
+
namespace: "kitcore",
|
|
26
|
+
name: "httpFetch",
|
|
27
|
+
value: myFetch,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Or supply it by id, with no plugin of your own:
|
|
31
|
+
createSdk(root, { configuration: { [HTTP_FETCH_ID]: myFetch } });
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
It is a value rather than a wrap, so the `dispatchHttpRequest` wrap slot stays
|
|
35
|
+
free for a host that replaces the stage outright.
|
|
36
|
+
|
|
3
37
|
## 0.17.2
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
CoreError: () => CoreError,
|
|
30
30
|
CoreErrorCode: () => CoreErrorCode,
|
|
31
31
|
CoreSignal: () => CoreSignal,
|
|
32
|
+
HTTP_FETCH_ID: () => HTTP_FETCH_ID,
|
|
32
33
|
RETRY_HTTP_REQUEST_OPTIONS_ID: () => RETRY_HTTP_REQUEST_OPTIONS_ID,
|
|
33
34
|
STABILITY_LEVELS: () => STABILITY_LEVELS,
|
|
34
35
|
STABILITY_TITLES: () => STABILITY_TITLES,
|
|
@@ -89,6 +90,7 @@ __export(index_exports, {
|
|
|
89
90
|
getRegistry: () => getRegistry,
|
|
90
91
|
getRegistryPlugin: () => getRegistryPlugin,
|
|
91
92
|
getSchemaDescription: () => getSchemaDescription,
|
|
93
|
+
httpFetchPluginRef: () => httpFetchPluginRef,
|
|
92
94
|
initializeHttpRequestPlugin: () => initializeHttpRequestPlugin,
|
|
93
95
|
isCoreCancelledSignal: () => isCoreCancelledSignal,
|
|
94
96
|
isCoreError: () => isCoreError,
|
|
@@ -773,6 +775,11 @@ function toIterable(source) {
|
|
|
773
775
|
return { [Symbol.asyncIterator]: () => source[Symbol.asyncIterator]() };
|
|
774
776
|
}
|
|
775
777
|
|
|
778
|
+
// src/utils/promise-utils.ts
|
|
779
|
+
function isPromiseLike(value) {
|
|
780
|
+
return value !== null && typeof value === "object" && typeof value.then === "function";
|
|
781
|
+
}
|
|
782
|
+
|
|
776
783
|
// src/utils/validation.ts
|
|
777
784
|
var parseOrThrow = (schema, input, { adaptError } = {}) => {
|
|
778
785
|
const result = schema.safeParse(input);
|
|
@@ -1239,7 +1246,7 @@ function createRawFunction(coreFn, options) {
|
|
|
1239
1246
|
try {
|
|
1240
1247
|
const parsed = schema ? validateOptions(schema, input, { adaptError }) : input;
|
|
1241
1248
|
const result = coreFn(parsed, context);
|
|
1242
|
-
if (result
|
|
1249
|
+
if (isPromiseLike(result)) {
|
|
1243
1250
|
return result.then(
|
|
1244
1251
|
(value) => {
|
|
1245
1252
|
fireEnd();
|
|
@@ -2571,9 +2578,6 @@ function applyListOutputPolicy(page, policy) {
|
|
|
2571
2578
|
var FRAMEWORK_CONFIGURATION_IDS = /* @__PURE__ */ new Set([
|
|
2572
2579
|
CORE_OPTIONS_ID
|
|
2573
2580
|
]);
|
|
2574
|
-
function isPromiseLike(value) {
|
|
2575
|
-
return value !== null && typeof value === "object" && typeof value.then === "function";
|
|
2576
|
-
}
|
|
2577
2581
|
function normalizeOutput(output) {
|
|
2578
2582
|
if (output === void 0) return { type: "raw" };
|
|
2579
2583
|
if (typeof output === "string") return { type: output };
|
|
@@ -4944,6 +4948,8 @@ var authorizeHttpRequestPlugin = defineMethod({
|
|
|
4944
4948
|
|
|
4945
4949
|
// src/transport/dispatch-http-request.ts
|
|
4946
4950
|
var import_zod7 = require("zod");
|
|
4951
|
+
var HTTP_FETCH_ID = "kitcore/httpFetch";
|
|
4952
|
+
var httpFetchPluginRef = declareOptionalProperty({ id: HTTP_FETCH_ID });
|
|
4947
4953
|
function toFetchInput(request) {
|
|
4948
4954
|
const init = { ...request };
|
|
4949
4955
|
const { url } = request;
|
|
@@ -4954,11 +4960,12 @@ function toFetchInput(request) {
|
|
|
4954
4960
|
var dispatchHttpRequestPlugin = defineMethod({
|
|
4955
4961
|
name: "dispatchHttpRequest",
|
|
4956
4962
|
namespace: "kitcore",
|
|
4963
|
+
imports: [httpFetchPluginRef],
|
|
4957
4964
|
inputSchema: import_zod7.z.custom(),
|
|
4958
4965
|
skipInputValidation: true,
|
|
4959
|
-
run: async ({ input }) => {
|
|
4966
|
+
run: async ({ input, imports }) => {
|
|
4960
4967
|
const { url, init } = toFetchInput(input.request);
|
|
4961
|
-
return fetch(url, init);
|
|
4968
|
+
return (imports.httpFetch ?? fetch)(url, init);
|
|
4962
4969
|
}
|
|
4963
4970
|
});
|
|
4964
4971
|
|
|
@@ -5057,6 +5064,7 @@ var DEFAULT_IDEMPOTENT_METHODS = [
|
|
|
5057
5064
|
"TRACE"
|
|
5058
5065
|
];
|
|
5059
5066
|
var BASE_BACKOFF_MILLISECONDS = 1e3;
|
|
5067
|
+
var MIN_BACKOFF_MILLISECONDS = 100;
|
|
5060
5068
|
var JITTER_FACTOR = 0.5;
|
|
5061
5069
|
var EPOCH_THRESHOLD_SECONDS = 1e9;
|
|
5062
5070
|
function directedDelayMilliseconds(response) {
|
|
@@ -5081,6 +5089,12 @@ function backoffMilliseconds(attemptNumber) {
|
|
|
5081
5089
|
const base = BASE_BACKOFF_MILLISECONDS * 2 ** (attemptNumber - 1);
|
|
5082
5090
|
return base + Math.random() * JITTER_FACTOR * base;
|
|
5083
5091
|
}
|
|
5092
|
+
function clampBackoffMilliseconds(attemptNumber, maxDelayMilliseconds) {
|
|
5093
|
+
return Math.max(
|
|
5094
|
+
Math.min(backoffMilliseconds(attemptNumber), maxDelayMilliseconds),
|
|
5095
|
+
MIN_BACKOFF_MILLISECONDS
|
|
5096
|
+
);
|
|
5097
|
+
}
|
|
5084
5098
|
function abortReason(signal) {
|
|
5085
5099
|
const reason = signal?.reason;
|
|
5086
5100
|
return reason ?? new Error("The request was aborted.");
|
|
@@ -5115,6 +5129,20 @@ var retryHttpRequestPlugin = defineHook({
|
|
|
5115
5129
|
const maxDelayMilliseconds = options.maxDelayMilliseconds ?? DEFAULT_MAX_DELAY_MILLISECONDS;
|
|
5116
5130
|
const idempotentMethods = options.idempotentMethods ?? DEFAULT_IDEMPOTENT_METHODS;
|
|
5117
5131
|
const statuses = isIdempotent(input.request, idempotentMethods) ? options.retryStatuses ?? DEFAULT_RETRY_STATUSES : options.nonIdempotentRetryStatuses ?? DEFAULT_NON_IDEMPOTENT_RETRY_STATUSES;
|
|
5132
|
+
const notifyRetry = (notice) => {
|
|
5133
|
+
try {
|
|
5134
|
+
const observed = options.onRetry?.({
|
|
5135
|
+
...notice,
|
|
5136
|
+
request: input.attempt.operation.request,
|
|
5137
|
+
operationId: input.attempt.operation.operationId
|
|
5138
|
+
});
|
|
5139
|
+
if (isPromiseLike(observed)) {
|
|
5140
|
+
void observed.then(void 0, () => {
|
|
5141
|
+
});
|
|
5142
|
+
}
|
|
5143
|
+
} catch {
|
|
5144
|
+
}
|
|
5145
|
+
};
|
|
5118
5146
|
for (let attemptNumber = 1; ; attemptNumber++) {
|
|
5119
5147
|
const attempt = {
|
|
5120
5148
|
...input.attempt,
|
|
@@ -5136,10 +5164,16 @@ var retryHttpRequestPlugin = defineHook({
|
|
|
5136
5164
|
)) {
|
|
5137
5165
|
throw error;
|
|
5138
5166
|
}
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5167
|
+
const errorDelay = clampBackoffMilliseconds(
|
|
5168
|
+
attemptNumber,
|
|
5169
|
+
maxDelayMilliseconds
|
|
5142
5170
|
);
|
|
5171
|
+
notifyRetry({
|
|
5172
|
+
attemptNumber,
|
|
5173
|
+
delayMilliseconds: errorDelay,
|
|
5174
|
+
error
|
|
5175
|
+
});
|
|
5176
|
+
await sleep(errorDelay, attempt.signal);
|
|
5143
5177
|
continue;
|
|
5144
5178
|
}
|
|
5145
5179
|
if (!statuses.includes(response.status) || !canRetry(
|
|
@@ -5152,10 +5186,8 @@ var retryHttpRequestPlugin = defineHook({
|
|
|
5152
5186
|
const directed = directedDelayMilliseconds(response);
|
|
5153
5187
|
if (directed != null && directed > maxDelayMilliseconds)
|
|
5154
5188
|
return response;
|
|
5155
|
-
const delay =
|
|
5156
|
-
|
|
5157
|
-
maxDelayMilliseconds
|
|
5158
|
-
);
|
|
5189
|
+
const delay = directed ?? clampBackoffMilliseconds(attemptNumber, maxDelayMilliseconds);
|
|
5190
|
+
notifyRetry({ attemptNumber, delayMilliseconds: delay, response });
|
|
5159
5191
|
await response.body?.cancel().catch(() => {
|
|
5160
5192
|
});
|
|
5161
5193
|
await sleep(delay, attempt.signal);
|
|
@@ -5311,6 +5343,7 @@ var resolveConnectionPlugin = defineMethod({
|
|
|
5311
5343
|
CoreError,
|
|
5312
5344
|
CoreErrorCode,
|
|
5313
5345
|
CoreSignal,
|
|
5346
|
+
HTTP_FETCH_ID,
|
|
5314
5347
|
RETRY_HTTP_REQUEST_OPTIONS_ID,
|
|
5315
5348
|
STABILITY_LEVELS,
|
|
5316
5349
|
STABILITY_TITLES,
|
|
@@ -5371,6 +5404,7 @@ var resolveConnectionPlugin = defineMethod({
|
|
|
5371
5404
|
getRegistry,
|
|
5372
5405
|
getRegistryPlugin,
|
|
5373
5406
|
getSchemaDescription,
|
|
5407
|
+
httpFetchPluginRef,
|
|
5374
5408
|
initializeHttpRequestPlugin,
|
|
5375
5409
|
isCoreCancelledSignal,
|
|
5376
5410
|
isCoreError,
|