deat
Version:
Model and manage your runtime feature-oriented dependencies
206 lines (204 loc) • 5.52 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
// src/index.ts
import { v4 as uuid } from "uuid";
var Deat = class _Deat {
constructor(deps, build) {
this.build = build;
this.build = build;
this.key = uuid();
this.headerKey = this.key;
this.keys = /* @__PURE__ */ new Set([this.key]);
this.next = null;
this.isHeader = true;
this.deps = deps;
this.prefixedDeps = _Deat.setPrefixForDeps(deps, this.headerKey);
}
static create(deps, build, peer) {
return new _Deat(deps, build);
}
static genPrefixForDeps(headerKey, key) {
return `${headerKey}-${key}`;
}
static setPrefixForDeps(deps, headerKey) {
const res = {};
Object.keys(deps).forEach((key) => {
res[_Deat.genPrefixForDeps(headerKey, key)] = deps[key];
});
return res;
}
static removePrefixForDeps(deps) {
const res = {};
Object.keys(deps).forEach((key) => {
res[key.split("-").at(-1)] = deps[key];
});
return res;
}
static updatePrefixForDeps(deps, prefix) {
const res = {};
Object.keys(deps).forEach((key) => {
res[prefix + "-" + key.split("-").at(-1)] = deps[key];
});
return res;
}
static getIsolatedDeps(deps, headerKey) {
return new Proxy(
deps,
{
get(target, p) {
return target[_Deat.genPrefixForDeps(headerKey, p)];
}
}
);
}
copy(headerKey) {
function copyNode(node) {
const copy = _Deat.create(node.deps, node.build);
copy.key = node.key;
copy.headerKey = node.headerKey;
copy.keys = new Set(node.keys);
copy.isHeader = node.isHeader;
copy.prefixedDeps = __spreadValues({}, node.prefixedDeps);
if (node.next) {
copy.next = copyNode(node.next);
}
if (headerKey) {
copy.headerKey = headerKey;
copy.prefixedDeps = _Deat.updatePrefixForDeps(copy.prefixedDeps, headerKey);
}
return copy;
}
return copyNode(this);
}
getDuplicates(target) {
this.validateHeader();
target.validateHeader();
const duplicates = [];
this.keys.forEach((key) => {
if (target.keys.has(key)) {
duplicates.push(key);
}
});
return duplicates;
}
validateHeader() {
if (!this.isHeader) {
throw new Error(`Only list header can execute chain method, but node ${this.key} is not the header`);
}
}
tail() {
let tail = this;
while (tail.next) {
tail = tail.next;
}
return tail;
}
getNodeByKey(key) {
let node = this;
while (node) {
if (node.key === key) {
return node;
}
node = node.next;
}
throw new Error(`Unable to get node with key "${key}"`);
}
_inspect() {
let curr = this;
while (curr) {
console.log(curr);
curr = curr.next;
}
}
_chain(deat, merge = true) {
this.validateHeader();
deat.validateHeader();
const copy = this.copy();
const tail = copy.tail();
const head = deat.copy(copy.key);
if (merge) {
head.isHeader = false;
head.keys = null;
}
tail.next = head;
deat.keys.forEach((key) => copy.keys.add(key));
return copy;
}
chain(deat) {
return this._chain(deat);
}
append(deps, build) {
return this.chain(_Deat.create(deps, build));
}
appendDeps(deps) {
return this.chain(_Deat.create(deps, () => ({})));
}
appendBuilder(build) {
return this.chain(_Deat.create({}, build));
}
// Merge two isolated deat instances into one chain. There are no interference between each other.
union(deat) {
const dups = this.getDuplicates(deat);
if (dups.length === 0) {
return this._chain(deat, false);
}
const copy = this.copy();
let prev = copy;
let inserted = deat.copy();
let dupIndex = 0;
while (inserted) {
copy.keys.add(inserted.key);
if (dups[dupIndex] === inserted.key) {
prev = prev.getNodeByKey(dups[dupIndex]);
dupIndex += 1;
inserted = inserted.next;
continue;
}
const next = prev.next;
prev.next = inserted;
inserted = inserted.next;
prev.next.next = next;
prev = prev.next;
}
return copy;
}
update(key, value) {
const copy = this.copy();
let node = copy;
while (node) {
if (node.deps[key]) {
node.deps[key] = value;
node.prefixedDeps[node.headerKey + "-" + key] = value;
}
node = node.next;
}
return copy;
}
run() {
let result = this.prefixedDeps;
let node = this;
while (node) {
const deps = node.prefixedDeps;
result = __spreadValues(__spreadValues(__spreadValues({}, result), deps), _Deat.setPrefixForDeps(node.build(_Deat.getIsolatedDeps(result, node.headerKey)), node.headerKey));
node = node.next;
}
return _Deat.removePrefixForDeps(result);
}
};
export {
Deat
};