{"version":3,"file":"TypeUuid.js","sourceRoot":"","sources":["../src/TypeUuid.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,mDAAgD;AAEhD,MAAM,wBAAwB,GAAW,MAAM,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAa,QAAQ;IAGnB;;;;OAIG;IACH,8DAA8D;IACvD,MAAM,CAAC,aAAa,CAAC,WAAgB,EAAE,QAAgB;QAC5D,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,0EAA0E,QAAQ,GAAG,CAAC,CAAC;QACzG,CAAC;QAED,8DAA8D;QAC9D,MAAM,oBAAoB,GAAQ,WAAW,CAAC,SAAS,CAAC;QAExD,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,EAAE,CAAC;YAC/E,MAAM,YAAY,GAAW,oBAAoB,CAAC,wBAAwB,CAAC,CAAC;YAC5E,MAAM,IAAI,6BAAa,CACrB,oCAAoC,WAAW,CAAC,IAAI,IAAI,EAAE,aAAa,QAAQ,EAAE;gBAC/E,oDAAoD,YAAY,EAAE,CACrE,CAAC;QACJ,CAAC;QACD,oBAAoB,CAAC,wBAAwB,CAAC,GAAG,QAAQ,CAAC;IAC5D,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,YAAY,CAAC,YAAqB,EAAE,QAAgB;QAChE,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YACxD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,eAAe,GAAO,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAC9D,OAAO,eAAe,KAAK,SAAS,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YACjE,8DAA8D;YAC9D,MAAM,cAAc,GAAY,eAAuB,CAAC,wBAAwB,CAAC,CAAC;YAClF,IAAI,cAAc,KAAK,QAAQ,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,gDAAgD;YAChD,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;;AApDH,4BAqDC;AApDgB,oBAAW,GAAW,gEAAgE,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { InternalError } from './InternalError';\n\nconst classPrototypeUuidSymbol: symbol = Symbol.for('TypeUuid.classPrototypeUuid');\n\n/**\n * Provides a version-independent implementation of the JavaScript `instanceof` operator.\n *\n * @remarks\n * The JavaScript `instanceof` operator normally only identifies objects from a particular library instance.\n * For example, suppose the NPM package `example-lib` has two published versions 1.2.0 and 1.3.0, and\n * it exports a class called `A`. Suppose some code consumes version `1.3.0` of the library, but it receives\n * an object that was constructed using version `1.2.0`. In this situation `a instanceof A` will return `false`,\n * even though `a` is an instance of `A`. The reason is that there are two prototypes for `A`; one for each\n * version.\n *\n * The `TypeUuid` facility provides a way to make `a instanceof A` return true for both prototypes of `A`,\n * by instead using a universally unique identifier (UUID) to detect object instances.\n *\n * You can use `Symbol.hasInstance` to enable the system `instanceof` operator to recognize type UUID equivalence:\n * ```ts\n * const uuidWidget: string = '9c340ef0-d29f-4e2e-a09f-42bacc59024b';\n * class Widget {\n * public static [Symbol.hasInstance](instance: object): boolean {\n * return TypeUuid.isInstanceOf(instance, uuidWidget);\n * }\n * }\n * ```\n * // Example usage:\n * ```ts\n * import { Widget as Widget1 } from 'v1-of-library';\n * import { Widget as Widget2 } from 'v2-of-library';\n * const widget = new Widget2();\n * console.log(widget instanceof Widget1); // prints true\n * ```\n *\n * @public\n */\nexport class TypeUuid {\n private static _uuidRegExp: RegExp = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;\n\n /**\n * Registers a JavaScript class as having a type identified by the specified UUID.\n * @privateRemarks\n * We cannot use a construct signature for `targetClass` because it may be an abstract class.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public static registerClass(targetClass: any, typeUuid: string): void {\n if (typeof targetClass !== 'function') {\n throw new Error('The targetClass parameter must be a JavaScript class');\n }\n\n if (!TypeUuid._uuidRegExp.test(typeUuid)) {\n throw new Error(`The type UUID must be specified as lowercase hexadecimal with dashes: \"${typeUuid}\"`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const targetClassPrototype: any = targetClass.prototype;\n\n if (Object.hasOwnProperty.call(targetClassPrototype, classPrototypeUuidSymbol)) {\n const existingUuid: string = targetClassPrototype[classPrototypeUuidSymbol];\n throw new InternalError(\n `Cannot register the target class ${targetClass.name || ''} typeUuid=${typeUuid}` +\n ` because it was already registered with typeUuid=${existingUuid}`\n );\n }\n targetClassPrototype[classPrototypeUuidSymbol] = typeUuid;\n }\n\n /**\n * Returns true if the `targetObject` is an instance of a JavaScript class that was previously\n * registered using the specified `typeUuid`. Base classes are also considered.\n */\n public static isInstanceOf(targetObject: unknown, typeUuid: string): boolean {\n if (targetObject === undefined || targetObject === null) {\n return false;\n }\n\n let objectPrototype: {} = Object.getPrototypeOf(targetObject);\n while (objectPrototype !== undefined && objectPrototype !== null) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const registeredUuid: string = (objectPrototype as any)[classPrototypeUuidSymbol];\n if (registeredUuid === typeUuid) {\n return true;\n }\n // Walk upwards an examine base class prototypes\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return false;\n }\n}\n"]}