@vielzeug/sourcerer 3.0.0 → 26.10.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.
Files changed (46) hide show
  1. package/dist/asyncSource.cjs +1 -1
  2. package/dist/asyncSource.cjs.map +1 -1
  3. package/dist/asyncSource.js +1 -63
  4. package/dist/asyncSource.js.map +1 -1
  5. package/dist/cursorSource.cjs +1 -1
  6. package/dist/cursorSource.cjs.map +1 -1
  7. package/dist/cursorSource.js +1 -114
  8. package/dist/cursorSource.js.map +1 -1
  9. package/dist/errors.cjs +1 -1
  10. package/dist/errors.cjs.map +1 -1
  11. package/dist/errors.d.ts +0 -3
  12. package/dist/errors.d.ts.map +1 -1
  13. package/dist/errors.js +1 -17
  14. package/dist/errors.js.map +1 -1
  15. package/dist/index.js +1 -6
  16. package/dist/infiniteSource.cjs +1 -1
  17. package/dist/infiniteSource.cjs.map +1 -1
  18. package/dist/infiniteSource.js +1 -111
  19. package/dist/infiniteSource.js.map +1 -1
  20. package/dist/localSource.cjs +1 -1
  21. package/dist/localSource.cjs.map +1 -1
  22. package/dist/localSource.js +1 -70
  23. package/dist/localSource.js.map +1 -1
  24. package/dist/pageSource.cjs +1 -1
  25. package/dist/pageSource.cjs.map +1 -1
  26. package/dist/pageSource.js +1 -116
  27. package/dist/pageSource.js.map +1 -1
  28. package/dist/pagination.cjs +1 -1
  29. package/dist/pagination.cjs.map +1 -1
  30. package/dist/pagination.js +1 -24
  31. package/dist/pagination.js.map +1 -1
  32. package/dist/requestController.cjs +1 -1
  33. package/dist/requestController.cjs.map +1 -1
  34. package/dist/requestController.js +1 -30
  35. package/dist/requestController.js.map +1 -1
  36. package/dist/sourceStore.cjs +1 -1
  37. package/dist/sourceStore.cjs.map +1 -1
  38. package/dist/sourceStore.js +1 -37
  39. package/dist/sourceStore.js.map +1 -1
  40. package/dist/sourcerer.cjs +1 -1
  41. package/dist/sourcerer.cjs.map +1 -1
  42. package/dist/sourcerer.iife.js +1 -1
  43. package/dist/sourcerer.iife.js.map +1 -1
  44. package/dist/sourcerer.js +1 -1
  45. package/dist/sourcerer.js.map +1 -1
  46. package/package.json +6 -6
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs"),t=require("./requestController.cjs"),n=require("./sourceStore.cjs");let r=require("@vielzeug/arsenal");var i=(e,t)=>new Promise((n,i)=>{let a=()=>i((0,r.abortError)(t,`The operation was aborted.`));if(t.aborted){a();return}t.addEventListener(`abort`,a,{once:!0});let o;try{o=e(t)}catch(e){t.removeEventListener(`abort`,a),i(e);return}o.then(e=>{t.removeEventListener(`abort`,a),n(e)},e=>{t.removeEventListener(`abort`,a),i(e)})});function a(r){let a=n.createSourceStore(r),o=t.createRequestController();return{get disposalSignal(){return a.disposalSignal},dispose(){o.dispose(),a.dispose()},get disposed(){return a.disposed},async fetch(n){if(a.disposed)throw new e.SourcererDisposedError;let r=o.begin(),s=a.value;a.set(n.pending(s));try{let e=await i(n.load,r.signal);if(!r.isCurrent()||a.disposed)return;let t=n.success(e);n.commit?.(t,e),a.set(t)}catch(e){if(!r.isCurrent()||a.disposed)return;let i=t.toError(e);throw a.set(n.failure(s,i)),i}finally{r.finish()}},get state(){return a.value},subscribe:a.subscribe}}exports.createAsyncSource=a;
1
+ const e=require("./errors.cjs"),t=require("./requestController.cjs"),n=require("./sourceStore.cjs");let r=require("@vielzeug/arsenal");var loadWithSignal=(e,t)=>new Promise((n,i)=>{let abort=()=>i((0,r.abortError)(t,`The operation was aborted.`));if(t.aborted){abort();return}t.addEventListener(`abort`,abort,{once:!0});let a;try{a=e(t)}catch(e){t.removeEventListener(`abort`,abort),i(e);return}a.then(e=>{t.removeEventListener(`abort`,abort),n(e)},e=>{t.removeEventListener(`abort`,abort),i(e)})});function createAsyncSource(r){let i=n.createSourceStore(r),a=t.createRequestController();return{get disposalSignal(){return i.disposalSignal},dispose(){a.dispose(),i.dispose()},get disposed(){return i.disposed},async fetch(n){if(i.disposed)throw new e.SourcererDisposedError;let r=a.begin(),o=i.value;i.set(n.pending(o));try{let e=await loadWithSignal(n.load,r.signal);if(!r.isCurrent()||i.disposed)return;let t=n.success(e);n.commit?.(t,e),i.set(t)}catch(e){if(!r.isCurrent()||i.disposed)return;let a=t.toError(e);throw i.set(n.failure(o,a)),a}finally{r.finish()}},get state(){return i.value},subscribe:i.subscribe}}exports.createAsyncSource=createAsyncSource;
2
2
  //# sourceMappingURL=asyncSource.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"asyncSource.cjs","names":[],"sources":["../src/asyncSource.ts"],"sourcesContent":["import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n"],"mappings":"uIAMA,IAAM,GAAqB,EAA2C,IACpE,IAAI,SAAS,EAAS,IAAW,CAC/B,IAAM,MAAoB,GAAA,EAAO,EAAA,WAAA,CAAW,EAAQ,4BAA4B,CAAC,EACjF,GAAI,EAAO,QAAS,CAClB,EAAM,EACN,MACF,CAEA,EAAO,iBAAiB,QAAS,EAAO,CAAE,KAAM,EAAK,CAAC,EACtD,IAAI,EACJ,GAAI,CACF,EAAS,EAAK,CAAM,CACtB,OAAS,EAAO,CACd,EAAO,oBAAoB,QAAS,CAAK,EACzC,EAAO,CAAK,EACZ,MACF,CAEA,EAAO,KACJ,GAAU,CACT,EAAO,oBAAoB,QAAS,CAAK,EACzC,EAAQ,CAAK,CACf,EACC,GAAmB,CAClB,EAAO,oBAAoB,QAAS,CAAK,EACzC,EAAO,CAAK,CACd,CACF,CACF,CAAC,EAoBH,SAAgB,EAA0B,EAAsC,CAC9E,IAAM,EAAQ,EAAA,kBAAkB,CAAO,EACjC,EAAW,EAAA,wBAAwB,EAEzC,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAM,cACf,EAEA,SAAU,CACR,EAAS,QAAQ,EACjB,EAAM,QAAQ,CAChB,EAEA,IAAI,UAAW,CACb,OAAO,EAAM,QACf,EAEA,MAAM,MAAM,EAAS,CACnB,GAAI,EAAM,SAAU,MAAM,IAAI,EAAA,uBAE9B,IAAM,EAAU,EAAS,MAAM,EACzB,EAAW,EAAM,MACvB,EAAM,IAAI,EAAQ,QAAQ,CAAQ,CAAC,EAEnC,GAAI,CACF,IAAM,EAAS,MAAM,EAAe,EAAQ,KAAM,EAAQ,MAAM,EAChE,GAAI,CAAC,EAAQ,UAAU,GAAK,EAAM,SAAU,OAE5C,IAAM,EAAQ,EAAQ,QAAQ,CAAM,EACpC,EAAQ,SAAS,EAAO,CAAM,EAC9B,EAAM,IAAI,CAAK,CACjB,OAAS,EAAiB,CACxB,GAAI,CAAC,EAAQ,UAAU,GAAK,EAAM,SAAU,OAE5C,IAAM,EAAQ,EAAA,QAAQ,CAAM,EAE5B,MADA,EAAM,IAAI,EAAQ,QAAQ,EAAU,CAAK,CAAC,EACpC,CACR,QAAU,CACR,EAAQ,OAAO,CACjB,CACF,EAEA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,EAEA,UAAW,EAAM,SACnB,CACF"}
1
+ {"version":3,"file":"asyncSource.cjs","names":[],"sources":["../src/asyncSource.ts"],"sourcesContent":["import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n"],"mappings":"uIAMA,IAAM,gBAAqB,EAA2C,IACpE,IAAI,SAAS,EAAS,IAAW,CAC/B,IAAM,UAAoB,GAAA,EAAO,EAAA,WAAA,CAAW,EAAQ,4BAA4B,CAAC,EACjF,GAAI,EAAO,QAAS,CAClB,MAAM,EACN,MACF,CAEA,EAAO,iBAAiB,QAAS,MAAO,CAAE,KAAM,EAAK,CAAC,EACtD,IAAI,EACJ,GAAI,CACF,EAAS,EAAK,CAAM,CACtB,OAAS,EAAO,CACd,EAAO,oBAAoB,QAAS,KAAK,EACzC,EAAO,CAAK,EACZ,MACF,CAEA,EAAO,KACJ,GAAU,CACT,EAAO,oBAAoB,QAAS,KAAK,EACzC,EAAQ,CAAK,CACf,EACC,GAAmB,CAClB,EAAO,oBAAoB,QAAS,KAAK,EACzC,EAAO,CAAK,CACd,CACF,CACF,CAAC,EAoBH,SAAgB,kBAA0B,EAAsC,CAC9E,IAAM,EAAQ,EAAA,kBAAkB,CAAO,EACjC,EAAW,EAAA,wBAAwB,EAEzC,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAM,cACf,EAEA,SAAU,CACR,EAAS,QAAQ,EACjB,EAAM,QAAQ,CAChB,EAEA,IAAI,UAAW,CACb,OAAO,EAAM,QACf,EAEA,MAAM,MAAM,EAAS,CACnB,GAAI,EAAM,SAAU,MAAM,IAAI,EAAA,uBAE9B,IAAM,EAAU,EAAS,MAAM,EACzB,EAAW,EAAM,MACvB,EAAM,IAAI,EAAQ,QAAQ,CAAQ,CAAC,EAEnC,GAAI,CACF,IAAM,EAAS,MAAM,eAAe,EAAQ,KAAM,EAAQ,MAAM,EAChE,GAAI,CAAC,EAAQ,UAAU,GAAK,EAAM,SAAU,OAE5C,IAAM,EAAQ,EAAQ,QAAQ,CAAM,EACpC,EAAQ,SAAS,EAAO,CAAM,EAC9B,EAAM,IAAI,CAAK,CACjB,OAAS,EAAiB,CACxB,GAAI,CAAC,EAAQ,UAAU,GAAK,EAAM,SAAU,OAE5C,IAAM,EAAQ,EAAA,QAAQ,CAAM,EAE5B,MADA,EAAM,IAAI,EAAQ,QAAQ,EAAU,CAAK,CAAC,EACpC,CACR,QAAU,CACR,EAAQ,OAAO,CACjB,CACF,EAEA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,EAEA,UAAW,EAAM,SACnB,CACF"}
@@ -1,64 +1,2 @@
1
- import { SourcererDisposedError as e } from "./errors.js";
2
- import { createRequestController as t, toError as n } from "./requestController.js";
3
- import { createSourceStore as r } from "./sourceStore.js";
4
- import { abortError as i } from "@vielzeug/arsenal";
5
- //#region src/asyncSource.ts
6
- var a = (e, t) => new Promise((n, r) => {
7
- let a = () => r(i(t, "The operation was aborted."));
8
- if (t.aborted) {
9
- a();
10
- return;
11
- }
12
- t.addEventListener("abort", a, { once: !0 });
13
- let o;
14
- try {
15
- o = e(t);
16
- } catch (e) {
17
- t.removeEventListener("abort", a), r(e);
18
- return;
19
- }
20
- o.then((e) => {
21
- t.removeEventListener("abort", a), n(e);
22
- }, (e) => {
23
- t.removeEventListener("abort", a), r(e);
24
- });
25
- });
26
- function o(i) {
27
- let o = r(i), s = t();
28
- return {
29
- get disposalSignal() {
30
- return o.disposalSignal;
31
- },
32
- dispose() {
33
- s.dispose(), o.dispose();
34
- },
35
- get disposed() {
36
- return o.disposed;
37
- },
38
- async fetch(t) {
39
- if (o.disposed) throw new e();
40
- let r = s.begin(), i = o.value;
41
- o.set(t.pending(i));
42
- try {
43
- let e = await a(t.load, r.signal);
44
- if (!r.isCurrent() || o.disposed) return;
45
- let n = t.success(e);
46
- t.commit?.(n, e), o.set(n);
47
- } catch (e) {
48
- if (!r.isCurrent() || o.disposed) return;
49
- let a = n(e);
50
- throw o.set(t.failure(i, a)), a;
51
- } finally {
52
- r.finish();
53
- }
54
- },
55
- get state() {
56
- return o.value;
57
- },
58
- subscribe: o.subscribe
59
- };
60
- }
61
- //#endregion
62
- export { o as createAsyncSource };
63
-
1
+ import{SourcererDisposedError as e}from"./errors.js";import{createRequestController as t,toError as n}from"./requestController.js";import{createSourceStore as r}from"./sourceStore.js";import{abortError as i}from"@vielzeug/arsenal";var loadWithSignal=(e,t)=>new Promise((n,r)=>{let abort=()=>r(i(t,`The operation was aborted.`));if(t.aborted){abort();return}t.addEventListener(`abort`,abort,{once:!0});let a;try{a=e(t)}catch(e){t.removeEventListener(`abort`,abort),r(e);return}a.then(e=>{t.removeEventListener(`abort`,abort),n(e)},e=>{t.removeEventListener(`abort`,abort),r(e)})});function createAsyncSource(i){let a=r(i),o=t();return{get disposalSignal(){return a.disposalSignal},dispose(){o.dispose(),a.dispose()},get disposed(){return a.disposed},async fetch(t){if(a.disposed)throw new e;let r=o.begin(),i=a.value;a.set(t.pending(i));try{let e=await loadWithSignal(t.load,r.signal);if(!r.isCurrent()||a.disposed)return;let n=t.success(e);t.commit?.(n,e),a.set(n)}catch(e){if(!r.isCurrent()||a.disposed)return;let o=n(e);throw a.set(t.failure(i,o)),o}finally{r.finish()}},get state(){return a.value},subscribe:a.subscribe}}export{createAsyncSource};
64
2
  //# sourceMappingURL=asyncSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"asyncSource.js","names":[],"sources":["../src/asyncSource.ts"],"sourcesContent":["import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n"],"mappings":";;;;;AAMA,IAAM,KAAqB,GAA2C,MACpE,IAAI,SAAS,GAAS,MAAW;CAC/B,IAAM,UAAoB,EAAO,EAAW,GAAQ,4BAA4B,CAAC;CACjF,IAAI,EAAO,SAAS;EAClB,EAAM;EACN;CACF;CAEA,EAAO,iBAAiB,SAAS,GAAO,EAAE,MAAM,GAAK,CAAC;CACtD,IAAI;CACJ,IAAI;EACF,IAAS,EAAK,CAAM;CACtB,SAAS,GAAO;EAEd,AADA,EAAO,oBAAoB,SAAS,CAAK,GACzC,EAAO,CAAK;EACZ;CACF;CAEA,EAAO,MACJ,MAAU;EAET,AADA,EAAO,oBAAoB,SAAS,CAAK,GACzC,EAAQ,CAAK;CACf,IACC,MAAmB;EAElB,AADA,EAAO,oBAAoB,SAAS,CAAK,GACzC,EAAO,CAAK;CACd,CACF;AACF,CAAC;AAoBH,SAAgB,EAA0B,GAAsC;CAC9E,IAAM,IAAQ,EAAkB,CAAO,GACjC,IAAW,EAAwB;CAEzC,OAAO;EACL,IAAI,iBAAiB;GACnB,OAAO,EAAM;EACf;EAEA,UAAU;GAER,AADA,EAAS,QAAQ,GACjB,EAAM,QAAQ;EAChB;EAEA,IAAI,WAAW;GACb,OAAO,EAAM;EACf;EAEA,MAAM,MAAM,GAAS;GACnB,IAAI,EAAM,UAAU,MAAM,IAAI,EAAuB;GAErD,IAAM,IAAU,EAAS,MAAM,GACzB,IAAW,EAAM;GACvB,EAAM,IAAI,EAAQ,QAAQ,CAAQ,CAAC;GAEnC,IAAI;IACF,IAAM,IAAS,MAAM,EAAe,EAAQ,MAAM,EAAQ,MAAM;IAChE,IAAI,CAAC,EAAQ,UAAU,KAAK,EAAM,UAAU;IAE5C,IAAM,IAAQ,EAAQ,QAAQ,CAAM;IAEpC,AADA,EAAQ,SAAS,GAAO,CAAM,GAC9B,EAAM,IAAI,CAAK;GACjB,SAAS,GAAiB;IACxB,IAAI,CAAC,EAAQ,UAAU,KAAK,EAAM,UAAU;IAE5C,IAAM,IAAQ,EAAQ,CAAM;IAE5B,MADA,EAAM,IAAI,EAAQ,QAAQ,GAAU,CAAK,CAAC,GACpC;GACR,UAAU;IACR,EAAQ,OAAO;GACjB;EACF;EAEA,IAAI,QAAQ;GACV,OAAO,EAAM;EACf;EAEA,WAAW,EAAM;CACnB;AACF"}
1
+ {"version":3,"file":"asyncSource.js","names":[],"sources":["../src/asyncSource.ts"],"sourcesContent":["import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n"],"mappings":"uOAMA,IAAM,gBAAqB,EAA2C,IACpE,IAAI,SAAS,EAAS,IAAW,CAC/B,IAAM,UAAoB,EAAO,EAAW,EAAQ,4BAA4B,CAAC,EACjF,GAAI,EAAO,QAAS,CAClB,MAAM,EACN,MACF,CAEA,EAAO,iBAAiB,QAAS,MAAO,CAAE,KAAM,EAAK,CAAC,EACtD,IAAI,EACJ,GAAI,CACF,EAAS,EAAK,CAAM,CACtB,OAAS,EAAO,CACd,EAAO,oBAAoB,QAAS,KAAK,EACzC,EAAO,CAAK,EACZ,MACF,CAEA,EAAO,KACJ,GAAU,CACT,EAAO,oBAAoB,QAAS,KAAK,EACzC,EAAQ,CAAK,CACf,EACC,GAAmB,CAClB,EAAO,oBAAoB,QAAS,KAAK,EACzC,EAAO,CAAK,CACd,CACF,CACF,CAAC,EAoBH,SAAgB,kBAA0B,EAAsC,CAC9E,IAAM,EAAQ,EAAkB,CAAO,EACjC,EAAW,EAAwB,EAEzC,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAM,cACf,EAEA,SAAU,CACR,EAAS,QAAQ,EACjB,EAAM,QAAQ,CAChB,EAEA,IAAI,UAAW,CACb,OAAO,EAAM,QACf,EAEA,MAAM,MAAM,EAAS,CACnB,GAAI,EAAM,SAAU,MAAM,IAAI,EAE9B,IAAM,EAAU,EAAS,MAAM,EACzB,EAAW,EAAM,MACvB,EAAM,IAAI,EAAQ,QAAQ,CAAQ,CAAC,EAEnC,GAAI,CACF,IAAM,EAAS,MAAM,eAAe,EAAQ,KAAM,EAAQ,MAAM,EAChE,GAAI,CAAC,EAAQ,UAAU,GAAK,EAAM,SAAU,OAE5C,IAAM,EAAQ,EAAQ,QAAQ,CAAM,EACpC,EAAQ,SAAS,EAAO,CAAM,EAC9B,EAAM,IAAI,CAAK,CACjB,OAAS,EAAiB,CACxB,GAAI,CAAC,EAAQ,UAAU,GAAK,EAAM,SAAU,OAE5C,IAAM,EAAQ,EAAQ,CAAM,EAE5B,MADA,EAAM,IAAI,EAAQ,QAAQ,EAAU,CAAK,CAAC,EACpC,CACR,QAAU,CACR,EAAQ,OAAO,CACjB,CACF,EAEA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,EAEA,UAAW,EAAM,SACnB,CACF"}
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs"),t=require("./asyncSource.cjs"),n=require("./pagination.cjs");var r=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:n.totalItems(t.totalItems)}});function i(i){if(i.after!==void 0&&i.before!==void 0)throw new e.SourcererConfigurationError(`Cursor source cannot start with both after and before`);let a={...i.after!==void 0&&{after:i.after},...i.before!==void 0&&{before:i.before},pageSize:n.positiveInteger(i.pageSize??20,`pageSize`),params:i.params},o=t.createAsyncSource({error:null,items:[],loading:!1,pagination:r(a.pageSize),params:a.params}),s=()=>{if(o.disposed)throw new e.SourcererDisposedError},c=e=>o.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>i.load({...e,signal:t}),pending:t=>({...t,error:null,loading:!0,...Object.is(e.params,t.params)?{}:{pendingParams:e.params}}),success:t=>({error:null,items:[...t.items],loading:!1,pagination:r(e.pageSize,t),params:e.params})}),l={get disposalSignal(){return o.disposalSignal},dispose:o.dispose,get disposed(){return o.disposed},async next(){s();let e=o.state.pagination.nextCursor;o.state.loading||e===void 0||(a={after:e,pageSize:a.pageSize,params:a.params},await c(a))},async previous(){s();let e=o.state.pagination.previousCursor;o.state.loading||e===void 0||(a={before:e,pageSize:a.pageSize,params:a.params},await c(a))},reload(){return c(a)},async setPageSize(e){s();let t=n.positiveInteger(e,`pageSize`);if(t===a.pageSize&&a.after===void 0&&a.before===void 0){if(o.state.loading||o.state.pagination.pageSize===t&&Object.is(o.state.params,a.params))return;await c(a);return}a={pageSize:t,params:a.params},await c(a)},async setParams(e){if(s(),Object.is(e,a.params)){!o.state.loading&&!Object.is(e,o.state.params)&&await c(a);return}a={pageSize:a.pageSize,params:e},await c(a)},get state(){return o.state},subscribe:o.subscribe,[Symbol.dispose](){l.dispose()}};return l}exports.createCursorSource=i;
1
+ const e=require("./errors.cjs"),t=require("./asyncSource.cjs"),n=require("./pagination.cjs");var createPagination=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:n.totalItems(t.totalItems)}});function createCursorSource(r){if(r.after!==void 0&&r.before!==void 0)throw new e.SourcererConfigurationError(`Cursor source cannot start with both after and before`);let i={...r.after!==void 0&&{after:r.after},...r.before!==void 0&&{before:r.before},pageSize:n.positiveInteger(r.pageSize??20,`pageSize`),params:r.params},a=t.createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination(i.pageSize),params:i.params}),assertLive=()=>{if(a.disposed)throw new e.SourcererDisposedError},fetch=e=>a.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>r.load({...e,signal:t}),pending:t=>({...t,error:null,loading:!0,...Object.is(e.params,t.params)?{}:{pendingParams:e.params}}),success:t=>({error:null,items:[...t.items],loading:!1,pagination:createPagination(e.pageSize,t),params:e.params})}),o={get disposalSignal(){return a.disposalSignal},dispose:a.dispose,get disposed(){return a.disposed},async next(){assertLive();let e=a.state.pagination.nextCursor;a.state.loading||e===void 0||(i={after:e,pageSize:i.pageSize,params:i.params},await fetch(i))},async previous(){assertLive();let e=a.state.pagination.previousCursor;a.state.loading||e===void 0||(i={before:e,pageSize:i.pageSize,params:i.params},await fetch(i))},reload(){return fetch(i)},async setPageSize(e){assertLive();let t=n.positiveInteger(e,`pageSize`);if(t===i.pageSize&&i.after===void 0&&i.before===void 0){if(a.state.loading||a.state.pagination.pageSize===t&&Object.is(a.state.params,i.params))return;await fetch(i);return}i={pageSize:t,params:i.params},await fetch(i)},async setParams(e){if(assertLive(),Object.is(e,i.params)){!a.state.loading&&!Object.is(e,a.state.params)&&await fetch(i);return}i={pageSize:i.pageSize,params:e},await fetch(i)},get state(){return a.state},subscribe:a.subscribe,[Symbol.dispose](){o.dispose()}};return o}exports.createCursorSource=createCursorSource;
2
2
  //# sourceMappingURL=cursorSource.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursorSource.cjs","names":[],"sources":["../src/cursorSource.ts"],"sourcesContent":["import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cursorSource.cjs","names":[],"sources":["../src/cursorSource.ts"],"sourcesContent":["import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"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"}
@@ -1,115 +1,2 @@
1
- import { SourcererConfigurationError as e, SourcererDisposedError as t } from "./errors.js";
2
- import { createAsyncSource as n } from "./asyncSource.js";
3
- import { positiveInteger as r, totalItems as i } from "./pagination.js";
4
- //#region src/cursorSource.ts
5
- var a = (e, t) => ({
6
- ...t?.nextCursor !== void 0 && { nextCursor: t.nextCursor },
7
- pageSize: e,
8
- ...t?.previousCursor !== void 0 && { previousCursor: t.previousCursor },
9
- ...t?.totalItems !== void 0 && { totalItems: i(t.totalItems) }
10
- });
11
- function o(i) {
12
- if (i.after !== void 0 && i.before !== void 0) throw new e("Cursor source cannot start with both after and before");
13
- let o = {
14
- ...i.after !== void 0 && { after: i.after },
15
- ...i.before !== void 0 && { before: i.before },
16
- pageSize: r(i.pageSize ?? 20, "pageSize"),
17
- params: i.params
18
- }, s = n({
19
- error: null,
20
- items: [],
21
- loading: !1,
22
- pagination: a(o.pageSize),
23
- params: o.params
24
- }), c = () => {
25
- if (s.disposed) throw new t();
26
- }, l = (e) => s.fetch({
27
- failure: (e, t) => ({
28
- ...e,
29
- error: t,
30
- loading: !1,
31
- pendingParams: void 0
32
- }),
33
- load: (t) => i.load({
34
- ...e,
35
- signal: t
36
- }),
37
- pending: (t) => ({
38
- ...t,
39
- error: null,
40
- loading: !0,
41
- ...Object.is(e.params, t.params) ? {} : { pendingParams: e.params }
42
- }),
43
- success: (t) => ({
44
- error: null,
45
- items: [...t.items],
46
- loading: !1,
47
- pagination: a(e.pageSize, t),
48
- params: e.params
49
- })
50
- }), u = {
51
- get disposalSignal() {
52
- return s.disposalSignal;
53
- },
54
- dispose: s.dispose,
55
- get disposed() {
56
- return s.disposed;
57
- },
58
- async next() {
59
- c();
60
- let e = s.state.pagination.nextCursor;
61
- s.state.loading || e === void 0 || (o = {
62
- after: e,
63
- pageSize: o.pageSize,
64
- params: o.params
65
- }, await l(o));
66
- },
67
- async previous() {
68
- c();
69
- let e = s.state.pagination.previousCursor;
70
- s.state.loading || e === void 0 || (o = {
71
- before: e,
72
- pageSize: o.pageSize,
73
- params: o.params
74
- }, await l(o));
75
- },
76
- reload() {
77
- return l(o);
78
- },
79
- async setPageSize(e) {
80
- c();
81
- let t = r(e, "pageSize");
82
- if (t === o.pageSize && o.after === void 0 && o.before === void 0) {
83
- if (s.state.loading || s.state.pagination.pageSize === t && Object.is(s.state.params, o.params)) return;
84
- await l(o);
85
- return;
86
- }
87
- o = {
88
- pageSize: t,
89
- params: o.params
90
- }, await l(o);
91
- },
92
- async setParams(e) {
93
- if (c(), Object.is(e, o.params)) {
94
- !s.state.loading && !Object.is(e, s.state.params) && await l(o);
95
- return;
96
- }
97
- o = {
98
- pageSize: o.pageSize,
99
- params: e
100
- }, await l(o);
101
- },
102
- get state() {
103
- return s.state;
104
- },
105
- subscribe: s.subscribe,
106
- [Symbol.dispose]() {
107
- u.dispose();
108
- }
109
- };
110
- return u;
111
- }
112
- //#endregion
113
- export { o as createCursorSource };
114
-
1
+ import{SourcererConfigurationError as e,SourcererDisposedError as t}from"./errors.js";import{createAsyncSource as n}from"./asyncSource.js";import{positiveInteger as r,totalItems as i}from"./pagination.js";var createPagination=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:i(t.totalItems)}});function createCursorSource(i){if(i.after!==void 0&&i.before!==void 0)throw new e(`Cursor source cannot start with both after and before`);let a={...i.after!==void 0&&{after:i.after},...i.before!==void 0&&{before:i.before},pageSize:r(i.pageSize??20,`pageSize`),params:i.params},o=n({error:null,items:[],loading:!1,pagination:createPagination(a.pageSize),params:a.params}),assertLive=()=>{if(o.disposed)throw new t},fetch=e=>o.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>i.load({...e,signal:t}),pending:t=>({...t,error:null,loading:!0,...Object.is(e.params,t.params)?{}:{pendingParams:e.params}}),success:t=>({error:null,items:[...t.items],loading:!1,pagination:createPagination(e.pageSize,t),params:e.params})}),s={get disposalSignal(){return o.disposalSignal},dispose:o.dispose,get disposed(){return o.disposed},async next(){assertLive();let e=o.state.pagination.nextCursor;o.state.loading||e===void 0||(a={after:e,pageSize:a.pageSize,params:a.params},await fetch(a))},async previous(){assertLive();let e=o.state.pagination.previousCursor;o.state.loading||e===void 0||(a={before:e,pageSize:a.pageSize,params:a.params},await fetch(a))},reload(){return fetch(a)},async setPageSize(e){assertLive();let t=r(e,`pageSize`);if(t===a.pageSize&&a.after===void 0&&a.before===void 0){if(o.state.loading||o.state.pagination.pageSize===t&&Object.is(o.state.params,a.params))return;await fetch(a);return}a={pageSize:t,params:a.params},await fetch(a)},async setParams(e){if(assertLive(),Object.is(e,a.params)){!o.state.loading&&!Object.is(e,o.state.params)&&await fetch(a);return}a={pageSize:a.pageSize,params:e},await fetch(a)},get state(){return o.state},subscribe:o.subscribe,[Symbol.dispose](){s.dispose()}};return s}export{createCursorSource};
115
2
  //# sourceMappingURL=cursorSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursorSource.js","names":[],"sources":["../src/cursorSource.ts"],"sourcesContent":["import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cursorSource.js","names":[],"sources":["../src/cursorSource.ts"],"sourcesContent":["import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"6MAYA,IAAM,kBACJ,EACA,KAC+B,CAC/B,GAAI,GAAQ,aAAe,IAAA,IAAa,CAAE,WAAY,EAAO,UAAW,EACxE,WACA,GAAI,GAAQ,iBAAmB,IAAA,IAAa,CAAE,eAAgB,EAAO,cAAe,EACpF,GAAI,GAAQ,aAAe,IAAA,IAAa,CAAE,WAAY,EAAW,EAAO,UAAU,CAAE,CACtF,GAGA,SAAgB,mBACd,EACmC,CACnC,GAAI,EAAO,QAAU,IAAA,IAAa,EAAO,SAAW,IAAA,GAClD,MAAM,IAAI,EAA4B,uDAAuD,EAG/F,IAAI,EAAuC,CACzC,GAAI,EAAO,QAAU,IAAA,IAAa,CAAE,MAAO,EAAO,KAAM,EACxD,GAAI,EAAO,SAAW,IAAA,IAAa,CAAE,OAAQ,EAAO,MAAO,EAC3D,SAAU,EAAgB,EAAO,UAAY,GAAI,UAAU,EAC3D,OAAQ,EAAO,MACjB,EACM,EAAc,EAA0D,CAC5E,MAAO,KACP,MAAO,CAAC,EACR,QAAS,GACT,WAAY,iBAAiB,EAAU,QAAQ,EAC/C,OAAQ,EAAU,MACpB,CAAC,EACK,eAAyB,CAC7B,GAAI,EAAY,SAAU,MAAM,IAAI,CACtC,EAEM,MAAS,GACb,EAAY,MAAM,CAChB,SAAU,EAAU,KAAW,CAAE,GAAG,EAAU,QAAO,QAAS,GAAO,cAAe,IAAA,EAAU,GAC9F,KAAO,GAAW,EAAO,KAAK,CAAE,GAAG,EAAS,QAAO,CAAC,EACpD,QAAU,IAAc,CACtB,GAAG,EACH,MAAO,KACP,QAAS,GACT,GAAI,OAAO,GAAG,EAAQ,OAAQ,EAAS,MAAM,EAAI,CAAC,EAAI,CAAE,cAAe,EAAQ,MAAO,CACxF,GACA,QAAU,IAAY,CACpB,MAAO,KACP,MAAO,CAAC,GAAG,EAAO,KAAK,EACvB,QAAS,GACT,WAAY,iBAAiB,EAAQ,SAAU,CAAM,EACrD,OAAQ,EAAQ,MAClB,EACF,CAAC,EAEG,EAA4C,CAChD,IAAI,gBAAiB,CACnB,OAAO,EAAY,cACrB,EAEA,QAAS,EAAY,QAErB,IAAI,UAAW,CACb,OAAO,EAAY,QACrB,EAEA,MAAM,MAAO,CACX,WAAW,EACX,IAAM,EAAS,EAAY,MAAM,WAAW,WACxC,EAAY,MAAM,SAAW,IAAW,IAAA,KAC5C,EAAY,CAAE,MAAO,EAAQ,SAAU,EAAU,SAAU,OAAQ,EAAU,MAAO,EACpF,MAAM,MAAM,CAAS,EACvB,EAEA,MAAM,UAAW,CACf,WAAW,EACX,IAAM,EAAS,EAAY,MAAM,WAAW,eACxC,EAAY,MAAM,SAAW,IAAW,IAAA,KAC5C,EAAY,CAAE,OAAQ,EAAQ,SAAU,EAAU,SAAU,OAAQ,EAAU,MAAO,EACrF,MAAM,MAAM,CAAS,EACvB,EAEA,QAAS,CACP,OAAO,MAAM,CAAS,CACxB,EAEA,MAAM,YAAY,EAAU,CAC1B,WAAW,EACX,IAAM,EAAa,EAAgB,EAAU,UAAU,EACvD,GAAI,IAAe,EAAU,UAAY,EAAU,QAAU,IAAA,IAAa,EAAU,SAAW,IAAA,GAAW,CACxG,GACE,EAAY,MAAM,SACjB,EAAY,MAAM,WAAW,WAAa,GACzC,OAAO,GAAG,EAAY,MAAM,OAAQ,EAAU,MAAM,EAEtD,OACF,MAAM,MAAM,CAAS,EACrB,MACF,CACA,EAAY,CAAE,SAAU,EAAY,OAAQ,EAAU,MAAO,EAC7D,MAAM,MAAM,CAAS,CACvB,EAEA,MAAM,UAAU,EAAQ,CAEtB,GADA,WAAW,EACP,OAAO,GAAG,EAAQ,EAAU,MAAM,EAAG,CACnC,CAAC,EAAY,MAAM,SAAW,CAAC,OAAO,GAAG,EAAQ,EAAY,MAAM,MAAM,GAAG,MAAM,MAAM,CAAS,EACrG,MACF,CACA,EAAY,CAAE,SAAU,EAAU,SAAU,QAAO,EACnD,MAAM,MAAM,CAAS,CACvB,EAEA,IAAI,OAAQ,CACV,OAAO,EAAY,KACrB,EAEA,UAAW,EAAY,UAEvB,CAAC,OAAO,UAAW,CACjB,EAAO,QAAQ,CACjB,CACF,EAEA,OAAO,CACT"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=class extends Error{static errorName=`SourcererError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{static errorName=`SourcererConfigurationError`},n=class extends e{static errorName=`SourcererDisposedError`;constructor(e=`Sourcerer source disposed`){super(e)}};exports.SourcererConfigurationError=t,exports.SourcererDisposedError=n,exports.SourcererError=e;
1
+ var SourcererError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},SourcererConfigurationError=class extends SourcererError{},SourcererDisposedError=class extends SourcererError{constructor(e=`Sourcerer source disposed`){super(e)}};exports.SourcererConfigurationError=SourcererConfigurationError,exports.SourcererDisposedError=SourcererDisposedError,exports.SourcererError=SourcererError;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n protected static readonly errorName: string = 'SourcererError';\n\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = (new.target as typeof SourcererError).errorName;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {\n protected static override readonly errorName = 'SourcererConfigurationError';\n}\n\nexport class SourcererDisposedError extends SourcererError {\n protected static override readonly errorName = 'SourcererDisposedError';\n\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n"],"mappings":"AACA,IAAa,EAAb,cAAoC,KAAM,CACxC,OAA0B,UAAoB,iBAE9C,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAQ,WAAqC,UAClD,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,EAAb,cAAiD,CAAe,CAC9D,OAAmC,UAAY,6BACjD,EAEa,EAAb,cAA4C,CAAe,CACzD,OAAmC,UAAY,yBAE/C,YAAY,EAAU,4BAA6B,CACjD,MAAM,CAAO,CACf,CACF"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {}\n\nexport class SourcererDisposedError extends SourcererError {\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n"],"mappings":"AACA,IAAa,eAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,4BAAb,cAAiD,cAAe,CAAC,EAEpD,uBAAb,cAA4C,cAAe,CACzD,YAAY,EAAU,4BAA6B,CACjD,MAAM,CAAO,CACf,CACF"}
package/dist/errors.d.ts CHANGED
@@ -1,14 +1,11 @@
1
1
  /** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */
2
2
  export declare class SourcererError extends Error {
3
- protected static readonly errorName: string;
4
3
  constructor(message: string, opts?: ErrorOptions);
5
4
  }
6
5
  /** Thrown when a source is configured or queried with invalid arguments. */
7
6
  export declare class SourcererConfigurationError extends SourcererError {
8
- protected static readonly errorName = "SourcererConfigurationError";
9
7
  }
10
8
  export declare class SourcererDisposedError extends SourcererError {
11
- protected static readonly errorName = "SourcererDisposedError";
12
9
  constructor(message?: string);
13
10
  }
14
11
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAoB;gBAEnD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED,4EAA4E;AAC5E,qBAAa,2BAA4B,SAAQ,cAAc;IAC7D,0BAAmC,SAAS,iCAAiC;CAC9E;AAED,qBAAa,sBAAuB,SAAQ,cAAc;IACxD,0BAAmC,SAAS,4BAA4B;gBAE5D,OAAO,SAA8B;CAGlD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED,4EAA4E;AAC5E,qBAAa,2BAA4B,SAAQ,cAAc;CAAG;AAElE,qBAAa,sBAAuB,SAAQ,cAAc;gBAC5C,OAAO,SAA8B;CAGlD"}
package/dist/errors.js CHANGED
@@ -1,18 +1,2 @@
1
- //#region src/errors.ts
2
- var e = class extends Error {
3
- static errorName = "SourcererError";
4
- constructor(e, t) {
5
- super(e, t), this.name = new.target.errorName, Object.setPrototypeOf(this, new.target.prototype);
6
- }
7
- }, t = class extends e {
8
- static errorName = "SourcererConfigurationError";
9
- }, n = class extends e {
10
- static errorName = "SourcererDisposedError";
11
- constructor(e = "Sourcerer source disposed") {
12
- super(e);
13
- }
14
- };
15
- //#endregion
16
- export { t as SourcererConfigurationError, n as SourcererDisposedError, e as SourcererError };
17
-
1
+ var SourcererError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},SourcererConfigurationError=class extends SourcererError{},SourcererDisposedError=class extends SourcererError{constructor(e=`Sourcerer source disposed`){super(e)}};export{SourcererConfigurationError,SourcererDisposedError,SourcererError};
18
2
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n protected static readonly errorName: string = 'SourcererError';\n\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = (new.target as typeof SourcererError).errorName;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {\n protected static override readonly errorName = 'SourcererConfigurationError';\n}\n\nexport class SourcererDisposedError extends SourcererError {\n protected static override readonly errorName = 'SourcererDisposedError';\n\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n"],"mappings":";AACA,IAAa,IAAb,cAAoC,MAAM;CACxC,OAA0B,YAAoB;CAE9C,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAQ,WAAqC,WAClD,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAGa,IAAb,cAAiD,EAAe;CAC9D,OAAmC,YAAY;AACjD,GAEa,IAAb,cAA4C,EAAe;CACzD,OAAmC,YAAY;CAE/C,YAAY,IAAU,6BAA6B;EACjD,MAAM,CAAO;CACf;AACF"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {}\n\nexport class SourcererDisposedError extends SourcererError {\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n"],"mappings":"AACA,IAAa,eAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,4BAAb,cAAiD,cAAe,CAAC,EAEpD,uBAAb,cAA4C,cAAe,CACzD,YAAY,EAAU,4BAA6B,CACjD,MAAM,CAAO,CACf,CACF"}
package/dist/index.js CHANGED
@@ -1,6 +1 @@
1
- import { SourcererConfigurationError as e, SourcererDisposedError as t, SourcererError as n } from "./errors.js";
2
- import { createCursorSource as r } from "./cursorSource.js";
3
- import { createInfiniteSource as i } from "./infiniteSource.js";
4
- import { createLocalSource as a } from "./localSource.js";
5
- import { createPageSource as o } from "./pageSource.js";
6
- export { e as SourcererConfigurationError, t as SourcererDisposedError, n as SourcererError, r as createCursorSource, i as createInfiniteSource, a as createLocalSource, o as createPageSource };
1
+ import{SourcererConfigurationError as e,SourcererDisposedError as t,SourcererError as n}from"./errors.js";import{createCursorSource as r}from"./cursorSource.js";import{createInfiniteSource as i}from"./infiniteSource.js";import{createLocalSource as a}from"./localSource.js";import{createPageSource as o}from"./pageSource.js";export{e as SourcererConfigurationError,t as SourcererDisposedError,n as SourcererError,r as createCursorSource,i as createInfiniteSource,a as createLocalSource,o as createPageSource};
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs"),t=require("./asyncSource.cjs"),n=require("./pagination.cjs");var r=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function i(i){let a={pageSize:n.positiveInteger(i.pageSize??20,`pageSize`),params:i.params},o=1,s=!1,c=t.createAsyncSource({error:null,items:[],loading:!1,pagination:r(0,a.pageSize,0),params:a.params}),l=()=>{if(c.disposed)throw new e.SourcererDisposedError},u=(e,t,l)=>{let u=c.state.items;return c.fetch({commit:()=>{s=!0,o=t+1,a=e},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>i.load({page:t,pageSize:e.pageSize,params:e.params,signal:n}),pending:t=>({...t,error:null,loading:!0,...l||Object.is(e.params,t.params)?{}:{pendingParams:e.params}}),success:t=>{let i=l?[...u,...t.items]:[...t.items];return{error:null,items:i,loading:!1,pagination:r(i.length,e.pageSize,n.totalItems(t.totalItems)),params:e.params}}})},d=()=>u(a,1,!1),f={get disposalSignal(){return c.disposalSignal},dispose:c.dispose,get disposed(){return c.disposed},async loadMore(){if(l(),!c.state.loading){if(!s||!Object.is(a.params,c.state.params)){await d();return}c.state.pagination.hasMore&&await u(a,o,!0)}},reload:d,async setPageSize(e){l();let t=n.positiveInteger(e,`pageSize`);if(t===a.pageSize){if(c.state.loading||c.state.pagination.pageSize===t)return;await d();return}a={...a,pageSize:t},o=1,await d()},async setParams(e){if(l(),Object.is(e,a.params)){!c.state.loading&&!Object.is(e,c.state.params)&&await d();return}a={...a,params:e},o=1,await d()},get state(){return c.state},subscribe:c.subscribe,[Symbol.dispose](){f.dispose()}};return f}exports.createInfiniteSource=i;
1
+ const e=require("./errors.cjs"),t=require("./asyncSource.cjs"),n=require("./pagination.cjs");var createPagination=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function createInfiniteSource(r){let i={pageSize:n.positiveInteger(r.pageSize??20,`pageSize`),params:r.params},a=1,o=!1,s=t.createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination(0,i.pageSize,0),params:i.params}),assertLive=()=>{if(s.disposed)throw new e.SourcererDisposedError},fetch=(e,t,c)=>{let l=s.state.items;return s.fetch({commit:()=>{o=!0,a=t+1,i=e},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>r.load({page:t,pageSize:e.pageSize,params:e.params,signal:n}),pending:t=>({...t,error:null,loading:!0,...c||Object.is(e.params,t.params)?{}:{pendingParams:e.params}}),success:t=>{let r=c?[...l,...t.items]:[...t.items];return{error:null,items:r,loading:!1,pagination:createPagination(r.length,e.pageSize,n.totalItems(t.totalItems)),params:e.params}}})},reload=()=>fetch(i,1,!1),c={get disposalSignal(){return s.disposalSignal},dispose:s.dispose,get disposed(){return s.disposed},async loadMore(){if(assertLive(),!s.state.loading){if(!o||!Object.is(i.params,s.state.params)){await reload();return}s.state.pagination.hasMore&&await fetch(i,a,!0)}},reload,async setPageSize(e){assertLive();let t=n.positiveInteger(e,`pageSize`);if(t===i.pageSize){if(s.state.loading||s.state.pagination.pageSize===t)return;await reload();return}i={...i,pageSize:t},a=1,await reload()},async setParams(e){if(assertLive(),Object.is(e,i.params)){!s.state.loading&&!Object.is(e,s.state.params)&&await reload();return}i={...i,params:e},a=1,await reload()},get state(){return s.state},subscribe:s.subscribe,[Symbol.dispose](){c.dispose()}};return c}exports.createInfiniteSource=createInfiniteSource;
2
2
  //# sourceMappingURL=infiniteSource.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"infiniteSource.cjs","names":[],"sources":["../src/infiniteSource.ts"],"sourcesContent":["import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { InfinitePagination, InfiniteSource, InfiniteSourceConfig, InfiniteSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ pageSize: number; params: TParams }>;\n\nconst createPagination = (loadedItems: number, pageSize: number, total: number): InfinitePagination => ({\n hasMore: loadedItems < total,\n loadedItems,\n pageSize,\n totalItems: total,\n});\n\n/** Infinite sources retain committed items while replacement work is pending. */\nexport function createInfiniteSource<T, TParams = undefined>(\n config: InfiniteSourceConfig<T, TParams>,\n): InfiniteSource<T, TParams> {\n let requested: Request<TParams> = {\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let nextPage = 1;\n let hasLoaded = false;\n const asyncSource = createAsyncSource<InfiniteSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(0, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams>, page: number, append: boolean): Promise<void> => {\n const loadedItems = asyncSource.state.items;\n\n return asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n nextPage = page + 1;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ page, pageSize: request.pageSize, params: request.params, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(append || Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => {\n const items = append ? [...loadedItems, ...result.items] : [...result.items];\n return {\n error: null,\n items,\n loading: false,\n pagination: createPagination(items.length, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => fetch(requested, 1, false);\n\n const source: InfiniteSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async loadMore() {\n assertLive();\n if (asyncSource.state.loading) return;\n if (!hasLoaded || !Object.is(requested.params, asyncSource.state.params)) {\n await reload();\n return;\n }\n if (asyncSource.state.pagination.hasMore) await fetch(requested, nextPage, true);\n },\n\n reload,\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize) {\n if (asyncSource.state.loading || asyncSource.state.pagination.pageSize === normalized) return;\n await reload();\n return;\n }\n requested = { ...requested, pageSize: normalized };\n nextPage = 1;\n await reload();\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await reload();\n return;\n }\n requested = { ...requested, params };\n nextPage = 1;\n await reload();\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"6FAOA,IAAM,GAAoB,EAAqB,EAAkB,KAAuC,CACtG,QAAS,EAAc,EACvB,cACA,WACA,WAAY,CACd,GAGA,SAAgB,EACd,EAC4B,CAC5B,IAAI,EAA8B,CAChC,SAAU,EAAA,gBAAgB,EAAO,UAAY,GAAI,UAAU,EAC3D,OAAQ,EAAO,MACjB,EACI,EAAW,EACX,EAAY,GACV,EAAc,EAAA,kBAAmD,CACrE,MAAO,KACP,MAAO,CAAC,EACR,QAAS,GACT,WAAY,EAAiB,EAAG,EAAU,SAAU,CAAC,EACrD,OAAQ,EAAU,MACpB,CAAC,EACK,MAAyB,CAC7B,GAAI,EAAY,SAAU,MAAM,IAAI,EAAA,sBACtC,EAEM,GAAS,EAA2B,EAAc,IAAmC,CACzF,IAAM,EAAc,EAAY,MAAM,MAEtC,OAAO,EAAY,MAAM,CACvB,WAAc,CACZ,EAAY,GACZ,EAAW,EAAO,EAClB,EAAY,CACd,EACA,SAAU,EAAU,KAAW,CAAE,GAAG,EAAU,QAAO,QAAS,GAAO,cAAe,IAAA,EAAU,GAC9F,KAAO,GAAW,EAAO,KAAK,CAAE,OAAM,SAAU,EAAQ,SAAU,OAAQ,EAAQ,OAAQ,QAAO,CAAC,EAClG,QAAU,IAAc,CACtB,GAAG,EACH,MAAO,KACP,QAAS,GACT,GAAI,GAAU,OAAO,GAAG,EAAQ,OAAQ,EAAS,MAAM,EAAI,CAAC,EAAI,CAAE,cAAe,EAAQ,MAAO,CAClG,GACA,QAAU,GAAW,CACnB,IAAM,EAAQ,EAAS,CAAC,GAAG,EAAa,GAAG,EAAO,KAAK,EAAI,CAAC,GAAG,EAAO,KAAK,EAC3E,MAAO,CACL,MAAO,KACP,QACA,QAAS,GACT,WAAY,EAAiB,EAAM,OAAQ,EAAQ,SAAU,EAAA,WAAW,EAAO,UAAU,CAAC,EAC1F,OAAQ,EAAQ,MAClB,CACF,CACF,CAAC,CACH,EAEM,MAA8B,EAAM,EAAW,EAAG,EAAK,EAEvD,EAAqC,CACzC,IAAI,gBAAiB,CACnB,OAAO,EAAY,cACrB,EAEA,QAAS,EAAY,QAErB,IAAI,UAAW,CACb,OAAO,EAAY,QACrB,EAEA,MAAM,UAAW,CACf,KAAW,EACP,GAAY,MAAM,QACtB,IAAI,CAAC,GAAa,CAAC,OAAO,GAAG,EAAU,OAAQ,EAAY,MAAM,MAAM,EAAG,CACxE,MAAM,EAAO,EACb,MACF,CACI,EAAY,MAAM,WAAW,SAAS,MAAM,EAAM,EAAW,EAAU,EAAI,CAD/E,CAEF,EAEA,SAEA,MAAM,YAAY,EAAU,CAC1B,EAAW,EACX,IAAM,EAAa,EAAA,gBAAgB,EAAU,UAAU,EACvD,GAAI,IAAe,EAAU,SAAU,CACrC,GAAI,EAAY,MAAM,SAAW,EAAY,MAAM,WAAW,WAAa,EAAY,OACvF,MAAM,EAAO,EACb,MACF,CACA,EAAY,CAAE,GAAG,EAAW,SAAU,CAAW,EACjD,EAAW,EACX,MAAM,EAAO,CACf,EAEA,MAAM,UAAU,EAAQ,CAEtB,GADA,EAAW,EACP,OAAO,GAAG,EAAQ,EAAU,MAAM,EAAG,CACnC,CAAC,EAAY,MAAM,SAAW,CAAC,OAAO,GAAG,EAAQ,EAAY,MAAM,MAAM,GAAG,MAAM,EAAO,EAC7F,MACF,CACA,EAAY,CAAE,GAAG,EAAW,QAAO,EACnC,EAAW,EACX,MAAM,EAAO,CACf,EAEA,IAAI,OAAQ,CACV,OAAO,EAAY,KACrB,EAEA,UAAW,EAAY,UAEvB,CAAC,OAAO,UAAW,CACjB,EAAO,QAAQ,CACjB,CACF,EAEA,OAAO,CACT"}
1
+ {"version":3,"file":"infiniteSource.cjs","names":[],"sources":["../src/infiniteSource.ts"],"sourcesContent":["import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { InfinitePagination, InfiniteSource, InfiniteSourceConfig, InfiniteSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ pageSize: number; params: TParams }>;\n\nconst createPagination = (loadedItems: number, pageSize: number, total: number): InfinitePagination => ({\n hasMore: loadedItems < total,\n loadedItems,\n pageSize,\n totalItems: total,\n});\n\n/** Infinite sources retain committed items while replacement work is pending. */\nexport function createInfiniteSource<T, TParams = undefined>(\n config: InfiniteSourceConfig<T, TParams>,\n): InfiniteSource<T, TParams> {\n let requested: Request<TParams> = {\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let nextPage = 1;\n let hasLoaded = false;\n const asyncSource = createAsyncSource<InfiniteSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(0, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams>, page: number, append: boolean): Promise<void> => {\n const loadedItems = asyncSource.state.items;\n\n return asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n nextPage = page + 1;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ page, pageSize: request.pageSize, params: request.params, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(append || Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => {\n const items = append ? [...loadedItems, ...result.items] : [...result.items];\n return {\n error: null,\n items,\n loading: false,\n pagination: createPagination(items.length, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => fetch(requested, 1, false);\n\n const source: InfiniteSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async loadMore() {\n assertLive();\n if (asyncSource.state.loading) return;\n if (!hasLoaded || !Object.is(requested.params, asyncSource.state.params)) {\n await reload();\n return;\n }\n if (asyncSource.state.pagination.hasMore) await fetch(requested, nextPage, true);\n },\n\n reload,\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize) {\n if (asyncSource.state.loading || asyncSource.state.pagination.pageSize === normalized) return;\n await reload();\n return;\n }\n requested = { ...requested, pageSize: normalized };\n nextPage = 1;\n await reload();\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await reload();\n return;\n }\n requested = { ...requested, params };\n nextPage = 1;\n await reload();\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"6FAOA,IAAM,kBAAoB,EAAqB,EAAkB,KAAuC,CACtG,QAAS,EAAc,EACvB,cACA,WACA,WAAY,CACd,GAGA,SAAgB,qBACd,EAC4B,CAC5B,IAAI,EAA8B,CAChC,SAAU,EAAA,gBAAgB,EAAO,UAAY,GAAI,UAAU,EAC3D,OAAQ,EAAO,MACjB,EACI,EAAW,EACX,EAAY,GACV,EAAc,EAAA,kBAAmD,CACrE,MAAO,KACP,MAAO,CAAC,EACR,QAAS,GACT,WAAY,iBAAiB,EAAG,EAAU,SAAU,CAAC,EACrD,OAAQ,EAAU,MACpB,CAAC,EACK,eAAyB,CAC7B,GAAI,EAAY,SAAU,MAAM,IAAI,EAAA,sBACtC,EAEM,OAAS,EAA2B,EAAc,IAAmC,CACzF,IAAM,EAAc,EAAY,MAAM,MAEtC,OAAO,EAAY,MAAM,CACvB,WAAc,CACZ,EAAY,GACZ,EAAW,EAAO,EAClB,EAAY,CACd,EACA,SAAU,EAAU,KAAW,CAAE,GAAG,EAAU,QAAO,QAAS,GAAO,cAAe,IAAA,EAAU,GAC9F,KAAO,GAAW,EAAO,KAAK,CAAE,OAAM,SAAU,EAAQ,SAAU,OAAQ,EAAQ,OAAQ,QAAO,CAAC,EAClG,QAAU,IAAc,CACtB,GAAG,EACH,MAAO,KACP,QAAS,GACT,GAAI,GAAU,OAAO,GAAG,EAAQ,OAAQ,EAAS,MAAM,EAAI,CAAC,EAAI,CAAE,cAAe,EAAQ,MAAO,CAClG,GACA,QAAU,GAAW,CACnB,IAAM,EAAQ,EAAS,CAAC,GAAG,EAAa,GAAG,EAAO,KAAK,EAAI,CAAC,GAAG,EAAO,KAAK,EAC3E,MAAO,CACL,MAAO,KACP,QACA,QAAS,GACT,WAAY,iBAAiB,EAAM,OAAQ,EAAQ,SAAU,EAAA,WAAW,EAAO,UAAU,CAAC,EAC1F,OAAQ,EAAQ,MAClB,CACF,CACF,CAAC,CACH,EAEM,WAA8B,MAAM,EAAW,EAAG,EAAK,EAEvD,EAAqC,CACzC,IAAI,gBAAiB,CACnB,OAAO,EAAY,cACrB,EAEA,QAAS,EAAY,QAErB,IAAI,UAAW,CACb,OAAO,EAAY,QACrB,EAEA,MAAM,UAAW,CACf,cAAW,EACP,GAAY,MAAM,QACtB,IAAI,CAAC,GAAa,CAAC,OAAO,GAAG,EAAU,OAAQ,EAAY,MAAM,MAAM,EAAG,CACxE,MAAM,OAAO,EACb,MACF,CACI,EAAY,MAAM,WAAW,SAAS,MAAM,MAAM,EAAW,EAAU,EAAI,CAD/E,CAEF,EAEA,OAEA,MAAM,YAAY,EAAU,CAC1B,WAAW,EACX,IAAM,EAAa,EAAA,gBAAgB,EAAU,UAAU,EACvD,GAAI,IAAe,EAAU,SAAU,CACrC,GAAI,EAAY,MAAM,SAAW,EAAY,MAAM,WAAW,WAAa,EAAY,OACvF,MAAM,OAAO,EACb,MACF,CACA,EAAY,CAAE,GAAG,EAAW,SAAU,CAAW,EACjD,EAAW,EACX,MAAM,OAAO,CACf,EAEA,MAAM,UAAU,EAAQ,CAEtB,GADA,WAAW,EACP,OAAO,GAAG,EAAQ,EAAU,MAAM,EAAG,CACnC,CAAC,EAAY,MAAM,SAAW,CAAC,OAAO,GAAG,EAAQ,EAAY,MAAM,MAAM,GAAG,MAAM,OAAO,EAC7F,MACF,CACA,EAAY,CAAE,GAAG,EAAW,QAAO,EACnC,EAAW,EACX,MAAM,OAAO,CACf,EAEA,IAAI,OAAQ,CACV,OAAO,EAAY,KACrB,EAEA,UAAW,EAAY,UAEvB,CAAC,OAAO,UAAW,CACjB,EAAO,QAAQ,CACjB,CACF,EAEA,OAAO,CACT"}
@@ -1,112 +1,2 @@
1
- import { SourcererDisposedError as e } from "./errors.js";
2
- import { createAsyncSource as t } from "./asyncSource.js";
3
- import { positiveInteger as n, totalItems as r } from "./pagination.js";
4
- //#region src/infiniteSource.ts
5
- var i = (e, t, n) => ({
6
- hasMore: e < n,
7
- loadedItems: e,
8
- pageSize: t,
9
- totalItems: n
10
- });
11
- function a(a) {
12
- let o = {
13
- pageSize: n(a.pageSize ?? 20, "pageSize"),
14
- params: a.params
15
- }, s = 1, c = !1, l = t({
16
- error: null,
17
- items: [],
18
- loading: !1,
19
- pagination: i(0, o.pageSize, 0),
20
- params: o.params
21
- }), u = () => {
22
- if (l.disposed) throw new e();
23
- }, d = (e, t, n) => {
24
- let u = l.state.items;
25
- return l.fetch({
26
- commit: () => {
27
- c = !0, s = t + 1, o = e;
28
- },
29
- failure: (e, t) => ({
30
- ...e,
31
- error: t,
32
- loading: !1,
33
- pendingParams: void 0
34
- }),
35
- load: (n) => a.load({
36
- page: t,
37
- pageSize: e.pageSize,
38
- params: e.params,
39
- signal: n
40
- }),
41
- pending: (t) => ({
42
- ...t,
43
- error: null,
44
- loading: !0,
45
- ...n || Object.is(e.params, t.params) ? {} : { pendingParams: e.params }
46
- }),
47
- success: (t) => {
48
- let a = n ? [...u, ...t.items] : [...t.items];
49
- return {
50
- error: null,
51
- items: a,
52
- loading: !1,
53
- pagination: i(a.length, e.pageSize, r(t.totalItems)),
54
- params: e.params
55
- };
56
- }
57
- });
58
- }, f = () => d(o, 1, !1), p = {
59
- get disposalSignal() {
60
- return l.disposalSignal;
61
- },
62
- dispose: l.dispose,
63
- get disposed() {
64
- return l.disposed;
65
- },
66
- async loadMore() {
67
- if (u(), !l.state.loading) {
68
- if (!c || !Object.is(o.params, l.state.params)) {
69
- await f();
70
- return;
71
- }
72
- l.state.pagination.hasMore && await d(o, s, !0);
73
- }
74
- },
75
- reload: f,
76
- async setPageSize(e) {
77
- u();
78
- let t = n(e, "pageSize");
79
- if (t === o.pageSize) {
80
- if (l.state.loading || l.state.pagination.pageSize === t) return;
81
- await f();
82
- return;
83
- }
84
- o = {
85
- ...o,
86
- pageSize: t
87
- }, s = 1, await f();
88
- },
89
- async setParams(e) {
90
- if (u(), Object.is(e, o.params)) {
91
- !l.state.loading && !Object.is(e, l.state.params) && await f();
92
- return;
93
- }
94
- o = {
95
- ...o,
96
- params: e
97
- }, s = 1, await f();
98
- },
99
- get state() {
100
- return l.state;
101
- },
102
- subscribe: l.subscribe,
103
- [Symbol.dispose]() {
104
- p.dispose();
105
- }
106
- };
107
- return p;
108
- }
109
- //#endregion
110
- export { a as createInfiniteSource };
111
-
1
+ import{SourcererDisposedError as e}from"./errors.js";import{createAsyncSource as t}from"./asyncSource.js";import{positiveInteger as n,totalItems as r}from"./pagination.js";var createPagination=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function createInfiniteSource(i){let a={pageSize:n(i.pageSize??20,`pageSize`),params:i.params},o=1,s=!1,c=t({error:null,items:[],loading:!1,pagination:createPagination(0,a.pageSize,0),params:a.params}),assertLive=()=>{if(c.disposed)throw new e},fetch=(e,t,n)=>{let l=c.state.items;return c.fetch({commit:()=>{s=!0,o=t+1,a=e},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>i.load({page:t,pageSize:e.pageSize,params:e.params,signal:n}),pending:t=>({...t,error:null,loading:!0,...n||Object.is(e.params,t.params)?{}:{pendingParams:e.params}}),success:t=>{let i=n?[...l,...t.items]:[...t.items];return{error:null,items:i,loading:!1,pagination:createPagination(i.length,e.pageSize,r(t.totalItems)),params:e.params}}})},reload=()=>fetch(a,1,!1),l={get disposalSignal(){return c.disposalSignal},dispose:c.dispose,get disposed(){return c.disposed},async loadMore(){if(assertLive(),!c.state.loading){if(!s||!Object.is(a.params,c.state.params)){await reload();return}c.state.pagination.hasMore&&await fetch(a,o,!0)}},reload,async setPageSize(e){assertLive();let t=n(e,`pageSize`);if(t===a.pageSize){if(c.state.loading||c.state.pagination.pageSize===t)return;await reload();return}a={...a,pageSize:t},o=1,await reload()},async setParams(e){if(assertLive(),Object.is(e,a.params)){!c.state.loading&&!Object.is(e,c.state.params)&&await reload();return}a={...a,params:e},o=1,await reload()},get state(){return c.state},subscribe:c.subscribe,[Symbol.dispose](){l.dispose()}};return l}export{createInfiniteSource};
112
2
  //# sourceMappingURL=infiniteSource.js.map