diff options
author | metamuffin <metamuffin@disroot.org> | 2023-12-10 21:07:30 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-12-10 21:07:30 +0100 |
commit | 56fefbe4495d71b7696b4a4a0980b24c5dc26bf4 (patch) | |
tree | 415a1090365f5caeb40d20dc096b524364a4bfc1 /src/observable.ts | |
parent | 2d36b0762459b8edfc1529827d0c15447edd2669 (diff) | |
download | jshelper-56fefbe4495d71b7696b4a4a0980b24c5dc26bf4.tar jshelper-56fefbe4495d71b7696b4a4a0980b24c5dc26bf4.tar.bz2 jshelper-56fefbe4495d71b7696b4a4a0980b24c5dc26bf4.tar.zst |
improve memory leak a little
Diffstat (limited to 'src/observable.ts')
-rw-r--r-- | src/observable.ts | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/observable.ts b/src/observable.ts index 15a1a2e..5185c9f 100644 --- a/src/observable.ts +++ b/src/observable.ts @@ -5,6 +5,9 @@ */ export class OVar<T> { private _value: T + private weak = false; // if weak, the source will be unsubscribed from, if all listeners are removed + private disabled = false + private cancel_source?: () => void private observers: ((v: T) => unknown)[] = [] constructor(initial: T) { @@ -16,8 +19,16 @@ export class OVar<T> { change() { this.observers.forEach(o => o(this._value)) } onchange(handler: (v: T) => unknown): () => void { + if (this.disabled) throw new Error("obervable is disabled"); this.observers.push(handler) - return () => this.observers = this.observers.filter(o => o != handler) + if (this.observers.length > 16) console.warn("likely memory leak here:", this); + return () => { + this.observers = this.observers.filter(o => o != handler) + if (this.observers.length == 0 && this.weak) { + this.cancel_source!() + this.disabled = true + } + } } onchangeinit(handler: (v: T) => unknown): () => void { const abort = this.onchange(handler) @@ -26,7 +37,8 @@ export class OVar<T> { } map<U>(fn: (v: T) => U): OVar<U> { const uv = new OVar(fn(this.value)) - this.onchange(v => uv.value = fn(v)) + uv.cancel_source = this.onchange(v => uv.value = fn(v)) + uv.weak = true return uv; } wait_for(val: T) { |