kr-observable
Version:
Adds reactivity power for your JavaScript
67 lines (66 loc) • 1.81 kB
JavaScript
import { Admin } from './Admin.js';
import { Utils } from './Utils.js';
import { Global } from './global.js';
const registry = new Map();
const error = new TypeError('First argument must be Observable');
export function subscribe(target, cb, keys) {
const adm = Utils.getAdm(target);
if (!adm)
throw error;
let disposer = registry.get(cb);
if (disposer)
return disposer;
const runnable = { subscriber: cb, runId: 1, active: false, deps: new Set };
keys.forEach(key => adm.subscribe(key, runnable));
disposer = () => {
registry.delete(cb);
Global.executor.dispose(runnable);
};
registry.set(cb, disposer);
return disposer;
}
export function autorun(work) {
let disposer = registry.get(work);
if (disposer)
return disposer;
const runnable = {
run: work,
subscriber() {
Global.executor.execute(this);
},
debug: false,
runId: 1,
active: false,
deps: undefined
};
disposer = () => {
registry.delete(work);
Global.executor.dispose(runnable);
};
registry.set(work, disposer);
Global.executor.execute(runnable);
return disposer;
}
export function listen(target, cb) {
const adm = Utils.getAdm(target);
if (!adm)
throw error;
if (!adm.listeners)
adm.listeners = new Set();
adm.listeners.add(cb);
return () => void adm.listeners.delete(cb);
}
export function transaction(work) {
Global.action = true;
work();
Global.action = false;
Global.queue.forEach(Admin.batch);
Global.queue.clear();
Global.notifier.flush();
}
export function untracked(work) {
Global.untracked = true;
const result = work();
Global.untracked = false;
return result;
}