@vertexvis/utils 0.12.0-canary.6 → 0.12.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/async.d.ts CHANGED
@@ -25,3 +25,48 @@ export declare function timeout(ms: number): Promise<void>;
25
25
  * @param promise The promise to assign a timeout to.
26
26
  */
27
27
  export declare function timeout<T>(ms: number, promise: Promise<T>): Promise<T>;
28
+ interface RetryOptions {
29
+ /**
30
+ * An array of delays that are used between each retry attempt.
31
+ */
32
+ delaysInMs?: number[];
33
+ /**
34
+ * The maximum number of retries that will be attempted.
35
+ */
36
+ maxRetries?: number;
37
+ }
38
+ /**
39
+ * Executes and reattempts execution of an asynchronous function if it throws an
40
+ * error. By default, this function will only retry once and reexecute
41
+ * immediately after the previous execution throws. You can configure the number
42
+ * of retry attempts and delays with the `maxRetries` and `delaysInMs` options.
43
+ *
44
+ * The `delaysInMs` is an array of delays in milliseconds for each retry
45
+ * attempt. If there are more retry attempts than delays, the last delay will be
46
+ * used.
47
+ *
48
+ * @param process The process to execute.
49
+ * @param opts Options to configure retry behavior.
50
+ * @returns A promise that resolves with a successful value, or the original
51
+ * rejected value if the process fails.
52
+ */
53
+ export declare function retry<T>(process: () => Promise<T>, opts?: RetryOptions): Promise<T>;
54
+ /**
55
+ * Returns a promise that either resolves with the result of `promise`, or a
56
+ * value that indicates the execution was aborted.
57
+ *
58
+ * **Note:** Because Promises in JS cannot be canceled, an abort signal will not
59
+ * cancel the execution of the promise.
60
+ *
61
+ * @param signal A signal that communicates the process should be aborted.
62
+ * @param promise A promise who's value will be returned if not aborted.
63
+ * @returns A value indicating if the process was aborted, or the value of
64
+ * `promise`.
65
+ */
66
+ export declare function abort<T>(signal: AbortSignal, promise: Promise<T>): Promise<{
67
+ aborted: true;
68
+ } | {
69
+ aborted: false;
70
+ result: T;
71
+ }>;
72
+ export {};
@@ -4,6 +4,34 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var tslib = require('tslib');
6
6
 
7
+ /**
8
+ * Adds a listener to the given `target`, and returns a promise that
9
+ * resolves with the first event emitted of the given `type`.
10
+ *
11
+ * @param target The target to add an event listener to.
12
+ * @param type The event type to listen for.
13
+ * @param opts Options to pass to `addEventListener`.
14
+ * @returns A promise that resolves with the first event emitted of `type`.
15
+ */
16
+ function once(target, type, opts) {
17
+ return tslib.__awaiter(this, void 0, void 0, function () {
18
+ return tslib.__generator(this, function (_a) {
19
+ return [2 /*return*/, new Promise(function (resolve) {
20
+ function handler(event) {
21
+ target.removeEventListener(type, handler);
22
+ resolve(event);
23
+ }
24
+ target.addEventListener(type, handler, opts);
25
+ })];
26
+ });
27
+ });
28
+ }
29
+
30
+ var eventTargets = /*#__PURE__*/Object.freeze({
31
+ __proto__: null,
32
+ once: once
33
+ });
34
+
7
35
  function delay() {
8
36
  var args = [];
9
37
  for (var _i = 0; _i < arguments.length; _i++) {
@@ -36,28 +64,132 @@ function timeout() {
36
64
  for (var _i = 0; _i < arguments.length; _i++) {
37
65
  args[_i] = arguments[_i];
38
66
  }
39
- var ms = args[0];
40
- if (typeof ms === 'number') {
41
- var promise = args[1];
42
- var timeout_1 = new Promise(function (_, reject) {
43
- return setTimeout(function () { return reject(new Error("Promise timed out after " + ms + "ms")); }, ms);
67
+ return tslib.__awaiter(this, void 0, void 0, function () {
68
+ var ms, promise, timer_1, timeout_1, res;
69
+ return tslib.__generator(this, function (_a) {
70
+ switch (_a.label) {
71
+ case 0:
72
+ ms = args[0];
73
+ if (!(typeof ms === 'number')) return [3 /*break*/, 4];
74
+ promise = args[1];
75
+ timeout_1 = new Promise(function (_, reject) {
76
+ timer_1 = setTimeout(function () { return reject(new Error("Promise timed out after ".concat(ms, "ms"))); }, ms);
77
+ });
78
+ if (!(promise != null)) return [3 /*break*/, 2];
79
+ return [4 /*yield*/, Promise.race([promise, timeout_1])];
80
+ case 1:
81
+ res = _a.sent();
82
+ clearTimeout(timer_1);
83
+ return [2 /*return*/, res];
84
+ case 2: return [2 /*return*/, timeout_1];
85
+ case 3: return [3 /*break*/, 5];
86
+ case 4: return [2 /*return*/, Promise.reject('First argument to `timeout` must be a number')];
87
+ case 5: return [2 /*return*/];
88
+ }
44
89
  });
45
- if (promise != null) {
46
- return Promise.race([promise, timeout_1]);
47
- }
48
- else {
49
- return timeout_1;
90
+ });
91
+ }
92
+ /**
93
+ * Executes and reattempts execution of an asynchronous function if it throws an
94
+ * error. By default, this function will only retry once and reexecute
95
+ * immediately after the previous execution throws. You can configure the number
96
+ * of retry attempts and delays with the `maxRetries` and `delaysInMs` options.
97
+ *
98
+ * The `delaysInMs` is an array of delays in milliseconds for each retry
99
+ * attempt. If there are more retry attempts than delays, the last delay will be
100
+ * used.
101
+ *
102
+ * @param process The process to execute.
103
+ * @param opts Options to configure retry behavior.
104
+ * @returns A promise that resolves with a successful value, or the original
105
+ * rejected value if the process fails.
106
+ */
107
+ function retry(process, opts) {
108
+ if (opts === void 0) { opts = {}; }
109
+ return tslib.__awaiter(this, void 0, void 0, function () {
110
+ function execute(attempt, process, opts) {
111
+ return tslib.__awaiter(this, void 0, void 0, function () {
112
+ var _a, delaysInMs, _b, maxRetries, delayInMs, e_1;
113
+ return tslib.__generator(this, function (_c) {
114
+ switch (_c.label) {
115
+ case 0:
116
+ _a = opts.delaysInMs, delaysInMs = _a === void 0 ? [] : _a, _b = opts.maxRetries, maxRetries = _b === void 0 ? 1 : _b;
117
+ _c.label = 1;
118
+ case 1:
119
+ _c.trys.push([1, 4, , 8]);
120
+ delayInMs = attempt === 0 || delaysInMs.length === 0
121
+ ? 0
122
+ : delaysInMs[Math.min(attempt - 1, delaysInMs.length - 1)];
123
+ return [4 /*yield*/, delay(delayInMs)];
124
+ case 2:
125
+ _c.sent();
126
+ return [4 /*yield*/, process()];
127
+ case 3: return [2 /*return*/, _c.sent()];
128
+ case 4:
129
+ e_1 = _c.sent();
130
+ if (!(attempt < maxRetries)) return [3 /*break*/, 6];
131
+ return [4 /*yield*/, execute(attempt + 1, process, opts)];
132
+ case 5: return [2 /*return*/, _c.sent()];
133
+ case 6: throw e_1;
134
+ case 7: return [3 /*break*/, 8];
135
+ case 8: return [2 /*return*/];
136
+ }
137
+ });
138
+ });
50
139
  }
140
+ return tslib.__generator(this, function (_a) {
141
+ return [2 /*return*/, execute(0, process, opts)];
142
+ });
143
+ });
144
+ }
145
+ /**
146
+ * Returns a promise that either resolves with the result of `promise`, or a
147
+ * value that indicates the execution was aborted.
148
+ *
149
+ * **Note:** Because Promises in JS cannot be canceled, an abort signal will not
150
+ * cancel the execution of the promise.
151
+ *
152
+ * @param signal A signal that communicates the process should be aborted.
153
+ * @param promise A promise who's value will be returned if not aborted.
154
+ * @returns A value indicating if the process was aborted, or the value of
155
+ * `promise`.
156
+ */
157
+ function abort(signal, promise) {
158
+ return tslib.__awaiter(this, void 0, void 0, function () {
159
+ var controller, pendingAbort, result;
160
+ return tslib.__generator(this, function (_a) {
161
+ switch (_a.label) {
162
+ case 0:
163
+ controller = new AbortController();
164
+ pendingAbort = once(signal, 'abort', { signal: controller.signal });
165
+ return [4 /*yield*/, Promise.race([promise, pendingAbort])];
166
+ case 1:
167
+ result = _a.sent();
168
+ if (isAbortEvent(result)) {
169
+ return [2 /*return*/, { aborted: true }];
170
+ }
171
+ else {
172
+ controller.abort();
173
+ return [2 /*return*/, { aborted: false, result: result }];
174
+ }
175
+ }
176
+ });
177
+ });
178
+ }
179
+ function isAbortEvent(obj) {
180
+ if (obj instanceof Event) {
181
+ return obj.type === 'abort';
51
182
  }
52
- else {
53
- return Promise.reject('First argument to `timeout` must be a number');
54
- }
183
+ else
184
+ return false;
55
185
  }
56
186
 
57
187
  var async = /*#__PURE__*/Object.freeze({
58
188
  __proto__: null,
59
189
  delay: delay,
60
- timeout: timeout
190
+ timeout: timeout,
191
+ retry: retry,
192
+ abort: abort
61
193
  });
62
194
 
63
195
  /**
@@ -187,7 +319,7 @@ var isOpaque = function (color) {
187
319
  * `#`.
188
320
  */
189
321
  var toHexString = function (color) {
190
- return "#" + componentToHex(color.r) + componentToHex(color.g) + componentToHex(color.b);
322
+ return "#".concat(componentToHex(color.r)).concat(componentToHex(color.g)).concat(componentToHex(color.b));
191
323
  };
192
324
  var componentToHex = function (num) {
193
325
  var hex = num.toString(16);
@@ -282,8 +414,9 @@ var color = /*#__PURE__*/Object.freeze({
282
414
  var MapperValidationError = /** @class */ (function (_super) {
283
415
  tslib.__extends(MapperValidationError, _super);
284
416
  function MapperValidationError(errors) {
285
- var _this = _super.call(this, 'Validation error while mapping object.') || this;
417
+ var _this = _super.call(this, 'Validation error mapping object.') || this;
286
418
  _this.errors = errors;
419
+ Object.setPrototypeOf(_this, MapperValidationError.prototype);
287
420
  return _this;
288
421
  }
289
422
  return MapperValidationError;
@@ -299,7 +432,7 @@ function required(name) {
299
432
  return input;
300
433
  }
301
434
  else {
302
- return { errors: [name + " is required."] };
435
+ return { errors: ["".concat(name, " is required.")] };
303
436
  }
304
437
  };
305
438
  }
@@ -317,7 +450,7 @@ function requiredProp(prop) {
317
450
  return value;
318
451
  }
319
452
  else {
320
- return { errors: [prop + " is required"] };
453
+ return { errors: ["".concat(prop, " is required")] };
321
454
  }
322
455
  };
323
456
  }
@@ -2848,7 +2981,7 @@ var isEqual = function (a, b) {
2848
2981
  queryA === queryB);
2849
2982
  };
2850
2983
  var replacePath = function (path, uri) {
2851
- var pathWithForwardSlash = path[0] === '/' ? path : "/" + path;
2984
+ var pathWithForwardSlash = path[0] === '/' ? path : "/".concat(path);
2852
2985
  return tslib.__assign(tslib.__assign({}, uri), { path: pathWithForwardSlash });
2853
2986
  };
2854
2987
  var pathAsArray = function (uri) {
@@ -2924,17 +3057,17 @@ var queryAsMap = function (uri) {
2924
3057
  var toString = function (uri) {
2925
3058
  var result = '';
2926
3059
  if (uri.scheme != null && uri.scheme.length > 0) {
2927
- result = uri.scheme + ":";
3060
+ result = "".concat(uri.scheme, ":");
2928
3061
  }
2929
3062
  if (uri.authority != null && uri.authority.length > 0) {
2930
- result += "//" + uri.authority;
3063
+ result += "//".concat(uri.authority);
2931
3064
  }
2932
3065
  result += uri.path;
2933
3066
  if (uri.query != null && uri.query.length > 0) {
2934
- result += "?" + uri.query;
3067
+ result += "?".concat(uri.query);
2935
3068
  }
2936
3069
  if (uri.fragment != null && uri.fragment.length > 0) {
2937
- result += "#" + uri.fragment;
3070
+ result += "#".concat(uri.fragment);
2938
3071
  }
2939
3072
  return result;
2940
3073
  };
@@ -3128,10 +3261,50 @@ var EventDispatcher = /** @class */ (function () {
3128
3261
  function EventDispatcher() {
3129
3262
  this.listeners = [];
3130
3263
  }
3131
- EventDispatcher.prototype.on = function (listener) {
3264
+ EventDispatcher.prototype.on = function (listener, opts) {
3132
3265
  var _this = this;
3266
+ var _a;
3267
+ if (opts === void 0) { opts = {}; }
3133
3268
  this.listeners.push(listener);
3134
- return { dispose: function () { return _this.off(listener); } };
3269
+ var controller = new AbortController();
3270
+ controller.signal.addEventListener('abort', function () { return _this.off(listener); });
3271
+ (_a = opts.abort) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', function () { return controller.abort(); });
3272
+ return { dispose: function () { return controller.abort(); } };
3273
+ };
3274
+ EventDispatcher.prototype.once = function (opts) {
3275
+ var _this = this;
3276
+ if (opts === void 0) { opts = {}; }
3277
+ return new Promise(function (resolve) {
3278
+ _this.on(function (event) { return resolve(event); }, opts);
3279
+ });
3280
+ };
3281
+ EventDispatcher.prototype.onceWhen = function (predicate, opts) {
3282
+ var _a;
3283
+ if (opts === void 0) { opts = {}; }
3284
+ return tslib.__awaiter(this, void 0, void 0, function () {
3285
+ var controller;
3286
+ var _this = this;
3287
+ return tslib.__generator(this, function (_b) {
3288
+ controller = new AbortController();
3289
+ (_a = opts.abort) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', function () { return controller.abort(); });
3290
+ return [2 /*return*/, new Promise(function (resolve) {
3291
+ _this.when(predicate, function (event) {
3292
+ if (predicate(event)) {
3293
+ controller.abort();
3294
+ resolve(event);
3295
+ }
3296
+ }, tslib.__assign(tslib.__assign({}, opts), { abort: controller.signal }));
3297
+ })];
3298
+ });
3299
+ });
3300
+ };
3301
+ EventDispatcher.prototype.when = function (predicate, listener, opts) {
3302
+ if (opts === void 0) { opts = {}; }
3303
+ return this.on(function (event) {
3304
+ if (predicate(event)) {
3305
+ listener(event);
3306
+ }
3307
+ }, opts);
3135
3308
  };
3136
3309
  EventDispatcher.prototype.off = function (listener) {
3137
3310
  var index = this.listeners.indexOf(listener);
@@ -3149,6 +3322,7 @@ exports.Async = async;
3149
3322
  exports.BinaryReader = binaryReader;
3150
3323
  exports.Color = color;
3151
3324
  exports.EventDispatcher = EventDispatcher;
3325
+ exports.EventTargets = eventTargets;
3152
3326
  exports.Mapper = mapper;
3153
3327
  exports.Objects = objects;
3154
3328
  exports.Range = range;