@vielzeug/sourcerer 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/asyncSearch.cjs +2 -0
- package/dist/asyncSearch.cjs.map +1 -0
- package/dist/asyncSearch.d.ts +13 -0
- package/dist/asyncSearch.d.ts.map +1 -0
- package/dist/asyncSearch.js +28 -0
- package/dist/asyncSearch.js.map +1 -0
- package/dist/cursorSource.cjs +1 -1
- package/dist/cursorSource.cjs.map +1 -1
- package/dist/cursorSource.d.ts.map +1 -1
- package/dist/cursorSource.js +37 -47
- package/dist/cursorSource.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/infiniteSource.cjs +1 -1
- package/dist/infiniteSource.cjs.map +1 -1
- package/dist/infiniteSource.d.ts.map +1 -1
- package/dist/infiniteSource.js +45 -55
- package/dist/infiniteSource.js.map +1 -1
- package/dist/presets.cjs +1 -1
- package/dist/presets.cjs.map +1 -1
- package/dist/presets.d.ts +5 -0
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +23 -4
- package/dist/presets.js.map +1 -1
- package/dist/remoteSource.cjs +1 -1
- package/dist/remoteSource.cjs.map +1 -1
- package/dist/remoteSource.d.ts.map +1 -1
- package/dist/remoteSource.js +55 -65
- package/dist/remoteSource.js.map +1 -1
- package/dist/sourcerer.cjs +1 -1
- package/dist/sourcerer.cjs.map +1 -1
- package/dist/sourcerer.iife.js +1 -1
- package/dist/sourcerer.iife.js.map +1 -1
- package/dist/sourcerer.js +1 -1
- package/dist/sourcerer.js.map +1 -1
- package/package.json +1 -1
- package/dist/_dev.d.ts +0 -2
- package/dist/_dev.d.ts.map +0 -1
package/dist/remoteSource.js
CHANGED
|
@@ -1,60 +1,59 @@
|
|
|
1
1
|
import { SourcererError as e } from "./errors.js";
|
|
2
2
|
import { defaultKeyOf as t, extractError as n, retry as r } from "./_utils.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { createAsyncSearchCoordinator as i } from "./asyncSearch.js";
|
|
4
|
+
import { createAsyncSource as a } from "./asyncSource.js";
|
|
5
|
+
import { clampPage as o, createMeta as s, pageCount as c } from "./pagination.js";
|
|
5
6
|
//#region src/remoteSource.ts
|
|
6
|
-
function
|
|
7
|
-
let
|
|
8
|
-
|
|
9
|
-
let C = [], w =
|
|
7
|
+
function l(l) {
|
|
8
|
+
let u = l.queryKey ?? t, d = l.staleTime ?? 0, f = Math.max(1, Math.trunc(l.limit ?? 20)), p = 1, m = "", h = l.filter, g = l.sort, _ = [], v = 0, y = null, b = 0, x = "", S = null;
|
|
9
|
+
l.snapshot && (_ = l.snapshot.items, v = l.snapshot.total, l.snapshot.page !== void 0 && (p = l.snapshot.page), l.snapshot.search && (m = l.snapshot.search), b = Date.now());
|
|
10
|
+
let C = [], w = s({
|
|
10
11
|
error: null,
|
|
11
12
|
isLoading: !1,
|
|
12
13
|
isSearchPending: !1,
|
|
13
14
|
pageNumber: 1,
|
|
14
|
-
pageSize:
|
|
15
|
+
pageSize: f,
|
|
15
16
|
totalItems: 0
|
|
16
17
|
}), T = () => {
|
|
17
|
-
let e =
|
|
18
|
-
C =
|
|
19
|
-
error:
|
|
18
|
+
let e = c(v, f), t = o(p, e);
|
|
19
|
+
C = _, w = s({
|
|
20
|
+
error: y,
|
|
20
21
|
isLoading: E.pendingCount() > 0,
|
|
21
22
|
isSearchPending: E.core.isScheduled,
|
|
22
23
|
pageNumber: t,
|
|
23
|
-
pageSize:
|
|
24
|
-
totalItems:
|
|
24
|
+
pageSize: f,
|
|
25
|
+
totalItems: v
|
|
25
26
|
});
|
|
26
|
-
}, E =
|
|
27
|
+
}, E = a(l, u, T), { autoFetch: D, debounceMs: O, retryAttempts: k, retryDelay: A } = E;
|
|
27
28
|
T();
|
|
28
29
|
let j = () => {
|
|
29
30
|
E.disposed || E.core.notify();
|
|
30
|
-
}, M = (e) => {
|
|
31
|
-
S?.active && (S.active = !1, S = null),
|
|
32
|
-
}, N = () => {
|
|
33
|
-
x &&= (x.resolve(), null);
|
|
31
|
+
}, M = i(E.core, j), N = (e) => {
|
|
32
|
+
S?.active && (S.active = !1, S = null), _ = e.items, v = e.total, p = o(p, c(v, f));
|
|
34
33
|
}, P = () => ({
|
|
35
|
-
...
|
|
36
|
-
...
|
|
37
|
-
...
|
|
38
|
-
limit:
|
|
39
|
-
page:
|
|
34
|
+
...h !== void 0 && { filter: h },
|
|
35
|
+
...g !== void 0 && { sort: g },
|
|
36
|
+
...m && { search: m },
|
|
37
|
+
limit: f,
|
|
38
|
+
page: p
|
|
40
39
|
}), F = (t) => {
|
|
41
|
-
let i =
|
|
42
|
-
return
|
|
40
|
+
let i = u(t);
|
|
41
|
+
return d > 0 && i === x && v > 0 && Date.now() - b < d && !S?.active ? Promise.resolve() : (y = null, E.fetch(t, async (t, a, o) => {
|
|
43
42
|
let s = Date.now();
|
|
44
43
|
try {
|
|
45
|
-
let e = await r((e) =>
|
|
44
|
+
let e = await r((e) => l.fetch(t, e), {
|
|
46
45
|
delay: A,
|
|
47
46
|
signal: a,
|
|
48
47
|
times: k + 1
|
|
49
48
|
});
|
|
50
|
-
o() && (
|
|
49
|
+
o() && (N(e), y = null, x = i, b = Date.now(), l.onFetch?.({
|
|
51
50
|
durationMs: Date.now() - s,
|
|
52
51
|
query: t,
|
|
53
52
|
status: "success"
|
|
54
53
|
}));
|
|
55
54
|
} catch (r) {
|
|
56
55
|
if (a.aborted) return;
|
|
57
|
-
o() && (S?.active ? (S.active = !1,
|
|
56
|
+
o() && (S?.active ? (S.active = !1, _ = S.prevItems, v = S.prevTotal, S = null) : (_ = [], v = 0), y = new e(n(r), {
|
|
58
57
|
cause: r,
|
|
59
58
|
context: {
|
|
60
59
|
kind: "remote",
|
|
@@ -62,15 +61,15 @@ function c(c) {
|
|
|
62
61
|
page: t.page,
|
|
63
62
|
...t.search && { search: t.search }
|
|
64
63
|
}
|
|
65
|
-
}),
|
|
64
|
+
}), l.onFetch?.({
|
|
66
65
|
durationMs: Date.now() - s,
|
|
67
|
-
error:
|
|
66
|
+
error: y,
|
|
68
67
|
query: t,
|
|
69
68
|
status: "error"
|
|
70
69
|
}));
|
|
71
70
|
}
|
|
72
71
|
}, () => {
|
|
73
|
-
j(), E.pendingCount()
|
|
72
|
+
j(), M.settleIfIdle(E.pendingCount());
|
|
74
73
|
}));
|
|
75
74
|
}, I = () => F(P());
|
|
76
75
|
return D && I(), E.startRefreshInterval(() => void I()), {
|
|
@@ -81,65 +80,65 @@ function c(c) {
|
|
|
81
80
|
return E.disposalSignal;
|
|
82
81
|
},
|
|
83
82
|
dispose: () => {
|
|
84
|
-
|
|
83
|
+
M.cancel(), M.dispose(), E.dispose();
|
|
85
84
|
},
|
|
86
85
|
get disposed() {
|
|
87
86
|
return E.disposed;
|
|
88
87
|
},
|
|
89
88
|
goTo(e) {
|
|
90
|
-
let t =
|
|
91
|
-
return t ===
|
|
89
|
+
let t = v > 0 ? o(e, c(v, f)) : Math.max(1, Math.trunc(e));
|
|
90
|
+
return t === p ? Promise.resolve() : (p = t, I());
|
|
92
91
|
},
|
|
93
92
|
goToLast() {
|
|
94
|
-
let e =
|
|
95
|
-
return
|
|
93
|
+
let e = c(v, f);
|
|
94
|
+
return p === e ? Promise.resolve() : (p = e, I());
|
|
96
95
|
},
|
|
97
96
|
get meta() {
|
|
98
97
|
return w;
|
|
99
98
|
},
|
|
100
99
|
next() {
|
|
101
|
-
let e =
|
|
102
|
-
return
|
|
100
|
+
let e = c(v, f);
|
|
101
|
+
return p >= e ? Promise.resolve() : (p++, I());
|
|
103
102
|
},
|
|
104
103
|
optimisticUpdate(t, n) {
|
|
105
104
|
if (S?.active) throw new e("An optimistic update is already active. Rollback the previous update before starting another.");
|
|
106
|
-
let r =
|
|
105
|
+
let r = _, i = v;
|
|
107
106
|
S = {
|
|
108
107
|
active: !0,
|
|
109
108
|
prevItems: r,
|
|
110
109
|
prevTotal: i
|
|
111
110
|
};
|
|
112
111
|
try {
|
|
113
|
-
|
|
112
|
+
_ = t(_);
|
|
114
113
|
} catch (e) {
|
|
115
114
|
throw S = null, e;
|
|
116
115
|
}
|
|
117
|
-
return
|
|
118
|
-
S?.active && (S.active = !1,
|
|
116
|
+
return v = n?.total ?? v, j(), () => {
|
|
117
|
+
S?.active && (S.active = !1, _ = r, v = i, S = null, j());
|
|
119
118
|
};
|
|
120
119
|
},
|
|
121
120
|
patch(e) {
|
|
122
121
|
let t = !1;
|
|
123
122
|
if (e.limit !== void 0) {
|
|
124
123
|
let n = Math.max(1, Math.trunc(e.limit));
|
|
125
|
-
n !== d && (d = n, t = !0);
|
|
126
|
-
}
|
|
127
|
-
if ("filter" in e && (m = e.filter, t = !0), "sort" in e && (h = e.sort, t = !0), "search" in e && (e.search !== p || E.core.isScheduled) && (p = e.search ?? "", t = !0), e.page !== void 0) {
|
|
128
|
-
let n = _ > 0 ? a(e.page, s(_, d)) : Math.max(1, Math.trunc(e.page));
|
|
129
124
|
n !== f && (f = n, t = !0);
|
|
130
125
|
}
|
|
131
|
-
|
|
126
|
+
if ("filter" in e && (h = e.filter, t = !0), "sort" in e && (g = e.sort, t = !0), "search" in e && (e.search !== m || E.core.isScheduled) && (m = e.search ?? "", t = !0), e.page !== void 0) {
|
|
127
|
+
let n = v > 0 ? o(e.page, c(v, f)) : Math.max(1, Math.trunc(e.page));
|
|
128
|
+
n !== p && (p = n, t = !0);
|
|
129
|
+
}
|
|
130
|
+
return t ? (M.cancel(), (e.limit !== void 0 || "filter" in e || "sort" in e || "search" in e) && e.page === void 0 && (p = 1), I()) : Promise.resolve();
|
|
132
131
|
},
|
|
133
132
|
prev() {
|
|
134
|
-
return
|
|
133
|
+
return p <= 1 ? Promise.resolve() : (p--, I());
|
|
135
134
|
},
|
|
136
135
|
get query() {
|
|
137
136
|
return {
|
|
138
|
-
...
|
|
139
|
-
...
|
|
140
|
-
...
|
|
141
|
-
limit:
|
|
142
|
-
page:
|
|
137
|
+
...h !== void 0 && { filter: h },
|
|
138
|
+
...g !== void 0 && { sort: g },
|
|
139
|
+
...m && { search: m },
|
|
140
|
+
limit: f,
|
|
141
|
+
page: p
|
|
143
142
|
};
|
|
144
143
|
},
|
|
145
144
|
ready(e) {
|
|
@@ -149,27 +148,18 @@ function c(c) {
|
|
|
149
148
|
return I();
|
|
150
149
|
},
|
|
151
150
|
reset() {
|
|
152
|
-
return
|
|
151
|
+
return M.cancel(), m = "", p = 1, h = l.filter, g = l.sort, I();
|
|
153
152
|
},
|
|
154
153
|
search(e, t) {
|
|
155
|
-
|
|
156
|
-
if (e === p) return Promise.resolve();
|
|
157
|
-
N(), p = e, f = 1;
|
|
158
|
-
let n, r = new Promise((e) => {
|
|
159
|
-
n = e;
|
|
160
|
-
});
|
|
161
|
-
return x = {
|
|
162
|
-
promise: r,
|
|
163
|
-
resolve: n
|
|
164
|
-
}, E.core.schedule(() => void I(), O), j(), r;
|
|
154
|
+
return t?.immediate ? e === m && !E.core.isScheduled ? Promise.resolve() : (M.cancel(), m = e, p = 1, I()) : e === m ? Promise.resolve() : (m = e, p = 1, M.schedule(() => void I(), O));
|
|
165
155
|
},
|
|
166
156
|
subscribe: (e) => E.core.subscribe(e),
|
|
167
157
|
[Symbol.dispose]: () => {
|
|
168
|
-
|
|
158
|
+
M.cancel(), M.dispose(), E.dispose();
|
|
169
159
|
}
|
|
170
160
|
};
|
|
171
161
|
}
|
|
172
162
|
//#endregion
|
|
173
|
-
export {
|
|
163
|
+
export { l as createRemoteSource };
|
|
174
164
|
|
|
175
165
|
//# sourceMappingURL=remoteSource.js.map
|
package/dist/remoteSource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteSource.js","names":[],"sources":["../src/remoteSource.ts"],"sourcesContent":["import type { RemoteConfig, RemoteSource, RemoteSourceQuery, SearchOptions } from './types';\n\nimport { defaultKeyOf, extractError, retry } from './_utils';\nimport { createAsyncSource } from './asyncSource';\nimport { SourcererError } from './errors';\nimport { clampPage, createMeta, pageCount } from './pagination';\n\ntype PendingSearch = { promise: Promise<void>; resolve: () => void };\n\n/** Creates a remote page-based source that fetches data from a network endpoint. */\nexport function createRemoteSource<T, TFilter = unknown, TSort = unknown>(\n cfg: RemoteConfig<T, TFilter, TSort>,\n): RemoteSource<T, TFilter, TSort> {\n const keyOf = cfg.queryKey ?? defaultKeyOf;\n\n // ── Config defaults ─────────────────────────────────────────────────────────\n const staleTimeMs = cfg.staleTime ?? 0;\n\n // ── Mutable state ───────────────────────────────────────────────────────────\n let limit = Math.max(1, Math.trunc(cfg.limit ?? 20));\n let page = 1;\n let search = '';\n let filter: TFilter | undefined = cfg.filter;\n let sort: TSort | undefined = cfg.sort;\n let items: readonly T[] = [];\n let total = 0;\n let error: SourcererError | null = null;\n let lastFetchTime = 0;\n let lastFetchKey = '';\n let pendingSearch: PendingSearch | null = null;\n\n // Optimistic update state.\n let optimistic: { active: boolean; prevItems: readonly T[]; prevTotal: number } | null = null;\n\n // ── Snapshot pre-population ─────────────────────────────────────────────────\n if (cfg.snapshot) {\n items = cfg.snapshot.items;\n total = cfg.snapshot.total;\n\n if (cfg.snapshot.page !== undefined) page = cfg.snapshot.page;\n\n if (cfg.snapshot.search) search = cfg.snapshot.search;\n\n lastFetchTime = Date.now();\n }\n\n // ── Cached accessors ────────────────────────────────────────────────────────\n let cachedCurrent: readonly T[] = [];\n let cachedMeta = createMeta({\n error: null,\n isLoading: false,\n isSearchPending: false,\n pageNumber: 1,\n pageSize: limit,\n totalItems: 0,\n });\n\n const refreshMeta = () => {\n const pages = pageCount(total, limit);\n const safePage = clampPage(page, pages);\n\n // items is already the current page from the server — no local slicing needed.\n cachedCurrent = items;\n cachedMeta = createMeta({\n error,\n isLoading: base.pendingCount() > 0,\n isSearchPending: base.core.isScheduled,\n pageNumber: safePage,\n pageSize: limit,\n totalItems: total,\n });\n };\n\n // onBeforeNotify ensures refreshMeta() runs before any subscriber observes the new state,\n // eliminating the need for a parallel listeners Set.\n const base = createAsyncSource<RemoteSourceQuery<TFilter, TSort>>(cfg, keyOf, refreshMeta);\n const { autoFetch, debounceMs, retryAttempts, retryDelay } = base;\n\n // Initialise cache before first fetch.\n refreshMeta();\n\n const notifyListeners = () => {\n if (base.disposed) return;\n\n base.core.notify();\n };\n\n // ── Assign result ───────────────────────────────────────────────────────────\n const assign = (result: Readonly<{ items: readonly T[]; total: number }>) => {\n if (optimistic?.active) {\n optimistic.active = false;\n optimistic = null;\n }\n\n items = result.items;\n total = result.total;\n page = clampPage(page, pageCount(total, limit));\n };\n\n const resolvePendingSearch = () => {\n if (pendingSearch) {\n pendingSearch.resolve();\n pendingSearch = null;\n }\n };\n\n // ── Core fetch ──────────────────────────────────────────────────────────────\n const toRemoteQuery = (): RemoteSourceQuery<TFilter, TSort> => ({\n ...(filter !== undefined && { filter }),\n ...(sort !== undefined && { sort }),\n ...(search && { search }),\n limit,\n page,\n });\n\n const fetchQuery = (q: RemoteSourceQuery<TFilter, TSort>): Promise<void> => {\n const key = keyOf(q);\n\n if (staleTimeMs > 0 && key === lastFetchKey && total > 0 && Date.now() - lastFetchTime < staleTimeMs) {\n return Promise.resolve();\n }\n\n error = null;\n\n return base.fetch(\n q,\n async (q: RemoteSourceQuery<TFilter, TSort>, signal, isLatest) => {\n const startTime = Date.now();\n\n try {\n const result = await retry((sig) => cfg.fetch(q, sig!), {\n delay: retryDelay,\n signal,\n times: retryAttempts + 1,\n });\n\n if (isLatest()) {\n assign(result);\n error = null;\n lastFetchKey = key;\n lastFetchTime = Date.now();\n cfg.onFetch?.({ durationMs: Date.now() - startTime, query: q, status: 'success' });\n }\n } catch (reason: unknown) {\n if (signal.aborted) return;\n\n if (isLatest()) {\n if (optimistic?.active) {\n optimistic.active = false;\n items = optimistic.prevItems;\n total = optimistic.prevTotal;\n optimistic = null;\n } else {\n items = [];\n total = 0;\n }\n\n error = new SourcererError(extractError(reason), {\n cause: reason,\n context: { kind: 'remote', limit: q.limit, page: q.page, ...(q.search && { search: q.search }) },\n });\n cfg.onFetch?.({ durationMs: Date.now() - startTime, error, query: q, status: 'error' });\n }\n }\n },\n () => {\n notifyListeners();\n\n if (base.pendingCount() === 0) resolvePendingSearch();\n },\n );\n };\n\n const doUpdate = () => fetchQuery(toRemoteQuery());\n\n // ── Auto-fetch + refresh interval ───────────────────────────────────────────\n if (autoFetch) void doUpdate();\n\n base.startRefreshInterval(() => void doUpdate());\n\n // ── Public API ──────────────────────────────────────────────────────────────\n return {\n get current() {\n return cachedCurrent;\n },\n\n get disposalSignal() {\n return base.disposalSignal;\n },\n\n dispose: () => {\n resolvePendingSearch();\n base.dispose();\n },\n\n get disposed() {\n return base.disposed;\n },\n\n goTo(target) {\n const clamped = total > 0 ? clampPage(target, pageCount(total, limit)) : Math.max(1, Math.trunc(target));\n\n if (clamped === page) return Promise.resolve();\n\n page = clamped;\n\n return doUpdate();\n },\n\n goToLast() {\n const last = pageCount(total, limit);\n\n if (page === last) return Promise.resolve();\n\n page = last;\n\n return doUpdate();\n },\n\n get meta() {\n return cachedMeta;\n },\n\n next() {\n const pages = pageCount(total, limit);\n\n if (page >= pages) return Promise.resolve();\n\n page++;\n\n return doUpdate();\n },\n\n optimisticUpdate(mutator, options) {\n if (optimistic?.active) {\n throw new SourcererError(\n 'An optimistic update is already active. Rollback the previous update before starting another.',\n );\n }\n\n const prevItems = items;\n const prevTotal = total;\n\n optimistic = { active: true, prevItems, prevTotal };\n\n try {\n items = mutator(items);\n } catch (e: unknown) {\n optimistic = null;\n throw e;\n }\n\n total = options?.total ?? total;\n notifyListeners();\n\n return () => {\n if (optimistic?.active) {\n optimistic.active = false;\n items = prevItems;\n total = prevTotal;\n optimistic = null;\n notifyListeners();\n }\n };\n },\n\n patch(changes) {\n let changed = false;\n\n if (changes.limit !== undefined) {\n const next = Math.max(1, Math.trunc(changes.limit));\n\n if (next !== limit) {\n limit = next;\n changed = true;\n }\n }\n\n if ('filter' in changes) {\n filter = changes.filter;\n changed = true;\n }\n\n if ('sort' in changes) {\n sort = changes.sort;\n changed = true;\n }\n\n // `|| base.core.isScheduled` also catches patching in the same search text as an already-pending\n // debounced search() call — that still needs flushing, not silently dropping as a no-op.\n if ('search' in changes && (changes.search !== search || base.core.isScheduled)) {\n search = changes.search ?? '';\n changed = true;\n }\n\n if (changes.page !== undefined) {\n const next =\n total > 0 ? clampPage(changes.page, pageCount(total, limit)) : Math.max(1, Math.trunc(changes.page));\n\n if (next !== page) {\n page = next;\n changed = true;\n }\n }\n\n if (!changed) return Promise.resolve();\n\n // patch() is documented as a single atomic fetch — cancel any debounced search()\n // still pending so it doesn't fire a second, redundant fetch afterwards.\n base.core.cancelTimer();\n resolvePendingSearch();\n\n // Reset to page 1 when non-page query fields changed without explicit page\n if (\n (changes.limit !== undefined || 'filter' in changes || 'sort' in changes || 'search' in changes) &&\n changes.page === undefined\n ) {\n page = 1;\n }\n\n return doUpdate();\n },\n\n prev() {\n if (page <= 1) return Promise.resolve();\n\n page--;\n\n return doUpdate();\n },\n\n get query() {\n return {\n ...(filter !== undefined && { filter }),\n ...(sort !== undefined && { sort }),\n ...(search && { search }),\n limit,\n page,\n };\n },\n\n ready(timeout) {\n return base.ready(timeout);\n },\n\n refresh() {\n return doUpdate();\n },\n\n reset() {\n base.core.cancelTimer();\n resolvePendingSearch();\n search = '';\n page = 1;\n filter = cfg.filter;\n sort = cfg.sort;\n\n return doUpdate();\n },\n\n search(q, opts?: SearchOptions): Promise<void> {\n if (opts?.immediate) {\n // A pending debounced search for this same text still needs flushing —\n // `q === search` alone doesn't mean the fetch already happened.\n if (q === search && !base.core.isScheduled) return Promise.resolve();\n\n base.core.cancelTimer();\n resolvePendingSearch();\n search = q;\n page = 1;\n\n return doUpdate();\n }\n\n if (q === search) return Promise.resolve();\n\n resolvePendingSearch();\n\n search = q;\n page = 1;\n\n let resolveSearch!: () => void;\n const promise = new Promise<void>((res) => {\n resolveSearch = res;\n });\n\n pendingSearch = { promise, resolve: resolveSearch };\n\n base.core.schedule(() => void doUpdate(), debounceMs);\n notifyListeners();\n\n return promise;\n },\n\n subscribe: (listener) => base.core.subscribe(listener),\n\n [Symbol.dispose]: () => {\n resolvePendingSearch();\n base.dispose();\n },\n };\n}\n"],"mappings":";;;;;AAUA,SAAgB,EACd,GACiC;CACjC,IAAM,IAAQ,EAAI,YAAY,GAGxB,IAAc,EAAI,aAAa,GAGjC,IAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,EAAI,SAAS,EAAE,CAAC,GAC/C,IAAO,GACP,IAAS,IACT,IAA8B,EAAI,QAClC,IAA0B,EAAI,MAC9B,IAAsB,CAAC,GACvB,IAAQ,GACR,IAA+B,MAC/B,IAAgB,GAChB,IAAe,IACf,IAAsC,MAGtC,IAAqF;CAGzF,AAAI,EAAI,aACN,IAAQ,EAAI,SAAS,OACrB,IAAQ,EAAI,SAAS,OAEjB,EAAI,SAAS,SAAS,KAAA,MAAW,IAAO,EAAI,SAAS,OAErD,EAAI,SAAS,WAAQ,IAAS,EAAI,SAAS,SAE/C,IAAgB,KAAK,IAAI;CAI3B,IAAI,IAA8B,CAAC,GAC/B,IAAa,EAAW;EAC1B,OAAO;EACP,WAAW;EACX,iBAAiB;EACjB,YAAY;EACZ,UAAU;EACV,YAAY;CACd,CAAC,GAEK,UAAoB;EACxB,IAAM,IAAQ,EAAU,GAAO,CAAK,GAC9B,IAAW,EAAU,GAAM,CAAK;EAItC,AADA,IAAgB,GAChB,IAAa,EAAW;GACtB;GACA,WAAW,EAAK,aAAa,IAAI;GACjC,iBAAiB,EAAK,KAAK;GAC3B,YAAY;GACZ,UAAU;GACV,YAAY;EACd,CAAC;CACH,GAIM,IAAO,EAAqD,GAAK,GAAO,CAAW,GACnF,EAAE,cAAW,eAAY,kBAAe,kBAAe;CAG7D,EAAY;CAEZ,IAAM,UAAwB;EACxB,EAAK,YAET,EAAK,KAAK,OAAO;CACnB,GAGM,KAAU,MAA6D;EAQ3E,AAPI,GAAY,WACd,EAAW,SAAS,IACpB,IAAa,OAGf,IAAQ,EAAO,OACf,IAAQ,EAAO,OACf,IAAO,EAAU,GAAM,EAAU,GAAO,CAAK,CAAC;CAChD,GAEM,UAA6B;EACjC,AAEE,OADA,EAAc,QAAQ,GACN;CAEpB,GAGM,WAA0D;EAC9D,GAAI,MAAW,KAAA,KAAa,EAAE,UAAO;EACrC,GAAI,MAAS,KAAA,KAAa,EAAE,QAAK;EACjC,GAAI,KAAU,EAAE,UAAO;EACvB;EACA;CACF,IAEM,KAAc,MAAwD;EAC1E,IAAM,IAAM,EAAM,CAAC;EAQnB,OANI,IAAc,KAAK,MAAQ,KAAgB,IAAQ,KAAK,KAAK,IAAI,IAAI,IAAgB,IAChF,QAAQ,QAAQ,KAGzB,IAAQ,MAED,EAAK,MACV,GACA,OAAO,GAAsC,GAAQ,MAAa;GAChE,IAAM,IAAY,KAAK,IAAI;GAE3B,IAAI;IACF,IAAM,IAAS,MAAM,GAAO,MAAQ,EAAI,MAAM,GAAG,CAAI,GAAG;KACtD,OAAO;KACP;KACA,OAAO,IAAgB;IACzB,CAAC;IAED,AAAI,EAAS,MACX,EAAO,CAAM,GACb,IAAQ,MACR,IAAe,GACf,IAAgB,KAAK,IAAI,GACzB,EAAI,UAAU;KAAE,YAAY,KAAK,IAAI,IAAI;KAAW,OAAO;KAAG,QAAQ;IAAU,CAAC;GAErF,SAAS,GAAiB;IACxB,IAAI,EAAO,SAAS;IAEpB,AAAI,EAAS,MACP,GAAY,UACd,EAAW,SAAS,IACpB,IAAQ,EAAW,WACnB,IAAQ,EAAW,WACnB,IAAa,SAEb,IAAQ,CAAC,GACT,IAAQ,IAGV,IAAQ,IAAI,EAAe,EAAa,CAAM,GAAG;KAC/C,OAAO;KACP,SAAS;MAAE,MAAM;MAAU,OAAO,EAAE;MAAO,MAAM,EAAE;MAAM,GAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO;KAAG;IACjG,CAAC,GACD,EAAI,UAAU;KAAE,YAAY,KAAK,IAAI,IAAI;KAAW;KAAO,OAAO;KAAG,QAAQ;IAAQ,CAAC;GAE1F;EACF,SACM;GAGJ,AAFA,EAAgB,GAEZ,EAAK,aAAa,MAAM,KAAG,EAAqB;EACtD,CACF;CACF,GAEM,UAAiB,EAAW,EAAc,CAAC;CAQjD,OALI,KAAW,EAAc,GAE7B,EAAK,2BAA2B,KAAK,EAAS,CAAC,GAGxC;EACL,IAAI,UAAU;GACZ,OAAO;EACT;EAEA,IAAI,iBAAiB;GACnB,OAAO,EAAK;EACd;EAEA,eAAe;GAEb,AADA,EAAqB,GACrB,EAAK,QAAQ;EACf;EAEA,IAAI,WAAW;GACb,OAAO,EAAK;EACd;EAEA,KAAK,GAAQ;GACX,IAAM,IAAU,IAAQ,IAAI,EAAU,GAAQ,EAAU,GAAO,CAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,CAAM,CAAC;GAMvG,OAJI,MAAY,IAAa,QAAQ,QAAQ,KAE7C,IAAO,GAEA,EAAS;EAClB;EAEA,WAAW;GACT,IAAM,IAAO,EAAU,GAAO,CAAK;GAMnC,OAJI,MAAS,IAAa,QAAQ,QAAQ,KAE1C,IAAO,GAEA,EAAS;EAClB;EAEA,IAAI,OAAO;GACT,OAAO;EACT;EAEA,OAAO;GACL,IAAM,IAAQ,EAAU,GAAO,CAAK;GAMpC,OAJI,KAAQ,IAAc,QAAQ,QAAQ,KAE1C,KAEO,EAAS;EAClB;EAEA,iBAAiB,GAAS,GAAS;GACjC,IAAI,GAAY,QACd,MAAM,IAAI,EACR,+FACF;GAGF,IAAM,IAAY,GACZ,IAAY;GAElB,IAAa;IAAE,QAAQ;IAAM;IAAW;GAAU;GAElD,IAAI;IACF,IAAQ,EAAQ,CAAK;GACvB,SAAS,GAAY;IAEnB,MADA,IAAa,MACP;GACR;GAKA,OAHA,IAAQ,GAAS,SAAS,GAC1B,EAAgB,SAEH;IACX,AAAI,GAAY,WACd,EAAW,SAAS,IACpB,IAAQ,GACR,IAAQ,GACR,IAAa,MACb,EAAgB;GAEpB;EACF;EAEA,MAAM,GAAS;GACb,IAAI,IAAU;GAEd,IAAI,EAAQ,UAAU,KAAA,GAAW;IAC/B,IAAM,IAAO,KAAK,IAAI,GAAG,KAAK,MAAM,EAAQ,KAAK,CAAC;IAElD,AAAI,MAAS,MACX,IAAQ,GACR,IAAU;GAEd;GAmBA,IAjBI,YAAY,MACd,IAAS,EAAQ,QACjB,IAAU,KAGR,UAAU,MACZ,IAAO,EAAQ,MACf,IAAU,KAKR,YAAY,MAAY,EAAQ,WAAW,KAAU,EAAK,KAAK,iBACjE,IAAS,EAAQ,UAAU,IAC3B,IAAU,KAGR,EAAQ,SAAS,KAAA,GAAW;IAC9B,IAAM,IACJ,IAAQ,IAAI,EAAU,EAAQ,MAAM,EAAU,GAAO,CAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,EAAQ,IAAI,CAAC;IAErG,AAAI,MAAS,MACX,IAAO,GACP,IAAU;GAEd;GAiBA,OAfK,KAIL,EAAK,KAAK,YAAY,GACtB,EAAqB,IAIlB,EAAQ,UAAU,KAAA,KAAa,YAAY,KAAW,UAAU,KAAW,YAAY,MACxF,EAAQ,SAAS,KAAA,MAEjB,IAAO,IAGF,EAAS,KAfK,QAAQ,QAAQ;EAgBvC;EAEA,OAAO;GAKL,OAJI,KAAQ,IAAU,QAAQ,QAAQ,KAEtC,KAEO,EAAS;EAClB;EAEA,IAAI,QAAQ;GACV,OAAO;IACL,GAAI,MAAW,KAAA,KAAa,EAAE,UAAO;IACrC,GAAI,MAAS,KAAA,KAAa,EAAE,QAAK;IACjC,GAAI,KAAU,EAAE,UAAO;IACvB;IACA;GACF;EACF;EAEA,MAAM,GAAS;GACb,OAAO,EAAK,MAAM,CAAO;EAC3B;EAEA,UAAU;GACR,OAAO,EAAS;EAClB;EAEA,QAAQ;GAQN,OAPA,EAAK,KAAK,YAAY,GACtB,EAAqB,GACrB,IAAS,IACT,IAAO,GACP,IAAS,EAAI,QACb,IAAO,EAAI,MAEJ,EAAS;EAClB;EAEA,OAAO,GAAG,GAAqC;GAC7C,IAAI,GAAM,WAUR,OAPI,MAAM,KAAU,CAAC,EAAK,KAAK,cAAoB,QAAQ,QAAQ,KAEnE,EAAK,KAAK,YAAY,GACtB,EAAqB,GACrB,IAAS,GACT,IAAO,GAEA,EAAS;GAGlB,IAAI,MAAM,GAAQ,OAAO,QAAQ,QAAQ;GAKzC,AAHA,EAAqB,GAErB,IAAS,GACT,IAAO;GAEP,IAAI,GACE,IAAU,IAAI,SAAe,MAAQ;IACzC,IAAgB;GAClB,CAAC;GAOD,OALA,IAAgB;IAAE;IAAS,SAAS;GAAc,GAElD,EAAK,KAAK,eAAe,KAAK,EAAS,GAAG,CAAU,GACpD,EAAgB,GAET;EACT;EAEA,YAAY,MAAa,EAAK,KAAK,UAAU,CAAQ;GAEpD,OAAO,gBAAgB;GAEtB,AADA,EAAqB,GACrB,EAAK,QAAQ;EACf;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"remoteSource.js","names":[],"sources":["../src/remoteSource.ts"],"sourcesContent":["import type { RemoteConfig, RemoteSource, RemoteSourceQuery, SearchOptions } from './types';\n\nimport { defaultKeyOf, extractError, retry } from './_utils';\nimport { createAsyncSearchCoordinator } from './asyncSearch';\nimport { createAsyncSource } from './asyncSource';\nimport { SourcererError } from './errors';\nimport { clampPage, createMeta, pageCount } from './pagination';\n\n/** Creates a remote page-based source that fetches data from a network endpoint. */\nexport function createRemoteSource<T, TFilter = unknown, TSort = unknown>(\n cfg: RemoteConfig<T, TFilter, TSort>,\n): RemoteSource<T, TFilter, TSort> {\n const keyOf = cfg.queryKey ?? defaultKeyOf;\n\n // ── Config defaults ─────────────────────────────────────────────────────────\n const staleTimeMs = cfg.staleTime ?? 0;\n\n // ── Mutable state ───────────────────────────────────────────────────────────\n let limit = Math.max(1, Math.trunc(cfg.limit ?? 20));\n let page = 1;\n let search = '';\n let filter: TFilter | undefined = cfg.filter;\n let sort: TSort | undefined = cfg.sort;\n let items: readonly T[] = [];\n let total = 0;\n let error: SourcererError | null = null;\n let lastFetchTime = 0;\n let lastFetchKey = '';\n\n // Optimistic update state.\n let optimistic: { active: boolean; prevItems: readonly T[]; prevTotal: number } | null = null;\n\n // ── Snapshot pre-population ─────────────────────────────────────────────────\n if (cfg.snapshot) {\n items = cfg.snapshot.items;\n total = cfg.snapshot.total;\n\n if (cfg.snapshot.page !== undefined) page = cfg.snapshot.page;\n\n if (cfg.snapshot.search) search = cfg.snapshot.search;\n\n lastFetchTime = Date.now();\n }\n\n // ── Cached accessors ────────────────────────────────────────────────────────\n let cachedCurrent: readonly T[] = [];\n let cachedMeta = createMeta({\n error: null,\n isLoading: false,\n isSearchPending: false,\n pageNumber: 1,\n pageSize: limit,\n totalItems: 0,\n });\n\n const refreshMeta = () => {\n const pages = pageCount(total, limit);\n const safePage = clampPage(page, pages);\n\n // items is already the current page from the server — no local slicing needed.\n cachedCurrent = items;\n cachedMeta = createMeta({\n error,\n isLoading: base.pendingCount() > 0,\n isSearchPending: base.core.isScheduled,\n pageNumber: safePage,\n pageSize: limit,\n totalItems: total,\n });\n };\n\n // onBeforeNotify ensures refreshMeta() runs before any subscriber observes the new state,\n // eliminating the need for a parallel listeners Set.\n const base = createAsyncSource<RemoteSourceQuery<TFilter, TSort>>(cfg, keyOf, refreshMeta);\n const { autoFetch, debounceMs, retryAttempts, retryDelay } = base;\n\n // Initialise cache before first fetch.\n refreshMeta();\n\n const notifyListeners = () => {\n if (base.disposed) return;\n\n base.core.notify();\n };\n const searchCoordinator = createAsyncSearchCoordinator(base.core, notifyListeners);\n\n // ── Assign result ───────────────────────────────────────────────────────────\n const assign = (result: Readonly<{ items: readonly T[]; total: number }>) => {\n if (optimistic?.active) {\n optimistic.active = false;\n optimistic = null;\n }\n\n items = result.items;\n total = result.total;\n page = clampPage(page, pageCount(total, limit));\n };\n\n // ── Core fetch ──────────────────────────────────────────────────────────────\n const toRemoteQuery = (): RemoteSourceQuery<TFilter, TSort> => ({\n ...(filter !== undefined && { filter }),\n ...(sort !== undefined && { sort }),\n ...(search && { search }),\n limit,\n page,\n });\n\n const fetchQuery = (q: RemoteSourceQuery<TFilter, TSort>): Promise<void> => {\n const key = keyOf(q);\n\n if (\n staleTimeMs > 0 &&\n key === lastFetchKey &&\n total > 0 &&\n Date.now() - lastFetchTime < staleTimeMs &&\n !optimistic?.active\n ) {\n return Promise.resolve();\n }\n\n error = null;\n\n return base.fetch(\n q,\n async (q: RemoteSourceQuery<TFilter, TSort>, signal, isLatest) => {\n const startTime = Date.now();\n\n try {\n const result = await retry((sig) => cfg.fetch(q, sig!), {\n delay: retryDelay,\n signal,\n times: retryAttempts + 1,\n });\n\n if (isLatest()) {\n assign(result);\n error = null;\n lastFetchKey = key;\n lastFetchTime = Date.now();\n cfg.onFetch?.({ durationMs: Date.now() - startTime, query: q, status: 'success' });\n }\n } catch (reason: unknown) {\n if (signal.aborted) return;\n\n if (isLatest()) {\n if (optimistic?.active) {\n optimistic.active = false;\n items = optimistic.prevItems;\n total = optimistic.prevTotal;\n optimistic = null;\n } else {\n items = [];\n total = 0;\n }\n\n error = new SourcererError(extractError(reason), {\n cause: reason,\n context: { kind: 'remote', limit: q.limit, page: q.page, ...(q.search && { search: q.search }) },\n });\n cfg.onFetch?.({ durationMs: Date.now() - startTime, error, query: q, status: 'error' });\n }\n }\n },\n () => {\n notifyListeners();\n\n searchCoordinator.settleIfIdle(base.pendingCount());\n },\n );\n };\n\n const doUpdate = () => fetchQuery(toRemoteQuery());\n\n // ── Auto-fetch + refresh interval ───────────────────────────────────────────\n if (autoFetch) void doUpdate();\n\n base.startRefreshInterval(() => void doUpdate());\n\n // ── Public API ──────────────────────────────────────────────────────────────\n return {\n get current() {\n return cachedCurrent;\n },\n\n get disposalSignal() {\n return base.disposalSignal;\n },\n\n dispose: () => {\n searchCoordinator.cancel();\n searchCoordinator.dispose();\n base.dispose();\n },\n\n get disposed() {\n return base.disposed;\n },\n\n goTo(target) {\n const clamped = total > 0 ? clampPage(target, pageCount(total, limit)) : Math.max(1, Math.trunc(target));\n\n if (clamped === page) return Promise.resolve();\n\n page = clamped;\n\n return doUpdate();\n },\n\n goToLast() {\n const last = pageCount(total, limit);\n\n if (page === last) return Promise.resolve();\n\n page = last;\n\n return doUpdate();\n },\n\n get meta() {\n return cachedMeta;\n },\n\n next() {\n const pages = pageCount(total, limit);\n\n if (page >= pages) return Promise.resolve();\n\n page++;\n\n return doUpdate();\n },\n\n optimisticUpdate(mutator, options) {\n if (optimistic?.active) {\n throw new SourcererError(\n 'An optimistic update is already active. Rollback the previous update before starting another.',\n );\n }\n\n const prevItems = items;\n const prevTotal = total;\n\n optimistic = { active: true, prevItems, prevTotal };\n\n try {\n items = mutator(items);\n } catch (e: unknown) {\n optimistic = null;\n throw e;\n }\n\n total = options?.total ?? total;\n notifyListeners();\n\n return () => {\n if (optimistic?.active) {\n optimistic.active = false;\n items = prevItems;\n total = prevTotal;\n optimistic = null;\n notifyListeners();\n }\n };\n },\n\n patch(changes) {\n let changed = false;\n\n if (changes.limit !== undefined) {\n const next = Math.max(1, Math.trunc(changes.limit));\n\n if (next !== limit) {\n limit = next;\n changed = true;\n }\n }\n\n if ('filter' in changes) {\n filter = changes.filter;\n changed = true;\n }\n\n if ('sort' in changes) {\n sort = changes.sort;\n changed = true;\n }\n\n // `|| base.core.isScheduled` also catches patching in the same search text as an already-pending\n // debounced search() call — that still needs flushing, not silently dropping as a no-op.\n if ('search' in changes && (changes.search !== search || base.core.isScheduled)) {\n search = changes.search ?? '';\n changed = true;\n }\n\n if (changes.page !== undefined) {\n const next =\n total > 0 ? clampPage(changes.page, pageCount(total, limit)) : Math.max(1, Math.trunc(changes.page));\n\n if (next !== page) {\n page = next;\n changed = true;\n }\n }\n\n if (!changed) return Promise.resolve();\n\n // patch() is documented as a single atomic fetch — cancel any debounced search()\n // still pending so it doesn't fire a second, redundant fetch afterwards.\n searchCoordinator.cancel();\n\n // Reset to page 1 when non-page query fields changed without explicit page\n if (\n (changes.limit !== undefined || 'filter' in changes || 'sort' in changes || 'search' in changes) &&\n changes.page === undefined\n ) {\n page = 1;\n }\n\n return doUpdate();\n },\n\n prev() {\n if (page <= 1) return Promise.resolve();\n\n page--;\n\n return doUpdate();\n },\n\n get query() {\n return {\n ...(filter !== undefined && { filter }),\n ...(sort !== undefined && { sort }),\n ...(search && { search }),\n limit,\n page,\n };\n },\n\n ready(timeout) {\n return base.ready(timeout);\n },\n\n refresh() {\n return doUpdate();\n },\n\n reset() {\n searchCoordinator.cancel();\n search = '';\n page = 1;\n filter = cfg.filter;\n sort = cfg.sort;\n\n return doUpdate();\n },\n\n search(q, opts?: SearchOptions): Promise<void> {\n if (opts?.immediate) {\n // A pending debounced search for this same text still needs flushing —\n // `q === search` alone doesn't mean the fetch already happened.\n if (q === search && !base.core.isScheduled) return Promise.resolve();\n\n searchCoordinator.cancel();\n search = q;\n page = 1;\n\n return doUpdate();\n }\n\n if (q === search) return Promise.resolve();\n\n search = q;\n page = 1;\n\n return searchCoordinator.schedule(() => void doUpdate(), debounceMs);\n },\n\n subscribe: (listener) => base.core.subscribe(listener),\n\n [Symbol.dispose]: () => {\n searchCoordinator.cancel();\n searchCoordinator.dispose();\n base.dispose();\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/sourcerer.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@vielzeug/arsenal");function t(e,t){return e.patch(t)}var n=class e extends Error{#e;constructor(e,t={}){super(e,t.cause===void 0?void 0:{cause:t.cause}),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype),this.#e=t}get attempt(){return this.#e.attempt??0}get context(){return this.#e.context}static is(t){return t instanceof e}},r=class extends n{timeoutMs;constructor(e){super(`Source.ready() timed out after ${e}ms`),this.timeoutMs=e}},i=class extends n{constructor(){super(`Source disposed while waiting for ready()`)}},a=e=>{let t={...e.search&&{search:e.search},limit:String(e.limit),page:String(e.page)},n=e;return n.filter!==void 0&&(t.filter=JSON.stringify(n.filter)),n.sort!==void 0&&(t.sort=JSON.stringify(n.sort)),t},o=(e,t={})=>{let r=e instanceof URLSearchParams?Object.fromEntries(e.entries()):e,{defaultLimit:i=20,strict:a=!1}=t,o=(e,t)=>{if(e===void 0)return t;let n=Array.isArray(e)?e[0]:e,r=Number(n);return Number.isInteger(r)&&r>0?r:t},s=(e,t)=>{if(t===void 0)return;let r=Array.isArray(t)?t[0]:t;try{return JSON.parse(r)}catch{if(a)throw new n(`Invalid query param "${e}": ${r}`);return}},c=r.limit,l=r.page,u=r.search,d=r.filter,f=r.sort,p=d===void 0?void 0:s(`filter`,d),m=f===void 0?void 0:s(`sort`,f);return{...p!==void 0&&{filter:p},...m!==void 0&&{sort:m},...u!==void 0&&{search:Array.isArray(u)?u[0]:u},limit:o(c,i),page:o(l,1)}},s=e.hash,c=e=>e instanceof Error?e.message:typeof e==`string`&&e.length>0?e:`Request failed`,l=t=>(0,e.backoff)(t);function u(e){let t=new Set,n=new Set,a=new AbortController,o,s=!1;return{cancelTimer(){o&&=(clearTimeout(o),void 0)},get disposalSignal(){return a.signal},dispose(){o&&=(clearTimeout(o),void 0);for(let e of n)e.timeoutId!==void 0&&clearTimeout(e.timeoutId),e.reject(new i);n.clear(),t.clear(),s=!0,a.abort()},flush(e){return o?(clearTimeout(o),o=void 0,e()):Promise.resolve()},get isDisposed(){return s},get isScheduled(){return o!==void 0},notify(r){if(!s){(r??e?.onBeforeNotify)?.();for(let e of t)e();for(let e of n)e.check()}},ready(e,t){return s?Promise.reject(new i):e()?Promise.resolve():new Promise((i,a)=>{let o={check:()=>{e()&&(o.timeoutId!==void 0&&clearTimeout(o.timeoutId),n.delete(o),i())},reject:a};t!==void 0&&(o.timeoutId=setTimeout(()=>{n.delete(o),a(new r(t))},t)),n.add(o)})},schedule(e,t){s||(o&&clearTimeout(o),o=setTimeout(()=>{o=void 0,e()},t))},subscribe(e){return s?()=>{}:(t.add(e),()=>t.delete(e))}}}function d(e){let t=new Map,n=``,r=0;return{dispose(){for(let e of t.values())e.controller.abort();t.clear(),r=0},get pendingCount(){return r},async run(i,a,o){let s=e(i);n=s;for(let[e,n]of t)e!==s&&(n.controller.abort(),t.delete(e));let c=t.get(s);if(c){r++,o();try{await c.promise}finally{r--,o()}return}let l=new AbortController;r++,o();let u=a(i,l.signal,()=>s===n).finally(()=>{t.delete(s),r--,o()});t.set(s,{controller:l,promise:u}),await u}}}function f(e,t=s,n){let r=u({onBeforeNotify:n}),i=d(t),a=e.debounceMs??300,o=e.retry?.attempts??0,c=e.retry?.delay??l,f=e.autoFetch!==!1,p,m=()=>{r.isDisposed||(p!==void 0&&(clearInterval(p),p=void 0),i.dispose(),r.dispose())};return{autoFetch:f,core:r,debounceMs:a,get disposalSignal(){return r.disposalSignal},dispose:m,get disposed(){return r.isDisposed},fetch(e,t,n){return i.run(e,t,n)},pendingCount:()=>i.pendingCount,ready(e){return r.ready(()=>i.pendingCount===0&&!r.isScheduled,e)},retryAttempts:o,retryDelay:c,startRefreshInterval(t){e.refreshInterval!==void 0&&e.refreshInterval>0&&(p=setInterval(()=>{r.isDisposed||t()},e.refreshInterval))},[Symbol.dispose]:m}}function p(t){let r=t.queryKey??s,i=Math.max(1,Math.trunc(t.limit??20)),a=``,o,l,u,d,p=[],m=0,h=null,g=null,_=[],v={error:null,hasNextPage:!1,hasPrevPage:!1,isLoading:!1,isSearchPending:!1,pageSize:i,totalItems:0},y=()=>{_=p,v={error:h,hasNextPage:u!==void 0,hasPrevPage:d!==void 0,isLoading:b.pendingCount()>0,isSearchPending:b.core.isScheduled,pageSize:i,totalItems:m}},b=f(t,r,y),{autoFetch:x,debounceMs:S,retryAttempts:C,retryDelay:w}=b;y();let T=()=>{b.disposed||b.core.notify()},E=()=>{g&&=(g.resolve(),null)},D=()=>({...o!==void 0&&{after:o},...l!==void 0&&{before:l},...a&&{search:a},limit:i}),O=r=>(h=null,b.fetch(r,async(r,i,a)=>{let o=Date.now();try{let n=await(0,e.retry)(e=>t.fetch(r,e),{delay:w,signal:i,times:C+1});a()&&(p=n.items,m=n.total??n.items.length,u=n.nextCursor,d=n.prevCursor,h=null,t.onFetch?.({durationMs:Date.now()-o,query:r,status:`success`}))}catch(e){if(i.aborted)return;a()&&(p=[],m=0,u=void 0,d=void 0,h=new n(c(e),{cause:e,context:{kind:`cursor`,limit:r.limit,...r.search&&{search:r.search}}}),t.onFetch?.({durationMs:Date.now()-o,error:h,query:r,status:`error`}))}},()=>{T(),b.pendingCount()===0&&E()})),k=()=>O(D());return x&&k(),b.startRefreshInterval(()=>void k()),{get current(){return _},get disposalSignal(){return b.disposalSignal},dispose:()=>{E(),b.dispose()},get disposed(){return b.disposed},get meta(){return v},next(){return u?(o=u,l=void 0,k()):Promise.resolve()},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==i&&(i=n,o=void 0,l=void 0,t=!0)}return`search`in e&&(e.search!==a||b.core.isScheduled)&&(a=e.search??``,o=void 0,l=void 0,t=!0),t?(b.core.cancelTimer(),E(),k()):Promise.resolve()},prev(){return d?(l=d,o=void 0,k()):Promise.resolve()},get query(){return{...o!==void 0&&{after:o},...l!==void 0&&{before:l},...a&&{search:a},limit:i}},ready(e){return b.ready(e)},refresh(){return k()},reset(){return b.core.cancelTimer(),E(),a=``,o=void 0,l=void 0,k()},search(e,t){if(t?.immediate)return e===a&&!b.core.isScheduled?Promise.resolve():(b.core.cancelTimer(),E(),a=e,o=void 0,l=void 0,k());if(e===a)return Promise.resolve();E(),a=e,o=void 0,l=void 0;let n,r=new Promise(e=>{n=e});return g={promise:r,resolve:n},b.core.schedule(()=>void k(),S),T(),r},subscribe:e=>b.core.subscribe(e),[Symbol.dispose]:()=>{E(),b.dispose()}}}function m(e,t){let n=u(),r=[],i=()=>{r=t(e.current)};i();let a=e.subscribe(()=>{i(),n.notify()});`disposalSignal`in e&&e.disposalSignal instanceof AbortSignal&&e.disposalSignal.addEventListener(`abort`,()=>n.dispose(),{once:!0});let o={get current(){return r},get disposalSignal(){return n.disposalSignal},dispose(){n.isDisposed||(a(),n.dispose())},get disposed(){return n.isDisposed},get meta(){return e.meta},subscribe(e){return n.subscribe(e)},[Symbol.dispose](){o.dispose()}};return o}function h(t){let r=t.queryKey??s,i=Math.max(1,Math.trunc(t.limit??20)),a=``,o=1,l=0,u=[],d=0,p=null,m=!1,h=null,g=[],_={error:null,hasMore:!1,isLoading:!1,isLoadingMore:!1,isSearchPending:!1,loadedPages:0,pageSize:i,totalItems:0},v=()=>{g=u,_={error:p,hasMore:u.length<d,isLoading:y.pendingCount()>0&&!m,isLoadingMore:m,isSearchPending:y.core.isScheduled,loadedPages:l,pageSize:i,totalItems:d}},y=f(t,r,v),{autoFetch:b,debounceMs:x,retryAttempts:S,retryDelay:C}=y;v();let w=()=>{y.disposed||y.core.notify()},T=()=>{h&&=(h.resolve(),null)},E=(r,s)=>{let f={...a&&{search:a},limit:i,page:r};return p=null,y.fetch(f,async(i,a,f)=>{let h=Date.now();try{let n=await(0,e.retry)(e=>t.fetch(i,e),{delay:C,signal:a,times:S+1});f()&&(u=s?[...u,...n.items]:n.items,d=n.total,o=r,l=s?l+1:1,p=null,t.onFetch?.({durationMs:Date.now()-h,query:i,status:`success`}))}catch(e){if(a.aborted)return;f()&&(s||(u=[]),d=s?d:0,p=new n(c(e),{cause:e,context:{kind:`infinite`,limit:i.limit,page:i.page,...i.search&&{search:i.search}}}),t.onFetch?.({durationMs:Date.now()-h,error:p,query:i,status:`error`}))}finally{m=!1}},()=>{w(),y.pendingCount()===0&&T()})},D=()=>E(1,!1);return b&&D(),y.startRefreshInterval(()=>void D()),{get current(){return g},get disposalSignal(){return y.disposalSignal},dispose:()=>{T(),y.dispose()},get disposed(){return y.disposed},loadMore(){return!_.hasMore||y.pendingCount()>0||m?Promise.resolve():(m=!0,v(),E(o+1,!0))},get meta(){return _},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==i&&(i=n,t=!0)}return`search`in e&&(e.search!==a||y.core.isScheduled)&&(a=e.search??``,t=!0),t?(y.core.cancelTimer(),T(),u=[],d=0,o=1,l=0,D()):Promise.resolve()},get query(){return{...a&&{search:a},limit:i,page:o}},ready(e){return y.ready(e)},reset(){return y.core.cancelTimer(),T(),o=1,l=0,u=[],d=0,a=``,D()},search(e,t){if(t?.immediate)return e===a&&!y.core.isScheduled?Promise.resolve():(y.core.cancelTimer(),T(),a=e,u=[],d=0,l=0,o=1,D());if(e===a)return Promise.resolve();T(),a=e,u=[],d=0,l=0,o=1;let n,r=new Promise(e=>{n=e});return h={promise:r,resolve:n},y.core.schedule(()=>void D(),x),w(),r},subscribe:e=>y.core.subscribe(e),[Symbol.dispose]:()=>{T(),y.dispose()}}}var g=(e,t)=>{let n=Math.trunc(e);return Number.isFinite(n)?Math.max(t,n):t},_=(e,t)=>{let n=g(e,0),r=g(t,1);return Math.max(1,Math.ceil(n/r))},v=(e,t)=>Math.max(1,Math.min(g(e,1),Math.max(1,t))),y=e=>{let t=g(e.pageSize,1),n=g(e.totalItems,0),r=_(n,t),i=v(e.pageNumber,r);return{error:e.error,isLoading:e.isLoading,isSearchPending:e.isSearchPending,pageCount:r,pageNumber:i,pageSize:t,totalItems:n}};function b(e){if(e.totalItems===0)return{end:0,start:0};let t=(e.pageNumber-1)*e.pageSize+1;return{end:Math.min(e.pageNumber*e.pageSize,e.totalItems),start:t}}var x=20,S=300;function C(e,t){let n=t.toLowerCase();return e.filter(e=>JSON.stringify(e).toLowerCase().includes(n))}function w(e,t={}){let r=u(),i=t.filterAsync!==void 0||t.sortAsync!==void 0,a=t.debounceMs??S,o=t.initialData??e,s=``,l=t.filter,d=t.sort,f=t.limit??x,p=1,m=[],h=!1,g=!1,b=null,w=null,T=null,E=()=>r.notify(),D=()=>{T&&=(T.resolve(),null)},O=()=>{let e=o;return s&&(e=(t.searchFn??C)(e,s)),l&&(e=e.filter(l)),d&&(e=[...e].sort(d)),e},k=()=>{m=O();let e=_(m.length,f);p=v(p,e)},A=async()=>{w?.abort();let e=new AbortController;w=e,h=!0,b=null,E();try{let n=o;if(s&&(n=(t.searchFn??C)(n,s)),l&&(n=n.filter(l)),t.filterAsync&&!e.signal.aborted&&(n=await t.filterAsync(n,e.signal)),d&&(n=[...n].sort(d)),t.sortAsync&&!e.signal.aborted&&(n=await t.sortAsync(n,e.signal)),e.signal.aborted)return;m=n,h=!1,g=!1;let r=_(m.length,f);p=v(p,r)}catch(t){e.signal.aborted||(h=!1,g=!1,b=new n(c(t),{cause:t}))}finally{w===e&&(w=null)}E(),D()},j=()=>i?A():(g=!1,k(),E(),D(),Promise.resolve());i?(m=O(),A()):k();let M={get current(){let e=(p-1)*f;return m.slice(e,e+f)},get disposalSignal(){return r.disposalSignal},dispose(){r.isDisposed||(r.cancelTimer(),w?.abort(),w=null,D(),r.dispose())},get disposed(){return r.isDisposed},goTo(e){let t=v(e,_(m.length,f));return t===p?Promise.resolve():(p=t,E(),Promise.resolve())},goToLast(){return M.goTo(_(m.length,f))},get meta(){return y({error:b,isLoading:h,isSearchPending:g,pageNumber:p,pageSize:f,totalItems:m.length})},next(){return M.goTo(p+1)},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==f&&(f=n,t=!0)}if(`filter`in e&&(l=e.filter,t=!0),`sort`in e&&(d=e.sort,t=!0),`search`in e&&(e.search!==s||r.isScheduled)&&(s=e.search??``,t=!0),e.page!==void 0){let n=v(e.page,_(m.length,f));n!==p&&(p=n,t=!0)}return t?(r.cancelTimer(),D(),(e.limit!==void 0||`filter`in e||`sort`in e||`search`in e)&&e.page===void 0&&(p=1),j()):Promise.resolve()},prev(){return M.goTo(p-1)},get query(){return{limit:f,page:p,...s&&{search:s}}},ready(e){return r.ready(()=>!h&&!r.isScheduled,e)},reset(){return r.cancelTimer(),g=!1,s=``,l=t.filter,d=t.sort,p=1,D(),j()},search(e,t){if(t?.immediate)return e===s&&!r.isScheduled?Promise.resolve():(r.cancelTimer(),g=!1,s=e,p=1,D(),j());if(e===s)return Promise.resolve();D(),s=e,p=1,g=!0,E();let n,i=new Promise(e=>{n=e});return T={promise:i,resolve:n},r.schedule(()=>{g=!1,j()},a),i},setData(e){return o=e,p=1,j()},subscribe(e){return r.subscribe(e)},[Symbol.dispose](){M.dispose()}};return M}function T(e,t){let n=u(),r=t(e.map(e=>e.current)),i=e.map(i=>i.subscribe(()=>{r=t(e.map(e=>e.current)),n.notify()})),a={get current(){return r},get disposalSignal(){return n.disposalSignal},dispose(){if(!n.isDisposed){for(let e of i)e();n.dispose()}},get disposed(){return n.isDisposed},subscribe(e){return n.subscribe(e)},[Symbol.dispose](){a.dispose()}};return a}function E(t){let r=t.queryKey??s,i=t.staleTime??0,a=Math.max(1,Math.trunc(t.limit??20)),o=1,l=``,u=t.filter,d=t.sort,p=[],m=0,h=null,g=0,b=``,x=null,S=null;t.snapshot&&(p=t.snapshot.items,m=t.snapshot.total,t.snapshot.page!==void 0&&(o=t.snapshot.page),t.snapshot.search&&(l=t.snapshot.search),g=Date.now());let C=[],w=y({error:null,isLoading:!1,isSearchPending:!1,pageNumber:1,pageSize:a,totalItems:0}),T=()=>{let e=_(m,a),t=v(o,e);C=p,w=y({error:h,isLoading:E.pendingCount()>0,isSearchPending:E.core.isScheduled,pageNumber:t,pageSize:a,totalItems:m})},E=f(t,r,T),{autoFetch:D,debounceMs:O,retryAttempts:k,retryDelay:A}=E;T();let j=()=>{E.disposed||E.core.notify()},M=e=>{S?.active&&(S.active=!1,S=null),p=e.items,m=e.total,o=v(o,_(m,a))},N=()=>{x&&=(x.resolve(),null)},P=()=>({...u!==void 0&&{filter:u},...d!==void 0&&{sort:d},...l&&{search:l},limit:a,page:o}),F=a=>{let o=r(a);return i>0&&o===b&&m>0&&Date.now()-g<i?Promise.resolve():(h=null,E.fetch(a,async(r,i,a)=>{let s=Date.now();try{let n=await(0,e.retry)(e=>t.fetch(r,e),{delay:A,signal:i,times:k+1});a()&&(M(n),h=null,b=o,g=Date.now(),t.onFetch?.({durationMs:Date.now()-s,query:r,status:`success`}))}catch(e){if(i.aborted)return;a()&&(S?.active?(S.active=!1,p=S.prevItems,m=S.prevTotal,S=null):(p=[],m=0),h=new n(c(e),{cause:e,context:{kind:`remote`,limit:r.limit,page:r.page,...r.search&&{search:r.search}}}),t.onFetch?.({durationMs:Date.now()-s,error:h,query:r,status:`error`}))}},()=>{j(),E.pendingCount()===0&&N()}))},I=()=>F(P());return D&&I(),E.startRefreshInterval(()=>void I()),{get current(){return C},get disposalSignal(){return E.disposalSignal},dispose:()=>{N(),E.dispose()},get disposed(){return E.disposed},goTo(e){let t=m>0?v(e,_(m,a)):Math.max(1,Math.trunc(e));return t===o?Promise.resolve():(o=t,I())},goToLast(){let e=_(m,a);return o===e?Promise.resolve():(o=e,I())},get meta(){return w},next(){let e=_(m,a);return o>=e?Promise.resolve():(o++,I())},optimisticUpdate(e,t){if(S?.active)throw new n(`An optimistic update is already active. Rollback the previous update before starting another.`);let r=p,i=m;S={active:!0,prevItems:r,prevTotal:i};try{p=e(p)}catch(e){throw S=null,e}return m=t?.total??m,j(),()=>{S?.active&&(S.active=!1,p=r,m=i,S=null,j())}},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==a&&(a=n,t=!0)}if(`filter`in e&&(u=e.filter,t=!0),`sort`in e&&(d=e.sort,t=!0),`search`in e&&(e.search!==l||E.core.isScheduled)&&(l=e.search??``,t=!0),e.page!==void 0){let n=m>0?v(e.page,_(m,a)):Math.max(1,Math.trunc(e.page));n!==o&&(o=n,t=!0)}return t?(E.core.cancelTimer(),N(),(e.limit!==void 0||`filter`in e||`sort`in e||`search`in e)&&e.page===void 0&&(o=1),I()):Promise.resolve()},prev(){return o<=1?Promise.resolve():(o--,I())},get query(){return{...u!==void 0&&{filter:u},...d!==void 0&&{sort:d},...l&&{search:l},limit:a,page:o}},ready(e){return E.ready(e)},refresh(){return I()},reset(){return E.core.cancelTimer(),N(),l=``,o=1,u=t.filter,d=t.sort,I()},search(e,t){if(t?.immediate)return e===l&&!E.core.isScheduled?Promise.resolve():(E.core.cancelTimer(),N(),l=e,o=1,I());if(e===l)return Promise.resolve();N(),l=e,o=1;let n,r=new Promise(e=>{n=e});return x={promise:r,resolve:n},E.core.schedule(()=>void I(),O),j(),r},subscribe:e=>E.core.subscribe(e),[Symbol.dispose]:()=>{N(),E.dispose()}}}var D=e=>{let t=e.query;return{items:e.current,...t.search&&{search:t.search},page:e.meta.pageNumber,total:e.meta.totalItems}};async function O(e){let t=E({...e,autoFetch:!1});try{if(await t.refresh(),t.meta.error)throw t.meta.error;return D(t)}finally{t.dispose()}}async function k(e){let t=E({...e,autoFetch:!1});if(await t.refresh(),t.meta.error)throw t.dispose(),t.meta.error;return{snapshot:D(t),source:t}}var A=(e,t,n=!1)=>{let r=n?t:t.toLowerCase();return t=>{let i=e(t)??``;return(n?i:i.toLowerCase()).includes(r)}},j=(e,t)=>n=>Object.is(e(n),t),M=(e,t)=>{let n=e=>e instanceof Date?e.getTime():e,r=t.min===void 0?void 0:n(t.min),i=t.max===void 0?void 0:n(t.max);return t=>{let a=n(e(t));return!(r!==void 0&&a<r||i!==void 0&&a>i)}},N=(e,t=`asc`)=>{let n=t===`asc`?1:-1;return(t,r)=>{let i=e(t),a=e(r);return i instanceof Date&&a instanceof Date?(i.getTime()-a.getTime())*n:i<a?-1*n:i>a?1*n:0}};function P(e){return e.meta.isLoading||e.meta.isSearchPending?{status:`loading`}:e.meta.error?{error:e.meta.error,status:`error`}:{items:e.current,status:`success`}}exports.SourceDisposedError=i,exports.SourceTimeoutError=r,exports.SourcererError=n,exports.applyQuery=t,exports.createCursorSource=p,exports.createInfiniteSource=h,exports.createLocalSource=w,exports.createRemoteSource=E,exports.decodeQuery=o,exports.deriveSource=m,exports.encodeQuery=a,exports.filterContains=A,exports.filterEquals=j,exports.filterRange=M,exports.itemRange=b,exports.mergeSource=T,exports.prefetchSource=O,exports.prefetchSourceAndKeep=k,exports.sortBy=N,exports.sourceState=P;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@vielzeug/arsenal");function t(e,t){return e.patch(t)}var n=class e extends Error{#e;constructor(e,t={}){super(e,t.cause===void 0?void 0:{cause:t.cause}),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype),this.#e=t}get attempt(){return this.#e.attempt??0}get context(){return this.#e.context}static is(t){return t instanceof e}},r=class extends n{timeoutMs;constructor(e){super(`Source.ready() timed out after ${e}ms`),this.timeoutMs=e}},i=class extends n{constructor(){super(`Source disposed while waiting for ready()`)}},a=e=>{let t={...e.search&&{search:e.search},limit:String(e.limit),page:String(e.page)},n=e;return n.filter!==void 0&&(t.filter=JSON.stringify(n.filter)),n.sort!==void 0&&(t.sort=JSON.stringify(n.sort)),t},o=(e,t={})=>{let r=e instanceof URLSearchParams?Object.fromEntries(e.entries()):e,{defaultLimit:i=20,strict:a=!1}=t,o=(e,t)=>{if(e===void 0)return t;let n=Array.isArray(e)?e[0]:e,r=Number(n);return Number.isInteger(r)&&r>0?r:t},s=(e,t)=>{if(t===void 0)return;let r=Array.isArray(t)?t[0]:t;try{return JSON.parse(r)}catch{if(a)throw new n(`Invalid query param "${e}": ${r}`);return}},c=r.limit,l=r.page,u=r.search,d=r.filter,f=r.sort,p=d===void 0?void 0:s(`filter`,d),m=f===void 0?void 0:s(`sort`,f);return{...p!==void 0&&{filter:p},...m!==void 0&&{sort:m},...u!==void 0&&{search:Array.isArray(u)?u[0]:u},limit:o(c,i),page:o(l,1)}},s=e.hash,c=e=>e instanceof Error?e.message:typeof e==`string`&&e.length>0?e:`Request failed`,l=t=>(0,e.backoff)(t);function u(e,t){let n=null,r=()=>{n&&=(n(),null)};return{cancel(){e.cancelTimer(),r()},dispose(){r()},schedule(i,a){r();let o=new Promise(e=>{n=e});return e.schedule(i,a),t(),o},settleIfIdle(e){e===0&&r()}}}function d(e){let t=new Set,n=new Set,a=new AbortController,o,s=!1;return{cancelTimer(){o&&=(clearTimeout(o),void 0)},get disposalSignal(){return a.signal},dispose(){o&&=(clearTimeout(o),void 0);for(let e of n)e.timeoutId!==void 0&&clearTimeout(e.timeoutId),e.reject(new i);n.clear(),t.clear(),s=!0,a.abort()},flush(e){return o?(clearTimeout(o),o=void 0,e()):Promise.resolve()},get isDisposed(){return s},get isScheduled(){return o!==void 0},notify(r){if(!s){(r??e?.onBeforeNotify)?.();for(let e of t)e();for(let e of n)e.check()}},ready(e,t){return s?Promise.reject(new i):e()?Promise.resolve():new Promise((i,a)=>{let o={check:()=>{e()&&(o.timeoutId!==void 0&&clearTimeout(o.timeoutId),n.delete(o),i())},reject:a};t!==void 0&&(o.timeoutId=setTimeout(()=>{n.delete(o),a(new r(t))},t)),n.add(o)})},schedule(e,t){s||(o&&clearTimeout(o),o=setTimeout(()=>{o=void 0,e()},t))},subscribe(e){return s?()=>{}:(t.add(e),()=>t.delete(e))}}}function f(e){let t=new Map,n=``,r=0;return{dispose(){for(let e of t.values())e.controller.abort();t.clear(),r=0},get pendingCount(){return r},async run(i,a,o){let s=e(i);n=s;for(let[e,n]of t)e!==s&&(n.controller.abort(),t.delete(e));let c=t.get(s);if(c){r++,o();try{await c.promise}finally{r--,o()}return}let l=new AbortController;r++,o();let u=a(i,l.signal,()=>s===n).finally(()=>{t.delete(s),r--,o()});t.set(s,{controller:l,promise:u}),await u}}}function p(e,t=s,n){let r=d({onBeforeNotify:n}),i=f(t),a=e.debounceMs??300,o=e.retry?.attempts??0,c=e.retry?.delay??l,u=e.autoFetch!==!1,p,m=()=>{r.isDisposed||(p!==void 0&&(clearInterval(p),p=void 0),i.dispose(),r.dispose())};return{autoFetch:u,core:r,debounceMs:a,get disposalSignal(){return r.disposalSignal},dispose:m,get disposed(){return r.isDisposed},fetch(e,t,n){return i.run(e,t,n)},pendingCount:()=>i.pendingCount,ready(e){return r.ready(()=>i.pendingCount===0&&!r.isScheduled,e)},retryAttempts:o,retryDelay:c,startRefreshInterval(t){e.refreshInterval!==void 0&&e.refreshInterval>0&&(p=setInterval(()=>{r.isDisposed||t()},e.refreshInterval))},[Symbol.dispose]:m}}function m(t){let r=t.queryKey??s,i=Math.max(1,Math.trunc(t.limit??20)),a=``,o,l,d,f,m=[],h=0,g=null,_=[],v={error:null,hasNextPage:!1,hasPrevPage:!1,isLoading:!1,isSearchPending:!1,pageSize:i,totalItems:0},y=()=>{_=m,v={error:g,hasNextPage:d!==void 0,hasPrevPage:f!==void 0,isLoading:b.pendingCount()>0,isSearchPending:b.core.isScheduled,pageSize:i,totalItems:h}},b=p(t,r,y),{autoFetch:x,debounceMs:S,retryAttempts:C,retryDelay:w}=b;y();let T=()=>{b.disposed||b.core.notify()},E=u(b.core,T),D=()=>({...o!==void 0&&{after:o},...l!==void 0&&{before:l},...a&&{search:a},limit:i}),O=r=>(g=null,b.fetch(r,async(r,i,a)=>{let o=Date.now();try{let n=await(0,e.retry)(e=>t.fetch(r,e),{delay:w,signal:i,times:C+1});a()&&(m=n.items,h=n.total??n.items.length,d=n.nextCursor,f=n.prevCursor,g=null,t.onFetch?.({durationMs:Date.now()-o,query:r,status:`success`}))}catch(e){if(i.aborted)return;a()&&(m=[],h=0,d=void 0,f=void 0,g=new n(c(e),{cause:e,context:{kind:`cursor`,limit:r.limit,...r.search&&{search:r.search}}}),t.onFetch?.({durationMs:Date.now()-o,error:g,query:r,status:`error`}))}},()=>{T(),E.settleIfIdle(b.pendingCount())})),k=()=>O(D());return x&&k(),b.startRefreshInterval(()=>void k()),{get current(){return _},get disposalSignal(){return b.disposalSignal},dispose:()=>{E.cancel(),E.dispose(),b.dispose()},get disposed(){return b.disposed},get meta(){return v},next(){return d?(o=d,l=void 0,k()):Promise.resolve()},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==i&&(i=n,o=void 0,l=void 0,t=!0)}return`search`in e&&(e.search!==a||b.core.isScheduled)&&(a=e.search??``,o=void 0,l=void 0,t=!0),t?(E.cancel(),k()):Promise.resolve()},prev(){return f?(l=f,o=void 0,k()):Promise.resolve()},get query(){return{...o!==void 0&&{after:o},...l!==void 0&&{before:l},...a&&{search:a},limit:i}},ready(e){return b.ready(e)},refresh(){return k()},reset(){return E.cancel(),a=``,o=void 0,l=void 0,k()},search(e,t){return t?.immediate?e===a&&!b.core.isScheduled?Promise.resolve():(E.cancel(),a=e,o=void 0,l=void 0,k()):e===a?Promise.resolve():(a=e,o=void 0,l=void 0,E.schedule(()=>void k(),S))},subscribe:e=>b.core.subscribe(e),[Symbol.dispose]:()=>{E.cancel(),E.dispose(),b.dispose()}}}function h(e,t){let n=d(),r=[],i=()=>{r=t(e.current)};i();let a=e.subscribe(()=>{i(),n.notify()});`disposalSignal`in e&&e.disposalSignal instanceof AbortSignal&&e.disposalSignal.addEventListener(`abort`,()=>n.dispose(),{once:!0});let o={get current(){return r},get disposalSignal(){return n.disposalSignal},dispose(){n.isDisposed||(a(),n.dispose())},get disposed(){return n.isDisposed},get meta(){return e.meta},subscribe(e){return n.subscribe(e)},[Symbol.dispose](){o.dispose()}};return o}function g(t){let r=t.queryKey??s,i=Math.max(1,Math.trunc(t.limit??20)),a=``,o=1,l=0,d=[],f=0,m=null,h=!1,g=[],_={error:null,hasMore:!1,isLoading:!1,isLoadingMore:!1,isSearchPending:!1,loadedPages:0,pageSize:i,totalItems:0},v=()=>{g=d,_={error:m,hasMore:d.length<f,isLoading:y.pendingCount()>0&&!h,isLoadingMore:h,isSearchPending:y.core.isScheduled,loadedPages:l,pageSize:i,totalItems:f}},y=p(t,r,v),{autoFetch:b,debounceMs:x,retryAttempts:S,retryDelay:C}=y;v();let w=()=>{y.disposed||y.core.notify()},T=u(y.core,w),E=(r,s)=>{let u={...a&&{search:a},limit:i,page:r};return m=null,y.fetch(u,async(i,a,u)=>{let p=Date.now();try{let n=await(0,e.retry)(e=>t.fetch(i,e),{delay:C,signal:a,times:S+1});u()&&(d=s?[...d,...n.items]:n.items,f=n.total,o=r,l=s?l+1:1,m=null,t.onFetch?.({durationMs:Date.now()-p,query:i,status:`success`}))}catch(e){if(a.aborted)return;u()&&(s||(d=[]),f=s?f:0,m=new n(c(e),{cause:e,context:{kind:`infinite`,limit:i.limit,page:i.page,...i.search&&{search:i.search}}}),t.onFetch?.({durationMs:Date.now()-p,error:m,query:i,status:`error`}))}finally{h=!1}},()=>{w(),T.settleIfIdle(y.pendingCount())})},D=()=>E(1,!1);return b&&D(),y.startRefreshInterval(()=>void D()),{get current(){return g},get disposalSignal(){return y.disposalSignal},dispose:()=>{T.cancel(),T.dispose(),y.dispose()},get disposed(){return y.disposed},loadMore(){return!_.hasMore||y.pendingCount()>0||h?Promise.resolve():(h=!0,v(),E(o+1,!0))},get meta(){return _},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==i&&(i=n,t=!0)}return`search`in e&&(e.search!==a||y.core.isScheduled)&&(a=e.search??``,t=!0),t?(T.cancel(),d=[],f=0,o=1,l=0,D()):Promise.resolve()},get query(){return{...a&&{search:a},limit:i,page:o}},ready(e){return y.ready(e)},reset(){return T.cancel(),o=1,l=0,d=[],f=0,a=``,D()},search(e,t){return t?.immediate?e===a&&!y.core.isScheduled?Promise.resolve():(T.cancel(),a=e,d=[],f=0,l=0,o=1,D()):e===a?Promise.resolve():(a=e,d=[],f=0,l=0,o=1,T.schedule(()=>void D(),x))},subscribe:e=>y.core.subscribe(e),[Symbol.dispose]:()=>{T.cancel(),T.dispose(),y.dispose()}}}var _=(e,t)=>{let n=Math.trunc(e);return Number.isFinite(n)?Math.max(t,n):t},v=(e,t)=>{let n=_(e,0),r=_(t,1);return Math.max(1,Math.ceil(n/r))},y=(e,t)=>Math.max(1,Math.min(_(e,1),Math.max(1,t))),b=e=>{let t=_(e.pageSize,1),n=_(e.totalItems,0),r=v(n,t),i=y(e.pageNumber,r);return{error:e.error,isLoading:e.isLoading,isSearchPending:e.isSearchPending,pageCount:r,pageNumber:i,pageSize:t,totalItems:n}};function x(e){if(e.totalItems===0)return{end:0,start:0};let t=(e.pageNumber-1)*e.pageSize+1;return{end:Math.min(e.pageNumber*e.pageSize,e.totalItems),start:t}}var S=20,C=300;function w(e,t){let n=t.toLowerCase();return e.filter(e=>JSON.stringify(e).toLowerCase().includes(n))}function T(e,t={}){let r=d(),i=t.filterAsync!==void 0||t.sortAsync!==void 0,a=t.debounceMs??C,o=t.initialData??e,s=``,l=t.filter,u=t.sort,f=t.limit??S,p=1,m=[],h=!1,g=!1,_=null,x=null,T=null,E=()=>r.notify(),D=()=>{T&&=(T.resolve(),null)},O=()=>{let e=o;return s&&(e=(t.searchFn??w)(e,s)),l&&(e=e.filter(l)),u&&(e=[...e].sort(u)),e},k=()=>{m=O();let e=v(m.length,f);p=y(p,e)},A=async()=>{x?.abort();let e=new AbortController;x=e,h=!0,_=null,E();try{let n=o;if(s&&(n=(t.searchFn??w)(n,s)),l&&(n=n.filter(l)),t.filterAsync&&!e.signal.aborted&&(n=await t.filterAsync(n,e.signal)),u&&(n=[...n].sort(u)),t.sortAsync&&!e.signal.aborted&&(n=await t.sortAsync(n,e.signal)),e.signal.aborted)return;m=n,h=!1,g=!1;let r=v(m.length,f);p=y(p,r)}catch(t){e.signal.aborted||(h=!1,g=!1,_=new n(c(t),{cause:t}))}finally{x===e&&(x=null)}E(),D()},j=()=>i?A():(g=!1,k(),E(),D(),Promise.resolve());i?(m=O(),A()):k();let M={get current(){let e=(p-1)*f;return m.slice(e,e+f)},get disposalSignal(){return r.disposalSignal},dispose(){r.isDisposed||(r.cancelTimer(),x?.abort(),x=null,D(),r.dispose())},get disposed(){return r.isDisposed},goTo(e){let t=y(e,v(m.length,f));return t===p?Promise.resolve():(p=t,E(),Promise.resolve())},goToLast(){return M.goTo(v(m.length,f))},get meta(){return b({error:_,isLoading:h,isSearchPending:g,pageNumber:p,pageSize:f,totalItems:m.length})},next(){return M.goTo(p+1)},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==f&&(f=n,t=!0)}if(`filter`in e&&(l=e.filter,t=!0),`sort`in e&&(u=e.sort,t=!0),`search`in e&&(e.search!==s||r.isScheduled)&&(s=e.search??``,t=!0),e.page!==void 0){let n=y(e.page,v(m.length,f));n!==p&&(p=n,t=!0)}return t?(r.cancelTimer(),D(),(e.limit!==void 0||`filter`in e||`sort`in e||`search`in e)&&e.page===void 0&&(p=1),j()):Promise.resolve()},prev(){return M.goTo(p-1)},get query(){return{limit:f,page:p,...s&&{search:s}}},ready(e){return r.ready(()=>!h&&!r.isScheduled,e)},reset(){return r.cancelTimer(),g=!1,s=``,l=t.filter,u=t.sort,p=1,D(),j()},search(e,t){if(t?.immediate)return e===s&&!r.isScheduled?Promise.resolve():(r.cancelTimer(),g=!1,s=e,p=1,D(),j());if(e===s)return Promise.resolve();D(),s=e,p=1,g=!0,E();let n,i=new Promise(e=>{n=e});return T={promise:i,resolve:n},r.schedule(()=>{g=!1,j()},a),i},setData(e){return o=e,p=1,j()},subscribe(e){return r.subscribe(e)},[Symbol.dispose](){M.dispose()}};return M}function E(e,t){let n=d(),r=t(e.map(e=>e.current)),i=e.map(i=>i.subscribe(()=>{r=t(e.map(e=>e.current)),n.notify()})),a={get current(){return r},get disposalSignal(){return n.disposalSignal},dispose(){if(!n.isDisposed){for(let e of i)e();n.dispose()}},get disposed(){return n.isDisposed},subscribe(e){return n.subscribe(e)},[Symbol.dispose](){a.dispose()}};return a}function D(t){let r=t.queryKey??s,i=t.staleTime??0,a=Math.max(1,Math.trunc(t.limit??20)),o=1,l=``,d=t.filter,f=t.sort,m=[],h=0,g=null,_=0,x=``,S=null;t.snapshot&&(m=t.snapshot.items,h=t.snapshot.total,t.snapshot.page!==void 0&&(o=t.snapshot.page),t.snapshot.search&&(l=t.snapshot.search),_=Date.now());let C=[],w=b({error:null,isLoading:!1,isSearchPending:!1,pageNumber:1,pageSize:a,totalItems:0}),T=()=>{let e=v(h,a),t=y(o,e);C=m,w=b({error:g,isLoading:E.pendingCount()>0,isSearchPending:E.core.isScheduled,pageNumber:t,pageSize:a,totalItems:h})},E=p(t,r,T),{autoFetch:D,debounceMs:O,retryAttempts:k,retryDelay:A}=E;T();let j=()=>{E.disposed||E.core.notify()},M=u(E.core,j),N=e=>{S?.active&&(S.active=!1,S=null),m=e.items,h=e.total,o=y(o,v(h,a))},P=()=>({...d!==void 0&&{filter:d},...f!==void 0&&{sort:f},...l&&{search:l},limit:a,page:o}),F=a=>{let o=r(a);return i>0&&o===x&&h>0&&Date.now()-_<i&&!S?.active?Promise.resolve():(g=null,E.fetch(a,async(r,i,a)=>{let s=Date.now();try{let n=await(0,e.retry)(e=>t.fetch(r,e),{delay:A,signal:i,times:k+1});a()&&(N(n),g=null,x=o,_=Date.now(),t.onFetch?.({durationMs:Date.now()-s,query:r,status:`success`}))}catch(e){if(i.aborted)return;a()&&(S?.active?(S.active=!1,m=S.prevItems,h=S.prevTotal,S=null):(m=[],h=0),g=new n(c(e),{cause:e,context:{kind:`remote`,limit:r.limit,page:r.page,...r.search&&{search:r.search}}}),t.onFetch?.({durationMs:Date.now()-s,error:g,query:r,status:`error`}))}},()=>{j(),M.settleIfIdle(E.pendingCount())}))},I=()=>F(P());return D&&I(),E.startRefreshInterval(()=>void I()),{get current(){return C},get disposalSignal(){return E.disposalSignal},dispose:()=>{M.cancel(),M.dispose(),E.dispose()},get disposed(){return E.disposed},goTo(e){let t=h>0?y(e,v(h,a)):Math.max(1,Math.trunc(e));return t===o?Promise.resolve():(o=t,I())},goToLast(){let e=v(h,a);return o===e?Promise.resolve():(o=e,I())},get meta(){return w},next(){let e=v(h,a);return o>=e?Promise.resolve():(o++,I())},optimisticUpdate(e,t){if(S?.active)throw new n(`An optimistic update is already active. Rollback the previous update before starting another.`);let r=m,i=h;S={active:!0,prevItems:r,prevTotal:i};try{m=e(m)}catch(e){throw S=null,e}return h=t?.total??h,j(),()=>{S?.active&&(S.active=!1,m=r,h=i,S=null,j())}},patch(e){let t=!1;if(e.limit!==void 0){let n=Math.max(1,Math.trunc(e.limit));n!==a&&(a=n,t=!0)}if(`filter`in e&&(d=e.filter,t=!0),`sort`in e&&(f=e.sort,t=!0),`search`in e&&(e.search!==l||E.core.isScheduled)&&(l=e.search??``,t=!0),e.page!==void 0){let n=h>0?y(e.page,v(h,a)):Math.max(1,Math.trunc(e.page));n!==o&&(o=n,t=!0)}return t?(M.cancel(),(e.limit!==void 0||`filter`in e||`sort`in e||`search`in e)&&e.page===void 0&&(o=1),I()):Promise.resolve()},prev(){return o<=1?Promise.resolve():(o--,I())},get query(){return{...d!==void 0&&{filter:d},...f!==void 0&&{sort:f},...l&&{search:l},limit:a,page:o}},ready(e){return E.ready(e)},refresh(){return I()},reset(){return M.cancel(),l=``,o=1,d=t.filter,f=t.sort,I()},search(e,t){return t?.immediate?e===l&&!E.core.isScheduled?Promise.resolve():(M.cancel(),l=e,o=1,I()):e===l?Promise.resolve():(l=e,o=1,M.schedule(()=>void I(),O))},subscribe:e=>E.core.subscribe(e),[Symbol.dispose]:()=>{M.cancel(),M.dispose(),E.dispose()}}}var O=e=>{let t=e.query;return{items:e.current,...t.search&&{search:t.search},page:e.meta.pageNumber,total:e.meta.totalItems}};async function k(e){let t=D({...e,autoFetch:!1});try{if(await t.refresh(),t.meta.error)throw t.meta.error;return O(t)}finally{t.dispose()}}async function A(e){let t=D({...e,autoFetch:!1});if(await t.refresh(),t.meta.error)throw t.dispose(),t.meta.error;return{snapshot:O(t),source:t}}var j=e=>{if(e==null)return``;if(typeof e==`bigint`||typeof e==`boolean`||typeof e==`number`||typeof e==`string`)return String(e);if(e instanceof Date)return e.toISOString();try{return JSON.stringify(e)??``}catch{return String(e)}},M=(e,t,n=!1)=>{let r=n?t:t.toLowerCase();return t=>{let i=e(t)??``;return(n?i:i.toLowerCase()).includes(r)}},N=(e,t)=>n=>Object.is(e(n),t),P=(e,t)=>{let n=e=>e instanceof Date?e.getTime():e,r=t.min===void 0?void 0:n(t.min),i=t.max===void 0?void 0:n(t.max);return t=>{let a=n(e(t));return!(r!==void 0&&a<r||i!==void 0&&a>i)}},F=(e,t=`asc`)=>{let n=t===`asc`?1:-1;return(t,r)=>{let i=e(t),a=e(r);return i instanceof Date&&a instanceof Date?(i.getTime()-a.getTime())*n:i<a?-1*n:i>a?1*n:0}},I=(e,t={})=>{let n=Array.isArray(e)?e:[e],r=t.caseSensitive===!0;return(e,t)=>{if(t.length===0)return e;let i=r?t:t.toLowerCase();return e.filter(e=>n.some(t=>{let n=j(t(e));return(r?n:n.toLowerCase()).includes(i)}))}};function L(e){return e.meta.isLoading||e.meta.isSearchPending?{status:`loading`}:e.meta.error?{error:e.meta.error,status:`error`}:{items:e.current,status:`success`}}exports.SourceDisposedError=i,exports.SourceTimeoutError=r,exports.SourcererError=n,exports.applyQuery=t,exports.createCursorSource=m,exports.createInfiniteSource=g,exports.createLocalSource=T,exports.createRemoteSource=D,exports.decodeQuery=o,exports.deriveSource=h,exports.encodeQuery=a,exports.filterContains=M,exports.filterEquals=N,exports.filterRange=P,exports.itemRange=x,exports.mergeSource=E,exports.prefetchSource=k,exports.prefetchSourceAndKeep=A,exports.searchBy=I,exports.sortBy=F,exports.sourceState=L;
|
|
2
2
|
//# sourceMappingURL=sourcerer.cjs.map
|