Commit e7283a63 authored by nanahira's avatar nanahira

Revert "Reapply "fix""

This reverts commit 312241b5.
parent a2be3607
......@@ -40,7 +40,6 @@ export class AppContextCore<Cur = Empty, Req = Empty> {
private provideRecords: ProvideRecord[] = [];
private registry = new Map<string | AnyClass, LoadEntry>();
private objectSteps: ObjectStep[] = [];
private parentContexts = new Set<AppContextCore<any, any>>();
started = false;
private starting = false;
private startingEntries: LoadEntry[] | null = null;
......@@ -89,57 +88,6 @@ export class AppContextCore<Cur = Empty, Req = Empty> {
}
}
private applyUsedContext(other: AppContextCore<any, any>) {
// Copy provide records
if (Array.isArray(other?.provideRecords)) {
this.provideRecords.push(...other.provideRecords);
}
// Copy and apply object steps
if (Array.isArray(other?.objectSteps)) {
this.objectSteps.push(...other.objectSteps);
for (const step of other.objectSteps) {
step(this);
}
}
// If the other context has already started, copy loaded entries only.
// They should remain initialized by the source context and must not be re-initialized.
if (other?.started) {
if (other?.registry instanceof Map) {
for (const [key, value] of other.registry.entries()) {
this.registry.set(key, value);
}
}
}
}
private hasStartedInParentChain(
visited = new Set<AppContextCore<any, any>>(),
): boolean {
if (visited.has(this)) return false;
visited.add(this);
if (this.started) return true;
for (const parent of this.parentContexts) {
if (parent.hasStartedInParentChain(visited)) {
return true;
}
}
return false;
}
private propagateUsedContextToParents(
other: AppContextCore<any, any>,
visited = new Set<AppContextCore<any, any>>(),
) {
if (visited.has(this)) return;
visited.add(this);
for (const parent of this.parentContexts) {
parent.applyUsedContext(other);
parent.propagateUsedContextToParents(other, visited);
}
}
provide<
C extends AppServiceClass<Cur, Req>,
const P extends string = '',
......@@ -286,15 +234,34 @@ export class AppContextCore<Cur = Empty, Req = Empty> {
for (const ctx of ctxes) {
const other = ctx as any as AppContextCore<any, any>;
if (this.hasStartedInParentChain() && !other?.started) {
if (this.started && !other?.started) {
throw new Error(
'Cannot use an unstarted context into a started context.',
);
}
this.applyUsedContext(other);
other.parentContexts.add(this);
this.propagateUsedContextToParents(other);
// Copy provide records
if (Array.isArray(other?.provideRecords)) {
this.provideRecords.push(...other.provideRecords);
}
// Copy and apply object steps
if (Array.isArray(other?.objectSteps)) {
this.objectSteps.push(...other.objectSteps);
for (const step of other.objectSteps) {
step(this);
}
}
// If the other context has already started, copy loaded entries only.
// They should remain initialized by the source context and must not be re-initialized.
if (other?.started) {
if (other?.registry instanceof Map) {
for (const [key, value] of other.registry.entries()) {
this.registry.set(key, value);
}
}
}
}
return this as any;
......
......@@ -226,23 +226,6 @@ describe('app-context runtime', () => {
expect(root.needsCounter.counter).toBe(root.counter);
expect(root.needsCounter.counter.value).toBe(34);
});
test('late b.use(c) propagates to a and c can access providers from a', async () => {
const p = createAppContext()
.provide(CounterService, 55, { provide: 'counter' })
.define();
const b = createAppContext().define();
const a = createAppContext().use(p).use(b).define();
const c = createAppContext()
.provide(NeedsCounterService, { provide: 'needsCounter' })
.define();
b.use(c);
const root = await a.start();
expect((root as any).needsCounter.counter).toBe(root.counter);
expect((root as any).needsCounter.counter.value).toBe(55);
});
});
describe('app-context type checks', () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment