Skip to content

Commit

Permalink
Eager instantiate nested custom scoped subgraphs
Browse files Browse the repository at this point in the history
  • Loading branch information
guyca committed Dec 28, 2024
1 parent 2970265 commit 8931c4d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
16 changes: 13 additions & 3 deletions packages/react-obsidian/src/graph/registry/GraphRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ObtainLifecycleBoundGraphException } from './ObtainLifecycleBoundGraphE
import { getGlobal } from '../../utils/getGlobal';
import { isString } from '../../utils/isString';
import referenceCounter from '../../ReferenceCounter';
import { isGraph } from '../ObjectGraph';

Check failure on line 9 in packages/react-obsidian/src/graph/registry/GraphRegistry.ts

View workflow job for this annotation

GitHub Actions / build (18)

Dependency cycle via ./PropertyRetriever:4

export class GraphRegistry {
private readonly constructorToInstance = new Map<Constructable<Graph>, Set<Graph>>();
Expand Down Expand Up @@ -106,9 +107,18 @@ export class GraphRegistry {
});
}

private getSubgraphsConstructors(graph: Graph): Constructable<Graph>[] {
const Graph = this.instanceToConstructor.get(graph)!;
return Array.from(this.graphToSubgraphs.get(Graph) ?? new Set());
private getSubgraphsConstructors(graph: Graph | Constructable<Graph>): Constructable<Graph>[] {
const Graph = isGraph(graph) ? graph : this.instanceToConstructor.get(graph as Graph)!;
const directSubgraphs = Array.from(this.graphToSubgraphs.get(Graph) ?? new Set<Constructable<Graph>>());
if (directSubgraphs.length === 0) return [];
return [
...directSubgraphs,
...new Set(
directSubgraphs
.map(subgraph => this.getSubgraphsConstructors(subgraph))
.flat(),
),
];
}

private getGraphConstructorByKey<T extends Graph>(key: string): Constructable<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
injectComponent,
LifecycleBound,
ObjectGraph,
Singleton,
} from '../../src';
import graphRegistry from '../../src/graph/registry/GraphRegistry';

Expand Down Expand Up @@ -41,6 +42,11 @@ describe('custom scoped lifecycle-bound graphs', () => {
render(<ComponentThatWronglyReliesOnCustomScopedGraph />);
}).toThrow(/Cannot instantiate the scoped graph 'CustomScopeGraph' as a subgraph of 'UnscopedGraph' because the scopes do not match. undefined !== customScope/);
});

it('eagerly instantiates nested scoped graphs', () => {
render(<ComponentThatReliesOnNestedCustomScopedGraph />);
expect(graphRegistry.isInstantiated(CustomScopeGraph)).toBe(true);
});
});

@LifecycleBound({scope: 'customScope'}) @Graph()
Expand Down Expand Up @@ -80,3 +86,16 @@ const ComponentThatWronglyReliesOnCustomScopedGraph = injectComponent(
() => <>This should error</>,
UnscopedGraph,
);

@Singleton() @Graph({subgraphs: [CustomScopeGraph]})
class SingletonGraphWithCustomScopeSubgraph extends ObjectGraph {
}

@LifecycleBound({scope: 'customScope'}) @Graph({subgraphs: [SingletonGraphWithCustomScopeSubgraph]})
class CustomScopedGraphWithNestedCustomScopeSubgraph extends ObjectGraph {
}

const ComponentThatReliesOnNestedCustomScopedGraph = injectComponent(
() => <>Hello</>,
CustomScopedGraphWithNestedCustomScopeSubgraph,
);

0 comments on commit 8931c4d

Please sign in to comment.