@verdant-web/store 4.6.1 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/index.js +14 -12
- package/dist/bundle/index.js.map +4 -4
- package/dist/esm/__tests__/fixtures/testStorage.d.ts +1 -1
- package/dist/esm/__tests__/fixtures/testStorage.js +3 -3
- package/dist/esm/__tests__/fixtures/testStorage.js.map +1 -1
- package/dist/esm/__tests__/queries.test.js +3 -3
- package/dist/esm/__tests__/queries.test.js.map +1 -1
- package/dist/esm/__tests__/schema.test.js +3 -3
- package/dist/esm/__tests__/schema.test.js.map +1 -1
- package/dist/esm/client/Client.d.ts +12 -10
- package/dist/esm/client/Client.js +40 -30
- package/dist/esm/client/Client.js.map +1 -1
- package/dist/esm/context/Time.d.ts +1 -1
- package/dist/esm/context/Time.js +1 -1
- package/dist/esm/context/Time.js.map +1 -1
- package/dist/esm/context/context.d.ts +84 -15
- package/dist/esm/context/context.js +98 -1
- package/dist/esm/context/context.js.map +1 -1
- package/dist/esm/entities/Entity.test.js +0 -1
- package/dist/esm/entities/Entity.test.js.map +1 -1
- package/dist/esm/entities/EntityMetadata.js +11 -5
- package/dist/esm/entities/EntityMetadata.js.map +1 -1
- package/dist/esm/entities/EntityStore.js +9 -7
- package/dist/esm/entities/EntityStore.js.map +1 -1
- package/dist/esm/files/EntityFile.js +1 -1
- package/dist/esm/files/EntityFile.js.map +1 -1
- package/dist/esm/files/FileManager.js +5 -5
- package/dist/esm/files/FileManager.js.map +1 -1
- package/dist/esm/index.d.ts +6 -4
- package/dist/esm/index.js +2 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal.d.ts +3 -4
- package/dist/esm/internal.js +1 -2
- package/dist/esm/internal.js.map +1 -1
- package/dist/esm/persistence/PersistenceMetadata.d.ts +3 -6
- package/dist/esm/persistence/PersistenceMetadata.js +5 -6
- package/dist/esm/persistence/PersistenceMetadata.js.map +1 -1
- package/dist/esm/persistence/idb/IdbService.d.ts +3 -3
- package/dist/esm/persistence/idb/IdbService.js +0 -1
- package/dist/esm/persistence/idb/IdbService.js.map +1 -1
- package/dist/esm/persistence/idb/idbPersistence.d.ts +9 -10
- package/dist/esm/persistence/idb/idbPersistence.js +11 -4
- package/dist/esm/persistence/idb/idbPersistence.js.map +1 -1
- package/dist/esm/persistence/idb/metadata/IdbMetadataDb.d.ts +2 -2
- package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js +1 -1
- package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js.map +1 -1
- package/dist/esm/persistence/idb/queries/IdbDocumentDb.d.ts +3 -2
- package/dist/esm/persistence/idb/queries/IdbDocumentDb.js +16 -15
- package/dist/esm/persistence/idb/queries/IdbDocumentDb.js.map +1 -1
- package/dist/esm/persistence/idb/queries/migration/db.js +7 -0
- package/dist/esm/persistence/idb/queries/migration/db.js.map +1 -1
- package/dist/esm/persistence/idb/util.js +27 -17
- package/dist/esm/persistence/idb/util.js.map +1 -1
- package/dist/esm/persistence/interfaces.d.ts +8 -8
- package/dist/esm/persistence/migration/engine.d.ts +5 -3
- package/dist/esm/persistence/migration/engine.js +23 -14
- package/dist/esm/persistence/migration/engine.js.map +1 -1
- package/dist/esm/persistence/migration/finalize.d.ts +5 -3
- package/dist/esm/persistence/migration/finalize.js +5 -4
- package/dist/esm/persistence/migration/finalize.js.map +1 -1
- package/dist/esm/persistence/migration/migrate.d.ts +8 -5
- package/dist/esm/persistence/migration/migrate.js +10 -4
- package/dist/esm/persistence/migration/migrate.js.map +1 -1
- package/dist/esm/persistence/persistence.d.ts +9 -2
- package/dist/esm/persistence/persistence.js +65 -32
- package/dist/esm/persistence/persistence.js.map +1 -1
- package/dist/esm/queries/FindAllQuery.js +1 -1
- package/dist/esm/queries/FindAllQuery.js.map +1 -1
- package/dist/esm/queries/FindInfiniteQuery.js +2 -2
- package/dist/esm/queries/FindInfiniteQuery.js.map +1 -1
- package/dist/esm/queries/FindOneQuery.js +1 -1
- package/dist/esm/queries/FindOneQuery.js.map +1 -1
- package/dist/esm/queries/FindPageQuery.js +1 -1
- package/dist/esm/queries/FindPageQuery.js.map +1 -1
- package/dist/esm/sync/PresenceManager.d.ts +2 -2
- package/dist/esm/sync/PresenceManager.js +5 -2
- package/dist/esm/sync/PresenceManager.js.map +1 -1
- package/dist/esm/sync/PushPullSync.js +4 -4
- package/dist/esm/sync/PushPullSync.js.map +1 -1
- package/dist/esm/sync/Sync.d.ts +2 -2
- package/dist/esm/sync/Sync.js +17 -14
- package/dist/esm/sync/Sync.js.map +1 -1
- package/dist/esm/sync/WebSocketSync.js +12 -7
- package/dist/esm/sync/WebSocketSync.js.map +1 -1
- package/dist/esm/sync/serviceWorker.d.ts +2 -2
- package/dist/esm/sync/serviceWorker.js +3 -4
- package/dist/esm/sync/serviceWorker.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/fixtures/testStorage.ts +4 -8
- package/src/__tests__/queries.test.ts +3 -5
- package/src/__tests__/schema.test.ts +3 -3
- package/src/client/Client.ts +50 -34
- package/src/context/Time.ts +2 -2
- package/src/context/context.ts +189 -17
- package/src/entities/Entity.test.ts +0 -1
- package/src/entities/EntityMetadata.ts +16 -5
- package/src/entities/EntityStore.ts +14 -10
- package/src/files/EntityFile.ts +1 -1
- package/src/files/FileManager.ts +5 -5
- package/src/index.ts +6 -10
- package/src/internal.ts +10 -11
- package/src/persistence/PersistenceMetadata.ts +9 -11
- package/src/persistence/idb/IdbService.ts +2 -3
- package/src/persistence/idb/idbPersistence.ts +25 -19
- package/src/persistence/idb/metadata/IdbMetadataDb.ts +3 -3
- package/src/persistence/idb/queries/IdbDocumentDb.ts +31 -17
- package/src/persistence/idb/queries/migration/db.ts +10 -0
- package/src/persistence/idb/util.ts +46 -24
- package/src/persistence/interfaces.ts +21 -12
- package/src/persistence/migration/engine.ts +33 -18
- package/src/persistence/migration/finalize.ts +11 -5
- package/src/persistence/migration/migrate.ts +15 -8
- package/src/persistence/persistence.ts +78 -67
- package/src/queries/FindAllQuery.ts +3 -1
- package/src/queries/FindInfiniteQuery.ts +6 -2
- package/src/queries/FindOneQuery.ts +3 -1
- package/src/queries/FindPageQuery.ts +3 -1
- package/src/sync/PresenceManager.ts +10 -7
- package/src/sync/PushPullSync.ts +8 -6
- package/src/sync/Sync.ts +26 -16
- package/src/sync/WebSocketSync.ts +25 -9
- package/src/sync/serviceWorker.ts +4 -6
- package/dist/esm/client/ClientDescriptor.d.ts +0 -87
- package/dist/esm/client/ClientDescriptor.js +0 -133
- package/dist/esm/client/ClientDescriptor.js.map +0 -1
- package/dist/esm/persistence/migration/types.d.ts +0 -3
- package/dist/esm/persistence/migration/types.js +0 -2
- package/dist/esm/persistence/migration/types.js.map +0 -1
- package/src/client/ClientDescriptor.ts +0 -246
- package/src/persistence/migration/types.ts +0 -4
|
@@ -93,12 +93,12 @@ export class WebSocketSync
|
|
|
93
93
|
this.ctx.log('debug', 'Starting sync');
|
|
94
94
|
this.hasStartedSync = true;
|
|
95
95
|
this.synced = false;
|
|
96
|
+
const meta = await this.ctx.meta;
|
|
97
|
+
this.ctx.log('debug', 'HERE');
|
|
96
98
|
this.send(
|
|
97
|
-
await
|
|
98
|
-
this.presence.self,
|
|
99
|
-
),
|
|
99
|
+
await meta.messageCreator.createPresenceUpdate(this.presence.self),
|
|
100
100
|
);
|
|
101
|
-
this.send(await
|
|
101
|
+
this.send(await meta.messageCreator.createSyncStep1());
|
|
102
102
|
this.heartbeat.start();
|
|
103
103
|
}
|
|
104
104
|
this.emit('onlineChange', online);
|
|
@@ -122,7 +122,9 @@ export class WebSocketSync
|
|
|
122
122
|
if (message.ackThisNonce) {
|
|
123
123
|
// we need to send the ack to confirm we got the response
|
|
124
124
|
this.send(
|
|
125
|
-
await
|
|
125
|
+
await (
|
|
126
|
+
await this.ctx.meta
|
|
127
|
+
).messageCreator.createAck(message.ackThisNonce),
|
|
126
128
|
);
|
|
127
129
|
}
|
|
128
130
|
this.hasStartedSync = true;
|
|
@@ -179,7 +181,7 @@ export class WebSocketSync
|
|
|
179
181
|
};
|
|
180
182
|
|
|
181
183
|
private onError = (event: Event) => {
|
|
182
|
-
this.ctx.log('error', 'Sync socket error', event);
|
|
184
|
+
this.ctx.log('error', 'Sync socket error', event, event.target);
|
|
183
185
|
if (this.disposed) return;
|
|
184
186
|
this.reconnectScheduler.next();
|
|
185
187
|
|
|
@@ -187,7 +189,7 @@ export class WebSocketSync
|
|
|
187
189
|
};
|
|
188
190
|
|
|
189
191
|
private onClose = (event: CloseEvent) => {
|
|
190
|
-
this.ctx.log('info', 'Sync socket disconnected');
|
|
192
|
+
this.ctx.log('info', 'Sync socket disconnected', event.code);
|
|
191
193
|
this.onOnlineChange(false);
|
|
192
194
|
if (this.disposed) return;
|
|
193
195
|
this.reconnectScheduler.next();
|
|
@@ -209,7 +211,7 @@ export class WebSocketSync
|
|
|
209
211
|
};
|
|
210
212
|
|
|
211
213
|
private sendHeartbeat = async () => {
|
|
212
|
-
this.send(await this.ctx.meta.messageCreator.createHeartbeat());
|
|
214
|
+
this.send(await (await this.ctx.meta).messageCreator.createHeartbeat());
|
|
213
215
|
};
|
|
214
216
|
|
|
215
217
|
reconnect = () => {
|
|
@@ -227,11 +229,25 @@ export class WebSocketSync
|
|
|
227
229
|
};
|
|
228
230
|
|
|
229
231
|
send = (message: ClientMessage) => {
|
|
230
|
-
if (this.status !== 'active')
|
|
232
|
+
if (this.status !== 'active') {
|
|
233
|
+
this.ctx.log(
|
|
234
|
+
'debug',
|
|
235
|
+
'Ignoring outgoing message',
|
|
236
|
+
message.type,
|
|
237
|
+
'sync is not active',
|
|
238
|
+
);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
231
241
|
|
|
232
242
|
// wait until a sync has started before doing anything other than sync.
|
|
233
243
|
// new "op" messages can arrive before sync has started, so we need to wait
|
|
234
244
|
if (!this.hasStartedSync && !this.canSkipSyncWait(message)) {
|
|
245
|
+
this.ctx.log(
|
|
246
|
+
'debug',
|
|
247
|
+
'Ignoring outgoing message',
|
|
248
|
+
message.type,
|
|
249
|
+
'still waiting to begin initial sync',
|
|
250
|
+
);
|
|
235
251
|
return;
|
|
236
252
|
}
|
|
237
253
|
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Client } from '../client/Client.js';
|
|
2
2
|
|
|
3
|
-
export async function registerBackgroundSync(
|
|
3
|
+
export async function registerBackgroundSync(client: Client) {
|
|
4
4
|
self.addEventListener('periodicsync', (event: any) => {
|
|
5
5
|
if (event.tag === 'verdant-sync') {
|
|
6
6
|
// See the "Think before you sync" section for
|
|
7
7
|
// checks you could perform before syncing.
|
|
8
|
-
event.waitUntil(sync(
|
|
8
|
+
event.waitUntil(sync(client));
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
async function sync(
|
|
13
|
+
async function sync(client: Client) {
|
|
14
14
|
try {
|
|
15
|
-
const client = await clientDesc.open();
|
|
16
|
-
|
|
17
15
|
await client.sync.syncOnce();
|
|
18
16
|
} catch (err) {
|
|
19
17
|
console.error('Failed to sync:', err);
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Migration, StorageSchema } from '@verdant-web/common';
|
|
2
|
-
import { FileConfig, InitialContext, QueryConfig } from '../context/context.js';
|
|
3
|
-
import { VerdantLogger } from '../logger.js';
|
|
4
|
-
import { PersistenceImplementation } from '../persistence/interfaces.js';
|
|
5
|
-
import { ServerSyncOptions } from '../sync/Sync.js';
|
|
6
|
-
import { UndoHistory } from '../UndoHistory.js';
|
|
7
|
-
import { Client } from './Client.js';
|
|
8
|
-
export interface ClientDescriptorOptions<Presence = any, Profile = any> {
|
|
9
|
-
/** The schema used to create this client */
|
|
10
|
-
schema: StorageSchema<any>;
|
|
11
|
-
oldSchemas: StorageSchema<any>[];
|
|
12
|
-
/** Migrations, in order, to upgrade to each successive version of the schema */
|
|
13
|
-
migrations: Migration<any>[];
|
|
14
|
-
/** Provide a sync config to turn on synchronization with a server */
|
|
15
|
-
sync?: ServerSyncOptions<Profile, Presence>;
|
|
16
|
-
/**
|
|
17
|
-
* Namespaces are used to separate data from different clients in IndexedDB.
|
|
18
|
-
*/
|
|
19
|
-
namespace: string;
|
|
20
|
-
/**
|
|
21
|
-
* Provide your own UndoHistory to have a unified undo system across multiple
|
|
22
|
-
* clients if you so desire.
|
|
23
|
-
*/
|
|
24
|
-
undoHistory?: UndoHistory;
|
|
25
|
-
/**
|
|
26
|
-
* Provide a log function to log internal debug messages
|
|
27
|
-
*/
|
|
28
|
-
log?: VerdantLogger | false;
|
|
29
|
-
disableRebasing?: boolean;
|
|
30
|
-
rebaseTimeout?: number;
|
|
31
|
-
/**
|
|
32
|
-
* Provide a specific schema number to override the schema version
|
|
33
|
-
* in the database. This is useful for testing migrations or recovering
|
|
34
|
-
* from a mistakenly deployed incorrect schema. A specific version is required
|
|
35
|
-
* so that you don't leave this on accidentally for all new schemas.
|
|
36
|
-
*/
|
|
37
|
-
overrideSchemaConflict?: number;
|
|
38
|
-
/**
|
|
39
|
-
* Configuration for file management
|
|
40
|
-
*/
|
|
41
|
-
files?: FileConfig;
|
|
42
|
-
/**
|
|
43
|
-
* Override the default IndexedDB persistence implementation.
|
|
44
|
-
*/
|
|
45
|
-
persistence?: PersistenceImplementation;
|
|
46
|
-
/**
|
|
47
|
-
* Specify the environment dependencies needed for the client.
|
|
48
|
-
* Normally these are provided by the browser, but in other
|
|
49
|
-
* runtimes you may need to provide your own.
|
|
50
|
-
*/
|
|
51
|
-
environment?: Partial<InitialContext['environment']>;
|
|
52
|
-
/**
|
|
53
|
-
* Enables experimental WeakRef usage to cull documents
|
|
54
|
-
* from cache that aren't being used. This is a performance
|
|
55
|
-
* optimization which has been tested under all Verdant's test
|
|
56
|
-
* suites but I still want to keep testing it in the real world
|
|
57
|
-
* before turning it on.
|
|
58
|
-
*/
|
|
59
|
-
EXPERIMENTAL_weakRefs?: boolean;
|
|
60
|
-
/**
|
|
61
|
-
* Customize querying behavior.
|
|
62
|
-
*/
|
|
63
|
-
queries?: QueryConfig;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Since storage initialization is async, this class wraps the core
|
|
67
|
-
* Storage creation promise and exposes some metadata which can
|
|
68
|
-
* be useful immediately.
|
|
69
|
-
*/
|
|
70
|
-
export declare class ClientDescriptor<Presence = any, Profile = any, ClientImpl extends Client = Client<Presence, Profile>> {
|
|
71
|
-
private readonly init;
|
|
72
|
-
private readonly _readyPromise;
|
|
73
|
-
private resolveReady;
|
|
74
|
-
private rejectReady;
|
|
75
|
-
private _resolvedValue;
|
|
76
|
-
private _initializing;
|
|
77
|
-
private _namespace;
|
|
78
|
-
get namespace(): string;
|
|
79
|
-
constructor(init: ClientDescriptorOptions<Presence, Profile>);
|
|
80
|
-
private initialize;
|
|
81
|
-
get current(): ClientImpl | undefined;
|
|
82
|
-
get readyPromise(): Promise<ClientImpl>;
|
|
83
|
-
get schema(): StorageSchema<any>;
|
|
84
|
-
open: () => Promise<ClientImpl>;
|
|
85
|
-
close: () => Promise<void>;
|
|
86
|
-
__dangerous__resetLocal: () => Promise<void>;
|
|
87
|
-
}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { EventSubscriber, HybridLogicalClockTimestampProvider, PatchCreator, VerdantError, } from '@verdant-web/common';
|
|
2
|
-
import { ShutdownHandler } from '../context/ShutdownHandler.js';
|
|
3
|
-
import { Time } from '../context/Time.js';
|
|
4
|
-
import { FakeWeakRef } from '../FakeWeakRef.js';
|
|
5
|
-
import { debugLogger, noLogger } from '../logger.js';
|
|
6
|
-
import { IdbPersistence } from '../persistence/idb/idbPersistence.js';
|
|
7
|
-
import { deleteAllDatabases } from '../persistence/idb/util.js';
|
|
8
|
-
import { initializePersistence } from '../persistence/persistence.js';
|
|
9
|
-
import { UndoHistory } from '../UndoHistory.js';
|
|
10
|
-
import { Client } from './Client.js';
|
|
11
|
-
/**
|
|
12
|
-
* Since storage initialization is async, this class wraps the core
|
|
13
|
-
* Storage creation promise and exposes some metadata which can
|
|
14
|
-
* be useful immediately.
|
|
15
|
-
*/
|
|
16
|
-
export class ClientDescriptor {
|
|
17
|
-
get namespace() {
|
|
18
|
-
return this._namespace;
|
|
19
|
-
}
|
|
20
|
-
constructor(init) {
|
|
21
|
-
this.init = init;
|
|
22
|
-
this._initializing = false;
|
|
23
|
-
this.initialize = async (init) => {
|
|
24
|
-
// if server-side and no alternative IndexedDB implementation was provided,
|
|
25
|
-
// we can't initialize the storage
|
|
26
|
-
if (typeof window === 'undefined' && !init.environment) {
|
|
27
|
-
throw new Error('A Verdant client was initialized in an environment without a global Window or `environment` configuration. If you are using verdant in a server-rendered framework, you must enforce that all clients are initialized on the client-side, or you must provide some mock interface of the environment to the ClientDescriptor options.');
|
|
28
|
-
}
|
|
29
|
-
if (this._initializing || this._resolvedValue) {
|
|
30
|
-
return this._readyPromise;
|
|
31
|
-
}
|
|
32
|
-
this._initializing = true;
|
|
33
|
-
try {
|
|
34
|
-
const time = new Time(new HybridLogicalClockTimestampProvider(), init.schema.version);
|
|
35
|
-
const logger = init.log === false ? noLogger : init.log || debugLogger('🌿');
|
|
36
|
-
const environment = Object.assign(Object.assign({}, defaultBrowserEnvironment), init.environment);
|
|
37
|
-
let ctx = {
|
|
38
|
-
closing: false,
|
|
39
|
-
entityEvents: new EventSubscriber(),
|
|
40
|
-
globalEvents: new EventSubscriber(),
|
|
41
|
-
internalEvents: new EventSubscriber(),
|
|
42
|
-
log: logger,
|
|
43
|
-
migrations: init.migrations,
|
|
44
|
-
namespace: init.namespace,
|
|
45
|
-
originalNamespace: init.namespace,
|
|
46
|
-
schema: init.schema,
|
|
47
|
-
oldSchemas: init.oldSchemas,
|
|
48
|
-
time,
|
|
49
|
-
undoHistory: init.undoHistory || new UndoHistory(),
|
|
50
|
-
weakRef: (val) => init.EXPERIMENTAL_weakRefs
|
|
51
|
-
? new WeakRef(val)
|
|
52
|
-
: new FakeWeakRef(val),
|
|
53
|
-
patchCreator: new PatchCreator(() => time.now),
|
|
54
|
-
config: {
|
|
55
|
-
files: init.files,
|
|
56
|
-
sync: init.sync,
|
|
57
|
-
persistence: {
|
|
58
|
-
disableRebasing: init.disableRebasing,
|
|
59
|
-
rebaseTimeout: init.rebaseTimeout,
|
|
60
|
-
},
|
|
61
|
-
queries: init.queries,
|
|
62
|
-
},
|
|
63
|
-
persistence: init.persistence || new IdbPersistence(environment.indexedDB),
|
|
64
|
-
environment,
|
|
65
|
-
persistenceShutdownHandler: new ShutdownHandler(logger),
|
|
66
|
-
pauseRebasing: false,
|
|
67
|
-
getClient() {
|
|
68
|
-
throw new VerdantError(VerdantError.Code.Unexpected, undefined, 'Client not yet initialized. This is a Verdant bug, please report it.');
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
ctx.log('info', 'Initializing client', {
|
|
72
|
-
namespace: ctx.namespace,
|
|
73
|
-
version: init.schema.version,
|
|
74
|
-
persistence: ctx.persistence.name,
|
|
75
|
-
});
|
|
76
|
-
const context = await initializePersistence(ctx);
|
|
77
|
-
const client = new Client(context);
|
|
78
|
-
this.resolveReady(client);
|
|
79
|
-
this._resolvedValue = client;
|
|
80
|
-
return client;
|
|
81
|
-
}
|
|
82
|
-
catch (err) {
|
|
83
|
-
if (err instanceof Error) {
|
|
84
|
-
this.rejectReady(err);
|
|
85
|
-
throw err;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
throw new Error('Unknown error initializing storage');
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
finally {
|
|
92
|
-
this._initializing = false;
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
this.open = () => this.initialize(this.init);
|
|
96
|
-
this.close = async () => {
|
|
97
|
-
if (this._resolvedValue) {
|
|
98
|
-
this._resolvedValue.close();
|
|
99
|
-
}
|
|
100
|
-
if (this._initializing) {
|
|
101
|
-
(await this._readyPromise).close();
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
this.__dangerous__resetLocal = async () => {
|
|
105
|
-
await deleteAllDatabases(this.namespace, defaultBrowserEnvironment);
|
|
106
|
-
};
|
|
107
|
-
this._readyPromise = new Promise((resolve, reject) => {
|
|
108
|
-
this.resolveReady = resolve;
|
|
109
|
-
this.rejectReady = reject;
|
|
110
|
-
});
|
|
111
|
-
this._namespace = init.namespace;
|
|
112
|
-
}
|
|
113
|
-
get current() {
|
|
114
|
-
// exposing an immediate value if already resolved lets us
|
|
115
|
-
// skip the promise microtask when accessing this externally if
|
|
116
|
-
// the initialization has been completed.
|
|
117
|
-
return this._resolvedValue;
|
|
118
|
-
}
|
|
119
|
-
get readyPromise() {
|
|
120
|
-
return this._readyPromise;
|
|
121
|
-
}
|
|
122
|
-
get schema() {
|
|
123
|
-
return this.init.schema;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
const defaultBrowserEnvironment = {
|
|
127
|
-
WebSocket: typeof WebSocket !== 'undefined' ? WebSocket : undefined,
|
|
128
|
-
fetch: typeof window !== 'undefined' ? window.fetch.bind(window) : fetch,
|
|
129
|
-
indexedDB: typeof indexedDB !== 'undefined' ? indexedDB : undefined,
|
|
130
|
-
location: typeof window !== 'undefined' ? window.location : undefined,
|
|
131
|
-
history: typeof window !== 'undefined' ? window.history : undefined,
|
|
132
|
-
};
|
|
133
|
-
//# sourceMappingURL=ClientDescriptor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ClientDescriptor.js","sourceRoot":"","sources":["../../../src/client/ClientDescriptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/persistence/migration/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EventSubscriber,
|
|
3
|
-
HybridLogicalClockTimestampProvider,
|
|
4
|
-
Migration,
|
|
5
|
-
PatchCreator,
|
|
6
|
-
StorageSchema,
|
|
7
|
-
VerdantError,
|
|
8
|
-
} from '@verdant-web/common';
|
|
9
|
-
import {
|
|
10
|
-
Context,
|
|
11
|
-
FileConfig,
|
|
12
|
-
InitialContext,
|
|
13
|
-
QueryConfig,
|
|
14
|
-
} from '../context/context.js';
|
|
15
|
-
import { ShutdownHandler } from '../context/ShutdownHandler.js';
|
|
16
|
-
import { Time } from '../context/Time.js';
|
|
17
|
-
import { FakeWeakRef } from '../FakeWeakRef.js';
|
|
18
|
-
import { debugLogger, noLogger, VerdantLogger } from '../logger.js';
|
|
19
|
-
import { IdbPersistence } from '../persistence/idb/idbPersistence.js';
|
|
20
|
-
import { deleteAllDatabases } from '../persistence/idb/util.js';
|
|
21
|
-
import { PersistenceImplementation } from '../persistence/interfaces.js';
|
|
22
|
-
import { initializePersistence } from '../persistence/persistence.js';
|
|
23
|
-
import { ServerSyncOptions } from '../sync/Sync.js';
|
|
24
|
-
import { UndoHistory } from '../UndoHistory.js';
|
|
25
|
-
import { Client } from './Client.js';
|
|
26
|
-
|
|
27
|
-
export interface ClientDescriptorOptions<Presence = any, Profile = any> {
|
|
28
|
-
/** The schema used to create this client */
|
|
29
|
-
schema: StorageSchema<any>;
|
|
30
|
-
oldSchemas: StorageSchema<any>[];
|
|
31
|
-
/** Migrations, in order, to upgrade to each successive version of the schema */
|
|
32
|
-
migrations: Migration<any>[];
|
|
33
|
-
/** Provide a sync config to turn on synchronization with a server */
|
|
34
|
-
sync?: ServerSyncOptions<Profile, Presence>;
|
|
35
|
-
/**
|
|
36
|
-
* Namespaces are used to separate data from different clients in IndexedDB.
|
|
37
|
-
*/
|
|
38
|
-
namespace: string;
|
|
39
|
-
/**
|
|
40
|
-
* Provide your own UndoHistory to have a unified undo system across multiple
|
|
41
|
-
* clients if you so desire.
|
|
42
|
-
*/
|
|
43
|
-
undoHistory?: UndoHistory;
|
|
44
|
-
/**
|
|
45
|
-
* Provide a log function to log internal debug messages
|
|
46
|
-
*/
|
|
47
|
-
log?: VerdantLogger | false;
|
|
48
|
-
disableRebasing?: boolean;
|
|
49
|
-
rebaseTimeout?: number;
|
|
50
|
-
/**
|
|
51
|
-
* Provide a specific schema number to override the schema version
|
|
52
|
-
* in the database. This is useful for testing migrations or recovering
|
|
53
|
-
* from a mistakenly deployed incorrect schema. A specific version is required
|
|
54
|
-
* so that you don't leave this on accidentally for all new schemas.
|
|
55
|
-
*/
|
|
56
|
-
overrideSchemaConflict?: number;
|
|
57
|
-
/**
|
|
58
|
-
* Configuration for file management
|
|
59
|
-
*/
|
|
60
|
-
files?: FileConfig;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Override the default IndexedDB persistence implementation.
|
|
64
|
-
*/
|
|
65
|
-
persistence?: PersistenceImplementation;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Specify the environment dependencies needed for the client.
|
|
69
|
-
* Normally these are provided by the browser, but in other
|
|
70
|
-
* runtimes you may need to provide your own.
|
|
71
|
-
*/
|
|
72
|
-
environment?: Partial<InitialContext['environment']>;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Enables experimental WeakRef usage to cull documents
|
|
76
|
-
* from cache that aren't being used. This is a performance
|
|
77
|
-
* optimization which has been tested under all Verdant's test
|
|
78
|
-
* suites but I still want to keep testing it in the real world
|
|
79
|
-
* before turning it on.
|
|
80
|
-
*/
|
|
81
|
-
EXPERIMENTAL_weakRefs?: boolean;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Customize querying behavior.
|
|
85
|
-
*/
|
|
86
|
-
queries?: QueryConfig;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Since storage initialization is async, this class wraps the core
|
|
91
|
-
* Storage creation promise and exposes some metadata which can
|
|
92
|
-
* be useful immediately.
|
|
93
|
-
*/
|
|
94
|
-
export class ClientDescriptor<
|
|
95
|
-
Presence = any,
|
|
96
|
-
Profile = any,
|
|
97
|
-
ClientImpl extends Client = Client<Presence, Profile>,
|
|
98
|
-
> {
|
|
99
|
-
private readonly _readyPromise: Promise<ClientImpl>;
|
|
100
|
-
// assertions because these are defined by plucking them from
|
|
101
|
-
// Promise initializer
|
|
102
|
-
private resolveReady!: (storage: ClientImpl) => void;
|
|
103
|
-
private rejectReady!: (err: Error) => void;
|
|
104
|
-
private _resolvedValue: ClientImpl | undefined;
|
|
105
|
-
private _initializing = false;
|
|
106
|
-
private _namespace: string;
|
|
107
|
-
|
|
108
|
-
get namespace() {
|
|
109
|
-
return this._namespace;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
constructor(
|
|
113
|
-
private readonly init: ClientDescriptorOptions<Presence, Profile>,
|
|
114
|
-
) {
|
|
115
|
-
this._readyPromise = new Promise((resolve, reject) => {
|
|
116
|
-
this.resolveReady = resolve;
|
|
117
|
-
this.rejectReady = reject;
|
|
118
|
-
});
|
|
119
|
-
this._namespace = init.namespace;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
private initialize = async (init: ClientDescriptorOptions) => {
|
|
123
|
-
// if server-side and no alternative IndexedDB implementation was provided,
|
|
124
|
-
// we can't initialize the storage
|
|
125
|
-
if (typeof window === 'undefined' && !init.environment) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
'A Verdant client was initialized in an environment without a global Window or `environment` configuration. If you are using verdant in a server-rendered framework, you must enforce that all clients are initialized on the client-side, or you must provide some mock interface of the environment to the ClientDescriptor options.',
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (this._initializing || this._resolvedValue) {
|
|
132
|
-
return this._readyPromise;
|
|
133
|
-
}
|
|
134
|
-
this._initializing = true;
|
|
135
|
-
try {
|
|
136
|
-
const time = new Time(
|
|
137
|
-
new HybridLogicalClockTimestampProvider(),
|
|
138
|
-
init.schema.version,
|
|
139
|
-
);
|
|
140
|
-
const logger =
|
|
141
|
-
init.log === false ? noLogger : init.log || debugLogger('🌿');
|
|
142
|
-
const environment = {
|
|
143
|
-
...defaultBrowserEnvironment,
|
|
144
|
-
...init.environment,
|
|
145
|
-
};
|
|
146
|
-
let ctx: InitialContext = {
|
|
147
|
-
closing: false,
|
|
148
|
-
entityEvents: new EventSubscriber(),
|
|
149
|
-
globalEvents: new EventSubscriber(),
|
|
150
|
-
internalEvents: new EventSubscriber(),
|
|
151
|
-
log: logger,
|
|
152
|
-
migrations: init.migrations,
|
|
153
|
-
namespace: init.namespace,
|
|
154
|
-
originalNamespace: init.namespace,
|
|
155
|
-
schema: init.schema,
|
|
156
|
-
oldSchemas: init.oldSchemas,
|
|
157
|
-
time,
|
|
158
|
-
undoHistory: init.undoHistory || new UndoHistory(),
|
|
159
|
-
weakRef: (val) =>
|
|
160
|
-
init.EXPERIMENTAL_weakRefs
|
|
161
|
-
? new WeakRef(val)
|
|
162
|
-
: (new FakeWeakRef(val) as any),
|
|
163
|
-
patchCreator: new PatchCreator(() => time.now),
|
|
164
|
-
config: {
|
|
165
|
-
files: init.files,
|
|
166
|
-
sync: init.sync,
|
|
167
|
-
persistence: {
|
|
168
|
-
disableRebasing: init.disableRebasing,
|
|
169
|
-
rebaseTimeout: init.rebaseTimeout,
|
|
170
|
-
},
|
|
171
|
-
queries: init.queries,
|
|
172
|
-
},
|
|
173
|
-
persistence:
|
|
174
|
-
init.persistence || new IdbPersistence(environment.indexedDB),
|
|
175
|
-
environment,
|
|
176
|
-
persistenceShutdownHandler: new ShutdownHandler(logger),
|
|
177
|
-
pauseRebasing: false,
|
|
178
|
-
getClient() {
|
|
179
|
-
throw new VerdantError(
|
|
180
|
-
VerdantError.Code.Unexpected,
|
|
181
|
-
undefined,
|
|
182
|
-
'Client not yet initialized. This is a Verdant bug, please report it.',
|
|
183
|
-
);
|
|
184
|
-
},
|
|
185
|
-
};
|
|
186
|
-
ctx.log('info', 'Initializing client', {
|
|
187
|
-
namespace: ctx.namespace,
|
|
188
|
-
version: init.schema.version,
|
|
189
|
-
persistence: ctx.persistence.name,
|
|
190
|
-
});
|
|
191
|
-
const context = await initializePersistence(ctx);
|
|
192
|
-
const client = new Client(context) as ClientImpl;
|
|
193
|
-
this.resolveReady(client);
|
|
194
|
-
this._resolvedValue = client;
|
|
195
|
-
return client;
|
|
196
|
-
} catch (err) {
|
|
197
|
-
if (err instanceof Error) {
|
|
198
|
-
this.rejectReady(err as Error);
|
|
199
|
-
throw err;
|
|
200
|
-
} else {
|
|
201
|
-
throw new Error('Unknown error initializing storage');
|
|
202
|
-
}
|
|
203
|
-
} finally {
|
|
204
|
-
this._initializing = false;
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
get current() {
|
|
209
|
-
// exposing an immediate value if already resolved lets us
|
|
210
|
-
// skip the promise microtask when accessing this externally if
|
|
211
|
-
// the initialization has been completed.
|
|
212
|
-
return this._resolvedValue;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
get readyPromise() {
|
|
216
|
-
return this._readyPromise;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
get schema() {
|
|
220
|
-
return this.init.schema;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
open = () => this.initialize(this.init);
|
|
224
|
-
|
|
225
|
-
close = async () => {
|
|
226
|
-
if (this._resolvedValue) {
|
|
227
|
-
this._resolvedValue.close();
|
|
228
|
-
}
|
|
229
|
-
if (this._initializing) {
|
|
230
|
-
(await this._readyPromise).close();
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
__dangerous__resetLocal = async () => {
|
|
235
|
-
await deleteAllDatabases(this.namespace, defaultBrowserEnvironment);
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const defaultBrowserEnvironment: Context['environment'] = {
|
|
240
|
-
WebSocket: typeof WebSocket !== 'undefined' ? WebSocket : (undefined as any),
|
|
241
|
-
fetch: typeof window !== 'undefined' ? window.fetch.bind(window) : fetch!,
|
|
242
|
-
indexedDB: typeof indexedDB !== 'undefined' ? indexedDB : (undefined as any),
|
|
243
|
-
location:
|
|
244
|
-
typeof window !== 'undefined' ? window.location : (undefined as any),
|
|
245
|
-
history: typeof window !== 'undefined' ? window.history : (undefined as any),
|
|
246
|
-
};
|