@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.
Files changed (137) hide show
  1. package/CHANGELOG.md +144 -17
  2. package/README.md +154 -0
  3. package/dist/aws-amplify-datastore.js +3740 -1599
  4. package/dist/aws-amplify-datastore.js.map +1 -1
  5. package/dist/aws-amplify-datastore.min.js +25 -95
  6. package/dist/aws-amplify-datastore.min.js.map +1 -1
  7. package/lib/authModeStrategies/multiAuthStrategy.d.ts +2 -2
  8. package/lib/authModeStrategies/multiAuthStrategy.js +32 -26
  9. package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
  10. package/lib/datastore/datastore.d.ts +17 -16
  11. package/lib/datastore/datastore.js +291 -83
  12. package/lib/datastore/datastore.js.map +1 -1
  13. package/lib/index.d.ts +3 -19
  14. package/lib/predicates/index.d.ts +3 -2
  15. package/lib/predicates/index.js +12 -2
  16. package/lib/predicates/index.js.map +1 -1
  17. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
  18. package/lib/storage/adapter/AsyncStorageAdapter.js +361 -193
  19. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  20. package/lib/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
  21. package/lib/storage/adapter/AsyncStorageDatabase.js +59 -28
  22. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  23. package/lib/storage/adapter/InMemoryStore.js +2 -2
  24. package/lib/storage/adapter/InMemoryStore.js.map +1 -1
  25. package/lib/storage/adapter/IndexedDBAdapter.d.ts +7 -2
  26. package/lib/storage/adapter/IndexedDBAdapter.js +454 -252
  27. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  28. package/lib/storage/adapter/index.d.ts +1 -1
  29. package/lib/storage/storage.d.ts +3 -3
  30. package/lib/storage/storage.js +106 -28
  31. package/lib/storage/storage.js.map +1 -1
  32. package/lib/sync/index.d.ts +23 -7
  33. package/lib/sync/index.js +18 -17
  34. package/lib/sync/index.js.map +1 -1
  35. package/lib/sync/merger.d.ts +3 -3
  36. package/lib/sync/merger.js +8 -6
  37. package/lib/sync/merger.js.map +1 -1
  38. package/lib/sync/outbox.d.ts +2 -2
  39. package/lib/sync/outbox.js +12 -9
  40. package/lib/sync/outbox.js.map +1 -1
  41. package/lib/sync/processors/errorMaps.d.ts +17 -0
  42. package/lib/sync/processors/errorMaps.js +125 -0
  43. package/lib/sync/processors/errorMaps.js.map +1 -0
  44. package/lib/sync/processors/mutation.d.ts +22 -4
  45. package/lib/sync/processors/mutation.js +119 -51
  46. package/lib/sync/processors/mutation.js.map +1 -1
  47. package/lib/sync/processors/subscription.d.ts +4 -2
  48. package/lib/sync/processors/subscription.js +76 -41
  49. package/lib/sync/processors/subscription.js.map +1 -1
  50. package/lib/sync/processors/sync.d.ts +4 -2
  51. package/lib/sync/processors/sync.js +62 -27
  52. package/lib/sync/processors/sync.js.map +1 -1
  53. package/lib/sync/utils.d.ts +3 -2
  54. package/lib/sync/utils.js +58 -7
  55. package/lib/sync/utils.js.map +1 -1
  56. package/lib/types.d.ts +90 -34
  57. package/lib/types.js +31 -2
  58. package/lib/types.js.map +1 -1
  59. package/lib/util.d.ts +48 -33
  60. package/lib/util.js +219 -57
  61. package/lib/util.js.map +1 -1
  62. package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +2 -2
  63. package/lib-esm/authModeStrategies/multiAuthStrategy.js +32 -26
  64. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
  65. package/lib-esm/datastore/datastore.d.ts +17 -16
  66. package/lib-esm/datastore/datastore.js +293 -85
  67. package/lib-esm/datastore/datastore.js.map +1 -1
  68. package/lib-esm/index.d.ts +3 -19
  69. package/lib-esm/predicates/index.d.ts +3 -2
  70. package/lib-esm/predicates/index.js +13 -3
  71. package/lib-esm/predicates/index.js.map +1 -1
  72. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
  73. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +361 -193
  74. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  75. package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
  76. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +60 -29
  77. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  78. package/lib-esm/storage/adapter/InMemoryStore.js +2 -2
  79. package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
  80. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +7 -2
  81. package/lib-esm/storage/adapter/IndexedDBAdapter.js +454 -252
  82. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  83. package/lib-esm/storage/adapter/index.d.ts +1 -1
  84. package/lib-esm/storage/storage.d.ts +3 -3
  85. package/lib-esm/storage/storage.js +106 -28
  86. package/lib-esm/storage/storage.js.map +1 -1
  87. package/lib-esm/sync/index.d.ts +23 -7
  88. package/lib-esm/sync/index.js +20 -19
  89. package/lib-esm/sync/index.js.map +1 -1
  90. package/lib-esm/sync/merger.d.ts +3 -3
  91. package/lib-esm/sync/merger.js +8 -6
  92. package/lib-esm/sync/merger.js.map +1 -1
  93. package/lib-esm/sync/outbox.d.ts +2 -2
  94. package/lib-esm/sync/outbox.js +13 -10
  95. package/lib-esm/sync/outbox.js.map +1 -1
  96. package/lib-esm/sync/processors/errorMaps.d.ts +17 -0
  97. package/lib-esm/sync/processors/errorMaps.js +119 -0
  98. package/lib-esm/sync/processors/errorMaps.js.map +1 -0
  99. package/lib-esm/sync/processors/mutation.d.ts +22 -4
  100. package/lib-esm/sync/processors/mutation.js +122 -54
  101. package/lib-esm/sync/processors/mutation.js.map +1 -1
  102. package/lib-esm/sync/processors/subscription.d.ts +4 -2
  103. package/lib-esm/sync/processors/subscription.js +77 -42
  104. package/lib-esm/sync/processors/subscription.js.map +1 -1
  105. package/lib-esm/sync/processors/sync.d.ts +4 -2
  106. package/lib-esm/sync/processors/sync.js +62 -27
  107. package/lib-esm/sync/processors/sync.js.map +1 -1
  108. package/lib-esm/sync/utils.d.ts +3 -2
  109. package/lib-esm/sync/utils.js +58 -8
  110. package/lib-esm/sync/utils.js.map +1 -1
  111. package/lib-esm/types.d.ts +90 -34
  112. package/lib-esm/types.js +29 -3
  113. package/lib-esm/types.js.map +1 -1
  114. package/lib-esm/util.d.ts +48 -33
  115. package/lib-esm/util.js +207 -54
  116. package/lib-esm/util.js.map +1 -1
  117. package/package.json +10 -9
  118. package/src/authModeStrategies/multiAuthStrategy.ts +24 -21
  119. package/src/datastore/datastore.ts +448 -148
  120. package/src/predicates/index.ts +32 -10
  121. package/src/storage/adapter/AsyncStorageAdapter.ts +305 -78
  122. package/src/storage/adapter/AsyncStorageDatabase.ts +65 -26
  123. package/src/storage/adapter/InMemoryStore.ts +2 -2
  124. package/src/storage/adapter/IndexedDBAdapter.ts +344 -101
  125. package/src/storage/adapter/index.ts +1 -1
  126. package/src/storage/storage.ts +85 -24
  127. package/src/sync/index.ts +74 -58
  128. package/src/sync/merger.ts +16 -4
  129. package/src/sync/outbox.ts +22 -8
  130. package/src/sync/processors/errorMaps.ts +93 -0
  131. package/src/sync/processors/mutation.ts +143 -84
  132. package/src/sync/processors/subscription.ts +67 -36
  133. package/src/sync/processors/sync.ts +37 -12
  134. package/src/sync/utils.ts +67 -16
  135. package/src/types.ts +252 -50
  136. package/src/util.ts +256 -42
  137. 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>(item: T, storeName: string) {
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(item.id) ||
102
+ this.getCollectionIndex(storeName).get(idxName) ||
91
103
  this.getMonotonicFactory(storeName)();
92
104
 
93
- const itemKey = this.getKeyForItem(storeName, item.id, ulid);
105
+ // Retrieve db key for item
106
+ const itemKey = this.getKeyForItem(storeName, keyValuesPath, ulid);
94
107
 
95
- this.getCollectionIndex(storeName).set(item.id, ulid);
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
- const { id, _deleted } = item;
118
- const ulid = collection.get(id) || this.getMonotonicFactory(storeName)();
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
- const key = this.getKeyForItem(storeName, id, ulid);
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
- collection.delete(itemsMap[key].model.id)
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
- collection.set(id, ulid);
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
- id: string,
243
+ keyValuePath: string,
205
244
  storeName: string
206
245
  ): Promise<T> {
207
- const ulid = this.getCollectionIndex(storeName).get(id);
208
- const itemKey = this.getKeyForItem(storeName, id, ulid);
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(id: string, storeName: string) {
276
- const ulid = this.getCollectionIndex(storeName).get(id);
277
- const itemKey = this.getKeyForItem(storeName, id, ulid);
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) => {