35 lines
1.4 KiB
JavaScript
35 lines
1.4 KiB
JavaScript
"use strict";
|
|
|
|
(function (global) {
|
|
const STORAGE_PREFIX = "tarinai_japanese_hash_slot_v1_";
|
|
const META_PREFIX = "tarinai_japanese_hash_slot_meta_v1_";
|
|
const SLOT_COUNT = 9;
|
|
function slotKey(slot) { return `${STORAGE_PREFIX}${slot}`; }
|
|
function metaKey(slot) { return `${META_PREFIX}${slot}`; }
|
|
function writeSlot(slot, hashText, meta = null) {
|
|
const hash = String(hashText || "").trim();
|
|
if (!hash.startsWith("\u305f")) throw new Error("unsupported Japanese hash slot value");
|
|
global.localStorage?.setItem(slotKey(slot), hash);
|
|
if (meta) global.localStorage?.setItem(metaKey(slot), JSON.stringify({ ...meta, savedAt: Date.now() }));
|
|
}
|
|
function readMeta(slot) {
|
|
const raw = global.localStorage?.getItem(metaKey(slot));
|
|
if (!raw) return null;
|
|
try { return JSON.parse(raw); } catch (_) { return null; }
|
|
}
|
|
function readSlot(slot) {
|
|
const hash = global.localStorage?.getItem(slotKey(slot));
|
|
if (!hash) return null;
|
|
return { hash, m: readMeta(slot) };
|
|
}
|
|
function requireSlot(slot) {
|
|
const entry = readSlot(slot);
|
|
if (!entry?.hash) throw new Error("empty slot");
|
|
return entry.hash;
|
|
}
|
|
function deleteSlot(slot) {
|
|
global.localStorage?.removeItem(slotKey(slot));
|
|
global.localStorage?.removeItem(metaKey(slot));
|
|
}
|
|
global.TarinaiSaveStorage = { SLOT_COUNT, writeSlot, readSlot, requireSlot, deleteSlot };
|
|
})(typeof window !== "undefined" ? window : globalThis);
|