Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions packages/mobile-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
"license": "Apache-2.0",
"author": "Fishjam Team",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"react-native": "src/index.ts",
"react-native": "dist/index.js",
"files": [
"dist/**",
"plugin/build/**",
Expand All @@ -25,29 +24,23 @@
"webrtc",
"fishjam"
],
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./app.plugin": "./app.plugin.js",
"./app.plugin.js": "./app.plugin.js",
"./package.json": "./package.json"
},
"scripts": {
"build": "tsc && EXPO_NONINTERACTIVE=1 expo-module build plugin",
"lint": "eslint . --ext .ts,.tsx --fix",
"prepare": "tsc && EXPO_NONINTERACTIVE=1 expo-module build plugin"
},
"peerDependencies": {
"@fishjam-cloud/react-native-webrtc": "0.25.0",
"expo": "*",
"react": "*",
"react-native": "*"
"react-native": "*",
"react-native-get-random-values": "1.11.0"
},
Comment on lines 32 to 38
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fishjam-cloud/react-native-webrtc and react-native-get-random-values are listed in both dependencies and peerDependencies. A dependency does not satisfy a peer dependency, so consumers may still see unmet-peer warnings and can end up with duplicate installs. Consider choosing one model (peer-only for host-provided native deps, or dependency-only for auto-install), and if keeping them as peers, remove them from dependencies and/or mark them optional via peerDependenciesMeta.

Copilot uses AI. Check for mistakes.
"dependencies": {
"@fishjam-cloud/react-client": "workspace:*",
"@fishjam-cloud/react-native-webrtc": "0.25.0",
"react-native-get-random-values": "^1.11.0"
"fast-text-encoding": "^1.0.6",
"react-native-get-random-values": "1.11.0"
},
"devDependencies": {
"eslint-config-expo": "~9.2.0",
Expand Down
1 change: 1 addition & 0 deletions packages/mobile-client/src/webrtc-polyfill.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'fast-text-encoding';
import 'react-native-get-random-values';

import { registerGlobals } from '@fishjam-cloud/react-native-webrtc';
Expand Down
5 changes: 2 additions & 3 deletions packages/react-client/src/utils/fishjamUrl.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
type LivestreamKind = "whip" | "whep";

export function resolveFishjamUrl(fishjamId: string): string {
try {
if (/^https?:\/\//.test(fishjamId)) {
return new URL(fishjamId).href;
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveFishjamUrl can still throw if fishjamId starts with http(s):// but is not a valid absolute URL (e.g. malformed input). Previously this was caught and fell back to the default connect URL; consider keeping a try/catch (or using URL.canParse where available) around new URL(...) so the function never throws for invalid inputs.

Suggested change
return new URL(fishjamId).href;
try {
return new URL(fishjamId).href;
} catch {
// Fall back to default connect URL if the provided string is not a valid absolute URL.
return `https://fishjam.io/api/v1/connect/${fishjamId}`;
}

Copilot uses AI. Check for mistakes.
} catch {
return `https://fishjam.io/api/v1/connect/${fishjamId}`;
}
return `https://fishjam.io/api/v1/connect/${fishjamId}`;
}

export function httpToWebsocketUrl(url: string): string {
Expand Down
7 changes: 3 additions & 4 deletions packages/ts-client/src/livestream.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { WHEPClient } from '@binbat/whip-whep/whep';
import { WHIPClient } from '@binbat/whip-whep/whip';

export type ReceiveLivestreamResult = {
stream: MediaStream;
stop: () => Promise<void>;
Expand All @@ -21,13 +18,14 @@ export type LivestreamCallbacks = {
onConnectionStateChange?: (pc: RTCPeerConnection) => void;
};

export function receiveLivestream(url: string, token?: string, callbacks?: LivestreamCallbacks) {
export async function receiveLivestream(url: string, token?: string, callbacks?: LivestreamCallbacks) {
const pc = new RTCPeerConnection({ bundlePolicy: 'max-bundle' });

pc.addTransceiver('video', { direction: 'recvonly' });
pc.addTransceiver('audio', { direction: 'recvonly' });
pc.onconnectionstatechange = (_ev) => callbacks?.onConnectionStateChange?.(pc);

const { WHEPClient } = await import('@binbat/whip-whep/whep');
const whep = new WHEPClient();
Comment on lines +28 to 29
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new dynamic import can now fail at runtime (e.g. bundler/module resolution issues) and will reject with the raw import error rather than a LivestreamError. To keep the public error surface consistent, wrap the import in try/catch and map failures to LivestreamError.UNKNOWN_ERROR (or reject accordingly).

Copilot uses AI. Check for mistakes.

return new Promise<ReceiveLivestreamResult>((resolve, reject) => {
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inside this new Promise(...) block, the whep.view(...).catch(...) logic only rejects when the caught value is an Error. If the underlying client rejects with a non-Error value, the promise can remain pending indefinitely. Consider ensuring the catch path always rejects (defaulting to LivestreamError.UNKNOWN_ERROR).

Copilot uses AI. Check for mistakes.
Expand Down Expand Up @@ -77,6 +75,7 @@ export async function publishLivestream(
if (video) pc.addTransceiver(video, { direction: 'sendonly' });
if (audio) pc.addTransceiver(audio, { direction: 'sendonly' });

const { WHIPClient } = await import('@binbat/whip-whep/whip');
const whip = new WHIPClient();
try {
await whip.publish(pc, url, token);
Expand Down
14 changes: 12 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3868,11 +3868,14 @@ __metadata:
eslint-config-expo: "npm:~9.2.0"
eslint-plugin-prettier: "npm:^5.5.1"
expo-module-scripts: "npm:^5.0.7"
react-native-get-random-values: "npm:^1.11.0"
fast-text-encoding: "npm:^1.0.6"
react-native-get-random-values: "npm:1.11.0"
peerDependencies:
"@fishjam-cloud/react-native-webrtc": 0.25.0
expo: "*"
react: "*"
react-native: "*"
react-native-get-random-values: 1.11.0
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -11865,6 +11868,13 @@ __metadata:
languageName: node
linkType: hard

"fast-text-encoding@npm:^1.0.6":
version: 1.0.6
resolution: "fast-text-encoding@npm:1.0.6"
checksum: 10c0/e1d0381bda229c92c7906f63308f3b9caca8c78b732768b1ee16f560089ed21bc159bbe1434138ccd3815931ec8d4785bdade1ad1c45accfdf27ac6606ac67d2
languageName: node
linkType: hard

"fastq@npm:^1.6.0":
version: 1.19.1
resolution: "fastq@npm:1.19.1"
Expand Down Expand Up @@ -16729,7 +16739,7 @@ __metadata:
languageName: node
linkType: hard

"react-native-get-random-values@npm:^1.11.0":
"react-native-get-random-values@npm:1.11.0":
version: 1.11.0
resolution: "react-native-get-random-values@npm:1.11.0"
dependencies:
Expand Down
Loading