UNPKG

runtime-branding

Version:
95 lines 2.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const brand = Symbol(); // TODO: do we need a global branding map? /** * Creates a new brand, identified by the provided branding object. * * @param brandObject An object that represents the brand. The shape of this object should be unique, and symbols may be used as unique keys. * @param callback An optional callback with variable arguments which is invoked during object branding */ function createBranding(brandObject, callback) { const brandedObjects = new WeakSet(); function has(obj) { return brandedObjects.has(obj); } function assert(obj) { if (!brandedObjects.has(obj)) { throw new Error("Object not branded."); } } function branding(obj) { if (has(obj)) { throw new Error("Object already branded."); } brandedObjects.add(obj); if (callback) { try { callback(obj, brandObject); } catch (e) { brandedObjects.delete(obj); throw e; } } return obj; } function refine(newBrand, newCallback) { const b = Object.assign({}, newBrand, brandObject); const refinedBranding = createBranding(b, newCallback); return merge(refinedBranding); } function merge(branding1) { return mixin(branding, branding1); } function generic() { return branding; } branding.has = has; // TODO: maybe all these should be built separately, then Object.assigned to branding() branding.assert = assert; branding.refine = refine; branding.merge = merge; branding.generic = generic; branding[brand] = brandObject; return branding; } exports.createBranding = createBranding; /** * Mixes two different brandings in a single one. * * @param fn1 The first branding function * @param fn2 The second branding function */ function mixin(fn1, fn2) { function has(obj) { return fn1.has(obj) && fn2.has(obj); } function assert(obj) { fn1.assert(obj); fn2.assert(obj); } function branding(obj) { fn1(obj); fn2(obj); return obj; } function refine(newBrand, callback) { const b = Object.assign({}, newBrand, fn1[brand], fn2[brand]); return createBranding(b, callback); } function merge(branding1) { return mixin(branding, branding1); } function generic() { return branding; } const newBrand = Object.assign({}, fn1[brand], fn2[brand]); branding.has = has; branding.assert = assert; branding.refine = refine; branding.merge = merge; branding.generic = generic; branding[brand] = newBrand; return branding; } //# sourceMappingURL=index.js.map