@osdk/client 2.5.0-beta.1 → 2.5.0-beta.2
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 +26 -0
- package/build/browser/Client.js +1 -1
- package/build/browser/Client.js.map +1 -1
- package/build/browser/intellisense.test.helpers/orderBySuggestionIsRight.js +8 -1
- package/build/browser/intellisense.test.helpers/orderBySuggestionIsRight.js.map +1 -1
- package/build/browser/intellisense.test.js +14 -4
- package/build/browser/intellisense.test.js.map +1 -1
- package/build/browser/object/Cache.js +1 -1
- package/build/browser/object/Cache.js.map +1 -1
- package/build/browser/object/SimpleCache.js +1 -1
- package/build/browser/object/SimpleCache.js.map +1 -1
- package/build/browser/object/convertWireToOsdkObjects.js +4 -0
- package/build/browser/object/convertWireToOsdkObjects.js.map +1 -1
- package/build/browser/object/fetchPage.js +8 -4
- package/build/browser/object/fetchPage.js.map +1 -1
- package/build/browser/object/geotimeseriesreference.test.js +0 -2
- package/build/browser/object/geotimeseriesreference.test.js.map +1 -1
- package/build/browser/objectSet/createObjectSet.js +3 -1
- package/build/browser/objectSet/createObjectSet.js.map +1 -1
- package/build/browser/observable/LinkPayload.js +2 -0
- package/build/browser/observable/LinkPayload.js.map +1 -0
- package/build/browser/observable/ObjectPayload.js.map +1 -1
- package/build/browser/observable/ObservableClient/ObserveLink.js +17 -0
- package/build/browser/observable/ObservableClient/ObserveLink.js.map +1 -0
- package/build/browser/observable/ObservableClient/common.js +2 -0
- package/build/browser/observable/ObservableClient/common.js.map +1 -0
- package/build/browser/observable/ObservableClient.js +20 -0
- package/build/browser/observable/ObservableClient.js.map +1 -1
- package/build/browser/observable/Unsubscribable.js +2 -0
- package/build/browser/observable/Unsubscribable.js.map +1 -0
- package/build/browser/observable/internal/AbstractHelper.js +50 -0
- package/build/browser/observable/internal/AbstractHelper.js.map +1 -0
- package/build/browser/observable/internal/BaseCollectionQuery.js +2 -0
- package/build/browser/observable/internal/BaseCollectionQuery.js.map +1 -0
- package/build/browser/observable/internal/BulkObjectLoader.js +3 -3
- package/build/browser/observable/internal/BulkObjectLoader.js.map +1 -1
- package/build/browser/observable/internal/CacheKeys.js +17 -2
- package/build/browser/observable/internal/CacheKeys.js.map +1 -1
- package/build/browser/observable/internal/Changes.js +6 -0
- package/build/browser/observable/internal/Changes.js.map +1 -1
- package/build/browser/observable/internal/KnownCacheKey.js +2 -0
- package/build/browser/observable/internal/KnownCacheKey.js.map +1 -0
- package/build/browser/observable/internal/Layer.js.map +1 -1
- package/build/browser/observable/internal/ListCacheKey.js +2 -0
- package/build/browser/observable/internal/ListCacheKey.js.map +1 -0
- package/build/browser/observable/internal/ListQuery.js +399 -161
- package/build/browser/observable/internal/ListQuery.js.map +1 -1
- package/build/browser/observable/internal/ObjectQuery.js +27 -2
- package/build/browser/observable/internal/ObjectQuery.js.map +1 -1
- package/build/browser/observable/internal/ObservableClientImpl.js +42 -2
- package/build/browser/observable/internal/ObservableClientImpl.js.map +1 -1
- package/build/browser/observable/internal/OptimisticJob.js +12 -3
- package/build/browser/observable/internal/OptimisticJob.js.map +1 -1
- package/build/browser/observable/internal/Query.js +17 -3
- package/build/browser/observable/internal/Query.js.map +1 -1
- package/build/browser/observable/internal/QuerySubscription.js +41 -0
- package/build/browser/observable/internal/QuerySubscription.js.map +1 -0
- package/build/browser/observable/internal/Store.invalidation.test.js +481 -0
- package/build/browser/observable/internal/Store.invalidation.test.js.map +1 -0
- package/build/browser/observable/internal/Store.js +38 -91
- package/build/browser/observable/internal/Store.js.map +1 -1
- package/build/browser/observable/internal/Store.test.js +318 -63
- package/build/browser/observable/internal/Store.test.js.map +1 -1
- package/build/browser/observable/internal/UnsubscribableWrapper.js +30 -0
- package/build/browser/observable/internal/UnsubscribableWrapper.js.map +1 -0
- package/build/browser/observable/internal/createCollectionConnectable.js +50 -0
- package/build/browser/observable/internal/createCollectionConnectable.js.map +1 -0
- package/build/browser/observable/internal/createCollectionConnectable.test.js +599 -0
- package/build/browser/observable/internal/createCollectionConnectable.test.js.map +1 -0
- package/build/browser/observable/internal/getObjectTypesThatInvalidate.js +216 -0
- package/build/browser/observable/internal/getObjectTypesThatInvalidate.js.map +1 -0
- package/build/browser/observable/internal/getObjectTypesThatInvalidate.test.js +382 -0
- package/build/browser/observable/internal/getObjectTypesThatInvalidate.test.js.map +1 -0
- package/build/browser/observable/internal/isObjectInstance.js +23 -0
- package/build/browser/observable/internal/isObjectInstance.js.map +1 -0
- package/build/browser/observable/internal/links/LinksHelper.js +37 -0
- package/build/browser/observable/internal/links/LinksHelper.js.map +1 -0
- package/build/browser/observable/internal/links/SpecificLinkCacheKey.js +2 -0
- package/build/browser/observable/internal/links/SpecificLinkCacheKey.js.map +1 -0
- package/build/browser/observable/internal/links/SpecificLinkQuery.js +185 -0
- package/build/browser/observable/internal/links/SpecificLinkQuery.js.map +1 -0
- package/build/browser/observable/internal/list/ListsHelper.js +49 -0
- package/build/browser/observable/internal/list/ListsHelper.js.map +1 -0
- package/build/browser/observable/internal/object/ObjectsHelper.js +34 -0
- package/build/browser/observable/internal/object/ObjectsHelper.js.map +1 -0
- package/build/browser/observable/internal/removeDuplicates.js +36 -0
- package/build/browser/observable/internal/removeDuplicates.js.map +1 -0
- package/build/browser/observable/internal/sorting/SortingStrategy.js +78 -0
- package/build/browser/observable/internal/sorting/SortingStrategy.js.map +1 -0
- package/build/browser/observable/internal/testUtils/invalidateList.js +23 -0
- package/build/browser/observable/internal/testUtils/invalidateList.js.map +1 -0
- package/build/browser/observable/internal/testUtils/observeLink/expectStandardObserveLink.js +69 -0
- package/build/browser/observable/internal/testUtils/observeLink/expectStandardObserveLink.js.map +1 -0
- package/build/browser/observable/internal/testUtils/observeObject/expectStandardObserveObject.js +56 -0
- package/build/browser/observable/internal/testUtils/observeObject/expectStandardObserveObject.js.map +1 -0
- package/build/browser/observable/internal/testUtils.js +70 -7
- package/build/browser/observable/internal/testUtils.js.map +1 -1
- package/build/browser/public/unstable-do-not-use.js.map +1 -1
- package/build/browser/util/UserAgent.js +2 -2
- package/build/browser/util/streamutils.js +1 -1
- package/build/browser/util/streamutils.js.map +1 -1
- package/build/cjs/{chunk-URDXPIRU.cjs → chunk-N5DMNYGH.cjs} +58 -54
- package/build/cjs/chunk-N5DMNYGH.cjs.map +1 -0
- package/build/cjs/{chunk-BJYCRD5Y.cjs → chunk-NWD33DSJ.cjs} +23 -19
- package/build/cjs/chunk-NWD33DSJ.cjs.map +1 -0
- package/build/cjs/index.cjs +7 -7
- package/build/cjs/public/internal.cjs +8 -8
- package/build/cjs/public/unstable-do-not-use.cjs +779 -268
- package/build/cjs/public/unstable-do-not-use.cjs.map +1 -1
- package/build/cjs/public/unstable-do-not-use.d.cts +161 -12
- package/build/esm/Client.js +1 -1
- package/build/esm/Client.js.map +1 -1
- package/build/esm/intellisense.test.helpers/orderBySuggestionIsRight.js +8 -1
- package/build/esm/intellisense.test.helpers/orderBySuggestionIsRight.js.map +1 -1
- package/build/esm/intellisense.test.js +14 -4
- package/build/esm/intellisense.test.js.map +1 -1
- package/build/esm/object/Cache.js +1 -1
- package/build/esm/object/Cache.js.map +1 -1
- package/build/esm/object/SimpleCache.js +1 -1
- package/build/esm/object/SimpleCache.js.map +1 -1
- package/build/esm/object/convertWireToOsdkObjects.js +4 -0
- package/build/esm/object/convertWireToOsdkObjects.js.map +1 -1
- package/build/esm/object/fetchPage.js +8 -4
- package/build/esm/object/fetchPage.js.map +1 -1
- package/build/esm/object/geotimeseriesreference.test.js +0 -2
- package/build/esm/object/geotimeseriesreference.test.js.map +1 -1
- package/build/esm/objectSet/createObjectSet.js +3 -1
- package/build/esm/objectSet/createObjectSet.js.map +1 -1
- package/build/esm/observable/LinkPayload.js +2 -0
- package/build/esm/observable/LinkPayload.js.map +1 -0
- package/build/esm/observable/ObjectPayload.js.map +1 -1
- package/build/esm/observable/ObservableClient/ObserveLink.js +17 -0
- package/build/esm/observable/ObservableClient/ObserveLink.js.map +1 -0
- package/build/esm/observable/ObservableClient/common.js +2 -0
- package/build/esm/observable/ObservableClient/common.js.map +1 -0
- package/build/esm/observable/ObservableClient.js +20 -0
- package/build/esm/observable/ObservableClient.js.map +1 -1
- package/build/esm/observable/Unsubscribable.js +2 -0
- package/build/esm/observable/Unsubscribable.js.map +1 -0
- package/build/esm/observable/internal/AbstractHelper.js +50 -0
- package/build/esm/observable/internal/AbstractHelper.js.map +1 -0
- package/build/esm/observable/internal/BaseCollectionQuery.js +2 -0
- package/build/esm/observable/internal/BaseCollectionQuery.js.map +1 -0
- package/build/esm/observable/internal/BulkObjectLoader.js +3 -3
- package/build/esm/observable/internal/BulkObjectLoader.js.map +1 -1
- package/build/esm/observable/internal/CacheKeys.js +17 -2
- package/build/esm/observable/internal/CacheKeys.js.map +1 -1
- package/build/esm/observable/internal/Changes.js +6 -0
- package/build/esm/observable/internal/Changes.js.map +1 -1
- package/build/esm/observable/internal/KnownCacheKey.js +2 -0
- package/build/esm/observable/internal/KnownCacheKey.js.map +1 -0
- package/build/esm/observable/internal/Layer.js.map +1 -1
- package/build/esm/observable/internal/ListCacheKey.js +2 -0
- package/build/esm/observable/internal/ListCacheKey.js.map +1 -0
- package/build/esm/observable/internal/ListQuery.js +399 -161
- package/build/esm/observable/internal/ListQuery.js.map +1 -1
- package/build/esm/observable/internal/ObjectQuery.js +27 -2
- package/build/esm/observable/internal/ObjectQuery.js.map +1 -1
- package/build/esm/observable/internal/ObservableClientImpl.js +42 -2
- package/build/esm/observable/internal/ObservableClientImpl.js.map +1 -1
- package/build/esm/observable/internal/OptimisticJob.js +12 -3
- package/build/esm/observable/internal/OptimisticJob.js.map +1 -1
- package/build/esm/observable/internal/Query.js +17 -3
- package/build/esm/observable/internal/Query.js.map +1 -1
- package/build/esm/observable/internal/QuerySubscription.js +41 -0
- package/build/esm/observable/internal/QuerySubscription.js.map +1 -0
- package/build/esm/observable/internal/Store.invalidation.test.js +481 -0
- package/build/esm/observable/internal/Store.invalidation.test.js.map +1 -0
- package/build/esm/observable/internal/Store.js +38 -91
- package/build/esm/observable/internal/Store.js.map +1 -1
- package/build/esm/observable/internal/Store.test.js +318 -63
- package/build/esm/observable/internal/Store.test.js.map +1 -1
- package/build/esm/observable/internal/UnsubscribableWrapper.js +30 -0
- package/build/esm/observable/internal/UnsubscribableWrapper.js.map +1 -0
- package/build/esm/observable/internal/createCollectionConnectable.js +50 -0
- package/build/esm/observable/internal/createCollectionConnectable.js.map +1 -0
- package/build/esm/observable/internal/createCollectionConnectable.test.js +599 -0
- package/build/esm/observable/internal/createCollectionConnectable.test.js.map +1 -0
- package/build/esm/observable/internal/getObjectTypesThatInvalidate.js +216 -0
- package/build/esm/observable/internal/getObjectTypesThatInvalidate.js.map +1 -0
- package/build/esm/observable/internal/getObjectTypesThatInvalidate.test.js +382 -0
- package/build/esm/observable/internal/getObjectTypesThatInvalidate.test.js.map +1 -0
- package/build/esm/observable/internal/isObjectInstance.js +23 -0
- package/build/esm/observable/internal/isObjectInstance.js.map +1 -0
- package/build/esm/observable/internal/links/LinksHelper.js +37 -0
- package/build/esm/observable/internal/links/LinksHelper.js.map +1 -0
- package/build/esm/observable/internal/links/SpecificLinkCacheKey.js +2 -0
- package/build/esm/observable/internal/links/SpecificLinkCacheKey.js.map +1 -0
- package/build/esm/observable/internal/links/SpecificLinkQuery.js +185 -0
- package/build/esm/observable/internal/links/SpecificLinkQuery.js.map +1 -0
- package/build/esm/observable/internal/list/ListsHelper.js +49 -0
- package/build/esm/observable/internal/list/ListsHelper.js.map +1 -0
- package/build/esm/observable/internal/object/ObjectsHelper.js +34 -0
- package/build/esm/observable/internal/object/ObjectsHelper.js.map +1 -0
- package/build/esm/observable/internal/removeDuplicates.js +36 -0
- package/build/esm/observable/internal/removeDuplicates.js.map +1 -0
- package/build/esm/observable/internal/sorting/SortingStrategy.js +78 -0
- package/build/esm/observable/internal/sorting/SortingStrategy.js.map +1 -0
- package/build/esm/observable/internal/testUtils/invalidateList.js +23 -0
- package/build/esm/observable/internal/testUtils/invalidateList.js.map +1 -0
- package/build/esm/observable/internal/testUtils/observeLink/expectStandardObserveLink.js +69 -0
- package/build/esm/observable/internal/testUtils/observeLink/expectStandardObserveLink.js.map +1 -0
- package/build/esm/observable/internal/testUtils/observeObject/expectStandardObserveObject.js +56 -0
- package/build/esm/observable/internal/testUtils/observeObject/expectStandardObserveObject.js.map +1 -0
- package/build/esm/observable/internal/testUtils.js +70 -7
- package/build/esm/observable/internal/testUtils.js.map +1 -1
- package/build/esm/public/unstable-do-not-use.js.map +1 -1
- package/build/esm/util/UserAgent.js +2 -2
- package/build/esm/util/streamutils.js +1 -1
- package/build/esm/util/streamutils.js.map +1 -1
- package/build/types/Client.d.ts +1 -1
- package/build/types/object/fetchPage.d.ts.map +1 -1
- package/build/types/observable/LinkPayload.d.ts +9 -0
- package/build/types/observable/LinkPayload.d.ts.map +1 -0
- package/build/types/observable/ObjectPayload.d.ts +4 -0
- package/build/types/observable/ObjectPayload.d.ts.map +1 -1
- package/build/types/observable/ObservableClient/ObserveLink.d.ts +32 -0
- package/build/types/observable/ObservableClient/ObserveLink.d.ts.map +1 -0
- package/build/types/observable/ObservableClient/common.d.ts +67 -0
- package/build/types/observable/ObservableClient/common.d.ts.map +1 -0
- package/build/types/observable/ObservableClient.d.ts +82 -15
- package/build/types/observable/ObservableClient.d.ts.map +1 -1
- package/build/types/observable/Unsubscribable.d.ts +3 -0
- package/build/types/observable/Unsubscribable.d.ts.map +1 -0
- package/build/types/observable/internal/AbstractHelper.d.ts +15 -0
- package/build/types/observable/internal/AbstractHelper.d.ts.map +1 -0
- package/build/types/observable/internal/BaseCollectionQuery.d.ts +64 -0
- package/build/types/observable/internal/BaseCollectionQuery.d.ts.map +1 -0
- package/build/types/observable/internal/BulkObjectLoader.d.ts.map +1 -1
- package/build/types/observable/internal/CacheKeys.d.ts +10 -4
- package/build/types/observable/internal/CacheKeys.d.ts.map +1 -1
- package/build/types/observable/internal/Changes.d.ts +7 -4
- package/build/types/observable/internal/Changes.d.ts.map +1 -1
- package/build/types/observable/internal/KnownCacheKey.d.ts +4 -0
- package/build/types/observable/internal/KnownCacheKey.d.ts.map +1 -0
- package/build/types/observable/internal/Layer.d.ts +7 -7
- package/build/types/observable/internal/Layer.d.ts.map +1 -1
- package/build/types/observable/internal/ListCacheKey.d.ts +7 -0
- package/build/types/observable/internal/ListCacheKey.d.ts.map +1 -0
- package/build/types/observable/internal/ListQuery.d.ts +160 -21
- package/build/types/observable/internal/ListQuery.d.ts.map +1 -1
- package/build/types/observable/internal/ObjectQuery.d.ts +3 -1
- package/build/types/observable/internal/ObjectQuery.d.ts.map +1 -1
- 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/QuerySubscription.d.ts +1 -0
- package/build/types/observable/internal/QuerySubscription.d.ts.map +1 -0
- package/build/types/observable/internal/Store.d.ts +34 -31
- package/build/types/observable/internal/Store.d.ts.map +1 -1
- package/build/types/observable/internal/Store.invalidation.test.d.ts +1 -0
- package/build/types/observable/internal/Store.invalidation.test.d.ts.map +1 -0
- package/build/types/observable/internal/Store.test.d.ts +4 -1
- package/build/types/observable/internal/Store.test.d.ts.map +1 -1
- package/build/types/observable/internal/UnsubscribableWrapper.d.ts +1 -0
- package/build/types/observable/internal/UnsubscribableWrapper.d.ts.map +1 -0
- package/build/types/observable/internal/createCollectionConnectable.d.ts +38 -0
- package/build/types/observable/internal/createCollectionConnectable.d.ts.map +1 -0
- package/build/types/observable/internal/createCollectionConnectable.test.d.ts +1 -0
- package/build/types/observable/internal/createCollectionConnectable.test.d.ts.map +1 -0
- package/build/types/observable/internal/getObjectTypesThatInvalidate.d.ts +9 -0
- package/build/types/observable/internal/getObjectTypesThatInvalidate.d.ts.map +1 -0
- package/build/types/observable/internal/getObjectTypesThatInvalidate.test.d.ts +1 -0
- package/build/types/observable/internal/getObjectTypesThatInvalidate.test.d.ts.map +1 -0
- package/build/types/observable/internal/isObjectInstance.d.ts +5 -0
- package/build/types/observable/internal/isObjectInstance.d.ts.map +1 -0
- package/build/types/observable/internal/links/LinksHelper.d.ts +29 -0
- package/build/types/observable/internal/links/LinksHelper.d.ts.map +1 -0
- package/build/types/observable/internal/links/SpecificLinkCacheKey.d.ts +17 -0
- package/build/types/observable/internal/links/SpecificLinkCacheKey.d.ts.map +1 -0
- package/build/types/observable/internal/links/SpecificLinkQuery.d.ts +45 -0
- package/build/types/observable/internal/links/SpecificLinkQuery.d.ts.map +1 -0
- package/build/types/observable/internal/list/ListsHelper.d.ts +17 -0
- package/build/types/observable/internal/list/ListsHelper.d.ts.map +1 -0
- package/build/types/observable/internal/object/ObjectsHelper.d.ts +11 -0
- package/build/types/observable/internal/object/ObjectsHelper.d.ts.map +1 -0
- package/build/types/observable/internal/removeDuplicates.d.ts +11 -0
- package/build/types/observable/internal/removeDuplicates.d.ts.map +1 -0
- package/build/types/observable/internal/sorting/SortingStrategy.d.ts +41 -0
- package/build/types/observable/internal/sorting/SortingStrategy.d.ts.map +1 -0
- package/build/types/observable/internal/testUtils/invalidateList.d.ts +9 -0
- package/build/types/observable/internal/testUtils/invalidateList.d.ts.map +1 -0
- package/build/types/observable/internal/testUtils/observeLink/expectStandardObserveLink.d.ts +46 -0
- package/build/types/observable/internal/testUtils/observeLink/expectStandardObserveLink.d.ts.map +1 -0
- package/build/types/observable/internal/testUtils/observeObject/expectStandardObserveObject.d.ts +26 -0
- package/build/types/observable/internal/testUtils/observeObject/expectStandardObserveObject.d.ts.map +1 -0
- package/build/types/observable/internal/testUtils.d.ts +25 -3
- package/build/types/observable/internal/testUtils.d.ts.map +1 -1
- package/build/types/public/unstable-do-not-use.d.ts +4 -2
- package/build/types/public/unstable-do-not-use.d.ts.map +1 -1
- package/package.json +10 -10
- package/build/cjs/chunk-BJYCRD5Y.cjs.map +0 -1
- package/build/cjs/chunk-URDXPIRU.cjs.map +0 -1
|
@@ -66,6 +66,8 @@ export class Query {
|
|
|
66
66
|
await this.pendingFetch;
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
// FIXME: This gets set to the first value used
|
|
69
71
|
if ((this.options.dedupeInterval ?? 0) > 0 && this.lastFetchStarted != null && Date.now() - this.lastFetchStarted < (this.options.dedupeInterval ?? 0)) {
|
|
70
72
|
if (process.env.NODE_ENV !== "production") {
|
|
71
73
|
logger?.debug("Within dupeInterval, aborting revalidate");
|
|
@@ -88,7 +90,7 @@ export class Query {
|
|
|
88
90
|
logger?.debug("calling _fetchAndStore()");
|
|
89
91
|
}
|
|
90
92
|
this.pendingFetch = this._fetchAndStore().finally(() => {
|
|
91
|
-
logger?.debug("finally _fetchAndStore()");
|
|
93
|
+
logger?.debug("promise's finally for _fetchAndStore()");
|
|
92
94
|
this.pendingFetch = undefined;
|
|
93
95
|
});
|
|
94
96
|
await this.pendingFetch;
|
|
@@ -105,10 +107,22 @@ export class Query {
|
|
|
105
107
|
if (process.env.NODE_ENV !== "production") {
|
|
106
108
|
this.logger?.child({
|
|
107
109
|
methodName: "setStatus"
|
|
108
|
-
}).debug(status);
|
|
110
|
+
}).debug(`Attempting to set status to '${status}'`);
|
|
109
111
|
}
|
|
110
112
|
const existing = batch.read(this.cacheKey);
|
|
111
|
-
if (existing?.status === status)
|
|
113
|
+
if (existing?.status === status) {
|
|
114
|
+
if (process.env.NODE_ENV !== "production") {
|
|
115
|
+
this.logger?.child({
|
|
116
|
+
methodName: "setStatus"
|
|
117
|
+
}).debug(`Status is already set to '${status}'; aborting`);
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (process.env.NODE_ENV !== "production") {
|
|
122
|
+
this.logger?.child({
|
|
123
|
+
methodName: "setStatus"
|
|
124
|
+
}).debug(`Writing status '${status}' to cache`);
|
|
125
|
+
}
|
|
112
126
|
batch.write(this.cacheKey, existing?.value, status);
|
|
113
127
|
}
|
|
114
128
|
dispose() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Query.js","names":["additionalContext","Query","retainCount","connectable","subscription","subject","constructor","store","observable","opts","cacheKey","logger","options","process","env","NODE_ENV","client","child","msgPrefix","type","otherKeys","map","x","JSON","stringify","join","subscribe","observer","_createConnectable","connect","revalidate","force","methodName","abortController","abort","pendingFetch","debug","dedupeInterval","lastFetchStarted","Date","now","Promise","resolve","batch","setStatus","_preFetch","_fetchAndStore","finally","undefined","status","existing","read","write","value","dispose","unsubscribe","_dispose"],"sources":["Query.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 { Logger } from \"@osdk/api\";\nimport type {\n Connectable,\n Observable,\n Observer,\n Subscribable,\n Subscription,\n} from \"rxjs\";\nimport { additionalContext } from \"../../Client.js\";\nimport type { CommonObserveOptions, Status } from \"../ObservableClient.js\";\nimport type { CacheKey } from \"./CacheKey.js\";\nimport type { Changes } from \"./Changes.js\";\nimport type { Entry } from \"./Layer.js\";\nimport type { OptimisticId } from \"./OptimisticId.js\";\nimport type { BatchContext, Store, SubjectPayload } from \"./Store.js\";\n\nexport abstract class Query<\n KEY extends CacheKey,\n PAYLOAD,\n O extends CommonObserveOptions,\n> implements Subscribable<PAYLOAD> {\n lastFetchStarted?: number;\n pendingFetch?: Promise<unknown>;\n retainCount: number = 0;\n options: O;\n cacheKey: KEY;\n store: Store;\n abortController?: AbortController;\n #connectable?: Connectable<PAYLOAD>;\n #subscription?: Subscription;\n #subject: Observable<SubjectPayload<KEY>>;\n\n /** @internal */\n protected logger: Logger | undefined;\n\n constructor(\n store: Store,\n observable: Observable<SubjectPayload<KEY>>,\n opts: O,\n cacheKey: KEY,\n logger?: Logger,\n ) {\n this.options = opts;\n this.cacheKey = cacheKey;\n this.store = store;\n this.#subject = observable;\n\n this.logger = logger ?? (\n process.env.NODE_ENV === \"production\"\n ? store.client[additionalContext].logger\n : store.client[additionalContext].logger?.child({}, {\n msgPrefix: process.env.NODE_ENV !== \"production\"\n ? (`Query<${cacheKey.type}, ${\n cacheKey.otherKeys.map(x => JSON.stringify(x)).join(\", \")\n }>`)\n : \"Query\",\n })\n );\n }\n\n protected abstract _createConnectable(\n subject: Observable<SubjectPayload<KEY>>,\n ): Connectable<PAYLOAD>;\n\n public subscribe(\n observer: Observer<PAYLOAD>,\n ): Subscription {\n this.#connectable ??= this._createConnectable(this.#subject);\n this.#subscription = this.#connectable.connect();\n return this.#connectable.subscribe(observer);\n }\n\n /**\n * Causes the query to revalidate. This will cause the query to fetch\n * the latest data from the server and update the store if it is deemed\n * \"stale\" or if `force` is true.\n *\n * @param force\n * @returns\n */\n async revalidate(force?: boolean): Promise<void> {\n const logger = process.env.NODE_ENV !== \"production\"\n ? this.logger?.child({ methodName: \"revalidate\" })\n : this.logger;\n\n if (force) {\n this.abortController?.abort();\n }\n\n // n.b. I think this isn't quite right since we may require multiple\n // pages to properly \"revalidate\" for someone. This only really works if you\n // have a single page/object. It needs to be redone. FIXME\n\n // if we are pending the first page/object we can just ignore this\n if (this.pendingFetch) {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"Fetch is already pending, using it\");\n }\n await this.pendingFetch;\n return;\n }\n\n if (\n (this.options.dedupeInterval ?? 0) > 0 && (\n this.lastFetchStarted != null\n && Date.now() - this.lastFetchStarted < (this.options.dedupeInterval\n ?? 0)\n )\n ) {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"Within dupeInterval, aborting revalidate\");\n }\n\n return Promise.resolve();\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"Starting actual revalidate\");\n }\n\n this.store.batch({}, (batch) => {\n // make sure the truth layer knows we are loading\n\n // this will not trigger an update to `changes` so it cannot trigger an\n // update of a list either. This may not be the behavior we want.\n this.setStatus(\"loading\", batch);\n });\n\n this._preFetch();\n\n this.lastFetchStarted = Date.now();\n\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"calling _fetchAndStore()\");\n }\n this.pendingFetch = this._fetchAndStore()\n .finally(() => {\n logger?.debug(\"finally _fetchAndStore()\");\n this.pendingFetch = undefined;\n });\n\n await this.pendingFetch;\n return;\n }\n\n protected _preFetch(): void {}\n\n protected abstract _fetchAndStore(): Promise<unknown>;\n\n /**\n * Sets the status of the query in the store (but does not store that in `changes`).\n *\n * @param status\n * @param batch\n * @returns\n */\n setStatus(\n status: Status,\n batch: BatchContext,\n ): void {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"setStatus\" }).debug(status);\n }\n const existing = batch.read(this.cacheKey);\n if (existing?.status === status) return;\n\n batch.write(this.cacheKey, existing?.value, status);\n }\n\n dispose(): void {\n if (this.abortController) {\n this.abortController.abort();\n }\n this.#subscription?.unsubscribe();\n this._dispose();\n }\n\n /**\n * Per query type dispose functionality\n */\n protected _dispose(): void {}\n\n /**\n * The purpose of this method is to provide a way for others to write\n * directly into the store for this query.\n *\n * @param data\n * @param status\n * @param batch\n */\n abstract writeToStore(\n data: KEY[\"__cacheKey\"][\"value\"],\n status: Status,\n batch: BatchContext,\n ): Entry<KEY>;\n\n /**\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 maybeUpdateAndRevalidate?: (\n changes: Changes,\n optimisticId: OptimisticId | undefined,\n ) => Promise<void> | undefined;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Query.js","names":["additionalContext","Query","retainCount","connectable","subscription","subject","constructor","store","observable","opts","cacheKey","logger","options","process","env","NODE_ENV","client","child","msgPrefix","type","otherKeys","map","x","JSON","stringify","join","subscribe","observer","_createConnectable","connect","revalidate","force","methodName","abortController","abort","pendingFetch","debug","dedupeInterval","lastFetchStarted","Date","now","Promise","resolve","batch","setStatus","_preFetch","_fetchAndStore","finally","undefined","status","existing","read","write","value","dispose","unsubscribe","_dispose"],"sources":["Query.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 { Logger } from \"@osdk/api\";\nimport type {\n Connectable,\n Observable,\n Observer,\n Subscribable,\n Subscription,\n} from \"rxjs\";\nimport { additionalContext } from \"../../Client.js\";\nimport type {\n CommonObserveOptions,\n Status,\n} from \"../ObservableClient/common.js\";\nimport type { Changes } from \"./Changes.js\";\nimport type { KnownCacheKey } from \"./KnownCacheKey.js\";\nimport type { Entry } from \"./Layer.js\";\nimport type { OptimisticId } from \"./OptimisticId.js\";\nimport type { BatchContext, Store, SubjectPayload } from \"./Store.js\";\n\nexport abstract class Query<\n KEY extends KnownCacheKey,\n PAYLOAD,\n O extends CommonObserveOptions,\n> implements Subscribable<PAYLOAD> {\n lastFetchStarted?: number;\n pendingFetch?: Promise<void>;\n retainCount: number = 0;\n options: O;\n cacheKey: KEY;\n store: Store;\n abortController?: AbortController;\n #connectable?: Connectable<PAYLOAD>;\n #subscription?: Subscription;\n #subject: Observable<SubjectPayload<KEY>>;\n\n /** @internal */\n protected logger: Logger | undefined;\n\n constructor(\n store: Store,\n observable: Observable<SubjectPayload<KEY>>,\n opts: O,\n cacheKey: KEY,\n logger?: Logger,\n ) {\n this.options = opts;\n this.cacheKey = cacheKey;\n this.store = store;\n this.#subject = observable;\n\n this.logger = logger ?? (\n process.env.NODE_ENV === \"production\"\n ? store.client[additionalContext].logger\n : store.client[additionalContext].logger?.child({}, {\n msgPrefix: process.env.NODE_ENV !== \"production\"\n ? (`Query<${cacheKey.type}, ${\n cacheKey.otherKeys.map(x => JSON.stringify(x)).join(\", \")\n }>`)\n : \"Query\",\n })\n );\n }\n\n protected abstract _createConnectable(\n subject: Observable<SubjectPayload<KEY>>,\n ): Connectable<PAYLOAD>;\n\n public subscribe(\n observer: Observer<PAYLOAD>,\n ): Subscription {\n this.#connectable ??= this._createConnectable(this.#subject);\n this.#subscription = this.#connectable.connect();\n return this.#connectable.subscribe(observer);\n }\n\n /**\n * Causes the query to revalidate. This will cause the query to fetch\n * the latest data from the server and update the store if it is deemed\n * \"stale\" or if `force` is true.\n *\n * @param force\n * @returns\n */\n async revalidate(force?: boolean): Promise<void> {\n const logger = process.env.NODE_ENV !== \"production\"\n ? this.logger?.child({ methodName: \"revalidate\" })\n : this.logger;\n\n if (force) {\n this.abortController?.abort();\n }\n\n // n.b. I think this isn't quite right since we may require multiple\n // pages to properly \"revalidate\" for someone. This only really works if you\n // have a single page/object. It needs to be redone. FIXME\n\n // if we are pending the first page/object we can just ignore this\n if (this.pendingFetch) {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"Fetch is already pending, using it\");\n }\n await this.pendingFetch;\n return;\n }\n\n // FIXME: This gets set to the first value used\n if (\n (this.options.dedupeInterval ?? 0) > 0 && (\n this.lastFetchStarted != null\n && Date.now() - this.lastFetchStarted < (this.options.dedupeInterval\n ?? 0)\n )\n ) {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"Within dupeInterval, aborting revalidate\");\n }\n\n return Promise.resolve();\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"Starting actual revalidate\");\n }\n\n this.store.batch({}, (batch) => {\n // make sure the truth layer knows we are loading\n\n // this will not trigger an update to `changes` so it cannot trigger an\n // update of a list either. This may not be the behavior we want.\n this.setStatus(\"loading\", batch);\n });\n\n this._preFetch();\n\n this.lastFetchStarted = Date.now();\n\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"calling _fetchAndStore()\");\n }\n this.pendingFetch = this._fetchAndStore()\n .finally(() => {\n logger?.debug(\"promise's finally for _fetchAndStore()\");\n this.pendingFetch = undefined;\n });\n\n await this.pendingFetch;\n return;\n }\n\n protected _preFetch(): void {}\n\n protected abstract _fetchAndStore(): Promise<void>;\n\n /**\n * Sets the status of the query in the store (but does not store that in `changes`).\n *\n * @param status\n * @param batch\n * @returns\n */\n setStatus(\n status: Status,\n batch: BatchContext,\n ): void {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"setStatus\" }).debug(\n `Attempting to set status to '${status}'`,\n );\n }\n const existing = batch.read(this.cacheKey);\n if (existing?.status === status) {\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"setStatus\" }).debug(\n `Status is already set to '${status}'; aborting`,\n );\n }\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"setStatus\" }).debug(\n `Writing status '${status}' to cache`,\n );\n }\n batch.write(this.cacheKey, existing?.value, status);\n }\n\n dispose(): void {\n if (this.abortController) {\n this.abortController.abort();\n }\n this.#subscription?.unsubscribe();\n this._dispose();\n }\n\n /**\n * Per query type dispose functionality\n */\n protected _dispose(): void {}\n\n /**\n * The purpose of this method is to provide a way for others to write\n * directly into the store for this query.\n *\n * @param data\n * @param status\n * @param batch\n */\n abstract writeToStore(\n data: KEY[\"__cacheKey\"][\"value\"],\n status: Status,\n batch: BatchContext,\n ): Entry<KEY>;\n\n /**\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 maybeUpdateAndRevalidate?: (\n changes: Changes,\n optimisticId: OptimisticId | undefined,\n ) => Promise<void> | undefined;\n\n abstract invalidateObjectType(\n objectType: string,\n changes: Changes | undefined,\n ): Promise<void>;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { UnsubscribableWrapper } from "./UnsubscribableWrapper.js";
|
|
18
|
+
|
|
19
|
+
/** @internal */
|
|
20
|
+
export class QuerySubscription extends UnsubscribableWrapper {
|
|
21
|
+
/** @internal */
|
|
22
|
+
|
|
23
|
+
/** @internal */
|
|
24
|
+
|
|
25
|
+
constructor(query, subscription) {
|
|
26
|
+
super(subscription);
|
|
27
|
+
this.query = query;
|
|
28
|
+
this.subscription = subscription;
|
|
29
|
+
|
|
30
|
+
// hide these from introspection
|
|
31
|
+
Object.defineProperties(this, {
|
|
32
|
+
query: {
|
|
33
|
+
enumerable: false
|
|
34
|
+
},
|
|
35
|
+
subscription: {
|
|
36
|
+
enumerable: false
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=QuerySubscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuerySubscription.js","names":["UnsubscribableWrapper","QuerySubscription","constructor","query","subscription","Object","defineProperties","enumerable"],"sources":["QuerySubscription.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 { Subscription } from \"rxjs\";\nimport type {\n CommonObserveOptions,\n ObserveOptions,\n} from \"../ObservableClient/common.js\";\nimport type { KnownCacheKey } from \"./KnownCacheKey.js\";\nimport type { Query } from \"./Query.js\";\nimport { UnsubscribableWrapper } from \"./UnsubscribableWrapper.js\";\n\n/** @internal */\nexport class QuerySubscription<\n TQuery extends Query<\n KnownCacheKey,\n unknown,\n CommonObserveOptions & ObserveOptions\n >,\n> extends UnsubscribableWrapper {\n /** @internal */\n query: TQuery;\n\n /** @internal */\n subscription: Subscription;\n\n constructor(query: TQuery, subscription: Subscription) {\n super(subscription);\n this.query = query;\n this.subscription = subscription;\n\n // hide these from introspection\n Object.defineProperties(this, {\n query: { enumerable: false },\n subscription: { enumerable: false },\n });\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AASA,SAASA,qBAAqB,QAAQ,4BAA4B;;AAElE;AACA,OAAO,MAAMC,iBAAiB,SAMpBD,qBAAqB,CAAC;EAC9B;;EAGA;;EAGAE,WAAWA,CAACC,KAAa,EAAEC,YAA0B,EAAE;IACrD,KAAK,CAACA,YAAY,CAAC;IACnB,IAAI,CAACD,KAAK,GAAGA,KAAK;IAClB,IAAI,CAACC,YAAY,GAAGA,YAAY;;IAEhC;IACAC,MAAM,CAACC,gBAAgB,CAAC,IAAI,EAAE;MAC5BH,KAAK,EAAE;QAAEI,UAAU,EAAE;MAAM,CAAC;MAC5BH,YAAY,EAAE;QAAEG,UAAU,EAAE;MAAM;IACpC,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { Employee, Office, Todo } from "@osdk/client.test.ontology";
|
|
18
|
+
import { FauxFoundry, ontologies, startNodeApiServer, stubData } from "@osdk/shared.test";
|
|
19
|
+
import invariant from "tiny-invariant";
|
|
20
|
+
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
21
|
+
import { createClient } from "../../createClient.js";
|
|
22
|
+
import { TestLogger } from "../../logger/TestLogger.js";
|
|
23
|
+
import { Store } from "./Store.js";
|
|
24
|
+
import { createDefer, mockListSubCallback, updateList } from "./testUtils.js";
|
|
25
|
+
import { expectStandardObserveLink } from "./testUtils/observeLink/expectStandardObserveLink.js";
|
|
26
|
+
import { expectStandardObserveObject } from "./testUtils/observeObject/expectStandardObserveObject.js";
|
|
27
|
+
|
|
28
|
+
// Defer utility to track subscriptions for cleanup
|
|
29
|
+
const defer = createDefer();
|
|
30
|
+
|
|
31
|
+
// Logger setup
|
|
32
|
+
const logger = new TestLogger({}, {
|
|
33
|
+
// level: "debug",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Constants for test objects
|
|
37
|
+
const EMPLOYEE_1_ID = 1;
|
|
38
|
+
const EMPLOYEE_2_ID = 2;
|
|
39
|
+
const OFFICE_1_ID = "101";
|
|
40
|
+
const OFFICE_2_ID = "102";
|
|
41
|
+
const TODO_1_ID = 201;
|
|
42
|
+
const TODO_2_ID = 202;
|
|
43
|
+
describe("Store Invalidation Type Isolation", () => {
|
|
44
|
+
let client;
|
|
45
|
+
let cache;
|
|
46
|
+
let fauxFoundry;
|
|
47
|
+
function setupOntology(fauxFoundry) {
|
|
48
|
+
const fauxOntology = fauxFoundry.getDefaultOntology();
|
|
49
|
+
ontologies.addEmployeeOntology(fauxOntology);
|
|
50
|
+
fauxFoundry.getDefaultOntology().registerObjectType(stubData.todoWithLinkTypes);
|
|
51
|
+
fauxFoundry.getDefaultOntology().registerActionType(stubData.editTodo.actionTypeV2, (b, payload) => {
|
|
52
|
+
const {
|
|
53
|
+
id,
|
|
54
|
+
...other
|
|
55
|
+
} = payload.parameters;
|
|
56
|
+
b.modifyObject(Todo.apiName, id, {
|
|
57
|
+
...other
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function setupTestObjects(fauxFoundry) {
|
|
62
|
+
const dataStore = fauxFoundry.getDefaultDataStore();
|
|
63
|
+
|
|
64
|
+
// Create Employees
|
|
65
|
+
const emp1 = dataStore.registerObject(Employee, {
|
|
66
|
+
employeeId: EMPLOYEE_1_ID,
|
|
67
|
+
fullName: "Employee One"
|
|
68
|
+
});
|
|
69
|
+
const emp2 = dataStore.registerObject(Employee, {
|
|
70
|
+
employeeId: EMPLOYEE_2_ID,
|
|
71
|
+
fullName: "Employee Two"
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Create Offices
|
|
75
|
+
const office1 = dataStore.registerObject(Office, {
|
|
76
|
+
officeId: OFFICE_1_ID,
|
|
77
|
+
name: "Office One"
|
|
78
|
+
});
|
|
79
|
+
const office2 = dataStore.registerObject(Office, {
|
|
80
|
+
officeId: OFFICE_2_ID,
|
|
81
|
+
name: "Office Two"
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Create Todos
|
|
85
|
+
const todo1 = dataStore.registerObject(Todo, {
|
|
86
|
+
$apiName: "Todo",
|
|
87
|
+
id: TODO_1_ID,
|
|
88
|
+
text: "Todo One"
|
|
89
|
+
});
|
|
90
|
+
const todo2 = dataStore.registerObject(Todo, {
|
|
91
|
+
$apiName: "Todo",
|
|
92
|
+
id: TODO_2_ID,
|
|
93
|
+
text: "Todo Two"
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Link employees to offices
|
|
97
|
+
dataStore.registerLink(emp1, "officeLink", office1, "occupants");
|
|
98
|
+
dataStore.registerLink(emp2, "officeLink", office2, "occupants");
|
|
99
|
+
|
|
100
|
+
// Link employees to todos (we're not using these links in this test, but showing different link patterns)
|
|
101
|
+
// Note: There are no direct Todo-Employee links in the test ontology
|
|
102
|
+
}
|
|
103
|
+
beforeAll(async () => {
|
|
104
|
+
// Set up the mock environment and client
|
|
105
|
+
const testSetup = startNodeApiServer(new FauxFoundry("https://stack.palantir.com/"), createClient, {
|
|
106
|
+
logger
|
|
107
|
+
});
|
|
108
|
+
({
|
|
109
|
+
client,
|
|
110
|
+
fauxFoundry
|
|
111
|
+
} = testSetup);
|
|
112
|
+
|
|
113
|
+
// Set up the test ontology and data
|
|
114
|
+
setupOntology(fauxFoundry);
|
|
115
|
+
setupTestObjects(fauxFoundry);
|
|
116
|
+
return () => {
|
|
117
|
+
testSetup.apiServer.close();
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
beforeEach(() => {
|
|
121
|
+
vi.resetAllMocks();
|
|
122
|
+
cache = new Store(client);
|
|
123
|
+
return () => {
|
|
124
|
+
cache = undefined;
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
describe("Object Type Isolation", () => {
|
|
128
|
+
it("invalidating Employee type should not affect Office objects", async () => {
|
|
129
|
+
// Set up observations for an Employee and Office object
|
|
130
|
+
const {
|
|
131
|
+
payload: emp1Payload,
|
|
132
|
+
subFn: empSubFn
|
|
133
|
+
} = await expectStandardObserveObject({
|
|
134
|
+
cache,
|
|
135
|
+
type: Employee,
|
|
136
|
+
primaryKey: EMPLOYEE_1_ID
|
|
137
|
+
});
|
|
138
|
+
const emp1 = emp1Payload?.object;
|
|
139
|
+
!emp1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
140
|
+
const {
|
|
141
|
+
payload: office1Payload,
|
|
142
|
+
subFn: officeSubFn
|
|
143
|
+
} = await expectStandardObserveObject({
|
|
144
|
+
cache,
|
|
145
|
+
type: Office,
|
|
146
|
+
primaryKey: OFFICE_1_ID
|
|
147
|
+
});
|
|
148
|
+
const office1 = office1Payload?.object;
|
|
149
|
+
!office1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
150
|
+
|
|
151
|
+
// Clear the initial calls
|
|
152
|
+
empSubFn.next.mockClear();
|
|
153
|
+
officeSubFn.next.mockClear();
|
|
154
|
+
|
|
155
|
+
// Invalidate only the Employee type
|
|
156
|
+
await cache.invalidateObjectType(Employee, undefined);
|
|
157
|
+
|
|
158
|
+
// Allow time for any potential updates
|
|
159
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
160
|
+
|
|
161
|
+
// Employee should be updated
|
|
162
|
+
expect(empSubFn.next).toHaveBeenCalled();
|
|
163
|
+
|
|
164
|
+
// Office object should NOT receive any updates
|
|
165
|
+
expect(officeSubFn.next).not.toHaveBeenCalled();
|
|
166
|
+
});
|
|
167
|
+
it("invalidating Office type should not affect Employee objects", async () => {
|
|
168
|
+
// Set up observations for an Employee and Office object
|
|
169
|
+
const {
|
|
170
|
+
payload: emp1Payload,
|
|
171
|
+
subFn: empSubFn
|
|
172
|
+
} = await expectStandardObserveObject({
|
|
173
|
+
cache,
|
|
174
|
+
type: Employee,
|
|
175
|
+
primaryKey: EMPLOYEE_1_ID
|
|
176
|
+
});
|
|
177
|
+
const emp1 = emp1Payload?.object;
|
|
178
|
+
!emp1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
179
|
+
const {
|
|
180
|
+
payload: office1Payload,
|
|
181
|
+
subFn: officeSubFn
|
|
182
|
+
} = await expectStandardObserveObject({
|
|
183
|
+
cache,
|
|
184
|
+
type: Office,
|
|
185
|
+
primaryKey: OFFICE_1_ID
|
|
186
|
+
});
|
|
187
|
+
const office1 = office1Payload?.object;
|
|
188
|
+
!office1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
189
|
+
|
|
190
|
+
// Clear the initial calls
|
|
191
|
+
empSubFn.next.mockClear();
|
|
192
|
+
officeSubFn.next.mockClear();
|
|
193
|
+
|
|
194
|
+
// Invalidate only the Office type
|
|
195
|
+
await cache.invalidateObjectType(Office, undefined);
|
|
196
|
+
|
|
197
|
+
// Allow time for any potential updates
|
|
198
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
199
|
+
|
|
200
|
+
// Office should be updated
|
|
201
|
+
expect(officeSubFn.next).toHaveBeenCalled();
|
|
202
|
+
|
|
203
|
+
// Employee object should NOT receive any updates
|
|
204
|
+
expect(empSubFn.next).not.toHaveBeenCalled();
|
|
205
|
+
});
|
|
206
|
+
it("invalidating Todo type should not affect Employee or Office objects", async () => {
|
|
207
|
+
// Set up observations for Employee, Office, and Todo objects
|
|
208
|
+
const {
|
|
209
|
+
payload: emp1Payload,
|
|
210
|
+
subFn: empSubFn
|
|
211
|
+
} = await expectStandardObserveObject({
|
|
212
|
+
cache,
|
|
213
|
+
type: Employee,
|
|
214
|
+
primaryKey: EMPLOYEE_1_ID
|
|
215
|
+
});
|
|
216
|
+
const emp1 = emp1Payload?.object;
|
|
217
|
+
!emp1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
218
|
+
const {
|
|
219
|
+
payload: office1Payload,
|
|
220
|
+
subFn: officeSubFn
|
|
221
|
+
} = await expectStandardObserveObject({
|
|
222
|
+
cache,
|
|
223
|
+
type: Office,
|
|
224
|
+
primaryKey: OFFICE_1_ID
|
|
225
|
+
});
|
|
226
|
+
const office1 = office1Payload?.object;
|
|
227
|
+
!office1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
228
|
+
const {
|
|
229
|
+
payload: todo1Payload,
|
|
230
|
+
subFn: todoSubFn
|
|
231
|
+
} = await expectStandardObserveObject({
|
|
232
|
+
cache,
|
|
233
|
+
type: Todo,
|
|
234
|
+
primaryKey: TODO_1_ID
|
|
235
|
+
});
|
|
236
|
+
const todo1 = todo1Payload?.object;
|
|
237
|
+
!todo1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
238
|
+
|
|
239
|
+
// Clear the initial calls
|
|
240
|
+
empSubFn.next.mockClear();
|
|
241
|
+
officeSubFn.next.mockClear();
|
|
242
|
+
todoSubFn.next.mockClear();
|
|
243
|
+
|
|
244
|
+
// Invalidate only the Todo type
|
|
245
|
+
await cache.invalidateObjectType(Todo, undefined);
|
|
246
|
+
|
|
247
|
+
// Allow time for any potential updates
|
|
248
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
249
|
+
|
|
250
|
+
// Todo should be updated
|
|
251
|
+
expect(todoSubFn.next).toHaveBeenCalled();
|
|
252
|
+
|
|
253
|
+
// Employee and Office objects should NOT receive any updates
|
|
254
|
+
expect(empSubFn.next).not.toHaveBeenCalled();
|
|
255
|
+
expect(officeSubFn.next).not.toHaveBeenCalled();
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
describe("List Query Isolation", () => {
|
|
259
|
+
it("invalidating Employee type should only affect Employee lists", async () => {
|
|
260
|
+
// Pre-seed the cache with lists - need to fetch the objects first to get proper instances
|
|
261
|
+
const emp1 = await client(Employee).fetchOne(EMPLOYEE_1_ID);
|
|
262
|
+
const emp2 = await client(Employee).fetchOne(EMPLOYEE_2_ID);
|
|
263
|
+
const office1 = await client(Office).fetchOne(OFFICE_1_ID);
|
|
264
|
+
const office2 = await client(Office).fetchOne(OFFICE_2_ID);
|
|
265
|
+
updateList(cache, {
|
|
266
|
+
type: Employee,
|
|
267
|
+
where: {},
|
|
268
|
+
orderBy: {}
|
|
269
|
+
}, [emp1, emp2]);
|
|
270
|
+
updateList(cache, {
|
|
271
|
+
type: Office,
|
|
272
|
+
where: {},
|
|
273
|
+
orderBy: {}
|
|
274
|
+
}, [office1, office2]);
|
|
275
|
+
|
|
276
|
+
// Set up list observations
|
|
277
|
+
const empListSubFn = mockListSubCallback();
|
|
278
|
+
defer(cache.lists.observe({
|
|
279
|
+
type: Employee,
|
|
280
|
+
where: {},
|
|
281
|
+
orderBy: {},
|
|
282
|
+
mode: "offline"
|
|
283
|
+
}, empListSubFn));
|
|
284
|
+
const officeListSubFn = mockListSubCallback();
|
|
285
|
+
defer(cache.lists.observe({
|
|
286
|
+
type: Office,
|
|
287
|
+
where: {},
|
|
288
|
+
orderBy: {},
|
|
289
|
+
mode: "offline"
|
|
290
|
+
}, officeListSubFn));
|
|
291
|
+
|
|
292
|
+
// Wait for the initial calls and clear them
|
|
293
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
294
|
+
empListSubFn.next.mockClear();
|
|
295
|
+
officeListSubFn.next.mockClear();
|
|
296
|
+
|
|
297
|
+
// Invalidate only the Employee type
|
|
298
|
+
await cache.invalidateObjectType(Employee, undefined);
|
|
299
|
+
|
|
300
|
+
// Allow time for any potential updates
|
|
301
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
302
|
+
|
|
303
|
+
// Employee list should be updated
|
|
304
|
+
expect(empListSubFn.next).toHaveBeenCalled();
|
|
305
|
+
|
|
306
|
+
// Office list should NOT be invalidated
|
|
307
|
+
expect(officeListSubFn.next).not.toHaveBeenCalled();
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
describe("Link Query Isolation", () => {
|
|
311
|
+
it("basic source object filtering works for direct invalidation", async () => {
|
|
312
|
+
// Get an Office object that has Employee occupants
|
|
313
|
+
const {
|
|
314
|
+
payload: office1Payload,
|
|
315
|
+
subFn: officeSubFn
|
|
316
|
+
} = await expectStandardObserveObject({
|
|
317
|
+
cache,
|
|
318
|
+
type: Office,
|
|
319
|
+
primaryKey: OFFICE_1_ID
|
|
320
|
+
});
|
|
321
|
+
const office1 = office1Payload?.object;
|
|
322
|
+
!office1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
323
|
+
|
|
324
|
+
// Get an Employee object
|
|
325
|
+
const {
|
|
326
|
+
payload: emp1Payload,
|
|
327
|
+
subFn: empSubFn
|
|
328
|
+
} = await expectStandardObserveObject({
|
|
329
|
+
cache,
|
|
330
|
+
type: Employee,
|
|
331
|
+
primaryKey: EMPLOYEE_1_ID
|
|
332
|
+
});
|
|
333
|
+
const emp1 = emp1Payload?.object;
|
|
334
|
+
!emp1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
335
|
+
|
|
336
|
+
// Set up observation of Employee -> Office link
|
|
337
|
+
const {
|
|
338
|
+
linkSubFn: officeLinkSubFn
|
|
339
|
+
} = await expectStandardObserveLink({
|
|
340
|
+
store: cache,
|
|
341
|
+
srcObject: emp1,
|
|
342
|
+
srcLinkName: "officeLink",
|
|
343
|
+
targetType: Office,
|
|
344
|
+
expected: [expect.objectContaining({
|
|
345
|
+
$primaryKey: OFFICE_1_ID
|
|
346
|
+
})]
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Clear initial calls
|
|
350
|
+
officeSubFn.next.mockClear();
|
|
351
|
+
empSubFn.next.mockClear();
|
|
352
|
+
officeLinkSubFn.next.mockClear();
|
|
353
|
+
|
|
354
|
+
// Invalidate the Employee type
|
|
355
|
+
await cache.invalidateObjectType(Employee, undefined);
|
|
356
|
+
|
|
357
|
+
// Allow time for any potential updates
|
|
358
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
359
|
+
|
|
360
|
+
// Employee object should be invalidated
|
|
361
|
+
expect(empSubFn.next).toHaveBeenCalled();
|
|
362
|
+
|
|
363
|
+
// Employee -> Office link (with Employee source) should be invalidated
|
|
364
|
+
// because its source is an Employee object
|
|
365
|
+
expect(officeLinkSubFn.next).toHaveBeenCalled();
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
describe("Complex Multi-Type Scenario", () => {
|
|
369
|
+
it("should correctly isolate invalidation across multiple related objects", async () => {
|
|
370
|
+
// Set up observations for all three object types
|
|
371
|
+
const {
|
|
372
|
+
payload: emp1Payload,
|
|
373
|
+
subFn: empSubFn
|
|
374
|
+
} = await expectStandardObserveObject({
|
|
375
|
+
cache,
|
|
376
|
+
type: Employee,
|
|
377
|
+
primaryKey: EMPLOYEE_1_ID
|
|
378
|
+
});
|
|
379
|
+
const emp1 = emp1Payload?.object;
|
|
380
|
+
!emp1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
381
|
+
const {
|
|
382
|
+
payload: office1Payload,
|
|
383
|
+
subFn: officeSubFn
|
|
384
|
+
} = await expectStandardObserveObject({
|
|
385
|
+
cache,
|
|
386
|
+
type: Office,
|
|
387
|
+
primaryKey: OFFICE_1_ID
|
|
388
|
+
});
|
|
389
|
+
const office1 = office1Payload?.object;
|
|
390
|
+
!office1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
391
|
+
const {
|
|
392
|
+
payload: todo1Payload,
|
|
393
|
+
subFn: todoSubFn
|
|
394
|
+
} = await expectStandardObserveObject({
|
|
395
|
+
cache,
|
|
396
|
+
type: Todo,
|
|
397
|
+
primaryKey: TODO_1_ID
|
|
398
|
+
});
|
|
399
|
+
const todo1 = todo1Payload?.object;
|
|
400
|
+
!todo1 ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
401
|
+
|
|
402
|
+
// Set up list observations
|
|
403
|
+
const empListSubFn = mockListSubCallback();
|
|
404
|
+
defer(cache.lists.observe({
|
|
405
|
+
type: Employee,
|
|
406
|
+
where: {},
|
|
407
|
+
orderBy: {},
|
|
408
|
+
mode: "offline"
|
|
409
|
+
}, empListSubFn));
|
|
410
|
+
const officeListSubFn = mockListSubCallback();
|
|
411
|
+
defer(cache.lists.observe({
|
|
412
|
+
type: Office,
|
|
413
|
+
where: {},
|
|
414
|
+
orderBy: {},
|
|
415
|
+
mode: "offline"
|
|
416
|
+
}, officeListSubFn));
|
|
417
|
+
const todoListSubFn = mockListSubCallback();
|
|
418
|
+
defer(cache.lists.observe({
|
|
419
|
+
type: Todo,
|
|
420
|
+
where: {},
|
|
421
|
+
orderBy: {},
|
|
422
|
+
mode: "offline"
|
|
423
|
+
}, todoListSubFn));
|
|
424
|
+
|
|
425
|
+
// Set up link observations
|
|
426
|
+
const {
|
|
427
|
+
linkSubFn: employeeOfficeLinkSubFn
|
|
428
|
+
} = await expectStandardObserveLink({
|
|
429
|
+
store: cache,
|
|
430
|
+
srcObject: emp1,
|
|
431
|
+
srcLinkName: "officeLink",
|
|
432
|
+
targetType: Office,
|
|
433
|
+
expected: [expect.objectContaining({
|
|
434
|
+
$primaryKey: OFFICE_1_ID
|
|
435
|
+
})]
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// Setup another link observation for the test
|
|
439
|
+
const {
|
|
440
|
+
linkSubFn: officeOccupantsLinkSubFn
|
|
441
|
+
} = await expectStandardObserveLink({
|
|
442
|
+
store: cache,
|
|
443
|
+
srcObject: office1,
|
|
444
|
+
srcLinkName: "occupants",
|
|
445
|
+
targetType: Employee,
|
|
446
|
+
expected: [expect.objectContaining({
|
|
447
|
+
$primaryKey: EMPLOYEE_1_ID
|
|
448
|
+
})]
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Clear all the initial calls
|
|
452
|
+
empSubFn.next.mockClear();
|
|
453
|
+
officeSubFn.next.mockClear();
|
|
454
|
+
todoSubFn.next.mockClear();
|
|
455
|
+
empListSubFn.next.mockClear();
|
|
456
|
+
officeListSubFn.next.mockClear();
|
|
457
|
+
todoListSubFn.next.mockClear();
|
|
458
|
+
employeeOfficeLinkSubFn.next.mockClear();
|
|
459
|
+
officeOccupantsLinkSubFn.next.mockClear();
|
|
460
|
+
|
|
461
|
+
// Invalidate only the Todo type
|
|
462
|
+
await cache.invalidateObjectType(Todo, undefined);
|
|
463
|
+
|
|
464
|
+
// Allow time for any potential updates
|
|
465
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
466
|
+
|
|
467
|
+
// Todo object and list should be invalidated
|
|
468
|
+
expect(todoSubFn.next).toHaveBeenCalled();
|
|
469
|
+
expect(todoListSubFn.next).toHaveBeenCalled();
|
|
470
|
+
|
|
471
|
+
// All Employee and Office related items should NOT be invalidated
|
|
472
|
+
expect(empSubFn.next).not.toHaveBeenCalled();
|
|
473
|
+
expect(officeSubFn.next).not.toHaveBeenCalled();
|
|
474
|
+
expect(empListSubFn.next).not.toHaveBeenCalled();
|
|
475
|
+
expect(officeListSubFn.next).not.toHaveBeenCalled();
|
|
476
|
+
expect(employeeOfficeLinkSubFn.next).not.toHaveBeenCalled();
|
|
477
|
+
expect(officeOccupantsLinkSubFn.next).not.toHaveBeenCalled();
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
});
|
|
481
|
+
//# sourceMappingURL=Store.invalidation.test.js.map
|