-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdb.ts
More file actions
101 lines (84 loc) · 2.74 KB
/
Copy pathdb.ts
File metadata and controls
101 lines (84 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import Dexie, { type EntityTable, type Table } from "dexie";
import type {
ConfigValues,
EncodedParams,
GameStatus,
PuzzleId,
} from "../puzzle/types.ts";
// Settings shared by all puzzles
export interface CommonSettings {
// App level settings
allowOfflineUse?: boolean;
autoUpdate?: boolean;
colorScheme?: "light" | "dark" | "system";
// Catalog-level settings
favoritePuzzles?: PuzzleId[];
showIntro?: boolean;
showUnfinishedPuzzles?: boolean;
// Preferences shared between all puzzles
puzzlePreferences?: ConfigValues;
// Secondary button emulation
showMouseButtonToggle?: boolean;
rightButtonLongPress?: boolean;
rightButtonTwoFingerTap?: boolean;
rightButtonAudioVolume?: number; // 0-100; 0 disables
rightButtonHoldTime?: number; // milliseconds
rightButtonDragThreshold?: number; // css pixel radius
// Appearance
showEndNotification?: boolean;
showPuzzleKeyboard?: boolean;
statusbarPlacement?: "start" | "end" | "hidden";
maxScale?: number | null; // null in DB/json === Infinity in exposed value
}
// PuzzleId-specific settings
export interface PuzzleSettings {
puzzlePreferences?: ConfigValues;
customPresets?: Array<{
name: string;
params: EncodedParams;
}>;
// Default params for new puzzles
params?: EncodedParams;
// For unfinished puzzles, timestamp when the alert was last shown
lastUnfinishedAlert?: number;
}
export type SettingsRecord =
| { id: "puzzle-common"; type: "puzzle-common"; data: CommonSettings }
| { id: PuzzleId; type: "puzzle"; data: PuzzleSettings };
export enum SaveType {
User = 0,
Auto = 1,
}
export const TIMESTAMP_MIN = Dexie.minKey;
export const TIMESTAMP_MAX = Dexie.maxKey;
export const PUZZLE_ID_MIN = Dexie.minKey;
export const PUZZLE_ID_MAX = Dexie.maxKey;
export interface SavedGameMetadata {
filename: string; // user filename or autoSaveFilename
puzzleId: PuzzleId;
timestamp: number;
status: GameStatus;
gameId: string;
}
export interface SavedGameRecord extends SavedGameMetadata {
saveType: SaveType; // IndexedDB can't index boolean, so use a number
// data was originally stored as Blob; changed for Safari private browsing mode
data: Uint8Array<ArrayBuffer> | Blob;
checkpoints?: readonly number[];
}
class Database extends Dexie {
settings!: EntityTable<SettingsRecord, "id">;
savedGames!: Table<SavedGameRecord, [PuzzleId, SaveType, string]>;
constructor() {
super("PuzzleAppData");
this.version(2).stores({
settings: ["id", "type"].join(", "),
savedGames: [
"&[puzzleId+saveType+filename]", // compound primary key
"[saveType+puzzleId+timestamp]", // supports query by saveType, most recent
].join(", "),
});
}
}
// Singleton database instance
export const db = new Database();