@fluidframework/synthesize 0.54.2 → 0.56.0-49831

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.
@@ -2,14 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IFluidObject } from "@fluidframework/core-interfaces";
6
- import { AsyncFluidObjectProvider, FluidObjectSymbolProvider, FluidObjectProvider, FluidObjectKey } from "./types";
7
- declare module "@fluidframework/core-interfaces" {
8
- interface IFluidObject {
9
- /** @deprecated - use `FluidObject<IFluidDependencySynthesizer>` instead */
10
- readonly IFluidDependencySynthesizer?: IFluidDependencySynthesizer;
11
- }
12
- }
5
+ import { AsyncFluidObjectProvider, FluidObjectSymbolProvider } from "./types";
13
6
  export declare const IFluidDependencySynthesizer: keyof IProvideFluidDependencySynthesizer;
14
7
  export interface IProvideFluidDependencySynthesizer {
15
8
  IFluidDependencySynthesizer: IFluidDependencySynthesizer;
@@ -20,22 +13,6 @@ export interface IProvideFluidDependencySynthesizer {
20
13
  * and required types.
21
14
  */
22
15
  export interface IFluidDependencySynthesizer extends IProvideFluidDependencySynthesizer {
23
- /**
24
- * All the registered types available
25
- */
26
- readonly registeredTypes: Iterable<(keyof IFluidObject)>;
27
- /**
28
- * Add a new provider
29
- * @param type - Name of the Type T being provided
30
- * @param provider - A provider that will resolve the T correctly when asked
31
- * @throws - If passing a type that's already registered
32
- */
33
- register<T extends keyof IFluidObject>(type: T, provider: FluidObjectProvider<T>): void;
34
- /**
35
- * Remove a provider
36
- * @param type - Name of the provider to remove
37
- */
38
- unregister<T extends keyof IFluidObject>(type: T): void;
39
16
  /**
40
17
  * synthesize takes optional and required types and returns an object that will fulfill the
41
18
  * defined types based off objects that has been previously registered.
@@ -43,16 +20,11 @@ export interface IFluidDependencySynthesizer extends IProvideFluidDependencySynt
43
20
  * @param optionalTypes - optional types to be in the Scope object
44
21
  * @param requiredTypes - required types that need to be in the Scope object
45
22
  */
46
- synthesize<O extends IFluidObject, R extends IFluidObject>(optionalTypes: FluidObjectSymbolProvider<O>, requiredTypes: FluidObjectSymbolProvider<R>): AsyncFluidObjectProvider<FluidObjectKey<O>, FluidObjectKey<R>>;
23
+ synthesize<O, R = undefined | Record<string, never>>(optionalTypes: FluidObjectSymbolProvider<O>, requiredTypes: Required<FluidObjectSymbolProvider<R>>): AsyncFluidObjectProvider<O, R>;
47
24
  /**
48
25
  * Check if a given type is registered
49
- * @param types - Type to check
50
- */
51
- has(...types: (keyof IFluidObject)[]): boolean;
52
- /**
53
- * Get a provider. undefined if not available.
54
- * @param type - Type to get
26
+ * @param type - Type to check
55
27
  */
56
- getProvider<T extends keyof IFluidObject>(type: T): FluidObjectProvider<T> | undefined;
28
+ has(type: string): boolean;
57
29
  }
58
30
  //# sourceMappingURL=IFluidDependencySynthesizer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IFluidDependencySynthesizer.d.ts","sourceRoot":"","sources":["../src/IFluidDependencySynthesizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EACH,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACjB,MAAM,SAAS,CAAC;AAEjB,OAAO,QAAQ,iCAAiC,CAAC;IAC7C,UAAiB,YAAY;QACzB,2EAA2E;QAC3E,QAAQ,CAAC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;KACtE;CACJ;AAED,eAAO,MAAM,2BAA2B,EAAE,MAAM,kCACb,CAAC;AAEpC,MAAM,WAAW,kCAAkC;IAC/C,2BAA2B,EAAE,2BAA2B,CAAC;CAC5D;AAED;;;;GAIG;AACH,MAAM,WAAW,2BAA4B,SAAQ,kCAAkC;IACnF;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAExF;;;OAGG;IACH,UAAU,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAExD;;;;;;OAMG;IACH,UAAU,CACN,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EAClB,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC,EAC3C,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAChD,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAElE;;;OAGG;IACH,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,YAAY,CAAC,EAAE,GAAG,OAAO,CAAC;IAE/C;;;OAGG;IACH,WAAW,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,IAAI,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CAC1F"}
1
+ {"version":3,"file":"IFluidDependencySynthesizer.d.ts","sourceRoot":"","sources":["../src/IFluidDependencySynthesizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,wBAAwB,EACxB,yBAAyB,EAC5B,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,2BAA2B,EAAE,MAAM,kCACb,CAAC;AAEpC,MAAM,WAAW,kCAAkC;IAC/C,2BAA2B,EAAE,2BAA2B,CAAC;CAC5D;AAED;;;;GAIG;AACH,MAAM,WAAW,2BAA4B,SAAQ,kCAAkC;IAEnF;;;;;;OAMG;IACH,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,GAAI,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC5C,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC,EAC3C,aAAa,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,GAC1D,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAElC;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"IFluidDependencySynthesizer.js","sourceRoot":"","sources":["../src/IFluidDependencySynthesizer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAiBU,QAAA,2BAA2B,GAClC,6BAA6B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidObject } from \"@fluidframework/core-interfaces\";\nimport {\n AsyncFluidObjectProvider,\n FluidObjectSymbolProvider,\n FluidObjectProvider,\n FluidObjectKey,\n} from \"./types\";\n\ndeclare module \"@fluidframework/core-interfaces\" {\n export interface IFluidObject {\n /** @deprecated - use `FluidObject<IFluidDependencySynthesizer>` instead */\n readonly IFluidDependencySynthesizer?: IFluidDependencySynthesizer;\n }\n}\n\nexport const IFluidDependencySynthesizer: keyof IProvideFluidDependencySynthesizer\n = \"IFluidDependencySynthesizer\";\n\nexport interface IProvideFluidDependencySynthesizer {\n IFluidDependencySynthesizer: IFluidDependencySynthesizer;\n}\n\n/**\n * IFluidDependencySynthesizer can generate IFluidObjects based on the IProvideFluidObject pattern.\n * It allow for registering providers and uses synthesize to generate a new object with the optional\n * and required types.\n */\nexport interface IFluidDependencySynthesizer extends IProvideFluidDependencySynthesizer {\n /**\n * All the registered types available\n */\n readonly registeredTypes: Iterable<(keyof IFluidObject)>;\n\n /**\n * Add a new provider\n * @param type - Name of the Type T being provided\n * @param provider - A provider that will resolve the T correctly when asked\n * @throws - If passing a type that's already registered\n */\n register<T extends keyof IFluidObject>(type: T, provider: FluidObjectProvider<T>): void;\n\n /**\n * Remove a provider\n * @param type - Name of the provider to remove\n */\n unregister<T extends keyof IFluidObject>(type: T): void;\n\n /**\n * synthesize takes optional and required types and returns an object that will fulfill the\n * defined types based off objects that has been previously registered.\n *\n * @param optionalTypes - optional types to be in the Scope object\n * @param requiredTypes - required types that need to be in the Scope object\n */\n synthesize<\n O extends IFluidObject,\n R extends IFluidObject>(\n optionalTypes: FluidObjectSymbolProvider<O>,\n requiredTypes: FluidObjectSymbolProvider<R>,\n ): AsyncFluidObjectProvider<FluidObjectKey<O>, FluidObjectKey<R>>;\n\n /**\n * Check if a given type is registered\n * @param types - Type to check\n */\n has(...types: (keyof IFluidObject)[]): boolean;\n\n /**\n * Get a provider. undefined if not available.\n * @param type - Type to get\n */\n getProvider<T extends keyof IFluidObject>(type: T): FluidObjectProvider<T> | undefined;\n}\n"]}
1
+ {"version":3,"file":"IFluidDependencySynthesizer.js","sourceRoot":"","sources":["../src/IFluidDependencySynthesizer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAOU,QAAA,2BAA2B,GAClC,6BAA6B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n AsyncFluidObjectProvider,\n FluidObjectSymbolProvider,\n} from \"./types\";\n\nexport const IFluidDependencySynthesizer: keyof IProvideFluidDependencySynthesizer\n = \"IFluidDependencySynthesizer\";\n\nexport interface IProvideFluidDependencySynthesizer {\n IFluidDependencySynthesizer: IFluidDependencySynthesizer;\n}\n\n/**\n * IFluidDependencySynthesizer can generate IFluidObjects based on the IProvideFluidObject pattern.\n * It allow for registering providers and uses synthesize to generate a new object with the optional\n * and required types.\n */\nexport interface IFluidDependencySynthesizer extends IProvideFluidDependencySynthesizer {\n \n /**\n * synthesize takes optional and required types and returns an object that will fulfill the\n * defined types based off objects that has been previously registered.\n *\n * @param optionalTypes - optional types to be in the Scope object\n * @param requiredTypes - required types that need to be in the Scope object\n */\n synthesize<O, R = undefined | Record<string, never>>(\n optionalTypes: FluidObjectSymbolProvider<O>,\n requiredTypes: Required<FluidObjectSymbolProvider<R>>,\n ): AsyncFluidObjectProvider<O, R>;\n\n /**\n * Check if a given type is registered\n * @param type - Type to check\n */\n has(type: string): boolean;\n}\n"]}
@@ -2,42 +2,38 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IFluidObject } from "@fluidframework/core-interfaces";
6
- import { AsyncFluidObjectProvider, FluidObjectSymbolProvider, FluidObjectProvider, FluidObjectKey } from "./types";
5
+ import { AsyncFluidObjectProvider, FluidObjectSymbolProvider, FluidObjectProvider } from "./types";
7
6
  import { IFluidDependencySynthesizer } from "./IFluidDependencySynthesizer";
8
7
  /**
9
8
  * DependencyContainer is similar to a IoC Container. It takes providers and will
10
9
  * synthesize an object based on them when requested.
11
10
  */
12
- export declare class DependencyContainer implements IFluidDependencySynthesizer {
13
- parent: IFluidDependencySynthesizer | undefined;
11
+ export declare class DependencyContainer<TMap> implements IFluidDependencySynthesizer {
14
12
  private readonly providers;
13
+ private readonly parents;
15
14
  get IFluidDependencySynthesizer(): this;
15
+ constructor(...parents: (IFluidDependencySynthesizer | undefined)[]);
16
16
  /**
17
- * {@inheritDoc (IFluidDependencySynthesizer:interface).registeredTypes}
17
+ * Add a new provider
18
+ * @param type - Name of the Type T being provided
19
+ * @param provider - A provider that will resolve the T correctly when asked
20
+ * @throws - If passing a type that's already registered
18
21
  */
19
- get registeredTypes(): Iterable<(keyof IFluidObject)>;
20
- constructor(parent?: IFluidDependencySynthesizer | undefined);
22
+ register<T extends keyof TMap = keyof TMap>(type: T, provider: FluidObjectProvider<Pick<TMap, T>>): void;
21
23
  /**
22
- * {@inheritDoc (IFluidDependencySynthesizer:interface).register}
24
+ * Remove a provider
25
+ * @param type - Name of the provider to remove
23
26
  */
24
- register<T extends keyof IFluidObject>(type: T, provider: FluidObjectProvider<T>): void;
25
- /**
26
- * {@inheritDoc (IFluidDependencySynthesizer:interface).unregister}
27
- */
28
- unregister<T extends keyof IFluidObject>(type: T): void;
27
+ unregister(type: keyof TMap): void;
29
28
  /**
30
29
  * {@inheritDoc (IFluidDependencySynthesizer:interface).synthesize}
31
30
  */
32
- synthesize<O extends IFluidObject, R extends IFluidObject = {}>(optionalTypes: FluidObjectSymbolProvider<O>, requiredTypes: FluidObjectSymbolProvider<R>): AsyncFluidObjectProvider<FluidObjectKey<O>, FluidObjectKey<R>>;
31
+ synthesize<O, R = undefined | Record<string, never>>(optionalTypes: FluidObjectSymbolProvider<O>, requiredTypes: Required<FluidObjectSymbolProvider<R>>): AsyncFluidObjectProvider<O, R>;
33
32
  /**
34
33
  * {@inheritDoc (IFluidDependencySynthesizer:interface).has}
34
+ * @param excludeParents - If true, exclude checking parent registries
35
35
  */
36
- has(...types: (keyof IFluidObject)[]): boolean;
37
- /**
38
- * {@inheritDoc (IFluidDependencySynthesizer:interface).getProvider}
39
- */
40
- getProvider<T extends keyof IFluidObject>(type: T): FluidObjectProvider<T> | undefined;
36
+ has(type: string, excludeParents?: boolean): boolean;
41
37
  private generateRequired;
42
38
  private generateOptional;
43
39
  private resolveProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"dependencyContainer.d.ts","sourceRoot":"","sources":["../src/dependencyContainer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EACH,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EACH,2BAA2B,EAC9B,MAAM,+BAA+B,CAAC;AAEvC;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,2BAA2B;IAYzC,MAAM,EAAE,2BAA2B,GAAG,SAAS;IAXzE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2D;IAErF,IAAW,2BAA2B,SAAmB;IAEzD;;OAEG;IACH,IAAW,eAAe,IAAI,QAAQ,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,CAE3D;gBAEyB,MAAM,GAAE,2BAA2B,GAAG,SAAqB;IAErF;;OAEG;IACI,QAAQ,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ9F;;OAEG;IACI,UAAU,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAM9D;;OAEG;IACI,UAAU,CACb,CAAC,SAAS,YAAY,EAEtB,CAAC,SAAS,YAAY,GAAG,EAAE,EACvB,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC,EAC3C,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAChD,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAcjE;;OAEG;IACI,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,YAAY,CAAC,EAAE,GAAG,OAAO;IAMrD;;OAEG;IACI,WAAW,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,IAAI,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,SAAS;IAc7F,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,eAAe;CA8B1B"}
1
+ {"version":3,"file":"dependencyContainer.d.ts","sourceRoot":"","sources":["../src/dependencyContainer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EAGtB,MAAM,SAAS,CAAC;AACjB,OAAO,EACH,2BAA2B,EAC9B,MAAM,+BAA+B,CAAC;AAEvC;;;GAGG;AACH,qBAAa,mBAAmB,CAAC,IAAI,CAAE,YAAW,2BAA2B;IACzE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmD;IAC7E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,IAAW,2BAA2B,SAAmB;gBAEtC,GAAI,OAAO,EAAE,CAAC,2BAA2B,GAAG,SAAS,CAAC,EAAE;IAI3E;;;;;OAKG;IACI,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ/G;;;OAGG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI;IAMzC;;OAEG;IACI,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACtD,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC,EAC3C,aAAa,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,GACtD,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC;IAQjC;;;OAGG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO;IAU3D,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,eAAe;CAyC1B"}
@@ -5,33 +5,32 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.DependencyContainer = void 0;
8
+ const IFluidDependencySynthesizer_1 = require("./IFluidDependencySynthesizer");
8
9
  /**
9
10
  * DependencyContainer is similar to a IoC Container. It takes providers and will
10
11
  * synthesize an object based on them when requested.
11
12
  */
12
13
  class DependencyContainer {
13
- constructor(parent = undefined) {
14
- this.parent = parent;
14
+ constructor(...parents) {
15
15
  this.providers = new Map();
16
+ this.parents = parents.filter((v) => v !== undefined);
16
17
  }
17
18
  get IFluidDependencySynthesizer() { return this; }
18
19
  /**
19
- * {@inheritDoc (IFluidDependencySynthesizer:interface).registeredTypes}
20
- */
21
- get registeredTypes() {
22
- return this.providers.keys();
23
- }
24
- /**
25
- * {@inheritDoc (IFluidDependencySynthesizer:interface).register}
20
+ * Add a new provider
21
+ * @param type - Name of the Type T being provided
22
+ * @param provider - A provider that will resolve the T correctly when asked
23
+ * @throws - If passing a type that's already registered
26
24
  */
27
25
  register(type, provider) {
28
- if (this.has(type)) {
26
+ if (this.providers.has(type)) {
29
27
  throw new Error(`Attempting to register a provider of type ${type} that already exists`);
30
28
  }
31
29
  this.providers.set(type, provider);
32
30
  }
33
31
  /**
34
- * {@inheritDoc (IFluidDependencySynthesizer:interface).unregister}
32
+ * Remove a provider
33
+ * @param type - Name of the provider to remove
35
34
  */
36
35
  unregister(type) {
37
36
  if (this.providers.has(type)) {
@@ -42,77 +41,76 @@ class DependencyContainer {
42
41
  * {@inheritDoc (IFluidDependencySynthesizer:interface).synthesize}
43
42
  */
44
43
  synthesize(optionalTypes, requiredTypes) {
45
- const optionalValues = Object.values(optionalTypes);
46
- const requiredValues = Object.values(requiredTypes);
47
- // There was nothing passed in so we can return
48
- if (optionalValues === [] && requiredValues === []) {
49
- return {};
50
- }
51
- const required = this.generateRequired(requiredTypes);
52
- const optional = this.generateOptional(optionalTypes);
53
- return Object.assign(Object.assign({}, required), optional);
44
+ const base = {};
45
+ this.generateRequired(base, requiredTypes);
46
+ this.generateOptional(base, optionalTypes);
47
+ Object.defineProperty(base, IFluidDependencySynthesizer_1.IFluidDependencySynthesizer, { get: () => this });
48
+ return base;
54
49
  }
55
50
  /**
56
51
  * {@inheritDoc (IFluidDependencySynthesizer:interface).has}
52
+ * @param excludeParents - If true, exclude checking parent registries
57
53
  */
58
- has(...types) {
59
- return types.every((type) => {
60
- return this.providers.has(type);
61
- });
62
- }
63
- /**
64
- * {@inheritDoc (IFluidDependencySynthesizer:interface).getProvider}
65
- */
66
- getProvider(type) {
67
- // If we have the provider return it
68
- const provider = this.providers.get(type);
69
- if (provider) {
70
- return provider;
54
+ has(type, excludeParents) {
55
+ if (this.providers.has(type)) {
56
+ return true;
71
57
  }
72
- if (this.parent) {
73
- return this.parent.getProvider(type);
58
+ if (excludeParents !== true) {
59
+ return this.parents.some((p) => p.has(type));
74
60
  }
75
- return undefined;
61
+ return false;
76
62
  }
77
- generateRequired(types) {
78
- const values = Object.values(types);
79
- return Object.assign({}, ...Array.from(values, (t) => {
80
- const provider = this.getProvider(t);
81
- if (!provider) {
82
- throw new Error(`Object attempted to be created without registered required provider ${t}`);
63
+ generateRequired(base, types) {
64
+ if (types === undefined)
65
+ return;
66
+ for (const key of Object.keys(types)) {
67
+ const provider = this.resolveProvider(key);
68
+ if (provider === undefined) {
69
+ throw new Error(`Object attempted to be created without registered required provider ${key}`);
83
70
  }
84
- return this.resolveProvider(provider, t);
85
- }));
71
+ Object.defineProperty(base, key, provider);
72
+ }
86
73
  }
87
- generateOptional(types) {
88
- const values = Object.values(types);
89
- return Object.assign({}, ...Array.from(values, (t) => {
90
- const provider = this.getProvider(t);
91
- if (!provider) {
92
- return { get [t]() { return Promise.resolve(undefined); } };
93
- }
94
- return this.resolveProvider(provider, t);
95
- }));
74
+ generateOptional(base, types) {
75
+ var _a;
76
+ if (types === undefined)
77
+ return;
78
+ for (const key of Object.keys(types)) {
79
+ // back-compat: in 0.56 we allow undefined in the types, but we didn't before
80
+ // this will keep runtime back compat, eventually we should support undefined properties
81
+ // rather than properties that return promises that resolve to undefined
82
+ const provider = (_a = this.resolveProvider(key)) !== null && _a !== void 0 ? _a : { get: () => Promise.resolve(undefined) };
83
+ Object.defineProperty(base, key, provider);
84
+ }
96
85
  }
97
- resolveProvider(provider, t) {
86
+ resolveProvider(t) {
87
+ // If we have the provider return it
88
+ const provider = this.providers.get(t);
89
+ if (provider === undefined) {
90
+ for (const parent of this.parents) {
91
+ const sp = { [t]: t };
92
+ const syn = parent.synthesize(sp, {});
93
+ const descriptor = Object.getOwnPropertyDescriptor(syn, t);
94
+ if (descriptor !== undefined) {
95
+ return descriptor;
96
+ }
97
+ }
98
+ return undefined;
99
+ }
98
100
  // The double nested gets are required for lazy loading the provider resolution
99
101
  if (typeof provider === "function") {
100
- // eslint-disable-next-line @typescript-eslint/no-this-alias
101
- const self = this;
102
102
  return {
103
- get [t]() {
103
+ get() {
104
104
  if (provider && typeof provider === "function") {
105
- return Promise.resolve(provider(self)).then((p) => {
106
- if (p) {
107
- return p[t];
108
- }
109
- });
105
+ return Promise.resolve(this[IFluidDependencySynthesizer_1.IFluidDependencySynthesizer])
106
+ .then(async (fds) => provider(fds))
107
+ .then((p) => p === null || p === void 0 ? void 0 : p[t]);
110
108
  }
111
109
  },
112
110
  };
113
111
  }
114
112
  return {
115
- get [t]() {
113
+ get() {
116
114
  if (provider) {
117
115
  return Promise.resolve(provider).then((p) => {
118
116
  if (p) {
@@ -1 +1 @@
1
- {"version":3,"file":"dependencyContainer.js","sourceRoot":"","sources":["../src/dependencyContainer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidObject } from \"@fluidframework/core-interfaces\";\n\nimport {\n AsyncFluidObjectProvider,\n FluidObjectSymbolProvider,\n FluidObjectProvider,\n FluidObjectKey,\n} from \"./types\";\nimport {\n IFluidDependencySynthesizer,\n} from \"./IFluidDependencySynthesizer\";\n\n/**\n * DependencyContainer is similar to a IoC Container. It takes providers and will\n * synthesize an object based on them when requested.\n */\nexport class DependencyContainer implements IFluidDependencySynthesizer {\n private readonly providers = new Map<keyof IFluidObject, FluidObjectProvider<any>>();\n\n public get IFluidDependencySynthesizer() { return this; }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).registeredTypes}\n */\n public get registeredTypes(): Iterable<(keyof IFluidObject)> {\n return this.providers.keys();\n }\n\n public constructor(public parent: IFluidDependencySynthesizer | undefined = undefined) { }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).register}\n */\n public register<T extends keyof IFluidObject>(type: T, provider: FluidObjectProvider<T>): void {\n if (this.has(type)) {\n throw new Error(`Attempting to register a provider of type ${type} that already exists`);\n }\n\n this.providers.set(type, provider);\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).unregister}\n */\n public unregister<T extends keyof IFluidObject>(type: T): void {\n if (this.providers.has(type)) {\n this.providers.delete(type);\n }\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).synthesize}\n */\n public synthesize<\n O extends IFluidObject,\n // eslint-disable-next-line @typescript-eslint/ban-types\n R extends IFluidObject = {}>(\n optionalTypes: FluidObjectSymbolProvider<O>,\n requiredTypes: FluidObjectSymbolProvider<R>,\n ): AsyncFluidObjectProvider<FluidObjectKey<O>, FluidObjectKey<R>> {\n const optionalValues = Object.values(optionalTypes);\n const requiredValues = Object.values(requiredTypes);\n\n // There was nothing passed in so we can return\n if (optionalValues === [] && requiredValues === []) {\n return {} as any;\n }\n\n const required = this.generateRequired<R>(requiredTypes);\n const optional = this.generateOptional<O>(optionalTypes);\n return { ...required, ...optional };\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).has}\n */\n public has(...types: (keyof IFluidObject)[]): boolean {\n return types.every((type) => {\n return this.providers.has(type);\n });\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).getProvider}\n */\n public getProvider<T extends keyof IFluidObject>(type: T): FluidObjectProvider<T> | undefined {\n // If we have the provider return it\n const provider = this.providers.get(type);\n if (provider) {\n return provider;\n }\n\n if (this.parent) {\n return this.parent.getProvider(type);\n }\n\n return undefined;\n }\n\n private generateRequired<T extends IFluidObject>(\n types: FluidObjectSymbolProvider<T>,\n ) {\n const values: (keyof IFluidObject)[] = Object.values(types);\n return Object.assign({}, ...Array.from(values, (t) => {\n const provider = this.getProvider(t);\n if (!provider) {\n throw new Error(`Object attempted to be created without registered required provider ${t}`);\n }\n\n return this.resolveProvider(provider, t);\n }));\n }\n\n private generateOptional<T extends IFluidObject>(\n types: FluidObjectSymbolProvider<T>,\n ) {\n const values: (keyof IFluidObject)[] = Object.values(types);\n return Object.assign({}, ...Array.from(values, (t) => {\n const provider = this.getProvider(t);\n if (!provider) {\n return { get [t]() { return Promise.resolve(undefined); } };\n }\n\n return this.resolveProvider(provider, t);\n }));\n }\n\n private resolveProvider<T extends keyof IFluidObject>(provider: FluidObjectProvider<T>, t: keyof IFluidObject) {\n // The double nested gets are required for lazy loading the provider resolution\n if (typeof provider === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return {\n get [t]() {\n if (provider && typeof provider === \"function\") {\n return Promise.resolve(provider(self)).then((p) => {\n if (p) {\n return p[t];\n }\n });\n }\n },\n };\n }\n\n return {\n get [t]() {\n if (provider) {\n return Promise.resolve(provider).then((p) => {\n if (p) {\n return p[t];\n }\n });\n }\n },\n };\n }\n}\n"]}
1
+ {"version":3,"file":"dependencyContainer.js","sourceRoot":"","sources":["../src/dependencyContainer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n AsyncFluidObjectProvider,\n FluidObjectSymbolProvider,\n FluidObjectProvider,\n AsyncOptionalFluidObjectProvider,\n AsyncRequiredFluidObjectProvider,\n} from \"./types\";\nimport {\n IFluidDependencySynthesizer,\n} from \"./IFluidDependencySynthesizer\";\n\n/**\n * DependencyContainer is similar to a IoC Container. It takes providers and will\n * synthesize an object based on them when requested.\n */\nexport class DependencyContainer<TMap> implements IFluidDependencySynthesizer {\n private readonly providers = new Map<keyof TMap, FluidObjectProvider<any>>();\n private readonly parents: IFluidDependencySynthesizer[];\n public get IFluidDependencySynthesizer() { return this; }\n\n public constructor(... parents: (IFluidDependencySynthesizer | undefined)[]) {\n this.parents = parents.filter((v): v is IFluidDependencySynthesizer => v !== undefined);\n }\n\n /**\n * Add a new provider\n * @param type - Name of the Type T being provided\n * @param provider - A provider that will resolve the T correctly when asked\n * @throws - If passing a type that's already registered\n */\n public register<T extends keyof TMap = keyof TMap>(type: T, provider: FluidObjectProvider<Pick<TMap, T>>): void {\n if (this.providers.has(type)) {\n throw new Error(`Attempting to register a provider of type ${type} that already exists`);\n }\n\n this.providers.set(type, provider);\n }\n\n /**\n * Remove a provider\n * @param type - Name of the provider to remove\n */\n public unregister(type: keyof TMap): void {\n if (this.providers.has(type)) {\n this.providers.delete(type);\n }\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).synthesize}\n */\n public synthesize<O, R = undefined | Record<string, never>>(\n optionalTypes: FluidObjectSymbolProvider<O>,\n requiredTypes: Required<FluidObjectSymbolProvider<R>>,\n ): AsyncFluidObjectProvider<O, R> {\n const base: AsyncFluidObjectProvider<O, R> = {} as any;\n this.generateRequired<R>(base, requiredTypes);\n this.generateOptional<O>(base, optionalTypes);\n Object.defineProperty(base, IFluidDependencySynthesizer, { get: () => this });\n return base;\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).has}\n * @param excludeParents - If true, exclude checking parent registries\n */\n public has(type: string, excludeParents?: boolean): boolean {\n if (this.providers.has(type as keyof TMap)) {\n return true;\n }\n if (excludeParents !== true) {\n return this.parents.some((p: IFluidDependencySynthesizer) => p.has(type));\n }\n return false;\n }\n\n private generateRequired<T>(\n base: AsyncRequiredFluidObjectProvider<T>,\n types: Required<FluidObjectSymbolProvider<T>>,\n ) {\n if(types === undefined) return;\n for(const key of Object.keys(types) as unknown as (keyof TMap)[]) {\n const provider = this.resolveProvider(key);\n if(provider === undefined) {\n throw new Error(`Object attempted to be created without registered required provider ${key}`);\n }\n Object.defineProperty(\n base,\n key,\n provider,\n );\n }\n }\n\n private generateOptional<T>(\n base: AsyncOptionalFluidObjectProvider<T>,\n types: FluidObjectSymbolProvider<T>,\n ) {\n if(types === undefined) return;\n for(const key of Object.keys(types) as unknown as (keyof TMap)[]) {\n // back-compat: in 0.56 we allow undefined in the types, but we didn't before\n // this will keep runtime back compat, eventually we should support undefined properties\n // rather than properties that return promises that resolve to undefined\n const provider = this.resolveProvider(key) ?? {get:()=>Promise.resolve(undefined)};\n Object.defineProperty(\n base,\n key,\n provider,\n );\n }\n }\n\n private resolveProvider<T extends keyof TMap>(t: T): PropertyDescriptor | undefined {\n // If we have the provider return it\n const provider = this.providers.get(t);\n if (provider === undefined) {\n for(const parent of this.parents) {\n const sp = { [t]: t } as FluidObjectSymbolProvider<Pick<TMap, T>>;\n const syn = parent.synthesize<Pick<TMap, T>,{}>(\n sp,\n {});\n const descriptor = Object.getOwnPropertyDescriptor(syn, t);\n if (descriptor !== undefined) {\n return descriptor;\n }\n }\n return undefined;\n }\n\n // The double nested gets are required for lazy loading the provider resolution\n if (typeof provider === \"function\") {\n return {\n get() {\n if (provider && typeof provider === \"function\") {\n return Promise.resolve(this[IFluidDependencySynthesizer])\n .then(async (fds): Promise<any> => provider(fds))\n .then((p) => p?.[t]);\n }\n },\n };\n }\n return {\n get() {\n if (provider) {\n return Promise.resolve(provider).then((p) => {\n if (p) {\n return p[t];\n }\n });\n }\n },\n };\n }\n}\n"]}