what-router 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/index.js +26 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "what-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "What Framework - File-based & programmatic router with View Transitions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"author": "",
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"what-core": "^0.
|
|
29
|
+
"what-core": "^0.3.0"
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
package/src/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Production-grade file-based routing with nested layouts, loading states,
|
|
3
3
|
// route groups, view transitions, and middleware.
|
|
4
4
|
|
|
5
|
-
import { signal, effect, computed, batch, h } from 'what-core';
|
|
5
|
+
import { signal, effect, computed, batch, h, ErrorBoundary } from 'what-core';
|
|
6
6
|
|
|
7
7
|
// --- Route State (global singleton) ---
|
|
8
8
|
|
|
@@ -187,6 +187,24 @@ export function Router({ routes, fallback, globalLayout }) {
|
|
|
187
187
|
});
|
|
188
188
|
|
|
189
189
|
const { route: r, params } = matched;
|
|
190
|
+
const queryObj = parseQuery(search);
|
|
191
|
+
|
|
192
|
+
// Run middleware (sync only — async middleware should use asyncGuard)
|
|
193
|
+
if (r.middleware && r.middleware.length > 0) {
|
|
194
|
+
for (const mw of r.middleware) {
|
|
195
|
+
const result = mw({ path, params, query: queryObj, route: r });
|
|
196
|
+
if (result === false) {
|
|
197
|
+
// Middleware rejected — show fallback
|
|
198
|
+
if (fallback) return h(fallback, {});
|
|
199
|
+
return h('div', { class: 'what-403' }, h('h1', null, '403'), h('p', null, 'Access denied'));
|
|
200
|
+
}
|
|
201
|
+
if (typeof result === 'string') {
|
|
202
|
+
// Middleware returned a redirect path
|
|
203
|
+
navigate(result, { replace: true });
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
190
208
|
|
|
191
209
|
// Build element with loading state support
|
|
192
210
|
let element;
|
|
@@ -196,15 +214,20 @@ export function Router({ routes, fallback, globalLayout }) {
|
|
|
196
214
|
} else {
|
|
197
215
|
element = h(r.component, {
|
|
198
216
|
params,
|
|
199
|
-
query:
|
|
217
|
+
query: queryObj,
|
|
200
218
|
route: r,
|
|
201
219
|
});
|
|
202
220
|
}
|
|
203
221
|
|
|
222
|
+
// Wrap with per-route error boundary if specified
|
|
223
|
+
if (r.error) {
|
|
224
|
+
element = h(ErrorBoundary, { fallback: r.error }, element);
|
|
225
|
+
}
|
|
226
|
+
|
|
204
227
|
// Wrap with nested layouts (innermost to outermost)
|
|
205
228
|
const layouts = buildLayoutChain(r, routes);
|
|
206
229
|
for (const Layout of layouts.reverse()) {
|
|
207
|
-
element = h(Layout, { params, query:
|
|
230
|
+
element = h(Layout, { params, query: queryObj }, element);
|
|
208
231
|
}
|
|
209
232
|
|
|
210
233
|
// Global layout wrapper
|