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