@sanity/util 6.12.1-next.1 → 6.13.0-next.17

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/client.d.ts CHANGED
@@ -4,6 +4,6 @@ import { SanityClient } from "@sanity/client";
4
4
  * requests. Keeps the concurrency limit state and returns wrapped clients with
5
5
  * that same state if the `clone` `config` or `withConfig` methods are called.
6
6
  */
7
- declare function createClientConcurrencyLimiter(maxConcurrency: number): (input: SanityClient) => SanityClient;
7
+ declare function createClientConcurrencyLimiter(maxConcurrency: number, defaultSignal?: AbortSignal): (input: SanityClient) => SanityClient;
8
8
  export { createClientConcurrencyLimiter };
9
9
  //# sourceMappingURL=client.d.ts.map
package/lib/client.js CHANGED
@@ -1,22 +1,39 @@
1
- import { t as ConcurrencyLimiter } from "./concurrency-limiter-C6gDjN0m.js";
2
- import { finalize, from, switchMap } from "rxjs";
1
+ import { t as ConcurrencyLimiter } from "./concurrency-limiter-BSWisa-q.js";
2
+ import { Observable, defer, finalize, switchMap } from "rxjs";
3
+ function acquireSlot(limiter, signal) {
4
+ return new Observable((subscriber) => {
5
+ let subscriptionController = new AbortController(), waitSignal = signal ? AbortSignal.any([signal, subscriptionController.signal]) : subscriptionController.signal;
6
+ return limiter.ready(waitSignal).then(() => {
7
+ if (subscriber.closed) {
8
+ limiter.release();
9
+ return;
10
+ }
11
+ subscriber.next(limiter.release), subscriber.complete();
12
+ }, (error) => subscriber.error(error)), () => subscriptionController.abort();
13
+ });
14
+ }
15
+ function runObservable(limiter, work, signal) {
16
+ return acquireSlot(limiter, signal).pipe(switchMap((release) => defer(() => (signal?.throwIfAborted(), work())).pipe(finalize(release))));
17
+ }
3
18
  /**
4
19
  * Decorates a sanity client to limit the concurrency of `client.fetch`
5
20
  * requests. Keeps the concurrency limit state and returns wrapped clients with
6
21
  * that same state if the `clone` `config` or `withConfig` methods are called.
7
22
  */
8
- function createClientConcurrencyLimiter(maxConcurrency) {
23
+ function createClientConcurrencyLimiter(maxConcurrency, defaultSignal) {
9
24
  let limiter = new ConcurrencyLimiter(maxConcurrency);
25
+ function resolveSignal(signal) {
26
+ return !defaultSignal || defaultSignal === signal ? signal || defaultSignal : signal ? AbortSignal.any([defaultSignal, signal]) : defaultSignal;
27
+ }
10
28
  function wrapClient(client) {
11
29
  return new Proxy(client, { get: (target, property) => {
12
30
  switch (property) {
13
- case "fetch": return async (...args) => {
14
- await limiter.ready();
15
- try {
16
- return await target.fetch(...args);
17
- } finally {
18
- limiter.release();
19
- }
31
+ case "fetch": return (...args) => {
32
+ let signal = resolveSignal(args[2]?.signal);
33
+ return signal !== args[2]?.signal && (args[2] = {
34
+ ...args[2],
35
+ signal
36
+ }), limiter.run(() => target.fetch(...args), signal);
20
37
  };
21
38
  case "clone": return (...args) => wrapClient(target.clone(...args));
22
39
  case "config": return (...args) => {
@@ -32,7 +49,13 @@ function createClientConcurrencyLimiter(maxConcurrency) {
32
49
  function wrapObservableClient(observableSanityClient) {
33
50
  return new Proxy(observableSanityClient, { get: (target, property) => {
34
51
  switch (property) {
35
- case "fetch": return (...args) => from(limiter.ready()).pipe(switchMap(() => target.fetch(...args)), finalize(() => limiter.release()));
52
+ case "fetch": return (...args) => {
53
+ let signal = resolveSignal(args[2]?.signal);
54
+ return signal !== args[2]?.signal && (args[2] = {
55
+ ...args[2],
56
+ signal
57
+ }), runObservable(limiter, () => target.fetch(...args), signal);
58
+ };
36
59
  case "clone": return (...args) => wrapObservableClient(target.clone(...args));
37
60
  case "config": return (...args) => {
38
61
  let result = target.config(...args);
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../src/client/concurrency-limiter/createClientConcurrencyLimiter.ts"],"sourcesContent":["import {type ObservableSanityClient, type SanityClient} from '@sanity/client'\nimport {finalize, from, switchMap} from 'rxjs'\n\nimport {ConcurrencyLimiter} from '../../concurrency-limiter'\n\n/**\n * Decorates a sanity client to limit the concurrency of `client.fetch`\n * requests. Keeps the concurrency limit state and returns wrapped clients with\n * that same state if the `clone` `config` or `withConfig` methods are called.\n */\nexport function createClientConcurrencyLimiter(\n maxConcurrency: number,\n): (input: SanityClient) => SanityClient {\n const limiter = new ConcurrencyLimiter(maxConcurrency)\n\n function wrapClient(client: SanityClient): SanityClient {\n return new Proxy(client, {\n get: (target, property) => {\n switch (property) {\n case 'fetch': {\n return async (...args: Parameters<SanityClient['fetch']>) => {\n await limiter.ready()\n try {\n // note we want to await before we return so the finally block\n // will run after the promise has been fulfilled or rejected\n return await target.fetch(...args)\n } finally {\n limiter.release()\n }\n }\n }\n case 'clone': {\n return (...args: Parameters<SanityClient['clone']>) => {\n return wrapClient(target.clone(...args))\n }\n }\n case 'config': {\n return (...args: Parameters<SanityClient['config']>) => {\n const result = target.config(...args)\n\n // if there is a config, it returns a client so we need to wrap again\n if (args[0]) return wrapClient(result)\n return result\n }\n }\n case 'withConfig': {\n return (...args: Parameters<SanityClient['withConfig']>) => {\n return wrapClient(target.withConfig(...args))\n }\n }\n case 'observable': {\n return wrapObservableClient(target.observable)\n }\n default: {\n return target[property as keyof SanityClient]\n }\n }\n },\n })\n }\n\n function wrapObservableClient(\n observableSanityClient: ObservableSanityClient,\n ): ObservableSanityClient {\n return new Proxy(observableSanityClient, {\n get: (target, property) => {\n switch (property) {\n case 'fetch': {\n return (...args: Parameters<ObservableSanityClient['fetch']>) =>\n from(limiter.ready()).pipe(\n switchMap(() => target.fetch(...args)),\n finalize(() => limiter.release()),\n )\n }\n case 'clone': {\n return (...args: Parameters<ObservableSanityClient['clone']>) => {\n return wrapObservableClient(target.clone(...args))\n }\n }\n case 'config': {\n return (...args: Parameters<ObservableSanityClient['config']>) => {\n const result = target.config(...args)\n\n // if there is a config, it returns a client so we need to wrap again\n if (args[0]) return wrapObservableClient(result)\n return result\n }\n }\n case 'withConfig': {\n return (...args: Parameters<ObservableSanityClient['withConfig']>) => {\n return wrapObservableClient(target.withConfig(...args))\n }\n }\n default: {\n return target[property as keyof ObservableSanityClient]\n }\n }\n },\n })\n }\n\n return wrapClient\n}\n"],"mappings":";;;;;;;AAUA,SAAgB,+BACd,gBACuC;CACvC,IAAM,UAAU,IAAI,mBAAmB,cAAc;CAErD,SAAS,WAAW,QAAoC;EACtD,OAAO,IAAI,MAAM,QAAQ,EACvB,MAAM,QAAQ,aAAa;GACzB,QAAQ,UAAR;IACE,KAAK,SACH,OAAO,OAAO,GAAG,SAA4C;KAC3D,MAAM,QAAQ,MAAM;KACpB,IAAI;MAGF,OAAO,MAAM,OAAO,MAAM,GAAG,IAAI;KACnC,UAAU;MACR,QAAQ,QAAQ;KAClB;IACF;IAEF,KAAK,SACH,QAAQ,GAAG,SACF,WAAW,OAAO,MAAM,GAAG,IAAI,CAAC;IAG3C,KAAK,UACH,QAAQ,GAAG,SAA6C;KACtD,IAAM,SAAS,OAAO,OAAO,GAAG,IAAI;KAIpC,OADI,KAAK,KAAW,WAAW,MAAM,IAC9B;IACT;IAEF,KAAK,cACH,QAAQ,GAAG,SACF,WAAW,OAAO,WAAW,GAAG,IAAI,CAAC;IAGhD,KAAK,cACH,OAAO,qBAAqB,OAAO,UAAU;IAE/C,SACE,OAAO,OAAO;GAElB;EACF,EACF,CAAC;CACH;CAEA,SAAS,qBACP,wBACwB;EACxB,OAAO,IAAI,MAAM,wBAAwB,EACvC,MAAM,QAAQ,aAAa;GACzB,QAAQ,UAAR;IACE,KAAK,SACH,QAAQ,GAAG,SACT,KAAK,QAAQ,MAAM,CAAC,CAAC,CAAC,KACpB,gBAAgB,OAAO,MAAM,GAAG,IAAI,CAAC,GACrC,eAAe,QAAQ,QAAQ,CAAC,CAClC;IAEJ,KAAK,SACH,QAAQ,GAAG,SACF,qBAAqB,OAAO,MAAM,GAAG,IAAI,CAAC;IAGrD,KAAK,UACH,QAAQ,GAAG,SAAuD;KAChE,IAAM,SAAS,OAAO,OAAO,GAAG,IAAI;KAIpC,OADI,KAAK,KAAW,qBAAqB,MAAM,IACxC;IACT;IAEF,KAAK,cACH,QAAQ,GAAG,SACF,qBAAqB,OAAO,WAAW,GAAG,IAAI,CAAC;IAG1D,SACE,OAAO,OAAO;GAElB;EACF,EACF,CAAC;CACH;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"client.js","names":[],"sources":["../src/client/concurrency-limiter/createClientConcurrencyLimiter.ts"],"sourcesContent":["import {type ObservableSanityClient, type SanityClient} from '@sanity/client'\nimport {defer, finalize, Observable, switchMap} from 'rxjs'\n\nimport {ConcurrencyLimiter} from '../../concurrency-limiter'\n\nfunction acquireSlot(limiter: ConcurrencyLimiter, signal?: AbortSignal): Observable<() => void> {\n return new Observable((subscriber) => {\n const subscriptionController = new AbortController()\n const waitSignal = signal\n ? AbortSignal.any([signal, subscriptionController.signal])\n : subscriptionController.signal\n\n void limiter.ready(waitSignal).then(\n () => {\n if (subscriber.closed) {\n limiter.release()\n return\n }\n\n subscriber.next(limiter.release)\n subscriber.complete()\n },\n (error) => subscriber.error(error),\n )\n\n return () => subscriptionController.abort()\n })\n}\n\nfunction runObservable<T>(\n limiter: ConcurrencyLimiter,\n work: () => Observable<T>,\n signal?: AbortSignal,\n): Observable<T> {\n return acquireSlot(limiter, signal).pipe(\n switchMap((release) =>\n defer(() => {\n signal?.throwIfAborted()\n return work()\n }).pipe(finalize(release)),\n ),\n )\n}\n\n/**\n * Decorates a sanity client to limit the concurrency of `client.fetch`\n * requests. Keeps the concurrency limit state and returns wrapped clients with\n * that same state if the `clone` `config` or `withConfig` methods are called.\n */\nexport function createClientConcurrencyLimiter(\n maxConcurrency: number,\n defaultSignal?: AbortSignal,\n): (input: SanityClient) => SanityClient {\n const limiter = new ConcurrencyLimiter(maxConcurrency)\n\n function resolveSignal(signal?: AbortSignal): AbortSignal | undefined {\n if (!defaultSignal || defaultSignal === signal) return signal || defaultSignal\n if (!signal) return defaultSignal\n return AbortSignal.any([defaultSignal, signal])\n }\n\n function wrapClient(client: SanityClient): SanityClient {\n return new Proxy(client, {\n get: (target, property) => {\n switch (property) {\n case 'fetch': {\n return (...args: Parameters<SanityClient['fetch']>) => {\n const signal = resolveSignal(args[2]?.signal)\n if (signal !== args[2]?.signal) args[2] = {...args[2], signal}\n return limiter.run(() => target.fetch(...args), signal)\n }\n }\n case 'clone': {\n return (...args: Parameters<SanityClient['clone']>) => {\n return wrapClient(target.clone(...args))\n }\n }\n case 'config': {\n return (...args: Parameters<SanityClient['config']>) => {\n const result = target.config(...args)\n\n // if there is a config, it returns a client so we need to wrap again\n if (args[0]) return wrapClient(result)\n return result\n }\n }\n case 'withConfig': {\n return (...args: Parameters<SanityClient['withConfig']>) => {\n return wrapClient(target.withConfig(...args))\n }\n }\n case 'observable': {\n return wrapObservableClient(target.observable)\n }\n default: {\n return target[property as keyof SanityClient]\n }\n }\n },\n })\n }\n\n function wrapObservableClient(\n observableSanityClient: ObservableSanityClient,\n ): ObservableSanityClient {\n return new Proxy(observableSanityClient, {\n get: (target, property) => {\n switch (property) {\n case 'fetch': {\n return (...args: Parameters<ObservableSanityClient['fetch']>) => {\n const signal = resolveSignal(args[2]?.signal)\n if (signal !== args[2]?.signal) args[2] = {...args[2], signal}\n return runObservable(limiter, () => target.fetch(...args), signal)\n }\n }\n case 'clone': {\n return (...args: Parameters<ObservableSanityClient['clone']>) => {\n return wrapObservableClient(target.clone(...args))\n }\n }\n case 'config': {\n return (...args: Parameters<ObservableSanityClient['config']>) => {\n const result = target.config(...args)\n\n // if there is a config, it returns a client so we need to wrap again\n if (args[0]) return wrapObservableClient(result)\n return result\n }\n }\n case 'withConfig': {\n return (...args: Parameters<ObservableSanityClient['withConfig']>) => {\n return wrapObservableClient(target.withConfig(...args))\n }\n }\n default: {\n return target[property as keyof ObservableSanityClient]\n }\n }\n },\n })\n }\n\n return wrapClient\n}\n"],"mappings":";;AAKA,SAAS,YAAY,SAA6B,QAA8C;CAC9F,OAAO,IAAI,YAAY,eAAe;EACpC,IAAM,yBAAyB,IAAI,gBAAgB,GAC7C,aAAa,SACf,YAAY,IAAI,CAAC,QAAQ,uBAAuB,MAAM,CAAC,IACvD,uBAAuB;EAe3B,OAbA,QAAa,MAAM,UAAU,CAAC,CAAC,WACvB;GACJ,IAAI,WAAW,QAAQ;IACrB,QAAQ,QAAQ;IAChB;GACF;GAGA,AADA,WAAW,KAAK,QAAQ,OAAO,GAC/B,WAAW,SAAS;EACtB,IACC,UAAU,WAAW,MAAM,KAAK,CACnC,SAEa,uBAAuB,MAAM;CAC5C,CAAC;AACH;AAEA,SAAS,cACP,SACA,MACA,QACe;CACf,OAAO,YAAY,SAAS,MAAM,CAAC,CAAC,KAClC,WAAW,YACT,aACE,QAAQ,eAAe,GAChB,KAAK,EACb,CAAC,CAAC,KAAK,SAAS,OAAO,CAAC,CAC3B,CACF;AACF;;;;;;AAOA,SAAgB,+BACd,gBACA,eACuC;CACvC,IAAM,UAAU,IAAI,mBAAmB,cAAc;CAErD,SAAS,cAAc,QAA+C;EAGpE,OAFI,CAAC,iBAAiB,kBAAkB,SAAe,UAAU,gBAC5D,SACE,YAAY,IAAI,CAAC,eAAe,MAAM,CAAC,IAD1B;CAEtB;CAEA,SAAS,WAAW,QAAoC;EACtD,OAAO,IAAI,MAAM,QAAQ,EACvB,MAAM,QAAQ,aAAa;GACzB,QAAQ,UAAR;IACE,KAAK,SACH,QAAQ,GAAG,SAA4C;KACrD,IAAM,SAAS,cAAc,KAAK,EAAE,EAAE,MAAM;KAE5C,OADI,WAAW,KAAK,EAAE,EAAE,WAAQ,KAAK,KAAK;MAAC,GAAG,KAAK;MAAI;KAAM,IACtD,QAAQ,UAAU,OAAO,MAAM,GAAG,IAAI,GAAG,MAAM;IACxD;IAEF,KAAK,SACH,QAAQ,GAAG,SACF,WAAW,OAAO,MAAM,GAAG,IAAI,CAAC;IAG3C,KAAK,UACH,QAAQ,GAAG,SAA6C;KACtD,IAAM,SAAS,OAAO,OAAO,GAAG,IAAI;KAIpC,OADI,KAAK,KAAW,WAAW,MAAM,IAC9B;IACT;IAEF,KAAK,cACH,QAAQ,GAAG,SACF,WAAW,OAAO,WAAW,GAAG,IAAI,CAAC;IAGhD,KAAK,cACH,OAAO,qBAAqB,OAAO,UAAU;IAE/C,SACE,OAAO,OAAO;GAElB;EACF,EACF,CAAC;CACH;CAEA,SAAS,qBACP,wBACwB;EACxB,OAAO,IAAI,MAAM,wBAAwB,EACvC,MAAM,QAAQ,aAAa;GACzB,QAAQ,UAAR;IACE,KAAK,SACH,QAAQ,GAAG,SAAsD;KAC/D,IAAM,SAAS,cAAc,KAAK,EAAE,EAAE,MAAM;KAE5C,OADI,WAAW,KAAK,EAAE,EAAE,WAAQ,KAAK,KAAK;MAAC,GAAG,KAAK;MAAI;KAAM,IACtD,cAAc,eAAe,OAAO,MAAM,GAAG,IAAI,GAAG,MAAM;IACnE;IAEF,KAAK,SACH,QAAQ,GAAG,SACF,qBAAqB,OAAO,MAAM,GAAG,IAAI,CAAC;IAGrD,KAAK,UACH,QAAQ,GAAG,SAAuD;KAChE,IAAM,SAAS,OAAO,OAAO,GAAG,IAAI;KAIpC,OADI,KAAK,KAAW,qBAAqB,MAAM,IACxC;IACT;IAEF,KAAK,cACH,QAAQ,GAAG,SACF,qBAAqB,OAAO,WAAW,GAAG,IAAI,CAAC;IAG1D,SACE,OAAO,OAAO;GAElB;EACF,EACF,CAAC;CACH;CAEA,OAAO;AACT"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * ConcurrencyLimiter manages the number of concurrent operations that can be performed.
3
+ * It ensures that the number of operations does not exceed a specified maximum limit.
4
+ */
5
+ var ConcurrencyLimiter = class {
6
+ current = 0;
7
+ resolvers = [];
8
+ max;
9
+ constructor(max) {
10
+ this.max = max;
11
+ }
12
+ /**
13
+ * Indicates when a slot for a new operation is ready.
14
+ * If under the limit, it resolves immediately; otherwise, it waits until a slot is free.
15
+ */
16
+ ready = (signal) => signal?.aborted ? Promise.reject(signal.reason) : this.max === Infinity ? Promise.resolve() : this.current < this.max ? (this.current++, Promise.resolve()) : new Promise((resolve, reject) => {
17
+ let pending = {
18
+ resolve,
19
+ reject,
20
+ signal,
21
+ onAbort: () => {}
22
+ };
23
+ pending.onAbort = () => {
24
+ let index = this.resolvers.indexOf(pending);
25
+ index !== -1 && this.resolvers.splice(index, 1), signal && reject(signal.reason);
26
+ }, signal?.addEventListener("abort", pending.onAbort, { once: !0 }), this.resolvers.push(pending);
27
+ });
28
+ /** Runs an operation when a concurrency slot is available. */
29
+ run = async (work, signal) => {
30
+ await this.ready(signal);
31
+ try {
32
+ return signal?.throwIfAborted(), await work();
33
+ } finally {
34
+ this.release();
35
+ }
36
+ };
37
+ /**
38
+ * Releases a slot, decrementing the current count of operations if nothing is in the queue.
39
+ * If there are operations waiting, it allows the next one in the queue to proceed.
40
+ */
41
+ release = () => {
42
+ if (this.max === Infinity) return;
43
+ let next = this.resolvers.shift();
44
+ for (; next;) {
45
+ if (next.signal?.removeEventListener("abort", next.onAbort), next.signal?.aborted) {
46
+ next.reject(next.signal.reason), next = this.resolvers.shift();
47
+ continue;
48
+ }
49
+ next.resolve();
50
+ return;
51
+ }
52
+ this.current = Math.max(0, this.current - 1);
53
+ };
54
+ };
55
+ export { ConcurrencyLimiter as t };
56
+
57
+ //# sourceMappingURL=concurrency-limiter-BSWisa-q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency-limiter-BSWisa-q.js","names":[],"sources":["../src/concurrency-limiter.ts"],"sourcesContent":["/**\n * ConcurrencyLimiter manages the number of concurrent operations that can be performed.\n * It ensures that the number of operations does not exceed a specified maximum limit.\n */\nexport class ConcurrencyLimiter {\n current = 0\n resolvers: Array<{\n resolve: () => void\n reject: (reason?: unknown) => void\n signal?: AbortSignal\n onAbort: () => void\n }> = []\n public max: number\n constructor(max: number) {\n this.max = max\n }\n\n /**\n * Indicates when a slot for a new operation is ready.\n * If under the limit, it resolves immediately; otherwise, it waits until a slot is free.\n */\n ready = (signal?: AbortSignal): Promise<void> => {\n if (signal?.aborted) return Promise.reject(signal.reason)\n if (this.max === Infinity) return Promise.resolve()\n\n if (this.current < this.max) {\n this.current++\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve, reject) => {\n const pending = {resolve, reject, signal, onAbort: () => {}}\n pending.onAbort = () => {\n const index = this.resolvers.indexOf(pending)\n if (index !== -1) this.resolvers.splice(index, 1)\n if (signal) reject(signal.reason)\n }\n signal?.addEventListener('abort', pending.onAbort, {once: true})\n this.resolvers.push(pending)\n })\n }\n\n /** Runs an operation when a concurrency slot is available. */\n run = async <T>(work: () => PromiseLike<T> | T, signal?: AbortSignal): Promise<T> => {\n await this.ready(signal)\n try {\n signal?.throwIfAborted()\n return await work()\n } finally {\n this.release()\n }\n }\n\n /**\n * Releases a slot, decrementing the current count of operations if nothing is in the queue.\n * If there are operations waiting, it allows the next one in the queue to proceed.\n */\n release = (): void => {\n if (this.max === Infinity) return\n\n let next = this.resolvers.shift()\n while (next) {\n next.signal?.removeEventListener('abort', next.onAbort)\n if (next.signal?.aborted) {\n next.reject(next.signal.reason)\n next = this.resolvers.shift()\n continue\n }\n next.resolve()\n return\n }\n\n this.current = Math.max(0, this.current - 1)\n }\n}\n"],"mappings":";;;;AAIA,IAAa,qBAAb,MAAgC;CAC9B,UAAU;CACV,YAKK,CAAC;CACN;CACA,YAAY,KAAa;EACvB,KAAK,MAAM;CACb;;;;;CAMA,SAAS,WACH,QAAQ,UAAgB,QAAQ,OAAO,OAAO,MAAM,IACpD,KAAK,QAAQ,WAAiB,QAAQ,QAAQ,IAE9C,KAAK,UAAU,KAAK,OACtB,KAAK,WACE,QAAQ,QAAQ,KAGlB,IAAI,SAAe,SAAS,WAAW;EAC5C,IAAM,UAAU;GAAC;GAAS;GAAQ;GAAQ,eAAe,CAAC;EAAC;EAO3D,AANA,QAAQ,gBAAgB;GACtB,IAAM,QAAQ,KAAK,UAAU,QAAQ,OAAO;GAE5C,AADI,UAAU,MAAI,KAAK,UAAU,OAAO,OAAO,CAAC,GAC5C,UAAQ,OAAO,OAAO,MAAM;EAClC,GACA,QAAQ,iBAAiB,SAAS,QAAQ,SAAS,EAAC,MAAM,GAAI,CAAC,GAC/D,KAAK,UAAU,KAAK,OAAO;CAC7B,CAAC;;CAIH,MAAM,OAAU,MAAgC,WAAqC;EACnF,MAAM,KAAK,MAAM,MAAM;EACvB,IAAI;GAEF,OADA,QAAQ,eAAe,GAChB,MAAM,KAAK;EACpB,UAAU;GACR,KAAK,QAAQ;EACf;CACF;;;;;CAMA,gBAAsB;EACpB,IAAI,KAAK,QAAQ,UAAU;EAE3B,IAAI,OAAO,KAAK,UAAU,MAAM;EAChC,OAAO,OAAM;GAEX,IADA,KAAK,QAAQ,oBAAoB,SAAS,KAAK,OAAO,GAClD,KAAK,QAAQ,SAAS;IAExB,AADA,KAAK,OAAO,KAAK,OAAO,MAAM,GAC9B,OAAO,KAAK,UAAU,MAAM;IAC5B;GACF;GACA,KAAK,QAAQ;GACb;EACF;EAEA,KAAK,UAAU,KAAK,IAAI,GAAG,KAAK,UAAU,CAAC;CAC7C;AACF"}
@@ -4,14 +4,21 @@
4
4
  */
5
5
  declare class ConcurrencyLimiter {
6
6
  current: number;
7
- resolvers: Array<() => void>;
7
+ resolvers: Array<{
8
+ resolve: () => void;
9
+ reject: (reason?: unknown) => void;
10
+ signal?: AbortSignal;
11
+ onAbort: () => void;
12
+ }>;
8
13
  max: number;
9
14
  constructor(max: number);
10
15
  /**
11
16
  * Indicates when a slot for a new operation is ready.
12
17
  * If under the limit, it resolves immediately; otherwise, it waits until a slot is free.
13
18
  */
14
- ready: () => Promise<void>;
19
+ ready: (signal?: AbortSignal) => Promise<void>;
20
+ /** Runs an operation when a concurrency slot is available. */
21
+ run: <T>(work: () => PromiseLike<T> | T, signal?: AbortSignal) => Promise<T>;
15
22
  /**
16
23
  * Releases a slot, decrementing the current count of operations if nothing is in the queue.
17
24
  * If there are operations waiting, it allows the next one in the queue to proceed.
@@ -1,2 +1,2 @@
1
- import { t as ConcurrencyLimiter } from "./concurrency-limiter-C6gDjN0m.js";
1
+ import { t as ConcurrencyLimiter } from "./concurrency-limiter-BSWisa-q.js";
2
2
  export { ConcurrencyLimiter };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/util",
3
- "version": "6.12.1-next.1",
3
+ "version": "6.13.0-next.17",
4
4
  "description": "Utilities shared across projects of Sanity",
5
5
  "keywords": [
6
6
  "cms",
@@ -67,7 +67,7 @@
67
67
  "@date-fns/tz": "^1.5.0",
68
68
  "@date-fns/utc": "^2.1.1",
69
69
  "@sanity/client": "^8.4.0",
70
- "@sanity/types": "6.12.1-next.1+c968ee427f",
70
+ "@sanity/types": "6.13.0-next.17+8919822b49",
71
71
  "date-fns": "^4.4.0",
72
72
  "rxjs": "^7.8.2"
73
73
  },
@@ -1,35 +0,0 @@
1
- /**
2
- * ConcurrencyLimiter manages the number of concurrent operations that can be performed.
3
- * It ensures that the number of operations does not exceed a specified maximum limit.
4
- */
5
- var ConcurrencyLimiter = class {
6
- current = 0;
7
- resolvers = [];
8
- max;
9
- constructor(max) {
10
- this.max = max;
11
- }
12
- /**
13
- * Indicates when a slot for a new operation is ready.
14
- * If under the limit, it resolves immediately; otherwise, it waits until a slot is free.
15
- */
16
- ready = () => this.max === Infinity ? Promise.resolve() : this.current < this.max ? (this.current++, Promise.resolve()) : new Promise((resolve) => {
17
- this.resolvers.push(resolve);
18
- });
19
- /**
20
- * Releases a slot, decrementing the current count of operations if nothing is in the queue.
21
- * If there are operations waiting, it allows the next one in the queue to proceed.
22
- */
23
- release = () => {
24
- if (this.max === Infinity) return;
25
- let nextResolver = this.resolvers.shift();
26
- if (nextResolver) {
27
- nextResolver();
28
- return;
29
- }
30
- this.current = Math.max(0, this.current - 1);
31
- };
32
- };
33
- export { ConcurrencyLimiter as t };
34
-
35
- //# sourceMappingURL=concurrency-limiter-C6gDjN0m.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"concurrency-limiter-C6gDjN0m.js","names":[],"sources":["../src/concurrency-limiter.ts"],"sourcesContent":["/**\n * ConcurrencyLimiter manages the number of concurrent operations that can be performed.\n * It ensures that the number of operations does not exceed a specified maximum limit.\n */\nexport class ConcurrencyLimiter {\n current = 0\n resolvers: Array<() => void> = []\n public max: number\n constructor(max: number) {\n this.max = max\n }\n\n /**\n * Indicates when a slot for a new operation is ready.\n * If under the limit, it resolves immediately; otherwise, it waits until a slot is free.\n */\n ready = (): Promise<void> => {\n if (this.max === Infinity) return Promise.resolve()\n\n if (this.current < this.max) {\n this.current++\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve) => {\n this.resolvers.push(resolve)\n })\n }\n\n /**\n * Releases a slot, decrementing the current count of operations if nothing is in the queue.\n * If there are operations waiting, it allows the next one in the queue to proceed.\n */\n release = (): void => {\n if (this.max === Infinity) return\n\n const nextResolver = this.resolvers.shift()\n if (nextResolver) {\n nextResolver()\n return\n }\n\n this.current = Math.max(0, this.current - 1)\n }\n}\n"],"mappings":";;;;AAIA,IAAa,qBAAb,MAAgC;CAC9B,UAAU;CACV,YAA+B,CAAC;CAChC;CACA,YAAY,KAAa;EACvB,KAAK,MAAM;CACb;;;;;CAMA,cACM,KAAK,QAAQ,WAAiB,QAAQ,QAAQ,IAE9C,KAAK,UAAU,KAAK,OACtB,KAAK,WACE,QAAQ,QAAQ,KAGlB,IAAI,SAAe,YAAY;EACpC,KAAK,UAAU,KAAK,OAAO;CAC7B,CAAC;;;;;CAOH,gBAAsB;EACpB,IAAI,KAAK,QAAQ,UAAU;EAE3B,IAAM,eAAe,KAAK,UAAU,MAAM;EAC1C,IAAI,cAAc;GAChB,aAAa;GACb;EACF;EAEA,KAAK,UAAU,KAAK,IAAI,GAAG,KAAK,UAAU,CAAC;CAC7C;AACF"}