node-osc 11.2.0 → 11.2.2

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 (48) hide show
  1. package/.github/workflows/bump-version.yml +3 -3
  2. package/.github/workflows/create-release.yml +4 -4
  3. package/.github/workflows/nodejs.yml +4 -4
  4. package/README.md +3 -2
  5. package/agent.md +330 -0
  6. package/dist/lib/Client.js +1 -1
  7. package/dist/lib/Message.js +3 -1
  8. package/dist/lib/Server.js +7 -12
  9. package/dist/lib/internal/decode.js +3 -1
  10. package/dist/lib/osc.js +32 -3
  11. package/dist/test/lib/osc.js +32 -3
  12. package/dist/test/test-bundle.js +13 -12
  13. package/dist/test/test-client.js +68 -37
  14. package/dist/test/test-decode.js +35 -0
  15. package/dist/test/test-e2e.js +9 -9
  16. package/dist/test/test-encode-decode.js +455 -0
  17. package/dist/test/test-error-handling.js +14 -13
  18. package/dist/test/test-message.js +261 -64
  19. package/dist/test/test-osc-internal.js +151 -0
  20. package/dist/test/test-promises.js +90 -26
  21. package/dist/test/test-server.js +19 -16
  22. package/docs/README.md +81 -0
  23. package/examples/README.md +3 -1
  24. package/lib/Client.mjs +1 -1
  25. package/lib/Message.mjs +3 -1
  26. package/lib/Server.mjs +7 -12
  27. package/lib/internal/decode.mjs +3 -1
  28. package/lib/osc.mjs +32 -3
  29. package/package.json +2 -2
  30. package/rollup.config.mjs +1 -0
  31. package/test/test-bundle.mjs +14 -13
  32. package/test/test-client.mjs +69 -38
  33. package/test/test-decode.mjs +35 -0
  34. package/test/test-e2e.mjs +10 -10
  35. package/test/test-encode-decode.mjs +455 -0
  36. package/test/test-error-handling.mjs +15 -14
  37. package/test/test-message.mjs +262 -66
  38. package/test/test-osc-internal.mjs +151 -0
  39. package/test/test-promises.mjs +91 -27
  40. package/test/test-server.mjs +20 -17
  41. package/types/Message.d.mts.map +1 -1
  42. package/types/Server.d.mts.map +1 -1
  43. package/types/internal/decode.d.mts.map +1 -1
  44. package/types/osc.d.mts.map +1 -1
  45. package/dist/test/test-getPort.js +0 -20
  46. package/dist/test/util.js +0 -34
  47. package/test/test-getPort.mjs +0 -18
  48. package/test/util.mjs +0 -34
@@ -1,29 +1,51 @@
1
1
  import { once } from 'node:events';
2
- import { beforeEach, test } from 'tap';
3
- import { bootstrap } from './util.mjs';
2
+ import { test } from 'tap';
4
3
 
5
4
  import { Server, Client } from 'node-osc';
6
5
 
7
- beforeEach(bootstrap);
8
-
9
6
  test('client: send with promise - array', async (t) => {
10
- const oscServer = new Server(t.context.port, '127.0.0.1');
11
- const client = new Client('127.0.0.1', t.context.port);
7
+ const server = new Server(0, '127.0.0.1');
8
+ await once(server, 'listening');
9
+ const client = new Client('127.0.0.1', server.port);
12
10
 
13
11
  t.plan(1);
14
12
 
13
+ server.on('message', (msg) => {
14
+ server.close();
15
+ t.same(msg, ['/test', 0, 1, 'testing', true], 'We should receive expected payload');
16
+ });
17
+
18
+ await client.send(['/test', 0, 1, 'testing', true]);
19
+ await client.close();
20
+ });
21
+
22
+ test('client: array is not mutated when sent with promise', async (t) => {
23
+ const oscServer = new Server(0, '127.0.0.1');
24
+ await once(oscServer, 'listening');
25
+ const client = new Client('127.0.0.1', oscServer.port);
26
+
27
+ t.plan(2);
28
+
29
+ const originalArray = ['/test', 0, 1, 'testing', true];
30
+ const expectedArray = ['/test', 0, 1, 'testing', true];
31
+
15
32
  oscServer.on('message', (msg) => {
16
33
  oscServer.close();
17
34
  t.same(msg, ['/test', 0, 1, 'testing', true], 'We should receive expected payload');
18
35
  });
19
36
 
20
- await client.send(['/test', 0, 1, 'testing', true]);
37
+ await client.send(originalArray);
38
+
39
+ // Verify the original array was not mutated
40
+ t.same(originalArray, expectedArray, 'Original array should not be mutated');
41
+
21
42
  await client.close();
22
43
  });
23
44
 
24
45
  test('client: send with promise - string', async (t) => {
25
- const oscServer = new Server(t.context.port, '127.0.0.1');
26
- const client = new Client('127.0.0.1', t.context.port);
46
+ const oscServer = new Server(0, '127.0.0.1');
47
+ await once(oscServer, 'listening');
48
+ const client = new Client('127.0.0.1', oscServer.port);
27
49
 
28
50
  t.plan(1);
29
51
 
@@ -37,8 +59,9 @@ test('client: send with promise - string', async (t) => {
37
59
  });
38
60
 
39
61
  test('client: send with promise - message object', async (t) => {
40
- const oscServer = new Server(t.context.port, '127.0.0.1');
41
- const client = new Client('127.0.0.1', t.context.port);
62
+ const oscServer = new Server(0, '127.0.0.1');
63
+ await once(oscServer, 'listening');
64
+ const client = new Client('127.0.0.1', oscServer.port);
42
65
 
43
66
  t.plan(1);
44
67
 
@@ -55,8 +78,9 @@ test('client: send with promise - message object', async (t) => {
55
78
  });
56
79
 
57
80
  test('client: send with promise - multiple args', async (t) => {
58
- const oscServer = new Server(t.context.port, '127.0.0.1');
59
- const client = new Client('127.0.0.1', t.context.port);
81
+ const oscServer = new Server(0, '127.0.0.1');
82
+ await once(oscServer, 'listening');
83
+ const client = new Client('127.0.0.1', oscServer.port);
60
84
 
61
85
  t.plan(1);
62
86
 
@@ -70,12 +94,15 @@ test('client: send with promise - multiple args', async (t) => {
70
94
  });
71
95
 
72
96
  test('client: send promise rejection on closed socket', async (t) => {
73
- const client = new Client('127.0.0.1', t.context.port);
97
+ const oscServer = new Server(0, '127.0.0.1');
98
+ await once(oscServer, 'listening');
99
+ const client = new Client('127.0.0.1', oscServer.port);
74
100
 
75
101
  t.plan(1);
76
102
 
77
103
  await client.close();
78
-
104
+ await oscServer.close();
105
+
79
106
  try {
80
107
  await client.send('/boom');
81
108
  t.fail('Should have thrown an error');
@@ -85,8 +112,9 @@ test('client: send promise rejection on closed socket', async (t) => {
85
112
  });
86
113
 
87
114
  test('client: async/await usage', async (t) => {
88
- const oscServer = new Server(t.context.port, '127.0.0.1');
89
- const client = new Client('127.0.0.1', t.context.port);
115
+ const oscServer = new Server(0, '127.0.0.1');
116
+ await once(oscServer, 'listening');
117
+ const client = new Client('127.0.0.1', oscServer.port);
90
118
 
91
119
  t.plan(1);
92
120
 
@@ -102,7 +130,7 @@ test('client: async/await usage', async (t) => {
102
130
  });
103
131
 
104
132
  test('server: close with promise', async (t) => {
105
- const oscServer = new Server(t.context.port, '127.0.0.1');
133
+ const oscServer = new Server(0, '127.0.0.1');
106
134
 
107
135
  t.plan(1);
108
136
 
@@ -113,7 +141,7 @@ test('server: close with promise', async (t) => {
113
141
  });
114
142
 
115
143
  test('server: no callback still emits listening event', async (t) => {
116
- const oscServer = new Server(t.context.port, '127.0.0.1');
144
+ const oscServer = new Server(0, '127.0.0.1');
117
145
 
118
146
  t.plan(1);
119
147
 
@@ -124,15 +152,16 @@ test('server: no callback still emits listening event', async (t) => {
124
152
  });
125
153
 
126
154
  test('client and server: full async/await workflow', async (t) => {
127
- const oscServer = new Server(t.context.port, '127.0.0.1');
128
- const client = new Client('127.0.0.1', t.context.port);
129
-
130
- t.plan(2);
155
+ t.plan(3);
156
+ const oscServer = new Server(0, '127.0.0.1');
131
157
 
132
158
  // Wait for server to be ready
133
159
  await once(oscServer, 'listening');
134
160
  t.pass('Server started');
135
161
 
162
+ const client = new Client('127.0.0.1', oscServer.port);
163
+ t.pass('Client created');
164
+
136
165
  // Set up message handler
137
166
  const messageReceived = once(oscServer, 'message');
138
167
 
@@ -147,9 +176,9 @@ test('client and server: full async/await workflow', async (t) => {
147
176
  });
148
177
 
149
178
  test('client: multiple sends with promises', async (t) => {
150
- const oscServer = new Server(t.context.port, '127.0.0.1');
151
- const client = new Client('127.0.0.1', t.context.port);
152
-
179
+ const oscServer = new Server(0, '127.0.0.1');
180
+ await once(oscServer, 'listening');
181
+ const client = new Client('127.0.0.1', oscServer.port);
153
182
  t.plan(3);
154
183
 
155
184
  const messages = [];
@@ -173,6 +202,8 @@ test('client: multiple sends with promises', async (t) => {
173
202
  });
174
203
 
175
204
  test('client: close promise rejection on error', async (t) => {
205
+ const oscServer = new Server(0, '127.0.0.1');
206
+ await once(oscServer, 'listening');
176
207
  const client = new Client('127.0.0.1', t.context.port);
177
208
 
178
209
  t.plan(1);
@@ -202,6 +233,7 @@ test('client: close promise rejection on error', async (t) => {
202
233
  };
203
234
 
204
235
  try {
236
+ await oscServer.close();
205
237
  await client.close();
206
238
  t.fail('Should have thrown an error');
207
239
  } catch (err) {
@@ -210,7 +242,7 @@ test('client: close promise rejection on error', async (t) => {
210
242
  });
211
243
 
212
244
  test('server: close promise rejection on error', async (t) => {
213
- const oscServer = new Server(t.context.port, '127.0.0.1');
245
+ const oscServer = new Server(0, '127.0.0.1');
214
246
 
215
247
  t.plan(1);
216
248
 
@@ -247,3 +279,35 @@ test('server: close promise rejection on error', async (t) => {
247
279
  t.equal(err.code, 'MOCK_ERROR', 'Should reject with mock error');
248
280
  }
249
281
  });
282
+
283
+ test('client: send promise rejection on send error', async (t) => {
284
+ const oscServer = new Server(0, '127.0.0.1');
285
+ await once(oscServer, 'listening');
286
+ const client = new Client('127.0.0.1', oscServer.port);
287
+
288
+ t.plan(1);
289
+
290
+ // Mock the socket's send method to simulate an error
291
+ const originalSend = client._sock.send;
292
+ client._sock.send = function(msg, offset, length, port, address, callback) {
293
+ // Simulate an error being passed to callback
294
+ const err = new Error('Mock send error');
295
+ err.code = 'MOCK_SEND_ERROR';
296
+ if (callback) {
297
+ setImmediate(() => callback(err));
298
+ }
299
+ };
300
+
301
+ t.teardown(async () => {
302
+ client._sock.send = originalSend;
303
+ await client.close();
304
+ await oscServer.close();
305
+ });
306
+
307
+ try {
308
+ await client.send('/test', 'data');
309
+ t.fail('Should have thrown an error');
310
+ } catch (err) {
311
+ t.equal(err.code, 'MOCK_SEND_ERROR', 'Should reject with mock send error');
312
+ }
313
+ });
@@ -1,21 +1,21 @@
1
- import { beforeEach, test } from 'tap';
2
- import { bootstrap } from './util.mjs';
1
+ import { once } from 'node:events';
2
+ import { test } from 'tap';
3
3
 
4
4
  import { Server, Client } from 'node-osc';
5
5
 
6
- beforeEach(bootstrap);
7
-
8
- test('server: create and close', (t) => {
6
+ test('server: create and close', async (t) => {
9
7
  t.plan(1);
10
- const oscServer = new Server(t.context.port, '127.0.0.1');
8
+ const oscServer = new Server(0, '127.0.0.1');
9
+ await once(oscServer, 'listening');
11
10
  oscServer.close((err) => {
12
11
  t.error(err);
13
12
  });
14
13
  });
15
14
 
16
- test('server: listen to message', (t) => {
17
- const oscServer = new Server(t.context.port);
18
- const client = new Client('127.0.0.1', t.context.port);
15
+ test('server: listen to message', async (t) => {
16
+ const oscServer = new Server(0);
17
+ await once(oscServer, 'listening');
18
+ const client = new Client('127.0.0.1', oscServer.port);
19
19
 
20
20
  t.plan(3);
21
21
 
@@ -37,9 +37,10 @@ test('server: listen to message', (t) => {
37
37
  });
38
38
  });
39
39
 
40
- test('server: no defined host', (t) => {
41
- const oscServer = new Server(t.context.port);
42
- const client = new Client('127.0.0.1', t.context.port);
40
+ test('server: no defined host', async (t) => {
41
+ const oscServer = new Server(0);
42
+ await once(oscServer, 'listening');
43
+ const client = new Client('127.0.0.1', oscServer.port);
43
44
 
44
45
  t.plan(3);
45
46
 
@@ -61,12 +62,13 @@ test('server: no defined host', (t) => {
61
62
  });
62
63
  });
63
64
 
64
- test('server: callback as second arg', (t) => {
65
+ test('server: callback as second arg', async (t) => {
65
66
  t.plan(4);
66
- const oscServer = new Server(t.context.port, () => {
67
+ const oscServer = new Server(0, () => {
67
68
  t.ok('callback called');
68
69
  });
69
- const client = new Client('127.0.0.1', t.context.port);
70
+ await once(oscServer, 'listening');
71
+ const client = new Client('127.0.0.1', oscServer.port);
70
72
 
71
73
  t.teardown(() => {
72
74
  oscServer.close();
@@ -86,9 +88,10 @@ test('server: callback as second arg', (t) => {
86
88
  });
87
89
  });
88
90
 
89
- test('server: bad message', (t) => {
91
+ test('server: bad message', async (t) => {
90
92
  t.plan(2);
91
- const oscServer = new Server(t.context.port, '127.0.0.1');
93
+ const oscServer = new Server(0, '127.0.0.1');
94
+ await once(oscServer, 'listening');
92
95
  t.throws(() => {
93
96
  oscServer._sock.emit('message', 'whoops');
94
97
  }, /can't decode incoming message:/);
@@ -1 +1 @@
1
- {"version":3,"file":"Message.d.mts","sourceRoot":"","sources":["../lib/Message.mjs"],"names":[],"mappings":";AAyBA;;;;;;;;;;;;;;;;;;GAkBG;AACH;IACE;;;;;;;;;;;;;;OAcG;IACH,qBAZW,MAAM,WACH,GAAC,EAAA,EAed;IAHC,gBAAwB;IACxB,gBAAsB;IACtB,YAAgB;IAGlB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,YA7BW,GAAC,QA2DX;CACF"}
1
+ {"version":3,"file":"Message.d.mts","sourceRoot":"","sources":["../lib/Message.mjs"],"names":[],"mappings":";AAyBA;;;;;;;;;;;;;;;;;;GAkBG;AACH;IACE;;;;;;;;;;;;;;OAcG;IACH,qBAZW,MAAM,WACH,GAAC,EAAA,EAed;IAHC,gBAAwB;IACxB,gBAAsB;IACtB,YAAgB;IAGlB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,YA7BW,GAAC,QA6DX;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"Server.d.mts","sourceRoot":"","sources":["../lib/Server.mjs"],"names":[],"mappings":";AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH;IACE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,kBApBW,MAAM,SACN,MAAM,iBAqEhB;IA1CC,aAAgB;IAChB,aAAgB;IAChB,8BAGE;IAsCJ;;;;;;;;;;;;;;;;;OAiBG;IACH,sBAZa,OAAO,CAAC,IAAI,CAAC,GAAC,SAAS,CAuBnC;CACF;6BA5J4B,aAAa"}
1
+ {"version":3,"file":"Server.d.mts","sourceRoot":"","sources":["../lib/Server.mjs"],"names":[],"mappings":";AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH;IACE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,kBApBW,MAAM,SACN,MAAM,iBAgEhB;IArCC,aAAgB;IAChB,aAAgB;IAChB,8BAGE;IAiCJ;;;;;;;;;;;;;;;;;OAiBG;IACH,sBAZa,OAAO,CAAC,IAAI,CAAC,GAAC,SAAS,CAuBnC;CACF;6BAvJ4B,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"decode.d.mts","sourceRoot":"","sources":["../../lib/internal/decode.mjs"],"names":[],"mappings":";AAmBA,iFAWC;uBA9BsB,YAAY"}
1
+ {"version":3,"file":"decode.d.mts","sourceRoot":"","sources":["../../lib/internal/decode.mjs"],"names":[],"mappings":";AAqBA,iFAWC;uBAhCsB,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"osc.d.mts","sourceRoot":"","sources":["../lib/osc.mjs"],"names":[],"mappings":"AA+MA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,sCAtBa,MAAM,CA4BlB;AA6CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,+BAzBW,MAAM,OAgChB;uBAlUsB,aAAa"}
1
+ {"version":3,"file":"osc.d.mts","sourceRoot":"","sources":["../lib/osc.mjs"],"names":[],"mappings":"AAyOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,sCAtBa,MAAM,CA4BlB;AA6CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,+BAzBW,MAAM,OAgChB;uBA5VsB,aAAa"}
@@ -1,20 +0,0 @@
1
- 'use strict';
2
-
3
- var tap = require('tap');
4
- var util = require('./util.js');
5
- var node_net = require('node:net');
6
-
7
- tap.test('getPort function returns an available port', async (t) => {
8
- const port = await util.getPort();
9
- t.plan(2);
10
- t.type(port, 'number', 'getPort should return a number');
11
-
12
- const server = node_net.createServer();
13
- server.listen(port, () => {
14
- t.pass('Port is usable');
15
- });
16
- server.on('close', () => {
17
- t.pass('Server closed');
18
- });
19
- server.close();
20
- });
package/dist/test/util.js DELETED
@@ -1,34 +0,0 @@
1
- 'use strict';
2
-
3
- var node_net = require('node:net');
4
- var promises = require('node:timers/promises');
5
-
6
- async function bootstrap(t) {
7
- const port = await getPort();
8
- t.context = {
9
- port
10
- };
11
- }
12
-
13
- async function getPort() {
14
- const server = node_net.createServer();
15
- server.unref();
16
-
17
- const port = await new Promise((resolve, reject) => {
18
- server.on('error', reject);
19
- server.listen(() => {
20
- resolve(server.address().port);
21
- });
22
- });
23
-
24
- await server.close();
25
-
26
- // Allow the event loop to process and ensure port is fully released
27
- // This prevents EACCES errors when immediately rebinding to the same port
28
- await promises.setImmediate();
29
-
30
- return port;
31
- }
32
-
33
- exports.bootstrap = bootstrap;
34
- exports.getPort = getPort;
@@ -1,18 +0,0 @@
1
- import { test } from 'tap';
2
- import { getPort } from './util.mjs';
3
- import { createServer } from 'node:net';
4
-
5
- test('getPort function returns an available port', async (t) => {
6
- const port = await getPort();
7
- t.plan(2);
8
- t.type(port, 'number', 'getPort should return a number');
9
-
10
- const server = createServer();
11
- server.listen(port, () => {
12
- t.pass('Port is usable');
13
- });
14
- server.on('close', () => {
15
- t.pass('Server closed');
16
- });
17
- server.close();
18
- });
package/test/util.mjs DELETED
@@ -1,34 +0,0 @@
1
- import { createServer } from 'node:net';
2
- import { setImmediate } from 'node:timers/promises';
3
-
4
- async function bootstrap(t) {
5
- const port = await getPort();
6
- t.context = {
7
- port
8
- };
9
- }
10
-
11
- async function getPort() {
12
- const server = createServer();
13
- server.unref();
14
-
15
- const port = await new Promise((resolve, reject) => {
16
- server.on('error', reject);
17
- server.listen(() => {
18
- resolve(server.address().port);
19
- });
20
- });
21
-
22
- await server.close();
23
-
24
- // Allow the event loop to process and ensure port is fully released
25
- // This prevents EACCES errors when immediately rebinding to the same port
26
- await setImmediate();
27
-
28
- return port;
29
- }
30
-
31
- export {
32
- bootstrap,
33
- getPort
34
- };