scontainers
Version:
A container/collection/iterator library for JavaScript, comfortable to use, performant and versatile.
145 lines (115 loc) • 3.39 kB
JavaScript
;
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 {
traits
} = require('../utils.js');
_testTraitSet(traits.utils);
_testTraitSet(traits.scontainers);
_testTraitSet(traits.semantics);
const _nth = _getSymbol("nth", traits.utils, traits.scontainers, traits.semantics);
const _get = _getSymbol("get", traits.utils, traits.scontainers, traits.semantics);
const _hasKey = _getSymbol("hasKey", traits.utils, traits.scontainers, traits.semantics);
const _kvIterator = _getSymbol("kvIterator", traits.utils, traits.scontainers, traits.semantics);
const _reverse = _getSymbol("reverse", traits.utils, traits.scontainers, traits.semantics);
const _cow = _getSymbol("cow", traits.utils, traits.scontainers, traits.semantics);
/*
TODO: decide how to do this thing...
How about... `Cow` takes a Type as a parameter
and instantiates a variable of that type when it needs to copy :F
by default it's map \o,o/
Yes, it's a good idea, buuut...
`CopyType` needs to be part of the `ParentCollection`, because stuff like `add` needs to depend on it.
So, maybe `CopyType` dynamically gets a new Collection? not sure \o,o/
*/
module.exports = function (ParentCollection) {
const parentProto = ParentCollection.prototype;
return function () {
return class Cow {
constructor(coll, CopyType = Map) {
this.wrapped = coll;
this.copy = null;
this.CopyType = CopyType;
}
nth() {
if (parentProto[_nth]) {
return function nth(n) {
return this.wrapped[_nth](n);
};
}
}
setNth() {
if (parentProto[_nth]) {
return function setNth(n, value) {
global.TODO();
};
}
}
get() {
if (parentProto[_get]) {
return function get(key) {
return this.wrapped[_get](key);
};
}
}
set() {
if (parentProto[_get]) {
return function set(key, value) {
global.TODO();
};
}
}
hasKey() {
if (parentProto[_hasKey]) {
return function hasKey(key) {
return this.wrapped[_hasKey](key);
};
}
}
/* TODO
add() {
if( this.
}
*/
kvIterator() {
return function kvIterator() {
return this.wrapped[_kvIterator]();
};
}
reverse() {
if (parentProto[_reverse]) {
return this.wrapped[_reverse]()[_cow]();
}
}
toString() {
return `${this.wrapped}.cow()`;
}
};
};
};