@wvdsh/sdk-js 1.3.10 → 1.3.11
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 +24 -6
- package/dist/index.js +108 -113
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -385,14 +385,25 @@ declare class FileSystemManager extends WavedashManager {
|
|
|
385
385
|
*/
|
|
386
386
|
deleteRemoteFile(filePath: string): Promise<string>;
|
|
387
387
|
/**
|
|
388
|
-
* Downloads a remote file to a local location
|
|
388
|
+
* Downloads a remote file to a local location.
|
|
389
|
+
* Throws on failure; the error message is the server's HTTP status (e.g. "404 (Not Found)")
|
|
390
|
+
* or a network-level description if the server didn't respond. See also: {@link remoteFileExists}
|
|
389
391
|
* @param filePath - The path of the remote file to download
|
|
390
392
|
* @returns The path of the local file that the remote file was downloaded to
|
|
391
393
|
*/
|
|
392
394
|
downloadRemoteFile(filePath: string): Promise<string>;
|
|
393
395
|
/**
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
+
* Checks whether a remote file exists by issuing a HEAD request.
|
|
397
|
+
* Does NOT throw for the "file does not exist" case — returns false.
|
|
398
|
+
* Throws only for real errors (network failure, auth failure, server error).
|
|
399
|
+
* @param filePath - The path of the remote file to check
|
|
400
|
+
* @returns true if the remote file exists, false otherwise
|
|
401
|
+
*/
|
|
402
|
+
remoteFileExists(filePath: string): Promise<boolean>;
|
|
403
|
+
/**
|
|
404
|
+
* Lists each file in a remote directory, including its subdirectories.
|
|
405
|
+
* Returns only file paths, no directory paths.
|
|
406
|
+
* An empty or non-existent directory returns an empty array — not an error.
|
|
396
407
|
* @param path - The path of the remote directory to list
|
|
397
408
|
* @returns A list of metadata for each file in the remote directory
|
|
398
409
|
*/
|
|
@@ -401,7 +412,7 @@ declare class FileSystemManager extends WavedashManager {
|
|
|
401
412
|
writeLocalFile(filePath: string, data: Uint8Array): Promise<boolean>;
|
|
402
413
|
readLocalFile(filePath: string): Promise<Uint8Array | null>;
|
|
403
414
|
upload(presignedUploadUrl: string, filePath: string): Promise<boolean>;
|
|
404
|
-
download(url: string, filePath: string): Promise<
|
|
415
|
+
download(url: string, filePath: string): Promise<void>;
|
|
405
416
|
private getRemoteStorageOrigin;
|
|
406
417
|
private getRemoteStorageUrl;
|
|
407
418
|
private uploadFromIndexedDb;
|
|
@@ -1009,12 +1020,19 @@ declare class WavedashSDK extends EventTarget {
|
|
|
1009
1020
|
*/
|
|
1010
1021
|
deleteRemoteFile(filePath: string): Promise<WavedashResponse<string>>;
|
|
1011
1022
|
/**
|
|
1012
|
-
* Downloads a remote file to a local location
|
|
1023
|
+
* Downloads a remote file to a local location.
|
|
1024
|
+
* Returns success=false (with the server status in `message`) if the file
|
|
1025
|
+
* doesn't exist or any other error occurs. See also: {@link remoteFileExists}
|
|
1013
1026
|
* @param filePath - The path of the remote file to download
|
|
1014
|
-
* @param downloadTo - Optionally provide a path to download the file to, defaults to the same path as the remote file
|
|
1015
1027
|
* @returns The path of the local file that the remote file was downloaded to
|
|
1016
1028
|
*/
|
|
1017
1029
|
downloadRemoteFile(filePath: string): Promise<WavedashResponse<string>>;
|
|
1030
|
+
/**
|
|
1031
|
+
* Checks whether a remote file exists. Sends a lightweight HEAD request to check for existence.
|
|
1032
|
+
* @param filePath - The path of the remote file to check
|
|
1033
|
+
* @returns true if the remote file exists, false if it does not.
|
|
1034
|
+
*/
|
|
1035
|
+
remoteFileExists(filePath: string): Promise<WavedashResponse<boolean>>;
|
|
1018
1036
|
/**
|
|
1019
1037
|
* Uploads a local file to remote storage
|
|
1020
1038
|
* @param filePath - The path of the local file to upload
|
package/dist/index.js
CHANGED
|
@@ -270,18 +270,14 @@ var _LobbyManager = class _LobbyManager extends WavedashManager {
|
|
|
270
270
|
}
|
|
271
271
|
getLobbyUsers(lobbyId) {
|
|
272
272
|
if (this.lobbyId !== lobbyId) {
|
|
273
|
-
logger.error(
|
|
274
|
-
"Must be a member of the lobby to access user list"
|
|
275
|
-
);
|
|
273
|
+
logger.error("Must be a member of the lobby to access user list");
|
|
276
274
|
return [];
|
|
277
275
|
}
|
|
278
276
|
return this.lobbyUsers;
|
|
279
277
|
}
|
|
280
278
|
getHostId(lobbyId) {
|
|
281
279
|
if (this.lobbyId !== lobbyId) {
|
|
282
|
-
logger.error(
|
|
283
|
-
"Must be a member of the lobby to access the host ID"
|
|
284
|
-
);
|
|
280
|
+
logger.error("Must be a member of the lobby to access the host ID");
|
|
285
281
|
return null;
|
|
286
282
|
}
|
|
287
283
|
return this.lobbyHostId;
|
|
@@ -467,9 +463,7 @@ var _LobbyManager = class _LobbyManager extends WavedashManager {
|
|
|
467
463
|
handleLobbyKicked(reason = LobbyKickedReason.KICKED) {
|
|
468
464
|
const lobbyId = this.lobbyId;
|
|
469
465
|
if (!lobbyId) return;
|
|
470
|
-
logger.warn(
|
|
471
|
-
`User was removed from lobby: ${lobbyId} (reason: ${reason})`
|
|
472
|
-
);
|
|
466
|
+
logger.warn(`User was removed from lobby: ${lobbyId} (reason: ${reason})`);
|
|
473
467
|
this.cleanupLobbyState();
|
|
474
468
|
this.sdk.iframeMessenger.postToParent(IFRAME_MESSAGE_TYPE.LOBBY_LEFT, {
|
|
475
469
|
lobbyId
|
|
@@ -576,9 +570,7 @@ var _LobbyManager = class _LobbyManager extends WavedashManager {
|
|
|
576
570
|
try {
|
|
577
571
|
if (newUsers.length <= 1) {
|
|
578
572
|
this.sdk.p2pManager.disconnectP2P();
|
|
579
|
-
logger.debug(
|
|
580
|
-
"Only one user in lobby, P2P connections disconnected"
|
|
581
|
-
);
|
|
573
|
+
logger.debug("Only one user in lobby, P2P connections disconnected");
|
|
582
574
|
return;
|
|
583
575
|
}
|
|
584
576
|
const wavedashUsers = newUsers.map((lobbyUser) => ({
|
|
@@ -745,21 +737,41 @@ var FileSystemManager = class extends WavedashManager {
|
|
|
745
737
|
return filePath;
|
|
746
738
|
}
|
|
747
739
|
/**
|
|
748
|
-
* Downloads a remote file to a local location
|
|
740
|
+
* Downloads a remote file to a local location.
|
|
741
|
+
* Throws on failure; the error message is the server's HTTP status (e.g. "404 (Not Found)")
|
|
742
|
+
* or a network-level description if the server didn't respond. See also: {@link remoteFileExists}
|
|
749
743
|
* @param filePath - The path of the remote file to download
|
|
750
744
|
* @returns The path of the local file that the remote file was downloaded to
|
|
751
745
|
*/
|
|
752
746
|
async downloadRemoteFile(filePath) {
|
|
753
747
|
const url = this.getRemoteStorageUrl(filePath);
|
|
754
|
-
|
|
755
|
-
if (!success) {
|
|
756
|
-
throw new Error(`Failed to download file: ${filePath}`);
|
|
757
|
-
}
|
|
748
|
+
await this.download(url, filePath);
|
|
758
749
|
return filePath;
|
|
759
750
|
}
|
|
760
751
|
/**
|
|
761
|
-
*
|
|
762
|
-
*
|
|
752
|
+
* Checks whether a remote file exists by issuing a HEAD request.
|
|
753
|
+
* Does NOT throw for the "file does not exist" case — returns false.
|
|
754
|
+
* Throws only for real errors (network failure, auth failure, server error).
|
|
755
|
+
* @param filePath - The path of the remote file to check
|
|
756
|
+
* @returns true if the remote file exists, false otherwise
|
|
757
|
+
*/
|
|
758
|
+
async remoteFileExists(filePath) {
|
|
759
|
+
const url = this.getRemoteStorageUrl(filePath);
|
|
760
|
+
const jwt = await this.sdk.ensureGameplayJwt();
|
|
761
|
+
const response = await fetch(url, {
|
|
762
|
+
method: "HEAD",
|
|
763
|
+
headers: {
|
|
764
|
+
Authorization: `Bearer ${jwt}`
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
if (response.status === 404) return false;
|
|
768
|
+
if (response.ok) return true;
|
|
769
|
+
throw new Error(`${response.status} (${response.statusText})`);
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Lists each file in a remote directory, including its subdirectories.
|
|
773
|
+
* Returns only file paths, no directory paths.
|
|
774
|
+
* An empty or non-existent directory returns an empty array — not an error.
|
|
763
775
|
* @param path - The path of the remote directory to list
|
|
764
776
|
* @returns A list of metadata for each file in the remote directory
|
|
765
777
|
*/
|
|
@@ -772,6 +784,7 @@ var FileSystemManager = class extends WavedashManager {
|
|
|
772
784
|
Authorization: `Bearer ${jwt}`
|
|
773
785
|
}
|
|
774
786
|
});
|
|
787
|
+
if (response.status === 404) return [];
|
|
775
788
|
if (!response.ok) {
|
|
776
789
|
throw new Error(`${response.status} (${response.statusText})`);
|
|
777
790
|
}
|
|
@@ -785,8 +798,14 @@ var FileSystemManager = class extends WavedashManager {
|
|
|
785
798
|
const files = await this.listRemoteDirectory(path);
|
|
786
799
|
const downloadPromises = files.map(async (file) => {
|
|
787
800
|
const url = this.getRemoteStorageUrl(file.key);
|
|
788
|
-
|
|
789
|
-
|
|
801
|
+
try {
|
|
802
|
+
await this.download(url, file.key);
|
|
803
|
+
return { fileName: file.name, success: true };
|
|
804
|
+
} catch (error) {
|
|
805
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
806
|
+
logger.error(`Failed to download ${file.name}: ${message}`);
|
|
807
|
+
return { fileName: file.name, success: false };
|
|
808
|
+
}
|
|
790
809
|
});
|
|
791
810
|
const downloadResults = await Promise.all(downloadPromises);
|
|
792
811
|
const failedDownloads = downloadResults.filter((result) => !result.success);
|
|
@@ -849,12 +868,15 @@ var FileSystemManager = class extends WavedashManager {
|
|
|
849
868
|
}
|
|
850
869
|
return success;
|
|
851
870
|
}
|
|
852
|
-
// Helper to download a file from a URL and save locally
|
|
871
|
+
// Helper to download a file from a URL and save locally.
|
|
872
|
+
// Throws on any failure with a message containing the HTTP status (e.g.
|
|
873
|
+
// "404 (Not Found)") for server-side failures, or a network/FS error
|
|
874
|
+
// description otherwise. Callers should let the error propagate; the
|
|
875
|
+
// public apiCall wrapper surfaces the message in WavedashResponse.message.
|
|
853
876
|
async download(url, filePath) {
|
|
854
877
|
logger.debug(`Downloading ${filePath} from: ${url}`);
|
|
855
878
|
if (this.sdk.engineInstance && !this.sdk.engineInstance.FS) {
|
|
856
|
-
|
|
857
|
-
return false;
|
|
879
|
+
throw new Error("Engine instance is missing the Emscripten FS API");
|
|
858
880
|
}
|
|
859
881
|
const jwt = await this.sdk.ensureGameplayJwt();
|
|
860
882
|
const response = await fetch(url, {
|
|
@@ -864,36 +886,34 @@ var FileSystemManager = class extends WavedashManager {
|
|
|
864
886
|
}
|
|
865
887
|
});
|
|
866
888
|
if (!response.ok) {
|
|
867
|
-
|
|
868
|
-
`Failed to download remote file: ${response.status} (${response.statusText})`
|
|
869
|
-
);
|
|
870
|
-
return false;
|
|
889
|
+
throw new Error(`${response.status} (${response.statusText})`);
|
|
871
890
|
}
|
|
872
891
|
const blob = await response.blob();
|
|
873
892
|
const arrayBuffer = await blob.arrayBuffer();
|
|
874
893
|
const dataArray = new Uint8Array(arrayBuffer);
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
} catch (_error) {
|
|
882
|
-
}
|
|
894
|
+
if (this.sdk.engineInstance) {
|
|
895
|
+
const dirPath = filePath.substring(0, filePath.lastIndexOf("/"));
|
|
896
|
+
if (dirPath) {
|
|
897
|
+
try {
|
|
898
|
+
this.sdk.engineInstance.FS.mkdirTree(dirPath);
|
|
899
|
+
} catch (_error) {
|
|
883
900
|
}
|
|
901
|
+
}
|
|
902
|
+
try {
|
|
884
903
|
this.sdk.engineInstance.FS.writeFile(filePath, dataArray);
|
|
885
|
-
}
|
|
886
|
-
const
|
|
887
|
-
|
|
904
|
+
} catch (error) {
|
|
905
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
906
|
+
throw new Error(`Failed to save file ${filePath} to engine FS: ${msg}`);
|
|
907
|
+
}
|
|
908
|
+
} else {
|
|
909
|
+
const success = await this.writeLocalFile(filePath, dataArray);
|
|
910
|
+
if (!success) {
|
|
911
|
+
throw new Error(
|
|
912
|
+
`Failed to save file ${filePath} to local IndexedDB storage`
|
|
913
|
+
);
|
|
888
914
|
}
|
|
889
|
-
logger.debug(`Successfully saved to: ${filePath}`);
|
|
890
|
-
return true;
|
|
891
|
-
} catch (error) {
|
|
892
|
-
logger.error(
|
|
893
|
-
`Failed to save file ${filePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
894
|
-
);
|
|
895
|
-
return false;
|
|
896
915
|
}
|
|
916
|
+
logger.debug(`Successfully saved to: ${filePath}`);
|
|
897
917
|
}
|
|
898
918
|
// ================
|
|
899
919
|
// Private Methods
|
|
@@ -1051,12 +1071,11 @@ var UGCManager = class extends WavedashManager {
|
|
|
1051
1071
|
api3.sdk.userGeneratedContent.getUGCItemDownloadUrl,
|
|
1052
1072
|
{ ugcId }
|
|
1053
1073
|
);
|
|
1054
|
-
|
|
1055
|
-
downloadUrl,
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
throw new Error(`Failed to download UGC item: ${ugcId}`);
|
|
1074
|
+
try {
|
|
1075
|
+
await this.sdk.fileSystemManager.download(downloadUrl, filePath);
|
|
1076
|
+
} catch (error) {
|
|
1077
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
1078
|
+
throw new Error(`Failed to download UGC item ${ugcId}: ${msg}`);
|
|
1060
1079
|
}
|
|
1061
1080
|
return ugcId;
|
|
1062
1081
|
}
|
|
@@ -1303,9 +1322,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1303
1322
|
return this.updateP2PConnection(members);
|
|
1304
1323
|
}
|
|
1305
1324
|
if (this.initializationInProgress && this.initializationLobbyId === lobbyId) {
|
|
1306
|
-
logger.debug(
|
|
1307
|
-
"P2P initialization already in progress, waiting..."
|
|
1308
|
-
);
|
|
1325
|
+
logger.debug("P2P initialization already in progress, waiting...");
|
|
1309
1326
|
await this.initializationInProgress;
|
|
1310
1327
|
if (this.currentConnection) {
|
|
1311
1328
|
return this.updateP2PConnection(members);
|
|
@@ -1386,9 +1403,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1386
1403
|
existingPeer.username = member.username;
|
|
1387
1404
|
}
|
|
1388
1405
|
} else {
|
|
1389
|
-
logger.debug(
|
|
1390
|
-
`Adding new peer: ${member.username} (${member.id})`
|
|
1391
|
-
);
|
|
1406
|
+
logger.debug(`Adding new peer: ${member.username} (${member.id})`);
|
|
1392
1407
|
this.currentConnection.peers[member.id] = {
|
|
1393
1408
|
userId: member.id,
|
|
1394
1409
|
username: member.username
|
|
@@ -1421,9 +1436,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1421
1436
|
return this.createOfferToPeer(userId);
|
|
1422
1437
|
});
|
|
1423
1438
|
await Promise.all(offerPromises);
|
|
1424
|
-
logger.debug(
|
|
1425
|
-
`Initiated ${offerPromises.length} offers to new peers`
|
|
1426
|
-
);
|
|
1439
|
+
logger.debug(`Initiated ${offerPromises.length} offers to new peers`);
|
|
1427
1440
|
}
|
|
1428
1441
|
}
|
|
1429
1442
|
for (const userId of Object.keys(
|
|
@@ -1512,10 +1525,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1512
1525
|
this.pendingProcessedMessageIds.delete(messageId);
|
|
1513
1526
|
}
|
|
1514
1527
|
} catch (error) {
|
|
1515
|
-
logger.error(
|
|
1516
|
-
"Failed to mark signaling messages as processed:",
|
|
1517
|
-
error
|
|
1518
|
-
);
|
|
1528
|
+
logger.error("Failed to mark signaling messages as processed:", error);
|
|
1519
1529
|
for (const messageId of newMessageIds) {
|
|
1520
1530
|
this.pendingProcessedMessageIds.delete(messageId);
|
|
1521
1531
|
}
|
|
@@ -1569,9 +1579,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1569
1579
|
await this.flushPendingIceCandidates(remoteUserId, pc);
|
|
1570
1580
|
const answer = await pc.createAnswer();
|
|
1571
1581
|
await pc.setLocalDescription(answer);
|
|
1572
|
-
logger.debug(
|
|
1573
|
-
` Answer created, waiting for ondatachannel events...`
|
|
1574
|
-
);
|
|
1582
|
+
logger.debug(` Answer created, waiting for ondatachannel events...`);
|
|
1575
1583
|
const answerData = {
|
|
1576
1584
|
type: answer.type,
|
|
1577
1585
|
sdp: answer.sdp
|
|
@@ -1603,10 +1611,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1603
1611
|
break;
|
|
1604
1612
|
}
|
|
1605
1613
|
default:
|
|
1606
|
-
logger.warn(
|
|
1607
|
-
"Unknown signaling message type:",
|
|
1608
|
-
message.messageType
|
|
1609
|
-
);
|
|
1614
|
+
logger.warn("Unknown signaling message type:", message.messageType);
|
|
1610
1615
|
}
|
|
1611
1616
|
}
|
|
1612
1617
|
/**
|
|
@@ -1648,9 +1653,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1648
1653
|
const peersToInitiate = Object.keys(connection.peers).filter((userId) => currentUserId < userId);
|
|
1649
1654
|
if (peersToInitiate.length > 0) {
|
|
1650
1655
|
const offerPromises = peersToInitiate.map((userId) => {
|
|
1651
|
-
logger.debug(
|
|
1652
|
-
`Initiating offer to peer ${userId} (lower userId rule)`
|
|
1653
|
-
);
|
|
1656
|
+
logger.debug(`Initiating offer to peer ${userId} (lower userId rule)`);
|
|
1654
1657
|
return this.createOfferToPeer(userId);
|
|
1655
1658
|
});
|
|
1656
1659
|
await Promise.all(offerPromises);
|
|
@@ -1691,9 +1694,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1691
1694
|
async createPeerConnection(remoteUserId, connection, shouldCreateChannels = false) {
|
|
1692
1695
|
const iceServers = await this.getIceServers();
|
|
1693
1696
|
if (!iceServers) {
|
|
1694
|
-
logger.error(
|
|
1695
|
-
`No ICE servers available for peer ${remoteUserId}`
|
|
1696
|
-
);
|
|
1697
|
+
logger.error(`No ICE servers available for peer ${remoteUserId}`);
|
|
1697
1698
|
this.sdk.gameEventManager.notifyGame(
|
|
1698
1699
|
WavedashEvents.P2P_CONNECTION_FAILED,
|
|
1699
1700
|
{
|
|
@@ -1919,9 +1920,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1919
1920
|
}
|
|
1920
1921
|
setupDataChannelHandlers(channel, remoteUserId, type) {
|
|
1921
1922
|
channel.onopen = () => {
|
|
1922
|
-
logger.debug(
|
|
1923
|
-
`${type} data channel opened with peer ${remoteUserId}`
|
|
1924
|
-
);
|
|
1923
|
+
logger.debug(`${type} data channel opened with peer ${remoteUserId}`);
|
|
1925
1924
|
if (this.isPeerReady(remoteUserId) && !this.establishedPeers.has(remoteUserId)) {
|
|
1926
1925
|
this.establishedPeers.add(remoteUserId);
|
|
1927
1926
|
const peer = this.currentConnection?.peers[remoteUserId];
|
|
@@ -1940,10 +1939,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1940
1939
|
this.enqueueMessage(event.data, remoteUserId);
|
|
1941
1940
|
};
|
|
1942
1941
|
channel.onerror = (error) => {
|
|
1943
|
-
logger.error(
|
|
1944
|
-
`Data channel error with peer ${remoteUserId}:`,
|
|
1945
|
-
error
|
|
1946
|
-
);
|
|
1942
|
+
logger.error(`Data channel error with peer ${remoteUserId}:`, error);
|
|
1947
1943
|
const peer = this.currentConnection?.peers[remoteUserId];
|
|
1948
1944
|
if (peer) {
|
|
1949
1945
|
this.sdk.gameEventManager.notifyGame(
|
|
@@ -1957,9 +1953,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1957
1953
|
}
|
|
1958
1954
|
};
|
|
1959
1955
|
channel.onclose = () => {
|
|
1960
|
-
logger.debug(
|
|
1961
|
-
`${type} data channel closed with peer ${remoteUserId}`
|
|
1962
|
-
);
|
|
1956
|
+
logger.debug(`${type} data channel closed with peer ${remoteUserId}`);
|
|
1963
1957
|
this.establishedPeers.delete(remoteUserId);
|
|
1964
1958
|
this.reconnectingPeers.delete(remoteUserId);
|
|
1965
1959
|
const peer = this.currentConnection?.peers[remoteUserId];
|
|
@@ -1988,9 +1982,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
1988
1982
|
return false;
|
|
1989
1983
|
}
|
|
1990
1984
|
if (!payload) {
|
|
1991
|
-
logger.error(
|
|
1992
|
-
`P2P send called with missing payload, dropping message.`
|
|
1993
|
-
);
|
|
1985
|
+
logger.error(`P2P send called with missing payload, dropping message.`);
|
|
1994
1986
|
this.reportPacketDrop(appChannel, "SEND", "INVALID_PAYLOAD_SIZE");
|
|
1995
1987
|
return false;
|
|
1996
1988
|
}
|
|
@@ -2031,10 +2023,7 @@ var _P2PManager = class _P2PManager extends WavedashManager {
|
|
|
2031
2023
|
try {
|
|
2032
2024
|
channel.send(messageData);
|
|
2033
2025
|
} catch (error) {
|
|
2034
|
-
logger.error(
|
|
2035
|
-
`P2P broadcast to peer ${peerUserId} failed:`,
|
|
2036
|
-
error
|
|
2037
|
-
);
|
|
2026
|
+
logger.error(`P2P broadcast to peer ${peerUserId} failed:`, error);
|
|
2038
2027
|
}
|
|
2039
2028
|
});
|
|
2040
2029
|
} else {
|
|
@@ -2517,11 +2506,10 @@ var StatsManager = class extends WavedashManager {
|
|
|
2517
2506
|
// storeNow=true (and storeStats()) call .flush() to fire the pending invocation
|
|
2518
2507
|
// immediately. The in-flight gate in persist() covers mutations that outlast
|
|
2519
2508
|
// the throttle window, which would otherwise overlap and cause OCC conflicts.
|
|
2520
|
-
this.throttledPersist = throttle2(
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
);
|
|
2509
|
+
this.throttledPersist = throttle2(() => this.persist(), STORE_THROTTLE_MS, {
|
|
2510
|
+
leading: false,
|
|
2511
|
+
trailing: true
|
|
2512
|
+
});
|
|
2525
2513
|
this.subscribe();
|
|
2526
2514
|
this.requestStats().catch((error) => {
|
|
2527
2515
|
logger.error("Initial stats fetch failed:", error);
|
|
@@ -2557,10 +2545,7 @@ var StatsManager = class extends WavedashManager {
|
|
|
2557
2545
|
this.knownAchievementIds = new Set(ids);
|
|
2558
2546
|
},
|
|
2559
2547
|
(error) => {
|
|
2560
|
-
logger.error(
|
|
2561
|
-
"Achievement identifiers subscription error:",
|
|
2562
|
-
error
|
|
2563
|
-
);
|
|
2548
|
+
logger.error("Achievement identifiers subscription error:", error);
|
|
2564
2549
|
}
|
|
2565
2550
|
),
|
|
2566
2551
|
this.sdk.convexClient.onUpdate(
|
|
@@ -2834,9 +2819,7 @@ var HeartbeatManager = class extends WavedashManager {
|
|
|
2834
2819
|
);
|
|
2835
2820
|
} else if (!this.isConnected && wasConnected) {
|
|
2836
2821
|
this.disconnectedAt = Date.now();
|
|
2837
|
-
logger.warn(
|
|
2838
|
-
"Backend disconnected - attempting to reconnect..."
|
|
2839
|
-
);
|
|
2822
|
+
logger.warn("Backend disconnected - attempting to reconnect...");
|
|
2840
2823
|
this.sdk.gameEventManager.notifyGame(
|
|
2841
2824
|
WavedashEvents.BACKEND_RECONNECTING,
|
|
2842
2825
|
connection
|
|
@@ -3118,7 +3101,7 @@ var FriendsManager = class extends WavedashManager {
|
|
|
3118
3101
|
/**
|
|
3119
3102
|
* Replace the leaderboard-page cache with the users from a single page of
|
|
3120
3103
|
* leaderboard entries.
|
|
3121
|
-
*
|
|
3104
|
+
*
|
|
3122
3105
|
* In general devs should just use the username and userAvatarUrl returned
|
|
3123
3106
|
* from `listLeaderboardEntries` directly, but we cache the latest leaderboard
|
|
3124
3107
|
* page here just so getUserAvatarUrl and getUsername still work for the current page.
|
|
@@ -3515,9 +3498,7 @@ var WavedashSDK = class extends EventTarget {
|
|
|
3515
3498
|
}
|
|
3516
3499
|
this.config = config ?? {};
|
|
3517
3500
|
this._initialized = true;
|
|
3518
|
-
logger.setLogLevel(
|
|
3519
|
-
this.config.debug ? LOG_LEVEL.DEBUG : LOG_LEVEL.WARN
|
|
3520
|
-
);
|
|
3501
|
+
logger.setLogLevel(this.config.debug ? LOG_LEVEL.DEBUG : LOG_LEVEL.WARN);
|
|
3521
3502
|
this.p2pManager.init(this.config.p2p);
|
|
3522
3503
|
logger.debug("Initialized with config:", this.config);
|
|
3523
3504
|
if (!this.config.deferEvents) {
|
|
@@ -3903,9 +3884,10 @@ var WavedashSDK = class extends EventTarget {
|
|
|
3903
3884
|
);
|
|
3904
3885
|
}
|
|
3905
3886
|
/**
|
|
3906
|
-
* Downloads a remote file to a local location
|
|
3887
|
+
* Downloads a remote file to a local location.
|
|
3888
|
+
* Returns success=false (with the server status in `message`) if the file
|
|
3889
|
+
* doesn't exist or any other error occurs. See also: {@link remoteFileExists}
|
|
3907
3890
|
* @param filePath - The path of the remote file to download
|
|
3908
|
-
* @param downloadTo - Optionally provide a path to download the file to, defaults to the same path as the remote file
|
|
3909
3891
|
* @returns The path of the local file that the remote file was downloaded to
|
|
3910
3892
|
*/
|
|
3911
3893
|
async downloadRemoteFile(filePath) {
|
|
@@ -3916,6 +3898,19 @@ var WavedashSDK = class extends EventTarget {
|
|
|
3916
3898
|
filePath
|
|
3917
3899
|
);
|
|
3918
3900
|
}
|
|
3901
|
+
/**
|
|
3902
|
+
* Checks whether a remote file exists. Sends a lightweight HEAD request to check for existence.
|
|
3903
|
+
* @param filePath - The path of the remote file to check
|
|
3904
|
+
* @returns true if the remote file exists, false if it does not.
|
|
3905
|
+
*/
|
|
3906
|
+
async remoteFileExists(filePath) {
|
|
3907
|
+
return this.apiCall(
|
|
3908
|
+
this.fileSystemManager,
|
|
3909
|
+
"remoteFileExists",
|
|
3910
|
+
[["filePath", vString]],
|
|
3911
|
+
filePath
|
|
3912
|
+
);
|
|
3913
|
+
}
|
|
3919
3914
|
/**
|
|
3920
3915
|
* Uploads a local file to remote storage
|
|
3921
3916
|
* @param filePath - The path of the local file to upload
|