Skip to content

Commit 274736a

Browse files
committed
feat: add options to web
1 parent 69811b7 commit 274736a

File tree

3 files changed

+112
-2
lines changed

3 files changed

+112
-2
lines changed

packages/common/src/client/sync/stream/AbstractStreamingSyncImplementation.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export interface PowerSyncConnectionOptions {
9191
*/
9292
crudUploadThrottleMs?: number;
9393
}
94+
export type PowerSyncConnectionRequiredOptions = Required<Omit<PowerSyncConnectionOptions, 'retryDelayMs' | 'crudUploadThrottleMs'>>;
9495

9596
export interface StreamingSyncImplementation extends BaseObserver<StreamingSyncImplementationListener>, Disposable {
9697
/**
@@ -439,7 +440,7 @@ The next upload iteration will be delayed.`);
439440
type: LockType.SYNC,
440441
signal,
441442
callback: async () => {
442-
const resolvedOptions: Required<Omit<PowerSyncConnectionOptions, 'retryDelayMs' | 'crudUploadThrottleMs'>> = {
443+
const resolvedOptions: Required<PowerSyncConnectionRequiredOptions> = {
443444
...DEFAULT_STREAM_CONNECTION_OPTIONS,
444445
...(options ?? {})
445446
};

packages/web/src/db/PowerSyncDatabase.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,20 @@ export class PowerSyncDatabase extends AbstractPowerSyncDatabase {
164164
return getNavigatorLocks().request(`lock-${this.database.name}`, cb);
165165
}
166166

167-
protected generateSyncStreamImplementation(connector: PowerSyncBackendConnector): StreamingSyncImplementation {
167+
protected generateSyncStreamImplementation(
168+
connector: PowerSyncBackendConnector,
169+
// This is used to pass in options on connection instead of only during db creation
170+
options?: {
171+
retryDelayMs?: number;
172+
crudUploadThrottleMs?: number;
173+
}
174+
): StreamingSyncImplementation {
168175
const remote = new WebRemote(connector);
169176

170177
const syncOptions: WebStreamingSyncImplementationOptions = {
171178
...(this.options as {}),
179+
retryDelayMs: options?.retryDelayMs || this.options.retryDelay,
180+
crudUploadThrottleMs: options?.crudUploadThrottleMs || this.options.crudUploadThrottleMs,
172181
flags: this.resolvedFlags,
173182
adapter: this.bucketStorageAdapter,
174183
remote,
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { describe, it, expect, beforeEach, vi } from 'vitest'
2+
import { PowerSyncDatabase, SharedWebStreamingSyncImplementation, WebStreamingSyncImplementation } from '../../../src'
3+
import { SSRStreamingSyncImplementation } from '../../../src/db/sync/SSRWebStreamingSyncImplementation'
4+
import { testSchema } from '../../utils/testDb'
5+
6+
7+
vi.mock('../../../src/db/sync/WebStreamingSyncImplementation')
8+
vi.mock('../../../src/db/sync/SharedWebStreamingSyncImplementation')
9+
vi.mock('../../../src/db/sync/SSRWebStreamingSyncImplementation')
10+
11+
describe('PowerSyncDatabase - generateSyncStreamImplementation', () => {
12+
const mockConnector = {
13+
uploadData: vi.fn(),
14+
fetchCredentials: vi.fn()
15+
}
16+
17+
beforeEach(() => {
18+
vi.resetAllMocks()
19+
})
20+
21+
it('uses SSRStreamingSyncImplementation when ssrMode is true', async () => {
22+
// This is to prevent a false positive from the unhandled rejection
23+
// of using SSR in this test.
24+
const handler = (event: PromiseRejectionEvent) => {
25+
event.preventDefault()
26+
}
27+
window.addEventListener('unhandledrejection', handler)
28+
29+
const db = new PowerSyncDatabase({
30+
schema: testSchema,
31+
database: {
32+
dbFilename: 'test.db'
33+
},
34+
flags: {
35+
ssrMode: true,
36+
},
37+
retryDelay: 1000,
38+
crudUploadThrottleMs: 2000
39+
})
40+
41+
db['generateSyncStreamImplementation'](mockConnector)
42+
expect(SSRStreamingSyncImplementation).toHaveBeenCalled()
43+
44+
await setTimeout(() => window.removeEventListener('unhandledrejection', handler), 1)
45+
})
46+
47+
it('uses SharedWebStreamingSyncImplementation when enableMultiTabs is true', () => {
48+
const db = new PowerSyncDatabase({
49+
schema: testSchema,
50+
database: { dbFilename: 'test.db' },
51+
flags: { enableMultiTabs: true }
52+
})
53+
db['generateSyncStreamImplementation'](mockConnector)
54+
expect(SharedWebStreamingSyncImplementation).toHaveBeenCalled()
55+
})
56+
57+
it('handles option overrides', () => {
58+
const db = new PowerSyncDatabase({
59+
schema: testSchema,
60+
database: {
61+
dbFilename: 'test.db'
62+
},
63+
flags: {
64+
ssrMode: false,
65+
enableMultiTabs: false,
66+
},
67+
crudUploadThrottleMs: 1000
68+
})
69+
70+
db['generateSyncStreamImplementation'](mockConnector, { crudUploadThrottleMs: 20000, retryDelayMs: 50000 })
71+
expect(WebStreamingSyncImplementation).toHaveBeenCalledWith(
72+
expect.objectContaining({
73+
retryDelayMs: 50000,
74+
crudUploadThrottleMs: 20000
75+
})
76+
)
77+
})
78+
79+
it('handles partial option overrides', () => {
80+
const db = new PowerSyncDatabase({
81+
schema: testSchema,
82+
database: {
83+
dbFilename: 'test.db'
84+
},
85+
flags: {
86+
ssrMode: false,
87+
enableMultiTabs: false,
88+
},
89+
retryDelay: 1000,
90+
crudUploadThrottleMs: 2000
91+
})
92+
93+
db['generateSyncStreamImplementation'](mockConnector, { retryDelayMs: 50000 })
94+
expect(WebStreamingSyncImplementation).toHaveBeenCalledWith(
95+
expect.objectContaining({
96+
retryDelayMs: 50000,
97+
})
98+
)
99+
})
100+
})

0 commit comments

Comments
 (0)