@logixjs/react 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Hooks.cjs +345 -142
- package/dist/Hooks.js +3 -3
- package/dist/ModuleScope.cjs +474 -187
- package/dist/ModuleScope.js +4 -4
- package/dist/Platform.cjs +1 -4
- package/dist/Platform.d.cts +1 -2
- package/dist/Platform.d.ts +1 -2
- package/dist/Platform.js +1 -1
- package/dist/ReactPlatform.cjs +395 -111
- package/dist/ReactPlatform.js +5 -5
- package/dist/RuntimeProvider.cjs +254 -50
- package/dist/RuntimeProvider.js +2 -2
- package/dist/{chunk-WOTNVLCD.js → chunk-6NLXTHZ7.js} +8 -8
- package/dist/{chunk-G2LX7WWQ.js → chunk-E3ZXST5F.js} +129 -49
- package/dist/{chunk-JC3R6GII.js → chunk-KYWW4KMQ.js} +3 -3
- package/dist/{chunk-2WFULYPJ.js → chunk-L7KTYBXN.js} +155 -32
- package/dist/{chunk-ZANGOPUQ.js → chunk-NKYV44OG.js} +1 -4
- package/dist/{chunk-STTE4SOJ.js → chunk-SDQF3WRT.js} +6 -3
- package/dist/{chunk-2M6MDNVT.js → chunk-XSGDBJXD.js} +100 -19
- package/dist/index.cjs +435 -151
- package/dist/index.js +7 -7
- package/package.json +9 -4
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
isDevEnv,
|
|
6
6
|
stableHash,
|
|
7
7
|
useLayerBinding
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-L7KTYBXN.js";
|
|
9
9
|
|
|
10
10
|
// src/internal/hooks/useRuntime.ts
|
|
11
11
|
import { useContext, useEffect, useMemo, useRef } from "react";
|
|
@@ -138,12 +138,12 @@ var shallow = (previous, next) => {
|
|
|
138
138
|
// src/internal/hooks/useSelector.ts
|
|
139
139
|
import { useContext as useContext3, useEffect as useEffect3, useMemo as useMemo3 } from "react";
|
|
140
140
|
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector";
|
|
141
|
-
import * as
|
|
141
|
+
import * as Logix4 from "@logixjs/core";
|
|
142
142
|
|
|
143
143
|
// src/internal/hooks/useModuleRuntime.ts
|
|
144
|
-
import { useEffect as useEffect2, useMemo as useMemo2, useContext as useContext2 } from "react";
|
|
145
|
-
import * as
|
|
146
|
-
import { Scope } from "effect";
|
|
144
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useContext as useContext2, useRef as useRef2 } from "react";
|
|
145
|
+
import * as Logix2 from "@logixjs/core";
|
|
146
|
+
import { Effect as Effect2, Scope } from "effect";
|
|
147
147
|
|
|
148
148
|
// src/internal/store/ModuleRef.ts
|
|
149
149
|
var isModuleRef = (value) => typeof value === "object" && value !== null && "runtime" in value && "actions" in value && "dispatch" in value;
|
|
@@ -234,11 +234,26 @@ var applyHandleExtend = (tag, runtime, base) => {
|
|
|
234
234
|
return { ...base, ...next };
|
|
235
235
|
};
|
|
236
236
|
|
|
237
|
+
// src/internal/provider/runtimeDebugBridge.ts
|
|
238
|
+
import { Effect } from "effect";
|
|
239
|
+
import * as Logix from "@logixjs/core";
|
|
240
|
+
var readRuntimeDiagnosticsLevel = (runtime) => {
|
|
241
|
+
try {
|
|
242
|
+
return runtime.runSync(Effect.service(Logix.Debug.internal.currentDiagnosticsLevel).pipe(Effect.orDie));
|
|
243
|
+
} catch {
|
|
244
|
+
return isDevEnv() ? "light" : "off";
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
var emitRuntimeDebugEventBestEffort = (runtime, event) => {
|
|
248
|
+
runtime.runFork(event);
|
|
249
|
+
};
|
|
250
|
+
|
|
237
251
|
// src/internal/hooks/useModuleRuntime.ts
|
|
238
252
|
var isModuleRuntime = (value) => typeof value === "object" && value !== null && "dispatch" in value && "getState" in value;
|
|
239
253
|
function useModuleRuntime(handle) {
|
|
240
254
|
const runtime = useRuntime();
|
|
241
255
|
const runtimeContext = useContext2(RuntimeContext);
|
|
256
|
+
const moduleTagResolveTraceRef = useRef2(void 0);
|
|
242
257
|
if (!runtimeContext) {
|
|
243
258
|
throw new RuntimeProviderNotFoundError("useModuleRuntime");
|
|
244
259
|
}
|
|
@@ -259,42 +274,54 @@ function useModuleRuntime(handle) {
|
|
|
259
274
|
const preloadKey = runtimeContext.policy.preload?.keysByTagId.get(tokenId);
|
|
260
275
|
const key = preloadKey ?? `tag:${tokenId}`;
|
|
261
276
|
const mode = runtimeContext.policy.moduleTagMode;
|
|
262
|
-
const
|
|
263
|
-
|
|
277
|
+
const startedAtMs = performance.now();
|
|
278
|
+
const factory = (scope) => Scope.provide(scope)(Effect2.service(tag).pipe(Effect2.orDie));
|
|
279
|
+
const resolvedRuntime = mode === "suspend" ? cache.read(key, factory, void 0, tokenId, {
|
|
264
280
|
entrypoint: "react.useModuleRuntime",
|
|
265
281
|
policyMode: runtimeContext.policy.mode,
|
|
266
|
-
yield: runtimeContext.policy.yield
|
|
282
|
+
yield: runtimeContext.policy.yield,
|
|
283
|
+
optimisticSyncBudgetMs: runtimeContext.policy.syncBudgetMs
|
|
267
284
|
}) : cache.readSync(key, factory, void 0, tokenId, {
|
|
268
285
|
entrypoint: "react.useModuleRuntime",
|
|
269
286
|
policyMode: runtimeContext.policy.mode,
|
|
270
287
|
warnSyncBlockingThresholdMs: 5
|
|
271
288
|
});
|
|
289
|
+
moduleTagResolveTraceRef.current = {
|
|
290
|
+
tokenId,
|
|
291
|
+
durationMs: Math.round((performance.now() - startedAtMs) * 100) / 100,
|
|
292
|
+
cacheMode: mode
|
|
293
|
+
};
|
|
294
|
+
return resolvedRuntime;
|
|
272
295
|
}, [cache, runtimeContext.policy, handle]);
|
|
273
296
|
useEffect2(() => {
|
|
274
297
|
if (!isTagHandle) {
|
|
275
298
|
return;
|
|
276
299
|
}
|
|
277
|
-
|
|
300
|
+
const diagnosticsLevel = readRuntimeDiagnosticsLevel(runtime);
|
|
301
|
+
if (diagnosticsLevel === "off") {
|
|
278
302
|
return;
|
|
279
303
|
}
|
|
280
304
|
const tokenId = handle?.id ?? "ModuleTag";
|
|
281
|
-
const
|
|
305
|
+
const trace = moduleTagResolveTraceRef.current;
|
|
306
|
+
const effect = Logix2.Debug.record({
|
|
282
307
|
type: "trace:react.moduleTag.resolve",
|
|
283
308
|
moduleId: resolved.moduleId,
|
|
284
309
|
instanceId: resolved.instanceId,
|
|
285
310
|
data: {
|
|
286
311
|
mode: runtimeContext.policy.moduleTagMode,
|
|
287
312
|
tokenId,
|
|
288
|
-
yieldStrategy: runtimeContext.policy.yield.strategy
|
|
313
|
+
yieldStrategy: runtimeContext.policy.yield.strategy,
|
|
314
|
+
durationMs: trace?.durationMs,
|
|
315
|
+
cacheMode: trace?.cacheMode ?? runtimeContext.policy.moduleTagMode
|
|
289
316
|
}
|
|
290
317
|
});
|
|
291
|
-
runtime
|
|
318
|
+
emitRuntimeDebugEventBestEffort(runtime, effect);
|
|
292
319
|
}, [runtime, runtimeContext.policy, resolved, handle, isTagHandle]);
|
|
293
320
|
return resolved;
|
|
294
321
|
}
|
|
295
322
|
|
|
296
323
|
// src/internal/store/RuntimeExternalStore.ts
|
|
297
|
-
import * as
|
|
324
|
+
import * as Logix3 from "@logixjs/core";
|
|
298
325
|
import { Fiber, Stream } from "effect";
|
|
299
326
|
var storesByRuntime = /* @__PURE__ */ new WeakMap();
|
|
300
327
|
var getStoreMapForRuntime = (runtime) => {
|
|
@@ -306,8 +333,8 @@ var getStoreMapForRuntime = (runtime) => {
|
|
|
306
333
|
};
|
|
307
334
|
var makeModuleInstanceKey = (moduleId, instanceId) => `${moduleId}::${instanceId}`;
|
|
308
335
|
var makeReadQueryTopicKey = (moduleInstanceKey, selectorId) => `${moduleInstanceKey}::rq:${selectorId}`;
|
|
309
|
-
var getRuntimeStore = (runtime) =>
|
|
310
|
-
var getHostScheduler = (runtime) =>
|
|
336
|
+
var getRuntimeStore = (runtime) => Logix3.InternalContracts.getRuntimeStore(runtime);
|
|
337
|
+
var getHostScheduler = (runtime) => Logix3.InternalContracts.getHostScheduler(runtime);
|
|
311
338
|
var getOrCreateStore = (runtime, topicKey, make) => {
|
|
312
339
|
const map = getStoreMapForRuntime(runtime);
|
|
313
340
|
const cached = map.get(topicKey);
|
|
@@ -331,6 +358,8 @@ var makeTopicExternalStore = (args) => {
|
|
|
331
358
|
let currentSnapshot;
|
|
332
359
|
const listeners = /* @__PURE__ */ new Set();
|
|
333
360
|
let unsubscribeFromRuntimeStore;
|
|
361
|
+
let teardownScheduled = false;
|
|
362
|
+
let teardownToken = 0;
|
|
334
363
|
const lowPriorityDelayMs = args.options?.lowPriorityDelayMs ?? 16;
|
|
335
364
|
const lowPriorityMaxDelayMs = args.options?.lowPriorityMaxDelayMs ?? 50;
|
|
336
365
|
let notifyScheduled = false;
|
|
@@ -415,7 +444,38 @@ var makeTopicExternalStore = (args) => {
|
|
|
415
444
|
currentSnapshot = next;
|
|
416
445
|
return next;
|
|
417
446
|
};
|
|
447
|
+
const cancelScheduledTeardown = () => {
|
|
448
|
+
if (!teardownScheduled) return;
|
|
449
|
+
teardownScheduled = false;
|
|
450
|
+
teardownToken += 1;
|
|
451
|
+
};
|
|
452
|
+
const finalizeTeardown = () => {
|
|
453
|
+
if (listeners.size > 0) return;
|
|
454
|
+
try {
|
|
455
|
+
args.onLastListener?.();
|
|
456
|
+
} catch {
|
|
457
|
+
}
|
|
458
|
+
const unsub = unsubscribeFromRuntimeStore;
|
|
459
|
+
unsubscribeFromRuntimeStore = void 0;
|
|
460
|
+
cancelLow();
|
|
461
|
+
try {
|
|
462
|
+
unsub?.();
|
|
463
|
+
} catch {
|
|
464
|
+
}
|
|
465
|
+
removeStore(runtime, topicKey);
|
|
466
|
+
};
|
|
467
|
+
const scheduleTeardown = () => {
|
|
468
|
+
if (teardownScheduled) return;
|
|
469
|
+
teardownScheduled = true;
|
|
470
|
+
const token = ++teardownToken;
|
|
471
|
+
hostScheduler.scheduleMicrotask(() => {
|
|
472
|
+
if (!teardownScheduled || token !== teardownToken) return;
|
|
473
|
+
teardownScheduled = false;
|
|
474
|
+
finalizeTeardown();
|
|
475
|
+
});
|
|
476
|
+
};
|
|
418
477
|
const subscribe = (listener) => {
|
|
478
|
+
cancelScheduledTeardown();
|
|
419
479
|
const isFirst = listeners.size === 0;
|
|
420
480
|
listeners.add(listener);
|
|
421
481
|
ensureSubscription();
|
|
@@ -429,18 +489,7 @@ var makeTopicExternalStore = (args) => {
|
|
|
429
489
|
return () => {
|
|
430
490
|
listeners.delete(listener);
|
|
431
491
|
if (listeners.size > 0) return;
|
|
432
|
-
|
|
433
|
-
args.onLastListener?.();
|
|
434
|
-
} catch {
|
|
435
|
-
}
|
|
436
|
-
const unsub = unsubscribeFromRuntimeStore;
|
|
437
|
-
unsubscribeFromRuntimeStore = void 0;
|
|
438
|
-
cancelLow();
|
|
439
|
-
try {
|
|
440
|
-
unsub?.();
|
|
441
|
-
} catch {
|
|
442
|
-
}
|
|
443
|
-
removeStore(runtime, topicKey);
|
|
492
|
+
scheduleTeardown();
|
|
444
493
|
};
|
|
445
494
|
};
|
|
446
495
|
return { getSnapshot, getServerSnapshot: getSnapshot, subscribe };
|
|
@@ -507,7 +556,7 @@ function useSelector(handle, selector, equalityFn) {
|
|
|
507
556
|
const moduleRuntime = useModuleRuntime(handle);
|
|
508
557
|
const actualSelector = selector ?? ((state) => state);
|
|
509
558
|
const selectorReadQuery = useMemo3(
|
|
510
|
-
() => typeof selector === "function" ?
|
|
559
|
+
() => typeof selector === "function" ? Logix4.ReadQuery.compile(selector) : void 0,
|
|
511
560
|
[selector]
|
|
512
561
|
);
|
|
513
562
|
const actualEqualityFn = useMemo3(() => {
|
|
@@ -545,7 +594,7 @@ function useSelector(handle, selector, equalityFn) {
|
|
|
545
594
|
actualEqualityFn
|
|
546
595
|
);
|
|
547
596
|
useEffect3(() => {
|
|
548
|
-
if (!isDevEnv() && !
|
|
597
|
+
if (!isDevEnv() && !Logix4.Debug.isDevtoolsEnabled()) {
|
|
549
598
|
return;
|
|
550
599
|
}
|
|
551
600
|
const instanceId = moduleRuntime.instanceId;
|
|
@@ -561,7 +610,7 @@ function useSelector(handle, selector, equalityFn) {
|
|
|
561
610
|
const rawDebugKey = meta.debugKey;
|
|
562
611
|
selectorKey = typeof rawDebugKey === "string" && rawDebugKey.length > 0 ? rawDebugKey : typeof selector.name === "string" && selector.name.length > 0 ? selector.name : void 0;
|
|
563
612
|
}
|
|
564
|
-
const effect =
|
|
613
|
+
const effect = Logix4.Debug.record({
|
|
565
614
|
type: "trace:react-selector",
|
|
566
615
|
moduleId: moduleRuntime.moduleId,
|
|
567
616
|
instanceId,
|
|
@@ -585,11 +634,11 @@ function useSelector(handle, selector, equalityFn) {
|
|
|
585
634
|
|
|
586
635
|
// src/internal/hooks/useModule.ts
|
|
587
636
|
import React2 from "react";
|
|
588
|
-
import * as
|
|
589
|
-
import {
|
|
637
|
+
import * as Logix6 from "@logixjs/core";
|
|
638
|
+
import { Effect as Effect4, Layer as Layer2, ServiceMap } from "effect";
|
|
590
639
|
|
|
591
640
|
// src/internal/store/resolveImportedModuleRef.ts
|
|
592
|
-
import * as
|
|
641
|
+
import * as Logix5 from "@logixjs/core";
|
|
593
642
|
var getOrCreateWeakMap = (map, key, make) => {
|
|
594
643
|
const cached = map.get(key);
|
|
595
644
|
if (cached) return cached;
|
|
@@ -613,7 +662,7 @@ var resolveImportedModuleRef = (runtime, parentRuntime, module) => {
|
|
|
613
662
|
if (cached) {
|
|
614
663
|
return cached;
|
|
615
664
|
}
|
|
616
|
-
const importsScope =
|
|
665
|
+
const importsScope = Logix5.InternalContracts.getImportsScope(parentRuntime);
|
|
617
666
|
const childRuntime = importsScope.get(module);
|
|
618
667
|
if (childRuntime) {
|
|
619
668
|
const dispatch = Object.assign(
|
|
@@ -699,8 +748,8 @@ var useStableId = () => {
|
|
|
699
748
|
|
|
700
749
|
// src/internal/hooks/useModule.ts
|
|
701
750
|
var isModuleImpl = (handle) => Boolean(handle) && typeof handle === "object" && handle._tag === "ModuleImpl";
|
|
702
|
-
var isModule = (handle) =>
|
|
703
|
-
var isModuleDef = (handle) =>
|
|
751
|
+
var isModule = (handle) => Logix6.Module.hasImpl(handle);
|
|
752
|
+
var isModuleDef = (handle) => Logix6.Module.is(handle) && handle._kind === "ModuleDef";
|
|
704
753
|
function useModule(handle, selectorOrOptions, equalityFn) {
|
|
705
754
|
const runtimeBase = useRuntime();
|
|
706
755
|
const runtimeContext = React2.useContext(RuntimeContext);
|
|
@@ -724,6 +773,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
|
|
|
724
773
|
}
|
|
725
774
|
}
|
|
726
775
|
let runtime;
|
|
776
|
+
const moduleImplResolveTraceRef = React2.useRef(void 0);
|
|
727
777
|
if (isModuleImpl(normalizedHandle)) {
|
|
728
778
|
const cache = React2.useMemo(
|
|
729
779
|
() => getModuleCache(runtimeBase, runtimeContext.reactConfigSnapshot, runtimeContext.configVersion),
|
|
@@ -752,9 +802,9 @@ function useModule(handle, selectorOrOptions, equalityFn) {
|
|
|
752
802
|
const key = depsHash ? `${baseKey}:${depsHash}` : baseKey;
|
|
753
803
|
const ownerId = moduleId;
|
|
754
804
|
const baseFactory = React2.useMemo(
|
|
755
|
-
() => (scope) => Layer2.buildWithScope(normalizedHandle.layer, scope).pipe(
|
|
756
|
-
|
|
757
|
-
(context) =>
|
|
805
|
+
() => (scope) => Layer2.buildWithScope(Layer2.fresh(normalizedHandle.layer), scope).pipe(
|
|
806
|
+
Effect4.map(
|
|
807
|
+
(context) => ServiceMap.get(context, normalizedHandle.module)
|
|
758
808
|
)
|
|
759
809
|
),
|
|
760
810
|
[normalizedHandle]
|
|
@@ -764,26 +814,56 @@ function useModule(handle, selectorOrOptions, equalityFn) {
|
|
|
764
814
|
return baseFactory;
|
|
765
815
|
}
|
|
766
816
|
return (scope) => baseFactory(scope).pipe(
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
817
|
+
Effect4.timeoutOption(initTimeoutMs),
|
|
818
|
+
Effect4.flatMap(
|
|
819
|
+
(maybe) => maybe._tag === "Some" ? Effect4.succeed(maybe.value) : Effect4.die(new Error(`[useModule] Module "${ownerId}" initialization timed out after ${initTimeoutMs}ms`))
|
|
820
|
+
)
|
|
771
821
|
);
|
|
772
822
|
}, [baseFactory, suspend, initTimeoutMs, ownerId]);
|
|
823
|
+
const moduleResolveStartedAt = performance.now();
|
|
773
824
|
const moduleRuntime = suspend ? cache.read(key, factory, gcTime, ownerId, {
|
|
774
825
|
entrypoint: "react.useModule",
|
|
775
826
|
policyMode: runtimeContext.policy.mode,
|
|
776
|
-
yield: runtimeContext.policy.yield
|
|
827
|
+
yield: runtimeContext.policy.yield,
|
|
828
|
+
optimisticSyncBudgetMs: runtimeContext.policy.syncBudgetMs
|
|
777
829
|
}) : cache.readSync(key, factory, gcTime, ownerId, {
|
|
778
830
|
entrypoint: "react.useModule",
|
|
779
831
|
policyMode: runtimeContext.policy.mode,
|
|
780
832
|
warnSyncBlockingThresholdMs: 5
|
|
781
833
|
});
|
|
834
|
+
moduleImplResolveTraceRef.current = {
|
|
835
|
+
moduleId,
|
|
836
|
+
cacheMode: suspend ? "suspend" : "sync",
|
|
837
|
+
durationMs: Math.round((performance.now() - moduleResolveStartedAt) * 100) / 100
|
|
838
|
+
};
|
|
782
839
|
React2.useEffect(() => cache.retain(key), [cache, key]);
|
|
783
840
|
runtime = moduleRuntime;
|
|
784
841
|
} else {
|
|
785
842
|
runtime = useModuleRuntime(normalizedHandle);
|
|
786
843
|
}
|
|
844
|
+
React2.useEffect(() => {
|
|
845
|
+
if (!isModuleImpl(normalizedHandle)) {
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
const diagnosticsLevel = readRuntimeDiagnosticsLevel(runtimeBase);
|
|
849
|
+
if (diagnosticsLevel === "off") {
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
const trace = moduleImplResolveTraceRef.current;
|
|
853
|
+
if (!trace) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
const effect = Logix6.Debug.record({
|
|
857
|
+
type: "trace:react.moduleImpl.resolve",
|
|
858
|
+
moduleId: trace.moduleId,
|
|
859
|
+
instanceId: runtime.instanceId,
|
|
860
|
+
data: {
|
|
861
|
+
cacheMode: trace.cacheMode,
|
|
862
|
+
durationMs: trace.durationMs
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
emitRuntimeDebugEventBestEffort(runtimeBase, effect);
|
|
866
|
+
}, [runtimeBase, runtime, normalizedHandle]);
|
|
787
867
|
React2.useEffect(() => {
|
|
788
868
|
if (!isModuleImpl(normalizedHandle)) {
|
|
789
869
|
return;
|
|
@@ -793,22 +873,22 @@ function useModule(handle, selectorOrOptions, equalityFn) {
|
|
|
793
873
|
if (!label) {
|
|
794
874
|
return;
|
|
795
875
|
}
|
|
796
|
-
const effect =
|
|
876
|
+
const effect = Logix6.Debug.record({
|
|
797
877
|
type: "trace:instanceLabel",
|
|
798
878
|
moduleId: normalizedHandle.module.id,
|
|
799
879
|
instanceId: runtime.instanceId,
|
|
800
880
|
data: { label }
|
|
801
881
|
});
|
|
802
|
-
runtimeBase
|
|
882
|
+
emitRuntimeDebugEventBestEffort(runtimeBase, effect);
|
|
803
883
|
}, [runtimeBase, runtime, normalizedHandle, options]);
|
|
804
884
|
React2.useEffect(() => {
|
|
805
|
-
if (!isDevEnv() && !
|
|
885
|
+
if (!isDevEnv() && !Logix6.Debug.isDevtoolsEnabled()) {
|
|
806
886
|
return;
|
|
807
887
|
}
|
|
808
888
|
if (!runtime.instanceId) {
|
|
809
889
|
return;
|
|
810
890
|
}
|
|
811
|
-
const effect =
|
|
891
|
+
const effect = Logix6.Debug.record({
|
|
812
892
|
type: "trace:react-render",
|
|
813
893
|
moduleId: runtime.moduleId,
|
|
814
894
|
instanceId: runtime.instanceId,
|
|
@@ -818,7 +898,7 @@ function useModule(handle, selectorOrOptions, equalityFn) {
|
|
|
818
898
|
}
|
|
819
899
|
});
|
|
820
900
|
runtimeBase.runFork(effect);
|
|
821
|
-
}
|
|
901
|
+
});
|
|
822
902
|
if (selector) {
|
|
823
903
|
if (isModuleImpl(normalizedHandle)) {
|
|
824
904
|
return useSelector(runtime, selector, equalityFn);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useDispatch,
|
|
3
3
|
useLocalModule
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6NLXTHZ7.js";
|
|
5
5
|
import {
|
|
6
6
|
useModule,
|
|
7
7
|
useSelector
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-E3ZXST5F.js";
|
|
9
9
|
import {
|
|
10
10
|
RuntimeProvider
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-XSGDBJXD.js";
|
|
12
12
|
|
|
13
13
|
// src/ReactPlatform.ts
|
|
14
14
|
import React from "react";
|
|
@@ -7,7 +7,7 @@ import { getNodeEnv, isDevEnv } from "@logixjs/core/Env";
|
|
|
7
7
|
|
|
8
8
|
// src/internal/provider/runtimeBindings.ts
|
|
9
9
|
import { useEffect, useRef, useState } from "react";
|
|
10
|
-
import {
|
|
10
|
+
import { Cause, Effect, Exit, Layer, Logger, References, Scope } from "effect";
|
|
11
11
|
import * as Logix from "@logixjs/core";
|
|
12
12
|
var toErrorString = (error) => error instanceof Error ? error.stack ?? error.message : String(error);
|
|
13
13
|
var debugScopeCloseFailure = (error) => {
|
|
@@ -76,14 +76,11 @@ var useLayerBinding = (runtime, layer, enabled, onError) => {
|
|
|
76
76
|
const newScope = Effect.runSync(Scope.make());
|
|
77
77
|
const buildEffect = Effect.gen(function* () {
|
|
78
78
|
const context = yield* Layer.buildWithScope(layer, newScope);
|
|
79
|
-
const applyEnv = (effect) => Effect.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
83
|
-
const loggers = yield* applyEnv(FiberRef.get(FiberRef.currentLoggers));
|
|
84
|
-
const logLevel = yield* applyEnv(FiberRef.get(FiberRef.currentLogLevel));
|
|
79
|
+
const applyEnv = (effect) => Scope.provide(newScope)(Effect.provideServices(effect, context));
|
|
80
|
+
const loggers = yield* applyEnv(Effect.service(Logger.CurrentLoggers)).pipe(Effect.orDie);
|
|
81
|
+
const logLevel = yield* applyEnv(Effect.service(References.MinimumLogLevel)).pipe(Effect.orDie);
|
|
85
82
|
const debugSinks = yield* applyEnv(
|
|
86
|
-
|
|
83
|
+
Effect.service(Logix.Debug.internal.currentDebugSinks).pipe(Effect.orDie)
|
|
87
84
|
);
|
|
88
85
|
return { context, loggers, logLevel, debugSinks };
|
|
89
86
|
});
|
|
@@ -128,7 +125,7 @@ var useLayerBinding = (runtime, layer, enabled, onError) => {
|
|
|
128
125
|
const cause = Cause.die(error);
|
|
129
126
|
runtime.runFork(
|
|
130
127
|
onError(cause, { source: "provider", phase: "provider.layer.build" }).pipe(
|
|
131
|
-
Effect.
|
|
128
|
+
Effect.catchCause(() => Effect.void)
|
|
132
129
|
)
|
|
133
130
|
);
|
|
134
131
|
}
|
|
@@ -166,18 +163,11 @@ var createRuntimeAdapter = (runtime, contexts, scopes, loggerSets, logLevels, de
|
|
|
166
163
|
if (contexts.length === 0 && scopes.length === 0 && loggerSets.length === 0 && logLevels.length === 0 && debugSinks.length === 0) {
|
|
167
164
|
return runtime;
|
|
168
165
|
}
|
|
169
|
-
const applyContexts = (effect) => (
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
acc,
|
|
175
|
-
(parent) => Context.merge(parent, ctx)
|
|
176
|
-
),
|
|
177
|
-
scopes.reduceRight(
|
|
178
|
-
(acc, scope) => Scope.extend(acc, scope),
|
|
179
|
-
effect
|
|
180
|
-
)
|
|
166
|
+
const applyContexts = (effect) => contexts.reduceRight(
|
|
167
|
+
(acc, ctx) => Effect.provideServices(acc, ctx),
|
|
168
|
+
scopes.reduceRight(
|
|
169
|
+
(acc, scope) => Scope.provide(scope)(acc),
|
|
170
|
+
effect
|
|
181
171
|
)
|
|
182
172
|
);
|
|
183
173
|
const applyLoggers = (effect) => {
|
|
@@ -186,16 +176,13 @@ var createRuntimeAdapter = (runtime, contexts, scopes, loggerSets, logLevels, de
|
|
|
186
176
|
const sinks = debugSinks.length > 0 ? debugSinks[debugSinks.length - 1] : null;
|
|
187
177
|
let result = effect;
|
|
188
178
|
if (last) {
|
|
189
|
-
result = Effect.
|
|
179
|
+
result = Effect.provideService(result, Logger.CurrentLoggers, last);
|
|
190
180
|
}
|
|
191
181
|
if (logLevel) {
|
|
192
|
-
result = Effect.
|
|
182
|
+
result = Effect.provideService(result, References.MinimumLogLevel, logLevel);
|
|
193
183
|
}
|
|
194
184
|
if (sinks && sinks.length > 0) {
|
|
195
|
-
result = Effect.
|
|
196
|
-
Logix.Debug.internal.currentDebugSinks,
|
|
197
|
-
sinks
|
|
198
|
-
)(result);
|
|
185
|
+
result = Effect.provideService(result, Logix.Debug.internal.currentDebugSinks, sinks);
|
|
199
186
|
}
|
|
200
187
|
return result;
|
|
201
188
|
};
|
|
@@ -326,9 +313,9 @@ ${message}`;
|
|
|
326
313
|
console.debug(label, message);
|
|
327
314
|
};
|
|
328
315
|
var causeToUnknown = (cause) => {
|
|
329
|
-
const failure = Option.getOrUndefined(Cause2.
|
|
316
|
+
const failure = Option.getOrUndefined(Cause2.findErrorOption(cause));
|
|
330
317
|
if (failure !== void 0) return failure;
|
|
331
|
-
const defect =
|
|
318
|
+
const defect = cause.reasons.filter(Cause2.isDieReason).map((reason) => reason.defect)[0];
|
|
332
319
|
if (defect !== void 0) return defect;
|
|
333
320
|
return cause;
|
|
334
321
|
};
|
|
@@ -337,7 +324,7 @@ var yieldEffect = (strategy) => {
|
|
|
337
324
|
case "none":
|
|
338
325
|
return Effect3.void;
|
|
339
326
|
case "microtask":
|
|
340
|
-
return Effect3.yieldNow
|
|
327
|
+
return Effect3.yieldNow;
|
|
341
328
|
case "macrotask":
|
|
342
329
|
return Effect3.promise(
|
|
343
330
|
() => new Promise((resolve) => {
|
|
@@ -430,6 +417,67 @@ var ModuleCache = class {
|
|
|
430
417
|
const scope = Effect3.runSync(Scope2.make());
|
|
431
418
|
const workloadKey = `${options?.entrypoint ?? "unknown"}::${ownerId ?? "unknown"}`;
|
|
432
419
|
const yieldDecision = decideYieldStrategy(this.runtime, workloadKey, options?.yield);
|
|
420
|
+
const optimisticSyncBudgetMs = options?.optimisticSyncBudgetMs ?? 0;
|
|
421
|
+
const shouldTryOptimisticSync = options?.policyMode === "suspend" && optimisticSyncBudgetMs > 0;
|
|
422
|
+
if (shouldTryOptimisticSync) {
|
|
423
|
+
const startedAt2 = performance.now();
|
|
424
|
+
try {
|
|
425
|
+
const value = this.runtime.runSync(factory(scope));
|
|
426
|
+
const durationMs = performance.now() - startedAt2;
|
|
427
|
+
YieldBudgetMemory.record({ runtime: this.runtime, workloadKey, durationMs });
|
|
428
|
+
const entry2 = {
|
|
429
|
+
scope,
|
|
430
|
+
status: "success",
|
|
431
|
+
promise: Promise.resolve(value),
|
|
432
|
+
value,
|
|
433
|
+
refCount: 0,
|
|
434
|
+
preloadRefCount: 0,
|
|
435
|
+
gcTime: gcTime ?? this.gcDelayMs,
|
|
436
|
+
ownerId,
|
|
437
|
+
createdBy: "read",
|
|
438
|
+
workloadKey,
|
|
439
|
+
yieldStrategy: "none"
|
|
440
|
+
};
|
|
441
|
+
this.scheduleGC(key, entry2);
|
|
442
|
+
this.entries.set(key, entry2);
|
|
443
|
+
if (isDevEnv() || Logix3.Debug.isDevtoolsEnabled()) {
|
|
444
|
+
void this.runtime.runPromise(
|
|
445
|
+
Logix3.Debug.record({
|
|
446
|
+
type: "trace:react.module.init",
|
|
447
|
+
moduleId: ownerId,
|
|
448
|
+
instanceId: value.instanceId,
|
|
449
|
+
data: {
|
|
450
|
+
mode: "suspend",
|
|
451
|
+
key,
|
|
452
|
+
durationMs: Math.round(durationMs * 100) / 100,
|
|
453
|
+
yieldStrategy: "none",
|
|
454
|
+
fastPath: "sync"
|
|
455
|
+
}
|
|
456
|
+
})
|
|
457
|
+
).catch((error) => {
|
|
458
|
+
debugBestEffortFailure("[ModuleCache] Debug.record failed", error);
|
|
459
|
+
});
|
|
460
|
+
void this.runtime.runPromise(
|
|
461
|
+
Logix3.Debug.record({
|
|
462
|
+
type: "trace:react.module-instance",
|
|
463
|
+
moduleId: ownerId,
|
|
464
|
+
instanceId: value.instanceId,
|
|
465
|
+
data: {
|
|
466
|
+
event: "attach",
|
|
467
|
+
key,
|
|
468
|
+
mode: "suspend",
|
|
469
|
+
gcTime: entry2.gcTime,
|
|
470
|
+
fastPath: "sync"
|
|
471
|
+
}
|
|
472
|
+
})
|
|
473
|
+
).catch((error) => {
|
|
474
|
+
debugBestEffortFailure("[ModuleCache] Debug.record failed", error);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
return value;
|
|
478
|
+
} catch {
|
|
479
|
+
}
|
|
480
|
+
}
|
|
433
481
|
const entry = {
|
|
434
482
|
scope,
|
|
435
483
|
status: "pending",
|
|
@@ -445,7 +493,7 @@ var ModuleCache = class {
|
|
|
445
493
|
};
|
|
446
494
|
this.scheduleGC(key, entry);
|
|
447
495
|
const startedAt = performance.now();
|
|
448
|
-
const buildEffect = yieldEffect(yieldDecision.strategy).pipe(Effect3.
|
|
496
|
+
const buildEffect = yieldEffect(yieldDecision.strategy).pipe(Effect3.flatMap(() => factory(scope)));
|
|
449
497
|
const fiber = this.runtime.runFork(buildEffect);
|
|
450
498
|
entry.fiber = fiber;
|
|
451
499
|
const promise = this.runtime.runPromise(Fiber.await(fiber)).then((exit) => {
|
|
@@ -641,6 +689,49 @@ var ModuleCache = class {
|
|
|
641
689
|
throw error;
|
|
642
690
|
}
|
|
643
691
|
}
|
|
692
|
+
warmSync(key, factory, gcTime, ownerId, options) {
|
|
693
|
+
const existing = this.entries.get(key);
|
|
694
|
+
if (existing) {
|
|
695
|
+
if (isDevEnv() && existing.ownerId !== void 0 && ownerId !== void 0 && existing.ownerId !== ownerId) {
|
|
696
|
+
throw new Error(
|
|
697
|
+
`[ModuleCache.warmSync] resource key "${key}" has already been claimed by module "${existing.ownerId}", but is now requested by module "${ownerId}".`
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
if (existing.status === "success") {
|
|
701
|
+
return existing.value;
|
|
702
|
+
}
|
|
703
|
+
return void 0;
|
|
704
|
+
}
|
|
705
|
+
const scope = this.runtime.runSync(Scope2.make());
|
|
706
|
+
const startedAt = performance.now();
|
|
707
|
+
const workloadKey = `${options?.entrypoint ?? "unknown"}::${ownerId ?? "unknown"}`;
|
|
708
|
+
try {
|
|
709
|
+
const value = this.runtime.runSync(factory(scope));
|
|
710
|
+
const durationMs = performance.now() - startedAt;
|
|
711
|
+
YieldBudgetMemory.record({ runtime: this.runtime, workloadKey, durationMs });
|
|
712
|
+
const entry = {
|
|
713
|
+
scope,
|
|
714
|
+
status: "success",
|
|
715
|
+
promise: Promise.resolve(value),
|
|
716
|
+
value,
|
|
717
|
+
refCount: 0,
|
|
718
|
+
preloadRefCount: 0,
|
|
719
|
+
gcTime: gcTime ?? this.gcDelayMs,
|
|
720
|
+
ownerId,
|
|
721
|
+
createdBy: "preload",
|
|
722
|
+
workloadKey,
|
|
723
|
+
yieldStrategy: "none"
|
|
724
|
+
};
|
|
725
|
+
this.scheduleGC(key, entry);
|
|
726
|
+
this.entries.set(key, entry);
|
|
727
|
+
return value;
|
|
728
|
+
} catch (error) {
|
|
729
|
+
void this.runtime.runPromise(Scope2.close(scope, Exit2.fail(error))).catch((closeError) => {
|
|
730
|
+
debugBestEffortFailure("[ModuleCache] Scope.close failed", closeError);
|
|
731
|
+
});
|
|
732
|
+
return void 0;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
644
735
|
preload(key, factory, options) {
|
|
645
736
|
const existing = this.entries.get(key);
|
|
646
737
|
if (existing) {
|
|
@@ -670,6 +761,38 @@ var ModuleCache = class {
|
|
|
670
761
|
const gcTime = options?.gcTime ?? this.gcDelayMs;
|
|
671
762
|
const workloadKey = `${options?.entrypoint ?? "unknown"}::${ownerId ?? "unknown"}`;
|
|
672
763
|
const yieldDecision = decideYieldStrategy(this.runtime, workloadKey, options?.yield);
|
|
764
|
+
const optimisticSyncBudgetMs = options?.optimisticSyncBudgetMs ?? 0;
|
|
765
|
+
const shouldTryOptimisticSync = options?.policyMode === "defer" && optimisticSyncBudgetMs > 0;
|
|
766
|
+
if (shouldTryOptimisticSync) {
|
|
767
|
+
const startedAt2 = performance.now();
|
|
768
|
+
try {
|
|
769
|
+
const value = this.runtime.runSync(factory(scope));
|
|
770
|
+
const durationMs = performance.now() - startedAt2;
|
|
771
|
+
YieldBudgetMemory.record({ runtime: this.runtime, workloadKey, durationMs });
|
|
772
|
+
const entry2 = {
|
|
773
|
+
scope,
|
|
774
|
+
status: "success",
|
|
775
|
+
promise: Promise.resolve(value),
|
|
776
|
+
value,
|
|
777
|
+
refCount: 0,
|
|
778
|
+
preloadRefCount: 1,
|
|
779
|
+
gcTime,
|
|
780
|
+
ownerId,
|
|
781
|
+
createdBy: "preload",
|
|
782
|
+
workloadKey,
|
|
783
|
+
yieldStrategy: "none"
|
|
784
|
+
};
|
|
785
|
+
this.scheduleGC(key, entry2);
|
|
786
|
+
this.entries.set(key, entry2);
|
|
787
|
+
return {
|
|
788
|
+
promise: Promise.resolve(value),
|
|
789
|
+
cancel: () => {
|
|
790
|
+
this.cancelPreload(key, entry2);
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
} catch {
|
|
794
|
+
}
|
|
795
|
+
}
|
|
673
796
|
const entry = {
|
|
674
797
|
scope,
|
|
675
798
|
status: "pending",
|
|
@@ -685,7 +808,7 @@ var ModuleCache = class {
|
|
|
685
808
|
this.scheduleGC(key, entry);
|
|
686
809
|
this.entries.set(key, entry);
|
|
687
810
|
const startedAt = performance.now();
|
|
688
|
-
const buildEffect = yieldEffect(yieldDecision.strategy).pipe(Effect3.
|
|
811
|
+
const buildEffect = yieldEffect(yieldDecision.strategy).pipe(Effect3.flatMap(() => factory(scope)));
|
|
689
812
|
const fiber = this.runtime.runFork(buildEffect);
|
|
690
813
|
entry.fiber = fiber;
|
|
691
814
|
const promise = this.runtime.runPromise(Fiber.await(fiber)).then((exit) => {
|
|
@@ -24,10 +24,7 @@ var makeReactPlatform = Effect.gen(function* () {
|
|
|
24
24
|
const resetRef = yield* Ref.make([]);
|
|
25
25
|
return new ReactPlatformImpl(suspendRef, resumeRef, resetRef);
|
|
26
26
|
});
|
|
27
|
-
var ReactPlatformLayer = Layer.
|
|
28
|
-
Platform.tag,
|
|
29
|
-
makeReactPlatform
|
|
30
|
-
);
|
|
27
|
+
var ReactPlatformLayer = Layer.effect(Platform.tag, makeReactPlatform);
|
|
31
28
|
|
|
32
29
|
export {
|
|
33
30
|
ReactPlatformLayer
|