@actdim/utico 1.1.1 → 1.1.2
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/cache/cacheContracts.d.ts +11 -11
- package/dist/cache/cacheContracts.d.ts.map +1 -1
- package/dist/cache/cacheContracts.es.js.map +1 -1
- package/dist/cache/persistentCache.d.ts +17 -17
- package/dist/cache/persistentCache.d.ts.map +1 -1
- package/dist/cache/persistentCache.es.js +48 -48
- package/dist/cache/persistentCache.es.js.map +1 -1
- package/dist/gfx/canvasUtils.d.ts +4 -5
- package/dist/gfx/canvasUtils.d.ts.map +1 -1
- package/dist/gfx/canvasUtils.es.js +77 -84
- package/dist/gfx/canvasUtils.es.js.map +1 -1
- package/dist/metadata.d.ts +1 -0
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.es.js +20 -14
- package/dist/metadata.es.js.map +1 -1
- package/dist/store/dataStore.d.ts +23 -23
- package/dist/store/dataStore.d.ts.map +1 -1
- package/dist/store/dataStore.es.js +120 -120
- package/dist/store/dataStore.es.js.map +1 -1
- package/dist/store/persistentStore.d.ts +3 -3
- package/dist/store/persistentStore.d.ts.map +1 -1
- package/dist/store/persistentStore.es.js +12 -12
- package/dist/store/persistentStore.es.js.map +1 -1
- package/dist/store/storeContracts.d.ts +20 -20
- package/dist/store/storeContracts.d.ts.map +1 -1
- package/dist/store/storeContracts.es.js.map +1 -1
- package/dist/store/storeDb.es.js +33 -33
- package/dist/store/storeDb.es.js.map +1 -1
- package/dist/utils.d.ts +4 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.es.js +70 -61
- package/dist/utils.es.js.map +1 -1
- package/package.json +6 -4
|
@@ -6,16 +6,16 @@ export declare class CacheMetadataRecord extends MetadataRecord {
|
|
|
6
6
|
expiresAt?: number;
|
|
7
7
|
}
|
|
8
8
|
export interface IPersistentCache<T extends CacheMetadataRecord = CacheMetadataRecord> {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
open(): Promise<void>;
|
|
10
|
+
getKeys(): Promise<string[]>;
|
|
11
|
+
contains(key: string): Promise<boolean>;
|
|
12
|
+
delete(key: string): Promise<void>;
|
|
13
|
+
bulkDelete(keys: string[]): Promise<void>;
|
|
14
|
+
clear(): Promise<void>;
|
|
15
|
+
get<TValue = any>(key: string): Promise<StoreItem<T, TValue>>;
|
|
16
|
+
set<TValue = any>(metadataRecord: T, value: TValue): Promise<string>;
|
|
17
|
+
getOrSet<TValue = any>(metadataRecord: T, factory: (metadataRecord: T) => TValue): Promise<StoreItem<T, TValue>>;
|
|
18
|
+
bulkGet<TValue = any>(keys: string[]): Promise<StoreItem<T, TValue>[]>;
|
|
19
|
+
bulkSet<TValue = any>(metadataRecords: T[], dataRecords: DataRecord<TValue>[]): Promise<string[]>;
|
|
20
20
|
}
|
|
21
21
|
//# sourceMappingURL=cacheContracts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheContracts.d.ts","sourceRoot":"","sources":["../../src/cache/cacheContracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG/E,qBAAa,mBAAoB,SAAQ,cAAc;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,mBAAmB,GAAG,mBAAmB;IAEjF,
|
|
1
|
+
{"version":3,"file":"cacheContracts.d.ts","sourceRoot":"","sources":["../../src/cache/cacheContracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG/E,qBAAa,mBAAoB,SAAQ,cAAc;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,mBAAmB,GAAG,mBAAmB;IAEjF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAExC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAE9D,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAErE,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,cAAc,EAAE,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;IAEhH,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAEvE,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACrG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheContracts.es.js","sources":["D:/Src/my/actdim/public/utico/src/cache/cacheContracts.ts"],"sourcesContent":["import { DataRecord, MetadataRecord, StoreItem } from \"@/store/storeContracts\";\r\n\r\n// CacheMetadataEntry\r\nexport class CacheMetadataRecord extends MetadataRecord {\r\n accessedAt?: number; // lastAccessed/lastAccessTime\r\n slidingExpiration?: number;\r\n absoluteExpiration?: number;\r\n expiresAt?: number; // expiryTime\r\n}\r\n\r\nexport interface IPersistentCache<T extends CacheMetadataRecord = CacheMetadataRecord> {\r\n\r\n
|
|
1
|
+
{"version":3,"file":"cacheContracts.es.js","sources":["D:/Src/my/actdim/public/utico/src/cache/cacheContracts.ts"],"sourcesContent":["import { DataRecord, MetadataRecord, StoreItem } from \"@/store/storeContracts\";\r\n\r\n// CacheMetadataEntry\r\nexport class CacheMetadataRecord extends MetadataRecord {\r\n accessedAt?: number; // lastAccessed/lastAccessTime\r\n slidingExpiration?: number;\r\n absoluteExpiration?: number;\r\n expiresAt?: number; // expiryTime\r\n}\r\n\r\nexport interface IPersistentCache<T extends CacheMetadataRecord = CacheMetadataRecord> {\r\n\r\n open(): Promise<void>;\r\n\r\n getKeys(): Promise<string[]>;\r\n\r\n contains(key: string): Promise<boolean>;\r\n\r\n delete(key: string): Promise<void>;\r\n\r\n bulkDelete(keys: string[]): Promise<void>;\r\n\r\n clear(): Promise<void>;\r\n\r\n get<TValue = any>(key: string): Promise<StoreItem<T, TValue>>;\r\n\r\n set<TValue = any>(metadataRecord: T, value: TValue): Promise<string>;\r\n\r\n getOrSet<TValue = any>(metadataRecord: T, factory: (metadataRecord: T) => TValue): Promise<StoreItem<T, TValue>>\r\n\r\n bulkGet<TValue = any>(keys: string[]): Promise<StoreItem<T, TValue>[]>;\r\n\r\n bulkSet<TValue = any>(metadataRecords: T[], dataRecords: DataRecord<TValue>[]): Promise<string[]>;\r\n}"],"names":["CacheMetadataRecord","MetadataRecord"],"mappings":";AAGO,MAAMA,UAA4BC,EAAe;AAAA,EACpD;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AACJ;"}
|
|
@@ -26,27 +26,27 @@ export declare class PersistentCache extends StructEventTarget<PersistentCacheEv
|
|
|
26
26
|
protected _isDisposed: boolean;
|
|
27
27
|
private _jobTimerId;
|
|
28
28
|
private readonly _options;
|
|
29
|
-
static
|
|
30
|
-
static
|
|
31
|
-
static
|
|
29
|
+
static delete(name: string): Promise<void>;
|
|
30
|
+
static exists(name: string): Promise<boolean>;
|
|
31
|
+
static open(name: string, options?: PersistentCacheOptions): Promise<PersistentCache>;
|
|
32
32
|
constructor(name: string, options: PersistentCacheOptions);
|
|
33
|
-
dispose(): void;
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
[Symbol.dispose](): void;
|
|
34
|
+
open(): any;
|
|
35
|
+
private exec;
|
|
36
|
+
getKeys(): Promise<string[]>;
|
|
37
|
+
contains(key: string): Promise<boolean>;
|
|
38
|
+
delete(key: string): Promise<void>;
|
|
39
|
+
bulkDelete(keys: string[]): Promise<void>;
|
|
40
|
+
clear(): Promise<void>;
|
|
41
41
|
private onGetMetadata;
|
|
42
42
|
scheduleServiceJob(): void;
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
deleteExpired(ts?: number): Promise<string[]>;
|
|
44
|
+
get<TValue = any>(key: string): Promise<StoreItem<CacheMetadataRecord, TValue>>;
|
|
45
45
|
private onCreateMetadata;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
set<TValue = any>(metadataRecord: CacheMetadataRecord, value: TValue, options: CacheOptions): Promise<string>;
|
|
47
|
+
getOrSet<TValue = any>(metadataRecord: CacheMetadataRecord, factory: (metadataRecord: CacheMetadataRecord) => TValue, options: CacheOptions): Promise<StoreItem<CacheMetadataRecord, any>>;
|
|
48
|
+
bulkGet<TValue = any>(keys: string[]): Promise<StoreItem<CacheMetadataRecord, TValue>[]>;
|
|
49
|
+
bulkSet<TValue = any>(metadataRecords: CacheMetadataRecord[], dataRecords: DataRecord<TValue>[], optionsProvider: (record: MetadataRecord) => CacheOptions): Promise<string[]>;
|
|
50
50
|
}
|
|
51
51
|
export {};
|
|
52
52
|
//# sourceMappingURL=persistentCache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistentCache.d.ts","sourceRoot":"","sources":["../../src/cache/persistentCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAY,cAAc,EAAE,SAAS,EAAmB,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,KAAK,QAAQ,GAAG,MAAM,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,sBAAsB,GAAG;IACjC,cAAc,EAAE,MAAM,CAAC;CAC1B,CAAC;AAMF,MAAM,MAAM,YAAY,GAAG;IACvB,kBAAkB,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACnC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAGF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAClC,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAC9B,KAAK,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAOF,qBAAa,eAAgB,SAAQ,iBAAiB,CAAC,0BAA0B,CAAC;IAE9E,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAE5C,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC;IAE/B,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAElD,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"persistentCache.d.ts","sourceRoot":"","sources":["../../src/cache/persistentCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAY,cAAc,EAAE,SAAS,EAAmB,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,KAAK,QAAQ,GAAG,MAAM,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,sBAAsB,GAAG;IACjC,cAAc,EAAE,MAAM,CAAC;CAC1B,CAAC;AAMF,MAAM,MAAM,YAAY,GAAG;IACvB,kBAAkB,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACnC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAGF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAClC,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAC9B,KAAK,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAOF,qBAAa,eAAgB,SAAQ,iBAAiB,CAAC,0BAA0B,CAAC;IAE9E,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAE5C,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC;IAE/B,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAElD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM;IAI1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM;IAI1B,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB;gBAK9C,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB;IAezD,CAAC,MAAM,CAAC,OAAO,CAAC;IAWhB,IAAI;IAIJ,OAAO,CAAC,IAAI;IAMZ,OAAO;IAIP,QAAQ,CAAC,GAAG,EAAE,MAAM;IAIpB,MAAM,CAAC,GAAG,EAAE,MAAM;IAKlB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE;IAKzB,KAAK;IAIL,OAAO,CAAC,aAAa;IAqBrB,kBAAkB;IAiBZ,aAAa,CAAC,EAAE,CAAC,EAAE,MAAM;IAwB/B,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAa/E,OAAO,CAAC,gBAAgB;IAwBxB,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,cAAc,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;IAqB3F,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,cAAc,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC,cAAc,EAAE,mBAAmB,KAAK,MAAM,EAAE,OAAO,EAAE,YAAY;IAe3I,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE;IAqBpC,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,eAAe,EAAE,mBAAmB,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,eAAe,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,YAAY;CA4B7J"}
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { keyOf as
|
|
2
|
-
import { StructEventTarget as u, StructEvent as
|
|
1
|
+
import { keyOf as l } from "../typeUtils.es.js";
|
|
2
|
+
import { StructEventTarget as u, StructEvent as d } from "../structEvent.es.js";
|
|
3
3
|
import { v4 as r } from "uuid";
|
|
4
4
|
import { StoreDb as n } from "../store/storeDb.es.js";
|
|
5
|
-
const
|
|
5
|
+
const b = {
|
|
6
6
|
cleanupTimeout: 1e3
|
|
7
|
-
},
|
|
7
|
+
}, h = ["&key", "createdAt", "updatedAt", "tags", "accessedAt", "expiresAt"];
|
|
8
8
|
class o extends u {
|
|
9
9
|
_db;
|
|
10
10
|
_isDisposed;
|
|
11
11
|
_jobTimerId;
|
|
12
12
|
_options;
|
|
13
|
-
static
|
|
14
|
-
return n.
|
|
13
|
+
static delete(t) {
|
|
14
|
+
return n.delete(t);
|
|
15
15
|
}
|
|
16
|
-
static
|
|
17
|
-
return n.
|
|
16
|
+
static exists(t) {
|
|
17
|
+
return n.exists(t);
|
|
18
18
|
}
|
|
19
|
-
static
|
|
20
|
-
return n.
|
|
19
|
+
static open(t, e) {
|
|
20
|
+
return n.open(t, () => new o(t, e));
|
|
21
21
|
}
|
|
22
22
|
// cleanupTimeout - serviceJobTimeout
|
|
23
23
|
constructor(t, e) {
|
|
24
24
|
if (super(), !t)
|
|
25
25
|
throw new Error("Name cannot be empty.");
|
|
26
|
-
this._options = { ...e, ...
|
|
26
|
+
this._options = { ...e, ...b }, this._db = new n(t, h), this._jobTimerId = null, this.scheduleServiceJob();
|
|
27
27
|
}
|
|
28
|
-
dispose() {
|
|
29
|
-
this._isDisposed || this._jobTimerId && (window.clearTimeout(this._jobTimerId), this._jobTimerId = null), this._db?.dispose(), this._db = null;
|
|
28
|
+
[Symbol.dispose]() {
|
|
29
|
+
this._isDisposed || this._jobTimerId && (window.clearTimeout(this._jobTimerId), this._jobTimerId = null), this._db?.[Symbol.dispose](), this._db = null;
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
return this._db.
|
|
31
|
+
open() {
|
|
32
|
+
return this._db.open();
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
return this._db.
|
|
34
|
+
exec(t, e = "r!") {
|
|
35
|
+
return this._db.exec(t, e);
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
return this._db.
|
|
37
|
+
getKeys() {
|
|
38
|
+
return this._db.getKeys();
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
return this._db.
|
|
40
|
+
contains(t) {
|
|
41
|
+
return this._db.contains(t);
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
return this._db.
|
|
43
|
+
delete(t) {
|
|
44
|
+
return this._db.deleteOne(t);
|
|
45
45
|
}
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
return this._db.
|
|
46
|
+
// deleteMany
|
|
47
|
+
bulkDelete(t) {
|
|
48
|
+
return this._db.bulkDelete(t);
|
|
49
49
|
}
|
|
50
50
|
// clearAllAsync
|
|
51
|
-
|
|
52
|
-
return this._db.
|
|
51
|
+
clear() {
|
|
52
|
+
return this._db.clear();
|
|
53
53
|
}
|
|
54
54
|
onGetMetadata(t) {
|
|
55
55
|
const e = Date.now();
|
|
@@ -61,7 +61,7 @@ class o extends u {
|
|
|
61
61
|
if (this._options.cleanupTimeout) {
|
|
62
62
|
const t = async () => {
|
|
63
63
|
try {
|
|
64
|
-
await this.
|
|
64
|
+
await this.deleteExpired();
|
|
65
65
|
} catch (e) {
|
|
66
66
|
console.error("Cache cleanup failed:", e);
|
|
67
67
|
} finally {
|
|
@@ -72,16 +72,16 @@ class o extends u {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
// evictExpiredAsync/clearExpiredAsync
|
|
75
|
-
async
|
|
75
|
+
async deleteExpired(t) {
|
|
76
76
|
const e = [];
|
|
77
77
|
t || (t = Date.now());
|
|
78
78
|
let i;
|
|
79
|
-
if (await this.
|
|
80
|
-
i = await this._db.metadata.where(
|
|
79
|
+
if (await this.exec(async () => {
|
|
80
|
+
i = await this._db.metadata.where(l("expiresAt")).below(t).toArray();
|
|
81
81
|
const s = i.map((a) => a.key);
|
|
82
|
-
await this.
|
|
82
|
+
await this.bulkDelete(s);
|
|
83
83
|
}, "rw"), i?.length) {
|
|
84
|
-
const s = new
|
|
84
|
+
const s = new d("evict", {
|
|
85
85
|
detail: {
|
|
86
86
|
records: i
|
|
87
87
|
},
|
|
@@ -92,8 +92,8 @@ class o extends u {
|
|
|
92
92
|
}
|
|
93
93
|
return e;
|
|
94
94
|
}
|
|
95
|
-
|
|
96
|
-
return this.
|
|
95
|
+
get(t) {
|
|
96
|
+
return this.exec(async () => {
|
|
97
97
|
const e = await this._db.metadata.get(t);
|
|
98
98
|
this.onGetMetadata(e), await this._db.metadata.put(e);
|
|
99
99
|
const i = await this._db.data.get(t);
|
|
@@ -107,11 +107,11 @@ class o extends u {
|
|
|
107
107
|
const i = Date.now();
|
|
108
108
|
t.createdAt = i, t.updatedAt = i, t.accessedAt = i, t.slidingExpiration = e.slidingExpiration, typeof e.absoluteExpiration == "number" ? t.absoluteExpiration = e.absoluteExpiration : e.absoluteExpiration instanceof Date && (t.absoluteExpiration = e.absoluteExpiration.getTime()), typeof e.ttl == "number" && (t.absoluteExpiration = i + e.ttl), t.absoluteExpiration == null && (t.absoluteExpiration = 1 / 0), this.onGetMetadata(t);
|
|
109
109
|
}
|
|
110
|
-
//
|
|
111
|
-
|
|
110
|
+
// upsert
|
|
111
|
+
set(t, e, i) {
|
|
112
112
|
if (e === void 0)
|
|
113
113
|
throw new Error('Invalid parameter: "value".');
|
|
114
|
-
return t.key || (t.key = r()), this.onCreateMetadata(t, i), this.
|
|
114
|
+
return t.key || (t.key = r()), this.onCreateMetadata(t, i), this.exec(async () => {
|
|
115
115
|
const s = await this._db.metadata.put(t);
|
|
116
116
|
return await this._db.data.put({
|
|
117
117
|
key: t.key,
|
|
@@ -119,18 +119,18 @@ class o extends u {
|
|
|
119
119
|
}), s;
|
|
120
120
|
}, "rw");
|
|
121
121
|
}
|
|
122
|
-
//
|
|
123
|
-
|
|
122
|
+
// getOrAdd
|
|
123
|
+
getOrSet(t, e, i) {
|
|
124
124
|
if (!t.key)
|
|
125
125
|
throw new Error('Key cannot be empty. Parameter: "metadataRecord".');
|
|
126
|
-
return this.
|
|
127
|
-
const s = await this.
|
|
128
|
-
return s || (await this.
|
|
126
|
+
return this.exec(async () => {
|
|
127
|
+
const s = await this.get(t.key);
|
|
128
|
+
return s || (await this.set(t, e(t), i), this.get(t.key));
|
|
129
129
|
}, "rw");
|
|
130
130
|
}
|
|
131
131
|
// getMany
|
|
132
|
-
|
|
133
|
-
return this.
|
|
132
|
+
bulkGet(t) {
|
|
133
|
+
return this.exec(async () => {
|
|
134
134
|
const e = /* @__PURE__ */ new Map(), i = await this._db.metadata.bulkGet(t);
|
|
135
135
|
for (const a of i)
|
|
136
136
|
this.onGetMetadata(a), e.set(a.key, {
|
|
@@ -145,7 +145,7 @@ class o extends u {
|
|
|
145
145
|
}, "rw");
|
|
146
146
|
}
|
|
147
147
|
// setMeny
|
|
148
|
-
|
|
148
|
+
bulkSet(t, e, i) {
|
|
149
149
|
let s;
|
|
150
150
|
if (t && (s = t.findIndex((a) => !a)) >= 0)
|
|
151
151
|
throw new Error(`Invalid metadata record. Parameter: "metadataRecords". Index: ${s}.`);
|
|
@@ -155,7 +155,7 @@ class o extends u {
|
|
|
155
155
|
throw new Error("No data provided.");
|
|
156
156
|
for (const a of t)
|
|
157
157
|
a.key || (a.key = r()), this.onCreateMetadata(a, i(a));
|
|
158
|
-
return this.
|
|
158
|
+
return this.exec(async () => {
|
|
159
159
|
let a;
|
|
160
160
|
return t && (a = await this._db.metadata.bulkPut(t, void 0, { allKeys: !0 })), e && await this._db.data.bulkPut(e, void 0, { allKeys: !0 }), a;
|
|
161
161
|
}, "rw");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistentCache.es.js","sources":["D:/Src/my/actdim/public/utico/src/cache/persistentCache.ts"],"sourcesContent":["import { keyOf } from \"@/typeUtils\";\r\nimport { StructEvent, StructEventTarget } from \"@/structEvent\";\r\nimport { v4 as uuid } from \"uuid\";\r\nimport { DataRecord, FieldDef, MetadataRecord, StoreItem, TransactionMode } from \"@/store/storeContracts\";\r\nimport { CacheMetadataRecord } from \"./cacheContracts\";\r\nimport { StoreDb } from \"@/store/storeDb\";\r\n\r\ntype Duration = number | { seconds?: number; minutes?: number; hours?: number };\r\n\r\nexport type PersistentCacheOptions = {\r\n cleanupTimeout: number;\r\n};\r\n\r\nconst defaultPersistentCacheOptions = {\r\n cleanupTimeout: 1000\r\n} satisfies PersistentCacheOptions;\r\n\r\nexport type CacheOptions = {\r\n absoluteExpiration?: Date | number;\r\n ttl?: Duration;\r\n slidingExpiration?: number; // \"autoRenewOnUse\" pattern\r\n};\r\n\r\n// CacheEntryEvictionEvent\r\nexport type CacheEvictionEvent = {\r\n records: CacheMetadataRecord[];\r\n};\r\n\r\ntype PersistentCacheEventStruct = {\r\n evict: CacheEvictionEvent;\r\n};\r\n\r\n// (registry/catalog)fieldNames\r\nconst metadataFieldDefTemplate = [\"&key\", \"createdAt\", \"updatedAt\", \"tags\", \"accessedAt\", \"expiresAt\"] satisfies (FieldDef<keyof CacheMetadataRecord>)[];\r\n\r\n// implements Struct<StructEventTarget<PersistentCacheEventStruct>>\r\n// PersistentCacheManager\r\nexport class PersistentCache extends StructEventTarget<PersistentCacheEventStruct> {\r\n\r\n protected _db: StoreDb<CacheMetadataRecord>;\r\n\r\n protected _isDisposed: boolean;\r\n\r\n private _jobTimerId: number;\r\n\r\n private readonly _options: PersistentCacheOptions;\r\n\r\n static deleteAsync(name: string) {\r\n return StoreDb.deleteAsync(name);\r\n }\r\n\r\n static existsAsync(name: string) {\r\n return StoreDb.existsAsync(name);\r\n }\r\n\r\n static openAsync(name: string, options?: PersistentCacheOptions) {\r\n return StoreDb.openAsync(name, () => new PersistentCache(name, options));\r\n }\r\n\r\n // cleanupTimeout - serviceJobTimeout\r\n constructor(name: string, options: PersistentCacheOptions) {\r\n super();\r\n if (!name) {\r\n throw new Error(\"Name cannot be empty.\");\r\n }\r\n this._options = { ...options, ...defaultPersistentCacheOptions };\r\n\r\n this._db = new StoreDb<CacheMetadataRecord>(name, metadataFieldDefTemplate);\r\n\r\n this._jobTimerId = null;\r\n\r\n // https://docs.nestjs.com/techniques/task-scheduling\r\n this.scheduleServiceJob();\r\n }\r\n\r\n dispose() {\r\n if (!this._isDisposed) {\r\n if (this._jobTimerId) {\r\n window.clearTimeout(this._jobTimerId);\r\n this._jobTimerId = null;\r\n }\r\n }\r\n this._db?.dispose();\r\n this._db = null;\r\n }\r\n\r\n openAsync() {\r\n return this._db.openAsync()\r\n }\r\n\r\n private execAsync<T>(\r\n action: () => Promise<T>, // scope\r\n transactionMode: TransactionMode = \"r!\") {\r\n return this._db.execAsync(action, transactionMode);\r\n }\r\n\r\n getKeysAsync() {\r\n return this._db.getKeysAsync();\r\n }\r\n\r\n containsAsync(key: string) {\r\n return this._db.containsAsync(key);\r\n }\r\n\r\n deleteAsync(key: string) {\r\n return this._db.deleteAsync(key);\r\n }\r\n\r\n // deleteManyAsync\r\n bulkDeleteAsync(keys: string[]) {\r\n return this._db.bulkDeleteAsync(keys);\r\n }\r\n\r\n // clearAllAsync\r\n clearAsync() {\r\n return this._db.clearAsync();\r\n }\r\n\r\n private onGetMetadata(record: CacheMetadataRecord) {\r\n const now = Date.now();\r\n record.accessedAt = now;\r\n\r\n let newExpiresAt = record.expiresAt ?? now;\r\n\r\n if (typeof record.slidingExpiration === 'number' && record.slidingExpiration > 0) {\r\n newExpiresAt = now + record.slidingExpiration;\r\n }\r\n\r\n if (\r\n typeof record.absoluteExpiration === 'number' &&\r\n record.absoluteExpiration > 0 &&\r\n newExpiresAt > record.absoluteExpiration\r\n ) {\r\n newExpiresAt = record.absoluteExpiration;\r\n }\r\n\r\n record.expiresAt = newExpiresAt;\r\n }\r\n\r\n scheduleServiceJob() {\r\n if (this._options.cleanupTimeout) {\r\n const doWork = async () => {\r\n try {\r\n // purge expired entries\r\n await this.deleteExpiredAsync();\r\n } catch (err) {\r\n console.error(\"Cache cleanup failed:\", err);\r\n } finally {\r\n setTimeout(doWork, this._options.cleanupTimeout);\r\n }\r\n };\r\n setTimeout(doWork, this._options.cleanupTimeout);\r\n }\r\n }\r\n\r\n // evictExpiredAsync/clearExpiredAsync\r\n async deleteExpiredAsync(ts?: number) {\r\n const result: string[] = []; // output keys\r\n if (!ts) {\r\n ts = Date.now();\r\n }\r\n let metadataRecords: MetadataRecord[];\r\n await this.execAsync(async () => {\r\n metadataRecords = await this._db.metadata.where(keyOf<CacheMetadataRecord>(\"expiresAt\")).below(ts).toArray();\r\n const keys = metadataRecords.map(x => x.key);\r\n await this.bulkDeleteAsync(keys);\r\n }, \"rw\");\r\n if (metadataRecords?.length) {\r\n const evt = new StructEvent<PersistentCacheEventStruct, this>(\"evict\", {\r\n detail: {\r\n records: metadataRecords\r\n },\r\n target: this,\r\n cancelable: true\r\n });\r\n this.dispatchEvent(evt);\r\n }\r\n return result;\r\n }\r\n\r\n getAsync<TValue = any>(key: string): Promise<StoreItem<CacheMetadataRecord, TValue>> {\r\n return this.execAsync(async () => {\r\n const metadataRecord = await this._db.metadata.get(key);\r\n this.onGetMetadata(metadataRecord);\r\n await this._db.metadata.put(metadataRecord);\r\n const dataRecord = await this._db.data.get(key);\r\n return {\r\n metadata: metadataRecord,\r\n data: dataRecord\r\n } as StoreItem<CacheMetadataRecord, TValue>;\r\n }, \"rw\");\r\n }\r\n\r\n private onCreateMetadata(record: CacheMetadataRecord, options: CacheOptions) {\r\n const now = Date.now();\r\n\r\n record.createdAt = now;\r\n record.updatedAt = now;\r\n record.accessedAt = now;\r\n\r\n record.slidingExpiration = options.slidingExpiration;\r\n if (typeof options.absoluteExpiration === \"number\") {\r\n record.absoluteExpiration = options.absoluteExpiration;\r\n } else if (options.absoluteExpiration instanceof Date) {\r\n record.absoluteExpiration = options.absoluteExpiration.getTime();\r\n }\r\n if (typeof options.ttl === \"number\") {\r\n record.absoluteExpiration = now + options.ttl;\r\n }\r\n if (record.absoluteExpiration == undefined) {\r\n record.absoluteExpiration = Infinity\r\n }\r\n\r\n this.onGetMetadata(record);\r\n\r\n }\r\n // upsertAsync\r\n setAsync<TValue = any>(metadataRecord: CacheMetadataRecord, value: TValue, options: CacheOptions) {\r\n if (value === undefined) {\r\n throw new Error('Invalid parameter: \"value\".');\r\n }\r\n if (!metadataRecord.key) {\r\n metadataRecord.key = uuid();\r\n }\r\n\r\n this.onCreateMetadata(metadataRecord, options);\r\n\r\n return this.execAsync(async () => {\r\n const result = await this._db.metadata.put(metadataRecord);\r\n await this._db.data.put({\r\n key: metadataRecord.key,\r\n value: value\r\n });\r\n return result;\r\n }, \"rw\");\r\n }\r\n\r\n // getOrAddAsync\r\n getOrSetAsync<TValue = any>(metadataRecord: CacheMetadataRecord, factory: (metadataRecord: CacheMetadataRecord) => TValue, options: CacheOptions) {\r\n if (!metadataRecord.key) {\r\n throw new Error(`Key cannot be empty. Parameter: \"metadataRecord\".`);\r\n }\r\n return this.execAsync(async () => {\r\n const existingStoreItem = await this.getAsync(metadataRecord.key);\r\n if (existingStoreItem) {\r\n return existingStoreItem;\r\n }\r\n await this.setAsync(metadataRecord, factory(metadataRecord), options);\r\n return this.getAsync(metadataRecord.key);\r\n }, \"rw\");\r\n }\r\n\r\n // getMany\r\n bulkGetAsync<TValue = any>(keys: string[]) {\r\n return this.execAsync(async () => {\r\n const map = new Map<string, StoreItem<CacheMetadataRecord, TValue>>();\r\n const metadataRecords = await this._db.metadata.bulkGet(keys);\r\n for (const metadataRecord of metadataRecords) {\r\n this.onGetMetadata(metadataRecord);\r\n map.set(metadataRecord.key, {\r\n metadata: metadataRecord,\r\n // data: undefined\r\n });\r\n }\r\n await this._db.metadata.bulkPut(metadataRecords);\r\n const dataRecords = await this._db.data.bulkGet(keys);\r\n for (const dataRecord of dataRecords) {\r\n map.get(dataRecord.key).data = dataRecord;\r\n }\r\n return [...map.values()];\r\n }, \"rw\");\r\n }\r\n\r\n // setMeny\r\n bulkSetAsync<TValue = any>(metadataRecords: CacheMetadataRecord[], dataRecords: DataRecord<TValue>[], optionsProvider: (record: MetadataRecord) => CacheOptions) {\r\n let index: number;\r\n if (metadataRecords && (index = metadataRecords.findIndex(x => !x)) >= 0) {\r\n throw new Error(`Invalid metadata record. Parameter: \"metadataRecords\". Index: ${index}.`);\r\n }\r\n if (dataRecords && (index = dataRecords.findIndex(x => (!x || !x.key || x.value === undefined))) >= 0) {\r\n throw new Error(`Invalid data record. Parameter: \"dataRecords\". Index: ${index}.`);\r\n }\r\n if (!metadataRecords && !dataRecords) {\r\n throw new Error(\"No data provided.\");\r\n }\r\n for (const metadataRecord of metadataRecords) {\r\n if (!metadataRecord.key) {\r\n metadataRecord.key = uuid();\r\n }\r\n this.onCreateMetadata(metadataRecord, optionsProvider(metadataRecord));\r\n }\r\n return this.execAsync(async () => {\r\n let mKeys: string[], dKeys: string[];\r\n if (metadataRecords) {\r\n mKeys = await this._db.metadata.bulkPut(metadataRecords, undefined, { allKeys: true });\r\n }\r\n if (dataRecords) {\r\n dKeys = await this._db.data.bulkPut(dataRecords, undefined, { allKeys: true });\r\n }\r\n return mKeys;\r\n }, \"rw\");\r\n }\r\n}\r\n\r\n// extra links:\r\n// https://demo.agektmr.com/storage/\r\n// https://www.html5rocks.com/en/tutorials/offline/quota-research/\r\n// https://www.raymondcamden.com/2015/04/17/indexeddb-and-limits\r\n// https://github.com/jonnysmith1981/getIndexedDbSize/blob/master/getIndexedDbSize.js\r\n// https://developer.chrome.com/apps/offline_storage#query\r\n// https://golb.hplar.ch/2018/01/IndexedDB-programming-with-Dexie-js.html\r\n// http://www.forerunnerdb.com/licensing.html\r\n// https://github.com/ignasbernotas/dexie-relationships\r\n// https://medium.com/square-corner-blog/useful-tools-headless-chrome-puppeteer-for-browser-automation-testing-1ac7707bad40\r\n// https://developers.google.com/web/updates/2017/06/headless-karma-mocha-chai?hl=ru\r\n// https://github.com/puppeteer/puppeteer\r\n// https://medium.com/web-standards/puppeteer-crawl-to-markdown-7752dff36b68\r\n\r\n/*\r\n(async () => {\r\n const alreadyPersisted = await window.navigator.storage?.persisted()\r\n\r\n if (alreadyPersisted) {\r\n return;\r\n }\r\n\r\n const persistentModeEnabled = await window.navigator.storage?.persist()\r\n\r\n if (!persistentModeEnabled) { \r\n // Storage may be cleared by the UA under storage pressure\r\n } else {\r\n // Storage will be persistent\r\n // Storage will not be cleared except by explicit user action\r\n }\r\n})();\r\n*/\r\n"],"names":["defaultPersistentCacheOptions","metadataFieldDefTemplate","PersistentCache","StructEventTarget","name","StoreDb","options","action","transactionMode","key","keys","record","now","newExpiresAt","doWork","err","ts","result","metadataRecords","keyOf","x","evt","StructEvent","metadataRecord","dataRecord","value","uuid","factory","existingStoreItem","map","dataRecords","optionsProvider","index","mKeys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"persistentCache.es.js","sources":["D:/Src/my/actdim/public/utico/src/cache/persistentCache.ts"],"sourcesContent":["import { keyOf } from \"@/typeUtils\";\r\nimport { StructEvent, StructEventTarget } from \"@/structEvent\";\r\nimport { v4 as uuid } from \"uuid\";\r\nimport { DataRecord, FieldDef, MetadataRecord, StoreItem, TransactionMode } from \"@/store/storeContracts\";\r\nimport { CacheMetadataRecord } from \"./cacheContracts\";\r\nimport { StoreDb } from \"@/store/storeDb\";\r\n\r\ntype Duration = number | { seconds?: number; minutes?: number; hours?: number };\r\n\r\nexport type PersistentCacheOptions = {\r\n cleanupTimeout: number;\r\n};\r\n\r\nconst defaultPersistentCacheOptions = {\r\n cleanupTimeout: 1000\r\n} satisfies PersistentCacheOptions;\r\n\r\nexport type CacheOptions = {\r\n absoluteExpiration?: Date | number;\r\n ttl?: Duration;\r\n slidingExpiration?: number; // \"autoRenewOnUse\" pattern\r\n};\r\n\r\n// CacheEntryEvictionEvent\r\nexport type CacheEvictionEvent = {\r\n records: CacheMetadataRecord[];\r\n};\r\n\r\ntype PersistentCacheEventStruct = {\r\n evict: CacheEvictionEvent;\r\n};\r\n\r\n// (registry/catalog)fieldNames\r\nconst metadataFieldDefTemplate = [\"&key\", \"createdAt\", \"updatedAt\", \"tags\", \"accessedAt\", \"expiresAt\"] satisfies (FieldDef<keyof CacheMetadataRecord>)[];\r\n\r\n// implements Struct<StructEventTarget<PersistentCacheEventStruct>>\r\n// PersistentCacheManager\r\nexport class PersistentCache extends StructEventTarget<PersistentCacheEventStruct> {\r\n\r\n protected _db: StoreDb<CacheMetadataRecord>;\r\n\r\n protected _isDisposed: boolean;\r\n\r\n private _jobTimerId: number;\r\n\r\n private readonly _options: PersistentCacheOptions;\r\n\r\n static delete(name: string) {\r\n return StoreDb.delete(name);\r\n }\r\n\r\n static exists(name: string) {\r\n return StoreDb.exists(name);\r\n }\r\n\r\n static open(name: string, options?: PersistentCacheOptions) {\r\n return StoreDb.open(name, () => new PersistentCache(name, options));\r\n }\r\n\r\n // cleanupTimeout - serviceJobTimeout\r\n constructor(name: string, options: PersistentCacheOptions) {\r\n super();\r\n if (!name) {\r\n throw new Error(\"Name cannot be empty.\");\r\n }\r\n this._options = { ...options, ...defaultPersistentCacheOptions };\r\n\r\n this._db = new StoreDb<CacheMetadataRecord>(name, metadataFieldDefTemplate);\r\n\r\n this._jobTimerId = null;\r\n\r\n // https://docs.nestjs.com/techniques/task-scheduling\r\n this.scheduleServiceJob();\r\n }\r\n\r\n [Symbol.dispose]() {\r\n if (!this._isDisposed) {\r\n if (this._jobTimerId) {\r\n window.clearTimeout(this._jobTimerId);\r\n this._jobTimerId = null;\r\n }\r\n }\r\n this._db?.[Symbol.dispose]();\r\n this._db = null;\r\n }\r\n\r\n open() {\r\n return this._db.open()\r\n }\r\n\r\n private exec<T>(\r\n action: () => Promise<T>, // scope\r\n transactionMode: TransactionMode = \"r!\") {\r\n return this._db.exec(action, transactionMode);\r\n }\r\n\r\n getKeys() {\r\n return this._db.getKeys();\r\n }\r\n\r\n contains(key: string) {\r\n return this._db.contains(key);\r\n }\r\n\r\n delete(key: string) {\r\n return this._db.deleteOne(key);\r\n }\r\n\r\n // deleteMany\r\n bulkDelete(keys: string[]) {\r\n return this._db.bulkDelete(keys);\r\n }\r\n\r\n // clearAllAsync\r\n clear() {\r\n return this._db.clear();\r\n }\r\n\r\n private onGetMetadata(record: CacheMetadataRecord) {\r\n const now = Date.now();\r\n record.accessedAt = now;\r\n\r\n let newExpiresAt = record.expiresAt ?? now;\r\n\r\n if (typeof record.slidingExpiration === 'number' && record.slidingExpiration > 0) {\r\n newExpiresAt = now + record.slidingExpiration;\r\n }\r\n\r\n if (\r\n typeof record.absoluteExpiration === 'number' &&\r\n record.absoluteExpiration > 0 &&\r\n newExpiresAt > record.absoluteExpiration\r\n ) {\r\n newExpiresAt = record.absoluteExpiration;\r\n }\r\n\r\n record.expiresAt = newExpiresAt;\r\n }\r\n\r\n scheduleServiceJob() {\r\n if (this._options.cleanupTimeout) {\r\n const doWork = async () => {\r\n try {\r\n // purge expired entries\r\n await this.deleteExpired();\r\n } catch (err) {\r\n console.error(\"Cache cleanup failed:\", err);\r\n } finally {\r\n setTimeout(doWork, this._options.cleanupTimeout);\r\n }\r\n };\r\n setTimeout(doWork, this._options.cleanupTimeout);\r\n }\r\n }\r\n\r\n // evictExpiredAsync/clearExpiredAsync\r\n async deleteExpired(ts?: number) {\r\n const result: string[] = []; // output keys\r\n if (!ts) {\r\n ts = Date.now();\r\n }\r\n let metadataRecords: MetadataRecord[];\r\n await this.exec(async () => {\r\n metadataRecords = await this._db.metadata.where(keyOf<CacheMetadataRecord>(\"expiresAt\")).below(ts).toArray();\r\n const keys = metadataRecords.map(x => x.key);\r\n await this.bulkDelete(keys);\r\n }, \"rw\");\r\n if (metadataRecords?.length) {\r\n const evt = new StructEvent<PersistentCacheEventStruct, this>(\"evict\", {\r\n detail: {\r\n records: metadataRecords\r\n },\r\n target: this,\r\n cancelable: true\r\n });\r\n this.dispatchEvent(evt);\r\n }\r\n return result;\r\n }\r\n\r\n get<TValue = any>(key: string): Promise<StoreItem<CacheMetadataRecord, TValue>> {\r\n return this.exec(async () => {\r\n const metadataRecord = await this._db.metadata.get(key);\r\n this.onGetMetadata(metadataRecord);\r\n await this._db.metadata.put(metadataRecord);\r\n const dataRecord = await this._db.data.get(key);\r\n return {\r\n metadata: metadataRecord,\r\n data: dataRecord\r\n } as StoreItem<CacheMetadataRecord, TValue>;\r\n }, \"rw\");\r\n }\r\n\r\n private onCreateMetadata(record: CacheMetadataRecord, options: CacheOptions) {\r\n const now = Date.now();\r\n\r\n record.createdAt = now;\r\n record.updatedAt = now;\r\n record.accessedAt = now;\r\n\r\n record.slidingExpiration = options.slidingExpiration;\r\n if (typeof options.absoluteExpiration === \"number\") {\r\n record.absoluteExpiration = options.absoluteExpiration;\r\n } else if (options.absoluteExpiration instanceof Date) {\r\n record.absoluteExpiration = options.absoluteExpiration.getTime();\r\n }\r\n if (typeof options.ttl === \"number\") {\r\n record.absoluteExpiration = now + options.ttl;\r\n }\r\n if (record.absoluteExpiration == undefined) {\r\n record.absoluteExpiration = Infinity\r\n }\r\n\r\n this.onGetMetadata(record);\r\n\r\n }\r\n // upsert\r\n set<TValue = any>(metadataRecord: CacheMetadataRecord, value: TValue, options: CacheOptions) {\r\n if (value === undefined) {\r\n throw new Error('Invalid parameter: \"value\".');\r\n }\r\n if (!metadataRecord.key) {\r\n metadataRecord.key = uuid();\r\n }\r\n\r\n this.onCreateMetadata(metadataRecord, options);\r\n\r\n return this.exec(async () => {\r\n const result = await this._db.metadata.put(metadataRecord);\r\n await this._db.data.put({\r\n key: metadataRecord.key,\r\n value: value\r\n });\r\n return result;\r\n }, \"rw\");\r\n }\r\n\r\n // getOrAdd\r\n getOrSet<TValue = any>(metadataRecord: CacheMetadataRecord, factory: (metadataRecord: CacheMetadataRecord) => TValue, options: CacheOptions) {\r\n if (!metadataRecord.key) {\r\n throw new Error(`Key cannot be empty. Parameter: \"metadataRecord\".`);\r\n }\r\n return this.exec(async () => {\r\n const existingStoreItem = await this.get(metadataRecord.key);\r\n if (existingStoreItem) {\r\n return existingStoreItem;\r\n }\r\n await this.set(metadataRecord, factory(metadataRecord), options);\r\n return this.get(metadataRecord.key);\r\n }, \"rw\");\r\n }\r\n\r\n // getMany\r\n bulkGet<TValue = any>(keys: string[]) {\r\n return this.exec(async () => {\r\n const map = new Map<string, StoreItem<CacheMetadataRecord, TValue>>();\r\n const metadataRecords = await this._db.metadata.bulkGet(keys);\r\n for (const metadataRecord of metadataRecords) {\r\n this.onGetMetadata(metadataRecord);\r\n map.set(metadataRecord.key, {\r\n metadata: metadataRecord,\r\n // data: undefined\r\n });\r\n }\r\n await this._db.metadata.bulkPut(metadataRecords);\r\n const dataRecords = await this._db.data.bulkGet(keys);\r\n for (const dataRecord of dataRecords) {\r\n map.get(dataRecord.key).data = dataRecord;\r\n }\r\n return [...map.values()];\r\n }, \"rw\");\r\n }\r\n\r\n // setMeny\r\n bulkSet<TValue = any>(metadataRecords: CacheMetadataRecord[], dataRecords: DataRecord<TValue>[], optionsProvider: (record: MetadataRecord) => CacheOptions) {\r\n let index: number;\r\n if (metadataRecords && (index = metadataRecords.findIndex(x => !x)) >= 0) {\r\n throw new Error(`Invalid metadata record. Parameter: \"metadataRecords\". Index: ${index}.`);\r\n }\r\n if (dataRecords && (index = dataRecords.findIndex(x => (!x || !x.key || x.value === undefined))) >= 0) {\r\n throw new Error(`Invalid data record. Parameter: \"dataRecords\". Index: ${index}.`);\r\n }\r\n if (!metadataRecords && !dataRecords) {\r\n throw new Error(\"No data provided.\");\r\n }\r\n for (const metadataRecord of metadataRecords) {\r\n if (!metadataRecord.key) {\r\n metadataRecord.key = uuid();\r\n }\r\n this.onCreateMetadata(metadataRecord, optionsProvider(metadataRecord));\r\n }\r\n return this.exec(async () => {\r\n let mKeys: string[], dKeys: string[];\r\n if (metadataRecords) {\r\n mKeys = await this._db.metadata.bulkPut(metadataRecords, undefined, { allKeys: true });\r\n }\r\n if (dataRecords) {\r\n dKeys = await this._db.data.bulkPut(dataRecords, undefined, { allKeys: true });\r\n }\r\n return mKeys;\r\n }, \"rw\");\r\n }\r\n}\r\n\r\n// extra links:\r\n// https://demo.agektmr.com/storage/\r\n// https://www.html5rocks.com/en/tutorials/offline/quota-research/\r\n// https://www.raymondcamden.com/2015/04/17/indexeddb-and-limits\r\n// https://github.com/jonnysmith1981/getIndexedDbSize/blob/master/getIndexedDbSize.js\r\n// https://developer.chrome.com/apps/offline_storage#query\r\n// https://golb.hplar.ch/2018/01/IndexedDB-programming-with-Dexie-js.html\r\n// http://www.forerunnerdb.com/licensing.html\r\n// https://github.com/ignasbernotas/dexie-relationships\r\n// https://medium.com/square-corner-blog/useful-tools-headless-chrome-puppeteer-for-browser-automation-testing-1ac7707bad40\r\n// https://developers.google.com/web/updates/2017/06/headless-karma-mocha-chai?hl=ru\r\n// https://github.com/puppeteer/puppeteer\r\n// https://medium.com/web-standards/puppeteer-crawl-to-markdown-7752dff36b68\r\n\r\n/*\r\n(async () => {\r\n const alreadyPersisted = await window.navigator.storage?.persisted()\r\n\r\n if (alreadyPersisted) {\r\n return;\r\n }\r\n\r\n const persistentModeEnabled = await window.navigator.storage?.persist()\r\n\r\n if (!persistentModeEnabled) { \r\n // Storage may be cleared by the UA under storage pressure\r\n } else {\r\n // Storage will be persistent\r\n // Storage will not be cleared except by explicit user action\r\n }\r\n})();\r\n*/\r\n"],"names":["defaultPersistentCacheOptions","metadataFieldDefTemplate","PersistentCache","StructEventTarget","name","StoreDb","options","action","transactionMode","key","keys","record","now","newExpiresAt","doWork","err","ts","result","metadataRecords","keyOf","x","evt","StructEvent","metadataRecord","dataRecord","value","uuid","factory","existingStoreItem","map","dataRecords","optionsProvider","index","mKeys"],"mappings":"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"}
|
|
@@ -4,15 +4,14 @@ export declare function createCanvas(w: number, h: number): {
|
|
|
4
4
|
};
|
|
5
5
|
export type TextSizeProvider = (fontSize: number) => [number, number];
|
|
6
6
|
export declare function fitText(ctx: CanvasRenderingContext2D, text: string, sizeProvider: TextSizeProvider, targetWidth?: number, fontFamily?: string): void;
|
|
7
|
-
export declare const
|
|
7
|
+
export declare const html2Svg: (elements: HTMLElement[], viewBoxSize: number[], css: string) => Promise<string>;
|
|
8
8
|
export declare function getSvgImageObjectUrl(svgData: string): string;
|
|
9
9
|
export declare function getSvgImageDataUrl(svgData: string): string;
|
|
10
10
|
export declare const querySvgData: (selector: string) => string;
|
|
11
11
|
export declare function toObjectUrl(canvas: HTMLCanvasElement, mimeType?: string, quality?: number): Promise<string>;
|
|
12
|
-
export declare function
|
|
13
|
-
export declare const
|
|
14
|
-
export declare function canvasToImage(canvas: HTMLCanvasElement, size?: number[], mimeType?: string, quality?: number): HTMLImageElement
|
|
15
|
-
export declare function canvasToImageAsync(canvas: HTMLCanvasElement, size?: number[], mimeType?: string, quality?: number): Promise<HTMLImageElement>;
|
|
12
|
+
export declare function drawImage(src: string, context: CanvasRenderingContext2D): Promise<void>;
|
|
13
|
+
export declare const drawSvg: (svgData: string, context: CanvasRenderingContext2D, useDataUrl?: boolean) => Promise<void>;
|
|
14
|
+
export declare function canvasToImage(canvas: HTMLCanvasElement, size?: number[], mimeType?: string, quality?: number): Promise<HTMLImageElement>;
|
|
16
15
|
export declare function objectUrlToDataURL(objectUrl: string): Promise<string>;
|
|
17
16
|
export declare const getSvgSize: (svg: string) => [number, number];
|
|
18
17
|
export declare function getSvgElementSize(svgDoc: SVGSVGElement): [number, number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvasUtils.d.ts","sourceRoot":"","sources":["../../src/gfx/canvasUtils.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;;;EAsBhD;AAID,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtE,wBAAgB,OAAO,CACnB,GAAG,EAAE,wBAAwB,EAC7B,IAAI,QAAK,EACT,YAAY,EAAE,gBAAgB,EAC9B,WAAW,SAAmB,EAC9B,UAAU,SAAU,QAkCvB;AASD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"canvasUtils.d.ts","sourceRoot":"","sources":["../../src/gfx/canvasUtils.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;;;EAsBhD;AAID,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtE,wBAAgB,OAAO,CACnB,GAAG,EAAE,wBAAwB,EAC7B,IAAI,QAAK,EACT,YAAY,EAAE,gBAAgB,EAC9B,WAAW,SAAmB,EAC9B,UAAU,SAAU,QAkCvB;AASD,eAAO,MAAM,QAAQ,aAEO,WAAW,EAAE,eAAe,MAAM,EAAE,OAAO,MAAM,oBAuBzE,CAAC;AAEL,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,UAGnD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,UAKjD;AAGD,eAAO,MAAM,YAAY,aAEH,MAAM,WAKxB,CAAC;AAEL,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,SAAc,EAAE,OAAO,CAAC,EAAE,MAAM,mBAe9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,iBAgBvE;AAED,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,EAAE,SAAS,wBAAwB,EAAE,oBAAkB,kBAG7F,CAAC;AAqBF,wBAAsB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,SAAc,EAAE,OAAO,CAAC,EAAE,MAAM,6BAgBvH;AAED,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa3E;AAED,eAAO,MAAM,UAAU,QAEN,MAAM,qBAOnB,CAAC;AAEL,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgCzE;AAED,eAAO,MAAM,SAAS,SAEJ,MAAM,WAUpB,CAAC;AAEL,wBAAgB,eAAe,CAC3B,OAAO,EAAE,wBAAwB,EACjC,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EACK,MAAM,GACN;IACI,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACd,QA0CV"}
|