1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 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);
}
}