Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/modules-modules / observable-utils / registryWeakMap.ts
Size: Mime:
import { isString, isNumber, isObjOrFunction } from 'exotic'

export type Class<Type> = { new (...args: any[]): Type }
export type _InstanceOf<Klass> = { [Key in keyof Klass]: [Klass[Key]] }
export type WithPrototype<Klass> = { prototype: Klass }
export type InstanceOf<Klass> = WithPrototype<Klass> &
  _InstanceOf<Klass> &
  Class<never>

/**
 * @description registry of references to have 1 per container
 *              POC here before moving to a standardized approach
 *              for multi-container architecture
 */
const referenceList = new WeakMap()

/**
 * @description could use object pooling here too
 * @todo curry1
 * @todo use ./decorateWithIdentity for INSTANCE scoping + CLASS scoping
 *
 * @param Klass class to instantiate
 * @param Target use to set as reference
 *
 * @return instantiated class
 */
function getInstance<ClassType = Class<any>>(
  Klass: ClassType & Class<any>,
  Target: ClassType & Class<any>
): InstanceOf<ClassType> {
  if (referenceList.has(Target) === false) {
    const instance = new Klass()
    instance.isMultiContainer = true
    referenceList.set(Target, instance)
  }
  return referenceList.get(Target)
}

/**
 * @see getInstance (this is the opposite of that)
 *
 * !!!!
 * @todo USE IDENTIFIER + GETINSTANCE FN TO CROSS-CHECK AND BE ABLE TO KEEP FLAT CONTAINERS
 *
 * @alias getScoped
 * @param Klass could get Klass from Object.getPrototypeOf(klassInstance)?
 *                  like get pooled?
 * @return instanceof Klass
 */
function useInstanceOrBuildScoped<ClassType = Class<any>>(
  scopedInstance: InstanceOf<ClassType>,
  klassInstance: InstanceOf<ClassType> | undefined,
  Klass: ClassType & Class<any>
): ClassType {
  if (referenceList.has(scopedInstance) === false) {
    const instance = new Klass()
    // instance.scoped = true
    referenceList.set(scopedInstance, instance)
  }
  return referenceList.get(scopedInstance)
}

const registry = {
  get: getInstance,
  registry: referenceList,
}

export { getInstance, referenceList }
export { registry }
export { registry as registryWeakMap }
export { useInstanceOrBuildScoped }
export { useInstanceOrBuildScoped as getScoped }
export default registry