react-obsidian 2.11.0 → 3.0.0-alpha.1
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/src/GraphProperties.js +1 -3
- package/dist/src/GraphProperties.js.map +1 -1
- package/dist/src/ProvidedPropertiesStore.js +4 -9
- package/dist/src/ProvidedPropertiesStore.js.map +1 -1
- package/dist/src/ReferenceCounter.js +2 -5
- package/dist/src/ReferenceCounter.js.map +1 -1
- package/dist/src/decorators/Graph.d.ts +2 -2
- package/dist/src/decorators/Graph.d.ts.map +1 -1
- package/dist/src/decorators/Graph.js +5 -6
- package/dist/src/decorators/Graph.js.map +1 -1
- package/dist/src/decorators/LifecycleBound.d.ts +1 -1
- package/dist/src/decorators/LifecycleBound.js +3 -5
- package/dist/src/decorators/LifecycleBound.js.map +1 -1
- package/dist/src/decorators/Memoize.d.ts +1 -1
- package/dist/src/decorators/Memoize.d.ts.map +1 -1
- package/dist/src/decorators/Memoize.js +8 -16
- package/dist/src/decorators/Memoize.js.map +1 -1
- package/dist/src/decorators/Singleton.d.ts +1 -3
- package/dist/src/decorators/Singleton.d.ts.map +1 -1
- package/dist/src/decorators/Singleton.js +18 -5
- package/dist/src/decorators/Singleton.js.map +1 -1
- package/dist/src/decorators/inject/Inject.d.ts +1 -1
- package/dist/src/decorators/inject/Inject.d.ts.map +1 -1
- package/dist/src/decorators/inject/Inject.js +10 -12
- package/dist/src/decorators/inject/Inject.js.map +1 -1
- package/dist/src/decorators/inject/Injectable.d.ts +1 -1
- package/dist/src/decorators/inject/Injectable.js +2 -3
- package/dist/src/decorators/inject/Injectable.js.map +1 -1
- package/dist/src/decorators/inject/LateInject.d.ts +1 -1
- package/dist/src/decorators/inject/LateInject.d.ts.map +1 -1
- package/dist/src/decorators/inject/LateInject.js +7 -6
- package/dist/src/decorators/inject/LateInject.js.map +1 -1
- package/dist/src/decorators/provides/MemoizeDescriptor.d.ts.map +1 -1
- package/dist/src/decorators/provides/MemoizeDescriptor.js +1 -3
- package/dist/src/decorators/provides/MemoizeDescriptor.js.map +1 -1
- package/dist/src/decorators/provides/Provides.d.ts +1 -2
- package/dist/src/decorators/provides/Provides.d.ts.map +1 -1
- package/dist/src/decorators/provides/Provides.js +19 -7
- package/dist/src/decorators/provides/Provides.js.map +1 -1
- package/dist/src/graph/CircularDependenciesDetector.js +2 -1
- package/dist/src/graph/CircularDependenciesDetector.js.map +1 -1
- package/dist/src/graph/ObjectGraph.d.ts +1 -1
- package/dist/src/graph/ObjectGraph.d.ts.map +1 -1
- package/dist/src/graph/ObjectGraph.js +6 -19
- package/dist/src/graph/ObjectGraph.js.map +1 -1
- package/dist/src/graph/PropertyRetriever.d.ts +1 -1
- package/dist/src/graph/PropertyRetriever.d.ts.map +1 -1
- package/dist/src/graph/PropertyRetriever.js +3 -2
- package/dist/src/graph/PropertyRetriever.js.map +1 -1
- package/dist/src/graph/PropertyRetrieverDelegate.d.ts +1 -1
- package/dist/src/graph/PropertyRetrieverDelegate.d.ts.map +1 -1
- package/dist/src/graph/ProviderBinder.d.ts.map +1 -1
- package/dist/src/graph/ProviderBinder.js +2 -4
- package/dist/src/graph/ProviderBinder.js.map +1 -1
- package/dist/src/graph/ServiceLocatorFactory.d.ts.map +1 -1
- package/dist/src/graph/VisitedNodes.js +2 -4
- package/dist/src/graph/VisitedNodes.js.map +1 -1
- package/dist/src/graph/registry/GraphMiddlewareChain.js +1 -0
- package/dist/src/graph/registry/GraphMiddlewareChain.js.map +1 -1
- package/dist/src/graph/registry/GraphRegistry.d.ts.map +1 -1
- package/dist/src/graph/registry/GraphRegistry.js +19 -26
- package/dist/src/graph/registry/GraphRegistry.js.map +1 -1
- package/dist/src/graph/registry/Middleware.js +1 -0
- package/dist/src/graph/registry/Middleware.js.map +1 -1
- package/dist/src/graph/registry/ObtainLifecycleBoundGraphException.js.map +1 -1
- package/dist/src/index.d.ts +42 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +50 -15
- package/dist/src/index.js.map +1 -1
- package/dist/src/injectors/class/ClassInjector.d.ts.map +1 -1
- package/dist/src/injectors/class/ClassInjector.js +6 -5
- package/dist/src/injectors/class/ClassInjector.js.map +1 -1
- package/dist/src/injectors/class/ConstructorArgs.js +1 -3
- package/dist/src/injectors/class/ConstructorArgs.js.map +1 -1
- package/dist/src/injectors/class/InjectionMetadata.js +5 -9
- package/dist/src/injectors/class/InjectionMetadata.js.map +1 -1
- package/dist/src/injectors/class/LateInjector.js +1 -1
- package/dist/src/injectors/class/LateInjector.js.map +1 -1
- package/dist/src/injectors/components/ComponentInjector.js.map +1 -1
- package/dist/src/injectors/components/InjectComponent.d.ts +2 -1
- package/dist/src/injectors/components/InjectComponent.d.ts.map +1 -1
- package/dist/src/injectors/components/InjectComponent.js.map +1 -1
- package/dist/src/injectors/components/PropsInjector.d.ts.map +1 -1
- package/dist/src/injectors/components/PropsInjector.js +1 -1
- package/dist/src/injectors/components/PropsInjector.js.map +1 -1
- package/dist/src/injectors/components/useGraph.d.ts +1 -1
- package/dist/src/injectors/components/useGraph.d.ts.map +1 -1
- package/dist/src/injectors/components/useGraph.js +1 -1
- package/dist/src/injectors/components/useGraph.js.map +1 -1
- package/dist/src/injectors/components/useInjectionToken.d.ts.map +1 -1
- package/dist/src/injectors/components/useInjectionToken.js +1 -1
- package/dist/src/injectors/components/useInjectionToken.js.map +1 -1
- package/dist/src/injectors/hooks/HookInjector.js +2 -1
- package/dist/src/injectors/hooks/HookInjector.js.map +1 -1
- package/dist/src/injectors/hooks/InjectHook.d.ts.map +1 -1
- package/dist/src/injectors/hooks/InjectHook.js +2 -3
- package/dist/src/injectors/hooks/InjectHook.js.map +1 -1
- package/dist/src/model/Model.js.map +1 -1
- package/dist/src/observable/Observable.d.ts.map +1 -1
- package/dist/src/observable/Observable.js +3 -2
- package/dist/src/observable/Observable.js.map +1 -1
- package/dist/src/observable/cold/ColdMediatorObservable.d.ts.map +1 -1
- package/dist/src/observable/cold/ColdMediatorObservable.js +3 -4
- package/dist/src/observable/cold/ColdMediatorObservable.js.map +1 -1
- package/dist/src/observable/cold/useColdObservers.js +1 -2
- package/dist/src/observable/cold/useColdObservers.js.map +1 -1
- package/dist/src/observable/mapObservablesToValues.js +1 -2
- package/dist/src/observable/mapObservablesToValues.js.map +1 -1
- package/dist/src/observable/mediator/MediatorObservable.js.map +1 -1
- package/dist/src/observable/useObserver.d.ts.map +1 -1
- package/dist/src/observable/useObserver.js +1 -3
- package/dist/src/observable/useObserver.js.map +1 -1
- package/dist/src/observable/useObservers.d.ts +2 -1
- package/dist/src/observable/useObservers.d.ts.map +1 -1
- package/dist/src/observable/useObservers.js +2 -3
- package/dist/src/observable/useObservers.js.map +1 -1
- package/dist/src/utils/React.d.ts.map +1 -1
- package/dist/src/utils/React.js +2 -3
- package/dist/src/utils/React.js.map +1 -1
- package/dist/src/utils/isDev.js +4 -7
- package/dist/src/utils/isDev.js.map +1 -1
- package/dist/src/utils/isNumber.js +1 -2
- package/dist/src/utils/isNumber.js.map +1 -1
- package/dist/src/utils/uniqueId.js +2 -3
- package/dist/src/utils/uniqueId.js.map +1 -1
- package/dist/test/fixtures/CircularDependencyFromSubgraph.d.ts +1 -1
- package/dist/test/fixtures/CircularDependencyFromSubgraph.d.ts.map +1 -1
- package/dist/test/fixtures/CircularDependencyFromSubgraph.js +4 -20
- package/dist/test/fixtures/CircularDependencyFromSubgraph.js.map +1 -1
- package/dist/test/fixtures/CircularDependencyGraph.d.ts.map +1 -1
- package/dist/test/fixtures/CircularDependencyGraph.js +5 -20
- package/dist/test/fixtures/CircularDependencyGraph.js.map +1 -1
- package/dist/test/fixtures/CircularDependencyGraph2.d.ts.map +1 -1
- package/dist/test/fixtures/CircularDependencyGraph2.js +7 -32
- package/dist/test/fixtures/CircularDependencyGraph2.js.map +1 -1
- package/dist/test/fixtures/GraphWithMultipleDependencies.js +7 -38
- package/dist/test/fixtures/GraphWithMultipleDependencies.js.map +1 -1
- package/dist/test/fixtures/GraphWithOnBind.d.ts +1 -1
- package/dist/test/fixtures/GraphWithOnBind.d.ts.map +1 -1
- package/dist/test/fixtures/GraphWithOnBind.js +5 -20
- package/dist/test/fixtures/GraphWithOnBind.js.map +1 -1
- package/dist/test/fixtures/LifecycleBoundGraph.js +9 -31
- package/dist/test/fixtures/LifecycleBoundGraph.js.map +1 -1
- package/dist/test/fixtures/LifecycleBoundWithLifecycleBoundSubgraph.d.ts.map +1 -1
- package/dist/test/fixtures/LifecycleBoundWithLifecycleBoundSubgraph.js +5 -21
- package/dist/test/fixtures/LifecycleBoundWithLifecycleBoundSubgraph.js.map +1 -1
- package/dist/test/fixtures/MainGraph.js +5 -27
- package/dist/test/fixtures/MainGraph.js.map +1 -1
- package/dist/test/fixtures/ScopedLifecycleBoundGraph.js +4 -12
- package/dist/test/fixtures/ScopedLifecycleBoundGraph.js.map +1 -1
- package/dist/test/fixtures/SingletonGraph.js +6 -25
- package/dist/test/fixtures/SingletonGraph.js.map +1 -1
- package/dist/test/fixtures/StringProvider.js +1 -0
- package/dist/test/fixtures/StringProvider.js.map +1 -1
- package/dist/test/fixtures/Subgraph.js +7 -38
- package/dist/test/fixtures/Subgraph.js.map +1 -1
- package/dist/test/fixtures/SubgraphWithCircularDependency.d.ts.map +1 -1
- package/dist/test/fixtures/SubgraphWithCircularDependency.js +7 -27
- package/dist/test/fixtures/SubgraphWithCircularDependency.js.map +1 -1
- package/dist/test/fixtures/ThrowingMainGraph.js +4 -20
- package/dist/test/fixtures/ThrowingMainGraph.js.map +1 -1
- package/dist/test/fixtures/UniqueNumberGraph.d.ts.map +1 -1
- package/dist/test/fixtures/UniqueNumberGraph.js +7 -29
- package/dist/test/fixtures/UniqueNumberGraph.js.map +1 -1
- package/dist/testkit/index.d.ts.map +1 -1
- package/dist/testkit/index.js +0 -1
- package/dist/testkit/index.js.map +1 -1
- package/dist/testkit/mockGraphs.js +1 -2
- package/dist/testkit/mockGraphs.js.map +1 -1
- package/dist/testkit/mockModel.js +1 -2
- package/dist/testkit/mockModel.js.map +1 -1
- package/dist/transformers/babel-plugin-obsidian/helpers/index.d.ts +2 -2
- package/dist/transformers/babel-plugin-obsidian/helpers/index.d.ts.map +1 -1
- package/dist/transformers/babel-plugin-obsidian/helpers/index.js +13 -16
- package/dist/transformers/babel-plugin-obsidian/helpers/index.js.map +1 -1
- package/dist/transformers/babel-plugin-obsidian/index.d.ts.map +1 -1
- package/dist/transformers/babel-plugin-obsidian/index.js +6 -6
- package/dist/transformers/babel-plugin-obsidian/index.js.map +1 -1
- package/dist/transformers/babel-plugin-obsidian/unmagler/method.d.ts.map +1 -1
- package/dist/transformers/babel-plugin-obsidian/unmagler/method.js +1 -3
- package/dist/transformers/babel-plugin-obsidian/unmagler/method.js.map +1 -1
- package/dist/transformers/babel-plugin-obsidian/unmagler/property.js.map +1 -1
- package/eslint.config.mjs +140 -0
- package/package.json +29 -28
- package/src/decorators/Graph.ts +5 -5
- package/src/decorators/LifecycleBound.ts +1 -1
- package/src/decorators/Memoize.ts +10 -15
- package/src/decorators/Singleton.ts +20 -9
- package/src/decorators/inject/Inject.ts +11 -11
- package/src/decorators/inject/Injectable.ts +1 -1
- package/src/decorators/inject/LateInject.ts +9 -4
- package/src/decorators/provides/MemoizeDescriptor.ts +0 -1
- package/src/decorators/provides/Provides.ts +24 -5
- package/src/graph/ObjectGraph.ts +4 -6
- package/src/graph/PropertyRetriever.ts +4 -4
- package/src/graph/PropertyRetrieverDelegate.ts +1 -1
- package/src/graph/ProviderBinder.ts +1 -2
- package/src/graph/registry/GraphRegistry.ts +8 -8
- package/src/graph/registry/ObtainLifecycleBoundGraphException.ts +1 -1
- package/src/index.ts +50 -7
- package/src/injectors/class/ClassInjector.ts +2 -2
- package/src/injectors/components/ComponentInjector.tsx +1 -1
- package/src/injectors/components/InjectComponent.ts +4 -3
- package/src/injectors/components/PropsInjector.ts +0 -1
- package/src/injectors/components/useGraph.ts +1 -2
- package/src/injectors/hooks/InjectHook.ts +0 -1
- package/src/observable/Observable.ts +2 -2
- package/src/observable/cold/ColdMediatorObservable.ts +0 -1
- package/src/observable/cold/useColdObservers.ts +1 -1
- package/src/observable/mediator/MediatorObservable.ts +1 -1
- package/src/observable/useObserver.ts +1 -2
- package/src/observable/useObservers.ts +4 -3
- package/src/utils/isDev.ts +1 -1
- package/testkit/index.ts +0 -1
- package/transformers/babel-plugin-obsidian/helpers/index.ts +8 -8
- package/transformers/babel-plugin-obsidian/index.ts +5 -6
- package/transformers/babel-plugin-obsidian/unmagler/method.ts +1 -2
package/src/decorators/Graph.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Constructable } from '../types';
|
|
1
|
+
import { Constructable, type Constructor } from '../types';
|
|
2
2
|
import 'reflect-metadata';
|
|
3
3
|
import graphRegistry from '../graph/registry/GraphRegistry';
|
|
4
4
|
import { ObjectGraph } from '../graph/ObjectGraph';
|
|
@@ -7,9 +7,9 @@ interface GraphParams {
|
|
|
7
7
|
subgraphs: Constructable<ObjectGraph>[];
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function
|
|
11
|
-
return (
|
|
12
|
-
graphRegistry.register(
|
|
13
|
-
return
|
|
10
|
+
export function graph<Class extends Constructor>({ subgraphs = [] }: Partial<GraphParams> = {}) {
|
|
11
|
+
return (Clazz: Class) => {
|
|
12
|
+
graphRegistry.register(Clazz, subgraphs);
|
|
13
|
+
return Clazz;
|
|
14
14
|
};
|
|
15
15
|
}
|
|
@@ -2,7 +2,7 @@ type Options = {
|
|
|
2
2
|
scope?: 'component' | 'feature';
|
|
3
3
|
};
|
|
4
4
|
|
|
5
|
-
export function
|
|
5
|
+
export function lifecycleBound(options?: Options) {
|
|
6
6
|
return (constructor: any) => {
|
|
7
7
|
Reflect.defineMetadata('isLifecycleBound', true, constructor);
|
|
8
8
|
Reflect.defineMetadata('lifecycleScope', options?.scope ?? 'feature', constructor);
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
/* eslint-disable no-param-reassign */
|
|
2
1
|
import 'reflect-metadata';
|
|
3
2
|
|
|
4
|
-
export default function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return value;
|
|
15
|
-
};
|
|
16
|
-
return descriptor;
|
|
17
|
-
};
|
|
3
|
+
export default function memoize<This, Return>(
|
|
4
|
+
target: (this: This) => Return,
|
|
5
|
+
context: ClassGetterDecoratorContext,
|
|
6
|
+
) {
|
|
7
|
+
function memoizer(this: This): Return {
|
|
8
|
+
const value = target.call(this);
|
|
9
|
+
Object.defineProperty(this, context.name, { value, enumerable: true });
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
return memoizer;
|
|
18
13
|
}
|
|
@@ -1,14 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
import { ObjectGraph } from '../graph/ObjectGraph';
|
|
3
|
-
|
|
4
|
-
export function Singleton() {
|
|
1
|
+
export function singleton() {
|
|
5
2
|
return function singleton(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
descriptor?: PropertyDescriptor,
|
|
9
|
-
): any {
|
|
10
|
-
const target = descriptor || constructorOrGraph;
|
|
3
|
+
target: any, // Class extends Constructor || (this: This, ...args: Args) => Return
|
|
4
|
+
) {
|
|
11
5
|
Reflect.defineMetadata('isSingleton', true, target);
|
|
12
6
|
return target;
|
|
7
|
+
|
|
8
|
+
// return function singleton(
|
|
9
|
+
// constructorOrGraph: Constructable<ObjectGraph> | ObjectGraph,
|
|
10
|
+
// _property?: string,
|
|
11
|
+
// descriptor?: PropertyDescriptor,
|
|
12
|
+
// ): any {
|
|
13
|
+
// const target = descriptor || constructorOrGraph;
|
|
14
|
+
// Reflect.defineMetadata('isSingleton', true, target);
|
|
15
|
+
// return target;
|
|
16
|
+
// };
|
|
13
17
|
};
|
|
14
18
|
}
|
|
19
|
+
|
|
20
|
+
// function methodSingleton<This, Args extends any[], Return>(
|
|
21
|
+
// target: (this: This, ...args: Args) => Return,
|
|
22
|
+
// ) {
|
|
23
|
+
// Reflect.defineMetadata('isSingleton', true, target);
|
|
24
|
+
// return target;
|
|
25
|
+
// }
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { isNumber } from '../../utils/isNumber';
|
|
2
1
|
import InjectionMetadata from '../../injectors/class/InjectionMetadata';
|
|
3
2
|
|
|
4
|
-
export function
|
|
3
|
+
export function inject<This, Return>(name?: string) {
|
|
5
4
|
return (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
indexOrPropertyDescriptor?: number | PropertyDescriptor,
|
|
5
|
+
_target: undefined,
|
|
6
|
+
context: ClassFieldDecoratorContext<This, Return>,
|
|
9
7
|
) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
metadata.
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
context.addInitializer(function (this: This) {
|
|
9
|
+
const metadata = new InjectionMetadata();
|
|
10
|
+
metadata.savePropertyMetadata((this as object).constructor, name!);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
return function (this: This, value: Return) {
|
|
14
|
+
return value;
|
|
15
|
+
};
|
|
16
16
|
};
|
|
17
17
|
}
|
|
@@ -3,6 +3,6 @@ import { Graph } from '../../graph/Graph';
|
|
|
3
3
|
import graphRegistry from '../../graph/registry/GraphRegistry';
|
|
4
4
|
import ClassInjector from '../../injectors/class/ClassInjector';
|
|
5
5
|
|
|
6
|
-
export function
|
|
6
|
+
export function injectable(Graph: Constructable<Graph>): any {
|
|
7
7
|
return new ClassInjector(graphRegistry).inject(Graph);
|
|
8
8
|
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import InjectionMetadata from '../../injectors/class/InjectionMetadata';
|
|
2
2
|
|
|
3
|
-
export function
|
|
4
|
-
return (
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export function lateInject<This, Value>(name?: string): any {
|
|
4
|
+
return (
|
|
5
|
+
_target: undefined,
|
|
6
|
+
context: ClassFieldDecoratorContext<This, Value>,
|
|
7
|
+
) => {
|
|
8
|
+
context.addInitializer(function (this: This) {
|
|
9
|
+
const metadata = new InjectionMetadata();
|
|
10
|
+
metadata.saveLatePropertyMetadata((this as object).constructor, name!);
|
|
11
|
+
});
|
|
7
12
|
};
|
|
8
13
|
}
|
|
@@ -1,14 +1,33 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
1
2
|
import { Graph } from '../../graph/Graph';
|
|
2
3
|
import providedPropertiesStore from '../../ProvidedPropertiesStore';
|
|
3
|
-
import { memoizeDescriptor } from './MemoizeDescriptor';
|
|
4
4
|
|
|
5
5
|
interface ProvidesParams {
|
|
6
6
|
name: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export function
|
|
10
|
-
return function
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
export function provides<This, Args extends any[], Return>({ name }: Partial<ProvidesParams> = {}) {
|
|
10
|
+
return function (
|
|
11
|
+
target: (this: This, ...args: Args) => Return,
|
|
12
|
+
context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>,
|
|
13
|
+
) {
|
|
14
|
+
context.addInitializer(function (this: This) {
|
|
15
|
+
const mangledProperty = String(context.name);
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
this[mangledProperty] = this[mangledProperty].bind(this);
|
|
18
|
+
providedPropertiesStore.set(this as Graph, mangledProperty, name!);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
function replacementMethod(this: This, ...args: Args): Return {
|
|
22
|
+
const memoizedResult = Reflect.get(this as object, `memoized${name!}`);
|
|
23
|
+
if (memoizedResult === undefined) {
|
|
24
|
+
const result = target.call(this, ...args);
|
|
25
|
+
Reflect.set(this as object, `memoized${name!}`, result);
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
return memoizedResult;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return replacementMethod;
|
|
13
32
|
};
|
|
14
33
|
}
|
package/src/graph/ObjectGraph.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uniqueId } from '../utils/uniqueId';
|
|
2
|
-
import
|
|
2
|
+
import memoize from '../decorators/Memoize';
|
|
3
3
|
import { bindProviders } from './ProviderBinder';
|
|
4
4
|
import { Graph } from './Graph';
|
|
5
5
|
import PropertyRetriever from './PropertyRetriever';
|
|
@@ -9,7 +9,7 @@ import { CircularDependenciesDetector } from './CircularDependenciesDetector';
|
|
|
9
9
|
export abstract class ObjectGraph<T = unknown> implements Graph {
|
|
10
10
|
private propertyRetriever = new PropertyRetriever(this);
|
|
11
11
|
|
|
12
|
-
@
|
|
12
|
+
@memoize
|
|
13
13
|
get name(): string {
|
|
14
14
|
return uniqueId(this.constructor.name);
|
|
15
15
|
}
|
|
@@ -26,13 +26,11 @@ export abstract class ObjectGraph<T = unknown> implements Graph {
|
|
|
26
26
|
return this.propertyRetriever.retrieve(property, receiver, detector) as Dependency | undefined;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
onBind(_target: any) {
|
|
30
|
-
|
|
31
|
-
}
|
|
29
|
+
onBind(_target: any) { void 0; }
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
Reflect.set(ObjectGraph, 'typeDiscriminator', 'ObjectGraph');
|
|
35
33
|
|
|
36
|
-
export function isGraph(object:
|
|
34
|
+
export function isGraph(object: any): object is Constructable<ObjectGraph> {
|
|
37
35
|
return Reflect.get(object, 'typeDiscriminator') === 'ObjectGraph';
|
|
38
36
|
}
|
|
@@ -10,7 +10,7 @@ export default class PropertyRetriever {
|
|
|
10
10
|
property: string,
|
|
11
11
|
receiver?: unknown,
|
|
12
12
|
maybeDetector?: CircularDependenciesDetector,
|
|
13
|
-
): unknown
|
|
13
|
+
): unknown {
|
|
14
14
|
const mangledPropertyKey = providedPropertiesStore.getMangledProperty(this.graph, property);
|
|
15
15
|
const circularDependenciesDetector = maybeDetector ?? new CircularDependenciesDetector(this.graph.name);
|
|
16
16
|
|
|
@@ -32,8 +32,8 @@ export default class PropertyRetriever {
|
|
|
32
32
|
if (circularDependenciesDetector.hasCircularDependencies()) {
|
|
33
33
|
throw new Error(
|
|
34
34
|
`Could not resolve ${circularDependenciesDetector.firstDependencyName}`
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
+ ` from ${circularDependenciesDetector.graphName} because of a circular dependency:`
|
|
36
|
+
+ ` ${circularDependenciesDetector.getDependencies().join(' -> ')}`,
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -56,6 +56,6 @@ export default class PropertyRetriever {
|
|
|
56
56
|
const subgraphs = graphRegistry.getSubgraphs(this.graph);
|
|
57
57
|
return subgraphs
|
|
58
58
|
.map((subgraph: Graph) => subgraph.retrieve(property, receiver, circularDependenciesDetector))
|
|
59
|
-
.filter(
|
|
59
|
+
.filter(result => result !== undefined);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/* eslint-disable no-param-reassign */
|
|
2
1
|
import providedPropertiesStore from '../ProvidedPropertiesStore';
|
|
3
2
|
import { Graph } from './Graph';
|
|
4
3
|
|
|
5
4
|
export function bindProviders(graph: Graph & Record<string, any>) {
|
|
6
5
|
providedPropertiesStore.getMangledProperties(graph)
|
|
7
|
-
.filter(
|
|
6
|
+
.filter(method => graph[method])
|
|
8
7
|
.forEach((method) => {
|
|
9
8
|
graph[method] = graph[method].bind(graph);
|
|
10
9
|
});
|
|
@@ -25,7 +25,7 @@ export class GraphRegistry {
|
|
|
25
25
|
getSubgraphs(graph: Graph): Graph[] {
|
|
26
26
|
const Graph = this.instanceToConstructor.get(graph)!;
|
|
27
27
|
const subgraphs = this.graphToSubgraphs.get(Graph) ?? new Set();
|
|
28
|
-
return Array.from(subgraphs).map(
|
|
28
|
+
return Array.from(subgraphs).map(G => this.resolve(G));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
getGraphInstance(name: string): Graph {
|
|
@@ -39,9 +39,9 @@ export class GraphRegistry {
|
|
|
39
39
|
injectionToken?: string,
|
|
40
40
|
): T {
|
|
41
41
|
if ((this.isSingleton(Graph) || this.isBoundToReactLifecycle(Graph)) && this.has(Graph, injectionToken)) {
|
|
42
|
-
return this.isComponentScopedLifecycleBound(Graph)
|
|
43
|
-
this.getByInjectionToken(Graph, injectionToken)
|
|
44
|
-
this.getFirst(Graph);
|
|
42
|
+
return this.isComponentScopedLifecycleBound(Graph)
|
|
43
|
+
? this.getByInjectionToken(Graph, injectionToken)
|
|
44
|
+
: this.getFirst(Graph);
|
|
45
45
|
}
|
|
46
46
|
if (this.isBoundToReactLifecycle(Graph) && source !== 'lifecycleOwner') {
|
|
47
47
|
throw new ObtainLifecycleBoundGraphException(Graph);
|
|
@@ -58,14 +58,14 @@ export class GraphRegistry {
|
|
|
58
58
|
if (this.isComponentScopedLifecycleBound(Graph)) {
|
|
59
59
|
return Array
|
|
60
60
|
.from(instances)
|
|
61
|
-
.some(
|
|
61
|
+
.some(graph => this.instanceToInjectionToken.get(graph) === injectionToken);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
return (this.constructorToInstance.get(Graph)?.size ?? 0) > 0;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
private getFirst<T extends Graph>(Graph: Constructable<T>): T {
|
|
68
|
-
return this.constructorToInstance.get(Graph)!.values().next().value;
|
|
68
|
+
return this.constructorToInstance.get(Graph)!.values().next().value as T;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
private getByInjectionToken<T extends Graph>(Graph: Constructable<T>, injectionToken?: string): T {
|
|
@@ -151,7 +151,7 @@ export class GraphRegistry {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
// @ts-
|
|
154
|
+
// @ts-expect-error - workaround an issue in jest tests where the registry was created multiple times
|
|
155
155
|
global.graphRegistry = global.graphRegistry || new GraphRegistry();
|
|
156
|
-
// @ts-
|
|
156
|
+
// @ts-expect-error - see above
|
|
157
157
|
export default global.graphRegistry as GraphRegistry;
|
|
@@ -10,6 +10,6 @@ export class ObtainLifecycleBoundGraphException extends Error {
|
|
|
10
10
|
private static createMessage(graph: Constructable<Graph>): string {
|
|
11
11
|
const graphName = isDev() ? ` ${graph.name}` : '';
|
|
12
12
|
return `Tried to obtain a @LifecycleBound graph${graphName}, but it was not created yet. `
|
|
13
|
-
|
|
13
|
+
+ '@LifecycleBound graphs can only be obtained after they were created by a React component or hook.';
|
|
14
14
|
}
|
|
15
15
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,59 @@
|
|
|
1
|
+
import { graph } from './decorators/Graph';
|
|
2
|
+
import { inject } from './decorators/inject/Inject';
|
|
3
|
+
import { injectable } from './decorators/inject/Injectable';
|
|
4
|
+
import { lateInject } from './decorators/inject/LateInject';
|
|
5
|
+
import { lifecycleBound } from './decorators/LifecycleBound';
|
|
6
|
+
import { provides } from './decorators/provides/Provides';
|
|
7
|
+
import { singleton } from './decorators/Singleton';
|
|
1
8
|
import _Obsidian from './Obsidian';
|
|
2
9
|
|
|
3
10
|
export * from './types';
|
|
4
11
|
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
12
|
+
export { graph } from './decorators/Graph';
|
|
13
|
+
export { singleton } from './decorators/Singleton';
|
|
14
|
+
export { provides } from './decorators/provides/Provides';
|
|
15
|
+
export { injectable } from './decorators/inject/Injectable';
|
|
16
|
+
export { inject } from './decorators/inject/Inject';
|
|
17
|
+
export { lateInject } from './decorators/inject/LateInject';
|
|
18
|
+
export { lifecycleBound } from './decorators/LifecycleBound';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Uppercase decorators are deprecated in favor of lowercase decorators to align with common naming conventions. Please use inject instead.
|
|
22
|
+
*/
|
|
23
|
+
export const Graph = graph;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @deprecated Uppercase decorators are deprecated in favor of lowercase decorators to align with common naming convention. Please use `singleton` instead.
|
|
27
|
+
*/
|
|
28
|
+
export const Singleton = singleton;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Uppercase decorators are deprecated in favor of lowercase decorators to align with common naming convention. Please use `provides` instead.
|
|
32
|
+
*/
|
|
33
|
+
export const Provides = provides;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated Uppercase decorators are deprecated in favor of lowercase decorators to align with common naming convention. Please use `injectable` instead.
|
|
37
|
+
*/
|
|
38
|
+
export const Injectable = injectable;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated Uppercase decorators are deprecated in favor of lowercase decorators to align with common naming convention. Please use `inject` instead.
|
|
42
|
+
*/
|
|
43
|
+
export const Inject = inject;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Uppercase decorators are deprecated in favor of lowercase decorators to align with common naming convention. Please use `lateInject` instead.
|
|
47
|
+
*/
|
|
48
|
+
export const LateInject = lateInject;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated Uppercase decorators are deprecated in favor of lowercase decorators to align with common naming convention. Please use `lifecycleBound` instead.
|
|
52
|
+
*/
|
|
53
|
+
export const LifecycleBound = lifecycleBound;
|
|
54
|
+
|
|
7
55
|
export { ObjectGraph } from './graph/ObjectGraph';
|
|
8
56
|
export { Graph as IGraph } from './graph/Graph';
|
|
9
|
-
export { Provides } from './decorators/provides/Provides';
|
|
10
|
-
export { Injectable } from './decorators/inject/Injectable';
|
|
11
|
-
export { Inject } from './decorators/inject/Inject';
|
|
12
|
-
export { LateInject } from './decorators/inject/LateInject';
|
|
13
|
-
export { LifecycleBound } from './decorators/LifecycleBound';
|
|
14
57
|
export { GraphMiddleware } from './graph/registry/GraphMiddleware';
|
|
15
58
|
export { GraphResolveChain as ResolveChain } from './graph/registry/GraphResolveChain';
|
|
16
59
|
|
|
@@ -35,10 +35,10 @@ export default class ClassInjector {
|
|
|
35
35
|
graph.onBind(target);
|
|
36
36
|
const createdObject = Reflect.construct(target, argsToInject, newTarget);
|
|
37
37
|
this.injectProperties(target, createdObject, graph);
|
|
38
|
-
const originalComponentWillUnmount = createdObject.componentWillUnmount;
|
|
38
|
+
const originalComponentWillUnmount: () => void | undefined = createdObject.componentWillUnmount;
|
|
39
39
|
createdObject.componentWillUnmount = () => {
|
|
40
40
|
originalComponentWillUnmount?.();
|
|
41
|
-
referenceCounter.release(graph,
|
|
41
|
+
referenceCounter.release(graph, g => graphRegistry.clear(g));
|
|
42
42
|
};
|
|
43
43
|
return createdObject;
|
|
44
44
|
}
|
|
@@ -32,7 +32,7 @@ export default class ComponentInjector {
|
|
|
32
32
|
const proxiedProps = new PropsInjector(graph).inject(passedProps);
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
|
-
<GraphContext.Provider value={{injectionToken}}>
|
|
35
|
+
<GraphContext.Provider value={{ injectionToken }}>
|
|
36
36
|
{Target(proxiedProps as unknown as PropsWithChildren<P>)}
|
|
37
37
|
</GraphContext.Provider>
|
|
38
38
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { ObjectGraph } from '../../graph/ObjectGraph';
|
|
2
3
|
import { Constructable } from '../../types';
|
|
3
4
|
import ComponentInjector from './ComponentInjector';
|
|
@@ -18,9 +19,9 @@ export const injectComponent = <OwnProps = Discriminator, InjectedProps = Discri
|
|
|
18
19
|
assertGraph(Graph, Target);
|
|
19
20
|
|
|
20
21
|
return componentInjector.inject(Target, Graph) as React.FunctionComponent<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
InjectedProps extends Discriminator ?
|
|
23
|
+
OwnProps extends Discriminator ? Partial<OwnProps> : OwnProps :
|
|
24
|
+
OwnProps extends InjectedProps ? Partial<OwnProps> : OwnProps & Partial<InjectedProps>
|
|
24
25
|
>;
|
|
25
26
|
};
|
|
26
27
|
function assertGraph(Graph: Constructable<ObjectGraph<unknown>>, Target: any) {
|
|
@@ -4,7 +4,6 @@ export default class PropsInjector<Props> {
|
|
|
4
4
|
constructor(private graph: ObjectGraph) {}
|
|
5
5
|
|
|
6
6
|
inject(passedProps: Props): Partial<Props> {
|
|
7
|
-
// eslint-disable-next-line prefer-object-spread
|
|
8
7
|
return new Proxy(Object.assign({}, passedProps), {
|
|
9
8
|
get: (target: object, p: string, receiver: any): any => {
|
|
10
9
|
return p in target ? Reflect.get(target, p, receiver) : this.graph.retrieve(p, receiver);
|
|
@@ -10,7 +10,6 @@ export default <P>(
|
|
|
10
10
|
props?: Partial<P>,
|
|
11
11
|
injectionToken?: string,
|
|
12
12
|
) => {
|
|
13
|
-
|
|
14
13
|
const [graph] = useState(() => {
|
|
15
14
|
const resolvedGraph = graphRegistry.resolve(Graph, 'lifecycleOwner', props, injectionToken);
|
|
16
15
|
resolvedGraph.onBind(target);
|
|
@@ -18,7 +17,7 @@ export default <P>(
|
|
|
18
17
|
});
|
|
19
18
|
useEffect(() => {
|
|
20
19
|
referenceCounter.retain(graph);
|
|
21
|
-
return () => referenceCounter.release(graph,
|
|
20
|
+
return () => referenceCounter.release(graph, g => graphRegistry.clear(g));
|
|
22
21
|
}, [graph]);
|
|
23
22
|
return graph;
|
|
24
23
|
};
|
|
@@ -14,7 +14,7 @@ export class Observable<T> implements IObservable<T> {
|
|
|
14
14
|
|
|
15
15
|
public set value(value: T) {
|
|
16
16
|
this.currentValue = value;
|
|
17
|
-
this.subscribers.forEach(
|
|
17
|
+
this.subscribers.forEach(subscriber => subscriber(value));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
async first(): Promise<T> {
|
|
@@ -35,7 +35,7 @@ export class Observable<T> implements IObservable<T> {
|
|
|
35
35
|
return () => this.subscribers.delete(onNext);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
public unsubscribe(onNext:OnNext<T>) {
|
|
38
|
+
public unsubscribe(onNext: OnNext<T>) {
|
|
39
39
|
if (!this.subscribers.has(onNext)) {
|
|
40
40
|
throw new Error(`Can't unsubscribe, subscriber doesn't exist`);
|
|
41
41
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Observable } from '../Observable';
|
|
2
2
|
import { MediatorObservable } from '../mediator/MediatorObservable';
|
|
3
3
|
import { OnNext } from '../types';
|
|
4
|
-
|
|
5
4
|
export class ColdMediatorObservable<T extends object> extends MediatorObservable<T> {
|
|
6
5
|
constructor(obj: T, private readonly handler = new PropertyAccessTrackingProxy<T>()) {
|
|
7
6
|
super(new Proxy(obj, handler));
|
|
@@ -10,7 +10,7 @@ export function useColdObservables<T extends Record<string, any>>(observables: T
|
|
|
10
10
|
const [values, setValues] = useState(() => mediator.value as ObservedValues<T>);
|
|
11
11
|
|
|
12
12
|
useEffect(() => {
|
|
13
|
-
Object.keys(observables
|
|
13
|
+
Object.keys(observables).forEach((key) => {
|
|
14
14
|
mediator.addSource(observables[key], (value) => {
|
|
15
15
|
mediator.setValue(key, value);
|
|
16
16
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable no-param-reassign */
|
|
2
1
|
import {
|
|
3
2
|
useCallback,
|
|
4
3
|
useEffect,
|
|
@@ -26,6 +25,6 @@ export function useObserver<T>(observableOrGenerator: ObservableOrGenerator<T>):
|
|
|
26
25
|
return [value, onNext];
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
function getOrGenerateObservable(observableOrGenerator: ObservableOrGenerator<
|
|
28
|
+
function getOrGenerateObservable<T>(observableOrGenerator: ObservableOrGenerator<T>): Observable<T> {
|
|
30
29
|
return observableOrGenerator instanceof Observable ? observableOrGenerator : observableOrGenerator();
|
|
31
30
|
}
|
|
@@ -2,15 +2,16 @@ import { useEffect, useState } from 'react';
|
|
|
2
2
|
import { MediatorObservable } from './mediator/MediatorObservable';
|
|
3
3
|
import { ObservedValues, Unsubscribe } from './types';
|
|
4
4
|
import { mapObservablesToValues } from './mapObservablesToValues';
|
|
5
|
+
import type { Observable } from './Observable';
|
|
5
6
|
|
|
6
|
-
export function useObservers<T extends Record<string, any
|
|
7
|
+
export function useObservers<T extends Record<string, Observable<any>>>(observables: T): ObservedValues<T> {
|
|
7
8
|
const [values, setValues] = useState(() => mapObservablesToValues(observables));
|
|
8
9
|
|
|
9
10
|
useEffect(() => {
|
|
10
11
|
const mediator = new MediatorObservable();
|
|
11
12
|
const unsubscribers: Unsubscribe[] = [];
|
|
12
13
|
|
|
13
|
-
Object.keys(observables
|
|
14
|
+
Object.keys(observables).forEach((key) => {
|
|
14
15
|
const onNext = (value: any) => setValues({ ...values, [key]: value });
|
|
15
16
|
mediator.addSource(observables[key], onNext);
|
|
16
17
|
|
|
@@ -19,7 +20,7 @@ export function useObservers<T extends Record<string, any>>(observables: T): Obs
|
|
|
19
20
|
});
|
|
20
21
|
});
|
|
21
22
|
|
|
22
|
-
return () => unsubscribers.forEach(
|
|
23
|
+
return () => unsubscribers.forEach(unsubscribe => unsubscribe());
|
|
23
24
|
}, []);
|
|
24
25
|
|
|
25
26
|
return values;
|
package/src/utils/isDev.ts
CHANGED
|
@@ -3,11 +3,11 @@ export function isDev(): boolean {
|
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
function isNodeDev(): boolean {
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
7
6
|
return ['test', 'development'].includes(process.env['NODE_ENV'] ?? '');
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
function isReactNativeDev(): boolean {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
11
11
|
// @ts-ignore
|
|
12
12
|
return __DEV__ as boolean ?? false;
|
|
13
13
|
}
|
package/testkit/index.ts
CHANGED
|
@@ -7,7 +7,6 @@ class TestKit {
|
|
|
7
7
|
* @deprecated testKit.mockGraphs is deprecated, use mockGraphs instead
|
|
8
8
|
*/
|
|
9
9
|
public mockGraphs(graphNameToGraph: Record<string, Constructable<ObjectGraph> | ((props: any) => ObjectGraph)>) {
|
|
10
|
-
// eslint-disable-next-line no-console
|
|
11
10
|
console.warn('testKit.mockGraphs is deprecated, use mockGraphs instead');
|
|
12
11
|
return mockGraphs(graphNameToGraph);
|
|
13
12
|
}
|