@wvdsh/sdk-js 1.3.14 → 1.3.15
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 +25 -8
- package/dist/index.js +119 -24
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -625,36 +625,53 @@ declare class HeartbeatManager extends WavedashManager {
|
|
|
625
625
|
private deviceFingerprintReady;
|
|
626
626
|
private testConnectionInterval;
|
|
627
627
|
private heartbeatInterval;
|
|
628
|
+
private gamepadPollInterval;
|
|
629
|
+
private inactivityTimeout;
|
|
628
630
|
private isConnected;
|
|
629
631
|
private sentDisconnectedEvent;
|
|
630
632
|
private disconnectedAt;
|
|
631
633
|
private lastHeartbeatTime;
|
|
634
|
+
private lastInputResetAt;
|
|
632
635
|
private heartbeatInFlight;
|
|
633
636
|
private isFirstTick;
|
|
634
637
|
private readonly TEST_CONNECTION_INTERVAL_MS;
|
|
635
638
|
private readonly DISCONNECTED_TIMEOUT_MS;
|
|
639
|
+
private readonly INACTIVITY_TIMEOUT_MS;
|
|
640
|
+
private readonly INPUT_THROTTLE_MS;
|
|
641
|
+
private readonly GAMEPAD_POLL_INTERVAL_MS;
|
|
642
|
+
private readonly GAMEPAD_AXIS_DEADZONE;
|
|
636
643
|
private cachedPresenceData;
|
|
637
644
|
constructor(sdk: WavedashSDK);
|
|
638
|
-
/**
|
|
645
|
+
/**
|
|
646
|
+
* Start (or refresh) the heartbeat. Idempotent: if intervals are already
|
|
647
|
+
* running this just reschedules the inactivity timer. No-op if the game
|
|
648
|
+
* hasn't loaded yet or the tab is hidden.
|
|
649
|
+
*/
|
|
639
650
|
start(): void;
|
|
640
|
-
/** Stop heartbeat and
|
|
651
|
+
/** Stop the heartbeat and clear the inactivity timer. Idempotent. */
|
|
641
652
|
stop(): void;
|
|
642
|
-
/** Full teardown — stops intervals and removes all listeners */
|
|
643
|
-
destroy(): void;
|
|
644
|
-
private handleVisibilityChange;
|
|
645
|
-
private tickHeartbeat;
|
|
646
|
-
private sendHeartbeat;
|
|
647
653
|
/**
|
|
648
654
|
* Updates user presence in the backend.
|
|
649
655
|
* @param data - Data to send to the backend
|
|
650
656
|
* @returns true if the presence was updated successfully
|
|
651
657
|
*/
|
|
652
658
|
updateUserPresence(data: Record<string, string | number | boolean | null>): Promise<boolean>;
|
|
659
|
+
isCurrentlyConnected(): boolean;
|
|
660
|
+
/** Full teardown — stops intervals and removes all listeners */
|
|
661
|
+
destroy(): void;
|
|
662
|
+
private tickHeartbeat;
|
|
663
|
+
private sendHeartbeat;
|
|
664
|
+
private handleVisibilityChange;
|
|
665
|
+
private handleUserInput;
|
|
666
|
+
/**
|
|
667
|
+
* Polls connected gamepads; any pressed button or out-of-deadzone axis
|
|
668
|
+
* counts as user activity and (re)starts the heartbeat.
|
|
669
|
+
*/
|
|
670
|
+
private pollGamepads;
|
|
653
671
|
/**
|
|
654
672
|
* Tests the connection to the backend
|
|
655
673
|
*/
|
|
656
674
|
private testConnection;
|
|
657
|
-
isCurrentlyConnected(): boolean;
|
|
658
675
|
}
|
|
659
676
|
|
|
660
677
|
declare class GameEventManager extends WavedashManager {
|
package/dist/index.js
CHANGED
|
@@ -2698,20 +2698,31 @@ import {
|
|
|
2698
2698
|
HEARTBEAT,
|
|
2699
2699
|
IFRAME_MESSAGE_TYPE as IFRAME_MESSAGE_TYPE2
|
|
2700
2700
|
} from "@wvdsh/api";
|
|
2701
|
+
var INPUT_LISTENER_OPTS = {
|
|
2702
|
+
passive: true,
|
|
2703
|
+
capture: true
|
|
2704
|
+
};
|
|
2701
2705
|
var HeartbeatManager = class extends WavedashManager {
|
|
2702
2706
|
constructor(sdk) {
|
|
2703
2707
|
super(sdk);
|
|
2704
2708
|
this.deviceFingerprint = void 0;
|
|
2705
2709
|
this.testConnectionInterval = null;
|
|
2706
2710
|
this.heartbeatInterval = null;
|
|
2711
|
+
this.gamepadPollInterval = null;
|
|
2712
|
+
this.inactivityTimeout = null;
|
|
2707
2713
|
this.isConnected = false;
|
|
2708
2714
|
this.sentDisconnectedEvent = false;
|
|
2709
2715
|
this.disconnectedAt = null;
|
|
2710
2716
|
this.lastHeartbeatTime = 0;
|
|
2717
|
+
this.lastInputResetAt = 0;
|
|
2711
2718
|
this.heartbeatInFlight = false;
|
|
2712
2719
|
this.isFirstTick = true;
|
|
2713
2720
|
this.TEST_CONNECTION_INTERVAL_MS = 1e3;
|
|
2714
2721
|
this.DISCONNECTED_TIMEOUT_MS = 9e4;
|
|
2722
|
+
this.INACTIVITY_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
2723
|
+
this.INPUT_THROTTLE_MS = 1e3;
|
|
2724
|
+
this.GAMEPAD_POLL_INTERVAL_MS = 1e3;
|
|
2725
|
+
this.GAMEPAD_AXIS_DEADZONE = 0.2;
|
|
2715
2726
|
this.cachedPresenceData = {};
|
|
2716
2727
|
this.handleVisibilityChange = () => {
|
|
2717
2728
|
if (document.visibilityState === "visible") {
|
|
@@ -2720,19 +2731,53 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2720
2731
|
this.stop();
|
|
2721
2732
|
}
|
|
2722
2733
|
};
|
|
2734
|
+
this.handleUserInput = () => {
|
|
2735
|
+
const now = Date.now();
|
|
2736
|
+
if (now - this.lastInputResetAt < this.INPUT_THROTTLE_MS) return;
|
|
2737
|
+
this.lastInputResetAt = now;
|
|
2738
|
+
this.start();
|
|
2739
|
+
};
|
|
2723
2740
|
this.isConnected = this.sdk.convexClient.client.connectionState().isWebSocketConnected;
|
|
2724
2741
|
document.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
2742
|
+
window.addEventListener(
|
|
2743
|
+
"keydown",
|
|
2744
|
+
this.handleUserInput,
|
|
2745
|
+
INPUT_LISTENER_OPTS
|
|
2746
|
+
);
|
|
2747
|
+
window.addEventListener(
|
|
2748
|
+
"pointerdown",
|
|
2749
|
+
this.handleUserInput,
|
|
2750
|
+
INPUT_LISTENER_OPTS
|
|
2751
|
+
);
|
|
2752
|
+
window.addEventListener(
|
|
2753
|
+
"pointermove",
|
|
2754
|
+
this.handleUserInput,
|
|
2755
|
+
INPUT_LISTENER_OPTS
|
|
2756
|
+
);
|
|
2757
|
+
window.addEventListener("wheel", this.handleUserInput, INPUT_LISTENER_OPTS);
|
|
2758
|
+
this.gamepadPollInterval = setInterval(() => {
|
|
2759
|
+
this.pollGamepads();
|
|
2760
|
+
}, this.GAMEPAD_POLL_INTERVAL_MS);
|
|
2725
2761
|
this.deviceFingerprintReady = this.sdk.iframeMessenger.requestFromParent(IFRAME_MESSAGE_TYPE2.GET_DEVICE_FINGERPRINT).then((fingerprint) => {
|
|
2726
2762
|
this.deviceFingerprint = fingerprint;
|
|
2727
2763
|
}).catch(() => {
|
|
2728
2764
|
});
|
|
2729
2765
|
}
|
|
2730
|
-
/**
|
|
2766
|
+
/**
|
|
2767
|
+
* Start (or refresh) the heartbeat. Idempotent: if intervals are already
|
|
2768
|
+
* running this just reschedules the inactivity timer. No-op if the game
|
|
2769
|
+
* hasn't loaded yet or the tab is hidden.
|
|
2770
|
+
*/
|
|
2731
2771
|
start() {
|
|
2732
|
-
if (!this.sdk.gameLoaded)
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2772
|
+
if (!this.sdk.gameLoaded) return;
|
|
2773
|
+
if (document.visibilityState !== "visible") return;
|
|
2774
|
+
if (this.inactivityTimeout !== null) {
|
|
2775
|
+
clearTimeout(this.inactivityTimeout);
|
|
2776
|
+
}
|
|
2777
|
+
this.inactivityTimeout = setTimeout(() => {
|
|
2778
|
+
this.stop();
|
|
2779
|
+
}, this.INACTIVITY_TIMEOUT_MS);
|
|
2780
|
+
if (this.heartbeatInterval !== null) return;
|
|
2736
2781
|
if (this.isFirstTick) {
|
|
2737
2782
|
void this.deviceFingerprintReady.then(() => {
|
|
2738
2783
|
if (!this.sdk.gameLoaded || !this.isFirstTick) return;
|
|
@@ -2748,8 +2793,12 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2748
2793
|
this.testConnection();
|
|
2749
2794
|
}, this.TEST_CONNECTION_INTERVAL_MS);
|
|
2750
2795
|
}
|
|
2751
|
-
/** Stop heartbeat and
|
|
2796
|
+
/** Stop the heartbeat and clear the inactivity timer. Idempotent. */
|
|
2752
2797
|
stop() {
|
|
2798
|
+
if (this.inactivityTimeout !== null) {
|
|
2799
|
+
clearTimeout(this.inactivityTimeout);
|
|
2800
|
+
this.inactivityTimeout = null;
|
|
2801
|
+
}
|
|
2753
2802
|
if (this.heartbeatInterval !== null) {
|
|
2754
2803
|
clearInterval(this.heartbeatInterval);
|
|
2755
2804
|
this.heartbeatInterval = null;
|
|
@@ -2759,14 +2808,62 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2759
2808
|
this.testConnectionInterval = null;
|
|
2760
2809
|
}
|
|
2761
2810
|
}
|
|
2811
|
+
/**
|
|
2812
|
+
* Updates user presence in the backend.
|
|
2813
|
+
* @param data - Data to send to the backend
|
|
2814
|
+
* @returns true if the presence was updated successfully
|
|
2815
|
+
*/
|
|
2816
|
+
async updateUserPresence(data) {
|
|
2817
|
+
try {
|
|
2818
|
+
this.cachedPresenceData = data;
|
|
2819
|
+
await this.sdk.convexClient.mutation(api7.sdk.presence.heartbeat, {
|
|
2820
|
+
data,
|
|
2821
|
+
deviceFingerprint: this.deviceFingerprint
|
|
2822
|
+
});
|
|
2823
|
+
return true;
|
|
2824
|
+
} catch (error) {
|
|
2825
|
+
logger.error(`Error updating presence: ${error}`);
|
|
2826
|
+
return false;
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
isCurrentlyConnected() {
|
|
2830
|
+
return this.isConnected;
|
|
2831
|
+
}
|
|
2762
2832
|
/** Full teardown — stops intervals and removes all listeners */
|
|
2763
2833
|
destroy() {
|
|
2764
2834
|
this.stop();
|
|
2835
|
+
if (this.gamepadPollInterval !== null) {
|
|
2836
|
+
clearInterval(this.gamepadPollInterval);
|
|
2837
|
+
this.gamepadPollInterval = null;
|
|
2838
|
+
}
|
|
2765
2839
|
document.removeEventListener(
|
|
2766
2840
|
"visibilitychange",
|
|
2767
2841
|
this.handleVisibilityChange
|
|
2768
2842
|
);
|
|
2843
|
+
window.removeEventListener(
|
|
2844
|
+
"keydown",
|
|
2845
|
+
this.handleUserInput,
|
|
2846
|
+
INPUT_LISTENER_OPTS
|
|
2847
|
+
);
|
|
2848
|
+
window.removeEventListener(
|
|
2849
|
+
"pointerdown",
|
|
2850
|
+
this.handleUserInput,
|
|
2851
|
+
INPUT_LISTENER_OPTS
|
|
2852
|
+
);
|
|
2853
|
+
window.removeEventListener(
|
|
2854
|
+
"pointermove",
|
|
2855
|
+
this.handleUserInput,
|
|
2856
|
+
INPUT_LISTENER_OPTS
|
|
2857
|
+
);
|
|
2858
|
+
window.removeEventListener(
|
|
2859
|
+
"wheel",
|
|
2860
|
+
this.handleUserInput,
|
|
2861
|
+
INPUT_LISTENER_OPTS
|
|
2862
|
+
);
|
|
2769
2863
|
}
|
|
2864
|
+
// =================
|
|
2865
|
+
// Private functions
|
|
2866
|
+
// =================
|
|
2770
2867
|
tickHeartbeat() {
|
|
2771
2868
|
const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeatTime;
|
|
2772
2869
|
const needsReestablish = this.isFirstTick || timeSinceLastHeartbeat >= HEARTBEAT.CLIENT_REESTABLISH_THRESHOLD_MS;
|
|
@@ -2796,21 +2893,22 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2796
2893
|
});
|
|
2797
2894
|
}
|
|
2798
2895
|
/**
|
|
2799
|
-
*
|
|
2800
|
-
*
|
|
2801
|
-
* @returns true if the presence was updated successfully
|
|
2896
|
+
* Polls connected gamepads; any pressed button or out-of-deadzone axis
|
|
2897
|
+
* counts as user activity and (re)starts the heartbeat.
|
|
2802
2898
|
*/
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2899
|
+
pollGamepads() {
|
|
2900
|
+
if (typeof navigator === "undefined" || !navigator.getGamepads) return;
|
|
2901
|
+
const pads = navigator.getGamepads();
|
|
2902
|
+
for (const pad of pads) {
|
|
2903
|
+
if (!pad) continue;
|
|
2904
|
+
if (pad.buttons.some((b) => b.pressed)) {
|
|
2905
|
+
this.start();
|
|
2906
|
+
return;
|
|
2907
|
+
}
|
|
2908
|
+
if (pad.axes.some((a) => Math.abs(a) > this.GAMEPAD_AXIS_DEADZONE)) {
|
|
2909
|
+
this.start();
|
|
2910
|
+
return;
|
|
2911
|
+
}
|
|
2814
2912
|
}
|
|
2815
2913
|
}
|
|
2816
2914
|
/**
|
|
@@ -2857,9 +2955,6 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2857
2955
|
logger.error("Error testing connection:", error);
|
|
2858
2956
|
}
|
|
2859
2957
|
}
|
|
2860
|
-
isCurrentlyConnected() {
|
|
2861
|
-
return this.isConnected;
|
|
2862
|
-
}
|
|
2863
2958
|
};
|
|
2864
2959
|
|
|
2865
2960
|
// src/services/gameEvents.ts
|
|
@@ -3673,11 +3768,11 @@ var WavedashSDK = class extends EventTarget {
|
|
|
3673
3768
|
expectAuth: true
|
|
3674
3769
|
});
|
|
3675
3770
|
this.gameCloudId = sdkConfig.gameCloudId;
|
|
3771
|
+
this.iframeMessenger = iframeMessenger;
|
|
3676
3772
|
this.convexClient.setAuth(
|
|
3677
3773
|
({ forceRefreshToken }) => this.getAuthToken(forceRefreshToken)
|
|
3678
3774
|
);
|
|
3679
3775
|
this.wavedashUser = sdkConfig.wavedashUser;
|
|
3680
|
-
this.iframeMessenger = iframeMessenger;
|
|
3681
3776
|
this.ugcHost = sdkConfig.ugcHost;
|
|
3682
3777
|
this.uploadsHost = sdkConfig.uploadsHost;
|
|
3683
3778
|
this.swMessenger = new SwMessenger();
|