tirtc-devtools-cli 0.0.13 → 0.0.15

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.
Files changed (137) hide show
  1. package/README.md +42 -46
  2. package/USAGE.md +87 -312
  3. package/dist/cli/src/embedded_paths.d.ts +0 -2
  4. package/dist/cli/src/embedded_paths.js +3 -25
  5. package/dist/cli/src/index.js +82 -584
  6. package/dist/cli/src/role_driver.d.ts +33 -0
  7. package/dist/cli/src/role_driver.js +500 -0
  8. package/dist/cli/src/token_command.js +4 -2
  9. package/dist/cli/src/token_issue.d.ts +9 -0
  10. package/dist/cli/src/token_issue.js +138 -0
  11. package/dist/cli/src/token_tool.d.ts +2 -4
  12. package/dist/cli/src/token_tool.js +12 -186
  13. package/package.json +3 -2
  14. package/vendor/devtools/driver/macos-arm64/devtools_driver_probe +0 -0
  15. package/vendor/devtools/driver/macos-arm64/runtime_validation_client_bin +0 -0
  16. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio.h +56 -2
  17. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io.h +9 -0
  18. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/av.h +52 -0
  19. package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/error.h +11 -0
  20. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_downlink.h +11 -5
  21. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_uplink.h +4 -0
  22. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/transport.h +52 -15
  23. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/trp.h +7 -5
  24. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_codec.h +41 -0
  25. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io.h +7 -0
  26. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_android.h +2 -0
  27. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_audio.a +0 -0
  28. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
  29. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_foundation_http.a +0 -0
  30. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_foundation_logging.a +0 -0
  31. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
  32. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
  33. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
  34. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/manifest.txt +20 -25
  35. package/vendor/runtime/script/prepare_runtime_media_dataset.sh +308 -12
  36. package/dist/app-server/protocol-client/index.d.ts +0 -25
  37. package/dist/app-server/protocol-client/index.js +0 -114
  38. package/dist/cli/src/bootstrap_flows.d.ts +0 -46
  39. package/dist/cli/src/bootstrap_flows.js +0 -249
  40. package/dist/cli/src/config.d.ts +0 -26
  41. package/dist/cli/src/config.js +0 -62
  42. package/dist/cli/src/facade.d.ts +0 -430
  43. package/dist/cli/src/facade.js +0 -170
  44. package/dist/cli/src/guide.d.ts +0 -1
  45. package/dist/cli/src/guide.js +0 -48
  46. package/dist/cli/src/session_manager.d.ts +0 -25
  47. package/dist/cli/src/session_manager.js +0 -391
  48. package/dist/cli/src/transport.d.ts +0 -30
  49. package/dist/cli/src/transport.js +0 -84
  50. package/vendor/app-server/bin/native/linux-x64/credential_napi.node +0 -0
  51. package/vendor/app-server/bin/native/macos-arm64/credential_napi.node +0 -0
  52. package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/credential.h +0 -34
  53. package/vendor/app-server/bin/runtime/linux-x64/lib/libcrypto.a +0 -0
  54. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_credential.a +0 -0
  55. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_http.a +0 -0
  56. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_logging.a +0 -0
  57. package/vendor/app-server/bin/runtime/linux-x64/lib/libssl.a +0 -0
  58. package/vendor/app-server/bin/runtime/linux-x64/lib/libxlog.a +0 -0
  59. package/vendor/app-server/bin/runtime/linux-x64/manifest.txt +0 -4
  60. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/credential.h +0 -34
  61. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/error.h +0 -52
  62. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/foundation/build_info.h +0 -27
  63. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/http.h +0 -57
  64. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/logging.h +0 -55
  65. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_av_sync.h +0 -61
  66. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_source.h +0 -77
  67. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_live_source.h +0 -71
  68. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_credential.a +0 -0
  69. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
  70. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
  71. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
  72. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
  73. package/vendor/app-server/bin/tirtc-devtool-host.js +0 -2
  74. package/vendor/app-server/dist/host/ArtifactManager.d.ts +0 -18
  75. package/vendor/app-server/dist/host/ArtifactManager.js +0 -98
  76. package/vendor/app-server/dist/host/HostCommandCoordinator.d.ts +0 -19
  77. package/vendor/app-server/dist/host/HostCommandCoordinator.js +0 -196
  78. package/vendor/app-server/dist/host/HostProtocol.d.ts +0 -103
  79. package/vendor/app-server/dist/host/HostProtocol.js +0 -239
  80. package/vendor/app-server/dist/host/HostServer.d.ts +0 -52
  81. package/vendor/app-server/dist/host/HostServer.js +0 -727
  82. package/vendor/app-server/dist/host/HostState.d.ts +0 -69
  83. package/vendor/app-server/dist/host/HostState.js +0 -19
  84. package/vendor/app-server/dist/host/RuntimeAdapter.d.ts +0 -95
  85. package/vendor/app-server/dist/host/RuntimeAdapter.js +0 -636
  86. package/vendor/app-server/dist/host/RuntimeReceiveWorker.d.ts +0 -37
  87. package/vendor/app-server/dist/host/RuntimeReceiveWorker.js +0 -186
  88. package/vendor/app-server/dist/host/RuntimeSendWorker.d.ts +0 -58
  89. package/vendor/app-server/dist/host/RuntimeSendWorker.js +0 -438
  90. package/vendor/app-server/dist/host/TokenTool.d.ts +0 -15
  91. package/vendor/app-server/dist/host/TokenTool.js +0 -84
  92. package/vendor/app-server/dist/host/WebPreviewGateway.d.ts +0 -28
  93. package/vendor/app-server/dist/host/WebPreviewGateway.js +0 -815
  94. package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.d.ts +0 -23
  95. package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.js +0 -115
  96. package/vendor/app-server/dist/host/native/RuntimeHostBridge.d.ts +0 -32
  97. package/vendor/app-server/dist/host/native/RuntimeHostBridge.js +0 -157
  98. package/vendor/app-server/dist/host/runtime_backed_preflight.d.ts +0 -10
  99. package/vendor/app-server/dist/host/runtime_backed_preflight.js +0 -78
  100. package/vendor/app-server/dist/host/tests/helpers/host_socket_client.d.ts +0 -28
  101. package/vendor/app-server/dist/host/tests/helpers/host_socket_client.js +0 -85
  102. package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.d.ts +0 -10
  103. package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.js +0 -41
  104. package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.d.ts +0 -11
  105. package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.js +0 -32
  106. package/vendor/app-server/dist/protocol/contract.d.ts +0 -1128
  107. package/vendor/app-server/dist/protocol/contract.js +0 -217
  108. package/vendor/app-server/dist/protocol-client/index.d.ts +0 -25
  109. package/vendor/app-server/dist/protocol-client/index.js +0 -114
  110. package/vendor/app-server/dist/src/index.d.ts +0 -1
  111. package/vendor/app-server/dist/src/index.js +0 -294
  112. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_codec.h +0 -0
  113. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_frame.h +0 -0
  114. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_android.h +0 -0
  115. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_apple.h +0 -0
  116. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_harmony.h +0 -0
  117. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_windows.h +0 -0
  118. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_processing.h +0 -0
  119. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_sample_rate.h +0 -0
  120. /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/foundation/build_info.h +0 -0
  121. /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/http.h +0 -0
  122. /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/logging.h +0 -0
  123. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_codec.h +0 -0
  124. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_frame.h +0 -0
  125. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_apple.h +0 -0
  126. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_harmony.h +0 -0
  127. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_windows.h +0 -0
  128. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_processing.h +0 -0
  129. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libTGTRP.a +0 -0
  130. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libTiRTC.a +0 -0
  131. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libcrypto.a +0 -0
  132. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libcrypto.dylib +0 -0
  133. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libssl.a +0 -0
  134. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libssl.dylib +0 -0
  135. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libtgrtc.dylib +0 -0
  136. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libwebrtc_apm.a +0 -0
  137. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libxlog.a +0 -0
@@ -1,636 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.RuntimeBackedAdapter = void 0;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- const RuntimeSendWorker_1 = require("./RuntimeSendWorker");
40
- const RuntimeReceiveWorker_1 = require("./RuntimeReceiveWorker");
41
- const WebPreviewGateway_1 = require("./WebPreviewGateway");
42
- function nowIsoString() {
43
- return new Date().toISOString();
44
- }
45
- function pathExists(p) {
46
- return fs.existsSync(p);
47
- }
48
- function ensureDir(dirPath) {
49
- if (!fs.existsSync(dirPath)) {
50
- fs.mkdirSync(dirPath, { recursive: true });
51
- }
52
- }
53
- function tryGetNumber(value) {
54
- if (typeof value === 'number' && Number.isFinite(value)) {
55
- return value;
56
- }
57
- if (typeof value === 'string' && value.trim().length > 0) {
58
- const parsed = Number(value);
59
- if (Number.isFinite(parsed)) {
60
- return parsed;
61
- }
62
- }
63
- return undefined;
64
- }
65
- function resolveRepoRoot() {
66
- const explicit = process.env.TIRTC_REPO_ROOT;
67
- const appServerRoot = process.env.TIRTC_APP_SERVER_ROOT;
68
- const candidates = [
69
- appServerRoot,
70
- explicit,
71
- process.cwd(),
72
- path.resolve(process.cwd(), '..'),
73
- path.resolve(__dirname, '../..'),
74
- path.resolve(__dirname, '../../..'),
75
- path.resolve(__dirname, '../../../..'),
76
- ].filter((v) => typeof v === 'string' && v.trim().length > 0);
77
- for (const candidate of candidates) {
78
- const normalized = path.resolve(candidate);
79
- if (pathExists(path.join(normalized, 'bin/runtime')) ||
80
- pathExists(path.join(normalized, 'bin/native')) ||
81
- pathExists(path.join(normalized, 'products/app-server/bin/runtime')) ||
82
- pathExists(path.join(normalized, 'products/app-server'))) {
83
- return normalized;
84
- }
85
- }
86
- return appServerRoot && appServerRoot.trim().length > 0 ? path.resolve(appServerRoot) : path.resolve(process.cwd());
87
- }
88
- function resolveDefaultServiceEntry() {
89
- const explicit = process.env.TIRTC_RUNTIME_SERVICE_ENTRY;
90
- if (explicit && explicit.trim().length > 0) {
91
- return explicit.trim();
92
- }
93
- return undefined;
94
- }
95
- function resolveOutputRoot() {
96
- const explicitArtifactRoot = process.env.TIRTC_HOST_ARTIFACT_DIR;
97
- if (explicitArtifactRoot && explicitArtifactRoot.trim().length > 0) {
98
- return path.join(path.resolve(explicitArtifactRoot.trim()), 'received-media');
99
- }
100
- const explicit = process.env.TIRTC_HOST_OUTPUT_DIR;
101
- if (explicit && explicit.trim().length > 0) {
102
- return path.resolve(explicit.trim());
103
- }
104
- return path.join(path.resolve(process.cwd()), '.tmp', 'tirtc-devtools-cli', 'output');
105
- }
106
- function normalizeMedia(media) {
107
- if (media === 'audio') {
108
- return 'audio';
109
- }
110
- if (media === 'video') {
111
- return 'video';
112
- }
113
- return undefined;
114
- }
115
- function resolveStreamAssetsDir(source) {
116
- if (source.mode !== 'local_assets') {
117
- throw new Error('unsupported stream source mode: ' + String(source.mode ?? '<unknown>'));
118
- }
119
- const assetsDir = path.resolve(source.local_assets.assets_dir);
120
- let stats;
121
- try {
122
- stats = fs.statSync(assetsDir);
123
- }
124
- catch {
125
- throw new Error('stream local assets directory does not exist: ' + assetsDir);
126
- }
127
- if (!stats.isDirectory()) {
128
- throw new Error('stream local assets path is not a directory: ' + assetsDir);
129
- }
130
- const manifestPath = path.join(assetsDir, 'manifest.json');
131
- if (!pathExists(manifestPath)) {
132
- throw new Error('stream local assets manifest not found: ' + manifestPath);
133
- }
134
- return assetsDir;
135
- }
136
- function decodePayload(payloadEncoding, payload) {
137
- if (payloadEncoding === 'base64') {
138
- return Uint8Array.from(Buffer.from(payload, 'base64'));
139
- }
140
- return Uint8Array.from(Buffer.from(payload, 'utf8'));
141
- }
142
- function encodePayload(payload) {
143
- const buffer = Buffer.from(payload);
144
- const utf8Text = buffer.toString('utf8');
145
- if (Buffer.from(utf8Text, 'utf8').equals(buffer)) {
146
- return {
147
- payloadEncoding: 'utf8',
148
- payload: utf8Text,
149
- };
150
- }
151
- return {
152
- payloadEncoding: 'base64',
153
- payload: buffer.toString('base64'),
154
- };
155
- }
156
- class RuntimeBackedAdapter {
157
- runtimeTarget;
158
- hostEndpoint = 'stdio://runtime-backed';
159
- runtimeBundleRoot;
160
- repoRoot;
161
- platform;
162
- sendWorker;
163
- receiveWorker;
164
- eventHandler;
165
- outputCounter = 1;
166
- commandSequence = 1;
167
- connected = false;
168
- defaultServiceEntry;
169
- activeService;
170
- connectionContext;
171
- outputs = new Map();
172
- receiveStreams = new Map();
173
- previewGateway = new WebPreviewGateway_1.WebPreviewGateway();
174
- receiveRefreshTimer;
175
- constructor(options) {
176
- this.runtimeBundleRoot = options.runtimeBundleRoot;
177
- this.platform = options.platform;
178
- this.runtimeTarget = 'runtime-backed/' + options.platform;
179
- this.repoRoot = resolveRepoRoot();
180
- this.sendWorker = new RuntimeSendWorker_1.RuntimeSendWorkerManager({
181
- repoRoot: this.repoRoot,
182
- platform: this.platform,
183
- onLogLine: (payload) => {
184
- this.emit('logs', 'runtime.line', payload);
185
- },
186
- onRuntimeEvent: (kind, payload) => {
187
- if (kind === 'connection.accepted') {
188
- this.connected = true;
189
- }
190
- else if (kind === 'connection.disconnected') {
191
- this.connected = false;
192
- }
193
- this.emit('runtime', kind, payload);
194
- },
195
- });
196
- this.receiveWorker = new RuntimeReceiveWorker_1.RuntimeReceiveWorkerManager({
197
- repoRoot: this.repoRoot,
198
- platform: this.platform,
199
- onLogLine: (payload) => {
200
- this.emit('logs', 'runtime.line', payload);
201
- },
202
- });
203
- }
204
- setEventHandler(handler) {
205
- this.eventHandler = handler;
206
- }
207
- emit(family, kind, payload) {
208
- this.recordOutputEvent(family, kind, payload);
209
- if (!this.eventHandler) {
210
- return;
211
- }
212
- this.eventHandler(family, kind, payload);
213
- }
214
- recordOutputEvent(family, kind, payload) {
215
- if (this.outputs.size === 0) {
216
- return;
217
- }
218
- const payloadStreamId = tryGetNumber(payload.streamId);
219
- const timestamp = nowIsoString();
220
- for (const output of this.outputs.values()) {
221
- if (output.receiveBoundEver) {
222
- continue;
223
- }
224
- if (payloadStreamId !== undefined && payloadStreamId !== output.streamId) {
225
- continue;
226
- }
227
- const line = JSON.stringify({
228
- at: timestamp,
229
- family,
230
- kind,
231
- streamId: output.streamId,
232
- payload,
233
- }) + '\n';
234
- try {
235
- fs.appendFileSync(output.targetPath, line, 'utf8');
236
- }
237
- catch {
238
- // no-op
239
- }
240
- }
241
- }
242
- assertRuntimeBundleReady() {
243
- const includePath = path.join(this.runtimeBundleRoot, 'include');
244
- const libPath = path.join(this.runtimeBundleRoot, 'lib');
245
- const manifestPath = path.join(this.runtimeBundleRoot, 'manifest.txt');
246
- if (!pathExists(includePath) || !pathExists(libPath) || !pathExists(manifestPath)) {
247
- throw new Error('runtime bundle is not ready at ' + this.runtimeBundleRoot);
248
- }
249
- }
250
- resolveServiceEntry(serviceEntry) {
251
- if (serviceEntry && serviceEntry.trim().length > 0) {
252
- return serviceEntry;
253
- }
254
- if (!this.defaultServiceEntry) {
255
- this.defaultServiceEntry = resolveDefaultServiceEntry();
256
- }
257
- return this.defaultServiceEntry ?? '';
258
- }
259
- scheduleReceiveRefresh() {
260
- if (this.receiveRefreshTimer) {
261
- clearTimeout(this.receiveRefreshTimer);
262
- }
263
- this.receiveRefreshTimer = setTimeout(() => {
264
- this.receiveRefreshTimer = undefined;
265
- void this.refreshReceiveWorker();
266
- }, 80);
267
- }
268
- async refreshReceiveWorker() {
269
- if (!this.connected || !this.connectionContext) {
270
- await this.receiveWorker.stopAll();
271
- return;
272
- }
273
- const bindings = [];
274
- for (const attachment of this.outputs.values()) {
275
- if (!attachment.media) {
276
- continue;
277
- }
278
- bindings.push({
279
- key: attachment.outputId + "/" + String(attachment.streamId) + "/" + attachment.media,
280
- serviceEntry: this.connectionContext.serviceEntry,
281
- peerId: this.connectionContext.peerId,
282
- token: this.connectionContext.token,
283
- streamId: attachment.streamId,
284
- media: attachment.media,
285
- targetPath: attachment.targetPath,
286
- framed: attachment.consumer === 'web_preview',
287
- });
288
- }
289
- await this.receiveWorker.syncBindings(bindings);
290
- }
291
- async startService(serviceEntry, license, timeoutMs) {
292
- this.assertRuntimeBundleReady();
293
- const resolvedServiceEntry = this.resolveServiceEntry(serviceEntry);
294
- const keepaliveSession = await this.sendWorker.ensureServiceSession(resolvedServiceEntry, license);
295
- this.activeService = {
296
- serviceEntry: resolvedServiceEntry,
297
- license,
298
- startedAt: nowIsoString(),
299
- };
300
- this.emit('service', 'start.requested', {
301
- serviceEntry: resolvedServiceEntry,
302
- licensePresent: license.length > 0,
303
- timeoutMs,
304
- senderBootstrapStarted: keepaliveSession.started,
305
- workerPid: keepaliveSession.pid,
306
- at: nowIsoString(),
307
- });
308
- return resolvedServiceEntry;
309
- }
310
- async stopService() {
311
- this.activeService = undefined;
312
- await this.sendWorker.stopAll();
313
- await this.receiveWorker.stopAll();
314
- if (this.receiveRefreshTimer) {
315
- clearTimeout(this.receiveRefreshTimer);
316
- this.receiveRefreshTimer = undefined;
317
- }
318
- this.previewGateway.dispose();
319
- this.emit('service', 'stop.requested', { at: nowIsoString() });
320
- }
321
- async connect(serviceEntry, peerId, token, timeoutMs) {
322
- this.assertRuntimeBundleReady();
323
- const resolvedServiceEntry = this.resolveServiceEntry(serviceEntry);
324
- this.emit('connection', 'connect.requested', {
325
- serviceEntry: resolvedServiceEntry,
326
- peerId,
327
- tokenPresent: token.length > 0,
328
- timeoutMs,
329
- at: nowIsoString(),
330
- });
331
- this.connected = true;
332
- this.connectionContext = {
333
- serviceEntry: resolvedServiceEntry,
334
- peerId,
335
- token,
336
- };
337
- this.emit('connection', 'connect.validated', {
338
- serviceEntry: resolvedServiceEntry,
339
- peerId,
340
- at: nowIsoString(),
341
- });
342
- const activeService = this.activeService;
343
- if (activeService) {
344
- this.emit('stream', 'send.auto.resume.requested', {
345
- serviceEntry: activeService.serviceEntry,
346
- startedAt: activeService.startedAt,
347
- at: nowIsoString(),
348
- });
349
- }
350
- await this.refreshReceiveWorker();
351
- return resolvedServiceEntry;
352
- }
353
- async disconnect() {
354
- this.connected = false;
355
- this.connectionContext = undefined;
356
- this.receiveStreams.clear();
357
- await this.sendWorker.stopAll();
358
- await this.receiveWorker.stopAll();
359
- if (this.receiveRefreshTimer) {
360
- clearTimeout(this.receiveRefreshTimer);
361
- this.receiveRefreshTimer = undefined;
362
- }
363
- this.previewGateway.dispose();
364
- this.emit('connection', 'disconnect.requested', { at: nowIsoString() });
365
- }
366
- async startSendStream(streamId, media, source) {
367
- const assetsDir = resolveStreamAssetsDir(source);
368
- const activeService = this.activeService;
369
- let autoStarted = false;
370
- let workerPid;
371
- if (activeService) {
372
- const key = String(streamId) + '/' + media;
373
- const startResult = await this.sendWorker.startDeviceStream({
374
- key,
375
- serviceEntry: activeService.serviceEntry,
376
- license: activeService.license,
377
- assetsDir,
378
- streamId,
379
- media: media === 'audio' ? 'audio' : 'video',
380
- });
381
- autoStarted = startResult.started;
382
- workerPid = startResult.pid;
383
- }
384
- this.emit('stream', 'send.start.requested', {
385
- streamId,
386
- media,
387
- sourceMode: source.mode,
388
- assetsDir,
389
- connected: this.connected,
390
- workerPid,
391
- autoStarted,
392
- deferred: !activeService,
393
- at: nowIsoString(),
394
- });
395
- return { autoStarted, workerPid };
396
- }
397
- async startSendStreams(streams) {
398
- const activeService = this.activeService;
399
- if (!activeService || streams.length === 0) {
400
- return streams.map(() => ({ autoStarted: false }));
401
- }
402
- const bindings = streams.map((stream) => ({
403
- key: String(stream.streamId) + '/' + stream.media,
404
- serviceEntry: activeService.serviceEntry,
405
- license: activeService.license,
406
- assetsDir: resolveStreamAssetsDir(stream.source),
407
- streamId: stream.streamId,
408
- media: stream.media === 'audio' ? 'audio' : 'video',
409
- }));
410
- const startResult = await this.sendWorker.startDeviceStreams(bindings);
411
- const startedAt = nowIsoString();
412
- for (const binding of bindings) {
413
- this.emit('stream', 'send.start.requested', {
414
- streamId: binding.streamId,
415
- media: binding.media,
416
- sourceMode: 'local_assets',
417
- assetsDir: binding.assetsDir,
418
- connected: this.connected,
419
- workerPid: startResult.pid,
420
- autoStarted: startResult.started,
421
- deferred: false,
422
- at: startedAt,
423
- });
424
- }
425
- return bindings.map(() => ({ autoStarted: startResult.started, workerPid: startResult.pid }));
426
- }
427
- async stopSendStream(streamId) {
428
- const keys = [String(streamId) + '/audio', String(streamId) + '/video'];
429
- for (const key of keys) {
430
- await this.sendWorker.stopStream(key);
431
- }
432
- this.emit('stream', 'send.stop.requested', { streamId, at: nowIsoString() });
433
- }
434
- async sendStreamMessage(streamId, payload) {
435
- if (!this.connected) {
436
- throw new Error('connection is not established');
437
- }
438
- await this.sendWorker.sendStreamMessage(streamId, decodePayload('utf8', payload));
439
- this.emit('stream', 'message.runtime.send', {
440
- streamId,
441
- payloadPreview: payload.slice(0, 120),
442
- payloadLength: payload.length,
443
- at: nowIsoString(),
444
- });
445
- }
446
- async startReceiveStream(streamId, media) {
447
- if (!this.connected) {
448
- throw new Error('connection is not established');
449
- }
450
- const normalized = normalizeMedia(media);
451
- if (!normalized) {
452
- throw new Error('unsupported receive media: ' + media);
453
- }
454
- this.receiveStreams.set(streamId, normalized);
455
- this.emit('stream', 'receive.start.requested', { streamId, media, at: nowIsoString() });
456
- await this.refreshReceiveWorker();
457
- }
458
- async stopReceiveStream(streamId) {
459
- this.receiveStreams.delete(streamId);
460
- this.emit('stream', 'receive.stop.requested', { streamId, at: nowIsoString() });
461
- await this.refreshReceiveWorker();
462
- }
463
- async attachOutput(streamId, consumer, mediaView, format, delivery, targetPath, maxFiles) {
464
- if (!this.connected) {
465
- throw new Error('connection is not established');
466
- }
467
- const outputId = 'rt-out-' + streamId + '-' + this.outputCounter;
468
- this.outputCounter += 1;
469
- const safeFormat = (format || 'bin').replace(/[^a-zA-Z0-9]/g, '').toLowerCase() || 'bin';
470
- const resolvedTargetPath = targetPath && targetPath.trim().length > 0
471
- ? path.resolve(targetPath)
472
- : path.join(resolveOutputRoot(), `${outputId}.${safeFormat}`);
473
- ensureDir(path.dirname(resolvedTargetPath));
474
- let receiveMedia = this.receiveStreams.get(streamId);
475
- if (!receiveMedia && consumer === 'web_preview') {
476
- if (format.toLowerCase() === 'g711a' || format.toLowerCase() === 'alaw' || format.toLowerCase() === 'pcm') {
477
- receiveMedia = 'audio';
478
- }
479
- else if (format.toLowerCase() === 'h264' || format.toLowerCase() === 'jpeg' || format.toLowerCase() === 'mjpeg') {
480
- receiveMedia = 'video';
481
- }
482
- if (receiveMedia) {
483
- this.receiveStreams.set(streamId, receiveMedia);
484
- }
485
- }
486
- if (receiveMedia) {
487
- for (const existing of this.outputs.values()) {
488
- if (existing.streamId === streamId && existing.media === receiveMedia) {
489
- throw new Error(`output already attached for stream=${streamId} media=${receiveMedia}; detach existing output first`);
490
- }
491
- }
492
- }
493
- fs.writeFileSync(resolvedTargetPath, Buffer.alloc(0));
494
- const attachedAt = nowIsoString();
495
- let preview;
496
- if (consumer === 'web_preview') {
497
- if (!receiveMedia) {
498
- throw new Error(`web_preview requires active receive stream binding for stream=${streamId}`);
499
- }
500
- preview = await this.previewGateway.registerSource(outputId, receiveMedia, streamId, resolvedTargetPath, async () => {
501
- if (!this.connected) {
502
- throw new Error('connection is not established');
503
- }
504
- this.scheduleReceiveRefresh();
505
- this.emit('stream', 'preview.start.requested', {
506
- streamId,
507
- media: receiveMedia,
508
- outputId,
509
- at: nowIsoString(),
510
- });
511
- }, async () => {
512
- if (!this.connected) {
513
- return;
514
- }
515
- this.scheduleReceiveRefresh();
516
- this.emit('stream', 'preview.stop.requested', {
517
- streamId,
518
- media: receiveMedia,
519
- outputId,
520
- at: nowIsoString(),
521
- });
522
- });
523
- }
524
- const attachment = {
525
- outputId,
526
- streamId,
527
- media: receiveMedia,
528
- consumer,
529
- mediaView,
530
- format,
531
- delivery,
532
- targetPath: resolvedTargetPath,
533
- attachedAt,
534
- receiveBoundEver: Boolean(receiveMedia),
535
- preview,
536
- };
537
- this.outputs.set(outputId, attachment);
538
- if (!receiveMedia) {
539
- const bootstrapLine = JSON.stringify({
540
- at: attachedAt,
541
- family: 'stream',
542
- kind: 'output.attach',
543
- streamId,
544
- outputId,
545
- consumer,
546
- mediaView,
547
- format,
548
- delivery,
549
- maxFiles,
550
- }) + '\n';
551
- fs.appendFileSync(resolvedTargetPath, bootstrapLine, 'utf8');
552
- }
553
- if (receiveMedia && consumer !== 'web_preview') {
554
- this.scheduleReceiveRefresh();
555
- }
556
- this.emit('stream', 'output.attach.requested', {
557
- outputId,
558
- streamId,
559
- consumer,
560
- mediaView,
561
- format,
562
- delivery,
563
- targetPath: resolvedTargetPath,
564
- maxFiles,
565
- at: attachedAt,
566
- runtimeDownlink: Boolean(receiveMedia),
567
- preview,
568
- });
569
- return {
570
- outputId,
571
- targetPath: resolvedTargetPath,
572
- attachedAt,
573
- preview,
574
- };
575
- }
576
- async detachOutput(outputId) {
577
- const attachment = this.outputs.get(outputId);
578
- if (attachment) {
579
- if (attachment.consumer === 'web_preview') {
580
- this.previewGateway.unregisterSource(outputId);
581
- }
582
- if (!attachment.receiveBoundEver) {
583
- const line = JSON.stringify({
584
- at: nowIsoString(),
585
- family: 'stream',
586
- kind: 'output.detach',
587
- streamId: attachment.streamId,
588
- outputId,
589
- }) + '\n';
590
- try {
591
- fs.appendFileSync(attachment.targetPath, line, 'utf8');
592
- }
593
- catch {
594
- // no-op
595
- }
596
- }
597
- this.outputs.delete(outputId);
598
- }
599
- await this.refreshReceiveWorker();
600
- this.emit('stream', 'output.detach.requested', { outputId, at: nowIsoString() });
601
- }
602
- async sendCommand(commandId, payloadEncoding, payload, timeoutMs) {
603
- if (!this.connected) {
604
- throw new Error('connection is not established');
605
- }
606
- this.emit('command', 'send.requested', {
607
- commandId,
608
- payloadEncoding,
609
- timeoutMs,
610
- at: nowIsoString(),
611
- });
612
- const sequenceNumber = this.commandSequence;
613
- this.commandSequence += 1;
614
- const response = await this.sendWorker.requestCommand(commandId, decodePayload(payloadEncoding, payload), timeoutMs ?? 15000);
615
- const encodedResponse = encodePayload(response.payload);
616
- return {
617
- sequenceNumber,
618
- payloadEncoding: encodedResponse.payloadEncoding,
619
- payload: encodedResponse.payload,
620
- };
621
- }
622
- async replyRemoteCommand(remoteRequestId, commandId, payloadEncoding, payload) {
623
- if (!this.connected) {
624
- throw new Error('connection is not established');
625
- }
626
- this.emit('command', 'reply.requested', {
627
- remoteRequestId,
628
- commandId,
629
- payloadEncoding,
630
- payloadLength: payload.length,
631
- at: nowIsoString(),
632
- });
633
- await this.sendWorker.replyRemoteCommand(remoteRequestId, commandId, decodePayload(payloadEncoding, payload));
634
- }
635
- }
636
- exports.RuntimeBackedAdapter = RuntimeBackedAdapter;
@@ -1,37 +0,0 @@
1
- type ReceiveWorkerManagerOptions = {
2
- repoRoot: string;
3
- platform: string;
4
- onLogLine?: (payload: {
5
- source: 'downlink';
6
- stream: 'stdout' | 'stderr';
7
- line: string;
8
- pid?: number;
9
- }) => void;
10
- };
11
- type ReceiveWorkerStartOptions = {
12
- key: string;
13
- serviceEntry: string;
14
- peerId: string;
15
- token: string;
16
- streamId: number;
17
- media: 'audio' | 'video';
18
- targetPath: string;
19
- framed: boolean;
20
- };
21
- export declare class RuntimeReceiveWorkerManager {
22
- private readonly bindings;
23
- private readonly onLogLine?;
24
- private readonly bridge;
25
- private sharedSession?;
26
- constructor(options: ReceiveWorkerManagerOptions);
27
- private emitLog;
28
- private buildDesiredConfig;
29
- private stopSharedSession;
30
- private ensureSharedSession;
31
- syncBindings(bindings: ReceiveWorkerStartOptions[]): Promise<{
32
- started: boolean;
33
- pid?: number;
34
- }>;
35
- stopAll(): Promise<void>;
36
- }
37
- export {};