@springfield/ham-radio-utils 3.2.6 → 4.0.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.
- package/dist/schemas/radio-protocol-schema.json +129 -295
- package/dist/utils/ui-logger.d.ts +0 -14
- package/dist/utils/ui-logger.d.ts.map +1 -1
- package/dist/utils/ui-logger.js +19 -65
- package/dist/utils/ui-logger.js.map +1 -1
- package/package.json +2 -2
- package/src/schemas/radio-protocol-schema.json +129 -295
- package/src/utils/ui-logger.ts +19 -85
package/src/utils/ui-logger.ts
CHANGED
|
@@ -6,20 +6,6 @@ import type { ILogLayer } from 'loglayer';
|
|
|
6
6
|
* This module provides a specialized logger for capturing command-level information
|
|
7
7
|
* that can be easily parsed and displayed in a UI. It captures details about
|
|
8
8
|
* commands, data sent, data expected, and data received in a structured format.
|
|
9
|
-
*
|
|
10
|
-
* Purpose:
|
|
11
|
-
* - Captures command-level information for UI display
|
|
12
|
-
* - Provides structured JSON logging for easy parsing
|
|
13
|
-
* - Tracks command execution details including timing
|
|
14
|
-
* - Supports protocol debugging in UI environments
|
|
15
|
-
* - Maintains separation from debug logging
|
|
16
|
-
*
|
|
17
|
-
* Design Rationale:
|
|
18
|
-
* - Single log entry per command provides clean UI display
|
|
19
|
-
* - JSON structure enables easy parsing and filtering
|
|
20
|
-
* - Command-level granularity is appropriate for UI debugging
|
|
21
|
-
* - Structured data supports rich UI representations
|
|
22
|
-
* - Separate from debug logging avoids UI noise
|
|
23
9
|
*/
|
|
24
10
|
|
|
25
11
|
interface ProtocolContext {
|
|
@@ -31,30 +17,9 @@ interface ProtocolContext {
|
|
|
31
17
|
*/
|
|
32
18
|
export type UIProtocolStep = Record<string, unknown>;
|
|
33
19
|
|
|
34
|
-
/**
|
|
35
|
-
* Type guards for protocol step properties
|
|
36
|
-
*/
|
|
37
20
|
const hasDescription = (obj: unknown): obj is { description: string } =>
|
|
38
21
|
typeof obj === 'object' && obj !== null && 'description' in obj && typeof (obj as Record<string, unknown>).description === 'string';
|
|
39
22
|
|
|
40
|
-
const hasReceive = (obj: unknown): obj is { receive: unknown } => typeof obj === 'object' && obj !== null && 'receive' in obj;
|
|
41
|
-
|
|
42
|
-
const hasEndChunk = (obj: unknown): obj is { endChunk: { receive: unknown } } =>
|
|
43
|
-
typeof obj === 'object' &&
|
|
44
|
-
obj !== null &&
|
|
45
|
-
'endChunk' in obj &&
|
|
46
|
-
typeof (obj as Record<string, unknown>).endChunk === 'object' &&
|
|
47
|
-
(obj as Record<string, unknown>).endChunk !== null &&
|
|
48
|
-
'receive' in ((obj as Record<string, unknown>).endChunk as Record<string, unknown>);
|
|
49
|
-
|
|
50
|
-
const hasStartChunk = (obj: unknown): obj is { startChunk: { receive: unknown } } =>
|
|
51
|
-
typeof obj === 'object' &&
|
|
52
|
-
obj !== null &&
|
|
53
|
-
'startChunk' in obj &&
|
|
54
|
-
typeof (obj as Record<string, unknown>).startChunk === 'object' &&
|
|
55
|
-
(obj as Record<string, unknown>).startChunk !== null &&
|
|
56
|
-
'receive' in ((obj as Record<string, unknown>).startChunk as Record<string, unknown>);
|
|
57
|
-
|
|
58
23
|
/**
|
|
59
24
|
* UI Logger for capturing command-level information for UI display
|
|
60
25
|
*/
|
|
@@ -98,15 +63,11 @@ export class UILogger {
|
|
|
98
63
|
const commandType = this.getCommandType(step);
|
|
99
64
|
const description = this.getStepDescription(step);
|
|
100
65
|
|
|
101
|
-
// Extract sent and received data from context
|
|
102
66
|
const dataSent = context.variables && context.variables.get('lastSentData');
|
|
103
67
|
const dataReceived = context.variables && context.variables.get('lastReceivedData');
|
|
104
68
|
const dataExpected = this.getExpectedData(step);
|
|
69
|
+
const dataChunks = commandType === 'read' && context.variables && context.variables.get('lastReadSegmentChunks');
|
|
105
70
|
|
|
106
|
-
// For readSegment, also extract chunk logs if present
|
|
107
|
-
const dataChunks = commandType === 'readSegment' && context.variables && context.variables.get('lastReadSegmentChunks');
|
|
108
|
-
|
|
109
|
-
// Convert dataSent and dataReceived to byte array format if they exist
|
|
110
71
|
// eslint-disable-next-line unicorn/prefer-spread
|
|
111
72
|
const dataSentArray = dataSent && Array.from(dataSent as Uint8Array);
|
|
112
73
|
// eslint-disable-next-line unicorn/prefer-spread
|
|
@@ -141,11 +102,9 @@ export class UILogger {
|
|
|
141
102
|
const commandType = this.getCommandType(step);
|
|
142
103
|
const description = this.getStepDescription(step);
|
|
143
104
|
|
|
144
|
-
// Extract sent data from context
|
|
145
105
|
const dataSent = context.variables && context.variables.get('lastSentData');
|
|
146
106
|
const dataExpected = this.getExpectedData(step);
|
|
147
107
|
|
|
148
|
-
// Convert dataSent to byte array format if it exists
|
|
149
108
|
// eslint-disable-next-line unicorn/prefer-spread
|
|
150
109
|
const dataSentArray = dataSent && Array.from(dataSent as Uint8Array);
|
|
151
110
|
|
|
@@ -168,63 +127,38 @@ export class UILogger {
|
|
|
168
127
|
}
|
|
169
128
|
|
|
170
129
|
private getCommandType(step: UIProtocolStep): string {
|
|
171
|
-
if ('
|
|
172
|
-
return '
|
|
130
|
+
if ('read' in step) {
|
|
131
|
+
return 'read';
|
|
173
132
|
}
|
|
174
|
-
if ('
|
|
175
|
-
return '
|
|
133
|
+
if ('write' in step) {
|
|
134
|
+
return 'write';
|
|
176
135
|
}
|
|
177
|
-
if ('
|
|
178
|
-
return '
|
|
179
|
-
}
|
|
180
|
-
if ('readSegment' in step) {
|
|
181
|
-
return 'readSegment';
|
|
182
|
-
}
|
|
183
|
-
if ('writeSegment' in step) {
|
|
184
|
-
return 'writeSegment';
|
|
185
|
-
}
|
|
186
|
-
if ('setVariable' in step) {
|
|
187
|
-
return 'setVariable';
|
|
136
|
+
if ('send' in step || 'expect' in step) {
|
|
137
|
+
return 'exchange';
|
|
188
138
|
}
|
|
189
139
|
return 'unknown';
|
|
190
140
|
}
|
|
191
141
|
|
|
192
142
|
private getStepDescription(step: UIProtocolStep): string {
|
|
193
|
-
if (
|
|
194
|
-
return step.
|
|
195
|
-
}
|
|
196
|
-
if ('send' in step && hasDescription(step.send)) {
|
|
197
|
-
return step.send.description;
|
|
198
|
-
}
|
|
199
|
-
if ('receive' in step && hasDescription(step.receive)) {
|
|
200
|
-
return step.receive.description;
|
|
201
|
-
}
|
|
202
|
-
if ('readSegment' in step && hasDescription(step.readSegment)) {
|
|
203
|
-
return step.readSegment.description;
|
|
204
|
-
}
|
|
205
|
-
if ('writeSegment' in step && hasDescription(step.writeSegment)) {
|
|
206
|
-
return step.writeSegment.description;
|
|
143
|
+
if (hasDescription(step)) {
|
|
144
|
+
return step.description;
|
|
207
145
|
}
|
|
208
146
|
return 'No description';
|
|
209
147
|
}
|
|
210
148
|
|
|
211
149
|
private getExpectedData(step: UIProtocolStep): unknown {
|
|
212
|
-
if ('
|
|
213
|
-
|
|
150
|
+
if ('read' in step && typeof step.read === 'object' && step.read !== null && 'expect' in step.read) {
|
|
151
|
+
const read = step.read as { expect: unknown; ack?: { expect?: unknown } };
|
|
152
|
+
return {
|
|
153
|
+
expect: read.expect,
|
|
154
|
+
ack: read.ack?.expect,
|
|
155
|
+
};
|
|
214
156
|
}
|
|
215
|
-
if ('
|
|
216
|
-
return step.
|
|
157
|
+
if ('write' in step && typeof step.write === 'object' && step.write !== null && 'expect' in step.write) {
|
|
158
|
+
return (step.write as { expect: unknown }).expect;
|
|
217
159
|
}
|
|
218
|
-
if ('
|
|
219
|
-
|
|
220
|
-
const { readSegment } = step;
|
|
221
|
-
if (hasEndChunk(readSegment) && hasStartChunk(readSegment)) {
|
|
222
|
-
return {
|
|
223
|
-
endChunk: readSegment.endChunk.receive,
|
|
224
|
-
startChunk: readSegment.startChunk.receive,
|
|
225
|
-
type: 'readSegment',
|
|
226
|
-
};
|
|
227
|
-
}
|
|
160
|
+
if ('expect' in step) {
|
|
161
|
+
return step.expect;
|
|
228
162
|
}
|
|
229
163
|
return {};
|
|
230
164
|
}
|