UNPKG

scontainers

Version:

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

149 lines (109 loc) 3.64 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 { assert, traits, semantics, toStr, id, KVN } = require('../utils.js'); _testTraitSet(traits.utils); _testTraitSet(traits.scontainers); _testTraitSet(traits.semantics); const _describeScontainer = _getSymbol("describeScontainer", traits.utils, traits.scontainers, traits.semantics); const _implCoreGenerators = _getSymbol("implCoreGenerators", traits.utils, traits.scontainers, traits.semantics); const _member = _getSymbol("member", traits.utils, traits.scontainers, traits.semantics); const _call = _getSymbol("call", traits.utils, traits.scontainers, traits.semantics); const _forIn = _getSymbol("forIn", traits.utils, traits.scontainers, traits.semantics); const _if = _getSymbol("if", traits.utils, traits.scontainers, traits.semantics); const _hasKey = _getSymbol("hasKey", traits.utils, traits.scontainers, traits.semantics); const _implCoreTraits = _getSymbol("implCoreTraits", traits.utils, traits.scontainers, traits.semantics); module.exports = function (ParentCollection) { assert(ParentCollection === Object, `ObjectOwnProperties is only needed by Object...`); return function () { class OwnProperties { static get name() { return `ObjectOwnProperties`; } constructor(coll) { this.object = coll; } toString() { var _context; return `${(_context = this.object, toStr).call(_context)}::ownProperties()`; } } OwnProperties[_describeScontainer]({ argKeys: [id`object`] }); OwnProperties[_implCoreGenerators]({ getUnchecked(key) { return this.args.object[_member](key, true); }, hasKey(key) { return this.args.object[_member](`hasOwnProperty`)[_call](key); }, loop() { const key = this.createUniqueVariable(`key`); this.body[_forIn](semantics.declare(key, undefined, `var`), this.args.object, semantics.block()[_if](this[_hasKey](key), this.body = semantics.block())); return new KVN(key, this.args.object[_member](key, true)); } }); OwnProperties[_implCoreTraits]({ getUnchecked(key) { return this.object[key]; }, hasKey(key) { return this.object.hasOwnProperty(key); }, // set( key, value ) { this.object[key] = value; },}, *iterator() { for (let key in this.object) { if (this[_hasKey](key)) { yield [key, this.object[key]]; } } }, kvIterator() { return { it: this[Symbol.iterator](), next() { const next = this.it.next(); if (!next.done) { return new KVN(next.value[0], next.value[1]); } } }; } }); return OwnProperties; }; };