@kasperrt/smolter 0.4.2 → 0.4.4
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/.generated/client/hash-history.ts +27 -0
- package/.generated/client/hydration.ts +98 -0
- package/.generated/client/root-data.ts +52 -0
- package/.generated/core/environment.ts +1 -0
- package/.generated/core/navigation.ts +1 -0
- package/.generated/core/prepare-routes.ts +50 -0
- package/.generated/core/presentation.ts +1 -1
- package/.generated/core/responses.ts +12 -0
- package/.generated/core/utils.ts +5 -2
- package/.generated/preact/await.tsx +1 -0
- package/.generated/preact/client.tsx +8 -27
- package/.generated/preact/deferred-hydration.ts +1 -98
- package/.generated/preact/document.tsx +10 -0
- package/.generated/preact/index.ts +11 -2
- package/.generated/preact/lazy-route.ts +7 -0
- package/.generated/preact/navigation.tsx +19 -5
- package/.generated/preact/root-data.ts +1 -45
- package/.generated/preact/route-hooks.tsx +12 -2
- package/.generated/preact/route-types.ts +14 -0
- package/.generated/preact/router.tsx +5 -48
- package/.generated/react/client.tsx +130 -0
- package/.generated/react/document.tsx +235 -0
- package/.generated/react/fetcher.ts +29 -7
- package/.generated/react/hooks.ts +20 -18
- package/.generated/react/index.ts +28 -2
- package/.generated/react/lazy-route.ts +116 -0
- package/.generated/react/link.ts +1 -38
- package/.generated/react/navigation-state.ts +13 -0
- package/.generated/react/navigation.ts +145 -0
- package/.generated/react/outlet.ts +48 -0
- package/.generated/react/root-context.ts +22 -0
- package/.generated/react/route-hooks.ts +159 -0
- package/.generated/react/route-types.ts +91 -0
- package/.generated/react/router.ts +50 -0
- package/.generated/react/runtime.ts +1 -0
- package/.generated/server/application.tsx +18 -250
- package/.generated/server/assets.ts +7 -0
- package/.generated/server/dispatch.ts +87 -0
- package/.generated/server/handler.ts +3 -0
- package/.generated/server/http.ts +2 -0
- package/.generated/server/index.ts +2 -0
- package/.generated/server/node.ts +5 -2
- package/.generated/server/preact.ts +5 -2
- package/.generated/server/react.ts +34 -0
- package/.generated/server/render-application.ts +203 -0
- package/.generated/vite/application/lazy-files.ts +2 -1
- package/.generated/vite/application/vite.ts +12 -4
- package/.generated/vite/react.ts +11 -0
- package/CHANGELOG.md +20 -0
- package/README.md +48 -48
- package/dist/client/hash-history.d.ts +2 -0
- package/dist/client/hash-history.js +26 -0
- package/dist/client/hydration.d.ts +10 -0
- package/dist/{preact/deferred-hydration.js → client/hydration.js} +1 -1
- package/dist/client/root-data.d.ts +14 -0
- package/dist/{preact → client}/root-data.js +1 -1
- package/dist/core/environment.d.ts +1 -0
- package/dist/core/navigation.d.ts +1 -0
- package/dist/core/prepare-routes.d.ts +7 -0
- package/dist/core/prepare-routes.js +28 -0
- package/dist/core/presentation.js +1 -1
- package/dist/core/responses.d.ts +12 -0
- package/dist/core/responses.js +5 -0
- package/dist/core/utils.d.ts +5 -2
- package/dist/core/utils.js +1 -2
- package/dist/preact/await.d.ts +1 -0
- package/dist/preact/await.js +1 -0
- package/dist/preact/client.d.ts +7 -1
- package/dist/preact/client.js +11 -27
- package/dist/preact/deferred-hydration.d.ts +1 -10
- package/dist/preact/document.d.ts +10 -0
- package/dist/preact/document.js +11 -2
- package/dist/preact/index.d.ts +6 -2
- package/dist/preact/index.js +1 -1
- package/dist/preact/lazy-route.d.ts +2 -0
- package/dist/preact/lazy-route.js +6 -0
- package/dist/preact/navigation-state.js +1 -1
- package/dist/preact/navigation.d.ts +6 -0
- package/dist/preact/navigation.js +9 -5
- package/dist/preact/root-data.d.ts +1 -8
- package/dist/preact/route-hooks.d.ts +10 -0
- package/dist/preact/route-hooks.js +13 -3
- package/dist/preact/route-types.d.ts +14 -0
- package/dist/preact/router.d.ts +5 -2
- package/dist/preact/router.js +4 -26
- package/dist/react/client.d.ts +20 -0
- package/dist/react/client.js +86 -0
- package/dist/react/document.d.ts +25 -0
- package/dist/react/document.js +169 -0
- package/dist/react/fetcher.d.ts +8 -4
- package/dist/react/fetcher.js +12 -1
- package/dist/react/form.js +1 -1
- package/dist/react/hooks.d.ts +7 -6
- package/dist/react/index.d.ts +13 -2
- package/dist/react/index.js +7 -2
- package/dist/react/lazy-route.d.ts +22 -0
- package/dist/react/lazy-route.js +57 -0
- package/dist/react/link.d.ts +1 -12
- package/dist/react/navigation-state.d.ts +2 -0
- package/dist/react/navigation-state.js +9 -0
- package/dist/react/navigation.d.ts +33 -0
- package/dist/react/navigation.js +64 -0
- package/dist/react/outlet.d.ts +16 -0
- package/dist/react/outlet.js +26 -0
- package/dist/react/root-context.d.ts +14 -0
- package/dist/react/root-context.js +10 -0
- package/dist/react/route-hooks.d.ts +34 -0
- package/dist/react/route-hooks.js +89 -0
- package/dist/react/route-types.d.ts +69 -0
- package/dist/react/router.d.ts +10 -0
- package/dist/react/router.js +22 -0
- package/dist/react/runtime.d.ts +1 -1
- package/dist/react/runtime.js +1 -1
- package/dist/server/application.d.ts +4 -5
- package/dist/server/application.js +9 -154
- package/dist/server/assets.d.ts +2 -0
- package/dist/server/assets.js +6 -0
- package/dist/server/dispatch.d.ts +5 -0
- package/dist/server/dispatch.js +50 -0
- package/dist/server/handler.d.ts +3 -0
- package/dist/server/http.d.ts +2 -0
- package/dist/server/http.js +2 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +2 -1
- package/dist/server/node.d.ts +5 -1
- package/dist/server/preact.d.ts +5 -1
- package/dist/server/preact.js +2 -1
- package/dist/server/react.d.ts +10 -0
- package/dist/server/react.js +22 -0
- package/dist/server/render-application.d.ts +31 -0
- package/dist/server/render-application.js +118 -0
- package/dist/vite/application/lazy-files.d.ts +1 -1
- package/dist/vite/application/lazy-files.js +2 -2
- package/dist/vite/application/vite.d.ts +2 -1
- package/dist/vite/application/vite.js +12 -5
- package/dist/vite/react.d.ts +4 -0
- package/dist/vite/react.js +9 -1
- package/jsr.json +10 -6
- package/package.json +21 -12
- package/.generated/core/resource-types.ts +0 -44
- package/.generated/core/resources.ts +0 -444
- package/.generated/react/data.ts +0 -25
- package/.generated/react/resources/components.tsx +0 -404
- package/dist/core/resource-types.d.ts +0 -37
- package/dist/core/resources.d.ts +0 -19
- package/dist/core/resources.js +0 -345
- package/dist/react/data.d.ts +0 -5
- package/dist/react/data.js +0 -3
- package/dist/react/link.js +0 -27
- package/dist/react/resources/components.d.ts +0 -64
- package/dist/react/resources/components.js +0 -239
package/dist/core/resources.js
DELETED
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
import { safeWrapAsync } from "./errors.js";
|
|
2
|
-
//#region .generated/core/resources.ts
|
|
3
|
-
var IDLE_ROUTE_STATE = {
|
|
4
|
-
actionData: null,
|
|
5
|
-
actionError: "",
|
|
6
|
-
actionState: "idle",
|
|
7
|
-
loaderData: null,
|
|
8
|
-
loaderError: "",
|
|
9
|
-
loaderInitialized: false,
|
|
10
|
-
loaderState: "idle",
|
|
11
|
-
navigationState: "idle",
|
|
12
|
-
unexpectedError: false
|
|
13
|
-
};
|
|
14
|
-
var ResourceRouter = class {
|
|
15
|
-
#cleanupTimers = /* @__PURE__ */ new Map();
|
|
16
|
-
#controllers = /* @__PURE__ */ new Map();
|
|
17
|
-
#inFlightLoads = /* @__PURE__ */ new Map();
|
|
18
|
-
#listeners = /* @__PURE__ */ new Map();
|
|
19
|
-
#persistentRoutes = /* @__PURE__ */ new Set();
|
|
20
|
-
#routes;
|
|
21
|
-
#states = /* @__PURE__ */ new Map();
|
|
22
|
-
constructor(routes) {
|
|
23
|
-
this.#routes = routes;
|
|
24
|
-
}
|
|
25
|
-
dispose() {
|
|
26
|
-
for (const controller of this.#controllers.values()) controller.abort();
|
|
27
|
-
this.#controllers.clear();
|
|
28
|
-
for (const timer of this.#cleanupTimers.values()) clearTimeout(timer);
|
|
29
|
-
this.#cleanupTimers.clear();
|
|
30
|
-
this.#inFlightLoads.clear();
|
|
31
|
-
this.#listeners.clear();
|
|
32
|
-
this.#persistentRoutes.clear();
|
|
33
|
-
}
|
|
34
|
-
getRoute(routeId) {
|
|
35
|
-
return this.#routes.get(routeId) ?? null;
|
|
36
|
-
}
|
|
37
|
-
getSnapshot(routeId, params) {
|
|
38
|
-
return this.#states.get(createRouteKey(routeId, params)) ?? IDLE_ROUTE_STATE;
|
|
39
|
-
}
|
|
40
|
-
hydrateRoute(routeId, data, params = {}) {
|
|
41
|
-
const routeKey = createRouteKey(routeId, params);
|
|
42
|
-
const currentState = this.#states.get(routeKey) ?? IDLE_ROUTE_STATE;
|
|
43
|
-
this.#setState(routeKey, {
|
|
44
|
-
...currentState,
|
|
45
|
-
loaderData: data,
|
|
46
|
-
loaderError: "",
|
|
47
|
-
loaderInitialized: true,
|
|
48
|
-
loaderState: "idle",
|
|
49
|
-
navigationState: currentState.actionState === "submitting" ? "submitting" : "idle",
|
|
50
|
-
unexpectedError: false
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
persist(routeId, params = {}) {
|
|
54
|
-
const routeKey = createRouteKey(routeId, params);
|
|
55
|
-
this.#persistentRoutes.add(routeKey);
|
|
56
|
-
const cleanupTimer = this.#cleanupTimers.get(routeKey);
|
|
57
|
-
if (!cleanupTimer) return;
|
|
58
|
-
clearTimeout(cleanupTimer);
|
|
59
|
-
this.#cleanupTimers.delete(routeKey);
|
|
60
|
-
}
|
|
61
|
-
disposeRoute(routeId, params = {}) {
|
|
62
|
-
this.#disposeRouteKey(createRouteKey(routeId, params));
|
|
63
|
-
}
|
|
64
|
-
#disposeRouteKey(routeKey) {
|
|
65
|
-
this.#persistentRoutes.delete(routeKey);
|
|
66
|
-
const cleanupTimer = this.#cleanupTimers.get(routeKey);
|
|
67
|
-
if (cleanupTimer) clearTimeout(cleanupTimer);
|
|
68
|
-
this.#cleanupTimers.delete(routeKey);
|
|
69
|
-
this.#controllers.get(routeKey)?.abort();
|
|
70
|
-
this.#controllers.get(`${routeKey}:action`)?.abort();
|
|
71
|
-
this.#controllers.delete(routeKey);
|
|
72
|
-
this.#controllers.delete(`${routeKey}:action`);
|
|
73
|
-
this.#inFlightLoads.delete(routeKey);
|
|
74
|
-
this.#states.delete(routeKey);
|
|
75
|
-
this.#notify(routeKey);
|
|
76
|
-
}
|
|
77
|
-
load(routeId, params = {}, force = false) {
|
|
78
|
-
const routeKey = createRouteKey(routeId, params);
|
|
79
|
-
const route = this.#routes.get(routeId);
|
|
80
|
-
if (!route?.loader) return Promise.resolve({
|
|
81
|
-
data: null,
|
|
82
|
-
error: "Route loader not found."
|
|
83
|
-
});
|
|
84
|
-
const currentState = this.#states.get(routeKey);
|
|
85
|
-
if (!force && currentState?.loaderInitialized) return Promise.resolve({
|
|
86
|
-
data: currentState?.loaderData,
|
|
87
|
-
error: currentState?.loaderError ?? ""
|
|
88
|
-
});
|
|
89
|
-
const currentLoad = this.#inFlightLoads.get(routeKey);
|
|
90
|
-
if (force && currentLoad) {
|
|
91
|
-
this.#controllers.get(routeKey)?.abort();
|
|
92
|
-
this.#inFlightLoads.delete(routeKey);
|
|
93
|
-
}
|
|
94
|
-
if (!force && currentLoad) return currentLoad;
|
|
95
|
-
const controller = this.#replaceController(routeKey);
|
|
96
|
-
this.#setState(routeKey, {
|
|
97
|
-
...currentState ?? IDLE_ROUTE_STATE,
|
|
98
|
-
loaderError: "",
|
|
99
|
-
loaderState: "loading",
|
|
100
|
-
navigationState: currentState?.actionState === "submitting" ? "submitting" : "loading",
|
|
101
|
-
unexpectedError: false
|
|
102
|
-
});
|
|
103
|
-
const load = this.#runLoader(route, routeKey, params, controller);
|
|
104
|
-
this.#inFlightLoads.set(routeKey, load);
|
|
105
|
-
return load;
|
|
106
|
-
}
|
|
107
|
-
subscribe(routeId, params, listener) {
|
|
108
|
-
const routeKey = createRouteKey(routeId, params);
|
|
109
|
-
const cleanupTimer = this.#cleanupTimers.get(routeKey);
|
|
110
|
-
if (cleanupTimer) {
|
|
111
|
-
clearTimeout(cleanupTimer);
|
|
112
|
-
this.#cleanupTimers.delete(routeKey);
|
|
113
|
-
}
|
|
114
|
-
const listeners = this.#listeners.get(routeKey) ?? /* @__PURE__ */ new Set();
|
|
115
|
-
listeners.add(listener);
|
|
116
|
-
this.#listeners.set(routeKey, listeners);
|
|
117
|
-
return () => {
|
|
118
|
-
if (!listeners.delete(listener) || listeners.size > 0) return;
|
|
119
|
-
this.#listeners.delete(routeKey);
|
|
120
|
-
if (this.#persistentRoutes.has(routeKey)) return;
|
|
121
|
-
const timer = setTimeout(() => this.#disposeRouteKey(routeKey), routeCleanupGraceMs);
|
|
122
|
-
this.#cleanupTimers.set(routeKey, timer);
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
async submit(routeId, input, params = {}) {
|
|
126
|
-
const routeKey = createRouteKey(routeId, params);
|
|
127
|
-
const route = this.#routes.get(routeId);
|
|
128
|
-
if (!route?.action) return {
|
|
129
|
-
data: null,
|
|
130
|
-
error: "Route action not found."
|
|
131
|
-
};
|
|
132
|
-
const controllerKey = `${routeKey}:action`;
|
|
133
|
-
const controller = this.#replaceController(controllerKey);
|
|
134
|
-
const currentState = this.#states.get(routeKey) ?? IDLE_ROUTE_STATE;
|
|
135
|
-
this.#setState(routeKey, {
|
|
136
|
-
...currentState,
|
|
137
|
-
actionError: "",
|
|
138
|
-
actionState: "submitting",
|
|
139
|
-
navigationState: "submitting",
|
|
140
|
-
unexpectedError: false
|
|
141
|
-
});
|
|
142
|
-
const { error, data: result } = await safeWrapAsync(() => route.action?.({
|
|
143
|
-
input,
|
|
144
|
-
params,
|
|
145
|
-
signal: controller.signal
|
|
146
|
-
}));
|
|
147
|
-
if (this.#controllers.get(controllerKey) === controller) this.#controllers.delete(controllerKey);
|
|
148
|
-
if (controller.signal.aborted) return {
|
|
149
|
-
data: null,
|
|
150
|
-
error: ""
|
|
151
|
-
};
|
|
152
|
-
const latestState = this.#states.get(routeKey) ?? IDLE_ROUTE_STATE;
|
|
153
|
-
if (error || !result) {
|
|
154
|
-
const publicError = "The request could not be completed.";
|
|
155
|
-
this.#setState(routeKey, {
|
|
156
|
-
...latestState,
|
|
157
|
-
actionData: null,
|
|
158
|
-
actionError: publicError,
|
|
159
|
-
actionState: "idle",
|
|
160
|
-
navigationState: latestState.loaderState === "loading" ? "loading" : "idle",
|
|
161
|
-
unexpectedError: true
|
|
162
|
-
});
|
|
163
|
-
return {
|
|
164
|
-
data: null,
|
|
165
|
-
error: publicError,
|
|
166
|
-
unexpected: true
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
this.#setState(routeKey, {
|
|
170
|
-
...latestState,
|
|
171
|
-
actionData: result.data,
|
|
172
|
-
actionError: result.error,
|
|
173
|
-
actionState: "idle",
|
|
174
|
-
navigationState: latestState.loaderState === "loading" ? "loading" : "idle",
|
|
175
|
-
unexpectedError: false
|
|
176
|
-
});
|
|
177
|
-
const actionResult = {
|
|
178
|
-
data: result.data,
|
|
179
|
-
error: result.error
|
|
180
|
-
};
|
|
181
|
-
const { error: revalidationError, data: shouldRevalidate } = await safeWrapAsync(() => route.shouldRevalidate?.({
|
|
182
|
-
actionResult: result,
|
|
183
|
-
defaultShouldRevalidate: Boolean(route.loader),
|
|
184
|
-
params
|
|
185
|
-
}) ?? Boolean(route.loader));
|
|
186
|
-
if (revalidationError) {
|
|
187
|
-
const publicError = "The request could not be completed.";
|
|
188
|
-
this.#setState(routeKey, {
|
|
189
|
-
...this.#states.get(routeKey) ?? IDLE_ROUTE_STATE,
|
|
190
|
-
actionError: publicError,
|
|
191
|
-
actionState: "idle",
|
|
192
|
-
unexpectedError: true
|
|
193
|
-
});
|
|
194
|
-
return {
|
|
195
|
-
data: null,
|
|
196
|
-
error: publicError,
|
|
197
|
-
unexpected: true
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
if (shouldRevalidate) await this.load(routeId, params, true);
|
|
201
|
-
return actionResult;
|
|
202
|
-
}
|
|
203
|
-
async fetchLoader(routeId, params, signal) {
|
|
204
|
-
const route = this.#routes.get(routeId);
|
|
205
|
-
if (!route?.loader) return {
|
|
206
|
-
data: null,
|
|
207
|
-
error: "Route loader not found."
|
|
208
|
-
};
|
|
209
|
-
const { error, data: result } = await safeWrapAsync(() => route.loader?.({
|
|
210
|
-
params,
|
|
211
|
-
signal
|
|
212
|
-
}));
|
|
213
|
-
if (signal.aborted) return {
|
|
214
|
-
data: null,
|
|
215
|
-
error: ""
|
|
216
|
-
};
|
|
217
|
-
if (error || !result) return {
|
|
218
|
-
data: null,
|
|
219
|
-
error: "The route could not be loaded.",
|
|
220
|
-
unexpected: true
|
|
221
|
-
};
|
|
222
|
-
return result;
|
|
223
|
-
}
|
|
224
|
-
async fetchAction(routeId, input, params, signal) {
|
|
225
|
-
const route = this.#routes.get(routeId);
|
|
226
|
-
if (!route?.action) return {
|
|
227
|
-
data: null,
|
|
228
|
-
error: "Route action not found."
|
|
229
|
-
};
|
|
230
|
-
const { error, data: result } = await safeWrapAsync(() => route.action?.({
|
|
231
|
-
input,
|
|
232
|
-
params,
|
|
233
|
-
signal
|
|
234
|
-
}));
|
|
235
|
-
if (signal.aborted) return {
|
|
236
|
-
data: null,
|
|
237
|
-
error: ""
|
|
238
|
-
};
|
|
239
|
-
if (error || !result) return {
|
|
240
|
-
data: null,
|
|
241
|
-
error: "The request could not be completed.",
|
|
242
|
-
unexpected: true
|
|
243
|
-
};
|
|
244
|
-
const { error: revalidationError, data: shouldRevalidate } = await safeWrapAsync(() => route.shouldRevalidate?.({
|
|
245
|
-
actionResult: result,
|
|
246
|
-
defaultShouldRevalidate: Boolean(route.loader),
|
|
247
|
-
params
|
|
248
|
-
}) ?? Boolean(route.loader));
|
|
249
|
-
if (signal.aborted) return {
|
|
250
|
-
data: null,
|
|
251
|
-
error: ""
|
|
252
|
-
};
|
|
253
|
-
if (revalidationError) return {
|
|
254
|
-
data: null,
|
|
255
|
-
error: "The request could not be completed.",
|
|
256
|
-
unexpected: true
|
|
257
|
-
};
|
|
258
|
-
if (shouldRevalidate) await this.load(routeId, params, true);
|
|
259
|
-
return result;
|
|
260
|
-
}
|
|
261
|
-
retry(routeId, params) {
|
|
262
|
-
const routeKey = createRouteKey(routeId, params);
|
|
263
|
-
this.#states.set(routeKey, IDLE_ROUTE_STATE);
|
|
264
|
-
this.#notify(routeKey);
|
|
265
|
-
return this.load(routeId, params, true);
|
|
266
|
-
}
|
|
267
|
-
reportUnexpected(routeId, params) {
|
|
268
|
-
const routeKey = createRouteKey(routeId, params);
|
|
269
|
-
const currentState = this.#states.get(routeKey) ?? IDLE_ROUTE_STATE;
|
|
270
|
-
this.#setState(routeKey, {
|
|
271
|
-
...currentState,
|
|
272
|
-
unexpectedError: true
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
async #runLoader(route, routeKey, params, controller) {
|
|
276
|
-
const { error, data: result } = await safeWrapAsync(() => route.loader?.({
|
|
277
|
-
params,
|
|
278
|
-
signal: controller.signal
|
|
279
|
-
}) ?? Promise.resolve({
|
|
280
|
-
data: null,
|
|
281
|
-
error: ""
|
|
282
|
-
}));
|
|
283
|
-
if (this.#controllers.get(routeKey) === controller) {
|
|
284
|
-
this.#controllers.delete(routeKey);
|
|
285
|
-
this.#inFlightLoads.delete(routeKey);
|
|
286
|
-
}
|
|
287
|
-
if (controller.signal.aborted) return {
|
|
288
|
-
data: null,
|
|
289
|
-
error: ""
|
|
290
|
-
};
|
|
291
|
-
if (error || !result) {
|
|
292
|
-
const publicError = "The route could not be loaded.";
|
|
293
|
-
this.#setState(routeKey, {
|
|
294
|
-
actionData: null,
|
|
295
|
-
actionError: "",
|
|
296
|
-
actionState: "idle",
|
|
297
|
-
loaderData: null,
|
|
298
|
-
loaderError: publicError,
|
|
299
|
-
loaderInitialized: true,
|
|
300
|
-
loaderState: "idle",
|
|
301
|
-
navigationState: "idle",
|
|
302
|
-
unexpectedError: true
|
|
303
|
-
});
|
|
304
|
-
return {
|
|
305
|
-
data: null,
|
|
306
|
-
error: publicError,
|
|
307
|
-
unexpected: true
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
const currentState = this.#states.get(routeKey) ?? IDLE_ROUTE_STATE;
|
|
311
|
-
this.#setState(routeKey, {
|
|
312
|
-
...currentState,
|
|
313
|
-
loaderData: result.data,
|
|
314
|
-
loaderError: result.error,
|
|
315
|
-
loaderInitialized: true,
|
|
316
|
-
loaderState: "idle",
|
|
317
|
-
navigationState: currentState.actionState === "submitting" ? "submitting" : "idle",
|
|
318
|
-
unexpectedError: false
|
|
319
|
-
});
|
|
320
|
-
return result;
|
|
321
|
-
}
|
|
322
|
-
#replaceController(key) {
|
|
323
|
-
this.#controllers.get(key)?.abort();
|
|
324
|
-
const controller = new AbortController();
|
|
325
|
-
this.#controllers.set(key, controller);
|
|
326
|
-
return controller;
|
|
327
|
-
}
|
|
328
|
-
#setState(routeKey, state) {
|
|
329
|
-
this.#states.set(routeKey, state);
|
|
330
|
-
this.#notify(routeKey);
|
|
331
|
-
}
|
|
332
|
-
#notify(routeKey) {
|
|
333
|
-
for (const listener of this.#listeners.get(routeKey) ?? []) listener();
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
function createResourceRouter(routes) {
|
|
337
|
-
return new ResourceRouter(routes);
|
|
338
|
-
}
|
|
339
|
-
function createRouteKey(routeId, params) {
|
|
340
|
-
const normalizedParams = Object.entries(params).sort(([left], [right]) => left.localeCompare(right));
|
|
341
|
-
return `${routeId}:${JSON.stringify(normalizedParams)}`;
|
|
342
|
-
}
|
|
343
|
-
var routeCleanupGraceMs = 100;
|
|
344
|
-
//#endregion
|
|
345
|
-
export { ResourceRouter, createResourceRouter };
|
package/dist/react/data.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/** Resource subscriptions independent of URL navigation. @module */
|
|
2
|
-
export type { ActionFunctionArgs as ResourceActionArgs, DataResult as ResourceResult, LoaderFunctionArgs as ResourceLoaderArgs, ShouldRevalidateFunctionArgs as ResourceRevalidationArgs, } from "../core/resource-types.ts";
|
|
3
|
-
export { createResourceRouter, ResourceRouter, } from "../core/resources.ts";
|
|
4
|
-
export type { ResourceRouteModule } from "./resources/components.tsx";
|
|
5
|
-
export { Form as ResourceForm, Route as Resource, RouterProvider as ResourceProvider, useActionData as useResourceActionData, useFetcher as useResourceFetcher, useLoaderData as useResourceData, useNavigation as useResourceNavigation, useRevalidator as useResourceRevalidator, useRouteLoaderData, useRouter as useResourceRouter, useSubmit as useResourceSubmit, } from "./resources/components.tsx";
|
package/dist/react/data.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { ResourceRouter, createResourceRouter } from "../core/resources.js";
|
|
2
|
-
import { Form, Route, RouterProvider, useActionData, useFetcher, useLoaderData, useNavigation, useRevalidator, useRouteLoaderData, useRouter, useSubmit } from "./resources/components.js";
|
|
3
|
-
export { Route as Resource, Form as ResourceForm, RouterProvider as ResourceProvider, ResourceRouter, createResourceRouter, useActionData as useResourceActionData, useLoaderData as useResourceData, useFetcher as useResourceFetcher, useNavigation as useResourceNavigation, useRevalidator as useResourceRevalidator, useRouter as useResourceRouter, useSubmit as useResourceSubmit, useRouteLoaderData };
|
package/dist/react/link.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { internalURL, navigationClick } from "../core/url.js";
|
|
2
|
-
import { createElement } from "./runtime.js";
|
|
3
|
-
import { useRouter } from "./context.js";
|
|
4
|
-
//#region .generated/react/link.ts
|
|
5
|
-
/**
|
|
6
|
-
* React components and typed data hooks. Import from @kasperrt/smolter/react.
|
|
7
|
-
* @module
|
|
8
|
-
*/
|
|
9
|
-
/** Render an anchor that handles internal navigation and preserves native modified clicks. */
|
|
10
|
-
function Link(options) {
|
|
11
|
-
const { href, replace, onClick, ...props } = options;
|
|
12
|
-
const router = useRouter();
|
|
13
|
-
const click = (event) => {
|
|
14
|
-
onClick?.(event);
|
|
15
|
-
if (!navigationClick(event, event.currentTarget)) return;
|
|
16
|
-
if (!internalURL(router.getSnapshot().url, href)) return;
|
|
17
|
-
event.preventDefault();
|
|
18
|
-
router.navigate(href, options);
|
|
19
|
-
};
|
|
20
|
-
return createElement("a", {
|
|
21
|
-
...props,
|
|
22
|
-
href,
|
|
23
|
-
onClick: click
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
27
|
-
export { Link };
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/** @jsxImportSource react */
|
|
2
|
-
import type { DataResult, NavigationState, Params, ResourceModule, RouteState } from "../../core/resource-types.ts";
|
|
3
|
-
import type { ResourceRouter } from "../../core/resources.ts";
|
|
4
|
-
import { type ComponentType, type PropsWithChildren } from "react";
|
|
5
|
-
export interface ResourceRouteModule extends ResourceModule {
|
|
6
|
-
default?: ComponentType;
|
|
7
|
-
ErrorBoundary?: ComponentType<{
|
|
8
|
-
retry: () => void;
|
|
9
|
-
}>;
|
|
10
|
-
HydrateFallback?: ComponentType;
|
|
11
|
-
}
|
|
12
|
-
interface RouterProviderProps extends PropsWithChildren {
|
|
13
|
-
initialMatches?: readonly {
|
|
14
|
-
params?: Params;
|
|
15
|
-
routeId: string;
|
|
16
|
-
}[];
|
|
17
|
-
router: ResourceRouter;
|
|
18
|
-
}
|
|
19
|
-
export declare function RouterProvider({ children, initialMatches, router, }: RouterProviderProps): import("react").JSX.Element;
|
|
20
|
-
interface RouteProps extends PropsWithChildren {
|
|
21
|
-
params?: Params;
|
|
22
|
-
persistent?: boolean;
|
|
23
|
-
routeId: string;
|
|
24
|
-
}
|
|
25
|
-
export declare function Route({ children, params, persistent, routeId, }: RouteProps): import("react").JSX.Element;
|
|
26
|
-
export declare function useLoaderData<Data>(): Data | null;
|
|
27
|
-
export declare function useRouteLoaderData<Data>(routeId: string, params?: Params): Data | null;
|
|
28
|
-
export declare function useActionData<Data>(): Data | null;
|
|
29
|
-
export declare function useNavigation(): {
|
|
30
|
-
state: NavigationState;
|
|
31
|
-
};
|
|
32
|
-
export declare function useRevalidator(): {
|
|
33
|
-
revalidate: () => Promise<DataResult<unknown>>;
|
|
34
|
-
state: string;
|
|
35
|
-
};
|
|
36
|
-
interface FetcherOptions {
|
|
37
|
-
params?: Params;
|
|
38
|
-
routeId?: string;
|
|
39
|
-
}
|
|
40
|
-
interface FetcherTarget {
|
|
41
|
-
params?: Params;
|
|
42
|
-
routeId?: string;
|
|
43
|
-
}
|
|
44
|
-
interface FormProps extends PropsWithChildren {
|
|
45
|
-
action?: string;
|
|
46
|
-
input?: unknown;
|
|
47
|
-
params?: Params;
|
|
48
|
-
}
|
|
49
|
-
export declare function Form({ action, children, input, params, }: FormProps): import("react").JSX.Element;
|
|
50
|
-
export declare function useSubmit(): (input?: unknown) => Promise<DataResult<unknown>>;
|
|
51
|
-
export declare function useFetcher<Data = unknown>(options?: FetcherOptions): readonly [
|
|
52
|
-
{
|
|
53
|
-
data: Data | null;
|
|
54
|
-
error: string;
|
|
55
|
-
state: NavigationState;
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
Form: ({ children, input, }: Pick<FormProps, "children" | "input">) => import("react").JSX.Element;
|
|
59
|
-
load: (target?: FetcherTarget) => Promise<DataResult<Data>>;
|
|
60
|
-
submit: (input: unknown, target?: FetcherTarget) => Promise<DataResult<Data>>;
|
|
61
|
-
}
|
|
62
|
-
];
|
|
63
|
-
export declare function useRouter(): ResourceRouter;
|
|
64
|
-
export type { NavigationState, RouteState };
|
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
import { Component, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
//#region .generated/react/resources/components.tsx
|
|
4
|
-
var RouterContext = createContext(null);
|
|
5
|
-
var RouteContext = createContext(null);
|
|
6
|
-
var FormContext = createContext(null);
|
|
7
|
-
function RouterProvider({ children, initialMatches = EMPTY_MATCHES, router }) {
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
for (const match of initialMatches) router.load(match.routeId, match.params ?? {});
|
|
10
|
-
return () => router.dispose();
|
|
11
|
-
}, [initialMatches, router]);
|
|
12
|
-
return /* @__PURE__ */ jsx(RouterContext.Provider, {
|
|
13
|
-
value: router,
|
|
14
|
-
children
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
function Route({ children, params = {}, persistent = false, routeId }) {
|
|
18
|
-
const router = useRouter();
|
|
19
|
-
const stableParams = useStableParams(params);
|
|
20
|
-
const state = useRouteState(routeId, stableParams, true);
|
|
21
|
-
const route = router.getRoute(routeId);
|
|
22
|
-
const retry = useCallback(() => void router.retry(routeId, stableParams), [
|
|
23
|
-
routeId,
|
|
24
|
-
router,
|
|
25
|
-
stableParams
|
|
26
|
-
]);
|
|
27
|
-
const contextValue = useMemo(() => ({
|
|
28
|
-
params: stableParams,
|
|
29
|
-
routeId
|
|
30
|
-
}), [routeId, stableParams]);
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if (persistent) router.persist(routeId, stableParams);
|
|
33
|
-
}, [
|
|
34
|
-
persistent,
|
|
35
|
-
routeId,
|
|
36
|
-
router,
|
|
37
|
-
stableParams
|
|
38
|
-
]);
|
|
39
|
-
let content = children;
|
|
40
|
-
if (children === void 0 && route?.default) {
|
|
41
|
-
const RouteComponent = route.default;
|
|
42
|
-
content = /* @__PURE__ */ jsx(RouteComponent, {});
|
|
43
|
-
}
|
|
44
|
-
if (state.unexpectedError && route?.ErrorBoundary) {
|
|
45
|
-
const ErrorBoundary = route.ErrorBoundary;
|
|
46
|
-
content = /* @__PURE__ */ jsx(ErrorBoundary, { retry });
|
|
47
|
-
}
|
|
48
|
-
if (!state.unexpectedError && !state.loaderInitialized && route?.HydrateFallback) {
|
|
49
|
-
const HydrateFallback = route.HydrateFallback;
|
|
50
|
-
content = /* @__PURE__ */ jsx(HydrateFallback, {});
|
|
51
|
-
}
|
|
52
|
-
return /* @__PURE__ */ jsx(RouteContext.Provider, {
|
|
53
|
-
value: contextValue,
|
|
54
|
-
children: /* @__PURE__ */ jsx(RenderErrorBoundary, {
|
|
55
|
-
onRetry: retry,
|
|
56
|
-
resetKey: `${routeId}:${JSON.stringify(stableParams)}`,
|
|
57
|
-
...route?.ErrorBoundary ? { fallback: route.ErrorBoundary } : {},
|
|
58
|
-
children: content
|
|
59
|
-
})
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
function useLoaderData() {
|
|
63
|
-
const route = useCurrentRoute();
|
|
64
|
-
return useRouteLoaderData(route.routeId, route.params);
|
|
65
|
-
}
|
|
66
|
-
function useRouteLoaderData(routeId, params = {}) {
|
|
67
|
-
return useRouteState(routeId, useStableParams(params), true).loaderData;
|
|
68
|
-
}
|
|
69
|
-
function useActionData() {
|
|
70
|
-
const route = useCurrentRoute();
|
|
71
|
-
return useRouteState(route.routeId, route.params, false).actionData;
|
|
72
|
-
}
|
|
73
|
-
function useNavigation() {
|
|
74
|
-
const route = useCurrentRoute();
|
|
75
|
-
return { state: useRouteState(route.routeId, route.params, false).navigationState };
|
|
76
|
-
}
|
|
77
|
-
function useRevalidator() {
|
|
78
|
-
const route = useCurrentRoute();
|
|
79
|
-
const router = useRouter();
|
|
80
|
-
const state = useRouteState(route.routeId, route.params, false);
|
|
81
|
-
return useMemo(() => ({
|
|
82
|
-
revalidate: () => router.load(route.routeId, route.params, true),
|
|
83
|
-
state: state.navigationState === "loading" ? "loading" : "idle"
|
|
84
|
-
}), [
|
|
85
|
-
route,
|
|
86
|
-
router,
|
|
87
|
-
state.navigationState
|
|
88
|
-
]);
|
|
89
|
-
}
|
|
90
|
-
function Form({ action, children, input, params }) {
|
|
91
|
-
const currentRoute = useContext(RouteContext);
|
|
92
|
-
const router = useRouter();
|
|
93
|
-
const routeId = action ?? currentRoute?.routeId ?? "";
|
|
94
|
-
const routeParams = useStableParams(params ?? currentRoute?.params ?? {});
|
|
95
|
-
const submit = useCallback((override) => router.submit(routeId, override === void 0 ? input : override, routeParams), [
|
|
96
|
-
input,
|
|
97
|
-
routeId,
|
|
98
|
-
routeParams,
|
|
99
|
-
router
|
|
100
|
-
]);
|
|
101
|
-
if (!routeId) throw new Error("Form requires an action or a parent Route.");
|
|
102
|
-
return /* @__PURE__ */ jsx(FormContext.Provider, {
|
|
103
|
-
value: submit,
|
|
104
|
-
children
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
function useSubmit() {
|
|
108
|
-
const submit = useContext(FormContext);
|
|
109
|
-
if (!submit) throw new Error("useSubmit must be used inside Form.");
|
|
110
|
-
return submit;
|
|
111
|
-
}
|
|
112
|
-
function useFetcher(options = {}) {
|
|
113
|
-
const currentRoute = useContext(RouteContext);
|
|
114
|
-
const router = useRouter();
|
|
115
|
-
const routeId = options.routeId ?? currentRoute?.routeId ?? "";
|
|
116
|
-
const params = useStableParams(options.params ?? currentRoute?.params ?? {});
|
|
117
|
-
const [data, setData] = useState(null);
|
|
118
|
-
const [error, setError] = useState("");
|
|
119
|
-
const [state, setState] = useState("idle");
|
|
120
|
-
const controller = useRef(null);
|
|
121
|
-
useEffect(() => () => {
|
|
122
|
-
controller.current?.abort();
|
|
123
|
-
}, []);
|
|
124
|
-
const run = useCallback(async (mutating, input, target) => {
|
|
125
|
-
controller.current?.abort();
|
|
126
|
-
const nextController = new AbortController();
|
|
127
|
-
const { signal } = nextController;
|
|
128
|
-
const targetId = target.routeId ?? routeId;
|
|
129
|
-
const targetParams = target.params ?? params;
|
|
130
|
-
controller.current = nextController;
|
|
131
|
-
setError("");
|
|
132
|
-
setState(mutating ? "submitting" : "loading");
|
|
133
|
-
const result = await (mutating ? router.fetchAction(targetId, input, targetParams, signal) : router.fetchLoader(targetId, targetParams, signal));
|
|
134
|
-
if (signal.aborted) return result;
|
|
135
|
-
controller.current = null;
|
|
136
|
-
setData(result.data);
|
|
137
|
-
setError(result.error);
|
|
138
|
-
setState("idle");
|
|
139
|
-
if (result.unexpected && currentRoute) router.reportUnexpected(currentRoute.routeId, currentRoute.params);
|
|
140
|
-
return result;
|
|
141
|
-
}, [
|
|
142
|
-
currentRoute,
|
|
143
|
-
params,
|
|
144
|
-
routeId,
|
|
145
|
-
router
|
|
146
|
-
]);
|
|
147
|
-
const submit = useCallback((input, target = {}) => run(true, input, target), [run]);
|
|
148
|
-
const load = useCallback((target = {}) => run(false, void 0, target), [run]);
|
|
149
|
-
const BoundForm = useCallback(({ children, input }) => /* @__PURE__ */ jsx(FormContext.Provider, {
|
|
150
|
-
value: (override) => submit(override === void 0 ? input : override),
|
|
151
|
-
children
|
|
152
|
-
}), [submit]);
|
|
153
|
-
if (!routeId) throw new Error("useFetcher requires a routeId or a parent Route.");
|
|
154
|
-
return [useMemo(() => ({
|
|
155
|
-
data,
|
|
156
|
-
error,
|
|
157
|
-
state
|
|
158
|
-
}), [
|
|
159
|
-
data,
|
|
160
|
-
error,
|
|
161
|
-
state
|
|
162
|
-
]), useMemo(() => ({
|
|
163
|
-
Form: BoundForm,
|
|
164
|
-
load,
|
|
165
|
-
submit
|
|
166
|
-
}), [
|
|
167
|
-
BoundForm,
|
|
168
|
-
load,
|
|
169
|
-
submit
|
|
170
|
-
])];
|
|
171
|
-
}
|
|
172
|
-
function useRouter() {
|
|
173
|
-
const router = useContext(RouterContext);
|
|
174
|
-
if (!router) throw new Error("RouterProvider is missing.");
|
|
175
|
-
return router;
|
|
176
|
-
}
|
|
177
|
-
function useCurrentRoute() {
|
|
178
|
-
const route = useContext(RouteContext);
|
|
179
|
-
if (!route) throw new Error("This hook requires a parent Route.");
|
|
180
|
-
return route;
|
|
181
|
-
}
|
|
182
|
-
function useRouteState(routeId, params, loadOnMount) {
|
|
183
|
-
const router = useRouter();
|
|
184
|
-
const subscribe = useCallback((listener) => router.subscribe(routeId, params, listener), [
|
|
185
|
-
params,
|
|
186
|
-
routeId,
|
|
187
|
-
router
|
|
188
|
-
]);
|
|
189
|
-
const getSnapshot = useCallback(() => router.getSnapshot(routeId, params), [
|
|
190
|
-
params,
|
|
191
|
-
routeId,
|
|
192
|
-
router
|
|
193
|
-
]);
|
|
194
|
-
const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
195
|
-
useEffect(() => {
|
|
196
|
-
if (loadOnMount) router.load(routeId, params);
|
|
197
|
-
}, [
|
|
198
|
-
loadOnMount,
|
|
199
|
-
params,
|
|
200
|
-
routeId,
|
|
201
|
-
router
|
|
202
|
-
]);
|
|
203
|
-
return state;
|
|
204
|
-
}
|
|
205
|
-
function useStableParams(params) {
|
|
206
|
-
const key = JSON.stringify(Object.entries(params).sort(([left], [right]) => left.localeCompare(right)));
|
|
207
|
-
const ref = useRef({
|
|
208
|
-
key,
|
|
209
|
-
value: params
|
|
210
|
-
});
|
|
211
|
-
if (ref.current.key !== key) ref.current = {
|
|
212
|
-
key,
|
|
213
|
-
value: params
|
|
214
|
-
};
|
|
215
|
-
return ref.current.value;
|
|
216
|
-
}
|
|
217
|
-
var RenderErrorBoundary = class extends Component {
|
|
218
|
-
state = { error: null };
|
|
219
|
-
static getDerivedStateFromError(error) {
|
|
220
|
-
return { error };
|
|
221
|
-
}
|
|
222
|
-
componentDidUpdate(previousProps) {
|
|
223
|
-
if (this.state.error && previousProps.resetKey !== this.props.resetKey) this.setState({ error: null });
|
|
224
|
-
}
|
|
225
|
-
render() {
|
|
226
|
-
if (this.state.error && this.props.fallback) {
|
|
227
|
-
const ErrorBoundary = this.props.fallback;
|
|
228
|
-
return /* @__PURE__ */ jsx(ErrorBoundary, { retry: () => {
|
|
229
|
-
this.setState({ error: null });
|
|
230
|
-
this.props.onRetry();
|
|
231
|
-
} });
|
|
232
|
-
}
|
|
233
|
-
if (this.state.error) throw this.state.error;
|
|
234
|
-
return this.props.children;
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
var EMPTY_MATCHES = [];
|
|
238
|
-
//#endregion
|
|
239
|
-
export { Form, Route, RouterProvider, useActionData, useFetcher, useLoaderData, useNavigation, useRevalidator, useRouteLoaderData, useRouter, useSubmit };
|