@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.
- package/LICENSE +201 -0
- package/README.md +1 -1
- package/dist/Hooks.cjs +462 -325
- package/dist/Hooks.d.cts +6 -6
- package/dist/Hooks.d.ts +6 -6
- package/dist/Hooks.js +3 -3
- package/dist/{ModuleRef-wZSQ3Wwo.d.cts → ModuleRef-gZmL6Zvb.d.cts} +8 -3
- package/dist/{ModuleRef-wZSQ3Wwo.d.ts → ModuleRef-gZmL6Zvb.d.ts} +8 -3
- package/dist/ModuleScope.cjs +596 -362
- package/dist/ModuleScope.d.cts +4 -4
- package/dist/ModuleScope.d.ts +4 -4
- 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 +543 -309
- package/dist/ReactPlatform.d.cts +2 -2
- package/dist/ReactPlatform.d.ts +2 -2
- package/dist/ReactPlatform.js +5 -5
- package/dist/RuntimeProvider.cjs +276 -56
- package/dist/RuntimeProvider.js +2 -2
- package/dist/{chunk-PYWHL7TA.js → chunk-6NLXTHZ7.js} +8 -8
- package/dist/{chunk-UFFCJGSZ.js → chunk-E3ZXST5F.js} +256 -240
- package/dist/{chunk-4G7H66OY.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-G5MRIFKK.js → chunk-SDQF3WRT.js} +7 -7
- package/dist/{chunk-JXAJTWSZ.js → chunk-XSGDBJXD.js} +122 -25
- package/dist/index.cjs +564 -333
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -7
- package/dist/{useDispatch-BnzYVkRE.d.ts → useDispatch-CiDimIYZ.d.ts} +13 -15
- package/dist/{useDispatch-CnO5-66H.d.cts → useDispatch-DiwQQAfC.d.cts} +13 -15
- package/package.json +12 -4
|
@@ -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
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useModule,
|
|
3
3
|
useRuntime
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-E3ZXST5F.js";
|
|
5
5
|
import {
|
|
6
6
|
RuntimeProvider
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-XSGDBJXD.js";
|
|
8
8
|
|
|
9
9
|
// src/ModuleScope.ts
|
|
10
10
|
import React from "react";
|
|
11
|
+
import { Effect } from "effect";
|
|
11
12
|
import * as Logix from "@logixjs/core";
|
|
12
13
|
var makeModuleScope = (handle, defaults) => {
|
|
13
14
|
const Context = React.createContext(null);
|
|
@@ -17,7 +18,9 @@ var makeModuleScope = (handle, defaults) => {
|
|
|
17
18
|
};
|
|
18
19
|
const getRegistryOrThrow = (runtime, where) => {
|
|
19
20
|
try {
|
|
20
|
-
const registry = runtime.runSync(
|
|
21
|
+
const registry = runtime.runSync(
|
|
22
|
+
Effect.service(Logix.ScopeRegistry.ScopeRegistryTag).pipe(Effect.orDie)
|
|
23
|
+
);
|
|
21
24
|
if (!registry) {
|
|
22
25
|
throw new Error("ScopeRegistry service is undefined");
|
|
23
26
|
}
|
|
@@ -61,10 +64,7 @@ var makeModuleScope = (handle, defaults) => {
|
|
|
61
64
|
const runtime = useRuntime();
|
|
62
65
|
const registry = getRegistryOrThrow(runtime, "[ModuleScope.Bridge]");
|
|
63
66
|
const scopedRuntime = registry.get(scopeId, Logix.ScopeRegistry.ScopedRuntimeTag);
|
|
64
|
-
const moduleRuntime = registry.get(
|
|
65
|
-
scopeId,
|
|
66
|
-
moduleToken
|
|
67
|
-
);
|
|
67
|
+
const moduleRuntime = registry.get(scopeId, moduleToken);
|
|
68
68
|
if (!scopedRuntime || !moduleRuntime) {
|
|
69
69
|
throw new Error(
|
|
70
70
|
`[ModuleScope.Bridge] Scope "${scopeId}" is not registered (or has been disposed). Ensure you have a corresponding <ModuleScope.Provider options={{ scopeId }}> mounted.`
|
|
@@ -4,16 +4,16 @@ import {
|
|
|
4
4
|
getModuleCache,
|
|
5
5
|
isDevEnv,
|
|
6
6
|
useLayerBinding
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-L7KTYBXN.js";
|
|
8
8
|
|
|
9
9
|
// src/internal/provider/RuntimeProvider.tsx
|
|
10
10
|
import React2, { useContext, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
|
|
11
|
-
import {
|
|
11
|
+
import { Cause, Effect as Effect2, Layer as Layer2, Scope, ServiceMap as ServiceMap2 } from "effect";
|
|
12
12
|
import * as Logix2 from "@logixjs/core";
|
|
13
13
|
|
|
14
14
|
// src/internal/provider/config.ts
|
|
15
|
-
import { Config,
|
|
16
|
-
var ReactRuntimeConfigTag = class extends
|
|
15
|
+
import { Config, Effect, Layer, Option, ServiceMap } from "effect";
|
|
16
|
+
var ReactRuntimeConfigTag = class extends ServiceMap.Service()("@logixjs/react/RuntimeConfig") {
|
|
17
17
|
};
|
|
18
18
|
var DEFAULT_CONFIG = {
|
|
19
19
|
gcTime: 500,
|
|
@@ -394,6 +394,9 @@ var RuntimeProvider = ({
|
|
|
394
394
|
}) => {
|
|
395
395
|
const parent = useContext(RuntimeContext);
|
|
396
396
|
const baseRuntime = useRuntimeResolution(runtime, parent);
|
|
397
|
+
const providerStartedAtRef = React2.useRef(performance.now());
|
|
398
|
+
const providerReadyAtRef = React2.useRef(void 0);
|
|
399
|
+
const didReportProviderGatingRef = React2.useRef(false);
|
|
397
400
|
const resolvedPolicy = useMemo(
|
|
398
401
|
() => resolveRuntimeProviderPolicy({
|
|
399
402
|
policy,
|
|
@@ -403,6 +406,20 @@ var RuntimeProvider = ({
|
|
|
403
406
|
);
|
|
404
407
|
const onErrorRef = React2.useRef(onError);
|
|
405
408
|
onErrorRef.current = onError;
|
|
409
|
+
const hasTickServices = useMemo(() => {
|
|
410
|
+
try {
|
|
411
|
+
Logix2.InternalContracts.getRuntimeStore(baseRuntime);
|
|
412
|
+
return true;
|
|
413
|
+
} catch {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
}, [baseRuntime]);
|
|
417
|
+
const { binding: tickBinding } = useLayerBinding(
|
|
418
|
+
baseRuntime,
|
|
419
|
+
Logix2.InternalContracts.tickServicesLayer,
|
|
420
|
+
!hasTickServices,
|
|
421
|
+
onErrorRef.current
|
|
422
|
+
);
|
|
406
423
|
const { binding: layerBinding } = useLayerBinding(baseRuntime, layer, Boolean(layer), onErrorRef.current);
|
|
407
424
|
const onErrorSink = useMemo(() => {
|
|
408
425
|
if (!onError) return null;
|
|
@@ -419,7 +436,7 @@ var RuntimeProvider = ({
|
|
|
419
436
|
moduleId: event.moduleId,
|
|
420
437
|
instanceId: event.instanceId,
|
|
421
438
|
runtimeLabel: event.runtimeLabel
|
|
422
|
-
}).pipe(Effect2.
|
|
439
|
+
}).pipe(Effect2.catchCause(() => Effect2.void));
|
|
423
440
|
}
|
|
424
441
|
if (event.type === "diagnostic" && event.severity === "error") {
|
|
425
442
|
return handler(
|
|
@@ -438,7 +455,7 @@ var RuntimeProvider = ({
|
|
|
438
455
|
instanceId: event.instanceId,
|
|
439
456
|
runtimeLabel: event.runtimeLabel
|
|
440
457
|
}
|
|
441
|
-
).pipe(Effect2.
|
|
458
|
+
).pipe(Effect2.catchCause(() => Effect2.void));
|
|
442
459
|
}
|
|
443
460
|
return Effect2.void;
|
|
444
461
|
}
|
|
@@ -453,25 +470,23 @@ var RuntimeProvider = ({
|
|
|
453
470
|
return layerBinding.debugSinks;
|
|
454
471
|
}
|
|
455
472
|
try {
|
|
456
|
-
return baseRuntime.runSync(
|
|
457
|
-
FiberRef.get(Logix2.Debug.internal.currentDebugSinks)
|
|
458
|
-
);
|
|
473
|
+
return baseRuntime.runSync(Effect2.service(Logix2.Debug.internal.currentDebugSinks).pipe(Effect2.orDie));
|
|
459
474
|
} catch {
|
|
460
475
|
return [];
|
|
461
476
|
}
|
|
462
477
|
}, [baseRuntime, layerBinding, onErrorSink]);
|
|
463
478
|
const runtimeWithBindings = useMemo(
|
|
464
|
-
() => layerBinding || onErrorSink ? createRuntimeAdapter(
|
|
479
|
+
() => tickBinding || layerBinding || onErrorSink ? createRuntimeAdapter(
|
|
465
480
|
baseRuntime,
|
|
466
|
-
layerBinding ? [layerBinding.context] : [],
|
|
467
|
-
layerBinding ? [layerBinding.scope] : [],
|
|
468
|
-
layerBinding ? [layerBinding.loggers] : [],
|
|
469
|
-
layerBinding ? [layerBinding.logLevel] : [],
|
|
481
|
+
[...tickBinding ? [tickBinding.context] : [], ...layerBinding ? [layerBinding.context] : []],
|
|
482
|
+
[...tickBinding ? [tickBinding.scope] : [], ...layerBinding ? [layerBinding.scope] : []],
|
|
483
|
+
layerBinding ? [layerBinding.loggers] : tickBinding ? [tickBinding.loggers] : [],
|
|
484
|
+
layerBinding ? [layerBinding.logLevel] : tickBinding ? [tickBinding.logLevel] : [],
|
|
470
485
|
[
|
|
471
486
|
onErrorSink ? [onErrorSink, ...inheritedDebugSinks] : layerBinding ? layerBinding.debugSinks : []
|
|
472
487
|
]
|
|
473
488
|
) : baseRuntime,
|
|
474
|
-
[baseRuntime, inheritedDebugSinks, layerBinding, onErrorSink]
|
|
489
|
+
[baseRuntime, inheritedDebugSinks, layerBinding, onErrorSink, tickBinding]
|
|
475
490
|
);
|
|
476
491
|
const didReportSyncConfigSnapshotRef = React2.useRef(false);
|
|
477
492
|
const [configState, setConfigState] = useState2(() => {
|
|
@@ -576,11 +591,47 @@ var RuntimeProvider = ({
|
|
|
576
591
|
}),
|
|
577
592
|
[runtimeWithBindings, configState, resolvedPolicy]
|
|
578
593
|
);
|
|
594
|
+
const isTickServicesReady = hasTickServices || tickBinding !== null;
|
|
579
595
|
const isLayerReady = !layer || layerBinding !== null;
|
|
580
596
|
const isConfigReady = configState.loaded;
|
|
581
597
|
const resolveFallback = (phase) => {
|
|
582
598
|
return resolveRuntimeProviderFallback({ fallback, phase, policyMode: resolvedPolicy.mode });
|
|
583
599
|
};
|
|
600
|
+
const preloadCache = useMemo(
|
|
601
|
+
() => getModuleCache(runtimeWithBindings, configState.snapshot, configState.version),
|
|
602
|
+
[runtimeWithBindings, configState.snapshot, configState.version]
|
|
603
|
+
);
|
|
604
|
+
const syncWarmPreloadReady = useMemo(() => {
|
|
605
|
+
if (resolvedPolicy.mode !== "defer") return false;
|
|
606
|
+
if (!resolvedPolicy.preload) return true;
|
|
607
|
+
if (!isLayerReady || !isConfigReady) return false;
|
|
608
|
+
const handles = resolvedPolicy.preload.handles;
|
|
609
|
+
if (handles.length === 0) return true;
|
|
610
|
+
for (const handle of handles) {
|
|
611
|
+
if (handle?._tag === "ModuleImpl") {
|
|
612
|
+
const moduleId = handle.module?.id ?? "ModuleImpl";
|
|
613
|
+
const key2 = resolvedPolicy.preload.keysByModuleId.get(moduleId) ?? getPreloadKeyForModuleId(moduleId);
|
|
614
|
+
const factory2 = (scope) => Layer2.buildWithScope(handle.layer, scope).pipe(
|
|
615
|
+
Effect2.map((context) => ServiceMap2.get(context, handle.module))
|
|
616
|
+
);
|
|
617
|
+
const value2 = preloadCache.warmSync(key2, factory2, configState.snapshot.gcTime, moduleId, {
|
|
618
|
+
entrypoint: "react.runtime.preload.sync-warm",
|
|
619
|
+
policyMode: "defer"
|
|
620
|
+
});
|
|
621
|
+
if (!value2) return false;
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
const tagId = handle.id ?? "ModuleTag";
|
|
625
|
+
const key = resolvedPolicy.preload.keysByTagId.get(tagId) ?? getPreloadKeyForTagId(tagId);
|
|
626
|
+
const factory = (scope) => Scope.provide(scope)(Effect2.service(handle).pipe(Effect2.orDie));
|
|
627
|
+
const value = preloadCache.warmSync(key, factory, configState.snapshot.gcTime, tagId, {
|
|
628
|
+
entrypoint: "react.runtime.preload.sync-warm",
|
|
629
|
+
policyMode: "defer"
|
|
630
|
+
});
|
|
631
|
+
if (!value) return false;
|
|
632
|
+
}
|
|
633
|
+
return true;
|
|
634
|
+
}, [resolvedPolicy, isLayerReady, isConfigReady, preloadCache, configState.snapshot.gcTime]);
|
|
584
635
|
const [deferReady, setDeferReady] = useState2(false);
|
|
585
636
|
useEffect2(() => {
|
|
586
637
|
if (resolvedPolicy.mode !== "defer") {
|
|
@@ -594,6 +645,10 @@ var RuntimeProvider = ({
|
|
|
594
645
|
if (resolvedPolicy.mode !== "defer") {
|
|
595
646
|
return;
|
|
596
647
|
}
|
|
648
|
+
if (syncWarmPreloadReady) {
|
|
649
|
+
setDeferReady(true);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
597
652
|
setDeferReady(false);
|
|
598
653
|
if (!resolvedPolicy.preload) {
|
|
599
654
|
setDeferReady(true);
|
|
@@ -603,7 +658,7 @@ var RuntimeProvider = ({
|
|
|
603
658
|
return;
|
|
604
659
|
}
|
|
605
660
|
let cancelled = false;
|
|
606
|
-
const cache =
|
|
661
|
+
const cache = preloadCache;
|
|
607
662
|
const preloadHandles = resolvedPolicy.preload.handles;
|
|
608
663
|
if (preloadHandles.length === 0) {
|
|
609
664
|
setDeferReady(true);
|
|
@@ -621,13 +676,14 @@ var RuntimeProvider = ({
|
|
|
621
676
|
const moduleId = handle.module?.id ?? "ModuleImpl";
|
|
622
677
|
const key2 = resolvedPolicy.preload.keysByModuleId.get(moduleId) ?? getPreloadKeyForModuleId(moduleId);
|
|
623
678
|
const factory2 = (scope) => Layer2.buildWithScope(handle.layer, scope).pipe(
|
|
624
|
-
Effect2.map((context) =>
|
|
679
|
+
Effect2.map((context) => ServiceMap2.get(context, handle.module))
|
|
625
680
|
);
|
|
626
681
|
const op2 = cache.preload(key2, factory2, {
|
|
627
682
|
ownerId: moduleId,
|
|
628
683
|
yield: resolvedPolicy.preload.yield,
|
|
629
684
|
entrypoint: "react.runtime.preload",
|
|
630
|
-
policyMode: "defer"
|
|
685
|
+
policyMode: "defer",
|
|
686
|
+
optimisticSyncBudgetMs: resolvedPolicy.syncBudgetMs
|
|
631
687
|
});
|
|
632
688
|
allCancels.add(op2.cancel);
|
|
633
689
|
await op2.promise;
|
|
@@ -652,14 +708,13 @@ var RuntimeProvider = ({
|
|
|
652
708
|
}
|
|
653
709
|
const tagId = handle.id ?? "ModuleTag";
|
|
654
710
|
const key = resolvedPolicy.preload.keysByTagId.get(tagId) ?? getPreloadKeyForTagId(tagId);
|
|
655
|
-
const factory = (scope) => handle.pipe(
|
|
656
|
-
Scope.extend(scope)
|
|
657
|
-
);
|
|
711
|
+
const factory = (scope) => Scope.provide(scope)(Effect2.service(handle).pipe(Effect2.orDie));
|
|
658
712
|
const op = cache.preload(key, factory, {
|
|
659
713
|
ownerId: tagId,
|
|
660
714
|
yield: resolvedPolicy.preload.yield,
|
|
661
715
|
entrypoint: "react.runtime.preload",
|
|
662
|
-
policyMode: "defer"
|
|
716
|
+
policyMode: "defer",
|
|
717
|
+
optimisticSyncBudgetMs: resolvedPolicy.syncBudgetMs
|
|
663
718
|
});
|
|
664
719
|
allCancels.add(op.cancel);
|
|
665
720
|
await op.promise;
|
|
@@ -697,7 +752,7 @@ var RuntimeProvider = ({
|
|
|
697
752
|
if (cancelled) return;
|
|
698
753
|
if (onErrorRef.current) {
|
|
699
754
|
runtimeWithBindings.runFork(
|
|
700
|
-
onErrorRef.current(Cause.die(error), { source: "provider", phase: "provider.layer.build" }).pipe(Effect2.
|
|
755
|
+
onErrorRef.current(Cause.die(error), { source: "provider", phase: "provider.layer.build" }).pipe(Effect2.catchCause(() => Effect2.void))
|
|
701
756
|
);
|
|
702
757
|
}
|
|
703
758
|
setDeferReady(true);
|
|
@@ -730,12 +785,54 @@ var RuntimeProvider = ({
|
|
|
730
785
|
release();
|
|
731
786
|
};
|
|
732
787
|
}, [resolvedPolicy.mode, deferReady]);
|
|
733
|
-
const isReady = isLayerReady && isConfigReady && (resolvedPolicy.mode !== "defer" || deferReady);
|
|
788
|
+
const isReady = isTickServicesReady && isLayerReady && isConfigReady && (resolvedPolicy.mode !== "defer" || deferReady || syncWarmPreloadReady);
|
|
789
|
+
if (isReady && providerReadyAtRef.current === void 0) {
|
|
790
|
+
providerReadyAtRef.current = performance.now();
|
|
791
|
+
}
|
|
792
|
+
useEffect2(() => {
|
|
793
|
+
if (!isReady) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
if (didReportProviderGatingRef.current) {
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
let diagnosticsLevel = "off";
|
|
800
|
+
try {
|
|
801
|
+
diagnosticsLevel = runtimeWithBindings.runSync(
|
|
802
|
+
Effect2.service(Logix2.Debug.internal.currentDiagnosticsLevel).pipe(Effect2.orDie)
|
|
803
|
+
);
|
|
804
|
+
} catch {
|
|
805
|
+
diagnosticsLevel = isDevEnv() ? "light" : "off";
|
|
806
|
+
}
|
|
807
|
+
if (diagnosticsLevel === "off") {
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
didReportProviderGatingRef.current = true;
|
|
811
|
+
const readyAt = providerReadyAtRef.current ?? performance.now();
|
|
812
|
+
const durationMs = Math.round((readyAt - providerStartedAtRef.current) * 100) / 100;
|
|
813
|
+
const effectDelayMs = Math.round((performance.now() - readyAt) * 100) / 100;
|
|
814
|
+
void runtimeWithBindings.runPromise(
|
|
815
|
+
Logix2.Debug.record({
|
|
816
|
+
type: "trace:react.provider.gating",
|
|
817
|
+
data: {
|
|
818
|
+
event: "ready",
|
|
819
|
+
policyMode: resolvedPolicy.mode,
|
|
820
|
+
durationMs,
|
|
821
|
+
effectDelayMs,
|
|
822
|
+
configLoadMode: configState.loadMode,
|
|
823
|
+
syncOverBudget: Boolean(configState.syncOverBudget),
|
|
824
|
+
syncDurationMs: configState.syncDurationMs !== void 0 ? Math.round(configState.syncDurationMs * 100) / 100 : void 0
|
|
825
|
+
}
|
|
826
|
+
})
|
|
827
|
+
).catch(() => {
|
|
828
|
+
});
|
|
829
|
+
}, [configState.loadMode, configState.syncDurationMs, configState.syncOverBudget, isReady, resolvedPolicy.mode, runtimeWithBindings]);
|
|
734
830
|
if (!isReady) {
|
|
735
831
|
const blockersList = [
|
|
832
|
+
isTickServicesReady ? null : "tick",
|
|
736
833
|
isLayerReady ? null : "layer",
|
|
737
834
|
isConfigReady ? null : "config",
|
|
738
|
-
resolvedPolicy.mode !== "defer" || deferReady ? null : "preload"
|
|
835
|
+
resolvedPolicy.mode !== "defer" || deferReady || syncWarmPreloadReady ? null : "preload"
|
|
739
836
|
].filter((x) => x !== null);
|
|
740
837
|
const blockers = blockersList.length > 0 ? blockersList.join("+") : void 0;
|
|
741
838
|
return /* @__PURE__ */ jsx2(
|