@octanejs/vite-plugin 0.1.46 → 0.1.48

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/vite-plugin",
3
- "version": "0.1.46",
3
+ "version": "0.1.48",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {
@@ -46,18 +46,18 @@
46
46
  }
47
47
  },
48
48
  "dependencies": {
49
- "@ripple-ts/adapter": "^0.3.118",
50
- "@octanejs/app-core": "0.0.42"
49
+ "@ripple-ts/adapter": "^0.3.125",
50
+ "@octanejs/app-core": "0.0.44"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "vite": "^8.0.16",
54
- "octane": "0.1.46"
54
+ "octane": "0.1.48"
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.46"
61
+ "octane": "0.1.48"
62
62
  }
63
63
  }
@@ -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)) return [];
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, new Set()))],
114
+ css: [...new Set(collectCss(manifestKey, false, visited))],
89
115
  };
90
116
  }
91
117
  return assets;
package/types/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export interface OctanePluginOptions {
15
15
  hmr?: boolean;
16
16
  /** Enable component profiling in client transforms. */
17
17
  profile?: boolean;
18
- /** Enable Strong mode for app code, overriding `compiler.strong` in `octane.config.ts`. */
18
+ /** Assert Strong mode's pure immutable-snapshot render contract for app code. */
19
19
  strong?: boolean;
20
20
  /**
21
21
  * Path fragments the compiler's plain `.ts`/`.js` hook-slotting pass must