From 46089e4825836f8693a0968c7e16940789425259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82az=CC=87ej=20Pankowski?= <86720177+pblazej@users.noreply.github.com> Date: Fri, 18 Sep 2026 09:52:21 +0200 Subject: [PATCH 1/7] feat(telemetry): the browser pipeline, run on Hermes The same src/telemetry/index.ts that client-sdk-js runs in Chromium, copied with no edits into a bare RN app: Metro resolves the OTLP encoder and Hermes executes both serializers, which is the whole claim behind "one implementation for web and React Native". Co-Authored-By: Claude Opus 5 (1M context) --- telemetry-poc/.bundle/config | 2 + telemetry-poc/.eslintrc.js | 4 + telemetry-poc/.gitignore | 75 + telemetry-poc/.prettierrc.js | 5 + telemetry-poc/.watchmanconfig | 1 + telemetry-poc/App.tsx | 46 + telemetry-poc/Gemfile | 16 + telemetry-poc/README.md | 45 + telemetry-poc/__tests__/App.test.tsx | 13 + telemetry-poc/android/app/build.gradle | 119 + telemetry-poc/android/app/debug.keystore | Bin 0 -> 2257 bytes telemetry-poc/android/app/proguard-rules.pro | 10 + .../android/app/src/main/AndroidManifest.xml | 27 + .../java/com/telemetrypoc/MainActivity.kt | 22 + .../java/com/telemetrypoc/MainApplication.kt | 27 + .../res/drawable/rn_edit_text_material.xml | 37 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/styles.xml | 9 + telemetry-poc/android/build.gradle | 21 + telemetry-poc/android/gradle.properties | 44 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 45457 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + telemetry-poc/android/gradlew | 251 + telemetry-poc/android/gradlew.bat | 99 + telemetry-poc/android/settings.gradle | 6 + telemetry-poc/app.json | 4 + telemetry-poc/babel.config.js | 3 + telemetry-poc/hermes-check.js | 18 + telemetry-poc/index.js | 9 + telemetry-poc/ios/.xcode.env | 11 + telemetry-poc/ios/Podfile | 46 + telemetry-poc/ios/Podfile.lock | 2726 ++++ .../TelemetryPoC.xcodeproj/project.pbxproj | 478 + .../xcschemes/TelemetryPoC.xcscheme | 88 + .../contents.xcworkspacedata | 10 + .../ios/TelemetryPoC/AppDelegate.swift | 48 + .../AppIcon.appiconset/Contents.json | 53 + .../Images.xcassets/Contents.json | 6 + telemetry-poc/ios/TelemetryPoC/Info.plist | 55 + .../ios/TelemetryPoC/LaunchScreen.storyboard | 47 + .../ios/TelemetryPoC/PrivacyInfo.xcprivacy | 37 + telemetry-poc/jest.config.js | 3 + telemetry-poc/metro.config.js | 11 + telemetry-poc/package-lock.json | 12087 ++++++++++++++++ telemetry-poc/package.json | 42 + telemetry-poc/src/telemetry/index.ts | 127 + telemetry-poc/tsconfig.json | 5 + 57 files changed, 16803 insertions(+) create mode 100644 telemetry-poc/.bundle/config create mode 100644 telemetry-poc/.eslintrc.js create mode 100644 telemetry-poc/.gitignore create mode 100644 telemetry-poc/.prettierrc.js create mode 100644 telemetry-poc/.watchmanconfig create mode 100644 telemetry-poc/App.tsx create mode 100644 telemetry-poc/Gemfile create mode 100644 telemetry-poc/README.md create mode 100644 telemetry-poc/__tests__/App.test.tsx create mode 100644 telemetry-poc/android/app/build.gradle create mode 100644 telemetry-poc/android/app/debug.keystore create mode 100644 telemetry-poc/android/app/proguard-rules.pro create mode 100644 telemetry-poc/android/app/src/main/AndroidManifest.xml create mode 100644 telemetry-poc/android/app/src/main/java/com/telemetrypoc/MainActivity.kt create mode 100644 telemetry-poc/android/app/src/main/java/com/telemetrypoc/MainApplication.kt create mode 100644 telemetry-poc/android/app/src/main/res/drawable/rn_edit_text_material.xml create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 telemetry-poc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 telemetry-poc/android/app/src/main/res/values/strings.xml create mode 100644 telemetry-poc/android/app/src/main/res/values/styles.xml create mode 100644 telemetry-poc/android/build.gradle create mode 100644 telemetry-poc/android/gradle.properties create mode 100644 telemetry-poc/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 telemetry-poc/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 telemetry-poc/android/gradlew create mode 100644 telemetry-poc/android/gradlew.bat create mode 100644 telemetry-poc/android/settings.gradle create mode 100644 telemetry-poc/app.json create mode 100644 telemetry-poc/babel.config.js create mode 100644 telemetry-poc/hermes-check.js create mode 100644 telemetry-poc/index.js create mode 100644 telemetry-poc/ios/.xcode.env create mode 100644 telemetry-poc/ios/Podfile create mode 100644 telemetry-poc/ios/Podfile.lock create mode 100644 telemetry-poc/ios/TelemetryPoC.xcodeproj/project.pbxproj create mode 100644 telemetry-poc/ios/TelemetryPoC.xcodeproj/xcshareddata/xcschemes/TelemetryPoC.xcscheme create mode 100644 telemetry-poc/ios/TelemetryPoC.xcworkspace/contents.xcworkspacedata create mode 100644 telemetry-poc/ios/TelemetryPoC/AppDelegate.swift create mode 100644 telemetry-poc/ios/TelemetryPoC/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 telemetry-poc/ios/TelemetryPoC/Images.xcassets/Contents.json create mode 100644 telemetry-poc/ios/TelemetryPoC/Info.plist create mode 100644 telemetry-poc/ios/TelemetryPoC/LaunchScreen.storyboard create mode 100644 telemetry-poc/ios/TelemetryPoC/PrivacyInfo.xcprivacy create mode 100644 telemetry-poc/jest.config.js create mode 100644 telemetry-poc/metro.config.js create mode 100644 telemetry-poc/package-lock.json create mode 100644 telemetry-poc/package.json create mode 100644 telemetry-poc/src/telemetry/index.ts create mode 100644 telemetry-poc/tsconfig.json diff --git a/telemetry-poc/.bundle/config b/telemetry-poc/.bundle/config new file mode 100644 index 00000000..848943bb --- /dev/null +++ b/telemetry-poc/.bundle/config @@ -0,0 +1,2 @@ +BUNDLE_PATH: "vendor/bundle" +BUNDLE_FORCE_RUBY_PLATFORM: 1 diff --git a/telemetry-poc/.eslintrc.js b/telemetry-poc/.eslintrc.js new file mode 100644 index 00000000..187894b6 --- /dev/null +++ b/telemetry-poc/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: '@react-native', +}; diff --git a/telemetry-poc/.gitignore b/telemetry-poc/.gitignore new file mode 100644 index 00000000..de999559 --- /dev/null +++ b/telemetry-poc/.gitignore @@ -0,0 +1,75 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +**/.xcode.env.local + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml +*.hprof +.cxx/ +*.keystore +!debug.keystore +.kotlin/ + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +**/fastlane/report.xml +**/fastlane/Preview.html +**/fastlane/screenshots +**/fastlane/test_output + +# Bundle artifact +*.jsbundle + +# Ruby / CocoaPods +**/Pods/ +/vendor/bundle/ + +# Temporary files created by Metro to check the health of the file watcher +.metro-health-check* + +# testing +/coverage + +# Yarn +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions diff --git a/telemetry-poc/.prettierrc.js b/telemetry-poc/.prettierrc.js new file mode 100644 index 00000000..06860c8d --- /dev/null +++ b/telemetry-poc/.prettierrc.js @@ -0,0 +1,5 @@ +module.exports = { + arrowParens: 'avoid', + singleQuote: true, + trailingComma: 'all', +}; diff --git a/telemetry-poc/.watchmanconfig b/telemetry-poc/.watchmanconfig new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/telemetry-poc/.watchmanconfig @@ -0,0 +1 @@ +{} diff --git a/telemetry-poc/App.tsx b/telemetry-poc/App.tsx new file mode 100644 index 00000000..3002bcb8 --- /dev/null +++ b/telemetry-poc/App.tsx @@ -0,0 +1,46 @@ +/** + * Telemetry PoC — the same `src/telemetry/index.ts` that `livekit-client` runs in a browser, + * copied verbatim, sending one `lk.ping` from Hermes at the collector on the host + * (`otelcol-contrib --config .../otelcol-web.yaml`, port 4320, fanning out to Grafana LGTM). + * + * The iOS simulator shares the host's network stack, so 127.0.0.1 is the Mac. + */ +import React, {useCallback, useState} from 'react'; +import {Button, SafeAreaView, ScrollView, Text} from 'react-native'; +import {ping} from './src/telemetry'; + +const endpoint = 'http://127.0.0.1:4320/v1/logs'; +const resource = { + 'service.name': 'livekit-client-react-native', + 'service.version': '0.0.0-poc', + 'os.name': 'ios', +}; + +export default function App() { + const [log, setLog] = useState([]); + const say = useCallback((line: string) => setLog(prev => [...prev, line]), []); + + const send = useCallback( + async (encoding: 'protobuf' | 'json') => { + try { + const delivery = await ping({endpoint, resource, encoding}, encoding === 'json' ? 2 : 1); + say(`${encoding}: status ${delivery.status}, ${delivery.bytes} bytes`); + } catch (error) { + say(`${encoding}: ${String(error)}`); + } + }, + [say], + ); + + return ( + +