@ztimson/utils 0.25.23 → 0.25.24
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/dist/database.d.ts +4 -1
- package/dist/index.cjs +193 -168
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +193 -168
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/database.d.ts
CHANGED
|
@@ -6,10 +6,13 @@ export type TableOptions = {
|
|
|
6
6
|
export declare class Database {
|
|
7
7
|
readonly database: string;
|
|
8
8
|
version?: number | undefined;
|
|
9
|
+
private schemaLock;
|
|
10
|
+
private upgrading;
|
|
9
11
|
connection: Promise<IDBDatabase>;
|
|
10
|
-
ready: boolean;
|
|
11
12
|
tables: TableOptions[];
|
|
13
|
+
get ready(): boolean;
|
|
12
14
|
constructor(database: string, tables?: (string | TableOptions)[], version?: number | undefined);
|
|
15
|
+
waitForUpgrade: () => Promise<void>;
|
|
13
16
|
createTable<K extends IDBValidKey = any, T = any>(table: string | TableOptions): Promise<Table<K, T>>;
|
|
14
17
|
deleteTable(table: string | TableOptions): Promise<void>;
|
|
15
18
|
includes(name: any): boolean;
|
package/dist/index.cjs
CHANGED
|
@@ -396,11 +396,179 @@ ${opts.message || this.desc}`;
|
|
|
396
396
|
function makeArray(value) {
|
|
397
397
|
return Array.isArray(value) ? value : [value];
|
|
398
398
|
}
|
|
399
|
+
function adjustedInterval(cb, ms) {
|
|
400
|
+
let cancel = false, timeout = null;
|
|
401
|
+
const p = async () => {
|
|
402
|
+
if (cancel) return;
|
|
403
|
+
const start = (/* @__PURE__ */ new Date()).getTime();
|
|
404
|
+
await cb();
|
|
405
|
+
const end = (/* @__PURE__ */ new Date()).getTime();
|
|
406
|
+
timeout = setTimeout(() => p(), ms - (end - start) || 1);
|
|
407
|
+
};
|
|
408
|
+
p();
|
|
409
|
+
return () => {
|
|
410
|
+
cancel = true;
|
|
411
|
+
if (timeout) clearTimeout(timeout);
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz) {
|
|
415
|
+
const timezones = [
|
|
416
|
+
["IDLW", -12],
|
|
417
|
+
["SST", -11],
|
|
418
|
+
["HST", -10],
|
|
419
|
+
["AKST", -9],
|
|
420
|
+
["PST", -8],
|
|
421
|
+
["MST", -7],
|
|
422
|
+
["CST", -6],
|
|
423
|
+
["EST", -5],
|
|
424
|
+
["AST", -4],
|
|
425
|
+
["BRT", -3],
|
|
426
|
+
["MAT", -2],
|
|
427
|
+
["AZOT", -1],
|
|
428
|
+
["UTC", 0],
|
|
429
|
+
["CET", 1],
|
|
430
|
+
["EET", 2],
|
|
431
|
+
["MSK", 3],
|
|
432
|
+
["AST", 4],
|
|
433
|
+
["PKT", 5],
|
|
434
|
+
["IST", 5.5],
|
|
435
|
+
["BST", 6],
|
|
436
|
+
["ICT", 7],
|
|
437
|
+
["CST", 8],
|
|
438
|
+
["JST", 9],
|
|
439
|
+
["AEST", 10],
|
|
440
|
+
["SBT", 11],
|
|
441
|
+
["FJT", 12],
|
|
442
|
+
["TOT", 13],
|
|
443
|
+
["LINT", 14]
|
|
444
|
+
];
|
|
445
|
+
function adjustTz(date2, gmt) {
|
|
446
|
+
const currentOffset = date2.getTimezoneOffset();
|
|
447
|
+
const adjustedOffset = gmt * 60;
|
|
448
|
+
return new Date(date2.getTime() + (adjustedOffset + currentOffset) * 6e4);
|
|
449
|
+
}
|
|
450
|
+
function day(num) {
|
|
451
|
+
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][num] || "Unknown";
|
|
452
|
+
}
|
|
453
|
+
function doy(date2) {
|
|
454
|
+
const start = /* @__PURE__ */ new Date(`${date2.getFullYear()}-01-01 0:00:00`);
|
|
455
|
+
return Math.ceil((date2.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
|
|
456
|
+
}
|
|
457
|
+
function month(num) {
|
|
458
|
+
return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][num] || "Unknown";
|
|
459
|
+
}
|
|
460
|
+
function suffix(num) {
|
|
461
|
+
if (num % 100 >= 11 && num % 100 <= 13) return `${num}th`;
|
|
462
|
+
switch (num % 10) {
|
|
463
|
+
case 1:
|
|
464
|
+
return `${num}st`;
|
|
465
|
+
case 2:
|
|
466
|
+
return `${num}nd`;
|
|
467
|
+
case 3:
|
|
468
|
+
return `${num}rd`;
|
|
469
|
+
default:
|
|
470
|
+
return `${num}th`;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
function tzOffset(offset) {
|
|
474
|
+
const hours = ~~(offset / 60);
|
|
475
|
+
const minutes = offset % 60;
|
|
476
|
+
return (offset > 0 ? "-" : "") + `${hours}:${minutes.toString().padStart(2, "0")}`;
|
|
477
|
+
}
|
|
478
|
+
if (typeof date == "number" || typeof date == "string" || date == null) date = new Date(date);
|
|
479
|
+
let t;
|
|
480
|
+
if (tz == null) tz = -(date.getTimezoneOffset() / 60);
|
|
481
|
+
t = timezones.find((t2) => isNaN(tz) ? t2[0] == tz : t2[1] == tz);
|
|
482
|
+
if (!t) throw new Error(`Unknown timezone: ${tz}`);
|
|
483
|
+
date = adjustTz(date, t[1]);
|
|
484
|
+
const tokens = {
|
|
485
|
+
"YYYY": date.getFullYear().toString(),
|
|
486
|
+
"YY": date.getFullYear().toString().slice(2),
|
|
487
|
+
"MMMM": month(date.getMonth()),
|
|
488
|
+
"MMM": month(date.getMonth()).slice(0, 3),
|
|
489
|
+
"MM": (date.getMonth() + 1).toString().padStart(2, "0"),
|
|
490
|
+
"M": (date.getMonth() + 1).toString(),
|
|
491
|
+
"DDD": doy(date).toString(),
|
|
492
|
+
"DD": date.getDate().toString().padStart(2, "0"),
|
|
493
|
+
"Do": suffix(date.getDate()),
|
|
494
|
+
"D": date.getDate().toString(),
|
|
495
|
+
"dddd": day(date.getDay()),
|
|
496
|
+
"ddd": day(date.getDay()).slice(0, 3),
|
|
497
|
+
"HH": date.getHours().toString().padStart(2, "0"),
|
|
498
|
+
"H": date.getHours().toString(),
|
|
499
|
+
"hh": (date.getHours() % 12 || 12).toString().padStart(2, "0"),
|
|
500
|
+
"h": (date.getHours() % 12 || 12).toString(),
|
|
501
|
+
"mm": date.getMinutes().toString().padStart(2, "0"),
|
|
502
|
+
"m": date.getMinutes().toString(),
|
|
503
|
+
"ss": date.getSeconds().toString().padStart(2, "0"),
|
|
504
|
+
"s": date.getSeconds().toString(),
|
|
505
|
+
"SSS": date.getMilliseconds().toString().padStart(3, "0"),
|
|
506
|
+
"A": date.getHours() >= 12 ? "PM" : "AM",
|
|
507
|
+
"a": date.getHours() >= 12 ? "pm" : "am",
|
|
508
|
+
"ZZ": tzOffset(t[1] * 60).replace(":", ""),
|
|
509
|
+
"Z": tzOffset(t[1] * 60),
|
|
510
|
+
"z": typeof tz == "string" ? tz : t[0]
|
|
511
|
+
};
|
|
512
|
+
return format.replace(/YYYY|YY|MMMM|MMM|MM|M|DDD|DD|Do|D|dddd|ddd|HH|H|hh|h|mm|m|ss|s|SSS|A|a|ZZ|Z|z/g, (token) => tokens[token]);
|
|
513
|
+
}
|
|
514
|
+
function instantInterval(fn2, interval) {
|
|
515
|
+
fn2();
|
|
516
|
+
return setInterval(fn2, interval);
|
|
517
|
+
}
|
|
518
|
+
function sleep(ms) {
|
|
519
|
+
return new Promise((res) => setTimeout(res, ms));
|
|
520
|
+
}
|
|
521
|
+
async function sleepWhile(fn2, checkInterval = 100) {
|
|
522
|
+
while (await fn2()) await sleep(checkInterval);
|
|
523
|
+
}
|
|
524
|
+
function timeUntil(date) {
|
|
525
|
+
return (date instanceof Date ? date.getTime() : date) - (/* @__PURE__ */ new Date()).getTime();
|
|
526
|
+
}
|
|
527
|
+
function timezoneOffset(tz, date = /* @__PURE__ */ new Date()) {
|
|
528
|
+
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
529
|
+
timeZone: tz,
|
|
530
|
+
hour12: false,
|
|
531
|
+
year: "numeric",
|
|
532
|
+
month: "2-digit",
|
|
533
|
+
day: "2-digit",
|
|
534
|
+
hour: "2-digit",
|
|
535
|
+
minute: "2-digit",
|
|
536
|
+
second: "2-digit"
|
|
537
|
+
});
|
|
538
|
+
const parts = dtf.formatToParts(date);
|
|
539
|
+
const get = (type) => {
|
|
540
|
+
var _a;
|
|
541
|
+
return Number((_a = parts.find((v) => v.type === type)) == null ? void 0 : _a.value);
|
|
542
|
+
};
|
|
543
|
+
const y = get("year");
|
|
544
|
+
const mo = get("month");
|
|
545
|
+
const d = get("day");
|
|
546
|
+
const h = get("hour");
|
|
547
|
+
const m = get("minute");
|
|
548
|
+
const s = get("second");
|
|
549
|
+
const asUTC = Date.UTC(y, mo - 1, d, h, m, s);
|
|
550
|
+
const asLocal = date.getTime();
|
|
551
|
+
return Math.round((asLocal - asUTC) / 6e4);
|
|
552
|
+
}
|
|
553
|
+
class AsyncLock {
|
|
554
|
+
constructor() {
|
|
555
|
+
__publicField(this, "p", Promise.resolve());
|
|
556
|
+
}
|
|
557
|
+
run(fn2) {
|
|
558
|
+
const res = this.p.then(fn2, fn2);
|
|
559
|
+
this.p = res.then(() => {
|
|
560
|
+
}, () => {
|
|
561
|
+
});
|
|
562
|
+
return res;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
399
565
|
class Database {
|
|
400
566
|
constructor(database, tables, version) {
|
|
567
|
+
__publicField(this, "schemaLock", new AsyncLock());
|
|
568
|
+
__publicField(this, "upgrading", false);
|
|
401
569
|
__publicField(this, "connection");
|
|
402
|
-
__publicField(this, "ready", false);
|
|
403
570
|
__publicField(this, "tables");
|
|
571
|
+
__publicField(this, "waitForUpgrade", () => sleepWhile(() => this.upgrading));
|
|
404
572
|
this.database = database;
|
|
405
573
|
this.version = version;
|
|
406
574
|
this.connection = new Promise((resolve, reject) => {
|
|
@@ -427,9 +595,10 @@ ${opts.message || this.desc}`;
|
|
|
427
595
|
this.version = db.version;
|
|
428
596
|
resolve(db);
|
|
429
597
|
}
|
|
430
|
-
this.
|
|
598
|
+
this.upgrading = false;
|
|
431
599
|
};
|
|
432
600
|
req.onupgradeneeded = () => {
|
|
601
|
+
this.upgrading = true;
|
|
433
602
|
const db = req.result;
|
|
434
603
|
const existingTables = new ASet(Array.from(db.objectStoreNames));
|
|
435
604
|
if (tables) {
|
|
@@ -446,21 +615,30 @@ ${opts.message || this.desc}`;
|
|
|
446
615
|
};
|
|
447
616
|
});
|
|
448
617
|
}
|
|
618
|
+
get ready() {
|
|
619
|
+
return !this.upgrading;
|
|
620
|
+
}
|
|
449
621
|
async createTable(table) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
622
|
+
return this.schemaLock.run(async () => {
|
|
623
|
+
if (typeof table == "string") table = { name: table };
|
|
624
|
+
const conn = await this.connection;
|
|
625
|
+
if (!this.includes(table.name)) {
|
|
626
|
+
conn.close();
|
|
627
|
+
Object.assign(this, new Database(this.database, [...this.tables, table], (this.version ?? 0) + 1));
|
|
628
|
+
await this.connection;
|
|
629
|
+
}
|
|
630
|
+
return this.table(table.name);
|
|
631
|
+
});
|
|
457
632
|
}
|
|
458
633
|
async deleteTable(table) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
634
|
+
return this.schemaLock.run(async () => {
|
|
635
|
+
if (typeof table == "string") table = { name: table };
|
|
636
|
+
if (!this.includes(table.name)) return;
|
|
637
|
+
const conn = await this.connection;
|
|
638
|
+
conn.close();
|
|
639
|
+
Object.assign(this, new Database(this.database, this.tables.filter((t) => t.name != table.name), (this.version ?? 0) + 1));
|
|
640
|
+
await this.connection;
|
|
641
|
+
});
|
|
464
642
|
}
|
|
465
643
|
includes(name) {
|
|
466
644
|
return !!this.tables.find((t) => t.name == (typeof name == "object" ? name.name : name.toString()));
|
|
@@ -483,6 +661,7 @@ ${opts.message || this.desc}`;
|
|
|
483
661
|
});
|
|
484
662
|
}
|
|
485
663
|
async tx(table, fn2, readonly = false) {
|
|
664
|
+
await this.database.waitForUpgrade();
|
|
486
665
|
const db = await this.database.connection;
|
|
487
666
|
const tx = db.transaction(table, readonly ? "readonly" : "readwrite");
|
|
488
667
|
const store = tx.objectStore(table);
|
|
@@ -997,160 +1176,6 @@ ${opts.message || this.desc}`;
|
|
|
997
1176
|
return this.from(super.finally(res));
|
|
998
1177
|
}
|
|
999
1178
|
}
|
|
1000
|
-
function adjustedInterval(cb, ms) {
|
|
1001
|
-
let cancel = false, timeout = null;
|
|
1002
|
-
const p = async () => {
|
|
1003
|
-
if (cancel) return;
|
|
1004
|
-
const start = (/* @__PURE__ */ new Date()).getTime();
|
|
1005
|
-
await cb();
|
|
1006
|
-
const end = (/* @__PURE__ */ new Date()).getTime();
|
|
1007
|
-
timeout = setTimeout(() => p(), ms - (end - start) || 1);
|
|
1008
|
-
};
|
|
1009
|
-
p();
|
|
1010
|
-
return () => {
|
|
1011
|
-
cancel = true;
|
|
1012
|
-
if (timeout) clearTimeout(timeout);
|
|
1013
|
-
};
|
|
1014
|
-
}
|
|
1015
|
-
function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz) {
|
|
1016
|
-
const timezones = [
|
|
1017
|
-
["IDLW", -12],
|
|
1018
|
-
["SST", -11],
|
|
1019
|
-
["HST", -10],
|
|
1020
|
-
["AKST", -9],
|
|
1021
|
-
["PST", -8],
|
|
1022
|
-
["MST", -7],
|
|
1023
|
-
["CST", -6],
|
|
1024
|
-
["EST", -5],
|
|
1025
|
-
["AST", -4],
|
|
1026
|
-
["BRT", -3],
|
|
1027
|
-
["MAT", -2],
|
|
1028
|
-
["AZOT", -1],
|
|
1029
|
-
["UTC", 0],
|
|
1030
|
-
["CET", 1],
|
|
1031
|
-
["EET", 2],
|
|
1032
|
-
["MSK", 3],
|
|
1033
|
-
["AST", 4],
|
|
1034
|
-
["PKT", 5],
|
|
1035
|
-
["IST", 5.5],
|
|
1036
|
-
["BST", 6],
|
|
1037
|
-
["ICT", 7],
|
|
1038
|
-
["CST", 8],
|
|
1039
|
-
["JST", 9],
|
|
1040
|
-
["AEST", 10],
|
|
1041
|
-
["SBT", 11],
|
|
1042
|
-
["FJT", 12],
|
|
1043
|
-
["TOT", 13],
|
|
1044
|
-
["LINT", 14]
|
|
1045
|
-
];
|
|
1046
|
-
function adjustTz(date2, gmt) {
|
|
1047
|
-
const currentOffset = date2.getTimezoneOffset();
|
|
1048
|
-
const adjustedOffset = gmt * 60;
|
|
1049
|
-
return new Date(date2.getTime() + (adjustedOffset + currentOffset) * 6e4);
|
|
1050
|
-
}
|
|
1051
|
-
function day(num) {
|
|
1052
|
-
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][num] || "Unknown";
|
|
1053
|
-
}
|
|
1054
|
-
function doy(date2) {
|
|
1055
|
-
const start = /* @__PURE__ */ new Date(`${date2.getFullYear()}-01-01 0:00:00`);
|
|
1056
|
-
return Math.ceil((date2.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
|
|
1057
|
-
}
|
|
1058
|
-
function month(num) {
|
|
1059
|
-
return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][num] || "Unknown";
|
|
1060
|
-
}
|
|
1061
|
-
function suffix(num) {
|
|
1062
|
-
if (num % 100 >= 11 && num % 100 <= 13) return `${num}th`;
|
|
1063
|
-
switch (num % 10) {
|
|
1064
|
-
case 1:
|
|
1065
|
-
return `${num}st`;
|
|
1066
|
-
case 2:
|
|
1067
|
-
return `${num}nd`;
|
|
1068
|
-
case 3:
|
|
1069
|
-
return `${num}rd`;
|
|
1070
|
-
default:
|
|
1071
|
-
return `${num}th`;
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
function tzOffset(offset) {
|
|
1075
|
-
const hours = ~~(offset / 60);
|
|
1076
|
-
const minutes = offset % 60;
|
|
1077
|
-
return (offset > 0 ? "-" : "") + `${hours}:${minutes.toString().padStart(2, "0")}`;
|
|
1078
|
-
}
|
|
1079
|
-
if (typeof date == "number" || typeof date == "string" || date == null) date = new Date(date);
|
|
1080
|
-
let t;
|
|
1081
|
-
if (tz == null) tz = -(date.getTimezoneOffset() / 60);
|
|
1082
|
-
t = timezones.find((t2) => isNaN(tz) ? t2[0] == tz : t2[1] == tz);
|
|
1083
|
-
if (!t) throw new Error(`Unknown timezone: ${tz}`);
|
|
1084
|
-
date = adjustTz(date, t[1]);
|
|
1085
|
-
const tokens = {
|
|
1086
|
-
"YYYY": date.getFullYear().toString(),
|
|
1087
|
-
"YY": date.getFullYear().toString().slice(2),
|
|
1088
|
-
"MMMM": month(date.getMonth()),
|
|
1089
|
-
"MMM": month(date.getMonth()).slice(0, 3),
|
|
1090
|
-
"MM": (date.getMonth() + 1).toString().padStart(2, "0"),
|
|
1091
|
-
"M": (date.getMonth() + 1).toString(),
|
|
1092
|
-
"DDD": doy(date).toString(),
|
|
1093
|
-
"DD": date.getDate().toString().padStart(2, "0"),
|
|
1094
|
-
"Do": suffix(date.getDate()),
|
|
1095
|
-
"D": date.getDate().toString(),
|
|
1096
|
-
"dddd": day(date.getDay()),
|
|
1097
|
-
"ddd": day(date.getDay()).slice(0, 3),
|
|
1098
|
-
"HH": date.getHours().toString().padStart(2, "0"),
|
|
1099
|
-
"H": date.getHours().toString(),
|
|
1100
|
-
"hh": (date.getHours() % 12 || 12).toString().padStart(2, "0"),
|
|
1101
|
-
"h": (date.getHours() % 12 || 12).toString(),
|
|
1102
|
-
"mm": date.getMinutes().toString().padStart(2, "0"),
|
|
1103
|
-
"m": date.getMinutes().toString(),
|
|
1104
|
-
"ss": date.getSeconds().toString().padStart(2, "0"),
|
|
1105
|
-
"s": date.getSeconds().toString(),
|
|
1106
|
-
"SSS": date.getMilliseconds().toString().padStart(3, "0"),
|
|
1107
|
-
"A": date.getHours() >= 12 ? "PM" : "AM",
|
|
1108
|
-
"a": date.getHours() >= 12 ? "pm" : "am",
|
|
1109
|
-
"ZZ": tzOffset(t[1] * 60).replace(":", ""),
|
|
1110
|
-
"Z": tzOffset(t[1] * 60),
|
|
1111
|
-
"z": typeof tz == "string" ? tz : t[0]
|
|
1112
|
-
};
|
|
1113
|
-
return format.replace(/YYYY|YY|MMMM|MMM|MM|M|DDD|DD|Do|D|dddd|ddd|HH|H|hh|h|mm|m|ss|s|SSS|A|a|ZZ|Z|z/g, (token) => tokens[token]);
|
|
1114
|
-
}
|
|
1115
|
-
function instantInterval(fn2, interval) {
|
|
1116
|
-
fn2();
|
|
1117
|
-
return setInterval(fn2, interval);
|
|
1118
|
-
}
|
|
1119
|
-
function sleep(ms) {
|
|
1120
|
-
return new Promise((res) => setTimeout(res, ms));
|
|
1121
|
-
}
|
|
1122
|
-
async function sleepWhile(fn2, checkInterval = 100) {
|
|
1123
|
-
while (await fn2()) await sleep(checkInterval);
|
|
1124
|
-
}
|
|
1125
|
-
function timeUntil(date) {
|
|
1126
|
-
return (date instanceof Date ? date.getTime() : date) - (/* @__PURE__ */ new Date()).getTime();
|
|
1127
|
-
}
|
|
1128
|
-
function timezoneOffset(tz, date = /* @__PURE__ */ new Date()) {
|
|
1129
|
-
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
1130
|
-
timeZone: tz,
|
|
1131
|
-
hour12: false,
|
|
1132
|
-
year: "numeric",
|
|
1133
|
-
month: "2-digit",
|
|
1134
|
-
day: "2-digit",
|
|
1135
|
-
hour: "2-digit",
|
|
1136
|
-
minute: "2-digit",
|
|
1137
|
-
second: "2-digit"
|
|
1138
|
-
});
|
|
1139
|
-
const parts = dtf.formatToParts(date);
|
|
1140
|
-
const get = (type) => {
|
|
1141
|
-
var _a;
|
|
1142
|
-
return Number((_a = parts.find((v) => v.type === type)) == null ? void 0 : _a.value);
|
|
1143
|
-
};
|
|
1144
|
-
const y = get("year");
|
|
1145
|
-
const mo = get("month");
|
|
1146
|
-
const d = get("day");
|
|
1147
|
-
const h = get("hour");
|
|
1148
|
-
const m = get("minute");
|
|
1149
|
-
const s = get("second");
|
|
1150
|
-
const asUTC = Date.UTC(y, mo - 1, d, h, m, s);
|
|
1151
|
-
const asLocal = date.getTime();
|
|
1152
|
-
return Math.round((asLocal - asUTC) / 6e4);
|
|
1153
|
-
}
|
|
1154
1179
|
function downloadFile(blob, name) {
|
|
1155
1180
|
if (!(blob instanceof Blob)) blob = new Blob(makeArray(blob));
|
|
1156
1181
|
const url = URL.createObjectURL(blob);
|