-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathConnectionManager.ts
More file actions
121 lines (102 loc) · 3.3 KB
/
Copy pathConnectionManager.ts
File metadata and controls
121 lines (102 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import {
BaseListener,
createBaseLogger,
LogLevel,
PowerSyncDatabase,
SyncClientImplementation,
TemporaryStorageOption,
WASQLiteOpenFactory,
WASQLiteVFS,
WebRemote,
WebStreamingSyncImplementation,
WebStreamingSyncImplementationOptions
} from '@powersync/web';
import { safeParse } from '../safeParse/safeParse';
import { DynamicSchemaManager } from './DynamicSchemaManager';
import { RecordingStorageAdapter } from './RecordingStorageAdapter';
import { TokenConnector } from './TokenConnector';
import { RustClientInterceptor } from './RustClientInterceptor';
const baseLogger = createBaseLogger();
baseLogger.useDefaults();
baseLogger.setLevel(LogLevel.DEBUG);
export const PARAMS_STORE = 'currentParams';
export const getParams = () => {
const stringifiedParams = localStorage.getItem(PARAMS_STORE);
const params = safeParse(stringifiedParams);
return params;
};
export const schemaManager = new DynamicSchemaManager();
const openFactory = new WASQLiteOpenFactory({
dbFilename: 'diagnostics.db',
debugMode: true,
cacheSizeKb: 500 * 1024,
temporaryStorage: TemporaryStorageOption.MEMORY,
vfs: WASQLiteVFS.OPFSCoopSyncVFS
});
export const db = new PowerSyncDatabase({
database: openFactory,
schema: schemaManager.buildSchema()
});
export const connector = new TokenConnector();
const adapter = new RecordingStorageAdapter(db.database, schemaManager);
export let sync: WebStreamingSyncImplementation | undefined;
export interface SyncErrorListener extends BaseListener {
lastErrorUpdated?: ((error: Error) => void) | undefined;
}
if (connector.hasCredentials()) {
connect();
}
export async function connect() {
const client =
localStorage.getItem('preferred_client_implementation') == SyncClientImplementation.RUST
? SyncClientImplementation.RUST
: SyncClientImplementation.JAVASCRIPT;
const params = getParams();
await sync?.disconnect();
const remote = new WebRemote(connector);
const adapter =
client == SyncClientImplementation.JAVASCRIPT
? new RecordingStorageAdapter(db.database, schemaManager)
: new RustClientInterceptor(db.database, remote, schemaManager);
const syncOptions: WebStreamingSyncImplementationOptions = {
adapter,
remote,
uploadCrud: async () => {
// No-op
},
identifier: 'diagnostics'
};
sync = new WebStreamingSyncImplementation(syncOptions);
await sync.connect({ params, clientImplementation: client });
if (!sync.syncStatus.connected) {
const error = sync.syncStatus.dataFlowStatus.downloadError ?? new Error('Failed to connect');
// Disconnect but don't wait for it
await sync.disconnect();
throw error;
}
}
export async function clearData() {
await sync?.disconnect();
await db.disconnectAndClear();
await schemaManager.clear();
await schemaManager.refreshSchema(db.database);
if (connector.hasCredentials()) {
const params = getParams();
await sync?.connect({ params });
}
}
export async function disconnect() {
await sync?.disconnect();
}
export async function signOut() {
connector.clearCredentials();
await disconnect();
await db.disconnectAndClear();
await schemaManager.clear();
}
export const setParams = (p: object) => {
const stringified = JSON.stringify(p);
localStorage.setItem(PARAMS_STORE, stringified);
connect();
};
(window as any).db = db;