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,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HostState = void 0;
|
|
4
|
+
class HostState {
|
|
5
|
+
service = { state: 'stopped' };
|
|
6
|
+
connection = { state: 'idle' };
|
|
7
|
+
streams = new Map();
|
|
8
|
+
subscriptions = new Set();
|
|
9
|
+
internalConnections = new Set();
|
|
10
|
+
streamRequestPolicy = { mode: 'manual' };
|
|
11
|
+
streamSourceBindings = new Map();
|
|
12
|
+
protocolVersion = '1.0.0';
|
|
13
|
+
serverVersion = '1.0.0';
|
|
14
|
+
runtimeTarget = 'runtime-backed/unknown';
|
|
15
|
+
hostEndpoint = 'stdio://runtime-backed';
|
|
16
|
+
startedAt = new Date().toISOString();
|
|
17
|
+
lastError;
|
|
18
|
+
}
|
|
19
|
+
exports.HostState = HostState;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { PreviewRegistration } from './WebPreviewGateway';
|
|
2
|
+
import { StreamSource } from './HostState';
|
|
3
|
+
export type RuntimeEventPayload = Record<string, unknown>;
|
|
4
|
+
export interface RuntimeCommandResponse {
|
|
5
|
+
sequenceNumber: number;
|
|
6
|
+
payloadEncoding: string;
|
|
7
|
+
payload: string;
|
|
8
|
+
}
|
|
9
|
+
export interface RuntimeSendStartResult {
|
|
10
|
+
autoStarted: boolean;
|
|
11
|
+
workerPid?: number;
|
|
12
|
+
}
|
|
13
|
+
export type OutputAttachResult = {
|
|
14
|
+
outputId: string;
|
|
15
|
+
targetPath: string;
|
|
16
|
+
attachedAt: string;
|
|
17
|
+
preview?: PreviewRegistration;
|
|
18
|
+
};
|
|
19
|
+
export interface RuntimeAdapter {
|
|
20
|
+
readonly runtimeTarget: string;
|
|
21
|
+
readonly hostEndpoint: string;
|
|
22
|
+
readonly runtimeBundleRoot: string;
|
|
23
|
+
readonly repoRoot: string;
|
|
24
|
+
readonly platform: string;
|
|
25
|
+
setEventHandler(handler: (family: string, kind: string, payload: RuntimeEventPayload) => void): void;
|
|
26
|
+
startService(serviceEntry: string | undefined, license: string, timeoutMs: number): Promise<string>;
|
|
27
|
+
stopService(): Promise<void>;
|
|
28
|
+
connect(serviceEntry: string | undefined, peerId: string, token: string, timeoutMs: number): Promise<string>;
|
|
29
|
+
disconnect(): Promise<void>;
|
|
30
|
+
startSendStream(streamId: number, media: string, source: StreamSource): Promise<RuntimeSendStartResult>;
|
|
31
|
+
stopSendStream(streamId: number): Promise<void>;
|
|
32
|
+
startReceiveStream(streamId: number, media: string): Promise<void>;
|
|
33
|
+
stopReceiveStream(streamId: number): Promise<void>;
|
|
34
|
+
attachOutput(streamId: number, consumer: string, mediaView: string, format: string, delivery: string, targetPath?: string, maxFiles?: number): Promise<OutputAttachResult>;
|
|
35
|
+
detachOutput(outputId: string): Promise<void>;
|
|
36
|
+
sendCommand(commandId: number, kind: string, payloadEncoding: string, payload: string, replyToSequenceNumber?: number, awaitResponse?: boolean, timeoutMs?: number): Promise<RuntimeCommandResponse | undefined>;
|
|
37
|
+
}
|
|
38
|
+
type RuntimeBackedAdapterOptions = {
|
|
39
|
+
runtimeBundleRoot: string;
|
|
40
|
+
platform: string;
|
|
41
|
+
};
|
|
42
|
+
export declare class RuntimeBackedAdapter implements RuntimeAdapter {
|
|
43
|
+
readonly runtimeTarget: string;
|
|
44
|
+
readonly hostEndpoint = "stdio://runtime-backed";
|
|
45
|
+
readonly runtimeBundleRoot: string;
|
|
46
|
+
readonly repoRoot: string;
|
|
47
|
+
readonly platform: string;
|
|
48
|
+
private readonly sendWorker;
|
|
49
|
+
private readonly receiveWorker;
|
|
50
|
+
private eventHandler?;
|
|
51
|
+
private outputCounter;
|
|
52
|
+
private commandSequence;
|
|
53
|
+
private connected;
|
|
54
|
+
private defaultServiceEntry?;
|
|
55
|
+
private activeService?;
|
|
56
|
+
private connectionContext?;
|
|
57
|
+
private readonly outputs;
|
|
58
|
+
private readonly receiveStreams;
|
|
59
|
+
private readonly previewGateway;
|
|
60
|
+
private receiveRefreshTimer?;
|
|
61
|
+
constructor(options: RuntimeBackedAdapterOptions);
|
|
62
|
+
setEventHandler(handler: (family: string, kind: string, payload: RuntimeEventPayload) => void): void;
|
|
63
|
+
private emit;
|
|
64
|
+
private recordOutputEvent;
|
|
65
|
+
private assertRuntimeBundleReady;
|
|
66
|
+
private resolveServiceEntry;
|
|
67
|
+
private scheduleReceiveRefresh;
|
|
68
|
+
private refreshReceiveWorker;
|
|
69
|
+
startService(serviceEntry: string | undefined, license: string, timeoutMs: number): Promise<string>;
|
|
70
|
+
stopService(): Promise<void>;
|
|
71
|
+
connect(serviceEntry: string | undefined, peerId: string, token: string, timeoutMs: number): Promise<string>;
|
|
72
|
+
disconnect(): Promise<void>;
|
|
73
|
+
startSendStream(streamId: number, media: string, source: StreamSource): Promise<RuntimeSendStartResult>;
|
|
74
|
+
stopSendStream(streamId: number): Promise<void>;
|
|
75
|
+
startReceiveStream(streamId: number, media: string): Promise<void>;
|
|
76
|
+
stopReceiveStream(streamId: number): Promise<void>;
|
|
77
|
+
attachOutput(streamId: number, consumer: string, mediaView: string, format: string, delivery: string, targetPath?: string, maxFiles?: number): Promise<OutputAttachResult>;
|
|
78
|
+
detachOutput(outputId: string): Promise<void>;
|
|
79
|
+
sendCommand(commandId: number, kind: string, payloadEncoding: string, payload: string, replyToSequenceNumber?: number, awaitResponse?: boolean, timeoutMs?: number): Promise<RuntimeCommandResponse | undefined>;
|
|
80
|
+
}
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,559 @@
|
|
|
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, 'app-server/bin/runtime')) ||
|
|
82
|
+
pathExists(path.join(normalized, '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-devtool', '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
|
+
class RuntimeBackedAdapter {
|
|
137
|
+
runtimeTarget;
|
|
138
|
+
hostEndpoint = 'stdio://runtime-backed';
|
|
139
|
+
runtimeBundleRoot;
|
|
140
|
+
repoRoot;
|
|
141
|
+
platform;
|
|
142
|
+
sendWorker;
|
|
143
|
+
receiveWorker;
|
|
144
|
+
eventHandler;
|
|
145
|
+
outputCounter = 1;
|
|
146
|
+
commandSequence = 1;
|
|
147
|
+
connected = false;
|
|
148
|
+
defaultServiceEntry;
|
|
149
|
+
activeService;
|
|
150
|
+
connectionContext;
|
|
151
|
+
outputs = new Map();
|
|
152
|
+
receiveStreams = new Map();
|
|
153
|
+
previewGateway = new WebPreviewGateway_1.WebPreviewGateway();
|
|
154
|
+
receiveRefreshTimer;
|
|
155
|
+
constructor(options) {
|
|
156
|
+
this.runtimeBundleRoot = options.runtimeBundleRoot;
|
|
157
|
+
this.platform = options.platform;
|
|
158
|
+
this.runtimeTarget = 'runtime-backed/' + options.platform;
|
|
159
|
+
this.repoRoot = resolveRepoRoot();
|
|
160
|
+
this.sendWorker = new RuntimeSendWorker_1.RuntimeSendWorkerManager({
|
|
161
|
+
repoRoot: this.repoRoot,
|
|
162
|
+
platform: this.platform,
|
|
163
|
+
onLogLine: (payload) => {
|
|
164
|
+
this.emit('logs', 'runtime.line', payload);
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
this.receiveWorker = new RuntimeReceiveWorker_1.RuntimeReceiveWorkerManager({
|
|
168
|
+
repoRoot: this.repoRoot,
|
|
169
|
+
platform: this.platform,
|
|
170
|
+
onLogLine: (payload) => {
|
|
171
|
+
this.emit('logs', 'runtime.line', payload);
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
setEventHandler(handler) {
|
|
176
|
+
this.eventHandler = handler;
|
|
177
|
+
}
|
|
178
|
+
emit(family, kind, payload) {
|
|
179
|
+
this.recordOutputEvent(family, kind, payload);
|
|
180
|
+
if (!this.eventHandler) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this.eventHandler(family, kind, payload);
|
|
184
|
+
}
|
|
185
|
+
recordOutputEvent(family, kind, payload) {
|
|
186
|
+
if (this.outputs.size === 0) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const payloadStreamId = tryGetNumber(payload.streamId);
|
|
190
|
+
const timestamp = nowIsoString();
|
|
191
|
+
for (const output of this.outputs.values()) {
|
|
192
|
+
if (output.receiveBoundEver) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (payloadStreamId !== undefined && payloadStreamId !== output.streamId) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const line = JSON.stringify({
|
|
199
|
+
at: timestamp,
|
|
200
|
+
family,
|
|
201
|
+
kind,
|
|
202
|
+
streamId: output.streamId,
|
|
203
|
+
payload,
|
|
204
|
+
}) + '\n';
|
|
205
|
+
try {
|
|
206
|
+
fs.appendFileSync(output.targetPath, line, 'utf8');
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// no-op
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
assertRuntimeBundleReady() {
|
|
214
|
+
const includePath = path.join(this.runtimeBundleRoot, 'include');
|
|
215
|
+
const libPath = path.join(this.runtimeBundleRoot, 'lib');
|
|
216
|
+
const manifestPath = path.join(this.runtimeBundleRoot, 'manifest.txt');
|
|
217
|
+
if (!pathExists(includePath) || !pathExists(libPath) || !pathExists(manifestPath)) {
|
|
218
|
+
throw new Error('runtime bundle is not ready at ' + this.runtimeBundleRoot);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
resolveServiceEntry(serviceEntry) {
|
|
222
|
+
if (serviceEntry && serviceEntry.trim().length > 0) {
|
|
223
|
+
return serviceEntry;
|
|
224
|
+
}
|
|
225
|
+
if (!this.defaultServiceEntry) {
|
|
226
|
+
this.defaultServiceEntry = resolveDefaultServiceEntry();
|
|
227
|
+
}
|
|
228
|
+
return this.defaultServiceEntry ?? '';
|
|
229
|
+
}
|
|
230
|
+
scheduleReceiveRefresh() {
|
|
231
|
+
if (this.receiveRefreshTimer) {
|
|
232
|
+
clearTimeout(this.receiveRefreshTimer);
|
|
233
|
+
}
|
|
234
|
+
this.receiveRefreshTimer = setTimeout(() => {
|
|
235
|
+
this.receiveRefreshTimer = undefined;
|
|
236
|
+
void this.refreshReceiveWorker();
|
|
237
|
+
}, 80);
|
|
238
|
+
}
|
|
239
|
+
async refreshReceiveWorker() {
|
|
240
|
+
if (!this.connected || !this.connectionContext) {
|
|
241
|
+
await this.receiveWorker.stopAll();
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const bindings = [];
|
|
245
|
+
for (const attachment of this.outputs.values()) {
|
|
246
|
+
if (!attachment.media) {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
bindings.push({
|
|
250
|
+
key: attachment.outputId + "/" + String(attachment.streamId) + "/" + attachment.media,
|
|
251
|
+
serviceEntry: this.connectionContext.serviceEntry,
|
|
252
|
+
peerId: this.connectionContext.peerId,
|
|
253
|
+
token: this.connectionContext.token,
|
|
254
|
+
streamId: attachment.streamId,
|
|
255
|
+
media: attachment.media,
|
|
256
|
+
targetPath: attachment.targetPath,
|
|
257
|
+
framed: attachment.consumer === 'web_preview',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
await this.receiveWorker.syncBindings(bindings);
|
|
261
|
+
}
|
|
262
|
+
async startService(serviceEntry, license, timeoutMs) {
|
|
263
|
+
this.assertRuntimeBundleReady();
|
|
264
|
+
const resolvedServiceEntry = this.resolveServiceEntry(serviceEntry);
|
|
265
|
+
const senderBootstrap = await this.sendWorker.ensureServiceSession(resolvedServiceEntry, license);
|
|
266
|
+
this.activeService = {
|
|
267
|
+
serviceEntry: resolvedServiceEntry,
|
|
268
|
+
license,
|
|
269
|
+
startedAt: nowIsoString(),
|
|
270
|
+
};
|
|
271
|
+
this.emit('service', 'start.requested', {
|
|
272
|
+
serviceEntry: resolvedServiceEntry,
|
|
273
|
+
licensePresent: license.length > 0,
|
|
274
|
+
timeoutMs,
|
|
275
|
+
senderBootstrapStarted: senderBootstrap.started,
|
|
276
|
+
senderWorkerPid: senderBootstrap.pid,
|
|
277
|
+
at: nowIsoString(),
|
|
278
|
+
});
|
|
279
|
+
return resolvedServiceEntry;
|
|
280
|
+
}
|
|
281
|
+
async stopService() {
|
|
282
|
+
this.activeService = undefined;
|
|
283
|
+
await this.sendWorker.stopAll();
|
|
284
|
+
await this.receiveWorker.stopAll();
|
|
285
|
+
if (this.receiveRefreshTimer) {
|
|
286
|
+
clearTimeout(this.receiveRefreshTimer);
|
|
287
|
+
this.receiveRefreshTimer = undefined;
|
|
288
|
+
}
|
|
289
|
+
this.previewGateway.dispose();
|
|
290
|
+
this.emit('service', 'stop.requested', { at: nowIsoString() });
|
|
291
|
+
}
|
|
292
|
+
async connect(serviceEntry, peerId, token, timeoutMs) {
|
|
293
|
+
this.assertRuntimeBundleReady();
|
|
294
|
+
const resolvedServiceEntry = this.resolveServiceEntry(serviceEntry);
|
|
295
|
+
this.emit('connection', 'connect.requested', {
|
|
296
|
+
serviceEntry: resolvedServiceEntry,
|
|
297
|
+
peerId,
|
|
298
|
+
tokenPresent: token.length > 0,
|
|
299
|
+
timeoutMs,
|
|
300
|
+
at: nowIsoString(),
|
|
301
|
+
});
|
|
302
|
+
this.connected = true;
|
|
303
|
+
this.connectionContext = {
|
|
304
|
+
serviceEntry: resolvedServiceEntry,
|
|
305
|
+
peerId,
|
|
306
|
+
token,
|
|
307
|
+
};
|
|
308
|
+
this.emit('connection', 'connect.validated', {
|
|
309
|
+
serviceEntry: resolvedServiceEntry,
|
|
310
|
+
peerId,
|
|
311
|
+
at: nowIsoString(),
|
|
312
|
+
});
|
|
313
|
+
const activeService = this.activeService;
|
|
314
|
+
if (activeService) {
|
|
315
|
+
this.emit('stream', 'send.auto.resume.requested', {
|
|
316
|
+
serviceEntry: activeService.serviceEntry,
|
|
317
|
+
startedAt: activeService.startedAt,
|
|
318
|
+
at: nowIsoString(),
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
await this.refreshReceiveWorker();
|
|
322
|
+
return resolvedServiceEntry;
|
|
323
|
+
}
|
|
324
|
+
async disconnect() {
|
|
325
|
+
this.connected = false;
|
|
326
|
+
this.connectionContext = undefined;
|
|
327
|
+
this.receiveStreams.clear();
|
|
328
|
+
await this.sendWorker.stopAll();
|
|
329
|
+
await this.receiveWorker.stopAll();
|
|
330
|
+
if (this.receiveRefreshTimer) {
|
|
331
|
+
clearTimeout(this.receiveRefreshTimer);
|
|
332
|
+
this.receiveRefreshTimer = undefined;
|
|
333
|
+
}
|
|
334
|
+
this.previewGateway.dispose();
|
|
335
|
+
this.emit('connection', 'disconnect.requested', { at: nowIsoString() });
|
|
336
|
+
}
|
|
337
|
+
async startSendStream(streamId, media, source) {
|
|
338
|
+
const assetsDir = resolveStreamAssetsDir(source);
|
|
339
|
+
const activeService = this.activeService;
|
|
340
|
+
let autoStarted = false;
|
|
341
|
+
let workerPid;
|
|
342
|
+
if (activeService) {
|
|
343
|
+
const key = String(streamId) + '/' + media;
|
|
344
|
+
const startResult = await this.sendWorker.startDeviceStream({
|
|
345
|
+
key,
|
|
346
|
+
serviceEntry: activeService.serviceEntry,
|
|
347
|
+
license: activeService.license,
|
|
348
|
+
assetsDir,
|
|
349
|
+
streamId,
|
|
350
|
+
media: media === 'audio' ? 'audio' : 'video',
|
|
351
|
+
});
|
|
352
|
+
autoStarted = startResult.started;
|
|
353
|
+
workerPid = startResult.pid;
|
|
354
|
+
}
|
|
355
|
+
this.emit('stream', 'send.start.requested', {
|
|
356
|
+
streamId,
|
|
357
|
+
media,
|
|
358
|
+
sourceMode: source.mode,
|
|
359
|
+
assetsDir,
|
|
360
|
+
connected: this.connected,
|
|
361
|
+
workerPid,
|
|
362
|
+
autoStarted,
|
|
363
|
+
deferred: !activeService,
|
|
364
|
+
at: nowIsoString(),
|
|
365
|
+
});
|
|
366
|
+
return { autoStarted, workerPid };
|
|
367
|
+
}
|
|
368
|
+
async stopSendStream(streamId) {
|
|
369
|
+
const keys = [String(streamId) + '/audio', String(streamId) + '/video'];
|
|
370
|
+
for (const key of keys) {
|
|
371
|
+
await this.sendWorker.stopStream(key);
|
|
372
|
+
}
|
|
373
|
+
this.emit('stream', 'send.stop.requested', { streamId, at: nowIsoString() });
|
|
374
|
+
}
|
|
375
|
+
async startReceiveStream(streamId, media) {
|
|
376
|
+
if (!this.connected) {
|
|
377
|
+
throw new Error('connection is not established');
|
|
378
|
+
}
|
|
379
|
+
const normalized = normalizeMedia(media);
|
|
380
|
+
if (!normalized) {
|
|
381
|
+
throw new Error('unsupported receive media: ' + media);
|
|
382
|
+
}
|
|
383
|
+
this.receiveStreams.set(streamId, normalized);
|
|
384
|
+
this.emit('stream', 'receive.start.requested', { streamId, media, at: nowIsoString() });
|
|
385
|
+
await this.refreshReceiveWorker();
|
|
386
|
+
}
|
|
387
|
+
async stopReceiveStream(streamId) {
|
|
388
|
+
this.receiveStreams.delete(streamId);
|
|
389
|
+
this.emit('stream', 'receive.stop.requested', { streamId, at: nowIsoString() });
|
|
390
|
+
await this.refreshReceiveWorker();
|
|
391
|
+
}
|
|
392
|
+
async attachOutput(streamId, consumer, mediaView, format, delivery, targetPath, maxFiles) {
|
|
393
|
+
if (!this.connected) {
|
|
394
|
+
throw new Error('connection is not established');
|
|
395
|
+
}
|
|
396
|
+
const outputId = 'rt-out-' + streamId + '-' + this.outputCounter;
|
|
397
|
+
this.outputCounter += 1;
|
|
398
|
+
const safeFormat = (format || 'bin').replace(/[^a-zA-Z0-9]/g, '').toLowerCase() || 'bin';
|
|
399
|
+
const resolvedTargetPath = targetPath && targetPath.trim().length > 0
|
|
400
|
+
? path.resolve(targetPath)
|
|
401
|
+
: path.join(resolveOutputRoot(), `${outputId}.${safeFormat}`);
|
|
402
|
+
ensureDir(path.dirname(resolvedTargetPath));
|
|
403
|
+
let receiveMedia = this.receiveStreams.get(streamId);
|
|
404
|
+
if (!receiveMedia && consumer === 'web_preview') {
|
|
405
|
+
if (format.toLowerCase() === 'g711a' || format.toLowerCase() === 'alaw' || format.toLowerCase() === 'pcm') {
|
|
406
|
+
receiveMedia = 'audio';
|
|
407
|
+
}
|
|
408
|
+
else if (format.toLowerCase() === 'h264' || format.toLowerCase() === 'jpeg' || format.toLowerCase() === 'mjpeg') {
|
|
409
|
+
receiveMedia = 'video';
|
|
410
|
+
}
|
|
411
|
+
if (receiveMedia) {
|
|
412
|
+
this.receiveStreams.set(streamId, receiveMedia);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (receiveMedia) {
|
|
416
|
+
for (const existing of this.outputs.values()) {
|
|
417
|
+
if (existing.streamId === streamId && existing.media === receiveMedia) {
|
|
418
|
+
throw new Error(`output already attached for stream=${streamId} media=${receiveMedia}; detach existing output first`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
fs.writeFileSync(resolvedTargetPath, Buffer.alloc(0));
|
|
423
|
+
const attachedAt = nowIsoString();
|
|
424
|
+
let preview;
|
|
425
|
+
if (consumer === 'web_preview') {
|
|
426
|
+
if (!receiveMedia) {
|
|
427
|
+
throw new Error(`web_preview requires active receive stream binding for stream=${streamId}`);
|
|
428
|
+
}
|
|
429
|
+
preview = await this.previewGateway.registerSource(outputId, receiveMedia, streamId, resolvedTargetPath, async () => {
|
|
430
|
+
if (!this.connected) {
|
|
431
|
+
throw new Error('connection is not established');
|
|
432
|
+
}
|
|
433
|
+
this.scheduleReceiveRefresh();
|
|
434
|
+
this.emit('stream', 'preview.start.requested', {
|
|
435
|
+
streamId,
|
|
436
|
+
media: receiveMedia,
|
|
437
|
+
outputId,
|
|
438
|
+
at: nowIsoString(),
|
|
439
|
+
});
|
|
440
|
+
}, async () => {
|
|
441
|
+
if (!this.connected) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
this.scheduleReceiveRefresh();
|
|
445
|
+
this.emit('stream', 'preview.stop.requested', {
|
|
446
|
+
streamId,
|
|
447
|
+
media: receiveMedia,
|
|
448
|
+
outputId,
|
|
449
|
+
at: nowIsoString(),
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
const attachment = {
|
|
454
|
+
outputId,
|
|
455
|
+
streamId,
|
|
456
|
+
media: receiveMedia,
|
|
457
|
+
consumer,
|
|
458
|
+
mediaView,
|
|
459
|
+
format,
|
|
460
|
+
delivery,
|
|
461
|
+
targetPath: resolvedTargetPath,
|
|
462
|
+
attachedAt,
|
|
463
|
+
receiveBoundEver: Boolean(receiveMedia),
|
|
464
|
+
preview,
|
|
465
|
+
};
|
|
466
|
+
this.outputs.set(outputId, attachment);
|
|
467
|
+
if (!receiveMedia) {
|
|
468
|
+
const bootstrapLine = JSON.stringify({
|
|
469
|
+
at: attachedAt,
|
|
470
|
+
family: 'stream',
|
|
471
|
+
kind: 'output.attach',
|
|
472
|
+
streamId,
|
|
473
|
+
outputId,
|
|
474
|
+
consumer,
|
|
475
|
+
mediaView,
|
|
476
|
+
format,
|
|
477
|
+
delivery,
|
|
478
|
+
maxFiles,
|
|
479
|
+
}) + '\n';
|
|
480
|
+
fs.appendFileSync(resolvedTargetPath, bootstrapLine, 'utf8');
|
|
481
|
+
}
|
|
482
|
+
if (receiveMedia && consumer !== 'web_preview') {
|
|
483
|
+
this.scheduleReceiveRefresh();
|
|
484
|
+
}
|
|
485
|
+
this.emit('stream', 'output.attach.requested', {
|
|
486
|
+
outputId,
|
|
487
|
+
streamId,
|
|
488
|
+
consumer,
|
|
489
|
+
mediaView,
|
|
490
|
+
format,
|
|
491
|
+
delivery,
|
|
492
|
+
targetPath: resolvedTargetPath,
|
|
493
|
+
maxFiles,
|
|
494
|
+
at: attachedAt,
|
|
495
|
+
runtimeDownlink: Boolean(receiveMedia),
|
|
496
|
+
preview,
|
|
497
|
+
});
|
|
498
|
+
return {
|
|
499
|
+
outputId,
|
|
500
|
+
targetPath: resolvedTargetPath,
|
|
501
|
+
attachedAt,
|
|
502
|
+
preview,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
async detachOutput(outputId) {
|
|
506
|
+
const attachment = this.outputs.get(outputId);
|
|
507
|
+
if (attachment) {
|
|
508
|
+
if (attachment.consumer === 'web_preview') {
|
|
509
|
+
this.previewGateway.unregisterSource(outputId);
|
|
510
|
+
}
|
|
511
|
+
if (!attachment.receiveBoundEver) {
|
|
512
|
+
const line = JSON.stringify({
|
|
513
|
+
at: nowIsoString(),
|
|
514
|
+
family: 'stream',
|
|
515
|
+
kind: 'output.detach',
|
|
516
|
+
streamId: attachment.streamId,
|
|
517
|
+
outputId,
|
|
518
|
+
}) + '\n';
|
|
519
|
+
try {
|
|
520
|
+
fs.appendFileSync(attachment.targetPath, line, 'utf8');
|
|
521
|
+
}
|
|
522
|
+
catch {
|
|
523
|
+
// no-op
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
this.outputs.delete(outputId);
|
|
527
|
+
}
|
|
528
|
+
await this.refreshReceiveWorker();
|
|
529
|
+
this.emit('stream', 'output.detach.requested', { outputId, at: nowIsoString() });
|
|
530
|
+
}
|
|
531
|
+
async sendCommand(commandId, kind, payloadEncoding, payload, replyToSequenceNumber, awaitResponse, timeoutMs) {
|
|
532
|
+
if (!this.connected) {
|
|
533
|
+
throw new Error('connection is not established');
|
|
534
|
+
}
|
|
535
|
+
this.emit('command', 'send.requested', {
|
|
536
|
+
commandId,
|
|
537
|
+
kind,
|
|
538
|
+
payloadEncoding,
|
|
539
|
+
replyToSequenceNumber,
|
|
540
|
+
awaitResponse: Boolean(awaitResponse),
|
|
541
|
+
timeoutMs,
|
|
542
|
+
at: nowIsoString(),
|
|
543
|
+
});
|
|
544
|
+
if (!awaitResponse) {
|
|
545
|
+
return undefined;
|
|
546
|
+
}
|
|
547
|
+
const sequenceNumber = this.commandSequence;
|
|
548
|
+
this.commandSequence += 1;
|
|
549
|
+
return {
|
|
550
|
+
sequenceNumber,
|
|
551
|
+
payloadEncoding: 'runtime-evidence',
|
|
552
|
+
payload: JSON.stringify({
|
|
553
|
+
evidence: 'runtime-backed-callbacks',
|
|
554
|
+
commandRxCount: 1,
|
|
555
|
+
}),
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
exports.RuntimeBackedAdapter = RuntimeBackedAdapter;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type AutoTokenIssueOptions = {
|
|
2
|
+
openapiEntry?: string;
|
|
3
|
+
accessId: string;
|
|
4
|
+
secretKey: string;
|
|
5
|
+
localId: string;
|
|
6
|
+
peerId: string;
|
|
7
|
+
userTtlSeconds?: number;
|
|
8
|
+
channelTtlSeconds?: number;
|
|
9
|
+
};
|
|
10
|
+
type RuntimeCredentialTokenIssuerOptions = {
|
|
11
|
+
repoRoot: string;
|
|
12
|
+
platform: string;
|
|
13
|
+
runtimeBundleRoot: string;
|
|
14
|
+
};
|
|
15
|
+
export declare class RuntimeCredentialTokenIssuer {
|
|
16
|
+
private readonly repoRoot;
|
|
17
|
+
private readonly platform;
|
|
18
|
+
private readonly runtimeBundleRoot;
|
|
19
|
+
private binding?;
|
|
20
|
+
constructor(options: RuntimeCredentialTokenIssuerOptions);
|
|
21
|
+
private resolveSourcePath;
|
|
22
|
+
private resolveBuildOutputPath;
|
|
23
|
+
private resolveRuntimeLibDir;
|
|
24
|
+
private resolveRuntimeIncludeDir;
|
|
25
|
+
private resolveNodeHeadersDir;
|
|
26
|
+
private ensureCredentialAddon;
|
|
27
|
+
private ensureBinding;
|
|
28
|
+
issueToken(options: AutoTokenIssueOptions): Promise<string>;
|
|
29
|
+
}
|
|
30
|
+
export {};
|