@xorgate/react-native 0.1.0
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/CHANGELOG.md +47 -0
- package/LICENSE +21 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/live-video.d.ts +46 -0
- package/dist/live-video.d.ts.map +1 -0
- package/dist/live-video.js +83 -0
- package/dist/live-video.js.map +1 -0
- package/dist/platform.d.ts +32 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +23 -0
- package/dist/platform.js.map +1 -0
- package/dist/polyfills.d.ts +3 -0
- package/dist/polyfills.d.ts.map +1 -0
- package/dist/polyfills.js +56 -0
- package/dist/polyfills.js.map +1 -0
- package/dist/provider.d.ts +19 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +28 -0
- package/dist/provider.js.map +1 -0
- package/dist/use-live-video.d.ts +38 -0
- package/dist/use-live-video.d.ts.map +1 -0
- package/dist/use-live-video.js +49 -0
- package/dist/use-live-video.js.map +1 -0
- package/dist/wake.d.ts +25 -0
- package/dist/wake.d.ts.map +1 -0
- package/dist/wake.js +38 -0
- package/dist/wake.js.map +1 -0
- package/dist/webcrypto.d.ts +45 -0
- package/dist/webcrypto.d.ts.map +1 -0
- package/dist/webcrypto.js +62 -0
- package/dist/webcrypto.js.map +1 -0
- package/dist/webrtc-platform.d.ts +21 -0
- package/dist/webrtc-platform.d.ts.map +1 -0
- package/dist/webrtc-platform.js +61 -0
- package/dist/webrtc-platform.js.map +1 -0
- package/package.json +95 -0
- package/readme.md +312 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
First release: live telemetry and live video on React Native, over
|
|
6
|
+
`@xorgate/react` 0.2.0's platform slot.
|
|
7
|
+
|
|
8
|
+
- `nativePlatform()` — three of `@xorgate/react`'s four platform slots: a
|
|
9
|
+
`WebRtcPlatform` whose peer connection is `react-native-webrtc`'s
|
|
10
|
+
(`iceTransportPolicy: "all"`, because a viewer on a carrier NAT often has no
|
|
11
|
+
path but the TURN relay), the `AppState` foreground edge as the wake source,
|
|
12
|
+
and id entropy from `expo-crypto`. `mqttConnect` is deliberately left unset:
|
|
13
|
+
mqtt.js 5 runs on React Native's global WebSocket unmodified. The three AWS
|
|
14
|
+
bodies — signaling endpoints, ICE servers, the lazy signaling facade — are
|
|
15
|
+
`@xorgate/react`'s own.
|
|
16
|
+
- `XorgateNativeProvider` — `XorgateProvider` with that platform already in it,
|
|
17
|
+
plus `randomId` / `wake` / `mqttConnect` props and a `platform` escape hatch.
|
|
18
|
+
- `useLiveVideo(channel)` / `<LiveVideo channel …/>` over `RTCView`. The
|
|
19
|
+
component holds the outgoing picture across a reconnect until the incoming
|
|
20
|
+
stream reports its first frame, so a blip does not flash black the way a new
|
|
21
|
+
`streamURL` on a bare `RTCView` would; it gives the hold up after 3 s rather
|
|
22
|
+
than pin a stale frame.
|
|
23
|
+
- `appStateWake` / `composeWake` — the foreground edge, and a way to add "the
|
|
24
|
+
network came back" without this package depending on a network library.
|
|
25
|
+
- `@xorgate/react-native/polyfills` — `getRandomValues` and `randomUUID` from
|
|
26
|
+
`expo-crypto` onto `globalThis.crypto`. **Required for live video**, though
|
|
27
|
+
not by this package: `nativePlatform()` covers the SDK's own entropy and
|
|
28
|
+
telemetry needs no polyfill, but `@smithy/core`'s React Native serde bundle
|
|
29
|
+
dereferences a BARE `crypto` in the very fallback it takes when `crypto` is
|
|
30
|
+
undefined, so the first KVS call throws `Property 'crypto' doesn't exist` on
|
|
31
|
+
Hermes (smithy-typescript#2276). A separate entry point so the polyfill is a deliberate line in the
|
|
32
|
+
consumer's entry file rather than an import side effect — and the WebRTC
|
|
33
|
+
platform checks for the global at its first AWS call and says so by name,
|
|
34
|
+
because the raw symptom is a `ReferenceError` the session retries forever.
|
|
35
|
+
- Live telemetry, the data hooks, the live-block policy, the replay timeline,
|
|
36
|
+
lanes, clock and telemetry math are re-exported unchanged from
|
|
37
|
+
`@xorgate/react`; its browser-only hooks deliberately are not.
|
|
38
|
+
- `@xorgate/react-native/webcrypto` — the WebCrypto subset the KVS signaling
|
|
39
|
+
client's SigV4 signer needs (`digest`, `importKey`, `sign`, all SHA-256),
|
|
40
|
+
for Metro to alias `isomorphic-webcrypto` at; that package's own React
|
|
41
|
+
Native build evaluates to `undefined` on Hermes.
|
|
42
|
+
|
|
43
|
+
Metro needs four resolver rules for the AWS / KVS tree; they are in the README
|
|
44
|
+
and nothing else (`buffer`, `process`, `events`, `url`, stream or URL
|
|
45
|
+
polyfills) was necessary on Expo SDK 57 / Hermes.
|
|
46
|
+
|
|
47
|
+
Replay over `expo-video` is 0.2.0.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Epye Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@xorgate/react-native` — the React Native half of `@xorgate/react`.
|
|
3
|
+
*
|
|
4
|
+
* Everything that is pure or platform-neutral lives in `@xorgate/react` and is
|
|
5
|
+
* re-exported here, so an app imports from ONE package: the data hooks, live
|
|
6
|
+
* telemetry, the live-block policy, the replay timeline and clock, the
|
|
7
|
+
* telemetry math, the types. What this package adds is the runtime underneath
|
|
8
|
+
* them (`nativePlatform`, `XorgateNativeProvider`) and the two pieces that
|
|
9
|
+
* cannot be neutral because they are pixels: `useLiveVideo` / `LiveVideo` over
|
|
10
|
+
* react-native-webrtc's `RTCView`.
|
|
11
|
+
*
|
|
12
|
+
* The browser-only exports of `@xorgate/react` — its `useLiveVideo`,
|
|
13
|
+
* `LiveVideo`, `useReplayPlayer`, `ReplayVideo` and the `browser*` platform
|
|
14
|
+
* helpers — are deliberately NOT re-exported: they need `HTMLVideoElement`,
|
|
15
|
+
* `window` or Media Source Extensions, none of which exist here. Importing
|
|
16
|
+
* `@xorgate/react` directly still works and is how you reach them on web.
|
|
17
|
+
*/
|
|
18
|
+
export { nativePlatform, type NativePlatformOptions } from "./platform.js";
|
|
19
|
+
export { createNativeWebRtcPlatform } from "./webrtc-platform.js";
|
|
20
|
+
export { appStateWake, composeWake, type WakeSource } from "./wake.js";
|
|
21
|
+
export { XorgateNativeProvider, type XorgateNativeProviderProps, } from "./provider.js";
|
|
22
|
+
export { useLiveVideo, type UseLiveVideo, type UseLiveVideoOptions, } from "./use-live-video.js";
|
|
23
|
+
export { LiveVideo, type LiveVideoProps } from "./live-video.js";
|
|
24
|
+
export { XorgateProvider, useXorgate, useXorgateTenancy, DEFAULT_BASE_URL, type XorgateProviderProps, type XorgateConfig, type XorgateAuth, type FirstPartyAuth, type SessionTokenAuth, type ApiKeyAuth, type LiveCredentialsAuth, type LiveCredentials, type LiveUnavailableReason, type Awaitable, type XorgatePlatform, XorgateError, isXorgateError, type Device, type DeviceModel, type LatestByMetric, type LatestReading, type MediaSession, type Me, type MetricName, type Organization, type PageMeta, type RecordingRun, type ReplayGap, type ReplayManifest, type ReplaySegment, type ReplaySession, type StreamKey, type TelemetryHistory, type TelemetryReading, type VideoChannel, type Workspace, type XorgateClient, useMe, useOrganizations, useWorkspaces, useDevices, useDevice, useDeviceModel, useTelemetryLatest, useTelemetryHistory, useVideoChannels, useRecordingRuns, useSessions, type QueryResult, type QueryOptions, type UseDevicesParams, type UseDevicesResult, type UseTelemetryHistoryParams, type UseSessionsParams, type UseRunsResult, type UseSessionsResult, useLiveTelemetry, useLivePlane, useLiveCredentials, parseTelemetryPayload, presignIotWssUrl, type UseLiveTelemetry, type UseLiveTelemetryOptions, type LiveStatus, type TelemetryPoint, type TelemetrySnapshot, type TelemetryFeedDeps, type MqttLikeClient, type MqttConnectionSpec, type ResolvedLiveCredentials, type ParsedTelemetryPayload, type TelemetryRecordingStatus, type TelemetryMediaStatus, type TelemetryStreamStatus, type LiveBlockPayload, useLiveBlock, resolveLiveBlock, liveBlockElapsedMs, LIVE_BLOCK_STALE_MS, type LiveBlockReason, type LiveBlockOpenReason, type LiveBlockState, type ResolveLiveBlockInput, useLiveVideoSession, type UseLiveVideoSession, type UseLiveVideoSessionOptions, type LiveVideoStatus, type LiveVideoStats, type WebRtcPlatform, type PeerConnectionLike, type SignalingLike, type TimerHost, useReplayManifest, useReplayPlayerCore, useReplayTelemetry, buildTimeline, segmentEnd, segmentAt, hasCoverageAt, gapAt, nextSegmentAfter, prevBoundary, nextBoundary, clampTs, buildLanes, buildClockTimeline, segmentUrlKey, ReplayClock, REPLAY_RATES, parseSegmentMediaInfo, seriesFromReadings, floorIndex, latestWithin, metricGroup, stalenessMs, overviewStalenessMs, chooseIntervalSeconds, windowBoundsFor, windowNeedsRefetch, buildTrace, traceLines, traveledLines, positionAt, GROUP_STALENESS_MS, DEFAULT_STALENESS_MS, WINDOW_SPAN_MS, WINDOW_MIN_SPAN_MS, type UseReplayManifestParams, type UseReplayManifestResult, type UseReplayPlayerCore, type UseReplayTelemetry, type UseReplayTelemetryOptions, type ReplayEngine, type ReplayEngineOptions, type ReplayEngineFactory, type ReplayTimeline, type ReplayLane, type LaneSegment, type ReplayClockState, type ReplayRate, type PacerCandidate, type GapSkipEvent, type SegmentMediaInfo, type MetricSeries, type GpsTrace, type WindowBounds, type PositionResolution, } from "@xorgate/react";
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@xorgate/react-native` — the React Native half of `@xorgate/react`.
|
|
3
|
+
*
|
|
4
|
+
* Everything that is pure or platform-neutral lives in `@xorgate/react` and is
|
|
5
|
+
* re-exported here, so an app imports from ONE package: the data hooks, live
|
|
6
|
+
* telemetry, the live-block policy, the replay timeline and clock, the
|
|
7
|
+
* telemetry math, the types. What this package adds is the runtime underneath
|
|
8
|
+
* them (`nativePlatform`, `XorgateNativeProvider`) and the two pieces that
|
|
9
|
+
* cannot be neutral because they are pixels: `useLiveVideo` / `LiveVideo` over
|
|
10
|
+
* react-native-webrtc's `RTCView`.
|
|
11
|
+
*
|
|
12
|
+
* The browser-only exports of `@xorgate/react` — its `useLiveVideo`,
|
|
13
|
+
* `LiveVideo`, `useReplayPlayer`, `ReplayVideo` and the `browser*` platform
|
|
14
|
+
* helpers — are deliberately NOT re-exported: they need `HTMLVideoElement`,
|
|
15
|
+
* `window` or Media Source Extensions, none of which exist here. Importing
|
|
16
|
+
* `@xorgate/react` directly still works and is how you reach them on web.
|
|
17
|
+
*/
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// The React Native runtime
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
export { nativePlatform } from "./platform.js";
|
|
22
|
+
export { createNativeWebRtcPlatform } from "./webrtc-platform.js";
|
|
23
|
+
export { appStateWake, composeWake } from "./wake.js";
|
|
24
|
+
export { XorgateNativeProvider, } from "./provider.js";
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Live video (RTCView)
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
export { useLiveVideo, } from "./use-live-video.js";
|
|
29
|
+
export { LiveVideo } from "./live-video.js";
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Re-exported unchanged from `@xorgate/react`
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
export {
|
|
34
|
+
// Provider and tenancy
|
|
35
|
+
XorgateProvider, useXorgate, useXorgateTenancy, DEFAULT_BASE_URL,
|
|
36
|
+
// Errors and the backend vocabulary
|
|
37
|
+
XorgateError, isXorgateError,
|
|
38
|
+
// Data hooks
|
|
39
|
+
useMe, useOrganizations, useWorkspaces, useDevices, useDevice, useDeviceModel, useTelemetryLatest, useTelemetryHistory, useVideoChannels, useRecordingRuns, useSessions,
|
|
40
|
+
// Live telemetry and the live plane
|
|
41
|
+
useLiveTelemetry, useLivePlane, useLiveCredentials, parseTelemetryPayload, presignIotWssUrl,
|
|
42
|
+
// Live-block policy
|
|
43
|
+
useLiveBlock, resolveLiveBlock, liveBlockElapsedMs, LIVE_BLOCK_STALE_MS,
|
|
44
|
+
// The video session core and its platform boundary
|
|
45
|
+
useLiveVideoSession,
|
|
46
|
+
// Replay: pure timeline, lanes, clock and telemetry math (the engine is N3)
|
|
47
|
+
useReplayManifest, useReplayPlayerCore, useReplayTelemetry, buildTimeline, segmentEnd, segmentAt, hasCoverageAt, gapAt, nextSegmentAfter, prevBoundary, nextBoundary, clampTs, buildLanes, buildClockTimeline, segmentUrlKey, ReplayClock, REPLAY_RATES, parseSegmentMediaInfo, seriesFromReadings, floorIndex, latestWithin, metricGroup, stalenessMs, overviewStalenessMs, chooseIntervalSeconds, windowBoundsFor, windowNeedsRefetch, buildTrace, traceLines, traveledLines, positionAt, GROUP_STALENESS_MS, DEFAULT_STALENESS_MS, WINDOW_SPAN_MS, WINDOW_MIN_SPAN_MS, } from "@xorgate/react";
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E,OAAO,EAAE,cAAc,EAA8B,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAmB,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,qBAAqB,GAEtB,MAAM,eAAe,CAAC;AAEvB,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,OAAO,EACL,YAAY,GAGb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAuB,MAAM,iBAAiB,CAAC;AAEjE,8EAA8E;AAC9E,8CAA8C;AAC9C,8EAA8E;AAE9E,OAAO;AACL,uBAAuB;AACvB,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,gBAAgB;AAahB,oCAAoC;AACpC,YAAY,EACZ,cAAc;AAsBd,aAAa;AACb,KAAK,EACL,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,WAAW;AAUX,oCAAoC;AACpC,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB;AAgBhB,oBAAoB;AACpB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB;AAMnB,mDAAmD;AACnD,mBAAmB;AAUnB,4EAA4E;AAC5E,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,SAAS,EACT,aAAa,EACb,KAAK,EACL,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,GAqBnB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { ViewProps } from "react-native";
|
|
3
|
+
import type { RTCVideoViewProps } from "react-native-webrtc";
|
|
4
|
+
import type { VideoChannel, XorgateError } from "@xorgate/react";
|
|
5
|
+
import type { LiveVideoStats, LiveVideoStatus, UseLiveVideoOptions } from "./use-live-video.js";
|
|
6
|
+
export interface LiveVideoProps extends Omit<ViewProps, "children"> {
|
|
7
|
+
channel: VideoChannel | null;
|
|
8
|
+
options?: UseLiveVideoOptions;
|
|
9
|
+
/** Defaults to "cover", matching the web component's object-fit. */
|
|
10
|
+
objectFit?: RTCVideoViewProps["objectFit"];
|
|
11
|
+
zOrder?: RTCVideoViewProps["zOrder"];
|
|
12
|
+
mirror?: RTCVideoViewProps["mirror"];
|
|
13
|
+
/** Called on every transition. The component renders no status chrome of its own. */
|
|
14
|
+
onStatusChange?: (status: LiveVideoStatus, error: XorgateError | null) => void;
|
|
15
|
+
/** Each inbound-rtp sample, for a stats row. Null between sessions. */
|
|
16
|
+
onStats?: (stats: LiveVideoStats | null) => void;
|
|
17
|
+
/** The encoded size of the picture on screen, as the renderer reports it. */
|
|
18
|
+
onVideoDimensions?: (dimensions: {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
}) => void;
|
|
22
|
+
/**
|
|
23
|
+
* The stream actually ON SCREEN, which during a reconnect lags the session's
|
|
24
|
+
* by the length of the hold below. Null while nothing is displayed.
|
|
25
|
+
*/
|
|
26
|
+
onDisplayedStreamChange?: (streamURL: string | null) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `useLiveVideo` plus the native video view, and nothing else: no card, no
|
|
30
|
+
* spinner, no status text, no aspect ratio. It exists so the 90% case is one
|
|
31
|
+
* line, not so it can be your player — the web `LiveVideo` makes the same
|
|
32
|
+
* promise.
|
|
33
|
+
*
|
|
34
|
+
* What it does add over a bare `RTCView` is the reconnect hold. Every
|
|
35
|
+
* reconnect produces a new `MediaStream` with a new `streamURL`, and an
|
|
36
|
+
* `RTCView` pointed at a stream that has not decoded a frame yet is black —
|
|
37
|
+
* so a 2 s blip on a phone would blank the picture, where the browser's
|
|
38
|
+
* `<video>` simply keeps its last frame. Here the new stream is mounted
|
|
39
|
+
* underneath at zero opacity and only promoted once the renderer reports its
|
|
40
|
+
* dimensions, which is the first-frame signal; until then the outgoing view
|
|
41
|
+
* stays on screen. If the new stream never produces a frame the swap happens
|
|
42
|
+
* anyway after {@link HOLD_TIMEOUT_MS}, so a dead stream cannot pin a stale
|
|
43
|
+
* frame forever.
|
|
44
|
+
*/
|
|
45
|
+
export declare function LiveVideo(props: LiveVideoProps): ReactNode;
|
|
46
|
+
//# sourceMappingURL=live-video.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-video.d.ts","sourceRoot":"","sources":["../src/live-video.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IACjE,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,oEAAoE;IACpE,SAAS,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,qFAAqF;IACrF,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/E,uEAAuE;IACvE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5E;;;OAGG;IACH,uBAAuB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CA+F1D"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { StyleSheet, View } from "react-native";
|
|
4
|
+
import { RTCView } from "react-native-webrtc";
|
|
5
|
+
import { useLiveVideo } from "./use-live-video.js";
|
|
6
|
+
/** How long to keep the outgoing picture if the incoming stream never reports a frame. */
|
|
7
|
+
const HOLD_TIMEOUT_MS = 3000;
|
|
8
|
+
/**
|
|
9
|
+
* `useLiveVideo` plus the native video view, and nothing else: no card, no
|
|
10
|
+
* spinner, no status text, no aspect ratio. It exists so the 90% case is one
|
|
11
|
+
* line, not so it can be your player — the web `LiveVideo` makes the same
|
|
12
|
+
* promise.
|
|
13
|
+
*
|
|
14
|
+
* What it does add over a bare `RTCView` is the reconnect hold. Every
|
|
15
|
+
* reconnect produces a new `MediaStream` with a new `streamURL`, and an
|
|
16
|
+
* `RTCView` pointed at a stream that has not decoded a frame yet is black —
|
|
17
|
+
* so a 2 s blip on a phone would blank the picture, where the browser's
|
|
18
|
+
* `<video>` simply keeps its last frame. Here the new stream is mounted
|
|
19
|
+
* underneath at zero opacity and only promoted once the renderer reports its
|
|
20
|
+
* dimensions, which is the first-frame signal; until then the outgoing view
|
|
21
|
+
* stays on screen. If the new stream never produces a frame the swap happens
|
|
22
|
+
* anyway after {@link HOLD_TIMEOUT_MS}, so a dead stream cannot pin a stale
|
|
23
|
+
* frame forever.
|
|
24
|
+
*/
|
|
25
|
+
export function LiveVideo(props) {
|
|
26
|
+
const { channel, options, objectFit = "cover", zOrder, mirror, onStatusChange, onStats, onVideoDimensions, onDisplayedStreamChange, style, ...viewProps } = props;
|
|
27
|
+
const { streamURL, status, error, stats } = useLiveVideo(channel, options);
|
|
28
|
+
const onStatusChangeRef = useRef(onStatusChange);
|
|
29
|
+
onStatusChangeRef.current = onStatusChange;
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
onStatusChangeRef.current?.(status, error);
|
|
32
|
+
}, [status, error]);
|
|
33
|
+
const onStatsRef = useRef(onStats);
|
|
34
|
+
onStatsRef.current = onStats;
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
onStatsRef.current?.(stats);
|
|
37
|
+
}, [stats]);
|
|
38
|
+
const onVideoDimensionsRef = useRef(onVideoDimensions);
|
|
39
|
+
onVideoDimensionsRef.current = onVideoDimensions;
|
|
40
|
+
// `shown` is the picture on screen; `incoming` is a newer stream warming up
|
|
41
|
+
// behind it. A first stream goes straight to `shown` — there is nothing to
|
|
42
|
+
// hold on to and no reason to make the viewer wait.
|
|
43
|
+
const [shown, setShown] = useState(null);
|
|
44
|
+
const [incoming, setIncoming] = useState(null);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (streamURL === null) {
|
|
47
|
+
setShown(null);
|
|
48
|
+
setIncoming(null);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
setShown((current) => {
|
|
52
|
+
if (current === null)
|
|
53
|
+
return streamURL;
|
|
54
|
+
if (current !== streamURL)
|
|
55
|
+
setIncoming(streamURL);
|
|
56
|
+
return current;
|
|
57
|
+
});
|
|
58
|
+
}, [streamURL]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (incoming === null)
|
|
61
|
+
return;
|
|
62
|
+
const timer = setTimeout(() => {
|
|
63
|
+
setShown(incoming);
|
|
64
|
+
setIncoming(null);
|
|
65
|
+
}, HOLD_TIMEOUT_MS);
|
|
66
|
+
return () => clearTimeout(timer);
|
|
67
|
+
}, [incoming]);
|
|
68
|
+
const promote = (url) => {
|
|
69
|
+
setShown(url);
|
|
70
|
+
setIncoming((current) => (current === url ? null : current));
|
|
71
|
+
};
|
|
72
|
+
const onDisplayedStreamChangeRef = useRef(onDisplayedStreamChange);
|
|
73
|
+
onDisplayedStreamChangeRef.current = onDisplayedStreamChange;
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
onDisplayedStreamChangeRef.current?.(shown);
|
|
76
|
+
}, [shown]);
|
|
77
|
+
return (_jsxs(View, { style: style, ...viewProps, children: [shown !== null && (_jsx(RTCView, { streamURL: shown, objectFit: objectFit, ...(zOrder !== undefined ? { zOrder } : {}), ...(mirror !== undefined ? { mirror } : {}), style: StyleSheet.absoluteFill, onDimensionsChange: (event) => onVideoDimensionsRef.current?.(event.nativeEvent) })), incoming !== null && (_jsx(RTCView, { streamURL: incoming, objectFit: objectFit, ...(zOrder !== undefined ? { zOrder } : {}), ...(mirror !== undefined ? { mirror } : {}), style: [StyleSheet.absoluteFill, styles.warming], onDimensionsChange: () => promote(incoming) }))] }));
|
|
78
|
+
}
|
|
79
|
+
const styles = StyleSheet.create({
|
|
80
|
+
// Mounted so the renderer decodes, invisible so the outgoing frame stands.
|
|
81
|
+
warming: { opacity: 0 },
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=live-video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-video.js","sourceRoot":"","sources":["../src/live-video.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { XorgatePlatform } from "@xorgate/react";
|
|
2
|
+
import { type WakeSource } from "./wake.js";
|
|
3
|
+
export interface NativePlatformOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Client-id entropy for MQTT and KVS signaling. Default: `expo-crypto`'s
|
|
6
|
+
* `randomUUID()`. Hermes has no `crypto` global, so there is nothing else
|
|
7
|
+
* to default to; pass your own only to use a different source.
|
|
8
|
+
*/
|
|
9
|
+
randomId?: () => string;
|
|
10
|
+
/**
|
|
11
|
+
* Extra wake sources, merged with the foreground edge. "The network came
|
|
12
|
+
* back" belongs here; the README has the expo-network and NetInfo recipes.
|
|
13
|
+
*/
|
|
14
|
+
wake?: WakeSource[];
|
|
15
|
+
/**
|
|
16
|
+
* Replace the MQTT transport. Leave unset: mqtt.js 5 runs unmodified on
|
|
17
|
+
* React Native's global WebSocket (its `react-native` export condition
|
|
18
|
+
* resolves to a self-contained ESM build), which is what the telemetry
|
|
19
|
+
* plane was measured on.
|
|
20
|
+
*/
|
|
21
|
+
mqttConnect?: XorgatePlatform["mqttConnect"];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The React Native half of `@xorgate/react`: pass it to the provider once and
|
|
25
|
+
* every neutral hook in that package — telemetry, live video, the data hooks'
|
|
26
|
+
* refetch-on-focus — runs on this runtime instead of a browser's.
|
|
27
|
+
*
|
|
28
|
+
* `XorgateNativeProvider` calls this for you; call it yourself only when you
|
|
29
|
+
* are composing the platform with slots of your own.
|
|
30
|
+
*/
|
|
31
|
+
export declare function nativePlatform(options?: NativePlatformOptions): XorgatePlatform;
|
|
32
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvE,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;CAC9C;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,eAAe,CAUnF"}
|
package/dist/platform.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { randomUUID } from "expo-crypto";
|
|
2
|
+
import { createNativeWebRtcPlatform } from "./webrtc-platform.js";
|
|
3
|
+
import { appStateWake, composeWake } from "./wake.js";
|
|
4
|
+
/**
|
|
5
|
+
* The React Native half of `@xorgate/react`: pass it to the provider once and
|
|
6
|
+
* every neutral hook in that package — telemetry, live video, the data hooks'
|
|
7
|
+
* refetch-on-focus — runs on this runtime instead of a browser's.
|
|
8
|
+
*
|
|
9
|
+
* `XorgateNativeProvider` calls this for you; call it yourself only when you
|
|
10
|
+
* are composing the platform with slots of your own.
|
|
11
|
+
*/
|
|
12
|
+
export function nativePlatform(options = {}) {
|
|
13
|
+
const randomId = options.randomId ?? randomUUID;
|
|
14
|
+
return {
|
|
15
|
+
createWebRtcPlatform: () => createNativeWebRtcPlatform(randomId),
|
|
16
|
+
subscribeWake: options.wake?.length
|
|
17
|
+
? composeWake(appStateWake, ...options.wake)
|
|
18
|
+
: appStateWake,
|
|
19
|
+
randomId,
|
|
20
|
+
...(options.mqttConnect ? { mqttConnect: options.mqttConnect } : {}),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAmB,MAAM,WAAW,CAAC;AAuBvE;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,UAAiC,EAAE;IAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,UAAU,CAAC;IAChD,OAAO;QACL,oBAAoB,EAAE,GAAG,EAAE,CAAC,0BAA0B,CAAC,QAAQ,CAAC;QAChE,aAAa,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM;YACjC,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAC5C,CAAC,CAAC,YAAY;QAChB,QAAQ;QACR,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polyfills.d.ts","sourceRoot":"","sources":["../src/polyfills.ts"],"names":[],"mappings":"AAyCA,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAAO,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@xorgate/react-native/polyfills` — the one runtime shim React Native needs
|
|
3
|
+
* for the live plane. Import it for its side effect, once, at the very top of
|
|
4
|
+
* your entry file, before anything that reaches the SDK:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import "@xorgate/react-native/polyfills"
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Hermes on Expo SDK 57 has NO `crypto` global — measured, not assumed: not
|
|
11
|
+
* `randomUUID`, not `getRandomValues`, not `subtle`.
|
|
12
|
+
*
|
|
13
|
+
* **Live video does not work without this import**, though not because of
|
|
14
|
+
* this package: `nativePlatform()` covers the SDK's own client ids through
|
|
15
|
+
* the `randomId` slot, and live telemetry runs with no polyfill at all. It is
|
|
16
|
+
* the AWS SDK underneath the KVS viewer. `@smithy/core`'s React Native serde
|
|
17
|
+
* bundle ends its UUID v4 path in `(array) => crypto.getRandomValues(array)`
|
|
18
|
+
* with a BARE `crypto`, and that is the fallback `bindV4` selects precisely
|
|
19
|
+
* when `typeof crypto === "undefined"` — so the guard hands control to the
|
|
20
|
+
* one line that cannot survive the case it guards for (the same bug was fixed
|
|
21
|
+
* for the Node build in smithy-typescript#2022; the native build was not —
|
|
22
|
+
* smithy-typescript#2276). `createNativeWebRtcPlatform` checks for the global
|
|
23
|
+
* at its first AWS call so the message names this import rather than leaving
|
|
24
|
+
* a `ReferenceError` to be retried forever.
|
|
25
|
+
*
|
|
26
|
+
* It is additive — an existing `crypto` keeps every function it already has —
|
|
27
|
+
* and it is a separate entry point so the polyfill is a deliberate line in
|
|
28
|
+
* your entry file rather than a side effect of importing the package.
|
|
29
|
+
*
|
|
30
|
+
* NOTE this is entropy and UUIDs only. `crypto.subtle` is NOT installed: the
|
|
31
|
+
* one place the SDK needs WebCrypto is SigV4 signing inside the KVS signaling
|
|
32
|
+
* client, and that is a Metro resolver rule (`isomorphic-webcrypto`), not a
|
|
33
|
+
* global. See README "Metro setup".
|
|
34
|
+
*/
|
|
35
|
+
import * as Crypto from "expo-crypto";
|
|
36
|
+
/** What this module installed, for diagnostics screens. Empty = nothing was missing. */
|
|
37
|
+
export const INSTALLED_POLYFILLS = [];
|
|
38
|
+
const g = globalThis;
|
|
39
|
+
if (!g.crypto) {
|
|
40
|
+
g.crypto = {
|
|
41
|
+
getRandomValues: Crypto.getRandomValues,
|
|
42
|
+
randomUUID: Crypto.randomUUID,
|
|
43
|
+
};
|
|
44
|
+
INSTALLED_POLYFILLS.push("crypto.getRandomValues", "crypto.randomUUID");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
if (typeof g.crypto.getRandomValues !== "function") {
|
|
48
|
+
g.crypto.getRandomValues = Crypto.getRandomValues;
|
|
49
|
+
INSTALLED_POLYFILLS.push("crypto.getRandomValues");
|
|
50
|
+
}
|
|
51
|
+
if (typeof g.crypto.randomUUID !== "function") {
|
|
52
|
+
g.crypto.randomUUID = Crypto.randomUUID;
|
|
53
|
+
INSTALLED_POLYFILLS.push("crypto.randomUUID");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=polyfills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polyfills.js","sourceRoot":"","sources":["../src/polyfills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAOtC,wFAAwF;AACxF,MAAM,CAAC,MAAM,mBAAmB,GAAa,EAAE,CAAC;AAEhD,MAAM,CAAC,GAAG,UAAuC,CAAC;AAElD,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACd,CAAC,CAAC,MAAM,GAAG;QACT,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC;IACF,mBAAmB,CAAC,IAAI,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,CAAC;AAC1E,CAAC;KAAM,CAAC;IACN,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;QACnD,CAAC,CAAC,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAClD,mBAAmB,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QAC9C,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACxC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { XorgatePlatform, XorgateProviderProps } from "@xorgate/react";
|
|
3
|
+
import { type NativePlatformOptions } from "./platform.js";
|
|
4
|
+
export interface XorgateNativeProviderProps extends Omit<XorgateProviderProps, "platform">, NativePlatformOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Slots merged OVER the native defaults, for the rare case where one of
|
|
7
|
+
* them is wrong for your app. Everything you leave out stays native.
|
|
8
|
+
*/
|
|
9
|
+
platform?: XorgatePlatform;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* `XorgateProvider` with the React Native platform already in it. Use it
|
|
13
|
+
* exactly where a web app uses `XorgateProvider` — same `auth`,
|
|
14
|
+
* `organizationId`, `workspaceId`, `config` and `onError` props, same rule
|
|
15
|
+
* that remounting on the organization (`key={orgId}`) is how you switch
|
|
16
|
+
* tenants.
|
|
17
|
+
*/
|
|
18
|
+
export declare function XorgateNativeProvider(props: XorgateNativeProviderProps): ReactNode;
|
|
19
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3E,MAAM,WAAW,0BACf,SAAQ,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,EAC5C,qBAAqB;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,SAAS,CAuBlF"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { XorgateProvider } from "@xorgate/react";
|
|
4
|
+
import { nativePlatform } from "./platform.js";
|
|
5
|
+
/**
|
|
6
|
+
* `XorgateProvider` with the React Native platform already in it. Use it
|
|
7
|
+
* exactly where a web app uses `XorgateProvider` — same `auth`,
|
|
8
|
+
* `organizationId`, `workspaceId`, `config` and `onError` props, same rule
|
|
9
|
+
* that remounting on the organization (`key={orgId}`) is how you switch
|
|
10
|
+
* tenants.
|
|
11
|
+
*/
|
|
12
|
+
export function XorgateNativeProvider(props) {
|
|
13
|
+
const { randomId, wake, mqttConnect, platform, children, ...providerProps } = props;
|
|
14
|
+
const merged = useMemo(() => ({
|
|
15
|
+
...nativePlatform({
|
|
16
|
+
...(randomId ? { randomId } : {}),
|
|
17
|
+
...(wake ? { wake } : {}),
|
|
18
|
+
...(mqttConnect ? { mqttConnect } : {}),
|
|
19
|
+
}),
|
|
20
|
+
...platform,
|
|
21
|
+
}),
|
|
22
|
+
// The wake array is read once per subscription; an inline literal must not
|
|
23
|
+
// rebuild the platform on every render.
|
|
24
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
25
|
+
[randomId, mqttConnect, platform]);
|
|
26
|
+
return (_jsx(XorgateProvider, { ...providerProps, platform: merged, children: children }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,cAAc,EAA8B,MAAM,eAAe,CAAC;AAY3E;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAiC;IACrE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,aAAa,EAAE,GAAG,KAAK,CAAC;IAEpF,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,cAAc,CAAC;YAChB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC;QACF,GAAG,QAAQ;KACZ,CAAC;IACF,2EAA2E;IAC3E,wCAAwC;IACxC,uDAAuD;IACvD,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAClC,CAAC;IAEF,OAAO,CACL,KAAC,eAAe,OAAK,aAAa,EAAE,QAAQ,EAAE,MAAM,YACjD,QAAQ,GACO,CACnB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { LiveUnavailableReason, LiveVideoStats, LiveVideoStatus, UseLiveVideoSessionOptions, VideoChannel, XorgateError } from "@xorgate/react";
|
|
2
|
+
import type { MediaStream } from "react-native-webrtc";
|
|
3
|
+
export type { LiveVideoStatus, LiveVideoStats } from "@xorgate/react";
|
|
4
|
+
export interface UseLiveVideo {
|
|
5
|
+
/**
|
|
6
|
+
* The received remote stream, or null while idle. A reconnect delivers a
|
|
7
|
+
* NEW stream object: the previous one is dead, not resumable.
|
|
8
|
+
*/
|
|
9
|
+
stream: MediaStream | null;
|
|
10
|
+
/** `stream.toURL()`, the only thing `RTCView` takes. Null while idle. */
|
|
11
|
+
streamURL: string | null;
|
|
12
|
+
status: LiveVideoStatus;
|
|
13
|
+
unavailableReason: LiveUnavailableReason | null;
|
|
14
|
+
error: XorgateError | null;
|
|
15
|
+
/** Null until the first sample lands. Reset to null on every reconnect. */
|
|
16
|
+
stats: LiveVideoStats | null;
|
|
17
|
+
}
|
|
18
|
+
export type UseLiveVideoOptions = Omit<UseLiveVideoSessionOptions, "onStream">;
|
|
19
|
+
/**
|
|
20
|
+
* Run a KVS WebRTC VIEWER for one signaling channel and hand back the
|
|
21
|
+
* received stream for an `RTCView`. Pass `null` to stay idle.
|
|
22
|
+
*
|
|
23
|
+
* This is the React Native wrapper over `@xorgate/react`'s
|
|
24
|
+
* `useLiveVideoSession`: the session itself — generation counter, per-step and
|
|
25
|
+
* whole-attempt deadlines, the disconnect grace, backoff, the ~50 minute
|
|
26
|
+
* credential cycle, the wake nudge — is the same code the web app runs, and it
|
|
27
|
+
* was earned against real LTE devices. What differs on a phone is the
|
|
28
|
+
* platform underneath it (`nativePlatform()`) and the fact that the picture
|
|
29
|
+
* goes to a native view instead of an element.
|
|
30
|
+
*
|
|
31
|
+
* Unlike the browser, where a reconnect leaves the last frame in the `<video>`
|
|
32
|
+
* element, `streamURL` changes on every reconnect and an `RTCView` handed a
|
|
33
|
+
* new URL has nothing to show until the first frame decodes. `LiveVideo`
|
|
34
|
+
* holds the outgoing picture across that swap; if you render `RTCView`
|
|
35
|
+
* yourself and care, do the same.
|
|
36
|
+
*/
|
|
37
|
+
export declare function useLiveVideo(channel: VideoChannel | null, options?: UseLiveVideoOptions): UseLiveVideo;
|
|
38
|
+
//# sourceMappingURL=use-live-video.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-live-video.d.ts","sourceRoot":"","sources":["../src/use-live-video.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,0BAA0B,EAC1B,YAAY,EACZ,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,yEAAyE;IACzE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,eAAe,CAAC;IACxB,iBAAiB,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAChD,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;AAE/E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,GAAG,IAAI,EAC5B,OAAO,GAAE,mBAAwB,GAChC,YAAY,CA8Bd"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { useLiveVideoSession } from "@xorgate/react";
|
|
3
|
+
/**
|
|
4
|
+
* Run a KVS WebRTC VIEWER for one signaling channel and hand back the
|
|
5
|
+
* received stream for an `RTCView`. Pass `null` to stay idle.
|
|
6
|
+
*
|
|
7
|
+
* This is the React Native wrapper over `@xorgate/react`'s
|
|
8
|
+
* `useLiveVideoSession`: the session itself — generation counter, per-step and
|
|
9
|
+
* whole-attempt deadlines, the disconnect grace, backoff, the ~50 minute
|
|
10
|
+
* credential cycle, the wake nudge — is the same code the web app runs, and it
|
|
11
|
+
* was earned against real LTE devices. What differs on a phone is the
|
|
12
|
+
* platform underneath it (`nativePlatform()`) and the fact that the picture
|
|
13
|
+
* goes to a native view instead of an element.
|
|
14
|
+
*
|
|
15
|
+
* Unlike the browser, where a reconnect leaves the last frame in the `<video>`
|
|
16
|
+
* element, `streamURL` changes on every reconnect and an `RTCView` handed a
|
|
17
|
+
* new URL has nothing to show until the first frame decodes. `LiveVideo`
|
|
18
|
+
* holds the outgoing picture across that swap; if you render `RTCView`
|
|
19
|
+
* yourself and care, do the same.
|
|
20
|
+
*/
|
|
21
|
+
export function useLiveVideo(channel, options = {}) {
|
|
22
|
+
const [stream, setStream] = useState(null);
|
|
23
|
+
const [streamURL, setStreamURL] = useState(null);
|
|
24
|
+
const onStream = useCallback((next) => {
|
|
25
|
+
const ms = next;
|
|
26
|
+
setStream(ms);
|
|
27
|
+
setStreamURL(ms.toURL());
|
|
28
|
+
}, []);
|
|
29
|
+
const session = useLiveVideoSession(channel, {
|
|
30
|
+
onStream,
|
|
31
|
+
...(options.enabled !== undefined ? { enabled: options.enabled } : {}),
|
|
32
|
+
...(options.statsIntervalMs !== undefined
|
|
33
|
+
? { statsIntervalMs: options.statsIntervalMs }
|
|
34
|
+
: {}),
|
|
35
|
+
});
|
|
36
|
+
// Drop the stream when the session goes away (channel change, disable,
|
|
37
|
+
// unmount) — never on a reconnect, which replaces it through `onStream`.
|
|
38
|
+
const active = channel !== null && options.enabled !== false;
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!active)
|
|
41
|
+
return;
|
|
42
|
+
return () => {
|
|
43
|
+
setStream(null);
|
|
44
|
+
setStreamURL(null);
|
|
45
|
+
};
|
|
46
|
+
}, [active, channel?.channelRef, channel?.region]);
|
|
47
|
+
return { stream, streamURL, ...session };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=use-live-video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-live-video.js","sourceRoot":"","sources":["../src/use-live-video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AA8BrD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA4B,EAC5B,UAA+B,EAAE;IAEjC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAEhE,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,IAAa,EAAE,EAAE;QAC7C,MAAM,EAAE,GAAG,IAAmB,CAAC;QAC/B,SAAS,CAAC,EAAE,CAAC,CAAC;QACd,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,EAAE;QAC3C,QAAQ;QACR,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;YACvC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE;YAC9C,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IAEH,uEAAuE;IACvE,yEAAyE;IACzE,MAAM,MAAM,GAAG,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC;IAC7D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,YAAY,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC;AAC3C,CAAC"}
|
package/dist/wake.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** `XorgatePlatform["subscribeWake"]`: call `onWake`, get an unsubscribe back. */
|
|
2
|
+
export type WakeSource = (onWake: () => void) => () => void;
|
|
3
|
+
/**
|
|
4
|
+
* The foreground edge. This is the wake source a phone actually needs: iOS
|
|
5
|
+
* suspends the app's sockets within seconds of it leaving the screen, so both
|
|
6
|
+
* the MQTT connection and the peer connection are usually dead by the time the
|
|
7
|
+
* user comes back — and the live plane would otherwise sit out a backoff of up
|
|
8
|
+
* to 30 s in front of them. A browser tab has the same problem in miniature;
|
|
9
|
+
* `visibilitychange` is the web's version of this listener.
|
|
10
|
+
*
|
|
11
|
+
* Only the `active` edge counts. "inactive" is the app switcher or a system
|
|
12
|
+
* sheet over the app, where nothing has been torn down yet.
|
|
13
|
+
*/
|
|
14
|
+
export declare function appStateWake(onWake: () => void): () => void;
|
|
15
|
+
/**
|
|
16
|
+
* Fan one `onWake` out over several sources. Used to add "the network came
|
|
17
|
+
* back" to the foreground edge; see the README for the expo-network and
|
|
18
|
+
* NetInfo recipes, which are four lines each and stay in the consumer so this
|
|
19
|
+
* package needs neither as a dependency.
|
|
20
|
+
*
|
|
21
|
+
* A wake is a hint, never a command: the feeds and the video session ignore
|
|
22
|
+
* one while they are connected or mid-connect, so firing twice costs nothing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function composeWake(...sources: WakeSource[]): WakeSource;
|
|
25
|
+
//# sourceMappingURL=wake.d.ts.map
|