@timber-js/app 0.1.26 → 0.1.28

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.
@@ -1 +1 @@
1
- {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/plugins/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqGhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA2FxD"}
1
+ {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/plugins/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqGhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA+DxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"server-bundle.d.ts","sourceRoot":"","sources":["../../src/plugins/server-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CA0G7C"}
1
+ {"version":3,"file":"server-bundle.d.ts","sourceRoot":"","sources":["../../src/plugins/server-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAyH7C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timber-js/app",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "Vite-native React framework for Cloudflare Workers — correct HTTP semantics, real status codes, pages that work without JavaScript",
5
5
  "keywords": [
6
6
  "cloudflare-workers",
@@ -177,39 +177,11 @@ export function timberEntries(ctx: PluginContext): Plugin {
177
177
  * in the client output. This is confusing since those chunks contain client
178
178
  * components, not server code. Renaming clarifies their purpose.
179
179
  */
180
- generateBundle(_options, bundle) {
181
- if ((this as any).environment?.name !== 'client') return;
182
-
183
- for (const [fileName, chunk] of Object.entries(bundle)) {
184
- if (chunk.type !== 'chunk') continue;
185
- if (!chunk.name?.startsWith('rsc-entry')) continue;
186
-
187
- const newFileName = fileName.replace('rsc-entry', 'rsc-client-entry');
188
- // Extract just the basename for matching code references like "./rsc-entry-XYZ.js"
189
- const oldBase = fileName.split('/').pop()!;
190
- const newBase = newFileName.split('/').pop()!;
191
-
192
- chunk.fileName = newFileName;
193
- chunk.name = chunk.name.replace('rsc-entry', 'rsc-client-entry');
194
- bundle[newFileName] = chunk;
195
- delete bundle[fileName];
196
-
197
- // Update import references in other chunks
198
- for (const other of Object.values(bundle)) {
199
- if (other.type !== 'chunk') continue;
200
- if (other.code.includes(oldBase)) {
201
- other.code = other.code.replaceAll(oldBase, newBase);
202
- }
203
- if (other.imports) {
204
- other.imports = other.imports.map((i) => (i === fileName ? newFileName : i));
205
- }
206
- if (other.dynamicImports) {
207
- other.dynamicImports = other.dynamicImports.map((i) =>
208
- i === fileName ? newFileName : i
209
- );
210
- }
211
- }
212
- }
213
- },
180
+ // Note: chunk renaming (rsc-entry → rsc-client-entry) was previously done
181
+ // in generateBundle by mutating the bundle object. Rolldown does not support
182
+ // bundle mutation in generateBundle — assignments are silently ignored, which
183
+ // causes the renamed file to never be emitted while code references are
184
+ // updated, breaking client hydration. The rename is purely cosmetic and has
185
+ // been removed. The chunks keep their original "rsc-entry" names.
214
186
  };
215
187
  }
@@ -95,10 +95,20 @@ export function timberServerBundle(): Plugin[] {
95
95
  // the variable assignment of the init function — so the module's React
96
96
  // imports, context creation, etc. never execute.
97
97
  //
98
- // The fix: patch the `__esmMin` runtime definition to eagerly execute
99
- // the init callback while still returning the lazy wrapper. This makes
100
- // all ESM module inits run at load time (standard ESM behavior) instead
101
- // of lazily, which is functionally correct and avoids the dropped-init bug.
98
+ // The fix: patch `__esmMin` to eagerly *attempt* each init, but fall
99
+ // back to lazy retry on failure. This handles two failure modes:
100
+ //
101
+ // 1. Forward references (e.g. Zod v4): `init_iso` calls `init_schemas`
102
+ // which hasn't been defined yet. Eager execution fails, but when the
103
+ // function is called lazily later, all dependencies are available.
104
+ //
105
+ // 2. Optional peer dep shims (e.g. @emotion/is-prop-valid for
106
+ // framer-motion): Vite generates shims that throw for missing
107
+ // optional deps. The throw is deferred to lazy execution where
108
+ // the consuming package's try/catch handles it.
109
+ //
110
+ // The key: on failure, `fn` is NOT cleared, so the next call retries.
111
+ // On success, `fn` is set to 0 so subsequent calls are no-ops.
102
112
  const esmInitFixPlugin: Plugin = {
103
113
  name: 'timber-esm-init-fix',
104
114
  applyToEnvironment(environment) {
@@ -108,11 +118,16 @@ export function timberServerBundle(): Plugin[] {
108
118
  const lazy = 'var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);';
109
119
  if (!code.includes(lazy)) return null;
110
120
 
111
- // Replace with eager-then-lazy: execute init immediately, then
112
- // return the lazy wrapper for any subsequent calls (which are
113
- // idempotent since fn is set to 0 after first execution).
114
- const eager =
115
- 'var __esmMin = (fn, res) => { var l = () => (fn && (res = fn(fn = 0)), res); l(); return l; };';
121
+ // Eager-with-retry: attempt init immediately. On success, mark done
122
+ // (fn = 0). On failure, leave fn intact so the lazy wrapper retries
123
+ // on next call by then forward dependencies are initialized.
124
+ const eager = [
125
+ 'var __esmMin = (fn, res) => {',
126
+ ' var l = () => { if (fn) { var f = fn; try { res = f(); fn = 0; } catch(e) {} } return res; };',
127
+ ' l();',
128
+ ' return l;',
129
+ '};',
130
+ ].join(' ');
116
131
 
117
132
  return { code: code.replace(lazy, eager), map: null };
118
133
  },