about summary refs log tree commit diff
path: root/src/lib/async/bundle.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/async/bundle.ts')
-rw-r--r--src/lib/async/bundle.ts24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/lib/async/bundle.ts b/src/lib/async/bundle.ts
new file mode 100644
index 000000000..e307cd437
--- /dev/null
+++ b/src/lib/async/bundle.ts
@@ -0,0 +1,24 @@
+type BundledFn<Args extends readonly unknown[], Res> = (
+  ...args: Args
+) => Promise<Res>
+
+/**
+ * A helper which ensures that multiple calls to an async function
+ * only produces one in-flight request at a time.
+ */
+export function bundleAsync<Args extends readonly unknown[], Res>(
+  fn: BundledFn<Args, Res>,
+): BundledFn<Args, Res> {
+  let promise: Promise<Res> | undefined
+  return async (...args) => {
+    if (promise) {
+      return promise
+    }
+    promise = fn(...args)
+    try {
+      return await promise
+    } finally {
+      promise = undefined
+    }
+  }
+}