@actdim/utico 0.9.2 → 0.9.4

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.
Files changed (55) hide show
  1. package/dist/arrayExtensions.es.js.map +1 -1
  2. package/dist/cache/memoryCache.es.js +5 -8
  3. package/dist/cache/memoryCache.es.js.map +1 -1
  4. package/dist/cache/persistentCache.d.ts +15 -19
  5. package/dist/cache/persistentCache.d.ts.map +1 -1
  6. package/dist/cache/persistentCache.es.js +80 -93
  7. package/dist/cache/persistentCache.es.js.map +1 -1
  8. package/dist/dataFormats.es.js.map +1 -1
  9. package/dist/dateTimeDataFormat.es.js +11 -11
  10. package/dist/dateTimeDataFormat.es.js.map +1 -1
  11. package/dist/gfx/canvasUtils.d.ts +8 -2
  12. package/dist/gfx/canvasUtils.d.ts.map +1 -1
  13. package/dist/gfx/canvasUtils.es.js +85 -74
  14. package/dist/gfx/canvasUtils.es.js.map +1 -1
  15. package/dist/gfx/color.es.js +1 -2
  16. package/dist/gfx/color.es.js.map +1 -1
  17. package/dist/i18n/enUsCulture.es.js.map +1 -1
  18. package/dist/math.es.js.map +1 -1
  19. package/dist/metadata.es.js.map +1 -1
  20. package/dist/mutex.es.js +3 -8
  21. package/dist/mutex.es.js.map +1 -1
  22. package/dist/store/dataStore.d.ts +33 -0
  23. package/dist/store/dataStore.d.ts.map +1 -0
  24. package/dist/store/dataStore.es.js +49 -0
  25. package/dist/store/dataStore.es.js.map +1 -0
  26. package/dist/store/persistentStore.d.ts +20 -0
  27. package/dist/store/persistentStore.d.ts.map +1 -0
  28. package/dist/store/persistentStore.es.js +96 -0
  29. package/dist/store/persistentStore.es.js.map +1 -0
  30. package/dist/store/storeContracts.d.ts +6 -0
  31. package/dist/store/storeContracts.d.ts.map +1 -0
  32. package/dist/store/storeContracts.es.js +2 -0
  33. package/dist/store/storeContracts.es.js.map +1 -0
  34. package/dist/stringCore.es.js.map +1 -1
  35. package/dist/structEvent.es.js +12 -16
  36. package/dist/structEvent.es.js.map +1 -1
  37. package/dist/typeUtils.es.js.map +1 -1
  38. package/dist/utils.d.ts +1 -0
  39. package/dist/utils.d.ts.map +1 -1
  40. package/dist/utils.es.js +44 -36
  41. package/dist/utils.es.js.map +1 -1
  42. package/dist/watchable.es.js.map +1 -1
  43. package/package.json +16 -14
  44. package/dist/cache/cacheDb.d.ts +0 -30
  45. package/dist/cache/cacheDb.d.ts.map +0 -1
  46. package/dist/cache/cacheDb.es.js +0 -50
  47. package/dist/cache/cacheDb.es.js.map +0 -1
  48. package/dist/storage/persistentStorage.d.ts +0 -11
  49. package/dist/storage/persistentStorage.d.ts.map +0 -1
  50. package/dist/storage/persistentStorage.es.js +0 -28
  51. package/dist/storage/persistentStorage.es.js.map +0 -1
  52. package/dist/storage/storageContracts.d.ts +0 -6
  53. package/dist/storage/storageContracts.d.ts.map +0 -1
  54. package/dist/storage/storageContracts.es.js +0 -2
  55. package/dist/storage/storageContracts.es.js.map +0 -1
@@ -0,0 +1,20 @@
1
+ import { IPersistentStore } from './storeContracts';
2
+ export declare class PersistentStore implements IPersistentStore {
3
+ private _db;
4
+ private _isDisposed;
5
+ private _useEncryption;
6
+ constructor(name: string, useEncryption?: boolean);
7
+ static delete(name: string): Promise<void>;
8
+ dispose(): void;
9
+ private execAsync;
10
+ getKeysAsync(): import('dexie').PromiseExtended<string[]>;
11
+ getAsync<T = any>(key: string): Promise<T>;
12
+ bulkGetAsync(ids: string[]): Promise<Record<string, any>>;
13
+ containsAsync(key: string): Promise<boolean>;
14
+ deleteAsync(id: string): Promise<void>;
15
+ bulkDeleteAsync(ids: string[]): Promise<void>;
16
+ setAsync(id: string, value: any): Promise<void>;
17
+ getOrSetAsync(key: string, factory: () => any): Promise<void>;
18
+ clearAsync(): Promise<void>;
19
+ }
20
+ //# sourceMappingURL=persistentStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistentStore.d.ts","sourceRoot":"","sources":["../../src/store/persistentStore.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAuBpD,qBAAa,eAAgB,YAAW,gBAAgB;IAEpD,OAAO,CAAC,GAAG,CAAY;IAEvB,OAAO,CAAC,WAAW,CAAU;IAE7B,OAAO,CAAC,cAAc,CAAU;gBAEpB,IAAI,EAAE,MAAM,EAAE,aAAa,UAAQ;IAQ/C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM;IAI1B,OAAO;YAaO,SAAS;IAevB,YAAY;IAIN,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAc1C,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IA+BzD,aAAa,CAAC,GAAG,EAAE,MAAM;IAQzB,WAAW,CAAC,EAAE,EAAE,MAAM;IAOtB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE;IAO7B,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG;IAyB/B,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAU7C,UAAU;CAQnB"}
@@ -0,0 +1,96 @@
1
+ import c from "dexie";
2
+ import { DataStore as y } from "./dataStore.es.js";
3
+ import { v4 as d } from "uuid";
4
+ class l {
5
+ _db;
6
+ _isDisposed;
7
+ _useEncryption;
8
+ // TODO: support
9
+ constructor(t, e = !1) {
10
+ if (!t)
11
+ throw new Error("Name cannot be empty");
12
+ this._useEncryption = e, this._db = new y(t);
13
+ }
14
+ static delete(t) {
15
+ return c.delete(t);
16
+ }
17
+ dispose() {
18
+ this._isDisposed || (this._isDisposed = !0, this._db && (this._db.isOpen() && this._db.close(), this._db = null));
19
+ }
20
+ async execAsync(t) {
21
+ this._db.isOpen() || await this._db.open();
22
+ try {
23
+ return await t();
24
+ } catch (e) {
25
+ throw this._db.isOpen(), e;
26
+ }
27
+ }
28
+ getKeysAsync() {
29
+ return this._db.registry.filter((t) => !0).primaryKeys();
30
+ }
31
+ async getAsync(t) {
32
+ return await this.execAsync(async () => {
33
+ if (await this._db.registry.get(t))
34
+ return (await this._db.data.get(t))?.value;
35
+ });
36
+ }
37
+ // getManyAsync
38
+ async bulkGetAsync(t) {
39
+ const e = {};
40
+ return await this.execAsync(async () => {
41
+ const a = (await this._db.registry.bulkGet(t)).reduce((s, n, h) => (s[n.id] = n, s), {}), r = await this._db.data.bulkGet(t);
42
+ for (const s of r)
43
+ e[s.id] = s.value, delete a[s.id];
44
+ for (const s of Object.keys(a))
45
+ e[s] = void 0;
46
+ return e;
47
+ });
48
+ }
49
+ async containsAsync(t) {
50
+ return await this.execAsync(async () => await this._db.registry.get(t) != null);
51
+ }
52
+ async deleteAsync(t) {
53
+ await this.execAsync(async () => {
54
+ await this._db.registry.delete(t);
55
+ });
56
+ }
57
+ // deleteManyAsync
58
+ async bulkDeleteAsync(t) {
59
+ await this.execAsync(async () => {
60
+ await this._db.registry.bulkDelete(t);
61
+ });
62
+ }
63
+ // upsertAsync
64
+ async setAsync(t, e) {
65
+ return await this.execAsync(async () => {
66
+ const i = await this._db.registry.get(t), a = (/* @__PURE__ */ new Date()).getTime();
67
+ t || (t = d()), await this._db.registry.put({
68
+ id: t,
69
+ createdAt: i ? i.createdAt : a,
70
+ accessedAt: i ? i.accessedAt : null,
71
+ // now
72
+ updatedAt: a,
73
+ expiresAt: void 0,
74
+ slidingExpiration: void 0
75
+ }), await this._db.data.put({
76
+ id: t,
77
+ value: e
78
+ });
79
+ });
80
+ }
81
+ // getOrAddAsync
82
+ async getOrSetAsync(t, e) {
83
+ await this.execAsync(async () => (await this.containsAsync(t) || await this.setAsync(t, e()), await this.getAsync(t)));
84
+ }
85
+ // clearAllAsync
86
+ async clearAsync() {
87
+ await this.execAsync(async () => {
88
+ await this._db.registry.clear(), await this._db.data.clear();
89
+ });
90
+ }
91
+ // TODO: support bulkSetAsync
92
+ }
93
+ export {
94
+ l as PersistentStore
95
+ };
96
+ //# sourceMappingURL=persistentStore.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistentStore.es.js","sources":["../../src/store/persistentStore.ts"],"sourcesContent":["// TODO: implement real encryption:\r\n// https://stackoverflow.com/questions/18279141/javascript-string-encryption-and-decryption\r\n\r\nimport Dexie from \"dexie\";\r\nimport { DataStore, IDataEntry } from \"./dataStore\";\r\nimport { IPersistentStore } from \"./storeContracts\";\r\nimport { v4 as uuid } from \"uuid\";\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\r\n// TODO: remove class, create factory method\r\nexport class PersistentStore implements IPersistentStore {\r\n\r\n private _db: DataStore;\r\n\r\n private _isDisposed: boolean;\r\n\r\n private _useEncryption: boolean; // TODO: support\r\n\r\n constructor(name: string, useEncryption = false) {\r\n if (!name) {\r\n throw new Error(\"Name cannot be empty\");\r\n }\r\n this._useEncryption = useEncryption;\r\n this._db = new DataStore(name);\r\n }\r\n\r\n static delete(name: string) {\r\n return Dexie.delete(name);\r\n }\r\n\r\n dispose() {\r\n if (!this._isDisposed) {\r\n this._isDisposed = true;\r\n\r\n if (this._db) {\r\n if (this._db.isOpen()) {\r\n this._db.close();\r\n }\r\n this._db = null;\r\n }\r\n }\r\n }\r\n\r\n private async execAsync<T>(action: () => Promise<T>) {\r\n if (!this._db.isOpen()) {\r\n await this._db.open();\r\n }\r\n try {\r\n const result = await action();\r\n return result;\r\n } catch (err) {\r\n if (this._db.isOpen()) {\r\n // this._db.close(); // generally speaking: we don't (never) need to close a connection\r\n }\r\n throw err;\r\n }\r\n }\r\n\r\n getKeysAsync() {\r\n return this._db.registry.filter((_) => true).primaryKeys();\r\n }\r\n\r\n async getAsync<T = any>(key: string): Promise<T> {\r\n return await this.execAsync(async () => {\r\n const entry = await this._db.registry.get(key);\r\n // const entry = await this._db.registry.where(keyOf<IDataEntry>(\"id\")).equals(key).first();\r\n if (entry) {\r\n const data = await this._db.data.get(key);\r\n // const data = await this._db.data.where(keyOf<IDataEntry>(\"id\")).equals(key).first();\r\n return data?.value;\r\n }\r\n return undefined;\r\n });\r\n }\r\n\r\n // getManyAsync\r\n async bulkGetAsync(ids: string[]): Promise<Record<string, any>> {\r\n const result: Record<string, any> = {};\r\n return await this.execAsync(async () => {\r\n // const entries = await this._db.registry.where(keyOf<IDataEntry>(\"id\")).anyOf(ids).toArray();\r\n const entries = await this._db.registry.bulkGet(ids);\r\n const entryMap: { [key: string]: IDataEntry } = entries.reduce((map, entry, i) => {\r\n map[entry.id] = entry;\r\n return map;\r\n }, {});\r\n\r\n // const dataItems = this._db.data.where(keyOf<IDataEntry>(\"id\")).anyOf(ids);\r\n // await dataItems.each((dataItem) => {\r\n // result[dataItem.id] = { ...entryMap[dataItem.id], ...dataItem };\r\n // delete entryMap[dataItem.id];\r\n // });\r\n\r\n const dataItems = await this._db.data.bulkGet(ids);\r\n for (const dataItem of dataItems) {\r\n result[dataItem.id] = dataItem.value;\r\n delete entryMap[dataItem.id];\r\n }\r\n\r\n for (const key of Object.keys(entryMap)) {\r\n // abandoned/orphaned entries:\r\n result[key] = undefined;\r\n }\r\n\r\n return result;\r\n });\r\n }\r\n\r\n async containsAsync(key: string) {\r\n return await this.execAsync(async () => {\r\n const entry = await this._db.registry.get(key);\r\n // const entry = await this._db.registry.where(keyOf<IDataEntry>(\"id\")).equals(key).first();\r\n return entry != undefined;\r\n });\r\n }\r\n\r\n async deleteAsync(id: string) {\r\n await this.execAsync(async () => {\r\n await this._db.registry.delete(id);\r\n });\r\n }\r\n\r\n // deleteManyAsync\r\n async bulkDeleteAsync(ids: string[]) {\r\n await this.execAsync(async () => {\r\n await this._db.registry.bulkDelete(ids);\r\n });\r\n }\r\n\r\n // upsertAsync\r\n async setAsync(id: string, value: any) {\r\n return await this.execAsync(async () => {\r\n const entry = await this._db.registry.get(id);\r\n // const entry = await this._db.registry.where(keyOf<IDataEntry>(\"id\")).equals(key).first();\r\n const now = new Date().getTime();\r\n if (!id) {\r\n id = uuid();\r\n }\r\n\r\n await this._db.registry.put({\r\n id: id,\r\n createdAt: entry ? entry.createdAt : now,\r\n accessedAt: entry ? entry.accessedAt : null, // now\r\n updatedAt: now,\r\n expiresAt: undefined,\r\n slidingExpiration: undefined\r\n });\r\n await this._db.data.put({\r\n id: id,\r\n value: value\r\n });\r\n });\r\n }\r\n\r\n // getOrAddAsync\r\n async getOrSetAsync(key: string, factory: () => any) {\r\n await this.execAsync(async () => {\r\n if (!(await this.containsAsync(key))) {\r\n await this.setAsync(key, factory());\r\n }\r\n return await this.getAsync(key);\r\n });\r\n }\r\n\r\n // clearAllAsync\r\n async clearAsync() {\r\n await this.execAsync(async () => {\r\n await this._db.registry.clear();\r\n await this._db.data.clear();\r\n });\r\n }\r\n\r\n // TODO: support bulkSetAsync\r\n}\r\n"],"names":["PersistentStore","name","useEncryption","DataStore","Dexie","action","err","_","key","ids","result","entryMap","map","entry","i","dataItems","dataItem","id","value","now","uuid","factory"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export type IPersistentStore = {
2
+ getAsync<T = any>(key: string, useEncryption?: boolean): Promise<T>;
3
+ setAsync<T = any>(key: string, value: T, useEncryption?: boolean): Promise<void>;
4
+ deleteAsync(key: string): Promise<void>;
5
+ };
6
+ //# sourceMappingURL=storeContracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storeContracts.d.ts","sourceRoot":"","sources":["../../src/store/storeContracts.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,gBAAgB,GAAG;IAC3B,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C,CAAA"}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=storeContracts.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storeContracts.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"stringCore.es.js","sources":["../src/stringCore.ts"],"sourcesContent":["// const currentLocale = new Intl.Locale(navigator.language);\r\n// const currentCollator = Intl.Collator(navigator.language);\r\nconst defaulCollator = Intl.Collator();\r\n\r\nconst ciCompare = (() => {\r\n const collatorOptions: Intl.CollatorOptions = {\r\n sensitivity: \"accent\" // or \"base\"\r\n };\r\n ;\r\n // feature detection\r\n return 'A'.localeCompare('a', undefined, collatorOptions) ? (strA: string, strB: string, locale = navigator.language) => {\r\n return strA.localeCompare(strB, locale, collatorOptions)\r\n } : (strA: string, strB: string, locale?: string) => {\r\n // fallback approach\r\n return strA.toLocaleUpperCase(locale).localeCompare(strB.toLocaleUpperCase(locale), locale);\r\n };\r\n})();\r\n\r\nfunction compare(strA: string, strB: string, ignoreCase = false, locale = navigator.language) {\r\n if (typeof strA !== 'string' || typeof strB !== 'string') {\r\n return defaulCollator.compare(strA, strB);\r\n }\r\n if (ignoreCase) {\r\n return ciCompare(strA, strB, locale);\r\n }\r\n return strA.localeCompare(strB, locale);\r\n}\r\n\r\n// isEqual\r\nfunction equals(strA: string, strB: string, ignoreCase = false, locale = navigator.language) {\r\n if (typeof strA !== 'string' || typeof strB !== 'string') {\r\n return strA === strB;\r\n }\r\n if (ignoreCase) {\r\n return ciCompare(strA, strB) === 0;\r\n }\r\n return strA.localeCompare(strB, locale) === 0;\r\n}\r\n\r\nfunction ciStartsWith(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return false;\r\n }\r\n return equals(str.substring(0, searchStr.length), searchStr, true, locale);\r\n}\r\n\r\nfunction ciEndsWith(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return false;\r\n }\r\n return equals(str.substring(str.length - searchStr.length), searchStr, true, locale);\r\n}\r\n\r\nfunction ciIndexOf(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return -1;\r\n }\r\n return str.toLocaleUpperCase(locale).indexOf(searchStr.toLocaleUpperCase(locale));\r\n}\r\n\r\nfunction ciIncludes(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return -1;\r\n }\r\n return str.toLocaleUpperCase(locale).includes(searchStr.toLocaleUpperCase(locale));\r\n}\r\n\r\nexport {\r\n equals,\r\n compare,\r\n ciCompare,\r\n ciStartsWith,\r\n ciEndsWith,\r\n ciIndexOf,\r\n ciIncludes\r\n};"],"names":["defaulCollator","ciCompare","collatorOptions","strA","strB","locale","compare","ignoreCase","equals","ciStartsWith","str","searchStr","ciEndsWith","ciIndexOf","ciIncludes"],"mappings":"AAEA,MAAMA,IAAiB,KAAK,YAEtBC,KAAa,MAAM;AACrB,QAAMC,IAAwC;AAAA,IAC1C,aAAa;AAAA;AAAA,EAAA;AAIV,SAAA,IAAI,cAAc,KAAK,QAAWA,CAAe,IAAI,CAACC,GAAcC,GAAcC,IAAS,UAAU,aACjGF,EAAK,cAAcC,GAAMC,GAAQH,CAAe,IACvD,CAACC,GAAcC,GAAcC,MAEtBF,EAAK,kBAAkBE,CAAM,EAAE,cAAcD,EAAK,kBAAkBC,CAAM,GAAGA,CAAM;AAElG,GAAG;AAEH,SAASC,EAAQH,GAAcC,GAAcG,IAAa,IAAOF,IAAS,UAAU,UAAU;AAC1F,SAAI,OAAOF,KAAS,YAAY,OAAOC,KAAS,WACrCJ,EAAe,QAAQG,GAAMC,CAAI,IAExCG,IACON,EAAUE,GAAMC,GAAMC,CAAM,IAEhCF,EAAK,cAAcC,GAAMC,CAAM;AAC1C;AAGA,SAASG,EAAOL,GAAcC,GAAcG,IAAa,IAAOF,IAAS,UAAU,UAAU;AACzF,SAAI,OAAOF,KAAS,YAAY,OAAOC,KAAS,WACrCD,MAASC,IAEhBG,IACON,EAAUE,GAAMC,CAAI,MAAM,IAE9BD,EAAK,cAAcC,GAAMC,CAAM,MAAM;AAChD;AAEA,SAASI,EAAaC,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AAC3E,SAAA,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJH,EAAOE,EAAI,UAAU,GAAGC,EAAU,MAAM,GAAGA,GAAW,IAAMN,CAAM;AAC7E;AAEA,SAASO,EAAWF,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AACzE,SAAA,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJH,EAAOE,EAAI,UAAUA,EAAI,SAASC,EAAU,MAAM,GAAGA,GAAW,IAAMN,CAAM;AACvF;AAEA,SAASQ,EAAUH,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AACxE,SAAA,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJD,EAAI,kBAAkBL,CAAM,EAAE,QAAQM,EAAU,kBAAkBN,CAAM,CAAC;AACpF;AAEA,SAASS,EAAWJ,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AACzE,SAAA,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJD,EAAI,kBAAkBL,CAAM,EAAE,SAASM,EAAU,kBAAkBN,CAAM,CAAC;AACrF;"}
1
+ {"version":3,"file":"stringCore.es.js","sources":["../src/stringCore.ts"],"sourcesContent":["// const currentLocale = new Intl.Locale(navigator.language);\r\n// const currentCollator = Intl.Collator(navigator.language);\r\nconst defaulCollator = Intl.Collator();\r\n\r\nconst ciCompare = (() => {\r\n const collatorOptions: Intl.CollatorOptions = {\r\n sensitivity: \"accent\" // or \"base\"\r\n };\r\n ;\r\n // feature detection\r\n return 'A'.localeCompare('a', undefined, collatorOptions) ? (strA: string, strB: string, locale = navigator.language) => {\r\n return strA.localeCompare(strB, locale, collatorOptions)\r\n } : (strA: string, strB: string, locale?: string) => {\r\n // fallback approach\r\n return strA.toLocaleUpperCase(locale).localeCompare(strB.toLocaleUpperCase(locale), locale);\r\n };\r\n})();\r\n\r\nfunction compare(strA: string, strB: string, ignoreCase = false, locale = navigator.language) {\r\n if (typeof strA !== 'string' || typeof strB !== 'string') {\r\n return defaulCollator.compare(strA, strB);\r\n }\r\n if (ignoreCase) {\r\n return ciCompare(strA, strB, locale);\r\n }\r\n return strA.localeCompare(strB, locale);\r\n}\r\n\r\n// isEqual\r\nfunction equals(strA: string, strB: string, ignoreCase = false, locale = navigator.language) {\r\n if (typeof strA !== 'string' || typeof strB !== 'string') {\r\n return strA === strB;\r\n }\r\n if (ignoreCase) {\r\n return ciCompare(strA, strB) === 0;\r\n }\r\n return strA.localeCompare(strB, locale) === 0;\r\n}\r\n\r\nfunction ciStartsWith(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return false;\r\n }\r\n return equals(str.substring(0, searchStr.length), searchStr, true, locale);\r\n}\r\n\r\nfunction ciEndsWith(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return false;\r\n }\r\n return equals(str.substring(str.length - searchStr.length), searchStr, true, locale);\r\n}\r\n\r\nfunction ciIndexOf(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return -1;\r\n }\r\n return str.toLocaleUpperCase(locale).indexOf(searchStr.toLocaleUpperCase(locale));\r\n}\r\n\r\nfunction ciIncludes(str: string, searchStr: string, locale = navigator.language) {\r\n if (typeof str !== 'string' || typeof searchStr !== 'string' || str.length < searchStr.length) {\r\n return -1;\r\n }\r\n return str.toLocaleUpperCase(locale).includes(searchStr.toLocaleUpperCase(locale));\r\n}\r\n\r\nexport {\r\n equals,\r\n compare,\r\n ciCompare,\r\n ciStartsWith,\r\n ciEndsWith,\r\n ciIndexOf,\r\n ciIncludes\r\n};"],"names":["defaulCollator","ciCompare","collatorOptions","strA","strB","locale","compare","ignoreCase","equals","ciStartsWith","str","searchStr","ciEndsWith","ciIndexOf","ciIncludes"],"mappings":"AAEA,MAAMA,IAAiB,KAAK,SAAA,GAEtBC,KAAa,MAAM;AACrB,QAAMC,IAAwC;AAAA,IAC1C,aAAa;AAAA;AAAA,EAAA;AAIjB,SAAO,IAAI,cAAc,KAAK,QAAWA,CAAe,IAAI,CAACC,GAAcC,GAAcC,IAAS,UAAU,aACjGF,EAAK,cAAcC,GAAMC,GAAQH,CAAe,IACvD,CAACC,GAAcC,GAAcC,MAEtBF,EAAK,kBAAkBE,CAAM,EAAE,cAAcD,EAAK,kBAAkBC,CAAM,GAAGA,CAAM;AAElG,GAAA;AAEA,SAASC,EAAQH,GAAcC,GAAcG,IAAa,IAAOF,IAAS,UAAU,UAAU;AAC1F,SAAI,OAAOF,KAAS,YAAY,OAAOC,KAAS,WACrCJ,EAAe,QAAQG,GAAMC,CAAI,IAExCG,IACON,EAAUE,GAAMC,GAAMC,CAAM,IAEhCF,EAAK,cAAcC,GAAMC,CAAM;AAC1C;AAGA,SAASG,EAAOL,GAAcC,GAAcG,IAAa,IAAOF,IAAS,UAAU,UAAU;AACzF,SAAI,OAAOF,KAAS,YAAY,OAAOC,KAAS,WACrCD,MAASC,IAEhBG,IACON,EAAUE,GAAMC,CAAI,MAAM,IAE9BD,EAAK,cAAcC,GAAMC,CAAM,MAAM;AAChD;AAEA,SAASI,EAAaC,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AAC/E,SAAI,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJH,EAAOE,EAAI,UAAU,GAAGC,EAAU,MAAM,GAAGA,GAAW,IAAMN,CAAM;AAC7E;AAEA,SAASO,EAAWF,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AAC7E,SAAI,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJH,EAAOE,EAAI,UAAUA,EAAI,SAASC,EAAU,MAAM,GAAGA,GAAW,IAAMN,CAAM;AACvF;AAEA,SAASQ,EAAUH,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AAC5E,SAAI,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJD,EAAI,kBAAkBL,CAAM,EAAE,QAAQM,EAAU,kBAAkBN,CAAM,CAAC;AACpF;AAEA,SAASS,EAAWJ,GAAaC,GAAmBN,IAAS,UAAU,UAAU;AAC7E,SAAI,OAAOK,KAAQ,YAAY,OAAOC,KAAc,YAAYD,EAAI,SAASC,EAAU,SAC5E,KAEJD,EAAI,kBAAkBL,CAAM,EAAE,SAASM,EAAU,kBAAkBN,CAAM,CAAC;AACrF;"}
@@ -1,23 +1,19 @@
1
- var o = Object.defineProperty;
2
- var a = (r, e, t) => e in r ? o(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
- var n = (r, e, t) => a(r, typeof e != "symbol" ? e + "" : e, t);
4
- class v extends CustomEvent {
5
- constructor(t, s) {
6
- super(t, s);
7
- n(this, "target");
8
- // currentTarget: TTarget;
9
- n(this, "type");
10
- this.target = s.target;
1
+ class n extends CustomEvent {
2
+ target;
3
+ // currentTarget: TTarget;
4
+ type;
5
+ constructor(e, t) {
6
+ super(e, t), this.target = t.target;
11
7
  }
12
8
  }
13
- class E extends EventTarget {
9
+ class o extends EventTarget {
14
10
  constructor() {
15
11
  super();
16
12
  }
17
- addEventListener(e, t, s) {
18
- super.addEventListener(e, t, s);
13
+ addEventListener(e, t, r) {
14
+ super.addEventListener(e, t, r);
19
15
  }
20
- removeEventListener(e, t, s) {
16
+ removeEventListener(e, t, r) {
21
17
  super.removeEventListener(e, t);
22
18
  }
23
19
  dispatchEvent(e) {
@@ -28,7 +24,7 @@ class E extends EventTarget {
28
24
  }
29
25
  }
30
26
  export {
31
- v as StructEvent,
32
- E as StructEventTarget
27
+ n as StructEvent,
28
+ o as StructEventTarget
33
29
  };
34
30
  //# sourceMappingURL=structEvent.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"structEvent.es.js","sources":["../src/structEvent.ts"],"sourcesContent":["import { Struct } from \"./typeCore\";\r\n\r\nexport class StructEvent<\r\n TStruct extends Record<string, any>,\r\n TTarget extends StructEventTarget<TStruct>,\r\n TType extends Extract<keyof TStruct, string> = Extract<keyof TStruct, string>\r\n> extends CustomEvent<TStruct[TType]> {\r\n target: TTarget;\r\n // currentTarget: TTarget;\r\n type: TType;\r\n constructor(type: TType, eventInitDict?: CustomEventInit<TStruct[TType]> & { target: TTarget }) {\r\n super(type, eventInitDict);\r\n this.target = eventInitDict.target;\r\n }\r\n}\r\n\r\n// TKeys extends Extract<keyof TStruct, string> = Extract<keyof TStruct, string>>\r\n// StructEventDispatcher\r\nexport class StructEventTarget<TStruct extends Record<string, any>> extends EventTarget implements StructEventTarget<TStruct> {\r\n constructor() {\r\n super();\r\n }\r\n\r\n addEventListener<K extends Extract<keyof TStruct, string>>(\r\n type: K,\r\n listener: (event: StructEvent<TStruct, this, K>) => void,\r\n options?: boolean | AddEventListenerOptions\r\n ): void {\r\n super.addEventListener(type, listener, options);\r\n }\r\n\r\n removeEventListener<K extends Extract<keyof TStruct, string>>(\r\n type: K,\r\n listener: (event: StructEvent<TStruct, this, K>) => void,\r\n options?: boolean | EventListenerOptions\r\n ): void {\r\n super.removeEventListener(type, listener);\r\n }\r\n\r\n dispatchEvent<K extends Extract<keyof TStruct, string>>(event: StructEvent<TStruct, this, K>): boolean {\r\n return super.dispatchEvent(event);\r\n }\r\n\r\n hasEventListener<K extends Extract<keyof TStruct, string>>(type: K, listener: (event: StructEvent<TStruct, this, K>) => void): boolean {\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n}\r\n"],"names":["StructEvent","type","eventInitDict","__publicField","StructEventTarget","listener","options","event"],"mappings":";;;AAEO,MAAMA,UAIH,YAA4B;AAAA,EAIlC,YAAYC,GAAaC,GAAuE;AAC5F,UAAMD,GAAMC,CAAa;AAJ7B,IAAAC,EAAA;AAEA;AAAA,IAAAA,EAAA;AAGI,SAAK,SAASD,EAAc;AAAA,EAChC;AACJ;AAIO,MAAME,UAA+D,YAAkD;AAAA,EAC1H,cAAc;AACJ;EACV;AAAA,EAEA,iBACIH,GACAI,GACAC,GACI;AACE,UAAA,iBAAiBL,GAAMI,GAAUC,CAAO;AAAA,EAClD;AAAA,EAEA,oBACIL,GACAI,GACAC,GACI;AACE,UAAA,oBAAoBL,GAAMI,CAAQ;AAAA,EAC5C;AAAA,EAEA,cAAwDE,GAA+C;AAC5F,WAAA,MAAM,cAAcA,CAAK;AAAA,EACpC;AAAA,EAEA,iBAA2DN,GAASI,GAAmE;AAC7H,UAAA,IAAI,MAAM,yBAAyB;AAAA,EAC7C;AACJ;"}
1
+ {"version":3,"file":"structEvent.es.js","sources":["../src/structEvent.ts"],"sourcesContent":["import { Struct } from \"./typeCore\";\r\n\r\nexport class StructEvent<\r\n TStruct extends Record<string, any>,\r\n TTarget extends StructEventTarget<TStruct>,\r\n TType extends Extract<keyof TStruct, string> = Extract<keyof TStruct, string>\r\n> extends CustomEvent<TStruct[TType]> {\r\n target: TTarget;\r\n // currentTarget: TTarget;\r\n type: TType;\r\n constructor(type: TType, eventInitDict?: CustomEventInit<TStruct[TType]> & { target: TTarget }) {\r\n super(type, eventInitDict);\r\n this.target = eventInitDict.target;\r\n }\r\n}\r\n\r\n// TKeys extends Extract<keyof TStruct, string> = Extract<keyof TStruct, string>>\r\n// StructEventDispatcher\r\nexport class StructEventTarget<TStruct extends Record<string, any>> extends EventTarget implements StructEventTarget<TStruct> {\r\n constructor() {\r\n super();\r\n }\r\n\r\n addEventListener<K extends Extract<keyof TStruct, string>>(\r\n type: K,\r\n listener: (event: StructEvent<TStruct, this, K>) => void,\r\n options?: boolean | AddEventListenerOptions\r\n ): void {\r\n super.addEventListener(type, listener, options);\r\n }\r\n\r\n removeEventListener<K extends Extract<keyof TStruct, string>>(\r\n type: K,\r\n listener: (event: StructEvent<TStruct, this, K>) => void,\r\n options?: boolean | EventListenerOptions\r\n ): void {\r\n super.removeEventListener(type, listener);\r\n }\r\n\r\n dispatchEvent<K extends Extract<keyof TStruct, string>>(event: StructEvent<TStruct, this, K>): boolean {\r\n return super.dispatchEvent(event);\r\n }\r\n\r\n hasEventListener<K extends Extract<keyof TStruct, string>>(type: K, listener: (event: StructEvent<TStruct, this, K>) => void): boolean {\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n}\r\n"],"names":["StructEvent","type","eventInitDict","StructEventTarget","listener","options","event"],"mappings":"AAEO,MAAMA,UAIH,YAA4B;AAAA,EAClC;AAAA;AAAA,EAEA;AAAA,EACA,YAAYC,GAAaC,GAAuE;AAC5F,UAAMD,GAAMC,CAAa,GACzB,KAAK,SAASA,EAAc;AAAA,EAChC;AACJ;AAIO,MAAMC,UAA+D,YAAkD;AAAA,EAC1H,cAAc;AACV,UAAA;AAAA,EACJ;AAAA,EAEA,iBACIF,GACAG,GACAC,GACI;AACJ,UAAM,iBAAiBJ,GAAMG,GAAUC,CAAO;AAAA,EAClD;AAAA,EAEA,oBACIJ,GACAG,GACAC,GACI;AACJ,UAAM,oBAAoBJ,GAAMG,CAAQ;AAAA,EAC5C;AAAA,EAEA,cAAwDE,GAA+C;AACnG,WAAO,MAAM,cAAcA,CAAK;AAAA,EACpC;AAAA,EAEA,iBAA2DL,GAASG,GAAmE;AACnI,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC7C;AACJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"typeUtils.es.js","sources":["../src/typeUtils.ts"],"sourcesContent":["import { CallableConstructor, Constructor, ConstructorClass } from \"./typeCore\";\r\n\r\n// @filename: typeUtils.ts\r\n\r\n// typed version of Object.keys\r\nexport function keysOf<T extends object>(obj: T) {\r\n return Object.keys(obj) as Array<keyof T>;\r\n}\r\n\r\nexport function entry<T extends object, TKey extends keyof T>(obj: T, name: TKey, caseInsensitive = true) {\r\n if (!obj || !name) {\r\n return undefined;\r\n }\r\n // name.toString()\r\n let nameStr = String(name).trim();\r\n const keys = keysOf(obj);\r\n let key: keyof T;\r\n if (caseInsensitive) {\r\n nameStr = nameStr.toLowerCase();\r\n key = keys.find((k) => String(k).toLowerCase().trim() === nameStr);\r\n } else {\r\n key = keys.find((k) => String(k).trim() === nameStr);\r\n }\r\n return [key, key == undefined ? undefined : (obj[key] as T[TKey])] as [TKey, T[TKey]];\r\n}\r\n\r\nexport function satisfies<TShape>() {\r\n return <T extends TShape>(obj: T) => obj;\r\n}\r\n\r\n// $keyOf\r\nexport const keyOf = <T extends object, TKey extends keyof T = keyof T>(key: TKey, obj?: T) => key;\r\n\r\n// $nameOf/$n\r\nexport function nameOf<T extends object>(f: (x: T) => T[keyof T]): keyof T;\r\nexport function nameOf(f: (x: any) => any): keyof any {\r\n const p = new Proxy(\r\n {},\r\n {\r\n get: (target, key) => key\r\n }\r\n );\r\n return f(p);\r\n}\r\n\r\ntype $KeyMap<T extends object> = {\r\n [K in keyof T]: K;\r\n};\r\n\r\nexport function $keyMap<T extends object>(obj?: T) {\r\n return new Proxy(\r\n {},\r\n {\r\n get: (target, key) => key\r\n }\r\n ) as $KeyMap<T>;\r\n}\r\n\r\n// $NU\r\ntype $NH<T> = {\r\n nameOf(f: (x: T) => T[keyof T]): keyof T;\r\n};\r\n\r\n// $nu\r\n// usage: $nh(obj).nameOf(x => x.prop) or $NH<ClassName>().nameOf(x => x.prop)\r\nexport function $nh<T>(obj?: T) {\r\n return {\r\n nameOf: (f: (x: any) => any) => {\r\n return nameOf(f);\r\n }\r\n } as $NH<T>;\r\n}\r\n\r\nexport function getPropertyPath<T>(expr: (x: T) => any) {\r\n return getPropertyPathInternal(expr);\r\n}\r\n\r\nfunction getPropertyPathInternal<T>(expr: (x: T) => any, path?: (string | number | symbol)[]) {\r\n if (path == undefined) {\r\n path = [];\r\n }\r\n let createProxy: () => any;\r\n createProxy = () => {\r\n return new Proxy(\r\n {},\r\n {\r\n get: (target, key) => {\r\n path.push(key);\r\n return createProxy();\r\n }\r\n }\r\n );\r\n };\r\n expr(createProxy());\r\n return path;\r\n}\r\n\r\nexport function combinePropertyPath(path?: (string | number | symbol)[]) {\r\n const builder: string[] = [];\r\n for (const key of path) {\r\n builder.push(`[\"${key.toString()}\"]`);\r\n }\r\n return builder.join(\"\");\r\n}\r\n\r\nconst nonObjectTypes: Constructor[] = [String, Number];\r\n\r\n// isNonObjectCtor\r\nfunction isNonObjectType<TConstructor extends Constructor>(type: TConstructor) {\r\n return nonObjectTypes.indexOf(type) >= 0;\r\n}\r\n\r\n// getConstructor\r\nexport function createConstructor<TConstructor extends Constructor>(\r\n type: TConstructor // ctor\r\n): CallableConstructor<TConstructor> {\r\n if (isNonObjectType(type)) {\r\n return type as CallableConstructor<TConstructor>;\r\n } else {\r\n function createInstance(...args: ConstructorParameters<TConstructor>): ConstructorClass<TConstructor> {\r\n // return Reflect.construct(type, args); // works too\r\n return new type(...args);\r\n }\r\n\r\n createInstance.prototype = type.prototype;\r\n return createInstance as CallableConstructor<TConstructor>;\r\n }\r\n}\r\n\r\nexport function getPrototypes(obj: any) {\r\n const result = [];\r\n let prototype;\r\n while (true) {\r\n prototype = Object.getPrototypeOf(prototype || obj);\r\n if (!prototype) {\r\n break;\r\n }\r\n result.push(prototype);\r\n }\r\n return result;\r\n}\r\n\r\nexport function proxify<T extends object>(source: () => T): T {\r\n return new Proxy(\r\n {},\r\n {\r\n get: (target, key) => {\r\n return Reflect.get(source(), key);\r\n // return source()[key];\r\n },\r\n set: (target, key, value) => {\r\n return Reflect.set(source(), key, value);\r\n // source()[key] = value;\r\n // return true;\r\n }\r\n }\r\n ) as T;\r\n}\r\n\r\nexport function getEnumValue<T>(enumType: T, name: string, defaultValue: T[keyof T]): T[keyof T] {\r\n let value = name ? enumType[name as keyof T] : defaultValue;\r\n if (value == undefined) {\r\n value = defaultValue;\r\n }\r\n return value;\r\n}\r\n\r\nexport function getEnumValues<T extends object, K extends keyof T>(enumType: T): Array<T[K]> {\r\n return getEnumKeys<T, K>(enumType).map((x) => enumType[x]);\r\n}\r\n\r\nexport function getEnumKeys<T extends object, K extends keyof T>(enumType: T): Array<K> {\r\n return Object.keys(enumType)\r\n .filter((x) => Number.isNaN(Number(x)))\r\n .map((x) => x as K);\r\n}\r\n\r\n// conditional assign with value factory\r\nexport function assignWith<T extends object, U extends object>(\r\n dst: T,\r\n src: U,\r\n callback?: (key: keyof U, value: U[keyof U], set: (value: U[keyof U]) => void) => any\r\n): T & Partial<U> {\r\n const result: T & Partial<U> = dst;\r\n if (src) {\r\n for (const key in src) {\r\n let value = src[key];\r\n const set = (v: U[keyof U]) => {\r\n // result[key as PropertyKey] = value;\r\n Reflect.set(result, key, v);\r\n };\r\n if (callback) {\r\n callback(key, value, set);\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n// constrained and typed assign\r\nexport function update<T extends object, U extends Partial<T>>(dst: T, src: U, props?: [keyof U]): T & Partial<U> {\r\n const propSet = new Set(props);\r\n\r\n return assignWith(dst, src, (key, value, set) => {\r\n if (!propSet.size || propSet.has(key)) {\r\n set(value);\r\n }\r\n });\r\n\r\n // for (const prop of props) {\r\n // // dst[prop as PropertyKey] = src[prop];\r\n // Reflect.set(dst, prop, src[prop]);\r\n // }\r\n // return dst;\r\n}\r\n\r\nexport function copy<T extends object, U extends object>(src: T, dst: U, props?: [keyof T]): U & Partial<T> {\r\n return update(dst, src, props);\r\n}\r\n\r\nexport function isPlainObject(value) {\r\n if (Object.prototype.toString.call(value) !== '[object Object]') return false;\r\n const proto = Object.getPrototypeOf(value);\r\n return proto === null || proto === Object.prototype;\r\n}\r\n\r\nconst sort = (() => {\r\n // It relies on Chrome's and Node's behaviour that the first key assigned to an object is outputted first by JSON.stringify.\r\n const noKeys = []; // emptyKeys\r\n function sortImpl(obj: any, keyCompareFn?: (a: string, b: string) => number) {\r\n const keys = obj ? Object.keys(obj) : noKeys;\r\n // const orderedKeys = desc ? keys.orderByDesc(k => k) : keys.orderBy(k => k);\r\n if (keyCompareFn) {\r\n // array sort method without compare function produces ascending but alphabetical, lexicographic (dictionary) order\r\n keyCompareFn = (a, b) => b.localeCompare(a);\r\n }\r\n const orderedKeys = keys.sort(keyCompareFn);\r\n // result\r\n const container = {}; // sortedObj\r\n for (const key of orderedKeys) {\r\n container[key] = isPlainObject(obj[key]) ? sortImpl(obj[key]) : obj[key];\r\n }\r\n return container;\r\n }\r\n return sortImpl;\r\n})();\r\n\r\n// stableStringify\r\nexport const orderedStringify = (() => {\r\n // https://www.gangofcoders.net/solution/sort-object-properties-and-json-stringify/\r\n // see also: https://www.npmjs.com/package/json-stable-stringify\r\n return (\r\n obj: any,\r\n keyCompareFn?: (a: string, b: string) => number,\r\n replacer?: (this: any, key: string, value: any) => any,\r\n // replacer?: (number | string)[] | null,\r\n space?: string | number\r\n ) => {\r\n return JSON.stringify(sort(obj, keyCompareFn), replacer, space);\r\n };\r\n})();\r\n\r\n// structural comparison helper\r\nexport function jsonEquals<T>(obj1: T, obj2: T) {\r\n // contentEquals\r\n return orderedStringify(obj1) === orderedStringify(obj2);\r\n}\r\n\r\n/** structuredClone alternative */\r\nexport function jsonClone<T extends object>(obj: T): T {\r\n const type = typeof obj;\r\n if (type !== \"object\") {\r\n throw new Error(`Unsupported object type: ${type}`);\r\n }\r\n if (!obj) {\r\n return obj;\r\n }\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n// freeze\r\nexport const lock = Symbol(\"__lock\");\r\n\r\n// IFreezable\r\nexport type ILockable<T = any> = Readonly<T> & { [lock]?: (locked: boolean) => void };\r\n\r\n// deepFreeze/lock\r\nexport function toReadOnly<T extends object>(obj: T, throwOnSet: boolean = false): ILockable<T> {\r\n return toReadOnlyInternal(obj, throwOnSet);\r\n}\r\n\r\nfunction toReadOnlyInternal<T extends object>(obj: T, throwOnSet: boolean = false, lockTest?: () => boolean): ILockable<T> {\r\n if (typeof obj !== \"object\" || !obj) {\r\n return obj;\r\n }\r\n\r\n let locked = true;\r\n if (!lockTest) {\r\n lockTest = () => locked;\r\n }\r\n\r\n const result = new Proxy(obj, {\r\n get: (target, property, receiver) => {\r\n // property in target\r\n if (Reflect.has(target, property)) {\r\n // Reflect.get(target, property)\r\n return toReadOnlyInternal(target[property], throwOnSet, lockTest);\r\n }\r\n return undefined;\r\n },\r\n set: (target, property, value, receiver) => {\r\n if (lockTest()) {\r\n if (throwOnSet) {\r\n throw new Error(\"Cannot set the value of read-only property\"); // read-only object\r\n }\r\n // return false; // will throw a TypeError exception in strict mode\r\n return true;\r\n } else {\r\n // target[property] = value;\r\n return Reflect.set(target, property, value);\r\n }\r\n }\r\n });\r\n\r\n result[lock] = (l: boolean) => {\r\n locked = l;\r\n };\r\n return result as Readonly<T> & { [lock]: (locked: boolean) => void };\r\n}\r\n\r\nexport type DeepPropertyKey = PropertyKey[];\r\n\r\nexport interface DeepProxyHandler<T extends object> {\r\n // getPrototypeOf?(target: T): object | null;\r\n // setPrototypeOf?(target: T, v: any): boolean;\r\n // isExtensible?(target: T): boolean;\r\n // preventExtensions?(target: T): boolean;\r\n // getOwnPropertyDescriptor?(target: T, p: DeepPropertyKey): PropertyDescriptor | undefined;\r\n // has?(target: T, p: DeepPropertyKey): boolean;\r\n // get?(target: T, p: DeepPropertyKey, receiver: any): any;\r\n set?(target: T, p: DeepPropertyKey, value: any, receiver: any): boolean;\r\n\r\n deleteProperty?(target: T, p: DeepPropertyKey): boolean;\r\n\r\n // defineProperty?(target: T, p: DeepPropertyKey, attributes: PropertyDescriptor): boolean;\r\n // enumerate?(target: T): DeepPropertyKey[];\r\n // ownKeys?(target: T): DeepPropertyKey[];\r\n // apply?(target: T, thisArg: any, argArray?: any): any; // assign\r\n // construct?(target: T, argArray: any, newTarget?: any): object;\r\n}\r\n\r\nexport function createDeepProxy<T extends object>(target: T, handler: DeepProxyHandler<T>) {\r\n const proxyMap = new WeakMap();\r\n\r\n function makeHandler(path: DeepPropertyKey) {\r\n return {\r\n set(target: any, propertyKey: PropertyKey, value: any, receiver) {\r\n if (typeof value === \"object\") {\r\n value = proxify(value, [...path, propertyKey]);\r\n }\r\n target[propertyKey] = value;\r\n\r\n if (handler.set) {\r\n handler.set(target, [...path, propertyKey], value, receiver);\r\n }\r\n return true;\r\n },\r\n\r\n deleteProperty(target: any, propertyKey: PropertyKey) {\r\n if (Reflect.has(target, propertyKey)) {\r\n unproxy(target, propertyKey);\r\n let deleted = Reflect.deleteProperty(target, propertyKey);\r\n if (deleted && handler.deleteProperty) {\r\n handler.deleteProperty(target, [...path, propertyKey]);\r\n }\r\n return deleted;\r\n }\r\n return false;\r\n }\r\n };\r\n }\r\n\r\n function unproxy(obj: any, key: PropertyKey) {\r\n if (proxyMap.has(obj[key])) {\r\n // console.log('unproxy',key);\r\n obj[key] = proxyMap.get(obj[key]);\r\n proxyMap.delete(obj[key]);\r\n }\r\n\r\n for (let k of Object.keys(obj[key])) {\r\n if (typeof obj[key][k] === \"object\") {\r\n unproxy(obj[key], k);\r\n }\r\n }\r\n }\r\n\r\n function proxify(obj: any, path: DeepPropertyKey) {\r\n for (let key of Object.keys(obj)) {\r\n if (typeof obj[key] === \"object\") {\r\n obj[key] = proxify(obj[key], [...path, key]);\r\n }\r\n }\r\n let p = new Proxy(obj, makeHandler(path));\r\n proxyMap.set(p, obj);\r\n return p;\r\n }\r\n\r\n return proxify(target, []);\r\n}\r\n"],"names":["keysOf","obj","entry","name","caseInsensitive","nameStr","keys","key","k","satisfies","keyOf","nameOf","f","p","target","$keyMap","$nh","getPropertyPath","expr","getPropertyPathInternal","path","createProxy","combinePropertyPath","builder","nonObjectTypes","isNonObjectType","type","createConstructor","createInstance","args","getPrototypes","result","prototype","proxify","source","value","getEnumValue","enumType","defaultValue","getEnumValues","getEnumKeys","x","assignWith","dst","src","callback","v","update","props","propSet","set","copy","isPlainObject","proto","sort","noKeys","sortImpl","keyCompareFn","a","b","orderedKeys","container","orderedStringify","replacer","space","jsonEquals","obj1","obj2","jsonClone","lock","toReadOnly","throwOnSet","toReadOnlyInternal","lockTest","locked","property","receiver","l","createDeepProxy","handler","proxyMap","makeHandler","propertyKey","unproxy","deleted"],"mappings":"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"}
1
+ {"version":3,"file":"typeUtils.es.js","sources":["../src/typeUtils.ts"],"sourcesContent":["import { CallableConstructor, Constructor, ConstructorClass } from \"./typeCore\";\r\n\r\n// @filename: typeUtils.ts\r\n\r\n// typed version of Object.keys\r\nexport function keysOf<T extends object>(obj: T) {\r\n return Object.keys(obj) as Array<keyof T>;\r\n}\r\n\r\nexport function entry<T extends object, TKey extends keyof T>(obj: T, name: TKey, caseInsensitive = true) {\r\n if (!obj || !name) {\r\n return undefined;\r\n }\r\n // name.toString()\r\n let nameStr = String(name).trim();\r\n const keys = keysOf(obj);\r\n let key: keyof T;\r\n if (caseInsensitive) {\r\n nameStr = nameStr.toLowerCase();\r\n key = keys.find((k) => String(k).toLowerCase().trim() === nameStr);\r\n } else {\r\n key = keys.find((k) => String(k).trim() === nameStr);\r\n }\r\n return [key, key == undefined ? undefined : (obj[key] as T[TKey])] as [TKey, T[TKey]];\r\n}\r\n\r\nexport function satisfies<TShape>() {\r\n return <T extends TShape>(obj: T) => obj;\r\n}\r\n\r\n// $keyOf\r\nexport const keyOf = <T extends object, TKey extends keyof T = keyof T>(key: TKey, obj?: T) => key;\r\n\r\n// $nameOf/$n\r\nexport function nameOf<T extends object>(f: (x: T) => T[keyof T]): keyof T;\r\nexport function nameOf(f: (x: any) => any): keyof any {\r\n const p = new Proxy(\r\n {},\r\n {\r\n get: (target, key) => key\r\n }\r\n );\r\n return f(p);\r\n}\r\n\r\ntype $KeyMap<T extends object> = {\r\n [K in keyof T]: K;\r\n};\r\n\r\nexport function $keyMap<T extends object>(obj?: T) {\r\n return new Proxy(\r\n {},\r\n {\r\n get: (target, key) => key\r\n }\r\n ) as $KeyMap<T>;\r\n}\r\n\r\n// $NU\r\ntype $NH<T> = {\r\n nameOf(f: (x: T) => T[keyof T]): keyof T;\r\n};\r\n\r\n// $nu\r\n// usage: $nh(obj).nameOf(x => x.prop) or $NH<ClassName>().nameOf(x => x.prop)\r\nexport function $nh<T>(obj?: T) {\r\n return {\r\n nameOf: (f: (x: any) => any) => {\r\n return nameOf(f);\r\n }\r\n } as $NH<T>;\r\n}\r\n\r\nexport function getPropertyPath<T>(expr: (x: T) => any) {\r\n return getPropertyPathInternal(expr);\r\n}\r\n\r\nfunction getPropertyPathInternal<T>(expr: (x: T) => any, path?: (string | number | symbol)[]) {\r\n if (path == undefined) {\r\n path = [];\r\n }\r\n let createProxy: () => any;\r\n createProxy = () => {\r\n return new Proxy(\r\n {},\r\n {\r\n get: (target, key) => {\r\n path.push(key);\r\n return createProxy();\r\n }\r\n }\r\n );\r\n };\r\n expr(createProxy());\r\n return path;\r\n}\r\n\r\nexport function combinePropertyPath(path?: (string | number | symbol)[]) {\r\n const builder: string[] = [];\r\n for (const key of path) {\r\n builder.push(`[\"${key.toString()}\"]`);\r\n }\r\n return builder.join(\"\");\r\n}\r\n\r\nconst nonObjectTypes: Constructor[] = [String, Number];\r\n\r\n// isNonObjectCtor\r\nfunction isNonObjectType<TConstructor extends Constructor>(type: TConstructor) {\r\n return nonObjectTypes.indexOf(type) >= 0;\r\n}\r\n\r\n// getConstructor\r\nexport function createConstructor<TConstructor extends Constructor>(\r\n type: TConstructor // ctor\r\n): CallableConstructor<TConstructor> {\r\n if (isNonObjectType(type)) {\r\n return type as CallableConstructor<TConstructor>;\r\n } else {\r\n function createInstance(...args: ConstructorParameters<TConstructor>): ConstructorClass<TConstructor> {\r\n // return Reflect.construct(type, args); // works too\r\n return new type(...args);\r\n }\r\n\r\n createInstance.prototype = type.prototype;\r\n return createInstance as CallableConstructor<TConstructor>;\r\n }\r\n}\r\n\r\nexport function getPrototypes(obj: any) {\r\n const result = [];\r\n let prototype;\r\n while (true) {\r\n prototype = Object.getPrototypeOf(prototype || obj);\r\n if (!prototype) {\r\n break;\r\n }\r\n result.push(prototype);\r\n }\r\n return result;\r\n}\r\n\r\nexport function proxify<T extends object>(source: () => T): T {\r\n return new Proxy(\r\n {},\r\n {\r\n get: (target, key) => {\r\n return Reflect.get(source(), key);\r\n // return source()[key];\r\n },\r\n set: (target, key, value) => {\r\n return Reflect.set(source(), key, value);\r\n // source()[key] = value;\r\n // return true;\r\n }\r\n }\r\n ) as T;\r\n}\r\n\r\nexport function getEnumValue<T>(enumType: T, name: string, defaultValue: T[keyof T]): T[keyof T] {\r\n let value = name ? enumType[name as keyof T] : defaultValue;\r\n if (value == undefined) {\r\n value = defaultValue;\r\n }\r\n return value;\r\n}\r\n\r\nexport function getEnumValues<T extends object, K extends keyof T>(enumType: T): Array<T[K]> {\r\n return getEnumKeys<T, K>(enumType).map((x) => enumType[x]);\r\n}\r\n\r\nexport function getEnumKeys<T extends object, K extends keyof T>(enumType: T): Array<K> {\r\n return Object.keys(enumType)\r\n .filter((x) => Number.isNaN(Number(x)))\r\n .map((x) => x as K);\r\n}\r\n\r\n// conditional assign with value factory\r\nexport function assignWith<T extends object, U extends object>(\r\n dst: T,\r\n src: U,\r\n callback?: (key: keyof U, value: U[keyof U], set: (value: U[keyof U]) => void) => any\r\n): T & Partial<U> {\r\n const result: T & Partial<U> = dst;\r\n if (src) {\r\n for (const key in src) {\r\n let value = src[key];\r\n const set = (v: U[keyof U]) => {\r\n // result[key as PropertyKey] = value;\r\n Reflect.set(result, key, v);\r\n };\r\n if (callback) {\r\n callback(key, value, set);\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n// constrained and typed assign\r\nexport function update<T extends object, U extends Partial<T>>(dst: T, src: U, props?: [keyof U]): T & Partial<U> {\r\n const propSet = new Set(props);\r\n\r\n return assignWith(dst, src, (key, value, set) => {\r\n if (!propSet.size || propSet.has(key)) {\r\n set(value);\r\n }\r\n });\r\n\r\n // for (const prop of props) {\r\n // // dst[prop as PropertyKey] = src[prop];\r\n // Reflect.set(dst, prop, src[prop]);\r\n // }\r\n // return dst;\r\n}\r\n\r\nexport function copy<T extends object, U extends object>(src: T, dst: U, props?: [keyof T]): U & Partial<T> {\r\n return update(dst, src, props);\r\n}\r\n\r\nexport function isPlainObject(value) {\r\n if (Object.prototype.toString.call(value) !== '[object Object]') return false;\r\n const proto = Object.getPrototypeOf(value);\r\n return proto === null || proto === Object.prototype;\r\n}\r\n\r\nconst sort = (() => {\r\n // It relies on Chrome's and Node's behaviour that the first key assigned to an object is outputted first by JSON.stringify.\r\n const noKeys = []; // emptyKeys\r\n function sortImpl(obj: any, keyCompareFn?: (a: string, b: string) => number) {\r\n const keys = obj ? Object.keys(obj) : noKeys;\r\n // const orderedKeys = desc ? keys.orderByDesc(k => k) : keys.orderBy(k => k);\r\n if (keyCompareFn) {\r\n // array sort method without compare function produces ascending but alphabetical, lexicographic (dictionary) order\r\n keyCompareFn = (a, b) => b.localeCompare(a);\r\n }\r\n const orderedKeys = keys.sort(keyCompareFn);\r\n // result\r\n const container = {}; // sortedObj\r\n for (const key of orderedKeys) {\r\n container[key] = isPlainObject(obj[key]) ? sortImpl(obj[key]) : obj[key];\r\n }\r\n return container;\r\n }\r\n return sortImpl;\r\n})();\r\n\r\n// stableStringify\r\nexport const orderedStringify = (() => {\r\n // https://www.gangofcoders.net/solution/sort-object-properties-and-json-stringify/\r\n // see also: https://www.npmjs.com/package/json-stable-stringify\r\n return (\r\n obj: any,\r\n keyCompareFn?: (a: string, b: string) => number,\r\n replacer?: (this: any, key: string, value: any) => any,\r\n // replacer?: (number | string)[] | null,\r\n space?: string | number\r\n ) => {\r\n return JSON.stringify(sort(obj, keyCompareFn), replacer, space);\r\n };\r\n})();\r\n\r\n// structural comparison helper\r\nexport function jsonEquals<T>(obj1: T, obj2: T) {\r\n // contentEquals\r\n return orderedStringify(obj1) === orderedStringify(obj2);\r\n}\r\n\r\n/** structuredClone alternative */\r\nexport function jsonClone<T extends object>(obj: T): T {\r\n const type = typeof obj;\r\n if (type !== \"object\") {\r\n throw new Error(`Unsupported object type: ${type}`);\r\n }\r\n if (!obj) {\r\n return obj;\r\n }\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n// freeze\r\nexport const lock = Symbol(\"__lock\");\r\n\r\n// IFreezable\r\nexport type ILockable<T = any> = Readonly<T> & { [lock]?: (locked: boolean) => void };\r\n\r\n// deepFreeze/lock\r\nexport function toReadOnly<T extends object>(obj: T, throwOnSet: boolean = false): ILockable<T> {\r\n return toReadOnlyInternal(obj, throwOnSet);\r\n}\r\n\r\nfunction toReadOnlyInternal<T extends object>(obj: T, throwOnSet: boolean = false, lockTest?: () => boolean): ILockable<T> {\r\n if (typeof obj !== \"object\" || !obj) {\r\n return obj;\r\n }\r\n\r\n let locked = true;\r\n if (!lockTest) {\r\n lockTest = () => locked;\r\n }\r\n\r\n const result = new Proxy(obj, {\r\n get: (target, property, receiver) => {\r\n // property in target\r\n if (Reflect.has(target, property)) {\r\n // Reflect.get(target, property)\r\n return toReadOnlyInternal(target[property], throwOnSet, lockTest);\r\n }\r\n return undefined;\r\n },\r\n set: (target, property, value, receiver) => {\r\n if (lockTest()) {\r\n if (throwOnSet) {\r\n throw new Error(\"Cannot set the value of read-only property\"); // read-only object\r\n }\r\n // return false; // will throw a TypeError exception in strict mode\r\n return true;\r\n } else {\r\n // target[property] = value;\r\n return Reflect.set(target, property, value);\r\n }\r\n }\r\n });\r\n\r\n result[lock] = (l: boolean) => {\r\n locked = l;\r\n };\r\n return result as Readonly<T> & { [lock]: (locked: boolean) => void };\r\n}\r\n\r\nexport type DeepPropertyKey = PropertyKey[];\r\n\r\nexport interface DeepProxyHandler<T extends object> {\r\n // getPrototypeOf?(target: T): object | null;\r\n // setPrototypeOf?(target: T, v: any): boolean;\r\n // isExtensible?(target: T): boolean;\r\n // preventExtensions?(target: T): boolean;\r\n // getOwnPropertyDescriptor?(target: T, p: DeepPropertyKey): PropertyDescriptor | undefined;\r\n // has?(target: T, p: DeepPropertyKey): boolean;\r\n // get?(target: T, p: DeepPropertyKey, receiver: any): any;\r\n set?(target: T, p: DeepPropertyKey, value: any, receiver: any): boolean;\r\n\r\n deleteProperty?(target: T, p: DeepPropertyKey): boolean;\r\n\r\n // defineProperty?(target: T, p: DeepPropertyKey, attributes: PropertyDescriptor): boolean;\r\n // enumerate?(target: T): DeepPropertyKey[];\r\n // ownKeys?(target: T): DeepPropertyKey[];\r\n // apply?(target: T, thisArg: any, argArray?: any): any; // assign\r\n // construct?(target: T, argArray: any, newTarget?: any): object;\r\n}\r\n\r\nexport function createDeepProxy<T extends object>(target: T, handler: DeepProxyHandler<T>) {\r\n const proxyMap = new WeakMap();\r\n\r\n function makeHandler(path: DeepPropertyKey) {\r\n return {\r\n set(target: any, propertyKey: PropertyKey, value: any, receiver) {\r\n if (typeof value === \"object\") {\r\n value = proxify(value, [...path, propertyKey]);\r\n }\r\n target[propertyKey] = value;\r\n\r\n if (handler.set) {\r\n handler.set(target, [...path, propertyKey], value, receiver);\r\n }\r\n return true;\r\n },\r\n\r\n deleteProperty(target: any, propertyKey: PropertyKey) {\r\n if (Reflect.has(target, propertyKey)) {\r\n unproxy(target, propertyKey);\r\n let deleted = Reflect.deleteProperty(target, propertyKey);\r\n if (deleted && handler.deleteProperty) {\r\n handler.deleteProperty(target, [...path, propertyKey]);\r\n }\r\n return deleted;\r\n }\r\n return false;\r\n }\r\n };\r\n }\r\n\r\n function unproxy(obj: any, key: PropertyKey) {\r\n if (proxyMap.has(obj[key])) {\r\n // console.log('unproxy',key);\r\n obj[key] = proxyMap.get(obj[key]);\r\n proxyMap.delete(obj[key]);\r\n }\r\n\r\n for (let k of Object.keys(obj[key])) {\r\n if (typeof obj[key][k] === \"object\") {\r\n unproxy(obj[key], k);\r\n }\r\n }\r\n }\r\n\r\n function proxify(obj: any, path: DeepPropertyKey) {\r\n for (let key of Object.keys(obj)) {\r\n if (typeof obj[key] === \"object\") {\r\n obj[key] = proxify(obj[key], [...path, key]);\r\n }\r\n }\r\n let p = new Proxy(obj, makeHandler(path));\r\n proxyMap.set(p, obj);\r\n return p;\r\n }\r\n\r\n return proxify(target, []);\r\n}\r\n"],"names":["keysOf","obj","entry","name","caseInsensitive","nameStr","keys","key","k","satisfies","keyOf","nameOf","f","p","target","$keyMap","$nh","getPropertyPath","expr","getPropertyPathInternal","path","createProxy","combinePropertyPath","builder","nonObjectTypes","isNonObjectType","type","createConstructor","createInstance","args","getPrototypes","result","prototype","proxify","source","value","getEnumValue","enumType","defaultValue","getEnumValues","getEnumKeys","x","assignWith","dst","src","callback","v","update","props","propSet","set","copy","isPlainObject","proto","sort","noKeys","sortImpl","keyCompareFn","a","b","orderedKeys","container","orderedStringify","replacer","space","jsonEquals","obj1","obj2","jsonClone","lock","toReadOnly","throwOnSet","toReadOnlyInternal","lockTest","locked","property","receiver","l","createDeepProxy","handler","proxyMap","makeHandler","propertyKey","unproxy","deleted"],"mappings":"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"}
package/dist/utils.d.ts CHANGED
@@ -9,4 +9,5 @@ export declare const suppressConsole: (action: () => void) => {
9
9
  method: keyof Console;
10
10
  args: any[];
11
11
  }[];
12
+ export declare function memoEffect<TDep, TResult>(getValue: () => TDep, callback: (v: TDep) => TResult, comparator?: (a: TDep, b: TDep) => boolean): () => TResult;
12
13
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,WAAiC,CAAC;AAGrE,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,UAO5C;AAGD,eAAO,MAAM,oBAAoB,YAEZ,GAAG,EAAE,WAiBtB,CAAC;AAEL,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,kBAEpC,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,EAAE,MAAM,KAAK,mBActD,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAS/E;AAQD,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,EAAE,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,OAc7G;AAED,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,IAAI;YAGlC,MAAM,OAAO;UACf,GAAG,EAAE;GAoBlB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,WAAiC,CAAC;AAGrE,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,UAO5C;AAGD,eAAO,MAAM,oBAAoB,YAEZ,GAAG,EAAE,WAiBtB,CAAC;AAEL,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,kBAEpC,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,EAAE,MAAM,KAAK,mBActD,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAS/E;AAQD,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,EAAE,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,OAc7G;AAED,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,IAAI;YAGlC,MAAM,OAAO;UACf,GAAG,EAAE;GAoBlB,CAAC;AAKF,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EACpC,QAAQ,EAAE,MAAM,IAAI,EACpB,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,OAAO,EAC9B,UAAU,GAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,OAA2B,iBAchE"}
package/dist/utils.es.js CHANGED
@@ -1,23 +1,23 @@
1
- import { v4 as i } from "uuid";
2
- const y = (o) => !o || !isFinite(o) ? 0 : o;
3
- function l(...o) {
4
- for (const e of o)
5
- if (e != null)
6
- return e;
1
+ import { v4 as u } from "uuid";
2
+ const a = (o) => !o || !isFinite(o) ? 0 : o;
3
+ function y(...o) {
4
+ for (const t of o)
5
+ if (t != null)
6
+ return t;
7
7
  }
8
- const a = /* @__PURE__ */ (() => {
8
+ const m = /* @__PURE__ */ (() => {
9
9
  const o = /* @__PURE__ */ new WeakMap();
10
- return (...e) => {
10
+ return (...t) => {
11
11
  const r = [];
12
- for (const t of e) {
13
- let n;
14
- typeof t == "number" || typeof t == "string" || typeof t == "boolean" || t == null ? n = "" + t : (n = o.get(t), n || (n = i(), o.set(t, n))), r.push(n);
12
+ for (const n of t) {
13
+ let e;
14
+ typeof n == "number" || typeof n == "string" || typeof n == "boolean" || n == null ? e = "" + n : (e = o.get(n), e || (e = u(), o.set(n, e))), r.push(e);
15
15
  }
16
16
  return `"${r.join("/")}"`;
17
17
  };
18
- })(), m = (o) => new Promise((e) => setTimeout(e, o)), c = (o, e) => (e || (e = new Error("Timeout exceeded")), new Promise(
19
- (r, t) => setTimeout(
20
- () => t(e),
18
+ })(), d = (o) => new Promise((t) => setTimeout(t, o)), c = (o, t) => (t || (t = new Error("Timeout exceeded")), new Promise(
19
+ (r, n) => setTimeout(
20
+ () => n(t),
21
21
  // Don't do this (!):
22
22
  // () => {
23
23
  // throw err;
@@ -25,47 +25,55 @@ const a = /* @__PURE__ */ (() => {
25
25
  o
26
26
  )
27
27
  ));
28
- function d(o, e) {
29
- return Promise.race([c(e), o]);
28
+ function p(o, t) {
29
+ return Promise.race([c(t), o]);
30
30
  }
31
- function u(o, e, r) {
31
+ function f(o, t, r) {
32
32
  if (o)
33
- for (const t of o) {
34
- if (e(t))
35
- return t;
36
- const n = u(r(t), e, r);
37
- if (n)
33
+ for (const n of o) {
34
+ if (t(n))
38
35
  return n;
36
+ const e = f(r(n), t, r);
37
+ if (e)
38
+ return e;
39
39
  }
40
40
  }
41
- const p = (o) => {
42
- const e = {}, r = [], t = [
41
+ const k = (o) => {
42
+ const t = {}, r = [], n = [
43
43
  "log"
44
44
  /*, "debug", "warn", "info"*/
45
45
  ];
46
- for (const n of t)
47
- e[n] = console[n], console[n] = function(...s) {
46
+ for (const e of n)
47
+ t[e] = console[e], console[e] = function(...s) {
48
48
  r.push({
49
- method: n,
49
+ method: e,
50
50
  args: s
51
51
  });
52
52
  };
53
53
  try {
54
54
  o();
55
55
  } finally {
56
- for (const n of t)
57
- console[n] = e[n];
56
+ for (const e of n)
57
+ console[e] = t[e];
58
58
  }
59
59
  return r;
60
60
  };
61
+ function v(o, t, r = (n, e) => n === e) {
62
+ let n, e = !1, s;
63
+ return () => {
64
+ const i = o();
65
+ return (!e || !r(i, n)) && (n = i, e = !0, s = t(i)), s;
66
+ };
67
+ }
61
68
  export {
62
- a as buildFuncArgCacheKey,
63
- m as delayAsync,
69
+ m as buildFuncArgCacheKey,
70
+ d as delayAsync,
64
71
  c as delayErrorAsync,
65
- y as normalize,
66
- l as numericOr,
67
- u as searchTree,
68
- p as suppressConsole,
69
- d as withTimeoutAsync
72
+ v as memoEffect,
73
+ a as normalize,
74
+ y as numericOr,
75
+ f as searchTree,
76
+ k as suppressConsole,
77
+ p as withTimeoutAsync
70
78
  };
71
79
  //# sourceMappingURL=utils.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.es.js","sources":["../src/utils.ts"],"sourcesContent":["import { v4 as uuid } from \"uuid\";\r\n\r\n// @filename: util.ts\r\n\r\n// export function guid() {\r\n// function s4() {\r\n// return Math.floor((1 + Math.random()) * 0x10000)\r\n// .toString(16)\r\n// .substring(1);\r\n// }\r\n// return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\r\n// }\r\n\r\nexport const normalize = (v: number) => (!v || !isFinite(v) ? 0 : v);\r\n\r\n// numericalOr\r\nexport function numericOr(...values: number[]) {\r\n for (const value of values) {\r\n if (value != undefined) {\r\n return value;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n// funcArgCacheKeyResolver(Provider/Builder)\r\nexport const buildFuncArgCacheKey = (() => {\r\n const weakMap = new WeakMap<any, string>();\r\n return (...args: any[]) => {\r\n const keys: string[] = [];\r\n for (const arg of args) {\r\n let key: string = undefined;\r\n if (typeof arg === \"number\" || typeof arg === \"string\" || typeof arg === \"boolean\" || arg == undefined) {\r\n key = \"\" + arg;\r\n } else {\r\n key = weakMap.get(arg);\r\n if (!key) {\r\n key = uuid();\r\n weakMap.set(arg, key);\r\n }\r\n }\r\n keys.push(key);\r\n }\r\n return `\"${keys.join(\"/\")}\"`;\r\n };\r\n})();\r\n\r\nexport const delayAsync = (ms: number) => {\r\n return new Promise<void>((resolve) => setTimeout(resolve, ms));\r\n};\r\n\r\n// scheduleErrorAsync\r\nexport const delayErrorAsync = (ms: number, err?: Error) => {\r\n if (!err) {\r\n err = new Error(\"Timeout exceeded\");\r\n }\r\n return new Promise<never>((_, reject) =>\r\n setTimeout(\r\n () => reject(err),\r\n // Don't do this (!):\r\n // () => {\r\n // throw err;\r\n // },\r\n ms\r\n )\r\n );\r\n};\r\n\r\nexport function withTimeoutAsync<T>(promise: Promise<T>, ms: number): Promise<T> {\r\n // return new Promise((resolve, reject) => {\r\n // const timer = setTimeout(() => reject(new Error('Timeout exceeded')), ms);\r\n // promise.then((value) => {\r\n // clearTimeout(timer);\r\n // resolve(value);\r\n // }, reject);\r\n // });\r\n return Promise.race([delayErrorAsync(ms), promise]);\r\n}\r\n\r\n/**\r\n * Search node in a tree\r\n * @param predicate filter\r\n * @param childSelector\r\n * @param treeNodes\r\n */\r\nexport function searchTree<T>(treeNodes: T[], predicate: (item: T) => boolean, childSelector: (item: T) => T[]) {\r\n if (!treeNodes) {\r\n return undefined;\r\n }\r\n for (const treeNode of treeNodes) {\r\n if (predicate(treeNode)) {\r\n return treeNode;\r\n }\r\n const node = searchTree(childSelector(treeNode), predicate, childSelector);\r\n if (node) {\r\n return node;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nexport const suppressConsole = (action: () => void) => {\r\n const origConsole: any = {};\r\n const result: {\r\n method: keyof Console;\r\n args: any[];\r\n }[] = [];\r\n const keys: (keyof Console)[] = [\"log\" /*, \"debug\", \"warn\", \"info\"*/];\r\n for (const key of keys) {\r\n origConsole[key] = console[key];\r\n console[key] = function (...args: any[]) {\r\n result.push({\r\n method: key,\r\n args: args\r\n });\r\n } as any;\r\n }\r\n try {\r\n action();\r\n } finally {\r\n for (const key of keys) {\r\n console[key] = origConsole[key];\r\n }\r\n }\r\n return result;\r\n};\r\n\r\n\r\n\r\n/*\r\nexport function memoizeThrottle<T extends Func>(\r\n func: T,\r\n wait = 0,\r\n options?: Parameters<typeof _.throttle<T>>[2],\r\n resolver?: Parameters<typeof _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.throttle<T>>>>[1]\r\n) {\r\n const mem = _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.throttle<T>>>(() => {\r\n return _.throttle<T>(func, wait, options);\r\n }, resolver);\r\n\r\n return (...args: Parameters<T>) => {\r\n return mem(...args)(...args);\r\n };\r\n}\r\n\r\nexport function memoizeDebounce<T extends Func>(\r\n func: T,\r\n wait = 0,\r\n options?: Parameters<typeof _.debounce<T>>[2],\r\n resolver?: Parameters<typeof _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.debounce<T>>>>[1]\r\n) {\r\n const mem = _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.debounce<T>>>(() => {\r\n return _.debounce<T>(func, wait, options);\r\n }, resolver);\r\n\r\n return (...args: Parameters<T>) => {\r\n return mem(...args)(...args);\r\n };\r\n}\r\n*/\r\n"],"names":["normalize","v","numericOr","values","value","buildFuncArgCacheKey","weakMap","args","keys","arg","key","uuid","delayAsync","ms","resolve","delayErrorAsync","err","_","reject","withTimeoutAsync","promise","searchTree","treeNodes","predicate","childSelector","treeNode","node","suppressConsole","action","origConsole","result"],"mappings":";AAaa,MAAAA,IAAY,CAACC,MAAe,CAACA,KAAK,CAAC,SAASA,CAAC,IAAI,IAAIA;AAG3D,SAASC,KAAaC,GAAkB;AAC3C,aAAWC,KAASD;AAChB,QAAIC,KAAS;AACF,aAAAA;AAInB;AAGO,MAAMC,IAA8B,uBAAA;AACjC,QAAAC,wBAAc;AACpB,SAAO,IAAIC,MAAgB;AACvB,UAAMC,IAAiB,CAAA;AACvB,eAAWC,KAAOF,GAAM;AACpB,UAAIG;AACA,MAAA,OAAOD,KAAQ,YAAY,OAAOA,KAAQ,YAAY,OAAOA,KAAQ,aAAaA,KAAO,OACzFC,IAAM,KAAKD,KAELC,IAAAJ,EAAQ,IAAIG,CAAG,GAChBC,MACDA,IAAMC,EAAK,GACHL,EAAA,IAAIG,GAAKC,CAAG,KAG5BF,EAAK,KAAKE,CAAG;AAAA,IACjB;AACA,WAAO,IAAIF,EAAK,KAAK,GAAG,CAAC;AAAA,EAAA;AAEjC,GAAG,GAEUI,IAAa,CAACC,MAChB,IAAI,QAAc,CAACC,MAAY,WAAWA,GAASD,CAAE,CAAC,GAIpDE,IAAkB,CAACF,GAAYG,OACnCA,MACKA,IAAA,IAAI,MAAM,kBAAkB,IAE/B,IAAI;AAAA,EAAe,CAACC,GAAGC,MAC1B;AAAA,IACI,MAAMA,EAAOF,CAAG;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhBH;AAAA,EACJ;AAAA;AAIQ,SAAAM,EAAoBC,GAAqBP,GAAwB;AAQ7E,SAAO,QAAQ,KAAK,CAACE,EAAgBF,CAAE,GAAGO,CAAO,CAAC;AACtD;AAQgB,SAAAC,EAAcC,GAAgBC,GAAiCC,GAAiC;AAC5G,MAAKF;AAGL,eAAWG,KAAYH,GAAW;AAC1B,UAAAC,EAAUE,CAAQ;AACX,eAAAA;AAEX,YAAMC,IAAOL,EAAWG,EAAcC,CAAQ,GAAGF,GAAWC,CAAa;AACzE,UAAIE;AACO,eAAAA;AAAA,IAEf;AAEJ;AAEa,MAAAC,IAAkB,CAACC,MAAuB;AACnD,QAAMC,IAAmB,CAAA,GACnBC,IAGA,CAAA,GACAtB,IAA0B;AAAA,IAAC;AAAA;AAAA,EAAA;AACjC,aAAWE,KAAOF;AACF,IAAAqB,EAAAnB,CAAG,IAAI,QAAQA,CAAG,GACtB,QAAAA,CAAG,IAAI,YAAaH,GAAa;AACrC,MAAAuB,EAAO,KAAK;AAAA,QACR,QAAQpB;AAAA,QACR,MAAAH;AAAA,MAAA,CACH;AAAA,IAAA;AAGL,MAAA;AACO,IAAAqB;EAAA,UACT;AACE,eAAWlB,KAAOF;AACN,cAAAE,CAAG,IAAImB,EAAYnB,CAAG;AAAA,EAEtC;AACO,SAAAoB;AACX;"}
1
+ {"version":3,"file":"utils.es.js","sources":["../src/utils.ts"],"sourcesContent":["import { v4 as uuid } from \"uuid\";\r\n\r\n// @filename: util.ts\r\n\r\n// export function guid() {\r\n// function s4() {\r\n// return Math.floor((1 + Math.random()) * 0x10000)\r\n// .toString(16)\r\n// .substring(1);\r\n// }\r\n// return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\r\n// }\r\n\r\nexport const normalize = (v: number) => (!v || !isFinite(v) ? 0 : v);\r\n\r\n// numericalOr\r\nexport function numericOr(...values: number[]) {\r\n for (const value of values) {\r\n if (value != undefined) {\r\n return value;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n// funcArgCacheKeyResolver(Provider/Builder)\r\nexport const buildFuncArgCacheKey = (() => {\r\n const weakMap = new WeakMap<any, string>();\r\n return (...args: any[]) => {\r\n const keys: string[] = [];\r\n for (const arg of args) {\r\n let key: string = undefined;\r\n if (typeof arg === \"number\" || typeof arg === \"string\" || typeof arg === \"boolean\" || arg == undefined) {\r\n key = \"\" + arg;\r\n } else {\r\n key = weakMap.get(arg);\r\n if (!key) {\r\n key = uuid();\r\n weakMap.set(arg, key);\r\n }\r\n }\r\n keys.push(key);\r\n }\r\n return `\"${keys.join(\"/\")}\"`;\r\n };\r\n})();\r\n\r\nexport const delayAsync = (ms: number) => {\r\n return new Promise<void>((resolve) => setTimeout(resolve, ms));\r\n};\r\n\r\n// scheduleErrorAsync\r\nexport const delayErrorAsync = (ms: number, err?: Error) => {\r\n if (!err) {\r\n err = new Error(\"Timeout exceeded\");\r\n }\r\n return new Promise<never>((_, reject) =>\r\n setTimeout(\r\n () => reject(err),\r\n // Don't do this (!):\r\n // () => {\r\n // throw err;\r\n // },\r\n ms\r\n )\r\n );\r\n};\r\n\r\nexport function withTimeoutAsync<T>(promise: Promise<T>, ms: number): Promise<T> {\r\n // return new Promise((resolve, reject) => {\r\n // const timer = setTimeout(() => reject(new Error('Timeout exceeded')), ms);\r\n // promise.then((value) => {\r\n // clearTimeout(timer);\r\n // resolve(value);\r\n // }, reject);\r\n // });\r\n return Promise.race([delayErrorAsync(ms), promise]);\r\n}\r\n\r\n/**\r\n * Search node in a tree\r\n * @param predicate filter\r\n * @param childSelector\r\n * @param treeNodes\r\n */\r\nexport function searchTree<T>(treeNodes: T[], predicate: (item: T) => boolean, childSelector: (item: T) => T[]) {\r\n if (!treeNodes) {\r\n return undefined;\r\n }\r\n for (const treeNode of treeNodes) {\r\n if (predicate(treeNode)) {\r\n return treeNode;\r\n }\r\n const node = searchTree(childSelector(treeNode), predicate, childSelector);\r\n if (node) {\r\n return node;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nexport const suppressConsole = (action: () => void) => {\r\n const origConsole: any = {};\r\n const result: {\r\n method: keyof Console;\r\n args: any[];\r\n }[] = [];\r\n const keys: (keyof Console)[] = [\"log\" /*, \"debug\", \"warn\", \"info\"*/];\r\n for (const key of keys) {\r\n origConsole[key] = console[key];\r\n console[key] = function (...args: any[]) {\r\n result.push({\r\n method: key,\r\n args: args\r\n });\r\n } as any;\r\n }\r\n try {\r\n action();\r\n } finally {\r\n for (const key of keys) {\r\n console[key] = origConsole[key];\r\n }\r\n }\r\n return result;\r\n};\r\n\r\n// another comparator example\r\n// const deepEqual = (a: any, b: any) => JSON.stringify(a) === JSON.stringify(b);\r\n// depEffect\r\nexport function memoEffect<TDep, TResult>(\r\n getValue: () => TDep, // getDep\r\n callback: (v: TDep) => TResult, // onChange/action\r\n comparator: (a: TDep, b: TDep) => boolean = (a, b) => a === b // equals\r\n) {\r\n let val: TDep | undefined;\r\n let initialized = false;\r\n let retVal: TResult;\r\n return () => {\r\n const next = getValue();\r\n if (!initialized || !comparator(next, val!)) {\r\n val = next;\r\n initialized = true;\r\n retVal = callback(next);\r\n }\r\n return retVal;\r\n };\r\n}\r\n\r\n/*\r\nexport function memoizeThrottle<T extends Func>(\r\n func: T,\r\n wait = 0,\r\n options?: Parameters<typeof _.throttle<T>>[2],\r\n resolver?: Parameters<typeof _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.throttle<T>>>>[1]\r\n) {\r\n const mem = _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.throttle<T>>>(() => {\r\n return _.throttle<T>(func, wait, options);\r\n }, resolver);\r\n\r\n return (...args: Parameters<T>) => {\r\n return mem(...args)(...args);\r\n };\r\n}\r\n\r\nexport function memoizeDebounce<T extends Func>(\r\n func: T,\r\n wait = 0,\r\n options?: Parameters<typeof _.debounce<T>>[2],\r\n resolver?: Parameters<typeof _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.debounce<T>>>>[1]\r\n) {\r\n const mem = _.memoize<(...args: Parameters<T>) => ReturnType<typeof _.debounce<T>>>(() => {\r\n return _.debounce<T>(func, wait, options);\r\n }, resolver);\r\n\r\n return (...args: Parameters<T>) => {\r\n return mem(...args)(...args);\r\n };\r\n}\r\n*/\r\n"],"names":["normalize","v","numericOr","values","value","buildFuncArgCacheKey","weakMap","args","keys","arg","key","uuid","delayAsync","ms","resolve","delayErrorAsync","err","_","reject","withTimeoutAsync","promise","searchTree","treeNodes","predicate","childSelector","treeNode","node","suppressConsole","action","origConsole","result","memoEffect","getValue","callback","comparator","a","b","val","initialized","retVal","next"],"mappings":";AAaO,MAAMA,IAAY,CAACC,MAAe,CAACA,KAAK,CAAC,SAASA,CAAC,IAAI,IAAIA;AAG3D,SAASC,KAAaC,GAAkB;AAC3C,aAAWC,KAASD;AAChB,QAAIC,KAAS;AACT,aAAOA;AAInB;AAGO,MAAMC,IAAwB,uBAAM;AACvC,QAAMC,wBAAc,QAAA;AACpB,SAAO,IAAIC,MAAgB;AACvB,UAAMC,IAAiB,CAAA;AACvB,eAAWC,KAAOF,GAAM;AACpB,UAAIG;AACJ,MAAI,OAAOD,KAAQ,YAAY,OAAOA,KAAQ,YAAY,OAAOA,KAAQ,aAAaA,KAAO,OACzFC,IAAM,KAAKD,KAEXC,IAAMJ,EAAQ,IAAIG,CAAG,GAChBC,MACDA,IAAMC,EAAA,GACNL,EAAQ,IAAIG,GAAKC,CAAG,KAG5BF,EAAK,KAAKE,CAAG;AAAA,IACjB;AACA,WAAO,IAAIF,EAAK,KAAK,GAAG,CAAC;AAAA,EAC7B;AACJ,GAAA,GAEaI,IAAa,CAACC,MAChB,IAAI,QAAc,CAACC,MAAY,WAAWA,GAASD,CAAE,CAAC,GAIpDE,IAAkB,CAACF,GAAYG,OACnCA,MACDA,IAAM,IAAI,MAAM,kBAAkB,IAE/B,IAAI;AAAA,EAAe,CAACC,GAAGC,MAC1B;AAAA,IACI,MAAMA,EAAOF,CAAG;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhBH;AAAA,EAAA;AACJ;AAID,SAASM,EAAoBC,GAAqBP,GAAwB;AAQ7E,SAAO,QAAQ,KAAK,CAACE,EAAgBF,CAAE,GAAGO,CAAO,CAAC;AACtD;AAQO,SAASC,EAAcC,GAAgBC,GAAiCC,GAAiC;AAC5G,MAAKF;AAGL,eAAWG,KAAYH,GAAW;AAC9B,UAAIC,EAAUE,CAAQ;AAClB,eAAOA;AAEX,YAAMC,IAAOL,EAAWG,EAAcC,CAAQ,GAAGF,GAAWC,CAAa;AACzE,UAAIE;AACA,eAAOA;AAAA,IAEf;AAEJ;AAEO,MAAMC,IAAkB,CAACC,MAAuB;AACnD,QAAMC,IAAmB,CAAA,GACnBC,IAGA,CAAA,GACAtB,IAA0B;AAAA,IAAC;AAAA;AAAA,EAAA;AACjC,aAAWE,KAAOF;AACd,IAAAqB,EAAYnB,CAAG,IAAI,QAAQA,CAAG,GAC9B,QAAQA,CAAG,IAAI,YAAaH,GAAa;AACrC,MAAAuB,EAAO,KAAK;AAAA,QACR,QAAQpB;AAAA,QACR,MAAAH;AAAA,MAAA,CACH;AAAA,IACL;AAEJ,MAAI;AACA,IAAAqB,EAAA;AAAA,EACJ,UAAA;AACI,eAAWlB,KAAOF;AACd,cAAQE,CAAG,IAAImB,EAAYnB,CAAG;AAAA,EAEtC;AACA,SAAOoB;AACX;AAKO,SAASC,EACZC,GACAC,GACAC,IAA4C,CAACC,GAAGC,MAAMD,MAAMC,GAC9D;AACE,MAAIC,GACAC,IAAc,IACdC;AACJ,SAAO,MAAM;AACT,UAAMC,IAAOR,EAAA;AACb,YAAI,CAACM,KAAe,CAACJ,EAAWM,GAAMH,CAAI,OACtCA,IAAMG,GACNF,IAAc,IACdC,IAASN,EAASO,CAAI,IAEnBD;AAAA,EACX;AACJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"watchable.es.js","sources":["../src/watchable.ts"],"sourcesContent":["import { Mutable, Executor, Func } from \"./typeCore\";\r\n\r\n// PromiseState\r\nexport type PromiseStatus = \"pending\" | \"fulfilled\" | \"rejected\";\r\n\r\n// TrackablePromise\r\nexport type WatchablePromise<T = void> = PromiseLike<T> & {\r\n readonly status?: PromiseStatus;\r\n readonly settled?: boolean;\r\n readonly result?: T;\r\n};\r\n\r\n// WatchableFn\r\nexport type WatchableFunc<TArgs extends any[] = any[], T = any> = Func<TArgs, T> & {\r\n executing?: boolean; // running/inProgress/pending\r\n};\r\n\r\n// we need promise wrapper because Promise [[PromiseState]] and [[PromiseResult]] symbols are not accessible\r\n// exec and watch/track\r\nexport function watch<T = void>(fn: Executor<T>) {\r\n // type PromiseExecutorType = ConstructorParameters<typeof Promise<Awaited<T>>>[0];\r\n let resolve!: (value: Awaited<T>) => void;\r\n // let resolve: Parameters<PromiseExecutorType>[0];\r\n let reject!: (reason: any) => void;\r\n // let reject: Parameters<PromiseExecutorType>[1];\r\n\r\n const promise: Mutable<WatchablePromise<Awaited<T>>> = new Promise<Awaited<T>>((res, rej) => {\r\n resolve = res;\r\n reject = rej;\r\n });\r\n\r\n promise.status = \"pending\";\r\n // TODO: create type-safe defineProperty utility method\r\n Object.defineProperty(promise, \"settled\" satisfies keyof typeof promise, {\r\n get: () => promise.status !== \"pending\"\r\n });\r\n\r\n (async () => {\r\n try {\r\n const retValue = (await Promise.resolve(fn())) as Awaited<T>;\r\n resolve(retValue);\r\n promise.result = retValue;\r\n promise.status = \"fulfilled\";\r\n } catch (err) {\r\n reject(err);\r\n promise.result = undefined;\r\n promise.status = \"rejected\";\r\n }\r\n })();\r\n\r\n return promise as WatchablePromise<Awaited<T>>;\r\n}\r\n\r\n// TODO: add Promise.prototype.finally support\r\n\r\n// toTrackable\r\n/** wrap to watchable func */\r\nexport function toWatchable<TArgs extends any[] = any[], T = void>(fn: Func<TArgs, T>): WatchableFunc<TArgs, T> {\r\n // result\r\n let watchable: Func<TArgs, T> & {\r\n executing?: boolean; // running/inProgress/pending\r\n };\r\n const complete = (err?: any) => {\r\n watchable.executing = false;\r\n // watchable result.executing;\r\n if (err) {\r\n // err instanceof Error\r\n throw err; // need to rethrow!\r\n }\r\n };\r\n watchable = (...args) => {\r\n watchable.executing = true;\r\n let isAsyncFn = false;\r\n try {\r\n const fnResult = fn(...args);\r\n if (fnResult instanceof Promise) {\r\n isAsyncFn = true;\r\n fnResult.catch(complete);\r\n fnResult.then(complete);\r\n }\r\n return fnResult;\r\n } finally {\r\n if (!isAsyncFn) {\r\n complete();\r\n }\r\n }\r\n };\r\n return watchable;\r\n}\r\n"],"names":["watch","fn","resolve","reject","promise","res","rej","retValue","err","toWatchable","watchable","complete","args","isAsyncFn","fnResult"],"mappings":"AAmBO,SAASA,EAAgBC,GAAiB;AAEzC,MAAAC,GAEAC;AAGJ,QAAMC,IAAiD,IAAI,QAAoB,CAACC,GAAKC,MAAQ;AAC/E,IAAAJ,IAAAG,GACDF,IAAAG;AAAA,EAAA,CACZ;AAED,SAAAF,EAAQ,SAAS,WAEV,OAAA,eAAeA,GAAS,WAA0C;AAAA,IACrE,KAAK,MAAMA,EAAQ,WAAW;AAAA,EAAA,CACjC,IAEA,YAAY;AACL,QAAA;AACA,YAAMG,IAAY,MAAM,QAAQ,QAAQN,EAAI,CAAA;AAC5C,MAAAC,EAAQK,CAAQ,GAChBH,EAAQ,SAASG,GACjBH,EAAQ,SAAS;AAAA,aACZI,GAAK;AACV,MAAAL,EAAOK,CAAG,GACVJ,EAAQ,SAAS,QACjBA,EAAQ,SAAS;AAAA,IACrB;AAAA,EAAA,MAGGA;AACX;AAMO,SAASK,EAAmDR,GAA6C;AAExG,MAAAS;AAGE,QAAAC,IAAW,CAACH,MAAc;AAG5B,QAFAE,EAAU,YAAY,IAElBF;AAEM,YAAAA;AAAA,EACV;AAEJ,SAAAE,IAAY,IAAIE,MAAS;AACrB,IAAAF,EAAU,YAAY;AACtB,QAAIG,IAAY;AACZ,QAAA;AACM,YAAAC,IAAWb,EAAG,GAAGW,CAAI;AAC3B,aAAIE,aAAoB,YACRD,IAAA,IACZC,EAAS,MAAMH,CAAQ,GACvBG,EAAS,KAAKH,CAAQ,IAEnBG;AAAA,IAAA,UACT;AACE,MAAKD,KACQF;IAEjB;AAAA,EAAA,GAEGD;AACX;"}
1
+ {"version":3,"file":"watchable.es.js","sources":["../src/watchable.ts"],"sourcesContent":["import { Mutable, Executor, Func } from \"./typeCore\";\r\n\r\n// PromiseState\r\nexport type PromiseStatus = \"pending\" | \"fulfilled\" | \"rejected\";\r\n\r\n// TrackablePromise\r\nexport type WatchablePromise<T = void> = PromiseLike<T> & {\r\n readonly status?: PromiseStatus;\r\n readonly settled?: boolean;\r\n readonly result?: T;\r\n};\r\n\r\n// WatchableFn\r\nexport type WatchableFunc<TArgs extends any[] = any[], T = any> = Func<TArgs, T> & {\r\n executing?: boolean; // running/inProgress/pending\r\n};\r\n\r\n// we need promise wrapper because Promise [[PromiseState]] and [[PromiseResult]] symbols are not accessible\r\n// exec and watch/track\r\nexport function watch<T = void>(fn: Executor<T>) {\r\n // type PromiseExecutorType = ConstructorParameters<typeof Promise<Awaited<T>>>[0];\r\n let resolve!: (value: Awaited<T>) => void;\r\n // let resolve: Parameters<PromiseExecutorType>[0];\r\n let reject!: (reason: any) => void;\r\n // let reject: Parameters<PromiseExecutorType>[1];\r\n\r\n const promise: Mutable<WatchablePromise<Awaited<T>>> = new Promise<Awaited<T>>((res, rej) => {\r\n resolve = res;\r\n reject = rej;\r\n });\r\n\r\n promise.status = \"pending\";\r\n // TODO: create type-safe defineProperty utility method\r\n Object.defineProperty(promise, \"settled\" satisfies keyof typeof promise, {\r\n get: () => promise.status !== \"pending\"\r\n });\r\n\r\n (async () => {\r\n try {\r\n const retValue = (await Promise.resolve(fn())) as Awaited<T>;\r\n resolve(retValue);\r\n promise.result = retValue;\r\n promise.status = \"fulfilled\";\r\n } catch (err) {\r\n reject(err);\r\n promise.result = undefined;\r\n promise.status = \"rejected\";\r\n }\r\n })();\r\n\r\n return promise as WatchablePromise<Awaited<T>>;\r\n}\r\n\r\n// TODO: add Promise.prototype.finally support\r\n\r\n// toTrackable\r\n/** wrap to watchable func */\r\nexport function toWatchable<TArgs extends any[] = any[], T = void>(fn: Func<TArgs, T>): WatchableFunc<TArgs, T> {\r\n // result\r\n let watchable: Func<TArgs, T> & {\r\n executing?: boolean; // running/inProgress/pending\r\n };\r\n const complete = (err?: any) => {\r\n watchable.executing = false;\r\n // watchable result.executing;\r\n if (err) {\r\n // err instanceof Error\r\n throw err; // need to rethrow!\r\n }\r\n };\r\n watchable = (...args) => {\r\n watchable.executing = true;\r\n let isAsyncFn = false;\r\n try {\r\n const fnResult = fn(...args);\r\n if (fnResult instanceof Promise) {\r\n isAsyncFn = true;\r\n fnResult.catch(complete);\r\n fnResult.then(complete);\r\n }\r\n return fnResult;\r\n } finally {\r\n if (!isAsyncFn) {\r\n complete();\r\n }\r\n }\r\n };\r\n return watchable;\r\n}\r\n"],"names":["watch","fn","resolve","reject","promise","res","rej","retValue","err","toWatchable","watchable","complete","args","isAsyncFn","fnResult"],"mappings":"AAmBO,SAASA,EAAgBC,GAAiB;AAE7C,MAAIC,GAEAC;AAGJ,QAAMC,IAAiD,IAAI,QAAoB,CAACC,GAAKC,MAAQ;AACzF,IAAAJ,IAAUG,GACVF,IAASG;AAAA,EACb,CAAC;AAED,SAAAF,EAAQ,SAAS,WAEjB,OAAO,eAAeA,GAAS,WAA0C;AAAA,IACrE,KAAK,MAAMA,EAAQ,WAAW;AAAA,EAAA,CACjC,IAEA,YAAY;AACT,QAAI;AACA,YAAMG,IAAY,MAAM,QAAQ,QAAQN,GAAI;AAC5C,MAAAC,EAAQK,CAAQ,GAChBH,EAAQ,SAASG,GACjBH,EAAQ,SAAS;AAAA,IACrB,SAASI,GAAK;AACV,MAAAL,EAAOK,CAAG,GACVJ,EAAQ,SAAS,QACjBA,EAAQ,SAAS;AAAA,IACrB;AAAA,EACJ,GAAA,GAEOA;AACX;AAMO,SAASK,EAAmDR,GAA6C;AAE5G,MAAIS;AAGJ,QAAMC,IAAW,CAACH,MAAc;AAG5B,QAFAE,EAAU,YAAY,IAElBF;AAEA,YAAMA;AAAA,EAEd;AACA,SAAAE,IAAY,IAAIE,MAAS;AACrB,IAAAF,EAAU,YAAY;AACtB,QAAIG,IAAY;AAChB,QAAI;AACA,YAAMC,IAAWb,EAAG,GAAGW,CAAI;AAC3B,aAAIE,aAAoB,YACpBD,IAAY,IACZC,EAAS,MAAMH,CAAQ,GACvBG,EAAS,KAAKH,CAAQ,IAEnBG;AAAA,IACX,UAAA;AACI,MAAKD,KACDF,EAAA;AAAA,IAER;AAAA,EACJ,GACOD;AACX;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actdim/utico",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "description": "A modern foundation toolkit for complex TypeScript apps",
5
5
  "author": "Pavel Borodaev",
6
6
  "license": "Proprietary",
@@ -50,9 +50,8 @@
50
50
  "scripts": {
51
51
  "test": "npx vitest",
52
52
  "wtest": "npx vitest --watch",
53
- "dtest": "node --inspect-brk node_modules/vitest/vitest.mjs run --poolOptions.threads.singleThread",
54
- "lint": "eslint . -f visualstudio --ext .ts,.tsx --report-unused-disable-directives --max-warnings 0",
55
- "online": "vite --host",
53
+ "dtest": "node --inspect-brk node_modules/vitest/vitest.mjs run --poolOptions.threads.singleThread",
54
+ "lint": "eslint . -f visualstudio --ext .ts,.tsx --report-unused-disable-directives --max-warnings 0",
56
55
  "build": "tsc -b && vite build",
57
56
  "npm:u": "npm update",
58
57
  "npm:ou": "npm outdated",
@@ -68,8 +67,12 @@
68
67
  "uuid": "^13.0.0"
69
68
  },
70
69
  "devDependencies": {
70
+ "@swc/core": "^1.13.5",
71
+ "@types/node": "^24.7.0",
72
+ "@types/uuid": "^11.0.0",
71
73
  "@typescript-eslint/eslint-plugin": "^8.45.0",
72
74
  "@typescript-eslint/parser": "^8.45.0",
75
+ "@vitejs/plugin-react-swc": "^4.1.0",
73
76
  "eslint": "^9.37.0",
74
77
  "eslint-config-prettier": "^10.1.8",
75
78
  "eslint-formatter-visualstudio": "^8.40.0",
@@ -78,19 +81,18 @@
78
81
  "eslint-plugin-react": "^7.37.5",
79
82
  "eslint-plugin-react-hooks": "^6.1.1",
80
83
  "eslint-plugin-react-refresh": "^0.4.23",
81
- "globals": "^16.4.0",
84
+ "fake-indexeddb": "^6.2.2",
85
+ "globals": "^16.4.0",
86
+ "npm-check-updates": "^19.0.0",
82
87
  "prettier": "^3.6.2",
83
88
  "prettier-plugin-classnames": "^0.8.4",
84
- "ts-node": "^10.9.2",
85
- "typescript-eslint": "^8.45.0",
86
- "@types/lodash": "^4.17.20",
87
- "@types/node": "^24.7.0",
88
- "@types/uuid": "^11.0.0",
89
- "@vitejs/plugin-react-swc": "^4.1.0",
90
- "npm-check-updates": "^19.0.0",
91
- "vite": "^7.1.9",
92
89
  "shx": "^0.4.0",
90
+ "ts-node": "^10.9.2",
93
91
  "typescript": "^5.9.3",
94
- "@swc/core": "^1.13.5"
92
+ "typescript-eslint": "^8.45.0",
93
+ "vite": "^7.1.9",
94
+ "vite-plugin-dts": "^4.5.4",
95
+ "vite-tsconfig-paths": "^5.1.4",
96
+ "vitest": "^3.2.4"
95
97
  }
96
98
  }