@strevokit/meeting-sdk 0.0.0-stage → 0.8.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.
@@ -0,0 +1,101 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Meeting example</title>
6
+ </head>
7
+ <body>
8
+ <p id="status">Not joined</p>
9
+ <video id="preview" autoplay muted playsinline width="320"></video>
10
+ <div>
11
+ <button id="camera" disabled>Camera</button>
12
+ <button id="microphone" disabled>Microphone</button>
13
+ <button id="screen" disabled>Share screen</button>
14
+ <button id="leave" disabled>Leave</button>
15
+ </div>
16
+ <ul id="participants"></ul>
17
+ <div id="remote"></div>
18
+
19
+ <script type="module">
20
+ // With a bundler, import from "@strevokit/meeting-sdk" instead.
21
+ import { createMeetingEngine, MeetingError } from "./node_modules/@strevokit/meeting-sdk/dist/index.js";
22
+
23
+ // Ask your backend for a join token (see backend-integration.md and ../backend-api.md).
24
+ const { token } = await fetch("/my-backend/join-token", { method: "POST" }).then((r) => r.json());
25
+
26
+ const engine = createMeetingEngine({ token, realtimeUrl: "wss://realtime.example.com" });
27
+ const $ = (id) => document.getElementById(id);
28
+ const buttons = ["camera", "microphone", "screen", "leave"].map($);
29
+
30
+ function renderParticipants() {
31
+ $("participants").replaceChildren(
32
+ ...engine.participants.map((p) => {
33
+ const item = document.createElement("li");
34
+ const on = Object.entries(p.media).filter(([, enabled]) => enabled).map(([kind]) => kind);
35
+ item.textContent = `${p.displayName ?? p.id} (${p.role})${on.length ? ` - ${on.join(", ")}` : ""}`;
36
+ return item;
37
+ }),
38
+ );
39
+ }
40
+
41
+ engine.on("state_changed", ({ state }) => {
42
+ $("status").textContent = state;
43
+ for (const button of buttons) button.disabled = state !== "joined";
44
+ });
45
+ for (const type of ["joined", "participant_joined", "participant_left", "participant_media_changed"]) {
46
+ engine.on(type, renderParticipants);
47
+ }
48
+ engine.on("local_media_changed", ({ kind, enabled }) => {
49
+ if (kind === "camera") $("preview").srcObject = engine.localMedia.camera;
50
+ $(kind).setAttribute("aria-pressed", String(enabled));
51
+ });
52
+ // One <figure> per remote participant, holding a <video> for their camera and an <audio> for their microphone.
53
+ function remoteTile(participantId) {
54
+ let tile = document.querySelector(`[data-participant="${participantId}"]`);
55
+ if (!tile) {
56
+ tile = document.createElement("figure");
57
+ tile.dataset.participant = participantId;
58
+ const video = Object.assign(document.createElement("video"), { autoplay: true, playsInline: true, muted: true, width: 320 });
59
+ const audio = Object.assign(document.createElement("audio"), { autoplay: true });
60
+ const caption = document.createElement("figcaption");
61
+ tile.append(video, audio, caption);
62
+ $("remote").append(tile);
63
+ }
64
+ return tile;
65
+ }
66
+ engine.on("remote_media_changed", ({ participantId, kind, stream }) => {
67
+ const tile = remoteTile(participantId);
68
+ if (kind === "camera") tile.querySelector("video").srcObject = stream;
69
+ if (kind === "microphone") tile.querySelector("audio").srcObject = stream;
70
+ });
71
+ engine.on("media_connection_changed", ({ participantId, status }) => {
72
+ remoteTile(participantId).querySelector("figcaption").textContent =
73
+ status === "interrupted" ? "Connection lost — reconnecting…" : (status ?? "");
74
+ });
75
+ engine.on("participant_left", ({ participantId }) => {
76
+ document.querySelector(`[data-participant="${participantId}"]`)?.remove();
77
+ });
78
+ engine.on("error", ({ error }) => alert(error.message));
79
+ engine.on("closed", ({ reason, error }) => {
80
+ $("status").textContent = error ? `Closed: ${error.message}` : `Closed (${reason})`;
81
+ });
82
+
83
+ async function run(action) {
84
+ try {
85
+ await action();
86
+ } catch (error) {
87
+ if (error instanceof MeetingError) alert(error.message);
88
+ else throw error;
89
+ }
90
+ }
91
+
92
+ $("camera").onclick = () => run(() => (engine.localMediaState.camera ? engine.disableCamera() : engine.enableCamera()));
93
+ $("microphone").onclick = () => run(() => (engine.localMediaState.microphone ? engine.mute() : engine.unmute()));
94
+ $("screen").onclick = () => run(() => (engine.localMediaState.screen ? engine.stopScreenShare() : engine.startScreenShare()));
95
+ $("leave").onclick = () => engine.leave();
96
+ window.addEventListener("pagehide", () => engine.dispose());
97
+
98
+ await run(() => engine.join());
99
+ </script>
100
+ </body>
101
+ </html>
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@strevokit/meeting-sdk",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.8.0",
4
+ "description": "Embed Strevokit meetings in your web product.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/AgiliaIT/strevokit-meeting-sdk.git",
9
+ "directory": "packages/meeting-sdk"
10
+ },
11
+ "homepage": "https://github.com/AgiliaIT/strevokit-meeting-sdk/tree/main/packages/meeting-sdk#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/AgiliaIT/strevokit-meeting-sdk/issues"
14
+ },
15
+ "type": "module",
16
+ "sideEffects": false,
17
+ "engines": {
18
+ "node": ">=22.12"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js"
24
+ },
25
+ "./package.json": "./package.json"
26
+ },
27
+ "files": [
28
+ "dist/index.js",
29
+ "dist/index.js.map",
30
+ "dist/index.d.ts",
31
+ "README.md",
32
+ "CHANGELOG.md",
33
+ "docs"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "scripts": {
39
+ "protocol:build": "npm --prefix ../signaling-protocol ci && npm --prefix ../signaling-protocol run build",
40
+ "build": "node scripts/build.mjs",
41
+ "typecheck": "tsc -p tsconfig.test.json",
42
+ "lint": "eslint .",
43
+ "test": "vitest run",
44
+ "api:check": "api-extractor run",
45
+ "api:update": "node scripts/build.mjs --update-api",
46
+ "check:surface": "node scripts/check-surface.mjs",
47
+ "check:docs": "node scripts/check-docs.mjs",
48
+ "check:size": "node scripts/check-size.mjs",
49
+ "check:release": "node scripts/check-release.mjs",
50
+ "pack:smoke": "node scripts/pack-smoke.mjs",
51
+ "check:publish-hygiene": "node scripts/check-publish-hygiene.mjs"
52
+ },
53
+ "dependencies": {},
54
+ "devDependencies": {
55
+ "@microsoft/api-extractor": "^7.59.0",
56
+ "@strevokit/signaling-protocol": "file:../signaling-protocol",
57
+ "@types/node": "^22.10.0",
58
+ "esbuild": "^0.28.0",
59
+ "eslint": "^10.11.0",
60
+ "typescript": "^5.7.0",
61
+ "typescript-eslint": "^8.71.0",
62
+ "vitest": "^5.0.0"
63
+ }
64
+ }