@solidjs/babel-plugin 2.0.0-rc.3 → 2.0.0-rc.4
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +7 -0
- package/index.js +36 -4
- package/package.json +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -7,4 +7,4 @@ src/shared/transform.ts -> src/ssr/element.ts -> src/shared/transform.ts
|
|
|
7
7
|
src/shared/transform.ts -> src/universal/element.ts -> src/shared/transform.ts
|
|
8
8
|
src/shared/transform.ts -> src/shared/component.ts -> src/shared/transform.ts
|
|
9
9
|
src/shared/transform.ts -> src/shared/fragment.ts -> src/shared/transform.ts
|
|
10
|
-
[32mcreated [1mindex.js[22m in [1m2.
|
|
10
|
+
[32mcreated [1mindex.js[22m in [1m2.9s[22m[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @solidjs/babel-plugin
|
|
2
2
|
|
|
3
|
+
## 2.0.0-rc.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8d249c7: Patch-channel contract hardening from the stage-2 re-audit: ordinary `patchDriver` registrations unbind with their owner (entries no longer leak past unmount); merged transitions move their held-patch stash so no patch strands; the optimistic drain shares the normal drain's per-entry error isolation and boundary routing; accessor-bearing records are excluded at admission (scan-before-trust) and records that acquire accessors demote their patches to tracked effect fallbacks; writable projection arrays emit setter row ops at their fold-commit visibility moment; row-ops/slot registrations resolve chained backings to the ultimate owner; duplicate keys match occurrence-aware instead of first-wins; the production dev-token typo (`_DX_DEV_`) is fixed; `patchDriver: true` normalizes identically in Babel and the native loader, the option is typed in `TransformOptions`, and a `dom-patch` parity tier ratchets patch-mode output across both compilers (currently byte-identical on all fixtures).
|
|
8
|
+
- b534733: Scope-wrap bare function children in hydratable mode. A function child (`<main>{() => <App/>}</main>`, including via the `children` attribute) is a deferred hole at runtime, but it never classified as `dynamic`, so neither generate reserved an id scope for it — its owner ids drifted across async retry passes on the server and desynced from the client (the #2900 hydration-id-parity class). Both compilers now treat syntactic function expressions as scope-eligible alongside dynamic values, emitting `_$scope(...)` in the ssr generate and around the matching insert accessor in the dom generate. The native compiler also unwraps TS casts in the allocate-ids predicate, matching Babel (fixes a scope-emission desync for `{call() as any}` children).
|
|
9
|
+
|
|
3
10
|
## 2.0.0-rc.3
|
|
4
11
|
|
|
5
12
|
### Minor Changes
|
package/index.js
CHANGED
|
@@ -478,6 +478,9 @@ function canReturnHydratableChild(node) {
|
|
|
478
478
|
if (t__namespace.isTSNonNullExpression(node) || t__namespace.isTSAsExpression(node) || t__namespace.isTSSatisfiesExpression(node))
|
|
479
479
|
return canReturnHydratableChild(node.expression);
|
|
480
480
|
if (t__namespace.isJSXElement(node) || t__namespace.isJSXFragment(node) || t__namespace.isCallExpression(node)) return true;
|
|
481
|
+
// A function child is a deferred hole: whatever it returns renders inside
|
|
482
|
+
// the hole, so it can always mint hydratable content.
|
|
483
|
+
if (t__namespace.isFunction(node)) return true;
|
|
481
484
|
if (t__namespace.isMemberExpression(node) || t__namespace.isOptionalMemberExpression(node)) {
|
|
482
485
|
return !node.computed && t__namespace.isIdentifier(node.property, { name: "children" });
|
|
483
486
|
}
|
|
@@ -493,6 +496,23 @@ function canChildSlotAllocateIds(node) {
|
|
|
493
496
|
return node.isJSXExpressionContainer() && canReturnHydratableChild(node.node.expression);
|
|
494
497
|
}
|
|
495
498
|
|
|
499
|
+
// A syntactic function-expression hole (`{() => ...}` / `{function () {}}`,
|
|
500
|
+
// TS casts unwrapped). Function children never classify as `dynamic` — the
|
|
501
|
+
// literal reads nothing at template time — yet at runtime they are deferred
|
|
502
|
+
// holes exactly like call-shaped values, so the scope gates treat them as
|
|
503
|
+
// scope-eligible alongside `dynamic` (solidjs/solid#3068 follow-up).
|
|
504
|
+
function isFunctionShapedHole(node) {
|
|
505
|
+
if (!node.isJSXExpressionContainer()) return false;
|
|
506
|
+
let expression = node.node.expression;
|
|
507
|
+
while (
|
|
508
|
+
t__namespace.isTSNonNullExpression(expression) ||
|
|
509
|
+
t__namespace.isTSAsExpression(expression) ||
|
|
510
|
+
t__namespace.isTSSatisfiesExpression(expression))
|
|
511
|
+
|
|
512
|
+
expression = expression.expression;
|
|
513
|
+
return t__namespace.isFunction(expression);
|
|
514
|
+
}
|
|
515
|
+
|
|
496
516
|
function wrappedByText(list, startIndex) {
|
|
497
517
|
let index = startIndex,
|
|
498
518
|
wrapped;
|
|
@@ -2408,6 +2428,8 @@ config)
|
|
|
2408
2428
|
if (!transformed) return memo;
|
|
2409
2429
|
transformed.allocatesIds =
|
|
2410
2430
|
config.hydratable && canChildSlotAllocateIds(child);
|
|
2431
|
+
transformed.functionHole =
|
|
2432
|
+
isFunctionShapedHole(child);
|
|
2411
2433
|
const i = memo.length;
|
|
2412
2434
|
if (transformed.text && i && memo[i - 1].text) {
|
|
2413
2435
|
memo[i - 1].template =
|
|
@@ -2493,7 +2515,12 @@ config)
|
|
|
2493
2515
|
// allocate hydration ids get their own owner scope (insert makes the
|
|
2494
2516
|
// outer render effect non-transparent for tagged accessors). Keyed off
|
|
2495
2517
|
// `dynamic` so both generates decide identically for the same source.
|
|
2496
|
-
|
|
2518
|
+
// Function children never classify as dynamic but are deferred holes
|
|
2519
|
+
// all the same, so they take the scope too.
|
|
2520
|
+
if (
|
|
2521
|
+
child.allocatesIds && (
|
|
2522
|
+
child.dynamic || child.functionHole))
|
|
2523
|
+
{
|
|
2497
2524
|
let expr = child.exprs[0];
|
|
2498
2525
|
// The shared transform simplifies `{sig()}` to the bare getter `sig`;
|
|
2499
2526
|
// rewrap so tagging the scope doesn't mutate the user's function.
|
|
@@ -4270,9 +4297,11 @@ results,
|
|
|
4270
4297
|
// Deferred holes that can allocate hydration ids evaluate under their
|
|
4271
4298
|
// own owner scope so retry timing can't skew sibling ids (mirrors the
|
|
4272
4299
|
// dom generate's `scope()` wrap around the matching insert accessor).
|
|
4273
|
-
// Keyed off `dynamic` so both generates decide identically.
|
|
4300
|
+
// Keyed off `dynamic` so both generates decide identically. Function
|
|
4301
|
+
// children never classify as dynamic but are deferred holes all the
|
|
4302
|
+
// same, so they take the scope too.
|
|
4274
4303
|
let expr = child.exprs[0];
|
|
4275
|
-
if (allocatesIds && child.dynamic) {
|
|
4304
|
+
if (allocatesIds && (child.dynamic || isFunctionShapedHole(node))) {
|
|
4276
4305
|
expr = t.callExpression(registerImportMethod(path, "scope"), [expr]);
|
|
4277
4306
|
}
|
|
4278
4307
|
|
|
@@ -4326,7 +4355,7 @@ path,
|
|
|
4326
4355
|
// dom generate scope()s the matching insert accessor regardless of
|
|
4327
4356
|
// spread, so skipping it here desyncs every hydration id that follows
|
|
4328
4357
|
// the hole.
|
|
4329
|
-
if (child.exprs.length && allocatesIds && child.dynamic) {
|
|
4358
|
+
if (child.exprs.length && allocatesIds && (child.dynamic || isFunctionShapedHole(path))) {
|
|
4330
4359
|
child.exprs[0] = t.callExpression(registerImportMethod(path, "scope"), [
|
|
4331
4360
|
child.exprs[0]]
|
|
4332
4361
|
);
|
|
@@ -14526,6 +14555,9 @@ const config = {
|
|
|
14526
14555
|
var preprocess = (path, state) => {
|
|
14527
14556
|
const file = path.hub.file;
|
|
14528
14557
|
const merged = file.metadata.config = Object.assign({}, config, state.opts);
|
|
14558
|
+
// Boolean opt-in parity with the native loader: `patchDriver: true` means
|
|
14559
|
+
// the default import name (downstream code uses the value AS the name).
|
|
14560
|
+
if (merged.patchDriver === true) merged.patchDriver = "patchDriver";
|
|
14529
14561
|
const lib = merged.requireImportSource;
|
|
14530
14562
|
if (lib) {
|
|
14531
14563
|
const comments = file.ast.comments ?? [];
|