Initial Commit
This commit is contained in:
commit
4c5d981e7f
9 changed files with 382 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
lib
|
||||
.log
|
||||
3
.npmignore
Normal file
3
.npmignore
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
src
|
||||
.log
|
||||
|
||||
19
README.md
Normal file
19
README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# ts-osc
|
||||
An easy to use, Typescript-Native OSC client.
|
||||
|
||||
## Usage example
|
||||
```javascript
|
||||
import {OSCClient} from 'ts-osc';
|
||||
|
||||
const client = new OSCClient({
|
||||
outHost: "localhost",
|
||||
outPort: 8000,
|
||||
inPort: 8000
|
||||
})
|
||||
|
||||
client.send('/hello', "string", "hello");
|
||||
|
||||
client.on('message', (msg)=>{
|
||||
console.log(msg);
|
||||
})
|
||||
```
|
||||
128
package-lock.json
generated
Normal file
128
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
{
|
||||
"name": "ts-osc",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "14.14.22",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz",
|
||||
"integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"binpack": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/binpack/-/binpack-0.1.0.tgz",
|
||||
"integrity": "sha1-vT0JdMPyoERuF99PYLVacqIFqX4="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"osc-min": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/osc-min/-/osc-min-1.1.2.tgz",
|
||||
"integrity": "sha512-8DbiO8ME85R75stgNVCZtHxB9MNBBNcyy+isNBXrsFeinXGjwNAauvKVmGlfRas5VJWC/mhzIx7spR2gFvWxvg==",
|
||||
"requires": {
|
||||
"binpack": "~0"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
|
||||
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg=="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
32
package.json
Normal file
32
package.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "ts-osc",
|
||||
"version": "1.0.0",
|
||||
"description": "Fully TypeScript-native OSC Client based on osc-min",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsc",
|
||||
"watch": "tsc --watch"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@gitlab.riksolo.com:2224/riksolo/ts-osc.git"
|
||||
},
|
||||
"keywords": [
|
||||
"osc",
|
||||
"open",
|
||||
"sound",
|
||||
"control"
|
||||
],
|
||||
"author": "Rik Berkelder <mail@riksolo.com>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"osc-min": "^1.1.2",
|
||||
"@types/node": "^14.14.22",
|
||||
"typescript": "^4.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^3.0.2"
|
||||
}
|
||||
}
|
||||
3
src/index.ts
Normal file
3
src/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from './oscClient';
|
||||
export {OSCType} from 'osc-min'
|
||||
|
||||
62
src/oscClient.ts
Normal file
62
src/oscClient.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import * as dgram from 'dgram';
|
||||
import {OSCArgument, OSCType, toBuffer, fromBuffer, OSCArgumentType} from 'osc-min';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
|
||||
interface OSCClientOptions {
|
||||
outHost: string;
|
||||
outPort: number;
|
||||
inPort?: number;
|
||||
}
|
||||
|
||||
interface ReceivedOSCMessage<T extends OSCType> {
|
||||
address: string;
|
||||
type: T;
|
||||
value: OSCArgumentType<T>
|
||||
}
|
||||
|
||||
// declare types for events
|
||||
export declare interface OSCClient {
|
||||
on(event: 'message', listener: (message: ReceivedOSCMessage<OSCType>) => void): this;
|
||||
}
|
||||
|
||||
export class OSCClient extends EventEmitter{
|
||||
private socket: dgram.Socket;
|
||||
private options: OSCClientOptions;
|
||||
constructor(options: OSCClientOptions){
|
||||
super();
|
||||
this.socket = dgram.createSocket({type: "udp4", reuseAddr: true});
|
||||
this.options = options;
|
||||
|
||||
if(options.inPort){
|
||||
this.socket.bind(options.inPort);
|
||||
}
|
||||
|
||||
this.socket.on('message', (msg)=>{
|
||||
const decoded = fromBuffer(msg)
|
||||
if(decoded.oscType === "message"){
|
||||
decoded.args.forEach((arg)=>{
|
||||
this.emit('message', {
|
||||
address: decoded.address,
|
||||
type: arg.type,
|
||||
value: arg.value
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private sendPacket(packet: Buffer): void{
|
||||
this.socket.send(packet, 0, packet.length, this.options.outPort, this.options.outHost)
|
||||
}
|
||||
|
||||
public send<T extends OSCType>(address: string, type: T, value: OSCArgumentType<T>){
|
||||
const arg: OSCArgument<T> = {
|
||||
type,
|
||||
value
|
||||
}
|
||||
|
||||
const encoded = toBuffer(address, [arg]);
|
||||
this.sendPacket(encoded);
|
||||
}
|
||||
}
|
||||
59
src/types/osc-min.d.ts
vendored
Normal file
59
src/types/osc-min.d.ts
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
declare module "osc-min" {
|
||||
export const enum OSCType {
|
||||
String = "string",
|
||||
Float = "float",
|
||||
Integer = "integer",
|
||||
Blob = "blob",
|
||||
True = "true",
|
||||
False = "false",
|
||||
Null = "null",
|
||||
Bang = "bang",
|
||||
Timetag = "timetag",
|
||||
Array = "array"
|
||||
}
|
||||
|
||||
export type OSCTimeTag = [number, number];
|
||||
|
||||
export interface OSCMessage {
|
||||
oscType?: "message",
|
||||
address: string,
|
||||
args: Array<OSCArgument<OSCType>>
|
||||
}
|
||||
|
||||
export interface OutgoingOSCMessage extends OSCMessage{
|
||||
args: OutgoingOSCArgsTypes;
|
||||
}
|
||||
|
||||
export type OutgoingOSCArgsTypes = Array<OSCArgument<OSCType> | Buffer | boolean | string | number>
|
||||
|
||||
export interface OSCBundle {
|
||||
oscType: "bundle",
|
||||
timetag: null | number | Date | OSCTimeTag,
|
||||
elements: Array<OSCMessage | OSCBundle>
|
||||
}
|
||||
|
||||
export type OSCArgumentType<T extends OSCType> = T extends OSCType.String ? string
|
||||
: T extends OSCType.Float | OSCType.Integer | OSCType.Timetag ? number
|
||||
: T extends OSCType.True ? true
|
||||
: T extends OSCType.False ? false
|
||||
: T extends OSCType.Blob ? Buffer
|
||||
: T extends OSCType.array ? Array<OSCArgument<OSCType>>
|
||||
: null;
|
||||
|
||||
export interface OSCArgument<T extends OSCType>{
|
||||
type: T;
|
||||
value: OSCArgumentType<T>;
|
||||
}
|
||||
|
||||
type OSCPacket = OSCMessage | OSCBundle;
|
||||
|
||||
export function fromBuffer(buffer: Buffer, strict?: boolean): OSCPacket;
|
||||
export function toBuffer(object: OutgoingOSCMessage, strict?: boolean): Buffer;
|
||||
export function toBuffer(address: string, args: Array<OSCArgument<OSCType>>, strict?: boolean): Buffer;
|
||||
export function applyMessageTransform(msg: Buffer, transform: (message: OSCMessage) => OSCMessage);
|
||||
export function applyAddressTransform(msg: Buffer, transform: (address: string) => string);
|
||||
export function timetagToDate(ntpTimeTag: OSCTimeTag): Date;
|
||||
export function dateToTimetag(date: Date): OSCTimeTag;
|
||||
export function timetagToTimestamp(timeTag: OSCTimeTag): number;
|
||||
export function timestampToTimetag(timestamp: number); OSCTimeTag;
|
||||
}
|
||||
73
tsconfig.json
Normal file
73
tsconfig.json
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||
"lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./lib", /* Redirect output structure to the directory. */
|
||||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
},
|
||||
|
||||
"include": ["./src/**/*"],
|
||||
"exclude": ["./node_modules/**/*"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue