@synnaxlabs/client 0.47.0 → 0.49.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 (311) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/dist/client.cjs +35 -35
  3. package/dist/client.js +6264 -5984
  4. package/dist/eslint.config.d.ts +3 -2
  5. package/dist/eslint.config.d.ts.map +1 -1
  6. package/dist/src/access/client.d.ts +3 -1
  7. package/dist/src/access/client.d.ts.map +1 -1
  8. package/dist/src/access/enforce.d.ts +35 -0
  9. package/dist/src/access/enforce.d.ts.map +1 -0
  10. package/dist/src/access/enforce.spec.d.ts +2 -0
  11. package/dist/src/access/enforce.spec.d.ts.map +1 -0
  12. package/dist/src/access/external.d.ts +3 -0
  13. package/dist/src/access/external.d.ts.map +1 -1
  14. package/dist/src/access/payload.d.ts +0 -6
  15. package/dist/src/access/payload.d.ts.map +1 -1
  16. package/dist/src/access/policy/access.spec.d.ts +2 -0
  17. package/dist/src/access/policy/access.spec.d.ts.map +1 -0
  18. package/dist/src/access/policy/client.d.ts +485 -31
  19. package/dist/src/access/policy/client.d.ts.map +1 -1
  20. package/dist/src/access/policy/payload.d.ts +36 -113
  21. package/dist/src/access/policy/payload.d.ts.map +1 -1
  22. package/dist/src/access/role/client.d.ts +135 -0
  23. package/dist/src/access/role/client.d.ts.map +1 -0
  24. package/dist/src/access/role/external.d.ts.map +1 -0
  25. package/dist/src/access/role/index.d.ts +2 -0
  26. package/dist/src/access/role/index.d.ts.map +1 -0
  27. package/dist/src/access/role/payload.d.ts +27 -0
  28. package/dist/src/access/role/payload.d.ts.map +1 -0
  29. package/dist/src/access/role/role.spec.d.ts +2 -0
  30. package/dist/src/access/role/role.spec.d.ts.map +1 -0
  31. package/dist/src/arc/access.spec.d.ts +2 -0
  32. package/dist/src/arc/access.spec.d.ts.map +1 -0
  33. package/dist/src/arc/client.d.ts +5 -14
  34. package/dist/src/arc/client.d.ts.map +1 -1
  35. package/dist/src/arc/payload.d.ts +11 -2
  36. package/dist/src/arc/payload.d.ts.map +1 -1
  37. package/dist/src/auth/auth.d.ts +5 -3
  38. package/dist/src/auth/auth.d.ts.map +1 -1
  39. package/dist/src/channel/access.spec.d.ts +2 -0
  40. package/dist/src/channel/access.spec.d.ts.map +1 -0
  41. package/dist/src/channel/client.d.ts +0 -1
  42. package/dist/src/channel/client.d.ts.map +1 -1
  43. package/dist/src/channel/payload.d.ts +19 -8
  44. package/dist/src/channel/payload.d.ts.map +1 -1
  45. package/dist/src/channel/payload.spec.d.ts +2 -0
  46. package/dist/src/channel/payload.spec.d.ts.map +1 -0
  47. package/dist/src/channel/retriever.d.ts +4 -6
  48. package/dist/src/channel/retriever.d.ts.map +1 -1
  49. package/dist/src/channel/writer.d.ts.map +1 -1
  50. package/dist/src/client.d.ts +18 -10
  51. package/dist/src/client.d.ts.map +1 -1
  52. package/dist/src/connection/checker.d.ts +2 -3
  53. package/dist/src/connection/checker.d.ts.map +1 -1
  54. package/dist/src/connection.spec.d.ts +2 -0
  55. package/dist/src/connection.spec.d.ts.map +1 -0
  56. package/dist/src/device/access.spec.d.ts +2 -0
  57. package/dist/src/device/access.spec.d.ts.map +1 -0
  58. package/dist/src/{hardware/device → device}/client.d.ts +14 -7
  59. package/dist/src/device/client.d.ts.map +1 -0
  60. package/dist/src/device/device.spec.d.ts.map +1 -0
  61. package/dist/src/device/external.d.ts.map +1 -0
  62. package/dist/src/device/index.d.ts.map +1 -0
  63. package/dist/src/{hardware/device → device}/payload.d.ts +1 -1
  64. package/dist/src/device/payload.d.ts.map +1 -0
  65. package/dist/src/errors.d.ts +3 -0
  66. package/dist/src/errors.d.ts.map +1 -1
  67. package/dist/src/framer/adapter.d.ts +2 -2
  68. package/dist/src/framer/adapter.d.ts.map +1 -1
  69. package/dist/src/framer/client.d.ts +8 -1
  70. package/dist/src/framer/client.d.ts.map +1 -1
  71. package/dist/src/framer/frame.d.ts +11 -5
  72. package/dist/src/framer/frame.d.ts.map +1 -1
  73. package/dist/src/framer/iterator.d.ts +3 -3
  74. package/dist/src/framer/streamer.d.ts +24 -21
  75. package/dist/src/framer/streamer.d.ts.map +1 -1
  76. package/dist/src/framer/writer.d.ts +13 -13
  77. package/dist/src/index.d.ts +6 -7
  78. package/dist/src/index.d.ts.map +1 -1
  79. package/dist/src/label/access.spec.d.ts +2 -0
  80. package/dist/src/label/access.spec.d.ts.map +1 -0
  81. package/dist/src/label/client.d.ts +20 -11
  82. package/dist/src/label/client.d.ts.map +1 -1
  83. package/dist/src/ontology/client.d.ts +6 -6
  84. package/dist/src/ontology/client.d.ts.map +1 -1
  85. package/dist/src/ontology/group/access.spec.d.ts +2 -0
  86. package/dist/src/ontology/group/access.spec.d.ts.map +1 -0
  87. package/dist/src/ontology/group/client.d.ts +2 -2
  88. package/dist/src/ontology/group/client.d.ts.map +1 -1
  89. package/dist/src/ontology/group/payload.d.ts +1 -2
  90. package/dist/src/ontology/group/payload.d.ts.map +1 -1
  91. package/dist/src/ontology/payload.d.ts +23 -17
  92. package/dist/src/ontology/payload.d.ts.map +1 -1
  93. package/dist/src/ontology/writer.d.ts +10 -10
  94. package/dist/src/ontology/writer.d.ts.map +1 -1
  95. package/dist/src/rack/access.spec.d.ts +2 -0
  96. package/dist/src/rack/access.spec.d.ts.map +1 -0
  97. package/dist/src/{hardware/rack → rack}/client.d.ts +15 -8
  98. package/dist/src/rack/client.d.ts.map +1 -0
  99. package/dist/src/rack/external.d.ts.map +1 -0
  100. package/dist/src/rack/index.d.ts.map +1 -0
  101. package/dist/src/{hardware/rack → rack}/payload.d.ts +1 -1
  102. package/dist/src/rack/payload.d.ts.map +1 -0
  103. package/dist/src/rack/rack.spec.d.ts.map +1 -0
  104. package/dist/src/ranger/access.spec.d.ts +2 -0
  105. package/dist/src/ranger/access.spec.d.ts.map +1 -0
  106. package/dist/src/ranger/alias.d.ts +1 -8
  107. package/dist/src/ranger/alias.d.ts.map +1 -1
  108. package/dist/src/ranger/client.d.ts +12 -5
  109. package/dist/src/ranger/client.d.ts.map +1 -1
  110. package/dist/src/ranger/kv.d.ts +0 -3
  111. package/dist/src/ranger/kv.d.ts.map +1 -1
  112. package/dist/src/ranger/writer.d.ts +2 -2
  113. package/dist/src/ranger/writer.d.ts.map +1 -1
  114. package/dist/src/status/access.spec.d.ts +2 -0
  115. package/dist/src/status/access.spec.d.ts.map +1 -0
  116. package/dist/src/status/client.d.ts +4 -4
  117. package/dist/src/status/client.d.ts.map +1 -1
  118. package/dist/src/status/payload.d.ts +9 -2
  119. package/dist/src/status/payload.d.ts.map +1 -1
  120. package/dist/src/task/access.spec.d.ts +2 -0
  121. package/dist/src/task/access.spec.d.ts.map +1 -0
  122. package/dist/src/{hardware/task → task}/client.d.ts +26 -15
  123. package/dist/src/task/client.d.ts.map +1 -0
  124. package/dist/src/task/external.d.ts +3 -0
  125. package/dist/src/task/external.d.ts.map +1 -0
  126. package/dist/src/task/index.d.ts.map +1 -0
  127. package/dist/src/{hardware/task → task}/payload.d.ts +45 -6
  128. package/dist/src/task/payload.d.ts.map +1 -0
  129. package/dist/src/task/task.spec.d.ts.map +1 -0
  130. package/dist/src/testutil/access.d.ts +4 -0
  131. package/dist/src/testutil/access.d.ts.map +1 -0
  132. package/dist/src/testutil/client.d.ts +3 -3
  133. package/dist/src/testutil/client.d.ts.map +1 -1
  134. package/dist/src/transport.d.ts.map +1 -1
  135. package/dist/src/user/access.spec.d.ts +2 -0
  136. package/dist/src/user/access.spec.d.ts.map +1 -0
  137. package/dist/src/user/client.d.ts +10 -1
  138. package/dist/src/user/client.d.ts.map +1 -1
  139. package/dist/src/user/external.d.ts +1 -1
  140. package/dist/src/user/external.d.ts.map +1 -1
  141. package/dist/src/user/payload.d.ts.map +1 -1
  142. package/dist/src/workspace/access.spec.d.ts +2 -0
  143. package/dist/src/workspace/access.spec.d.ts.map +1 -0
  144. package/dist/src/workspace/client.d.ts +10 -5
  145. package/dist/src/workspace/client.d.ts.map +1 -1
  146. package/dist/src/workspace/lineplot/access.spec.d.ts +2 -0
  147. package/dist/src/workspace/lineplot/access.spec.d.ts.map +1 -0
  148. package/dist/src/workspace/lineplot/client.d.ts +8 -1
  149. package/dist/src/workspace/lineplot/client.d.ts.map +1 -1
  150. package/dist/src/workspace/log/access.spec.d.ts +2 -0
  151. package/dist/src/workspace/log/access.spec.d.ts.map +1 -0
  152. package/dist/src/workspace/log/client.d.ts +8 -1
  153. package/dist/src/workspace/log/client.d.ts.map +1 -1
  154. package/dist/src/workspace/schematic/access.spec.d.ts +2 -0
  155. package/dist/src/workspace/schematic/access.spec.d.ts.map +1 -0
  156. package/dist/src/workspace/schematic/client.d.ts +8 -1
  157. package/dist/src/workspace/schematic/client.d.ts.map +1 -1
  158. package/dist/src/workspace/schematic/symbol/access.spec.d.ts +2 -0
  159. package/dist/src/workspace/schematic/symbol/access.spec.d.ts.map +1 -0
  160. package/dist/src/workspace/schematic/symbol/client.d.ts +1 -5
  161. package/dist/src/workspace/schematic/symbol/client.d.ts.map +1 -1
  162. package/dist/src/workspace/schematic/symbol/payload.d.ts +2 -2
  163. package/dist/src/workspace/table/access.spec.d.ts +2 -0
  164. package/dist/src/workspace/table/access.spec.d.ts.map +1 -0
  165. package/dist/src/workspace/table/client.d.ts +8 -1
  166. package/dist/src/workspace/table/client.d.ts.map +1 -1
  167. package/eslint.config.ts +3 -1
  168. package/package.json +8 -8
  169. package/src/access/client.ts +5 -2
  170. package/src/access/enforce.spec.ts +189 -0
  171. package/src/access/enforce.ts +84 -0
  172. package/src/access/external.ts +3 -0
  173. package/src/access/payload.ts +1 -13
  174. package/src/access/policy/access.spec.ts +147 -0
  175. package/src/access/policy/client.ts +21 -25
  176. package/src/access/policy/payload.ts +9 -5
  177. package/src/access/role/client.ts +135 -0
  178. package/src/access/role/external.ts +11 -0
  179. package/src/{hardware → access/role}/index.ts +1 -1
  180. package/src/access/role/payload.ts +32 -0
  181. package/src/access/role/role.spec.ts +95 -0
  182. package/src/arc/access.spec.ts +143 -0
  183. package/src/arc/client.ts +7 -31
  184. package/src/arc/payload.ts +4 -0
  185. package/src/auth/auth.spec.ts +13 -13
  186. package/src/auth/auth.ts +33 -11
  187. package/src/channel/access.spec.ts +116 -0
  188. package/src/channel/channel.spec.ts +63 -73
  189. package/src/channel/client.ts +2 -8
  190. package/src/channel/payload.spec.ts +171 -0
  191. package/src/channel/payload.ts +37 -8
  192. package/src/channel/retriever.ts +10 -11
  193. package/src/channel/writer.ts +3 -7
  194. package/src/client.ts +38 -28
  195. package/src/connection/checker.ts +10 -10
  196. package/src/connection/connection.spec.ts +13 -13
  197. package/src/connection.spec.ts +145 -0
  198. package/src/device/access.spec.ts +159 -0
  199. package/src/{hardware/device → device}/client.ts +12 -21
  200. package/src/{hardware/device → device}/device.spec.ts +70 -34
  201. package/src/device/external.ts +11 -0
  202. package/src/{hardware/rack → device}/index.ts +1 -1
  203. package/src/{hardware/device → device}/payload.ts +3 -3
  204. package/src/errors.ts +2 -0
  205. package/src/framer/adapter.spec.ts +351 -13
  206. package/src/framer/adapter.ts +23 -13
  207. package/src/framer/client.spec.ts +14 -20
  208. package/src/framer/client.ts +3 -5
  209. package/src/framer/deleter.spec.ts +1 -1
  210. package/src/framer/frame.spec.ts +427 -0
  211. package/src/framer/frame.ts +30 -3
  212. package/src/framer/iterator.ts +4 -4
  213. package/src/framer/streamer.spec.ts +155 -10
  214. package/src/framer/streamer.ts +35 -12
  215. package/src/framer/writer.spec.ts +5 -5
  216. package/src/index.ts +13 -7
  217. package/src/label/access.spec.ts +109 -0
  218. package/src/label/client.ts +10 -14
  219. package/src/ontology/client.ts +4 -6
  220. package/src/ontology/group/access.spec.ts +77 -0
  221. package/src/ontology/group/client.ts +3 -7
  222. package/src/ontology/group/group.spec.ts +18 -0
  223. package/src/ontology/group/payload.ts +2 -2
  224. package/src/ontology/ontology.spec.ts +2 -0
  225. package/src/ontology/payload.ts +18 -2
  226. package/src/ontology/writer.ts +3 -7
  227. package/src/rack/access.spec.ts +102 -0
  228. package/src/{hardware/rack → rack}/client.ts +14 -19
  229. package/src/{hardware/device/index.ts → rack/external.ts} +2 -1
  230. package/src/{hardware/external.ts → rack/index.ts} +1 -1
  231. package/src/{hardware/rack → rack}/payload.ts +2 -2
  232. package/src/{hardware/rack → rack}/rack.spec.ts +43 -17
  233. package/src/ranger/access.spec.ts +115 -0
  234. package/src/ranger/alias.ts +6 -14
  235. package/src/ranger/client.ts +13 -14
  236. package/src/ranger/kv.ts +7 -9
  237. package/src/ranger/ranger.spec.ts +4 -4
  238. package/src/ranger/writer.ts +3 -7
  239. package/src/status/access.spec.ts +129 -0
  240. package/src/status/client.ts +5 -9
  241. package/src/status/payload.ts +3 -2
  242. package/src/task/access.spec.ts +131 -0
  243. package/src/{hardware/task → task}/client.ts +50 -25
  244. package/src/task/external.ts +11 -0
  245. package/src/{hardware/task → task}/index.ts +1 -1
  246. package/src/{hardware/task → task}/payload.ts +22 -3
  247. package/src/{hardware/task → task}/task.spec.ts +197 -34
  248. package/src/testutil/access.ts +34 -0
  249. package/src/testutil/channels.ts +3 -3
  250. package/src/testutil/client.ts +4 -4
  251. package/src/transport.ts +1 -3
  252. package/src/user/access.spec.ts +107 -0
  253. package/src/user/client.ts +10 -12
  254. package/src/user/external.ts +12 -1
  255. package/src/user/payload.ts +3 -5
  256. package/src/workspace/access.spec.ts +108 -0
  257. package/src/workspace/client.ts +11 -27
  258. package/src/workspace/lineplot/access.spec.ts +134 -0
  259. package/src/workspace/lineplot/client.ts +8 -13
  260. package/src/workspace/log/access.spec.ts +134 -0
  261. package/src/workspace/log/client.ts +8 -13
  262. package/src/workspace/schematic/access.spec.ts +134 -0
  263. package/src/workspace/schematic/client.ts +9 -18
  264. package/src/workspace/schematic/symbol/access.spec.ts +172 -0
  265. package/src/workspace/schematic/symbol/client.ts +6 -17
  266. package/src/workspace/schematic/symbol/payload.ts +1 -1
  267. package/src/workspace/table/access.spec.ts +134 -0
  268. package/src/workspace/table/client.ts +8 -13
  269. package/dist/src/access/policy/policy.spec.d.ts +0 -2
  270. package/dist/src/access/policy/policy.spec.d.ts.map +0 -1
  271. package/dist/src/hardware/client.d.ts +0 -10
  272. package/dist/src/hardware/client.d.ts.map +0 -1
  273. package/dist/src/hardware/device/client.d.ts.map +0 -1
  274. package/dist/src/hardware/device/device.spec.d.ts.map +0 -1
  275. package/dist/src/hardware/device/external.d.ts.map +0 -1
  276. package/dist/src/hardware/device/index.d.ts.map +0 -1
  277. package/dist/src/hardware/device/payload.d.ts.map +0 -1
  278. package/dist/src/hardware/external.d.ts +0 -2
  279. package/dist/src/hardware/external.d.ts.map +0 -1
  280. package/dist/src/hardware/index.d.ts +0 -2
  281. package/dist/src/hardware/index.d.ts.map +0 -1
  282. package/dist/src/hardware/rack/client.d.ts.map +0 -1
  283. package/dist/src/hardware/rack/external.d.ts.map +0 -1
  284. package/dist/src/hardware/rack/index.d.ts.map +0 -1
  285. package/dist/src/hardware/rack/payload.d.ts.map +0 -1
  286. package/dist/src/hardware/rack/rack.spec.d.ts.map +0 -1
  287. package/dist/src/hardware/task/client.d.ts.map +0 -1
  288. package/dist/src/hardware/task/external.d.ts.map +0 -1
  289. package/dist/src/hardware/task/index.d.ts.map +0 -1
  290. package/dist/src/hardware/task/payload.d.ts.map +0 -1
  291. package/dist/src/hardware/task/task.spec.d.ts.map +0 -1
  292. package/dist/src/user/retriever.d.ts +0 -16
  293. package/dist/src/user/retriever.d.ts.map +0 -1
  294. package/dist/src/user/writer.d.ts +0 -11
  295. package/dist/src/user/writer.d.ts.map +0 -1
  296. package/src/access/policy/policy.spec.ts +0 -329
  297. package/src/hardware/client.ts +0 -24
  298. package/src/hardware/device/external.ts +0 -11
  299. package/src/hardware/rack/external.ts +0 -11
  300. package/src/hardware/task/external.ts +0 -11
  301. package/src/user/retriever.ts +0 -41
  302. package/src/user/writer.ts +0 -84
  303. /package/dist/src/{hardware/device → access/role}/external.d.ts +0 -0
  304. /package/dist/src/{hardware/device → device}/device.spec.d.ts +0 -0
  305. /package/dist/src/{hardware/rack → device}/external.d.ts +0 -0
  306. /package/dist/src/{hardware/device → device}/index.d.ts +0 -0
  307. /package/dist/src/{hardware/task → rack}/external.d.ts +0 -0
  308. /package/dist/src/{hardware/rack → rack}/index.d.ts +0 -0
  309. /package/dist/src/{hardware/rack → rack}/rack.spec.d.ts +0 -0
  310. /package/dist/src/{hardware/task → task}/index.d.ts +0 -0
  311. /package/dist/src/{hardware/task → task}/task.spec.d.ts +0 -0
@@ -23,12 +23,10 @@ import { Frame } from "@/framer/frame";
23
23
  import { AUTO_SPAN, Iterator, type IteratorConfig } from "@/framer/iterator";
24
24
  import { openStreamer, type Streamer, type StreamerConfig } from "@/framer/streamer";
25
25
  import { Writer, type WriterConfig, WriterMode } from "@/framer/writer";
26
- import { type ontology } from "@/ontology";
26
+ import { ontology } from "@/ontology";
27
27
 
28
- export const ontologyID = (key: channel.Key): ontology.ID => ({
29
- type: "framer",
30
- key: key.toString(),
31
- });
28
+ export const ontologyID = ontology.createIDFactory<string>("framer");
29
+ export const TYPE_ONTOLOGY_ID = ontologyID("");
32
30
 
33
31
  export class Client {
34
32
  private readonly streamClient: WebSocketClient;
@@ -58,7 +58,7 @@ describe("Deleter", () => {
58
58
  });
59
59
 
60
60
  await expect(
61
- client.delete(["billy bob", dataCh.name], TimeRange.MAX),
61
+ client.delete(["nonexistent_channel_name", dataCh.name], TimeRange.MAX),
62
62
  ).rejects.toThrow(NotFoundError);
63
63
 
64
64
  const res = await client.read(TimeRange.MAX, dataCh.key);
@@ -543,4 +543,431 @@ describe("framer.Frame", () => {
543
543
  expect(digest[13][0]).toEqual(s3.digest);
544
544
  });
545
545
  });
546
+
547
+ describe("forEachUnique", () => {
548
+ it("should iterate over all unique columns in the frame", () => {
549
+ const f = new framer.Frame(
550
+ new Map([
551
+ [
552
+ 12,
553
+ [
554
+ new Series({
555
+ data: new Float32Array([1, 2, 3]),
556
+ timeRange: new TimeRange(1, 2),
557
+ }),
558
+ ],
559
+ ],
560
+ [
561
+ 13,
562
+ [
563
+ new Series({
564
+ data: new Float32Array([4, 5, 6]),
565
+ timeRange: new TimeRange(4, 6),
566
+ }),
567
+ ],
568
+ ],
569
+ [
570
+ 14,
571
+ [
572
+ new Series({
573
+ data: new Float32Array([7, 8, 9]),
574
+ timeRange: new TimeRange(7, 9),
575
+ }),
576
+ ],
577
+ ],
578
+ ]),
579
+ );
580
+ f.push(
581
+ 12,
582
+ new Series({
583
+ data: new Float32Array([10, 11, 12]),
584
+ timeRange: new TimeRange(10, 12),
585
+ }),
586
+ );
587
+ f.push(
588
+ 13,
589
+ new Series({
590
+ data: new Float32Array([13, 14, 15]),
591
+ timeRange: new TimeRange(13, 15),
592
+ }),
593
+ );
594
+ f.push(
595
+ 14,
596
+ new Series({
597
+ data: new Float32Array([7, 8, 9]),
598
+ timeRange: new TimeRange(7, 9),
599
+ }),
600
+ );
601
+ const firstValues = new Set<number>();
602
+ f.forEachUnique((_, ms) => {
603
+ firstValues.add(ms.at(0) as number);
604
+ });
605
+ expect(firstValues).toEqual(new Set([1, 4, 7]));
606
+ });
607
+ it("should get all data from the frame", () => {
608
+ const f = new framer.Frame(
609
+ new Map([
610
+ [
611
+ 12,
612
+ [
613
+ new Series({
614
+ data: new Float32Array([1, 2, 3]),
615
+ timeRange: new TimeRange(1, 2),
616
+ }),
617
+ ],
618
+ ],
619
+ ]),
620
+ );
621
+ f.push(
622
+ 12,
623
+ new Series({
624
+ data: new Float32Array([10, 11, 12]),
625
+ timeRange: new TimeRange(10, 12),
626
+ }),
627
+ );
628
+ f.push(
629
+ 13,
630
+ new Series({
631
+ data: new Float32Array([13, 14, 15]),
632
+ timeRange: new TimeRange(13, 15),
633
+ }),
634
+ );
635
+ const data: number[] = [];
636
+ f.forEachUnique((key, ms) => {
637
+ if (key !== 12) return;
638
+ for (let i = 0; i < ms.length; i++) data.push(ms.at(i, true) as number);
639
+ });
640
+ expect(data).toEqual([1, 2, 3, 10, 11, 12]);
641
+ });
642
+ it("should allow use of an index parameter", () => {
643
+ const f = new framer.Frame(
644
+ new Map([
645
+ [
646
+ 12,
647
+ [
648
+ new Series({
649
+ data: new Float32Array([1, 2, 3]),
650
+ timeRange: new TimeRange(1, 2),
651
+ }),
652
+ ],
653
+ ],
654
+ ]),
655
+ );
656
+ f.push(
657
+ 12,
658
+ new Series({
659
+ data: new Float32Array([10, 11, 12]),
660
+ timeRange: new TimeRange(10, 12),
661
+ }),
662
+ );
663
+ f.push(
664
+ 13,
665
+ new Series({
666
+ data: new Float32Array([13, 14, 15]),
667
+ timeRange: new TimeRange(13, 15),
668
+ }),
669
+ );
670
+ let currentIndex = 0;
671
+ f.forEachUnique((_, __, i) => {
672
+ expect(i).toEqual(currentIndex);
673
+ currentIndex++;
674
+ });
675
+ expect(currentIndex).toEqual(2);
676
+ });
677
+ });
678
+ describe("mapFilter", () => {
679
+ it("should filter out items based on the keep boolean", () => {
680
+ const f = new framer.Frame(
681
+ new Map([
682
+ [
683
+ 12,
684
+ [
685
+ new Series({
686
+ data: new Float32Array([1, 2, 3]),
687
+ timeRange: new TimeRange(40, 50000),
688
+ }),
689
+ ],
690
+ ],
691
+ [
692
+ 13,
693
+ [
694
+ new Series({
695
+ data: new Float32Array([4, 5, 6]),
696
+ timeRange: new TimeRange(500, 50001),
697
+ }),
698
+ ],
699
+ ],
700
+ [
701
+ 14,
702
+ [
703
+ new Series({
704
+ data: new Float32Array([7, 8, 9]),
705
+ timeRange: new TimeRange(600, 60000),
706
+ }),
707
+ ],
708
+ ],
709
+ ]),
710
+ );
711
+ const filtered = f.mapFilter((k, arr) => [k, arr, k !== 13]);
712
+ expect(filtered.columns).toEqual([12, 14]);
713
+ expect(filtered.series.length).toEqual(2);
714
+ });
715
+
716
+ it("should map keys to new values", () => {
717
+ const f = new framer.Frame(
718
+ new Map([
719
+ [
720
+ 12,
721
+ [
722
+ new Series({
723
+ data: new Float32Array([1, 2, 3]),
724
+ timeRange: new TimeRange(40, 50000),
725
+ }),
726
+ ],
727
+ ],
728
+ [
729
+ 13,
730
+ [
731
+ new Series({
732
+ data: new Float32Array([4, 5, 6]),
733
+ timeRange: new TimeRange(500, 50001),
734
+ }),
735
+ ],
736
+ ],
737
+ ]),
738
+ );
739
+ const mapped = f.mapFilter((k, arr) => {
740
+ const newKey = typeof k === "number" ? k + 100 : k;
741
+ return [newKey, arr, true];
742
+ });
743
+ expect(mapped.columns).toEqual([112, 113]);
744
+ expect(mapped.series.length).toEqual(2);
745
+ });
746
+
747
+ it("should map series to new series", () => {
748
+ const f = new framer.Frame(
749
+ new Map([
750
+ [
751
+ 12,
752
+ [
753
+ new Series({
754
+ data: new Float32Array([1, 2, 3]),
755
+ timeRange: new TimeRange(40, 50000),
756
+ }),
757
+ ],
758
+ ],
759
+ ]),
760
+ );
761
+ const mapped = f.mapFilter((k, arr) => {
762
+ const newData = new Float32Array(arr.length);
763
+ for (let j = 0; j < arr.length; j++) newData[j] = (arr.at(j) as number) * 2;
764
+ const newArr = new Series({
765
+ data: newData,
766
+ timeRange: arr.timeRange,
767
+ });
768
+ return [k, newArr, true];
769
+ });
770
+ expect(mapped.get(12).at(0)).toEqual(2);
771
+ expect(mapped.get(12).at(1)).toEqual(4);
772
+ expect(mapped.get(12).at(2)).toEqual(6);
773
+ });
774
+
775
+ it("should both map and filter simultaneously", () => {
776
+ const f = new framer.Frame(
777
+ new Map([
778
+ [
779
+ 12,
780
+ [
781
+ new Series({
782
+ data: new Float32Array([1, 2, 3]),
783
+ timeRange: new TimeRange(40, 50000),
784
+ }),
785
+ ],
786
+ ],
787
+ [
788
+ 13,
789
+ [
790
+ new Series({
791
+ data: new Float32Array([4, 5, 6]),
792
+ timeRange: new TimeRange(500, 50001),
793
+ }),
794
+ ],
795
+ ],
796
+ [
797
+ 14,
798
+ [
799
+ new Series({
800
+ data: new Float32Array([7, 8, 9]),
801
+ timeRange: new TimeRange(600, 60000),
802
+ }),
803
+ ],
804
+ ],
805
+ ]),
806
+ );
807
+ const result = f.mapFilter((k, arr) => {
808
+ const keep = typeof k === "number" && k % 2 === 0;
809
+ const newKey = typeof k === "number" ? k + 1 : k;
810
+ return [newKey, arr, keep];
811
+ });
812
+ expect(result.columns).toEqual([13, 15]);
813
+ expect(result.series.length).toEqual(2);
814
+ });
815
+
816
+ it("should handle empty frames", () => {
817
+ const f = new framer.Frame();
818
+ const result = f.mapFilter((k, arr) => [k, arr, true]);
819
+ expect(result.columns).toEqual([]);
820
+ expect(result.series.length).toEqual(0);
821
+ });
822
+
823
+ it("should handle filtering out all items", () => {
824
+ const f = new framer.Frame(
825
+ new Map([
826
+ [
827
+ 12,
828
+ [
829
+ new Series({
830
+ data: new Float32Array([1, 2, 3]),
831
+ timeRange: new TimeRange(40, 50000),
832
+ }),
833
+ ],
834
+ ],
835
+ [
836
+ 13,
837
+ [
838
+ new Series({
839
+ data: new Float32Array([4, 5, 6]),
840
+ timeRange: new TimeRange(500, 50001),
841
+ }),
842
+ ],
843
+ ],
844
+ ]),
845
+ );
846
+ const result = f.mapFilter((k, arr) => [k, arr, false]);
847
+ expect(result.columns).toEqual([]);
848
+ expect(result.series.length).toEqual(0);
849
+ });
850
+
851
+ it("should keep all items when keep is always true", () => {
852
+ const f = new framer.Frame(
853
+ new Map([
854
+ [
855
+ 12,
856
+ [
857
+ new Series({
858
+ data: new Float32Array([1, 2, 3]),
859
+ timeRange: new TimeRange(40, 50000),
860
+ }),
861
+ ],
862
+ ],
863
+ [
864
+ 13,
865
+ [
866
+ new Series({
867
+ data: new Float32Array([4, 5, 6]),
868
+ timeRange: new TimeRange(500, 50001),
869
+ }),
870
+ ],
871
+ ],
872
+ ]),
873
+ );
874
+ const result = f.mapFilter((k, arr) => [k, arr, true]);
875
+ expect(result.columns).toEqual([12, 13]);
876
+ expect(result.series.length).toEqual(2);
877
+ });
878
+
879
+ it("should use the index parameter correctly", () => {
880
+ const f = new framer.Frame(
881
+ new Map([
882
+ [
883
+ 12,
884
+ [
885
+ new Series({
886
+ data: new Float32Array([1, 2, 3]),
887
+ timeRange: new TimeRange(40, 50000),
888
+ }),
889
+ ],
890
+ ],
891
+ [
892
+ 13,
893
+ [
894
+ new Series({
895
+ data: new Float32Array([4, 5, 6]),
896
+ timeRange: new TimeRange(500, 50001),
897
+ }),
898
+ ],
899
+ ],
900
+ [
901
+ 14,
902
+ [
903
+ new Series({
904
+ data: new Float32Array([7, 8, 9]),
905
+ timeRange: new TimeRange(600, 60000),
906
+ }),
907
+ ],
908
+ ],
909
+ ]),
910
+ );
911
+ // Keep only items at even indices
912
+ const result = f.mapFilter((k, arr, i) => [k, arr, i % 2 === 0]);
913
+ expect(result.columns).toEqual([12, 14]);
914
+ expect(result.series.length).toEqual(2);
915
+ });
916
+
917
+ it("should work with string keys", () => {
918
+ const f = new framer.Frame({
919
+ a: new Series({
920
+ data: new Float32Array([1, 2, 3]),
921
+ timeRange: new TimeRange(40, 50000),
922
+ }),
923
+ b: new Series({
924
+ data: new Float32Array([4, 5, 6]),
925
+ timeRange: new TimeRange(500, 50001),
926
+ }),
927
+ c: new Series({
928
+ data: new Float32Array([7, 8, 9]),
929
+ timeRange: new TimeRange(600, 60000),
930
+ }),
931
+ });
932
+ const result = f.mapFilter((k, arr) => {
933
+ const newKey = k === "a" ? "x" : k;
934
+ const keep = k === "a" || k === "c";
935
+ return [newKey, arr, keep];
936
+ });
937
+ expect(result.columns).toEqual(["x", "c"]);
938
+ expect(result.series.length).toEqual(2);
939
+ });
940
+
941
+ it("should handle frames with multiple series per channel", () => {
942
+ const f = new framer.Frame(
943
+ new Map([
944
+ [
945
+ 12,
946
+ [
947
+ new Series({
948
+ data: new Float32Array([1, 2, 3]),
949
+ timeRange: new TimeRange(40, 50000),
950
+ }),
951
+ new Series({
952
+ data: new Float32Array([4, 5, 6]),
953
+ timeRange: new TimeRange(50001, 60000),
954
+ }),
955
+ ],
956
+ ],
957
+ [
958
+ 13,
959
+ [
960
+ new Series({
961
+ data: new Float32Array([7, 8, 9]),
962
+ timeRange: new TimeRange(500, 50001),
963
+ }),
964
+ ],
965
+ ],
966
+ ]),
967
+ );
968
+ const result = f.mapFilter((k, arr) => [k, arr, k === 12]);
969
+ expect(result.columns).toEqual([12, 12]);
970
+ expect(result.series.length).toEqual(2);
971
+ });
972
+ });
546
973
  });
@@ -305,7 +305,11 @@ export class Frame {
305
305
 
306
306
  push(keyOrFrame: channel.KeyOrName | Frame, ...v: Series[]): void {
307
307
  if (keyOrFrame instanceof Frame) {
308
- if (this.colType !== null && keyOrFrame.colType !== this.colType)
308
+ if (
309
+ keyOrFrame.colType != null &&
310
+ this.colType !== null &&
311
+ keyOrFrame.colType !== this.colType
312
+ )
309
313
  throw new ValidationError("keyVariant must match");
310
314
  this.series.push(...keyOrFrame.series);
311
315
  (this.columns as channel.Keys).push(...(keyOrFrame.columns as channel.Keys));
@@ -355,6 +359,21 @@ export class Frame {
355
359
  return frame;
356
360
  }
357
361
 
362
+ mapFilter(
363
+ fn: (
364
+ k: channel.KeyOrName,
365
+ arr: Series,
366
+ i: number,
367
+ ) => [channel.KeyOrName, Series, boolean],
368
+ ): Frame {
369
+ const frame = new Frame();
370
+ this.forEach((k, arr, i) => {
371
+ const [newK, newArr, keep] = fn(k, arr, i);
372
+ if (keep) frame.push(newK, newArr);
373
+ });
374
+ return frame;
375
+ }
376
+
358
377
  /**
359
378
  * Iterates over all series in the current frame.
360
379
  *
@@ -367,6 +386,14 @@ export class Frame {
367
386
  });
368
387
  }
369
388
 
389
+ /**
390
+ * Iterates over all unique columns in the frame.
391
+ * @param fn a function that takes a channel key, multi-series, and index.
392
+ */
393
+ forEachUnique(fn: (k: channel.KeyOrName, ms: MultiSeries, i: number) => void): void {
394
+ this.uniqueColumns.forEach((k, i) => fn(k, this.get(k), i));
395
+ }
396
+
370
397
  at(index: number, required: true): Record<channel.KeyOrName, TelemValue>;
371
398
 
372
399
  at(
@@ -438,11 +465,11 @@ export class Frame {
438
465
  export const frameZ = z.object({
439
466
  keys: z.union([
440
467
  z.null().transform<number[]>(() => []),
441
- z.number().array().optional().default([]),
468
+ z.number().array().default([]),
442
469
  ]),
443
470
  series: z.union([
444
471
  z.null().transform<z.infer<typeof Series.crudeZ>[]>(() => []),
445
- Series.crudeZ.array().optional().default([]),
472
+ Series.crudeZ.array().default([]),
446
473
  ]),
447
474
  });
448
475
 
@@ -111,7 +111,7 @@ export class Iterator {
111
111
  const iter = new Iterator(stream, adapter);
112
112
  await iter.execute({
113
113
  command: Command.Open,
114
- keys: adapter.keys,
114
+ keys: Array.from(adapter.keys),
115
115
  bounds: new TimeRange(tr),
116
116
  chunkSize: opts.chunkSize ?? 1e5,
117
117
  });
@@ -196,9 +196,9 @@ export class Iterator {
196
196
  }
197
197
 
198
198
  /**
199
- * @returns true if the iterator value contains a valid segment, and fale otherwise.
200
- * valid most commonly returns false when the iterator is exhausted or has
201
- * accumulated an error.
199
+ * @returns true if the iterator value contains a valid segment, and false otherwise.
200
+ * valid most commonly returns false when the iterator is exhausted or has accumulated
201
+ * an error.
202
202
  */
203
203
  async valid(): Promise<boolean> {
204
204
  return await this.execute({ command: Command.Valid });