Last active
August 24, 2022 18:41
-
-
Save intrnl/abab1b5f5a550392216d511482ebb803 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let effects = []; | |
let current = null; | |
let dirty = 0n; | |
let flushing = false; | |
export let access = Symbol(); | |
export function state (flag, value) { | |
return (next, effect = true) => { | |
if (next === access) { | |
if (current && effect) { | |
current.d |= flag; | |
} | |
return value; | |
} | |
else { | |
if (effect) { | |
dirty |= flag; | |
update(); | |
} | |
return value = next; | |
} | |
}; | |
} | |
export function computed (flag, getter) { | |
let _dirty = true; | |
let _value; | |
let _compute = effect(getter, () => { | |
_dirty = true; | |
dirty |= flag; | |
update(); | |
}); | |
return (next, effect = true) => { | |
if (next === access) { | |
if (current && effect) { | |
current.d |= flag; | |
} | |
if (_dirty) { | |
_value = _compute(); | |
} | |
} | |
return _value; | |
}; | |
} | |
export function effect (fn, scheduler) { | |
let run = () => { | |
let prev_current = current; | |
try { | |
current = run; | |
current.d = 0n; | |
return fn(); | |
} | |
finally { | |
current = prev_current; | |
} | |
}; | |
run.s = scheduler; | |
if (!scheduler) { | |
run(); | |
} | |
effects.push(run); | |
} | |
let resolved_promise = Promise.resolve(); | |
export function update () { | |
if (!flushing) { | |
flushing = true; | |
resolved_promise.then(flush); | |
} | |
} | |
function flush () { | |
while (dirty) { | |
let next = dirty; | |
dirty = 0n | |
for (let fn of effects) { | |
if (fn.d & next) { | |
fn.d = 0n; | |
if (fn.s) { | |
fn.s(); | |
} | |
else { | |
fn(); | |
} | |
} | |
} | |
} | |
flushing = false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment