@abextm/cache2
Version:
Utilities for reading OSRS "caches"
115 lines (114 loc) • 3.28 kB
JavaScript
export function Typed(v, _ctx) {
return v;
}
(function (Typed) {
Typed.type = Symbol("type");
Typed.wrapped = Symbol("wrapped");
function mergeType(a, b) {
if (!a || !b) {
return a ?? b;
}
if (a.type !== b.type) {
return b;
}
if (a.type === "obj" && b.type == "obj") {
let entries = {
...a.entries,
};
for (let [k, v] of Object.entries(b.entries)) {
if (k in entries) {
entries[k] = mergeType(entries[k], v);
}
else {
entries[k] = v;
}
}
return {
type: a.type,
entries,
defaultEntry: mergeType(a.defaultEntry, b.defaultEntry),
default: b.default ?? a.default,
};
}
return {
...a,
...b,
};
}
function withType(type, v) {
if (!type) {
return v;
}
let onto;
if (typeof v === "function") {
onto = v.prototype;
}
else if (typeof v === "object" && v) {
onto = v;
}
else {
onto = v = {
[Typed.wrapped]: true,
v,
};
}
if (!Object.hasOwn(onto, Typed.type)) {
if (typeof type === "function" || Typed.type in onto) {
let typefn = typeof type === "function" ? type : () => type;
let value;
Object.defineProperty(onto, Typed.type, {
enumerable: false,
get() {
if (value) {
return value;
}
let superType = Object.getPrototypeOf(this)?.[Typed.type];
value = typefn();
if (superType) {
value = mergeType(superType, value);
}
return value;
},
});
}
else {
Object.defineProperty(onto, Typed.type, {
enumerable: false,
value: type,
});
}
}
return v;
}
Typed.withType = withType;
function getType(v) {
return v[Typed.type];
}
Typed.getType = getType;
// injected value wrapper for c2.Typed(value) calls
/** @internal */
function d(type) {
return (v) => withType(type, v);
}
Typed.d = d;
// injected value wrapper for typedCall
/** @internal */
function v(type, value) {
return withType(type, value);
}
Typed.v = v;
// injected value wrapper for typedCall with a spread argument
/** @internal */
function s(type, value) {
if (type?.type === "list") {
return value.map(v => withType(type.entries, v));
}
else if (type?.type === "tuple") {
return value.map((v, i) => withType(type.entries[i], v));
}
else {
return value;
}
}
Typed.s = s;
})(Typed || (Typed = {}));