@octanejs/vite-plugin 0.1.47 → 0.1.49
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 +4 -4
- package/src/client-assets.js +28 -2
- package/src/index.js +13 -2
- package/types/index.d.ts +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octanejs/vite-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.49",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -47,17 +47,17 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@ripple-ts/adapter": "^0.3.125",
|
|
50
|
-
"@octanejs/app-core": "0.0.
|
|
50
|
+
"@octanejs/app-core": "0.0.45"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"vite": "^8.0.16",
|
|
54
|
-
"octane": "0.1.
|
|
54
|
+
"octane": "0.1.49"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/node": "^24.13.3",
|
|
58
58
|
"playwright": "^1.61.1",
|
|
59
59
|
"type-fest": "^5.8.0",
|
|
60
60
|
"vite": "^8.1.5",
|
|
61
|
-
"octane": "0.1.
|
|
61
|
+
"octane": "0.1.49"
|
|
62
62
|
}
|
|
63
63
|
}
|
package/src/client-assets.js
CHANGED
|
@@ -39,6 +39,14 @@ export function createClientAssetMap(manifest, moduleIds, entryFiles = {}) {
|
|
|
39
39
|
const manifestKeysByFile = new Map(
|
|
40
40
|
Object.entries(manifest).map(([key, entry]) => [entry.file, key]),
|
|
41
41
|
);
|
|
42
|
+
// Route entries usually converge on the same shared chunks. Cache only small,
|
|
43
|
+
// complete transitive CSS results for this immutable manifest build so a large
|
|
44
|
+
// shared JavaScript graph is walked once without retaining quadratic CSS lists.
|
|
45
|
+
const MAX_CACHED_CSS_FILES = 64;
|
|
46
|
+
/** @type {Map<string, string[]>} */
|
|
47
|
+
const cssCache = new Map();
|
|
48
|
+
let traversalVersion = 0;
|
|
49
|
+
let traversalDepth = 0;
|
|
42
50
|
|
|
43
51
|
/**
|
|
44
52
|
* @param {string} key
|
|
@@ -48,11 +56,22 @@ export function createClientAssetMap(manifest, moduleIds, entryFiles = {}) {
|
|
|
48
56
|
*/
|
|
49
57
|
function collectCss(key, deferredHydrationBranch, visited) {
|
|
50
58
|
const visitKey = `${deferredHydrationBranch ? 'deferred' : 'eager'}:${key}`;
|
|
51
|
-
if (visited.has(visitKey))
|
|
59
|
+
if (visited.has(visitKey)) {
|
|
60
|
+
// This result is complete for the current route because the earlier path
|
|
61
|
+
// already supplied the subtree. It is not safe to reuse as a standalone
|
|
62
|
+
// result for another route; the version change prevents its active callers
|
|
63
|
+
// from caching their now-context-dependent results.
|
|
64
|
+
traversalVersion++;
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
52
67
|
visited.add(visitKey);
|
|
68
|
+
const cached = cssCache.get(visitKey);
|
|
69
|
+
if (cached !== undefined) return cached;
|
|
53
70
|
const entry = manifest[key];
|
|
54
71
|
if (!entry) return [];
|
|
55
72
|
|
|
73
|
+
const version = traversalVersion;
|
|
74
|
+
traversalDepth++;
|
|
56
75
|
const css = [...(entry.css || [])];
|
|
57
76
|
for (const imported of entry.imports || []) {
|
|
58
77
|
css.push(...collectCss(imported, deferredHydrationBranch, visited));
|
|
@@ -67,6 +86,11 @@ export function createClientAssetMap(manifest, moduleIds, entryFiles = {}) {
|
|
|
67
86
|
css.push(...collectCss(imported, true, visited));
|
|
68
87
|
}
|
|
69
88
|
}
|
|
89
|
+
traversalDepth--;
|
|
90
|
+
// Top-level route entries are consumed once; caching them only grows the map.
|
|
91
|
+
if (traversalDepth > 0 && traversalVersion === version && css.length <= MAX_CACHED_CSS_FILES) {
|
|
92
|
+
cssCache.set(visitKey, css);
|
|
93
|
+
}
|
|
70
94
|
return css;
|
|
71
95
|
}
|
|
72
96
|
|
|
@@ -83,9 +107,11 @@ export function createClientAssetMap(manifest, moduleIds, entryFiles = {}) {
|
|
|
83
107
|
: manifestKeysByFile.get(entryFiles[moduleId]);
|
|
84
108
|
if (!manifestKey) continue;
|
|
85
109
|
const entry = manifest[manifestKey];
|
|
110
|
+
const visited = new Set();
|
|
111
|
+
traversalVersion = 0;
|
|
86
112
|
assets[moduleId] = {
|
|
87
113
|
js: entry.file,
|
|
88
|
-
css: [...new Set(collectCss(manifestKey, false,
|
|
114
|
+
css: [...new Set(collectCss(manifestKey, false, visited))],
|
|
89
115
|
};
|
|
90
116
|
}
|
|
91
117
|
return assets;
|
package/src/index.js
CHANGED
|
@@ -221,7 +221,7 @@ function collect_hydrate_module_paths(config) {
|
|
|
221
221
|
* it). An explicit `profile` (true or false) always takes precedence over
|
|
222
222
|
* `devtools`.
|
|
223
223
|
*
|
|
224
|
-
* @param {{ hmr?: boolean, profile?: boolean, devtools?: boolean, strong?: boolean, exclude?: string[], requireDirective?: boolean, renderers?: import('@octanejs/app-core').ExperimentalRendererConfigOptions, cssModuleConstants?: import('octane/compiler/vite').OctaneVitePluginOptions['cssModuleConstants'] }} [inlineOptions]
|
|
224
|
+
* @param {{ hmr?: boolean, profile?: boolean, devtools?: boolean, strong?: boolean, nativeReads?: boolean, exclude?: string[], requireDirective?: boolean, renderers?: import('@octanejs/app-core').ExperimentalRendererConfigOptions, cssModuleConstants?: import('octane/compiler/vite').OctaneVitePluginOptions['cssModuleConstants'] }} [inlineOptions]
|
|
225
225
|
* @returns {Plugin[]}
|
|
226
226
|
*/
|
|
227
227
|
export function octane(inlineOptions = {}) {
|
|
@@ -881,6 +881,7 @@ export function octane(inlineOptions = {}) {
|
|
|
881
881
|
* hmr?: boolean,
|
|
882
882
|
* profile?: boolean | 'auto',
|
|
883
883
|
* strong?: boolean,
|
|
884
|
+
* nativeReads?: boolean,
|
|
884
885
|
* exclude?: string[],
|
|
885
886
|
* requireDirective?: boolean,
|
|
886
887
|
* renderers?: import('@octanejs/app-core').ExperimentalRendererConfigOptions,
|
|
@@ -894,6 +895,8 @@ export function octane(inlineOptions = {}) {
|
|
|
894
895
|
if (inlineOptions.profile !== undefined) compilerOptions.profile = inlineOptions.profile;
|
|
895
896
|
else if (inlineOptions.devtools === true) compilerOptions.profile = 'auto';
|
|
896
897
|
if (inlineOptions.strong !== undefined) compilerOptions.strong = inlineOptions.strong;
|
|
898
|
+
if (inlineOptions.nativeReads !== undefined)
|
|
899
|
+
compilerOptions.nativeReads = inlineOptions.nativeReads;
|
|
897
900
|
if (inlineOptions.exclude !== undefined) compilerOptions.exclude = inlineOptions.exclude;
|
|
898
901
|
if (inlineOptions.requireDirective !== undefined) {
|
|
899
902
|
compilerOptions.requireDirective = inlineOptions.requireDirective;
|
|
@@ -909,7 +912,11 @@ export function octane(inlineOptions = {}) {
|
|
|
909
912
|
const projectRoot = userConfig.root ? path.resolve(userConfig.root) : process.cwd();
|
|
910
913
|
// Both inline compiler options override app config independently. Preserve
|
|
911
914
|
// the synchronous path when neither needs to read octane.config.ts.
|
|
912
|
-
if (
|
|
915
|
+
if (
|
|
916
|
+
inlineOptions.renderers !== undefined &&
|
|
917
|
+
inlineOptions.strong !== undefined &&
|
|
918
|
+
inlineOptions.nativeReads !== undefined
|
|
919
|
+
) {
|
|
913
920
|
compilerConfigWatchFiles.clear();
|
|
914
921
|
return compilerConfigHook.call(this, userConfig, env);
|
|
915
922
|
}
|
|
@@ -918,6 +925,7 @@ export function octane(inlineOptions = {}) {
|
|
|
918
925
|
if (!octaneConfigExists(projectRoot)) {
|
|
919
926
|
if (inlineOptions.renderers === undefined) delete compilerOptions.renderers;
|
|
920
927
|
if (inlineOptions.strong === undefined) delete compilerOptions.strong;
|
|
928
|
+
if (inlineOptions.nativeReads === undefined) delete compilerOptions.nativeReads;
|
|
921
929
|
compilerConfigWatchFiles.clear();
|
|
922
930
|
// A new app config can introduce Strong mode or renderer rules.
|
|
923
931
|
compilerConfigWatchFiles.add(path.resolve(configPath));
|
|
@@ -932,6 +940,9 @@ export function octane(inlineOptions = {}) {
|
|
|
932
940
|
if (inlineOptions.strong === undefined) {
|
|
933
941
|
compilerOptions.strong = config.config.compiler.strong;
|
|
934
942
|
}
|
|
943
|
+
if (inlineOptions.nativeReads === undefined) {
|
|
944
|
+
compilerOptions.nativeReads = config.config.compiler.nativeReads;
|
|
945
|
+
}
|
|
935
946
|
compilerConfigWatchFiles.clear();
|
|
936
947
|
for (const file of [...config.dependencies, ...config.missingDependencies]) {
|
|
937
948
|
compilerConfigWatchFiles.add(path.resolve(file));
|
package/types/index.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export interface OctanePluginOptions {
|
|
|
15
15
|
hmr?: boolean;
|
|
16
16
|
/** Enable component profiling in client transforms. */
|
|
17
17
|
profile?: boolean;
|
|
18
|
-
/**
|
|
18
|
+
/** Assert Strong mode's pure immutable-snapshot render contract for app code. */
|
|
19
19
|
strong?: boolean;
|
|
20
|
+
/** Experimental native signal reads in DOM client/server render scopes. */
|
|
21
|
+
nativeReads?: boolean;
|
|
20
22
|
/**
|
|
21
23
|
* Path fragments the compiler's plain `.ts`/`.js` hook-slotting pass must
|
|
22
24
|
* skip. Prefer package manifest `octane.hookSlots.manual` declarations.
|