@auxilium/datalynk-client 1.4.1 → 1.5.0
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.
- package/README.md +36 -0
- package/bin/datalynk-migrate.mjs +86 -0
- package/bin/datalynk-models.mjs +3 -3
- package/bin/utils.mjs +163 -0
- package/dist/api.d.ts +96 -5
- package/dist/api.d.ts.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/index.cjs +548 -845
- package/dist/index.mjs +546 -843
- package/dist/login-prompt.d.ts +4 -1
- package/dist/login-prompt.d.ts.map +1 -1
- package/dist/slice.d.ts +22 -5
- package/dist/slice.d.ts.map +1 -1
- package/dist/themes.d.ts +1 -1
- package/dist/themes.d.ts.map +1 -1
- package/dist/utils.d.ts +95 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/webrtc.d.ts +1 -1
- package/dist/webrtc.d.ts.map +1 -1
- package/package.json +11 -7
package/dist/index.cjs
CHANGED
|
@@ -1,902 +1,276 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.utils = {}));
|
|
3
3
|
})(this, function(exports2) {
|
|
4
4
|
"use strict";var __defProp = Object.defineProperty;
|
|
5
5
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
6
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} else {
|
|
16
|
-
Object.entries(obj).forEach(([key, value]) => {
|
|
17
|
-
if (undefinedOnly && value === void 0 || !undefinedOnly && value == null) delete obj[key];
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
return obj;
|
|
8
|
+
function clean(value, undefinedOnly = false) {
|
|
9
|
+
if (value == null) throw new Error("Cannot clean a NULL value");
|
|
10
|
+
if (Array.isArray(value)) return value.filter((item) => undefinedOnly ? item !== void 0 : item != null);
|
|
11
|
+
Object.entries(value).forEach(([key, item]) => {
|
|
12
|
+
if (undefinedOnly && item === void 0 || !undefinedOnly && item == null) delete value[key];
|
|
13
|
+
});
|
|
14
|
+
return value;
|
|
21
15
|
}
|
|
22
16
|
function deepCopy(value) {
|
|
23
17
|
try {
|
|
24
18
|
return structuredClone(value);
|
|
25
19
|
} catch {
|
|
26
|
-
|
|
20
|
+
const seen = [];
|
|
21
|
+
return JSON.parse(JSON.stringify(value, (_key, item) => {
|
|
22
|
+
if (typeof item === "object" && item !== null) {
|
|
23
|
+
if (seen.includes(item)) return "[Circular]";
|
|
24
|
+
seen.push(item);
|
|
25
|
+
}
|
|
26
|
+
return item;
|
|
27
|
+
}));
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
|
-
function
|
|
30
|
-
if (obj == null || !prop) return void 0;
|
|
31
|
-
return prop.split(/[.[\]]/g).filter((prop2) => prop2.length).reduce((obj2, prop2, i, arr) => {
|
|
32
|
-
if (prop2[0] == '"' || prop2[0] == "'") prop2 = prop2.slice(1, -1);
|
|
33
|
-
if (!(obj2 == null ? void 0 : obj2.hasOwnProperty(prop2))) {
|
|
34
|
-
return void 0;
|
|
35
|
-
}
|
|
36
|
-
return obj2[prop2];
|
|
37
|
-
}, obj);
|
|
38
|
-
}
|
|
39
|
-
function isEqual(a, b) {
|
|
40
|
-
const ta = typeof a, tb = typeof b;
|
|
41
|
-
if (ta != "object" || a == null || (tb != "object" || b == null))
|
|
42
|
-
return ta == "function" && tb == "function" ? a.toString() == b.toString() : a === b;
|
|
43
|
-
const keys = Object.keys(a);
|
|
44
|
-
if (keys.length != Object.keys(b).length) return false;
|
|
45
|
-
return Object.keys(a).every((key) => isEqual(a[key], b[key]));
|
|
46
|
-
}
|
|
47
|
-
function JSONAttemptParse(json) {
|
|
30
|
+
function JSONAttemptParse(value) {
|
|
48
31
|
try {
|
|
49
|
-
return JSON.parse(
|
|
32
|
+
return JSON.parse(value);
|
|
50
33
|
} catch {
|
|
51
|
-
return json;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function JSONSanitize(obj, space) {
|
|
55
|
-
const cache = [];
|
|
56
|
-
return JSON.stringify(obj, (key, value) => {
|
|
57
|
-
if (typeof value === "object" && value !== null) {
|
|
58
|
-
if (cache.includes(value)) return "[Circular]";
|
|
59
|
-
cache.push(value);
|
|
60
|
-
}
|
|
61
34
|
return value;
|
|
62
|
-
}, space);
|
|
63
|
-
}
|
|
64
|
-
class ASet extends Array {
|
|
65
|
-
/** Number of elements in set */
|
|
66
|
-
get size() {
|
|
67
|
-
return this.length;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Array to create set from, duplicate values will be removed
|
|
71
|
-
* @param {T[]} elements Elements which will be added to set
|
|
72
|
-
*/
|
|
73
|
-
constructor(elements = []) {
|
|
74
|
-
super();
|
|
75
|
-
if (!!(elements == null ? void 0 : elements["forEach"]))
|
|
76
|
-
elements.forEach((el) => this.add(el));
|
|
77
35
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Add elements to set if unique
|
|
80
|
-
* @param items
|
|
81
|
-
*/
|
|
82
|
-
add(...items) {
|
|
83
|
-
items.filter((el) => !this.has(el)).forEach((el) => this.push(el));
|
|
84
|
-
return this;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Remove all elements
|
|
88
|
-
*/
|
|
89
|
-
clear() {
|
|
90
|
-
this.splice(0, this.length);
|
|
91
|
-
return this;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Delete elements from set
|
|
95
|
-
* @param items Elements that will be deleted
|
|
96
|
-
*/
|
|
97
|
-
delete(...items) {
|
|
98
|
-
items.forEach((el) => {
|
|
99
|
-
const index = this.indexOf(el);
|
|
100
|
-
if (index != -1) this.splice(index, 1);
|
|
101
|
-
});
|
|
102
|
-
return this;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Create list of elements this set has which the comparison set does not
|
|
106
|
-
* @param {ASet<T>} set Set to compare against
|
|
107
|
-
* @return {ASet<T>} Different elements
|
|
108
|
-
*/
|
|
109
|
-
difference(set) {
|
|
110
|
-
return new ASet(this.filter((el) => !set.has(el)));
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Check if set includes element
|
|
114
|
-
* @param {T} el Element to look for
|
|
115
|
-
* @return {boolean} True if element was found, false otherwise
|
|
116
|
-
*/
|
|
117
|
-
has(el) {
|
|
118
|
-
return this.indexOf(el) != -1;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Find index number of element, or -1 if it doesn't exist. Matches by equality not reference
|
|
122
|
-
*
|
|
123
|
-
* @param {T} search Element to find
|
|
124
|
-
* @param {number} fromIndex Starting index position
|
|
125
|
-
* @return {number} Element index number or -1 if missing
|
|
126
|
-
*/
|
|
127
|
-
indexOf(search2, fromIndex) {
|
|
128
|
-
return super.findIndex((el) => isEqual(el, search2), fromIndex);
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Create list of elements this set has in common with the comparison set
|
|
132
|
-
* @param {ASet<T>} set Set to compare against
|
|
133
|
-
* @return {boolean} Set of common elements
|
|
134
|
-
*/
|
|
135
|
-
intersection(set) {
|
|
136
|
-
return new ASet(this.filter((el) => set.has(el)));
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Check if this set has no elements in common with the comparison set
|
|
140
|
-
* @param {ASet<T>} set Set to compare against
|
|
141
|
-
* @return {boolean} True if nothing in common, false otherwise
|
|
142
|
-
*/
|
|
143
|
-
isDisjointFrom(set) {
|
|
144
|
-
return this.intersection(set).size == 0;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Check if all elements in this set are included in the comparison set
|
|
148
|
-
* @param {ASet<T>} set Set to compare against
|
|
149
|
-
* @return {boolean} True if all elements are included, false otherwise
|
|
150
|
-
*/
|
|
151
|
-
isSubsetOf(set) {
|
|
152
|
-
return this.findIndex((el) => !set.has(el)) == -1;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Check if all elements from comparison set are included in this set
|
|
156
|
-
* @param {ASet<T>} set Set to compare against
|
|
157
|
-
* @return {boolean} True if all elements are included, false otherwise
|
|
158
|
-
*/
|
|
159
|
-
isSuperset(set) {
|
|
160
|
-
return set.findIndex((el) => !this.has(el)) == -1;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Create list of elements that are only in one set but not both (XOR)
|
|
164
|
-
* @param {ASet<T>} set Set to compare against
|
|
165
|
-
* @return {ASet<T>} New set of unique elements
|
|
166
|
-
*/
|
|
167
|
-
symmetricDifference(set) {
|
|
168
|
-
return new ASet([...this.difference(set), ...set.difference(this)]);
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Create joined list of elements included in this & the comparison set
|
|
172
|
-
* @param {ASet<T>} set Set join
|
|
173
|
-
* @return {ASet<T>} New set of both previous sets combined
|
|
174
|
-
*/
|
|
175
|
-
union(set) {
|
|
176
|
-
return new ASet([...this, ...set]);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
function sortByProp(prop, reverse = false) {
|
|
180
|
-
return function(a, b) {
|
|
181
|
-
const aVal = dotNotation(a, prop);
|
|
182
|
-
const bVal = dotNotation(b, prop);
|
|
183
|
-
if (typeof aVal == "number" && typeof bVal == "number")
|
|
184
|
-
return (reverse ? -1 : 1) * (aVal - bVal);
|
|
185
|
-
if (aVal > bVal) return reverse ? -1 : 1;
|
|
186
|
-
if (aVal < bVal) return reverse ? 1 : -1;
|
|
187
|
-
return 0;
|
|
188
|
-
};
|
|
189
36
|
}
|
|
190
37
|
function makeArray(value) {
|
|
191
38
|
return Array.isArray(value) ? value : [value];
|
|
192
39
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
__publicField2(this, "connection");
|
|
196
|
-
__publicField2(this, "tables");
|
|
197
|
-
this.database = database;
|
|
198
|
-
this.version = version2;
|
|
199
|
-
this.connection = new Promise((resolve, reject) => {
|
|
200
|
-
const req = indexedDB.open(this.database, this.version);
|
|
201
|
-
this.tables = tables.map((t) => {
|
|
202
|
-
t = typeof t == "object" ? t : { name: t };
|
|
203
|
-
return { ...t, name: t.name.toString() };
|
|
204
|
-
});
|
|
205
|
-
const tableNames = new ASet(this.tables.map((t) => t.name));
|
|
206
|
-
req.onerror = () => reject(req.error);
|
|
207
|
-
req.onsuccess = () => {
|
|
208
|
-
const db = req.result;
|
|
209
|
-
if (tableNames.symmetricDifference(new ASet(Array.from(db.objectStoreNames))).length) {
|
|
210
|
-
db.close();
|
|
211
|
-
Object.assign(this, new Database(this.database, this.tables, db.version + 1));
|
|
212
|
-
} else {
|
|
213
|
-
this.version = db.version;
|
|
214
|
-
resolve(db);
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
req.onupgradeneeded = () => {
|
|
218
|
-
const db = req.result;
|
|
219
|
-
const existingTables = new ASet(Array.from(db.objectStoreNames));
|
|
220
|
-
existingTables.difference(tableNames).forEach((name) => db.deleteObjectStore(name));
|
|
221
|
-
tableNames.difference(existingTables).forEach((name) => db.createObjectStore(name));
|
|
222
|
-
};
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
includes(name) {
|
|
226
|
-
return !!this.tables.find((t) => t.name == name.toString());
|
|
227
|
-
}
|
|
228
|
-
table(name) {
|
|
229
|
-
return new Table(this, name.toString());
|
|
230
|
-
}
|
|
40
|
+
function property(value, path) {
|
|
41
|
+
return path.split(".").reduce((current, key) => current == null ? void 0 : current[key], value);
|
|
231
42
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
add(value, key) {
|
|
248
|
-
return this.tx(this.name, (store) => store.add(value, key));
|
|
249
|
-
}
|
|
250
|
-
count() {
|
|
251
|
-
return this.tx(this.name, (store) => store.count(), true);
|
|
252
|
-
}
|
|
253
|
-
put(key, value) {
|
|
254
|
-
return this.tx(this.name, (store) => store.put(value, key));
|
|
255
|
-
}
|
|
256
|
-
getAll() {
|
|
257
|
-
return this.tx(this.name, (store) => store.getAll(), true);
|
|
258
|
-
}
|
|
259
|
-
getAllKeys() {
|
|
260
|
-
return this.tx(this.name, (store) => store.getAllKeys(), true);
|
|
261
|
-
}
|
|
262
|
-
get(key) {
|
|
263
|
-
return this.tx(this.name, (store) => store.get(key), true);
|
|
264
|
-
}
|
|
265
|
-
delete(key) {
|
|
266
|
-
return this.tx(this.name, (store) => store.delete(key));
|
|
267
|
-
}
|
|
268
|
-
clear() {
|
|
269
|
-
return this.tx(this.name, (store) => store.clear());
|
|
270
|
-
}
|
|
43
|
+
function sortByProp(path, reverse = false) {
|
|
44
|
+
return (a, b) => {
|
|
45
|
+
const aValue = property(a, path);
|
|
46
|
+
const bValue = property(b, path);
|
|
47
|
+
if (typeof aValue == "number" && typeof bValue == "number")
|
|
48
|
+
return (reverse ? -1 : 1) * (aValue - bValue);
|
|
49
|
+
if (aValue > bValue) return reverse ? -1 : 1;
|
|
50
|
+
if (aValue < bValue) return reverse ? 1 : -1;
|
|
51
|
+
return 0;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function sleepWhile(condition, interval = 100) {
|
|
55
|
+
while (await condition()) await new Promise((resolve) => setTimeout(resolve, interval));
|
|
271
56
|
}
|
|
272
57
|
function contrast(background) {
|
|
273
|
-
const
|
|
274
|
-
if (!
|
|
275
|
-
const [
|
|
276
|
-
|
|
277
|
-
return luminance > 0.5 ? "black" : "white";
|
|
58
|
+
const parts = background == null ? void 0 : background.match(background.length >= 6 ? /[0-9a-fA-F]{2}/g : /[0-9a-fA-F]/g);
|
|
59
|
+
if (!parts || parts.length < 3) return "black";
|
|
60
|
+
const [red, green, blue] = parts.map((hex) => parseInt(hex.length === 1 ? hex + hex : hex, 16));
|
|
61
|
+
return (0.299 * red + 0.587 * green + 0.114 * blue) / 255 > 0.5 ? "black" : "white";
|
|
278
62
|
}
|
|
279
|
-
const LETTER_LIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
280
|
-
const NUMBER_LIST = "0123456789";
|
|
281
|
-
const SYMBOL_LIST = "~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/";
|
|
282
63
|
function randomStringBuilder(length, letters = false, numbers = false, symbols = false) {
|
|
64
|
+
const LETTER_LIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
65
|
+
const NUMBER_LIST = "0123456789";
|
|
66
|
+
const SYMBOL_LIST = "~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/";
|
|
283
67
|
if (!letters && !numbers && !symbols) throw new Error("Must enable at least one: letters, numbers, symbols");
|
|
284
68
|
return Array(length).fill(null).map(() => {
|
|
285
|
-
let
|
|
69
|
+
let character;
|
|
286
70
|
do {
|
|
287
71
|
const type = ~~(Math.random() * 3);
|
|
288
|
-
if (letters && type == 0)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
c = SYMBOL_LIST[~~(Math.random() * SYMBOL_LIST.length)];
|
|
294
|
-
}
|
|
295
|
-
} while (!c);
|
|
296
|
-
return c;
|
|
72
|
+
if (letters && type == 0) character = LETTER_LIST[~~(Math.random() * LETTER_LIST.length)];
|
|
73
|
+
else if (numbers && type == 1) character = NUMBER_LIST[~~(Math.random() * NUMBER_LIST.length)];
|
|
74
|
+
else if (symbols && type == 2) character = SYMBOL_LIST[~~(Math.random() * SYMBOL_LIST.length)];
|
|
75
|
+
} while (!character);
|
|
76
|
+
return character;
|
|
297
77
|
}).join("");
|
|
298
78
|
}
|
|
299
|
-
class PromiseProgress extends Promise {
|
|
300
|
-
constructor(executor) {
|
|
301
|
-
super((resolve, reject) => executor(
|
|
302
|
-
(value) => resolve(value),
|
|
303
|
-
(reason) => reject(reason),
|
|
304
|
-
(progress) => this.progress = progress
|
|
305
|
-
));
|
|
306
|
-
__publicField2(this, "listeners", []);
|
|
307
|
-
__publicField2(this, "_progress", 0);
|
|
308
|
-
}
|
|
309
|
-
get progress() {
|
|
310
|
-
return this._progress;
|
|
311
|
-
}
|
|
312
|
-
set progress(p) {
|
|
313
|
-
if (p == this._progress) return;
|
|
314
|
-
this._progress = p;
|
|
315
|
-
this.listeners.forEach((l) => l(p));
|
|
316
|
-
}
|
|
317
|
-
static from(promise) {
|
|
318
|
-
if (promise instanceof PromiseProgress) return promise;
|
|
319
|
-
return new PromiseProgress((res, rej) => promise.then((...args) => res(...args)).catch((...args) => rej(...args)));
|
|
320
|
-
}
|
|
321
|
-
from(promise) {
|
|
322
|
-
const newPromise = PromiseProgress.from(promise);
|
|
323
|
-
this.onProgress((p) => newPromise.progress = p);
|
|
324
|
-
return newPromise;
|
|
325
|
-
}
|
|
326
|
-
onProgress(callback) {
|
|
327
|
-
this.listeners.push(callback);
|
|
328
|
-
return this;
|
|
329
|
-
}
|
|
330
|
-
then(res, rej) {
|
|
331
|
-
const resp = super.then(res, rej);
|
|
332
|
-
return this.from(resp);
|
|
333
|
-
}
|
|
334
|
-
catch(rej) {
|
|
335
|
-
return this.from(super.catch(rej));
|
|
336
|
-
}
|
|
337
|
-
finally(res) {
|
|
338
|
-
return this.from(super.finally(res));
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
function sleep(ms) {
|
|
342
|
-
return new Promise((res) => setTimeout(res, ms));
|
|
343
|
-
}
|
|
344
|
-
async function sleepWhile(fn2, checkInterval = 100) {
|
|
345
|
-
while (await fn2()) await sleep(checkInterval);
|
|
346
|
-
}
|
|
347
|
-
class TypedEmitter {
|
|
348
|
-
constructor() {
|
|
349
|
-
__publicField2(this, "listeners", {});
|
|
350
|
-
}
|
|
351
|
-
static emit(event, ...args) {
|
|
352
|
-
(this.listeners["*"] || []).forEach((l) => l(event, ...args));
|
|
353
|
-
(this.listeners[event.toString()] || []).forEach((l) => l(...args));
|
|
354
|
-
}
|
|
355
|
-
static off(event, listener) {
|
|
356
|
-
const e = event.toString();
|
|
357
|
-
this.listeners[e] = (this.listeners[e] || []).filter((l) => l != listener);
|
|
358
|
-
}
|
|
359
|
-
static on(event, listener) {
|
|
360
|
-
var _a;
|
|
361
|
-
const e = event.toString();
|
|
362
|
-
if (!this.listeners[e]) this.listeners[e] = [];
|
|
363
|
-
(_a = this.listeners[e]) == null ? void 0 : _a.push(listener);
|
|
364
|
-
return () => this.off(event, listener);
|
|
365
|
-
}
|
|
366
|
-
static once(event, listener) {
|
|
367
|
-
return new Promise((res) => {
|
|
368
|
-
const unsubscribe = this.on(event, (...args) => {
|
|
369
|
-
res(args.length == 1 ? args[0] : args);
|
|
370
|
-
if (listener) listener(...args);
|
|
371
|
-
unsubscribe();
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
emit(event, ...args) {
|
|
376
|
-
(this.listeners["*"] || []).forEach((l) => l(event, ...args));
|
|
377
|
-
(this.listeners[event] || []).forEach((l) => l(...args));
|
|
378
|
-
}
|
|
379
|
-
off(event, listener) {
|
|
380
|
-
this.listeners[event] = (this.listeners[event] || []).filter((l) => l != listener);
|
|
381
|
-
}
|
|
382
|
-
on(event, listener) {
|
|
383
|
-
var _a;
|
|
384
|
-
if (!this.listeners[event]) this.listeners[event] = [];
|
|
385
|
-
(_a = this.listeners[event]) == null ? void 0 : _a.push(listener);
|
|
386
|
-
return () => this.off(event, listener);
|
|
387
|
-
}
|
|
388
|
-
once(event, listener) {
|
|
389
|
-
return new Promise((res) => {
|
|
390
|
-
const unsubscribe = this.on(event, (...args) => {
|
|
391
|
-
res(args.length == 1 ? args[0] : args);
|
|
392
|
-
if (listener) listener(...args);
|
|
393
|
-
unsubscribe();
|
|
394
|
-
});
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
__publicField2(TypedEmitter, "listeners", {});
|
|
399
79
|
class CustomError extends Error {
|
|
400
80
|
constructor(message, code) {
|
|
401
81
|
super(message);
|
|
402
|
-
|
|
82
|
+
__publicField(this, "_code");
|
|
403
83
|
if (code != null) this._code = code;
|
|
404
84
|
}
|
|
405
85
|
get code() {
|
|
406
86
|
return this._code || this.constructor.code;
|
|
407
87
|
}
|
|
408
|
-
set code(
|
|
409
|
-
this._code =
|
|
410
|
-
}
|
|
411
|
-
static from(err) {
|
|
412
|
-
const code = Number(err.statusCode) ?? Number(err.code);
|
|
413
|
-
const newErr = new this(err.message || err.toString());
|
|
414
|
-
return Object.assign(newErr, {
|
|
415
|
-
stack: err.stack,
|
|
416
|
-
...err,
|
|
417
|
-
code: code ?? void 0
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
static instanceof(err) {
|
|
421
|
-
return err.constructor.code != void 0;
|
|
88
|
+
set code(code) {
|
|
89
|
+
this._code = code;
|
|
422
90
|
}
|
|
423
91
|
toString() {
|
|
424
92
|
return this.message || super.toString();
|
|
425
93
|
}
|
|
426
94
|
}
|
|
427
|
-
|
|
95
|
+
__publicField(CustomError, "code", 500);
|
|
428
96
|
class BadRequestError extends CustomError {
|
|
429
97
|
constructor(message = "Bad Request") {
|
|
430
98
|
super(message);
|
|
431
99
|
}
|
|
432
|
-
static instanceof(err) {
|
|
433
|
-
return err.constructor.code == this.code;
|
|
434
|
-
}
|
|
435
100
|
}
|
|
436
|
-
|
|
101
|
+
__publicField(BadRequestError, "code", 400);
|
|
437
102
|
class UnauthorizedError extends CustomError {
|
|
438
103
|
constructor(message = "Unauthorized") {
|
|
439
104
|
super(message);
|
|
440
105
|
}
|
|
441
|
-
static instanceof(err) {
|
|
442
|
-
return err.constructor.code == this.code;
|
|
443
|
-
}
|
|
444
106
|
}
|
|
445
|
-
|
|
107
|
+
__publicField(UnauthorizedError, "code", 401);
|
|
446
108
|
class PaymentRequiredError extends CustomError {
|
|
447
109
|
constructor(message = "Payment Required") {
|
|
448
110
|
super(message);
|
|
449
111
|
}
|
|
450
|
-
static instanceof(err) {
|
|
451
|
-
return err.constructor.code == this.code;
|
|
452
|
-
}
|
|
453
112
|
}
|
|
454
|
-
|
|
113
|
+
__publicField(PaymentRequiredError, "code", 402);
|
|
455
114
|
class ForbiddenError extends CustomError {
|
|
456
115
|
constructor(message = "Forbidden") {
|
|
457
116
|
super(message);
|
|
458
117
|
}
|
|
459
|
-
static instanceof(err) {
|
|
460
|
-
return err.constructor.code == this.code;
|
|
461
|
-
}
|
|
462
118
|
}
|
|
463
|
-
|
|
119
|
+
__publicField(ForbiddenError, "code", 403);
|
|
464
120
|
class NotFoundError extends CustomError {
|
|
465
121
|
constructor(message = "Not Found") {
|
|
466
122
|
super(message);
|
|
467
123
|
}
|
|
468
|
-
static instanceof(err) {
|
|
469
|
-
return err.constructor.code == this.code;
|
|
470
|
-
}
|
|
471
124
|
}
|
|
472
|
-
|
|
125
|
+
__publicField(NotFoundError, "code", 404);
|
|
473
126
|
class MethodNotAllowedError extends CustomError {
|
|
474
127
|
constructor(message = "Method Not Allowed") {
|
|
475
128
|
super(message);
|
|
476
129
|
}
|
|
477
|
-
static instanceof(err) {
|
|
478
|
-
return err.constructor.code == this.code;
|
|
479
|
-
}
|
|
480
130
|
}
|
|
481
|
-
|
|
131
|
+
__publicField(MethodNotAllowedError, "code", 405);
|
|
482
132
|
class NotAcceptableError extends CustomError {
|
|
483
133
|
constructor(message = "Not Acceptable") {
|
|
484
134
|
super(message);
|
|
485
135
|
}
|
|
486
|
-
static instanceof(err) {
|
|
487
|
-
return err.constructor.code == this.code;
|
|
488
|
-
}
|
|
489
136
|
}
|
|
490
|
-
|
|
137
|
+
__publicField(NotAcceptableError, "code", 406);
|
|
491
138
|
class InternalServerError extends CustomError {
|
|
492
139
|
constructor(message = "Internal Server Error") {
|
|
493
140
|
super(message);
|
|
494
141
|
}
|
|
495
|
-
static instanceof(err) {
|
|
496
|
-
return err.constructor.code == this.code;
|
|
497
|
-
}
|
|
498
142
|
}
|
|
499
|
-
|
|
143
|
+
__publicField(InternalServerError, "code", 500);
|
|
500
144
|
class NotImplementedError extends CustomError {
|
|
501
145
|
constructor(message = "Not Implemented") {
|
|
502
146
|
super(message);
|
|
503
147
|
}
|
|
504
|
-
static instanceof(err) {
|
|
505
|
-
return err.constructor.code == this.code;
|
|
506
|
-
}
|
|
507
148
|
}
|
|
508
|
-
|
|
149
|
+
__publicField(NotImplementedError, "code", 501);
|
|
509
150
|
class BadGatewayError extends CustomError {
|
|
510
151
|
constructor(message = "Bad Gateway") {
|
|
511
152
|
super(message);
|
|
512
153
|
}
|
|
513
|
-
static instanceof(err) {
|
|
514
|
-
return err.constructor.code == this.code;
|
|
515
|
-
}
|
|
516
154
|
}
|
|
517
|
-
|
|
155
|
+
__publicField(BadGatewayError, "code", 502);
|
|
518
156
|
class ServiceUnavailableError extends CustomError {
|
|
519
157
|
constructor(message = "Service Unavailable") {
|
|
520
158
|
super(message);
|
|
521
159
|
}
|
|
522
|
-
static instanceof(err) {
|
|
523
|
-
return err.constructor.code == this.code;
|
|
524
|
-
}
|
|
525
160
|
}
|
|
526
|
-
|
|
161
|
+
__publicField(ServiceUnavailableError, "code", 503);
|
|
527
162
|
class GatewayTimeoutError extends CustomError {
|
|
528
163
|
constructor(message = "Gateway Timeout") {
|
|
529
164
|
super(message);
|
|
530
165
|
}
|
|
531
|
-
static instanceof(err) {
|
|
532
|
-
return err.constructor.code == this.code;
|
|
533
|
-
}
|
|
534
166
|
}
|
|
535
|
-
|
|
167
|
+
__publicField(GatewayTimeoutError, "code", 504);
|
|
536
168
|
function errorFromCode(code, message) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
return new InternalServerError(message);
|
|
554
|
-
case 501:
|
|
555
|
-
return new NotImplementedError(message);
|
|
556
|
-
case 502:
|
|
557
|
-
return new BadGatewayError(message);
|
|
558
|
-
case 503:
|
|
559
|
-
return new ServiceUnavailableError(message);
|
|
560
|
-
case 504:
|
|
561
|
-
return new GatewayTimeoutError(message);
|
|
562
|
-
default:
|
|
563
|
-
return new CustomError(message, code);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
class HttpResponse extends Response {
|
|
567
|
-
constructor(resp, stream) {
|
|
568
|
-
const body = [204, 205, 304].includes(resp.status) ? null : stream;
|
|
569
|
-
super(body, {
|
|
570
|
-
headers: resp.headers,
|
|
571
|
-
status: resp.status,
|
|
572
|
-
statusText: resp.statusText
|
|
573
|
-
});
|
|
574
|
-
__publicField2(this, "data");
|
|
575
|
-
__publicField2(this, "ok");
|
|
576
|
-
__publicField2(this, "redirected");
|
|
577
|
-
__publicField2(this, "type");
|
|
578
|
-
__publicField2(this, "url");
|
|
579
|
-
this.ok = resp.ok;
|
|
580
|
-
this.redirected = resp.redirected;
|
|
581
|
-
this.type = resp.type;
|
|
582
|
-
this.url = resp.url;
|
|
583
|
-
}
|
|
169
|
+
const errors = {
|
|
170
|
+
400: BadRequestError,
|
|
171
|
+
401: UnauthorizedError,
|
|
172
|
+
402: PaymentRequiredError,
|
|
173
|
+
403: ForbiddenError,
|
|
174
|
+
404: NotFoundError,
|
|
175
|
+
405: MethodNotAllowedError,
|
|
176
|
+
406: NotAcceptableError,
|
|
177
|
+
500: InternalServerError,
|
|
178
|
+
501: NotImplementedError,
|
|
179
|
+
502: BadGatewayError,
|
|
180
|
+
503: ServiceUnavailableError,
|
|
181
|
+
504: GatewayTimeoutError
|
|
182
|
+
};
|
|
183
|
+
const ErrorType = errors[code];
|
|
184
|
+
return ErrorType ? new ErrorType(message) : new CustomError(message, code);
|
|
584
185
|
}
|
|
585
|
-
const _Http = class _Http2 {
|
|
586
|
-
constructor(defaults = {}) {
|
|
587
|
-
__publicField2(this, "interceptors", {});
|
|
588
|
-
__publicField2(this, "headers", {});
|
|
589
|
-
__publicField2(this, "url");
|
|
590
|
-
this.url = defaults.url ?? null;
|
|
591
|
-
this.headers = defaults.headers || {};
|
|
592
|
-
if (defaults.interceptors) {
|
|
593
|
-
defaults.interceptors.forEach((i) => _Http2.addInterceptor(i));
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
static addInterceptor(fn2) {
|
|
597
|
-
const key = Object.keys(_Http2.interceptors).length.toString();
|
|
598
|
-
_Http2.interceptors[key] = fn2;
|
|
599
|
-
return () => {
|
|
600
|
-
_Http2.interceptors[key] = null;
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
addInterceptor(fn2) {
|
|
604
|
-
const key = Object.keys(this.interceptors).length.toString();
|
|
605
|
-
this.interceptors[key] = fn2;
|
|
606
|
-
return () => {
|
|
607
|
-
this.interceptors[key] = null;
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
request(opts = {}) {
|
|
611
|
-
var _a;
|
|
612
|
-
if (!this.url && !opts.url) throw new Error("URL needs to be set");
|
|
613
|
-
let url = ((_a = opts.url) == null ? void 0 : _a.startsWith("http")) ? opts.url : (this.url || "") + (opts.url || "");
|
|
614
|
-
url = url.replaceAll(/([^:]\/)\/+/g, "$1");
|
|
615
|
-
if (opts.fragment) url.includes("#") ? url.replace(/#.*(\?|\n)/g, (match, arg1) => `#${opts.fragment}${arg1}`) : `${url}#${opts.fragment}`;
|
|
616
|
-
if (opts.query) {
|
|
617
|
-
const q = Array.isArray(opts.query) ? opts.query : Object.keys(opts.query).map((k) => ({ key: k, value: opts.query[k] }));
|
|
618
|
-
url += (url.includes("?") ? "&" : "?") + q.map((q2) => `${q2.key}=${q2.value}`).join("&");
|
|
619
|
-
}
|
|
620
|
-
const headers = clean({
|
|
621
|
-
"Content-Type": !opts.body ? void 0 : opts.body instanceof FormData ? "multipart/form-data" : "application/json",
|
|
622
|
-
..._Http2.headers,
|
|
623
|
-
...this.headers,
|
|
624
|
-
...opts.headers
|
|
625
|
-
});
|
|
626
|
-
if (typeof opts.body == "object" && opts.body != null && headers["Content-Type"] == "application/json")
|
|
627
|
-
opts.body = JSON.stringify(opts.body);
|
|
628
|
-
return new PromiseProgress((res, rej, prog) => {
|
|
629
|
-
try {
|
|
630
|
-
fetch(url, {
|
|
631
|
-
headers,
|
|
632
|
-
method: opts.method || (opts.body ? "POST" : "GET"),
|
|
633
|
-
body: opts.body
|
|
634
|
-
}).then(async (resp) => {
|
|
635
|
-
var _a2, _b;
|
|
636
|
-
for (let fn2 of [...Object.values(_Http2.interceptors), ...Object.values(this.interceptors)]) {
|
|
637
|
-
await new Promise((res2) => fn2(resp, () => res2()));
|
|
638
|
-
}
|
|
639
|
-
const contentLength = resp.headers.get("Content-Length");
|
|
640
|
-
const total = contentLength ? parseInt(contentLength, 10) : 0;
|
|
641
|
-
let loaded = 0;
|
|
642
|
-
const reader = (_a2 = resp.body) == null ? void 0 : _a2.getReader();
|
|
643
|
-
const stream = new ReadableStream({
|
|
644
|
-
start(controller) {
|
|
645
|
-
function push() {
|
|
646
|
-
reader == null ? void 0 : reader.read().then((event) => {
|
|
647
|
-
if (event.done) return controller.close();
|
|
648
|
-
loaded += event.value.byteLength;
|
|
649
|
-
prog(loaded / total);
|
|
650
|
-
controller.enqueue(event.value);
|
|
651
|
-
push();
|
|
652
|
-
}).catch((error) => controller.error(error));
|
|
653
|
-
}
|
|
654
|
-
push();
|
|
655
|
-
}
|
|
656
|
-
});
|
|
657
|
-
resp = new HttpResponse(resp, stream);
|
|
658
|
-
if (opts.decode !== false) {
|
|
659
|
-
const content = (_b = resp.headers.get("Content-Type")) == null ? void 0 : _b.toLowerCase();
|
|
660
|
-
if (content == null ? void 0 : content.includes("form")) resp.data = await resp.formData();
|
|
661
|
-
else if (content == null ? void 0 : content.includes("json")) resp.data = await resp.json();
|
|
662
|
-
else if (content == null ? void 0 : content.includes("text")) resp.data = await resp.text();
|
|
663
|
-
else if (content == null ? void 0 : content.includes("application")) resp.data = await resp.blob();
|
|
664
|
-
}
|
|
665
|
-
if (resp.ok) res(resp);
|
|
666
|
-
else rej(resp);
|
|
667
|
-
}).catch((err) => rej(err));
|
|
668
|
-
} catch (err) {
|
|
669
|
-
rej(err);
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
};
|
|
674
|
-
__publicField2(_Http, "interceptors", {});
|
|
675
|
-
__publicField2(_Http, "headers", {});
|
|
676
186
|
function decodeJwt(token) {
|
|
677
187
|
const base64 = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
678
|
-
return JSONAttemptParse(decodeURIComponent(atob(base64).split("").map(
|
|
679
|
-
|
|
680
|
-
|
|
188
|
+
return JSONAttemptParse(decodeURIComponent(atob(base64).split("").map(
|
|
189
|
+
(character) => "%" + ("00" + character.charCodeAt(0).toString(16)).slice(-2)
|
|
190
|
+
).join("")));
|
|
681
191
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
console.debug(CliForeground.LIGHT_GREY + str + CliEffects.CLEAR);
|
|
706
|
-
}
|
|
707
|
-
log(...args) {
|
|
708
|
-
if (_Logger2.LOG_LEVEL < 3) return;
|
|
709
|
-
const str = this.format(...args);
|
|
710
|
-
_Logger2.emit(3, str);
|
|
711
|
-
console.log(CliEffects.CLEAR + str);
|
|
712
|
-
}
|
|
713
|
-
info(...args) {
|
|
714
|
-
if (_Logger2.LOG_LEVEL < 2) return;
|
|
715
|
-
const str = this.format(...args);
|
|
716
|
-
_Logger2.emit(2, str);
|
|
717
|
-
console.info(CliForeground.BLUE + str + CliEffects.CLEAR);
|
|
718
|
-
}
|
|
719
|
-
warn(...args) {
|
|
720
|
-
if (_Logger2.LOG_LEVEL < 1) return;
|
|
721
|
-
const str = this.format(...args);
|
|
722
|
-
_Logger2.emit(1, str);
|
|
723
|
-
console.warn(CliForeground.YELLOW + str + CliEffects.CLEAR);
|
|
724
|
-
}
|
|
725
|
-
error(...args) {
|
|
726
|
-
if (_Logger2.LOG_LEVEL < 0) return;
|
|
727
|
-
const str = this.format(...args);
|
|
728
|
-
_Logger2.emit(0, str);
|
|
729
|
-
console.error(CliForeground.RED + str + CliEffects.CLEAR);
|
|
730
|
-
}
|
|
731
|
-
};
|
|
732
|
-
__publicField2(_Logger, "LOG_LEVEL", 4);
|
|
733
|
-
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
734
|
-
var dist = {};
|
|
735
|
-
var persist$1 = {};
|
|
736
|
-
Object.defineProperty(persist$1, "__esModule", { value: true });
|
|
737
|
-
persist$1.persist = persist$1.Persist = void 0;
|
|
738
|
-
class Persist {
|
|
739
|
-
/**
|
|
740
|
-
* @param {string} key Primary key value will be stored under
|
|
741
|
-
* @param {PersistOptions<T>} options Configure using {@link PersistOptions}
|
|
742
|
-
*/
|
|
743
|
-
constructor(key, options = {}) {
|
|
744
|
-
__publicField2(this, "key");
|
|
745
|
-
__publicField2(this, "options");
|
|
746
|
-
__publicField2(this, "storage");
|
|
747
|
-
__publicField2(this, "watches", {});
|
|
748
|
-
__publicField2(this, "_value");
|
|
749
|
-
this.key = key;
|
|
750
|
-
this.options = options;
|
|
751
|
-
this.storage = options.storage || localStorage;
|
|
752
|
-
this.load();
|
|
753
|
-
}
|
|
754
|
-
/** Current value or default if undefined */
|
|
755
|
-
get value() {
|
|
756
|
-
var _a;
|
|
757
|
-
return this._value !== void 0 ? this._value : (_a = this.options) == null ? void 0 : _a.default;
|
|
758
|
-
}
|
|
759
|
-
/** Set value with proxy object wrapper to sync future changes */
|
|
760
|
-
set value(v) {
|
|
761
|
-
if (v == null || typeof v != "object")
|
|
762
|
-
this._value = v;
|
|
763
|
-
else
|
|
764
|
-
this._value = new Proxy(v, {
|
|
765
|
-
get: (target, p) => {
|
|
766
|
-
const f = typeof target[p] == "function";
|
|
767
|
-
if (!f)
|
|
768
|
-
return target[p];
|
|
769
|
-
return (...args) => {
|
|
770
|
-
const value = target[p](...args);
|
|
771
|
-
this.save();
|
|
772
|
-
return value;
|
|
773
|
-
};
|
|
774
|
-
},
|
|
775
|
-
set: (target, p, newValue) => {
|
|
776
|
-
target[p] = newValue;
|
|
777
|
-
this.save();
|
|
778
|
-
return true;
|
|
192
|
+
class Database {
|
|
193
|
+
constructor(database, tables, version2) {
|
|
194
|
+
__publicField(this, "connection");
|
|
195
|
+
__publicField(this, "tables");
|
|
196
|
+
this.database = database;
|
|
197
|
+
this.version = version2;
|
|
198
|
+
this.tables = tables.map((table) => typeof table === "object" ? { ...table, name: table.name.toString() } : { name: table.toString() });
|
|
199
|
+
this.connection = new Promise((resolve, reject) => {
|
|
200
|
+
const request = indexedDB.open(this.database, this.version);
|
|
201
|
+
const requested = new Set(this.tables.map((table) => table.name));
|
|
202
|
+
request.onerror = () => reject(request.error);
|
|
203
|
+
request.onsuccess = () => {
|
|
204
|
+
const db = request.result;
|
|
205
|
+
const existing = new Set(Array.from(db.objectStoreNames));
|
|
206
|
+
if ([...requested].some((name) => !existing.has(name)) || [...existing].some((name) => !requested.has(name))) {
|
|
207
|
+
db.close();
|
|
208
|
+
const upgraded = new Database(this.database, this.tables, db.version + 1);
|
|
209
|
+
this.version = upgraded.version;
|
|
210
|
+
this.connection = upgraded.connection;
|
|
211
|
+
this.connection.then(resolve, reject);
|
|
212
|
+
} else {
|
|
213
|
+
this.version = db.version;
|
|
214
|
+
resolve(db);
|
|
779
215
|
}
|
|
780
|
-
}
|
|
781
|
-
|
|
216
|
+
};
|
|
217
|
+
request.onupgradeneeded = () => {
|
|
218
|
+
const db = request.result;
|
|
219
|
+
const existing = new Set(Array.from(db.objectStoreNames));
|
|
220
|
+
existing.forEach((name) => {
|
|
221
|
+
if (!requested.has(name)) db.deleteObjectStore(name);
|
|
222
|
+
});
|
|
223
|
+
requested.forEach((name) => {
|
|
224
|
+
if (!existing.has(name)) db.createObjectStore(name);
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
});
|
|
782
228
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
Object.values(this.watches).forEach((watch) => watch(value));
|
|
229
|
+
includes(name) {
|
|
230
|
+
return this.tables.some((table) => table.name === name.toString());
|
|
786
231
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
this.storage.removeItem(this.key);
|
|
790
|
-
}
|
|
791
|
-
/** Save current value to storage */
|
|
792
|
-
save() {
|
|
793
|
-
if (this._value === void 0)
|
|
794
|
-
this.clear();
|
|
795
|
-
else
|
|
796
|
-
this.storage.setItem(this.key, JSON.stringify(this._value));
|
|
797
|
-
this.notify(this.value);
|
|
798
|
-
}
|
|
799
|
-
/** Load value from storage */
|
|
800
|
-
load() {
|
|
801
|
-
if (this.storage[this.key] != void 0) {
|
|
802
|
-
let value = JSON.parse(this.storage.getItem(this.key));
|
|
803
|
-
if (value != null && typeof value == "object" && this.options.type)
|
|
804
|
-
value.__proto__ = this.options.type.prototype;
|
|
805
|
-
this.value = value;
|
|
806
|
-
} else
|
|
807
|
-
this.value = this.options.default || void 0;
|
|
232
|
+
table(name) {
|
|
233
|
+
return new Table(this, name.toString());
|
|
808
234
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
*/
|
|
815
|
-
watch(fn2) {
|
|
816
|
-
const index = Object.keys(this.watches).length;
|
|
817
|
-
this.watches[index] = fn2;
|
|
818
|
-
return () => {
|
|
819
|
-
delete this.watches[index];
|
|
820
|
-
};
|
|
235
|
+
}
|
|
236
|
+
class Table {
|
|
237
|
+
constructor(database, name) {
|
|
238
|
+
this.database = database;
|
|
239
|
+
this.name = name;
|
|
821
240
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
241
|
+
async tx(operation, readonly = false) {
|
|
242
|
+
const db = await this.database.connection;
|
|
243
|
+
return new Promise((resolve, reject) => {
|
|
244
|
+
const request = operation(db.transaction(this.name, readonly ? "readonly" : "readwrite").objectStore(this.name));
|
|
245
|
+
request.onsuccess = () => resolve(request.result);
|
|
246
|
+
request.onerror = () => reject(request.error);
|
|
247
|
+
});
|
|
829
248
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
*
|
|
833
|
-
* @returns {T} Current value
|
|
834
|
-
*/
|
|
835
|
-
valueOf() {
|
|
836
|
-
return this.value;
|
|
249
|
+
add(value, key) {
|
|
250
|
+
return this.tx((store) => store.add(value, key));
|
|
837
251
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
function persist(options) {
|
|
841
|
-
return (target, prop) => {
|
|
842
|
-
const key = (options == null ? void 0 : options.key) || `${target.constructor.name}.${prop.toString()}`;
|
|
843
|
-
const wrapper = new Persist(key, options);
|
|
844
|
-
Object.defineProperty(target, prop, {
|
|
845
|
-
get: function() {
|
|
846
|
-
return wrapper.value;
|
|
847
|
-
},
|
|
848
|
-
set: function(v) {
|
|
849
|
-
wrapper.value = v;
|
|
850
|
-
}
|
|
851
|
-
});
|
|
852
|
-
};
|
|
853
|
-
}
|
|
854
|
-
persist$1.persist = persist;
|
|
855
|
-
var memoryStorage = {};
|
|
856
|
-
Object.defineProperty(memoryStorage, "__esModule", { value: true });
|
|
857
|
-
memoryStorage.MemoryStorage = void 0;
|
|
858
|
-
class MemoryStorage {
|
|
859
|
-
get length() {
|
|
860
|
-
return Object.keys(this).length;
|
|
252
|
+
put(key, value) {
|
|
253
|
+
return this.tx((store) => store.put(value, key));
|
|
861
254
|
}
|
|
862
|
-
|
|
863
|
-
|
|
255
|
+
get(key) {
|
|
256
|
+
return this.tx((store) => store.get(key), true);
|
|
864
257
|
}
|
|
865
|
-
|
|
866
|
-
return this
|
|
258
|
+
getAll() {
|
|
259
|
+
return this.tx((store) => store.getAll(), true);
|
|
867
260
|
}
|
|
868
|
-
|
|
869
|
-
return
|
|
261
|
+
getAllKeys() {
|
|
262
|
+
return this.tx((store) => store.getAllKeys(), true);
|
|
870
263
|
}
|
|
871
|
-
|
|
872
|
-
|
|
264
|
+
delete(key) {
|
|
265
|
+
return this.tx((store) => store.delete(key));
|
|
266
|
+
}
|
|
267
|
+
clear() {
|
|
268
|
+
return this.tx((store) => store.clear());
|
|
873
269
|
}
|
|
874
|
-
|
|
875
|
-
this
|
|
270
|
+
count() {
|
|
271
|
+
return this.tx((store) => store.count(), true);
|
|
876
272
|
}
|
|
877
273
|
}
|
|
878
|
-
memoryStorage.MemoryStorage = MemoryStorage;
|
|
879
|
-
(function(exports3) {
|
|
880
|
-
var __createBinding = commonjsGlobal && commonjsGlobal.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
881
|
-
if (k2 === void 0) k2 = k;
|
|
882
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
883
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
884
|
-
desc = { enumerable: true, get: function() {
|
|
885
|
-
return m[k];
|
|
886
|
-
} };
|
|
887
|
-
}
|
|
888
|
-
Object.defineProperty(o, k2, desc);
|
|
889
|
-
} : function(o, m, k, k2) {
|
|
890
|
-
if (k2 === void 0) k2 = k;
|
|
891
|
-
o[k2] = m[k];
|
|
892
|
-
});
|
|
893
|
-
var __exportStar = commonjsGlobal && commonjsGlobal.__exportStar || function(m, exports22) {
|
|
894
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports22, p)) __createBinding(exports22, m, p);
|
|
895
|
-
};
|
|
896
|
-
Object.defineProperty(exports3, "__esModule", { value: true });
|
|
897
|
-
__exportStar(persist$1, exports3);
|
|
898
|
-
__exportStar(memoryStorage, exports3);
|
|
899
|
-
})(dist);
|
|
900
274
|
var extendStatics = function(d, b) {
|
|
901
275
|
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
|
|
902
276
|
d2.__proto__ = b2;
|
|
@@ -1751,6 +1125,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
1751
1125
|
__publicField(this, "alert");
|
|
1752
1126
|
__publicField(this, "button");
|
|
1753
1127
|
__publicField(this, "form");
|
|
1128
|
+
__publicField(this, "forgotLink");
|
|
1754
1129
|
__publicField(this, "password");
|
|
1755
1130
|
__publicField(this, "persist");
|
|
1756
1131
|
__publicField(this, "username");
|
|
@@ -1779,8 +1154,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
1779
1154
|
this.password = document.querySelector('#datalynk-login-form input[name="password"]');
|
|
1780
1155
|
this.persist = document.querySelector('#datalynk-login-form input[name="persist"]');
|
|
1781
1156
|
this.username = document.querySelector('#datalynk-login-form input[name="username"]');
|
|
1157
|
+
this.forgotLink = document.querySelector("#datalynk-login-forgot");
|
|
1782
1158
|
if (this.options.persist === false) this.persist.parentElement.remove();
|
|
1783
1159
|
this.form.onsubmit = (event) => this.login(event);
|
|
1160
|
+
this.forgotLink.onclick = (event) => this.forgotPassword(event);
|
|
1161
|
+
const toggleForgotVisibility = () => this.forgotLink.classList.toggle("hidden", !this.username.value.trim());
|
|
1162
|
+
this.username.addEventListener("input", toggleForgotVisibility);
|
|
1163
|
+
const passwordToggle = document.querySelector("#datalynk-password-toggle");
|
|
1164
|
+
if (passwordToggle) passwordToggle.onclick = () => this.password.type = this.password.type === "password" ? "text" : "password";
|
|
1784
1165
|
const pwaLink = document.querySelector("#pwa-install-link");
|
|
1785
1166
|
if (pwaLink) {
|
|
1786
1167
|
pwaLink.addEventListener("click", async (e) => {
|
|
@@ -1852,6 +1233,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
1852
1233
|
this.button.disabled = false;
|
|
1853
1234
|
});
|
|
1854
1235
|
}
|
|
1236
|
+
/** Forgot password link click event */
|
|
1237
|
+
forgotPassword(event) {
|
|
1238
|
+
event.preventDefault();
|
|
1239
|
+
const login = this.username.value.trim() || prompt("Enter your email or username") || "";
|
|
1240
|
+
if (!login) return;
|
|
1241
|
+
this.alert.classList.remove("hidden");
|
|
1242
|
+
this.alert.innerHTML = "Sending reset email...";
|
|
1243
|
+
return this.api.auth.resetRequest(login, "email").then(() => {
|
|
1244
|
+
this.alert.innerHTML = "If an account exists, a reset email has been sent.";
|
|
1245
|
+
}).catch((err) => {
|
|
1246
|
+
this.alert.innerHTML = err.message || "Unable to send reset email.";
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1855
1249
|
};
|
|
1856
1250
|
/** Dynamically create CSS style */
|
|
1857
1251
|
__publicField(_LoginPrompt, "css", (options) => `
|
|
@@ -2004,6 +1398,35 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2004
1398
|
text-decoration: none;
|
|
2005
1399
|
}
|
|
2006
1400
|
|
|
1401
|
+
#datalynk-login .login-forgot {
|
|
1402
|
+
display: block;
|
|
1403
|
+
text-align: left;
|
|
1404
|
+
margin-bottom: 0.75rem;
|
|
1405
|
+
color: var(--theme-text);
|
|
1406
|
+
font-size: 14px;
|
|
1407
|
+
text-decoration: none;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
#datalynk-login .login-forgot:hover {
|
|
1411
|
+
text-decoration: underline;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
#datalynk-login .password-wrapper {
|
|
1415
|
+
position: relative;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
#datalynk-login .password-toggle {
|
|
1419
|
+
position: absolute;
|
|
1420
|
+
right: 30px;
|
|
1421
|
+
top: 50%;
|
|
1422
|
+
transform: translateY(-50%);
|
|
1423
|
+
background: none;
|
|
1424
|
+
border: none;
|
|
1425
|
+
padding: 0;
|
|
1426
|
+
color: #333;
|
|
1427
|
+
cursor: pointer;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
2007
1430
|
#datalynk-login #pwa-install-link {
|
|
2008
1431
|
display: inline-flex;
|
|
2009
1432
|
align-items: center;
|
|
@@ -2061,7 +1484,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2061
1484
|
</div>
|
|
2062
1485
|
<div class="login-content">
|
|
2063
1486
|
<div class="login-body" style="max-width: 300px">
|
|
2064
|
-
<div id="datalynk-login-alert" class="hidden"></div>
|
|
2065
1487
|
<form id="datalynk-login-form">
|
|
2066
1488
|
<div>
|
|
2067
1489
|
<label for="username">Email or Username</label>
|
|
@@ -2070,12 +1492,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2070
1492
|
<br>
|
|
2071
1493
|
<div>
|
|
2072
1494
|
<label for="password">Password</label>
|
|
2073
|
-
<
|
|
1495
|
+
<div class="password-wrapper">
|
|
1496
|
+
<input id="password" name="password" type="password" autocomplete="current-password">
|
|
1497
|
+
<button type="button" id="datalynk-password-toggle" class="password-toggle" tabindex="-1">
|
|
1498
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zm0 12.5c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5zm0-8a3 3 0 100 6 3 3 0 000-6z"/></svg>
|
|
1499
|
+
</button>
|
|
1500
|
+
</div>
|
|
2074
1501
|
</div>
|
|
1502
|
+
<a href="#" id="datalynk-login-forgot" class="login-forgot hidden">Forgot Password?</a>
|
|
2075
1503
|
<br>
|
|
2076
1504
|
<label style="display: block; margin-bottom: 0.75rem;">
|
|
2077
1505
|
<input type="checkbox" name="persist" style="width: 20px"> Stay Logged In
|
|
2078
1506
|
</label>
|
|
1507
|
+
<div id="datalynk-login-alert" class="hidden"></div>
|
|
2079
1508
|
<button type="submit">Login</button>
|
|
2080
1509
|
</form>
|
|
2081
1510
|
</div>
|
|
@@ -2116,7 +1545,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2116
1545
|
this.api = api;
|
|
2117
1546
|
this.api.token$.subscribe(async (token) => {
|
|
2118
1547
|
if (token === void 0) return;
|
|
2119
|
-
|
|
1548
|
+
try {
|
|
1549
|
+
this.user = await this.current(token);
|
|
1550
|
+
} catch (error) {
|
|
1551
|
+
if (this.api.status === "unauthorized") this.user = null;
|
|
1552
|
+
else console.error("Unable to refresh the current Datalynk user", error);
|
|
1553
|
+
}
|
|
2120
1554
|
});
|
|
2121
1555
|
if ((_a = this.api.options.offline) == null ? void 0 : _a.length)
|
|
2122
1556
|
this.user$.pipe(filter((u) => u !== void 0)).subscribe((u) => localStorage.setItem("datalynk-user", JSON.stringify(u)));
|
|
@@ -2636,9 +2070,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2636
2070
|
document.head.append(style);
|
|
2637
2071
|
}
|
|
2638
2072
|
const iconUrl = this.resolvedIconUrl || "https://datalynk-client.primary.auxilium.world/logo.png";
|
|
2639
|
-
const
|
|
2640
|
-
|
|
2641
|
-
|
|
2073
|
+
const prompt2 = document.createElement("div");
|
|
2074
|
+
prompt2.classList.add("pwa-prompt");
|
|
2075
|
+
prompt2.innerHTML = `
|
|
2642
2076
|
<div class="pwa-prompt-header">
|
|
2643
2077
|
<img src="${iconUrl}" alt="Logo" />
|
|
2644
2078
|
<h1>Install ${this.api.options.name}</h1>
|
|
@@ -2654,14 +2088,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2654
2088
|
${this.nativeInstallPrompt ? `<button id="installPwaBtn">Install App</button>` : stepsHtml}
|
|
2655
2089
|
</div>
|
|
2656
2090
|
`;
|
|
2657
|
-
const closeBtn =
|
|
2091
|
+
const closeBtn = prompt2.querySelector(".pwa-prompt-close");
|
|
2658
2092
|
closeBtn.onclick = () => {
|
|
2659
2093
|
var _a2;
|
|
2660
2094
|
!!((_a2 = this.api.options.pwaSettings) == null ? void 0 : _a2.dismissExpiry) ? localStorage.setItem(storageKey, Date.now().toString()) : localStorage.removeItem(storageKey);
|
|
2661
|
-
|
|
2095
|
+
prompt2.remove();
|
|
2662
2096
|
};
|
|
2663
|
-
document.body.append(
|
|
2664
|
-
const img =
|
|
2097
|
+
document.body.append(prompt2);
|
|
2098
|
+
const img = prompt2.querySelector(".pwa-prompt-header img");
|
|
2665
2099
|
if (img) img.onerror = () => img.src = "https://datalynk-client.primary.auxilium.world/logo.png";
|
|
2666
2100
|
if (this.nativeInstallPrompt) this.bindInstallButton();
|
|
2667
2101
|
}
|
|
@@ -3249,7 +2683,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3249
2683
|
set cache(cache) {
|
|
3250
2684
|
this.cache$.next(cache);
|
|
3251
2685
|
}
|
|
3252
|
-
/**
|
|
2686
|
+
/**
|
|
2687
|
+
* Whether this slice has local IndexedDB/offline support enabled.
|
|
2688
|
+
*
|
|
2689
|
+
* Offline-enabled slices can fall back to their local cache when either the
|
|
2690
|
+
* browser loses network connectivity or the Datalynk client enters an
|
|
2691
|
+
* unavailable recovery state after a returned server/API failure.
|
|
2692
|
+
*/
|
|
3253
2693
|
get offlineEnabled() {
|
|
3254
2694
|
var _a;
|
|
3255
2695
|
return (_a = this.api.database) == null ? void 0 : _a.includes(this.slice.toString());
|
|
@@ -3262,7 +2702,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3262
2702
|
const onlineExec = call.exec.bind(call);
|
|
3263
2703
|
return async () => {
|
|
3264
2704
|
const offlineSupported = this.offlineEnabled && typeof navigator !== "undefined";
|
|
3265
|
-
const offlineNow = offlineSupported && !(navigator == null ? void 0 : navigator.onLine);
|
|
2705
|
+
const offlineNow = offlineSupported && (!this.api.online || !(navigator == null ? void 0 : navigator.onLine));
|
|
3266
2706
|
const offlineSim = async () => {
|
|
3267
2707
|
var _a, _b, _c;
|
|
3268
2708
|
const where = (row, condition) => {
|
|
@@ -3561,24 +3001,39 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3561
3001
|
return this.info;
|
|
3562
3002
|
}
|
|
3563
3003
|
/**
|
|
3564
|
-
* Synchronize cache with server
|
|
3004
|
+
* Synchronize the local slice cache with the server and subscribe to socket changes.
|
|
3005
|
+
*
|
|
3006
|
+
* For an offline-enabled slice, synchronization failures caused by network or
|
|
3007
|
+
* API unavailability are contained in the background rather than becoming
|
|
3008
|
+
* unhandled promise rejections. Local cached data remains usable while the
|
|
3009
|
+
* {@link Api} recovery loop determines when the failed API path works again.
|
|
3010
|
+
* When the client becomes online again, pending local changes are scheduled
|
|
3011
|
+
* for upload without overlapping push operations.
|
|
3012
|
+
*
|
|
3013
|
+
* Calling `sync(false)` unsubscribes from slice socket events.
|
|
3014
|
+
*
|
|
3565
3015
|
* @example
|
|
3566
3016
|
* ```ts
|
|
3567
3017
|
* const slice: Slice = new Slice<T>(Slices.Contact);
|
|
3568
|
-
* slice.sync()
|
|
3018
|
+
* const rows$ = slice.sync();
|
|
3019
|
+
* rows$?.subscribe((rows: T[]) => console.log(rows));
|
|
3569
3020
|
* ```
|
|
3570
|
-
* @param
|
|
3571
|
-
* @
|
|
3021
|
+
* @param on Enable or disable synchronization/socket events.
|
|
3022
|
+
* @returns The observable local cache when synchronization is enabled.
|
|
3572
3023
|
*/
|
|
3573
3024
|
sync(on = true) {
|
|
3574
3025
|
if (on) {
|
|
3575
|
-
this.pushChanges().then(() => this.select().rows().exec().then((rows) => {
|
|
3026
|
+
void this.pushChanges().then(() => this.select().rows().exec()).then((rows) => {
|
|
3576
3027
|
this.cache = rows;
|
|
3577
3028
|
this.loaded = true;
|
|
3578
|
-
}))
|
|
3029
|
+
}).catch((error) => {
|
|
3030
|
+
if (this.api.online) console.warn("Unable to synchronize offline slice", error);
|
|
3031
|
+
});
|
|
3579
3032
|
if (!this.unsubscribe) this.unsubscribe = this.api.socket.sliceEvents(this.slice, (event) => {
|
|
3580
3033
|
const ids = [...event.data.new, ...event.data.changed];
|
|
3581
|
-
this.select(ids).rows().exec().then((rows) => this.cache = [...this.cache.filter((c) => c.id != null && !ids.includes(c.id)), ...rows])
|
|
3034
|
+
void this.select(ids).rows().exec().then((rows) => this.cache = [...this.cache.filter((c) => c.id != null && !ids.includes(c.id)), ...rows]).catch((error) => {
|
|
3035
|
+
if (this.api.online) console.warn("Unable to refresh offline slice from socket event", error);
|
|
3036
|
+
});
|
|
3582
3037
|
this.cache = this.cache.filter((v) => v.id && !event.data.lost.includes(v.id));
|
|
3583
3038
|
});
|
|
3584
3039
|
return this.cache$;
|
|
@@ -3651,7 +3106,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3651
3106
|
this.options = options;
|
|
3652
3107
|
if (!options.url && options.url !== false) {
|
|
3653
3108
|
const origin = new URL(this.api.url).origin;
|
|
3654
|
-
this.options.url = origin.replace("http", "ws").replace(/:\d+/g, "") +
|
|
3109
|
+
this.options.url = origin.replace("http", "ws").replace(/:\d+/g, "") + `/s/`;
|
|
3655
3110
|
}
|
|
3656
3111
|
if (this.options.url !== false)
|
|
3657
3112
|
api.token$.pipe(filter((u) => u !== void 0), distinctUntilChanged()).subscribe(() => this.connect());
|
|
@@ -3774,7 +3229,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3774
3229
|
} });
|
|
3775
3230
|
}
|
|
3776
3231
|
}
|
|
3777
|
-
const version = "1.
|
|
3232
|
+
const version = "1.5.0";
|
|
3778
3233
|
class WebRtc {
|
|
3779
3234
|
constructor(api) {
|
|
3780
3235
|
__publicField(this, "ice");
|
|
@@ -4289,6 +3744,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4289
3744
|
};
|
|
4290
3745
|
__publicField(_Gps, "GPS_ACK_TIMEOUT_MS", 15e3);
|
|
4291
3746
|
let Gps = _Gps;
|
|
3747
|
+
class UnexpectedApiResponseError extends Error {
|
|
3748
|
+
constructor(response, body) {
|
|
3749
|
+
super(`Unexpected API response (${response.status} ${response.statusText})`);
|
|
3750
|
+
this.response = response;
|
|
3751
|
+
this.body = body;
|
|
3752
|
+
this.name = "UnexpectedApiResponseError";
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
4292
3755
|
const _Api = class _Api {
|
|
4293
3756
|
/**
|
|
4294
3757
|
* Connect to Datalynk & send requests
|
|
@@ -4312,6 +3775,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4312
3775
|
target: "version.php",
|
|
4313
3776
|
timeout: 6e4
|
|
4314
3777
|
});
|
|
3778
|
+
__publicField(this, "authenticationInvalid", false);
|
|
3779
|
+
__publicField(this, "tokenExpiryTimeout", null);
|
|
3780
|
+
/** Request-specific recovery after a server response proves an API call is broken. */
|
|
3781
|
+
__publicField(this, "recovery", null);
|
|
3782
|
+
/** Retry the failed request twice immediately, then this long after each failed recovery response. */
|
|
3783
|
+
__publicField(this, "recoveryRetryInterval", 3e4);
|
|
3784
|
+
__publicField(this, "recoveryImmediateRetries", 2);
|
|
4315
3785
|
/** LocalStorage key for persisting logins */
|
|
4316
3786
|
__publicField(this, "localStorageKey", "datalynk-token");
|
|
4317
3787
|
/** Pending requests cache */
|
|
@@ -4344,7 +3814,20 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4344
3814
|
/** Client library version */
|
|
4345
3815
|
__publicField(this, "version", version);
|
|
4346
3816
|
__publicField(this, "onlineOverride", false);
|
|
4347
|
-
__publicField(this, "
|
|
3817
|
+
__publicField(this, "initialOnline", typeof navigator == "undefined" || typeof navigator.onLine == "undefined" ? true : navigator.onLine);
|
|
3818
|
+
/**
|
|
3819
|
+
* Detailed API connection state.
|
|
3820
|
+
*
|
|
3821
|
+
* Subscribe to this when callers need to distinguish physical/network
|
|
3822
|
+
* offline state from authentication failure or server/API unavailability.
|
|
3823
|
+
*/
|
|
3824
|
+
__publicField(this, "status$", new BehaviorSubject(this.initialOnline ? "online" : "offline"));
|
|
3825
|
+
/**
|
|
3826
|
+
* Backwards-compatible boolean connection state.
|
|
3827
|
+
*
|
|
3828
|
+
* `false` includes `offline`, `unauthorized`, and `unavailable` states.
|
|
3829
|
+
*/
|
|
3830
|
+
__publicField(this, "online$", new BehaviorSubject(this.initialOnline));
|
|
4348
3831
|
/** API Session token */
|
|
4349
3832
|
__publicField(this, "token$", new BehaviorSubject(void 0));
|
|
4350
3833
|
var _a, _b;
|
|
@@ -4365,14 +3848,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4365
3848
|
...options.webrtc || {}
|
|
4366
3849
|
}
|
|
4367
3850
|
};
|
|
4368
|
-
if (this.options.saveSession) {
|
|
4369
|
-
if (typeof localStorage == "undefined") return;
|
|
3851
|
+
if (this.options.saveSession && typeof localStorage != "undefined") {
|
|
4370
3852
|
this.token = localStorage.getItem(this.localStorageKey) || null;
|
|
4371
3853
|
this.token$.pipe(distinctUntilChanged()).subscribe((token) => {
|
|
4372
3854
|
if (token) localStorage.setItem(this.localStorageKey, token);
|
|
4373
3855
|
else localStorage.removeItem(this.localStorageKey);
|
|
4374
3856
|
});
|
|
4375
3857
|
}
|
|
3858
|
+
this.token$.pipe(distinctUntilChanged()).subscribe((token) => this.scheduleTokenExpiry(token));
|
|
4376
3859
|
this.socket = new Socket(this, { url: options.socket });
|
|
4377
3860
|
this.gps = new Gps(this, options.gps);
|
|
4378
3861
|
this.auth = new Auth(this);
|
|
@@ -4395,12 +3878,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4395
3878
|
});
|
|
4396
3879
|
}
|
|
4397
3880
|
if (typeof window !== "undefined") {
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
};
|
|
4401
|
-
window.addEventListener("online", () => handleOffline(true));
|
|
4402
|
-
window.addEventListener("offline", () => handleOffline(false));
|
|
3881
|
+
window.addEventListener("online", () => this.checkConnection());
|
|
3882
|
+
window.addEventListener("offline", () => this.setConnectionStatus("offline"));
|
|
4403
3883
|
this.online$.subscribe(() => this.offlineBanner());
|
|
3884
|
+
this.startHeartbeat();
|
|
4404
3885
|
}
|
|
4405
3886
|
if ((_a = this.options.offline) == null ? void 0 : _a.length) {
|
|
4406
3887
|
this.pwa.setup();
|
|
@@ -4433,26 +3914,50 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4433
3914
|
/** Get session info from JWT payload */
|
|
4434
3915
|
get jwtPayload() {
|
|
4435
3916
|
if (!this.token) return null;
|
|
4436
|
-
|
|
3917
|
+
try {
|
|
3918
|
+
return decodeJwt(this.token);
|
|
3919
|
+
} catch {
|
|
3920
|
+
return null;
|
|
3921
|
+
}
|
|
3922
|
+
}
|
|
3923
|
+
/** Current detailed Datalynk API connection state. */
|
|
3924
|
+
get status() {
|
|
3925
|
+
return this.status$.getValue();
|
|
4437
3926
|
}
|
|
4438
|
-
/**
|
|
3927
|
+
/**
|
|
3928
|
+
* Whether normal Datalynk network requests are currently available.
|
|
3929
|
+
*
|
|
3930
|
+
* This becomes `false` for network outages, rejected/expired sessions, and
|
|
3931
|
+
* request-owned server recovery. It therefore describes Datalynk
|
|
3932
|
+
* availability rather than only `navigator.onLine`.
|
|
3933
|
+
*/
|
|
4439
3934
|
get online() {
|
|
4440
3935
|
return this.online$.getValue();
|
|
4441
3936
|
}
|
|
3937
|
+
/**
|
|
3938
|
+
* Whether normal Datalynk API access is currently unavailable.
|
|
3939
|
+
*
|
|
3940
|
+
* This is the inverse of {@link online}. It can be `true` while the browser
|
|
3941
|
+
* still has Internet access, for example during MySQL/HTTP 5xx recovery.
|
|
3942
|
+
*/
|
|
4442
3943
|
get offline() {
|
|
4443
3944
|
return !this.online;
|
|
4444
3945
|
}
|
|
4445
|
-
/**
|
|
3946
|
+
/**
|
|
3947
|
+
* Override the boolean connection state.
|
|
3948
|
+
*
|
|
3949
|
+
* Set `true` or `false` to force the corresponding state. Set `null` to
|
|
3950
|
+
* remove the override and resume normal connection checking. This is a
|
|
3951
|
+
* manual override and can supersede the current recovery state, so normal
|
|
3952
|
+
* applications should generally observe {@link status} instead of forcing it.
|
|
3953
|
+
*/
|
|
4446
3954
|
set online(value) {
|
|
4447
3955
|
if (value == null) {
|
|
4448
3956
|
this.onlineOverride = false;
|
|
4449
|
-
this.
|
|
3957
|
+
this.checkConnection();
|
|
4450
3958
|
} else {
|
|
4451
3959
|
this.onlineOverride = true;
|
|
4452
|
-
|
|
4453
|
-
this.online$.next(value);
|
|
4454
|
-
if (value) this.startHeartbeat();
|
|
4455
|
-
else this.stopHeartbeat();
|
|
3960
|
+
this.setConnectionStatus(value ? "online" : "offline");
|
|
4456
3961
|
}
|
|
4457
3962
|
}
|
|
4458
3963
|
/** Logged in spoke */
|
|
@@ -4464,56 +3969,246 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4464
3969
|
return this.token$.getValue();
|
|
4465
3970
|
}
|
|
4466
3971
|
set token(token) {
|
|
3972
|
+
if (this.recovery && token !== this.recovery.token)
|
|
3973
|
+
this.cancelRecovery(errorFromCode(401, "Session changed during API recovery"));
|
|
3974
|
+
if (token && this.isTokenExpired(token)) {
|
|
3975
|
+
this.authenticationInvalid = true;
|
|
3976
|
+
this.token$.next(null);
|
|
3977
|
+
this.setConnectionStatus("unauthorized");
|
|
3978
|
+
return;
|
|
3979
|
+
}
|
|
3980
|
+
this.authenticationInvalid = false;
|
|
4467
3981
|
this.token$.next(token);
|
|
3982
|
+
if (token && !this.online && !this.recovery) {
|
|
3983
|
+
this.setConnectionStatus(typeof navigator == "undefined" || navigator.onLine ? "online" : "offline");
|
|
3984
|
+
}
|
|
4468
3985
|
}
|
|
4469
|
-
_request(req, options = {}) {
|
|
3986
|
+
async _request(req, options = {}) {
|
|
3987
|
+
if (this.recovery) throw errorFromCode(503, "Datalynk is unavailable");
|
|
3988
|
+
const retryRequest = deepCopy(req);
|
|
3989
|
+
const retryOptions = { ...options };
|
|
4470
3990
|
const token = options.token || this.token;
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
3991
|
+
try {
|
|
3992
|
+
return await this._requestOnce(req, options, false);
|
|
3993
|
+
} catch (error) {
|
|
3994
|
+
if (!this.isRecoverableResponseError(error)) throw error;
|
|
3995
|
+
this.beginRecovery(retryRequest, retryOptions, token);
|
|
3996
|
+
throw error;
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
/** Execute exactly one HTTP API attempt. Recovery uses this directly to avoid recursive retry loops. */
|
|
4000
|
+
async _requestOnce(req, options = {}, recoveryAttempt = false) {
|
|
4001
|
+
const token = options.token || this.token;
|
|
4002
|
+
if (token && this.isTokenExpired(token)) {
|
|
4003
|
+
this.markUnauthorized(token);
|
|
4004
|
+
throw errorFromCode(401, "Session token expired");
|
|
4005
|
+
}
|
|
4006
|
+
let resp;
|
|
4007
|
+
try {
|
|
4008
|
+
resp = await fetch(this.url, {
|
|
4009
|
+
method: "POST",
|
|
4010
|
+
headers: clean({
|
|
4011
|
+
Authorization: token ? `Bearer ${token}` : void 0,
|
|
4012
|
+
"Content-Type": "application/json",
|
|
4013
|
+
"X-Date-Return-Format": this.options.legacyDates ? void 0 : "ISO8601"
|
|
4014
|
+
}),
|
|
4015
|
+
body: JSON.stringify(_Api.translateTokens(req))
|
|
4016
|
+
});
|
|
4017
|
+
} catch (error) {
|
|
4018
|
+
this.setConnectionStatus("offline");
|
|
4019
|
+
throw error;
|
|
4020
|
+
}
|
|
4021
|
+
const warning = resp.headers.get("X-Warning");
|
|
4022
|
+
if (warning) console.warn(warning);
|
|
4023
|
+
const banner = resp.headers.get("X-User-Notice");
|
|
4024
|
+
if (banner) {
|
|
4025
|
+
createBanner(banner);
|
|
4026
|
+
setTimeout(() => removeBanner(), 1e4);
|
|
4027
|
+
}
|
|
4028
|
+
const body = await resp.text();
|
|
4029
|
+
let data;
|
|
4030
|
+
try {
|
|
4031
|
+
data = JSON.parse(body);
|
|
4032
|
+
} catch {
|
|
4033
|
+
throw new UnexpectedApiResponseError(resp, body);
|
|
4034
|
+
}
|
|
4035
|
+
if (resp.status === 401) this.markUnauthorized(token);
|
|
4036
|
+
if (!resp.ok || (data == null ? void 0 : data.error)) {
|
|
4037
|
+
const error = Object.assign(errorFromCode(resp.status, data == null ? void 0 : data.error), data);
|
|
4038
|
+
Object.defineProperty(error, "response", { value: resp, configurable: true });
|
|
4039
|
+
if (!recoveryAttempt && resp.status < 500 && resp.status !== 401 && !this.isMysqlError(error))
|
|
4040
|
+
this.setConnectionStatus("online");
|
|
4041
|
+
throw error;
|
|
4042
|
+
}
|
|
4043
|
+
if (!options.raw) data = _Api.translateTokens(data);
|
|
4044
|
+
if (!recoveryAttempt) this.setConnectionStatus("online");
|
|
4045
|
+
return data;
|
|
4046
|
+
}
|
|
4047
|
+
/** Only server-response failures own global recovery; auth and ordinary 4xx errors do not. */
|
|
4048
|
+
isRecoverableResponseError(error) {
|
|
4049
|
+
var _a;
|
|
4050
|
+
if (error instanceof UnexpectedApiResponseError) return true;
|
|
4051
|
+
if ((error == null ? void 0 : error.code) === 401) return false;
|
|
4052
|
+
const status = ((_a = error == null ? void 0 : error.response) == null ? void 0 : _a.status) ?? (error == null ? void 0 : error.code);
|
|
4053
|
+
return status >= 500 || this.isMysqlError(error);
|
|
4054
|
+
}
|
|
4055
|
+
isMysqlError(error) {
|
|
4056
|
+
const message = String((error == null ? void 0 : error.error) ?? (error == null ? void 0 : error.message) ?? "");
|
|
4057
|
+
return /\bSQLSTATE\[[A-Z0-9]+\]/i.test(message);
|
|
4058
|
+
}
|
|
4059
|
+
/**
|
|
4060
|
+
* A returned server failure immediately makes the client unavailable. The exact
|
|
4061
|
+
* failed request is then retried twice back-to-back. After that, retries are
|
|
4062
|
+
* scheduled 30 seconds after each completed failed attempt, never with overlap.
|
|
4063
|
+
*/
|
|
4064
|
+
beginRecovery(req, options, token) {
|
|
4065
|
+
if (this.recovery) return;
|
|
4066
|
+
this.setConnectionStatus("unavailable");
|
|
4067
|
+
this.recovery = {
|
|
4068
|
+
request: deepCopy(req),
|
|
4069
|
+
options: { ...options },
|
|
4070
|
+
token,
|
|
4071
|
+
timer: null,
|
|
4072
|
+
running: false
|
|
4073
|
+
};
|
|
4074
|
+
void this.runImmediateRecovery();
|
|
4075
|
+
}
|
|
4076
|
+
async runImmediateRecovery() {
|
|
4077
|
+
for (let attempt = 0; attempt < this.recoveryImmediateRetries; attempt++) {
|
|
4078
|
+
const result = await this.tryRecoveryOnce();
|
|
4079
|
+
if (result.ok) {
|
|
4080
|
+
this.finishRecovery();
|
|
4081
|
+
return;
|
|
4486
4082
|
}
|
|
4487
|
-
this.
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4083
|
+
if (!this.recovery || this.status === "unauthorized") return;
|
|
4084
|
+
}
|
|
4085
|
+
if (this.recovery) this.scheduleRecovery();
|
|
4086
|
+
}
|
|
4087
|
+
async tryRecoveryOnce() {
|
|
4088
|
+
const recovery = this.recovery;
|
|
4089
|
+
if (!recovery) return { ok: false, error: errorFromCode(503, "API recovery was cancelled") };
|
|
4090
|
+
if (recovery.running) return { ok: false, error: errorFromCode(503, "API recovery request is already running") };
|
|
4091
|
+
if (recovery.token !== (recovery.options.token || this.token)) {
|
|
4092
|
+
const error = errorFromCode(401, "Session changed during API recovery");
|
|
4093
|
+
this.cancelRecovery(error);
|
|
4094
|
+
return { ok: false, error };
|
|
4095
|
+
}
|
|
4096
|
+
recovery.running = true;
|
|
4097
|
+
try {
|
|
4098
|
+
const value = await this._requestOnce(
|
|
4099
|
+
deepCopy(recovery.request),
|
|
4100
|
+
{ ...recovery.options, token: recovery.token || void 0 },
|
|
4101
|
+
true
|
|
4102
|
+
);
|
|
4103
|
+
return { ok: true, value };
|
|
4104
|
+
} catch (error) {
|
|
4105
|
+
return { ok: false, error };
|
|
4106
|
+
} finally {
|
|
4107
|
+
if (this.recovery === recovery) recovery.running = false;
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
scheduleRecovery() {
|
|
4111
|
+
const recovery = this.recovery;
|
|
4112
|
+
if (!recovery) return;
|
|
4113
|
+
if (recovery.timer) clearTimeout(recovery.timer);
|
|
4114
|
+
recovery.timer = setTimeout(async () => {
|
|
4115
|
+
const current = this.recovery;
|
|
4116
|
+
if (!current || current !== recovery) return;
|
|
4117
|
+
current.timer = null;
|
|
4118
|
+
const result = await this.tryRecoveryOnce();
|
|
4119
|
+
if (result.ok) {
|
|
4120
|
+
this.finishRecovery();
|
|
4121
|
+
return;
|
|
4122
|
+
}
|
|
4123
|
+
if (this.recovery && this.status !== "unauthorized") this.scheduleRecovery();
|
|
4124
|
+
}, this.recoveryRetryInterval);
|
|
4125
|
+
}
|
|
4126
|
+
finishRecovery() {
|
|
4127
|
+
const recovery = this.recovery;
|
|
4128
|
+
if (!recovery) return;
|
|
4129
|
+
if (recovery.timer) clearTimeout(recovery.timer);
|
|
4130
|
+
this.recovery = null;
|
|
4131
|
+
this.setConnectionStatus("online");
|
|
4132
|
+
}
|
|
4133
|
+
cancelRecovery(_error) {
|
|
4134
|
+
const recovery = this.recovery;
|
|
4135
|
+
if (!recovery) return;
|
|
4136
|
+
if (recovery.timer) clearTimeout(recovery.timer);
|
|
4137
|
+
this.recovery = null;
|
|
4493
4138
|
}
|
|
4494
4139
|
async checkConnection() {
|
|
4140
|
+
if (this.recovery) return;
|
|
4495
4141
|
if (typeof navigator != "undefined" && !navigator.onLine) {
|
|
4496
|
-
this.
|
|
4142
|
+
this.setConnectionStatus("offline");
|
|
4497
4143
|
return;
|
|
4498
4144
|
}
|
|
4499
4145
|
if (this.onlineOverride) return;
|
|
4146
|
+
if (this.authenticationInvalid) {
|
|
4147
|
+
this.setConnectionStatus("unauthorized");
|
|
4148
|
+
return;
|
|
4149
|
+
}
|
|
4150
|
+
if (this.token && this.isTokenExpired(this.token)) {
|
|
4151
|
+
this.markUnauthorized(this.token);
|
|
4152
|
+
return;
|
|
4153
|
+
}
|
|
4500
4154
|
const controller = new AbortController();
|
|
4501
4155
|
const timeout = setTimeout(() => controller.abort(), this.heartbeat.timeout);
|
|
4502
4156
|
try {
|
|
4503
4157
|
const response = await fetch(this.url + this.heartbeat.target, { signal: controller.signal });
|
|
4504
|
-
this.
|
|
4158
|
+
if (this.recovery) return;
|
|
4159
|
+
this.setConnectionStatus(response.ok ? "online" : "unavailable");
|
|
4505
4160
|
} catch (error) {
|
|
4506
|
-
this.
|
|
4161
|
+
if (!this.recovery) this.setConnectionStatus("offline");
|
|
4507
4162
|
} finally {
|
|
4508
4163
|
clearTimeout(timeout);
|
|
4509
4164
|
}
|
|
4510
4165
|
}
|
|
4166
|
+
isTokenExpired(token) {
|
|
4167
|
+
var _a;
|
|
4168
|
+
try {
|
|
4169
|
+
return (((_a = decodeJwt(token)) == null ? void 0 : _a.exp) ?? 0) * 1e3 <= Date.now();
|
|
4170
|
+
} catch {
|
|
4171
|
+
return true;
|
|
4172
|
+
}
|
|
4173
|
+
}
|
|
4174
|
+
scheduleTokenExpiry(token) {
|
|
4175
|
+
var _a, _b, _c;
|
|
4176
|
+
if (this.tokenExpiryTimeout) clearTimeout(this.tokenExpiryTimeout);
|
|
4177
|
+
this.tokenExpiryTimeout = null;
|
|
4178
|
+
if (!token) return;
|
|
4179
|
+
let expiresAt = 0;
|
|
4180
|
+
try {
|
|
4181
|
+
expiresAt = (((_a = decodeJwt(token)) == null ? void 0 : _a.exp) ?? 0) * 1e3;
|
|
4182
|
+
} catch {
|
|
4183
|
+
return this.markUnauthorized(token);
|
|
4184
|
+
}
|
|
4185
|
+
const delay = expiresAt - Date.now();
|
|
4186
|
+
if (delay <= 0) return this.markUnauthorized(token);
|
|
4187
|
+
this.tokenExpiryTimeout = setTimeout(() => {
|
|
4188
|
+
if (delay > 2147e6) this.scheduleTokenExpiry(token);
|
|
4189
|
+
else this.markUnauthorized(token);
|
|
4190
|
+
}, Math.min(delay, 2147e6));
|
|
4191
|
+
(_c = (_b = this.tokenExpiryTimeout) == null ? void 0 : _b.unref) == null ? void 0 : _c.call(_b);
|
|
4192
|
+
}
|
|
4193
|
+
markUnauthorized(token) {
|
|
4194
|
+
if (token && token !== this.token) return;
|
|
4195
|
+
this.authenticationInvalid = true;
|
|
4196
|
+
this.cancelRecovery(errorFromCode(401, "Session expired"));
|
|
4197
|
+
if (this.token != null) this.token$.next(null);
|
|
4198
|
+
this.setConnectionStatus("unauthorized");
|
|
4199
|
+
}
|
|
4200
|
+
setConnectionStatus(status) {
|
|
4201
|
+
if (this.status !== status) this.status$.next(status);
|
|
4202
|
+
const online = status === "online";
|
|
4203
|
+
if (this.online !== online) this.online$.next(online);
|
|
4204
|
+
}
|
|
4511
4205
|
offlineBanner() {
|
|
4512
4206
|
if (this.options.offlineBanner === false || typeof document == "undefined") return;
|
|
4513
|
-
if (this.online) {
|
|
4207
|
+
if (this.status === "online") {
|
|
4514
4208
|
removeBanner("datalynk-offline-banner");
|
|
4515
4209
|
} else {
|
|
4516
|
-
|
|
4210
|
+
const message = this.status === "unauthorized" ? "⚠️ Your session expired, please sign in again" : this.status === "unavailable" ? "⚠️ Datalynk is currently unavailable" : "⚠️ You are offline, please reconnect to sync changes";
|
|
4211
|
+
createBanner(message, {
|
|
4517
4212
|
id: "datalynk-offline-banner",
|
|
4518
4213
|
position: this.options.offlineBanner === "top" ? "top" : "bottom"
|
|
4519
4214
|
});
|
|
@@ -4625,9 +4320,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4625
4320
|
var _a, _b;
|
|
4626
4321
|
data = typeof data == "string" ? { [data]: {} } : data;
|
|
4627
4322
|
let key = JSON.stringify(data);
|
|
4628
|
-
if (this.offline) {
|
|
4629
|
-
|
|
4630
|
-
|
|
4323
|
+
if (this.offline && typeof navigator != "undefined") {
|
|
4324
|
+
if (this.status === "unauthorized") return Promise.reject(errorFromCode(401, "Session expired"));
|
|
4325
|
+
if (options.offline) {
|
|
4326
|
+
(_b = (_a = this.database) == null ? void 0 : _a.table("pending")) == null ? void 0 : _b.add(data, key);
|
|
4327
|
+
return Promise.resolve();
|
|
4328
|
+
}
|
|
4329
|
+
return Promise.reject(errorFromCode(503, this.status === "unavailable" ? "Datalynk is unavailable" : "You are offline"));
|
|
4631
4330
|
}
|
|
4632
4331
|
if (options.noOptimize) {
|
|
4633
4332
|
return new Promise((res, rej) => {
|
|
@@ -4638,7 +4337,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4638
4337
|
}
|
|
4639
4338
|
if (!this.pending[key]) {
|
|
4640
4339
|
this.pending[key] = new Promise((res, rej) => this.bundle.push({ data, res, rej }));
|
|
4641
|
-
this.pending[key].
|
|
4340
|
+
this.pending[key].then(() => delete this.pending[key], () => delete this.pending[key]);
|
|
4642
4341
|
if (!this.bundleOngoing) {
|
|
4643
4342
|
this.bundleOngoing = true;
|
|
4644
4343
|
setTimeout(() => {
|
|
@@ -4648,7 +4347,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4648
4347
|
data = originalBundle.map((row) => row.data);
|
|
4649
4348
|
this._request(data, options).then((resp) => {
|
|
4650
4349
|
if (!(resp instanceof Array)) resp = [resp];
|
|
4651
|
-
|
|
4350
|
+
originalBundle.forEach((request, index) => {
|
|
4351
|
+
const row = resp[index];
|
|
4352
|
+
(row == null ? void 0 : row.error) ? request.rej(row.error) : request.res(row);
|
|
4353
|
+
});
|
|
4652
4354
|
}).catch((err) => originalBundle.forEach((req) => req.rej(err)));
|
|
4653
4355
|
}, this.options.bundleTime);
|
|
4654
4356
|
}
|
|
@@ -4688,6 +4390,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4688
4390
|
exports2.Slice = Slice;
|
|
4689
4391
|
exports2.Socket = Socket;
|
|
4690
4392
|
exports2.Superuser = Superuser;
|
|
4393
|
+
exports2.UnexpectedApiResponseError = UnexpectedApiResponseError;
|
|
4691
4394
|
exports2.getTheme = getTheme;
|
|
4692
4395
|
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
4693
4396
|
});
|