@honua/app-platform 0.1.1-beta.0 → 0.1.4-beta.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 (383) hide show
  1. package/collaboration/client.d.ts.map +1 -1
  2. package/connect-url-safety.d.ts +53 -0
  3. package/connect-url-safety.js +189 -0
  4. package/contract/discovery.d.ts +34 -0
  5. package/contract/discovery.d.ts.map +1 -1
  6. package/contract/index.d.ts +7 -5
  7. package/contract/index.d.ts.map +1 -1
  8. package/contract/index.js +3 -2
  9. package/contract/pmtiles.d.ts +10 -1
  10. package/contract/pmtiles.d.ts.map +1 -1
  11. package/contract/pmtiles.js +10 -2
  12. package/contract/protocol-module.d.ts +84 -9
  13. package/contract/protocol-module.d.ts.map +1 -1
  14. package/contract/query-filter-fes.d.ts +18 -0
  15. package/contract/query-filter-fes.d.ts.map +1 -0
  16. package/contract/query-filter-fes.js +122 -0
  17. package/contract/query-filter.d.ts +300 -0
  18. package/contract/query-filter.d.ts.map +1 -0
  19. package/contract/query-filter.js +883 -0
  20. package/contract/schema.d.ts +12 -0
  21. package/contract/schema.d.ts.map +1 -1
  22. package/contract/schema.js +34 -0
  23. package/contract/source-capability-support.d.ts.map +1 -1
  24. package/contract/source-capability-support.js +15 -3
  25. package/contract/source.d.ts +45 -25
  26. package/contract/source.d.ts.map +1 -1
  27. package/contract/source.js +719 -479
  28. package/contract/types.d.ts +87 -18
  29. package/contract/types.d.ts.map +1 -1
  30. package/contract/widget-source.d.ts.map +1 -1
  31. package/controls/basemap-switcher.d.ts +19 -11
  32. package/controls/basemap-switcher.d.ts.map +1 -1
  33. package/controls/basemap-switcher.js +58 -25
  34. package/controls/catalog.d.ts +105 -0
  35. package/controls/catalog.d.ts.map +1 -0
  36. package/controls/catalog.js +341 -0
  37. package/controls/element-utils.d.ts +9 -0
  38. package/controls/element-utils.d.ts.map +1 -1
  39. package/controls/element-utils.js +17 -0
  40. package/controls/index.d.ts +29 -8
  41. package/controls/index.d.ts.map +1 -1
  42. package/controls/index.js +26 -8
  43. package/controls/layer-list.d.ts +13 -5
  44. package/controls/layer-list.d.ts.map +1 -1
  45. package/controls/layer-list.js +72 -15
  46. package/controls/legend.d.ts +32 -5
  47. package/controls/legend.d.ts.map +1 -1
  48. package/controls/legend.js +95 -25
  49. package/controls/qualification.d.ts +152 -0
  50. package/controls/qualification.d.ts.map +1 -0
  51. package/controls/qualification.js +1265 -0
  52. package/controls/registry.d.ts +104 -0
  53. package/controls/registry.d.ts.map +1 -0
  54. package/controls/registry.js +150 -0
  55. package/controls/swipe-control.d.ts +6 -1
  56. package/controls/swipe-control.d.ts.map +1 -1
  57. package/controls/swipe-control.js +82 -20
  58. package/core/client.d.ts +45 -21
  59. package/core/client.d.ts.map +1 -1
  60. package/core/client.js +224 -46
  61. package/core/error-classifications.d.ts +6 -0
  62. package/core/error-classifications.d.ts.map +1 -1
  63. package/core/error-classifications.js +6 -0
  64. package/core/error-code-registry.d.ts +6 -0
  65. package/core/error-code-registry.d.ts.map +1 -1
  66. package/core/error-code-registry.js +6 -0
  67. package/core/error-envelope.js +2 -0
  68. package/core/errors.d.ts +1 -1
  69. package/core/errors.js +1 -1
  70. package/core/geoparquet-sql.d.ts +68 -4
  71. package/core/geoparquet-sql.d.ts.map +1 -1
  72. package/core/geoparquet-sql.js +325 -8
  73. package/core/odata-write-codec.d.ts.map +1 -1
  74. package/core/odata-write-codec.js +0 -1
  75. package/core/odata.d.ts +6 -0
  76. package/core/odata.d.ts.map +1 -1
  77. package/core/odata.js +6 -1
  78. package/core/ogc-processes.d.ts +182 -25
  79. package/core/ogc-processes.d.ts.map +1 -1
  80. package/core/ogc-processes.js +602 -30
  81. package/core/process-runner.d.ts +8 -1
  82. package/core/process-runner.d.ts.map +1 -1
  83. package/core/process-runner.js +1 -0
  84. package/core/protocol-transport.d.ts +2 -0
  85. package/core/protocol-transport.d.ts.map +1 -1
  86. package/core/stac.d.ts +31 -0
  87. package/core/stac.d.ts.map +1 -1
  88. package/core/stac.js +136 -19
  89. package/core/surfaces.d.ts.map +1 -1
  90. package/core/surfaces.js +273 -68
  91. package/core/types.d.ts +123 -9
  92. package/core/types.d.ts.map +1 -1
  93. package/core/wfs-axis-order.d.ts +18 -0
  94. package/core/wfs-axis-order.d.ts.map +1 -0
  95. package/core/wfs-axis-order.js +108 -0
  96. package/core/wfs-capabilities.d.ts +65 -24
  97. package/core/wfs-capabilities.d.ts.map +1 -1
  98. package/core/wfs-capabilities.js +237 -27
  99. package/core/wfs-filter.d.ts +26 -3
  100. package/core/wfs-filter.d.ts.map +1 -1
  101. package/core/wfs-filter.js +48 -53
  102. package/core/wfs-protocol-error.d.ts +12 -0
  103. package/core/wfs-protocol-error.d.ts.map +1 -0
  104. package/core/wfs-protocol-error.js +13 -0
  105. package/core/wfs.d.ts +53 -1
  106. package/core/wfs.d.ts.map +1 -1
  107. package/core/wfs.js +251 -29
  108. package/core/wms-feature-info.d.ts +92 -0
  109. package/core/wms-feature-info.d.ts.map +1 -0
  110. package/core/wms-feature-info.js +285 -0
  111. package/core/wms.d.ts +9 -0
  112. package/core/wms.d.ts.map +1 -1
  113. package/core/wms.js +17 -5
  114. package/esri-compat/event-bus.d.ts +20 -0
  115. package/esri-compat/event-bus.d.ts.map +1 -1
  116. package/esri-compat/feature-filter.d.ts +46 -1
  117. package/esri-compat/feature-filter.d.ts.map +1 -1
  118. package/esri-compat/feature-filter.js +49 -0
  119. package/esri-compat/geojson-layer.d.ts +4 -2
  120. package/esri-compat/geojson-layer.d.ts.map +1 -1
  121. package/esri-compat/geojson-layer.js +4 -2
  122. package/esri-compat/identity-manager.js +2 -2
  123. package/esri-compat/imagery-layer.d.ts +2 -1
  124. package/esri-compat/imagery-layer.d.ts.map +1 -1
  125. package/esri-compat/imagery-layer.js +2 -1
  126. package/esri-compat/layer-list.d.ts +8 -1
  127. package/esri-compat/layer-list.d.ts.map +1 -1
  128. package/esri-compat/layer-list.js +11 -4
  129. package/esri-compat/legend.d.ts.map +1 -1
  130. package/esri-compat/legend.js +1 -1
  131. package/esri-compat/locator.d.ts +297 -0
  132. package/esri-compat/locator.d.ts.map +1 -0
  133. package/esri-compat/locator.js +579 -0
  134. package/esri-compat/map-image-layer.d.ts.map +1 -1
  135. package/esri-compat/map-view.d.ts.map +1 -1
  136. package/esri-compat/map-view.js +1 -1
  137. package/esri-compat/scene-view.d.ts.map +1 -1
  138. package/esri-compat/time-slider.d.ts +29 -0
  139. package/esri-compat/time-slider.d.ts.map +1 -1
  140. package/esri-compat/time-slider.js +117 -0
  141. package/esri-compat/wfs-layer.d.ts +2 -1
  142. package/esri-compat/wfs-layer.d.ts.map +1 -1
  143. package/esri-compat/wfs-layer.js +2 -1
  144. package/esri-compat/widget-host.d.ts +42 -6
  145. package/esri-compat/widget-host.d.ts.map +1 -1
  146. package/esri-compat/widget-host.js +99 -10
  147. package/generated-app/projection.d.ts.map +1 -1
  148. package/generated-app/runtime.d.ts.map +1 -1
  149. package/map/data-to-map-bridge.d.ts +1 -1
  150. package/map/data-to-map-bridge.d.ts.map +1 -1
  151. package/map/data-to-map-bridge.js +1 -2
  152. package/map/honua-map.d.ts.map +1 -1
  153. package/map/honua-map.js +1 -1
  154. package/map/index.d.ts +2 -0
  155. package/map/index.d.ts.map +1 -1
  156. package/map/index.js +2 -0
  157. package/map/realtime-reconciliation-adapter.d.ts +98 -0
  158. package/map/realtime-reconciliation-adapter.d.ts.map +1 -0
  159. package/map/realtime-reconciliation-adapter.js +84 -0
  160. package/map/temporal-playback.d.ts +25 -0
  161. package/map/temporal-playback.d.ts.map +1 -1
  162. package/map/temporal-playback.js +29 -1
  163. package/operator/workspace/workspace.d.ts.map +1 -1
  164. package/operator/workspace/workspace.js +0 -2
  165. package/package.json +4 -3
  166. package/query-planner/canonical-filter.d.ts +30 -0
  167. package/query-planner/canonical-filter.d.ts.map +1 -0
  168. package/query-planner/canonical-filter.js +30 -0
  169. package/query-planner/columnar-plan.d.ts +63 -0
  170. package/query-planner/columnar-plan.d.ts.map +1 -0
  171. package/query-planner/columnar-plan.js +94 -0
  172. package/query-planner/diagnostics.d.ts +3 -3
  173. package/query-planner/diagnostics.d.ts.map +1 -1
  174. package/query-planner/diagnostics.js +17 -4
  175. package/query-planner/duckdb.d.ts.map +1 -1
  176. package/query-planner/duckdb.js +16 -2
  177. package/query-planner/execution-context.d.ts.map +1 -1
  178. package/query-planner/execution-context.js +3 -1
  179. package/query-planner/executor.d.ts.map +1 -1
  180. package/query-planner/executor.js +7 -1
  181. package/query-planner/geoservices.d.ts.map +1 -1
  182. package/query-planner/geoservices.js +24 -5
  183. package/query-planner/grpc.d.ts.map +1 -1
  184. package/query-planner/grpc.js +29 -5
  185. package/query-planner/index.d.ts +20 -5
  186. package/query-planner/index.d.ts.map +1 -1
  187. package/query-planner/index.js +16 -3
  188. package/query-planner/ir.d.ts +6 -1
  189. package/query-planner/ir.d.ts.map +1 -1
  190. package/query-planner/ir.js +63 -1
  191. package/query-planner/odata-protocol-module.d.ts +54 -0
  192. package/query-planner/odata-protocol-module.d.ts.map +1 -0
  193. package/query-planner/odata-protocol-module.js +199 -0
  194. package/query-planner/odata-v1.d.ts +23 -0
  195. package/query-planner/odata-v1.d.ts.map +1 -0
  196. package/query-planner/odata-v1.js +202 -0
  197. package/query-planner/odata.d.ts +0 -3
  198. package/query-planner/odata.d.ts.map +1 -1
  199. package/query-planner/odata.js +0 -143
  200. package/query-planner/ogc-features.d.ts.map +1 -1
  201. package/query-planner/ogc-features.js +23 -1
  202. package/query-planner/planner.d.ts +2 -2
  203. package/query-planner/planner.d.ts.map +1 -1
  204. package/query-planner/planner.js +146 -27
  205. package/query-planner/representation.d.ts +59 -0
  206. package/query-planner/representation.d.ts.map +1 -0
  207. package/query-planner/representation.js +140 -0
  208. package/query-planner/types.d.ts +153 -3
  209. package/query-planner/types.d.ts.map +1 -1
  210. package/query-planner/wfs-protocol-module.d.ts +57 -0
  211. package/query-planner/wfs-protocol-module.d.ts.map +1 -0
  212. package/query-planner/wfs-protocol-module.js +731 -0
  213. package/query-planner/wfs-v1.d.ts +41 -0
  214. package/query-planner/wfs-v1.d.ts.map +1 -0
  215. package/query-planner/wfs-v1.js +366 -0
  216. package/query-planner/wfs.d.ts +1 -3
  217. package/query-planner/wfs.d.ts.map +1 -1
  218. package/query-planner/wfs.js +1 -70
  219. package/realtime/checkpoint-store.d.ts +206 -0
  220. package/realtime/checkpoint-store.d.ts.map +1 -0
  221. package/realtime/checkpoint-store.js +504 -0
  222. package/realtime/honua-server.d.ts +8 -0
  223. package/realtime/honua-server.d.ts.map +1 -1
  224. package/realtime/honua-server.js +123 -14
  225. package/realtime/index.d.ts +4 -0
  226. package/realtime/index.d.ts.map +1 -1
  227. package/realtime/index.js +2 -0
  228. package/realtime/reconciliation.d.ts +245 -0
  229. package/realtime/reconciliation.d.ts.map +1 -0
  230. package/realtime/reconciliation.js +377 -0
  231. package/realtime/resumable-transport.d.ts.map +1 -1
  232. package/realtime/sse.d.ts.map +1 -1
  233. package/realtime/websocket.d.ts.map +1 -1
  234. package/realtime/wire.d.ts +2 -1
  235. package/realtime/wire.d.ts.map +1 -1
  236. package/realtime/wire.js +24 -8
  237. package/replica-sync/errors.d.ts +19 -1
  238. package/replica-sync/errors.d.ts.map +1 -1
  239. package/replica-sync/errors.js +16 -0
  240. package/replica-sync/geoservices.d.ts +260 -0
  241. package/replica-sync/geoservices.d.ts.map +1 -0
  242. package/replica-sync/geoservices.js +1093 -0
  243. package/replica-sync/index.d.ts +5 -1
  244. package/replica-sync/index.d.ts.map +1 -1
  245. package/replica-sync/index.js +3 -1
  246. package/replica-sync/transport-conformance.d.ts +58 -0
  247. package/replica-sync/transport-conformance.d.ts.map +1 -0
  248. package/replica-sync/transport-conformance.js +265 -0
  249. package/replica-sync/types.d.ts +22 -0
  250. package/replica-sync/types.d.ts.map +1 -1
  251. package/runtime/index.d.ts +6 -2
  252. package/runtime/index.d.ts.map +1 -1
  253. package/runtime/index.js +3 -1
  254. package/runtime/load-package.d.ts +24 -0
  255. package/runtime/load-package.d.ts.map +1 -1
  256. package/runtime/load-package.js +45 -1
  257. package/runtime/maplibre-renderer.d.ts +11 -0
  258. package/runtime/maplibre-renderer.d.ts.map +1 -1
  259. package/runtime/maplibre-renderer.js +32 -7
  260. package/runtime/offline-region-protocol.d.ts +73 -0
  261. package/runtime/offline-region-protocol.d.ts.map +1 -0
  262. package/runtime/offline-region-protocol.js +63 -0
  263. package/runtime/offline-region-style.d.ts +78 -0
  264. package/runtime/offline-region-style.d.ts.map +1 -0
  265. package/runtime/offline-region-style.js +147 -0
  266. package/runtime/pmtiles-protocol.d.ts +7 -8
  267. package/runtime/pmtiles-protocol.d.ts.map +1 -1
  268. package/runtime/pmtiles-protocol.js +19 -66
  269. package/runtime/protocol-registry.d.ts +55 -0
  270. package/runtime/protocol-registry.d.ts.map +1 -0
  271. package/runtime/protocol-registry.js +103 -0
  272. package/runtime/runtime.d.ts +2 -0
  273. package/runtime/runtime.d.ts.map +1 -1
  274. package/runtime/runtime.js +6 -1
  275. package/scene-workspace/analysis-widgets.d.ts +4 -2
  276. package/scene-workspace/analysis-widgets.d.ts.map +1 -1
  277. package/scene-workspace/analysis-widgets.js +4 -2
  278. package/scene-workspace/camera-correspondence.d.ts +151 -0
  279. package/scene-workspace/camera-correspondence.d.ts.map +1 -0
  280. package/scene-workspace/camera-correspondence.js +220 -0
  281. package/scene-workspace/cesium-adapter.d.ts +230 -29
  282. package/scene-workspace/cesium-adapter.d.ts.map +1 -1
  283. package/scene-workspace/cesium-adapter.js +741 -56
  284. package/scene-workspace/cesium-mount.d.ts +205 -0
  285. package/scene-workspace/cesium-mount.d.ts.map +1 -0
  286. package/scene-workspace/cesium-mount.js +392 -0
  287. package/scene-workspace/cesium-scene-owner.d.ts +160 -0
  288. package/scene-workspace/cesium-scene-owner.d.ts.map +1 -0
  289. package/scene-workspace/cesium-scene-owner.js +205 -0
  290. package/scene-workspace/cesium-state-sync.d.ts +101 -0
  291. package/scene-workspace/cesium-state-sync.d.ts.map +1 -0
  292. package/scene-workspace/cesium-state-sync.js +432 -0
  293. package/scene-workspace/cesium-time.d.ts +346 -0
  294. package/scene-workspace/cesium-time.d.ts.map +1 -0
  295. package/scene-workspace/cesium-time.js +403 -0
  296. package/scene-workspace/index.d.ts +42 -10
  297. package/scene-workspace/index.d.ts.map +1 -1
  298. package/scene-workspace/index.js +32 -7
  299. package/scene-workspace/maplibre-state-sync.d.ts +112 -0
  300. package/scene-workspace/maplibre-state-sync.d.ts.map +1 -0
  301. package/scene-workspace/maplibre-state-sync.js +400 -0
  302. package/scene-workspace/primitives.d.ts +237 -3
  303. package/scene-workspace/primitives.d.ts.map +1 -1
  304. package/scene-workspace/primitives.js +1087 -17
  305. package/scene-workspace/scene-discovery.d.ts +5 -2
  306. package/scene-workspace/scene-discovery.d.ts.map +1 -1
  307. package/scene-workspace/scene-discovery.js +5 -2
  308. package/scene-workspace/scene-view.d.ts +5 -2
  309. package/scene-workspace/scene-view.d.ts.map +1 -1
  310. package/scene-workspace/scene-view.js +5 -2
  311. package/scene-workspace/source-to-cesium.d.ts +141 -8
  312. package/scene-workspace/source-to-cesium.d.ts.map +1 -1
  313. package/scene-workspace/source-to-cesium.js +497 -72
  314. package/scene-workspace/state-sync-port-kit.d.ts +156 -0
  315. package/scene-workspace/state-sync-port-kit.d.ts.map +1 -0
  316. package/scene-workspace/state-sync-port-kit.js +319 -0
  317. package/scene-workspace/state-sync.d.ts +34 -1
  318. package/scene-workspace/state-sync.d.ts.map +1 -1
  319. package/scene-workspace/state-sync.js +48 -0
  320. package/scene-workspace/types.d.ts +8 -0
  321. package/scene-workspace/types.d.ts.map +1 -1
  322. package/scene-workspace/types.js +2 -0
  323. package/scene-workspace/workspace.d.ts +12 -1
  324. package/scene-workspace/workspace.d.ts.map +1 -1
  325. package/scene-workspace/workspace.js +13 -0
  326. package/studio/index.d.ts +24 -7
  327. package/studio/index.d.ts.map +1 -1
  328. package/studio/index.js +21 -7
  329. package/studio/lifecycle-client.d.ts +164 -0
  330. package/studio/lifecycle-client.d.ts.map +1 -0
  331. package/studio/lifecycle-client.js +299 -0
  332. package/studio/lifecycle-errors.d.ts +91 -0
  333. package/studio/lifecycle-errors.d.ts.map +1 -0
  334. package/studio/lifecycle-errors.js +77 -0
  335. package/studio/lifecycle-types.d.ts +321 -0
  336. package/studio/lifecycle-types.d.ts.map +1 -0
  337. package/studio/lifecycle-types.js +22 -0
  338. package/web-components/controller.d.ts.map +1 -1
  339. package/web-components/csp-styles.d.ts +6 -0
  340. package/web-components/csp-styles.d.ts.map +1 -0
  341. package/web-components/csp-styles.js +53 -0
  342. package/web-components/elements.d.ts +158 -2
  343. package/web-components/elements.d.ts.map +1 -1
  344. package/web-components/elements.js +1302 -215
  345. package/web-components/export-redaction.d.ts +252 -0
  346. package/web-components/export-redaction.d.ts.map +1 -0
  347. package/web-components/export-redaction.js +588 -0
  348. package/web-components/export.d.ts +417 -0
  349. package/web-components/export.d.ts.map +1 -0
  350. package/web-components/export.js +719 -0
  351. package/web-components/feature-editor-model.d.ts +265 -0
  352. package/web-components/feature-editor-model.d.ts.map +1 -0
  353. package/web-components/feature-editor-model.js +438 -0
  354. package/web-components/feature-editor-sketch.d.ts +125 -0
  355. package/web-components/feature-editor-sketch.d.ts.map +1 -0
  356. package/web-components/feature-editor-sketch.js +194 -0
  357. package/web-components/feature-editor-workflow.d.ts +286 -0
  358. package/web-components/feature-editor-workflow.d.ts.map +1 -0
  359. package/web-components/feature-editor-workflow.js +889 -0
  360. package/web-components/feature-editor.d.ts +83 -0
  361. package/web-components/feature-editor.d.ts.map +1 -0
  362. package/web-components/feature-editor.js +829 -0
  363. package/web-components/feature-table-engine.d.ts +465 -0
  364. package/web-components/feature-table-engine.d.ts.map +1 -0
  365. package/web-components/feature-table-engine.js +1360 -0
  366. package/web-components/feature-table-view.d.ts +95 -0
  367. package/web-components/feature-table-view.d.ts.map +1 -0
  368. package/web-components/feature-table-view.js +343 -0
  369. package/web-components/index.d.ts +34 -3
  370. package/web-components/index.d.ts.map +1 -1
  371. package/web-components/index.js +35 -2
  372. package/web-components/maplibre-renderer.d.ts.map +1 -1
  373. package/web-components/maplibre-renderer.js +13 -4
  374. package/web-components/measurement.d.ts +3 -1
  375. package/web-components/measurement.d.ts.map +1 -1
  376. package/web-components/measurement.js +62 -18
  377. package/web-components/time-slider.d.ts +122 -0
  378. package/web-components/time-slider.d.ts.map +1 -0
  379. package/web-components/time-slider.js +740 -0
  380. package/web-components/types.d.ts +310 -0
  381. package/web-components/types.d.ts.map +1 -1
  382. package/webmap/convert-label.js +0 -1
  383. package/webmap/convert-symbol.d.ts.map +1 -1
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Renderer-neutral reconciliation of accepted realtime deltas (issue #559).
3
+ *
4
+ * `reducer.ts` already folds `snapshot`/`upsert`/`delete`/`delta` events into
5
+ * one authoritative `RealtimeFeatureState` (`records`/`tombstones`, keyed by
6
+ * {@link realtimeFeatureKey}) — that state is the accepted realtime store this
7
+ * module builds on. This module adds the piece #556/#557 deliberately left
8
+ * open: turning a `(previous, next, trigger)` state transition into an
9
+ * explicit, identity-stable **patch** (create/update/delete) or **rebuild**
10
+ * (replacement snapshot, schema change, or policy-driven queue overflow)
11
+ * decision, plus the derived-state reconciliation that keeps caches,
12
+ * selection, filters, and viewport deterministic across it:
13
+ *
14
+ * - {@link diffRealtimeFeatureState} — pure REQ-001 identity/patch-rebuild
15
+ * classification for one event or explicit reset trigger.
16
+ * - {@link createRealtimeReconciler} — stateful REQ-004 policy: bounds the
17
+ * pending-patch queue and switches `mode` to `"rebuild"` once a single
18
+ * event or the accumulated queue crosses an explicit threshold, so a
19
+ * renderer never has to apply an unbounded patch backlog.
20
+ * - {@link realtimeReconciliationVersion} — the resume-position fields a
21
+ * derived cache should record so it can state exactly which cursor/sequence
22
+ * it reflects (the accepted store in `store.ts`/`reducer.ts` remains the
23
+ * sole authority; nothing here re-derives truth from a cache).
24
+ * - {@link createRealtimeReconciledCache} — a REQ-002 generic, renderer-neutral
25
+ * feature cache driven by reconciliation results; adapt its snapshot into a
26
+ * `Result<T>`-shaped or `HonuaQueryCache`-backed cache as needed.
27
+ * - {@link reconcileRealtimeKeyedState} / {@link reconcileRealtimeViewport} —
28
+ * REQ-003 deterministic preservation of any identity-keyed UI state
29
+ * (selection, an active client-side filter's matched-feature set) and of an
30
+ * opaque viewport value, both with a structured invalidation reason instead
31
+ * of a silent reset.
32
+ *
33
+ * `@honua/sdk-js/map`'s `realtime-reconciliation-adapter.ts` is the only
34
+ * place a `RealtimeReconciliationResult` is projected onto MapLibre
35
+ * (`setFeatureState` for `"patch"`, a caller-supplied rebuild callback for
36
+ * `"rebuild"`) — this module never imports `maplibre-gl` and has no
37
+ * renderer-specific dependency (REQ-005). deck.gl/Cesium adapters and the
38
+ * transport implementations that feed `previous`/`next` state are out of
39
+ * scope for #559.
40
+ *
41
+ * @module
42
+ */
43
+ import { HonuaSdkError, mergeHonuaErrorContext } from "../core/error-envelope.js";
44
+ import { realtimeFeatureKey } from "./reducer.js";
45
+ /** A stable, machine-readable reconciliation failure. @experimental */
46
+ export class HonuaRealtimeReconciliationError extends HonuaSdkError {
47
+ code;
48
+ detail;
49
+ constructor(code, message, detail, options = {}) {
50
+ super(REALTIME_RECONCILIATION_ERROR_CODES[code], message, {
51
+ ...options,
52
+ context: mergeHonuaErrorContext(detail, options.context),
53
+ });
54
+ this.code = code;
55
+ this.detail = detail;
56
+ this.name = "HonuaRealtimeReconciliationError";
57
+ }
58
+ }
59
+ const REALTIME_RECONCILIATION_ERROR_CODES = {
60
+ disposed: "realtime.reconciliation.disposed",
61
+ "invalid-option": "realtime.reconciliation.invalid-option",
62
+ };
63
+ /**
64
+ * Classify one `(previous, next)` accepted-store transition into identity-stable
65
+ * create/update/delete changes, or an explicit reset (replacement snapshot,
66
+ * schema change, source-version change, authorization-scope change, or a
67
+ * caller-initiated manual reset). Pure and side-effect free — `next` must
68
+ * already be the reducer's output for `trigger` (`reduceRealtimeFeatureState`
69
+ * when `trigger.kind === "event"`); this function never re-derives store state.
70
+ *
71
+ * @experimental
72
+ */
73
+ export function diffRealtimeFeatureState(previous, next, trigger) {
74
+ if (trigger.kind === "reset") {
75
+ return Object.freeze({
76
+ changes: recordsAsCreateChanges(next),
77
+ reset: true,
78
+ resetReason: trigger.reason,
79
+ ...(trigger.detail !== undefined ? { resetDetail: trigger.detail } : {}),
80
+ });
81
+ }
82
+ const event = trigger.event;
83
+ switch (event.type) {
84
+ case "snapshot": {
85
+ if (event.replace ?? true) {
86
+ return Object.freeze({
87
+ changes: recordsAsCreateChanges(next),
88
+ reset: true,
89
+ resetReason: "replacement-snapshot",
90
+ });
91
+ }
92
+ return Object.freeze({
93
+ changes: event.features.map((feature) => classifyUpsert(previous, next, feature)),
94
+ reset: false,
95
+ });
96
+ }
97
+ case "upsert":
98
+ return Object.freeze({ changes: [classifyUpsert(previous, next, event.feature)], reset: false });
99
+ case "delete":
100
+ return Object.freeze({ changes: [classifyDelete(next, event)], reset: false });
101
+ case "delta":
102
+ return Object.freeze({
103
+ changes: [
104
+ ...(event.upserts ?? []).map((feature) => classifyUpsert(previous, next, feature)),
105
+ ...(event.deletes ?? []).map((tombstone) => classifyDelete(next, tombstone)),
106
+ ],
107
+ reset: false,
108
+ });
109
+ case "heartbeat":
110
+ case "status":
111
+ case "error":
112
+ return Object.freeze({ changes: [], reset: false });
113
+ }
114
+ }
115
+ function classifyUpsert(previous, next, patch) {
116
+ const key = realtimeFeatureKey(patch.sourceId, patch.id);
117
+ const existed = Boolean(previous.records[key]);
118
+ const record = next.records[key];
119
+ return Object.freeze({
120
+ kind: existed ? "update" : "create",
121
+ key,
122
+ id: patch.id,
123
+ ...(patch.sourceId !== undefined ? { sourceId: patch.sourceId } : {}),
124
+ ...(record ? { record } : {}),
125
+ });
126
+ }
127
+ function classifyDelete(next, input) {
128
+ const key = realtimeFeatureKey(input.sourceId, input.id);
129
+ const tombstone = next.tombstones[key];
130
+ return Object.freeze({
131
+ kind: "delete",
132
+ key,
133
+ id: input.id,
134
+ ...(input.sourceId !== undefined ? { sourceId: input.sourceId } : {}),
135
+ ...(tombstone ? { tombstone } : {}),
136
+ });
137
+ }
138
+ function recordsAsCreateChanges(next) {
139
+ return Object.freeze(Object.values(next.records).map((record) => Object.freeze({
140
+ kind: "create",
141
+ key: record.key,
142
+ id: record.id,
143
+ ...(record.sourceId !== undefined ? { sourceId: record.sourceId } : {}),
144
+ record,
145
+ })));
146
+ }
147
+ /** Project the accepted store's current resume position — what a derived cache built from `state` reflects. @experimental */
148
+ export function realtimeReconciliationVersion(state) {
149
+ return Object.freeze({
150
+ ...(state.cursor !== undefined ? { cursor: state.cursor } : {}),
151
+ ...(state.watermark !== undefined ? { watermark: state.watermark } : {}),
152
+ ...(state.timestamp !== undefined ? { timestamp: state.timestamp } : {}),
153
+ ...(state.lastSequence !== undefined ? { sequence: state.lastSequence } : {}),
154
+ ...(state.deltaToken !== undefined ? { deltaToken: state.deltaToken } : {}),
155
+ });
156
+ }
157
+ /**
158
+ * Create a bounded, renderer-neutral reconciliation policy: identity changes
159
+ * classify through {@link diffRealtimeFeatureState}; a single oversized event,
160
+ * or an accumulated pending-patch count over `rebuildThreshold`, switches
161
+ * `mode` to `"rebuild"` by explicit policy rather than growing an unbounded
162
+ * patch queue.
163
+ *
164
+ * @experimental
165
+ */
166
+ export function createRealtimeReconciler(options = {}) {
167
+ const maxChangesPerEvent = positiveInteger(options.maxChangesPerEvent, 500, "maxChangesPerEvent");
168
+ const rebuildThreshold = positiveInteger(options.rebuildThreshold, 2000, "rebuildThreshold");
169
+ let pending = 0;
170
+ let disposed = false;
171
+ return {
172
+ get disposed() {
173
+ return disposed;
174
+ },
175
+ get pendingPatchCount() {
176
+ return pending;
177
+ },
178
+ reconcile(previous, next, trigger) {
179
+ if (disposed) {
180
+ throw new HonuaRealtimeReconciliationError("disposed", "Cannot reconcile with a disposed realtime reconciler.");
181
+ }
182
+ const diff = diffRealtimeFeatureState(previous, next, trigger);
183
+ const version = realtimeReconciliationVersion(next);
184
+ if (diff.reset) {
185
+ pending = 0;
186
+ return freezeResult({
187
+ mode: "rebuild",
188
+ rebuildReason: "reset",
189
+ changes: diff.changes,
190
+ version,
191
+ reset: true,
192
+ ...(diff.resetReason !== undefined ? { resetReason: diff.resetReason } : {}),
193
+ pendingPatchCount: 0,
194
+ });
195
+ }
196
+ if (diff.changes.length > maxChangesPerEvent) {
197
+ pending = 0;
198
+ return freezeResult({
199
+ mode: "rebuild",
200
+ rebuildReason: "event-exceeds-patch-bound",
201
+ changes: nonResetRebuildChanges(next, diff.changes),
202
+ version,
203
+ reset: false,
204
+ pendingPatchCount: 0,
205
+ });
206
+ }
207
+ pending += diff.changes.length;
208
+ if (pending > rebuildThreshold) {
209
+ pending = 0;
210
+ return freezeResult({
211
+ mode: "rebuild",
212
+ rebuildReason: "queue-threshold-exceeded",
213
+ changes: nonResetRebuildChanges(next, diff.changes),
214
+ version,
215
+ reset: false,
216
+ pendingPatchCount: 0,
217
+ });
218
+ }
219
+ return freezeResult({
220
+ mode: "patch",
221
+ changes: diff.changes,
222
+ version,
223
+ reset: false,
224
+ pendingPatchCount: pending,
225
+ });
226
+ },
227
+ dispose() {
228
+ disposed = true;
229
+ pending = 0;
230
+ },
231
+ };
232
+ }
233
+ // A rebuild consumer (createRealtimeReconciledCache.apply, a mounted source's
234
+ // re-materialization path) treats `changes` as the complete replacement state,
235
+ // so a non-reset rebuild must carry the full accepted store — the triggering
236
+ // event's diff alone would drop every live feature outside that one event. The
237
+ // event's deletes ride along so identity-keyed state (selection, filter
238
+ // membership) can still invalidate exactly what this transition removed.
239
+ function nonResetRebuildChanges(next, eventChanges) {
240
+ return Object.freeze([...recordsAsCreateChanges(next), ...eventChanges.filter((change) => change.kind === "delete")]);
241
+ }
242
+ function freezeResult(result) {
243
+ return Object.freeze({ ...result, changes: Object.freeze([...result.changes]) });
244
+ }
245
+ function positiveInteger(value, fallback, name) {
246
+ if (value === undefined)
247
+ return fallback;
248
+ if (!Number.isSafeInteger(value) || value < 1) {
249
+ throw new HonuaRealtimeReconciliationError("invalid-option", `${name} must be a positive safe integer.`, {
250
+ [name]: value,
251
+ });
252
+ }
253
+ return value;
254
+ }
255
+ /**
256
+ * Create a generic, renderer-neutral cache of live features keyed exactly
257
+ * like the accepted realtime store. Adapt {@link RealtimeReconciledCache.snapshot}
258
+ * into a `Result<T>`-shaped or `HonuaQueryCache`-backed cache entry as needed —
259
+ * this module intentionally does not import either.
260
+ *
261
+ * @experimental
262
+ */
263
+ export function createRealtimeReconciledCache() {
264
+ let order = [];
265
+ let byKey = new Map();
266
+ let version = Object.freeze({});
267
+ let disposed = false;
268
+ const snapshotOf = () => Object.freeze({
269
+ features: Object.freeze(order.map((key) => byKey.get(key))),
270
+ version,
271
+ });
272
+ return {
273
+ get disposed() {
274
+ return disposed;
275
+ },
276
+ snapshot: snapshotOf,
277
+ apply(result) {
278
+ if (disposed) {
279
+ throw new HonuaRealtimeReconciliationError("disposed", "Cannot apply to a disposed realtime reconciled cache.");
280
+ }
281
+ if (result.mode === "rebuild") {
282
+ const nextOrder = [];
283
+ const nextByKey = new Map();
284
+ for (const change of result.changes) {
285
+ if (change.kind === "delete" || !change.record)
286
+ continue;
287
+ nextOrder.push(change.key);
288
+ nextByKey.set(change.key, change.record.feature);
289
+ }
290
+ order = nextOrder;
291
+ byKey = nextByKey;
292
+ }
293
+ else {
294
+ for (const change of result.changes) {
295
+ if (change.kind === "delete") {
296
+ if (byKey.delete(change.key))
297
+ order = order.filter((key) => key !== change.key);
298
+ }
299
+ else if (change.record) {
300
+ if (!byKey.has(change.key))
301
+ order.push(change.key);
302
+ byKey.set(change.key, change.record.feature);
303
+ }
304
+ }
305
+ }
306
+ version = result.version;
307
+ return snapshotOf();
308
+ },
309
+ dispose() {
310
+ disposed = true;
311
+ order = [];
312
+ byKey = new Map();
313
+ },
314
+ };
315
+ }
316
+ /**
317
+ * Deterministically preserve or invalidate an identity-keyed set of feature
318
+ * keys (a selection, or the matched-key set of an active client-side filter)
319
+ * across one reconciliation result:
320
+ *
321
+ * - `result.reset` (replacement snapshot, schema/source/scope change, or
322
+ * manual reset): every key is invalidated with reason `"reset"` (or
323
+ * `"schema-changed"` when that was the reset reason) and `next` is empty —
324
+ * a rebuild replaces identity wholesale, so no prior key is safe to assume
325
+ * still exists.
326
+ * - Otherwise: a key backed by a feature the delta deleted is invalidated
327
+ * with reason `"feature-deleted"`; every other key is preserved unchanged.
328
+ *
329
+ * Reused for both selection and filter membership — both are "a set of
330
+ * feature keys that must stay valid or be explicitly dropped."
331
+ *
332
+ * @experimental
333
+ */
334
+ export function reconcileRealtimeKeyedState(keys, result) {
335
+ if (result.reset) {
336
+ const reason = result.resetReason === "schema-changed" ? "schema-changed" : "reset";
337
+ return Object.freeze({
338
+ next: Object.freeze(new Set()),
339
+ invalidations: Object.freeze([...keys].map((key) => Object.freeze({ key, reason }))),
340
+ });
341
+ }
342
+ const deletedKeys = new Set();
343
+ for (const change of result.changes) {
344
+ if (change.kind === "delete")
345
+ deletedKeys.add(change.key);
346
+ }
347
+ if (deletedKeys.size === 0) {
348
+ return Object.freeze({ next: keys, invalidations: Object.freeze([]) });
349
+ }
350
+ const next = new Set();
351
+ const invalidations = [];
352
+ for (const key of keys) {
353
+ if (deletedKeys.has(key))
354
+ invalidations.push(Object.freeze({ key, reason: "feature-deleted" }));
355
+ else
356
+ next.add(key);
357
+ }
358
+ return Object.freeze({ next: Object.freeze(next), invalidations: Object.freeze(invalidations) });
359
+ }
360
+ /**
361
+ * Preserve an opaque viewport value across a reconciliation result. The
362
+ * viewport itself is always passed through unchanged (this module never
363
+ * moves a camera); `invalidated` is `true` only on `result.reset`, so a
364
+ * caller can decide whether to refit bounds — deterministic, and never a
365
+ * silent no-op on a schema/replacement-snapshot reset.
366
+ *
367
+ * @experimental
368
+ */
369
+ export function reconcileRealtimeViewport(viewport, result) {
370
+ if (!result.reset)
371
+ return Object.freeze({ viewport, invalidated: false });
372
+ return Object.freeze({
373
+ viewport,
374
+ invalidated: true,
375
+ reason: result.resetReason === "schema-changed" ? "schema-changed" : "reset",
376
+ });
377
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"resumable-transport.d.ts","sourceRoot":"","sources":["../../../src/realtime/resumable-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,KAAK,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAEhC,KAAK,uBAAuB,EAG7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,wCAAwC,EAAE,MAAM,UAAU,CAAC;AACzE,OAAO,KAAK,EAGV,wBAAwB,EAGzB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,gBAAgB,CAAC;AAExE,MAAM,WAAW,uBAAuB;IACtC,gHAAgH;IAChH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kHAAkH;IAClH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,mCAAmC;IAClD,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,4BAA4B,CAAC;CACpD;AAED,MAAM,WAAW,iCAAiC,CAAC,QAAQ,GAAG,OAAO;IACnE,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,uBAAuB,CAAC;IACnD;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,2BAA2B,CAAC;IACzD,yDAAyD;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC;IAC7C,wHAAwH;IACxH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,mCAAmC,KAAK,IAAI,CAAC;IAChF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAkCD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAK5G;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,QAAQ,GAAG,OAAO,EACjE,SAAS,EAAE,wBAAwB,CAAC,QAAQ,CAAC,EAC7C,OAAO,EAAE,iCAAiC,CAAC,QAAQ,CAAC,GACnD,wBAAwB,CAAC,QAAQ,CAAC,CA+TpC;AAED;;;GAGG;AACH,wBAAgB,wCAAwC,CAAC,QAAQ,GAAG,OAAO,EACzE,UAAU,EAAE,wCAAwC,CAAC,QAAQ,CAAC,EAC9D,gBAAgB,EAAE,iCAAiC,CAAC,QAAQ,CAAC,GAC5D,wBAAwB,CAAC,QAAQ,CAAC,CAKpC;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,QAAQ,GAAG,OAAO,EAClE,gBAAgB,EAAE,iCAAiC,CAAC,QAAQ,CAAC,EAC7D,gBAAgB,EAAE,iCAAiC,CAAC,QAAQ,CAAC,GAC5D,wBAAwB,CAAC,QAAQ,CAAC,CAKpC"}
1
+ {"version":3,"file":"resumable-transport.d.ts","sourceRoot":"","sources":["../../../src/realtime/resumable-transport.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/realtime/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAEpB,wBAAwB,EAExB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,KAAK,IAAI,IAAI,CAAC;IACd,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvF,mBAAmB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;CAC3F;AAED,MAAM,MAAM,oCAAoC,GAAG,CACjD,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,eAAe,KACnB,6BAA6B,CAAC;AAEnC,MAAM,WAAW,wCAAwC,CAAC,QAAQ,GAAG,OAAO;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,oCAAoC,CAAC;IACnE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,CAAC,QAAQ,CAAC,CAAC;CAC7E;AAID,wBAAgB,uCAAuC,CAAC,QAAQ,GAAG,OAAO,EACxE,OAAO,EAAE,wCAAwC,CAAC,QAAQ,CAAC,GAC1D,wBAAwB,CAAC,QAAQ,CAAC,CAgGpC;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,GAAG,GAAG,CAsBhG;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAElH"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/realtime/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EAExB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,KAAK,IAAI,IAAI,CAAC;IACd,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvF,mBAAmB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;CAC3F;AAED,MAAM,MAAM,oCAAoC,GAAG,CACjD,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,eAAe,KACnB,6BAA6B,CAAC;AAEnC,MAAM,WAAW,wCAAwC,CAAC,QAAQ,GAAG,OAAO;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,oCAAoC,CAAC;IACnE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,CAAC,QAAQ,CAAC,CAAC;CAC7E;AAID,wBAAgB,uCAAuC,CAAC,QAAQ,GAAG,OAAO,EACxE,OAAO,EAAE,wCAAwC,CAAC,QAAQ,CAAC,GAC1D,wBAAwB,CAAC,QAAQ,CAAC,CAgGpC;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,GAAG,GAAG,CAsBhG;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAElH"}
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../../src/realtime/websocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EACV,oBAAoB,EAEpB,wBAAwB,EAExB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,kGAAkG;AAClG,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,wBAAwB,GAAG,CACrC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,KAClD,iBAAiB,CAAC;AAEvB,MAAM,WAAW,iCAAiC,CAAC,QAAQ,GAAG,OAAO;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC5E;;;;;OAKG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,OAAO,CAAC;IACpF;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAClD;AAID,wBAAgB,gCAAgC,CAAC,QAAQ,GAAG,OAAO,EACjE,OAAO,EAAE,iCAAiC,CAAC,QAAQ,CAAC,GACnD,wBAAwB,CAAC,QAAQ,CAAC,CAwGpC"}
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../../src/realtime/websocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EAExB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,kGAAkG;AAClG,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,wBAAwB,GAAG,CACrC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,KAClD,iBAAiB,CAAC;AAEvB,MAAM,WAAW,iCAAiC,CAAC,QAAQ,GAAG,OAAO;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC5E;;;;;OAKG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,OAAO,CAAC;IACpF;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAClD;AAID,wBAAgB,gCAAgC,CAAC,QAAQ,GAAG,OAAO,EACjE,OAAO,EAAE,iCAAiC,CAAC,QAAQ,CAAC,GACnD,wBAAwB,CAAC,QAAQ,CAAC,CAwGpC"}
@@ -22,6 +22,7 @@ export declare function decodeDefaultRealtimeEnvelope<TFeature = unknown>(payloa
22
22
  */
23
23
  export declare function normalizeRealtimeErrorEvent<TFeature>(event: RealtimeFeatureEvent<TFeature>): RealtimeFeatureEvent<TFeature>;
24
24
  export type RealtimeTransportFailureCode = "consumer-failed" | "delivery-failed" | "invalid-event" | "transport-gap";
25
- export declare function realtimeFailure(code: RealtimeTransportFailureCode, message: string, cause: unknown): HonuaRealtimeResumeError;
25
+ export type RealtimeWireFailureCode = RealtimeTransportFailureCode | "cursor-expired" | "resume-unsupported";
26
+ export declare function realtimeFailure(code: RealtimeWireFailureCode, message: string, cause: unknown): HonuaRealtimeResumeError;
26
27
  export declare function isRecord(value: unknown): value is Record<string, unknown>;
27
28
  //# sourceMappingURL=wire.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../../src/realtime/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAclH;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAClD,KAAK,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GACpC,oBAAoB,CAAC,QAAQ,CAAC,CAehC;AAED,MAAM,MAAM,4BAA4B,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,eAAe,GAAG,eAAe,CAAC;AAErH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,4BAA4B,EAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,GACb,wBAAwB,CAI1B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../../src/realtime/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAclH;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAClD,KAAK,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GACpC,oBAAoB,CAAC,QAAQ,CAAC,CAuBhC;AAED,MAAM,MAAM,4BAA4B,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,eAAe,GAAG,eAAe,CAAC;AACrH,MAAM,MAAM,uBAAuB,GAAG,4BAA4B,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAE7G,wBAAgB,eAAe,CAC7B,IAAI,EAAE,uBAAuB,EAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,GACb,wBAAwB,CAM1B;AAYD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
package/realtime/wire.js CHANGED
@@ -37,20 +37,36 @@ export function decodeDefaultRealtimeEnvelope(payload) {
37
37
  export function normalizeRealtimeErrorEvent(event) {
38
38
  if (event.type !== "error")
39
39
  return event;
40
- const code = event.terminal ? "invalid-event" : "transport-gap";
41
- if (event.error instanceof HonuaRealtimeResumeError && isHonuaSdkError(event.error) && event.error.code === code)
42
- return event;
40
+ const terminal = event.terminal === true;
41
+ const code = terminal ? "invalid-event" : normalizeReconnectableWireCode(event.code);
42
+ const error = realtimeFailure(code, terminal
43
+ ? "Realtime stream reported a terminal protocol failure."
44
+ : code === "cursor-expired"
45
+ ? "Realtime stream reported that its resume cursor expired."
46
+ : code === "resume-unsupported"
47
+ ? "Realtime stream reported that resume is unsupported."
48
+ : "Realtime stream reported a reconnectable transport failure.", undefined);
43
49
  return {
44
- ...event,
45
- error: realtimeFailure(code, event.terminal
46
- ? "Realtime stream reported a terminal protocol failure."
47
- : "Realtime stream reported a reconnectable transport failure.", event.error),
50
+ type: "error",
51
+ code,
52
+ error,
53
+ ...(typeof event.terminal === "boolean" ? { terminal: event.terminal } : {}),
54
+ ...(isNonNegativeFiniteNumber(event.retryAfterMs) ? { retryAfterMs: event.retryAfterMs } : {}),
55
+ ...(isNonNegativeFiniteNumber(event.receivedAt) ? { receivedAt: event.receivedAt } : {}),
48
56
  };
49
57
  }
50
58
  export function realtimeFailure(code, message, cause) {
51
59
  return cause instanceof HonuaRealtimeResumeError && isHonuaSdkError(cause) && cause.code === code
52
60
  ? cause
53
- : new HonuaRealtimeResumeError(code, message, { cause });
61
+ : cause === undefined
62
+ ? new HonuaRealtimeResumeError(code, message)
63
+ : new HonuaRealtimeResumeError(code, message, { cause });
64
+ }
65
+ function normalizeReconnectableWireCode(value) {
66
+ return value === "cursor-expired" || value === "resume-unsupported" ? value : "transport-gap";
67
+ }
68
+ function isNonNegativeFiniteNumber(value) {
69
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
54
70
  }
55
71
  export function isRecord(value) {
56
72
  return typeof value === "object" && value !== null;
@@ -8,7 +8,13 @@
8
8
  * @module
9
9
  */
10
10
  import { HonuaSdkError } from "../core/error-envelope.js";
11
- export type ReplicaSyncErrorCode = "unsupported-sync" | "unsupported-conflict-review" | "unsupported-conflict-resolution" | "replica-not-found" | "conflict-not-found" | "replica-expired" | "conflict-already-resolved" | "merge-required" | "permission-denied" | "transport-failure";
11
+ export type ReplicaSyncErrorCode = "unsupported-sync" | "unsupported-conflict-review" | "unsupported-conflict-resolution" | "replica-not-found" | "conflict-not-found" | "replica-expired" | "conflict-already-resolved" | "merge-required" | "permission-denied"
12
+ /**
13
+ * A server response did not match the dialect this build was written against:
14
+ * an unknown classification code, a missing required member, or a value that
15
+ * cannot be read losslessly. Raised instead of guessing a mapping.
16
+ */
17
+ | "response-drift" | "transport-failure";
12
18
  export declare class HonuaReplicaSyncError extends HonuaSdkError {
13
19
  readonly code: ReplicaSyncErrorCode;
14
20
  readonly details: unknown;
@@ -20,4 +26,16 @@ export declare class HonuaReplicaSyncError extends HonuaSdkError {
20
26
  export declare function isHonuaReplicaSyncError(error: unknown): error is HonuaReplicaSyncError;
21
27
  /** True for the `unsupported-*` family of codes. */
22
28
  export declare function isUnsupportedReplicaSyncError(error: unknown): error is HonuaReplicaSyncError;
29
+ /**
30
+ * True for every typed refusal that means "this deployment does not offer the
31
+ * replica-sync capability you asked for".
32
+ *
33
+ * Two vocabularies legitimately answer that question: a transport that infers
34
+ * it from its own state raises the `unsupported-*` family, while a transport
35
+ * that reads a server's advertised capability surface raises the SDK-wide
36
+ * {@link HonuaCapabilityNotSupportedError} naming the capability. A caller
37
+ * deciding whether to hide manual conflict review must accept both, so the
38
+ * predicate lives here rather than being re-derived per call site.
39
+ */
40
+ export declare function isReplicaSyncCapabilityRefusal(error: unknown): boolean;
23
41
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/replica-sync/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAuB,aAAa,EAAyC,MAAM,2BAA2B,CAAC;AAEtH,MAAM,MAAM,oBAAoB,GAC5B,kBAAkB,GAClB,6BAA6B,GAC7B,iCAAiC,GACjC,mBAAmB,GACnB,oBAAoB,GACpB,iBAAiB,GACjB,2BAA2B,GAC3B,gBAAgB,GAChB,mBAAmB,GACnB,mBAAmB,CAAC;AAExB,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,SAAgB,IAAI,EAAE,oBAAoB,CAAC;IAC3C,SAAgB,OAAO,EAAE,OAAO,CAAC;gBAG/B,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAWzE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAEtF;AAED,oDAAoD;AACpD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAO5F"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/replica-sync/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAuB,aAAa,EAAyC,MAAM,2BAA2B,CAAC;AAGtH,MAAM,MAAM,oBAAoB,GAC5B,kBAAkB,GAClB,6BAA6B,GAC7B,iCAAiC,GACjC,mBAAmB,GACnB,oBAAoB,GACpB,iBAAiB,GACjB,2BAA2B,GAC3B,gBAAgB,GAChB,mBAAmB;AACrB;;;;GAIG;GACD,gBAAgB,GAChB,mBAAmB,CAAC;AAExB,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,SAAgB,IAAI,EAAE,oBAAoB,CAAC;IAC3C,SAAgB,OAAO,EAAE,OAAO,CAAC;gBAG/B,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAWzE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAEtF;AAED,oDAAoD;AACpD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAO5F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtE"}
@@ -8,6 +8,7 @@
8
8
  * @module
9
9
  */
10
10
  import { HonuaSdkError, isRetryableNetworkOrTimeoutHonuaError } from "../core/error-envelope.js";
11
+ import { HonuaCapabilityNotSupportedError } from "../core/errors.js";
11
12
  export class HonuaReplicaSyncError extends HonuaSdkError {
12
13
  code;
13
14
  details;
@@ -32,6 +33,20 @@ export function isUnsupportedReplicaSyncError(error) {
32
33
  error.code === "unsupported-conflict-review" ||
33
34
  error.code === "unsupported-conflict-resolution"));
34
35
  }
36
+ /**
37
+ * True for every typed refusal that means "this deployment does not offer the
38
+ * replica-sync capability you asked for".
39
+ *
40
+ * Two vocabularies legitimately answer that question: a transport that infers
41
+ * it from its own state raises the `unsupported-*` family, while a transport
42
+ * that reads a server's advertised capability surface raises the SDK-wide
43
+ * {@link HonuaCapabilityNotSupportedError} naming the capability. A caller
44
+ * deciding whether to hide manual conflict review must accept both, so the
45
+ * predicate lives here rather than being re-derived per call site.
46
+ */
47
+ export function isReplicaSyncCapabilityRefusal(error) {
48
+ return isUnsupportedReplicaSyncError(error) || error instanceof HonuaCapabilityNotSupportedError;
49
+ }
35
50
  const REPLICA_SYNC_ERROR_CODES = {
36
51
  "unsupported-sync": "offline.replica-sync.capability",
37
52
  "unsupported-conflict-review": "offline.replica-sync.capability",
@@ -41,6 +56,7 @@ const REPLICA_SYNC_ERROR_CODES = {
41
56
  "replica-expired": "offline.replica-sync.validation",
42
57
  "conflict-already-resolved": "offline.replica-sync.validation",
43
58
  "merge-required": "offline.replica-sync.validation",
59
+ "response-drift": "offline.replica-sync.validation",
44
60
  "permission-denied": "offline.replica-sync.permission-denied",
45
61
  "transport-failure": "offline.transport.failure",
46
62
  };