@osdk/client 2.4.2 → 2.5.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (521) hide show
  1. package/CHANGELOG.md +106 -93
  2. package/build/browser/Client.js +1 -1
  3. package/build/browser/Client.js.map +1 -1
  4. package/build/browser/MinimalClientContext.js.map +1 -1
  5. package/build/browser/actions/applyAction.js +4 -0
  6. package/build/browser/actions/applyAction.js.map +1 -1
  7. package/build/browser/createClient.js +6 -2
  8. package/build/browser/createClient.js.map +1 -1
  9. package/build/browser/createMinimalClient.js +2 -1
  10. package/build/browser/createMinimalClient.js.map +1 -1
  11. package/build/browser/derivedProperties/createWithPropertiesObjectSet.js +17 -0
  12. package/build/browser/derivedProperties/createWithPropertiesObjectSet.js.map +1 -1
  13. package/build/browser/fetchMetadata.test.js +11 -0
  14. package/build/browser/fetchMetadata.test.js.map +1 -1
  15. package/build/browser/index.js +3 -1
  16. package/build/browser/index.js.map +1 -1
  17. package/build/browser/intellisense.test.helpers/orderBySuggestionIsRight.js +8 -1
  18. package/build/browser/intellisense.test.helpers/orderBySuggestionIsRight.js.map +1 -1
  19. package/build/browser/intellisense.test.js +14 -4
  20. package/build/browser/intellisense.test.js.map +1 -1
  21. package/build/browser/object/Cache.js +1 -1
  22. package/build/browser/object/Cache.js.map +1 -1
  23. package/build/browser/object/Cache.test.js +1 -1
  24. package/build/browser/object/Cache.test.js.map +1 -1
  25. package/build/browser/object/SimpleCache.js +1 -1
  26. package/build/browser/object/SimpleCache.js.map +1 -1
  27. package/build/browser/object/aggregate.js +2 -0
  28. package/build/browser/object/aggregate.js.map +1 -1
  29. package/build/browser/object/aggregate.test.js +30 -0
  30. package/build/browser/object/aggregate.test.js.map +1 -1
  31. package/build/browser/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js +1 -0
  32. package/build/browser/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js.map +1 -1
  33. package/build/browser/object/convertWireToOsdkObjects/createOsdkInterface.js +6 -0
  34. package/build/browser/object/convertWireToOsdkObjects/createOsdkInterface.js.map +1 -1
  35. package/build/browser/object/convertWireToOsdkObjects/getDollarLink.js +20 -1
  36. package/build/browser/object/convertWireToOsdkObjects/getDollarLink.js.map +1 -1
  37. package/build/browser/object/convertWireToOsdkObjects.js +4 -0
  38. package/build/browser/object/convertWireToOsdkObjects.js.map +1 -1
  39. package/build/browser/object/convertWireToOsdkObjects.test.js +14 -0
  40. package/build/browser/object/convertWireToOsdkObjects.test.js.map +1 -1
  41. package/build/browser/object/fetchPage.js +96 -21
  42. package/build/browser/object/fetchPage.js.map +1 -1
  43. package/build/browser/object/fetchPage.test.js +35 -1
  44. package/build/browser/object/fetchPage.test.js.map +1 -1
  45. package/build/browser/object/geotimeseriesreference.test.js +0 -2
  46. package/build/browser/object/geotimeseriesreference.test.js.map +1 -1
  47. package/build/browser/object/mediaUpload.js +3 -0
  48. package/build/browser/object/mediaUpload.js.map +1 -1
  49. package/build/browser/objectSet/ObjectSet.test.js +6 -0
  50. package/build/browser/objectSet/ObjectSet.test.js.map +1 -1
  51. package/build/browser/objectSet/ObjectSetListenerWebsocket.js +31 -9
  52. package/build/browser/objectSet/ObjectSetListenerWebsocket.js.map +1 -1
  53. package/build/browser/objectSet/ObjectSetListenerWebsocket.test.js +69 -4
  54. package/build/browser/objectSet/ObjectSetListenerWebsocket.test.js.map +1 -1
  55. package/build/browser/objectSet/createObjectSet.js +3 -1
  56. package/build/browser/objectSet/createObjectSet.js.map +1 -1
  57. package/build/browser/observable/LinkPayload.js +2 -0
  58. package/build/browser/observable/LinkPayload.js.map +1 -0
  59. package/build/browser/observable/ObjectPayload.js.map +1 -1
  60. package/build/browser/observable/ObservableClient/ObserveLink.js +17 -0
  61. package/build/browser/observable/ObservableClient/ObserveLink.js.map +1 -0
  62. package/build/browser/observable/ObservableClient/common.js +2 -0
  63. package/build/browser/observable/ObservableClient/common.js.map +1 -0
  64. package/build/browser/observable/ObservableClient.js +20 -0
  65. package/build/browser/observable/ObservableClient.js.map +1 -1
  66. package/build/browser/observable/Unsubscribable.js +2 -0
  67. package/build/browser/observable/Unsubscribable.js.map +1 -0
  68. package/build/browser/observable/internal/AbstractHelper.js +54 -0
  69. package/build/browser/observable/internal/AbstractHelper.js.map +1 -0
  70. package/build/browser/observable/internal/BatchContext.js +2 -0
  71. package/build/browser/observable/internal/BatchContext.js.map +1 -0
  72. package/build/browser/observable/internal/BulkObjectLoader.js +3 -3
  73. package/build/browser/observable/internal/BulkObjectLoader.js.map +1 -1
  74. package/build/browser/observable/internal/CacheKeys.js +65 -25
  75. package/build/browser/observable/internal/CacheKeys.js.map +1 -1
  76. package/build/browser/observable/internal/Changes.js +6 -0
  77. package/build/browser/observable/internal/Changes.js.map +1 -1
  78. package/build/browser/observable/internal/KnownCacheKey.js +2 -0
  79. package/build/browser/observable/internal/KnownCacheKey.js.map +1 -0
  80. package/build/browser/observable/internal/Layer.js +0 -8
  81. package/build/browser/observable/internal/Layer.js.map +1 -1
  82. package/build/browser/observable/internal/Layers.js +151 -0
  83. package/build/browser/observable/internal/Layers.js.map +1 -0
  84. package/build/browser/observable/internal/ObservableClientImpl.js +54 -3
  85. package/build/browser/observable/internal/ObservableClientImpl.js.map +1 -1
  86. package/build/browser/observable/internal/OrderByCanonicalizer.js +1 -37
  87. package/build/browser/observable/internal/OrderByCanonicalizer.js.map +1 -1
  88. package/build/browser/observable/internal/Queries.js +40 -0
  89. package/build/browser/observable/internal/Queries.js.map +1 -0
  90. package/build/browser/observable/internal/Query.js +45 -4
  91. package/build/browser/observable/internal/Query.js.map +1 -1
  92. package/build/browser/observable/internal/QuerySubscription.js +48 -0
  93. package/build/browser/observable/internal/QuerySubscription.js.map +1 -0
  94. package/build/browser/observable/internal/Store.invalidation.test.js +646 -0
  95. package/build/browser/observable/internal/Store.invalidation.test.js.map +1 -0
  96. package/build/browser/observable/internal/Store.js +87 -308
  97. package/build/browser/observable/internal/Store.js.map +1 -1
  98. package/build/browser/observable/internal/Store.test.js +330 -73
  99. package/build/browser/observable/internal/Store.test.js.map +1 -1
  100. package/build/browser/observable/internal/SubjectPayload.js +2 -0
  101. package/build/browser/observable/internal/SubjectPayload.js.map +1 -0
  102. package/build/browser/observable/internal/Subjects.js +55 -0
  103. package/build/browser/observable/internal/Subjects.js.map +1 -0
  104. package/build/browser/observable/internal/UnsubscribableWrapper.js +30 -0
  105. package/build/browser/observable/internal/UnsubscribableWrapper.js.map +1 -0
  106. package/build/browser/observable/internal/WeakRefTrie.js +61 -0
  107. package/build/browser/observable/internal/WeakRefTrie.js.map +1 -0
  108. package/build/browser/observable/internal/{ActionApplication.js → actions/ActionApplication.js} +2 -2
  109. package/build/browser/observable/internal/actions/ActionApplication.js.map +1 -0
  110. package/build/{esm/observable/internal → browser/observable/internal/actions}/OptimisticJob.js +15 -6
  111. package/build/browser/observable/internal/actions/OptimisticJob.js.map +1 -0
  112. package/build/browser/observable/internal/base-list/BaseCollectionQuery.js +2 -0
  113. package/build/browser/observable/internal/base-list/BaseCollectionQuery.js.map +1 -0
  114. package/build/browser/observable/internal/base-list/BaseListQuery.js +411 -0
  115. package/build/browser/observable/internal/base-list/BaseListQuery.js.map +1 -0
  116. package/build/browser/observable/internal/base-list/createCollectionConnectable.js +50 -0
  117. package/build/browser/observable/internal/base-list/createCollectionConnectable.js.map +1 -0
  118. package/build/browser/observable/internal/base-list/createCollectionConnectable.test.js +597 -0
  119. package/build/browser/observable/internal/base-list/createCollectionConnectable.test.js.map +1 -0
  120. package/build/browser/observable/internal/base-list/removeDuplicates.js +36 -0
  121. package/build/browser/observable/internal/base-list/removeDuplicates.js.map +1 -0
  122. package/build/browser/observable/internal/createInitEntry.js +25 -0
  123. package/build/browser/observable/internal/createInitEntry.js.map +1 -0
  124. package/build/browser/observable/internal/getObjectTypesThatInvalidate.js +216 -0
  125. package/build/browser/observable/internal/getObjectTypesThatInvalidate.js.map +1 -0
  126. package/build/browser/observable/internal/getObjectTypesThatInvalidate.test.js +382 -0
  127. package/build/browser/observable/internal/getObjectTypesThatInvalidate.test.js.map +1 -0
  128. package/build/browser/observable/internal/isObjectInstance.js +23 -0
  129. package/build/browser/observable/internal/isObjectInstance.js.map +1 -0
  130. package/build/browser/observable/internal/links/LinksHelper.js +37 -0
  131. package/build/browser/observable/internal/links/LinksHelper.js.map +1 -0
  132. package/build/browser/observable/internal/links/SpecificLinkCacheKey.js +2 -0
  133. package/build/browser/observable/internal/links/SpecificLinkCacheKey.js.map +1 -0
  134. package/build/browser/observable/internal/links/SpecificLinkQuery.js +185 -0
  135. package/build/browser/observable/internal/links/SpecificLinkQuery.js.map +1 -0
  136. package/build/browser/observable/internal/list/InterfaceListQuery.js +83 -0
  137. package/build/browser/observable/internal/list/InterfaceListQuery.js.map +1 -0
  138. package/build/browser/observable/internal/list/ListCacheKey.js +2 -0
  139. package/build/browser/observable/internal/list/ListCacheKey.js.map +1 -0
  140. package/build/browser/observable/internal/list/ListQuery.js +372 -0
  141. package/build/browser/observable/internal/list/ListQuery.js.map +1 -0
  142. package/build/browser/observable/internal/list/ListQueryOptions.js +2 -0
  143. package/build/browser/observable/internal/list/ListQueryOptions.js.map +1 -0
  144. package/build/browser/observable/internal/list/ListsHelper.js +51 -0
  145. package/build/browser/observable/internal/list/ListsHelper.js.map +1 -0
  146. package/build/browser/observable/internal/list/ObjectListQuery.js +48 -0
  147. package/build/browser/observable/internal/list/ObjectListQuery.js.map +1 -0
  148. package/build/browser/observable/internal/object/ObjectCacheKey.js +2 -0
  149. package/build/browser/observable/internal/object/ObjectCacheKey.js.map +1 -0
  150. package/build/browser/observable/internal/{ObjectQuery.js → object/ObjectQuery.js} +27 -18
  151. package/build/browser/observable/internal/object/ObjectQuery.js.map +1 -0
  152. package/build/browser/observable/internal/object/ObjectsHelper.js +48 -0
  153. package/build/browser/observable/internal/object/ObjectsHelper.js.map +1 -0
  154. package/build/browser/observable/internal/sorting/SortingStrategy.js +78 -0
  155. package/build/browser/observable/internal/sorting/SortingStrategy.js.map +1 -0
  156. package/build/browser/observable/internal/testUtils/invalidateList.js +23 -0
  157. package/build/browser/observable/internal/testUtils/invalidateList.js.map +1 -0
  158. package/build/browser/observable/internal/testUtils/observeLink/expectStandardObserveLink.js +69 -0
  159. package/build/browser/observable/internal/testUtils/observeLink/expectStandardObserveLink.js.map +1 -0
  160. package/build/browser/observable/internal/testUtils/observeObject/expectStandardObserveObject.js +56 -0
  161. package/build/browser/observable/internal/testUtils/observeObject/expectStandardObserveObject.js.map +1 -0
  162. package/build/browser/observable/internal/testUtils.js +72 -10
  163. package/build/browser/observable/internal/testUtils.js.map +1 -1
  164. package/build/browser/ontology/loadActionMetadata.js +3 -1
  165. package/build/browser/ontology/loadActionMetadata.js.map +1 -1
  166. package/build/browser/ontology/loadFullObjectMetadata.js +2 -1
  167. package/build/browser/ontology/loadFullObjectMetadata.js.map +1 -1
  168. package/build/browser/ontology/loadInterfaceMetadata.js +2 -1
  169. package/build/browser/ontology/loadInterfaceMetadata.js.map +1 -1
  170. package/build/browser/public/unstable-do-not-use.js.map +1 -1
  171. package/build/browser/util/UserAgent.js +2 -2
  172. package/build/browser/util/UserAgent.js.map +1 -1
  173. package/build/browser/util/exponentialBackoff.js +51 -0
  174. package/build/browser/util/exponentialBackoff.js.map +1 -0
  175. package/build/browser/util/exponentialBackoff.test.js +81 -0
  176. package/build/browser/util/exponentialBackoff.test.js.map +1 -0
  177. package/build/browser/util/extractObjectOrInterfaceType.js +9 -1
  178. package/build/browser/util/extractObjectOrInterfaceType.js.map +1 -1
  179. package/build/browser/util/extractObjectOrInterfaceType.test.js +2 -2
  180. package/build/browser/util/extractObjectOrInterfaceType.test.js.map +1 -1
  181. package/build/browser/util/streamutils.js +1 -1
  182. package/build/browser/util/streamutils.js.map +1 -1
  183. package/build/browser/util/toDataValue.js +15 -1
  184. package/build/browser/util/toDataValue.js.map +1 -1
  185. package/build/browser/util/toDataValue.test.js +42 -2
  186. package/build/browser/util/toDataValue.test.js.map +1 -1
  187. package/build/cjs/{chunk-633AI7EA.cjs → chunk-GVGP7T5P.cjs} +407 -257
  188. package/build/cjs/chunk-GVGP7T5P.cjs.map +1 -0
  189. package/build/cjs/{chunk-26WFEZQO.cjs → chunk-YADG7KA6.cjs} +136 -84
  190. package/build/cjs/chunk-YADG7KA6.cjs.map +1 -0
  191. package/build/cjs/{createClient-BJo8T7Js.d.cts → createClient-mOlFts15.d.cts} +1 -0
  192. package/build/cjs/index.cjs +11 -7
  193. package/build/cjs/index.d.cts +2 -2
  194. package/build/cjs/public/internal.cjs +8 -8
  195. package/build/cjs/public/unstable-do-not-use.cjs +1502 -851
  196. package/build/cjs/public/unstable-do-not-use.cjs.map +1 -1
  197. package/build/cjs/public/unstable-do-not-use.d.cts +183 -13
  198. package/build/esm/Client.js +1 -1
  199. package/build/esm/Client.js.map +1 -1
  200. package/build/esm/MinimalClientContext.js.map +1 -1
  201. package/build/esm/actions/applyAction.js +4 -0
  202. package/build/esm/actions/applyAction.js.map +1 -1
  203. package/build/esm/createClient.js +6 -2
  204. package/build/esm/createClient.js.map +1 -1
  205. package/build/esm/createMinimalClient.js +2 -1
  206. package/build/esm/createMinimalClient.js.map +1 -1
  207. package/build/esm/derivedProperties/createWithPropertiesObjectSet.js +17 -0
  208. package/build/esm/derivedProperties/createWithPropertiesObjectSet.js.map +1 -1
  209. package/build/esm/fetchMetadata.test.js +11 -0
  210. package/build/esm/fetchMetadata.test.js.map +1 -1
  211. package/build/esm/index.js +3 -1
  212. package/build/esm/index.js.map +1 -1
  213. package/build/esm/intellisense.test.helpers/orderBySuggestionIsRight.js +8 -1
  214. package/build/esm/intellisense.test.helpers/orderBySuggestionIsRight.js.map +1 -1
  215. package/build/esm/intellisense.test.js +14 -4
  216. package/build/esm/intellisense.test.js.map +1 -1
  217. package/build/esm/object/Cache.js +1 -1
  218. package/build/esm/object/Cache.js.map +1 -1
  219. package/build/esm/object/Cache.test.js +1 -1
  220. package/build/esm/object/Cache.test.js.map +1 -1
  221. package/build/esm/object/SimpleCache.js +1 -1
  222. package/build/esm/object/SimpleCache.js.map +1 -1
  223. package/build/esm/object/aggregate.js +2 -0
  224. package/build/esm/object/aggregate.js.map +1 -1
  225. package/build/esm/object/aggregate.test.js +30 -0
  226. package/build/esm/object/aggregate.test.js.map +1 -1
  227. package/build/esm/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js +1 -0
  228. package/build/esm/object/convertWireToOsdkObjects/OsdkCustomInspectPrototype.js.map +1 -1
  229. package/build/esm/object/convertWireToOsdkObjects/createOsdkInterface.js +6 -0
  230. package/build/esm/object/convertWireToOsdkObjects/createOsdkInterface.js.map +1 -1
  231. package/build/esm/object/convertWireToOsdkObjects/getDollarLink.js +20 -1
  232. package/build/esm/object/convertWireToOsdkObjects/getDollarLink.js.map +1 -1
  233. package/build/esm/object/convertWireToOsdkObjects.js +4 -0
  234. package/build/esm/object/convertWireToOsdkObjects.js.map +1 -1
  235. package/build/esm/object/convertWireToOsdkObjects.test.js +14 -0
  236. package/build/esm/object/convertWireToOsdkObjects.test.js.map +1 -1
  237. package/build/esm/object/fetchPage.js +96 -21
  238. package/build/esm/object/fetchPage.js.map +1 -1
  239. package/build/esm/object/fetchPage.test.js +35 -1
  240. package/build/esm/object/fetchPage.test.js.map +1 -1
  241. package/build/esm/object/geotimeseriesreference.test.js +0 -2
  242. package/build/esm/object/geotimeseriesreference.test.js.map +1 -1
  243. package/build/esm/object/mediaUpload.js +3 -0
  244. package/build/esm/object/mediaUpload.js.map +1 -1
  245. package/build/esm/objectSet/ObjectSet.test.js +6 -0
  246. package/build/esm/objectSet/ObjectSet.test.js.map +1 -1
  247. package/build/esm/objectSet/ObjectSetListenerWebsocket.js +31 -9
  248. package/build/esm/objectSet/ObjectSetListenerWebsocket.js.map +1 -1
  249. package/build/esm/objectSet/ObjectSetListenerWebsocket.test.js +69 -4
  250. package/build/esm/objectSet/ObjectSetListenerWebsocket.test.js.map +1 -1
  251. package/build/esm/objectSet/createObjectSet.js +3 -1
  252. package/build/esm/objectSet/createObjectSet.js.map +1 -1
  253. package/build/esm/observable/LinkPayload.js +2 -0
  254. package/build/esm/observable/LinkPayload.js.map +1 -0
  255. package/build/esm/observable/ObjectPayload.js.map +1 -1
  256. package/build/esm/observable/ObservableClient/ObserveLink.js +17 -0
  257. package/build/esm/observable/ObservableClient/ObserveLink.js.map +1 -0
  258. package/build/esm/observable/ObservableClient/common.js +2 -0
  259. package/build/esm/observable/ObservableClient/common.js.map +1 -0
  260. package/build/esm/observable/ObservableClient.js +20 -0
  261. package/build/esm/observable/ObservableClient.js.map +1 -1
  262. package/build/esm/observable/Unsubscribable.js +2 -0
  263. package/build/esm/observable/Unsubscribable.js.map +1 -0
  264. package/build/esm/observable/internal/AbstractHelper.js +54 -0
  265. package/build/esm/observable/internal/AbstractHelper.js.map +1 -0
  266. package/build/esm/observable/internal/BatchContext.js +2 -0
  267. package/build/esm/observable/internal/BatchContext.js.map +1 -0
  268. package/build/esm/observable/internal/BulkObjectLoader.js +3 -3
  269. package/build/esm/observable/internal/BulkObjectLoader.js.map +1 -1
  270. package/build/esm/observable/internal/CacheKeys.js +65 -25
  271. package/build/esm/observable/internal/CacheKeys.js.map +1 -1
  272. package/build/esm/observable/internal/Changes.js +6 -0
  273. package/build/esm/observable/internal/Changes.js.map +1 -1
  274. package/build/esm/observable/internal/KnownCacheKey.js +2 -0
  275. package/build/esm/observable/internal/KnownCacheKey.js.map +1 -0
  276. package/build/esm/observable/internal/Layer.js +0 -8
  277. package/build/esm/observable/internal/Layer.js.map +1 -1
  278. package/build/esm/observable/internal/Layers.js +151 -0
  279. package/build/esm/observable/internal/Layers.js.map +1 -0
  280. package/build/esm/observable/internal/ObservableClientImpl.js +54 -3
  281. package/build/esm/observable/internal/ObservableClientImpl.js.map +1 -1
  282. package/build/esm/observable/internal/OrderByCanonicalizer.js +1 -37
  283. package/build/esm/observable/internal/OrderByCanonicalizer.js.map +1 -1
  284. package/build/esm/observable/internal/Queries.js +40 -0
  285. package/build/esm/observable/internal/Queries.js.map +1 -0
  286. package/build/esm/observable/internal/Query.js +45 -4
  287. package/build/esm/observable/internal/Query.js.map +1 -1
  288. package/build/esm/observable/internal/QuerySubscription.js +48 -0
  289. package/build/esm/observable/internal/QuerySubscription.js.map +1 -0
  290. package/build/esm/observable/internal/Store.invalidation.test.js +646 -0
  291. package/build/esm/observable/internal/Store.invalidation.test.js.map +1 -0
  292. package/build/esm/observable/internal/Store.js +87 -308
  293. package/build/esm/observable/internal/Store.js.map +1 -1
  294. package/build/esm/observable/internal/Store.test.js +330 -73
  295. package/build/esm/observable/internal/Store.test.js.map +1 -1
  296. package/build/esm/observable/internal/SubjectPayload.js +2 -0
  297. package/build/esm/observable/internal/SubjectPayload.js.map +1 -0
  298. package/build/esm/observable/internal/Subjects.js +55 -0
  299. package/build/esm/observable/internal/Subjects.js.map +1 -0
  300. package/build/esm/observable/internal/UnsubscribableWrapper.js +30 -0
  301. package/build/esm/observable/internal/UnsubscribableWrapper.js.map +1 -0
  302. package/build/esm/observable/internal/WeakRefTrie.js +61 -0
  303. package/build/esm/observable/internal/WeakRefTrie.js.map +1 -0
  304. package/build/esm/observable/internal/{ActionApplication.js → actions/ActionApplication.js} +2 -2
  305. package/build/esm/observable/internal/actions/ActionApplication.js.map +1 -0
  306. package/build/{browser/observable/internal → esm/observable/internal/actions}/OptimisticJob.js +15 -6
  307. package/build/esm/observable/internal/actions/OptimisticJob.js.map +1 -0
  308. package/build/esm/observable/internal/base-list/BaseCollectionQuery.js +2 -0
  309. package/build/esm/observable/internal/base-list/BaseCollectionQuery.js.map +1 -0
  310. package/build/esm/observable/internal/base-list/BaseListQuery.js +411 -0
  311. package/build/esm/observable/internal/base-list/BaseListQuery.js.map +1 -0
  312. package/build/esm/observable/internal/base-list/createCollectionConnectable.js +50 -0
  313. package/build/esm/observable/internal/base-list/createCollectionConnectable.js.map +1 -0
  314. package/build/esm/observable/internal/base-list/createCollectionConnectable.test.js +597 -0
  315. package/build/esm/observable/internal/base-list/createCollectionConnectable.test.js.map +1 -0
  316. package/build/esm/observable/internal/base-list/removeDuplicates.js +36 -0
  317. package/build/esm/observable/internal/base-list/removeDuplicates.js.map +1 -0
  318. package/build/esm/observable/internal/createInitEntry.js +25 -0
  319. package/build/esm/observable/internal/createInitEntry.js.map +1 -0
  320. package/build/esm/observable/internal/getObjectTypesThatInvalidate.js +216 -0
  321. package/build/esm/observable/internal/getObjectTypesThatInvalidate.js.map +1 -0
  322. package/build/esm/observable/internal/getObjectTypesThatInvalidate.test.js +382 -0
  323. package/build/esm/observable/internal/getObjectTypesThatInvalidate.test.js.map +1 -0
  324. package/build/esm/observable/internal/isObjectInstance.js +23 -0
  325. package/build/esm/observable/internal/isObjectInstance.js.map +1 -0
  326. package/build/esm/observable/internal/links/LinksHelper.js +37 -0
  327. package/build/esm/observable/internal/links/LinksHelper.js.map +1 -0
  328. package/build/esm/observable/internal/links/SpecificLinkCacheKey.js +2 -0
  329. package/build/esm/observable/internal/links/SpecificLinkCacheKey.js.map +1 -0
  330. package/build/esm/observable/internal/links/SpecificLinkQuery.js +185 -0
  331. package/build/esm/observable/internal/links/SpecificLinkQuery.js.map +1 -0
  332. package/build/esm/observable/internal/list/InterfaceListQuery.js +83 -0
  333. package/build/esm/observable/internal/list/InterfaceListQuery.js.map +1 -0
  334. package/build/esm/observable/internal/list/ListCacheKey.js +2 -0
  335. package/build/esm/observable/internal/list/ListCacheKey.js.map +1 -0
  336. package/build/esm/observable/internal/list/ListQuery.js +372 -0
  337. package/build/esm/observable/internal/list/ListQuery.js.map +1 -0
  338. package/build/esm/observable/internal/list/ListQueryOptions.js +2 -0
  339. package/build/esm/observable/internal/list/ListQueryOptions.js.map +1 -0
  340. package/build/esm/observable/internal/list/ListsHelper.js +51 -0
  341. package/build/esm/observable/internal/list/ListsHelper.js.map +1 -0
  342. package/build/esm/observable/internal/list/ObjectListQuery.js +48 -0
  343. package/build/esm/observable/internal/list/ObjectListQuery.js.map +1 -0
  344. package/build/esm/observable/internal/object/ObjectCacheKey.js +2 -0
  345. package/build/esm/observable/internal/object/ObjectCacheKey.js.map +1 -0
  346. package/build/esm/observable/internal/{ObjectQuery.js → object/ObjectQuery.js} +27 -18
  347. package/build/esm/observable/internal/object/ObjectQuery.js.map +1 -0
  348. package/build/esm/observable/internal/object/ObjectsHelper.js +48 -0
  349. package/build/esm/observable/internal/object/ObjectsHelper.js.map +1 -0
  350. package/build/esm/observable/internal/sorting/SortingStrategy.js +78 -0
  351. package/build/esm/observable/internal/sorting/SortingStrategy.js.map +1 -0
  352. package/build/esm/observable/internal/testUtils/invalidateList.js +23 -0
  353. package/build/esm/observable/internal/testUtils/invalidateList.js.map +1 -0
  354. package/build/esm/observable/internal/testUtils/observeLink/expectStandardObserveLink.js +69 -0
  355. package/build/esm/observable/internal/testUtils/observeLink/expectStandardObserveLink.js.map +1 -0
  356. package/build/esm/observable/internal/testUtils/observeObject/expectStandardObserveObject.js +56 -0
  357. package/build/esm/observable/internal/testUtils/observeObject/expectStandardObserveObject.js.map +1 -0
  358. package/build/esm/observable/internal/testUtils.js +72 -10
  359. package/build/esm/observable/internal/testUtils.js.map +1 -1
  360. package/build/esm/ontology/loadActionMetadata.js +3 -1
  361. package/build/esm/ontology/loadActionMetadata.js.map +1 -1
  362. package/build/esm/ontology/loadFullObjectMetadata.js +2 -1
  363. package/build/esm/ontology/loadFullObjectMetadata.js.map +1 -1
  364. package/build/esm/ontology/loadInterfaceMetadata.js +2 -1
  365. package/build/esm/ontology/loadInterfaceMetadata.js.map +1 -1
  366. package/build/esm/public/unstable-do-not-use.js.map +1 -1
  367. package/build/esm/util/UserAgent.js +2 -2
  368. package/build/esm/util/UserAgent.js.map +1 -1
  369. package/build/esm/util/exponentialBackoff.js +51 -0
  370. package/build/esm/util/exponentialBackoff.js.map +1 -0
  371. package/build/esm/util/exponentialBackoff.test.js +81 -0
  372. package/build/esm/util/exponentialBackoff.test.js.map +1 -0
  373. package/build/esm/util/extractObjectOrInterfaceType.js +9 -1
  374. package/build/esm/util/extractObjectOrInterfaceType.js.map +1 -1
  375. package/build/esm/util/extractObjectOrInterfaceType.test.js +2 -2
  376. package/build/esm/util/extractObjectOrInterfaceType.test.js.map +1 -1
  377. package/build/esm/util/streamutils.js +1 -1
  378. package/build/esm/util/streamutils.js.map +1 -1
  379. package/build/esm/util/toDataValue.js +15 -1
  380. package/build/esm/util/toDataValue.js.map +1 -1
  381. package/build/esm/util/toDataValue.test.js +42 -2
  382. package/build/esm/util/toDataValue.test.js.map +1 -1
  383. package/build/types/Client.d.ts +1 -1
  384. package/build/types/MinimalClientContext.d.ts +1 -0
  385. package/build/types/MinimalClientContext.d.ts.map +1 -1
  386. package/build/types/actions/applyAction.d.ts.map +1 -1
  387. package/build/types/createClient.d.ts +1 -0
  388. package/build/types/createClient.d.ts.map +1 -1
  389. package/build/types/index.d.ts +1 -1
  390. package/build/types/index.d.ts.map +1 -1
  391. package/build/types/object/fetchPage.d.ts.map +1 -1
  392. package/build/types/object/mediaUpload.d.ts +2 -1
  393. package/build/types/object/mediaUpload.d.ts.map +1 -1
  394. package/build/types/observable/LinkPayload.d.ts +9 -0
  395. package/build/types/observable/LinkPayload.d.ts.map +1 -0
  396. package/build/types/observable/ObjectPayload.d.ts +4 -0
  397. package/build/types/observable/ObjectPayload.d.ts.map +1 -1
  398. package/build/types/observable/ObservableClient/ObserveLink.d.ts +32 -0
  399. package/build/types/observable/ObservableClient/ObserveLink.d.ts.map +1 -0
  400. package/build/types/observable/ObservableClient/common.d.ts +67 -0
  401. package/build/types/observable/ObservableClient/common.d.ts.map +1 -0
  402. package/build/types/observable/ObservableClient.d.ts +103 -15
  403. package/build/types/observable/ObservableClient.d.ts.map +1 -1
  404. package/build/types/observable/Unsubscribable.d.ts +3 -0
  405. package/build/types/observable/Unsubscribable.d.ts.map +1 -0
  406. package/build/types/observable/internal/AbstractHelper.d.ts +17 -0
  407. package/build/types/observable/internal/AbstractHelper.d.ts.map +1 -0
  408. package/build/types/observable/internal/BatchContext.d.ts +11 -0
  409. package/build/types/observable/internal/BatchContext.d.ts.map +1 -0
  410. package/build/types/observable/internal/BulkObjectLoader.d.ts.map +1 -1
  411. package/build/types/observable/internal/CacheKeys.d.ts +12 -6
  412. package/build/types/observable/internal/CacheKeys.d.ts.map +1 -1
  413. package/build/types/observable/internal/Changes.d.ts +8 -5
  414. package/build/types/observable/internal/Changes.d.ts.map +1 -1
  415. package/build/types/observable/internal/KnownCacheKey.d.ts +4 -0
  416. package/build/types/observable/internal/KnownCacheKey.d.ts.map +1 -0
  417. package/build/types/observable/internal/Layer.d.ts +6 -7
  418. package/build/types/observable/internal/Layer.d.ts.map +1 -1
  419. package/build/types/observable/internal/Layers.d.ts +26 -0
  420. package/build/types/observable/internal/Layers.d.ts.map +1 -0
  421. package/build/types/observable/internal/OrderByCanonicalizer.d.ts +0 -7
  422. package/build/types/observable/internal/OrderByCanonicalizer.d.ts.map +1 -1
  423. package/build/types/observable/internal/Queries.d.ts +9 -0
  424. package/build/types/observable/internal/Queries.d.ts.map +1 -0
  425. package/build/types/observable/internal/Query.d.ts +23 -6
  426. package/build/types/observable/internal/Query.d.ts.map +1 -1
  427. package/build/types/observable/internal/QuerySubscription.d.ts +1 -0
  428. package/build/types/observable/internal/QuerySubscription.d.ts.map +1 -0
  429. package/build/types/observable/internal/Store.d.ts +41 -51
  430. package/build/types/observable/internal/Store.d.ts.map +1 -1
  431. package/build/types/observable/internal/Store.invalidation.test.d.ts +1 -0
  432. package/build/types/observable/internal/Store.invalidation.test.d.ts.map +1 -0
  433. package/build/types/observable/internal/Store.test.d.ts +4 -1
  434. package/build/types/observable/internal/Store.test.d.ts.map +1 -1
  435. package/build/types/observable/internal/SubjectPayload.d.ts +5 -0
  436. package/build/types/observable/internal/SubjectPayload.d.ts.map +1 -0
  437. package/build/types/observable/internal/Subjects.d.ts +16 -0
  438. package/build/types/observable/internal/Subjects.d.ts.map +1 -0
  439. package/build/types/observable/internal/UnsubscribableWrapper.d.ts +1 -0
  440. package/build/types/observable/internal/UnsubscribableWrapper.d.ts.map +1 -0
  441. package/build/types/observable/internal/WeakRefTrie.d.ts +13 -0
  442. package/build/types/observable/internal/WeakRefTrie.d.ts.map +1 -0
  443. package/build/types/observable/internal/{ActionApplication.d.ts → actions/ActionApplication.d.ts} +2 -2
  444. package/build/types/observable/internal/{ActionApplication.d.ts.map → actions/ActionApplication.d.ts.map} +1 -1
  445. package/build/types/observable/internal/{OptimisticJob.d.ts → actions/OptimisticJob.d.ts} +4 -4
  446. package/build/types/observable/internal/actions/OptimisticJob.d.ts.map +1 -0
  447. package/build/types/observable/internal/base-list/BaseCollectionQuery.d.ts +64 -0
  448. package/build/types/observable/internal/base-list/BaseCollectionQuery.d.ts.map +1 -0
  449. package/build/types/observable/internal/base-list/BaseListQuery.d.ts +145 -0
  450. package/build/types/observable/internal/base-list/BaseListQuery.d.ts.map +1 -0
  451. package/build/types/observable/internal/base-list/createCollectionConnectable.d.ts +39 -0
  452. package/build/types/observable/internal/base-list/createCollectionConnectable.d.ts.map +1 -0
  453. package/build/types/observable/internal/base-list/createCollectionConnectable.test.d.ts +1 -0
  454. package/build/types/observable/internal/base-list/createCollectionConnectable.test.d.ts.map +1 -0
  455. package/build/types/observable/internal/base-list/removeDuplicates.d.ts +11 -0
  456. package/build/types/observable/internal/base-list/removeDuplicates.d.ts.map +1 -0
  457. package/build/types/observable/internal/createInitEntry.d.ts +3 -0
  458. package/build/types/observable/internal/createInitEntry.d.ts.map +1 -0
  459. package/build/types/observable/internal/getObjectTypesThatInvalidate.d.ts +9 -0
  460. package/build/types/observable/internal/getObjectTypesThatInvalidate.d.ts.map +1 -0
  461. package/build/types/observable/internal/getObjectTypesThatInvalidate.test.d.ts +1 -0
  462. package/build/types/observable/internal/getObjectTypesThatInvalidate.test.d.ts.map +1 -0
  463. package/build/types/observable/internal/isObjectInstance.d.ts +5 -0
  464. package/build/types/observable/internal/isObjectInstance.d.ts.map +1 -0
  465. package/build/types/observable/internal/links/LinksHelper.d.ts +31 -0
  466. package/build/types/observable/internal/links/LinksHelper.d.ts.map +1 -0
  467. package/build/types/observable/internal/links/SpecificLinkCacheKey.d.ts +17 -0
  468. package/build/types/observable/internal/links/SpecificLinkCacheKey.d.ts.map +1 -0
  469. package/build/types/observable/internal/links/SpecificLinkQuery.d.ts +47 -0
  470. package/build/types/observable/internal/links/SpecificLinkQuery.d.ts.map +1 -0
  471. package/build/types/observable/internal/list/InterfaceListQuery.d.ts +18 -0
  472. package/build/types/observable/internal/list/InterfaceListQuery.d.ts.map +1 -0
  473. package/build/types/observable/internal/list/ListCacheKey.d.ts +7 -0
  474. package/build/types/observable/internal/list/ListCacheKey.d.ts.map +1 -0
  475. package/build/types/observable/internal/list/ListQuery.d.ts +106 -0
  476. package/build/types/observable/internal/list/ListQuery.d.ts.map +1 -0
  477. package/build/types/observable/internal/list/ListQueryOptions.d.ts +4 -0
  478. package/build/types/observable/internal/list/ListQueryOptions.d.ts.map +1 -0
  479. package/build/types/observable/internal/list/ListsHelper.d.ts +19 -0
  480. package/build/types/observable/internal/list/ListsHelper.d.ts.map +1 -0
  481. package/build/types/observable/internal/list/ObjectListQuery.d.ts +18 -0
  482. package/build/types/observable/internal/list/ObjectListQuery.d.ts.map +1 -0
  483. package/build/types/observable/internal/object/ObjectCacheKey.d.ts +5 -0
  484. package/build/types/observable/internal/object/ObjectCacheKey.d.ts.map +1 -0
  485. package/build/types/observable/internal/{ObjectQuery.d.ts → object/ObjectQuery.d.ts} +11 -9
  486. package/build/types/observable/internal/object/ObjectQuery.d.ts.map +1 -0
  487. package/build/types/observable/internal/object/ObjectsHelper.d.ts +11 -0
  488. package/build/types/observable/internal/object/ObjectsHelper.d.ts.map +1 -0
  489. package/build/types/observable/internal/sorting/SortingStrategy.d.ts +41 -0
  490. package/build/types/observable/internal/sorting/SortingStrategy.d.ts.map +1 -0
  491. package/build/types/observable/internal/testUtils/invalidateList.d.ts +9 -0
  492. package/build/types/observable/internal/testUtils/invalidateList.d.ts.map +1 -0
  493. package/build/types/observable/internal/testUtils/observeLink/expectStandardObserveLink.d.ts +46 -0
  494. package/build/types/observable/internal/testUtils/observeLink/expectStandardObserveLink.d.ts.map +1 -0
  495. package/build/types/observable/internal/testUtils/observeObject/expectStandardObserveObject.d.ts +26 -0
  496. package/build/types/observable/internal/testUtils/observeObject/expectStandardObserveObject.d.ts.map +1 -0
  497. package/build/types/observable/internal/testUtils.d.ts +26 -4
  498. package/build/types/observable/internal/testUtils.d.ts.map +1 -1
  499. package/build/types/public/unstable-do-not-use.d.ts +4 -2
  500. package/build/types/public/unstable-do-not-use.d.ts.map +1 -1
  501. package/build/types/util/exponentialBackoff.d.ts +14 -0
  502. package/build/types/util/exponentialBackoff.d.ts.map +1 -0
  503. package/build/types/util/exponentialBackoff.test.d.ts +1 -0
  504. package/build/types/util/exponentialBackoff.test.d.ts.map +1 -0
  505. package/package.json +27 -27
  506. package/build/browser/observable/internal/ActionApplication.js.map +0 -1
  507. package/build/browser/observable/internal/ListQuery.js +0 -618
  508. package/build/browser/observable/internal/ListQuery.js.map +0 -1
  509. package/build/browser/observable/internal/ObjectQuery.js.map +0 -1
  510. package/build/browser/observable/internal/OptimisticJob.js.map +0 -1
  511. package/build/cjs/chunk-26WFEZQO.cjs.map +0 -1
  512. package/build/cjs/chunk-633AI7EA.cjs.map +0 -1
  513. package/build/esm/observable/internal/ActionApplication.js.map +0 -1
  514. package/build/esm/observable/internal/ListQuery.js +0 -618
  515. package/build/esm/observable/internal/ListQuery.js.map +0 -1
  516. package/build/esm/observable/internal/ObjectQuery.js.map +0 -1
  517. package/build/esm/observable/internal/OptimisticJob.js.map +0 -1
  518. package/build/types/observable/internal/ListQuery.d.ts +0 -88
  519. package/build/types/observable/internal/ListQuery.d.ts.map +0 -1
  520. package/build/types/observable/internal/ObjectQuery.d.ts.map +0 -1
  521. package/build/types/observable/internal/OptimisticJob.d.ts.map +0 -1
@@ -1,32 +1,91 @@
1
1
  'use strict';
2
2
 
3
- var chunk26WFEZQO_cjs = require('../chunk-26WFEZQO.cjs');
4
- var chunk633AI7EA_cjs = require('../chunk-633AI7EA.cjs');
3
+ var chunkYADG7KA6_cjs = require('../chunk-YADG7KA6.cjs');
4
+ var chunkGVGP7T5P_cjs = require('../chunk-GVGP7T5P.cjs');
5
5
  require('../chunk-Q7SFCCGT.cjs');
6
6
  var shared_net_fetch = require('@osdk/shared.net.fetch');
7
7
  var rxjs = require('rxjs');
8
8
  var invariant2 = require('tiny-invariant');
9
9
  var trie = require('@wry/trie');
10
10
  var mnemonist = require('mnemonist');
11
- var deepEqual2 = require('fast-deep-equal');
11
+ var deepEqual4 = require('fast-deep-equal');
12
12
  var groupBy = require('object.groupby');
13
13
  var shared_net_errors = require('@osdk/shared.net.errors');
14
14
 
15
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
16
 
17
17
  var invariant2__default = /*#__PURE__*/_interopDefault(invariant2);
18
- var deepEqual2__default = /*#__PURE__*/_interopDefault(deepEqual2);
18
+ var deepEqual4__default = /*#__PURE__*/_interopDefault(deepEqual4);
19
19
  var groupBy__default = /*#__PURE__*/_interopDefault(groupBy);
20
20
 
21
+ // src/observable/internal/UnsubscribableWrapper.ts
22
+ var UnsubscribableWrapper = class {
23
+ #subscription;
24
+ constructor(subscription) {
25
+ this.#subscription = subscription;
26
+ }
27
+ unsubscribe() {
28
+ this.#subscription?.unsubscribe();
29
+ }
30
+ };
31
+
21
32
  // src/observable/internal/ObservableClientImpl.ts
22
33
  var ObservableClientImpl = class {
23
34
  constructor(store) {
24
35
  this.__experimentalStore = store;
25
- this.observeObject = store.observeObject.bind(store);
26
- this.observeList = store.observeList.bind(store);
27
36
  this.applyAction = store.applyAction.bind(store);
28
37
  this.validateAction = store.validateAction.bind(store);
29
- this.canonicalizeWhereClause = store.canonicalizeWhereClause.bind(store);
38
+ }
39
+ observeObject = (apiName, pk, options, subFn) => {
40
+ return this.__experimentalStore.objects.observe(
41
+ {
42
+ ...options,
43
+ apiName,
44
+ pk
45
+ },
46
+ // cast to cross typed to untyped barrier
47
+ subFn
48
+ );
49
+ };
50
+ observeList = (options, subFn) => {
51
+ return this.__experimentalStore.lists.observe(
52
+ options,
53
+ // cast to cross typed to untyped barrier
54
+ subFn
55
+ );
56
+ };
57
+ observeLinks = (objects, linkName, options, subFn) => {
58
+ const objectsArray = Array.isArray(objects) ? objects : [objects];
59
+ const parentSub = new rxjs.Subscription();
60
+ for (const obj of objectsArray) {
61
+ const querySubscription = this.__experimentalStore.links.observe(
62
+ {
63
+ ...options,
64
+ srcType: {
65
+ type: "object",
66
+ apiName: obj.$apiName
67
+ },
68
+ linkName,
69
+ pk: obj.$primaryKey
70
+ },
71
+ // cast to cross typed to untyped barrier
72
+ subFn
73
+ );
74
+ parentSub.add(querySubscription);
75
+ }
76
+ return new UnsubscribableWrapper(parentSub);
77
+ };
78
+ invalidateAll() {
79
+ return this.__experimentalStore.invalidateAll();
80
+ }
81
+ invalidateObjects(objects) {
82
+ return this.__experimentalStore.invalidateObjects(objects);
83
+ }
84
+ invalidateObjectType(type) {
85
+ return this.__experimentalStore.invalidateObjectType(type, void 0);
86
+ }
87
+ canonicalizeWhereClause(where) {
88
+ return this.__experimentalStore.whereCanonicalizer.canonicalize(where);
30
89
  }
31
90
  };
32
91
 
@@ -47,7 +106,7 @@ function createOptimisticId() {
47
106
  return /* @__PURE__ */ Object.create(null);
48
107
  }
49
108
 
50
- // src/observable/internal/OptimisticJob.ts
109
+ // src/observable/internal/actions/OptimisticJob.ts
51
110
  var OptimisticJob = class {
52
111
  #result;
53
112
  constructor(store, optimisticId) {
@@ -64,16 +123,25 @@ var OptimisticJob = class {
64
123
  }, (batch) => {
65
124
  for (const obj of addedObjects) {
66
125
  if (obj.status === "fulfilled") {
67
- store.getObjectQuery(obj.value.$objectType, obj.value.$primaryKey).writeToStore(obj.value, "loading", batch);
126
+ store.objects.getQuery({
127
+ apiName: obj.value.$objectType,
128
+ pk: obj.value.$primaryKey
129
+ }).writeToStore(obj.value, "loading", batch);
68
130
  } else {
69
131
  throw obj;
70
132
  }
71
133
  }
72
134
  for (const obj of updatedObjects) {
73
- store.getObjectQuery(obj.$objectType, obj.$primaryKey).writeToStore(obj, "loading", batch);
135
+ store.objects.getQuery({
136
+ apiName: obj.$objectType,
137
+ pk: obj.$primaryKey
138
+ }).writeToStore(obj, "loading", batch);
74
139
  }
75
140
  for (const obj of deletedObjects) {
76
- store.getObjectQuery(obj.$objectType, obj.$primaryKey).deleteFromStore("loading", batch);
141
+ store.objects.getQuery({
142
+ apiName: obj.$objectType,
143
+ pk: obj.$primaryKey
144
+ }).deleteFromStore("loading", batch);
77
145
  }
78
146
  });
79
147
  return batchResult.changes;
@@ -85,7 +153,7 @@ var OptimisticJob = class {
85
153
  return this;
86
154
  },
87
155
  createObject(type, pk, properties) {
88
- const create = store.client[chunk633AI7EA_cjs.additionalContext].objectFactory2(store.client[chunk633AI7EA_cjs.additionalContext], [{
156
+ const create = store.client[chunkGVGP7T5P_cjs.additionalContext].objectFactory2(store.client[chunkGVGP7T5P_cjs.additionalContext], [{
89
157
  $primaryKey: pk,
90
158
  $apiName: type.apiName,
91
159
  $objectType: type.apiName,
@@ -116,12 +184,12 @@ function runOptimisticJob(store, optimisticUpdate) {
116
184
  // we don't want to leak the result
117
185
  () => void 0
118
186
  ).finally(() => {
119
- store.removeLayer(optimisticId);
187
+ store.layers.remove(optimisticId);
120
188
  });
121
189
  };
122
190
  }
123
191
 
124
- // src/observable/internal/ActionApplication.ts
192
+ // src/observable/internal/actions/ActionApplication.ts
125
193
  var ACTION_DELAY = process.env.NODE_ENV === "production" ? 0 : 1e3;
126
194
  var ActionApplication = class {
127
195
  constructor(store) {
@@ -187,8 +255,8 @@ var ActionApplication = class {
187
255
  objectType,
188
256
  primaryKey
189
257
  } of deletedObjects ?? []) {
190
- const cacheKey = this.store.getCacheKey("object", objectType, primaryKey);
191
- this.store.peekQuery(cacheKey)?.deleteFromStore(
258
+ const cacheKey = this.store.cacheKeys.get("object", objectType, primaryKey);
259
+ this.store.queries.peek(cacheKey)?.deleteFromStore(
192
260
  "loaded",
193
261
  // this is probably not the best value to use
194
262
  batch
@@ -203,39 +271,110 @@ var ActionApplication = class {
203
271
  }
204
272
  };
205
273
  };
274
+
275
+ // src/observable/internal/RefCounts.ts
276
+ var RefCounts = class {
277
+ refCounts = /* @__PURE__ */ new Map();
278
+ // keeps our objects around for some extended duration after they are no longer
279
+ // needed which is good for quick clicks across tabs.
280
+ gcMap = /* @__PURE__ */ new Map();
281
+ constructor(keepAlive, cleanup) {
282
+ this.keepAlive = keepAlive;
283
+ this.cleanup = cleanup;
284
+ }
285
+ register(key) {
286
+ if (!this.refCounts.has(key)) {
287
+ this.gcMap.set(key, Date.now() + this.keepAlive);
288
+ }
289
+ return key;
290
+ }
291
+ retain(key) {
292
+ const count = this.refCounts.get(key) ?? 0;
293
+ this.refCounts.set(key, count + 1);
294
+ if (this.gcMap.has(key)) {
295
+ this.gcMap.delete(key);
296
+ }
297
+ }
298
+ release(key) {
299
+ const count = this.refCounts.get(key);
300
+ if (count === void 0) ; else if (count === 1) {
301
+ this.refCounts.delete(key);
302
+ this.gcMap.set(key, Date.now() + this.keepAlive);
303
+ } else {
304
+ this.refCounts.set(key, count - 1);
305
+ }
306
+ }
307
+ has(key) {
308
+ return this.refCounts.has(key);
309
+ }
310
+ gc() {
311
+ const now = Date.now();
312
+ for (const [key, deathTime] of this.gcMap) {
313
+ if (deathTime < now) {
314
+ this.gcMap.delete(key);
315
+ this.cleanup(key);
316
+ }
317
+ }
318
+ }
319
+ };
320
+
321
+ // src/observable/internal/CacheKeys.ts
206
322
  var CacheKeys = class {
207
323
  #cacheKeys = new trie.Trie(false, (keys) => {
208
- const ret = {
324
+ const cacheKey = {
209
325
  type: keys[0],
210
326
  otherKeys: keys.slice(1)
211
327
  };
212
- this.#onCreate(ret);
213
- return ret;
328
+ this.#onCreate?.(cacheKey);
329
+ return cacheKey;
214
330
  });
215
- #cacheKeyFactories = /* @__PURE__ */ new Map();
331
+ #refCounts = new RefCounts(6e4, (k) => this.#cleanupCacheKey(k));
332
+ // we are currently only using this for debug logging and should just remove it in the future if that
333
+ // continues to be true
334
+ #finalizationRegistry;
216
335
  #onCreate;
217
- constructor(whereCanonicalizer, orderByCanonicalizer, onCreate) {
336
+ #onDestroy;
337
+ constructor({
338
+ onCreate,
339
+ onDestroy
340
+ }) {
218
341
  this.#onCreate = onCreate;
219
- this.#registerCacheKeyFactory("object", (apiName, pk) => {
220
- if (process.env.NODE_ENV !== "production" && DEBUG_CACHE_KEYS) ;
221
- return this.#cacheKeys.lookupArray(["object", apiName, pk]);
222
- });
223
- this.#registerCacheKeyFactory("list", (type, apiName, where, orderBy) => {
224
- if (process.env.NODE_ENV !== "production" && DEBUG_CACHE_KEYS) ;
225
- return this.#cacheKeys.lookupArray(["list", type, apiName, whereCanonicalizer.canonicalize(where), orderByCanonicalizer.canonicalize(orderBy)]);
342
+ this.#onDestroy = onDestroy;
343
+ setInterval(() => {
344
+ this.#refCounts.gc();
345
+ }, 1e3);
346
+ this.#finalizationRegistry = new FinalizationRegistry((cleanupCallback) => {
347
+ try {
348
+ cleanupCallback();
349
+ } catch (e) {
350
+ console.error("Caught an error while running a finalization callback", e);
351
+ }
226
352
  });
227
353
  }
228
- #registerCacheKeyFactory(type, factory) {
229
- this.#cacheKeyFactories.set(type, factory);
230
- }
231
354
  get(type, ...args) {
232
- const factory = this.#cacheKeyFactories.get(type);
233
- !factory ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, `no cache key factory for type "${type}"`) : invariant2__default.default(false) : void 0;
234
- return factory(...args);
355
+ const cacheKeyArgs = [type, ...args];
356
+ if (process.env.NODE_ENV !== "production" && DEBUG_CACHE_KEYS) ;
357
+ const cacheKey = this.#cacheKeys.lookupArray(cacheKeyArgs);
358
+ this.#refCounts.register(cacheKey);
359
+ return cacheKey;
360
+ }
361
+ retain(cacheKey) {
362
+ this.#refCounts.retain(cacheKey);
363
+ }
364
+ release(cacheKey) {
365
+ this.#refCounts.release(cacheKey);
235
366
  }
236
- remove(cacheKey) {
367
+ #remove(cacheKey) {
237
368
  this.#cacheKeys.remove(cacheKey.type, ...cacheKey.otherKeys);
238
369
  }
370
+ /**
371
+ * Called after a key is no longer retained and the timeout has elapsed
372
+ * @param key
373
+ */
374
+ #cleanupCacheKey = (key) => {
375
+ this.#onDestroy?.(key);
376
+ this.#remove(key);
377
+ };
239
378
  };
240
379
 
241
380
  // src/observable/internal/CacheKey.ts
@@ -271,6 +410,12 @@ var Changes = class {
271
410
  registerList = (key) => {
272
411
  this.modified.add(key);
273
412
  };
413
+ registerLink = (cacheKey) => {
414
+ this.modified.add(cacheKey);
415
+ };
416
+ deleteLink = (cacheKey) => {
417
+ this.deleted.add(cacheKey);
418
+ };
274
419
  isEmpty() {
275
420
  return this.modifiedObjects.size === 0 && this.addedObjects.size === 0 && this.added.size === 0 && this.modified.size === 0 && this.deleted.size === 0;
276
421
  }
@@ -299,6 +444,16 @@ function multimapHelper(multimap) {
299
444
  }));
300
445
  }
301
446
 
447
+ // src/observable/internal/createInitEntry.ts
448
+ function createInitEntry(cacheKey) {
449
+ return {
450
+ cacheKey,
451
+ status: "init",
452
+ value: void 0,
453
+ lastUpdated: 0
454
+ };
455
+ }
456
+
302
457
  // src/observable/internal/WeakMapWithEntries.ts
303
458
  var WeakMapWithEntries = class {
304
459
  #map = /* @__PURE__ */ new WeakMap();
@@ -446,197 +601,240 @@ var Layer = class _Layer {
446
601
  this.#cache.set(cacheKey, value);
447
602
  }
448
603
  };
449
- var Entry = class {
450
- constructor(cacheKey, value, lastUpdated, status = "init") {
451
- this.cacheKey = cacheKey;
452
- this.value = value;
453
- this.lastUpdated = lastUpdated;
454
- this.status = status;
455
- }
456
- };
457
- function is$and(whereClause) {
458
- if (process.env.NODE_ENV !== "production") {
459
- if ("$and" in whereClause) {
460
- !Array.isArray(whereClause.$and) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected $and to be an array") : invariant2__default.default(false) : void 0;
461
- !(Object.keys(whereClause).length === 1) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected only $and to be present") : invariant2__default.default(false) : void 0;
462
- }
604
+ var Subjects = class {
605
+ #layers;
606
+ // we can use a regular Map here because the refCounting will
607
+ // handle cleanup.
608
+ #cacheKeyToSubject = /* @__PURE__ */ new WeakMap();
609
+ constructor({
610
+ logger,
611
+ layers
612
+ }) {
613
+ this.logger = logger;
614
+ this.#layers = layers;
463
615
  }
464
- return "$and" in whereClause;
465
- }
466
- function is$or(whereClause) {
467
- if (process.env.NODE_ENV !== "production") {
468
- if ("$or" in whereClause) {
469
- !Array.isArray(whereClause.$or) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected $or to be an array") : invariant2__default.default(false) : void 0;
470
- !(Object.keys(whereClause).length === 1) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected only $or to be present") : invariant2__default.default(false) : void 0;
616
+ peek = (cacheKey) => {
617
+ return this.#cacheKeyToSubject.get(cacheKey);
618
+ };
619
+ get = (cacheKey) => {
620
+ let subject = this.#cacheKeyToSubject.get(cacheKey);
621
+ if (!subject) {
622
+ const initialValue = this.#layers.top.get(cacheKey) ?? createInitEntry(cacheKey);
623
+ subject = new rxjs.BehaviorSubject({
624
+ ...initialValue,
625
+ isOptimistic: initialValue.value !== this.#layers.truth.get(cacheKey)?.value
626
+ });
627
+ this.#cacheKeyToSubject.set(cacheKey, subject);
471
628
  }
472
- }
473
- return "$or" in whereClause;
474
- }
475
- function is$not(whereClause) {
476
- if (process.env.NODE_ENV !== "production") {
477
- if ("$not" in whereClause) {
478
- !(Object.keys(whereClause).length === 1) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected only $not to be present") : invariant2__default.default(false) : void 0;
629
+ return subject;
630
+ };
631
+ delete = (cacheKey) => {
632
+ const subject = this.peek(cacheKey);
633
+ if (subject) {
634
+ subject.complete();
635
+ this.#cacheKeyToSubject.delete(cacheKey);
479
636
  }
637
+ };
638
+ };
639
+
640
+ // src/observable/internal/tombstone.ts
641
+ var tombstone = void 0;
642
+
643
+ // src/observable/internal/Layers.ts
644
+ var Layers = class {
645
+ #truthLayer = new Layer(void 0, void 0);
646
+ #topLayer;
647
+ #onRevalidate;
648
+ constructor({
649
+ logger,
650
+ onRevalidate
651
+ }) {
652
+ this.logger = logger;
653
+ this.#topLayer = this.#truthLayer;
654
+ this.subjects = new Subjects({
655
+ logger,
656
+ layers: this
657
+ });
658
+ this.#onRevalidate = onRevalidate;
480
659
  }
481
- return "$not" in whereClause;
482
- }
483
- function objectSortaMatchesWhereClause(o, whereClause, strict) {
484
- if (deepEqual2__default.default({}, whereClause)) {
485
- return true;
486
- }
487
- if (is$and(whereClause)) {
488
- return whereClause.$and.every((w) => objectSortaMatchesWhereClause(o, w, strict));
489
- }
490
- if (is$or(whereClause)) {
491
- return whereClause.$or.some((w) => objectSortaMatchesWhereClause(o, w, strict));
660
+ get top() {
661
+ return this.#topLayer;
492
662
  }
493
- if (is$not(whereClause)) {
494
- return !objectSortaMatchesWhereClause(o, whereClause.$not, strict);
663
+ get truth() {
664
+ return this.#truthLayer;
495
665
  }
496
- return Object.entries(whereClause).every(([key, filter]) => {
497
- if (typeof filter === "object") {
498
- const realValue = o[key];
499
- const [f] = Object.keys(filter);
500
- const expected = filter[f];
501
- switch (f) {
502
- case "$eq":
503
- return realValue === expected;
504
- case "$gt":
505
- return realValue > expected;
506
- case "$lt":
507
- return realValue < expected;
508
- case "$gte":
509
- return realValue >= expected;
510
- case "$lte":
511
- return realValue <= expected;
512
- case "$ne":
513
- return realValue !== expected;
514
- case "$in":
515
- return expected.$in.includes(realValue);
516
- case "$isNull":
517
- return realValue == null;
518
- case "$startsWith":
519
- return realValue.startsWith(expected);
520
- case "$contains":
521
- case "$containsAllTerms":
522
- case "$containsAllTermsInOrder":
523
- case "$containsAnyTerm":
524
- case "$intersects":
525
- case "$within":
526
- return !strict;
527
- default:
528
- if (process.env.NODE_ENV !== "production") {
529
- process.env.NODE_ENV !== "production" ? invariant2__default.default(false, `Unknown where filter ${f}`) : invariant2__default.default(false) ;
530
- }
531
- return !strict;
666
+ remove(layerId) {
667
+ !(layerId != null) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "undefined is the reserved layerId for the truth layer") : invariant2__default.default(false) : void 0;
668
+ let currentLayer = this.#topLayer;
669
+ const cacheKeys = /* @__PURE__ */ new Map();
670
+ while (currentLayer != null && currentLayer.parentLayer != null) {
671
+ if (currentLayer.layerId === layerId) {
672
+ for (const [k, v] of currentLayer.entries()) {
673
+ if (cacheKeys.has(k)) continue;
674
+ cacheKeys.set(k, v);
675
+ }
532
676
  }
677
+ currentLayer = currentLayer.parentLayer;
533
678
  }
534
- if (key in o) {
535
- if (o[key] === filter) {
536
- return true;
679
+ this.#topLayer = this.#topLayer.removeLayer(layerId);
680
+ for (const [k, oldEntry] of cacheKeys) {
681
+ const currentEntry = this.#topLayer.get(k);
682
+ if (oldEntry !== currentEntry) {
683
+ const newEntry = currentEntry ?? createInitEntry(k);
684
+ this.subjects.peek(k)?.next({
685
+ ...newEntry,
686
+ isOptimistic: currentEntry?.value !== this.#truthLayer.get(k)?.value
687
+ });
537
688
  }
538
689
  }
539
- return false;
540
- });
541
- }
542
-
543
- // ../../node_modules/.pnpm/p-defer@4.0.1/node_modules/p-defer/index.js
544
- function pDefer() {
545
- const deferred = {};
546
- deferred.promise = new Promise((resolve, reject) => {
547
- deferred.resolve = resolve;
548
- deferred.reject = reject;
549
- });
550
- return deferred;
551
- }
552
-
553
- // src/observable/internal/BulkObjectLoader.ts
554
- var weakCache = new mnemonist.DefaultWeakMap((c) => new BulkObjectLoader(c));
555
- function getBulkObjectLoader(client) {
556
- return weakCache.get(client);
557
- }
558
- var BulkObjectLoader = class {
559
- #client;
560
- #m = new mnemonist.DefaultMap(() => ({
561
- data: [],
562
- timer: void 0
563
- }));
564
- #logger;
565
- #maxWait;
566
- #maxEntries;
567
- constructor(client, maxWait = 25, maxEntries = 100) {
568
- this.#client = client;
569
- this.#logger = client[chunk633AI7EA_cjs.additionalContext].logger;
570
- this.#maxWait = maxWait;
571
- this.#maxEntries = maxEntries;
572
690
  }
573
- fetch(apiName, primaryKey) {
574
- const deferred = pDefer();
575
- const entry = this.#m.get(apiName);
576
- entry.data.push({
577
- primaryKey,
578
- deferred
691
+ batch({
692
+ optimisticId,
693
+ changes
694
+ }, batchFn) {
695
+ !(optimisticId === void 0 || !!optimisticId) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "optimistic must be undefined or not falsy") : invariant2__default.default(false) : void 0;
696
+ const batchContext = this.#createBatchContext({
697
+ optimisticId,
698
+ changes
579
699
  });
580
- if (!entry.timer) {
581
- entry.timer = setTimeout(() => {
582
- this.#loadObjects(apiName, entry.data);
583
- }, this.#maxWait);
584
- }
585
- if (entry.data.length >= this.#maxEntries) {
586
- clearTimeout(entry.timer);
587
- this.#loadObjects(apiName, entry.data);
588
- }
589
- return deferred.promise;
590
- }
591
- #loadObjects(apiName, arr) {
592
- this.#m.delete(apiName);
593
- this.#reallyLoadObjects(apiName, arr).catch((e) => {
594
- this.#logger?.error("Unhandled exception", e);
700
+ const retVal = batchFn(batchContext);
701
+ this.#onRevalidate(changes, optimisticId).catch((e) => {
702
+ if (this.logger) {
703
+ this.logger.error("Unhandled error in batch", e);
704
+ } else {
705
+ console.error("Unhandled error in batch", e);
706
+ throw e;
707
+ }
595
708
  });
709
+ return {
710
+ batchResult: batchContext,
711
+ retVal,
712
+ changes: batchContext.changes
713
+ };
596
714
  }
597
- async #reallyLoadObjects(apiName, arr) {
598
- const miniDef = {
599
- type: "object",
600
- apiName
715
+ #createBatchContext({
716
+ optimisticId,
717
+ changes
718
+ }) {
719
+ let needsLayer = optimisticId !== void 0;
720
+ const batchContext = {
721
+ changes,
722
+ createLayerIfNeeded: () => {
723
+ if (needsLayer) {
724
+ this.#topLayer = this.#topLayer.addLayer(optimisticId);
725
+ needsLayer = false;
726
+ }
727
+ },
728
+ optimisticWrite: !!optimisticId,
729
+ write: (cacheKey, value, status) => {
730
+ const oldTopValue = this.#topLayer.get(cacheKey);
731
+ if (optimisticId) batchContext.createLayerIfNeeded();
732
+ const writeLayer = optimisticId ? this.#topLayer : this.#truthLayer;
733
+ const newValue = {
734
+ cacheKey,
735
+ value,
736
+ lastUpdated: Date.now(),
737
+ status
738
+ };
739
+ writeLayer.set(cacheKey, newValue);
740
+ const newTopValue = this.#topLayer.get(cacheKey);
741
+ if (oldTopValue !== newTopValue) {
742
+ this.subjects.get(cacheKey)?.next({
743
+ ...newValue,
744
+ isOptimistic: newTopValue?.value !== this.#truthLayer.get(cacheKey)?.value
745
+ });
746
+ }
747
+ return newValue;
748
+ },
749
+ delete: (cacheKey, status) => {
750
+ return batchContext.write(cacheKey, tombstone, status);
751
+ },
752
+ read: (cacheKey) => {
753
+ return optimisticId ? this.#topLayer.get(cacheKey) : this.#truthLayer.get(cacheKey);
754
+ }
601
755
  };
602
- const objMetadata = await this.#client.fetchMetadata(miniDef);
603
- const pks = arr.map((x) => x.primaryKey);
604
- const {
605
- data
606
- } = await this.#client(miniDef).where({
607
- [objMetadata.primaryKeyApiName]: {
608
- $in: pks
756
+ return batchContext;
757
+ }
758
+ };
759
+
760
+ // src/observable/internal/QuerySubscription.ts
761
+ var subscriptionIdCounter = 0;
762
+ var QuerySubscription = class extends UnsubscribableWrapper {
763
+ /** @internal */
764
+ /** @internal */
765
+ /** @internal */
766
+ constructor(query, subscription) {
767
+ super(subscription);
768
+ this.query = query;
769
+ this.subscription = subscription;
770
+ this.subscriptionId = `sub_${++subscriptionIdCounter}`;
771
+ Object.defineProperties(this, {
772
+ query: {
773
+ enumerable: false
774
+ },
775
+ subscription: {
776
+ enumerable: false
777
+ },
778
+ subscriptionId: {
779
+ enumerable: false
609
780
  }
610
- }).fetchPage({
611
- $pageSize: pks.length
612
781
  });
613
- for (const {
614
- primaryKey,
615
- deferred
616
- } of arr) {
617
- const object = data.find((x) => x.$primaryKey === primaryKey);
618
- if (object) {
619
- deferred.resolve(object);
620
- } else {
621
- deferred.reject(new shared_net_errors.PalantirApiError("Object not found"));
622
- }
782
+ }
783
+ };
784
+
785
+ // src/observable/internal/AbstractHelper.ts
786
+ var AbstractHelper = class {
787
+ constructor(store, cacheKeys) {
788
+ this.store = store;
789
+ this.cacheKeys = cacheKeys;
790
+ }
791
+ observe(options, subFn) {
792
+ const query = this.getQuery(options);
793
+ return this._subscribe(query, options, subFn);
794
+ }
795
+ _subscribe(query, options, subFn) {
796
+ this.store.cacheKeys.retain(query.cacheKey);
797
+ if (options.mode !== "offline") {
798
+ query.revalidate(options.mode === "force").catch((e) => {
799
+ subFn.error(e);
800
+ if (this.store.logger) {
801
+ this.store.logger.error("Unhandled error in observeObject", e);
802
+ } else {
803
+ throw e;
804
+ }
805
+ });
623
806
  }
807
+ const sub = query.subscribe(subFn);
808
+ const querySub = new QuerySubscription(query, sub);
809
+ query.registerSubscriptionDedupeInterval(querySub.subscriptionId, options.dedupeInterval);
810
+ sub.add(() => {
811
+ query.unregisterSubscriptionDedupeInterval(querySub.subscriptionId);
812
+ this.store.cacheKeys.release(query.cacheKey);
813
+ });
814
+ return querySub;
624
815
  }
625
816
  };
626
817
 
818
+ // src/observable/internal/isObjectInstance.ts
819
+ function isObjectInstance(item) {
820
+ return item != null && typeof item === "object" && "$primaryKey" in item;
821
+ }
822
+
627
823
  // src/observable/internal/Query.ts
628
824
  var Query = class {
629
825
  retainCount = 0;
630
826
  #connectable;
631
827
  #subscription;
632
828
  #subject;
829
+ #subscriptionDedupeIntervals = /* @__PURE__ */ new Map();
633
830
  /** @internal */
634
831
  constructor(store, observable, opts, cacheKey, logger) {
635
832
  this.options = opts;
636
833
  this.cacheKey = cacheKey;
637
834
  this.store = store;
835
+ this.cacheKeys = store.cacheKeys;
638
836
  this.#subject = observable;
639
- this.logger = logger ?? (process.env.NODE_ENV === "production" ? store.client[chunk633AI7EA_cjs.additionalContext].logger : store.client[chunk633AI7EA_cjs.additionalContext].logger?.child({}, {
837
+ this.logger = logger ?? (process.env.NODE_ENV === "production" ? store.client[chunkGVGP7T5P_cjs.additionalContext].logger : store.client[chunkGVGP7T5P_cjs.additionalContext].logger?.child({}, {
640
838
  msgPrefix: process.env.NODE_ENV !== "production" ? `Query<${cacheKey.type}, ${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>` : "Query"
641
839
  }));
642
840
  }
@@ -645,6 +843,29 @@ var Query = class {
645
843
  this.#subscription = this.#connectable.connect();
646
844
  return this.#connectable.subscribe(observer);
647
845
  }
846
+ /**
847
+ * Register a subscription's dedupeInterval value
848
+ */
849
+ registerSubscriptionDedupeInterval(subscriptionId, dedupeInterval) {
850
+ if (dedupeInterval != null && dedupeInterval > 0) {
851
+ this.#subscriptionDedupeIntervals.set(subscriptionId, dedupeInterval);
852
+ }
853
+ }
854
+ /**
855
+ * Unregister a subscription's dedupeInterval value
856
+ */
857
+ unregisterSubscriptionDedupeInterval(subscriptionId) {
858
+ this.#subscriptionDedupeIntervals.delete(subscriptionId);
859
+ }
860
+ /**
861
+ * Get the minimum dedupeInterval from all active subscriptions
862
+ */
863
+ getMinimumDedupeInterval() {
864
+ if (this.#subscriptionDedupeIntervals.size === 0) {
865
+ return this.options.dedupeInterval ?? 0;
866
+ }
867
+ return Math.min(...this.#subscriptionDedupeIntervals.values());
868
+ }
648
869
  /**
649
870
  * Causes the query to revalidate. This will cause the query to fetch
650
871
  * the latest data from the server and update the store if it is deemed
@@ -667,7 +888,8 @@ var Query = class {
667
888
  await this.pendingFetch;
668
889
  return;
669
890
  }
670
- if ((this.options.dedupeInterval ?? 0) > 0 && this.lastFetchStarted != null && Date.now() - this.lastFetchStarted < (this.options.dedupeInterval ?? 0)) {
891
+ const minDedupeInterval = this.getMinimumDedupeInterval();
892
+ if (minDedupeInterval > 0 && this.lastFetchStarted != null && Date.now() - this.lastFetchStarted < minDedupeInterval) {
671
893
  if (process.env.NODE_ENV !== "production") {
672
894
  logger?.debug("Within dupeInterval, aborting revalidate");
673
895
  }
@@ -685,7 +907,7 @@ var Query = class {
685
907
  logger?.debug("calling _fetchAndStore()");
686
908
  }
687
909
  this.pendingFetch = this._fetchAndStore().finally(() => {
688
- logger?.debug("finally _fetchAndStore()");
910
+ logger?.debug("promise's finally for _fetchAndStore()");
689
911
  this.pendingFetch = void 0;
690
912
  });
691
913
  await this.pendingFetch;
@@ -704,10 +926,22 @@ var Query = class {
704
926
  if (process.env.NODE_ENV !== "production") {
705
927
  this.logger?.child({
706
928
  methodName: "setStatus"
707
- }).debug(status);
929
+ }).debug(`Attempting to set status to '${status}'`);
708
930
  }
709
931
  const existing = batch.read(this.cacheKey);
710
- if (existing?.status === status) return;
932
+ if (existing?.status === status) {
933
+ if (process.env.NODE_ENV !== "production") {
934
+ this.logger?.child({
935
+ methodName: "setStatus"
936
+ }).debug(`Status is already set to '${status}'; aborting`);
937
+ }
938
+ return;
939
+ }
940
+ if (process.env.NODE_ENV !== "production") {
941
+ this.logger?.child({
942
+ methodName: "setStatus"
943
+ }).debug(`Writing status '${status}' to cache`);
944
+ }
711
945
  batch.write(this.cacheKey, existing?.value, status);
712
946
  }
713
947
  dispose() {
@@ -738,167 +972,191 @@ var Query = class {
738
972
  */
739
973
  };
740
974
 
741
- // src/observable/internal/tombstone.ts
742
- var tombstone = void 0;
743
-
744
- // src/observable/internal/ObjectQuery.ts
745
- var ObjectQuery = class extends Query {
746
- #apiName;
747
- #pk;
748
- constructor(store, subject, type, pk, cacheKey, opts) {
749
- super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[chunk633AI7EA_cjs.additionalContext].logger?.child({}, {
750
- msgPrefix: `ObjectQuery<${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>`
751
- }) : void 0);
752
- this.#apiName = type;
753
- this.#pk = pk;
975
+ // src/observable/internal/sorting/SortingStrategy.ts
976
+ var NoOpSortingStrategy = class {
977
+ sortCacheKeys(objectCacheKeys, _batch) {
978
+ return objectCacheKeys;
754
979
  }
755
- _createConnectable(subject) {
756
- return rxjs.connectable(subject.pipe(rxjs.map((x) => {
757
- return {
758
- status: x.status,
759
- object: x.value,
760
- lastUpdated: x.lastUpdated,
761
- isOptimistic: x.isOptimistic
762
- };
763
- })), {
764
- connector: () => new rxjs.BehaviorSubject({
765
- status: "init",
766
- object: void 0,
767
- lastUpdated: 0,
768
- isOptimistic: false
769
- })
980
+ };
981
+ var OrderBySortingStrategy = class {
982
+ constructor(apiName, orderBy) {
983
+ this.apiName = apiName;
984
+ this.orderBy = orderBy;
985
+ this.sortFns = createOrderBySortFns(orderBy);
986
+ }
987
+ sortCacheKeys(objectCacheKeys, batch) {
988
+ if (Object.keys(this.orderBy).length === 0) {
989
+ return objectCacheKeys;
990
+ }
991
+ return objectCacheKeys.sort((a, b) => {
992
+ for (const sortFn of this.sortFns) {
993
+ const ret = sortFn(batch.read(a)?.value?.$as(this.apiName), batch.read(b)?.value?.$as(this.apiName));
994
+ if (ret !== 0) {
995
+ return ret;
996
+ }
997
+ }
998
+ return 0;
770
999
  });
771
1000
  }
772
- async _fetchAndStore() {
1001
+ };
1002
+ function createOrderBySortFns(orderBy) {
1003
+ return Object.entries(orderBy).map(([key, order]) => {
1004
+ return (a, b) => {
1005
+ const aValue = a?.[key];
1006
+ const bValue = b?.[key];
1007
+ if (aValue == null && bValue == null) {
1008
+ return 0;
1009
+ }
1010
+ if (aValue == null) {
1011
+ return 1;
1012
+ }
1013
+ if (bValue == null) {
1014
+ return -1;
1015
+ }
1016
+ const m = order === "asc" ? -1 : 1;
1017
+ return aValue < bValue ? m : aValue > bValue ? -m : 0;
1018
+ };
1019
+ });
1020
+ }
1021
+ function createCollectionConnectable(subject, subjects, createPayload) {
1022
+ return rxjs.connectable(subject.pipe(rxjs.switchMap((listEntry) => {
1023
+ const resolvedData = listEntry?.value?.data == null || listEntry.value.data.length === 0 ? rxjs.of([]) : rxjs.combineLatest(listEntry.value.data.map((cacheKey) => subjects.get(cacheKey).pipe(rxjs.map((objectEntry) => objectEntry?.value), rxjs.distinctUntilChanged())));
1024
+ return rxjs.scheduled(rxjs.combineLatest({
1025
+ resolvedData,
1026
+ isOptimistic: rxjs.of(listEntry.isOptimistic),
1027
+ status: rxjs.of(listEntry.status),
1028
+ lastUpdated: rxjs.of(listEntry.lastUpdated)
1029
+ }).pipe(rxjs.map((params) => createPayload({
1030
+ resolvedData: Array.isArray(params.resolvedData) ? params.resolvedData : [],
1031
+ isOptimistic: params.isOptimistic,
1032
+ status: params.status,
1033
+ lastUpdated: params.lastUpdated
1034
+ }))), rxjs.asapScheduler);
1035
+ })), {
1036
+ resetOnDisconnect: false,
1037
+ connector: () => new rxjs.ReplaySubject(1)
1038
+ });
1039
+ }
1040
+
1041
+ // src/observable/internal/base-list/removeDuplicates.ts
1042
+ function removeDuplicates(objectCacheKeys, batch) {
1043
+ const visited = /* @__PURE__ */ new Set();
1044
+ return objectCacheKeys.filter((key) => {
1045
+ batch.read(key);
1046
+ if (visited.has(key)) {
1047
+ return false;
1048
+ }
1049
+ visited.add(key);
1050
+ return true;
1051
+ });
1052
+ }
1053
+
1054
+ // src/observable/internal/base-list/BaseListQuery.ts
1055
+ var BaseListQuery = class extends Query {
1056
+ /**
1057
+ * The sorting strategy to use for this collection
1058
+ * @protected
1059
+ */
1060
+ sortingStrategy = new NoOpSortingStrategy();
1061
+ // Collection-specific behavior is implemented by subclasses
1062
+ /**
1063
+ * Token for the next page of results
1064
+ * @protected
1065
+ */
1066
+ /**
1067
+ * Promise tracking an in-progress page fetch
1068
+ * @protected
1069
+ */
1070
+ //
1071
+ // Shared Implementations
1072
+ //
1073
+ /**
1074
+ * Standard method to update a list of objects
1075
+ * Handles common list update patterns for both ListQuery and SpecificLinkQuery
1076
+ *
1077
+ * @param items Objects or cache keys to add to the list
1078
+ * @param status Status to set for the list
1079
+ * @param batch Batch context to use
1080
+ * @param append Whether to append to the existing list or replace it
1081
+ * @returns The updated entry
1082
+ */
1083
+ _updateList(items, status, batch, append = false) {
773
1084
  if (process.env.NODE_ENV !== "production") {
774
1085
  this.logger?.child({
775
- methodName: "_fetchAndStore"
776
- }).debug("calling _fetchAndStore");
1086
+ methodName: "updateList"
1087
+ }).debug(`{status: ${status}, append: ${append}}`, JSON.stringify(items, null, 2));
777
1088
  }
778
- const obj = await getBulkObjectLoader(this.store.client).fetch(this.#apiName, this.#pk);
779
- this.store.batch({}, (batch) => {
780
- this.writeToStore(obj, "loaded", batch);
781
- });
1089
+ let objectCacheKeys;
1090
+ if (items.length === 0) {
1091
+ objectCacheKeys = [];
1092
+ } else if (isObjectInstance(items[0])) {
1093
+ objectCacheKeys = this.store.objects.storeOsdkInstances(items, batch);
1094
+ } else {
1095
+ objectCacheKeys = items;
1096
+ }
1097
+ objectCacheKeys = this.#retainReleaseAppend(batch, append, objectCacheKeys);
1098
+ objectCacheKeys = this._sortCacheKeys(objectCacheKeys, batch);
1099
+ objectCacheKeys = removeDuplicates(objectCacheKeys, batch);
1100
+ return this.writeToStore({
1101
+ data: objectCacheKeys
1102
+ }, status, batch);
782
1103
  }
1104
+ /**
1105
+ * Common implementation for writing to store for collection-based queries
1106
+ * @param data The collection data to write to the store
1107
+ * @param status The status to set
1108
+ * @param batch The batch context
1109
+ */
783
1110
  writeToStore(data, status, batch) {
784
1111
  const entry = batch.read(this.cacheKey);
785
- if (entry && deepEqual2__default.default(data, entry.value)) {
1112
+ if (entry && deepEqual4__default.default(data, entry.value)) {
1113
+ if (entry.status === status) {
1114
+ if (process.env.NODE_ENV !== "production") {
1115
+ this.logger?.child({
1116
+ methodName: "writeToStore"
1117
+ }).debug(`Collection data was deep equal and status unchanged (${status}), skipping update`);
1118
+ }
1119
+ return entry;
1120
+ }
786
1121
  if (process.env.NODE_ENV !== "production") {
787
1122
  this.logger?.child({
788
1123
  methodName: "writeToStore"
789
- }).debug(`Object was deep equal, just setting status`);
1124
+ }).debug(`Collection data was deep equal, just updating status from ${entry.status} to ${status}`);
790
1125
  }
791
1126
  return batch.write(this.cacheKey, entry.value, status);
792
1127
  }
793
1128
  if (process.env.NODE_ENV !== "production") {
794
1129
  this.logger?.child({
795
1130
  methodName: "writeToStore"
796
- }).debug(JSON.stringify({
797
- status
798
- }), data);
1131
+ }).debug(`{status: ${status}},`, DEBUG_ONLY__cacheKeysToString(data.data));
799
1132
  }
800
1133
  const ret = batch.write(this.cacheKey, data, status);
801
- batch.changes.registerObject(
802
- this.cacheKey,
803
- data,
804
- /* isNew */
805
- !entry
806
- );
1134
+ this.registerCacheChanges(batch);
807
1135
  return ret;
808
1136
  }
809
- deleteFromStore(status, batch) {
810
- const entry = batch.read(this.cacheKey);
811
- if (entry && deepEqual2__default.default(tombstone, entry.value)) {
812
- if (process.env.NODE_ENV !== "production") {
813
- this.logger?.child({
814
- methodName: "deleteFromStore"
815
- }).debug(`Object was deep equal, just setting status`);
816
- }
817
- return batch.write(this.cacheKey, entry.value, status);
818
- }
819
- if (process.env.NODE_ENV !== "production") {
820
- this.logger?.child({
821
- methodName: "deleteFromStore"
822
- }).debug(JSON.stringify({
823
- status
824
- }));
825
- }
826
- if (!entry || !entry.value) {
827
- return;
828
- }
829
- const ret = batch.delete(this.cacheKey, status);
830
- batch.changes.deleteObject(this.cacheKey);
831
- return ret;
832
- }
833
- };
834
- function storeOsdkInstances(store, values, batch) {
835
- return values.map((v) => {
836
- return store.getObjectQuery(v.$apiName, v.$primaryKey).writeToStore(v, "loaded", batch).cacheKey;
837
- });
838
- }
839
-
840
- // src/observable/internal/ListQuery.ts
841
- var API_NAME_IDX = 1;
842
- var BaseListQuery = class extends Query {
843
- //
844
- // Per list type implementations
845
- //
846
- //
847
- // Shared Implementations
848
- //
849
1137
  /**
850
- * Only intended to be "protected" and used by subclasses but exposed for
851
- * testing.
1138
+ * Register changes to the cache based on the specific collection type
1139
+ * Implemented by subclasses to handle specific change registration
1140
+ */
1141
+ /**
1142
+ * Common method for managing object reference counting and appending results
1143
+ * Used by collection queries when updating object references
852
1144
  *
853
- * @param objectCacheKeys
854
- * @param append
855
- * @param status
856
- * @param batch
857
- * @returns
1145
+ * @param batch The batch context to use
1146
+ * @param append Whether to append to existing objects or replace them
1147
+ * @param objectCacheKeys Array of object cache keys to process
1148
+ * @returns The final array of object cache keys after retain/release/append
858
1149
  */
859
- _updateList(objectCacheKeys, append, status, batch) {
860
- if (process.env.NODE_ENV !== "production") {
861
- const logger = process.env.NODE_ENV !== "production" ? this.logger?.child({
862
- methodName: "updateList"
863
- }) : this.logger;
864
- logger?.debug(`{status: ${status}}`, JSON.stringify(objectCacheKeys, null, 2));
865
- }
866
- objectCacheKeys = this.#retainReleaseAppend(batch, append, objectCacheKeys);
867
- objectCacheKeys = this._sortCacheKeys(objectCacheKeys, batch);
868
- objectCacheKeys = removeDuplicates(objectCacheKeys, batch);
869
- return this.writeToStore({
870
- data: objectCacheKeys
871
- }, status, batch);
872
- }
873
- writeToStore(data, status, batch) {
874
- const entry = batch.read(this.cacheKey);
875
- if (entry && deepEqual2__default.default(data, entry.value)) {
876
- if (process.env.NODE_ENV !== "production") {
877
- this.logger?.child({
878
- methodName: "writeToStore"
879
- }).debug(`Object was deep equal, just setting status`);
880
- }
881
- return batch.write(this.cacheKey, entry.value, status);
882
- }
883
- if (process.env.NODE_ENV !== "production") {
884
- this.logger?.child({
885
- methodName: "writeToStore"
886
- }).debug(`{status: ${status}},`, DEBUG_ONLY__cacheKeysToString(data.data));
887
- }
888
- const ret = batch.write(this.cacheKey, data, status);
889
- batch.changes.registerList(this.cacheKey);
890
- return ret;
891
- }
892
1150
  #retainReleaseAppend(batch, append, objectCacheKeys) {
893
1151
  const existingList = batch.read(this.cacheKey);
894
1152
  if (!batch.optimisticWrite) {
895
1153
  if (!append) {
896
1154
  for (const objectCacheKey of existingList?.value?.data ?? []) {
897
- this.store.release(objectCacheKey);
1155
+ this.store.cacheKeys.release(objectCacheKey);
898
1156
  }
899
1157
  }
900
1158
  for (const objectCacheKey of objectCacheKeys) {
901
- this.store.retain(objectCacheKey);
1159
+ this.store.cacheKeys.retain(objectCacheKey);
902
1160
  }
903
1161
  }
904
1162
  if (append) {
@@ -907,68 +1165,87 @@ var BaseListQuery = class extends Query {
907
1165
  return objectCacheKeys;
908
1166
  }
909
1167
  _dispose() {
910
- console.log("DISPOSE LIST QUERY");
911
1168
  this.store.batch({}, (batch) => {
912
1169
  const entry = batch.read(this.cacheKey);
913
1170
  if (entry) {
914
1171
  for (const objectCacheKey of entry.value?.data ?? []) {
915
- this.store.release(objectCacheKey);
1172
+ this.store.cacheKeys.release(objectCacheKey);
916
1173
  }
917
1174
  }
918
1175
  });
919
1176
  }
920
- };
921
- var ListQuery = class extends BaseListQuery {
922
- // pageSize?: number; // this is the internal page size. we need to track this properly
923
- #type;
924
- #apiName;
925
- #whereClause;
926
- // this represents the minimum number of results we need to load if we revalidate
927
- #minNumResults = 0;
928
- #nextPageToken;
929
- #pendingPageFetch;
930
- #orderBy;
931
- #objectSet;
932
- #sortFns;
933
- constructor(store, subject, apiType, apiName, whereClause, orderBy, cacheKey, opts) {
934
- super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[chunk633AI7EA_cjs.additionalContext].logger?.child({}, {
935
- msgPrefix: `ListQuery<${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>`
936
- }) : void 0);
937
- this.#type = apiType;
938
- this.#apiName = apiName;
939
- this.#whereClause = whereClause;
940
- this.#orderBy = orderBy;
941
- this.#objectSet = store.client({
942
- type: this.#type,
943
- apiName: this.#apiName
944
- }).where(this.#whereClause);
945
- this.#sortFns = createOrderBySortFns(this.#orderBy);
946
- }
947
- get canonicalWhere() {
948
- return this.#whereClause;
1177
+ /**
1178
+ * Creates a payload from collection parameters
1179
+ * Default implementation that covers common fields for all collection types
1180
+ * Subclasses may override to add type-specific fields if needed
1181
+ *
1182
+ * @param params Common collection parameters
1183
+ * @returns A typed payload for the specific collection type
1184
+ */
1185
+ createPayload(params) {
1186
+ return {
1187
+ resolvedList: params.resolvedData,
1188
+ isOptimistic: params.isOptimistic,
1189
+ fetchMore: this.fetchMore,
1190
+ hasMore: this.nextPageToken != null,
1191
+ status: params.status,
1192
+ lastUpdated: params.lastUpdated
1193
+ };
949
1194
  }
1195
+ /**
1196
+ * Creates a connectable observable for this collection
1197
+ * Common implementation shared by all collection types
1198
+ *
1199
+ * @param subject The subject to connect to
1200
+ * @returns A connectable observable of the collection's payload type
1201
+ */
950
1202
  _createConnectable(subject) {
951
- return rxjs.connectable(subject.pipe(
952
- rxjs.switchMap((listEntry) => {
953
- return rxjs.combineLatest({
954
- resolvedList: listEntry?.value?.data == null || listEntry.value.data.length === 0 ? rxjs.of([]) : rxjs.combineLatest(listEntry.value.data.map((cacheKey) => this.store.getSubject(cacheKey).pipe(rxjs.map((objectEntry) => objectEntry?.value)))),
955
- isOptimistic: rxjs.of(listEntry.isOptimistic),
956
- fetchMore: rxjs.of(this.fetchMore),
957
- hasMore: rxjs.of(this.#nextPageToken != null),
958
- status: rxjs.of(listEntry.status),
959
- lastUpdated: rxjs.of(listEntry.lastUpdated)
960
- });
961
- }),
962
- // like throttle but returns the tail
963
- rxjs.auditTime(0)
964
- ), {
965
- resetOnDisconnect: false,
966
- connector: () => new rxjs.ReplaySubject(1)
967
- });
1203
+ return createCollectionConnectable(subject, this.store.subjects, (params) => this.createPayload(params));
968
1204
  }
1205
+ /**
1206
+ * @override Reset pagination state before a fetch
1207
+ */
969
1208
  _preFetch() {
970
- this.#nextPageToken = void 0;
1209
+ this.nextPageToken = void 0;
1210
+ super._preFetch();
971
1211
  }
1212
+ /**
1213
+ * Common fetchMore implementation for pagination
1214
+ * Handles pending request management and loading states
1215
+ */
1216
+ fetchMore = () => {
1217
+ if (this.pendingPageFetch) {
1218
+ return this.pendingPageFetch;
1219
+ }
1220
+ if (this.pendingFetch) {
1221
+ this.pendingPageFetch = new Promise(async (res) => {
1222
+ await this.pendingFetch;
1223
+ res(this.fetchMore());
1224
+ });
1225
+ return this.pendingPageFetch;
1226
+ }
1227
+ if (this.nextPageToken == null) {
1228
+ return Promise.resolve(void 0);
1229
+ }
1230
+ this.store.batch({}, (batch) => {
1231
+ this.setStatus("loading", batch);
1232
+ });
1233
+ this.pendingFetch = this.fetchPageAndUpdate("loaded", this.abortController?.signal).then(() => void 0).finally(() => {
1234
+ this.pendingPageFetch = void 0;
1235
+ });
1236
+ return this.pendingFetch;
1237
+ };
1238
+ /**
1239
+ * Minimum number of results to load initially
1240
+ * May be overridden by subclasses for specific collection types
1241
+ * @protected
1242
+ */
1243
+ minResultsToLoad = 0;
1244
+ /**
1245
+ * Common _fetchAndStore implementation for pagination
1246
+ * Uses fetchPageAndUpdate to load the initial set of data
1247
+ * Will load multiple pages if necessary to reach minResultsToLoad
1248
+ */
972
1249
  async _fetchAndStore() {
973
1250
  if (process.env.NODE_ENV !== "production") {
974
1251
  this.logger?.child({
@@ -976,13 +1253,12 @@ var ListQuery = class extends BaseListQuery {
976
1253
  }).debug("fetching pages");
977
1254
  }
978
1255
  while (true) {
979
- const entry = await this.#fetchPageAndUpdate(this.#objectSet, "loading", this.abortController?.signal);
1256
+ const entry = await this.fetchPageAndUpdate("loading", this.abortController?.signal);
980
1257
  if (!entry) {
981
1258
  return;
982
1259
  }
983
- !entry.value?.data ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false) : invariant2__default.default(false) : void 0;
984
- const count = entry.value.data.length;
985
- if (count > this.#minNumResults || this.#nextPageToken == null) {
1260
+ const count = entry.value?.data.length || 0;
1261
+ if (count >= this.minResultsToLoad || this.nextPageToken == null) {
986
1262
  break;
987
1263
  }
988
1264
  }
@@ -991,91 +1267,406 @@ var ListQuery = class extends BaseListQuery {
991
1267
  });
992
1268
  return Promise.resolve();
993
1269
  }
994
- fetchMore = () => {
995
- if (this.#pendingPageFetch) {
996
- return this.#pendingPageFetch;
997
- }
998
- if (this.pendingFetch) {
999
- this.#pendingPageFetch = new Promise(async (res) => {
1000
- await this.pendingFetch;
1001
- res(this.fetchMore());
1002
- });
1003
- return this.#pendingPageFetch;
1270
+ /**
1271
+ * Template method for fetching a page of data and updating the store
1272
+ * Provides common error handling and abort signal checking
1273
+ *
1274
+ * @param status The status to set for the entry
1275
+ * @param signal Optional AbortSignal for cancellation
1276
+ * @returns A promise that resolves to the updated entry or undefined if aborted
1277
+ */
1278
+ async fetchPageAndUpdate(status, signal) {
1279
+ if (process.env.NODE_ENV !== "production") {
1280
+ this.logger?.child({
1281
+ methodName: "fetchPageAndUpdate"
1282
+ }).debug(`Fetching data with status: ${status}`);
1004
1283
  }
1005
- if (this.#nextPageToken == null) {
1006
- return Promise.resolve();
1284
+ if (signal?.aborted) {
1285
+ return void 0;
1007
1286
  }
1008
- this.store.batch({}, (batch) => {
1009
- this.setStatus("loading", batch);
1010
- });
1011
- this.pendingFetch = this.#fetchPageAndUpdate(this.#objectSet, "loaded", this.abortController?.signal).finally(() => {
1012
- this.#pendingPageFetch = void 0;
1013
- });
1014
- return this.pendingFetch;
1015
- };
1016
- async #fetchPageAndUpdate(objectSet, status, signal) {
1017
- const append = this.#nextPageToken != null;
1018
1287
  try {
1019
- let {
1020
- data,
1021
- nextPageToken
1022
- } = await objectSet.fetchPage({
1023
- $nextPageToken: this.#nextPageToken,
1024
- $pageSize: this.options.pageSize,
1025
- // For now this keeps the shared test code from falling apart
1026
- // but shouldn't be needed ideally
1027
- ...Object.keys(this.#orderBy).length > 0 ? {
1028
- $orderBy: this.#orderBy
1029
- } : {}
1030
- });
1288
+ const result = await this.fetchPageData(signal);
1031
1289
  if (signal?.aborted) {
1032
- return;
1033
- }
1034
- this.#nextPageToken = nextPageToken;
1035
- if (this.#type === "interface") {
1036
- data = await reloadDataAsFullObjects(this.store.client, data);
1290
+ return void 0;
1037
1291
  }
1038
1292
  const {
1039
1293
  retVal
1040
1294
  } = this.store.batch({}, (batch) => {
1041
- return this._updateList(storeOsdkInstances(this.store, data, batch), append, nextPageToken ? status : "loaded", batch);
1295
+ const append = this.nextPageToken != null;
1296
+ const finalStatus = result.nextPageToken ? status : "loaded";
1297
+ return this._updateList(this.store.objects.storeOsdkInstances(result.data, batch), finalStatus, batch, append);
1042
1298
  });
1043
1299
  return retVal;
1044
- } catch (e) {
1045
- this.logger?.error("error", e);
1046
- this.store.getSubject(this.cacheKey).error(e);
1300
+ } catch (error) {
1301
+ if (process.env.NODE_ENV !== "production") {
1302
+ this.logger?.child({
1303
+ methodName: "fetchPageAndUpdate"
1304
+ }).error("Error fetching data", error);
1305
+ }
1306
+ if (!signal?.aborted) {
1307
+ const {
1308
+ retVal
1309
+ } = this.store.batch({}, (batch) => {
1310
+ return this.handleFetchError(error, status, batch);
1311
+ });
1312
+ return retVal;
1313
+ }
1314
+ return void 0;
1047
1315
  }
1048
1316
  }
1049
1317
  /**
1050
- * Will revalidate the list if its query is affected by invalidating the
1051
- * apiName of the object type passed in.
1318
+ * Abstract method that subclasses implement for their specific data fetching logic
1052
1319
  *
1053
- * @param apiName to invalidate
1054
- * @returns
1320
+ * @param signal Optional AbortSignal for cancellation
1321
+ * @returns A promise that resolves to the fetched data
1055
1322
  */
1056
- revalidateObjectType = async (apiName) => {
1057
- if (this.#type === "object") {
1058
- if (this.#apiName === apiName) {
1059
- await this.revalidate(
1060
- /* force */
1061
- true
1062
- );
1063
- return;
1064
- } else {
1065
- return;
1066
- }
1323
+ /**
1324
+ * Handle fetch errors by setting appropriate error state
1325
+ * Default implementation that subclasses can override
1326
+ *
1327
+ * @param error The error that occurred
1328
+ * @param status The intended status if successful
1329
+ * @param batch The batch context to use
1330
+ * @returns The updated entry with error status
1331
+ */
1332
+ handleFetchError(_error, _status, batch) {
1333
+ return this.writeToStore({
1334
+ data: []
1335
+ }, "error", batch);
1336
+ }
1337
+ /**
1338
+ * Sort the collection items using the configured sorting strategy
1339
+ * @param objectCacheKeys - The cache keys to sort
1340
+ * @param batch - The batch context
1341
+ * @returns Sorted array of cache keys
1342
+ */
1343
+ _sortCacheKeys(objectCacheKeys, batch) {
1344
+ return this.sortingStrategy.sortCacheKeys(objectCacheKeys, batch);
1345
+ }
1346
+ /**
1347
+ * Unified method for updating collection data in the store
1348
+ * Handles storing, sorting, deduplication, and reference counting
1349
+ *
1350
+ * @param items - Either object cache keys or object instances to update
1351
+ * @param options - Configuration options for the update
1352
+ * @param batch - The batch context to use
1353
+ * @returns The updated entry
1354
+ */
1355
+ updateCollection(items, options, batch) {
1356
+ if (process.env.NODE_ENV !== "production") {
1357
+ const logger = process.env.NODE_ENV !== "production" ? this.logger?.child({
1358
+ methodName: "updateCollection"
1359
+ }) : this.logger;
1360
+ logger?.debug(`{status: ${options.status}, append: ${options.append}}`, JSON.stringify(items, null, 2));
1067
1361
  }
1068
- const objectMetadata = await this.store.client.fetchMetadata({
1362
+ let objectCacheKeys;
1363
+ if (items.length === 0) {
1364
+ objectCacheKeys = [];
1365
+ } else if (isObjectInstance(items[0])) {
1366
+ objectCacheKeys = this.store.objects.storeOsdkInstances(items, batch);
1367
+ } else {
1368
+ objectCacheKeys = items;
1369
+ }
1370
+ objectCacheKeys = this.#retainReleaseAppend(batch, options.append ?? false, objectCacheKeys);
1371
+ objectCacheKeys = this._sortCacheKeys(objectCacheKeys, batch);
1372
+ objectCacheKeys = removeDuplicates(objectCacheKeys, batch);
1373
+ return this.writeToStore({
1374
+ data: objectCacheKeys
1375
+ }, options.status, batch);
1376
+ }
1377
+ };
1378
+
1379
+ // src/observable/internal/links/SpecificLinkQuery.ts
1380
+ var SpecificLinkQuery = class extends BaseListQuery {
1381
+ #sourceApiName;
1382
+ #sourcePk;
1383
+ #linkName;
1384
+ #whereClause;
1385
+ #orderBy;
1386
+ /**
1387
+ * Register changes to the cache specific to SpecificLinkQuery
1388
+ */
1389
+ registerCacheChanges(batch) {
1390
+ batch.changes.modified.add(this.cacheKey);
1391
+ }
1392
+ constructor(store, subject, cacheKey, opts) {
1393
+ super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[chunkGVGP7T5P_cjs.additionalContext].logger?.child({}, {
1394
+ msgPrefix: `SpecificLinkQuery<${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>`
1395
+ }) : void 0);
1396
+ [this.#sourceApiName, this.#sourcePk, this.#linkName, this.#whereClause, this.#orderBy] = cacheKey.otherKeys;
1397
+ this.sortingStrategy = new OrderBySortingStrategy(this.#linkName, this.#orderBy);
1398
+ }
1399
+ // _fetchAndStore is now implemented in BaseCollectionQuery
1400
+ /**
1401
+ * Implements fetchPageData from the BaseCollectionQuery template method pattern
1402
+ * Fetches a page of linked objects
1403
+ */
1404
+ async fetchPageData(signal) {
1405
+ const client = this.store.client;
1406
+ const sourceObjectDef = {
1069
1407
  type: "object",
1070
- apiName
1408
+ apiName: this.#sourceApiName
1409
+ };
1410
+ const sourceMetadata = await client[chunkGVGP7T5P_cjs.additionalContext].ontologyProvider.getObjectDefinition(this.#sourceApiName);
1411
+ const sourceQuery = client(sourceObjectDef).where({
1412
+ [sourceMetadata.primaryKeyApiName]: this.#sourcePk
1071
1413
  });
1072
- if (this.#apiName in objectMetadata.interfaceMap) {
1073
- await this.revalidate(
1074
- /* force */
1075
- true
1076
- );
1414
+ const linkQuery = sourceQuery.pivotTo(this.#linkName);
1415
+ if (signal?.aborted) {
1416
+ throw new Error("Aborted");
1417
+ }
1418
+ const queryParams = {
1419
+ $pageSize: this.options.pageSize || 100,
1420
+ $nextPageToken: this.nextPageToken
1421
+ };
1422
+ if (this.#orderBy && Object.keys(this.#orderBy).length > 0) {
1423
+ queryParams.$orderBy = this.#orderBy;
1424
+ }
1425
+ if (this.#whereClause && Object.keys(this.#whereClause).length > 0) {
1426
+ queryParams.$where = this.#whereClause;
1427
+ }
1428
+ const response = await linkQuery.fetchPage(queryParams);
1429
+ this.nextPageToken = response.nextPageToken;
1430
+ return response;
1431
+ }
1432
+ /**
1433
+ * Removes a link query from the store
1434
+ */
1435
+ deleteFromStore(status, batch) {
1436
+ const entry = batch.read(this.cacheKey);
1437
+ if (entry && deepEqual4__default.default(tombstone, entry.value)) {
1438
+ if (process.env.NODE_ENV !== "production") {
1439
+ this.logger?.child({
1440
+ methodName: "deleteFromStore"
1441
+ }).debug(`Links were already deleted, just setting status`);
1442
+ }
1443
+ return batch.write(this.cacheKey, entry.value, status);
1444
+ }
1445
+ if (process.env.NODE_ENV !== "production") {
1446
+ this.logger?.child({
1447
+ methodName: "deleteFromStore"
1448
+ }).debug(JSON.stringify({
1449
+ status
1450
+ }));
1451
+ }
1452
+ if (!entry || !entry.value) {
1077
1453
  return;
1078
1454
  }
1455
+ const ret = batch.delete(this.cacheKey, status);
1456
+ batch.changes.deleted.add(this.cacheKey);
1457
+ return ret;
1458
+ }
1459
+ /**
1460
+ * Implements Query.maybeUpdateAndRevalidate to handle cache invalidation
1461
+ */
1462
+ maybeUpdateAndRevalidate = async (changes, _optimisticId) => {
1463
+ if (changes.modified.has(this.cacheKey)) {
1464
+ return this.revalidate(true);
1465
+ }
1466
+ return Promise.resolve();
1467
+ };
1468
+ invalidateObjectType = (objectType, changes) => {
1469
+ if (this.#sourceApiName === objectType) {
1470
+ changes?.modified.add(this.cacheKey);
1471
+ return this.revalidate(true);
1472
+ } else {
1473
+ return (async () => {
1474
+ const sourceMetadata = await this.store.client[chunkGVGP7T5P_cjs.additionalContext].ontologyProvider.getObjectDefinition(this.#sourceApiName);
1475
+ const linkDef = sourceMetadata.links?.[this.#linkName];
1476
+ if (!linkDef || linkDef.targetType !== objectType) return;
1477
+ const promise = this.revalidate(true);
1478
+ changes?.modified.add(this.cacheKey);
1479
+ return promise;
1480
+ })();
1481
+ }
1482
+ };
1483
+ };
1484
+
1485
+ // src/observable/internal/links/LinksHelper.ts
1486
+ var LinksHelper = class extends AbstractHelper {
1487
+ constructor(store, cacheKeys, whereCanonicalizer, orderByCanonicalizer) {
1488
+ super(store, cacheKeys);
1489
+ this.whereCanonicalizer = whereCanonicalizer;
1490
+ this.orderByCanonicalizer = orderByCanonicalizer;
1491
+ }
1492
+ getQuery(options) {
1493
+ const {
1494
+ apiName
1495
+ } = options.srcType;
1496
+ const canonWhere = this.whereCanonicalizer.canonicalize(options.where ?? {});
1497
+ const canonOrderBy = this.orderByCanonicalizer.canonicalize(options.orderBy ?? {});
1498
+ const linkCacheKey = this.cacheKeys.get("specificLink", apiName, options.pk, options.linkName, canonWhere, canonOrderBy);
1499
+ return this.store.queries.get(linkCacheKey, () => {
1500
+ return new SpecificLinkQuery(this.store, this.store.subjects.get(linkCacheKey), linkCacheKey, options);
1501
+ });
1502
+ }
1503
+ };
1504
+ function is$and(whereClause) {
1505
+ if (process.env.NODE_ENV !== "production") {
1506
+ if ("$and" in whereClause) {
1507
+ !Array.isArray(whereClause.$and) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected $and to be an array") : invariant2__default.default(false) : void 0;
1508
+ !(Object.keys(whereClause).length === 1) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected only $and to be present") : invariant2__default.default(false) : void 0;
1509
+ }
1510
+ }
1511
+ return "$and" in whereClause;
1512
+ }
1513
+ function is$or(whereClause) {
1514
+ if (process.env.NODE_ENV !== "production") {
1515
+ if ("$or" in whereClause) {
1516
+ !Array.isArray(whereClause.$or) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected $or to be an array") : invariant2__default.default(false) : void 0;
1517
+ !(Object.keys(whereClause).length === 1) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected only $or to be present") : invariant2__default.default(false) : void 0;
1518
+ }
1519
+ }
1520
+ return "$or" in whereClause;
1521
+ }
1522
+ function is$not(whereClause) {
1523
+ if (process.env.NODE_ENV !== "production") {
1524
+ if ("$not" in whereClause) {
1525
+ !(Object.keys(whereClause).length === 1) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "expected only $not to be present") : invariant2__default.default(false) : void 0;
1526
+ }
1527
+ }
1528
+ return "$not" in whereClause;
1529
+ }
1530
+ function objectSortaMatchesWhereClause(o, whereClause, strict) {
1531
+ if (deepEqual4__default.default({}, whereClause)) {
1532
+ return true;
1533
+ }
1534
+ if (is$and(whereClause)) {
1535
+ return whereClause.$and.every((w) => objectSortaMatchesWhereClause(o, w, strict));
1536
+ }
1537
+ if (is$or(whereClause)) {
1538
+ return whereClause.$or.some((w) => objectSortaMatchesWhereClause(o, w, strict));
1539
+ }
1540
+ if (is$not(whereClause)) {
1541
+ return !objectSortaMatchesWhereClause(o, whereClause.$not, strict);
1542
+ }
1543
+ return Object.entries(whereClause).every(([key, filter]) => {
1544
+ if (typeof filter === "object") {
1545
+ const realValue = o[key];
1546
+ const [f] = Object.keys(filter);
1547
+ const expected = filter[f];
1548
+ switch (f) {
1549
+ case "$eq":
1550
+ return realValue === expected;
1551
+ case "$gt":
1552
+ return realValue > expected;
1553
+ case "$lt":
1554
+ return realValue < expected;
1555
+ case "$gte":
1556
+ return realValue >= expected;
1557
+ case "$lte":
1558
+ return realValue <= expected;
1559
+ case "$ne":
1560
+ return realValue !== expected;
1561
+ case "$in":
1562
+ return expected.$in.includes(realValue);
1563
+ case "$isNull":
1564
+ return realValue == null;
1565
+ case "$startsWith":
1566
+ return realValue.startsWith(expected);
1567
+ case "$contains":
1568
+ case "$containsAllTerms":
1569
+ case "$containsAllTermsInOrder":
1570
+ case "$containsAnyTerm":
1571
+ case "$intersects":
1572
+ case "$within":
1573
+ return !strict;
1574
+ default:
1575
+ if (process.env.NODE_ENV !== "production") {
1576
+ process.env.NODE_ENV !== "production" ? invariant2__default.default(false, `Unknown where filter ${f}`) : invariant2__default.default(false) ;
1577
+ }
1578
+ return !strict;
1579
+ }
1580
+ }
1581
+ if (key in o) {
1582
+ if (o[key] === filter) {
1583
+ return true;
1584
+ }
1585
+ }
1586
+ return false;
1587
+ });
1588
+ }
1589
+
1590
+ // src/observable/internal/list/ListQuery.ts
1591
+ var API_NAME_IDX = 1;
1592
+ var ListQuery = class extends BaseListQuery {
1593
+ // pageSize?: number; // this is the internal page size. we need to track this properly
1594
+ #whereClause;
1595
+ // Using base class minResultsToLoad instead of a private property
1596
+ #orderBy;
1597
+ #objectSet;
1598
+ /**
1599
+ * Register changes to the cache specific to ListQuery
1600
+ */
1601
+ registerCacheChanges(batch) {
1602
+ batch.changes.registerList(this.cacheKey);
1603
+ }
1604
+ constructor(store, subject, apiName, whereClause, orderBy, cacheKey, opts) {
1605
+ super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[chunkGVGP7T5P_cjs.additionalContext].logger?.child({}, {
1606
+ msgPrefix: `ListQuery<${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>`
1607
+ }) : void 0);
1608
+ this.apiName = apiName;
1609
+ this.#whereClause = whereClause;
1610
+ this.#orderBy = orderBy;
1611
+ this.#objectSet = this.createObjectSet(store);
1612
+ this.sortingStrategy = new OrderBySortingStrategy(this.apiName, this.#orderBy);
1613
+ this.minResultsToLoad = 0;
1614
+ }
1615
+ get canonicalWhere() {
1616
+ return this.#whereClause;
1617
+ }
1618
+ /**
1619
+ * Create the ObjectSet for this query.
1620
+ */
1621
+ /**
1622
+ * Implements fetchPageData from BaseCollectionQuery template method
1623
+ * Fetches a page of data
1624
+ */
1625
+ async fetchPageData(signal) {
1626
+ const resp = await this.#objectSet.fetchPage({
1627
+ $nextPageToken: this.nextPageToken,
1628
+ $pageSize: this.options.pageSize,
1629
+ // For now this keeps the shared test code from falling apart
1630
+ // but shouldn't be needed ideally
1631
+ ...Object.keys(this.#orderBy).length > 0 ? {
1632
+ $orderBy: this.#orderBy
1633
+ } : {}
1634
+ });
1635
+ if (signal?.aborted) {
1636
+ throw new Error("Aborted");
1637
+ }
1638
+ this.nextPageToken = resp.nextPageToken;
1639
+ const fetchedData = await this.postProcessFetchedData(resp.data);
1640
+ return {
1641
+ ...resp,
1642
+ data: fetchedData
1643
+ };
1644
+ }
1645
+ /**
1646
+ * Handle fetch errors by setting appropriate error state and notifying subscribers
1647
+ */
1648
+ handleFetchError(error, _status, batch) {
1649
+ this.logger?.error("error", error);
1650
+ this.store.subjects.get(this.cacheKey).error(error);
1651
+ return this.writeToStore({
1652
+ data: []
1653
+ }, "error", batch);
1654
+ }
1655
+ /**
1656
+ * Will revalidate the list if its query is affected by invalidating the
1657
+ * apiName of the object type passed in.
1658
+ *
1659
+ * @param apiName to invalidate
1660
+ * @returns
1661
+ */
1662
+ /**
1663
+ * Postprocess fetched data.
1664
+ */
1665
+ invalidateObjectType = async (objectType, changes) => {
1666
+ if (this.cacheKey.otherKeys[1] === objectType) {
1667
+ changes?.modified.add(this.cacheKey);
1668
+ return this.revalidate(true);
1669
+ }
1079
1670
  };
1080
1671
  /**
1081
1672
  * Note: This method is not async because I want it to return right after it
@@ -1091,11 +1682,14 @@ var ListQuery = class extends BaseListQuery {
1091
1682
  this.logger?.child({
1092
1683
  methodName: "maybeUpdateAndRevalidate"
1093
1684
  }).debug(DEBUG_ONLY__changesToString(changes));
1685
+ this.logger?.child({
1686
+ methodName: "maybeUpdateAndRevalidate"
1687
+ }).debug(`Already in changes? ${changes.modified.has(this.cacheKey)}`);
1094
1688
  }
1095
1689
  if (changes.modified.has(this.cacheKey)) return;
1096
1690
  changes.modified.add(this.cacheKey);
1097
1691
  try {
1098
- const relevantObjects = this._extractRelevantObjects(changes);
1692
+ const relevantObjects = this._extractAndCategorizeRelevantObjects(changes);
1099
1693
  const status = optimisticId || relevantObjects.added.sortaMatches.size > 0 || relevantObjects.modified.sortaMatches.size > 0 ? "loading" : "loaded";
1100
1694
  const newList = [];
1101
1695
  let needsRevalidation = false;
@@ -1111,7 +1705,7 @@ var ListQuery = class extends BaseListQuery {
1111
1705
  const toRemove = new Set(changes.deleted);
1112
1706
  for (const obj of relevantObjects.modified.all) {
1113
1707
  if (relevantObjects.modified.strictMatches.has(obj)) {
1114
- const objectCacheKey = this.store.getCacheKey("object", obj.$objectType, obj.$primaryKey);
1708
+ const objectCacheKey = this.cacheKeys.get("object", obj.$objectType, obj.$primaryKey);
1115
1709
  if (!existingList.has(objectCacheKey)) {
1116
1710
  toAdd.add(obj);
1117
1711
  }
@@ -1119,7 +1713,7 @@ var ListQuery = class extends BaseListQuery {
1119
1713
  } else if (batch.optimisticWrite) {
1120
1714
  continue;
1121
1715
  } else {
1122
- const existingObjectCacheKey = this.store.getCacheKey("object", obj.$objectType, obj.$primaryKey);
1716
+ const existingObjectCacheKey = this.cacheKeys.get("object", obj.$objectType, obj.$primaryKey);
1123
1717
  toRemove.add(existingObjectCacheKey);
1124
1718
  if (relevantObjects.modified.sortaMatches.has(obj)) {
1125
1719
  needsRevalidation = true;
@@ -1131,14 +1725,14 @@ var ListQuery = class extends BaseListQuery {
1131
1725
  newList.push(key);
1132
1726
  }
1133
1727
  for (const obj of toAdd) {
1134
- newList.push(this.store.getCacheKey("object", obj.$objectType, obj.$primaryKey));
1728
+ newList.push(this.cacheKeys.get("object", obj.$objectType, obj.$primaryKey));
1135
1729
  }
1136
1730
  this._updateList(
1137
1731
  newList,
1138
- /* append */
1139
- false,
1140
1732
  status,
1141
- batch
1733
+ batch,
1734
+ /* append */
1735
+ false
1142
1736
  );
1143
1737
  });
1144
1738
  if (needsRevalidation) {
@@ -1151,76 +1745,32 @@ var ListQuery = class extends BaseListQuery {
1151
1745
  methodName: "maybeUpdateAndRevalidate"
1152
1746
  }).debug("in finally");
1153
1747
  }
1154
- }
1155
- };
1156
- #matchType(obj) {
1157
- if (objectSortaMatchesWhereClause(obj, this.#whereClause, true)) {
1158
- return "strict";
1159
- }
1160
- if (objectSortaMatchesWhereClause(obj, this.#whereClause, false)) {
1161
- return "sorta";
1162
- }
1163
- return false;
1164
- }
1165
- _extractRelevantObjects(changes) {
1166
- const relevantObjects = this.#type === "object" ? this.#extractRelevantObjectsForTypeObject(changes) : this.#extractRelevantObjectsForTypeInterface(changes);
1167
- for (const group of Object.values(relevantObjects)) {
1168
- for (const obj of group.all ?? []) {
1169
- const matchType = this.#matchType(obj);
1170
- if (matchType) {
1171
- group[`${matchType}Matches`].add(obj);
1172
- }
1173
- }
1174
- }
1175
- return relevantObjects;
1176
- }
1177
- #extractRelevantObjectsForTypeInterface(changes) {
1178
- const matchesApiName = ([, object]) => {
1179
- return this.#apiName in object[chunk26WFEZQO_cjs.ObjectDefRef].interfaceMap;
1180
- };
1181
- const added = Array.from(changes.addedObjects).filter(matchesApiName).map(([, object]) => object.$as(this.#apiName));
1182
- const modified = Array.from(changes.modifiedObjects).filter(matchesApiName).map(([, object]) => object.$as(this.#apiName));
1183
- return {
1184
- added: {
1185
- all: added,
1186
- strictMatches: /* @__PURE__ */ new Set(),
1187
- sortaMatches: /* @__PURE__ */ new Set()
1188
- },
1189
- modified: {
1190
- all: modified,
1191
- strictMatches: /* @__PURE__ */ new Set(),
1192
- sortaMatches: /* @__PURE__ */ new Set()
1193
- }
1194
- };
1195
- }
1196
- #extractRelevantObjectsForTypeObject(changes) {
1197
- return {
1198
- added: {
1199
- all: changes.addedObjects.get(this.cacheKey.otherKeys[API_NAME_IDX]) ?? [],
1200
- strictMatches: /* @__PURE__ */ new Set(),
1201
- sortaMatches: /* @__PURE__ */ new Set()
1202
- },
1203
- modified: {
1204
- all: changes.modifiedObjects.get(this.cacheKey.otherKeys[API_NAME_IDX]) ?? [],
1205
- strictMatches: /* @__PURE__ */ new Set(),
1206
- sortaMatches: /* @__PURE__ */ new Set()
1207
- }
1208
- };
1748
+ }
1749
+ };
1750
+ #matchType(obj) {
1751
+ if (objectSortaMatchesWhereClause(obj, this.#whereClause, true)) {
1752
+ return "strict";
1753
+ }
1754
+ if (objectSortaMatchesWhereClause(obj, this.#whereClause, false)) {
1755
+ return "sorta";
1756
+ }
1757
+ return false;
1209
1758
  }
1210
- _sortCacheKeys(objectCacheKeys, batch) {
1211
- if (Object.keys(this.#orderBy).length > 0) {
1212
- objectCacheKeys = objectCacheKeys.sort((a, b) => {
1213
- for (const sortFn of this.#sortFns) {
1214
- const ret = sortFn(batch.read(a)?.value?.$as(this.#apiName), batch.read(b)?.value?.$as(this.#apiName));
1215
- if (ret !== 0) {
1216
- return ret;
1217
- }
1759
+ _extractAndCategorizeRelevantObjects(changes) {
1760
+ const relevantObjects = this.extractRelevantObjects(changes);
1761
+ for (const group of Object.values(relevantObjects)) {
1762
+ for (const obj of group.all ?? []) {
1763
+ const matchType = this.#matchType(obj);
1764
+ if (matchType) {
1765
+ group[`${matchType}Matches`].add(obj);
1218
1766
  }
1219
- return 0;
1220
- });
1767
+ }
1221
1768
  }
1222
- return objectCacheKeys;
1769
+ return relevantObjects;
1223
1770
  }
1771
+ /**
1772
+ * Extract relevant objects for this query type.
1773
+ */
1224
1774
  registerStreamUpdates(sub) {
1225
1775
  const logger = process.env.NODE_ENV !== "production" ? this.logger?.child({
1226
1776
  methodName: "registerStreamUpdates"
@@ -1231,10 +1781,10 @@ var ListQuery = class extends BaseListQuery {
1231
1781
  }).info("Subscribing from websocket");
1232
1782
  }
1233
1783
  const websocketSubscription = this.#objectSet.subscribe({
1234
- onChange: this.#onOswChange.bind(this),
1235
- onError: this.#onOswError.bind(this),
1236
- onOutOfDate: this.#onOswOutOfDate.bind(this),
1237
- onSuccessfulSubscription: this.#onOswSuccessfulSubscription.bind(this)
1784
+ onChange: this.onOswChange.bind(this),
1785
+ onError: this.onOswError.bind(this),
1786
+ onOutOfDate: this.onOswOutOfDate.bind(this),
1787
+ onSuccessfulSubscription: this.onOswSuccessfulSubscription.bind(this)
1238
1788
  });
1239
1789
  sub.add(() => {
1240
1790
  if (process.env.NODE_ENV !== "production") {
@@ -1245,28 +1795,28 @@ var ListQuery = class extends BaseListQuery {
1245
1795
  websocketSubscription.unsubscribe();
1246
1796
  });
1247
1797
  }
1248
- #onOswSuccessfulSubscription() {
1798
+ onOswSuccessfulSubscription() {
1249
1799
  if (process.env.NODE_ENV !== "production") {
1250
1800
  this.logger?.child({
1251
1801
  methodName: "onSuccessfulSubscription"
1252
1802
  }).debug("");
1253
1803
  }
1254
1804
  }
1255
- #onOswOutOfDate() {
1805
+ onOswOutOfDate() {
1256
1806
  if (process.env.NODE_ENV !== "production") {
1257
1807
  this.logger?.child({
1258
1808
  methodName: "onOutOfDate"
1259
1809
  }).debug("");
1260
1810
  }
1261
1811
  }
1262
- #onOswError(errors) {
1812
+ onOswError(errors) {
1263
1813
  if (this.logger) {
1264
1814
  this.logger?.child({
1265
1815
  methodName: "onError"
1266
1816
  }).error("subscription errors", errors);
1267
1817
  }
1268
1818
  }
1269
- #onOswChange({
1819
+ onOswChange({
1270
1820
  object: objOrIface,
1271
1821
  state
1272
1822
  }) {
@@ -1281,18 +1831,18 @@ var ListQuery = class extends BaseListQuery {
1281
1831
  if (state === "ADDED_OR_UPDATED") {
1282
1832
  const object = objOrIface.$apiName !== objOrIface.$objectType ? objOrIface.$as(objOrIface.$objectType) : objOrIface;
1283
1833
  this.store.batch({}, (batch) => {
1284
- storeOsdkInstances(this.store, [object], batch);
1834
+ this.store.objects.storeOsdkInstances([object], batch);
1285
1835
  });
1286
1836
  } else if (state === "REMOVED") {
1287
- this.#onOswRemoved(objOrIface, logger);
1837
+ this.onOswRemoved(objOrIface, logger);
1288
1838
  }
1289
1839
  }
1290
- #onOswRemoved(objOrIface, logger) {
1840
+ onOswRemoved(objOrIface, logger) {
1291
1841
  this.store.batch({}, (batch) => {
1292
1842
  const existing = batch.read(this.cacheKey);
1293
1843
  !existing ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "the truth value for our list should exist as we already subscribed") : invariant2__default.default(false) : void 0;
1294
1844
  if (existing.status === "loaded") {
1295
- const objectCacheKey = this.store.getCacheKey("object", objOrIface.$objectType, objOrIface.$primaryKey);
1845
+ const objectCacheKey = this.cacheKeys.get("object", objOrIface.$objectType, objOrIface.$primaryKey);
1296
1846
  const newObjects = existing.value?.data.filter((o) => o !== objectCacheKey);
1297
1847
  if (newObjects?.length !== existing.value?.data.length) {
1298
1848
  batch.changes.registerList(this.cacheKey);
@@ -1318,41 +1868,54 @@ var ListQuery = class extends BaseListQuery {
1318
1868
  });
1319
1869
  }
1320
1870
  };
1321
- function removeDuplicates(objectCacheKeys, batch) {
1322
- const visited = /* @__PURE__ */ new Set();
1323
- objectCacheKeys = objectCacheKeys.filter((key) => {
1324
- batch.read(key);
1325
- if (visited.has(key)) {
1326
- return false;
1871
+
1872
+ // src/observable/internal/list/InterfaceListQuery.ts
1873
+ var InterfaceListQuery = class extends ListQuery {
1874
+ createObjectSet(store) {
1875
+ return store.client({
1876
+ type: "interface",
1877
+ apiName: this.apiName
1878
+ }).where(this.canonicalWhere);
1879
+ }
1880
+ async revalidateObjectType(apiName) {
1881
+ const objectMetadata = await this.store.client.fetchMetadata({
1882
+ type: "object",
1883
+ apiName
1884
+ });
1885
+ if (this.apiName in objectMetadata.interfaceMap) {
1886
+ await this.revalidate(
1887
+ /* force */
1888
+ true
1889
+ );
1327
1890
  }
1328
- visited.add(key);
1329
- return true;
1330
- });
1331
- return objectCacheKeys;
1332
- }
1333
- function createOrderBySortFns(orderBy) {
1334
- return Object.entries(orderBy).map(([key, order]) => {
1335
- return (a, b) => {
1336
- const aValue = a?.[key];
1337
- const bValue = b?.[key];
1338
- if (aValue == null && bValue == null) {
1339
- return 0;
1340
- }
1341
- if (aValue == null) {
1342
- return 1;
1343
- }
1344
- if (bValue == null) {
1345
- return -1;
1891
+ }
1892
+ async postProcessFetchedData(data) {
1893
+ return reloadDataAsFullObjects(this.store.client, data);
1894
+ }
1895
+ extractRelevantObjects(changes) {
1896
+ const matchesApiName = ([, object]) => {
1897
+ return this.apiName in object[chunkYADG7KA6_cjs.ObjectDefRef].interfaceMap;
1898
+ };
1899
+ const added = Array.from(changes.addedObjects).filter(matchesApiName).map(([, object]) => object.$as(this.apiName));
1900
+ const modified = Array.from(changes.modifiedObjects).filter(matchesApiName).map(([, object]) => object.$as(this.apiName));
1901
+ return {
1902
+ added: {
1903
+ all: added,
1904
+ strictMatches: /* @__PURE__ */ new Set(),
1905
+ sortaMatches: /* @__PURE__ */ new Set()
1906
+ },
1907
+ modified: {
1908
+ all: modified,
1909
+ strictMatches: /* @__PURE__ */ new Set(),
1910
+ sortaMatches: /* @__PURE__ */ new Set()
1346
1911
  }
1347
- const m = order === "asc" ? -1 : 1;
1348
- return aValue < bValue ? m : aValue > bValue ? -m : 0;
1349
1912
  };
1350
- });
1351
- }
1913
+ }
1914
+ };
1352
1915
  async function reloadDataAsFullObjects(client, data) {
1353
1916
  const groups = groupBy__default.default(data, (x) => x.$objectType);
1354
1917
  const objectTypeToPrimaryKeyToObject = Object.fromEntries(await Promise.all(Object.entries(groups).map(async ([apiName, objects]) => {
1355
- const objectDef = objects[0][chunk26WFEZQO_cjs.UnderlyingOsdkObject][chunk26WFEZQO_cjs.ObjectDefRef];
1918
+ const objectDef = objects[0][chunkYADG7KA6_cjs.UnderlyingOsdkObject][chunkYADG7KA6_cjs.ObjectDefRef];
1356
1919
  const where = {
1357
1920
  [objectDef.primaryKeyApiName]: {
1358
1921
  $in: objects.map((x) => x.$primaryKey)
@@ -1367,9 +1930,292 @@ async function reloadDataAsFullObjects(client, data) {
1367
1930
  });
1368
1931
  return data;
1369
1932
  }
1370
- function isListCacheKey(cacheKey) {
1371
- return cacheKey.type === "list";
1933
+
1934
+ // src/observable/internal/list/ObjectListQuery.ts
1935
+ var ObjectListQuery = class extends ListQuery {
1936
+ createObjectSet(store) {
1937
+ return store.client({
1938
+ type: "object",
1939
+ apiName: this.apiName
1940
+ }).where(this.canonicalWhere);
1941
+ }
1942
+ async revalidateObjectType(apiName) {
1943
+ if (this.apiName === apiName) {
1944
+ await this.revalidate(
1945
+ /* force */
1946
+ true
1947
+ );
1948
+ }
1949
+ }
1950
+ postProcessFetchedData(data) {
1951
+ return Promise.resolve(data);
1952
+ }
1953
+ extractRelevantObjects(changes) {
1954
+ return {
1955
+ added: {
1956
+ all: changes.addedObjects.get(this.cacheKey.otherKeys[API_NAME_IDX]) ?? [],
1957
+ strictMatches: /* @__PURE__ */ new Set(),
1958
+ sortaMatches: /* @__PURE__ */ new Set()
1959
+ },
1960
+ modified: {
1961
+ all: changes.modifiedObjects.get(this.cacheKey.otherKeys[API_NAME_IDX]) ?? [],
1962
+ strictMatches: /* @__PURE__ */ new Set(),
1963
+ sortaMatches: /* @__PURE__ */ new Set()
1964
+ }
1965
+ };
1966
+ }
1967
+ };
1968
+
1969
+ // src/observable/internal/list/ListsHelper.ts
1970
+ var ListsHelper = class extends AbstractHelper {
1971
+ constructor(store, cacheKeys, whereCanonicalizer, orderByCanonicalizer) {
1972
+ super(store, cacheKeys);
1973
+ this.whereCanonicalizer = whereCanonicalizer;
1974
+ this.orderByCanonicalizer = orderByCanonicalizer;
1975
+ }
1976
+ observe(options, subFn) {
1977
+ const ret = super.observe(options, subFn);
1978
+ if (options.streamUpdates) {
1979
+ ret.query.registerStreamUpdates(ret.subscription);
1980
+ }
1981
+ return ret;
1982
+ }
1983
+ getQuery(options) {
1984
+ const {
1985
+ type: {
1986
+ apiName,
1987
+ type
1988
+ },
1989
+ where,
1990
+ orderBy
1991
+ } = options;
1992
+ const canonWhere = this.whereCanonicalizer.canonicalize(where ?? {});
1993
+ const canonOrderBy = this.orderByCanonicalizer.canonicalize(orderBy ?? {});
1994
+ const listCacheKey = this.cacheKeys.get("list", type, apiName, canonWhere, canonOrderBy);
1995
+ return this.store.queries.get(listCacheKey, () => {
1996
+ const QueryClass = type === "object" ? ObjectListQuery : InterfaceListQuery;
1997
+ return new QueryClass(this.store, this.store.subjects.get(listCacheKey), apiName, canonWhere, canonOrderBy, listCacheKey, options);
1998
+ });
1999
+ }
2000
+ };
2001
+
2002
+ // ../../node_modules/.pnpm/p-defer@4.0.1/node_modules/p-defer/index.js
2003
+ function pDefer() {
2004
+ const deferred = {};
2005
+ deferred.promise = new Promise((resolve, reject) => {
2006
+ deferred.resolve = resolve;
2007
+ deferred.reject = reject;
2008
+ });
2009
+ return deferred;
2010
+ }
2011
+
2012
+ // src/observable/internal/BulkObjectLoader.ts
2013
+ var weakCache = new mnemonist.DefaultWeakMap((c) => new BulkObjectLoader(c));
2014
+ function getBulkObjectLoader(client) {
2015
+ return weakCache.get(client);
1372
2016
  }
2017
+ var BulkObjectLoader = class {
2018
+ #client;
2019
+ #m = new mnemonist.DefaultMap(() => ({
2020
+ data: [],
2021
+ timer: void 0
2022
+ }));
2023
+ #logger;
2024
+ #maxWait;
2025
+ #maxEntries;
2026
+ constructor(client, maxWait = 25, maxEntries = 100) {
2027
+ this.#client = client;
2028
+ this.#logger = client[chunkGVGP7T5P_cjs.additionalContext].logger;
2029
+ this.#maxWait = maxWait;
2030
+ this.#maxEntries = maxEntries;
2031
+ }
2032
+ async fetch(apiName, primaryKey) {
2033
+ const deferred = pDefer();
2034
+ const entry = this.#m.get(apiName);
2035
+ entry.data.push({
2036
+ primaryKey,
2037
+ deferred
2038
+ });
2039
+ if (!entry.timer) {
2040
+ entry.timer = setTimeout(() => {
2041
+ this.#loadObjects(apiName, entry.data);
2042
+ }, this.#maxWait);
2043
+ }
2044
+ if (entry.data.length >= this.#maxEntries) {
2045
+ clearTimeout(entry.timer);
2046
+ this.#loadObjects(apiName, entry.data);
2047
+ }
2048
+ return await deferred.promise;
2049
+ }
2050
+ #loadObjects(apiName, arr) {
2051
+ this.#m.delete(apiName);
2052
+ this.#reallyLoadObjects(apiName, arr).catch((e) => {
2053
+ this.#logger?.error("Unhandled exception", e);
2054
+ });
2055
+ }
2056
+ async #reallyLoadObjects(apiName, arr) {
2057
+ const miniDef = {
2058
+ type: "object",
2059
+ apiName
2060
+ };
2061
+ const objMetadata = await this.#client.fetchMetadata(miniDef);
2062
+ const pks = arr.map((x) => x.primaryKey);
2063
+ const {
2064
+ data
2065
+ } = await this.#client(miniDef).where({
2066
+ [objMetadata.primaryKeyApiName]: {
2067
+ $in: pks
2068
+ }
2069
+ }).fetchPage({
2070
+ $pageSize: pks.length
2071
+ });
2072
+ for (const {
2073
+ primaryKey,
2074
+ deferred
2075
+ } of arr) {
2076
+ const object = data.find((x) => x.$primaryKey === primaryKey);
2077
+ if (object) {
2078
+ deferred.resolve(object);
2079
+ } else {
2080
+ deferred.reject(new shared_net_errors.PalantirApiError(`Object not found: ${primaryKey}`));
2081
+ }
2082
+ }
2083
+ }
2084
+ };
2085
+
2086
+ // src/observable/internal/object/ObjectQuery.ts
2087
+ var ObjectQuery = class extends Query {
2088
+ #apiName;
2089
+ #pk;
2090
+ constructor(store, subject, type, pk, cacheKey, opts) {
2091
+ super(store, subject, opts, cacheKey, process.env.NODE_ENV !== "production" ? store.client[chunkGVGP7T5P_cjs.additionalContext].logger?.child({}, {
2092
+ msgPrefix: `ObjectQuery<${cacheKey.otherKeys.map((x) => JSON.stringify(x)).join(", ")}>`
2093
+ }) : void 0);
2094
+ this.#apiName = type;
2095
+ this.#pk = pk;
2096
+ }
2097
+ _createConnectable(subject) {
2098
+ return rxjs.connectable(subject.pipe(rxjs.map((x) => {
2099
+ return {
2100
+ status: x.status,
2101
+ object: x.value,
2102
+ lastUpdated: x.lastUpdated,
2103
+ isOptimistic: x.isOptimistic
2104
+ };
2105
+ })), {
2106
+ connector: () => new rxjs.BehaviorSubject({
2107
+ status: "init",
2108
+ object: void 0,
2109
+ lastUpdated: 0,
2110
+ isOptimistic: false
2111
+ })
2112
+ });
2113
+ }
2114
+ async _fetchAndStore() {
2115
+ if (process.env.NODE_ENV !== "production") {
2116
+ this.logger?.child({
2117
+ methodName: "_fetchAndStore"
2118
+ }).debug("calling _fetchAndStore");
2119
+ }
2120
+ const obj = await getBulkObjectLoader(this.store.client).fetch(this.#apiName, this.#pk);
2121
+ this.store.batch({}, (batch) => {
2122
+ this.writeToStore(obj, "loaded", batch);
2123
+ });
2124
+ }
2125
+ writeToStore(data, status, batch) {
2126
+ const entry = batch.read(this.cacheKey);
2127
+ if (entry && deepEqual4__default.default(data, entry.value)) {
2128
+ if (entry.status === status) {
2129
+ if (process.env.NODE_ENV !== "production") {
2130
+ this.logger?.child({
2131
+ methodName: "writeToStore"
2132
+ }).debug(`Object was deep equal and status unchanged (${status}), skipping update`);
2133
+ }
2134
+ return entry;
2135
+ }
2136
+ if (process.env.NODE_ENV !== "production") {
2137
+ this.logger?.child({
2138
+ methodName: "writeToStore"
2139
+ }).debug(`Object was deep equal, just setting status (old status: ${entry.status}, new status: ${status})`);
2140
+ }
2141
+ return batch.write(this.cacheKey, entry.value, status);
2142
+ }
2143
+ if (process.env.NODE_ENV !== "production") {
2144
+ this.logger?.child({
2145
+ methodName: "writeToStore"
2146
+ }).debug(JSON.stringify({
2147
+ status
2148
+ }), data);
2149
+ }
2150
+ const ret = batch.write(this.cacheKey, data, status);
2151
+ batch.changes.registerObject(
2152
+ this.cacheKey,
2153
+ data,
2154
+ /* isNew */
2155
+ !entry
2156
+ );
2157
+ return ret;
2158
+ }
2159
+ deleteFromStore(status, batch) {
2160
+ const entry = batch.read(this.cacheKey);
2161
+ if (entry && deepEqual4__default.default(tombstone, entry.value)) {
2162
+ if (process.env.NODE_ENV !== "production") {
2163
+ this.logger?.child({
2164
+ methodName: "deleteFromStore"
2165
+ }).debug(`Object was deep equal, just setting status`);
2166
+ }
2167
+ return batch.write(this.cacheKey, entry.value, status);
2168
+ }
2169
+ if (process.env.NODE_ENV !== "production") {
2170
+ this.logger?.child({
2171
+ methodName: "deleteFromStore"
2172
+ }).debug(JSON.stringify({
2173
+ status
2174
+ }));
2175
+ }
2176
+ if (!entry || !entry.value) {
2177
+ return;
2178
+ }
2179
+ const ret = batch.delete(this.cacheKey, status);
2180
+ batch.changes.deleteObject(this.cacheKey);
2181
+ return ret;
2182
+ }
2183
+ invalidateObjectType = (objectType, changes) => {
2184
+ if (this.#apiName === objectType) {
2185
+ changes?.modified.add(this.cacheKey);
2186
+ return this.revalidate(true);
2187
+ }
2188
+ return Promise.resolve();
2189
+ };
2190
+ };
2191
+
2192
+ // src/observable/internal/object/ObjectsHelper.ts
2193
+ var ObjectsHelper = class extends AbstractHelper {
2194
+ observe(options, subFn) {
2195
+ return super.observe(options, subFn);
2196
+ }
2197
+ getQuery(options) {
2198
+ const apiName = typeof options.apiName === "string" ? options.apiName : options.apiName.apiName;
2199
+ const {
2200
+ pk
2201
+ } = options;
2202
+ const objectCacheKey = this.cacheKeys.get("object", apiName, pk);
2203
+ return this.store.queries.get(objectCacheKey, () => new ObjectQuery(this.store, this.store.subjects.get(objectCacheKey), apiName, pk, objectCacheKey, {
2204
+ dedupeInterval: 0
2205
+ }));
2206
+ }
2207
+ /**
2208
+ * Internal helper method for writing objects to the store and returning their
2209
+ * object keys
2210
+ * @internal
2211
+ */
2212
+ storeOsdkInstances(values, batch) {
2213
+ return values.map((v) => this.getQuery({
2214
+ apiName: v.$apiName,
2215
+ pk: v.$primaryKey
2216
+ }).writeToStore(v, "loaded", batch).cacheKey);
2217
+ }
2218
+ };
1373
2219
  var defaultMakeData = () => /* @__PURE__ */ Object.create(null);
1374
2220
  var WeakRefTrie = class {
1375
2221
  #finalizer = new FinalizationRegistry((orderBy) => {
@@ -1404,6 +2250,8 @@ var WeakRefTrie = class {
1404
2250
  return this.#trie.removeArray(array)?.deref();
1405
2251
  }
1406
2252
  };
2253
+
2254
+ // src/observable/internal/OrderByCanonicalizer.ts
1407
2255
  var OrderByCanonicalizer = class {
1408
2256
  #trie = new WeakRefTrie((array) => {
1409
2257
  const pairs = array.reduce(function(result, _, index, array2) {
@@ -1424,49 +2272,28 @@ var OrderByCanonicalizer = class {
1424
2272
  };
1425
2273
  };
1426
2274
 
1427
- // src/observable/internal/RefCounts.ts
1428
- var RefCounts = class {
1429
- refCounts = /* @__PURE__ */ new Map();
1430
- // keeps our objects around for some extended duration after they are no longer
1431
- // needed which is good for quick clicks across tabs.
1432
- gcMap = /* @__PURE__ */ new Map();
1433
- constructor(keepAlive, cleanup) {
1434
- this.keepAlive = keepAlive;
1435
- this.cleanup = cleanup;
1436
- }
1437
- register(key) {
1438
- if (!this.refCounts.has(key)) {
1439
- this.gcMap.set(key, Date.now() + this.keepAlive);
1440
- }
1441
- return key;
1442
- }
1443
- retain(key) {
1444
- const count = this.refCounts.get(key) ?? 0;
1445
- this.refCounts.set(key, count + 1);
1446
- if (this.gcMap.has(key)) {
1447
- this.gcMap.delete(key);
1448
- }
2275
+ // src/observable/internal/Queries.ts
2276
+ var Queries = class {
2277
+ // we can use a regular Map here because the refCounting will
2278
+ // handle cleanup.
2279
+ map = /* @__PURE__ */ new Map();
2280
+ peek(cacheKey) {
2281
+ return this.map.get(cacheKey);
1449
2282
  }
1450
- release(key) {
1451
- const count = this.refCounts.get(key);
1452
- if (count === void 0) ; else if (count === 1) {
1453
- this.refCounts.delete(key);
1454
- this.gcMap.set(key, Date.now() + this.keepAlive);
1455
- } else {
1456
- this.refCounts.set(key, count - 1);
2283
+ get(cacheKey, createQuery) {
2284
+ let query = this.peek(cacheKey);
2285
+ if (!query) {
2286
+ query = createQuery();
2287
+ this.map.set(cacheKey, query);
1457
2288
  }
2289
+ return query;
1458
2290
  }
1459
- has(key) {
1460
- return this.refCounts.has(key);
2291
+ keys() {
2292
+ return this.map.keys();
1461
2293
  }
1462
- gc() {
1463
- const now = Date.now();
1464
- for (const [key, deathTime] of this.gcMap) {
1465
- if (deathTime < now) {
1466
- this.gcMap.delete(key);
1467
- this.cleanup(key);
1468
- }
1469
- }
2294
+ delete(cacheKey) {
2295
+ this.map.get(cacheKey)?.dispose();
2296
+ this.map.delete(cacheKey);
1470
2297
  }
1471
2298
  };
1472
2299
  var WhereClauseCanonicalizer = class {
@@ -1501,7 +2328,7 @@ var WhereClauseCanonicalizer = class {
1501
2328
  options: []
1502
2329
  };
1503
2330
  this.#existingOptions.set(cacheKey, lookupEntry);
1504
- const canon = lookupEntry.options.find((ref) => deepEqual2__default.default(ref.deref(), calculatedCanon))?.deref() ?? calculatedCanon;
2331
+ const canon = lookupEntry.options.find((ref) => deepEqual4__default.default(ref.deref(), calculatedCanon))?.deref() ?? calculatedCanon;
1505
2332
  if (canon === calculatedCanon) {
1506
2333
  lookupEntry.options.push(new WeakRef(canon));
1507
2334
  }
@@ -1535,65 +2362,40 @@ var WhereClauseCanonicalizer = class {
1535
2362
  };
1536
2363
 
1537
2364
  // src/observable/internal/Store.ts
1538
- function createInitEntry(cacheKey) {
1539
- return {
1540
- cacheKey,
1541
- status: "init",
1542
- value: void 0,
1543
- lastUpdated: 0
1544
- };
1545
- }
1546
2365
  var Store = class {
1547
2366
  whereCanonicalizer = new WhereClauseCanonicalizer();
1548
2367
  orderByCanonicalizer = new OrderByCanonicalizer();
1549
- #truthLayer = new Layer(void 0, void 0);
1550
- #topLayer;
1551
2368
  /** @internal */
1552
- // we can use a regular Map here because the refCounting will
1553
- // handle cleanup.
1554
- #queries = /* @__PURE__ */ new Map();
1555
- #cacheKeyToSubject = /* @__PURE__ */ new WeakMap();
1556
- #cacheKeys;
1557
- #refCounts = new RefCounts(6e4, (k) => this.#cleanupCacheKey(k));
1558
- // we are currently only using this for debug logging and should just remove it in the future if that
1559
- // continues to be true
1560
- #finalizationRegistry;
2369
+ queries = new Queries();
2370
+ layers = new Layers({
2371
+ logger: this.logger,
2372
+ onRevalidate: this.#maybeRevalidateQueries.bind(this)
2373
+ });
2374
+ subjects = this.layers.subjects;
2375
+ // these are hopefully temporary
1561
2376
  constructor(client) {
1562
- this.client = client;
1563
- this.logger = client[chunk633AI7EA_cjs.additionalContext].logger?.child({}, {
2377
+ this.logger = client[chunkGVGP7T5P_cjs.additionalContext].logger?.child({}, {
1564
2378
  msgPrefix: "Store"
1565
2379
  });
1566
- this.#topLayer = this.#truthLayer;
1567
- this.#cacheKeys = new CacheKeys(this.whereCanonicalizer, this.orderByCanonicalizer, (k) => {
1568
- this.#refCounts.register(k);
1569
- });
1570
- setInterval(() => {
1571
- this.#refCounts.gc();
1572
- }, 1e3);
1573
- this.#finalizationRegistry = new FinalizationRegistry((cleanupCallback) => {
1574
- try {
1575
- cleanupCallback();
1576
- } catch (e) {
1577
- console.error("Caught an error while running a finalization callback", e);
1578
- }
2380
+ this.client = client;
2381
+ this.cacheKeys = new CacheKeys({
2382
+ onDestroy: this.#cleanupCacheKey
1579
2383
  });
2384
+ this.lists = new ListsHelper(this, this.cacheKeys, this.whereCanonicalizer, this.orderByCanonicalizer);
2385
+ this.objects = new ObjectsHelper(this, this.cacheKeys);
2386
+ this.links = new LinksHelper(this, this.cacheKeys, this.whereCanonicalizer, this.orderByCanonicalizer);
1580
2387
  }
1581
2388
  /**
1582
2389
  * Called after a key is no longer retained and the timeout has elapsed
1583
2390
  * @param key
1584
2391
  */
1585
2392
  #cleanupCacheKey = (key) => {
1586
- const subject = this.peekSubject(key);
1587
- this.#cacheKeys.remove(key);
2393
+ const subject = this.subjects.peek(key);
1588
2394
  if (process.env.NODE_ENV !== "production") {
1589
2395
  !subject ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false) : invariant2__default.default(false) : void 0;
1590
2396
  }
1591
- if (subject) {
1592
- subject.complete();
1593
- this.#cacheKeyToSubject.delete(key);
1594
- }
1595
- this.#queries.get(key)?.dispose();
1596
- this.#queries.delete(key);
2397
+ this.subjects.delete(key);
2398
+ this.queries.delete(key);
1597
2399
  };
1598
2400
  applyAction = async (action, args, opts) => {
1599
2401
  return await new ActionApplication(this).applyAction(action, args, opts);
@@ -1605,228 +2407,68 @@ var Store = class {
1605
2407
  });
1606
2408
  return result;
1607
2409
  };
1608
- removeLayer(layerId) {
1609
- !(layerId != null) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "undefined is the reserved layerId for the truth layer") : invariant2__default.default(false) : void 0;
1610
- let currentLayer = this.#topLayer;
1611
- const cacheKeys = /* @__PURE__ */ new Map();
1612
- while (currentLayer != null && currentLayer.parentLayer != null) {
1613
- if (currentLayer.layerId === layerId) {
1614
- for (const [k, v] of currentLayer.entries()) {
1615
- if (cacheKeys.has(k)) continue;
1616
- cacheKeys.set(k, v);
1617
- }
1618
- }
1619
- currentLayer = currentLayer.parentLayer;
1620
- }
1621
- this.#topLayer = this.#topLayer.removeLayer(layerId);
1622
- for (const [k, oldEntry] of cacheKeys) {
1623
- const currentEntry = this.#topLayer.get(k);
1624
- if (oldEntry !== currentEntry) {
1625
- this.peekSubject(k)?.next({
1626
- // eslint-disable-next-line @typescript-eslint/no-misused-spread
1627
- ...currentEntry ?? createInitEntry(k),
1628
- isOptimistic: currentEntry?.value !== this.#truthLayer.get(k)?.value
1629
- });
1630
- }
1631
- }
1632
- }
1633
- getCacheKey(type, ...args) {
1634
- return this.#refCounts.register(this.#cacheKeys.get(type, ...args));
1635
- }
1636
- peekSubject = (cacheKey) => {
1637
- return this.#cacheKeyToSubject.get(cacheKey);
1638
- };
1639
- getSubject = (cacheKey) => {
1640
- let subject = this.#cacheKeyToSubject.get(cacheKey);
1641
- if (!subject) {
1642
- const initialValue = this.#topLayer.get(cacheKey) ?? createInitEntry(cacheKey);
1643
- subject = new rxjs.BehaviorSubject({
1644
- // eslint-disable-next-line @typescript-eslint/no-misused-spread
1645
- ...initialValue,
1646
- isOptimistic: initialValue.value !== this.#truthLayer.get(cacheKey)?.value
1647
- });
1648
- this.#cacheKeyToSubject.set(cacheKey, subject);
1649
- }
1650
- return subject;
1651
- };
1652
- canonicalizeWhereClause(where) {
1653
- return this.whereCanonicalizer.canonicalize(where);
1654
- }
1655
- observeObject(apiName, pk, options, subFn) {
1656
- if (typeof apiName !== "string") {
1657
- apiName = apiName.apiName;
1658
- }
1659
- const query = this.getObjectQuery(apiName, pk);
1660
- this.retain(query.cacheKey);
1661
- if (options.mode !== "offline") {
1662
- query.revalidate(options.mode === "force").catch((e) => {
1663
- subFn.error(e);
1664
- if (this.logger) {
1665
- this.logger.error("Unhandled error in observeObject", e);
1666
- } else {
1667
- throw e;
1668
- }
1669
- });
1670
- }
1671
- const sub = query.subscribe(subFn);
1672
- return {
1673
- unsubscribe: () => {
1674
- sub.unsubscribe();
1675
- this.release(query.cacheKey);
1676
- }
1677
- };
1678
- }
1679
- observeList(options, subFn) {
1680
- const query = this.getListQuery(options.type, options.where ?? {}, options.orderBy ?? {}, options);
1681
- this.retain(query.cacheKey);
1682
- if (options.mode !== "offline") {
1683
- query.revalidate(options.mode === "force").catch((x) => {
1684
- subFn.error(x);
1685
- });
1686
- }
1687
- const sub = query.subscribe(subFn);
1688
- if (options.streamUpdates) {
1689
- query.registerStreamUpdates(sub);
1690
- }
1691
- return {
1692
- unsubscribe: () => {
1693
- sub.unsubscribe();
1694
- this.release(query.cacheKey);
1695
- }
1696
- };
1697
- }
1698
- peekQuery(cacheKey) {
1699
- return this.#queries.get(cacheKey);
1700
- }
1701
- #getQuery(cacheKey, createQuery) {
1702
- let query = this.peekQuery(cacheKey);
1703
- if (!query) {
1704
- query = createQuery();
1705
- this.#queries.set(cacheKey, query);
1706
- }
1707
- return query;
1708
- }
1709
- getListQuery(def, where, orderBy, opts) {
1710
- const {
1711
- apiName,
1712
- type
1713
- } = def;
1714
- const canonWhere = this.whereCanonicalizer.canonicalize(where);
1715
- const canonOrderBy = this.orderByCanonicalizer.canonicalize(orderBy);
1716
- const listCacheKey = this.getCacheKey("list", type, apiName, canonWhere, canonOrderBy);
1717
- return this.#getQuery(listCacheKey, () => {
1718
- return new ListQuery(this, this.getSubject(listCacheKey), type, apiName, canonWhere, canonOrderBy, listCacheKey, opts);
1719
- });
1720
- }
1721
- getObjectQuery(apiName, pk) {
1722
- if (typeof apiName !== "string") {
1723
- apiName = apiName.apiName;
1724
- }
1725
- const objectCacheKey = this.getCacheKey("object", apiName, pk);
1726
- return this.#getQuery(objectCacheKey, () => new ObjectQuery(this, this.getSubject(objectCacheKey), apiName, pk, objectCacheKey, {
1727
- dedupeInterval: 0
1728
- }));
1729
- }
1730
2410
  getValue(cacheKey) {
1731
- return this.#topLayer.get(cacheKey);
2411
+ return this.layers.top.get(cacheKey);
1732
2412
  }
1733
- batch = ({
2413
+ batch({
1734
2414
  optimisticId,
1735
2415
  changes = createChangedObjects()
1736
- }, batchFn) => {
1737
- !(optimisticId === void 0 || !!optimisticId) ? process.env.NODE_ENV !== "production" ? invariant2__default.default(false, "optimistic must be undefined or not falsy") : invariant2__default.default(false) : void 0;
1738
- let needsLayer = optimisticId !== void 0;
1739
- const batchContext = {
1740
- changes,
1741
- createLayerIfNeeded: () => {
1742
- if (needsLayer) {
1743
- this.#topLayer = this.#topLayer.addLayer(optimisticId);
1744
- needsLayer = false;
1745
- }
1746
- },
1747
- optimisticWrite: !!optimisticId,
1748
- write: (cacheKey, value, status) => {
1749
- const oldTopValue = this.#topLayer.get(cacheKey);
1750
- if (optimisticId) batchContext.createLayerIfNeeded();
1751
- const writeLayer = optimisticId ? this.#topLayer : this.#truthLayer;
1752
- const newValue = new Entry(cacheKey, value, Date.now(), status);
1753
- writeLayer.set(cacheKey, newValue);
1754
- const newTopValue = this.#topLayer.get(cacheKey);
1755
- if (oldTopValue !== newTopValue) {
1756
- this.#cacheKeyToSubject.get(cacheKey)?.next({
1757
- // eslint-disable-next-line @typescript-eslint/no-misused-spread
1758
- ...newValue,
1759
- isOptimistic: newTopValue?.value !== this.#truthLayer.get(cacheKey)?.value
1760
- });
1761
- }
1762
- return newValue;
1763
- },
1764
- delete: (cacheKey, status) => {
1765
- return batchContext.write(cacheKey, tombstone, status);
1766
- },
1767
- read: (cacheKey) => {
1768
- return optimisticId ? this.#topLayer.get(cacheKey) : this.#truthLayer.get(cacheKey);
1769
- }
1770
- };
1771
- const retVal = batchFn(batchContext);
1772
- this.maybeRevalidateQueries(changes, optimisticId).catch((e) => {
1773
- if (this.logger) {
1774
- this.logger.error("Unhandled error in batch", e);
1775
- } else {
1776
- console.error("Unhandled error in batch", e);
1777
- throw e;
1778
- }
1779
- });
1780
- return {
1781
- batchResult: batchContext,
1782
- retVal,
1783
- changes: batchContext.changes
1784
- };
1785
- };
2416
+ }, batchFn) {
2417
+ return this.layers.batch({
2418
+ optimisticId,
2419
+ changes
2420
+ }, batchFn);
2421
+ }
1786
2422
  invalidateObject(apiName, pk) {
1787
2423
  if (typeof apiName !== "string") {
1788
2424
  apiName = apiName.apiName;
1789
2425
  }
1790
- return this.getObjectQuery(apiName, pk).revalidate(
2426
+ return this.objects.getQuery({
2427
+ apiName,
2428
+ pk
2429
+ }).revalidate(
1791
2430
  /* force */
1792
2431
  true
1793
2432
  );
1794
2433
  }
1795
- async maybeRevalidateQueries(changes, optimisticId) {
2434
+ async #maybeRevalidateQueries(changes, optimisticId) {
2435
+ const logger = process.env.NODE_ENV !== "production" ? this.logger?.child({
2436
+ methodName: "maybeRevalidateQueries"
2437
+ }) : void 0;
1796
2438
  if (changes.isEmpty()) {
1797
2439
  if (process.env.NODE_ENV !== "production") {
1798
- this.logger?.child({
1799
- methodName: "maybeRevalidateQueries"
1800
- }).debug("No changes, aborting");
2440
+ logger?.debug("No changes, aborting");
1801
2441
  }
1802
2442
  return;
1803
2443
  }
1804
2444
  if (process.env.NODE_ENV !== "production") {
1805
- this.logger?.child({
1806
- methodName: "maybeRevalidateQueries"
1807
- }).debug(DEBUG_ONLY__changesToString(changes), {
2445
+ logger?.debug(DEBUG_ONLY__changesToString(changes), {
1808
2446
  optimisticId
1809
2447
  });
1810
2448
  }
1811
2449
  try {
1812
2450
  const promises = [];
1813
- for (const cacheKey of this.#queries.keys()) {
1814
- const promise = this.peekQuery(cacheKey)?.maybeUpdateAndRevalidate?.(changes, optimisticId);
2451
+ for (const cacheKey of this.queries.keys()) {
2452
+ const promise = this.queries.peek(cacheKey)?.maybeUpdateAndRevalidate?.(changes, optimisticId);
1815
2453
  if (promise) promises.push(promise);
1816
2454
  }
1817
2455
  await Promise.all(promises);
1818
2456
  } finally {
1819
2457
  if (process.env.NODE_ENV !== "production") {
1820
- this.logger?.child({
1821
- methodName: "maybeRevalidateQueries"
1822
- }).debug("in finally", DEBUG_ONLY__changesToString(changes));
2458
+ logger?.debug("in finally", DEBUG_ONLY__changesToString(changes));
1823
2459
  }
1824
2460
  }
1825
2461
  }
1826
2462
  /**
1827
- * @param apiName
1828
- * @param changes The changes we know about / to update
1829
- * @returns
2463
+ * Invalidates all cache entries for a specific object type.
2464
+ * This will revalidate:
2465
+ * 1. All objects of the specified type
2466
+ * 2. All lists of the specified type
2467
+ * 3. All links where the source object is of the specified type
2468
+ *
2469
+ * @param apiName - The API name of the object type to invalidate
2470
+ * @param changes - Optional changes object to track what has been modified
2471
+ * @returns Promise that resolves when all invalidations are complete
1830
2472
  */
1831
2473
  invalidateObjectType(apiName, changes) {
1832
2474
  if (typeof apiName !== "string") {
@@ -1838,33 +2480,42 @@ var Store = class {
1838
2480
  }).info(changes ? DEBUG_ONLY__changesToString(changes) : void 0);
1839
2481
  }
1840
2482
  const promises = [];
1841
- for (const cacheKey of this.#truthLayer.keys()) {
1842
- if (isListCacheKey(cacheKey)) {
1843
- if (!changes || !changes.modified.has(cacheKey)) {
1844
- const promise = this.peekQuery(cacheKey)?.revalidate(true);
1845
- if (promise) {
1846
- promises.push(promise);
1847
- changes?.modified.add(cacheKey);
1848
- }
1849
- }
2483
+ for (const cacheKey of this.layers.truth.keys()) {
2484
+ if (changes && changes.modified.has(cacheKey)) {
2485
+ continue;
1850
2486
  }
2487
+ const query = this.queries.peek(cacheKey);
2488
+ if (!query) continue;
2489
+ promises.push(query.invalidateObjectType(apiName, changes));
1851
2490
  }
1852
- return Promise.all(promises).then(() => void 0);
2491
+ return Promise.allSettled(promises).then(() => void 0);
1853
2492
  }
1854
- retain(cacheKey) {
1855
- this.#refCounts.retain(cacheKey);
2493
+ async invalidateAll() {
2494
+ const promises = [];
2495
+ for (const cacheKey of this.queries.keys()) {
2496
+ const query = this.queries.peek(cacheKey);
2497
+ if (query) {
2498
+ promises.push(query.revalidate(true));
2499
+ }
2500
+ }
2501
+ return Promise.allSettled(promises).then(() => void 0);
1856
2502
  }
1857
- release(cacheKey) {
1858
- this.#refCounts.release(cacheKey);
2503
+ async invalidateObjects(objects) {
2504
+ const objectsArray = Array.isArray(objects) ? objects : [objects];
2505
+ const promises = [];
2506
+ for (const obj of objectsArray) {
2507
+ promises.push(this.invalidateObject(obj.$objectType, obj.$primaryKey));
2508
+ }
2509
+ return Promise.allSettled(promises).then(() => void 0);
1859
2510
  }
1860
2511
  };
1861
2512
 
1862
2513
  // src/observable/ObservableClient.ts
1863
2514
  function createObservableClient(client) {
1864
- const tweakedClient = chunk26WFEZQO_cjs.createClientFromContext({
1865
- ...client[chunk633AI7EA_cjs.additionalContext],
1866
- fetch: shared_net_fetch.createFetchHeaderMutator(client[chunk633AI7EA_cjs.additionalContext].fetch, (headers) => {
1867
- headers.set("Fetch-User-Agent", [headers.get("Fetch-User-Agent"), chunk26WFEZQO_cjs.OBSERVABLE_USER_AGENT].filter((x) => x && x?.length > 0).join(" "));
2515
+ const tweakedClient = chunkYADG7KA6_cjs.createClientFromContext({
2516
+ ...client[chunkGVGP7T5P_cjs.additionalContext],
2517
+ fetch: shared_net_fetch.createFetchHeaderMutator(client[chunkGVGP7T5P_cjs.additionalContext].fetch, (headers) => {
2518
+ headers.set("Fetch-User-Agent", [headers.get("Fetch-User-Agent"), chunkYADG7KA6_cjs.OBSERVABLE_USER_AGENT].filter((x) => x && x?.length > 0).join(" "));
1868
2519
  return headers;
1869
2520
  })
1870
2521
  });
@@ -1907,11 +2558,11 @@ function getOsdkConfig(ontologyRid) {
1907
2558
 
1908
2559
  Object.defineProperty(exports, "createClientWithTransaction", {
1909
2560
  enumerable: true,
1910
- get: function () { return chunk26WFEZQO_cjs.createClientWithTransaction; }
2561
+ get: function () { return chunkYADG7KA6_cjs.createClientWithTransaction; }
1911
2562
  });
1912
2563
  Object.defineProperty(exports, "augment", {
1913
2564
  enumerable: true,
1914
- get: function () { return chunk633AI7EA_cjs.augment; }
2565
+ get: function () { return chunkGVGP7T5P_cjs.augment; }
1915
2566
  });
1916
2567
  exports.createObservableClient = createObservableClient;
1917
2568
  exports.getMetaTagContent = getMetaTagContent;