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.
- package/.gitattributes +11 -0
- package/.github/workflows/bump-version.yml +2 -0
- package/.github/workflows/nodejs.yml +3 -0
- package/LICENSE +201 -165
- package/README.md +135 -42
- package/dist/lib/Bundle.js +66 -0
- package/dist/lib/Client.js +137 -22
- package/dist/lib/Message.js +87 -1
- package/dist/lib/Server.js +117 -6
- package/dist/lib/index.js +3 -0
- package/dist/lib/internal/decode.js +4 -4
- package/{lib/internal/osc.mjs → dist/lib/osc.js} +94 -23
- package/dist/test/lib/osc.js +395 -0
- package/dist/test/test-client.js +152 -0
- package/dist/test/test-e2e.js +9 -3
- package/dist/test/test-encode-decode.js +849 -0
- package/dist/test/test-error-handling.js +116 -0
- package/dist/test/test-osc-internal.js +399 -41
- package/dist/test/test-promises.js +250 -0
- package/dist/test/test-types.js +42 -0
- package/dist/test/util.js +15 -8
- package/docs/API.md +477 -0
- package/docs/GUIDE.md +605 -0
- package/examples/README.md +119 -0
- package/examples/async-await.mjs +57 -0
- package/examples/bundle-example.mjs +92 -0
- package/examples/client.js +22 -5
- package/examples/error-handling.mjs +152 -0
- package/examples/esm.mjs +21 -0
- package/examples/server.js +16 -0
- package/jsdoc.json +16 -0
- package/lib/Bundle.mjs +66 -0
- package/lib/Client.mjs +137 -22
- package/lib/Message.mjs +87 -1
- package/lib/Server.mjs +117 -6
- package/lib/index.mjs +1 -0
- package/lib/internal/decode.mjs +4 -4
- package/{dist/lib/internal/osc.js → lib/osc.mjs} +71 -7
- package/package.json +12 -10
- package/rollup.config.mjs +48 -37
- package/scripts/generate-docs.mjs +229 -0
- package/test/fixtures/types/test-cjs-types.ts +19 -0
- package/test/fixtures/types/test-esm-types.ts +35 -0
- package/test/fixtures/types/tsconfig-cjs.test.json +17 -0
- package/test/fixtures/types/tsconfig-esm.test.json +17 -0
- package/test/test-bundle.mjs +0 -1
- package/test/test-client.mjs +152 -0
- package/test/test-e2e.mjs +9 -3
- package/test/test-encode-decode.mjs +847 -0
- package/test/test-error-handling.mjs +115 -0
- package/test/test-osc-internal.mjs +400 -42
- package/test/test-promises.mjs +249 -0
- package/test/test-types.mjs +39 -0
- package/test/util.mjs +15 -8
- package/tsconfig.json +45 -0
- package/types/Bundle.d.mts +70 -0
- package/types/Bundle.d.mts.map +1 -0
- package/types/Client.d.mts +101 -0
- package/types/Client.d.mts.map +1 -0
- package/types/Message.d.mts +84 -0
- package/types/Message.d.mts.map +1 -0
- package/types/Server.d.mts +98 -0
- package/types/Server.d.mts.map +1 -0
- package/types/index.d.mts +6 -0
- package/types/index.d.mts.map +1 -0
- package/types/internal/decode.d.mts +4 -0
- package/types/internal/decode.d.mts.map +1 -0
- package/types/osc.d.mts +66 -0
- package/types/osc.d.mts.map +1 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSC Client and Server Example (ESM with Async/Await)
|
|
3
|
+
*
|
|
4
|
+
* This is the recommended pattern for modern Node.js applications.
|
|
5
|
+
* It demonstrates:
|
|
6
|
+
* - Using async/await for cleaner async code
|
|
7
|
+
* - Properly waiting for server to be ready
|
|
8
|
+
* - Sending multiple messages in parallel
|
|
9
|
+
* - Clean shutdown of resources
|
|
10
|
+
*
|
|
11
|
+
* To run this example:
|
|
12
|
+
* node examples/async-await.mjs
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// Example: Using async/await with node-osc Client and Server (ESM)
|
|
16
|
+
import { once } from "node:events";
|
|
17
|
+
import { setImmediate } from "node:timers/promises";
|
|
18
|
+
import { Client, Server } from "node-osc";
|
|
19
|
+
|
|
20
|
+
// Create server on all interfaces, port 3333
|
|
21
|
+
const server = new Server(3333, "0.0.0.0");
|
|
22
|
+
|
|
23
|
+
// Wait for server to be ready using once() - cleaner than event listeners
|
|
24
|
+
await once(server, "listening");
|
|
25
|
+
|
|
26
|
+
console.log("OSC server listening on port 3333");
|
|
27
|
+
|
|
28
|
+
// Set up message handler
|
|
29
|
+
// Messages arrive as arrays: [address, ...arguments]
|
|
30
|
+
server.on("message", (msg) => {
|
|
31
|
+
const [address, ...args] = msg;
|
|
32
|
+
console.log("Received:", address, args);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Create client pointing to localhost
|
|
36
|
+
const client = new Client("127.0.0.1", 3333);
|
|
37
|
+
|
|
38
|
+
// Send a simple message
|
|
39
|
+
await client.send("/hello", "world");
|
|
40
|
+
console.log("Sent /hello");
|
|
41
|
+
|
|
42
|
+
// Send multiple messages in parallel using Promise.all()
|
|
43
|
+
await Promise.all([
|
|
44
|
+
client.send("/counter", 1),
|
|
45
|
+
client.send("/counter", 2),
|
|
46
|
+
client.send("/counter", 3),
|
|
47
|
+
]);
|
|
48
|
+
console.log("Sent counters");
|
|
49
|
+
|
|
50
|
+
// Allow socket I/O to be processed before shutting down
|
|
51
|
+
await setImmediate();
|
|
52
|
+
|
|
53
|
+
// Clean shutdown - always close resources
|
|
54
|
+
await client.close();
|
|
55
|
+
await server.close();
|
|
56
|
+
|
|
57
|
+
console.log("Client and server closed");
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSC Bundle Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to create and send OSC bundles.
|
|
5
|
+
* Bundles allow you to group multiple messages together, optionally
|
|
6
|
+
* with a timetag for synchronized processing.
|
|
7
|
+
*
|
|
8
|
+
* To run this example:
|
|
9
|
+
* node examples/bundle-example.mjs
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { once } from "node:events";
|
|
13
|
+
import { setImmediate } from "node:timers/promises";
|
|
14
|
+
import { Bundle, Client, Message, Server } from "node-osc";
|
|
15
|
+
|
|
16
|
+
// Start server
|
|
17
|
+
const server = new Server(3333, "0.0.0.0");
|
|
18
|
+
await once(server, "listening");
|
|
19
|
+
console.log("Server listening on port 3333\n");
|
|
20
|
+
|
|
21
|
+
// Handle bundles specifically
|
|
22
|
+
server.on("bundle", (bundle, rinfo) => {
|
|
23
|
+
console.log(`📦 Received bundle from ${rinfo.address}:${rinfo.port}`);
|
|
24
|
+
console.log(` Timetag: ${bundle.timetag}`);
|
|
25
|
+
console.log(` Elements: ${bundle.elements.length}`);
|
|
26
|
+
|
|
27
|
+
// Process each element in the bundle
|
|
28
|
+
bundle.elements.forEach((element, i) => {
|
|
29
|
+
if (element.oscType === 'message') {
|
|
30
|
+
const [address, ...args] = element;
|
|
31
|
+
console.log(` ${i + 1}. ${address}: ${args.join(', ')}`);
|
|
32
|
+
} else if (element.oscType === 'bundle') {
|
|
33
|
+
console.log(` ${i + 1}. [Nested Bundle]`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
console.log();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Create client
|
|
40
|
+
const client = new Client("127.0.0.1", 3333);
|
|
41
|
+
|
|
42
|
+
// Example 1: Bundle without timetag (array notation)
|
|
43
|
+
console.log("Sending bundle without timetag...");
|
|
44
|
+
const bundle1 = new Bundle(
|
|
45
|
+
["/synth/freq", 440],
|
|
46
|
+
["/synth/amp", 0.5],
|
|
47
|
+
["/synth/gate", 1]
|
|
48
|
+
);
|
|
49
|
+
await client.send(bundle1);
|
|
50
|
+
await setImmediate();
|
|
51
|
+
|
|
52
|
+
// Example 2: Bundle with timetag
|
|
53
|
+
console.log("Sending bundle with timetag...");
|
|
54
|
+
const bundle2 = new Bundle(
|
|
55
|
+
10, // timetag
|
|
56
|
+
["/oscillator/1/freq", 220],
|
|
57
|
+
["/oscillator/2/freq", 330]
|
|
58
|
+
);
|
|
59
|
+
await client.send(bundle2);
|
|
60
|
+
await setImmediate();
|
|
61
|
+
|
|
62
|
+
// Example 3: Bundle with Message objects
|
|
63
|
+
console.log("Sending bundle with Message objects...");
|
|
64
|
+
const msg1 = new Message("/note", 60, 127);
|
|
65
|
+
const msg2 = new Message("/note", 64, 127);
|
|
66
|
+
const msg3 = new Message("/note", 67, 127);
|
|
67
|
+
const bundle3 = new Bundle(msg1, msg2, msg3);
|
|
68
|
+
await client.send(bundle3);
|
|
69
|
+
await setImmediate();
|
|
70
|
+
|
|
71
|
+
// Example 4: Nested bundles
|
|
72
|
+
console.log("Sending nested bundles...");
|
|
73
|
+
const innerBundle = new Bundle(["/inner/message", 123]);
|
|
74
|
+
const outerBundle = new Bundle(["/outer/message", 456]);
|
|
75
|
+
outerBundle.append(innerBundle);
|
|
76
|
+
await client.send(outerBundle);
|
|
77
|
+
await setImmediate();
|
|
78
|
+
|
|
79
|
+
// Example 5: Building a bundle incrementally
|
|
80
|
+
console.log("Sending incrementally built bundle...");
|
|
81
|
+
// Create bundle with initial element, then append more
|
|
82
|
+
const bundle5 = new Bundle(["/initial", 0]);
|
|
83
|
+
bundle5.append(["/control/1", 10]);
|
|
84
|
+
bundle5.append(["/control/2", 20]);
|
|
85
|
+
bundle5.append(["/control/3", 30]);
|
|
86
|
+
await client.send(bundle5);
|
|
87
|
+
await setImmediate();
|
|
88
|
+
|
|
89
|
+
// Clean shutdown
|
|
90
|
+
await client.close();
|
|
91
|
+
await server.close();
|
|
92
|
+
console.log("Done!");
|
package/examples/client.js
CHANGED
|
@@ -1,23 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSC Client Example (CommonJS)
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to create an OSC client and send messages
|
|
5
|
+
* using the Message class with callbacks.
|
|
6
|
+
*
|
|
7
|
+
* To run this example:
|
|
8
|
+
* 1. Start the server: node examples/server.js
|
|
9
|
+
* 2. Run this client: node examples/client.js
|
|
10
|
+
*/
|
|
11
|
+
|
|
1
12
|
'use strict';
|
|
2
13
|
const { Client, Message } = require('node-osc');
|
|
3
14
|
|
|
15
|
+
// Create a client connected to localhost on port 3333
|
|
4
16
|
const client = new Client('127.0.0.1', 3333);
|
|
5
17
|
|
|
18
|
+
// Create a message using the Message class
|
|
6
19
|
const message = new Message('/address');
|
|
7
|
-
message.append('testing');
|
|
8
|
-
message.append('testing');
|
|
9
|
-
message.append(123);
|
|
20
|
+
message.append('testing'); // Append a string
|
|
21
|
+
message.append('testing'); // Append the same string again (for demonstration)
|
|
22
|
+
message.append(123); // Append an integer
|
|
10
23
|
|
|
24
|
+
// Send the message with a callback
|
|
11
25
|
client.send(message, (err) => {
|
|
12
26
|
if (err) {
|
|
13
27
|
console.error(new Error(err));
|
|
14
28
|
}
|
|
29
|
+
// Always close the client when done
|
|
15
30
|
client.close();
|
|
16
31
|
});
|
|
17
32
|
|
|
18
|
-
//
|
|
33
|
+
// Alternative ways to send messages:
|
|
34
|
+
|
|
35
|
+
// Method 1: Send address and arguments directly
|
|
19
36
|
// client.send('/address', 'testing', 'testing', 123);
|
|
20
37
|
|
|
21
|
-
//
|
|
38
|
+
// Method 2: Create message with constructor arguments
|
|
22
39
|
// const msg = new Message('/address', 1, 2, 3);
|
|
23
40
|
// client.send(msg);
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSC Error Handling Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates proper error handling patterns with node-osc,
|
|
5
|
+
* including handling server errors, client errors, and ensuring cleanup.
|
|
6
|
+
*
|
|
7
|
+
* To run this example:
|
|
8
|
+
* node examples/error-handling.mjs
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { once } from "node:events";
|
|
12
|
+
import { Client, Server } from "node-osc";
|
|
13
|
+
|
|
14
|
+
console.log("=== OSC Error Handling Examples ===\n");
|
|
15
|
+
|
|
16
|
+
// Example 1: Server decode errors
|
|
17
|
+
console.log("1. Testing server decode error handling...");
|
|
18
|
+
const server = new Server(3333, "0.0.0.0");
|
|
19
|
+
|
|
20
|
+
// Set up error handler for server
|
|
21
|
+
server.on("error", (err, rinfo) => {
|
|
22
|
+
console.error(`❌ Server error from ${rinfo.address}:${rinfo.port}`);
|
|
23
|
+
console.error(` ${err.message}`);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
await once(server, "listening");
|
|
27
|
+
console.log("✅ Server started successfully\n");
|
|
28
|
+
|
|
29
|
+
// Example 2: Try/catch with async/await
|
|
30
|
+
console.log("2. Testing client send with try/catch...");
|
|
31
|
+
const client = new Client("127.0.0.1", 3333);
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
await client.send("/test", 123, "hello", true);
|
|
35
|
+
console.log("✅ Message sent successfully\n");
|
|
36
|
+
} catch (err) {
|
|
37
|
+
console.error(`❌ Failed to send message: ${err.message}\n`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Example 3: Error when sending on closed socket
|
|
41
|
+
console.log("3. Testing send on closed socket...");
|
|
42
|
+
await client.close();
|
|
43
|
+
console.log(" Client closed");
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
await client.send("/test", 456);
|
|
47
|
+
console.log("✅ Message sent (this shouldn't happen)\n");
|
|
48
|
+
} catch (err) {
|
|
49
|
+
console.log(`✅ Caught expected error: ${err.message}`);
|
|
50
|
+
console.log(` Error code: ${err.code}\n`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Example 4: Try/finally for cleanup
|
|
54
|
+
console.log("4. Testing try/finally for guaranteed cleanup...");
|
|
55
|
+
const client2 = new Client("127.0.0.1", 3333);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
await client2.send("/cleanup/test", 789);
|
|
59
|
+
console.log("✅ Message sent");
|
|
60
|
+
|
|
61
|
+
// Simulate an error
|
|
62
|
+
throw new Error("Simulated error");
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.log(`⚠️ Caught error: ${err.message}`);
|
|
65
|
+
} finally {
|
|
66
|
+
// This always runs, even if there was an error
|
|
67
|
+
await client2.close();
|
|
68
|
+
console.log("✅ Client closed in finally block\n");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Example 5: Callback-based error handling
|
|
72
|
+
console.log("5. Testing callback-based error handling...");
|
|
73
|
+
const client3 = new Client("127.0.0.1", 3333);
|
|
74
|
+
|
|
75
|
+
await new Promise((resolve) => {
|
|
76
|
+
client3.send("/callback/test", 999, (err) => {
|
|
77
|
+
if (err) {
|
|
78
|
+
console.error(`❌ Send error: ${err}`);
|
|
79
|
+
} else {
|
|
80
|
+
console.log("✅ Message sent via callback");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
client3.close((err) => {
|
|
84
|
+
if (err) {
|
|
85
|
+
console.error(`❌ Close error: ${err}`);
|
|
86
|
+
} else {
|
|
87
|
+
console.log("✅ Client closed via callback\n");
|
|
88
|
+
}
|
|
89
|
+
resolve();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Example 6: Multiple operations with proper error handling
|
|
95
|
+
console.log("6. Testing multiple operations with error handling...");
|
|
96
|
+
const client4 = new Client("127.0.0.1", 3333);
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
// Send multiple messages
|
|
100
|
+
const results = await Promise.allSettled([
|
|
101
|
+
client4.send("/multi/1", 1),
|
|
102
|
+
client4.send("/multi/2", 2),
|
|
103
|
+
client4.send("/multi/3", 3),
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
// Check results
|
|
107
|
+
results.forEach((result, i) => {
|
|
108
|
+
if (result.status === "fulfilled") {
|
|
109
|
+
console.log(`✅ Message ${i + 1} sent successfully`);
|
|
110
|
+
} else {
|
|
111
|
+
console.error(`❌ Message ${i + 1} failed: ${result.reason}`);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
} catch (err) {
|
|
115
|
+
console.error(`❌ Unexpected error: ${err.message}`);
|
|
116
|
+
} finally {
|
|
117
|
+
await client4.close();
|
|
118
|
+
console.log("✅ Client closed\n");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Example 7: Server error event
|
|
122
|
+
console.log("7. Testing server message handling with error check...");
|
|
123
|
+
let messageReceived = false;
|
|
124
|
+
|
|
125
|
+
server.on("message", (msg) => {
|
|
126
|
+
messageReceived = true;
|
|
127
|
+
const [address, ...args] = msg;
|
|
128
|
+
console.log(`✅ Received: ${address} with args: ${args.join(", ")}`);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const client5 = new Client("127.0.0.1", 3333);
|
|
132
|
+
await client5.send("/final/test", "done");
|
|
133
|
+
await client5.close();
|
|
134
|
+
|
|
135
|
+
// Wait a bit for message to be received
|
|
136
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
137
|
+
|
|
138
|
+
if (!messageReceived) {
|
|
139
|
+
console.log("⚠️ Warning: Message was not received");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Clean shutdown
|
|
143
|
+
await server.close();
|
|
144
|
+
console.log("\n✅ All tests complete, server closed");
|
|
145
|
+
|
|
146
|
+
console.log("\n=== Key Takeaways ===");
|
|
147
|
+
console.log("1. Always use try/catch with async/await");
|
|
148
|
+
console.log("2. Use try/finally to ensure cleanup");
|
|
149
|
+
console.log("3. Listen for 'error' events on servers");
|
|
150
|
+
console.log("4. Check for errors in callbacks");
|
|
151
|
+
console.log("5. Don't send on closed sockets");
|
|
152
|
+
console.log("6. Use Promise.allSettled for multiple operations");
|
package/examples/esm.mjs
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSC Client and Server Example (ESM with Callbacks)
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates using node-osc with ES modules and callback-based API.
|
|
5
|
+
* It shows how to create both a client and server, send messages, and handle events.
|
|
6
|
+
*
|
|
7
|
+
* To run this example:
|
|
8
|
+
* node examples/esm.mjs
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
import { Client, Server } from 'node-osc';
|
|
2
12
|
|
|
13
|
+
// Create a client connected to localhost on port 3333
|
|
3
14
|
const client = new Client('127.0.0.1', 3333);
|
|
15
|
+
|
|
16
|
+
// Create a server listening on port 3333, bound to all interfaces
|
|
4
17
|
var server = new Server(3333, '0.0.0.0');
|
|
5
18
|
|
|
19
|
+
// Listen for when the server is ready
|
|
6
20
|
server.on('listening', () => {
|
|
7
21
|
console.log('OSC Server is Listening');
|
|
8
22
|
});
|
|
9
23
|
|
|
24
|
+
// Listen for incoming messages
|
|
10
25
|
server.on('message', (msg, rinfo) => {
|
|
26
|
+
// msg is an array: [address, ...arguments]
|
|
11
27
|
console.log(`Message: ${msg}\nReceived from: ${rinfo.address}:${rinfo.port}`);
|
|
28
|
+
|
|
29
|
+
// Close the server after receiving a message
|
|
12
30
|
server.close();
|
|
13
31
|
});
|
|
14
32
|
|
|
33
|
+
// Send a message with callback-based API
|
|
15
34
|
client.send('/hello', 'world', (err) => {
|
|
16
35
|
if (err) console.error(err);
|
|
36
|
+
|
|
37
|
+
// Close the client after sending
|
|
17
38
|
client.close();
|
|
18
39
|
});
|
package/examples/server.js
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSC Server Example (CommonJS)
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to create an OSC server that listens for
|
|
5
|
+
* incoming messages and displays them along with sender information.
|
|
6
|
+
*
|
|
7
|
+
* To run this example:
|
|
8
|
+
* 1. Start this server: node examples/server.js
|
|
9
|
+
* 2. Send messages from client: node examples/client.js
|
|
10
|
+
*/
|
|
11
|
+
|
|
1
12
|
'use strict';
|
|
2
13
|
var { Server } = require('node-osc');
|
|
3
14
|
|
|
15
|
+
// Create a server listening on port 3333, bound to all interfaces
|
|
4
16
|
var oscServer = new Server(3333, '0.0.0.0');
|
|
5
17
|
|
|
18
|
+
// Listen for incoming OSC messages
|
|
6
19
|
oscServer.on('message', function (msg, rinfo) {
|
|
20
|
+
// msg is an array: [address, ...arguments]
|
|
7
21
|
console.log(`Message: ${msg}\nReceived from: ${rinfo.address}:${rinfo.port}`);
|
|
22
|
+
|
|
23
|
+
// Close the server after receiving one message (for demo purposes)
|
|
8
24
|
oscServer.close();
|
|
9
25
|
});
|
package/jsdoc.json
ADDED
package/lib/Bundle.mjs
CHANGED
|
@@ -1,11 +1,60 @@
|
|
|
1
1
|
import Message from './Message.mjs';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Convert array notation to Message object.
|
|
5
|
+
* @private
|
|
6
|
+
* @param {Array|Message|Bundle} element - The element to sanitize.
|
|
7
|
+
* @returns {Message|Bundle} The sanitized element.
|
|
8
|
+
*/
|
|
3
9
|
function sanitize(element) {
|
|
4
10
|
if (element instanceof Array) element = new Message(element[0], ...element.slice(1));
|
|
5
11
|
return element;
|
|
6
12
|
}
|
|
7
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Represents an OSC bundle containing multiple messages or nested bundles.
|
|
16
|
+
*
|
|
17
|
+
* OSC bundles allow multiple messages to be sent together, optionally with
|
|
18
|
+
* a timetag indicating when the bundle should be processed.
|
|
19
|
+
*
|
|
20
|
+
* @class
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Create a bundle without a timetag
|
|
24
|
+
* const bundle = new Bundle(['/one', 1], ['/two', 2]);
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Create a bundle with a timetag
|
|
28
|
+
* const bundle = new Bundle(10, ['/one', 1], ['/two', 2]);
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Nest bundles
|
|
32
|
+
* const bundle1 = new Bundle(['/one', 1]);
|
|
33
|
+
* const bundle2 = new Bundle(['/two', 2]);
|
|
34
|
+
* bundle1.append(bundle2);
|
|
35
|
+
*/
|
|
8
36
|
class Bundle {
|
|
37
|
+
/**
|
|
38
|
+
* Create an OSC Bundle.
|
|
39
|
+
*
|
|
40
|
+
* @param {number|Message|Bundle|Array} [timetagOrElement=0] - Timetag, or if not a number, the first element and timetag will default to 0.
|
|
41
|
+
* @param {...(Message|Bundle|Array)} elements - Messages or bundles to include.
|
|
42
|
+
* Arrays will be automatically converted to Message objects.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Bundle without timetag
|
|
46
|
+
* const bundle = new Bundle(['/test', 1], ['/test2', 2]);
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Bundle with timetag of 10
|
|
50
|
+
* const bundle = new Bundle(10, ['/test', 1]);
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Bundle with Message objects
|
|
54
|
+
* const msg1 = new Message('/one', 1);
|
|
55
|
+
* const msg2 = new Message('/two', 2);
|
|
56
|
+
* const bundle = new Bundle(msg1, msg2);
|
|
57
|
+
*/
|
|
9
58
|
constructor(timetag, ...elements) {
|
|
10
59
|
if (!(typeof timetag === 'number')) {
|
|
11
60
|
elements.unshift(timetag);
|
|
@@ -16,6 +65,23 @@ class Bundle {
|
|
|
16
65
|
this.elements = elements.map(sanitize);
|
|
17
66
|
}
|
|
18
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Append a message or bundle to this bundle.
|
|
70
|
+
*
|
|
71
|
+
* @param {Message|Bundle|Array} element - The message or bundle to append.
|
|
72
|
+
* Arrays will be automatically converted to Message objects.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* const bundle = new Bundle();
|
|
76
|
+
* bundle.append(['/test', 1]);
|
|
77
|
+
* bundle.append(new Message('/test2', 2));
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* // Append a nested bundle
|
|
81
|
+
* const bundle1 = new Bundle(['/one', 1]);
|
|
82
|
+
* const bundle2 = new Bundle(['/two', 2]);
|
|
83
|
+
* bundle1.append(bundle2);
|
|
84
|
+
*/
|
|
19
85
|
append(element) {
|
|
20
86
|
this.elements.push(sanitize(element));
|
|
21
87
|
}
|