@wvdsh/sdk-js 1.3.14 → 1.3.16
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.ts +57 -8
- package/dist/index.js +174 -24
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -91,6 +91,8 @@ type UpsertedLeaderboardEntry = FunctionReturnType<typeof api.sdk.leaderboards.u
|
|
|
91
91
|
userId: GenericId<"users">;
|
|
92
92
|
username: string;
|
|
93
93
|
userAvatarUrl?: string;
|
|
94
|
+
submittedScore: number;
|
|
95
|
+
submittedRank: number;
|
|
94
96
|
};
|
|
95
97
|
type WavedashEvent = (typeof WavedashEvents)[keyof typeof WavedashEvents];
|
|
96
98
|
interface WavedashConfig {
|
|
@@ -625,36 +627,53 @@ declare class HeartbeatManager extends WavedashManager {
|
|
|
625
627
|
private deviceFingerprintReady;
|
|
626
628
|
private testConnectionInterval;
|
|
627
629
|
private heartbeatInterval;
|
|
630
|
+
private gamepadPollInterval;
|
|
631
|
+
private inactivityTimeout;
|
|
628
632
|
private isConnected;
|
|
629
633
|
private sentDisconnectedEvent;
|
|
630
634
|
private disconnectedAt;
|
|
631
635
|
private lastHeartbeatTime;
|
|
636
|
+
private lastInputResetAt;
|
|
632
637
|
private heartbeatInFlight;
|
|
633
638
|
private isFirstTick;
|
|
634
639
|
private readonly TEST_CONNECTION_INTERVAL_MS;
|
|
635
640
|
private readonly DISCONNECTED_TIMEOUT_MS;
|
|
641
|
+
private readonly INACTIVITY_TIMEOUT_MS;
|
|
642
|
+
private readonly INPUT_THROTTLE_MS;
|
|
643
|
+
private readonly GAMEPAD_POLL_INTERVAL_MS;
|
|
644
|
+
private readonly GAMEPAD_AXIS_DEADZONE;
|
|
636
645
|
private cachedPresenceData;
|
|
637
646
|
constructor(sdk: WavedashSDK);
|
|
638
|
-
/**
|
|
647
|
+
/**
|
|
648
|
+
* Start (or refresh) the heartbeat. Idempotent: if intervals are already
|
|
649
|
+
* running this just reschedules the inactivity timer. No-op if the game
|
|
650
|
+
* hasn't loaded yet or the tab is hidden.
|
|
651
|
+
*/
|
|
639
652
|
start(): void;
|
|
640
|
-
/** Stop heartbeat and
|
|
653
|
+
/** Stop the heartbeat and clear the inactivity timer. Idempotent. */
|
|
641
654
|
stop(): void;
|
|
642
|
-
/** Full teardown — stops intervals and removes all listeners */
|
|
643
|
-
destroy(): void;
|
|
644
|
-
private handleVisibilityChange;
|
|
645
|
-
private tickHeartbeat;
|
|
646
|
-
private sendHeartbeat;
|
|
647
655
|
/**
|
|
648
656
|
* Updates user presence in the backend.
|
|
649
657
|
* @param data - Data to send to the backend
|
|
650
658
|
* @returns true if the presence was updated successfully
|
|
651
659
|
*/
|
|
652
660
|
updateUserPresence(data: Record<string, string | number | boolean | null>): Promise<boolean>;
|
|
661
|
+
isCurrentlyConnected(): boolean;
|
|
662
|
+
/** Full teardown — stops intervals and removes all listeners */
|
|
663
|
+
destroy(): void;
|
|
664
|
+
private tickHeartbeat;
|
|
665
|
+
private sendHeartbeat;
|
|
666
|
+
private handleVisibilityChange;
|
|
667
|
+
private handleUserInput;
|
|
668
|
+
/**
|
|
669
|
+
* Polls connected gamepads; any pressed button or out-of-deadzone axis
|
|
670
|
+
* counts as user activity and (re)starts the heartbeat.
|
|
671
|
+
*/
|
|
672
|
+
private pollGamepads;
|
|
653
673
|
/**
|
|
654
674
|
* Tests the connection to the backend
|
|
655
675
|
*/
|
|
656
676
|
private testConnection;
|
|
657
|
-
isCurrentlyConnected(): boolean;
|
|
658
677
|
}
|
|
659
678
|
|
|
660
679
|
declare class GameEventManager extends WavedashManager {
|
|
@@ -750,6 +769,20 @@ declare class AudioManager extends WavedashManager {
|
|
|
750
769
|
private mutationObserver;
|
|
751
770
|
constructor(sdk: WavedashSDK);
|
|
752
771
|
isMuted(): boolean;
|
|
772
|
+
/**
|
|
773
|
+
* Ask the host to mute (true) or unmute (false). Resolves to `true` if the
|
|
774
|
+
* host applied the change, `false` otherwise — notably, the host rejects an
|
|
775
|
+
* unmute when the user muted the game from the Wavedash UI, so games can't
|
|
776
|
+
* override an explicit user mute. The resulting state arrives via the usual
|
|
777
|
+
* MUTE_CHANGED broadcast, so `isMuted()` updates independently of this result.
|
|
778
|
+
*/
|
|
779
|
+
requestMute(muted: boolean): Promise<boolean>;
|
|
780
|
+
/**
|
|
781
|
+
* Toggle mute. Like `requestMute`, the host may reject the unmute half of a
|
|
782
|
+
* toggle if the user muted from the Wavedash UI. Resolves to `true` if the
|
|
783
|
+
* host applied the change.
|
|
784
|
+
*/
|
|
785
|
+
toggleMute(): Promise<boolean>;
|
|
753
786
|
private handleMute;
|
|
754
787
|
/**
|
|
755
788
|
* Track a media element and (if SDK is currently muted) silence it.
|
|
@@ -1004,6 +1037,22 @@ declare class WavedashSDK extends EventTarget {
|
|
|
1004
1037
|
* a user gesture handler when entering fullscreen.
|
|
1005
1038
|
*/
|
|
1006
1039
|
toggleFullscreen(): Promise<boolean>;
|
|
1040
|
+
/**
|
|
1041
|
+
* Whether the game is currently muted. Mirrored from the Wavedash host page,
|
|
1042
|
+
* which owns the mute control so its UI button and the game stay in sync.
|
|
1043
|
+
*/
|
|
1044
|
+
isMuted(): boolean;
|
|
1045
|
+
/**
|
|
1046
|
+
* Ask the host to mute (true) or unmute (false). Resolves to `true` if the
|
|
1047
|
+
* change was applied, `false` if it was rejected — the host won't let the
|
|
1048
|
+
* game unmute when the user has muted from the Wavedash UI.
|
|
1049
|
+
*/
|
|
1050
|
+
requestMute(muted: boolean): Promise<boolean>;
|
|
1051
|
+
/**
|
|
1052
|
+
* Toggle mute. Resolves to `true` if the change was applied, `false` if it
|
|
1053
|
+
* was rejected (e.g. trying to unmute over an explicit user mute).
|
|
1054
|
+
*/
|
|
1055
|
+
toggleMute(): Promise<boolean>;
|
|
1007
1056
|
getUser(): SDKUser;
|
|
1008
1057
|
/**
|
|
1009
1058
|
* Get a username. Returns the logged in user's username if no ID is passed.
|
package/dist/index.js
CHANGED
|
@@ -1172,7 +1172,12 @@ var LeaderboardManager = class extends WavedashManager {
|
|
|
1172
1172
|
this.updateCachedTotalEntries(leaderboardId, result.totalEntries);
|
|
1173
1173
|
}
|
|
1174
1174
|
return {
|
|
1175
|
+
// Where your current leaderboard standing ranks
|
|
1175
1176
|
...result.entry,
|
|
1177
|
+
// Where the submission itself ranks
|
|
1178
|
+
submittedScore: result.submission.score,
|
|
1179
|
+
submittedRank: result.submission.globalRank,
|
|
1180
|
+
// User info
|
|
1176
1181
|
userId: this.sdk.wavedashUser.id,
|
|
1177
1182
|
username: this.sdk.wavedashUser.username,
|
|
1178
1183
|
userAvatarUrl: this.sdk.wavedashUser.avatarUrl
|
|
@@ -2698,20 +2703,31 @@ import {
|
|
|
2698
2703
|
HEARTBEAT,
|
|
2699
2704
|
IFRAME_MESSAGE_TYPE as IFRAME_MESSAGE_TYPE2
|
|
2700
2705
|
} from "@wvdsh/api";
|
|
2706
|
+
var INPUT_LISTENER_OPTS = {
|
|
2707
|
+
passive: true,
|
|
2708
|
+
capture: true
|
|
2709
|
+
};
|
|
2701
2710
|
var HeartbeatManager = class extends WavedashManager {
|
|
2702
2711
|
constructor(sdk) {
|
|
2703
2712
|
super(sdk);
|
|
2704
2713
|
this.deviceFingerprint = void 0;
|
|
2705
2714
|
this.testConnectionInterval = null;
|
|
2706
2715
|
this.heartbeatInterval = null;
|
|
2716
|
+
this.gamepadPollInterval = null;
|
|
2717
|
+
this.inactivityTimeout = null;
|
|
2707
2718
|
this.isConnected = false;
|
|
2708
2719
|
this.sentDisconnectedEvent = false;
|
|
2709
2720
|
this.disconnectedAt = null;
|
|
2710
2721
|
this.lastHeartbeatTime = 0;
|
|
2722
|
+
this.lastInputResetAt = 0;
|
|
2711
2723
|
this.heartbeatInFlight = false;
|
|
2712
2724
|
this.isFirstTick = true;
|
|
2713
2725
|
this.TEST_CONNECTION_INTERVAL_MS = 1e3;
|
|
2714
2726
|
this.DISCONNECTED_TIMEOUT_MS = 9e4;
|
|
2727
|
+
this.INACTIVITY_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
2728
|
+
this.INPUT_THROTTLE_MS = 1e3;
|
|
2729
|
+
this.GAMEPAD_POLL_INTERVAL_MS = 1e3;
|
|
2730
|
+
this.GAMEPAD_AXIS_DEADZONE = 0.2;
|
|
2715
2731
|
this.cachedPresenceData = {};
|
|
2716
2732
|
this.handleVisibilityChange = () => {
|
|
2717
2733
|
if (document.visibilityState === "visible") {
|
|
@@ -2720,19 +2736,53 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2720
2736
|
this.stop();
|
|
2721
2737
|
}
|
|
2722
2738
|
};
|
|
2739
|
+
this.handleUserInput = () => {
|
|
2740
|
+
const now = Date.now();
|
|
2741
|
+
if (now - this.lastInputResetAt < this.INPUT_THROTTLE_MS) return;
|
|
2742
|
+
this.lastInputResetAt = now;
|
|
2743
|
+
this.start();
|
|
2744
|
+
};
|
|
2723
2745
|
this.isConnected = this.sdk.convexClient.client.connectionState().isWebSocketConnected;
|
|
2724
2746
|
document.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
2747
|
+
window.addEventListener(
|
|
2748
|
+
"keydown",
|
|
2749
|
+
this.handleUserInput,
|
|
2750
|
+
INPUT_LISTENER_OPTS
|
|
2751
|
+
);
|
|
2752
|
+
window.addEventListener(
|
|
2753
|
+
"pointerdown",
|
|
2754
|
+
this.handleUserInput,
|
|
2755
|
+
INPUT_LISTENER_OPTS
|
|
2756
|
+
);
|
|
2757
|
+
window.addEventListener(
|
|
2758
|
+
"pointermove",
|
|
2759
|
+
this.handleUserInput,
|
|
2760
|
+
INPUT_LISTENER_OPTS
|
|
2761
|
+
);
|
|
2762
|
+
window.addEventListener("wheel", this.handleUserInput, INPUT_LISTENER_OPTS);
|
|
2763
|
+
this.gamepadPollInterval = setInterval(() => {
|
|
2764
|
+
this.pollGamepads();
|
|
2765
|
+
}, this.GAMEPAD_POLL_INTERVAL_MS);
|
|
2725
2766
|
this.deviceFingerprintReady = this.sdk.iframeMessenger.requestFromParent(IFRAME_MESSAGE_TYPE2.GET_DEVICE_FINGERPRINT).then((fingerprint) => {
|
|
2726
2767
|
this.deviceFingerprint = fingerprint;
|
|
2727
2768
|
}).catch(() => {
|
|
2728
2769
|
});
|
|
2729
2770
|
}
|
|
2730
|
-
/**
|
|
2771
|
+
/**
|
|
2772
|
+
* Start (or refresh) the heartbeat. Idempotent: if intervals are already
|
|
2773
|
+
* running this just reschedules the inactivity timer. No-op if the game
|
|
2774
|
+
* hasn't loaded yet or the tab is hidden.
|
|
2775
|
+
*/
|
|
2731
2776
|
start() {
|
|
2732
|
-
if (!this.sdk.gameLoaded)
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2777
|
+
if (!this.sdk.gameLoaded) return;
|
|
2778
|
+
if (document.visibilityState !== "visible") return;
|
|
2779
|
+
if (this.inactivityTimeout !== null) {
|
|
2780
|
+
clearTimeout(this.inactivityTimeout);
|
|
2781
|
+
}
|
|
2782
|
+
this.inactivityTimeout = setTimeout(() => {
|
|
2783
|
+
this.stop();
|
|
2784
|
+
}, this.INACTIVITY_TIMEOUT_MS);
|
|
2785
|
+
if (this.heartbeatInterval !== null) return;
|
|
2736
2786
|
if (this.isFirstTick) {
|
|
2737
2787
|
void this.deviceFingerprintReady.then(() => {
|
|
2738
2788
|
if (!this.sdk.gameLoaded || !this.isFirstTick) return;
|
|
@@ -2748,8 +2798,12 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2748
2798
|
this.testConnection();
|
|
2749
2799
|
}, this.TEST_CONNECTION_INTERVAL_MS);
|
|
2750
2800
|
}
|
|
2751
|
-
/** Stop heartbeat and
|
|
2801
|
+
/** Stop the heartbeat and clear the inactivity timer. Idempotent. */
|
|
2752
2802
|
stop() {
|
|
2803
|
+
if (this.inactivityTimeout !== null) {
|
|
2804
|
+
clearTimeout(this.inactivityTimeout);
|
|
2805
|
+
this.inactivityTimeout = null;
|
|
2806
|
+
}
|
|
2753
2807
|
if (this.heartbeatInterval !== null) {
|
|
2754
2808
|
clearInterval(this.heartbeatInterval);
|
|
2755
2809
|
this.heartbeatInterval = null;
|
|
@@ -2759,14 +2813,62 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2759
2813
|
this.testConnectionInterval = null;
|
|
2760
2814
|
}
|
|
2761
2815
|
}
|
|
2816
|
+
/**
|
|
2817
|
+
* Updates user presence in the backend.
|
|
2818
|
+
* @param data - Data to send to the backend
|
|
2819
|
+
* @returns true if the presence was updated successfully
|
|
2820
|
+
*/
|
|
2821
|
+
async updateUserPresence(data) {
|
|
2822
|
+
try {
|
|
2823
|
+
this.cachedPresenceData = data;
|
|
2824
|
+
await this.sdk.convexClient.mutation(api7.sdk.presence.heartbeat, {
|
|
2825
|
+
data,
|
|
2826
|
+
deviceFingerprint: this.deviceFingerprint
|
|
2827
|
+
});
|
|
2828
|
+
return true;
|
|
2829
|
+
} catch (error) {
|
|
2830
|
+
logger.error(`Error updating presence: ${error}`);
|
|
2831
|
+
return false;
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
isCurrentlyConnected() {
|
|
2835
|
+
return this.isConnected;
|
|
2836
|
+
}
|
|
2762
2837
|
/** Full teardown — stops intervals and removes all listeners */
|
|
2763
2838
|
destroy() {
|
|
2764
2839
|
this.stop();
|
|
2840
|
+
if (this.gamepadPollInterval !== null) {
|
|
2841
|
+
clearInterval(this.gamepadPollInterval);
|
|
2842
|
+
this.gamepadPollInterval = null;
|
|
2843
|
+
}
|
|
2765
2844
|
document.removeEventListener(
|
|
2766
2845
|
"visibilitychange",
|
|
2767
2846
|
this.handleVisibilityChange
|
|
2768
2847
|
);
|
|
2848
|
+
window.removeEventListener(
|
|
2849
|
+
"keydown",
|
|
2850
|
+
this.handleUserInput,
|
|
2851
|
+
INPUT_LISTENER_OPTS
|
|
2852
|
+
);
|
|
2853
|
+
window.removeEventListener(
|
|
2854
|
+
"pointerdown",
|
|
2855
|
+
this.handleUserInput,
|
|
2856
|
+
INPUT_LISTENER_OPTS
|
|
2857
|
+
);
|
|
2858
|
+
window.removeEventListener(
|
|
2859
|
+
"pointermove",
|
|
2860
|
+
this.handleUserInput,
|
|
2861
|
+
INPUT_LISTENER_OPTS
|
|
2862
|
+
);
|
|
2863
|
+
window.removeEventListener(
|
|
2864
|
+
"wheel",
|
|
2865
|
+
this.handleUserInput,
|
|
2866
|
+
INPUT_LISTENER_OPTS
|
|
2867
|
+
);
|
|
2769
2868
|
}
|
|
2869
|
+
// =================
|
|
2870
|
+
// Private functions
|
|
2871
|
+
// =================
|
|
2770
2872
|
tickHeartbeat() {
|
|
2771
2873
|
const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeatTime;
|
|
2772
2874
|
const needsReestablish = this.isFirstTick || timeSinceLastHeartbeat >= HEARTBEAT.CLIENT_REESTABLISH_THRESHOLD_MS;
|
|
@@ -2796,21 +2898,22 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2796
2898
|
});
|
|
2797
2899
|
}
|
|
2798
2900
|
/**
|
|
2799
|
-
*
|
|
2800
|
-
*
|
|
2801
|
-
* @returns true if the presence was updated successfully
|
|
2901
|
+
* Polls connected gamepads; any pressed button or out-of-deadzone axis
|
|
2902
|
+
* counts as user activity and (re)starts the heartbeat.
|
|
2802
2903
|
*/
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2904
|
+
pollGamepads() {
|
|
2905
|
+
if (typeof navigator === "undefined" || !navigator.getGamepads) return;
|
|
2906
|
+
const pads = navigator.getGamepads();
|
|
2907
|
+
for (const pad of pads) {
|
|
2908
|
+
if (!pad) continue;
|
|
2909
|
+
if (pad.buttons.some((b) => b.pressed)) {
|
|
2910
|
+
this.start();
|
|
2911
|
+
return;
|
|
2912
|
+
}
|
|
2913
|
+
if (pad.axes.some((a) => Math.abs(a) > this.GAMEPAD_AXIS_DEADZONE)) {
|
|
2914
|
+
this.start();
|
|
2915
|
+
return;
|
|
2916
|
+
}
|
|
2814
2917
|
}
|
|
2815
2918
|
}
|
|
2816
2919
|
/**
|
|
@@ -2857,9 +2960,6 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2857
2960
|
logger.error("Error testing connection:", error);
|
|
2858
2961
|
}
|
|
2859
2962
|
}
|
|
2860
|
-
isCurrentlyConnected() {
|
|
2861
|
-
return this.isConnected;
|
|
2862
|
-
}
|
|
2863
2963
|
};
|
|
2864
2964
|
|
|
2865
2965
|
// src/services/gameEvents.ts
|
|
@@ -3101,6 +3201,31 @@ var AudioManager = class extends WavedashManager {
|
|
|
3101
3201
|
isMuted() {
|
|
3102
3202
|
return this._isMuted;
|
|
3103
3203
|
}
|
|
3204
|
+
/**
|
|
3205
|
+
* Ask the host to mute (true) or unmute (false). Resolves to `true` if the
|
|
3206
|
+
* host applied the change, `false` otherwise — notably, the host rejects an
|
|
3207
|
+
* unmute when the user muted the game from the Wavedash UI, so games can't
|
|
3208
|
+
* override an explicit user mute. The resulting state arrives via the usual
|
|
3209
|
+
* MUTE_CHANGED broadcast, so `isMuted()` updates independently of this result.
|
|
3210
|
+
*/
|
|
3211
|
+
async requestMute(muted) {
|
|
3212
|
+
const response = await this.sdk.iframeMessenger.requestFromParent(
|
|
3213
|
+
IFRAME_MESSAGE_TYPE5.SET_MUTE,
|
|
3214
|
+
{ muted }
|
|
3215
|
+
);
|
|
3216
|
+
return response.success;
|
|
3217
|
+
}
|
|
3218
|
+
/**
|
|
3219
|
+
* Toggle mute. Like `requestMute`, the host may reject the unmute half of a
|
|
3220
|
+
* toggle if the user muted from the Wavedash UI. Resolves to `true` if the
|
|
3221
|
+
* host applied the change.
|
|
3222
|
+
*/
|
|
3223
|
+
async toggleMute() {
|
|
3224
|
+
const response = await this.sdk.iframeMessenger.requestFromParent(
|
|
3225
|
+
IFRAME_MESSAGE_TYPE5.TOGGLE_MUTE
|
|
3226
|
+
);
|
|
3227
|
+
return response.success;
|
|
3228
|
+
}
|
|
3104
3229
|
/**
|
|
3105
3230
|
* Track a media element and (if SDK is currently muted) silence it.
|
|
3106
3231
|
* Idempotent — safe to call multiple times for the same element.
|
|
@@ -3673,11 +3798,11 @@ var WavedashSDK = class extends EventTarget {
|
|
|
3673
3798
|
expectAuth: true
|
|
3674
3799
|
});
|
|
3675
3800
|
this.gameCloudId = sdkConfig.gameCloudId;
|
|
3801
|
+
this.iframeMessenger = iframeMessenger;
|
|
3676
3802
|
this.convexClient.setAuth(
|
|
3677
3803
|
({ forceRefreshToken }) => this.getAuthToken(forceRefreshToken)
|
|
3678
3804
|
);
|
|
3679
3805
|
this.wavedashUser = sdkConfig.wavedashUser;
|
|
3680
|
-
this.iframeMessenger = iframeMessenger;
|
|
3681
3806
|
this.ugcHost = sdkConfig.ugcHost;
|
|
3682
3807
|
this.uploadsHost = sdkConfig.uploadsHost;
|
|
3683
3808
|
this.swMessenger = new SwMessenger();
|
|
@@ -3881,6 +4006,31 @@ var WavedashSDK = class extends EventTarget {
|
|
|
3881
4006
|
async toggleFullscreen() {
|
|
3882
4007
|
return this.fullscreenManager.toggleFullscreen();
|
|
3883
4008
|
}
|
|
4009
|
+
// =====
|
|
4010
|
+
// Audio
|
|
4011
|
+
// =====
|
|
4012
|
+
/**
|
|
4013
|
+
* Whether the game is currently muted. Mirrored from the Wavedash host page,
|
|
4014
|
+
* which owns the mute control so its UI button and the game stay in sync.
|
|
4015
|
+
*/
|
|
4016
|
+
isMuted() {
|
|
4017
|
+
return this.audioManager.isMuted();
|
|
4018
|
+
}
|
|
4019
|
+
/**
|
|
4020
|
+
* Ask the host to mute (true) or unmute (false). Resolves to `true` if the
|
|
4021
|
+
* change was applied, `false` if it was rejected — the host won't let the
|
|
4022
|
+
* game unmute when the user has muted from the Wavedash UI.
|
|
4023
|
+
*/
|
|
4024
|
+
async requestMute(muted) {
|
|
4025
|
+
return this.audioManager.requestMute(muted);
|
|
4026
|
+
}
|
|
4027
|
+
/**
|
|
4028
|
+
* Toggle mute. Resolves to `true` if the change was applied, `false` if it
|
|
4029
|
+
* was rejected (e.g. trying to unmute over an explicit user mute).
|
|
4030
|
+
*/
|
|
4031
|
+
async toggleMute() {
|
|
4032
|
+
return this.audioManager.toggleMute();
|
|
4033
|
+
}
|
|
3884
4034
|
// ============
|
|
3885
4035
|
// User methods
|
|
3886
4036
|
// ============
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wvdsh/sdk-js",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Wavedash JavaScript SDK",
|
|
6
6
|
"main": "./dist/client.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"typescript-eslint": "^8.52.0"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@wvdsh/api": "^0.1.
|
|
52
|
+
"@wvdsh/api": "^0.1.32",
|
|
53
53
|
"convex": "^1.39.1",
|
|
54
54
|
"lodash.throttle": "^4.1.1"
|
|
55
55
|
}
|