Files
mapper/backend/node_modules/node-osc/agent.md
2026-03-10 20:48:09 +00:00

11 KiB

Agent Instructions for node-osc

This document provides context and instructions for AI agents (GitHub Copilot, Cursor, and other agentic platforms) working on the node-osc project.

Project Overview

node-osc is a Node.js library for sending and receiving Open Sound Control (OSC) messages over UDP. It provides a simple, no-frills API inspired by pyOSC.

Key Features

  • Send and receive OSC messages and bundles
  • Dual module support (ESM and CommonJS)
  • Both callback and async/await APIs
  • TypeScript type definitions generated from JSDoc
  • Well-tested with comprehensive test coverage
  • Supports Node.js 20, 22, and 24

Architecture

Core Components

  1. Server (lib/Server.mjs) - EventEmitter-based OSC server for receiving messages

    • Listens on UDP socket
    • Emits events: listening, message, bundle, error, and address-specific events
  2. Client (lib/Client.mjs) - OSC client for sending messages

    • Sends messages over UDP
    • Supports both callbacks and async/await
  3. Message (lib/Message.mjs) - Represents a single OSC message

    • Contains address (string) and arguments (array)
    • Can append additional arguments
  4. Bundle (lib/Bundle.mjs) - Represents a collection of OSC messages

    • Contains timetag and array of elements (messages or nested bundles)
    • Used for sending multiple messages together
  5. Low-level encoding/decoding (lib/osc.mjs, lib/internal/) - Binary OSC protocol implementation

    • encode() - Converts Message/Bundle objects to binary Buffer
    • decode() - Parses binary Buffer into Message/Bundle objects

Module System

The project uses ESM as the source format but provides dual ESM/CommonJS support:

  • Source files: lib/**/*.mjs (ESM)
  • Built CommonJS files: dist/lib/**/*.js (transpiled via Rollup)
  • TypeScript definitions: types/index.d.mts (generated from JSDoc)

Important: The single .d.mts type definition file works for both ESM and CommonJS consumers.

Package Exports

{
  "exports": {
    "types": "./types/index.d.mts",
    "require": "./dist/lib/index.js",
    "import": "./lib/index.mjs",
    "default": "./lib/index.mjs"
  }
}

Development Workflow

Essential Commands

# Install dependencies
npm install

# Run linter (ESLint)
npm run lint

# Build the project (clean, transpile to CJS, generate types)
npm run build

# Run all tests (lint + build + ESM tests + CJS tests)
npm test

# Run only ESM tests
npm run test:esm

# Run only CJS tests
npm run test:cjs

# Generate API documentation from JSDoc
npm run docs

# Clean build artifacts
npm run clean

Testing Strategy

  • Tests are written in ESM format in test/test-*.mjs
  • Tests are run against both ESM source (lib/) and transpiled CJS (dist/)
  • Uses tap test framework
  • Test utilities in test/util.mjs provide helpers like getPort() for getting available ports
  • Always run npm run build before running CJS tests
  • 100% test coverage is required - All lines, branches, functions, and statements must be covered

Build Process

  1. Clean: Removes dist/ and types/ directories
  2. Rollup: Transpiles ESM to CommonJS in dist/ directory
  3. TypeScript: Generates type definitions from JSDoc in types/ directory

The build is automatically run before publishing (prepublishOnly script).

Coding Standards

JavaScript Style

  • ES Modules: Use ESM syntax (import/export)
  • File extension: Use .mjs for ESM files
  • Linting: Follow ESLint rules in eslint.config.mjs
  • Modern JavaScript: Use async/await, arrow functions, destructuring
  • Error handling: Always handle errors in async operations

Documentation

  • JSDoc comments: All public APIs must have JSDoc comments
  • Type annotations: Use JSDoc types for TypeScript generation
  • Examples: Include code examples in JSDoc comments
  • Auto-generated docs: Run npm run docs after changing JSDoc comments

Example JSDoc pattern:

/**
 * Sends an OSC message or bundle.
 * 
 * @param {Message|Bundle|string} msg - The message, bundle, or address to send.
 * @param {...*} args - Additional arguments (used when first param is a string address).
 * @returns {Promise<void>}
 * 
 * @example
 * await client.send('/test', 123);
 * 
 * @example
 * const message = new Message('/test', 123);
 * await client.send(message);
 */
async send(msg, ...args) { ... }

Type System

  • TypeScript definitions are generated from JSDoc comments
  • Do not manually edit types/*.d.mts files
  • Update JSDoc comments in source files instead
  • Run npm run build:types to regenerate types

Naming Conventions

  • Classes: PascalCase (e.g., Client, Server, Message, Bundle)
  • Functions: camelCase (e.g., encode, decode, toBuffer)
  • Private functions: Prefix with underscore (e.g., _oscType)
  • Constants: UPPER_SNAKE_CASE for true constants
  • Files: Match class names or use descriptive kebab-case

Dual Module Support Patterns

When writing code that needs to work in both ESM and CJS:

  1. Imports: Use ESM imports in source (Rollup handles conversion)
  2. Exports: Use named exports for all public APIs
  3. Testing: Test both ESM and CJS builds
  4. Package imports: Use #decode subpath import for internal modules (defined in package.json imports field)

Important Files and Directories

Source Files

  • lib/ - ESM source code (the canonical source)
  • lib/index.mjs - Main entry point, exports all public APIs
  • lib/internal/ - Internal utilities (decode, encode, helpers)
  • lib/osc.mjs - Low-level encode/decode functions

Build Artifacts

  • dist/ - Transpiled CommonJS files (generated, do not edit)
  • types/ - TypeScript type definitions (generated, do not edit)

Tests

  • test/test-*.mjs - Test files using tap framework
  • test/util.mjs - Test utilities and helpers
  • test/fixtures/ - Test data and fixtures

Documentation

  • README.md - Main documentation with quick start guide
  • docs/API.md - Auto-generated API reference (do not edit manually)
  • docs/GUIDE.md - Best practices, error handling, troubleshooting
  • examples/ - Working example code for various use cases

Configuration

  • package.json - Package configuration, scripts, exports
  • eslint.config.mjs - ESLint configuration
  • rollup.config.mjs - Rollup build configuration (ESM to CJS)
  • tsconfig.json - TypeScript compiler options for type generation
  • jsdoc.json - JSDoc configuration for documentation generation

Making Changes

Adding a New Feature

  1. Write ESM source in lib/
  2. Add JSDoc comments with types and examples
  3. Export from lib/index.mjs if it's a public API
  4. Write tests in test/test-*.mjs - must achieve 100% coverage (lines, branches, functions, statements)
  5. Run tests: npm test (tests both ESM and CJS)
  6. Update docs: npm run docs to regenerate API.md
  7. Update README.md if adding user-facing functionality

Fixing a Bug

  1. Write a failing test that demonstrates the bug
  2. Fix the bug in the ESM source files
  3. Run tests: npm test to verify fix works in both ESM and CJS
  4. Verify coverage: Ensure 100% test coverage is maintained
  5. Check no regressions: Ensure all tests pass

Modifying the API

  1. Update JSDoc in source files
  2. Regenerate types: npm run build:types
  3. Update tests to cover new behavior - must maintain 100% coverage
  4. Regenerate docs: npm run docs
  5. Update README.md and docs/GUIDE.md as appropriate

Common Patterns

Creating a Server

import { Server } from 'node-osc';

const server = new Server(3333, '0.0.0.0');
server.on('message', (msg, rinfo) => {
  console.log('Message:', msg);
});

Creating a Client

import { Client } from 'node-osc';

const client = new Client('127.0.0.1', 3333);
await client.send('/test', 123);
await client.close();

Working with Bundles

import { Bundle } from 'node-osc';

const bundle = new Bundle(['/one', 1], ['/two', 2]);
await client.send(bundle);

Low-level Encoding/Decoding

import { Message, encode, decode } from 'node-osc';

const message = new Message('/test', 123);
const buffer = encode(message);
const decoded = decode(buffer);

Troubleshooting

Build Issues

  • "Cannot find module": Run npm install to install dependencies
  • Type generation fails: Check JSDoc syntax in source files
  • CJS tests fail but ESM pass: Run npm run build before testing

Test Issues

  • Port conflicts: Tests use dynamic port allocation via getPort() utility
  • Timing issues: Use async/await and proper event handling
  • ESM/CJS differences: Ensure code works in both environments

Module Resolution

  • Dual package hazard: The package exports both ESM and CJS - don't mix them
  • Type imports: TypeScript consumers get types automatically from types/index.d.mts
  • Internal imports: Use #decode subpath for internal modules

Dependencies

Runtime Dependencies

  • None - This is a zero-dependency library for production use

Development Dependencies

  • eslint - Code linting
  • tap - Test framework
  • rollup - Module bundler for ESM → CJS transpilation
  • typescript - Type definition generation from JSDoc
  • jsdoc - Documentation generation
  • globals - ESLint globals configuration

OSC Protocol Knowledge

When working with OSC message encoding/decoding:

  • OSC addresses start with / (e.g., /oscillator/frequency)
  • OSC types: integer (i), float (f), string (s), blob (b), time tag (t)
  • Messages are null-padded to 4-byte boundaries
  • Bundles have time tags (when to execute) and can contain nested bundles
  • See OSC Specification for protocol details

Security Considerations

  • Always validate input data when decoding OSC messages
  • Be careful with buffer operations to avoid out-of-bounds access
  • Limit message and bundle sizes to prevent DoS attacks
  • Sanitize OSC addresses before using them as event names
  • Handle malformed OSC data gracefully (emit errors, don't crash)

License

This project uses the Apache-2.0 license. When contributing code:

  • Ensure all new code is compatible with Apache-2.0
  • Do not introduce dependencies with incompatible licenses
  • Include proper attribution for any third-party code

Getting Help

  • API Documentation: See docs/API.md
  • Usage Guide: See docs/GUIDE.md
  • Examples: See examples/ directory
  • Issues: Check existing GitHub issues for similar problems
  • OSC Protocol: Refer to http://opensoundcontrol.org for protocol details