aboutsummaryrefslogtreecommitdiffstats
path: root/packages/excalidraw/queue.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/excalidraw/queue.ts')
-rw-r--r--packages/excalidraw/queue.ts46
1 files changed, 46 insertions, 0 deletions
diff --git a/packages/excalidraw/queue.ts b/packages/excalidraw/queue.ts
new file mode 100644
index 0000000..9cac2c5
--- /dev/null
+++ b/packages/excalidraw/queue.ts
@@ -0,0 +1,46 @@
+import type { MaybePromise } from "./utility-types";
+import type { ResolvablePromise } from "./utils";
+import { promiseTry, resolvablePromise } from "./utils";
+
+type Job<T, TArgs extends unknown[]> = (...args: TArgs) => MaybePromise<T>;
+
+type QueueJob<T, TArgs extends unknown[]> = {
+ jobFactory: Job<T, TArgs>;
+ promise: ResolvablePromise<T>;
+ args: TArgs;
+};
+
+export class Queue {
+ private jobs: QueueJob<any, any[]>[] = [];
+ private running = false;
+
+ private tick() {
+ if (this.running) {
+ return;
+ }
+ const job = this.jobs.shift();
+ if (job) {
+ this.running = true;
+ job.promise.resolve(
+ promiseTry(job.jobFactory, ...job.args).finally(() => {
+ this.running = false;
+ this.tick();
+ }),
+ );
+ } else {
+ this.running = false;
+ }
+ }
+
+ push<TValue, TArgs extends unknown[]>(
+ jobFactory: Job<TValue, TArgs>,
+ ...args: TArgs
+ ): Promise<TValue> {
+ const promise = resolvablePromise<TValue>();
+ this.jobs.push({ jobFactory, promise, args });
+
+ this.tick();
+
+ return promise;
+ }
+}