@tinyweb_dev/oe-meeting-react 0.1.0 → 0.3.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/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@ import { CSSProperties, Ref } from 'react';
3
3
 
4
4
  declare const EMBED_PROTOCOL_VERSION: 1;
5
5
  declare const EMBED_MESSAGE_SOURCE: "oemeeting";
6
- declare const DEFAULT_EMBED_ORIGIN = "https://meet.oceanedu.org";
6
+ declare const DEFAULT_EMBED_ORIGIN = "https://meet.ocean.edu.vn";
7
7
  declare enum EmbedEventType {
8
8
  READY = "oemeeting:ready",
9
9
  JOINED = "oemeeting:joined",
@@ -11,7 +11,10 @@ declare enum EmbedEventType {
11
11
  PARTICIPANT_JOINED = "oemeeting:participant-joined",
12
12
  PARTICIPANT_LEFT = "oemeeting:participant-left",
13
13
  ENDED = "oemeeting:ended",
14
- ERROR = "oemeeting:error"
14
+ ERROR = "oemeeting:error",
15
+ STAGE_CHANGED = "oemeeting:stage-changed",
16
+ TRANSCRIPT_STARTED = "oemeeting:transcript-started",
17
+ RECORDING_STARTED = "oemeeting:recording-started"
15
18
  }
16
19
  declare enum EmbedCommandType {
17
20
  COMMAND = "oemeeting:command"
@@ -19,7 +22,9 @@ declare enum EmbedCommandType {
19
22
  declare enum EmbedCommandAction {
20
23
  LEAVE = "leave",
21
24
  TOGGLE_MIC = "toggleMic",
22
- TOGGLE_CAMERA = "toggleCamera"
25
+ TOGGLE_CAMERA = "toggleCamera",
26
+ OPEN_STAGE = "openStage",
27
+ CLOSE_STAGE = "closeStage"
23
28
  }
24
29
  declare enum EmbedErrorCode {
25
30
  TOKEN_INVALID = "TOKEN_INVALID",
@@ -28,8 +33,17 @@ declare enum EmbedErrorCode {
28
33
  ROOM_ACCESS_DENIED = "ROOM_ACCESS_DENIED",
29
34
  CONNECTION_FAILED = "CONNECTION_FAILED",
30
35
  PROTOCOL_MISMATCH = "PROTOCOL_MISMATCH",
36
+ STAGE_ORIGIN_DENIED = "STAGE_ORIGIN_DENIED",
37
+ STAGE_URL_INVALID = "STAGE_URL_INVALID",
38
+ TRANSCRIPT_START_FAILED = "TRANSCRIPT_START_FAILED",
39
+ RECORDING_START_FAILED = "RECORDING_START_FAILED",
31
40
  UNKNOWN = "UNKNOWN"
32
41
  }
42
+ /** Open host-owned tool id. Meeting does not catalog values. */
43
+ type StageToolId = string;
44
+ declare const MAX_STAGE_URL_LENGTH = 2048;
45
+ declare const MAX_STAGE_TOOL_ID_LENGTH = 32;
46
+ declare function isStageToolId(value: unknown): value is StageToolId;
33
47
  declare enum EmbedQueryParam {
34
48
  INSTANCE_ID = "instanceId",
35
49
  HOST_ORIGIN = "hostOrigin",
@@ -38,7 +52,23 @@ declare enum EmbedQueryParam {
38
52
  EXTERNAL_USER_ID = "externalUserId",
39
53
  LANG = "lang",
40
54
  AUTO_JOIN = "autoJoin",
41
- HIDE_LEAVE = "hideLeave"
55
+ HIDE_LEAVE = "hideLeave",
56
+ AUTO_TRANSCRIBE = "autoTranscribe",
57
+ AUTO_RECORD = "autoRecord"
58
+ }
59
+ /**
60
+ * What happened to the auto-transcribe request the embed made.
61
+ *
62
+ * `ALREADY_RUNNING` is the normal outcome for every participant after the
63
+ * first, because the transcript is a room-level asset rather than a
64
+ * per-participant one. `DISABLED` means the OE Meeting deployment has
65
+ * transcription turned off.
66
+ */
67
+ declare enum EmbedCaptureOutcome {
68
+ STARTED = "started",
69
+ ALREADY_RUNNING = "already_running",
70
+ DISABLED = "disabled",
71
+ FAILED = "failed"
42
72
  }
43
73
 
44
74
  interface EmbedMessageBase {
@@ -78,6 +108,38 @@ interface EmbedErrorPayload {
78
108
  code: EmbedErrorCode | string;
79
109
  message: string;
80
110
  }
111
+ interface EmbedStageChangedPayload {
112
+ url: string | null;
113
+ title?: string;
114
+ tool?: StageToolId;
115
+ openedBy?: string;
116
+ }
117
+ /**
118
+ * Reported once per meeting when `autoTranscribe` is set. Use `roomSlug` to
119
+ * fetch the transcript from your backend once the meeting ends.
120
+ *
121
+ * `transcriptId` is null when nothing was started (`DISABLED` or `FAILED`);
122
+ * pair a `FAILED` outcome with the `TRANSCRIPT_START_FAILED` error event for
123
+ * the reason.
124
+ */
125
+ interface EmbedTranscriptStartedPayload {
126
+ roomSlug: string;
127
+ outcome: EmbedCaptureOutcome;
128
+ transcriptId: string | null;
129
+ status: string | null;
130
+ }
131
+ /** Reported after the embed handles an `autoRecord` request. */
132
+ interface EmbedRecordingStartedPayload {
133
+ roomSlug: string;
134
+ outcome: EmbedCaptureOutcome;
135
+ recordingId: string | null;
136
+ status: string | null;
137
+ }
138
+ interface OpenStageInput {
139
+ url: string;
140
+ title?: string;
141
+ tool?: StageToolId;
142
+ }
81
143
  type EmbedEventPayloadMap = {
82
144
  [EmbedEventType.READY]: EmbedReadyPayload;
83
145
  [EmbedEventType.JOINED]: EmbedJoinedPayload;
@@ -86,6 +148,9 @@ type EmbedEventPayloadMap = {
86
148
  [EmbedEventType.PARTICIPANT_LEFT]: EmbedParticipantLeftPayload;
87
149
  [EmbedEventType.ENDED]: EmbedEndedPayload;
88
150
  [EmbedEventType.ERROR]: EmbedErrorPayload;
151
+ [EmbedEventType.STAGE_CHANGED]: EmbedStageChangedPayload;
152
+ [EmbedEventType.TRANSCRIPT_STARTED]: EmbedTranscriptStartedPayload;
153
+ [EmbedEventType.RECORDING_STARTED]: EmbedRecordingStartedPayload;
89
154
  };
90
155
  type EmbedEventByType<T extends EmbedEventType> = EmbedMessageBase & {
91
156
  type: T;
@@ -100,11 +165,14 @@ type EmbedEventOf<T extends EmbedEventType> = Extract<EmbedEvent, {
100
165
  type EmbedCommandMessage = EmbedMessageBase & {
101
166
  type: 'oemeeting:command';
102
167
  action: EmbedCommandAction;
168
+ payload?: OpenStageInput;
103
169
  };
104
170
  interface OeMeetingHandle {
105
171
  leave: () => void;
106
172
  toggleMic: () => void;
107
173
  toggleCamera: () => void;
174
+ openStage: (input: OpenStageInput) => void;
175
+ closeStage: () => void;
108
176
  getIframe: () => HTMLIFrameElement | null;
109
177
  }
110
178
  interface OeMeetingProps {
@@ -116,6 +184,15 @@ interface OeMeetingProps {
116
184
  lang?: string;
117
185
  autoJoin?: boolean;
118
186
  hideLeave?: boolean;
187
+ /**
188
+ * Start the shared transcript as soon as the embed connects. The transcript
189
+ * is a room-level asset: the first participant to connect starts it and it
190
+ * keeps running after they leave. Retrieve it afterwards from your backend
191
+ * with `GET /external-api/v1.0/rooms/:idOrSlug/transcript`.
192
+ */
193
+ autoTranscribe?: boolean;
194
+ /** Start the shared room recording as soon as the embed connects. */
195
+ autoRecord?: boolean;
119
196
  title?: string;
120
197
  width?: number | string;
121
198
  height?: number | string;
@@ -132,6 +209,9 @@ interface OeMeetingProps {
132
209
  onParticipantLeft?: (event: EmbedEventOf<EmbedEventType.PARTICIPANT_LEFT>) => void;
133
210
  onEnded?: (event: EmbedEventOf<EmbedEventType.ENDED>) => void;
134
211
  onError?: (event: EmbedEventOf<EmbedEventType.ERROR>) => void;
212
+ onStageChanged?: (event: EmbedEventOf<EmbedEventType.STAGE_CHANGED>) => void;
213
+ onTranscriptStarted?: (event: EmbedEventOf<EmbedEventType.TRANSCRIPT_STARTED>) => void;
214
+ onRecordingStarted?: (event: EmbedEventOf<EmbedEventType.RECORDING_STARTED>) => void;
135
215
  onEvent?: (event: EmbedEvent) => void;
136
216
  }
137
217
  interface BuildEmbedUrlOptions {
@@ -143,6 +223,8 @@ interface BuildEmbedUrlOptions {
143
223
  lang?: string;
144
224
  autoJoin?: boolean;
145
225
  hideLeave?: boolean;
226
+ autoTranscribe?: boolean;
227
+ autoRecord?: boolean;
146
228
  instanceId?: string;
147
229
  hostOrigin?: string;
148
230
  }
@@ -150,7 +232,7 @@ interface BuildEmbedUrlOptions {
150
232
  declare const DEFAULT_IFRAME_ALLOW = "camera; microphone; fullscreen; autoplay; display-capture; clipboard-write; encrypted-media";
151
233
  declare const OeMeeting: react.ForwardRefExoticComponent<OeMeetingProps & react.RefAttributes<OeMeetingHandle>>;
152
234
 
153
- type UseOeMeetingOptions = Pick<OeMeetingProps, 'onReady' | 'onJoined' | 'onLeft' | 'onParticipantJoined' | 'onParticipantLeft' | 'onEnded' | 'onError' | 'onEvent'> & {
235
+ type UseOeMeetingOptions = Pick<OeMeetingProps, 'onReady' | 'onJoined' | 'onLeft' | 'onParticipantJoined' | 'onParticipantLeft' | 'onEnded' | 'onError' | 'onStageChanged' | 'onTranscriptStarted' | 'onRecordingStarted' | 'onEvent'> & {
154
236
  instanceId: string;
155
237
  targetOrigin: string;
156
238
  handleRef?: Ref<OeMeetingHandle>;
@@ -164,4 +246,7 @@ declare function buildEmbedUrl(options: BuildEmbedUrlOptions): string;
164
246
 
165
247
  declare function parseEmbedEvent(data: unknown): EmbedEvent | null;
166
248
 
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 };
249
+ declare function isValidStageUrl(url: string): boolean;
250
+ declare function normalizeOpenStageInput(input: OpenStageInput): OpenStageInput | null;
251
+
252
+ export { type BuildEmbedUrlOptions, DEFAULT_EMBED_ORIGIN, DEFAULT_IFRAME_ALLOW, EMBED_MESSAGE_SOURCE, EMBED_PROTOCOL_VERSION, EmbedCaptureOutcome, 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, type EmbedRecordingStartedPayload, type EmbedStageChangedPayload, type EmbedTranscriptStartedPayload, MAX_STAGE_TOOL_ID_LENGTH, MAX_STAGE_URL_LENGTH, OeMeeting, type OeMeetingHandle, type OeMeetingProps, type OpenStageInput, type StageToolId, buildEmbedUrl, isStageToolId, isValidStageUrl, normalizeOpenStageInput, parseEmbedEvent, useOeMeeting };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { CSSProperties, Ref } from 'react';
3
3
 
4
4
  declare const EMBED_PROTOCOL_VERSION: 1;
5
5
  declare const EMBED_MESSAGE_SOURCE: "oemeeting";
6
- declare const DEFAULT_EMBED_ORIGIN = "https://meet.oceanedu.org";
6
+ declare const DEFAULT_EMBED_ORIGIN = "https://meet.ocean.edu.vn";
7
7
  declare enum EmbedEventType {
8
8
  READY = "oemeeting:ready",
9
9
  JOINED = "oemeeting:joined",
@@ -11,7 +11,10 @@ declare enum EmbedEventType {
11
11
  PARTICIPANT_JOINED = "oemeeting:participant-joined",
12
12
  PARTICIPANT_LEFT = "oemeeting:participant-left",
13
13
  ENDED = "oemeeting:ended",
14
- ERROR = "oemeeting:error"
14
+ ERROR = "oemeeting:error",
15
+ STAGE_CHANGED = "oemeeting:stage-changed",
16
+ TRANSCRIPT_STARTED = "oemeeting:transcript-started",
17
+ RECORDING_STARTED = "oemeeting:recording-started"
15
18
  }
16
19
  declare enum EmbedCommandType {
17
20
  COMMAND = "oemeeting:command"
@@ -19,7 +22,9 @@ declare enum EmbedCommandType {
19
22
  declare enum EmbedCommandAction {
20
23
  LEAVE = "leave",
21
24
  TOGGLE_MIC = "toggleMic",
22
- TOGGLE_CAMERA = "toggleCamera"
25
+ TOGGLE_CAMERA = "toggleCamera",
26
+ OPEN_STAGE = "openStage",
27
+ CLOSE_STAGE = "closeStage"
23
28
  }
24
29
  declare enum EmbedErrorCode {
25
30
  TOKEN_INVALID = "TOKEN_INVALID",
@@ -28,8 +33,17 @@ declare enum EmbedErrorCode {
28
33
  ROOM_ACCESS_DENIED = "ROOM_ACCESS_DENIED",
29
34
  CONNECTION_FAILED = "CONNECTION_FAILED",
30
35
  PROTOCOL_MISMATCH = "PROTOCOL_MISMATCH",
36
+ STAGE_ORIGIN_DENIED = "STAGE_ORIGIN_DENIED",
37
+ STAGE_URL_INVALID = "STAGE_URL_INVALID",
38
+ TRANSCRIPT_START_FAILED = "TRANSCRIPT_START_FAILED",
39
+ RECORDING_START_FAILED = "RECORDING_START_FAILED",
31
40
  UNKNOWN = "UNKNOWN"
32
41
  }
42
+ /** Open host-owned tool id. Meeting does not catalog values. */
43
+ type StageToolId = string;
44
+ declare const MAX_STAGE_URL_LENGTH = 2048;
45
+ declare const MAX_STAGE_TOOL_ID_LENGTH = 32;
46
+ declare function isStageToolId(value: unknown): value is StageToolId;
33
47
  declare enum EmbedQueryParam {
34
48
  INSTANCE_ID = "instanceId",
35
49
  HOST_ORIGIN = "hostOrigin",
@@ -38,7 +52,23 @@ declare enum EmbedQueryParam {
38
52
  EXTERNAL_USER_ID = "externalUserId",
39
53
  LANG = "lang",
40
54
  AUTO_JOIN = "autoJoin",
41
- HIDE_LEAVE = "hideLeave"
55
+ HIDE_LEAVE = "hideLeave",
56
+ AUTO_TRANSCRIBE = "autoTranscribe",
57
+ AUTO_RECORD = "autoRecord"
58
+ }
59
+ /**
60
+ * What happened to the auto-transcribe request the embed made.
61
+ *
62
+ * `ALREADY_RUNNING` is the normal outcome for every participant after the
63
+ * first, because the transcript is a room-level asset rather than a
64
+ * per-participant one. `DISABLED` means the OE Meeting deployment has
65
+ * transcription turned off.
66
+ */
67
+ declare enum EmbedCaptureOutcome {
68
+ STARTED = "started",
69
+ ALREADY_RUNNING = "already_running",
70
+ DISABLED = "disabled",
71
+ FAILED = "failed"
42
72
  }
43
73
 
44
74
  interface EmbedMessageBase {
@@ -78,6 +108,38 @@ interface EmbedErrorPayload {
78
108
  code: EmbedErrorCode | string;
79
109
  message: string;
80
110
  }
111
+ interface EmbedStageChangedPayload {
112
+ url: string | null;
113
+ title?: string;
114
+ tool?: StageToolId;
115
+ openedBy?: string;
116
+ }
117
+ /**
118
+ * Reported once per meeting when `autoTranscribe` is set. Use `roomSlug` to
119
+ * fetch the transcript from your backend once the meeting ends.
120
+ *
121
+ * `transcriptId` is null when nothing was started (`DISABLED` or `FAILED`);
122
+ * pair a `FAILED` outcome with the `TRANSCRIPT_START_FAILED` error event for
123
+ * the reason.
124
+ */
125
+ interface EmbedTranscriptStartedPayload {
126
+ roomSlug: string;
127
+ outcome: EmbedCaptureOutcome;
128
+ transcriptId: string | null;
129
+ status: string | null;
130
+ }
131
+ /** Reported after the embed handles an `autoRecord` request. */
132
+ interface EmbedRecordingStartedPayload {
133
+ roomSlug: string;
134
+ outcome: EmbedCaptureOutcome;
135
+ recordingId: string | null;
136
+ status: string | null;
137
+ }
138
+ interface OpenStageInput {
139
+ url: string;
140
+ title?: string;
141
+ tool?: StageToolId;
142
+ }
81
143
  type EmbedEventPayloadMap = {
82
144
  [EmbedEventType.READY]: EmbedReadyPayload;
83
145
  [EmbedEventType.JOINED]: EmbedJoinedPayload;
@@ -86,6 +148,9 @@ type EmbedEventPayloadMap = {
86
148
  [EmbedEventType.PARTICIPANT_LEFT]: EmbedParticipantLeftPayload;
87
149
  [EmbedEventType.ENDED]: EmbedEndedPayload;
88
150
  [EmbedEventType.ERROR]: EmbedErrorPayload;
151
+ [EmbedEventType.STAGE_CHANGED]: EmbedStageChangedPayload;
152
+ [EmbedEventType.TRANSCRIPT_STARTED]: EmbedTranscriptStartedPayload;
153
+ [EmbedEventType.RECORDING_STARTED]: EmbedRecordingStartedPayload;
89
154
  };
90
155
  type EmbedEventByType<T extends EmbedEventType> = EmbedMessageBase & {
91
156
  type: T;
@@ -100,11 +165,14 @@ type EmbedEventOf<T extends EmbedEventType> = Extract<EmbedEvent, {
100
165
  type EmbedCommandMessage = EmbedMessageBase & {
101
166
  type: 'oemeeting:command';
102
167
  action: EmbedCommandAction;
168
+ payload?: OpenStageInput;
103
169
  };
104
170
  interface OeMeetingHandle {
105
171
  leave: () => void;
106
172
  toggleMic: () => void;
107
173
  toggleCamera: () => void;
174
+ openStage: (input: OpenStageInput) => void;
175
+ closeStage: () => void;
108
176
  getIframe: () => HTMLIFrameElement | null;
109
177
  }
110
178
  interface OeMeetingProps {
@@ -116,6 +184,15 @@ interface OeMeetingProps {
116
184
  lang?: string;
117
185
  autoJoin?: boolean;
118
186
  hideLeave?: boolean;
187
+ /**
188
+ * Start the shared transcript as soon as the embed connects. The transcript
189
+ * is a room-level asset: the first participant to connect starts it and it
190
+ * keeps running after they leave. Retrieve it afterwards from your backend
191
+ * with `GET /external-api/v1.0/rooms/:idOrSlug/transcript`.
192
+ */
193
+ autoTranscribe?: boolean;
194
+ /** Start the shared room recording as soon as the embed connects. */
195
+ autoRecord?: boolean;
119
196
  title?: string;
120
197
  width?: number | string;
121
198
  height?: number | string;
@@ -132,6 +209,9 @@ interface OeMeetingProps {
132
209
  onParticipantLeft?: (event: EmbedEventOf<EmbedEventType.PARTICIPANT_LEFT>) => void;
133
210
  onEnded?: (event: EmbedEventOf<EmbedEventType.ENDED>) => void;
134
211
  onError?: (event: EmbedEventOf<EmbedEventType.ERROR>) => void;
212
+ onStageChanged?: (event: EmbedEventOf<EmbedEventType.STAGE_CHANGED>) => void;
213
+ onTranscriptStarted?: (event: EmbedEventOf<EmbedEventType.TRANSCRIPT_STARTED>) => void;
214
+ onRecordingStarted?: (event: EmbedEventOf<EmbedEventType.RECORDING_STARTED>) => void;
135
215
  onEvent?: (event: EmbedEvent) => void;
136
216
  }
137
217
  interface BuildEmbedUrlOptions {
@@ -143,6 +223,8 @@ interface BuildEmbedUrlOptions {
143
223
  lang?: string;
144
224
  autoJoin?: boolean;
145
225
  hideLeave?: boolean;
226
+ autoTranscribe?: boolean;
227
+ autoRecord?: boolean;
146
228
  instanceId?: string;
147
229
  hostOrigin?: string;
148
230
  }
@@ -150,7 +232,7 @@ interface BuildEmbedUrlOptions {
150
232
  declare const DEFAULT_IFRAME_ALLOW = "camera; microphone; fullscreen; autoplay; display-capture; clipboard-write; encrypted-media";
151
233
  declare const OeMeeting: react.ForwardRefExoticComponent<OeMeetingProps & react.RefAttributes<OeMeetingHandle>>;
152
234
 
153
- type UseOeMeetingOptions = Pick<OeMeetingProps, 'onReady' | 'onJoined' | 'onLeft' | 'onParticipantJoined' | 'onParticipantLeft' | 'onEnded' | 'onError' | 'onEvent'> & {
235
+ type UseOeMeetingOptions = Pick<OeMeetingProps, 'onReady' | 'onJoined' | 'onLeft' | 'onParticipantJoined' | 'onParticipantLeft' | 'onEnded' | 'onError' | 'onStageChanged' | 'onTranscriptStarted' | 'onRecordingStarted' | 'onEvent'> & {
154
236
  instanceId: string;
155
237
  targetOrigin: string;
156
238
  handleRef?: Ref<OeMeetingHandle>;
@@ -164,4 +246,7 @@ declare function buildEmbedUrl(options: BuildEmbedUrlOptions): string;
164
246
 
165
247
  declare function parseEmbedEvent(data: unknown): EmbedEvent | null;
166
248
 
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 };
249
+ declare function isValidStageUrl(url: string): boolean;
250
+ declare function normalizeOpenStageInput(input: OpenStageInput): OpenStageInput | null;
251
+
252
+ export { type BuildEmbedUrlOptions, DEFAULT_EMBED_ORIGIN, DEFAULT_IFRAME_ALLOW, EMBED_MESSAGE_SOURCE, EMBED_PROTOCOL_VERSION, EmbedCaptureOutcome, 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, type EmbedRecordingStartedPayload, type EmbedStageChangedPayload, type EmbedTranscriptStartedPayload, MAX_STAGE_TOOL_ID_LENGTH, MAX_STAGE_URL_LENGTH, OeMeeting, type OeMeetingHandle, type OeMeetingProps, type OpenStageInput, type StageToolId, buildEmbedUrl, isStageToolId, isValidStageUrl, normalizeOpenStageInput, parseEmbedEvent, useOeMeeting };
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  // src/embed-protocol.ts
9
9
  var EMBED_PROTOCOL_VERSION = 1;
10
10
  var EMBED_MESSAGE_SOURCE = "oemeeting";
11
- var DEFAULT_EMBED_ORIGIN = "https://meet.oceanedu.org";
11
+ var DEFAULT_EMBED_ORIGIN = "https://meet.ocean.edu.vn";
12
12
  var EmbedEventType = /* @__PURE__ */ ((EmbedEventType2) => {
13
13
  EmbedEventType2["READY"] = "oemeeting:ready";
14
14
  EmbedEventType2["JOINED"] = "oemeeting:joined";
@@ -17,6 +17,9 @@ var EmbedEventType = /* @__PURE__ */ ((EmbedEventType2) => {
17
17
  EmbedEventType2["PARTICIPANT_LEFT"] = "oemeeting:participant-left";
18
18
  EmbedEventType2["ENDED"] = "oemeeting:ended";
19
19
  EmbedEventType2["ERROR"] = "oemeeting:error";
20
+ EmbedEventType2["STAGE_CHANGED"] = "oemeeting:stage-changed";
21
+ EmbedEventType2["TRANSCRIPT_STARTED"] = "oemeeting:transcript-started";
22
+ EmbedEventType2["RECORDING_STARTED"] = "oemeeting:recording-started";
20
23
  return EmbedEventType2;
21
24
  })(EmbedEventType || {});
22
25
  var EmbedCommandType = /* @__PURE__ */ ((EmbedCommandType2) => {
@@ -27,6 +30,8 @@ var EmbedCommandAction = /* @__PURE__ */ ((EmbedCommandAction2) => {
27
30
  EmbedCommandAction2["LEAVE"] = "leave";
28
31
  EmbedCommandAction2["TOGGLE_MIC"] = "toggleMic";
29
32
  EmbedCommandAction2["TOGGLE_CAMERA"] = "toggleCamera";
33
+ EmbedCommandAction2["OPEN_STAGE"] = "openStage";
34
+ EmbedCommandAction2["CLOSE_STAGE"] = "closeStage";
30
35
  return EmbedCommandAction2;
31
36
  })(EmbedCommandAction || {});
32
37
  var EmbedErrorCode = /* @__PURE__ */ ((EmbedErrorCode2) => {
@@ -36,9 +41,19 @@ var EmbedErrorCode = /* @__PURE__ */ ((EmbedErrorCode2) => {
36
41
  EmbedErrorCode2["ROOM_ACCESS_DENIED"] = "ROOM_ACCESS_DENIED";
37
42
  EmbedErrorCode2["CONNECTION_FAILED"] = "CONNECTION_FAILED";
38
43
  EmbedErrorCode2["PROTOCOL_MISMATCH"] = "PROTOCOL_MISMATCH";
44
+ EmbedErrorCode2["STAGE_ORIGIN_DENIED"] = "STAGE_ORIGIN_DENIED";
45
+ EmbedErrorCode2["STAGE_URL_INVALID"] = "STAGE_URL_INVALID";
46
+ EmbedErrorCode2["TRANSCRIPT_START_FAILED"] = "TRANSCRIPT_START_FAILED";
47
+ EmbedErrorCode2["RECORDING_START_FAILED"] = "RECORDING_START_FAILED";
39
48
  EmbedErrorCode2["UNKNOWN"] = "UNKNOWN";
40
49
  return EmbedErrorCode2;
41
50
  })(EmbedErrorCode || {});
51
+ var MAX_STAGE_URL_LENGTH = 2048;
52
+ var MAX_STAGE_TOOL_ID_LENGTH = 32;
53
+ var STAGE_TOOL_ID_PATTERN = /^[a-z][a-z0-9._-]{0,31}$/;
54
+ function isStageToolId(value) {
55
+ return typeof value === "string" && value.length > 0 && value.length <= MAX_STAGE_TOOL_ID_LENGTH && STAGE_TOOL_ID_PATTERN.test(value);
56
+ }
42
57
  var EmbedQueryParam = /* @__PURE__ */ ((EmbedQueryParam2) => {
43
58
  EmbedQueryParam2["INSTANCE_ID"] = "instanceId";
44
59
  EmbedQueryParam2["HOST_ORIGIN"] = "hostOrigin";
@@ -48,8 +63,17 @@ var EmbedQueryParam = /* @__PURE__ */ ((EmbedQueryParam2) => {
48
63
  EmbedQueryParam2["LANG"] = "lang";
49
64
  EmbedQueryParam2["AUTO_JOIN"] = "autoJoin";
50
65
  EmbedQueryParam2["HIDE_LEAVE"] = "hideLeave";
66
+ EmbedQueryParam2["AUTO_TRANSCRIBE"] = "autoTranscribe";
67
+ EmbedQueryParam2["AUTO_RECORD"] = "autoRecord";
51
68
  return EmbedQueryParam2;
52
69
  })(EmbedQueryParam || {});
70
+ var EmbedCaptureOutcome = /* @__PURE__ */ ((EmbedCaptureOutcome2) => {
71
+ EmbedCaptureOutcome2["STARTED"] = "started";
72
+ EmbedCaptureOutcome2["ALREADY_RUNNING"] = "already_running";
73
+ EmbedCaptureOutcome2["DISABLED"] = "disabled";
74
+ EmbedCaptureOutcome2["FAILED"] = "failed";
75
+ return EmbedCaptureOutcome2;
76
+ })(EmbedCaptureOutcome || {});
53
77
 
54
78
  // src/buildEmbedUrl.ts
55
79
  var QUERY_FLAG_ENABLED = "1";
@@ -80,7 +104,9 @@ function buildEmbedUrl(options) {
80
104
  ["externalUserId" /* EXTERNAL_USER_ID */, options.externalUserId],
81
105
  ["lang" /* LANG */, options.lang],
82
106
  ["autoJoin" /* AUTO_JOIN */, toFlag(options.autoJoin)],
83
- ["hideLeave" /* HIDE_LEAVE */, toFlag(options.hideLeave)]
107
+ ["hideLeave" /* HIDE_LEAVE */, toFlag(options.hideLeave)],
108
+ ["autoTranscribe" /* AUTO_TRANSCRIBE */, toFlag(options.autoTranscribe)],
109
+ ["autoRecord" /* AUTO_RECORD */, toFlag(options.autoRecord)]
84
110
  ];
85
111
  for (const [key, value] of entries) {
86
112
  if (value !== void 0 && value !== "") {
@@ -99,6 +125,31 @@ import {
99
125
  useRef
100
126
  } from "react";
101
127
 
128
+ // src/openStage.ts
129
+ function isValidStageUrl(url) {
130
+ if (url.length === 0 || url.length > MAX_STAGE_URL_LENGTH) return false;
131
+ try {
132
+ const parsed = new URL(url);
133
+ if (parsed.protocol === "https:") return true;
134
+ if (parsed.protocol === "http:") {
135
+ return parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1";
136
+ }
137
+ return false;
138
+ } catch {
139
+ return false;
140
+ }
141
+ }
142
+ function normalizeOpenStageInput(input) {
143
+ const url = input.url.trim();
144
+ if (!isValidStageUrl(url)) return null;
145
+ const title = input.title?.trim();
146
+ return {
147
+ url,
148
+ ...title ? { title: title.slice(0, 200) } : {},
149
+ ...isStageToolId(input.tool) ? { tool: input.tool } : {}
150
+ };
151
+ }
152
+
102
153
  // src/parseEmbedEvent.ts
103
154
  var EVENT_TYPES = new Set(Object.values(EmbedEventType));
104
155
  function isRecord(value) {
@@ -107,6 +158,13 @@ function isRecord(value) {
107
158
  function isOptionalString(value) {
108
159
  return value === void 0 || typeof value === "string";
109
160
  }
161
+ function isNullableString(value) {
162
+ return value === null || typeof value === "string";
163
+ }
164
+ var CAPTURE_OUTCOMES = new Set(Object.values(EmbedCaptureOutcome));
165
+ function isCaptureOutcome(value) {
166
+ return typeof value === "string" && CAPTURE_OUTCOMES.has(value);
167
+ }
110
168
  function hasValidPayload(type, payload) {
111
169
  switch (type) {
112
170
  case "oemeeting:ready" /* READY */:
@@ -123,6 +181,12 @@ function hasValidPayload(type, payload) {
123
181
  return typeof payload.roomSlug === "string" && typeof payload.endedAt === "string";
124
182
  case "oemeeting:error" /* ERROR */:
125
183
  return typeof payload.code === "string" && typeof payload.message === "string";
184
+ case "oemeeting:stage-changed" /* STAGE_CHANGED */:
185
+ return (payload.url === null || typeof payload.url === "string") && isOptionalString(payload.title) && isOptionalString(payload.tool) && isOptionalString(payload.openedBy);
186
+ case "oemeeting:transcript-started" /* TRANSCRIPT_STARTED */:
187
+ return typeof payload.roomSlug === "string" && isCaptureOutcome(payload.outcome) && isNullableString(payload.transcriptId) && isNullableString(payload.status);
188
+ case "oemeeting:recording-started" /* RECORDING_STARTED */:
189
+ return typeof payload.roomSlug === "string" && isCaptureOutcome(payload.outcome) && isNullableString(payload.recordingId) && isNullableString(payload.status);
126
190
  }
127
191
  }
128
192
  function parseEmbedEvent(data) {
@@ -144,7 +208,8 @@ function postCommand(options) {
144
208
  version: EMBED_PROTOCOL_VERSION,
145
209
  instanceId: options.instanceId,
146
210
  type: "oemeeting:command" /* COMMAND */,
147
- action: options.action
211
+ action: options.action,
212
+ ...options.payload ? { payload: options.payload } : {}
148
213
  };
149
214
  frameWindow.postMessage(message, options.targetOrigin);
150
215
  }
@@ -186,17 +251,27 @@ function useOeMeeting(options) {
186
251
  case "oemeeting:error" /* ERROR */:
187
252
  callbacks.onError?.(embedEvent);
188
253
  break;
254
+ case "oemeeting:stage-changed" /* STAGE_CHANGED */:
255
+ callbacks.onStageChanged?.(embedEvent);
256
+ break;
257
+ case "oemeeting:transcript-started" /* TRANSCRIPT_STARTED */:
258
+ callbacks.onTranscriptStarted?.(embedEvent);
259
+ break;
260
+ case "oemeeting:recording-started" /* RECORDING_STARTED */:
261
+ callbacks.onRecordingStarted?.(embedEvent);
262
+ break;
189
263
  }
190
264
  };
191
265
  window.addEventListener("message", onMessage);
192
266
  return () => window.removeEventListener("message", onMessage);
193
267
  }, [options.instanceId, options.targetOrigin]);
194
268
  const send = useCallback(
195
- (action) => postCommand({
269
+ (action, payload) => postCommand({
196
270
  iframe: iframeRef.current,
197
271
  instanceId: options.instanceId,
198
272
  action,
199
- targetOrigin: options.targetOrigin
273
+ targetOrigin: options.targetOrigin,
274
+ payload
200
275
  }),
201
276
  [options.instanceId, options.targetOrigin]
202
277
  );
@@ -209,10 +284,29 @@ function useOeMeeting(options) {
209
284
  () => send("toggleCamera" /* TOGGLE_CAMERA */),
210
285
  [send]
211
286
  );
287
+ const openStage = useCallback(
288
+ (input) => {
289
+ const normalized = normalizeOpenStageInput(input);
290
+ if (!normalized) return;
291
+ send("openStage" /* OPEN_STAGE */, normalized);
292
+ },
293
+ [send]
294
+ );
295
+ const closeStage = useCallback(
296
+ () => send("closeStage" /* CLOSE_STAGE */),
297
+ [send]
298
+ );
212
299
  const getIframe = useCallback(() => iframeRef.current, []);
213
300
  const handle = useMemo(
214
- () => ({ leave, toggleMic, toggleCamera, getIframe }),
215
- [getIframe, leave, toggleCamera, toggleMic]
301
+ () => ({
302
+ leave,
303
+ toggleMic,
304
+ toggleCamera,
305
+ openStage,
306
+ closeStage,
307
+ getIframe
308
+ }),
309
+ [closeStage, getIframe, leave, openStage, toggleCamera, toggleMic]
216
310
  );
217
311
  useImperativeHandle(options.handleRef, () => handle, [handle]);
218
312
  return { iframeRef, handle };
@@ -239,6 +333,8 @@ var OeMeeting = forwardRef(
239
333
  lang,
240
334
  autoJoin = true,
241
335
  hideLeave,
336
+ autoTranscribe,
337
+ autoRecord,
242
338
  title = "OE Meeting room",
243
339
  width = "100%",
244
340
  height = 640,
@@ -255,6 +351,9 @@ var OeMeeting = forwardRef(
255
351
  onParticipantLeft,
256
352
  onEnded,
257
353
  onError,
354
+ onStageChanged,
355
+ onTranscriptStarted,
356
+ onRecordingStarted,
258
357
  onEvent
259
358
  } = props;
260
359
  const reactId = useId();
@@ -275,11 +374,15 @@ var OeMeeting = forwardRef(
275
374
  lang,
276
375
  autoJoin,
277
376
  hideLeave,
377
+ autoTranscribe,
378
+ autoRecord,
278
379
  instanceId,
279
380
  hostOrigin
280
381
  }),
281
382
  [
282
383
  autoJoin,
384
+ autoRecord,
385
+ autoTranscribe,
283
386
  externalUserId,
284
387
  hideLeave,
285
388
  hostOrigin,
@@ -302,6 +405,9 @@ var OeMeeting = forwardRef(
302
405
  onParticipantLeft,
303
406
  onEnded,
304
407
  onError,
408
+ onStageChanged,
409
+ onTranscriptStarted,
410
+ onRecordingStarted,
305
411
  onEvent
306
412
  });
307
413
  const wrapperStyle = {
@@ -345,13 +451,19 @@ export {
345
451
  DEFAULT_IFRAME_ALLOW,
346
452
  EMBED_MESSAGE_SOURCE,
347
453
  EMBED_PROTOCOL_VERSION,
454
+ EmbedCaptureOutcome,
348
455
  EmbedCommandAction,
349
456
  EmbedCommandType,
350
457
  EmbedErrorCode,
351
458
  EmbedEventType,
352
459
  EmbedQueryParam,
460
+ MAX_STAGE_TOOL_ID_LENGTH,
461
+ MAX_STAGE_URL_LENGTH,
353
462
  OeMeeting,
354
463
  buildEmbedUrl,
464
+ isStageToolId,
465
+ isValidStageUrl,
466
+ normalizeOpenStageInput,
355
467
  parseEmbedEvent,
356
468
  useOeMeeting
357
469
  };