@antischematic/angular-state-library
Version:
Reactive state without boilerplate
84 lines • 10.6 kB
JavaScript
const cache = new WeakMap();
const proxies = new WeakMap();
let deps = [];
export function pushStack(value) {
deps.unshift(value);
}
export function popStack() {
deps.shift();
}
function isTracking() {
return deps.length > 0;
}
export const changesMap = new WeakMap();
export function getChanges(deps) {
const changes = changesMap.get(deps) ?? new Map();
changesMap.set(deps, changes);
return changes;
}
export function addDep(object, key, value, previous = value, update = false) {
if (isTracking()) {
let seen = false;
for (const dep of deps) {
const keyValues = dep.get(object) ?? new Map;
dep.set(object, keyValues);
if (!seen && update && !Object.is(value, previous)) {
seen = true;
const changes = getChanges(dep);
const change = changes.get(object) ?? new Map();
changes.set(object, change);
if (!change.has(key)) {
change.set(key, untrack(previous));
}
}
if (update && keyValues.has(key) || !update) {
keyValues.set(key, value);
}
}
}
}
function createObjectProxy(object) {
return new Proxy(object, {
get(target, p) {
const value = Reflect.get(target, p);
addDep(target, p, value);
return value;
},
set(target, p, value, receiver) {
const previous = Reflect.get(target, p);
const result = Reflect.set(target, p, value, receiver);
addDep(target, p, value, previous, true);
return result;
},
deleteProperty(target, p) {
const previous = Reflect.get(target, p);
const result = Reflect.deleteProperty(target, p);
addDep(target, p, void 0, previous, true);
return result;
}
});
}
export function createProxy(object) {
if (!isObject(object))
return object;
if (cache.has(object)) {
return cache.get(object);
}
const proxy = createObjectProxy(object);
cache.set(object, proxy);
proxies.set(proxy, object);
return proxy;
}
export function isTracked(object) {
return proxies.has(object);
}
function isObject(value) {
return typeof value === "object" && value !== null;
}
export function track(object) {
return isObject(object) && !isTracked(object) ? createProxy(object) : object;
}
export function untrack(object) {
return proxies.get(object) ?? object;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9wcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLEtBQUssR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO0FBQzNCLE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFFN0IsSUFBSSxJQUFJLEdBQThCLEVBQUUsQ0FBQTtBQUV4QyxNQUFNLFVBQVUsU0FBUyxDQUFDLEtBQW9CO0lBQzNDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDdEIsQ0FBQztBQUVELE1BQU0sVUFBVSxRQUFRO0lBQ3JCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtBQUNmLENBQUM7QUFFRCxTQUFTLFVBQVU7SUFDaEIsT0FBTyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQTtBQUN6QixDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFFdkMsTUFBTSxVQUFVLFVBQVUsQ0FBQyxJQUFZO0lBQ3BDLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUNqRCxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUM3QixPQUFPLE9BQU8sQ0FBQTtBQUNqQixDQUFDO0FBRUQsTUFBTSxVQUFVLE1BQU0sQ0FBQyxNQUFjLEVBQUUsR0FBZ0IsRUFBRSxLQUFVLEVBQUUsV0FBZ0IsS0FBSyxFQUFFLE1BQU0sR0FBRyxLQUFLO0lBQ3ZHLElBQUksVUFBVSxFQUFFLEVBQUU7UUFDZixJQUFJLElBQUksR0FBRyxLQUFLLENBQUE7UUFDaEIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUU7WUFDckIsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLEdBQUcs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LENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQzFCLE9BQU8sS0FBSyxDQUFBO0FBQ2YsQ0FBQztBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsTUFBVztJQUNsQyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUE7QUFDN0IsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFDLEtBQVU7SUFDekIsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQTtBQUNyRCxDQUFDO0FBRUQsTUFBTSxVQUFVLEtBQUssQ0FBSSxNQUFTO0lBQy9CLE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQTtBQUN0RixDQUFDO0FBRUQsTUFBTSxVQUFVLE9BQU8sQ0FBSSxNQUFTO0lBQ2pDLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFhLENBQUMsSUFBSSxNQUFNLENBQUE7QUFDOUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RGVwTWFwfSBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5cbmNvbnN0IGNhY2hlID0gbmV3IFdlYWtNYXAoKVxuY29uc3QgcHJveGllcyA9IG5ldyBXZWFrTWFwKClcblxubGV0IGRlcHM6IE1hcDxhbnksIE1hcDxhbnksIGFueT4+W10gPSBbXVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaFN0YWNrKHZhbHVlOiBNYXA8YW55LCBhbnk+KSB7XG4gICBkZXBzLnVuc2hpZnQodmFsdWUpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwb3BTdGFjaygpIHtcbiAgIGRlcHMuc2hpZnQoKVxufVxuXG5mdW5jdGlvbiBpc1RyYWNraW5nKCkge1xuICAgcmV0dXJuIGRlcHMubGVuZ3RoID4gMFxufVxuXG5leHBvcnQgY29uc3QgY2hhbmdlc01hcCA9IG5ldyBXZWFrTWFwKClcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5nZXMoZGVwczogRGVwTWFwKSB7XG4gICBjb25zdCBjaGFuZ2VzID0gY2hhbmdlc01hcC5nZXQoZGVwcykgPz8gbmV3IE1hcCgpXG4gICBjaGFuZ2VzTWFwLnNldChkZXBzLCBjaGFuZ2VzKVxuICAgcmV0dXJuIGNoYW5nZXNcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZERlcChvYmplY3Q6IG9iamVjdCwga2V5OiBQcm9wZXJ0eUtleSwgdmFsdWU6IGFueSwgcHJldmlvdXM6IGFueSA9IHZhbHVlLCB1cGRhdGUgPSBmYWxzZSkge1xuICAgaWYgKGlzVHJhY2tpbmcoKSkge1xuICAgICAgbGV0IHNlZW4gPSBmYWxzZVxuICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICAgY29uc3Qga2V5VmFsdWVzID0gZGVwLmdldChvYmplY3QpID8/IG5ldyBNYXBcbiAgICAgICAgIGRlcC5zZXQob2JqZWN0LCBrZXlWYWx1ZXMpXG4gICAgICAgICBpZiAoIXNlZW4gJiYgdXBkYXRlICYmICFPYmplY3QuaXModmFsdWUsIHByZXZpb3VzKSkge1xuICAgICAgICAgICAgc2VlbiA9IHRydWVcbiAgICAgICAgICAgIGNvbnN0IGNoYW5nZXMgPSBnZXRDaGFuZ2VzKGRlcClcbiAgICAgICAgICAgIGNvbnN0IGNoYW5nZSA9IGNoYW5nZXMuZ2V0KG9iamVjdCkgPz8gbmV3IE1hcCgpXG4gICAgICAgICAgICBjaGFuZ2VzLnNldChvYmplY3QsIGNoYW5nZSlcbiAgICAgICAgICAgIGlmICghY2hhbmdlLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICAgICBjaGFuZ2Uuc2V0KGtleSwgdW50cmFjayhwcmV2aW91cykpXG4gICAgICAgICAgICB9XG4gICAgICAgICB9XG4gICAgICAgICBpZiAodXBkYXRlICYmIGtleVZhbHVlcy5oYXMoa2V5KSB8fCAhdXBkYXRlKSB7XG4gICAgICAgICAgICBrZXlWYWx1ZXMuc2V0KGtleSwgdmFsdWUpXG4gICAgICAgICB9XG4gICAgICB9XG4gICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9iamVjdFByb3h5KG9iamVjdDogb2JqZWN0KSB7XG4gICByZXR1cm4gbmV3IFByb3h5KG9iamVjdCwge1xuICAgICAgZ2V0KHRhcmdldDogb2JqZWN0LCBwOiBzdHJpbmcgfCBzeW1ib2wpOiBhbnkge1xuICAgICAgICAgY29uc3QgdmFsdWUgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHApXG4gICAgICAgICBhZGREZXAodGFyZ2V0LCBwLCB2YWx1ZSlcbiAgICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgfSxcbiAgICAgIHNldCh0YXJnZXQ6IG9iamVjdCwgcDogc3RyaW5nIHwgc3ltYm9sLCB2YWx1ZTogYW55LCByZWNlaXZlcjogYW55KTogYm9vbGVhbiB7XG4gICAgICAgICBjb25zdCBwcmV2aW91cyA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcClcbiAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3Quc2V0KHRhcmdldCwgcCwgdmFsdWUsIHJlY2VpdmVyKVxuICAgICAgICAgYWRkRGVwKHRhcmdldCwgcCwgdmFsdWUsIHByZXZpb3VzLCB0cnVlKVxuICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgfSxcbiAgICAgIGRlbGV0ZVByb3BlcnR5KHRhcmdldDogb2JqZWN0LCBwOiBzdHJpbmcgfCBzeW1ib2wpOiBib29sZWFuIHtcbiAgICAgICAgIGNvbnN0IHByZXZpb3VzID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwKVxuICAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0YXJnZXQsIHApXG4gICAgICAgICBhZGREZXAodGFyZ2V0LCBwLCB2b2lkIDAsIHByZXZpb3VzLCB0cnVlKVxuICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgfVxuICAgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVByb3h5KG9iamVjdDogb2JqZWN0KSB7XG4gICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHJldHVybiBvYmplY3RcbiAgIGlmIChjYWNoZS5oYXMob2JqZWN0KSkge1xuICAgICAgcmV0dXJuIGNhY2hlLmdldChvYmplY3QpIVxuICAgfVxuICAgY29uc3QgcHJveHkgPSBjcmVhdGVPYmplY3RQcm94eShvYmplY3QpXG4gICBjYWNoZS5zZXQob2JqZWN0LCBwcm94eSlcbiAgIHByb3hpZXMuc2V0KHByb3h5LCBvYmplY3QpXG4gICByZXR1cm4gcHJveHlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVHJhY2tlZChvYmplY3Q6IGFueSkge1xuICAgcmV0dXJuIHByb3hpZXMuaGFzKG9iamVjdClcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QodmFsdWU6IGFueSkge1xuICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbFxufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJhY2s8VD4ob2JqZWN0OiBUKTogVCB7XG4gICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiAhaXNUcmFja2VkKG9iamVjdCkgPyBjcmVhdGVQcm94eShvYmplY3QgYXMgYW55KSA6IG9iamVjdFxufVxuXG5leHBvcnQgZnVuY3Rpb24gdW50cmFjazxUPihvYmplY3Q6IFQpOiBUIHtcbiAgIHJldHVybiBwcm94aWVzLmdldChvYmplY3QgYXMgYW55KSA/PyBvYmplY3Rcbn1cbiJdfQ==