@stinkycomputing/sesame-api-client 1.4.1-alpha.9 → 1.4.1-beta.10

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/README.md CHANGED
@@ -1,16 +1,10 @@
1
1
  # @stinkycomputing/sesame-api-client
2
2
 
3
- Official TypeScript/JavaScript client library for the Sesame video production server.
3
+ TypeScript client library for the Sesame video production server. Provides type-safe protobuf definitions, a WebSocket RPC client with reconnection, and helpers for building command lists.
4
4
 
5
- ## Features
5
+ All websocket traffic uses protobuf wire framing — see [Wire Protocol](#wire-protocol).
6
6
 
7
- - 🎯 **Full Protobuf API** - Complete type-safe protobuf definitions for all Sesame APIs
8
- - 🔧 **Command List Helper** - Fluent API for building command lists
9
- - 🌐 **RPC Client** - WebSocket-based RPC client with automatic reconnection
10
- - 📦 **Modular Design** - New v1 API with domain-specific modules
11
- - 🔄 **Backward Compatible** - Supports both legacy and new API structures
12
-
13
- ## Installation
7
+ ## Install
14
8
 
15
9
  ```bash
16
10
  npm install @stinkycomputing/sesame-api-client
@@ -18,196 +12,126 @@ npm install @stinkycomputing/sesame-api-client
18
12
 
19
13
  ## Quick Start
20
14
 
21
- ### Node.js (Full Client with RPC)
22
-
23
- For Node.js applications that need the full RPC client:
24
-
25
15
  ```typescript
26
16
  import { SesameClient, CommandList } from '@stinkycomputing/sesame-api-client';
27
17
 
28
- // Create client
29
- const client = new SesameClient(8080);
18
+ const client = new SesameClient(9000);
30
19
 
31
- // Build command list
32
20
  const cl = new CommandList();
33
- cl.sourceAdd('my-source', {
34
- type: 'file',
35
- path: '/path/to/video.mp4'
36
- });
21
+ cl.sourceAdd('my-source', { type: 'file', path: '/path/to/video.mp4' });
37
22
  cl.compositorAdd('main', 1920, 1080, false);
38
23
 
39
- // Execute commands
40
24
  await client.execute(cl);
41
-
42
- // Listen to events
43
- client.on('status', (status) => {
44
- console.log('Status update:', status);
45
- });
46
25
  ```
47
26
 
48
- ### Browser (Protobuf Types Only)
27
+ Works in the browser too — the browser entry point bundles `events` and other Node built-ins so `SesameClient`, `RPCClient`, and `WireProtocol` all work without polyfills.
49
28
 
50
- For browser applications that only need protobuf types (e.g., for decoding messages from WebSocket):
29
+ ## Protobuf Modules
51
30
 
52
- ```typescript
53
- import { Sesame } from '@stinkycomputing/sesame-api-client/browser';
31
+ Types are generated from `.proto` files under `sesame.v1.*`:
54
32
 
55
- // Decode a status message received from WebSocket
56
- const statusBytes = new Uint8Array(data);
57
- const status = Sesame.PB.StatusMessage.decode(statusBytes);
58
- const statusObj = Sesame.PB.StatusMessage.toObject(status, { longs: Number });
59
- console.log('Status:', statusObj);
33
+ ```typescript
34
+ import { sesame } from '@stinkycomputing/sesame-api-client';
60
35
  ```
61
36
 
62
- **Browser entry point (`/browser`) includes:**
63
- - ✅ Protobuf types (`Sesame`, `sesame`, `Message`)
64
- - `CommandList` helper
65
- - `SesameBinaryProtocol` utilities
66
- - Logger abstraction
67
- - No Node.js dependencies (`events`, `ws`)
68
- - ❌ No `RPCClient` or `SesameConnection` classes
37
+ | Module | Contents |
38
+ |--------|----------|
39
+ | `sesame.v1.wire` | Wire framing (FrameHeader, FrameType, MediaCodecData) |
40
+ | `sesame.v1.common` | Shared types (Empty, Vec4, PropValue, EventTopic) |
41
+ | `sesame.v1.sources` | Source config and transport |
42
+ | `sesame.v1.outputs` | Output config and encoder settings |
43
+ | `sesame.v1.compositor` | Scene graph, nodes, properties, animations |
44
+ | `sesame.v1.audio` | Audio mixer and channels |
45
+ | `sesame.v1.recorder` | Recorder, clips, playlists |
46
+ | `sesame.v1.jobs` | Background export/import jobs |
47
+ | `sesame.v1.status` | Status polling and event subscriptions |
48
+ | `sesame.v1.commands` | Command list items |
49
+ | `sesame.v1.rpc` | RPC message envelope (Request/Response/Event) |
69
50
 
70
- ## API Structure
51
+ For the complete type reference with every enum value, message field, and property name, see **[Protocol Reference](docs/protocol-reference.md)**.
71
52
 
72
- ### Legacy API (Sesame.PB)
53
+ ## Wire Protocol
73
54
 
74
- The legacy API uses the `Sesame.PB` namespace:
55
+ Every websocket message is framed as:
75
56
 
76
- ```typescript
77
- import { Sesame } from '@stinkycomputing/sesame-api-client';
78
-
79
- const msg: Sesame.PB.AddSourceMessage = {
80
- id: 'source1',
81
- type: Sesame.PB.SourceType.ST_FILE,
82
- // ...
83
- };
57
+ ```
58
+ [4-byte LE header_size][FrameHeader protobuf][payload bytes]
84
59
  ```
85
60
 
86
- ### New Modular API (sesame.v1.*)
87
-
88
- The new API is organized into domain-specific modules:
61
+ `WireProtocol.serialize` / `WireProtocol.parse` handle this:
89
62
 
90
63
  ```typescript
91
- import { sesame } from '@stinkycomputing/sesame-api-client';
64
+ import { WireProtocol, sesame } from '@stinkycomputing/sesame-api-client';
92
65
 
93
- const msg: sesame.v1.sources.SourceAddRequest = {
94
- id: 'source1',
95
- type: sesame.v1.sources.SourceType.SOURCE_TYPE_FILE,
96
- // ...
97
- };
98
- ```
66
+ // serialize
67
+ const frame = WireProtocol.serialize(
68
+ { type: sesame.v1.wire.FrameType.FRAME_TYPE_RPC },
69
+ rpcPayload,
70
+ );
99
71
 
100
- #### Available Modules
72
+ // parse
73
+ const parsed = WireProtocol.parse(incoming);
74
+ if (parsed.valid) {
75
+ // parsed.header.type, parsed.payload
76
+ }
77
+ ```
101
78
 
102
- - `sesame.v1.common` - Common types (Empty, Vec4, PropValue, etc.)
103
- - `sesame.v1.sources` - Source management
104
- - `sesame.v1.outputs` - Output management
105
- - `sesame.v1.compositor` - Compositor and scene graph
106
- - `sesame.v1.audio` - Audio mixer
107
- - `sesame.v1.recorder` - Recorder and clips
108
- - `sesame.v1.jobs` - Background jobs (export/import)
109
- - `sesame.v1.status` - Status and events
110
- - `sesame.v1.commands` - Command list system
111
- - `sesame.v1.rpc` - RPC protocol
79
+ Frame types: `FRAME_TYPE_RPC`, `FRAME_TYPE_VIDEO`, `FRAME_TYPE_AUDIO`, `FRAME_TYPE_MUXED`, `FRAME_TYPE_DECODER_DATA`, `FRAME_TYPE_DATA`.
112
80
 
113
- ## Command List Helper
81
+ ## Command List
114
82
 
115
- The `CommandList` class provides a fluent API for building command sequences:
83
+ `CommandList` builds a batch of operations to send in one `execute` call:
116
84
 
117
85
  ```typescript
118
86
  const cl = new CommandList();
119
87
 
120
- // Add source
121
- cl.sourceAdd('cam1', {
122
- type: 'decklink',
123
- deviceIndex: 0
124
- });
125
-
126
- // Add compositor
88
+ cl.sourceAdd('cam1', { type: 'decklink', deviceIndex: 0 });
127
89
  cl.compositorAdd('main', 1920, 1080, false);
90
+ cl.nodeAdd('main', 'cam1-node', 'source', { sourceId: 'cam1' });
128
91
 
129
- // Add node to compositor
130
- cl.nodeAdd('main', 'cam1-node', 'source', {
131
- sourceId: 'cam1'
132
- });
133
-
134
- // Set properties
135
92
  cl.propertySet(
136
93
  { compositor: 'main', node: 'cam1-node' },
137
- 'transform',
138
- 'position',
139
- { vecValue: { r: 100, g: 100 } }
94
+ 'transform', 'position',
95
+ { vecValue: { r: 100, g: 100 } },
140
96
  );
141
97
 
142
- // Transport control
143
98
  cl.transportCommand('cam1', { type: 'play' });
144
99
 
145
- // Execute all commands
146
100
  await client.execute(cl);
147
101
  ```
148
102
 
149
103
  ### Animations
150
104
 
151
- Use the `keyframe()` helper to build type-safe animation keyframes. The easing parameters are constrained to the `EaseKind` enum, so invalid values are caught at compile time:
152
-
153
105
  ```typescript
154
106
  import { CommandList, keyframe, EaseKind, sesame } from '@stinkycomputing/sesame-api-client';
155
107
 
156
108
  const cl = new CommandList();
157
-
158
109
  cl.propertyAnimate(
159
- { compositor: 'main', node: 'cam1-node' }, // property domain
160
- 'cam1-node', // address
161
- 'opacity', // property name
162
- sesame.v1.compositor.AnimationChannelEvaluationMode.HOLD, // before
163
- sesame.v1.compositor.AnimationChannelEvaluationMode.HOLD, // after
110
+ { compositor: 'main', node: 'cam1-node' },
111
+ 'cam1-node', 'opacity',
112
+ sesame.v1.compositor.AnimationChannelEvaluationMode.HOLD,
113
+ sesame.v1.compositor.AnimationChannelEvaluationMode.HOLD,
164
114
  [
165
115
  keyframe(0, { floatValue: 0.0 }),
166
116
  keyframe(500000, { floatValue: 1.0 }, EaseKind.QUADRATIC_INOUT),
167
117
  keyframe(1000000, { floatValue: 0.5 }, EaseKind.CUBIC_IN, EaseKind.CUBIC_OUT),
168
- ]
118
+ ],
169
119
  );
170
120
  ```
171
121
 
172
- The `keyframe(timeUs, value, easingIn?, easingOut?)` parameters:
173
- - **timeUs** — time in microseconds
174
- - **value** — a `PropValue` (`floatValue`, `intValue`, `vec4Value`, `stringValue`, or `boolValue`)
175
- - **easingIn** *(optional)* — easing curve entering this keyframe (`EaseKind`)
176
- - **easingOut** *(optional)* — easing curve leaving this keyframe (`EaseKind`)
177
-
178
- ## Deployment Notes
122
+ `keyframe(timeUs, value, easingIn?, easingOut?)` — time in microseconds, value is a `PropValue`, easing uses `EaseKind`.
179
123
 
180
- When using this package in a bundled application (e.g., with esbuild):
124
+ ## Bundling
181
125
 
182
- - **Bundle the package**: Include `@stinkycomputing/sesame-api-client` in your bundle for zero-dependency deployment
183
- - **External native deps**: Only mark native binary modules as external (`ws`, `bufferutil`, `utf-8-validate`)
184
- - **Production install**: Only `npm install` the native dependencies in production
185
-
186
- This approach gives you:
187
- - ✅ Single bundle file with all code
188
- - ✅ Minimal production dependencies (3 packages)
189
- - ✅ Fast deployment
190
- - ✅ No version conflicts
126
+ All dependencies (`events`, `long`, `protobufjs`) are pure JS — no native modules. The package bundles cleanly with esbuild or similar without any special `external` config.
191
127
 
192
128
  ## Publishing
193
129
 
194
- The package is published manually to npm from a local machine.
195
-
196
- ### Prerequisites (one-time setup)
197
-
198
- 1. Create the `@stinkycomputing` organization on [npmjs.com](https://www.npmjs.com/org/create)
199
- 2. Log in to npm: `npm login`
200
-
201
- ### Release process
202
-
203
- 1. Update the version in `package.json`
204
- 2. Build: `npm run build`
205
- 3. Publish:
206
- - **Stable release:** `npm publish --access public`
207
- - **Prerelease:** `npm publish --access public --tag alpha` (or `beta`, etc.)
208
- 4. Commit and tag: `git tag api-client-vX.Y.Z && git push origin api-client-vX.Y.Z`
130
+ 1. Bump version in `package.json`
131
+ 2. `npm run build`
132
+ 3. `npm publish --access public` (or `--tag alpha` for prereleases)
133
+ 4. `git tag api-client-vX.Y.Z && git push origin api-client-vX.Y.Z`
209
134
 
210
135
  ## License
211
136
 
212
137
  MIT
213
-