aveazul 1.0.2 → 2.0.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/lib/aveazul.js DELETED
@@ -1,645 +0,0 @@
1
- "use strict";
2
-
3
- const xaa = require("xaa");
4
- const { promisify } = require("./promisify");
5
- const { promisifyAll } = require("./promisify-all");
6
- const { Disposer } = require("./disposer");
7
- const { using } = require("./using");
8
- const { isPromise, triggerUncaughtException, toArray } = require("./util");
9
- const { AggregateError } = require("@jchip/error");
10
- const { OperationalError, isOperationalError } = require("./operational-error");
11
- /**
12
- * @fileoverview
13
- * AveAzul ("Blue Bird" in Spanish) - Extended Promise class that provides Bluebird like utility methods
14
- * This implementation is inspired by and provides similar APIs to the Bluebird Promise library,
15
- * but built on top of native Promises. The name is a Spanish play on words referencing Bluebird.
16
- * @extends Promise
17
- */
18
- class AveAzul extends Promise {
19
- constructor(executor) {
20
- super(executor);
21
- }
22
-
23
- /**
24
- * Note: Per ECMAScript specification, when extending Promise, both .then() and static methods
25
- * (resolve, reject, all, etc) must return instances of the derived class (AveAzul), so there's
26
- * no need to explicitly wrap returns in new AveAzul(). This behavior is standard across all
27
- * spec-compliant JS engines (V8, SpiderMonkey, JavaScriptCore, etc).
28
- */
29
-
30
- /**
31
- * Bluebird-style tap() method that lets you perform side effects in a chain
32
- * Similar to Bluebird's Promise.prototype.tap()
33
- * @param {Function} fn - Function to execute with the resolved value
34
- * @returns {Promise} Promise that resolves with the original value
35
- */
36
- tap(fn) {
37
- return this.then(async (value) => {
38
- await fn(value);
39
- return value;
40
- });
41
- }
42
-
43
- /**
44
- * Bluebird-style filter() method for array operations
45
- * Similar to Bluebird's Promise.prototype.filter()
46
- * @param {Function} fn - Filter function to apply to each element
47
- * @returns {Promise} Promise that resolves with the filtered array
48
- */
49
- filter(fn) {
50
- return this.then((value) => xaa.filter(value, fn));
51
- }
52
-
53
- /**
54
- * Bluebird-style map() method for array operations
55
- * Similar to Bluebird's Promise.prototype.map()
56
- * @param {Function} fn - Map function to apply to each element
57
- * @returns {Promise} Promise that resolves with the mapped array
58
- */
59
- map(fn, options = { concurrency: 50 }) {
60
- return this.then((value) => xaa.map(value, fn, options));
61
- }
62
-
63
- /**
64
- * Bluebird-style mapSeries() method for array operations
65
- * Similar to Bluebird's Promise.prototype.mapSeries()
66
- * @param {Function} fn - Map function to apply to each element
67
- * @returns {Promise} Promise that resolves with the mapped array
68
- */
69
- mapSeries(fn) {
70
- return this.map(fn, { concurrency: 1 });
71
- }
72
-
73
- /**
74
- * Bluebird-style return() method to inject a value into the chain
75
- * Similar to Bluebird's Promise.prototype.return()
76
- * @param {*} value - Value to return
77
- * @returns {Promise} Promise that resolves with the new value
78
- */
79
- return(value) {
80
- return this.then(() => value);
81
- }
82
-
83
- /**
84
- * Bluebird-style any() method for waiting for any promises to resolve
85
- * @param {Array|Iterable} promises - Array or iterable of promises
86
- * @returns {Promise} Promise that resolves with the first resolved promise
87
- */
88
- any() {
89
- return this.then((args) => {
90
- return AveAzul.any(toArray(args));
91
- });
92
- }
93
-
94
- /**
95
- * Bluebird-style each() method for array iteration
96
- * Similar to Bluebird's Promise.prototype.each()
97
- * @param {Function} fn - Function to execute for each element
98
- * @returns {Promise} Promise that resolves when iteration is complete
99
- */
100
- each(fn) {
101
- return this.then(async (value) => {
102
- const result = [];
103
- for (let i = 0; i < value.length; i++) {
104
- let x = value[i];
105
- if (isPromise(x)) {
106
- x = await x;
107
- }
108
- await fn(x, i, value.length);
109
- result.push(x);
110
- }
111
- return result;
112
- });
113
- }
114
-
115
- /**
116
- * Bluebird-style delay() method
117
- * @param {number} ms - Milliseconds to delay
118
- * @returns {Promise} Promise that resolves after the delay
119
- */
120
- delay(ms) {
121
- return xaa.delay(ms);
122
- }
123
-
124
- /**
125
- * Bluebird-style timeout() method
126
- * @param {number} ms - Milliseconds before timeout
127
- * @param {string} [message] - Optional error message
128
- * @returns {Promise} Promise that rejects if timeout occurs
129
- */
130
- timeout(ms, message = "operation timed out") {
131
- return xaa
132
- .timeout(ms, message, {
133
- Promise: AveAzul,
134
- TimeoutError: OperationalError,
135
- })
136
- .run(this);
137
- }
138
-
139
- /**
140
- * Bluebird-style props() for object properties
141
- * @param {Object} obj - Object with promise values
142
- * @returns {Promise} Promise that resolves with an object of resolved values
143
- */
144
- props() {
145
- return this.then((value) => {
146
- const keys = Object.keys(value);
147
- const values = keys.map((k) => value[k]);
148
-
149
- return AveAzul.all(values).then((results) => {
150
- const resolved = {};
151
- keys.forEach((k, i) => {
152
- resolved[k] = results[i];
153
- });
154
- return resolved;
155
- });
156
- });
157
- }
158
-
159
- /**
160
- * Bluebird-style tapCatch() for side effects on rejection
161
- * @param {Function} fn - Function to execute on rejection
162
- * @returns {Promise} Promise that maintains the rejection
163
- */
164
- tapCatch(fn) {
165
- return this.catch((err) => {
166
- fn(err);
167
- throw err;
168
- });
169
- }
170
-
171
- /**
172
- * Bluebird-style reduce() method for array reduction
173
- * Similar to Bluebird's Promise.prototype.reduce()
174
- * @param {Function} fn - Reducer function to apply to each element
175
- * @param {*} [initialValue] - Optional initial value
176
- * @returns {Promise} Promise that resolves with the final reduced value
177
- */
178
- reduce(fn, initialValue) {
179
- const hasInitial = arguments.length > 1;
180
-
181
- return this.then(async (array) => {
182
- const len = array.length;
183
- let value;
184
- let idx;
185
- if (hasInitial) {
186
- idx = 0;
187
- value = initialValue;
188
- } else {
189
- idx = 1;
190
- value = array[0];
191
- }
192
-
193
- value = isPromise(value) ? await value : value;
194
-
195
- for (; idx < len; idx++) {
196
- let x = array[idx];
197
- if (isPromise(x)) {
198
- x = await x;
199
- }
200
- value = await fn(value, x, idx, len);
201
- }
202
-
203
- return value;
204
- });
205
- }
206
-
207
- /**
208
- * Bluebird-style throw() that returns a rejected promise with the given reason
209
- * @param {*} reason - Value to reject the promise with
210
- * @returns {Promise} Promise that rejects with the given reason
211
- */
212
- throw(reason) {
213
- return AveAzul.reject(reason);
214
- }
215
-
216
- /**
217
- * Bluebird-style catchThrow() that catches an error and throws a new one
218
- * @param {*} reason - Value to reject the promise with
219
- * @returns {Promise} Promise that rejects with the new reason
220
- */
221
- catchThrow(reason) {
222
- return this.catch(() => {
223
- throw reason;
224
- });
225
- }
226
-
227
- /**
228
- * Bluebird-style catchReturn() that catches an error and returns a value instead
229
- * @param {*} value - Value to return
230
- * @returns {Promise} Promise that resolves with the given value
231
- */
232
- catchReturn(value) {
233
- return this.catch(() => value);
234
- }
235
-
236
- /**
237
- * Bluebird-style get() for retrieving a property value
238
- * @param {string|number} key - Key to retrieve
239
- * @returns {Promise} Promise that resolves with the property value
240
- */
241
- get(key) {
242
- return this.then((value) => value[key]);
243
- }
244
-
245
- /**
246
- * Bluebird-style disposer() for resource cleanup
247
- * @param {Function} fn - Cleanup function
248
- * @returns {Disposer} Disposer object
249
- */
250
- disposer(fn) {
251
- if (typeof fn !== "function") {
252
- throw new TypeError("Expected a function");
253
- }
254
-
255
- return new Disposer(fn, this);
256
- }
257
-
258
- /**
259
- * Bluebird-style spread() method for handling array arguments
260
- * Similar to Bluebird's Promise.prototype.spread()
261
- * @param {Function} fn - Function to apply to the array arguments
262
- * @returns {Promise} Promise that resolves with the function's return value
263
- */
264
- spread(fn) {
265
- if (typeof fn !== "function") {
266
- return AveAzul.reject(
267
- new TypeError("expecting a function but got " + fn)
268
- );
269
- }
270
-
271
- return this.then(async (args) => {
272
- if (Array.isArray(args)) {
273
- for (let i = 0; i < args.length; i++) {
274
- if (isPromise(args[i])) {
275
- args[i] = await args[i];
276
- }
277
- }
278
- return fn(...args);
279
- } else {
280
- return fn(args);
281
- }
282
- });
283
- }
284
-
285
- some(count) {
286
- return this.then((args) => {
287
- args = toArray(args);
288
-
289
- return new AveAzul((resolve, reject) => {
290
- // If too many promises are rejected so that the promise can never become fulfilled,
291
- // it will be immediately rejected with an AggregateError of the rejection reasons
292
- // in the order they were thrown in.
293
- const errors = [];
294
- // The fulfillment value is an array with count values
295
- // in the order they were fulfilled.
296
- const results = [];
297
- const len = args.length;
298
-
299
- let settled = false;
300
-
301
- const addDone = (result) => {
302
- if (settled) return;
303
- results.push(result);
304
- if (results.length >= count) {
305
- settled = true;
306
- // Resolve with exactly count results to match Bluebird's behavior
307
- resolve(results.slice(0, count));
308
- }
309
- };
310
-
311
- const addError = (err) => {
312
- if (settled) return;
313
- errors.push(err);
314
- if (len - errors.length < count) {
315
- settled = true;
316
- reject(new AggregateError(errors, `aggregate error`));
317
- }
318
- };
319
-
320
- for (let i = 0; i < len; i++) {
321
- const x = args[i];
322
- if (isPromise(x)) {
323
- x.then(addDone, addError);
324
- } else {
325
- addDone(x);
326
- }
327
- }
328
- });
329
- });
330
- }
331
-
332
- /**
333
- * Bluebird-style all() method for array operations
334
- * Similar to Promise.all() but operates on the resolved value of this promise
335
- * @returns {Promise} Promise that resolves when all items in the array resolve
336
- */
337
- all() {
338
- return this.then((value) => {
339
- return AveAzul.all(toArray(value));
340
- });
341
- }
342
-
343
- /**
344
- * Bluebird-style asCallback() method
345
- * Attaches a callback to the promise and returns the promise.
346
- * The callback is invoked when the promise is resolved or rejected.
347
- *
348
- * @param {Function} cb - Node.js-style callback function (err, value)
349
- * @param {Object} [options] - Additional options
350
- * @param {boolean} [options.spread=false] - Pass array values as arguments to callback
351
- * @returns {Promise} The same promise instance
352
- */
353
- asCallback(cb, options = {}) {
354
- if (typeof cb !== "function") {
355
- return this;
356
- }
357
-
358
- const spread = options && options.spread === true;
359
-
360
- this.then(
361
- (value) => {
362
- try {
363
- if (spread && Array.isArray(value)) {
364
- cb(null, ...value);
365
- } else {
366
- cb(null, value);
367
- }
368
- } catch (err) {
369
- AveAzul.___throwUncaughtError(err);
370
- }
371
- },
372
- (reason) => {
373
- try {
374
- cb(reason);
375
- } catch (err) {
376
- AveAzul.___throwUncaughtError(err);
377
- }
378
- }
379
- );
380
-
381
- return this;
382
- }
383
-
384
- nodeify(cb, options) {
385
- return this.asCallback(cb, options);
386
- }
387
-
388
- /**
389
- * Bluebird-style call() method for calling a method on the resolved value
390
- * @param {string} methodName - Name of the method to call
391
- * @param {...any} args - Arguments to pass to the method
392
- * @returns {Promise} Promise that resolves with the method's return value
393
- */
394
- call(methodName, ...args) {
395
- return this.then(function (obj) {
396
- return obj[methodName].call(obj, ...args);
397
- });
398
- }
399
-
400
- /**
401
- * Catches only operational errors and passes them to the handler.
402
- * Programmer errors (non-operational) are rethrown.
403
- * @param {Function} handler - Function to handle operational errors
404
- * @returns {Promise} - Promise with the error handled or rethrown
405
- */
406
- error(handler) {
407
- return this.catch((err) => {
408
- if (isOperationalError(err)) {
409
- return handler(err);
410
- }
411
- throw err;
412
- });
413
- }
414
- }
415
-
416
- /**
417
- * Static helper methods
418
- */
419
-
420
- /**
421
- * Bluebird-style delay() that resolves after specified milliseconds
422
- * @param {number} ms - Milliseconds to delay
423
- * @param {*} [value] - Optional value to resolve with
424
- * @returns {Promise} Promise that resolves after the delay
425
- */
426
- AveAzul.delay = (ms, value) => {
427
- if (value === undefined) {
428
- return AveAzul.resolve(xaa.delay(ms));
429
- }
430
- return AveAzul.resolve(xaa.delay(ms, value));
431
- };
432
-
433
- /**
434
- * Bluebird-style map() for array operations
435
- * @param {Array} value - Array to map over
436
- * @param {Function} fn - Map function to apply to each element
437
- * @returns {Promise} Promise that resolves with the mapped array
438
- */
439
- AveAzul.map = (value, fn, options = { concurrency: 50 }) =>
440
- AveAzul.resolve(value).map(fn, options);
441
-
442
- /**
443
- * Bluebird-style mapSeries() for array operations
444
- * @param {Array} value - Array to map over
445
- * @param {Function} fn - Map function to apply to each element
446
- * @returns {Promise} Promise that resolves with the mapped array
447
- */
448
- AveAzul.mapSeries = (value, fn) => AveAzul.map(value, fn, { concurrency: 1 });
449
-
450
- /**
451
- * Bluebird-style try() for wrapping sync/async functions
452
- * @param {Function} fn - Function to execute
453
- * @returns {Promise} Promise that resolves with the function's return value
454
- */
455
- AveAzul.try = (fn) => AveAzul.resolve(xaa.wrap(fn));
456
-
457
- /**
458
- * Bluebird-style props() for object properties
459
- * @param {Object} obj - Object with promise values
460
- * @returns {Promise} Promise that resolves with an object of resolved values
461
- */
462
- AveAzul.props = (obj) => {
463
- const keys = Object.keys(obj);
464
- const values = keys.map((k) => obj[k]);
465
-
466
- return AveAzul.all(values).then((results) => {
467
- const resolved = {};
468
- keys.forEach((k, i) => {
469
- resolved[k] = results[i];
470
- });
471
- return resolved;
472
- });
473
- };
474
-
475
- /**
476
- * Bluebird-style defer() for creating a deferred promise
477
- * @returns {Object} Deferred object with promise, resolve, and reject methods
478
- */
479
- AveAzul.defer = () => {
480
- return xaa.makeDefer(AveAzul);
481
- };
482
-
483
- /**
484
- * Bluebird-style each() for array iteration
485
- * @param {Array} items - Array to iterate over
486
- * @param {Function} fn - Iterator function to call for each item
487
- * @returns {Promise} Promise that resolves when iteration is complete
488
- */
489
- AveAzul.each = function (items, fn) {
490
- return AveAzul.resolve(items).each(fn);
491
- };
492
-
493
- /**
494
- * Bluebird-style reduce() for array reduction
495
- * @param {Array} array - Array to reduce
496
- * @param {Function} fn - Reducer function (value, item, index, length)
497
- * @param {*} [initialValue] - Optional initial value
498
- * @returns {Promise} Promise that resolves with the final reduced value
499
- */
500
- AveAzul.reduce = function (array, ...args) {
501
- return AveAzul.resolve(array).reduce(...args);
502
- };
503
-
504
- /**
505
- * Bluebird-style promisify() for converting callback-based functions to promises
506
- * @param {Function} fn - Function to promisify
507
- * @param {Object} [options] - Options object
508
- * @returns {Function} Promisified function
509
- */
510
- AveAzul.promisify = (fn, options) => {
511
- return promisify(fn, {
512
- ...options,
513
- Promise: AveAzul,
514
- });
515
- };
516
-
517
- /**
518
- * Bluebird-style promisifyAll() for converting callback-based functions to promises
519
- * @param {Object} target - Object to promisify
520
- * @param {Object} [options] - Options object
521
- * @returns {Object} Object with promisified methods
522
- */
523
- AveAzul.promisifyAll = (target, options) => {
524
- return promisifyAll(target, { ...options, Promise: AveAzul });
525
- };
526
-
527
- /**
528
- * Bluebird-style method() for creating a method that returns a promise
529
- * @param {Function} fn - Function to create a method for
530
- * @returns {Function} Method function that returns a promise
531
- */
532
- AveAzul.method = (fn) => {
533
- return function (...args) {
534
- return new AveAzul((resolve, reject) => {
535
- try {
536
- const result = fn.call(this, ...args);
537
- resolve(result);
538
- } catch (error) {
539
- reject(error);
540
- }
541
- });
542
- };
543
- };
544
-
545
- /**
546
- * Bluebird-style using() for resource management. There is only a static version of this method.
547
- * After the handler finish and returns, regardless of whether it resolves or rejects, the resources will be disposed.
548
- *
549
- * @param {Disposer|Array<Disposer>} resources - Resource disposers, either an array of disposers or a variadic argument list
550
- * @param {Function} handler - Handler function that will receive the resources as arguments
551
- * @returns {Promise} Promise that resolves with handler result
552
- */
553
- AveAzul.using = (resources, ...args) => {
554
- if (args.length === 0) {
555
- throw new TypeError("resrouces and handler function required");
556
- }
557
-
558
- if (Array.isArray(resources)) {
559
- if (args.length > 1) {
560
- throw new TypeError(
561
- "only two arguments are allowed when passing an array of resources"
562
- );
563
- }
564
- return using(resources, args[0], AveAzul, true);
565
- }
566
- const handler = args.pop();
567
- return using([resources, ...args], handler, AveAzul, false);
568
- };
569
-
570
- /**
571
- * Bluebird-style join() for joining promises
572
- *
573
- * @param {...Promise} args - Promises to join
574
- * @param {Function} handler - Handler function to apply to the joined results
575
- * @returns {Promise} Promise that resolves with the handler's return value
576
- */
577
- AveAzul.join = function (...args) {
578
- if (args.length > 1 && typeof args[args.length - 1] === "function") {
579
- const handler = args.pop();
580
- return AveAzul.all(args).then((results) => handler(...results));
581
- } else {
582
- return AveAzul.all(args);
583
- }
584
- };
585
-
586
- function fromCallback(fn, options) {
587
- return new AveAzul((resolve, reject) => {
588
- try {
589
- fn((err, ...args) => {
590
- if (err) {
591
- reject(err);
592
- } else {
593
- if (options && options.multiArgs) {
594
- resolve(args);
595
- } else {
596
- resolve(args[0]);
597
- }
598
- }
599
- });
600
- } catch (err) {
601
- reject(err);
602
- }
603
- });
604
- }
605
-
606
- AveAzul.fromNode = fromCallback;
607
-
608
- /**
609
- * Bluebird-style fromCallback() for converting callback-based functions to promises
610
- * @param {Function} fn - Function to convert
611
- * @param {Object} [options] - Options object
612
- * @returns {Promise} Promise that resolves with the function's return value
613
- */
614
- AveAzul.fromCallback = fromCallback;
615
-
616
- /**
617
- * @description
618
- * When fatal error and AveAzul needs to crash the process,
619
- * this method is used to throw the error.
620
- *
621
- * @param {Error} error - The error to throw.
622
- */
623
- AveAzul.___throwUncaughtError = triggerUncaughtException;
624
-
625
- /**
626
- * Bluebird-style some() for waiting for some promises to resolve
627
- * @param {Array|Iterable} promises - Array or iterable of promises
628
- * @param {number} count - Number of promises that need to resolve
629
- * @returns {Promise} Promise that resolves when count promises have resolved
630
- */
631
- AveAzul.some = function (promises, count) {
632
- return AveAzul.resolve(promises).some(count);
633
- };
634
-
635
- const { addStaticAny } = require("./any");
636
- addStaticAny(AveAzul);
637
-
638
- // Setup the not implemented methods
639
- const { setupNotImplemented } = require("./not-implemented");
640
- setupNotImplemented(AveAzul);
641
-
642
- // Add these static properties after the class definition
643
- AveAzul.OperationalError = OperationalError;
644
-
645
- module.exports = AveAzul;
package/lib/disposer.js DELETED
@@ -1,14 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * Disposer class for resource cleanup
5
- * @private
6
- */
7
- class Disposer {
8
- constructor(fn, promise) {
9
- this._data = fn; // The cleanup function
10
- this._promise = promise; // The promise that resolves to the resource
11
- }
12
- }
13
-
14
- module.exports.Disposer = Disposer;