@zwave-js/waddle 1.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.
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var Task_exports = {};
21
+ __export(Task_exports, {
22
+ TaskInterruptBehavior: () => TaskInterruptBehavior,
23
+ TaskPriority: () => TaskPriority,
24
+ TaskScheduler: () => TaskScheduler,
25
+ TaskState: () => TaskState
26
+ });
27
+ module.exports = __toCommonJS(Task_exports);
28
+ var import_deferred_promise = require("alcalzone-shared/deferred-promise");
29
+ var import_sorted_list = require("alcalzone-shared/sorted-list");
30
+ var import_wrappingCounter = require("./wrappingCounter.js");
31
+ var import_utils = require("./utils.js");
32
+ function getTaskName(task) {
33
+ return `${task.name ?? (task.tag && JSON.stringify(task.tag)) ?? "unnamed"} (ID ${task.id})`;
34
+ }
35
+ __name(getTaskName, "getTaskName");
36
+ function isTaskBuilder(obj) {
37
+ return typeof obj === "object" && typeof obj.task === "function" && typeof obj.priority === "number";
38
+ }
39
+ __name(isTaskBuilder, "isTaskBuilder");
40
+ var TaskPriority;
41
+ (function(TaskPriority2) {
42
+ TaskPriority2[TaskPriority2["Highest"] = 0] = "Highest";
43
+ TaskPriority2[TaskPriority2["High"] = 1] = "High";
44
+ TaskPriority2[TaskPriority2["Normal"] = 2] = "Normal";
45
+ TaskPriority2[TaskPriority2["Low"] = 3] = "Low";
46
+ TaskPriority2[TaskPriority2["Lower"] = 4] = "Lower";
47
+ TaskPriority2[TaskPriority2["Idle"] = 5] = "Idle";
48
+ })(TaskPriority || (TaskPriority = {}));
49
+ var TaskState;
50
+ (function(TaskState2) {
51
+ TaskState2[TaskState2["None"] = 0] = "None";
52
+ TaskState2[TaskState2["Active"] = 1] = "Active";
53
+ TaskState2[TaskState2["AwaitingPromise"] = 2] = "AwaitingPromise";
54
+ TaskState2[TaskState2["AwaitingTask"] = 3] = "AwaitingTask";
55
+ TaskState2[TaskState2["Done"] = 4] = "Done";
56
+ })(TaskState || (TaskState = {}));
57
+ var TaskInterruptBehavior;
58
+ (function(TaskInterruptBehavior2) {
59
+ TaskInterruptBehavior2[TaskInterruptBehavior2["Forbidden"] = 0] = "Forbidden";
60
+ TaskInterruptBehavior2[TaskInterruptBehavior2["Resume"] = 1] = "Resume";
61
+ TaskInterruptBehavior2[TaskInterruptBehavior2["Restart"] = 2] = "Restart";
62
+ })(TaskInterruptBehavior || (TaskInterruptBehavior = {}));
63
+ function compareTasks(a, b) {
64
+ if (a.priority < b.priority)
65
+ return 1;
66
+ if (a.priority > b.priority)
67
+ return -1;
68
+ const aWaiting = a.state === TaskState.AwaitingPromise || a.state === TaskState.AwaitingTask;
69
+ const bWaiting = b.state === TaskState.AwaitingPromise || b.state === TaskState.AwaitingTask;
70
+ if (!aWaiting && bWaiting)
71
+ return 1;
72
+ if (aWaiting && !bWaiting)
73
+ return -1;
74
+ if (a.timestamp < b.timestamp)
75
+ return 1;
76
+ if (a.timestamp > b.timestamp)
77
+ return -1;
78
+ return Math.sign(b.id - a.id);
79
+ }
80
+ __name(compareTasks, "compareTasks");
81
+ class TaskScheduler {
82
+ static {
83
+ __name(this, "TaskScheduler");
84
+ }
85
+ defaultErrorFactory;
86
+ verbose;
87
+ constructor(defaultErrorFactory = () => new Error("Task was removed"), verbose = false) {
88
+ this.defaultErrorFactory = defaultErrorFactory;
89
+ this.verbose = verbose;
90
+ }
91
+ _tasks = new import_sorted_list.SortedList(void 0, compareTasks);
92
+ _currentTask;
93
+ _idGenerator = (0, import_wrappingCounter.createWrappingCounter)(16777215);
94
+ _continueSignal;
95
+ _stopSignal;
96
+ _stopPromise;
97
+ queueTask(builder) {
98
+ const task = this.createTask(builder);
99
+ this._tasks.add(task);
100
+ if (this.verbose) {
101
+ console.log(`Task queued: ${getTaskName(task)}`);
102
+ }
103
+ if (this._continueSignal)
104
+ this._continueSignal.resolve();
105
+ return task.promise;
106
+ }
107
+ /** Removes/stops tasks matching the given predicate. Returns `true` when a task was removed, `false` otherwise. */
108
+ async removeTasks(predicate, reason) {
109
+ const tasksToRemove = [];
110
+ let removeCurrentTask = false;
111
+ for (const task of this._tasks) {
112
+ if (predicate(task)) {
113
+ if (task === this._currentTask) {
114
+ removeCurrentTask = true;
115
+ } else {
116
+ tasksToRemove.push(task);
117
+ }
118
+ }
119
+ }
120
+ reason ??= this.defaultErrorFactory();
121
+ for (const task of tasksToRemove) {
122
+ if (this.verbose) {
123
+ console.log(`Removing task: ${getTaskName(task)}`);
124
+ }
125
+ this._tasks.remove(task);
126
+ if (task.state === TaskState.Active || task.state === TaskState.AwaitingPromise || task.state === TaskState.AwaitingTask) {
127
+ await task.reset().catch(import_utils.noop);
128
+ }
129
+ task.reject(reason);
130
+ if (task.parent) {
131
+ if (this.verbose) {
132
+ console.log(`Restoring parent task: ${getTaskName(task.parent)}`);
133
+ }
134
+ this._tasks.add(task.parent);
135
+ }
136
+ }
137
+ if (removeCurrentTask && this._currentTask) {
138
+ if (this.verbose) {
139
+ console.log(`Removing task: ${getTaskName(this._currentTask)}`);
140
+ }
141
+ this._tasks.remove(this._currentTask);
142
+ await this._currentTask.reset().catch(import_utils.noop);
143
+ this._currentTask.reject(reason);
144
+ if (this._currentTask.parent) {
145
+ if (this.verbose) {
146
+ console.log(`Restoring parent task: ${getTaskName(this._currentTask.parent)}`);
147
+ }
148
+ this._tasks.add(this._currentTask.parent);
149
+ }
150
+ this._currentTask = void 0;
151
+ }
152
+ if (this._continueSignal)
153
+ this._continueSignal.resolve();
154
+ return tasksToRemove.length > 0 || removeCurrentTask;
155
+ }
156
+ findTask(predicate) {
157
+ return this._tasks.find((t) => predicate(t))?.promise;
158
+ }
159
+ /** Creates a task that can be executed */
160
+ createTask(builder, parent) {
161
+ let state = TaskState.None;
162
+ let generator;
163
+ let waitForPromise;
164
+ const promise = (0, import_deferred_promise.createDeferredPromise)();
165
+ let prevResult;
166
+ let waitError;
167
+ const self = this;
168
+ return {
169
+ id: this._idGenerator(),
170
+ timestamp: (0, import_utils.highResTimestamp)(),
171
+ builder,
172
+ parent,
173
+ name: builder.name,
174
+ tag: builder.tag,
175
+ priority: builder.priority,
176
+ interrupt: builder.interrupt ?? TaskInterruptBehavior.Resume,
177
+ promise,
178
+ async step() {
179
+ if (state === TaskState.AwaitingPromise && waitForPromise) {
180
+ return {
181
+ newState: state,
182
+ promise: waitForPromise
183
+ };
184
+ } else if (state === TaskState.AwaitingTask) {
185
+ throw new Error("Cannot step through a task that is waiting for another task");
186
+ }
187
+ generator ??= builder.task();
188
+ state = TaskState.Active;
189
+ const { value, done } = waitError ? await generator.throw(waitError) : await generator.next(prevResult);
190
+ prevResult = void 0;
191
+ waitError = void 0;
192
+ if (done) {
193
+ state = TaskState.Done;
194
+ return {
195
+ newState: state,
196
+ result: value
197
+ };
198
+ } else if (value != void 0) {
199
+ const waitFor = (0, import_utils.evalOrStatic)(value);
200
+ if (waitFor instanceof Promise) {
201
+ state = TaskState.AwaitingPromise;
202
+ waitForPromise = waitFor.then((result) => {
203
+ prevResult = result;
204
+ }).catch((e) => {
205
+ waitError = e;
206
+ }).finally(() => {
207
+ waitForPromise = void 0;
208
+ if (state === TaskState.AwaitingPromise) {
209
+ state = TaskState.Active;
210
+ }
211
+ });
212
+ return {
213
+ newState: state,
214
+ promise: waitForPromise
215
+ };
216
+ } else if (isTaskBuilder(waitFor)) {
217
+ if (waitFor.priority > builder.priority) {
218
+ throw new Error("Tasks cannot yield to tasks with lower priority than their own");
219
+ }
220
+ state = TaskState.AwaitingTask;
221
+ const subTask = self.createTask(waitFor, this);
222
+ subTask.promise.then((result) => {
223
+ prevResult = result;
224
+ }).catch((e) => {
225
+ waitError = e;
226
+ }).finally(() => {
227
+ if (state === TaskState.AwaitingTask) {
228
+ state = TaskState.Active;
229
+ }
230
+ });
231
+ return {
232
+ newState: state,
233
+ task: subTask
234
+ };
235
+ } else {
236
+ throw new Error("Invalid value yielded by task");
237
+ }
238
+ } else {
239
+ return { newState: state };
240
+ }
241
+ },
242
+ async reset() {
243
+ if (state === TaskState.None)
244
+ return;
245
+ state = TaskState.None;
246
+ waitForPromise = void 0;
247
+ generator = void 0;
248
+ await builder.cleanup?.();
249
+ },
250
+ resolve(result) {
251
+ promise.resolve(result);
252
+ },
253
+ reject(error) {
254
+ promise.reject(error);
255
+ },
256
+ get state() {
257
+ return state;
258
+ },
259
+ get generator() {
260
+ return generator;
261
+ }
262
+ };
263
+ }
264
+ start() {
265
+ this._stopSignal = (0, import_deferred_promise.createDeferredPromise)();
266
+ setImmediate(async () => {
267
+ try {
268
+ await this.run();
269
+ } catch (e) {
270
+ console.error("Task runner crashed", e);
271
+ }
272
+ });
273
+ }
274
+ async run() {
275
+ while (true) {
276
+ let waitFor;
277
+ if (this._tasks.length > 0) {
278
+ const firstTask = this._tasks.peekStart();
279
+ if (!this._currentTask) {
280
+ this._currentTask = firstTask;
281
+ } else if (this._currentTask !== firstTask && this._currentTask.interrupt !== TaskInterruptBehavior.Forbidden) {
282
+ if (this._currentTask.interrupt === TaskInterruptBehavior.Restart) {
283
+ await this._currentTask.reset();
284
+ }
285
+ this._currentTask = firstTask;
286
+ }
287
+ if (this.verbose) {
288
+ console.log(`Stepping through task: ${getTaskName(this._currentTask)}`);
289
+ }
290
+ const cleanupCurrentTask = /* @__PURE__ */ __name(async () => {
291
+ if (this._currentTask) {
292
+ this._tasks.remove(this._currentTask);
293
+ await this._currentTask.reset();
294
+ if (this._currentTask.parent) {
295
+ if (this.verbose) {
296
+ console.log(`Restoring parent task: ${getTaskName(this._currentTask.parent)}`);
297
+ }
298
+ this._tasks.add(this._currentTask.parent);
299
+ }
300
+ this._currentTask = void 0;
301
+ }
302
+ }, "cleanupCurrentTask");
303
+ waitFor = void 0;
304
+ let stepResult;
305
+ try {
306
+ stepResult = await this._currentTask.step();
307
+ } catch (e) {
308
+ if (this.verbose) {
309
+ console.error(`- Task threw an error:`, e);
310
+ }
311
+ this._currentTask.reject(e);
312
+ await cleanupCurrentTask();
313
+ continue;
314
+ }
315
+ if (stepResult.newState === TaskState.Done) {
316
+ if (this.verbose) {
317
+ console.log(`- Task finished`);
318
+ }
319
+ this._currentTask.resolve(stepResult.result);
320
+ await cleanupCurrentTask();
321
+ continue;
322
+ } else if (stepResult.newState === TaskState.AwaitingPromise) {
323
+ if (this.verbose) {
324
+ console.log(`- Task waiting`);
325
+ }
326
+ if (this._currentTask.interrupt !== TaskInterruptBehavior.Forbidden) {
327
+ this._tasks.remove(this._currentTask);
328
+ this._tasks.add(this._currentTask);
329
+ if (this._tasks.peekStart() !== this._currentTask) {
330
+ if (this.verbose) {
331
+ console.log(`-- Continuing with another task`);
332
+ }
333
+ continue;
334
+ }
335
+ }
336
+ waitFor = stepResult.promise;
337
+ } else if (stepResult.newState === TaskState.AwaitingTask) {
338
+ if (this.verbose) {
339
+ console.log(`- Task spawned a sub-task`);
340
+ }
341
+ this._tasks.add(stepResult.task);
342
+ this._tasks.remove(this._currentTask);
343
+ continue;
344
+ } else {
345
+ continue;
346
+ }
347
+ }
348
+ this._continueSignal = (0, import_deferred_promise.createDeferredPromise)();
349
+ const nextAction = await Promise.race([
350
+ this._continueSignal.then(() => "continue"),
351
+ this._stopSignal.then(() => "stop"),
352
+ waitFor?.then(() => "continue")
353
+ ].filter((p) => p !== void 0));
354
+ this._continueSignal = void 0;
355
+ if (nextAction === "stop")
356
+ break;
357
+ }
358
+ this._stopPromise.resolve();
359
+ }
360
+ async stop() {
361
+ if (!this._stopSignal)
362
+ return;
363
+ this._stopPromise = (0, import_deferred_promise.createDeferredPromise)();
364
+ this._stopSignal.resolve();
365
+ await this._stopPromise;
366
+ }
367
+ }
368
+ // Annotate the CommonJS export names for ESM import in node:
369
+ 0 && (module.exports = {
370
+ TaskInterruptBehavior,
371
+ TaskPriority,
372
+ TaskScheduler,
373
+ TaskState
374
+ });
375
+ //# sourceMappingURL=Task.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/Task.ts"],
4
+ "sourcesContent": ["import type { CompareResult } from \"alcalzone-shared/comparable\";\nimport {\n\ttype DeferredPromise,\n\tcreateDeferredPromise,\n} from \"alcalzone-shared/deferred-promise\";\nimport { SortedList } from \"alcalzone-shared/sorted-list\";\nimport { createWrappingCounter } from \"./wrappingCounter.js\";\nimport { evalOrStatic, highResTimestamp, noop } from \"./utils.js\";\n\n/** A high-level task that can be started and stepped through */\nexport interface Task<\n\tTReturn,\n\tTaskTag extends { id: string } = { id: string },\n\tTError extends Error = Error,\n> {\n\treadonly id: number;\n\treadonly timestamp: number;\n\treadonly builder: TaskBuilder<TReturn, TaskTag>;\n\n\t/** The parent task spawning this subtask, if any */\n\treadonly parent?: Task<unknown, TaskTag, TError>;\n\n\t/** A name to identify the task */\n\treadonly name?: string;\n\t/** A tag to identify the task programmatically */\n\treadonly tag?: TaskTag;\n\t/** The task's priority */\n\treadonly priority: TaskPriority;\n\t/** How the task should behave when interrupted */\n\treadonly interrupt: TaskInterruptBehavior;\n\t/** Starts the task it if hasn't been started yet, and executes the next step of the task */\n\tstep(): Promise<TaskStepResult<TReturn, TaskTag>>;\n\t/** Stops the task without further executing it, cleans up, and prepares it for starting again */\n\treset(): Promise<void>;\n\t/** Resolves the task's promise to notify the caller */\n\tresolve(result: TReturn): void;\n\t/** Rejects the task's promise to notify the caller */\n\treject(error: TError): void;\n\t/** The current state of the task */\n\tget state(): TaskState;\n\n\treadonly generator: ReturnType<TaskBuilder<TReturn>[\"task\"]> | undefined;\n\treadonly promise: Promise<TReturn>;\n}\n\nfunction getTaskName(task: Task<unknown>): string {\n\treturn `${\n\t\ttask.name ?? (task.tag && JSON.stringify(task.tag)) ?? \"unnamed\"\n\t} (ID ${task.id})`;\n}\n\n/** Defines the necessary information for creating a task */\nexport interface TaskBuilder<\n\tTReturn,\n\tTaskTag extends { id: string } = { id: string },\n\tTInner = unknown,\n> {\n\t/** A name to identify the task */\n\tname?: string;\n\t/** A tag to identify the task programmatically */\n\ttag?: TaskTag;\n\t/** The task's priority */\n\tpriority: TaskPriority;\n\t/** How the task should behave when interrupted */\n\tinterrupt?: TaskInterruptBehavior;\n\t/**\n\t * The task's main generator function. This is called repeatedly until it's done.\n\t * The function must yield at points where it may be interrupted.\n\t *\n\t * At those points, the task can also wait for something to happen:\n\t * - Either a Promise, in which case it must yield a function that returns that Promise\n\t * - Or another task, in which case it must yield a TaskBuilder object or a function that returns one\n\t *\n\t * Yielded Promises should not spawn new tasks. If they do, the spawned tasks MUST have a higher priority than the parent task.\n\t */\n\ttask: () => AsyncGenerator<\n\t\t| (() => Promise<TInner> | TaskBuilder<TReturn, TaskTag, TInner>)\n\t\t| (() => TaskBuilder<TReturn, TaskTag, TInner>)\n\t\t| TaskBuilder<TReturn, TaskTag, TInner>\n\t\t| undefined,\n\t\tTReturn,\n\t\tTInner\n\t>;\n\t/** A cleanup function that gets called when the task is dropped */\n\tcleanup?: () => Promise<void>;\n}\n\nexport type TaskReturnType<T extends TaskBuilder<unknown>> =\n\tT extends TaskBuilder<infer R> ? R : never;\n\nfunction isTaskBuilder<T>(obj: any): obj is TaskBuilder<T> {\n\treturn (\n\t\ttypeof obj === \"object\" &&\n\t\ttypeof obj.task === \"function\" &&\n\t\ttypeof obj.priority === \"number\"\n\t);\n}\n\n/**\n * The priority of a task.\n *\n * Higher priority tasks are executed first and interrupt lower priority tasks.\n * The recommended priority for application-initiated communication is `Normal`.\n * `Low` and `Lower` are recommended for internal long-running tasks that should not interfere with user-initiated tasks.\n * `Idle` is recommended for tasks that should only run when no other tasks are pending.\n */\nexport enum TaskPriority {\n\tHighest,\n\tHigh = 1,\n\tNormal = 2,\n\tLow = 3,\n\tLower = 4,\n\tIdle = 5,\n}\n\nexport enum TaskState {\n\t/** The task has not been created yet */\n\tNone,\n\t/** The task is being executed */\n\tActive,\n\t/** The task is waiting for a Promise to resolve */\n\tAwaitingPromise,\n\t/** The task is waiting for another task to finish */\n\tAwaitingTask,\n\t/** The task is finished */\n\tDone,\n}\n\nexport enum TaskInterruptBehavior {\n\t/** The task may not be interrupted */\n\tForbidden,\n\t/** The task will be resumed after being interrupted (default) */\n\tResume,\n\t/** The task needs to be restarted after being interrupted */\n\tRestart,\n}\n\nexport type TaskStepResult<\n\tT,\n\tTaskTag extends { id: string } = { id: string },\n> =\n\t| {\n\t\t\tnewState: TaskState.Done;\n\t\t\tresult: T;\n\t }\n\t| {\n\t\t\tnewState: TaskState.Active;\n\t }\n\t| {\n\t\t\tnewState: TaskState.AwaitingPromise;\n\t\t\tpromise: Promise<unknown>;\n\t }\n\t| {\n\t\t\tnewState: TaskState.AwaitingTask;\n\t\t\ttask: Task<unknown, TaskTag>;\n\t };\n\nfunction compareTasks<T1, T2>(a: Task<T1>, b: Task<T2>): CompareResult {\n\t// Sort by priority first. Higher priority goes to the end of the list\n\tif (a.priority < b.priority) return 1;\n\tif (a.priority > b.priority) return -1;\n\n\t// Deprioritize waiting tasks\n\tconst aWaiting =\n\t\ta.state === TaskState.AwaitingPromise ||\n\t\ta.state === TaskState.AwaitingTask;\n\tconst bWaiting =\n\t\tb.state === TaskState.AwaitingPromise ||\n\t\tb.state === TaskState.AwaitingTask;\n\tif (!aWaiting && bWaiting) return 1;\n\tif (aWaiting && !bWaiting) return -1;\n\n\t// Sort equal priority by timestamp. Newer tasks go to the end of the list\n\tif (a.timestamp < b.timestamp) return 1;\n\tif (a.timestamp > b.timestamp) return -1;\n\n\t// If all else fails, sort by ID\n\treturn Math.sign(b.id - a.id) as CompareResult;\n}\n\nexport class TaskScheduler<\n\tTaskTag extends { id: string } = { id: string },\n\tTError extends Error = Error,\n> {\n\tpublic constructor(\n\t\tprivate defaultErrorFactory: () => TError = () =>\n\t\t\tnew Error(\"Task was removed\") as any,\n\t\tprivate verbose: boolean = false,\n\t) {}\n\n\tprivate _tasks = new SortedList<Task<unknown, TaskTag>>(\n\t\tundefined,\n\t\tcompareTasks,\n\t);\n\tprivate _currentTask: Task<unknown, TaskTag> | undefined;\n\n\tprivate _idGenerator = createWrappingCounter(0xff_ff_ff);\n\tprivate _continueSignal: DeferredPromise<void> | undefined;\n\tprivate _stopSignal: DeferredPromise<void> | undefined;\n\tprivate _stopPromise: DeferredPromise<void> | undefined;\n\n\tpublic queueTask<T>(builder: TaskBuilder<T, TaskTag>): Promise<T> {\n\t\tconst task = this.createTask(builder);\n\t\tthis._tasks.add(task);\n\t\tif (this.verbose) {\n\t\t\tconsole.log(`Task queued: ${getTaskName(task)}`);\n\t\t}\n\n\t\tif (this._continueSignal) this._continueSignal.resolve();\n\t\treturn task.promise;\n\t}\n\n\t/** Removes/stops tasks matching the given predicate. Returns `true` when a task was removed, `false` otherwise. */\n\tpublic async removeTasks(\n\t\tpredicate: (task: Task<unknown, TaskTag>) => boolean,\n\t\treason?: TError,\n\t): Promise<boolean> {\n\t\t// Collect tasks that should be removed, but in reverse order,\n\t\t// so that we handle the current task last.\n\t\tconst tasksToRemove: Task<unknown, TaskTag>[] = [];\n\t\tlet removeCurrentTask = false;\n\t\tfor (const task of this._tasks) {\n\t\t\tif (predicate(task)) {\n\t\t\t\tif (task === this._currentTask) {\n\t\t\t\t\tremoveCurrentTask = true;\n\t\t\t\t} else {\n\t\t\t\t\ttasksToRemove.push(task);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treason ??= this.defaultErrorFactory();\n\n\t\tfor (const task of tasksToRemove) {\n\t\t\tif (this.verbose) {\n\t\t\t\tconsole.log(`Removing task: ${getTaskName(task)}`);\n\t\t\t}\n\t\t\tthis._tasks.remove(task);\n\t\t\tif (\n\t\t\t\ttask.state === TaskState.Active ||\n\t\t\t\ttask.state === TaskState.AwaitingPromise ||\n\t\t\t\ttask.state === TaskState.AwaitingTask\n\t\t\t) {\n\t\t\t\t// The task is running, clean it up\n\t\t\t\tawait task.reset().catch(noop);\n\t\t\t}\n\t\t\ttask.reject(reason);\n\t\t\t// Re-add the parent task to the list if there is one\n\t\t\tif (task.parent) {\n\t\t\t\tif (this.verbose) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`Restoring parent task: ${getTaskName(task.parent)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis._tasks.add(task.parent);\n\t\t\t}\n\t\t}\n\n\t\tif (removeCurrentTask && this._currentTask) {\n\t\t\tif (this.verbose) {\n\t\t\t\tconsole.log(`Removing task: ${getTaskName(this._currentTask)}`);\n\t\t\t}\n\t\t\tthis._tasks.remove(this._currentTask);\n\t\t\tawait this._currentTask.reset().catch(noop);\n\t\t\tthis._currentTask.reject(reason);\n\t\t\t// Re-add the parent task to the list if there is one\n\t\t\tif (this._currentTask.parent) {\n\t\t\t\tif (this.verbose) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`Restoring parent task: ${getTaskName(\n\t\t\t\t\t\t\tthis._currentTask.parent,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis._tasks.add(this._currentTask.parent);\n\t\t\t}\n\t\t\tthis._currentTask = undefined;\n\t\t}\n\n\t\tif (this._continueSignal) this._continueSignal.resolve();\n\n\t\treturn tasksToRemove.length > 0 || removeCurrentTask;\n\t}\n\n\tpublic findTask<T = unknown>(\n\t\tpredicate: (task: Task<T, TaskTag>) => boolean,\n\t): Promise<T> | undefined {\n\t\treturn this._tasks.find((t: any) => predicate(t))?.promise as\n\t\t\t| Promise<T>\n\t\t\t| undefined;\n\t}\n\n\t/** Creates a task that can be executed */\n\tprivate createTask<T>(\n\t\tbuilder: TaskBuilder<T, TaskTag>,\n\t\tparent?: Task<unknown, TaskTag>,\n\t): Task<T, TaskTag, TError> {\n\t\tlet state = TaskState.None;\n\t\tlet generator: ReturnType<TaskBuilder<T, TaskTag>[\"task\"]> | undefined;\n\t\tlet waitForPromise: Promise<unknown> | undefined;\n\t\tconst promise = createDeferredPromise<T>();\n\n\t\tlet prevResult: unknown;\n\t\tlet waitError: unknown;\n\n\t\tconst self = this;\n\n\t\treturn {\n\t\t\tid: this._idGenerator(),\n\t\t\ttimestamp: highResTimestamp(),\n\t\t\tbuilder,\n\t\t\tparent,\n\t\t\tname: builder.name,\n\t\t\ttag: builder.tag,\n\t\t\tpriority: builder.priority,\n\t\t\tinterrupt: builder.interrupt ?? TaskInterruptBehavior.Resume,\n\t\t\tpromise,\n\t\t\tasync step() {\n\t\t\t\t// Do not proceed while still waiting for a Promise to resolve\n\t\t\t\tif (state === TaskState.AwaitingPromise && waitForPromise) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tnewState: state,\n\t\t\t\t\t\tpromise: waitForPromise,\n\t\t\t\t\t};\n\t\t\t\t} else if (state === TaskState.AwaitingTask) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Cannot step through a task that is waiting for another task\",\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tgenerator ??= builder.task();\n\t\t\t\tstate = TaskState.Active;\n\n\t\t\t\tconst { value, done } = waitError\n\t\t\t\t\t? await generator.throw(waitError)\n\t\t\t\t\t: await generator.next(prevResult);\n\t\t\t\tprevResult = undefined;\n\t\t\t\twaitError = undefined;\n\t\t\t\tif (done) {\n\t\t\t\t\tstate = TaskState.Done;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tnewState: state,\n\t\t\t\t\t\tresult: value,\n\t\t\t\t\t};\n\t\t\t\t} else if (value != undefined) {\n\t\t\t\t\tconst waitFor = evalOrStatic(value);\n\t\t\t\t\tif (waitFor instanceof Promise) {\n\t\t\t\t\t\tstate = TaskState.AwaitingPromise;\n\t\t\t\t\t\twaitForPromise = waitFor\n\t\t\t\t\t\t\t.then((result) => {\n\t\t\t\t\t\t\t\tprevResult = result;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\t\t\twaitError = e;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\t\twaitForPromise = undefined;\n\t\t\t\t\t\t\t\tif (state === TaskState.AwaitingPromise) {\n\t\t\t\t\t\t\t\t\tstate = TaskState.Active;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tnewState: state,\n\t\t\t\t\t\t\tpromise: waitForPromise,\n\t\t\t\t\t\t};\n\t\t\t\t\t} else if (isTaskBuilder(waitFor)) {\n\t\t\t\t\t\tif (waitFor.priority > builder.priority) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"Tasks cannot yield to tasks with lower priority than their own\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Create a sub-task with a reference to this task\n\t\t\t\t\t\tstate = TaskState.AwaitingTask;\n\t\t\t\t\t\tconst subTask = self.createTask(waitFor, this);\n\n\t\t\t\t\t\tsubTask.promise\n\t\t\t\t\t\t\t.then((result) => {\n\t\t\t\t\t\t\t\tprevResult = result;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\t\t\twaitError = e;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\t\tif (state === TaskState.AwaitingTask) {\n\t\t\t\t\t\t\t\t\tstate = TaskState.Active;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tnewState: state,\n\t\t\t\t\t\t\ttask: subTask,\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error(\"Invalid value yielded by task\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn { newState: state };\n\t\t\t\t}\n\t\t\t},\n\t\t\tasync reset() {\n\t\t\t\tif (state === TaskState.None) return;\n\t\t\t\tstate = TaskState.None;\n\t\t\t\twaitForPromise = undefined;\n\t\t\t\tgenerator = undefined;\n\n\t\t\t\tawait builder.cleanup?.();\n\t\t\t},\n\t\t\tresolve(result) {\n\t\t\t\tpromise.resolve(result);\n\t\t\t},\n\t\t\treject(error) {\n\t\t\t\tpromise.reject(error);\n\t\t\t},\n\t\t\tget state() {\n\t\t\t\treturn state;\n\t\t\t},\n\t\t\tget generator() {\n\t\t\t\treturn generator;\n\t\t\t},\n\t\t};\n\t}\n\n\tpublic start(): void {\n\t\tthis._stopSignal = createDeferredPromise();\n\t\tsetImmediate(async () => {\n\t\t\ttry {\n\t\t\t\tawait this.run();\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(\"Task runner crashed\", e);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async run(): Promise<void> {\n\t\twhile (true) {\n\t\t\tlet waitFor: Promise<unknown> | undefined;\n\t\t\tif (this._tasks.length > 0) {\n\t\t\t\tconst firstTask = this._tasks.peekStart()!;\n\t\t\t\tif (!this._currentTask) {\n\t\t\t\t\t// We're not currently executing a task, start executing the first one\n\t\t\t\t\tthis._currentTask = firstTask;\n\t\t\t\t} else if (\n\t\t\t\t\tthis._currentTask !== firstTask &&\n\t\t\t\t\tthis._currentTask.interrupt !==\n\t\t\t\t\t\tTaskInterruptBehavior.Forbidden\n\t\t\t\t) {\n\t\t\t\t\t// We are executing an interruptible task, and a new task with a higher priority was added\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis._currentTask.interrupt ===\n\t\t\t\t\t\tTaskInterruptBehavior.Restart\n\t\t\t\t\t) {\n\t\t\t\t\t\t// The current task needs to be restarted after being interrupted, so reset it\n\t\t\t\t\t\tawait this._currentTask.reset();\n\t\t\t\t\t}\n\t\t\t\t\t// switch to the new task\n\t\t\t\t\tthis._currentTask = firstTask;\n\t\t\t\t}\n\n\t\t\t\tif (this.verbose) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`Stepping through task: ${getTaskName(\n\t\t\t\t\t\t\tthis._currentTask,\n\t\t\t\t\t\t)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst cleanupCurrentTask = async () => {\n\t\t\t\t\tif (this._currentTask) {\n\t\t\t\t\t\tthis._tasks.remove(this._currentTask);\n\t\t\t\t\t\tawait this._currentTask.reset();\n\t\t\t\t\t\t// Re-add the parent task to the list if there is one\n\t\t\t\t\t\tif (this._currentTask.parent) {\n\t\t\t\t\t\t\tif (this.verbose) {\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t`Restoring parent task: ${getTaskName(\n\t\t\t\t\t\t\t\t\t\tthis._currentTask.parent,\n\t\t\t\t\t\t\t\t\t)}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._tasks.add(this._currentTask.parent);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis._currentTask = undefined;\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Execute the current task one step further\n\t\t\t\twaitFor = undefined;\n\t\t\t\tlet stepResult: TaskStepResult<unknown, TaskTag>;\n\t\t\t\ttry {\n\t\t\t\t\tstepResult = await this._currentTask.step();\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (this.verbose) {\n\t\t\t\t\t\tconsole.error(`- Task threw an error:`, e);\n\t\t\t\t\t}\n\t\t\t\t\t// The task threw an error, expose the result and clean up.\n\t\t\t\t\tthis._currentTask.reject(e as Error);\n\t\t\t\t\tawait cleanupCurrentTask();\n\t\t\t\t\t// Then continue with the next iteration\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (stepResult.newState === TaskState.Done) {\n\t\t\t\t\tif (this.verbose) {\n\t\t\t\t\t\tconsole.log(`- Task finished`);\n\t\t\t\t\t}\n\t\t\t\t\t// The task is done, clean up\n\t\t\t\t\tthis._currentTask.resolve(stepResult.result);\n\t\t\t\t\tawait cleanupCurrentTask();\n\t\t\t\t\t// Then continue with the next iteration\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if (stepResult.newState === TaskState.AwaitingPromise) {\n\t\t\t\t\t// The task is waiting for something\n\t\t\t\t\tif (this.verbose) {\n\t\t\t\t\t\tconsole.log(`- Task waiting`);\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the task may be interrupted, check if there are other same-priority tasks that should be executed instead\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis._currentTask.interrupt !==\n\t\t\t\t\t\tTaskInterruptBehavior.Forbidden\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Re-queue the task, so the queue gets reordered\n\t\t\t\t\t\tthis._tasks.remove(this._currentTask);\n\t\t\t\t\t\tthis._tasks.add(this._currentTask);\n\n\t\t\t\t\t\tif (this._tasks.peekStart() !== this._currentTask) {\n\t\t\t\t\t\t\tif (this.verbose) {\n\t\t\t\t\t\t\t\tconsole.log(`-- Continuing with another task`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// The task is no longer the first in the queue. Switch to the other one\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Otherwise, we got nothing to do right now than to wait\n\t\t\t\t\twaitFor = stepResult.promise;\n\t\t\t\t} else if (stepResult.newState === TaskState.AwaitingTask) {\n\t\t\t\t\t// The task spawned a sub-task. Replace it with the sub-task and continue executing\n\t\t\t\t\tif (this.verbose) {\n\t\t\t\t\t\tconsole.log(`- Task spawned a sub-task`);\n\t\t\t\t\t}\n\t\t\t\t\tthis._tasks.add(stepResult.task);\n\t\t\t\t\tthis._tasks.remove(this._currentTask);\n\t\t\t\t\t// Continue with the next iteration\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\t// The current task is not done, continue with the next iteration\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Task queue empty. Wait for either a new task or the stop signal,\n\t\t\t// or the current task to finish waiting\n\t\t\tthis._continueSignal = createDeferredPromise();\n\t\t\tconst nextAction = await Promise.race(\n\t\t\t\t[\n\t\t\t\t\tthis._continueSignal.then(() => \"continue\" as const),\n\t\t\t\t\tthis._stopSignal!.then(() => \"stop\" as const),\n\t\t\t\t\twaitFor?.then(() => \"continue\" as const),\n\t\t\t\t].filter((p) => p !== undefined),\n\t\t\t);\n\t\t\tthis._continueSignal = undefined;\n\t\t\tif (nextAction === \"stop\") break;\n\t\t}\n\t\tthis._stopPromise!.resolve();\n\t}\n\n\tpublic async stop(): Promise<void> {\n\t\tif (!this._stopSignal) return;\n\t\t// Signal to the task runner that it should stop\n\t\tthis._stopPromise = createDeferredPromise();\n\t\tthis._stopSignal.resolve();\n\t\tawait this._stopPromise;\n\t}\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["TaskPriority", "TaskState", "TaskInterruptBehavior"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export { Task, TaskBuilder, TaskInterruptBehavior, TaskPriority, TaskReturnType, TaskScheduler, TaskState, TaskStepResult, } from "./Task.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
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
+ var index_exports = {};
20
+ __export(index_exports, {
21
+ TaskInterruptBehavior: () => import_Task.TaskInterruptBehavior,
22
+ TaskPriority: () => import_Task.TaskPriority,
23
+ TaskScheduler: () => import_Task.TaskScheduler,
24
+ TaskState: () => import_Task.TaskState
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+ var import_Task = require("./Task.js");
28
+ // Annotate the CommonJS export names for ESM import in node:
29
+ 0 && (module.exports = {
30
+ TaskInterruptBehavior,
31
+ TaskPriority,
32
+ TaskScheduler,
33
+ TaskState
34
+ });
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": ["export {\n\tTask,\n\tTaskBuilder,\n\tTaskInterruptBehavior,\n\tTaskPriority,\n\tTaskReturnType,\n\tTaskScheduler,\n\tTaskState,\n\tTaskStepResult,\n} from \"./Task.js\";\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAAA,kBASO;",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,8 @@
1
+ /** Returns a timestamp with nano-second precision */
2
+ export declare function highResTimestamp(): number;
3
+ /** Does nothing. Can be used for empty `.catch(...)` calls. */
4
+ export declare function noop(): void;
5
+ export type FnOrStatic<TArgs extends any[], TReturn> = ((...args: TArgs) => TReturn) | TReturn;
6
+ export type ReturnTypeOrStatic<T> = T extends (...args: any[]) => infer R ? R : T;
7
+ export declare function evalOrStatic<T>(fnOrConst: T, ...args: any[]): ReturnTypeOrStatic<T>;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var utils_exports = {};
21
+ __export(utils_exports, {
22
+ evalOrStatic: () => evalOrStatic,
23
+ highResTimestamp: () => highResTimestamp,
24
+ noop: () => noop
25
+ });
26
+ module.exports = __toCommonJS(utils_exports);
27
+ function highResTimestamp() {
28
+ if (typeof process !== "undefined") {
29
+ const [s, ns] = process.hrtime();
30
+ return s * 1e9 + ns;
31
+ } else if (performance != void 0) {
32
+ return performance.now() * 1e6;
33
+ } else {
34
+ throw new Error("No high-resolution timer available");
35
+ }
36
+ }
37
+ __name(highResTimestamp, "highResTimestamp");
38
+ function noop() {
39
+ }
40
+ __name(noop, "noop");
41
+ function evalOrStatic(fnOrConst, ...args) {
42
+ return typeof fnOrConst === "function" ? fnOrConst(...args) : fnOrConst;
43
+ }
44
+ __name(evalOrStatic, "evalOrStatic");
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ evalOrStatic,
48
+ highResTimestamp,
49
+ noop
50
+ });
51
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils.ts"],
4
+ "sourcesContent": ["/** Returns a timestamp with nano-second precision */\nexport function highResTimestamp(): number {\n\tif (typeof process !== \"undefined\") {\n\t\tconst [s, ns] = process.hrtime();\n\t\treturn s * 1e9 + ns;\n\t} else if (performance != undefined) {\n\t\treturn performance.now() * 1e6;\n\t} else {\n\t\tthrow new Error(\"No high-resolution timer available\");\n\t}\n}\n\n/** Does nothing. Can be used for empty `.catch(...)` calls. */\nexport function noop(): void {\n\t// intentionally empty\n}\n\nexport type FnOrStatic<TArgs extends any[], TReturn> =\n\t| ((...args: TArgs) => TReturn)\n\t| TReturn;\n\nexport type ReturnTypeOrStatic<T> = T extends (...args: any[]) => infer R ? R\n\t: T;\n\nexport function evalOrStatic<T>(\n\tfnOrConst: T,\n\t...args: any[]\n): ReturnTypeOrStatic<T> {\n\t// @ts-expect-error https://github.com/microsoft/TypeScript/issues/61337\n\treturn typeof fnOrConst === \"function\" ? fnOrConst(...args) : fnOrConst;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;;;;;;;AACM,SAAU,mBAAgB;AAC/B,MAAI,OAAO,YAAY,aAAa;AACnC,UAAM,CAAC,GAAG,EAAE,IAAI,QAAQ,OAAM;AAC9B,WAAO,IAAI,MAAM;EAClB,WAAW,eAAe,QAAW;AACpC,WAAO,YAAY,IAAG,IAAK;EAC5B,OAAO;AACN,UAAM,IAAI,MAAM,oCAAoC;EACrD;AACD;AATgB;AAYV,SAAU,OAAI;AAEpB;AAFgB;AAWV,SAAU,aACf,cACG,MAAW;AAGd,SAAO,OAAO,cAAc,aAAa,UAAU,GAAG,IAAI,IAAI;AAC/D;AANgB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Creates a counter that starts at 1 and wraps after surpassing `maxValue`.
3
+ * @param maxValue The maximum value that the counter can reach. Must a number where all bits are set to 1.
4
+ * @param randomSeed Whether the initial value should be randomized. Default: `false`.
5
+ */
6
+ export declare function createWrappingCounter(maxValue: number, randomSeed?: boolean): () => number;
7
+ //# sourceMappingURL=wrappingCounter.d.ts.map
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var wrappingCounter_exports = {};
21
+ __export(wrappingCounter_exports, {
22
+ createWrappingCounter: () => createWrappingCounter
23
+ });
24
+ module.exports = __toCommonJS(wrappingCounter_exports);
25
+ function createWrappingCounter(maxValue, randomSeed = false) {
26
+ let value = randomSeed ? Math.round(Math.random() * maxValue) : 0;
27
+ return () => {
28
+ value = value + 1 & maxValue;
29
+ if (value === 0)
30
+ value = 1;
31
+ return value;
32
+ };
33
+ }
34
+ __name(createWrappingCounter, "createWrappingCounter");
35
+ // Annotate the CommonJS export names for ESM import in node:
36
+ 0 && (module.exports = {
37
+ createWrappingCounter
38
+ });
39
+ //# sourceMappingURL=wrappingCounter.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/wrappingCounter.ts"],
4
+ "sourcesContent": ["/**\n * Creates a counter that starts at 1 and wraps after surpassing `maxValue`.\n * @param maxValue The maximum value that the counter can reach. Must a number where all bits are set to 1.\n * @param randomSeed Whether the initial value should be randomized. Default: `false`.\n */\nexport function createWrappingCounter(\n\tmaxValue: number,\n\trandomSeed: boolean = false,\n): () => number {\n\tlet value = randomSeed ? Math.round(Math.random() * maxValue) : 0;\n\treturn () => {\n\t\tvalue = (value + 1) & maxValue;\n\t\tif (value === 0) value = 1;\n\t\treturn value;\n\t};\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;;;;;AAKM,SAAU,sBACf,UACA,aAAsB,OAAK;AAE3B,MAAI,QAAQ,aAAa,KAAK,MAAM,KAAK,OAAM,IAAK,QAAQ,IAAI;AAChE,SAAO,MAAK;AACX,YAAS,QAAQ,IAAK;AACtB,QAAI,UAAU;AAAG,cAAQ;AACzB,WAAO;EACR;AACD;AAVgB;",
6
+ "names": []
7
+ }