tirtc-devtools-cli 0.0.1
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 +52 -0
- package/USAGE.md +417 -0
- package/bin/tirtc-devtool.js +2 -0
- package/dist/app-server/protocol-client/index.d.ts +25 -0
- package/dist/app-server/protocol-client/index.js +114 -0
- package/dist/devtools/cli/src/config.d.ts +46 -0
- package/dist/devtools/cli/src/config.js +98 -0
- package/dist/devtools/cli/src/dummy.d.ts +0 -0
- package/dist/devtools/cli/src/dummy.js +1 -0
- package/dist/devtools/cli/src/embedded_paths.d.ts +7 -0
- package/dist/devtools/cli/src/embedded_paths.js +85 -0
- package/dist/devtools/cli/src/facade.d.ts +723 -0
- package/dist/devtools/cli/src/facade.js +194 -0
- package/dist/devtools/cli/src/ffmpeg_tool.d.ts +6 -0
- package/dist/devtools/cli/src/ffmpeg_tool.js +146 -0
- package/dist/devtools/cli/src/guide.d.ts +1 -0
- package/dist/devtools/cli/src/guide.js +49 -0
- package/dist/devtools/cli/src/index.d.ts +1 -0
- package/dist/devtools/cli/src/index.js +753 -0
- package/dist/devtools/cli/src/media_assets.d.ts +25 -0
- package/dist/devtools/cli/src/media_assets.js +121 -0
- package/dist/devtools/cli/src/session_manager.d.ts +25 -0
- package/dist/devtools/cli/src/session_manager.js +393 -0
- package/dist/devtools/cli/src/token_tool.d.ts +33 -0
- package/dist/devtools/cli/src/token_tool.js +217 -0
- package/dist/devtools/cli/src/transport.d.ts +30 -0
- package/dist/devtools/cli/src/transport.js +84 -0
- package/dist/dummy.d.ts +0 -0
- package/dist/dummy.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +48 -0
- package/package.json +54 -0
- package/script/ensure_ffmpeg.sh +22 -0
- package/vendor/app-server/bin/native/macos-arm64/credential_napi.node +0 -0
- package/vendor/app-server/bin/native/macos-arm64/libcrypto.dylib +0 -0
- package/vendor/app-server/bin/native/macos-arm64/libssl.dylib +0 -0
- package/vendor/app-server/bin/native/macos-arm64/libtgrtc.dylib +0 -0
- package/vendor/app-server/bin/native/macos-arm64/runtime_host_napi.node +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_codec.h +23 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_frame.h +36 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_io.h +56 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_io_android.h +19 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_io_apple.h +19 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_io_harmony.h +19 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_io_windows.h +19 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_processing.h +56 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/audio_sample_rate.h +18 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/error.h +20 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/logging.h +53 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/media_codec.h +21 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/media_downlink.h +89 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/media_uplink.h +115 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/runtime.h +236 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_codec.h +57 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_frame.h +55 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_io.h +46 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_io_android.h +32 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_io_apple.h +34 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_io_harmony.h +32 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_io_windows.h +26 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/video_processing.h +34 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_audio.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_facade.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_logging.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_media.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_video.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libwebrtc_apm.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libxlog.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/manifest.txt +34 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio.h +398 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_codec.h +23 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_frame.h +36 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_io.h +56 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_io_android.h +19 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_io_apple.h +19 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_io_harmony.h +19 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_io_windows.h +19 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_processing.h +56 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio_sample_rate.h +18 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/av.h +452 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/credential.h +34 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/error.h +30 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/foundation/build_info.h +27 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/http.h +57 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/logging.h +55 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_codec.h +21 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_downlink.h +95 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_av_sync.h +61 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_source.h +77 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_live_source.h +71 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_uplink.h +116 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/transport.h +481 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/trp.h +541 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_codec.h +58 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_frame.h +55 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_io.h +46 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_io_android.h +32 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_io_apple.h +47 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_io_harmony.h +32 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_io_windows.h +26 -0
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/video_processing.h +34 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libcrypto.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libcrypto.dylib +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_audio.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_credential.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_foundation_http.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_foundation_logging.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libssl.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libssl.dylib +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libwebrtc_apm.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libxlog.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/manifest.txt +50 -0
- package/vendor/app-server/bin/tirtc-devtool-host.js +2 -0
- package/vendor/app-server/dist/host/ArtifactManager.d.ts +18 -0
- package/vendor/app-server/dist/host/ArtifactManager.js +83 -0
- package/vendor/app-server/dist/host/HostProtocol.d.ts +107 -0
- package/vendor/app-server/dist/host/HostProtocol.js +256 -0
- package/vendor/app-server/dist/host/HostServer.d.ts +49 -0
- package/vendor/app-server/dist/host/HostServer.js +635 -0
- package/vendor/app-server/dist/host/HostState.d.ts +60 -0
- package/vendor/app-server/dist/host/HostState.js +19 -0
- package/vendor/app-server/dist/host/RuntimeAdapter.d.ts +81 -0
- package/vendor/app-server/dist/host/RuntimeAdapter.js +559 -0
- package/vendor/app-server/dist/host/RuntimeCredentialTokenIssuer.d.ts +30 -0
- package/vendor/app-server/dist/host/RuntimeCredentialTokenIssuer.js +224 -0
- package/vendor/app-server/dist/host/RuntimeReceiveWorker.d.ts +37 -0
- package/vendor/app-server/dist/host/RuntimeReceiveWorker.js +186 -0
- package/vendor/app-server/dist/host/RuntimeSendWorker.d.ts +42 -0
- package/vendor/app-server/dist/host/RuntimeSendWorker.js +274 -0
- package/vendor/app-server/dist/host/TokenTool.d.ts +15 -0
- package/vendor/app-server/dist/host/TokenTool.js +84 -0
- package/vendor/app-server/dist/host/WebPreviewGateway.d.ts +28 -0
- package/vendor/app-server/dist/host/WebPreviewGateway.js +815 -0
- package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.d.ts +26 -0
- package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.js +118 -0
- package/vendor/app-server/dist/host/native/RuntimeHostBridge.d.ts +19 -0
- package/vendor/app-server/dist/host/native/RuntimeHostBridge.js +141 -0
- package/vendor/app-server/dist/host/runtime_backed_preflight.d.ts +10 -0
- package/vendor/app-server/dist/host/runtime_backed_preflight.js +78 -0
- package/vendor/app-server/dist/host/tests/helpers/host_socket_client.d.ts +28 -0
- package/vendor/app-server/dist/host/tests/helpers/host_socket_client.js +85 -0
- package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.d.ts +10 -0
- package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.js +41 -0
- package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.d.ts +11 -0
- package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.js +32 -0
- package/vendor/app-server/dist/protocol/contract.d.ts +983 -0
- package/vendor/app-server/dist/protocol/contract.js +198 -0
- package/vendor/app-server/dist/protocol-client/index.d.ts +25 -0
- package/vendor/app-server/dist/protocol-client/index.js +114 -0
- package/vendor/app-server/dist/src/index.d.ts +1 -0
- package/vendor/app-server/dist/src/index.js +294 -0
- package/vendor/runtime/script/prepare_runtime_media_dataset.sh +427 -0
|
@@ -0,0 +1,635 @@
|
|
|
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.HostServer = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const TokenTool_1 = require("./TokenTool");
|
|
40
|
+
const RuntimeCredentialTokenIssuer_1 = require("./native/RuntimeCredentialTokenIssuer");
|
|
41
|
+
const HostState_1 = require("./HostState");
|
|
42
|
+
const HostProtocol_1 = require("./HostProtocol");
|
|
43
|
+
function streamBindingKey(streamId, media) {
|
|
44
|
+
return `${streamId}/${media}`;
|
|
45
|
+
}
|
|
46
|
+
function resolveLocalAssetsDir(source) {
|
|
47
|
+
if (source.mode !== 'local_assets') {
|
|
48
|
+
throw new HostProtocol_1.HostProtocolError('invalid_request', 'Unsupported source.mode', false);
|
|
49
|
+
}
|
|
50
|
+
const assetsDir = path.resolve(source.local_assets.assets_dir);
|
|
51
|
+
let stats;
|
|
52
|
+
try {
|
|
53
|
+
stats = fs.statSync(assetsDir);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
throw new HostProtocol_1.HostProtocolError('invalid_request', 'source.local_assets.assets_dir does not exist', false);
|
|
57
|
+
}
|
|
58
|
+
if (!stats.isDirectory()) {
|
|
59
|
+
throw new HostProtocol_1.HostProtocolError('invalid_request', 'source.local_assets.assets_dir must be a directory', false);
|
|
60
|
+
}
|
|
61
|
+
const manifestPath = path.join(assetsDir, 'manifest.json');
|
|
62
|
+
if (!fs.existsSync(manifestPath)) {
|
|
63
|
+
throw new HostProtocol_1.HostProtocolError('invalid_request', 'source.local_assets.assets_dir missing manifest.json', false);
|
|
64
|
+
}
|
|
65
|
+
return assetsDir;
|
|
66
|
+
}
|
|
67
|
+
class HostServer {
|
|
68
|
+
state;
|
|
69
|
+
artifactManager;
|
|
70
|
+
runtimeAdapter;
|
|
71
|
+
isInitialized = false;
|
|
72
|
+
eventCounter = 1;
|
|
73
|
+
commandSequence = 1;
|
|
74
|
+
tokenTool;
|
|
75
|
+
runtimeCredentialTokenIssuer;
|
|
76
|
+
eventSinks = new Set();
|
|
77
|
+
constructor(artifactManager, runtimeAdapter, hostEndpoint) {
|
|
78
|
+
this.state = new HostState_1.HostState();
|
|
79
|
+
this.artifactManager = artifactManager;
|
|
80
|
+
this.runtimeAdapter = runtimeAdapter;
|
|
81
|
+
this.state.runtimeTarget = runtimeAdapter.runtimeTarget;
|
|
82
|
+
this.state.hostEndpoint = hostEndpoint ?? runtimeAdapter.hostEndpoint;
|
|
83
|
+
this.tokenTool = new TokenTool_1.TokenTool(this.artifactManager.getPaths().rootPath);
|
|
84
|
+
this.runtimeCredentialTokenIssuer = new RuntimeCredentialTokenIssuer_1.RuntimeCredentialTokenIssuer({
|
|
85
|
+
repoRoot: runtimeAdapter.repoRoot,
|
|
86
|
+
platform: runtimeAdapter.platform,
|
|
87
|
+
runtimeBundleRoot: runtimeAdapter.runtimeBundleRoot,
|
|
88
|
+
});
|
|
89
|
+
this.runtimeAdapter.setEventHandler((family, kind, payload) => {
|
|
90
|
+
this.handleRuntimeEvent(family, kind, payload);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async handleMessage(message) {
|
|
94
|
+
let request;
|
|
95
|
+
try {
|
|
96
|
+
request = (0, HostProtocol_1.parseRequest)(message);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return JSON.stringify({
|
|
100
|
+
error: {
|
|
101
|
+
code: -32700,
|
|
102
|
+
message: 'Parse error',
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (request.method === 'initialized') {
|
|
107
|
+
this.isInitialized = true;
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const params = (0, HostProtocol_1.toParamsRecord)(request.params);
|
|
111
|
+
try {
|
|
112
|
+
const result = await this.dispatch(request.method, params);
|
|
113
|
+
if (request.id === undefined) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
return JSON.stringify({ id: request.id, result });
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (request.id === undefined) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const normalized = (0, HostProtocol_1.normalizeError)(error);
|
|
123
|
+
const response = {
|
|
124
|
+
id: request.id,
|
|
125
|
+
error: {
|
|
126
|
+
code: -32000,
|
|
127
|
+
message: normalized.message,
|
|
128
|
+
data: {
|
|
129
|
+
reasonCode: normalized.reasonCode,
|
|
130
|
+
message: normalized.message,
|
|
131
|
+
retryable: normalized.retryable,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
return JSON.stringify(response);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
writeEvent(family, kind, payload) {
|
|
139
|
+
const event = {
|
|
140
|
+
eventId: 'evt-' + String(this.eventCounter++),
|
|
141
|
+
timestamp: new Date().toISOString(),
|
|
142
|
+
family,
|
|
143
|
+
kind,
|
|
144
|
+
payload,
|
|
145
|
+
};
|
|
146
|
+
this.artifactManager.writeEvent(event);
|
|
147
|
+
if (this.state.subscriptions.has(family) || this.state.subscriptions.has('*')) {
|
|
148
|
+
this.pushEvent(event);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
pushEvent(event) {
|
|
152
|
+
for (const sink of this.eventSinks) {
|
|
153
|
+
try {
|
|
154
|
+
sink(event);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// no-op
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
addEventSink(sink) {
|
|
162
|
+
this.eventSinks.add(sink);
|
|
163
|
+
}
|
|
164
|
+
removeEventSink(sink) {
|
|
165
|
+
this.eventSinks.delete(sink);
|
|
166
|
+
}
|
|
167
|
+
appendHostLog(line) {
|
|
168
|
+
const withNewline = line.endsWith('\n') ? line : line + '\n';
|
|
169
|
+
this.artifactManager.appendHostLog(withNewline);
|
|
170
|
+
const normalized = withNewline.endsWith('\n') ? withNewline.slice(0, -1) : withNewline;
|
|
171
|
+
this.writeEvent('logs', 'host.line', { line: normalized });
|
|
172
|
+
}
|
|
173
|
+
handleRuntimeEvent(family, kind, payload) {
|
|
174
|
+
this.writeEvent(family, kind, payload);
|
|
175
|
+
if (family !== 'runtime') {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (kind === 'transport.remote.request') {
|
|
179
|
+
const streamId = Number(payload.streamId);
|
|
180
|
+
const mediaRaw = String(payload.media ?? '');
|
|
181
|
+
if ((mediaRaw === 'audio' || mediaRaw === 'video') && Number.isFinite(streamId)) {
|
|
182
|
+
this.maybeAutoStartStreamFromRemoteDemand(streamId, mediaRaw, payload);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
maybeAutoStartStreamFromRemoteDemand(streamId, media, payload) {
|
|
187
|
+
if (this.state.streamRequestPolicy.mode !== 'auto-if-bound') {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const key = streamBindingKey(streamId, media);
|
|
191
|
+
const bound = this.state.streamSourceBindings.get(key);
|
|
192
|
+
if (!bound) {
|
|
193
|
+
this.writeEvent('stream', 'send.auto.skipped', {
|
|
194
|
+
reason: 'source_not_bound',
|
|
195
|
+
streamId,
|
|
196
|
+
media,
|
|
197
|
+
at: new Date().toISOString(),
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const existing = this.state.streams.get(streamId);
|
|
202
|
+
if (existing && existing.direction === 'send' && existing.state === 'active') {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const stream = {
|
|
206
|
+
streamId,
|
|
207
|
+
media,
|
|
208
|
+
direction: 'send',
|
|
209
|
+
state: this.state.connection.state === 'connected' ? 'active' : 'pending_on_connection',
|
|
210
|
+
source: bound.source,
|
|
211
|
+
updatedAt: new Date().toISOString(),
|
|
212
|
+
};
|
|
213
|
+
this.state.streams.set(streamId, stream);
|
|
214
|
+
this.writeEvent('stream', 'send.auto.started', {
|
|
215
|
+
streamId,
|
|
216
|
+
media,
|
|
217
|
+
sourceMode: bound.source.mode,
|
|
218
|
+
assetsDir: bound.source.local_assets.assets_dir,
|
|
219
|
+
trigger: payload.kind ?? 'remote_request',
|
|
220
|
+
at: new Date().toISOString(),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
async dispatch(method, params) {
|
|
224
|
+
if (method === 'initialize') {
|
|
225
|
+
return this.handleInitialize();
|
|
226
|
+
}
|
|
227
|
+
if (!this.isInitialized) {
|
|
228
|
+
throw new HostProtocol_1.HostProtocolError('not_initialized', 'Initialize has not been called', false);
|
|
229
|
+
}
|
|
230
|
+
switch (method) {
|
|
231
|
+
case 'host/status':
|
|
232
|
+
return this.handleHostStatus();
|
|
233
|
+
case 'host/shutdown':
|
|
234
|
+
return this.handleHostShutdown();
|
|
235
|
+
case 'service/start':
|
|
236
|
+
return this.handleServiceStart((0, HostProtocol_1.parseServiceStartParams)(params));
|
|
237
|
+
case 'service/stop':
|
|
238
|
+
return this.handleServiceStop();
|
|
239
|
+
case 'connection/get':
|
|
240
|
+
return this.handleConnectionGet();
|
|
241
|
+
case 'connection/connect':
|
|
242
|
+
return this.handleConnectionConnect((0, HostProtocol_1.parseConnectionConnectParams)(params));
|
|
243
|
+
case 'connection/disconnect':
|
|
244
|
+
return this.handleConnectionDisconnect();
|
|
245
|
+
case 'stream/list':
|
|
246
|
+
return this.handleStreamList();
|
|
247
|
+
case 'stream/sendStart':
|
|
248
|
+
return this.handleStreamSendStart((0, HostProtocol_1.parseStreamSendStartParams)(params));
|
|
249
|
+
case 'stream/sendStop':
|
|
250
|
+
return this.handleStreamSendStop((0, HostProtocol_1.parseStreamStopParams)(params));
|
|
251
|
+
case 'stream/receiveStart':
|
|
252
|
+
return this.handleStreamReceiveStart((0, HostProtocol_1.parseStreamReceiveStartParams)(params));
|
|
253
|
+
case 'stream/receiveStop':
|
|
254
|
+
return this.handleStreamReceiveStop((0, HostProtocol_1.parseStreamStopParams)(params));
|
|
255
|
+
case 'stream/requestPolicy/get':
|
|
256
|
+
return this.handleStreamRequestPolicyGet();
|
|
257
|
+
case 'stream/requestPolicy/set':
|
|
258
|
+
return this.handleStreamRequestPolicySet((0, HostProtocol_1.parseStreamRequestPolicySetParams)(params));
|
|
259
|
+
case 'output/attach':
|
|
260
|
+
return this.handleOutputAttach((0, HostProtocol_1.parseOutputAttachParams)(params));
|
|
261
|
+
case 'output/detach':
|
|
262
|
+
return this.handleOutputDetach((0, HostProtocol_1.parseOutputDetachParams)(params));
|
|
263
|
+
case 'command/send':
|
|
264
|
+
return this.handleCommandSend((0, HostProtocol_1.parseCommandSendParams)(params));
|
|
265
|
+
case 'events/subscribe':
|
|
266
|
+
return this.handleEventsSubscribe((0, HostProtocol_1.parseEventsSubscribeParams)(params));
|
|
267
|
+
case 'artifact/readReport':
|
|
268
|
+
return this.handleArtifactReadReport();
|
|
269
|
+
case 'artifact/exportLogs':
|
|
270
|
+
return this.handleArtifactExportLogs((0, HostProtocol_1.parseArtifactExportParams)(params));
|
|
271
|
+
case 'artifact/exportReport':
|
|
272
|
+
return this.handleArtifactExportReport((0, HostProtocol_1.parseArtifactExportParams)(params));
|
|
273
|
+
case 'debug/token/qrcode':
|
|
274
|
+
return this.handleDebugTokenQrcode((0, HostProtocol_1.parseDebugTokenQrcodeParams)(params));
|
|
275
|
+
default:
|
|
276
|
+
throw new HostProtocol_1.HostProtocolError('method_not_found', `Method ${method} not found`, false);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
async handleInitialize() {
|
|
280
|
+
return {
|
|
281
|
+
serverInfo: {
|
|
282
|
+
name: 'TiRTC App Server Host',
|
|
283
|
+
version: this.state.serverVersion,
|
|
284
|
+
},
|
|
285
|
+
protocolVersion: this.state.protocolVersion,
|
|
286
|
+
runtimeTarget: this.state.runtimeTarget,
|
|
287
|
+
hostEndpoint: this.state.hostEndpoint,
|
|
288
|
+
capabilities: {
|
|
289
|
+
streamRequestPolicy: {
|
|
290
|
+
mode: this.state.streamRequestPolicy.mode,
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
async handleHostStatus() {
|
|
296
|
+
return {
|
|
297
|
+
hostEndpoint: this.state.hostEndpoint,
|
|
298
|
+
serverVersion: this.state.serverVersion,
|
|
299
|
+
protocolVersion: this.state.protocolVersion,
|
|
300
|
+
runtimeTarget: this.state.runtimeTarget,
|
|
301
|
+
startedAt: this.state.startedAt,
|
|
302
|
+
service: this.state.service,
|
|
303
|
+
connection: this.state.connection,
|
|
304
|
+
streamRequestPolicy: this.state.streamRequestPolicy,
|
|
305
|
+
artifactPaths: this.artifactManager.getPaths(),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
async handleHostShutdown() {
|
|
309
|
+
return {
|
|
310
|
+
acceptedAt: new Date().toISOString(),
|
|
311
|
+
service: this.state.service,
|
|
312
|
+
connection: this.state.connection,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
async handleServiceStart(params) {
|
|
316
|
+
if (this.state.service.state !== 'stopped') {
|
|
317
|
+
throw new HostProtocol_1.HostProtocolError('busy', 'Service is not stopped', false);
|
|
318
|
+
}
|
|
319
|
+
if (this.state.connection.state !== 'idle' &&
|
|
320
|
+
this.state.connection.state !== 'disconnected' &&
|
|
321
|
+
this.state.connection.state !== 'failed') {
|
|
322
|
+
throw new HostProtocol_1.HostProtocolError('busy', 'Connection is not idle', false);
|
|
323
|
+
}
|
|
324
|
+
const resolvedServiceEntry = await this.runtimeAdapter.startService(params.serviceEntry, params.license, params.timeoutMs);
|
|
325
|
+
this.state.service = {
|
|
326
|
+
state: 'waiting_peer',
|
|
327
|
+
serviceEntry: resolvedServiceEntry,
|
|
328
|
+
startedAt: new Date().toISOString(),
|
|
329
|
+
};
|
|
330
|
+
return this.state.service;
|
|
331
|
+
}
|
|
332
|
+
async handleServiceStop() {
|
|
333
|
+
if (this.state.service.state === 'stopped') {
|
|
334
|
+
return {
|
|
335
|
+
acceptedAt: new Date().toISOString(),
|
|
336
|
+
service: this.state.service,
|
|
337
|
+
connection: this.state.connection,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
await this.runtimeAdapter.stopService();
|
|
341
|
+
this.state.service.state = 'stopped';
|
|
342
|
+
this.state.service.stoppedAt = new Date().toISOString();
|
|
343
|
+
return {
|
|
344
|
+
acceptedAt: new Date().toISOString(),
|
|
345
|
+
service: this.state.service,
|
|
346
|
+
connection: this.state.connection,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
async handleConnectionGet() {
|
|
350
|
+
return this.state.connection;
|
|
351
|
+
}
|
|
352
|
+
async resolveConnectionToken(params) {
|
|
353
|
+
const trimmedToken = params.token?.trim();
|
|
354
|
+
const wantsAuto = params.tokenMode === "auto" || (!trimmedToken && params.autoToken !== undefined);
|
|
355
|
+
if (!wantsAuto) {
|
|
356
|
+
if (!trimmedToken || trimmedToken.length === 0) {
|
|
357
|
+
throw new HostProtocol_1.HostProtocolError("invalid_request", "token is required when tokenMode is manual", false);
|
|
358
|
+
}
|
|
359
|
+
return { token: trimmedToken, mode: "manual" };
|
|
360
|
+
}
|
|
361
|
+
if (!params.autoToken) {
|
|
362
|
+
throw new HostProtocol_1.HostProtocolError("invalid_request", "auto token mode requires autoToken config", false);
|
|
363
|
+
}
|
|
364
|
+
const issued = await this.runtimeCredentialTokenIssuer.issueToken({
|
|
365
|
+
openapiEntry: params.autoToken.openapiEntry,
|
|
366
|
+
accessId: params.autoToken.accessId,
|
|
367
|
+
secretKey: params.autoToken.secretKey,
|
|
368
|
+
localId: params.autoToken.localId ?? params.peerId,
|
|
369
|
+
peerId: params.peerId,
|
|
370
|
+
userTtlSeconds: params.autoToken.userTtlSeconds,
|
|
371
|
+
channelTtlSeconds: params.autoToken.channelTtlSeconds,
|
|
372
|
+
});
|
|
373
|
+
return { token: issued, mode: "auto" };
|
|
374
|
+
}
|
|
375
|
+
async handleConnectionConnect(params) {
|
|
376
|
+
if (this.state.connection.state !== "idle" &&
|
|
377
|
+
this.state.connection.state !== "disconnected" &&
|
|
378
|
+
this.state.connection.state !== "failed") {
|
|
379
|
+
throw new HostProtocol_1.HostProtocolError("busy", "Connection is not idle", false);
|
|
380
|
+
}
|
|
381
|
+
if (this.state.service.state !== "stopped") {
|
|
382
|
+
throw new HostProtocol_1.HostProtocolError("busy", "Service is not stopped", false);
|
|
383
|
+
}
|
|
384
|
+
const tokenResolve = await this.resolveConnectionToken(params);
|
|
385
|
+
this.writeEvent("connection", "token.prepared", {
|
|
386
|
+
mode: tokenResolve.mode,
|
|
387
|
+
peerId: params.peerId,
|
|
388
|
+
tokenLength: tokenResolve.token.length,
|
|
389
|
+
at: new Date().toISOString(),
|
|
390
|
+
});
|
|
391
|
+
const resolvedServiceEntry = await this.runtimeAdapter.connect(params.serviceEntry, params.peerId, tokenResolve.token, params.timeoutMs);
|
|
392
|
+
this.state.connection = {
|
|
393
|
+
state: 'connecting',
|
|
394
|
+
direction: 'outgoing',
|
|
395
|
+
peerId: params.peerId,
|
|
396
|
+
};
|
|
397
|
+
if (this.state.service.state === 'stopped') {
|
|
398
|
+
this.state.service.serviceEntry = resolvedServiceEntry;
|
|
399
|
+
}
|
|
400
|
+
this.state.connection.state = 'connected';
|
|
401
|
+
this.state.connection.connectedAt = new Date().toISOString();
|
|
402
|
+
await this.startDeferredSendStreamsOnConnected();
|
|
403
|
+
this.activatePendingStreamsOnConnected();
|
|
404
|
+
return this.state.connection;
|
|
405
|
+
}
|
|
406
|
+
async startDeferredSendStreamsOnConnected() {
|
|
407
|
+
if (this.state.service.state === 'stopped') {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const now = new Date().toISOString();
|
|
411
|
+
for (const stream of this.state.streams.values()) {
|
|
412
|
+
if (stream.direction !== 'send' || stream.state !== 'pending_on_connection' || !stream.source) {
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
const sendResult = await this.runtimeAdapter.startSendStream(stream.streamId, stream.media, stream.source);
|
|
417
|
+
this.writeEvent('stream', 'send.deferred.started_on_connection', {
|
|
418
|
+
streamId: stream.streamId,
|
|
419
|
+
media: stream.media,
|
|
420
|
+
sourceMode: stream.source.mode,
|
|
421
|
+
assetsDir: stream.source.local_assets.assets_dir,
|
|
422
|
+
autoStarted: sendResult.autoStarted,
|
|
423
|
+
workerPid: sendResult.workerPid,
|
|
424
|
+
at: now,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
catch (error) {
|
|
428
|
+
stream.state = 'failed';
|
|
429
|
+
stream.updatedAt = now;
|
|
430
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
431
|
+
this.writeEvent('stream', 'send.deferred.failed_on_connection', {
|
|
432
|
+
streamId: stream.streamId,
|
|
433
|
+
media: stream.media,
|
|
434
|
+
sourceMode: stream.source.mode,
|
|
435
|
+
assetsDir: stream.source.local_assets.assets_dir,
|
|
436
|
+
message,
|
|
437
|
+
at: now,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
activatePendingStreamsOnConnected() {
|
|
443
|
+
const now = new Date().toISOString();
|
|
444
|
+
for (const stream of this.state.streams.values()) {
|
|
445
|
+
if (stream.state !== 'pending_on_connection') {
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
stream.state = 'active';
|
|
449
|
+
stream.updatedAt = now;
|
|
450
|
+
this.writeEvent('stream', 'state.activated_on_connection', {
|
|
451
|
+
streamId: stream.streamId,
|
|
452
|
+
media: stream.media,
|
|
453
|
+
direction: stream.direction,
|
|
454
|
+
at: now,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
async handleConnectionDisconnect() {
|
|
459
|
+
if (this.state.connection.state === 'idle' || this.state.connection.state === 'disconnected') {
|
|
460
|
+
return {
|
|
461
|
+
acceptedAt: new Date().toISOString(),
|
|
462
|
+
service: this.state.service,
|
|
463
|
+
connection: this.state.connection,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
await this.runtimeAdapter.disconnect();
|
|
467
|
+
this.state.connection.state = 'disconnected';
|
|
468
|
+
this.state.connection.disconnectedAt = new Date().toISOString();
|
|
469
|
+
return {
|
|
470
|
+
acceptedAt: new Date().toISOString(),
|
|
471
|
+
service: this.state.service,
|
|
472
|
+
connection: this.state.connection,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
async handleStreamList() {
|
|
476
|
+
return {
|
|
477
|
+
streams: Array.from(this.state.streams.values()),
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
async handleStreamSendStart(params) {
|
|
481
|
+
resolveLocalAssetsDir(params.source);
|
|
482
|
+
const hasActiveService = this.state.service.state !== 'stopped';
|
|
483
|
+
if (hasActiveService) {
|
|
484
|
+
await this.runtimeAdapter.startSendStream(params.streamId, params.media, params.source);
|
|
485
|
+
}
|
|
486
|
+
const stream = {
|
|
487
|
+
streamId: params.streamId,
|
|
488
|
+
media: params.media,
|
|
489
|
+
direction: 'send',
|
|
490
|
+
state: this.state.connection.state === 'connected' ? 'active' : 'pending_on_connection',
|
|
491
|
+
source: params.source,
|
|
492
|
+
updatedAt: new Date().toISOString(),
|
|
493
|
+
};
|
|
494
|
+
this.state.streams.set(params.streamId, stream);
|
|
495
|
+
this.state.streamSourceBindings.set(streamBindingKey(params.streamId, params.media), {
|
|
496
|
+
streamId: params.streamId,
|
|
497
|
+
media: params.media,
|
|
498
|
+
source: params.source,
|
|
499
|
+
updatedAt: new Date().toISOString(),
|
|
500
|
+
});
|
|
501
|
+
return stream;
|
|
502
|
+
}
|
|
503
|
+
async handleStreamSendStop(params) {
|
|
504
|
+
const stream = this.state.streams.get(params.streamId);
|
|
505
|
+
if (!stream || stream.direction !== 'send') {
|
|
506
|
+
throw new HostProtocol_1.HostProtocolError('stream_not_found', `Stream ${params.streamId} not found or not a send stream`, false);
|
|
507
|
+
}
|
|
508
|
+
await this.runtimeAdapter.stopSendStream(params.streamId);
|
|
509
|
+
stream.state = 'stopped';
|
|
510
|
+
stream.updatedAt = new Date().toISOString();
|
|
511
|
+
return stream;
|
|
512
|
+
}
|
|
513
|
+
async handleStreamReceiveStart(params) {
|
|
514
|
+
await this.runtimeAdapter.startReceiveStream(params.streamId, params.media);
|
|
515
|
+
const stream = {
|
|
516
|
+
streamId: params.streamId,
|
|
517
|
+
media: params.media,
|
|
518
|
+
direction: 'receive',
|
|
519
|
+
state: this.state.connection.state === 'connected' ? 'active' : 'pending_on_connection',
|
|
520
|
+
updatedAt: new Date().toISOString(),
|
|
521
|
+
};
|
|
522
|
+
this.state.streams.set(params.streamId, stream);
|
|
523
|
+
return stream;
|
|
524
|
+
}
|
|
525
|
+
async handleStreamReceiveStop(params) {
|
|
526
|
+
const stream = this.state.streams.get(params.streamId);
|
|
527
|
+
if (!stream || stream.direction !== 'receive') {
|
|
528
|
+
throw new HostProtocol_1.HostProtocolError('stream_not_found', `Stream ${params.streamId} not found or not a receive stream`, false);
|
|
529
|
+
}
|
|
530
|
+
await this.runtimeAdapter.stopReceiveStream(params.streamId);
|
|
531
|
+
stream.state = 'stopped';
|
|
532
|
+
stream.updatedAt = new Date().toISOString();
|
|
533
|
+
return stream;
|
|
534
|
+
}
|
|
535
|
+
async handleStreamRequestPolicyGet() {
|
|
536
|
+
return {
|
|
537
|
+
mode: this.state.streamRequestPolicy.mode,
|
|
538
|
+
updatedAt: new Date().toISOString(),
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
async handleStreamRequestPolicySet(params) {
|
|
542
|
+
this.state.streamRequestPolicy.mode = params.mode;
|
|
543
|
+
const updatedAt = new Date().toISOString();
|
|
544
|
+
this.writeEvent('stream', 'request_policy.updated', {
|
|
545
|
+
mode: params.mode,
|
|
546
|
+
at: updatedAt,
|
|
547
|
+
});
|
|
548
|
+
return {
|
|
549
|
+
mode: this.state.streamRequestPolicy.mode,
|
|
550
|
+
updatedAt,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
async handleOutputAttach(params) {
|
|
554
|
+
const attachment = await this.runtimeAdapter.attachOutput(params.streamId, params.consumer, params.mediaView, params.format, params.delivery, params.targetPath, params.maxFiles);
|
|
555
|
+
return {
|
|
556
|
+
outputId: attachment.outputId,
|
|
557
|
+
streamId: params.streamId,
|
|
558
|
+
consumer: params.consumer,
|
|
559
|
+
mediaView: params.mediaView,
|
|
560
|
+
format: params.format,
|
|
561
|
+
delivery: params.delivery,
|
|
562
|
+
target: attachment.targetPath,
|
|
563
|
+
attachedAt: attachment.attachedAt,
|
|
564
|
+
preview: attachment.preview,
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
async handleOutputDetach(params) {
|
|
568
|
+
await this.runtimeAdapter.detachOutput(params.outputId);
|
|
569
|
+
return {
|
|
570
|
+
outputId: params.outputId,
|
|
571
|
+
detachedAt: new Date().toISOString(),
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
async handleCommandSend(params) {
|
|
575
|
+
const response = await this.runtimeAdapter.sendCommand(params.commandId, params.kind, params.payloadEncoding, params.payload, params.replyToSequenceNumber, params.awaitResponse, params.timeoutMs);
|
|
576
|
+
return {
|
|
577
|
+
sequenceNumber: this.commandSequence++,
|
|
578
|
+
commandId: params.commandId,
|
|
579
|
+
kind: params.kind,
|
|
580
|
+
acceptedAt: new Date().toISOString(),
|
|
581
|
+
response,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
async handleEventsSubscribe(params) {
|
|
585
|
+
const families = params.families ?? [];
|
|
586
|
+
for (const family of families) {
|
|
587
|
+
this.state.subscriptions.add(family);
|
|
588
|
+
}
|
|
589
|
+
this.appendHostLog('events subscribed: ' + (families.length > 0 ? families.join(',') : '(none)'));
|
|
590
|
+
return {
|
|
591
|
+
families,
|
|
592
|
+
subscribedAt: new Date().toISOString(),
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
async handleArtifactReadReport() {
|
|
596
|
+
const report = {
|
|
597
|
+
status: 'completed',
|
|
598
|
+
reasonCode: 'success',
|
|
599
|
+
summary: 'Report summary runtime-backed contract',
|
|
600
|
+
service: this.state.service,
|
|
601
|
+
connection: this.state.connection,
|
|
602
|
+
streams: Array.from(this.state.streams.values()),
|
|
603
|
+
streamRequestPolicy: this.state.streamRequestPolicy,
|
|
604
|
+
artifacts: this.artifactManager.getPaths(),
|
|
605
|
+
lastError: this.state.lastError,
|
|
606
|
+
};
|
|
607
|
+
this.artifactManager.writeReport(report);
|
|
608
|
+
return report;
|
|
609
|
+
}
|
|
610
|
+
async handleArtifactExportLogs(params) {
|
|
611
|
+
return {
|
|
612
|
+
outputPath: params.outputPath,
|
|
613
|
+
exportedAt: new Date().toISOString(),
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
async handleArtifactExportReport(params) {
|
|
617
|
+
return {
|
|
618
|
+
outputPath: params.outputPath,
|
|
619
|
+
exportedAt: new Date().toISOString(),
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
async handleDebugTokenQrcode(params) {
|
|
623
|
+
const qr = await this.tokenTool.generateQrcode({
|
|
624
|
+
payload: params.payload,
|
|
625
|
+
outputStem: params.outputStem,
|
|
626
|
+
});
|
|
627
|
+
return {
|
|
628
|
+
payload: qr.payload,
|
|
629
|
+
qrAsciiPath: qr.asciiPath,
|
|
630
|
+
qrPngPath: qr.pngPath,
|
|
631
|
+
generatedAt: new Date().toISOString(),
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
exports.HostServer = HostServer;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface ServiceSnapshot {
|
|
2
|
+
state: 'stopped' | 'starting' | 'waiting_peer' | 'stopping' | 'failed';
|
|
3
|
+
serviceEntry?: string;
|
|
4
|
+
localEndpoint?: string;
|
|
5
|
+
startedAt?: string;
|
|
6
|
+
stoppedAt?: string;
|
|
7
|
+
reasonCode?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ConnectionSnapshot {
|
|
10
|
+
state: 'idle' | 'connecting' | 'accepting' | 'connected' | 'disconnecting' | 'disconnected' | 'failed' | 'missed';
|
|
11
|
+
direction?: 'incoming' | 'outgoing';
|
|
12
|
+
peerId?: string;
|
|
13
|
+
connectedAt?: string;
|
|
14
|
+
disconnectedAt?: string;
|
|
15
|
+
reasonCode?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface StreamSnapshot {
|
|
18
|
+
streamId: number;
|
|
19
|
+
media: 'audio' | 'video';
|
|
20
|
+
direction: 'send' | 'receive';
|
|
21
|
+
state: 'idle' | 'pending_on_connection' | 'starting' | 'active' | 'stopping' | 'stopped' | 'failed';
|
|
22
|
+
source?: StreamSource;
|
|
23
|
+
updatedAt: string;
|
|
24
|
+
}
|
|
25
|
+
export interface StreamLocalAssetsSource {
|
|
26
|
+
mode: 'local_assets';
|
|
27
|
+
local_assets: {
|
|
28
|
+
assets_dir: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export type StreamSource = StreamLocalAssetsSource;
|
|
32
|
+
export type StreamRequestPolicyMode = 'manual' | 'auto-if-bound';
|
|
33
|
+
export interface StreamRequestPolicy {
|
|
34
|
+
mode: StreamRequestPolicyMode;
|
|
35
|
+
}
|
|
36
|
+
export interface StreamSourceBinding {
|
|
37
|
+
streamId: number;
|
|
38
|
+
media: 'audio' | 'video';
|
|
39
|
+
source: StreamSource;
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
}
|
|
42
|
+
export declare class HostState {
|
|
43
|
+
service: ServiceSnapshot;
|
|
44
|
+
connection: ConnectionSnapshot;
|
|
45
|
+
streams: Map<number, StreamSnapshot>;
|
|
46
|
+
subscriptions: Set<string>;
|
|
47
|
+
internalConnections: Set<string>;
|
|
48
|
+
streamRequestPolicy: StreamRequestPolicy;
|
|
49
|
+
streamSourceBindings: Map<string, StreamSourceBinding>;
|
|
50
|
+
protocolVersion: string;
|
|
51
|
+
serverVersion: string;
|
|
52
|
+
runtimeTarget: string;
|
|
53
|
+
hostEndpoint: string;
|
|
54
|
+
startedAt: string;
|
|
55
|
+
lastError?: {
|
|
56
|
+
reasonCode: string;
|
|
57
|
+
message: string;
|
|
58
|
+
retryable: boolean;
|
|
59
|
+
};
|
|
60
|
+
}
|