@vielzeug/sourcerer 2.3.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 (72) hide show
  1. package/README.md +17 -18
  2. package/dist/asyncSource.cjs +1 -1
  3. package/dist/asyncSource.cjs.map +1 -1
  4. package/dist/asyncSource.d.ts +11 -12
  5. package/dist/asyncSource.d.ts.map +1 -1
  6. package/dist/asyncSource.js +1 -50
  7. package/dist/asyncSource.js.map +1 -1
  8. package/dist/cursorSource.cjs +1 -1
  9. package/dist/cursorSource.cjs.map +1 -1
  10. package/dist/cursorSource.d.ts +2 -2
  11. package/dist/cursorSource.d.ts.map +1 -1
  12. package/dist/cursorSource.js +1 -81
  13. package/dist/cursorSource.js.map +1 -1
  14. package/dist/errors.cjs +1 -1
  15. package/dist/errors.cjs.map +1 -1
  16. package/dist/errors.d.ts +3 -0
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/errors.js +1 -9
  19. package/dist/errors.js.map +1 -1
  20. package/dist/index.cjs +1 -1
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -6
  24. package/dist/infiniteSource.cjs +1 -1
  25. package/dist/infiniteSource.cjs.map +1 -1
  26. package/dist/infiniteSource.d.ts +2 -2
  27. package/dist/infiniteSource.d.ts.map +1 -1
  28. package/dist/infiniteSource.js +1 -83
  29. package/dist/infiniteSource.js.map +1 -1
  30. package/dist/localSource.cjs +1 -1
  31. package/dist/localSource.cjs.map +1 -1
  32. package/dist/localSource.d.ts +3 -2
  33. package/dist/localSource.d.ts.map +1 -1
  34. package/dist/localSource.js +1 -73
  35. package/dist/localSource.js.map +1 -1
  36. package/dist/pageSource.cjs +1 -1
  37. package/dist/pageSource.cjs.map +1 -1
  38. package/dist/pageSource.d.ts +2 -2
  39. package/dist/pageSource.d.ts.map +1 -1
  40. package/dist/pageSource.js +1 -84
  41. package/dist/pageSource.js.map +1 -1
  42. package/dist/pagination.cjs +1 -1
  43. package/dist/pagination.cjs.map +1 -1
  44. package/dist/pagination.d.ts +1 -2
  45. package/dist/pagination.d.ts.map +1 -1
  46. package/dist/pagination.js +1 -28
  47. package/dist/pagination.js.map +1 -1
  48. package/dist/requestController.cjs +1 -1
  49. package/dist/requestController.cjs.map +1 -1
  50. package/dist/requestController.js +1 -30
  51. package/dist/requestController.js.map +1 -1
  52. package/dist/sourceStore.cjs +1 -1
  53. package/dist/sourceStore.cjs.map +1 -1
  54. package/dist/sourceStore.d.ts +5 -2
  55. package/dist/sourceStore.d.ts.map +1 -1
  56. package/dist/sourceStore.js +1 -37
  57. package/dist/sourceStore.js.map +1 -1
  58. package/dist/sourcerer.cjs +1 -1
  59. package/dist/sourcerer.cjs.map +1 -1
  60. package/dist/sourcerer.iife.js +1 -1
  61. package/dist/sourcerer.iife.js.map +1 -1
  62. package/dist/sourcerer.js +1 -1
  63. package/dist/sourcerer.js.map +1 -1
  64. package/dist/types.d.ts +130 -117
  65. package/dist/types.d.ts.map +1 -1
  66. package/package.json +12 -8
  67. package/dist/_dev.cjs +0 -2
  68. package/dist/_dev.cjs.map +0 -1
  69. package/dist/_dev.d.ts +0 -2
  70. package/dist/_dev.d.ts.map +0 -1
  71. package/dist/_dev.js +0 -6
  72. package/dist/_dev.js.map +0 -1
package/README.md CHANGED
@@ -1,43 +1,42 @@
1
1
  # @vielzeug/sourcerer
2
2
 
3
- Atomic reactive sources for local, numbered-page, cursor, and infinite collections.
3
+ > Reactive collection sources with local, page, cursor, and infinite pagination
4
+
5
+ ## Installation
4
6
 
5
7
  ```sh
6
8
  pnpm add @vielzeug/sourcerer
9
+ npm install @vielzeug/sourcerer
10
+ yarn add @vielzeug/sourcerer
7
11
  ```
8
12
 
13
+ ## Quick Start
14
+
9
15
  ```ts
10
16
  import { createPageSource } from '@vielzeug/sourcerer';
11
17
 
12
18
  const users = createPageSource({
13
- autoStart: false,
14
- initialQuery: { pageSize: 20 },
15
- load: async () => ({ data: [{ id: 1, name: 'Ada' }], total: 1 }),
19
+ load: async ({ page, pageSize }) => ({
20
+ items: [{ id: page, name: 'Ada' }].slice(0, pageSize),
21
+ totalItems: 1,
22
+ }),
23
+ pageSize: 20,
16
24
  });
17
25
 
18
26
  await users.reload();
19
- console.log(users.snapshot.data);
20
- console.log(users.snapshot.pagination.total);
27
+ console.log(users.state.items);
28
+ console.log(users.state.pagination.totalItems);
21
29
  users.dispose();
22
30
  ```
23
31
 
24
- Every source exposes an atomic `snapshot` and `subscribe(listener)`. `setQuery()` changes query fields; `page.*` changes page index. While newer work is active, `pendingQuery` records it without mixing it into loaded data. Page sources cancel superseded requests and preserve successful data on background refresh failures.
25
-
26
- | Factory | Purpose |
27
- | --- | --- |
28
- | `createLocalSource()` | Synchronous in-memory collection |
29
- | `createPageSource()` | Numbered async pages |
30
- | `createCursorSource()` | Cursor-based async pages |
31
- | `createInfiniteSource()` | Appended async pages |
32
-
33
- Sourcerer manages collection state and request succession. Configure retries, cache, polling, URL serialization, and optimistic mutation with your transport or application layer.
34
-
35
32
  ## Documentation
36
33
 
37
34
  - [Overview](https://vielzeug.dev/sourcerer/)
38
35
  - [Usage Guide](https://vielzeug.dev/sourcerer/usage)
39
36
  - [API Reference](https://vielzeug.dev/sourcerer/api)
37
+ - [Examples](https://vielzeug.dev/sourcerer/examples)
38
+ - [Migration Guide](https://vielzeug.dev/sourcerer/migration)
40
39
 
41
40
  ## License
42
41
 
43
- MIT © Helmuth Saatkamp — part of Vielzeug.
42
+ MIT © [Helmuth Saatkamp](https://github.com/helmuthdu) — part of the [Vielzeug](https://github.com/helmuthdu/vielzeug) monorepo.
@@ -1,2 +1,2 @@
1
- const e=require("./requestController.cjs"),t=require("./sourceStore.cjs");function n(n){let r=t.createSourceStore(n),i=e.createRequestController();return{get disposalSignal(){return r.disposalSignal},dispose(){i.dispose(),r.dispose()},get disposed(){return r.disposed},async fetch(t){if(r.disposed)return;let{query:n,load:a,success:o,pending:s,failure:c}=t,l=i.begin(),u=r.value;r.set(s?s(u):{...u,error:null,isFetching:!0,pendingQuery:n});let d;try{d=o(await a(l.signal))}catch(t){if(!l.isCurrent()||r.disposed)return;let n=e.toError(t);throw r.set(c?c(u,n):{...u,error:n,isFetching:!1,pendingQuery:void 0}),n}finally{l.finish()}!l.isCurrent()||r.disposed||r.set(d)},get snapshot(){return r.value},subscribe:r.subscribe}}exports.createAsyncSource=n;
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 { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\nimport type { AnyPagination, SourceSnapshot } from './types';\n\ntype FetchOptions<T, TQuery, TPagination extends AnyPagination, TResult> = {\n query: TQuery;\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): SourceSnapshot<T, TQuery, TPagination>;\n pending?(previous: SourceSnapshot<T, TQuery, TPagination>): SourceSnapshot<T, TQuery, TPagination>;\n failure?(previous: SourceSnapshot<T, TQuery, TPagination>, error: Error): SourceSnapshot<T, TQuery, TPagination>;\n};\n\ntype AsyncSource<T, TQuery, TPagination extends AnyPagination> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<T, TQuery, TPagination, TResult>): Promise<void>;\n readonly snapshot: SourceSnapshot<T, TQuery, TPagination>;\n subscribe(listener: (snapshot: SourceSnapshot<T, TQuery, TPagination>) => void): () => void;\n}>;\n\n/** Request failures and observer failures stay separate so observers cannot corrupt source state. */\nexport function createAsyncSource<T, TQuery, TPagination extends AnyPagination>(\n initial: SourceSnapshot<T, TQuery, TPagination>,\n): AsyncSource<T, TQuery, TPagination> {\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) return;\n\n const { query, load, success, pending, failure } = options;\n const request = requests.begin();\n const previous = store.value;\n\n store.set(pending ? pending(previous) : { ...previous, error: null, isFetching: true, pendingQuery: query });\n\n let next: SourceSnapshot<T, TQuery, TPagination>;\n\n try {\n next = success(await load(request.signal));\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n\n store.set(\n failure ? failure(previous, error) : { ...previous, error, isFetching: false, pendingQuery: undefined },\n );\n throw error;\n } finally {\n request.finish();\n }\n\n if (!request.isCurrent() || store.disposed) return;\n\n store.set(next);\n },\n\n get snapshot() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n"],"mappings":"0EAsBA,SAAgB,EACd,EACqC,CACrC,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,OAEpB,GAAM,CAAE,QAAO,OAAM,UAAS,UAAS,WAAY,EAC7C,EAAU,EAAS,MAAM,EACzB,EAAW,EAAM,MAEvB,EAAM,IAAI,EAAU,EAAQ,CAAQ,EAAI,CAAE,GAAG,EAAU,MAAO,KAAM,WAAY,GAAM,aAAc,CAAM,CAAC,EAE3G,IAAI,EAEJ,GAAI,CACF,EAAO,EAAQ,MAAM,EAAK,EAAQ,MAAM,CAAC,CAC3C,OAAS,EAAiB,CACxB,GAAI,CAAC,EAAQ,UAAU,GAAK,EAAM,SAAU,OAE5C,IAAM,EAAQ,EAAA,QAAQ,CAAM,EAK5B,MAHA,EAAM,IACJ,EAAU,EAAQ,EAAU,CAAK,EAAI,CAAE,GAAG,EAAU,QAAO,WAAY,GAAO,aAAc,IAAA,EAAU,CACxG,EACM,CACR,QAAU,CACR,EAAQ,OAAO,CACjB,CAEI,CAAC,EAAQ,UAAU,GAAK,EAAM,UAElC,EAAM,IAAI,CAAI,CAChB,EAEA,IAAI,UAAW,CACb,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,20 +1,19 @@
1
- import type { AnyPagination, SourceSnapshot } from './types';
2
- type FetchOptions<T, TQuery, TPagination extends AnyPagination, TResult> = {
3
- query: TQuery;
1
+ type FetchOptions<TState, TResult> = {
4
2
  load(signal: AbortSignal): Promise<TResult>;
5
- success(result: TResult): SourceSnapshot<T, TQuery, TPagination>;
6
- pending?(previous: SourceSnapshot<T, TQuery, TPagination>): SourceSnapshot<T, TQuery, TPagination>;
7
- failure?(previous: SourceSnapshot<T, TQuery, TPagination>, error: Error): SourceSnapshot<T, TQuery, TPagination>;
3
+ success(result: TResult): TState;
4
+ commit?(state: TState, result: TResult): void;
5
+ pending(previous: TState): TState;
6
+ failure(previous: TState, error: Error): TState;
8
7
  };
9
- type AsyncSource<T, TQuery, TPagination extends AnyPagination> = Readonly<{
8
+ type AsyncSource<TState> = Readonly<{
10
9
  readonly disposalSignal: AbortSignal;
11
10
  dispose(): void;
12
11
  readonly disposed: boolean;
13
- fetch<TResult>(options: FetchOptions<T, TQuery, TPagination, TResult>): Promise<void>;
14
- readonly snapshot: SourceSnapshot<T, TQuery, TPagination>;
15
- subscribe(listener: (snapshot: SourceSnapshot<T, TQuery, TPagination>) => void): () => void;
12
+ fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;
13
+ readonly state: TState;
14
+ subscribe(listener: (state: TState) => void): () => void;
16
15
  }>;
17
- /** Request failures and observer failures stay separate so observers cannot corrupt source state. */
18
- export declare function createAsyncSource<T, TQuery, TPagination extends AnyPagination>(initial: SourceSnapshot<T, TQuery, TPagination>): AsyncSource<T, TQuery, TPagination>;
16
+ /** Only the current request may commit; superseded work settles without changing source state. */
17
+ export declare function createAsyncSource<TState>(initial: TState): AsyncSource<TState>;
19
18
  export {};
20
19
  //# sourceMappingURL=asyncSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"asyncSource.d.ts","sourceRoot":"","sources":["../src/asyncSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE7D,KAAK,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,SAAS,aAAa,EAAE,OAAO,IAAI;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACnG,OAAO,CAAC,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;CAClH,CAAC;AAEF,KAAK,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,SAAS,aAAa,IAAI,QAAQ,CAAC;IACxE,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC1D,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC7F,CAAC,CAAC;AAEH,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,SAAS,aAAa,EAC5E,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAC9C,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAuDrC"}
1
+ {"version":3,"file":"asyncSource.d.ts","sourceRoot":"","sources":["../src/asyncSource.ts"],"names":[],"mappings":"AAoCA,KAAK,YAAY,CAAC,MAAM,EAAE,OAAO,IAAI;IACnC,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;CACjD,CAAC;AAEF,KAAK,WAAW,CAAC,MAAM,IAAI,QAAQ,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC1D,CAAC,CAAC;AAEH,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAiD9E"}
@@ -1,51 +1,2 @@
1
- import { createRequestController as e, toError as t } from "./requestController.js";
2
- import { createSourceStore as n } from "./sourceStore.js";
3
- //#region src/asyncSource.ts
4
- function r(r) {
5
- let i = n(r), a = e();
6
- return {
7
- get disposalSignal() {
8
- return i.disposalSignal;
9
- },
10
- dispose() {
11
- a.dispose(), i.dispose();
12
- },
13
- get disposed() {
14
- return i.disposed;
15
- },
16
- async fetch(e) {
17
- if (i.disposed) return;
18
- let { query: n, load: r, success: o, pending: s, failure: c } = e, l = a.begin(), u = i.value;
19
- i.set(s ? s(u) : {
20
- ...u,
21
- error: null,
22
- isFetching: !0,
23
- pendingQuery: n
24
- });
25
- let d;
26
- try {
27
- d = o(await r(l.signal));
28
- } catch (e) {
29
- if (!l.isCurrent() || i.disposed) return;
30
- let n = t(e);
31
- throw i.set(c ? c(u, n) : {
32
- ...u,
33
- error: n,
34
- isFetching: !1,
35
- pendingQuery: void 0
36
- }), n;
37
- } finally {
38
- l.finish();
39
- }
40
- !l.isCurrent() || i.disposed || i.set(d);
41
- },
42
- get snapshot() {
43
- return i.value;
44
- },
45
- subscribe: i.subscribe
46
- };
47
- }
48
- //#endregion
49
- export { r as createAsyncSource };
50
-
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};
51
2
  //# sourceMappingURL=asyncSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"asyncSource.js","names":[],"sources":["../src/asyncSource.ts"],"sourcesContent":["import { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\nimport type { AnyPagination, SourceSnapshot } from './types';\n\ntype FetchOptions<T, TQuery, TPagination extends AnyPagination, TResult> = {\n query: TQuery;\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): SourceSnapshot<T, TQuery, TPagination>;\n pending?(previous: SourceSnapshot<T, TQuery, TPagination>): SourceSnapshot<T, TQuery, TPagination>;\n failure?(previous: SourceSnapshot<T, TQuery, TPagination>, error: Error): SourceSnapshot<T, TQuery, TPagination>;\n};\n\ntype AsyncSource<T, TQuery, TPagination extends AnyPagination> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<T, TQuery, TPagination, TResult>): Promise<void>;\n readonly snapshot: SourceSnapshot<T, TQuery, TPagination>;\n subscribe(listener: (snapshot: SourceSnapshot<T, TQuery, TPagination>) => void): () => void;\n}>;\n\n/** Request failures and observer failures stay separate so observers cannot corrupt source state. */\nexport function createAsyncSource<T, TQuery, TPagination extends AnyPagination>(\n initial: SourceSnapshot<T, TQuery, TPagination>,\n): AsyncSource<T, TQuery, TPagination> {\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) return;\n\n const { query, load, success, pending, failure } = options;\n const request = requests.begin();\n const previous = store.value;\n\n store.set(pending ? pending(previous) : { ...previous, error: null, isFetching: true, pendingQuery: query });\n\n let next: SourceSnapshot<T, TQuery, TPagination>;\n\n try {\n next = success(await load(request.signal));\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n\n store.set(\n failure ? failure(previous, error) : { ...previous, error, isFetching: false, pendingQuery: undefined },\n );\n throw error;\n } finally {\n request.finish();\n }\n\n if (!request.isCurrent() || store.disposed) return;\n\n store.set(next);\n },\n\n get snapshot() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n"],"mappings":";;;AAsBA,SAAgB,EACd,GACqC;CACrC,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;GAEpB,IAAM,EAAE,UAAO,SAAM,YAAS,YAAS,eAAY,GAC7C,IAAU,EAAS,MAAM,GACzB,IAAW,EAAM;GAEvB,EAAM,IAAI,IAAU,EAAQ,CAAQ,IAAI;IAAE,GAAG;IAAU,OAAO;IAAM,YAAY;IAAM,cAAc;GAAM,CAAC;GAE3G,IAAI;GAEJ,IAAI;IACF,IAAO,EAAQ,MAAM,EAAK,EAAQ,MAAM,CAAC;GAC3C,SAAS,GAAiB;IACxB,IAAI,CAAC,EAAQ,UAAU,KAAK,EAAM,UAAU;IAE5C,IAAM,IAAQ,EAAQ,CAAM;IAK5B,MAHA,EAAM,IACJ,IAAU,EAAQ,GAAU,CAAK,IAAI;KAAE,GAAG;KAAU;KAAO,YAAY;KAAO,cAAc,KAAA;IAAU,CACxG,GACM;GACR,UAAU;IACR,EAAQ,OAAO;GACjB;GAEI,CAAC,EAAQ,UAAU,KAAK,EAAM,YAElC,EAAM,IAAI,CAAI;EAChB;EAEA,IAAI,WAAW;GACb,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("./_dev.cjs"),t=require("./asyncSource.cjs"),n=require("./errors.cjs"),r=require("./pagination.cjs");var i=e=>({hasNext:e?.nextCursor!==void 0,hasPrevious:e?.previousCursor!==void 0,kind:`cursor`,...e?.nextCursor!==void 0&&{nextCursor:e.nextCursor},...e?.previousCursor!==void 0&&{previousCursor:e.previousCursor},...e?.total!==void 0&&{total:r.totalItems(e.total)}}),a=(e,t={})=>{if(t.after!==void 0&&t.before!==void 0)throw new n.SourcererConfigurationError(`Cursor query cannot include both after and before`);let i=t.pageSize!==void 0||t.search!==void 0,a=i||`before`in t?void 0:`after`in t?t.after:e.after,o=i||`after`in t?void 0:`before`in t?t.before:e.before;return{...a!==void 0&&{after:a},...o!==void 0&&{before:o},pageSize:r.positiveInteger(t.pageSize??e.pageSize,`pageSize`),search:t.search??e.search}};function o(n){let o=a({pageSize:20,search:``},n.initialQuery),s=t.createAsyncSource({data:[],error:null,isFetching:!1,pagination:i(),query:o}),c=e=>s.fetch({load:t=>n.load({query:e,signal:t}),query:e,success:t=>({data:t.data,error:null,isFetching:!1,pagination:i(t),query:e})}),l=()=>c(o),u=async e=>{let t=a(s.snapshot.pendingQuery??s.snapshot.query,e);r.sameQuery(t,o)||(o=t,await c(t))},d={get disposalSignal(){return s.disposalSignal},dispose:s.dispose,get disposed(){return s.disposed},page:{next(){let e=s.snapshot.pagination.nextCursor;return s.snapshot.isFetching||e===void 0?Promise.resolve():u({after:e})},previous(){let e=s.snapshot.pagination.previousCursor;return s.snapshot.isFetching||e===void 0?Promise.resolve():u({before:e})}},reload:l,setQuery:u,get snapshot(){return s.snapshot},subscribe:s.subscribe,[Symbol.dispose](){d.dispose()}};return n.autoStart!==!1&&l().catch(()=>e.warn(`Initial load failed. Inspect source.snapshot.error.`)),d}exports.createCursorSource=o;
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 { warn } from './_dev';\nimport { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError } from './errors';\nimport { positiveInteger, sameQuery, totalItems } from './pagination';\nimport type { CursorPagination, CursorQuery, CursorQueryPatch, CursorSource, CursorSourceConfig } from './types';\n\nconst createPagination = <TCursor>(result?: {\n nextCursor?: TCursor;\n previousCursor?: TCursor;\n total?: number;\n}): CursorPagination<TCursor> => ({\n hasNext: result?.nextCursor !== undefined,\n hasPrevious: result?.previousCursor !== undefined,\n kind: 'cursor',\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.total !== undefined && { total: totalItems(result.total) }),\n});\n\nconst normalizeQuery = <TCursor>(\n current: CursorQuery<TCursor>,\n patch: CursorQueryPatch<TCursor> = {},\n): CursorQuery<TCursor> => {\n if (patch.after !== undefined && patch.before !== undefined) {\n throw new SourcererConfigurationError('Cursor query cannot include both after and before');\n }\n\n const resetsCursor = patch.pageSize !== undefined || patch.search !== undefined;\n const after = resetsCursor || 'before' in patch ? undefined : 'after' in patch ? patch.after : current.after;\n const before = resetsCursor || 'after' in patch ? undefined : 'before' in patch ? patch.before : current.before;\n\n return {\n ...(after !== undefined && { after }),\n ...(before !== undefined && { before }),\n pageSize: positiveInteger(patch.pageSize ?? current.pageSize, 'pageSize'),\n search: patch.search ?? current.search,\n };\n};\n\n/** Cursor sources retain loaded cursors while pendingQuery records newer navigation. */\nexport function createCursorSource<T, TCursor = string>(\n config: CursorSourceConfig<T, TCursor>,\n): CursorSource<T, TCursor> {\n const initialQuery: CursorQuery<TCursor> = { pageSize: 20, search: '' };\n let requestedQuery = normalizeQuery(initialQuery, config.initialQuery);\n const asyncSource = createAsyncSource<T, CursorQuery<TCursor>, CursorPagination<TCursor>>({\n data: [],\n error: null,\n isFetching: false,\n pagination: createPagination(),\n query: requestedQuery,\n });\n\n const fetch = (query: CursorQuery<TCursor>): Promise<void> =>\n asyncSource.fetch({\n load: (signal) => config.load({ query, signal }),\n query,\n success: (result) => ({\n data: result.data,\n error: null,\n isFetching: false,\n pagination: createPagination(result),\n query,\n }),\n });\n\n const reload = (): Promise<void> => fetch(requestedQuery);\n\n const setQuery = async (patch: CursorQueryPatch<TCursor>): Promise<void> => {\n const current = asyncSource.snapshot.pendingQuery ?? asyncSource.snapshot.query;\n const next = normalizeQuery(current, patch);\n\n if (sameQuery(next, requestedQuery)) return;\n\n requestedQuery = next;\n await fetch(next);\n };\n\n const source: CursorSource<T, 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 page: {\n next() {\n const cursor = asyncSource.snapshot.pagination.nextCursor;\n\n return asyncSource.snapshot.isFetching || cursor === undefined\n ? Promise.resolve()\n : setQuery({ after: cursor });\n },\n\n previous() {\n const cursor = asyncSource.snapshot.pagination.previousCursor;\n\n return asyncSource.snapshot.isFetching || cursor === undefined\n ? Promise.resolve()\n : setQuery({ before: cursor });\n },\n },\n\n reload,\n setQuery,\n\n get snapshot() {\n return asyncSource.snapshot;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n if (config.autoStart !== false)\n void reload().catch(() => warn('Initial load failed. Inspect source.snapshot.error.'));\n\n return source;\n}\n"],"mappings":"qHAMA,IAAM,EAA6B,IAID,CAChC,QAAS,GAAQ,aAAe,IAAA,GAChC,YAAa,GAAQ,iBAAmB,IAAA,GACxC,KAAM,SACN,GAAI,GAAQ,aAAe,IAAA,IAAa,CAAE,WAAY,EAAO,UAAW,EACxE,GAAI,GAAQ,iBAAmB,IAAA,IAAa,CAAE,eAAgB,EAAO,cAAe,EACpF,GAAI,GAAQ,QAAU,IAAA,IAAa,CAAE,MAAO,EAAA,WAAW,EAAO,KAAK,CAAE,CACvE,GAEM,GACJ,EACA,EAAmC,CAAC,IACX,CACzB,GAAI,EAAM,QAAU,IAAA,IAAa,EAAM,SAAW,IAAA,GAChD,MAAM,IAAI,EAAA,4BAA4B,mDAAmD,EAG3F,IAAM,EAAe,EAAM,WAAa,IAAA,IAAa,EAAM,SAAW,IAAA,GAChE,EAAQ,GAAgB,WAAY,EAAQ,IAAA,GAAY,UAAW,EAAQ,EAAM,MAAQ,EAAQ,MACjG,EAAS,GAAgB,UAAW,EAAQ,IAAA,GAAY,WAAY,EAAQ,EAAM,OAAS,EAAQ,OAEzG,MAAO,CACL,GAAI,IAAU,IAAA,IAAa,CAAE,OAAM,EACnC,GAAI,IAAW,IAAA,IAAa,CAAE,QAAO,EACrC,SAAU,EAAA,gBAAgB,EAAM,UAAY,EAAQ,SAAU,UAAU,EACxE,OAAQ,EAAM,QAAU,EAAQ,MAClC,CACF,EAGA,SAAgB,EACd,EAC0B,CAE1B,IAAI,EAAiB,EAAe,CADS,SAAU,GAAI,OAAQ,EAC/B,EAAc,EAAO,YAAY,EAC/D,EAAc,EAAA,kBAAsE,CACxF,KAAM,CAAC,EACP,MAAO,KACP,WAAY,GACZ,WAAY,EAAiB,EAC7B,MAAO,CACT,CAAC,EAEK,EAAS,GACb,EAAY,MAAM,CAChB,KAAO,GAAW,EAAO,KAAK,CAAE,QAAO,QAAO,CAAC,EAC/C,QACA,QAAU,IAAY,CACpB,KAAM,EAAO,KACb,MAAO,KACP,WAAY,GACZ,WAAY,EAAiB,CAAM,EACnC,OACF,EACF,CAAC,EAEG,MAA8B,EAAM,CAAc,EAElD,EAAW,KAAO,IAAoD,CAE1E,IAAM,EAAO,EADG,EAAY,SAAS,cAAgB,EAAY,SAAS,MACrC,CAAK,EAEtC,EAAA,UAAU,EAAM,CAAc,IAElC,EAAiB,EACjB,MAAM,EAAM,CAAI,EAClB,EAEM,EAAmC,CACvC,IAAI,gBAAiB,CACnB,OAAO,EAAY,cACrB,EAEA,QAAS,EAAY,QAErB,IAAI,UAAW,CACb,OAAO,EAAY,QACrB,EAEA,KAAM,CACJ,MAAO,CACL,IAAM,EAAS,EAAY,SAAS,WAAW,WAE/C,OAAO,EAAY,SAAS,YAAc,IAAW,IAAA,GACjD,QAAQ,QAAQ,EAChB,EAAS,CAAE,MAAO,CAAO,CAAC,CAChC,EAEA,UAAW,CACT,IAAM,EAAS,EAAY,SAAS,WAAW,eAE/C,OAAO,EAAY,SAAS,YAAc,IAAW,IAAA,GACjD,QAAQ,QAAQ,EAChB,EAAS,CAAE,OAAQ,CAAO,CAAC,CACjC,CACF,EAEA,SACA,WAEA,IAAI,UAAW,CACb,OAAO,EAAY,QACrB,EAEA,UAAW,EAAY,UAEvB,CAAC,OAAO,UAAW,CACjB,EAAO,QAAQ,CACjB,CACF,EAKA,OAHI,EAAO,YAAc,IACvB,EAAY,CAAC,CAAC,UAAY,EAAA,KAAK,qDAAqD,CAAC,EAEhF,CACT"}
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,4 +1,4 @@
1
1
  import type { CursorSource, CursorSourceConfig } from './types';
2
- /** Cursor sources retain loaded cursors while pendingQuery records newer navigation. */
3
- export declare function createCursorSource<T, TCursor = string>(config: CursorSourceConfig<T, TCursor>): CursorSource<T, TCursor>;
2
+ /** Cursor sources retain committed items and cursors while replacement work is pending. */
3
+ export declare function createCursorSource<T, TParams = undefined, TCursor = string>(config: CursorSourceConfig<T, TParams, TCursor>): CursorSource<T, TParams, TCursor>;
4
4
  //# sourceMappingURL=cursorSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursorSource.d.ts","sourceRoot":"","sources":["../src/cursorSource.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAmD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAmCjH,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,EACpD,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,OAAO,CAAC,GACrC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAmF1B"}
1
+ {"version":3,"file":"cursorSource.d.ts","sourceRoot":"","sources":["../src/cursorSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkC,YAAY,EAAE,kBAAkB,EAAqB,MAAM,SAAS,CAAC;AAmBnH,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,GAAG,MAAM,EACzE,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAC9C,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CA+GnC"}
@@ -1,82 +1,2 @@
1
- import { warn as e } from "./_dev.js";
2
- import { createAsyncSource as t } from "./asyncSource.js";
3
- import { SourcererConfigurationError as n } from "./errors.js";
4
- import { positiveInteger as r, sameQuery as i, totalItems as a } from "./pagination.js";
5
- //#region src/cursorSource.ts
6
- var o = (e) => ({
7
- hasNext: e?.nextCursor !== void 0,
8
- hasPrevious: e?.previousCursor !== void 0,
9
- kind: "cursor",
10
- ...e?.nextCursor !== void 0 && { nextCursor: e.nextCursor },
11
- ...e?.previousCursor !== void 0 && { previousCursor: e.previousCursor },
12
- ...e?.total !== void 0 && { total: a(e.total) }
13
- }), s = (e, t = {}) => {
14
- if (t.after !== void 0 && t.before !== void 0) throw new n("Cursor query cannot include both after and before");
15
- let i = t.pageSize !== void 0 || t.search !== void 0, a = i || "before" in t ? void 0 : "after" in t ? t.after : e.after, o = i || "after" in t ? void 0 : "before" in t ? t.before : e.before;
16
- return {
17
- ...a !== void 0 && { after: a },
18
- ...o !== void 0 && { before: o },
19
- pageSize: r(t.pageSize ?? e.pageSize, "pageSize"),
20
- search: t.search ?? e.search
21
- };
22
- };
23
- function c(n) {
24
- let r = s({
25
- pageSize: 20,
26
- search: ""
27
- }, n.initialQuery), a = t({
28
- data: [],
29
- error: null,
30
- isFetching: !1,
31
- pagination: o(),
32
- query: r
33
- }), c = (e) => a.fetch({
34
- load: (t) => n.load({
35
- query: e,
36
- signal: t
37
- }),
38
- query: e,
39
- success: (t) => ({
40
- data: t.data,
41
- error: null,
42
- isFetching: !1,
43
- pagination: o(t),
44
- query: e
45
- })
46
- }), l = () => c(r), u = async (e) => {
47
- let t = s(a.snapshot.pendingQuery ?? a.snapshot.query, e);
48
- i(t, r) || (r = t, await c(t));
49
- }, d = {
50
- get disposalSignal() {
51
- return a.disposalSignal;
52
- },
53
- dispose: a.dispose,
54
- get disposed() {
55
- return a.disposed;
56
- },
57
- page: {
58
- next() {
59
- let e = a.snapshot.pagination.nextCursor;
60
- return a.snapshot.isFetching || e === void 0 ? Promise.resolve() : u({ after: e });
61
- },
62
- previous() {
63
- let e = a.snapshot.pagination.previousCursor;
64
- return a.snapshot.isFetching || e === void 0 ? Promise.resolve() : u({ before: e });
65
- }
66
- },
67
- reload: l,
68
- setQuery: u,
69
- get snapshot() {
70
- return a.snapshot;
71
- },
72
- subscribe: a.subscribe,
73
- [Symbol.dispose]() {
74
- d.dispose();
75
- }
76
- };
77
- return n.autoStart !== !1 && l().catch(() => /* @__PURE__ */ e("Initial load failed. Inspect source.snapshot.error.")), d;
78
- }
79
- //#endregion
80
- export { c as createCursorSource };
81
-
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};
82
2
  //# sourceMappingURL=cursorSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursorSource.js","names":[],"sources":["../src/cursorSource.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError } from './errors';\nimport { positiveInteger, sameQuery, totalItems } from './pagination';\nimport type { CursorPagination, CursorQuery, CursorQueryPatch, CursorSource, CursorSourceConfig } from './types';\n\nconst createPagination = <TCursor>(result?: {\n nextCursor?: TCursor;\n previousCursor?: TCursor;\n total?: number;\n}): CursorPagination<TCursor> => ({\n hasNext: result?.nextCursor !== undefined,\n hasPrevious: result?.previousCursor !== undefined,\n kind: 'cursor',\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.total !== undefined && { total: totalItems(result.total) }),\n});\n\nconst normalizeQuery = <TCursor>(\n current: CursorQuery<TCursor>,\n patch: CursorQueryPatch<TCursor> = {},\n): CursorQuery<TCursor> => {\n if (patch.after !== undefined && patch.before !== undefined) {\n throw new SourcererConfigurationError('Cursor query cannot include both after and before');\n }\n\n const resetsCursor = patch.pageSize !== undefined || patch.search !== undefined;\n const after = resetsCursor || 'before' in patch ? undefined : 'after' in patch ? patch.after : current.after;\n const before = resetsCursor || 'after' in patch ? undefined : 'before' in patch ? patch.before : current.before;\n\n return {\n ...(after !== undefined && { after }),\n ...(before !== undefined && { before }),\n pageSize: positiveInteger(patch.pageSize ?? current.pageSize, 'pageSize'),\n search: patch.search ?? current.search,\n };\n};\n\n/** Cursor sources retain loaded cursors while pendingQuery records newer navigation. */\nexport function createCursorSource<T, TCursor = string>(\n config: CursorSourceConfig<T, TCursor>,\n): CursorSource<T, TCursor> {\n const initialQuery: CursorQuery<TCursor> = { pageSize: 20, search: '' };\n let requestedQuery = normalizeQuery(initialQuery, config.initialQuery);\n const asyncSource = createAsyncSource<T, CursorQuery<TCursor>, CursorPagination<TCursor>>({\n data: [],\n error: null,\n isFetching: false,\n pagination: createPagination(),\n query: requestedQuery,\n });\n\n const fetch = (query: CursorQuery<TCursor>): Promise<void> =>\n asyncSource.fetch({\n load: (signal) => config.load({ query, signal }),\n query,\n success: (result) => ({\n data: result.data,\n error: null,\n isFetching: false,\n pagination: createPagination(result),\n query,\n }),\n });\n\n const reload = (): Promise<void> => fetch(requestedQuery);\n\n const setQuery = async (patch: CursorQueryPatch<TCursor>): Promise<void> => {\n const current = asyncSource.snapshot.pendingQuery ?? asyncSource.snapshot.query;\n const next = normalizeQuery(current, patch);\n\n if (sameQuery(next, requestedQuery)) return;\n\n requestedQuery = next;\n await fetch(next);\n };\n\n const source: CursorSource<T, 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 page: {\n next() {\n const cursor = asyncSource.snapshot.pagination.nextCursor;\n\n return asyncSource.snapshot.isFetching || cursor === undefined\n ? Promise.resolve()\n : setQuery({ after: cursor });\n },\n\n previous() {\n const cursor = asyncSource.snapshot.pagination.previousCursor;\n\n return asyncSource.snapshot.isFetching || cursor === undefined\n ? Promise.resolve()\n : setQuery({ before: cursor });\n },\n },\n\n reload,\n setQuery,\n\n get snapshot() {\n return asyncSource.snapshot;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n if (config.autoStart !== false)\n void reload().catch(() => warn('Initial load failed. Inspect source.snapshot.error.'));\n\n return source;\n}\n"],"mappings":";;;;;AAMA,IAAM,KAA6B,OAID;CAChC,SAAS,GAAQ,eAAe,KAAA;CAChC,aAAa,GAAQ,mBAAmB,KAAA;CACxC,MAAM;CACN,GAAI,GAAQ,eAAe,KAAA,KAAa,EAAE,YAAY,EAAO,WAAW;CACxE,GAAI,GAAQ,mBAAmB,KAAA,KAAa,EAAE,gBAAgB,EAAO,eAAe;CACpF,GAAI,GAAQ,UAAU,KAAA,KAAa,EAAE,OAAO,EAAW,EAAO,KAAK,EAAE;AACvE,IAEM,KACJ,GACA,IAAmC,CAAC,MACX;CACzB,IAAI,EAAM,UAAU,KAAA,KAAa,EAAM,WAAW,KAAA,GAChD,MAAM,IAAI,EAA4B,mDAAmD;CAG3F,IAAM,IAAe,EAAM,aAAa,KAAA,KAAa,EAAM,WAAW,KAAA,GAChE,IAAQ,KAAgB,YAAY,IAAQ,KAAA,IAAY,WAAW,IAAQ,EAAM,QAAQ,EAAQ,OACjG,IAAS,KAAgB,WAAW,IAAQ,KAAA,IAAY,YAAY,IAAQ,EAAM,SAAS,EAAQ;CAEzG,OAAO;EACL,GAAI,MAAU,KAAA,KAAa,EAAE,SAAM;EACnC,GAAI,MAAW,KAAA,KAAa,EAAE,UAAO;EACrC,UAAU,EAAgB,EAAM,YAAY,EAAQ,UAAU,UAAU;EACxE,QAAQ,EAAM,UAAU,EAAQ;CAClC;AACF;AAGA,SAAgB,EACd,GAC0B;CAE1B,IAAI,IAAiB,EAAe;EADS,UAAU;EAAI,QAAQ;CAC/B,GAAc,EAAO,YAAY,GAC/D,IAAc,EAAsE;EACxF,MAAM,CAAC;EACP,OAAO;EACP,YAAY;EACZ,YAAY,EAAiB;EAC7B,OAAO;CACT,CAAC,GAEK,KAAS,MACb,EAAY,MAAM;EAChB,OAAO,MAAW,EAAO,KAAK;GAAE;GAAO;EAAO,CAAC;EAC/C;EACA,UAAU,OAAY;GACpB,MAAM,EAAO;GACb,OAAO;GACP,YAAY;GACZ,YAAY,EAAiB,CAAM;GACnC;EACF;CACF,CAAC,GAEG,UAA8B,EAAM,CAAc,GAElD,IAAW,OAAO,MAAoD;EAE1E,IAAM,IAAO,EADG,EAAY,SAAS,gBAAgB,EAAY,SAAS,OACrC,CAAK;EAEtC,EAAU,GAAM,CAAc,MAElC,IAAiB,GACjB,MAAM,EAAM,CAAI;CAClB,GAEM,IAAmC;EACvC,IAAI,iBAAiB;GACnB,OAAO,EAAY;EACrB;EAEA,SAAS,EAAY;EAErB,IAAI,WAAW;GACb,OAAO,EAAY;EACrB;EAEA,MAAM;GACJ,OAAO;IACL,IAAM,IAAS,EAAY,SAAS,WAAW;IAE/C,OAAO,EAAY,SAAS,cAAc,MAAW,KAAA,IACjD,QAAQ,QAAQ,IAChB,EAAS,EAAE,OAAO,EAAO,CAAC;GAChC;GAEA,WAAW;IACT,IAAM,IAAS,EAAY,SAAS,WAAW;IAE/C,OAAO,EAAY,SAAS,cAAc,MAAW,KAAA,IACjD,QAAQ,QAAQ,IAChB,EAAS,EAAE,QAAQ,EAAO,CAAC;GACjC;EACF;EAEA;EACA;EAEA,IAAI,WAAW;GACb,OAAO,EAAY;EACrB;EAEA,WAAW,EAAY;EAEvB,CAAC,OAAO,WAAW;GACjB,EAAO,QAAQ;EACjB;CACF;CAKA,OAHI,EAAO,cAAc,MACvB,EAAY,CAAC,CAAC,YAAY,kBAAK,qDAAqD,CAAC,GAEhF;AACT"}
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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"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{};exports.SourcererConfigurationError=t,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 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"],"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,EAAb,cAAiD,CAAe,CAAC"}
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
@@ -5,4 +5,7 @@ export declare class SourcererError extends Error {
5
5
  /** Thrown when a source is configured or queried with invalid arguments. */
6
6
  export declare class SourcererConfigurationError extends SourcererError {
7
7
  }
8
+ export declare class SourcererDisposedError extends SourcererError {
9
+ constructor(message?: string);
10
+ }
8
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;gBAC3B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED,4EAA4E;AAC5E,qBAAa,2BAA4B,SAAQ,cAAc;CAAG"}
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,10 +1,2 @@
1
- //#region src/errors.ts
2
- var e = class extends Error {
3
- constructor(e, t) {
4
- super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
5
- }
6
- }, t = class extends e {};
7
- //#endregion
8
- export { t as SourcererConfigurationError, e as SourcererError };
9
-
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};
10
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 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"],"mappings":";AACA,IAAa,IAAb,cAAoC,MAAM;CACxC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAGa,IAAb,cAAiD,EAAe,CAAC"}
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.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./cursorSource.cjs"),n=require("./infiniteSource.cjs"),r=require("./localSource.cjs"),i=require("./pageSource.cjs");exports.SourcererConfigurationError=e.SourcererConfigurationError,exports.SourcererError=e.SourcererError,exports.createCursorSource=t.createCursorSource,exports.createInfiniteSource=n.createInfiniteSource,exports.createLocalSource=r.createLocalSource,exports.createPageSource=i.createPageSource;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./cursorSource.cjs"),n=require("./infiniteSource.cjs"),r=require("./localSource.cjs"),i=require("./pageSource.cjs");exports.SourcererConfigurationError=e.SourcererConfigurationError,exports.SourcererDisposedError=e.SourcererDisposedError,exports.SourcererError=e.SourcererError,exports.createCursorSource=t.createCursorSource,exports.createInfiniteSource=n.createInfiniteSource,exports.createLocalSource=r.createLocalSource,exports.createPageSource=i.createPageSource;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { createCursorSource } from './cursorSource';
2
- export { SourcererConfigurationError, SourcererError } from './errors';
2
+ export { SourcererConfigurationError, SourcererDisposedError, SourcererError } from './errors';
3
3
  export { createInfiniteSource } from './infiniteSource';
4
4
  export { createLocalSource } from './localSource';
5
5
  export { createPageSource } from './pageSource';
6
- export type { AnyPagination, CursorPagination, CursorQuery, CursorQueryPatch, CursorResult, CursorSource, CursorSourceConfig, InfiniteLoadQuery, InfinitePagination, InfiniteQuery, InfiniteQueryPatch, InfiniteSource, InfiniteSourceConfig, LoadContext, LocalQuery, LocalQueryPatch, LocalSource, LocalSourceConfig, PagePagination, PageQuery, PageQueryPatch, PageResult, PageSource, PageSourceConfig, Source, SourceSnapshot, } from './types';
6
+ export type { CursorLoadContext, CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState, InfiniteLoadContext, InfinitePagination, InfiniteSource, InfiniteSourceConfig, InfiniteSourceState, LocalSource, LocalSourceConfig, LocalSourceState, PageLoadContext, PagePagination, PageResult, PageSource, PageSourceConfig, PageSourceState, } from './types';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,cAAc,EACd,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,cAAc,GACf,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,GAChB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1 @@
1
- import { SourcererConfigurationError as e, SourcererError as t } from "./errors.js";
2
- import { createCursorSource as n } from "./cursorSource.js";
3
- import { createInfiniteSource as r } from "./infiniteSource.js";
4
- import { createLocalSource as i } from "./localSource.js";
5
- import { createPageSource as a } from "./pageSource.js";
6
- export { e as SourcererConfigurationError, t as SourcererError, n as createCursorSource, r as createInfiniteSource, i as createLocalSource, a 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("./_dev.cjs"),t=require("./asyncSource.cjs"),n=require("./pagination.cjs");var r=(e,t)=>({hasMore:e<t,kind:`infinite`,loaded:e,total:t}),i=(e,t={})=>({pageSize:n.positiveInteger(t.pageSize??e.pageSize,`pageSize`),search:t.search??e.search});function a(a){let o=i({pageSize:20,search:``},a.initialQuery),s=1,c=t.createAsyncSource({data:[],error:null,isFetching:!1,pagination:r(0,0),query:o}),l=(e,t,i)=>{let o=c.snapshot.data;return c.fetch({load:n=>a.load({query:{page:t,pageSize:e.pageSize,search:e.search},signal:n}),pending:t=>({...t,error:null,isFetching:!0,pagination:r(t.data.length,t.pagination.total),...i?{}:{pendingQuery:e}}),query:e,success:a=>{let c=n.totalItems(a.total),l=i?[...o,...a.data]:a.data;return s=t+1,{data:l,error:null,isFetching:!1,pagination:r(l.length,c),query:e}}})},u=()=>(s=1,l(o,1,!1)),d={get disposalSignal(){return c.disposalSignal},dispose:c.dispose,get disposed(){return c.disposed},loadMore(){let{isFetching:e,pagination:t}=c.snapshot;return e||c.snapshot.data.length>0&&!t.hasMore?Promise.resolve():l(o,s,!0)},reload:u,setQuery:async e=>{let t=i(c.snapshot.pendingQuery??c.snapshot.query,e);n.sameQuery(t,o)||(o=t,s=1,await l(t,1,!1))},get snapshot(){return c.snapshot},subscribe:c.subscribe,[Symbol.dispose](){d.dispose()}};return a.autoStart!==!1&&u().catch(()=>e.warn(`Initial load failed. Inspect source.snapshot.error.`)),d}exports.createInfiniteSource=a;
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