Skip to content

Instantly share code, notes, and snippets.

@rasmusmerzin
Created January 1, 2026 19:56
Show Gist options
  • Select an option

  • Save rasmusmerzin/15446bab542f7eeaf23390b74d461276 to your computer and use it in GitHub Desktop.

Select an option

Save rasmusmerzin/15446bab542f7eeaf23390b74d461276 to your computer and use it in GitHub Desktop.
export interface Observer<T> {
update(value: T): void;
}
export interface Observable<T> {
observe(observer: Observer<T>): Abortable;
}
export interface Abortable {
abort(): void;
}
export interface Relay<T> extends Observable<T>, Observer<T> {}
// implementation
export function noop(_?: unknown) {}
export function update<T>(value: T, raise = console.error) {
return function update(observer: Observer<T>) {
try {
observer.update(value);
} catch (notice) {
raise(notice);
}
};
}
export class Subject<T> implements Relay<T> {
private _observers = new Set<Observer<T>>();
constructor(private _state: T) {}
get state(): T {
return this._state;
}
observe(observer: Observer<T>) {
this._observers.add(observer);
return { abort: () => this._observers.delete(observer) };
}
update(value: T) {
this._observers.forEach(update(this._state = value));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment