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/lib/Client.mjs CHANGED
@@ -1,42 +1,92 @@
1
1
  import { createSocket } from 'node:dgram';
2
- import { toBuffer } from '#osc';
2
+ import { EventEmitter } from 'node:events';
3
+ import { encode } from './osc.mjs';
3
4
  import Message from './Message.mjs';
4
5
 
5
- class Client {
6
+ /**
7
+ * OSC Client for sending messages and bundles over UDP.
8
+ *
9
+ * Extends EventEmitter and emits the following events:
10
+ * - 'error': Emitted when a socket error occurs
11
+ *
12
+ * @class
13
+ * @extends EventEmitter
14
+ * @example
15
+ * // Create a client
16
+ * const client = new Client('127.0.0.1', 3333);
17
+ *
18
+ * // Send a message with callback
19
+ * client.send('/oscAddress', 200, (err) => {
20
+ * if (err) console.error(err);
21
+ * client.close();
22
+ * });
23
+ *
24
+ * @example
25
+ * // Send a message with async/await
26
+ * const client = new Client('127.0.0.1', 3333);
27
+ * await client.send('/oscAddress', 200);
28
+ * await client.close();
29
+ */
30
+ class Client extends EventEmitter {
31
+ /**
32
+ * Create an OSC Client.
33
+ *
34
+ * @param {string} host - The hostname or IP address of the OSC server.
35
+ * @param {number} port - The port number of the OSC server.
36
+ *
37
+ * @example
38
+ * const client = new Client('127.0.0.1', 3333);
39
+ */
6
40
  constructor(host, port) {
41
+ super();
7
42
  this.host = host;
8
43
  this.port = port;
9
44
  this._sock = createSocket({
10
45
  type: 'udp4',
11
46
  reuseAddr: true
12
47
  });
48
+
49
+ this._sock.on('error', (err) => {
50
+ this.emit('error', err);
51
+ });
13
52
  }
53
+ /**
54
+ * Close the client socket.
55
+ *
56
+ * This method can be used with either a callback or as a Promise.
57
+ *
58
+ * @param {Function} [cb] - Optional callback function called when socket is closed.
59
+ * @returns {Promise<void>|undefined} Returns a Promise if no callback is provided.
60
+ *
61
+ * @example
62
+ * // With callback
63
+ * client.close((err) => {
64
+ * if (err) console.error(err);
65
+ * });
66
+ *
67
+ * @example
68
+ * // With async/await
69
+ * await client.close();
70
+ */
14
71
  close(cb) {
15
- this._sock.close(cb);
16
- }
17
- send(...args) {
18
- let message = args[0];
19
- let callback;
20
- if (typeof args[args.length - 1] === 'function') {
21
- callback = args.pop();
22
- }
23
- else {
24
- callback = () => {};
72
+ if (cb) {
73
+ this._sock.close(cb);
74
+ } else {
75
+ return new Promise((resolve, reject) => {
76
+ this._sock.close((err) => {
77
+ if (err) reject(err);
78
+ else resolve();
79
+ });
80
+ });
25
81
  }
26
-
27
- if (message instanceof Array) {
28
- message = {
29
- address: message[0],
30
- args: message.splice(1)
31
- };
32
- }
33
-
82
+ }
83
+ _performSend(message, args, callback) {
34
84
  let mes;
35
85
  let buf;
36
86
  try {
37
87
  switch (typeof message) {
38
88
  case 'object':
39
- buf = toBuffer(message);
89
+ buf = encode(message);
40
90
  this._sock.send(buf, 0, buf.length, this.port, this.host, callback);
41
91
  break;
42
92
  case 'string':
@@ -44,7 +94,7 @@ class Client {
44
94
  for (let i = 1; i < args.length; i++) {
45
95
  mes.append(args[i]);
46
96
  }
47
- buf = toBuffer(mes);
97
+ buf = encode(mes);
48
98
  this._sock.send(buf, 0, buf.length, this.port, this.host, callback);
49
99
  break;
50
100
  default:
@@ -58,6 +108,71 @@ class Client {
58
108
  callback(error);
59
109
  }
60
110
  }
111
+ /**
112
+ * Send an OSC message or bundle to the server.
113
+ *
114
+ * This method can be used with either a callback or as a Promise.
115
+ * Messages can be sent in several formats:
116
+ * - As separate arguments: address followed by values
117
+ * - As a Message or Bundle object
118
+ * - As an array: [address, ...values]
119
+ *
120
+ * @param {...*} args - The message to send. Can be:
121
+ * - (address: string, ...values: any[], callback?: Function)
122
+ * - (message: Message|Bundle, callback?: Function)
123
+ * - (array: Array, callback?: Function)
124
+ * @returns {Promise<void>|undefined} Returns a Promise if no callback is provided.
125
+ *
126
+ * @throws {TypeError} If the message format is invalid.
127
+ * @throws {ReferenceError} If attempting to send on a closed socket.
128
+ *
129
+ * @example
130
+ * // Send with address and arguments
131
+ * client.send('/oscAddress', 200, 'hello', (err) => {
132
+ * if (err) console.error(err);
133
+ * });
134
+ *
135
+ * @example
136
+ * // Send with async/await
137
+ * await client.send('/oscAddress', 200, 'hello');
138
+ *
139
+ * @example
140
+ * // Send a Message object
141
+ * const msg = new Message('/test', 1, 2, 3);
142
+ * await client.send(msg);
143
+ *
144
+ * @example
145
+ * // Send a Bundle object
146
+ * const bundle = new Bundle(['/one', 1], ['/two', 2]);
147
+ * await client.send(bundle);
148
+ */
149
+ send(...args) {
150
+ let message = args[0];
151
+ let callback;
152
+
153
+ // Convert array syntax to message object
154
+ if (message instanceof Array) {
155
+ message = {
156
+ address: message[0],
157
+ args: message.splice(1)
158
+ };
159
+ }
160
+
161
+ if (typeof args[args.length - 1] === 'function') {
162
+ callback = args.pop();
163
+ this._performSend(message, args, callback);
164
+ }
165
+ else {
166
+ // No callback provided, return a Promise
167
+ return new Promise((resolve, reject) => {
168
+ callback = (err) => {
169
+ if (err) reject(err);
170
+ else resolve();
171
+ };
172
+ this._performSend(message, args, callback);
173
+ });
174
+ }
175
+ }
61
176
  }
62
177
 
63
178
  export default Client;
package/lib/Message.mjs CHANGED
@@ -2,23 +2,109 @@ const typeTags = {
2
2
  s: 'string',
3
3
  f: 'float',
4
4
  i: 'integer',
5
- b: 'blob'
5
+ b: 'blob',
6
+ m: 'midi'
6
7
  };
7
8
 
9
+ /**
10
+ * Represents a typed argument for an OSC message.
11
+ *
12
+ * @class
13
+ * @private
14
+ */
8
15
  class Argument {
16
+ /**
17
+ * @param {string} type - The type of the argument (string, float, integer, blob, boolean).
18
+ * @param {*} value - The value of the argument.
19
+ */
9
20
  constructor(type, value) {
10
21
  this.type = type;
11
22
  this.value = value;
12
23
  }
13
24
  }
14
25
 
26
+ /**
27
+ * Represents an OSC message with an address and arguments.
28
+ *
29
+ * OSC messages consist of an address pattern (string starting with '/')
30
+ * and zero or more arguments of various types.
31
+ *
32
+ * @class
33
+ *
34
+ * @example
35
+ * // Create a message with constructor arguments
36
+ * const msg = new Message('/test', 1, 2, 'hello');
37
+ *
38
+ * @example
39
+ * // Create a message and append arguments
40
+ * const msg = new Message('/test');
41
+ * msg.append(1);
42
+ * msg.append('hello');
43
+ * msg.append(3.14);
44
+ */
15
45
  class Message {
46
+ /**
47
+ * Create an OSC Message.
48
+ *
49
+ * @param {string} address - The OSC address pattern (e.g., '/oscillator/frequency').
50
+ * @param {...*} args - Optional arguments to include in the message.
51
+ *
52
+ * @example
53
+ * const msg = new Message('/test');
54
+ *
55
+ * @example
56
+ * const msg = new Message('/test', 1, 2, 3);
57
+ *
58
+ * @example
59
+ * const msg = new Message('/synth', 'note', 60, 0.5);
60
+ */
16
61
  constructor(address, ...args) {
17
62
  this.oscType = 'message';
18
63
  this.address = address;
19
64
  this.args = args;
20
65
  }
21
66
 
67
+ /**
68
+ * Append an argument to the message.
69
+ *
70
+ * Automatically detects the type based on the JavaScript type:
71
+ * - Integers are encoded as OSC integers
72
+ * - Floats are encoded as OSC floats
73
+ * - Strings are encoded as OSC strings
74
+ * - Booleans are encoded as OSC booleans
75
+ * - Buffers are encoded as OSC blobs
76
+ * - Arrays are recursively appended
77
+ * - Objects with a 'type' property are used as-is
78
+ *
79
+ * @param {*} arg - The argument to append. Can be:
80
+ * - A primitive value (number, string, boolean)
81
+ * - A Buffer (encoded as blob)
82
+ * - An array of values (will be recursively appended)
83
+ * - An object with 'type' and 'value' properties for explicit type control
84
+ *
85
+ * @throws {Error} If the argument type cannot be encoded.
86
+ *
87
+ * @example
88
+ * const msg = new Message('/test');
89
+ * msg.append(42); // Integer
90
+ * msg.append(3.14); // Float
91
+ * msg.append('hello'); // String
92
+ * msg.append(true); // Boolean
93
+ *
94
+ * @example
95
+ * // Append multiple values at once
96
+ * msg.append([1, 2, 3]);
97
+ *
98
+ * @example
99
+ * // Explicitly specify type
100
+ * msg.append({ type: 'float', value: 42 });
101
+ * msg.append({ type: 'blob', value: Buffer.from('data') });
102
+ *
103
+ * @example
104
+ * // MIDI messages (4 bytes: port, status, data1, data2)
105
+ * msg.append({ type: 'midi', value: { port: 0, status: 144, data1: 60, data2: 127 } });
106
+ * msg.append({ type: 'm', value: Buffer.from([0, 144, 60, 127]) });
107
+ */
22
108
  append(arg) {
23
109
  let argOut;
24
110
  switch (typeof arg) {
package/lib/Server.mjs CHANGED
@@ -3,14 +3,84 @@ import { EventEmitter } from 'node:events';
3
3
 
4
4
  import decode from '#decode';
5
5
 
6
+ /**
7
+ * OSC Server for receiving messages and bundles over UDP.
8
+ *
9
+ * Emits the following events:
10
+ * - 'listening': Emitted when the server starts listening
11
+ * - 'message': Emitted when an OSC message is received (receives msg array and rinfo object)
12
+ * - 'bundle': Emitted when an OSC bundle is received (receives bundle object and rinfo object)
13
+ * - 'error': Emitted when a socket error or decoding error occurs (receives error and rinfo)
14
+ * - Address-specific events: Emitted for each message address (e.g., '/test')
15
+ *
16
+ * @class
17
+ * @extends EventEmitter
18
+ *
19
+ * @fires Server#listening
20
+ * @fires Server#message
21
+ * @fires Server#bundle
22
+ * @fires Server#error
23
+ *
24
+ * @example
25
+ * // Create and listen for messages
26
+ * const server = new Server(3333, '0.0.0.0', () => {
27
+ * console.log('Server is listening');
28
+ * });
29
+ *
30
+ * server.on('message', (msg, rinfo) => {
31
+ * console.log('Message:', msg);
32
+ * console.log('From:', rinfo.address, rinfo.port);
33
+ * });
34
+ *
35
+ * @example
36
+ * // Using async/await with events.once
37
+ * import { once } from 'node:events';
38
+ *
39
+ * const server = new Server(3333, '0.0.0.0');
40
+ * await once(server, 'listening');
41
+ *
42
+ * server.on('message', (msg) => {
43
+ * console.log('Message:', msg);
44
+ * });
45
+ *
46
+ * @example
47
+ * // Listen for specific OSC addresses
48
+ * server.on('/note', (msg) => {
49
+ * const [address, pitch, velocity] = msg;
50
+ * console.log(`Note: ${pitch}, Velocity: ${velocity}`);
51
+ * });
52
+ */
6
53
  class Server extends EventEmitter {
54
+ /**
55
+ * Create an OSC Server.
56
+ *
57
+ * @param {number} port - The port to listen on.
58
+ * @param {string} [host='127.0.0.1'] - The host address to bind to. Use '0.0.0.0' to listen on all interfaces.
59
+ * @param {Function} [cb] - Optional callback function called when server starts listening.
60
+ *
61
+ * @example
62
+ * // Basic server
63
+ * const server = new Server(3333);
64
+ *
65
+ * @example
66
+ * // Server on all interfaces with callback
67
+ * const server = new Server(3333, '0.0.0.0', () => {
68
+ * console.log('Server started');
69
+ * });
70
+ *
71
+ * @example
72
+ * // Host parameter can be omitted, callback as second parameter
73
+ * const server = new Server(3333, () => {
74
+ * console.log('Server started on 127.0.0.1');
75
+ * });
76
+ */
7
77
  constructor(port, host='127.0.0.1', cb) {
8
78
  super();
9
79
  if (typeof host === 'function') {
10
80
  cb = host;
11
81
  host = '127.0.0.1';
12
82
  }
13
- if (!cb) cb = () => {};
83
+
14
84
  let decoded;
15
85
  this.port = port;
16
86
  this.host = host;
@@ -19,10 +89,20 @@ class Server extends EventEmitter {
19
89
  reuseAddr: true
20
90
  });
21
91
  this._sock.bind(port, host);
22
- this._sock.on('listening', () => {
23
- this.emit('listening');
24
- cb();
25
- });
92
+
93
+ // Support both callback and promise-based listening
94
+ if (cb) {
95
+ this._sock.on('listening', () => {
96
+ this.emit('listening');
97
+ cb();
98
+ });
99
+ } else {
100
+ // For promise support, still emit the event but don't require a callback
101
+ this._sock.on('listening', () => {
102
+ this.emit('listening');
103
+ });
104
+ }
105
+
26
106
  this._sock.on('message', (msg, rinfo) => {
27
107
  try {
28
108
  decoded = decode(msg);
@@ -40,9 +120,40 @@ class Server extends EventEmitter {
40
120
  this.emit(decoded[0], decoded, rinfo);
41
121
  }
42
122
  });
123
+
124
+ this._sock.on('error', (err) => {
125
+ this.emit('error', err);
126
+ });
43
127
  }
128
+ /**
129
+ * Close the server socket.
130
+ *
131
+ * This method can be used with either a callback or as a Promise.
132
+ *
133
+ * @param {Function} [cb] - Optional callback function called when socket is closed.
134
+ * @returns {Promise<void>|undefined} Returns a Promise if no callback is provided.
135
+ *
136
+ * @example
137
+ * // With callback
138
+ * server.close((err) => {
139
+ * if (err) console.error(err);
140
+ * });
141
+ *
142
+ * @example
143
+ * // With async/await
144
+ * await server.close();
145
+ */
44
146
  close(cb) {
45
- this._sock.close(cb);
147
+ if (cb) {
148
+ this._sock.close(cb);
149
+ } else {
150
+ return new Promise((resolve, reject) => {
151
+ this._sock.close((err) => {
152
+ if (err) reject(err);
153
+ else resolve();
154
+ });
155
+ });
156
+ }
46
157
  }
47
158
  }
48
159
 
package/lib/index.mjs CHANGED
@@ -2,3 +2,4 @@ export { default as Message } from './Message.mjs';
2
2
  export { default as Bundle } from './Bundle.mjs';
3
3
  export { default as Server } from './Server.mjs';
4
4
  export { default as Client } from './Client.mjs';
5
+ export { encode, decode } from './osc.mjs';
@@ -1,4 +1,4 @@
1
- import { fromBuffer } from '#osc';
1
+ import { decode } from '../osc.mjs';
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, customFromBuffer = fromBuffer) {
21
- const decoded = customFromBuffer(data);
20
+ function decodeAndSanitize(data, customDecode = decode) {
21
+ const decoded = customDecode(data);
22
22
  if (decoded.oscType === 'bundle') {
23
23
  return sanitizeBundle(decoded);
24
24
  }
@@ -30,4 +30,4 @@ function decode(data, customFromBuffer = fromBuffer) {
30
30
  }
31
31
  }
32
32
 
33
- export default decode;
33
+ export default decodeAndSanitize;
@@ -1,10 +1,10 @@
1
- 'use strict';
2
-
3
1
  // OSC 1.0 Protocol Implementation
4
2
  // Based on http://opensoundcontrol.org/spec-1_0
5
3
 
6
4
  // Helper functions for OSC encoding/decoding
7
5
 
6
+ import { Buffer } from 'node:buffer';
7
+
8
8
  function padString(str) {
9
9
  const nullTerminated = str + '\0';
10
10
  const padding = 4 - (nullTerminated.length % 4);
@@ -149,6 +149,9 @@ function encodeArgument(arg) {
149
149
  // For doubles, use float for now (OSC 1.0 doesn't have double)
150
150
  return { tag: 'f', data: writeFloat32(arg.value) };
151
151
  case 'T':
152
+ return { tag: 'T', data: Buffer.alloc(0) };
153
+ case 'F':
154
+ return { tag: 'F', data: Buffer.alloc(0) };
152
155
  case 'boolean':
153
156
  return arg.value ? { tag: 'T', data: Buffer.alloc(0) } : { tag: 'F', data: Buffer.alloc(0) };
154
157
  case 'm':
@@ -202,7 +205,37 @@ function decodeArgument(tag, buffer, offset) {
202
205
  }
203
206
  }
204
207
 
205
- function toBuffer(message) {
208
+ /**
209
+ * Encode an OSC message or bundle to a Buffer.
210
+ *
211
+ * This low-level function converts OSC messages and bundles into binary format
212
+ * for transmission or storage. Useful for sending OSC over custom transports
213
+ * (WebSocket, TCP, HTTP), storing to files, or implementing custom OSC routers.
214
+ *
215
+ * @param {Object} message - OSC message or bundle object with oscType property
216
+ * @returns {Buffer} The encoded OSC data ready for transmission
217
+ *
218
+ * @example
219
+ * // Encode a message
220
+ * import { Message, encode } from 'node-osc';
221
+ *
222
+ * const message = new Message('/oscillator/frequency', 440);
223
+ * const buffer = encode(message);
224
+ * console.log('Encoded bytes:', buffer.length);
225
+ *
226
+ * @example
227
+ * // Encode a bundle
228
+ * import { Bundle, encode } from 'node-osc';
229
+ *
230
+ * const bundle = new Bundle(['/one', 1], ['/two', 2]);
231
+ * const buffer = encode(bundle);
232
+ *
233
+ * @example
234
+ * // Send over WebSocket
235
+ * const buffer = encode(message);
236
+ * websocket.send(buffer);
237
+ */
238
+ function encode(message) {
206
239
  if (message.oscType === 'bundle') {
207
240
  return encodeBundleToBuffer(message);
208
241
  } else {
@@ -253,7 +286,39 @@ function encodeBundleToBuffer(bundle) {
253
286
  return Buffer.concat([bundleStringBuffer, timetagBuffer, ...elementBuffers]);
254
287
  }
255
288
 
256
- function fromBuffer(buffer) {
289
+ /**
290
+ * Decode a Buffer containing OSC data into a message or bundle object.
291
+ *
292
+ * This low-level function parses binary OSC data back into JavaScript objects.
293
+ * Useful for receiving OSC over custom transports, reading from files,
294
+ * or implementing custom OSC routers.
295
+ *
296
+ * @param {Buffer} buffer - The Buffer containing OSC data
297
+ * @returns {Object} The decoded OSC message or bundle. Messages have
298
+ * {oscType: 'message', address: string, args: Array}, bundles have
299
+ * {oscType: 'bundle', timetag: number, elements: Array}
300
+ * @throws {Error} If the buffer contains malformed OSC data
301
+ *
302
+ * @example
303
+ * // Decode received data
304
+ * import { decode } from 'node-osc';
305
+ *
306
+ * const decoded = decode(buffer);
307
+ * if (decoded.oscType === 'message') {
308
+ * console.log('Address:', decoded.address);
309
+ * console.log('Arguments:', decoded.args);
310
+ * }
311
+ *
312
+ * @example
313
+ * // Round-trip encode/decode
314
+ * import { Message, encode, decode } from 'node-osc';
315
+ *
316
+ * const original = new Message('/test', 42, 'hello');
317
+ * const buffer = encode(original);
318
+ * const decoded = decode(buffer);
319
+ * console.log(decoded.address); // '/test'
320
+ */
321
+ function decode(buffer) {
257
322
  // Check if it's a bundle or message
258
323
  if (buffer.length >= 8 && buffer.subarray(0, 8).toString() === '#bundle\0') {
259
324
  return decodeBundleFromBuffer(buffer);
@@ -313,7 +378,7 @@ function decodeBundleFromBuffer(buffer) {
313
378
 
314
379
  // Read element data
315
380
  const elementBuffer = buffer.subarray(offset, offset + size);
316
- const element = fromBuffer(elementBuffer);
381
+ const element = decode(elementBuffer);
317
382
  elements.push(element);
318
383
  offset += size;
319
384
  }
@@ -325,5 +390,4 @@ function decodeBundleFromBuffer(buffer) {
325
390
  };
326
391
  }
327
392
 
328
- exports.fromBuffer = fromBuffer;
329
- exports.toBuffer = toBuffer;
393
+ export { encode, decode };
package/package.json CHANGED
@@ -1,19 +1,17 @@
1
1
  {
2
2
  "name": "node-osc",
3
3
  "description": "pyOSC inspired library for sending and receiving OSC messages",
4
- "version": "11.1.0",
4
+ "version": "11.2.0",
5
5
  "exports": {
6
+ "types": "./types/index.d.mts",
6
7
  "require": "./dist/lib/index.js",
8
+ "import": "./lib/index.mjs",
7
9
  "default": "./lib/index.mjs"
8
10
  },
9
11
  "imports": {
10
12
  "#decode": {
11
13
  "require": "./dist/lib/internal/decode.js",
12
14
  "default": "./lib/internal/decode.mjs"
13
- },
14
- "#osc": {
15
- "require": "./dist/lib/internal/osc.js",
16
- "default": "./lib/internal/osc.mjs"
17
15
  }
18
16
  },
19
17
  "author": {
@@ -23,12 +21,14 @@
23
21
  "engines": {
24
22
  "node": "^20.9.0 || ^22.11.0 || >=24.0.0"
25
23
  },
26
- "license": "LGPL-3.0-or-later",
24
+ "license": "Apache-2.0",
27
25
  "scripts": {
28
- "clean": "rm -rf dist/",
29
- "build": "npm run clean && rollup --config rollup.config.mjs",
26
+ "clean": "rm -rf dist/ types/",
27
+ "build": "npm run clean && rollup --config rollup.config.mjs && npm run build:types",
28
+ "build:types": "tsc",
29
+ "docs": "node scripts/generate-docs.mjs",
30
30
  "prepublishOnly": "npm run build",
31
- "lint": "eslint \"lib/**/*.mjs\" test/* examples/* rollup.config.mjs",
31
+ "lint": "eslint \"lib/**/*.mjs\" \"test/test-*.mjs\" test/util.mjs examples/*.js examples/*.mjs rollup.config.mjs",
32
32
  "test": "npm run lint && npm run build && npm run test:esm && npm run test:cjs",
33
33
  "test:esm": "tap test/test-*.mjs",
34
34
  "test:cjs": "tap dist/test/test-*.js"
@@ -50,7 +50,9 @@
50
50
  "@eslint/js": "^9.32.0",
51
51
  "eslint": "^9.32.0",
52
52
  "globals": "^16.3.0",
53
+ "jsdoc": "^4.0.5",
53
54
  "rollup": "^4.46.2",
54
- "tap": "^21.1.0"
55
+ "tap": "^21.1.0",
56
+ "typescript": "^5.9.3"
55
57
  }
56
58
  }