|
@@ -0,0 +1,34 @@
|
|
|
+import { useState, useEffect } from "react";
|
|
|
+
|
|
|
+export const createObservable = (
|
|
|
+ initial,
|
|
|
+ {
|
|
|
+ equality = (x, y) => x === y,
|
|
|
+ } = {}
|
|
|
+) => {
|
|
|
+ let _val = initial;
|
|
|
+ let _listeners = [];
|
|
|
+
|
|
|
+ return {
|
|
|
+ _sub: listener => {
|
|
|
+ _listeners.push(listener);
|
|
|
+ return () => {
|
|
|
+ _listeners = _listeners.filter(ln => ln !== listener);
|
|
|
+ };
|
|
|
+ },
|
|
|
+ get: () => _val,
|
|
|
+ set: newVal => {
|
|
|
+ const old = _val;
|
|
|
+ _val = newVal;
|
|
|
+ if (!equality(old, newVal)) {
|
|
|
+ _listeners.forEach(ln => ln(newVal));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+export default obs => {
|
|
|
+ const [val, setVal] = useState(obs.get());
|
|
|
+ useEffect(() => obs._sub(setVal), [obs]);
|
|
|
+ return val
|
|
|
+};
|