tilia
Version:
🍃 State management library, domain-driven.
784 lines (727 loc) • 19.3 kB
JavaScript
// Generated by ReScript, PLEASE EDIT WITH CARE
var raise = (function (message) {
throw new Error(message)
});
var symbol = (function(s) {
return Symbol.for('tilia:' + s);
});
var indexKey = symbol("indexKey");
var metaKey = symbol("metaKey");
var dynamicKey = symbol("dynamicKey");
var ctxKey = symbol("ctx");
var proxiable = (function(v) {
if ( typeof v === 'object' && v !== null) {
const proto = Object.getPrototypeOf(v)
return proto === Object.prototype || proto === Array.prototype || proto === null
}
return false;
});
var dynamic = (function(v) {
return typeof v === 'object' && v !== null && v[dynamicKey] ? v : undefined;
});
function readonly(o, k) {
var d = Object.getOwnPropertyDescriptor(o, k);
if (d === null || d === undefined) {
return false;
} else {
return d.writable === false;
}
}
function observeKey(observed, key) {
var w = observed.get(key);
if (!(w === null || w === undefined)) {
return w;
}
w === null;
var w$1 = {
state: "Pristine",
key: key,
observed: observed,
observers: new Set()
};
observed.set(key, w$1);
return w$1;
}
function flush(root) {
if (root.expired.size > 0) {
while(root.expired.size > 0) {
var expired = root.expired;
root.expired = new Set();
expired.forEach(function (observer) {
observer.notify();
});
};
}
var gc = root.gc;
if (gc.active.size >= gc.threshold) {
gc.quarantine.forEach(function (w) {
if (w.state === "Pristine" && w.observers.size === 0) {
w.state = "Cleared";
w.observed.delete(w.key);
return ;
}
});
gc.quarantine = gc.active;
gc.active = new Set();
return ;
}
}
function _clear(observer) {
var root = observer.root;
observer.observing.forEach(function (watchers) {
if (watchers.state === "Pristine" && watchers.observers.delete(observer) && watchers.observers.size === 0) {
root.gc.active.add(watchers);
return ;
}
});
var o = root.observer;
if (o === null || o === undefined || o !== observer) {
return ;
} else {
root.observer = undefined;
if (!root.lock) {
return flush(root);
} else {
return ;
}
}
}
function _ready(observer, notifyIfChanged) {
observer.observing.find(function (w, idx) {
var match = w.state;
switch (match) {
case "Pristine" :
w.observers.add(observer);
return false;
case "Changed" :
case "Cleared" :
break;
}
if (notifyIfChanged) {
_clear(observer);
observer.notify();
return true;
}
var w$1 = observeKey(w.observed, w.key);
w$1.observers.add(observer);
observer.observing[idx] = w$1;
return false;
});
var root = observer.root;
var o = root.observer;
if (o === null || o === undefined || o !== observer) {
return ;
} else {
root.observer = undefined;
if (!root.lock) {
return flush(root);
} else {
return ;
}
}
}
function notify(root, observed, key) {
var watchers = observed.get(key);
if (watchers === null || watchers === undefined) {
return ;
}
observed.delete(key);
watchers.state = "Changed";
var expired = root.expired;
watchers.observers.forEach(function (observer) {
_clear(observer);
expired.add(observer);
});
var match = root.observer;
if (!(match === null || match === undefined)) {
return ;
}
match === null;
if (!root.lock) {
return flush(root);
}
}
function set(root, observed, proxied, computes, isArray, _fromComputed, target, _key, _value) {
while(true) {
var value = _value;
var key = _key;
var fromComputed = _fromComputed;
var hadKey = Reflect.has(target, key);
var prev = Reflect.get(target, key);
var proxiable$1 = proxiable(value);
var same;
if (proxiable$1) {
var m = Reflect.get(value, metaKey);
same = m === null || m === undefined ? prev === value : m.target === prev;
} else {
same = prev === value;
}
if (same) {
return true;
}
if (!Reflect.set(target, key, value)) {
return false;
}
var key$1 = isArray && key === "length" ? indexKey : key;
if (proxiable$1) {
proxied.delete(key$1);
}
if (!fromComputed) {
var clear = computes.get(key$1);
if (clear === null || clear === undefined) {
clear === null;
} else {
computes.delete(key$1);
clear();
}
}
var match = dynamic(value);
if (match === null || match === undefined) {
match === null;
} else {
var w = observed.get(key$1);
if (w === null || w === undefined) {
return true;
}
if (!(w.state === "Pristine" && w.observers.size > 0)) {
return true;
}
Reflect.set(target, key$1, prev);
var compile$1 = (function(key$1){
return function compile$1(callback) {
return compile(root, observed, proxied, computes, isArray, target, key$1, callback);
}
}(key$1));
var setter = (function(key$1){
return function setter(v) {
set(root, observed, proxied, computes, isArray, true, target, key$1, v);
}
}(key$1));
var get = function (_value) {
while(true) {
var value = _value;
var dynamic$1 = dynamic(value);
if (dynamic$1 === null || dynamic$1 === undefined) {
return value;
}
var v;
switch (dynamic$1.TAG) {
case "Computed" :
v = compile$1(dynamic$1._0);
break;
case "Source" :
var source = dynamic$1._0;
var v$1 = source.value;
var val = {
contents: v$1
};
var set = (function(val){
return function set(v) {
val.contents = v;
setter(v);
}
}(val));
var callback = source.source;
v = compile$1((set(v$1), (function(val,callback){
return function () {
callback(set);
return val.contents;
}
}(val,callback))));
break;
case "Store" :
var store = dynamic$1._0;
v = compile$1((function(store){
return function () {
return store(setter);
}
}(store)));
break;
case "Compiled" :
var rebuild = dynamic$1._0.rebuild;
v = rebuild();
break;
}
if (!proxiable(v)) {
return v;
}
_value = v;
continue ;
};
};
var v = get(value);
_value = v;
_key = key$1;
_fromComputed = true;
continue ;
}
notify(root, observed, key$1);
if (!hadKey) {
notify(root, observed, indexKey);
}
return true;
};
}
function compile(root, observed, proxied, computes, isArray, target, key, callback) {
var lastValue = {
v: undefined
};
var observer = {
o: undefined
};
var compute = {
rebuild: undefined
};
var compiled = {
TAG: "Compiled",
_0: compute
};
Reflect.set(compiled, dynamicKey, true);
var notify = function () {
var v = Reflect.get(target, key);
if (v !== compiled) {
lastValue.v = v;
}
var w = observed.get(key);
if (!(w === null || w === undefined)) {
if (w.observers.size > 0) {
set(root, observed, proxied, computes, isArray, true, target, key, rebuild());
} else {
w.state = "Changed";
observed.delete(key);
proxied.delete(key);
Reflect.set(target, key, compiled);
}
return ;
}
w === null;
proxied.delete(key);
Reflect.set(target, key, compiled);
};
var rebuild = function () {
var curr = Reflect.get(target, key);
if (curr === compiled) {
Reflect.set(target, key, lastValue.v);
} else {
lastValue.v = curr;
}
var o_observing = [];
var o = {
root: root,
notify: notify,
observing: o_observing
};
observer.o = o;
var previous = root.observer;
root.observer = o;
var v = callback();
root.observer = previous;
if (o_observing.length === 0) {
_clear(o);
computes.delete(key);
} else {
_ready(o, false);
}
return v;
};
compute.rebuild = rebuild;
var clear = function () {
var o = observer.o;
if (o === null || o === undefined) {
return ;
}
_clear(o);
((o.observing.length = 0));
};
computes.set(key, clear);
return rebuild();
}
function proxify(root, _target) {
while(true) {
var target = _target;
var proxied = new Map();
var observed = new Map();
var computes = new Map();
var m = Reflect.get(target, metaKey);
if (m === null || m === undefined) {
m === null;
} else {
if (m.root === root) {
return m;
}
_target = m.target;
continue ;
}
var meta = ({root, target, observed, proxied, computes});
var isArray = Array.isArray(target);
var proxy = new Proxy(target, {
set: (function(proxied,observed,computes,isArray){
return function (extra, extra$1, extra$2) {
return set(root, observed, proxied, computes, isArray, false, extra, extra$1, extra$2);
}
}(proxied,observed,computes,isArray)),
deleteProperty: (function(proxied,observed,computes){
return function (extra, extra$1) {
var res = Reflect.deleteProperty(extra, extra$1);
proxied.delete(extra$1);
var clear = computes.get(extra$1);
if (clear === null || clear === undefined) {
clear === null;
} else {
computes.delete(extra$1);
clear();
}
notify(root, observed, extra$1);
return res;
}
}(proxied,observed,computes)),
get: (function(proxied,observed,computes,isArray){
return function (extra, extra$1) {
if (extra$1 === metaKey) {
return meta;
}
if (extra$1 === dynamicKey) {
return undefined;
}
var value = Reflect.get(extra, extra$1);
var own = Object.hasOwn(extra, extra$1);
if (!(value === undefined || own)) {
return value;
}
var o = root.observer;
if (o === null || o === undefined) {
o === null;
} else if (isArray && extra$1 === "length") {
var w = observeKey(observed, indexKey);
o.observing.push(w);
} else {
var w$1 = observeKey(observed, extra$1);
o.observing.push(w$1);
}
if (!(proxiable(value) && !readonly(extra, extra$1))) {
return value;
}
var m = proxied.get(extra$1);
if (!(m === null || m === undefined)) {
return m.proxy;
}
m === null;
var compile$1 = function (callback) {
return compile(root, observed, proxied, computes, isArray, extra, extra$1, callback);
};
var setter = function (v) {
set(root, observed, proxied, computes, isArray, true, extra, extra$1, v);
};
var get = function (_value) {
while(true) {
var value = _value;
var dynamic$1 = dynamic(value);
if (dynamic$1 === null || dynamic$1 === undefined) {
return value;
}
var v;
switch (dynamic$1.TAG) {
case "Computed" :
v = compile$1(dynamic$1._0);
break;
case "Source" :
var source = dynamic$1._0;
var v$1 = source.value;
var val = {
contents: v$1
};
var set = (function(val){
return function set(v) {
val.contents = v;
setter(v);
}
}(val));
var callback = source.source;
v = compile$1((set(v$1), (function(val,callback){
return function () {
callback(set);
return val.contents;
}
}(val,callback))));
break;
case "Store" :
var store = dynamic$1._0;
v = compile$1((function(store){
return function () {
return store(setter);
}
}(store)));
break;
case "Compiled" :
var rebuild = dynamic$1._0.rebuild;
v = rebuild();
break;
}
if (!proxiable(v)) {
return v;
}
_value = v;
continue ;
};
};
var v = get(value);
Reflect.set(extra, extra$1, v);
if (!proxiable(v)) {
return v;
}
var m$1 = proxify(root, v);
proxied.set(extra$1, m$1);
return m$1.proxy;
}
}(proxied,observed,computes,isArray)),
ownKeys: (function(observed){
return function (extra) {
var keys = Reflect.ownKeys(extra);
var o = root.observer;
if (o === null || o === undefined) {
o === null;
} else {
var w = observeKey(observed, indexKey);
o.observing.push(w);
}
return keys;
}
}(observed))
});
meta.proxy = proxy;
return meta;
};
}
function makeTilia(root) {
return function (value) {
if (!proxiable(value)) {
raise("tilia: value is not an object or array");
}
return proxify(root, value).proxy;
};
}
function makeDerived(p) {
return function (fn) {
var v = {
TAG: "Computed",
_0: (function () {
return fn(p.contents);
})
};
Reflect.set(v, dynamicKey, true);
return v;
};
}
function makeReactive(derived) {
return { derived }
}
;
function makeCarve(root) {
return function (fn) {
var p = {
contents: {}
};
var ctx = makeReactive(makeDerived(p));
var value = fn(ctx);
if (!proxiable(value)) {
raise("tilia: value is not an object or array");
}
var value$1 = proxify(root, value).proxy;
p.contents = value$1;
return value$1;
};
}
function makeObserve(root) {
return function (callback) {
var notify = function () {
var observer_observing = [];
var observer = {
root: root,
notify: notify,
observing: observer_observing
};
root.observer = observer;
var o = observer;
callback();
_ready(o, true);
};
notify();
};
}
function makeWatch(root, observe_) {
return function (callback, effect) {
var notify = function () {
var o = observe_(notify);
var v = callback();
o.root.observer = undefined;
if (root.lock) {
effect(v);
} else {
root.lock = true;
effect(v);
root.lock = false;
}
_ready(o, false);
};
var o = observe_(notify);
callback();
_ready(o, false);
};
}
function makeBatch(root) {
return function (callback) {
if (root.lock) {
return callback();
} else {
root.lock = true;
callback();
root.lock = false;
return flush(root);
}
};
}
function computed(fn) {
var v = {
TAG: "Computed",
_0: fn
};
Reflect.set(v, dynamicKey, true);
return v;
}
function source(source$1, value) {
var v = {
TAG: "Source",
_0: {
source: source$1,
value: value
}
};
Reflect.set(v, dynamicKey, true);
return v;
}
function store(callback) {
var v = {
TAG: "Store",
_0: callback
};
Reflect.set(v, dynamicKey, true);
return v;
}
function makeDerived$1(tilia) {
return function (fn) {
return tilia({
value: computed(function () {
return fn();
})
});
};
}
function _done(o) {
o.root.observer = undefined;
}
function connector(tilia, carve, observe, watch, batch, signal, derived, _observe) {
return {
tilia,
carve,
observe,
watch,
batch,
// extra
signal,
derived,
// internal
_observe,
};
}
;
function make(gcOpt) {
var gc = gcOpt !== undefined ? gcOpt : 50;
var gc$1 = {
active: new Set(),
quarantine: new Set(),
threshold: gc
};
var root = {
observer: undefined,
expired: new Set(),
lock: false,
gc: gc$1
};
var tilia = makeTilia(root);
var _observe = function (extra) {
var observer_observing = [];
var observer = {
root: root,
notify: extra,
observing: observer_observing
};
root.observer = observer;
return observer;
};
return connector(tilia, makeCarve(root), makeObserve(root), makeWatch(root, _observe), makeBatch(root), (function (value) {
return tilia({
value: value
});
}), makeDerived$1(tilia), _observe);
}
var ctx = Reflect.get(globalThis, ctxKey);
var _ctx;
var exit = 0;
if (ctx === null || ctx === undefined) {
exit = 1;
} else {
_ctx = ctx;
}
if (exit === 1) {
var ctx$1 = make(undefined);
Reflect.set(globalThis, ctxKey, ctx$1);
_ctx = ctx$1;
}
function readonly$1(data) {
var obj = {};
Object.defineProperty(obj, "data", {
writable: false,
enumerable: true,
configurable: false,
value: data
});
return obj;
}
function unwrap(s) {
return computed(function () {
return s.value;
});
}
var tilia = _ctx.tilia;
var carve = _ctx.carve;
var observe = _ctx.observe;
var watch = _ctx.watch;
var batch = _ctx.batch;
var signal = _ctx.signal;
var derived = _ctx.derived;
var _observe = _ctx._observe;
function _meta(p) {
return Reflect.get(p, metaKey);
}
export {
make ,
tilia ,
carve ,
observe ,
watch ,
batch ,
signal ,
derived ,
readonly$1 as readonly,
computed ,
unwrap ,
source ,
store ,
_observe ,
_done ,
_ready ,
_clear ,
_meta ,
_ctx ,
}
/* indexKey Not a pure module */