doover-js 0.11.0 → 0.13.0

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 (389) hide show
  1. package/README.md +106 -0
  2. package/dist/apis/_args.js +5 -5
  3. package/dist/apis/agents-api.d.ts +4 -4
  4. package/dist/apis/agents-api.js +2 -2
  5. package/dist/apis/aggregates-api.d.ts +4 -4
  6. package/dist/apis/aggregates-api.js +5 -5
  7. package/dist/apis/alarms-api.d.ts +2 -2
  8. package/dist/apis/alarms-api.js +3 -3
  9. package/dist/apis/channels-api.d.ts +3 -3
  10. package/dist/apis/channels-api.js +6 -6
  11. package/dist/apis/connections-api.d.ts +2 -2
  12. package/dist/apis/connections-api.js +6 -6
  13. package/dist/apis/messages-api.d.ts +4 -4
  14. package/dist/apis/messages-api.js +11 -11
  15. package/dist/apis/notifications-api.d.ts +2 -2
  16. package/dist/apis/notifications-api.js +4 -4
  17. package/dist/apis/organisations-api.d.ts +2 -2
  18. package/dist/apis/permissions-api.d.ts +2 -2
  19. package/dist/apis/permissions-api.js +3 -3
  20. package/dist/apis/processors-api.d.ts +2 -2
  21. package/dist/apis/turn-api.d.ts +2 -2
  22. package/dist/apis/users-api.d.ts +2 -2
  23. package/dist/auth/auth-store.d.ts +1 -1
  24. package/dist/auth/build-auth.d.ts +3 -3
  25. package/dist/auth/build-auth.js +8 -8
  26. package/dist/auth/cookie-auth.d.ts +1 -1
  27. package/dist/auth/cookie-auth.js +2 -2
  28. package/dist/auth/doover-auth.d.ts +2 -2
  29. package/dist/auth/doover-token-auth.d.ts +3 -3
  30. package/dist/auth/doover-token-auth.js +13 -13
  31. package/dist/auth/index.d.ts +10 -0
  32. package/dist/auth/index.js +15 -0
  33. package/dist/client/data-client.d.ts +17 -14
  34. package/dist/client/doover-client.d.ts +9 -7
  35. package/dist/client/doover-client.js +44 -42
  36. package/dist/client/errors.d.ts +2 -2
  37. package/dist/client/errors.js +4 -4
  38. package/dist/client/index.d.ts +6 -0
  39. package/dist/client/index.js +12 -0
  40. package/dist/client/local-agent-client.d.ts +3 -3
  41. package/dist/client/local-agent-client.js +19 -19
  42. package/dist/client/multiplex-client.d.ts +5 -5
  43. package/dist/client/multiplex-client.js +25 -25
  44. package/dist/client/multiplex-gateway.d.ts +3 -3
  45. package/dist/client/multiplex-merge.d.ts +1 -1
  46. package/dist/client/network-status.d.ts +17 -0
  47. package/dist/client/network-status.js +70 -0
  48. package/dist/client/offline-cache.d.ts +9 -4
  49. package/dist/client/offline-cache.js +34 -22
  50. package/dist/client/provenance.d.ts +1 -1
  51. package/dist/client/request-options.d.ts +1 -1
  52. package/dist/client/singleton.d.ts +2 -2
  53. package/dist/client/singleton.js +2 -2
  54. package/dist/client/status-tracker.d.ts +1 -1
  55. package/dist/esm/apis/_args.d.ts +16 -0
  56. package/dist/esm/apis/_args.js +27 -0
  57. package/dist/esm/apis/agents-api.d.ts +196 -0
  58. package/dist/esm/apis/agents-api.js +327 -0
  59. package/dist/esm/apis/aggregates-api.d.ts +67 -0
  60. package/dist/esm/apis/aggregates-api.js +64 -0
  61. package/dist/esm/apis/alarms-api.d.ts +48 -0
  62. package/dist/esm/apis/alarms-api.js +75 -0
  63. package/dist/esm/apis/channels-api.d.ts +83 -0
  64. package/dist/esm/apis/channels-api.js +65 -0
  65. package/dist/esm/apis/connections-api.d.ts +45 -0
  66. package/dist/esm/apis/connections-api.js +44 -0
  67. package/dist/esm/apis/messages-api.d.ts +128 -0
  68. package/dist/esm/apis/messages-api.js +179 -0
  69. package/dist/esm/apis/notifications-api.d.ts +94 -0
  70. package/dist/esm/apis/notifications-api.js +153 -0
  71. package/dist/esm/apis/organisations-api.d.ts +26 -0
  72. package/dist/esm/apis/organisations-api.js +41 -0
  73. package/dist/esm/apis/permissions-api.d.ts +17 -0
  74. package/dist/esm/apis/permissions-api.js +23 -0
  75. package/dist/esm/apis/processors-api.d.ts +56 -0
  76. package/dist/esm/apis/processors-api.js +97 -0
  77. package/dist/esm/apis/turn-api.d.ts +7 -0
  78. package/dist/esm/apis/turn-api.js +8 -0
  79. package/dist/esm/apis/users-api.d.ts +8 -0
  80. package/dist/esm/apis/users-api.js +9 -0
  81. package/dist/esm/auth/auth-profile.d.ts +45 -0
  82. package/dist/esm/auth/auth-profile.js +68 -0
  83. package/dist/esm/auth/auth-store.d.ts +14 -0
  84. package/dist/esm/auth/build-auth.d.ts +38 -0
  85. package/dist/esm/auth/build-auth.js +92 -0
  86. package/dist/esm/auth/cookie-auth.d.ts +91 -0
  87. package/dist/esm/auth/cookie-auth.js +196 -0
  88. package/dist/esm/auth/doover-auth.d.ts +52 -0
  89. package/dist/esm/auth/doover-auth.js +28 -0
  90. package/dist/esm/auth/doover-token-auth.d.ts +39 -0
  91. package/dist/esm/auth/doover-token-auth.js +217 -0
  92. package/dist/esm/auth/errors.d.ts +3 -0
  93. package/dist/esm/auth/errors.js +6 -0
  94. package/dist/esm/auth/index.d.ts +10 -0
  95. package/dist/esm/auth/index.js +6 -0
  96. package/dist/esm/auth/jwt.d.ts +6 -0
  97. package/dist/esm/auth/jwt.js +26 -0
  98. package/dist/esm/client/capabilities.d.ts +10 -0
  99. package/dist/esm/client/capabilities.js +42 -0
  100. package/dist/esm/client/data-client.d.ts +107 -0
  101. package/dist/esm/client/doover-client.d.ts +48 -0
  102. package/dist/esm/client/doover-client.js +96 -0
  103. package/dist/esm/client/errors.d.ts +32 -0
  104. package/dist/esm/client/errors.js +64 -0
  105. package/dist/esm/client/index.d.ts +6 -0
  106. package/dist/esm/client/index.js +3 -0
  107. package/dist/esm/client/local-agent-client.d.ts +65 -0
  108. package/dist/esm/client/local-agent-client.js +225 -0
  109. package/dist/esm/client/multiplex-client.d.ts +165 -0
  110. package/dist/esm/client/multiplex-client.js +842 -0
  111. package/dist/esm/client/multiplex-gateway.d.ts +49 -0
  112. package/dist/esm/client/multiplex-gateway.js +110 -0
  113. package/dist/esm/client/multiplex-merge.d.ts +12 -0
  114. package/dist/esm/client/multiplex-merge.js +38 -0
  115. package/dist/esm/client/network-status.d.ts +17 -0
  116. package/dist/esm/client/network-status.js +66 -0
  117. package/dist/esm/client/offline-cache.d.ts +167 -0
  118. package/dist/esm/client/offline-cache.js +769 -0
  119. package/dist/esm/client/provenance.d.ts +60 -0
  120. package/dist/esm/client/provenance.js +108 -0
  121. package/dist/esm/client/request-options.d.ts +23 -0
  122. package/dist/esm/client/request-options.js +23 -0
  123. package/dist/esm/client/singleton.d.ts +26 -0
  124. package/dist/esm/client/singleton.js +54 -0
  125. package/dist/esm/client/stats.d.ts +79 -0
  126. package/dist/esm/client/stats.js +155 -0
  127. package/dist/esm/client/status-tracker.d.ts +24 -0
  128. package/dist/esm/client/status-tracker.js +86 -0
  129. package/dist/esm/gateway/gateway-client.d.ts +86 -0
  130. package/dist/esm/gateway/gateway-client.js +463 -0
  131. package/dist/esm/gateway/index.d.ts +3 -0
  132. package/dist/esm/gateway/index.js +1 -0
  133. package/dist/esm/gateway/types.d.ts +142 -0
  134. package/dist/esm/http/errors.d.ts +19 -0
  135. package/dist/esm/http/errors.js +22 -0
  136. package/dist/esm/http/index.d.ts +3 -0
  137. package/dist/esm/http/index.js +2 -0
  138. package/dist/esm/http/rest-client.d.ts +64 -0
  139. package/dist/esm/http/rest-client.js +181 -0
  140. package/dist/esm/index.d.ts +64 -0
  141. package/dist/esm/index.js +38 -0
  142. package/dist/esm/node/config-manager.d.ts +34 -0
  143. package/dist/esm/node/config-manager.js +140 -0
  144. package/dist/esm/node/index.d.ts +1 -0
  145. package/dist/esm/node/index.js +1 -0
  146. package/dist/esm/package.json +1 -0
  147. package/dist/esm/react/context.d.ts +23 -0
  148. package/dist/esm/react/context.js +28 -0
  149. package/dist/esm/react/index.d.ts +38 -0
  150. package/dist/esm/react/index.js +21 -0
  151. package/dist/esm/react/messageRangeStore.d.ts +93 -0
  152. package/dist/esm/react/messageRangeStore.js +140 -0
  153. package/dist/esm/react/sharedQueryClient.d.ts +21 -0
  154. package/dist/esm/react/sharedQueryClient.js +35 -0
  155. package/dist/esm/react/useAgentChannel.d.ts +8 -0
  156. package/dist/esm/react/useAgentChannel.js +9 -0
  157. package/dist/esm/react/useAgentConnections.d.ts +8 -0
  158. package/dist/esm/react/useAgentConnections.js +20 -0
  159. package/dist/esm/react/useAgentTokenState.d.ts +70 -0
  160. package/dist/esm/react/useAgentTokenState.js +127 -0
  161. package/dist/esm/react/useChannelAggregate.d.ts +64 -0
  162. package/dist/esm/react/useChannelAggregate.js +77 -0
  163. package/dist/esm/react/useChannelMessage.d.ts +45 -0
  164. package/dist/esm/react/useChannelMessage.js +79 -0
  165. package/dist/esm/react/useChannelMessages.d.ts +83 -0
  166. package/dist/esm/react/useChannelMessages.js +214 -0
  167. package/dist/esm/react/useChannelSubscription.d.ts +27 -0
  168. package/dist/esm/react/useChannelSubscription.js +30 -0
  169. package/dist/esm/react/useClientStatus.d.ts +10 -0
  170. package/dist/esm/react/useClientStatus.js +19 -0
  171. package/dist/esm/react/useConnectionState.d.ts +26 -0
  172. package/dist/esm/react/useConnectionState.js +45 -0
  173. package/dist/esm/react/useDeviceMap.d.ts +109 -0
  174. package/dist/esm/react/useDeviceMap.js +59 -0
  175. package/dist/esm/react/useInvocationLogs.d.ts +23 -0
  176. package/dist/esm/react/useInvocationLogs.js +37 -0
  177. package/dist/esm/react/useMultiAgentAggregates.d.ts +38 -0
  178. package/dist/esm/react/useMultiAgentAggregates.js +104 -0
  179. package/dist/esm/react/useMultiAgentChannelMessages.d.ts +79 -0
  180. package/dist/esm/react/useMultiAgentChannelMessages.js +169 -0
  181. package/dist/esm/react/useOfflineStatus.d.ts +8 -0
  182. package/dist/esm/react/useOfflineStatus.js +37 -0
  183. package/dist/esm/react/useSendMessage.d.ts +16 -0
  184. package/dist/esm/react/useSendMessage.js +26 -0
  185. package/dist/esm/react/useSendRpc.d.ts +68 -0
  186. package/dist/esm/react/useSendRpc.js +164 -0
  187. package/dist/esm/react/useTurnCredentials.d.ts +12 -0
  188. package/dist/esm/react/useTurnCredentials.js +22 -0
  189. package/dist/esm/react/useUpdateAggregate.d.ts +27 -0
  190. package/dist/esm/react/useUpdateAggregate.js +39 -0
  191. package/dist/esm/react/useUpdateMessage.d.ts +38 -0
  192. package/dist/esm/react/useUpdateMessage.js +36 -0
  193. package/dist/esm/refine/index.d.ts +72 -0
  194. package/dist/esm/refine/index.js +215 -0
  195. package/dist/esm/rpc/errors.d.ts +10 -0
  196. package/dist/esm/rpc/errors.js +19 -0
  197. package/dist/esm/rpc/index.d.ts +3 -0
  198. package/dist/esm/rpc/index.js +2 -0
  199. package/dist/esm/rpc/rpc-dispatcher.d.ts +41 -0
  200. package/dist/esm/rpc/rpc-dispatcher.js +141 -0
  201. package/dist/esm/types/audit.d.ts +53 -0
  202. package/dist/esm/types/audit.js +11 -0
  203. package/dist/esm/types/batch.d.ts +85 -0
  204. package/dist/esm/types/batch.js +42 -0
  205. package/dist/esm/types/common.d.ts +250 -0
  206. package/dist/esm/types/connection.d.ts +72 -0
  207. package/dist/esm/types/connection.js +7 -0
  208. package/dist/esm/types/index.d.ts +9 -0
  209. package/dist/esm/types/openapi.d.ts +195 -0
  210. package/dist/esm/types/provenance.d.ts +45 -0
  211. package/dist/esm/types/viewer.d.ts +122 -0
  212. package/dist/esm/utils/snowflake.d.ts +21 -0
  213. package/dist/esm/utils/snowflake.js +33 -0
  214. package/dist/esm/viewer/doover-data-provider.d.ts +90 -0
  215. package/dist/esm/viewer/doover-data-provider.js +189 -0
  216. package/dist/esm/viewer/path-parsing.d.ts +5 -0
  217. package/dist/esm/viewer/path-parsing.js +35 -0
  218. package/dist/gateway/gateway-client.d.ts +5 -5
  219. package/dist/gateway/gateway-client.js +5 -5
  220. package/dist/gateway/index.d.ts +3 -0
  221. package/dist/gateway/index.js +5 -0
  222. package/dist/gateway/types.d.ts +1 -1
  223. package/dist/http/index.d.ts +3 -0
  224. package/dist/http/index.js +9 -0
  225. package/dist/http/rest-client.d.ts +5 -3
  226. package/dist/http/rest-client.js +2 -2
  227. package/dist/index.d.ts +64 -62
  228. package/dist/index.js +92 -89
  229. package/dist/node/config-manager.d.ts +2 -2
  230. package/dist/node/config-manager.js +5 -5
  231. package/dist/node/index.d.ts +1 -1
  232. package/dist/node/index.js +2 -2
  233. package/dist/react/context.d.ts +1 -1
  234. package/dist/react/index.d.ts +38 -38
  235. package/dist/react/index.js +59 -59
  236. package/dist/react/messageRangeStore.d.ts +1 -1
  237. package/dist/react/useAgentChannel.d.ts +3 -3
  238. package/dist/react/useAgentChannel.js +2 -2
  239. package/dist/react/useAgentConnections.d.ts +1 -1
  240. package/dist/react/useAgentConnections.js +2 -2
  241. package/dist/react/useAgentTokenState.d.ts +3 -3
  242. package/dist/react/useAgentTokenState.js +8 -8
  243. package/dist/react/useChannelAggregate.d.ts +3 -3
  244. package/dist/react/useChannelAggregate.js +8 -8
  245. package/dist/react/useChannelMessage.d.ts +2 -2
  246. package/dist/react/useChannelMessage.js +4 -4
  247. package/dist/react/useChannelMessages.d.ts +3 -3
  248. package/dist/react/useChannelMessages.js +10 -10
  249. package/dist/react/useChannelSubscription.d.ts +2 -2
  250. package/dist/react/useChannelSubscription.js +2 -2
  251. package/dist/react/useClientStatus.d.ts +1 -1
  252. package/dist/react/useClientStatus.js +2 -2
  253. package/dist/react/useConnectionState.js +2 -2
  254. package/dist/react/useDeviceMap.js +2 -2
  255. package/dist/react/useInvocationLogs.d.ts +1 -1
  256. package/dist/react/useInvocationLogs.js +2 -2
  257. package/dist/react/useMultiAgentAggregates.d.ts +1 -1
  258. package/dist/react/useMultiAgentAggregates.js +5 -5
  259. package/dist/react/useMultiAgentChannelMessages.d.ts +1 -1
  260. package/dist/react/useMultiAgentChannelMessages.js +2 -2
  261. package/dist/react/useOfflineStatus.d.ts +2 -2
  262. package/dist/react/useOfflineStatus.js +31 -17
  263. package/dist/react/useSendMessage.d.ts +2 -2
  264. package/dist/react/useSendMessage.js +2 -2
  265. package/dist/react/useSendRpc.d.ts +2 -2
  266. package/dist/react/useSendRpc.js +2 -2
  267. package/dist/react/useTurnCredentials.d.ts +2 -2
  268. package/dist/react/useTurnCredentials.js +2 -2
  269. package/dist/react/useUpdateAggregate.d.ts +3 -3
  270. package/dist/react/useUpdateAggregate.js +4 -4
  271. package/dist/react/useUpdateMessage.d.ts +2 -2
  272. package/dist/react/useUpdateMessage.js +2 -2
  273. package/dist/refine/index.d.ts +1 -1
  274. package/dist/rpc/errors.d.ts +1 -1
  275. package/dist/rpc/index.d.ts +3 -0
  276. package/dist/rpc/index.js +7 -0
  277. package/dist/rpc/rpc-dispatcher.d.ts +4 -4
  278. package/dist/rpc/rpc-dispatcher.js +2 -2
  279. package/dist/types/common.d.ts +1 -1
  280. package/dist/types/index.d.ts +9 -0
  281. package/dist/types/index.js +2 -0
  282. package/dist/types/openapi.d.ts +1 -1
  283. package/dist/types/viewer.d.ts +2 -2
  284. package/dist/viewer/doover-data-provider.d.ts +10 -10
  285. package/dist/viewer/doover-data-provider.js +25 -25
  286. package/dist/viewer/path-parsing.d.ts +1 -1
  287. package/package.json +795 -8
  288. package/dist/test/api-args.test.js +0 -48
  289. package/dist/test/api-overloads.test.d.ts +0 -9
  290. package/dist/test/api-overloads.test.js +0 -330
  291. package/dist/test/apis.test.js +0 -408
  292. package/dist/test/auth.test.js +0 -708
  293. package/dist/test/batch-apis.test.js +0 -183
  294. package/dist/test/capabilities.test.js +0 -27
  295. package/dist/test/config-manager.test.js +0 -160
  296. package/dist/test/data-client-errors.test.js +0 -24
  297. package/dist/test/data-client-shape.test.js +0 -28
  298. package/dist/test/doover-client-dataclient.test.d.ts +0 -1
  299. package/dist/test/doover-client-dataclient.test.js +0 -58
  300. package/dist/test/doover-client-provenance.test.d.ts +0 -1
  301. package/dist/test/doover-client-provenance.test.js +0 -32
  302. package/dist/test/doover-client.test.d.ts +0 -1
  303. package/dist/test/doover-client.test.js +0 -42
  304. package/dist/test/doover-data-provider.test.d.ts +0 -1
  305. package/dist/test/doover-data-provider.test.js +0 -657
  306. package/dist/test/exports.test.d.ts +0 -1
  307. package/dist/test/exports.test.js +0 -80
  308. package/dist/test/gateway-client.test.d.ts +0 -1
  309. package/dist/test/gateway-client.test.js +0 -474
  310. package/dist/test/gateway-provenance.test.d.ts +0 -1
  311. package/dist/test/gateway-provenance.test.js +0 -29
  312. package/dist/test/gateway-subscriptions.test.d.ts +0 -1
  313. package/dist/test/gateway-subscriptions.test.js +0 -95
  314. package/dist/test/helpers.d.ts +0 -32
  315. package/dist/test/helpers.js +0 -115
  316. package/dist/test/local-agent-client.test.d.ts +0 -1
  317. package/dist/test/local-agent-client.test.js +0 -202
  318. package/dist/test/message-range-store.test.d.ts +0 -1
  319. package/dist/test/message-range-store.test.js +0 -183
  320. package/dist/test/multiplex-capabilities.test.d.ts +0 -1
  321. package/dist/test/multiplex-capabilities.test.js +0 -37
  322. package/dist/test/multiplex-conflicts.test.d.ts +0 -1
  323. package/dist/test/multiplex-conflicts.test.js +0 -35
  324. package/dist/test/multiplex-gateway.test.d.ts +0 -1
  325. package/dist/test/multiplex-gateway.test.js +0 -103
  326. package/dist/test/multiplex-merge.test.d.ts +0 -1
  327. package/dist/test/multiplex-merge.test.js +0 -19
  328. package/dist/test/multiplex-noncore.test.d.ts +0 -1
  329. package/dist/test/multiplex-noncore.test.js +0 -82
  330. package/dist/test/multiplex-passthrough.test.d.ts +0 -1
  331. package/dist/test/multiplex-passthrough.test.js +0 -35
  332. package/dist/test/multiplex-reads.test.d.ts +0 -1
  333. package/dist/test/multiplex-reads.test.js +0 -87
  334. package/dist/test/multiplex-registry.test.d.ts +0 -1
  335. package/dist/test/multiplex-registry.test.js +0 -81
  336. package/dist/test/multiplex-routing.test.d.ts +0 -1
  337. package/dist/test/multiplex-routing.test.js +0 -45
  338. package/dist/test/multiplex-status.test.d.ts +0 -1
  339. package/dist/test/multiplex-status.test.js +0 -63
  340. package/dist/test/multiplex-writes.test.d.ts +0 -1
  341. package/dist/test/multiplex-writes.test.js +0 -93
  342. package/dist/test/offline-cache.test.d.ts +0 -1
  343. package/dist/test/offline-cache.test.js +0 -289
  344. package/dist/test/provenance-regression.test.d.ts +0 -1
  345. package/dist/test/provenance-regression.test.js +0 -45
  346. package/dist/test/provenance-stamper.test.d.ts +0 -1
  347. package/dist/test/provenance-stamper.test.js +0 -41
  348. package/dist/test/provenance-type.test.d.ts +0 -1
  349. package/dist/test/provenance-type.test.js +0 -15
  350. package/dist/test/react-channel-messages-forward.test.d.ts +0 -1
  351. package/dist/test/react-channel-messages-forward.test.js +0 -139
  352. package/dist/test/react-channel-messages-range.test.d.ts +0 -1
  353. package/dist/test/react-channel-messages-range.test.js +0 -109
  354. package/dist/test/react-client-status.test.d.ts +0 -1
  355. package/dist/test/react-client-status.test.js +0 -35
  356. package/dist/test/react-dataclient.test.d.ts +0 -1
  357. package/dist/test/react-dataclient.test.js +0 -28
  358. package/dist/test/react-exports.test.d.ts +0 -1
  359. package/dist/test/react-exports.test.js +0 -46
  360. package/dist/test/react-multiagent-messages.test.d.ts +0 -1
  361. package/dist/test/react-multiagent-messages.test.js +0 -113
  362. package/dist/test/react-sources-option.test.d.ts +0 -1
  363. package/dist/test/react-sources-option.test.js +0 -41
  364. package/dist/test/react.test.d.ts +0 -1
  365. package/dist/test/react.test.js +0 -482
  366. package/dist/test/refine.test.d.ts +0 -1
  367. package/dist/test/refine.test.js +0 -71
  368. package/dist/test/rest-client.test.d.ts +0 -1
  369. package/dist/test/rest-client.test.js +0 -197
  370. package/dist/test/rpc-dispatcher.test.d.ts +0 -1
  371. package/dist/test/rpc-dispatcher.test.js +0 -251
  372. package/dist/test/singleton.test.d.ts +0 -1
  373. package/dist/test/singleton.test.js +0 -62
  374. package/dist/test/stats-rpc.test.d.ts +0 -1
  375. package/dist/test/stats-rpc.test.js +0 -69
  376. package/dist/test/status-tracker.test.d.ts +0 -1
  377. package/dist/test/status-tracker.test.js +0 -85
  378. package/dist/test/users-api.test.d.ts +0 -1
  379. package/dist/test/users-api.test.js +0 -19
  380. package/dist/test/utils.test.d.ts +0 -1
  381. package/dist/test/utils.test.js +0 -64
  382. /package/dist/{test/api-args.test.d.ts → esm/auth/auth-store.js} +0 -0
  383. /package/dist/{test/apis.test.d.ts → esm/client/data-client.js} +0 -0
  384. /package/dist/{test/auth.test.d.ts → esm/gateway/types.js} +0 -0
  385. /package/dist/{test/batch-apis.test.d.ts → esm/types/common.js} +0 -0
  386. /package/dist/{test/capabilities.test.d.ts → esm/types/index.js} +0 -0
  387. /package/dist/{test/config-manager.test.d.ts → esm/types/openapi.js} +0 -0
  388. /package/dist/{test/data-client-errors.test.d.ts → esm/types/provenance.js} +0 -0
  389. /package/dist/{test/data-client-shape.test.d.ts → esm/types/viewer.js} +0 -0
@@ -0,0 +1,769 @@
1
+ import { browserNetworkStatus } from "./network-status.js";
2
+ import { DooverOfflineError } from "./errors.js";
3
+ import { delegateRequestOptions, splitRequestOptions, } from "./request-options.js";
4
+ export const DEFAULT_OFFLINE_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
5
+ export class MemoryOfflineStorageAdapter {
6
+ constructor() {
7
+ this.json = new Map();
8
+ this.blobs = new Map();
9
+ }
10
+ async getJson(key) {
11
+ return this.json.get(key);
12
+ }
13
+ async setJson(key, record) {
14
+ this.json.set(key, record);
15
+ }
16
+ async deleteJson(key) {
17
+ this.json.delete(key);
18
+ }
19
+ async listJsonKeys(prefix) {
20
+ const keys = [...this.json.keys()];
21
+ return prefix ? keys.filter((key) => key.startsWith(prefix)) : keys;
22
+ }
23
+ async clearScope(scope) {
24
+ for (const [key, record] of this.json) {
25
+ if (scopeMatches(record.scope, scope))
26
+ this.json.delete(key);
27
+ }
28
+ for (const [key, record] of this.blobs) {
29
+ if (scopeMatches(record.metadata.scope, scope))
30
+ this.blobs.delete(key);
31
+ }
32
+ }
33
+ async getBlob(key) {
34
+ return this.blobs.get(key)?.blob;
35
+ }
36
+ async setBlob(key, blob, metadata) {
37
+ this.blobs.set(key, { blob, metadata });
38
+ }
39
+ async deleteBlob(key) {
40
+ this.blobs.delete(key);
41
+ }
42
+ }
43
+ const SCHEMA_VERSION = 1;
44
+ const INITIAL_OFFLINE_STATUS = {
45
+ online: true,
46
+ state: "online",
47
+ isOfflineFallback: false,
48
+ isExpired: false,
49
+ at: 0,
50
+ };
51
+ export class OfflineDataClient {
52
+ constructor(options) {
53
+ this.offlineStatusListeners = new Set();
54
+ this.offlineStatus = INITIAL_OFFLINE_STATUS;
55
+ this.persistQueue = Promise.resolve();
56
+ this.client = options.client;
57
+ this.networkStatus = options.networkStatus ?? options.client.networkStatus ?? browserNetworkStatus;
58
+ this.storage = options.storage;
59
+ this.scope = options.scope;
60
+ this.defaultRetentionMs = options.defaultRetentionMs ?? DEFAULT_OFFLINE_RETENTION_MS;
61
+ this.isOnlineFn = options.isOnline;
62
+ this.policies = [...(options.policies ?? [])];
63
+ this.agents = this.makeAgentsFacade();
64
+ this.channels = this.makeChannelsFacade();
65
+ this.messages = this.makeMessagesFacade();
66
+ this.aggregates = this.makeAggregatesFacade();
67
+ this.alarms = this.passThroughSubclient("alarms");
68
+ this.connections = this.passThroughSubclient("connections");
69
+ this.notifications = this.passThroughSubclient("notifications");
70
+ this.permissions = this.passThroughSubclient("permissions");
71
+ this.processors = this.passThroughSubclient("processors");
72
+ this.turn = this.passThroughSubclient("turn");
73
+ this.users = this.passThroughSubclient("users");
74
+ this.gateway = this.makeGatewayFacade();
75
+ this.rpc = this.makeRpcFacade();
76
+ }
77
+ setChannelPolicy(policy) {
78
+ const id = policy.id ?? `${policy.channel.agentId ?? "*"}/${policy.channel.channelName}`;
79
+ this.policies = [
80
+ ...this.policies.filter((existing) => (existing.id ?? `${existing.channel.agentId ?? "*"}/${existing.channel.channelName}`) !== id),
81
+ { ...policy, id },
82
+ ];
83
+ }
84
+ setChannelPolicies(policies) {
85
+ this.policies = [...policies];
86
+ }
87
+ getChannelPolicies() {
88
+ return this.policies;
89
+ }
90
+ getOfflineStatus() {
91
+ const online = this.isOnline();
92
+ if (online !== this.offlineStatus.online) {
93
+ this.offlineStatus = { ...this.offlineStatus, online, at: Date.now() };
94
+ }
95
+ return this.offlineStatus;
96
+ }
97
+ onOfflineStatusChange(listener) {
98
+ this.offlineStatusListeners.add(listener);
99
+ if (!this.unsubscribeNetwork) {
100
+ this.unsubscribeNetwork = this.networkStatus.subscribe(() => {
101
+ const status = this.getOfflineStatus();
102
+ this.offlineStatusListeners.forEach((callback) => callback(status));
103
+ });
104
+ }
105
+ let active = true;
106
+ return () => {
107
+ if (!active)
108
+ return;
109
+ active = false;
110
+ this.offlineStatusListeners.delete(listener);
111
+ if (!this.offlineStatusListeners.size) {
112
+ this.unsubscribeNetwork?.();
113
+ this.unsubscribeNetwork = undefined;
114
+ }
115
+ };
116
+ }
117
+ async clearScope(scope = this.scope) {
118
+ if (this.storage.clearScope) {
119
+ await this.storage.clearScope(scope);
120
+ return;
121
+ }
122
+ const keys = await this.storage.listJsonKeys?.(this.scopePrefix(scope));
123
+ if (!keys || !this.storage.deleteJson)
124
+ return;
125
+ await Promise.all(keys.map((key) => this.storage.deleteJson(key)));
126
+ }
127
+ getCapabilities() { return this.client.getCapabilities(); }
128
+ supports(cap) { return this.client.supports(cap); }
129
+ isConnected() { return this.client.isConnected(); }
130
+ getStatus() { return this.client.getStatus(); }
131
+ onStatusChange(listener) {
132
+ return this.client.onStatusChange(listener);
133
+ }
134
+ getAgentScope() { return this.client.getAgentScope(); }
135
+ getKnownAgentScope() { return this.client.getKnownAgentScope(); }
136
+ makeAgentsFacade() {
137
+ const target = this.client.agents;
138
+ return {
139
+ listAgents: ((...rawArgs) => {
140
+ const { args, request } = splitRequestOptions(rawArgs);
141
+ return this.readCached(() => target.listAgents(...this.withDelegateOptions(args, request)), {
142
+ operation: "agents.listAgents",
143
+ kind: "agents.list",
144
+ keyParts: ["agents", "list", args],
145
+ request,
146
+ });
147
+ }),
148
+ getMultiAgentMessages: ((channelName, ...rest) => {
149
+ const { args, request } = splitRequestOptions([channelName, ...rest]);
150
+ const params = args[1];
151
+ return this.readCached(() => target.getMultiAgentMessages(...this.withDelegateOptions(args, request)), {
152
+ operation: "agents.getMultiAgentMessages",
153
+ kind: "agents.multiAgentMessages",
154
+ keyParts: ["agents", "multiAgentMessages", args],
155
+ channelName: String(args[0]),
156
+ agentId: params?.agent_id?.join(","),
157
+ request,
158
+ });
159
+ }),
160
+ getMultiAgentAggregates: ((channelName, ...rest) => {
161
+ const { args, request } = splitRequestOptions([channelName, ...rest]);
162
+ const params = args[1];
163
+ return this.readCached(() => target.getMultiAgentAggregates(...this.withDelegateOptions(args, request)), {
164
+ operation: "agents.getMultiAgentAggregates",
165
+ kind: "agents.multiAgentAggregates",
166
+ keyParts: ["agents", "multiAgentAggregates", args],
167
+ channelName: String(args[0]),
168
+ agentId: params?.agent_id?.join(","),
169
+ request,
170
+ });
171
+ }),
172
+ };
173
+ }
174
+ makeChannelsFacade() {
175
+ const target = this.client.channels;
176
+ return {
177
+ listChannels: ((...rawArgs) => {
178
+ const { args, request } = splitRequestOptions(rawArgs);
179
+ const agentId = extractAgentId(args);
180
+ return this.readCached(() => target.listChannels(...this.withDelegateOptions(args, request)), {
181
+ operation: "channels.listChannels",
182
+ kind: "channels.list",
183
+ keyParts: ["channels", "list", args],
184
+ agentId,
185
+ request,
186
+ });
187
+ }),
188
+ getChannel: ((...rawArgs) => {
189
+ const { args, request } = splitRequestOptions(rawArgs);
190
+ const { agentId, channelName } = extractChannelId(args);
191
+ return this.readCached(() => target.getChannel(...this.withDelegateOptions(args, request)), {
192
+ operation: "channels.getChannel",
193
+ kind: "channels.get",
194
+ keyParts: ["channels", "get", args],
195
+ agentId,
196
+ channelName,
197
+ request,
198
+ });
199
+ }),
200
+ createChannel: this.offlineGuard("channels.createChannel", target.createChannel.bind(target)),
201
+ putChannel: this.offlineGuard("channels.putChannel", target.putChannel.bind(target)),
202
+ archiveChannel: this.offlineGuard("channels.archiveChannel", target.archiveChannel.bind(target)),
203
+ unarchiveChannel: this.offlineGuard("channels.unarchiveChannel", target.unarchiveChannel.bind(target)),
204
+ listDataSeries: ((...args) => target.listDataSeries(...args)),
205
+ };
206
+ }
207
+ makeAggregatesFacade() {
208
+ const target = this.client.aggregates;
209
+ return {
210
+ getAggregate: ((...rawArgs) => {
211
+ const { args, request } = splitRequestOptions(rawArgs);
212
+ const { agentId, channelName } = extractChannelId(args);
213
+ return this.readCached(() => target.getAggregate(...this.withDelegateOptions(args, request)), {
214
+ operation: "aggregates.getAggregate",
215
+ kind: "aggregates.get",
216
+ keyParts: ["aggregates", "get", args],
217
+ agentId,
218
+ channelName,
219
+ request,
220
+ serverUpdatedAt: (value) => typeof value?.last_updated === "number"
221
+ ? value.last_updated
222
+ : undefined,
223
+ });
224
+ }),
225
+ putAggregate: this.offlineGuard("aggregates.putAggregate", target.putAggregate.bind(target)),
226
+ patchAggregate: this.offlineGuard("aggregates.patchAggregate", target.patchAggregate.bind(target)),
227
+ batchPatchAggregates: this.offlineGuard("aggregates.batchPatchAggregates", target.batchPatchAggregates.bind(target)),
228
+ getAggregateAttachment: ((...rawArgs) => {
229
+ const { args, request } = splitRequestOptions(rawArgs);
230
+ const { agentId, channelName } = extractChannelId(args);
231
+ const attachmentId = String(args[2] ?? args[1] ?? "");
232
+ return this.readBlobCached(() => target.getAggregateAttachment(...this.withDelegateOptions(args, request)), {
233
+ operation: "aggregates.getAggregateAttachment",
234
+ kind: "aggregates.attachment",
235
+ keyParts: ["aggregates", "attachment", args, attachmentId],
236
+ agentId,
237
+ channelName,
238
+ request,
239
+ });
240
+ }),
241
+ };
242
+ }
243
+ makeMessagesFacade() {
244
+ const target = this.client.messages;
245
+ return {
246
+ listMessages: ((...rawArgs) => {
247
+ const { args, request } = splitRequestOptions(rawArgs);
248
+ const { agentId, channelName } = extractChannelId(args);
249
+ return this.readCached(() => target.listMessages(...this.withDelegateOptions(args, request)), {
250
+ operation: "messages.listMessages",
251
+ kind: "messages.list",
252
+ keyParts: ["messages", "list", args],
253
+ fallbackKeyParts: this.latestMessagesKeyParts(agentId ?? "", channelName ?? ""),
254
+ agentId,
255
+ channelName,
256
+ request,
257
+ serverUpdatedAt: newestMessageTimestamp,
258
+ });
259
+ }),
260
+ getMessage: ((...rawArgs) => {
261
+ const { args, request } = splitRequestOptions(rawArgs);
262
+ const { agentId, channelName } = extractChannelId(args);
263
+ const messageId = String(args[2] ?? args[1] ?? "");
264
+ return this.readCached(() => target.getMessage(...this.withDelegateOptions(args, request)), {
265
+ operation: "messages.getMessage",
266
+ kind: "messages.get",
267
+ keyParts: ["messages", "get", args, messageId],
268
+ agentId,
269
+ channelName,
270
+ request,
271
+ serverUpdatedAt: (value) => typeof value?.timestamp === "number"
272
+ ? value.timestamp
273
+ : undefined,
274
+ });
275
+ }),
276
+ postMessage: this.offlineGuard("messages.postMessage", target.postMessage.bind(target)),
277
+ putMessage: this.offlineGuard("messages.putMessage", target.putMessage.bind(target)),
278
+ patchMessage: this.offlineGuard("messages.patchMessage", target.patchMessage.bind(target)),
279
+ deleteMessage: this.offlineGuard("messages.deleteMessage", target.deleteMessage.bind(target)),
280
+ batchPostMessages: this.offlineGuard("messages.batchPostMessages", target.batchPostMessages.bind(target)),
281
+ batchPatchMessages: this.offlineGuard("messages.batchPatchMessages", target.batchPatchMessages.bind(target)),
282
+ batchPutMessages: this.offlineGuard("messages.batchPutMessages", target.batchPutMessages.bind(target)),
283
+ batchDeleteMessages: this.offlineGuard("messages.batchDeleteMessages", target.batchDeleteMessages.bind(target)),
284
+ getTimeseries: ((...args) => target.getTimeseries(...args)),
285
+ getMessageAttachment: ((...rawArgs) => {
286
+ const { args, request } = splitRequestOptions(rawArgs);
287
+ const { agentId, channelName } = extractChannelId(args);
288
+ const messageId = String(args[2] ?? args[1] ?? "");
289
+ const attachmentId = String(args[3] ?? args[2] ?? "");
290
+ return this.readBlobCached(() => target.getMessageAttachment(...this.withDelegateOptions(args, request)), {
291
+ operation: "messages.getMessageAttachment",
292
+ kind: "messages.attachment",
293
+ keyParts: ["messages", "attachment", args, messageId, attachmentId],
294
+ agentId,
295
+ channelName,
296
+ request,
297
+ });
298
+ }),
299
+ getInvocationLogs: ((...args) => target.getInvocationLogs(...args)),
300
+ createMultipartPayload: target.createMultipartPayload.bind(target),
301
+ };
302
+ }
303
+ makeGatewayFacade() {
304
+ const target = this.client.gateway;
305
+ return {
306
+ ...target,
307
+ connect: target.connect.bind(target),
308
+ disconnect: target.disconnect.bind(target),
309
+ on: target.on.bind(target),
310
+ off: target.off.bind(target),
311
+ subscribe: target.subscribe.bind(target),
312
+ unsubscribe: target.unsubscribe.bind(target),
313
+ subscribeToChannel: ((channel, handlers) => target.subscribeToChannel(channel, {
314
+ ...handlers,
315
+ onMessage: (message) => {
316
+ this.enqueuePersist(() => this.persistGatewayMessage(message));
317
+ handlers.onMessage?.(message);
318
+ },
319
+ onMessageUpdate: (message, requestData) => {
320
+ this.enqueuePersist(() => this.persistGatewayMessage(message));
321
+ handlers.onMessageUpdate?.(message, requestData);
322
+ },
323
+ onAggregate: (aggregate) => {
324
+ this.enqueuePersist(() => this.persistGatewayAggregate(channel, aggregate));
325
+ handlers.onAggregate?.(aggregate);
326
+ },
327
+ })),
328
+ syncChannel: this.offlineGuard("gateway.syncChannel", target.syncChannel.bind(target)),
329
+ sendOneShotMessage: this.offlineGuard("gateway.sendOneShotMessage", target.sendOneShotMessage.bind(target)),
330
+ getSession: target.getSession.bind(target),
331
+ isConnected: target.isConnected.bind(target),
332
+ getSubscriptionCount: target.getSubscriptionCount.bind(target),
333
+ getSubscriptions: target.getSubscriptions.bind(target),
334
+ reconnect: target.reconnect.bind(target),
335
+ };
336
+ }
337
+ makeRpcFacade() {
338
+ const target = this.client.rpc;
339
+ return {
340
+ setStats: target.setStats?.bind(target) ?? (() => undefined),
341
+ send: this.offlineGuard("rpc.send", target.send.bind(target)),
342
+ };
343
+ }
344
+ passThroughSubclient(name) {
345
+ const target = this.client[name];
346
+ return new Proxy({}, {
347
+ get: (_unused, prop) => {
348
+ if (typeof prop !== "string")
349
+ return undefined;
350
+ const value = target[prop];
351
+ if (typeof value !== "function")
352
+ return value;
353
+ const operation = `${name}.${prop}`;
354
+ if (isLikelyWrite(prop))
355
+ return this.offlineGuard(operation, value.bind(target));
356
+ return value.bind(target);
357
+ },
358
+ });
359
+ }
360
+ offlineGuard(operation, fn) {
361
+ return ((...args) => {
362
+ if (!this.isOnline())
363
+ throw new DooverOfflineError(operation);
364
+ return fn(...args);
365
+ });
366
+ }
367
+ async readCached(fetcher, descriptor) {
368
+ const effective = this.effectivePolicy(descriptor);
369
+ const key = this.cacheKey(descriptor);
370
+ const fallbackKey = descriptor.fallbackKeyParts
371
+ ? this.cacheKey({ ...descriptor, kind: "messages.latest", keyParts: descriptor.fallbackKeyParts })
372
+ : undefined;
373
+ const read = () => this.readRecord(key, descriptor.operation, effective.allowExpired, fallbackKey);
374
+ if (effective.mode === "cache-only" || !this.isOnline()) {
375
+ return read();
376
+ }
377
+ if (effective.mode === "cache-first") {
378
+ const cached = await this.tryReadRecord(key, effective.allowExpired);
379
+ if (cached.hit)
380
+ return cached.value;
381
+ }
382
+ try {
383
+ const value = await fetcher();
384
+ if (effective.enabled) {
385
+ await this.writeRecord(key, descriptor, effective, value);
386
+ await this.writePolicyDerivedRecords(descriptor, effective, value);
387
+ }
388
+ this.setOfflineStatus({
389
+ state: "online",
390
+ operation: descriptor.operation,
391
+ cacheKey: key,
392
+ isOfflineFallback: false,
393
+ isExpired: false,
394
+ });
395
+ return value;
396
+ }
397
+ catch (error) {
398
+ if (!effective.enabled)
399
+ throw error;
400
+ const cached = await this.tryReadRecord(key, effective.allowExpired);
401
+ if (cached.hit)
402
+ return cached.value;
403
+ throw error;
404
+ }
405
+ }
406
+ async readBlobCached(fetcher, descriptor) {
407
+ const effective = this.effectivePolicy(descriptor);
408
+ const key = this.cacheKey(descriptor);
409
+ if (effective.mode === "cache-only" || !this.isOnline()) {
410
+ const cached = await this.storage.getBlob?.(key);
411
+ if (cached) {
412
+ this.setOfflineStatus({
413
+ state: this.isOnline() ? "cache-hit" : "cache-fallback",
414
+ operation: descriptor.operation,
415
+ cacheKey: key,
416
+ isOfflineFallback: !this.isOnline(),
417
+ isExpired: false,
418
+ });
419
+ return cached;
420
+ }
421
+ this.setOfflineStatus({
422
+ state: "cache-miss",
423
+ operation: descriptor.operation,
424
+ cacheKey: key,
425
+ isOfflineFallback: !this.isOnline(),
426
+ isExpired: false,
427
+ });
428
+ throw new DooverOfflineError(descriptor.operation, `No cached attachment is available for "${descriptor.operation}" while offline.`, key);
429
+ }
430
+ if (effective.mode === "cache-first") {
431
+ const cached = await this.storage.getBlob?.(key);
432
+ if (cached)
433
+ return cached;
434
+ }
435
+ const value = await fetcher();
436
+ if (!(value instanceof Blob))
437
+ return value;
438
+ if (effective.enabled && this.shouldCacheAttachmentBlob(descriptor)) {
439
+ const now = Date.now();
440
+ await this.storage.setBlob?.(key, value, {
441
+ key,
442
+ scope: this.scope,
443
+ kind: descriptor.kind,
444
+ value: {
445
+ content_type: value.type || null,
446
+ size: value.size,
447
+ },
448
+ cachedAt: now,
449
+ lastAccessedAt: now,
450
+ expiresAt: effective.retentionMs > 0 ? now + effective.retentionMs : null,
451
+ schemaVersion: SCHEMA_VERSION,
452
+ ...(effective.policyId ? { policyId: effective.policyId } : {}),
453
+ });
454
+ }
455
+ this.setOfflineStatus({
456
+ state: "online",
457
+ operation: descriptor.operation,
458
+ cacheKey: key,
459
+ isOfflineFallback: false,
460
+ isExpired: false,
461
+ });
462
+ return value;
463
+ }
464
+ async readRecord(key, operation, allowExpired, fallbackKey) {
465
+ const result = await this.tryReadRecord(key, allowExpired);
466
+ if (result.hit)
467
+ return result.value;
468
+ if (fallbackKey) {
469
+ const fallback = await this.tryReadRecord(fallbackKey, allowExpired);
470
+ if (fallback.hit)
471
+ return fallback.value;
472
+ }
473
+ this.setOfflineStatus({
474
+ state: "cache-miss",
475
+ operation,
476
+ cacheKey: key,
477
+ isOfflineFallback: !this.isOnline(),
478
+ isExpired: false,
479
+ });
480
+ throw new DooverOfflineError(operation, `No cached data is available for "${operation}" while offline.`, key);
481
+ }
482
+ async tryReadRecord(key, allowExpired) {
483
+ const record = await this.storage.getJson(key);
484
+ if (!record)
485
+ return { hit: false };
486
+ const expired = record.expiresAt !== null && record.expiresAt <= Date.now();
487
+ if (expired && !allowExpired) {
488
+ this.setOfflineStatus({
489
+ state: "expired",
490
+ operation: record.kind,
491
+ cacheKey: key,
492
+ cachedAt: record.cachedAt,
493
+ expiresAt: record.expiresAt,
494
+ serverUpdatedAt: record.serverUpdatedAt ?? null,
495
+ isOfflineFallback: !this.isOnline(),
496
+ isExpired: true,
497
+ });
498
+ return { hit: false };
499
+ }
500
+ record.lastAccessedAt = Date.now();
501
+ await this.storage.setJson(key, record);
502
+ this.setOfflineStatus({
503
+ state: this.isOnline() ? "cache-hit" : "cache-fallback",
504
+ operation: record.kind,
505
+ cacheKey: key,
506
+ cachedAt: record.cachedAt,
507
+ expiresAt: record.expiresAt,
508
+ serverUpdatedAt: record.serverUpdatedAt ?? null,
509
+ isOfflineFallback: !this.isOnline(),
510
+ isExpired: expired,
511
+ });
512
+ return { hit: true, value: record.value };
513
+ }
514
+ async writeRecord(key, descriptor, effective, value) {
515
+ const now = Date.now();
516
+ const record = {
517
+ key,
518
+ scope: this.scope,
519
+ kind: descriptor.kind,
520
+ value,
521
+ cachedAt: now,
522
+ lastAccessedAt: now,
523
+ expiresAt: effective.retentionMs > 0 ? now + effective.retentionMs : null,
524
+ serverUpdatedAt: descriptor.serverUpdatedAt?.(value) ?? null,
525
+ schemaVersion: SCHEMA_VERSION,
526
+ ...(effective.policyId ? { policyId: effective.policyId } : {}),
527
+ };
528
+ await this.storage.setJson(key, record);
529
+ }
530
+ async writePolicyDerivedRecords(descriptor, effective, value) {
531
+ if (descriptor.kind !== "messages.list" || !descriptor.agentId || !descriptor.channelName) {
532
+ return;
533
+ }
534
+ if (!Array.isArray(value))
535
+ return;
536
+ await this.writeLatestMessagesRecord(descriptor.agentId, descriptor.channelName, value, effective);
537
+ }
538
+ async writeLatestMessagesRecord(agentId, channelName, messages, effective) {
539
+ const policy = this.matchPolicy(agentId, channelName);
540
+ if (!policy && !effective)
541
+ return;
542
+ if (policy?.cache === false)
543
+ return;
544
+ const retentionMs = effective?.retentionMs ?? policy?.retentionMs ?? this.defaultRetentionMs;
545
+ const count = policy?.messages?.count ?? messages.length;
546
+ const pruned = pruneLatestMessages(messages, count);
547
+ const descriptor = {
548
+ operation: "messages.latest",
549
+ kind: "messages.latest",
550
+ keyParts: this.latestMessagesKeyParts(agentId, channelName),
551
+ agentId,
552
+ channelName,
553
+ serverUpdatedAt: newestMessageTimestamp,
554
+ };
555
+ await this.writeRecord(this.cacheKey(descriptor), descriptor, {
556
+ enabled: true,
557
+ mode: "network-first",
558
+ retentionMs,
559
+ allowExpired: false,
560
+ ...(effective?.policyId || policy?.id ? { policyId: effective?.policyId ?? policy?.id } : {}),
561
+ }, pruned);
562
+ }
563
+ async mergeLatestMessage(agentId, channelName, message) {
564
+ const policy = this.matchPolicy(agentId, channelName);
565
+ if (!policy || policy.cache === false)
566
+ return;
567
+ const descriptor = {
568
+ operation: "messages.latest",
569
+ kind: "messages.latest",
570
+ keyParts: this.latestMessagesKeyParts(agentId, channelName),
571
+ agentId,
572
+ channelName,
573
+ serverUpdatedAt: newestMessageTimestamp,
574
+ };
575
+ const key = this.cacheKey(descriptor);
576
+ const existing = await this.storage.getJson(key);
577
+ const current = existing?.value ?? [];
578
+ const withoutDuplicate = current.filter((item) => item.id !== message.id);
579
+ await this.writeLatestMessagesRecord(agentId, channelName, [...withoutDuplicate, message], {
580
+ enabled: true,
581
+ mode: "network-first",
582
+ retentionMs: policy.retentionMs ?? this.defaultRetentionMs,
583
+ allowExpired: false,
584
+ ...(policy.id ? { policyId: policy.id } : {}),
585
+ });
586
+ }
587
+ async persistGatewayMessage(message) {
588
+ await this.mergeLatestMessage(message.channel.agent_id, message.channel.name, message);
589
+ const descriptor = {
590
+ operation: "messages.getMessage",
591
+ kind: "messages.get",
592
+ keyParts: ["messages", "get", [{ agentId: message.channel.agent_id, channelName: message.channel.name }, message.id], message.id],
593
+ agentId: message.channel.agent_id,
594
+ channelName: message.channel.name,
595
+ serverUpdatedAt: (value) => typeof value?.timestamp === "number"
596
+ ? value.timestamp
597
+ : undefined,
598
+ };
599
+ const policy = this.matchPolicy(message.channel.agent_id, message.channel.name);
600
+ if (!policy || policy.cache === false)
601
+ return;
602
+ await this.writeRecord(this.cacheKey(descriptor), descriptor, {
603
+ enabled: true,
604
+ mode: "network-first",
605
+ retentionMs: policy.retentionMs ?? this.defaultRetentionMs,
606
+ allowExpired: false,
607
+ ...(policy.id ? { policyId: policy.id } : {}),
608
+ }, message);
609
+ }
610
+ async persistGatewayAggregate(channel, aggregate) {
611
+ const policy = this.matchPolicy(channel.agent_id, channel.name);
612
+ if (!policy || policy.cache === false)
613
+ return;
614
+ const descriptor = {
615
+ operation: "aggregates.getAggregate",
616
+ kind: "aggregates.get",
617
+ keyParts: ["aggregates", "get", [{ agentId: channel.agent_id, channelName: channel.name }]],
618
+ agentId: channel.agent_id,
619
+ channelName: channel.name,
620
+ serverUpdatedAt: (value) => typeof value?.last_updated === "number"
621
+ ? value.last_updated
622
+ : undefined,
623
+ };
624
+ await this.writeRecord(this.cacheKey(descriptor), descriptor, {
625
+ enabled: true,
626
+ mode: "network-first",
627
+ retentionMs: policy.retentionMs ?? this.defaultRetentionMs,
628
+ allowExpired: false,
629
+ ...(policy.id ? { policyId: policy.id } : {}),
630
+ }, aggregate);
631
+ }
632
+ effectivePolicy(descriptor) {
633
+ const cache = descriptor.request?.cache;
634
+ const cacheOptions = cache === false ? undefined : cache;
635
+ const matching = this.matchPolicy(descriptor.agentId, descriptor.channelName);
636
+ const enabled = cache === false ? false :
637
+ cacheOptions?.enabled !== undefined ? cacheOptions.enabled :
638
+ matching ? matching.cache !== false :
639
+ cache !== undefined;
640
+ return {
641
+ enabled,
642
+ mode: cacheOptions?.mode ?? "network-first",
643
+ retentionMs: cacheOptions?.retentionMs !== undefined
644
+ ? cacheOptions.retentionMs
645
+ : matching?.retentionMs ?? this.defaultRetentionMs,
646
+ allowExpired: !!cacheOptions?.allowExpired,
647
+ ...(cacheOptions?.policy ? { policyId: cacheOptions.policy } : matching?.id ? { policyId: matching.id } : {}),
648
+ };
649
+ }
650
+ matchPolicy(agentId, channelName) {
651
+ if (!channelName)
652
+ return undefined;
653
+ return this.policies.find((policy) => policy.channel.channelName === channelName &&
654
+ (policy.channel.agentId === undefined || policy.channel.agentId === agentId));
655
+ }
656
+ shouldCacheAttachmentBlob(descriptor) {
657
+ const policy = this.matchPolicy(descriptor.agentId, descriptor.channelName);
658
+ if (!policy)
659
+ return descriptor.request?.cache !== undefined && descriptor.request.cache !== false;
660
+ if (descriptor.kind === "messages.attachment") {
661
+ return policy.messageAttachments?.include === "metadata-and-selected-blobs";
662
+ }
663
+ if (descriptor.kind === "aggregates.attachment") {
664
+ return policy.aggregateAttachments?.include === "metadata-and-selected-blobs";
665
+ }
666
+ return false;
667
+ }
668
+ withDelegateOptions(args, request) {
669
+ const delegate = delegateRequestOptions(request);
670
+ return delegate ? [...args, delegate] : args;
671
+ }
672
+ cacheKey(descriptor) {
673
+ return `${this.scopePrefix(this.scope)}:${stableStringify({
674
+ kind: descriptor.kind,
675
+ keyParts: descriptor.keyParts,
676
+ sources: descriptor.request?.sources ? [...descriptor.request.sources].sort() : undefined,
677
+ })}`;
678
+ }
679
+ latestMessagesKeyParts(agentId, channelName) {
680
+ return ["messages", "latest", { agentId, channelName }];
681
+ }
682
+ scopePrefix(scope) {
683
+ return `doover-offline:v${SCHEMA_VERSION}:${stableStringify({
684
+ userId: scope.userId,
685
+ organisationId: scope.organisationId ?? null,
686
+ sourceId: scope.sourceId ?? "default",
687
+ sharing: scope.sharing ?? null,
688
+ assumeUserId: scope.assumeUserId ?? null,
689
+ })}`;
690
+ }
691
+ isOnline() {
692
+ if (this.isOnlineFn)
693
+ return this.isOnlineFn();
694
+ return this.networkStatus.getSnapshot().online;
695
+ }
696
+ setOfflineStatus(status) {
697
+ this.offlineStatus = {
698
+ ...status,
699
+ online: this.isOnline(),
700
+ at: Date.now(),
701
+ };
702
+ this.offlineStatusListeners.forEach((listener) => listener(this.offlineStatus));
703
+ }
704
+ enqueuePersist(task) {
705
+ this.persistQueue = this.persistQueue
706
+ .then(task)
707
+ .catch(() => undefined);
708
+ }
709
+ }
710
+ function extractAgentId(args) {
711
+ return typeof args[0] === "string"
712
+ ? args[0]
713
+ : args[0]?.agentId;
714
+ }
715
+ function extractChannelId(args) {
716
+ if (typeof args[0] === "string") {
717
+ return { agentId: args[0], channelName: args[1] };
718
+ }
719
+ const id = args[0];
720
+ return { agentId: id?.agentId, channelName: id?.channelName };
721
+ }
722
+ function newestMessageTimestamp(value) {
723
+ if (!Array.isArray(value))
724
+ return undefined;
725
+ let newest = null;
726
+ for (const message of value) {
727
+ const timestamp = message.timestamp;
728
+ if (typeof timestamp === "number" && (newest === null || timestamp > newest)) {
729
+ newest = timestamp;
730
+ }
731
+ }
732
+ return newest;
733
+ }
734
+ function pruneLatestMessages(messages, count) {
735
+ if (count <= 0)
736
+ return [];
737
+ const byId = new Map();
738
+ for (const message of messages)
739
+ byId.set(message.id, message);
740
+ return [...byId.values()]
741
+ .sort((a, b) => a.timestamp - b.timestamp)
742
+ .slice(-count);
743
+ }
744
+ function isLikelyWrite(method) {
745
+ return /^(create|put|patch|post|delete|update|sync|archive|unarchive|test|regenerate|invoke)/.test(method);
746
+ }
747
+ function stableStringify(value) {
748
+ return JSON.stringify(sortForStringify(value));
749
+ }
750
+ function sortForStringify(value) {
751
+ if (Array.isArray(value))
752
+ return value.map(sortForStringify);
753
+ if (!value || typeof value !== "object")
754
+ return value;
755
+ const record = value;
756
+ return Object.keys(record).sort().reduce((acc, key) => {
757
+ const inner = record[key];
758
+ if (inner !== undefined)
759
+ acc[key] = sortForStringify(inner);
760
+ return acc;
761
+ }, {});
762
+ }
763
+ function scopeMatches(candidate, wanted) {
764
+ return (candidate.userId === wanted.userId &&
765
+ (wanted.organisationId === undefined || candidate.organisationId === wanted.organisationId) &&
766
+ (wanted.sourceId === undefined || candidate.sourceId === wanted.sourceId) &&
767
+ (wanted.sharing === undefined || candidate.sharing === wanted.sharing) &&
768
+ (wanted.assumeUserId === undefined || candidate.assumeUserId === wanted.assumeUserId));
769
+ }