@webjsdev/core 0.7.20 → 0.7.21
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/dist/webjs-core-browser.js +2 -2
- package/dist/webjs-core-browser.js.map +2 -2
- package/dist/webjs-core-testing.js +14 -14
- package/dist/webjs-core-testing.js.map +2 -2
- package/dist/webjs-core.js +2 -2
- package/dist/webjs-core.js.map +2 -2
- package/package.json +1 -1
- package/src/render-server.js +6 -2
- package/src/serialize.js +16 -2
package/package.json
CHANGED
package/src/render-server.js
CHANGED
|
@@ -361,11 +361,15 @@ const SSR_HTMLELEMENT_METHODS = new Set([
|
|
|
361
361
|
*/
|
|
362
362
|
function browserMemberHint(e) {
|
|
363
363
|
const msg = e && typeof (/** @type any */ (e).message) === 'string' ? /** @type any */ (e).message : '';
|
|
364
|
-
|
|
364
|
+
// Match on a word boundary, NOT end-of-string: V8 (Node) ends the message at
|
|
365
|
+
// "is not defined" / "is not a function", but JSC (Bun) appends a detail
|
|
366
|
+
// clause (e.g. ". (In '({}).querySelector(\"p\")', '...' is undefined)"), so an
|
|
367
|
+
// anchored `$` would miss the Bun message and drop the actionable hint.
|
|
368
|
+
let m = /^(\w+) is not defined\b/.exec(msg);
|
|
365
369
|
if (e instanceof ReferenceError && m && SSR_BROWSER_GLOBALS.has(m[1])) {
|
|
366
370
|
return `\`${m[1]}\` is a browser-only global and is undefined during SSR.`;
|
|
367
371
|
}
|
|
368
|
-
m = /\.(\w+) is not a function
|
|
372
|
+
m = /\.(\w+) is not a function\b/.exec(msg);
|
|
369
373
|
if (e instanceof TypeError && m && SSR_HTMLELEMENT_METHODS.has(m[1])) {
|
|
370
374
|
return `\`${m[1]}\` is an HTMLElement method that does not exist on the server-side component instance during SSR.`;
|
|
371
375
|
}
|
package/src/serialize.js
CHANGED
|
@@ -142,6 +142,12 @@ function newEncodeCtx() {
|
|
|
142
142
|
emitted: new Set(), // ids already emitted as the canonical encoding
|
|
143
143
|
nextId: 0,
|
|
144
144
|
blobBytes: new Map(), // Blob → Uint8Array (precomputed during countRefs)
|
|
145
|
+
// FormData → its entries captured ONCE. Bun returns a FRESH Blob/File
|
|
146
|
+
// identity on every FormData.entries()/get() call (Node returns a stable
|
|
147
|
+
// one), so countRefs and encode must iterate the SAME captured array or the
|
|
148
|
+
// identity-keyed blobBytes lookup misses on Bun (crash). Captured here so
|
|
149
|
+
// both passes see the same Blob objects on every runtime.
|
|
150
|
+
fdEntries: new Map(),
|
|
145
151
|
};
|
|
146
152
|
}
|
|
147
153
|
|
|
@@ -164,7 +170,11 @@ async function countRefs(value, ctx) {
|
|
|
164
170
|
continue;
|
|
165
171
|
}
|
|
166
172
|
if (typeof FormData !== 'undefined' && v instanceof FormData) {
|
|
167
|
-
|
|
173
|
+
// Capture entries ONCE (see fdEntries note) and traverse THOSE Blob
|
|
174
|
+
// objects, so encode reuses the exact instances whose bytes we precompute.
|
|
175
|
+
const captured = ctx.fdEntries.get(v) || [...v.entries()];
|
|
176
|
+
ctx.fdEntries.set(v, captured);
|
|
177
|
+
for (const [, val] of captured) {
|
|
168
178
|
if (typeof val !== 'string') stack.push(val);
|
|
169
179
|
}
|
|
170
180
|
continue;
|
|
@@ -233,8 +243,12 @@ function encodeOne(v, ctx) {
|
|
|
233
243
|
out = { [TAG]: 'Blob', v: bytesToB64(bytes), t: v.type || '' };
|
|
234
244
|
}
|
|
235
245
|
} else if (typeof FormData !== 'undefined' && v instanceof FormData) {
|
|
246
|
+
// Reuse the entries captured in countRefs so the Blob/File instances match
|
|
247
|
+
// the ones whose bytes were precomputed (Bun yields fresh identities per
|
|
248
|
+
// entries() call; see the fdEntries note in newEncodeCtx).
|
|
249
|
+
const captured = ctx.fdEntries.get(v) || [...v.entries()];
|
|
236
250
|
const entries = [];
|
|
237
|
-
for (const [k, val] of
|
|
251
|
+
for (const [k, val] of captured) entries.push([k, encodeOne(val, ctx)]);
|
|
238
252
|
out = { [TAG]: 'FD', v: entries };
|
|
239
253
|
} else if (ArrayBuffer.isView(v) || v instanceof ArrayBuffer) {
|
|
240
254
|
out = encodeBinary(v);
|