@pickleball/expo-sdk 0.2.0 → 1.0.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +155 -101
  3. package/dist/advanced-DcbHBCGb.d.ts +300 -0
  4. package/dist/advanced-DeQwg7MK.d.cts +300 -0
  5. package/dist/advanced.cjs +14 -2
  6. package/dist/advanced.d.cts +2 -2
  7. package/dist/advanced.d.ts +2 -2
  8. package/dist/advanced.js +17 -5
  9. package/dist/camera-controls-By8tHigY.d.cts +97 -0
  10. package/dist/camera-controls-rCBUGGPC.d.ts +97 -0
  11. package/dist/chunk-62YV3PCD.cjs +139 -0
  12. package/dist/chunk-6F3HN6US.js +50 -0
  13. package/dist/chunk-6YE5BL3A.cjs +50 -0
  14. package/dist/chunk-7Z7TN5N3.js +318 -0
  15. package/dist/{chunk-TRLASNPQ.cjs → chunk-GXQYMPHE.cjs} +1 -1
  16. package/dist/{chunk-TBPR2QND.cjs → chunk-IUIRVKJI.cjs} +736 -399
  17. package/dist/chunk-TBUEXRFQ.cjs +318 -0
  18. package/dist/{chunk-FODE2W2H.js → chunk-XGP2MN5R.js} +688 -351
  19. package/dist/{chunk-6JOMESNT.js → chunk-XL4CISVQ.js} +1 -1
  20. package/dist/chunk-ZSKSXOCZ.js +139 -0
  21. package/dist/convex-command-subscription-Cabh9tND.d.ts +41 -0
  22. package/dist/convex-command-subscription-DUgpu75l.d.cts +41 -0
  23. package/dist/device-agent/index.cjs +973 -44
  24. package/dist/device-agent/index.d.cts +339 -3
  25. package/dist/device-agent/index.d.ts +339 -3
  26. package/dist/device-agent/index.js +940 -11
  27. package/dist/{engine-CCSSqPbZ.d.cts → engine-BSvSdCSE.d.cts} +227 -2
  28. package/dist/{engine-CCSSqPbZ.d.ts → engine-BSvSdCSE.d.ts} +227 -2
  29. package/dist/index.cjs +419 -937
  30. package/dist/index.d.cts +315 -32
  31. package/dist/index.d.ts +315 -32
  32. package/dist/index.js +423 -941
  33. package/dist/plugin.cjs +11 -13
  34. package/dist/plugin.d.cts +15 -1
  35. package/dist/plugin.d.ts +15 -1
  36. package/dist/plugin.js +7 -9
  37. package/dist/realtime/index.cjs +31 -0
  38. package/dist/realtime/index.d.cts +15 -0
  39. package/dist/realtime/index.d.ts +15 -0
  40. package/dist/realtime/index.js +31 -0
  41. package/dist/ui/index.cjs +1297 -0
  42. package/dist/ui/index.d.cts +493 -0
  43. package/dist/ui/index.d.ts +493 -0
  44. package/dist/ui/index.js +1297 -0
  45. package/dist/version.cjs +2 -2
  46. package/dist/version.js +1 -1
  47. package/package.json +31 -15
  48. package/src/advanced.ts +11 -9
  49. package/src/auto-resume.tsx +259 -0
  50. package/src/camera-controls.ts +99 -0
  51. package/src/camera-grant-provider.ts +392 -0
  52. package/src/camera-settings.ts +133 -0
  53. package/src/contracts.ts +73 -0
  54. package/src/device-agent/agent.ts +262 -9
  55. package/src/device-agent/beat-policy.ts +46 -0
  56. package/src/device-agent/component.tsx +11 -0
  57. package/src/device-agent/convex-beat-transport.ts +140 -0
  58. package/src/device-agent/convex-command-subscription.ts +101 -0
  59. package/src/device-agent/convex-control-channel.ts +7 -1
  60. package/src/device-agent/http-transport.ts +22 -1
  61. package/src/device-agent/index.ts +22 -0
  62. package/src/device-agent/mqtt-channel.ts +379 -0
  63. package/src/device-agent/mqtt-codec.ts +347 -0
  64. package/src/device-agent/tournament.ts +352 -0
  65. package/src/engine.ts +580 -15
  66. package/src/http-session-provider.ts +21 -189
  67. package/src/index.ts +84 -5
  68. package/src/local-video-quality.ts +43 -0
  69. package/src/native-runtime.ts +234 -78
  70. package/src/plugin.ts +19 -6
  71. package/src/provider.tsx +94 -18
  72. package/src/realtime/index.ts +56 -0
  73. package/src/resume-policy.ts +85 -0
  74. package/src/resume.ts +132 -0
  75. package/src/rtmp-room-adapter.ts +164 -12
  76. package/src/session-grant.ts +256 -0
  77. package/src/ui/camera-screen.tsx +484 -0
  78. package/src/ui/controls-sheet.tsx +445 -0
  79. package/src/ui/copy.ts +326 -0
  80. package/src/ui/helpers.ts +105 -0
  81. package/src/ui/hooks.ts +59 -0
  82. package/src/ui/index.ts +42 -0
  83. package/src/ui/preview-view.tsx +39 -0
  84. package/src/ui/primitives.tsx +304 -0
  85. package/src/uplink-check.ts +173 -0
  86. package/dist/advanced-BXDrDl1h.d.ts +0 -316
  87. package/dist/advanced-BdAa2Erv.d.cts +0 -316
  88. package/src/livekit-room-adapter.ts +0 -390
  89. package/src/livestream-screen.tsx +0 -1002
@@ -0,0 +1,300 @@
1
+ import { R as RoomAdapter, a1 as RoomConnection, e as CameraDeviceInfo, g as CaptureOrientation, a2 as RoomEvent, r as SdkBootstrap, C as CameraGrant, b as SdkSessionGrant, y as SdkSessionRefresh, z as SdkTelemetryCredentials, a3 as EngineDependencies, w as SdkNetwork, x as SdkRuntime, a as SdkStorage, T as TelemetrySink, a0 as LivestreamEngine, B as BootstrapInput, m as LivestreamSnapshot, c as StartLivestreamInput, i as EndReason, L as LivestreamSessionProvider, H as SessionCommandChannel, S as SessionCommandSubscription, o as PickleballExpoError } from './engine-BSvSdCSE.cjs';
2
+ import React, { ReactNode } from 'react';
3
+
4
+ /**
5
+ * Trạng thái từ tầng RTMP native (trùng NativeRtmpStatus của @pickleball/rtmp-native).
6
+ */
7
+ type RtmpStatus = {
8
+ readonly status: "idle" | "connecting" | "connected" | "publishing";
9
+ } | {
10
+ readonly status: "disconnected";
11
+ readonly reason?: string;
12
+ } | {
13
+ readonly status: "error";
14
+ readonly code: string;
15
+ readonly message: string;
16
+ };
17
+ /** Phản hồi băng thông từ native (trùng NativeRtmpBandwidth của rtmp-native). */
18
+ interface RtmpBandwidth {
19
+ /** false = encoder đang đẩy nhanh hơn đường truyền chịu được. */
20
+ readonly sufficient: boolean;
21
+ readonly videoBitrate: number;
22
+ }
23
+ /**
24
+ * Dấu hiệu để UI biết render nguồn nào. LiveKit trả về một track object; RTMP
25
+ * không có "track" ở JS (khung hình đi thẳng trong native), nên trả marker này
26
+ * — nếu trả undefined thì UI tưởng chưa có preview và vẽ màn TỐI ĐEN.
27
+ */
28
+ interface RtmpPreviewMarker {
29
+ readonly kind: "rtmp";
30
+ }
31
+ /** Bề mặt native mà adapter cần — tiêm vào để test được không cần thiết bị thật. */
32
+ interface NativeRtmpBindings {
33
+ prepare(options: {
34
+ quality: 720 | 1080;
35
+ landscape: boolean;
36
+ /** fps mong muốn (24 tiết kiệm băng thông, 30 mặc định) — thiếu = native tự chọn. */
37
+ frameRate?: 24 | 30 | 60;
38
+ /**
39
+ * Camera mở ngay từ đầu. Thiếu = native dùng camera sau mặc định. Đặt ở đây
40
+ * thay vì gọi selectCamera sau prepare để không phải mở camera hai lần.
41
+ */
42
+ cameraId?: string;
43
+ }): Promise<void>;
44
+ /**
45
+ * Xin quyền camera/mic bằng API quyền thuần (PermissionsAndroid, ...).
46
+ * Không có thì engine rơi về getUserMedia của WebRTC — thứ mở camera thật
47
+ * và đụng HaishinKit trên máy Android chỉ cho một camera mở cùng lúc.
48
+ */
49
+ requestPermissions?(): Promise<boolean>;
50
+ /** Hướng cầm máy hiện tại — cùng nguồn mà LiveKitRoomAdapter dùng. */
51
+ isLandscape?(): boolean;
52
+ connect(options: {
53
+ url: string;
54
+ videoBitrate: number;
55
+ publish: boolean;
56
+ }): Promise<void>;
57
+ setPublishing(enabled: boolean): Promise<void>;
58
+ disconnect(): Promise<void>;
59
+ switchCamera(): Promise<void>;
60
+ listCameras(): Array<{
61
+ deviceId: string;
62
+ label: string;
63
+ facing: string;
64
+ }>;
65
+ selectCamera(deviceId: string, facing: string): Promise<void>;
66
+ setMicrophoneEnabled(enabled: boolean): Promise<void>;
67
+ setVideoBitrate(bitsPerSecond: number): Promise<void>;
68
+ dispose(): Promise<void>;
69
+ addStatusListener(listener: (event: RtmpStatus) => void): {
70
+ remove(): void;
71
+ };
72
+ /** Optional: bản native cũ chưa phát onBandwidth thì adapter bỏ qua thích ứng. */
73
+ addBandwidthListener?(listener: (event: RtmpBandwidth) => void): {
74
+ remove(): void;
75
+ };
76
+ }
77
+ /**
78
+ * Adapter cho mode deliveryMode="device-rtmp".
79
+ *
80
+ * Thiết bị mã hoá H.264 bằng phần cứng MỘT lần rồi đẩy thẳng RTMP; server chỉ
81
+ * remux sang HLS. Không có phòng LiveKit, không egress → $0 transcode.
82
+ *
83
+ * Khác LiveKitRoomAdapter ở một điểm quan trọng: RTMP **không có kênh dữ liệu**,
84
+ * nên adapter này không bao giờ phát RoomEvent "command". Lệnh điều khiển từ
85
+ * dashboard đi đường khác (deviceControl trên Convex) — xem device-agent.
86
+ */
87
+ declare class RtmpRoomAdapter implements RoomAdapter {
88
+ private readonly bindings;
89
+ private readonly options;
90
+ /**
91
+ * RTMP không tự hồi: native chỉ phát hiện đứt (watchdog iOS / onDisconnect
92
+ * Android) và báo "disconnected" — không tự quay số lại. Engine thấy cờ này
93
+ * là chạy vòng redial backoff. Thiếu cờ: phiên ngồi chờ "reconnected" không
94
+ * bao giờ tới rồi chết network_timeout sau 30s (prod 17/08/2026).
95
+ */
96
+ readonly needsManualReconnect = true;
97
+ private readonly listeners;
98
+ private nativeSubscription?;
99
+ private bandwidthSubscription?;
100
+ private quality;
101
+ private connected;
102
+ private prepared;
103
+ /** Khung người dùng chọn trên UI (9:16/16:9) — ưu tiên hơn hướng cầm máy. */
104
+ private captureOrientation?;
105
+ private bitrateState?;
106
+ /**
107
+ * Chỉ tồn tại khi bindings hỗ trợ — engine kiểm tra truthiness để quyết định
108
+ * fallback về runtime.requestPermissions() (getUserMedia), nên KHÔNG được
109
+ * khai báo method luôn-có rồi tự fallback bên trong.
110
+ */
111
+ readonly requestPermissions?: () => Promise<boolean>;
112
+ constructor(bindings: NativeRtmpBindings, options?: {
113
+ frameRate?: 24 | 30 | 60;
114
+ cameraId?: string;
115
+ });
116
+ /**
117
+ * Phần tuỳ chọn của prepare(). Giữ dạng spread có điều kiện: truyền
118
+ * `frameRate: undefined` xuống Expo Record là ghi đè mặc định của native
119
+ * bằng null chứ không phải "bỏ qua trường".
120
+ */
121
+ private prepareOverrides;
122
+ preparePreview(quality: 720 | 1080): Promise<RtmpPreviewMarker>;
123
+ connect(input: RoomConnection): Promise<void>;
124
+ setPublishing(enabled: boolean): Promise<void>;
125
+ disconnect(_stopTracks?: boolean): Promise<void>;
126
+ switchCamera(): Promise<void>;
127
+ /** Ống kính vật lý (0.5x siêu rộng · 1x · tele) — không có thì UI kẹt ở mặc định. */
128
+ listCameras(): Promise<CameraDeviceInfo[]>;
129
+ selectCamera(deviceId: string, facing: CameraDeviceInfo["facing"]): Promise<void>;
130
+ setMicrophoneEnabled(enabled: boolean): Promise<void>;
131
+ /** Hạ chất lượng khi mạng yếu — thay cho BWE mà WebRTC cho sẵn. */
132
+ setVideoBitrate(bitsPerSecond: number): Promise<void>;
133
+ setCaptureOrientation(orientation: CaptureOrientation): Promise<void>;
134
+ subscribe(listener: (event: RoomEvent) => void): () => void;
135
+ dispose(): Promise<void>;
136
+ private handleBandwidth;
137
+ private emit;
138
+ }
139
+
140
+ /**
141
+ * Validator + helper HTTP dùng chung cho hai session provider:
142
+ * - createHttpSessionProvider (proxy đối tác / first-party device-app)
143
+ * - createCameraGrantProvider (điện thoại đối tác, grant từ backend đối tác)
144
+ *
145
+ * Tách ra để hai provider không chép luật "grant thế nào là hợp lệ" ra hai nơi
146
+ * rồi lệch nhau; engine chỉ tin `isSdkRemoteConfig`, còn hình dạng grant là
147
+ * việc của lớp này.
148
+ */
149
+ type Fetch = typeof globalThis.fetch;
150
+ declare function isBootstrap(value: unknown): value is SdkBootstrap;
151
+ declare function isTelemetryCredentials(value: unknown): value is SdkTelemetryCredentials;
152
+ /**
153
+ * Grant phiên. SDK 1.0 là RTMP-only: `serverUrl` phải là rtmp(s):// (ingest).
154
+ * Grant LiveKit (wss://) của mô hình cũ bị từ chối ngay ở đây — lỗi
155
+ * INVALID_RESPONSE rõ ràng thay vì HaishinKit ném lúc connect.
156
+ */
157
+ declare function isSessionGrant(value: unknown): value is SdkSessionGrant;
158
+ /**
159
+ * Camera grant (điện thoại đối tác): superset của SdkSessionGrant, BẮT BUỘC là
160
+ * RTMP và mang `status` để đường nhận lại biết phiên cũ đang phát hay đang chờ.
161
+ */
162
+ declare function isCameraGrant(value: unknown): value is CameraGrant;
163
+ declare function isSessionRefresh(value: unknown): value is SdkSessionRefresh;
164
+ /**
165
+ * Gốc API của phiên suy từ endpoint telemetry trong grant: `…/sessions/{id}/telemetry`
166
+ * → `…/sessions/{id}`. Đây là cách duy nhất SDK biết namespace (sdk / camera /
167
+ * device-app) mà không cần app cấu hình URL PickLive nào.
168
+ */
169
+ declare function sessionApiBaseFromTelemetryEndpoint(endpoint: string): string;
170
+
171
+ /**
172
+ * Runtime cho app RTMP-only (KHÔNG có LiveKit/WebRTC): assert bằng module
173
+ * @pickleball/rtmp-native, xin quyền bằng API quyền thuần (Android) hoặc hàm
174
+ * native `requestPermissions` (iOS, rtmp-native ≥ 0.2; thiếu thì AVFoundation
175
+ * hỏi lúc mở camera). Chuyển từ apps/device-streamer (createRtmpOnlyRuntime).
176
+ * Không dùng getUserMedia: máy MediaTek chỉ cho một camera mở cùng lúc.
177
+ */
178
+ declare function createRtmpRuntime(): SdkRuntime;
179
+ /** Runtime mặc định của SDK 1.0 = RTMP (LiveKit đã gỡ khỏi SDK — ADR-0002). */
180
+ declare const createDefaultRuntime: typeof createRtmpRuntime;
181
+ declare function createDefaultStorage(): SdkStorage;
182
+ declare function createDefaultNetwork(): SdkNetwork;
183
+ declare function createDefaultTelemetry(fetchImplementation?: typeof fetch, timeoutMs?: number): TelemetrySink;
184
+ /** roomFactory mặc định của SDK 1.0 = RTMP (fps/camera mặc định của native). */
185
+ declare function createDefaultRoomFactory(): EngineDependencies["roomFactory"];
186
+ /**
187
+ * Bindings native RTMP. `require` động: app chưa cài @pickleball/rtmp-native
188
+ * chỉ lỗi khi thật sự mở camera (UnsupportedRuntimeError rõ ràng), không gãy
189
+ * lúc import SDK — static-render web của expo-router vẫn nạp được module.
190
+ */
191
+ declare function createNativeRtmpBindings(): NativeRtmpBindings;
192
+ /** roomFactory cho mode device-rtmp (thiết bị đẩy RTMP, không dùng LiveKit). */
193
+ declare function createRtmpRoomFactory(options?: {
194
+ /**
195
+ * fps capture + encode (24 tiết kiệm băng thông, 30 mặc định của native).
196
+ * 60 chỉ nên truyền khi `getCameraCapabilities().supportedFrameRates` có nó —
197
+ * native bỏ qua trong im lặng nếu ống kính đang gắn không chạy được.
198
+ */
199
+ frameRate?: 24 | 30 | 60;
200
+ /** Camera mở sẵn lúc prepare — thiếu = camera sau mặc định của native. */
201
+ cameraId?: string;
202
+ }): EngineDependencies["roomFactory"];
203
+ /**
204
+ * Thu chỉ số thiết bị cho heartbeat. Mỗi nguồn là optional — thiếu package
205
+ * (expo-battery/expo-device/expo-file-system) thì bỏ qua trường đó thay vì lỗi.
206
+ */
207
+ declare function createDefaultDeviceMetrics(): NonNullable<EngineDependencies["deviceMetrics"]>;
208
+
209
+ interface LivestreamTheme {
210
+ background: string;
211
+ foreground: string;
212
+ accent: string;
213
+ danger: string;
214
+ /** Chữ phụ mờ nhất (labels, chú thích). */
215
+ muted: string;
216
+ overlay: string;
217
+ radius: number;
218
+ /** Token FintechX — đồng bộ với dashboard web. */
219
+ surface: string;
220
+ elevated: string;
221
+ hairline: string;
222
+ /** Màu chữ đặt trên nền accent. */
223
+ ink: string;
224
+ textSecondary: string;
225
+ radiusSm: number;
226
+ fontFamily?: string;
227
+ fontFamilyBold?: string;
228
+ displayFontFamily?: string;
229
+ }
230
+ /** FintechX design tokens — trùng bộ token trong apps/web/globals.css. */
231
+ declare const defaultLivestreamTheme: LivestreamTheme;
232
+ interface PickleballLiveProviderProps {
233
+ children?: ReactNode;
234
+ sessionProvider: LivestreamSessionProvider;
235
+ bootstrapInput: BootstrapInput;
236
+ /**
237
+ * Phiên phải SỐNG TIẾP khi app biến mất giữa chừng (sụp nguồn, bị vuốt tắt,
238
+ * component remount), để lần mở sau nhận lại đúng phiên cũ — giữ nguyên link
239
+ * xem và VOD liền một mạch.
240
+ *
241
+ * Mặc định false = hành vi cũ: mở app lại là dọn sạch phiên cũ. App gác sân bật
242
+ * cờ này khi máy đang được gán sân; máy không gán sân vẫn dọn như cũ để không
243
+ * để lại phiên treo trong các ca ngoài giải.
244
+ *
245
+ * Nhận boolean HOẶC hàm (được phép async). App nên truyền HÀM ĐỌC THẲNG ĐĨA:
246
+ * engine hỏi cờ này đúng lúc khởi động, thường TRƯỚC khi state React kịp
247
+ * restore — truyền boolean suy từ state là dính race keep=false oan (đã dính
248
+ * thật 18/08/2026, sinh phiên chờ thứ hai đè phiên live cũ).
249
+ */
250
+ keepSessionOnRestart?: boolean | (() => boolean | Promise<boolean>);
251
+ runtime?: SdkRuntime;
252
+ storage?: SdkStorage;
253
+ network?: SdkNetwork;
254
+ telemetry?: TelemetrySink;
255
+ /** Kênh poll lệnh cho mode device-rtmp — mặc định suy từ telemetry endpoint. */
256
+ commandChannel?: SessionCommandChannel;
257
+ /**
258
+ * Kênh nhận lệnh qua websocket (first-party nối thẳng Convex). Có thì lệnh về
259
+ * tức thì và poll tụt về nhịp reconcile chậm — cắt phần lớn function call của
260
+ * đường poll. Thiếu (máy đối tác qua proxy) thì chỉ dùng poll HTTP như cũ.
261
+ */
262
+ commandSubscription?: SessionCommandSubscription;
263
+ roomFactory?: () => RoomAdapter;
264
+ deviceMetrics?: EngineDependencies["deviceMetrics"];
265
+ theme?: Partial<LivestreamTheme>;
266
+ locale?: "vi" | "en";
267
+ onError?: (error: PickleballExpoError) => void;
268
+ }
269
+ /**
270
+ * Context nội bộ cho các module opt-in (VD PickleballDeviceAgent) cần truy cập
271
+ * engine trực tiếp — export qua "./advanced", không thuộc API tích hợp cơ bản.
272
+ */
273
+ interface LivestreamHostContextValue {
274
+ engine: LivestreamEngine;
275
+ bootstrapInput: BootstrapInput;
276
+ deviceMetrics: NonNullable<EngineDependencies["deviceMetrics"]>;
277
+ }
278
+ declare function useLivestreamHost(): LivestreamHostContextValue;
279
+ interface LivestreamContextValue extends LivestreamSnapshot {
280
+ locale: "vi" | "en";
281
+ theme: LivestreamTheme;
282
+ prepare(): Promise<void>;
283
+ start(input: StartLivestreamInput, options?: {
284
+ autoPublish?: boolean;
285
+ }): Promise<void>;
286
+ /** Bắt đầu phát khi đang standby. */
287
+ startPublishing(): Promise<void>;
288
+ /** Tạm dừng phát về standby (không kết thúc phiên). */
289
+ stopPublishing(): Promise<void>;
290
+ stop(reason?: EndReason): Promise<void>;
291
+ retry(): Promise<void>;
292
+ switchCamera(): Promise<void>;
293
+ setMicrophoneEnabled(enabled: boolean): Promise<void>;
294
+ setCaptureOrientation(orientation: "portrait" | "landscape"): Promise<void>;
295
+ selectCamera(deviceId: string): Promise<void>;
296
+ }
297
+ declare function PickleballLiveProvider(props: PickleballLiveProviderProps): React.JSX.Element;
298
+ declare function useLivestream(): LivestreamContextValue;
299
+
300
+ export { type Fetch as F, type LivestreamContextValue as L, type NativeRtmpBindings as N, PickleballLiveProvider as P, RtmpRoomAdapter as R, type LivestreamTheme as a, type PickleballLiveProviderProps as b, createDefaultStorage as c, createRtmpRoomFactory as d, createRtmpRuntime as e, defaultLivestreamTheme as f, type LivestreamHostContextValue as g, type RtmpStatus as h, createDefaultDeviceMetrics as i, createDefaultNetwork as j, createDefaultRoomFactory as k, createDefaultRuntime as l, createDefaultTelemetry as m, createNativeRtmpBindings as n, isBootstrap as o, isCameraGrant as p, isSessionGrant as q, isSessionRefresh as r, isTelemetryCredentials as s, sessionApiBaseFromTelemetryEndpoint as t, useLivestream as u, useLivestreamHost as v };
package/dist/advanced.cjs CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
 
7
7
 
8
+ var _chunk62YV3PCDcjs = require('./chunk-62YV3PCD.cjs');
8
9
 
9
10
 
10
11
 
@@ -14,7 +15,13 @@
14
15
 
15
16
 
16
17
 
17
- var _chunkTBPR2QNDcjs = require('./chunk-TBPR2QND.cjs');
18
+
19
+
20
+
21
+
22
+
23
+
24
+ var _chunkIUIRVKJIcjs = require('./chunk-IUIRVKJI.cjs');
18
25
  require('./chunk-7OX2DSKI.cjs');
19
26
 
20
27
 
@@ -32,4 +39,9 @@ require('./chunk-7OX2DSKI.cjs');
32
39
 
33
40
 
34
41
 
35
- exports.LEGAL_LIVESTREAM_TRANSITIONS = _chunkTBPR2QNDcjs.LEGAL_LIVESTREAM_TRANSITIONS; exports.LiveKitRoomAdapter = _chunkTBPR2QNDcjs.LiveKitRoomAdapter; exports.LivestreamEngine = _chunkTBPR2QNDcjs.LivestreamEngine; exports.PENDING_END_KEY = _chunkTBPR2QNDcjs.PENDING_END_KEY; exports.RtmpRoomAdapter = _chunkTBPR2QNDcjs.RtmpRoomAdapter; exports.createDefaultDeviceMetrics = _chunkTBPR2QNDcjs.createDefaultDeviceMetrics; exports.createDefaultNetwork = _chunkTBPR2QNDcjs.createDefaultNetwork; exports.createDefaultRoomFactory = _chunkTBPR2QNDcjs.createDefaultRoomFactory; exports.createDefaultRuntime = _chunkTBPR2QNDcjs.createDefaultRuntime; exports.createDefaultStorage = _chunkTBPR2QNDcjs.createDefaultStorage; exports.createDefaultTelemetry = _chunkTBPR2QNDcjs.createDefaultTelemetry; exports.createNativeLiveKitBindings = _chunkTBPR2QNDcjs.createNativeLiveKitBindings; exports.createNativeRtmpBindings = _chunkTBPR2QNDcjs.createNativeRtmpBindings; exports.createRtmpRoomFactory = _chunkTBPR2QNDcjs.createRtmpRoomFactory; exports.useLivestreamHost = _chunkTBPR2QNDcjs.useLivestreamHost;
42
+
43
+
44
+
45
+
46
+
47
+ exports.LEGAL_LIVESTREAM_TRANSITIONS = _chunkIUIRVKJIcjs.LEGAL_LIVESTREAM_TRANSITIONS; exports.LivestreamEngine = _chunkIUIRVKJIcjs.LivestreamEngine; exports.PENDING_END_KEY = _chunkIUIRVKJIcjs.PENDING_END_KEY; exports.RtmpRoomAdapter = _chunkIUIRVKJIcjs.RtmpRoomAdapter; exports.createDefaultDeviceMetrics = _chunkIUIRVKJIcjs.createDefaultDeviceMetrics; exports.createDefaultNetwork = _chunkIUIRVKJIcjs.createDefaultNetwork; exports.createDefaultRoomFactory = _chunkIUIRVKJIcjs.createDefaultRoomFactory; exports.createDefaultRuntime = _chunkIUIRVKJIcjs.createDefaultRuntime; exports.createDefaultStorage = _chunkIUIRVKJIcjs.createDefaultStorage; exports.createDefaultTelemetry = _chunkIUIRVKJIcjs.createDefaultTelemetry; exports.createNativeRtmpBindings = _chunkIUIRVKJIcjs.createNativeRtmpBindings; exports.createRtmpRoomFactory = _chunkIUIRVKJIcjs.createRtmpRoomFactory; exports.createRtmpRuntime = _chunkIUIRVKJIcjs.createRtmpRuntime; exports.isBootstrap = _chunk62YV3PCDcjs.isBootstrap; exports.isCameraGrant = _chunk62YV3PCDcjs.isCameraGrant; exports.isSessionGrant = _chunk62YV3PCDcjs.isSessionGrant; exports.isSessionRefresh = _chunk62YV3PCDcjs.isSessionRefresh; exports.isTelemetryCredentials = _chunk62YV3PCDcjs.isTelemetryCredentials; exports.sessionApiBaseFromTelemetryEndpoint = _chunk62YV3PCDcjs.sessionApiBaseFromTelemetryEndpoint; exports.useLivestreamHost = _chunkIUIRVKJIcjs.useLivestreamHost;
@@ -1,3 +1,3 @@
1
- export { C as CameraDeviceInfo, a as CaptureOrientation, D as DeviceMetricsSample, X as EngineDependencies, Y as LEGAL_LIVESTREAM_TRANSITIONS, Q as LivestreamEngine, g as LivestreamSnapshot, Z as PENDING_END_KEY, j as RoomAdapter, V as RoomConnection, W as RoomEvent, p as SdkNetwork, r as SdkRuntime, u as SdkStorage, T as TelemetrySink } from './engine-CCSSqPbZ.cjs';
2
- export { e as LiveKitRoomAdapter, f as LivestreamHostContextValue, g as LocalPreviewReference, N as NativeLiveKitBindings, h as NativeRtmpBindings, R as RtmpRoomAdapter, i as RtmpStatus, j as createDefaultDeviceMetrics, k as createDefaultNetwork, l as createDefaultRoomFactory, m as createDefaultRuntime, c as createDefaultStorage, n as createDefaultTelemetry, o as createNativeLiveKitBindings, p as createNativeRtmpBindings, q as createRtmpRoomFactory, r as useLivestreamHost } from './advanced-BdAa2Erv.cjs';
1
+ export { e as CameraDeviceInfo, g as CaptureOrientation, D as DeviceMetricsSample, a3 as EngineDependencies, a4 as LEGAL_LIVESTREAM_TRANSITIONS, a0 as LivestreamEngine, m as LivestreamSnapshot, a5 as PENDING_END_KEY, R as RoomAdapter, a1 as RoomConnection, a2 as RoomEvent, w as SdkNetwork, x as SdkRuntime, a as SdkStorage, H as SessionCommandChannel, T as TelemetrySink } from './engine-BSvSdCSE.cjs';
2
+ export { g as LivestreamHostContextValue, N as NativeRtmpBindings, R as RtmpRoomAdapter, h as RtmpStatus, i as createDefaultDeviceMetrics, j as createDefaultNetwork, k as createDefaultRoomFactory, l as createDefaultRuntime, c as createDefaultStorage, m as createDefaultTelemetry, n as createNativeRtmpBindings, d as createRtmpRoomFactory, e as createRtmpRuntime, o as isBootstrap, p as isCameraGrant, q as isSessionGrant, r as isSessionRefresh, s as isTelemetryCredentials, t as sessionApiBaseFromTelemetryEndpoint, v as useLivestreamHost } from './advanced-DeQwg7MK.cjs';
3
3
  import 'react';
@@ -1,3 +1,3 @@
1
- export { C as CameraDeviceInfo, a as CaptureOrientation, D as DeviceMetricsSample, X as EngineDependencies, Y as LEGAL_LIVESTREAM_TRANSITIONS, Q as LivestreamEngine, g as LivestreamSnapshot, Z as PENDING_END_KEY, j as RoomAdapter, V as RoomConnection, W as RoomEvent, p as SdkNetwork, r as SdkRuntime, u as SdkStorage, T as TelemetrySink } from './engine-CCSSqPbZ.js';
2
- export { e as LiveKitRoomAdapter, f as LivestreamHostContextValue, g as LocalPreviewReference, N as NativeLiveKitBindings, h as NativeRtmpBindings, R as RtmpRoomAdapter, i as RtmpStatus, j as createDefaultDeviceMetrics, k as createDefaultNetwork, l as createDefaultRoomFactory, m as createDefaultRuntime, c as createDefaultStorage, n as createDefaultTelemetry, o as createNativeLiveKitBindings, p as createNativeRtmpBindings, q as createRtmpRoomFactory, r as useLivestreamHost } from './advanced-BXDrDl1h.js';
1
+ export { e as CameraDeviceInfo, g as CaptureOrientation, D as DeviceMetricsSample, a3 as EngineDependencies, a4 as LEGAL_LIVESTREAM_TRANSITIONS, a0 as LivestreamEngine, m as LivestreamSnapshot, a5 as PENDING_END_KEY, R as RoomAdapter, a1 as RoomConnection, a2 as RoomEvent, w as SdkNetwork, x as SdkRuntime, a as SdkStorage, H as SessionCommandChannel, T as TelemetrySink } from './engine-BSvSdCSE.js';
2
+ export { g as LivestreamHostContextValue, N as NativeRtmpBindings, R as RtmpRoomAdapter, h as RtmpStatus, i as createDefaultDeviceMetrics, j as createDefaultNetwork, k as createDefaultRoomFactory, l as createDefaultRuntime, c as createDefaultStorage, m as createDefaultTelemetry, n as createNativeRtmpBindings, d as createRtmpRoomFactory, e as createRtmpRuntime, o as isBootstrap, p as isCameraGrant, q as isSessionGrant, r as isSessionRefresh, s as isTelemetryCredentials, t as sessionApiBaseFromTelemetryEndpoint, v as useLivestreamHost } from './advanced-DcbHBCGb.js';
3
3
  import 'react';
package/dist/advanced.js CHANGED
@@ -1,6 +1,13 @@
1
+ import {
2
+ isBootstrap,
3
+ isCameraGrant,
4
+ isSessionGrant,
5
+ isSessionRefresh,
6
+ isTelemetryCredentials,
7
+ sessionApiBaseFromTelemetryEndpoint
8
+ } from "./chunk-ZSKSXOCZ.js";
1
9
  import {
2
10
  LEGAL_LIVESTREAM_TRANSITIONS,
3
- LiveKitRoomAdapter,
4
11
  LivestreamEngine,
5
12
  PENDING_END_KEY,
6
13
  RtmpRoomAdapter,
@@ -10,15 +17,14 @@ import {
10
17
  createDefaultRuntime,
11
18
  createDefaultStorage,
12
19
  createDefaultTelemetry,
13
- createNativeLiveKitBindings,
14
20
  createNativeRtmpBindings,
15
21
  createRtmpRoomFactory,
22
+ createRtmpRuntime,
16
23
  useLivestreamHost
17
- } from "./chunk-FODE2W2H.js";
24
+ } from "./chunk-XGP2MN5R.js";
18
25
  import "./chunk-KFQGP6VL.js";
19
26
  export {
20
27
  LEGAL_LIVESTREAM_TRANSITIONS,
21
- LiveKitRoomAdapter,
22
28
  LivestreamEngine,
23
29
  PENDING_END_KEY,
24
30
  RtmpRoomAdapter,
@@ -28,8 +34,14 @@ export {
28
34
  createDefaultRuntime,
29
35
  createDefaultStorage,
30
36
  createDefaultTelemetry,
31
- createNativeLiveKitBindings,
32
37
  createNativeRtmpBindings,
33
38
  createRtmpRoomFactory,
39
+ createRtmpRuntime,
40
+ isBootstrap,
41
+ isCameraGrant,
42
+ isSessionGrant,
43
+ isSessionRefresh,
44
+ isTelemetryCredentials,
45
+ sessionApiBaseFromTelemetryEndpoint,
34
46
  useLivestreamHost
35
47
  };
@@ -0,0 +1,97 @@
1
+ import { a as SdkStorage, R as RoomAdapter } from './engine-BSvSdCSE.cjs';
2
+
3
+ /**
4
+ * Cấu hình camera LOCAL — không phụ thuộc server, sống qua OTA (chuyển từ
5
+ * apps/device-streamer/src/local-config.ts). Resolution override videoQuality
6
+ * qua withLocalVideoQuality; fps + cameraId đi vào createRtmpRoomFactory. Đổi
7
+ * resolution/fps/cameraId → remount provider (dùng cameraSettingsKey làm `key`)
8
+ * để engine re-prepare.
9
+ */
10
+ type AntiFlickerMode = "auto" | "50hz" | "60hz";
11
+ interface CameraSettings {
12
+ resolution: 720 | 1080;
13
+ /** 60 chỉ chọn được khi capabilities của lens đang gắn báo hỗ trợ. */
14
+ fps: 24 | 30 | 60;
15
+ /**
16
+ * Chống chớp đèn. Mặc định "50hz" (lưới điện VN) chứ KHÔNG phải "auto": để
17
+ * auto là giao cho HAL đoán tần số, HyperOS đoán trật 60Hz thường xuyên → đèn
18
+ * LED trong nhà vằn trên sóng. Android-only hiện tại.
19
+ */
20
+ antiFlicker: AntiFlickerMode;
21
+ /**
22
+ * Camera mặc định mỗi lần mở app. null = camera sau mặc định của native. Cần
23
+ * vì máy thật có nhiều camera trùng nhãn (Redmi Note 15: hai "Back Camera").
24
+ */
25
+ cameraId: string | null;
26
+ }
27
+ declare const CAMERA_SETTINGS_STORAGE_KEY = "@pickleball/expo-sdk/camera-settings";
28
+ declare const DEFAULT_CAMERA_SETTINGS: CameraSettings;
29
+ /** Parse thuần — giá trị lạ/thiếu rơi về mặc định (config cũ chưa có field vẫn đọc được). */
30
+ declare function parseCameraSettings(raw: string | null, defaults?: CameraSettings): CameraSettings;
31
+ interface CameraSettingsStore {
32
+ readonly key: string;
33
+ get(): CameraSettings;
34
+ set(patch: Partial<CameraSettings>): void;
35
+ subscribe(listener: () => void): () => void;
36
+ /** Nạp từ đĩa; gọi một lần lúc app khởi động. */
37
+ restore(): Promise<void>;
38
+ isRestored(): boolean;
39
+ }
40
+ interface CameraSettingsStoreOptions {
41
+ storage?: SdkStorage;
42
+ /** Khoá lưu — app fleet giữ khoá cũ để setting sống qua OTA. */
43
+ key?: string;
44
+ defaults?: Partial<CameraSettings>;
45
+ }
46
+ declare function createCameraSettingsStore(options?: CameraSettingsStoreOptions): CameraSettingsStore;
47
+ declare function useCameraSettings(store: CameraSettingsStore): CameraSettings;
48
+ /** `key` cho PickleballLiveProvider: đổi giá trị → remount → engine re-prepare đúng cấu hình. */
49
+ declare function cameraSettingsKey(settings: CameraSettings): string;
50
+ /** roomFactory RTMP theo cấu hình (fps + camera mặc định). */
51
+ declare function rtmpRoomFactoryFor(settings: CameraSettings): () => RoomAdapter;
52
+
53
+ /**
54
+ * Điều khiển camera RUNTIME (zoom, EV, khoá nét/sáng, đèn pin, chống chớp) —
55
+ * gọi THẲNG native module @pickleball/rtmp-native (singleton), chủ ý bypass
56
+ * engine/adapter vì đây là tinh chỉnh camera, không phải lifecycle phiên.
57
+ *
58
+ * Mọi hàm `typeof`-guard: binary cũ (rtmp-native 0.1.0 trên fleet 1.0.2) thiếu
59
+ * vài hàm thì trả null/no-op thay vì ném — UI ẩn control tương ứng.
60
+ */
61
+ interface CameraCapabilityRange {
62
+ min: number;
63
+ max: number;
64
+ supported: boolean;
65
+ }
66
+ interface CameraCapabilities {
67
+ zoom: CameraCapabilityRange;
68
+ exposureBias: CameraCapabilityRange & {
69
+ step?: number;
70
+ };
71
+ torch: {
72
+ supported: boolean;
73
+ };
74
+ focusLock: {
75
+ supported: boolean;
76
+ };
77
+ exposureLock: {
78
+ supported: boolean;
79
+ };
80
+ supportedFrameRates?: number[];
81
+ }
82
+ /** Bounds + cờ hỗ trợ của lens đang gắn; null khi module/hàm chưa có. */
83
+ declare function getCameraCapabilities(): Promise<CameraCapabilities | null>;
84
+ declare function setZoom(factor: number): Promise<void>;
85
+ declare function setExposureBias(ev: number): Promise<void>;
86
+ declare function setFocusLocked(locked: boolean): Promise<void>;
87
+ declare function setExposureLocked(locked: boolean): Promise<void>;
88
+ declare function setTorch(enabled: boolean): Promise<void>;
89
+ /** Android-only: iOS/binary cũ thiếu hàm → no-op. Native tự áp lại mỗi lần mở camera/đổi lens. */
90
+ declare function applyAntiFlicker(mode: "auto" | "50hz" | "60hz"): Promise<void>;
91
+ /**
92
+ * Xin quyền camera/mic qua native (iOS, rtmp-native ≥ 0.2). null = native chưa
93
+ * có hàm → caller tự quyết (AVFoundation sẽ hỏi lúc mở camera).
94
+ */
95
+ declare function requestNativePermissions(): Promise<boolean | null>;
96
+
97
+ export { type AntiFlickerMode as A, CAMERA_SETTINGS_STORAGE_KEY as C, DEFAULT_CAMERA_SETTINGS as D, type CameraCapabilities as a, type CameraCapabilityRange as b, type CameraSettings as c, type CameraSettingsStore as d, type CameraSettingsStoreOptions as e, applyAntiFlicker as f, cameraSettingsKey as g, createCameraSettingsStore as h, getCameraCapabilities as i, rtmpRoomFactoryFor as j, setExposureLocked as k, setFocusLocked as l, setTorch as m, setZoom as n, parseCameraSettings as p, requestNativePermissions as r, setExposureBias as s, useCameraSettings as u };
@@ -0,0 +1,97 @@
1
+ import { a as SdkStorage, R as RoomAdapter } from './engine-BSvSdCSE.js';
2
+
3
+ /**
4
+ * Cấu hình camera LOCAL — không phụ thuộc server, sống qua OTA (chuyển từ
5
+ * apps/device-streamer/src/local-config.ts). Resolution override videoQuality
6
+ * qua withLocalVideoQuality; fps + cameraId đi vào createRtmpRoomFactory. Đổi
7
+ * resolution/fps/cameraId → remount provider (dùng cameraSettingsKey làm `key`)
8
+ * để engine re-prepare.
9
+ */
10
+ type AntiFlickerMode = "auto" | "50hz" | "60hz";
11
+ interface CameraSettings {
12
+ resolution: 720 | 1080;
13
+ /** 60 chỉ chọn được khi capabilities của lens đang gắn báo hỗ trợ. */
14
+ fps: 24 | 30 | 60;
15
+ /**
16
+ * Chống chớp đèn. Mặc định "50hz" (lưới điện VN) chứ KHÔNG phải "auto": để
17
+ * auto là giao cho HAL đoán tần số, HyperOS đoán trật 60Hz thường xuyên → đèn
18
+ * LED trong nhà vằn trên sóng. Android-only hiện tại.
19
+ */
20
+ antiFlicker: AntiFlickerMode;
21
+ /**
22
+ * Camera mặc định mỗi lần mở app. null = camera sau mặc định của native. Cần
23
+ * vì máy thật có nhiều camera trùng nhãn (Redmi Note 15: hai "Back Camera").
24
+ */
25
+ cameraId: string | null;
26
+ }
27
+ declare const CAMERA_SETTINGS_STORAGE_KEY = "@pickleball/expo-sdk/camera-settings";
28
+ declare const DEFAULT_CAMERA_SETTINGS: CameraSettings;
29
+ /** Parse thuần — giá trị lạ/thiếu rơi về mặc định (config cũ chưa có field vẫn đọc được). */
30
+ declare function parseCameraSettings(raw: string | null, defaults?: CameraSettings): CameraSettings;
31
+ interface CameraSettingsStore {
32
+ readonly key: string;
33
+ get(): CameraSettings;
34
+ set(patch: Partial<CameraSettings>): void;
35
+ subscribe(listener: () => void): () => void;
36
+ /** Nạp từ đĩa; gọi một lần lúc app khởi động. */
37
+ restore(): Promise<void>;
38
+ isRestored(): boolean;
39
+ }
40
+ interface CameraSettingsStoreOptions {
41
+ storage?: SdkStorage;
42
+ /** Khoá lưu — app fleet giữ khoá cũ để setting sống qua OTA. */
43
+ key?: string;
44
+ defaults?: Partial<CameraSettings>;
45
+ }
46
+ declare function createCameraSettingsStore(options?: CameraSettingsStoreOptions): CameraSettingsStore;
47
+ declare function useCameraSettings(store: CameraSettingsStore): CameraSettings;
48
+ /** `key` cho PickleballLiveProvider: đổi giá trị → remount → engine re-prepare đúng cấu hình. */
49
+ declare function cameraSettingsKey(settings: CameraSettings): string;
50
+ /** roomFactory RTMP theo cấu hình (fps + camera mặc định). */
51
+ declare function rtmpRoomFactoryFor(settings: CameraSettings): () => RoomAdapter;
52
+
53
+ /**
54
+ * Điều khiển camera RUNTIME (zoom, EV, khoá nét/sáng, đèn pin, chống chớp) —
55
+ * gọi THẲNG native module @pickleball/rtmp-native (singleton), chủ ý bypass
56
+ * engine/adapter vì đây là tinh chỉnh camera, không phải lifecycle phiên.
57
+ *
58
+ * Mọi hàm `typeof`-guard: binary cũ (rtmp-native 0.1.0 trên fleet 1.0.2) thiếu
59
+ * vài hàm thì trả null/no-op thay vì ném — UI ẩn control tương ứng.
60
+ */
61
+ interface CameraCapabilityRange {
62
+ min: number;
63
+ max: number;
64
+ supported: boolean;
65
+ }
66
+ interface CameraCapabilities {
67
+ zoom: CameraCapabilityRange;
68
+ exposureBias: CameraCapabilityRange & {
69
+ step?: number;
70
+ };
71
+ torch: {
72
+ supported: boolean;
73
+ };
74
+ focusLock: {
75
+ supported: boolean;
76
+ };
77
+ exposureLock: {
78
+ supported: boolean;
79
+ };
80
+ supportedFrameRates?: number[];
81
+ }
82
+ /** Bounds + cờ hỗ trợ của lens đang gắn; null khi module/hàm chưa có. */
83
+ declare function getCameraCapabilities(): Promise<CameraCapabilities | null>;
84
+ declare function setZoom(factor: number): Promise<void>;
85
+ declare function setExposureBias(ev: number): Promise<void>;
86
+ declare function setFocusLocked(locked: boolean): Promise<void>;
87
+ declare function setExposureLocked(locked: boolean): Promise<void>;
88
+ declare function setTorch(enabled: boolean): Promise<void>;
89
+ /** Android-only: iOS/binary cũ thiếu hàm → no-op. Native tự áp lại mỗi lần mở camera/đổi lens. */
90
+ declare function applyAntiFlicker(mode: "auto" | "50hz" | "60hz"): Promise<void>;
91
+ /**
92
+ * Xin quyền camera/mic qua native (iOS, rtmp-native ≥ 0.2). null = native chưa
93
+ * có hàm → caller tự quyết (AVFoundation sẽ hỏi lúc mở camera).
94
+ */
95
+ declare function requestNativePermissions(): Promise<boolean | null>;
96
+
97
+ export { type AntiFlickerMode as A, CAMERA_SETTINGS_STORAGE_KEY as C, DEFAULT_CAMERA_SETTINGS as D, type CameraCapabilities as a, type CameraCapabilityRange as b, type CameraSettings as c, type CameraSettingsStore as d, type CameraSettingsStoreOptions as e, applyAntiFlicker as f, cameraSettingsKey as g, createCameraSettingsStore as h, getCameraCapabilities as i, rtmpRoomFactoryFor as j, setExposureLocked as k, setFocusLocked as l, setTorch as m, setZoom as n, parseCameraSettings as p, requestNativePermissions as r, setExposureBias as s, useCameraSettings as u };