Files

64 lines
1.8 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Export / import of the save as a JSON or TXT file (or pasted text).
// Works on every device: download via a Blob link, import via file input or paste.
// The save is theme-independent: any export can be imported under any theme.
import { sanitizeState, serializeState } from '../engine/state.js';
const GAME_ID = 'idle-clicker';
const FORMAT = 1;
export class ImportError extends Error {
/** @param {'empty'|'invalid'|'wrong_game'} code */
constructor(code) {
super(code);
this.code = code;
}
}
/** The text a player downloads, copies or pastes back. */
export function buildExport(state, now = Date.now()) {
return JSON.stringify(
{
game: GAME_ID,
format: FORMAT,
exportedAt: new Date(now).toISOString(),
state: JSON.parse(serializeState(state)),
},
null,
2,
);
}
/** Validate imported text and return a clean state. Throws ImportError; never trusts the content. */
export function parseImport(text, ctx) {
const trimmed = String(text ?? '').trim().replace(/^/, '');
if (!trimmed) throw new ImportError('empty');
let data;
try {
data = JSON.parse(trimmed);
} catch {
throw new ImportError('invalid');
}
if (data?.game !== GAME_ID || data.format !== FORMAT) throw new ImportError('wrong_game');
const state = sanitizeState(data.state, ctx);
if (!state) throw new ImportError('invalid');
return state;
}
export function downloadText(filename, text, mime = 'application/json') {
const url = URL.createObjectURL(new Blob([text], { type: `${mime};charset=utf-8` }));
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.append(link);
link.click();
link.remove();
setTimeout(() => URL.revokeObjectURL(url), 10_000);
}
export function readFileText(file) {
return file.text();
}