Skip to content

Instantly share code, notes, and snippets.

@cyco130
Last active October 24, 2022 12:39
Show Gist options
  • Save cyco130/e4e15f22ba4bc95aeaa489368392fa50 to your computer and use it in GitHub Desktop.
Save cyco130/e4e15f22ba4bc95aeaa489368392fa50 to your computer and use it in GitHub Desktop.
export function observable<T>(value: T): Observable<T> {
const subscribers = new Set<(val: T) => void>();
function run(): T;
function run(newValue: T): void;
function run(updateFunction: (oldValue: T) => T): void;
function run(newValueOrUpdateFn?: T | ((oldValue: T) => T)): T | void {
if (newValueOrUpdateFn === undefined) {
return value;
}
const oldValue = value;
if (typeof newValueOrUpdateFn === "function") {
value = (newValueOrUpdateFn as any)(value);
} else {
value = newValueOrUpdateFn;
}
if (oldValue !== value) {
subscribers.forEach((fn) => fn(value));
}
}
run.subscribe = (fn: (val: T) => void) => {
subscribers.add(fn);
return () => {
subscribers.delete(fn);
};
};
return run;
}
export interface Observable<T> {
(): T;
(newValue: T): void;
(val: (oldValue: T) => T): void;
subscribe(fn: (value: T) => void): () => void;
}
const count = observable(0);
const unsubscribe = count.subscribe(console.log);
count(1); // Prints 1
count((x) => x + 1); // Prints 2
console.log(count()); // Prints 2
count(2); // Doesn't print (value unchanged)
unsubscribe();
count(3); // Doesn't print (unsubscribed)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment