@osdk/client 2.2.0-beta.3 → 2.2.0-beta.4
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 +12 -0
- package/build/browser/Logger.js.map +1 -1
- package/build/browser/observable/ObservableClient.js.map +1 -1
- package/build/browser/observable/internal/ActionApplication.js +102 -0
- package/build/browser/observable/internal/ActionApplication.js.map +1 -0
- package/build/browser/observable/internal/CacheKey.js +38 -1
- package/build/browser/observable/internal/CacheKey.js.map +1 -1
- package/build/browser/observable/internal/CacheKeys.js +4 -4
- package/build/browser/observable/internal/CacheKeys.js.map +1 -1
- package/build/browser/observable/internal/ChangedObjects.js +24 -1
- package/build/browser/observable/internal/ChangedObjects.js.map +1 -1
- package/build/browser/observable/internal/Layer.js +3 -3
- package/build/browser/observable/internal/Layer.js.map +1 -1
- package/build/browser/observable/internal/ListQuery.js +188 -66
- package/build/browser/observable/internal/ListQuery.js.map +1 -1
- package/build/browser/observable/internal/ObjectQuery.js +16 -3
- package/build/browser/observable/internal/ObjectQuery.js.map +1 -1
- package/build/browser/observable/internal/ObservableClientImpl.js +2 -2
- package/build/browser/observable/internal/ObservableClientImpl.js.map +1 -1
- package/build/browser/observable/internal/OptimisticJob.js +30 -29
- package/build/browser/observable/internal/OptimisticJob.js.map +1 -1
- package/build/browser/observable/internal/Query.js +42 -2
- package/build/browser/observable/internal/Query.js.map +1 -1
- package/build/browser/observable/internal/Store.js +259 -126
- package/build/browser/observable/internal/Store.js.map +1 -1
- package/build/browser/observable/internal/Store.test.js +416 -76
- package/build/browser/observable/internal/Store.test.js.map +1 -1
- package/build/browser/observable/internal/testUtils.js +142 -6
- package/build/browser/observable/internal/testUtils.js.map +1 -1
- package/build/browser/util/UserAgent.js +1 -1
- package/build/cjs/index.cjs +1 -1
- package/build/cjs/public/unstable-do-not-use.cjs +657 -268
- package/build/cjs/public/unstable-do-not-use.cjs.map +1 -1
- package/build/cjs/public/unstable-do-not-use.d.cts +13 -4
- package/build/esm/Logger.js.map +1 -1
- package/build/esm/observable/ObservableClient.js.map +1 -1
- package/build/esm/observable/internal/ActionApplication.js +102 -0
- package/build/esm/observable/internal/ActionApplication.js.map +1 -0
- package/build/esm/observable/internal/CacheKey.js +38 -1
- package/build/esm/observable/internal/CacheKey.js.map +1 -1
- package/build/esm/observable/internal/CacheKeys.js +4 -4
- package/build/esm/observable/internal/CacheKeys.js.map +1 -1
- package/build/esm/observable/internal/ChangedObjects.js +24 -1
- package/build/esm/observable/internal/ChangedObjects.js.map +1 -1
- package/build/esm/observable/internal/Layer.js +3 -3
- package/build/esm/observable/internal/Layer.js.map +1 -1
- package/build/esm/observable/internal/ListQuery.js +188 -66
- package/build/esm/observable/internal/ListQuery.js.map +1 -1
- package/build/esm/observable/internal/ObjectQuery.js +16 -3
- package/build/esm/observable/internal/ObjectQuery.js.map +1 -1
- package/build/esm/observable/internal/ObservableClientImpl.js +2 -2
- package/build/esm/observable/internal/ObservableClientImpl.js.map +1 -1
- package/build/esm/observable/internal/OptimisticJob.js +30 -29
- package/build/esm/observable/internal/OptimisticJob.js.map +1 -1
- package/build/esm/observable/internal/Query.js +42 -2
- package/build/esm/observable/internal/Query.js.map +1 -1
- package/build/esm/observable/internal/Store.js +259 -126
- package/build/esm/observable/internal/Store.js.map +1 -1
- package/build/esm/observable/internal/Store.test.js +416 -76
- package/build/esm/observable/internal/Store.test.js.map +1 -1
- package/build/esm/observable/internal/testUtils.js +142 -6
- package/build/esm/observable/internal/testUtils.js.map +1 -1
- package/build/esm/util/UserAgent.js +1 -1
- package/build/types/Logger.d.ts +1 -2
- package/build/types/Logger.d.ts.map +1 -1
- package/build/types/observable/ObservableClient.d.ts +10 -3
- package/build/types/observable/ObservableClient.d.ts.map +1 -1
- package/build/types/observable/internal/ActionApplication.d.ts +9 -0
- package/build/types/observable/internal/ActionApplication.d.ts.map +1 -0
- package/build/types/observable/internal/CacheKeys.d.ts +2 -1
- package/build/types/observable/internal/CacheKeys.d.ts.map +1 -1
- package/build/types/observable/internal/ChangedObjects.d.ts +6 -2
- package/build/types/observable/internal/ChangedObjects.d.ts.map +1 -1
- package/build/types/observable/internal/Layer.d.ts +1 -1
- package/build/types/observable/internal/Layer.d.ts.map +1 -1
- package/build/types/observable/internal/ListQuery.d.ts +18 -17
- package/build/types/observable/internal/ListQuery.d.ts.map +1 -1
- package/build/types/observable/internal/ObjectQuery.d.ts +3 -3
- package/build/types/observable/internal/ObjectQuery.d.ts.map +1 -1
- package/build/types/observable/internal/OptimisticJob.d.ts +2 -2
- package/build/types/observable/internal/OptimisticJob.d.ts.map +1 -1
- package/build/types/observable/internal/Query.d.ts +6 -5
- package/build/types/observable/internal/Query.d.ts.map +1 -1
- package/build/types/observable/internal/Store.d.ts +47 -19
- package/build/types/observable/internal/Store.d.ts.map +1 -1
- package/build/types/observable/internal/testUtils.d.ts +13 -3
- package/build/types/observable/internal/testUtils.d.ts.map +1 -1
- package/package.json +8 -7
|
@@ -4,8 +4,8 @@ var chunkX7WGNFZ4_cjs = require('../chunk-X7WGNFZ4.cjs');
|
|
|
4
4
|
require('../chunk-Q7SFCCGT.cjs');
|
|
5
5
|
var rxjs = require('rxjs');
|
|
6
6
|
var invariant2 = require('tiny-invariant');
|
|
7
|
-
var trie = require('@wry/trie');
|
|
8
7
|
var mnemonist = require('mnemonist');
|
|
8
|
+
var trie = require('@wry/trie');
|
|
9
9
|
var deepEqual = require('fast-deep-equal');
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -22,8 +22,8 @@ var ObservableClientImpl = class {
|
|
|
22
22
|
observeObject(apiName, pk, options, subFn) {
|
|
23
23
|
return this.#store.observeObject(apiName, pk, options, subFn);
|
|
24
24
|
}
|
|
25
|
-
observeList(
|
|
26
|
-
return this.#store.observeList(
|
|
25
|
+
observeList(options, subFn) {
|
|
26
|
+
return this.#store.observeList(options, subFn);
|
|
27
27
|
}
|
|
28
28
|
applyAction(action, args, opts) {
|
|
29
29
|
return this.#store.applyAction(action, args, opts);
|
|
@@ -33,6 +33,10 @@ var ObservableClientImpl = class {
|
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
// src/observable/DebugFlags.ts
|
|
37
|
+
process.env.NODE_ENV !== "production" && false;
|
|
38
|
+
var DEBUG_CACHE_KEYS = process.env.NODE_ENV !== "production" && false;
|
|
39
|
+
|
|
36
40
|
// ../../node_modules/.pnpm/is-node-process@1.2.0/node_modules/is-node-process/lib/index.mjs
|
|
37
41
|
function isNodeProcess() {
|
|
38
42
|
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
@@ -86,9 +90,200 @@ async function delay(durationOrMode) {
|
|
|
86
90
|
return new Promise((resolve) => setTimeout(resolve, delayTime));
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
// src/observable/
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
// src/observable/internal/CacheKey.ts
|
|
94
|
+
function DEBUG_ONLY__cacheKeyToString(x) {
|
|
95
|
+
if (process.env.NODE_ENV !== "production") {
|
|
96
|
+
return `${x.type}CacheKey<${x.otherKeys.map((xx) => JSON.stringify(xx)).join(", ")}>`.replaceAll('"', "'");
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error("not implemented");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function DEBUG_ONLY__cacheKeysToString(x) {
|
|
102
|
+
if (process.env.NODE_ENV !== "production") {
|
|
103
|
+
return JSON.stringify(x.map(DEBUG_ONLY__cacheKeyToString), null, 2);
|
|
104
|
+
} else {
|
|
105
|
+
throw new Error("not implemented");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/observable/internal/ChangedObjects.ts
|
|
110
|
+
function createChangedObjects() {
|
|
111
|
+
return {
|
|
112
|
+
modifiedObjects: new mnemonist.MultiMap(),
|
|
113
|
+
addedObjects: new mnemonist.MultiMap(),
|
|
114
|
+
addedLists: /* @__PURE__ */ new Set(),
|
|
115
|
+
modifiedLists: /* @__PURE__ */ new Set()
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function DEBUG_ONLY__changesToString(changes) {
|
|
119
|
+
if (process.env.NODE_ENV !== "production") {
|
|
120
|
+
return JSON.stringify({
|
|
121
|
+
modifiedObjects: multimapHelper(changes.modifiedObjects),
|
|
122
|
+
addedObjects: multimapHelper(changes.addedObjects),
|
|
123
|
+
addedLists: listHelper(changes.addedLists),
|
|
124
|
+
modifiedLists: listHelper(changes.modifiedLists)
|
|
125
|
+
}, null, 2);
|
|
126
|
+
} else {
|
|
127
|
+
throw new Error("not implemented");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function listHelper(set) {
|
|
131
|
+
return Array.from(set).map(DEBUG_ONLY__cacheKeyToString);
|
|
132
|
+
}
|
|
133
|
+
function multimapHelper(multimap) {
|
|
134
|
+
return Object.fromEntries(Array.from(multimap.associations()).map(([type, objects]) => {
|
|
135
|
+
return [type, objects.map((o) => o.$primaryKey)];
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/observable/internal/OptimisticId.ts
|
|
140
|
+
function createOptimisticId() {
|
|
141
|
+
if (process.env.NODE_ENV !== "production") {
|
|
142
|
+
if (createOptimisticId.counter === undefined) {
|
|
143
|
+
createOptimisticId.counter = 0;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
__optimisticId: createOptimisticId.counter++
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return /* @__PURE__ */ Object.create(null);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/observable/internal/OptimisticJob.ts
|
|
153
|
+
var OptimisticJob = class {
|
|
154
|
+
#result;
|
|
155
|
+
constructor(store, optimisticId) {
|
|
156
|
+
const updatedObjects = [];
|
|
157
|
+
const addedObjectPromises = [];
|
|
158
|
+
this.getResult = () => {
|
|
159
|
+
return this.#result ??= (async () => {
|
|
160
|
+
const addedObjects = await Promise.allSettled(addedObjectPromises);
|
|
161
|
+
const {
|
|
162
|
+
batchResult
|
|
163
|
+
} = store.batch({
|
|
164
|
+
optimisticId
|
|
165
|
+
}, (batch) => {
|
|
166
|
+
for (const obj of addedObjects) {
|
|
167
|
+
if (obj.status === "fulfilled") {
|
|
168
|
+
store.getObjectQuery(obj.value.$objectType, obj.value.$primaryKey).writeToStore(obj.value, "loading", batch);
|
|
169
|
+
} else {
|
|
170
|
+
throw obj;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
for (const obj of updatedObjects) {
|
|
174
|
+
store.getObjectQuery(obj.$objectType, obj.$primaryKey).writeToStore(obj, "loading", batch);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return batchResult.changes;
|
|
178
|
+
})();
|
|
179
|
+
};
|
|
180
|
+
this.context = {
|
|
181
|
+
updateObject(value) {
|
|
182
|
+
updatedObjects.push(value);
|
|
183
|
+
return this;
|
|
184
|
+
},
|
|
185
|
+
createObject(type, pk, properties) {
|
|
186
|
+
const create = store.client[chunkX7WGNFZ4_cjs.additionalContext].objectFactory2(store.client[chunkX7WGNFZ4_cjs.additionalContext], [{
|
|
187
|
+
$primaryKey: pk,
|
|
188
|
+
$apiName: type.apiName,
|
|
189
|
+
$objectType: type.apiName,
|
|
190
|
+
...properties
|
|
191
|
+
}], undefined).then((objs) => {
|
|
192
|
+
return objs[0];
|
|
193
|
+
});
|
|
194
|
+
addedObjectPromises.push(create);
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
function runOptimisticJob(store, optimisticUpdate) {
|
|
201
|
+
if (!optimisticUpdate) {
|
|
202
|
+
return () => Promise.resolve();
|
|
203
|
+
}
|
|
204
|
+
const optimisticId = createOptimisticId();
|
|
205
|
+
const job = new OptimisticJob(store, optimisticId);
|
|
206
|
+
optimisticUpdate(job.context);
|
|
207
|
+
const optimisticApplicationDone = job.getResult();
|
|
208
|
+
return () => {
|
|
209
|
+
return optimisticApplicationDone.then(
|
|
210
|
+
// we don't want to leak the result
|
|
211
|
+
() => undefined
|
|
212
|
+
).finally(() => {
|
|
213
|
+
store.removeLayer(optimisticId);
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/observable/internal/ActionApplication.ts
|
|
219
|
+
var ACTION_DELAY = process.env.NODE_ENV === "production" ? 0 : 1e3;
|
|
220
|
+
var ActionApplication = class {
|
|
221
|
+
constructor(store) {
|
|
222
|
+
this.store = store;
|
|
223
|
+
}
|
|
224
|
+
applyAction = (action, args, {
|
|
225
|
+
optimisticUpdate
|
|
226
|
+
} = {}) => {
|
|
227
|
+
const removeOptimisticResult = runOptimisticJob(this.store, optimisticUpdate);
|
|
228
|
+
return (async () => {
|
|
229
|
+
try {
|
|
230
|
+
const actionResults = await this.store.client(action).applyAction(args, {
|
|
231
|
+
$returnEdits: true
|
|
232
|
+
});
|
|
233
|
+
if (ACTION_DELAY > 0) {
|
|
234
|
+
console.log("action done, pausing");
|
|
235
|
+
await delay(ACTION_DELAY);
|
|
236
|
+
console.log("action done, pausing done");
|
|
237
|
+
}
|
|
238
|
+
await this.#invalidateActionEditResponse(actionResults);
|
|
239
|
+
return actionResults;
|
|
240
|
+
} finally {
|
|
241
|
+
if (process.env.NODE_ENV !== "production") {
|
|
242
|
+
this.store.logger?.debug("optimistic action complete; remove the results");
|
|
243
|
+
}
|
|
244
|
+
await removeOptimisticResult();
|
|
245
|
+
}
|
|
246
|
+
})();
|
|
247
|
+
};
|
|
248
|
+
#invalidateActionEditResponse = async (value) => {
|
|
249
|
+
const typesToInvalidate = /* @__PURE__ */ new Set();
|
|
250
|
+
let changes;
|
|
251
|
+
if (value.type === "edits") {
|
|
252
|
+
const promisesToWait = [];
|
|
253
|
+
for (const obj of value.modifiedObjects) {
|
|
254
|
+
promisesToWait.push(this.store.invalidateObject(obj.objectType, obj.primaryKey));
|
|
255
|
+
}
|
|
256
|
+
for (const obj of value.addedObjects) {
|
|
257
|
+
promisesToWait.push(this.store.invalidateObject(obj.objectType, obj.primaryKey));
|
|
258
|
+
typesToInvalidate.add(obj.objectType);
|
|
259
|
+
}
|
|
260
|
+
await Promise.all(promisesToWait);
|
|
261
|
+
changes = this.#changesFromActionEditResponse(value);
|
|
262
|
+
await this.store.maybeRevalidateLists(changes);
|
|
263
|
+
} else {
|
|
264
|
+
for (const apiName of value.editedObjectTypes) {
|
|
265
|
+
typesToInvalidate.add(apiName.toString());
|
|
266
|
+
await this.store.invalidateObjectType(apiName, changes);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return value;
|
|
270
|
+
};
|
|
271
|
+
#changesFromActionEditResponse = (value) => {
|
|
272
|
+
const changes = createChangedObjects();
|
|
273
|
+
for (const changeType of ["addedObjects", "modifiedObjects"]) {
|
|
274
|
+
for (const {
|
|
275
|
+
objectType,
|
|
276
|
+
primaryKey
|
|
277
|
+
} of value[changeType] ?? []) {
|
|
278
|
+
const obj = this.store.getObject(objectType, primaryKey);
|
|
279
|
+
if (obj) {
|
|
280
|
+
changes[changeType].set(objectType, obj);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return changes;
|
|
285
|
+
};
|
|
286
|
+
};
|
|
92
287
|
var CacheKeys = class {
|
|
93
288
|
#cacheKeys = new trie.Trie(false, (keys) => {
|
|
94
289
|
const ret = {
|
|
@@ -100,15 +295,15 @@ var CacheKeys = class {
|
|
|
100
295
|
});
|
|
101
296
|
#cacheKeyFactories = /* @__PURE__ */ new Map();
|
|
102
297
|
#onCreate;
|
|
103
|
-
constructor(whereCanonicalizer, onCreate) {
|
|
298
|
+
constructor(whereCanonicalizer, orderByCanonicalizer, onCreate) {
|
|
104
299
|
this.#onCreate = onCreate;
|
|
105
300
|
this.#registerCacheKeyFactory("object", (apiName, pk) => {
|
|
106
301
|
if (process.env.NODE_ENV !== "production" && DEBUG_CACHE_KEYS) ;
|
|
107
302
|
return this.#cacheKeys.lookupArray(["object", apiName, pk]);
|
|
108
303
|
});
|
|
109
|
-
this.#registerCacheKeyFactory("list", (apiName, where) => {
|
|
304
|
+
this.#registerCacheKeyFactory("list", (apiName, where, orderBy) => {
|
|
110
305
|
if (process.env.NODE_ENV !== "production" && DEBUG_CACHE_KEYS) ;
|
|
111
|
-
return this.#cacheKeys.lookupArray(["list", apiName, whereCanonicalizer.canonicalize(where)]);
|
|
306
|
+
return this.#cacheKeys.lookupArray(["list", apiName, whereCanonicalizer.canonicalize(where), orderByCanonicalizer.canonicalize(orderBy)]);
|
|
112
307
|
});
|
|
113
308
|
}
|
|
114
309
|
#registerCacheKeyFactory(type, factory) {
|
|
@@ -123,12 +318,6 @@ var CacheKeys = class {
|
|
|
123
318
|
this.#cacheKeys.remove(cacheKey.type, ...cacheKey.otherKeys);
|
|
124
319
|
}
|
|
125
320
|
};
|
|
126
|
-
function createChangedObjects() {
|
|
127
|
-
return {
|
|
128
|
-
modifiedObjects: new mnemonist.MultiMap(),
|
|
129
|
-
addedObjects: new mnemonist.MultiMap()
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
321
|
|
|
133
322
|
// src/observable/internal/WeakMapWithEntries.ts
|
|
134
323
|
var WeakMapWithEntries = class {
|
|
@@ -262,7 +451,7 @@ var Layer = class _Layer {
|
|
|
262
451
|
this.#parent = this.#parent.removeLayer(layerId);
|
|
263
452
|
return this;
|
|
264
453
|
}
|
|
265
|
-
return this.#parent
|
|
454
|
+
return this.#parent.removeLayer(layerId);
|
|
266
455
|
}
|
|
267
456
|
entries() {
|
|
268
457
|
return this.#cache.entries();
|
|
@@ -275,11 +464,11 @@ var Layer = class _Layer {
|
|
|
275
464
|
}
|
|
276
465
|
};
|
|
277
466
|
var Entry = class {
|
|
278
|
-
constructor(cacheKey, value, lastUpdated) {
|
|
467
|
+
constructor(cacheKey, value, lastUpdated, status = "init") {
|
|
279
468
|
this.cacheKey = cacheKey;
|
|
280
469
|
this.value = value;
|
|
281
470
|
this.lastUpdated = lastUpdated;
|
|
282
|
-
this.status =
|
|
471
|
+
this.status = status;
|
|
283
472
|
}
|
|
284
473
|
};
|
|
285
474
|
function is$and(whereClause) {
|
|
@@ -374,11 +563,15 @@ var Query = class {
|
|
|
374
563
|
#connectable;
|
|
375
564
|
#subscription;
|
|
376
565
|
#subject;
|
|
377
|
-
|
|
566
|
+
/** @internal */
|
|
567
|
+
constructor(store, observable, opts, cacheKey, logger) {
|
|
378
568
|
this.options = opts;
|
|
379
569
|
this.cacheKey = cacheKey;
|
|
380
570
|
this.store = store;
|
|
381
571
|
this.#subject = observable;
|
|
572
|
+
this.logger = logger ?? (process.env.NODE_ENV === "production" ? store.client[chunkX7WGNFZ4_cjs.additionalContext].logger : store.client[chunkX7WGNFZ4_cjs.additionalContext].logger?.child({}, {
|
|
573
|
+
msgPrefix: process.env.NODE_ENV !== "production" ? `Query<${cacheKey.type}, ${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>` : "Query"
|
|
574
|
+
}));
|
|
382
575
|
}
|
|
383
576
|
subscribe(observer) {
|
|
384
577
|
this.#connectable ??= this._createConnectable(this.#subject);
|
|
@@ -386,6 +579,11 @@ var Query = class {
|
|
|
386
579
|
return this.#connectable.subscribe(observer);
|
|
387
580
|
}
|
|
388
581
|
revalidate(force) {
|
|
582
|
+
if (process.env.NODE_ENV !== "production") {
|
|
583
|
+
this.logger?.info({
|
|
584
|
+
methodName: "revalidate"
|
|
585
|
+
});
|
|
586
|
+
}
|
|
389
587
|
if (force) {
|
|
390
588
|
this.abortController?.abort();
|
|
391
589
|
}
|
|
@@ -393,6 +591,11 @@ var Query = class {
|
|
|
393
591
|
return this.pendingFetch;
|
|
394
592
|
}
|
|
395
593
|
if ((this.options.dedupeInterval ?? 0) > 0 && this.lastFetchStarted != null && Date.now() - this.lastFetchStarted < (this.options.dedupeInterval ?? 0)) {
|
|
594
|
+
if (process.env.NODE_ENV !== "production") {
|
|
595
|
+
this.logger?.trace({
|
|
596
|
+
methodName: "revalidate"
|
|
597
|
+
}, "DEDUPE");
|
|
598
|
+
}
|
|
396
599
|
return Promise.resolve();
|
|
397
600
|
}
|
|
398
601
|
this.store.batch({}, (batch) => {
|
|
@@ -400,14 +603,37 @@ var Query = class {
|
|
|
400
603
|
});
|
|
401
604
|
this._preFetch();
|
|
402
605
|
this.lastFetchStarted = Date.now();
|
|
403
|
-
|
|
606
|
+
if (process.env.NODE_ENV !== "production") {
|
|
607
|
+
this.logger?.trace({
|
|
608
|
+
methodName: "revalidate"
|
|
609
|
+
}, "calling _fetch()");
|
|
610
|
+
}
|
|
611
|
+
this.pendingFetch = this._fetch().catch((e) => {
|
|
612
|
+
this.logger?.error({
|
|
613
|
+
methodName: "revalidate"
|
|
614
|
+
}, "_fetch() FAILED", e);
|
|
615
|
+
throw e;
|
|
616
|
+
}).finally(() => {
|
|
617
|
+
this.logger?.info({
|
|
618
|
+
methodName: "revalidate"
|
|
619
|
+
}, "finally _fetch()");
|
|
404
620
|
this.pendingFetch = undefined;
|
|
405
621
|
});
|
|
622
|
+
if (process.env.NODE_ENV !== "production") {
|
|
623
|
+
this.logger?.info({
|
|
624
|
+
methodName: "revalidate"
|
|
625
|
+
}, "Returning");
|
|
626
|
+
}
|
|
406
627
|
return this.pendingFetch;
|
|
407
628
|
}
|
|
408
629
|
_preFetch() {
|
|
409
630
|
}
|
|
410
631
|
setStatus(status, batch) {
|
|
632
|
+
if (process.env.NODE_ENV !== "production") {
|
|
633
|
+
this.logger?.trace({
|
|
634
|
+
methodName: "setStatus"
|
|
635
|
+
}, status);
|
|
636
|
+
}
|
|
411
637
|
const existing = batch.read(this.cacheKey);
|
|
412
638
|
if (existing?.status === status) return;
|
|
413
639
|
batch.write(this.cacheKey, existing?.value, status);
|
|
@@ -424,7 +650,6 @@ var Query = class {
|
|
|
424
650
|
};
|
|
425
651
|
|
|
426
652
|
// src/observable/internal/ListQuery.ts
|
|
427
|
-
rxjs.auditTime(0);
|
|
428
653
|
var ListQuery = class extends Query {
|
|
429
654
|
// pageSize?: number; // this is the internal page size. we need to track this properly
|
|
430
655
|
#client;
|
|
@@ -435,16 +660,23 @@ var ListQuery = class extends Query {
|
|
|
435
660
|
#nextPageToken;
|
|
436
661
|
#pendingPageFetch;
|
|
437
662
|
#toRelease = /* @__PURE__ */ new Set();
|
|
438
|
-
|
|
439
|
-
|
|
663
|
+
#orderBy;
|
|
664
|
+
constructor(store, subject, objectType, whereClause, orderBy, cacheKey, opts) {
|
|
665
|
+
super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[chunkX7WGNFZ4_cjs.additionalContext].logger?.child({}, {
|
|
666
|
+
msgPrefix: `ListQuery<${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>`
|
|
667
|
+
}) : undefined);
|
|
440
668
|
this.#client = store.client;
|
|
441
|
-
this.#type =
|
|
669
|
+
this.#type = objectType;
|
|
442
670
|
this.#whereClause = whereClause;
|
|
671
|
+
this.#orderBy = orderBy;
|
|
443
672
|
rxjs.observeOn(rxjs.asyncScheduler);
|
|
444
673
|
}
|
|
674
|
+
get canonicalWhere() {
|
|
675
|
+
return this.#whereClause;
|
|
676
|
+
}
|
|
445
677
|
_createConnectable(subject) {
|
|
446
678
|
return rxjs.connectable(subject.pipe(
|
|
447
|
-
rxjs.
|
|
679
|
+
rxjs.switchMap((listEntry) => {
|
|
448
680
|
return rxjs.combineLatest({
|
|
449
681
|
resolvedList: listEntry?.value?.data == null ? rxjs.of([]) : rxjs.combineLatest(listEntry.value.data.map((cacheKey) => this.store.getSubject(cacheKey).pipe(rxjs.map((objectEntry) => objectEntry?.value)))),
|
|
450
682
|
isOptimistic: rxjs.of(listEntry.isOptimistic),
|
|
@@ -518,7 +750,12 @@ var ListQuery = class extends Query {
|
|
|
518
750
|
nextPageToken
|
|
519
751
|
} = await objectSet.fetchPage({
|
|
520
752
|
$nextPageToken: this.#nextPageToken,
|
|
521
|
-
$pageSize: this.options.pageSize
|
|
753
|
+
$pageSize: this.options.pageSize,
|
|
754
|
+
// For now this keeps the shared test code from falling apart
|
|
755
|
+
// but shouldn't be needed ideally
|
|
756
|
+
...Object.keys(this.#orderBy).length > 0 ? {
|
|
757
|
+
$orderBy: this.#orderBy
|
|
758
|
+
} : {}
|
|
522
759
|
});
|
|
523
760
|
if (signal?.aborted) {
|
|
524
761
|
return;
|
|
@@ -527,70 +764,121 @@ var ListQuery = class extends Query {
|
|
|
527
764
|
const {
|
|
528
765
|
retVal
|
|
529
766
|
} = this.store.batch({}, (batch) => {
|
|
530
|
-
return this.updateList(data, append, nextPageToken ? status : "loaded", batch);
|
|
767
|
+
return this.updateList(this.store.updateObjects(data, batch), append, nextPageToken ? status : "loaded", batch);
|
|
531
768
|
});
|
|
532
769
|
return retVal;
|
|
533
770
|
}
|
|
534
771
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
772
|
+
* Note: This method is not async because I want it to return right after it
|
|
773
|
+
* finishes the synchronous updates. The promise that is returned
|
|
774
|
+
* will resolve after the revalidation is complete.
|
|
775
|
+
* @param changes
|
|
538
776
|
* @param optimisticId
|
|
539
|
-
* @returns
|
|
777
|
+
* @returns If revalidation is needed, a promise that resolves after the
|
|
778
|
+
* revalidation is complete. Otherwise, undefined.
|
|
540
779
|
*/
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
780
|
+
maybeUpdateAndRevalidate = (changes, optimisticId) => {
|
|
781
|
+
if (process.env.NODE_ENV !== "production") {
|
|
782
|
+
this.logger?.info({
|
|
783
|
+
methodName: "#maybeMaybe"
|
|
784
|
+
}, DEBUG_ONLY__changesToString(changes));
|
|
785
|
+
}
|
|
786
|
+
if (changes.modifiedLists.has(this.cacheKey)) return;
|
|
787
|
+
try {
|
|
788
|
+
const relevantObjects = {
|
|
789
|
+
added: {
|
|
790
|
+
all: changes.addedObjects.get(this.cacheKey.otherKeys[0]) ?? [],
|
|
791
|
+
strictMatches: /* @__PURE__ */ new Set(),
|
|
792
|
+
sortaMatches: /* @__PURE__ */ new Set()
|
|
793
|
+
},
|
|
794
|
+
modified: {
|
|
795
|
+
all: changes.modifiedObjects.get(this.cacheKey.otherKeys[0]) ?? [],
|
|
796
|
+
strictMatches: /* @__PURE__ */ new Set(),
|
|
797
|
+
sortaMatches: /* @__PURE__ */ new Set()
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
if (relevantObjects.added.all.length === 0 && relevantObjects.modified.all.length === 0) {
|
|
801
|
+
return;
|
|
547
802
|
}
|
|
548
|
-
for (const
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
803
|
+
for (const group of Object.values(relevantObjects)) {
|
|
804
|
+
for (const obj of group.all ?? []) {
|
|
805
|
+
const strictMatch = objectSortaMatchesWhereClause(obj, this.#whereClause, true);
|
|
806
|
+
if (strictMatch) {
|
|
807
|
+
group.strictMatches.add(obj);
|
|
808
|
+
} else {
|
|
809
|
+
const sortaMatch = objectSortaMatchesWhereClause(obj, this.#whereClause, false);
|
|
810
|
+
if (sortaMatch) {
|
|
811
|
+
group.sortaMatches.add(obj);
|
|
812
|
+
}
|
|
556
813
|
}
|
|
557
814
|
}
|
|
558
815
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
816
|
+
const status = optimisticId || relevantObjects.added.sortaMatches.size > 0 || relevantObjects.modified.sortaMatches.size > 0 ? "loading" : "loaded";
|
|
817
|
+
changes.modifiedLists.add(this.cacheKey);
|
|
818
|
+
const newList = [];
|
|
819
|
+
let needsRevalidation = false;
|
|
562
820
|
this.store.batch({
|
|
563
|
-
optimisticId
|
|
821
|
+
optimisticId,
|
|
822
|
+
changes
|
|
564
823
|
}, (batch) => {
|
|
565
|
-
|
|
824
|
+
const curValue = batch.read(this.cacheKey);
|
|
825
|
+
const existingList = new Set(curValue?.value?.data);
|
|
826
|
+
const toAdd = new Set(
|
|
827
|
+
// easy case. objects are new to the cache and they match this filter
|
|
828
|
+
relevantObjects.added.strictMatches
|
|
829
|
+
);
|
|
830
|
+
const toRemove = /* @__PURE__ */ new Set();
|
|
831
|
+
for (const obj of relevantObjects.modified.all) {
|
|
832
|
+
if (relevantObjects.modified.strictMatches.has(obj)) {
|
|
833
|
+
const existingObjectCacheKey = this.store.getCacheKey("object", obj.$apiName, obj.$primaryKey);
|
|
834
|
+
if (!existingList.has(existingObjectCacheKey)) {
|
|
835
|
+
toAdd.add(obj);
|
|
836
|
+
}
|
|
837
|
+
continue;
|
|
838
|
+
} else if (batch.optimisticWrite) {
|
|
839
|
+
continue;
|
|
840
|
+
} else {
|
|
841
|
+
const existingObjectCacheKey = this.store.getCacheKey("object", obj.$apiName, obj.$primaryKey);
|
|
842
|
+
toRemove.add(existingObjectCacheKey);
|
|
843
|
+
if (relevantObjects.modified.sortaMatches.has(obj)) {
|
|
844
|
+
needsRevalidation = true;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
for (const key of existingList) {
|
|
849
|
+
if (toRemove.has(key)) continue;
|
|
850
|
+
newList.push(key);
|
|
851
|
+
}
|
|
852
|
+
for (const obj of toAdd) {
|
|
853
|
+
newList.push(this.store.getCacheKey("object", obj.$apiName, obj.$primaryKey));
|
|
854
|
+
}
|
|
855
|
+
this.updateList(
|
|
856
|
+
newList,
|
|
857
|
+
/* append */
|
|
858
|
+
false,
|
|
859
|
+
status,
|
|
860
|
+
batch
|
|
861
|
+
);
|
|
566
862
|
});
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
maybeRevalidate(changedObjects) {
|
|
571
|
-
let needsRevalidation = false;
|
|
572
|
-
for (const [type, objects] of changedObjects.addedObjects.associations()) {
|
|
573
|
-
if (this.cacheKey.otherKeys[0] !== type) {
|
|
574
|
-
continue;
|
|
863
|
+
if (needsRevalidation) {
|
|
864
|
+
changes.modifiedLists.add(this.cacheKey);
|
|
865
|
+
return this.revalidate(true).then(() => void 0);
|
|
575
866
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
867
|
+
return void 0;
|
|
868
|
+
} finally {
|
|
869
|
+
if (process.env.NODE_ENV !== "production") {
|
|
870
|
+
this.logger?.trace({
|
|
871
|
+
methodName: "#maybeMaybe"
|
|
872
|
+
}, "in finally");
|
|
581
873
|
}
|
|
582
874
|
}
|
|
583
|
-
|
|
584
|
-
|
|
875
|
+
};
|
|
876
|
+
updateList(objectCacheKeys, append, status, batch) {
|
|
877
|
+
if (process.env.NODE_ENV !== "production") {
|
|
878
|
+
this.logger?.trace({
|
|
879
|
+
methodName: "updateList"
|
|
880
|
+
}, `{status: ${status}}`, JSON.stringify(objectCacheKeys, null, 2));
|
|
585
881
|
}
|
|
586
|
-
return Promise.resolve();
|
|
587
|
-
}
|
|
588
|
-
updateList(values, append, status, batch) {
|
|
589
|
-
let objectCacheKeys = values.map((v) => {
|
|
590
|
-
if (v instanceof Entry) return v.cacheKey;
|
|
591
|
-
this.store.getObjectQuery(this.#type, v.$primaryKey).writeToStore(v, "loaded", batch);
|
|
592
|
-
return this.store.getCacheKey("object", v.$apiName, v.$primaryKey);
|
|
593
|
-
});
|
|
594
882
|
const existingList = batch.read(this.cacheKey);
|
|
595
883
|
if (!batch.optimisticWrite) {
|
|
596
884
|
if (!append) {
|
|
@@ -607,17 +895,67 @@ var ListQuery = class extends Query {
|
|
|
607
895
|
if (append) {
|
|
608
896
|
objectCacheKeys = [...existingList?.value?.data ?? [], ...objectCacheKeys];
|
|
609
897
|
}
|
|
898
|
+
if (Object.keys(this.#orderBy).length > 0) {
|
|
899
|
+
if (process.env.NODE_ENV !== "production") {
|
|
900
|
+
this.logger?.info({
|
|
901
|
+
methodName: "updateList"
|
|
902
|
+
}, "Sorting entries");
|
|
903
|
+
this.logger?.trace({
|
|
904
|
+
methodName: "updateList"
|
|
905
|
+
}, DEBUG_ONLY__cacheKeysToString(objectCacheKeys));
|
|
906
|
+
}
|
|
907
|
+
const sortFns = Object.entries(this.#orderBy).map(([key, order]) => {
|
|
908
|
+
return (a, b) => {
|
|
909
|
+
const aValue = a?.[key];
|
|
910
|
+
const bValue = b?.[key];
|
|
911
|
+
if (aValue == null && bValue == null) {
|
|
912
|
+
return 0;
|
|
913
|
+
}
|
|
914
|
+
if (aValue == null) {
|
|
915
|
+
return 1;
|
|
916
|
+
}
|
|
917
|
+
if (bValue == null) {
|
|
918
|
+
return -1;
|
|
919
|
+
}
|
|
920
|
+
const m = order === "asc" ? -1 : 1;
|
|
921
|
+
return aValue < bValue ? m : aValue > bValue ? -m : 0;
|
|
922
|
+
};
|
|
923
|
+
});
|
|
924
|
+
objectCacheKeys = objectCacheKeys.sort((a, b) => {
|
|
925
|
+
for (const sortFn of sortFns) {
|
|
926
|
+
const ret = sortFn(batch.read(a)?.value, batch.read(b)?.value);
|
|
927
|
+
if (ret !== 0) {
|
|
928
|
+
return ret;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return 0;
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
const visited = /* @__PURE__ */ new Set();
|
|
935
|
+
objectCacheKeys = objectCacheKeys.filter((key) => {
|
|
936
|
+
batch.read(key);
|
|
937
|
+
if (visited.has(key)) {
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
visited.add(key);
|
|
941
|
+
return true;
|
|
942
|
+
});
|
|
610
943
|
return this.writeToStore({
|
|
611
944
|
data: objectCacheKeys
|
|
612
945
|
}, status, batch);
|
|
613
946
|
}
|
|
614
947
|
writeToStore(data, status, batch) {
|
|
948
|
+
if (process.env.NODE_ENV !== "production") {
|
|
949
|
+
this.logger?.trace({
|
|
950
|
+
methodName: "writeToStore"
|
|
951
|
+
}, `{status: ${status}},`, DEBUG_ONLY__cacheKeysToString(data.data));
|
|
952
|
+
}
|
|
615
953
|
const entry = batch.read(this.cacheKey);
|
|
616
954
|
if (entry && deepEqual__default.default(data, entry.value)) {
|
|
617
955
|
return batch.write(this.cacheKey, entry.value, status);
|
|
618
956
|
}
|
|
619
957
|
const ret = batch.write(this.cacheKey, data, status);
|
|
620
|
-
batch.modifiedLists.add(this.cacheKey);
|
|
958
|
+
batch.changes.modifiedLists.add(this.cacheKey);
|
|
621
959
|
return ret;
|
|
622
960
|
}
|
|
623
961
|
_dispose() {
|
|
@@ -639,7 +977,9 @@ var ObjectQuery = class extends Query {
|
|
|
639
977
|
#apiName;
|
|
640
978
|
#pk;
|
|
641
979
|
constructor(store, subject, type, pk, cacheKey, opts) {
|
|
642
|
-
super(store, subject, opts, cacheKey
|
|
980
|
+
super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[chunkX7WGNFZ4_cjs.additionalContext].logger?.child({}, {
|
|
981
|
+
msgPrefix: `ObjectQuery<${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>`
|
|
982
|
+
}) : undefined);
|
|
643
983
|
this.#apiName = type;
|
|
644
984
|
this.#pk = pk;
|
|
645
985
|
}
|
|
@@ -661,6 +1001,11 @@ var ObjectQuery = class extends Query {
|
|
|
661
1001
|
});
|
|
662
1002
|
}
|
|
663
1003
|
async _fetch() {
|
|
1004
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1005
|
+
this.logger?.info({
|
|
1006
|
+
methodName: "_fetch"
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
664
1009
|
const objectSet = this.store.client({
|
|
665
1010
|
type: "object",
|
|
666
1011
|
apiName: this.#apiName
|
|
@@ -671,103 +1016,25 @@ var ObjectQuery = class extends Query {
|
|
|
671
1016
|
});
|
|
672
1017
|
}
|
|
673
1018
|
writeToStore(data, status, batch) {
|
|
1019
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1020
|
+
this.logger?.trace({
|
|
1021
|
+
methodName: "writeToStore"
|
|
1022
|
+
}, `{status: ${status}},`, data);
|
|
1023
|
+
}
|
|
674
1024
|
const entry = batch.read(this.cacheKey);
|
|
675
1025
|
if (entry && deepEqual__default.default(data, entry.value)) {
|
|
676
1026
|
return batch.write(this.cacheKey, entry.value, status);
|
|
677
1027
|
}
|
|
678
1028
|
const ret = batch.write(this.cacheKey, data, status);
|
|
679
1029
|
if (entry) {
|
|
680
|
-
batch.modifiedObjects.
|
|
1030
|
+
batch.changes.modifiedObjects.set(data.$apiName, data);
|
|
681
1031
|
} else {
|
|
682
|
-
batch.addedObjects.
|
|
1032
|
+
batch.changes.addedObjects.set(data.$apiName, data);
|
|
683
1033
|
}
|
|
684
1034
|
return ret;
|
|
685
1035
|
}
|
|
686
1036
|
};
|
|
687
1037
|
|
|
688
|
-
// src/observable/internal/OptimisticId.ts
|
|
689
|
-
function createOptimisticId() {
|
|
690
|
-
if (process.env.NODE_ENV !== "production") {
|
|
691
|
-
if (createOptimisticId.counter === undefined) {
|
|
692
|
-
createOptimisticId.counter = 0;
|
|
693
|
-
}
|
|
694
|
-
return {
|
|
695
|
-
__optimisticId: createOptimisticId.counter++
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
|
-
return /* @__PURE__ */ Object.create(null);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
// src/observable/internal/OptimisticJob.ts
|
|
702
|
-
var OptimisticJob = class {
|
|
703
|
-
#result;
|
|
704
|
-
constructor(store, optimisticId) {
|
|
705
|
-
const updatedObjects = [];
|
|
706
|
-
const addedObjects = [];
|
|
707
|
-
this.getResult = () => {
|
|
708
|
-
return this.#result ??= (async () => {
|
|
709
|
-
const changes = {
|
|
710
|
-
addedObjects: new mnemonist.MultiMap(),
|
|
711
|
-
modifiedObjects: new mnemonist.MultiMap()
|
|
712
|
-
};
|
|
713
|
-
const settled = await Promise.allSettled(addedObjects);
|
|
714
|
-
for (const added of settled) {
|
|
715
|
-
if (added.status === "fulfilled") {
|
|
716
|
-
changes.addedObjects.set(added.value.$objectType, added.value);
|
|
717
|
-
} else {
|
|
718
|
-
throw added;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
for (const modified of updatedObjects) {
|
|
722
|
-
changes.modifiedObjects.set(modified.$apiName, modified);
|
|
723
|
-
}
|
|
724
|
-
store.batch({
|
|
725
|
-
optimisticId
|
|
726
|
-
}, (batch) => {
|
|
727
|
-
for (const a of ["addedObjects", "modifiedObjects"]) {
|
|
728
|
-
for (const b of changes[a].values()) {
|
|
729
|
-
store.getObjectQuery(b.$objectType, b.$primaryKey).writeToStore(b, "loading", batch);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
});
|
|
733
|
-
return changes;
|
|
734
|
-
})();
|
|
735
|
-
};
|
|
736
|
-
this.context = {
|
|
737
|
-
updateObject(value) {
|
|
738
|
-
updatedObjects.push(value);
|
|
739
|
-
return this;
|
|
740
|
-
},
|
|
741
|
-
createObject(type, pk, properties) {
|
|
742
|
-
const create = store.client[chunkX7WGNFZ4_cjs.additionalContext].objectFactory2(store.client[chunkX7WGNFZ4_cjs.additionalContext], [{
|
|
743
|
-
$primaryKey: pk,
|
|
744
|
-
$apiName: type.apiName,
|
|
745
|
-
$objectType: type.apiName,
|
|
746
|
-
...properties
|
|
747
|
-
}], undefined).then((x) => x[0]);
|
|
748
|
-
addedObjects.push(create);
|
|
749
|
-
return this;
|
|
750
|
-
}
|
|
751
|
-
};
|
|
752
|
-
}
|
|
753
|
-
};
|
|
754
|
-
function runOptimisticJob(store, optimisticUpdate) {
|
|
755
|
-
if (!optimisticUpdate) {
|
|
756
|
-
return () => Promise.resolve();
|
|
757
|
-
}
|
|
758
|
-
const optimisticId = createOptimisticId();
|
|
759
|
-
const job = new OptimisticJob(store, optimisticId);
|
|
760
|
-
optimisticUpdate(job.context);
|
|
761
|
-
const optimisticApplicationDone = job.getResult().then((result) => {
|
|
762
|
-
store.maybeUpdateLists(result, optimisticId);
|
|
763
|
-
});
|
|
764
|
-
return () => {
|
|
765
|
-
return optimisticApplicationDone.finally(() => {
|
|
766
|
-
store.removeLayer(optimisticId);
|
|
767
|
-
});
|
|
768
|
-
};
|
|
769
|
-
}
|
|
770
|
-
|
|
771
1038
|
// src/observable/internal/RefCounts.ts
|
|
772
1039
|
var RefCounts = class {
|
|
773
1040
|
refCounts = /* @__PURE__ */ new Map();
|
|
@@ -871,7 +1138,6 @@ var WhereClauseCanonicalizer = class {
|
|
|
871
1138
|
};
|
|
872
1139
|
|
|
873
1140
|
// src/observable/internal/Store.ts
|
|
874
|
-
var ACTION_DELAY = process.env.NODE_ENV === "production" ? 0 : 1e3;
|
|
875
1141
|
function createInitEntry(cacheKey) {
|
|
876
1142
|
return {
|
|
877
1143
|
cacheKey,
|
|
@@ -880,19 +1146,36 @@ function createInitEntry(cacheKey) {
|
|
|
880
1146
|
lastUpdated: 0
|
|
881
1147
|
};
|
|
882
1148
|
}
|
|
1149
|
+
var OrderByCanonicalizer = class {
|
|
1150
|
+
// crappy version
|
|
1151
|
+
#map = /* @__PURE__ */ new Map();
|
|
1152
|
+
canonicalize = (orderBy) => {
|
|
1153
|
+
if (this.#map.has(JSON.stringify(orderBy))) {
|
|
1154
|
+
return this.#map.get(JSON.stringify(orderBy));
|
|
1155
|
+
} else {
|
|
1156
|
+
this.#map.set(JSON.stringify(orderBy), orderBy);
|
|
1157
|
+
return orderBy;
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
};
|
|
883
1161
|
var Store = class {
|
|
884
1162
|
whereCanonicalizer = new WhereClauseCanonicalizer();
|
|
1163
|
+
orderByCanonicalizer = new OrderByCanonicalizer();
|
|
885
1164
|
#truthLayer = new Layer(undefined, undefined);
|
|
886
1165
|
#topLayer;
|
|
887
|
-
|
|
1166
|
+
/** @internal */
|
|
1167
|
+
#queries = new WeakMapWithEntries();
|
|
888
1168
|
#cacheKeyToSubject = /* @__PURE__ */ new WeakMap();
|
|
889
1169
|
#cacheKeys;
|
|
890
1170
|
#refCounts = new RefCounts(6e4, (k) => this.#cleanupCacheKey(k));
|
|
891
1171
|
#finalizationRegistry;
|
|
892
1172
|
constructor(client) {
|
|
893
1173
|
this.client = client;
|
|
1174
|
+
this.logger = client[chunkX7WGNFZ4_cjs.additionalContext].logger?.child({}, {
|
|
1175
|
+
msgPrefix: "Store"
|
|
1176
|
+
});
|
|
894
1177
|
this.#topLayer = this.#truthLayer;
|
|
895
|
-
this.#cacheKeys = new CacheKeys(this.whereCanonicalizer, (k) => {
|
|
1178
|
+
this.#cacheKeys = new CacheKeys(this.whereCanonicalizer, this.orderByCanonicalizer, (k) => {
|
|
896
1179
|
this.#refCounts.register(k);
|
|
897
1180
|
});
|
|
898
1181
|
setInterval(() => {
|
|
@@ -977,7 +1260,13 @@ var Store = class {
|
|
|
977
1260
|
const query = this.getObjectQuery(apiName, pk);
|
|
978
1261
|
this.#refCounts.retain(query.cacheKey);
|
|
979
1262
|
if (options.mode !== "offline") {
|
|
980
|
-
|
|
1263
|
+
query.revalidate(options.mode === "force").catch((e) => {
|
|
1264
|
+
if (this.logger) {
|
|
1265
|
+
this.logger.error("Unhandled error in observeObject", e);
|
|
1266
|
+
} else {
|
|
1267
|
+
throw e;
|
|
1268
|
+
}
|
|
1269
|
+
});
|
|
981
1270
|
}
|
|
982
1271
|
const sub = query.subscribe({
|
|
983
1272
|
next: subFn
|
|
@@ -989,11 +1278,8 @@ var Store = class {
|
|
|
989
1278
|
}
|
|
990
1279
|
};
|
|
991
1280
|
}
|
|
992
|
-
observeList(
|
|
993
|
-
|
|
994
|
-
apiName = apiName.apiName;
|
|
995
|
-
}
|
|
996
|
-
const query = this.getListQuery(apiName, where, options);
|
|
1281
|
+
observeList(options, subFn) {
|
|
1282
|
+
const query = this.getListQuery(options.objectType, options.where ?? {}, options.orderBy ?? {}, options);
|
|
997
1283
|
this.#refCounts.retain(query.cacheKey);
|
|
998
1284
|
if (options.mode !== "offline") {
|
|
999
1285
|
void query.revalidate(options.mode === "force");
|
|
@@ -1001,6 +1287,99 @@ var Store = class {
|
|
|
1001
1287
|
const sub = query.subscribe({
|
|
1002
1288
|
next: subFn
|
|
1003
1289
|
});
|
|
1290
|
+
if (options.streamUpdates) {
|
|
1291
|
+
const miniDef = {
|
|
1292
|
+
type: "object",
|
|
1293
|
+
apiName: typeof options.objectType === "string" ? options.objectType : options.objectType.apiName
|
|
1294
|
+
};
|
|
1295
|
+
let objectSet = this.client(miniDef);
|
|
1296
|
+
if (options.where) {
|
|
1297
|
+
objectSet = objectSet.where(options.where ?? {});
|
|
1298
|
+
}
|
|
1299
|
+
const store = this;
|
|
1300
|
+
const websocketSubscription = objectSet.subscribe({
|
|
1301
|
+
onChange({
|
|
1302
|
+
object,
|
|
1303
|
+
state
|
|
1304
|
+
}) {
|
|
1305
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1306
|
+
store.logger?.debug({
|
|
1307
|
+
methodName: "onError"
|
|
1308
|
+
}, "updates", state, object);
|
|
1309
|
+
}
|
|
1310
|
+
const cacheKey = store.getCacheKey("object", object.$objectType, object.$primaryKey);
|
|
1311
|
+
const type = store.#peekQuery(cacheKey) == null ? "addedObjects" : "modifiedObjects";
|
|
1312
|
+
const changes = createChangedObjects();
|
|
1313
|
+
changes[type].set(object.$objectType, object);
|
|
1314
|
+
if (state === "ADDED_OR_UPDATED") {
|
|
1315
|
+
store.updateObject(object.$objectType, object);
|
|
1316
|
+
store.maybeRevalidateLists(changes).catch((err) => {
|
|
1317
|
+
console.error("Unhandled error in maybeRevalidateLists", err);
|
|
1318
|
+
});
|
|
1319
|
+
} else if (state === "REMOVED") {
|
|
1320
|
+
const changes2 = createChangedObjects();
|
|
1321
|
+
store.batch({
|
|
1322
|
+
changes: changes2
|
|
1323
|
+
}, (batch) => {
|
|
1324
|
+
const existing = batch.read(query.cacheKey);
|
|
1325
|
+
const cacheKeyToRemove = store.getCacheKey("object", object.$objectType, object.$primaryKey);
|
|
1326
|
+
if (existing?.status === "loaded") {
|
|
1327
|
+
const newObjects = existing.value?.data.filter((o) => o !== cacheKeyToRemove);
|
|
1328
|
+
if (newObjects?.length !== existing.value?.data.length) {
|
|
1329
|
+
batch.changes.modifiedLists.add(query.cacheKey);
|
|
1330
|
+
batch.write(query.cacheKey, {
|
|
1331
|
+
data: newObjects ?? []
|
|
1332
|
+
}, "loaded");
|
|
1333
|
+
}
|
|
1334
|
+
} else {
|
|
1335
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1336
|
+
store.logger?.info("Removing an object from an object list that is in the middle of being loaded.", existing);
|
|
1337
|
+
}
|
|
1338
|
+
query.revalidate(
|
|
1339
|
+
/* force */
|
|
1340
|
+
true
|
|
1341
|
+
).catch((e) => {
|
|
1342
|
+
if (store.logger) {
|
|
1343
|
+
store.logger?.error("Uncaught error while revalidating list", e);
|
|
1344
|
+
} else {
|
|
1345
|
+
console.error("Uncaught error while revalidating list", e);
|
|
1346
|
+
}
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
},
|
|
1352
|
+
onError(errors) {
|
|
1353
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1354
|
+
store.logger?.info({
|
|
1355
|
+
methodName: "onError"
|
|
1356
|
+
}, "subscription errors", errors);
|
|
1357
|
+
}
|
|
1358
|
+
},
|
|
1359
|
+
onOutOfDate() {
|
|
1360
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1361
|
+
store.logger?.info({
|
|
1362
|
+
methodName: "onOutOfDate"
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
},
|
|
1366
|
+
onSuccessfulSubscription() {
|
|
1367
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1368
|
+
store.logger?.info({
|
|
1369
|
+
methodName: "onSuccessfulSubscription"
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
});
|
|
1374
|
+
sub.add(() => {
|
|
1375
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1376
|
+
store.logger?.info({
|
|
1377
|
+
methodName: "observeList"
|
|
1378
|
+
}, "Unsubscribing from websocket");
|
|
1379
|
+
}
|
|
1380
|
+
websocketSubscription.unsubscribe();
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1004
1383
|
return {
|
|
1005
1384
|
unsubscribe: () => {
|
|
1006
1385
|
sub.unsubscribe();
|
|
@@ -1019,14 +1398,15 @@ var Store = class {
|
|
|
1019
1398
|
}
|
|
1020
1399
|
return query;
|
|
1021
1400
|
}
|
|
1022
|
-
getListQuery(apiName, where,
|
|
1401
|
+
getListQuery(apiName, where, orderBy, opts) {
|
|
1023
1402
|
if (typeof apiName !== "string") {
|
|
1024
1403
|
apiName = apiName.apiName;
|
|
1025
1404
|
}
|
|
1026
1405
|
const canonWhere = this.whereCanonicalizer.canonicalize(where);
|
|
1027
|
-
const
|
|
1406
|
+
const canonOrderBy = this.orderByCanonicalizer.canonicalize(orderBy);
|
|
1407
|
+
const listCacheKey = this.getCacheKey("list", apiName, canonWhere, canonOrderBy);
|
|
1028
1408
|
return this.#getQuery(listCacheKey, () => {
|
|
1029
|
-
return new ListQuery(this, this.getSubject(listCacheKey), apiName, canonWhere, listCacheKey, opts);
|
|
1409
|
+
return new ListQuery(this, this.getSubject(listCacheKey), apiName, canonWhere, canonOrderBy, listCacheKey, opts);
|
|
1030
1410
|
});
|
|
1031
1411
|
}
|
|
1032
1412
|
getObjectQuery(apiName, pk) {
|
|
@@ -1047,14 +1427,13 @@ var Store = class {
|
|
|
1047
1427
|
return objEntry?.value;
|
|
1048
1428
|
}
|
|
1049
1429
|
batch = ({
|
|
1050
|
-
optimisticId
|
|
1430
|
+
optimisticId,
|
|
1431
|
+
changes = createChangedObjects()
|
|
1051
1432
|
}, batchFn) => {
|
|
1052
1433
|
!(optimisticId === undefined || !!optimisticId) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "optimistic must be undefined or not falsy") : invariant2__default.default(false) : undefined;
|
|
1053
1434
|
let needsLayer = optimisticId !== undefined;
|
|
1054
1435
|
const batchContext = {
|
|
1055
|
-
|
|
1056
|
-
modifiedObjects: /* @__PURE__ */ new Set(),
|
|
1057
|
-
modifiedLists: /* @__PURE__ */ new Set(),
|
|
1436
|
+
changes,
|
|
1058
1437
|
createLayerIfNeeded: () => {
|
|
1059
1438
|
if (needsLayer) {
|
|
1060
1439
|
this.#topLayer = this.#topLayer.addLayer(optimisticId);
|
|
@@ -1066,16 +1445,12 @@ var Store = class {
|
|
|
1066
1445
|
const oldTopValue = this.#topLayer.get(cacheKey);
|
|
1067
1446
|
if (optimisticId) batchContext.createLayerIfNeeded();
|
|
1068
1447
|
const writeLayer = optimisticId ? this.#topLayer : this.#truthLayer;
|
|
1069
|
-
const newValue =
|
|
1070
|
-
cacheKey,
|
|
1071
|
-
value,
|
|
1072
|
-
lastUpdated: Date.now(),
|
|
1073
|
-
status
|
|
1074
|
-
};
|
|
1448
|
+
const newValue = new Entry(cacheKey, value, Date.now(), status);
|
|
1075
1449
|
writeLayer.set(cacheKey, newValue);
|
|
1076
1450
|
const newTopValue = this.#topLayer.get(cacheKey);
|
|
1077
1451
|
if (oldTopValue !== newTopValue) {
|
|
1078
1452
|
this.#cacheKeyToSubject.get(cacheKey)?.next({
|
|
1453
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
|
1079
1454
|
...newValue,
|
|
1080
1455
|
isOptimistic: newTopValue?.value !== this.#truthLayer.get(cacheKey)?.value
|
|
1081
1456
|
});
|
|
@@ -1087,6 +1462,7 @@ var Store = class {
|
|
|
1087
1462
|
}
|
|
1088
1463
|
};
|
|
1089
1464
|
const retVal = batchFn(batchContext);
|
|
1465
|
+
void this.maybeUpdateLists(changes, optimisticId);
|
|
1090
1466
|
return {
|
|
1091
1467
|
batchResult: batchContext,
|
|
1092
1468
|
retVal
|
|
@@ -1099,35 +1475,90 @@ var Store = class {
|
|
|
1099
1475
|
const query = this.getObjectQuery(apiName, pk);
|
|
1100
1476
|
return query.revalidate(true);
|
|
1101
1477
|
}
|
|
1102
|
-
maybeRevalidateLists(changes) {
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1478
|
+
async maybeRevalidateLists(changes) {
|
|
1479
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1480
|
+
this.logger?.trace({
|
|
1481
|
+
methodName: "maybeRevalidateList"
|
|
1482
|
+
}, DEBUG_ONLY__changesToString(changes));
|
|
1483
|
+
}
|
|
1484
|
+
try {
|
|
1485
|
+
const promises = [];
|
|
1486
|
+
for (const [cacheKey, v] of this.#truthLayer.entries()) {
|
|
1487
|
+
if (isListCacheKey(cacheKey)) {
|
|
1488
|
+
const promise = this.#peekQuery(cacheKey)?.maybeUpdateAndRevalidate(changes, void 0);
|
|
1489
|
+
if (promise) promises.push(promise);
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
await Promise.all(promises);
|
|
1493
|
+
} finally {
|
|
1494
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1495
|
+
this.logger?.trace({
|
|
1496
|
+
methodName: "maybeRevalidateList"
|
|
1497
|
+
}, "in finally", DEBUG_ONLY__changesToString(changes));
|
|
1106
1498
|
}
|
|
1107
1499
|
}
|
|
1108
1500
|
}
|
|
1109
1501
|
maybeUpdateLists(changes, optimisticId) {
|
|
1110
|
-
|
|
1502
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1503
|
+
this.logger?.trace({
|
|
1504
|
+
methodName: "maybeUpdateLists"
|
|
1505
|
+
}, DEBUG_ONLY__changesToString(changes), {
|
|
1506
|
+
optimisticId
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
if (changes.addedObjects.size === 0 && changes.modifiedObjects.size === 0) {
|
|
1510
|
+
return Promise.resolve([]);
|
|
1511
|
+
}
|
|
1512
|
+
const promises = [];
|
|
1513
|
+
for (const cacheKey of this.#queries.keys()) {
|
|
1111
1514
|
if (isListCacheKey(cacheKey)) {
|
|
1112
|
-
|
|
1515
|
+
if (!changes.modifiedLists.has(cacheKey)) {
|
|
1516
|
+
const promise = this.#peekQuery(cacheKey)?.maybeUpdateAndRevalidate(changes, optimisticId);
|
|
1517
|
+
if (promise) promises.push(promise);
|
|
1518
|
+
}
|
|
1113
1519
|
}
|
|
1114
1520
|
}
|
|
1521
|
+
return Promise.all(promises);
|
|
1115
1522
|
}
|
|
1116
|
-
|
|
1523
|
+
/**
|
|
1524
|
+
* @param apiName
|
|
1525
|
+
* @param changes The changes we know about / to update
|
|
1526
|
+
* @returns
|
|
1527
|
+
*/
|
|
1528
|
+
invalidateObjectType(apiName, changes) {
|
|
1117
1529
|
if (typeof apiName !== "string") {
|
|
1118
1530
|
apiName = apiName.apiName;
|
|
1119
1531
|
}
|
|
1532
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1533
|
+
this.logger?.info({
|
|
1534
|
+
methodName: "invalidateObjectType"
|
|
1535
|
+
}, changes ? DEBUG_ONLY__changesToString(changes) : undefined);
|
|
1536
|
+
}
|
|
1537
|
+
const promises = [];
|
|
1120
1538
|
for (const [cacheKey, v] of this.#truthLayer.entries()) {
|
|
1121
1539
|
if (isListCacheKey(cacheKey, apiName)) {
|
|
1122
|
-
|
|
1540
|
+
if (!changes || !changes.modifiedLists.has(cacheKey)) {
|
|
1541
|
+
const promise = this.#peekQuery(cacheKey)?.revalidate(true);
|
|
1542
|
+
if (promise) {
|
|
1543
|
+
promises.push(promise);
|
|
1544
|
+
changes?.modifiedLists.add(cacheKey);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1123
1547
|
}
|
|
1124
1548
|
}
|
|
1549
|
+
return Promise.all(promises);
|
|
1125
1550
|
}
|
|
1126
|
-
invalidateList(
|
|
1127
|
-
|
|
1128
|
-
|
|
1551
|
+
invalidateList({
|
|
1552
|
+
objectType,
|
|
1553
|
+
where,
|
|
1554
|
+
orderBy
|
|
1555
|
+
}) {
|
|
1556
|
+
if (typeof objectType !== "string") {
|
|
1557
|
+
objectType = objectType.apiName;
|
|
1129
1558
|
}
|
|
1130
|
-
|
|
1559
|
+
where = this.whereCanonicalizer.canonicalize(where ?? {});
|
|
1560
|
+
orderBy = this.orderByCanonicalizer.canonicalize(orderBy ?? {});
|
|
1561
|
+
const cacheKey = this.getCacheKey("list", objectType, where, orderBy);
|
|
1131
1562
|
void this.#peekQuery(cacheKey)?.revalidate(true);
|
|
1132
1563
|
}
|
|
1133
1564
|
updateObject(apiName, value, {
|
|
@@ -1143,19 +1574,45 @@ var Store = class {
|
|
|
1143
1574
|
return query.writeToStore(value, "loaded", batch);
|
|
1144
1575
|
}).retVal.value;
|
|
1145
1576
|
}
|
|
1146
|
-
|
|
1577
|
+
updateObjects(values, batch) {
|
|
1578
|
+
return values.map((v) => {
|
|
1579
|
+
return this.getObjectQuery(v.$apiName, v.$primaryKey).writeToStore(v, "loaded", batch).cacheKey;
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Updates the internal state of a list and will create a new internal query if needed.
|
|
1584
|
+
*
|
|
1585
|
+
* Helper method only for tests right now. May be removed later.
|
|
1586
|
+
*
|
|
1587
|
+
* @param apiName
|
|
1588
|
+
* @param where
|
|
1589
|
+
* @param orderBy
|
|
1590
|
+
* @param objects
|
|
1591
|
+
* @param param4
|
|
1592
|
+
* @param opts
|
|
1593
|
+
*/
|
|
1594
|
+
updateList({
|
|
1595
|
+
objectType: apiName,
|
|
1596
|
+
where,
|
|
1597
|
+
orderBy
|
|
1598
|
+
}, objects, {
|
|
1147
1599
|
optimisticId
|
|
1148
1600
|
} = {}, opts = {
|
|
1149
1601
|
dedupeInterval: 0
|
|
1150
1602
|
}) {
|
|
1151
|
-
if (
|
|
1152
|
-
|
|
1603
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1604
|
+
this.logger?.info({
|
|
1605
|
+
methodName: "updateList"
|
|
1606
|
+
}, "", {
|
|
1607
|
+
optimisticId
|
|
1608
|
+
});
|
|
1153
1609
|
}
|
|
1154
|
-
const query = this.getListQuery(apiName, where, opts);
|
|
1610
|
+
const query = this.getListQuery(apiName, where ?? {}, orderBy ?? {}, opts);
|
|
1155
1611
|
this.batch({
|
|
1156
1612
|
optimisticId
|
|
1157
|
-
}, (
|
|
1158
|
-
|
|
1613
|
+
}, (batch) => {
|
|
1614
|
+
const objectCacheKeys = this.updateObjects(objects, batch);
|
|
1615
|
+
query.updateList(objectCacheKeys, false, "loaded", batch);
|
|
1159
1616
|
});
|
|
1160
1617
|
}
|
|
1161
1618
|
retain(cacheKey) {
|
|
@@ -1165,74 +1622,6 @@ var Store = class {
|
|
|
1165
1622
|
this.#refCounts.release(cacheKey);
|
|
1166
1623
|
}
|
|
1167
1624
|
};
|
|
1168
|
-
var ActionApplication = class {
|
|
1169
|
-
constructor(store) {
|
|
1170
|
-
this.store = store;
|
|
1171
|
-
}
|
|
1172
|
-
applyAction = (action, args, {
|
|
1173
|
-
optimisticUpdate
|
|
1174
|
-
} = {}) => {
|
|
1175
|
-
const removeOptimisticResult = runOptimisticJob(this.store, optimisticUpdate);
|
|
1176
|
-
return (async () => {
|
|
1177
|
-
try {
|
|
1178
|
-
const actionResults = await this.store.client(action).applyAction(args, {
|
|
1179
|
-
$returnEdits: true
|
|
1180
|
-
});
|
|
1181
|
-
if (ACTION_DELAY > 0) {
|
|
1182
|
-
console.log("action done, pausing");
|
|
1183
|
-
await delay(ACTION_DELAY);
|
|
1184
|
-
console.log("action done, pausing done");
|
|
1185
|
-
}
|
|
1186
|
-
await this.#invalidateActionEditResponse(actionResults);
|
|
1187
|
-
return actionResults;
|
|
1188
|
-
} finally {
|
|
1189
|
-
await removeOptimisticResult();
|
|
1190
|
-
}
|
|
1191
|
-
})();
|
|
1192
|
-
};
|
|
1193
|
-
#invalidateActionEditResponse = (value) => {
|
|
1194
|
-
const typesToInvalidate = /* @__PURE__ */ new Set();
|
|
1195
|
-
let promisesToWait = [];
|
|
1196
|
-
if (value.type === "edits") {
|
|
1197
|
-
for (const obj of value.modifiedObjects) {
|
|
1198
|
-
promisesToWait.push(this.store.invalidateObject(obj.objectType, obj.primaryKey));
|
|
1199
|
-
}
|
|
1200
|
-
for (const obj of value.addedObjects) {
|
|
1201
|
-
promisesToWait.push(this.store.invalidateObject(obj.objectType, obj.primaryKey));
|
|
1202
|
-
typesToInvalidate.add(obj.objectType);
|
|
1203
|
-
}
|
|
1204
|
-
promisesToWait = [Promise.allSettled(promisesToWait).then(() => {
|
|
1205
|
-
const changes2 = this.#changesFromActionEditResponse(value);
|
|
1206
|
-
this.store.maybeRevalidateLists(changes2);
|
|
1207
|
-
})];
|
|
1208
|
-
} else {
|
|
1209
|
-
for (const apiName of value.editedObjectTypes) {
|
|
1210
|
-
typesToInvalidate.add(apiName.toString());
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
return Promise.allSettled(promisesToWait).then(() => {
|
|
1214
|
-
for (const objectType of typesToInvalidate) {
|
|
1215
|
-
this.store.invalidateObjectType(objectType);
|
|
1216
|
-
}
|
|
1217
|
-
return value;
|
|
1218
|
-
});
|
|
1219
|
-
};
|
|
1220
|
-
#changesFromActionEditResponse = (value) => {
|
|
1221
|
-
const changes = createChangedObjects();
|
|
1222
|
-
for (const changeType of ["addedObjects", "modifiedObjects"]) {
|
|
1223
|
-
for (const {
|
|
1224
|
-
objectType,
|
|
1225
|
-
primaryKey
|
|
1226
|
-
} of value[changeType] ?? []) {
|
|
1227
|
-
const obj = this.store.getObject(objectType, primaryKey);
|
|
1228
|
-
if (obj) {
|
|
1229
|
-
changes[changeType].set(objectType, obj);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
return changes;
|
|
1234
|
-
};
|
|
1235
|
-
};
|
|
1236
1625
|
|
|
1237
1626
|
// src/observable/ObservableClient.ts
|
|
1238
1627
|
function createObservableClient(client) {
|