@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
@@ -1 +1 @@
1
- {"version":3,"file":"infiniteSource.cjs","names":[],"sources":["../src/infiniteSource.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { createAsyncSource } from './asyncSource';\nimport { positiveInteger, sameQuery, totalItems } from './pagination';\nimport type {\n InfinitePagination,\n InfiniteQuery,\n InfiniteQueryPatch,\n InfiniteSource,\n InfiniteSourceConfig,\n} from './types';\n\nconst createPagination = (loaded: number, total: number): InfinitePagination => ({\n hasMore: loaded < total,\n kind: 'infinite',\n loaded,\n total,\n});\n\nconst normalizeQuery = (current: InfiniteQuery, patch: InfiniteQueryPatch = {}): InfiniteQuery => ({\n pageSize: positiveInteger(patch.pageSize ?? current.pageSize, 'pageSize'),\n search: patch.search ?? current.search,\n});\n\n/** Infinite sources preserve loaded collection state while a pending query replaces it. */\nexport function createInfiniteSource<T>(config: InfiniteSourceConfig<T>): InfiniteSource<T> {\n const initialQuery: InfiniteQuery = { pageSize: 20, search: '' };\n let requestedQuery = normalizeQuery(initialQuery, config.initialQuery);\n let nextPage = 1;\n const asyncSource = createAsyncSource<T, InfiniteQuery, InfinitePagination>({\n data: [],\n error: null,\n isFetching: false,\n pagination: createPagination(0, 0),\n query: requestedQuery,\n });\n\n const fetch = (query: InfiniteQuery, page: number, append: boolean): Promise<void> => {\n const loadedData = asyncSource.snapshot.data;\n\n return asyncSource.fetch({\n load: (signal) => config.load({ query: { page, pageSize: query.pageSize, search: query.search }, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n isFetching: true,\n pagination: createPagination(previous.data.length, previous.pagination.total),\n ...(append ? {} : { pendingQuery: query }),\n }),\n query,\n success: (result) => {\n const total = totalItems(result.total);\n const data = append ? [...loadedData, ...result.data] : result.data;\n\n nextPage = page + 1;\n\n return {\n data,\n error: null,\n isFetching: false,\n pagination: createPagination(data.length, total),\n query,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => {\n nextPage = 1;\n\n return fetch(requestedQuery, 1, false);\n };\n\n const setQuery = async (patch: InfiniteQueryPatch): 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 nextPage = 1;\n await fetch(next, 1, false);\n };\n\n const source: InfiniteSource<T> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n loadMore() {\n const { isFetching, pagination } = asyncSource.snapshot;\n\n return isFetching || (asyncSource.snapshot.data.length > 0 && !pagination.hasMore)\n ? Promise.resolve()\n : fetch(requestedQuery, nextPage, true);\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":"2FAWA,IAAM,GAAoB,EAAgB,KAAuC,CAC/E,QAAS,EAAS,EAClB,KAAM,WACN,SACA,OACF,GAEM,GAAkB,EAAwB,EAA4B,CAAC,KAAsB,CACjG,SAAU,EAAA,gBAAgB,EAAM,UAAY,EAAQ,SAAU,UAAU,EACxE,OAAQ,EAAM,QAAU,EAAQ,MAClC,GAGA,SAAgB,EAAwB,EAAoD,CAE1F,IAAI,EAAiB,EAAe,CADE,SAAU,GAAI,OAAQ,EACxB,EAAc,EAAO,YAAY,EACjE,EAAW,EACT,EAAc,EAAA,kBAAwD,CAC1E,KAAM,CAAC,EACP,MAAO,KACP,WAAY,GACZ,WAAY,EAAiB,EAAG,CAAC,EACjC,MAAO,CACT,CAAC,EAEK,GAAS,EAAsB,EAAc,IAAmC,CACpF,IAAM,EAAa,EAAY,SAAS,KAExC,OAAO,EAAY,MAAM,CACvB,KAAO,GAAW,EAAO,KAAK,CAAE,MAAO,CAAE,OAAM,SAAU,EAAM,SAAU,OAAQ,EAAM,MAAO,EAAG,QAAO,CAAC,EACzG,QAAU,IAAc,CACtB,GAAG,EACH,MAAO,KACP,WAAY,GACZ,WAAY,EAAiB,EAAS,KAAK,OAAQ,EAAS,WAAW,KAAK,EAC5E,GAAI,EAAS,CAAC,EAAI,CAAE,aAAc,CAAM,CAC1C,GACA,QACA,QAAU,GAAW,CACnB,IAAM,EAAQ,EAAA,WAAW,EAAO,KAAK,EAC/B,EAAO,EAAS,CAAC,GAAG,EAAY,GAAG,EAAO,IAAI,EAAI,EAAO,KAI/D,MAFA,GAAW,EAAO,EAEX,CACL,OACA,MAAO,KACP,WAAY,GACZ,WAAY,EAAiB,EAAK,OAAQ,CAAK,EAC/C,OACF,CACF,CACF,CAAC,CACH,EAEM,OACJ,EAAW,EAEJ,EAAM,EAAgB,EAAG,EAAK,GAcjC,EAA4B,CAChC,IAAI,gBAAiB,CACnB,OAAO,EAAY,cACrB,EAEA,QAAS,EAAY,QAErB,IAAI,UAAW,CACb,OAAO,EAAY,QACrB,EAEA,UAAW,CACT,GAAM,CAAE,aAAY,cAAe,EAAY,SAE/C,OAAO,GAAe,EAAY,SAAS,KAAK,OAAS,GAAK,CAAC,EAAW,QACtE,QAAQ,QAAQ,EAChB,EAAM,EAAgB,EAAU,EAAI,CAC1C,EAEA,SACA,cA/BsB,IAA6C,CAEnE,IAAM,EAAO,EADG,EAAY,SAAS,cAAgB,EAAY,SAAS,MACrC,CAAK,EAEtC,EAAA,UAAU,EAAM,CAAc,IAElC,EAAiB,EACjB,EAAW,EACX,MAAM,EAAM,EAAM,EAAG,EAAK,EAC5B,EAwBE,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":"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,4 +1,4 @@
1
1
  import type { InfiniteSource, InfiniteSourceConfig } from './types';
2
- /** Infinite sources preserve loaded collection state while a pending query replaces it. */
3
- export declare function createInfiniteSource<T>(config: InfiniteSourceConfig<T>): InfiniteSource<T>;
2
+ /** Infinite sources retain committed items while replacement work is pending. */
3
+ export declare function createInfiniteSource<T, TParams = undefined>(config: InfiniteSourceConfig<T, TParams>): InfiniteSource<T, TParams>;
4
4
  //# sourceMappingURL=infiniteSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"infiniteSource.d.ts","sourceRoot":"","sources":["../src/infiniteSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAIV,cAAc,EACd,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAcjB,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAgG1F"}
1
+ {"version":3,"file":"infiniteSource.d.ts","sourceRoot":"","sources":["../src/infiniteSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAsB,cAAc,EAAE,oBAAoB,EAAuB,MAAM,SAAS,CAAC;AAW7G,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EACzD,MAAM,EAAE,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,GACvC,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,CA6G5B"}
@@ -1,84 +1,2 @@
1
- import { warn as e } from "./_dev.js";
2
- import { createAsyncSource as t } from "./asyncSource.js";
3
- import { positiveInteger as n, sameQuery as r, totalItems as i } from "./pagination.js";
4
- //#region src/infiniteSource.ts
5
- var a = (e, t) => ({
6
- hasMore: e < t,
7
- kind: "infinite",
8
- loaded: e,
9
- total: t
10
- }), o = (e, t = {}) => ({
11
- pageSize: n(t.pageSize ?? e.pageSize, "pageSize"),
12
- search: t.search ?? e.search
13
- });
14
- function s(n) {
15
- let s = o({
16
- pageSize: 20,
17
- search: ""
18
- }, n.initialQuery), c = 1, l = t({
19
- data: [],
20
- error: null,
21
- isFetching: !1,
22
- pagination: a(0, 0),
23
- query: s
24
- }), u = (e, t, r) => {
25
- let o = l.snapshot.data;
26
- return l.fetch({
27
- load: (r) => n.load({
28
- query: {
29
- page: t,
30
- pageSize: e.pageSize,
31
- search: e.search
32
- },
33
- signal: r
34
- }),
35
- pending: (t) => ({
36
- ...t,
37
- error: null,
38
- isFetching: !0,
39
- pagination: a(t.data.length, t.pagination.total),
40
- ...r ? {} : { pendingQuery: e }
41
- }),
42
- query: e,
43
- success: (n) => {
44
- let s = i(n.total), l = r ? [...o, ...n.data] : n.data;
45
- return c = t + 1, {
46
- data: l,
47
- error: null,
48
- isFetching: !1,
49
- pagination: a(l.length, s),
50
- query: e
51
- };
52
- }
53
- });
54
- }, d = () => (c = 1, u(s, 1, !1)), f = {
55
- get disposalSignal() {
56
- return l.disposalSignal;
57
- },
58
- dispose: l.dispose,
59
- get disposed() {
60
- return l.disposed;
61
- },
62
- loadMore() {
63
- let { isFetching: e, pagination: t } = l.snapshot;
64
- return e || l.snapshot.data.length > 0 && !t.hasMore ? Promise.resolve() : u(s, c, !0);
65
- },
66
- reload: d,
67
- setQuery: async (e) => {
68
- let t = o(l.snapshot.pendingQuery ?? l.snapshot.query, e);
69
- r(t, s) || (s = t, c = 1, await u(t, 1, !1));
70
- },
71
- get snapshot() {
72
- return l.snapshot;
73
- },
74
- subscribe: l.subscribe,
75
- [Symbol.dispose]() {
76
- f.dispose();
77
- }
78
- };
79
- return n.autoStart !== !1 && d().catch(() => /* @__PURE__ */ e("Initial load failed. Inspect source.snapshot.error.")), f;
80
- }
81
- //#endregion
82
- export { s as createInfiniteSource };
83
-
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};
84
2
  //# sourceMappingURL=infiniteSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"infiniteSource.js","names":[],"sources":["../src/infiniteSource.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { createAsyncSource } from './asyncSource';\nimport { positiveInteger, sameQuery, totalItems } from './pagination';\nimport type {\n InfinitePagination,\n InfiniteQuery,\n InfiniteQueryPatch,\n InfiniteSource,\n InfiniteSourceConfig,\n} from './types';\n\nconst createPagination = (loaded: number, total: number): InfinitePagination => ({\n hasMore: loaded < total,\n kind: 'infinite',\n loaded,\n total,\n});\n\nconst normalizeQuery = (current: InfiniteQuery, patch: InfiniteQueryPatch = {}): InfiniteQuery => ({\n pageSize: positiveInteger(patch.pageSize ?? current.pageSize, 'pageSize'),\n search: patch.search ?? current.search,\n});\n\n/** Infinite sources preserve loaded collection state while a pending query replaces it. */\nexport function createInfiniteSource<T>(config: InfiniteSourceConfig<T>): InfiniteSource<T> {\n const initialQuery: InfiniteQuery = { pageSize: 20, search: '' };\n let requestedQuery = normalizeQuery(initialQuery, config.initialQuery);\n let nextPage = 1;\n const asyncSource = createAsyncSource<T, InfiniteQuery, InfinitePagination>({\n data: [],\n error: null,\n isFetching: false,\n pagination: createPagination(0, 0),\n query: requestedQuery,\n });\n\n const fetch = (query: InfiniteQuery, page: number, append: boolean): Promise<void> => {\n const loadedData = asyncSource.snapshot.data;\n\n return asyncSource.fetch({\n load: (signal) => config.load({ query: { page, pageSize: query.pageSize, search: query.search }, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n isFetching: true,\n pagination: createPagination(previous.data.length, previous.pagination.total),\n ...(append ? {} : { pendingQuery: query }),\n }),\n query,\n success: (result) => {\n const total = totalItems(result.total);\n const data = append ? [...loadedData, ...result.data] : result.data;\n\n nextPage = page + 1;\n\n return {\n data,\n error: null,\n isFetching: false,\n pagination: createPagination(data.length, total),\n query,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => {\n nextPage = 1;\n\n return fetch(requestedQuery, 1, false);\n };\n\n const setQuery = async (patch: InfiniteQueryPatch): 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 nextPage = 1;\n await fetch(next, 1, false);\n };\n\n const source: InfiniteSource<T> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n loadMore() {\n const { isFetching, pagination } = asyncSource.snapshot;\n\n return isFetching || (asyncSource.snapshot.data.length > 0 && !pagination.hasMore)\n ? Promise.resolve()\n : fetch(requestedQuery, nextPage, true);\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":";;;;AAWA,IAAM,KAAoB,GAAgB,OAAuC;CAC/E,SAAS,IAAS;CAClB,MAAM;CACN;CACA;AACF,IAEM,KAAkB,GAAwB,IAA4B,CAAC,OAAsB;CACjG,UAAU,EAAgB,EAAM,YAAY,EAAQ,UAAU,UAAU;CACxE,QAAQ,EAAM,UAAU,EAAQ;AAClC;AAGA,SAAgB,EAAwB,GAAoD;CAE1F,IAAI,IAAiB,EAAe;EADE,UAAU;EAAI,QAAQ;CACxB,GAAc,EAAO,YAAY,GACjE,IAAW,GACT,IAAc,EAAwD;EAC1E,MAAM,CAAC;EACP,OAAO;EACP,YAAY;EACZ,YAAY,EAAiB,GAAG,CAAC;EACjC,OAAO;CACT,CAAC,GAEK,KAAS,GAAsB,GAAc,MAAmC;EACpF,IAAM,IAAa,EAAY,SAAS;EAExC,OAAO,EAAY,MAAM;GACvB,OAAO,MAAW,EAAO,KAAK;IAAE,OAAO;KAAE;KAAM,UAAU,EAAM;KAAU,QAAQ,EAAM;IAAO;IAAG;GAAO,CAAC;GACzG,UAAU,OAAc;IACtB,GAAG;IACH,OAAO;IACP,YAAY;IACZ,YAAY,EAAiB,EAAS,KAAK,QAAQ,EAAS,WAAW,KAAK;IAC5E,GAAI,IAAS,CAAC,IAAI,EAAE,cAAc,EAAM;GAC1C;GACA;GACA,UAAU,MAAW;IACnB,IAAM,IAAQ,EAAW,EAAO,KAAK,GAC/B,IAAO,IAAS,CAAC,GAAG,GAAY,GAAG,EAAO,IAAI,IAAI,EAAO;IAI/D,OAFA,IAAW,IAAO,GAEX;KACL;KACA,OAAO;KACP,YAAY;KACZ,YAAY,EAAiB,EAAK,QAAQ,CAAK;KAC/C;IACF;GACF;EACF,CAAC;CACH,GAEM,WACJ,IAAW,GAEJ,EAAM,GAAgB,GAAG,EAAK,IAcjC,IAA4B;EAChC,IAAI,iBAAiB;GACnB,OAAO,EAAY;EACrB;EAEA,SAAS,EAAY;EAErB,IAAI,WAAW;GACb,OAAO,EAAY;EACrB;EAEA,WAAW;GACT,IAAM,EAAE,eAAY,kBAAe,EAAY;GAE/C,OAAO,KAAe,EAAY,SAAS,KAAK,SAAS,KAAK,CAAC,EAAW,UACtE,QAAQ,QAAQ,IAChB,EAAM,GAAgB,GAAU,EAAI;EAC1C;EAEA;EACA,iBA/BsB,MAA6C;GAEnE,IAAM,IAAO,EADG,EAAY,SAAS,gBAAgB,EAAY,SAAS,OACrC,CAAK;GAEtC,EAAU,GAAM,CAAc,MAElC,IAAiB,GACjB,IAAW,GACX,MAAM,EAAM,GAAM,GAAG,EAAK;EAC5B;EAwBE,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":"infiniteSource.js","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":"4KAOA,IAAM,kBAAoB,EAAqB,EAAkB,KAAuC,CACtG,QAAS,EAAc,EACvB,cACA,WACA,WAAY,CACd,GAGA,SAAgB,qBACd,EAC4B,CAC5B,IAAI,EAA8B,CAChC,SAAU,EAAgB,EAAO,UAAY,GAAI,UAAU,EAC3D,OAAQ,EAAO,MACjB,EACI,EAAW,EACX,EAAY,GACV,EAAc,EAAmD,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,CACtC,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,EAAW,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,EAAgB,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,2 +1,2 @@
1
- const e=require("./sourceStore.cjs"),t=require("./pagination.cjs");var n=(e,n={},r)=>{let i=n.page??e.page,a=n.pageSize??e.pageSize,o=n.search??e.search,s=n.pageSize!==void 0||n.search!==void 0,c=n.page??(s?1:i);return{page:r===void 0?t.positiveInteger(c,`page`):Math.min(t.positiveInteger(c,`page`),r),pageSize:t.positiveInteger(a,`pageSize`),search:o}};function r(r,i={}){let a=r,o=n({page:1,pageSize:20,search:``},i.initialQuery),s=()=>{let e=o.search.length>0&&i.match?a.filter(e=>i.match?.(e,o.search)):a,n=t.totalItems(e.length),r=t.createPagePagination(o.page,o.pageSize,n),s=(r.index-1)*r.size;return o={...o,page:r.index},{data:e.slice(s,s+r.size),error:null,isFetching:!1,pagination:r,query:o}},c=e.createSourceStore(s()),l=()=>{let e=s();return t.sameQuery(e.query,c.value.query)&&e.data===c.value.data&&e.pagination===c.value.pagination?!1:(c.set(e),!0)},u=e=>{let r=n(o,e,c.value.pagination.count);t.sameQuery(r,o)||(o=r,l())},d={get disposalSignal(){return c.disposalSignal},dispose:c.dispose,get disposed(){return c.disposed},page:{go(e){u({page:e})},last(){u({page:c.value.pagination.count})},next(){c.value.pagination.hasNext&&u({page:c.value.pagination.index+1})},previous(){c.value.pagination.hasPrevious&&u({page:c.value.pagination.index-1})}},setData(e){e!==a&&(a=e,l())},setQuery:u,get snapshot(){return c.value},subscribe:c.subscribe,[Symbol.dispose](){d.dispose()}};return d}exports.createLocalSource=r;
1
+ const e=require("./errors.cjs"),t=require("./sourceStore.cjs"),n=require("./pagination.cjs");function createLocalSource(r,i={}){let a=r,o=1,s=n.positiveInteger(i.pageSize??20,`pageSize`),c=i.params,buildState=()=>{let e=i.filter?a.filter(e=>i.filter?.(e,c)):a,t=n.createPagePagination(o,s,e.length);if(o>t.pageCount)return o=t.pageCount,buildState();let r=(o-1)*s;return{error:null,items:e.slice(r,r+s),loading:!1,pagination:t,params:c}},l=t.createSourceStore(buildState()),assertLive=()=>{if(l.disposed)throw new e.SourcererDisposedError},samePagination=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),commit=()=>{let e=buildState(),t=l.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&samePagination(e.pagination,t.pagination)||l.set(e)},goTo=e=>{assertLive();let t=Math.min(n.positiveInteger(e,`page`),l.value.pagination.pageCount);t!==o&&(o=t,commit())},u={get disposalSignal(){return l.disposalSignal},dispose:l.dispose,get disposed(){return l.disposed},first(){goTo(1)},goTo,last(){goTo(l.value.pagination.pageCount)},next(){l.value.pagination.hasNext?goTo(o+1):assertLive()},previous(){l.value.pagination.hasPrevious?goTo(o-1):assertLive()},setItems(e){assertLive(),e!==a&&(a=e,commit())},setPageSize(e){assertLive();let t=n.positiveInteger(e,`pageSize`);t!==s&&(o=1,s=t,commit())},setParams(e){assertLive(),!Object.is(e,c)&&(o=1,c=e,commit())},get state(){return l.value},subscribe:l.subscribe,[Symbol.dispose](){u.dispose()}};return u}exports.createLocalSource=createLocalSource;
2
2
  //# sourceMappingURL=localSource.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"localSource.cjs","names":[],"sources":["../src/localSource.ts"],"sourcesContent":["import { createPagePagination, positiveInteger, sameQuery, totalItems } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type {\n LocalQuery,\n LocalQueryPatch,\n LocalSource,\n LocalSourceConfig,\n PagePagination,\n SourceSnapshot,\n} from './types';\n\nconst normalizeQuery = (current: LocalQuery, patch: LocalQueryPatch = {}, maxPage?: number): LocalQuery => {\n const page = patch.page ?? current.page;\n const pageSize = patch.pageSize ?? current.pageSize;\n const search = patch.search ?? current.search;\n const resetsPage = patch.pageSize !== undefined || patch.search !== undefined;\n\n const requestedPage = patch.page ?? (resetsPage ? 1 : page);\n\n return {\n page:\n maxPage === undefined\n ? positiveInteger(requestedPage, 'page')\n : Math.min(positiveInteger(requestedPage, 'page'), maxPage),\n pageSize: positiveInteger(pageSize, 'pageSize'),\n search,\n };\n};\n\n/** Local sources own only search and pagination; callers prepare filtering and ranking. */\nexport function createLocalSource<T>(data: readonly T[], config: LocalSourceConfig<T> = {}): LocalSource<T> {\n let allData = data;\n let query = normalizeQuery({ page: 1, pageSize: 20, search: '' }, config.initialQuery);\n\n const buildSnapshot = (): SourceSnapshot<T, LocalQuery, PagePagination> => {\n const matched =\n query.search.length > 0 && config.match ? allData.filter((item) => config.match?.(item, query.search)) : allData;\n const total = totalItems(matched.length);\n const pagination = createPagePagination(query.page, query.pageSize, total);\n const start = (pagination.index - 1) * pagination.size;\n\n query = { ...query, page: pagination.index };\n\n return {\n data: matched.slice(start, start + pagination.size),\n error: null,\n isFetching: false,\n pagination,\n query,\n };\n };\n\n const store = createSourceStore(buildSnapshot());\n\n const commit = (): boolean => {\n const next = buildSnapshot();\n\n if (\n sameQuery(next.query, store.value.query) &&\n next.data === store.value.data &&\n next.pagination === store.value.pagination\n ) {\n return false;\n }\n\n store.set(next);\n\n return true;\n };\n\n const setQuery = (patch: LocalQueryPatch): void => {\n const next = normalizeQuery(query, patch, store.value.pagination.count);\n\n if (sameQuery(next, query)) return;\n\n query = next;\n\n commit();\n };\n\n const source: LocalSource<T> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n page: {\n go(index) {\n setQuery({ page: index });\n },\n\n last() {\n setQuery({ page: store.value.pagination.count });\n },\n\n next() {\n if (store.value.pagination.hasNext) setQuery({ page: store.value.pagination.index + 1 });\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) setQuery({ page: store.value.pagination.index - 1 });\n },\n },\n\n setData(nextData) {\n if (nextData === allData) return;\n\n allData = nextData;\n\n commit();\n },\n\n setQuery,\n\n get snapshot() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"mEAWA,IAAM,GAAkB,EAAqB,EAAyB,CAAC,EAAG,IAAiC,CACzG,IAAM,EAAO,EAAM,MAAQ,EAAQ,KAC7B,EAAW,EAAM,UAAY,EAAQ,SACrC,EAAS,EAAM,QAAU,EAAQ,OACjC,EAAa,EAAM,WAAa,IAAA,IAAa,EAAM,SAAW,IAAA,GAE9D,EAAgB,EAAM,OAAS,EAAa,EAAI,GAEtD,MAAO,CACL,KACE,IAAY,IAAA,GACR,EAAA,gBAAgB,EAAe,MAAM,EACrC,KAAK,IAAI,EAAA,gBAAgB,EAAe,MAAM,EAAG,CAAO,EAC9D,SAAU,EAAA,gBAAgB,EAAU,UAAU,EAC9C,QACF,CACF,EAGA,SAAgB,EAAqB,EAAoB,EAA+B,CAAC,EAAmB,CAC1G,IAAI,EAAU,EACV,EAAQ,EAAe,CAAE,KAAM,EAAG,SAAU,GAAI,OAAQ,EAAG,EAAG,EAAO,YAAY,EAE/E,MAAqE,CACzE,IAAM,EACJ,EAAM,OAAO,OAAS,GAAK,EAAO,MAAQ,EAAQ,OAAQ,GAAS,EAAO,QAAQ,EAAM,EAAM,MAAM,CAAC,EAAI,EACrG,EAAQ,EAAA,WAAW,EAAQ,MAAM,EACjC,EAAa,EAAA,qBAAqB,EAAM,KAAM,EAAM,SAAU,CAAK,EACnE,GAAS,EAAW,MAAQ,GAAK,EAAW,KAIlD,MAFA,GAAQ,CAAE,GAAG,EAAO,KAAM,EAAW,KAAM,EAEpC,CACL,KAAM,EAAQ,MAAM,EAAO,EAAQ,EAAW,IAAI,EAClD,MAAO,KACP,WAAY,GACZ,aACA,OACF,CACF,EAEM,EAAQ,EAAA,kBAAkB,EAAc,CAAC,EAEzC,MAAwB,CAC5B,IAAM,EAAO,EAAc,EAY3B,OATE,EAAA,UAAU,EAAK,MAAO,EAAM,MAAM,KAAK,GACvC,EAAK,OAAS,EAAM,MAAM,MAC1B,EAAK,aAAe,EAAM,MAAM,WAEzB,IAGT,EAAM,IAAI,CAAI,EAEP,GACT,EAEM,EAAY,GAAiC,CACjD,IAAM,EAAO,EAAe,EAAO,EAAO,EAAM,MAAM,WAAW,KAAK,EAElE,EAAA,UAAU,EAAM,CAAK,IAEzB,EAAQ,EAER,EAAO,EACT,EAEM,EAAyB,CAC7B,IAAI,gBAAiB,CACnB,OAAO,EAAM,cACf,EAEA,QAAS,EAAM,QAEf,IAAI,UAAW,CACb,OAAO,EAAM,QACf,EAEA,KAAM,CACJ,GAAG,EAAO,CACR,EAAS,CAAE,KAAM,CAAM,CAAC,CAC1B,EAEA,MAAO,CACL,EAAS,CAAE,KAAM,EAAM,MAAM,WAAW,KAAM,CAAC,CACjD,EAEA,MAAO,CACD,EAAM,MAAM,WAAW,SAAS,EAAS,CAAE,KAAM,EAAM,MAAM,WAAW,MAAQ,CAAE,CAAC,CACzF,EAEA,UAAW,CACL,EAAM,MAAM,WAAW,aAAa,EAAS,CAAE,KAAM,EAAM,MAAM,WAAW,MAAQ,CAAE,CAAC,CAC7F,CACF,EAEA,QAAQ,EAAU,CACZ,IAAa,IAEjB,EAAU,EAEV,EAAO,EACT,EAEA,WAEA,IAAI,UAAW,CACb,OAAO,EAAM,KACf,EAEA,UAAW,EAAM,UAEjB,CAAC,OAAO,UAAW,CACjB,EAAO,QAAQ,CACjB,CACF,EAEA,OAAO,CACT"}
1
+ {"version":3,"file":"localSource.cjs","names":[],"sources":["../src/localSource.ts"],"sourcesContent":["import { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type { LocalSource, LocalSourceConfig, LocalSourceState, PagePagination } from './types';\n\n/** Local sources filter and paginate an in-memory collection synchronously. */\nexport function createLocalSource<T>(items: readonly T[]): LocalSource<T>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams> = {} as LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams> {\n let allItems = items;\n let page = 1;\n let pageSize = positiveInteger(config.pageSize ?? 20, 'pageSize');\n let params = config.params as TParams;\n\n const buildState = (): LocalSourceState<T, TParams> => {\n const filtered = config.filter ? allItems.filter((item) => config.filter?.(item, params)) : allItems;\n const pagination = createPagePagination(page, pageSize, filtered.length);\n if (page > pagination.pageCount) {\n page = pagination.pageCount;\n return buildState();\n }\n const start = (page - 1) * pageSize;\n\n return {\n error: null,\n items: filtered.slice(start, start + pageSize),\n loading: false,\n pagination,\n params,\n };\n };\n\n const store = createSourceStore(buildState());\n const assertLive = (): void => {\n if (store.disposed) throw new SourcererDisposedError();\n };\n const samePagination = (left: PagePagination, right: PagePagination): boolean =>\n Object.keys(left).every((key) => left[key as keyof PagePagination] === right[key as keyof PagePagination]);\n const commit = (): void => {\n const next = buildState();\n const current = store.value;\n const sameItems =\n next.items.length === current.items.length &&\n next.items.every((item, index) => Object.is(item, current.items[index]));\n\n if (Object.is(next.params, current.params) && sameItems && samePagination(next.pagination, current.pagination))\n return;\n store.set(next);\n };\n const goTo = (nextPage: number): void => {\n assertLive();\n const normalized = Math.min(positiveInteger(nextPage, 'page'), store.value.pagination.pageCount);\n if (normalized === page) return;\n page = normalized;\n commit();\n };\n\n const source: LocalSource<T, TParams> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n first() {\n goTo(1);\n },\n\n goTo,\n\n last() {\n goTo(store.value.pagination.pageCount);\n },\n\n next() {\n if (store.value.pagination.hasNext) goTo(page + 1);\n else assertLive();\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) goTo(page - 1);\n else assertLive();\n },\n\n setItems(nextItems) {\n assertLive();\n if (nextItems === allItems) return;\n allItems = nextItems;\n commit();\n },\n\n setPageSize(nextPageSize) {\n assertLive();\n const normalized = positiveInteger(nextPageSize, 'pageSize');\n if (normalized === pageSize) return;\n page = 1;\n pageSize = normalized;\n commit();\n },\n\n setParams(nextParams) {\n assertLive();\n if (Object.is(nextParams, params)) return;\n page = 1;\n params = nextParams;\n commit();\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"6FAWA,SAAgB,kBACd,EACA,EAAwC,CAAC,EAChB,CACzB,IAAI,EAAW,EACX,EAAO,EACP,EAAW,EAAA,gBAAgB,EAAO,UAAY,GAAI,UAAU,EAC5D,EAAS,EAAO,OAEd,eAAiD,CACrD,IAAM,EAAW,EAAO,OAAS,EAAS,OAAQ,GAAS,EAAO,SAAS,EAAM,CAAM,CAAC,EAAI,EACtF,EAAa,EAAA,qBAAqB,EAAM,EAAU,EAAS,MAAM,EACvE,GAAI,EAAO,EAAW,UAEpB,MADA,GAAO,EAAW,UACX,WAAW,EAEpB,IAAM,GAAS,EAAO,GAAK,EAE3B,MAAO,CACL,MAAO,KACP,MAAO,EAAS,MAAM,EAAO,EAAQ,CAAQ,EAC7C,QAAS,GACT,aACA,QACF,CACF,EAEM,EAAQ,EAAA,kBAAkB,WAAW,CAAC,EACtC,eAAyB,CAC7B,GAAI,EAAM,SAAU,MAAM,IAAI,EAAA,sBAChC,EACM,gBAAkB,EAAsB,IAC5C,OAAO,KAAK,CAAI,CAAC,CAAC,MAAO,GAAQ,EAAK,KAAiC,EAAM,EAA4B,EACrG,WAAqB,CACzB,IAAM,EAAO,WAAW,EAClB,EAAU,EAAM,MAChB,EACJ,EAAK,MAAM,SAAW,EAAQ,MAAM,QACpC,EAAK,MAAM,OAAO,EAAM,IAAU,OAAO,GAAG,EAAM,EAAQ,MAAM,EAAM,CAAC,EAErE,OAAO,GAAG,EAAK,OAAQ,EAAQ,MAAM,GAAK,GAAa,eAAe,EAAK,WAAY,EAAQ,UAAU,GAE7G,EAAM,IAAI,CAAI,CAChB,EACM,KAAQ,GAA2B,CACvC,WAAW,EACX,IAAM,EAAa,KAAK,IAAI,EAAA,gBAAgB,EAAU,MAAM,EAAG,EAAM,MAAM,WAAW,SAAS,EAC3F,IAAe,IACnB,EAAO,EACP,OAAO,EACT,EAEM,EAAkC,CACtC,IAAI,gBAAiB,CACnB,OAAO,EAAM,cACf,EAEA,QAAS,EAAM,QAEf,IAAI,UAAW,CACb,OAAO,EAAM,QACf,EAEA,OAAQ,CACN,KAAK,CAAC,CACR,EAEA,KAEA,MAAO,CACL,KAAK,EAAM,MAAM,WAAW,SAAS,CACvC,EAEA,MAAO,CACD,EAAM,MAAM,WAAW,QAAS,KAAK,EAAO,CAAC,EAC5C,WAAW,CAClB,EAEA,UAAW,CACL,EAAM,MAAM,WAAW,YAAa,KAAK,EAAO,CAAC,EAChD,WAAW,CAClB,EAEA,SAAS,EAAW,CAClB,WAAW,EACP,IAAc,IAClB,EAAW,EACX,OAAO,EACT,EAEA,YAAY,EAAc,CACxB,WAAW,EACX,IAAM,EAAa,EAAA,gBAAgB,EAAc,UAAU,EACvD,IAAe,IACnB,EAAO,EACP,EAAW,EACX,OAAO,EACT,EAEA,UAAU,EAAY,CACpB,WAAW,EACP,QAAO,GAAG,EAAY,CAAM,IAChC,EAAO,EACP,EAAS,EACT,OAAO,EACT,EAEA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,EAEA,UAAW,EAAM,UAEjB,CAAC,OAAO,UAAW,CACjB,EAAO,QAAQ,CACjB,CACF,EAEA,OAAO,CACT"}
@@ -1,4 +1,5 @@
1
1
  import type { LocalSource, LocalSourceConfig } from './types';
2
- /** Local sources own only search and pagination; callers prepare filtering and ranking. */
3
- export declare function createLocalSource<T>(data: readonly T[], config?: LocalSourceConfig<T>): LocalSource<T>;
2
+ /** Local sources filter and paginate an in-memory collection synchronously. */
3
+ export declare function createLocalSource<T>(items: readonly T[]): LocalSource<T>;
4
+ export declare function createLocalSource<T, TParams = undefined>(items: readonly T[], config: LocalSourceConfig<T, TParams>): LocalSource<T, TParams>;
4
5
  //# sourceMappingURL=localSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"localSource.d.ts","sourceRoot":"","sources":["../src/localSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,WAAW,EACX,iBAAiB,EAGlB,MAAM,SAAS,CAAC;AAoBjB,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,GAAE,iBAAiB,CAAC,CAAC,CAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAqG1G"}
1
+ {"version":3,"file":"localSource.d.ts","sourceRoot":"","sources":["../src/localSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAoC,MAAM,SAAS,CAAC;AAEhG,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1E,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EACtD,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,GACpC,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC"}
@@ -1,74 +1,2 @@
1
- import { createSourceStore as e } from "./sourceStore.js";
2
- import { createPagePagination as t, positiveInteger as n, sameQuery as r, totalItems as i } from "./pagination.js";
3
- //#region src/localSource.ts
4
- var a = (e, t = {}, r) => {
5
- let i = t.page ?? e.page, a = t.pageSize ?? e.pageSize, o = t.search ?? e.search, s = t.pageSize !== void 0 || t.search !== void 0, c = t.page ?? (s ? 1 : i);
6
- return {
7
- page: r === void 0 ? n(c, "page") : Math.min(n(c, "page"), r),
8
- pageSize: n(a, "pageSize"),
9
- search: o
10
- };
11
- };
12
- function o(n, o = {}) {
13
- let s = n, c = a({
14
- page: 1,
15
- pageSize: 20,
16
- search: ""
17
- }, o.initialQuery), l = () => {
18
- let e = c.search.length > 0 && o.match ? s.filter((e) => o.match?.(e, c.search)) : s, n = i(e.length), r = t(c.page, c.pageSize, n), a = (r.index - 1) * r.size;
19
- return c = {
20
- ...c,
21
- page: r.index
22
- }, {
23
- data: e.slice(a, a + r.size),
24
- error: null,
25
- isFetching: !1,
26
- pagination: r,
27
- query: c
28
- };
29
- }, u = e(l()), d = () => {
30
- let e = l();
31
- return r(e.query, u.value.query) && e.data === u.value.data && e.pagination === u.value.pagination ? !1 : (u.set(e), !0);
32
- }, f = (e) => {
33
- let t = a(c, e, u.value.pagination.count);
34
- r(t, c) || (c = t, d());
35
- }, p = {
36
- get disposalSignal() {
37
- return u.disposalSignal;
38
- },
39
- dispose: u.dispose,
40
- get disposed() {
41
- return u.disposed;
42
- },
43
- page: {
44
- go(e) {
45
- f({ page: e });
46
- },
47
- last() {
48
- f({ page: u.value.pagination.count });
49
- },
50
- next() {
51
- u.value.pagination.hasNext && f({ page: u.value.pagination.index + 1 });
52
- },
53
- previous() {
54
- u.value.pagination.hasPrevious && f({ page: u.value.pagination.index - 1 });
55
- }
56
- },
57
- setData(e) {
58
- e !== s && (s = e, d());
59
- },
60
- setQuery: f,
61
- get snapshot() {
62
- return u.value;
63
- },
64
- subscribe: u.subscribe,
65
- [Symbol.dispose]() {
66
- p.dispose();
67
- }
68
- };
69
- return p;
70
- }
71
- //#endregion
72
- export { o as createLocalSource };
73
-
1
+ import{SourcererDisposedError as e}from"./errors.js";import{createSourceStore as t}from"./sourceStore.js";import{createPagePagination as n,positiveInteger as r}from"./pagination.js";function createLocalSource(i,a={}){let o=i,s=1,c=r(a.pageSize??20,`pageSize`),l=a.params,buildState=()=>{let e=a.filter?o.filter(e=>a.filter?.(e,l)):o,t=n(s,c,e.length);if(s>t.pageCount)return s=t.pageCount,buildState();let r=(s-1)*c;return{error:null,items:e.slice(r,r+c),loading:!1,pagination:t,params:l}},u=t(buildState()),assertLive=()=>{if(u.disposed)throw new e},samePagination=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),commit=()=>{let e=buildState(),t=u.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&samePagination(e.pagination,t.pagination)||u.set(e)},goTo=e=>{assertLive();let t=Math.min(r(e,`page`),u.value.pagination.pageCount);t!==s&&(s=t,commit())},d={get disposalSignal(){return u.disposalSignal},dispose:u.dispose,get disposed(){return u.disposed},first(){goTo(1)},goTo,last(){goTo(u.value.pagination.pageCount)},next(){u.value.pagination.hasNext?goTo(s+1):assertLive()},previous(){u.value.pagination.hasPrevious?goTo(s-1):assertLive()},setItems(e){assertLive(),e!==o&&(o=e,commit())},setPageSize(e){assertLive();let t=r(e,`pageSize`);t!==c&&(s=1,c=t,commit())},setParams(e){assertLive(),!Object.is(e,l)&&(s=1,l=e,commit())},get state(){return u.value},subscribe:u.subscribe,[Symbol.dispose](){d.dispose()}};return d}export{createLocalSource};
74
2
  //# sourceMappingURL=localSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"localSource.js","names":[],"sources":["../src/localSource.ts"],"sourcesContent":["import { createPagePagination, positiveInteger, sameQuery, totalItems } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type {\n LocalQuery,\n LocalQueryPatch,\n LocalSource,\n LocalSourceConfig,\n PagePagination,\n SourceSnapshot,\n} from './types';\n\nconst normalizeQuery = (current: LocalQuery, patch: LocalQueryPatch = {}, maxPage?: number): LocalQuery => {\n const page = patch.page ?? current.page;\n const pageSize = patch.pageSize ?? current.pageSize;\n const search = patch.search ?? current.search;\n const resetsPage = patch.pageSize !== undefined || patch.search !== undefined;\n\n const requestedPage = patch.page ?? (resetsPage ? 1 : page);\n\n return {\n page:\n maxPage === undefined\n ? positiveInteger(requestedPage, 'page')\n : Math.min(positiveInteger(requestedPage, 'page'), maxPage),\n pageSize: positiveInteger(pageSize, 'pageSize'),\n search,\n };\n};\n\n/** Local sources own only search and pagination; callers prepare filtering and ranking. */\nexport function createLocalSource<T>(data: readonly T[], config: LocalSourceConfig<T> = {}): LocalSource<T> {\n let allData = data;\n let query = normalizeQuery({ page: 1, pageSize: 20, search: '' }, config.initialQuery);\n\n const buildSnapshot = (): SourceSnapshot<T, LocalQuery, PagePagination> => {\n const matched =\n query.search.length > 0 && config.match ? allData.filter((item) => config.match?.(item, query.search)) : allData;\n const total = totalItems(matched.length);\n const pagination = createPagePagination(query.page, query.pageSize, total);\n const start = (pagination.index - 1) * pagination.size;\n\n query = { ...query, page: pagination.index };\n\n return {\n data: matched.slice(start, start + pagination.size),\n error: null,\n isFetching: false,\n pagination,\n query,\n };\n };\n\n const store = createSourceStore(buildSnapshot());\n\n const commit = (): boolean => {\n const next = buildSnapshot();\n\n if (\n sameQuery(next.query, store.value.query) &&\n next.data === store.value.data &&\n next.pagination === store.value.pagination\n ) {\n return false;\n }\n\n store.set(next);\n\n return true;\n };\n\n const setQuery = (patch: LocalQueryPatch): void => {\n const next = normalizeQuery(query, patch, store.value.pagination.count);\n\n if (sameQuery(next, query)) return;\n\n query = next;\n\n commit();\n };\n\n const source: LocalSource<T> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n page: {\n go(index) {\n setQuery({ page: index });\n },\n\n last() {\n setQuery({ page: store.value.pagination.count });\n },\n\n next() {\n if (store.value.pagination.hasNext) setQuery({ page: store.value.pagination.index + 1 });\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) setQuery({ page: store.value.pagination.index - 1 });\n },\n },\n\n setData(nextData) {\n if (nextData === allData) return;\n\n allData = nextData;\n\n commit();\n },\n\n setQuery,\n\n get snapshot() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":";;;AAWA,IAAM,KAAkB,GAAqB,IAAyB,CAAC,GAAG,MAAiC;CACzG,IAAM,IAAO,EAAM,QAAQ,EAAQ,MAC7B,IAAW,EAAM,YAAY,EAAQ,UACrC,IAAS,EAAM,UAAU,EAAQ,QACjC,IAAa,EAAM,aAAa,KAAA,KAAa,EAAM,WAAW,KAAA,GAE9D,IAAgB,EAAM,SAAS,IAAa,IAAI;CAEtD,OAAO;EACL,MACE,MAAY,KAAA,IACR,EAAgB,GAAe,MAAM,IACrC,KAAK,IAAI,EAAgB,GAAe,MAAM,GAAG,CAAO;EAC9D,UAAU,EAAgB,GAAU,UAAU;EAC9C;CACF;AACF;AAGA,SAAgB,EAAqB,GAAoB,IAA+B,CAAC,GAAmB;CAC1G,IAAI,IAAU,GACV,IAAQ,EAAe;EAAE,MAAM;EAAG,UAAU;EAAI,QAAQ;CAAG,GAAG,EAAO,YAAY,GAE/E,UAAqE;EACzE,IAAM,IACJ,EAAM,OAAO,SAAS,KAAK,EAAO,QAAQ,EAAQ,QAAQ,MAAS,EAAO,QAAQ,GAAM,EAAM,MAAM,CAAC,IAAI,GACrG,IAAQ,EAAW,EAAQ,MAAM,GACjC,IAAa,EAAqB,EAAM,MAAM,EAAM,UAAU,CAAK,GACnE,KAAS,EAAW,QAAQ,KAAK,EAAW;EAIlD,OAFA,IAAQ;GAAE,GAAG;GAAO,MAAM,EAAW;EAAM,GAEpC;GACL,MAAM,EAAQ,MAAM,GAAO,IAAQ,EAAW,IAAI;GAClD,OAAO;GACP,YAAY;GACZ;GACA;EACF;CACF,GAEM,IAAQ,EAAkB,EAAc,CAAC,GAEzC,UAAwB;EAC5B,IAAM,IAAO,EAAc;EAY3B,OATE,EAAU,EAAK,OAAO,EAAM,MAAM,KAAK,KACvC,EAAK,SAAS,EAAM,MAAM,QAC1B,EAAK,eAAe,EAAM,MAAM,aAEzB,MAGT,EAAM,IAAI,CAAI,GAEP;CACT,GAEM,KAAY,MAAiC;EACjD,IAAM,IAAO,EAAe,GAAO,GAAO,EAAM,MAAM,WAAW,KAAK;EAElE,EAAU,GAAM,CAAK,MAEzB,IAAQ,GAER,EAAO;CACT,GAEM,IAAyB;EAC7B,IAAI,iBAAiB;GACnB,OAAO,EAAM;EACf;EAEA,SAAS,EAAM;EAEf,IAAI,WAAW;GACb,OAAO,EAAM;EACf;EAEA,MAAM;GACJ,GAAG,GAAO;IACR,EAAS,EAAE,MAAM,EAAM,CAAC;GAC1B;GAEA,OAAO;IACL,EAAS,EAAE,MAAM,EAAM,MAAM,WAAW,MAAM,CAAC;GACjD;GAEA,OAAO;IACL,AAAI,EAAM,MAAM,WAAW,WAAS,EAAS,EAAE,MAAM,EAAM,MAAM,WAAW,QAAQ,EAAE,CAAC;GACzF;GAEA,WAAW;IACT,AAAI,EAAM,MAAM,WAAW,eAAa,EAAS,EAAE,MAAM,EAAM,MAAM,WAAW,QAAQ,EAAE,CAAC;GAC7F;EACF;EAEA,QAAQ,GAAU;GACZ,MAAa,MAEjB,IAAU,GAEV,EAAO;EACT;EAEA;EAEA,IAAI,WAAW;GACb,OAAO,EAAM;EACf;EAEA,WAAW,EAAM;EAEjB,CAAC,OAAO,WAAW;GACjB,EAAO,QAAQ;EACjB;CACF;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"localSource.js","names":[],"sources":["../src/localSource.ts"],"sourcesContent":["import { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type { LocalSource, LocalSourceConfig, LocalSourceState, PagePagination } from './types';\n\n/** Local sources filter and paginate an in-memory collection synchronously. */\nexport function createLocalSource<T>(items: readonly T[]): LocalSource<T>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams> = {} as LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams> {\n let allItems = items;\n let page = 1;\n let pageSize = positiveInteger(config.pageSize ?? 20, 'pageSize');\n let params = config.params as TParams;\n\n const buildState = (): LocalSourceState<T, TParams> => {\n const filtered = config.filter ? allItems.filter((item) => config.filter?.(item, params)) : allItems;\n const pagination = createPagePagination(page, pageSize, filtered.length);\n if (page > pagination.pageCount) {\n page = pagination.pageCount;\n return buildState();\n }\n const start = (page - 1) * pageSize;\n\n return {\n error: null,\n items: filtered.slice(start, start + pageSize),\n loading: false,\n pagination,\n params,\n };\n };\n\n const store = createSourceStore(buildState());\n const assertLive = (): void => {\n if (store.disposed) throw new SourcererDisposedError();\n };\n const samePagination = (left: PagePagination, right: PagePagination): boolean =>\n Object.keys(left).every((key) => left[key as keyof PagePagination] === right[key as keyof PagePagination]);\n const commit = (): void => {\n const next = buildState();\n const current = store.value;\n const sameItems =\n next.items.length === current.items.length &&\n next.items.every((item, index) => Object.is(item, current.items[index]));\n\n if (Object.is(next.params, current.params) && sameItems && samePagination(next.pagination, current.pagination))\n return;\n store.set(next);\n };\n const goTo = (nextPage: number): void => {\n assertLive();\n const normalized = Math.min(positiveInteger(nextPage, 'page'), store.value.pagination.pageCount);\n if (normalized === page) return;\n page = normalized;\n commit();\n };\n\n const source: LocalSource<T, TParams> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n first() {\n goTo(1);\n },\n\n goTo,\n\n last() {\n goTo(store.value.pagination.pageCount);\n },\n\n next() {\n if (store.value.pagination.hasNext) goTo(page + 1);\n else assertLive();\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) goTo(page - 1);\n else assertLive();\n },\n\n setItems(nextItems) {\n assertLive();\n if (nextItems === allItems) return;\n allItems = nextItems;\n commit();\n },\n\n setPageSize(nextPageSize) {\n assertLive();\n const normalized = positiveInteger(nextPageSize, 'pageSize');\n if (normalized === pageSize) return;\n page = 1;\n pageSize = normalized;\n commit();\n },\n\n setParams(nextParams) {\n assertLive();\n if (Object.is(nextParams, params)) return;\n page = 1;\n params = nextParams;\n commit();\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"sLAWA,SAAgB,kBACd,EACA,EAAwC,CAAC,EAChB,CACzB,IAAI,EAAW,EACX,EAAO,EACP,EAAW,EAAgB,EAAO,UAAY,GAAI,UAAU,EAC5D,EAAS,EAAO,OAEd,eAAiD,CACrD,IAAM,EAAW,EAAO,OAAS,EAAS,OAAQ,GAAS,EAAO,SAAS,EAAM,CAAM,CAAC,EAAI,EACtF,EAAa,EAAqB,EAAM,EAAU,EAAS,MAAM,EACvE,GAAI,EAAO,EAAW,UAEpB,MADA,GAAO,EAAW,UACX,WAAW,EAEpB,IAAM,GAAS,EAAO,GAAK,EAE3B,MAAO,CACL,MAAO,KACP,MAAO,EAAS,MAAM,EAAO,EAAQ,CAAQ,EAC7C,QAAS,GACT,aACA,QACF,CACF,EAEM,EAAQ,EAAkB,WAAW,CAAC,EACtC,eAAyB,CAC7B,GAAI,EAAM,SAAU,MAAM,IAAI,CAChC,EACM,gBAAkB,EAAsB,IAC5C,OAAO,KAAK,CAAI,CAAC,CAAC,MAAO,GAAQ,EAAK,KAAiC,EAAM,EAA4B,EACrG,WAAqB,CACzB,IAAM,EAAO,WAAW,EAClB,EAAU,EAAM,MAChB,EACJ,EAAK,MAAM,SAAW,EAAQ,MAAM,QACpC,EAAK,MAAM,OAAO,EAAM,IAAU,OAAO,GAAG,EAAM,EAAQ,MAAM,EAAM,CAAC,EAErE,OAAO,GAAG,EAAK,OAAQ,EAAQ,MAAM,GAAK,GAAa,eAAe,EAAK,WAAY,EAAQ,UAAU,GAE7G,EAAM,IAAI,CAAI,CAChB,EACM,KAAQ,GAA2B,CACvC,WAAW,EACX,IAAM,EAAa,KAAK,IAAI,EAAgB,EAAU,MAAM,EAAG,EAAM,MAAM,WAAW,SAAS,EAC3F,IAAe,IACnB,EAAO,EACP,OAAO,EACT,EAEM,EAAkC,CACtC,IAAI,gBAAiB,CACnB,OAAO,EAAM,cACf,EAEA,QAAS,EAAM,QAEf,IAAI,UAAW,CACb,OAAO,EAAM,QACf,EAEA,OAAQ,CACN,KAAK,CAAC,CACR,EAEA,KAEA,MAAO,CACL,KAAK,EAAM,MAAM,WAAW,SAAS,CACvC,EAEA,MAAO,CACD,EAAM,MAAM,WAAW,QAAS,KAAK,EAAO,CAAC,EAC5C,WAAW,CAClB,EAEA,UAAW,CACL,EAAM,MAAM,WAAW,YAAa,KAAK,EAAO,CAAC,EAChD,WAAW,CAClB,EAEA,SAAS,EAAW,CAClB,WAAW,EACP,IAAc,IAClB,EAAW,EACX,OAAO,EACT,EAEA,YAAY,EAAc,CACxB,WAAW,EACX,IAAM,EAAa,EAAgB,EAAc,UAAU,EACvD,IAAe,IACnB,EAAO,EACP,EAAW,EACX,OAAO,EACT,EAEA,UAAU,EAAY,CACpB,WAAW,EACP,QAAO,GAAG,EAAY,CAAM,IAChC,EAAO,EACP,EAAS,EACT,OAAO,EACT,EAEA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,EAEA,UAAW,EAAM,UAEjB,CAAC,OAAO,UAAW,CACjB,EAAO,QAAQ,CACjB,CACF,EAEA,OAAO,CACT"}
@@ -1,2 +1,2 @@
1
- const e=require("./_dev.cjs"),t=require("./asyncSource.cjs"),n=require("./pagination.cjs");var r=(e,t={},r)=>{let i=t.page??e.page,a=t.pageSize??e.pageSize,o=t.search??e.search,s=`filter`in t||t.pageSize!==void 0||t.search!==void 0||`sort`in t,c=t.page??(s?1:i);return{...`filter`in t?t.filter!==void 0&&{filter:t.filter}:e.filter!==void 0&&{filter:e.filter},...`sort`in t?t.sort!==void 0&&{sort:t.sort}:e.sort!==void 0&&{sort:e.sort},page:r===void 0?n.positiveInteger(c,`page`):Math.min(n.positiveInteger(c,`page`),r),pageSize:n.positiveInteger(a,`pageSize`),search:o}};function i(i){let a=r({page:1,pageSize:20,search:``},i.initialQuery),o=t.createAsyncSource({data:[],error:null,isFetching:!1,pagination:n.createPagePagination(a.page,a.pageSize,0),query:a}),s=e=>o.fetch({load:t=>i.load({query:e,signal:t}),query:e,success:t=>{let r=n.totalItems(t.total),i=n.createPagePagination(e.page,e.pageSize,r),o={...e,page:i.index};return a=o,{data:t.data,error:null,isFetching:!1,pagination:i,query:o}}}),c=()=>s(a),l=async e=>{let t=r(o.snapshot.pendingQuery??o.snapshot.query,e,o.snapshot.pagination.total>0?o.snapshot.pagination.count:void 0);n.sameQuery(t,a)||(a=t,await s(t))},u={get disposalSignal(){return o.disposalSignal},dispose:o.dispose,get disposed(){return o.disposed},page:{go(e){return o.snapshot.isFetching?Promise.resolve():l({page:e})},last(){return o.snapshot.isFetching?Promise.resolve():l({page:o.snapshot.pagination.count})},next(){return o.snapshot.isFetching||!o.snapshot.pagination.hasNext?Promise.resolve():l({page:o.snapshot.pagination.index+1})},previous(){return o.snapshot.isFetching||!o.snapshot.pagination.hasPrevious?Promise.resolve():l({page:o.snapshot.pagination.index-1})}},reload:c,setQuery:l,get snapshot(){return o.snapshot},subscribe:o.subscribe,[Symbol.dispose](){u.dispose()}};return i.autoStart!==!1&&c().catch(()=>e.warn(`Initial load failed. Inspect source.snapshot.error.`)),u}exports.createPageSource=i;
1
+ const e=require("./errors.cjs"),t=require("./asyncSource.cjs"),n=require("./pagination.cjs");function createPageSource(r){let i={page:1,pageSize:n.positiveInteger(r.pageSize??20,`pageSize`),params:r.params},a=!1,o=t.createAsyncSource({error:null,items:[],loading:!1,pagination:n.createPagePagination(i.page,i.pageSize,0),params:i.params}),assertLive=()=>{if(o.disposed)throw new e.SourcererDisposedError},isCommitted=e=>o.state.pagination.page===e.page&&o.state.pagination.pageSize===e.pageSize&&Object.is(o.state.params,e.params),fetch=e=>o.fetch({commit:()=>{a=!0,i=e},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:n.createPagePagination(e.page,e.pageSize,n.totalItems(t.totalItems)),params:e.params})}),goTo=async e=>{assertLive();let t=a?Math.min(n.positiveInteger(e,`page`),o.state.pagination.pageCount):n.positiveInteger(e,`page`);if(t===i.page){!o.state.loading&&(!a||!isCommitted(i))&&await fetch(i);return}i={...i,page:t},await fetch(i)},s={get disposalSignal(){return o.disposalSignal},dispose:o.dispose,get disposed(){return o.disposed},first(){return goTo(1)},goTo,last(){return goTo(o.state.pagination.pageCount)},async next(){assertLive(),(!a||i.page<o.state.pagination.pageCount)&&await goTo(i.page+1)},async previous(){assertLive(),i.page>1&&await goTo(i.page-1)},reload(){return fetch(i)},async setPageSize(e){assertLive();let t=n.positiveInteger(e,`pageSize`);if(t===i.pageSize&&i.page===1){!o.state.loading&&!isCommitted(i)&&await fetch(i);return}i={...i,page:1,pageSize:t},await fetch(i)},async setParams(e){if(assertLive(),Object.is(e,i.params)){!o.state.loading&&!isCommitted(i)&&await fetch(i);return}i={...i,page:1,params:e},await fetch(i)},get state(){return o.state},subscribe:o.subscribe,[Symbol.dispose](){s.dispose()}};return s}exports.createPageSource=createPageSource;
2
2
  //# sourceMappingURL=pageSource.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pageSource.cjs","names":[],"sources":["../src/pageSource.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { createAsyncSource } from './asyncSource';\nimport { createPagePagination, positiveInteger, sameQuery, totalItems } from './pagination';\nimport type { PagePagination, PageQuery, PageQueryPatch, PageSource, PageSourceConfig } from './types';\n\nconst normalizeQuery = <TFilter, TSort>(\n current: PageQuery<TFilter, TSort>,\n patch: PageQueryPatch<TFilter, TSort> = {},\n maxPage?: number,\n): PageQuery<TFilter, TSort> => {\n const page = patch.page ?? current.page;\n const pageSize = patch.pageSize ?? current.pageSize;\n const search = patch.search ?? current.search;\n const resetsPage = 'filter' in patch || patch.pageSize !== undefined || patch.search !== undefined || 'sort' in patch;\n\n const requestedPage = patch.page ?? (resetsPage ? 1 : page);\n\n return {\n ...('filter' in patch\n ? patch.filter !== undefined && { filter: patch.filter }\n : current.filter !== undefined && { filter: current.filter }),\n ...('sort' in patch\n ? patch.sort !== undefined && { sort: patch.sort }\n : current.sort !== undefined && { sort: current.sort }),\n page:\n maxPage === undefined\n ? positiveInteger(requestedPage, 'page')\n : Math.min(positiveInteger(requestedPage, 'page'), maxPage),\n pageSize: positiveInteger(pageSize, 'pageSize'),\n search,\n };\n};\n\n/** Page sources retain loaded state while pendingQuery records newer work. */\nexport function createPageSource<T, TFilter = unknown, TSort = unknown>(\n config: PageSourceConfig<T, TFilter, TSort>,\n): PageSource<T, TFilter, TSort> {\n const initialQuery: PageQuery<TFilter, TSort> = {\n page: 1,\n pageSize: 20,\n search: '',\n };\n let requestedQuery = normalizeQuery(initialQuery, config.initialQuery);\n const asyncSource = createAsyncSource<T, PageQuery<TFilter, TSort>, PagePagination>({\n data: [],\n error: null,\n isFetching: false,\n pagination: createPagePagination(requestedQuery.page, requestedQuery.pageSize, 0),\n query: requestedQuery,\n });\n\n const fetch = (query: PageQuery<TFilter, TSort>): Promise<void> =>\n asyncSource.fetch({\n load: (signal) => config.load({ query, signal }),\n query,\n success: (result) => {\n const total = totalItems(result.total);\n const pagination = createPagePagination(query.page, query.pageSize, total);\n const loadedQuery = { ...query, page: pagination.index };\n\n requestedQuery = loadedQuery;\n\n return {\n data: result.data,\n error: null,\n isFetching: false,\n pagination,\n query: loadedQuery,\n };\n },\n });\n\n const reload = (): Promise<void> => fetch(requestedQuery);\n\n const setQuery = async (patch: PageQueryPatch<TFilter, TSort>): Promise<void> => {\n const current = asyncSource.snapshot.pendingQuery ?? asyncSource.snapshot.query;\n const next = normalizeQuery(\n current,\n patch,\n asyncSource.snapshot.pagination.total > 0 ? asyncSource.snapshot.pagination.count : undefined,\n );\n\n if (sameQuery(next, requestedQuery)) return;\n\n requestedQuery = next;\n await fetch(next);\n };\n\n const source: PageSource<T, TFilter, TSort> = {\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 go(index) {\n return asyncSource.snapshot.isFetching ? Promise.resolve() : setQuery({ page: index });\n },\n\n last() {\n return asyncSource.snapshot.isFetching\n ? Promise.resolve()\n : setQuery({ page: asyncSource.snapshot.pagination.count });\n },\n\n next() {\n return asyncSource.snapshot.isFetching || !asyncSource.snapshot.pagination.hasNext\n ? Promise.resolve()\n : setQuery({ page: asyncSource.snapshot.pagination.index + 1 });\n },\n\n previous() {\n return asyncSource.snapshot.isFetching || !asyncSource.snapshot.pagination.hasPrevious\n ? Promise.resolve()\n : setQuery({ page: asyncSource.snapshot.pagination.index - 1 });\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":"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"}
1
+ {"version":3,"file":"pageSource.cjs","names":[],"sources":["../src/pageSource.ts"],"sourcesContent":["import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger, totalItems } from './pagination';\nimport type { PageSource, PageSourceConfig, PageSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ page: number; pageSize: number; params: TParams }>;\n\n/** Page sources retain committed items while replacement work is pending. */\nexport function createPageSource<T, TParams = undefined>(config: PageSourceConfig<T, TParams>): PageSource<T, TParams> {\n let requested: Request<TParams> = {\n page: 1,\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let hasLoaded = false;\n const asyncSource = createAsyncSource<PageSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagePagination(requested.page, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n const isCommitted = (request: Request<TParams>): boolean =>\n asyncSource.state.pagination.page === request.page &&\n asyncSource.state.pagination.pageSize === request.pageSize &&\n Object.is(asyncSource.state.params, request.params);\n\n const fetch = (request: Request<TParams>): Promise<void> =>\n asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n requested = request;\n },\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: createPagePagination(request.page, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n }),\n });\n\n const goTo = async (page: number): Promise<void> => {\n assertLive();\n const normalized = hasLoaded\n ? Math.min(positiveInteger(page, 'page'), asyncSource.state.pagination.pageCount)\n : positiveInteger(page, 'page');\n if (normalized === requested.page) {\n if (!asyncSource.state.loading && (!hasLoaded || !isCommitted(requested))) await fetch(requested);\n return;\n }\n requested = { ...requested, page: normalized };\n await fetch(requested);\n };\n\n const source: PageSource<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 first() {\n return goTo(1);\n },\n\n goTo,\n\n last() {\n return goTo(asyncSource.state.pagination.pageCount);\n },\n\n async next() {\n assertLive();\n if (!hasLoaded || requested.page < asyncSource.state.pagination.pageCount) await goTo(requested.page + 1);\n },\n\n async previous() {\n assertLive();\n if (requested.page > 1) await goTo(requested.page - 1);\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.page === 1) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, pageSize: normalized };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, 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 { PageSource, PageSourceConfig } from './types';
2
- /** Page sources retain loaded state while pendingQuery records newer work. */
3
- export declare function createPageSource<T, TFilter = unknown, TSort = unknown>(config: PageSourceConfig<T, TFilter, TSort>): PageSource<T, TFilter, TSort>;
2
+ /** Page sources retain committed items while replacement work is pending. */
3
+ export declare function createPageSource<T, TParams = undefined>(config: PageSourceConfig<T, TParams>): PageSource<T, TParams>;
4
4
  //# sourceMappingURL=pageSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pageSource.d.ts","sourceRoot":"","sources":["../src/pageSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAA6C,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA8BvG,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,EACpE,MAAM,EAAE,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,GAC1C,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAyG/B"}
1
+ {"version":3,"file":"pageSource.d.ts","sourceRoot":"","sources":["../src/pageSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAmB,MAAM,SAAS,CAAC;AAI7E,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CA8HrH"}
@@ -1,85 +1,2 @@
1
- import { warn as e } from "./_dev.js";
2
- import { createAsyncSource as t } from "./asyncSource.js";
3
- import { createPagePagination as n, positiveInteger as r, sameQuery as i, totalItems as a } from "./pagination.js";
4
- //#region src/pageSource.ts
5
- var o = (e, t = {}, n) => {
6
- let i = t.page ?? e.page, a = t.pageSize ?? e.pageSize, o = t.search ?? e.search, s = "filter" in t || t.pageSize !== void 0 || t.search !== void 0 || "sort" in t, c = t.page ?? (s ? 1 : i);
7
- return {
8
- ..."filter" in t ? t.filter !== void 0 && { filter: t.filter } : e.filter !== void 0 && { filter: e.filter },
9
- ..."sort" in t ? t.sort !== void 0 && { sort: t.sort } : e.sort !== void 0 && { sort: e.sort },
10
- page: n === void 0 ? r(c, "page") : Math.min(r(c, "page"), n),
11
- pageSize: r(a, "pageSize"),
12
- search: o
13
- };
14
- };
15
- function s(r) {
16
- let s = o({
17
- page: 1,
18
- pageSize: 20,
19
- search: ""
20
- }, r.initialQuery), c = t({
21
- data: [],
22
- error: null,
23
- isFetching: !1,
24
- pagination: n(s.page, s.pageSize, 0),
25
- query: s
26
- }), l = (e) => c.fetch({
27
- load: (t) => r.load({
28
- query: e,
29
- signal: t
30
- }),
31
- query: e,
32
- success: (t) => {
33
- let r = a(t.total), i = n(e.page, e.pageSize, r), o = {
34
- ...e,
35
- page: i.index
36
- };
37
- return s = o, {
38
- data: t.data,
39
- error: null,
40
- isFetching: !1,
41
- pagination: i,
42
- query: o
43
- };
44
- }
45
- }), u = () => l(s), d = async (e) => {
46
- let t = o(c.snapshot.pendingQuery ?? c.snapshot.query, e, c.snapshot.pagination.total > 0 ? c.snapshot.pagination.count : void 0);
47
- i(t, s) || (s = t, await l(t));
48
- }, f = {
49
- get disposalSignal() {
50
- return c.disposalSignal;
51
- },
52
- dispose: c.dispose,
53
- get disposed() {
54
- return c.disposed;
55
- },
56
- page: {
57
- go(e) {
58
- return c.snapshot.isFetching ? Promise.resolve() : d({ page: e });
59
- },
60
- last() {
61
- return c.snapshot.isFetching ? Promise.resolve() : d({ page: c.snapshot.pagination.count });
62
- },
63
- next() {
64
- return c.snapshot.isFetching || !c.snapshot.pagination.hasNext ? Promise.resolve() : d({ page: c.snapshot.pagination.index + 1 });
65
- },
66
- previous() {
67
- return c.snapshot.isFetching || !c.snapshot.pagination.hasPrevious ? Promise.resolve() : d({ page: c.snapshot.pagination.index - 1 });
68
- }
69
- },
70
- reload: u,
71
- setQuery: d,
72
- get snapshot() {
73
- return c.snapshot;
74
- },
75
- subscribe: c.subscribe,
76
- [Symbol.dispose]() {
77
- f.dispose();
78
- }
79
- };
80
- return r.autoStart !== !1 && u().catch(() => /* @__PURE__ */ e("Initial load failed. Inspect source.snapshot.error.")), f;
81
- }
82
- //#endregion
83
- export { s as createPageSource };
84
-
1
+ import{SourcererDisposedError as e}from"./errors.js";import{createAsyncSource as t}from"./asyncSource.js";import{createPagePagination as n,positiveInteger as r,totalItems as i}from"./pagination.js";function createPageSource(a){let o={page:1,pageSize:r(a.pageSize??20,`pageSize`),params:a.params},s=!1,c=t({error:null,items:[],loading:!1,pagination:n(o.page,o.pageSize,0),params:o.params}),assertLive=()=>{if(c.disposed)throw new e},isCommitted=e=>c.state.pagination.page===e.page&&c.state.pagination.pageSize===e.pageSize&&Object.is(c.state.params,e.params),fetch=e=>c.fetch({commit:()=>{s=!0,o=e},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>a.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:n(e.page,e.pageSize,i(t.totalItems)),params:e.params})}),goTo=async e=>{assertLive();let t=s?Math.min(r(e,`page`),c.state.pagination.pageCount):r(e,`page`);if(t===o.page){!c.state.loading&&(!s||!isCommitted(o))&&await fetch(o);return}o={...o,page:t},await fetch(o)},l={get disposalSignal(){return c.disposalSignal},dispose:c.dispose,get disposed(){return c.disposed},first(){return goTo(1)},goTo,last(){return goTo(c.state.pagination.pageCount)},async next(){assertLive(),(!s||o.page<c.state.pagination.pageCount)&&await goTo(o.page+1)},async previous(){assertLive(),o.page>1&&await goTo(o.page-1)},reload(){return fetch(o)},async setPageSize(e){assertLive();let t=r(e,`pageSize`);if(t===o.pageSize&&o.page===1){!c.state.loading&&!isCommitted(o)&&await fetch(o);return}o={...o,page:1,pageSize:t},await fetch(o)},async setParams(e){if(assertLive(),Object.is(e,o.params)){!c.state.loading&&!isCommitted(o)&&await fetch(o);return}o={...o,page:1,params:e},await fetch(o)},get state(){return c.state},subscribe:c.subscribe,[Symbol.dispose](){l.dispose()}};return l}export{createPageSource};
85
2
  //# sourceMappingURL=pageSource.js.map