@osdk/client 2.2.0-beta.3 → 2.2.0-beta.5
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 +25 -0
- package/build/browser/Logger.js.map +1 -1
- package/build/browser/observable/ObservableClient.js.map +1 -1
- package/build/browser/observable/OptimisticBuilder.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 +418 -78
- package/build/browser/observable/internal/Store.test.js.map +1 -1
- package/build/browser/observable/internal/objectMatchesWhereClause.js +0 -2
- package/build/browser/observable/internal/objectMatchesWhereClause.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 +14 -5
- package/build/esm/Logger.js.map +1 -1
- package/build/esm/observable/ObservableClient.js.map +1 -1
- package/build/esm/observable/OptimisticBuilder.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 +418 -78
- package/build/esm/observable/internal/Store.test.js.map +1 -1
- package/build/esm/observable/internal/objectMatchesWhereClause.js +0 -2
- package/build/esm/observable/internal/objectMatchesWhereClause.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/OptimisticBuilder.d.ts +1 -1
- package/build/types/observable/OptimisticBuilder.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 +9 -8
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import deepEqual from "fast-deep-equal";
|
|
18
|
-
import { asyncScheduler, auditTime, combineLatest, connectable, map,
|
|
18
|
+
import { asyncScheduler, auditTime, combineLatest, connectable, map, observeOn, of, ReplaySubject, switchMap } from "rxjs";
|
|
19
19
|
import invariant from "tiny-invariant";
|
|
20
|
-
import {
|
|
20
|
+
import { additionalContext } from "../../Client.js";
|
|
21
|
+
import { DEBUG_ONLY__cacheKeysToString } from "./CacheKey.js";
|
|
22
|
+
import { DEBUG_ONLY__changesToString } from "./ChangedObjects.js";
|
|
21
23
|
import { objectSortaMatchesWhereClause } from "./objectMatchesWhereClause.js";
|
|
22
24
|
import { Query } from "./Query.js";
|
|
23
|
-
auditTime(0);
|
|
24
25
|
export class ListQuery extends Query {
|
|
25
26
|
// pageSize?: number; // this is the internal page size. we need to track this properly
|
|
26
27
|
#client;
|
|
@@ -32,15 +33,22 @@ export class ListQuery extends Query {
|
|
|
32
33
|
#nextPageToken;
|
|
33
34
|
#pendingPageFetch;
|
|
34
35
|
#toRelease = new Set();
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
#orderBy;
|
|
37
|
+
constructor(store, subject, objectType, whereClause, orderBy, cacheKey, opts) {
|
|
38
|
+
super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[additionalContext].logger?.child({}, {
|
|
39
|
+
msgPrefix: `ListQuery<${cacheKey.otherKeys.map(x => JSON.stringify(x)).join(", ")}>`
|
|
40
|
+
}) : undefined);
|
|
37
41
|
this.#client = store.client;
|
|
38
|
-
this.#type =
|
|
42
|
+
this.#type = objectType;
|
|
39
43
|
this.#whereClause = whereClause;
|
|
44
|
+
this.#orderBy = orderBy;
|
|
40
45
|
observeOn(asyncScheduler);
|
|
41
46
|
}
|
|
47
|
+
get canonicalWhere() {
|
|
48
|
+
return this.#whereClause;
|
|
49
|
+
}
|
|
42
50
|
_createConnectable(subject) {
|
|
43
|
-
return connectable(subject.pipe(
|
|
51
|
+
return connectable(subject.pipe(switchMap(listEntry => {
|
|
44
52
|
return combineLatest({
|
|
45
53
|
resolvedList: listEntry?.value?.data == null ? of([]) : combineLatest(listEntry.value.data.map(cacheKey => this.store.getSubject(cacheKey).pipe(map(objectEntry => objectEntry?.value)))),
|
|
46
54
|
isOptimistic: of(listEntry.isOptimistic),
|
|
@@ -114,7 +122,12 @@ export class ListQuery extends Query {
|
|
|
114
122
|
nextPageToken
|
|
115
123
|
} = await objectSet.fetchPage({
|
|
116
124
|
$nextPageToken: this.#nextPageToken,
|
|
117
|
-
$pageSize: this.options.pageSize
|
|
125
|
+
$pageSize: this.options.pageSize,
|
|
126
|
+
// For now this keeps the shared test code from falling apart
|
|
127
|
+
// but shouldn't be needed ideally
|
|
128
|
+
...(Object.keys(this.#orderBy).length > 0 ? {
|
|
129
|
+
$orderBy: this.#orderBy
|
|
130
|
+
} : {})
|
|
118
131
|
});
|
|
119
132
|
if (signal?.aborted) {
|
|
120
133
|
return;
|
|
@@ -123,85 +136,147 @@ export class ListQuery extends Query {
|
|
|
123
136
|
const {
|
|
124
137
|
retVal
|
|
125
138
|
} = this.store.batch({}, batch => {
|
|
126
|
-
return this.updateList(data, append, nextPageToken ? status : "loaded", batch);
|
|
139
|
+
return this.updateList(this.store.updateObjects(data, batch), append, nextPageToken ? status : "loaded", batch);
|
|
127
140
|
});
|
|
128
141
|
return retVal;
|
|
129
142
|
}
|
|
130
143
|
|
|
131
144
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
145
|
+
* Note: This method is not async because I want it to return right after it
|
|
146
|
+
* finishes the synchronous updates. The promise that is returned
|
|
147
|
+
* will resolve after the revalidation is complete.
|
|
148
|
+
* @param changes
|
|
135
149
|
* @param optimisticId
|
|
136
|
-
* @returns
|
|
150
|
+
* @returns If revalidation is needed, a promise that resolves after the
|
|
151
|
+
* revalidation is complete. Otherwise, undefined.
|
|
137
152
|
*/
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
153
|
+
|
|
154
|
+
maybeUpdateAndRevalidate = (changes, optimisticId) => {
|
|
155
|
+
if (process.env.NODE_ENV !== "production") {
|
|
156
|
+
this.logger?.info({
|
|
157
|
+
methodName: "#maybeMaybe"
|
|
158
|
+
}, DEBUG_ONLY__changesToString(changes));
|
|
159
|
+
}
|
|
160
|
+
if (changes.modifiedLists.has(this.cacheKey)) return;
|
|
161
|
+
try {
|
|
162
|
+
const relevantObjects = {
|
|
163
|
+
added: {
|
|
164
|
+
all: changes.addedObjects.get(this.cacheKey.otherKeys[0]) ?? [],
|
|
165
|
+
strictMatches: new Set(),
|
|
166
|
+
sortaMatches: new Set()
|
|
167
|
+
},
|
|
168
|
+
modified: {
|
|
169
|
+
all: changes.modifiedObjects.get(this.cacheKey.otherKeys[0]) ?? [],
|
|
170
|
+
strictMatches: new Set(),
|
|
171
|
+
sortaMatches: new Set()
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
if (relevantObjects.added.all.length === 0 && relevantObjects.modified.all.length === 0) {
|
|
175
|
+
return;
|
|
144
176
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
177
|
+
|
|
178
|
+
// categorize
|
|
179
|
+
for (const group of Object.values(relevantObjects)) {
|
|
180
|
+
for (const obj of group.all ?? []) {
|
|
181
|
+
// if its a strict match we can just insert it into place
|
|
182
|
+
const strictMatch = objectSortaMatchesWhereClause(obj, this.#whereClause, true);
|
|
183
|
+
if (strictMatch) {
|
|
184
|
+
group.strictMatches.add(obj);
|
|
185
|
+
} else {
|
|
186
|
+
// sorta match means it used a filter we cannot use on the frontend
|
|
187
|
+
const sortaMatch = objectSortaMatchesWhereClause(obj, this.#whereClause, false);
|
|
188
|
+
if (sortaMatch) {
|
|
189
|
+
group.sortaMatches.add(obj);
|
|
190
|
+
}
|
|
155
191
|
}
|
|
156
192
|
}
|
|
157
193
|
}
|
|
158
|
-
}
|
|
159
|
-
needsRevalidation ||= objectsToInsert.length > 0;
|
|
160
|
-
if (objectsToInsert.length > 0) {
|
|
161
|
-
// for now we are not doing sorting which makes life easy :)
|
|
162
|
-
// FIXME
|
|
163
194
|
|
|
195
|
+
// If we got purely strict matches we can just update the list and move
|
|
196
|
+
// on with our lives. But if we got sorta matches, then we need to revalidate
|
|
197
|
+
// the list so we preemptively set it to loading to avoid thrashing the store.
|
|
198
|
+
const status = optimisticId || relevantObjects.added.sortaMatches.size > 0 || relevantObjects.modified.sortaMatches.size > 0 ? "loading" : "loaded";
|
|
199
|
+
|
|
200
|
+
// while we only push updates for the strict matches, we still need to
|
|
201
|
+
// trigger the list updating if some of our objects changed
|
|
202
|
+
|
|
203
|
+
// mark ourselves as updated so we don't infinite recurse.
|
|
204
|
+
changes.modifiedLists.add(this.cacheKey);
|
|
205
|
+
const newList = [];
|
|
206
|
+
let needsRevalidation = false;
|
|
164
207
|
this.store.batch({
|
|
165
|
-
optimisticId
|
|
208
|
+
optimisticId,
|
|
209
|
+
changes
|
|
166
210
|
}, batch => {
|
|
167
|
-
|
|
211
|
+
const curValue = batch.read(this.cacheKey);
|
|
212
|
+
const existingList = new Set(curValue?.value?.data);
|
|
213
|
+
const toAdd = new Set(
|
|
214
|
+
// easy case. objects are new to the cache and they match this filter
|
|
215
|
+
relevantObjects.added.strictMatches);
|
|
216
|
+
const toRemove = new Set();
|
|
217
|
+
|
|
218
|
+
// deal with the modified objects
|
|
219
|
+
for (const obj of relevantObjects.modified.all) {
|
|
220
|
+
if (relevantObjects.modified.strictMatches.has(obj)) {
|
|
221
|
+
const existingObjectCacheKey = this.store.getCacheKey("object", obj.$apiName, obj.$primaryKey);
|
|
222
|
+
|
|
223
|
+
// full match and already there, do nothing
|
|
224
|
+
if (!existingList.has(existingObjectCacheKey)) {
|
|
225
|
+
// object is new to the list
|
|
226
|
+
toAdd.add(obj);
|
|
227
|
+
}
|
|
228
|
+
continue;
|
|
229
|
+
} else if (batch.optimisticWrite) {
|
|
230
|
+
// we aren't removing objects in optimistic mode
|
|
231
|
+
// we also don't want to trigger revalidation in optimistic mode
|
|
232
|
+
// as it should be triggered when the optimistic job is done
|
|
233
|
+
continue;
|
|
234
|
+
} else {
|
|
235
|
+
// object is no longer a strict match
|
|
236
|
+
const existingObjectCacheKey = this.store.getCacheKey("object", obj.$apiName, obj.$primaryKey);
|
|
237
|
+
toRemove.add(existingObjectCacheKey);
|
|
238
|
+
if (relevantObjects.modified.sortaMatches.has(obj)) {
|
|
239
|
+
// since it might still be in the list we need to revalidate
|
|
240
|
+
needsRevalidation = true;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
for (const key of existingList) {
|
|
245
|
+
if (toRemove.has(key)) continue;
|
|
246
|
+
newList.push(key);
|
|
247
|
+
}
|
|
248
|
+
for (const obj of toAdd) {
|
|
249
|
+
newList.push(this.store.getCacheKey("object", obj.$apiName, obj.$primaryKey));
|
|
250
|
+
}
|
|
251
|
+
this.updateList(newList, /* append */false, status, batch);
|
|
168
252
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
maybeRevalidate(changedObjects) {
|
|
173
|
-
let needsRevalidation = false;
|
|
174
|
-
for (const [type, objects] of changedObjects.addedObjects.associations()) {
|
|
175
|
-
if (this.cacheKey.otherKeys[0] !== type) {
|
|
176
|
-
continue;
|
|
253
|
+
if (needsRevalidation) {
|
|
254
|
+
changes.modifiedLists.add(this.cacheKey);
|
|
255
|
+
return this.revalidate(true).then(() => void 0); // strip return value
|
|
177
256
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
257
|
+
return undefined;
|
|
258
|
+
} finally {
|
|
259
|
+
if (process.env.NODE_ENV !== "production") {
|
|
260
|
+
this.logger?.trace({
|
|
261
|
+
methodName: "#maybeMaybe"
|
|
262
|
+
}, "in finally");
|
|
184
263
|
}
|
|
185
264
|
}
|
|
186
|
-
|
|
187
|
-
|
|
265
|
+
};
|
|
266
|
+
updateList(objectCacheKeys, append, status, batch) {
|
|
267
|
+
if (process.env.NODE_ENV !== "production") {
|
|
268
|
+
this.logger?.trace({
|
|
269
|
+
methodName: "updateList"
|
|
270
|
+
}, `{status: ${status}}`, JSON.stringify(objectCacheKeys, null, 2));
|
|
188
271
|
}
|
|
189
|
-
return Promise.resolve();
|
|
190
|
-
}
|
|
191
|
-
updateList(values, append, status, batch) {
|
|
192
|
-
// update the cache for any object that has changed
|
|
193
|
-
// and save the mapped values to return
|
|
194
|
-
let objectCacheKeys = values.map(v => {
|
|
195
|
-
if (v instanceof Entry) return v.cacheKey;
|
|
196
|
-
this.store.getObjectQuery(this.#type, v.$primaryKey).writeToStore(v, "loaded", batch);
|
|
197
|
-
return this.store.getCacheKey("object", v.$apiName, v.$primaryKey);
|
|
198
|
-
});
|
|
199
272
|
const existingList = batch.read(this.cacheKey);
|
|
200
273
|
|
|
201
274
|
// whether its append or update we need to retain all the new objects
|
|
202
275
|
if (!batch.optimisticWrite) {
|
|
203
276
|
if (!append) {
|
|
204
277
|
// we need to release all the old objects
|
|
278
|
+
// N.B. the store keeps the cache keys around for a bit so we don't
|
|
279
|
+
// need to worry about them being GC'd before we re-retain them
|
|
205
280
|
for (const objectCacheKey of existingList?.value?.data ?? []) {
|
|
206
281
|
this.store.release(objectCacheKey);
|
|
207
282
|
this.#toRelease.delete(objectCacheKey);
|
|
@@ -212,23 +287,70 @@ export class ListQuery extends Query {
|
|
|
212
287
|
this.store.retain(objectCacheKey);
|
|
213
288
|
}
|
|
214
289
|
}
|
|
215
|
-
|
|
216
|
-
// EA TODO: I think we need to do more here.
|
|
217
|
-
|
|
218
290
|
if (append) {
|
|
219
291
|
objectCacheKeys = [...(existingList?.value?.data ?? []), ...objectCacheKeys];
|
|
220
292
|
}
|
|
293
|
+
if (Object.keys(this.#orderBy).length > 0) {
|
|
294
|
+
if (process.env.NODE_ENV !== "production") {
|
|
295
|
+
this.logger?.info({
|
|
296
|
+
methodName: "updateList"
|
|
297
|
+
}, "Sorting entries");
|
|
298
|
+
this.logger?.trace({
|
|
299
|
+
methodName: "updateList"
|
|
300
|
+
}, DEBUG_ONLY__cacheKeysToString(objectCacheKeys));
|
|
301
|
+
}
|
|
302
|
+
const sortFns = Object.entries(this.#orderBy).map(([key, order]) => {
|
|
303
|
+
return (a, b) => {
|
|
304
|
+
const aValue = a?.[key];
|
|
305
|
+
const bValue = b?.[key];
|
|
306
|
+
if (aValue == null && bValue == null) {
|
|
307
|
+
return 0;
|
|
308
|
+
}
|
|
309
|
+
if (aValue == null) {
|
|
310
|
+
return 1;
|
|
311
|
+
}
|
|
312
|
+
if (bValue == null) {
|
|
313
|
+
return -1;
|
|
314
|
+
}
|
|
315
|
+
const m = order === "asc" ? -1 : 1;
|
|
316
|
+
return aValue < bValue ? m : aValue > bValue ? -m : 0;
|
|
317
|
+
};
|
|
318
|
+
});
|
|
319
|
+
objectCacheKeys = objectCacheKeys.sort((a, b) => {
|
|
320
|
+
for (const sortFn of sortFns) {
|
|
321
|
+
const ret = sortFn(batch.read(a)?.value, batch.read(b)?.value);
|
|
322
|
+
if (ret !== 0) {
|
|
323
|
+
return ret;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return 0;
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
const visited = new Set();
|
|
330
|
+
objectCacheKeys = objectCacheKeys.filter(key => {
|
|
331
|
+
batch.read(key);
|
|
332
|
+
if (visited.has(key)) {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
visited.add(key);
|
|
336
|
+
return true;
|
|
337
|
+
});
|
|
221
338
|
return this.writeToStore({
|
|
222
339
|
data: objectCacheKeys
|
|
223
340
|
}, status, batch);
|
|
224
341
|
}
|
|
225
342
|
writeToStore(data, status, batch) {
|
|
343
|
+
if (process.env.NODE_ENV !== "production") {
|
|
344
|
+
this.logger?.trace({
|
|
345
|
+
methodName: "writeToStore"
|
|
346
|
+
}, `{status: ${status}},`, DEBUG_ONLY__cacheKeysToString(data.data));
|
|
347
|
+
}
|
|
226
348
|
const entry = batch.read(this.cacheKey);
|
|
227
349
|
if (entry && deepEqual(data, entry.value)) {
|
|
228
350
|
return batch.write(this.cacheKey, entry.value, status);
|
|
229
351
|
}
|
|
230
352
|
const ret = batch.write(this.cacheKey, data, status);
|
|
231
|
-
batch.modifiedLists.add(this.cacheKey);
|
|
353
|
+
batch.changes.modifiedLists.add(this.cacheKey);
|
|
232
354
|
return ret;
|
|
233
355
|
}
|
|
234
356
|
_dispose() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListQuery.js","names":["deepEqual","asyncScheduler","auditTime","combineLatest","connectable","map","mergeMap","observeOn","of","ReplaySubject","invariant","Entry","objectSortaMatchesWhereClause","Query","ListQuery","client","type","whereClause","minNumResults","nextPageToken","pendingPageFetch","toRelease","Set","constructor","store","subject","cacheKey","opts","_createConnectable","pipe","listEntry","resolvedList","value","data","getSubject","objectEntry","isOptimistic","fetchMore","hasMore","status","lastUpdated","resetOnDisconnect","connector","_preFetch","undefined","_fetch","objectSet","apiName","where","entry","fetchPageAndUpdate","abortController","signal","process","env","NODE_ENV","count","length","batch","setStatus","Promise","resolve","pendingFetch","res","finally","#fetchPageAndUpdate","append","fetchPage","$nextPageToken","$pageSize","options","pageSize","aborted","retVal","updateList","maybeUpdate","changedObjects","optimisticId","needsRevalidation","objectsToInsert","objects","addedObjects","associations","otherKeys","obj","strictMatch","push","sortaMatch","maybeRevalidate","revalidate","values","objectCacheKeys","v","getObjectQuery","$primaryKey","writeToStore","getCacheKey","$apiName","existingList","read","optimisticWrite","objectCacheKey","release","delete","add","retain","write","ret","modifiedLists","_dispose","console","log","isListCacheKey"],"sources":["ListQuery.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ObjectSet,\n ObjectTypeDefinition,\n Osdk,\n WhereClause,\n} from \"@osdk/api\";\nimport deepEqual from \"fast-deep-equal\";\nimport {\n asyncScheduler,\n auditTime,\n combineLatest,\n type Connectable,\n connectable,\n map,\n mergeMap,\n type Observable,\n observeOn,\n of,\n ReplaySubject,\n} from \"rxjs\";\nimport invariant from \"tiny-invariant\";\nimport type { Client } from \"../../Client.js\";\nimport type { ListPayload } from \"../ListPayload.js\";\nimport type { QueryOptions, Status } from \"../ObservableClient.js\";\nimport type { CacheKey } from \"./CacheKey.js\";\nimport type { Canonical } from \"./Canonical.js\";\nimport type { ChangedObjects } from \"./ChangedObjects.js\";\nimport { Entry } from \"./Layer.js\";\nimport { objectSortaMatchesWhereClause } from \"./objectMatchesWhereClause.js\";\nimport type { ObjectCacheKey, ObjectEntry } from \"./ObjectQuery.js\";\nimport type { OptimisticId } from \"./OptimisticId.js\";\nimport { Query } from \"./Query.js\";\nimport type { BatchContext, Store, SubjectPayload } from \"./Store.js\";\n\nexport interface ListEntry extends Entry<ListCacheKey> {}\n\nauditTime(0);\ninterface ListStorageData {\n data: ObjectCacheKey[];\n}\n\nexport interface ListCacheKey extends\n CacheKey<\n \"list\",\n ListStorageData,\n ListQuery,\n [\n apiName: string,\n whereClause: WhereClause<ObjectTypeDefinition>,\n ]\n > //\n{}\n\nexport interface ListQueryOptions extends QueryOptions {\n pageSize?: number;\n}\n\nexport class ListQuery extends Query<\n ListCacheKey,\n ListPayload,\n ListQueryOptions\n> {\n // pageSize?: number; // this is the internal page size. we need to track this properly\n #client: Client;\n #type: string;\n #whereClause: Canonical<WhereClause<ObjectTypeDefinition>>;\n\n // this represents the minimum number of results we need to load if we revalidate\n #minNumResults = 0;\n\n #nextPageToken?: string;\n #pendingPageFetch?: Promise<unknown>;\n #toRelease: Set<ObjectCacheKey> = new Set();\n\n constructor(\n store: Store,\n subject: Observable<SubjectPayload<ListCacheKey>>,\n type: string,\n whereClause: Canonical<WhereClause<ObjectTypeDefinition>>,\n cacheKey: ListCacheKey,\n opts: ListQueryOptions,\n ) {\n super(\n store,\n subject,\n opts,\n cacheKey,\n );\n\n this.#client = store.client;\n this.#type = type;\n this.#whereClause = whereClause;\n observeOn(asyncScheduler);\n }\n\n protected _createConnectable(\n subject: Observable<SubjectPayload<ListCacheKey>>,\n ): Connectable<ListPayload> {\n return connectable(\n subject.pipe(\n mergeMap(listEntry => {\n return combineLatest({\n resolvedList: listEntry?.value?.data == null\n ? of([])\n : combineLatest(\n listEntry.value.data.map(cacheKey =>\n this.store.getSubject(cacheKey).pipe(\n map(objectEntry => objectEntry?.value!),\n )\n ),\n ),\n isOptimistic: of(listEntry.isOptimistic),\n fetchMore: of(this.fetchMore),\n hasMore: of(this.#nextPageToken != null),\n status: of(listEntry.status),\n lastUpdated: of(listEntry.lastUpdated),\n });\n }),\n // like throttle but returns the tail\n auditTime(0),\n ),\n {\n resetOnDisconnect: false,\n connector: () => new ReplaySubject(1),\n },\n );\n }\n\n _preFetch(): void {\n this.#nextPageToken = undefined;\n }\n\n async _fetch(): Promise<void> {\n const objectSet =\n (this.#client({ type: \"object\", apiName: this.#type }) as ObjectSet<\n ObjectTypeDefinition\n >)\n .where(this.#whereClause);\n\n while (true) {\n const entry = await this.#fetchPageAndUpdate(\n objectSet,\n \"loading\",\n this.abortController?.signal,\n );\n if (!entry) {\n // we were aborted\n return;\n }\n\n invariant(entry.value?.data);\n const count = entry.value.data.length;\n\n if (count > this.#minNumResults || this.#nextPageToken == null) {\n break;\n }\n }\n this.store.batch({}, (batch) => {\n this.setStatus(\"loaded\", batch);\n });\n\n return Promise.resolve();\n }\n\n fetchMore = (): Promise<unknown> => {\n if (this.#pendingPageFetch) {\n return this.#pendingPageFetch;\n }\n\n if (this.pendingFetch) {\n this.#pendingPageFetch = new Promise(async (res) => {\n await this.pendingFetch;\n res(this.fetchMore());\n });\n return this.#pendingPageFetch;\n }\n\n if (this.#nextPageToken == null) {\n return Promise.resolve();\n }\n\n this.store.batch({}, (batch) => {\n this.setStatus(\"loading\", batch);\n });\n\n const objectSet =\n (this.#client({ type: \"object\", apiName: this.#type }) as ObjectSet<\n ObjectTypeDefinition\n >).where(this.#whereClause);\n\n this.pendingFetch = this.#fetchPageAndUpdate(\n objectSet,\n \"loaded\",\n this.abortController?.signal,\n ).finally(() => {\n this.#pendingPageFetch = undefined;\n });\n return this.pendingFetch;\n };\n\n async #fetchPageAndUpdate(\n objectSet: ObjectSet,\n status: Status,\n signal: AbortSignal | undefined,\n ): Promise<Entry<ListCacheKey> | undefined> {\n const append = this.#nextPageToken != null;\n const { data, nextPageToken } = await objectSet.fetchPage({\n $nextPageToken: this.#nextPageToken,\n $pageSize: this.options.pageSize,\n });\n\n if (signal?.aborted) {\n return;\n }\n\n this.#nextPageToken = nextPageToken;\n\n const { retVal } = this.store.batch({}, (batch) => {\n return this.updateList(\n data,\n append,\n nextPageToken ? status : \"loaded\",\n batch,\n );\n });\n\n return retVal;\n }\n\n /**\n * Caller is responsible for removing the layer\n *\n * @param changedObjects\n * @param optimisticId\n * @returns\n */\n maybeUpdate(\n changedObjects: ChangedObjects,\n optimisticId: OptimisticId,\n ): boolean {\n let needsRevalidation = false;\n const objectsToInsert: Osdk.Instance<ObjectTypeDefinition>[] = [];\n for (const [type, objects] of changedObjects.addedObjects.associations()) {\n if (this.cacheKey.otherKeys[0] !== type) {\n continue;\n }\n\n for (const obj of objects) {\n // strict match means it didn't use a filter we cannot use on the frontend\n const strictMatch = objectSortaMatchesWhereClause(\n obj,\n this.#whereClause,\n true,\n );\n\n if (strictMatch) {\n objectsToInsert.push(obj);\n } else {\n // sorta match means it used a filter we cannot use on the frontend\n const sortaMatch = objectSortaMatchesWhereClause(\n obj,\n this.#whereClause,\n false,\n );\n if (sortaMatch) {\n needsRevalidation = true;\n }\n }\n }\n }\n\n needsRevalidation ||= objectsToInsert.length > 0;\n\n if (objectsToInsert.length > 0) {\n // for now we are not doing sorting which makes life easy :)\n // FIXME\n\n this.store.batch({ optimisticId }, (batch) => {\n this.updateList(\n objectsToInsert,\n true,\n \"loading\",\n batch,\n );\n });\n }\n\n return needsRevalidation;\n }\n\n maybeRevalidate(\n changedObjects: ChangedObjects,\n ): Promise<unknown> {\n let needsRevalidation = false;\n for (const [type, objects] of changedObjects.addedObjects.associations()) {\n if (this.cacheKey.otherKeys[0] !== type) {\n continue;\n }\n\n for (const obj of objects) {\n // sorta match means it used a filter we cannot use on the frontend\n const sortaMatch = objectSortaMatchesWhereClause(\n obj,\n this.#whereClause,\n false,\n );\n if (sortaMatch) {\n needsRevalidation = true;\n }\n }\n }\n\n if (needsRevalidation) {\n return this.revalidate(true);\n }\n\n return Promise.resolve();\n }\n\n updateList(\n values: Array<Osdk.Instance<ObjectTypeDefinition> | ObjectEntry>,\n append: boolean,\n status: Status,\n batch: BatchContext,\n ): Entry<ListCacheKey> {\n // update the cache for any object that has changed\n // and save the mapped values to return\n let objectCacheKeys = values.map(v => {\n if (v instanceof Entry) return v.cacheKey;\n\n this.store.getObjectQuery(this.#type, v.$primaryKey as string | number)\n .writeToStore(v, \"loaded\", batch);\n return this.store.getCacheKey<ObjectCacheKey>(\n \"object\",\n v.$apiName,\n v.$primaryKey,\n );\n });\n\n const existingList = batch.read(this.cacheKey);\n\n // whether its append or update we need to retain all the new objects\n if (!batch.optimisticWrite) {\n if (!append) {\n // we need to release all the old objects\n for (const objectCacheKey of existingList?.value?.data ?? []) {\n this.store.release(objectCacheKey);\n this.#toRelease.delete(objectCacheKey);\n }\n }\n\n for (const objectCacheKey of objectCacheKeys) {\n this.#toRelease.add(objectCacheKey);\n this.store.retain(objectCacheKey);\n }\n }\n\n // EA TODO: I think we need to do more here.\n\n if (append) {\n objectCacheKeys = [\n ...existingList?.value?.data ?? [],\n ...objectCacheKeys,\n ];\n }\n\n return this.writeToStore({ data: objectCacheKeys }, status, batch);\n }\n\n writeToStore(\n data: ListStorageData,\n status: Status,\n batch: BatchContext,\n ): Entry<ListCacheKey> {\n const entry = batch.read(this.cacheKey);\n\n if (entry && deepEqual(data, entry.value)) {\n return batch.write(this.cacheKey, entry.value, status);\n }\n\n const ret = batch.write(this.cacheKey, data, status);\n batch.modifiedLists.add(this.cacheKey);\n\n return ret;\n }\n\n _dispose(): void {\n // eslint-disable-next-line no-console\n console.log(\"DISPOSE LIST QUERY\");\n this.store.batch({}, (batch) => {\n const entry = batch.read(this.cacheKey);\n if (entry) {\n for (const objectCacheKey of entry.value?.data ?? []) {\n this.store.release(objectCacheKey);\n }\n }\n });\n }\n}\n\nexport function isListCacheKey(\n cacheKey: CacheKey,\n apiName?: string,\n): cacheKey is ListCacheKey {\n return cacheKey.type === \"list\"\n && (apiName == null || cacheKey.otherKeys[0] === apiName);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"ListQuery.js","names":["deepEqual","asyncScheduler","auditTime","combineLatest","connectable","map","observeOn","of","ReplaySubject","switchMap","invariant","additionalContext","DEBUG_ONLY__cacheKeysToString","DEBUG_ONLY__changesToString","objectSortaMatchesWhereClause","Query","ListQuery","client","type","whereClause","minNumResults","nextPageToken","pendingPageFetch","toRelease","Set","orderBy","constructor","store","subject","objectType","cacheKey","opts","process","env","NODE_ENV","logger","child","msgPrefix","otherKeys","x","JSON","stringify","join","undefined","canonicalWhere","_createConnectable","pipe","listEntry","resolvedList","value","data","getSubject","objectEntry","isOptimistic","fetchMore","hasMore","status","lastUpdated","resetOnDisconnect","connector","_preFetch","_fetch","objectSet","apiName","where","entry","fetchPageAndUpdate","abortController","signal","count","length","batch","setStatus","Promise","resolve","pendingFetch","res","finally","#fetchPageAndUpdate","append","fetchPage","$nextPageToken","$pageSize","options","pageSize","Object","keys","$orderBy","aborted","retVal","updateList","updateObjects","maybeUpdateAndRevalidate","changes","optimisticId","info","methodName","modifiedLists","has","relevantObjects","added","all","addedObjects","get","strictMatches","sortaMatches","modified","modifiedObjects","group","values","obj","strictMatch","add","sortaMatch","size","newList","needsRevalidation","curValue","read","existingList","toAdd","toRemove","existingObjectCacheKey","getCacheKey","$apiName","$primaryKey","optimisticWrite","key","push","revalidate","then","trace","objectCacheKeys","objectCacheKey","release","delete","retain","sortFns","entries","order","a","b","aValue","bValue","m","sort","sortFn","ret","visited","filter","writeToStore","write","_dispose","console","log","isListCacheKey"],"sources":["ListQuery.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ObjectSet,\n ObjectTypeDefinition,\n Osdk,\n WhereClause,\n} from \"@osdk/api\";\nimport deepEqual from \"fast-deep-equal\";\nimport {\n asyncScheduler,\n auditTime,\n combineLatest,\n type Connectable,\n connectable,\n map,\n type Observable,\n observeOn,\n of,\n ReplaySubject,\n switchMap,\n} from \"rxjs\";\nimport invariant from \"tiny-invariant\";\nimport { additionalContext, type Client } from \"../../Client.js\";\nimport type { ListPayload } from \"../ListPayload.js\";\nimport type { CommonObserveOptions, Status } from \"../ObservableClient.js\";\nimport {\n type CacheKey,\n DEBUG_ONLY__cacheKeysToString as DEBUG_ONLY__cacheKeysToString,\n} from \"./CacheKey.js\";\nimport type { Canonical } from \"./Canonical.js\";\nimport { type Changes, DEBUG_ONLY__changesToString } from \"./ChangedObjects.js\";\nimport type { Entry } from \"./Layer.js\";\nimport { objectSortaMatchesWhereClause } from \"./objectMatchesWhereClause.js\";\nimport type { ObjectCacheKey } from \"./ObjectQuery.js\";\nimport type { OptimisticId } from \"./OptimisticId.js\";\nimport { Query } from \"./Query.js\";\nimport type { BatchContext, Store, SubjectPayload } from \"./Store.js\";\n\ninterface ListStorageData {\n data: ObjectCacheKey[];\n}\n\nexport interface ListCacheKey extends\n CacheKey<\n \"list\",\n ListStorageData,\n ListQuery,\n [\n apiName: string,\n whereClause: Canonical<WhereClause<ObjectTypeDefinition>>,\n orderByClause: Canonical<Record<string, \"asc\" | \"desc\" | undefined>>,\n ]\n > //\n{}\n\nexport interface ListQueryOptions extends CommonObserveOptions {\n pageSize?: number;\n}\n\nexport class ListQuery extends Query<\n ListCacheKey,\n ListPayload,\n ListQueryOptions\n> {\n // pageSize?: number; // this is the internal page size. we need to track this properly\n #client: Client;\n #type: string;\n #whereClause: Canonical<WhereClause<ObjectTypeDefinition>>;\n\n // this represents the minimum number of results we need to load if we revalidate\n #minNumResults = 0;\n\n #nextPageToken?: string;\n #pendingPageFetch?: Promise<unknown>;\n #toRelease: Set<ObjectCacheKey> = new Set();\n #orderBy: Canonical<Record<string, \"asc\" | \"desc\" | undefined>>;\n\n constructor(\n store: Store,\n subject: Observable<SubjectPayload<ListCacheKey>>,\n objectType: string,\n whereClause: Canonical<WhereClause<ObjectTypeDefinition>>,\n orderBy: Canonical<Record<string, \"asc\" | \"desc\" | undefined>>,\n cacheKey: ListCacheKey,\n opts: ListQueryOptions,\n ) {\n super(\n store,\n subject,\n opts,\n cacheKey,\n process.env.NODE_ENV !== \"production\"\n ? (\n store.client[additionalContext].logger?.child({}, {\n msgPrefix: `ListQuery<${\n cacheKey.otherKeys.map(x => JSON.stringify(x)).join(\", \")\n }>`,\n })\n )\n : undefined,\n );\n\n this.#client = store.client;\n this.#type = objectType;\n this.#whereClause = whereClause;\n this.#orderBy = orderBy;\n\n observeOn(asyncScheduler);\n }\n\n get canonicalWhere(): Canonical<WhereClause<ObjectTypeDefinition>> {\n return this.#whereClause;\n }\n\n protected _createConnectable(\n subject: Observable<SubjectPayload<ListCacheKey>>,\n ): Connectable<ListPayload> {\n return connectable(\n subject.pipe(\n switchMap(listEntry => {\n return combineLatest({\n resolvedList: listEntry?.value?.data == null\n ? of([])\n : combineLatest(\n listEntry.value.data.map(cacheKey =>\n this.store.getSubject(cacheKey).pipe(\n map(objectEntry => objectEntry?.value!),\n )\n ),\n ),\n isOptimistic: of(listEntry.isOptimistic),\n fetchMore: of(this.fetchMore),\n hasMore: of(this.#nextPageToken != null),\n status: of(listEntry.status),\n lastUpdated: of(listEntry.lastUpdated),\n });\n }),\n // like throttle but returns the tail\n auditTime(0),\n ),\n {\n resetOnDisconnect: false,\n connector: () => new ReplaySubject(1),\n },\n );\n }\n\n _preFetch(): void {\n this.#nextPageToken = undefined;\n }\n\n async _fetch(): Promise<void> {\n const objectSet =\n (this.#client({ type: \"object\", apiName: this.#type }) as ObjectSet<\n ObjectTypeDefinition\n >)\n .where(this.#whereClause);\n\n while (true) {\n const entry = await this.#fetchPageAndUpdate(\n objectSet,\n \"loading\",\n this.abortController?.signal,\n );\n if (!entry) {\n // we were aborted\n return;\n }\n\n invariant(entry.value?.data);\n const count = entry.value.data.length;\n\n if (count > this.#minNumResults || this.#nextPageToken == null) {\n break;\n }\n }\n this.store.batch({}, (batch) => {\n this.setStatus(\"loaded\", batch);\n });\n\n return Promise.resolve();\n }\n\n fetchMore = (): Promise<unknown> => {\n if (this.#pendingPageFetch) {\n return this.#pendingPageFetch;\n }\n\n if (this.pendingFetch) {\n this.#pendingPageFetch = new Promise(async (res) => {\n await this.pendingFetch;\n res(this.fetchMore());\n });\n return this.#pendingPageFetch;\n }\n\n if (this.#nextPageToken == null) {\n return Promise.resolve();\n }\n\n this.store.batch({}, (batch) => {\n this.setStatus(\"loading\", batch);\n });\n\n const objectSet =\n (this.#client({ type: \"object\", apiName: this.#type }) as ObjectSet<\n ObjectTypeDefinition\n >).where(this.#whereClause);\n\n this.pendingFetch = this.#fetchPageAndUpdate(\n objectSet,\n \"loaded\",\n this.abortController?.signal,\n ).finally(() => {\n this.#pendingPageFetch = undefined;\n });\n return this.pendingFetch;\n };\n\n async #fetchPageAndUpdate(\n objectSet: ObjectSet,\n status: Status,\n signal: AbortSignal | undefined,\n ): Promise<Entry<ListCacheKey> | undefined> {\n const append = this.#nextPageToken != null;\n const { data, nextPageToken } = await objectSet.fetchPage({\n $nextPageToken: this.#nextPageToken,\n $pageSize: this.options.pageSize,\n // For now this keeps the shared test code from falling apart\n // but shouldn't be needed ideally\n ...(Object.keys(this.#orderBy).length > 0\n ? {\n $orderBy: this.#orderBy,\n }\n : {}),\n });\n\n if (signal?.aborted) {\n return;\n }\n\n this.#nextPageToken = nextPageToken;\n\n const { retVal } = this.store.batch({}, (batch) => {\n return this.updateList(\n this.store.updateObjects(data, batch),\n append,\n nextPageToken ? status : \"loaded\",\n batch,\n );\n });\n\n return retVal;\n }\n\n /**\n * Note: This method is not async because I want it to return right after it\n * finishes the synchronous updates. The promise that is returned\n * will resolve after the revalidation is complete.\n * @param changes\n * @param optimisticId\n * @returns If revalidation is needed, a promise that resolves after the\n * revalidation is complete. Otherwise, undefined.\n */\n\n maybeUpdateAndRevalidate = (\n changes: Changes,\n optimisticId: OptimisticId | undefined,\n ): Promise<void> | undefined => {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.info(\n { methodName: \"#maybeMaybe\" },\n DEBUG_ONLY__changesToString(changes),\n );\n }\n if (changes.modifiedLists.has(this.cacheKey)) return;\n\n try {\n const relevantObjects: Record<\"added\" | \"modified\", {\n all: Osdk.Instance<ObjectTypeDefinition>[];\n strictMatches: Set<Osdk.Instance<ObjectTypeDefinition>>;\n sortaMatches: Set<Osdk.Instance<ObjectTypeDefinition>>;\n }> = {\n added: {\n all: changes.addedObjects.get(this.cacheKey.otherKeys[0]) ?? [],\n strictMatches: new Set(),\n sortaMatches: new Set(),\n },\n modified: {\n all: changes.modifiedObjects.get(this.cacheKey.otherKeys[0]) ?? [],\n strictMatches: new Set(),\n sortaMatches: new Set(),\n },\n };\n\n if (\n relevantObjects.added.all.length === 0\n && relevantObjects.modified.all.length === 0\n ) {\n return;\n }\n\n // categorize\n for (const group of Object.values(relevantObjects)) {\n for (const obj of group.all ?? []) {\n // if its a strict match we can just insert it into place\n const strictMatch = objectSortaMatchesWhereClause(\n obj,\n this.#whereClause,\n true,\n );\n\n if (strictMatch) {\n group.strictMatches.add(obj);\n } else {\n // sorta match means it used a filter we cannot use on the frontend\n const sortaMatch = objectSortaMatchesWhereClause(\n obj,\n this.#whereClause,\n false,\n );\n if (sortaMatch) {\n group.sortaMatches.add(obj);\n }\n }\n }\n }\n\n // If we got purely strict matches we can just update the list and move\n // on with our lives. But if we got sorta matches, then we need to revalidate\n // the list so we preemptively set it to loading to avoid thrashing the store.\n const status = optimisticId\n || relevantObjects.added.sortaMatches.size > 0\n || relevantObjects.modified.sortaMatches.size > 0\n ? \"loading\"\n : \"loaded\";\n\n // while we only push updates for the strict matches, we still need to\n // trigger the list updating if some of our objects changed\n\n // mark ourselves as updated so we don't infinite recurse.\n changes.modifiedLists.add(this.cacheKey);\n\n const newList: Array<ObjectCacheKey> = [];\n\n let needsRevalidation = false;\n this.store.batch({ optimisticId, changes }, (batch) => {\n const curValue = batch.read(this.cacheKey);\n\n const existingList = new Set(curValue?.value?.data);\n\n const toAdd = new Set<Osdk.Instance<ObjectTypeDefinition>>(\n // easy case. objects are new to the cache and they match this filter\n relevantObjects.added.strictMatches,\n );\n\n const toRemove = new Set<ObjectCacheKey>();\n\n // deal with the modified objects\n for (const obj of relevantObjects.modified.all) {\n if (relevantObjects.modified.strictMatches.has(obj)) {\n const existingObjectCacheKey = this.store.getCacheKey<\n ObjectCacheKey\n >(\n \"object\",\n obj.$apiName,\n obj.$primaryKey,\n );\n\n // full match and already there, do nothing\n if (!existingList.has(existingObjectCacheKey)) {\n // object is new to the list\n toAdd.add(obj);\n }\n continue;\n } else if (batch.optimisticWrite) {\n // we aren't removing objects in optimistic mode\n // we also don't want to trigger revalidation in optimistic mode\n // as it should be triggered when the optimistic job is done\n continue;\n } else {\n // object is no longer a strict match\n const existingObjectCacheKey = this.store.getCacheKey<\n ObjectCacheKey\n >(\n \"object\",\n obj.$apiName,\n obj.$primaryKey,\n );\n\n toRemove.add(existingObjectCacheKey);\n\n if (relevantObjects.modified.sortaMatches.has(obj)) {\n // since it might still be in the list we need to revalidate\n needsRevalidation = true;\n }\n }\n }\n\n for (const key of existingList) {\n if (toRemove.has(key)) continue;\n newList.push(key);\n }\n for (const obj of toAdd) {\n newList.push(\n this.store.getCacheKey<ObjectCacheKey>(\n \"object\",\n obj.$apiName,\n obj.$primaryKey,\n ),\n );\n }\n\n this.updateList(\n newList,\n /* append */ false,\n status,\n batch,\n );\n });\n\n if (needsRevalidation) {\n changes.modifiedLists.add(this.cacheKey);\n return this.revalidate(true).then(() => void 0); // strip return value\n }\n return undefined;\n } finally {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.trace(\n { methodName: \"#maybeMaybe\" },\n \"in finally\",\n );\n }\n }\n };\n\n updateList(\n objectCacheKeys: Array<ObjectCacheKey>,\n append: boolean,\n status: Status,\n batch: BatchContext,\n ): Entry<ListCacheKey> {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.trace(\n { methodName: \"updateList\" },\n `{status: ${status}}`,\n JSON.stringify(objectCacheKeys, null, 2),\n );\n }\n\n const existingList = batch.read(this.cacheKey);\n\n // whether its append or update we need to retain all the new objects\n if (!batch.optimisticWrite) {\n if (!append) {\n // we need to release all the old objects\n // N.B. the store keeps the cache keys around for a bit so we don't\n // need to worry about them being GC'd before we re-retain them\n for (const objectCacheKey of existingList?.value?.data ?? []) {\n this.store.release(objectCacheKey);\n this.#toRelease.delete(objectCacheKey);\n }\n }\n\n for (const objectCacheKey of objectCacheKeys) {\n this.#toRelease.add(objectCacheKey);\n this.store.retain(objectCacheKey);\n }\n }\n\n if (append) {\n objectCacheKeys = [\n ...existingList?.value?.data ?? [],\n ...objectCacheKeys,\n ];\n }\n\n if (Object.keys(this.#orderBy).length > 0) {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.info({ methodName: \"updateList\" }, \"Sorting entries\");\n this.logger?.trace(\n { methodName: \"updateList\" },\n DEBUG_ONLY__cacheKeysToString(objectCacheKeys),\n );\n }\n const sortFns = Object.entries(this.#orderBy).map(([key, order]) => {\n return (\n a: Osdk.Instance<ObjectTypeDefinition, never, any, {}> | undefined,\n b: Osdk.Instance<ObjectTypeDefinition, never, any, {}> | undefined,\n ): number => {\n const aValue = a?.[key];\n const bValue = b?.[key];\n\n if (aValue == null && bValue == null) {\n return 0;\n }\n if (aValue == null) {\n return 1;\n }\n if (bValue == null) {\n return -1;\n }\n const m = order === \"asc\" ? -1 : 1;\n return aValue < bValue ? m : aValue > bValue ? -m : 0;\n };\n });\n\n objectCacheKeys = objectCacheKeys.sort((a, b) => {\n for (const sortFn of sortFns) {\n const ret = sortFn(\n batch.read(a)?.value,\n batch.read(b)?.value,\n );\n if (ret !== 0) {\n return ret;\n }\n }\n return 0;\n });\n }\n\n const visited = new Set<ObjectCacheKey>();\n objectCacheKeys = objectCacheKeys.filter((key) => {\n batch.read(key);\n if (visited.has(key)) {\n return false;\n }\n visited.add(key);\n return true;\n });\n\n return this.writeToStore({ data: objectCacheKeys }, status, batch);\n }\n\n writeToStore(\n data: ListStorageData,\n status: Status,\n batch: BatchContext,\n ): Entry<ListCacheKey> {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.trace(\n { methodName: \"writeToStore\" },\n `{status: ${status}},`,\n DEBUG_ONLY__cacheKeysToString(data.data),\n );\n }\n const entry = batch.read(this.cacheKey);\n\n if (entry && deepEqual(data, entry.value)) {\n return batch.write(this.cacheKey, entry.value, status);\n }\n\n const ret = batch.write(this.cacheKey, data, status);\n batch.changes.modifiedLists.add(this.cacheKey);\n return ret;\n }\n\n _dispose(): void {\n // eslint-disable-next-line no-console\n console.log(\"DISPOSE LIST QUERY\");\n this.store.batch({}, (batch) => {\n const entry = batch.read(this.cacheKey);\n if (entry) {\n for (const objectCacheKey of entry.value?.data ?? []) {\n this.store.release(objectCacheKey);\n }\n }\n });\n }\n}\n\nexport function isListCacheKey(\n cacheKey: CacheKey,\n apiName?: string,\n): cacheKey is ListCacheKey {\n return cacheKey.type === \"list\"\n && (apiName == null || cacheKey.otherKeys[0] === apiName);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -16,12 +16,15 @@
|
|
|
16
16
|
|
|
17
17
|
import deepEqual from "fast-deep-equal";
|
|
18
18
|
import { BehaviorSubject, connectable, map } from "rxjs";
|
|
19
|
+
import { additionalContext } from "../../Client.js";
|
|
19
20
|
import { Query } from "./Query.js";
|
|
20
21
|
export class ObjectQuery extends Query {
|
|
21
22
|
#apiName;
|
|
22
23
|
#pk;
|
|
23
24
|
constructor(store, subject, type, pk, cacheKey, opts) {
|
|
24
|
-
super(store, subject, opts, cacheKey
|
|
25
|
+
super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[additionalContext].logger?.child({}, {
|
|
26
|
+
msgPrefix: `ObjectQuery<${cacheKey.otherKeys.map(x => JSON.stringify(x)).join(", ")}>`
|
|
27
|
+
}) : undefined);
|
|
25
28
|
this.#apiName = type;
|
|
26
29
|
this.#pk = pk;
|
|
27
30
|
}
|
|
@@ -43,6 +46,11 @@ export class ObjectQuery extends Query {
|
|
|
43
46
|
});
|
|
44
47
|
}
|
|
45
48
|
async _fetch() {
|
|
49
|
+
if (process.env.NODE_ENV !== "production") {
|
|
50
|
+
this.logger?.info({
|
|
51
|
+
methodName: "_fetch"
|
|
52
|
+
});
|
|
53
|
+
}
|
|
46
54
|
const objectSet = this.store.client({
|
|
47
55
|
type: "object",
|
|
48
56
|
apiName: this.#apiName
|
|
@@ -53,6 +61,11 @@ export class ObjectQuery extends Query {
|
|
|
53
61
|
});
|
|
54
62
|
}
|
|
55
63
|
writeToStore(data, status, batch) {
|
|
64
|
+
if (process.env.NODE_ENV !== "production") {
|
|
65
|
+
this.logger?.trace({
|
|
66
|
+
methodName: "writeToStore"
|
|
67
|
+
}, `{status: ${status}},`, data);
|
|
68
|
+
}
|
|
56
69
|
const entry = batch.read(this.cacheKey);
|
|
57
70
|
if (entry && deepEqual(data, entry.value)) {
|
|
58
71
|
// must do a "full write" here so that the lastUpdated is updated
|
|
@@ -61,9 +74,9 @@ export class ObjectQuery extends Query {
|
|
|
61
74
|
}
|
|
62
75
|
const ret = batch.write(this.cacheKey, data, status);
|
|
63
76
|
if (entry) {
|
|
64
|
-
batch.modifiedObjects.
|
|
77
|
+
batch.changes.modifiedObjects.set(data.$apiName, data);
|
|
65
78
|
} else {
|
|
66
|
-
batch.addedObjects.
|
|
79
|
+
batch.changes.addedObjects.set(data.$apiName, data);
|
|
67
80
|
}
|
|
68
81
|
return ret;
|
|
69
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectQuery.js","names":["deepEqual","BehaviorSubject","connectable","map","Query","ObjectQuery","apiName","pk","constructor","store","subject","type","cacheKey","opts","
|
|
1
|
+
{"version":3,"file":"ObjectQuery.js","names":["deepEqual","BehaviorSubject","connectable","map","additionalContext","Query","ObjectQuery","apiName","pk","constructor","store","subject","type","cacheKey","opts","process","env","NODE_ENV","client","logger","child","msgPrefix","otherKeys","x","JSON","stringify","join","undefined","_createConnectable","pipe","status","object","value","lastUpdated","isOptimistic","connector","_fetch","info","methodName","objectSet","obj","fetchOne","batch","writeToStore","data","trace","entry","read","write","ret","changes","modifiedObjects","set","$apiName","addedObjects"],"sources":["ObjectQuery.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ObjectSet,\n ObjectTypeDefinition,\n Osdk,\n PrimaryKeyType,\n} from \"@osdk/api\";\nimport deepEqual from \"fast-deep-equal\";\nimport type { Connectable, Observable, Subject } from \"rxjs\";\nimport { BehaviorSubject, connectable, map } from \"rxjs\";\nimport { additionalContext } from \"../../Client.js\";\nimport type { ObjectPayload } from \"../ObjectPayload.js\";\nimport type { CommonObserveOptions, Status } from \"../ObservableClient.js\";\nimport type { CacheKey } from \"./CacheKey.js\";\nimport type { Entry } from \"./Layer.js\";\nimport { Query } from \"./Query.js\";\nimport type { BatchContext, Store, SubjectPayload } from \"./Store.js\";\n\nexport interface ObjectEntry extends Entry<ObjectCacheKey> {}\n\ntype ObjectStorageData = Osdk.Instance<ObjectTypeDefinition>;\n\nexport interface ObjectCacheKey extends\n CacheKey<\n \"object\",\n ObjectStorageData,\n ObjectQuery,\n [string, pk: PrimaryKeyType<ObjectTypeDefinition>]\n >\n{}\n\nexport class ObjectQuery extends Query<\n ObjectCacheKey,\n ObjectPayload,\n CommonObserveOptions\n> {\n #apiName: string;\n #pk: string | number | boolean;\n\n constructor(\n store: Store,\n subject: Subject<SubjectPayload<ObjectCacheKey>>,\n type: string,\n pk: PrimaryKeyType<ObjectTypeDefinition>,\n cacheKey: ObjectCacheKey,\n opts: CommonObserveOptions,\n ) {\n super(\n store,\n subject,\n opts,\n cacheKey,\n process.env.NODE_ENV !== \"production\"\n ? (\n store.client[additionalContext].logger?.child({}, {\n msgPrefix: `ObjectQuery<${\n cacheKey.otherKeys.map(x => JSON.stringify(x)).join(\", \")\n }>`,\n })\n )\n : undefined,\n );\n this.#apiName = type;\n this.#pk = pk;\n }\n\n protected _createConnectable(\n subject: Observable<SubjectPayload<ObjectCacheKey>>,\n ): Connectable<ObjectPayload> {\n return connectable(\n subject.pipe(\n map((x) => {\n return {\n status: x.status,\n object: x.value,\n lastUpdated: x.lastUpdated,\n isOptimistic: x.isOptimistic,\n };\n }),\n ),\n {\n connector: () =>\n new BehaviorSubject<ObjectPayload>({\n status: \"init\",\n object: undefined,\n lastUpdated: 0,\n isOptimistic: false,\n }),\n },\n );\n }\n\n async _fetch(): Promise<void> {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.info({ methodName: \"_fetch\" });\n }\n\n const objectSet = this.store.client({\n type: \"object\",\n apiName: this.#apiName,\n }) as ObjectSet<ObjectTypeDefinition>;\n const obj = await objectSet.fetchOne(this.#pk);\n this.store.batch({}, (batch) => {\n this.writeToStore(\n obj as Osdk.Instance<ObjectTypeDefinition>,\n \"loaded\",\n batch,\n );\n });\n }\n\n writeToStore(\n data: Osdk.Instance<ObjectTypeDefinition>,\n status: Status,\n batch: BatchContext,\n ): Entry<ObjectCacheKey> {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.trace(\n { methodName: \"writeToStore\" },\n `{status: ${status}},`,\n data,\n );\n }\n const entry = batch.read(this.cacheKey);\n\n if (entry && deepEqual(data, entry.value)) {\n // must do a \"full write\" here so that the lastUpdated is updated\n return batch.write(this.cacheKey, entry.value, status);\n // return entry.value.data as Osdk.Instance<ObjectTypeDefinition>;\n }\n const ret = batch.write(this.cacheKey, data, status);\n\n if (entry) {\n batch.changes.modifiedObjects.set(data.$apiName, data);\n } else {\n batch.changes.addedObjects.set(data.$apiName, data);\n }\n\n return ret;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -25,8 +25,8 @@ export class ObservableClientImpl {
|
|
|
25
25
|
observeObject(apiName, pk, options, subFn) {
|
|
26
26
|
return this.#store.observeObject(apiName, pk, options, subFn);
|
|
27
27
|
}
|
|
28
|
-
observeList(
|
|
29
|
-
return this.#store.observeList(
|
|
28
|
+
observeList(options, subFn) {
|
|
29
|
+
return this.#store.observeList(options, subFn);
|
|
30
30
|
}
|
|
31
31
|
applyAction(action, args, opts) {
|
|
32
32
|
return this.#store.applyAction(action, args, opts);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObservableClientImpl.js","names":["ObservableClientImpl","store","constructor","observeObject","apiName","pk","options","subFn","observeList","
|
|
1
|
+
{"version":3,"file":"ObservableClientImpl.js","names":["ObservableClientImpl","store","constructor","observeObject","apiName","pk","options","subFn","observeList","applyAction","action","args","opts","canonicalizeWhereClause","where","whereCanonicalizer","canonicalize"],"sources":["ObservableClientImpl.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ActionDefinition,\n ObjectTypeDefinition,\n PrimaryKeyType,\n WhereClause,\n} from \"@osdk/api\";\nimport type { ActionSignatureFromDef } from \"../../actions/applyAction.js\";\nimport type { ListPayload } from \"../ListPayload.js\";\nimport type { ObjectPayload } from \"../ObjectPayload.js\";\nimport type {\n ObservableClient,\n ObserveListOptions,\n ObserveObjectOptions,\n ObserveOptions,\n Unsubscribable,\n} from \"../ObservableClient.js\";\nimport type { SubFn } from \"../types.js\";\nimport type { Canonical } from \"./Canonical.js\";\nimport type { Store } from \"./Store.js\";\n\n/**\n * @internal\n */\nexport class ObservableClientImpl implements ObservableClient {\n #store: Store;\n\n constructor(store: Store) {\n this.#store = store;\n }\n\n public observeObject<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n pk: PrimaryKeyType<T>,\n options: ObserveObjectOptions<T>,\n subFn: SubFn<ObjectPayload>,\n ): Unsubscribable {\n return this.#store.observeObject(apiName, pk, options, subFn);\n }\n\n public observeList<T extends ObjectTypeDefinition>(\n options: ObserveOptions & ObserveListOptions<T>,\n subFn: SubFn<ListPayload>,\n ): Unsubscribable {\n return this.#store.observeList(options, subFn);\n }\n\n public applyAction<Q extends ActionDefinition<any>>(\n action: Q,\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n opts?: ObservableClient.ApplyActionOptions,\n ): Promise<unknown> {\n return this.#store.applyAction(action, args, opts);\n }\n\n public canonicalizeWhereClause<T extends ObjectTypeDefinition>(\n where: WhereClause<T>,\n ): Canonical<WhereClause<T>> {\n return this.#store.whereCanonicalizer.canonicalize(where);\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAsBA;AACA;AACA;AACA,OAAO,MAAMA,oBAAoB,CAA6B;EAC5D,CAACC,KAAK;EAENC,WAAWA,CAACD,KAAY,EAAE;IACxB,IAAI,CAAC,CAACA,KAAK,GAAGA,KAAK;EACrB;EAEOE,aAAaA,CAClBC,OAAyB,EACzBC,EAAqB,EACrBC,OAAgC,EAChCC,KAA2B,EACX;IAChB,OAAO,IAAI,CAAC,CAACN,KAAK,CAACE,aAAa,CAACC,OAAO,EAAEC,EAAE,EAAEC,OAAO,EAAEC,KAAK,CAAC;EAC/D;EAEOC,WAAWA,CAChBF,OAA+C,EAC/CC,KAAyB,EACT;IAChB,OAAO,IAAI,CAAC,CAACN,KAAK,CAACO,WAAW,CAACF,OAAO,EAAEC,KAAK,CAAC;EAChD;EAEOE,WAAWA,CAChBC,MAAS,EACTC,IAA6D,EAC7DC,IAA0C,EACxB;IAClB,OAAO,IAAI,CAAC,CAACX,KAAK,CAACQ,WAAW,CAACC,MAAM,EAAEC,IAAI,EAAEC,IAAI,CAAC;EACpD;EAEOC,uBAAuBA,CAC5BC,KAAqB,EACM;IAC3B,OAAO,IAAI,CAAC,CAACb,KAAK,CAACc,kBAAkB,CAACC,YAAY,CAACF,KAAK,CAAC;EAC3D;AACF","ignoreList":[]}
|