@zajno/common 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,12 +27,14 @@ Prior to v2 some part of this library were depending on [MobX](https://mobx.js.o
27
27
 
28
28
  It can be used a git submodule if you're brave enough, but it's possible to use it as npm package (kinda) as well. In your project:
29
29
 
30
- 1. Install from NPM
30
+ 1. Install from NPM w/ yarn
31
31
 
32
32
  ```
33
33
  yarn add @zajno/common
34
34
  ```
35
35
 
36
+ [`tslib`](https://www.npmjs.com/package/tslib) is the only peer dependency.
37
+
36
38
  2. In your code, use each module separately:
37
39
 
38
40
  ```typescript
@@ -43,6 +45,8 @@ import logger, { ILogger } from '@zajno/common/logger';
43
45
 
44
46
  Previously one had to import from like `@zajno/common/lib/logger` since compiling had been doing at `postinstall` time so Typescript with its config was a peer dependency. Currently it's not the case and this packages is provided with build artifacts (js + d.ts + source maps); so no need to include `/lib` part in imports anymore.
45
47
 
48
+ Although install time has been decreased, the main downside is that sources are built being targeted on [ES2019 & CommonJS](./tsconfig.json#L13-L14) (for now!). This might be not always suitable and/or optimal for all build setups.
49
+
46
50
  ## Local development
47
51
 
48
52
  If you plan to update the sources while using it in your project, we'd recommend using [`yalc`](https://www.npmjs.com/package/yalc). It does some magic to allow both using it in your project and updating it.
@@ -63,4 +67,4 @@ The flow will look like the following. [1] – operations made on this project,
63
67
  ## Challenges & TODOs
64
68
 
65
69
  1. This library should be and will be updated frequently. When and how to integrate these changes? For small projects that would not be required, but for long-running ones the strategy would be essential.
66
- 2. It needs [more] tests.
70
+ 2. It needs (more) tests.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zajno/common",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "Zajno's re-usable utilities for JS/TS projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,10 +16,10 @@
16
16
  "build": "tsc -P tsconfig.build.json",
17
17
  "build:clean": "rimraf ./lib && yarn build",
18
18
  "build:w": "yarn build --watch",
19
- "publish:local": "yalc push --replace --update",
19
+ "publish:local": "yarn build-for-publish && yarn copy-for-publish && cd lib && yalc push --replace --update",
20
+ "publish:from-lib": "yarn build-for-publish && yarn copy-for-publish && cd lib && yarn publish",
20
21
  "build-for-publish": "yarn build:clean && yarn lint && yarn test",
21
22
  "copy-for-publish": "cpy package.json LICENSE README.md lib/",
22
- "publish-from-lib": "yarn build-for-publish && yarn copy-for-publish && cd lib && yarn publish",
23
23
  "lint": "eslint \"src/**/*.ts?(x)\"",
24
24
  "test": "yarn jest --clearCache && yarn jest"
25
25
  },
@@ -0,0 +1,46 @@
1
+ export declare type DeferredGetter<T> = {
2
+ readonly current: T;
3
+ readonly promise: Promise<T>;
4
+ readonly busy: boolean;
5
+ };
6
+ export declare namespace DeferredGetter {
7
+ const Empty: DeferredGetter<null>;
8
+ }
9
+ export declare class PromiseCache<T, K = string> {
10
+ readonly fetcher: (id: K) => Promise<T>;
11
+ readonly keyAdapter?: K extends string ? null : (k: K) => string;
12
+ readonly keyParser?: K extends string ? null : (id: string) => K;
13
+ protected readonly _itemsCache: Record<string, T>;
14
+ protected readonly _itemsStatus: Record<string, boolean>;
15
+ private readonly _fetchCache;
16
+ private _logger;
17
+ protected _busyCount: number;
18
+ constructor(fetcher: (id: K) => Promise<T>, keyAdapter?: K extends string ? null : (k: K) => string, keyParser?: K extends string ? null : (id: string) => K);
19
+ get busyCount(): number;
20
+ private _pk;
21
+ useLogger(name?: string): this;
22
+ getDeferred(key: K): DeferredGetter<T>;
23
+ getIsBusy(id: K): boolean;
24
+ getCurrent(id: K, initiateFetch?: boolean): T;
25
+ get(id: K): Promise<T>;
26
+ protected _doFetchAsync: (id: K, key: string) => Promise<T>;
27
+ invalidate(id: K): void;
28
+ updateValueDirectly(id: K, value: T): void;
29
+ hasKey(id: K): boolean;
30
+ keys(): string[];
31
+ keysParsed(): K[];
32
+ protected _set(key: string, item: T, promise: Promise<T>, busy: boolean): void;
33
+ /** @override */
34
+ protected setStatus(key: string, status: boolean): void;
35
+ /** @override */
36
+ protected setPromise(key: string, promise: Promise<T>): void;
37
+ /** @override */
38
+ protected onBeforeFetch(_key: string): void;
39
+ /** @override */
40
+ protected prepareResult(res: Awaited<T>): Awaited<T>;
41
+ /** @override */
42
+ protected storeResult(key: string, res: Awaited<T>): void;
43
+ /** @override */
44
+ protected onFetchComplete(key: string): void;
45
+ }
46
+ //# sourceMappingURL=promiseCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promiseCache.d.ts","sourceRoot":"","sources":["../../src/structures/promiseCache.ts"],"names":[],"mappings":"AAEA,oBAAY,cAAc,CAAC,CAAC,IAAI;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,yBAAiB,cAAc,CAAC;IAErB,MAAM,KAAK,sBAKO,CAAC;CAC7B;AAED,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM;IAW/B,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC;IAXpE,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAO;IACxD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAO;IAE/D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAE/D,OAAO,CAAC,OAAO,CAAiB;IAChC,SAAS,CAAC,UAAU,SAAK;gBAGZ,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EACvD,SAAS,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC;IAKpE,IAAW,SAAS,WAA8B;IAElD,OAAO,CAAC,GAAG;IAgBX,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM;IAKvB,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAStC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO;IAKzB,UAAU,CAAC,EAAE,EAAE,CAAC,EAAE,aAAa,UAAO,GAAG,CAAC;IAU1C,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAuBtB,SAAS,CAAC,aAAa,OAAc,CAAC,OAAO,MAAM,gBAajD;IAEF,UAAU,CAAC,EAAE,EAAE,CAAC;IAKhB,mBAAmB,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;IAKnC,MAAM,CAAC,EAAE,EAAE,CAAC;IAKZ,IAAI;IAIJ,UAAU;IAQV,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO;IAMvE,gBAAgB;IAChB,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAIhD,gBAAgB;IAChB,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAIrD,gBAAgB;IAChB,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM;IAIpC,gBAAgB;IAChB,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAIvC,gBAAgB;IAChB,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAIlD,gBAAgB;IAChB,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM;CAKxC"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromiseCache = exports.DeferredGetter = void 0;
4
+ const logger_1 = require("../logger");
5
+ var DeferredGetter;
6
+ (function (DeferredGetter) {
7
+ const _resolvedPromise = Promise.resolve(undefined);
8
+ DeferredGetter.Empty = {
9
+ get current() { return undefined; },
10
+ get promise() { return _resolvedPromise; },
11
+ get busy() { return undefined; },
12
+ isEmpty: true,
13
+ };
14
+ })(DeferredGetter = exports.DeferredGetter || (exports.DeferredGetter = {}));
15
+ class PromiseCache {
16
+ constructor(fetcher, keyAdapter, keyParser) {
17
+ this.fetcher = fetcher;
18
+ this.keyAdapter = keyAdapter;
19
+ this.keyParser = keyParser;
20
+ this._itemsCache = {};
21
+ this._itemsStatus = {};
22
+ this._fetchCache = {};
23
+ this._logger = null;
24
+ this._busyCount = 0;
25
+ this._doFetchAsync = async (id, key) => {
26
+ var _a;
27
+ try {
28
+ this.onBeforeFetch(key);
29
+ let res = await this.fetcher(id);
30
+ if (this._fetchCache[key]) {
31
+ (_a = this._logger) === null || _a === void 0 ? void 0 : _a.log(key, 'item\'s <promise> resolved to', res);
32
+ res = this.prepareResult(res);
33
+ this.storeResult(key, res);
34
+ }
35
+ return res;
36
+ }
37
+ finally {
38
+ this.onFetchComplete(key);
39
+ }
40
+ };
41
+ //
42
+ }
43
+ get busyCount() { return this._busyCount; }
44
+ _pk(k) {
45
+ if (k == null) {
46
+ throw new Error('PromiseCache: null keys are not supported');
47
+ }
48
+ if (typeof k === 'string') {
49
+ return k;
50
+ }
51
+ if (!this.keyAdapter) {
52
+ throw new Error('Provide key adapter for non-string keys');
53
+ }
54
+ return this.keyAdapter(k);
55
+ }
56
+ useLogger(name) {
57
+ this._logger = (0, logger_1.createLogger)(`[PromiseCache:${name || '?'}]`);
58
+ return this;
59
+ }
60
+ getDeferred(key) {
61
+ const self = this;
62
+ return {
63
+ get current() { return self.getCurrent(key); },
64
+ get promise() { return self.get(key); },
65
+ get busy() { return self.getIsBusy(key); },
66
+ };
67
+ }
68
+ getIsBusy(id) {
69
+ const key = this._pk(id);
70
+ return this._itemsStatus[key];
71
+ }
72
+ getCurrent(id, initiateFetch = true) {
73
+ var _a;
74
+ const key = this._pk(id);
75
+ const item = this._itemsCache[key];
76
+ if (initiateFetch) {
77
+ this.get(id);
78
+ }
79
+ (_a = this._logger) === null || _a === void 0 ? void 0 : _a.log(key, 'getCurrent returns', item);
80
+ return item;
81
+ }
82
+ get(id) {
83
+ var _a, _b;
84
+ const key = this._pk(id);
85
+ const item = this._itemsCache[key];
86
+ if (item !== undefined) {
87
+ (_a = this._logger) === null || _a === void 0 ? void 0 : _a.log(key, 'item resolved to', item);
88
+ return Promise.resolve(item);
89
+ }
90
+ let promise = this._fetchCache[key];
91
+ if (promise) {
92
+ (_b = this._logger) === null || _b === void 0 ? void 0 : _b.log(key, 'item resolved to <promise>');
93
+ return promise;
94
+ }
95
+ this.setStatus(key, true);
96
+ promise = this._doFetchAsync(id, key);
97
+ this.setPromise(key, promise);
98
+ return promise;
99
+ }
100
+ invalidate(id) {
101
+ const key = this._pk(id);
102
+ this._set(key, undefined, undefined, undefined);
103
+ }
104
+ updateValueDirectly(id, value) {
105
+ const key = this._pk(id);
106
+ this._set(key, value, undefined, undefined);
107
+ }
108
+ hasKey(id) {
109
+ const key = this._pk(id);
110
+ return this._itemsCache[key] !== undefined || this._itemsStatus[key] !== undefined;
111
+ }
112
+ keys() {
113
+ return Object.keys(this._itemsCache);
114
+ }
115
+ keysParsed() {
116
+ if (!this.keyParser) {
117
+ return null;
118
+ }
119
+ return this.keys().map(this.keyParser);
120
+ }
121
+ _set(key, item, promise, busy) {
122
+ _setX(key, this._fetchCache, promise);
123
+ _setX(key, this._itemsStatus, busy);
124
+ _setX(key, this._itemsCache, item);
125
+ }
126
+ /** @override */
127
+ setStatus(key, status) {
128
+ this._itemsStatus[key] = status;
129
+ }
130
+ /** @override */
131
+ setPromise(key, promise) {
132
+ this._fetchCache[key] = promise;
133
+ }
134
+ /** @override */
135
+ onBeforeFetch(_key) {
136
+ ++this._busyCount;
137
+ }
138
+ /** @override */
139
+ prepareResult(res) {
140
+ return res || null;
141
+ }
142
+ /** @override */
143
+ storeResult(key, res) {
144
+ this._itemsCache[key] = res;
145
+ }
146
+ /** @override */
147
+ onFetchComplete(key) {
148
+ --this._busyCount;
149
+ delete this._fetchCache[key];
150
+ this._itemsStatus[key] = false;
151
+ }
152
+ }
153
+ exports.PromiseCache = PromiseCache;
154
+ function _setX(key, obj, val) {
155
+ if (val === undefined) {
156
+ delete obj[key];
157
+ }
158
+ else {
159
+ obj[key] = val;
160
+ }
161
+ }
162
+ //# sourceMappingURL=promiseCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promiseCache.js","sourceRoot":"","sources":["../../src/structures/promiseCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { IDisposable } from '../functions/disposer';
2
+ declare type Unsub = () => void;
3
+ export declare class SubscribersMap implements IDisposable {
4
+ readonly subscribe: null | ((key: string) => Promise<Unsub[]>);
5
+ readonly name?: string;
6
+ /** Unsusbcribers map: key => unsub fn */
7
+ private readonly _map;
8
+ /** Timeouts map: key => timeout handle */
9
+ private readonly _timeouts;
10
+ private readonly _logger;
11
+ protected _count: number;
12
+ constructor(subscribe: null | ((key: string) => Promise<Unsub[]>), name?: string);
13
+ get count(): number;
14
+ getIsObserving(key: string): boolean;
15
+ getHasObserveTimeout(key: string): boolean;
16
+ enable(key: string, enable: boolean, clearAfter?: number, existingUnsubs?: Unsub[]): Promise<void>;
17
+ private refreshTimeout;
18
+ protected setCount(v: number): void;
19
+ clear(): void;
20
+ dispose(): void;
21
+ }
22
+ export {};
23
+ //# sourceMappingURL=subscribersMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribersMap.d.ts","sourceRoot":"","sources":["../../src/structures/subscribersMap.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEtE,aAAK,KAAK,GAAG,MAAM,IAAI,CAAC;AAExB,qBAAa,cAAe,YAAW,WAAW;IASlC,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IARlG,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IACtD,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,SAAS,CAAC,MAAM,SAAK;gBAEA,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAW,IAAI,CAAC,EAAE,MAAM;IAIlG,IAAW,KAAK,WAA0B;IAEnC,cAAc,CAAC,GAAG,EAAE,MAAM;IAI1B,oBAAoB,CAAC,GAAG,EAAE,MAAM;IAI1B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAE,MAAa,EAAE,cAAc,GAAE,KAAK,EAAS;IAuC3G,OAAO,CAAC,cAAc;IAkBtB,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM;IAIrB,KAAK;IAeL,OAAO;CAGjB"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubscribersMap = void 0;
4
+ const logger_1 = require("../logger");
5
+ const disposer_1 = require("../functions/disposer");
6
+ class SubscribersMap {
7
+ constructor(subscribe, name) {
8
+ this.subscribe = subscribe;
9
+ this.name = name;
10
+ /** Unsusbcribers map: key => unsub fn */
11
+ this._map = new Map();
12
+ /** Timeouts map: key => timeout handle */
13
+ this._timeouts = new Map();
14
+ this._logger = null;
15
+ this._count = 0;
16
+ this._logger = (0, logger_1.createLogger)(`[Observers:${this.name || '?'}]`);
17
+ }
18
+ get count() { return this._count; }
19
+ getIsObserving(key) {
20
+ return this._map.has(key);
21
+ }
22
+ getHasObserveTimeout(key) {
23
+ return this.getIsObserving(key) && this._timeouts.has(key);
24
+ }
25
+ async enable(key, enable, clearAfter = null, existingUnsubs = null) {
26
+ if (enable === this.getIsObserving(key)) {
27
+ this.refreshTimeout(key, enable, clearAfter, true);
28
+ return;
29
+ }
30
+ if (enable) {
31
+ this._logger.log('Adding observer for key =', key, clearAfter ? `, clearAfter = ${clearAfter}` : '');
32
+ // this marker will help to determine whether unsubscribe was requested while we were in process of subscribing
33
+ let disabed = false;
34
+ const marker = () => { disabed = true; };
35
+ this._map.set(key, marker);
36
+ if (!this.subscribe && !existingUnsubs) {
37
+ throw new Error('Neither subscribe function nor existingUnsubs has been configured');
38
+ }
39
+ const unsubs = existingUnsubs || await this.subscribe(key);
40
+ const result = (0, disposer_1.combineDisposers)(...unsubs);
41
+ if (disabed) { // unsubscribe was requested
42
+ result();
43
+ }
44
+ else {
45
+ this._map.set(key, result);
46
+ this.setCount(this._count + 1);
47
+ this.refreshTimeout(key, true, clearAfter);
48
+ }
49
+ }
50
+ else {
51
+ this._logger.log('Removing observer for key =', key);
52
+ this.refreshTimeout(key, false);
53
+ const unsub = this._map.get(key);
54
+ this._map.delete(key);
55
+ unsub();
56
+ this.setCount(this._count - 1);
57
+ }
58
+ }
59
+ refreshTimeout(key, enable, timeout, refresh = false) {
60
+ const current = this._timeouts.get(key);
61
+ if (current) {
62
+ clearTimeout(current);
63
+ this._timeouts.delete(key);
64
+ }
65
+ if (enable && refresh && current == null) {
66
+ // DO NOT setup new timeout because it's not intended to clear subscribtion if it was previously enabled for long term
67
+ return;
68
+ }
69
+ if (enable && timeout) {
70
+ const t = setTimeout(() => this.enable(key, false), timeout);
71
+ this._timeouts.set(key, t);
72
+ }
73
+ }
74
+ setCount(v) {
75
+ this._count = v;
76
+ }
77
+ clear() {
78
+ // Clear timeouts
79
+ for (const t of this._timeouts.values()) {
80
+ clearTimeout(t);
81
+ }
82
+ this._timeouts.clear();
83
+ // Invoke unsubscribers
84
+ for (const u of this._map.values()) {
85
+ u();
86
+ }
87
+ this._map.clear();
88
+ this.setCount(0);
89
+ }
90
+ dispose() {
91
+ this.clear();
92
+ }
93
+ }
94
+ exports.SubscribersMap = SubscribersMap;
95
+ //# sourceMappingURL=subscribersMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribersMap.js","sourceRoot":"","sources":["../../src/structures/subscribersMap.ts"],"names":[],"mappings":"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"}
package/types/index.d.ts CHANGED
@@ -12,4 +12,5 @@ export declare type NestedPick<T, K extends any[]> = K extends Array<never> ? T
12
12
  export declare type Mutable<T> = {
13
13
  -readonly [P in keyof T]: T[P];
14
14
  };
15
+ export declare type LengthArray<T, N extends number, R extends T[] = []> = number extends N ? T[] : R['length'] extends N ? R : LengthArray<T, N, [T, ...R]>;
15
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAE7B,oBAAY,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;AAEjD,oBAAY,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI;KACxC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK;CAC7C,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,oBAAY,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAEpE,oBAAY,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,CAAC,GAC7D,CAAC,GACD;KACG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK;CAC1E,CAAC;AAEN,oBAAY,OAAO,CAAC,CAAC,IAAI;IACrB,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACjC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAE7B,oBAAY,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;AAEjD,oBAAY,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI;KACxC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK;CAC7C,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,oBAAY,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAEpE,oBAAY,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,CAAC,GAC7D,CAAC,GACD;KACG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK;CAC1E,CAAC;AAEN,oBAAY,OAAO,CAAC,CAAC,IAAI;IACrB,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACjC,CAAC;AAGF,oBAAY,WAAW,CACf,CAAC,EACD,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAClB,MAAM,SAAS,CAAC,GACd,CAAC,EAAE,GACH,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GACrB,CAAC,GACD,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC"}