@synnaxlabs/client 0.56.2 → 0.57.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 (741) hide show
  1. package/dist/client-B08VDLSA.js +14463 -0
  2. package/dist/client-B08VDLSA.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 +71 -0
  99. package/dist/src/framer/cache/dynamic.d.ts.map +1 -0
  100. package/dist/src/framer/cache/reader.d.ts +43 -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 +37 -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 +40 -17
  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 +279 -0
  398. package/src/framer/cache/reader.ts +160 -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 +104 -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 +18 -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
@@ -0,0 +1,279 @@
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 { alamos } from "@synnaxlabs/alamos";
11
+ import {
12
+ DataType,
13
+ math,
14
+ MultiSeries,
15
+ Series,
16
+ type TimeSpan,
17
+ TimeStamp,
18
+ } from "@synnaxlabs/x";
19
+
20
+ import { IDENTITY_TRANSFORM, type Transform } from "@/framer/cache/transform";
21
+
22
+ /** Response from a write to the {@link Dynamic} cache. */
23
+ export interface WriteResponse {
24
+ /** Series flushed because the write did not fit in the current buffer. */
25
+ flushed: MultiSeries;
26
+ /** A list of series that were allocated during the write. */
27
+ allocated: MultiSeries;
28
+ }
29
+
30
+ /** Props for the {@link Dynamic} cache. */
31
+ export interface DynamicProps {
32
+ /**
33
+ * Sets the maximum size of the buffer that the cache will maintain before flushing
34
+ * data out to the caller.
35
+ */
36
+ dynamicBufferSize: number | TimeSpan;
37
+ /** Applied to every series before it enters a buffer. Defaults to identity. */
38
+ transform?: Transform;
39
+ /** Used for logging. */
40
+ instrumentation?: alamos.Instrumentation;
41
+ /** Pulls the current time. */
42
+ now?: () => TimeStamp;
43
+ }
44
+
45
+ // Bounds for dynamically calculated buffer sizes.
46
+ const MIN_SIZE = 100;
47
+ const MAX_SIZE = 1e6;
48
+ // Size used until enough writes have arrived to estimate a rate.
49
+ const DEF_SIZE = 1e4;
50
+ const MAX_DEF_WRITES = 100;
51
+
52
+ // Variable-rate types allocate bytes, not samples. Rough bytes-per-sample estimate.
53
+ const VARIABLE_DT_MULTIPLIER = 40;
54
+
55
+ /**
56
+ * A cache for channel data that maintains a single, rolling Series as a buffer
57
+ * for channel data. The buffer's data type is derived from the first written series,
58
+ * so the cache needs no channel metadata.
59
+ */
60
+ export class Dynamic {
61
+ private readonly props: Required<Omit<DynamicProps, "now">>;
62
+
63
+ private counter = 0;
64
+ private curr: Series | null = null;
65
+ /** End timestamp of the last fully written stamped series in the current buffer.
66
+ * Null when the buffer holds unstamped or partially written data, in which case
67
+ * the flush falls back to the wall clock. */
68
+ private currDataEnd: TimeStamp | null = null;
69
+ private avgRate: number = 0;
70
+ private timeOfLastWrite: TimeStamp;
71
+ private totalWrites: number = 0;
72
+ private readonly now: () => TimeStamp;
73
+
74
+ constructor(props: DynamicProps) {
75
+ const {
76
+ dynamicBufferSize,
77
+ transform = IDENTITY_TRANSFORM,
78
+ instrumentation = alamos.NOOP,
79
+ now = () => TimeStamp.now(),
80
+ } = props;
81
+ this.props = { dynamicBufferSize, transform, instrumentation };
82
+ this.now = now;
83
+ this.timeOfLastWrite = this.now();
84
+ }
85
+
86
+ /** @returns the number of samples currently held in the cache. */
87
+ get length(): number {
88
+ return this.curr?.length ?? 0;
89
+ }
90
+
91
+ /**
92
+ * @returns the current buffer being written to by the cache. Under no circumstances
93
+ * should this be modified by the caller.
94
+ */
95
+ get leadingBuffer(): Series | null {
96
+ return this.curr;
97
+ }
98
+
99
+ /**
100
+ * @returns a list of buffers that were filled by the cache during the write. If the
101
+ * current buffer is able to fit all writes, no buffers will be returned.
102
+ */
103
+ write(series: MultiSeries): WriteResponse {
104
+ const res: WriteResponse = {
105
+ flushed: new MultiSeries([]),
106
+ allocated: new MultiSeries([]),
107
+ };
108
+ const list = series.series;
109
+ for (let i = 0; i < list.length; i++) this._write(list[i], res);
110
+ return res;
111
+ }
112
+
113
+ private allocate(
114
+ capacity: number,
115
+ alignment: bigint,
116
+ start: TimeStamp,
117
+ source: Series,
118
+ sampleIndex: number,
119
+ ): Series {
120
+ this.counter++;
121
+ const dt = this.props.transform.resolveDataType(source.dataType);
122
+ // Bigint series narrowed to a non-bigint buffer store each value as a small delta
123
+ // off a per-buffer anchor to avoid losing precision. For timestamps, now() is
124
+ // close enough to the values being written. For int64 and uint64 the values can
125
+ // be anything, so the first sample we see is used as the anchor.
126
+ const narrowing = source.dataType.usesBigInt && !dt.usesBigInt;
127
+ let sampleOffset: math.Numeric = 0;
128
+ if (narrowing)
129
+ if (source.dataType.equals(DataType.TIMESTAMP)) sampleOffset = start.valueOf();
130
+ else if (sampleIndex < source.length)
131
+ sampleOffset = BigInt(source.data[sampleIndex].valueOf());
132
+ return Series.alloc({
133
+ capacity: dt.isVariable ? capacity * VARIABLE_DT_MULTIPLIER : capacity,
134
+ dataType: dt,
135
+ timeRange: start.range(TimeStamp.MAX),
136
+ sampleOffset,
137
+ glBufferUsage: "dynamic",
138
+ alignment,
139
+ key: `dynamic-${this.counter}`,
140
+ });
141
+ }
142
+
143
+ // Unstamped series (virtual channels, writes without an in-frame index) fall back
144
+ // to the wall clock.
145
+ private allocStart(series: Series): TimeStamp {
146
+ return series.timeRange.isZero ? this.now() : series.timeRange.start;
147
+ }
148
+
149
+ private allocCurr(
150
+ res: WriteResponse,
151
+ alignment: bigint,
152
+ start: TimeStamp,
153
+ source: Series,
154
+ sampleIndex: number,
155
+ ): Series {
156
+ this.curr = this.allocate(
157
+ this.nextBufferSize(),
158
+ alignment,
159
+ start,
160
+ source,
161
+ sampleIndex,
162
+ );
163
+ res.allocated.push(this.curr);
164
+ return this.curr;
165
+ }
166
+
167
+ private flushCurr(res: WriteResponse): void {
168
+ if (this.curr == null) return;
169
+ this.curr.timeRange.end = this.currDataEnd ?? this.now();
170
+ this.currDataEnd = null;
171
+ res.flushed.push(this.curr);
172
+ this.curr = null;
173
+ }
174
+
175
+ private _write(series: Series, res: WriteResponse): void {
176
+ const { transform, instrumentation: ins } = this.props;
177
+ if (this.curr != null) {
178
+ const resolved = transform.resolveDataType(series.dataType);
179
+ if (!this.curr.dataType.equals(resolved)) {
180
+ // The channel's data type changed (e.g. a calculated channel was reconfigured).
181
+ ins.L.warn("buffer data type changed, resetting", {
182
+ prev: this.curr.dataType.toString(),
183
+ next: resolved.toString(),
184
+ });
185
+ this.flushCurr(res);
186
+ } else if (series.alignment < this.curr.alignment) {
187
+ // The alignment counter rewound (e.g. the Core restarted and reset its
188
+ // in-memory counter).
189
+ ins.L.warn("alignment regressed, resetting buffer", {
190
+ buffer: this.curr.alignment.toString(),
191
+ incoming: series.alignment.toString(),
192
+ });
193
+ this.flushCurr(res);
194
+ }
195
+ }
196
+ let curr = this.curr;
197
+ if (curr == null)
198
+ curr = this.allocCurr(res, series.alignment, this.allocStart(series), series, 0);
199
+ else {
200
+ // overlap > 0: the incoming series steps back into samples the current buffer
201
+ // already holds. overlap < 0: there is a gap between the buffer and the series.
202
+ const overlap = Number(curr.alignment + BigInt(curr.length) - series.alignment);
203
+ if (overlap > 0) {
204
+ // Drop the re-sent leading samples; a fresh allocation here would fragment
205
+ // the cache with overlapping series. sub() is zero-copy.
206
+ if (overlap >= series.length) return;
207
+ series = series.sub(overlap);
208
+ } else if (overlap < 0) {
209
+ this.flushCurr(res);
210
+ curr = this.allocCurr(
211
+ res,
212
+ series.alignment,
213
+ this.allocStart(series),
214
+ series,
215
+ 0,
216
+ );
217
+ }
218
+ }
219
+ while (true) {
220
+ const converted = transform.convert(series, curr.sampleOffset);
221
+ const amountWritten = curr.write(converted);
222
+ if (amountWritten === series.length) {
223
+ this.currDataEnd = series.timeRange.isZero ? null : series.timeRange.end;
224
+ this.updateAvgRate(series);
225
+ return;
226
+ }
227
+ // The timestamp at the split point is unknowable from the data series, so
228
+ // both sides fall back to the wall clock.
229
+ this.currDataEnd = null;
230
+ this.flushCurr(res);
231
+ curr = this.allocCurr(
232
+ res,
233
+ series.alignment + BigInt(amountWritten),
234
+ this.now(),
235
+ series,
236
+ amountWritten,
237
+ );
238
+ series = series.slice(amountWritten);
239
+ }
240
+ }
241
+
242
+ private updateAvgRate(series: Series): void {
243
+ if (typeof this.props.dynamicBufferSize === "number") return;
244
+ const now = this.now();
245
+ const newRate = series.length / now.span(this.timeOfLastWrite).seconds;
246
+ if (this.totalWrites > 0 && isFinite(newRate) && newRate > 0)
247
+ this.avgRate =
248
+ (this.avgRate * (this.totalWrites - 1) + newRate) / this.totalWrites;
249
+ this.totalWrites++;
250
+ this.timeOfLastWrite = now;
251
+ }
252
+
253
+ private nextBufferSize(): number {
254
+ const { dynamicBufferSize } = this.props;
255
+ if (typeof dynamicBufferSize === "number") return dynamicBufferSize;
256
+ if (this.totalWrites < MAX_DEF_WRITES) return DEF_SIZE;
257
+ const size = math.roundToNearestMagnitude(this.avgRate * dynamicBufferSize.seconds);
258
+ return Math.round(Math.max(Math.min(size, MAX_SIZE), MIN_SIZE));
259
+ }
260
+
261
+ /**
262
+ * Flushes the leading buffer, stamping its end with the last stamped write or
263
+ * the wall clock.
264
+ * @returns the flushed buffer, or null when there is none.
265
+ */
266
+ flush(): Series | null {
267
+ const res: WriteResponse = {
268
+ flushed: new MultiSeries([]),
269
+ allocated: new MultiSeries([]),
270
+ };
271
+ this.flushCurr(res);
272
+ return res.flushed.series[0] ?? null;
273
+ }
274
+
275
+ /** Closes the cache. It must not be used afterwards. */
276
+ close(): void {
277
+ this.curr = null;
278
+ }
279
+ }
@@ -0,0 +1,160 @@
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
+ debounce,
12
+ MultiSeries,
13
+ type Series,
14
+ sync,
15
+ TimeRange,
16
+ TimeSpan,
17
+ } from "@synnaxlabs/x";
18
+
19
+ import { type channel } from "@/channel";
20
+ import { UnexpectedError } from "@/errors";
21
+ import { type Cache } from "@/framer/cache/cache";
22
+ import { type Frame } from "@/framer/frame";
23
+
24
+ /** A function that reads a telemetry frame from the Synnax cluster. */
25
+ export interface RemoteReader {
26
+ (tr: TimeRange, keys: channel.Key[]): Promise<Frame>;
27
+ }
28
+
29
+ interface ReadRequest {
30
+ channel: channel.Key;
31
+ gaps: TimeRange[];
32
+ }
33
+
34
+ interface BatchFetch {
35
+ gap: TimeRange;
36
+ channels: Set<channel.Key>;
37
+ entries: Set<debounce.Entry<ReadRequest>>;
38
+ }
39
+
40
+ export interface ReaderProps {
41
+ /** Function used to read remote data from the server. */
42
+ readRemote: RemoteReader;
43
+ /** Will read from and populate the given cache with fetched data. */
44
+ cache: Cache;
45
+ /**
46
+ * Used to batch read requests to the server to minimize traffic. The window is not
47
+ * extended by later reads, so it is also the maximum wait before a batch fires.
48
+ * @default TimeSpan.milliseconds(50)
49
+ */
50
+ batchDebounce?: TimeSpan;
51
+ /**
52
+ * Reads whose gap time ranges are within this threshold merge into one request.
53
+ * @default TimeSpan.milliseconds(5)
54
+ */
55
+ overlapThreshold?: TimeSpan;
56
+ }
57
+
58
+ /**
59
+ * Reads historical telemetry, serving from the cache and batch-filling gaps from the
60
+ * server. A batch failure rejects only the reads whose gaps were in the failed fetch.
61
+ */
62
+ export class Reader {
63
+ private readonly props: Required<Omit<ReaderProps, "batchDebounce">>;
64
+ private readonly batcher: debounce.Batcher<ReadRequest>;
65
+ // Serializes batch execution against close, so close waits for the batch in flight.
66
+ private readonly mu = sync.newMutex({ closed: false });
67
+
68
+ constructor(props: ReaderProps) {
69
+ const {
70
+ readRemote,
71
+ cache,
72
+ batchDebounce = TimeSpan.milliseconds(50),
73
+ overlapThreshold = TimeSpan.milliseconds(5),
74
+ } = props;
75
+ this.props = { readRemote, cache, overlapThreshold };
76
+ this.batcher = new debounce.Batcher({
77
+ interval: batchDebounce,
78
+ exec: async (entries) =>
79
+ await this.mu.runExclusive(async () => {
80
+ if (this.mu.closed) throw new UnexpectedError("telemetry reader is closed");
81
+ await this.batchRead(entries);
82
+ }),
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Reads the given time range for the given channel.
88
+ * @throws {UnexpectedError} if the reader is closed while the read is pending.
89
+ */
90
+ async read(tr: TimeRange, channel: channel.Key): Promise<MultiSeries> {
91
+ const { cache } = this.props;
92
+ const unary = cache.get(channel);
93
+ const { series, gaps } = unary.read(tr);
94
+ if (gaps.length === 0) return series;
95
+ if (this.mu.closed) throw new UnexpectedError("telemetry reader is closed");
96
+ await this.batcher.enqueue({ channel, gaps });
97
+ return unary.read(tr).series;
98
+ }
99
+
100
+ private async batchRead(entries: Array<debounce.Entry<ReadRequest>>): Promise<void> {
101
+ const { readRemote, cache, overlapThreshold } = this.props;
102
+ const batched: BatchFetch[] = [];
103
+ entries.forEach((entry) => {
104
+ const unary = cache.get(entry.req.channel);
105
+ entry.req.gaps.forEach((rawGap) => {
106
+ // A concurrent batch or a streaming write may have filled part of the gap
107
+ // while this entry sat in the debounce window.
108
+ unary.read(rawGap).gaps.forEach((gap) => {
109
+ const g = batched.find((r) => r.gap.equals(gap, overlapThreshold));
110
+ if (g == null)
111
+ batched.push({
112
+ gap,
113
+ channels: new Set([entry.req.channel]),
114
+ entries: new Set([entry]),
115
+ });
116
+ else {
117
+ g.channels.add(entry.req.channel);
118
+ g.gap = TimeRange.max(g.gap, gap);
119
+ g.entries.add(entry);
120
+ }
121
+ });
122
+ });
123
+ });
124
+ const failures = new Map<debounce.Entry<ReadRequest>, unknown>();
125
+ await Promise.all(
126
+ batched.map(async ({ gap, channels, entries: served }) => {
127
+ try {
128
+ const frame = await readRemote(gap, Array.from(channels));
129
+ // Group series by key in one pass; per-key get() scans the whole frame.
130
+ const grouped = new Map<channel.Key, Series[]>();
131
+ frame.forEach((k, s) => {
132
+ const key = k as channel.Key;
133
+ const existing = grouped.get(key);
134
+ if (existing == null) grouped.set(key, [s]);
135
+ else existing.push(s);
136
+ });
137
+ channels.forEach((key) =>
138
+ cache.get(key).writeStatic(new MultiSeries(grouped.get(key) ?? [])),
139
+ );
140
+ } catch (err) {
141
+ served.forEach((entry) => {
142
+ if (!failures.has(entry)) failures.set(entry, err);
143
+ });
144
+ }
145
+ }),
146
+ );
147
+ entries.forEach((entry) => {
148
+ const err = failures.get(entry);
149
+ if (err == null) entry.resolve();
150
+ else entry.reject(err);
151
+ });
152
+ }
153
+
154
+ async close(): Promise<void> {
155
+ this.batcher.close(new UnexpectedError("telemetry reader is closed"));
156
+ await this.mu.runExclusive(async () => {
157
+ this.mu.closed = true;
158
+ });
159
+ }
160
+ }
@@ -0,0 +1,215 @@
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 { alamos } from "@synnaxlabs/alamos";
11
+ import {
12
+ bounds,
13
+ MultiSeries,
14
+ type Series,
15
+ Size,
16
+ TimeRange,
17
+ TimeSpan,
18
+ TimeStamp,
19
+ } from "@synnaxlabs/x";
20
+
21
+ import { IDENTITY_TRANSFORM, type Transform } from "@/framer/cache/transform";
22
+
23
+ export interface DirtyReadResult {
24
+ series: MultiSeries;
25
+ gaps: TimeRange[];
26
+ }
27
+
28
+ export interface GCMetrics {
29
+ purgedSeries: number;
30
+ purgedBytes: Size;
31
+ }
32
+
33
+ export const zeroGCMetrics = (): GCMetrics => ({
34
+ purgedSeries: 0,
35
+ purgedBytes: Size.bytes(0),
36
+ });
37
+
38
+ /** Props for the {@link Static} cache. */
39
+ export interface StaticProps {
40
+ /** Used for logging */
41
+ instrumentation?: alamos.Instrumentation;
42
+ /** Applied to every series before it enters the cache. Defaults to identity. */
43
+ transform?: Transform;
44
+ /**
45
+ * Sets the amount of time that a cache entry must be in the cache before it can
46
+ * be marked as stale and subject to garbage collection.
47
+ * @default TimeSpan.seconds(20) */
48
+ staleEntryThreshold?: TimeSpan;
49
+ }
50
+
51
+ export const DEFAULT_STATIC_PROPS: Required<StaticProps> = {
52
+ instrumentation: alamos.NOOP,
53
+ transform: IDENTITY_TRANSFORM,
54
+ staleEntryThreshold: TimeSpan.seconds(20),
55
+ };
56
+
57
+ interface CacheEntry {
58
+ /** The cached samples, after the transform and any insertion trimming. */
59
+ data: Series;
60
+ /** When the entry entered the cache, for garbage collection staleness. */
61
+ addedAt: TimeStamp;
62
+ }
63
+
64
+ /**
65
+ * A cache for historical channel data that will not be modified after it is written.
66
+ * Fetched and streamed entries are held apart because they measure position in
67
+ * different spaces: a fetched sample carries its committed alignment, the same sample
68
+ * streamed carries a provisional leading one. Insertion and gap computation both assume
69
+ * a single space, so each kind gets its own list.
70
+ */
71
+ export class Static {
72
+ private fetched: CacheEntry[] = [];
73
+ private streamed: CacheEntry[] = [];
74
+ private readonly props: Required<StaticProps>;
75
+
76
+ constructor(props: StaticProps) {
77
+ const {
78
+ instrumentation = DEFAULT_STATIC_PROPS.instrumentation,
79
+ transform = DEFAULT_STATIC_PROPS.transform,
80
+ staleEntryThreshold = DEFAULT_STATIC_PROPS.staleEntryThreshold,
81
+ } = props;
82
+ this.props = { instrumentation, transform, staleEntryThreshold };
83
+ }
84
+
85
+ /**
86
+ * Writes the given series to the cache, merging written series with any existing
87
+ * series in the cache.
88
+ * @param streamed - Marks the series as live-streamed data. A fetched write evicts
89
+ * every streamed entry whose time range it fully covers.
90
+ */
91
+ write(series: MultiSeries, streamed: boolean = false): void {
92
+ if (series.length === 0) return;
93
+ if (!streamed) this.evictStreamed(series);
94
+ const entries = streamed ? this.streamed : this.fetched;
95
+ series.series.forEach((s) =>
96
+ this.writeOne(this.props.transform.convert(s), entries),
97
+ );
98
+ this.repairIntegrity(series, entries);
99
+ }
100
+
101
+ // Containment, not overlap: a fetch stamped wider than the data it returned
102
+ // (an uncommitted tail) must not evict streamed samples it did not replace.
103
+ private evictStreamed(written: MultiSeries): void {
104
+ this.streamed = this.streamed.filter(
105
+ (e) =>
106
+ !written.series.some(
107
+ (s) =>
108
+ s.timeRange.start.beforeEq(e.data.timeRange.start) &&
109
+ s.timeRange.end.afterEq(e.data.timeRange.end),
110
+ ),
111
+ );
112
+ }
113
+
114
+ /**
115
+ * Executes a 'dirty' read of the cache, retrieving any series in the cache that
116
+ * overlap with the given time range. The series may extend before or after the range.
117
+ * Gaps are computed against fetched entries only. Streamed entries carry provisional
118
+ * leading alignments that cannot pair with fetched data on another channel, so they
119
+ * never claim coverage; the fetch they provoke evicts them.
120
+ * @returns A list of series that overlap with the given time range and a list of
121
+ * gaps, representing the regions of time the fetched series do not cover.
122
+ */
123
+ dirtyRead(tr: TimeRange): DirtyReadResult {
124
+ const overlapping = (entries: CacheEntry[]): Series[] =>
125
+ entries.filter((e) => e.data.timeRange.overlapsWith(tr)).map((e) => e.data);
126
+ const fetched = overlapping(this.fetched);
127
+ const series = [...fetched, ...overlapping(this.streamed)];
128
+ if (fetched.length === 0) return { series: new MultiSeries(series), gaps: [tr] };
129
+ const gaps: TimeRange[] = [];
130
+ const pushGap = (start: TimeStamp, end: TimeStamp): void => {
131
+ const gap = new TimeRange(start, end);
132
+ if (gap.isValid && !gap.span.isZero) gaps.push(gap);
133
+ };
134
+ pushGap(tr.start, fetched[0].timeRange.start);
135
+ for (let i = 1; i < fetched.length; i++)
136
+ pushGap(fetched[i - 1].timeRange.end, fetched[i].timeRange.start);
137
+ pushGap(fetched[fetched.length - 1].timeRange.end, tr.end);
138
+ return { series: new MultiSeries(series), gaps };
139
+ }
140
+
141
+ /**
142
+ * Garbage collects the cache, removing any stale entries.
143
+ * @returns metrics about the garbage collection.
144
+ */
145
+ gc(): GCMetrics {
146
+ const { staleEntryThreshold } = this.props;
147
+ const res = zeroGCMetrics();
148
+ const collect = (entries: CacheEntry[]): CacheEntry[] =>
149
+ entries.filter((s) => {
150
+ const shouldKeep =
151
+ s.data.refCount > 0 ||
152
+ TimeStamp.since(s.addedAt).lessThan(staleEntryThreshold);
153
+ if (!shouldKeep) {
154
+ res.purgedBytes = res.purgedBytes.add(s.data.byteCapacity);
155
+ res.purgedSeries++;
156
+ }
157
+ return shouldKeep;
158
+ });
159
+ this.fetched = collect(this.fetched);
160
+ this.streamed = collect(this.streamed);
161
+ return res;
162
+ }
163
+
164
+ /** Closes the cache, freeing all of its resources. */
165
+ close(): void {
166
+ this.fetched = [];
167
+ this.streamed = [];
168
+ }
169
+
170
+ private writeOne(series: Series, entries: CacheEntry[]): void {
171
+ const {
172
+ instrumentation: { L },
173
+ } = this.props;
174
+ if (series.length === 0) return;
175
+ const insertionPlan = bounds.buildInsertionPlan(
176
+ entries.map((s) => s.data.alignmentBounds),
177
+ series.alignmentBounds,
178
+ );
179
+ if (insertionPlan === null)
180
+ return L.debug("Found no viable insertion plan", () => ({
181
+ inserting: series.digest,
182
+ cacheContents: entries.map((s) => s.data.digest),
183
+ }));
184
+ const { removeBefore, removeAfter, insertInto, deleteInBetween } = insertionPlan;
185
+ series = series.slice(removeBefore, series.length - removeAfter);
186
+ if (series.length === 0) return;
187
+ entries.splice(insertInto, deleteInBetween, {
188
+ data: series,
189
+ addedAt: TimeStamp.now(),
190
+ });
191
+ }
192
+
193
+ private repairIntegrity(write: MultiSeries, entries: CacheEntry[]): void {
194
+ const {
195
+ instrumentation: { L },
196
+ } = this.props;
197
+ // Entries are ordered and non-overlapping, so neighbor comparison suffices. An
198
+ // overlap is an insertion bug: evict both entries and let a refetch heal the gap.
199
+ for (let i = 1; i < entries.length; i++) {
200
+ if (
201
+ !bounds.overlapsWith(
202
+ entries[i - 1].data.alignmentBounds,
203
+ entries[i].data.alignmentBounds,
204
+ )
205
+ )
206
+ continue;
207
+ const [prev, curr] = entries.splice(i - 1, 2);
208
+ L.error("cache integrity violation - evicting overlapping entries", () => ({
209
+ write: write.series.map((s) => s.digest),
210
+ evicted: [prev.data.digest, curr.data.digest],
211
+ }));
212
+ i = 0;
213
+ }
214
+ }
215
+ }