@tinyweb_dev/oe-meeting-react 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.
@@ -0,0 +1,167 @@
1
+ import * as react from 'react';
2
+ import { CSSProperties, Ref } from 'react';
3
+
4
+ declare const EMBED_PROTOCOL_VERSION: 1;
5
+ declare const EMBED_MESSAGE_SOURCE: "oemeeting";
6
+ declare const DEFAULT_EMBED_ORIGIN = "https://meet.oceanedu.org";
7
+ declare enum EmbedEventType {
8
+ READY = "oemeeting:ready",
9
+ JOINED = "oemeeting:joined",
10
+ LEFT = "oemeeting:left",
11
+ PARTICIPANT_JOINED = "oemeeting:participant-joined",
12
+ PARTICIPANT_LEFT = "oemeeting:participant-left",
13
+ ENDED = "oemeeting:ended",
14
+ ERROR = "oemeeting:error"
15
+ }
16
+ declare enum EmbedCommandType {
17
+ COMMAND = "oemeeting:command"
18
+ }
19
+ declare enum EmbedCommandAction {
20
+ LEAVE = "leave",
21
+ TOGGLE_MIC = "toggleMic",
22
+ TOGGLE_CAMERA = "toggleCamera"
23
+ }
24
+ declare enum EmbedErrorCode {
25
+ TOKEN_INVALID = "TOKEN_INVALID",
26
+ TOKEN_EXPIRED = "TOKEN_EXPIRED",
27
+ ROOM_NOT_FOUND = "ROOM_NOT_FOUND",
28
+ ROOM_ACCESS_DENIED = "ROOM_ACCESS_DENIED",
29
+ CONNECTION_FAILED = "CONNECTION_FAILED",
30
+ PROTOCOL_MISMATCH = "PROTOCOL_MISMATCH",
31
+ UNKNOWN = "UNKNOWN"
32
+ }
33
+ declare enum EmbedQueryParam {
34
+ INSTANCE_ID = "instanceId",
35
+ HOST_ORIGIN = "hostOrigin",
36
+ JOIN_TOKEN = "joinToken",
37
+ USER_NAME = "userName",
38
+ EXTERNAL_USER_ID = "externalUserId",
39
+ LANG = "lang",
40
+ AUTO_JOIN = "autoJoin",
41
+ HIDE_LEAVE = "hideLeave"
42
+ }
43
+
44
+ interface EmbedMessageBase {
45
+ source: 'oemeeting';
46
+ version: number;
47
+ instanceId: string;
48
+ }
49
+ interface EmbedReadyPayload {
50
+ roomSlug: string;
51
+ }
52
+ interface EmbedJoinedPayload {
53
+ roomSlug: string;
54
+ identity: string;
55
+ name?: string;
56
+ joinedAt: string;
57
+ }
58
+ interface EmbedLeftPayload {
59
+ roomSlug: string;
60
+ identity: string;
61
+ leftAt: string;
62
+ durationMs?: number;
63
+ }
64
+ interface EmbedParticipantJoinedPayload {
65
+ identity: string;
66
+ name?: string;
67
+ participantCount: number;
68
+ }
69
+ interface EmbedParticipantLeftPayload {
70
+ identity: string;
71
+ participantCount: number;
72
+ }
73
+ interface EmbedEndedPayload {
74
+ roomSlug: string;
75
+ endedAt: string;
76
+ }
77
+ interface EmbedErrorPayload {
78
+ code: EmbedErrorCode | string;
79
+ message: string;
80
+ }
81
+ type EmbedEventPayloadMap = {
82
+ [EmbedEventType.READY]: EmbedReadyPayload;
83
+ [EmbedEventType.JOINED]: EmbedJoinedPayload;
84
+ [EmbedEventType.LEFT]: EmbedLeftPayload;
85
+ [EmbedEventType.PARTICIPANT_JOINED]: EmbedParticipantJoinedPayload;
86
+ [EmbedEventType.PARTICIPANT_LEFT]: EmbedParticipantLeftPayload;
87
+ [EmbedEventType.ENDED]: EmbedEndedPayload;
88
+ [EmbedEventType.ERROR]: EmbedErrorPayload;
89
+ };
90
+ type EmbedEventByType<T extends EmbedEventType> = EmbedMessageBase & {
91
+ type: T;
92
+ payload: EmbedEventPayloadMap[T];
93
+ };
94
+ type EmbedEvent = {
95
+ [T in EmbedEventType]: EmbedEventByType<T>;
96
+ }[EmbedEventType];
97
+ type EmbedEventOf<T extends EmbedEventType> = Extract<EmbedEvent, {
98
+ type: T;
99
+ }>;
100
+ type EmbedCommandMessage = EmbedMessageBase & {
101
+ type: 'oemeeting:command';
102
+ action: EmbedCommandAction;
103
+ };
104
+ interface OeMeetingHandle {
105
+ leave: () => void;
106
+ toggleMic: () => void;
107
+ toggleCamera: () => void;
108
+ getIframe: () => HTMLIFrameElement | null;
109
+ }
110
+ interface OeMeetingProps {
111
+ roomSlug: string;
112
+ joinToken: string;
113
+ userName?: string;
114
+ externalUserId?: string;
115
+ origin?: string;
116
+ lang?: string;
117
+ autoJoin?: boolean;
118
+ hideLeave?: boolean;
119
+ title?: string;
120
+ width?: number | string;
121
+ height?: number | string;
122
+ className?: string;
123
+ style?: CSSProperties;
124
+ iframeClassName?: string;
125
+ iframeStyle?: CSSProperties;
126
+ allow?: string;
127
+ targetOrigin?: string;
128
+ onReady?: (event: EmbedEventOf<EmbedEventType.READY>) => void;
129
+ onJoined?: (event: EmbedEventOf<EmbedEventType.JOINED>) => void;
130
+ onLeft?: (event: EmbedEventOf<EmbedEventType.LEFT>) => void;
131
+ onParticipantJoined?: (event: EmbedEventOf<EmbedEventType.PARTICIPANT_JOINED>) => void;
132
+ onParticipantLeft?: (event: EmbedEventOf<EmbedEventType.PARTICIPANT_LEFT>) => void;
133
+ onEnded?: (event: EmbedEventOf<EmbedEventType.ENDED>) => void;
134
+ onError?: (event: EmbedEventOf<EmbedEventType.ERROR>) => void;
135
+ onEvent?: (event: EmbedEvent) => void;
136
+ }
137
+ interface BuildEmbedUrlOptions {
138
+ roomSlug: string;
139
+ joinToken: string;
140
+ origin?: string;
141
+ userName?: string;
142
+ externalUserId?: string;
143
+ lang?: string;
144
+ autoJoin?: boolean;
145
+ hideLeave?: boolean;
146
+ instanceId?: string;
147
+ hostOrigin?: string;
148
+ }
149
+
150
+ declare const DEFAULT_IFRAME_ALLOW = "camera; microphone; fullscreen; autoplay; display-capture; clipboard-write; encrypted-media";
151
+ declare const OeMeeting: react.ForwardRefExoticComponent<OeMeetingProps & react.RefAttributes<OeMeetingHandle>>;
152
+
153
+ type UseOeMeetingOptions = Pick<OeMeetingProps, 'onReady' | 'onJoined' | 'onLeft' | 'onParticipantJoined' | 'onParticipantLeft' | 'onEnded' | 'onError' | 'onEvent'> & {
154
+ instanceId: string;
155
+ targetOrigin: string;
156
+ handleRef?: Ref<OeMeetingHandle>;
157
+ };
158
+ declare function useOeMeeting(options: UseOeMeetingOptions): {
159
+ iframeRef: react.MutableRefObject<HTMLIFrameElement | null>;
160
+ handle: OeMeetingHandle;
161
+ };
162
+
163
+ declare function buildEmbedUrl(options: BuildEmbedUrlOptions): string;
164
+
165
+ declare function parseEmbedEvent(data: unknown): EmbedEvent | null;
166
+
167
+ export { type BuildEmbedUrlOptions, DEFAULT_EMBED_ORIGIN, DEFAULT_IFRAME_ALLOW, EMBED_MESSAGE_SOURCE, EMBED_PROTOCOL_VERSION, EmbedCommandAction, type EmbedCommandMessage, EmbedCommandType, type EmbedEndedPayload, EmbedErrorCode, type EmbedErrorPayload, type EmbedEvent, type EmbedEventOf, type EmbedEventPayloadMap, EmbedEventType, type EmbedJoinedPayload, type EmbedLeftPayload, type EmbedMessageBase, type EmbedParticipantJoinedPayload, type EmbedParticipantLeftPayload, EmbedQueryParam, type EmbedReadyPayload, OeMeeting, type OeMeetingHandle, type OeMeetingProps, buildEmbedUrl, parseEmbedEvent, useOeMeeting };
@@ -0,0 +1,167 @@
1
+ import * as react from 'react';
2
+ import { CSSProperties, Ref } from 'react';
3
+
4
+ declare const EMBED_PROTOCOL_VERSION: 1;
5
+ declare const EMBED_MESSAGE_SOURCE: "oemeeting";
6
+ declare const DEFAULT_EMBED_ORIGIN = "https://meet.oceanedu.org";
7
+ declare enum EmbedEventType {
8
+ READY = "oemeeting:ready",
9
+ JOINED = "oemeeting:joined",
10
+ LEFT = "oemeeting:left",
11
+ PARTICIPANT_JOINED = "oemeeting:participant-joined",
12
+ PARTICIPANT_LEFT = "oemeeting:participant-left",
13
+ ENDED = "oemeeting:ended",
14
+ ERROR = "oemeeting:error"
15
+ }
16
+ declare enum EmbedCommandType {
17
+ COMMAND = "oemeeting:command"
18
+ }
19
+ declare enum EmbedCommandAction {
20
+ LEAVE = "leave",
21
+ TOGGLE_MIC = "toggleMic",
22
+ TOGGLE_CAMERA = "toggleCamera"
23
+ }
24
+ declare enum EmbedErrorCode {
25
+ TOKEN_INVALID = "TOKEN_INVALID",
26
+ TOKEN_EXPIRED = "TOKEN_EXPIRED",
27
+ ROOM_NOT_FOUND = "ROOM_NOT_FOUND",
28
+ ROOM_ACCESS_DENIED = "ROOM_ACCESS_DENIED",
29
+ CONNECTION_FAILED = "CONNECTION_FAILED",
30
+ PROTOCOL_MISMATCH = "PROTOCOL_MISMATCH",
31
+ UNKNOWN = "UNKNOWN"
32
+ }
33
+ declare enum EmbedQueryParam {
34
+ INSTANCE_ID = "instanceId",
35
+ HOST_ORIGIN = "hostOrigin",
36
+ JOIN_TOKEN = "joinToken",
37
+ USER_NAME = "userName",
38
+ EXTERNAL_USER_ID = "externalUserId",
39
+ LANG = "lang",
40
+ AUTO_JOIN = "autoJoin",
41
+ HIDE_LEAVE = "hideLeave"
42
+ }
43
+
44
+ interface EmbedMessageBase {
45
+ source: 'oemeeting';
46
+ version: number;
47
+ instanceId: string;
48
+ }
49
+ interface EmbedReadyPayload {
50
+ roomSlug: string;
51
+ }
52
+ interface EmbedJoinedPayload {
53
+ roomSlug: string;
54
+ identity: string;
55
+ name?: string;
56
+ joinedAt: string;
57
+ }
58
+ interface EmbedLeftPayload {
59
+ roomSlug: string;
60
+ identity: string;
61
+ leftAt: string;
62
+ durationMs?: number;
63
+ }
64
+ interface EmbedParticipantJoinedPayload {
65
+ identity: string;
66
+ name?: string;
67
+ participantCount: number;
68
+ }
69
+ interface EmbedParticipantLeftPayload {
70
+ identity: string;
71
+ participantCount: number;
72
+ }
73
+ interface EmbedEndedPayload {
74
+ roomSlug: string;
75
+ endedAt: string;
76
+ }
77
+ interface EmbedErrorPayload {
78
+ code: EmbedErrorCode | string;
79
+ message: string;
80
+ }
81
+ type EmbedEventPayloadMap = {
82
+ [EmbedEventType.READY]: EmbedReadyPayload;
83
+ [EmbedEventType.JOINED]: EmbedJoinedPayload;
84
+ [EmbedEventType.LEFT]: EmbedLeftPayload;
85
+ [EmbedEventType.PARTICIPANT_JOINED]: EmbedParticipantJoinedPayload;
86
+ [EmbedEventType.PARTICIPANT_LEFT]: EmbedParticipantLeftPayload;
87
+ [EmbedEventType.ENDED]: EmbedEndedPayload;
88
+ [EmbedEventType.ERROR]: EmbedErrorPayload;
89
+ };
90
+ type EmbedEventByType<T extends EmbedEventType> = EmbedMessageBase & {
91
+ type: T;
92
+ payload: EmbedEventPayloadMap[T];
93
+ };
94
+ type EmbedEvent = {
95
+ [T in EmbedEventType]: EmbedEventByType<T>;
96
+ }[EmbedEventType];
97
+ type EmbedEventOf<T extends EmbedEventType> = Extract<EmbedEvent, {
98
+ type: T;
99
+ }>;
100
+ type EmbedCommandMessage = EmbedMessageBase & {
101
+ type: 'oemeeting:command';
102
+ action: EmbedCommandAction;
103
+ };
104
+ interface OeMeetingHandle {
105
+ leave: () => void;
106
+ toggleMic: () => void;
107
+ toggleCamera: () => void;
108
+ getIframe: () => HTMLIFrameElement | null;
109
+ }
110
+ interface OeMeetingProps {
111
+ roomSlug: string;
112
+ joinToken: string;
113
+ userName?: string;
114
+ externalUserId?: string;
115
+ origin?: string;
116
+ lang?: string;
117
+ autoJoin?: boolean;
118
+ hideLeave?: boolean;
119
+ title?: string;
120
+ width?: number | string;
121
+ height?: number | string;
122
+ className?: string;
123
+ style?: CSSProperties;
124
+ iframeClassName?: string;
125
+ iframeStyle?: CSSProperties;
126
+ allow?: string;
127
+ targetOrigin?: string;
128
+ onReady?: (event: EmbedEventOf<EmbedEventType.READY>) => void;
129
+ onJoined?: (event: EmbedEventOf<EmbedEventType.JOINED>) => void;
130
+ onLeft?: (event: EmbedEventOf<EmbedEventType.LEFT>) => void;
131
+ onParticipantJoined?: (event: EmbedEventOf<EmbedEventType.PARTICIPANT_JOINED>) => void;
132
+ onParticipantLeft?: (event: EmbedEventOf<EmbedEventType.PARTICIPANT_LEFT>) => void;
133
+ onEnded?: (event: EmbedEventOf<EmbedEventType.ENDED>) => void;
134
+ onError?: (event: EmbedEventOf<EmbedEventType.ERROR>) => void;
135
+ onEvent?: (event: EmbedEvent) => void;
136
+ }
137
+ interface BuildEmbedUrlOptions {
138
+ roomSlug: string;
139
+ joinToken: string;
140
+ origin?: string;
141
+ userName?: string;
142
+ externalUserId?: string;
143
+ lang?: string;
144
+ autoJoin?: boolean;
145
+ hideLeave?: boolean;
146
+ instanceId?: string;
147
+ hostOrigin?: string;
148
+ }
149
+
150
+ declare const DEFAULT_IFRAME_ALLOW = "camera; microphone; fullscreen; autoplay; display-capture; clipboard-write; encrypted-media";
151
+ declare const OeMeeting: react.ForwardRefExoticComponent<OeMeetingProps & react.RefAttributes<OeMeetingHandle>>;
152
+
153
+ type UseOeMeetingOptions = Pick<OeMeetingProps, 'onReady' | 'onJoined' | 'onLeft' | 'onParticipantJoined' | 'onParticipantLeft' | 'onEnded' | 'onError' | 'onEvent'> & {
154
+ instanceId: string;
155
+ targetOrigin: string;
156
+ handleRef?: Ref<OeMeetingHandle>;
157
+ };
158
+ declare function useOeMeeting(options: UseOeMeetingOptions): {
159
+ iframeRef: react.MutableRefObject<HTMLIFrameElement | null>;
160
+ handle: OeMeetingHandle;
161
+ };
162
+
163
+ declare function buildEmbedUrl(options: BuildEmbedUrlOptions): string;
164
+
165
+ declare function parseEmbedEvent(data: unknown): EmbedEvent | null;
166
+
167
+ export { type BuildEmbedUrlOptions, DEFAULT_EMBED_ORIGIN, DEFAULT_IFRAME_ALLOW, EMBED_MESSAGE_SOURCE, EMBED_PROTOCOL_VERSION, EmbedCommandAction, type EmbedCommandMessage, EmbedCommandType, type EmbedEndedPayload, EmbedErrorCode, type EmbedErrorPayload, type EmbedEvent, type EmbedEventOf, type EmbedEventPayloadMap, EmbedEventType, type EmbedJoinedPayload, type EmbedLeftPayload, type EmbedMessageBase, type EmbedParticipantJoinedPayload, type EmbedParticipantLeftPayload, EmbedQueryParam, type EmbedReadyPayload, OeMeeting, type OeMeetingHandle, type OeMeetingProps, buildEmbedUrl, parseEmbedEvent, useOeMeeting };
package/dist/index.js ADDED
@@ -0,0 +1,358 @@
1
+ // src/OeMeeting.tsx
2
+ import {
3
+ forwardRef,
4
+ useId,
5
+ useMemo as useMemo2
6
+ } from "react";
7
+
8
+ // src/embed-protocol.ts
9
+ var EMBED_PROTOCOL_VERSION = 1;
10
+ var EMBED_MESSAGE_SOURCE = "oemeeting";
11
+ var DEFAULT_EMBED_ORIGIN = "https://meet.oceanedu.org";
12
+ var EmbedEventType = /* @__PURE__ */ ((EmbedEventType2) => {
13
+ EmbedEventType2["READY"] = "oemeeting:ready";
14
+ EmbedEventType2["JOINED"] = "oemeeting:joined";
15
+ EmbedEventType2["LEFT"] = "oemeeting:left";
16
+ EmbedEventType2["PARTICIPANT_JOINED"] = "oemeeting:participant-joined";
17
+ EmbedEventType2["PARTICIPANT_LEFT"] = "oemeeting:participant-left";
18
+ EmbedEventType2["ENDED"] = "oemeeting:ended";
19
+ EmbedEventType2["ERROR"] = "oemeeting:error";
20
+ return EmbedEventType2;
21
+ })(EmbedEventType || {});
22
+ var EmbedCommandType = /* @__PURE__ */ ((EmbedCommandType2) => {
23
+ EmbedCommandType2["COMMAND"] = "oemeeting:command";
24
+ return EmbedCommandType2;
25
+ })(EmbedCommandType || {});
26
+ var EmbedCommandAction = /* @__PURE__ */ ((EmbedCommandAction2) => {
27
+ EmbedCommandAction2["LEAVE"] = "leave";
28
+ EmbedCommandAction2["TOGGLE_MIC"] = "toggleMic";
29
+ EmbedCommandAction2["TOGGLE_CAMERA"] = "toggleCamera";
30
+ return EmbedCommandAction2;
31
+ })(EmbedCommandAction || {});
32
+ var EmbedErrorCode = /* @__PURE__ */ ((EmbedErrorCode2) => {
33
+ EmbedErrorCode2["TOKEN_INVALID"] = "TOKEN_INVALID";
34
+ EmbedErrorCode2["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
35
+ EmbedErrorCode2["ROOM_NOT_FOUND"] = "ROOM_NOT_FOUND";
36
+ EmbedErrorCode2["ROOM_ACCESS_DENIED"] = "ROOM_ACCESS_DENIED";
37
+ EmbedErrorCode2["CONNECTION_FAILED"] = "CONNECTION_FAILED";
38
+ EmbedErrorCode2["PROTOCOL_MISMATCH"] = "PROTOCOL_MISMATCH";
39
+ EmbedErrorCode2["UNKNOWN"] = "UNKNOWN";
40
+ return EmbedErrorCode2;
41
+ })(EmbedErrorCode || {});
42
+ var EmbedQueryParam = /* @__PURE__ */ ((EmbedQueryParam2) => {
43
+ EmbedQueryParam2["INSTANCE_ID"] = "instanceId";
44
+ EmbedQueryParam2["HOST_ORIGIN"] = "hostOrigin";
45
+ EmbedQueryParam2["JOIN_TOKEN"] = "joinToken";
46
+ EmbedQueryParam2["USER_NAME"] = "userName";
47
+ EmbedQueryParam2["EXTERNAL_USER_ID"] = "externalUserId";
48
+ EmbedQueryParam2["LANG"] = "lang";
49
+ EmbedQueryParam2["AUTO_JOIN"] = "autoJoin";
50
+ EmbedQueryParam2["HIDE_LEAVE"] = "hideLeave";
51
+ return EmbedQueryParam2;
52
+ })(EmbedQueryParam || {});
53
+
54
+ // src/buildEmbedUrl.ts
55
+ var QUERY_FLAG_ENABLED = "1";
56
+ var QUERY_FLAG_DISABLED = "0";
57
+ function toFlag(value) {
58
+ if (value === void 0) return void 0;
59
+ return value ? QUERY_FLAG_ENABLED : QUERY_FLAG_DISABLED;
60
+ }
61
+ function normalizeOrigin(origin) {
62
+ return origin.replace(/\/+$/, "");
63
+ }
64
+ function buildEmbedUrl(options) {
65
+ const roomSlug = options.roomSlug.trim();
66
+ const joinToken = options.joinToken.trim();
67
+ if (!roomSlug) {
68
+ throw new Error("OE Meeting embed requires a non-empty roomSlug.");
69
+ }
70
+ if (!joinToken) {
71
+ throw new Error("OE Meeting embed requires a non-empty joinToken.");
72
+ }
73
+ const origin = normalizeOrigin(options.origin ?? DEFAULT_EMBED_ORIGIN);
74
+ const url = new URL(`${origin}/embed/${encodeURIComponent(roomSlug)}`);
75
+ const entries = [
76
+ ["instanceId" /* INSTANCE_ID */, options.instanceId],
77
+ ["hostOrigin" /* HOST_ORIGIN */, options.hostOrigin],
78
+ ["joinToken" /* JOIN_TOKEN */, joinToken],
79
+ ["userName" /* USER_NAME */, options.userName],
80
+ ["externalUserId" /* EXTERNAL_USER_ID */, options.externalUserId],
81
+ ["lang" /* LANG */, options.lang],
82
+ ["autoJoin" /* AUTO_JOIN */, toFlag(options.autoJoin)],
83
+ ["hideLeave" /* HIDE_LEAVE */, toFlag(options.hideLeave)]
84
+ ];
85
+ for (const [key, value] of entries) {
86
+ if (value !== void 0 && value !== "") {
87
+ url.searchParams.set(key, value);
88
+ }
89
+ }
90
+ return url.toString();
91
+ }
92
+
93
+ // src/useOeMeeting.ts
94
+ import {
95
+ useCallback,
96
+ useEffect,
97
+ useImperativeHandle,
98
+ useMemo,
99
+ useRef
100
+ } from "react";
101
+
102
+ // src/parseEmbedEvent.ts
103
+ var EVENT_TYPES = new Set(Object.values(EmbedEventType));
104
+ function isRecord(value) {
105
+ return typeof value === "object" && value !== null;
106
+ }
107
+ function isOptionalString(value) {
108
+ return value === void 0 || typeof value === "string";
109
+ }
110
+ function hasValidPayload(type, payload) {
111
+ switch (type) {
112
+ case "oemeeting:ready" /* READY */:
113
+ return typeof payload.roomSlug === "string";
114
+ case "oemeeting:joined" /* JOINED */:
115
+ return typeof payload.roomSlug === "string" && typeof payload.identity === "string" && isOptionalString(payload.name) && typeof payload.joinedAt === "string";
116
+ case "oemeeting:left" /* LEFT */:
117
+ return typeof payload.roomSlug === "string" && typeof payload.identity === "string" && typeof payload.leftAt === "string" && (payload.durationMs === void 0 || typeof payload.durationMs === "number");
118
+ case "oemeeting:participant-joined" /* PARTICIPANT_JOINED */:
119
+ return typeof payload.identity === "string" && isOptionalString(payload.name) && typeof payload.participantCount === "number";
120
+ case "oemeeting:participant-left" /* PARTICIPANT_LEFT */:
121
+ return typeof payload.identity === "string" && typeof payload.participantCount === "number";
122
+ case "oemeeting:ended" /* ENDED */:
123
+ return typeof payload.roomSlug === "string" && typeof payload.endedAt === "string";
124
+ case "oemeeting:error" /* ERROR */:
125
+ return typeof payload.code === "string" && typeof payload.message === "string";
126
+ }
127
+ }
128
+ function parseEmbedEvent(data) {
129
+ if (!isRecord(data)) return null;
130
+ if (data.source !== EMBED_MESSAGE_SOURCE || data.version !== EMBED_PROTOCOL_VERSION || typeof data.instanceId !== "string" || data.instanceId.length === 0 || typeof data.type !== "string" || !EVENT_TYPES.has(data.type) || !isRecord(data.payload)) {
131
+ return null;
132
+ }
133
+ const type = data.type;
134
+ if (!hasValidPayload(type, data.payload)) return null;
135
+ return data;
136
+ }
137
+
138
+ // src/useOeMeeting.ts
139
+ function postCommand(options) {
140
+ const frameWindow = options.iframe?.contentWindow;
141
+ if (!frameWindow) return;
142
+ const message = {
143
+ source: EMBED_MESSAGE_SOURCE,
144
+ version: EMBED_PROTOCOL_VERSION,
145
+ instanceId: options.instanceId,
146
+ type: "oemeeting:command" /* COMMAND */,
147
+ action: options.action
148
+ };
149
+ frameWindow.postMessage(message, options.targetOrigin);
150
+ }
151
+ function useOeMeeting(options) {
152
+ const iframeRef = useRef(null);
153
+ const callbacksRef = useRef(options);
154
+ useEffect(() => {
155
+ callbacksRef.current = options;
156
+ }, [options]);
157
+ useEffect(() => {
158
+ const onMessage = (event) => {
159
+ const frameWindow = iframeRef.current?.contentWindow;
160
+ if (!frameWindow || event.source !== frameWindow || event.origin !== options.targetOrigin) {
161
+ return;
162
+ }
163
+ const embedEvent = parseEmbedEvent(event.data);
164
+ if (!embedEvent || embedEvent.instanceId !== options.instanceId) return;
165
+ const callbacks = callbacksRef.current;
166
+ callbacks.onEvent?.(embedEvent);
167
+ switch (embedEvent.type) {
168
+ case "oemeeting:ready" /* READY */:
169
+ callbacks.onReady?.(embedEvent);
170
+ break;
171
+ case "oemeeting:joined" /* JOINED */:
172
+ callbacks.onJoined?.(embedEvent);
173
+ break;
174
+ case "oemeeting:left" /* LEFT */:
175
+ callbacks.onLeft?.(embedEvent);
176
+ break;
177
+ case "oemeeting:participant-joined" /* PARTICIPANT_JOINED */:
178
+ callbacks.onParticipantJoined?.(embedEvent);
179
+ break;
180
+ case "oemeeting:participant-left" /* PARTICIPANT_LEFT */:
181
+ callbacks.onParticipantLeft?.(embedEvent);
182
+ break;
183
+ case "oemeeting:ended" /* ENDED */:
184
+ callbacks.onEnded?.(embedEvent);
185
+ break;
186
+ case "oemeeting:error" /* ERROR */:
187
+ callbacks.onError?.(embedEvent);
188
+ break;
189
+ }
190
+ };
191
+ window.addEventListener("message", onMessage);
192
+ return () => window.removeEventListener("message", onMessage);
193
+ }, [options.instanceId, options.targetOrigin]);
194
+ const send = useCallback(
195
+ (action) => postCommand({
196
+ iframe: iframeRef.current,
197
+ instanceId: options.instanceId,
198
+ action,
199
+ targetOrigin: options.targetOrigin
200
+ }),
201
+ [options.instanceId, options.targetOrigin]
202
+ );
203
+ const leave = useCallback(() => send("leave" /* LEAVE */), [send]);
204
+ const toggleMic = useCallback(
205
+ () => send("toggleMic" /* TOGGLE_MIC */),
206
+ [send]
207
+ );
208
+ const toggleCamera = useCallback(
209
+ () => send("toggleCamera" /* TOGGLE_CAMERA */),
210
+ [send]
211
+ );
212
+ const getIframe = useCallback(() => iframeRef.current, []);
213
+ const handle = useMemo(
214
+ () => ({ leave, toggleMic, toggleCamera, getIframe }),
215
+ [getIframe, leave, toggleCamera, toggleMic]
216
+ );
217
+ useImperativeHandle(options.handleRef, () => handle, [handle]);
218
+ return { iframeRef, handle };
219
+ }
220
+
221
+ // src/OeMeeting.tsx
222
+ import { jsx } from "react/jsx-runtime";
223
+ var DEFAULT_IFRAME_ALLOW = "camera; microphone; fullscreen; autoplay; display-capture; clipboard-write; encrypted-media";
224
+ function toCssSize(value) {
225
+ if (value === void 0) return void 0;
226
+ return typeof value === "number" ? `${value}px` : value;
227
+ }
228
+ function getOrigin(value) {
229
+ return new URL(value).origin;
230
+ }
231
+ var OeMeeting = forwardRef(
232
+ function OeMeeting2(props, ref) {
233
+ const {
234
+ roomSlug,
235
+ joinToken,
236
+ userName,
237
+ externalUserId,
238
+ origin = DEFAULT_EMBED_ORIGIN,
239
+ lang,
240
+ autoJoin = true,
241
+ hideLeave,
242
+ title = "OE Meeting room",
243
+ width = "100%",
244
+ height = 640,
245
+ className,
246
+ style,
247
+ iframeClassName,
248
+ iframeStyle,
249
+ allow = DEFAULT_IFRAME_ALLOW,
250
+ targetOrigin,
251
+ onReady,
252
+ onJoined,
253
+ onLeft,
254
+ onParticipantJoined,
255
+ onParticipantLeft,
256
+ onEnded,
257
+ onError,
258
+ onEvent
259
+ } = props;
260
+ const reactId = useId();
261
+ const instanceId = useMemo2(
262
+ () => `oem-${reactId.replace(/:/g, "")}`,
263
+ [reactId]
264
+ );
265
+ const embedOrigin = useMemo2(() => getOrigin(origin), [origin]);
266
+ const resolvedTargetOrigin = targetOrigin ?? embedOrigin;
267
+ const hostOrigin = typeof window === "undefined" ? void 0 : window.location.origin;
268
+ const src = useMemo2(
269
+ () => buildEmbedUrl({
270
+ roomSlug,
271
+ joinToken,
272
+ userName,
273
+ externalUserId,
274
+ origin,
275
+ lang,
276
+ autoJoin,
277
+ hideLeave,
278
+ instanceId,
279
+ hostOrigin
280
+ }),
281
+ [
282
+ autoJoin,
283
+ externalUserId,
284
+ hideLeave,
285
+ hostOrigin,
286
+ instanceId,
287
+ joinToken,
288
+ lang,
289
+ origin,
290
+ roomSlug,
291
+ userName
292
+ ]
293
+ );
294
+ const { iframeRef } = useOeMeeting({
295
+ instanceId,
296
+ targetOrigin: resolvedTargetOrigin,
297
+ handleRef: ref,
298
+ onReady,
299
+ onJoined,
300
+ onLeft,
301
+ onParticipantJoined,
302
+ onParticipantLeft,
303
+ onEnded,
304
+ onError,
305
+ onEvent
306
+ });
307
+ const wrapperStyle = {
308
+ width: toCssSize(width),
309
+ height: toCssSize(height),
310
+ ...style
311
+ };
312
+ const frameStyle = {
313
+ width: "100%",
314
+ height: "100%",
315
+ border: 0,
316
+ display: "block",
317
+ ...iframeStyle
318
+ };
319
+ return /* @__PURE__ */ jsx(
320
+ "div",
321
+ {
322
+ className,
323
+ style: wrapperStyle,
324
+ "data-oe-meeting-instance": instanceId,
325
+ children: /* @__PURE__ */ jsx(
326
+ "iframe",
327
+ {
328
+ ref: iframeRef,
329
+ className: iframeClassName,
330
+ style: frameStyle,
331
+ src,
332
+ title,
333
+ allow,
334
+ allowFullScreen: true,
335
+ referrerPolicy: "strict-origin-when-cross-origin"
336
+ }
337
+ )
338
+ }
339
+ );
340
+ }
341
+ );
342
+ OeMeeting.displayName = "OeMeeting";
343
+ export {
344
+ DEFAULT_EMBED_ORIGIN,
345
+ DEFAULT_IFRAME_ALLOW,
346
+ EMBED_MESSAGE_SOURCE,
347
+ EMBED_PROTOCOL_VERSION,
348
+ EmbedCommandAction,
349
+ EmbedCommandType,
350
+ EmbedErrorCode,
351
+ EmbedEventType,
352
+ EmbedQueryParam,
353
+ OeMeeting,
354
+ buildEmbedUrl,
355
+ parseEmbedEvent,
356
+ useOeMeeting
357
+ };
358
+ //# sourceMappingURL=index.js.map