Skip to content

Commit e2e68e2

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

File tree

2 files changed

+28
-14
lines changed

2 files changed

+28
-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: 19 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;
@@ -89,6 +88,7 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
8988

9089
async fetchData() {
9190
try {
91+
await new Promise((resolve) => setTimeout(resolve, 18000));
9292
const result =
9393
typeof this.query.rawQuery == 'string'
9494
? await this.db.getAll(this.query.sqlStatement, this.query.queryParameters)
@@ -106,7 +106,8 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
106106
if (this.controller != null) {
107107
return;
108108
}
109-
if (this.listeners.size == 0 && this.temporaryHolds.size == 0) {
109+
110+
if (this.onUpdateListenersCount() == 0 && this.temporaryHolds.size == 0) {
110111
return;
111112
}
112113

@@ -145,7 +146,7 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
145146
this.currentError = undefined;
146147
this.resolveReady?.();
147148

148-
this.iterateListeners((l) => l?.onUpdate());
149+
this.iterateListeners((l) => l.onUpdate?.());
149150
}
150151

151152
private setError(error: any) {
@@ -154,21 +155,29 @@ export class WatchedQuery extends BaseObserver<WatchedQueryListener> {
154155
this.currentError = error;
155156
this.resolveReady?.();
156157

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

160165
private maybeDispose() {
161-
if (this.listeners.size == 0 && this.temporaryHolds.size == 0) {
166+
if (this.onUpdateListenersCount() == 0 && this.temporaryHolds.size == 0) {
162167
this.controller?.abort();
163168
this.controller = undefined;
164169
this.isReady = false;
165170
this.currentData = undefined;
166171
this.currentError = undefined;
167-
this.disposer?.();
172+
this.dispose();
168173

169174
this.readyPromise = new Promise((resolve, reject) => {
170175
this.resolveReady = resolve;
171176
});
172177
}
173178
}
179+
180+
async dispose() {
181+
this.iterateAsyncListeners(async (l) => l.disposed?.());
182+
}
174183
}

0 commit comments

Comments
 (0)