@logixjs/react 0.1.0 → 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.
Files changed (36) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1 -1
  3. package/dist/Hooks.cjs +462 -325
  4. package/dist/Hooks.d.cts +6 -6
  5. package/dist/Hooks.d.ts +6 -6
  6. package/dist/Hooks.js +3 -3
  7. package/dist/{ModuleRef-wZSQ3Wwo.d.cts → ModuleRef-gZmL6Zvb.d.cts} +8 -3
  8. package/dist/{ModuleRef-wZSQ3Wwo.d.ts → ModuleRef-gZmL6Zvb.d.ts} +8 -3
  9. package/dist/ModuleScope.cjs +596 -362
  10. package/dist/ModuleScope.d.cts +4 -4
  11. package/dist/ModuleScope.d.ts +4 -4
  12. package/dist/ModuleScope.js +4 -4
  13. package/dist/Platform.cjs +1 -4
  14. package/dist/Platform.d.cts +1 -2
  15. package/dist/Platform.d.ts +1 -2
  16. package/dist/Platform.js +1 -1
  17. package/dist/ReactPlatform.cjs +543 -309
  18. package/dist/ReactPlatform.d.cts +2 -2
  19. package/dist/ReactPlatform.d.ts +2 -2
  20. package/dist/ReactPlatform.js +5 -5
  21. package/dist/RuntimeProvider.cjs +276 -56
  22. package/dist/RuntimeProvider.js +2 -2
  23. package/dist/{chunk-PYWHL7TA.js → chunk-6NLXTHZ7.js} +8 -8
  24. package/dist/{chunk-UFFCJGSZ.js → chunk-E3ZXST5F.js} +256 -240
  25. package/dist/{chunk-4G7H66OY.js → chunk-KYWW4KMQ.js} +3 -3
  26. package/dist/{chunk-2WFULYPJ.js → chunk-L7KTYBXN.js} +155 -32
  27. package/dist/{chunk-ZANGOPUQ.js → chunk-NKYV44OG.js} +1 -4
  28. package/dist/{chunk-G5MRIFKK.js → chunk-SDQF3WRT.js} +7 -7
  29. package/dist/{chunk-JXAJTWSZ.js → chunk-XSGDBJXD.js} +122 -25
  30. package/dist/index.cjs +564 -333
  31. package/dist/index.d.cts +2 -2
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.js +7 -7
  34. package/dist/{useDispatch-BnzYVkRE.d.ts → useDispatch-CiDimIYZ.d.ts} +13 -15
  35. package/dist/{useDispatch-CnO5-66H.d.cts → useDispatch-DiwQQAfC.d.cts} +13 -15
  36. package/package.json +12 -4
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,
@@ -1292,6 +1418,20 @@ var RuntimeProvider = ({
1292
1418
  );
1293
1419
  const onErrorRef = import_react4.default.useRef(onError);
1294
1420
  onErrorRef.current = onError;
1421
+ const hasTickServices = (0, import_react4.useMemo)(() => {
1422
+ try {
1423
+ Logix5.InternalContracts.getRuntimeStore(baseRuntime);
1424
+ return true;
1425
+ } catch {
1426
+ return false;
1427
+ }
1428
+ }, [baseRuntime]);
1429
+ const { binding: tickBinding } = useLayerBinding(
1430
+ baseRuntime,
1431
+ Logix5.InternalContracts.tickServicesLayer,
1432
+ !hasTickServices,
1433
+ onErrorRef.current
1434
+ );
1295
1435
  const { binding: layerBinding } = useLayerBinding(baseRuntime, layer, Boolean(layer), onErrorRef.current);
1296
1436
  const onErrorSink = (0, import_react4.useMemo)(() => {
1297
1437
  if (!onError) return null;
@@ -1308,7 +1448,7 @@ var RuntimeProvider = ({
1308
1448
  moduleId: event.moduleId,
1309
1449
  instanceId: event.instanceId,
1310
1450
  runtimeLabel: event.runtimeLabel
1311
- }).pipe(import_effect5.Effect.catchAllCause(() => import_effect5.Effect.void));
1451
+ }).pipe(import_effect5.Effect.catchCause(() => import_effect5.Effect.void));
1312
1452
  }
1313
1453
  if (event.type === "diagnostic" && event.severity === "error") {
1314
1454
  return handler(
@@ -1327,7 +1467,7 @@ var RuntimeProvider = ({
1327
1467
  instanceId: event.instanceId,
1328
1468
  runtimeLabel: event.runtimeLabel
1329
1469
  }
1330
- ).pipe(import_effect5.Effect.catchAllCause(() => import_effect5.Effect.void));
1470
+ ).pipe(import_effect5.Effect.catchCause(() => import_effect5.Effect.void));
1331
1471
  }
1332
1472
  return import_effect5.Effect.void;
1333
1473
  }
@@ -1342,25 +1482,23 @@ var RuntimeProvider = ({
1342
1482
  return layerBinding.debugSinks;
1343
1483
  }
1344
1484
  try {
1345
- return baseRuntime.runSync(
1346
- import_effect5.FiberRef.get(Logix5.Debug.internal.currentDebugSinks)
1347
- );
1485
+ return baseRuntime.runSync(import_effect5.Effect.service(Logix5.Debug.internal.currentDebugSinks).pipe(import_effect5.Effect.orDie));
1348
1486
  } catch {
1349
1487
  return [];
1350
1488
  }
1351
1489
  }, [baseRuntime, layerBinding, onErrorSink]);
1352
1490
  const runtimeWithBindings = (0, import_react4.useMemo)(
1353
- () => layerBinding || onErrorSink ? createRuntimeAdapter(
1491
+ () => tickBinding || layerBinding || onErrorSink ? createRuntimeAdapter(
1354
1492
  baseRuntime,
1355
- layerBinding ? [layerBinding.context] : [],
1356
- layerBinding ? [layerBinding.scope] : [],
1357
- layerBinding ? [layerBinding.loggers] : [],
1358
- layerBinding ? [layerBinding.logLevel] : [],
1493
+ [...tickBinding ? [tickBinding.context] : [], ...layerBinding ? [layerBinding.context] : []],
1494
+ [...tickBinding ? [tickBinding.scope] : [], ...layerBinding ? [layerBinding.scope] : []],
1495
+ layerBinding ? [layerBinding.loggers] : tickBinding ? [tickBinding.loggers] : [],
1496
+ layerBinding ? [layerBinding.logLevel] : tickBinding ? [tickBinding.logLevel] : [],
1359
1497
  [
1360
1498
  onErrorSink ? [onErrorSink, ...inheritedDebugSinks] : layerBinding ? layerBinding.debugSinks : []
1361
1499
  ]
1362
1500
  ) : baseRuntime,
1363
- [baseRuntime, inheritedDebugSinks, layerBinding, onErrorSink]
1501
+ [baseRuntime, inheritedDebugSinks, layerBinding, onErrorSink, tickBinding]
1364
1502
  );
1365
1503
  const didReportSyncConfigSnapshotRef = import_react4.default.useRef(false);
1366
1504
  const [configState, setConfigState] = (0, import_react4.useState)(() => {
@@ -1465,11 +1603,47 @@ var RuntimeProvider = ({
1465
1603
  }),
1466
1604
  [runtimeWithBindings, configState, resolvedPolicy]
1467
1605
  );
1606
+ const isTickServicesReady = hasTickServices || tickBinding !== null;
1468
1607
  const isLayerReady = !layer || layerBinding !== null;
1469
1608
  const isConfigReady = configState.loaded;
1470
1609
  const resolveFallback = (phase) => {
1471
1610
  return resolveRuntimeProviderFallback({ fallback, phase, policyMode: resolvedPolicy.mode });
1472
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]);
1473
1647
  const [deferReady, setDeferReady] = (0, import_react4.useState)(false);
1474
1648
  (0, import_react4.useEffect)(() => {
1475
1649
  if (resolvedPolicy.mode !== "defer") {
@@ -1483,6 +1657,10 @@ var RuntimeProvider = ({
1483
1657
  if (resolvedPolicy.mode !== "defer") {
1484
1658
  return;
1485
1659
  }
1660
+ if (syncWarmPreloadReady) {
1661
+ setDeferReady(true);
1662
+ return;
1663
+ }
1486
1664
  setDeferReady(false);
1487
1665
  if (!resolvedPolicy.preload) {
1488
1666
  setDeferReady(true);
@@ -1492,7 +1670,7 @@ var RuntimeProvider = ({
1492
1670
  return;
1493
1671
  }
1494
1672
  let cancelled = false;
1495
- const cache = getModuleCache(runtimeWithBindings, configState.snapshot, configState.version);
1673
+ const cache = preloadCache;
1496
1674
  const preloadHandles = resolvedPolicy.preload.handles;
1497
1675
  if (preloadHandles.length === 0) {
1498
1676
  setDeferReady(true);
@@ -1510,13 +1688,14 @@ var RuntimeProvider = ({
1510
1688
  const moduleId = handle.module?.id ?? "ModuleImpl";
1511
1689
  const key2 = resolvedPolicy.preload.keysByModuleId.get(moduleId) ?? getPreloadKeyForModuleId(moduleId);
1512
1690
  const factory2 = (scope) => import_effect5.Layer.buildWithScope(handle.layer, scope).pipe(
1513
- 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))
1514
1692
  );
1515
1693
  const op2 = cache.preload(key2, factory2, {
1516
1694
  ownerId: moduleId,
1517
1695
  yield: resolvedPolicy.preload.yield,
1518
1696
  entrypoint: "react.runtime.preload",
1519
- policyMode: "defer"
1697
+ policyMode: "defer",
1698
+ optimisticSyncBudgetMs: resolvedPolicy.syncBudgetMs
1520
1699
  });
1521
1700
  allCancels.add(op2.cancel);
1522
1701
  await op2.promise;
@@ -1541,14 +1720,13 @@ var RuntimeProvider = ({
1541
1720
  }
1542
1721
  const tagId = handle.id ?? "ModuleTag";
1543
1722
  const key = resolvedPolicy.preload.keysByTagId.get(tagId) ?? getPreloadKeyForTagId(tagId);
1544
- const factory = (scope) => handle.pipe(
1545
- import_effect5.Scope.extend(scope)
1546
- );
1723
+ const factory = (scope) => import_effect5.Scope.provide(scope)(import_effect5.Effect.service(handle).pipe(import_effect5.Effect.orDie));
1547
1724
  const op = cache.preload(key, factory, {
1548
1725
  ownerId: tagId,
1549
1726
  yield: resolvedPolicy.preload.yield,
1550
1727
  entrypoint: "react.runtime.preload",
1551
- policyMode: "defer"
1728
+ policyMode: "defer",
1729
+ optimisticSyncBudgetMs: resolvedPolicy.syncBudgetMs
1552
1730
  });
1553
1731
  allCancels.add(op.cancel);
1554
1732
  await op.promise;
@@ -1586,7 +1764,7 @@ var RuntimeProvider = ({
1586
1764
  if (cancelled) return;
1587
1765
  if (onErrorRef.current) {
1588
1766
  runtimeWithBindings.runFork(
1589
- 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))
1590
1768
  );
1591
1769
  }
1592
1770
  setDeferReady(true);
@@ -1619,12 +1797,54 @@ var RuntimeProvider = ({
1619
1797
  release();
1620
1798
  };
1621
1799
  }, [resolvedPolicy.mode, deferReady]);
1622
- const isReady = 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]);
1623
1842
  if (!isReady) {
1624
1843
  const blockersList = [
1844
+ isTickServicesReady ? null : "tick",
1625
1845
  isLayerReady ? null : "layer",
1626
1846
  isConfigReady ? null : "config",
1627
- resolvedPolicy.mode !== "defer" || deferReady ? null : "preload"
1847
+ resolvedPolicy.mode !== "defer" || deferReady || syncWarmPreloadReady ? null : "preload"
1628
1848
  ].filter((x) => x !== null);
1629
1849
  const blockers = blockersList.length > 0 ? blockersList.join("+") : void 0;
1630
1850
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -1737,13 +1957,13 @@ function useRuntime(options) {
1737
1957
 
1738
1958
  // src/internal/hooks/useModule.ts
1739
1959
  var import_react9 = __toESM(require("react"), 1);
1740
- var Logix9 = __toESM(require("@logixjs/core"), 1);
1960
+ var Logix11 = __toESM(require("@logixjs/core"), 1);
1741
1961
  var import_effect10 = require("effect");
1742
1962
 
1743
1963
  // src/internal/hooks/useModuleRuntime.ts
1744
1964
  var import_react6 = require("react");
1745
- var Logix6 = __toESM(require("@logixjs/core"), 1);
1746
- var import_effect7 = require("effect");
1965
+ var Logix7 = __toESM(require("@logixjs/core"), 1);
1966
+ var import_effect8 = require("effect");
1747
1967
 
1748
1968
  // src/internal/store/ModuleRef.ts
1749
1969
  var isModuleRef = (value) => typeof value === "object" && value !== null && "runtime" in value && "actions" in value && "dispatch" in value;
@@ -1834,11 +2054,26 @@ var applyHandleExtend = (tag, runtime, base) => {
1834
2054
  return { ...base, ...next };
1835
2055
  };
1836
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
+
1837
2071
  // src/internal/hooks/useModuleRuntime.ts
1838
2072
  var isModuleRuntime = (value) => typeof value === "object" && value !== null && "dispatch" in value && "getState" in value;
1839
2073
  function useModuleRuntime(handle) {
1840
2074
  const runtime = useRuntime();
1841
2075
  const runtimeContext = (0, import_react6.useContext)(RuntimeContext);
2076
+ const moduleTagResolveTraceRef = (0, import_react6.useRef)(void 0);
1842
2077
  if (!runtimeContext) {
1843
2078
  throw new RuntimeProviderNotFoundError("useModuleRuntime");
1844
2079
  }
@@ -1859,36 +2094,48 @@ function useModuleRuntime(handle) {
1859
2094
  const preloadKey = runtimeContext.policy.preload?.keysByTagId.get(tokenId);
1860
2095
  const key = preloadKey ?? `tag:${tokenId}`;
1861
2096
  const mode = runtimeContext.policy.moduleTagMode;
1862
- const factory = (scope) => tag.pipe(import_effect7.Scope.extend(scope));
1863
- 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, {
1864
2100
  entrypoint: "react.useModuleRuntime",
1865
2101
  policyMode: runtimeContext.policy.mode,
1866
- yield: runtimeContext.policy.yield
2102
+ yield: runtimeContext.policy.yield,
2103
+ optimisticSyncBudgetMs: runtimeContext.policy.syncBudgetMs
1867
2104
  }) : cache.readSync(key, factory, void 0, tokenId, {
1868
2105
  entrypoint: "react.useModuleRuntime",
1869
2106
  policyMode: runtimeContext.policy.mode,
1870
2107
  warnSyncBlockingThresholdMs: 5
1871
2108
  });
2109
+ moduleTagResolveTraceRef.current = {
2110
+ tokenId,
2111
+ durationMs: Math.round((performance.now() - startedAtMs) * 100) / 100,
2112
+ cacheMode: mode
2113
+ };
2114
+ return resolvedRuntime;
1872
2115
  }, [cache, runtimeContext.policy, handle]);
1873
2116
  (0, import_react6.useEffect)(() => {
1874
2117
  if (!isTagHandle) {
1875
2118
  return;
1876
2119
  }
1877
- if (!(0, import_Env.isDevEnv)() && !Logix6.Debug.isDevtoolsEnabled()) {
2120
+ const diagnosticsLevel = readRuntimeDiagnosticsLevel(runtime);
2121
+ if (diagnosticsLevel === "off") {
1878
2122
  return;
1879
2123
  }
1880
2124
  const tokenId = handle?.id ?? "ModuleTag";
1881
- const effect = Logix6.Debug.record({
2125
+ const trace = moduleTagResolveTraceRef.current;
2126
+ const effect = Logix7.Debug.record({
1882
2127
  type: "trace:react.moduleTag.resolve",
1883
2128
  moduleId: resolved.moduleId,
1884
2129
  instanceId: resolved.instanceId,
1885
2130
  data: {
1886
2131
  mode: runtimeContext.policy.moduleTagMode,
1887
2132
  tokenId,
1888
- yieldStrategy: runtimeContext.policy.yield.strategy
2133
+ yieldStrategy: runtimeContext.policy.yield.strategy,
2134
+ durationMs: trace?.durationMs,
2135
+ cacheMode: trace?.cacheMode ?? runtimeContext.policy.moduleTagMode
1889
2136
  }
1890
2137
  });
1891
- runtime.runFork(effect);
2138
+ emitRuntimeDebugEventBestEffort(runtime, effect);
1892
2139
  }, [runtime, runtimeContext.policy, resolved, handle, isTagHandle]);
1893
2140
  return resolved;
1894
2141
  }
@@ -1896,55 +2143,73 @@ function useModuleRuntime(handle) {
1896
2143
  // src/internal/hooks/useSelector.ts
1897
2144
  var import_react7 = require("react");
1898
2145
  var import_with_selector = require("use-sync-external-store/shim/with-selector");
1899
- var Logix7 = __toESM(require("@logixjs/core"), 1);
2146
+ var Logix9 = __toESM(require("@logixjs/core"), 1);
1900
2147
 
1901
- // src/internal/store/ModuleRuntimeExternalStore.ts
1902
- var import_effect8 = require("effect");
2148
+ // src/internal/store/RuntimeExternalStore.ts
2149
+ var Logix8 = __toESM(require("@logixjs/core"), 1);
2150
+ var import_effect9 = require("effect");
1903
2151
  var storesByRuntime = /* @__PURE__ */ new WeakMap();
1904
2152
  var getStoreMapForRuntime = (runtime) => {
1905
2153
  const cached = storesByRuntime.get(runtime);
1906
2154
  if (cached) return cached;
1907
- const next = /* @__PURE__ */ new WeakMap();
2155
+ const next = /* @__PURE__ */ new Map();
1908
2156
  storesByRuntime.set(runtime, next);
1909
2157
  return next;
1910
2158
  };
1911
- var getModuleRuntimeExternalStore = (runtime, moduleRuntime, options) => {
1912
- const byModule = getStoreMapForRuntime(runtime);
1913
- const cached = byModule.get(moduleRuntime);
2159
+ var makeModuleInstanceKey = (moduleId, instanceId) => `${moduleId}::${instanceId}`;
2160
+ var makeReadQueryTopicKey = (moduleInstanceKey, selectorId) => `${moduleInstanceKey}::rq:${selectorId}`;
2161
+ var getRuntimeStore = (runtime) => Logix8.InternalContracts.getRuntimeStore(runtime);
2162
+ var getHostScheduler = (runtime) => Logix8.InternalContracts.getHostScheduler(runtime);
2163
+ var getOrCreateStore = (runtime, topicKey, make) => {
2164
+ const map = getStoreMapForRuntime(runtime);
2165
+ const cached = map.get(topicKey);
1914
2166
  if (cached) {
1915
2167
  return cached;
1916
2168
  }
1917
- let currentState;
2169
+ const created = make();
2170
+ map.set(topicKey, created);
2171
+ return created;
2172
+ };
2173
+ var removeStore = (runtime, topicKey) => {
2174
+ const map = storesByRuntime.get(runtime);
2175
+ if (!map) return;
2176
+ map.delete(topicKey);
2177
+ };
2178
+ var makeTopicExternalStore = (args) => {
2179
+ const { runtime, runtimeStore, topicKey } = args;
2180
+ const hostScheduler = getHostScheduler(runtime);
2181
+ let currentVersion;
2182
+ let hasSnapshot = false;
2183
+ let currentSnapshot;
1918
2184
  const listeners = /* @__PURE__ */ new Set();
1919
- const lowPriorityDelayMs = options?.lowPriorityDelayMs ?? 16;
1920
- const lowPriorityMaxDelayMs = options?.lowPriorityMaxDelayMs ?? 50;
2185
+ let unsubscribeFromRuntimeStore;
2186
+ let teardownScheduled = false;
2187
+ let teardownToken = 0;
2188
+ const lowPriorityDelayMs = args.options?.lowPriorityDelayMs ?? 16;
2189
+ const lowPriorityMaxDelayMs = args.options?.lowPriorityMaxDelayMs ?? 50;
1921
2190
  let notifyScheduled = false;
1922
2191
  let notifyScheduledLow = false;
1923
- let lowTimeoutId;
1924
- let lowMaxTimeoutId;
1925
- let lowRafId;
2192
+ let lowCancelDelay;
2193
+ let lowCancelMaxDelay;
2194
+ let lowCancelRaf;
1926
2195
  const cancelLow = () => {
1927
2196
  if (!notifyScheduledLow) return;
1928
2197
  notifyScheduledLow = false;
1929
- if (lowTimeoutId != null) {
1930
- clearTimeout(lowTimeoutId);
1931
- lowTimeoutId = void 0;
1932
- }
1933
- if (lowMaxTimeoutId != null) {
1934
- clearTimeout(lowMaxTimeoutId);
1935
- lowMaxTimeoutId = void 0;
1936
- }
1937
- const cancel = globalThis.cancelAnimationFrame;
1938
- if (cancel && typeof lowRafId === "number") {
1939
- cancel(lowRafId);
1940
- lowRafId = void 0;
1941
- }
2198
+ lowCancelDelay?.();
2199
+ lowCancelDelay = void 0;
2200
+ lowCancelMaxDelay?.();
2201
+ lowCancelMaxDelay = void 0;
2202
+ lowCancelRaf?.();
2203
+ lowCancelRaf = void 0;
1942
2204
  };
1943
2205
  const flushNotify = () => {
1944
2206
  notifyScheduled = false;
1945
2207
  cancelLow();
1946
2208
  for (const listener of listeners) {
1947
- listener();
2209
+ try {
2210
+ listener();
2211
+ } catch {
2212
+ }
1948
2213
  }
1949
2214
  };
1950
2215
  const scheduleNotify = (priority) => {
@@ -1956,72 +2221,155 @@ var getModuleRuntimeExternalStore = (runtime, moduleRuntime, options) => {
1956
2221
  if (!notifyScheduledLow) return;
1957
2222
  flushNotify();
1958
2223
  };
1959
- const raf = globalThis.requestAnimationFrame;
1960
- if (raf) {
1961
- lowRafId = raf(flush);
2224
+ const scheduleRaf = () => {
2225
+ if (!notifyScheduledLow) return;
2226
+ lowCancelRaf = hostScheduler.scheduleAnimationFrame(flush);
2227
+ };
2228
+ if (lowPriorityDelayMs <= 0) {
2229
+ scheduleRaf();
1962
2230
  } else {
1963
- lowTimeoutId = setTimeout(flush, lowPriorityDelayMs);
2231
+ lowCancelDelay = hostScheduler.scheduleTimeout(lowPriorityDelayMs, scheduleRaf);
1964
2232
  }
1965
- lowMaxTimeoutId = setTimeout(flush, lowPriorityMaxDelayMs);
2233
+ lowCancelMaxDelay = hostScheduler.scheduleTimeout(lowPriorityMaxDelayMs, flush);
1966
2234
  return;
1967
2235
  }
1968
2236
  cancelLow();
1969
2237
  if (notifyScheduled) return;
1970
2238
  notifyScheduled = true;
1971
- queueMicrotask(flushNotify);
2239
+ hostScheduler.scheduleMicrotask(flushNotify);
2240
+ };
2241
+ const onRuntimeStoreChange = () => {
2242
+ try {
2243
+ scheduleNotify(runtimeStore.getTopicPriority(topicKey));
2244
+ } catch {
2245
+ }
1972
2246
  };
1973
- let fiber;
1974
2247
  const ensureSubscription = () => {
1975
- if (fiber) return;
1976
- fiber = runtime.runFork(
1977
- import_effect8.Stream.runForEach(
1978
- moduleRuntime.changesWithMeta((state) => state),
1979
- ({ value: state, meta }) => import_effect8.Effect.sync(() => {
1980
- currentState = state;
1981
- scheduleNotify(meta.priority);
1982
- })
1983
- )
1984
- );
2248
+ if (unsubscribeFromRuntimeStore) return;
2249
+ unsubscribeFromRuntimeStore = runtimeStore.subscribeTopic(topicKey, onRuntimeStoreChange);
1985
2250
  };
1986
2251
  const refreshSnapshotIfStale = () => {
1987
- if (currentState === void 0) {
1988
- return;
1989
- }
2252
+ if (!hasSnapshot) return;
1990
2253
  try {
1991
- const latest = runtime.runSync(moduleRuntime.getState);
1992
- if (currentState === void 0 || !Object.is(currentState, latest)) {
1993
- currentState = latest;
1994
- scheduleNotify("normal");
2254
+ const version = runtimeStore.getTopicVersion(topicKey);
2255
+ if (currentVersion !== version) {
2256
+ scheduleNotify(runtimeStore.getTopicPriority(topicKey));
1995
2257
  }
1996
2258
  } catch {
1997
2259
  }
1998
2260
  };
1999
2261
  const getSnapshot = () => {
2000
- if (currentState !== void 0) return currentState;
2001
- currentState = runtime.runSync(moduleRuntime.getState);
2002
- return currentState;
2262
+ const version = runtimeStore.getTopicVersion(topicKey);
2263
+ if (hasSnapshot && currentVersion === version) {
2264
+ return currentSnapshot;
2265
+ }
2266
+ const next = args.readSnapshot();
2267
+ currentVersion = version;
2268
+ hasSnapshot = true;
2269
+ currentSnapshot = next;
2270
+ return next;
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
+ });
2003
2301
  };
2004
2302
  const subscribe = (listener) => {
2303
+ cancelScheduledTeardown();
2304
+ const isFirst = listeners.size === 0;
2005
2305
  listeners.add(listener);
2006
2306
  ensureSubscription();
2007
2307
  refreshSnapshotIfStale();
2308
+ if (isFirst) {
2309
+ try {
2310
+ args.onFirstListener?.();
2311
+ } catch {
2312
+ }
2313
+ }
2008
2314
  return () => {
2009
2315
  listeners.delete(listener);
2010
2316
  if (listeners.size > 0) return;
2011
- const running = fiber;
2012
- if (!running) return;
2013
- fiber = void 0;
2014
- cancelLow();
2015
- runtime.runFork(import_effect8.Fiber.interrupt(running));
2317
+ scheduleTeardown();
2016
2318
  };
2017
2319
  };
2018
- const store = { getSnapshot, subscribe };
2019
- byModule.set(moduleRuntime, store);
2020
- return store;
2320
+ return { getSnapshot, getServerSnapshot: getSnapshot, subscribe };
2321
+ };
2322
+ var getRuntimeModuleExternalStore = (runtime, moduleRuntime, options) => {
2323
+ const moduleInstanceKey = makeModuleInstanceKey(moduleRuntime.moduleId, moduleRuntime.instanceId);
2324
+ const runtimeStore = getRuntimeStore(runtime);
2325
+ return getOrCreateStore(
2326
+ runtime,
2327
+ moduleInstanceKey,
2328
+ () => makeTopicExternalStore({
2329
+ runtime,
2330
+ runtimeStore,
2331
+ topicKey: moduleInstanceKey,
2332
+ readSnapshot: () => {
2333
+ const state = runtimeStore.getModuleState(moduleInstanceKey);
2334
+ if (state !== void 0) return state;
2335
+ return runtime.runSync(moduleRuntime.getState);
2336
+ },
2337
+ options
2338
+ })
2339
+ );
2340
+ };
2341
+ var getRuntimeReadQueryExternalStore = (runtime, moduleRuntime, selectorReadQuery, options) => {
2342
+ const moduleInstanceKey = makeModuleInstanceKey(moduleRuntime.moduleId, moduleRuntime.instanceId);
2343
+ const topicKey = makeReadQueryTopicKey(moduleInstanceKey, selectorReadQuery.selectorId);
2344
+ const runtimeStore = getRuntimeStore(runtime);
2345
+ let readQueryDrainFiber;
2346
+ return getOrCreateStore(
2347
+ runtime,
2348
+ topicKey,
2349
+ () => makeTopicExternalStore({
2350
+ runtime,
2351
+ runtimeStore,
2352
+ topicKey,
2353
+ readSnapshot: () => {
2354
+ const state = runtimeStore.getModuleState(moduleInstanceKey);
2355
+ const current = state ?? runtime.runSync(moduleRuntime.getState);
2356
+ return selectorReadQuery.select(current);
2357
+ },
2358
+ options,
2359
+ onFirstListener: () => {
2360
+ if (readQueryDrainFiber) return;
2361
+ const effect = import_effect9.Stream.runDrain(moduleRuntime.changesReadQueryWithMeta(selectorReadQuery));
2362
+ readQueryDrainFiber = runtime.runFork(effect);
2363
+ },
2364
+ onLastListener: () => {
2365
+ const fiber = readQueryDrainFiber;
2366
+ if (!fiber) return;
2367
+ readQueryDrainFiber = void 0;
2368
+ runtime.runFork(import_effect9.Fiber.interrupt(fiber));
2369
+ }
2370
+ })
2371
+ );
2021
2372
  };
2022
-
2023
- // src/internal/store/ModuleRuntimeSelectorExternalStore.ts
2024
- var import_effect9 = require("effect");
2025
2373
 
2026
2374
  // src/internal/hooks/shallow.ts
2027
2375
  var hasObjectShape = (value) => typeof value === "object" && value !== null;
@@ -2073,146 +2421,6 @@ var shallow = (previous, next) => {
2073
2421
  return true;
2074
2422
  };
2075
2423
 
2076
- // src/internal/store/ModuleRuntimeSelectorExternalStore.ts
2077
- var storesByRuntime2 = /* @__PURE__ */ new WeakMap();
2078
- var getStoreMapForRuntime2 = (runtime) => {
2079
- const cached = storesByRuntime2.get(runtime);
2080
- if (cached) return cached;
2081
- const next = /* @__PURE__ */ new WeakMap();
2082
- storesByRuntime2.set(runtime, next);
2083
- return next;
2084
- };
2085
- var getOrCreateSelectorMapForModule = (byModule, moduleRuntime) => {
2086
- const cached = byModule.get(moduleRuntime);
2087
- if (cached) return cached;
2088
- const next = /* @__PURE__ */ new Map();
2089
- byModule.set(moduleRuntime, next);
2090
- return next;
2091
- };
2092
- var equalsValue = (readQuery, a, b) => {
2093
- if (readQuery.equalsKind === "custom" && typeof readQuery.equals === "function") {
2094
- return readQuery.equals(a, b);
2095
- }
2096
- if (readQuery.equalsKind === "shallowStruct") {
2097
- return shallow(a, b);
2098
- }
2099
- return Object.is(a, b);
2100
- };
2101
- var getModuleRuntimeSelectorExternalStore = (runtime, moduleRuntime, selectorReadQuery, options) => {
2102
- const byModule = getStoreMapForRuntime2(runtime);
2103
- const bySelector = getOrCreateSelectorMapForModule(byModule, moduleRuntime);
2104
- const cached = bySelector.get(selectorReadQuery.selectorId);
2105
- if (cached) {
2106
- return cached;
2107
- }
2108
- let currentValue;
2109
- const listeners = /* @__PURE__ */ new Set();
2110
- const lowPriorityDelayMs = options?.lowPriorityDelayMs ?? 16;
2111
- const lowPriorityMaxDelayMs = options?.lowPriorityMaxDelayMs ?? 50;
2112
- let notifyScheduled = false;
2113
- let notifyScheduledLow = false;
2114
- let lowTimeoutId;
2115
- let lowMaxTimeoutId;
2116
- let lowRafId;
2117
- const cancelLow = () => {
2118
- if (!notifyScheduledLow) return;
2119
- notifyScheduledLow = false;
2120
- if (lowTimeoutId != null) {
2121
- clearTimeout(lowTimeoutId);
2122
- lowTimeoutId = void 0;
2123
- }
2124
- if (lowMaxTimeoutId != null) {
2125
- clearTimeout(lowMaxTimeoutId);
2126
- lowMaxTimeoutId = void 0;
2127
- }
2128
- const cancel = globalThis.cancelAnimationFrame;
2129
- if (cancel && typeof lowRafId === "number") {
2130
- cancel(lowRafId);
2131
- lowRafId = void 0;
2132
- }
2133
- };
2134
- const flushNotify = () => {
2135
- notifyScheduled = false;
2136
- cancelLow();
2137
- for (const listener of listeners) {
2138
- listener();
2139
- }
2140
- };
2141
- const scheduleNotify = (priority) => {
2142
- if (priority === "low") {
2143
- if (notifyScheduled) return;
2144
- if (notifyScheduledLow) return;
2145
- notifyScheduledLow = true;
2146
- const flush = () => {
2147
- if (!notifyScheduledLow) return;
2148
- flushNotify();
2149
- };
2150
- const raf = globalThis.requestAnimationFrame;
2151
- if (raf) {
2152
- lowRafId = raf(flush);
2153
- } else {
2154
- lowTimeoutId = setTimeout(flush, lowPriorityDelayMs);
2155
- }
2156
- lowMaxTimeoutId = setTimeout(flush, lowPriorityMaxDelayMs);
2157
- return;
2158
- }
2159
- cancelLow();
2160
- if (notifyScheduled) return;
2161
- notifyScheduled = true;
2162
- queueMicrotask(flushNotify);
2163
- };
2164
- let fiber;
2165
- const ensureSubscription = () => {
2166
- if (fiber) return;
2167
- fiber = runtime.runFork(
2168
- import_effect9.Stream.runForEach(
2169
- moduleRuntime.changesReadQueryWithMeta(selectorReadQuery),
2170
- ({ value, meta }) => import_effect9.Effect.sync(() => {
2171
- currentValue = value;
2172
- scheduleNotify(meta.priority);
2173
- })
2174
- )
2175
- );
2176
- };
2177
- const refreshSnapshotIfStale = () => {
2178
- if (currentValue === void 0) {
2179
- return;
2180
- }
2181
- try {
2182
- const state = runtime.runSync(moduleRuntime.getState);
2183
- const next = selectorReadQuery.select(state);
2184
- if (currentValue === void 0 || !equalsValue(selectorReadQuery, currentValue, next)) {
2185
- currentValue = next;
2186
- scheduleNotify("normal");
2187
- }
2188
- } catch {
2189
- }
2190
- };
2191
- const getSnapshot = () => {
2192
- if (currentValue !== void 0) return currentValue;
2193
- const state = runtime.runSync(moduleRuntime.getState);
2194
- currentValue = selectorReadQuery.select(state);
2195
- return currentValue;
2196
- };
2197
- const subscribe = (listener) => {
2198
- listeners.add(listener);
2199
- ensureSubscription();
2200
- refreshSnapshotIfStale();
2201
- return () => {
2202
- listeners.delete(listener);
2203
- if (listeners.size > 0) return;
2204
- const running = fiber;
2205
- if (!running) return;
2206
- fiber = void 0;
2207
- cancelLow();
2208
- runtime.runFork(import_effect9.Fiber.interrupt(running));
2209
- };
2210
- };
2211
- const store = { getSnapshot, subscribe };
2212
- bySelector.set(selectorReadQuery.selectorId, store);
2213
- return store;
2214
- };
2215
-
2216
2424
  // src/internal/hooks/useSelector.ts
2217
2425
  function useSelector(handle, selector, equalityFn) {
2218
2426
  const runtimeContext = (0, import_react7.useContext)(RuntimeContext);
@@ -2223,7 +2431,7 @@ function useSelector(handle, selector, equalityFn) {
2223
2431
  const moduleRuntime = useModuleRuntime(handle);
2224
2432
  const actualSelector = selector ?? ((state) => state);
2225
2433
  const selectorReadQuery = (0, import_react7.useMemo)(
2226
- () => typeof selector === "function" ? Logix7.ReadQuery.compile(selector) : void 0,
2434
+ () => typeof selector === "function" ? Logix9.ReadQuery.compile(selector) : void 0,
2227
2435
  [selector]
2228
2436
  );
2229
2437
  const actualEqualityFn = (0, import_react7.useMemo)(() => {
@@ -2231,17 +2439,12 @@ function useSelector(handle, selector, equalityFn) {
2231
2439
  if (typeof selector !== "function") return Object.is;
2232
2440
  return selectorReadQuery?.equalsKind === "shallowStruct" ? shallow : Object.is;
2233
2441
  }, [equalityFn, selector, selectorReadQuery?.equalsKind]);
2234
- const useStaticLane = typeof selector === "function" && selectorReadQuery?.lane === "static";
2442
+ const selectorTopicEligible = typeof selector === "function" && selectorReadQuery?.lane === "static" && selectorReadQuery.readsDigest != null && selectorReadQuery.fallbackReason == null;
2235
2443
  const store = (0, import_react7.useMemo)(
2236
- () => useStaticLane && selectorReadQuery ? getModuleRuntimeSelectorExternalStore(
2237
- runtime,
2238
- moduleRuntime,
2239
- selectorReadQuery,
2240
- {
2241
- lowPriorityDelayMs: runtimeContext.reactConfigSnapshot.lowPriorityDelayMs,
2242
- lowPriorityMaxDelayMs: runtimeContext.reactConfigSnapshot.lowPriorityMaxDelayMs
2243
- }
2244
- ) : getModuleRuntimeExternalStore(
2444
+ () => selectorTopicEligible && selectorReadQuery ? getRuntimeReadQueryExternalStore(runtime, moduleRuntime, selectorReadQuery, {
2445
+ lowPriorityDelayMs: runtimeContext.reactConfigSnapshot.lowPriorityDelayMs,
2446
+ lowPriorityMaxDelayMs: runtimeContext.reactConfigSnapshot.lowPriorityMaxDelayMs
2447
+ }) : getRuntimeModuleExternalStore(
2245
2448
  runtime,
2246
2449
  moduleRuntime,
2247
2450
  {
@@ -2255,18 +2458,18 @@ function useSelector(handle, selector, equalityFn) {
2255
2458
  runtimeContext.reactConfigSnapshot.lowPriorityDelayMs,
2256
2459
  runtimeContext.reactConfigSnapshot.lowPriorityMaxDelayMs,
2257
2460
  selectorReadQuery,
2258
- useStaticLane
2461
+ selectorTopicEligible
2259
2462
  ]
2260
2463
  );
2261
2464
  const selected = (0, import_with_selector.useSyncExternalStoreWithSelector)(
2262
2465
  store.subscribe,
2263
2466
  store.getSnapshot,
2264
- store.getSnapshot,
2265
- useStaticLane ? (snapshot) => snapshot : (snapshot) => actualSelector(snapshot),
2467
+ store.getServerSnapshot ?? store.getSnapshot,
2468
+ selectorTopicEligible ? (snapshot) => snapshot : (snapshot) => actualSelector(snapshot),
2266
2469
  actualEqualityFn
2267
2470
  );
2268
2471
  (0, import_react7.useEffect)(() => {
2269
- if (!(0, import_Env.isDevEnv)() && !Logix7.Debug.isDevtoolsEnabled()) {
2472
+ if (!(0, import_Env.isDevEnv)() && !Logix9.Debug.isDevtoolsEnabled()) {
2270
2473
  return;
2271
2474
  }
2272
2475
  const instanceId = moduleRuntime.instanceId;
@@ -2282,7 +2485,7 @@ function useSelector(handle, selector, equalityFn) {
2282
2485
  const rawDebugKey = meta.debugKey;
2283
2486
  selectorKey = typeof rawDebugKey === "string" && rawDebugKey.length > 0 ? rawDebugKey : typeof selector.name === "string" && selector.name.length > 0 ? selector.name : void 0;
2284
2487
  }
2285
- const effect = Logix7.Debug.record({
2488
+ const effect = Logix9.Debug.record({
2286
2489
  type: "trace:react-selector",
2287
2490
  moduleId: moduleRuntime.moduleId,
2288
2491
  instanceId,
@@ -2305,7 +2508,7 @@ function useSelector(handle, selector, equalityFn) {
2305
2508
  }
2306
2509
 
2307
2510
  // src/internal/store/resolveImportedModuleRef.ts
2308
- var Logix8 = __toESM(require("@logixjs/core"), 1);
2511
+ var Logix10 = __toESM(require("@logixjs/core"), 1);
2309
2512
  var getOrCreateWeakMap = (map, key, make) => {
2310
2513
  const cached = map.get(key);
2311
2514
  if (cached) return cached;
@@ -2329,7 +2532,7 @@ var resolveImportedModuleRef = (runtime, parentRuntime, module2) => {
2329
2532
  if (cached) {
2330
2533
  return cached;
2331
2534
  }
2332
- const importsScope = Logix8.InternalContracts.getImportsScope(parentRuntime);
2535
+ const importsScope = Logix10.InternalContracts.getImportsScope(parentRuntime);
2333
2536
  const childRuntime = importsScope.get(module2);
2334
2537
  if (childRuntime) {
2335
2538
  const dispatch = Object.assign(
@@ -2415,8 +2618,8 @@ var useStableId = () => {
2415
2618
 
2416
2619
  // src/internal/hooks/useModule.ts
2417
2620
  var isModuleImpl2 = (handle) => Boolean(handle) && typeof handle === "object" && handle._tag === "ModuleImpl";
2418
- var isModule = (handle) => Logix9.Module.hasImpl(handle);
2419
- var isModuleDef = (handle) => Logix9.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";
2420
2623
  function useModule(handle, selectorOrOptions, equalityFn) {
2421
2624
  const runtimeBase = useRuntime();
2422
2625
  const runtimeContext = import_react9.default.useContext(RuntimeContext);
@@ -2440,6 +2643,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2440
2643
  }
2441
2644
  }
2442
2645
  let runtime;
2646
+ const moduleImplResolveTraceRef = import_react9.default.useRef(void 0);
2443
2647
  if (isModuleImpl2(normalizedHandle)) {
2444
2648
  const cache = import_react9.default.useMemo(
2445
2649
  () => getModuleCache(runtimeBase, runtimeContext.reactConfigSnapshot, runtimeContext.configVersion),
@@ -2468,9 +2672,9 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2468
2672
  const key = depsHash ? `${baseKey}:${depsHash}` : baseKey;
2469
2673
  const ownerId = moduleId;
2470
2674
  const baseFactory = import_react9.default.useMemo(
2471
- () => (scope) => import_effect10.Layer.buildWithScope(normalizedHandle.layer, scope).pipe(
2675
+ () => (scope) => import_effect10.Layer.buildWithScope(import_effect10.Layer.fresh(normalizedHandle.layer), scope).pipe(
2472
2676
  import_effect10.Effect.map(
2473
- (context) => import_effect10.Context.get(context, normalizedHandle.module)
2677
+ (context) => import_effect10.ServiceMap.get(context, normalizedHandle.module)
2474
2678
  )
2475
2679
  ),
2476
2680
  [normalizedHandle]
@@ -2480,26 +2684,56 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2480
2684
  return baseFactory;
2481
2685
  }
2482
2686
  return (scope) => baseFactory(scope).pipe(
2483
- import_effect10.Effect.timeoutFail({
2484
- duration: initTimeoutMs,
2485
- onTimeout: () => new Error(`[useModule] Module "${ownerId}" initialization timed out after ${initTimeoutMs}ms`)
2486
- })
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
+ )
2487
2691
  );
2488
2692
  }, [baseFactory, suspend, initTimeoutMs, ownerId]);
2693
+ const moduleResolveStartedAt = performance.now();
2489
2694
  const moduleRuntime = suspend ? cache.read(key, factory, gcTime, ownerId, {
2490
2695
  entrypoint: "react.useModule",
2491
2696
  policyMode: runtimeContext.policy.mode,
2492
- yield: runtimeContext.policy.yield
2697
+ yield: runtimeContext.policy.yield,
2698
+ optimisticSyncBudgetMs: runtimeContext.policy.syncBudgetMs
2493
2699
  }) : cache.readSync(key, factory, gcTime, ownerId, {
2494
2700
  entrypoint: "react.useModule",
2495
2701
  policyMode: runtimeContext.policy.mode,
2496
2702
  warnSyncBlockingThresholdMs: 5
2497
2703
  });
2704
+ moduleImplResolveTraceRef.current = {
2705
+ moduleId,
2706
+ cacheMode: suspend ? "suspend" : "sync",
2707
+ durationMs: Math.round((performance.now() - moduleResolveStartedAt) * 100) / 100
2708
+ };
2498
2709
  import_react9.default.useEffect(() => cache.retain(key), [cache, key]);
2499
2710
  runtime = moduleRuntime;
2500
2711
  } else {
2501
2712
  runtime = useModuleRuntime(normalizedHandle);
2502
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]);
2503
2737
  import_react9.default.useEffect(() => {
2504
2738
  if (!isModuleImpl2(normalizedHandle)) {
2505
2739
  return;
@@ -2509,22 +2743,22 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2509
2743
  if (!label) {
2510
2744
  return;
2511
2745
  }
2512
- const effect = Logix9.Debug.record({
2746
+ const effect = Logix11.Debug.record({
2513
2747
  type: "trace:instanceLabel",
2514
2748
  moduleId: normalizedHandle.module.id,
2515
2749
  instanceId: runtime.instanceId,
2516
2750
  data: { label }
2517
2751
  });
2518
- runtimeBase.runFork(effect);
2752
+ emitRuntimeDebugEventBestEffort(runtimeBase, effect);
2519
2753
  }, [runtimeBase, runtime, normalizedHandle, options]);
2520
2754
  import_react9.default.useEffect(() => {
2521
- if (!(0, import_Env.isDevEnv)() && !Logix9.Debug.isDevtoolsEnabled()) {
2755
+ if (!(0, import_Env.isDevEnv)() && !Logix11.Debug.isDevtoolsEnabled()) {
2522
2756
  return;
2523
2757
  }
2524
2758
  if (!runtime.instanceId) {
2525
2759
  return;
2526
2760
  }
2527
- const effect = Logix9.Debug.record({
2761
+ const effect = Logix11.Debug.record({
2528
2762
  type: "trace:react-render",
2529
2763
  moduleId: runtime.moduleId,
2530
2764
  instanceId: runtime.instanceId,
@@ -2534,7 +2768,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2534
2768
  }
2535
2769
  });
2536
2770
  runtimeBase.runFork(effect);
2537
- }, [runtimeBase, runtime]);
2771
+ });
2538
2772
  if (selector) {
2539
2773
  if (isModuleImpl2(normalizedHandle)) {
2540
2774
  return useSelector(runtime, selector, equalityFn);
@@ -2621,7 +2855,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2621
2855
 
2622
2856
  // src/internal/hooks/useLocalModule.ts
2623
2857
  var import_react10 = __toESM(require("react"), 1);
2624
- var Logix10 = __toESM(require("@logixjs/core"), 1);
2858
+ var Logix12 = __toESM(require("@logixjs/core"), 1);
2625
2859
  var import_effect11 = require("effect");
2626
2860
  function isModuleTag2(source) {
2627
2861
  if (!source || typeof source !== "object" && typeof source !== "function") {
@@ -2642,7 +2876,7 @@ function useLocalModule(source, second) {
2642
2876
  );
2643
2877
  const componentId = useStableId();
2644
2878
  const moduleTag = import_react10.default.useMemo(() => {
2645
- if (Logix10.Module.is(source)) {
2879
+ if (Logix12.Module.is(source)) {
2646
2880
  return source.tag;
2647
2881
  }
2648
2882
  if (isModuleTag2(source)) {
@@ -2651,7 +2885,7 @@ function useLocalModule(source, second) {
2651
2885
  return null;
2652
2886
  }, [source]);
2653
2887
  const def = import_react10.default.useMemo(() => {
2654
- if (Logix10.Module.is(source) || isModuleTag2(source)) {
2888
+ if (Logix12.Module.is(source) || isModuleTag2(source)) {
2655
2889
  return source;
2656
2890
  }
2657
2891
  return void 0;
@@ -2679,7 +2913,7 @@ function useLocalModule(source, second) {
2679
2913
  return createModuleTagFactory(moduleTag, moduleOptions);
2680
2914
  }
2681
2915
  const factoryFn = source;
2682
- return (scope) => factoryFn().pipe(import_effect11.Scope.extend(scope));
2916
+ return (scope) => import_effect11.Scope.provide(scope)(factoryFn());
2683
2917
  }, [isModule2, moduleTag, source, moduleOptions]);
2684
2918
  const moduleRuntime = cache.readSync(key, factory, void 0, ownerId, {
2685
2919
  entrypoint: "react.useLocalModule",
@@ -2741,7 +2975,7 @@ function createModuleTagFactory(module2, options) {
2741
2975
  const logics = options.logics ?? [];
2742
2976
  return (scope) => import_effect11.Layer.buildWithScope(module2.live(options.initial, ...logics), scope).pipe(
2743
2977
  import_effect11.Effect.map((context) => {
2744
- const runtime = import_effect11.Context.get(context, module2);
2978
+ const runtime = import_effect11.ServiceMap.get(context, module2);
2745
2979
  return runtime;
2746
2980
  })
2747
2981
  );
@@ -2754,7 +2988,7 @@ function useLayerModule(module2, layer, deps = []) {
2754
2988
  const factory = import_react11.default.useCallback(
2755
2989
  () => import_effect12.Layer.build(layer).pipe(
2756
2990
  import_effect12.Effect.scoped,
2757
- import_effect12.Effect.map((context) => import_effect12.Context.get(context, module2))
2991
+ import_effect12.Effect.map((context) => import_effect12.ServiceMap.get(context, module2))
2758
2992
  ),
2759
2993
  // layer/module are typically constants; deps lets callers opt into rebuilding when needed.
2760
2994
  [layer, module2]
@@ -2812,7 +3046,7 @@ function useImportedModule(parent, module2) {
2812
3046
  // src/internal/hooks/useProcesses.ts
2813
3047
  var import_react15 = __toESM(require("react"), 1);
2814
3048
  var import_effect13 = require("effect");
2815
- var Logix11 = __toESM(require("@logixjs/core"), 1);
3049
+ var Logix13 = __toESM(require("@logixjs/core"), 1);
2816
3050
  var ProcessSubtreeRegistry = class {
2817
3051
  constructor(runtime) {
2818
3052
  this.runtime = runtime;
@@ -2878,7 +3112,7 @@ var getRegistry = (runtime) => {
2878
3112
  var stableProcessSignature = (processes) => {
2879
3113
  const ids = [];
2880
3114
  for (let i = 0; i < processes.length; i++) {
2881
- const def = Logix11.Process.getDefinition(processes[i]);
3115
+ const def = Logix13.Process.getDefinition(processes[i]);
2882
3116
  ids.push(def?.processId ?? `legacy#${i}`);
2883
3117
  }
2884
3118
  return ids.join("|");
@@ -2923,7 +3157,7 @@ function useProcesses(processes, options) {
2923
3157
  install: (scope) => {
2924
3158
  const program = import_effect13.Effect.forEach(
2925
3159
  processes,
2926
- (process) => Logix11.InternalContracts.installProcess(process, {
3160
+ (process) => Logix13.InternalContracts.installProcess(process, {
2927
3161
  scope: { type: "uiSubtree", subtreeId },
2928
3162
  enabled: true,
2929
3163
  installedAt: "uiSubtree",
@@ -2935,7 +3169,7 @@ function useProcesses(processes, options) {
2935
3169
  }
2936
3170
  return import_effect13.Effect.forkScoped(process).pipe(import_effect13.Effect.asVoid);
2937
3171
  }),
2938
- import_effect13.Effect.catchAll(() => import_effect13.Effect.forkScoped(process).pipe(import_effect13.Effect.asVoid))
3172
+ import_effect13.Effect.catch(() => import_effect13.Effect.forkScoped(process).pipe(import_effect13.Effect.asVoid))
2939
3173
  ),
2940
3174
  { discard: true }
2941
3175
  ).pipe(import_effect13.Effect.provideService(import_effect13.Scope.Scope, scope));
@@ -2972,10 +3206,7 @@ var makeReactPlatform = import_effect14.Effect.gen(function* () {
2972
3206
  const resetRef = yield* import_effect14.Ref.make([]);
2973
3207
  return new ReactPlatformImpl(suspendRef, resumeRef, resetRef);
2974
3208
  });
2975
- var ReactPlatformLayer = import_effect14.Layer.scoped(
2976
- import_core.Platform.tag,
2977
- makeReactPlatform
2978
- );
3209
+ var ReactPlatformLayer = import_effect14.Layer.effect(import_core.Platform.tag, makeReactPlatform);
2979
3210
 
2980
3211
  // src/ReactPlatform.ts
2981
3212
  var import_react16 = __toESM(require("react"), 1);
@@ -3018,16 +3249,19 @@ var ReactPlatform = {
3018
3249
 
3019
3250
  // src/ModuleScope.ts
3020
3251
  var import_react17 = __toESM(require("react"), 1);
3021
- var Logix12 = __toESM(require("@logixjs/core"), 1);
3252
+ var import_effect15 = require("effect");
3253
+ var Logix14 = __toESM(require("@logixjs/core"), 1);
3022
3254
  var makeModuleScope = (handle, defaults) => {
3023
- const Context7 = import_react17.default.createContext(null);
3255
+ const Context = import_react17.default.createContext(null);
3024
3256
  const toUseModuleOptions = (options) => {
3025
3257
  const { scopeId, ...rest } = options;
3026
3258
  return scopeId != null ? { ...rest, key: scopeId } : rest;
3027
3259
  };
3028
3260
  const getRegistryOrThrow = (runtime, where) => {
3029
3261
  try {
3030
- const registry = runtime.runSync(Logix12.ScopeRegistry.ScopeRegistryTag);
3262
+ const registry = runtime.runSync(
3263
+ import_effect15.Effect.service(Logix14.ScopeRegistry.ScopeRegistryTag).pipe(import_effect15.Effect.orDie)
3264
+ );
3031
3265
  if (!registry) {
3032
3266
  throw new Error("ScopeRegistry service is undefined");
3033
3267
  }
@@ -3038,7 +3272,7 @@ var makeModuleScope = (handle, defaults) => {
3038
3272
  );
3039
3273
  }
3040
3274
  };
3041
- const moduleToken = Logix12.Module.hasImpl(handle) ? handle.tag : handle.module;
3275
+ const moduleToken = Logix14.Module.hasImpl(handle) ? handle.tag : handle.module;
3042
3276
  const Provider = ({ children, options }) => {
3043
3277
  const runtime = useRuntime();
3044
3278
  const merged = defaults || options ? { ...defaults ?? {}, ...options ?? {} } : void 0;
@@ -3047,17 +3281,17 @@ var makeModuleScope = (handle, defaults) => {
3047
3281
  import_react17.default.useEffect(() => {
3048
3282
  if (!scopeId) return;
3049
3283
  const registry = getRegistryOrThrow(runtime, "[ModuleScope]");
3050
- const leaseRuntime = registry.register(scopeId, Logix12.ScopeRegistry.ScopedRuntimeTag, runtime);
3284
+ const leaseRuntime = registry.register(scopeId, Logix14.ScopeRegistry.ScopedRuntimeTag, runtime);
3051
3285
  const leaseModule = registry.register(scopeId, moduleToken, ref.runtime);
3052
3286
  return () => {
3053
3287
  leaseModule.release();
3054
3288
  leaseRuntime.release();
3055
3289
  };
3056
3290
  }, [runtime, scopeId, ref.runtime]);
3057
- return import_react17.default.createElement(Context7.Provider, { value: ref }, children);
3291
+ return import_react17.default.createElement(Context.Provider, { value: ref }, children);
3058
3292
  };
3059
3293
  const use = () => {
3060
- const ref = import_react17.default.useContext(Context7);
3294
+ const ref = import_react17.default.useContext(Context);
3061
3295
  if (!ref) {
3062
3296
  throw new Error("[ModuleScope] Provider not found");
3063
3297
  }
@@ -3070,11 +3304,8 @@ var makeModuleScope = (handle, defaults) => {
3070
3304
  const Bridge = ({ scopeId, children }) => {
3071
3305
  const runtime = useRuntime();
3072
3306
  const registry = getRegistryOrThrow(runtime, "[ModuleScope.Bridge]");
3073
- const scopedRuntime = registry.get(scopeId, Logix12.ScopeRegistry.ScopedRuntimeTag);
3074
- const moduleRuntime = registry.get(
3075
- scopeId,
3076
- moduleToken
3077
- );
3307
+ const scopedRuntime = registry.get(scopeId, Logix14.ScopeRegistry.ScopedRuntimeTag);
3308
+ const moduleRuntime = registry.get(scopeId, moduleToken);
3078
3309
  if (!scopedRuntime || !moduleRuntime) {
3079
3310
  throw new Error(
3080
3311
  `[ModuleScope.Bridge] Scope "${scopeId}" is not registered (or has been disposed). Ensure you have a corresponding <ModuleScope.Provider options={{ scopeId }}> mounted.`
@@ -3083,18 +3314,18 @@ var makeModuleScope = (handle, defaults) => {
3083
3314
  return import_react17.default.createElement(
3084
3315
  RuntimeProvider,
3085
3316
  { runtime: scopedRuntime },
3086
- import_react17.default.createElement(BridgeInner, { moduleRuntime, Context: Context7 }, children)
3317
+ import_react17.default.createElement(BridgeInner, { moduleRuntime, Context }, children)
3087
3318
  );
3088
3319
  };
3089
3320
  const BridgeInner = ({
3090
3321
  moduleRuntime,
3091
- Context: Context8,
3322
+ Context: Context2,
3092
3323
  children
3093
3324
  }) => {
3094
3325
  const ref = useModule(moduleRuntime);
3095
- return import_react17.default.createElement(Context8.Provider, { value: ref }, children);
3326
+ return import_react17.default.createElement(Context2.Provider, { value: ref }, children);
3096
3327
  };
3097
- return { Provider, use, useImported, Context: Context7, Bridge };
3328
+ return { Provider, use, useImported, Context, Bridge };
3098
3329
  };
3099
3330
  var ModuleScope = {
3100
3331
  make: makeModuleScope