@osdk/client 2.2.0-beta.8 → 2.3.0-beta.1

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 (489) hide show
  1. package/CHANGELOG.md +388 -0
  2. package/build/browser/MinimalClientContext.js.map +1 -1
  3. package/build/browser/__unstable/ConjureSupport.js.map +1 -1
  4. package/build/browser/actions/ActionValidationError.js +1 -1
  5. package/build/browser/actions/ActionValidationError.js.map +1 -1
  6. package/build/browser/actions/actions.test.js +134 -89
  7. package/build/browser/actions/actions.test.js.map +1 -1
  8. package/build/browser/actions/applyAction.js.map +1 -1
  9. package/build/browser/createClient.js +5 -1
  10. package/build/browser/createClient.js.map +1 -1
  11. package/build/browser/createClient.test.js +14 -6
  12. package/build/browser/createClient.test.js.map +1 -1
  13. package/build/browser/createMinimalClient.js +2 -2
  14. package/build/browser/createMinimalClient.js.map +1 -1
  15. package/build/browser/createMinimalClientHelper.js +25 -0
  16. package/build/browser/createMinimalClientHelper.js.map +1 -0
  17. package/build/browser/derivedProperties/createWithPropertiesObjectSet.js +36 -13
  18. package/build/browser/derivedProperties/createWithPropertiesObjectSet.js.map +1 -1
  19. package/build/browser/derivedProperties/createWithPropertiesObjectSet.test.js +133 -0
  20. package/build/browser/derivedProperties/createWithPropertiesObjectSet.test.js.map +1 -1
  21. package/build/browser/derivedProperties/derivedPropertyDefinitionFactory.js +93 -0
  22. package/build/browser/derivedProperties/derivedPropertyDefinitionFactory.js.map +1 -0
  23. package/build/browser/fetchMetadata.js +1 -1
  24. package/build/browser/fetchMetadata.js.map +1 -1
  25. package/build/browser/fetchMetadata.test.js +11 -9
  26. package/build/browser/fetchMetadata.test.js.map +1 -1
  27. package/build/browser/index.js +0 -1
  28. package/build/browser/index.js.map +1 -1
  29. package/build/{esm/util/isOsdkBaseObject.js → browser/intellisense.test.helpers/showsObjectPropertyJsdoc.js} +9 -4
  30. package/build/browser/intellisense.test.helpers/showsObjectPropertyJsdoc.js.map +1 -0
  31. package/build/browser/intellisense.test.js +17 -1
  32. package/build/browser/intellisense.test.js.map +1 -1
  33. package/build/browser/logger/BaseLogger.js +59 -0
  34. package/build/browser/logger/BaseLogger.js.map +1 -0
  35. package/build/browser/logger/BrowserLogger.js +67 -0
  36. package/build/browser/logger/BrowserLogger.js.map +1 -0
  37. package/build/browser/logger/MinimalLogger.js +39 -0
  38. package/build/browser/logger/MinimalLogger.js.map +1 -0
  39. package/build/browser/logger/MinimalLogger.test.js +60 -0
  40. package/build/browser/logger/MinimalLogger.test.js.map +1 -0
  41. package/build/browser/logger/TestLogger.js +56 -0
  42. package/build/browser/logger/TestLogger.js.map +1 -0
  43. package/build/browser/object/SimpleOsdkProperties.js +2 -0
  44. package/build/browser/object/SimpleOsdkProperties.js.map +1 -0
  45. package/build/browser/object/attachment.test.js +20 -7
  46. package/build/browser/object/attachment.test.js.map +1 -1
  47. package/build/browser/object/convertWireToOsdkObjects/BaseHolder.js +2 -0
  48. package/build/browser/object/convertWireToOsdkObjects/BaseHolder.js.map +1 -0
  49. package/build/browser/object/convertWireToOsdkObjects/InterfaceHolder.js.map +1 -1
  50. package/build/browser/object/convertWireToOsdkObjects/ObjectHolder.js.map +1 -1
  51. package/build/browser/object/convertWireToOsdkObjects/createOsdkInterface.js +4 -0
  52. package/build/browser/object/convertWireToOsdkObjects/createOsdkInterface.js.map +1 -1
  53. package/build/browser/object/convertWireToOsdkObjects/createOsdkObject.js +53 -35
  54. package/build/browser/object/convertWireToOsdkObjects/createOsdkObject.js.map +1 -1
  55. package/build/browser/object/convertWireToOsdkObjects/getDollarAs.js.map +1 -1
  56. package/build/browser/object/convertWireToOsdkObjects/getDollarLink.js.map +1 -1
  57. package/build/browser/object/convertWireToOsdkObjects.js +7 -15
  58. package/build/browser/object/convertWireToOsdkObjects.js.map +1 -1
  59. package/build/browser/object/convertWireToOsdkObjects.test.js +39 -33
  60. package/build/browser/object/convertWireToOsdkObjects.test.js.map +1 -1
  61. package/build/browser/object/fetchPage.js +17 -4
  62. package/build/browser/object/fetchPage.js.map +1 -1
  63. package/build/browser/object/fetchPage.test.js +56 -2
  64. package/build/browser/object/fetchPage.test.js.map +1 -1
  65. package/build/browser/object/geotimeseriesreference.test.js +56 -134
  66. package/build/browser/object/geotimeseriesreference.test.js.map +1 -1
  67. package/build/browser/object/media.test.js +19 -14
  68. package/build/browser/object/media.test.js.map +1 -1
  69. package/build/browser/object/object.test.js +96 -89
  70. package/build/browser/object/object.test.js.map +1 -1
  71. package/build/browser/object/timeseries.test.js +119 -85
  72. package/build/browser/object/timeseries.test.js.map +1 -1
  73. package/build/browser/objectSet/InterfaceObjectSet.test.js +37 -17
  74. package/build/browser/objectSet/InterfaceObjectSet.test.js.map +1 -1
  75. package/build/browser/objectSet/ObjectSet.test.js +200 -116
  76. package/build/browser/objectSet/ObjectSet.test.js.map +1 -1
  77. package/build/browser/objectSet/ObjectSetListenerWebsocket.js +20 -16
  78. package/build/browser/objectSet/ObjectSetListenerWebsocket.js.map +1 -1
  79. package/build/browser/objectSet/ObjectSetListenerWebsocket.test.js +19 -12
  80. package/build/browser/objectSet/ObjectSetListenerWebsocket.test.js.map +1 -1
  81. package/build/browser/objectSet/createObjectSet.js +2 -1
  82. package/build/browser/objectSet/createObjectSet.js.map +1 -1
  83. package/build/browser/observable/ListPayload.js.map +1 -1
  84. package/build/browser/observable/ObjectPayload.js.map +1 -1
  85. package/build/browser/observable/ObservableClient.js.map +1 -1
  86. package/build/browser/observable/internal/ActionApplication.js +32 -32
  87. package/build/browser/observable/internal/ActionApplication.js.map +1 -1
  88. package/build/browser/observable/internal/BulkObjectLoader.js +93 -0
  89. package/build/browser/observable/internal/BulkObjectLoader.js.map +1 -0
  90. package/build/browser/observable/internal/BulkObjectLoader.test.js +112 -0
  91. package/build/browser/observable/internal/BulkObjectLoader.test.js.map +1 -0
  92. package/build/browser/observable/internal/CacheKey.js +1 -1
  93. package/build/browser/observable/internal/CacheKey.js.map +1 -1
  94. package/build/browser/observable/internal/CacheKeys.js +2 -2
  95. package/build/browser/observable/internal/CacheKeys.js.map +1 -1
  96. package/build/browser/observable/internal/{ChangedObjects.js → Changes.js} +20 -9
  97. package/build/browser/observable/internal/Changes.js.map +1 -0
  98. package/build/browser/observable/internal/Layer.js +3 -0
  99. package/build/browser/observable/internal/Layer.js.map +1 -1
  100. package/build/browser/observable/internal/ListQuery.js +414 -170
  101. package/build/browser/observable/internal/ListQuery.js.map +1 -1
  102. package/build/browser/observable/internal/ObjectQuery.js +34 -21
  103. package/build/browser/observable/internal/ObjectQuery.js.map +1 -1
  104. package/build/browser/observable/internal/ObservableClientImpl.js +4 -12
  105. package/build/browser/observable/internal/ObservableClientImpl.js.map +1 -1
  106. package/build/browser/observable/internal/OptimisticJob.js +1 -1
  107. package/build/browser/observable/internal/OptimisticJob.js.map +1 -1
  108. package/build/browser/observable/internal/OrderByCanonicalizer.js +73 -0
  109. package/build/browser/observable/internal/OrderByCanonicalizer.js.map +1 -0
  110. package/build/browser/observable/internal/OrderByCanonicalizer.test.js +78 -0
  111. package/build/browser/observable/internal/OrderByCanonicalizer.test.js.map +1 -0
  112. package/build/browser/observable/internal/Query.js +64 -31
  113. package/build/browser/observable/internal/Query.js.map +1 -1
  114. package/build/browser/observable/internal/RefCounts.js +7 -2
  115. package/build/browser/observable/internal/RefCounts.js.map +1 -1
  116. package/build/browser/observable/internal/SimpleWhereClause.js +2 -0
  117. package/build/browser/observable/internal/SimpleWhereClause.js.map +1 -0
  118. package/build/browser/observable/internal/Store.js +86 -269
  119. package/build/browser/observable/internal/Store.js.map +1 -1
  120. package/build/browser/observable/internal/Store.test.js +401 -375
  121. package/build/browser/observable/internal/Store.test.js.map +1 -1
  122. package/build/browser/observable/internal/WhereClauseCanonicalizer.js +11 -3
  123. package/build/browser/observable/internal/WhereClauseCanonicalizer.js.map +1 -1
  124. package/build/browser/observable/internal/objectMatchesWhereClause.js +0 -2
  125. package/build/browser/observable/internal/objectMatchesWhereClause.js.map +1 -1
  126. package/build/browser/observable/internal/objectMatchesWhereClause.test.js.map +1 -1
  127. package/build/browser/observable/internal/testUtils.js +85 -20
  128. package/build/browser/observable/internal/testUtils.js.map +1 -1
  129. package/build/browser/ontology/OntologyProvider.js.map +1 -1
  130. package/build/browser/ontology/StandardOntologyProvider.js +12 -5
  131. package/build/browser/ontology/StandardOntologyProvider.js.map +1 -1
  132. package/build/browser/ontology/StandardOntologyProvider.test.js +17 -16
  133. package/build/browser/ontology/StandardOntologyProvider.test.js.map +1 -1
  134. package/build/browser/ontology/loadFullObjectMetadata.js +0 -1
  135. package/build/browser/ontology/loadFullObjectMetadata.js.map +1 -1
  136. package/build/browser/ontology/loadQueryMetadata.js +5 -2
  137. package/build/browser/ontology/loadQueryMetadata.js.map +1 -1
  138. package/build/browser/public/internal.js +2 -0
  139. package/build/browser/public/internal.js.map +1 -1
  140. package/build/browser/public/unstable-do-not-use.js +1 -0
  141. package/build/browser/public/unstable-do-not-use.js.map +1 -1
  142. package/build/browser/public-utils/osdkConfig.js +49 -0
  143. package/build/browser/public-utils/osdkConfig.js.map +1 -0
  144. package/build/browser/{object/createObjectSpecifierFromPrimaryKey.js → public-utils/vite-env.d.ts} +2 -3
  145. package/build/browser/queries/applyQuery.js +6 -4
  146. package/build/browser/queries/applyQuery.js.map +1 -1
  147. package/build/browser/queries/queries.test.js +93 -27
  148. package/build/browser/queries/queries.test.js.map +1 -1
  149. package/build/browser/queries/types.js.map +1 -1
  150. package/build/browser/tsserver.js.map +1 -1
  151. package/build/browser/util/UserAgent.js +1 -1
  152. package/build/browser/util/extractRdpDefinition.js +140 -0
  153. package/build/browser/util/extractRdpDefinition.js.map +1 -0
  154. package/build/browser/util/extractRdpDefinition.test.js +233 -0
  155. package/build/browser/util/extractRdpDefinition.test.js.map +1 -0
  156. package/build/browser/util/{isOsdkBaseObject.js → isObjectSpecifiersObject.js} +2 -2
  157. package/build/browser/util/isObjectSpecifiersObject.js.map +1 -0
  158. package/build/browser/util/isPoint.js +20 -0
  159. package/build/browser/util/isPoint.js.map +1 -0
  160. package/build/browser/util/objectSpecifierUtils.js +48 -0
  161. package/build/browser/util/objectSpecifierUtils.js.map +1 -0
  162. package/build/browser/util/objectSpecifierUtils.test.js +42 -0
  163. package/build/browser/util/objectSpecifierUtils.test.js.map +1 -0
  164. package/build/browser/util/toDataValue.js +6 -2
  165. package/build/browser/util/toDataValue.js.map +1 -1
  166. package/build/browser/util/toDataValue.test.js +37 -16
  167. package/build/browser/util/toDataValue.test.js.map +1 -1
  168. package/build/browser/util/toDataValueQueries.js +4 -6
  169. package/build/browser/util/toDataValueQueries.js.map +1 -1
  170. package/build/cjs/{Client-DBTcM9gB.d.cts → Client-CgL2LKN9.d.cts} +6 -7
  171. package/build/cjs/{chunk-IU47QMYO.cjs → chunk-FKI2LO2O.cjs} +250 -82
  172. package/build/cjs/chunk-FKI2LO2O.cjs.map +1 -0
  173. package/build/cjs/chunk-T4NIFYZS.cjs +14 -0
  174. package/build/cjs/chunk-T4NIFYZS.cjs.map +1 -0
  175. package/build/cjs/{chunk-JPENHIJB.cjs → chunk-W5PFESFR.cjs} +174 -35
  176. package/build/cjs/chunk-W5PFESFR.cjs.map +1 -0
  177. package/build/cjs/index.cjs +212 -193
  178. package/build/cjs/index.cjs.map +1 -1
  179. package/build/cjs/index.d.cts +4 -24
  180. package/build/cjs/public/internal.cjs +61 -7
  181. package/build/cjs/public/internal.cjs.map +1 -1
  182. package/build/cjs/public/internal.d.cts +50 -3
  183. package/build/cjs/public/unstable-do-not-use.cjs +885 -620
  184. package/build/cjs/public/unstable-do-not-use.cjs.map +1 -1
  185. package/build/cjs/public/unstable-do-not-use.d.cts +35 -25
  186. package/build/esm/MinimalClientContext.js.map +1 -1
  187. package/build/esm/__unstable/ConjureSupport.js.map +1 -1
  188. package/build/esm/actions/ActionValidationError.js +1 -1
  189. package/build/esm/actions/ActionValidationError.js.map +1 -1
  190. package/build/esm/actions/actions.test.js +134 -89
  191. package/build/esm/actions/actions.test.js.map +1 -1
  192. package/build/esm/actions/applyAction.js.map +1 -1
  193. package/build/esm/createClient.js +5 -1
  194. package/build/esm/createClient.js.map +1 -1
  195. package/build/esm/createClient.test.js +14 -6
  196. package/build/esm/createClient.test.js.map +1 -1
  197. package/build/esm/createMinimalClient.js +2 -2
  198. package/build/esm/createMinimalClient.js.map +1 -1
  199. package/build/esm/createMinimalClientHelper.js +25 -0
  200. package/build/esm/createMinimalClientHelper.js.map +1 -0
  201. package/build/esm/derivedProperties/createWithPropertiesObjectSet.js +36 -13
  202. package/build/esm/derivedProperties/createWithPropertiesObjectSet.js.map +1 -1
  203. package/build/esm/derivedProperties/createWithPropertiesObjectSet.test.js +133 -0
  204. package/build/esm/derivedProperties/createWithPropertiesObjectSet.test.js.map +1 -1
  205. package/build/esm/derivedProperties/derivedPropertyDefinitionFactory.js +93 -0
  206. package/build/esm/derivedProperties/derivedPropertyDefinitionFactory.js.map +1 -0
  207. package/build/esm/fetchMetadata.js +1 -1
  208. package/build/esm/fetchMetadata.js.map +1 -1
  209. package/build/esm/fetchMetadata.test.js +11 -9
  210. package/build/esm/fetchMetadata.test.js.map +1 -1
  211. package/build/esm/index.js +0 -1
  212. package/build/esm/index.js.map +1 -1
  213. package/build/esm/{util/isOsdkObject.js → intellisense.test.helpers/showsObjectPropertyJsdoc.js} +9 -4
  214. package/build/esm/intellisense.test.helpers/showsObjectPropertyJsdoc.js.map +1 -0
  215. package/build/esm/intellisense.test.js +17 -1
  216. package/build/esm/intellisense.test.js.map +1 -1
  217. package/build/esm/logger/BaseLogger.js +59 -0
  218. package/build/esm/logger/BaseLogger.js.map +1 -0
  219. package/build/esm/logger/BrowserLogger.js +67 -0
  220. package/build/esm/logger/BrowserLogger.js.map +1 -0
  221. package/build/esm/logger/MinimalLogger.js +39 -0
  222. package/build/esm/logger/MinimalLogger.js.map +1 -0
  223. package/build/esm/logger/MinimalLogger.test.js +60 -0
  224. package/build/esm/logger/MinimalLogger.test.js.map +1 -0
  225. package/build/esm/logger/TestLogger.js +56 -0
  226. package/build/esm/logger/TestLogger.js.map +1 -0
  227. package/build/esm/object/SimpleOsdkProperties.js +2 -0
  228. package/build/esm/object/SimpleOsdkProperties.js.map +1 -0
  229. package/build/esm/object/attachment.test.js +20 -7
  230. package/build/esm/object/attachment.test.js.map +1 -1
  231. package/build/esm/object/convertWireToOsdkObjects/BaseHolder.js +2 -0
  232. package/build/esm/object/convertWireToOsdkObjects/BaseHolder.js.map +1 -0
  233. package/build/esm/object/convertWireToOsdkObjects/InterfaceHolder.js.map +1 -1
  234. package/build/esm/object/convertWireToOsdkObjects/ObjectHolder.js.map +1 -1
  235. package/build/esm/object/convertWireToOsdkObjects/createOsdkInterface.js +4 -0
  236. package/build/esm/object/convertWireToOsdkObjects/createOsdkInterface.js.map +1 -1
  237. package/build/esm/object/convertWireToOsdkObjects/createOsdkObject.js +53 -35
  238. package/build/esm/object/convertWireToOsdkObjects/createOsdkObject.js.map +1 -1
  239. package/build/esm/object/convertWireToOsdkObjects/getDollarAs.js.map +1 -1
  240. package/build/esm/object/convertWireToOsdkObjects/getDollarLink.js.map +1 -1
  241. package/build/esm/object/convertWireToOsdkObjects.js +7 -15
  242. package/build/esm/object/convertWireToOsdkObjects.js.map +1 -1
  243. package/build/esm/object/convertWireToOsdkObjects.test.js +39 -33
  244. package/build/esm/object/convertWireToOsdkObjects.test.js.map +1 -1
  245. package/build/esm/object/fetchPage.js +17 -4
  246. package/build/esm/object/fetchPage.js.map +1 -1
  247. package/build/esm/object/fetchPage.test.js +56 -2
  248. package/build/esm/object/fetchPage.test.js.map +1 -1
  249. package/build/esm/object/geotimeseriesreference.test.js +56 -134
  250. package/build/esm/object/geotimeseriesreference.test.js.map +1 -1
  251. package/build/esm/object/media.test.js +19 -14
  252. package/build/esm/object/media.test.js.map +1 -1
  253. package/build/esm/object/object.test.js +96 -89
  254. package/build/esm/object/object.test.js.map +1 -1
  255. package/build/esm/object/timeseries.test.js +119 -85
  256. package/build/esm/object/timeseries.test.js.map +1 -1
  257. package/build/esm/objectSet/InterfaceObjectSet.test.js +37 -17
  258. package/build/esm/objectSet/InterfaceObjectSet.test.js.map +1 -1
  259. package/build/esm/objectSet/ObjectSet.test.js +200 -116
  260. package/build/esm/objectSet/ObjectSet.test.js.map +1 -1
  261. package/build/esm/objectSet/ObjectSetListenerWebsocket.js +20 -16
  262. package/build/esm/objectSet/ObjectSetListenerWebsocket.js.map +1 -1
  263. package/build/esm/objectSet/ObjectSetListenerWebsocket.test.js +19 -12
  264. package/build/esm/objectSet/ObjectSetListenerWebsocket.test.js.map +1 -1
  265. package/build/esm/objectSet/createObjectSet.js +2 -1
  266. package/build/esm/objectSet/createObjectSet.js.map +1 -1
  267. package/build/esm/observable/ListPayload.js.map +1 -1
  268. package/build/esm/observable/ObjectPayload.js.map +1 -1
  269. package/build/esm/observable/ObservableClient.js.map +1 -1
  270. package/build/esm/observable/internal/ActionApplication.js +32 -32
  271. package/build/esm/observable/internal/ActionApplication.js.map +1 -1
  272. package/build/esm/observable/internal/BulkObjectLoader.js +93 -0
  273. package/build/esm/observable/internal/BulkObjectLoader.js.map +1 -0
  274. package/build/esm/observable/internal/BulkObjectLoader.test.js +112 -0
  275. package/build/esm/observable/internal/BulkObjectLoader.test.js.map +1 -0
  276. package/build/esm/observable/internal/CacheKey.js +1 -1
  277. package/build/esm/observable/internal/CacheKey.js.map +1 -1
  278. package/build/esm/observable/internal/CacheKeys.js +2 -2
  279. package/build/esm/observable/internal/CacheKeys.js.map +1 -1
  280. package/build/esm/observable/internal/{ChangedObjects.js → Changes.js} +20 -9
  281. package/build/esm/observable/internal/Changes.js.map +1 -0
  282. package/build/esm/observable/internal/Layer.js +3 -0
  283. package/build/esm/observable/internal/Layer.js.map +1 -1
  284. package/build/esm/observable/internal/ListQuery.js +414 -170
  285. package/build/esm/observable/internal/ListQuery.js.map +1 -1
  286. package/build/esm/observable/internal/ObjectQuery.js +34 -21
  287. package/build/esm/observable/internal/ObjectQuery.js.map +1 -1
  288. package/build/esm/observable/internal/ObservableClientImpl.js +4 -12
  289. package/build/esm/observable/internal/ObservableClientImpl.js.map +1 -1
  290. package/build/esm/observable/internal/OptimisticJob.js +1 -1
  291. package/build/esm/observable/internal/OptimisticJob.js.map +1 -1
  292. package/build/esm/observable/internal/OrderByCanonicalizer.js +73 -0
  293. package/build/esm/observable/internal/OrderByCanonicalizer.js.map +1 -0
  294. package/build/esm/observable/internal/OrderByCanonicalizer.test.js +78 -0
  295. package/build/esm/observable/internal/OrderByCanonicalizer.test.js.map +1 -0
  296. package/build/esm/observable/internal/Query.js +64 -31
  297. package/build/esm/observable/internal/Query.js.map +1 -1
  298. package/build/esm/observable/internal/RefCounts.js +7 -2
  299. package/build/esm/observable/internal/RefCounts.js.map +1 -1
  300. package/build/esm/observable/internal/SimpleWhereClause.js +2 -0
  301. package/build/esm/observable/internal/SimpleWhereClause.js.map +1 -0
  302. package/build/esm/observable/internal/Store.js +86 -269
  303. package/build/esm/observable/internal/Store.js.map +1 -1
  304. package/build/esm/observable/internal/Store.test.js +401 -375
  305. package/build/esm/observable/internal/Store.test.js.map +1 -1
  306. package/build/esm/observable/internal/WhereClauseCanonicalizer.js +11 -3
  307. package/build/esm/observable/internal/WhereClauseCanonicalizer.js.map +1 -1
  308. package/build/esm/observable/internal/objectMatchesWhereClause.js +0 -2
  309. package/build/esm/observable/internal/objectMatchesWhereClause.js.map +1 -1
  310. package/build/esm/observable/internal/objectMatchesWhereClause.test.js.map +1 -1
  311. package/build/esm/observable/internal/testUtils.js +85 -20
  312. package/build/esm/observable/internal/testUtils.js.map +1 -1
  313. package/build/esm/ontology/OntologyProvider.js.map +1 -1
  314. package/build/esm/ontology/StandardOntologyProvider.js +12 -5
  315. package/build/esm/ontology/StandardOntologyProvider.js.map +1 -1
  316. package/build/esm/ontology/StandardOntologyProvider.test.js +17 -16
  317. package/build/esm/ontology/StandardOntologyProvider.test.js.map +1 -1
  318. package/build/esm/ontology/loadFullObjectMetadata.js +0 -1
  319. package/build/esm/ontology/loadFullObjectMetadata.js.map +1 -1
  320. package/build/esm/ontology/loadQueryMetadata.js +5 -2
  321. package/build/esm/ontology/loadQueryMetadata.js.map +1 -1
  322. package/build/esm/public/internal.js +2 -0
  323. package/build/esm/public/internal.js.map +1 -1
  324. package/build/esm/public/unstable-do-not-use.js +1 -0
  325. package/build/esm/public/unstable-do-not-use.js.map +1 -1
  326. package/build/esm/public-utils/osdkConfig.js +49 -0
  327. package/build/esm/public-utils/osdkConfig.js.map +1 -0
  328. package/build/esm/{object/createObjectSpecifierFromPrimaryKey.js → public-utils/vite-env.d.ts} +2 -3
  329. package/build/esm/queries/applyQuery.js +6 -4
  330. package/build/esm/queries/applyQuery.js.map +1 -1
  331. package/build/esm/queries/queries.test.js +93 -27
  332. package/build/esm/queries/queries.test.js.map +1 -1
  333. package/build/esm/queries/types.js.map +1 -1
  334. package/build/esm/tsserver.js.map +1 -1
  335. package/build/esm/util/UserAgent.js +1 -1
  336. package/build/esm/util/extractRdpDefinition.js +140 -0
  337. package/build/esm/util/extractRdpDefinition.js.map +1 -0
  338. package/build/esm/util/extractRdpDefinition.test.js +233 -0
  339. package/build/esm/util/extractRdpDefinition.test.js.map +1 -0
  340. package/build/{browser/util/isOsdkObject.js → esm/util/isObjectSpecifiersObject.js} +2 -2
  341. package/build/esm/util/isObjectSpecifiersObject.js.map +1 -0
  342. package/build/esm/util/isPoint.js +20 -0
  343. package/build/esm/util/isPoint.js.map +1 -0
  344. package/build/esm/util/objectSpecifierUtils.js +48 -0
  345. package/build/esm/util/objectSpecifierUtils.js.map +1 -0
  346. package/build/esm/util/objectSpecifierUtils.test.js +42 -0
  347. package/build/esm/util/objectSpecifierUtils.test.js.map +1 -0
  348. package/build/esm/util/toDataValue.js +6 -2
  349. package/build/esm/util/toDataValue.js.map +1 -1
  350. package/build/esm/util/toDataValue.test.js +37 -16
  351. package/build/esm/util/toDataValue.test.js.map +1 -1
  352. package/build/esm/util/toDataValueQueries.js +4 -6
  353. package/build/esm/util/toDataValueQueries.js.map +1 -1
  354. package/build/types/MinimalClientContext.d.ts +1 -1
  355. package/build/types/MinimalClientContext.d.ts.map +1 -1
  356. package/build/types/__unstable/ConjureSupport.d.ts +2 -2
  357. package/build/types/actions/applyAction.d.ts +1 -2
  358. package/build/types/actions/applyAction.d.ts.map +1 -1
  359. package/build/types/createClient.d.ts +1 -1
  360. package/build/types/createClient.d.ts.map +1 -1
  361. package/build/types/createClient.test.d.ts +2 -1
  362. package/build/types/createClient.test.d.ts.map +1 -1
  363. package/build/types/createMinimalClientHelper.d.ts +1 -0
  364. package/build/types/createMinimalClientHelper.d.ts.map +1 -0
  365. package/build/types/derivedProperties/derivedPropertyDefinitionFactory.d.ts +1 -0
  366. package/build/types/derivedProperties/derivedPropertyDefinitionFactory.d.ts.map +1 -0
  367. package/build/types/index.d.ts +4 -6
  368. package/build/types/index.d.ts.map +1 -1
  369. package/build/types/intellisense.test.helpers/showsObjectPropertyJsdoc.d.ts +1 -0
  370. package/build/types/intellisense.test.helpers/showsObjectPropertyJsdoc.d.ts.map +1 -0
  371. package/build/types/logger/BaseLogger.d.ts +33 -0
  372. package/build/types/logger/BaseLogger.d.ts.map +1 -0
  373. package/build/types/logger/BrowserLogger.d.ts +9 -0
  374. package/build/types/logger/BrowserLogger.d.ts.map +1 -0
  375. package/build/types/logger/MinimalLogger.d.ts +9 -0
  376. package/build/types/logger/MinimalLogger.d.ts.map +1 -0
  377. package/build/types/logger/MinimalLogger.test.d.ts +1 -0
  378. package/build/types/logger/MinimalLogger.test.d.ts.map +1 -0
  379. package/build/types/logger/TestLogger.d.ts +14 -0
  380. package/build/types/logger/TestLogger.d.ts.map +1 -0
  381. package/build/types/object/SimpleOsdkProperties.d.ts +1 -0
  382. package/build/types/object/SimpleOsdkProperties.d.ts.map +1 -0
  383. package/build/types/object/convertWireToOsdkObjects/BaseHolder.d.ts +1 -0
  384. package/build/types/object/convertWireToOsdkObjects/BaseHolder.d.ts.map +1 -0
  385. package/build/types/object/convertWireToOsdkObjects.d.ts +8 -1
  386. package/build/types/object/convertWireToOsdkObjects.d.ts.map +1 -1
  387. package/build/types/object/fetchPage.d.ts.map +1 -1
  388. package/build/types/object/object.test.d.ts.map +1 -1
  389. package/build/types/objectSet/ObjectSet.test.d.ts.map +1 -1
  390. package/build/types/observable/ListPayload.d.ts +5 -9
  391. package/build/types/observable/ListPayload.d.ts.map +1 -1
  392. package/build/types/observable/ObjectPayload.d.ts +4 -7
  393. package/build/types/observable/ObjectPayload.d.ts.map +1 -1
  394. package/build/types/observable/ObservableClient.d.ts +27 -11
  395. package/build/types/observable/ObservableClient.d.ts.map +1 -1
  396. package/build/types/observable/internal/ActionApplication.d.ts +2 -2
  397. package/build/types/observable/internal/ActionApplication.d.ts.map +1 -1
  398. package/build/types/observable/internal/BulkObjectLoader.d.ts +8 -0
  399. package/build/types/observable/internal/BulkObjectLoader.d.ts.map +1 -0
  400. package/build/types/observable/internal/BulkObjectLoader.test.d.ts +1 -0
  401. package/build/types/observable/internal/BulkObjectLoader.test.d.ts.map +1 -0
  402. package/build/types/observable/internal/CacheKeys.d.ts +1 -1
  403. package/build/types/observable/internal/CacheKeys.d.ts.map +1 -1
  404. package/build/types/observable/internal/Changes.d.ts +15 -0
  405. package/build/types/observable/internal/Changes.d.ts.map +1 -0
  406. package/build/types/observable/internal/Layer.d.ts +1 -0
  407. package/build/types/observable/internal/Layer.d.ts.map +1 -1
  408. package/build/types/observable/internal/ListQuery.d.ts +59 -14
  409. package/build/types/observable/internal/ListQuery.d.ts.map +1 -1
  410. package/build/types/observable/internal/ObjectQuery.d.ts +5 -6
  411. package/build/types/observable/internal/ObjectQuery.d.ts.map +1 -1
  412. package/build/types/observable/internal/OptimisticJob.d.ts +1 -1
  413. package/build/types/observable/internal/OptimisticJob.d.ts.map +1 -1
  414. package/build/types/observable/internal/OrderByCanonicalizer.d.ts +12 -0
  415. package/build/types/observable/internal/OrderByCanonicalizer.d.ts.map +1 -0
  416. package/build/types/observable/internal/OrderByCanonicalizer.test.d.ts +1 -0
  417. package/build/types/observable/internal/OrderByCanonicalizer.test.d.ts.map +1 -0
  418. package/build/types/observable/internal/Query.d.ts +41 -6
  419. package/build/types/observable/internal/Query.d.ts.map +1 -1
  420. package/build/types/observable/internal/RefCounts.d.ts.map +1 -1
  421. package/build/types/observable/internal/SimpleWhereClause.d.ts +2 -0
  422. package/build/types/observable/internal/SimpleWhereClause.d.ts.map +1 -0
  423. package/build/types/observable/internal/Store.d.ts +20 -44
  424. package/build/types/observable/internal/Store.d.ts.map +1 -1
  425. package/build/types/observable/internal/WhereClauseCanonicalizer.d.ts +2 -1
  426. package/build/types/observable/internal/WhereClauseCanonicalizer.d.ts.map +1 -1
  427. package/build/types/observable/internal/objectMatchesWhereClause.d.ts +4 -2
  428. package/build/types/observable/internal/objectMatchesWhereClause.d.ts.map +1 -1
  429. package/build/types/observable/internal/testUtils.d.ts +39 -10
  430. package/build/types/observable/internal/testUtils.d.ts.map +1 -1
  431. package/build/types/ontology/OntologyProvider.d.ts +1 -1
  432. package/build/types/ontology/OntologyProvider.d.ts.map +1 -1
  433. package/build/types/ontology/loadQueryMetadata.d.ts +1 -1
  434. package/build/types/ontology/loadQueryMetadata.d.ts.map +1 -1
  435. package/build/types/public/internal.d.ts +2 -0
  436. package/build/types/public/internal.d.ts.map +1 -1
  437. package/build/types/public/unstable-do-not-use.d.ts +4 -5
  438. package/build/types/public/unstable-do-not-use.d.ts.map +1 -1
  439. package/build/types/public-utils/osdkConfig.d.ts +8 -0
  440. package/build/types/public-utils/osdkConfig.d.ts.map +1 -0
  441. package/build/types/public-utils/vite-env.d.d.ts +3 -0
  442. package/build/types/public-utils/vite-env.d.d.ts.map +1 -0
  443. package/build/types/queries/applyQuery.d.ts +2 -2
  444. package/build/types/queries/applyQuery.d.ts.map +1 -1
  445. package/build/types/queries/types.d.ts +1 -1
  446. package/build/types/queries/types.d.ts.map +1 -1
  447. package/build/types/tsserver.d.ts +1 -1
  448. package/build/types/tsserver.d.ts.map +1 -1
  449. package/build/types/util/extractRdpDefinition.d.ts +4 -0
  450. package/build/types/util/extractRdpDefinition.d.ts.map +1 -0
  451. package/build/types/util/extractRdpDefinition.test.d.ts +1 -0
  452. package/build/types/util/extractRdpDefinition.test.d.ts.map +1 -0
  453. package/build/types/util/isObjectSpecifiersObject.d.ts +5 -0
  454. package/build/types/util/isObjectSpecifiersObject.d.ts.map +1 -0
  455. package/build/types/util/isPoint.d.ts +1 -0
  456. package/build/types/util/isPoint.d.ts.map +1 -0
  457. package/build/types/util/objectSpecifierUtils.d.ts +24 -0
  458. package/build/types/util/objectSpecifierUtils.d.ts.map +1 -0
  459. package/build/types/util/objectSpecifierUtils.test.d.ts +1 -0
  460. package/build/types/util/objectSpecifierUtils.test.d.ts.map +1 -0
  461. package/package.json +21 -18
  462. package/build/browser/Logger.js +0 -2
  463. package/build/browser/Logger.js.map +0 -1
  464. package/build/browser/object/createObjectSpecifierFromPrimaryKey.js.map +0 -1
  465. package/build/browser/observable/internal/ChangedObjects.js.map +0 -1
  466. package/build/browser/util/isOsdkBaseObject.js.map +0 -1
  467. package/build/browser/util/isOsdkObject.js.map +0 -1
  468. package/build/cjs/chunk-IU47QMYO.cjs.map +0 -1
  469. package/build/cjs/chunk-JPENHIJB.cjs.map +0 -1
  470. package/build/cjs/chunk-Q7SFCCGT.cjs +0 -11
  471. package/build/cjs/chunk-Q7SFCCGT.cjs.map +0 -1
  472. package/build/cjs/graphql-RGM5SRWV.cjs +0 -10532
  473. package/build/cjs/graphql-RGM5SRWV.cjs.map +0 -1
  474. package/build/esm/Logger.js +0 -2
  475. package/build/esm/Logger.js.map +0 -1
  476. package/build/esm/object/createObjectSpecifierFromPrimaryKey.js.map +0 -1
  477. package/build/esm/observable/internal/ChangedObjects.js.map +0 -1
  478. package/build/esm/util/isOsdkBaseObject.js.map +0 -1
  479. package/build/esm/util/isOsdkObject.js.map +0 -1
  480. package/build/types/Logger.d.ts +0 -17
  481. package/build/types/Logger.d.ts.map +0 -1
  482. package/build/types/object/createObjectSpecifierFromPrimaryKey.d.ts +0 -2
  483. package/build/types/object/createObjectSpecifierFromPrimaryKey.d.ts.map +0 -1
  484. package/build/types/observable/internal/ChangedObjects.d.ts +0 -11
  485. package/build/types/observable/internal/ChangedObjects.d.ts.map +0 -1
  486. package/build/types/util/isOsdkBaseObject.d.ts +0 -2
  487. package/build/types/util/isOsdkBaseObject.d.ts.map +0 -1
  488. package/build/types/util/isOsdkObject.d.ts +0 -2
  489. package/build/types/util/isOsdkObject.d.ts.map +0 -1
@@ -14,16 +14,21 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { $ontologyRid, createOffice, Employee, Todo } from "@osdk/client.test.ontology";
18
- import { apiServer } from "@osdk/shared.test";
17
+ import { editTodo, Employee, FooInterface, Todo } from "@osdk/client.test.ontology";
18
+ import { ActionTypeBuilder, FauxFoundry, ontologies, startNodeApiServer, stubData } from "@osdk/shared.test";
19
19
  import chalk from "chalk";
20
+ import invariant from "tiny-invariant";
20
21
  import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi, vitest } from "vitest";
22
+ import { ActionValidationError } from "../../actions/ActionValidationError.js";
21
23
  import { createClient } from "../../createClient.js";
24
+ import { TestLogger } from "../../logger/TestLogger.js";
22
25
  import { createOptimisticId } from "./OptimisticId.js";
23
26
  import { runOptimisticJob } from "./OptimisticJob.js";
24
- import { Store } from "./Store.js";
25
- import { applyCustomMatchers, createClientMockHelper, createDefer, createTestLogger, expectSingleListCallAndClear, expectSingleObjectCallAndClear, listPayloadContaining, mockListSubCallback, mockSingleSubCallback, objectPayloadContaining, waitForCall } from "./testUtils.js";
27
+ import { invalidateList, Store } from "./Store.js";
28
+ import { applyCustomMatchers, createClientMockHelper, createDefer, expectNoMoreCalls, expectSingleListCallAndClear, expectSingleObjectCallAndClear, getObject, mockListSubCallback, mockSingleSubCallback, objectPayloadContaining, updateList, updateObject, waitForCall } from "./testUtils.js";
29
+ const JOHN_DOE_ID = 50030;
26
30
  const defer = createDefer();
31
+ const logger = new TestLogger();
27
32
  beforeAll(() => {
28
33
  vi.setConfig({
29
34
  fakeTimers: {
@@ -54,6 +59,42 @@ function testStage(s) {
54
59
  console.log(chalk.bgYellow(`Test Stage: ${s}`));
55
60
  }
56
61
  applyCustomMatchers();
62
+ function setupOntology(fauxFoundry) {
63
+ const fauxOntology = fauxFoundry.getDefaultOntology();
64
+ ontologies.addEmployeeOntology(fauxOntology);
65
+ fauxFoundry.getDefaultOntology().registerObjectType(stubData.todoWithLinkTypes);
66
+ fauxFoundry.getDefaultOntology().registerActionType(stubData.editTodo.actionTypeV2, (b, payload) => {
67
+ const {
68
+ id,
69
+ ...other
70
+ } = payload.parameters;
71
+ b.modifyObject(Todo.apiName, id, {
72
+ ...other
73
+ });
74
+ });
75
+ }
76
+ function setupSomeEmployees(fauxFoundry) {
77
+ const dataStore = fauxFoundry.getDefaultDataStore();
78
+ dataStore.registerObject(Employee, {
79
+ employeeId: 1
80
+ });
81
+ dataStore.registerObject(Employee, {
82
+ employeeId: 2
83
+ });
84
+ dataStore.registerObject(Employee, {
85
+ $apiName: "Employee",
86
+ employeeId: 3
87
+ });
88
+ dataStore.registerObject(Employee, {
89
+ $apiName: "Employee",
90
+ employeeId: 4
91
+ });
92
+ dataStore.registerObject(Employee, {
93
+ $apiName: "Employee",
94
+ employeeId: JOHN_DOE_ID,
95
+ fullName: "John Doe"
96
+ });
97
+ }
57
98
  describe(Store, () => {
58
99
  describe("with mock server", () => {
59
100
  let client;
@@ -61,46 +102,51 @@ describe(Store, () => {
61
102
  let employeesAsServerReturns;
62
103
  let mutatedEmployees;
63
104
  beforeAll(async () => {
64
- apiServer.listen();
65
- client = createClient("https://stack.palantir.com", $ontologyRid, async () => "myAccessToken", {
66
- logger: createTestLogger({})
105
+ const testSetup = startNodeApiServer(new FauxFoundry("https://stack.palantir.com/"), createClient, {
106
+ logger
67
107
  });
108
+ ({
109
+ client
110
+ } = testSetup);
111
+ setupOntology(testSetup.fauxFoundry);
112
+ setupSomeEmployees(testSetup.fauxFoundry);
68
113
  employeesAsServerReturns = (await client(Employee).fetchPage()).data;
69
114
  mutatedEmployees = [employeesAsServerReturns[0], employeesAsServerReturns[1].$clone({
70
115
  fullName: "foo"
71
116
  }), ...employeesAsServerReturns.slice(2)];
72
- });
73
- afterAll(() => {
74
- apiServer.close();
117
+ return () => {
118
+ testSetup.apiServer.close();
119
+ };
75
120
  });
76
121
  beforeEach(() => {
77
122
  cache = new Store(client);
78
- });
79
- afterEach(() => {
80
- cache = undefined;
123
+ return () => {
124
+ cache = undefined;
125
+ };
81
126
  });
82
127
  it("basic single object works", async () => {
83
128
  const emp = employeesAsServerReturns[0];
129
+ const cacheKey = cache.getCacheKey("object", "Employee", emp.$primaryKey);
84
130
 
85
131
  // starts empty
86
- expect(cache.getObject(Employee, emp.$primaryKey)).toBeUndefined();
87
- const result = cache.updateObject(Employee, emp);
132
+ expect(cache.getValue(cacheKey)?.value).toBeUndefined();
133
+ const result = updateObject(cache, emp);
88
134
  expect(emp).toBe(result);
89
135
 
90
136
  // getting the object now matches the result
91
- expect(cache.getObject(Employee, emp.$primaryKey)).toEqual(result);
92
- const updatedEmpFromCache = cache.updateObject(Employee, emp.$clone({
137
+ expect(cache.getValue(cacheKey)?.value).toEqual(result);
138
+ const updatedEmpFromCache = updateObject(cache, emp.$clone({
93
139
  fullName: "new name"
94
140
  }));
95
141
  expect(updatedEmpFromCache).not.toBe(emp);
96
142
 
97
143
  // getting it again is the updated object
98
- expect(cache.getObject(Employee, emp.$primaryKey)).toEqual(updatedEmpFromCache);
144
+ expect(cache.getValue(cacheKey)?.value).toEqual(updatedEmpFromCache);
99
145
  });
100
146
  describe("optimistic updates", () => {
101
147
  it("rolls back objects", async () => {
102
148
  const emp = employeesAsServerReturns[0];
103
- cache.updateObject(Employee, emp); // pre-seed the cache with the "real" value
149
+ updateObject(cache, emp); // pre-seed the cache with the "real" value
104
150
 
105
151
  const subFn = mockSingleSubCallback();
106
152
  defer(cache.observeObject(Employee, emp.$primaryKey, {
@@ -109,7 +155,7 @@ describe(Store, () => {
109
155
  expectSingleObjectCallAndClear(subFn, emp, "loaded");
110
156
  const optimisticId = createOptimisticId();
111
157
  // update with an optimistic write
112
- cache.updateObject(Employee, emp.$clone({
158
+ updateObject(cache, emp.$clone({
113
159
  fullName: "new name"
114
160
  }), {
115
161
  optimisticId
@@ -124,8 +170,8 @@ describe(Store, () => {
124
170
  });
125
171
  it("rolls back to an updated real value", async () => {
126
172
  // pre-seed the cache with the "real" value
127
- cache.updateList({
128
- objectType: Employee,
173
+ updateList(cache, {
174
+ type: Employee,
129
175
  where: {},
130
176
  orderBy: {}
131
177
  }, employeesAsServerReturns);
@@ -137,7 +183,7 @@ describe(Store, () => {
137
183
  expectSingleObjectCallAndClear(empSubFn, emp, "loaded");
138
184
  const listSubFn = mockListSubCallback();
139
185
  defer(cache.observeList({
140
- objectType: Employee,
186
+ type: Employee,
141
187
  mode: "offline"
142
188
  }, listSubFn));
143
189
  await waitForCall(listSubFn, 1);
@@ -147,10 +193,10 @@ describe(Store, () => {
147
193
  });
148
194
  const optimisticId = createOptimisticId();
149
195
  testStage("optimistic update");
150
- expect(listSubFn).not.toHaveBeenCalled();
196
+ expect(listSubFn.next).not.toHaveBeenCalled();
151
197
 
152
198
  // update with an optimistic write
153
- cache.updateObject(Employee, optimisticEmployee, {
199
+ updateObject(cache, optimisticEmployee, {
154
200
  optimisticId
155
201
  });
156
202
  testStage("after optimistic update");
@@ -170,8 +216,8 @@ describe(Store, () => {
170
216
  fullName: "real update"
171
217
  });
172
218
  testStage("write real update");
173
- cache.updateList({
174
- objectType: Employee,
219
+ updateList(cache, {
220
+ type: Employee,
175
221
  where: {},
176
222
  orderBy: {}
177
223
  }, [truthUpdatedEmployee]);
@@ -188,47 +234,38 @@ describe(Store, () => {
188
234
  status: "loaded",
189
235
  isOptimistic: false
190
236
  });
191
- vi.useRealTimers();
192
237
  });
193
238
  it("rolls back to an updated real value via list", async () => {
194
239
  const emp = employeesAsServerReturns[0];
195
- cache.updateObject(Employee, emp); // pre-seed the cache with the "real" value
240
+ updateObject(cache, emp); // pre-seed the cache with the "real" value
196
241
 
197
242
  const subFn = mockSingleSubCallback();
198
243
  defer(cache.observeObject(Employee, emp.$primaryKey, {
199
244
  mode: "offline"
200
245
  }, subFn));
201
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
202
- object: emp,
203
- status: "loaded"
204
- }));
205
- subFn.mockClear();
246
+ expectSingleObjectCallAndClear(subFn, emp, "loaded");
206
247
  const optimisticEmployee = emp.$clone({
207
248
  fullName: "new name"
208
249
  });
209
250
 
210
251
  // update with an optimistic write
211
252
  const optimisticId = createOptimisticId();
212
- cache.updateObject(Employee, optimisticEmployee, {
253
+ updateObject(cache, optimisticEmployee, {
213
254
  optimisticId
214
255
  });
215
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
216
- object: optimisticEmployee
217
- }));
218
- subFn.mockClear();
256
+ expectSingleObjectCallAndClear(subFn, optimisticEmployee);
219
257
  const truthUpdatedEmployee = emp.$clone({
220
258
  fullName: "real update"
221
259
  });
222
- cache.updateObject(Employee, truthUpdatedEmployee);
260
+ updateObject(cache, truthUpdatedEmployee);
223
261
 
224
262
  // we shouldn't expect an update because the top layer has a value
225
- expect(subFn).not.toHaveBeenCalled();
263
+ expect(subFn.next).not.toHaveBeenCalled();
226
264
 
227
265
  // remove the optimistic write
228
266
  cache.removeLayer(optimisticId);
229
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
230
- object: truthUpdatedEmployee
231
- }));
267
+ expectSingleObjectCallAndClear(subFn, truthUpdatedEmployee);
268
+ expectNoMoreCalls(subFn);
232
269
  });
233
270
  });
234
271
  describe(".invalidateObject", () => {
@@ -237,29 +274,20 @@ describe(Store, () => {
237
274
  const staleEmp = emp.$clone({
238
275
  fullName: "stale"
239
276
  });
240
- cache.updateObject(Employee, staleEmp);
277
+ updateObject(cache, staleEmp);
241
278
  const subFn = mockSingleSubCallback();
242
279
  defer(cache.observeObject(Employee, emp.$primaryKey, {
243
280
  mode: "offline"
244
281
  }, subFn));
245
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
246
- object: staleEmp,
247
- status: "loaded"
248
- }));
249
- subFn.mockClear();
282
+ expectSingleObjectCallAndClear(subFn, staleEmp, "loaded");
250
283
 
251
284
  // invalidate
252
285
  void cache.invalidateObject(Employee, staleEmp.$primaryKey);
253
- await vi.waitFor(() => expect(subFn).toHaveBeenCalled());
254
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
255
- object: staleEmp,
256
- status: "loading"
257
- }));
258
- subFn.mockClear();
259
- await vi.waitFor(() => expect(subFn).toHaveBeenCalled());
260
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
261
- object: emp
262
- }));
286
+ await waitForCall(subFn);
287
+ expectSingleObjectCallAndClear(subFn, staleEmp, "loading");
288
+ await waitForCall(subFn);
289
+ expectSingleObjectCallAndClear(subFn, emp, "loaded");
290
+ expectNoMoreCalls(subFn);
263
291
  });
264
292
  });
265
293
  describe(".invalidateList", () => {
@@ -274,8 +302,8 @@ describe(Store, () => {
274
302
  const staleEmp = emp.$clone({
275
303
  fullName: "stale"
276
304
  });
277
- cache.updateList({
278
- objectType: Employee,
305
+ updateList(cache, {
306
+ type: Employee,
279
307
  where: {},
280
308
  orderBy: {}
281
309
  }, [staleEmp]);
@@ -286,7 +314,7 @@ describe(Store, () => {
286
314
  expectSingleObjectCallAndClear(subFn, staleEmp);
287
315
  const subListFn = mockListSubCallback();
288
316
  defer(cache.observeList({
289
- objectType: Employee,
317
+ type: Employee,
290
318
  mode: "offline"
291
319
  }, subListFn));
292
320
  await waitForCall(subListFn, 1);
@@ -294,8 +322,8 @@ describe(Store, () => {
294
322
  status: "loaded"
295
323
  });
296
324
  testStage("invalidate");
297
- cache.invalidateList({
298
- objectType: Employee
325
+ const invalidateListPromise = invalidateList(cache, {
326
+ type: Employee
299
327
  });
300
328
  testStage("check invalidate");
301
329
  await waitForCall(subListFn, 1);
@@ -308,6 +336,9 @@ describe(Store, () => {
308
336
  });
309
337
  await waitForCall(subFn, 1);
310
338
  expectSingleObjectCallAndClear(subFn, emp, "loaded");
339
+
340
+ // don't leave promises dangling
341
+ await invalidateListPromise;
311
342
  });
312
343
  });
313
344
  describe(".invalidateObjectType", () => {
@@ -322,8 +353,8 @@ describe(Store, () => {
322
353
  const staleEmp = emp.$clone({
323
354
  fullName: "stale"
324
355
  });
325
- cache.updateList({
326
- objectType: Employee,
356
+ updateList(cache, {
357
+ type: Employee,
327
358
  where: {},
328
359
  orderBy: {}
329
360
  }, [staleEmp]);
@@ -334,7 +365,7 @@ describe(Store, () => {
334
365
  expectSingleObjectCallAndClear(subFn, staleEmp);
335
366
  const subListFn = mockListSubCallback();
336
367
  defer(cache.observeList({
337
- objectType: Employee,
368
+ type: Employee,
338
369
  where: {},
339
370
  orderBy: {},
340
371
  mode: "offline"
@@ -346,21 +377,13 @@ describe(Store, () => {
346
377
  testStage("invalidate");
347
378
  const pInvalidateComplete = cache.invalidateObjectType(Employee, undefined);
348
379
  await waitForCall(subListFn, 1);
349
- expect(subListFn).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
350
- resolvedList: [staleEmp],
380
+ expectSingleListCallAndClear(subListFn, [staleEmp], {
351
381
  status: "loading"
352
- }));
353
- subListFn.mockClear();
354
- await vi.waitFor(() => expect(subListFn).toHaveBeenCalled());
355
- expect(subListFn).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
356
- resolvedList: employeesAsServerReturns
357
- }));
358
- subListFn.mockClear();
359
- await vi.waitFor(() => expect(subFn).toHaveBeenCalled());
360
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
361
- status: "loaded",
362
- object: emp
363
- }));
382
+ });
383
+ await waitForCall(subListFn, 1);
384
+ expectSingleListCallAndClear(subListFn, employeesAsServerReturns);
385
+ await waitForCall(subFn, 1);
386
+ expectSingleObjectCallAndClear(subFn, emp, "loaded");
364
387
 
365
388
  // we don't need this value to control the test but we want to make sure we don't have
366
389
  // any unhandled exceptions upon test completion
@@ -371,53 +394,51 @@ describe(Store, () => {
371
394
  const subFn1 = mockSingleSubCallback();
372
395
  const subFn2 = mockSingleSubCallback();
373
396
  beforeEach(async () => {
374
- subFn1.mockClear();
375
- subFn2.mockClear();
397
+ subFn1.complete.mockClear();
398
+ subFn1.next.mockClear();
399
+ subFn1.error.mockClear();
400
+ subFn2.complete.mockClear();
401
+ subFn2.next.mockClear();
402
+ subFn2.error.mockClear();
376
403
  });
377
404
  const likeEmployee50030 = expect.objectContaining({
378
- $primaryKey: 50030,
405
+ $primaryKey: JOHN_DOE_ID,
379
406
  fullName: "John Doe"
380
407
  });
381
408
  it("fetches and updates twice", async () => {
382
- defer(cache.observeObject(Employee, 50030, {
409
+ defer(cache.observeObject(Employee, JOHN_DOE_ID, {
383
410
  mode: "force"
384
411
  }, subFn1));
385
- expect(subFn1).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
412
+ expect(subFn1.next).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
386
413
  status: "loading",
387
414
  object: undefined,
388
415
  isOptimistic: false
389
416
  }));
390
- subFn1.mockClear();
391
- await vi.waitFor(() => expect(subFn1).toHaveBeenCalled());
392
- expect(subFn1).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
417
+ subFn1.next.mockClear();
418
+ await waitForCall(subFn1);
419
+ expect(subFn1.next).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
393
420
  object: likeEmployee50030,
394
421
  isOptimistic: false
395
422
  }));
396
- const firstLoad = subFn1.mock.lastCall?.[0];
397
- subFn1.mockClear();
398
- defer(cache.observeObject(Employee, 50030, {
423
+ const firstLoad = subFn1.next.mock.lastCall?.[0];
424
+ subFn1.next.mockClear();
425
+ defer(cache.observeObject(Employee, JOHN_DOE_ID, {
399
426
  mode: "force"
400
427
  }, subFn2));
401
- expect(subFn1).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
402
- status: "loading"
403
- }));
404
- subFn1.mockClear();
428
+ expectSingleObjectCallAndClear(subFn1, likeEmployee50030, "loading");
405
429
 
406
430
  // should be the earlier results
407
- expect(subFn2).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
408
- status: "loading"
409
- }));
410
- subFn2.mockClear();
431
+ expectSingleObjectCallAndClear(subFn2, likeEmployee50030, "loading");
411
432
 
412
433
  // both will be updated
413
434
  for (const s of [subFn1, subFn2]) {
414
435
  // wait for the result to come in
415
- await vi.waitFor(() => expect(s).toHaveBeenCalled());
416
- expect(s).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
436
+ await waitForCall(s, 1);
437
+ expect(s.next).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
417
438
  ...firstLoad,
418
439
  lastUpdated: expect.toBeGreaterThan(firstLoad.lastUpdated)
419
440
  }));
420
- s.mockClear();
441
+ s.next.mockClear();
421
442
  }
422
443
  });
423
444
  });
@@ -425,68 +446,66 @@ describe(Store, () => {
425
446
  const subFn = mockSingleSubCallback();
426
447
  let sub;
427
448
  beforeEach(() => {
428
- subFn.mockClear();
429
- sub = defer(cache.observeObject(Employee, 50030, {
449
+ subFn.complete.mockClear();
450
+ subFn.next.mockClear();
451
+ subFn.error.mockClear();
452
+ sub = defer(cache.observeObject(Employee, JOHN_DOE_ID, {
430
453
  mode: "offline"
431
454
  }, subFn));
432
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
433
- status: "init",
434
- object: undefined
435
- }));
436
- subFn.mockClear();
455
+ expectSingleObjectCallAndClear(subFn, undefined, "init");
437
456
  });
438
457
  it("does basic observation and unsubscribe", async () => {
439
- const emp = employeesAsServerReturns[0];
458
+ const emp = employeesAsServerReturns.find(x => x.$primaryKey === JOHN_DOE_ID);
440
459
 
441
460
  // force an update
442
- cache.updateObject(Employee, emp);
443
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
444
- object: emp
445
- }));
446
- subFn.mockClear();
461
+ updateObject(cache, emp);
462
+ expectSingleObjectCallAndClear(subFn, emp);
447
463
 
448
464
  // force again
449
- cache.updateObject(Employee, emp.$clone({
465
+ updateObject(cache, emp.$clone({
450
466
  fullName: "new name"
451
467
  }));
452
- expect(subFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
453
- object: expect.objectContaining({
454
- fullName: "new name"
455
- })
468
+ expectSingleObjectCallAndClear(subFn, emp.$clone({
469
+ fullName: "new name"
456
470
  }));
457
- subFn.mockClear();
458
471
  sub.unsubscribe();
459
472
 
460
473
  // force again but no subscription update
461
- cache.updateObject(Employee, emp.$clone({
474
+ updateObject(cache, emp.$clone({
462
475
  fullName: "new name 2"
463
476
  }));
464
- expect(subFn).not.toHaveBeenCalled();
477
+ expect(subFn.next).not.toHaveBeenCalled();
465
478
  });
466
479
  it("observes with list update", async () => {
467
- const emp = employeesAsServerReturns[0];
480
+ const emp = employeesAsServerReturns.find(x => x.$primaryKey === JOHN_DOE_ID);
468
481
 
469
482
  // force an update
470
- cache.updateObject(Employee, emp.$clone({
483
+ updateObject(cache, emp.$clone({
471
484
  fullName: "not the name"
472
485
  }));
473
- expect(subFn).toHaveBeenCalledTimes(1);
474
- cache.updateList({
475
- objectType: Employee,
486
+ expect(subFn.next).toHaveBeenCalledTimes(1);
487
+ updateList(cache, {
488
+ type: Employee,
476
489
  where: {},
477
490
  orderBy: {}
478
491
  }, employeesAsServerReturns);
479
- expect(subFn).toHaveBeenCalledTimes(2);
480
- expect(subFn.mock.calls[1][0]).toEqual(objectPayloadContaining({
492
+ expect(subFn.next).toHaveBeenCalledTimes(2);
493
+ expect(subFn.next.mock.calls[1][0]).toEqual(objectPayloadContaining({
481
494
  object: emp
482
495
  }));
483
496
  });
484
497
  });
485
498
  describe(".observeList", () => {
486
499
  const listSub1 = mockListSubCallback();
500
+ const ifaceSub = mockListSubCallback();
487
501
  beforeEach(() => {
488
502
  vi.useFakeTimers({});
489
- listSub1.mockReset();
503
+ vi.mocked(listSub1.next).mockReset();
504
+ vi.mocked(listSub1.error).mockReset();
505
+ vi.mocked(listSub1.complete).mockReset();
506
+ vi.mocked(ifaceSub.next).mockReset();
507
+ vi.mocked(ifaceSub.error).mockReset();
508
+ vi.mocked(ifaceSub.complete).mockReset();
490
509
  });
491
510
  afterEach(() => {
492
511
  vi.useRealTimers();
@@ -494,102 +513,107 @@ describe(Store, () => {
494
513
  describe("mode=force", () => {
495
514
  it("initial load", async () => {
496
515
  defer(cache.observeList({
497
- objectType: Employee,
498
- where: {},
516
+ type: Employee,
499
517
  orderBy: {},
500
518
  mode: "force"
501
519
  }, listSub1));
520
+ defer(cache.observeList({
521
+ type: FooInterface,
522
+ orderBy: {},
523
+ mode: "force"
524
+ }, ifaceSub));
502
525
  vitest.runOnlyPendingTimers();
503
- await vi.waitFor(() => expect(listSub1).toHaveBeenCalled());
504
- expect(listSub1).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
505
- status: "loading",
506
- resolvedList: []
507
- }));
508
- listSub1.mockClear();
509
- await vi.waitFor(() => expect(listSub1).toHaveBeenCalled());
510
- expect(listSub1).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
511
- resolvedList: employeesAsServerReturns,
526
+ await waitForCall(listSub1);
527
+ await waitForCall(ifaceSub);
528
+ expectSingleListCallAndClear(listSub1, [], {
529
+ status: "loading"
530
+ });
531
+ expectSingleListCallAndClear(ifaceSub, [], {
532
+ status: "loading"
533
+ });
534
+ await waitForCall(listSub1);
535
+ expectSingleListCallAndClear(listSub1, employeesAsServerReturns, {
512
536
  status: "loaded"
513
- }));
537
+ });
538
+ await waitForCall(ifaceSub);
539
+ expectSingleListCallAndClear(ifaceSub, employeesAsServerReturns, {
540
+ status: "loaded"
541
+ });
542
+ expectNoMoreCalls(listSub1);
543
+ expectNoMoreCalls(ifaceSub);
544
+ expect(listSub1.next).not.toHaveBeenCalled();
545
+ expect(listSub1.error).not.toHaveBeenCalled();
546
+ expect(ifaceSub.next).not.toHaveBeenCalled();
547
+ expect(ifaceSub.error).not.toHaveBeenCalled();
514
548
  });
515
549
  it("subsequent load", async () => {
516
550
  // Pre-seed with data the server doesn't return
517
- cache.updateList({
518
- objectType: Employee,
551
+ updateList(cache, {
552
+ type: Employee,
519
553
  where: {},
520
554
  orderBy: {}
521
555
  }, mutatedEmployees);
522
556
  defer(cache.observeList({
523
- objectType: Employee,
557
+ type: Employee,
524
558
  mode: "force"
525
559
  }, listSub1));
526
560
  await waitForCall(listSub1, 1);
527
- const firstLoad = listSub1.mock.calls[0][0];
561
+ const firstLoad = listSub1.next.mock.calls[0][0];
528
562
  expectSingleListCallAndClear(listSub1, mutatedEmployees, {
529
563
  status: "loading"
530
564
  });
531
- await vi.waitFor(() => expect(listSub1).toHaveBeenCalled());
532
- expect(listSub1).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
533
- resolvedList: employeesAsServerReturns,
565
+ await waitForCall(listSub1, 1);
566
+ expectSingleListCallAndClear(listSub1, employeesAsServerReturns, {
534
567
  status: "loaded",
535
568
  lastUpdated: expect.toBeGreaterThan(firstLoad.lastUpdated)
536
- }));
537
- listSub1.mockClear();
569
+ });
538
570
  });
539
571
  });
540
572
  describe("mode = offline", () => {
541
573
  it("updates with list updates", async () => {
542
574
  defer(cache.observeList({
543
- objectType: Employee,
575
+ type: Employee,
544
576
  where: {},
545
577
  orderBy: {},
546
578
  mode: "offline"
547
579
  }, listSub1));
548
- expect(listSub1).toHaveBeenCalledTimes(0);
549
- cache.updateList({
550
- objectType: Employee,
580
+ expect(listSub1.next).toHaveBeenCalledTimes(0);
581
+ updateList(cache, {
582
+ type: Employee,
551
583
  where: {},
552
584
  orderBy: {}
553
585
  }, employeesAsServerReturns);
554
586
  vitest.runOnlyPendingTimers();
555
- expect(listSub1).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
556
- resolvedList: employeesAsServerReturns
557
- }));
558
- listSub1.mockClear();
587
+ expectSingleListCallAndClear(listSub1, employeesAsServerReturns);
559
588
 
560
589
  // list is just now one object
561
- cache.updateList({
562
- objectType: Employee,
590
+ updateList(cache, {
591
+ type: Employee,
563
592
  where: {},
564
593
  orderBy: {}
565
594
  }, [employeesAsServerReturns[0]]);
566
595
  vitest.runOnlyPendingTimers();
567
- expect(listSub1).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
568
- resolvedList: [employeesAsServerReturns[0]]
569
- }));
596
+ expectSingleListCallAndClear(listSub1, [employeesAsServerReturns[0]]);
570
597
  });
571
598
  it("updates with different list updates", async () => {
572
599
  defer(cache.observeList({
573
- objectType: Employee,
600
+ type: Employee,
574
601
  where: {},
575
602
  orderBy: {},
576
603
  mode: "offline"
577
604
  }, listSub1));
578
- expect(listSub1).toHaveBeenCalledTimes(0);
579
- cache.updateList({
580
- objectType: Employee,
605
+ expect(listSub1.next).toHaveBeenCalledTimes(0);
606
+ updateList(cache, {
607
+ type: Employee,
581
608
  where: {},
582
609
  orderBy: {}
583
610
  }, employeesAsServerReturns);
584
611
  vitest.runOnlyPendingTimers();
585
- expect(listSub1).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
586
- resolvedList: employeesAsServerReturns
587
- }));
588
- listSub1.mockClear();
612
+ expectSingleListCallAndClear(listSub1, employeesAsServerReturns);
589
613
 
590
614
  // new where === different list
591
- cache.updateList({
592
- objectType: Employee,
615
+ updateList(cache, {
616
+ type: Employee,
593
617
  where: {
594
618
  employeeId: {
595
619
  $gt: 0
@@ -600,9 +624,7 @@ describe(Store, () => {
600
624
  vitest.runOnlyPendingTimers();
601
625
 
602
626
  // original list updates still
603
- expect(listSub1).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
604
- resolvedList: mutatedEmployees
605
- }));
627
+ expectSingleListCallAndClear(listSub1, mutatedEmployees);
606
628
  });
607
629
  });
608
630
  });
@@ -616,56 +638,123 @@ describe(Store, () => {
616
638
  it("works in the solo case", async () => {
617
639
  const listSub = mockListSubCallback();
618
640
  defer(cache.observeList({
619
- objectType: Employee,
641
+ type: Employee,
620
642
  where: {},
621
643
  orderBy: {},
622
644
  mode: "force",
623
645
  pageSize: 1
624
646
  }, listSub));
625
- expect(listSub).not.toHaveBeenCalled();
626
- await vi.waitFor(() => expect(listSub).toHaveBeenCalled());
627
- expect(listSub).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
647
+ expect(listSub.next).not.toHaveBeenCalled();
648
+ await waitForCall(listSub, 1);
649
+ expectSingleListCallAndClear(listSub, [], {
628
650
  status: "loading"
629
- }));
630
- listSub.mockClear();
631
- await vi.waitFor(() => expect(listSub).toHaveBeenCalled());
632
- expect(listSub).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
633
- resolvedList: employeesAsServerReturns.slice(0, 1),
634
- status: "loaded"
635
- }));
651
+ });
652
+ await waitForCall(listSub, 1);
636
653
  const {
637
654
  fetchMore
638
- } = listSub.mock.calls[0][0];
639
- listSub.mockClear();
655
+ } = listSub.next.mock.calls[0][0];
656
+ expectSingleListCallAndClear(listSub, employeesAsServerReturns.slice(0, 1), {
657
+ status: "loaded"
658
+ });
640
659
  void fetchMore();
641
- await vi.waitFor(() => expect(listSub).toHaveBeenCalledTimes(1));
642
- expect(listSub).toHaveBeenCalledExactlyOnceWith(listPayloadContaining({
643
- resolvedList: employeesAsServerReturns.slice(0, 1),
660
+ await waitForCall(listSub, 1);
661
+ expectSingleListCallAndClear(listSub, employeesAsServerReturns.slice(0, 1), {
644
662
  status: "loading"
645
- }));
646
- listSub.mockClear();
647
- await vi.waitFor(() => expect(listSub).toHaveBeenCalledTimes(1));
648
- expect(listSub).toHaveBeenCalledWith(listPayloadContaining({
649
- resolvedList: employeesAsServerReturns.slice(0, 2),
663
+ });
664
+ await waitForCall(listSub, 1);
665
+ expectSingleListCallAndClear(listSub, employeesAsServerReturns.slice(0, 2), {
650
666
  status: "loaded"
651
- }));
667
+ });
652
668
  });
653
669
  });
654
670
  });
655
671
  describe("with mock client", () => {
656
672
  let client;
657
- let mockClient;
673
+ let apiServer;
674
+ let fauxFoundry;
658
675
  let store;
676
+ beforeAll(async () => {
677
+ const testSetup = startNodeApiServer(new FauxFoundry("https://stack.palantir.com/", undefined, {
678
+ logger
679
+ }), createClient, {
680
+ logger
681
+ });
682
+ ({
683
+ client,
684
+ apiServer,
685
+ fauxFoundry
686
+ } = testSetup);
687
+ setupOntology(testSetup.fauxFoundry);
688
+ return () => {
689
+ testSetup.apiServer.close();
690
+ };
691
+ });
692
+ beforeEach(() => {
693
+ apiServer.resetHandlers();
694
+ });
659
695
  beforeEach(async () => {
660
- mockClient = createClientMockHelper();
661
- client = mockClient.client;
662
696
  store = new Store(client);
663
697
  });
698
+ it("properly fires error handler for a list", async () => {
699
+ const sub = mockListSubCallback();
700
+ store.observeList({
701
+ type: Employee,
702
+ where: {
703
+ aBadPropertyThatDoesNotExist: "aBadValue"
704
+ },
705
+ orderBy: {}
706
+ }, sub);
707
+ await waitForCall(sub.error, 1);
708
+ expect(sub.error).toHaveBeenCalled();
709
+ expect(sub.next).not.toHaveBeenCalled();
710
+ });
711
+ describe("batching", () => {
712
+ it("groups requests for single objects", async () => {
713
+ fauxFoundry.getDefaultDataStore().registerObject(Employee, {
714
+ $apiName: "Employee",
715
+ employeeId: 0
716
+ });
717
+ fauxFoundry.getDefaultDataStore().registerObject(Employee, {
718
+ $apiName: "Employee",
719
+ employeeId: 1
720
+ });
721
+ const a = mockSingleSubCallback();
722
+ const b = mockSingleSubCallback();
723
+ defer(store.observeObject(Employee, 0, {}, a));
724
+ defer(store.observeObject(Employee, 1, {}, b));
725
+ await a.expectLoadingAndLoaded({
726
+ loading: objectPayloadContaining({
727
+ status: "loading",
728
+ object: undefined
729
+ }),
730
+ loaded: objectPayloadContaining({
731
+ object: expect.objectContaining({
732
+ $primaryKey: 0
733
+ })
734
+ })
735
+ });
736
+ await b.expectLoadingAndLoaded({
737
+ loading: objectPayloadContaining({
738
+ status: "loading",
739
+ object: undefined
740
+ }),
741
+ loaded: objectPayloadContaining({
742
+ object: expect.objectContaining({
743
+ $primaryKey: 1
744
+ })
745
+ })
746
+ });
747
+ });
748
+ });
664
749
  describe("actions", () => {
750
+ beforeEach(() => {
751
+ fauxFoundry.getDefaultDataStore().clear();
752
+ });
665
753
  it("properly invalidates objects", async () => {
666
- // after the below `observeObject`, the cache will need to load from the server
667
- mockClient.mockFetchOneOnce().resolve({
668
- $apiName: "Todo"
754
+ fauxFoundry.getDefaultDataStore().registerObject(Todo, {
755
+ $apiName: "Todo",
756
+ id: 0,
757
+ text: "og title"
669
758
  });
670
759
  const todoSubFn = mockSingleSubCallback();
671
760
  defer(store.observeObject(Todo, 0, {}, todoSubFn));
@@ -682,23 +771,10 @@ describe(Store, () => {
682
771
  });
683
772
 
684
773
  // at this point we have an observation properly set up
685
- mockClient.mockApplyActionOnce().resolve({
686
- addedObjects: [{
687
- objectType: "Todo",
688
- primaryKey: 0
689
- }]
690
- });
691
-
692
- // after we apply the action, the object is invalidated and gets re-requested
693
-
694
- mockClient.mockFetchOneOnce().resolve({
695
- $apiName: "Todo",
774
+ await store.applyAction(editTodo, {
775
+ id: 0,
696
776
  text: "hello there kind sir"
697
777
  });
698
- const actionPromise = store.applyAction(createOffice, {
699
- officeId: "whatever"
700
- });
701
- await actionPromise;
702
778
  await todoSubFn.expectLoadingAndLoaded({
703
779
  loading: objectPayloadContaining({
704
780
  status: "loading"
@@ -711,15 +787,17 @@ describe(Store, () => {
711
787
  });
712
788
  });
713
789
  it("rolls back optimistic updates on error", async () => {
714
- const fauxObject = {
715
- $apiName: "Todo",
716
- $objectType: "Todo",
717
- $primaryKey: 0,
718
- $title: "does not matter"
719
- };
790
+ const fauxObject = expect.objectContaining({
791
+ id: 0,
792
+ text: "does not matter"
793
+ });
720
794
 
721
- // after the below `observeObject`, the cache will need to load from the server
722
- mockClient.mockFetchOneOnce().resolve(fauxObject);
795
+ // set the object in the "backend"
796
+ fauxFoundry.getDefaultDataStore().registerObject(Todo, {
797
+ $apiName: "Todo",
798
+ id: 0,
799
+ text: "does not matter"
800
+ });
723
801
  const todoSubFn = mockSingleSubCallback();
724
802
  defer(store.observeObject(Todo, 0, {}, todoSubFn));
725
803
  await todoSubFn.expectLoadingAndLoaded({
@@ -734,73 +812,61 @@ describe(Store, () => {
734
812
  isOptimistic: false
735
813
  })
736
814
  });
815
+ const object = store.getValue(store.getCacheKey("object", "Todo", 0))?.value;
816
+ !object ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
737
817
 
738
818
  // at this point we have an observation properly set up
739
- const applyActionResult = mockClient.mockApplyActionOnce();
740
- const actionPromise = store.applyAction(createOffice, {
741
- officeId: "whatever"
819
+ await expect(store.applyAction(editTodo, {
820
+ id: "not an id that exists"
742
821
  }, {
743
822
  optimisticUpdate: ctx => {
744
- ctx.updateObject({
745
- ...fauxObject,
823
+ ctx.updateObject(object.$clone({
746
824
  text: "optimistic"
747
- });
825
+ }));
748
826
  }
827
+ })).rejects.toThrow(ActionValidationError);
828
+ await waitForCall(todoSubFn, 2);
829
+ await todoSubFn.expectLoadingAndLoaded({
830
+ loading: objectPayloadContaining({
831
+ status: "loading",
832
+ object: expect.objectContaining({
833
+ id: 0,
834
+ text: "optimistic"
835
+ }),
836
+ isOptimistic: true
837
+ }),
838
+ loaded: objectPayloadContaining({
839
+ object: fauxObject,
840
+ status: "loaded",
841
+ isOptimistic: false
842
+ })
749
843
  });
750
- await waitForCall(todoSubFn, 1);
751
- expect(todoSubFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
752
- object: {
753
- ...fauxObject,
754
- text: "optimistic"
755
- },
756
- status: "loading",
757
- isOptimistic: true
758
- }));
759
- todoSubFn.mockClear();
760
-
761
- // let the action error out
762
- applyActionResult.reject("an error thrown");
763
- await expect(actionPromise).rejects.toThrow("an error thrown");
764
-
765
- // back to the original object
766
- await waitForCall(todoSubFn, 1);
767
- expect(todoSubFn).toHaveBeenCalledExactlyOnceWith(objectPayloadContaining({
768
- object: fauxObject,
769
- status: "loaded",
770
- isOptimistic: false
771
- }));
772
844
  });
773
845
  });
774
- describe("orderBy", () => {
846
+ describe("orderBy", async () => {
775
847
  let nextPk = 0;
776
- const fauxObjectA = {
777
- $apiName: "Todo",
778
- $objectType: "Todo",
779
- $primaryKey: nextPk++,
780
- $title: "a",
781
- text: "a"
782
- };
783
- const fauxObjectB = {
784
- $apiName: "Todo",
785
- $objectType: "Todo",
786
- $primaryKey: nextPk++,
787
- $title: "b",
788
- text: "b"
789
- };
790
- const fauxObjectC = {
791
- $apiName: "Todo",
792
- $objectType: "Todo",
793
- $primaryKey: nextPk++,
794
- $title: "c",
795
- text: "c"
796
- };
848
+ let fauxObjectA;
849
+ let fauxObjectB;
850
+ let fauxObjectC;
851
+ beforeAll(async () => {
852
+ fauxFoundry.getDefaultDataStore().clear();
853
+ [fauxObjectA, fauxObjectB, fauxObjectC] = await Promise.all(["a", "b", "c"].map(text => {
854
+ const id = nextPk++;
855
+ fauxFoundry.getDefaultDataStore().registerObject(Todo, {
856
+ $apiName: "Todo",
857
+ id,
858
+ text
859
+ });
860
+ return client(Todo).fetchOne(id);
861
+ }));
862
+ });
797
863
  const noWhereNoOrderBy = {
798
- objectType: Todo,
864
+ type: Todo,
799
865
  where: {},
800
866
  orderBy: {}
801
867
  };
802
868
  const noWhereOrderByText = {
803
- objectType: Todo,
869
+ type: Todo,
804
870
  where: {},
805
871
  orderBy: {
806
872
  text: "asc"
@@ -813,16 +879,16 @@ describe(Store, () => {
813
879
  ...noWhereNoOrderBy,
814
880
  mode: "offline"
815
881
  }, subListUnordered));
816
- expect(subListUnordered).toHaveBeenCalledTimes(0);
882
+ expect(subListUnordered.next).toHaveBeenCalledTimes(0);
817
883
  defer(store.observeList({
818
884
  ...noWhereOrderByText,
819
885
  mode: "offline"
820
886
  }, subListOrdered));
821
- expect(subListOrdered).toHaveBeenCalledTimes(0);
887
+ expect(subListOrdered.next).toHaveBeenCalledTimes(0);
822
888
  });
823
889
  it("invalidates the correct lists", async () => {
824
890
  // for whatever reason, the first list is loaded as [B, A]
825
- store.updateList(noWhereNoOrderBy, [fauxObjectB, fauxObjectA]);
891
+ updateList(store, noWhereNoOrderBy, [fauxObjectB, fauxObjectA]);
826
892
  await waitForCall(subListUnordered, 1);
827
893
  expectSingleListCallAndClear(subListUnordered, [fauxObjectB, fauxObjectA]);
828
894
 
@@ -833,8 +899,8 @@ describe(Store, () => {
833
899
 
834
900
  // For whatever reason, object B is no longer in the first set (use your imagination)
835
901
  // but we have added a C before A. So the first list is [C, A]
836
- store.updateList({
837
- objectType: Todo,
902
+ updateList(store, {
903
+ type: Todo,
838
904
  where: {},
839
905
  orderBy: {}
840
906
  }, [fauxObjectC, fauxObjectA]);
@@ -847,22 +913,17 @@ describe(Store, () => {
847
913
  expectSingleListCallAndClear(subListOrdered, [fauxObjectA, fauxObjectB, fauxObjectC]);
848
914
  });
849
915
  it("produces proper results with optimistic updates and successful action", async () => {
850
- const optimisticallyMutatedA = {
851
- ...fauxObjectA,
916
+ const optimisticallyMutatedA = fauxObjectA.$clone({
852
917
  text: "optimistic"
853
- };
918
+ });
854
919
  const pkForOptimistic = nextPk++;
855
- const optimisticallyCreatedObjectD = {
856
- "$apiName": "Todo",
857
- "$objectType": "Todo",
858
- "$primaryKey": pkForOptimistic,
859
- "$title": "d",
920
+ const optimisticallyCreatedObjectD = expect.objectContaining({
860
921
  "text": "d",
861
922
  id: pkForOptimistic
862
- };
923
+ });
863
924
 
864
925
  // for whatever reason, the first list is loaded as [B, A]
865
- store.updateList(noWhereNoOrderBy, [fauxObjectB, fauxObjectA]);
926
+ updateList(store, noWhereNoOrderBy, [fauxObjectB, fauxObjectA]);
866
927
  await waitForCall(subListUnordered, 1);
867
928
  expectSingleListCallAndClear(subListUnordered, [fauxObjectB, fauxObjectA]);
868
929
 
@@ -872,10 +933,6 @@ describe(Store, () => {
872
933
  expectSingleListCallAndClear(subListOrdered, [fauxObjectA, fauxObjectB]);
873
934
  testStage("Start");
874
935
 
875
- // the optimistic job will call createObject which triggers the `objectFactory2` of the
876
- // cache context.
877
- mockClient.mockObjectFactory2Once().resolve([optimisticallyCreatedObjectD]);
878
-
879
936
  // Perform something optimistic.
880
937
  const removeOptimisticResult = runOptimisticJob(store, b => {
881
938
  b.createObject(Todo, pkForOptimistic, {
@@ -917,32 +974,20 @@ describe(Store, () => {
917
974
  // I think these are named backwards
918
975
  it("produces proper results with optimistic updates and rollback", async () => {
919
976
  const pkForOptimistic = nextPk++;
920
- const optimisticallyCreatedObjectD = {
921
- "$apiName": "Todo",
922
- "$objectType": "Todo",
977
+ const optimisticallyCreatedObjectD = expect.objectContaining({
923
978
  "$primaryKey": pkForOptimistic,
924
- "$title": "d",
925
- "text": "d",
979
+ "$title": undefined,
980
+ // FIXME once this is calculated by optimistic then this needs to be the right value
981
+ "text": "d optimistic",
926
982
  id: pkForOptimistic
927
- };
928
- const optimisticallyMutatedA = {
929
- ...fauxObjectA,
983
+ });
984
+ const optimisticallyMutatedA = fauxObjectA.$clone({
930
985
  text: "optimistic"
931
- };
986
+ });
932
987
  testStage("Initial Setup");
933
988
 
934
- // later we will "create" this object
935
- const createdObjectD = {
936
- "$apiName": "Todo",
937
- "$objectType": "Todo",
938
- "$primaryKey": 9000,
939
- "$title": "d prime",
940
- "text": "d prime",
941
- id: 9000
942
- };
943
-
944
989
  // for whatever reason, the first list is loaded as [B, A]
945
- store.updateList(noWhereNoOrderBy, [fauxObjectB, fauxObjectA]);
990
+ updateList(store, noWhereNoOrderBy, [fauxObjectB, fauxObjectA]);
946
991
  await waitForCall(subListUnordered, 1);
947
992
  expectSingleListCallAndClear(subListUnordered, [fauxObjectB, fauxObjectA]);
948
993
 
@@ -951,19 +996,33 @@ describe(Store, () => {
951
996
  expectSingleListCallAndClear(subListOrdered, [fauxObjectA, fauxObjectB]);
952
997
  testStage("Optimistic Creation");
953
998
 
999
+ // create the weirdest action ever. It always creates a Todo with
1000
+ // a new primary key and the text "d" and updates A
1001
+ const {
1002
+ actionDefinition: crazyAction,
1003
+ actionTypeV2: crazyActionTypeV2
1004
+ } = new ActionTypeBuilder("asdf").addParameter("foo", "string").build();
1005
+ fauxFoundry.getDefaultOntology().registerActionType(crazyActionTypeV2, batch => {
1006
+ const idForD = nextPk++;
1007
+ batch.addObject(Todo.apiName, idForD, {
1008
+ id: idForD,
1009
+ text: "d"
1010
+ });
1011
+ batch.modifyObject(fauxObjectA.$apiName, fauxObjectA.$primaryKey, {
1012
+ text: "a prime",
1013
+ $title: "a prime" // FIXME we shouldn't have to set this, it can be calculated
1014
+ });
1015
+ });
1016
+
954
1017
  // the optimistic job will call createObject which triggers the `objectFactory2` of the
955
1018
  // cache context.
956
1019
 
957
- mockClient.mockObjectFactory2Once().resolve([optimisticallyCreatedObjectD]);
958
- const mockedApplyAction = mockClient.mockApplyActionOnce();
959
- testStage("Apply Action");
960
- const actionPromise = store.applyAction(createOffice, {
961
- officeId: "5"
962
- }, {
1020
+ // Perform something optimistic.
1021
+ const pActionResult = store.applyAction(crazyAction, {}, {
963
1022
  optimisticUpdate: b => {
964
1023
  b.createObject(Todo, pkForOptimistic, {
965
1024
  id: pkForOptimistic,
966
- text: "d"
1025
+ text: "d optimistic"
967
1026
  });
968
1027
  b.updateObject(optimisticallyMutatedA);
969
1028
  }
@@ -978,54 +1037,21 @@ describe(Store, () => {
978
1037
  isOptimistic: true
979
1038
  });
980
1039
 
981
- // the second list is now [A, B, optimistic]
1040
+ // the second list is now [B, optimistic, optimistic a]
982
1041
  await waitForCall(subListOrdered, 1);
983
1042
  expectSingleListCallAndClear(subListOrdered, [fauxObjectB, optimisticallyCreatedObjectD, optimisticallyMutatedA], {
984
1043
  isOptimistic: true
985
1044
  });
986
1045
  testStage("Resolve Action");
987
- const modifiedObjectA = {
988
- ...fauxObjectA,
1046
+ const modifiedObjectA = fauxObjectA.$clone({
989
1047
  text: "a prime"
990
- };
991
-
992
- // The action will complete and then revalidate in order...
993
- mockClient.mockFetchOneOnce(modifiedObjectA.$primaryKey).resolve(modifiedObjectA);
994
- mockClient.mockFetchOneOnce(createdObjectD.$primaryKey).resolve(createdObjectD);
995
-
996
- // this order matters!
997
- // but now we don't need them because we just update lists instead of revalidate when we can
998
- // const plainList = mockClient.mockFetchPageOnce<Todo>();
999
- // const orderedList = mockClient.mockFetchPageOnce<Todo>();
1000
-
1001
- mockedApplyAction.resolve({
1002
- addedObjects: [{
1003
- objectType: "Todo",
1004
- primaryKey: createdObjectD.id
1005
- }],
1006
- modifiedObjects: [{
1007
- objectType: "Todo",
1008
- primaryKey: fauxObjectA.$primaryKey
1009
- }]
1010
1048
  });
1011
-
1012
- // plainList.resolve({
1013
- // nextPageToken: undefined,
1014
- // totalCount: "4",
1015
- // data: [fauxObjectB, fauxObjectC, modifiedObjectA, createdObjectD],
1016
- // });
1017
-
1018
- // orderedList.resolve({
1019
- // nextPageToken: undefined,
1020
- // totalCount: "4",
1021
- // data: [modifiedObjectA, fauxObjectC, createdObjectD],
1022
- // });
1023
-
1024
- await actionPromise;
1049
+ const pkForD = (await pActionResult).addedObjects?.[0].primaryKey;
1050
+ !(typeof pkForD === "number") ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
1051
+ // load this without the cache for comparisons
1052
+ const createdObjectD = await client(Todo).fetchOne(pkForD);
1025
1053
  await waitForCall(subListUnordered, 1);
1026
- expectSingleListCallAndClear(subListUnordered, [fauxObjectB,
1027
- // fauxObjectC,
1028
- modifiedObjectA, createdObjectD], {
1054
+ expectSingleListCallAndClear(subListUnordered, [fauxObjectB, modifiedObjectA, createdObjectD], {
1029
1055
  isOptimistic: false
1030
1056
  });
1031
1057
  await waitForCall(subListOrdered, 1);
@@ -1049,12 +1075,12 @@ describe(Store, () => {
1049
1075
 
1050
1076
  // set the truth
1051
1077
  for (const obj of baseObjects) {
1052
- store.updateObject("Employee", obj);
1078
+ updateObject(store, obj);
1053
1079
  }
1054
1080
 
1055
1081
  // expect the truth
1056
1082
  for (const obj of baseObjects) {
1057
- expect(store.getObject("Employee", obj.$primaryKey)).toEqual(expect.objectContaining({
1083
+ expect(getObject(store, "Employee", obj.$primaryKey)).toEqual(expect.objectContaining({
1058
1084
  $title: `truth ${obj.$primaryKey}`
1059
1085
  }));
1060
1086
  }
@@ -1074,7 +1100,7 @@ describe(Store, () => {
1074
1100
 
1075
1101
  // expect the optimistic values
1076
1102
  for (let i = 0; i < 2; i++) {
1077
- expect(store.getObject("Employee", baseObjects[i].$primaryKey)).toEqual(expect.objectContaining({
1103
+ expect(getObject(store, "Employee", baseObjects[i].$primaryKey)).toEqual(expect.objectContaining({
1078
1104
  $title: `optimistic ${baseObjects[i].$primaryKey}`
1079
1105
  }));
1080
1106
  }
@@ -1083,10 +1109,10 @@ describe(Store, () => {
1083
1109
  store.removeLayer(layerIds[0]);
1084
1110
 
1085
1111
  // should have truth object 1 and optimistic object 2
1086
- expect(store.getObject("Employee", 1)).toEqual(expect.objectContaining({
1112
+ expect(getObject(store, "Employee", 1)).toEqual(expect.objectContaining({
1087
1113
  $title: "truth 1"
1088
1114
  }));
1089
- expect(store.getObject("Employee", 2)).toEqual(expect.objectContaining({
1115
+ expect(getObject(store, "Employee", 2)).toEqual(expect.objectContaining({
1090
1116
  $title: "optimistic 2"
1091
1117
  }));
1092
1118
 
@@ -1095,7 +1121,7 @@ describe(Store, () => {
1095
1121
 
1096
1122
  // should have truth objects
1097
1123
  for (const obj of baseObjects) {
1098
- expect(store.getObject("Employee", obj.$primaryKey)).toEqual(expect.objectContaining({
1124
+ expect(getObject(store, "Employee", obj.$primaryKey)).toEqual(expect.objectContaining({
1099
1125
  $title: `truth ${obj.$primaryKey}`
1100
1126
  }));
1101
1127
  }