@servicetitan/react-ioc 38.1.0 → 38.2.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/dist/container-config.d.ts +12 -0
- package/dist/container-config.d.ts.map +1 -0
- package/dist/container-config.js +85 -0
- package/dist/container-config.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +3 -82
- package/dist/provider.js.map +1 -1
- package/dist/use-local-stores.d.ts +7 -0
- package/dist/use-local-stores.d.ts.map +1 -0
- package/dist/use-local-stores.js +62 -0
- package/dist/use-local-stores.js.map +1 -0
- package/package.json +3 -3
- package/src/__tests__/container-config.test.ts +159 -0
- package/src/__tests__/use-local-stores.test.tsx +849 -0
- package/src/container-config.ts +125 -0
- package/src/index.ts +1 -0
- package/src/provider.tsx +13 -122
- package/src/use-local-stores.ts +86 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Container } from 'inversify';
|
|
2
|
+
import { Token } from './common';
|
|
3
|
+
import { ProviderConfigEntries } from './entry-helpers';
|
|
4
|
+
import { Store } from './store';
|
|
5
|
+
export declare function getStoreInstances(container: Container, { singletons, instances }: ProviderConfigEntries): Store[];
|
|
6
|
+
export declare function bindEntries(container: Container, { singletons, instances }: ProviderConfigEntries): void;
|
|
7
|
+
export declare function unbindEntries(container: Container, { singletons, instances }: ProviderConfigEntries): void;
|
|
8
|
+
export declare function initializeStores(stores: Store[], onError: (error: any) => void): Promise<void>[];
|
|
9
|
+
export declare function disposeStores(stores: Store[]): void;
|
|
10
|
+
export declare function formatDuplicatesMessage(source: string, duplicates: Token<any>[]): string;
|
|
11
|
+
export declare function rethrowAsync(e: any): void;
|
|
12
|
+
//# sourceMappingURL=container-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container-config.d.ts","sourceRoot":"","sources":["../src/container-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAOH,qBAAqB,EAExB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAW,KAAK,EAAE,MAAM,SAAS,CAAC;AAEzC,wBAAgB,iBAAiB,CAC7B,SAAS,EAAE,SAAS,EACpB,EAAE,UAAe,EAAE,SAAc,EAAE,EAAE,qBAAqB,GAC3D,KAAK,EAAE,CAUT;AA4CD,wBAAgB,WAAW,CACvB,SAAS,EAAE,SAAS,EACpB,EAAE,UAAe,EAAE,SAAc,EAAE,EAAE,qBAAqB,QAM7D;AAED,wBAAgB,aAAa,CACzB,SAAS,EAAE,SAAS,EACpB,EAAE,UAAe,EAAE,SAAc,EAAE,EAAE,qBAAqB,QAG7D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,mBAkB9E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,QAI5C;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,CAGxF;AAGD,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,QAIlC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { formatToken, getProvideTokenWithClass, isClassProviderConfigEntryToken, isClassProviderConfigEntryUseClass, isProviderConfigEntryInheritable, isValueProviderConfigEntry } from './entry-helpers';
|
|
2
|
+
import { isStore } from './store';
|
|
3
|
+
export function getStoreInstances(container, { singletons = [], instances = [] }) {
|
|
4
|
+
return [
|
|
5
|
+
...singletons,
|
|
6
|
+
...instances
|
|
7
|
+
].reduce((out, entry)=>{
|
|
8
|
+
const [provide, useClass] = getProvideTokenWithClass(entry);
|
|
9
|
+
if (provide && useClass && container.isCurrentBound(provide) && isStore(useClass)) {
|
|
10
|
+
out.push(container.get(provide));
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}, []);
|
|
14
|
+
}
|
|
15
|
+
const bindEntry = (container, checkInherit)=>(entry)=>{
|
|
16
|
+
if (checkInherit && isProviderConfigEntryInheritable(entry) && entry.inherit && container.isBound(entry.provide)) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
if (isClassProviderConfigEntryUseClass(entry)) {
|
|
20
|
+
return container.bind(entry.provide).to(entry.useClass);
|
|
21
|
+
}
|
|
22
|
+
if (isClassProviderConfigEntryToken(entry)) {
|
|
23
|
+
return container.bind(entry.provide).to(entry.provide);
|
|
24
|
+
}
|
|
25
|
+
if (isValueProviderConfigEntry(entry)) {
|
|
26
|
+
// using toDynamicValue to return BindingInSyntax
|
|
27
|
+
return container.bind(entry.provide).toDynamicValue(()=>entry.useValue);
|
|
28
|
+
}
|
|
29
|
+
return container.bind(entry).to(entry);
|
|
30
|
+
};
|
|
31
|
+
const unbindEntry = (container)=>(entry)=>{
|
|
32
|
+
if (isProviderConfigEntryInheritable(entry) && !container.isCurrentBound(entry.provide)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (isClassProviderConfigEntryUseClass(entry) || isValueProviderConfigEntry(entry) || isClassProviderConfigEntryToken(entry)) {
|
|
36
|
+
return container.unbind(entry.provide);
|
|
37
|
+
}
|
|
38
|
+
return container.unbind(entry);
|
|
39
|
+
};
|
|
40
|
+
export function bindEntries(container, { singletons = [], instances = [] }) {
|
|
41
|
+
singletons.map(bindEntry(container, true)).forEach((binding)=>{
|
|
42
|
+
binding === null || binding === void 0 ? void 0 : binding.inSingletonScope();
|
|
43
|
+
});
|
|
44
|
+
instances.forEach(bindEntry(container, false));
|
|
45
|
+
}
|
|
46
|
+
export function unbindEntries(container, { singletons = [], instances = [] }) {
|
|
47
|
+
[
|
|
48
|
+
...singletons,
|
|
49
|
+
...instances
|
|
50
|
+
].forEach(unbindEntry(container));
|
|
51
|
+
}
|
|
52
|
+
export function initializeStores(stores, onError) {
|
|
53
|
+
const promises = [];
|
|
54
|
+
for (const instance of stores){
|
|
55
|
+
let promise;
|
|
56
|
+
try {
|
|
57
|
+
var _instance_initialize;
|
|
58
|
+
promise = (_instance_initialize = instance.initialize) === null || _instance_initialize === void 0 ? void 0 : _instance_initialize.call(instance);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
onError(e);
|
|
61
|
+
}
|
|
62
|
+
if (promise && typeof promise.catch === 'function') {
|
|
63
|
+
promises.push(promise.catch(onError));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return promises;
|
|
67
|
+
}
|
|
68
|
+
export function disposeStores(stores) {
|
|
69
|
+
for (const instance of stores){
|
|
70
|
+
var _instance_dispose;
|
|
71
|
+
(_instance_dispose = instance.dispose) === null || _instance_dispose === void 0 ? void 0 : _instance_dispose.call(instance);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function formatDuplicatesMessage(source, duplicates) {
|
|
75
|
+
const names = duplicates.map(formatToken).join(', ');
|
|
76
|
+
return `${source}: token listed more than once: ${names}. Remove the duplicate entries.`;
|
|
77
|
+
}
|
|
78
|
+
// Rethrow asynchronously so the error reaches the global error handler
|
|
79
|
+
export function rethrowAsync(e) {
|
|
80
|
+
setTimeout(()=>{
|
|
81
|
+
throw e;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//# sourceMappingURL=container-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/container-config.ts"],"sourcesContent":["import { Container } from 'inversify';\nimport { Token } from './common';\nimport {\n formatToken,\n getProvideTokenWithClass,\n isClassProviderConfigEntryToken,\n isClassProviderConfigEntryUseClass,\n isProviderConfigEntryInheritable,\n isValueProviderConfigEntry,\n ProviderConfigEntries,\n ProviderConfigEntry,\n} from './entry-helpers';\nimport { isStore, Store } from './store';\n\nexport function getStoreInstances(\n container: Container,\n { singletons = [], instances = [] }: ProviderConfigEntries\n): Store[] {\n return [...singletons, ...instances].reduce((out, entry) => {\n const [provide, useClass] = getProvideTokenWithClass(entry);\n\n if (provide && useClass && container.isCurrentBound(provide) && isStore(useClass)) {\n out.push(container.get(provide));\n }\n\n return out;\n }, [] as Store[]);\n}\n\nconst bindEntry =\n (container: Container, checkInherit: boolean) => (entry: ProviderConfigEntry<any>) => {\n if (\n checkInherit &&\n isProviderConfigEntryInheritable(entry) &&\n entry.inherit &&\n container.isBound(entry.provide)\n ) {\n return undefined;\n }\n\n if (isClassProviderConfigEntryUseClass(entry)) {\n return container.bind(entry.provide).to(entry.useClass);\n }\n\n if (isClassProviderConfigEntryToken(entry)) {\n return container.bind(entry.provide).to(entry.provide);\n }\n\n if (isValueProviderConfigEntry(entry)) {\n // using toDynamicValue to return BindingInSyntax\n return container.bind(entry.provide).toDynamicValue(() => entry.useValue);\n }\n\n return container.bind(entry).to(entry);\n };\n\nconst unbindEntry = (container: Container) => (entry: ProviderConfigEntry<any>) => {\n if (isProviderConfigEntryInheritable(entry) && !container.isCurrentBound(entry.provide)) {\n return;\n }\n if (\n isClassProviderConfigEntryUseClass(entry) ||\n isValueProviderConfigEntry(entry) ||\n isClassProviderConfigEntryToken(entry)\n ) {\n return container.unbind(entry.provide);\n }\n\n return container.unbind(entry);\n};\n\nexport function bindEntries(\n container: Container,\n { singletons = [], instances = [] }: ProviderConfigEntries\n) {\n singletons.map(bindEntry(container, true)).forEach(binding => {\n binding?.inSingletonScope();\n });\n instances.forEach(bindEntry(container, false));\n}\n\nexport function unbindEntries(\n container: Container,\n { singletons = [], instances = [] }: ProviderConfigEntries\n) {\n [...singletons, ...instances].forEach(unbindEntry(container));\n}\n\nexport function initializeStores(stores: Store[], onError: (error: any) => void) {\n const promises: Promise<void>[] = [];\n\n for (const instance of stores) {\n let promise;\n\n try {\n promise = instance.initialize?.();\n } catch (e: any) {\n onError(e);\n }\n\n if (promise && typeof promise.catch === 'function') {\n promises.push(promise.catch(onError));\n }\n }\n\n return promises;\n}\n\nexport function disposeStores(stores: Store[]) {\n for (const instance of stores) {\n instance.dispose?.();\n }\n}\n\nexport function formatDuplicatesMessage(source: string, duplicates: Token<any>[]): string {\n const names = duplicates.map(formatToken).join(', ');\n return `${source}: token listed more than once: ${names}. Remove the duplicate entries.`;\n}\n\n// Rethrow asynchronously so the error reaches the global error handler\nexport function rethrowAsync(e: any) {\n setTimeout(() => {\n throw e;\n });\n}\n"],"names":["formatToken","getProvideTokenWithClass","isClassProviderConfigEntryToken","isClassProviderConfigEntryUseClass","isProviderConfigEntryInheritable","isValueProviderConfigEntry","isStore","getStoreInstances","container","singletons","instances","reduce","out","entry","provide","useClass","isCurrentBound","push","get","bindEntry","checkInherit","inherit","isBound","undefined","bind","to","toDynamicValue","useValue","unbindEntry","unbind","bindEntries","map","forEach","binding","inSingletonScope","unbindEntries","initializeStores","stores","onError","promises","instance","promise","initialize","e","catch","disposeStores","dispose","formatDuplicatesMessage","source","duplicates","names","join","rethrowAsync","setTimeout"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { Provider } from './provider';
|
|
|
7
7
|
export type { ProviderProps } from './provider';
|
|
8
8
|
export { Store } from './store';
|
|
9
9
|
export { useDependencies, useOptionalDependencies } from './use-dependencies';
|
|
10
|
+
export { useLocalStores } from './use-local-stores';
|
|
10
11
|
export { Container, inject, injectable, optional, unmanaged } from 'inversify';
|
|
11
12
|
export type { interfaces } from 'inversify';
|
|
12
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { provide } from './provide';
|
|
|
5
5
|
export { Provider } from './provider';
|
|
6
6
|
export { Store } from './store';
|
|
7
7
|
export { useDependencies, useOptionalDependencies } from './use-dependencies';
|
|
8
|
+
export { useLocalStores } from './use-local-stores';
|
|
8
9
|
export { Container, inject, injectable, optional, unmanaged } from 'inversify';
|
|
9
10
|
|
|
10
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import 'reflect-metadata';\n\nexport { rootContainer, symbolToken } from './common';\nexport type { SymbolToken, Token } from './common';\nexport { injectDependency } from './inject-dependency';\nexport { provide } from './provide';\nexport { Provider } from './provider';\nexport type { ProviderProps } from './provider';\nexport { Store } from './store';\nexport { useDependencies, useOptionalDependencies } from './use-dependencies';\n\nexport { Container, inject, injectable, optional, unmanaged } from 'inversify';\nexport type { interfaces } from 'inversify';\n"],"names":["rootContainer","symbolToken","injectDependency","provide","Provider","Store","useDependencies","useOptionalDependencies","Container","inject","injectable","optional","unmanaged"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAASA,aAAa,EAAEC,WAAW,QAAQ,WAAW;AAEtD,SAASC,gBAAgB,QAAQ,sBAAsB;AACvD,SAASC,OAAO,QAAQ,YAAY;AACpC,SAASC,QAAQ,QAAQ,aAAa;AAEtC,SAASC,KAAK,QAAQ,UAAU;AAChC,SAASC,eAAe,EAAEC,uBAAuB,QAAQ,qBAAqB;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import 'reflect-metadata';\n\nexport { rootContainer, symbolToken } from './common';\nexport type { SymbolToken, Token } from './common';\nexport { injectDependency } from './inject-dependency';\nexport { provide } from './provide';\nexport { Provider } from './provider';\nexport type { ProviderProps } from './provider';\nexport { Store } from './store';\nexport { useDependencies, useOptionalDependencies } from './use-dependencies';\nexport { useLocalStores } from './use-local-stores';\n\nexport { Container, inject, injectable, optional, unmanaged } from 'inversify';\nexport type { interfaces } from 'inversify';\n"],"names":["rootContainer","symbolToken","injectDependency","provide","Provider","Store","useDependencies","useOptionalDependencies","useLocalStores","Container","inject","injectable","optional","unmanaged"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAASA,aAAa,EAAEC,WAAW,QAAQ,WAAW;AAEtD,SAASC,gBAAgB,QAAQ,sBAAsB;AACvD,SAASC,OAAO,QAAQ,YAAY;AACpC,SAASC,QAAQ,QAAQ,aAAa;AAEtC,SAASC,KAAK,QAAQ,UAAU;AAChC,SAASC,eAAe,EAAEC,uBAAuB,QAAQ,qBAAqB;AAC9E,SAASC,cAAc,QAAQ,qBAAqB;AAEpD,SAASC,SAAS,EAAEC,MAAM,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,SAAS,QAAQ,YAAY"}
|
package/dist/provider.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAmC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAmC,MAAM,OAAO,CAAC;AAa1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,MAAM,aAAa,GAAG,iBAAiB,CACzC,qBAAqB,GAAG;IACpB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,aAAa,CAAC,EAAE,SAAS,CAAC;CAC7B,CACJ,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAwEtC,CAAC"}
|
package/dist/provider.js
CHANGED
|
@@ -3,85 +3,9 @@ import { Container } from 'inversify';
|
|
|
3
3
|
import { useContext, useEffect, useState } from 'react';
|
|
4
4
|
import { Await } from './await';
|
|
5
5
|
import { ContainerContext } from './common';
|
|
6
|
+
import { bindEntries, disposeStores, formatDuplicatesMessage, getStoreInstances, initializeStores, rethrowAsync, unbindEntries } from './container-config';
|
|
6
7
|
import { dedupeEntries } from './dedupe-entries';
|
|
7
|
-
import { formatToken, getProvideTokenWithClass, isClassProviderConfigEntryToken, isClassProviderConfigEntryUseClass, isProviderConfigEntryInheritable, isValueProviderConfigEntry } from './entry-helpers';
|
|
8
8
|
import { defaultErrorFallback, defaultLoadingFallback } from './fallbacks';
|
|
9
|
-
import { isStore } from './store';
|
|
10
|
-
function getStoreInstances(container, { singletons = [], instances = [] }) {
|
|
11
|
-
return [
|
|
12
|
-
...singletons,
|
|
13
|
-
...instances
|
|
14
|
-
].reduce((out, entry)=>{
|
|
15
|
-
const [provide, useClass] = getProvideTokenWithClass(entry);
|
|
16
|
-
if (provide && useClass && container.isCurrentBound(provide) && isStore(useClass)) {
|
|
17
|
-
out.push(container.get(provide));
|
|
18
|
-
}
|
|
19
|
-
return out;
|
|
20
|
-
}, []);
|
|
21
|
-
}
|
|
22
|
-
const bindEntry = (container, checkInherit)=>(entry)=>{
|
|
23
|
-
if (checkInherit && isProviderConfigEntryInheritable(entry) && entry.inherit && container.isBound(entry.provide)) {
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
26
|
-
if (isClassProviderConfigEntryUseClass(entry)) {
|
|
27
|
-
return container.bind(entry.provide).to(entry.useClass);
|
|
28
|
-
}
|
|
29
|
-
if (isClassProviderConfigEntryToken(entry)) {
|
|
30
|
-
return container.bind(entry.provide).to(entry.provide);
|
|
31
|
-
}
|
|
32
|
-
if (isValueProviderConfigEntry(entry)) {
|
|
33
|
-
// using toDynamicValue to return BindingInSyntax
|
|
34
|
-
return container.bind(entry.provide).toDynamicValue(()=>entry.useValue);
|
|
35
|
-
}
|
|
36
|
-
return container.bind(entry).to(entry);
|
|
37
|
-
};
|
|
38
|
-
const unbindEntry = (container)=>(entry)=>{
|
|
39
|
-
if (isProviderConfigEntryInheritable(entry) && !container.isCurrentBound(entry.provide)) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (isClassProviderConfigEntryUseClass(entry) || isValueProviderConfigEntry(entry) || isClassProviderConfigEntryToken(entry)) {
|
|
43
|
-
return container.unbind(entry.provide);
|
|
44
|
-
}
|
|
45
|
-
return container.unbind(entry);
|
|
46
|
-
};
|
|
47
|
-
function bindEntries(container, { singletons = [], instances = [] }) {
|
|
48
|
-
singletons.map(bindEntry(container, true)).forEach((binding)=>{
|
|
49
|
-
binding === null || binding === void 0 ? void 0 : binding.inSingletonScope();
|
|
50
|
-
});
|
|
51
|
-
instances.forEach(bindEntry(container, false));
|
|
52
|
-
}
|
|
53
|
-
function unbindEntries(container, { singletons = [], instances = [] }) {
|
|
54
|
-
[
|
|
55
|
-
...singletons,
|
|
56
|
-
...instances
|
|
57
|
-
].forEach(unbindEntry(container));
|
|
58
|
-
}
|
|
59
|
-
function initializeStores(stores, onError) {
|
|
60
|
-
const promises = [];
|
|
61
|
-
for (const instance of stores){
|
|
62
|
-
let promise;
|
|
63
|
-
try {
|
|
64
|
-
var _instance_initialize;
|
|
65
|
-
promise = (_instance_initialize = instance.initialize) === null || _instance_initialize === void 0 ? void 0 : _instance_initialize.call(instance);
|
|
66
|
-
} catch (e) {
|
|
67
|
-
onError(e);
|
|
68
|
-
}
|
|
69
|
-
if (promise && typeof promise.catch === 'function') {
|
|
70
|
-
promises.push(promise.catch(onError));
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return promises;
|
|
74
|
-
}
|
|
75
|
-
function disposeStores(stores) {
|
|
76
|
-
for (const instance of stores){
|
|
77
|
-
var _instance_dispose;
|
|
78
|
-
(_instance_dispose = instance.dispose) === null || _instance_dispose === void 0 ? void 0 : _instance_dispose.call(instance);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
function formatDuplicatesMessage(duplicates) {
|
|
82
|
-
const names = duplicates.map(formatToken).join(', ');
|
|
83
|
-
return `Provider: token listed more than once: ${names}. Remove the duplicate entries.`;
|
|
84
|
-
}
|
|
85
9
|
export const Provider = ({ singletons, instances, loadingFallback = defaultLoadingFallback, errorFallback = defaultErrorFallback, children })=>{
|
|
86
10
|
const parentContainer = useContext(ContainerContext);
|
|
87
11
|
const [container, setContainer] = useState();
|
|
@@ -93,17 +17,14 @@ export const Provider = ({ singletons, instances, loadingFallback = defaultLoadi
|
|
|
93
17
|
setContainer(container);
|
|
94
18
|
const handleError = (e)=>{
|
|
95
19
|
setError(true);
|
|
96
|
-
|
|
97
|
-
setTimeout(()=>{
|
|
98
|
-
throw e;
|
|
99
|
-
});
|
|
20
|
+
rethrowAsync(e);
|
|
100
21
|
};
|
|
101
22
|
const config = dedupeEntries({
|
|
102
23
|
singletons,
|
|
103
24
|
instances
|
|
104
25
|
});
|
|
105
26
|
if (config.duplicates.length > 0) {
|
|
106
|
-
const message = formatDuplicatesMessage(config.duplicates);
|
|
27
|
+
const message = formatDuplicatesMessage('Provider', config.duplicates);
|
|
107
28
|
if (process.env.NODE_ENV !== 'production') {
|
|
108
29
|
handleError(new Error(message));
|
|
109
30
|
return ()=>{
|
package/dist/provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.tsx"],"sourcesContent":["import { Container } from 'inversify';\nimport { FC, PropsWithChildren, ReactNode, useContext, useEffect, useState } from 'react';\nimport { Await } from './await';\nimport { ContainerContext, Token } from './common';\nimport { dedupeEntries } from './dedupe-entries';\nimport {\n formatToken,\n getProvideTokenWithClass,\n isClassProviderConfigEntryToken,\n isClassProviderConfigEntryUseClass,\n isProviderConfigEntryInheritable,\n isValueProviderConfigEntry,\n ProviderConfigEntries,\n ProviderConfigEntry,\n} from './entry-helpers';\nimport { defaultErrorFallback, defaultLoadingFallback } from './fallbacks';\nimport { isStore, Store } from './store';\n\nfunction getStoreInstances(\n container: Container,\n { singletons = [], instances = [] }: ProviderConfigEntries\n): Store[] {\n return [...singletons, ...instances].reduce((out, entry) => {\n const [provide, useClass] = getProvideTokenWithClass(entry);\n\n if (provide && useClass && container.isCurrentBound(provide) && isStore(useClass)) {\n out.push(container.get(provide));\n }\n\n return out;\n }, [] as Store[]);\n}\n\nconst bindEntry =\n (container: Container, checkInherit: boolean) => (entry: ProviderConfigEntry<any>) => {\n if (\n checkInherit &&\n isProviderConfigEntryInheritable(entry) &&\n entry.inherit &&\n container.isBound(entry.provide)\n ) {\n return undefined;\n }\n\n if (isClassProviderConfigEntryUseClass(entry)) {\n return container.bind(entry.provide).to(entry.useClass);\n }\n\n if (isClassProviderConfigEntryToken(entry)) {\n return container.bind(entry.provide).to(entry.provide);\n }\n\n if (isValueProviderConfigEntry(entry)) {\n // using toDynamicValue to return BindingInSyntax\n return container.bind(entry.provide).toDynamicValue(() => entry.useValue);\n }\n\n return container.bind(entry).to(entry);\n };\n\nconst unbindEntry = (container: Container) => (entry: ProviderConfigEntry<any>) => {\n if (isProviderConfigEntryInheritable(entry) && !container.isCurrentBound(entry.provide)) {\n return;\n }\n if (\n isClassProviderConfigEntryUseClass(entry) ||\n isValueProviderConfigEntry(entry) ||\n isClassProviderConfigEntryToken(entry)\n ) {\n return container.unbind(entry.provide);\n }\n\n return container.unbind(entry);\n};\n\nfunction bindEntries(\n container: Container,\n { singletons = [], instances = [] }: ProviderConfigEntries\n) {\n singletons.map(bindEntry(container, true)).forEach(binding => {\n binding?.inSingletonScope();\n });\n instances.forEach(bindEntry(container, false));\n}\n\nfunction unbindEntries(\n container: Container,\n { singletons = [], instances = [] }: ProviderConfigEntries\n) {\n [...singletons, ...instances].forEach(unbindEntry(container));\n}\n\nfunction initializeStores(stores: Store[], onError: (error: any) => void) {\n const promises: Promise<void>[] = [];\n\n for (const instance of stores) {\n let promise;\n\n try {\n promise = instance.initialize?.();\n } catch (e: any) {\n onError(e);\n }\n\n if (promise && typeof promise.catch === 'function') {\n promises.push(promise.catch(onError));\n }\n }\n\n return promises;\n}\n\nfunction disposeStores(stores: Store[]) {\n for (const instance of stores) {\n instance.dispose?.();\n }\n}\n\nfunction formatDuplicatesMessage(duplicates: Token<any>[]): string {\n const names = duplicates.map(formatToken).join(', ');\n return `Provider: token listed more than once: ${names}. Remove the duplicate entries.`;\n}\n\nexport type ProviderProps = PropsWithChildren<\n ProviderConfigEntries & {\n loadingFallback?: ReactNode;\n errorFallback?: ReactNode;\n }\n>;\n\nexport const Provider: FC<ProviderProps> = ({\n singletons,\n instances,\n loadingFallback = defaultLoadingFallback,\n errorFallback = defaultErrorFallback,\n children,\n}) => {\n const parentContainer = useContext(ContainerContext);\n const [container, setContainer] = useState<Container>();\n const [promises, setPromises] = useState<Promise<void>[]>([]);\n const [error, setError] = useState(false);\n\n useEffect(() => {\n const container = new Container();\n container.parent = parentContainer;\n setContainer(container);\n\n const handleError = (e: any) => {\n setError(true);\n // Rethrow asynchronously for global error handler\n setTimeout(() => {\n throw e;\n });\n };\n\n const config = dedupeEntries({ singletons, instances });\n\n if (config.duplicates.length > 0) {\n const message = formatDuplicatesMessage(config.duplicates);\n if (process.env.NODE_ENV !== 'production') {\n handleError(new Error(message));\n return () => {\n setContainer(undefined);\n setPromises([]);\n };\n }\n // eslint-disable-next-line no-console\n console.warn(message);\n }\n\n bindEntries(container, config);\n const promises = initializeStores(getStoreInstances(container, config), handleError);\n setPromises(promises);\n\n return () => {\n const storeInstances = getStoreInstances(container, config);\n\n unbindEntries(container, config);\n disposeStores(storeInstances);\n setContainer(undefined);\n setPromises([]);\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!container) {\n return null;\n }\n\n const getContent = () => {\n if (error) {\n return errorFallback;\n }\n\n if (promises.length) {\n return (\n <Await promises={promises} fallback={loadingFallback}>\n {children}\n </Await>\n );\n }\n\n return children;\n };\n\n return <ContainerContext.Provider value={container}>{getContent()}</ContainerContext.Provider>;\n};\n"],"names":["Container","useContext","useEffect","useState","Await","ContainerContext","dedupeEntries","formatToken","getProvideTokenWithClass","isClassProviderConfigEntryToken","isClassProviderConfigEntryUseClass","isProviderConfigEntryInheritable","isValueProviderConfigEntry","defaultErrorFallback","defaultLoadingFallback","isStore","getStoreInstances","container","singletons","instances","reduce","out","entry","provide","useClass","isCurrentBound","push","get","bindEntry","checkInherit","inherit","isBound","undefined","bind","to","toDynamicValue","useValue","unbindEntry","unbind","bindEntries","map","forEach","binding","inSingletonScope","unbindEntries","initializeStores","stores","onError","promises","instance","promise","initialize","e","catch","disposeStores","dispose","formatDuplicatesMessage","duplicates","names","join","Provider","loadingFallback","errorFallback","children","parentContainer","setContainer","setPromises","error","setError","parent","handleError","setTimeout","config","length","message","process","env","NODE_ENV","Error","console","warn","storeInstances","getContent","fallback","value"],"mappings":";AAAA,SAASA,SAAS,QAAQ,YAAY;AACtC,SAA2CC,UAAU,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAC1F,SAASC,KAAK,QAAQ,UAAU;AAChC,SAASC,gBAAgB,QAAe,WAAW;AACnD,SAASC,aAAa,QAAQ,mBAAmB;AACjD,SACIC,WAAW,EACXC,wBAAwB,EACxBC,+BAA+B,EAC/BC,kCAAkC,EAClCC,gCAAgC,EAChCC,0BAA0B,QAGvB,kBAAkB;AACzB,SAASC,oBAAoB,EAAEC,sBAAsB,QAAQ,cAAc;AAC3E,SAASC,OAAO,QAAe,UAAU;AAEzC,SAASC,kBACLC,SAAoB,EACpB,EAAEC,aAAa,EAAE,EAAEC,YAAY,EAAE,EAAyB;IAE1D,OAAO;WAAID;WAAeC;KAAU,CAACC,MAAM,CAAC,CAACC,KAAKC;QAC9C,MAAM,CAACC,SAASC,SAAS,GAAGhB,yBAAyBc;QAErD,IAAIC,WAAWC,YAAYP,UAAUQ,cAAc,CAACF,YAAYR,QAAQS,WAAW;YAC/EH,IAAIK,IAAI,CAACT,UAAUU,GAAG,CAACJ;QAC3B;QAEA,OAAOF;IACX,GAAG,EAAE;AACT;AAEA,MAAMO,YACF,CAACX,WAAsBY,eAA0B,CAACP;QAC9C,IACIO,gBACAlB,iCAAiCW,UACjCA,MAAMQ,OAAO,IACbb,UAAUc,OAAO,CAACT,MAAMC,OAAO,GACjC;YACE,OAAOS;QACX;QAEA,IAAItB,mCAAmCY,QAAQ;YAC3C,OAAOL,UAAUgB,IAAI,CAACX,MAAMC,OAAO,EAAEW,EAAE,CAACZ,MAAME,QAAQ;QAC1D;QAEA,IAAIf,gCAAgCa,QAAQ;YACxC,OAAOL,UAAUgB,IAAI,CAACX,MAAMC,OAAO,EAAEW,EAAE,CAACZ,MAAMC,OAAO;QACzD;QAEA,IAAIX,2BAA2BU,QAAQ;YACnC,iDAAiD;YACjD,OAAOL,UAAUgB,IAAI,CAACX,MAAMC,OAAO,EAAEY,cAAc,CAAC,IAAMb,MAAMc,QAAQ;QAC5E;QAEA,OAAOnB,UAAUgB,IAAI,CAACX,OAAOY,EAAE,CAACZ;IACpC;AAEJ,MAAMe,cAAc,CAACpB,YAAyB,CAACK;QAC3C,IAAIX,iCAAiCW,UAAU,CAACL,UAAUQ,cAAc,CAACH,MAAMC,OAAO,GAAG;YACrF;QACJ;QACA,IACIb,mCAAmCY,UACnCV,2BAA2BU,UAC3Bb,gCAAgCa,QAClC;YACE,OAAOL,UAAUqB,MAAM,CAAChB,MAAMC,OAAO;QACzC;QAEA,OAAON,UAAUqB,MAAM,CAAChB;IAC5B;AAEA,SAASiB,YACLtB,SAAoB,EACpB,EAAEC,aAAa,EAAE,EAAEC,YAAY,EAAE,EAAyB;IAE1DD,WAAWsB,GAAG,CAACZ,UAAUX,WAAW,OAAOwB,OAAO,CAACC,CAAAA;QAC/CA,oBAAAA,8BAAAA,QAASC,gBAAgB;IAC7B;IACAxB,UAAUsB,OAAO,CAACb,UAAUX,WAAW;AAC3C;AAEA,SAAS2B,cACL3B,SAAoB,EACpB,EAAEC,aAAa,EAAE,EAAEC,YAAY,EAAE,EAAyB;IAE1D;WAAID;WAAeC;KAAU,CAACsB,OAAO,CAACJ,YAAYpB;AACtD;AAEA,SAAS4B,iBAAiBC,MAAe,EAAEC,OAA6B;IACpE,MAAMC,WAA4B,EAAE;IAEpC,KAAK,MAAMC,YAAYH,OAAQ;QAC3B,IAAII;QAEJ,IAAI;gBACUD;YAAVC,WAAUD,uBAAAA,SAASE,UAAU,cAAnBF,2CAAAA,0BAAAA;QACd,EAAE,OAAOG,GAAQ;YACbL,QAAQK;QACZ;QAEA,IAAIF,WAAW,OAAOA,QAAQG,KAAK,KAAK,YAAY;YAChDL,SAAStB,IAAI,CAACwB,QAAQG,KAAK,CAACN;QAChC;IACJ;IAEA,OAAOC;AACX;AAEA,SAASM,cAAcR,MAAe;IAClC,KAAK,MAAMG,YAAYH,OAAQ;YAC3BG;SAAAA,oBAAAA,SAASM,OAAO,cAAhBN,wCAAAA,uBAAAA;IACJ;AACJ;AAEA,SAASO,wBAAwBC,UAAwB;IACrD,MAAMC,QAAQD,WAAWjB,GAAG,CAACjC,aAAaoD,IAAI,CAAC;IAC/C,OAAO,CAAC,uCAAuC,EAAED,MAAM,+BAA+B,CAAC;AAC3F;AASA,OAAO,MAAME,WAA8B,CAAC,EACxC1C,UAAU,EACVC,SAAS,EACT0C,kBAAkB/C,sBAAsB,EACxCgD,gBAAgBjD,oBAAoB,EACpCkD,QAAQ,EACX;IACG,MAAMC,kBAAkB/D,WAAWI;IACnC,MAAM,CAACY,WAAWgD,aAAa,GAAG9D;IAClC,MAAM,CAAC6C,UAAUkB,YAAY,GAAG/D,SAA0B,EAAE;IAC5D,MAAM,CAACgE,OAAOC,SAAS,GAAGjE,SAAS;IAEnCD,UAAU;QACN,MAAMe,YAAY,IAAIjB;QACtBiB,UAAUoD,MAAM,GAAGL;QACnBC,aAAahD;QAEb,MAAMqD,cAAc,CAAClB;YACjBgB,SAAS;YACT,kDAAkD;YAClDG,WAAW;gBACP,MAAMnB;YACV;QACJ;QAEA,MAAMoB,SAASlE,cAAc;YAAEY;YAAYC;QAAU;QAErD,IAAIqD,OAAOf,UAAU,CAACgB,MAAM,GAAG,GAAG;YAC9B,MAAMC,UAAUlB,wBAAwBgB,OAAOf,UAAU;YACzD,IAAIkB,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACvCP,YAAY,IAAIQ,MAAMJ;gBACtB,OAAO;oBACHT,aAAajC;oBACbkC,YAAY,EAAE;gBAClB;YACJ;YACA,sCAAsC;YACtCa,QAAQC,IAAI,CAACN;QACjB;QAEAnC,YAAYtB,WAAWuD;QACvB,MAAMxB,WAAWH,iBAAiB7B,kBAAkBC,WAAWuD,SAASF;QACxEJ,YAAYlB;QAEZ,OAAO;YACH,MAAMiC,iBAAiBjE,kBAAkBC,WAAWuD;YAEpD5B,cAAc3B,WAAWuD;YACzBlB,cAAc2B;YACdhB,aAAajC;YACbkC,YAAY,EAAE;QAClB;IACJ,GAAG,EAAE,GAAG,kDAAkD;IAE1D,IAAI,CAACjD,WAAW;QACZ,OAAO;IACX;IAEA,MAAMiE,aAAa;QACf,IAAIf,OAAO;YACP,OAAOL;QACX;QAEA,IAAId,SAASyB,MAAM,EAAE;YACjB,qBACI,KAACrE;gBAAM4C,UAAUA;gBAAUmC,UAAUtB;0BAChCE;;QAGb;QAEA,OAAOA;IACX;IAEA,qBAAO,KAAC1D,iBAAiBuD,QAAQ;QAACwB,OAAOnE;kBAAYiE;;AACzD,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../src/provider.tsx"],"sourcesContent":["import { Container } from 'inversify';\nimport { FC, PropsWithChildren, ReactNode, useContext, useEffect, useState } from 'react';\nimport { Await } from './await';\nimport { ContainerContext } from './common';\nimport {\n bindEntries,\n disposeStores,\n formatDuplicatesMessage,\n getStoreInstances,\n initializeStores,\n rethrowAsync,\n unbindEntries,\n} from './container-config';\nimport { dedupeEntries } from './dedupe-entries';\nimport { ProviderConfigEntries } from './entry-helpers';\nimport { defaultErrorFallback, defaultLoadingFallback } from './fallbacks';\n\nexport type ProviderProps = PropsWithChildren<\n ProviderConfigEntries & {\n loadingFallback?: ReactNode;\n errorFallback?: ReactNode;\n }\n>;\n\nexport const Provider: FC<ProviderProps> = ({\n singletons,\n instances,\n loadingFallback = defaultLoadingFallback,\n errorFallback = defaultErrorFallback,\n children,\n}) => {\n const parentContainer = useContext(ContainerContext);\n const [container, setContainer] = useState<Container>();\n const [promises, setPromises] = useState<Promise<void>[]>([]);\n const [error, setError] = useState(false);\n\n useEffect(() => {\n const container = new Container();\n container.parent = parentContainer;\n setContainer(container);\n\n const handleError = (e: any) => {\n setError(true);\n rethrowAsync(e);\n };\n\n const config = dedupeEntries({ singletons, instances });\n\n if (config.duplicates.length > 0) {\n const message = formatDuplicatesMessage('Provider', config.duplicates);\n if (process.env.NODE_ENV !== 'production') {\n handleError(new Error(message));\n return () => {\n setContainer(undefined);\n setPromises([]);\n };\n }\n // eslint-disable-next-line no-console\n console.warn(message);\n }\n\n bindEntries(container, config);\n const promises = initializeStores(getStoreInstances(container, config), handleError);\n setPromises(promises);\n\n return () => {\n const storeInstances = getStoreInstances(container, config);\n\n unbindEntries(container, config);\n disposeStores(storeInstances);\n setContainer(undefined);\n setPromises([]);\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!container) {\n return null;\n }\n\n const getContent = () => {\n if (error) {\n return errorFallback;\n }\n\n if (promises.length) {\n return (\n <Await promises={promises} fallback={loadingFallback}>\n {children}\n </Await>\n );\n }\n\n return children;\n };\n\n return <ContainerContext.Provider value={container}>{getContent()}</ContainerContext.Provider>;\n};\n"],"names":["Container","useContext","useEffect","useState","Await","ContainerContext","bindEntries","disposeStores","formatDuplicatesMessage","getStoreInstances","initializeStores","rethrowAsync","unbindEntries","dedupeEntries","defaultErrorFallback","defaultLoadingFallback","Provider","singletons","instances","loadingFallback","errorFallback","children","parentContainer","container","setContainer","promises","setPromises","error","setError","parent","handleError","e","config","duplicates","length","message","process","env","NODE_ENV","Error","undefined","console","warn","storeInstances","getContent","fallback","value"],"mappings":";AAAA,SAASA,SAAS,QAAQ,YAAY;AACtC,SAA2CC,UAAU,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAC1F,SAASC,KAAK,QAAQ,UAAU;AAChC,SAASC,gBAAgB,QAAQ,WAAW;AAC5C,SACIC,WAAW,EACXC,aAAa,EACbC,uBAAuB,EACvBC,iBAAiB,EACjBC,gBAAgB,EAChBC,YAAY,EACZC,aAAa,QACV,qBAAqB;AAC5B,SAASC,aAAa,QAAQ,mBAAmB;AAEjD,SAASC,oBAAoB,EAAEC,sBAAsB,QAAQ,cAAc;AAS3E,OAAO,MAAMC,WAA8B,CAAC,EACxCC,UAAU,EACVC,SAAS,EACTC,kBAAkBJ,sBAAsB,EACxCK,gBAAgBN,oBAAoB,EACpCO,QAAQ,EACX;IACG,MAAMC,kBAAkBrB,WAAWI;IACnC,MAAM,CAACkB,WAAWC,aAAa,GAAGrB;IAClC,MAAM,CAACsB,UAAUC,YAAY,GAAGvB,SAA0B,EAAE;IAC5D,MAAM,CAACwB,OAAOC,SAAS,GAAGzB,SAAS;IAEnCD,UAAU;QACN,MAAMqB,YAAY,IAAIvB;QACtBuB,UAAUM,MAAM,GAAGP;QACnBE,aAAaD;QAEb,MAAMO,cAAc,CAACC;YACjBH,SAAS;YACTjB,aAAaoB;QACjB;QAEA,MAAMC,SAASnB,cAAc;YAAEI;YAAYC;QAAU;QAErD,IAAIc,OAAOC,UAAU,CAACC,MAAM,GAAG,GAAG;YAC9B,MAAMC,UAAU3B,wBAAwB,YAAYwB,OAAOC,UAAU;YACrE,IAAIG,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACvCR,YAAY,IAAIS,MAAMJ;gBACtB,OAAO;oBACHX,aAAagB;oBACbd,YAAY,EAAE;gBAClB;YACJ;YACA,sCAAsC;YACtCe,QAAQC,IAAI,CAACP;QACjB;QAEA7B,YAAYiB,WAAWS;QACvB,MAAMP,WAAWf,iBAAiBD,kBAAkBc,WAAWS,SAASF;QACxEJ,YAAYD;QAEZ,OAAO;YACH,MAAMkB,iBAAiBlC,kBAAkBc,WAAWS;YAEpDpB,cAAcW,WAAWS;YACzBzB,cAAcoC;YACdnB,aAAagB;YACbd,YAAY,EAAE;QAClB;IACJ,GAAG,EAAE,GAAG,kDAAkD;IAE1D,IAAI,CAACH,WAAW;QACZ,OAAO;IACX;IAEA,MAAMqB,aAAa;QACf,IAAIjB,OAAO;YACP,OAAOP;QACX;QAEA,IAAIK,SAASS,MAAM,EAAE;YACjB,qBACI,KAAC9B;gBAAMqB,UAAUA;gBAAUoB,UAAU1B;0BAChCE;;QAGb;QAEA,OAAOA;IACX;IAEA,qBAAO,KAAChB,iBAAiBW,QAAQ;QAAC8B,OAAOvB;kBAAYqB;;AACzD,EAAE"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { interfaces } from 'inversify';
|
|
2
|
+
type Newables<T extends any[]> = {
|
|
3
|
+
[P in keyof T]: interfaces.Newable<T[P]>;
|
|
4
|
+
};
|
|
5
|
+
export declare function useLocalStores<T extends any[]>(...stores: Newables<T>): [T, boolean];
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=use-local-stores.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-local-stores.d.ts","sourceRoot":"","sources":["../src/use-local-stores.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,WAAW,CAAC;AAclD,KAAK,QAAQ,CAAC,CAAC,SAAS,GAAG,EAAE,IAAI;KAC5B,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC3C,CAAC;AAOF,wBAAgB,cAAc,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,GAAG,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CA8DpF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Container } from 'inversify';
|
|
2
|
+
import { useContext, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { ContainerContext } from './common';
|
|
4
|
+
import { bindEntries, disposeStores, formatDuplicatesMessage, getStoreInstances, initializeStores, rethrowAsync } from './container-config';
|
|
5
|
+
import { dedupeEntries } from './dedupe-entries';
|
|
6
|
+
export function useLocalStores(...stores) {
|
|
7
|
+
const parentContainer = useContext(ContainerContext);
|
|
8
|
+
const ref = useRef(null);
|
|
9
|
+
/*
|
|
10
|
+
* Build the private container once, eagerly, so the instances are available
|
|
11
|
+
* synchronously on the first render. That is the reason this hook exists.
|
|
12
|
+
*/ if (ref.current === null) {
|
|
13
|
+
const container = new Container();
|
|
14
|
+
container.parent = parentContainer;
|
|
15
|
+
const config = dedupeEntries({
|
|
16
|
+
singletons: stores
|
|
17
|
+
});
|
|
18
|
+
if (config.duplicates.length > 0) {
|
|
19
|
+
const message = formatDuplicatesMessage('useLocalStores', config.duplicates);
|
|
20
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
21
|
+
throw new Error(message);
|
|
22
|
+
}
|
|
23
|
+
// eslint-disable-next-line no-console
|
|
24
|
+
console.warn(message);
|
|
25
|
+
}
|
|
26
|
+
bindEntries(container, config);
|
|
27
|
+
const storeInstances = getStoreInstances(container, config);
|
|
28
|
+
ref.current = {
|
|
29
|
+
instances: stores.map((store)=>container.get(store)),
|
|
30
|
+
storeInstances
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const { instances, storeInstances } = ref.current;
|
|
34
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
35
|
+
useEffect(()=>{
|
|
36
|
+
let cancelled = false;
|
|
37
|
+
const promises = initializeStores(storeInstances, (e)=>{
|
|
38
|
+
rethrowAsync(e);
|
|
39
|
+
});
|
|
40
|
+
if (promises.length === 0) {
|
|
41
|
+
setIsInitialized(true);
|
|
42
|
+
} else {
|
|
43
|
+
Promise.all(promises).then(()=>{
|
|
44
|
+
if (!cancelled) {
|
|
45
|
+
setIsInitialized(true);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return ()=>{
|
|
50
|
+
cancelled = true;
|
|
51
|
+
disposeStores(storeInstances);
|
|
52
|
+
setIsInitialized(false);
|
|
53
|
+
};
|
|
54
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
|
+
}, []);
|
|
56
|
+
return [
|
|
57
|
+
instances,
|
|
58
|
+
isInitialized
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=use-local-stores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/use-local-stores.ts"],"sourcesContent":["import { Container, interfaces } from 'inversify';\nimport { useContext, useEffect, useRef, useState } from 'react';\nimport { ContainerContext } from './common';\nimport {\n bindEntries,\n disposeStores,\n formatDuplicatesMessage,\n getStoreInstances,\n initializeStores,\n rethrowAsync,\n} from './container-config';\nimport { dedupeEntries } from './dedupe-entries';\nimport { Store } from './store';\n\ntype Newables<T extends any[]> = {\n [P in keyof T]: interfaces.Newable<T[P]>;\n};\n\ninterface LocalStores<T extends any[]> {\n instances: T;\n storeInstances: Store[];\n}\n\nexport function useLocalStores<T extends any[]>(...stores: Newables<T>): [T, boolean] {\n const parentContainer = useContext(ContainerContext);\n const ref = useRef<LocalStores<T> | null>(null);\n\n /*\n * Build the private container once, eagerly, so the instances are available\n * synchronously on the first render. That is the reason this hook exists.\n */\n if (ref.current === null) {\n const container = new Container();\n container.parent = parentContainer;\n\n const config = dedupeEntries({ singletons: stores });\n\n if (config.duplicates.length > 0) {\n const message = formatDuplicatesMessage('useLocalStores', config.duplicates);\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(message);\n }\n // eslint-disable-next-line no-console\n console.warn(message);\n }\n\n bindEntries(container, config);\n\n const storeInstances = getStoreInstances(container, config);\n\n ref.current = {\n instances: stores.map(store => container.get(store)) as T,\n storeInstances,\n };\n }\n\n const { instances, storeInstances } = ref.current;\n const [isInitialized, setIsInitialized] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n\n const promises = initializeStores(storeInstances, e => {\n rethrowAsync(e);\n });\n\n if (promises.length === 0) {\n setIsInitialized(true);\n } else {\n Promise.all(promises).then(() => {\n if (!cancelled) {\n setIsInitialized(true);\n }\n });\n }\n\n return () => {\n cancelled = true;\n disposeStores(storeInstances);\n setIsInitialized(false);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return [instances, isInitialized];\n}\n"],"names":["Container","useContext","useEffect","useRef","useState","ContainerContext","bindEntries","disposeStores","formatDuplicatesMessage","getStoreInstances","initializeStores","rethrowAsync","dedupeEntries","useLocalStores","stores","parentContainer","ref","current","container","parent","config","singletons","duplicates","length","message","process","env","NODE_ENV","Error","console","warn","storeInstances","instances","map","store","get","isInitialized","setIsInitialized","cancelled","promises","e","Promise","all","then"],"mappings":"AAAA,SAASA,SAAS,QAAoB,YAAY;AAClD,SAASC,UAAU,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAChE,SAASC,gBAAgB,QAAQ,WAAW;AAC5C,SACIC,WAAW,EACXC,aAAa,EACbC,uBAAuB,EACvBC,iBAAiB,EACjBC,gBAAgB,EAChBC,YAAY,QACT,qBAAqB;AAC5B,SAASC,aAAa,QAAQ,mBAAmB;AAYjD,OAAO,SAASC,eAAgC,GAAGC,MAAmB;IAClE,MAAMC,kBAAkBd,WAAWI;IACnC,MAAMW,MAAMb,OAA8B;IAE1C;;;KAGC,GACD,IAAIa,IAAIC,OAAO,KAAK,MAAM;QACtB,MAAMC,YAAY,IAAIlB;QACtBkB,UAAUC,MAAM,GAAGJ;QAEnB,MAAMK,SAASR,cAAc;YAAES,YAAYP;QAAO;QAElD,IAAIM,OAAOE,UAAU,CAACC,MAAM,GAAG,GAAG;YAC9B,MAAMC,UAAUhB,wBAAwB,kBAAkBY,OAAOE,UAAU;YAC3E,IAAIG,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACvC,MAAM,IAAIC,MAAMJ;YACpB;YACA,sCAAsC;YACtCK,QAAQC,IAAI,CAACN;QACjB;QAEAlB,YAAYY,WAAWE;QAEvB,MAAMW,iBAAiBtB,kBAAkBS,WAAWE;QAEpDJ,IAAIC,OAAO,GAAG;YACVe,WAAWlB,OAAOmB,GAAG,CAACC,CAAAA,QAAShB,UAAUiB,GAAG,CAACD;YAC7CH;QACJ;IACJ;IAEA,MAAM,EAAEC,SAAS,EAAED,cAAc,EAAE,GAAGf,IAAIC,OAAO;IACjD,MAAM,CAACmB,eAAeC,iBAAiB,GAAGjC,SAAS;IAEnDF,UAAU;QACN,IAAIoC,YAAY;QAEhB,MAAMC,WAAW7B,iBAAiBqB,gBAAgBS,CAAAA;YAC9C7B,aAAa6B;QACjB;QAEA,IAAID,SAAShB,MAAM,KAAK,GAAG;YACvBc,iBAAiB;QACrB,OAAO;YACHI,QAAQC,GAAG,CAACH,UAAUI,IAAI,CAAC;gBACvB,IAAI,CAACL,WAAW;oBACZD,iBAAiB;gBACrB;YACJ;QACJ;QAEA,OAAO;YACHC,YAAY;YACZ/B,cAAcwB;YACdM,iBAAiB;QACrB;IACA,uDAAuD;IAC3D,GAAG,EAAE;IAEL,OAAO;QAACL;QAAWI;KAAc;AACrC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/react-ioc",
|
|
3
|
-
"version": "38.
|
|
3
|
+
"version": "38.2.0",
|
|
4
4
|
"description": "Implementation of InversifyJS for React applications using Context API",
|
|
5
5
|
"homepage": "https://docs.st.dev/docs/frontend/uikit/react-ioc",
|
|
6
6
|
"repository": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@testing-library/dom": "^10.4.1",
|
|
24
|
-
"@testing-library/jest-dom": "^
|
|
24
|
+
"@testing-library/jest-dom": "^7.0.0",
|
|
25
25
|
"@testing-library/react": "^16.3.2",
|
|
26
26
|
"@types/react": "~18.3.3",
|
|
27
27
|
"react": "~18.3.1"
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"cli": {
|
|
36
36
|
"webpack": false
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "fd8cf00982a529371e44d76a0ca455dbbb42bae5"
|
|
39
39
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { Container, inject, injectable } from 'inversify';
|
|
2
|
+
import { bindEntries, initializeStores } from '../container-config';
|
|
3
|
+
import { Store } from '../store';
|
|
4
|
+
|
|
5
|
+
@injectable()
|
|
6
|
+
class Leaf extends Store {}
|
|
7
|
+
|
|
8
|
+
@injectable()
|
|
9
|
+
class Mid extends Store {
|
|
10
|
+
constructor(@inject(Leaf) public leaf: Leaf) {
|
|
11
|
+
super();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@injectable()
|
|
16
|
+
class Top extends Store {
|
|
17
|
+
constructor(@inject(Mid) public mid: Mid) {
|
|
18
|
+
super();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@injectable()
|
|
23
|
+
class BranchOne extends Store {
|
|
24
|
+
constructor(@inject(Leaf) public leaf: Leaf) {
|
|
25
|
+
super();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@injectable()
|
|
30
|
+
class BranchTwo extends Store {
|
|
31
|
+
constructor(@inject(Leaf) public leaf: Leaf) {
|
|
32
|
+
super();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@injectable()
|
|
37
|
+
class DiamondTop extends Store {
|
|
38
|
+
constructor(
|
|
39
|
+
@inject(BranchOne) public one: BranchOne,
|
|
40
|
+
@inject(BranchTwo) public two: BranchTwo
|
|
41
|
+
) {
|
|
42
|
+
super();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
describe('[react-ioc] container-config', () => {
|
|
47
|
+
describe('bindEntries', () => {
|
|
48
|
+
let container: Container;
|
|
49
|
+
|
|
50
|
+
beforeEach(() => (container = new Container()));
|
|
51
|
+
|
|
52
|
+
describe('with a three-level dependency chain', () => {
|
|
53
|
+
beforeEach(() => bindEntries(container, { singletons: [Top, Mid, Leaf] }));
|
|
54
|
+
|
|
55
|
+
const subject = () => container.get(Top);
|
|
56
|
+
|
|
57
|
+
test('shares the Mid instance with the one injected into Top', () => {
|
|
58
|
+
const top = subject();
|
|
59
|
+
|
|
60
|
+
expect(container.get(Mid)).toBe(top.mid);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('shares the Leaf instance with the one injected into Mid', () => {
|
|
64
|
+
const top = subject();
|
|
65
|
+
|
|
66
|
+
expect(container.get(Leaf)).toBe(top.mid.leaf);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('with a diamond dependency graph', () => {
|
|
71
|
+
beforeEach(() =>
|
|
72
|
+
bindEntries(container, { singletons: [DiamondTop, BranchOne, BranchTwo, Leaf] })
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const subject = () => container.get(DiamondTop);
|
|
76
|
+
|
|
77
|
+
test('shares the Leaf instance across both branches', () => {
|
|
78
|
+
const top = subject();
|
|
79
|
+
|
|
80
|
+
expect(top.one.leaf).toBe(top.two.leaf);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('with the dependent listed before its dependency', () => {
|
|
85
|
+
beforeEach(() => bindEntries(container, { singletons: [Mid, Leaf] }));
|
|
86
|
+
|
|
87
|
+
const subject = () => container.get(Mid);
|
|
88
|
+
|
|
89
|
+
test('resolves the dependency regardless of listing order', () => {
|
|
90
|
+
const mid = subject();
|
|
91
|
+
|
|
92
|
+
expect(container.get(Leaf)).toBe(mid.leaf);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('initializeStores', () => {
|
|
98
|
+
let onError: jest.Mock;
|
|
99
|
+
|
|
100
|
+
beforeEach(() => (onError = jest.fn()));
|
|
101
|
+
|
|
102
|
+
describe('with a store whose initialize throws synchronously', () => {
|
|
103
|
+
class Thrower extends Store {
|
|
104
|
+
initialize() {
|
|
105
|
+
throw new Error('init failed');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
class Later extends Store {
|
|
110
|
+
initialize = jest.fn();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let later: Later;
|
|
114
|
+
|
|
115
|
+
beforeEach(() => (later = new Later()));
|
|
116
|
+
|
|
117
|
+
const subject = () => initializeStores([new Thrower(), later], onError);
|
|
118
|
+
|
|
119
|
+
test('reports the error to onError', () => {
|
|
120
|
+
subject();
|
|
121
|
+
|
|
122
|
+
expect(onError).toHaveBeenCalledWith(
|
|
123
|
+
expect.objectContaining({ message: 'init failed' })
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('still initializes the later store', () => {
|
|
128
|
+
subject();
|
|
129
|
+
|
|
130
|
+
expect(later.initialize).toHaveBeenCalled();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('with a store whose initialize rejects', () => {
|
|
135
|
+
class Rejecter extends Store {
|
|
136
|
+
initialize() {
|
|
137
|
+
return Promise.reject(new Error('async init failed'));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const subject = () => initializeStores([new Rejecter()], onError);
|
|
142
|
+
|
|
143
|
+
test('settles the returned promise instead of rejecting', async () => {
|
|
144
|
+
const [promise] = subject();
|
|
145
|
+
|
|
146
|
+
await expect(promise).resolves.toBeUndefined();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('reports the error to onError', async () => {
|
|
150
|
+
const [promise] = subject();
|
|
151
|
+
await promise;
|
|
152
|
+
|
|
153
|
+
expect(onError).toHaveBeenCalledWith(
|
|
154
|
+
expect.objectContaining({ message: 'async init failed' })
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|