@logixjs/react 0.1.1 → 1.0.0

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/index.cjs CHANGED
@@ -58,7 +58,7 @@ var RuntimeContext = (0, import_react.createContext)(null);
58
58
 
59
59
  // src/internal/provider/config.ts
60
60
  var import_effect = require("effect");
61
- var ReactRuntimeConfigTag = class extends import_effect.Context.Tag("@logixjs/react/RuntimeConfig")() {
61
+ var ReactRuntimeConfigTag = class extends import_effect.ServiceMap.Service()("@logixjs/react/RuntimeConfig") {
62
62
  };
63
63
  var DEFAULT_CONFIG = {
64
64
  gcTime: 500,
@@ -168,13 +168,13 @@ var ReactRuntimeConfigSnapshot = {
168
168
  })
169
169
  };
170
170
 
171
+ // src/internal/provider/env.ts
172
+ var import_Env = require("@logixjs/core/Env");
173
+
171
174
  // src/internal/provider/fallback.tsx
172
175
  var import_react2 = require("react");
173
176
  var Logix = __toESM(require("@logixjs/core"), 1);
174
177
 
175
- // src/internal/provider/env.ts
176
- var import_Env = require("@logixjs/core/Env");
177
-
178
178
  // src/internal/provider/docs.ts
179
179
  var LOGIX_DOCS_PREFIX_ENV = "LOGIX_DOCS_PREFIX";
180
180
  var stripTrailingSlashes = (value) => value.replace(/\/+$/, "");
@@ -435,14 +435,11 @@ var useLayerBinding = (runtime, layer, enabled, onError) => {
435
435
  const newScope = import_effect2.Effect.runSync(import_effect2.Scope.make());
436
436
  const buildEffect = import_effect2.Effect.gen(function* () {
437
437
  const context = yield* import_effect2.Layer.buildWithScope(layer, newScope);
438
- const applyEnv = (effect) => import_effect2.Effect.mapInputContext(
439
- import_effect2.Scope.extend(effect, newScope),
440
- (parent) => import_effect2.Context.merge(parent, context)
441
- );
442
- const loggers = yield* applyEnv(import_effect2.FiberRef.get(import_effect2.FiberRef.currentLoggers));
443
- const logLevel = yield* applyEnv(import_effect2.FiberRef.get(import_effect2.FiberRef.currentLogLevel));
438
+ const applyEnv = (effect) => import_effect2.Scope.provide(newScope)(import_effect2.Effect.provideServices(effect, context));
439
+ const loggers = yield* applyEnv(import_effect2.Effect.service(import_effect2.Logger.CurrentLoggers)).pipe(import_effect2.Effect.orDie);
440
+ const logLevel = yield* applyEnv(import_effect2.Effect.service(import_effect2.References.MinimumLogLevel)).pipe(import_effect2.Effect.orDie);
444
441
  const debugSinks = yield* applyEnv(
445
- import_effect2.FiberRef.get(Logix2.Debug.internal.currentDebugSinks)
442
+ import_effect2.Effect.service(Logix2.Debug.internal.currentDebugSinks).pipe(import_effect2.Effect.orDie)
446
443
  );
447
444
  return { context, loggers, logLevel, debugSinks };
448
445
  });
@@ -487,7 +484,7 @@ var useLayerBinding = (runtime, layer, enabled, onError) => {
487
484
  const cause = import_effect2.Cause.die(error);
488
485
  runtime.runFork(
489
486
  onError(cause, { source: "provider", phase: "provider.layer.build" }).pipe(
490
- import_effect2.Effect.catchAllCause(() => import_effect2.Effect.void)
487
+ import_effect2.Effect.catchCause(() => import_effect2.Effect.void)
491
488
  )
492
489
  );
493
490
  }
@@ -525,18 +522,11 @@ var createRuntimeAdapter = (runtime, contexts, scopes, loggerSets, logLevels, de
525
522
  if (contexts.length === 0 && scopes.length === 0 && loggerSets.length === 0 && logLevels.length === 0 && debugSinks.length === 0) {
526
523
  return runtime;
527
524
  }
528
- const applyContexts = (effect) => (
529
- // First inherit Provider scopes via scope.extend (preserving FiberRef/Logger changes),
530
- // then merge Context via mapInputContext (inner overrides outer).
531
- contexts.reduceRight(
532
- (acc, ctx) => import_effect2.Effect.mapInputContext(
533
- acc,
534
- (parent) => import_effect2.Context.merge(parent, ctx)
535
- ),
536
- scopes.reduceRight(
537
- (acc, scope) => import_effect2.Scope.extend(acc, scope),
538
- effect
539
- )
525
+ const applyContexts = (effect) => contexts.reduceRight(
526
+ (acc, ctx) => import_effect2.Effect.provideServices(acc, ctx),
527
+ scopes.reduceRight(
528
+ (acc, scope) => import_effect2.Scope.provide(scope)(acc),
529
+ effect
540
530
  )
541
531
  );
542
532
  const applyLoggers = (effect) => {
@@ -545,16 +535,13 @@ var createRuntimeAdapter = (runtime, contexts, scopes, loggerSets, logLevels, de
545
535
  const sinks = debugSinks.length > 0 ? debugSinks[debugSinks.length - 1] : null;
546
536
  let result = effect;
547
537
  if (last) {
548
- result = import_effect2.Effect.locally(import_effect2.FiberRef.currentLoggers, last)(result);
538
+ result = import_effect2.Effect.provideService(result, import_effect2.Logger.CurrentLoggers, last);
549
539
  }
550
540
  if (logLevel) {
551
- result = import_effect2.Effect.locally(import_effect2.FiberRef.currentLogLevel, logLevel)(result);
541
+ result = import_effect2.Effect.provideService(result, import_effect2.References.MinimumLogLevel, logLevel);
552
542
  }
553
543
  if (sinks && sinks.length > 0) {
554
- result = import_effect2.Effect.locally(
555
- Logix2.Debug.internal.currentDebugSinks,
556
- sinks
557
- )(result);
544
+ result = import_effect2.Effect.provideService(result, Logix2.Debug.internal.currentDebugSinks, sinks);
558
545
  }
559
546
  return result;
560
547
  };
@@ -685,9 +672,9 @@ ${message}`;
685
672
  console.debug(label, message);
686
673
  };
687
674
  var causeToUnknown = (cause) => {
688
- const failure = import_effect4.Option.getOrUndefined(import_effect4.Cause.failureOption(cause));
675
+ const failure = import_effect4.Option.getOrUndefined(import_effect4.Cause.findErrorOption(cause));
689
676
  if (failure !== void 0) return failure;
690
- const defect = import_effect4.Option.getOrUndefined(import_effect4.Cause.dieOption(cause));
677
+ const defect = cause.reasons.filter(import_effect4.Cause.isDieReason).map((reason) => reason.defect)[0];
691
678
  if (defect !== void 0) return defect;
692
679
  return cause;
693
680
  };
@@ -696,7 +683,7 @@ var yieldEffect = (strategy) => {
696
683
  case "none":
697
684
  return import_effect4.Effect.void;
698
685
  case "microtask":
699
- return import_effect4.Effect.yieldNow();
686
+ return import_effect4.Effect.yieldNow;
700
687
  case "macrotask":
701
688
  return import_effect4.Effect.promise(
702
689
  () => new Promise((resolve) => {
@@ -789,6 +776,67 @@ var ModuleCache = class {
789
776
  const scope = import_effect4.Effect.runSync(import_effect4.Scope.make());
790
777
  const workloadKey = `${options?.entrypoint ?? "unknown"}::${ownerId ?? "unknown"}`;
791
778
  const yieldDecision = decideYieldStrategy(this.runtime, workloadKey, options?.yield);
779
+ const optimisticSyncBudgetMs = options?.optimisticSyncBudgetMs ?? 0;
780
+ const shouldTryOptimisticSync = options?.policyMode === "suspend" && optimisticSyncBudgetMs > 0;
781
+ if (shouldTryOptimisticSync) {
782
+ const startedAt2 = performance.now();
783
+ try {
784
+ const value = this.runtime.runSync(factory(scope));
785
+ const durationMs = performance.now() - startedAt2;
786
+ YieldBudgetMemory.record({ runtime: this.runtime, workloadKey, durationMs });
787
+ const entry2 = {
788
+ scope,
789
+ status: "success",
790
+ promise: Promise.resolve(value),
791
+ value,
792
+ refCount: 0,
793
+ preloadRefCount: 0,
794
+ gcTime: gcTime ?? this.gcDelayMs,
795
+ ownerId,
796
+ createdBy: "read",
797
+ workloadKey,
798
+ yieldStrategy: "none"
799
+ };
800
+ this.scheduleGC(key, entry2);
801
+ this.entries.set(key, entry2);
802
+ if ((0, import_Env.isDevEnv)() || Logix4.Debug.isDevtoolsEnabled()) {
803
+ void this.runtime.runPromise(
804
+ Logix4.Debug.record({
805
+ type: "trace:react.module.init",
806
+ moduleId: ownerId,
807
+ instanceId: value.instanceId,
808
+ data: {
809
+ mode: "suspend",
810
+ key,
811
+ durationMs: Math.round(durationMs * 100) / 100,
812
+ yieldStrategy: "none",
813
+ fastPath: "sync"
814
+ }
815
+ })
816
+ ).catch((error) => {
817
+ debugBestEffortFailure("[ModuleCache] Debug.record failed", error);
818
+ });
819
+ void this.runtime.runPromise(
820
+ Logix4.Debug.record({
821
+ type: "trace:react.module-instance",
822
+ moduleId: ownerId,
823
+ instanceId: value.instanceId,
824
+ data: {
825
+ event: "attach",
826
+ key,
827
+ mode: "suspend",
828
+ gcTime: entry2.gcTime,
829
+ fastPath: "sync"
830
+ }
831
+ })
832
+ ).catch((error) => {
833
+ debugBestEffortFailure("[ModuleCache] Debug.record failed", error);
834
+ });
835
+ }
836
+ return value;
837
+ } catch {
838
+ }
839
+ }
792
840
  const entry = {
793
841
  scope,
794
842
  status: "pending",
@@ -804,7 +852,7 @@ var ModuleCache = class {
804
852
  };
805
853
  this.scheduleGC(key, entry);
806
854
  const startedAt = performance.now();
807
- const buildEffect = yieldEffect(yieldDecision.strategy).pipe(import_effect4.Effect.zipRight(factory(scope)));
855
+ const buildEffect = yieldEffect(yieldDecision.strategy).pipe(import_effect4.Effect.flatMap(() => factory(scope)));
808
856
  const fiber = this.runtime.runFork(buildEffect);
809
857
  entry.fiber = fiber;
810
858
  const promise = this.runtime.runPromise(import_effect4.Fiber.await(fiber)).then((exit) => {
@@ -1000,6 +1048,49 @@ var ModuleCache = class {
1000
1048
  throw error;
1001
1049
  }
1002
1050
  }
1051
+ warmSync(key, factory, gcTime, ownerId, options) {
1052
+ const existing = this.entries.get(key);
1053
+ if (existing) {
1054
+ if ((0, import_Env.isDevEnv)() && existing.ownerId !== void 0 && ownerId !== void 0 && existing.ownerId !== ownerId) {
1055
+ throw new Error(
1056
+ `[ModuleCache.warmSync] resource key "${key}" has already been claimed by module "${existing.ownerId}", but is now requested by module "${ownerId}".`
1057
+ );
1058
+ }
1059
+ if (existing.status === "success") {
1060
+ return existing.value;
1061
+ }
1062
+ return void 0;
1063
+ }
1064
+ const scope = this.runtime.runSync(import_effect4.Scope.make());
1065
+ const startedAt = performance.now();
1066
+ const workloadKey = `${options?.entrypoint ?? "unknown"}::${ownerId ?? "unknown"}`;
1067
+ try {
1068
+ const value = this.runtime.runSync(factory(scope));
1069
+ const durationMs = performance.now() - startedAt;
1070
+ YieldBudgetMemory.record({ runtime: this.runtime, workloadKey, durationMs });
1071
+ const entry = {
1072
+ scope,
1073
+ status: "success",
1074
+ promise: Promise.resolve(value),
1075
+ value,
1076
+ refCount: 0,
1077
+ preloadRefCount: 0,
1078
+ gcTime: gcTime ?? this.gcDelayMs,
1079
+ ownerId,
1080
+ createdBy: "preload",
1081
+ workloadKey,
1082
+ yieldStrategy: "none"
1083
+ };
1084
+ this.scheduleGC(key, entry);
1085
+ this.entries.set(key, entry);
1086
+ return value;
1087
+ } catch (error) {
1088
+ void this.runtime.runPromise(import_effect4.Scope.close(scope, import_effect4.Exit.fail(error))).catch((closeError) => {
1089
+ debugBestEffortFailure("[ModuleCache] Scope.close failed", closeError);
1090
+ });
1091
+ return void 0;
1092
+ }
1093
+ }
1003
1094
  preload(key, factory, options) {
1004
1095
  const existing = this.entries.get(key);
1005
1096
  if (existing) {
@@ -1029,6 +1120,38 @@ var ModuleCache = class {
1029
1120
  const gcTime = options?.gcTime ?? this.gcDelayMs;
1030
1121
  const workloadKey = `${options?.entrypoint ?? "unknown"}::${ownerId ?? "unknown"}`;
1031
1122
  const yieldDecision = decideYieldStrategy(this.runtime, workloadKey, options?.yield);
1123
+ const optimisticSyncBudgetMs = options?.optimisticSyncBudgetMs ?? 0;
1124
+ const shouldTryOptimisticSync = options?.policyMode === "defer" && optimisticSyncBudgetMs > 0;
1125
+ if (shouldTryOptimisticSync) {
1126
+ const startedAt2 = performance.now();
1127
+ try {
1128
+ const value = this.runtime.runSync(factory(scope));
1129
+ const durationMs = performance.now() - startedAt2;
1130
+ YieldBudgetMemory.record({ runtime: this.runtime, workloadKey, durationMs });
1131
+ const entry2 = {
1132
+ scope,
1133
+ status: "success",
1134
+ promise: Promise.resolve(value),
1135
+ value,
1136
+ refCount: 0,
1137
+ preloadRefCount: 1,
1138
+ gcTime,
1139
+ ownerId,
1140
+ createdBy: "preload",
1141
+ workloadKey,
1142
+ yieldStrategy: "none"
1143
+ };
1144
+ this.scheduleGC(key, entry2);
1145
+ this.entries.set(key, entry2);
1146
+ return {
1147
+ promise: Promise.resolve(value),
1148
+ cancel: () => {
1149
+ this.cancelPreload(key, entry2);
1150
+ }
1151
+ };
1152
+ } catch {
1153
+ }
1154
+ }
1032
1155
  const entry = {
1033
1156
  scope,
1034
1157
  status: "pending",
@@ -1044,7 +1167,7 @@ var ModuleCache = class {
1044
1167
  this.scheduleGC(key, entry);
1045
1168
  this.entries.set(key, entry);
1046
1169
  const startedAt = performance.now();
1047
- const buildEffect = yieldEffect(yieldDecision.strategy).pipe(import_effect4.Effect.zipRight(factory(scope)));
1170
+ const buildEffect = yieldEffect(yieldDecision.strategy).pipe(import_effect4.Effect.flatMap(() => factory(scope)));
1048
1171
  const fiber = this.runtime.runFork(buildEffect);
1049
1172
  entry.fiber = fiber;
1050
1173
  const promise = this.runtime.runPromise(import_effect4.Fiber.await(fiber)).then((exit) => {
@@ -1283,6 +1406,9 @@ var RuntimeProvider = ({
1283
1406
  }) => {
1284
1407
  const parent = (0, import_react4.useContext)(RuntimeContext);
1285
1408
  const baseRuntime = useRuntimeResolution(runtime, parent);
1409
+ const providerStartedAtRef = import_react4.default.useRef(performance.now());
1410
+ const providerReadyAtRef = import_react4.default.useRef(void 0);
1411
+ const didReportProviderGatingRef = import_react4.default.useRef(false);
1286
1412
  const resolvedPolicy = (0, import_react4.useMemo)(
1287
1413
  () => resolveRuntimeProviderPolicy({
1288
1414
  policy,
@@ -1322,7 +1448,7 @@ var RuntimeProvider = ({
1322
1448
  moduleId: event.moduleId,
1323
1449
  instanceId: event.instanceId,
1324
1450
  runtimeLabel: event.runtimeLabel
1325
- }).pipe(import_effect5.Effect.catchAllCause(() => import_effect5.Effect.void));
1451
+ }).pipe(import_effect5.Effect.catchCause(() => import_effect5.Effect.void));
1326
1452
  }
1327
1453
  if (event.type === "diagnostic" && event.severity === "error") {
1328
1454
  return handler(
@@ -1341,7 +1467,7 @@ var RuntimeProvider = ({
1341
1467
  instanceId: event.instanceId,
1342
1468
  runtimeLabel: event.runtimeLabel
1343
1469
  }
1344
- ).pipe(import_effect5.Effect.catchAllCause(() => import_effect5.Effect.void));
1470
+ ).pipe(import_effect5.Effect.catchCause(() => import_effect5.Effect.void));
1345
1471
  }
1346
1472
  return import_effect5.Effect.void;
1347
1473
  }
@@ -1356,9 +1482,7 @@ var RuntimeProvider = ({
1356
1482
  return layerBinding.debugSinks;
1357
1483
  }
1358
1484
  try {
1359
- return baseRuntime.runSync(
1360
- import_effect5.FiberRef.get(Logix5.Debug.internal.currentDebugSinks)
1361
- );
1485
+ return baseRuntime.runSync(import_effect5.Effect.service(Logix5.Debug.internal.currentDebugSinks).pipe(import_effect5.Effect.orDie));
1362
1486
  } catch {
1363
1487
  return [];
1364
1488
  }
@@ -1485,6 +1609,41 @@ var RuntimeProvider = ({
1485
1609
  const resolveFallback = (phase) => {
1486
1610
  return resolveRuntimeProviderFallback({ fallback, phase, policyMode: resolvedPolicy.mode });
1487
1611
  };
1612
+ const preloadCache = (0, import_react4.useMemo)(
1613
+ () => getModuleCache(runtimeWithBindings, configState.snapshot, configState.version),
1614
+ [runtimeWithBindings, configState.snapshot, configState.version]
1615
+ );
1616
+ const syncWarmPreloadReady = (0, import_react4.useMemo)(() => {
1617
+ if (resolvedPolicy.mode !== "defer") return false;
1618
+ if (!resolvedPolicy.preload) return true;
1619
+ if (!isLayerReady || !isConfigReady) return false;
1620
+ const handles = resolvedPolicy.preload.handles;
1621
+ if (handles.length === 0) return true;
1622
+ for (const handle of handles) {
1623
+ if (handle?._tag === "ModuleImpl") {
1624
+ const moduleId = handle.module?.id ?? "ModuleImpl";
1625
+ const key2 = resolvedPolicy.preload.keysByModuleId.get(moduleId) ?? getPreloadKeyForModuleId(moduleId);
1626
+ const factory2 = (scope) => import_effect5.Layer.buildWithScope(handle.layer, scope).pipe(
1627
+ import_effect5.Effect.map((context) => import_effect5.ServiceMap.get(context, handle.module))
1628
+ );
1629
+ const value2 = preloadCache.warmSync(key2, factory2, configState.snapshot.gcTime, moduleId, {
1630
+ entrypoint: "react.runtime.preload.sync-warm",
1631
+ policyMode: "defer"
1632
+ });
1633
+ if (!value2) return false;
1634
+ continue;
1635
+ }
1636
+ const tagId = handle.id ?? "ModuleTag";
1637
+ const key = resolvedPolicy.preload.keysByTagId.get(tagId) ?? getPreloadKeyForTagId(tagId);
1638
+ const factory = (scope) => import_effect5.Scope.provide(scope)(import_effect5.Effect.service(handle).pipe(import_effect5.Effect.orDie));
1639
+ const value = preloadCache.warmSync(key, factory, configState.snapshot.gcTime, tagId, {
1640
+ entrypoint: "react.runtime.preload.sync-warm",
1641
+ policyMode: "defer"
1642
+ });
1643
+ if (!value) return false;
1644
+ }
1645
+ return true;
1646
+ }, [resolvedPolicy, isLayerReady, isConfigReady, preloadCache, configState.snapshot.gcTime]);
1488
1647
  const [deferReady, setDeferReady] = (0, import_react4.useState)(false);
1489
1648
  (0, import_react4.useEffect)(() => {
1490
1649
  if (resolvedPolicy.mode !== "defer") {
@@ -1498,6 +1657,10 @@ var RuntimeProvider = ({
1498
1657
  if (resolvedPolicy.mode !== "defer") {
1499
1658
  return;
1500
1659
  }
1660
+ if (syncWarmPreloadReady) {
1661
+ setDeferReady(true);
1662
+ return;
1663
+ }
1501
1664
  setDeferReady(false);
1502
1665
  if (!resolvedPolicy.preload) {
1503
1666
  setDeferReady(true);
@@ -1507,7 +1670,7 @@ var RuntimeProvider = ({
1507
1670
  return;
1508
1671
  }
1509
1672
  let cancelled = false;
1510
- const cache = getModuleCache(runtimeWithBindings, configState.snapshot, configState.version);
1673
+ const cache = preloadCache;
1511
1674
  const preloadHandles = resolvedPolicy.preload.handles;
1512
1675
  if (preloadHandles.length === 0) {
1513
1676
  setDeferReady(true);
@@ -1525,13 +1688,14 @@ var RuntimeProvider = ({
1525
1688
  const moduleId = handle.module?.id ?? "ModuleImpl";
1526
1689
  const key2 = resolvedPolicy.preload.keysByModuleId.get(moduleId) ?? getPreloadKeyForModuleId(moduleId);
1527
1690
  const factory2 = (scope) => import_effect5.Layer.buildWithScope(handle.layer, scope).pipe(
1528
- import_effect5.Effect.map((context) => import_effect5.Context.get(context, handle.module))
1691
+ import_effect5.Effect.map((context) => import_effect5.ServiceMap.get(context, handle.module))
1529
1692
  );
1530
1693
  const op2 = cache.preload(key2, factory2, {
1531
1694
  ownerId: moduleId,
1532
1695
  yield: resolvedPolicy.preload.yield,
1533
1696
  entrypoint: "react.runtime.preload",
1534
- policyMode: "defer"
1697
+ policyMode: "defer",
1698
+ optimisticSyncBudgetMs: resolvedPolicy.syncBudgetMs
1535
1699
  });
1536
1700
  allCancels.add(op2.cancel);
1537
1701
  await op2.promise;
@@ -1556,14 +1720,13 @@ var RuntimeProvider = ({
1556
1720
  }
1557
1721
  const tagId = handle.id ?? "ModuleTag";
1558
1722
  const key = resolvedPolicy.preload.keysByTagId.get(tagId) ?? getPreloadKeyForTagId(tagId);
1559
- const factory = (scope) => handle.pipe(
1560
- import_effect5.Scope.extend(scope)
1561
- );
1723
+ const factory = (scope) => import_effect5.Scope.provide(scope)(import_effect5.Effect.service(handle).pipe(import_effect5.Effect.orDie));
1562
1724
  const op = cache.preload(key, factory, {
1563
1725
  ownerId: tagId,
1564
1726
  yield: resolvedPolicy.preload.yield,
1565
1727
  entrypoint: "react.runtime.preload",
1566
- policyMode: "defer"
1728
+ policyMode: "defer",
1729
+ optimisticSyncBudgetMs: resolvedPolicy.syncBudgetMs
1567
1730
  });
1568
1731
  allCancels.add(op.cancel);
1569
1732
  await op.promise;
@@ -1601,7 +1764,7 @@ var RuntimeProvider = ({
1601
1764
  if (cancelled) return;
1602
1765
  if (onErrorRef.current) {
1603
1766
  runtimeWithBindings.runFork(
1604
- onErrorRef.current(import_effect5.Cause.die(error), { source: "provider", phase: "provider.layer.build" }).pipe(import_effect5.Effect.catchAllCause(() => import_effect5.Effect.void))
1767
+ onErrorRef.current(import_effect5.Cause.die(error), { source: "provider", phase: "provider.layer.build" }).pipe(import_effect5.Effect.catchCause(() => import_effect5.Effect.void))
1605
1768
  );
1606
1769
  }
1607
1770
  setDeferReady(true);
@@ -1634,13 +1797,54 @@ var RuntimeProvider = ({
1634
1797
  release();
1635
1798
  };
1636
1799
  }, [resolvedPolicy.mode, deferReady]);
1637
- const isReady = isTickServicesReady && isLayerReady && isConfigReady && (resolvedPolicy.mode !== "defer" || deferReady);
1800
+ const isReady = isTickServicesReady && isLayerReady && isConfigReady && (resolvedPolicy.mode !== "defer" || deferReady || syncWarmPreloadReady);
1801
+ if (isReady && providerReadyAtRef.current === void 0) {
1802
+ providerReadyAtRef.current = performance.now();
1803
+ }
1804
+ (0, import_react4.useEffect)(() => {
1805
+ if (!isReady) {
1806
+ return;
1807
+ }
1808
+ if (didReportProviderGatingRef.current) {
1809
+ return;
1810
+ }
1811
+ let diagnosticsLevel = "off";
1812
+ try {
1813
+ diagnosticsLevel = runtimeWithBindings.runSync(
1814
+ import_effect5.Effect.service(Logix5.Debug.internal.currentDiagnosticsLevel).pipe(import_effect5.Effect.orDie)
1815
+ );
1816
+ } catch {
1817
+ diagnosticsLevel = (0, import_Env.isDevEnv)() ? "light" : "off";
1818
+ }
1819
+ if (diagnosticsLevel === "off") {
1820
+ return;
1821
+ }
1822
+ didReportProviderGatingRef.current = true;
1823
+ const readyAt = providerReadyAtRef.current ?? performance.now();
1824
+ const durationMs = Math.round((readyAt - providerStartedAtRef.current) * 100) / 100;
1825
+ const effectDelayMs = Math.round((performance.now() - readyAt) * 100) / 100;
1826
+ void runtimeWithBindings.runPromise(
1827
+ Logix5.Debug.record({
1828
+ type: "trace:react.provider.gating",
1829
+ data: {
1830
+ event: "ready",
1831
+ policyMode: resolvedPolicy.mode,
1832
+ durationMs,
1833
+ effectDelayMs,
1834
+ configLoadMode: configState.loadMode,
1835
+ syncOverBudget: Boolean(configState.syncOverBudget),
1836
+ syncDurationMs: configState.syncDurationMs !== void 0 ? Math.round(configState.syncDurationMs * 100) / 100 : void 0
1837
+ }
1838
+ })
1839
+ ).catch(() => {
1840
+ });
1841
+ }, [configState.loadMode, configState.syncDurationMs, configState.syncOverBudget, isReady, resolvedPolicy.mode, runtimeWithBindings]);
1638
1842
  if (!isReady) {
1639
1843
  const blockersList = [
1640
1844
  isTickServicesReady ? null : "tick",
1641
1845
  isLayerReady ? null : "layer",
1642
1846
  isConfigReady ? null : "config",
1643
- resolvedPolicy.mode !== "defer" || deferReady ? null : "preload"
1847
+ resolvedPolicy.mode !== "defer" || deferReady || syncWarmPreloadReady ? null : "preload"
1644
1848
  ].filter((x) => x !== null);
1645
1849
  const blockers = blockersList.length > 0 ? blockersList.join("+") : void 0;
1646
1850
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -1753,13 +1957,13 @@ function useRuntime(options) {
1753
1957
 
1754
1958
  // src/internal/hooks/useModule.ts
1755
1959
  var import_react9 = __toESM(require("react"), 1);
1756
- var Logix10 = __toESM(require("@logixjs/core"), 1);
1757
- var import_effect9 = require("effect");
1960
+ var Logix11 = __toESM(require("@logixjs/core"), 1);
1961
+ var import_effect10 = require("effect");
1758
1962
 
1759
1963
  // src/internal/hooks/useModuleRuntime.ts
1760
1964
  var import_react6 = require("react");
1761
- var Logix6 = __toESM(require("@logixjs/core"), 1);
1762
- var import_effect7 = require("effect");
1965
+ var Logix7 = __toESM(require("@logixjs/core"), 1);
1966
+ var import_effect8 = require("effect");
1763
1967
 
1764
1968
  // src/internal/store/ModuleRef.ts
1765
1969
  var isModuleRef = (value) => typeof value === "object" && value !== null && "runtime" in value && "actions" in value && "dispatch" in value;
@@ -1850,11 +2054,26 @@ var applyHandleExtend = (tag, runtime, base) => {
1850
2054
  return { ...base, ...next };
1851
2055
  };
1852
2056
 
2057
+ // src/internal/provider/runtimeDebugBridge.ts
2058
+ var import_effect7 = require("effect");
2059
+ var Logix6 = __toESM(require("@logixjs/core"), 1);
2060
+ var readRuntimeDiagnosticsLevel = (runtime) => {
2061
+ try {
2062
+ return runtime.runSync(import_effect7.Effect.service(Logix6.Debug.internal.currentDiagnosticsLevel).pipe(import_effect7.Effect.orDie));
2063
+ } catch {
2064
+ return (0, import_Env.isDevEnv)() ? "light" : "off";
2065
+ }
2066
+ };
2067
+ var emitRuntimeDebugEventBestEffort = (runtime, event) => {
2068
+ runtime.runFork(event);
2069
+ };
2070
+
1853
2071
  // src/internal/hooks/useModuleRuntime.ts
1854
2072
  var isModuleRuntime = (value) => typeof value === "object" && value !== null && "dispatch" in value && "getState" in value;
1855
2073
  function useModuleRuntime(handle) {
1856
2074
  const runtime = useRuntime();
1857
2075
  const runtimeContext = (0, import_react6.useContext)(RuntimeContext);
2076
+ const moduleTagResolveTraceRef = (0, import_react6.useRef)(void 0);
1858
2077
  if (!runtimeContext) {
1859
2078
  throw new RuntimeProviderNotFoundError("useModuleRuntime");
1860
2079
  }
@@ -1875,36 +2094,48 @@ function useModuleRuntime(handle) {
1875
2094
  const preloadKey = runtimeContext.policy.preload?.keysByTagId.get(tokenId);
1876
2095
  const key = preloadKey ?? `tag:${tokenId}`;
1877
2096
  const mode = runtimeContext.policy.moduleTagMode;
1878
- const factory = (scope) => tag.pipe(import_effect7.Scope.extend(scope));
1879
- return mode === "suspend" ? cache.read(key, factory, void 0, tokenId, {
2097
+ const startedAtMs = performance.now();
2098
+ const factory = (scope) => import_effect8.Scope.provide(scope)(import_effect8.Effect.service(tag).pipe(import_effect8.Effect.orDie));
2099
+ const resolvedRuntime = mode === "suspend" ? cache.read(key, factory, void 0, tokenId, {
1880
2100
  entrypoint: "react.useModuleRuntime",
1881
2101
  policyMode: runtimeContext.policy.mode,
1882
- yield: runtimeContext.policy.yield
2102
+ yield: runtimeContext.policy.yield,
2103
+ optimisticSyncBudgetMs: runtimeContext.policy.syncBudgetMs
1883
2104
  }) : cache.readSync(key, factory, void 0, tokenId, {
1884
2105
  entrypoint: "react.useModuleRuntime",
1885
2106
  policyMode: runtimeContext.policy.mode,
1886
2107
  warnSyncBlockingThresholdMs: 5
1887
2108
  });
2109
+ moduleTagResolveTraceRef.current = {
2110
+ tokenId,
2111
+ durationMs: Math.round((performance.now() - startedAtMs) * 100) / 100,
2112
+ cacheMode: mode
2113
+ };
2114
+ return resolvedRuntime;
1888
2115
  }, [cache, runtimeContext.policy, handle]);
1889
2116
  (0, import_react6.useEffect)(() => {
1890
2117
  if (!isTagHandle) {
1891
2118
  return;
1892
2119
  }
1893
- if (!(0, import_Env.isDevEnv)() && !Logix6.Debug.isDevtoolsEnabled()) {
2120
+ const diagnosticsLevel = readRuntimeDiagnosticsLevel(runtime);
2121
+ if (diagnosticsLevel === "off") {
1894
2122
  return;
1895
2123
  }
1896
2124
  const tokenId = handle?.id ?? "ModuleTag";
1897
- const effect = Logix6.Debug.record({
2125
+ const trace = moduleTagResolveTraceRef.current;
2126
+ const effect = Logix7.Debug.record({
1898
2127
  type: "trace:react.moduleTag.resolve",
1899
2128
  moduleId: resolved.moduleId,
1900
2129
  instanceId: resolved.instanceId,
1901
2130
  data: {
1902
2131
  mode: runtimeContext.policy.moduleTagMode,
1903
2132
  tokenId,
1904
- yieldStrategy: runtimeContext.policy.yield.strategy
2133
+ yieldStrategy: runtimeContext.policy.yield.strategy,
2134
+ durationMs: trace?.durationMs,
2135
+ cacheMode: trace?.cacheMode ?? runtimeContext.policy.moduleTagMode
1905
2136
  }
1906
2137
  });
1907
- runtime.runFork(effect);
2138
+ emitRuntimeDebugEventBestEffort(runtime, effect);
1908
2139
  }, [runtime, runtimeContext.policy, resolved, handle, isTagHandle]);
1909
2140
  return resolved;
1910
2141
  }
@@ -1912,11 +2143,11 @@ function useModuleRuntime(handle) {
1912
2143
  // src/internal/hooks/useSelector.ts
1913
2144
  var import_react7 = require("react");
1914
2145
  var import_with_selector = require("use-sync-external-store/shim/with-selector");
1915
- var Logix8 = __toESM(require("@logixjs/core"), 1);
2146
+ var Logix9 = __toESM(require("@logixjs/core"), 1);
1916
2147
 
1917
2148
  // src/internal/store/RuntimeExternalStore.ts
1918
- var Logix7 = __toESM(require("@logixjs/core"), 1);
1919
- var import_effect8 = require("effect");
2149
+ var Logix8 = __toESM(require("@logixjs/core"), 1);
2150
+ var import_effect9 = require("effect");
1920
2151
  var storesByRuntime = /* @__PURE__ */ new WeakMap();
1921
2152
  var getStoreMapForRuntime = (runtime) => {
1922
2153
  const cached = storesByRuntime.get(runtime);
@@ -1927,8 +2158,8 @@ var getStoreMapForRuntime = (runtime) => {
1927
2158
  };
1928
2159
  var makeModuleInstanceKey = (moduleId, instanceId) => `${moduleId}::${instanceId}`;
1929
2160
  var makeReadQueryTopicKey = (moduleInstanceKey, selectorId) => `${moduleInstanceKey}::rq:${selectorId}`;
1930
- var getRuntimeStore = (runtime) => Logix7.InternalContracts.getRuntimeStore(runtime);
1931
- var getHostScheduler = (runtime) => Logix7.InternalContracts.getHostScheduler(runtime);
2161
+ var getRuntimeStore = (runtime) => Logix8.InternalContracts.getRuntimeStore(runtime);
2162
+ var getHostScheduler = (runtime) => Logix8.InternalContracts.getHostScheduler(runtime);
1932
2163
  var getOrCreateStore = (runtime, topicKey, make) => {
1933
2164
  const map = getStoreMapForRuntime(runtime);
1934
2165
  const cached = map.get(topicKey);
@@ -1952,6 +2183,8 @@ var makeTopicExternalStore = (args) => {
1952
2183
  let currentSnapshot;
1953
2184
  const listeners = /* @__PURE__ */ new Set();
1954
2185
  let unsubscribeFromRuntimeStore;
2186
+ let teardownScheduled = false;
2187
+ let teardownToken = 0;
1955
2188
  const lowPriorityDelayMs = args.options?.lowPriorityDelayMs ?? 16;
1956
2189
  const lowPriorityMaxDelayMs = args.options?.lowPriorityMaxDelayMs ?? 50;
1957
2190
  let notifyScheduled = false;
@@ -2036,7 +2269,38 @@ var makeTopicExternalStore = (args) => {
2036
2269
  currentSnapshot = next;
2037
2270
  return next;
2038
2271
  };
2272
+ const cancelScheduledTeardown = () => {
2273
+ if (!teardownScheduled) return;
2274
+ teardownScheduled = false;
2275
+ teardownToken += 1;
2276
+ };
2277
+ const finalizeTeardown = () => {
2278
+ if (listeners.size > 0) return;
2279
+ try {
2280
+ args.onLastListener?.();
2281
+ } catch {
2282
+ }
2283
+ const unsub = unsubscribeFromRuntimeStore;
2284
+ unsubscribeFromRuntimeStore = void 0;
2285
+ cancelLow();
2286
+ try {
2287
+ unsub?.();
2288
+ } catch {
2289
+ }
2290
+ removeStore(runtime, topicKey);
2291
+ };
2292
+ const scheduleTeardown = () => {
2293
+ if (teardownScheduled) return;
2294
+ teardownScheduled = true;
2295
+ const token = ++teardownToken;
2296
+ hostScheduler.scheduleMicrotask(() => {
2297
+ if (!teardownScheduled || token !== teardownToken) return;
2298
+ teardownScheduled = false;
2299
+ finalizeTeardown();
2300
+ });
2301
+ };
2039
2302
  const subscribe = (listener) => {
2303
+ cancelScheduledTeardown();
2040
2304
  const isFirst = listeners.size === 0;
2041
2305
  listeners.add(listener);
2042
2306
  ensureSubscription();
@@ -2050,18 +2314,7 @@ var makeTopicExternalStore = (args) => {
2050
2314
  return () => {
2051
2315
  listeners.delete(listener);
2052
2316
  if (listeners.size > 0) return;
2053
- try {
2054
- args.onLastListener?.();
2055
- } catch {
2056
- }
2057
- const unsub = unsubscribeFromRuntimeStore;
2058
- unsubscribeFromRuntimeStore = void 0;
2059
- cancelLow();
2060
- try {
2061
- unsub?.();
2062
- } catch {
2063
- }
2064
- removeStore(runtime, topicKey);
2317
+ scheduleTeardown();
2065
2318
  };
2066
2319
  };
2067
2320
  return { getSnapshot, getServerSnapshot: getSnapshot, subscribe };
@@ -2105,14 +2358,14 @@ var getRuntimeReadQueryExternalStore = (runtime, moduleRuntime, selectorReadQuer
2105
2358
  options,
2106
2359
  onFirstListener: () => {
2107
2360
  if (readQueryDrainFiber) return;
2108
- const effect = import_effect8.Stream.runDrain(moduleRuntime.changesReadQueryWithMeta(selectorReadQuery));
2361
+ const effect = import_effect9.Stream.runDrain(moduleRuntime.changesReadQueryWithMeta(selectorReadQuery));
2109
2362
  readQueryDrainFiber = runtime.runFork(effect);
2110
2363
  },
2111
2364
  onLastListener: () => {
2112
2365
  const fiber = readQueryDrainFiber;
2113
2366
  if (!fiber) return;
2114
2367
  readQueryDrainFiber = void 0;
2115
- runtime.runFork(import_effect8.Fiber.interrupt(fiber));
2368
+ runtime.runFork(import_effect9.Fiber.interrupt(fiber));
2116
2369
  }
2117
2370
  })
2118
2371
  );
@@ -2178,7 +2431,7 @@ function useSelector(handle, selector, equalityFn) {
2178
2431
  const moduleRuntime = useModuleRuntime(handle);
2179
2432
  const actualSelector = selector ?? ((state) => state);
2180
2433
  const selectorReadQuery = (0, import_react7.useMemo)(
2181
- () => typeof selector === "function" ? Logix8.ReadQuery.compile(selector) : void 0,
2434
+ () => typeof selector === "function" ? Logix9.ReadQuery.compile(selector) : void 0,
2182
2435
  [selector]
2183
2436
  );
2184
2437
  const actualEqualityFn = (0, import_react7.useMemo)(() => {
@@ -2216,7 +2469,7 @@ function useSelector(handle, selector, equalityFn) {
2216
2469
  actualEqualityFn
2217
2470
  );
2218
2471
  (0, import_react7.useEffect)(() => {
2219
- if (!(0, import_Env.isDevEnv)() && !Logix8.Debug.isDevtoolsEnabled()) {
2472
+ if (!(0, import_Env.isDevEnv)() && !Logix9.Debug.isDevtoolsEnabled()) {
2220
2473
  return;
2221
2474
  }
2222
2475
  const instanceId = moduleRuntime.instanceId;
@@ -2232,7 +2485,7 @@ function useSelector(handle, selector, equalityFn) {
2232
2485
  const rawDebugKey = meta.debugKey;
2233
2486
  selectorKey = typeof rawDebugKey === "string" && rawDebugKey.length > 0 ? rawDebugKey : typeof selector.name === "string" && selector.name.length > 0 ? selector.name : void 0;
2234
2487
  }
2235
- const effect = Logix8.Debug.record({
2488
+ const effect = Logix9.Debug.record({
2236
2489
  type: "trace:react-selector",
2237
2490
  moduleId: moduleRuntime.moduleId,
2238
2491
  instanceId,
@@ -2255,7 +2508,7 @@ function useSelector(handle, selector, equalityFn) {
2255
2508
  }
2256
2509
 
2257
2510
  // src/internal/store/resolveImportedModuleRef.ts
2258
- var Logix9 = __toESM(require("@logixjs/core"), 1);
2511
+ var Logix10 = __toESM(require("@logixjs/core"), 1);
2259
2512
  var getOrCreateWeakMap = (map, key, make) => {
2260
2513
  const cached = map.get(key);
2261
2514
  if (cached) return cached;
@@ -2279,7 +2532,7 @@ var resolveImportedModuleRef = (runtime, parentRuntime, module2) => {
2279
2532
  if (cached) {
2280
2533
  return cached;
2281
2534
  }
2282
- const importsScope = Logix9.InternalContracts.getImportsScope(parentRuntime);
2535
+ const importsScope = Logix10.InternalContracts.getImportsScope(parentRuntime);
2283
2536
  const childRuntime = importsScope.get(module2);
2284
2537
  if (childRuntime) {
2285
2538
  const dispatch = Object.assign(
@@ -2365,8 +2618,8 @@ var useStableId = () => {
2365
2618
 
2366
2619
  // src/internal/hooks/useModule.ts
2367
2620
  var isModuleImpl2 = (handle) => Boolean(handle) && typeof handle === "object" && handle._tag === "ModuleImpl";
2368
- var isModule = (handle) => Logix10.Module.hasImpl(handle);
2369
- var isModuleDef = (handle) => Logix10.Module.is(handle) && handle._kind === "ModuleDef";
2621
+ var isModule = (handle) => Logix11.Module.hasImpl(handle);
2622
+ var isModuleDef = (handle) => Logix11.Module.is(handle) && handle._kind === "ModuleDef";
2370
2623
  function useModule(handle, selectorOrOptions, equalityFn) {
2371
2624
  const runtimeBase = useRuntime();
2372
2625
  const runtimeContext = import_react9.default.useContext(RuntimeContext);
@@ -2390,6 +2643,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2390
2643
  }
2391
2644
  }
2392
2645
  let runtime;
2646
+ const moduleImplResolveTraceRef = import_react9.default.useRef(void 0);
2393
2647
  if (isModuleImpl2(normalizedHandle)) {
2394
2648
  const cache = import_react9.default.useMemo(
2395
2649
  () => getModuleCache(runtimeBase, runtimeContext.reactConfigSnapshot, runtimeContext.configVersion),
@@ -2418,9 +2672,9 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2418
2672
  const key = depsHash ? `${baseKey}:${depsHash}` : baseKey;
2419
2673
  const ownerId = moduleId;
2420
2674
  const baseFactory = import_react9.default.useMemo(
2421
- () => (scope) => import_effect9.Layer.buildWithScope(normalizedHandle.layer, scope).pipe(
2422
- import_effect9.Effect.map(
2423
- (context) => import_effect9.Context.get(context, normalizedHandle.module)
2675
+ () => (scope) => import_effect10.Layer.buildWithScope(import_effect10.Layer.fresh(normalizedHandle.layer), scope).pipe(
2676
+ import_effect10.Effect.map(
2677
+ (context) => import_effect10.ServiceMap.get(context, normalizedHandle.module)
2424
2678
  )
2425
2679
  ),
2426
2680
  [normalizedHandle]
@@ -2430,26 +2684,56 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2430
2684
  return baseFactory;
2431
2685
  }
2432
2686
  return (scope) => baseFactory(scope).pipe(
2433
- import_effect9.Effect.timeoutFail({
2434
- duration: initTimeoutMs,
2435
- onTimeout: () => new Error(`[useModule] Module "${ownerId}" initialization timed out after ${initTimeoutMs}ms`)
2436
- })
2687
+ import_effect10.Effect.timeoutOption(initTimeoutMs),
2688
+ import_effect10.Effect.flatMap(
2689
+ (maybe) => maybe._tag === "Some" ? import_effect10.Effect.succeed(maybe.value) : import_effect10.Effect.die(new Error(`[useModule] Module "${ownerId}" initialization timed out after ${initTimeoutMs}ms`))
2690
+ )
2437
2691
  );
2438
2692
  }, [baseFactory, suspend, initTimeoutMs, ownerId]);
2693
+ const moduleResolveStartedAt = performance.now();
2439
2694
  const moduleRuntime = suspend ? cache.read(key, factory, gcTime, ownerId, {
2440
2695
  entrypoint: "react.useModule",
2441
2696
  policyMode: runtimeContext.policy.mode,
2442
- yield: runtimeContext.policy.yield
2697
+ yield: runtimeContext.policy.yield,
2698
+ optimisticSyncBudgetMs: runtimeContext.policy.syncBudgetMs
2443
2699
  }) : cache.readSync(key, factory, gcTime, ownerId, {
2444
2700
  entrypoint: "react.useModule",
2445
2701
  policyMode: runtimeContext.policy.mode,
2446
2702
  warnSyncBlockingThresholdMs: 5
2447
2703
  });
2704
+ moduleImplResolveTraceRef.current = {
2705
+ moduleId,
2706
+ cacheMode: suspend ? "suspend" : "sync",
2707
+ durationMs: Math.round((performance.now() - moduleResolveStartedAt) * 100) / 100
2708
+ };
2448
2709
  import_react9.default.useEffect(() => cache.retain(key), [cache, key]);
2449
2710
  runtime = moduleRuntime;
2450
2711
  } else {
2451
2712
  runtime = useModuleRuntime(normalizedHandle);
2452
2713
  }
2714
+ import_react9.default.useEffect(() => {
2715
+ if (!isModuleImpl2(normalizedHandle)) {
2716
+ return;
2717
+ }
2718
+ const diagnosticsLevel = readRuntimeDiagnosticsLevel(runtimeBase);
2719
+ if (diagnosticsLevel === "off") {
2720
+ return;
2721
+ }
2722
+ const trace = moduleImplResolveTraceRef.current;
2723
+ if (!trace) {
2724
+ return;
2725
+ }
2726
+ const effect = Logix11.Debug.record({
2727
+ type: "trace:react.moduleImpl.resolve",
2728
+ moduleId: trace.moduleId,
2729
+ instanceId: runtime.instanceId,
2730
+ data: {
2731
+ cacheMode: trace.cacheMode,
2732
+ durationMs: trace.durationMs
2733
+ }
2734
+ });
2735
+ emitRuntimeDebugEventBestEffort(runtimeBase, effect);
2736
+ }, [runtimeBase, runtime, normalizedHandle]);
2453
2737
  import_react9.default.useEffect(() => {
2454
2738
  if (!isModuleImpl2(normalizedHandle)) {
2455
2739
  return;
@@ -2459,22 +2743,22 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2459
2743
  if (!label) {
2460
2744
  return;
2461
2745
  }
2462
- const effect = Logix10.Debug.record({
2746
+ const effect = Logix11.Debug.record({
2463
2747
  type: "trace:instanceLabel",
2464
2748
  moduleId: normalizedHandle.module.id,
2465
2749
  instanceId: runtime.instanceId,
2466
2750
  data: { label }
2467
2751
  });
2468
- runtimeBase.runFork(effect);
2752
+ emitRuntimeDebugEventBestEffort(runtimeBase, effect);
2469
2753
  }, [runtimeBase, runtime, normalizedHandle, options]);
2470
2754
  import_react9.default.useEffect(() => {
2471
- if (!(0, import_Env.isDevEnv)() && !Logix10.Debug.isDevtoolsEnabled()) {
2755
+ if (!(0, import_Env.isDevEnv)() && !Logix11.Debug.isDevtoolsEnabled()) {
2472
2756
  return;
2473
2757
  }
2474
2758
  if (!runtime.instanceId) {
2475
2759
  return;
2476
2760
  }
2477
- const effect = Logix10.Debug.record({
2761
+ const effect = Logix11.Debug.record({
2478
2762
  type: "trace:react-render",
2479
2763
  moduleId: runtime.moduleId,
2480
2764
  instanceId: runtime.instanceId,
@@ -2484,7 +2768,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2484
2768
  }
2485
2769
  });
2486
2770
  runtimeBase.runFork(effect);
2487
- }, [runtimeBase, runtime]);
2771
+ });
2488
2772
  if (selector) {
2489
2773
  if (isModuleImpl2(normalizedHandle)) {
2490
2774
  return useSelector(runtime, selector, equalityFn);
@@ -2571,8 +2855,8 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2571
2855
 
2572
2856
  // src/internal/hooks/useLocalModule.ts
2573
2857
  var import_react10 = __toESM(require("react"), 1);
2574
- var Logix11 = __toESM(require("@logixjs/core"), 1);
2575
- var import_effect10 = require("effect");
2858
+ var Logix12 = __toESM(require("@logixjs/core"), 1);
2859
+ var import_effect11 = require("effect");
2576
2860
  function isModuleTag2(source) {
2577
2861
  if (!source || typeof source !== "object" && typeof source !== "function") {
2578
2862
  return false;
@@ -2592,7 +2876,7 @@ function useLocalModule(source, second) {
2592
2876
  );
2593
2877
  const componentId = useStableId();
2594
2878
  const moduleTag = import_react10.default.useMemo(() => {
2595
- if (Logix11.Module.is(source)) {
2879
+ if (Logix12.Module.is(source)) {
2596
2880
  return source.tag;
2597
2881
  }
2598
2882
  if (isModuleTag2(source)) {
@@ -2601,7 +2885,7 @@ function useLocalModule(source, second) {
2601
2885
  return null;
2602
2886
  }, [source]);
2603
2887
  const def = import_react10.default.useMemo(() => {
2604
- if (Logix11.Module.is(source) || isModuleTag2(source)) {
2888
+ if (Logix12.Module.is(source) || isModuleTag2(source)) {
2605
2889
  return source;
2606
2890
  }
2607
2891
  return void 0;
@@ -2629,7 +2913,7 @@ function useLocalModule(source, second) {
2629
2913
  return createModuleTagFactory(moduleTag, moduleOptions);
2630
2914
  }
2631
2915
  const factoryFn = source;
2632
- return (scope) => factoryFn().pipe(import_effect10.Scope.extend(scope));
2916
+ return (scope) => import_effect11.Scope.provide(scope)(factoryFn());
2633
2917
  }, [isModule2, moduleTag, source, moduleOptions]);
2634
2918
  const moduleRuntime = cache.readSync(key, factory, void 0, ownerId, {
2635
2919
  entrypoint: "react.useLocalModule",
@@ -2689,9 +2973,9 @@ function createModuleTagFactory(module2, options) {
2689
2973
  throw new Error("useLocalModule(module, options) \u9700\u8981\u63D0\u4F9B initial \u72B6\u6001");
2690
2974
  }
2691
2975
  const logics = options.logics ?? [];
2692
- return (scope) => import_effect10.Layer.buildWithScope(module2.live(options.initial, ...logics), scope).pipe(
2693
- import_effect10.Effect.map((context) => {
2694
- const runtime = import_effect10.Context.get(context, module2);
2976
+ return (scope) => import_effect11.Layer.buildWithScope(module2.live(options.initial, ...logics), scope).pipe(
2977
+ import_effect11.Effect.map((context) => {
2978
+ const runtime = import_effect11.ServiceMap.get(context, module2);
2695
2979
  return runtime;
2696
2980
  })
2697
2981
  );
@@ -2699,12 +2983,12 @@ function createModuleTagFactory(module2, options) {
2699
2983
 
2700
2984
  // src/internal/hooks/useLayerModule.ts
2701
2985
  var import_react11 = __toESM(require("react"), 1);
2702
- var import_effect11 = require("effect");
2986
+ var import_effect12 = require("effect");
2703
2987
  function useLayerModule(module2, layer, deps = []) {
2704
2988
  const factory = import_react11.default.useCallback(
2705
- () => import_effect11.Layer.build(layer).pipe(
2706
- import_effect11.Effect.scoped,
2707
- import_effect11.Effect.map((context) => import_effect11.Context.get(context, module2))
2989
+ () => import_effect12.Layer.build(layer).pipe(
2990
+ import_effect12.Effect.scoped,
2991
+ import_effect12.Effect.map((context) => import_effect12.ServiceMap.get(context, module2))
2708
2992
  ),
2709
2993
  // layer/module are typically constants; deps lets callers opt into rebuilding when needed.
2710
2994
  [layer, module2]
@@ -2761,8 +3045,8 @@ function useImportedModule(parent, module2) {
2761
3045
 
2762
3046
  // src/internal/hooks/useProcesses.ts
2763
3047
  var import_react15 = __toESM(require("react"), 1);
2764
- var import_effect12 = require("effect");
2765
- var Logix12 = __toESM(require("@logixjs/core"), 1);
3048
+ var import_effect13 = require("effect");
3049
+ var Logix13 = __toESM(require("@logixjs/core"), 1);
2766
3050
  var ProcessSubtreeRegistry = class {
2767
3051
  constructor(runtime) {
2768
3052
  this.runtime = runtime;
@@ -2783,7 +3067,7 @@ var ProcessSubtreeRegistry = class {
2783
3067
  }
2784
3068
  return () => this.release({ key: args.key, gcTime: args.gcTime });
2785
3069
  }
2786
- const scope = import_effect12.Effect.runSync(import_effect12.Scope.make());
3070
+ const scope = import_effect13.Effect.runSync(import_effect13.Scope.make());
2787
3071
  const entry = {
2788
3072
  key: args.key,
2789
3073
  signature: args.signature,
@@ -2811,7 +3095,7 @@ var ProcessSubtreeRegistry = class {
2811
3095
  const current = this.entries.get(entry.key);
2812
3096
  if (!current || current !== entry) return;
2813
3097
  if (current.refCount > 0) return;
2814
- void this.runtime.runPromise(import_effect12.Scope.close(entry.scope, import_effect12.Exit.void)).catch(() => {
3098
+ void this.runtime.runPromise(import_effect13.Scope.close(entry.scope, import_effect13.Exit.void)).catch(() => {
2815
3099
  });
2816
3100
  this.entries.delete(entry.key);
2817
3101
  }, timeoutMs);
@@ -2828,7 +3112,7 @@ var getRegistry = (runtime) => {
2828
3112
  var stableProcessSignature = (processes) => {
2829
3113
  const ids = [];
2830
3114
  for (let i = 0; i < processes.length; i++) {
2831
- const def = Logix12.Process.getDefinition(processes[i]);
3115
+ const def = Logix13.Process.getDefinition(processes[i]);
2832
3116
  ids.push(def?.processId ?? `legacy#${i}`);
2833
3117
  }
2834
3118
  return ids.join("|");
@@ -2871,24 +3155,24 @@ function useProcesses(processes, options) {
2871
3155
  signature,
2872
3156
  gcTime,
2873
3157
  install: (scope) => {
2874
- const program = import_effect12.Effect.forEach(
3158
+ const program = import_effect13.Effect.forEach(
2875
3159
  processes,
2876
- (process) => Logix12.InternalContracts.installProcess(process, {
3160
+ (process) => Logix13.InternalContracts.installProcess(process, {
2877
3161
  scope: { type: "uiSubtree", subtreeId },
2878
3162
  enabled: true,
2879
3163
  installedAt: "uiSubtree",
2880
3164
  mode
2881
3165
  }).pipe(
2882
- import_effect12.Effect.flatMap((installation) => {
3166
+ import_effect13.Effect.flatMap((installation) => {
2883
3167
  if (installation !== void 0) {
2884
- return import_effect12.Effect.void;
3168
+ return import_effect13.Effect.void;
2885
3169
  }
2886
- return import_effect12.Effect.forkScoped(process).pipe(import_effect12.Effect.asVoid);
3170
+ return import_effect13.Effect.forkScoped(process).pipe(import_effect13.Effect.asVoid);
2887
3171
  }),
2888
- import_effect12.Effect.catchAll(() => import_effect12.Effect.forkScoped(process).pipe(import_effect12.Effect.asVoid))
3172
+ import_effect13.Effect.catch(() => import_effect13.Effect.forkScoped(process).pipe(import_effect13.Effect.asVoid))
2889
3173
  ),
2890
3174
  { discard: true }
2891
- ).pipe(import_effect12.Effect.provideService(import_effect12.Scope.Scope, scope));
3175
+ ).pipe(import_effect13.Effect.provideService(import_effect13.Scope.Scope, scope));
2892
3176
  void runtime.runPromise(program).catch(() => {
2893
3177
  });
2894
3178
  }
@@ -2897,7 +3181,7 @@ function useProcesses(processes, options) {
2897
3181
  }
2898
3182
 
2899
3183
  // src/internal/platform/ReactPlatformLayer.ts
2900
- var import_effect13 = require("effect");
3184
+ var import_effect14 = require("effect");
2901
3185
  var import_core = require("@logixjs/core");
2902
3186
  var ReactPlatformImpl = class {
2903
3187
  constructor(suspendRef, resumeRef, resetRef) {
@@ -2905,27 +3189,24 @@ var ReactPlatformImpl = class {
2905
3189
  this.resumeRef = resumeRef;
2906
3190
  this.resetRef = resetRef;
2907
3191
  this.lifecycle = {
2908
- onSuspend: (eff) => import_effect13.Ref.update(this.suspendRef, (list) => [...list, eff]).pipe(import_effect13.Effect.asVoid),
2909
- onResume: (eff) => import_effect13.Ref.update(this.resumeRef, (list) => [...list, eff]).pipe(import_effect13.Effect.asVoid),
2910
- onReset: (eff) => import_effect13.Ref.update(this.resetRef, (list) => [...list, eff]).pipe(import_effect13.Effect.asVoid)
3192
+ onSuspend: (eff) => import_effect14.Ref.update(this.suspendRef, (list) => [...list, eff]).pipe(import_effect14.Effect.asVoid),
3193
+ onResume: (eff) => import_effect14.Ref.update(this.resumeRef, (list) => [...list, eff]).pipe(import_effect14.Effect.asVoid),
3194
+ onReset: (eff) => import_effect14.Ref.update(this.resetRef, (list) => [...list, eff]).pipe(import_effect14.Effect.asVoid)
2911
3195
  };
2912
3196
  // The emit* methods are not part of the official Logic.Platform interface; they are for host/test use only.
2913
3197
  // After retrieving the instance via `Effect.service(Logic.Platform)`, call them via `any`.
2914
- this.emitSuspend = () => import_effect13.Ref.get(this.suspendRef).pipe(import_effect13.Effect.flatMap((effects) => import_effect13.Effect.forEach(effects, (eff) => eff, { discard: true })));
2915
- this.emitResume = () => import_effect13.Ref.get(this.resumeRef).pipe(import_effect13.Effect.flatMap((effects) => import_effect13.Effect.forEach(effects, (eff) => eff, { discard: true })));
2916
- this.emitReset = () => import_effect13.Ref.get(this.resetRef).pipe(import_effect13.Effect.flatMap((effects) => import_effect13.Effect.forEach(effects, (eff) => eff, { discard: true })));
3198
+ this.emitSuspend = () => import_effect14.Ref.get(this.suspendRef).pipe(import_effect14.Effect.flatMap((effects) => import_effect14.Effect.forEach(effects, (eff) => eff, { discard: true })));
3199
+ this.emitResume = () => import_effect14.Ref.get(this.resumeRef).pipe(import_effect14.Effect.flatMap((effects) => import_effect14.Effect.forEach(effects, (eff) => eff, { discard: true })));
3200
+ this.emitReset = () => import_effect14.Ref.get(this.resetRef).pipe(import_effect14.Effect.flatMap((effects) => import_effect14.Effect.forEach(effects, (eff) => eff, { discard: true })));
2917
3201
  }
2918
3202
  };
2919
- var makeReactPlatform = import_effect13.Effect.gen(function* () {
2920
- const suspendRef = yield* import_effect13.Ref.make([]);
2921
- const resumeRef = yield* import_effect13.Ref.make([]);
2922
- const resetRef = yield* import_effect13.Ref.make([]);
3203
+ var makeReactPlatform = import_effect14.Effect.gen(function* () {
3204
+ const suspendRef = yield* import_effect14.Ref.make([]);
3205
+ const resumeRef = yield* import_effect14.Ref.make([]);
3206
+ const resetRef = yield* import_effect14.Ref.make([]);
2923
3207
  return new ReactPlatformImpl(suspendRef, resumeRef, resetRef);
2924
3208
  });
2925
- var ReactPlatformLayer = import_effect13.Layer.scoped(
2926
- import_core.Platform.tag,
2927
- makeReactPlatform
2928
- );
3209
+ var ReactPlatformLayer = import_effect14.Layer.effect(import_core.Platform.tag, makeReactPlatform);
2929
3210
 
2930
3211
  // src/ReactPlatform.ts
2931
3212
  var import_react16 = __toESM(require("react"), 1);
@@ -2968,16 +3249,19 @@ var ReactPlatform = {
2968
3249
 
2969
3250
  // src/ModuleScope.ts
2970
3251
  var import_react17 = __toESM(require("react"), 1);
2971
- var Logix13 = __toESM(require("@logixjs/core"), 1);
3252
+ var import_effect15 = require("effect");
3253
+ var Logix14 = __toESM(require("@logixjs/core"), 1);
2972
3254
  var makeModuleScope = (handle, defaults) => {
2973
- const Context7 = import_react17.default.createContext(null);
3255
+ const Context = import_react17.default.createContext(null);
2974
3256
  const toUseModuleOptions = (options) => {
2975
3257
  const { scopeId, ...rest } = options;
2976
3258
  return scopeId != null ? { ...rest, key: scopeId } : rest;
2977
3259
  };
2978
3260
  const getRegistryOrThrow = (runtime, where) => {
2979
3261
  try {
2980
- const registry = runtime.runSync(Logix13.ScopeRegistry.ScopeRegistryTag);
3262
+ const registry = runtime.runSync(
3263
+ import_effect15.Effect.service(Logix14.ScopeRegistry.ScopeRegistryTag).pipe(import_effect15.Effect.orDie)
3264
+ );
2981
3265
  if (!registry) {
2982
3266
  throw new Error("ScopeRegistry service is undefined");
2983
3267
  }
@@ -2988,7 +3272,7 @@ var makeModuleScope = (handle, defaults) => {
2988
3272
  );
2989
3273
  }
2990
3274
  };
2991
- const moduleToken = Logix13.Module.hasImpl(handle) ? handle.tag : handle.module;
3275
+ const moduleToken = Logix14.Module.hasImpl(handle) ? handle.tag : handle.module;
2992
3276
  const Provider = ({ children, options }) => {
2993
3277
  const runtime = useRuntime();
2994
3278
  const merged = defaults || options ? { ...defaults ?? {}, ...options ?? {} } : void 0;
@@ -2997,17 +3281,17 @@ var makeModuleScope = (handle, defaults) => {
2997
3281
  import_react17.default.useEffect(() => {
2998
3282
  if (!scopeId) return;
2999
3283
  const registry = getRegistryOrThrow(runtime, "[ModuleScope]");
3000
- const leaseRuntime = registry.register(scopeId, Logix13.ScopeRegistry.ScopedRuntimeTag, runtime);
3284
+ const leaseRuntime = registry.register(scopeId, Logix14.ScopeRegistry.ScopedRuntimeTag, runtime);
3001
3285
  const leaseModule = registry.register(scopeId, moduleToken, ref.runtime);
3002
3286
  return () => {
3003
3287
  leaseModule.release();
3004
3288
  leaseRuntime.release();
3005
3289
  };
3006
3290
  }, [runtime, scopeId, ref.runtime]);
3007
- return import_react17.default.createElement(Context7.Provider, { value: ref }, children);
3291
+ return import_react17.default.createElement(Context.Provider, { value: ref }, children);
3008
3292
  };
3009
3293
  const use = () => {
3010
- const ref = import_react17.default.useContext(Context7);
3294
+ const ref = import_react17.default.useContext(Context);
3011
3295
  if (!ref) {
3012
3296
  throw new Error("[ModuleScope] Provider not found");
3013
3297
  }
@@ -3020,7 +3304,7 @@ var makeModuleScope = (handle, defaults) => {
3020
3304
  const Bridge = ({ scopeId, children }) => {
3021
3305
  const runtime = useRuntime();
3022
3306
  const registry = getRegistryOrThrow(runtime, "[ModuleScope.Bridge]");
3023
- const scopedRuntime = registry.get(scopeId, Logix13.ScopeRegistry.ScopedRuntimeTag);
3307
+ const scopedRuntime = registry.get(scopeId, Logix14.ScopeRegistry.ScopedRuntimeTag);
3024
3308
  const moduleRuntime = registry.get(scopeId, moduleToken);
3025
3309
  if (!scopedRuntime || !moduleRuntime) {
3026
3310
  throw new Error(
@@ -3030,18 +3314,18 @@ var makeModuleScope = (handle, defaults) => {
3030
3314
  return import_react17.default.createElement(
3031
3315
  RuntimeProvider,
3032
3316
  { runtime: scopedRuntime },
3033
- import_react17.default.createElement(BridgeInner, { moduleRuntime, Context: Context7 }, children)
3317
+ import_react17.default.createElement(BridgeInner, { moduleRuntime, Context }, children)
3034
3318
  );
3035
3319
  };
3036
3320
  const BridgeInner = ({
3037
3321
  moduleRuntime,
3038
- Context: Context8,
3322
+ Context: Context2,
3039
3323
  children
3040
3324
  }) => {
3041
3325
  const ref = useModule(moduleRuntime);
3042
- return import_react17.default.createElement(Context8.Provider, { value: ref }, children);
3326
+ return import_react17.default.createElement(Context2.Provider, { value: ref }, children);
3043
3327
  };
3044
- return { Provider, use, useImported, Context: Context7, Bridge };
3328
+ return { Provider, use, useImported, Context, Bridge };
3045
3329
  };
3046
3330
  var ModuleScope = {
3047
3331
  make: makeModuleScope