UNPKG

scontainers

Version:

A container/collection/iterator library for JavaScript, comfortable to use, performant and versatile.

120 lines (89 loc) 3.04 kB
"use strict"; function _implSymbol(target, sym, value) { Object.defineProperty(target, sym, { value, configurable: true }); return target[sym]; } function _getSymbol(targetSymName, ...traitSets) { let symbol; traitSets.forEach(traitSet => { const sym = traitSet[targetSymName]; if (typeof sym === 'symbol') { if (!!symbol && symbol !== sym) { throw new Error(`Symbol ${targetSymName} offered by multiple trait sets.`); } symbol = sym; } }); if (!symbol) { throw new Error(`No trait set is providing symbol ${targetSymName}.`); } return symbol; } function _testTraitSet(traitSet) { if (!traitSet || typeof traitSet === 'boolean' || typeof traitSet === 'number' || typeof traitSet === 'string') { throw new Error(`${traitSet} cannot be used as a trait set.`); } } const straits = require('straits'); const semanticTraits = require('esast/dist/semantics.js'); const descriptorTraits = require('./traits/descriptor.js'); const generatorTraits = require('./traits/generators.js'); const scontainerTraits = require('./traits/scontainers.js'); const utilTraits = require('./traits/utils.js'); const { ReorderedIterator } = require('./reordered_iterator.js'); const utilsLight = require('./utils_light.js'); const { assert } = utilsLight; _testTraitSet(utilTraits); _testTraitSet(scontainerTraits); const _asMethod = _getSymbol("asMethod", utilTraits, scontainerTraits); const _addTraitFactories = _getSymbol("addTraitFactories", utilTraits, scontainerTraits); const _wrapScontainer = _getSymbol("wrapScontainer", utilTraits, scontainerTraits); const _implScontainer = _getSymbol("implScontainer", utilTraits, scontainerTraits); const utils = { ReorderedIterator, traits: { descriptors: descriptorTraits, generators: generatorTraits, scontainers: scontainerTraits, utils: utilTraits, semantics: semanticTraits }, toStr: straits.common.toString[_asMethod]() }; Object.assign(utils, utilsLight); // implementing util traits { _implSymbol(Object.prototype, _implScontainer, function (implementationObj) { const factoryObj = {}; for (let key in implementationObj) { factoryObj[key] = function () { return implementationObj[key]; }; } // return scontainerTraits._Straits.addTrait( this, implementationObj ); return scontainerTraits[_addTraitFactories](this, factoryObj); }); _implSymbol(Object.prototype, _wrapScontainer, function (decoratorFactoryFactory) { const Container = this; const decoratorFactory = decoratorFactoryFactory(Container); if (!decoratorFactory) { // this decorator can't be implemented on `Type` return; } return { factory() { const Decorator = decoratorFactory(Container); assert(typeof Decorator === 'function', `${decoratorFactory.name} is broken.`); return function (...args) { return new Decorator(this, ...args); }; } }; }); } module.exports = utils;