@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 +60 -136
- package/dist/index.browser.mjs +2054 -1520
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +2058 -1522
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +2054 -1520
- package/dist/index.mjs.map +4 -4
- package/dist/jobs-api.d.ts +5 -6
- package/dist/jobs-api.d.ts.map +1 -1
- package/dist/proto/api.d.ts +936 -897
- package/dist/proto/api.js +3716 -3072
- package/dist/rpc-client.d.ts +7 -0
- package/dist/rpc-client.d.ts.map +1 -1
- package/dist/sesame-api-client.d.ts +5 -6
- package/dist/sesame-api-client.d.ts.map +1 -1
- package/dist/sesame-connection.d.ts +11 -2
- package/dist/sesame-connection.d.ts.map +1 -1
- package/dist/sesame-wire-protocol.d.ts +29 -0
- package/dist/sesame-wire-protocol.d.ts.map +1 -0
- package/dist/status-api.d.ts +0 -1
- package/dist/status-api.d.ts.map +1 -1
- package/docs/protocol-reference.md +1218 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
# @stinkycomputing/sesame-api-client
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
5
|
+
All websocket traffic uses protobuf wire framing — see [Wire Protocol](#wire-protocol).
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
29
|
+
## Protobuf Modules
|
|
51
30
|
|
|
52
|
-
|
|
53
|
-
import { Sesame } from '@stinkycomputing/sesame-api-client/browser';
|
|
31
|
+
Types are generated from `.proto` files under `sesame.v1.*`:
|
|
54
32
|
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
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
|
-
|
|
53
|
+
## Wire Protocol
|
|
73
54
|
|
|
74
|
-
|
|
55
|
+
Every websocket message is framed as:
|
|
75
56
|
|
|
76
|
-
```
|
|
77
|
-
|
|
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
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
type: sesame.v1.
|
|
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
|
-
|
|
72
|
+
// parse
|
|
73
|
+
const parsed = WireProtocol.parse(incoming);
|
|
74
|
+
if (parsed.valid) {
|
|
75
|
+
// parsed.header.type, parsed.payload
|
|
76
|
+
}
|
|
77
|
+
```
|
|
101
78
|
|
|
102
|
-
|
|
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
|
|
81
|
+
## Command List
|
|
114
82
|
|
|
115
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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' },
|
|
160
|
-
'cam1-node',
|
|
161
|
-
|
|
162
|
-
sesame.v1.compositor.AnimationChannelEvaluationMode.HOLD,
|
|
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
|
-
|
|
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
|
-
|
|
124
|
+
## Bundling
|
|
181
125
|
|
|
182
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|