@verdant-web/store 3.12.0 → 4.0.0-next.0
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 +11 -13
- package/dist/bundle/index.js.map +4 -4
- package/dist/esm/__tests__/batching.test.js +5 -5
- package/dist/esm/__tests__/batching.test.js.map +1 -1
- package/dist/esm/__tests__/entities.test.js +1 -1
- package/dist/esm/__tests__/entities.test.js.map +1 -1
- package/dist/esm/__tests__/fixtures/testStorage.d.ts +1 -3
- 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.map +1 -1
- package/dist/esm/backup.d.ts +3 -4
- package/dist/esm/backup.js.map +1 -1
- package/dist/esm/client/Client.d.ts +28 -33
- package/dist/esm/client/Client.js +50 -161
- package/dist/esm/client/Client.js.map +1 -1
- package/dist/esm/client/ClientDescriptor.d.ts +8 -11
- package/dist/esm/client/ClientDescriptor.js +39 -141
- package/dist/esm/client/ClientDescriptor.js.map +1 -1
- package/dist/esm/context/Time.d.ts +13 -0
- package/dist/esm/context/Time.js +27 -0
- package/dist/esm/context/Time.js.map +1 -0
- package/dist/esm/context/context.d.ts +170 -0
- package/dist/esm/{context.js.map → context/context.js.map} +1 -1
- package/dist/esm/entities/DocumentManager.js.map +1 -1
- package/dist/esm/entities/Entity.d.ts +4 -5
- package/dist/esm/entities/Entity.js +5 -3
- package/dist/esm/entities/Entity.js.map +1 -1
- package/dist/esm/entities/Entity.test.js +4 -3
- package/dist/esm/entities/Entity.test.js.map +1 -1
- package/dist/esm/entities/EntityCache.d.ts +0 -3
- package/dist/esm/entities/EntityCache.js +0 -9
- package/dist/esm/entities/EntityCache.js.map +1 -1
- package/dist/esm/entities/EntityMetadata.d.ts +1 -1
- package/dist/esm/entities/EntityMetadata.js +6 -5
- package/dist/esm/entities/EntityMetadata.js.map +1 -1
- package/dist/esm/entities/EntityStore.d.ts +2 -6
- package/dist/esm/entities/EntityStore.js +22 -16
- package/dist/esm/entities/EntityStore.js.map +1 -1
- package/dist/esm/entities/OperationBatcher.d.ts +2 -5
- package/dist/esm/entities/OperationBatcher.js +9 -7
- package/dist/esm/entities/OperationBatcher.js.map +1 -1
- package/dist/esm/entities/types.d.ts +1 -1
- package/dist/esm/errors.d.ts +8 -0
- package/dist/esm/errors.js +12 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/files/EntityFile.d.ts +6 -3
- package/dist/esm/files/EntityFile.js +22 -19
- package/dist/esm/files/EntityFile.js.map +1 -1
- package/dist/esm/files/FileManager.d.ts +8 -39
- package/dist/esm/files/FileManager.js +15 -170
- package/dist/esm/files/FileManager.js.map +1 -1
- package/dist/esm/files/utils.d.ts +0 -1
- package/dist/esm/files/utils.js +0 -14
- package/dist/esm/files/utils.js.map +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{metadata → persistence}/MessageCreator.d.ts +5 -6
- package/dist/esm/{metadata → persistence}/MessageCreator.js +31 -38
- package/dist/esm/persistence/MessageCreator.js.map +1 -0
- package/dist/esm/persistence/PersistenceFiles.d.ts +48 -0
- package/dist/esm/persistence/PersistenceFiles.js +160 -0
- package/dist/esm/persistence/PersistenceFiles.js.map +1 -0
- package/dist/esm/persistence/PersistenceMetadata.d.ts +69 -0
- package/dist/esm/persistence/PersistenceMetadata.js +302 -0
- package/dist/esm/persistence/PersistenceMetadata.js.map +1 -0
- package/dist/esm/persistence/PersistenceQueries.d.ts +34 -0
- package/dist/esm/persistence/PersistenceQueries.js +15 -0
- package/dist/esm/persistence/PersistenceQueries.js.map +1 -0
- package/dist/esm/persistence/PersistenceRebaser.d.ts +32 -0
- package/dist/esm/persistence/PersistenceRebaser.js +120 -0
- package/dist/esm/persistence/PersistenceRebaser.js.map +1 -0
- package/dist/esm/{IDBService.d.ts → persistence/idb/IdbService.d.ts} +9 -7
- package/dist/esm/{IDBService.js → persistence/idb/IdbService.js} +29 -8
- package/dist/esm/persistence/idb/IdbService.js.map +1 -0
- package/dist/esm/persistence/idb/files/IdbPersistenceFileDb.d.ts +58 -0
- package/dist/esm/{files/FileStorage.js → persistence/idb/files/IdbPersistenceFileDb.js} +85 -50
- package/dist/esm/persistence/idb/files/IdbPersistenceFileDb.js.map +1 -0
- package/dist/esm/persistence/idb/idbPersistence.d.ts +19 -0
- package/dist/esm/persistence/idb/idbPersistence.js +80 -0
- package/dist/esm/persistence/idb/idbPersistence.js.map +1 -0
- package/dist/esm/persistence/idb/metadata/IdbMetadataDb.d.ts +72 -0
- package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js +235 -0
- package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js.map +1 -0
- package/dist/esm/{metadata → persistence/idb/metadata}/openMetadataDatabase.d.ts +3 -1
- package/dist/esm/{metadata → persistence/idb/metadata}/openMetadataDatabase.js +12 -3
- package/dist/esm/persistence/idb/metadata/openMetadataDatabase.js.map +1 -0
- package/dist/esm/persistence/idb/queries/IdbQueryDb.d.ts +41 -0
- package/dist/esm/persistence/idb/queries/IdbQueryDb.js +174 -0
- package/dist/esm/persistence/idb/queries/IdbQueryDb.js.map +1 -0
- package/dist/esm/{migration → persistence/idb/queries/migration}/db.d.ts +1 -1
- package/dist/esm/{migration → persistence/idb/queries/migration}/db.js +10 -48
- package/dist/esm/persistence/idb/queries/migration/db.js.map +1 -0
- package/dist/esm/persistence/idb/queries/migration/engine.d.ts +12 -0
- package/dist/esm/{migration → persistence/idb/queries/migration}/engine.js +29 -46
- package/dist/esm/persistence/idb/queries/migration/engine.js.map +1 -0
- package/dist/esm/{migration → persistence/idb/queries/migration}/migrations.d.ts +1 -3
- package/dist/esm/{migration → persistence/idb/queries/migration}/migrations.js +11 -10
- package/dist/esm/persistence/idb/queries/migration/migrations.js.map +1 -0
- package/dist/esm/{migration → persistence/idb/queries/migration}/openQueryDatabase.d.ts +1 -3
- package/dist/esm/{migration → persistence/idb/queries/migration}/openQueryDatabase.js +4 -7
- package/dist/esm/persistence/idb/queries/migration/openQueryDatabase.js.map +1 -0
- package/dist/esm/{migration → persistence/idb/queries/migration}/paths.js +2 -2
- package/dist/esm/persistence/idb/queries/migration/paths.js.map +1 -0
- package/dist/esm/persistence/idb/queries/migration/paths.test.js.map +1 -0
- package/dist/esm/persistence/idb/queries/migration/types.d.ts +6 -0
- package/dist/esm/persistence/idb/queries/migration/types.js.map +1 -0
- package/dist/esm/persistence/idb/queries/ranges.d.ts +2 -0
- package/dist/esm/persistence/idb/queries/ranges.js +66 -0
- package/dist/esm/persistence/idb/queries/ranges.js.map +1 -0
- package/dist/esm/{idb.d.ts → persistence/idb/util.d.ts} +11 -0
- package/dist/esm/{idb.js → persistence/idb/util.js} +58 -1
- package/dist/esm/persistence/idb/util.js.map +1 -0
- package/dist/esm/persistence/interfaces.d.ts +181 -0
- package/dist/esm/persistence/interfaces.js +2 -0
- package/dist/esm/persistence/interfaces.js.map +1 -0
- package/dist/esm/persistence/persistence.d.ts +4 -0
- package/dist/esm/persistence/persistence.js +126 -0
- package/dist/esm/persistence/persistence.js.map +1 -0
- package/dist/esm/queries/BaseQuery.d.ts +2 -1
- package/dist/esm/queries/BaseQuery.js +3 -0
- package/dist/esm/queries/BaseQuery.js.map +1 -1
- package/dist/esm/queries/CollectionQueries.d.ts +1 -1
- package/dist/esm/queries/FindAllQuery.js +1 -3
- package/dist/esm/queries/FindAllQuery.js.map +1 -1
- package/dist/esm/queries/FindInfiniteQuery.js +2 -5
- package/dist/esm/queries/FindInfiniteQuery.js.map +1 -1
- package/dist/esm/queries/FindOneQuery.js +1 -3
- package/dist/esm/queries/FindOneQuery.js.map +1 -1
- package/dist/esm/queries/FindPageQuery.js +1 -3
- package/dist/esm/queries/FindPageQuery.js.map +1 -1
- package/dist/esm/queries/QueryCache.d.ts +1 -1
- package/dist/esm/queries/QueryCache.js +4 -0
- package/dist/esm/queries/QueryCache.js.map +1 -1
- package/dist/esm/sync/FileSync.d.ts +23 -8
- package/dist/esm/sync/FileSync.js +76 -28
- package/dist/esm/sync/FileSync.js.map +1 -1
- package/dist/esm/sync/PresenceManager.d.ts +4 -3
- package/dist/esm/sync/PresenceManager.js +2 -2
- package/dist/esm/sync/PresenceManager.js.map +1 -1
- package/dist/esm/sync/PushPullSync.d.ts +4 -6
- package/dist/esm/sync/PushPullSync.js +13 -12
- package/dist/esm/sync/PushPullSync.js.map +1 -1
- package/dist/esm/sync/Sync.d.ts +9 -11
- package/dist/esm/sync/Sync.js +34 -29
- package/dist/esm/sync/Sync.js.map +1 -1
- package/dist/esm/sync/WebSocketSync.d.ts +4 -6
- package/dist/esm/sync/WebSocketSync.js +20 -22
- package/dist/esm/sync/WebSocketSync.js.map +1 -1
- package/dist/esm/utils/Disposable.d.ts +5 -2
- package/dist/esm/utils/Disposable.js +3 -2
- package/dist/esm/utils/Disposable.js.map +1 -1
- package/dist/esm/utils/wip.d.ts +2 -0
- package/dist/esm/utils/wip.js +5 -0
- package/dist/esm/utils/wip.js.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/batching.test.ts +6 -6
- package/src/__tests__/entities.test.ts +1 -1
- package/src/__tests__/fixtures/testStorage.ts +2 -10
- package/src/__tests__/queries.test.ts +1 -1
- package/src/backup.ts +3 -4
- package/src/client/Client.ts +69 -226
- package/src/client/ClientDescriptor.ts +53 -184
- package/src/context/Time.ts +35 -0
- package/src/context/context.ts +200 -0
- package/src/entities/DocumentManager.ts +0 -3
- package/src/entities/Entity.test.ts +9 -9
- package/src/entities/Entity.ts +6 -12
- package/src/entities/EntityCache.ts +0 -9
- package/src/entities/EntityMetadata.ts +4 -4
- package/src/entities/EntityStore.ts +26 -29
- package/src/entities/OperationBatcher.ts +9 -11
- package/src/entities/types.ts +1 -1
- package/src/errors.ts +13 -0
- package/src/files/EntityFile.ts +16 -5
- package/src/files/FileManager.ts +18 -245
- package/src/files/utils.ts +0 -15
- package/src/index.ts +2 -1
- package/src/{metadata → persistence}/MessageCreator.ts +46 -36
- package/src/persistence/PersistenceFiles.ts +227 -0
- package/src/persistence/PersistenceMetadata.ts +425 -0
- package/src/persistence/PersistenceQueries.ts +22 -0
- package/src/persistence/PersistenceRebaser.ts +171 -0
- package/src/{IDBService.ts → persistence/idb/IdbService.ts} +45 -12
- package/src/{files/FileStorage.ts → persistence/idb/files/IdbPersistenceFileDb.ts} +128 -86
- package/src/persistence/idb/idbPersistence.ts +116 -0
- package/src/persistence/idb/metadata/IdbMetadataDb.ts +460 -0
- package/src/{metadata → persistence/idb/metadata}/openMetadataDatabase.ts +21 -4
- package/src/persistence/idb/queries/IdbQueryDb.ts +251 -0
- package/src/{migration → persistence/idb/queries/migration}/db.ts +18 -72
- package/src/{migration → persistence/idb/queries/migration}/engine.ts +39 -62
- package/src/{migration → persistence/idb/queries/migration}/migrations.ts +13 -18
- package/src/{migration → persistence/idb/queries/migration}/openQueryDatabase.ts +5 -14
- package/src/{migration → persistence/idb/queries/migration}/paths.ts +4 -3
- package/src/persistence/idb/queries/migration/types.ts +8 -0
- package/src/persistence/idb/queries/ranges.ts +107 -0
- package/src/{idb.ts → persistence/idb/util.ts} +75 -0
- package/src/persistence/interfaces.ts +240 -0
- package/src/persistence/persistence.ts +223 -0
- package/src/queries/BaseQuery.ts +5 -1
- package/src/queries/CollectionQueries.ts +2 -2
- package/src/queries/FindAllQuery.ts +1 -3
- package/src/queries/FindInfiniteQuery.ts +2 -5
- package/src/queries/FindOneQuery.ts +1 -3
- package/src/queries/FindPageQuery.ts +1 -3
- package/src/queries/QueryCache.ts +20 -1
- package/src/sync/FileSync.ts +93 -30
- package/src/sync/PresenceManager.ts +5 -7
- package/src/sync/PushPullSync.ts +23 -19
- package/src/sync/Sync.ts +45 -36
- package/src/sync/WebSocketSync.ts +41 -27
- package/src/utils/Disposable.ts +7 -4
- package/src/utils/wip.ts +5 -0
- package/dist/esm/IDBService.js.map +0 -1
- package/dist/esm/__tests__/legacyOids.test.d.ts +0 -1
- package/dist/esm/__tests__/legacyOids.test.js +0 -352
- package/dist/esm/__tests__/legacyOids.test.js.map +0 -1
- package/dist/esm/context.d.ts +0 -45
- package/dist/esm/files/FileStorage.d.ts +0 -47
- package/dist/esm/files/FileStorage.js.map +0 -1
- package/dist/esm/idb.js.map +0 -1
- package/dist/esm/metadata/AckInfoStore.d.ts +0 -10
- package/dist/esm/metadata/AckInfoStore.js +0 -22
- package/dist/esm/metadata/AckInfoStore.js.map +0 -1
- package/dist/esm/metadata/BaselinesStore.d.ts +0 -40
- package/dist/esm/metadata/BaselinesStore.js +0 -102
- package/dist/esm/metadata/BaselinesStore.js.map +0 -1
- package/dist/esm/metadata/LocalReplicaStore.d.ts +0 -19
- package/dist/esm/metadata/LocalReplicaStore.js +0 -56
- package/dist/esm/metadata/LocalReplicaStore.js.map +0 -1
- package/dist/esm/metadata/MessageCreator.js.map +0 -1
- package/dist/esm/metadata/Metadata.d.ts +0 -146
- package/dist/esm/metadata/Metadata.js +0 -452
- package/dist/esm/metadata/Metadata.js.map +0 -1
- package/dist/esm/metadata/OperationsStore.d.ts +0 -62
- package/dist/esm/metadata/OperationsStore.js +0 -175
- package/dist/esm/metadata/OperationsStore.js.map +0 -1
- package/dist/esm/metadata/SchemaStore.d.ts +0 -9
- package/dist/esm/metadata/SchemaStore.js +0 -35
- package/dist/esm/metadata/SchemaStore.js.map +0 -1
- package/dist/esm/metadata/openMetadataDatabase.js.map +0 -1
- package/dist/esm/migration/db.js.map +0 -1
- package/dist/esm/migration/engine.d.ts +0 -15
- package/dist/esm/migration/engine.js.map +0 -1
- package/dist/esm/migration/errors.d.ts +0 -5
- package/dist/esm/migration/errors.js +0 -8
- package/dist/esm/migration/errors.js.map +0 -1
- package/dist/esm/migration/migrations.js.map +0 -1
- package/dist/esm/migration/openQueryDatabase.js.map +0 -1
- package/dist/esm/migration/openWIPDatabase.d.ts +0 -11
- package/dist/esm/migration/openWIPDatabase.js +0 -65
- package/dist/esm/migration/openWIPDatabase.js.map +0 -1
- package/dist/esm/migration/paths.js.map +0 -1
- package/dist/esm/migration/paths.test.js.map +0 -1
- package/dist/esm/migration/types.d.ts +0 -3
- package/dist/esm/migration/types.js.map +0 -1
- package/dist/esm/queries/QueryableStorage.d.ts +0 -20
- package/dist/esm/queries/QueryableStorage.js +0 -90
- package/dist/esm/queries/QueryableStorage.js.map +0 -1
- package/dist/esm/queries/dbQueries.d.ts +0 -22
- package/dist/esm/queries/dbQueries.js +0 -130
- package/dist/esm/queries/dbQueries.js.map +0 -1
- package/src/__tests__/legacyOids.test.ts +0 -375
- package/src/context.ts +0 -55
- package/src/metadata/AckInfoStore.ts +0 -30
- package/src/metadata/BaselinesStore.ts +0 -188
- package/src/metadata/LocalReplicaStore.ts +0 -79
- package/src/metadata/Metadata.ts +0 -685
- package/src/metadata/OperationsStore.ts +0 -332
- package/src/metadata/SchemaStore.ts +0 -47
- package/src/migration/errors.ts +0 -7
- package/src/migration/openWIPDatabase.ts +0 -97
- package/src/migration/types.ts +0 -4
- package/src/queries/QueryableStorage.ts +0 -122
- package/src/queries/dbQueries.ts +0 -161
- /package/dist/esm/{context.js → context/context.js} +0 -0
- /package/dist/esm/{migration → persistence/idb/queries/migration}/paths.d.ts +0 -0
- /package/dist/esm/{migration → persistence/idb/queries/migration}/paths.test.d.ts +0 -0
- /package/dist/esm/{migration → persistence/idb/queries/migration}/paths.test.js +0 -0
- /package/dist/esm/{migration → persistence/idb/queries/migration}/types.js +0 -0
- /package/src/{migration → persistence/idb/queries/migration}/paths.test.ts +0 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CollectionFilter,
|
|
3
|
+
createOid,
|
|
4
|
+
decomposeOid,
|
|
5
|
+
getIndexValues,
|
|
6
|
+
ObjectIdentifier,
|
|
7
|
+
} from '@verdant-web/common';
|
|
8
|
+
import { Context } from '../../../context/context.js';
|
|
9
|
+
import {
|
|
10
|
+
AbstractTransaction,
|
|
11
|
+
CommonQueryOptions,
|
|
12
|
+
PersistenceQueryDb,
|
|
13
|
+
QueryMode,
|
|
14
|
+
} from '../../interfaces.js';
|
|
15
|
+
import { IdbService } from '../IdbService.js';
|
|
16
|
+
import { getRange } from './ranges.js';
|
|
17
|
+
import { closeDatabase, getSizeOfObjectStore, isAbortError } from '../util.js';
|
|
18
|
+
|
|
19
|
+
export class IdbQueryDb extends IdbService implements PersistenceQueryDb {
|
|
20
|
+
private ctx;
|
|
21
|
+
constructor(db: IDBDatabase, context: Omit<Context, 'queries' | 'files'>) {
|
|
22
|
+
super(db, { log: context.log });
|
|
23
|
+
this.ctx = context;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
stats = async (): Promise<
|
|
27
|
+
Record<string, { count: number; size: number }>
|
|
28
|
+
> => {
|
|
29
|
+
const collectionNames = Object.keys(this.ctx.schema.collections);
|
|
30
|
+
const collections: Record<string, { count: number; size: number }> = {};
|
|
31
|
+
await Promise.all(
|
|
32
|
+
collectionNames.map(async (name) => {
|
|
33
|
+
const size = await getSizeOfObjectStore(this.db, name);
|
|
34
|
+
collections[name] = size;
|
|
35
|
+
}),
|
|
36
|
+
);
|
|
37
|
+
return collections;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
transaction = (opts: {
|
|
41
|
+
mode?: QueryMode;
|
|
42
|
+
storeNames: string[];
|
|
43
|
+
abort?: AbortSignal;
|
|
44
|
+
}): AbstractTransaction => {
|
|
45
|
+
return this.createTransaction(opts.storeNames, {
|
|
46
|
+
mode: opts.mode,
|
|
47
|
+
abort: opts.abort,
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
findOneOid = async (opts: {
|
|
52
|
+
collection: string;
|
|
53
|
+
index?: CollectionFilter;
|
|
54
|
+
}): Promise<ObjectIdentifier | null> => {
|
|
55
|
+
const result = await this.run<IDBCursorWithValue | null>(
|
|
56
|
+
opts.collection,
|
|
57
|
+
(store) => {
|
|
58
|
+
const source = opts.index?.where
|
|
59
|
+
? store.index(opts.index.where)
|
|
60
|
+
: store;
|
|
61
|
+
const direction = opts.index?.order === 'desc' ? 'prev' : 'next';
|
|
62
|
+
const range = getRange(this.ctx.schema, opts.collection, opts.index);
|
|
63
|
+
return source.openCursor(range, direction);
|
|
64
|
+
},
|
|
65
|
+
{ mode: 'readonly' },
|
|
66
|
+
);
|
|
67
|
+
if (result) {
|
|
68
|
+
return createOid(opts.collection, result.primaryKey.toString());
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
};
|
|
72
|
+
findAllOids = async ({
|
|
73
|
+
collection,
|
|
74
|
+
index,
|
|
75
|
+
offset,
|
|
76
|
+
limit,
|
|
77
|
+
}: {
|
|
78
|
+
collection: string;
|
|
79
|
+
index?: CollectionFilter;
|
|
80
|
+
limit?: number;
|
|
81
|
+
offset?: number;
|
|
82
|
+
}): Promise<{ result: ObjectIdentifier[]; hasNextPage: boolean }> => {
|
|
83
|
+
const tx = this.createTransaction([collection], { mode: 'readonly' });
|
|
84
|
+
const store = tx.objectStore(collection);
|
|
85
|
+
const source = index?.where ? store.index(index.where) : store;
|
|
86
|
+
const direction = index?.order === 'desc' ? 'prev' : 'next';
|
|
87
|
+
const range = getRange(this.ctx.schema, collection, index);
|
|
88
|
+
const request = source.openCursor(range, direction);
|
|
89
|
+
|
|
90
|
+
let hasNextPage = false;
|
|
91
|
+
const result = await new Promise<string[]>((resolve, reject) => {
|
|
92
|
+
let hasDoneOffset = !offset;
|
|
93
|
+
let visited = 0;
|
|
94
|
+
const results = new Set<ObjectIdentifier>();
|
|
95
|
+
|
|
96
|
+
request.onsuccess = () => {
|
|
97
|
+
visited++;
|
|
98
|
+
const cursor = request.result as IDBCursorWithValue | null;
|
|
99
|
+
if (!cursor) {
|
|
100
|
+
resolve(Array.from(results));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// first offset, if we have one. cursor opens at beginning.
|
|
105
|
+
if (offset && !hasDoneOffset) {
|
|
106
|
+
cursor.advance(offset);
|
|
107
|
+
hasDoneOffset = true;
|
|
108
|
+
// next iteration we begin adding results.
|
|
109
|
+
} else {
|
|
110
|
+
// add result to set, unless we have reached limit.
|
|
111
|
+
if (!limit || results.size < limit) {
|
|
112
|
+
results.add(createOid(collection, cursor.primaryKey.toString()));
|
|
113
|
+
}
|
|
114
|
+
// even if we reached limit, we keep going one more to check if there's
|
|
115
|
+
// a next page.
|
|
116
|
+
if (limit && visited > limit) {
|
|
117
|
+
hasNextPage = true;
|
|
118
|
+
// stop iteration here; we reached limit and we have next page
|
|
119
|
+
// info we need.
|
|
120
|
+
resolve(Array.from(results));
|
|
121
|
+
} else {
|
|
122
|
+
cursor.continue();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
request.onerror = () => {
|
|
128
|
+
if (request.error?.name === 'InvalidStateError') {
|
|
129
|
+
this.ctx.log(
|
|
130
|
+
'error',
|
|
131
|
+
`find query failed with InvalidStateError`,
|
|
132
|
+
request.error,
|
|
133
|
+
);
|
|
134
|
+
resolve([]);
|
|
135
|
+
} else if (request.error && isAbortError(request.error)) {
|
|
136
|
+
resolve([]);
|
|
137
|
+
} else {
|
|
138
|
+
reject(request.error);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
result,
|
|
145
|
+
hasNextPage,
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
saveEntities = async (
|
|
150
|
+
entities: { oid: ObjectIdentifier; getSnapshot: () => any }[],
|
|
151
|
+
opts?: CommonQueryOptions & { abort?: AbortSignal },
|
|
152
|
+
): Promise<void> => {
|
|
153
|
+
if (entities.length === 0) return;
|
|
154
|
+
|
|
155
|
+
let collections = Array.from(
|
|
156
|
+
new Set(entities.map((e) => decomposeOid(e.oid).collection)),
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const toRemove = collections.filter((c) => !this.ctx.schema.collections[c]);
|
|
160
|
+
if (toRemove.length > 0) {
|
|
161
|
+
this.ctx.log(
|
|
162
|
+
'warn',
|
|
163
|
+
`Ignoring entities from collections that no longer exist: ${toRemove.join(
|
|
164
|
+
', ',
|
|
165
|
+
)}`,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const withRemoved = new Set(collections);
|
|
169
|
+
toRemove.forEach((c) => withRemoved.delete(c));
|
|
170
|
+
collections = Array.from(withRemoved);
|
|
171
|
+
|
|
172
|
+
const options = {
|
|
173
|
+
transaction: this.createTransaction(collections, {
|
|
174
|
+
mode: 'readwrite',
|
|
175
|
+
abort: opts?.abort,
|
|
176
|
+
}),
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// FIXME: not test is making it to this line
|
|
180
|
+
|
|
181
|
+
await Promise.all(
|
|
182
|
+
entities.map(async (e) => {
|
|
183
|
+
const snapshot = e.getSnapshot();
|
|
184
|
+
try {
|
|
185
|
+
await this.saveDocument(e.oid, snapshot, options);
|
|
186
|
+
} catch (err) {
|
|
187
|
+
this.ctx.log(
|
|
188
|
+
'error',
|
|
189
|
+
`Error saving document ${e.oid} (${JSON.stringify(snapshot)})`,
|
|
190
|
+
err,
|
|
191
|
+
);
|
|
192
|
+
if (err instanceof Error) {
|
|
193
|
+
throw err;
|
|
194
|
+
} else {
|
|
195
|
+
throw new Error('Unknown error saving document');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}),
|
|
199
|
+
);
|
|
200
|
+
options.transaction.commit();
|
|
201
|
+
this.ctx.entityEvents.emit('collectionsChanged', collections);
|
|
202
|
+
for (const entity of entities) {
|
|
203
|
+
this.ctx.entityEvents.emit('documentChanged', entity.oid);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
reset = async (opts?: {
|
|
208
|
+
transaction?: AbstractTransaction;
|
|
209
|
+
}): Promise<void> => {
|
|
210
|
+
const names = Object.keys(this.ctx.schema.collections);
|
|
211
|
+
const tx =
|
|
212
|
+
(opts?.transaction as IDBTransaction) ||
|
|
213
|
+
this.createTransaction(names, { mode: 'readwrite' });
|
|
214
|
+
await Promise.all(
|
|
215
|
+
names.map((name) =>
|
|
216
|
+
this.run(name, (store) => store.clear(), { transaction: tx }),
|
|
217
|
+
),
|
|
218
|
+
);
|
|
219
|
+
this.ctx.entityEvents.emit('collectionsChanged', names);
|
|
220
|
+
this.ctx.log('info', '💨 Reset queryable storage');
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
dispose = () => {
|
|
224
|
+
return closeDatabase(this.db);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
private saveDocument = async (
|
|
228
|
+
oid: ObjectIdentifier,
|
|
229
|
+
doc: any,
|
|
230
|
+
{ transaction }: { transaction?: IDBTransaction },
|
|
231
|
+
) => {
|
|
232
|
+
this.ctx.log('debug', `Saving document indexes for querying ${oid}`);
|
|
233
|
+
const { collection, id } = decomposeOid(oid);
|
|
234
|
+
if (!doc) {
|
|
235
|
+
await this.run(collection, (store) => store.delete(id), {
|
|
236
|
+
mode: 'readwrite',
|
|
237
|
+
transaction,
|
|
238
|
+
});
|
|
239
|
+
this.ctx.log('debug', `Deleted document indexes for querying ${oid}`);
|
|
240
|
+
} else {
|
|
241
|
+
const schema = this.ctx.schema.collections[collection];
|
|
242
|
+
// no need to validate before storing; the entity's snapshot is already validated.
|
|
243
|
+
const indexes = getIndexValues(schema, doc);
|
|
244
|
+
await this.run(collection, (store) => store.put(indexes), {
|
|
245
|
+
mode: 'readwrite',
|
|
246
|
+
transaction,
|
|
247
|
+
});
|
|
248
|
+
this.ctx.log('debug', `Save complete for ${oid}`, indexes);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
@@ -1,48 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
globalIDB,
|
|
3
|
+
storeRequestPromise,
|
|
4
|
+
openDatabase as baseOpenDatabase,
|
|
5
|
+
getDocumentDbName,
|
|
6
|
+
} from '../../util.js';
|
|
2
7
|
import { OpenDocumentDbContext } from './types.js';
|
|
3
8
|
|
|
4
9
|
export async function getDatabaseVersion(
|
|
5
10
|
indexedDB: IDBFactory,
|
|
6
11
|
namespace: string,
|
|
7
|
-
version: number,
|
|
8
|
-
log?: (...args: any[]) => void,
|
|
9
12
|
): Promise<number> {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
) {
|
|
14
|
-
|
|
15
|
-
let database: IDBDatabase;
|
|
16
|
-
const request = indexedDB.open(
|
|
17
|
-
[namespace, 'collections'].join('_'),
|
|
18
|
-
version,
|
|
19
|
-
);
|
|
20
|
-
request.onupgradeneeded = async (event) => {
|
|
21
|
-
currentVersion = event.oldVersion;
|
|
22
|
-
const transaction = request.transaction!;
|
|
23
|
-
database = request.result;
|
|
24
|
-
transaction.abort();
|
|
25
|
-
};
|
|
26
|
-
request.onsuccess = (event) => {
|
|
27
|
-
resolve([request.result.version, request.result]);
|
|
28
|
-
};
|
|
29
|
-
request.onblocked = (event) => {
|
|
30
|
-
// retry if blocked
|
|
31
|
-
log?.('Database blocked, waiting...');
|
|
32
|
-
// setTimeout(() => {
|
|
33
|
-
// openAndGetVersion(resolve, reject);
|
|
34
|
-
// }, 200);
|
|
35
|
-
};
|
|
36
|
-
request.onerror = (event) => {
|
|
37
|
-
// FIXME: this fails if the code is older than the local database
|
|
38
|
-
resolve([currentVersion!, database!]);
|
|
39
|
-
};
|
|
13
|
+
const databaseName = getDocumentDbName(namespace);
|
|
14
|
+
const dbInfo = await indexedDB.databases();
|
|
15
|
+
const existingDb = dbInfo.find((info) => info.name === databaseName);
|
|
16
|
+
if (existingDb) {
|
|
17
|
+
return existingDb.version ?? 0;
|
|
40
18
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
);
|
|
44
|
-
await closeDatabase(db);
|
|
45
|
-
return currentVersion;
|
|
19
|
+
|
|
20
|
+
return 0;
|
|
46
21
|
}
|
|
47
22
|
|
|
48
23
|
/**
|
|
@@ -121,40 +96,11 @@ export async function openDatabase({
|
|
|
121
96
|
context: OpenDocumentDbContext;
|
|
122
97
|
}): Promise<IDBDatabase> {
|
|
123
98
|
context.log('debug', 'Opening database', namespace, 'at version', version);
|
|
124
|
-
const db = await
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
request.onupgradeneeded = async (event) => {
|
|
130
|
-
const transaction = request.transaction!;
|
|
131
|
-
transaction.abort();
|
|
132
|
-
|
|
133
|
-
context.log(
|
|
134
|
-
'error',
|
|
135
|
-
'Database upgrade needed, but not expected',
|
|
136
|
-
'Expected',
|
|
137
|
-
version,
|
|
138
|
-
'Got',
|
|
139
|
-
request.result.version,
|
|
140
|
-
);
|
|
141
|
-
reject(
|
|
142
|
-
request.error ||
|
|
143
|
-
new Error(
|
|
144
|
-
`Migration error: database version changed unexpectedly when reading current data. Expected ${version}, got ${request.result.version}`,
|
|
145
|
-
),
|
|
146
|
-
);
|
|
147
|
-
};
|
|
148
|
-
request.onsuccess = (event) => {
|
|
149
|
-
resolve(request.result);
|
|
150
|
-
};
|
|
151
|
-
request.onblocked = (event) => {
|
|
152
|
-
reject(new Error('Migration error: database blocked'));
|
|
153
|
-
};
|
|
154
|
-
request.onerror = (event) => {
|
|
155
|
-
reject(new Error('Migration error: database error'));
|
|
156
|
-
};
|
|
157
|
-
});
|
|
99
|
+
const db = await baseOpenDatabase(
|
|
100
|
+
getDocumentDbName(namespace),
|
|
101
|
+
version,
|
|
102
|
+
indexedDB,
|
|
103
|
+
);
|
|
158
104
|
|
|
159
105
|
db.addEventListener('versionchange', (event) => {
|
|
160
106
|
db.close();
|
|
@@ -10,25 +10,20 @@ import {
|
|
|
10
10
|
createOid,
|
|
11
11
|
diffToPatches,
|
|
12
12
|
getOid,
|
|
13
|
-
initialToPatches,
|
|
14
13
|
removeOidPropertiesFromAllSubObjects,
|
|
15
14
|
AuthorizationKey,
|
|
16
15
|
} from '@verdant-web/common';
|
|
17
|
-
import { Context } from '../context.js';
|
|
18
|
-
import { Metadata } from '../metadata/Metadata.js';
|
|
19
|
-
import { findAllOids, findOneOid } from '../queries/dbQueries.js';
|
|
20
16
|
import { OpenDocumentDbContext } from './types.js';
|
|
17
|
+
import { IdbQueryDb } from '../IdbQueryDb.js';
|
|
21
18
|
|
|
22
19
|
function getMigrationMutations({
|
|
23
20
|
migration,
|
|
24
|
-
meta,
|
|
25
|
-
getMigrationNow,
|
|
26
21
|
newOids,
|
|
22
|
+
ctx,
|
|
27
23
|
}: {
|
|
28
24
|
migration: Migration<any>;
|
|
29
25
|
newOids: string[];
|
|
30
|
-
|
|
31
|
-
meta: Metadata;
|
|
26
|
+
ctx: OpenDocumentDbContext;
|
|
32
27
|
}) {
|
|
33
28
|
return migration.allCollections.reduce((acc, collectionName) => {
|
|
34
29
|
acc[collectionName] = {
|
|
@@ -40,24 +35,22 @@ function getMigrationMutations({
|
|
|
40
35
|
const oid = createOid(collectionName, primaryKey);
|
|
41
36
|
newOids.push(oid);
|
|
42
37
|
|
|
43
|
-
await
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
await ctx.time.withMigrationTime(migration.version, () =>
|
|
39
|
+
ctx.meta.insertData({
|
|
40
|
+
operations: ctx.patchCreator.createInitialize(
|
|
41
|
+
doc,
|
|
42
|
+
oid,
|
|
43
|
+
options?.access,
|
|
44
|
+
),
|
|
45
|
+
isLocal: true,
|
|
46
46
|
}),
|
|
47
47
|
);
|
|
48
48
|
return doc;
|
|
49
49
|
},
|
|
50
50
|
delete: async (id: string) => {
|
|
51
51
|
const rootOid = createOid(collectionName, id);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return meta.insertLocalOperations(
|
|
55
|
-
allOids.map((oid) => ({
|
|
56
|
-
oid,
|
|
57
|
-
timestamp: getMigrationNow(),
|
|
58
|
-
data: { op: 'delete' },
|
|
59
|
-
authz,
|
|
60
|
-
})),
|
|
52
|
+
await ctx.time.withMigrationTime(migration.version, () =>
|
|
53
|
+
ctx.meta.deleteDocument(rootOid),
|
|
61
54
|
);
|
|
62
55
|
},
|
|
63
56
|
};
|
|
@@ -68,46 +61,46 @@ function getMigrationMutations({
|
|
|
68
61
|
function getMigrationQueries({
|
|
69
62
|
migration,
|
|
70
63
|
context,
|
|
71
|
-
|
|
64
|
+
queryDb,
|
|
72
65
|
}: {
|
|
73
66
|
migration: Migration<any>;
|
|
74
|
-
context:
|
|
75
|
-
|
|
67
|
+
context: OpenDocumentDbContext;
|
|
68
|
+
queryDb: IDBDatabase;
|
|
76
69
|
}) {
|
|
70
|
+
const queries = new IdbQueryDb(queryDb, context);
|
|
71
|
+
|
|
77
72
|
return migration.oldCollections.reduce((acc, collectionName) => {
|
|
78
73
|
acc[collectionName] = {
|
|
79
74
|
get: async (id: string) => {
|
|
80
75
|
const oid = createOid(collectionName, id);
|
|
81
|
-
const doc = await meta.getDocumentSnapshot(oid, {
|
|
76
|
+
const doc = await context.meta.getDocumentSnapshot(oid, {
|
|
82
77
|
// only get the snapshot up to the previous version (newer operations may have synced)
|
|
83
|
-
to:
|
|
78
|
+
to: context.time.nowWithVersion(migration.oldSchema.version),
|
|
84
79
|
});
|
|
85
80
|
return doc;
|
|
86
81
|
},
|
|
87
82
|
findOne: async (filter: CollectionFilter) => {
|
|
88
|
-
const oid = await findOneOid({
|
|
83
|
+
const oid = await queries.findOneOid({
|
|
89
84
|
collection: collectionName,
|
|
90
85
|
index: filter,
|
|
91
|
-
context,
|
|
92
86
|
});
|
|
93
87
|
if (!oid) return null;
|
|
94
|
-
const doc = await meta.getDocumentSnapshot(oid, {
|
|
88
|
+
const doc = await context.meta.getDocumentSnapshot(oid, {
|
|
95
89
|
// only get the snapshot up to the previous version (newer operations may have synced)
|
|
96
|
-
to:
|
|
90
|
+
to: context.time.nowWithVersion(migration.oldSchema.version),
|
|
97
91
|
});
|
|
98
92
|
return doc;
|
|
99
93
|
},
|
|
100
94
|
findAll: async (filter: CollectionFilter) => {
|
|
101
|
-
const oids = await findAllOids({
|
|
95
|
+
const { result: oids } = await queries.findAllOids({
|
|
102
96
|
collection: collectionName,
|
|
103
97
|
index: filter,
|
|
104
|
-
context,
|
|
105
98
|
});
|
|
106
99
|
const docs = await Promise.all(
|
|
107
100
|
oids.map((oid) =>
|
|
108
|
-
meta.getDocumentSnapshot(oid, {
|
|
101
|
+
context.meta.getDocumentSnapshot(oid, {
|
|
109
102
|
// only get the snapshot up to the previous version (newer operations may have synced)
|
|
110
|
-
to:
|
|
103
|
+
to: context.time.nowWithVersion(migration.oldSchema.version),
|
|
111
104
|
}),
|
|
112
105
|
),
|
|
113
106
|
);
|
|
@@ -119,41 +112,29 @@ function getMigrationQueries({
|
|
|
119
112
|
}
|
|
120
113
|
|
|
121
114
|
export function getMigrationEngine({
|
|
122
|
-
meta,
|
|
123
115
|
migration,
|
|
124
116
|
context,
|
|
117
|
+
queryDb,
|
|
125
118
|
}: {
|
|
126
119
|
log?: (...args: any[]) => void;
|
|
127
120
|
migration: Migration;
|
|
128
|
-
|
|
129
|
-
|
|
121
|
+
context: OpenDocumentDbContext;
|
|
122
|
+
queryDb: IDBDatabase;
|
|
130
123
|
}): MigrationEngine {
|
|
131
|
-
function getMigrationNow() {
|
|
132
|
-
return meta.time.zero(migration.version);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
124
|
const newOids = new Array<ObjectIdentifier>();
|
|
136
125
|
|
|
137
126
|
const queries = getMigrationQueries({
|
|
138
127
|
migration,
|
|
139
128
|
context,
|
|
140
|
-
|
|
129
|
+
queryDb,
|
|
141
130
|
});
|
|
142
131
|
const mutations = getMigrationMutations({
|
|
143
132
|
migration,
|
|
144
|
-
getMigrationNow,
|
|
145
133
|
newOids,
|
|
146
|
-
|
|
134
|
+
ctx: context,
|
|
147
135
|
});
|
|
148
136
|
const deleteCollection = async (collection: string) => {
|
|
149
|
-
|
|
150
|
-
return meta.insertLocalOperations(
|
|
151
|
-
allOids.map((oid) => ({
|
|
152
|
-
oid,
|
|
153
|
-
timestamp: getMigrationNow(),
|
|
154
|
-
data: { op: 'delete' },
|
|
155
|
-
})),
|
|
156
|
-
);
|
|
137
|
+
await context.meta.deleteCollection(collection);
|
|
157
138
|
};
|
|
158
139
|
const awaitables = new Array<Promise<any>>();
|
|
159
140
|
const engine: MigrationEngine = {
|
|
@@ -174,7 +155,7 @@ export function getMigrationEngine({
|
|
|
174
155
|
// when the snapshots themselves are derived from the same data...)
|
|
175
156
|
// maybe don't use the findAll query, and instead go a level
|
|
176
157
|
// lower to retain access to lower level data here?
|
|
177
|
-
const authz = await meta.getDocumentAuthz(rootOid);
|
|
158
|
+
const authz = await context.meta.getDocumentAuthz(rootOid);
|
|
178
159
|
const original = cloneDeep(doc);
|
|
179
160
|
// @ts-ignore - excessive type resolution
|
|
180
161
|
const newValue = await strategy(doc);
|
|
@@ -188,7 +169,7 @@ export function getMigrationEngine({
|
|
|
188
169
|
const patches = diffToPatches(
|
|
189
170
|
original,
|
|
190
171
|
newValue,
|
|
191
|
-
|
|
172
|
+
() => context.time.zeroWithVersion(migration.version),
|
|
192
173
|
undefined,
|
|
193
174
|
[],
|
|
194
175
|
{
|
|
@@ -197,7 +178,10 @@ export function getMigrationEngine({
|
|
|
197
178
|
},
|
|
198
179
|
);
|
|
199
180
|
if (patches.length > 0) {
|
|
200
|
-
await meta.
|
|
181
|
+
await context.meta.insertData({
|
|
182
|
+
operations: patches,
|
|
183
|
+
isLocal: true,
|
|
184
|
+
});
|
|
201
185
|
}
|
|
202
186
|
}
|
|
203
187
|
}),
|
|
@@ -211,18 +195,12 @@ export function getMigrationEngine({
|
|
|
211
195
|
}
|
|
212
196
|
|
|
213
197
|
export function getInitialMigrationEngine({
|
|
214
|
-
meta,
|
|
215
198
|
migration,
|
|
216
199
|
context,
|
|
217
200
|
}: {
|
|
218
201
|
context: OpenDocumentDbContext;
|
|
219
202
|
migration: Migration;
|
|
220
|
-
meta: Metadata;
|
|
221
203
|
}): MigrationEngine {
|
|
222
|
-
function getMigrationNow() {
|
|
223
|
-
return meta.time.zero(migration.version);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
204
|
const newOids = new Array<ObjectIdentifier>();
|
|
227
205
|
|
|
228
206
|
const queries = new Proxy({} as any, {
|
|
@@ -235,9 +213,8 @@ export function getInitialMigrationEngine({
|
|
|
235
213
|
|
|
236
214
|
const mutations = getMigrationMutations({
|
|
237
215
|
migration,
|
|
238
|
-
getMigrationNow,
|
|
239
216
|
newOids,
|
|
240
|
-
|
|
217
|
+
ctx: context,
|
|
241
218
|
});
|
|
242
219
|
const engine: MigrationEngine = {
|
|
243
220
|
log: context.log,
|
|
@@ -6,12 +6,11 @@ import {
|
|
|
6
6
|
getIndexValues,
|
|
7
7
|
getOidRoot,
|
|
8
8
|
} from '@verdant-web/common';
|
|
9
|
-
import {
|
|
10
|
-
import { ClientOperation } from '../metadata/OperationsStore.js';
|
|
9
|
+
import { ClientOperation } from '../../../interfaces.js';
|
|
11
10
|
import { acquireLock, openDatabase, upgradeDatabase } from './db.js';
|
|
12
11
|
import { getInitialMigrationEngine, getMigrationEngine } from './engine.js';
|
|
13
12
|
import { OpenDocumentDbContext } from './types.js';
|
|
14
|
-
import { closeDatabase } from '
|
|
13
|
+
import { closeDatabase } from '../../util.js';
|
|
15
14
|
|
|
16
15
|
const globalIDB =
|
|
17
16
|
typeof window !== 'undefined' ? window.indexedDB : (undefined as any);
|
|
@@ -19,13 +18,11 @@ const globalIDB =
|
|
|
19
18
|
export async function runMigrations({
|
|
20
19
|
context,
|
|
21
20
|
toRun,
|
|
22
|
-
meta,
|
|
23
21
|
indexedDB = globalIDB,
|
|
24
22
|
namespace = context.namespace,
|
|
25
23
|
}: {
|
|
26
24
|
context: OpenDocumentDbContext;
|
|
27
25
|
toRun: Migration<any>[];
|
|
28
|
-
meta: Metadata;
|
|
29
26
|
indexedDB?: IDBFactory;
|
|
30
27
|
/** This namespace value controls where the database being migrated is. */
|
|
31
28
|
namespace?: string;
|
|
@@ -39,7 +36,6 @@ export async function runMigrations({
|
|
|
39
36
|
// migrations from 0 (i.e. initial migrations) don't attempt to open an existing db
|
|
40
37
|
if (migration.oldSchema.version === 0) {
|
|
41
38
|
engine = getInitialMigrationEngine({
|
|
42
|
-
meta,
|
|
43
39
|
migration,
|
|
44
40
|
context,
|
|
45
41
|
});
|
|
@@ -56,12 +52,9 @@ export async function runMigrations({
|
|
|
56
52
|
|
|
57
53
|
// this will only write to our metadata store via operations!
|
|
58
54
|
engine = getMigrationEngine({
|
|
59
|
-
meta,
|
|
60
55
|
migration,
|
|
61
|
-
context
|
|
62
|
-
|
|
63
|
-
documentDb: originalDatabase,
|
|
64
|
-
},
|
|
56
|
+
context,
|
|
57
|
+
queryDb: originalDatabase,
|
|
65
58
|
});
|
|
66
59
|
try {
|
|
67
60
|
await migration.migrate(engine);
|
|
@@ -115,9 +108,9 @@ export async function runMigrations({
|
|
|
115
108
|
* would be missing from findAll and findOne queries.
|
|
116
109
|
*/
|
|
117
110
|
const docsWithUnappliedMigrations = await getDocsWithUnappliedMigrations({
|
|
118
|
-
meta,
|
|
119
111
|
currentVersion: migration.oldSchema.version,
|
|
120
112
|
newVersion: migration.newSchema.version,
|
|
113
|
+
ctx: context,
|
|
121
114
|
});
|
|
122
115
|
|
|
123
116
|
// once the schema is ready, we can write back the migrated documents
|
|
@@ -163,7 +156,7 @@ export async function runMigrations({
|
|
|
163
156
|
const snapshots = await Promise.all(
|
|
164
157
|
oids.map(async (oid) => {
|
|
165
158
|
try {
|
|
166
|
-
const snap = await meta.getDocumentSnapshot(oid);
|
|
159
|
+
const snap = await context.meta.getDocumentSnapshot(oid);
|
|
167
160
|
return [oid, snap];
|
|
168
161
|
} catch (e) {
|
|
169
162
|
// this seems to happen with baselines/ops which are not fully
|
|
@@ -279,22 +272,24 @@ async function putView(store: IDBObjectStore, view: any) {
|
|
|
279
272
|
* future. These documents need to be refreshed in storage.
|
|
280
273
|
*/
|
|
281
274
|
async function getDocsWithUnappliedMigrations({
|
|
282
|
-
meta,
|
|
283
275
|
currentVersion,
|
|
284
276
|
newVersion: _,
|
|
277
|
+
ctx,
|
|
285
278
|
}: {
|
|
286
279
|
currentVersion: number;
|
|
287
280
|
newVersion: number;
|
|
288
|
-
|
|
281
|
+
ctx: OpenDocumentDbContext;
|
|
289
282
|
}) {
|
|
290
283
|
// scan for all operations in metadata after the current version.
|
|
291
284
|
// this could be more efficient if also filtering below or equal newVersion but
|
|
292
285
|
// that seems so unlikely in practice...
|
|
293
286
|
const unappliedOperations: ClientOperation[] = [];
|
|
294
|
-
await meta.
|
|
295
|
-
(op) =>
|
|
287
|
+
await ctx.meta.iterateAllOperations(
|
|
288
|
+
(op) => {
|
|
289
|
+
unappliedOperations.push(op);
|
|
290
|
+
},
|
|
296
291
|
{
|
|
297
|
-
from:
|
|
292
|
+
from: ctx.time.zeroWithVersion(currentVersion + 1),
|
|
298
293
|
},
|
|
299
294
|
);
|
|
300
295
|
return Array.from(
|