{"version":3,"file":"index.cjs.js","sources":["../src/component.ts","../src/constants.ts","../src/provider.ts","../src/component_container.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from '@firebase/util';\nimport { ComponentContainer } from './component_container';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { InstantiationMode, Name, NameServiceMapping } from './types';\nimport { Component } from './component';\n\n/**\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\n * NameServiceMapping[T] is an alias for the type of the instance\n */\nexport class Provider {\n private component: Component | null = null;\n private readonly instances: Map = new Map();\n private readonly instancesDeferred: Map<\n string,\n Deferred\n > = new Map();\n\n constructor(\n private readonly name: T,\n private readonly container: ComponentContainer\n ) {}\n\n /**\n * @param identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n */\n get(identifier: string = DEFAULT_ENTRY_NAME): Promise {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\n const deferred = new Deferred();\n this.instancesDeferred.set(normalizedIdentifier, deferred);\n // If the service instance is available, resolve the promise with it immediately\n try {\n const instance = this.getOrInitializeService(normalizedIdentifier);\n if (instance) {\n deferred.resolve(instance);\n }\n } catch (e) {\n // when the instance factory throws an exception during get(), it should not cause\n // a fatal error. We just return the unresolved promise in this case.\n }\n }\n\n return this.instancesDeferred.get(normalizedIdentifier)!.promise;\n }\n\n /**\n *\n * @param options.identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n * @param options.optional If optional is false or not provided, the method throws an error when\n * the service is not immediately available.\n * If optional is true, the method returns null if the service is not immediately available.\n */\n getImmediate(options: {\n identifier?: string;\n optional: true;\n }): NameServiceMapping[T] | null;\n getImmediate(options?: {\n identifier?: string;\n optional?: false;\n }): NameServiceMapping[T];\n getImmediate(options?: {\n identifier?: string;\n optional?: boolean;\n }): NameServiceMapping[T] | null {\n const { identifier, optional } = {\n identifier: DEFAULT_ENTRY_NAME,\n optional: false,\n ...options\n };\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n try {\n const instance = this.getOrInitializeService(normalizedIdentifier);\n\n if (!instance) {\n if (optional) {\n return null;\n }\n throw Error(`Service ${this.name} is not available`);\n }\n return instance;\n } catch (e) {\n if (optional) {\n return null;\n } else {\n throw e;\n }\n }\n }\n\n getComponent(): Component | null {\n return this.component;\n }\n\n setComponent(component: Component): void {\n if (component.name !== this.name) {\n throw Error(\n `Mismatching Component ${component.name} for Provider ${this.name}.`\n );\n }\n\n if (this.component) {\n throw Error(`Component for ${this.name} has already been provided`);\n }\n\n this.component = component;\n // if the service is eager, initialize the default instance\n if (isComponentEager(component)) {\n try {\n this.getOrInitializeService(DEFAULT_ENTRY_NAME);\n } catch (e) {\n // when the instance factory for an eager Component throws an exception during the eager\n // initialization, it should not cause a fatal error.\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\n // a fatal error in this case?\n }\n }\n\n // Create service instances for the pending promises and resolve them\n // NOTE: if this.multipleInstances is false, only the default instance will be created\n // and all promises with resolve with it regardless of the identifier.\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n instanceIdentifier\n );\n\n try {\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\n const instance = this.getOrInitializeService(normalizedIdentifier)!;\n instanceDeferred.resolve(instance);\n } catch (e) {\n // when the instance factory throws an exception, it should not cause\n // a fatal error. We just leave the promise unresolved.\n }\n }\n }\n\n clearInstance(identifier: string = DEFAULT_ENTRY_NAME): void {\n this.instancesDeferred.delete(identifier);\n this.instances.delete(identifier);\n }\n\n // app.delete() will call this method on every provider to delete the services\n // TODO: should we mark the provider as deleted?\n async delete(): Promise {\n const services = Array.from(this.instances.values());\n\n await Promise.all(\n services\n .filter(service => 'INTERNAL' in service)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any).INTERNAL!.delete())\n );\n }\n\n isComponentSet(): boolean {\n return this.component != null;\n }\n\n private getOrInitializeService(\n identifier: string\n ): NameServiceMapping[T] | null {\n let instance = this.instances.get(identifier);\n if (!instance && this.component) {\n instance = this.component.instanceFactory(\n this.container,\n normalizeIdentifierForFactory(identifier)\n ) as NameServiceMapping[T];\n this.instances.set(identifier, instance);\n }\n\n return instance || null;\n }\n\n private normalizeInstanceIdentifier(identifier: string): string {\n if (this.component) {\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\n } else {\n return identifier; // assume multiple instances are supported before the component is provided.\n }\n }\n}\n\n// undefined should be passed to the service factory for the default instance\nfunction normalizeIdentifierForFactory(identifier: string): string | undefined {\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\n}\n\nfunction isComponentEager(component: Component): boolean {\n return component.instantiationMode === InstantiationMode.EAGER;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Provider } from './provider';\nimport { Component } from './component';\nimport { Name } from './types';\n\n/**\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\n */\nexport class ComponentContainer {\n private readonly providers = new Map>();\n\n constructor(private readonly name: string) {}\n\n /**\n *\n * @param component Component being added\n * @param overwrite When a component with the same name has already been registered,\n * if overwrite is true: overwrite the existing component with the new component and create a new\n * provider with the new component. It can be useful in tests where you want to use different mocks\n * for different tests.\n * if overwrite is false: throw an exception\n */\n addComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n throw new Error(\n `Component ${component.name} has already been registered with ${this.name}`\n );\n }\n\n provider.setComponent(component);\n }\n\n addOrOverwriteComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n // delete the existing provider from the container, so we can register the new component\n this.providers.delete(component.name);\n }\n\n this.addComponent(component);\n }\n\n /**\n * getProvider provides a type safe interface where it can only be called with a field name\n * present in NameServiceMapping interface.\n *\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\n * themselves.\n */\n getProvider(name: T): Provider {\n if (this.providers.has(name)) {\n return this.providers.get(name) as Provider;\n }\n\n // create a Provider for a service that hasn't registered with Firebase\n const provider = new Provider(name, this);\n this.providers.set(name, provider);\n\n return provider as Provider;\n }\n\n getProviders(): Array> {\n return Array.from(this.providers.values());\n }\n}\n"],"names":["Deferred","__values"],"mappings":"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"}