@aws-amplify/datastore 3.7.3 → 3.7.4-custom-pk.86
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/CHANGELOG.md +144 -17
- package/README.md +154 -0
- package/dist/aws-amplify-datastore.js +3740 -1599
- package/dist/aws-amplify-datastore.js.map +1 -1
- package/dist/aws-amplify-datastore.min.js +25 -95
- package/dist/aws-amplify-datastore.min.js.map +1 -1
- package/lib/authModeStrategies/multiAuthStrategy.d.ts +2 -2
- package/lib/authModeStrategies/multiAuthStrategy.js +32 -26
- package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib/datastore/datastore.d.ts +17 -16
- package/lib/datastore/datastore.js +291 -83
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/index.d.ts +3 -19
- package/lib/predicates/index.d.ts +3 -2
- package/lib/predicates/index.js +12 -2
- package/lib/predicates/index.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
- package/lib/storage/adapter/AsyncStorageAdapter.js +361 -193
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
- package/lib/storage/adapter/AsyncStorageDatabase.js +59 -28
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.js +2 -2
- package/lib/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +7 -2
- package/lib/storage/adapter/IndexedDBAdapter.js +454 -252
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/adapter/index.d.ts +1 -1
- package/lib/storage/storage.d.ts +3 -3
- package/lib/storage/storage.js +106 -28
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/index.d.ts +23 -7
- package/lib/sync/index.js +18 -17
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.d.ts +3 -3
- package/lib/sync/merger.js +8 -6
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.d.ts +2 -2
- package/lib/sync/outbox.js +12 -9
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/errorMaps.d.ts +17 -0
- package/lib/sync/processors/errorMaps.js +125 -0
- package/lib/sync/processors/errorMaps.js.map +1 -0
- package/lib/sync/processors/mutation.d.ts +22 -4
- package/lib/sync/processors/mutation.js +119 -51
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.d.ts +4 -2
- package/lib/sync/processors/subscription.js +76 -41
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.d.ts +4 -2
- package/lib/sync/processors/sync.js +62 -27
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.d.ts +3 -2
- package/lib/sync/utils.js +58 -7
- package/lib/sync/utils.js.map +1 -1
- package/lib/types.d.ts +90 -34
- package/lib/types.js +31 -2
- package/lib/types.js.map +1 -1
- package/lib/util.d.ts +48 -33
- package/lib/util.js +219 -57
- package/lib/util.js.map +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +2 -2
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +32 -26
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +17 -16
- package/lib-esm/datastore/datastore.js +293 -85
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/index.d.ts +3 -19
- package/lib-esm/predicates/index.d.ts +3 -2
- package/lib-esm/predicates/index.js +13 -3
- package/lib-esm/predicates/index.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +361 -193
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +60 -29
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.js +2 -2
- package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +7 -2
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +454 -252
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/index.d.ts +1 -1
- package/lib-esm/storage/storage.d.ts +3 -3
- package/lib-esm/storage/storage.js +106 -28
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/index.d.ts +23 -7
- package/lib-esm/sync/index.js +20 -19
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.d.ts +3 -3
- package/lib-esm/sync/merger.js +8 -6
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.d.ts +2 -2
- package/lib-esm/sync/outbox.js +13 -10
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/errorMaps.d.ts +17 -0
- package/lib-esm/sync/processors/errorMaps.js +119 -0
- package/lib-esm/sync/processors/errorMaps.js.map +1 -0
- package/lib-esm/sync/processors/mutation.d.ts +22 -4
- package/lib-esm/sync/processors/mutation.js +122 -54
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.d.ts +4 -2
- package/lib-esm/sync/processors/subscription.js +77 -42
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.d.ts +4 -2
- package/lib-esm/sync/processors/sync.js +62 -27
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.d.ts +3 -2
- package/lib-esm/sync/utils.js +58 -8
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/types.d.ts +90 -34
- package/lib-esm/types.js +29 -3
- package/lib-esm/types.js.map +1 -1
- package/lib-esm/util.d.ts +48 -33
- package/lib-esm/util.js +207 -54
- package/lib-esm/util.js.map +1 -1
- package/package.json +10 -9
- package/src/authModeStrategies/multiAuthStrategy.ts +24 -21
- package/src/datastore/datastore.ts +448 -148
- package/src/predicates/index.ts +32 -10
- package/src/storage/adapter/AsyncStorageAdapter.ts +305 -78
- package/src/storage/adapter/AsyncStorageDatabase.ts +65 -26
- package/src/storage/adapter/InMemoryStore.ts +2 -2
- package/src/storage/adapter/IndexedDBAdapter.ts +344 -101
- package/src/storage/adapter/index.ts +1 -1
- package/src/storage/storage.ts +85 -24
- package/src/sync/index.ts +74 -58
- package/src/sync/merger.ts +16 -4
- package/src/sync/outbox.ts +22 -8
- package/src/sync/processors/errorMaps.ts +93 -0
- package/src/sync/processors/mutation.ts +143 -84
- package/src/sync/processors/subscription.ts +67 -36
- package/src/sync/processors/sync.ts +37 -12
- package/src/sync/utils.ts +67 -16
- package/src/types.ts +252 -50
- package/src/util.ts +256 -42
- package/ssr/package.json +1 -1
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
PersistentModel,
|
|
7
7
|
QueryOne,
|
|
8
8
|
} from '../../types';
|
|
9
|
-
import { monotonicUlidFactory } from '../../util';
|
|
9
|
+
import { indexNameFromKeys, monotonicUlidFactory } from '../../util';
|
|
10
10
|
import { createInMemoryStore } from './InMemoryStore';
|
|
11
11
|
|
|
12
12
|
const DB_NAME = '@AmplifyDatastore';
|
|
@@ -15,6 +15,8 @@ const DATA = 'Data';
|
|
|
15
15
|
|
|
16
16
|
const monotonicFactoriesMap = new Map<string, ULID>();
|
|
17
17
|
|
|
18
|
+
const DEFAULT_PRIMARY_KEY_SEPARATOR = ':::';
|
|
19
|
+
|
|
18
20
|
class AsyncStorageDatabase {
|
|
19
21
|
/**
|
|
20
22
|
* Maps storeNames to a map of ulid->id
|
|
@@ -23,14 +25,17 @@ class AsyncStorageDatabase {
|
|
|
23
25
|
|
|
24
26
|
private storage = createInMemoryStore();
|
|
25
27
|
|
|
28
|
+
// Collection index is map of stores (i.e. sync, metadata, mutation event, and data)
|
|
26
29
|
private getCollectionIndex(storeName: string) {
|
|
27
30
|
if (!this._collectionInMemoryIndex.has(storeName)) {
|
|
28
31
|
this._collectionInMemoryIndex.set(storeName, new Map());
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
// Map of ulid->id
|
|
31
35
|
return this._collectionInMemoryIndex.get(storeName);
|
|
32
36
|
}
|
|
33
37
|
|
|
38
|
+
// Return ULID for store if it exists, otherwise create a new one
|
|
34
39
|
private getMonotonicFactory(storeName: string): ULID {
|
|
35
40
|
if (!monotonicFactoriesMap.has(storeName)) {
|
|
36
41
|
monotonicFactoriesMap.set(storeName, monotonicUlidFactory());
|
|
@@ -85,39 +90,63 @@ class AsyncStorageDatabase {
|
|
|
85
90
|
}
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
async save<T extends PersistentModel>(
|
|
93
|
+
async save<T extends PersistentModel>(
|
|
94
|
+
item: T,
|
|
95
|
+
storeName: string,
|
|
96
|
+
keys: string[],
|
|
97
|
+
keyValuesPath: string
|
|
98
|
+
) {
|
|
99
|
+
const idxName = indexNameFromKeys(keys);
|
|
100
|
+
|
|
89
101
|
const ulid =
|
|
90
|
-
this.getCollectionIndex(storeName).get(
|
|
102
|
+
this.getCollectionIndex(storeName).get(idxName) ||
|
|
91
103
|
this.getMonotonicFactory(storeName)();
|
|
92
104
|
|
|
93
|
-
|
|
105
|
+
// Retrieve db key for item
|
|
106
|
+
const itemKey = this.getKeyForItem(storeName, keyValuesPath, ulid);
|
|
94
107
|
|
|
95
|
-
|
|
108
|
+
// Set key in collection index
|
|
109
|
+
this.getCollectionIndex(storeName).set(keyValuesPath, ulid);
|
|
96
110
|
|
|
111
|
+
// Save item in db
|
|
97
112
|
await this.storage.setItem(itemKey, JSON.stringify(item));
|
|
98
113
|
}
|
|
99
114
|
|
|
100
115
|
async batchSave<T extends PersistentModel>(
|
|
101
116
|
storeName: string,
|
|
102
|
-
items: ModelInstanceMetadata[]
|
|
117
|
+
items: ModelInstanceMetadata[],
|
|
118
|
+
keys: string[]
|
|
103
119
|
): Promise<[T, OpType][]> {
|
|
104
120
|
if (items.length === 0) {
|
|
105
121
|
return [];
|
|
106
122
|
}
|
|
107
123
|
|
|
108
124
|
const result: [T, OpType][] = [];
|
|
109
|
-
|
|
110
125
|
const collection = this.getCollectionIndex(storeName);
|
|
111
126
|
|
|
112
127
|
const keysToDelete = new Set<string>();
|
|
113
128
|
const keysToSave = new Set<string>();
|
|
114
129
|
const allItemsKeys = [];
|
|
115
130
|
const itemsMap: Record<string, { ulid: string; model: T }> = {};
|
|
131
|
+
|
|
132
|
+
/* Populate allItemKeys, keysToDelete, and keysToSave */
|
|
116
133
|
for (const item of items) {
|
|
117
|
-
|
|
118
|
-
const
|
|
134
|
+
// Extract keys from concatenated key path, map to item values
|
|
135
|
+
const keyValues = keys.map(field => item[field]);
|
|
136
|
+
|
|
137
|
+
const { _deleted } = item;
|
|
138
|
+
|
|
139
|
+
// If id is in the store, retrieve, otherwise generate new ULID
|
|
140
|
+
const ulid =
|
|
141
|
+
collection.get(keyValues.join(DEFAULT_PRIMARY_KEY_SEPARATOR)) ||
|
|
142
|
+
this.getMonotonicFactory(storeName)();
|
|
119
143
|
|
|
120
|
-
|
|
144
|
+
// Generate the "longer key" for the item
|
|
145
|
+
const key = this.getKeyForItem(
|
|
146
|
+
storeName,
|
|
147
|
+
keyValues.join(DEFAULT_PRIMARY_KEY_SEPARATOR),
|
|
148
|
+
ulid
|
|
149
|
+
);
|
|
121
150
|
|
|
122
151
|
allItemsKeys.push(key);
|
|
123
152
|
itemsMap[key] = { ulid, model: <T>(<unknown>item) };
|
|
@@ -136,6 +165,7 @@ class AsyncStorageDatabase {
|
|
|
136
165
|
.filter(([, v]) => !!v)
|
|
137
166
|
.reduce((set, [k]) => set.add(k), new Set<string>());
|
|
138
167
|
|
|
168
|
+
// Delete
|
|
139
169
|
await new Promise((resolve, reject) => {
|
|
140
170
|
if (keysToDelete.size === 0) {
|
|
141
171
|
resolve();
|
|
@@ -144,9 +174,15 @@ class AsyncStorageDatabase {
|
|
|
144
174
|
|
|
145
175
|
const keysToDeleteArray = Array.from(keysToDelete);
|
|
146
176
|
|
|
147
|
-
keysToDeleteArray.forEach(key =>
|
|
148
|
-
|
|
149
|
-
|
|
177
|
+
keysToDeleteArray.forEach(key => {
|
|
178
|
+
// key: full db key
|
|
179
|
+
// keys: PK and/or SK keys
|
|
180
|
+
const primaryKeyValues: string = keys
|
|
181
|
+
.map(field => itemsMap[key].model[field])
|
|
182
|
+
.join(DEFAULT_PRIMARY_KEY_SEPARATOR);
|
|
183
|
+
|
|
184
|
+
collection.delete(primaryKeyValues);
|
|
185
|
+
});
|
|
150
186
|
|
|
151
187
|
this.storage.multiRemove(keysToDeleteArray, (errors?: Error[]) => {
|
|
152
188
|
if (errors && errors.length > 0) {
|
|
@@ -157,6 +193,7 @@ class AsyncStorageDatabase {
|
|
|
157
193
|
});
|
|
158
194
|
});
|
|
159
195
|
|
|
196
|
+
// Save
|
|
160
197
|
await new Promise((resolve, reject) => {
|
|
161
198
|
if (keysToSave.size === 0) {
|
|
162
199
|
resolve();
|
|
@@ -169,12 +206,14 @@ class AsyncStorageDatabase {
|
|
|
169
206
|
]);
|
|
170
207
|
|
|
171
208
|
keysToSave.forEach(key => {
|
|
172
|
-
const {
|
|
173
|
-
model: { id },
|
|
174
|
-
ulid,
|
|
175
|
-
} = itemsMap[key];
|
|
209
|
+
const { model, ulid } = itemsMap[key];
|
|
176
210
|
|
|
177
|
-
|
|
211
|
+
// Retrieve values from model, use as key for collection index
|
|
212
|
+
const keyValues: string = keys
|
|
213
|
+
.map(field => model[field])
|
|
214
|
+
.join(DEFAULT_PRIMARY_KEY_SEPARATOR);
|
|
215
|
+
|
|
216
|
+
collection.set(keyValues, ulid);
|
|
178
217
|
});
|
|
179
218
|
|
|
180
219
|
this.storage.multiSet(entriesToSet, (errors?: Error[]) => {
|
|
@@ -201,11 +240,11 @@ class AsyncStorageDatabase {
|
|
|
201
240
|
}
|
|
202
241
|
|
|
203
242
|
async get<T extends PersistentModel>(
|
|
204
|
-
|
|
243
|
+
keyValuePath: string,
|
|
205
244
|
storeName: string
|
|
206
245
|
): Promise<T> {
|
|
207
|
-
const ulid = this.getCollectionIndex(storeName).get(
|
|
208
|
-
const itemKey = this.getKeyForItem(storeName,
|
|
246
|
+
const ulid = this.getCollectionIndex(storeName).get(keyValuePath);
|
|
247
|
+
const itemKey = this.getKeyForItem(storeName, keyValuePath, ulid);
|
|
209
248
|
const recordAsString = await this.storage.getItem(itemKey);
|
|
210
249
|
const record = recordAsString && JSON.parse(recordAsString);
|
|
211
250
|
return record;
|
|
@@ -227,6 +266,7 @@ class AsyncStorageDatabase {
|
|
|
227
266
|
return [id, ulid];
|
|
228
267
|
})();
|
|
229
268
|
const itemKey = this.getKeyForItem(storeName, itemId, ulid);
|
|
269
|
+
|
|
230
270
|
const itemString = itemKey && (await this.storage.getItem(itemKey));
|
|
231
271
|
|
|
232
272
|
const result = itemString ? JSON.parse(itemString) || undefined : undefined;
|
|
@@ -272,11 +312,10 @@ class AsyncStorageDatabase {
|
|
|
272
312
|
return records;
|
|
273
313
|
}
|
|
274
314
|
|
|
275
|
-
async delete(
|
|
276
|
-
const ulid = this.getCollectionIndex(storeName).get(
|
|
277
|
-
const itemKey = this.getKeyForItem(storeName,
|
|
278
|
-
|
|
279
|
-
this.getCollectionIndex(storeName).delete(id);
|
|
315
|
+
async delete(key: string, storeName: string) {
|
|
316
|
+
const ulid = this.getCollectionIndex(storeName).get(key);
|
|
317
|
+
const itemKey = this.getKeyForItem(storeName, key, ulid);
|
|
318
|
+
this.getCollectionIndex(storeName).delete(key);
|
|
280
319
|
await this.storage.removeItem(itemKey);
|
|
281
320
|
}
|
|
282
321
|
|
|
@@ -12,7 +12,7 @@ export class InMemoryStore {
|
|
|
12
12
|
multiRemove = async (keys: string[], callback?) => {
|
|
13
13
|
keys.forEach(k => this.db.delete(k));
|
|
14
14
|
|
|
15
|
-
callback();
|
|
15
|
+
typeof callback === 'function' && callback();
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
multiSet = async (entries: string[][], callback?) => {
|
|
@@ -20,7 +20,7 @@ export class InMemoryStore {
|
|
|
20
20
|
this.setItem(key, value);
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
callback();
|
|
23
|
+
typeof callback === 'function' && callback();
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
setItem = async (key: string, value: string) => {
|