octane 0.1.39 → 0.1.41

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/README.md CHANGED
@@ -17,6 +17,10 @@ wrapper is narrower: the wrapper must be locally declared in a fully compiled
17
17
  parameter to a supported hook. This package ships both the runtime and compiler,
18
18
  with the compiler exposed at `octane/compiler`.
19
19
 
20
+ Custom Node build pipelines can opt into project-aware string-child inference
21
+ through `octane/compiler/typescript`. See the
22
+ [type-aware text compilation guide](https://github.com/octanejs/octane/blob/main/docs/compiler-text-inference.md).
23
+
20
24
  Direct Node or Bun server scripts can preload `octane/compiler/register` to
21
25
  compile imported Octane components without going through Vite. See the
22
26
  [SSR guide](https://github.com/octanejs/octane/blob/main/docs/ssr.md#run-an-ssg-script-directly).
@@ -104,6 +104,15 @@ __export(runtime_exports, {
104
104
  hasPendingWork: () => hasPendingWork,
105
105
  headBlock: () => headBlock,
106
106
  hmr: () => hmr,
107
+ hookMemoCreate: () => hookMemoCreate,
108
+ hookMemoEqual: () => hookMemoEqual,
109
+ hookMemoPublish: () => hookMemoPublish,
110
+ hookMemoPublish0: () => hookMemoPublish0,
111
+ hookMemoPublish1: () => hookMemoPublish1,
112
+ hookMemoPublish2: () => hookMemoPublish2,
113
+ hookMemoPublish3: () => hookMemoPublish3,
114
+ hookMemoPublish4: () => hookMemoPublish4,
115
+ hookMemoPublishInvariant: () => hookMemoPublishInvariant,
107
116
  hookSlots: () => hookSlots,
108
117
  hostComponent: () => hostComponent,
109
118
  htext: () => htext,
@@ -121,6 +130,14 @@ __export(runtime_exports, {
121
130
  markNativeChangeDiagnosticStatic: () => markNativeChangeDiagnosticStatic,
122
131
  markSingleRoot: () => markSingleRoot,
123
132
  memo: () => memo,
133
+ memoPublish: () => memoPublish,
134
+ memoPublishAlways: () => memoPublishAlways,
135
+ memoSlot: () => memoSlot,
136
+ memoTake0: () => memoTake0,
137
+ memoTake1: () => memoTake1,
138
+ memoTake2: () => memoTake2,
139
+ memoTake3: () => memoTake3,
140
+ memoTake4: () => memoTake4,
124
141
  mountFragmentRef: () => mountFragmentRef,
125
142
  namespaceHead: () => namespaceHead,
126
143
  namespaceHeadElement: () => namespaceHeadElement,
@@ -525,7 +542,7 @@ let deferringStagedRevealEffects = false;
525
542
  let ACTIVE_TRANSITION_ATTEMPT = null;
526
543
  let FLUSHED_TRANSITION_UPDATES = [];
527
544
  let HELD_SYNC_TRANSITION = null;
528
- let PROMOTED_PU_SWAPS = null;
545
+ let PROMOTED_MEMO_SWAPS = null;
529
546
  let PROMOTED_WARM_HARVEST = null;
530
547
  function beginTransitionAttempt(block) {
531
548
  if (block.pendingMode !== "transition" || ACTIVE_TRANSITION_ATTEMPT !== null) return null;
@@ -543,7 +560,7 @@ function beginTransitionAttempt(block) {
543
560
  refDetach: refDetachQueue.length,
544
561
  effectDeps: snapshotSubtreeEffectDeps(block),
545
562
  heldSlots: null,
546
- puSwaps: null
563
+ memoSwaps: null
547
564
  };
548
565
  ACTIVE_TRANSITION_ATTEMPT = attempt;
549
566
  return attempt;
@@ -553,7 +570,7 @@ function endTransitionAttempt(attempt) {
553
570
  ACTIVE_TRANSITION_ATTEMPT = null;
554
571
  const held = attempt.heldSlots;
555
572
  if (held === null || held.size === 0) {
556
- PROMOTED_PU_SWAPS = null;
573
+ PROMOTED_MEMO_SWAPS = null;
557
574
  PROMOTED_WARM_HARVEST = null;
558
575
  }
559
576
  let entries = null;
@@ -587,19 +604,15 @@ function endTransitionAttempt(attempt) {
587
604
  refAttachQueue.length = attempt.refAttach;
588
605
  refDetachQueue.length = attempt.refDetach;
589
606
  restoreSubtreeEffectDeps(attempt.origin, attempt.effectDeps);
590
- const continuing = PROMOTED_PU_SWAPS !== null || PROMOTED_WARM_HARVEST !== null;
591
- let puSwaps = attempt.puSwaps;
607
+ const continuing = PROMOTED_MEMO_SWAPS !== null || PROMOTED_WARM_HARVEST !== null;
608
+ let memoSwaps = attempt.memoSwaps;
592
609
  if (continuing) {
593
- if (PROMOTED_PU_SWAPS !== null) {
594
- puSwaps = puSwaps === null ? PROMOTED_PU_SWAPS : PROMOTED_PU_SWAPS.concat(puSwaps);
595
- PROMOTED_PU_SWAPS = null;
596
- }
597
- } else if (puSwaps !== null) {
598
- for (let i = puSwaps.length - 1; i >= 0; i--) {
599
- const [hooks, slot, prev] = puSwaps[i];
600
- if (prev === void 0) hooks.delete(slot);
601
- else hooks.set(slot, prev);
610
+ if (PROMOTED_MEMO_SWAPS !== null) {
611
+ memoSwaps = memoSwaps === null ? PROMOTED_MEMO_SWAPS : PROMOTED_MEMO_SWAPS.concat(memoSwaps);
612
+ PROMOTED_MEMO_SWAPS = null;
602
613
  }
614
+ } else if (memoSwaps !== null) {
615
+ for (let i = memoSwaps.length - 1; i >= 0; i--) applyTransitionMemoSwap(memoSwaps[i], false);
603
616
  }
604
617
  for (let i = 0; i < entries.length; i++) {
605
618
  entries[i].slot.value = entries[i].baseValue;
@@ -632,7 +645,7 @@ function endTransitionAttempt(attempt) {
632
645
  HELD_SYNC_TRANSITION = {
633
646
  origin: attempt.origin,
634
647
  entries,
635
- puSwaps,
648
+ memoSwaps,
636
649
  warmHarvest,
637
650
  holders: new Set(held)
638
651
  };
@@ -644,11 +657,26 @@ function endTransitionAttempt(attempt) {
644
657
  flushParkedItems();
645
658
  }
646
659
  }
647
- function journalPuEntry(scope, slot, next) {
660
+ function journalMemoEntry(scope, slot, next) {
648
661
  const attempt = ACTIVE_TRANSITION_ATTEMPT;
649
662
  if (attempt === null) return;
650
663
  const hooks = ensureHooks(scope);
651
- (attempt.puSwaps ??= []).push([hooks, slot, hooks.get(slot), next]);
664
+ (attempt.memoSwaps ??= []).push([0, hooks, slot, hooks.get(slot), next]);
665
+ }
666
+ function journalHookMemoCells(cells, base, next) {
667
+ const attempt = ACTIVE_TRANSITION_ATTEMPT;
668
+ if (attempt === null) return;
669
+ (attempt.memoSwaps ??= []).push([1, cells, base, cells.slice(base, base + next.length), next]);
670
+ }
671
+ function applyTransitionMemoSwap(swap, forward) {
672
+ if (swap[0] === 0) {
673
+ const value = forward ? swap[4] : swap[3];
674
+ if (!forward && value === void 0) swap[1].delete(swap[2]);
675
+ else swap[1].set(swap[2], value);
676
+ return;
677
+ }
678
+ const values = forward ? swap[4] : swap[3];
679
+ for (let i = 0; i < values.length; i++) swap[1][swap[2] + i] = values[i];
652
680
  }
653
681
  function heldSyncCellsIntact(state) {
654
682
  const held = HELD_SYNC_TRANSITION;
@@ -663,13 +691,10 @@ function promoteHeldSyncTransition() {
663
691
  const held = HELD_SYNC_TRANSITION;
664
692
  if (held === null) return false;
665
693
  HELD_SYNC_TRANSITION = null;
666
- const puSwaps = held.puSwaps;
667
- if (puSwaps !== null) {
668
- for (let i = 0; i < puSwaps.length; i++) {
669
- const [hooks, slot, , next] = puSwaps[i];
670
- hooks.set(slot, next);
671
- }
672
- PROMOTED_PU_SWAPS = PROMOTED_PU_SWAPS === null ? puSwaps : PROMOTED_PU_SWAPS.concat(puSwaps);
694
+ const memoSwaps = held.memoSwaps;
695
+ if (memoSwaps !== null) {
696
+ for (let i = 0; i < memoSwaps.length; i++) applyTransitionMemoSwap(memoSwaps[i], true);
697
+ PROMOTED_MEMO_SWAPS = PROMOTED_MEMO_SWAPS === null ? memoSwaps : PROMOTED_MEMO_SWAPS.concat(memoSwaps);
673
698
  }
674
699
  PROMOTED_WARM_HARVEST = held.warmHarvest;
675
700
  const promoted = [];
@@ -695,7 +720,7 @@ function discardHeldSyncTransition(state) {
695
720
  if (held === null || !held.holders.delete(state)) return;
696
721
  if (held.holders.size === 0) {
697
722
  HELD_SYNC_TRANSITION = null;
698
- PROMOTED_PU_SWAPS = null;
723
+ PROMOTED_MEMO_SWAPS = null;
699
724
  PROMOTED_WARM_HARVEST = null;
700
725
  }
701
726
  }
@@ -3505,45 +3530,115 @@ function useInsertionEffect(fn, deps, slot) {
3505
3530
  const [d, s] = resolveHookArgs("useInsertionEffect", deps, slot);
3506
3531
  enqueueEffect(s, fn, d, INSERTION);
3507
3532
  }
3533
+ function memoEntryHit(slot, entry) {
3534
+ if (entry.warmEpisode !== CURRENT_WARM_EPISODE && recordRealWarmMemo(slot, entry.deps, entry)) {
3535
+ entry.warmEpisode = CURRENT_WARM_EPISODE;
3536
+ }
3537
+ return entry;
3538
+ }
3539
+ function adoptMemoEntry(scope, slot, deps) {
3540
+ const adopted = adoptWarmValue(slot, deps);
3541
+ if (adopted === WARM_MISS) return null;
3542
+ const entry = {
3543
+ deps,
3544
+ value: adopted,
3545
+ warmEpisode: CURRENT_WARM_EPISODE
3546
+ };
3547
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) journalMemoEntry(scope, slot, entry);
3548
+ ensureHooks(scope).set(slot, entry);
3549
+ return entry;
3550
+ }
3551
+ function readMemoEntry(scope, slot, deps) {
3552
+ const prev = scope.hooks?.get(slot);
3553
+ if (prev && deps !== void 0 && !depsChanged(prev.deps, deps)) {
3554
+ return memoEntryHit(slot, prev);
3555
+ }
3556
+ return WARM_EVER && deps !== void 0 ? adoptMemoEntry(scope, slot, deps) : null;
3557
+ }
3558
+ function publishMemoEntry(scope, slot, deps, value) {
3559
+ const entry = { deps, value };
3560
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) journalMemoEntry(scope, slot, entry);
3561
+ ensureHooks(scope).set(slot, entry);
3562
+ if (deps !== void 0 && recordRealWarmMemo(slot, deps, entry)) {
3563
+ entry.warmEpisode = CURRENT_WARM_EPISODE;
3564
+ }
3565
+ return value;
3566
+ }
3508
3567
  function useMemo(compute, deps, slot) {
3509
3568
  const [d, s] = resolveHookArgs("useMemo", deps, slot);
3510
3569
  const scope = CURRENT_SCOPE;
3511
- const prev = scope.hooks?.get(s);
3512
- if (prev && d !== void 0 && !depsChanged(prev.deps, d)) {
3513
- if (prev.warmEpisode !== CURRENT_WARM_EPISODE && recordRealWarmMemo(s, d, prev)) {
3514
- prev.warmEpisode = CURRENT_WARM_EPISODE;
3515
- }
3516
- return prev.value;
3517
- }
3518
- if (WARM_EVER && d !== void 0) {
3519
- const adopted = adoptWarmValue(s, d);
3520
- if (adopted !== WARM_MISS) {
3521
- const adoptedEntry = {
3522
- deps: d,
3523
- value: adopted,
3524
- warmEpisode: CURRENT_WARM_EPISODE
3525
- };
3526
- if (ACTIVE_TRANSITION_ATTEMPT !== null) journalPuEntry(scope, s, adoptedEntry);
3527
- ensureHooks(scope).set(s, adoptedEntry);
3528
- return adopted;
3529
- }
3530
- }
3570
+ const entry = readMemoEntry(scope, s, d);
3571
+ if (entry !== null) return entry.value;
3531
3572
  const value = compute.apply(null, d ?? []);
3532
- const entry = { deps: d, value };
3533
- if (ACTIVE_TRANSITION_ATTEMPT !== null) journalPuEntry(scope, s, entry);
3534
- ensureHooks(scope).set(s, entry);
3535
- if (d !== void 0 && recordRealWarmMemo(s, d, entry)) {
3536
- entry.warmEpisode = CURRENT_WARM_EPISODE;
3573
+ return publishMemoEntry(scope, s, d, value);
3574
+ }
3575
+ function useCallback(fn, deps, slot) {
3576
+ const [d, s] = resolveHookArgs("useCallback", deps, slot);
3577
+ const scope = CURRENT_SCOPE;
3578
+ const entry = readMemoEntry(scope, s, d);
3579
+ return entry === null ? publishMemoEntry(scope, s, d, fn) : entry.value;
3580
+ }
3581
+ const hookMemoEqual = Object.is;
3582
+ function hookMemoCreate(size) {
3583
+ return new Array(size).fill(void 0);
3584
+ }
3585
+ function hookMemoPublish0(cells, base, value) {
3586
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) journalHookMemoCells(cells, base, [true, value]);
3587
+ cells[base + 1] = value;
3588
+ cells[base] = true;
3589
+ return value;
3590
+ }
3591
+ function hookMemoPublish1(cells, base, value, d0) {
3592
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) journalHookMemoCells(cells, base, [true, d0, value]);
3593
+ cells[base + 2] = value;
3594
+ cells[base + 1] = d0;
3595
+ cells[base] = true;
3596
+ return value;
3597
+ }
3598
+ function hookMemoPublish2(cells, base, value, d0, d1) {
3599
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) journalHookMemoCells(cells, base, [true, d0, d1, value]);
3600
+ cells[base + 3] = value;
3601
+ cells[base + 1] = d0;
3602
+ cells[base + 2] = d1;
3603
+ cells[base] = true;
3604
+ return value;
3605
+ }
3606
+ function hookMemoPublish3(cells, base, value, d0, d1, d2) {
3607
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) {
3608
+ journalHookMemoCells(cells, base, [true, d0, d1, d2, value]);
3537
3609
  }
3610
+ cells[base + 4] = value;
3611
+ cells[base + 1] = d0;
3612
+ cells[base + 2] = d1;
3613
+ cells[base + 3] = d2;
3614
+ cells[base] = true;
3538
3615
  return value;
3539
3616
  }
3540
- function useCallback(fn, deps, slot) {
3541
- if (slot === void 0 && typeof deps === "symbol") {
3542
- slot = deps;
3543
- deps = void 0;
3617
+ function hookMemoPublish4(cells, base, value, d0, d1, d2, d3) {
3618
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) {
3619
+ journalHookMemoCells(cells, base, [true, d0, d1, d2, d3, value]);
3544
3620
  }
3545
- if (resolveSlot(slot) === void 0) missingSlot("useCallback");
3546
- return useMemo(() => fn, deps, slot);
3621
+ cells[base + 5] = value;
3622
+ cells[base + 1] = d0;
3623
+ cells[base + 2] = d1;
3624
+ cells[base + 3] = d2;
3625
+ cells[base + 4] = d3;
3626
+ cells[base] = true;
3627
+ return value;
3628
+ }
3629
+ function hookMemoPublish(cells, base, value, ...deps) {
3630
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) {
3631
+ journalHookMemoCells(cells, base, [true, ...deps, value]);
3632
+ }
3633
+ cells[base + deps.length + 1] = value;
3634
+ for (let i = 0; i < deps.length; i++) cells[base + i + 1] = deps[i];
3635
+ cells[base] = true;
3636
+ return value;
3637
+ }
3638
+ function hookMemoPublishInvariant(cells, base, value) {
3639
+ if (ACTIVE_TRANSITION_ATTEMPT !== null) journalHookMemoCells(cells, base, [value]);
3640
+ cells[base] = value;
3641
+ return value;
3547
3642
  }
3548
3643
  function useRef(initial, slot) {
3549
3644
  if (slot === void 0 && typeof initial === "symbol") {
@@ -3628,6 +3723,10 @@ function useSyncExternalStore(subscribe, getSnapshot, ...rest) {
3628
3723
  scheduleRender(block);
3629
3724
  } : () => scheduleRender(block),
3630
3725
  onStoreChange: () => {
3726
+ if (block.disposed) return;
3727
+ if (CURRENT_BLOCK === null && block.pending && block.pendingMode === "urgent" && !block.pendingDeferred && !(typeof __OCTANE_PROFILE_ENABLED__ !== "undefined" && __OCTANE_PROFILE_ENABLED__) && (process.env.NODE_ENV === "production" || !IS_OCTANE_ACT_ENVIRONMENT || actScopeDepth !== 0 || syncFlush)) {
3728
+ return;
3729
+ }
3631
3730
  if (checkStoreChanged(created)) created.forceUpdate();
3632
3731
  },
3633
3732
  block,
@@ -5360,28 +5459,14 @@ function adoptWarmValue(slot, deps) {
5360
5459
  return WARM_MISS;
5361
5460
  }
5362
5461
  const puMiss = /* @__PURE__ */ Symbol("octane.pu.miss");
5363
- function puHit(slot, entry) {
5364
- if (entry.warmEpisode !== CURRENT_WARM_EPISODE && recordRealWarmMemo(slot, entry.deps, entry)) {
5365
- entry.warmEpisode = CURRENT_WARM_EPISODE;
5366
- }
5367
- return entry.value;
5368
- }
5369
5462
  function puAdopt(slot, deps) {
5370
- const adopted = adoptWarmValue(slot, deps);
5371
- if (adopted === WARM_MISS) return puMiss;
5372
- const adoptedEntry = {
5373
- deps,
5374
- value: adopted,
5375
- warmEpisode: CURRENT_WARM_EPISODE
5376
- };
5377
- if (ACTIVE_TRANSITION_ATTEMPT !== null) journalPuEntry(CURRENT_SCOPE, slot, adoptedEntry);
5378
- ensureHooks(CURRENT_SCOPE).set(slot, adoptedEntry);
5379
- return adopted;
5463
+ const entry = adoptMemoEntry(CURRENT_SCOPE, slot, deps);
5464
+ return entry === null ? puMiss : entry.value;
5380
5465
  }
5381
5466
  function puTake0(slot) {
5382
5467
  const prev = CURRENT_SCOPE.hooks?.get(slot);
5383
5468
  if (prev !== void 0 && prev.deps !== void 0 && prev.deps.length === 0) {
5384
- return puHit(slot, prev);
5469
+ return memoEntryHit(slot, prev).value;
5385
5470
  }
5386
5471
  if (WARM_EVER) return puAdopt(slot, []);
5387
5472
  return puMiss;
@@ -5390,7 +5475,9 @@ function puTake1(slot, d0) {
5390
5475
  const prev = CURRENT_SCOPE.hooks?.get(slot);
5391
5476
  if (prev !== void 0) {
5392
5477
  const pd = prev.deps;
5393
- if (pd !== void 0 && pd.length === 1 && Object.is(pd[0], d0)) return puHit(slot, prev);
5478
+ if (pd !== void 0 && pd.length === 1 && Object.is(pd[0], d0)) {
5479
+ return memoEntryHit(slot, prev).value;
5480
+ }
5394
5481
  }
5395
5482
  if (WARM_EVER) return puAdopt(slot, [d0]);
5396
5483
  return puMiss;
@@ -5400,7 +5487,7 @@ function puTake2(slot, d0, d1) {
5400
5487
  if (prev !== void 0) {
5401
5488
  const pd = prev.deps;
5402
5489
  if (pd !== void 0 && pd.length === 2 && Object.is(pd[0], d0) && Object.is(pd[1], d1)) {
5403
- return puHit(slot, prev);
5490
+ return memoEntryHit(slot, prev).value;
5404
5491
  }
5405
5492
  }
5406
5493
  if (WARM_EVER) return puAdopt(slot, [d0, d1]);
@@ -5411,7 +5498,7 @@ function puTake3(slot, d0, d1, d2) {
5411
5498
  if (prev !== void 0) {
5412
5499
  const pd = prev.deps;
5413
5500
  if (pd !== void 0 && pd.length === 3 && Object.is(pd[0], d0) && Object.is(pd[1], d1) && Object.is(pd[2], d2)) {
5414
- return puHit(slot, prev);
5501
+ return memoEntryHit(slot, prev).value;
5415
5502
  }
5416
5503
  }
5417
5504
  if (WARM_EVER) return puAdopt(slot, [d0, d1, d2]);
@@ -5422,18 +5509,77 @@ function puTake4(slot, d0, d1, d2, d3) {
5422
5509
  if (prev !== void 0) {
5423
5510
  const pd = prev.deps;
5424
5511
  if (pd !== void 0 && pd.length === 4 && Object.is(pd[0], d0) && Object.is(pd[1], d1) && Object.is(pd[2], d2) && Object.is(pd[3], d3)) {
5425
- return puHit(slot, prev);
5512
+ return memoEntryHit(slot, prev).value;
5426
5513
  }
5427
5514
  }
5428
5515
  if (WARM_EVER) return puAdopt(slot, [d0, d1, d2, d3]);
5429
5516
  return puMiss;
5430
5517
  }
5431
5518
  function puPub(slot, value, ...deps) {
5432
- const entry = { deps, value };
5433
- if (ACTIVE_TRANSITION_ATTEMPT !== null) journalPuEntry(CURRENT_SCOPE, slot, entry);
5434
- ensureHooks(CURRENT_SCOPE).set(slot, entry);
5435
- if (recordRealWarmMemo(slot, deps, entry)) entry.warmEpisode = CURRENT_WARM_EPISODE;
5436
- return value;
5519
+ return publishMemoEntry(CURRENT_SCOPE, slot, deps, value);
5520
+ }
5521
+ function memoSlot(slot, name) {
5522
+ const resolved = resolveSlot(slot);
5523
+ if (resolved === void 0) missingSlot(name);
5524
+ return resolved;
5525
+ }
5526
+ function memoTake0(slot) {
5527
+ const scope = CURRENT_SCOPE;
5528
+ const prev = scope.hooks?.get(slot);
5529
+ if (prev !== void 0 && prev.deps !== void 0 && prev.deps.length === 0) {
5530
+ return memoEntryHit(slot, prev);
5531
+ }
5532
+ return WARM_EVER ? adoptMemoEntry(scope, slot, []) : null;
5533
+ }
5534
+ function memoTake1(slot, d0) {
5535
+ const scope = CURRENT_SCOPE;
5536
+ const prev = scope.hooks?.get(slot);
5537
+ if (prev !== void 0) {
5538
+ const pd = prev.deps;
5539
+ if (pd !== void 0 && pd.length === 1 && Object.is(pd[0], d0)) {
5540
+ return memoEntryHit(slot, prev);
5541
+ }
5542
+ }
5543
+ return WARM_EVER ? adoptMemoEntry(scope, slot, [d0]) : null;
5544
+ }
5545
+ function memoTake2(slot, d0, d1) {
5546
+ const scope = CURRENT_SCOPE;
5547
+ const prev = scope.hooks?.get(slot);
5548
+ if (prev !== void 0) {
5549
+ const pd = prev.deps;
5550
+ if (pd !== void 0 && pd.length === 2 && Object.is(pd[0], d0) && Object.is(pd[1], d1)) {
5551
+ return memoEntryHit(slot, prev);
5552
+ }
5553
+ }
5554
+ return WARM_EVER ? adoptMemoEntry(scope, slot, [d0, d1]) : null;
5555
+ }
5556
+ function memoTake3(slot, d0, d1, d2) {
5557
+ const scope = CURRENT_SCOPE;
5558
+ const prev = scope.hooks?.get(slot);
5559
+ if (prev !== void 0) {
5560
+ const pd = prev.deps;
5561
+ if (pd !== void 0 && pd.length === 3 && Object.is(pd[0], d0) && Object.is(pd[1], d1) && Object.is(pd[2], d2)) {
5562
+ return memoEntryHit(slot, prev);
5563
+ }
5564
+ }
5565
+ return WARM_EVER ? adoptMemoEntry(scope, slot, [d0, d1, d2]) : null;
5566
+ }
5567
+ function memoTake4(slot, d0, d1, d2, d3) {
5568
+ const scope = CURRENT_SCOPE;
5569
+ const prev = scope.hooks?.get(slot);
5570
+ if (prev !== void 0) {
5571
+ const pd = prev.deps;
5572
+ if (pd !== void 0 && pd.length === 4 && Object.is(pd[0], d0) && Object.is(pd[1], d1) && Object.is(pd[2], d2) && Object.is(pd[3], d3)) {
5573
+ return memoEntryHit(slot, prev);
5574
+ }
5575
+ }
5576
+ return WARM_EVER ? adoptMemoEntry(scope, slot, [d0, d1, d2, d3]) : null;
5577
+ }
5578
+ function memoPublish(slot, value, ...deps) {
5579
+ return publishMemoEntry(CURRENT_SCOPE, slot, deps, value);
5580
+ }
5581
+ function memoPublishAlways(slot, value) {
5582
+ return publishMemoEntry(CURRENT_SCOPE, slot, void 0, value);
5437
5583
  }
5438
5584
  const LAZY_COMPONENT = /* @__PURE__ */ Symbol.for("octane.lazy");
5439
5585
  function resolveLazyModule(mod) {
@@ -16977,6 +17123,15 @@ function scriptResource(attrs) {
16977
17123
  hasPendingWork,
16978
17124
  headBlock,
16979
17125
  hmr,
17126
+ hookMemoCreate,
17127
+ hookMemoEqual,
17128
+ hookMemoPublish,
17129
+ hookMemoPublish0,
17130
+ hookMemoPublish1,
17131
+ hookMemoPublish2,
17132
+ hookMemoPublish3,
17133
+ hookMemoPublish4,
17134
+ hookMemoPublishInvariant,
16980
17135
  hookSlots,
16981
17136
  hostComponent,
16982
17137
  htext,
@@ -16994,6 +17149,14 @@ function scriptResource(attrs) {
16994
17149
  markNativeChangeDiagnosticStatic,
16995
17150
  markSingleRoot,
16996
17151
  memo,
17152
+ memoPublish,
17153
+ memoPublishAlways,
17154
+ memoSlot,
17155
+ memoTake0,
17156
+ memoTake1,
17157
+ memoTake2,
17158
+ memoTake3,
17159
+ memoTake4,
16997
17160
  mountFragmentRef,
16998
17161
  namespaceHead,
16999
17162
  namespaceHeadElement,
@@ -3133,24 +3133,27 @@ const useLayoutEffect = useEffect;
3133
3133
  const useInsertionEffect = useEffect;
3134
3134
  function useImperativeHandle() {
3135
3135
  }
3136
- function useMemo(compute, depsOrSlot, maybeSlot) {
3136
+ function memoHookValue(input, compute, depsOrSlot, maybeSlot) {
3137
3137
  const deps = Array.isArray(depsOrSlot) ? depsOrSlot : null;
3138
3138
  const slot = maybeSlot ?? (Array.isArray(depsOrSlot) || depsOrSlot === null ? void 0 : depsOrSlot);
3139
- if (deps === null) return compute();
3139
+ if (deps === null) return compute ? input() : input;
3140
3140
  const position = hookPosition(slot);
3141
- if (position === null) return compute();
3141
+ if (position === null) return compute ? input() : input;
3142
3142
  let rec = position.list[position.index];
3143
3143
  if (rec === void 0) {
3144
- rec = { value: compute(), deps: deps.slice() };
3144
+ rec = { value: compute ? input() : input, deps: deps.slice() };
3145
3145
  position.list[position.index] = rec;
3146
3146
  } else if (!serverDepsEqual(rec.deps, deps)) {
3147
- rec.value = compute();
3147
+ rec.value = compute ? input() : input;
3148
3148
  rec.deps = deps.slice();
3149
3149
  }
3150
3150
  return rec.value;
3151
3151
  }
3152
+ function useMemo(compute, depsOrSlot, maybeSlot) {
3153
+ return memoHookValue(compute, true, depsOrSlot, maybeSlot);
3154
+ }
3152
3155
  function useCallback(fn, depsOrSlot, maybeSlot) {
3153
- return useMemo(() => fn, depsOrSlot, maybeSlot);
3156
+ return memoHookValue(fn, false, depsOrSlot, maybeSlot);
3154
3157
  }
3155
3158
  function useRef(initial, slot) {
3156
3159
  if (slot === void 0 && typeof initial === "symbol") {
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  version: () => version
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const version = "0.1.39";
24
+ const version = "0.1.41";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  version
@@ -480,6 +480,7 @@ class OctaneBundlerCompiler {
480
480
  hmr: normalizeHmrDialect(options.hmr),
481
481
  dev: options.dev,
482
482
  profile: options.profile === true,
483
+ inlineHookMemo: options.inlineHookMemo !== false,
483
484
  strong: options.strong === true,
484
485
  universalRuntime: normalizeUniversalRuntime(options.universalRuntime),
485
486
  };
@@ -990,6 +991,7 @@ class OctaneBundlerCompiler {
990
991
  // of both HMR and dev hydration diagnostics. Server transforms stay byte-for-
991
992
  // byte identical even when a shared client/server bundler configuration opts in.
992
993
  const profile = environment === 'client' && (options.profile ?? this.defaults.profile) === true;
994
+ const inlineHookMemo = (options.inlineHookMemo ?? this.defaults.inlineHookMemo) !== false;
993
995
  // An application's global policy never leaks into installed or linked
994
996
  // compatibility packages, including workspace packages nested inside the
995
997
  // project root. Modules may still opt themselves in with their own
@@ -1087,6 +1089,7 @@ class OctaneBundlerCompiler {
1087
1089
  dev,
1088
1090
  profile,
1089
1091
  profileFilename,
1092
+ ...(inlineHookMemo ? null : { inlineHookMemo: false }),
1090
1093
  ...(strong ? { strong: true } : null),
1091
1094
  ...(universalRuntime === undefined ? null : { universalRuntime }),
1092
1095
  // Keep the established DOM compiler call byte-for-byte equivalent. A
@@ -1170,7 +1173,16 @@ class OctaneBundlerCompiler {
1170
1173
  this._warnUnmarkedOctaneImport(code, filename);
1171
1174
  return passThrough();
1172
1175
  }
1173
- if (this._hasManualHookSlots(file, collected)) {
1176
+ const manualSlots = this._hasManualHookSlots(file, collected);
1177
+ const inlinePlainMemo =
1178
+ inlineHookMemo &&
1179
+ environment === 'client' &&
1180
+ hmr === false &&
1181
+ dev === false &&
1182
+ profile === false &&
1183
+ renderer.target === 'dom' &&
1184
+ universalRuntime === undefined;
1185
+ if (manualSlots && !inlinePlainMemo) {
1174
1186
  // Hand-slotted bindings still own their authored policy. Opting one
1175
1187
  // module in must not require changing its established slot ABI.
1176
1188
  if (strong || code.includes('use strong')) {
@@ -1183,12 +1195,19 @@ class OctaneBundlerCompiler {
1183
1195
  }
1184
1196
  const profileFilename = profile ? this._profileModuleId(file, collected) : undefined;
1185
1197
  const specializeVoidRoot =
1186
- environment === 'client' && hmr === false && dev === false && profile === false;
1198
+ !manualSlots &&
1199
+ environment === 'client' &&
1200
+ hmr === false &&
1201
+ dev === false &&
1202
+ profile === false;
1187
1203
  const out = slotHooks(code, filename, {
1188
1204
  environment,
1189
1205
  hmr: !!hmr,
1206
+ dev,
1190
1207
  profile,
1191
1208
  profileFilename,
1209
+ inlineHookMemo: inlinePlainMemo,
1210
+ ...(manualSlots ? { manualSlots: true } : null),
1192
1211
  ...(strong ? { strong: true } : null),
1193
1212
  ...(specializeVoidRoot
1194
1213
  ? {
@@ -685,7 +685,7 @@ function createLexicalScope(parent, isFunction = false) {
685
685
  return scope;
686
686
  }
687
687
 
688
- function createLexicalAnalysis(ast) {
688
+ export function createLexicalAnalysis(ast) {
689
689
  const bindingNodes = new WeakSet();
690
690
  const nonReferenceNodes = new WeakSet();
691
691
  const nodeScopes = new WeakMap();