@osdk/client 2.5.0-beta.4 → 2.5.0-beta.6
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 +33 -4
- package/build/browser/MinimalClientContext.js.map +1 -1
- package/build/browser/actions/applyAction.js +4 -0
- package/build/browser/actions/applyAction.js.map +1 -1
- package/build/browser/createClient.js +2 -1
- package/build/browser/createClient.js.map +1 -1
- package/build/browser/createMinimalClient.js +2 -1
- package/build/browser/createMinimalClient.js.map +1 -1
- package/build/browser/index.js +2 -0
- package/build/browser/index.js.map +1 -1
- package/build/browser/object/Cache.test.js +1 -1
- package/build/browser/object/Cache.test.js.map +1 -1
- package/build/browser/object/aggregate.js +2 -0
- package/build/browser/object/aggregate.js.map +1 -1
- package/build/browser/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js +1 -0
- package/build/browser/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js.map +1 -1
- package/build/browser/object/convertWireToOsdkObjects/createOsdkInterface.js +6 -0
- package/build/browser/object/convertWireToOsdkObjects/createOsdkInterface.js.map +1 -1
- package/build/browser/object/convertWireToOsdkObjects/getDollarLink.js +20 -1
- package/build/browser/object/convertWireToOsdkObjects/getDollarLink.js.map +1 -1
- package/build/browser/object/convertWireToOsdkObjects.test.js +2 -0
- package/build/browser/object/convertWireToOsdkObjects.test.js.map +1 -1
- package/build/browser/object/fetchPage.js +5 -2
- package/build/browser/object/fetchPage.js.map +1 -1
- package/build/browser/observable/internal/AbstractHelper.js +4 -3
- package/build/browser/observable/internal/AbstractHelper.js.map +1 -1
- package/build/browser/observable/internal/BatchContext.js +2 -0
- package/build/browser/observable/internal/BatchContext.js.map +1 -0
- package/build/browser/observable/internal/CacheKeys.js +61 -36
- package/build/browser/observable/internal/CacheKeys.js.map +1 -1
- package/build/browser/observable/internal/Changes.js.map +1 -1
- package/build/browser/observable/internal/KnownCacheKey.js.map +1 -1
- package/build/browser/observable/internal/Layer.js +0 -8
- package/build/browser/observable/internal/Layer.js.map +1 -1
- package/build/browser/observable/internal/Layers.js +151 -0
- package/build/browser/observable/internal/Layers.js.map +1 -0
- package/build/browser/observable/internal/ObservableClientImpl.js +3 -1
- package/build/browser/observable/internal/ObservableClientImpl.js.map +1 -1
- package/build/browser/observable/internal/OrderByCanonicalizer.js +1 -37
- package/build/browser/observable/internal/OrderByCanonicalizer.js.map +1 -1
- package/build/browser/observable/internal/Queries.js +40 -0
- package/build/browser/observable/internal/Queries.js.map +1 -0
- package/build/browser/observable/internal/Query.js +1 -0
- package/build/browser/observable/internal/Query.js.map +1 -1
- package/build/browser/observable/internal/Store.js +37 -226
- package/build/browser/observable/internal/Store.js.map +1 -1
- package/build/browser/observable/internal/Store.test.js +12 -10
- package/build/browser/observable/internal/Store.test.js.map +1 -1
- package/build/browser/observable/internal/SubjectPayload.js +2 -0
- package/build/browser/observable/internal/SubjectPayload.js.map +1 -0
- package/build/browser/observable/internal/Subjects.js +55 -0
- package/build/browser/observable/internal/Subjects.js.map +1 -0
- package/build/browser/observable/internal/WeakRefTrie.js +61 -0
- package/build/browser/observable/internal/WeakRefTrie.js.map +1 -0
- package/build/browser/observable/internal/{ActionApplication.js → actions/ActionApplication.js} +2 -2
- package/build/browser/observable/internal/actions/ActionApplication.js.map +1 -0
- package/build/browser/observable/internal/{OptimisticJob.js → actions/OptimisticJob.js} +3 -3
- package/build/browser/observable/internal/actions/OptimisticJob.js.map +1 -0
- package/build/browser/observable/internal/base-list/BaseCollectionQuery.js.map +1 -0
- package/build/browser/observable/internal/base-list/BaseListQuery.js +411 -0
- package/build/browser/observable/internal/base-list/BaseListQuery.js.map +1 -0
- package/build/{esm/observable/internal → browser/observable/internal/base-list}/createCollectionConnectable.js +2 -2
- package/build/browser/observable/internal/base-list/createCollectionConnectable.js.map +1 -0
- package/build/{esm/observable/internal → browser/observable/internal/base-list}/createCollectionConnectable.test.js +24 -26
- package/build/browser/observable/internal/base-list/createCollectionConnectable.test.js.map +1 -0
- package/build/browser/observable/internal/base-list/removeDuplicates.js.map +1 -0
- package/build/browser/observable/internal/createInitEntry.js +25 -0
- package/build/browser/observable/internal/createInitEntry.js.map +1 -0
- package/build/browser/observable/internal/links/LinksHelper.js +5 -5
- package/build/browser/observable/internal/links/LinksHelper.js.map +1 -1
- package/build/browser/observable/internal/links/SpecificLinkCacheKey.js.map +1 -1
- package/build/browser/observable/internal/links/SpecificLinkQuery.js +1 -1
- package/build/browser/observable/internal/links/SpecificLinkQuery.js.map +1 -1
- package/build/browser/observable/internal/{ListCacheKey.js.map → list/ListCacheKey.js.map} +1 -1
- package/build/browser/observable/internal/{ListQuery.js → list/ListQuery.js} +12 -421
- package/build/browser/observable/internal/list/ListQuery.js.map +1 -0
- package/build/browser/observable/internal/list/ListQueryOptions.js +2 -0
- package/build/browser/observable/internal/list/ListQueryOptions.js.map +1 -0
- package/build/browser/observable/internal/list/ListsHelper.js +6 -6
- package/build/browser/observable/internal/list/ListsHelper.js.map +1 -1
- package/build/browser/observable/internal/object/ObjectCacheKey.js +2 -0
- package/build/browser/observable/internal/object/ObjectCacheKey.js.map +1 -0
- package/build/browser/observable/internal/{ObjectQuery.js → object/ObjectQuery.js} +4 -20
- package/build/browser/observable/internal/object/ObjectQuery.js.map +1 -0
- package/build/browser/observable/internal/object/ObjectsHelper.js +17 -3
- package/build/browser/observable/internal/object/ObjectsHelper.js.map +1 -1
- package/build/browser/observable/internal/sorting/SortingStrategy.js.map +1 -1
- package/build/browser/observable/internal/testUtils/invalidateList.js +2 -2
- package/build/browser/observable/internal/testUtils/invalidateList.js.map +1 -1
- package/build/browser/observable/internal/testUtils.js +2 -3
- package/build/browser/observable/internal/testUtils.js.map +1 -1
- package/build/browser/ontology/loadActionMetadata.js +3 -1
- package/build/browser/ontology/loadActionMetadata.js.map +1 -1
- package/build/browser/ontology/loadFullObjectMetadata.js +2 -1
- package/build/browser/ontology/loadFullObjectMetadata.js.map +1 -1
- package/build/browser/ontology/loadInterfaceMetadata.js +2 -1
- package/build/browser/ontology/loadInterfaceMetadata.js.map +1 -1
- package/build/browser/queries/applyQuery.js +3 -3
- package/build/browser/queries/applyQuery.js.map +1 -1
- package/build/browser/util/UserAgent.js +2 -2
- package/build/browser/util/extractObjectOrInterfaceType.js +9 -1
- package/build/browser/util/extractObjectOrInterfaceType.js.map +1 -1
- package/build/browser/util/extractObjectOrInterfaceType.test.js +2 -2
- package/build/browser/util/extractObjectOrInterfaceType.test.js.map +1 -1
- package/build/cjs/{chunk-6CBVXAAV.cjs → chunk-4GWXMQZE.cjs} +107 -75
- package/build/cjs/chunk-4GWXMQZE.cjs.map +1 -0
- package/build/cjs/{chunk-QR7IBJPZ.cjs → chunk-5KDG5ZET.cjs} +18 -6
- package/build/cjs/chunk-5KDG5ZET.cjs.map +1 -0
- package/build/cjs/{createClient-BJo8T7Js.d.cts → createClient-mOlFts15.d.cts} +1 -0
- package/build/cjs/index.cjs +7 -7
- package/build/cjs/index.d.cts +1 -1
- package/build/cjs/public/internal.cjs +8 -8
- package/build/cjs/public/unstable-do-not-use.cjs +831 -775
- package/build/cjs/public/unstable-do-not-use.cjs.map +1 -1
- package/build/cjs/public/unstable-do-not-use.d.cts +1 -1
- package/build/esm/MinimalClientContext.js.map +1 -1
- package/build/esm/actions/applyAction.js +4 -0
- package/build/esm/actions/applyAction.js.map +1 -1
- package/build/esm/createClient.js +2 -1
- package/build/esm/createClient.js.map +1 -1
- package/build/esm/createMinimalClient.js +2 -1
- package/build/esm/createMinimalClient.js.map +1 -1
- package/build/esm/index.js +2 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/object/Cache.test.js +1 -1
- package/build/esm/object/Cache.test.js.map +1 -1
- package/build/esm/object/aggregate.js +2 -0
- package/build/esm/object/aggregate.js.map +1 -1
- package/build/esm/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js +1 -0
- package/build/esm/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js.map +1 -1
- package/build/esm/object/convertWireToOsdkObjects/createOsdkInterface.js +6 -0
- package/build/esm/object/convertWireToOsdkObjects/createOsdkInterface.js.map +1 -1
- package/build/esm/object/convertWireToOsdkObjects/getDollarLink.js +20 -1
- package/build/esm/object/convertWireToOsdkObjects/getDollarLink.js.map +1 -1
- package/build/esm/object/convertWireToOsdkObjects.test.js +2 -0
- package/build/esm/object/convertWireToOsdkObjects.test.js.map +1 -1
- package/build/esm/object/fetchPage.js +5 -2
- package/build/esm/object/fetchPage.js.map +1 -1
- package/build/esm/observable/internal/AbstractHelper.js +4 -3
- package/build/esm/observable/internal/AbstractHelper.js.map +1 -1
- package/build/esm/observable/internal/BatchContext.js +2 -0
- package/build/esm/observable/internal/BatchContext.js.map +1 -0
- package/build/esm/observable/internal/CacheKeys.js +61 -36
- package/build/esm/observable/internal/CacheKeys.js.map +1 -1
- package/build/esm/observable/internal/Changes.js.map +1 -1
- package/build/esm/observable/internal/KnownCacheKey.js.map +1 -1
- package/build/esm/observable/internal/Layer.js +0 -8
- package/build/esm/observable/internal/Layer.js.map +1 -1
- package/build/esm/observable/internal/Layers.js +151 -0
- package/build/esm/observable/internal/Layers.js.map +1 -0
- package/build/esm/observable/internal/ObservableClientImpl.js +3 -1
- package/build/esm/observable/internal/ObservableClientImpl.js.map +1 -1
- package/build/esm/observable/internal/OrderByCanonicalizer.js +1 -37
- package/build/esm/observable/internal/OrderByCanonicalizer.js.map +1 -1
- package/build/esm/observable/internal/Queries.js +40 -0
- package/build/esm/observable/internal/Queries.js.map +1 -0
- package/build/esm/observable/internal/Query.js +1 -0
- package/build/esm/observable/internal/Query.js.map +1 -1
- package/build/esm/observable/internal/Store.js +37 -226
- package/build/esm/observable/internal/Store.js.map +1 -1
- package/build/esm/observable/internal/Store.test.js +12 -10
- package/build/esm/observable/internal/Store.test.js.map +1 -1
- package/build/esm/observable/internal/SubjectPayload.js +2 -0
- package/build/esm/observable/internal/SubjectPayload.js.map +1 -0
- package/build/esm/observable/internal/Subjects.js +55 -0
- package/build/esm/observable/internal/Subjects.js.map +1 -0
- package/build/esm/observable/internal/WeakRefTrie.js +61 -0
- package/build/esm/observable/internal/WeakRefTrie.js.map +1 -0
- package/build/esm/observable/internal/{ActionApplication.js → actions/ActionApplication.js} +2 -2
- package/build/esm/observable/internal/actions/ActionApplication.js.map +1 -0
- package/build/esm/observable/internal/{OptimisticJob.js → actions/OptimisticJob.js} +3 -3
- package/build/esm/observable/internal/actions/OptimisticJob.js.map +1 -0
- package/build/esm/observable/internal/base-list/BaseCollectionQuery.js.map +1 -0
- package/build/esm/observable/internal/base-list/BaseListQuery.js +411 -0
- package/build/esm/observable/internal/base-list/BaseListQuery.js.map +1 -0
- package/build/{browser/observable/internal → esm/observable/internal/base-list}/createCollectionConnectable.js +2 -2
- package/build/esm/observable/internal/base-list/createCollectionConnectable.js.map +1 -0
- package/build/{browser/observable/internal → esm/observable/internal/base-list}/createCollectionConnectable.test.js +24 -26
- package/build/esm/observable/internal/base-list/createCollectionConnectable.test.js.map +1 -0
- package/build/esm/observable/internal/base-list/removeDuplicates.js.map +1 -0
- package/build/esm/observable/internal/createInitEntry.js +25 -0
- package/build/esm/observable/internal/createInitEntry.js.map +1 -0
- package/build/esm/observable/internal/links/LinksHelper.js +5 -5
- package/build/esm/observable/internal/links/LinksHelper.js.map +1 -1
- package/build/esm/observable/internal/links/SpecificLinkCacheKey.js.map +1 -1
- package/build/esm/observable/internal/links/SpecificLinkQuery.js +1 -1
- package/build/esm/observable/internal/links/SpecificLinkQuery.js.map +1 -1
- package/build/esm/observable/internal/{ListCacheKey.js.map → list/ListCacheKey.js.map} +1 -1
- package/build/esm/observable/internal/{ListQuery.js → list/ListQuery.js} +12 -421
- package/build/esm/observable/internal/list/ListQuery.js.map +1 -0
- package/build/esm/observable/internal/list/ListQueryOptions.js +2 -0
- package/build/esm/observable/internal/list/ListQueryOptions.js.map +1 -0
- package/build/esm/observable/internal/list/ListsHelper.js +6 -6
- package/build/esm/observable/internal/list/ListsHelper.js.map +1 -1
- package/build/esm/observable/internal/object/ObjectCacheKey.js +2 -0
- package/build/esm/observable/internal/object/ObjectCacheKey.js.map +1 -0
- package/build/esm/observable/internal/{ObjectQuery.js → object/ObjectQuery.js} +4 -20
- package/build/esm/observable/internal/object/ObjectQuery.js.map +1 -0
- package/build/esm/observable/internal/object/ObjectsHelper.js +17 -3
- package/build/esm/observable/internal/object/ObjectsHelper.js.map +1 -1
- package/build/esm/observable/internal/sorting/SortingStrategy.js.map +1 -1
- package/build/esm/observable/internal/testUtils/invalidateList.js +2 -2
- package/build/esm/observable/internal/testUtils/invalidateList.js.map +1 -1
- package/build/esm/observable/internal/testUtils.js +2 -3
- package/build/esm/observable/internal/testUtils.js.map +1 -1
- package/build/esm/ontology/loadActionMetadata.js +3 -1
- package/build/esm/ontology/loadActionMetadata.js.map +1 -1
- package/build/esm/ontology/loadFullObjectMetadata.js +2 -1
- package/build/esm/ontology/loadFullObjectMetadata.js.map +1 -1
- package/build/esm/ontology/loadInterfaceMetadata.js +2 -1
- package/build/esm/ontology/loadInterfaceMetadata.js.map +1 -1
- package/build/esm/queries/applyQuery.js +3 -3
- package/build/esm/queries/applyQuery.js.map +1 -1
- package/build/esm/util/UserAgent.js +2 -2
- package/build/esm/util/extractObjectOrInterfaceType.js +9 -1
- package/build/esm/util/extractObjectOrInterfaceType.js.map +1 -1
- package/build/esm/util/extractObjectOrInterfaceType.test.js +2 -2
- package/build/esm/util/extractObjectOrInterfaceType.test.js.map +1 -1
- package/build/types/MinimalClientContext.d.ts +1 -0
- package/build/types/MinimalClientContext.d.ts.map +1 -1
- package/build/types/actions/applyAction.d.ts.map +1 -1
- package/build/types/createClient.d.ts +1 -0
- package/build/types/createClient.d.ts.map +1 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/observable/internal/AbstractHelper.d.ts +3 -1
- package/build/types/observable/internal/AbstractHelper.d.ts.map +1 -1
- package/build/types/observable/internal/BatchContext.d.ts +11 -0
- package/build/types/observable/internal/BatchContext.d.ts.map +1 -0
- package/build/types/observable/internal/CacheKeys.d.ts +9 -9
- package/build/types/observable/internal/CacheKeys.d.ts.map +1 -1
- package/build/types/observable/internal/Changes.d.ts +2 -2
- package/build/types/observable/internal/Changes.d.ts.map +1 -1
- package/build/types/observable/internal/KnownCacheKey.d.ts +2 -2
- package/build/types/observable/internal/KnownCacheKey.d.ts.map +1 -1
- package/build/types/observable/internal/Layer.d.ts +1 -2
- package/build/types/observable/internal/Layer.d.ts.map +1 -1
- package/build/types/observable/internal/Layers.d.ts +26 -0
- package/build/types/observable/internal/Layers.d.ts.map +1 -0
- package/build/types/observable/internal/OrderByCanonicalizer.d.ts +0 -7
- package/build/types/observable/internal/OrderByCanonicalizer.d.ts.map +1 -1
- package/build/types/observable/internal/Queries.d.ts +9 -0
- package/build/types/observable/internal/Queries.d.ts.map +1 -0
- package/build/types/observable/internal/Query.d.ts +5 -1
- package/build/types/observable/internal/Query.d.ts.map +1 -1
- package/build/types/observable/internal/Store.d.ts +19 -34
- package/build/types/observable/internal/Store.d.ts.map +1 -1
- package/build/types/observable/internal/Store.test.d.ts.map +1 -1
- package/build/types/observable/internal/SubjectPayload.d.ts +5 -0
- package/build/types/observable/internal/SubjectPayload.d.ts.map +1 -0
- package/build/types/observable/internal/Subjects.d.ts +16 -0
- package/build/types/observable/internal/Subjects.d.ts.map +1 -0
- package/build/types/observable/internal/WeakRefTrie.d.ts +13 -0
- package/build/types/observable/internal/WeakRefTrie.d.ts.map +1 -0
- package/build/types/observable/internal/{ActionApplication.d.ts → actions/ActionApplication.d.ts} +2 -2
- package/build/types/observable/internal/{ActionApplication.d.ts.map → actions/ActionApplication.d.ts.map} +1 -1
- package/build/types/observable/internal/{OptimisticJob.d.ts → actions/OptimisticJob.d.ts} +4 -4
- package/build/types/observable/internal/actions/OptimisticJob.d.ts.map +1 -0
- package/build/types/observable/internal/{BaseCollectionQuery.d.ts → base-list/BaseCollectionQuery.d.ts} +4 -4
- package/build/types/observable/internal/base-list/BaseCollectionQuery.d.ts.map +1 -0
- package/build/types/observable/internal/{ListQuery.d.ts → base-list/BaseListQuery.d.ts} +9 -91
- package/build/types/observable/internal/base-list/BaseListQuery.d.ts.map +1 -0
- package/build/types/observable/internal/{createCollectionConnectable.d.ts → base-list/createCollectionConnectable.d.ts} +5 -4
- package/build/types/observable/internal/base-list/createCollectionConnectable.d.ts.map +1 -0
- package/build/types/observable/internal/base-list/createCollectionConnectable.test.d.ts.map +1 -0
- package/build/types/observable/internal/{removeDuplicates.d.ts → base-list/removeDuplicates.d.ts} +2 -2
- package/build/types/observable/internal/base-list/removeDuplicates.d.ts.map +1 -0
- package/build/types/observable/internal/createInitEntry.d.ts +3 -0
- package/build/types/observable/internal/createInitEntry.d.ts.map +1 -0
- package/build/types/observable/internal/links/LinksHelper.d.ts +3 -1
- package/build/types/observable/internal/links/LinksHelper.d.ts.map +1 -1
- package/build/types/observable/internal/links/SpecificLinkCacheKey.d.ts +1 -1
- package/build/types/observable/internal/links/SpecificLinkCacheKey.d.ts.map +1 -1
- package/build/types/observable/internal/links/SpecificLinkQuery.d.ts +4 -2
- package/build/types/observable/internal/links/SpecificLinkQuery.d.ts.map +1 -1
- package/build/types/observable/internal/{ListCacheKey.d.ts → list/ListCacheKey.d.ts} +4 -4
- package/build/types/observable/internal/list/ListCacheKey.d.ts.map +1 -0
- package/build/types/observable/internal/list/ListQuery.d.ts +75 -0
- package/build/types/observable/internal/list/ListQuery.d.ts.map +1 -0
- package/build/types/observable/internal/list/ListQueryOptions.d.ts +4 -0
- package/build/types/observable/internal/list/ListQueryOptions.d.ts.map +1 -0
- package/build/types/observable/internal/list/ListsHelper.d.ts +4 -2
- package/build/types/observable/internal/list/ListsHelper.d.ts.map +1 -1
- package/build/types/observable/internal/object/ObjectCacheKey.d.ts +5 -0
- package/build/types/observable/internal/object/ObjectCacheKey.d.ts.map +1 -0
- package/build/types/observable/internal/{ObjectQuery.d.ts → object/ObjectQuery.d.ts} +10 -10
- package/build/types/observable/internal/object/ObjectQuery.d.ts.map +1 -0
- package/build/types/observable/internal/object/ObjectsHelper.d.ts +1 -1
- package/build/types/observable/internal/object/ObjectsHelper.d.ts.map +1 -1
- package/build/types/observable/internal/sorting/SortingStrategy.d.ts +2 -2
- package/build/types/observable/internal/sorting/SortingStrategy.d.ts.map +1 -1
- package/build/types/observable/internal/testUtils.d.ts +1 -1
- package/build/types/observable/internal/testUtils.d.ts.map +1 -1
- package/package.json +23 -23
- package/build/browser/observable/internal/ActionApplication.js.map +0 -1
- package/build/browser/observable/internal/BaseCollectionQuery.js.map +0 -1
- package/build/browser/observable/internal/ListQuery.js.map +0 -1
- package/build/browser/observable/internal/ObjectQuery.js.map +0 -1
- package/build/browser/observable/internal/OptimisticJob.js.map +0 -1
- package/build/browser/observable/internal/createCollectionConnectable.js.map +0 -1
- package/build/browser/observable/internal/createCollectionConnectable.test.js.map +0 -1
- package/build/browser/observable/internal/removeDuplicates.js.map +0 -1
- package/build/cjs/chunk-6CBVXAAV.cjs.map +0 -1
- package/build/cjs/chunk-QR7IBJPZ.cjs.map +0 -1
- package/build/esm/observable/internal/ActionApplication.js.map +0 -1
- package/build/esm/observable/internal/BaseCollectionQuery.js.map +0 -1
- package/build/esm/observable/internal/ListQuery.js.map +0 -1
- package/build/esm/observable/internal/ObjectQuery.js.map +0 -1
- package/build/esm/observable/internal/OptimisticJob.js.map +0 -1
- package/build/esm/observable/internal/createCollectionConnectable.js.map +0 -1
- package/build/esm/observable/internal/createCollectionConnectable.test.js.map +0 -1
- package/build/esm/observable/internal/removeDuplicates.js.map +0 -1
- package/build/types/observable/internal/BaseCollectionQuery.d.ts.map +0 -1
- package/build/types/observable/internal/ListCacheKey.d.ts.map +0 -1
- package/build/types/observable/internal/ListQuery.d.ts.map +0 -1
- package/build/types/observable/internal/ObjectQuery.d.ts.map +0 -1
- package/build/types/observable/internal/OptimisticJob.d.ts.map +0 -1
- package/build/types/observable/internal/createCollectionConnectable.d.ts.map +0 -1
- package/build/types/observable/internal/createCollectionConnectable.test.d.ts.map +0 -1
- package/build/types/observable/internal/removeDuplicates.d.ts.map +0 -1
- /package/build/browser/observable/internal/{BaseCollectionQuery.js → base-list/BaseCollectionQuery.js} +0 -0
- /package/build/browser/observable/internal/{removeDuplicates.js → base-list/removeDuplicates.js} +0 -0
- /package/build/browser/observable/internal/{ListCacheKey.js → list/ListCacheKey.js} +0 -0
- /package/build/esm/observable/internal/{BaseCollectionQuery.js → base-list/BaseCollectionQuery.js} +0 -0
- /package/build/esm/observable/internal/{removeDuplicates.js → base-list/removeDuplicates.js} +0 -0
- /package/build/esm/observable/internal/{ListCacheKey.js → list/ListCacheKey.js} +0 -0
- /package/build/types/observable/internal/{createCollectionConnectable.test.d.ts → base-list/createCollectionConnectable.test.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Queries.js","names":["Queries","map","Map","peek","cacheKey","get","createQuery","query","set","keys","delete","dispose"],"sources":["Queries.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 { KnownCacheKey } from \"./KnownCacheKey.js\";\nimport type { Query } from \"./Query.js\";\n\nexport class Queries {\n // we can use a regular Map here because the refCounting will\n // handle cleanup.\n map: Map<\n KnownCacheKey,\n Query<any, any, any>\n > = new Map();\n\n peek<K extends KnownCacheKey>(\n cacheKey: K,\n ): K[\"__cacheKey\"][\"query\"] | undefined {\n return this.map.get(cacheKey) as K[\"__cacheKey\"][\"query\"] | undefined;\n }\n\n get<K extends KnownCacheKey>(\n cacheKey: K,\n createQuery: () => K[\"__cacheKey\"][\"query\"],\n ): K[\"__cacheKey\"][\"query\"] {\n let query = this.peek(cacheKey);\n if (!query) {\n query = createQuery();\n this.map.set(cacheKey, query);\n }\n return query;\n }\n\n keys(): IterableIterator<KnownCacheKey> {\n return this.map.keys();\n }\n\n delete<K extends KnownCacheKey>(cacheKey: K): void {\n this.map.get(cacheKey)?.dispose();\n this.map.delete(cacheKey);\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA,OAAO,MAAMA,OAAO,CAAC;EACnB;EACA;EACAC,GAAG,GAGC,IAAIC,GAAG,CAAC,CAAC;EAEbC,IAAIA,CACFC,QAAW,EAC2B;IACtC,OAAO,IAAI,CAACH,GAAG,CAACI,GAAG,CAACD,QAAQ,CAAC;EAC/B;EAEAC,GAAGA,CACDD,QAAW,EACXE,WAA2C,EACjB;IAC1B,IAAIC,KAAK,GAAG,IAAI,CAACJ,IAAI,CAACC,QAAQ,CAAC;IAC/B,IAAI,CAACG,KAAK,EAAE;MACVA,KAAK,GAAGD,WAAW,CAAC,CAAC;MACrB,IAAI,CAACL,GAAG,CAACO,GAAG,CAACJ,QAAQ,EAAEG,KAAK,CAAC;IAC/B;IACA,OAAOA,KAAK;EACd;EAEAE,IAAIA,CAAA,EAAoC;IACtC,OAAO,IAAI,CAACR,GAAG,CAACQ,IAAI,CAAC,CAAC;EACxB;EAEAC,MAAMA,CAA0BN,QAAW,EAAQ;IACjD,IAAI,CAACH,GAAG,CAACI,GAAG,CAACD,QAAQ,CAAC,EAAEO,OAAO,CAAC,CAAC;IACjC,IAAI,CAACV,GAAG,CAACS,MAAM,CAACN,QAAQ,CAAC;EAC3B;AACF","ignoreList":[]}
|
|
@@ -27,6 +27,7 @@ export class Query {
|
|
|
27
27
|
this.options = opts;
|
|
28
28
|
this.cacheKey = cacheKey;
|
|
29
29
|
this.store = store;
|
|
30
|
+
this.cacheKeys = store.cacheKeys;
|
|
30
31
|
this.#subject = observable;
|
|
31
32
|
this.logger = logger ?? (process.env.NODE_ENV === "production" ? store.client[additionalContext].logger : store.client[additionalContext].logger?.child({}, {
|
|
32
33
|
msgPrefix: process.env.NODE_ENV !== "production" ? `Query<${cacheKey.type}, ${cacheKey.otherKeys.map(x => JSON.stringify(x)).join(", ")}>` : "Query"
|
|
@@ -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 {\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":[]}
|
|
1
|
+
{"version":3,"file":"Query.js","names":["additionalContext","Query","retainCount","connectable","subscription","subject","constructor","store","observable","opts","cacheKey","logger","options","cacheKeys","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 { BatchContext } from \"./BatchContext.js\";\nimport type { CacheKeys } from \"./CacheKeys.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 { Store } from \"./Store.js\";\nimport type { SubjectPayload } from \"./SubjectPayload.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 protected readonly cacheKeys: CacheKeys<KnownCacheKey>;\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.cacheKeys = store.cacheKeys;\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":[]}
|
|
@@ -14,47 +14,19 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { BehaviorSubject } from "rxjs";
|
|
18
17
|
import invariant from "tiny-invariant";
|
|
19
18
|
import { additionalContext } from "../../Client.js";
|
|
20
19
|
import { DEBUG_REFCOUNTS } from "../DebugFlags.js";
|
|
21
|
-
import { ActionApplication } from "./ActionApplication.js";
|
|
20
|
+
import { ActionApplication } from "./actions/ActionApplication.js";
|
|
22
21
|
import { CacheKeys } from "./CacheKeys.js";
|
|
23
22
|
import { createChangedObjects, DEBUG_ONLY__changesToString } from "./Changes.js";
|
|
24
|
-
import {
|
|
23
|
+
import { Layers } from "./Layers.js";
|
|
25
24
|
import { LinksHelper } from "./links/LinksHelper.js";
|
|
26
25
|
import { ListsHelper } from "./list/ListsHelper.js";
|
|
27
26
|
import { ObjectsHelper } from "./object/ObjectsHelper.js";
|
|
28
27
|
import { OrderByCanonicalizer } from "./OrderByCanonicalizer.js";
|
|
29
|
-
import {
|
|
30
|
-
import { tombstone } from "./tombstone.js";
|
|
28
|
+
import { Queries } from "./Queries.js";
|
|
31
29
|
import { WhereClauseCanonicalizer } from "./WhereClauseCanonicalizer.js";
|
|
32
|
-
|
|
33
|
-
/*
|
|
34
|
-
Work still to do:
|
|
35
|
-
- [x] testing for optimistic writes
|
|
36
|
-
- [x] automatic invalidation of actions
|
|
37
|
-
- [x] automatic optimistic list updates
|
|
38
|
-
- [x] useOsdkObjects
|
|
39
|
-
- [x] imply offline for objects passed directly
|
|
40
|
-
- [x] websocket subscriptions
|
|
41
|
-
- [ ] links
|
|
42
|
-
- [x] add pagination
|
|
43
|
-
- [ ] sub-selection support
|
|
44
|
-
- [ ] interfaces
|
|
45
|
-
- [ ] setup defaults
|
|
46
|
-
- [ ] reduce updates in react
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
function createInitEntry(cacheKey) {
|
|
50
|
-
return {
|
|
51
|
-
cacheKey,
|
|
52
|
-
status: "init",
|
|
53
|
-
value: undefined,
|
|
54
|
-
lastUpdated: 0
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
30
|
/*
|
|
59
31
|
Notes:
|
|
60
32
|
- Subjects are one per type per store (by cache key)
|
|
@@ -70,57 +42,29 @@ function createInitEntry(cacheKey) {
|
|
|
70
42
|
export class Store {
|
|
71
43
|
whereCanonicalizer = new WhereClauseCanonicalizer();
|
|
72
44
|
orderByCanonicalizer = new OrderByCanonicalizer();
|
|
73
|
-
#truthLayer = new Layer(undefined, undefined);
|
|
74
|
-
#topLayer;
|
|
75
45
|
|
|
76
46
|
/** @internal */
|
|
77
47
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// we are currently only using this for debug logging and should just remove it in the future if that
|
|
86
|
-
// continues to be true
|
|
87
|
-
#finalizationRegistry;
|
|
48
|
+
queries = new Queries();
|
|
49
|
+
layers = new Layers({
|
|
50
|
+
logger: this.logger,
|
|
51
|
+
onRevalidate: this.#maybeRevalidateQueries.bind(this)
|
|
52
|
+
});
|
|
53
|
+
subjects = this.layers.subjects;
|
|
88
54
|
|
|
89
55
|
// these are hopefully temporary
|
|
90
56
|
|
|
91
57
|
constructor(client) {
|
|
92
|
-
this.client = client;
|
|
93
58
|
this.logger = client[additionalContext].logger?.child({}, {
|
|
94
59
|
msgPrefix: "Store"
|
|
95
60
|
});
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
98
|
-
|
|
99
|
-
this.#topLayer = this.#truthLayer;
|
|
100
|
-
this.#cacheKeys = new CacheKeys(this.whereCanonicalizer, this.orderByCanonicalizer, k => {
|
|
101
|
-
if (DEBUG_REFCOUNTS) {
|
|
102
|
-
const cacheKeyType = k.type;
|
|
103
|
-
const otherKeys = k.otherKeys;
|
|
104
|
-
// eslint-disable-next-line no-console
|
|
105
|
-
console.log(`CacheKeys.onCreate(${cacheKeyType}, ${JSON.stringify(otherKeys)})`);
|
|
106
|
-
this.#finalizationRegistry.register(k, () => {
|
|
107
|
-
// eslint-disable-next-line no-console
|
|
108
|
-
console.log(`CacheKey Finalization(${cacheKeyType}, ${JSON.stringify(otherKeys)})`);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
this.#refCounts.register(k);
|
|
112
|
-
});
|
|
113
|
-
setInterval(() => {
|
|
114
|
-
this.#refCounts.gc();
|
|
115
|
-
}, 1000);
|
|
116
|
-
this.#finalizationRegistry = new FinalizationRegistry(cleanupCallback => {
|
|
117
|
-
try {
|
|
118
|
-
cleanupCallback();
|
|
119
|
-
} catch (e) {
|
|
120
|
-
// eslint-disable-next-line no-console
|
|
121
|
-
console.error("Caught an error while running a finalization callback", e);
|
|
122
|
-
}
|
|
61
|
+
this.client = client;
|
|
62
|
+
this.cacheKeys = new CacheKeys({
|
|
63
|
+
onDestroy: this.#cleanupCacheKey
|
|
123
64
|
});
|
|
65
|
+
this.lists = new ListsHelper(this, this.cacheKeys, this.whereCanonicalizer, this.orderByCanonicalizer);
|
|
66
|
+
this.objects = new ObjectsHelper(this, this.cacheKeys);
|
|
67
|
+
this.links = new LinksHelper(this, this.cacheKeys, this.whereCanonicalizer, this.orderByCanonicalizer);
|
|
124
68
|
}
|
|
125
69
|
|
|
126
70
|
/**
|
|
@@ -128,7 +72,7 @@ export class Store {
|
|
|
128
72
|
* @param key
|
|
129
73
|
*/
|
|
130
74
|
#cleanupCacheKey = key => {
|
|
131
|
-
const subject = this.
|
|
75
|
+
const subject = this.subjects.peek(key);
|
|
132
76
|
if (DEBUG_REFCOUNTS) {
|
|
133
77
|
// eslint-disable-next-line no-console
|
|
134
78
|
console.log(`CacheKey cleaning up (${JSON.stringify({
|
|
@@ -136,16 +80,11 @@ export class Store {
|
|
|
136
80
|
observed: subject?.observed
|
|
137
81
|
})})`, JSON.stringify([key.type, ...key.otherKeys], null, 2));
|
|
138
82
|
}
|
|
139
|
-
this.#cacheKeys.remove(key);
|
|
140
83
|
if (process.env.NODE_ENV !== "production") {
|
|
141
84
|
!subject ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
|
|
142
85
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
this.#cacheKeyToSubject.delete(key);
|
|
146
|
-
}
|
|
147
|
-
this.#queries.get(key)?.dispose();
|
|
148
|
-
this.#queries.delete(key);
|
|
86
|
+
this.subjects.delete(key);
|
|
87
|
+
this.queries.delete(key);
|
|
149
88
|
};
|
|
150
89
|
applyAction = async (action, args, opts) => {
|
|
151
90
|
return await new ActionApplication(this).applyAction(action, args, opts);
|
|
@@ -157,134 +96,18 @@ export class Store {
|
|
|
157
96
|
});
|
|
158
97
|
return result;
|
|
159
98
|
};
|
|
160
|
-
removeLayer(layerId) {
|
|
161
|
-
!(layerId != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "undefined is the reserved layerId for the truth layer") : invariant(false) : void 0;
|
|
162
|
-
// 1. collect all cache keys for a given layerId
|
|
163
|
-
let currentLayer = this.#topLayer;
|
|
164
|
-
const cacheKeys = new Map();
|
|
165
|
-
while (currentLayer != null && currentLayer.parentLayer != null) {
|
|
166
|
-
if (currentLayer.layerId === layerId) {
|
|
167
|
-
for (const [k, v] of currentLayer.entries()) {
|
|
168
|
-
if (cacheKeys.has(k)) continue;
|
|
169
|
-
cacheKeys.set(k, v);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
currentLayer = currentLayer.parentLayer;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// 2. remove the layers from the chain
|
|
176
|
-
this.#topLayer = this.#topLayer.removeLayer(layerId);
|
|
177
|
-
|
|
178
|
-
// 3. check each cache key to see if it is different in the new chain
|
|
179
|
-
for (const [k, oldEntry] of cacheKeys) {
|
|
180
|
-
const currentEntry = this.#topLayer.get(k);
|
|
181
|
-
|
|
182
|
-
// 4. if different, update the subject
|
|
183
|
-
if (oldEntry !== currentEntry) {
|
|
184
|
-
currentEntry ?? createInitEntry(k); // We are going to be pretty lazy here and just re-emit the value.
|
|
185
|
-
// In the future it may benefit us to deep equal check her but I think
|
|
186
|
-
// the subjects are effectively doing this anyway.
|
|
187
|
-
this.peekSubject(k)?.next({
|
|
188
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
|
189
|
-
...(currentEntry ?? createInitEntry(k)),
|
|
190
|
-
isOptimistic: currentEntry?.value !== this.#truthLayer.get(k)?.value
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
getCacheKey(type, ...args) {
|
|
196
|
-
return this.#refCounts.register(this.#cacheKeys.get(type, ...args));
|
|
197
|
-
}
|
|
198
|
-
peekSubject = cacheKey => {
|
|
199
|
-
return this.#cacheKeyToSubject.get(cacheKey);
|
|
200
|
-
};
|
|
201
|
-
getSubject = cacheKey => {
|
|
202
|
-
let subject = this.#cacheKeyToSubject.get(cacheKey);
|
|
203
|
-
if (!subject) {
|
|
204
|
-
const initialValue = this.#topLayer.get(cacheKey) ?? createInitEntry(cacheKey);
|
|
205
|
-
subject = new BehaviorSubject({
|
|
206
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
|
207
|
-
...initialValue,
|
|
208
|
-
isOptimistic: initialValue.value !== this.#truthLayer.get(cacheKey)?.value
|
|
209
|
-
});
|
|
210
|
-
this.#cacheKeyToSubject.set(cacheKey, subject);
|
|
211
|
-
}
|
|
212
|
-
return subject;
|
|
213
|
-
};
|
|
214
|
-
canonicalizeWhereClause(where) {
|
|
215
|
-
return this.whereCanonicalizer.canonicalize(where);
|
|
216
|
-
}
|
|
217
|
-
peekQuery(cacheKey) {
|
|
218
|
-
return this.#queries.get(cacheKey);
|
|
219
|
-
}
|
|
220
|
-
getQuery(cacheKey, createQuery) {
|
|
221
|
-
let query = this.peekQuery(cacheKey);
|
|
222
|
-
if (!query) {
|
|
223
|
-
query = createQuery();
|
|
224
|
-
this.#queries.set(cacheKey, query);
|
|
225
|
-
}
|
|
226
|
-
return query;
|
|
227
|
-
}
|
|
228
99
|
getValue(cacheKey) {
|
|
229
|
-
return this
|
|
100
|
+
return this.layers.top.get(cacheKey);
|
|
230
101
|
}
|
|
231
|
-
batch
|
|
102
|
+
batch({
|
|
232
103
|
optimisticId,
|
|
233
104
|
changes = createChangedObjects()
|
|
234
|
-
}, batchFn)
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (needsLayer) {
|
|
241
|
-
this.#topLayer = this.#topLayer.addLayer(optimisticId);
|
|
242
|
-
needsLayer = false;
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
optimisticWrite: !!optimisticId,
|
|
246
|
-
write: (cacheKey, value, status) => {
|
|
247
|
-
const oldTopValue = this.#topLayer.get(cacheKey);
|
|
248
|
-
if (optimisticId) batchContext.createLayerIfNeeded();
|
|
249
|
-
const writeLayer = optimisticId ? this.#topLayer : this.#truthLayer;
|
|
250
|
-
const newValue = new Entry(cacheKey, value, Date.now(), status);
|
|
251
|
-
writeLayer.set(cacheKey, newValue);
|
|
252
|
-
const newTopValue = this.#topLayer.get(cacheKey);
|
|
253
|
-
if (oldTopValue !== newTopValue) {
|
|
254
|
-
this.getSubject(cacheKey)?.next({
|
|
255
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
|
256
|
-
...newValue,
|
|
257
|
-
isOptimistic: newTopValue?.value !== this.#truthLayer.get(cacheKey)?.value
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
return newValue;
|
|
261
|
-
},
|
|
262
|
-
delete: (cacheKey, status) => {
|
|
263
|
-
return batchContext.write(cacheKey, tombstone, status);
|
|
264
|
-
},
|
|
265
|
-
read: cacheKey => {
|
|
266
|
-
return optimisticId ? this.#topLayer.get(cacheKey) : this.#truthLayer.get(cacheKey);
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
const retVal = batchFn(batchContext);
|
|
270
|
-
this.maybeRevalidateQueries(changes, optimisticId).catch(e => {
|
|
271
|
-
// we don't want batch() to return a promise,
|
|
272
|
-
// so we settle for logging an error here instead of
|
|
273
|
-
// dropping it on the floor.
|
|
274
|
-
if (this.logger) {
|
|
275
|
-
this.logger.error("Unhandled error in batch", e);
|
|
276
|
-
} else {
|
|
277
|
-
// eslint-disable-next-line no-console
|
|
278
|
-
console.error("Unhandled error in batch", e);
|
|
279
|
-
throw e;
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
return {
|
|
283
|
-
batchResult: batchContext,
|
|
284
|
-
retVal: retVal,
|
|
285
|
-
changes: batchContext.changes
|
|
286
|
-
};
|
|
287
|
-
};
|
|
105
|
+
}, batchFn) {
|
|
106
|
+
return this.layers.batch({
|
|
107
|
+
optimisticId,
|
|
108
|
+
changes
|
|
109
|
+
}, batchFn);
|
|
110
|
+
}
|
|
288
111
|
invalidateObject(apiName, pk) {
|
|
289
112
|
if (typeof apiName !== "string") {
|
|
290
113
|
apiName = apiName.apiName;
|
|
@@ -294,37 +117,31 @@ export class Store {
|
|
|
294
117
|
pk
|
|
295
118
|
}).revalidate(/* force */true);
|
|
296
119
|
}
|
|
297
|
-
async maybeRevalidateQueries(changes, optimisticId) {
|
|
120
|
+
async #maybeRevalidateQueries(changes, optimisticId) {
|
|
121
|
+
const logger = process.env.NODE_ENV !== "production" ? this.logger?.child({
|
|
122
|
+
methodName: "maybeRevalidateQueries"
|
|
123
|
+
}) : undefined;
|
|
298
124
|
if (changes.isEmpty()) {
|
|
299
125
|
if (process.env.NODE_ENV !== "production") {
|
|
300
|
-
|
|
301
|
-
this.logger?.child({
|
|
302
|
-
methodName: "maybeRevalidateQueries"
|
|
303
|
-
}).debug("No changes, aborting");
|
|
126
|
+
logger?.debug("No changes, aborting");
|
|
304
127
|
}
|
|
305
128
|
return;
|
|
306
129
|
}
|
|
307
130
|
if (process.env.NODE_ENV !== "production") {
|
|
308
|
-
|
|
309
|
-
this.logger?.child({
|
|
310
|
-
methodName: "maybeRevalidateQueries"
|
|
311
|
-
}).debug(DEBUG_ONLY__changesToString(changes), {
|
|
131
|
+
logger?.debug(DEBUG_ONLY__changesToString(changes), {
|
|
312
132
|
optimisticId
|
|
313
133
|
});
|
|
314
134
|
}
|
|
315
135
|
try {
|
|
316
136
|
const promises = [];
|
|
317
|
-
for (const cacheKey of this
|
|
318
|
-
const promise = this.
|
|
137
|
+
for (const cacheKey of this.queries.keys()) {
|
|
138
|
+
const promise = this.queries.peek(cacheKey)?.maybeUpdateAndRevalidate?.(changes, optimisticId);
|
|
319
139
|
if (promise) promises.push(promise);
|
|
320
140
|
}
|
|
321
141
|
await Promise.all(promises);
|
|
322
142
|
} finally {
|
|
323
143
|
if (process.env.NODE_ENV !== "production") {
|
|
324
|
-
|
|
325
|
-
this.logger?.child({
|
|
326
|
-
methodName: "maybeRevalidateQueries"
|
|
327
|
-
}).debug("in finally", DEBUG_ONLY__changesToString(changes));
|
|
144
|
+
logger?.debug("in finally", DEBUG_ONLY__changesToString(changes));
|
|
328
145
|
}
|
|
329
146
|
}
|
|
330
147
|
}
|
|
@@ -350,11 +167,11 @@ export class Store {
|
|
|
350
167
|
}).info(changes ? DEBUG_ONLY__changesToString(changes) : void 0);
|
|
351
168
|
}
|
|
352
169
|
const promises = [];
|
|
353
|
-
for (const cacheKey of this
|
|
170
|
+
for (const cacheKey of this.layers.truth.keys()) {
|
|
354
171
|
if (changes && changes.modified.has(cacheKey)) {
|
|
355
172
|
continue;
|
|
356
173
|
}
|
|
357
|
-
const query = this.
|
|
174
|
+
const query = this.queries.peek(cacheKey);
|
|
358
175
|
if (!query) continue;
|
|
359
176
|
promises.push(query.invalidateObjectType(apiName, changes));
|
|
360
177
|
}
|
|
@@ -362,11 +179,5 @@ export class Store {
|
|
|
362
179
|
// we use allSettled here because we don't care if it succeeds or fails, just that they all complete.
|
|
363
180
|
return Promise.allSettled(promises).then(() => void 0);
|
|
364
181
|
}
|
|
365
|
-
retain(cacheKey) {
|
|
366
|
-
this.#refCounts.retain(cacheKey);
|
|
367
|
-
}
|
|
368
|
-
release(cacheKey) {
|
|
369
|
-
this.#refCounts.release(cacheKey);
|
|
370
|
-
}
|
|
371
182
|
}
|
|
372
183
|
//# sourceMappingURL=Store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Store.js","names":["BehaviorSubject","invariant","additionalContext","DEBUG_REFCOUNTS","ActionApplication","CacheKeys","createChangedObjects","DEBUG_ONLY__changesToString","Entry","Layer","LinksHelper","ListsHelper","ObjectsHelper","OrderByCanonicalizer","RefCounts","tombstone","WhereClauseCanonicalizer","createInitEntry","cacheKey","status","value","undefined","lastUpdated","Store","whereCanonicalizer","orderByCanonicalizer","truthLayer","topLayer","queries","Map","cacheKeyToSubject","WeakMap","cacheKeys","refCounts","k","cleanupCacheKey","finalizationRegistry","constructor","client","logger","child","msgPrefix","lists","objects","links","cacheKeyType","type","otherKeys","console","log","JSON","stringify","register","setInterval","gc","FinalizationRegistry","cleanupCallback","e","error","key","subject","peekSubject","closed","observed","remove","process","env","NODE_ENV","complete","delete","get","dispose","applyAction","action","args","opts","validateAction","result","$validateOnly","$returnEdits","removeLayer","layerId","currentLayer","parentLayer","v","entries","has","set","oldEntry","currentEntry","next","isOptimistic","getCacheKey","getSubject","initialValue","canonicalizeWhereClause","where","canonicalize","peekQuery","getQuery","createQuery","query","getValue","batch","optimisticId","changes","batchFn","needsLayer","batchContext","createLayerIfNeeded","addLayer","optimisticWrite","write","oldTopValue","writeLayer","newValue","Date","now","newTopValue","read","retVal","maybeRevalidateQueries","catch","batchResult","invalidateObject","apiName","pk","revalidate","isEmpty","methodName","debug","promises","keys","promise","maybeUpdateAndRevalidate","push","Promise","all","invalidateObjectType","info","modified","allSettled","then","retain","release"],"sources":["Store.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 ActionEditResponse,\n ActionValidationResponse,\n InterfaceDefinition,\n Logger,\n ObjectTypeDefinition,\n PrimaryKeyType,\n WhereClause,\n} from \"@osdk/api\";\nimport { BehaviorSubject } from \"rxjs\";\nimport invariant from \"tiny-invariant\";\nimport type { ActionSignatureFromDef } from \"../../actions/applyAction.js\";\nimport { additionalContext, type Client } from \"../../Client.js\";\nimport { DEBUG_REFCOUNTS } from \"../DebugFlags.js\";\nimport type { OptimisticBuilder } from \"../OptimisticBuilder.js\";\nimport { ActionApplication } from \"./ActionApplication.js\";\nimport { CacheKeys } from \"./CacheKeys.js\";\nimport type { Canonical } from \"./Canonical.js\";\nimport {\n type Changes,\n createChangedObjects,\n DEBUG_ONLY__changesToString,\n} from \"./Changes.js\";\nimport type { KnownCacheKey } from \"./KnownCacheKey.js\";\nimport { Entry, Layer } from \"./Layer.js\";\nimport { LinksHelper } from \"./links/LinksHelper.js\";\nimport { ListsHelper } from \"./list/ListsHelper.js\";\nimport { ObjectsHelper } from \"./object/ObjectsHelper.js\";\nimport { type OptimisticId } from \"./OptimisticId.js\";\nimport { OrderByCanonicalizer } from \"./OrderByCanonicalizer.js\";\nimport type { Query } from \"./Query.js\";\nimport { RefCounts } from \"./RefCounts.js\";\nimport type { SimpleWhereClause } from \"./SimpleWhereClause.js\";\nimport { tombstone } from \"./tombstone.js\";\nimport { WhereClauseCanonicalizer } from \"./WhereClauseCanonicalizer.js\";\n\n/*\n Work still to do:\n - [x] testing for optimistic writes\n - [x] automatic invalidation of actions\n - [x] automatic optimistic list updates\n - [x] useOsdkObjects\n - [x] imply offline for objects passed directly\n - [x] websocket subscriptions\n - [ ] links\n - [x] add pagination\n - [ ] sub-selection support\n - [ ] interfaces\n - [ ] setup defaults\n - [ ] reduce updates in react\n*/\n\nexport interface SubjectPayload<KEY extends KnownCacheKey> extends Entry<KEY> {\n isOptimistic: boolean;\n}\n\nexport interface BatchContext {\n changes: Changes;\n createLayerIfNeeded: () => void;\n optimisticWrite: boolean;\n\n write: <K extends KnownCacheKey>(\n k: K,\n v: Entry<K>[\"value\"],\n status: Entry<K>[\"status\"],\n ) => Entry<K>;\n\n read: <K extends KnownCacheKey>(\n k: K,\n ) => Entry<K> | undefined;\n\n delete: <K extends KnownCacheKey>(\n k: K,\n status: Entry<K>[\"status\"],\n ) => Entry<K>;\n}\n\ninterface UpdateOptions {\n optimisticId?: OptimisticId;\n}\n\nexport namespace Store {\n export interface ApplyActionOptions {\n optimisticUpdate?: (ctx: OptimisticBuilder) => void;\n }\n}\n\nfunction createInitEntry(cacheKey: KnownCacheKey): Entry<any> {\n return {\n cacheKey,\n status: \"init\",\n value: undefined,\n lastUpdated: 0,\n };\n}\n\n/*\n Notes:\n - Subjects are one per type per store (by cache key)\n - Data is one per layer per cache key\n*/\n\n/**\n * Central data store with layered cache architecture.\n * - Truth layer: server state | Optimistic layers: pending changes\n * - Reference counting prevents memory leaks\n * - Batch operations ensure consistency\n */\nexport class Store {\n whereCanonicalizer: WhereClauseCanonicalizer = new WhereClauseCanonicalizer();\n orderByCanonicalizer: OrderByCanonicalizer = new OrderByCanonicalizer();\n #truthLayer: Layer = new Layer(undefined, undefined);\n #topLayer: Layer;\n client: Client;\n\n /** @internal */\n logger?: Logger;\n\n // we can use a regular Map here because the refCounting will\n // handle cleanup.\n #queries: Map<\n KnownCacheKey,\n Query<any, any, any>\n > = new Map();\n\n #cacheKeyToSubject = new WeakMap<\n KnownCacheKey,\n BehaviorSubject<SubjectPayload<any>>\n >();\n #cacheKeys: CacheKeys;\n\n #refCounts = new RefCounts<KnownCacheKey>(\n DEBUG_REFCOUNTS ? 15_000 : 60_000,\n (k) => this.#cleanupCacheKey(k),\n );\n\n // we are currently only using this for debug logging and should just remove it in the future if that\n // continues to be true\n #finalizationRegistry: FinalizationRegistry<() => void>;\n\n // these are hopefully temporary\n lists: ListsHelper;\n objects: ObjectsHelper;\n links: LinksHelper;\n\n constructor(client: Client) {\n this.client = client;\n this.logger = client[additionalContext].logger?.child({}, {\n msgPrefix: \"Store\",\n });\n\n this.lists = new ListsHelper(\n this,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n this.objects = new ObjectsHelper(this);\n this.links = new LinksHelper(\n this,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n\n this.#topLayer = this.#truthLayer;\n this.#cacheKeys = new CacheKeys(\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n (k) => {\n if (DEBUG_REFCOUNTS) {\n const cacheKeyType = k.type;\n const otherKeys = k.otherKeys;\n // eslint-disable-next-line no-console\n console.log(\n `CacheKeys.onCreate(${cacheKeyType}, ${JSON.stringify(otherKeys)})`,\n );\n\n this.#finalizationRegistry.register(k, () => {\n // eslint-disable-next-line no-console\n console.log(\n `CacheKey Finalization(${cacheKeyType}, ${\n JSON.stringify(otherKeys)\n })`,\n );\n });\n }\n\n this.#refCounts.register(k);\n },\n );\n\n setInterval(() => {\n this.#refCounts.gc();\n }, 1000);\n\n this.#finalizationRegistry = new FinalizationRegistry<() => void>(\n (cleanupCallback) => {\n try {\n cleanupCallback();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(\n \"Caught an error while running a finalization callback\",\n e,\n );\n }\n },\n );\n }\n\n /**\n * Called after a key is no longer retained and the timeout has elapsed\n * @param key\n */\n #cleanupCacheKey = (key: KnownCacheKey) => {\n const subject = this.peekSubject(key);\n\n if (DEBUG_REFCOUNTS) {\n // eslint-disable-next-line no-console\n console.log(\n `CacheKey cleaning up (${\n JSON.stringify({\n closed: subject?.closed,\n observed: subject?.observed,\n })\n })`,\n JSON.stringify([key.type, ...key.otherKeys], null, 2),\n );\n }\n this.#cacheKeys.remove(key);\n if (process.env.NODE_ENV !== \"production\") {\n invariant(subject);\n }\n\n if (subject) {\n subject.complete();\n this.#cacheKeyToSubject.delete(key);\n }\n\n this.#queries.get(key)?.dispose();\n this.#queries.delete(key);\n };\n\n applyAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args:\n | Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]\n | Array<Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]>,\n opts?: Store.ApplyActionOptions,\n ) => Promise<ActionEditResponse> = async (action, args, opts) => {\n return await new ActionApplication(this).applyAction(action, args, opts);\n };\n\n validateAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ) => Promise<ActionValidationResponse> = async (action, args) => {\n const result = await this.client(action).applyAction(args as any, {\n $validateOnly: true,\n $returnEdits: false,\n });\n return result as ActionValidationResponse;\n };\n\n removeLayer(layerId: OptimisticId): void {\n invariant(\n layerId != null,\n \"undefined is the reserved layerId for the truth layer\",\n );\n // 1. collect all cache keys for a given layerId\n let currentLayer: Layer | undefined = this.#topLayer;\n const cacheKeys = new Map<KnownCacheKey, Entry<any>>();\n while (currentLayer != null && currentLayer.parentLayer != null) {\n if (currentLayer.layerId === layerId) {\n for (const [k, v] of currentLayer.entries()) {\n if (cacheKeys.has(k)) continue;\n cacheKeys.set(k, v);\n }\n }\n\n currentLayer = currentLayer.parentLayer;\n }\n\n // 2. remove the layers from the chain\n this.#topLayer = this.#topLayer.removeLayer(layerId);\n\n // 3. check each cache key to see if it is different in the new chain\n for (const [k, oldEntry] of cacheKeys) {\n const currentEntry = this.#topLayer.get(k);\n\n // 4. if different, update the subject\n if (oldEntry !== currentEntry) {\n const x = currentEntry ?? createInitEntry(k);\n // We are going to be pretty lazy here and just re-emit the value.\n // In the future it may benefit us to deep equal check her but I think\n // the subjects are effectively doing this anyway.\n this.peekSubject(k)?.next(\n {\n // eslint-disable-next-line @typescript-eslint/no-misused-spread\n ...(currentEntry ?? createInitEntry(k)),\n isOptimistic:\n currentEntry?.value !== this.#truthLayer.get(k)?.value,\n },\n );\n }\n }\n }\n\n getCacheKey<K extends KnownCacheKey>(\n type: K[\"type\"],\n ...args: K[\"__cacheKey\"][\"args\"]\n ): K {\n return this.#refCounts.register(this.#cacheKeys.get(type, ...args));\n }\n\n peekSubject = <KEY extends KnownCacheKey>(\n cacheKey: KEY,\n ):\n | BehaviorSubject<SubjectPayload<KEY>>\n | undefined =>\n {\n return this.#cacheKeyToSubject.get(cacheKey);\n };\n\n getSubject = <KEY extends KnownCacheKey>(\n cacheKey: KEY,\n ): BehaviorSubject<SubjectPayload<KEY>> => {\n let subject = this.#cacheKeyToSubject.get(cacheKey);\n if (!subject) {\n const initialValue: Entry<KEY> = this.#topLayer.get(cacheKey)\n ?? createInitEntry(cacheKey);\n\n subject = new BehaviorSubject({\n // eslint-disable-next-line @typescript-eslint/no-misused-spread\n ...initialValue,\n isOptimistic:\n initialValue.value !== this.#truthLayer.get(cacheKey)?.value,\n });\n this.#cacheKeyToSubject.set(cacheKey, subject);\n }\n\n return subject;\n };\n\n public canonicalizeWhereClause<\n T extends ObjectTypeDefinition | InterfaceDefinition,\n >(\n where: WhereClause<T>,\n ): Canonical<SimpleWhereClause> {\n return this.whereCanonicalizer.canonicalize(where);\n }\n\n peekQuery<K extends KnownCacheKey>(\n cacheKey: K,\n ): K[\"__cacheKey\"][\"query\"] | undefined {\n return this.#queries.get(cacheKey) as K[\"__cacheKey\"][\"query\"] | undefined;\n }\n\n getQuery<K extends KnownCacheKey>(\n cacheKey: K,\n createQuery: () => K[\"__cacheKey\"][\"query\"],\n ): K[\"__cacheKey\"][\"query\"] {\n let query = this.peekQuery(cacheKey);\n if (!query) {\n query = createQuery();\n this.#queries.set(cacheKey, query);\n }\n return query;\n }\n\n public getValue<K extends KnownCacheKey>(\n cacheKey: K,\n ): Entry<K> | undefined {\n return this.#topLayer.get(cacheKey);\n }\n\n batch = <X>(\n { optimisticId, changes = createChangedObjects() }: {\n optimisticId?: OptimisticId;\n changes?: Changes;\n },\n batchFn: (batchContext: BatchContext) => X,\n ): {\n batchResult: BatchContext;\n retVal: X;\n changes: Changes;\n } => {\n invariant(\n optimisticId === undefined || !!optimisticId,\n \"optimistic must be undefined or not falsy\",\n );\n\n let needsLayer = optimisticId !== undefined;\n const batchContext: BatchContext = {\n changes,\n createLayerIfNeeded: () => {\n if (needsLayer) {\n this.#topLayer = this.#topLayer.addLayer(optimisticId);\n needsLayer = false;\n }\n },\n optimisticWrite: !!optimisticId,\n write: (cacheKey, value, status) => {\n const oldTopValue = this.#topLayer.get(cacheKey);\n\n if (optimisticId) batchContext.createLayerIfNeeded();\n\n const writeLayer = optimisticId\n ? this.#topLayer\n : this.#truthLayer;\n const newValue = new Entry(\n cacheKey,\n value,\n Date.now(),\n status,\n );\n\n writeLayer.set(cacheKey, newValue);\n\n const newTopValue = this.#topLayer.get(cacheKey);\n\n if (oldTopValue !== newTopValue) {\n this.getSubject(cacheKey)?.next({\n // eslint-disable-next-line @typescript-eslint/no-misused-spread\n ...newValue,\n isOptimistic:\n newTopValue?.value !== this.#truthLayer.get(cacheKey)?.value,\n });\n }\n\n return newValue;\n },\n delete: (cacheKey, status) => {\n return batchContext.write(cacheKey, tombstone, status);\n },\n read: (cacheKey) => {\n return optimisticId\n ? this.#topLayer.get(cacheKey)\n : this.#truthLayer.get(cacheKey);\n },\n };\n\n const retVal = batchFn(batchContext);\n this.maybeRevalidateQueries(changes, optimisticId).catch(e => {\n // we don't want batch() to return a promise,\n // so we settle for logging an error here instead of\n // dropping it on the floor.\n if (this.logger) {\n this.logger.error(\"Unhandled error in batch\", e);\n } else {\n // eslint-disable-next-line no-console\n console.error(\"Unhandled error in batch\", e);\n throw e;\n }\n });\n\n return {\n batchResult: batchContext,\n retVal: retVal,\n changes: batchContext.changes,\n };\n };\n\n public invalidateObject<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n pk: PrimaryKeyType<T>,\n ): Promise<unknown> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n\n return this.objects.getQuery({\n apiName,\n pk,\n }).revalidate(/* force */ true);\n }\n\n async maybeRevalidateQueries(\n changes: Changes,\n optimisticId?: OptimisticId | undefined,\n ): Promise<void> {\n if (changes.isEmpty()) {\n if (process.env.NODE_ENV !== \"production\") {\n // todo\n this.logger?.child({ methodName: \"maybeRevalidateQueries\" }).debug(\n \"No changes, aborting\",\n );\n }\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n // todo\n this.logger?.child({ methodName: \"maybeRevalidateQueries\" }).debug(\n DEBUG_ONLY__changesToString(changes),\n { optimisticId },\n );\n }\n\n try {\n const promises: Array<Promise<unknown>> = [];\n for (const cacheKey of this.#queries.keys()) {\n const promise = this.peekQuery(cacheKey)?.maybeUpdateAndRevalidate?.(\n changes,\n optimisticId,\n );\n if (promise) promises.push(promise);\n }\n await Promise.all(promises);\n } finally {\n if (process.env.NODE_ENV !== \"production\") {\n // todo\n this.logger?.child({ methodName: \"maybeRevalidateQueries\" }).debug(\n \"in finally\",\n DEBUG_ONLY__changesToString(changes),\n );\n }\n }\n }\n\n /**\n * Invalidates all cache entries for a specific object type.\n * This will revalidate:\n * 1. All objects of the specified type\n * 2. All lists of the specified type\n * 3. All links where the source object is of the specified type\n *\n * @param apiName - The API name of the object type to invalidate\n * @param changes - Optional changes object to track what has been modified\n * @returns Promise that resolves when all invalidations are complete\n */\n public invalidateObjectType<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n changes: Changes | undefined,\n ): Promise<void> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"invalidateObjectType\" }).info(\n changes ? DEBUG_ONLY__changesToString(changes) : void 0,\n );\n }\n\n const promises: Array<Promise<void>> = [];\n\n for (const cacheKey of this.#truthLayer.keys()) {\n if (changes && changes.modified.has(cacheKey)) {\n continue;\n }\n const query = this.peekQuery(cacheKey);\n if (!query) continue;\n\n promises.push(query.invalidateObjectType(apiName, changes));\n }\n\n // we use allSettled here because we don't care if it succeeds or fails, just that they all complete.\n return Promise.allSettled(promises).then(() => void 0);\n }\n\n retain(cacheKey: KnownCacheKey): void {\n this.#refCounts.retain(cacheKey);\n }\n\n release(cacheKey: KnownCacheKey): void {\n this.#refCounts.release(cacheKey);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Store.js","names":["invariant","additionalContext","DEBUG_REFCOUNTS","ActionApplication","CacheKeys","createChangedObjects","DEBUG_ONLY__changesToString","Layers","LinksHelper","ListsHelper","ObjectsHelper","OrderByCanonicalizer","Queries","WhereClauseCanonicalizer","Store","whereCanonicalizer","orderByCanonicalizer","queries","layers","logger","onRevalidate","maybeRevalidateQueries","bind","subjects","constructor","client","child","msgPrefix","cacheKeys","onDestroy","cleanupCacheKey","lists","objects","links","key","subject","peek","console","log","JSON","stringify","closed","observed","type","otherKeys","process","env","NODE_ENV","delete","applyAction","action","args","opts","validateAction","result","$validateOnly","$returnEdits","getValue","cacheKey","top","get","batch","optimisticId","changes","batchFn","invalidateObject","apiName","pk","getQuery","revalidate","#maybeRevalidateQueries","methodName","undefined","isEmpty","debug","promises","keys","promise","maybeUpdateAndRevalidate","push","Promise","all","invalidateObjectType","info","truth","modified","has","query","allSettled","then"],"sources":["Store.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 ActionEditResponse,\n ActionValidationResponse,\n Logger,\n ObjectTypeDefinition,\n PrimaryKeyType,\n} from \"@osdk/api\";\nimport invariant from \"tiny-invariant\";\nimport type { ActionSignatureFromDef } from \"../../actions/applyAction.js\";\nimport { additionalContext, type Client } from \"../../Client.js\";\nimport { DEBUG_REFCOUNTS } from \"../DebugFlags.js\";\nimport type { OptimisticBuilder } from \"../OptimisticBuilder.js\";\nimport { ActionApplication } from \"./actions/ActionApplication.js\";\nimport type { BatchContext } from \"./BatchContext.js\";\nimport { CacheKeys } from \"./CacheKeys.js\";\nimport {\n type Changes,\n createChangedObjects,\n DEBUG_ONLY__changesToString,\n} from \"./Changes.js\";\nimport type { KnownCacheKey } from \"./KnownCacheKey.js\";\nimport type { Entry } from \"./Layer.js\";\nimport { Layers } from \"./Layers.js\";\nimport { LinksHelper } from \"./links/LinksHelper.js\";\nimport { ListsHelper } from \"./list/ListsHelper.js\";\nimport { ObjectsHelper } from \"./object/ObjectsHelper.js\";\nimport { type OptimisticId } from \"./OptimisticId.js\";\nimport { OrderByCanonicalizer } from \"./OrderByCanonicalizer.js\";\nimport { Queries } from \"./Queries.js\";\nimport type { Subjects } from \"./Subjects.js\";\nimport { WhereClauseCanonicalizer } from \"./WhereClauseCanonicalizer.js\";\n\nexport namespace Store {\n export interface ApplyActionOptions {\n optimisticUpdate?: (ctx: OptimisticBuilder) => void;\n }\n}\n\n/*\n Notes:\n - Subjects are one per type per store (by cache key)\n - Data is one per layer per cache key\n*/\n\n/**\n * Central data store with layered cache architecture.\n * - Truth layer: server state | Optimistic layers: pending changes\n * - Reference counting prevents memory leaks\n * - Batch operations ensure consistency\n */\nexport class Store {\n readonly whereCanonicalizer: WhereClauseCanonicalizer =\n new WhereClauseCanonicalizer();\n readonly orderByCanonicalizer: OrderByCanonicalizer =\n new OrderByCanonicalizer();\n\n readonly client: Client;\n\n /** @internal */\n readonly logger?: Logger;\n\n readonly cacheKeys: CacheKeys<KnownCacheKey>;\n readonly queries: Queries = new Queries();\n\n readonly layers: Layers = new Layers({\n logger: this.logger,\n onRevalidate: this.#maybeRevalidateQueries.bind(this),\n });\n readonly subjects: Subjects = this.layers.subjects;\n\n // these are hopefully temporary\n readonly lists: ListsHelper;\n readonly objects: ObjectsHelper;\n readonly links: LinksHelper;\n\n constructor(client: Client) {\n this.logger = client[additionalContext].logger?.child({}, {\n msgPrefix: \"Store\",\n });\n this.client = client;\n\n this.cacheKeys = new CacheKeys<KnownCacheKey>({\n onDestroy: this.#cleanupCacheKey,\n });\n\n this.lists = new ListsHelper(\n this,\n this.cacheKeys,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n this.objects = new ObjectsHelper(this, this.cacheKeys);\n this.links = new LinksHelper(\n this,\n this.cacheKeys,\n this.whereCanonicalizer,\n this.orderByCanonicalizer,\n );\n }\n\n /**\n * Called after a key is no longer retained and the timeout has elapsed\n * @param key\n */\n #cleanupCacheKey = (key: KnownCacheKey) => {\n const subject = this.subjects.peek(key);\n\n if (DEBUG_REFCOUNTS) {\n // eslint-disable-next-line no-console\n console.log(\n `CacheKey cleaning up (${\n JSON.stringify({\n closed: subject?.closed,\n observed: subject?.observed,\n })\n })`,\n JSON.stringify([key.type, ...key.otherKeys], null, 2),\n );\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n invariant(subject);\n }\n\n this.subjects.delete(key);\n this.queries.delete(key);\n };\n\n applyAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args:\n | Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]\n | Array<Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]>,\n opts?: Store.ApplyActionOptions,\n ) => Promise<ActionEditResponse> = async (action, args, opts) => {\n return await new ActionApplication(this).applyAction(action, args, opts);\n };\n\n validateAction: <Q extends ActionDefinition<any>>(\n action: Q,\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ) => Promise<ActionValidationResponse> = async (action, args) => {\n const result = await this.client(action).applyAction(args as any, {\n $validateOnly: true,\n $returnEdits: false,\n });\n return result as ActionValidationResponse;\n };\n\n public getValue<K extends KnownCacheKey>(\n cacheKey: K,\n ): Entry<K> | undefined {\n return this.layers.top.get(cacheKey);\n }\n\n batch<X>(\n { optimisticId, changes = createChangedObjects() }: {\n optimisticId?: OptimisticId;\n changes?: Changes;\n },\n batchFn: (batchContext: BatchContext) => X,\n ): {\n batchResult: BatchContext;\n retVal: X;\n changes: Changes;\n } {\n return this.layers.batch({ optimisticId, changes }, batchFn);\n }\n\n public invalidateObject<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n pk: PrimaryKeyType<T>,\n ): Promise<unknown> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n\n return this.objects.getQuery({\n apiName,\n pk,\n }).revalidate(/* force */ true);\n }\n\n async #maybeRevalidateQueries(\n changes: Changes,\n optimisticId?: OptimisticId | undefined,\n ): Promise<void> {\n const logger = process.env.NODE_ENV !== \"production\"\n ? this.logger?.child({ methodName: \"maybeRevalidateQueries\" })\n : undefined;\n\n if (changes.isEmpty()) {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"No changes, aborting\");\n }\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(DEBUG_ONLY__changesToString(changes), { optimisticId });\n }\n\n try {\n const promises: Array<Promise<unknown>> = [];\n for (const cacheKey of this.queries.keys()) {\n const promise = this.queries.peek(cacheKey)?.maybeUpdateAndRevalidate?.(\n changes,\n optimisticId,\n );\n if (promise) promises.push(promise);\n }\n await Promise.all(promises);\n } finally {\n if (process.env.NODE_ENV !== \"production\") {\n logger?.debug(\"in finally\", DEBUG_ONLY__changesToString(changes));\n }\n }\n }\n\n /**\n * Invalidates all cache entries for a specific object type.\n * This will revalidate:\n * 1. All objects of the specified type\n * 2. All lists of the specified type\n * 3. All links where the source object is of the specified type\n *\n * @param apiName - The API name of the object type to invalidate\n * @param changes - Optional changes object to track what has been modified\n * @returns Promise that resolves when all invalidations are complete\n */\n public invalidateObjectType<T extends ObjectTypeDefinition>(\n apiName: T[\"apiName\"] | T,\n changes: Changes | undefined,\n ): Promise<void> {\n if (typeof apiName !== \"string\") {\n apiName = apiName.apiName;\n }\n if (process.env.NODE_ENV !== \"production\") {\n this.logger?.child({ methodName: \"invalidateObjectType\" }).info(\n changes ? DEBUG_ONLY__changesToString(changes) : void 0,\n );\n }\n\n const promises: Array<Promise<void>> = [];\n\n for (const cacheKey of this.layers.truth.keys()) {\n if (changes && changes.modified.has(cacheKey)) {\n continue;\n }\n const query = this.queries.peek(cacheKey);\n if (!query) continue;\n\n promises.push(query.invalidateObjectType(apiName, changes));\n }\n\n // we use allSettled here because we don't care if it succeeds or fails, just that they all complete.\n return Promise.allSettled(promises).then(() => void 0);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|