bunja 3.0.0-alpha.3 → 3.0.0-alpha.4
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/bunja.ts +32 -49
- package/deno.json +1 -1
- package/dist/{bunja-BJSmIdkQ.cjs → bunja-C_hneAUK.cjs} +26 -23
- package/dist/{bunja-CtHOS4_Q.js → bunja-D0Qa6gsc.js} +26 -23
- package/dist/bunja.cjs +1 -1
- package/dist/bunja.js +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.js +1 -1
- package/dist/solid.cjs +1 -1
- package/dist/solid.js +1 -1
- package/package.json +1 -1
- package/test.ts +99 -0
package/bunja.ts
CHANGED
|
@@ -94,7 +94,6 @@ export type Dep<T> = Bunja<T, any> | Scope<T>;
|
|
|
94
94
|
|
|
95
95
|
type AnyBunja = Bunja<any, any>;
|
|
96
96
|
type ScopeInstanceMap = Map<Scope<unknown>, ScopeInstance>;
|
|
97
|
-
type BunjaDependencyEdge = "required" | "optional";
|
|
98
97
|
|
|
99
98
|
interface BunjaFrame {
|
|
100
99
|
use: BunjaUseFn;
|
|
@@ -251,11 +250,8 @@ function getBoundScopeSet(
|
|
|
251
250
|
function getScopeInstances(
|
|
252
251
|
scopes: Scope<unknown>[],
|
|
253
252
|
scopeInstanceMap: ScopeInstanceMap,
|
|
254
|
-
excludeScopes: Set<Scope<unknown>> = new Set(),
|
|
255
253
|
): ScopeInstance[] {
|
|
256
|
-
return scopes
|
|
257
|
-
.filter((scope) => !excludeScopes.has(scope))
|
|
258
|
-
.map((scope) => scopeInstanceMap.get(scope)!);
|
|
254
|
+
return scopes.map((scope) => scopeInstanceMap.get(scope)!);
|
|
259
255
|
}
|
|
260
256
|
|
|
261
257
|
function dedupeScopeInstances(
|
|
@@ -331,6 +327,7 @@ export class BunjaStore {
|
|
|
331
327
|
readScope,
|
|
332
328
|
new Set(),
|
|
333
329
|
bunjaRef.seed,
|
|
330
|
+
true,
|
|
334
331
|
);
|
|
335
332
|
const result: BunjaStoreGetResult<T> = {
|
|
336
333
|
value: resolved.value,
|
|
@@ -366,6 +363,7 @@ export class BunjaStore {
|
|
|
366
363
|
readScope: ReadScope,
|
|
367
364
|
inProgressBunjas: Set<AnyBunja>,
|
|
368
365
|
seed: Seed = bunjaRef.bunja.defaultSeed,
|
|
366
|
+
includeBoundScopeDeps: boolean = false,
|
|
369
367
|
): ResolvedBunja<T> {
|
|
370
368
|
const { bunja } = bunjaRef;
|
|
371
369
|
if (inProgressBunjas.has(bunja)) {
|
|
@@ -382,6 +380,7 @@ export class BunjaStore {
|
|
|
382
380
|
resolvedReadScope,
|
|
383
381
|
inProgressBunjas,
|
|
384
382
|
seed,
|
|
383
|
+
includeBoundScopeDeps,
|
|
385
384
|
);
|
|
386
385
|
}
|
|
387
386
|
const scopeInstanceMap = this.#resolveScopeInstanceMap(
|
|
@@ -394,9 +393,10 @@ export class BunjaStore {
|
|
|
394
393
|
scopeInstanceMap,
|
|
395
394
|
);
|
|
396
395
|
const directDeps = getScopeInstances(
|
|
397
|
-
|
|
396
|
+
includeBoundScopeDeps
|
|
397
|
+
? bunja.requiredScopes
|
|
398
|
+
: bunja.requiredScopes.filter((scope) => !boundScopes.has(scope)),
|
|
398
399
|
scopeInstanceMap,
|
|
399
|
-
boundScopes,
|
|
400
400
|
);
|
|
401
401
|
const baseId = bunja.calcBaseInstanceId(scopeInstanceMap);
|
|
402
402
|
const bucket = this.#bunjaBuckets.get(baseId);
|
|
@@ -433,6 +433,7 @@ export class BunjaStore {
|
|
|
433
433
|
resolvedReadScope,
|
|
434
434
|
inProgressBunjas,
|
|
435
435
|
seed,
|
|
436
|
+
includeBoundScopeDeps,
|
|
436
437
|
scopeInstanceMap,
|
|
437
438
|
);
|
|
438
439
|
} finally {
|
|
@@ -444,6 +445,7 @@ export class BunjaStore {
|
|
|
444
445
|
readScope: ReadScope,
|
|
445
446
|
inProgressBunjas: Set<AnyBunja>,
|
|
446
447
|
seed: Seed,
|
|
448
|
+
includeBoundScopeDeps: boolean,
|
|
447
449
|
initialScopeInstanceMap: ScopeInstanceMap = new Map(),
|
|
448
450
|
): ResolvedBunja<T> {
|
|
449
451
|
const { bunja } = bunjaRef;
|
|
@@ -475,9 +477,10 @@ export class BunjaStore {
|
|
|
475
477
|
frame.scopeInstanceMap,
|
|
476
478
|
);
|
|
477
479
|
const directDeps = getScopeInstances(
|
|
478
|
-
|
|
480
|
+
includeBoundScopeDeps
|
|
481
|
+
? bunja.requiredScopes
|
|
482
|
+
: bunja.requiredScopes.filter((scope) => !boundScopes.has(scope)),
|
|
479
483
|
frame.scopeInstanceMap,
|
|
480
|
-
boundScopes,
|
|
481
484
|
);
|
|
482
485
|
const baseId = bunja.calcBaseInstanceId(frame.scopeInstanceMap);
|
|
483
486
|
const id = bunja.calcInstanceId(
|
|
@@ -560,11 +563,10 @@ export class BunjaStore {
|
|
|
560
563
|
return this.#useScopeInFrame(frame, dep as Scope<unknown>);
|
|
561
564
|
}
|
|
562
565
|
if (dep instanceof Bunja || isBunjaRef(dep)) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
);
|
|
566
|
+
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
567
|
+
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
568
|
+
currentBunja.addRequiredBunjaRef(graphRef);
|
|
569
|
+
return this.#useBunjaDependencyInFrame(frame, bunjaRef);
|
|
568
570
|
}
|
|
569
571
|
throw new Error("`bunja.use` can only be used with Bunja or Scope.");
|
|
570
572
|
}) as BunjaUseFn,
|
|
@@ -573,18 +575,15 @@ export class BunjaStore {
|
|
|
573
575
|
throw new Error("`bunja.will` can only be used with Bunja.");
|
|
574
576
|
}
|
|
575
577
|
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
576
|
-
|
|
578
|
+
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
579
|
+
currentBunja.addOptionalBunjaRef(graphRef);
|
|
577
580
|
return () => {
|
|
578
581
|
if (frameStack[frameStack.length - 1] !== frame) {
|
|
579
582
|
throw new Error(
|
|
580
583
|
"A thunk returned by `bunja.will` can only be called inside the same bunja init function.",
|
|
581
584
|
);
|
|
582
585
|
}
|
|
583
|
-
return this.#useBunjaDependencyInFrame(
|
|
584
|
-
frame,
|
|
585
|
-
bunjaRef,
|
|
586
|
-
"optional",
|
|
587
|
-
);
|
|
586
|
+
return this.#useBunjaDependencyInFrame(frame, bunjaRef);
|
|
588
587
|
};
|
|
589
588
|
}) as BunjaWillFn,
|
|
590
589
|
effect: ((callback: BunjaEffectCallback) => {
|
|
@@ -615,14 +614,8 @@ export class BunjaStore {
|
|
|
615
614
|
#useBunjaDependencyInFrame<T, Seed>(
|
|
616
615
|
frame: BunjaInitFrame,
|
|
617
616
|
bunjaRef: NormalizedBunjaRuntimeRef<T, Seed>,
|
|
618
|
-
edge: BunjaDependencyEdge,
|
|
619
617
|
): T {
|
|
620
618
|
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
621
|
-
if (edge === "optional" || graphRef.scopeValuePairs.length > 0) {
|
|
622
|
-
frame.currentBunja.addOptionalBunjaRef(graphRef);
|
|
623
|
-
} else if (edge === "required") {
|
|
624
|
-
frame.currentBunja.addRequiredBunjaRef(graphRef);
|
|
625
|
-
}
|
|
626
619
|
const resolved = this.#resolveBunjaRef(
|
|
627
620
|
graphRef,
|
|
628
621
|
frame.readScope,
|
|
@@ -725,11 +718,14 @@ export class BunjaStore {
|
|
|
725
718
|
return readScope(dep as Scope<unknown>);
|
|
726
719
|
}
|
|
727
720
|
if (dep instanceof Bunja || isBunjaRef(dep)) {
|
|
728
|
-
const bunjaRef =
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
721
|
+
const bunjaRef = toBunjaGraphRef(
|
|
722
|
+
normalizeBunjaRuntimeRef(dep, scopeValuePairs),
|
|
723
|
+
);
|
|
724
|
+
currentBunja.addRequiredBunjaRef(bunjaRef);
|
|
725
|
+
return this.#prebakeBunjaRef(
|
|
726
|
+
bunjaRef,
|
|
727
|
+
readScope,
|
|
728
|
+
prebakeContext,
|
|
733
729
|
);
|
|
734
730
|
}
|
|
735
731
|
throw new Error("`bunja.use` can only be used with Bunja or Scope.");
|
|
@@ -760,22 +756,6 @@ export class BunjaStore {
|
|
|
760
756
|
} satisfies BunjaPrebakeFrame;
|
|
761
757
|
return frame;
|
|
762
758
|
}
|
|
763
|
-
#prebakeBunjaDependencyInFrame<T, Seed>(
|
|
764
|
-
frame: BunjaPrebakeFrame,
|
|
765
|
-
bunjaRef: NormalizedBunjaRef<T, Seed>,
|
|
766
|
-
edge: BunjaDependencyEdge,
|
|
767
|
-
): T {
|
|
768
|
-
if (edge === "optional" || bunjaRef.scopeValuePairs.length > 0) {
|
|
769
|
-
frame.currentBunja.addOptionalBunjaRef(bunjaRef);
|
|
770
|
-
} else if (edge === "required") {
|
|
771
|
-
frame.currentBunja.addRequiredBunjaRef(bunjaRef);
|
|
772
|
-
}
|
|
773
|
-
return this.#prebakeBunjaRef(
|
|
774
|
-
bunjaRef,
|
|
775
|
-
frame.readScope,
|
|
776
|
-
frame.prebakeContext,
|
|
777
|
-
);
|
|
778
|
-
}
|
|
779
759
|
#resolveScopeInstanceMap(
|
|
780
760
|
bunja: AnyBunja,
|
|
781
761
|
readScope: ReadScope,
|
|
@@ -984,8 +964,11 @@ export class Bunja<T, Seed = NoSeed> {
|
|
|
984
964
|
const requiredBunjas = this.requiredBunjas;
|
|
985
965
|
const expandedRequiredBunjas = toposortRequiredBunjas(requiredBunjas);
|
|
986
966
|
const requiredScopeSet = new Set<Scope<unknown>>();
|
|
987
|
-
for (const
|
|
988
|
-
|
|
967
|
+
for (const ref of requiredBunjaRefs) {
|
|
968
|
+
const boundScopes = getBoundScopeSet(ref.scopeValuePairs);
|
|
969
|
+
for (const scope of ref.bunja.requiredScopes) {
|
|
970
|
+
if (!boundScopes.has(scope)) requiredScopeSet.add(scope);
|
|
971
|
+
}
|
|
989
972
|
}
|
|
990
973
|
for (const scope of scopes) requiredScopeSet.add(scope);
|
|
991
974
|
const requiredScopes = Array.from(requiredScopeSet);
|
package/deno.json
CHANGED
|
@@ -73,8 +73,8 @@ function isBunjaRef(value) {
|
|
|
73
73
|
function getBoundScopeSet(scopeValuePairs) {
|
|
74
74
|
return new Set(scopeValuePairs.map(([scope]) => scope));
|
|
75
75
|
}
|
|
76
|
-
function getScopeInstances(scopes, scopeInstanceMap
|
|
77
|
-
return scopes.
|
|
76
|
+
function getScopeInstances(scopes, scopeInstanceMap) {
|
|
77
|
+
return scopes.map((scope) => scopeInstanceMap.get(scope));
|
|
78
78
|
}
|
|
79
79
|
function dedupeScopeInstances(scopeInstances) {
|
|
80
80
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -127,7 +127,7 @@ var BunjaStore = class BunjaStore {
|
|
|
127
127
|
}
|
|
128
128
|
get(bunjaOrRef, readScope) {
|
|
129
129
|
const bunjaRef = normalizeBunjaRuntimeRef(bunjaOrRef);
|
|
130
|
-
const resolved = this.#resolveBunjaRef(toBunjaGraphRef(bunjaRef), readScope, /* @__PURE__ */ new Set(), bunjaRef.seed);
|
|
130
|
+
const resolved = this.#resolveBunjaRef(toBunjaGraphRef(bunjaRef), readScope, /* @__PURE__ */ new Set(), bunjaRef.seed, true);
|
|
131
131
|
const result = {
|
|
132
132
|
value: resolved.value,
|
|
133
133
|
mount: resolved.mount,
|
|
@@ -150,17 +150,17 @@ var BunjaStore = class BunjaStore {
|
|
|
150
150
|
requiredScopes: bunjaRef.bunja.requiredScopes
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
|
-
#resolveBunjaRef(bunjaRef, readScope, inProgressBunjas, seed = bunjaRef.bunja.defaultSeed) {
|
|
153
|
+
#resolveBunjaRef(bunjaRef, readScope, inProgressBunjas, seed = bunjaRef.bunja.defaultSeed, includeBoundScopeDeps = false) {
|
|
154
154
|
const { bunja: bunja$1 } = bunjaRef;
|
|
155
155
|
if (inProgressBunjas.has(bunja$1)) throw new Error("Circular bunja dependency detected.");
|
|
156
156
|
const resolvedReadScope = bunjaRef.scopeValuePairs.length > 0 ? createReadScopeFn(bunjaRef.scopeValuePairs, readScope) : readScope;
|
|
157
157
|
inProgressBunjas.add(bunja$1);
|
|
158
158
|
try {
|
|
159
|
-
if (!bunja$1.baked) return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed);
|
|
159
|
+
if (!bunja$1.baked) return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed, includeBoundScopeDeps);
|
|
160
160
|
const scopeInstanceMap = this.#resolveScopeInstanceMap(bunja$1, resolvedReadScope);
|
|
161
161
|
const boundScopes = getBoundScopeSet(bunjaRef.scopeValuePairs);
|
|
162
162
|
const scopeInstances = getScopeInstances(bunja$1.requiredScopes, scopeInstanceMap);
|
|
163
|
-
const directDeps = getScopeInstances(bunja$1.requiredScopes
|
|
163
|
+
const directDeps = getScopeInstances(includeBoundScopeDeps ? bunja$1.requiredScopes : bunja$1.requiredScopes.filter((scope) => !boundScopes.has(scope)), scopeInstanceMap);
|
|
164
164
|
const baseId = bunja$1.calcBaseInstanceId(scopeInstanceMap);
|
|
165
165
|
const bucket = this.#bunjaBuckets.get(baseId);
|
|
166
166
|
if (bucket) for (const candidateId of Array.from(bucket)) {
|
|
@@ -175,12 +175,12 @@ var BunjaStore = class BunjaStore {
|
|
|
175
175
|
if (!instance) continue;
|
|
176
176
|
return this.#toResolvedBunja(instance, scopeInstances, directDeps, activeDeps.deps);
|
|
177
177
|
}
|
|
178
|
-
return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed, scopeInstanceMap);
|
|
178
|
+
return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed, includeBoundScopeDeps, scopeInstanceMap);
|
|
179
179
|
} finally {
|
|
180
180
|
inProgressBunjas.delete(bunja$1);
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
-
#createResolvedBunja(bunjaRef, readScope, inProgressBunjas, seed, initialScopeInstanceMap = /* @__PURE__ */ new Map()) {
|
|
183
|
+
#createResolvedBunja(bunjaRef, readScope, inProgressBunjas, seed, includeBoundScopeDeps, initialScopeInstanceMap = /* @__PURE__ */ new Map()) {
|
|
184
184
|
const { bunja: bunja$1 } = bunjaRef;
|
|
185
185
|
return this.wrapInstance((dispose) => {
|
|
186
186
|
let instanceCreated = false;
|
|
@@ -197,7 +197,7 @@ var BunjaStore = class BunjaStore {
|
|
|
197
197
|
this.#ensureRequiredScopeInstances(bunja$1, frame.scopeInstanceMap, readScope);
|
|
198
198
|
const boundScopes = getBoundScopeSet(bunjaRef.scopeValuePairs);
|
|
199
199
|
const scopeInstances = getScopeInstances(bunja$1.requiredScopes, frame.scopeInstanceMap);
|
|
200
|
-
const directDeps = getScopeInstances(bunja$1.requiredScopes, frame.scopeInstanceMap
|
|
200
|
+
const directDeps = getScopeInstances(includeBoundScopeDeps ? bunja$1.requiredScopes : bunja$1.requiredScopes.filter((scope) => !boundScopes.has(scope)), frame.scopeInstanceMap);
|
|
201
201
|
const baseId = bunja$1.calcBaseInstanceId(frame.scopeInstanceMap);
|
|
202
202
|
const id = bunja$1.calcInstanceId(frame.scopeInstanceMap, frame.activeDependencyIds);
|
|
203
203
|
const existing = this.#bunjas[id];
|
|
@@ -242,16 +242,22 @@ var BunjaStore = class BunjaStore {
|
|
|
242
242
|
activeDependencyDeps: [],
|
|
243
243
|
use: ((dep, scopeValuePairs) => {
|
|
244
244
|
if (dep instanceof Scope) return this.#useScopeInFrame(frame, dep);
|
|
245
|
-
if (dep instanceof Bunja || isBunjaRef(dep))
|
|
245
|
+
if (dep instanceof Bunja || isBunjaRef(dep)) {
|
|
246
|
+
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
247
|
+
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
248
|
+
currentBunja.addRequiredBunjaRef(graphRef);
|
|
249
|
+
return this.#useBunjaDependencyInFrame(frame, bunjaRef);
|
|
250
|
+
}
|
|
246
251
|
throw new Error("`bunja.use` can only be used with Bunja or Scope.");
|
|
247
252
|
}),
|
|
248
253
|
will: ((dep, scopeValuePairs) => {
|
|
249
254
|
if (!(dep instanceof Bunja || isBunjaRef(dep))) throw new Error("`bunja.will` can only be used with Bunja.");
|
|
250
255
|
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
251
|
-
|
|
256
|
+
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
257
|
+
currentBunja.addOptionalBunjaRef(graphRef);
|
|
252
258
|
return () => {
|
|
253
259
|
if (frameStack[frameStack.length - 1] !== frame) throw new Error("A thunk returned by `bunja.will` can only be called inside the same bunja init function.");
|
|
254
|
-
return this.#useBunjaDependencyInFrame(frame, bunjaRef
|
|
260
|
+
return this.#useBunjaDependencyInFrame(frame, bunjaRef);
|
|
255
261
|
};
|
|
256
262
|
}),
|
|
257
263
|
effect: ((callback) => {
|
|
@@ -270,10 +276,8 @@ var BunjaStore = class BunjaStore {
|
|
|
270
276
|
}
|
|
271
277
|
return scopeInstance.value;
|
|
272
278
|
}
|
|
273
|
-
#useBunjaDependencyInFrame(frame, bunjaRef
|
|
279
|
+
#useBunjaDependencyInFrame(frame, bunjaRef) {
|
|
274
280
|
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
275
|
-
if (edge === "optional" || graphRef.scopeValuePairs.length > 0) frame.currentBunja.addOptionalBunjaRef(graphRef);
|
|
276
|
-
else if (edge === "required") frame.currentBunja.addRequiredBunjaRef(graphRef);
|
|
277
281
|
const resolved = this.#resolveBunjaRef(graphRef, frame.readScope, frame.inProgressBunjas, bunjaRef.seed);
|
|
278
282
|
frame.activeDependencyIds.add(resolved.instance.id);
|
|
279
283
|
frame.activeDependencyRecipes.push({
|
|
@@ -331,8 +335,9 @@ var BunjaStore = class BunjaStore {
|
|
|
331
335
|
return readScope(dep);
|
|
332
336
|
}
|
|
333
337
|
if (dep instanceof Bunja || isBunjaRef(dep)) {
|
|
334
|
-
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
335
|
-
|
|
338
|
+
const bunjaRef = toBunjaGraphRef(normalizeBunjaRuntimeRef(dep, scopeValuePairs));
|
|
339
|
+
currentBunja.addRequiredBunjaRef(bunjaRef);
|
|
340
|
+
return this.#prebakeBunjaRef(bunjaRef, readScope, prebakeContext);
|
|
336
341
|
}
|
|
337
342
|
throw new Error("`bunja.use` can only be used with Bunja or Scope.");
|
|
338
343
|
}),
|
|
@@ -350,11 +355,6 @@ var BunjaStore = class BunjaStore {
|
|
|
350
355
|
};
|
|
351
356
|
return frame;
|
|
352
357
|
}
|
|
353
|
-
#prebakeBunjaDependencyInFrame(frame, bunjaRef, edge) {
|
|
354
|
-
if (edge === "optional" || bunjaRef.scopeValuePairs.length > 0) frame.currentBunja.addOptionalBunjaRef(bunjaRef);
|
|
355
|
-
else if (edge === "required") frame.currentBunja.addRequiredBunjaRef(bunjaRef);
|
|
356
|
-
return this.#prebakeBunjaRef(bunjaRef, frame.readScope, frame.prebakeContext);
|
|
357
|
-
}
|
|
358
358
|
#resolveScopeInstanceMap(bunja$1, readScope) {
|
|
359
359
|
const scopeInstanceMap = /* @__PURE__ */ new Map();
|
|
360
360
|
this.#ensureRequiredScopeInstances(bunja$1, scopeInstanceMap, readScope);
|
|
@@ -485,7 +485,10 @@ var Bunja = class Bunja {
|
|
|
485
485
|
const requiredBunjas = this.requiredBunjas;
|
|
486
486
|
const expandedRequiredBunjas = toposortRequiredBunjas(requiredBunjas);
|
|
487
487
|
const requiredScopeSet = /* @__PURE__ */ new Set();
|
|
488
|
-
for (const
|
|
488
|
+
for (const ref of requiredBunjaRefs) {
|
|
489
|
+
const boundScopes = getBoundScopeSet(ref.scopeValuePairs);
|
|
490
|
+
for (const scope of ref.bunja.requiredScopes) if (!boundScopes.has(scope)) requiredScopeSet.add(scope);
|
|
491
|
+
}
|
|
489
492
|
for (const scope of scopes) requiredScopeSet.add(scope);
|
|
490
493
|
this.#phase = {
|
|
491
494
|
baked: true,
|
|
@@ -72,8 +72,8 @@ function isBunjaRef(value) {
|
|
|
72
72
|
function getBoundScopeSet(scopeValuePairs) {
|
|
73
73
|
return new Set(scopeValuePairs.map(([scope]) => scope));
|
|
74
74
|
}
|
|
75
|
-
function getScopeInstances(scopes, scopeInstanceMap
|
|
76
|
-
return scopes.
|
|
75
|
+
function getScopeInstances(scopes, scopeInstanceMap) {
|
|
76
|
+
return scopes.map((scope) => scopeInstanceMap.get(scope));
|
|
77
77
|
}
|
|
78
78
|
function dedupeScopeInstances(scopeInstances) {
|
|
79
79
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -126,7 +126,7 @@ var BunjaStore = class BunjaStore {
|
|
|
126
126
|
}
|
|
127
127
|
get(bunjaOrRef, readScope) {
|
|
128
128
|
const bunjaRef = normalizeBunjaRuntimeRef(bunjaOrRef);
|
|
129
|
-
const resolved = this.#resolveBunjaRef(toBunjaGraphRef(bunjaRef), readScope, /* @__PURE__ */ new Set(), bunjaRef.seed);
|
|
129
|
+
const resolved = this.#resolveBunjaRef(toBunjaGraphRef(bunjaRef), readScope, /* @__PURE__ */ new Set(), bunjaRef.seed, true);
|
|
130
130
|
const result = {
|
|
131
131
|
value: resolved.value,
|
|
132
132
|
mount: resolved.mount,
|
|
@@ -149,17 +149,17 @@ var BunjaStore = class BunjaStore {
|
|
|
149
149
|
requiredScopes: bunjaRef.bunja.requiredScopes
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
-
#resolveBunjaRef(bunjaRef, readScope, inProgressBunjas, seed = bunjaRef.bunja.defaultSeed) {
|
|
152
|
+
#resolveBunjaRef(bunjaRef, readScope, inProgressBunjas, seed = bunjaRef.bunja.defaultSeed, includeBoundScopeDeps = false) {
|
|
153
153
|
const { bunja: bunja$1 } = bunjaRef;
|
|
154
154
|
if (inProgressBunjas.has(bunja$1)) throw new Error("Circular bunja dependency detected.");
|
|
155
155
|
const resolvedReadScope = bunjaRef.scopeValuePairs.length > 0 ? createReadScopeFn(bunjaRef.scopeValuePairs, readScope) : readScope;
|
|
156
156
|
inProgressBunjas.add(bunja$1);
|
|
157
157
|
try {
|
|
158
|
-
if (!bunja$1.baked) return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed);
|
|
158
|
+
if (!bunja$1.baked) return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed, includeBoundScopeDeps);
|
|
159
159
|
const scopeInstanceMap = this.#resolveScopeInstanceMap(bunja$1, resolvedReadScope);
|
|
160
160
|
const boundScopes = getBoundScopeSet(bunjaRef.scopeValuePairs);
|
|
161
161
|
const scopeInstances = getScopeInstances(bunja$1.requiredScopes, scopeInstanceMap);
|
|
162
|
-
const directDeps = getScopeInstances(bunja$1.requiredScopes
|
|
162
|
+
const directDeps = getScopeInstances(includeBoundScopeDeps ? bunja$1.requiredScopes : bunja$1.requiredScopes.filter((scope) => !boundScopes.has(scope)), scopeInstanceMap);
|
|
163
163
|
const baseId = bunja$1.calcBaseInstanceId(scopeInstanceMap);
|
|
164
164
|
const bucket = this.#bunjaBuckets.get(baseId);
|
|
165
165
|
if (bucket) for (const candidateId of Array.from(bucket)) {
|
|
@@ -174,12 +174,12 @@ var BunjaStore = class BunjaStore {
|
|
|
174
174
|
if (!instance) continue;
|
|
175
175
|
return this.#toResolvedBunja(instance, scopeInstances, directDeps, activeDeps.deps);
|
|
176
176
|
}
|
|
177
|
-
return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed, scopeInstanceMap);
|
|
177
|
+
return this.#createResolvedBunja(bunjaRef, resolvedReadScope, inProgressBunjas, seed, includeBoundScopeDeps, scopeInstanceMap);
|
|
178
178
|
} finally {
|
|
179
179
|
inProgressBunjas.delete(bunja$1);
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
#createResolvedBunja(bunjaRef, readScope, inProgressBunjas, seed, initialScopeInstanceMap = /* @__PURE__ */ new Map()) {
|
|
182
|
+
#createResolvedBunja(bunjaRef, readScope, inProgressBunjas, seed, includeBoundScopeDeps, initialScopeInstanceMap = /* @__PURE__ */ new Map()) {
|
|
183
183
|
const { bunja: bunja$1 } = bunjaRef;
|
|
184
184
|
return this.wrapInstance((dispose) => {
|
|
185
185
|
let instanceCreated = false;
|
|
@@ -196,7 +196,7 @@ var BunjaStore = class BunjaStore {
|
|
|
196
196
|
this.#ensureRequiredScopeInstances(bunja$1, frame.scopeInstanceMap, readScope);
|
|
197
197
|
const boundScopes = getBoundScopeSet(bunjaRef.scopeValuePairs);
|
|
198
198
|
const scopeInstances = getScopeInstances(bunja$1.requiredScopes, frame.scopeInstanceMap);
|
|
199
|
-
const directDeps = getScopeInstances(bunja$1.requiredScopes, frame.scopeInstanceMap
|
|
199
|
+
const directDeps = getScopeInstances(includeBoundScopeDeps ? bunja$1.requiredScopes : bunja$1.requiredScopes.filter((scope) => !boundScopes.has(scope)), frame.scopeInstanceMap);
|
|
200
200
|
const baseId = bunja$1.calcBaseInstanceId(frame.scopeInstanceMap);
|
|
201
201
|
const id = bunja$1.calcInstanceId(frame.scopeInstanceMap, frame.activeDependencyIds);
|
|
202
202
|
const existing = this.#bunjas[id];
|
|
@@ -241,16 +241,22 @@ var BunjaStore = class BunjaStore {
|
|
|
241
241
|
activeDependencyDeps: [],
|
|
242
242
|
use: ((dep, scopeValuePairs) => {
|
|
243
243
|
if (dep instanceof Scope) return this.#useScopeInFrame(frame, dep);
|
|
244
|
-
if (dep instanceof Bunja || isBunjaRef(dep))
|
|
244
|
+
if (dep instanceof Bunja || isBunjaRef(dep)) {
|
|
245
|
+
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
246
|
+
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
247
|
+
currentBunja.addRequiredBunjaRef(graphRef);
|
|
248
|
+
return this.#useBunjaDependencyInFrame(frame, bunjaRef);
|
|
249
|
+
}
|
|
245
250
|
throw new Error("`bunja.use` can only be used with Bunja or Scope.");
|
|
246
251
|
}),
|
|
247
252
|
will: ((dep, scopeValuePairs) => {
|
|
248
253
|
if (!(dep instanceof Bunja || isBunjaRef(dep))) throw new Error("`bunja.will` can only be used with Bunja.");
|
|
249
254
|
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
250
|
-
|
|
255
|
+
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
256
|
+
currentBunja.addOptionalBunjaRef(graphRef);
|
|
251
257
|
return () => {
|
|
252
258
|
if (frameStack[frameStack.length - 1] !== frame) throw new Error("A thunk returned by `bunja.will` can only be called inside the same bunja init function.");
|
|
253
|
-
return this.#useBunjaDependencyInFrame(frame, bunjaRef
|
|
259
|
+
return this.#useBunjaDependencyInFrame(frame, bunjaRef);
|
|
254
260
|
};
|
|
255
261
|
}),
|
|
256
262
|
effect: ((callback) => {
|
|
@@ -269,10 +275,8 @@ var BunjaStore = class BunjaStore {
|
|
|
269
275
|
}
|
|
270
276
|
return scopeInstance.value;
|
|
271
277
|
}
|
|
272
|
-
#useBunjaDependencyInFrame(frame, bunjaRef
|
|
278
|
+
#useBunjaDependencyInFrame(frame, bunjaRef) {
|
|
273
279
|
const graphRef = toBunjaGraphRef(bunjaRef);
|
|
274
|
-
if (edge === "optional" || graphRef.scopeValuePairs.length > 0) frame.currentBunja.addOptionalBunjaRef(graphRef);
|
|
275
|
-
else if (edge === "required") frame.currentBunja.addRequiredBunjaRef(graphRef);
|
|
276
280
|
const resolved = this.#resolveBunjaRef(graphRef, frame.readScope, frame.inProgressBunjas, bunjaRef.seed);
|
|
277
281
|
frame.activeDependencyIds.add(resolved.instance.id);
|
|
278
282
|
frame.activeDependencyRecipes.push({
|
|
@@ -330,8 +334,9 @@ var BunjaStore = class BunjaStore {
|
|
|
330
334
|
return readScope(dep);
|
|
331
335
|
}
|
|
332
336
|
if (dep instanceof Bunja || isBunjaRef(dep)) {
|
|
333
|
-
const bunjaRef = normalizeBunjaRuntimeRef(dep, scopeValuePairs);
|
|
334
|
-
|
|
337
|
+
const bunjaRef = toBunjaGraphRef(normalizeBunjaRuntimeRef(dep, scopeValuePairs));
|
|
338
|
+
currentBunja.addRequiredBunjaRef(bunjaRef);
|
|
339
|
+
return this.#prebakeBunjaRef(bunjaRef, readScope, prebakeContext);
|
|
335
340
|
}
|
|
336
341
|
throw new Error("`bunja.use` can only be used with Bunja or Scope.");
|
|
337
342
|
}),
|
|
@@ -349,11 +354,6 @@ var BunjaStore = class BunjaStore {
|
|
|
349
354
|
};
|
|
350
355
|
return frame;
|
|
351
356
|
}
|
|
352
|
-
#prebakeBunjaDependencyInFrame(frame, bunjaRef, edge) {
|
|
353
|
-
if (edge === "optional" || bunjaRef.scopeValuePairs.length > 0) frame.currentBunja.addOptionalBunjaRef(bunjaRef);
|
|
354
|
-
else if (edge === "required") frame.currentBunja.addRequiredBunjaRef(bunjaRef);
|
|
355
|
-
return this.#prebakeBunjaRef(bunjaRef, frame.readScope, frame.prebakeContext);
|
|
356
|
-
}
|
|
357
357
|
#resolveScopeInstanceMap(bunja$1, readScope) {
|
|
358
358
|
const scopeInstanceMap = /* @__PURE__ */ new Map();
|
|
359
359
|
this.#ensureRequiredScopeInstances(bunja$1, scopeInstanceMap, readScope);
|
|
@@ -484,7 +484,10 @@ var Bunja = class Bunja {
|
|
|
484
484
|
const requiredBunjas = this.requiredBunjas;
|
|
485
485
|
const expandedRequiredBunjas = toposortRequiredBunjas(requiredBunjas);
|
|
486
486
|
const requiredScopeSet = /* @__PURE__ */ new Set();
|
|
487
|
-
for (const
|
|
487
|
+
for (const ref of requiredBunjaRefs) {
|
|
488
|
+
const boundScopes = getBoundScopeSet(ref.scopeValuePairs);
|
|
489
|
+
for (const scope of ref.bunja.requiredScopes) if (!boundScopes.has(scope)) requiredScopeSet.add(scope);
|
|
490
|
+
}
|
|
488
491
|
for (const scope of scopes) requiredScopeSet.add(scope);
|
|
489
492
|
this.#phase = {
|
|
490
493
|
baked: true,
|
package/dist/bunja.cjs
CHANGED
package/dist/bunja.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Bunja, BunjaStore, Scope, bunja, createBunjaStore, createReadScopeFn, createScope, delayUnmount } from "./bunja-
|
|
1
|
+
import { Bunja, BunjaStore, Scope, bunja, createBunjaStore, createReadScopeFn, createScope, delayUnmount } from "./bunja-D0Qa6gsc.js";
|
|
2
2
|
|
|
3
3
|
export { Bunja, BunjaStore, Scope, bunja, createBunjaStore, createReadScopeFn, createScope, delayUnmount };
|
package/dist/react.cjs
CHANGED
package/dist/react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
import { createBunjaStore, createReadScopeFn, createScope, delayUnmount } from "./bunja-
|
|
4
|
+
import { createBunjaStore, createReadScopeFn, createScope, delayUnmount } from "./bunja-D0Qa6gsc.js";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { createContext, createElement, useContext, useEffect, useMemo, useState } from "react";
|
|
7
7
|
|
package/dist/solid.cjs
CHANGED
package/dist/solid.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createBunjaStore, createReadScopeFn, createScope } from "./bunja-
|
|
1
|
+
import { createBunjaStore, createReadScopeFn, createScope } from "./bunja-D0Qa6gsc.js";
|
|
2
2
|
import { createComponent, createContext, createEffect, createMemo, createRoot, getOwner, onCleanup, useContext } from "solid-js";
|
|
3
3
|
|
|
4
4
|
//#region solid.ts
|
package/package.json
CHANGED
package/test.ts
CHANGED
|
@@ -207,6 +207,32 @@ Deno.test({
|
|
|
207
207
|
},
|
|
208
208
|
});
|
|
209
209
|
|
|
210
|
+
Deno.test({
|
|
211
|
+
name: "root scope value pairs are included in store.get deps",
|
|
212
|
+
fn() {
|
|
213
|
+
const store = createBunjaStore();
|
|
214
|
+
const myScope = createScope<string>();
|
|
215
|
+
const myBunja = bunja(() => {
|
|
216
|
+
const scopeValue = bunja.use(myScope);
|
|
217
|
+
return { scopeValue };
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const first = store.get(
|
|
221
|
+
{ bunja: myBunja, with: [myScope.bind("foo")] },
|
|
222
|
+
readNull,
|
|
223
|
+
);
|
|
224
|
+
const second = store.get(
|
|
225
|
+
{ bunja: myBunja, with: [myScope.bind("bar")] },
|
|
226
|
+
readNull,
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
assertEquals(first.value.scopeValue, "foo");
|
|
230
|
+
assertEquals(second.value.scopeValue, "bar");
|
|
231
|
+
assertEquals(first.deps, ["foo"]);
|
|
232
|
+
assertEquals(second.deps, ["bar"]);
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
|
|
210
236
|
Deno.test({
|
|
211
237
|
name: "bunja.use can override scope value pairs inside a bunja init",
|
|
212
238
|
fn() {
|
|
@@ -272,6 +298,56 @@ Deno.test({
|
|
|
272
298
|
},
|
|
273
299
|
});
|
|
274
300
|
|
|
301
|
+
Deno.test({
|
|
302
|
+
name: "bunja.use with scope value pairs propagates unbound required scopes",
|
|
303
|
+
fn() {
|
|
304
|
+
const createGraph = () => {
|
|
305
|
+
const injectedScope = createScope<string>();
|
|
306
|
+
const outerScope = createScope<string>();
|
|
307
|
+
const dependencyBunja = bunja(() => {
|
|
308
|
+
const injected = bunja.use(injectedScope);
|
|
309
|
+
const outer = bunja.use(outerScope);
|
|
310
|
+
return { injected, outer };
|
|
311
|
+
});
|
|
312
|
+
const consumerBunja = bunja(() =>
|
|
313
|
+
bunja.use(dependencyBunja, [injectedScope.bind("injected")])
|
|
314
|
+
);
|
|
315
|
+
return { consumerBunja, injectedScope, outerScope };
|
|
316
|
+
};
|
|
317
|
+
const readScope = <T>() => "outer" as T;
|
|
318
|
+
|
|
319
|
+
const prebakeGraph = createGraph();
|
|
320
|
+
const { requiredScopes } = createBunjaStore().prebake(
|
|
321
|
+
prebakeGraph.consumerBunja,
|
|
322
|
+
readScope,
|
|
323
|
+
);
|
|
324
|
+
assertEquals(requiredScopes.length, 1);
|
|
325
|
+
assertEquals(requiredScopes[0] === prebakeGraph.outerScope, true);
|
|
326
|
+
assertEquals(
|
|
327
|
+
requiredScopes.some((scope) => scope === prebakeGraph.injectedScope),
|
|
328
|
+
false,
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
const getGraph = createGraph();
|
|
332
|
+
const { value, deps } = createBunjaStore().get(
|
|
333
|
+
getGraph.consumerBunja,
|
|
334
|
+
readScope,
|
|
335
|
+
);
|
|
336
|
+
const requiredScopes2 = getGraph.consumerBunja.requiredScopes;
|
|
337
|
+
assertEquals(value, { injected: "injected", outer: "outer" });
|
|
338
|
+
assertEquals(deps, ["outer"]);
|
|
339
|
+
assertEquals(requiredScopes2.length, 1);
|
|
340
|
+
assertEquals(
|
|
341
|
+
requiredScopes2[0] === getGraph.outerScope,
|
|
342
|
+
true,
|
|
343
|
+
);
|
|
344
|
+
assertEquals(
|
|
345
|
+
requiredScopes2.some((scope) => scope === getGraph.injectedScope),
|
|
346
|
+
false,
|
|
347
|
+
);
|
|
348
|
+
},
|
|
349
|
+
});
|
|
350
|
+
|
|
275
351
|
Deno.test({
|
|
276
352
|
name: "seed is used only when creating a bunja instance",
|
|
277
353
|
fn() {
|
|
@@ -404,6 +480,29 @@ Deno.test({
|
|
|
404
480
|
},
|
|
405
481
|
});
|
|
406
482
|
|
|
483
|
+
Deno.test({
|
|
484
|
+
name: "bunja.will records optional refs once when thunk is used",
|
|
485
|
+
fn() {
|
|
486
|
+
const createConsumer = () => {
|
|
487
|
+
const dependencyBunja = bunja(() => "dependency");
|
|
488
|
+
const consumerBunja = bunja(() => {
|
|
489
|
+
const getDependency = bunja.will(dependencyBunja);
|
|
490
|
+
return getDependency();
|
|
491
|
+
});
|
|
492
|
+
return { consumerBunja };
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
const getGraph = createConsumer();
|
|
496
|
+
createBunjaStore().get(getGraph.consumerBunja, readNull);
|
|
497
|
+
|
|
498
|
+
const prebakeGraph = createConsumer();
|
|
499
|
+
createBunjaStore().prebake(prebakeGraph.consumerBunja, readNull);
|
|
500
|
+
|
|
501
|
+
assertEquals(getGraph.consumerBunja.optionalBunjaRefs.length, 1);
|
|
502
|
+
assertEquals(prebakeGraph.consumerBunja.optionalBunjaRefs.length, 1);
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
|
|
407
506
|
Deno.test({
|
|
408
507
|
name: "relatedBunjas includes nested bunja.will dependencies",
|
|
409
508
|
fn() {
|