diff --git a/electron/saveDataBinaryFormat.d.ts b/electron/saveDataBinaryFormat.d.ts index 183582233..747b50f12 100644 --- a/electron/saveDataBinaryFormat.d.ts +++ b/electron/saveDataBinaryFormat.d.ts @@ -1 +1 @@ -export declare const isBinaryFormat: (saveData: string | Uint8Array) => boolean; +export declare const isBinaryFormat: (saveData: string | Uint8Array) => boolean; diff --git a/markdown/bitburner.singularity.getsavedata.md b/markdown/bitburner.singularity.getsavedata.md index e48925b28..65491bc0e 100644 --- a/markdown/bitburner.singularity.getsavedata.md +++ b/markdown/bitburner.singularity.getsavedata.md @@ -9,11 +9,11 @@ This function returns the save data. **Signature:** ```typescript -getSaveData(): Promise; +getSaveData(): Promise>; ``` **Returns:** -Promise<Uint8Array> +Promise<Uint8Array<ArrayBuffer>> ## Remarks diff --git a/package-lock.json b/package-lock.json index 03e7dc97f..009e29724 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "prettier": "^2.8.8", "react-refresh": "^0.18.0", "style-loader": "^4.0.0", - "typescript": "^5.8.3", + "typescript": "^5.9.3", "webpack": "^5.100.2", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.2", @@ -18081,9 +18081,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 1ce42cbd2..53ce10849 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "prettier": "^2.8.8", "react-refresh": "^0.18.0", "style-loader": "^4.0.0", - "typescript": "^5.8.3", + "typescript": "^5.9.3", "webpack": "^5.100.2", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.2", diff --git a/src/Electron.tsx b/src/Electron.tsx index ab37bbea0..c78a91b51 100644 --- a/src/Electron.tsx +++ b/src/Electron.tsx @@ -10,6 +10,7 @@ import { exportScripts } from "./Terminal/commands/download"; import { CONSTANTS } from "./Constants"; import { commitHash } from "./utils/helpers/commitHash"; import { handleGetSaveDataInfoError } from "./utils/ErrorHandler"; +import { assertSaveData } from "./utils/TypeAssertion"; interface IReturnWebStatus extends IReturnStatus { data?: Record; @@ -122,9 +123,7 @@ function initElectronBridge(): void { }); }); bridge.receive("get-save-info-request", (saveData: unknown) => { - if (typeof saveData !== "string" && !(saveData instanceof Uint8Array)) { - throw new Error("Error while trying to get save info"); - } + assertSaveData(saveData); window.appSaveFns .getSaveInfo(saveData) .then((saveInfo) => { diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 5792ee5c9..cbc4bb98d 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -1879,7 +1879,7 @@ export interface Singularity { * @remarks * RAM cost: 1 GB * 16/4/1 */ - getSaveData(): Promise; + getSaveData(): Promise>; /** * Backup game save. diff --git a/src/types.ts b/src/types.ts index 384bbdd8d..39e218b42 100644 --- a/src/types.ts +++ b/src/types.ts @@ -46,4 +46,4 @@ export interface IMinMaxRange { } // Type of save data. The base64 format is string, the binary format is Uint8Array. -export type SaveData = string | Uint8Array; +export type SaveData = string | Uint8Array; diff --git a/src/utils/SaveDataUtils.ts b/src/utils/SaveDataUtils.ts index e4bc60a8d..d62f942f8 100644 --- a/src/utils/SaveDataUtils.ts +++ b/src/utils/SaveDataUtils.ts @@ -15,12 +15,12 @@ export function canUseBinaryFormat(): boolean { return "CompressionStream" in globalThis; } -async function compress(dataString: string): Promise { +async function compress(dataString: string): Promise> { const compressedReadableStream = new Blob([dataString]).stream().pipeThrough(new CompressionStream("gzip")); return new Uint8Array(await new Response(compressedReadableStream).arrayBuffer()); } -async function decompress(binaryData: Uint8Array): Promise { +async function decompress(binaryData: Uint8Array): Promise { const decompressedReadableStream = new Blob([binaryData]).stream().pipeThrough(new DecompressionStream("gzip")); const reader = decompressedReadableStream.pipeThrough(new TextDecoderStream("utf-8", { fatal: true })).getReader(); let result = ""; diff --git a/src/utils/TypeAssertion.ts b/src/utils/TypeAssertion.ts index 0b7312d80..018ef2a73 100644 --- a/src/utils/TypeAssertion.ts +++ b/src/utils/TypeAssertion.ts @@ -1,4 +1,4 @@ -import type { Unknownify } from "../types"; +import type { SaveData, Unknownify } from "../types"; // This function is empty because Unknownify is a typesafe assertion on any object with no runtime checks needed. // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -89,3 +89,14 @@ export function assertNumberArray(unknownData: unknown, assertFinite = false): a } } } + +export function assertSaveData(unknownData: unknown): asserts unknownData is SaveData { + if (typeof unknownData !== "string" && !(unknownData instanceof Uint8Array)) { + console.error(unknownData); + throw new Error(`Invalid save data. Its type is ${getFriendlyType(unknownData)}.`); + } + if (unknownData instanceof Uint8Array && !(unknownData.buffer instanceof ArrayBuffer)) { + console.error(unknownData); + throw new Error("Invalid save data. It's Uint8Array, but its buffer is not ArrayBuffer."); + } +}