@instantdb/core 0.22.96-experimental.drewh-ts-target.20761590091.1 → 0.22.97-experimental.bump-next-cia.20761479934.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 (126) hide show
  1. package/dist/commonjs/Connection.js +51 -50
  2. package/dist/commonjs/Connection.js.map +1 -1
  3. package/dist/commonjs/InMemoryStorage.js +32 -13
  4. package/dist/commonjs/InMemoryStorage.js.map +1 -1
  5. package/dist/commonjs/IndexedDBStorage.js +217 -193
  6. package/dist/commonjs/IndexedDBStorage.js.map +1 -1
  7. package/dist/commonjs/InstantError.js +0 -1
  8. package/dist/commonjs/InstantError.js.map +1 -1
  9. package/dist/commonjs/Reactor.js +610 -566
  10. package/dist/commonjs/Reactor.js.map +1 -1
  11. package/dist/commonjs/StorageAPI.js +70 -51
  12. package/dist/commonjs/StorageAPI.js.map +1 -1
  13. package/dist/commonjs/SyncTable.js +81 -68
  14. package/dist/commonjs/SyncTable.js.map +1 -1
  15. package/dist/commonjs/WindowNetworkListener.js +13 -2
  16. package/dist/commonjs/WindowNetworkListener.js.map +1 -1
  17. package/dist/commonjs/__types__/fieldsTypeTest.js +16 -8
  18. package/dist/commonjs/__types__/fieldsTypeTest.js.map +1 -1
  19. package/dist/commonjs/__types__/useDatesTypeTest.js +6 -3
  20. package/dist/commonjs/__types__/useDatesTypeTest.js.map +1 -1
  21. package/dist/commonjs/authAPI.js +79 -62
  22. package/dist/commonjs/authAPI.js.map +1 -1
  23. package/dist/commonjs/createRouteHandler.js +15 -5
  24. package/dist/commonjs/createRouteHandler.js.map +1 -1
  25. package/dist/commonjs/datalog.js +1 -1
  26. package/dist/commonjs/datalog.js.map +1 -1
  27. package/dist/commonjs/devtool.js +8 -26
  28. package/dist/commonjs/devtool.js.map +1 -1
  29. package/dist/commonjs/framework.d.ts.map +1 -1
  30. package/dist/commonjs/framework.js +152 -142
  31. package/dist/commonjs/framework.js.map +1 -1
  32. package/dist/commonjs/index.js +190 -204
  33. package/dist/commonjs/index.js.map +1 -1
  34. package/dist/commonjs/instaml.js +30 -44
  35. package/dist/commonjs/instaml.js.map +1 -1
  36. package/dist/commonjs/instaql.js +33 -25
  37. package/dist/commonjs/instaql.js.map +1 -1
  38. package/dist/commonjs/parseSchemaFromJSON.js +7 -6
  39. package/dist/commonjs/parseSchemaFromJSON.js.map +1 -1
  40. package/dist/commonjs/presence.js +8 -7
  41. package/dist/commonjs/presence.js.map +1 -1
  42. package/dist/commonjs/queryValidation.js +2 -1
  43. package/dist/commonjs/queryValidation.js.map +1 -1
  44. package/dist/commonjs/schema.js +6 -8
  45. package/dist/commonjs/schema.js.map +1 -1
  46. package/dist/commonjs/schemaTypes.js +3 -22
  47. package/dist/commonjs/schemaTypes.js.map +1 -1
  48. package/dist/commonjs/store.js +38 -29
  49. package/dist/commonjs/store.js.map +1 -1
  50. package/dist/commonjs/transactionValidation.js +2 -1
  51. package/dist/commonjs/transactionValidation.js.map +1 -1
  52. package/dist/commonjs/utils/Deferred.js +0 -3
  53. package/dist/commonjs/utils/Deferred.js.map +1 -1
  54. package/dist/commonjs/utils/PersistedObject.js +233 -216
  55. package/dist/commonjs/utils/PersistedObject.js.map +1 -1
  56. package/dist/commonjs/utils/fetch.js +19 -9
  57. package/dist/commonjs/utils/fetch.js.map +1 -1
  58. package/dist/commonjs/utils/linkIndex.js +4 -2
  59. package/dist/commonjs/utils/linkIndex.js.map +1 -1
  60. package/dist/commonjs/utils/object.js +1 -1
  61. package/dist/commonjs/utils/object.js.map +1 -1
  62. package/dist/esm/Connection.js +51 -50
  63. package/dist/esm/Connection.js.map +1 -1
  64. package/dist/esm/InMemoryStorage.js +32 -13
  65. package/dist/esm/InMemoryStorage.js.map +1 -1
  66. package/dist/esm/IndexedDBStorage.js +217 -193
  67. package/dist/esm/IndexedDBStorage.js.map +1 -1
  68. package/dist/esm/InstantError.js +0 -1
  69. package/dist/esm/InstantError.js.map +1 -1
  70. package/dist/esm/Reactor.js +610 -566
  71. package/dist/esm/Reactor.js.map +1 -1
  72. package/dist/esm/StorageAPI.js +70 -51
  73. package/dist/esm/StorageAPI.js.map +1 -1
  74. package/dist/esm/SyncTable.js +81 -68
  75. package/dist/esm/SyncTable.js.map +1 -1
  76. package/dist/esm/WindowNetworkListener.js +13 -2
  77. package/dist/esm/WindowNetworkListener.js.map +1 -1
  78. package/dist/esm/__types__/fieldsTypeTest.js +16 -8
  79. package/dist/esm/__types__/fieldsTypeTest.js.map +1 -1
  80. package/dist/esm/__types__/useDatesTypeTest.js +6 -3
  81. package/dist/esm/__types__/useDatesTypeTest.js.map +1 -1
  82. package/dist/esm/authAPI.js +79 -62
  83. package/dist/esm/authAPI.js.map +1 -1
  84. package/dist/esm/createRouteHandler.js +15 -5
  85. package/dist/esm/createRouteHandler.js.map +1 -1
  86. package/dist/esm/datalog.js +1 -1
  87. package/dist/esm/datalog.js.map +1 -1
  88. package/dist/esm/devtool.js +8 -26
  89. package/dist/esm/devtool.js.map +1 -1
  90. package/dist/esm/framework.d.ts.map +1 -1
  91. package/dist/esm/framework.js +152 -142
  92. package/dist/esm/framework.js.map +1 -1
  93. package/dist/esm/index.js +190 -204
  94. package/dist/esm/index.js.map +1 -1
  95. package/dist/esm/instaml.js +30 -44
  96. package/dist/esm/instaml.js.map +1 -1
  97. package/dist/esm/instaql.js +33 -25
  98. package/dist/esm/instaql.js.map +1 -1
  99. package/dist/esm/parseSchemaFromJSON.js +7 -6
  100. package/dist/esm/parseSchemaFromJSON.js.map +1 -1
  101. package/dist/esm/presence.js +8 -7
  102. package/dist/esm/presence.js.map +1 -1
  103. package/dist/esm/queryValidation.js +2 -1
  104. package/dist/esm/queryValidation.js.map +1 -1
  105. package/dist/esm/schema.js +6 -8
  106. package/dist/esm/schema.js.map +1 -1
  107. package/dist/esm/schemaTypes.js +3 -22
  108. package/dist/esm/schemaTypes.js.map +1 -1
  109. package/dist/esm/store.js +38 -29
  110. package/dist/esm/store.js.map +1 -1
  111. package/dist/esm/transactionValidation.js +2 -1
  112. package/dist/esm/transactionValidation.js.map +1 -1
  113. package/dist/esm/utils/Deferred.js +0 -3
  114. package/dist/esm/utils/Deferred.js.map +1 -1
  115. package/dist/esm/utils/PersistedObject.js +233 -216
  116. package/dist/esm/utils/PersistedObject.js.map +1 -1
  117. package/dist/esm/utils/fetch.js +19 -9
  118. package/dist/esm/utils/fetch.js.map +1 -1
  119. package/dist/esm/utils/linkIndex.js +4 -2
  120. package/dist/esm/utils/linkIndex.js.map +1 -1
  121. package/dist/esm/utils/object.js +1 -1
  122. package/dist/esm/utils/object.js.map +1 -1
  123. package/dist/standalone/index.js +2367 -2610
  124. package/dist/standalone/index.umd.cjs +3 -3
  125. package/package.json +2 -2
  126. package/src/framework.ts +1 -0
@@ -13,6 +13,15 @@
13
13
  // Each PersistedObject provides it's own `onMerge`
14
14
  // function to handle the merge of data from storage and memory
15
15
  // on load
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
16
25
  Object.defineProperty(exports, "__esModule", { value: true });
17
26
  exports.PersistedObject = exports.StorageInterface = exports.META_KEY = void 0;
18
27
  // Uses `requestIdleCallback` if available, otherwise calls the
@@ -32,40 +41,29 @@ class StorageInterface {
32
41
  }
33
42
  exports.StorageInterface = StorageInterface;
34
43
  class PersistedObject {
35
- currentValue;
36
- _subs = [];
37
- _persister;
38
- _merge;
39
- serialize;
40
- parse;
41
- _saveThrottleMs;
42
- _idleCallbackMaxWaitMs;
43
- _nextSave = null;
44
- _nextGc = null;
45
- _pendingSaveKeys = new Set();
46
- _loadedKeys = new Set();
47
- _loadingKeys;
48
- _objectSize;
49
- _log;
50
- onKeyLoaded;
51
- _version = 0;
52
- _meta = {
53
- isLoading: true,
54
- onLoadCbs: [],
55
- value: null,
56
- error: null,
57
- attempts: 0,
58
- };
59
- _gcOpts;
60
44
  constructor(opts) {
45
+ var _a, _b;
46
+ this._subs = [];
47
+ this._nextSave = null;
48
+ this._nextGc = null;
49
+ this._pendingSaveKeys = new Set();
50
+ this._loadedKeys = new Set();
51
+ this._version = 0;
52
+ this._meta = {
53
+ isLoading: true,
54
+ onLoadCbs: [],
55
+ value: null,
56
+ error: null,
57
+ attempts: 0,
58
+ };
61
59
  this._persister = opts.persister;
62
60
  this._merge = opts.merge;
63
61
  this.serialize = opts.serialize;
64
62
  this.parse = opts.parse;
65
63
  this._objectSize = opts.objectSize;
66
64
  this._log = opts.logger;
67
- this._saveThrottleMs = opts.saveThrottleMs ?? 100;
68
- this._idleCallbackMaxWaitMs = opts.idleCallbackMaxWaitMs ?? 1000;
65
+ this._saveThrottleMs = (_a = opts.saveThrottleMs) !== null && _a !== void 0 ? _a : 100;
66
+ this._idleCallbackMaxWaitMs = (_b = opts.idleCallbackMaxWaitMs) !== null && _b !== void 0 ? _b : 1000;
69
67
  this._gcOpts = opts.gc;
70
68
  this.currentValue = {};
71
69
  this._loadedKeys = new Set();
@@ -75,85 +73,97 @@ class PersistedObject {
75
73
  this._preloadEntries(opts.preloadEntryCount);
76
74
  }
77
75
  }
78
- async _initMeta() {
79
- if (this._meta.loadingPromise) {
80
- await this._meta.loadingPromise;
81
- }
82
- try {
83
- const p = this._persister.getItem(exports.META_KEY);
84
- this._meta.loadingPromise = p;
85
- const v = await p;
86
- this._meta.isLoading = false;
87
- this._meta.error = null;
88
- this._meta.loadingPromise = null;
89
- this._meta.attempts = 0;
90
- const existingObjects = this._meta.value?.objects ?? {};
91
- const value = v ?? {};
92
- const objects = value.objects ?? {};
93
- // Merge the values from storage with in-memory values
94
- this._meta.value = {
95
- ...value,
96
- objects: { ...existingObjects, ...objects },
97
- };
98
- }
99
- catch (e) {
100
- this._meta.error = e;
101
- this._meta.attempts++;
102
- this._meta.loadingPromise = null;
103
- }
76
+ _initMeta() {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ var _a, _b, _c;
79
+ if (this._meta.loadingPromise) {
80
+ yield this._meta.loadingPromise;
81
+ }
82
+ try {
83
+ const p = this._persister.getItem(exports.META_KEY);
84
+ this._meta.loadingPromise = p;
85
+ const v = yield p;
86
+ this._meta.isLoading = false;
87
+ this._meta.error = null;
88
+ this._meta.loadingPromise = null;
89
+ this._meta.attempts = 0;
90
+ const existingObjects = (_b = (_a = this._meta.value) === null || _a === void 0 ? void 0 : _a.objects) !== null && _b !== void 0 ? _b : {};
91
+ const value = v !== null && v !== void 0 ? v : {};
92
+ const objects = (_c = value.objects) !== null && _c !== void 0 ? _c : {};
93
+ // Merge the values from storage with in-memory values
94
+ this._meta.value = Object.assign(Object.assign({}, value), { objects: Object.assign(Object.assign({}, existingObjects), objects) });
95
+ }
96
+ catch (e) {
97
+ this._meta.error = e;
98
+ this._meta.attempts++;
99
+ this._meta.loadingPromise = null;
100
+ }
101
+ });
104
102
  }
105
- async _getMeta() {
106
- if (this._meta.value) {
107
- return this._meta.value;
108
- }
109
- if (this._meta.loadingPromise) {
110
- await this._meta.loadingPromise;
103
+ _getMeta() {
104
+ return __awaiter(this, void 0, void 0, function* () {
105
+ if (this._meta.value) {
106
+ return this._meta.value;
107
+ }
108
+ if (this._meta.loadingPromise) {
109
+ yield this._meta.loadingPromise;
110
+ return this._meta.value;
111
+ }
112
+ this._initMeta();
113
+ yield this._meta.loadingPromise;
111
114
  return this._meta.value;
112
- }
113
- this._initMeta();
114
- await this._meta.loadingPromise;
115
- return this._meta.value;
115
+ });
116
116
  }
117
- async _refreshMeta() {
118
- await this._initMeta();
119
- return this._meta.value;
117
+ _refreshMeta() {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ yield this._initMeta();
120
+ return this._meta.value;
121
+ });
120
122
  }
121
- async _preloadEntries(n) {
122
- const meta = await this.waitForMetaToLoad();
123
- if (!meta)
124
- return;
125
- const entries = Object.entries(meta.objects);
126
- entries.sort(([_k_a, a_meta], [_k_b, b_meta]) => {
127
- return b_meta.updatedAt - a_meta.updatedAt;
123
+ _preloadEntries(n) {
124
+ return __awaiter(this, void 0, void 0, function* () {
125
+ const meta = yield this.waitForMetaToLoad();
126
+ if (!meta)
127
+ return;
128
+ const entries = Object.entries(meta.objects);
129
+ entries.sort(([_k_a, a_meta], [_k_b, b_meta]) => {
130
+ return b_meta.updatedAt - a_meta.updatedAt;
131
+ });
132
+ for (const [k] of entries.slice(0, n)) {
133
+ this._loadKey(k);
134
+ }
128
135
  });
129
- for (const [k] of entries.slice(0, n)) {
130
- this._loadKey(k);
131
- }
132
136
  }
133
- async _getFromStorage(key) {
134
- try {
135
- const data = await this._persister.getItem(key);
136
- if (!data) {
137
- return data;
137
+ _getFromStorage(key) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ try {
140
+ const data = yield this._persister.getItem(key);
141
+ if (!data) {
142
+ return data;
143
+ }
144
+ const parsed = this.parse(key, data);
145
+ return parsed;
138
146
  }
139
- const parsed = this.parse(key, data);
140
- return parsed;
141
- }
142
- catch (e) {
143
- console.error(`Unable to read from storage for key=${key}`, e);
144
- return null;
145
- }
147
+ catch (e) {
148
+ console.error(`Unable to read from storage for key=${key}`, e);
149
+ return null;
150
+ }
151
+ });
146
152
  }
147
- async waitForKeyToLoad(k) {
148
- if (this._loadedKeys.has(k)) {
153
+ waitForKeyToLoad(k) {
154
+ return __awaiter(this, void 0, void 0, function* () {
155
+ if (this._loadedKeys.has(k)) {
156
+ return this.currentValue[k];
157
+ }
158
+ yield (this._loadingKeys[k] || this._loadKey(k));
149
159
  return this.currentValue[k];
150
- }
151
- await (this._loadingKeys[k] || this._loadKey(k));
152
- return this.currentValue[k];
160
+ });
153
161
  }
154
162
  // Used for tests
155
- async waitForMetaToLoad() {
156
- return this._getMeta();
163
+ waitForMetaToLoad() {
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ return this._getMeta();
166
+ });
157
167
  }
158
168
  // Unloads the key so that it can be garbage collected, but does not
159
169
  // delete it. Removes the key from currentValue.
@@ -162,38 +172,41 @@ class PersistedObject {
162
172
  delete this._loadingKeys[k];
163
173
  delete this.currentValue[k];
164
174
  }
165
- async _loadKey(k) {
166
- if (this._loadedKeys.has(k) || k in this._loadingKeys)
167
- return;
168
- const p = this._getFromStorage(k);
169
- this._loadingKeys[k] = p;
170
- const value = await p;
171
- delete this._loadingKeys[k];
172
- this._loadedKeys.add(k);
173
- if (value) {
174
- const merged = this._merge(k, value, this.currentValue[k]);
175
- if (merged) {
176
- this.currentValue[k] = merged;
175
+ _loadKey(k) {
176
+ return __awaiter(this, void 0, void 0, function* () {
177
+ if (this._loadedKeys.has(k) || k in this._loadingKeys)
178
+ return;
179
+ const p = this._getFromStorage(k);
180
+ this._loadingKeys[k] = p;
181
+ const value = yield p;
182
+ delete this._loadingKeys[k];
183
+ this._loadedKeys.add(k);
184
+ if (value) {
185
+ const merged = this._merge(k, value, this.currentValue[k]);
186
+ if (merged) {
187
+ this.currentValue[k] = merged;
188
+ }
177
189
  }
178
- }
179
- this.onKeyLoaded && this.onKeyLoaded(k);
190
+ this.onKeyLoaded && this.onKeyLoaded(k);
191
+ });
180
192
  }
181
193
  // Returns a promise with a number so that we can wait for flush
182
194
  // to finish in the tests. The number is the number of operations
183
195
  // it performed, but it's mostly there so that typescript will warn
184
196
  // us if we forget to retun the promise from the function.
185
197
  _writeToStorage(opts) {
198
+ var _a, _b;
186
199
  const promises = [];
187
- const skipGc = opts?.skipGc;
200
+ const skipGc = opts === null || opts === void 0 ? void 0 : opts.skipGc;
188
201
  if (this._meta.isLoading) {
189
202
  // Wait for meta to load and try again, give it a delay so that
190
203
  // we don't spend too much time retrying
191
204
  const p = new Promise((resolve, reject) => {
205
+ var _a;
192
206
  setTimeout(() => this._enqueuePersist(opts
193
- ? { ...opts, attempts: (opts.attempts || 0) + 1 }
194
- : { attempts: 1 })
207
+ ? Object.assign(Object.assign({}, opts), { attempts: (opts.attempts || 0) + 1 }) : { attempts: 1 })
195
208
  .then(resolve)
196
- .catch(reject), 10 + (opts?.attempts ?? 0) * 1000);
209
+ .catch(reject), 10 + ((_a = opts === null || opts === void 0 ? void 0 : opts.attempts) !== null && _a !== void 0 ? _a : 0) * 1000);
197
210
  });
198
211
  promises.push(p);
199
212
  return Promise.all(promises).then((vs) => vs.reduce((acc, x) => acc + x, 0));
@@ -224,14 +237,14 @@ class PersistedObject {
224
237
  }
225
238
  const keysToLoad = [];
226
239
  const kvPairs = [[exports.META_KEY, metaValue]];
227
- const metaObjects = metaValue.objects ?? {};
240
+ const metaObjects = (_a = metaValue.objects) !== null && _a !== void 0 ? _a : {};
228
241
  metaValue.objects = metaObjects;
229
242
  for (const k of keysToUpdate) {
230
243
  if (this._loadedKeys.has(k)) {
231
244
  const serializedV = this.serialize(k, this.currentValue[k]);
232
245
  kvPairs.push([k, serializedV]);
233
246
  const size = this._objectSize(serializedV);
234
- const m = metaObjects[k] ?? {
247
+ const m = (_b = metaObjects[k]) !== null && _b !== void 0 ? _b : {
235
248
  createdAt: Date.now(),
236
249
  updatedAt: Date.now(),
237
250
  size,
@@ -262,115 +275,119 @@ class PersistedObject {
262
275
  return vs.reduce((acc, x) => acc + x, 0);
263
276
  });
264
277
  }
265
- async flush() {
266
- if (!this._nextSave) {
267
- return;
268
- }
269
- clearTimeout(this._nextSave);
270
- this._nextSave = null;
271
- const p = this._writeToStorage();
272
- return p;
278
+ flush() {
279
+ return __awaiter(this, void 0, void 0, function* () {
280
+ if (!this._nextSave) {
281
+ return;
282
+ }
283
+ clearTimeout(this._nextSave);
284
+ this._nextSave = null;
285
+ const p = this._writeToStorage();
286
+ return p;
287
+ });
273
288
  }
274
- async _gc() {
275
- if (!this._gcOpts) {
276
- return;
277
- }
278
- const keys = new Set(await this._persister.getAllKeys());
279
- keys.delete(exports.META_KEY);
280
- // Keys we can't delete
281
- const sacredKeys = new Set(Object.keys(this.currentValue));
282
- for (const k of Object.keys(this._loadingKeys)) {
283
- sacredKeys.add(k);
284
- }
285
- for (const k of this._loadedKeys) {
286
- sacredKeys.add(k);
287
- }
288
- // Refresh meta from the store so that we're less likely to
289
- // clobber data from other tabs
290
- const meta = await this._refreshMeta();
291
- if (!meta) {
292
- this._log.info('Could not gc because we were not able to load meta');
293
- return;
294
- }
295
- const promises = [];
296
- const deets = {
297
- gcOpts: this._gcOpts,
298
- keys,
299
- sacredKeys,
300
- removed: [],
301
- metaRemoved: [],
302
- removedMissingCount: 0,
303
- removedOldCount: 0,
304
- removedThresholdCount: 0,
305
- removedSizeCount: 0,
306
- };
307
- // First, remove all keys we don't know about
308
- for (const key of keys) {
309
- if (sacredKeys.has(key) || key in meta.objects) {
310
- continue;
289
+ _gc() {
290
+ return __awaiter(this, void 0, void 0, function* () {
291
+ if (!this._gcOpts) {
292
+ return;
311
293
  }
312
- this._log.info('Lost track of key in meta', key);
313
- promises.push(this._persister.removeItem(key));
314
- deets.removed.push(key);
315
- deets.removedMissingCount++;
316
- }
317
- // Remove anything over the max age
318
- const now = Date.now();
319
- for (const [k, m] of Object.entries(meta.objects)) {
320
- if (!sacredKeys.has(k) &&
321
- m.updatedAt < now - this._gcOpts.maxAgeMs) {
322
- promises.push(this._persister.removeItem(k));
323
- delete meta.objects[k];
324
- deets.removed.push(k);
325
- deets.removedOldCount++;
294
+ const keys = new Set(yield this._persister.getAllKeys());
295
+ keys.delete(exports.META_KEY);
296
+ // Keys we can't delete
297
+ const sacredKeys = new Set(Object.keys(this.currentValue));
298
+ for (const k of Object.keys(this._loadingKeys)) {
299
+ sacredKeys.add(k);
326
300
  }
327
- }
328
- // Keep queries under max queries
329
- const maxEntries = Object.entries(meta.objects);
330
- maxEntries.sort(([_k_a, a_meta], [_k_b, b_meta]) => {
331
- return a_meta.updatedAt - b_meta.updatedAt;
332
- });
333
- const deletableMaxEntries = maxEntries.filter(([x]) => !sacredKeys.has(x));
334
- if (maxEntries.length > this._gcOpts.maxEntries) {
335
- for (const [k] of deletableMaxEntries.slice(0, maxEntries.length - this._gcOpts.maxEntries)) {
301
+ for (const k of this._loadedKeys) {
302
+ sacredKeys.add(k);
303
+ }
304
+ // Refresh meta from the store so that we're less likely to
305
+ // clobber data from other tabs
306
+ const meta = yield this._refreshMeta();
307
+ if (!meta) {
308
+ this._log.info('Could not gc because we were not able to load meta');
309
+ return;
310
+ }
311
+ const promises = [];
312
+ const deets = {
313
+ gcOpts: this._gcOpts,
314
+ keys,
315
+ sacredKeys,
316
+ removed: [],
317
+ metaRemoved: [],
318
+ removedMissingCount: 0,
319
+ removedOldCount: 0,
320
+ removedThresholdCount: 0,
321
+ removedSizeCount: 0,
322
+ };
323
+ // First, remove all keys we don't know about
324
+ for (const key of keys) {
325
+ if (sacredKeys.has(key) || key in meta.objects) {
326
+ continue;
327
+ }
328
+ this._log.info('Lost track of key in meta', key);
329
+ promises.push(this._persister.removeItem(key));
330
+ deets.removed.push(key);
331
+ deets.removedMissingCount++;
332
+ }
333
+ // Remove anything over the max age
334
+ const now = Date.now();
335
+ for (const [k, m] of Object.entries(meta.objects)) {
336
+ if (!sacredKeys.has(k) &&
337
+ m.updatedAt < now - this._gcOpts.maxAgeMs) {
338
+ promises.push(this._persister.removeItem(k));
339
+ delete meta.objects[k];
340
+ deets.removed.push(k);
341
+ deets.removedOldCount++;
342
+ }
343
+ }
344
+ // Keep queries under max queries
345
+ const maxEntries = Object.entries(meta.objects);
346
+ maxEntries.sort(([_k_a, a_meta], [_k_b, b_meta]) => {
347
+ return a_meta.updatedAt - b_meta.updatedAt;
348
+ });
349
+ const deletableMaxEntries = maxEntries.filter(([x]) => !sacredKeys.has(x));
350
+ if (maxEntries.length > this._gcOpts.maxEntries) {
351
+ for (const [k] of deletableMaxEntries.slice(0, maxEntries.length - this._gcOpts.maxEntries)) {
352
+ promises.push(this._persister.removeItem(k));
353
+ delete meta.objects[k];
354
+ deets.removed.push(k);
355
+ deets.removedThresholdCount++;
356
+ }
357
+ }
358
+ // Remove oldest entries until we are under max size
359
+ const delEntries = Object.entries(meta.objects);
360
+ delEntries.sort(([_k_a, a_meta], [_k_b, b_meta]) => {
361
+ return a_meta.updatedAt - b_meta.updatedAt;
362
+ });
363
+ const deletableDelEntries = delEntries.filter(([x]) => !sacredKeys.has(x));
364
+ let currentSize = delEntries.reduce((acc, [_k, m]) => {
365
+ return acc + m.size;
366
+ }, 0);
367
+ while (currentSize > 0 &&
368
+ currentSize > this._gcOpts.maxSize &&
369
+ deletableDelEntries.length) {
370
+ const [[k, m]] = deletableDelEntries.splice(0, 1);
371
+ currentSize -= m.size;
336
372
  promises.push(this._persister.removeItem(k));
337
373
  delete meta.objects[k];
338
374
  deets.removed.push(k);
339
- deets.removedThresholdCount++;
375
+ deets.removedSizeCount++;
340
376
  }
341
- }
342
- // Remove oldest entries until we are under max size
343
- const delEntries = Object.entries(meta.objects);
344
- delEntries.sort(([_k_a, a_meta], [_k_b, b_meta]) => {
345
- return a_meta.updatedAt - b_meta.updatedAt;
346
- });
347
- const deletableDelEntries = delEntries.filter(([x]) => !sacredKeys.has(x));
348
- let currentSize = delEntries.reduce((acc, [_k, m]) => {
349
- return acc + m.size;
350
- }, 0);
351
- while (currentSize > 0 &&
352
- currentSize > this._gcOpts.maxSize &&
353
- deletableDelEntries.length) {
354
- const [[k, m]] = deletableDelEntries.splice(0, 1);
355
- currentSize -= m.size;
356
- promises.push(this._persister.removeItem(k));
357
- delete meta.objects[k];
358
- deets.removed.push(k);
359
- deets.removedSizeCount++;
360
- }
361
- // Update meta to remove keys that are no longer in the store
362
- for (const k of Object.keys(meta.objects)) {
363
- if (!keys.has(k) && !sacredKeys.has(k)) {
364
- delete meta.objects[k];
377
+ // Update meta to remove keys that are no longer in the store
378
+ for (const k of Object.keys(meta.objects)) {
379
+ if (!keys.has(k) && !sacredKeys.has(k)) {
380
+ delete meta.objects[k];
381
+ }
365
382
  }
366
- }
367
- if (deets.removed.length || deets.metaRemoved.length) {
368
- // Trigger a flush of the meta
369
- promises.push(this._enqueuePersist({ skipGc: true }));
370
- }
371
- this._log.info('Completed GC', deets);
372
- await Promise.all(promises);
373
- return deets;
383
+ if (deets.removed.length || deets.metaRemoved.length) {
384
+ // Trigger a flush of the meta
385
+ promises.push(this._enqueuePersist({ skipGc: true }));
386
+ }
387
+ this._log.info('Completed GC', deets);
388
+ yield Promise.all(promises);
389
+ return deets;
390
+ });
374
391
  }
375
392
  // Schedules a GC to run in one minute (unless it is already scheduled)
376
393
  gc() {