~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atlibs

0
0
main
29 lines · 960 B Raw History
// A Cubit (from the BLoC pattern): one immutable state object, replaced by emit().
// Views subscribe and render whatever state they are handed; they never mutate it.
export class Cubit extends EventTarget {
	#state;

	constructor(state) {
		super();
		this.#state = Object.freeze(state);
	}

	get state() {
		return this.#state;
	}

	// Shallow-merges patch into a new frozen state and notifies subscribers with (state, previous).
	emit(patch) {
		const previous = this.#state;
		this.#state = Object.freeze({ ...previous, ...patch });
		this.dispatchEvent(new CustomEvent("change", { detail: { state: this.#state, previous } }));
	}

	// Calls fn(state, previous) now and on every change; returns an unsubscribe function.
	subscribe(fn) {
		const listener = (event) => fn(event.detail.state, event.detail.previous);
		this.addEventListener("change", listener);
		fn(this.#state, undefined);
		return () => this.removeEventListener("change", listener);
	}
}