refactor: remove rxjs dependency

Replace rxjs with a lightweight internal Subject implementation
to reduce package size and complexity.
This commit is contained in:
2026-05-31 16:38:27 +08:00
parent 87c01858e7
commit 46da8abbe1
6 changed files with 55 additions and 22 deletions
+1
View File
@@ -17,3 +17,4 @@ export type {
RelationshipUpdate,
} from "./observable/events";
export type { WorldSnapshot } from "./serialization";
export type { Observable, Subscription } from "./observable/subject";
+1 -1
View File
@@ -1,4 +1,4 @@
import { Subject } from "rxjs";
import { Subject } from "./subject";
import type { Query } from "../query";
import type { Entity } from "../entity";
import type {
+50
View File
@@ -0,0 +1,50 @@
// ── Internal Observable / Subject ─────────────────────
/** Minimal subscription handle returned by `.subscribe()`. */
export interface Subscription {
unsubscribe(): void;
}
/** Minimal observable interface — only supports single-callback subscribe. */
export interface Observable<T> {
subscribe(observer: (value: T) => void): Subscription;
}
/** Lightweight multicast subject, replacing the RxJS dependency. */
export class Subject<T> implements Observable<T> {
private _subs = new Set<(value: T) => void>();
private _done = false;
/** Push a value to all current subscribers. No-op after complete. */
next(value: T): void {
if (this._done) return;
for (const fn of this._subs) {
fn(value);
}
}
/** Register a subscriber. Returns a handle to unsubscribe. */
subscribe(observer: (value: T) => void): Subscription {
const fn = observer;
this._subs.add(fn);
return {
unsubscribe: () => {
this._subs.delete(fn);
},
};
}
/** Complete this subject — clears all subscribers and silences future calls. */
complete(): void {
this._done = true;
this._subs.clear();
}
/** Return a read-only Observable facade (hides `next` / `complete`). */
asObservable(): Observable<T> {
return {
subscribe: (observer: (value: T) => void): Subscription => {
return this.subscribe(observer);
},
};
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ import { SparseSet } from "./storage/sparse-set";
import { ObservableLayer } from "./observable/observe";
import type { QueryUpdate, RelationshipUpdate } from "./observable/events";
import type { RelationshipDef } from "./relationship";
import { Observable } from "rxjs";
import type { Observable } from "./observable/subject";
import type { WorldEvent } from "./observable/events";
import type { WorldSnapshot } from "./serialization";