@robdobsn/raftjs 1.8.5 → 1.11.5

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 (240) hide show
  1. package/.editorconfig +14 -0
  2. package/.gitattributes +11 -0
  3. package/.nvmrc +1 -0
  4. package/TODO.md +1 -0
  5. package/dist/react-native/RaftAttributeHandler.d.ts +14 -0
  6. package/dist/react-native/RaftAttributeHandler.js +375 -0
  7. package/dist/react-native/RaftAttributeHandler.js.map +1 -0
  8. package/dist/react-native/RaftChannel.d.ts +20 -0
  9. package/dist/react-native/RaftChannel.js +12 -0
  10. package/dist/react-native/RaftChannel.js.map +1 -0
  11. package/dist/react-native/RaftChannelBLE.native.d.ts +95 -0
  12. package/dist/react-native/RaftChannelBLE.native.js +483 -0
  13. package/dist/react-native/RaftChannelBLE.native.js.map +1 -0
  14. package/dist/react-native/RaftChannelBLE.web.d.ts +40 -0
  15. package/dist/react-native/RaftChannelBLE.web.js +302 -0
  16. package/dist/react-native/RaftChannelBLE.web.js.map +1 -0
  17. package/dist/react-native/RaftChannelBLEFactory.d.ts +10 -0
  18. package/dist/react-native/RaftChannelBLEFactory.js +17 -0
  19. package/dist/react-native/RaftChannelBLEFactory.js.map +1 -0
  20. package/dist/react-native/RaftChannelBLEScanner.native.d.ts +18 -0
  21. package/dist/react-native/RaftChannelBLEScanner.native.js +138 -0
  22. package/dist/react-native/RaftChannelBLEScanner.native.js.map +1 -0
  23. package/dist/react-native/RaftChannelSimulated.d.ts +42 -0
  24. package/dist/react-native/RaftChannelSimulated.js +1001 -0
  25. package/dist/react-native/RaftChannelSimulated.js.map +1 -0
  26. package/dist/react-native/RaftChannelWebSerial.d.ts +39 -0
  27. package/dist/react-native/RaftChannelWebSerial.js +329 -0
  28. package/dist/react-native/RaftChannelWebSerial.js.map +1 -0
  29. package/dist/react-native/RaftChannelWebSocket.d.ts +30 -0
  30. package/dist/react-native/RaftChannelWebSocket.js +222 -0
  31. package/dist/react-native/RaftChannelWebSocket.js.map +1 -0
  32. package/dist/react-native/RaftCommsStats.d.ts +39 -0
  33. package/dist/react-native/RaftCommsStats.js +128 -0
  34. package/dist/react-native/RaftCommsStats.js.map +1 -0
  35. package/dist/react-native/RaftConnEvents.d.ts +39 -0
  36. package/dist/react-native/RaftConnEvents.js +54 -0
  37. package/dist/react-native/RaftConnEvents.js.map +1 -0
  38. package/dist/react-native/RaftConnector.d.ts +257 -0
  39. package/dist/react-native/RaftConnector.js +671 -0
  40. package/dist/react-native/RaftConnector.js.map +1 -0
  41. package/dist/react-native/RaftCustomAttrHandler.d.ts +6 -0
  42. package/dist/react-native/RaftCustomAttrHandler.js +93 -0
  43. package/dist/react-native/RaftCustomAttrHandler.js.map +1 -0
  44. package/dist/react-native/RaftDeviceInfo.d.ts +71 -0
  45. package/dist/react-native/RaftDeviceInfo.js +50 -0
  46. package/dist/react-native/RaftDeviceInfo.js.map +1 -0
  47. package/dist/react-native/RaftDeviceManager.d.ts +73 -0
  48. package/dist/react-native/RaftDeviceManager.js +812 -0
  49. package/dist/react-native/RaftDeviceManager.js.map +1 -0
  50. package/dist/react-native/RaftDeviceMgrIF.d.ts +19 -0
  51. package/dist/react-native/RaftDeviceMgrIF.js +11 -0
  52. package/dist/react-native/RaftDeviceMgrIF.js.map +1 -0
  53. package/dist/react-native/RaftDeviceMsg.d.ts +9 -0
  54. package/dist/react-native/RaftDeviceMsg.js +11 -0
  55. package/dist/react-native/RaftDeviceMsg.js.map +1 -0
  56. package/dist/react-native/RaftDeviceStates.d.ts +55 -0
  57. package/dist/react-native/RaftDeviceStates.js +81 -0
  58. package/dist/react-native/RaftDeviceStates.js.map +1 -0
  59. package/dist/react-native/RaftFileHandler.d.ts +52 -0
  60. package/dist/react-native/RaftFileHandler.js +502 -0
  61. package/dist/react-native/RaftFileHandler.js.map +1 -0
  62. package/dist/react-native/RaftLog.d.ts +22 -0
  63. package/dist/react-native/RaftLog.js +63 -0
  64. package/dist/react-native/RaftLog.js.map +1 -0
  65. package/dist/react-native/RaftMiniHDLC.d.ts +18 -0
  66. package/dist/react-native/RaftMiniHDLC.js +383 -0
  67. package/dist/react-native/RaftMiniHDLC.js.map +1 -0
  68. package/dist/react-native/RaftMsgHandler.d.ts +62 -0
  69. package/dist/react-native/RaftMsgHandler.js +511 -0
  70. package/dist/react-native/RaftMsgHandler.js.map +1 -0
  71. package/dist/react-native/RaftMsgTrackInfo.d.ts +17 -0
  72. package/dist/react-native/RaftMsgTrackInfo.js +42 -0
  73. package/dist/react-native/RaftMsgTrackInfo.js.map +1 -0
  74. package/dist/react-native/RaftProtocolDefs.d.ts +30 -0
  75. package/dist/react-native/RaftProtocolDefs.js +48 -0
  76. package/dist/react-native/RaftProtocolDefs.js.map +1 -0
  77. package/dist/react-native/RaftPublish.d.ts +2 -0
  78. package/dist/react-native/RaftPublish.js +81 -0
  79. package/dist/react-native/RaftPublish.js.map +1 -0
  80. package/dist/react-native/RaftStreamHandler.d.ts +49 -0
  81. package/dist/react-native/RaftStreamHandler.js +324 -0
  82. package/dist/react-native/RaftStreamHandler.js.map +1 -0
  83. package/dist/react-native/RaftStruct.d.ts +3 -0
  84. package/dist/react-native/RaftStruct.js +258 -0
  85. package/dist/react-native/RaftStruct.js.map +1 -0
  86. package/dist/react-native/RaftSysTypeManager.d.ts +16 -0
  87. package/dist/react-native/RaftSysTypeManager.js +78 -0
  88. package/dist/react-native/RaftSysTypeManager.js.map +1 -0
  89. package/dist/react-native/RaftSystemType.d.ts +30 -0
  90. package/dist/react-native/RaftSystemType.js +3 -0
  91. package/dist/react-native/RaftSystemType.js.map +1 -0
  92. package/dist/react-native/RaftSystemUtils.d.ts +152 -0
  93. package/dist/react-native/RaftSystemUtils.js +463 -0
  94. package/dist/react-native/RaftSystemUtils.js.map +1 -0
  95. package/dist/react-native/RaftTypes.d.ts +216 -0
  96. package/dist/react-native/RaftTypes.js +153 -0
  97. package/dist/react-native/RaftTypes.js.map +1 -0
  98. package/dist/react-native/RaftUpdateEvents.d.ts +33 -0
  99. package/dist/react-native/RaftUpdateEvents.js +46 -0
  100. package/dist/react-native/RaftUpdateEvents.js.map +1 -0
  101. package/dist/react-native/RaftUpdateManager.d.ts +61 -0
  102. package/dist/react-native/RaftUpdateManager.js +621 -0
  103. package/dist/react-native/RaftUpdateManager.js.map +1 -0
  104. package/dist/react-native/RaftUtils.d.ts +128 -0
  105. package/dist/react-native/RaftUtils.js +487 -0
  106. package/dist/react-native/RaftUtils.js.map +1 -0
  107. package/dist/react-native/RaftWifiTypes.d.ts +23 -0
  108. package/dist/react-native/RaftWifiTypes.js +43 -0
  109. package/dist/react-native/RaftWifiTypes.js.map +1 -0
  110. package/dist/react-native/main.d.ts +27 -0
  111. package/dist/react-native/main.js +52 -0
  112. package/dist/react-native/main.js.map +1 -0
  113. package/dist/web/RaftAttributeHandler.js +1 -1
  114. package/dist/web/RaftAttributeHandler.js.map +1 -1
  115. package/dist/web/RaftChannelBLE.web.js +8 -6
  116. package/dist/web/RaftChannelBLE.web.js.map +1 -1
  117. package/dist/web/RaftChannelSimulated.d.ts +10 -0
  118. package/dist/web/RaftChannelSimulated.js +665 -82
  119. package/dist/web/RaftChannelSimulated.js.map +1 -1
  120. package/dist/web/RaftChannelWebSerial.js +2 -2
  121. package/dist/web/RaftChannelWebSerial.js.map +1 -1
  122. package/dist/web/RaftChannelWebSocket.js +16 -1
  123. package/dist/web/RaftChannelWebSocket.js.map +1 -1
  124. package/dist/web/RaftConnector.d.ts +12 -1
  125. package/dist/web/RaftConnector.js +45 -9
  126. package/dist/web/RaftConnector.js.map +1 -1
  127. package/dist/web/RaftCustomAttrHandler.d.ts +2 -0
  128. package/dist/web/RaftCustomAttrHandler.js +54 -26
  129. package/dist/web/RaftCustomAttrHandler.js.map +1 -1
  130. package/dist/web/RaftDeviceInfo.d.ts +3 -1
  131. package/dist/web/RaftDeviceInfo.js +17 -3
  132. package/dist/web/RaftDeviceInfo.js.map +1 -1
  133. package/dist/web/RaftDeviceManager.d.ts +32 -2
  134. package/dist/web/RaftDeviceManager.js +307 -74
  135. package/dist/web/RaftDeviceManager.js.map +1 -1
  136. package/dist/web/RaftDeviceMgrIF.d.ts +5 -1
  137. package/dist/web/RaftDeviceStates.d.ts +20 -2
  138. package/dist/web/RaftDeviceStates.js +25 -4
  139. package/dist/web/RaftDeviceStates.js.map +1 -1
  140. package/dist/web/RaftMsgHandler.js.map +1 -1
  141. package/dist/web/RaftPublish.d.ts +2 -0
  142. package/dist/web/RaftPublish.js +81 -0
  143. package/dist/web/RaftPublish.js.map +1 -0
  144. package/dist/web/RaftStreamHandler.d.ts +11 -0
  145. package/dist/web/RaftStreamHandler.js +68 -1
  146. package/dist/web/RaftStreamHandler.js.map +1 -1
  147. package/dist/web/RaftStruct.js +197 -147
  148. package/dist/web/RaftStruct.js.map +1 -1
  149. package/dist/web/RaftSystemUtils.d.ts +17 -1
  150. package/dist/web/RaftSystemUtils.js +51 -0
  151. package/dist/web/RaftSystemUtils.js.map +1 -1
  152. package/dist/web/RaftTypes.d.ts +21 -0
  153. package/dist/web/RaftTypes.js.map +1 -1
  154. package/dist/web/RaftUpdateManager.js +1 -1
  155. package/dist/web/RaftUpdateManager.js.map +1 -1
  156. package/dist/web/RaftUtils.d.ts +2 -0
  157. package/dist/web/RaftUtils.js +20 -0
  158. package/dist/web/RaftUtils.js.map +1 -1
  159. package/dist/web/main.d.ts +2 -0
  160. package/dist/web/main.js +1 -0
  161. package/dist/web/main.js.map +1 -1
  162. package/eslint.config.mjs +33 -0
  163. package/examples/dashboard/package.json +36 -0
  164. package/examples/dashboard/src/CommandPanel.tsx +147 -0
  165. package/examples/dashboard/src/ConnManager.ts +166 -0
  166. package/examples/dashboard/src/DeviceActionsForm.tsx +133 -0
  167. package/examples/dashboard/src/DeviceAttrsForm.tsx +49 -0
  168. package/examples/dashboard/src/DeviceLineChart.tsx +163 -0
  169. package/examples/dashboard/src/DevicePanel.tsx +247 -0
  170. package/examples/dashboard/src/DeviceStatsPanel.tsx +65 -0
  171. package/examples/dashboard/src/DevicesPanel.tsx +69 -0
  172. package/examples/dashboard/src/DispLedGrid.tsx +110 -0
  173. package/examples/dashboard/src/DispOneLed.tsx +20 -0
  174. package/examples/dashboard/src/LatencyTest.ts +130 -0
  175. package/examples/dashboard/src/LatencyTestPanel.tsx +92 -0
  176. package/examples/dashboard/src/Main.tsx +234 -0
  177. package/examples/dashboard/src/SettingsManager.ts +67 -0
  178. package/examples/dashboard/src/SettingsScreen.tsx +179 -0
  179. package/examples/dashboard/src/StatusPanel.tsx +71 -0
  180. package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +170 -0
  181. package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +125 -0
  182. package/examples/dashboard/src/SystemTypeGeneric/StateInfoGeneric.ts +38 -0
  183. package/examples/dashboard/src/SystemTypeGeneric/SystemTypeGeneric.ts +125 -0
  184. package/examples/dashboard/src/SystemTypeMarty/RICAddOn.ts +70 -0
  185. package/examples/dashboard/src/SystemTypeMarty/RICAddOnBase.ts +33 -0
  186. package/examples/dashboard/src/SystemTypeMarty/RICAddOnManager.ts +342 -0
  187. package/examples/dashboard/src/SystemTypeMarty/RICCommsStats.ts +170 -0
  188. package/examples/dashboard/src/SystemTypeMarty/RICHWElem.ts +123 -0
  189. package/examples/dashboard/src/SystemTypeMarty/RICLEDPatternChecker.ts +207 -0
  190. package/examples/dashboard/src/SystemTypeMarty/RICROSSerial.ts +464 -0
  191. package/examples/dashboard/src/SystemTypeMarty/RICServoFaultDetector.ts +146 -0
  192. package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +105 -0
  193. package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +371 -0
  194. package/examples/dashboard/src/SystemTypeMarty/RICTypes.ts +20 -0
  195. package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +119 -0
  196. package/examples/dashboard/src/index.html +15 -0
  197. package/examples/dashboard/src/index.tsx +13 -0
  198. package/examples/dashboard/src/styles.css +570 -0
  199. package/examples/dashboard/tsconfig.json +18 -0
  200. package/jest.config.js +11 -0
  201. package/package.json +49 -52
  202. package/src/RaftAttributeHandler.ts +450 -0
  203. package/src/RaftChannel.ts +32 -0
  204. package/src/RaftChannelBLE.native.ts +617 -0
  205. package/src/RaftChannelBLE.web.ts +374 -0
  206. package/src/RaftChannelBLEFactory.ts +13 -0
  207. package/src/RaftChannelBLEScanner.native.ts +184 -0
  208. package/src/RaftChannelSimulated.ts +1177 -0
  209. package/src/RaftChannelWebSerial.ts +420 -0
  210. package/src/RaftChannelWebSocket.ts +272 -0
  211. package/src/RaftCommsStats.ts +142 -0
  212. package/src/RaftConnEvents.ts +58 -0
  213. package/src/RaftConnector.ts +806 -0
  214. package/src/RaftCustomAttrHandler.ts +117 -0
  215. package/src/RaftDeviceInfo.ts +125 -0
  216. package/src/RaftDeviceManager.ts +1014 -0
  217. package/src/RaftDeviceMgrIF.ts +37 -0
  218. package/src/RaftDeviceMsg.ts +20 -0
  219. package/src/RaftDeviceStates.ts +122 -0
  220. package/src/RaftFileHandler.ts +668 -0
  221. package/src/RaftLog.ts +70 -0
  222. package/src/RaftMiniHDLC.ts +396 -0
  223. package/src/RaftMsgHandler.ts +812 -0
  224. package/src/RaftMsgTrackInfo.ts +51 -0
  225. package/src/RaftProtocolDefs.ts +46 -0
  226. package/src/RaftPublish.ts +92 -0
  227. package/src/RaftStreamHandler.ts +412 -0
  228. package/src/RaftStruct.ts +282 -0
  229. package/src/RaftSysTypeManager.ts +87 -0
  230. package/src/RaftSystemType.ts +34 -0
  231. package/src/RaftSystemUtils.ts +548 -0
  232. package/src/RaftTypes.ts +306 -0
  233. package/src/RaftUpdateEvents.ts +48 -0
  234. package/src/RaftUpdateManager.ts +781 -0
  235. package/src/RaftUtils.ts +514 -0
  236. package/src/RaftWifiTypes.ts +36 -0
  237. package/src/main.ts +40 -0
  238. package/testdata/TestDeviceTypeRecs.json +492 -0
  239. package/tsconfig.json +30 -0
  240. package/tsconfig.react-native.json +29 -0
@@ -0,0 +1,282 @@
1
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // RaftStruct
4
+ // Part of RaftJS
5
+ //
6
+ // Rob Dobson 2024
7
+ // (C) 2024 All rights reserved
8
+ //
9
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10
+
11
+ type FormatInstruction =
12
+ | { kind: "endian"; littleEndian: boolean }
13
+ | { kind: "spec"; code: string; repeat: number };
14
+
15
+ function parseFormatInstructions(format: string): FormatInstruction[] {
16
+ const instructions: FormatInstruction[] = [];
17
+ let idx = 0;
18
+
19
+ while (idx < format.length) {
20
+
21
+ const char = format[idx];
22
+
23
+ // Endianness specifiers
24
+ if (char === "<" || char === ">") {
25
+ instructions.push({ kind: "endian", littleEndian: char === "<" });
26
+ idx++;
27
+ continue;
28
+ }
29
+
30
+ // Ignore whitespace
31
+ if (/\s/.test(char)) {
32
+ idx++;
33
+ continue;
34
+ }
35
+
36
+ // Attribute code
37
+ const code = char;
38
+ idx++;
39
+
40
+ // Check for repeat count using [N] syntax
41
+ let repeat = 1;
42
+ if (idx < format.length && format[idx] === "[") {
43
+ const endIdx = format.indexOf("]", idx + 1);
44
+ if (endIdx === -1) {
45
+ throw new Error(`Invalid format string: missing closing ] in "${format}"`);
46
+ }
47
+ const repeatStr = format.slice(idx + 1, endIdx);
48
+ repeat = parseInt(repeatStr, 10);
49
+ if (!Number.isFinite(repeat) || repeat <= 0) {
50
+ throw new Error(`Invalid repeat count "${repeatStr}" in format string "${format}"`);
51
+ }
52
+ idx = endIdx + 1;
53
+ }
54
+
55
+ instructions.push({ kind: "spec", code, repeat });
56
+ }
57
+
58
+ return instructions;
59
+ }
60
+
61
+ export function structUnpack(format: string, data: Uint8Array): number[] {
62
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
63
+ const results: number[] = [];
64
+ let offset = 0;
65
+ let littleEndian = false;
66
+
67
+ const instructions = parseFormatInstructions(format);
68
+
69
+ for (const instruction of instructions) {
70
+ if (instruction.kind === "endian") {
71
+ littleEndian = instruction.littleEndian;
72
+ continue;
73
+ }
74
+
75
+ const { code, repeat } = instruction;
76
+
77
+ for (let count = 0; count < repeat; count++) {
78
+ switch (code) {
79
+ case "x": // Padding byte
80
+ offset += 1;
81
+ break;
82
+ case "c": // Char
83
+ case "B": // Unsigned 8-bit integer
84
+ case "?": // Boolean (stored as uint8)
85
+ results.push(view.getUint8(offset));
86
+ offset += 1;
87
+ break;
88
+ case "b": // Signed 8-bit integer
89
+ results.push(view.getInt8(offset));
90
+ offset += 1;
91
+ break;
92
+ case "h": // Signed 16-bit integer
93
+ results.push(view.getInt16(offset, littleEndian));
94
+ offset += 2;
95
+ break;
96
+ case "H": // Unsigned 16-bit integer
97
+ results.push(view.getUint16(offset, littleEndian));
98
+ offset += 2;
99
+ break;
100
+ case "i": // Signed 32-bit integer
101
+ case "l": // Signed 32-bit integer
102
+ results.push(view.getInt32(offset, littleEndian));
103
+ offset += 4;
104
+ break;
105
+ case "I": // Unsigned 32-bit integer
106
+ case "L": // Unsigned 32-bit integer
107
+ results.push(view.getUint32(offset, littleEndian));
108
+ offset += 4;
109
+ break;
110
+ // case "q": // Signed 64-bit integer
111
+ // results.push(Number(view.getBigInt64(offset, littleEndian)));
112
+ // offset += 8;
113
+ // break;
114
+ // case "Q": // Unsigned 64-bit integer
115
+ // results.push(Number(view.getBigUint64(offset, littleEndian)));
116
+ // offset += 8;
117
+ // break;
118
+ case "f": // 32-bit float
119
+ results.push(view.getFloat32(offset, littleEndian));
120
+ offset += 4;
121
+ break;
122
+ case "d": // 64-bit float
123
+ results.push(view.getFloat64(offset, littleEndian));
124
+ offset += 8;
125
+ break;
126
+ default:
127
+ throw new Error(`Unknown format character: ${code}`);
128
+ }
129
+ }
130
+ }
131
+
132
+ return results;
133
+ }
134
+
135
+ export function structSizeOf(format: string): number {
136
+ let size = 0;
137
+ const instructions = parseFormatInstructions(format);
138
+
139
+ for (const instruction of instructions) {
140
+ if (instruction.kind === "endian") {
141
+ continue;
142
+ }
143
+
144
+ const { code, repeat } = instruction;
145
+ let unitSize: number;
146
+
147
+ switch (code) {
148
+ case "x": // Padding byte
149
+ case "c": // Char
150
+ case "b": // Signed 8-bit integer
151
+ case "B": // Unsigned 8-bit integer
152
+ case "?": // Boolean (uint8)
153
+ unitSize = 1;
154
+ break;
155
+ case "h": // Signed 16-bit integer
156
+ case "H": // Unsigned 16-bit integer
157
+ unitSize = 2;
158
+ break;
159
+ case "i": // Signed 32-bit integer
160
+ case "I": // Unsigned 32-bit integer
161
+ case "l": // Signed 32-bit integer
162
+ case "L": // Unsigned 32-bit integer
163
+ unitSize = 4;
164
+ break;
165
+ // case "q": // Signed 64-bit integer
166
+ // case "Q": // Unsigned 64-bit integer
167
+ // unitSize = 8;
168
+ // break;
169
+ case "f": // 32-bit float
170
+ unitSize = 4;
171
+ break;
172
+ case "d": // 64-bit float
173
+ unitSize = 8;
174
+ break;
175
+ default:
176
+ throw new Error(`Unknown format character: ${code}`);
177
+ }
178
+
179
+ size += unitSize * repeat;
180
+ }
181
+ return size;
182
+ }
183
+
184
+ export function structPack(format: string, values: number[]): Uint8Array {
185
+ const size = structSizeOf(format);
186
+ const buffer = new ArrayBuffer(size);
187
+ const view = new DataView(buffer);
188
+ let offset = 0;
189
+ let littleEndian = false;
190
+
191
+ const instructions = parseFormatInstructions(format);
192
+ let valueIdx = 0;
193
+
194
+ for (const instruction of instructions) {
195
+ if (instruction.kind === "endian") {
196
+ littleEndian = instruction.littleEndian;
197
+ continue;
198
+ }
199
+
200
+ const { code, repeat } = instruction;
201
+
202
+ for (let count = 0; count < repeat; count++) {
203
+ switch (code) {
204
+ case "x": // Padding byte
205
+ offset += 1;
206
+ break;
207
+ case "c": // Char
208
+ case "b": // Signed 8-bit integer
209
+ if (valueIdx >= values.length) {
210
+ throw new Error("Insufficient values provided for structPack");
211
+ }
212
+ view.setInt8(offset, values[valueIdx++]);
213
+ offset += 1;
214
+ break;
215
+ case "B": // Unsigned 8-bit integer
216
+ case "?": // Boolean (uint8)
217
+ if (valueIdx >= values.length) {
218
+ throw new Error("Insufficient values provided for structPack");
219
+ }
220
+ view.setUint8(offset, values[valueIdx++]);
221
+ offset += 1;
222
+ break;
223
+ case "h": // Signed 16-bit integer
224
+ if (valueIdx >= values.length) {
225
+ throw new Error("Insufficient values provided for structPack");
226
+ }
227
+ view.setInt16(offset, values[valueIdx++], littleEndian);
228
+ offset += 2;
229
+ break;
230
+ case "H": // Unsigned 16-bit integer
231
+ if (valueIdx >= values.length) {
232
+ throw new Error("Insufficient values provided for structPack");
233
+ }
234
+ view.setUint16(offset, values[valueIdx++], littleEndian);
235
+ offset += 2;
236
+ break;
237
+ case "i": // Signed 32-bit integer
238
+ case "l": // Signed 32-bit integer
239
+ if (valueIdx >= values.length) {
240
+ throw new Error("Insufficient values provided for structPack");
241
+ }
242
+ view.setInt32(offset, values[valueIdx++], littleEndian);
243
+ offset += 4;
244
+ break;
245
+ case "I": // Unsigned 32-bit integer
246
+ case "L": // Unsigned 32-bit integer
247
+ if (valueIdx >= values.length) {
248
+ throw new Error("Insufficient values provided for structPack");
249
+ }
250
+ view.setUint32(offset, values[valueIdx++], littleEndian);
251
+ offset += 4;
252
+ break;
253
+ // case "q": // Signed 64-bit integer
254
+ // view.setBigInt64(offset, BigInt(values[valueIdx++]), littleEndian);
255
+ // offset += 8;
256
+ // break;
257
+ // case "Q": // Unsigned 64-bit integer
258
+ // view.setBigUint64(offset, BigInt(values[valueIdx++]), littleEndian);
259
+ // offset += 8;
260
+ // break;
261
+ case "f": // 32-bit float
262
+ if (valueIdx >= values.length) {
263
+ throw new Error("Insufficient values provided for structPack");
264
+ }
265
+ view.setFloat32(offset, values[valueIdx++], littleEndian);
266
+ offset += 4;
267
+ break;
268
+ case "d": // 64-bit float
269
+ if (valueIdx >= values.length) {
270
+ throw new Error("Insufficient values provided for structPack");
271
+ }
272
+ view.setFloat64(offset, values[valueIdx++], littleEndian);
273
+ offset += 8;
274
+ break;
275
+ default:
276
+ throw new Error(`Unknown format character: ${code}`);
277
+ }
278
+ }
279
+ }
280
+
281
+ return new Uint8Array(buffer);
282
+ }
@@ -0,0 +1,87 @@
1
+ import { RaftSystemType } from "./RaftSystemType";
2
+
3
+ type RaftSystemTypeCreator = () => RaftSystemType;
4
+
5
+ export default class RaftSysTypeManager {
6
+ // Singleton instance
7
+ private static _instance: RaftSysTypeManager;
8
+
9
+ // System type map
10
+ private _sysTypes: Map<string, RaftSystemTypeCreator> = new Map();
11
+ private _defaultSysTypeFactory: RaftSystemTypeCreator | null = null;
12
+
13
+ // Get instance (Singleton)
14
+ public static getInstance(): RaftSysTypeManager {
15
+ if (!RaftSysTypeManager._instance) {
16
+ RaftSysTypeManager._instance = new RaftSysTypeManager();
17
+ }
18
+ return RaftSysTypeManager._instance;
19
+ }
20
+
21
+ // Add a system type by name with its factory
22
+ public addSystemType(sysType: string, factory: RaftSystemTypeCreator): void {
23
+ if (this._sysTypes.has(sysType)) {
24
+ throw new Error(`System type '${sysType}' is already registered.`);
25
+ }
26
+ this._sysTypes.set(sysType, factory);
27
+ }
28
+
29
+ // Set the default system type factory
30
+ public addDefaultSystemType(factory: RaftSystemTypeCreator): void {
31
+ this._defaultSysTypeFactory = factory;
32
+ }
33
+
34
+ // Create a system type by name
35
+ public createSystemType(sysType: string): RaftSystemType | null {
36
+ const factory = this._sysTypes.get(sysType);
37
+ if (!factory) {
38
+ return null;
39
+ }
40
+ return factory();
41
+ }
42
+
43
+ // Create the default system type
44
+ public createDefaultSystemType(): RaftSystemType | null {
45
+ if (!this._defaultSysTypeFactory) {
46
+ return null;
47
+ }
48
+ return this._defaultSysTypeFactory();
49
+ }
50
+
51
+ // Get a list of all unique BLE service UUIDs
52
+ getAllServiceUUIDs(): string[] {
53
+ const serviceUUIDs = new Set<string>();
54
+ this._sysTypes.forEach((factory) => {
55
+ const sysType = factory();
56
+ if (!sysType.BLEServiceUUIDs) {
57
+ return;
58
+ }
59
+ sysType.BLEServiceUUIDs.forEach((uuid) => serviceUUIDs.add(uuid));
60
+ });
61
+ return Array.from(serviceUUIDs);
62
+ }
63
+
64
+ // Get a list of all device name prefixes to filter on
65
+ getAllNamePrefixes(): string[] {
66
+ const deviceNames = new Set<string>();
67
+ this._sysTypes.forEach((factory) => {
68
+ const sysType = factory();
69
+ if (!sysType.BLEDeviceNames) {
70
+ return;
71
+ }
72
+ sysType.BLEDeviceNames.forEach((name) => deviceNames.add(name));
73
+ });
74
+ return Array.from(deviceNames);
75
+ }
76
+
77
+ // Find the system type for a given BLE device name prefix
78
+ getSystemTypeByBLENamePrefix(name: string): RaftSystemType | null {
79
+ for (const factory of this._sysTypes.values()) {
80
+ const sysType = factory();
81
+ if (sysType.BLEDeviceNames && sysType.BLEDeviceNames.some((prefix) => name.startsWith(prefix))) {
82
+ return sysType;
83
+ }
84
+ }
85
+ return null;
86
+ }
87
+ }
@@ -0,0 +1,34 @@
1
+ import RaftDeviceMgrIF from "./RaftDeviceMgrIF";
2
+ import RaftSystemUtils from "./RaftSystemUtils";
3
+ import { RaftEventFn } from "./RaftTypes";
4
+
5
+ export type RaftSubscribeForUpdatesCBType = (systemUtils: RaftSystemUtils, enable: boolean) => Promise<void>;
6
+ export type RaftStateIsInvalidCBType = () => void;
7
+ export type RaftRxOtherMsgType = (payload: Uint8Array, _frameTimeMs: number) => void;
8
+
9
+ export interface ConnectorOptions {
10
+ wsSuffix?: string;
11
+ connTimeoutMs?: number;
12
+ bleConnItvlMs?: number;
13
+ bleUuid?: string;
14
+ }
15
+
16
+ export interface RaftSystemType {
17
+ nameForDialogs: string;
18
+ defaultWiFiHostname?: string;
19
+ BLEServiceUUIDs?: string[];
20
+ BLECmdUUID?: string;
21
+ BLERespUUID?: string;
22
+ BLEDeviceNames?: string[];
23
+ firmwareDestName?: string;
24
+ normalFileDestName?: string;
25
+ connectorOptions: ConnectorOptions;
26
+ setup: (systemUtils: RaftSystemUtils, onEvent: RaftEventFn | null) => void;
27
+ subscribeForUpdates: RaftSubscribeForUpdatesCBType | null;
28
+ stateIsInvalid: RaftStateIsInvalidCBType | null;
29
+ rxOtherMsgType: RaftRxOtherMsgType | null;
30
+ deviceMgrIF?: RaftDeviceMgrIF;
31
+ nonRaftTypeCode?: string;
32
+ }
33
+
34
+ export type RaftGetSystemTypeCBType = (systemUtils: RaftSystemUtils) => Promise<RaftSystemType | null>;