- Add GETTING_STARTED.md with quick start guide and development modes - Add INSTALL.sh automated installation script - Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md - Add QUICK_REFERENCE.md for common commands - Add SETUP_GUIDE.md with detailed setup instructions - Update README.md with improved project overview - Add did-wallet app dependencies and node_modules
332 lines
18 KiB
JavaScript
332 lines
18 KiB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
};
|
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
};
|
|
var _PQueue_instances, _PQueue_carryoverConcurrencyCount, _PQueue_isIntervalIgnored, _PQueue_intervalCount, _PQueue_intervalCap, _PQueue_interval, _PQueue_intervalEnd, _PQueue_intervalId, _PQueue_timeoutId, _PQueue_queue, _PQueue_queueClass, _PQueue_pending, _PQueue_concurrency, _PQueue_isPaused, _PQueue_throwOnTimeout, _PQueue_doesIntervalAllowAnother_get, _PQueue_doesConcurrentAllowAnother_get, _PQueue_next, _PQueue_onResumeInterval, _PQueue_isIntervalPaused_get, _PQueue_tryToStartAnother, _PQueue_initializeIntervalIfNeeded, _PQueue_onInterval, _PQueue_processQueue, _PQueue_throwOnAbort, _PQueue_onEvent;
|
|
import { EventEmitter } from 'eventemitter3';
|
|
import pTimeout, { TimeoutError } from 'p-timeout';
|
|
import PriorityQueue from './priority-queue.js';
|
|
/**
|
|
The error thrown by `queue.add()` when a job is aborted before it is run. See `signal`.
|
|
*/
|
|
export class AbortError extends Error {
|
|
}
|
|
/**
|
|
Promise queue with concurrency control.
|
|
*/
|
|
class PQueue extends EventEmitter {
|
|
// TODO: The `throwOnTimeout` option should affect the return types of `add()` and `addAll()`
|
|
constructor(options) {
|
|
var _a, _b, _c, _d;
|
|
super();
|
|
_PQueue_instances.add(this);
|
|
_PQueue_carryoverConcurrencyCount.set(this, void 0);
|
|
_PQueue_isIntervalIgnored.set(this, void 0);
|
|
_PQueue_intervalCount.set(this, 0);
|
|
_PQueue_intervalCap.set(this, void 0);
|
|
_PQueue_interval.set(this, void 0);
|
|
_PQueue_intervalEnd.set(this, 0);
|
|
_PQueue_intervalId.set(this, void 0);
|
|
_PQueue_timeoutId.set(this, void 0);
|
|
_PQueue_queue.set(this, void 0);
|
|
_PQueue_queueClass.set(this, void 0);
|
|
_PQueue_pending.set(this, 0);
|
|
// The `!` is needed because of https://github.com/microsoft/TypeScript/issues/32194
|
|
_PQueue_concurrency.set(this, void 0);
|
|
_PQueue_isPaused.set(this, void 0);
|
|
_PQueue_throwOnTimeout.set(this, void 0);
|
|
/**
|
|
Per-operation timeout in milliseconds. Operations fulfill once `timeout` elapses if they haven't already.
|
|
|
|
Applies to each future operation.
|
|
*/
|
|
Object.defineProperty(this, "timeout", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: void 0
|
|
});
|
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
options = {
|
|
carryoverConcurrencyCount: false,
|
|
intervalCap: Number.POSITIVE_INFINITY,
|
|
interval: 0,
|
|
concurrency: Number.POSITIVE_INFINITY,
|
|
autoStart: true,
|
|
queueClass: PriorityQueue,
|
|
...options,
|
|
};
|
|
if (!(typeof options.intervalCap === 'number' && options.intervalCap >= 1)) {
|
|
throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${(_b = (_a = options.intervalCap) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : ''}\` (${typeof options.intervalCap})`);
|
|
}
|
|
if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) {
|
|
throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${(_d = (_c = options.interval) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : ''}\` (${typeof options.interval})`);
|
|
}
|
|
__classPrivateFieldSet(this, _PQueue_carryoverConcurrencyCount, options.carryoverConcurrencyCount, "f");
|
|
__classPrivateFieldSet(this, _PQueue_isIntervalIgnored, options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0, "f");
|
|
__classPrivateFieldSet(this, _PQueue_intervalCap, options.intervalCap, "f");
|
|
__classPrivateFieldSet(this, _PQueue_interval, options.interval, "f");
|
|
__classPrivateFieldSet(this, _PQueue_queue, new options.queueClass(), "f");
|
|
__classPrivateFieldSet(this, _PQueue_queueClass, options.queueClass, "f");
|
|
this.concurrency = options.concurrency;
|
|
this.timeout = options.timeout;
|
|
__classPrivateFieldSet(this, _PQueue_throwOnTimeout, options.throwOnTimeout === true, "f");
|
|
__classPrivateFieldSet(this, _PQueue_isPaused, options.autoStart === false, "f");
|
|
}
|
|
get concurrency() {
|
|
return __classPrivateFieldGet(this, _PQueue_concurrency, "f");
|
|
}
|
|
set concurrency(newConcurrency) {
|
|
if (!(typeof newConcurrency === 'number' && newConcurrency >= 1)) {
|
|
throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${newConcurrency}\` (${typeof newConcurrency})`);
|
|
}
|
|
__classPrivateFieldSet(this, _PQueue_concurrency, newConcurrency, "f");
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_processQueue).call(this);
|
|
}
|
|
async add(function_, options = {}) {
|
|
options = {
|
|
timeout: this.timeout,
|
|
throwOnTimeout: __classPrivateFieldGet(this, _PQueue_throwOnTimeout, "f"),
|
|
...options,
|
|
};
|
|
return new Promise((resolve, reject) => {
|
|
__classPrivateFieldGet(this, _PQueue_queue, "f").enqueue(async () => {
|
|
var _a;
|
|
var _b, _c;
|
|
__classPrivateFieldSet(this, _PQueue_pending, (_b = __classPrivateFieldGet(this, _PQueue_pending, "f"), _b++, _b), "f");
|
|
__classPrivateFieldSet(this, _PQueue_intervalCount, (_c = __classPrivateFieldGet(this, _PQueue_intervalCount, "f"), _c++, _c), "f");
|
|
try {
|
|
// TODO: Use options.signal?.throwIfAborted() when targeting Node.js 18
|
|
if ((_a = options.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
|
|
// TODO: Use ABORT_ERR code when targeting Node.js 16 (https://nodejs.org/docs/latest-v16.x/api/errors.html#abort_err)
|
|
throw new AbortError('The task was aborted.');
|
|
}
|
|
let operation = function_({ signal: options.signal });
|
|
if (options.timeout) {
|
|
operation = pTimeout(Promise.resolve(operation), options.timeout);
|
|
}
|
|
if (options.signal) {
|
|
operation = Promise.race([operation, __classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_throwOnAbort).call(this, options.signal)]);
|
|
}
|
|
const result = await operation;
|
|
resolve(result);
|
|
this.emit('completed', result);
|
|
}
|
|
catch (error) {
|
|
if (error instanceof TimeoutError && !options.throwOnTimeout) {
|
|
resolve();
|
|
return;
|
|
}
|
|
reject(error);
|
|
this.emit('error', error);
|
|
}
|
|
finally {
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_next).call(this);
|
|
}
|
|
}, options);
|
|
this.emit('add');
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_tryToStartAnother).call(this);
|
|
});
|
|
}
|
|
async addAll(functions, options) {
|
|
return Promise.all(functions.map(async (function_) => this.add(function_, options)));
|
|
}
|
|
/**
|
|
Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.)
|
|
*/
|
|
start() {
|
|
if (!__classPrivateFieldGet(this, _PQueue_isPaused, "f")) {
|
|
return this;
|
|
}
|
|
__classPrivateFieldSet(this, _PQueue_isPaused, false, "f");
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_processQueue).call(this);
|
|
return this;
|
|
}
|
|
/**
|
|
Put queue execution on hold.
|
|
*/
|
|
pause() {
|
|
__classPrivateFieldSet(this, _PQueue_isPaused, true, "f");
|
|
}
|
|
/**
|
|
Clear the queue.
|
|
*/
|
|
clear() {
|
|
__classPrivateFieldSet(this, _PQueue_queue, new (__classPrivateFieldGet(this, _PQueue_queueClass, "f"))(), "f");
|
|
}
|
|
/**
|
|
Can be called multiple times. Useful if you for example add additional items at a later time.
|
|
|
|
@returns A promise that settles when the queue becomes empty.
|
|
*/
|
|
async onEmpty() {
|
|
// Instantly resolve if the queue is empty
|
|
if (__classPrivateFieldGet(this, _PQueue_queue, "f").size === 0) {
|
|
return;
|
|
}
|
|
await __classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_onEvent).call(this, 'empty');
|
|
}
|
|
/**
|
|
@returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`.
|
|
|
|
If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item.
|
|
|
|
Note that this only limits the number of items waiting to start. There could still be up to `concurrency` jobs already running that this call does not include in its calculation.
|
|
*/
|
|
async onSizeLessThan(limit) {
|
|
// Instantly resolve if the queue is empty.
|
|
if (__classPrivateFieldGet(this, _PQueue_queue, "f").size < limit) {
|
|
return;
|
|
}
|
|
await __classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_onEvent).call(this, 'next', () => __classPrivateFieldGet(this, _PQueue_queue, "f").size < limit);
|
|
}
|
|
/**
|
|
The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.
|
|
|
|
@returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`.
|
|
*/
|
|
async onIdle() {
|
|
// Instantly resolve if none pending and if nothing else is queued
|
|
if (__classPrivateFieldGet(this, _PQueue_pending, "f") === 0 && __classPrivateFieldGet(this, _PQueue_queue, "f").size === 0) {
|
|
return;
|
|
}
|
|
await __classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_onEvent).call(this, 'idle');
|
|
}
|
|
/**
|
|
Size of the queue, the number of queued items waiting to run.
|
|
*/
|
|
get size() {
|
|
return __classPrivateFieldGet(this, _PQueue_queue, "f").size;
|
|
}
|
|
/**
|
|
Size of the queue, filtered by the given options.
|
|
|
|
For example, this can be used to find the number of items remaining in the queue with a specific priority level.
|
|
*/
|
|
sizeBy(options) {
|
|
// eslint-disable-next-line unicorn/no-array-callback-reference
|
|
return __classPrivateFieldGet(this, _PQueue_queue, "f").filter(options).length;
|
|
}
|
|
/**
|
|
Number of running items (no longer in the queue).
|
|
*/
|
|
get pending() {
|
|
return __classPrivateFieldGet(this, _PQueue_pending, "f");
|
|
}
|
|
/**
|
|
Whether the queue is currently paused.
|
|
*/
|
|
get isPaused() {
|
|
return __classPrivateFieldGet(this, _PQueue_isPaused, "f");
|
|
}
|
|
}
|
|
_PQueue_carryoverConcurrencyCount = new WeakMap(), _PQueue_isIntervalIgnored = new WeakMap(), _PQueue_intervalCount = new WeakMap(), _PQueue_intervalCap = new WeakMap(), _PQueue_interval = new WeakMap(), _PQueue_intervalEnd = new WeakMap(), _PQueue_intervalId = new WeakMap(), _PQueue_timeoutId = new WeakMap(), _PQueue_queue = new WeakMap(), _PQueue_queueClass = new WeakMap(), _PQueue_pending = new WeakMap(), _PQueue_concurrency = new WeakMap(), _PQueue_isPaused = new WeakMap(), _PQueue_throwOnTimeout = new WeakMap(), _PQueue_instances = new WeakSet(), _PQueue_doesIntervalAllowAnother_get = function _PQueue_doesIntervalAllowAnother_get() {
|
|
return __classPrivateFieldGet(this, _PQueue_isIntervalIgnored, "f") || __classPrivateFieldGet(this, _PQueue_intervalCount, "f") < __classPrivateFieldGet(this, _PQueue_intervalCap, "f");
|
|
}, _PQueue_doesConcurrentAllowAnother_get = function _PQueue_doesConcurrentAllowAnother_get() {
|
|
return __classPrivateFieldGet(this, _PQueue_pending, "f") < __classPrivateFieldGet(this, _PQueue_concurrency, "f");
|
|
}, _PQueue_next = function _PQueue_next() {
|
|
var _a;
|
|
__classPrivateFieldSet(this, _PQueue_pending, (_a = __classPrivateFieldGet(this, _PQueue_pending, "f"), _a--, _a), "f");
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_tryToStartAnother).call(this);
|
|
this.emit('next');
|
|
}, _PQueue_onResumeInterval = function _PQueue_onResumeInterval() {
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_onInterval).call(this);
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_initializeIntervalIfNeeded).call(this);
|
|
__classPrivateFieldSet(this, _PQueue_timeoutId, undefined, "f");
|
|
}, _PQueue_isIntervalPaused_get = function _PQueue_isIntervalPaused_get() {
|
|
const now = Date.now();
|
|
if (__classPrivateFieldGet(this, _PQueue_intervalId, "f") === undefined) {
|
|
const delay = __classPrivateFieldGet(this, _PQueue_intervalEnd, "f") - now;
|
|
if (delay < 0) {
|
|
// Act as the interval was done
|
|
// We don't need to resume it here because it will be resumed on line 160
|
|
__classPrivateFieldSet(this, _PQueue_intervalCount, (__classPrivateFieldGet(this, _PQueue_carryoverConcurrencyCount, "f")) ? __classPrivateFieldGet(this, _PQueue_pending, "f") : 0, "f");
|
|
}
|
|
else {
|
|
// Act as the interval is pending
|
|
if (__classPrivateFieldGet(this, _PQueue_timeoutId, "f") === undefined) {
|
|
__classPrivateFieldSet(this, _PQueue_timeoutId, setTimeout(() => {
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_onResumeInterval).call(this);
|
|
}, delay), "f");
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}, _PQueue_tryToStartAnother = function _PQueue_tryToStartAnother() {
|
|
if (__classPrivateFieldGet(this, _PQueue_queue, "f").size === 0) {
|
|
// We can clear the interval ("pause")
|
|
// Because we can redo it later ("resume")
|
|
if (__classPrivateFieldGet(this, _PQueue_intervalId, "f")) {
|
|
clearInterval(__classPrivateFieldGet(this, _PQueue_intervalId, "f"));
|
|
}
|
|
__classPrivateFieldSet(this, _PQueue_intervalId, undefined, "f");
|
|
this.emit('empty');
|
|
if (__classPrivateFieldGet(this, _PQueue_pending, "f") === 0) {
|
|
this.emit('idle');
|
|
}
|
|
return false;
|
|
}
|
|
if (!__classPrivateFieldGet(this, _PQueue_isPaused, "f")) {
|
|
const canInitializeInterval = !__classPrivateFieldGet(this, _PQueue_instances, "a", _PQueue_isIntervalPaused_get);
|
|
if (__classPrivateFieldGet(this, _PQueue_instances, "a", _PQueue_doesIntervalAllowAnother_get) && __classPrivateFieldGet(this, _PQueue_instances, "a", _PQueue_doesConcurrentAllowAnother_get)) {
|
|
const job = __classPrivateFieldGet(this, _PQueue_queue, "f").dequeue();
|
|
if (!job) {
|
|
return false;
|
|
}
|
|
this.emit('active');
|
|
job();
|
|
if (canInitializeInterval) {
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_initializeIntervalIfNeeded).call(this);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}, _PQueue_initializeIntervalIfNeeded = function _PQueue_initializeIntervalIfNeeded() {
|
|
if (__classPrivateFieldGet(this, _PQueue_isIntervalIgnored, "f") || __classPrivateFieldGet(this, _PQueue_intervalId, "f") !== undefined) {
|
|
return;
|
|
}
|
|
__classPrivateFieldSet(this, _PQueue_intervalId, setInterval(() => {
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_onInterval).call(this);
|
|
}, __classPrivateFieldGet(this, _PQueue_interval, "f")), "f");
|
|
__classPrivateFieldSet(this, _PQueue_intervalEnd, Date.now() + __classPrivateFieldGet(this, _PQueue_interval, "f"), "f");
|
|
}, _PQueue_onInterval = function _PQueue_onInterval() {
|
|
if (__classPrivateFieldGet(this, _PQueue_intervalCount, "f") === 0 && __classPrivateFieldGet(this, _PQueue_pending, "f") === 0 && __classPrivateFieldGet(this, _PQueue_intervalId, "f")) {
|
|
clearInterval(__classPrivateFieldGet(this, _PQueue_intervalId, "f"));
|
|
__classPrivateFieldSet(this, _PQueue_intervalId, undefined, "f");
|
|
}
|
|
__classPrivateFieldSet(this, _PQueue_intervalCount, __classPrivateFieldGet(this, _PQueue_carryoverConcurrencyCount, "f") ? __classPrivateFieldGet(this, _PQueue_pending, "f") : 0, "f");
|
|
__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_processQueue).call(this);
|
|
}, _PQueue_processQueue = function _PQueue_processQueue() {
|
|
// eslint-disable-next-line no-empty
|
|
while (__classPrivateFieldGet(this, _PQueue_instances, "m", _PQueue_tryToStartAnother).call(this)) { }
|
|
}, _PQueue_throwOnAbort = async function _PQueue_throwOnAbort(signal) {
|
|
return new Promise((_resolve, reject) => {
|
|
signal.addEventListener('abort', () => {
|
|
// TODO: Reject with signal.throwIfAborted() when targeting Node.js 18
|
|
// TODO: Use ABORT_ERR code when targeting Node.js 16 (https://nodejs.org/docs/latest-v16.x/api/errors.html#abort_err)
|
|
reject(new AbortError('The task was aborted.'));
|
|
}, { once: true });
|
|
});
|
|
}, _PQueue_onEvent = async function _PQueue_onEvent(event, filter) {
|
|
return new Promise(resolve => {
|
|
const listener = () => {
|
|
if (filter && !filter()) {
|
|
return;
|
|
}
|
|
this.off(event, listener);
|
|
resolve();
|
|
};
|
|
this.on(event, listener);
|
|
});
|
|
};
|
|
export default PQueue;
|