@waterloorocketry/omnibus-ts 0.1.0 → 0.3.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.
@@ -0,0 +1,30 @@
1
+ import { z } from 'zod';
2
+ // Message priority enum schema
3
+ const MsgPrioSchema = z.enum(['LOW', 'MEDIUM', 'HIGH', 'HIGHEST']);
4
+ // TODO: This will extend a Parsley interface that will have boardTypeId... etc.
5
+ export const ParsleyMessageSchema = z.object({
6
+ boardTypeId: z.string(),
7
+ boardInstId: z.string(),
8
+ msgPrio: MsgPrioSchema,
9
+ msgType: z.string(),
10
+ data: z.unknown().nullable(), // parsley data payload
11
+ parsley: z.string(),
12
+ messageFormatVersion: z.literal(2),
13
+ });
14
+ export const CANCommandMessageSchema = z.object({
15
+ boardTypeId: z.string(),
16
+ boardInstId: z.string(),
17
+ msgPrio: MsgPrioSchema,
18
+ msgType: z.string(),
19
+ canMsg: z.unknown().nullable(),
20
+ parsley: z.string(), // Parsley server instance ID
21
+ messageFormatVersion: z.literal(2),
22
+ });
23
+ // TODO: Once RLCS uses a better message type, replace it (probably when RLCSv4 uses CAN)
24
+ const RLCSSensorNameSchema = z.string();
25
+ export const RLCSv3MessageSchema = z.record(RLCSSensorNameSchema, z.union([z.number(), z.string()]));
26
+ export const ParsleyHeartbeatMessageSchema = z.object({
27
+ id: z.string(),
28
+ health: z.string(),
29
+ });
30
+ //# sourceMappingURL=CANMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CANMessage.js","sourceRoot":"","sources":["../../src/data/CANMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,+BAA+B;AAC/B,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAA;AAElE,gFAAgF;AAChF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,uBAAuB;IACrD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,oBAAoB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;CACrC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,6BAA6B;IAClD,oBAAoB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;CACrC,CAAC,CAAA;AAEF,yFAAyF;AACzF,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CACvC,oBAAoB,EACpB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CACpC,CAAA;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import z from 'zod';
2
+ export const DAQMessageSchema = z.object({
3
+ timestamp: z.number(),
4
+ data: z.record(z.string(), z.array(z.number())),
5
+ relativeTimestamps: z.array(z.number()),
6
+ sampleRate: z.int(),
7
+ messageFormatVersion: z.literal(3),
8
+ });
9
+ //# sourceMappingURL=DAQMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DAQMessage.js","sourceRoot":"","sources":["../../src/data/DAQMessage.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAEnB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/C,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACvC,UAAU,EAAE,CAAC,CAAC,GAAG,EAAE;IACnB,oBAAoB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;CACrC,CAAC,CAAA"}
package/dist/helpers.js CHANGED
@@ -1,12 +1,17 @@
1
- import _ from 'lodash';
2
- export const toSnakeCase = (obj) => _.transform(obj, (result, value, key) => {
3
- const snakeKey = _.snakeCase(String(key));
4
- result[snakeKey] =
5
- _.isObject(value) && !_.isArray(value) ? toSnakeCase(value) : value;
6
- });
7
- export const toCamelCase = (obj) => _.transform(obj, (result, value, key) => {
8
- const camelKey = _.camelCase(String(key));
9
- result[camelKey] =
10
- _.isObject(value) && !_.isArray(value) ? toCamelCase(value) : value;
11
- });
1
+ import { mapKeys, snake, camel } from 'radash';
2
+ import { z } from 'zod';
3
+ // Omnibus messages come in and leave as snake case dictionaries, so we should respect that
4
+ export const snakeCaseParser = (targetSchema) => {
5
+ return z
6
+ .record(z.string(), z.unknown())
7
+ .transform((x) => mapKeys(x, camel))
8
+ .pipe(targetSchema);
9
+ };
10
+ export const toSnakeCase = (input) => {
11
+ const convertedEntries = Object.entries(input).map(([key, value]) => [
12
+ snake(key),
13
+ value,
14
+ ]);
15
+ return Object.fromEntries(convertedEntries);
16
+ };
12
17
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AAoBtB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAmB,GAAM,EAAE,EAAE,CACpD,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAwB,EAAE,KAAU,EAAE,GAAG,EAAE,EAAE;IAC3D,MAAM,QAAQ,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAA2B,CAAA;IACnE,MAAM,CAAC,QAAQ,CAAC;QACZ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC3E,CAAC,CAAC,CAAA;AAEN,MAAM,CAAC,MAAM,WAAW,GAAG,CAAmB,GAAM,EAAE,EAAE,CACpD,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAwB,EAAE,KAAU,EAAE,GAAG,EAAE,EAAE;IAC3D,MAAM,QAAQ,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAA2B,CAAA;IACnE,MAAM,CAAC,QAAQ,CAAC;QACZ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC3E,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,2FAA2F;AAC3F,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,YAAuC,EAAE,EAAE;IACvE,OAAO,CAAC;SACH,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/B,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;SACnC,IAAI,CAAC,YAAY,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAmB,KAAQ,EAAE,EAAE;IACtD,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;QACjE,KAAK,CAAC,GAAG,CAAC;QACV,KAAK;KACR,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAA;AAC/C,CAAC,CAAA"}
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ const communicator = ({ serverURL, allowUnsafe = false, allowExposeSocket = fals
5
5
  sender: fns.sender,
6
6
  receiver: fns.receiver,
7
7
  disconnect: fns.disconnect,
8
+ connection: fns.connection,
8
9
  };
9
10
  if (allowUnsafe) {
10
11
  res.unsafeReceiveGenericMessage = fns.unsafeReceiveGenericMessage;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAEvD,MAAM,YAAY,GAAG,CAAC,EAClB,SAAS,EACT,WAAW,GAAG,KAAK,EACnB,iBAAiB,GAAG,KAAK,GAK5B,EAAE,EAAE;IACD,MAAM,GAAG,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAA;IAC/C,MAAM,GAAG,GAML;QACA,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,UAAU,EAAE,GAAG,CAAC,UAAU;KAC7B,CAAA;IACD,IAAI,WAAW,EAAE,CAAC;QACd,GAAG,CAAC,2BAA2B,GAAG,GAAG,CAAC,2BAA2B,CAAA;IACrE,CAAC;IACD,IAAI,iBAAiB,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;IAC3B,CAAC;IAED,OAAO,GAAG,CAAA;AACd,CAAC,CAAA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAMvD,MAAM,YAAY,GAAG,CAAC,EAClB,SAAS,EACT,WAAW,GAAG,KAAK,EACnB,iBAAiB,GAAG,KAAK,GAK5B,EAAE,EAAE;IACD,MAAM,GAAG,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAA;IAC/C,MAAM,GAAG,GAOL;QACA,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;KAC7B,CAAA;IACD,IAAI,WAAW,EAAE,CAAC;QACd,GAAG,CAAC,2BAA2B,GAAG,GAAG,CAAC,2BAA2B,CAAA;IACrE,CAAC;IACD,IAAI,iBAAiB,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;IAC3B,CAAC;IAED,OAAO,GAAG,CAAA;AACd,CAAC,CAAA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
package/dist/message.js CHANGED
@@ -1,26 +1,57 @@
1
+ // TODO: Maybe there's a better name for this file?
1
2
  import { io } from 'socket.io-client';
2
3
  import msgpackParser from 'socket.io-msgpack-parser';
3
- import { toCamelCase, toSnakeCase } from './helpers.js';
4
+ import { snakeCaseParser, toSnakeCase } from './helpers.js';
5
+ import { tryit } from 'radash';
6
+ import { z } from 'zod';
7
+ import { DAQMessageSchema } from './data/DAQMessage.js';
8
+ import { ParsleyMessageSchema, CANCommandMessageSchema, RLCSv3MessageSchema, ParsleyHeartbeatMessageSchema, } from './data/CANMessage.js';
9
+ const getPayloadSchemaFromChannel = (channel) => {
10
+ if (typeof channel !== 'string') {
11
+ throw new Error(`[Omnibus] Channel must be a string, got: ${typeof channel}`);
12
+ }
13
+ const mapChannelPrefix = {
14
+ DAQ: DAQMessageSchema,
15
+ 'CAN/Parsley': ParsleyMessageSchema,
16
+ 'CAN/Commands': CANCommandMessageSchema,
17
+ 'Parsley/Health': ParsleyHeartbeatMessageSchema,
18
+ RLCS: RLCSv3MessageSchema,
19
+ };
20
+ const channelPrefix = Object.keys(mapChannelPrefix).find((prefix) => {
21
+ const channelParts = channel.split('/');
22
+ return prefix.split('/').every((part, i) => channelParts[i] === part);
23
+ });
24
+ return channelPrefix ? mapChannelPrefix[channelPrefix] : undefined;
25
+ };
4
26
  export const socketCallbackBuilder = (channel, afterMessageReceived) => {
5
27
  const buildMessageObject = (channel, timestamp, payload) => {
6
28
  return {
7
29
  channel: channel,
8
30
  timestamp: timestamp,
9
- payload: toCamelCase(payload),
31
+ payload: payload,
10
32
  };
11
33
  };
12
- return (event, timestamp, payload) => {
13
- if (typeof timestamp !== 'number' ||
14
- typeof payload !== 'object' ||
15
- !payload) {
16
- console.warn(`[Omnibus] Malformed Message! ${[event, timestamp, payload]}`);
34
+ const eventHandler = (event, timestamp, payload) => {
35
+ if (!event.startsWith(channel) && channel !== '')
36
+ return;
37
+ const [schemaGetError, schema] = tryit(getPayloadSchemaFromChannel)(event);
38
+ if (schemaGetError) {
39
+ console.warn(schemaGetError);
40
+ return;
41
+ }
42
+ if (!schema) {
43
+ console.warn('[Omnibus] Received message on unknown channel:', event);
17
44
  return;
18
45
  }
19
- if (event.toLowerCase().startsWith(channel.toLowerCase()) ||
20
- channel === '') {
21
- afterMessageReceived(buildMessageObject(event, timestamp, payload));
46
+ const [parserError, messagePayload] = tryit(snakeCaseParser(schema).parse)(payload);
47
+ if (parserError) {
48
+ console.warn(`[Omnibus] Received malformed payload on channel ${event}:`, parserError);
49
+ return;
22
50
  }
51
+ const msgObject = buildMessageObject(event, timestamp, messagePayload);
52
+ afterMessageReceived(msgObject);
23
53
  };
54
+ return eventHandler;
24
55
  };
25
56
  export function getOmnibusSenderReceiver(serverURL) {
26
57
  const socket = io(serverURL, {
@@ -32,20 +63,42 @@ export function getOmnibusSenderReceiver(serverURL) {
32
63
  socket.emit(msg.channel, msg.timestamp, toSnakeCase(msg.payload));
33
64
  };
34
65
  const _attachReceiver = (channel, callback) => {
35
- socket.onAny(socketCallbackBuilder(channel, callback));
66
+ const handler = socketCallbackBuilder(channel, callback);
67
+ socket.onAny(handler);
68
+ return () => socket.offAny(handler);
36
69
  };
37
70
  const receive = (channel, callback) => {
38
- _attachReceiver(channel, callback);
71
+ return _attachReceiver(channel, callback);
39
72
  };
40
73
  const receiveAll = (callback) => {
41
- _attachReceiver('', callback);
74
+ return _attachReceiver('', callback);
42
75
  };
43
76
  // No static type checking or runtime sanity checks
44
77
  const unsafeReceiveGenericMessage = (callback) => {
45
- socket.onAny((event, timestamp, payload) => {
78
+ const fn = (event, timestamp, payload) => {
46
79
  callback({ channel: event, timestamp, payload });
47
- });
80
+ };
81
+ socket.onAny(fn);
82
+ return () => socket.offAny(fn);
83
+ };
84
+ const onConnectionChange = (callback) => {
85
+ const onConnect = () => callback('connected');
86
+ const onDisconnect = () => callback('disconnected');
87
+ const onError = (err) => callback('error', err);
88
+ socket.on('connect', onConnect);
89
+ socket.on('disconnect', onDisconnect);
90
+ socket.on('connect_error', onError);
91
+ // Emit current state immediately
92
+ if (socket.connected) {
93
+ callback('connected');
94
+ }
95
+ return () => {
96
+ socket.off('connect', onConnect);
97
+ socket.off('disconnect', onDisconnect);
98
+ socket.off('connect_error', onError);
99
+ };
48
100
  };
101
+ const isConnected = () => socket.connected;
49
102
  const disconnect = () => {
50
103
  socket.disconnect();
51
104
  };
@@ -58,6 +111,10 @@ export function getOmnibusSenderReceiver(serverURL) {
58
111
  },
59
112
  unsafeReceiveGenericMessage,
60
113
  disconnect,
114
+ connection: {
115
+ onConnectionChange,
116
+ isConnected,
117
+ },
61
118
  };
62
119
  }
63
120
  //# sourceMappingURL=message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","sourceRoot":"","sources":["../src/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AACrC,OAAO,aAAa,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAmCvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACjC,OAAe,EACf,oBAA+C,EACjD,EAAE;IACA,MAAM,kBAAkB,GAAG,CACvB,OAAe,EACf,SAAiB,EACjB,OAAe,EACjB,EAAE;QACA,OAAO;YACH,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,WAAW,CAAC,OAAO,CAAM;SACrC,CAAA;IACL,CAAC,CAAA;IACD,OAAO,CAAC,KAAa,EAAE,SAAiB,EAAE,OAAe,EAAE,EAAE;QACzD,IACI,OAAO,SAAS,KAAK,QAAQ;YAC7B,OAAO,OAAO,KAAK,QAAQ;YAC3B,CAAC,OAAO,EACV,CAAC;YACC,OAAO,CAAC,IAAI,CACR,gCAAgC,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAChE,CAAA;YACD,OAAM;QACV,CAAC;QAED,IACI,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACrD,OAAO,KAAK,EAAE,EAChB,CAAC;YACC,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;QACvE,CAAC;IACL,CAAC,CAAA;AACL,CAAC,CAAA;AAED,MAAM,UAAU,wBAAwB,CAAC,SAAiB;IACtD,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,EAAE;QACzB,MAAM,EAAE,aAAa;QACrB,UAAU,EAAE,CAAC,WAAW,CAAC;QACzB,OAAO,EAAE,KAAK;KACjB,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,CAAuB,GAAqB,EAAE,EAAE;QACzD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IACrE,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,CACpB,OAAoB,EACpB,QAAmC,EACrC,EAAE;QACA,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAI,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;IAC7D,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,CACZ,OAAuC,EACvC,QAAmC,EACrC,EAAE;QACA,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IACtC,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,CAAC,QAA4C,EAAE,EAAE;QAChE,eAAe,CAAa,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC7C,CAAC,CAAA;IAED,mDAAmD;IACnD,MAAM,2BAA2B,GAAG,CAChC,QAQU,EACZ,EAAE;QACA,MAAM,CAAC,KAAK,CAAC,CAAC,KAAa,EAAE,SAAiB,EAAE,OAAU,EAAE,EAAE;YAC1D,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAA;QACpD,CAAC,CAAC,CAAA;IACN,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,GAAG,EAAE;QACpB,MAAM,CAAC,UAAU,EAAE,CAAA;IACvB,CAAC,CAAA;IAED,OAAO;QACH,MAAM;QACN,MAAM,EAAE,EAAE,IAAI,EAAE;QAChB,QAAQ,EAAE;YACN,OAAO;YACP,UAAU;SACb;QACD,2BAA2B;QAC3B,UAAU;KACb,CAAA;AACL,CAAC"}
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../src/message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { z } from 'zod';
2
+ export declare const ParsleyMessageSchema: z.ZodObject<{
3
+ boardTypeId: z.ZodString;
4
+ boardInstId: z.ZodString;
5
+ msgPrio: z.ZodEnum<{
6
+ LOW: "LOW";
7
+ MEDIUM: "MEDIUM";
8
+ HIGH: "HIGH";
9
+ HIGHEST: "HIGHEST";
10
+ }>;
11
+ msgType: z.ZodString;
12
+ data: z.ZodNullable<z.ZodUnknown>;
13
+ parsley: z.ZodString;
14
+ messageFormatVersion: z.ZodLiteral<2>;
15
+ }, z.core.$strip>;
16
+ export declare const CANCommandMessageSchema: z.ZodObject<{
17
+ boardTypeId: z.ZodString;
18
+ boardInstId: z.ZodString;
19
+ msgPrio: z.ZodEnum<{
20
+ LOW: "LOW";
21
+ MEDIUM: "MEDIUM";
22
+ HIGH: "HIGH";
23
+ HIGHEST: "HIGHEST";
24
+ }>;
25
+ msgType: z.ZodString;
26
+ canMsg: z.ZodNullable<z.ZodUnknown>;
27
+ parsley: z.ZodString;
28
+ messageFormatVersion: z.ZodLiteral<2>;
29
+ }, z.core.$strip>;
30
+ export declare const RLCSv3MessageSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
31
+ export declare const ParsleyHeartbeatMessageSchema: z.ZodObject<{
32
+ id: z.ZodString;
33
+ health: z.ZodString;
34
+ }, z.core.$strip>;
35
+ export type ParsleyMessage<T = unknown> = z.infer<typeof ParsleyMessageSchema> & {
36
+ data: T | null;
37
+ };
38
+ export type CANCommandMessage<T = unknown> = z.infer<typeof CANCommandMessageSchema> & {
39
+ canMsg: T | null;
40
+ };
41
+ export type RLCSv3Message = z.infer<typeof RLCSv3MessageSchema>;
42
+ export type ParsleyHeartbeatMessage = z.infer<typeof ParsleyHeartbeatMessageSchema>;
43
+ //# sourceMappingURL=CANMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CANMessage.d.ts","sourceRoot":"","sources":["../../../src/data/CANMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;iBAQ/B,CAAA;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;iBAQlC,CAAA;AAIF,eAAO,MAAM,mBAAmB,2EAG/B,CAAA;AAED,eAAO,MAAM,6BAA6B;;;iBAGxC,CAAA;AAEF,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,KAAK,CAC7C,OAAO,oBAAoB,CAC9B,GAAG;IAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,CAAA;AACtB,MAAM,MAAM,iBAAiB,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,KAAK,CAChD,OAAO,uBAAuB,CACjC,GAAG;IAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,CAAA;AACxB,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CACzC,OAAO,6BAA6B,CACvC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import z from 'zod';
2
+ export declare const DAQMessageSchema: z.ZodObject<{
3
+ timestamp: z.ZodNumber;
4
+ data: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodNumber>>;
5
+ relativeTimestamps: z.ZodArray<z.ZodNumber>;
6
+ sampleRate: z.ZodInt;
7
+ messageFormatVersion: z.ZodLiteral<3>;
8
+ }, z.z.core.$strip>;
9
+ export type DAQMessage = z.infer<typeof DAQMessageSchema>;
10
+ //# sourceMappingURL=DAQMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DAQMessage.d.ts","sourceRoot":"","sources":["../../../src/data/DAQMessage.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAEnB,eAAO,MAAM,gBAAgB;;;;;;mBAM3B,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA"}
@@ -1,12 +1,4 @@
1
- type SnakeToCamelCase<S extends string> = S extends `${infer T}_${infer U}` ? `${T}${Capitalize<SnakeToCamelCase<U>>}` : S;
2
- type CamelToSnakeCase<S extends string> = S extends `${infer First}${infer Rest}` ? `${First extends Lowercase<First> ? First : `_${Lowercase<First>}`}${CamelToSnakeCase<Rest>}` : S;
3
- type CamelCaseKeys<T extends object> = {
4
- [K in keyof T as K extends string ? SnakeToCamelCase<K> : K]: T[K];
5
- };
6
- type SnakeCaseKeys<T extends object> = {
7
- [K in keyof T as K extends string ? CamelToSnakeCase<K> : K]: T[K];
8
- };
9
- export declare const toSnakeCase: <T extends object>(obj: T) => SnakeCaseKeys<T>;
10
- export declare const toCamelCase: <T extends object>(obj: T) => CamelCaseKeys<T>;
11
- export {};
1
+ import { z } from 'zod';
2
+ export declare const snakeCaseParser: (targetSchema: z.ZodObject | z.ZodRecord) => z.ZodPipe<z.ZodPipe<z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodTransform<Record<string, unknown>, Record<string, unknown>>>, z.ZodObject<z.core.$ZodLooseShape, z.core.$strip> | z.ZodRecord<z.core.$ZodRecordKey, z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
3
+ export declare const toSnakeCase: <T extends object>(input: T) => any;
12
4
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAClC,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,GACxE,CAAC,CAAA;AAET,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAClC,CAAC,SAAS,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,GACnC,GAAG,KAAK,SAAS,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAE,GAC7F,CAAC,CAAA;AAET,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,IAAI;KAClC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrE,CAAA;AAED,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,IAAI;KAClC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrE,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,qBAK9C,CAAA;AAEN,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,qBAK9C,CAAA"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,eAAe,GAAI,cAAc,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,ySAKtE,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,OAAO,CAAC,QAMrD,CAAA"}
@@ -1,3 +1,6 @@
1
+ export type * from './data/DAQMessage.ts';
2
+ export type * from './data/CANMessage.ts';
3
+ export type { ConnectionStatus } from './message.ts';
1
4
  declare const communicator: ({ serverURL, allowUnsafe, allowExposeSocket, }: {
2
5
  serverURL: string;
3
6
  allowUnsafe?: boolean;
@@ -8,15 +11,28 @@ declare const communicator: ({ serverURL, allowUnsafe, allowExposeSocket, }: {
8
11
  send: <T extends import("./message.js").AnyPayload>(msg: import("./message.js").MessageToSend<T>) => void;
9
12
  };
10
13
  receiver: {
11
- receive: <T extends import("./message.js").AnyPayload>(channel: T extends import("./data/daqMessage.js").DAQMessage ? `DAQ${string}` : T extends import("./data/canMessage.js").ParsleyMessage<unknown> ? `CAN/Parsley${string}` : T extends import("./data/canMessage.js").CANCommandMessage<unknown> ? `CAN/Commands${string}` : T extends import("./data/canMessage.js").ParsleyHeartbeatMessage ? `Parsley/Health${string}` : T extends import("./data/canMessage.js").RLCSv3Message ? `RLCS${string}` : never, callback: (msg: import("./message.js").Message<T>) => void) => void;
12
- receiveAll: (callback: (msg: import("./message.js").Message<import("./message.js").AnyPayload>) => void) => void;
14
+ receive: <T extends import("./message.js").AnyPayload>(channel: T extends {
15
+ timestamp: number;
16
+ data: Record<string, number[]>;
17
+ relativeTimestamps: number[];
18
+ sampleRate: number;
19
+ messageFormatVersion: 3;
20
+ } ? `DAQ/${string}` | "DAQ" : T extends import("./data/CANMessage.ts").ParsleyMessage ? `CAN/Parsley/${string}` | "CAN/Parsley" : T extends import("./data/CANMessage.ts").CANCommandMessage ? `CAN/Commands/${string}` | "CAN/Commands" : T extends {
21
+ id: string;
22
+ health: string;
23
+ } ? `Parsley/Health/${string}` | "Parsley/Health" : T extends Record<string, string | number> ? `RLCS/${string}` | "RLCS" : never, callback: (msg: import("./message.js").Message<T>) => void) => () => import("socket.io-client").Socket<import("@socket.io/component-emitter").DefaultEventsMap, import("@socket.io/component-emitter").DefaultEventsMap>;
24
+ receiveAll: (callback: (msg: import("./message.js").Message<import("./message.js").AnyPayload>) => void) => () => import("socket.io-client").Socket<import("@socket.io/component-emitter").DefaultEventsMap, import("@socket.io/component-emitter").DefaultEventsMap>;
13
25
  };
14
26
  unsafeReceiveGenericMessage?: <T = unknown>(callback: ({ channel, timestamp, payload, }: {
15
27
  channel: string;
16
28
  timestamp: number;
17
29
  payload: T;
18
- }) => void) => void;
30
+ }) => void) => () => import("socket.io-client").Socket<import("@socket.io/component-emitter").DefaultEventsMap, import("@socket.io/component-emitter").DefaultEventsMap>;
19
31
  disconnect: () => void;
32
+ connection: {
33
+ onConnectionChange: (callback: (status: import("./message.js").ConnectionStatus, error?: Error) => void) => (() => void);
34
+ isConnected: () => boolean;
35
+ };
20
36
  };
21
37
  export { communicator };
22
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,YAAY,GAAI,gDAInB;IACC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC9B;;;;;;;;;;;;;;;CAqBA,CAAA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,mBAAmB,sBAAsB,CAAA;AACzC,mBAAmB,sBAAsB,CAAA;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAEpD,QAAA,MAAM,YAAY,GAAI,gDAInB;IACC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC9B;;;;;;;;;;;;;;;;;;;;;;;;;8FA0ByrI,CAAC;;;CAH1rI,CAAA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
@@ -1,7 +1,8 @@
1
- import type { DAQMessage } from './data/daqMessage.ts';
2
- import type { ParsleyMessage, CANCommandMessage, RLCSv3Message, ParsleyHeartbeatMessage } from './data/canMessage.ts';
1
+ import type { DAQMessage } from './data/DAQMessage.ts';
2
+ import type { ParsleyMessage, CANCommandMessage, RLCSv3Message, ParsleyHeartbeatMessage } from './data/CANMessage.ts';
3
3
  export type AnyPayload = DAQMessage | ParsleyMessage | CANCommandMessage | RLCSv3Message | ParsleyHeartbeatMessage;
4
- type ChannelLiteralToPayloadType<T extends AnyPayload> = T extends DAQMessage ? `DAQ${string}` : T extends ParsleyMessage ? `CAN/Parsley${string}` : T extends CANCommandMessage ? `CAN/Commands${string}` : T extends ParsleyHeartbeatMessage ? `Parsley/Health${string}` : T extends RLCSv3Message ? `RLCS${string}` : never;
4
+ type ChannelLiteralToPayloadType<T extends AnyPayload> = T extends DAQMessage ? `DAQ/${string}` | 'DAQ' : T extends ParsleyMessage ? `CAN/Parsley/${string}` | 'CAN/Parsley' : T extends CANCommandMessage ? `CAN/Commands/${string}` | 'CAN/Commands' : T extends ParsleyHeartbeatMessage ? `Parsley/Health/${string}` | 'Parsley/Health' : T extends RLCSv3Message ? `RLCS/${string}` | 'RLCS' : never;
5
+ export type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error';
5
6
  export interface Message<T extends AnyPayload> {
6
7
  channel: string;
7
8
  timestamp: number;
@@ -17,15 +18,19 @@ export declare function getOmnibusSenderReceiver(serverURL: string): {
17
18
  send: <T extends AnyPayload>(msg: MessageToSend<T>) => void;
18
19
  };
19
20
  receiver: {
20
- receive: <T extends AnyPayload>(channel: ChannelLiteralToPayloadType<T>, callback: (msg: Message<T>) => void) => void;
21
- receiveAll: (callback: (msg: Message<AnyPayload>) => void) => void;
21
+ receive: <T extends AnyPayload>(channel: ChannelLiteralToPayloadType<T>, callback: (msg: Message<T>) => void) => () => import("socket.io-client").Socket<import("@socket.io/component-emitter").DefaultEventsMap, import("@socket.io/component-emitter").DefaultEventsMap>;
22
+ receiveAll: (callback: (msg: Message<AnyPayload>) => void) => () => import("socket.io-client").Socket<import("@socket.io/component-emitter").DefaultEventsMap, import("@socket.io/component-emitter").DefaultEventsMap>;
22
23
  };
23
24
  unsafeReceiveGenericMessage: <T = unknown>(callback: ({ channel, timestamp, payload, }: {
24
25
  channel: string;
25
26
  timestamp: number;
26
27
  payload: T;
27
- }) => void) => void;
28
+ }) => void) => () => import("socket.io-client").Socket<import("@socket.io/component-emitter").DefaultEventsMap, import("@socket.io/component-emitter").DefaultEventsMap>;
28
29
  disconnect: () => void;
30
+ connection: {
31
+ onConnectionChange: (callback: (status: ConnectionStatus, error?: Error) => void) => (() => void);
32
+ isConnected: () => boolean;
33
+ };
29
34
  };
30
35
  export {};
31
36
  //# sourceMappingURL=message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/message.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EACR,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,uBAAuB,EAC1B,MAAM,sBAAsB,CAAA;AAE7B,MAAM,MAAM,UAAU,GAChB,UAAU,GACV,cAAc,GACd,iBAAiB,GACjB,aAAa,GACb,uBAAuB,CAAA;AAE7B,KAAK,2BAA2B,CAAC,CAAC,SAAS,UAAU,IACjD,CAAC,SAAS,UAAU,GAAG,MAAM,MAAM,EAAE,GACnC,CAAC,SAAS,cAAc,GAAG,cAAc,MAAM,EAAE,GACjD,CAAC,SAAS,iBAAiB,GAAG,eAAe,MAAM,EAAE,GACrD,CAAC,SAAS,uBAAuB,GAAG,iBAAiB,MAAM,EAAE,GAC7D,CAAC,SAAS,aAAa,GAAG,OAAO,MAAM,EAAE,GACzC,KAAK,CAAA;AAEX,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,UAAU;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,CAAC,CAAA;CACb;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,UAAU,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;IACnE,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAA;CAC1C;AAED,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,UAAU,EACtD,SAAS,MAAM,EACf,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,MAavC,OAAO,MAAM,EAAE,WAAW,MAAM,EAAE,SAAS,MAAM,SAmB5D,CAAA;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM;;;eAOxC,CAAC,SAAS,UAAU,OAAO,aAAa,CAAC,CAAC,CAAC;;;kBAWxC,CAAC,SAAS,UAAU,WACxB,2BAA2B,CAAC,CAAC,CAAC,YAC7B,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;+BAKT,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI;;kCAK3B,CAAC,sBACxB,CAAC,EACP,OAAO,EACP,SAAS,EACT,OAAO,GACV,EAAE;QACC,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,CAAC,CAAA;KACb,KAAK,IAAI;;EAqBjB"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/message.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAStD,OAAO,KAAK,EACR,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,uBAAuB,EAC1B,MAAM,sBAAsB,CAAA;AAE7B,MAAM,MAAM,UAAU,GAChB,UAAU,GACV,cAAc,GACd,iBAAiB,GACjB,aAAa,GACb,uBAAuB,CAAA;AAE7B,KAAK,2BAA2B,CAAC,CAAC,SAAS,UAAU,IACjD,CAAC,SAAS,UAAU,GAAG,OAAO,MAAM,EAAE,GAAG,KAAK,GAC5C,CAAC,SAAS,cAAc,GAAG,eAAe,MAAM,EAAE,GAAG,aAAa,GAClE,CAAC,SAAS,iBAAiB,GAAG,gBAAgB,MAAM,EAAE,GAAG,cAAc,GACvE,CAAC,SAAS,uBAAuB,GAC/B,kBAAkB,MAAM,EAAE,GAAG,gBAAgB,GAC/C,CAAC,SAAS,aAAa,GAAG,QAAQ,MAAM,EAAE,GAAG,MAAM,GACnD,KAAK,CAAA;AAEX,MAAM,MAAM,gBAAgB,GACtB,YAAY,GACZ,WAAW,GACX,cAAc,GACd,OAAO,CAAA;AAEb,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,UAAU;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,CAAC,CAAA;CACb;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,UAAU,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;IACnE,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAA;CAC1C;AAyBD,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,UAAU,EACtD,SAAS,MAAM,EACf,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,aAepC,MAAM,aACF,MAAM,WACR,MAAM,SAsCtB,CAAA;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM;;;eAOxC,CAAC,SAAS,UAAU,OAAO,aAAa,CAAC,CAAC,CAAC;;;kBAaxC,CAAC,SAAS,UAAU,WACxB,2BAA2B,CAAC,CAAC,CAAC,YAC7B,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;+BAKT,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI;;kCAK3B,CAAC,sBACxB,CAAC,EACP,OAAO,EACP,SAAS,EACT,OAAO,GACV,EAAE;QACC,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,CAAC,CAAA;KACb,KAAK,IAAI;;;uCAUA,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,KAC5D,CAAC,MAAM,IAAI,CAAC;;;EAyClB"}
package/package.json CHANGED
@@ -1,25 +1,28 @@
1
1
  {
2
2
  "name": "@waterloorocketry/omnibus-ts",
3
3
  "public": true,
4
- "version": "0.1.0",
4
+ "version": "0.3.0",
5
5
  "description": "Omnibus Message bindings for TypeScript and SocketIO",
6
6
  "license": "MIT",
7
7
  "author": "Waterloo Rocketry",
8
8
  "type": "module",
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/types/index.d.ts",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/waterloo-rocketry/omnibus-ts.git"
14
+ },
11
15
  "scripts": {
12
16
  "test": "vitest",
13
17
  "build": "tsc",
14
18
  "format": "prettier --write .",
15
- "lint": "eslint . --ext .ts",
19
+ "lint": "eslint src; eslint tests",
16
20
  "coverage": "vitest run --coverage"
17
21
  },
18
22
  "devDependencies": {
19
23
  "@eslint/js": "^9.39.0",
20
24
  "@eslint/json": "^0.13.2",
21
25
  "@types/express": "^5.0.5",
22
- "@types/lodash": "^4.17.20",
23
26
  "@types/node": "^24.9.2",
24
27
  "@vitest/coverage-v8": "^4.0.6",
25
28
  "eslint": "^9.39.0",
@@ -33,9 +36,10 @@
33
36
  "vitest": "^4.0.6"
34
37
  },
35
38
  "dependencies": {
36
- "lodash": "^4.17.21",
39
+ "radash": "^12.1.1",
37
40
  "socket.io-client": "^4.8.1",
38
- "socket.io-msgpack-parser": "^3.0.2"
41
+ "socket.io-msgpack-parser": "^3.0.2",
42
+ "zod": "^4.1.12"
39
43
  },
40
44
  "files": [
41
45
  "dist/**/*"
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=canMessage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"canMessage.js","sourceRoot":"","sources":["../../src/data/canMessage.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=daqMessage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"daqMessage.js","sourceRoot":"","sources":["../../src/data/daqMessage.ts"],"names":[],"mappings":""}
@@ -1,26 +0,0 @@
1
- export interface ParsleyMessage<T = unknown> {
2
- boardTypeId: string;
3
- boardInstId: string;
4
- msgPrio: 'LOW' | 'MEDIUM' | 'HIGH' | 'HIGHEST';
5
- msgType: string;
6
- data: T | null;
7
- parsley: string;
8
- messageVersion: number;
9
- }
10
- export interface CANCommandMessage<T = unknown> {
11
- boardTypeId: string;
12
- boardInstId: string;
13
- msgPrio: 'LOW' | 'MEDIUM' | 'HIGH' | 'HIGHEST';
14
- msgType: string;
15
- canMsg: T | null;
16
- parsley: string;
17
- messageVersion: number;
18
- }
19
- type RLCSSensorName = string;
20
- export type RLCSv3Message = Map<RLCSSensorName, number | string>;
21
- export interface ParsleyHeartbeatMessage {
22
- id: string;
23
- health: string;
24
- }
25
- export {};
26
- //# sourceMappingURL=canMessage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"canMessage.d.ts","sourceRoot":"","sources":["../../../src/data/canMessage.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACvC,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAA;IAC9C,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAA;IAC9C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,CAAC,GAAG,IAAI,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;CACzB;AAGD,KAAK,cAAc,GAAG,MAAM,CAAA;AAC5B,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;AAEhE,MAAM,WAAW,uBAAuB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;CACjB"}
@@ -1,10 +0,0 @@
1
- type SensorName = string;
2
- export interface DAQMessage extends Record<string, unknown> {
3
- timestamp: number;
4
- data: Record<SensorName, number[]>;
5
- relativeTimestamps: number[];
6
- sampleRate: number;
7
- messageVersion: number;
8
- }
9
- export {};
10
- //# sourceMappingURL=daqMessage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"daqMessage.d.ts","sourceRoot":"","sources":["../../../src/data/daqMessage.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,MAAM,CAAA;AAExB,MAAM,WAAW,UAAW,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvD,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;IAClC,kBAAkB,EAAE,MAAM,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;CACzB"}