@octanejs/app-core 0.0.43 → 0.0.45
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 +3 -3
- package/src/resolve-config.js +4 -0
- package/src/server/router.js +20 -12
- package/types/index.d.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octanejs/app-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.45",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -79,10 +79,10 @@
|
|
|
79
79
|
"esbuild": "^0.28.1"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
|
-
"octane": "0.1.
|
|
82
|
+
"octane": "0.1.49"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@types/node": "^24.13.3",
|
|
86
|
-
"octane": "0.1.
|
|
86
|
+
"octane": "0.1.49"
|
|
87
87
|
}
|
|
88
88
|
}
|
package/src/resolve-config.js
CHANGED
|
@@ -177,6 +177,9 @@ export function resolveOctaneConfig(raw, options = {}) {
|
|
|
177
177
|
if (raw.compiler?.strong !== undefined && typeof raw.compiler.strong !== 'boolean') {
|
|
178
178
|
throw new Error('[octane] compiler.strong must be a boolean when provided.');
|
|
179
179
|
}
|
|
180
|
+
if (raw.compiler?.nativeReads !== undefined && typeof raw.compiler.nativeReads !== 'boolean') {
|
|
181
|
+
throw new Error('[octane] compiler.nativeReads must be a boolean when provided.');
|
|
182
|
+
}
|
|
180
183
|
|
|
181
184
|
if (raw.router?.routes !== undefined && !Array.isArray(raw.router.routes)) {
|
|
182
185
|
throw new Error('[octane] router.routes must be an array.');
|
|
@@ -236,6 +239,7 @@ export function resolveOctaneConfig(raw, options = {}) {
|
|
|
236
239
|
adapter: raw.adapter,
|
|
237
240
|
compiler: {
|
|
238
241
|
strong: raw.compiler?.strong ?? false,
|
|
242
|
+
nativeReads: raw.compiler?.nativeReads ?? false,
|
|
239
243
|
renderers: normalizeRendererConfig(raw.compiler?.renderers),
|
|
240
244
|
},
|
|
241
245
|
router: {
|
package/src/server/router.js
CHANGED
|
@@ -14,20 +14,20 @@
|
|
|
14
14
|
/**
|
|
15
15
|
* @typedef {Object} CompiledRoute
|
|
16
16
|
* @property {Route} route
|
|
17
|
-
* @property {RegExp} pattern
|
|
17
|
+
* @property {string | RegExp} pattern
|
|
18
18
|
* @property {string[]} paramNames
|
|
19
19
|
* @property {number} specificity - Higher = more specific (static > param > catch-all)
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Compile a route path into an exact string or capturing RegExp
|
|
24
24
|
* Supports:
|
|
25
25
|
* - Static segments: /about, /api/hello
|
|
26
26
|
* - Named params: /posts/:id, /users/:userId/posts/:postId
|
|
27
27
|
* - Catch-all: /docs/*slug
|
|
28
28
|
*
|
|
29
29
|
* @param {string} path
|
|
30
|
-
* @returns {{ pattern: RegExp, paramNames: string[], specificity: number }}
|
|
30
|
+
* @returns {{ pattern: string | RegExp, paramNames: string[], specificity: number }}
|
|
31
31
|
*/
|
|
32
32
|
function compilePath(path) {
|
|
33
33
|
/** @type {string[]} */
|
|
@@ -62,7 +62,9 @@ function compilePath(path) {
|
|
|
62
62
|
})
|
|
63
63
|
.join('/');
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
// Static paths are already exact matchers. Keep RegExp capture work for the
|
|
66
|
+
// parameter and catch-all routes that need it.
|
|
67
|
+
const pattern = paramNames.length === 0 ? path || '/' : new RegExp(`^${regexString || '/'}$`);
|
|
66
68
|
return { pattern, paramNames, specificity };
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -98,24 +100,30 @@ export function createRouter(routes) {
|
|
|
98
100
|
* @returns {RouteMatch | null}
|
|
99
101
|
*/
|
|
100
102
|
match(method, pathname) {
|
|
103
|
+
let normalizedMethod;
|
|
101
104
|
for (const { route, pattern, paramNames } of compiledRoutes) {
|
|
102
105
|
// Check method for ServerRoute
|
|
103
106
|
if (route.type === 'server') {
|
|
104
107
|
const methods = /** @type {ServerRoute} */ (route).methods;
|
|
105
|
-
|
|
108
|
+
normalizedMethod ??= method.toUpperCase();
|
|
109
|
+
if (!methods.includes(normalizedMethod)) {
|
|
106
110
|
continue;
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
|
|
114
|
+
if (typeof pattern === 'string') {
|
|
115
|
+
if (pathname === pattern) return { route, params: {} };
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
110
119
|
const match = pathname.match(pattern);
|
|
111
|
-
if (match)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
return { route, params };
|
|
120
|
+
if (!match) continue;
|
|
121
|
+
/** @type {Record<string, string>} */
|
|
122
|
+
const params = {};
|
|
123
|
+
for (let i = 0; i < paramNames.length; i++) {
|
|
124
|
+
params[paramNames[i]] = decodeURIComponent(match[i + 1]);
|
|
118
125
|
}
|
|
126
|
+
return { route, params };
|
|
119
127
|
}
|
|
120
128
|
return null;
|
|
121
129
|
},
|
package/types/index.d.ts
CHANGED
|
@@ -393,8 +393,10 @@ export interface OctaneConfigOptions {
|
|
|
393
393
|
adapter?: OctaneAdapter;
|
|
394
394
|
/** @experimental Compiler-owned configuration shared by all bundler integrations. */
|
|
395
395
|
compiler?: {
|
|
396
|
-
/**
|
|
396
|
+
/** Assert pure immutable-snapshot renders and reject detectable violations. @default false */
|
|
397
397
|
strong?: boolean;
|
|
398
|
+
/** Experimental native signal reads in DOM client/server render scopes. */
|
|
399
|
+
nativeReads?: boolean;
|
|
398
400
|
renderers?: ExperimentalRendererConfigOptions;
|
|
399
401
|
};
|
|
400
402
|
router?: {
|
|
@@ -456,6 +458,7 @@ export interface ResolvedOctaneConfig {
|
|
|
456
458
|
compiler: {
|
|
457
459
|
/** @default false */
|
|
458
460
|
strong: boolean;
|
|
461
|
+
nativeReads: boolean;
|
|
459
462
|
renderers: ExperimentalResolvedRendererConfig;
|
|
460
463
|
};
|
|
461
464
|
router: {
|