@sanity/util 6.19.0-next.13 → 6.19.0-next.25
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.js +2 -6
- package/lib/client.js.map +1 -1
- package/lib/{concurrency-limiter-BSWisa-q.js → concurrency-limiter-Cm1A8i7a.js} +3 -6
- package/lib/{concurrency-limiter-BSWisa-q.js.map → concurrency-limiter-Cm1A8i7a.js.map} +1 -1
- package/lib/concurrency-limiter.js +1 -2
- package/package.json +3 -3
package/lib/client.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import { t as ConcurrencyLimiter } from "./concurrency-limiter-
|
|
1
|
+
import { t as ConcurrencyLimiter } from "./concurrency-limiter-Cm1A8i7a.js";
|
|
2
2
|
import { anySignal } from "get-it/any-signal";
|
|
3
3
|
import { Observable, defer, finalize, switchMap } from "rxjs";
|
|
4
4
|
function acquireSlot(limiter, signal) {
|
|
5
5
|
return new Observable((subscriber) => {
|
|
6
6
|
let subscriptionController = new AbortController(), waitSignal = signal ? anySignal([signal, subscriptionController.signal]) : subscriptionController.signal;
|
|
7
7
|
return limiter.ready(waitSignal).then(() => {
|
|
8
|
-
|
|
9
|
-
limiter.release();
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
subscriber.next(limiter.release), subscriber.complete();
|
|
8
|
+
subscriber.closed ? limiter.release() : (subscriber.next(limiter.release), subscriber.complete());
|
|
13
9
|
}, (error) => subscriber.error(error)), () => subscriptionController.abort();
|
|
14
10
|
});
|
|
15
11
|
}
|
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 {anySignal} from 'get-it/any-signal'\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 ? anySignal([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 anySignal([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":";;;AAMA,SAAS,YAAY,SAA6B,QAA8C;CAC9F,OAAO,IAAI,YAAY,eAAe;EACpC,IAAM,yBAAyB,IAAI,gBAAgB,GAC7C,aAAa,SACf,UAAU,CAAC,QAAQ,uBAAuB,MAAM,CAAC,IACjD,uBAAuB;EAe3B,OAbA,QAAa,MAAM,UAAU,CAAC,CAAC,WACvB;GACJ,
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../src/client/concurrency-limiter/createClientConcurrencyLimiter.ts"],"sourcesContent":["import {type ObservableSanityClient, type SanityClient} from '@sanity/client'\nimport {anySignal} from 'get-it/any-signal'\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 ? anySignal([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 anySignal([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":";;;AAMA,SAAS,YAAY,SAA6B,QAA8C;CAC9F,OAAO,IAAI,YAAY,eAAe;EACpC,IAAM,yBAAyB,IAAI,gBAAgB,GAC7C,aAAa,SACf,UAAU,CAAC,QAAQ,uBAAuB,MAAM,CAAC,IACjD,uBAAuB;EAe3B,OAbA,QAAa,MAAM,UAAU,CAAC,CAAC,WACvB;GACJ,AAAI,WAAW,SACb,QAAQ,QAAQ,KAIlB,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,UAAU,CAAC,eAAe,MAAM,CAAC,IADpB;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"}
|
|
@@ -41,11 +41,8 @@ var ConcurrencyLimiter = class {
|
|
|
41
41
|
release = () => {
|
|
42
42
|
if (this.max === Infinity) return;
|
|
43
43
|
let next = this.resolvers.shift();
|
|
44
|
-
for (; next;)
|
|
45
|
-
|
|
46
|
-
next.reject(next.signal.reason), next = this.resolvers.shift();
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
44
|
+
for (; next;) if (next.signal?.removeEventListener("abort", next.onAbort), next.signal?.aborted) next.reject(next.signal.reason), next = this.resolvers.shift();
|
|
45
|
+
else {
|
|
49
46
|
next.resolve();
|
|
50
47
|
return;
|
|
51
48
|
}
|
|
@@ -54,4 +51,4 @@ var ConcurrencyLimiter = class {
|
|
|
54
51
|
};
|
|
55
52
|
export { ConcurrencyLimiter as t };
|
|
56
53
|
|
|
57
|
-
//# sourceMappingURL=concurrency-limiter-
|
|
54
|
+
//# sourceMappingURL=concurrency-limiter-Cm1A8i7a.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"concurrency-limiter-
|
|
1
|
+
{"version":3,"file":"concurrency-limiter-Cm1A8i7a.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,OAEL,IADA,KAAK,QAAQ,oBAAoB,SAAS,KAAK,OAAO,GAClD,KAAK,QAAQ,SAEf,AADA,KAAK,OAAO,KAAK,OAAO,MAAM,GAC9B,OAAO,KAAK,UAAU,MAAM;OAG9B;QAAK,QAAQ;GACb;EADa;EAIf,KAAK,UAAU,KAAK,IAAI,GAAG,KAAK,UAAU,CAAC;CAC7C;AACF"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { ConcurrencyLimiter };
|
|
1
|
+
export { t as ConcurrencyLimiter } from "./concurrency-limiter-Cm1A8i7a.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/util",
|
|
3
|
-
"version": "6.19.0-next.
|
|
3
|
+
"version": "6.19.0-next.25",
|
|
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.9.0",
|
|
70
|
-
"@sanity/types": "6.19.0-next.
|
|
70
|
+
"@sanity/types": "6.19.0-next.25+285b064ed0",
|
|
71
71
|
"date-fns": "^4.4.0",
|
|
72
72
|
"get-it": "^9.6.1",
|
|
73
73
|
"rxjs": "^7.8.2"
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"@types/node": "^24.13.3",
|
|
80
80
|
"tsdown": "^0.23.0",
|
|
81
81
|
"typescript": "^7.0.2",
|
|
82
|
-
"vite": "^8.3.
|
|
82
|
+
"vite": "^8.3.4",
|
|
83
83
|
"vitest": "^5.0.3"
|
|
84
84
|
},
|
|
85
85
|
"browserslist": [
|