npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tirtc-electron

v2.4.2

Published

TiRTC Electron SDK for macOS arm64, macOS x64, and Windows x64 preview

Readme

tirtc-electron

tirtc-electron is the Electron main-process SDK for an active TiRTC client and Ti Cloud Storage. Version 2.4.2 contains self-contained native closures for macOS arm64, macOS x64, and Windows x64.

In 2.4.2, Ti Cloud Storage replay progress continues to follow media consumption after the source finishes delivering data. Source completion and output playback completion retain their distinct meanings.

Install and support

Install the stable package or pin the exact version:

npm install --save-exact [email protected]
# or: npm install tirtc-electron

| Tuple | Product status | | --- | --- | | macOS arm64 | native behavior qualification | | macOS x64 | Rosetta x86_64 behavior qualification | | Windows x64 | preview-static-qualified; runtime, GUI, RTC, Ti Cloud Storage, and lifecycle are not-run |

The qualification toolchain is Electron 43.3.0, Electron Builder 26.15.7, TypeScript 5.9.2, and Node-API 9. The npm package never downloads or compiles Runtime during install or load.

Process and credential boundary

Create all SDK objects after app.whenReady() in the main process. The package derives its writable Runtime root from Electron's app.getPath('userData'); call app.setPath('userData', absolutePath) before initialization if the application needs another root.

App ID and short-lived RTC/Ti Cloud Storage Tokens come from the application's server or existing credential flow. Do not generate, persist, or send them to Renderer. Keep contextIsolation and sandbox enabled, keep nodeIntegration disabled, and expose only the application's narrow typed preload methods.

RTC client path

import {
  TiRtc,
  TiRtcAudioInput,
  TiRtcAudioOutput,
  TiRtcConn,
  TiRtcVideoOutput,
  TiVideoView,
} from 'tirtc-electron';

TiRtc.init({appId, endpoint});

const connection = new TiRtcConn();
const microphone = new TiRtcAudioInput();
const audio = new TiRtcAudioOutput();
const video = new TiRtcVideoOutput();
const view = new TiVideoView(browserWindow, {x: 0, y: 0, width: 640, height: 360});

connection.onStateChanged = (state, error) => {
  if (state === 'connected') {
    connection.subscribeAudio(10);
    connection.subscribeVideo(11);
  } else if (state === 'disconnected' && error) {
    console.error(error.code, error.nativeCode);
  }
};

audio.attach(connection, 10);
video.mount(view);
video.attach(connection, 11);
microphone.attach(connection, 12);
microphone.start();
connection.connect({remoteId, token});

JavaScript type, enum, range, and option-combination errors throw TypeError before entering Native. Runtime state, device, network, authorization, resource, and file failures throw or reject TiRtcError; inspect its string code and diagnostic nativeCode. Accepted connection/media commands complete through object state callbacks.

Dispose in reverse ownership order: stop tasks, copy and delete returned temporary files, stop and detach the microphone, detach/unmount/dispose outputs, dispose the view, disconnect/dispose the connection, then TiRtc.shutdown().

Ti Cloud Storage path

import {
  TiCloudStorage,
  TiCloudStorageAudioOutput,
  TiCloudStorageVideoOutput,
  TiVideoView,
} from 'tirtc-electron';

TiCloudStorage.init({appId, endpoint});
const storage = new TiCloudStorage(token);
const recordings = await storage.listRecordings({startTimeMs, endTimeMs});

const replay = storage.createReplay();
const audio = new TiCloudStorageAudioOutput();
const video = new TiCloudStorageVideoOutput();
const view = new TiVideoView(browserWindow, bounds);
audio.attach(replay, audioChannelId);
video.mount(view);
video.attach(replay, videoChannelId);
replay.play({startTimeMs: recordings[0].startTimeMs, endTimeMs: recordings[0].endTimeMs});

Replay supports pause, resume, seek, numeric speeds 0.125..8, snapshots, play-time recording, and direct range export. If an operation reports token-expired, obtain a new Token, call storage.updateToken(newToken), and explicitly retry the operation.

Teardown in reverse order: stop recording/export work, copy and delete returned temporary files, stop replay, detach/unmount/dispose outputs, dispose the view and replay, dispose storage, then TiCloudStorage.shutdown().

Temporary media

Recording, snapshot, and export results are private Runtime-cache files. Copy them to an application-owned absolute path, then call the file object's idempotent delete(). The canonical desktop Example writes a unique name directly to Downloads and never overwrites an existing file.

import {constants, copyFile} from 'node:fs/promises';

const task = connection.startRecording({videoStreamId: 11, audioStreamId: 10});
const media = await task.stop();
await copyFile(media.path, destinationPath, constants.COPYFILE_EXCL);
await media.delete();

If the copy fails, retain the cache source so the user can retry.

Logging without product initialization

import {TiRtcLogging} from 'tirtc-electron';

const logId = await TiRtcLogging.upload();

Log upload is process-wide single-flight and can establish a temporary logging-only Runtime lease. It does not enable product constructors or connections. The resolved log ID is non-empty; a concurrent upload rejects with TiRtcError code in-use.

Electron Builder

The canonical Example is the packaging reference. Set one target tuple and build a directory:

cd electron/tirtc_electron/example
npm ci
TIRTC_ELECTRON_TARGET_TUPLE=darwin-arm64 npm run package:dir -- --mac --arm64

Use darwin-x64 with --mac --x64 or win32-x64 with --win --x64. The Builder hook removes the two unused native tuples after ASAR creation, keeps the selected .node plus its Runtime/Nano libraries in app.asar.unpacked, and leaves no duplicate native closure in app.asar. The application owns signing, notarization, entitlements, microphone permission text, and distribution.

Canonical Example and public Sample

example/ is the canonical source. It follows the Flutter desktop Example's visible pages, copy, state, and interaction, including disabled scan controls, system Audio Input only, and direct Downloads saves. Its main process owns SDK resources and credentials; Renderer only receives serializable state/actions.

After publication the exact-version projection is available at [email protected]:tangeai/tirtc-api-samples.git under electron/. It installs only the published npm package and retains the same Builder configuration.

Local owner validation

Build all three payloads, select one candidate, then validate a clean consumer:

electron/tirtc_electron/script/electron_verify.sh --mode build-payload \
  --tuple darwin-arm64 --runtime-root <macos-arm64-runtime-root> --output-root .build/electron-sdk
electron/tirtc_electron/script/electron_verify.sh --mode build-payload \
  --tuple darwin-x64 --runtime-root <macos-x64-runtime-root> --output-root .build/electron-sdk
electron/tirtc_electron/script/electron_verify.sh --mode build-payload \
  --tuple win32-x64 --runtime-root <windows-x64-runtime-root> --output-root .build/electron-sdk

node electron/tirtc_electron/script/package_candidate.mjs \
  --darwin-arm64-payload .build/electron-sdk/payload/darwin-arm64 \
  --darwin-x64-payload .build/electron-sdk/payload/darwin-x64 \
  --windows-x64-payload .build/electron-sdk/payload/win32-x64 \
  --source-commit <40-hex-source-commit> \
  --output .build/electron-sdk/candidate

electron/tirtc_electron/script/electron_verify.sh --mode candidate-contract \
  --candidate .build/electron-sdk/candidate/tirtc-electron-2.4.2.tgz \
  --output-root .build/electron-sdk

The electron-test owner runs macOS arm64 and macOS x64 behavior lanes separately. Windows cross-build/package checks produce only preview-static-qualified evidence.

See the exact public declarations, RTC reference, Ti Cloud Storage reference, and breaking migration.