@synnaxlabs/client 0.56.2 → 0.57.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (741) hide show
  1. package/dist/client-DDACDVZ-.js +14505 -0
  2. package/dist/client-DDACDVZ-.js.map +1 -0
  3. package/dist/client.js +1128 -14876
  4. package/dist/client.js.map +1 -0
  5. package/dist/src/access/client.d.ts +10 -1
  6. package/dist/src/access/client.d.ts.map +1 -1
  7. package/dist/src/access/enforce.d.ts.map +1 -1
  8. package/dist/src/access/external.d.ts +1 -0
  9. package/dist/src/access/external.d.ts.map +1 -1
  10. package/dist/src/access/granted.d.ts +39 -0
  11. package/dist/src/access/granted.d.ts.map +1 -0
  12. package/dist/src/access/policy/client.d.ts +136 -147
  13. package/dist/src/access/policy/client.d.ts.map +1 -1
  14. package/dist/src/access/policy/types.gen.d.ts +15 -68
  15. package/dist/src/access/policy/types.gen.d.ts.map +1 -1
  16. package/dist/src/access/role/client.d.ts +77 -58
  17. package/dist/src/access/role/client.d.ts.map +1 -1
  18. package/dist/src/access/role/types.gen.d.ts +8 -14
  19. package/dist/src/access/role/types.gen.d.ts.map +1 -1
  20. package/dist/src/actions/actions.d.ts +5 -6
  21. package/dist/src/actions/actions.d.ts.map +1 -1
  22. package/dist/src/actions/controller.d.ts +194 -0
  23. package/dist/src/actions/controller.d.ts.map +1 -0
  24. package/dist/src/actions/external.d.ts +1 -0
  25. package/dist/src/actions/external.d.ts.map +1 -1
  26. package/dist/src/arc/actions.d.ts +575 -0
  27. package/dist/src/arc/actions.d.ts.map +1 -0
  28. package/dist/src/arc/actions.gen.d.ts +1439 -0
  29. package/dist/src/arc/actions.gen.d.ts.map +1 -0
  30. package/dist/src/arc/client.d.ts +97 -13
  31. package/dist/src/arc/client.d.ts.map +1 -1
  32. package/dist/src/arc/compiler/types.gen.d.ts +3 -3
  33. package/dist/src/arc/compiler/types.gen.d.ts.map +1 -1
  34. package/dist/src/arc/external.d.ts +2 -0
  35. package/dist/src/arc/external.d.ts.map +1 -1
  36. package/dist/src/arc/graph/types.gen.d.ts +45 -597
  37. package/dist/src/arc/graph/types.gen.d.ts.map +1 -1
  38. package/dist/src/arc/ir/index.d.ts +1 -1
  39. package/dist/src/arc/ir/index.d.ts.map +1 -1
  40. package/dist/src/arc/ir/ir.d.ts +2 -0
  41. package/dist/src/arc/ir/ir.d.ts.map +1 -0
  42. package/dist/src/arc/ir/types.gen.d.ts +58 -2807
  43. package/dist/src/arc/ir/types.gen.d.ts.map +1 -1
  44. package/dist/src/arc/module/types.gen.d.ts +18 -1090
  45. package/dist/src/arc/module/types.gen.d.ts.map +1 -1
  46. package/dist/src/arc/program/types.gen.d.ts +18 -1090
  47. package/dist/src/arc/program/types.gen.d.ts.map +1 -1
  48. package/dist/src/arc/text/types.gen.d.ts +54 -1
  49. package/dist/src/arc/text/types.gen.d.ts.map +1 -1
  50. package/dist/src/arc/types/types.gen.d.ts +35 -153
  51. package/dist/src/arc/types/types.gen.d.ts.map +1 -1
  52. package/dist/src/arc/types.gen.d.ts +98 -2278
  53. package/dist/src/arc/types.gen.d.ts.map +1 -1
  54. package/dist/src/auth/auth.d.ts +14 -2
  55. package/dist/src/auth/auth.d.ts.map +1 -1
  56. package/dist/src/channel/client.d.ts +113 -75
  57. package/dist/src/channel/client.d.ts.map +1 -1
  58. package/dist/src/channel/external.d.ts +0 -1
  59. package/dist/src/channel/external.d.ts.map +1 -1
  60. package/dist/src/channel/payload.d.ts +65 -56
  61. package/dist/src/channel/payload.d.ts.map +1 -1
  62. package/dist/src/channel/types.gen.d.ts +26 -73
  63. package/dist/src/channel/types.gen.d.ts.map +1 -1
  64. package/dist/src/channel/writer.d.ts +1 -3
  65. package/dist/src/channel/writer.d.ts.map +1 -1
  66. package/dist/src/client.d.ts +55 -27
  67. package/dist/src/client.d.ts.map +1 -1
  68. package/dist/src/connection/client.d.ts +146 -0
  69. package/dist/src/connection/client.d.ts.map +1 -0
  70. package/dist/src/connection/external.d.ts +3 -0
  71. package/dist/src/connection/external.d.ts.map +1 -0
  72. package/dist/src/connection/index.d.ts +1 -1
  73. package/dist/src/connection/index.d.ts.map +1 -1
  74. package/dist/src/connection/status.d.ts +252 -0
  75. package/dist/src/connection/status.d.ts.map +1 -0
  76. package/dist/src/control/client.d.ts +31 -7
  77. package/dist/src/control/client.d.ts.map +1 -1
  78. package/dist/src/control/state.d.ts +47 -16
  79. package/dist/src/control/state.d.ts.map +1 -1
  80. package/dist/src/device/client.d.ts +59 -17
  81. package/dist/src/device/client.d.ts.map +1 -1
  82. package/dist/src/device/types.gen.d.ts +17 -67
  83. package/dist/src/device/types.gen.d.ts.map +1 -1
  84. package/dist/src/errors.d.ts +17 -20
  85. package/dist/src/errors.d.ts.map +1 -1
  86. package/dist/src/ethercat/external.d.ts +2 -0
  87. package/dist/src/ethercat/external.d.ts.map +1 -0
  88. package/dist/src/ethercat/index.d.ts +2 -0
  89. package/dist/src/ethercat/index.d.ts.map +1 -0
  90. package/dist/src/ethercat/types.gen.d.ts +243 -0
  91. package/dist/src/ethercat/types.gen.d.ts.map +1 -0
  92. package/dist/src/framer/adapter.d.ts +8 -5
  93. package/dist/src/framer/adapter.d.ts.map +1 -1
  94. package/dist/src/framer/benchutil.d.ts +19 -0
  95. package/dist/src/framer/benchutil.d.ts.map +1 -0
  96. package/dist/src/framer/cache/cache.d.ts +38 -0
  97. package/dist/src/framer/cache/cache.d.ts.map +1 -0
  98. package/dist/src/framer/cache/dynamic.d.ts +91 -0
  99. package/dist/src/framer/cache/dynamic.d.ts.map +1 -0
  100. package/dist/src/framer/cache/reader.d.ts +57 -0
  101. package/dist/src/framer/cache/reader.d.ts.map +1 -0
  102. package/dist/src/framer/cache/static.d.ts +66 -0
  103. package/dist/src/framer/cache/static.d.ts.map +1 -0
  104. package/dist/src/framer/cache/streamer.d.ts +86 -0
  105. package/dist/src/framer/cache/streamer.d.ts.map +1 -0
  106. package/dist/src/framer/cache/transform.d.ts +18 -0
  107. package/dist/src/framer/cache/transform.d.ts.map +1 -0
  108. package/dist/src/framer/cache/unary.d.ts +39 -0
  109. package/dist/src/framer/cache/unary.d.ts.map +1 -0
  110. package/dist/src/framer/client.d.ts +35 -14
  111. package/dist/src/framer/client.d.ts.map +1 -1
  112. package/dist/src/framer/codec.d.ts.map +1 -1
  113. package/dist/src/framer/deleter.d.ts +3 -2
  114. package/dist/src/framer/deleter.d.ts.map +1 -1
  115. package/dist/src/framer/external.d.ts +6 -0
  116. package/dist/src/framer/external.d.ts.map +1 -1
  117. package/dist/src/framer/feed.d.ts +40 -0
  118. package/dist/src/framer/feed.d.ts.map +1 -0
  119. package/dist/src/framer/frame.d.ts +16 -20
  120. package/dist/src/framer/frame.d.ts.map +1 -1
  121. package/dist/src/framer/hardened.d.ts +70 -0
  122. package/dist/src/framer/hardened.d.ts.map +1 -0
  123. package/dist/src/framer/iterator.d.ts +36 -43
  124. package/dist/src/framer/iterator.d.ts.map +1 -1
  125. package/dist/src/framer/reader.d.ts +3 -2
  126. package/dist/src/framer/reader.d.ts.map +1 -1
  127. package/dist/src/framer/streamer.d.ts +132 -205
  128. package/dist/src/framer/streamer.d.ts.map +1 -1
  129. package/dist/src/framer/writer.d.ts +130 -161
  130. package/dist/src/framer/writer.d.ts.map +1 -1
  131. package/dist/src/group/client.d.ts +66 -9
  132. package/dist/src/group/client.d.ts.map +1 -1
  133. package/dist/src/group/types.gen.d.ts +2 -2
  134. package/dist/src/http/external.d.ts +2 -0
  135. package/dist/src/http/external.d.ts.map +1 -0
  136. package/dist/src/http/index.d.ts +2 -0
  137. package/dist/src/http/index.d.ts.map +1 -0
  138. package/dist/src/http/types.gen.d.ts +451 -0
  139. package/dist/src/http/types.gen.d.ts.map +1 -0
  140. package/dist/src/imex/client.d.ts +88 -0
  141. package/dist/src/imex/client.d.ts.map +1 -0
  142. package/dist/src/imex/index.d.ts +2 -0
  143. package/dist/src/imex/index.d.ts.map +1 -0
  144. package/dist/src/index.d.ts +18 -5
  145. package/dist/src/index.d.ts.map +1 -1
  146. package/dist/src/label/client.d.ts +55 -36
  147. package/dist/src/label/client.d.ts.map +1 -1
  148. package/dist/src/label/external.d.ts +2 -0
  149. package/dist/src/label/external.d.ts.map +1 -1
  150. package/dist/src/label/payload.d.ts +4 -46
  151. package/dist/src/label/payload.d.ts.map +1 -1
  152. package/dist/src/label/store.d.ts +8 -0
  153. package/dist/src/label/store.d.ts.map +1 -0
  154. package/dist/src/label/types.gen.d.ts +45 -0
  155. package/dist/src/label/types.gen.d.ts.map +1 -0
  156. package/dist/src/labjack/external.d.ts +2 -0
  157. package/dist/src/labjack/external.d.ts.map +1 -0
  158. package/dist/src/labjack/index.d.ts +2 -0
  159. package/dist/src/labjack/index.d.ts.map +1 -0
  160. package/dist/src/labjack/types.gen.d.ts +442 -0
  161. package/dist/src/labjack/types.gen.d.ts.map +1 -0
  162. package/dist/src/lineplot/actions.d.ts +914 -0
  163. package/dist/src/lineplot/actions.d.ts.map +1 -0
  164. package/dist/src/lineplot/actions.gen.d.ts +4208 -0
  165. package/dist/src/lineplot/actions.gen.d.ts.map +1 -0
  166. package/dist/src/lineplot/client.d.ts +66 -16
  167. package/dist/src/lineplot/client.d.ts.map +1 -1
  168. package/dist/src/lineplot/external.d.ts +3 -0
  169. package/dist/src/lineplot/external.d.ts.map +1 -1
  170. package/dist/src/lineplot/line.d.ts +16 -0
  171. package/dist/src/lineplot/line.d.ts.map +1 -0
  172. package/dist/src/lineplot/types.gen.d.ts +837 -14
  173. package/dist/src/lineplot/types.gen.d.ts.map +1 -1
  174. package/dist/src/log/actions.d.ts +271 -0
  175. package/dist/src/log/actions.d.ts.map +1 -0
  176. package/dist/src/log/actions.gen.d.ts +1529 -0
  177. package/dist/src/log/actions.gen.d.ts.map +1 -0
  178. package/dist/src/log/client.d.ts +66 -16
  179. package/dist/src/log/client.d.ts.map +1 -1
  180. package/dist/src/log/external.d.ts +2 -0
  181. package/dist/src/log/external.d.ts.map +1 -1
  182. package/dist/src/log/types.gen.d.ts +139 -14
  183. package/dist/src/log/types.gen.d.ts.map +1 -1
  184. package/dist/src/modbus/external.d.ts +2 -0
  185. package/dist/src/modbus/external.d.ts.map +1 -0
  186. package/dist/src/modbus/index.d.ts +2 -0
  187. package/dist/src/modbus/index.d.ts.map +1 -0
  188. package/dist/src/modbus/types.gen.d.ts +280 -0
  189. package/dist/src/modbus/types.gen.d.ts.map +1 -0
  190. package/dist/src/ni/external.d.ts +2 -0
  191. package/dist/src/ni/external.d.ts.map +1 -0
  192. package/dist/src/ni/index.d.ts +2 -0
  193. package/dist/src/ni/index.d.ts.map +1 -0
  194. package/dist/src/ni/types.gen.d.ts +21029 -0
  195. package/dist/src/ni/types.gen.d.ts.map +1 -0
  196. package/dist/src/node/index.d.ts +2 -0
  197. package/dist/src/node/index.d.ts.map +1 -0
  198. package/dist/src/node/types.gen.d.ts +4 -0
  199. package/dist/src/node/types.gen.d.ts.map +1 -0
  200. package/dist/src/ontology/client.d.ts +314 -67
  201. package/dist/src/ontology/client.d.ts.map +1 -1
  202. package/dist/src/ontology/external.d.ts +1 -0
  203. package/dist/src/ontology/external.d.ts.map +1 -1
  204. package/dist/src/ontology/payload.d.ts +60 -18
  205. package/dist/src/ontology/payload.d.ts.map +1 -1
  206. package/dist/src/ontology/store.d.ts +32 -0
  207. package/dist/src/ontology/store.d.ts.map +1 -0
  208. package/dist/src/ontology/types.gen.d.ts +3 -2
  209. package/dist/src/ontology/types.gen.d.ts.map +1 -1
  210. package/dist/src/ontology/writer.d.ts +16 -10
  211. package/dist/src/ontology/writer.d.ts.map +1 -1
  212. package/dist/src/opcua/external.d.ts +2 -0
  213. package/dist/src/opcua/external.d.ts.map +1 -0
  214. package/dist/src/opcua/index.d.ts +2 -0
  215. package/dist/src/opcua/index.d.ts.map +1 -0
  216. package/dist/src/opcua/types.gen.d.ts +82 -0
  217. package/dist/src/opcua/types.gen.d.ts.map +1 -0
  218. package/dist/src/pagerduty/external.d.ts +2 -0
  219. package/dist/src/pagerduty/external.d.ts.map +1 -0
  220. package/dist/src/pagerduty/index.d.ts +2 -0
  221. package/dist/src/pagerduty/index.d.ts.map +1 -0
  222. package/dist/src/pagerduty/types.gen.d.ts +30 -0
  223. package/dist/src/pagerduty/types.gen.d.ts.map +1 -0
  224. package/dist/src/panel/actions.d.ts +273 -0
  225. package/dist/src/panel/actions.d.ts.map +1 -0
  226. package/dist/src/panel/actions.gen.d.ts +1255 -0
  227. package/dist/src/panel/actions.gen.d.ts.map +1 -0
  228. package/dist/src/panel/client.d.ts +148 -0
  229. package/dist/src/panel/client.d.ts.map +1 -0
  230. package/dist/src/panel/external.d.ts +6 -0
  231. package/dist/src/panel/external.d.ts.map +1 -0
  232. package/dist/src/panel/index.d.ts +2 -0
  233. package/dist/src/panel/index.d.ts.map +1 -0
  234. package/dist/src/panel/tree.d.ts +50 -0
  235. package/dist/src/panel/tree.d.ts.map +1 -0
  236. package/dist/src/panel/types.gen.d.ts +370 -0
  237. package/dist/src/panel/types.gen.d.ts.map +1 -0
  238. package/dist/src/project/client.d.ts +89 -0
  239. package/dist/src/project/client.d.ts.map +1 -0
  240. package/dist/src/project/external.d.ts.map +1 -0
  241. package/dist/src/project/index.d.ts +2 -0
  242. package/dist/src/project/index.d.ts.map +1 -0
  243. package/dist/src/project/types.gen.d.ts +27 -0
  244. package/dist/src/project/types.gen.d.ts.map +1 -0
  245. package/dist/src/query/cache.d.ts +132 -0
  246. package/dist/src/query/cache.d.ts.map +1 -0
  247. package/dist/src/query/deleted.d.ts +20 -0
  248. package/dist/src/query/deleted.d.ts.map +1 -0
  249. package/dist/src/query/derived.d.ts +33 -0
  250. package/dist/src/query/derived.d.ts.map +1 -0
  251. package/dist/src/query/external.d.ts +10 -0
  252. package/dist/src/query/external.d.ts.map +1 -0
  253. package/dist/src/query/index.d.ts +2 -0
  254. package/dist/src/query/index.d.ts.map +1 -0
  255. package/dist/src/query/query.d.ts +235 -0
  256. package/dist/src/query/query.d.ts.map +1 -0
  257. package/dist/src/query/retriever.d.ts +135 -0
  258. package/dist/src/query/retriever.d.ts.map +1 -0
  259. package/dist/src/query/streamer.d.ts +67 -0
  260. package/dist/src/query/streamer.d.ts.map +1 -0
  261. package/dist/src/query/table.d.ts +219 -0
  262. package/dist/src/query/table.d.ts.map +1 -0
  263. package/dist/src/query/types.d.ts +35 -0
  264. package/dist/src/query/types.d.ts.map +1 -0
  265. package/dist/src/query/write.d.ts +21 -0
  266. package/dist/src/query/write.d.ts.map +1 -0
  267. package/dist/src/rack/client.d.ts +58 -20
  268. package/dist/src/rack/client.d.ts.map +1 -1
  269. package/dist/src/rack/types.gen.d.ts +11 -12
  270. package/dist/src/rack/types.gen.d.ts.map +1 -1
  271. package/dist/src/range/alias/types.gen.d.ts +2 -3
  272. package/dist/src/range/alias/types.gen.d.ts.map +1 -1
  273. package/dist/src/ranger/client.d.ts +138 -27
  274. package/dist/src/ranger/client.d.ts.map +1 -1
  275. package/dist/src/ranger/kv/client.d.ts +7 -4
  276. package/dist/src/ranger/kv/client.d.ts.map +1 -1
  277. package/dist/src/ranger/payload.d.ts +3 -0
  278. package/dist/src/ranger/payload.d.ts.map +1 -1
  279. package/dist/src/ranger/types.gen.d.ts +45 -101
  280. package/dist/src/ranger/types.gen.d.ts.map +1 -1
  281. package/dist/src/ranger/writer.d.ts +2 -74
  282. package/dist/src/ranger/writer.d.ts.map +1 -1
  283. package/dist/src/schematic/actions.d.ts +90 -33
  284. package/dist/src/schematic/actions.d.ts.map +1 -1
  285. package/dist/src/schematic/actions.gen.d.ts +207 -114
  286. package/dist/src/schematic/actions.gen.d.ts.map +1 -1
  287. package/dist/src/schematic/client.d.ts +70 -68
  288. package/dist/src/schematic/client.d.ts.map +1 -1
  289. package/dist/src/schematic/symbol/client.d.ts +133 -27
  290. package/dist/src/schematic/symbol/client.d.ts.map +1 -1
  291. package/dist/src/schematic/symbol/types.gen.d.ts +258 -153
  292. package/dist/src/schematic/symbol/types.gen.d.ts.map +1 -1
  293. package/dist/src/schematic/types.gen.d.ts +17 -96
  294. package/dist/src/schematic/types.gen.d.ts.map +1 -1
  295. package/dist/src/status/client.d.ts +69 -14
  296. package/dist/src/status/client.d.ts.map +1 -1
  297. package/dist/src/status/external.d.ts +2 -0
  298. package/dist/src/status/external.d.ts.map +1 -1
  299. package/dist/src/status/payload.d.ts +2 -36
  300. package/dist/src/status/payload.d.ts.map +1 -1
  301. package/dist/src/status/status.d.ts +65 -0
  302. package/dist/src/status/status.d.ts.map +1 -0
  303. package/dist/src/status/types.gen.d.ts +58 -0
  304. package/dist/src/status/types.gen.d.ts.map +1 -0
  305. package/dist/src/table/actions.d.ts +72 -13
  306. package/dist/src/table/actions.d.ts.map +1 -1
  307. package/dist/src/table/actions.gen.d.ts +221 -137
  308. package/dist/src/table/actions.gen.d.ts.map +1 -1
  309. package/dist/src/table/client.d.ts +64 -40
  310. package/dist/src/table/client.d.ts.map +1 -1
  311. package/dist/src/table/types.gen.d.ts +20 -55
  312. package/dist/src/table/types.gen.d.ts.map +1 -1
  313. package/dist/src/task/client.d.ts +149 -28
  314. package/dist/src/task/client.d.ts.map +1 -1
  315. package/dist/src/task/types.gen.d.ts +71 -89
  316. package/dist/src/task/types.gen.d.ts.map +1 -1
  317. package/dist/src/testutil/access.d.ts +27 -1
  318. package/dist/src/testutil/access.d.ts.map +1 -1
  319. package/dist/src/testutil/channels.d.ts +2 -0
  320. package/dist/src/testutil/channels.d.ts.map +1 -1
  321. package/dist/src/testutil/client.d.ts +5 -0
  322. package/dist/src/testutil/client.d.ts.map +1 -1
  323. package/dist/src/testutil/connection.d.ts +10 -0
  324. package/dist/src/testutil/connection.d.ts.map +1 -0
  325. package/dist/src/testutil/index.d.ts +9 -0
  326. package/dist/src/testutil/index.d.ts.map +1 -0
  327. package/dist/src/testutil/panels.d.ts +8 -0
  328. package/dist/src/testutil/panels.d.ts.map +1 -0
  329. package/dist/src/testutil/proxy.d.ts +29 -0
  330. package/dist/src/testutil/proxy.d.ts.map +1 -0
  331. package/dist/src/testutil/query.d.ts +7 -0
  332. package/dist/src/testutil/query.d.ts.map +1 -0
  333. package/dist/src/testutil/telem.d.ts +4 -0
  334. package/dist/src/testutil/telem.d.ts.map +1 -1
  335. package/dist/src/transport.d.ts +10 -4
  336. package/dist/src/transport.d.ts.map +1 -1
  337. package/dist/src/user/client.d.ts +29 -28
  338. package/dist/src/user/client.d.ts.map +1 -1
  339. package/dist/src/user/external.d.ts +1 -1
  340. package/dist/src/user/external.d.ts.map +1 -1
  341. package/dist/src/user/types.gen.d.ts +4 -4
  342. package/dist/src/util/retrieve.d.ts +2 -2
  343. package/dist/src/util/retrieve.d.ts.map +1 -1
  344. package/dist/src/util/telem.d.ts.map +1 -1
  345. package/dist/src/view/client.d.ts +30 -14
  346. package/dist/src/view/client.d.ts.map +1 -1
  347. package/dist/src/view/types.gen.d.ts +7 -15
  348. package/dist/src/view/types.gen.d.ts.map +1 -1
  349. package/dist/testutil.js +189 -0
  350. package/dist/testutil.js.map +1 -0
  351. package/package.json +39 -16
  352. package/src/access/client.ts +14 -3
  353. package/src/access/enforce.ts +0 -3
  354. package/src/access/external.ts +1 -0
  355. package/src/access/granted.ts +114 -0
  356. package/src/access/policy/client.ts +135 -43
  357. package/src/access/policy/types.gen.ts +9 -11
  358. package/src/access/role/client.ts +160 -38
  359. package/src/access/role/types.gen.ts +8 -12
  360. package/src/actions/actions.ts +5 -6
  361. package/src/actions/controller.ts +626 -0
  362. package/src/actions/external.ts +11 -0
  363. package/src/arc/actions.gen.ts +313 -0
  364. package/src/arc/actions.ts +192 -0
  365. package/src/arc/client.ts +424 -41
  366. package/src/arc/compiler/types.gen.ts +5 -6
  367. package/src/arc/external.ts +2 -0
  368. package/src/arc/graph/types.gen.ts +24 -22
  369. package/src/arc/ir/index.ts +1 -1
  370. package/{eslint.config.ts → src/arc/ir/ir.ts} +1 -4
  371. package/src/arc/ir/types.gen.ts +42 -41
  372. package/src/arc/text/types.gen.ts +21 -2
  373. package/src/arc/types/types.gen.ts +40 -32
  374. package/src/arc/types.gen.ts +31 -29
  375. package/src/auth/auth.ts +40 -8
  376. package/src/channel/client.ts +529 -132
  377. package/src/channel/external.ts +0 -1
  378. package/src/channel/payload.ts +30 -3
  379. package/src/channel/types.gen.ts +37 -48
  380. package/src/channel/writer.ts +2 -11
  381. package/src/client.ts +215 -91
  382. package/src/connection/client.ts +495 -0
  383. package/src/connection/external.ts +34 -0
  384. package/src/connection/index.ts +1 -1
  385. package/src/connection/status.ts +442 -0
  386. package/src/control/client.ts +84 -12
  387. package/src/control/state.ts +17 -36
  388. package/src/device/client.ts +293 -41
  389. package/src/device/types.gen.ts +15 -26
  390. package/src/errors.ts +45 -22
  391. package/src/{workspace → ethercat}/external.ts +1 -2
  392. package/src/{workspace → ethercat}/index.ts +1 -1
  393. package/src/ethercat/types.gen.ts +151 -0
  394. package/src/framer/adapter.ts +60 -37
  395. package/src/framer/benchutil.ts +67 -0
  396. package/src/framer/cache/cache.ts +115 -0
  397. package/src/framer/cache/dynamic.ts +340 -0
  398. package/src/framer/cache/reader.ts +231 -0
  399. package/src/framer/cache/static.ts +215 -0
  400. package/src/framer/cache/streamer.ts +391 -0
  401. package/src/framer/cache/transform.ts +31 -0
  402. package/src/framer/cache/unary.ts +108 -0
  403. package/src/framer/client.ts +71 -43
  404. package/src/framer/codec.ts +55 -18
  405. package/src/framer/deleter.ts +4 -6
  406. package/src/framer/external.ts +10 -0
  407. package/src/framer/feed.ts +108 -0
  408. package/src/framer/frame.ts +13 -23
  409. package/src/framer/hardened.ts +283 -0
  410. package/src/framer/iterator.ts +31 -42
  411. package/src/framer/reader.ts +11 -11
  412. package/src/framer/streamer.ts +18 -178
  413. package/src/framer/writer.ts +39 -59
  414. package/src/group/client.ts +158 -23
  415. package/src/http/external.ts +10 -0
  416. package/src/{cluster → http}/index.ts +1 -1
  417. package/src/http/types.gen.ts +245 -0
  418. package/src/imex/client.ts +125 -0
  419. package/src/imex/index.ts +10 -0
  420. package/src/index.ts +19 -6
  421. package/src/label/client.ts +193 -54
  422. package/src/label/external.ts +2 -0
  423. package/src/label/payload.ts +4 -9
  424. package/src/label/store.ts +28 -0
  425. package/src/label/types.gen.ts +31 -0
  426. package/src/labjack/external.ts +10 -0
  427. package/src/labjack/index.ts +10 -0
  428. package/src/labjack/types.gen.ts +251 -0
  429. package/src/lineplot/actions.gen.ts +880 -0
  430. package/src/lineplot/actions.ts +535 -0
  431. package/src/lineplot/client.ts +224 -52
  432. package/src/lineplot/external.ts +3 -0
  433. package/src/lineplot/line.ts +80 -0
  434. package/src/lineplot/types.gen.ts +225 -12
  435. package/src/log/actions.gen.ts +474 -0
  436. package/src/log/actions.ts +242 -0
  437. package/src/log/client.ts +223 -52
  438. package/src/log/external.ts +2 -0
  439. package/src/log/types.gen.ts +45 -14
  440. package/src/modbus/external.ts +10 -0
  441. package/src/modbus/index.ts +10 -0
  442. package/src/modbus/types.gen.ts +185 -0
  443. package/src/ni/external.ts +10 -0
  444. package/src/ni/index.ts +10 -0
  445. package/src/ni/types.gen.ts +1632 -0
  446. package/src/node/index.ts +10 -0
  447. package/src/{cluster → node}/types.gen.ts +2 -2
  448. package/src/ontology/client.ts +408 -99
  449. package/src/ontology/external.ts +7 -0
  450. package/src/ontology/payload.ts +48 -7
  451. package/src/ontology/store.ts +83 -0
  452. package/src/ontology/types.gen.ts +2 -1
  453. package/src/ontology/writer.ts +1 -0
  454. package/src/opcua/external.ts +10 -0
  455. package/src/opcua/index.ts +10 -0
  456. package/src/opcua/types.gen.ts +65 -0
  457. package/src/pagerduty/external.ts +10 -0
  458. package/src/pagerduty/index.ts +10 -0
  459. package/src/pagerduty/types.gen.ts +41 -0
  460. package/src/panel/actions.gen.ts +267 -0
  461. package/src/panel/actions.ts +357 -0
  462. package/src/panel/client.ts +327 -0
  463. package/src/panel/external.ts +14 -0
  464. package/src/panel/index.ts +10 -0
  465. package/src/panel/tree.ts +163 -0
  466. package/src/panel/types.gen.ts +164 -0
  467. package/src/project/client.ts +273 -0
  468. package/src/project/external.ts +11 -0
  469. package/src/project/index.ts +10 -0
  470. package/src/project/types.gen.ts +40 -0
  471. package/src/query/cache.ts +326 -0
  472. package/src/query/deleted.ts +38 -0
  473. package/src/query/derived.ts +101 -0
  474. package/src/query/external.ts +51 -0
  475. package/src/query/index.ts +10 -0
  476. package/src/query/query.ts +865 -0
  477. package/src/query/retriever.ts +308 -0
  478. package/src/query/streamer.ts +207 -0
  479. package/src/query/table.ts +625 -0
  480. package/src/query/types.ts +54 -0
  481. package/src/query/write.ts +42 -0
  482. package/src/rack/client.ts +233 -45
  483. package/src/rack/types.gen.ts +15 -16
  484. package/src/range/alias/types.gen.ts +2 -3
  485. package/src/ranger/client.ts +581 -70
  486. package/src/ranger/kv/client.ts +52 -21
  487. package/src/ranger/payload.ts +3 -0
  488. package/src/ranger/types.gen.ts +21 -23
  489. package/src/ranger/writer.ts +4 -8
  490. package/src/schematic/actions.gen.ts +62 -53
  491. package/src/schematic/actions.ts +44 -42
  492. package/src/schematic/client.ts +226 -70
  493. package/src/schematic/symbol/client.ts +277 -48
  494. package/src/schematic/symbol/types.gen.ts +22 -34
  495. package/src/schematic/types.gen.ts +22 -29
  496. package/src/status/client.ts +321 -44
  497. package/src/status/external.ts +2 -0
  498. package/src/status/payload.ts +1 -23
  499. package/src/status/status.ts +241 -0
  500. package/src/status/types.gen.ts +108 -0
  501. package/src/table/actions.gen.ts +96 -63
  502. package/src/table/actions.ts +44 -19
  503. package/src/table/client.ts +220 -56
  504. package/src/table/types.gen.ts +24 -31
  505. package/src/task/client.ts +580 -101
  506. package/src/task/types.gen.ts +68 -75
  507. package/src/testutil/access.ts +102 -6
  508. package/src/testutil/channels.ts +29 -0
  509. package/src/testutil/client.ts +27 -2
  510. package/src/testutil/connection.ts +47 -0
  511. package/src/testutil/index.ts +17 -0
  512. package/src/testutil/panels.ts +26 -0
  513. package/src/testutil/proxy.ts +106 -0
  514. package/src/testutil/query.ts +28 -0
  515. package/src/testutil/telem.ts +17 -1
  516. package/src/transport.ts +18 -7
  517. package/src/user/client.ts +165 -64
  518. package/src/user/external.ts +1 -1
  519. package/src/user/types.gen.ts +5 -5
  520. package/src/util/retrieve.ts +4 -4
  521. package/src/util/telem.ts +0 -1
  522. package/src/view/client.ts +120 -37
  523. package/src/view/types.gen.ts +8 -11
  524. package/.turbo/turbo-build.log +0 -20
  525. package/.vscode/settings.json +0 -3
  526. package/CONTRIBUTING.md +0 -47
  527. package/dist/client.cjs +0 -118
  528. package/dist/eslint.config.d.ts +0 -4
  529. package/dist/eslint.config.d.ts.map +0 -1
  530. package/dist/src/access/enforce.spec.d.ts +0 -2
  531. package/dist/src/access/enforce.spec.d.ts.map +0 -1
  532. package/dist/src/access/policy/access.spec.d.ts +0 -2
  533. package/dist/src/access/policy/access.spec.d.ts.map +0 -1
  534. package/dist/src/access/role/role.spec.d.ts +0 -2
  535. package/dist/src/access/role/role.spec.d.ts.map +0 -1
  536. package/dist/src/actions/actions.spec.d.ts +0 -2
  537. package/dist/src/actions/actions.spec.d.ts.map +0 -1
  538. package/dist/src/arc/access.spec.d.ts +0 -2
  539. package/dist/src/arc/access.spec.d.ts.map +0 -1
  540. package/dist/src/arc/arc.spec.d.ts +0 -2
  541. package/dist/src/arc/arc.spec.d.ts.map +0 -1
  542. package/dist/src/arc/lsp.spec.d.ts +0 -2
  543. package/dist/src/arc/lsp.spec.d.ts.map +0 -1
  544. package/dist/src/auth/auth.spec.d.ts +0 -2
  545. package/dist/src/auth/auth.spec.d.ts.map +0 -1
  546. package/dist/src/channel/access.spec.d.ts +0 -2
  547. package/dist/src/channel/access.spec.d.ts.map +0 -1
  548. package/dist/src/channel/batchRetriever.spec.d.ts +0 -2
  549. package/dist/src/channel/batchRetriever.spec.d.ts.map +0 -1
  550. package/dist/src/channel/channel.spec.d.ts +0 -2
  551. package/dist/src/channel/channel.spec.d.ts.map +0 -1
  552. package/dist/src/channel/payload.spec.d.ts +0 -2
  553. package/dist/src/channel/payload.spec.d.ts.map +0 -1
  554. package/dist/src/channel/retriever.d.ts +0 -64
  555. package/dist/src/channel/retriever.d.ts.map +0 -1
  556. package/dist/src/cluster/index.d.ts +0 -2
  557. package/dist/src/cluster/index.d.ts.map +0 -1
  558. package/dist/src/cluster/types.gen.d.ts +0 -4
  559. package/dist/src/cluster/types.gen.d.ts.map +0 -1
  560. package/dist/src/connection/checker.d.ts +0 -86
  561. package/dist/src/connection/checker.d.ts.map +0 -1
  562. package/dist/src/connection/connection.spec.d.ts +0 -2
  563. package/dist/src/connection/connection.spec.d.ts.map +0 -1
  564. package/dist/src/connection.spec.d.ts +0 -2
  565. package/dist/src/connection.spec.d.ts.map +0 -1
  566. package/dist/src/control/state.spec.d.ts +0 -2
  567. package/dist/src/control/state.spec.d.ts.map +0 -1
  568. package/dist/src/device/access.spec.d.ts +0 -2
  569. package/dist/src/device/access.spec.d.ts.map +0 -1
  570. package/dist/src/device/device.spec.d.ts +0 -2
  571. package/dist/src/device/device.spec.d.ts.map +0 -1
  572. package/dist/src/device/payload.spec.d.ts +0 -2
  573. package/dist/src/device/payload.spec.d.ts.map +0 -1
  574. package/dist/src/errors.spec.d.ts +0 -2
  575. package/dist/src/errors.spec.d.ts.map +0 -1
  576. package/dist/src/framer/adapter.spec.d.ts +0 -2
  577. package/dist/src/framer/adapter.spec.d.ts.map +0 -1
  578. package/dist/src/framer/client.spec.d.ts +0 -2
  579. package/dist/src/framer/client.spec.d.ts.map +0 -1
  580. package/dist/src/framer/codec.spec.d.ts +0 -2
  581. package/dist/src/framer/codec.spec.d.ts.map +0 -1
  582. package/dist/src/framer/deleter.spec.d.ts +0 -2
  583. package/dist/src/framer/deleter.spec.d.ts.map +0 -1
  584. package/dist/src/framer/frame.spec.d.ts +0 -2
  585. package/dist/src/framer/frame.spec.d.ts.map +0 -1
  586. package/dist/src/framer/iterator.spec.d.ts +0 -2
  587. package/dist/src/framer/iterator.spec.d.ts.map +0 -1
  588. package/dist/src/framer/reader.spec.d.ts +0 -2
  589. package/dist/src/framer/reader.spec.d.ts.map +0 -1
  590. package/dist/src/framer/streamer.spec.d.ts +0 -2
  591. package/dist/src/framer/streamer.spec.d.ts.map +0 -1
  592. package/dist/src/framer/writer.spec.d.ts +0 -2
  593. package/dist/src/framer/writer.spec.d.ts.map +0 -1
  594. package/dist/src/group/access.spec.d.ts +0 -2
  595. package/dist/src/group/access.spec.d.ts.map +0 -1
  596. package/dist/src/group/group.spec.d.ts +0 -2
  597. package/dist/src/group/group.spec.d.ts.map +0 -1
  598. package/dist/src/label/access.spec.d.ts +0 -2
  599. package/dist/src/label/access.spec.d.ts.map +0 -1
  600. package/dist/src/label/label.spec.d.ts +0 -2
  601. package/dist/src/label/label.spec.d.ts.map +0 -1
  602. package/dist/src/lineplot/access.spec.d.ts +0 -2
  603. package/dist/src/lineplot/access.spec.d.ts.map +0 -1
  604. package/dist/src/lineplot/lineplot.spec.d.ts +0 -2
  605. package/dist/src/lineplot/lineplot.spec.d.ts.map +0 -1
  606. package/dist/src/log/access.spec.d.ts +0 -2
  607. package/dist/src/log/access.spec.d.ts.map +0 -1
  608. package/dist/src/log/log.spec.d.ts +0 -2
  609. package/dist/src/log/log.spec.d.ts.map +0 -1
  610. package/dist/src/ontology/ontology.spec.d.ts +0 -2
  611. package/dist/src/ontology/ontology.spec.d.ts.map +0 -1
  612. package/dist/src/rack/access.spec.d.ts +0 -2
  613. package/dist/src/rack/access.spec.d.ts.map +0 -1
  614. package/dist/src/rack/rack.spec.d.ts +0 -2
  615. package/dist/src/rack/rack.spec.d.ts.map +0 -1
  616. package/dist/src/ranger/access.spec.d.ts +0 -2
  617. package/dist/src/ranger/access.spec.d.ts.map +0 -1
  618. package/dist/src/ranger/alias/payload.spec.d.ts +0 -2
  619. package/dist/src/ranger/alias/payload.spec.d.ts.map +0 -1
  620. package/dist/src/ranger/ranger.spec.d.ts +0 -2
  621. package/dist/src/ranger/ranger.spec.d.ts.map +0 -1
  622. package/dist/src/schematic/access.spec.d.ts +0 -2
  623. package/dist/src/schematic/access.spec.d.ts.map +0 -1
  624. package/dist/src/schematic/actions.spec.d.ts +0 -2
  625. package/dist/src/schematic/actions.spec.d.ts.map +0 -1
  626. package/dist/src/schematic/schematic.spec.d.ts +0 -2
  627. package/dist/src/schematic/schematic.spec.d.ts.map +0 -1
  628. package/dist/src/schematic/symbol/access.spec.d.ts +0 -2
  629. package/dist/src/schematic/symbol/access.spec.d.ts.map +0 -1
  630. package/dist/src/schematic/symbol/client.spec.d.ts +0 -2
  631. package/dist/src/schematic/symbol/client.spec.d.ts.map +0 -1
  632. package/dist/src/status/access.spec.d.ts +0 -2
  633. package/dist/src/status/access.spec.d.ts.map +0 -1
  634. package/dist/src/status/status.spec.d.ts +0 -2
  635. package/dist/src/status/status.spec.d.ts.map +0 -1
  636. package/dist/src/table/access.spec.d.ts +0 -2
  637. package/dist/src/table/access.spec.d.ts.map +0 -1
  638. package/dist/src/table/table.spec.d.ts +0 -2
  639. package/dist/src/table/table.spec.d.ts.map +0 -1
  640. package/dist/src/task/access.spec.d.ts +0 -2
  641. package/dist/src/task/access.spec.d.ts.map +0 -1
  642. package/dist/src/task/payload.spec.d.ts +0 -2
  643. package/dist/src/task/payload.spec.d.ts.map +0 -1
  644. package/dist/src/task/task.spec.d.ts +0 -2
  645. package/dist/src/task/task.spec.d.ts.map +0 -1
  646. package/dist/src/user/access.spec.d.ts +0 -2
  647. package/dist/src/user/access.spec.d.ts.map +0 -1
  648. package/dist/src/user/user.spec.d.ts +0 -2
  649. package/dist/src/user/user.spec.d.ts.map +0 -1
  650. package/dist/src/util/retrieve.spec.d.ts +0 -2
  651. package/dist/src/util/retrieve.spec.d.ts.map +0 -1
  652. package/dist/src/view/view.spec.d.ts +0 -2
  653. package/dist/src/view/view.spec.d.ts.map +0 -1
  654. package/dist/src/workspace/access.spec.d.ts +0 -2
  655. package/dist/src/workspace/access.spec.d.ts.map +0 -1
  656. package/dist/src/workspace/client.d.ts +0 -36
  657. package/dist/src/workspace/client.d.ts.map +0 -1
  658. package/dist/src/workspace/external.d.ts.map +0 -1
  659. package/dist/src/workspace/index.d.ts +0 -2
  660. package/dist/src/workspace/index.d.ts.map +0 -1
  661. package/dist/src/workspace/types.gen.d.ts +0 -34
  662. package/dist/src/workspace/types.gen.d.ts.map +0 -1
  663. package/dist/src/workspace/workspace.spec.d.ts +0 -2
  664. package/dist/src/workspace/workspace.spec.d.ts.map +0 -1
  665. package/examples/node/basicReadWrite.js +0 -86
  666. package/examples/node/createChannels.js +0 -50
  667. package/examples/node/createRange.js +0 -67
  668. package/examples/node/package-lock.json +0 -133
  669. package/examples/node/package.json +0 -17
  670. package/examples/node/readLatest.js +0 -76
  671. package/examples/node/seriesAndFrames.js +0 -173
  672. package/examples/node/streamRead.js +0 -50
  673. package/examples/node/streamWrite.js +0 -87
  674. package/src/access/enforce.spec.ts +0 -188
  675. package/src/access/policy/access.spec.ts +0 -147
  676. package/src/access/role/role.spec.ts +0 -95
  677. package/src/actions/actions.spec.ts +0 -229
  678. package/src/arc/access.spec.ts +0 -149
  679. package/src/arc/arc.spec.ts +0 -44
  680. package/src/arc/lsp.spec.ts +0 -717
  681. package/src/auth/auth.spec.ts +0 -101
  682. package/src/channel/access.spec.ts +0 -116
  683. package/src/channel/batchRetriever.spec.ts +0 -115
  684. package/src/channel/channel.spec.ts +0 -352
  685. package/src/channel/payload.spec.ts +0 -117
  686. package/src/channel/retriever.ts +0 -252
  687. package/src/connection/checker.ts +0 -203
  688. package/src/connection/connection.spec.ts +0 -152
  689. package/src/connection.spec.ts +0 -145
  690. package/src/control/state.spec.ts +0 -22
  691. package/src/device/access.spec.ts +0 -159
  692. package/src/device/device.spec.ts +0 -461
  693. package/src/device/payload.spec.ts +0 -142
  694. package/src/errors.spec.ts +0 -71
  695. package/src/framer/adapter.spec.ts +0 -620
  696. package/src/framer/client.spec.ts +0 -180
  697. package/src/framer/codec.spec.ts +0 -383
  698. package/src/framer/deleter.spec.ts +0 -103
  699. package/src/framer/frame.spec.ts +0 -973
  700. package/src/framer/iterator.spec.ts +0 -169
  701. package/src/framer/reader.spec.ts +0 -865
  702. package/src/framer/streamer.spec.ts +0 -871
  703. package/src/framer/writer.spec.ts +0 -486
  704. package/src/group/access.spec.ts +0 -77
  705. package/src/group/group.spec.ts +0 -65
  706. package/src/label/access.spec.ts +0 -109
  707. package/src/label/label.spec.ts +0 -83
  708. package/src/lineplot/access.spec.ts +0 -134
  709. package/src/lineplot/lineplot.spec.ts +0 -120
  710. package/src/log/access.spec.ts +0 -132
  711. package/src/log/log.spec.ts +0 -106
  712. package/src/ontology/ontology.spec.ts +0 -521
  713. package/src/rack/access.spec.ts +0 -102
  714. package/src/rack/rack.spec.ts +0 -171
  715. package/src/ranger/access.spec.ts +0 -115
  716. package/src/ranger/alias/payload.spec.ts +0 -52
  717. package/src/ranger/ranger.spec.ts +0 -343
  718. package/src/schematic/access.spec.ts +0 -134
  719. package/src/schematic/actions.spec.ts +0 -699
  720. package/src/schematic/schematic.spec.ts +0 -340
  721. package/src/schematic/symbol/access.spec.ts +0 -172
  722. package/src/schematic/symbol/client.spec.ts +0 -160
  723. package/src/status/access.spec.ts +0 -129
  724. package/src/status/status.spec.ts +0 -448
  725. package/src/table/access.spec.ts +0 -128
  726. package/src/table/table.spec.ts +0 -651
  727. package/src/task/access.spec.ts +0 -131
  728. package/src/task/payload.spec.ts +0 -113
  729. package/src/task/task.spec.ts +0 -657
  730. package/src/user/access.spec.ts +0 -107
  731. package/src/user/user.spec.ts +0 -290
  732. package/src/util/retrieve.spec.ts +0 -49
  733. package/src/view/view.spec.ts +0 -165
  734. package/src/workspace/access.spec.ts +0 -108
  735. package/src/workspace/client.ts +0 -112
  736. package/src/workspace/types.gen.ts +0 -46
  737. package/src/workspace/workspace.spec.ts +0 -111
  738. package/tsconfig.json +0 -5
  739. package/tsconfig.vite.json +0 -4
  740. package/vite.config.ts +0 -29
  741. /package/dist/src/{workspace → project}/external.d.ts +0 -0
@@ -9,6 +9,7 @@
9
9
 
10
10
  // Code generated by Oracle. DO NOT EDIT.
11
11
 
12
+ import { uuid } from "@synnaxlabs/x";
12
13
  import { z } from "zod";
13
14
 
14
15
  import { ontology } from "@/ontology";
@@ -18,29 +19,24 @@ export type Key = z.infer<typeof keyZ>;
18
19
 
19
20
  /**
20
21
  * Role is a named collection of policies that can be assigned to users, enabling
21
- * group-based permission management. Roles define what actions users can
22
- * perform on resources.
22
+ * group-based permission management. Roles define what actions users can perform on
23
+ * resources.
23
24
  */
24
25
  export const roleZ = z.object({
25
26
  /** key is the unique identifier for this role. */
26
- key: keyZ,
27
- /**
28
- * name is a human-readable name for the role (e.g., 'Administrator',
29
- * 'Engineer').
30
- */
27
+ key: keyZ.default(uuid.create),
28
+ /** name is a human-readable name for the role (e.g., 'Administrator', 'Engineer'). */
31
29
  name: z.string(),
32
30
  /**
33
31
  * description is an optional description explaining what permissions the role
34
32
  * provides.
35
33
  */
36
- description: z.string().optional(),
34
+ description: z.string().default(""),
37
35
  /** internal is true if this is a built-in system role that cannot be deleted. */
38
- internal: z.boolean().optional(),
36
+ internal: z.boolean().default(false),
39
37
  });
40
38
  export interface Role extends z.infer<typeof roleZ> {}
41
-
42
- export const newZ = roleZ.partial({ key: true });
43
- export interface New extends z.input<typeof newZ> {}
39
+ export interface New extends z.input<typeof roleZ> {}
44
40
 
45
41
  export const ontologyID = ontology.createIDFactory<Key>("role");
46
42
  export const TYPE_ONTOLOGY_ID = ontologyID("");
@@ -40,12 +40,11 @@ export interface ReduceAllResult<S, A> {
40
40
  }
41
41
 
42
42
  /**
43
- * Returns a plain-object snapshot of an Immer draft so the result is safe to
44
- * embed in an action stored on the undo stack. Returns non-draft inputs
45
- * unchanged. The non-draft passthrough exists because when a reducer applies
46
- * multiple actions in one produce(), an earlier action's wholesale
47
- * assignment leaves the slot as a plain object, so the next action would
48
- * crash if it called `current` unconditionally.
43
+ * Returns a plain-object snapshot of an Immer draft so the result is safe to embed in
44
+ * an action stored on the undo stack. Returns non-draft inputs unchanged. The non-draft
45
+ * passthrough exists because when a reducer applies multiple actions in one produce(),
46
+ * an earlier action's wholesale assignment leaves the slot as a plain object, so the
47
+ * next action would crash if it called `current` unconditionally.
49
48
  */
50
49
  export const snapshotDraft = <T>(v: T): T => (isDraft(v) ? current(v as Draft<T>) : v);
51
50
 
@@ -0,0 +1,626 @@
1
+ // Copyright 2026 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
10
+ import {
11
+ compare,
12
+ destructor,
13
+ errors,
14
+ id,
15
+ type record,
16
+ TimeSpan,
17
+ TimeStamp,
18
+ } from "@synnaxlabs/x";
19
+ import type z from "zod";
20
+
21
+ import { type query } from "@/query";
22
+ import { Table } from "@/query/table";
23
+
24
+ const DEFAULT_COALESCE_WINDOW = TimeSpan.milliseconds(500);
25
+ const DEFAULT_STACK_CAP = 200;
26
+ const STALE_AUTO_ADVANCE_CAP = 10;
27
+
28
+ export interface StackEntry<Action> {
29
+ forward: Action[];
30
+ inverse: Action[];
31
+ kind: string;
32
+ /** Wall-clock push time, used only for coalescing. */
33
+ ts: TimeStamp;
34
+ /** Tick of the earliest push, used to order the entry against remote touches. */
35
+ tick: number;
36
+ targets: readonly string[];
37
+ }
38
+
39
+ interface UndoState<Action> {
40
+ undo: StackEntry<Action>[];
41
+ redo: StackEntry<Action>[];
42
+ remoteTouched: Record<string, number>;
43
+ }
44
+
45
+ const ZERO_UNDO = <A>(): UndoState<A> => ({ undo: [], redo: [], remoteTouched: {} });
46
+
47
+ const pushOnto = <A>(
48
+ stack: StackEntry<A>[],
49
+ next: StackEntry<A>,
50
+ window: TimeSpan,
51
+ cap: number,
52
+ ): StackEntry<A>[] => {
53
+ const top = stack[stack.length - 1];
54
+ const merged =
55
+ top != null &&
56
+ top.kind === next.kind &&
57
+ next.ts.span(top.ts).lessThanOrEqual(window) &&
58
+ compare.unorderedPrimitiveArrays(top.targets, next.targets) === compare.EQUAL
59
+ ? {
60
+ forward: [...top.forward, ...next.forward],
61
+ inverse: [...next.inverse, ...top.inverse],
62
+ kind: next.kind,
63
+ ts: next.ts,
64
+ tick: top.tick,
65
+ targets: top.targets,
66
+ }
67
+ : null;
68
+ const out = merged != null ? [...stack.slice(0, -1), merged] : [...stack, next];
69
+ return out.length > cap ? out.slice(out.length - cap) : out;
70
+ };
71
+
72
+ export interface Reducer<State extends query.Data, Action> {
73
+ (
74
+ state: State,
75
+ actions: Action[],
76
+ ): { next: State; inverse: Action[]; targets: readonly string[] };
77
+ }
78
+
79
+ /** Result of replaying a set of actions locally. The caller commits the
80
+ * matching server send and runs `rollback` on failure. */
81
+ export interface ReplayResult<Action> {
82
+ processed: Action[];
83
+ inverse: Action[];
84
+ targets: readonly string[];
85
+ // changed reports whether the replay produced a different state. Reducers
86
+ // return the input state by reference when no action touched it, so a false
87
+ // value means the entire vector was a no-op and need not reach the server.
88
+ changed: boolean;
89
+ rollback: destructor.Destructor;
90
+ }
91
+
92
+ /** Result of preparing to undo or redo. The caller applies `actions` and runs
93
+ * `commit` on success (which itself returns a destructor for failure-rollback). */
94
+ export interface Reversal<Action> {
95
+ actions: Action[];
96
+ commit: () => destructor.Destructor;
97
+ }
98
+
99
+ /**
100
+ * A staged set of dispatches committed atomically as one undoable. Commit
101
+ * resolves false when there is nothing to send; a send failure rolls back the
102
+ * staged state and rethrows.
103
+ */
104
+ export interface Transaction<Action> {
105
+ add: (actions: Action | Action[]) => void;
106
+ commit: () => Promise<boolean>;
107
+ abort: () => void;
108
+ }
109
+
110
+ /** Sends an already-processed action list to the server. Supplied by the
111
+ * caller so the controller stays free of network concerns. */
112
+ export type Send<Action> = (actions: Action[]) => Promise<void>;
113
+
114
+ /**
115
+ * Network send used by the dispatch/undo/redo loops. Receives the
116
+ * controller-generated dispatch key that was registered as outstanding before
117
+ * the call, so the broadcast echo is recognized as own.
118
+ */
119
+ export type SendDispatch<Action> = (
120
+ actions: Action[],
121
+ dispatchKey: string,
122
+ ) => Promise<void>;
123
+
124
+ /** Rewrites an action batch against the current document before replay. */
125
+ export type Preprocess<State, Action> = (state: State, actions: Action[]) => Action[];
126
+
127
+ /** Options accepted by domain-client dispatch methods. */
128
+ export interface Options<State, Action> {
129
+ /**
130
+ * Per-call action rewrite requiring caller context the domain client lacks
131
+ * (e.g. diagram geometry). Runs against the cached doc before replay.
132
+ */
133
+ preprocess?: Preprocess<State, Action>;
134
+ }
135
+
136
+ /** The action-dispatch surface a document domain client exposes. */
137
+ export interface Domain<Key extends record.Key, State extends query.Data, Action> {
138
+ dispatch(
139
+ key: Key,
140
+ actions: Action | Action[],
141
+ opts?: Options<State, Action>,
142
+ ): Promise<boolean>;
143
+ undo(key: Key): Promise<boolean>;
144
+ redo(key: Key): Promise<boolean>;
145
+ hasUndo(key: Key): boolean;
146
+ hasRedo(key: Key): boolean;
147
+ onUndoStateChange(callback: () => void, key?: Key): destructor.Destructor;
148
+ beginTransaction(key: Key, kind?: string): Transaction<Action>;
149
+ }
150
+
151
+ /**
152
+ * The canonical wire shape for a broadcast action frame. The consumer's `schema` must
153
+ * produce this shape (use a zod transform if the server emits differently-named
154
+ * fields). `seq` is a per-key monotonic sequence stamped by the originating server node
155
+ * and is used to skip echoes that are stale relative to the high-water mark — see
156
+ * `applyRemote`. `dispatchKey` is the client-generated batch identifier the originator
157
+ * registered as outstanding before sending; it is used to recognize own echoes
158
+ * race-safely so a redundant reduce can be skipped when no foreign action interleaved.
159
+ */
160
+ export interface Frame<Key, Action> {
161
+ key: Key;
162
+ dispatchKey: string;
163
+ seq: number;
164
+ actions: Action[];
165
+ }
166
+
167
+ export interface ControllerParams<
168
+ Key extends record.Key,
169
+ State extends query.Data,
170
+ Action,
171
+ > {
172
+ /** The table holding the documents this controller dispatches over. */
173
+ store: Table<Key, State>;
174
+ /** Reports listener errors that have no caller to throw to. */
175
+ onError: (error: Error) => void;
176
+ reduce: Reducer<State, Action>;
177
+ preprocess?: (state: State, actions: Action[]) => Action[];
178
+ isUndoable?: (action: Action) => boolean;
179
+ kindOf?: (actions: Action[]) => string;
180
+ /**
181
+ * Returns the document carried by a create action, undefined otherwise.
182
+ * Lets remote frames for never-cached documents ingest instead of drop.
183
+ */
184
+ createOf?: (action: Action) => State | undefined;
185
+ coalesceWindow?: TimeSpan;
186
+ stackCap?: number;
187
+ /** Clock stamping entries for the coalesce window. Defaults to TimeStamp.now. */
188
+ now?: () => TimeStamp;
189
+ }
190
+
191
+ /**
192
+ * Owns the action-dispatch loop for one document table: local replay with
193
+ * rollback, per-doc undo/redo stacks, echo recognition, and remote-frame
194
+ * application. Operates on a plain cache table; all dispatch bookkeeping is
195
+ * session-local and dropped when a document's row is deleted (tombstoned).
196
+ */
197
+ export class Controller<Key extends record.Key, State extends query.Data, Action> {
198
+ private readonly docs: Table<Key, State>;
199
+ private readonly undos: Table<Key, UndoState<Action>>;
200
+ private readonly params: Required<
201
+ Omit<ControllerParams<Key, State, Action>, "store">
202
+ >;
203
+ // lastAppliedSeq tracks the highest broadcast sequence number applied for each key.
204
+ // Echoes whose seq does not exceed this are stale (a fresher value already overwrote
205
+ // them on the server) and are dropped. A seq of 0 is treated as "unstamped" and
206
+ // always applies — that covers frames from servers that predate the field.
207
+ private readonly lastAppliedSeq = new Map<Key, number>();
208
+ // outstandingDispatches tracks per-key dispatches the originator has applied locally
209
+ // via replay but whose broadcast echo has not yet arrived. Each entry's `disturbed`
210
+ // flag is flipped to true when a foreign echo lands during the outstanding window; on
211
+ // own-echo arrival, an entry that is not disturbed skips the reduce (the local replay
212
+ // was authoritative) and an entry that is disturbed re-runs to recover from the
213
+ // foreign overwrite.
214
+ private readonly outstandingDispatches = new Map<
215
+ Key,
216
+ Map<string, { disturbed: boolean }>
217
+ >();
218
+ // Monotonic counter ordering entry pushes against remote touches. Program
219
+ // order is the ground truth here; the wall clock ties within a millisecond
220
+ // and steps on sleep/wake or NTP resync, so it cannot be trusted for this.
221
+ private tick = 0;
222
+
223
+ constructor(opts: ControllerParams<Key, State, Action>) {
224
+ this.params = {
225
+ onError: opts.onError,
226
+ reduce: opts.reduce,
227
+ preprocess: opts.preprocess ?? ((_, a) => a),
228
+ isUndoable: opts.isUndoable ?? (() => true),
229
+ kindOf: opts.kindOf ?? (() => "default"),
230
+ createOf: opts.createOf ?? (() => undefined),
231
+ coalesceWindow: opts.coalesceWindow ?? DEFAULT_COALESCE_WINDOW,
232
+ stackCap: opts.stackCap ?? DEFAULT_STACK_CAP,
233
+ now: opts.now ?? (() => TimeStamp.now()),
234
+ };
235
+ this.docs = opts.store;
236
+ // Undo states are rebuilt objects on every update; comparing them would
237
+ // be pure waste, so equality is disabled.
238
+ this.undos = new Table<Key, UndoState<Action>>({
239
+ onError: this.params.onError,
240
+ equal: () => false,
241
+ });
242
+ // Stacks are session-local: when a document is deleted (tombstoned), its
243
+ // dispatch bookkeeping goes with it.
244
+ this.docs.subscribe((event) => {
245
+ if (event.variant === "delete") this.drop(event.key);
246
+ });
247
+ }
248
+
249
+ private drop(key: Key): void {
250
+ this.undos.delete(key);
251
+ this.lastAppliedSeq.delete(key);
252
+ this.outstandingDispatches.delete(key);
253
+ }
254
+
255
+ private updateUndo(
256
+ key: Key,
257
+ fn: (s: UndoState<Action>) => UndoState<Action>,
258
+ ): destructor.Destructor {
259
+ return this.undos.set(key, (prev) => fn(prev ?? ZERO_UNDO<Action>()));
260
+ }
261
+
262
+ /**
263
+ * Run preprocess + reduce against the cached doc and write the result.
264
+ * Returns the reducer output and a rollback that restores the prior doc
265
+ * state. Returns null if the doc isn't cached.
266
+ */
267
+ replay(
268
+ key: Key,
269
+ actions: Action[],
270
+ opts: { skipPreprocess?: boolean } = {},
271
+ ): ReplayResult<Action> | null {
272
+ const current = this.docs.get(key);
273
+ if (current == null) return null;
274
+ const processed = opts.skipPreprocess
275
+ ? actions
276
+ : this.params.preprocess(current, actions);
277
+ const { next, inverse, targets } = this.params.reduce(current, processed);
278
+ return {
279
+ processed,
280
+ inverse,
281
+ targets,
282
+ changed: next !== current,
283
+ rollback: this.docs.set(key, next),
284
+ };
285
+ }
286
+
287
+ /**
288
+ * Append an undoable entry to the stack. Filters non-undoable actions,
289
+ * derives the kind, and coalesces with the prior entry if it falls within
290
+ * the configured window with matching kind/targets. Clears redo.
291
+ */
292
+ recordEntry(
293
+ key: Key,
294
+ forward: Action[],
295
+ inverse: Action[],
296
+ targets: readonly string[],
297
+ kindOverride?: string,
298
+ ): destructor.Destructor {
299
+ if (targets.length === 0) return destructor.NOOP;
300
+ const undoableForward = forward.filter(this.params.isUndoable);
301
+ if (undoableForward.length === 0) return destructor.NOOP;
302
+ const entry: StackEntry<Action> = {
303
+ forward: undoableForward,
304
+ inverse,
305
+ kind: kindOverride ?? this.params.kindOf(forward),
306
+ ts: this.params.now(),
307
+ tick: ++this.tick,
308
+ targets,
309
+ };
310
+ return this.updateUndo(key, (s) => ({
311
+ ...s,
312
+ undo: pushOnto(s.undo, entry, this.params.coalesceWindow, this.params.stackCap),
313
+ redo: [],
314
+ }));
315
+ }
316
+
317
+ // Walks the chosen stack from the top, skipping entries whose targets were
318
+ // remote-touched after the entry was pushed. Caps the walk at
319
+ // STALE_AUTO_ADVANCE_CAP and drops a fully stale tail. On hit, returns the
320
+ // entry's reversal actions (inverse for undo, forward for redo) and a
321
+ // commit that moves the entry to the opposite stack.
322
+ private prepareReversal(key: Key, side: "undo" | "redo"): Reversal<Action> | null {
323
+ const state = this.undos.get(key);
324
+ if (state == null) return null;
325
+ const stack = state[side];
326
+ if (stack.length === 0) return null;
327
+ let stale = 0;
328
+ let idx = -1;
329
+ for (let i = stack.length - 1; i >= 0; i--) {
330
+ const e = stack[i];
331
+ if (e.targets.some((t) => (state.remoteTouched[t] ?? 0) > e.tick)) {
332
+ stale++;
333
+ if (stale >= STALE_AUTO_ADVANCE_CAP) break;
334
+ } else {
335
+ idx = i;
336
+ break;
337
+ }
338
+ }
339
+ if (idx === -1) {
340
+ if (stale > 0)
341
+ this.updateUndo(key, (s) => ({
342
+ ...s,
343
+ [side]: s[side].slice(0, s[side].length - stale),
344
+ }));
345
+ return null;
346
+ }
347
+ const entry = stack[idx];
348
+ const other = side === "undo" ? "redo" : "undo";
349
+ return {
350
+ actions: side === "undo" ? entry.inverse : entry.forward,
351
+ commit: () =>
352
+ this.updateUndo(key, (s) => ({
353
+ ...s,
354
+ [side]: s[side].slice(0, idx),
355
+ [other]: [...s[other], entry],
356
+ })),
357
+ };
358
+ }
359
+
360
+ // Reduce + send with rollback: replay locally, run the per-op stack
361
+ // mutation, register the batch as outstanding *before* the network send
362
+ // (the broadcast echo can race the HTTP response), and roll back stack and
363
+ // state when the send fails. Returns false when the doc isn't cached.
364
+ private async applySend(
365
+ key: Key,
366
+ actions: Action[],
367
+ commitStack: (r: ReplayResult<Action>) => destructor.Destructor,
368
+ send: SendDispatch<Action>,
369
+ preprocess?: Preprocess<State, Action>,
370
+ ): Promise<boolean> {
371
+ const current = this.docs.get(key);
372
+ if (current == null) return false;
373
+ const processed = preprocess == null ? actions : preprocess(current, actions);
374
+ const r = this.replay(key, processed, { skipPreprocess: true });
375
+ if (r == null) return false;
376
+ const stackRollback = commitStack(r);
377
+ // A replay that left the state untouched has nothing for the server: no
378
+ // document change, no broadcast worth echoing. The stack mutation still
379
+ // runs above so undo/redo consume their entry instead of pinning it.
380
+ if (!r.changed) return true;
381
+ const dispatchKey = id.create();
382
+ this.registerOutstandingDispatch(key, dispatchKey);
383
+ try {
384
+ await send(r.processed, dispatchKey);
385
+ return true;
386
+ } catch (e) {
387
+ stackRollback();
388
+ r.rollback();
389
+ throw errors.fromUnknown(e);
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Apply an action batch to the cached doc and send it to the server,
395
+ * recording an undoable entry. Returns false without side effects when the
396
+ * doc isn't cached. Rolls back the local apply and rethrows on send failure.
397
+ */
398
+ async dispatch(
399
+ key: Key,
400
+ actions: Action[],
401
+ send: SendDispatch<Action>,
402
+ opts: Options<State, Action> = {},
403
+ ): Promise<boolean> {
404
+ if (actions.length === 0) return true;
405
+ return await this.applySend(
406
+ key,
407
+ actions,
408
+ ({ processed, inverse, targets }) =>
409
+ this.recordEntry(key, processed, inverse, targets),
410
+ send,
411
+ opts.preprocess,
412
+ );
413
+ }
414
+
415
+ /**
416
+ * Apply and send the top live undo entry, moving it to the redo stack. Returns false
417
+ * when nothing is undoable. Rolls back and rethrows on send failure.
418
+ */
419
+ async undo(key: Key, send: SendDispatch<Action>): Promise<boolean> {
420
+ const prepared = this.prepareUndo(key);
421
+ if (prepared == null) return false;
422
+ return await this.applySend(key, prepared.actions, () => prepared.commit(), send);
423
+ }
424
+
425
+ /** Mirror of {@link undo} for the redo stack. */
426
+ async redo(key: Key, send: SendDispatch<Action>): Promise<boolean> {
427
+ const prepared = this.prepareRedo(key);
428
+ if (prepared == null) return false;
429
+ return await this.applySend(key, prepared.actions, () => prepared.commit(), send);
430
+ }
431
+
432
+ /**
433
+ * Stage actions committed atomically as one undoable entry, registering the batch as
434
+ * outstanding before the send so the broadcast echo is recognized as own.
435
+ */
436
+ transaction(
437
+ key: Key,
438
+ send: SendDispatch<Action>,
439
+ kind?: string,
440
+ ): Transaction<Action> {
441
+ return this.beginTransaction(
442
+ key,
443
+ async (actions) => {
444
+ const dispatchKey = id.create();
445
+ this.registerOutstandingDispatch(key, dispatchKey);
446
+ await send(actions, dispatchKey);
447
+ },
448
+ kind,
449
+ );
450
+ }
451
+
452
+ prepareUndo(key: Key): Reversal<Action> | null {
453
+ return this.prepareReversal(key, "undo");
454
+ }
455
+
456
+ prepareRedo(key: Key): Reversal<Action> | null {
457
+ return this.prepareReversal(key, "redo");
458
+ }
459
+
460
+ beginTransaction(key: Key, send: Send<Action>, kind?: string): Transaction<Action> {
461
+ const initial = this.docs.get(key);
462
+ const accumulated: Action[] = [];
463
+ let done = false;
464
+ return {
465
+ add: (actions) => {
466
+ if (done) throw new Error("transaction finalized");
467
+ if (initial == null) return;
468
+ const arr = Array.isArray(actions) ? actions : [actions];
469
+ const r = this.replay(key, arr);
470
+ if (r != null) accumulated.push(...r.processed);
471
+ },
472
+ commit: async () => {
473
+ if (done) return false;
474
+ done = true;
475
+ if (accumulated.length === 0 || initial == null) return false;
476
+ // Inverse must be computed against the pre-transaction snapshot so
477
+ // undo restores to where the user started, not the last-add post-state.
478
+ const { inverse, targets } = this.params.reduce(initial, accumulated);
479
+ const stackRollback = this.recordEntry(
480
+ key,
481
+ accumulated,
482
+ inverse,
483
+ targets,
484
+ kind,
485
+ );
486
+ try {
487
+ await send(accumulated);
488
+ return true;
489
+ } catch (e) {
490
+ stackRollback();
491
+ this.docs.set(key, initial);
492
+ throw errors.fromUnknown(e);
493
+ }
494
+ },
495
+ abort: () => {
496
+ if (done) return;
497
+ done = true;
498
+ if (initial != null) this.docs.set(key, initial);
499
+ },
500
+ };
501
+ }
502
+
503
+ markRemoteTouched(key: Key, targets: readonly string[]): destructor.Destructor {
504
+ if (targets.length === 0) return destructor.NOOP;
505
+ const tick = ++this.tick;
506
+ return this.updateUndo(key, (s) => {
507
+ const remoteTouched = { ...s.remoteTouched };
508
+ for (const t of targets) remoteTouched[t] = tick;
509
+ return { ...s, remoteTouched };
510
+ });
511
+ }
512
+
513
+ /** Whether any locally replayed dispatch for the key still awaits its echo. */
514
+ hasOutstanding(key: Key): boolean {
515
+ return (this.outstandingDispatches.get(key)?.size ?? 0) > 0;
516
+ }
517
+
518
+ /**
519
+ * Register a dispatch as outstanding so when its broadcast echo arrives it
520
+ * can be recognized as own and a redundant reduce skipped. Called by the
521
+ * dispatcher *before* the network send so the registration always wins the
522
+ * race against a fast echo. A registration whose echo has already been
523
+ * applied (seq advanced past it) is silently dropped; that's the safe
524
+ * fallback when the echo arrives before the dispatch promise resolves.
525
+ */
526
+ registerOutstandingDispatch(key: Key, dispatchKey: string): void {
527
+ let bucket = this.outstandingDispatches.get(key);
528
+ if (bucket == null) {
529
+ bucket = new Map();
530
+ this.outstandingDispatches.set(key, bucket);
531
+ }
532
+ bucket.set(dispatchKey, { disturbed: false });
533
+ }
534
+
535
+ /**
536
+ * Apply a remote frame. The frame is dropped if its seq does not exceed the
537
+ * high-water mark previously applied for this key. If `dispatchKey` matches an entry
538
+ * the originator registered as outstanding, these actions were already applied via
539
+ * replay: if no foreign action interleaved during the outstanding window, skip the
540
+ * reduce; otherwise re-run it to recover from the foreign overwrite. A foreign frame
541
+ * (one whose dispatchKey is unknown) always reduces and marks every outstanding own
542
+ * dispatch with a greater seq as needing recovery.
543
+ */
544
+ applyRemote(key: Key, seq: number, dispatchKey: string, actions: Action[]): void {
545
+ if (seq !== 0) {
546
+ const last = this.lastAppliedSeq.get(key) ?? 0;
547
+ if (seq <= last) return;
548
+ this.lastAppliedSeq.set(key, seq);
549
+ }
550
+ // Create frames carry no dispatch key, so the originator cannot recognize
551
+ // its own echo; applying one to a cached doc would revert local edits to
552
+ // the creation state. Drop the create and keep any trailing actions.
553
+ if (
554
+ actions.length > 0 &&
555
+ this.params.createOf(actions[0]) != null &&
556
+ this.docs.get(key) != null
557
+ ) {
558
+ actions = actions.slice(1);
559
+ if (actions.length === 0) return;
560
+ }
561
+ const bucket = this.outstandingDispatches.get(key);
562
+ const ownEntry = bucket?.get(dispatchKey);
563
+ const isOwnEcho = ownEntry != null;
564
+ if (ownEntry != null) {
565
+ bucket?.delete(dispatchKey);
566
+ // Local replay was authoritative; nothing interleaved.
567
+ if (!ownEntry.disturbed) return;
568
+ // Fall through to reduce: a foreign echo overwrote state during the
569
+ // outstanding window, so we must re-apply to recover.
570
+ } else if (bucket != null)
571
+ // Foreign echo: any outstanding own dispatch represents a local replay that the
572
+ // server has not yet broadcast back. We don't know each entry's server-stamped
573
+ // seq yet (the echo carrying it hasn't arrived), so we can't tell whether the
574
+ // foreign was applied before or after it on the server — mark every outstanding
575
+ // entry as disturbed. Entries whose seq turns out to be greater than this
576
+ // foreign's seq genuinely need recovery; entries whose seq was lower will re-run
577
+ // idempotently and converge to the same value.
578
+ for (const entry of bucket.values()) entry.disturbed = true;
579
+ const current = this.docs.get(key);
580
+ if (current == null) {
581
+ // A create-headed frame seeds the document; anything else predates our
582
+ // knowledge of the doc and is unreconstructable, so it drops.
583
+ const created = actions.length > 0 ? this.params.createOf(actions[0]) : undefined;
584
+ if (created == null) return;
585
+ const { next } = this.params.reduce(created, actions.slice(1));
586
+ this.docs.set(key, next);
587
+ return;
588
+ }
589
+ const { next, targets } = this.params.reduce(current, actions);
590
+ this.docs.set(key, next);
591
+ if (!isOwnEcho) this.markRemoteTouched(key, targets);
592
+ }
593
+
594
+ hasUndo(key: Key): boolean {
595
+ const s = this.undos.get(key);
596
+ return (s?.undo.length ?? 0) > 0;
597
+ }
598
+
599
+ hasRedo(key: Key): boolean {
600
+ const s = this.undos.get(key);
601
+ return (s?.redo.length ?? 0) > 0;
602
+ }
603
+
604
+ onUndoStateChange(callback: () => void, key?: Key): destructor.Destructor {
605
+ return this.undos.subscribe(() => callback(), key);
606
+ }
607
+
608
+ /**
609
+ * Builds a channel listener that applies broadcast action frames from the
610
+ * given channel to this controller. Registered via {@link query.Cache.listen}.
611
+ */
612
+ listener(
613
+ channel: string,
614
+ schema: z.ZodType<Frame<Key, Action>>,
615
+ ): query.Listener<z.ZodType<Frame<Key, Action>>> {
616
+ return {
617
+ channel,
618
+ schema,
619
+ onChange: (frames) => {
620
+ frames.forEach(({ key, seq, dispatchKey, actions }) =>
621
+ this.applyRemote(key, seq, dispatchKey, actions),
622
+ );
623
+ },
624
+ };
625
+ }
626
+ }