@logixjs/react 0.1.0 → 0.1.1

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
@@ -1292,6 +1292,20 @@ var RuntimeProvider = ({
1292
1292
  );
1293
1293
  const onErrorRef = import_react4.default.useRef(onError);
1294
1294
  onErrorRef.current = onError;
1295
+ const hasTickServices = (0, import_react4.useMemo)(() => {
1296
+ try {
1297
+ Logix5.InternalContracts.getRuntimeStore(baseRuntime);
1298
+ return true;
1299
+ } catch {
1300
+ return false;
1301
+ }
1302
+ }, [baseRuntime]);
1303
+ const { binding: tickBinding } = useLayerBinding(
1304
+ baseRuntime,
1305
+ Logix5.InternalContracts.tickServicesLayer,
1306
+ !hasTickServices,
1307
+ onErrorRef.current
1308
+ );
1295
1309
  const { binding: layerBinding } = useLayerBinding(baseRuntime, layer, Boolean(layer), onErrorRef.current);
1296
1310
  const onErrorSink = (0, import_react4.useMemo)(() => {
1297
1311
  if (!onError) return null;
@@ -1350,17 +1364,17 @@ var RuntimeProvider = ({
1350
1364
  }
1351
1365
  }, [baseRuntime, layerBinding, onErrorSink]);
1352
1366
  const runtimeWithBindings = (0, import_react4.useMemo)(
1353
- () => layerBinding || onErrorSink ? createRuntimeAdapter(
1367
+ () => tickBinding || layerBinding || onErrorSink ? createRuntimeAdapter(
1354
1368
  baseRuntime,
1355
- layerBinding ? [layerBinding.context] : [],
1356
- layerBinding ? [layerBinding.scope] : [],
1357
- layerBinding ? [layerBinding.loggers] : [],
1358
- layerBinding ? [layerBinding.logLevel] : [],
1369
+ [...tickBinding ? [tickBinding.context] : [], ...layerBinding ? [layerBinding.context] : []],
1370
+ [...tickBinding ? [tickBinding.scope] : [], ...layerBinding ? [layerBinding.scope] : []],
1371
+ layerBinding ? [layerBinding.loggers] : tickBinding ? [tickBinding.loggers] : [],
1372
+ layerBinding ? [layerBinding.logLevel] : tickBinding ? [tickBinding.logLevel] : [],
1359
1373
  [
1360
1374
  onErrorSink ? [onErrorSink, ...inheritedDebugSinks] : layerBinding ? layerBinding.debugSinks : []
1361
1375
  ]
1362
1376
  ) : baseRuntime,
1363
- [baseRuntime, inheritedDebugSinks, layerBinding, onErrorSink]
1377
+ [baseRuntime, inheritedDebugSinks, layerBinding, onErrorSink, tickBinding]
1364
1378
  );
1365
1379
  const didReportSyncConfigSnapshotRef = import_react4.default.useRef(false);
1366
1380
  const [configState, setConfigState] = (0, import_react4.useState)(() => {
@@ -1465,6 +1479,7 @@ var RuntimeProvider = ({
1465
1479
  }),
1466
1480
  [runtimeWithBindings, configState, resolvedPolicy]
1467
1481
  );
1482
+ const isTickServicesReady = hasTickServices || tickBinding !== null;
1468
1483
  const isLayerReady = !layer || layerBinding !== null;
1469
1484
  const isConfigReady = configState.loaded;
1470
1485
  const resolveFallback = (phase) => {
@@ -1619,9 +1634,10 @@ var RuntimeProvider = ({
1619
1634
  release();
1620
1635
  };
1621
1636
  }, [resolvedPolicy.mode, deferReady]);
1622
- const isReady = isLayerReady && isConfigReady && (resolvedPolicy.mode !== "defer" || deferReady);
1637
+ const isReady = isTickServicesReady && isLayerReady && isConfigReady && (resolvedPolicy.mode !== "defer" || deferReady);
1623
1638
  if (!isReady) {
1624
1639
  const blockersList = [
1640
+ isTickServicesReady ? null : "tick",
1625
1641
  isLayerReady ? null : "layer",
1626
1642
  isConfigReady ? null : "config",
1627
1643
  resolvedPolicy.mode !== "defer" || deferReady ? null : "preload"
@@ -1737,8 +1753,8 @@ function useRuntime(options) {
1737
1753
 
1738
1754
  // src/internal/hooks/useModule.ts
1739
1755
  var import_react9 = __toESM(require("react"), 1);
1740
- var Logix9 = __toESM(require("@logixjs/core"), 1);
1741
- var import_effect10 = require("effect");
1756
+ var Logix10 = __toESM(require("@logixjs/core"), 1);
1757
+ var import_effect9 = require("effect");
1742
1758
 
1743
1759
  // src/internal/hooks/useModuleRuntime.ts
1744
1760
  var import_react6 = require("react");
@@ -1896,55 +1912,71 @@ function useModuleRuntime(handle) {
1896
1912
  // src/internal/hooks/useSelector.ts
1897
1913
  var import_react7 = require("react");
1898
1914
  var import_with_selector = require("use-sync-external-store/shim/with-selector");
1899
- var Logix7 = __toESM(require("@logixjs/core"), 1);
1915
+ var Logix8 = __toESM(require("@logixjs/core"), 1);
1900
1916
 
1901
- // src/internal/store/ModuleRuntimeExternalStore.ts
1917
+ // src/internal/store/RuntimeExternalStore.ts
1918
+ var Logix7 = __toESM(require("@logixjs/core"), 1);
1902
1919
  var import_effect8 = require("effect");
1903
1920
  var storesByRuntime = /* @__PURE__ */ new WeakMap();
1904
1921
  var getStoreMapForRuntime = (runtime) => {
1905
1922
  const cached = storesByRuntime.get(runtime);
1906
1923
  if (cached) return cached;
1907
- const next = /* @__PURE__ */ new WeakMap();
1924
+ const next = /* @__PURE__ */ new Map();
1908
1925
  storesByRuntime.set(runtime, next);
1909
1926
  return next;
1910
1927
  };
1911
- var getModuleRuntimeExternalStore = (runtime, moduleRuntime, options) => {
1912
- const byModule = getStoreMapForRuntime(runtime);
1913
- const cached = byModule.get(moduleRuntime);
1928
+ var makeModuleInstanceKey = (moduleId, instanceId) => `${moduleId}::${instanceId}`;
1929
+ var makeReadQueryTopicKey = (moduleInstanceKey, selectorId) => `${moduleInstanceKey}::rq:${selectorId}`;
1930
+ var getRuntimeStore = (runtime) => Logix7.InternalContracts.getRuntimeStore(runtime);
1931
+ var getHostScheduler = (runtime) => Logix7.InternalContracts.getHostScheduler(runtime);
1932
+ var getOrCreateStore = (runtime, topicKey, make) => {
1933
+ const map = getStoreMapForRuntime(runtime);
1934
+ const cached = map.get(topicKey);
1914
1935
  if (cached) {
1915
1936
  return cached;
1916
1937
  }
1917
- let currentState;
1938
+ const created = make();
1939
+ map.set(topicKey, created);
1940
+ return created;
1941
+ };
1942
+ var removeStore = (runtime, topicKey) => {
1943
+ const map = storesByRuntime.get(runtime);
1944
+ if (!map) return;
1945
+ map.delete(topicKey);
1946
+ };
1947
+ var makeTopicExternalStore = (args) => {
1948
+ const { runtime, runtimeStore, topicKey } = args;
1949
+ const hostScheduler = getHostScheduler(runtime);
1950
+ let currentVersion;
1951
+ let hasSnapshot = false;
1952
+ let currentSnapshot;
1918
1953
  const listeners = /* @__PURE__ */ new Set();
1919
- const lowPriorityDelayMs = options?.lowPriorityDelayMs ?? 16;
1920
- const lowPriorityMaxDelayMs = options?.lowPriorityMaxDelayMs ?? 50;
1954
+ let unsubscribeFromRuntimeStore;
1955
+ const lowPriorityDelayMs = args.options?.lowPriorityDelayMs ?? 16;
1956
+ const lowPriorityMaxDelayMs = args.options?.lowPriorityMaxDelayMs ?? 50;
1921
1957
  let notifyScheduled = false;
1922
1958
  let notifyScheduledLow = false;
1923
- let lowTimeoutId;
1924
- let lowMaxTimeoutId;
1925
- let lowRafId;
1959
+ let lowCancelDelay;
1960
+ let lowCancelMaxDelay;
1961
+ let lowCancelRaf;
1926
1962
  const cancelLow = () => {
1927
1963
  if (!notifyScheduledLow) return;
1928
1964
  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
- }
1965
+ lowCancelDelay?.();
1966
+ lowCancelDelay = void 0;
1967
+ lowCancelMaxDelay?.();
1968
+ lowCancelMaxDelay = void 0;
1969
+ lowCancelRaf?.();
1970
+ lowCancelRaf = void 0;
1942
1971
  };
1943
1972
  const flushNotify = () => {
1944
1973
  notifyScheduled = false;
1945
1974
  cancelLow();
1946
1975
  for (const listener of listeners) {
1947
- listener();
1976
+ try {
1977
+ listener();
1978
+ } catch {
1979
+ }
1948
1980
  }
1949
1981
  };
1950
1982
  const scheduleNotify = (priority) => {
@@ -1956,72 +1988,135 @@ var getModuleRuntimeExternalStore = (runtime, moduleRuntime, options) => {
1956
1988
  if (!notifyScheduledLow) return;
1957
1989
  flushNotify();
1958
1990
  };
1959
- const raf = globalThis.requestAnimationFrame;
1960
- if (raf) {
1961
- lowRafId = raf(flush);
1991
+ const scheduleRaf = () => {
1992
+ if (!notifyScheduledLow) return;
1993
+ lowCancelRaf = hostScheduler.scheduleAnimationFrame(flush);
1994
+ };
1995
+ if (lowPriorityDelayMs <= 0) {
1996
+ scheduleRaf();
1962
1997
  } else {
1963
- lowTimeoutId = setTimeout(flush, lowPriorityDelayMs);
1998
+ lowCancelDelay = hostScheduler.scheduleTimeout(lowPriorityDelayMs, scheduleRaf);
1964
1999
  }
1965
- lowMaxTimeoutId = setTimeout(flush, lowPriorityMaxDelayMs);
2000
+ lowCancelMaxDelay = hostScheduler.scheduleTimeout(lowPriorityMaxDelayMs, flush);
1966
2001
  return;
1967
2002
  }
1968
2003
  cancelLow();
1969
2004
  if (notifyScheduled) return;
1970
2005
  notifyScheduled = true;
1971
- queueMicrotask(flushNotify);
2006
+ hostScheduler.scheduleMicrotask(flushNotify);
2007
+ };
2008
+ const onRuntimeStoreChange = () => {
2009
+ try {
2010
+ scheduleNotify(runtimeStore.getTopicPriority(topicKey));
2011
+ } catch {
2012
+ }
1972
2013
  };
1973
- let fiber;
1974
2014
  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
- );
2015
+ if (unsubscribeFromRuntimeStore) return;
2016
+ unsubscribeFromRuntimeStore = runtimeStore.subscribeTopic(topicKey, onRuntimeStoreChange);
1985
2017
  };
1986
2018
  const refreshSnapshotIfStale = () => {
1987
- if (currentState === void 0) {
1988
- return;
1989
- }
2019
+ if (!hasSnapshot) return;
1990
2020
  try {
1991
- const latest = runtime.runSync(moduleRuntime.getState);
1992
- if (currentState === void 0 || !Object.is(currentState, latest)) {
1993
- currentState = latest;
1994
- scheduleNotify("normal");
2021
+ const version = runtimeStore.getTopicVersion(topicKey);
2022
+ if (currentVersion !== version) {
2023
+ scheduleNotify(runtimeStore.getTopicPriority(topicKey));
1995
2024
  }
1996
2025
  } catch {
1997
2026
  }
1998
2027
  };
1999
2028
  const getSnapshot = () => {
2000
- if (currentState !== void 0) return currentState;
2001
- currentState = runtime.runSync(moduleRuntime.getState);
2002
- return currentState;
2029
+ const version = runtimeStore.getTopicVersion(topicKey);
2030
+ if (hasSnapshot && currentVersion === version) {
2031
+ return currentSnapshot;
2032
+ }
2033
+ const next = args.readSnapshot();
2034
+ currentVersion = version;
2035
+ hasSnapshot = true;
2036
+ currentSnapshot = next;
2037
+ return next;
2003
2038
  };
2004
2039
  const subscribe = (listener) => {
2040
+ const isFirst = listeners.size === 0;
2005
2041
  listeners.add(listener);
2006
2042
  ensureSubscription();
2007
2043
  refreshSnapshotIfStale();
2044
+ if (isFirst) {
2045
+ try {
2046
+ args.onFirstListener?.();
2047
+ } catch {
2048
+ }
2049
+ }
2008
2050
  return () => {
2009
2051
  listeners.delete(listener);
2010
2052
  if (listeners.size > 0) return;
2011
- const running = fiber;
2012
- if (!running) return;
2013
- fiber = void 0;
2053
+ try {
2054
+ args.onLastListener?.();
2055
+ } catch {
2056
+ }
2057
+ const unsub = unsubscribeFromRuntimeStore;
2058
+ unsubscribeFromRuntimeStore = void 0;
2014
2059
  cancelLow();
2015
- runtime.runFork(import_effect8.Fiber.interrupt(running));
2060
+ try {
2061
+ unsub?.();
2062
+ } catch {
2063
+ }
2064
+ removeStore(runtime, topicKey);
2016
2065
  };
2017
2066
  };
2018
- const store = { getSnapshot, subscribe };
2019
- byModule.set(moduleRuntime, store);
2020
- return store;
2067
+ return { getSnapshot, getServerSnapshot: getSnapshot, subscribe };
2068
+ };
2069
+ var getRuntimeModuleExternalStore = (runtime, moduleRuntime, options) => {
2070
+ const moduleInstanceKey = makeModuleInstanceKey(moduleRuntime.moduleId, moduleRuntime.instanceId);
2071
+ const runtimeStore = getRuntimeStore(runtime);
2072
+ return getOrCreateStore(
2073
+ runtime,
2074
+ moduleInstanceKey,
2075
+ () => makeTopicExternalStore({
2076
+ runtime,
2077
+ runtimeStore,
2078
+ topicKey: moduleInstanceKey,
2079
+ readSnapshot: () => {
2080
+ const state = runtimeStore.getModuleState(moduleInstanceKey);
2081
+ if (state !== void 0) return state;
2082
+ return runtime.runSync(moduleRuntime.getState);
2083
+ },
2084
+ options
2085
+ })
2086
+ );
2087
+ };
2088
+ var getRuntimeReadQueryExternalStore = (runtime, moduleRuntime, selectorReadQuery, options) => {
2089
+ const moduleInstanceKey = makeModuleInstanceKey(moduleRuntime.moduleId, moduleRuntime.instanceId);
2090
+ const topicKey = makeReadQueryTopicKey(moduleInstanceKey, selectorReadQuery.selectorId);
2091
+ const runtimeStore = getRuntimeStore(runtime);
2092
+ let readQueryDrainFiber;
2093
+ return getOrCreateStore(
2094
+ runtime,
2095
+ topicKey,
2096
+ () => makeTopicExternalStore({
2097
+ runtime,
2098
+ runtimeStore,
2099
+ topicKey,
2100
+ readSnapshot: () => {
2101
+ const state = runtimeStore.getModuleState(moduleInstanceKey);
2102
+ const current = state ?? runtime.runSync(moduleRuntime.getState);
2103
+ return selectorReadQuery.select(current);
2104
+ },
2105
+ options,
2106
+ onFirstListener: () => {
2107
+ if (readQueryDrainFiber) return;
2108
+ const effect = import_effect8.Stream.runDrain(moduleRuntime.changesReadQueryWithMeta(selectorReadQuery));
2109
+ readQueryDrainFiber = runtime.runFork(effect);
2110
+ },
2111
+ onLastListener: () => {
2112
+ const fiber = readQueryDrainFiber;
2113
+ if (!fiber) return;
2114
+ readQueryDrainFiber = void 0;
2115
+ runtime.runFork(import_effect8.Fiber.interrupt(fiber));
2116
+ }
2117
+ })
2118
+ );
2021
2119
  };
2022
-
2023
- // src/internal/store/ModuleRuntimeSelectorExternalStore.ts
2024
- var import_effect9 = require("effect");
2025
2120
 
2026
2121
  // src/internal/hooks/shallow.ts
2027
2122
  var hasObjectShape = (value) => typeof value === "object" && value !== null;
@@ -2073,146 +2168,6 @@ var shallow = (previous, next) => {
2073
2168
  return true;
2074
2169
  };
2075
2170
 
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
2171
  // src/internal/hooks/useSelector.ts
2217
2172
  function useSelector(handle, selector, equalityFn) {
2218
2173
  const runtimeContext = (0, import_react7.useContext)(RuntimeContext);
@@ -2223,7 +2178,7 @@ function useSelector(handle, selector, equalityFn) {
2223
2178
  const moduleRuntime = useModuleRuntime(handle);
2224
2179
  const actualSelector = selector ?? ((state) => state);
2225
2180
  const selectorReadQuery = (0, import_react7.useMemo)(
2226
- () => typeof selector === "function" ? Logix7.ReadQuery.compile(selector) : void 0,
2181
+ () => typeof selector === "function" ? Logix8.ReadQuery.compile(selector) : void 0,
2227
2182
  [selector]
2228
2183
  );
2229
2184
  const actualEqualityFn = (0, import_react7.useMemo)(() => {
@@ -2231,17 +2186,12 @@ function useSelector(handle, selector, equalityFn) {
2231
2186
  if (typeof selector !== "function") return Object.is;
2232
2187
  return selectorReadQuery?.equalsKind === "shallowStruct" ? shallow : Object.is;
2233
2188
  }, [equalityFn, selector, selectorReadQuery?.equalsKind]);
2234
- const useStaticLane = typeof selector === "function" && selectorReadQuery?.lane === "static";
2189
+ const selectorTopicEligible = typeof selector === "function" && selectorReadQuery?.lane === "static" && selectorReadQuery.readsDigest != null && selectorReadQuery.fallbackReason == null;
2235
2190
  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(
2191
+ () => selectorTopicEligible && selectorReadQuery ? getRuntimeReadQueryExternalStore(runtime, moduleRuntime, selectorReadQuery, {
2192
+ lowPriorityDelayMs: runtimeContext.reactConfigSnapshot.lowPriorityDelayMs,
2193
+ lowPriorityMaxDelayMs: runtimeContext.reactConfigSnapshot.lowPriorityMaxDelayMs
2194
+ }) : getRuntimeModuleExternalStore(
2245
2195
  runtime,
2246
2196
  moduleRuntime,
2247
2197
  {
@@ -2255,18 +2205,18 @@ function useSelector(handle, selector, equalityFn) {
2255
2205
  runtimeContext.reactConfigSnapshot.lowPriorityDelayMs,
2256
2206
  runtimeContext.reactConfigSnapshot.lowPriorityMaxDelayMs,
2257
2207
  selectorReadQuery,
2258
- useStaticLane
2208
+ selectorTopicEligible
2259
2209
  ]
2260
2210
  );
2261
2211
  const selected = (0, import_with_selector.useSyncExternalStoreWithSelector)(
2262
2212
  store.subscribe,
2263
2213
  store.getSnapshot,
2264
- store.getSnapshot,
2265
- useStaticLane ? (snapshot) => snapshot : (snapshot) => actualSelector(snapshot),
2214
+ store.getServerSnapshot ?? store.getSnapshot,
2215
+ selectorTopicEligible ? (snapshot) => snapshot : (snapshot) => actualSelector(snapshot),
2266
2216
  actualEqualityFn
2267
2217
  );
2268
2218
  (0, import_react7.useEffect)(() => {
2269
- if (!(0, import_Env.isDevEnv)() && !Logix7.Debug.isDevtoolsEnabled()) {
2219
+ if (!(0, import_Env.isDevEnv)() && !Logix8.Debug.isDevtoolsEnabled()) {
2270
2220
  return;
2271
2221
  }
2272
2222
  const instanceId = moduleRuntime.instanceId;
@@ -2282,7 +2232,7 @@ function useSelector(handle, selector, equalityFn) {
2282
2232
  const rawDebugKey = meta.debugKey;
2283
2233
  selectorKey = typeof rawDebugKey === "string" && rawDebugKey.length > 0 ? rawDebugKey : typeof selector.name === "string" && selector.name.length > 0 ? selector.name : void 0;
2284
2234
  }
2285
- const effect = Logix7.Debug.record({
2235
+ const effect = Logix8.Debug.record({
2286
2236
  type: "trace:react-selector",
2287
2237
  moduleId: moduleRuntime.moduleId,
2288
2238
  instanceId,
@@ -2305,7 +2255,7 @@ function useSelector(handle, selector, equalityFn) {
2305
2255
  }
2306
2256
 
2307
2257
  // src/internal/store/resolveImportedModuleRef.ts
2308
- var Logix8 = __toESM(require("@logixjs/core"), 1);
2258
+ var Logix9 = __toESM(require("@logixjs/core"), 1);
2309
2259
  var getOrCreateWeakMap = (map, key, make) => {
2310
2260
  const cached = map.get(key);
2311
2261
  if (cached) return cached;
@@ -2329,7 +2279,7 @@ var resolveImportedModuleRef = (runtime, parentRuntime, module2) => {
2329
2279
  if (cached) {
2330
2280
  return cached;
2331
2281
  }
2332
- const importsScope = Logix8.InternalContracts.getImportsScope(parentRuntime);
2282
+ const importsScope = Logix9.InternalContracts.getImportsScope(parentRuntime);
2333
2283
  const childRuntime = importsScope.get(module2);
2334
2284
  if (childRuntime) {
2335
2285
  const dispatch = Object.assign(
@@ -2415,8 +2365,8 @@ var useStableId = () => {
2415
2365
 
2416
2366
  // src/internal/hooks/useModule.ts
2417
2367
  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";
2368
+ var isModule = (handle) => Logix10.Module.hasImpl(handle);
2369
+ var isModuleDef = (handle) => Logix10.Module.is(handle) && handle._kind === "ModuleDef";
2420
2370
  function useModule(handle, selectorOrOptions, equalityFn) {
2421
2371
  const runtimeBase = useRuntime();
2422
2372
  const runtimeContext = import_react9.default.useContext(RuntimeContext);
@@ -2468,9 +2418,9 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2468
2418
  const key = depsHash ? `${baseKey}:${depsHash}` : baseKey;
2469
2419
  const ownerId = moduleId;
2470
2420
  const baseFactory = import_react9.default.useMemo(
2471
- () => (scope) => import_effect10.Layer.buildWithScope(normalizedHandle.layer, scope).pipe(
2472
- import_effect10.Effect.map(
2473
- (context) => import_effect10.Context.get(context, normalizedHandle.module)
2421
+ () => (scope) => import_effect9.Layer.buildWithScope(normalizedHandle.layer, scope).pipe(
2422
+ import_effect9.Effect.map(
2423
+ (context) => import_effect9.Context.get(context, normalizedHandle.module)
2474
2424
  )
2475
2425
  ),
2476
2426
  [normalizedHandle]
@@ -2480,7 +2430,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2480
2430
  return baseFactory;
2481
2431
  }
2482
2432
  return (scope) => baseFactory(scope).pipe(
2483
- import_effect10.Effect.timeoutFail({
2433
+ import_effect9.Effect.timeoutFail({
2484
2434
  duration: initTimeoutMs,
2485
2435
  onTimeout: () => new Error(`[useModule] Module "${ownerId}" initialization timed out after ${initTimeoutMs}ms`)
2486
2436
  })
@@ -2509,7 +2459,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2509
2459
  if (!label) {
2510
2460
  return;
2511
2461
  }
2512
- const effect = Logix9.Debug.record({
2462
+ const effect = Logix10.Debug.record({
2513
2463
  type: "trace:instanceLabel",
2514
2464
  moduleId: normalizedHandle.module.id,
2515
2465
  instanceId: runtime.instanceId,
@@ -2518,13 +2468,13 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2518
2468
  runtimeBase.runFork(effect);
2519
2469
  }, [runtimeBase, runtime, normalizedHandle, options]);
2520
2470
  import_react9.default.useEffect(() => {
2521
- if (!(0, import_Env.isDevEnv)() && !Logix9.Debug.isDevtoolsEnabled()) {
2471
+ if (!(0, import_Env.isDevEnv)() && !Logix10.Debug.isDevtoolsEnabled()) {
2522
2472
  return;
2523
2473
  }
2524
2474
  if (!runtime.instanceId) {
2525
2475
  return;
2526
2476
  }
2527
- const effect = Logix9.Debug.record({
2477
+ const effect = Logix10.Debug.record({
2528
2478
  type: "trace:react-render",
2529
2479
  moduleId: runtime.moduleId,
2530
2480
  instanceId: runtime.instanceId,
@@ -2621,8 +2571,8 @@ function useModule(handle, selectorOrOptions, equalityFn) {
2621
2571
 
2622
2572
  // src/internal/hooks/useLocalModule.ts
2623
2573
  var import_react10 = __toESM(require("react"), 1);
2624
- var Logix10 = __toESM(require("@logixjs/core"), 1);
2625
- var import_effect11 = require("effect");
2574
+ var Logix11 = __toESM(require("@logixjs/core"), 1);
2575
+ var import_effect10 = require("effect");
2626
2576
  function isModuleTag2(source) {
2627
2577
  if (!source || typeof source !== "object" && typeof source !== "function") {
2628
2578
  return false;
@@ -2642,7 +2592,7 @@ function useLocalModule(source, second) {
2642
2592
  );
2643
2593
  const componentId = useStableId();
2644
2594
  const moduleTag = import_react10.default.useMemo(() => {
2645
- if (Logix10.Module.is(source)) {
2595
+ if (Logix11.Module.is(source)) {
2646
2596
  return source.tag;
2647
2597
  }
2648
2598
  if (isModuleTag2(source)) {
@@ -2651,7 +2601,7 @@ function useLocalModule(source, second) {
2651
2601
  return null;
2652
2602
  }, [source]);
2653
2603
  const def = import_react10.default.useMemo(() => {
2654
- if (Logix10.Module.is(source) || isModuleTag2(source)) {
2604
+ if (Logix11.Module.is(source) || isModuleTag2(source)) {
2655
2605
  return source;
2656
2606
  }
2657
2607
  return void 0;
@@ -2679,7 +2629,7 @@ function useLocalModule(source, second) {
2679
2629
  return createModuleTagFactory(moduleTag, moduleOptions);
2680
2630
  }
2681
2631
  const factoryFn = source;
2682
- return (scope) => factoryFn().pipe(import_effect11.Scope.extend(scope));
2632
+ return (scope) => factoryFn().pipe(import_effect10.Scope.extend(scope));
2683
2633
  }, [isModule2, moduleTag, source, moduleOptions]);
2684
2634
  const moduleRuntime = cache.readSync(key, factory, void 0, ownerId, {
2685
2635
  entrypoint: "react.useLocalModule",
@@ -2739,9 +2689,9 @@ function createModuleTagFactory(module2, options) {
2739
2689
  throw new Error("useLocalModule(module, options) \u9700\u8981\u63D0\u4F9B initial \u72B6\u6001");
2740
2690
  }
2741
2691
  const logics = options.logics ?? [];
2742
- return (scope) => import_effect11.Layer.buildWithScope(module2.live(options.initial, ...logics), scope).pipe(
2743
- import_effect11.Effect.map((context) => {
2744
- const runtime = import_effect11.Context.get(context, module2);
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);
2745
2695
  return runtime;
2746
2696
  })
2747
2697
  );
@@ -2749,12 +2699,12 @@ function createModuleTagFactory(module2, options) {
2749
2699
 
2750
2700
  // src/internal/hooks/useLayerModule.ts
2751
2701
  var import_react11 = __toESM(require("react"), 1);
2752
- var import_effect12 = require("effect");
2702
+ var import_effect11 = require("effect");
2753
2703
  function useLayerModule(module2, layer, deps = []) {
2754
2704
  const factory = import_react11.default.useCallback(
2755
- () => import_effect12.Layer.build(layer).pipe(
2756
- import_effect12.Effect.scoped,
2757
- import_effect12.Effect.map((context) => import_effect12.Context.get(context, module2))
2705
+ () => import_effect11.Layer.build(layer).pipe(
2706
+ import_effect11.Effect.scoped,
2707
+ import_effect11.Effect.map((context) => import_effect11.Context.get(context, module2))
2758
2708
  ),
2759
2709
  // layer/module are typically constants; deps lets callers opt into rebuilding when needed.
2760
2710
  [layer, module2]
@@ -2811,8 +2761,8 @@ function useImportedModule(parent, module2) {
2811
2761
 
2812
2762
  // src/internal/hooks/useProcesses.ts
2813
2763
  var import_react15 = __toESM(require("react"), 1);
2814
- var import_effect13 = require("effect");
2815
- var Logix11 = __toESM(require("@logixjs/core"), 1);
2764
+ var import_effect12 = require("effect");
2765
+ var Logix12 = __toESM(require("@logixjs/core"), 1);
2816
2766
  var ProcessSubtreeRegistry = class {
2817
2767
  constructor(runtime) {
2818
2768
  this.runtime = runtime;
@@ -2833,7 +2783,7 @@ var ProcessSubtreeRegistry = class {
2833
2783
  }
2834
2784
  return () => this.release({ key: args.key, gcTime: args.gcTime });
2835
2785
  }
2836
- const scope = import_effect13.Effect.runSync(import_effect13.Scope.make());
2786
+ const scope = import_effect12.Effect.runSync(import_effect12.Scope.make());
2837
2787
  const entry = {
2838
2788
  key: args.key,
2839
2789
  signature: args.signature,
@@ -2861,7 +2811,7 @@ var ProcessSubtreeRegistry = class {
2861
2811
  const current = this.entries.get(entry.key);
2862
2812
  if (!current || current !== entry) return;
2863
2813
  if (current.refCount > 0) return;
2864
- void this.runtime.runPromise(import_effect13.Scope.close(entry.scope, import_effect13.Exit.void)).catch(() => {
2814
+ void this.runtime.runPromise(import_effect12.Scope.close(entry.scope, import_effect12.Exit.void)).catch(() => {
2865
2815
  });
2866
2816
  this.entries.delete(entry.key);
2867
2817
  }, timeoutMs);
@@ -2878,7 +2828,7 @@ var getRegistry = (runtime) => {
2878
2828
  var stableProcessSignature = (processes) => {
2879
2829
  const ids = [];
2880
2830
  for (let i = 0; i < processes.length; i++) {
2881
- const def = Logix11.Process.getDefinition(processes[i]);
2831
+ const def = Logix12.Process.getDefinition(processes[i]);
2882
2832
  ids.push(def?.processId ?? `legacy#${i}`);
2883
2833
  }
2884
2834
  return ids.join("|");
@@ -2921,24 +2871,24 @@ function useProcesses(processes, options) {
2921
2871
  signature,
2922
2872
  gcTime,
2923
2873
  install: (scope) => {
2924
- const program = import_effect13.Effect.forEach(
2874
+ const program = import_effect12.Effect.forEach(
2925
2875
  processes,
2926
- (process) => Logix11.InternalContracts.installProcess(process, {
2876
+ (process) => Logix12.InternalContracts.installProcess(process, {
2927
2877
  scope: { type: "uiSubtree", subtreeId },
2928
2878
  enabled: true,
2929
2879
  installedAt: "uiSubtree",
2930
2880
  mode
2931
2881
  }).pipe(
2932
- import_effect13.Effect.flatMap((installation) => {
2882
+ import_effect12.Effect.flatMap((installation) => {
2933
2883
  if (installation !== void 0) {
2934
- return import_effect13.Effect.void;
2884
+ return import_effect12.Effect.void;
2935
2885
  }
2936
- return import_effect13.Effect.forkScoped(process).pipe(import_effect13.Effect.asVoid);
2886
+ return import_effect12.Effect.forkScoped(process).pipe(import_effect12.Effect.asVoid);
2937
2887
  }),
2938
- import_effect13.Effect.catchAll(() => import_effect13.Effect.forkScoped(process).pipe(import_effect13.Effect.asVoid))
2888
+ import_effect12.Effect.catchAll(() => import_effect12.Effect.forkScoped(process).pipe(import_effect12.Effect.asVoid))
2939
2889
  ),
2940
2890
  { discard: true }
2941
- ).pipe(import_effect13.Effect.provideService(import_effect13.Scope.Scope, scope));
2891
+ ).pipe(import_effect12.Effect.provideService(import_effect12.Scope.Scope, scope));
2942
2892
  void runtime.runPromise(program).catch(() => {
2943
2893
  });
2944
2894
  }
@@ -2947,7 +2897,7 @@ function useProcesses(processes, options) {
2947
2897
  }
2948
2898
 
2949
2899
  // src/internal/platform/ReactPlatformLayer.ts
2950
- var import_effect14 = require("effect");
2900
+ var import_effect13 = require("effect");
2951
2901
  var import_core = require("@logixjs/core");
2952
2902
  var ReactPlatformImpl = class {
2953
2903
  constructor(suspendRef, resumeRef, resetRef) {
@@ -2955,24 +2905,24 @@ var ReactPlatformImpl = class {
2955
2905
  this.resumeRef = resumeRef;
2956
2906
  this.resetRef = resetRef;
2957
2907
  this.lifecycle = {
2958
- onSuspend: (eff) => import_effect14.Ref.update(this.suspendRef, (list) => [...list, eff]).pipe(import_effect14.Effect.asVoid),
2959
- onResume: (eff) => import_effect14.Ref.update(this.resumeRef, (list) => [...list, eff]).pipe(import_effect14.Effect.asVoid),
2960
- onReset: (eff) => import_effect14.Ref.update(this.resetRef, (list) => [...list, eff]).pipe(import_effect14.Effect.asVoid)
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)
2961
2911
  };
2962
2912
  // The emit* methods are not part of the official Logic.Platform interface; they are for host/test use only.
2963
2913
  // After retrieving the instance via `Effect.service(Logic.Platform)`, call them via `any`.
2964
- this.emitSuspend = () => import_effect14.Ref.get(this.suspendRef).pipe(import_effect14.Effect.flatMap((effects) => import_effect14.Effect.forEach(effects, (eff) => eff, { discard: true })));
2965
- this.emitResume = () => import_effect14.Ref.get(this.resumeRef).pipe(import_effect14.Effect.flatMap((effects) => import_effect14.Effect.forEach(effects, (eff) => eff, { discard: true })));
2966
- this.emitReset = () => import_effect14.Ref.get(this.resetRef).pipe(import_effect14.Effect.flatMap((effects) => import_effect14.Effect.forEach(effects, (eff) => eff, { discard: true })));
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 })));
2967
2917
  }
2968
2918
  };
2969
- var makeReactPlatform = import_effect14.Effect.gen(function* () {
2970
- const suspendRef = yield* import_effect14.Ref.make([]);
2971
- const resumeRef = yield* import_effect14.Ref.make([]);
2972
- const resetRef = yield* import_effect14.Ref.make([]);
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([]);
2973
2923
  return new ReactPlatformImpl(suspendRef, resumeRef, resetRef);
2974
2924
  });
2975
- var ReactPlatformLayer = import_effect14.Layer.scoped(
2925
+ var ReactPlatformLayer = import_effect13.Layer.scoped(
2976
2926
  import_core.Platform.tag,
2977
2927
  makeReactPlatform
2978
2928
  );
@@ -3018,7 +2968,7 @@ var ReactPlatform = {
3018
2968
 
3019
2969
  // src/ModuleScope.ts
3020
2970
  var import_react17 = __toESM(require("react"), 1);
3021
- var Logix12 = __toESM(require("@logixjs/core"), 1);
2971
+ var Logix13 = __toESM(require("@logixjs/core"), 1);
3022
2972
  var makeModuleScope = (handle, defaults) => {
3023
2973
  const Context7 = import_react17.default.createContext(null);
3024
2974
  const toUseModuleOptions = (options) => {
@@ -3027,7 +2977,7 @@ var makeModuleScope = (handle, defaults) => {
3027
2977
  };
3028
2978
  const getRegistryOrThrow = (runtime, where) => {
3029
2979
  try {
3030
- const registry = runtime.runSync(Logix12.ScopeRegistry.ScopeRegistryTag);
2980
+ const registry = runtime.runSync(Logix13.ScopeRegistry.ScopeRegistryTag);
3031
2981
  if (!registry) {
3032
2982
  throw new Error("ScopeRegistry service is undefined");
3033
2983
  }
@@ -3038,7 +2988,7 @@ var makeModuleScope = (handle, defaults) => {
3038
2988
  );
3039
2989
  }
3040
2990
  };
3041
- const moduleToken = Logix12.Module.hasImpl(handle) ? handle.tag : handle.module;
2991
+ const moduleToken = Logix13.Module.hasImpl(handle) ? handle.tag : handle.module;
3042
2992
  const Provider = ({ children, options }) => {
3043
2993
  const runtime = useRuntime();
3044
2994
  const merged = defaults || options ? { ...defaults ?? {}, ...options ?? {} } : void 0;
@@ -3047,7 +2997,7 @@ var makeModuleScope = (handle, defaults) => {
3047
2997
  import_react17.default.useEffect(() => {
3048
2998
  if (!scopeId) return;
3049
2999
  const registry = getRegistryOrThrow(runtime, "[ModuleScope]");
3050
- const leaseRuntime = registry.register(scopeId, Logix12.ScopeRegistry.ScopedRuntimeTag, runtime);
3000
+ const leaseRuntime = registry.register(scopeId, Logix13.ScopeRegistry.ScopedRuntimeTag, runtime);
3051
3001
  const leaseModule = registry.register(scopeId, moduleToken, ref.runtime);
3052
3002
  return () => {
3053
3003
  leaseModule.release();
@@ -3070,11 +3020,8 @@ var makeModuleScope = (handle, defaults) => {
3070
3020
  const Bridge = ({ scopeId, children }) => {
3071
3021
  const runtime = useRuntime();
3072
3022
  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
- );
3023
+ const scopedRuntime = registry.get(scopeId, Logix13.ScopeRegistry.ScopedRuntimeTag);
3024
+ const moduleRuntime = registry.get(scopeId, moduleToken);
3078
3025
  if (!scopedRuntime || !moduleRuntime) {
3079
3026
  throw new Error(
3080
3027
  `[ModuleScope.Bridge] Scope "${scopeId}" is not registered (or has been disposed). Ensure you have a corresponding <ModuleScope.Provider options={{ scopeId }}> mounted.`