node-osc 9.1.7 → 11.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/.github/workflows/bump-version.yml +1 -1
- package/.github/workflows/create-release.yml +4 -4
- package/.github/workflows/nodejs.yml +1 -1
- package/dist/lib/Bundle.js +1 -0
- package/dist/lib/Client.js +3 -5
- package/dist/lib/internal/decode.js +3 -3
- package/dist/lib/internal/osc.js +329 -0
- package/dist/test/test-decode.js +77 -0
- package/dist/test/test-osc-internal.js +498 -0
- package/examples/esm.mjs +2 -2
- package/examples/server.js +2 -2
- package/lib/Bundle.mjs +1 -0
- package/lib/Client.mjs +1 -3
- package/lib/internal/decode.mjs +3 -3
- package/lib/internal/osc.mjs +324 -0
- package/package.json +10 -9
- package/rollup.config.mjs +0 -2
- package/test/test-decode.mjs +77 -0
- package/test/test-osc-internal.mjs +496 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tap = require('tap');
|
|
4
|
+
var _osc = require('#osc');
|
|
5
|
+
|
|
6
|
+
tap.test('osc: timetag encoding with non-number value', (t) => {
|
|
7
|
+
// Test the else branch in writeTimeTag that writes zeros for non-number values
|
|
8
|
+
const bundle = {
|
|
9
|
+
oscType: 'bundle',
|
|
10
|
+
timetag: 'immediate', // Non-number value
|
|
11
|
+
elements: [
|
|
12
|
+
{
|
|
13
|
+
oscType: 'message',
|
|
14
|
+
address: '/test',
|
|
15
|
+
args: []
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const buffer = _osc.toBuffer(bundle);
|
|
21
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
22
|
+
|
|
23
|
+
t.equal(decoded.oscType, 'bundle', 'should decode as bundle');
|
|
24
|
+
t.equal(decoded.timetag, 0, 'should decode timetag as 0 for immediate execution');
|
|
25
|
+
t.end();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
tap.test('osc: timetag with immediate execution values', (t) => {
|
|
29
|
+
// Test readTimeTag with seconds === 0 && fraction === 1
|
|
30
|
+
const bundle = {
|
|
31
|
+
oscType: 'bundle',
|
|
32
|
+
timetag: null, // This will trigger the non-number path
|
|
33
|
+
elements: [
|
|
34
|
+
{
|
|
35
|
+
oscType: 'message',
|
|
36
|
+
address: '/test',
|
|
37
|
+
args: []
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const buffer = _osc.toBuffer(bundle);
|
|
43
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
44
|
+
|
|
45
|
+
t.equal(decoded.timetag, 0, 'should handle immediate execution timetag');
|
|
46
|
+
t.end();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
tap.test('osc: argument encoding with unknown type', (t) => {
|
|
50
|
+
// Test encodeArgument with unknown argument type to trigger line 122
|
|
51
|
+
const message = {
|
|
52
|
+
oscType: 'message',
|
|
53
|
+
address: '/test',
|
|
54
|
+
args: [
|
|
55
|
+
{
|
|
56
|
+
type: 'unknown',
|
|
57
|
+
value: 'test'
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
t.throws(() => {
|
|
63
|
+
_osc.toBuffer(message);
|
|
64
|
+
}, /Unknown argument type: unknown/, 'should throw error for unknown argument type');
|
|
65
|
+
t.end();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
tap.test('osc: argument encoding with boolean false', (t) => {
|
|
69
|
+
// Test explicit boolean false encoding to cover lines 132-133
|
|
70
|
+
const message = {
|
|
71
|
+
oscType: 'message',
|
|
72
|
+
address: '/test',
|
|
73
|
+
args: [
|
|
74
|
+
{
|
|
75
|
+
type: 'boolean',
|
|
76
|
+
value: false
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const buffer = _osc.toBuffer(message);
|
|
82
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
83
|
+
|
|
84
|
+
t.equal(decoded.args[0].value, false, 'should encode and decode false boolean');
|
|
85
|
+
t.end();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
tap.test('osc: argument encoding with unsupported object', (t) => {
|
|
89
|
+
// Test encodeArgument with unsupported object to trigger lines 139-142
|
|
90
|
+
const message = {
|
|
91
|
+
oscType: 'message',
|
|
92
|
+
address: '/test',
|
|
93
|
+
args: [
|
|
94
|
+
{ unsupported: 'object' } // Object without type/value properties
|
|
95
|
+
]
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
t.throws(() => {
|
|
99
|
+
_osc.toBuffer(message);
|
|
100
|
+
}, /Don't know how to encode argument/, 'should throw error for unsupported object');
|
|
101
|
+
t.end();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
tap.test('osc: argument encoding with undefined value', (t) => {
|
|
105
|
+
// Test encodeArgument with undefined to trigger error case
|
|
106
|
+
const message = {
|
|
107
|
+
oscType: 'message',
|
|
108
|
+
address: '/test',
|
|
109
|
+
args: [undefined]
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
t.throws(() => {
|
|
113
|
+
_osc.toBuffer(message);
|
|
114
|
+
}, /Don't know how to encode argument/, 'should throw error for undefined argument');
|
|
115
|
+
t.end();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
tap.test('osc: argument decoding with unknown type tag', (t) => {
|
|
119
|
+
// Test decodeArgument with unknown type tag to trigger line 161
|
|
120
|
+
// We need to manually create a buffer with an invalid type tag
|
|
121
|
+
const addressPart = '/test\0\0\0';
|
|
122
|
+
const typeTagPart = ',X\0\0'; // X is not a valid OSC type tag
|
|
123
|
+
const buffer = Buffer.from(addressPart + typeTagPart);
|
|
124
|
+
|
|
125
|
+
t.throws(() => {
|
|
126
|
+
_osc.fromBuffer(buffer);
|
|
127
|
+
}, /I don't understand the argument code X/, 'should throw error for unknown type tag');
|
|
128
|
+
t.end();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
tap.test('osc: null argument encoding and decoding', (t) => {
|
|
132
|
+
// Test null argument handling (N type tag)
|
|
133
|
+
// Since our current implementation doesn't directly support null in encoding,
|
|
134
|
+
// let's test that we can at least decode it if we manually create the buffer
|
|
135
|
+
const addressPart = '/test\0\0\0';
|
|
136
|
+
const typeTagPart = ',N\0\0'; // N is null type tag
|
|
137
|
+
const buffer = Buffer.from(addressPart + typeTagPart);
|
|
138
|
+
|
|
139
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
140
|
+
t.equal(decoded.args[0].value, null, 'should decode null argument');
|
|
141
|
+
t.end();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
tap.test('osc: double type argument encoding', (t) => {
|
|
145
|
+
// Test double type argument which should fall back to float
|
|
146
|
+
const message = {
|
|
147
|
+
oscType: 'message',
|
|
148
|
+
address: '/test',
|
|
149
|
+
args: [
|
|
150
|
+
{
|
|
151
|
+
type: 'd',
|
|
152
|
+
value: 3.14159
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const buffer = _osc.toBuffer(message);
|
|
158
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
159
|
+
|
|
160
|
+
t.ok(Math.abs(decoded.args[0].value - 3.14159) < 0.001, 'should encode double as float');
|
|
161
|
+
t.end();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
tap.test('osc: blob argument with Buffer', (t) => {
|
|
165
|
+
// Test blob encoding with actual Buffer to ensure Buffer.isBuffer path is covered
|
|
166
|
+
const testBuffer = Buffer.from('test data');
|
|
167
|
+
const message = {
|
|
168
|
+
oscType: 'message',
|
|
169
|
+
address: '/test',
|
|
170
|
+
args: [testBuffer] // Direct Buffer without type wrapper
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const buffer = _osc.toBuffer(message);
|
|
174
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
175
|
+
|
|
176
|
+
t.ok(Buffer.isBuffer(decoded.args[0].value), 'should decode as Buffer');
|
|
177
|
+
t.equal(decoded.args[0].value.toString(), 'test data', 'should preserve blob content');
|
|
178
|
+
t.end();
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
tap.test('osc: float number encoding', (t) => {
|
|
182
|
+
// Test encoding of float numbers to cover lines 132-133
|
|
183
|
+
const message = {
|
|
184
|
+
oscType: 'message',
|
|
185
|
+
address: '/test',
|
|
186
|
+
args: [3.14159] // Non-integer number should be encoded as float
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const buffer = _osc.toBuffer(message);
|
|
190
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
191
|
+
|
|
192
|
+
t.ok(typeof decoded.args[0].value === 'number', 'should decode as number');
|
|
193
|
+
t.ok(!Number.isInteger(decoded.args[0].value), 'should be float, not integer');
|
|
194
|
+
t.ok(Math.abs(decoded.args[0].value - 3.14159) < 0.001, 'should preserve float value');
|
|
195
|
+
t.end();
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
tap.test('osc: explicit integer type encoding', (t) => {
|
|
199
|
+
// Test explicit integer type to cover line 102
|
|
200
|
+
const message = {
|
|
201
|
+
oscType: 'message',
|
|
202
|
+
address: '/test',
|
|
203
|
+
args: [
|
|
204
|
+
{
|
|
205
|
+
type: 'i',
|
|
206
|
+
value: 42
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const buffer = _osc.toBuffer(message);
|
|
212
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
213
|
+
|
|
214
|
+
t.equal(decoded.args[0].value, 42, 'should encode and decode integer');
|
|
215
|
+
t.end();
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
tap.test('osc: explicit float type encoding', (t) => {
|
|
219
|
+
// Test explicit float type to cover line 105
|
|
220
|
+
const message = {
|
|
221
|
+
oscType: 'message',
|
|
222
|
+
address: '/test',
|
|
223
|
+
args: [
|
|
224
|
+
{
|
|
225
|
+
type: 'f',
|
|
226
|
+
value: 3.14
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const buffer = _osc.toBuffer(message);
|
|
232
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
233
|
+
|
|
234
|
+
t.ok(Math.abs(decoded.args[0].value - 3.14) < 0.001, 'should encode and decode float');
|
|
235
|
+
t.end();
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
tap.test('osc: explicit string type encoding', (t) => {
|
|
239
|
+
// Test explicit string type to cover line 108
|
|
240
|
+
const message = {
|
|
241
|
+
oscType: 'message',
|
|
242
|
+
address: '/test',
|
|
243
|
+
args: [
|
|
244
|
+
{
|
|
245
|
+
type: 's',
|
|
246
|
+
value: 'hello'
|
|
247
|
+
}
|
|
248
|
+
]
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const buffer = _osc.toBuffer(message);
|
|
252
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
253
|
+
|
|
254
|
+
t.equal(decoded.args[0].value, 'hello', 'should encode and decode string');
|
|
255
|
+
t.end();
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
tap.test('osc: explicit blob type encoding', (t) => {
|
|
259
|
+
// Test explicit blob type to cover line 111
|
|
260
|
+
const testData = Buffer.from('blob data');
|
|
261
|
+
const message = {
|
|
262
|
+
oscType: 'message',
|
|
263
|
+
address: '/test',
|
|
264
|
+
args: [
|
|
265
|
+
{
|
|
266
|
+
type: 'b',
|
|
267
|
+
value: testData
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const buffer = _osc.toBuffer(message);
|
|
273
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
274
|
+
|
|
275
|
+
t.ok(Buffer.isBuffer(decoded.args[0].value), 'should decode as Buffer');
|
|
276
|
+
t.equal(decoded.args[0].value.toString(), 'blob data', 'should preserve blob data');
|
|
277
|
+
t.end();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
tap.test('osc: explicit boolean true type encoding', (t) => {
|
|
281
|
+
// Test explicit boolean true type to cover line 118
|
|
282
|
+
const message = {
|
|
283
|
+
oscType: 'message',
|
|
284
|
+
address: '/test',
|
|
285
|
+
args: [
|
|
286
|
+
{
|
|
287
|
+
type: 'T',
|
|
288
|
+
value: true
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const buffer = _osc.toBuffer(message);
|
|
294
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
295
|
+
|
|
296
|
+
t.equal(decoded.args[0].value, true, 'should encode and decode boolean true');
|
|
297
|
+
t.end();
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
tap.test('osc: MIDI type encoding with Buffer', (t) => {
|
|
301
|
+
// Test MIDI type with 4-byte Buffer
|
|
302
|
+
const midiData = Buffer.from([0x01, 0x90, 0x3C, 0x7F]); // port 1, note on, middle C, velocity 127
|
|
303
|
+
const message = {
|
|
304
|
+
oscType: 'message',
|
|
305
|
+
address: '/midi',
|
|
306
|
+
args: [
|
|
307
|
+
{
|
|
308
|
+
type: 'm',
|
|
309
|
+
value: midiData
|
|
310
|
+
}
|
|
311
|
+
]
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const buffer = _osc.toBuffer(message);
|
|
315
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
316
|
+
|
|
317
|
+
t.ok(Buffer.isBuffer(decoded.args[0].value), 'should decode as Buffer');
|
|
318
|
+
t.equal(decoded.args[0].value.length, 4, 'should be 4 bytes');
|
|
319
|
+
t.equal(decoded.args[0].value[0], 0x01, 'port id should match');
|
|
320
|
+
t.equal(decoded.args[0].value[1], 0x90, 'status byte should match');
|
|
321
|
+
t.equal(decoded.args[0].value[2], 0x3C, 'data1 should match');
|
|
322
|
+
t.equal(decoded.args[0].value[3], 0x7F, 'data2 should match');
|
|
323
|
+
t.end();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
tap.test('osc: MIDI type encoding with object', (t) => {
|
|
327
|
+
// Test MIDI type with object format
|
|
328
|
+
const message = {
|
|
329
|
+
oscType: 'message',
|
|
330
|
+
address: '/midi',
|
|
331
|
+
args: [
|
|
332
|
+
{
|
|
333
|
+
type: 'midi',
|
|
334
|
+
value: {
|
|
335
|
+
port: 2,
|
|
336
|
+
status: 0x80,
|
|
337
|
+
data1: 0x40,
|
|
338
|
+
data2: 0x00
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
const buffer = _osc.toBuffer(message);
|
|
345
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
346
|
+
|
|
347
|
+
t.ok(Buffer.isBuffer(decoded.args[0].value), 'should decode as Buffer');
|
|
348
|
+
t.equal(decoded.args[0].value[0], 2, 'port should match');
|
|
349
|
+
t.equal(decoded.args[0].value[1], 0x80, 'status should match');
|
|
350
|
+
t.equal(decoded.args[0].value[2], 0x40, 'data1 should match');
|
|
351
|
+
t.equal(decoded.args[0].value[3], 0x00, 'data2 should match');
|
|
352
|
+
t.end();
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
tap.test('osc: MIDI type with invalid buffer length', (t) => {
|
|
356
|
+
// Test MIDI type with wrong buffer length
|
|
357
|
+
const message = {
|
|
358
|
+
oscType: 'message',
|
|
359
|
+
address: '/midi',
|
|
360
|
+
args: [
|
|
361
|
+
{
|
|
362
|
+
type: 'm',
|
|
363
|
+
value: Buffer.from([0x90, 0x3C]) // Only 2 bytes
|
|
364
|
+
}
|
|
365
|
+
]
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
t.throws(() => {
|
|
369
|
+
_osc.toBuffer(message);
|
|
370
|
+
}, /MIDI message must be exactly 4 bytes/, 'should throw error for wrong buffer length');
|
|
371
|
+
t.end();
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
tap.test('osc: MIDI type with invalid value type', (t) => {
|
|
375
|
+
// Test MIDI type with invalid value
|
|
376
|
+
const message = {
|
|
377
|
+
oscType: 'message',
|
|
378
|
+
address: '/midi',
|
|
379
|
+
args: [
|
|
380
|
+
{
|
|
381
|
+
type: 'm',
|
|
382
|
+
value: 'invalid'
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
t.throws(() => {
|
|
388
|
+
_osc.toBuffer(message);
|
|
389
|
+
}, /MIDI value must be a 4-byte Buffer or object/, 'should throw error for invalid value type');
|
|
390
|
+
t.end();
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
tap.test('osc: MIDI type with partial object', (t) => {
|
|
394
|
+
// Test MIDI type with object having only some properties (should default others to 0)
|
|
395
|
+
const message = {
|
|
396
|
+
oscType: 'message',
|
|
397
|
+
address: '/midi',
|
|
398
|
+
args: [
|
|
399
|
+
{
|
|
400
|
+
type: 'm',
|
|
401
|
+
value: {
|
|
402
|
+
status: 0x90,
|
|
403
|
+
data1: 0x3C
|
|
404
|
+
// port and data2 should default to 0
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
]
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
const buffer = _osc.toBuffer(message);
|
|
411
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
412
|
+
|
|
413
|
+
t.equal(decoded.args[0].value[0], 0, 'port should default to 0');
|
|
414
|
+
t.equal(decoded.args[0].value[1], 0x90, 'status should match');
|
|
415
|
+
t.equal(decoded.args[0].value[2], 0x3C, 'data1 should match');
|
|
416
|
+
t.equal(decoded.args[0].value[3], 0, 'data2 should default to 0');
|
|
417
|
+
t.end();
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
tap.test('osc: MIDI type decoding with insufficient buffer data', (t) => {
|
|
421
|
+
// Test the error case in readMidi when buffer doesn't have enough bytes
|
|
422
|
+
// This manually crafts a malformed OSC buffer with MIDI type tag but insufficient data
|
|
423
|
+
|
|
424
|
+
// Create a minimal OSC message buffer with MIDI type but truncated data
|
|
425
|
+
// OSC Format: address + typetags + arguments
|
|
426
|
+
// Address: "/m" (padded to 4 bytes)
|
|
427
|
+
const address = Buffer.from('/m\0\0', 'ascii'); // 4 bytes
|
|
428
|
+
|
|
429
|
+
// Type tags: ",m" (padded to 4 bytes)
|
|
430
|
+
const typeTags = Buffer.from(',m\0\0', 'ascii'); // 4 bytes
|
|
431
|
+
|
|
432
|
+
// MIDI data: only 2 bytes instead of required 4
|
|
433
|
+
const insufficientMidiData = Buffer.from([0x90, 0x3C]); // Only 2 bytes, need 4
|
|
434
|
+
|
|
435
|
+
// Combine into malformed OSC buffer
|
|
436
|
+
const malformedBuffer = Buffer.concat([address, typeTags, insufficientMidiData]);
|
|
437
|
+
|
|
438
|
+
t.throws(() => {
|
|
439
|
+
_osc.fromBuffer(malformedBuffer);
|
|
440
|
+
}, /Not enough bytes for MIDI message/, 'should throw error when MIDI data is truncated');
|
|
441
|
+
t.end();
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
tap.test('osc: MIDI type with falsy status and data1 values', (t) => {
|
|
445
|
+
// Test MIDI type with object having undefined/falsy status and data1 (should default to 0)
|
|
446
|
+
const message = {
|
|
447
|
+
oscType: 'message',
|
|
448
|
+
address: '/midi',
|
|
449
|
+
args: [
|
|
450
|
+
{
|
|
451
|
+
type: 'm',
|
|
452
|
+
value: {
|
|
453
|
+
port: 5,
|
|
454
|
+
data2: 0x40
|
|
455
|
+
// status and data1 are undefined, should default to 0
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
]
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
const buffer = _osc.toBuffer(message);
|
|
462
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
463
|
+
|
|
464
|
+
t.equal(decoded.args[0].value[0], 5, 'port should match');
|
|
465
|
+
t.equal(decoded.args[0].value[1], 0, 'status should default to 0');
|
|
466
|
+
t.equal(decoded.args[0].value[2], 0, 'data1 should default to 0');
|
|
467
|
+
t.equal(decoded.args[0].value[3], 0x40, 'data2 should match');
|
|
468
|
+
t.end();
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
tap.test('osc: MIDI type with explicit zero status and data1 values', (t) => {
|
|
472
|
+
// Test MIDI type with object having explicit 0 values for status and data1
|
|
473
|
+
const message = {
|
|
474
|
+
oscType: 'message',
|
|
475
|
+
address: '/midi',
|
|
476
|
+
args: [
|
|
477
|
+
{
|
|
478
|
+
type: 'm',
|
|
479
|
+
value: {
|
|
480
|
+
port: 3,
|
|
481
|
+
status: 0,
|
|
482
|
+
data1: 0,
|
|
483
|
+
data2: 0x60
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
]
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
const buffer = _osc.toBuffer(message);
|
|
490
|
+
const decoded = _osc.fromBuffer(buffer);
|
|
491
|
+
|
|
492
|
+
t.equal(decoded.args[0].value[0], 3, 'port should match');
|
|
493
|
+
t.equal(decoded.args[0].value[1], 0, 'status should be 0');
|
|
494
|
+
t.equal(decoded.args[0].value[2], 0, 'data1 should be 0');
|
|
495
|
+
t.equal(decoded.args[0].value[3], 0x60, 'data2 should match');
|
|
496
|
+
t.end();
|
|
497
|
+
|
|
498
|
+
});
|
package/examples/esm.mjs
CHANGED
|
@@ -7,8 +7,8 @@ server.on('listening', () => {
|
|
|
7
7
|
console.log('OSC Server is Listening');
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
server.on('message', (msg) => {
|
|
11
|
-
console.log(`Message: ${msg}`);
|
|
10
|
+
server.on('message', (msg, rinfo) => {
|
|
11
|
+
console.log(`Message: ${msg}\nReceived from: ${rinfo.address}:${rinfo.port}`);
|
|
12
12
|
server.close();
|
|
13
13
|
});
|
|
14
14
|
|
package/examples/server.js
CHANGED
|
@@ -3,7 +3,7 @@ var { Server } = require('node-osc');
|
|
|
3
3
|
|
|
4
4
|
var oscServer = new Server(3333, '0.0.0.0');
|
|
5
5
|
|
|
6
|
-
oscServer.on('message', function (msg) {
|
|
7
|
-
console.log(`Message: ${msg}`);
|
|
6
|
+
oscServer.on('message', function (msg, rinfo) {
|
|
7
|
+
console.log(`Message: ${msg}\nReceived from: ${rinfo.address}:${rinfo.port}`);
|
|
8
8
|
oscServer.close();
|
|
9
9
|
});
|
package/lib/Bundle.mjs
CHANGED
package/lib/Client.mjs
CHANGED
package/lib/internal/decode.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fromBuffer } from 'osc
|
|
1
|
+
import { fromBuffer } from '#osc';
|
|
2
2
|
|
|
3
3
|
function sanitizeMessage(decoded) {
|
|
4
4
|
const message = [];
|
|
@@ -17,8 +17,8 @@ function sanitizeBundle(decoded) {
|
|
|
17
17
|
return decoded;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
function decode(data) {
|
|
21
|
-
const decoded =
|
|
20
|
+
function decode(data, customFromBuffer = fromBuffer) {
|
|
21
|
+
const decoded = customFromBuffer(data);
|
|
22
22
|
if (decoded.oscType === 'bundle') {
|
|
23
23
|
return sanitizeBundle(decoded);
|
|
24
24
|
}
|