Skip to content

Commit c1f96ac

Browse files
committed
Implementing Disposable interface.
1 parent 782b70e commit c1f96ac

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

packages/react/src/QueryStore.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@ export class QueryStore {
1515
if (this.cache.has(key)) {
1616
return this.cache.get(key);
1717
}
18-
const disposer = () => {
19-
this.cache.delete(key);
20-
};
21-
const q = new WatchedQuery(this.db, query, options, disposer);
18+
19+
const q = new WatchedQuery(this.db, query, options);
20+
const disposer = q.registerListener({
21+
disposed: () => {
22+
this.cache.delete(key);
23+
disposer?.();
24+
}
25+
});
26+
2227
this.cache.set(key, q);
2328

2429
return q;

packages/react/src/WatchedQuery.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AbstractPowerSyncDatabase, BaseListener, BaseObserver, CompilableQuery } from '@powersync/common';
1+
import { AbstractPowerSyncDatabase, BaseListener, BaseObserver, CompilableQuery, Disposable } from '@powersync/common';
22
import { AdditionalOptions } from './hooks/useQuery';
33

44
export class Query<T> {
@@ -9,9 +9,10 @@ export class Query<T> {
99

1010
export interface WatchedQueryListener extends BaseListener {
1111
onUpdate: () => void;
12+
disposed: () => void;
1213
}
1314

14-
export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
15+
export class WatchedQuery extends BaseObserver<WatchedQueryListener> implements Disposable {
1516
readyPromise: Promise<void>;
1617
isReady: boolean = false;
1718
currentData: any[] | undefined;
@@ -26,14 +27,12 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
2627

2728
readonly query: Query<unknown>;
2829
readonly options: AdditionalOptions;
29-
private disposer: () => void;
3030

31-
constructor(db: AbstractPowerSyncDatabase, query: Query<unknown>, options: AdditionalOptions, disposer: () => void) {
31+
constructor(db: AbstractPowerSyncDatabase, query: Query<unknown>, options: AdditionalOptions) {
3232
super();
3333
this.db = db;
3434
this.query = query;
3535
this.options = options;
36-
this.disposer = disposer;
3736

3837
this.readyPromise = new Promise((resolve) => {
3938
this.resolveReady = resolve;
@@ -106,7 +105,8 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
106105
if (this.controller != null) {
107106
return;
108107
}
109-
if (this.listeners.size == 0 && this.temporaryHolds.size == 0) {
108+
109+
if (this.onUpdateListenersCount() == 0 && this.temporaryHolds.size == 0) {
110110
return;
111111
}
112112

@@ -145,7 +145,7 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
145145
this.currentError = undefined;
146146
this.resolveReady?.();
147147

148-
this.iterateListeners((l) => l?.onUpdate());
148+
this.iterateListeners((l) => l.onUpdate?.());
149149
}
150150

151151
private setError(error: any) {
@@ -154,21 +154,29 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
154154
this.currentError = error;
155155
this.resolveReady?.();
156156

157-
this.iterateListeners((l) => l?.onUpdate());
157+
this.iterateListeners((l) => l.onUpdate?.());
158+
}
159+
160+
private onUpdateListenersCount(): number {
161+
return Array.from(this.listeners).filter((listener) => listener.onUpdate !== undefined).length;
158162
}
159163

160164
private maybeDispose() {
161-
if (this.listeners.size == 0 && this.temporaryHolds.size == 0) {
165+
if (this.onUpdateListenersCount() == 0 && this.temporaryHolds.size == 0) {
162166
this.controller?.abort();
163167
this.controller = undefined;
164168
this.isReady = false;
165169
this.currentData = undefined;
166170
this.currentError = undefined;
167-
this.disposer?.();
171+
this.dispose();
168172

169173
this.readyPromise = new Promise((resolve, reject) => {
170174
this.resolveReady = resolve;
171175
});
172176
}
173177
}
178+
179+
async dispose() {
180+
this.iterateAsyncListeners(async (l) => l.disposed?.());
181+
}
174182
}

0 commit comments

Comments
 (0)