node-osc 11.1.0 → 11.2.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 (69) hide show
  1. package/.gitattributes +11 -0
  2. package/.github/workflows/bump-version.yml +2 -0
  3. package/.github/workflows/nodejs.yml +3 -0
  4. package/LICENSE +201 -165
  5. package/README.md +135 -42
  6. package/dist/lib/Bundle.js +66 -0
  7. package/dist/lib/Client.js +137 -22
  8. package/dist/lib/Message.js +87 -1
  9. package/dist/lib/Server.js +117 -6
  10. package/dist/lib/index.js +3 -0
  11. package/dist/lib/internal/decode.js +4 -4
  12. package/{lib/internal/osc.mjs → dist/lib/osc.js} +94 -23
  13. package/dist/test/lib/osc.js +395 -0
  14. package/dist/test/test-client.js +152 -0
  15. package/dist/test/test-e2e.js +9 -3
  16. package/dist/test/test-encode-decode.js +849 -0
  17. package/dist/test/test-error-handling.js +116 -0
  18. package/dist/test/test-osc-internal.js +399 -41
  19. package/dist/test/test-promises.js +250 -0
  20. package/dist/test/test-types.js +42 -0
  21. package/dist/test/util.js +15 -8
  22. package/docs/API.md +477 -0
  23. package/docs/GUIDE.md +605 -0
  24. package/examples/README.md +119 -0
  25. package/examples/async-await.mjs +57 -0
  26. package/examples/bundle-example.mjs +92 -0
  27. package/examples/client.js +22 -5
  28. package/examples/error-handling.mjs +152 -0
  29. package/examples/esm.mjs +21 -0
  30. package/examples/server.js +16 -0
  31. package/jsdoc.json +16 -0
  32. package/lib/Bundle.mjs +66 -0
  33. package/lib/Client.mjs +137 -22
  34. package/lib/Message.mjs +87 -1
  35. package/lib/Server.mjs +117 -6
  36. package/lib/index.mjs +1 -0
  37. package/lib/internal/decode.mjs +4 -4
  38. package/{dist/lib/internal/osc.js → lib/osc.mjs} +71 -7
  39. package/package.json +12 -10
  40. package/rollup.config.mjs +48 -37
  41. package/scripts/generate-docs.mjs +229 -0
  42. package/test/fixtures/types/test-cjs-types.ts +19 -0
  43. package/test/fixtures/types/test-esm-types.ts +35 -0
  44. package/test/fixtures/types/tsconfig-cjs.test.json +17 -0
  45. package/test/fixtures/types/tsconfig-esm.test.json +17 -0
  46. package/test/test-bundle.mjs +0 -1
  47. package/test/test-client.mjs +152 -0
  48. package/test/test-e2e.mjs +9 -3
  49. package/test/test-encode-decode.mjs +847 -0
  50. package/test/test-error-handling.mjs +115 -0
  51. package/test/test-osc-internal.mjs +400 -42
  52. package/test/test-promises.mjs +249 -0
  53. package/test/test-types.mjs +39 -0
  54. package/test/util.mjs +15 -8
  55. package/tsconfig.json +45 -0
  56. package/types/Bundle.d.mts +70 -0
  57. package/types/Bundle.d.mts.map +1 -0
  58. package/types/Client.d.mts +101 -0
  59. package/types/Client.d.mts.map +1 -0
  60. package/types/Message.d.mts +84 -0
  61. package/types/Message.d.mts.map +1 -0
  62. package/types/Server.d.mts +98 -0
  63. package/types/Server.d.mts.map +1 -0
  64. package/types/index.d.mts +6 -0
  65. package/types/index.d.mts.map +1 -0
  66. package/types/internal/decode.d.mts +4 -0
  67. package/types/internal/decode.d.mts.map +1 -0
  68. package/types/osc.d.mts +66 -0
  69. package/types/osc.d.mts.map +1 -0
package/docs/API.md ADDED
@@ -0,0 +1,477 @@
1
+ <!-- Generated by JSDoc. Update this documentation by updating the source code. -->
2
+
3
+ # API Reference
4
+
5
+ > **⚠️ This file is auto-generated from JSDoc comments in the source code.**
6
+ > To update this documentation, edit the JSDoc comments in the source files and run `npm run docs`.
7
+
8
+ This document provides detailed API reference for all classes, methods, and functions in node-osc.
9
+
10
+ For usage guides, best practices, and troubleshooting, see the **[Guide](./GUIDE.md)**.
11
+
12
+ ## Table of Contents
13
+
14
+ - [Server](#server)
15
+ - [Constructor](#server-constructor)
16
+ - [close()](#server-close)
17
+ - [Client](#client)
18
+ - [Constructor](#client-constructor)
19
+ - [close()](#client-close)
20
+ - [send()](#client-send)
21
+ - [Message](#message)
22
+ - [Constructor](#message-constructor)
23
+ - [append()](#message-append)
24
+ - [Bundle](#bundle)
25
+ - [Constructor](#bundle-constructor)
26
+ - [append()](#bundle-append)
27
+ - [Low Level Functions](#low-level-functions)
28
+ - [encode()](#encode)
29
+ - [decode()](#decode)
30
+
31
+ ---
32
+
33
+ ## Server
34
+
35
+ **Extends:** EventEmitter
36
+
37
+ OSC Server for receiving messages and bundles over UDP.
38
+
39
+ Emits the following events:
40
+ - 'listening': Emitted when the server starts listening
41
+ - 'message': Emitted when an OSC message is received (receives msg array and rinfo object)
42
+ - 'bundle': Emitted when an OSC bundle is received (receives bundle object and rinfo object)
43
+ - 'error': Emitted when a socket error or decoding error occurs (receives error and rinfo)
44
+ - Address-specific events: Emitted for each message address (e.g., '/test')
45
+
46
+ ### Server Constructor
47
+
48
+ Creates a new Server instance.
49
+
50
+ **Parameters:**
51
+
52
+ - `port` *{number}* - The port to listen on.
53
+ - `host` *{string}* (optional) - Default: `'127.0.0.1'` - The host address to bind to. Use '0.0.0.0' to listen on all interfaces.
54
+ - `cb` *{function}* (optional) - Optional callback function called when server starts listening.
55
+
56
+ **Examples:**
57
+
58
+ ```javascript
59
+ // Create and listen for messages
60
+ const server = new Server(3333, '0.0.0.0', () => {
61
+ console.log('Server is listening');
62
+ });
63
+
64
+ server.on('message', (msg, rinfo) => {
65
+ console.log('Message:', msg);
66
+ console.log('From:', rinfo.address, rinfo.port);
67
+ });
68
+ ```
69
+
70
+ ```javascript
71
+ // Using async/await with events.once
72
+ import { once } from 'node:events';
73
+
74
+ const server = new Server(3333, '0.0.0.0');
75
+ await once(server, 'listening');
76
+
77
+ server.on('message', (msg) => {
78
+ console.log('Message:', msg);
79
+ });
80
+ ```
81
+
82
+ ```javascript
83
+ // Listen for specific OSC addresses
84
+ server.on('/note', (msg) => {
85
+ const [address, pitch, velocity] = msg;
86
+ console.log(`Note: ${pitch}, Velocity: ${velocity}`);
87
+ });
88
+ ```
89
+
90
+
91
+ ### Server.close()
92
+
93
+ Close the server socket.
94
+
95
+ This method can be used with either a callback or as a Promise.
96
+
97
+ **Parameters:**
98
+
99
+ - `cb` *{function}* (optional) - Optional callback function called when socket is closed.
100
+
101
+ **Returns:** *{Promise.<void> | undefined}* - Returns a Promise if no callback is provided.
102
+
103
+ **Examples:**
104
+
105
+ ```javascript
106
+ // With callback
107
+ server.close((err) => {
108
+ if (err) console.error(err);
109
+ });
110
+ ```
111
+
112
+ ```javascript
113
+ // With async/await
114
+ await server.close();
115
+ ```
116
+
117
+
118
+ ---
119
+
120
+ ## Client
121
+
122
+ **Extends:** EventEmitter
123
+
124
+ OSC Client for sending messages and bundles over UDP.
125
+
126
+ Extends EventEmitter and emits the following events:
127
+ - 'error': Emitted when a socket error occurs
128
+
129
+ ### Client Constructor
130
+
131
+ Creates a new Client instance.
132
+
133
+ **Parameters:**
134
+
135
+ - `host` *{string}* - The hostname or IP address of the OSC server.
136
+ - `port` *{number}* - The port number of the OSC server.
137
+
138
+ **Examples:**
139
+
140
+ ```javascript
141
+ // Create a client
142
+ const client = new Client('127.0.0.1', 3333);
143
+
144
+ // Send a message with callback
145
+ client.send('/oscAddress', 200, (err) => {
146
+ if (err) console.error(err);
147
+ client.close();
148
+ });
149
+ ```
150
+
151
+ ```javascript
152
+ // Send a message with async/await
153
+ const client = new Client('127.0.0.1', 3333);
154
+ await client.send('/oscAddress', 200);
155
+ await client.close();
156
+ ```
157
+
158
+
159
+ ### Client.close()
160
+
161
+ Close the client socket.
162
+
163
+ This method can be used with either a callback or as a Promise.
164
+
165
+ **Parameters:**
166
+
167
+ - `cb` *{function}* (optional) - Optional callback function called when socket is closed.
168
+
169
+ **Returns:** *{Promise.<void> | undefined}* - Returns a Promise if no callback is provided.
170
+
171
+ **Examples:**
172
+
173
+ ```javascript
174
+ // With callback
175
+ client.close((err) => {
176
+ if (err) console.error(err);
177
+ });
178
+ ```
179
+
180
+ ```javascript
181
+ // With async/await
182
+ await client.close();
183
+ ```
184
+
185
+
186
+ ### Client.send()
187
+
188
+ Send an OSC message or bundle to the server.
189
+
190
+ This method can be used with either a callback or as a Promise.
191
+ Messages can be sent in several formats:
192
+ - As separate arguments: address followed by values
193
+ - As a Message or Bundle object
194
+ - As an array: [address, ...values]
195
+
196
+ **Parameters:**
197
+
198
+ - `args` *{*}* - The message to send. Can be:
199
+ - (address: string, ...values: any[], callback?: Function)
200
+ - (message: Message|Bundle, callback?: Function)
201
+ - (array: Array, callback?: Function)
202
+
203
+ **Returns:** *{Promise.<void> | undefined}* - Returns a Promise if no callback is provided.
204
+
205
+ **Throws:**
206
+
207
+ - *{TypeError}* - If the message format is invalid.
208
+ - *{ReferenceError}* - If attempting to send on a closed socket.
209
+
210
+ **Examples:**
211
+
212
+ ```javascript
213
+ // Send with address and arguments
214
+ client.send('/oscAddress', 200, 'hello', (err) => {
215
+ if (err) console.error(err);
216
+ });
217
+ ```
218
+
219
+ ```javascript
220
+ // Send with async/await
221
+ await client.send('/oscAddress', 200, 'hello');
222
+ ```
223
+
224
+ ```javascript
225
+ // Send a Message object
226
+ const msg = new Message('/test', 1, 2, 3);
227
+ await client.send(msg);
228
+ ```
229
+
230
+ ```javascript
231
+ // Send a Bundle object
232
+ const bundle = new Bundle(['/one', 1], ['/two', 2]);
233
+ await client.send(bundle);
234
+ ```
235
+
236
+
237
+ ---
238
+
239
+ ## Message
240
+
241
+ Represents an OSC message with an address and arguments.
242
+
243
+ OSC messages consist of an address pattern (string starting with '/')
244
+ and zero or more arguments of various types.
245
+
246
+ ### Message Constructor
247
+
248
+ Creates a new Message instance.
249
+
250
+ **Parameters:**
251
+
252
+ - `address` *{string}* - The OSC address pattern (e.g., '/oscillator/frequency').
253
+ - `args` *{*}* - Optional arguments to include in the message.
254
+
255
+ **Examples:**
256
+
257
+ ```javascript
258
+ // Create a message with constructor arguments
259
+ const msg = new Message('/test', 1, 2, 'hello');
260
+ ```
261
+
262
+ ```javascript
263
+ // Create a message and append arguments
264
+ const msg = new Message('/test');
265
+ msg.append(1);
266
+ msg.append('hello');
267
+ msg.append(3.14);
268
+ ```
269
+
270
+
271
+ ### Message.append()
272
+
273
+ Append an argument to the message.
274
+
275
+ Automatically detects the type based on the JavaScript type:
276
+ - Integers are encoded as OSC integers
277
+ - Floats are encoded as OSC floats
278
+ - Strings are encoded as OSC strings
279
+ - Booleans are encoded as OSC booleans
280
+ - Buffers are encoded as OSC blobs
281
+ - Arrays are recursively appended
282
+ - Objects with a 'type' property are used as-is
283
+
284
+ **Parameters:**
285
+
286
+ - `arg` *{*}* - The argument to append. Can be:
287
+ - A primitive value (number, string, boolean)
288
+ - A Buffer (encoded as blob)
289
+ - An array of values (will be recursively appended)
290
+ - An object with 'type' and 'value' properties for explicit type control
291
+
292
+ **Throws:**
293
+
294
+ - *{Error}* - If the argument type cannot be encoded.
295
+
296
+ **Examples:**
297
+
298
+ ```javascript
299
+ const msg = new Message('/test');
300
+ msg.append(42); // Integer
301
+ msg.append(3.14); // Float
302
+ msg.append('hello'); // String
303
+ msg.append(true); // Boolean
304
+ ```
305
+
306
+ ```javascript
307
+ // Append multiple values at once
308
+ msg.append([1, 2, 3]);
309
+ ```
310
+
311
+ ```javascript
312
+ // Explicitly specify type
313
+ msg.append({ type: 'float', value: 42 });
314
+ msg.append({ type: 'blob', value: Buffer.from('data') });
315
+ ```
316
+
317
+ ```javascript
318
+ // MIDI messages (4 bytes: port, status, data1, data2)
319
+ msg.append({ type: 'midi', value: { port: 0, status: 144, data1: 60, data2: 127 } });
320
+ msg.append({ type: 'm', value: Buffer.from([0, 144, 60, 127]) });
321
+ ```
322
+
323
+
324
+ ---
325
+
326
+ ## Bundle
327
+
328
+ Represents an OSC bundle containing multiple messages or nested bundles.
329
+
330
+ OSC bundles allow multiple messages to be sent together, optionally with
331
+ a timetag indicating when the bundle should be processed.
332
+
333
+ ### Bundle Constructor
334
+
335
+ Creates a new Bundle instance.
336
+
337
+ **Parameters:**
338
+
339
+ - `timetagOrElement` *{number | Message | Bundle | Array}* (optional) - Timetag, or if not a number, the first element and timetag will default to 0.
340
+ - `elements` *{Message | Bundle | Array}* - Messages or bundles to include.
341
+ Arrays will be automatically converted to Message objects.
342
+
343
+ **Examples:**
344
+
345
+ ```javascript
346
+ // Create a bundle without a timetag
347
+ const bundle = new Bundle(['/one', 1], ['/two', 2]);
348
+ ```
349
+
350
+ ```javascript
351
+ // Create a bundle with a timetag
352
+ const bundle = new Bundle(10, ['/one', 1], ['/two', 2]);
353
+ ```
354
+
355
+ ```javascript
356
+ // Nest bundles
357
+ const bundle1 = new Bundle(['/one', 1]);
358
+ const bundle2 = new Bundle(['/two', 2]);
359
+ bundle1.append(bundle2);
360
+ ```
361
+
362
+
363
+ ### Bundle.append()
364
+
365
+ Append a message or bundle to this bundle.
366
+
367
+ **Parameters:**
368
+
369
+ - `element` *{Message | Bundle | Array}* - The message or bundle to append.
370
+ Arrays will be automatically converted to Message objects.
371
+
372
+ **Examples:**
373
+
374
+ ```javascript
375
+ const bundle = new Bundle();
376
+ bundle.append(['/test', 1]);
377
+ bundle.append(new Message('/test2', 2));
378
+ ```
379
+
380
+ ```javascript
381
+ // Append a nested bundle
382
+ const bundle1 = new Bundle(['/one', 1]);
383
+ const bundle2 = new Bundle(['/two', 2]);
384
+ bundle1.append(bundle2);
385
+ ```
386
+
387
+
388
+ ---
389
+
390
+ ## Low Level Functions
391
+
392
+ These functions provide low-level access to OSC encoding and decoding for advanced use cases.
393
+
394
+ ### encode()
395
+
396
+ Encode an OSC message or bundle to a Buffer.
397
+
398
+ This low-level function converts OSC messages and bundles into binary format
399
+ for transmission or storage. Useful for sending OSC over custom transports
400
+ (WebSocket, TCP, HTTP), storing to files, or implementing custom OSC routers.
401
+
402
+ **Parameters:**
403
+
404
+ - `message` *{Object}* - OSC message or bundle object with oscType property
405
+
406
+ **Returns:** *{Buffer}* - The encoded OSC data ready for transmission
407
+
408
+ **Examples:**
409
+
410
+ ```javascript
411
+ // Encode a message
412
+ import { Message, encode } from 'node-osc';
413
+
414
+ const message = new Message('/oscillator/frequency', 440);
415
+ const buffer = encode(message);
416
+ console.log('Encoded bytes:', buffer.length);
417
+ ```
418
+
419
+ ```javascript
420
+ // Encode a bundle
421
+ import { Bundle, encode } from 'node-osc';
422
+
423
+ const bundle = new Bundle(['/one', 1], ['/two', 2]);
424
+ const buffer = encode(bundle);
425
+ ```
426
+
427
+ ```javascript
428
+ // Send over WebSocket
429
+ const buffer = encode(message);
430
+ websocket.send(buffer);
431
+ ```
432
+
433
+
434
+ ### decode()
435
+
436
+ Decode a Buffer containing OSC data into a message or bundle object.
437
+
438
+ This low-level function parses binary OSC data back into JavaScript objects.
439
+ Useful for receiving OSC over custom transports, reading from files,
440
+ or implementing custom OSC routers.
441
+
442
+ **Parameters:**
443
+
444
+ - `buffer` *{Buffer}* - The Buffer containing OSC data
445
+
446
+ **Returns:** *{Object}* - The decoded OSC message or bundle. Messages have
447
+ {oscType: 'message', address: string, args: Array}, bundles have
448
+ {oscType: 'bundle', timetag: number, elements: Array}
449
+
450
+ **Throws:**
451
+
452
+ - *{Error}* - If the buffer contains malformed OSC data
453
+
454
+ **Examples:**
455
+
456
+ ```javascript
457
+ // Decode received data
458
+ import { decode } from 'node-osc';
459
+
460
+ const decoded = decode(buffer);
461
+ if (decoded.oscType === 'message') {
462
+ console.log('Address:', decoded.address);
463
+ console.log('Arguments:', decoded.args);
464
+ }
465
+ ```
466
+
467
+ ```javascript
468
+ // Round-trip encode/decode
469
+ import { Message, encode, decode } from 'node-osc';
470
+
471
+ const original = new Message('/test', 42, 'hello');
472
+ const buffer = encode(original);
473
+ const decoded = decode(buffer);
474
+ console.log(decoded.address); // '/test'
475
+ ```
476
+
477
+