@mebius-io/web 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mebius
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/README.md ADDED
@@ -0,0 +1,354 @@
1
+ # @mebius-io/web
2
+
3
+ SDK web Mebius untuk live streaming — install, ikuti docs, hit API.
4
+
5
+ [![npm version](https://img.shields.io/badge/npm-%40mebius%2Fweb-blue)](https://www.npmjs.com/package/@mebius-io/web)
6
+ [![license](https://img.shields.io/badge/license-MIT-green)](../../LICENSE)
7
+
8
+ ## Requirements
9
+
10
+ - Browser modern dengan WebRTC (Chrome, Edge, Firefox, Safari terbaru).
11
+ - **HTTPS wajib di production.** `localhost` boleh dipakai untuk development.
12
+ - Node 20+ hanya untuk build tooling (bukan runtime SDK).
13
+
14
+ ## Install
15
+
16
+ > Repo ini **private** dan belum dipublish ke npm registry / domain manapun.
17
+ > Metode install yang terbukti jalan adalah **tarball** (di bawah). Lihat
18
+ > [Distribusi private](#distribusi-private-github--tarball) untuk detail +
19
+ > caveat git install.
20
+
21
+ ### Tarball (cara utama, paling reliable)
22
+
23
+ Maintainer membuat tarball sekali per rilis, lalu consumer install dari file:
24
+
25
+ ```bash
26
+ # Maintainer (di repo SDK):
27
+ pnpm --filter @mebius-io/web build
28
+ pnpm --filter @mebius-io/web pack # -> packages/web/mebius-web-0.1.0.tgz
29
+
30
+ # Consumer (di project kamu):
31
+ npm i ./mebius-web-0.1.0.tgz
32
+ # atau: pnpm add ./mebius-web-0.1.0.tgz / yarn add ./mebius-web-0.1.0.tgz
33
+ ```
34
+
35
+ Tarball sudah berisi `dist/` (ESM + CJS + UMD + types) dan menarik dependency
36
+ runtime (`hls.js`) otomatis. Tidak perlu build di sisi consumer.
37
+
38
+ ```ts
39
+ const { Mebius } = require("@mebius-io/web"); // CJS — works
40
+ import { Mebius } from "@mebius-io/web"; // ESM — works
41
+ ```
42
+
43
+ Setelah package dipublish ke npm registry (opsi masa depan, npm tidak butuh
44
+ domain):
45
+
46
+ ```bash
47
+ npm i @mebius-io/web
48
+ # atau: pnpm add @mebius-io/web / yarn add @mebius-io/web
49
+ ```
50
+
51
+ Via CDN (UMD global `Mebius`) — hanya tersedia setelah publish ke registry/CDN:
52
+
53
+ ```html
54
+ <script src="https://unpkg.com/@mebius-io/web/dist/index.global.js"></script>
55
+ <script>
56
+ Mebius.Mebius.init({ appId: "app_123", gateway: "https://gateway.mebius.io" });
57
+ </script>
58
+ ```
59
+
60
+ ### Single-file drop-in (PHP / plain HTML, no build)
61
+
62
+ For PHP or any plain-HTML project: download ONE self-contained file and add a
63
+ `<script>` tag — no npm, no bundler. The scale engine is bundled in; zero
64
+ external deps. `Mebius` becomes a global.
65
+
66
+ ```html
67
+ <script src="mebius.min.js"></script>
68
+ <script>
69
+ Mebius.init({ appId: "app_123", gateway: "https://gateway.mebius.io" });
70
+ const client = Mebius.connect({ token }); // token from your backend
71
+ </script>
72
+ ```
73
+
74
+ File + full PHP example: [`standalone/`](./standalone/). Raw download:
75
+ `https://raw.githubusercontent.com/russimobiledroidx/mebius-web-sdk/v0.1.0/packages/web/standalone/mebius.min.js`
76
+
77
+ ## Quick Start
78
+
79
+ ### a. Auth
80
+
81
+ > Token di-mint dari **backend kamu**, JANGAN embed `appSecret` di client.
82
+ > Backend menukar (appId + appSecret) jadi JWT short-lived; client cuma terima
83
+ > string token-nya.
84
+
85
+ ### b. Init + connect
86
+
87
+ ```ts
88
+ import { Mebius } from "@mebius-io/web";
89
+
90
+ Mebius.init({ appId: "app_123", gateway: "https://gateway.mebius.io" });
91
+
92
+ const token = await fetch("/api/mebius-token").then((r) => r.text());
93
+ const client = Mebius.connect({ token });
94
+
95
+ client.on("connected", () => console.log("Mebius connected"));
96
+ client.on("error", (err) => {
97
+ if (err.code === "TOKEN_EXPIRED") {
98
+ // refresh token dari backend, lalu connect ulang
99
+ }
100
+ });
101
+ ```
102
+
103
+ ### c. Broadcast
104
+
105
+ ```ts
106
+ const broadcaster = client.createBroadcaster({ video: true, audio: true });
107
+
108
+ broadcaster.on("started", ({ streamId }) => console.log("live:", streamId));
109
+ broadcaster.on("stats", (s) => console.log(s.bitrateKbps, "kbps"));
110
+
111
+ await broadcaster.start("my-stream");
112
+ broadcaster.attachPreview("#preview"); // preview lokal (web convenience)
113
+
114
+ // kontrol
115
+ broadcaster.setMicEnabled(false);
116
+ broadcaster.setCameraEnabled(true);
117
+ await broadcaster.switchCamera();
118
+
119
+ // stop
120
+ await broadcaster.stop();
121
+ ```
122
+
123
+ ### d. Watch
124
+
125
+ ```ts
126
+ const player = client.createPlayer({ mode: "low-latency" }); // atau "scale"
127
+
128
+ player.on("playing", ({ streamId }) => console.log("playing", streamId));
129
+ player.on("buffering", () => console.log("buffering..."));
130
+ player.on("ended", () => console.log("ended"));
131
+
132
+ await player.play("my-stream", "#viewer"); // <video id="viewer">
133
+ player.setVolume(0.8);
134
+
135
+ await player.stop();
136
+ ```
137
+
138
+ Ganti mode kapan saja dengan membuat player baru: `mode: "low-latency"` untuk
139
+ delay minimum, `mode: "scale"` untuk audiens besar.
140
+
141
+ ## Integrasi per framework
142
+
143
+ ### Vanilla JS
144
+
145
+ ESM:
146
+
147
+ ```ts
148
+ import { Mebius } from "@mebius-io/web";
149
+ Mebius.init({ appId, gateway });
150
+ const client = Mebius.connect({ token });
151
+ ```
152
+
153
+ UMD `<script>`:
154
+
155
+ ```html
156
+ <script src="https://unpkg.com/@mebius-io/web/dist/index.global.js"></script>
157
+ <script>
158
+ const { Mebius } = window.Mebius;
159
+ Mebius.init({ appId, gateway });
160
+ </script>
161
+ ```
162
+
163
+ ### React
164
+
165
+ Pakai `@mebius-io/react` (hooks tipis di atas package ini):
166
+
167
+ ```tsx
168
+ import { useMebius, usePlayer } from "@mebius-io/react";
169
+
170
+ function Watch({ token, streamId }) {
171
+ const { client } = useMebius({ appId, gateway, token });
172
+ const { videoRef, play } = usePlayer(client, { mode: "low-latency" });
173
+ return <video ref={videoRef} onClick={() => play(streamId)} autoPlay />;
174
+ }
175
+ ```
176
+
177
+ ### Next.js
178
+
179
+ ```tsx
180
+ "use client";
181
+ import dynamic from "next/dynamic";
182
+ // SDK butuh WebRTC browser → jangan render di server.
183
+ const Watch = dynamic(() => import("../components/Watch"), { ssr: false });
184
+ export default function Page() {
185
+ return <Watch />;
186
+ }
187
+ ```
188
+
189
+ ### Vue 3 (Composition API)
190
+
191
+ ```ts
192
+ import { onMounted, onUnmounted, ref } from "vue";
193
+ import { Mebius } from "@mebius-io/web";
194
+
195
+ export function useWatch(streamId: string) {
196
+ const video = ref<HTMLVideoElement>();
197
+ let player: ReturnType<ReturnType<typeof Mebius.connect>["createPlayer"]>;
198
+ onMounted(async () => {
199
+ Mebius.init({ appId, gateway });
200
+ const client = Mebius.connect({ token: await getToken() });
201
+ player = client.createPlayer({ mode: "low-latency" });
202
+ await player.play(streamId, video.value!);
203
+ });
204
+ onUnmounted(() => player?.stop());
205
+ return { video };
206
+ }
207
+ ```
208
+
209
+ ### Vite
210
+
211
+ Tidak ada config khusus. ESM langsung jalan; `hls.js` di-load lazy hanya saat
212
+ mode `"scale"` dipakai, jadi tidak menambah bundle low-latency.
213
+
214
+ ## API Reference
215
+
216
+ | Class | Method | Return | Keterangan |
217
+ |---|---|---|---|
218
+ | `Mebius` | `init({ appId, gateway })` | `void` | Konfigurasi sekali di awal. |
219
+ | `Mebius` | `connect({ token })` | `MebiusClient` | Buka koneksi. |
220
+ | `MebiusClient` | `createBroadcaster({ video?, audio? })` | `MebiusBroadcaster` | |
221
+ | `MebiusClient` | `createPlayer({ mode })` | `MebiusPlayer` | `mode: "low-latency" \| "scale"` |
222
+ | `MebiusClient` | `disconnect(reason?)` | `void` | |
223
+ | `MebiusBroadcaster` | `start(streamId)` | `Promise<void>` | |
224
+ | `MebiusBroadcaster` | `stop()` | `Promise<void>` | |
225
+ | `MebiusBroadcaster` | `switchCamera()` | `Promise<void>` | |
226
+ | `MebiusBroadcaster` | `setMicEnabled(bool)` | `void` | |
227
+ | `MebiusBroadcaster` | `setCameraEnabled(bool)` | `void` | |
228
+ | `MebiusBroadcaster` | `attachPreview(target)` | `void` | Preview lokal (web). |
229
+ | `MebiusPlayer` | `play(streamId, viewTarget)` | `Promise<void>` | `viewTarget`: `<video>` atau selector. |
230
+ | `MebiusPlayer` | `stop()` | `Promise<void>` | |
231
+ | `MebiusPlayer` | `setVolume(0..1)` | `void` | |
232
+
233
+ ### Events
234
+
235
+ | Emitter | Event | Payload |
236
+ |---|---|---|
237
+ | client | `connected` | — |
238
+ | client | `disconnected` | `{ reason? }` |
239
+ | client | `error` | `MebiusError` |
240
+ | broadcaster | `started` | `{ streamId }` |
241
+ | broadcaster | `stopped` | — |
242
+ | broadcaster | `stats` | `{ bitrateKbps, framesPerSecond, rttMs? }` |
243
+ | player | `playing` | `{ streamId }` |
244
+ | player | `buffering` | — |
245
+ | player | `ended` | — |
246
+ | player | `stats` | `{ bitrateKbps, framesPerSecond, latencyMs? }` |
247
+
248
+ ```ts
249
+ client.on("connected", () => {});
250
+ client.on("error", (e) => console.warn(e.code, e.message));
251
+ broadcaster.on("stats", (s) => console.log(s.bitrateKbps));
252
+ ```
253
+
254
+ ## Error handling
255
+
256
+ Semua error adalah `MebiusError` dengan `.code`:
257
+
258
+ | Code | Arti | Recover |
259
+ |---|---|---|
260
+ | `TOKEN_EXPIRED` | Token habis masa berlaku | Mint token baru di backend, connect ulang. |
261
+ | `PERMISSION_DENIED` | Izin kamera/mic ditolak | Minta user mengizinkan, retry `start()`. |
262
+ | `CONNECTION_FAILED` | Gagal konek ke gateway | Cek jaringan/gateway, retry dengan backoff. |
263
+ | `NOT_CONNECTED` | Dipakai sebelum `connect()` | Pastikan `connect()` sukses dulu. |
264
+ | `STREAM_NOT_FOUND` | Stream tidak ada | Verifikasi `streamId`. |
265
+
266
+ ```ts
267
+ client.on("error", (e) => {
268
+ switch (e.code) {
269
+ case "TOKEN_EXPIRED": return refreshAndReconnect();
270
+ case "PERMISSION_DENIED": return showPermissionHelp();
271
+ default: console.error(e);
272
+ }
273
+ });
274
+ ```
275
+
276
+ ## Troubleshooting
277
+
278
+ - **Izin kamera/mic:** browser hanya memberi izin di context aman (HTTPS atau
279
+ `localhost`). Pastikan halaman tidak dibuka via `file://`.
280
+ - **HTTPS:** WebRTC butuh secure context di production.
281
+ - **Autoplay:** browser memblok autoplay dengan suara. Mulai playback setelah
282
+ interaksi user, atau set `muted` dulu lalu unmute via `setVolume`.
283
+
284
+ ## Distribusi private (GitHub / tarball)
285
+
286
+ SDK ini hidup di **monorepo private** (`russimobiledroidx/mebius-web-sdk`)
287
+ dengan 3 package: `@mebius-io/web` (core, tanpa dependency internal), `@mebius-io/react`,
288
+ `@mebius-io/react-native`. Tidak ada registry/domain publik. Berikut metode install
289
+ beserta tingkat keandalannya — apa adanya, tanpa janji palsu.
290
+
291
+ ### ✅ Tarball — reliable (cara utama)
292
+
293
+ ```bash
294
+ # 1. Maintainer build + pack semua package sekaligus (di repo SDK):
295
+ pnpm pack:all
296
+ # -> mebius-web-0.1.0.tgz
297
+ # mebius-react-0.1.0.tgz
298
+ # mebius-react-native-0.1.0.tgz (di root repo)
299
+
300
+ # 2. Consumer install (copy .tgz ke project, lalu):
301
+ npm i ./mebius-web-0.1.0.tgz
302
+ ```
303
+
304
+ Selalu jalan untuk repo private karena tidak menyentuh registry sama sekali.
305
+ `@mebius-io/web` self-contained (tidak punya workspace dep), jadi paling bersih.
306
+
307
+ ### ⚠️ git install — TIDAK reliable untuk monorepo subpackage
308
+
309
+ `npm i 'github:russimobiledroidx/mebius-web-sdk'` **tidak** bisa dipakai untuk
310
+ menginstall satu sub-package: npm/pnpm meng-clone seluruh repo dan hanya membaca
311
+ `package.json` di root, yang `private: true` dan bukan salah satu dari ketiga
312
+ package. npm juga tidak mendukung pemilihan sub-direktori untuk git dependency
313
+ secara native. Jadi metode ini **tidak didukung** di sini — pakai tarball.
314
+
315
+ (Catatan: tool pihak ketiga seperti `gitpkg` mem-publish subdir sebagai git URL,
316
+ tetapi **tidak bekerja untuk repo private**. Karena itu tarball adalah jalur
317
+ utama.)
318
+
319
+ ### Cross-package dependency (react / react-native)
320
+
321
+ `@mebius-io/react` bergantung ke `@mebius-io/web`. Saat di-pack, pnpm menulis ulang
322
+ `workspace:*` menjadi versi konkret (`"@mebius-io/web": "0.1.0"`) yang tidak ada di
323
+ registry manapun untuk repo private ini. Akibatnya, **install tarball react
324
+ sendirian akan gagal** (npm mencoba mengambil `@mebius-io/web@0.1.0` dari registry).
325
+
326
+ Solusi: install kedua tarball dalam **satu perintah** supaya npm memuaskan
327
+ `@mebius-io/web@0.1.0` dari tarball lokal yang kamu sediakan:
328
+
329
+ ```bash
330
+ npm i ./mebius-web-0.1.0.tgz ./mebius-react-0.1.0.tgz react
331
+ ```
332
+
333
+ `@mebius-io/web` (core) dan `@mebius-io/react-native` (skeleton, tanpa dep internal)
334
+ bisa di-install standalone tanpa kendala ini.
335
+
336
+ ### Opsi masa depan (lebih mulus): npm publish / GitHub Packages
337
+
338
+ Tidak seperti Maven Central, **npm tidak punya syarat domain**. Begitu siap,
339
+ publish ke registry npm privat atau **GitHub Packages** menghapus seluruh dance
340
+ tarball:
341
+
342
+ ```bash
343
+ pnpm release # turbo build + changeset publish
344
+ # consumer cukup: npm i @mebius-io/web
345
+ ```
346
+
347
+ ## Versioning & changelog
348
+
349
+ SemVer. Public API stabil per major version; perubahan breaking pada kontrak =
350
+ major bump serempak di semua platform Mebius. Lihat changeset di repo.
351
+
352
+ ## License
353
+
354
+ MIT