@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.
Files changed (130) hide show
  1. package/dist/bundle/index.js +14 -12
  2. package/dist/bundle/index.js.map +4 -4
  3. package/dist/esm/__tests__/fixtures/testStorage.d.ts +1 -1
  4. package/dist/esm/__tests__/fixtures/testStorage.js +3 -3
  5. package/dist/esm/__tests__/fixtures/testStorage.js.map +1 -1
  6. package/dist/esm/__tests__/queries.test.js +3 -3
  7. package/dist/esm/__tests__/queries.test.js.map +1 -1
  8. package/dist/esm/__tests__/schema.test.js +3 -3
  9. package/dist/esm/__tests__/schema.test.js.map +1 -1
  10. package/dist/esm/client/Client.d.ts +12 -10
  11. package/dist/esm/client/Client.js +40 -30
  12. package/dist/esm/client/Client.js.map +1 -1
  13. package/dist/esm/context/Time.d.ts +1 -1
  14. package/dist/esm/context/Time.js +1 -1
  15. package/dist/esm/context/Time.js.map +1 -1
  16. package/dist/esm/context/context.d.ts +84 -15
  17. package/dist/esm/context/context.js +98 -1
  18. package/dist/esm/context/context.js.map +1 -1
  19. package/dist/esm/entities/Entity.test.js +0 -1
  20. package/dist/esm/entities/Entity.test.js.map +1 -1
  21. package/dist/esm/entities/EntityMetadata.js +11 -5
  22. package/dist/esm/entities/EntityMetadata.js.map +1 -1
  23. package/dist/esm/entities/EntityStore.js +9 -7
  24. package/dist/esm/entities/EntityStore.js.map +1 -1
  25. package/dist/esm/files/EntityFile.js +1 -1
  26. package/dist/esm/files/EntityFile.js.map +1 -1
  27. package/dist/esm/files/FileManager.js +5 -5
  28. package/dist/esm/files/FileManager.js.map +1 -1
  29. package/dist/esm/index.d.ts +6 -4
  30. package/dist/esm/index.js +2 -3
  31. package/dist/esm/index.js.map +1 -1
  32. package/dist/esm/internal.d.ts +3 -4
  33. package/dist/esm/internal.js +1 -2
  34. package/dist/esm/internal.js.map +1 -1
  35. package/dist/esm/persistence/PersistenceMetadata.d.ts +3 -6
  36. package/dist/esm/persistence/PersistenceMetadata.js +5 -6
  37. package/dist/esm/persistence/PersistenceMetadata.js.map +1 -1
  38. package/dist/esm/persistence/idb/IdbService.d.ts +3 -3
  39. package/dist/esm/persistence/idb/IdbService.js +0 -1
  40. package/dist/esm/persistence/idb/IdbService.js.map +1 -1
  41. package/dist/esm/persistence/idb/idbPersistence.d.ts +9 -10
  42. package/dist/esm/persistence/idb/idbPersistence.js +11 -4
  43. package/dist/esm/persistence/idb/idbPersistence.js.map +1 -1
  44. package/dist/esm/persistence/idb/metadata/IdbMetadataDb.d.ts +2 -2
  45. package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js +1 -1
  46. package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js.map +1 -1
  47. package/dist/esm/persistence/idb/queries/IdbDocumentDb.d.ts +3 -2
  48. package/dist/esm/persistence/idb/queries/IdbDocumentDb.js +16 -15
  49. package/dist/esm/persistence/idb/queries/IdbDocumentDb.js.map +1 -1
  50. package/dist/esm/persistence/idb/queries/migration/db.js +7 -0
  51. package/dist/esm/persistence/idb/queries/migration/db.js.map +1 -1
  52. package/dist/esm/persistence/idb/util.js +27 -17
  53. package/dist/esm/persistence/idb/util.js.map +1 -1
  54. package/dist/esm/persistence/interfaces.d.ts +8 -8
  55. package/dist/esm/persistence/migration/engine.d.ts +5 -3
  56. package/dist/esm/persistence/migration/engine.js +23 -14
  57. package/dist/esm/persistence/migration/engine.js.map +1 -1
  58. package/dist/esm/persistence/migration/finalize.d.ts +5 -3
  59. package/dist/esm/persistence/migration/finalize.js +5 -4
  60. package/dist/esm/persistence/migration/finalize.js.map +1 -1
  61. package/dist/esm/persistence/migration/migrate.d.ts +8 -5
  62. package/dist/esm/persistence/migration/migrate.js +10 -4
  63. package/dist/esm/persistence/migration/migrate.js.map +1 -1
  64. package/dist/esm/persistence/persistence.d.ts +9 -2
  65. package/dist/esm/persistence/persistence.js +65 -32
  66. package/dist/esm/persistence/persistence.js.map +1 -1
  67. package/dist/esm/queries/FindAllQuery.js +1 -1
  68. package/dist/esm/queries/FindAllQuery.js.map +1 -1
  69. package/dist/esm/queries/FindInfiniteQuery.js +2 -2
  70. package/dist/esm/queries/FindInfiniteQuery.js.map +1 -1
  71. package/dist/esm/queries/FindOneQuery.js +1 -1
  72. package/dist/esm/queries/FindOneQuery.js.map +1 -1
  73. package/dist/esm/queries/FindPageQuery.js +1 -1
  74. package/dist/esm/queries/FindPageQuery.js.map +1 -1
  75. package/dist/esm/sync/PresenceManager.d.ts +2 -2
  76. package/dist/esm/sync/PresenceManager.js +5 -2
  77. package/dist/esm/sync/PresenceManager.js.map +1 -1
  78. package/dist/esm/sync/PushPullSync.js +4 -4
  79. package/dist/esm/sync/PushPullSync.js.map +1 -1
  80. package/dist/esm/sync/Sync.d.ts +2 -2
  81. package/dist/esm/sync/Sync.js +17 -14
  82. package/dist/esm/sync/Sync.js.map +1 -1
  83. package/dist/esm/sync/WebSocketSync.js +12 -7
  84. package/dist/esm/sync/WebSocketSync.js.map +1 -1
  85. package/dist/esm/sync/serviceWorker.d.ts +2 -2
  86. package/dist/esm/sync/serviceWorker.js +3 -4
  87. package/dist/esm/sync/serviceWorker.js.map +1 -1
  88. package/package.json +2 -2
  89. package/src/__tests__/fixtures/testStorage.ts +4 -8
  90. package/src/__tests__/queries.test.ts +3 -5
  91. package/src/__tests__/schema.test.ts +3 -3
  92. package/src/client/Client.ts +50 -34
  93. package/src/context/Time.ts +2 -2
  94. package/src/context/context.ts +189 -17
  95. package/src/entities/Entity.test.ts +0 -1
  96. package/src/entities/EntityMetadata.ts +16 -5
  97. package/src/entities/EntityStore.ts +14 -10
  98. package/src/files/EntityFile.ts +1 -1
  99. package/src/files/FileManager.ts +5 -5
  100. package/src/index.ts +6 -10
  101. package/src/internal.ts +10 -11
  102. package/src/persistence/PersistenceMetadata.ts +9 -11
  103. package/src/persistence/idb/IdbService.ts +2 -3
  104. package/src/persistence/idb/idbPersistence.ts +25 -19
  105. package/src/persistence/idb/metadata/IdbMetadataDb.ts +3 -3
  106. package/src/persistence/idb/queries/IdbDocumentDb.ts +31 -17
  107. package/src/persistence/idb/queries/migration/db.ts +10 -0
  108. package/src/persistence/idb/util.ts +46 -24
  109. package/src/persistence/interfaces.ts +21 -12
  110. package/src/persistence/migration/engine.ts +33 -18
  111. package/src/persistence/migration/finalize.ts +11 -5
  112. package/src/persistence/migration/migrate.ts +15 -8
  113. package/src/persistence/persistence.ts +78 -67
  114. package/src/queries/FindAllQuery.ts +3 -1
  115. package/src/queries/FindInfiniteQuery.ts +6 -2
  116. package/src/queries/FindOneQuery.ts +3 -1
  117. package/src/queries/FindPageQuery.ts +3 -1
  118. package/src/sync/PresenceManager.ts +10 -7
  119. package/src/sync/PushPullSync.ts +8 -6
  120. package/src/sync/Sync.ts +26 -16
  121. package/src/sync/WebSocketSync.ts +25 -9
  122. package/src/sync/serviceWorker.ts +4 -6
  123. package/dist/esm/client/ClientDescriptor.d.ts +0 -87
  124. package/dist/esm/client/ClientDescriptor.js +0 -133
  125. package/dist/esm/client/ClientDescriptor.js.map +0 -1
  126. package/dist/esm/persistence/migration/types.d.ts +0 -3
  127. package/dist/esm/persistence/migration/types.js +0 -2
  128. package/dist/esm/persistence/migration/types.js.map +0 -1
  129. package/src/client/ClientDescriptor.ts +0 -246
  130. 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 this.ctx.meta.messageCreator.createPresenceUpdate(
98
- this.presence.self,
99
- ),
99
+ await meta.messageCreator.createPresenceUpdate(this.presence.self),
100
100
  );
101
- this.send(await this.ctx.meta.messageCreator.createSyncStep1());
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 this.ctx.meta.messageCreator.createAck(message.ackThisNonce),
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') return;
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 { ClientDescriptor } from '../client/ClientDescriptor.js';
1
+ import type { Client } from '../client/Client.js';
2
2
 
3
- export async function registerBackgroundSync(clientDesc: ClientDescriptor) {
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(clientDesc));
8
+ event.waitUntil(sync(client));
9
9
  }
10
10
  });
11
11
  }
12
12
 
13
- async function sync(clientDesc: ClientDescriptor) {
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,3 +0,0 @@
1
- import { Context } from '../../context/context.js';
2
- /** During migration, only a partial context is available */
3
- export type OpenDocumentDbContext = Omit<Context, 'documents' | 'files'>;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -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
- };
@@ -1,4 +0,0 @@
1
- import { Context } from '../../context/context.js';
2
-
3
- /** During migration, only a partial context is available */
4
- export type OpenDocumentDbContext = Omit<Context, 'documents' | 'files'>;