@ai-matrx/meet 0.11.43 → 0.11.44
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/CHANGELOG.md +6 -0
- package/dist/core.cjs +148 -13
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +96 -1
- package/dist/core.d.ts +96 -1
- package/dist/core.js +148 -13
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +148 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +148 -13
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +385 -25
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +791 -431
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +262 -15
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.d.cts +2 -1
- package/dist/skins/meet.d.ts +2 -1
- package/dist/skins/meet.js +609 -362
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -146,6 +146,7 @@ __export(src_exports, {
|
|
|
146
146
|
createReconnectPolicy: () => createReconnectPolicy,
|
|
147
147
|
createRecordingController: () => createRecordingController,
|
|
148
148
|
createRoomEngine: () => createRoomEngine,
|
|
149
|
+
createSpeakingWhileMutedDetector: () => createSpeakingWhileMutedDetector,
|
|
149
150
|
createTokenClient: () => createTokenClient,
|
|
150
151
|
createWebDeviceStorage: () => createWebDeviceStorage,
|
|
151
152
|
createWebEffectsStorage: () => createWebEffectsStorage,
|
|
@@ -154,6 +155,7 @@ __export(src_exports, {
|
|
|
154
155
|
createWebRoomTokenStorage: () => createWebRoomTokenStorage,
|
|
155
156
|
defaultCaptionLanguage: () => defaultCaptionLanguage,
|
|
156
157
|
detectBrowser: () => detectBrowser,
|
|
158
|
+
detectCapabilities: () => detectCapabilities,
|
|
157
159
|
detectOs: () => detectOs,
|
|
158
160
|
deviceChipLabel: () => deviceChipLabel,
|
|
159
161
|
deviceFixSteps: () => deviceFixSteps,
|
|
@@ -178,6 +180,7 @@ __export(src_exports, {
|
|
|
178
180
|
isLinkFollower: () => isLinkFollower,
|
|
179
181
|
isListenOnly: () => isListenOnly,
|
|
180
182
|
isLivePhase: () => isLivePhase,
|
|
183
|
+
isMobileUserAgent: () => isMobileUserAgent,
|
|
181
184
|
isNoteTaker: () => isNoteTaker,
|
|
182
185
|
isObserverRole: () => isObserverRole,
|
|
183
186
|
isRealName: () => isRealName,
|
|
@@ -269,6 +272,7 @@ __export(src_exports, {
|
|
|
269
272
|
transcriptDocument: () => transcriptDocument,
|
|
270
273
|
unavailableFrom: () => unavailableFrom,
|
|
271
274
|
uniqueAttendees: () => uniqueAttendees,
|
|
275
|
+
unsupportedWords: () => unsupportedWords,
|
|
272
276
|
untranslatedLines: () => untranslatedLines,
|
|
273
277
|
userTopic: () => userTopic,
|
|
274
278
|
wasRefused: () => wasRefused,
|
|
@@ -3782,11 +3786,13 @@ function consentPending(policy, role, recordingOn, given) {
|
|
|
3782
3786
|
}
|
|
3783
3787
|
|
|
3784
3788
|
// src/core/attendance.ts
|
|
3789
|
+
var IDLE_PREVIEW = { state: "idle", unavailable: null };
|
|
3785
3790
|
var IDLE_MEDIA_REGION = {
|
|
3786
3791
|
permission: { microphone: "unknown", camera: "unknown" },
|
|
3787
3792
|
audioOutput: "ok",
|
|
3788
3793
|
notice: null,
|
|
3789
|
-
offer: null
|
|
3794
|
+
offer: null,
|
|
3795
|
+
preview: { microphone: IDLE_PREVIEW, camera: IDLE_PREVIEW }
|
|
3790
3796
|
};
|
|
3791
3797
|
var IDLE_TRACK = { enabled: false, unavailable: null };
|
|
3792
3798
|
var IDLE_MEDIA = {
|
|
@@ -4713,6 +4719,47 @@ function gridColumns(count2) {
|
|
|
4713
4719
|
return 5;
|
|
4714
4720
|
}
|
|
4715
4721
|
|
|
4722
|
+
// src/core/capabilities.ts
|
|
4723
|
+
var IN_APP = [
|
|
4724
|
+
[/Instagram/i, "Instagram"],
|
|
4725
|
+
[/FBAN|FBAV|FB_IAB/i, "Facebook"],
|
|
4726
|
+
[/LinkedInApp/i, "LinkedIn"],
|
|
4727
|
+
[/MicroMessenger/i, "WeChat"],
|
|
4728
|
+
[/Snapchat/i, "Snapchat"],
|
|
4729
|
+
[/\bLine\//i, "LINE"],
|
|
4730
|
+
[/Twitter|TwitterAndroid/i, "X"],
|
|
4731
|
+
[/TikTok|musical_ly|BytedanceWebview/i, "TikTok"]
|
|
4732
|
+
];
|
|
4733
|
+
function isMobileUserAgent(userAgent, maxTouchPoints = 0) {
|
|
4734
|
+
if (/iPhone|iPod|Android|Mobile|iPad/i.test(userAgent)) return true;
|
|
4735
|
+
return /Macintosh/.test(userAgent) && maxTouchPoints > 1;
|
|
4736
|
+
}
|
|
4737
|
+
function detectCapabilities(scope = typeof globalThis === "undefined" ? null : globalThis) {
|
|
4738
|
+
if (scope === null || scope.navigator === void 0) {
|
|
4739
|
+
return { canJoin: true, reason: null, inAppBrowser: null, mobile: false, canShareScreen: false };
|
|
4740
|
+
}
|
|
4741
|
+
const ua = scope.navigator.userAgent ?? "";
|
|
4742
|
+
const webrtc = typeof scope.RTCPeerConnection === "function" || typeof scope.webkitRTCPeerConnection === "function";
|
|
4743
|
+
const mobile = isMobileUserAgent(ua, scope.navigator.maxTouchPoints ?? 0);
|
|
4744
|
+
const inAppBrowser = IN_APP.find(([pattern]) => pattern.test(ua))?.[1] ?? null;
|
|
4745
|
+
return {
|
|
4746
|
+
canJoin: webrtc,
|
|
4747
|
+
reason: webrtc ? null : "no_webrtc",
|
|
4748
|
+
inAppBrowser,
|
|
4749
|
+
mobile,
|
|
4750
|
+
canShareScreen: !mobile && typeof scope.navigator.mediaDevices?.getDisplayMedia === "function"
|
|
4751
|
+
};
|
|
4752
|
+
}
|
|
4753
|
+
function unsupportedWords(capabilities) {
|
|
4754
|
+
if (capabilities.inAppBrowser !== null) {
|
|
4755
|
+
return {
|
|
4756
|
+
title: `${capabilities.inAppBrowser}'s browser can't join calls`,
|
|
4757
|
+
body: "Open this link in Chrome, Safari, Edge or Firefox"
|
|
4758
|
+
};
|
|
4759
|
+
}
|
|
4760
|
+
return { title: "This browser can't join calls", body: "Open this link in Chrome, Safari, Edge or Firefox" };
|
|
4761
|
+
}
|
|
4762
|
+
|
|
4716
4763
|
// src/core/room-driver.ts
|
|
4717
4764
|
var DATA_TOPICS = {
|
|
4718
4765
|
reaction: "mx.reaction",
|
|
@@ -4867,7 +4914,15 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4867
4914
|
created.on(RoomEvent.ParticipantConnected, roster).on(RoomEvent.ParticipantDisconnected, (participant, reason) => {
|
|
4868
4915
|
handlers.participantLeft?.(participant.identity, reasonName(reason));
|
|
4869
4916
|
roster();
|
|
4870
|
-
}).on(RoomEvent.TrackSubscribed, roster).on(RoomEvent.TrackUnsubscribed, roster).on(RoomEvent.TrackMuted, roster).on(RoomEvent.TrackUnmuted, roster).on(RoomEvent.LocalTrackPublished,
|
|
4917
|
+
}).on(RoomEvent.TrackSubscribed, roster).on(RoomEvent.TrackUnsubscribed, roster).on(RoomEvent.TrackMuted, roster).on(RoomEvent.TrackUnmuted, roster).on(RoomEvent.LocalTrackPublished, (publication) => {
|
|
4918
|
+
if (publication.source === Track.Source.ScreenShare) {
|
|
4919
|
+
const ended = () => {
|
|
4920
|
+
void created.localParticipant.setScreenShareEnabled(false).catch(() => void 0);
|
|
4921
|
+
};
|
|
4922
|
+
publication.track?.mediaStreamTrack.addEventListener("ended", ended, { once: true });
|
|
4923
|
+
}
|
|
4924
|
+
roster();
|
|
4925
|
+
}).on(RoomEvent.LocalTrackUnpublished, roster).on(RoomEvent.ParticipantNameChanged, roster).on(RoomEvent.ParticipantAttributesChanged, roster).on(RoomEvent.ParticipantMetadataChanged, roster).on(RoomEvent.RoomMetadataChanged, (metadata) => {
|
|
4871
4926
|
handlers.roomMetadata?.(metadata ?? "");
|
|
4872
4927
|
}).on(RoomEvent.AudioPlaybackStatusChanged, (canPlay) => {
|
|
4873
4928
|
handlers.audioPlayback?.(canPlay);
|
|
@@ -5008,7 +5063,10 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
5008
5063
|
},
|
|
5009
5064
|
async setScreenShareEnabled(enabled) {
|
|
5010
5065
|
try {
|
|
5011
|
-
await requireRoom("setScreenShareEnabled").localParticipant.setScreenShareEnabled(
|
|
5066
|
+
await requireRoom("setScreenShareEnabled").localParticipant.setScreenShareEnabled(
|
|
5067
|
+
enabled,
|
|
5068
|
+
enabled ? { audio: true, systemAudio: "include" } : void 0
|
|
5069
|
+
);
|
|
5012
5070
|
} catch (error) {
|
|
5013
5071
|
throw normalizeScreenShareError(error, "meet.setScreenShareEnabled");
|
|
5014
5072
|
}
|
|
@@ -5047,8 +5105,13 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
5047
5105
|
supportsVideoEffects() {
|
|
5048
5106
|
return videoEffectsSupported();
|
|
5049
5107
|
},
|
|
5108
|
+
screenShareHasAudio() {
|
|
5109
|
+
const target = room;
|
|
5110
|
+
if (target === null) return false;
|
|
5111
|
+
return target.localParticipant.getTrackPublications().some((p) => String(p.source) === "screen_share_audio" && p.track !== void 0);
|
|
5112
|
+
},
|
|
5050
5113
|
supportsScreenShare() {
|
|
5051
|
-
return
|
|
5114
|
+
return detectCapabilities().canShareScreen;
|
|
5052
5115
|
},
|
|
5053
5116
|
attach(identity, kind, element) {
|
|
5054
5117
|
const target = requireRoom("attach");
|
|
@@ -6353,7 +6416,7 @@ function deviceFixSteps(kind, reason, where) {
|
|
|
6353
6416
|
case "safari":
|
|
6354
6417
|
return where.os === "ios" ? [`Settings \u203A Apps \u203A Safari \u203A ${device}`, "Choose Allow", "Return here and press Try again"] : ["Safari \u203A Settings for This Website", `Set ${device} to Allow`, "Press Try again"];
|
|
6355
6418
|
default:
|
|
6356
|
-
return ["Click the icon
|
|
6419
|
+
return ["Click the site settings icon in the address bar", `Set ${device} to Allow`, "Press Try again"];
|
|
6357
6420
|
}
|
|
6358
6421
|
case "blocked_os": {
|
|
6359
6422
|
const app = where.browser === "chrome" ? "Google Chrome" : where.browser === "edge" ? "Microsoft Edge" : where.browser === "firefox" ? "Firefox" : "your browser";
|
|
@@ -6451,7 +6514,7 @@ function createMediaSupervisor(options) {
|
|
|
6451
6514
|
function setRegion(next) {
|
|
6452
6515
|
const current = region();
|
|
6453
6516
|
const merged = { ...current, ...next };
|
|
6454
|
-
if (merged.audioOutput === current.audioOutput && merged.notice === current.notice && merged.offer === current.offer && merged.permission.microphone === current.permission.microphone && merged.permission.camera === current.permission.camera) {
|
|
6517
|
+
if (merged.audioOutput === current.audioOutput && merged.notice === current.notice && merged.offer === current.offer && merged.preview === current.preview && merged.permission.microphone === current.permission.microphone && merged.permission.camera === current.permission.camera) {
|
|
6455
6518
|
return;
|
|
6456
6519
|
}
|
|
6457
6520
|
store.patch({ mediaRegion: merged });
|
|
@@ -6547,7 +6610,7 @@ function createMediaSupervisor(options) {
|
|
|
6547
6610
|
if (permission !== "unknown") setPermission(kind, permission);
|
|
6548
6611
|
return unavailableFrom(normalized, classifyDeviceFailure(normalized, permission));
|
|
6549
6612
|
}
|
|
6550
|
-
|
|
6613
|
+
const api = {
|
|
6551
6614
|
start() {
|
|
6552
6615
|
if (started || platform === null) return;
|
|
6553
6616
|
started = true;
|
|
@@ -6569,6 +6632,16 @@ function createMediaSupervisor(options) {
|
|
|
6569
6632
|
started = false;
|
|
6570
6633
|
},
|
|
6571
6634
|
unavailable,
|
|
6635
|
+
async preview(kind, outcome) {
|
|
6636
|
+
api.start();
|
|
6637
|
+
let next;
|
|
6638
|
+
if (typeof outcome === "string") next = { state: outcome, unavailable: null };
|
|
6639
|
+
else next = { state: "unavailable", unavailable: await unavailable(outcome.error, kind, `meet.${kind}Preview`) };
|
|
6640
|
+
const current = region().preview;
|
|
6641
|
+
const was = current[kind];
|
|
6642
|
+
if (was.state === next.state && was.unavailable?.reason === next.unavailable?.reason && was.unavailable?.message === next.unavailable?.message) return;
|
|
6643
|
+
setRegion({ preview: { ...region().preview, [kind]: next } });
|
|
6644
|
+
},
|
|
6572
6645
|
onAudioPlayback(canPlay) {
|
|
6573
6646
|
setRegion({ audioOutput: canPlay ? "ok" : "blocked" });
|
|
6574
6647
|
},
|
|
@@ -6627,6 +6700,7 @@ function createMediaSupervisor(options) {
|
|
|
6627
6700
|
setRegion({ notice: null });
|
|
6628
6701
|
}
|
|
6629
6702
|
};
|
|
6703
|
+
return api;
|
|
6630
6704
|
}
|
|
6631
6705
|
|
|
6632
6706
|
// src/core/room.ts
|
|
@@ -6788,7 +6862,8 @@ function createRoomEngine(options) {
|
|
|
6788
6862
|
message: normalized.message,
|
|
6789
6863
|
remedy: normalized.remedy,
|
|
6790
6864
|
reason: normalized.reason,
|
|
6791
|
-
retryAt: normalized.retryAfterSeconds === null ? null : now() + normalized.retryAfterSeconds * 1e3
|
|
6865
|
+
retryAt: normalized.retryAfterSeconds === null ? null : now() + normalized.retryAfterSeconds * 1e3,
|
|
6866
|
+
stage: "join"
|
|
6792
6867
|
}
|
|
6793
6868
|
});
|
|
6794
6869
|
store.dispatch({ type: "join_failed", reason: normalized.reason ?? null });
|
|
@@ -7179,6 +7254,10 @@ function createRoomEngine(options) {
|
|
|
7179
7254
|
}
|
|
7180
7255
|
departures.clear();
|
|
7181
7256
|
liveRoster = list;
|
|
7257
|
+
const localNow = list.find((p) => p.isLocal);
|
|
7258
|
+
if (localNow !== void 0 && !localNow.screenSharing && store.snapshot().share.state === "presenting") {
|
|
7259
|
+
store.patch({ share: NO_SHARE });
|
|
7260
|
+
}
|
|
7182
7261
|
const merged = mergeGhosts(list, ghosts, at);
|
|
7183
7262
|
ghosts = merged.kept;
|
|
7184
7263
|
const people = /* @__PURE__ */ new Map();
|
|
@@ -7398,7 +7477,10 @@ function createRoomEngine(options) {
|
|
|
7398
7477
|
try {
|
|
7399
7478
|
await driver.setScreenShareEnabled(enabled);
|
|
7400
7479
|
ambiguousShareDenials = 0;
|
|
7401
|
-
|
|
7480
|
+
const audio = enabled ? driver?.screenShareHasAudio?.() : void 0;
|
|
7481
|
+
store.patch({
|
|
7482
|
+
share: { state: enabled ? "presenting" : "none", reason: null, remedy: null, at: now(), ...audio !== void 0 ? { audio } : {} }
|
|
7483
|
+
});
|
|
7402
7484
|
} catch (error) {
|
|
7403
7485
|
const kind = classifyScreenShareError(error);
|
|
7404
7486
|
if (kind === "ambiguous") {
|
|
@@ -7465,13 +7547,14 @@ function createRoomEngine(options) {
|
|
|
7465
7547
|
return driver?.supportsVideoEffects?.() ?? false;
|
|
7466
7548
|
},
|
|
7467
7549
|
supportsScreenShare() {
|
|
7468
|
-
return driver?.supportsScreenShare?.() ??
|
|
7550
|
+
return driver?.supportsScreenShare?.() ?? detectCapabilities().canShareScreen;
|
|
7469
7551
|
},
|
|
7470
7552
|
async switchDevice(kind, deviceId) {
|
|
7471
7553
|
if (driver === null) return;
|
|
7472
7554
|
await driver.switchDevice(kind, deviceId);
|
|
7473
7555
|
},
|
|
7474
7556
|
enableAudio: () => media.enableAudio(),
|
|
7557
|
+
previewDevice: (kind, outcome) => media.preview(kind, outcome),
|
|
7475
7558
|
acceptDeviceOffer: () => media.acceptOffer(),
|
|
7476
7559
|
dismissDeviceOffer: () => media.dismissOffer(),
|
|
7477
7560
|
dismissDeviceNotice: () => media.dismissNotice(),
|
|
@@ -8502,6 +8585,21 @@ function observedDevice(track, permission = "unknown", held = null) {
|
|
|
8502
8585
|
const reason = deviceUnavailableReason(track, permission);
|
|
8503
8586
|
return reason === null ? "muted_by_me" : `unavailable:${reason}`;
|
|
8504
8587
|
}
|
|
8588
|
+
function observedPreview(preview, permission = "unknown") {
|
|
8589
|
+
if (permission === "denied") return "unavailable:denied";
|
|
8590
|
+
switch (preview.state) {
|
|
8591
|
+
case "on":
|
|
8592
|
+
return "on";
|
|
8593
|
+
case "off":
|
|
8594
|
+
return "muted_by_me";
|
|
8595
|
+
case "prompting":
|
|
8596
|
+
return "prompting";
|
|
8597
|
+
case "unavailable":
|
|
8598
|
+
return `unavailable:${preview.unavailable?.reason ?? "failed"}`;
|
|
8599
|
+
default:
|
|
8600
|
+
return null;
|
|
8601
|
+
}
|
|
8602
|
+
}
|
|
8505
8603
|
function endedRecord(snapshot, given) {
|
|
8506
8604
|
const record = snapshot?.meeting ?? given;
|
|
8507
8605
|
return record !== null && record.endedAt !== null;
|
|
@@ -8525,18 +8623,22 @@ function observe(input) {
|
|
|
8525
8623
|
const canAdmit = actual !== "none" && ADMITTER_ROLES.has(actual);
|
|
8526
8624
|
const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
|
|
8527
8625
|
const deviceInPlay = phase === "joining" || inCall;
|
|
8626
|
+
const region = snapshot?.mediaRegion;
|
|
8627
|
+
const atPrejoin = phase === "prejoin" && region !== void 0;
|
|
8528
8628
|
return {
|
|
8529
8629
|
phase,
|
|
8530
8630
|
reason: phase === "ended" ? snapshot?.reason ?? null : snapshot?.reason ?? reasonOf(phase),
|
|
8531
8631
|
role,
|
|
8532
|
-
|
|
8632
|
+
// `net-blip`: in the call, a drop shorter than `reconnect_banner_delay_ms` is not something the
|
|
8633
|
+
// person sees — the contract says what is on screen, so it reads `stable` until the banner shows.
|
|
8634
|
+
connection: snapshot === null ? "stable" : inCall && snapshot.connection !== "stable" && !snapshot.connectionBanner ? "stable" : snapshot.connection,
|
|
8533
8635
|
hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : snapshot !== null && isWaitingPhase(snapshot.phase) ? snapshot.waiting?.admittersPresent ?? null : null,
|
|
8534
8636
|
lobbyCount: canAdmit && snapshot !== null ? snapshot.lobby.filter((entry) => entry.state === "knocking").length : 0,
|
|
8535
8637
|
recording: snapshot?.recording === "recording" || snapshot?.recording === "stopping",
|
|
8536
8638
|
// S6c: the autoplay region is known only inside the room (no remote audio exists elsewhere).
|
|
8537
8639
|
audioBlocked: inCall && snapshot !== null ? snapshot.mediaRegion.audioOutput === "blocked" : null,
|
|
8538
|
-
camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera, lockedFor(snapshot, "camera", inCall)) : null,
|
|
8539
|
-
microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone, lockedFor(snapshot, "microphone", inCall)) : null
|
|
8640
|
+
camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera, lockedFor(snapshot, "camera", inCall)) : atPrejoin ? observedPreview(region.preview.camera, region.permission.camera) : null,
|
|
8641
|
+
microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone, lockedFor(snapshot, "microphone", inCall)) : atPrejoin ? observedPreview(region.preview.microphone, region.permission.microphone) : null
|
|
8540
8642
|
};
|
|
8541
8643
|
}
|
|
8542
8644
|
function lockedFor(snapshot, kind, inCall) {
|
|
@@ -8616,4 +8718,37 @@ function microphoneNoticeCode(track, permission = "unknown") {
|
|
|
8616
8718
|
if (reason === null) return null;
|
|
8617
8719
|
return deviceNoticeCode("microphone", reason) === "mic-blocked" ? "mic-blocked" : "device-lost";
|
|
8618
8720
|
}
|
|
8721
|
+
|
|
8722
|
+
// src/core/speaking-detector.ts
|
|
8723
|
+
function createSpeakingWhileMutedDetector(options = {}) {
|
|
8724
|
+
const threshold = options.threshold ?? 0.06;
|
|
8725
|
+
const holdMs = options.holdMs ?? 600;
|
|
8726
|
+
const gapMs = options.gapMs ?? 400;
|
|
8727
|
+
const cooldownMs = options.cooldownMs ?? 2e4;
|
|
8728
|
+
let speechStart = null;
|
|
8729
|
+
let lastLoud = null;
|
|
8730
|
+
let firedAt = null;
|
|
8731
|
+
return {
|
|
8732
|
+
feed(level, at) {
|
|
8733
|
+
if (level >= threshold) {
|
|
8734
|
+
if (speechStart === null || lastLoud === null || at - lastLoud > gapMs) speechStart = at;
|
|
8735
|
+
lastLoud = at;
|
|
8736
|
+
} else if (lastLoud !== null && at - lastLoud > gapMs) {
|
|
8737
|
+
speechStart = null;
|
|
8738
|
+
lastLoud = null;
|
|
8739
|
+
}
|
|
8740
|
+
if (speechStart === null || at - speechStart < holdMs) return false;
|
|
8741
|
+
if (firedAt !== null && at - firedAt < cooldownMs) return false;
|
|
8742
|
+
firedAt = at;
|
|
8743
|
+
speechStart = null;
|
|
8744
|
+
lastLoud = null;
|
|
8745
|
+
return true;
|
|
8746
|
+
},
|
|
8747
|
+
reset() {
|
|
8748
|
+
speechStart = null;
|
|
8749
|
+
lastLoud = null;
|
|
8750
|
+
firedAt = null;
|
|
8751
|
+
}
|
|
8752
|
+
};
|
|
8753
|
+
}
|
|
8619
8754
|
//# sourceMappingURL=index.cjs.map
|