@arcadible/sdk 1.2.0 → 1.2.1
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.
|
@@ -13,6 +13,9 @@ const CHANNEL = "arcadible-saves";
|
|
|
13
13
|
// every save is a guest's for One; a signed-in player's sit beside them
|
|
14
14
|
// later, under their own id, with no migration.
|
|
15
15
|
const GUEST = "guest";
|
|
16
|
+
// after a failed reopen, how long calls fail at once before it's tried again,
|
|
17
|
+
// so a game saving every frame doesn't try, and fail, every frame.
|
|
18
|
+
const REOPEN_WAIT = 1000;
|
|
16
19
|
// [function]
|
|
17
20
|
function settle(request) {
|
|
18
21
|
return new Promise((resolve, reject) => {
|
|
@@ -66,7 +69,7 @@ function isClosed(err) {
|
|
|
66
69
|
// refuses to open (a browser blocking site data, some `file://` pages),
|
|
67
70
|
// they're kept in memory, and `status()` says so. Once it has opened, it
|
|
68
71
|
// never switches: a lost connection fails calls with `unavailable` until it
|
|
69
|
-
// opens again, rather than show an empty copy.
|
|
72
|
+
// opens again, trying at most once a second, rather than show an empty copy.
|
|
70
73
|
export function indexedDBBackend(options = {}) {
|
|
71
74
|
const factory = options.factory === undefined
|
|
72
75
|
? (globalThis.indexedDB ?? null)
|
|
@@ -79,6 +82,9 @@ export function indexedDBBackend(options = {}) {
|
|
|
79
82
|
let opened = false;
|
|
80
83
|
let current = null;
|
|
81
84
|
let opening = null;
|
|
85
|
+
// whether reopening has failed since it last worked, and when to try again.
|
|
86
|
+
let down = false;
|
|
87
|
+
let retryAt = 0;
|
|
82
88
|
let asked = false;
|
|
83
89
|
const keyOf = (scope) => `${player}\u0000${scope.game}\u0000${scope.channel}`;
|
|
84
90
|
const rangeOf = (scope) => IDBKeyRange.only([player, scope.game, scope.channel]);
|
|
@@ -86,6 +92,7 @@ export function indexedDBBackend(options = {}) {
|
|
|
86
92
|
if (current === db)
|
|
87
93
|
current = null;
|
|
88
94
|
};
|
|
95
|
+
const unreachable = () => new ArcadibleError(Codes.Unavailable, "Saves can't be reached right now. Try again.");
|
|
89
96
|
const connect = async function () {
|
|
90
97
|
try {
|
|
91
98
|
if (!factory)
|
|
@@ -103,13 +110,19 @@ export function indexedDBBackend(options = {}) {
|
|
|
103
110
|
globalThis.navigator?.storage?.persist?.().catch(() => false);
|
|
104
111
|
}
|
|
105
112
|
opened = true;
|
|
113
|
+
down = false;
|
|
106
114
|
current = db;
|
|
107
115
|
return db;
|
|
108
116
|
}
|
|
109
117
|
catch (err) {
|
|
110
118
|
if (opened) {
|
|
111
|
-
|
|
112
|
-
|
|
119
|
+
// once until it works again: the calls failing meanwhile say so.
|
|
120
|
+
if (!down) {
|
|
121
|
+
log("warn", "the saves' storage couldn't be opened again.", err);
|
|
122
|
+
}
|
|
123
|
+
down = true;
|
|
124
|
+
retryAt = Date.now() + (options.reopenWait ?? REOPEN_WAIT);
|
|
125
|
+
throw unreachable();
|
|
113
126
|
}
|
|
114
127
|
log("warn", "this browser won't keep saves here, so they're kept in memory until the page closes.", err);
|
|
115
128
|
status = "memory";
|
|
@@ -125,6 +138,9 @@ export function indexedDBBackend(options = {}) {
|
|
|
125
138
|
return Promise.resolve(null);
|
|
126
139
|
if (current)
|
|
127
140
|
return Promise.resolve(current);
|
|
141
|
+
if (down && !opening && Date.now() < retryAt) {
|
|
142
|
+
return Promise.reject(unreachable());
|
|
143
|
+
}
|
|
128
144
|
opening ??= connect();
|
|
129
145
|
return opening;
|
|
130
146
|
};
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.2.
|
|
1
|
+
export declare const VERSION = "1.2.1";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED