fetchium 0.1.0 → 0.1.1
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/CHANGELOG.md +6 -5
- package/dist/cjs/development/QueryClient-CLi3ONNM.js +2 -0
- package/dist/cjs/development/QueryClient-CLi3ONNM.js.map +1 -0
- package/dist/cjs/development/QueryController-BQA49OYU.js +2 -0
- package/dist/cjs/development/QueryController-BQA49OYU.js.map +1 -0
- package/dist/cjs/development/index.js +1 -1
- package/dist/cjs/development/index.js.map +1 -1
- package/dist/cjs/development/mutation-CikIl_6k.js +2 -0
- package/dist/cjs/development/mutation-CikIl_6k.js.map +1 -0
- package/dist/cjs/development/react/index.js +1 -1
- package/dist/cjs/development/rest/index.js +2 -0
- package/dist/cjs/development/rest/index.js.map +1 -0
- package/dist/cjs/development/topic/index.js +2 -0
- package/dist/cjs/development/topic/index.js.map +1 -0
- package/dist/cjs/production/QueryClient-N0MJmuHW.js +2 -0
- package/dist/cjs/production/QueryClient-N0MJmuHW.js.map +1 -0
- package/dist/cjs/production/QueryController-BQA49OYU.js +2 -0
- package/dist/cjs/production/QueryController-BQA49OYU.js.map +1 -0
- package/dist/cjs/production/index.js +1 -1
- package/dist/cjs/production/index.js.map +1 -1
- package/dist/cjs/production/mutation-P_Yb4LI9.js +2 -0
- package/dist/cjs/production/mutation-P_Yb4LI9.js.map +1 -0
- package/dist/cjs/production/react/index.js +1 -1
- package/dist/cjs/production/rest/index.js +2 -0
- package/dist/cjs/production/rest/index.js.map +1 -0
- package/dist/cjs/production/topic/index.js +2 -0
- package/dist/cjs/production/topic/index.js.map +1 -0
- package/dist/esm/MutationResult.d.ts +0 -1
- package/dist/esm/MutationResult.d.ts.map +1 -1
- package/dist/esm/QueryClient.d.ts +26 -4
- package/dist/esm/QueryClient.d.ts.map +1 -1
- package/dist/esm/QueryController.d.ts +49 -0
- package/dist/esm/QueryController.d.ts.map +1 -0
- package/dist/esm/QueryResult.d.ts +10 -10
- package/dist/esm/QueryResult.d.ts.map +1 -1
- package/dist/esm/development/QueryClient-Dtde3pss.js +2572 -0
- package/dist/esm/development/QueryClient-Dtde3pss.js.map +1 -0
- package/dist/esm/development/QueryController-Ch_ncxiI.js +14 -0
- package/dist/esm/development/QueryController-Ch_ncxiI.js.map +1 -0
- package/dist/esm/development/index.js +29 -100
- package/dist/esm/development/index.js.map +1 -1
- package/dist/esm/development/mutation-UZshUQAf.js +58 -0
- package/dist/esm/development/mutation-UZshUQAf.js.map +1 -0
- package/dist/esm/development/react/index.js +1 -1
- package/dist/esm/development/rest/index.js +142 -0
- package/dist/esm/development/rest/index.js.map +1 -0
- package/dist/esm/development/{shared-Dq2yW78d.js → shared-DcuVH8Pf.js} +5 -5
- package/dist/esm/development/{shared-Dq2yW78d.js.map → shared-DcuVH8Pf.js.map} +1 -1
- package/dist/esm/development/stores/async.js +6 -6
- package/dist/esm/development/stores/sync.js +5 -5
- package/dist/esm/development/topic/index.js +86 -0
- package/dist/esm/development/topic/index.js.map +1 -0
- package/dist/esm/index.d.ts +5 -4
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/mutation.d.ts +6 -19
- package/dist/esm/mutation.d.ts.map +1 -1
- package/dist/esm/production/{QueryClient-BP0Z1rQV.js → QueryClient-YqnBxFy1.js} +972 -968
- package/dist/esm/production/QueryClient-YqnBxFy1.js.map +1 -0
- package/dist/esm/production/QueryController-Ch_ncxiI.js +14 -0
- package/dist/esm/production/QueryController-Ch_ncxiI.js.map +1 -0
- package/dist/esm/production/index.js +29 -100
- package/dist/esm/production/index.js.map +1 -1
- package/dist/esm/production/mutation-pgFl1uIY.js +58 -0
- package/dist/esm/production/mutation-pgFl1uIY.js.map +1 -0
- package/dist/esm/production/react/index.js +1 -1
- package/dist/esm/production/rest/index.js +142 -0
- package/dist/esm/production/rest/index.js.map +1 -0
- package/dist/esm/production/{shared-Dq2yW78d.js → shared-DcuVH8Pf.js} +5 -5
- package/dist/esm/production/{shared-Dq2yW78d.js.map → shared-DcuVH8Pf.js.map} +1 -1
- package/dist/esm/production/stores/async.js +6 -6
- package/dist/esm/production/stores/sync.js +5 -5
- package/dist/esm/production/topic/index.js +86 -0
- package/dist/esm/production/topic/index.js.map +1 -0
- package/dist/esm/query-types.d.ts +2 -4
- package/dist/esm/query-types.d.ts.map +1 -1
- package/dist/esm/query.d.ts +17 -39
- package/dist/esm/query.d.ts.map +1 -1
- package/dist/esm/rest/RESTMutation.d.ts +18 -0
- package/dist/esm/rest/RESTMutation.d.ts.map +1 -0
- package/dist/esm/rest/RESTQuery.d.ts +24 -0
- package/dist/esm/rest/RESTQuery.d.ts.map +1 -0
- package/dist/esm/rest/RESTQueryController.d.ts +34 -0
- package/dist/esm/rest/RESTQueryController.d.ts.map +1 -0
- package/dist/esm/rest/index.d.ts +5 -0
- package/dist/esm/rest/index.d.ts.map +1 -0
- package/dist/esm/stores/shared.d.ts.map +1 -1
- package/dist/esm/testing/MockClient.d.ts +64 -0
- package/dist/esm/testing/MockClient.d.ts.map +1 -0
- package/dist/esm/testing/auto-generate.d.ts +20 -0
- package/dist/esm/testing/auto-generate.d.ts.map +1 -0
- package/dist/esm/testing/entity-factory.d.ts +13 -0
- package/dist/esm/testing/entity-factory.d.ts.map +1 -0
- package/dist/esm/testing/index.d.ts +6 -0
- package/dist/esm/testing/index.d.ts.map +1 -0
- package/dist/esm/testing/types.d.ts +37 -0
- package/dist/esm/testing/types.d.ts.map +1 -0
- package/dist/esm/topic/TopicQuery.d.ts +10 -0
- package/dist/esm/topic/TopicQuery.d.ts.map +1 -0
- package/dist/esm/topic/TopicQueryController.d.ts +43 -0
- package/dist/esm/topic/TopicQueryController.d.ts.map +1 -0
- package/dist/esm/topic/index.d.ts +3 -0
- package/dist/esm/topic/index.d.ts.map +1 -0
- package/dist/esm/typeDefs.d.ts +1 -1
- package/dist/esm/types.d.ts +9 -4
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +51 -4
- package/plugin/.claude-plugin/plugin.json +10 -0
- package/plugin/agents/fetchium.md +168 -0
- package/plugin/docs/api/fetchium-react.md +135 -0
- package/plugin/docs/api/fetchium.md +674 -0
- package/plugin/docs/api/stores-async.md +219 -0
- package/plugin/docs/api/stores-sync.md +133 -0
- package/plugin/docs/core/entities.md +351 -0
- package/plugin/docs/core/queries.md +600 -0
- package/plugin/docs/core/streaming.md +550 -0
- package/plugin/docs/core/types.md +374 -0
- package/plugin/docs/data/caching.md +298 -0
- package/plugin/docs/data/live-data.md +435 -0
- package/plugin/docs/data/mutations.md +465 -0
- package/plugin/docs/guides/auth.md +318 -0
- package/plugin/docs/guides/error-handling.md +351 -0
- package/plugin/docs/guides/offline.md +270 -0
- package/plugin/docs/guides/testing.md +301 -0
- package/plugin/docs/quickstart.md +170 -0
- package/plugin/docs/reference/pagination.md +519 -0
- package/plugin/docs/reference/rest-queries.md +107 -0
- package/plugin/docs/reference/why-signalium.md +364 -0
- package/plugin/docs/setup/project-setup.md +319 -0
- package/plugin/install.mjs +88 -0
- package/plugin/skills/design/SKILL.md +140 -0
- package/plugin/skills/teach/SKILL.md +105 -0
- package/dist/cjs/development/QueryClient-CpmwggOn.js +0 -2
- package/dist/cjs/development/QueryClient-CpmwggOn.js.map +0 -1
- package/dist/cjs/production/QueryClient-qi3bR0eD.js +0 -2
- package/dist/cjs/production/QueryClient-qi3bR0eD.js.map +0 -1
- package/dist/esm/development/QueryClient-DRZtPKFD.js +0 -2568
- package/dist/esm/development/QueryClient-DRZtPKFD.js.map +0 -1
- package/dist/esm/production/QueryClient-BP0Z1rQV.js.map +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class t {
|
|
2
|
+
queryClient;
|
|
3
|
+
/**
|
|
4
|
+
* Called once by QueryClient when this controller is registered.
|
|
5
|
+
* Subclasses can override to do setup (e.g. open a WebSocket connection).
|
|
6
|
+
*/
|
|
7
|
+
register(e) {
|
|
8
|
+
this.queryClient = e;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
t as Q
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=QueryController-Ch_ncxiI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryController-Ch_ncxiI.js","sources":["../../../src/QueryController.ts"],"sourcesContent":["import { type QueryContext } from './query-types.js';\nimport type { Query } from './query.js';\nimport type { Mutation } from './mutation.js';\n\n// ================================\n// IQueryClient — minimal interface QueryController needs from the client\n// (avoids circular import: QueryClient → QueryController → QueryClient)\n// ================================\n\nexport interface IQueryClientForController {\n getContext(): QueryContext;\n applyMutationEvent(event: import('./types.js').MutationEvent): void;\n}\n\n// ================================\n// QueryController base class\n// ================================\n\nexport abstract class QueryController {\n protected queryClient: IQueryClientForController | undefined;\n\n /**\n * Called once by QueryClient when this controller is registered.\n * Subclasses can override to do setup (e.g. open a WebSocket connection).\n */\n register(queryClient: IQueryClientForController): void {\n this.queryClient = queryClient;\n }\n\n /**\n * Called when the network comes online or goes offline.\n * Subclasses can override to reconnect persistent connections (e.g. WebSocket).\n */\n onNetworkStatusChange?(isOnline: boolean): void;\n\n /**\n * Called when the QueryClient is destroyed.\n * Subclasses can override to clean up connections or timers.\n */\n destroy?(): void;\n\n /**\n * Send the query and return the raw response data.\n * @param ctx The query execution context (a reified Query instance with params applied).\n * @param signal AbortSignal to cancel the in-flight request.\n */\n abstract send(ctx: Query, signal: AbortSignal): Promise<unknown>;\n\n /**\n * Fetch the next page of results. Only implement if the controller supports pagination.\n * @param ctx The query execution context. `ctx.resultData` contains the current page's data.\n * @param signal AbortSignal to cancel the in-flight request.\n */\n sendNext?(ctx: Query, signal: AbortSignal): Promise<unknown>;\n\n /**\n * Return true if more pages are available for the current result.\n * Called reactively — do not perform async work here.\n */\n hasNext?(ctx: Query): boolean;\n\n /**\n * Send a mutation and return the raw response data.\n * @param ctx The mutation execution context (a reified Mutation instance with params applied).\n * @param signal AbortSignal to cancel the in-flight request.\n */\n sendMutation?(ctx: Mutation, signal: AbortSignal): Promise<unknown>;\n}\n"],"names":["QueryController","queryClient"],"mappings":"AAkBO,MAAeA,EAAgB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,SAASC,GAA8C;AACrD,SAAK,cAAcA;AAAA,EACrB;AAwCF;"}
|
|
@@ -1,103 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
class D {
|
|
5
|
-
params;
|
|
6
|
-
result;
|
|
7
|
-
optimisticUpdates;
|
|
8
|
-
config;
|
|
9
|
-
effects;
|
|
10
|
-
constructor() {
|
|
11
|
-
return m(this);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
class q extends D {
|
|
15
|
-
path;
|
|
16
|
-
method = "POST";
|
|
17
|
-
body;
|
|
18
|
-
headers;
|
|
19
|
-
requestOptions;
|
|
20
|
-
getStorageKey() {
|
|
21
|
-
return `${this.method ?? "POST"}:${this.path ?? ""}`;
|
|
22
|
-
}
|
|
23
|
-
async send() {
|
|
24
|
-
const t = this.getPath ? this.getPath() : this.path, s = this.getMethod ? this.getMethod() : this.method, i = this.getBody ? this.getBody() : this.body, r = this.getRequestOptions ? this.getRequestOptions() : this.requestOptions;
|
|
25
|
-
if (!t)
|
|
26
|
-
throw new Error("RESTMutation requires a path. Define `path` as a field or override `getPath()`.");
|
|
27
|
-
const n = i ?? this.params, o = p(r?.baseUrl) ?? p(this.context.baseUrl), f = o ? `${o}${t}` : t, { baseUrl: c, signal: d, ...a } = r ?? {}, h = {
|
|
28
|
-
"Content-Type": "application/json",
|
|
29
|
-
...this.headers
|
|
30
|
-
}, g = await this.context.fetch(f, {
|
|
31
|
-
method: s,
|
|
32
|
-
headers: h,
|
|
33
|
-
body: JSON.stringify(n),
|
|
34
|
-
signal: this.signal,
|
|
35
|
-
...a
|
|
36
|
-
});
|
|
37
|
-
return this.response = g, g.json();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
const u = /* @__PURE__ */ new WeakMap(), C = (e) => {
|
|
41
|
-
const t = u.get(e);
|
|
42
|
-
if (t === void 0)
|
|
43
|
-
throw new Error("Mutation definition not found");
|
|
44
|
-
return t().id;
|
|
45
|
-
};
|
|
46
|
-
function E(e) {
|
|
47
|
-
let t = u.get(e);
|
|
48
|
-
if (t !== void 0)
|
|
49
|
-
return t;
|
|
50
|
-
let s;
|
|
51
|
-
const i = () => {
|
|
52
|
-
if (s !== void 0)
|
|
53
|
-
return s;
|
|
54
|
-
const r = new e(), n = b(r), { fields: o } = n, f = `mutation:${String(n.methods.getStorageKey.call(o))}`, c = o.params ?? {}, d = c instanceof l ? c : y.object(c), a = o.result, h = a !== void 0 ? a instanceof l ? a : y.object(a) : void 0;
|
|
55
|
-
return s = {
|
|
56
|
-
id: f,
|
|
57
|
-
requestShape: d,
|
|
58
|
-
responseShape: h,
|
|
59
|
-
captured: n,
|
|
60
|
-
optimisticUpdates: o.optimisticUpdates ?? !1,
|
|
61
|
-
config: o.config,
|
|
62
|
-
effects: o.effects,
|
|
63
|
-
hasGetEffects: typeof n.methods.getEffects == "function"
|
|
64
|
-
}, s;
|
|
65
|
-
};
|
|
66
|
-
return u.set(e, i), i;
|
|
67
|
-
}
|
|
68
|
-
function S(e) {
|
|
69
|
-
const t = E(e), s = w(M);
|
|
70
|
-
if (s === void 0)
|
|
71
|
-
throw new Error("QueryClient not found");
|
|
72
|
-
return s.getMutation(t());
|
|
73
|
-
}
|
|
1
|
+
import { A as r, E as s, G as t, L as o, a as n, M as i, N as M, b as g, c as u, d as y, e as l, Q as C, f, g as N, h as Q, R as k, i as d, j as m, k as p, q as E, r as R, t as w } from "./QueryClient-YqnBxFy1.js";
|
|
2
|
+
import { Q as F } from "./QueryController-Ch_ncxiI.js";
|
|
3
|
+
import { M as K, g as Y, m as A } from "./mutation-pgFl1uIY.js";
|
|
74
4
|
export {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
y as t
|
|
5
|
+
r as ARRAY_KEY,
|
|
6
|
+
s as Entity,
|
|
7
|
+
t as GcManager,
|
|
8
|
+
o as LiveFieldConfig,
|
|
9
|
+
n as LiveFieldType,
|
|
10
|
+
i as Mask,
|
|
11
|
+
K as Mutation,
|
|
12
|
+
M as NetworkManager,
|
|
13
|
+
g as NetworkManagerContext,
|
|
14
|
+
u as NetworkMode,
|
|
15
|
+
y as NoOpGcManager,
|
|
16
|
+
l as NoOpNetworkManager,
|
|
17
|
+
C as QUERY_ID,
|
|
18
|
+
f as Query,
|
|
19
|
+
N as QueryClient,
|
|
20
|
+
Q as QueryClientContext,
|
|
21
|
+
F as QueryController,
|
|
22
|
+
k as RECORD_KEY,
|
|
23
|
+
d as defaultNetworkManager,
|
|
24
|
+
m as draft,
|
|
25
|
+
p as fetchQuery,
|
|
26
|
+
Y as getMutation,
|
|
27
|
+
A as mutationKeyForClass,
|
|
28
|
+
E as queryKeyForClass,
|
|
29
|
+
R as registerFormat,
|
|
30
|
+
w as t
|
|
102
31
|
};
|
|
103
32
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getContext as h } from "signalium";
|
|
2
|
+
import { l as y, h as D, m as w, V as u, t as l } from "./QueryClient-YqnBxFy1.js";
|
|
3
|
+
class x {
|
|
4
|
+
static controller;
|
|
5
|
+
params;
|
|
6
|
+
result;
|
|
7
|
+
optimisticUpdates;
|
|
8
|
+
config;
|
|
9
|
+
effects;
|
|
10
|
+
constructor() {
|
|
11
|
+
return y(this);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const c = /* @__PURE__ */ new WeakMap(), C = (t) => {
|
|
15
|
+
const e = c.get(t);
|
|
16
|
+
if (e === void 0)
|
|
17
|
+
throw new Error("Mutation definition not found");
|
|
18
|
+
return e().id;
|
|
19
|
+
};
|
|
20
|
+
function M(t) {
|
|
21
|
+
let e = c.get(t);
|
|
22
|
+
if (e !== void 0)
|
|
23
|
+
return e;
|
|
24
|
+
let o;
|
|
25
|
+
const a = () => {
|
|
26
|
+
if (o !== void 0)
|
|
27
|
+
return o;
|
|
28
|
+
const d = new t(), i = w(d), { fields: n } = i, m = `mutation:${String(i.methods.getIdentityKey.call(n))}`, s = n.params ?? {}, p = s instanceof u ? s : l.object(s), r = n.result, g = r !== void 0 ? r instanceof u ? r : l.object(r) : void 0, f = t.controller;
|
|
29
|
+
if (!f)
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Mutation class "${t.name}" must define a static \`controller\` property. Extend RESTMutation (from fetchium/rest) or set \`static controller = MyController\` on your mutation class.`
|
|
32
|
+
);
|
|
33
|
+
return o = {
|
|
34
|
+
id: m,
|
|
35
|
+
requestShape: p,
|
|
36
|
+
responseShape: g,
|
|
37
|
+
captured: i,
|
|
38
|
+
optimisticUpdates: n.optimisticUpdates ?? !1,
|
|
39
|
+
config: n.config,
|
|
40
|
+
effects: n.effects,
|
|
41
|
+
hasGetEffects: typeof i.methods.getEffects == "function",
|
|
42
|
+
controllerClass: f
|
|
43
|
+
}, o;
|
|
44
|
+
};
|
|
45
|
+
return c.set(t, a), a;
|
|
46
|
+
}
|
|
47
|
+
function S(t) {
|
|
48
|
+
const e = M(t), o = h(D);
|
|
49
|
+
if (o === void 0)
|
|
50
|
+
throw new Error("QueryClient not found");
|
|
51
|
+
return o.getMutation(e());
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
x as M,
|
|
55
|
+
S as g,
|
|
56
|
+
C as m
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=mutation-pgFl1uIY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation-pgFl1uIY.js","sources":["../../../src/mutation.ts"],"sourcesContent":["import { getContext, ReactiveTask } from 'signalium';\nimport { ExtractType, InternalTypeDef, MutationEffects, TypeDef, RetryConfig, TypeDefShape } from './types.js';\nimport { QueryClientContext, type QueryContext } from './QueryClient.js';\nimport { ValidatorDef, t } from './typeDefs.js';\nimport { createDefinitionProxy, extractDefinition, type CapturedDefinition } from './fieldRef.js';\nimport type { QueryController } from './QueryController.js';\n\n// ================================\n// Mutation Definition Types\n// ================================\n\nexport interface MutationConfigOptions {\n retry?: RetryConfig | number | false;\n}\n\nexport interface MutationDefinition<Request, Response> {\n id: string;\n requestShape: InternalTypeDef;\n responseShape: InternalTypeDef | undefined;\n captured: CapturedDefinition<Mutation>;\n optimisticUpdates: boolean;\n config?: MutationConfigOptions;\n effects?: MutationEffects;\n hasGetEffects: boolean;\n controllerClass: typeof QueryController;\n}\n\n// ================================\n// Mutation base class\n// ================================\n\nexport abstract class Mutation {\n static controller?: typeof QueryController;\n\n readonly params?: TypeDefShape;\n readonly result?: TypeDefShape;\n readonly optimisticUpdates?: boolean;\n readonly config?: MutationConfigOptions;\n readonly effects?: Readonly<MutationEffects>;\n\n declare context: QueryContext;\n\n abstract getIdentityKey(): unknown;\n\n getEffects?(): MutationEffects;\n\n constructor() {\n return createDefinitionProxy(this);\n }\n}\n\n// ================================\n// Mutation definition cache and lookup\n// ================================\n\nconst mutationDefCache = new WeakMap<new () => Mutation, () => MutationDefinition<any, any>>();\n\nexport const mutationKeyForClass = (cls: new () => Mutation): string => {\n const getMutationDef = mutationDefCache.get(cls);\n\n if (getMutationDef === undefined) {\n throw new Error('Mutation definition not found');\n }\n\n return getMutationDef().id;\n};\n\n// ================================\n// Internal: build mutation definition from class\n// ================================\n\nfunction buildMutationDefinition(MutationClass: new () => Mutation): () => MutationDefinition<any, any> {\n let cached = mutationDefCache.get(MutationClass);\n\n if (cached !== undefined) {\n return cached;\n }\n\n let mutationDefinition: MutationDefinition<any, any> | undefined;\n\n const getter = (): MutationDefinition<any, any> => {\n if (mutationDefinition !== undefined) {\n return mutationDefinition;\n }\n\n const instance = new MutationClass();\n const captured = extractDefinition(instance);\n const { fields } = captured;\n\n const id = `mutation:${String(captured.methods.getIdentityKey.call(fields))}`;\n\n const requestDef = fields.params ?? {};\n const requestShape = (requestDef instanceof ValidatorDef\n ? requestDef\n : t.object(requestDef)) as unknown as InternalTypeDef;\n const responseDef = fields.result;\n const responseShape =\n responseDef !== undefined\n ? ((responseDef instanceof ValidatorDef ? responseDef : t.object(responseDef)) as unknown as InternalTypeDef)\n : undefined;\n\n const controllerClass = (MutationClass as typeof Mutation).controller;\n if (!controllerClass) {\n throw new Error(\n `Mutation class \"${MutationClass.name}\" must define a static \\`controller\\` property. ` +\n `Extend RESTMutation (from fetchium/rest) or set \\`static controller = MyController\\` on your mutation class.`,\n );\n }\n\n mutationDefinition = {\n id,\n requestShape,\n responseShape,\n captured,\n optimisticUpdates: fields.optimisticUpdates ?? false,\n config: fields.config,\n effects: fields.effects,\n hasGetEffects: typeof captured.methods.getEffects === 'function',\n controllerClass,\n };\n\n return mutationDefinition;\n };\n\n mutationDefCache.set(MutationClass, getter);\n return getter;\n}\n\n// ================================\n// Public API\n// ================================\n\nexport function getMutation<T extends Mutation>(\n MutationClass: new () => T,\n): ReactiveTask<Readonly<ExtractType<T['result']>>, [ExtractType<T['params']>]> {\n const getMutationDef = buildMutationDefinition(MutationClass);\n\n const queryClient = getContext(QueryClientContext);\n\n if (queryClient === undefined) {\n throw new Error('QueryClient not found');\n }\n\n return queryClient.getMutation<any, any>(getMutationDef());\n}\n"],"names":["Mutation","createDefinitionProxy","mutationDefCache","mutationKeyForClass","cls","getMutationDef","buildMutationDefinition","MutationClass","cached","mutationDefinition","getter","instance","captured","extractDefinition","fields","id","requestDef","requestShape","ValidatorDef","t","responseDef","responseShape","controllerClass","getMutation","queryClient","getContext","QueryClientContext"],"mappings":";;AA+BO,MAAeA,EAAS;AAAA,EAC7B,OAAO;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAQT,cAAc;AACZ,WAAOC,EAAsB,IAAI;AAAA,EACnC;AACF;AAMA,MAAMC,wBAAuB,QAAA,GAEhBC,IAAsB,CAACC,MAAoC;AACtE,QAAMC,IAAiBH,EAAiB,IAAIE,CAAG;AAE/C,MAAIC,MAAmB;AACrB,UAAM,IAAI,MAAM,+BAA+B;AAGjD,SAAOA,IAAiB;AAC1B;AAMA,SAASC,EAAwBC,GAAuE;AACtG,MAAIC,IAASN,EAAiB,IAAIK,CAAa;AAE/C,MAAIC,MAAW;AACb,WAAOA;AAGT,MAAIC;AAEJ,QAAMC,IAAS,MAAoC;AACjD,QAAID,MAAuB;AACzB,aAAOA;AAGT,UAAME,IAAW,IAAIJ,EAAA,GACfK,IAAWC,EAAkBF,CAAQ,GACrC,EAAE,QAAAG,MAAWF,GAEbG,IAAK,YAAY,OAAOH,EAAS,QAAQ,eAAe,KAAKE,CAAM,CAAC,CAAC,IAErEE,IAAaF,EAAO,UAAU,CAAA,GAC9BG,IAAgBD,aAAsBE,IACxCF,IACAG,EAAE,OAAOH,CAAU,GACjBI,IAAcN,EAAO,QACrBO,IACJD,MAAgB,SACVA,aAAuBF,IAAeE,IAAcD,EAAE,OAAOC,CAAW,IAC1E,QAEAE,IAAmBf,EAAkC;AAC3D,QAAI,CAACe;AACH,YAAM,IAAI;AAAA,QACR,mBAAmBf,EAAc,IAAI;AAAA,MAAA;AAKzC,WAAAE,IAAqB;AAAA,MACnB,IAAAM;AAAA,MACA,cAAAE;AAAA,MACA,eAAAI;AAAA,MACA,UAAAT;AAAA,MACA,mBAAmBE,EAAO,qBAAqB;AAAA,MAC/C,QAAQA,EAAO;AAAA,MACf,SAASA,EAAO;AAAA,MAChB,eAAe,OAAOF,EAAS,QAAQ,cAAe;AAAA,MACtD,iBAAAU;AAAA,IAAA,GAGKb;AAAA,EACT;AAEA,SAAAP,EAAiB,IAAIK,GAAeG,CAAM,GACnCA;AACT;AAMO,SAASa,EACdhB,GAC8E;AAC9E,QAAMF,IAAiBC,EAAwBC,CAAa,GAEtDiB,IAAcC,EAAWC,CAAkB;AAEjD,MAAIF,MAAgB;AAClB,UAAM,IAAI,MAAM,uBAAuB;AAGzC,SAAOA,EAAY,YAAsBnB,GAAgB;AAC3D;"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { n as v, o as U, f as O } from "../QueryClient-YqnBxFy1.js";
|
|
2
|
+
import { Q as T } from "../QueryController-Ch_ncxiI.js";
|
|
3
|
+
import { M as w } from "../mutation-pgFl1uIY.js";
|
|
4
|
+
class P extends T {
|
|
5
|
+
_fetch;
|
|
6
|
+
_baseUrl;
|
|
7
|
+
constructor(e) {
|
|
8
|
+
super(), this._fetch = e?.fetch ?? globalThis.fetch, this._baseUrl = e?.baseUrl;
|
|
9
|
+
}
|
|
10
|
+
async send(e, s) {
|
|
11
|
+
return this.executeRequest(e, s);
|
|
12
|
+
}
|
|
13
|
+
async sendNext(e, s) {
|
|
14
|
+
const t = this.resolveFetchNext(e);
|
|
15
|
+
if (t === void 0)
|
|
16
|
+
throw new Error("fetchNext is not configured for this query");
|
|
17
|
+
return this.executeRequest(e, s, t);
|
|
18
|
+
}
|
|
19
|
+
hasNext(e) {
|
|
20
|
+
const s = this.resolveFetchNext(e);
|
|
21
|
+
if (s === void 0) return !1;
|
|
22
|
+
if (s.url !== void 0 && s.url !== null)
|
|
23
|
+
return !0;
|
|
24
|
+
if (s.searchParams !== void 0) {
|
|
25
|
+
const t = Object.keys(s.searchParams);
|
|
26
|
+
if (t.length === 0) return !1;
|
|
27
|
+
for (const r of t)
|
|
28
|
+
if (s.searchParams[r] === void 0 || s.searchParams[r] === null)
|
|
29
|
+
return !1;
|
|
30
|
+
return !0;
|
|
31
|
+
}
|
|
32
|
+
return !1;
|
|
33
|
+
}
|
|
34
|
+
resolveFetchNext(e) {
|
|
35
|
+
const t = (e.getFetchNext ? e.getFetchNext() : void 0) ?? e.rawFetchNext;
|
|
36
|
+
if (t === void 0) return;
|
|
37
|
+
const r = {
|
|
38
|
+
params: e.params ?? {},
|
|
39
|
+
result: e.resultData
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
url: t.url !== void 0 ? v(t.url, r) : void 0,
|
|
43
|
+
searchParams: t.searchParams !== void 0 ? v(t.searchParams, r) : void 0
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolves a path to a full URL.
|
|
48
|
+
*
|
|
49
|
+
* - Absolute URLs (`https://...`, `//...`) are returned as-is.
|
|
50
|
+
* - Root-relative paths (`/foo`) are prepended with the resolved baseUrl.
|
|
51
|
+
* The baseUrl priority is: per-query/mutation > controller-level > `location.origin`.
|
|
52
|
+
* If none is available and the path is root-relative, an error is thrown.
|
|
53
|
+
* - Other paths (e.g. `example.com/foo`) are returned as-is.
|
|
54
|
+
*/
|
|
55
|
+
buildUrl(e, s) {
|
|
56
|
+
if (e.startsWith("http://") || e.startsWith("https://") || e.startsWith("//"))
|
|
57
|
+
return e;
|
|
58
|
+
if (e.startsWith("/")) {
|
|
59
|
+
const t = U(s) ?? U(this._baseUrl) ?? globalThis.location?.origin;
|
|
60
|
+
if (!t)
|
|
61
|
+
throw new Error(
|
|
62
|
+
`RESTQueryController: cannot resolve URL for path "${e}". Set \`baseUrl\` on the query/mutation, pass it to \`new RESTQueryController({ baseUrl })\`, or use an absolute URL.`
|
|
63
|
+
);
|
|
64
|
+
return `${t}${e}`;
|
|
65
|
+
}
|
|
66
|
+
return e;
|
|
67
|
+
}
|
|
68
|
+
async executeRequest(e, s, t) {
|
|
69
|
+
const r = t?.url ?? (e.getPath ? e.getPath() : e.path), h = e.getMethod ? e.getMethod() : e.method, o = e.getSearchParams ? e.getSearchParams() : e.searchParams, a = t?.searchParams ? { ...o, ...t.searchParams } : o, n = e.getBody ? e.getBody() : e.body, i = e.getRequestOptions ? e.getRequestOptions() : e.requestOptions;
|
|
70
|
+
if (!r)
|
|
71
|
+
throw new Error("RESTQuery requires a path. Define `path` as a field or override `getPath()`.");
|
|
72
|
+
let l = r;
|
|
73
|
+
if (a) {
|
|
74
|
+
const y = new URLSearchParams();
|
|
75
|
+
for (const b in a) {
|
|
76
|
+
const c = a[b];
|
|
77
|
+
c != null && y.append(b, String(c));
|
|
78
|
+
}
|
|
79
|
+
const m = y.toString();
|
|
80
|
+
m && (l += "?" + m);
|
|
81
|
+
}
|
|
82
|
+
const f = i?.baseUrl ?? e.baseUrl, u = this.buildUrl(l, f), { baseUrl: g, signal: R, ...q } = i ?? {}, S = n || e.headers ? {
|
|
83
|
+
...n ? { "Content-Type": "application/json" } : void 0,
|
|
84
|
+
...e.headers
|
|
85
|
+
} : void 0, p = await this._fetch(u, {
|
|
86
|
+
method: h,
|
|
87
|
+
headers: S,
|
|
88
|
+
body: n ? JSON.stringify(n) : void 0,
|
|
89
|
+
signal: s,
|
|
90
|
+
...q
|
|
91
|
+
});
|
|
92
|
+
return e.response = p, p.json();
|
|
93
|
+
}
|
|
94
|
+
async sendMutation(e, s) {
|
|
95
|
+
const t = e, r = t.getPath ? t.getPath() : t.path, h = t.getMethod ? t.getMethod() : t.method, o = t.getBody ? t.getBody() : t.body, a = t.getRequestOptions ? t.getRequestOptions() : t.requestOptions;
|
|
96
|
+
if (!r)
|
|
97
|
+
throw new Error("RESTMutation requires a path. Define `path` as a field or override `getPath()`.");
|
|
98
|
+
const n = a?.baseUrl ?? t.baseUrl, i = this.buildUrl(r, n), { baseUrl: l, signal: f, ...u } = a ?? {}, g = {
|
|
99
|
+
...o !== void 0 ? { "Content-Type": "application/json" } : {},
|
|
100
|
+
...t.headers
|
|
101
|
+
};
|
|
102
|
+
return (await this._fetch(i, {
|
|
103
|
+
method: h,
|
|
104
|
+
headers: g,
|
|
105
|
+
...o !== void 0 ? { body: JSON.stringify(o) } : {},
|
|
106
|
+
signal: s,
|
|
107
|
+
...u
|
|
108
|
+
})).json();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
class M extends O {
|
|
112
|
+
static controller = P;
|
|
113
|
+
method = "GET";
|
|
114
|
+
path;
|
|
115
|
+
baseUrl;
|
|
116
|
+
searchParams;
|
|
117
|
+
body;
|
|
118
|
+
headers;
|
|
119
|
+
requestOptions;
|
|
120
|
+
fetchNext;
|
|
121
|
+
getIdentityKey() {
|
|
122
|
+
return `${this.method ?? "GET"}:${this.path ?? ""}`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
class Q extends w {
|
|
126
|
+
static controller = P;
|
|
127
|
+
path;
|
|
128
|
+
baseUrl;
|
|
129
|
+
method = "POST";
|
|
130
|
+
body;
|
|
131
|
+
headers;
|
|
132
|
+
requestOptions;
|
|
133
|
+
getIdentityKey() {
|
|
134
|
+
return `${this.method ?? "POST"}:${this.path ?? ""}`;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export {
|
|
138
|
+
Q as RESTMutation,
|
|
139
|
+
M as RESTQuery,
|
|
140
|
+
P as RESTQueryController
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/rest/RESTQueryController.ts","../../../../src/rest/RESTQuery.ts","../../../../src/rest/RESTMutation.ts"],"sourcesContent":["import { QueryController } from '../QueryController.js';\nimport { resolveBaseUrl } from '../query-types.js';\nimport { reifyValue } from '../fieldRef.js';\nimport type { Query } from '../query.js';\nimport type { Mutation } from '../mutation.js';\nimport type { FetchNextConfig } from '../query-types.js';\nimport type { RESTQuery } from './RESTQuery.js';\nimport type { RESTMutation } from './RESTMutation.js';\nimport type { QueryRequestInit, BaseUrlValue, QueryRequestOptions } from '../types.js';\n\n// ================================\n// ResolvedFetchNext\n// ================================\n\nexport interface ResolvedFetchNext {\n url?: string;\n searchParams?: Record<string, unknown>;\n}\n\n// ================================\n// RESTQueryController options\n// ================================\n\nexport interface RESTQueryControllerOptions {\n fetch?: (url: string, init?: QueryRequestInit) => Promise<Response>;\n baseUrl?: BaseUrlValue;\n}\n\n// ================================\n// RESTQueryController\n// ================================\n\nexport class RESTQueryController extends QueryController {\n private readonly _fetch: (url: string, init?: QueryRequestInit) => Promise<Response>;\n private readonly _baseUrl: BaseUrlValue | undefined;\n\n constructor(options?: RESTQueryControllerOptions) {\n super();\n this._fetch =\n options?.fetch ?? (globalThis.fetch as unknown as (url: string, init?: QueryRequestInit) => Promise<Response>);\n this._baseUrl = options?.baseUrl;\n }\n\n override async send(ctx: Query, signal: AbortSignal): Promise<unknown> {\n return this.executeRequest(ctx as RESTQuery, signal);\n }\n\n override async sendNext(ctx: Query, signal: AbortSignal): Promise<unknown> {\n const resolved = this.resolveFetchNext(ctx as RESTQuery);\n if (resolved === undefined) {\n throw new Error('fetchNext is not configured for this query');\n }\n return this.executeRequest(ctx as RESTQuery, signal, resolved);\n }\n\n override hasNext(ctx: Query): boolean {\n const resolved = this.resolveFetchNext(ctx as RESTQuery);\n if (resolved === undefined) return false;\n\n if (resolved.url !== undefined && resolved.url !== null) {\n return true;\n }\n\n if (resolved.searchParams !== undefined) {\n const keys = Object.keys(resolved.searchParams);\n if (keys.length === 0) return false;\n for (const key of keys) {\n if (resolved.searchParams[key] === undefined || resolved.searchParams[key] === null) {\n return false;\n }\n }\n return true;\n }\n\n return false;\n }\n\n private resolveFetchNext(ctx: RESTQuery): ResolvedFetchNext | undefined {\n const dynamicConfig = ctx.getFetchNext ? ctx.getFetchNext() : undefined;\n const fetchNextConfig: FetchNextConfig | undefined = dynamicConfig ?? ctx.rawFetchNext;\n if (fetchNextConfig === undefined) return undefined;\n\n const resolveRoot: Record<string, unknown> = {\n params: ctx.params ?? {},\n result: ctx.resultData,\n };\n\n return {\n url: fetchNextConfig.url !== undefined ? (reifyValue(fetchNextConfig.url, resolveRoot) as string) : undefined,\n searchParams:\n fetchNextConfig.searchParams !== undefined\n ? (reifyValue(fetchNextConfig.searchParams, resolveRoot) as Record<string, unknown>)\n : undefined,\n };\n }\n\n /**\n * Resolves a path to a full URL.\n *\n * - Absolute URLs (`https://...`, `//...`) are returned as-is.\n * - Root-relative paths (`/foo`) are prepended with the resolved baseUrl.\n * The baseUrl priority is: per-query/mutation > controller-level > `location.origin`.\n * If none is available and the path is root-relative, an error is thrown.\n * - Other paths (e.g. `example.com/foo`) are returned as-is.\n */\n private buildUrl(path: string, ctxBaseUrl: BaseUrlValue | undefined): string {\n // Absolute URL — use as-is regardless of any configured baseUrl\n if (path.startsWith('http://') || path.startsWith('https://') || path.startsWith('//')) {\n return path;\n }\n\n // Root-relative path — needs a base\n if (path.startsWith('/')) {\n const base = resolveBaseUrl(ctxBaseUrl) ?? resolveBaseUrl(this._baseUrl) ?? globalThis.location?.origin;\n\n if (!base) {\n throw new Error(\n `RESTQueryController: cannot resolve URL for path \"${path}\". ` +\n `Set \\`baseUrl\\` on the query/mutation, pass it to \\`new RESTQueryController({ baseUrl })\\`, ` +\n `or use an absolute URL.`,\n );\n }\n\n return `${base}${path}`;\n }\n\n // Relative path — use as-is\n return path;\n }\n\n private async executeRequest(\n ctx: RESTQuery,\n signal: AbortSignal,\n next?: { url?: string; searchParams?: Record<string, unknown> },\n ): Promise<unknown> {\n const path = next?.url ?? (ctx.getPath ? ctx.getPath() : ctx.path);\n const method = ctx.getMethod ? ctx.getMethod() : ctx.method;\n const baseSearchParams = ctx.getSearchParams ? ctx.getSearchParams() : ctx.searchParams;\n const searchParams = next?.searchParams ? { ...baseSearchParams, ...next.searchParams } : baseSearchParams;\n const body = ctx.getBody ? ctx.getBody() : ctx.body;\n const requestOptions = ctx.getRequestOptions ? ctx.getRequestOptions() : ctx.requestOptions;\n\n if (!path) {\n throw new Error('RESTQuery requires a path. Define `path` as a field or override `getPath()`.');\n }\n\n let url = path;\n\n if (searchParams) {\n const sp = new URLSearchParams();\n for (const key in searchParams) {\n const val = searchParams[key];\n if (val !== undefined && val !== null) {\n sp.append(key, String(val));\n }\n }\n const qs = sp.toString();\n if (qs) {\n url += '?' + qs;\n }\n }\n\n const ctxBaseUrl = requestOptions?.baseUrl ?? ctx.baseUrl;\n const fullUrl = this.buildUrl(url, ctxBaseUrl);\n\n const { baseUrl: _baseUrl, signal: _signal, ...fetchOptions } = requestOptions ?? ({} as Record<string, unknown>);\n\n const hasHeaders = body || ctx.headers;\n const headers: HeadersInit | undefined = hasHeaders\n ? {\n ...(body ? { 'Content-Type': 'application/json' } : undefined),\n ...(ctx.headers as Record<string, string>),\n }\n : undefined;\n\n const fetchResponse = await this._fetch(fullUrl, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal,\n ...fetchOptions,\n });\n\n ctx.response = fetchResponse as unknown as Response;\n\n return fetchResponse.json();\n }\n\n override async sendMutation(ctx: Mutation, signal: AbortSignal): Promise<unknown> {\n const restCtx = ctx as RESTMutation;\n const path = restCtx.getPath ? restCtx.getPath() : restCtx.path;\n const method = restCtx.getMethod ? restCtx.getMethod() : restCtx.method;\n const body = restCtx.getBody ? restCtx.getBody() : restCtx.body;\n const requestOptions = restCtx.getRequestOptions ? restCtx.getRequestOptions() : restCtx.requestOptions;\n\n if (!path) {\n throw new Error('RESTMutation requires a path. Define `path` as a field or override `getPath()`.');\n }\n\n const ctxBaseUrl = (requestOptions as QueryRequestOptions | undefined)?.baseUrl ?? restCtx.baseUrl;\n const fullUrl = this.buildUrl(path, ctxBaseUrl);\n\n const { baseUrl: _baseUrl, signal: _signal, ...fetchOptions } = (requestOptions ?? {}) as Record<string, unknown>;\n\n const headers: HeadersInit = {\n ...(body !== undefined ? { 'Content-Type': 'application/json' } : {}),\n ...(restCtx.headers as Record<string, string>),\n };\n\n const fetchResponse = await this._fetch(fullUrl, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n signal,\n ...fetchOptions,\n });\n\n return fetchResponse.json();\n }\n}\n","import { Query } from '../query.js';\nimport { RESTQueryController } from './RESTQueryController.js';\nimport type { FetchNextConfig } from '../query-types.js';\nimport type { BaseUrlValue, QueryRequestOptions } from '../types.js';\n\n// ================================\n// RESTQuery — declarative HTTP query definition\n// ================================\n\nexport abstract class RESTQuery extends Query {\n static override controller = RESTQueryController;\n\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' = 'GET';\n path?: string;\n baseUrl?: BaseUrlValue;\n searchParams?: Record<string, unknown>;\n body?: Record<string, unknown>;\n headers?: HeadersInit;\n requestOptions?: QueryRequestOptions;\n fetchNext?: FetchNextConfig;\n\n declare response: Response | undefined;\n\n getIdentityKey(): string {\n return `${this.method ?? 'GET'}:${this.path ?? ''}`;\n }\n\n // User-overridable getters — the controller reads these from the execution context\n getPath?(): string | undefined;\n getMethod?(): string;\n getSearchParams?(): Record<string, unknown> | undefined;\n getBody?(): Record<string, unknown> | undefined;\n getRequestOptions?(): QueryRequestOptions | undefined;\n getFetchNext?(): FetchNextConfig | undefined;\n}\n","import { Mutation } from '../mutation.js';\nimport type { BaseUrlValue, QueryRequestOptions } from '../types.js';\nimport { RESTQueryController } from './RESTQueryController.js';\n\nexport abstract class RESTMutation extends Mutation {\n static override controller = RESTQueryController;\n\n path?: string;\n baseUrl?: BaseUrlValue;\n method: 'POST' | 'PUT' | 'DELETE' | 'PATCH' = 'POST';\n body?: Record<string, unknown>;\n headers?: HeadersInit;\n requestOptions?: QueryRequestOptions;\n\n getIdentityKey(): string {\n return `${this.method ?? 'POST'}:${this.path ?? ''}`;\n }\n\n getPath?(): string | undefined;\n getMethod?(): string;\n getBody?(): Record<string, unknown> | undefined;\n getRequestOptions?(): QueryRequestOptions | undefined;\n}\n"],"names":["RESTQueryController","QueryController","options","ctx","signal","resolved","keys","key","fetchNextConfig","resolveRoot","reifyValue","path","ctxBaseUrl","base","resolveBaseUrl","next","method","baseSearchParams","searchParams","body","requestOptions","url","sp","val","qs","fullUrl","_baseUrl","_signal","fetchOptions","headers","fetchResponse","restCtx","RESTQuery","Query","RESTMutation","Mutation"],"mappings":";;;AAgCO,MAAMA,UAA4BC,EAAgB;AAAA,EACtC;AAAA,EACA;AAAA,EAEjB,YAAYC,GAAsC;AAChD,UAAA,GACA,KAAK,SACHA,GAAS,SAAU,WAAW,OAChC,KAAK,WAAWA,GAAS;AAAA,EAC3B;AAAA,EAEA,MAAe,KAAKC,GAAYC,GAAuC;AACrE,WAAO,KAAK,eAAeD,GAAkBC,CAAM;AAAA,EACrD;AAAA,EAEA,MAAe,SAASD,GAAYC,GAAuC;AACzE,UAAMC,IAAW,KAAK,iBAAiBF,CAAgB;AACvD,QAAIE,MAAa;AACf,YAAM,IAAI,MAAM,4CAA4C;AAE9D,WAAO,KAAK,eAAeF,GAAkBC,GAAQC,CAAQ;AAAA,EAC/D;AAAA,EAES,QAAQF,GAAqB;AACpC,UAAME,IAAW,KAAK,iBAAiBF,CAAgB;AACvD,QAAIE,MAAa,OAAW,QAAO;AAEnC,QAAIA,EAAS,QAAQ,UAAaA,EAAS,QAAQ;AACjD,aAAO;AAGT,QAAIA,EAAS,iBAAiB,QAAW;AACvC,YAAMC,IAAO,OAAO,KAAKD,EAAS,YAAY;AAC9C,UAAIC,EAAK,WAAW,EAAG,QAAO;AAC9B,iBAAWC,KAAOD;AAChB,YAAID,EAAS,aAAaE,CAAG,MAAM,UAAaF,EAAS,aAAaE,CAAG,MAAM;AAC7E,iBAAO;AAGX,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiBJ,GAA+C;AAEtE,UAAMK,KADgBL,EAAI,eAAeA,EAAI,iBAAiB,WACQA,EAAI;AAC1E,QAAIK,MAAoB,OAAW;AAEnC,UAAMC,IAAuC;AAAA,MAC3C,QAAQN,EAAI,UAAU,CAAA;AAAA,MACtB,QAAQA,EAAI;AAAA,IAAA;AAGd,WAAO;AAAA,MACL,KAAKK,EAAgB,QAAQ,SAAaE,EAAWF,EAAgB,KAAKC,CAAW,IAAe;AAAA,MACpG,cACED,EAAgB,iBAAiB,SAC5BE,EAAWF,EAAgB,cAAcC,CAAW,IACrD;AAAA,IAAA;AAAA,EAEV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,SAASE,GAAcC,GAA8C;AAE3E,QAAID,EAAK,WAAW,SAAS,KAAKA,EAAK,WAAW,UAAU,KAAKA,EAAK,WAAW,IAAI;AACnF,aAAOA;AAIT,QAAIA,EAAK,WAAW,GAAG,GAAG;AACxB,YAAME,IAAOC,EAAeF,CAAU,KAAKE,EAAe,KAAK,QAAQ,KAAK,WAAW,UAAU;AAEjG,UAAI,CAACD;AACH,cAAM,IAAI;AAAA,UACR,qDAAqDF,CAAI;AAAA,QAAA;AAM7D,aAAO,GAAGE,CAAI,GAAGF,CAAI;AAAA,IACvB;AAGA,WAAOA;AAAA,EACT;AAAA,EAEA,MAAc,eACZR,GACAC,GACAW,GACkB;AAClB,UAAMJ,IAAOI,GAAM,QAAQZ,EAAI,UAAUA,EAAI,QAAA,IAAYA,EAAI,OACvDa,IAASb,EAAI,YAAYA,EAAI,UAAA,IAAcA,EAAI,QAC/Cc,IAAmBd,EAAI,kBAAkBA,EAAI,gBAAA,IAAoBA,EAAI,cACrEe,IAAeH,GAAM,eAAe,EAAE,GAAGE,GAAkB,GAAGF,EAAK,aAAA,IAAiBE,GACpFE,IAAOhB,EAAI,UAAUA,EAAI,QAAA,IAAYA,EAAI,MACzCiB,IAAiBjB,EAAI,oBAAoBA,EAAI,kBAAA,IAAsBA,EAAI;AAE7E,QAAI,CAACQ;AACH,YAAM,IAAI,MAAM,8EAA8E;AAGhG,QAAIU,IAAMV;AAEV,QAAIO,GAAc;AAChB,YAAMI,IAAK,IAAI,gBAAA;AACf,iBAAWf,KAAOW,GAAc;AAC9B,cAAMK,IAAML,EAAaX,CAAG;AAC5B,QAAyBgB,KAAQ,QAC/BD,EAAG,OAAOf,GAAK,OAAOgB,CAAG,CAAC;AAAA,MAE9B;AACA,YAAMC,IAAKF,EAAG,SAAA;AACd,MAAIE,MACFH,KAAO,MAAMG;AAAA,IAEjB;AAEA,UAAMZ,IAAaQ,GAAgB,WAAWjB,EAAI,SAC5CsB,IAAU,KAAK,SAASJ,GAAKT,CAAU,GAEvC,EAAE,SAASc,GAAU,QAAQC,GAAS,GAAGC,EAAA,IAAiBR,KAAmB,CAAA,GAG7ES,IADaV,KAAQhB,EAAI,UAE3B;AAAA,MACE,GAAIgB,IAAO,EAAE,gBAAgB,uBAAuB;AAAA,MACpD,GAAIhB,EAAI;AAAA,IAAA,IAEV,QAEE2B,IAAgB,MAAM,KAAK,OAAOL,GAAS;AAAA,MAC/C,QAAAT;AAAA,MACA,SAAAa;AAAA,MACA,MAAMV,IAAO,KAAK,UAAUA,CAAI,IAAI;AAAA,MACpC,QAAAf;AAAA,MACA,GAAGwB;AAAA,IAAA,CACJ;AAED,WAAAzB,EAAI,WAAW2B,GAERA,EAAc,KAAA;AAAA,EACvB;AAAA,EAEA,MAAe,aAAa3B,GAAeC,GAAuC;AAChF,UAAM2B,IAAU5B,GACVQ,IAAOoB,EAAQ,UAAUA,EAAQ,QAAA,IAAYA,EAAQ,MACrDf,IAASe,EAAQ,YAAYA,EAAQ,UAAA,IAAcA,EAAQ,QAC3DZ,IAAOY,EAAQ,UAAUA,EAAQ,QAAA,IAAYA,EAAQ,MACrDX,IAAiBW,EAAQ,oBAAoBA,EAAQ,kBAAA,IAAsBA,EAAQ;AAEzF,QAAI,CAACpB;AACH,YAAM,IAAI,MAAM,iFAAiF;AAGnG,UAAMC,IAAcQ,GAAoD,WAAWW,EAAQ,SACrFN,IAAU,KAAK,SAASd,GAAMC,CAAU,GAExC,EAAE,SAASc,GAAU,QAAQC,GAAS,GAAGC,EAAA,IAAkBR,KAAkB,CAAA,GAE7ES,IAAuB;AAAA,MAC3B,GAAIV,MAAS,SAAY,EAAE,gBAAgB,mBAAA,IAAuB,CAAA;AAAA,MAClE,GAAIY,EAAQ;AAAA,IAAA;AAWd,YARsB,MAAM,KAAK,OAAON,GAAS;AAAA,MAC/C,QAAAT;AAAA,MACA,SAAAa;AAAA,MACA,GAAIV,MAAS,SAAY,EAAE,MAAM,KAAK,UAAUA,CAAI,EAAA,IAAM,CAAA;AAAA,MAC1D,QAAAf;AAAA,MACA,GAAGwB;AAAA,IAAA,CACJ,GAEoB,KAAA;AAAA,EACvB;AACF;AClNO,MAAeI,UAAkBC,EAAM;AAAA,EAC5C,OAAgB,aAAajC;AAAA,EAE7B,SAAsD;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAIA,iBAAyB;AACvB,WAAO,GAAG,KAAK,UAAU,KAAK,IAAI,KAAK,QAAQ,EAAE;AAAA,EACnD;AASF;AC9BO,MAAekC,UAAqBC,EAAS;AAAA,EAClD,OAAgB,aAAanC;AAAA,EAE7B;AAAA,EACA;AAAA,EACA,SAA8C;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EAEA,iBAAyB;AACvB,WAAO,GAAG,KAAK,UAAU,MAAM,IAAI,KAAK,QAAQ,EAAE;AAAA,EACpD;AAMF;"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const o = (s) => `sq:doc:value:${s}`, e = (s) => `sq:doc:refCount:${s}`, c = (s) => `sq:doc:refIds:${s}`, a = (s) => `sq:doc:updatedAt:${s}`, t = (s) => `sq:doc:queue:${s}`, d = (s) => `sq:doc:lastUsed:${s}`, n = (s) => `sq:doc:cacheTime:${s}`, r = "sq:doc:lastUsed:", q = 50, u = 1440, F = 5;
|
|
2
2
|
export {
|
|
3
|
-
|
|
3
|
+
u as D,
|
|
4
4
|
r as L,
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
q as a,
|
|
6
|
+
e as b,
|
|
7
7
|
n as c,
|
|
8
|
-
|
|
8
|
+
F as d,
|
|
9
9
|
d as l,
|
|
10
10
|
t as q,
|
|
11
11
|
c as r,
|
|
12
12
|
a as u,
|
|
13
13
|
o as v
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=shared-
|
|
15
|
+
//# sourceMappingURL=shared-DcuVH8Pf.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-
|
|
1
|
+
{"version":3,"file":"shared-DcuVH8Pf.js","sources":["../../../src/stores/shared.ts"],"sourcesContent":["// Query Instance keys\nexport const valueKeyFor = (id: number) => `sq:doc:value:${id}`;\nexport const refCountKeyFor = (id: number) => `sq:doc:refCount:${id}`;\nexport const refIdsKeyFor = (id: number) => `sq:doc:refIds:${id}`;\nexport const updatedAtKeyFor = (id: number) => `sq:doc:updatedAt:${id}`;\n// Query Type keys\nexport const queueKeyFor = (queryDefId: string) => `sq:doc:queue:${queryDefId}`;\n// Query Type metadata keys (used for stale cache cleanup)\nexport const lastUsedKeyFor = (queryDefId: string) => `sq:doc:lastUsed:${queryDefId}`;\nexport const cacheTimeKeyFor = (queryDefId: string) => `sq:doc:cacheTime:${queryDefId}`;\n\nexport const LAST_USED_PREFIX = 'sq:doc:lastUsed:';\n\n// Default values\nexport const DEFAULT_MAX_COUNT = 50;\nexport const DEFAULT_CACHE_TIME = 60 * 24; // 24 hours in minutes\nexport const DEFAULT_GC_TIME = 5; // 5 minutes - in-memory eviction default\n"],"names":["valueKeyFor","id","refCountKeyFor","refIdsKeyFor","updatedAtKeyFor","queueKeyFor","queryDefId","lastUsedKeyFor","cacheTimeKeyFor","LAST_USED_PREFIX","DEFAULT_MAX_COUNT","DEFAULT_CACHE_TIME","DEFAULT_GC_TIME"],"mappings":"AACO,MAAMA,IAAc,CAACC,MAAe,gBAAgBA,CAAE,IAChDC,IAAiB,CAACD,MAAe,mBAAmBA,CAAE,IACtDE,IAAe,CAACF,MAAe,iBAAiBA,CAAE,IAClDG,IAAkB,CAACH,MAAe,oBAAoBA,CAAE,IAExDI,IAAc,CAACC,MAAuB,gBAAgBA,CAAU,IAEhEC,IAAiB,CAACD,MAAuB,mBAAmBA,CAAU,IACtEE,IAAkB,CAACF,MAAuB,oBAAoBA,CAAU,IAExEG,IAAmB,oBAGnBC,IAAoB,IACpBC,IAAqB,MACrBC,IAAkB;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as h,
|
|
1
|
+
import { u as h, D as d, v as u, r as l, a as v, l as m, c as w, L as y, q as f, b as g } from "../shared-DcuVH8Pf.js";
|
|
2
2
|
class A {
|
|
3
3
|
isWriter;
|
|
4
4
|
delegate;
|
|
@@ -134,13 +134,13 @@ class A {
|
|
|
134
134
|
async writerActivateQuery(e, t, s) {
|
|
135
135
|
if (!await this.delegate.has(u(t)))
|
|
136
136
|
return;
|
|
137
|
-
const a =
|
|
137
|
+
const a = f(e);
|
|
138
138
|
let i = this.queues.get(e);
|
|
139
139
|
if (i === void 0) {
|
|
140
140
|
const o = v;
|
|
141
141
|
i = await this.delegate.getBuffer(a), i === void 0 ? (i = new Uint32Array(o), await this.delegate.setBuffer(a, i)) : i.length !== o && (i = new Uint32Array(i.buffer, 0, o), await this.delegate.setBuffer(a, i)), this.queues.set(e, i);
|
|
142
142
|
}
|
|
143
|
-
await this.delegate.setNumber(m(e), Date.now()), await this.delegate.setNumber(
|
|
143
|
+
await this.delegate.setNumber(m(e), Date.now()), await this.delegate.setNumber(w(e), s);
|
|
144
144
|
const r = i.indexOf(t);
|
|
145
145
|
if (r >= 0) {
|
|
146
146
|
if (r === 0)
|
|
@@ -156,13 +156,13 @@ class A {
|
|
|
156
156
|
const e = await this.delegate.getAllKeys(), t = Date.now();
|
|
157
157
|
for (const s of e) {
|
|
158
158
|
if (!s.startsWith(y)) continue;
|
|
159
|
-
const a = s.slice(y.length), i = await this.delegate.getNumber(s), n = (await this.delegate.getNumber(
|
|
159
|
+
const a = s.slice(y.length), i = await this.delegate.getNumber(s), n = (await this.delegate.getNumber(w(a)) ?? d) * 60 * 1e3;
|
|
160
160
|
if (i === void 0 || t - i > n) {
|
|
161
|
-
const o = await this.delegate.getBuffer(
|
|
161
|
+
const o = await this.delegate.getBuffer(f(a));
|
|
162
162
|
if (o !== void 0)
|
|
163
163
|
for (const c of o)
|
|
164
164
|
c !== 0 && (await this.writerDeleteValue(c), await this.delegate.delete(h(c)));
|
|
165
|
-
await this.delegate.delete(
|
|
165
|
+
await this.delegate.delete(f(a)), await this.delegate.delete(s), await this.delegate.delete(w(a)), this.queues.delete(a);
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as v,
|
|
1
|
+
import { u as v, D as l, v as f, r as h, a as y, q as a, l as C, c as d, L as g, b as k } from "../shared-DcuVH8Pf.js";
|
|
2
2
|
class N {
|
|
3
3
|
kv = /* @__PURE__ */ Object.create(null);
|
|
4
4
|
has(e) {
|
|
@@ -35,7 +35,7 @@ class S {
|
|
|
35
35
|
}
|
|
36
36
|
queues = /* @__PURE__ */ new Map();
|
|
37
37
|
loadQuery(e, s) {
|
|
38
|
-
const i = this.kv.getNumber(v(s)), t = (e.statics.cache?.cacheTime ??
|
|
38
|
+
const i = this.kv.getNumber(v(s)), t = (e.statics.cache?.cacheTime ?? l) * 60 * 1e3;
|
|
39
39
|
if (i === void 0 || i < Date.now() - t)
|
|
40
40
|
return;
|
|
41
41
|
const n = this.kv.getString(f(s));
|
|
@@ -75,7 +75,7 @@ class S {
|
|
|
75
75
|
const o = e.statics.cache?.maxCount ?? y;
|
|
76
76
|
t = this.kv.getBuffer(a(i)), t === void 0 ? (t = new Uint32Array(o), this.kv.setBuffer(a(i), t)) : t.length !== o && (t = new Uint32Array(t.buffer, 0, o), this.kv.setBuffer(a(i), t)), this.queues.set(i, t);
|
|
77
77
|
}
|
|
78
|
-
this.kv.setNumber(C(i), Date.now()), this.kv.setNumber(
|
|
78
|
+
this.kv.setNumber(C(i), Date.now()), this.kv.setNumber(d(i), e.statics.cache?.cacheTime ?? l);
|
|
79
79
|
const n = t.indexOf(s);
|
|
80
80
|
if (n >= 0) {
|
|
81
81
|
if (n === 0)
|
|
@@ -90,13 +90,13 @@ class S {
|
|
|
90
90
|
const e = this.kv.getAllKeys(), s = Date.now();
|
|
91
91
|
for (const i of e) {
|
|
92
92
|
if (!i.startsWith(g)) continue;
|
|
93
|
-
const t = i.slice(g.length), n = this.kv.getNumber(i), o = (this.kv.getNumber(
|
|
93
|
+
const t = i.slice(g.length), n = this.kv.getNumber(i), o = (this.kv.getNumber(d(t)) ?? l) * 60 * 1e3;
|
|
94
94
|
if (n === void 0 || s - n > o) {
|
|
95
95
|
const c = this.kv.getBuffer(a(t));
|
|
96
96
|
if (c !== void 0)
|
|
97
97
|
for (const u of c)
|
|
98
98
|
u !== 0 && (this.deleteQuery(u), this.kv.delete(v(u)));
|
|
99
|
-
this.kv.delete(a(t)), this.kv.delete(i), this.kv.delete(
|
|
99
|
+
this.kv.delete(a(t)), this.kv.delete(i), this.kv.delete(d(t)), this.queues.delete(t);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { f as a } from "../QueryClient-YqnBxFy1.js";
|
|
2
|
+
import { Q as d } from "../QueryController-Ch_ncxiI.js";
|
|
3
|
+
class g extends a {
|
|
4
|
+
static controller;
|
|
5
|
+
getIdentityKey() {
|
|
6
|
+
return `topic:${this.topic}`;
|
|
7
|
+
}
|
|
8
|
+
getConfig() {
|
|
9
|
+
return {
|
|
10
|
+
staleTime: 0,
|
|
11
|
+
subscribe: () => () => {
|
|
12
|
+
this._topicController?.unsubscribe(this.topic);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class _ extends d {
|
|
18
|
+
_topics = /* @__PURE__ */ new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the pending promise for a topic with initial data.
|
|
21
|
+
* Can be called before `send()` — the data will be picked up
|
|
22
|
+
* when the query activates.
|
|
23
|
+
*/
|
|
24
|
+
fulfillTopic(e, s) {
|
|
25
|
+
const t = this._topics.get(e);
|
|
26
|
+
if (t === void 0) {
|
|
27
|
+
this._topics.set(e, { status: "fulfilled", data: s });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
t.status === "pending" && (t.status = "fulfilled", t.data = s, t.resolve(s));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Reject the pending promise for a topic.
|
|
34
|
+
* Can be called before `send()` — the error will be propagated
|
|
35
|
+
* when the query activates.
|
|
36
|
+
*/
|
|
37
|
+
rejectTopic(e, s) {
|
|
38
|
+
const t = this._topics.get(e);
|
|
39
|
+
if (t === void 0) {
|
|
40
|
+
this._topics.set(e, { status: "rejected", error: s });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
t.status === "pending" && (t.status = "rejected", t.error = s, t.reject(s));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Clears internal state for a topic. Called automatically by
|
|
47
|
+
* `unsubscribe` — subclasses generally don't need to call this.
|
|
48
|
+
*/
|
|
49
|
+
clearTopic(e) {
|
|
50
|
+
this._topics.delete(e);
|
|
51
|
+
}
|
|
52
|
+
clearAll() {
|
|
53
|
+
this._topics.clear();
|
|
54
|
+
}
|
|
55
|
+
async send(e, s) {
|
|
56
|
+
const t = e;
|
|
57
|
+
t._topicController = this;
|
|
58
|
+
const r = t.topic, i = this._topics.get(r);
|
|
59
|
+
if (i)
|
|
60
|
+
switch (i.status) {
|
|
61
|
+
case "fulfilled":
|
|
62
|
+
return i.data;
|
|
63
|
+
case "rejected":
|
|
64
|
+
throw i.error;
|
|
65
|
+
case "pending":
|
|
66
|
+
return i.promise;
|
|
67
|
+
}
|
|
68
|
+
let o, c;
|
|
69
|
+
const n = new Promise((p, u) => {
|
|
70
|
+
o = p, c = u;
|
|
71
|
+
});
|
|
72
|
+
return this._topics.set(r, { status: "pending", promise: n, resolve: o, reject: c }), this.subscribe(r), n;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Convenience wrapper — pushes a mutation event through the QueryClient
|
|
76
|
+
* so that entities and live collections are updated reactively.
|
|
77
|
+
*/
|
|
78
|
+
sendMutationEvent(e) {
|
|
79
|
+
this.queryClient.applyMutationEvent(e);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
g as TopicQuery,
|
|
84
|
+
_ as TopicQueryController
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=index.js.map
|