alphatheta-connect 0.26.0 → 0.27.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/lib/network.d.ts CHANGED
@@ -10,7 +10,7 @@ import { MixstatusProcessor } from "./mixstatus";
10
10
  import RemoteDatabase from "./remotedb";
11
11
  import StatusEmitter from "./status";
12
12
  import PositionEmitter from "./status/position";
13
- import { NetworkState } from "./types";
13
+ import { Device, NetworkState } from "./types";
14
14
  export interface NetworkConfig {
15
15
  /**
16
16
  * The network interface to listen for devices on the network over
@@ -199,6 +199,12 @@ export declare class ProlinkNetwork {
199
199
  * accurate timecode/video sync even during scratching, reverse play, and loops.
200
200
  */
201
201
  get positionEmitter(): PositionEmitter | null;
202
+ /**
203
+ * The device this network announces itself as, once connected: the
204
+ * `hostDevice` the status emitter's media query and the control service
205
+ * send from.
206
+ */
207
+ get virtualDevice(): Device | null;
202
208
  /**
203
209
  * Get the {@link Control} service. This service can be used to control the
204
210
  * Playstate of CDJs on the network.
@@ -0,0 +1,66 @@
1
+ export interface HueConfig {
2
+ bridge: string;
3
+ appKey: string;
4
+ }
5
+ /**
6
+ * One group as the bridge lists it: a room or a zone.
7
+ */
8
+ export interface HueGroup {
9
+ id: string;
10
+ name: string;
11
+ type: string;
12
+ lights: string[];
13
+ /** Every light in the group is on. */
14
+ allOn: boolean;
15
+ /** At least one light in the group is on. */
16
+ anyOn: boolean;
17
+ }
18
+ export declare class HueError extends Error {
19
+ }
20
+ /**
21
+ * Raised when nothing has been paired and the environment names no bridge.
22
+ */
23
+ export declare class HueUnconfiguredError extends HueError {
24
+ constructor();
25
+ }
26
+ /**
27
+ * Raised when the bridge has no group by the name asked for.
28
+ */
29
+ export declare class HueNoGroupError extends HueError {
30
+ constructor(name: string, groups: HueGroup[]);
31
+ }
32
+ export declare function hueConfigPath(): string;
33
+ /**
34
+ * The environment first (`HUE_BRIDGE`, `HUE_APP_KEY`), then the file `hue
35
+ * pair` wrote; `null` when neither is there.
36
+ */
37
+ export declare function loadHueConfig(): Promise<HueConfig | null>;
38
+ export declare function saveHueConfig(config: HueConfig): Promise<string>;
39
+ export declare class Hue {
40
+ #private;
41
+ constructor(config: HueConfig);
42
+ get bridge(): string;
43
+ /**
44
+ * Every room and zone on the bridge, by name.
45
+ */
46
+ groups(): Promise<HueGroup[]>;
47
+ /**
48
+ * The group called `name`, matched without regard to case.
49
+ */
50
+ groupNamed(name: string): Promise<HueGroup>;
51
+ /**
52
+ * Switch every light (and plug) in the group.
53
+ */
54
+ setGroupOn(groupId: string, on: boolean): Promise<void>;
55
+ }
56
+ /**
57
+ * Ask the bridge for an application key. The bridge only issues one in the
58
+ * thirty seconds after its link button is pressed, so this asks once a second
59
+ * until it does or `waitMs` runs out.
60
+ */
61
+ export declare function pairHue(bridge: string, waitMs?: number): Promise<HueConfig>;
62
+ /**
63
+ * Where the bridge is: `HUE_BRIDGE`, else Signify's discovery service, which
64
+ * lists the bridges that have phoned home from this public address.
65
+ */
66
+ export declare function discoverHueBridge(): Promise<string>;
@@ -0,0 +1,100 @@
1
+ import { LoadSource } from "../control";
2
+ import { Logger } from "../logger";
3
+ import { ProlinkNetwork } from "../network";
4
+ import { CDJStatus, Device, MediaSlotInfo } from "../types";
5
+ /**
6
+ * The Stagehand transport opcodes (packet 0x07) the iPad app was captured
7
+ * sending, besides play (0x0f then 0x14 pressed) and pause (0x14 released),
8
+ * which `Control` sends itself. These are held while pressed.
9
+ */
10
+ export declare const TransportOp: {
11
+ readonly SkipForward: 24;
12
+ readonly SkipBackward: 25;
13
+ readonly SeekForward: 26;
14
+ readonly SeekBackward: 27;
15
+ };
16
+ export declare class RemoteError extends Error {
17
+ }
18
+ export declare class NoPlayerError extends RemoteError {
19
+ constructor(number: number);
20
+ }
21
+ export declare class CueUnknownError extends RemoteError {
22
+ constructor();
23
+ }
24
+ export interface RemoteOptions {
25
+ /** Interface name or address; default: the one the first player heard is on. */
26
+ iface?: string;
27
+ /** Device number 141..211; default: one derived from the interface's MAC. */
28
+ number?: number;
29
+ /** The Stagehand opcode for CUE, once one is found. */
30
+ cueOp?: number;
31
+ logger?: Logger;
32
+ }
33
+ /**
34
+ * A player as the API reports it: its identity from the keep-alives and its
35
+ * last status, when it has sent one.
36
+ */
37
+ export interface Player {
38
+ number: number;
39
+ name: string;
40
+ ip: string;
41
+ status?: CDJStatus.State;
42
+ }
43
+ export declare class Remote {
44
+ #private;
45
+ private constructor();
46
+ /**
47
+ * Join the link and start collecting status. Resolves once the Stagehand
48
+ * join sequence is through and keep-alives are running.
49
+ */
50
+ static join(opts?: RemoteOptions): Promise<Remote>;
51
+ get network(): ProlinkNetwork;
52
+ /**
53
+ * Our own device as announced.
54
+ */
55
+ get me(): Device | null;
56
+ /**
57
+ * Every device heard on the link, by number.
58
+ */
59
+ get devices(): Device[];
60
+ /**
61
+ * The players, with the last status each one sent.
62
+ */
63
+ get players(): Player[];
64
+ player(number: number): Device;
65
+ play(number: number): Promise<void>;
66
+ pause(number: number): Promise<void>;
67
+ /**
68
+ * Press and release the cue button, once its opcode is known.
69
+ */
70
+ cue(number: number): Promise<void>;
71
+ /**
72
+ * Hold fast-forward for `holdMs`.
73
+ */
74
+ fastForward(number: number, holdMs: number): Promise<void>;
75
+ /**
76
+ * Hold rewind for `holdMs`.
77
+ */
78
+ rewind(number: number, holdMs: number): Promise<void>;
79
+ skipForward(number: number): Promise<void>;
80
+ skipBackward(number: number): Promise<void>;
81
+ /**
82
+ * One transport packet: `op` pressed or released.
83
+ */
84
+ transport(number: number, op: number, press: boolean): Promise<void>;
85
+ /**
86
+ * Press `op`, hold it for `holdMs`, release it.
87
+ */
88
+ tap(number: number, op: number, holdMs: number): Promise<void>;
89
+ /**
90
+ * What is in a player's USB and SD slots, as the player answers a media
91
+ * query; a slot it does not answer for is left out.
92
+ */
93
+ media(number: number): Promise<MediaSlotInfo[]>;
94
+ /**
95
+ * Tell a player to load a track from `source` (another player's stick, or a
96
+ * library served over the link).
97
+ */
98
+ loadTrack(number: number, trackId: number, source: LoadSource): Promise<void>;
99
+ leave(): Promise<void>;
100
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The REST API over a {@link Remote}. JSON in and out; every error is
3
+ * `{"error": "…"}` with a status that says whose fault it was.
4
+ *
5
+ * GET / who we are, every device heard, the booth's power
6
+ * GET /players the players with their last status
7
+ * GET /players/{n}/media what is in the player's USB and SD slots
8
+ * POST /players/{n}/play
9
+ * POST /players/{n}/pause
10
+ * POST /players/{n}/cue
11
+ * POST /players/{n}/ff {"hold_ms": 500} hold fast-forward, then release
12
+ * POST /players/{n}/rew {"hold_ms": 500}
13
+ * POST /players/{n}/skip {"direction": "forward" | "backward"}
14
+ * POST /players/{n}/op {"op": 26, "press": true} one raw transport packet
15
+ * POST /players/{n}/load {"track_id": 1, "source": {"device": 2, "slot": "usb"}}
16
+ * GET /booth the Hue group and whether it is on
17
+ * PUT /booth {"on": true}
18
+ * POST /booth/on
19
+ * POST /booth/off
20
+ * GET /hue/groups every room and zone the bridge has
21
+ */
22
+ import http from 'http';
23
+ import { Logger } from "../logger";
24
+ import { Hue } from './hue';
25
+ import { Remote } from './index';
26
+ export interface ServerOptions {
27
+ remote: Remote;
28
+ hue: Hue | null;
29
+ /** The Hue room or zone the booth's gear is plugged into. */
30
+ boothGroup: string;
31
+ logger?: Logger;
32
+ }
33
+ export declare function createServer({ remote, hue, boothGroup, logger }: ServerOptions): http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
@@ -65,7 +65,7 @@ export declare const UInt8: {
65
65
  data: Buffer;
66
66
  };
67
67
  type: NumberFieldType;
68
- bytesToRead: 1 | 2 | 4;
68
+ bytesToRead: 1 | 4 | 2;
69
69
  };
70
70
  /**
71
71
  * Field representing a UInt16
@@ -81,7 +81,7 @@ export declare const UInt16: {
81
81
  data: Buffer;
82
82
  };
83
83
  type: NumberFieldType;
84
- bytesToRead: 1 | 2 | 4;
84
+ bytesToRead: 1 | 4 | 2;
85
85
  };
86
86
  /**
87
87
  * Field representing a UInt32
@@ -97,7 +97,7 @@ export declare const UInt32: {
97
97
  data: Buffer;
98
98
  };
99
99
  type: NumberFieldType;
100
- bytesToRead: 1 | 2 | 4;
100
+ bytesToRead: 1 | 4 | 2;
101
101
  };
102
102
  /**
103
103
  * Field representing a null-terminated big endian UTF-16 string
@@ -131,7 +131,7 @@ declare const fieldMap: {
131
131
  data: Buffer;
132
132
  };
133
133
  type: NumberFieldType;
134
- bytesToRead: 1 | 2 | 4;
134
+ bytesToRead: 1 | 4 | 2;
135
135
  };
136
136
  readonly 16: {
137
137
  new (value: number | Buffer): {
@@ -144,7 +144,7 @@ declare const fieldMap: {
144
144
  data: Buffer;
145
145
  };
146
146
  type: NumberFieldType;
147
- bytesToRead: 1 | 2 | 4;
147
+ bytesToRead: 1 | 4 | 2;
148
148
  };
149
149
  readonly 17: {
150
150
  new (value: number | Buffer): {
@@ -157,7 +157,7 @@ declare const fieldMap: {
157
157
  data: Buffer;
158
158
  };
159
159
  type: NumberFieldType;
160
- bytesToRead: 1 | 2 | 4;
160
+ bytesToRead: 1 | 4 | 2;
161
161
  };
162
162
  readonly 20: typeof Binary;
163
163
  readonly 38: typeof String;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alphatheta-connect",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "main": "lib/index.js",
5
5
  "author": "Evan Purkhiser <evanpurkhiser@gmail.com>",
6
6
  "contributors": [