@smithy/util-waiter 4.1.0 → 4.2.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/dist-cjs/index.js +152 -189
- package/package.json +3 -3
- package/dist-cjs/createWaiter.js +0 -1
- package/dist-cjs/poller.js +0 -1
- package/dist-cjs/utils/index.js +0 -1
- package/dist-cjs/utils/sleep.js +0 -1
- package/dist-cjs/utils/validate.js +0 -1
- package/dist-cjs/waiter.js +0 -1
package/dist-cjs/index.js
CHANGED
|
@@ -1,203 +1,166 @@
|
|
|
1
|
-
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
WaiterState: () => WaiterState,
|
|
24
|
-
checkExceptions: () => checkExceptions,
|
|
25
|
-
createWaiter: () => createWaiter,
|
|
26
|
-
waiterServiceDefaults: () => waiterServiceDefaults
|
|
27
|
-
});
|
|
28
|
-
module.exports = __toCommonJS(index_exports);
|
|
1
|
+
'use strict';
|
|
29
2
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}, "sleep");
|
|
3
|
+
const sleep = (seconds) => {
|
|
4
|
+
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
|
5
|
+
};
|
|
34
6
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
7
|
+
const waiterServiceDefaults = {
|
|
8
|
+
minDelay: 2,
|
|
9
|
+
maxDelay: 120,
|
|
10
|
+
};
|
|
11
|
+
exports.WaiterState = void 0;
|
|
12
|
+
(function (WaiterState) {
|
|
13
|
+
WaiterState["ABORTED"] = "ABORTED";
|
|
14
|
+
WaiterState["FAILURE"] = "FAILURE";
|
|
15
|
+
WaiterState["SUCCESS"] = "SUCCESS";
|
|
16
|
+
WaiterState["RETRY"] = "RETRY";
|
|
17
|
+
WaiterState["TIMEOUT"] = "TIMEOUT";
|
|
18
|
+
})(exports.WaiterState || (exports.WaiterState = {}));
|
|
19
|
+
const checkExceptions = (result) => {
|
|
20
|
+
if (result.state === exports.WaiterState.ABORTED) {
|
|
21
|
+
const abortError = new Error(`${JSON.stringify({
|
|
22
|
+
...result,
|
|
23
|
+
reason: "Request was aborted",
|
|
24
|
+
})}`);
|
|
25
|
+
abortError.name = "AbortError";
|
|
26
|
+
throw abortError;
|
|
27
|
+
}
|
|
28
|
+
else if (result.state === exports.WaiterState.TIMEOUT) {
|
|
29
|
+
const timeoutError = new Error(`${JSON.stringify({
|
|
30
|
+
...result,
|
|
31
|
+
reason: "Waiter has timed out",
|
|
32
|
+
})}`);
|
|
33
|
+
timeoutError.name = "TimeoutError";
|
|
34
|
+
throw timeoutError;
|
|
35
|
+
}
|
|
36
|
+
else if (result.state !== exports.WaiterState.SUCCESS) {
|
|
37
|
+
throw new Error(`${JSON.stringify(result)}`);
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
39
40
|
};
|
|
40
|
-
var WaiterState = /* @__PURE__ */ ((WaiterState2) => {
|
|
41
|
-
WaiterState2["ABORTED"] = "ABORTED";
|
|
42
|
-
WaiterState2["FAILURE"] = "FAILURE";
|
|
43
|
-
WaiterState2["SUCCESS"] = "SUCCESS";
|
|
44
|
-
WaiterState2["RETRY"] = "RETRY";
|
|
45
|
-
WaiterState2["TIMEOUT"] = "TIMEOUT";
|
|
46
|
-
return WaiterState2;
|
|
47
|
-
})(WaiterState || {});
|
|
48
|
-
var checkExceptions = /* @__PURE__ */ __name((result) => {
|
|
49
|
-
if (result.state === "ABORTED" /* ABORTED */) {
|
|
50
|
-
const abortError = new Error(
|
|
51
|
-
`${JSON.stringify({
|
|
52
|
-
...result,
|
|
53
|
-
reason: "Request was aborted"
|
|
54
|
-
})}`
|
|
55
|
-
);
|
|
56
|
-
abortError.name = "AbortError";
|
|
57
|
-
throw abortError;
|
|
58
|
-
} else if (result.state === "TIMEOUT" /* TIMEOUT */) {
|
|
59
|
-
const timeoutError = new Error(
|
|
60
|
-
`${JSON.stringify({
|
|
61
|
-
...result,
|
|
62
|
-
reason: "Waiter has timed out"
|
|
63
|
-
})}`
|
|
64
|
-
);
|
|
65
|
-
timeoutError.name = "TimeoutError";
|
|
66
|
-
throw timeoutError;
|
|
67
|
-
} else if (result.state !== "SUCCESS" /* SUCCESS */) {
|
|
68
|
-
throw new Error(`${JSON.stringify(result)}`);
|
|
69
|
-
}
|
|
70
|
-
return result;
|
|
71
|
-
}, "checkExceptions");
|
|
72
41
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
if (state !== "RETRY" /* RETRY */) {
|
|
89
|
-
return { state, reason, observedResponses };
|
|
90
|
-
}
|
|
91
|
-
let currentAttempt = 1;
|
|
92
|
-
const waitUntil = Date.now() + maxWaitTime * 1e3;
|
|
93
|
-
const attemptCeiling = Math.log(maxDelay / minDelay) / Math.log(2) + 1;
|
|
94
|
-
while (true) {
|
|
95
|
-
if (abortController?.signal?.aborted || abortSignal?.aborted) {
|
|
96
|
-
const message = "AbortController signal aborted.";
|
|
97
|
-
observedResponses[message] |= 0;
|
|
98
|
-
observedResponses[message] += 1;
|
|
99
|
-
return { state: "ABORTED" /* ABORTED */, observedResponses };
|
|
42
|
+
const exponentialBackoffWithJitter = (minDelay, maxDelay, attemptCeiling, attempt) => {
|
|
43
|
+
if (attempt > attemptCeiling)
|
|
44
|
+
return maxDelay;
|
|
45
|
+
const delay = minDelay * 2 ** (attempt - 1);
|
|
46
|
+
return randomInRange(minDelay, delay);
|
|
47
|
+
};
|
|
48
|
+
const randomInRange = (min, max) => min + Math.random() * (max - min);
|
|
49
|
+
const runPolling = async ({ minDelay, maxDelay, maxWaitTime, abortController, client, abortSignal }, input, acceptorChecks) => {
|
|
50
|
+
const observedResponses = {};
|
|
51
|
+
const { state, reason } = await acceptorChecks(client, input);
|
|
52
|
+
if (reason) {
|
|
53
|
+
const message = createMessageFromResponse(reason);
|
|
54
|
+
observedResponses[message] |= 0;
|
|
55
|
+
observedResponses[message] += 1;
|
|
100
56
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return { state: "TIMEOUT" /* TIMEOUT */, observedResponses };
|
|
57
|
+
if (state !== exports.WaiterState.RETRY) {
|
|
58
|
+
return { state, reason, observedResponses };
|
|
104
59
|
}
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
60
|
+
let currentAttempt = 1;
|
|
61
|
+
const waitUntil = Date.now() + maxWaitTime * 1000;
|
|
62
|
+
const attemptCeiling = Math.log(maxDelay / minDelay) / Math.log(2) + 1;
|
|
63
|
+
while (true) {
|
|
64
|
+
if (abortController?.signal?.aborted || abortSignal?.aborted) {
|
|
65
|
+
const message = "AbortController signal aborted.";
|
|
66
|
+
observedResponses[message] |= 0;
|
|
67
|
+
observedResponses[message] += 1;
|
|
68
|
+
return { state: exports.WaiterState.ABORTED, observedResponses };
|
|
69
|
+
}
|
|
70
|
+
const delay = exponentialBackoffWithJitter(minDelay, maxDelay, attemptCeiling, currentAttempt);
|
|
71
|
+
if (Date.now() + delay * 1000 > waitUntil) {
|
|
72
|
+
return { state: exports.WaiterState.TIMEOUT, observedResponses };
|
|
73
|
+
}
|
|
74
|
+
await sleep(delay);
|
|
75
|
+
const { state, reason } = await acceptorChecks(client, input);
|
|
76
|
+
if (reason) {
|
|
77
|
+
const message = createMessageFromResponse(reason);
|
|
78
|
+
observedResponses[message] |= 0;
|
|
79
|
+
observedResponses[message] += 1;
|
|
80
|
+
}
|
|
81
|
+
if (state !== exports.WaiterState.RETRY) {
|
|
82
|
+
return { state, reason, observedResponses };
|
|
83
|
+
}
|
|
84
|
+
currentAttempt += 1;
|
|
111
85
|
}
|
|
112
|
-
|
|
113
|
-
|
|
86
|
+
};
|
|
87
|
+
const createMessageFromResponse = (reason) => {
|
|
88
|
+
if (reason?.$responseBodyText) {
|
|
89
|
+
return `Deserialization error for body: ${reason.$responseBodyText}`;
|
|
114
90
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return `Deserialization error for body: ${reason.$responseBodyText}`;
|
|
121
|
-
}
|
|
122
|
-
if (reason?.$metadata?.httpStatusCode) {
|
|
123
|
-
if (reason.$response || reason.message) {
|
|
124
|
-
return `${reason.$response.statusCode ?? reason.$metadata.httpStatusCode ?? "Unknown"}: ${reason.message}`;
|
|
91
|
+
if (reason?.$metadata?.httpStatusCode) {
|
|
92
|
+
if (reason.$response || reason.message) {
|
|
93
|
+
return `${reason.$response.statusCode ?? reason.$metadata.httpStatusCode ?? "Unknown"}: ${reason.message}`;
|
|
94
|
+
}
|
|
95
|
+
return `${reason.$metadata.httpStatusCode}: OK`;
|
|
125
96
|
}
|
|
126
|
-
return
|
|
127
|
-
|
|
128
|
-
return String(reason?.message ?? JSON.stringify(reason) ?? "Unknown");
|
|
129
|
-
}, "createMessageFromResponse");
|
|
130
|
-
|
|
131
|
-
// src/utils/validate.ts
|
|
132
|
-
var validateWaiterOptions = /* @__PURE__ */ __name((options) => {
|
|
133
|
-
if (options.maxWaitTime <= 0) {
|
|
134
|
-
throw new Error(`WaiterConfiguration.maxWaitTime must be greater than 0`);
|
|
135
|
-
} else if (options.minDelay <= 0) {
|
|
136
|
-
throw new Error(`WaiterConfiguration.minDelay must be greater than 0`);
|
|
137
|
-
} else if (options.maxDelay <= 0) {
|
|
138
|
-
throw new Error(`WaiterConfiguration.maxDelay must be greater than 0`);
|
|
139
|
-
} else if (options.maxWaitTime <= options.minDelay) {
|
|
140
|
-
throw new Error(
|
|
141
|
-
`WaiterConfiguration.maxWaitTime [${options.maxWaitTime}] must be greater than WaiterConfiguration.minDelay [${options.minDelay}] for this waiter`
|
|
142
|
-
);
|
|
143
|
-
} else if (options.maxDelay < options.minDelay) {
|
|
144
|
-
throw new Error(
|
|
145
|
-
`WaiterConfiguration.maxDelay [${options.maxDelay}] must be greater than WaiterConfiguration.minDelay [${options.minDelay}] for this waiter`
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
}, "validateWaiterOptions");
|
|
97
|
+
return String(reason?.message ?? JSON.stringify(reason) ?? "Unknown");
|
|
98
|
+
};
|
|
149
99
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const promise = new Promise((resolve) => {
|
|
154
|
-
onAbort = /* @__PURE__ */ __name(() => resolve({ state: "ABORTED" /* ABORTED */ }), "onAbort");
|
|
155
|
-
if (typeof abortSignal.addEventListener === "function") {
|
|
156
|
-
abortSignal.addEventListener("abort", onAbort);
|
|
157
|
-
} else {
|
|
158
|
-
abortSignal.onabort = onAbort;
|
|
100
|
+
const validateWaiterOptions = (options) => {
|
|
101
|
+
if (options.maxWaitTime <= 0) {
|
|
102
|
+
throw new Error(`WaiterConfiguration.maxWaitTime must be greater than 0`);
|
|
159
103
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
clearListener() {
|
|
163
|
-
if (typeof abortSignal.removeEventListener === "function") {
|
|
164
|
-
abortSignal.removeEventListener("abort", onAbort);
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
aborted: promise
|
|
168
|
-
};
|
|
169
|
-
}, "abortTimeout");
|
|
170
|
-
var createWaiter = /* @__PURE__ */ __name(async (options, input, acceptorChecks) => {
|
|
171
|
-
const params = {
|
|
172
|
-
...waiterServiceDefaults,
|
|
173
|
-
...options
|
|
174
|
-
};
|
|
175
|
-
validateWaiterOptions(params);
|
|
176
|
-
const exitConditions = [runPolling(params, input, acceptorChecks)];
|
|
177
|
-
const finalize = [];
|
|
178
|
-
if (options.abortSignal) {
|
|
179
|
-
const { aborted, clearListener } = abortTimeout(options.abortSignal);
|
|
180
|
-
finalize.push(clearListener);
|
|
181
|
-
exitConditions.push(aborted);
|
|
182
|
-
}
|
|
183
|
-
if (options.abortController?.signal) {
|
|
184
|
-
const { aborted, clearListener } = abortTimeout(options.abortController.signal);
|
|
185
|
-
finalize.push(clearListener);
|
|
186
|
-
exitConditions.push(aborted);
|
|
187
|
-
}
|
|
188
|
-
return Promise.race(exitConditions).then((result) => {
|
|
189
|
-
for (const fn of finalize) {
|
|
190
|
-
fn();
|
|
104
|
+
else if (options.minDelay <= 0) {
|
|
105
|
+
throw new Error(`WaiterConfiguration.minDelay must be greater than 0`);
|
|
191
106
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
107
|
+
else if (options.maxDelay <= 0) {
|
|
108
|
+
throw new Error(`WaiterConfiguration.maxDelay must be greater than 0`);
|
|
109
|
+
}
|
|
110
|
+
else if (options.maxWaitTime <= options.minDelay) {
|
|
111
|
+
throw new Error(`WaiterConfiguration.maxWaitTime [${options.maxWaitTime}] must be greater than WaiterConfiguration.minDelay [${options.minDelay}] for this waiter`);
|
|
112
|
+
}
|
|
113
|
+
else if (options.maxDelay < options.minDelay) {
|
|
114
|
+
throw new Error(`WaiterConfiguration.maxDelay [${options.maxDelay}] must be greater than WaiterConfiguration.minDelay [${options.minDelay}] for this waiter`);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
196
117
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
118
|
+
const abortTimeout = (abortSignal) => {
|
|
119
|
+
let onAbort;
|
|
120
|
+
const promise = new Promise((resolve) => {
|
|
121
|
+
onAbort = () => resolve({ state: exports.WaiterState.ABORTED });
|
|
122
|
+
if (typeof abortSignal.addEventListener === "function") {
|
|
123
|
+
abortSignal.addEventListener("abort", onAbort);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
abortSignal.onabort = onAbort;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
clearListener() {
|
|
131
|
+
if (typeof abortSignal.removeEventListener === "function") {
|
|
132
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
aborted: promise,
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
const createWaiter = async (options, input, acceptorChecks) => {
|
|
139
|
+
const params = {
|
|
140
|
+
...waiterServiceDefaults,
|
|
141
|
+
...options,
|
|
142
|
+
};
|
|
143
|
+
validateWaiterOptions(params);
|
|
144
|
+
const exitConditions = [runPolling(params, input, acceptorChecks)];
|
|
145
|
+
const finalize = [];
|
|
146
|
+
if (options.abortSignal) {
|
|
147
|
+
const { aborted, clearListener } = abortTimeout(options.abortSignal);
|
|
148
|
+
finalize.push(clearListener);
|
|
149
|
+
exitConditions.push(aborted);
|
|
150
|
+
}
|
|
151
|
+
if (options.abortController?.signal) {
|
|
152
|
+
const { aborted, clearListener } = abortTimeout(options.abortController.signal);
|
|
153
|
+
finalize.push(clearListener);
|
|
154
|
+
exitConditions.push(aborted);
|
|
155
|
+
}
|
|
156
|
+
return Promise.race(exitConditions).then((result) => {
|
|
157
|
+
for (const fn of finalize) {
|
|
158
|
+
fn();
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
});
|
|
162
|
+
};
|
|
203
163
|
|
|
164
|
+
exports.checkExceptions = checkExceptions;
|
|
165
|
+
exports.createWaiter = createWaiter;
|
|
166
|
+
exports.waiterServiceDefaults = waiterServiceDefaults;
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithy/util-waiter",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Shared utilities for client waiters for the AWS SDK",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@smithy/abort-controller": "^4.
|
|
7
|
-
"@smithy/types": "^4.
|
|
6
|
+
"@smithy/abort-controller": "^4.2.0",
|
|
7
|
+
"@smithy/types": "^4.6.0",
|
|
8
8
|
"tslib": "^2.6.2"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
package/dist-cjs/createWaiter.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
package/dist-cjs/poller.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
package/dist-cjs/utils/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("../index.js");
|
package/dist-cjs/utils/sleep.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("../index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("../index.js");
|
package/dist-cjs/waiter.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|