@kirill.konshin/utils 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @kirill.konshin/utils
2
+
3
+ ## 0.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 7e76543: Initial release
@@ -0,0 +1,27 @@
1
+ export declare function shallowCompare(prev: any, next: any): boolean;
2
+ export declare function equal(prev: any, next: any): boolean;
3
+ export declare class CacheInPlace<Key, Val, Dep = any> {
4
+ protected readonly name: string;
5
+ protected map: Map<Key, Val>;
6
+ protected lastDependency: Dep | null;
7
+ constructor(name: string);
8
+ private compare;
9
+ trackDependency(dependency: Dep, shallow?: boolean): boolean;
10
+ remove(key: Key): void;
11
+ dispose(value: Val, key: Key): void;
12
+ clear(): void;
13
+ memo({ key, memo, hit, invalidate, }: {
14
+ key: Key;
15
+ memo: (oldValue: Val | undefined, key: Key) => Promise<Val> | Val;
16
+ hit?: (oldValue: Val, key: Key) => Promise<Val> | Val;
17
+ invalidate?: (oldValue: Val, key: Key) => boolean;
18
+ }): Promise<Val>;
19
+ get size(): number;
20
+ }
21
+ export declare abstract class TypedCache<Key, Val = Key, Dep = any> extends CacheInPlace<Key, Val, Dep> {
22
+ protected invalidate(newValue: Val, oldValue: Val, key: Key): boolean;
23
+ protected memoizer(key: Key, newValue: Val, oldValue: Val | undefined): Promise<Val> | Val;
24
+ protected hit(oldValue: Val, key: Key): Promise<Val> | Val;
25
+ memo(init: any): Promise<Val>;
26
+ memoValue(key: Key, newValue: Val): Promise<Val>;
27
+ }
package/build/cache.js ADDED
@@ -0,0 +1,80 @@
1
+ export function shallowCompare(prev, next) {
2
+ for (const key of Object.keys(prev).concat(Object.keys(next))) {
3
+ if (prev[key] !== next[key])
4
+ return false;
5
+ }
6
+ return true;
7
+ }
8
+ export function equal(prev, next) {
9
+ return prev === next;
10
+ }
11
+ export class CacheInPlace {
12
+ constructor(name) {
13
+ this.name = name;
14
+ this.map = new Map();
15
+ this.lastDependency = null;
16
+ }
17
+ compare(prev, next, shallow = false) {
18
+ const comparator = shallow ? shallowCompare : equal;
19
+ return comparator(prev, next);
20
+ }
21
+ trackDependency(dependency, shallow = false) {
22
+ if (!this.lastDependency || !dependency || this.compare(this.lastDependency, dependency, shallow)) {
23
+ // console.log('RETAINED cache', this.name, 'last', this.lastObj, 'new', obj);
24
+ return false;
25
+ }
26
+ // console.log('INVALIDATED cache', this.name, 'last', this.lastObj, 'new', obj);
27
+ this.map.clear();
28
+ this.lastDependency = dependency;
29
+ return true;
30
+ }
31
+ remove(key) {
32
+ if (this.map.has(key))
33
+ this.dispose(this.map.get(key), key);
34
+ this.map.delete(key);
35
+ }
36
+ dispose(value, key) { }
37
+ clear() {
38
+ console.log('CLEAR cache', this.name);
39
+ this.map.forEach(this.dispose);
40
+ this.map.clear();
41
+ this.lastDependency = null;
42
+ }
43
+ async memo({ key, memo, hit, invalidate, }) {
44
+ const oldValue = this.map.get(key);
45
+ if (!!oldValue && invalidate && !invalidate(oldValue, key)) {
46
+ return hit ? await hit(oldValue, key) : oldValue;
47
+ }
48
+ if (this.map.has(key))
49
+ this.remove(key);
50
+ const value = await memo(oldValue, key);
51
+ this.map.set(key, value);
52
+ // console.log('INVALIDATED KEY cache', this.name, key, 'has', has, 'invalidate', invalidate, 'new value', value);
53
+ return value;
54
+ }
55
+ get size() {
56
+ return this.map.size;
57
+ }
58
+ }
59
+ export class TypedCache extends CacheInPlace {
60
+ invalidate(newValue, oldValue, key) {
61
+ return newValue && newValue !== oldValue; // shallow compare ever?
62
+ }
63
+ memoizer(key, newValue, oldValue) {
64
+ return newValue;
65
+ }
66
+ hit(oldValue, key) {
67
+ return oldValue;
68
+ }
69
+ async memo(init) {
70
+ throw new Error('Use memoIfNotFound() method');
71
+ }
72
+ async memoValue(key, newValue) {
73
+ return super.memo({
74
+ key,
75
+ memo: (oldValue) => this.memoizer(key, newValue, oldValue),
76
+ hit: this.hit,
77
+ invalidate: (oldValue, key) => this.invalidate(newValue, oldValue, key),
78
+ });
79
+ }
80
+ }
@@ -0,0 +1,4 @@
1
+ export * as cache from './cache';
2
+ export * as measure from './measure';
3
+ export * as mutex from './mutex';
4
+ export * as worker from './worker';
package/build/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * as cache from './cache';
2
+ export * as measure from './measure';
3
+ export * as mutex from './mutex';
4
+ export * as worker from './worker';
@@ -0,0 +1,34 @@
1
+ import { bold, magenta, cyan, yellow, red, green } from 'colors/safe';
2
+ export declare const colored: {
3
+ important: typeof bold;
4
+ subject: typeof magenta;
5
+ arg: typeof cyan;
6
+ sup: typeof yellow;
7
+ err: typeof red;
8
+ ok: typeof green;
9
+ };
10
+ export declare const uncolored: {
11
+ important: (str: any) => any;
12
+ subject: (str: any) => any;
13
+ arg: (str: any) => any;
14
+ sup: (str: any) => any;
15
+ err: (str: any) => any;
16
+ ok: (str: any) => any;
17
+ };
18
+ export declare function createMeasurer({ colors, prepend, padding }: {
19
+ colors?: boolean | undefined;
20
+ prepend?: string | undefined;
21
+ padding?: number | undefined;
22
+ }): {
23
+ measure: (what: string, step: string, supplemental?: string, ...args: any[]) => {
24
+ done: (result?: string, ...args2: any[]) => void;
25
+ fail: (result?: string, ...args2: any[]) => void;
26
+ log: (...args2: any[]) => void;
27
+ };
28
+ important: (str: any) => any;
29
+ subject: (str: any) => any;
30
+ arg: (str: any) => any;
31
+ sup: (str: any) => any;
32
+ ok: (str: any) => any;
33
+ err: (str: any) => any;
34
+ };
@@ -0,0 +1,48 @@
1
+ import { bold, magenta, cyan, yellow, red, green } from 'colors/safe';
2
+ export const colored = {
3
+ important: bold,
4
+ subject: magenta,
5
+ arg: cyan,
6
+ sup: yellow,
7
+ err: red,
8
+ ok: green,
9
+ };
10
+ const noColor = (str) => str;
11
+ export const uncolored = {
12
+ important: noColor,
13
+ subject: noColor,
14
+ arg: noColor,
15
+ sup: noColor,
16
+ err: noColor,
17
+ ok: noColor,
18
+ };
19
+ export function createMeasurer({ colors = true, prepend = 'LOG', padding = 10 }) {
20
+ const { important, subject, arg, sup, ok, err } = colors ? colored : uncolored;
21
+ function measure(what, step, supplemental = '', ...args) {
22
+ const time = performance.now();
23
+ const prefix = [
24
+ prepend,
25
+ important(subject(what.substring(0, padding).padStart(padding, ' '))),
26
+ arg(step),
27
+ sup(supplemental),
28
+ ...args,
29
+ ];
30
+ const done = (result = ok('DONE'), ...args2) => {
31
+ console.log(...[
32
+ ...prefix,
33
+ important(result),
34
+ ...args2,
35
+ 'in',
36
+ important((performance.now() - time).toFixed(0)),
37
+ 'ms',
38
+ ].filter(Boolean));
39
+ console.groupEnd();
40
+ };
41
+ const fail = (result = err('FAIL'), ...args2) => done(result, ...args2);
42
+ const log = (...args2) => {
43
+ console.log(...prefix, ...args2);
44
+ };
45
+ return { done, fail, log };
46
+ }
47
+ return { measure, important, subject, arg, sup, ok, err };
48
+ }
@@ -0,0 +1,5 @@
1
+ export declare class Mutex {
2
+ private promise;
3
+ exec(fn: (...args: any) => any): ReturnType<typeof fn>;
4
+ wrap(fn: (...args: any) => any): ReturnType<typeof fn>;
5
+ }
package/build/mutex.js ADDED
@@ -0,0 +1,22 @@
1
+ //TODO Implement queue with ranking & sorting
2
+ export class Mutex {
3
+ constructor() {
4
+ this.promise = Promise.resolve();
5
+ }
6
+ exec(fn) {
7
+ return new Promise((resolve, reject) => {
8
+ // wrap in always successful function
9
+ this.promise = this.promise.then(async () => {
10
+ try {
11
+ resolve(await fn());
12
+ }
13
+ catch (e) {
14
+ reject(e);
15
+ }
16
+ });
17
+ });
18
+ }
19
+ wrap(fn) {
20
+ return (...args) => this.exec(() => fn(...args));
21
+ }
22
+ }
@@ -0,0 +1,83 @@
1
+ export declare function isTransferable(obj: any): boolean;
2
+ type WebWorker = Worker | (Window & typeof globalThis) | (WorkerGlobalScope & typeof globalThis);
3
+ type MethodReturn<R, M extends keyof R> = R[M] extends (...args: any[]) => any ? Partial<Awaited<ReturnType<R[M]>>> : never;
4
+ type MethodArg<R, M extends keyof R> = R[M] extends (arg: infer A, ...args: any[]) => any ? Partial<A> : never;
5
+ export type Ctx<R, K extends keyof R> = {
6
+ id: string;
7
+ parentId?: string;
8
+ message: K;
9
+ };
10
+ type Data<R, M extends keyof R> = MethodReturn<R, M> | MethodArg<R, M> | Error;
11
+ type Event<R, M extends keyof R> = MessageEvent<{
12
+ data: Data<R, M>;
13
+ ctx: Ctx<R, M>;
14
+ }>;
15
+ type Listener<R, M extends keyof R, D extends Data<R, M> = Data<R, M>, S extends Context<R, M> = Context<R, M>> = (data: D, self: S, event: Event<R, M>) => void | Promise<void>;
16
+ export declare class WorkerDialog<R extends RespondersBase<any>> {
17
+ worker: WebWorker;
18
+ responders: R;
19
+ name: string;
20
+ readonly contexts: Set<Context<R, keyof R>>;
21
+ protected closed: boolean;
22
+ constructor(worker: WebWorker, responders: R, name: string);
23
+ close(): void;
24
+ withMessage<M extends keyof R>(message: M): RequestContext<R, M>;
25
+ }
26
+ export declare class RespondersBase<R> {
27
+ create<M extends keyof R, F extends (input: any, context: ResponseContext<R, M>) => any>(message: M, responder: F): F;
28
+ }
29
+ declare abstract class Context<R, M extends keyof R> {
30
+ protected readonly dialog: WorkerDialog<any>;
31
+ message: M;
32
+ id: string | undefined;
33
+ parent: Context<R, keyof R> | undefined | null;
34
+ protected readonly unsub: Set<() => void>;
35
+ protected closed: boolean;
36
+ constructor(dialog: WorkerDialog<any>, message: M, id: string | undefined, parent?: Context<R, keyof R> | undefined | null);
37
+ abstract withMessage<M2 extends keyof R>(message: M2, id?: string): Context<R, M2>;
38
+ close(reason?: string): void;
39
+ get info(): string;
40
+ protected postMessage(data?: Data<R, M>): Data<R, M> | undefined;
41
+ send(data?: Data<R, M>): Data<R, M> | undefined;
42
+ /**
43
+ * Does not automatically close, assumes consumer will close
44
+ *
45
+ * ```ts
46
+ * dialog.request('x').fetch((c) => {
47
+ * c.response('x').listen(() => { ... }); // listens to "x", will be closed by upper level fetch
48
+ * c.request('x').fetcH(y, (c) => { ... }); // closes
49
+ * }) // closes
50
+ *
51
+ * const un = dialog.context('x').listen((e) => { ... }); // listens to 'x'
52
+ * un(); // closes
53
+ *
54
+ * const un = dialog.context('x').listen((e) => { ... }); // listens to 'x'
55
+ * un(); // closes
56
+ * ```
57
+ */
58
+ listen(callback: Listener<R, M>): () => void;
59
+ }
60
+ declare class RequestContext<R, M extends keyof R> extends Context<R, M> {
61
+ withMessage<M2 extends keyof R>(message: M2, id?: string): RequestContext<R, M2>;
62
+ send(data?: MethodArg<R, M>): MethodArg<R, M>;
63
+ listen(callback: Listener<R, M, MethodReturn<R, M>, RequestContext<R, M>>): () => void;
64
+ /**
65
+ * Returns response
66
+ * If you need to work with ctx, use callback
67
+ * Closed automatically on response
68
+ *
69
+ * dialog.fetch('x', (c) => {
70
+ * c.listen(() => { ... }); // will be closed by upper level fetch
71
+ * c.fetcH(y, (c) => { ... }); // closes c
72
+ * c.context().fetcH(y, (c) => { ... }); // closes sub, not closes c, will be closed by upper level fetch
73
+ * })
74
+ */
75
+ fetch(data?: MethodArg<R, M>, callback?: (context: RequestContext<R, M>) => void): Promise<MethodReturn<R, M>>;
76
+ protected expect(): Promise<MethodReturn<R, M>>;
77
+ }
78
+ declare class ResponseContext<R, M extends keyof R> extends Context<R, M> {
79
+ withMessage<M2 extends keyof R>(message: M2, id?: string): ResponseContext<R, M2>;
80
+ listen(callback: Listener<R, M, MethodArg<R, M>, ResponseContext<R, M>>): () => void;
81
+ send(data?: MethodReturn<R, M>): MethodReturn<R, M>;
82
+ }
83
+ export {};
@@ -0,0 +1,250 @@
1
+ export function isTransferable(obj) {
2
+ return transferrable.some((t) => obj instanceof t) ? obj : null;
3
+ }
4
+ function getTransferrable(data = {}) {
5
+ if (!data)
6
+ return [];
7
+ return Object.values(data)
8
+ .reduce((r, v) => {
9
+ return Array.isArray(v) ? [...r, ...v.map(isTransferable)] : [...r, isTransferable(v)];
10
+ }, [])
11
+ .filter(Boolean);
12
+ }
13
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects
14
+ const transferrable = typeof window !== 'undefined'
15
+ ? [
16
+ ArrayBuffer,
17
+ MessagePort,
18
+ ReadableStream,
19
+ WritableStream,
20
+ TransformStream,
21
+ // WebTransportReceiveStream, // ReferenceError: WebTransportReceiveStream is not defined
22
+ // WebTransportSendStream, // ReferenceError: WebTransportReceiveStream is not defined
23
+ // AudioData, // TS2304: Cannot find name AudioData
24
+ ImageBitmap,
25
+ VideoFrame,
26
+ OffscreenCanvas,
27
+ RTCDataChannel,
28
+ MediaSourceHandle,
29
+ // MIDIAccess, // ReferenceError: MIDIAccess is not defined
30
+ ].filter(Boolean)
31
+ : [];
32
+ const ALL = '*';
33
+ let id = 0;
34
+ function getID() {
35
+ return (++id).toString();
36
+ }
37
+ function checkClosed(obj, label = 'external') {
38
+ if (obj === null || obj === void 0 ? void 0 : obj.closed)
39
+ throw new Error(`Context is closed ${this.info} (${label})`, { cause: obj });
40
+ }
41
+ function checkMessage(obj, message) {
42
+ if (!message)
43
+ throw new Error('New context must have message', { cause: obj });
44
+ }
45
+ export class WorkerDialog {
46
+ constructor(worker, responders, name) {
47
+ this.worker = worker;
48
+ this.responders = responders;
49
+ this.name = name;
50
+ this.contexts = new Set();
51
+ this.closed = false;
52
+ if (!this.worker)
53
+ return; // Next.js SSR
54
+ for (const message in this.responders) {
55
+ if (['constructor', 'create'].includes(message))
56
+ continue;
57
+ // root context with id=all
58
+ const rootContext = new ResponseContext(this, message, ALL);
59
+ //TODO: unsub(); ? Probably not needed, root must be always listening until closed by WorkerDialog
60
+ rootContext.listen(async (data, context, event) => {
61
+ // create sub context with ID
62
+ const responseContext = context.withMessage(message, event.data.ctx.id);
63
+ console.log('Root Listener', rootContext.info, {
64
+ rootContext: context,
65
+ data,
66
+ responseContext,
67
+ event,
68
+ responder: this.responders[message],
69
+ });
70
+ try {
71
+ responseContext.send(await this.responders[message](data, responseContext));
72
+ responseContext.close('root.listener');
73
+ }
74
+ catch (e) {
75
+ console.error(`Error in responder ${responseContext.info}`, { e });
76
+ responseContext.send(e);
77
+ }
78
+ });
79
+ }
80
+ }
81
+ close() {
82
+ for (const context of this.contexts)
83
+ context.close('root');
84
+ this.contexts.clear();
85
+ this.worker.onmessage = null;
86
+ }
87
+ withMessage(message) {
88
+ return new RequestContext(this, message, getID());
89
+ }
90
+ }
91
+ export class RespondersBase {
92
+ create(message, responder) {
93
+ return responder;
94
+ }
95
+ }
96
+ // can only be used to create actual contexts, carries the context data
97
+ class Context {
98
+ constructor(dialog, message, id, parent = null) {
99
+ var _a;
100
+ this.dialog = dialog;
101
+ this.message = message;
102
+ this.id = id;
103
+ this.parent = parent;
104
+ this.unsub = new Set();
105
+ this.closed = false;
106
+ checkClosed(this.dialog, 'newContext');
107
+ checkClosed(this.parent, 'newContext');
108
+ checkMessage(this, message);
109
+ this.id = (parent === null || parent === void 0 ? void 0 : parent.id) === ALL ? getID() : id ? id : (_a = this.parent) === null || _a === void 0 ? void 0 : _a.id;
110
+ if (!this.id)
111
+ throw new Error('ID is required', { cause: this });
112
+ }
113
+ close(reason = 'external') {
114
+ // console.log('Closing', this.id, reason, this);
115
+ this.dialog.contexts.delete(this);
116
+ // Unsubscribe from all listeners
117
+ for (const unsub of this.unsub)
118
+ unsub();
119
+ this.unsub.clear();
120
+ // Remove all child contexts
121
+ this.dialog.contexts.forEach((context) => {
122
+ var _a;
123
+ if (((_a = context.parent) === null || _a === void 0 ? void 0 : _a.id) === this.id)
124
+ context.close('parent');
125
+ });
126
+ this.closed = true;
127
+ }
128
+ get info() {
129
+ var _a;
130
+ return this.dialog.name + '.' + ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.id) + '.' + this.id + '.' + this.message.toString();
131
+ }
132
+ postMessage(data) {
133
+ var _a;
134
+ checkClosed(this, 'postMessage');
135
+ const transfer = getTransferrable(data);
136
+ // console.log('postMessage', this.id, this, { mergedCtx, data, transfer });
137
+ this.dialog.worker.postMessage({
138
+ data,
139
+ ctx: {
140
+ id: this.id,
141
+ parentId: (_a = this.parent) === null || _a === void 0 ? void 0 : _a.id,
142
+ message: this.message,
143
+ },
144
+ }, transfer);
145
+ return data;
146
+ }
147
+ send(data) {
148
+ return this.postMessage(data);
149
+ }
150
+ /**
151
+ * Does not automatically close, assumes consumer will close
152
+ *
153
+ * ```ts
154
+ * dialog.request('x').fetch((c) => {
155
+ * c.response('x').listen(() => { ... }); // listens to "x", will be closed by upper level fetch
156
+ * c.request('x').fetcH(y, (c) => { ... }); // closes
157
+ * }) // closes
158
+ *
159
+ * const un = dialog.context('x').listen((e) => { ... }); // listens to 'x'
160
+ * un(); // closes
161
+ *
162
+ * const un = dialog.context('x').listen((e) => { ... }); // listens to 'x'
163
+ * un(); // closes
164
+ * ```
165
+ */
166
+ listen(callback) {
167
+ checkClosed(this, 'listen');
168
+ let workerListener;
169
+ this.dialog.worker.addEventListener('message', (workerListener = async (event) => {
170
+ try {
171
+ const { data: { ctx, data }, } = event;
172
+ if (!ctx || (this.id !== ALL && this.id !== ctx.id) || this.message !== ctx.message)
173
+ return; // unknown message from devtools etc., or different context
174
+ console.log('Shared listener event', this.info, this, event);
175
+ await callback(data, this, event); // Requests can come here, but they're typed in responders
176
+ }
177
+ catch (e) {
178
+ console.error(`Error in listener ${this.info}`, this, { event, e });
179
+ }
180
+ }));
181
+ const unsub = () => {
182
+ // console.log('Stop listening', this.id, this);
183
+ this.dialog.worker.removeEventListener('message', workerListener);
184
+ this.unsub.delete(unsub);
185
+ };
186
+ this.unsub.add(unsub);
187
+ return unsub;
188
+ }
189
+ }
190
+ class RequestContext extends Context {
191
+ withMessage(message, id) {
192
+ return new RequestContext(this.dialog, message, id, this);
193
+ }
194
+ send(data) {
195
+ return super.send(data);
196
+ }
197
+ listen(callback) {
198
+ return super.listen(callback);
199
+ }
200
+ /**
201
+ * Returns response
202
+ * If you need to work with ctx, use callback
203
+ * Closed automatically on response
204
+ *
205
+ * dialog.fetch('x', (c) => {
206
+ * c.listen(() => { ... }); // will be closed by upper level fetch
207
+ * c.fetcH(y, (c) => { ... }); // closes c
208
+ * c.context().fetcH(y, (c) => { ... }); // closes sub, not closes c, will be closed by upper level fetch
209
+ * })
210
+ */
211
+ async fetch(data, callback) {
212
+ const res = await Promise.all([
213
+ callback === null || callback === void 0 ? void 0 : callback(this),
214
+ this.expect(), // will be closed in expect -> listener -> unsub
215
+ this.send(data),
216
+ ]);
217
+ // console.log('Fetch', this.id, this.contexts, this.ownContexts);
218
+ this.close('fetch');
219
+ return res[1];
220
+ }
221
+ async expect() {
222
+ checkClosed(this, 'expect');
223
+ //FIXME Manual promise type
224
+ return new Promise((resolve, reject) => {
225
+ const responseListener = this.listen(async (data) => {
226
+ try {
227
+ if (data instanceof Error)
228
+ throw data;
229
+ responseListener();
230
+ // console.log('Expect', this.id, this, eventData);
231
+ resolve(data);
232
+ }
233
+ catch (e) {
234
+ reject(e);
235
+ }
236
+ });
237
+ });
238
+ }
239
+ }
240
+ class ResponseContext extends Context {
241
+ withMessage(message, id) {
242
+ return new ResponseContext(this.dialog, message, id, this);
243
+ }
244
+ listen(callback) {
245
+ return super.listen(callback);
246
+ }
247
+ send(data) {
248
+ return super.send(data);
249
+ }
250
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@kirill.konshin/utils",
3
+ "version": "0.0.2",
4
+ "type": "module",
5
+ "main": "build/index.js",
6
+ "module": "build/index.js",
7
+ "types": "build/index.d.ts",
8
+ "exports": {
9
+ ".": "./build/index.js",
10
+ "./measure": "./build/measure.js"
11
+ },
12
+ "scripts": {
13
+ "clean": "rm -rf .tscache tsconfig.tsbuildinfo build",
14
+ "build": "tsc --build",
15
+ "start": "yarn build:ts --watch --preserveWatchOutput",
16
+ "wait": "wait-on build/index.js"
17
+ },
18
+ "dependencies": {
19
+ "colors": "^1.4.0"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "^5.7.2"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "author": "Kirill Konshin <kirill@konshin.org> (https://konshin.org)",
28
+ "license": "MIT",
29
+ "description": ""
30
+ }
package/src/cache.ts ADDED
@@ -0,0 +1,109 @@
1
+ export function shallowCompare(prev: any, next: any) {
2
+ for (const key of Object.keys(prev).concat(Object.keys(next))) {
3
+ if (prev[key] !== next[key]) return false;
4
+ }
5
+ return true;
6
+ }
7
+
8
+ export function equal(prev: any, next: any) {
9
+ return prev === next;
10
+ }
11
+
12
+ export class CacheInPlace<Key, Val, Dep = any> {
13
+ protected map = new Map<Key, Val>();
14
+ protected lastDependency: Dep | null = null;
15
+
16
+ constructor(protected readonly name: string) {}
17
+
18
+ private compare(prev: Dep, next: Dep, shallow = false) {
19
+ const comparator = shallow ? shallowCompare : equal;
20
+ return comparator(prev, next);
21
+ }
22
+
23
+ trackDependency(dependency: Dep, shallow = false) {
24
+ if (!this.lastDependency || !dependency || this.compare(this.lastDependency, dependency, shallow)) {
25
+ // console.log('RETAINED cache', this.name, 'last', this.lastObj, 'new', obj);
26
+ return false;
27
+ }
28
+
29
+ // console.log('INVALIDATED cache', this.name, 'last', this.lastObj, 'new', obj);
30
+
31
+ this.map.clear();
32
+ this.lastDependency = dependency;
33
+
34
+ return true;
35
+ }
36
+
37
+ remove(key: Key) {
38
+ if (this.map.has(key)) this.dispose(this.map.get(key) as Val, key);
39
+ this.map.delete(key);
40
+ }
41
+
42
+ dispose(value: Val, key: Key) {}
43
+
44
+ clear() {
45
+ console.log('CLEAR cache', this.name);
46
+ this.map.forEach(this.dispose);
47
+ this.map.clear();
48
+ this.lastDependency = null;
49
+ }
50
+
51
+ async memo({
52
+ key,
53
+ memo,
54
+ hit,
55
+ invalidate,
56
+ }: {
57
+ key: Key;
58
+ memo: (oldValue: Val | undefined, key: Key) => Promise<Val> | Val;
59
+ hit?: (oldValue: Val, key: Key) => Promise<Val> | Val;
60
+ invalidate?: (oldValue: Val, key: Key) => boolean;
61
+ }): Promise<Val> {
62
+ const oldValue = this.map.get(key);
63
+
64
+ if (!!oldValue && invalidate && !invalidate(oldValue, key)) {
65
+ return hit ? await hit(oldValue, key) : oldValue;
66
+ }
67
+
68
+ if (this.map.has(key)) this.remove(key);
69
+
70
+ const value = await memo(oldValue, key);
71
+
72
+ this.map.set(key, value);
73
+
74
+ // console.log('INVALIDATED KEY cache', this.name, key, 'has', has, 'invalidate', invalidate, 'new value', value);
75
+
76
+ return value;
77
+ }
78
+
79
+ get size() {
80
+ return this.map.size;
81
+ }
82
+ }
83
+
84
+ export abstract class TypedCache<Key, Val = Key, Dep = any> extends CacheInPlace<Key, Val, Dep> {
85
+ protected invalidate(newValue: Val, oldValue: Val, key: Key): boolean {
86
+ return newValue && newValue !== oldValue; // shallow compare ever?
87
+ }
88
+
89
+ protected memoizer(key: Key, newValue: Val, oldValue: Val | undefined): Promise<Val> | Val {
90
+ return newValue;
91
+ }
92
+
93
+ protected hit(oldValue: Val, key: Key): Promise<Val> | Val {
94
+ return oldValue;
95
+ }
96
+
97
+ async memo(init: any): Promise<Val> {
98
+ throw new Error('Use memoIfNotFound() method');
99
+ }
100
+
101
+ async memoValue(key: Key, newValue: Val): Promise<Val> {
102
+ return super.memo({
103
+ key,
104
+ memo: (oldValue) => this.memoizer(key, newValue, oldValue),
105
+ hit: this.hit,
106
+ invalidate: (oldValue, key) => this.invalidate(newValue, oldValue, key),
107
+ });
108
+ }
109
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * as cache from './cache';
2
+ export * as measure from './measure';
3
+ export * as mutex from './mutex';
4
+ export * as worker from './worker';
package/src/measure.ts ADDED
@@ -0,0 +1,61 @@
1
+ import { bold, magenta, cyan, yellow, red, green } from 'colors/safe';
2
+
3
+ export const colored = {
4
+ important: bold,
5
+ subject: magenta,
6
+ arg: cyan,
7
+ sup: yellow,
8
+ err: red,
9
+ ok: green,
10
+ };
11
+
12
+ const noColor = (str) => str;
13
+
14
+ export const uncolored = {
15
+ important: noColor,
16
+ subject: noColor,
17
+ arg: noColor,
18
+ sup: noColor,
19
+ err: noColor,
20
+ ok: noColor,
21
+ };
22
+
23
+ export function createMeasurer({ colors = true, prepend = 'LOG', padding = 10 }) {
24
+ const { important, subject, arg, sup, ok, err } = colors ? colored : uncolored;
25
+
26
+ function measure(what: string, step: string, supplemental: string = '', ...args) {
27
+ const time = performance.now();
28
+
29
+ const prefix = [
30
+ prepend,
31
+ important(subject(what.substring(0, padding).padStart(padding, ' '))),
32
+ arg(step),
33
+ sup(supplemental),
34
+ ...args,
35
+ ];
36
+
37
+ const done = (result: string = ok('DONE'), ...args2) => {
38
+ console.log(
39
+ ...[
40
+ ...prefix,
41
+ important(result),
42
+ ...args2,
43
+ 'in',
44
+ important((performance.now() - time).toFixed(0)),
45
+ 'ms',
46
+ ].filter(Boolean),
47
+ );
48
+ console.groupEnd();
49
+ };
50
+
51
+ const fail = (result: string = err('FAIL'), ...args2) => done(result, ...args2);
52
+
53
+ const log = (...args2) => {
54
+ console.log(...prefix, ...args2);
55
+ };
56
+
57
+ return { done, fail, log };
58
+ }
59
+
60
+ return { measure, important, subject, arg, sup, ok, err };
61
+ }
package/src/mutex.ts ADDED
@@ -0,0 +1,21 @@
1
+ //TODO Implement queue with ranking & sorting
2
+ export class Mutex {
3
+ private promise = Promise.resolve();
4
+
5
+ public exec(fn: (...args: any) => any): ReturnType<typeof fn> {
6
+ return new Promise((resolve, reject) => {
7
+ // wrap in always successful function
8
+ this.promise = this.promise.then(async () => {
9
+ try {
10
+ resolve(await fn());
11
+ } catch (e) {
12
+ reject(e);
13
+ }
14
+ });
15
+ });
16
+ }
17
+
18
+ public wrap(fn: (...args: any) => any): ReturnType<typeof fn> {
19
+ return (...args: any) => this.exec(() => fn(...args));
20
+ }
21
+ }
package/src/worker.ts ADDED
@@ -0,0 +1,327 @@
1
+ export function isTransferable(obj: any): boolean {
2
+ return transferrable.some((t) => obj instanceof t) ? obj : null;
3
+ }
4
+
5
+ function getTransferrable(data: any = {}): Transferable[] {
6
+ if (!data) return [];
7
+ return Object.values<any>(data)
8
+ .reduce((r, v) => {
9
+ return Array.isArray(v) ? [...r, ...v.map(isTransferable)] : [...r, isTransferable(v)];
10
+ }, [])
11
+ .filter(Boolean);
12
+ }
13
+
14
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects
15
+ const transferrable =
16
+ typeof window !== 'undefined'
17
+ ? [
18
+ ArrayBuffer,
19
+ MessagePort,
20
+ ReadableStream,
21
+ WritableStream,
22
+ TransformStream,
23
+ // WebTransportReceiveStream, // ReferenceError: WebTransportReceiveStream is not defined
24
+ // WebTransportSendStream, // ReferenceError: WebTransportReceiveStream is not defined
25
+ // AudioData, // TS2304: Cannot find name AudioData
26
+ ImageBitmap,
27
+ VideoFrame,
28
+ OffscreenCanvas,
29
+ RTCDataChannel,
30
+ MediaSourceHandle,
31
+ // MIDIAccess, // ReferenceError: MIDIAccess is not defined
32
+ ].filter(Boolean)
33
+ : [];
34
+
35
+ type WebWorker = Worker | (Window & typeof globalThis) | (WorkerGlobalScope & typeof globalThis);
36
+
37
+ type MethodReturn<R, M extends keyof R> = R[M] extends (...args: any[]) => any
38
+ ? Partial<Awaited<ReturnType<R[M]>>>
39
+ : never;
40
+
41
+ type MethodArg<R, M extends keyof R> = R[M] extends (arg: infer A, ...args: any[]) => any ? Partial<A> : never;
42
+
43
+ export type Ctx<R, K extends keyof R> = {
44
+ id: string;
45
+ parentId?: string;
46
+ message: K;
47
+ };
48
+
49
+ type Data<R, M extends keyof R> = MethodReturn<R, M> | MethodArg<R, M> | Error;
50
+
51
+ type Event<R, M extends keyof R> = MessageEvent<{ data: Data<R, M>; ctx: Ctx<R, M> }>;
52
+
53
+ type Listener<R, M extends keyof R, D extends Data<R, M> = Data<R, M>, S extends Context<R, M> = Context<R, M>> = (
54
+ data: D,
55
+ self: S,
56
+ event: Event<R, M>,
57
+ ) => void | Promise<void>;
58
+
59
+ const ALL = '*';
60
+
61
+ let id = 0;
62
+
63
+ function getID() {
64
+ return (++id).toString();
65
+ }
66
+
67
+ function checkClosed(obj: any, label: string = 'external') {
68
+ if (obj?.closed) throw new Error(`Context is closed ${this.info} (${label})`, { cause: obj });
69
+ }
70
+
71
+ function checkMessage(obj: any, message: any) {
72
+ if (!message) throw new Error('New context must have message', { cause: obj });
73
+ }
74
+
75
+ export class WorkerDialog<R extends RespondersBase<any>> {
76
+ readonly contexts = new Set<Context<R, keyof R>>();
77
+ protected closed = false;
78
+
79
+ constructor(
80
+ public worker: WebWorker,
81
+ public responders: R,
82
+ public name: string,
83
+ ) {
84
+ if (!this.worker) return; // Next.js SSR
85
+
86
+ for (const message in this.responders) {
87
+ if (['constructor', 'create'].includes(message)) continue;
88
+
89
+ // root context with id=all
90
+ const rootContext = new ResponseContext<R, typeof message>(this, message, ALL);
91
+
92
+ //TODO: unsub(); ? Probably not needed, root must be always listening until closed by WorkerDialog
93
+ rootContext.listen(async (data, context, event) => {
94
+ // create sub context with ID
95
+ const responseContext = context.withMessage(message, event.data.ctx.id);
96
+
97
+ console.log('Root Listener', rootContext.info, {
98
+ rootContext: context,
99
+ data,
100
+ responseContext,
101
+ event,
102
+ responder: this.responders[message],
103
+ });
104
+
105
+ try {
106
+ responseContext.send(await (this.responders[message] as any)(data, responseContext));
107
+ responseContext.close('root.listener');
108
+ } catch (e) {
109
+ console.error(`Error in responder ${responseContext.info}`, { e });
110
+ responseContext.send(e);
111
+ }
112
+ });
113
+ }
114
+ }
115
+
116
+ close() {
117
+ for (const context of this.contexts) context.close('root');
118
+ this.contexts.clear();
119
+ this.worker.onmessage = null;
120
+ }
121
+
122
+ withMessage<M extends keyof R>(message: M) {
123
+ return new RequestContext<R, M>(this, message, getID());
124
+ }
125
+ }
126
+
127
+ export class RespondersBase<R> {
128
+ create<M extends keyof R, F extends (input: any, context: ResponseContext<R, M>) => any>(
129
+ message: M,
130
+ responder: F,
131
+ ): F {
132
+ return responder as any;
133
+ }
134
+ }
135
+
136
+ // can only be used to create actual contexts, carries the context data
137
+ abstract class Context<R, M extends keyof R> {
138
+ protected readonly unsub = new Set<() => void>();
139
+ protected closed = false;
140
+
141
+ constructor(
142
+ protected readonly dialog: WorkerDialog<any>,
143
+ public message: M,
144
+ public id: string | undefined,
145
+ public parent: Context<R, keyof R> | undefined | null = null,
146
+ ) {
147
+ checkClosed(this.dialog, 'newContext');
148
+ checkClosed(this.parent, 'newContext');
149
+ checkMessage(this, message);
150
+ this.id = parent?.id === ALL ? getID() : id ? id : this.parent?.id;
151
+ if (!this.id) throw new Error('ID is required', { cause: this });
152
+ }
153
+
154
+ abstract withMessage<M2 extends keyof R>(message: M2, id?: string): Context<R, M2>;
155
+
156
+ close(reason: string = 'external') {
157
+ // console.log('Closing', this.id, reason, this);
158
+
159
+ this.dialog.contexts.delete(this);
160
+
161
+ // Unsubscribe from all listeners
162
+ for (const unsub of this.unsub) unsub();
163
+ this.unsub.clear();
164
+
165
+ // Remove all child contexts
166
+ this.dialog.contexts.forEach((context) => {
167
+ if (context.parent?.id === this.id) context.close('parent');
168
+ });
169
+
170
+ this.closed = true;
171
+ }
172
+
173
+ get info() {
174
+ return this.dialog.name + '.' + this.parent?.id + '.' + this.id + '.' + this.message.toString();
175
+ }
176
+
177
+ protected postMessage(data?: Data<R, M>) {
178
+ checkClosed(this, 'postMessage');
179
+
180
+ const transfer = getTransferrable(data);
181
+
182
+ // console.log('postMessage', this.id, this, { mergedCtx, data, transfer });
183
+
184
+ this.dialog.worker.postMessage(
185
+ {
186
+ data,
187
+ ctx: {
188
+ id: this.id,
189
+ parentId: this.parent?.id,
190
+ message: this.message,
191
+ },
192
+ },
193
+ transfer,
194
+ );
195
+
196
+ return data;
197
+ }
198
+
199
+ send(data?: Data<R, M>) {
200
+ return this.postMessage(data);
201
+ }
202
+
203
+ /**
204
+ * Does not automatically close, assumes consumer will close
205
+ *
206
+ * ```ts
207
+ * dialog.request('x').fetch((c) => {
208
+ * c.response('x').listen(() => { ... }); // listens to "x", will be closed by upper level fetch
209
+ * c.request('x').fetcH(y, (c) => { ... }); // closes
210
+ * }) // closes
211
+ *
212
+ * const un = dialog.context('x').listen((e) => { ... }); // listens to 'x'
213
+ * un(); // closes
214
+ *
215
+ * const un = dialog.context('x').listen((e) => { ... }); // listens to 'x'
216
+ * un(); // closes
217
+ * ```
218
+ */
219
+ listen(callback: Listener<R, M>): () => void {
220
+ checkClosed(this, 'listen');
221
+
222
+ let workerListener: any;
223
+
224
+ this.dialog.worker.addEventListener(
225
+ 'message',
226
+ (workerListener = async (event: Event<R, M>) => {
227
+ try {
228
+ const {
229
+ data: { ctx, data },
230
+ } = event;
231
+
232
+ if (!ctx || (this.id !== ALL && this.id !== ctx.id) || this.message !== ctx.message) return; // unknown message from devtools etc., or different context
233
+
234
+ console.log('Shared listener event', this.info, this, event);
235
+
236
+ await callback(data, this, event); // Requests can come here, but they're typed in responders
237
+ } catch (e) {
238
+ console.error(`Error in listener ${this.info}`, this, { event, e });
239
+ }
240
+ }),
241
+ );
242
+
243
+ const unsub = () => {
244
+ // console.log('Stop listening', this.id, this);
245
+ this.dialog.worker.removeEventListener('message', workerListener);
246
+ this.unsub.delete(unsub);
247
+ };
248
+
249
+ this.unsub.add(unsub);
250
+
251
+ return unsub;
252
+ }
253
+ }
254
+
255
+ class RequestContext<R, M extends keyof R> extends Context<R, M> {
256
+ withMessage<M2 extends keyof R>(message: M2, id?: string): RequestContext<R, M2> {
257
+ return new RequestContext<R, M2>(this.dialog, message, id, this);
258
+ }
259
+
260
+ send(data?: MethodArg<R, M>): MethodArg<R, M> {
261
+ return super.send(data) as any;
262
+ }
263
+
264
+ listen(callback: Listener<R, M, MethodReturn<R, M>, RequestContext<R, M>>): () => void {
265
+ return super.listen(callback);
266
+ }
267
+
268
+ /**
269
+ * Returns response
270
+ * If you need to work with ctx, use callback
271
+ * Closed automatically on response
272
+ *
273
+ * dialog.fetch('x', (c) => {
274
+ * c.listen(() => { ... }); // will be closed by upper level fetch
275
+ * c.fetcH(y, (c) => { ... }); // closes c
276
+ * c.context().fetcH(y, (c) => { ... }); // closes sub, not closes c, will be closed by upper level fetch
277
+ * })
278
+ */
279
+ async fetch(
280
+ data?: MethodArg<R, M>,
281
+ callback?: (context: RequestContext<R, M>) => void,
282
+ ): Promise<MethodReturn<R, M>> {
283
+ const res = await Promise.all([
284
+ callback?.(this),
285
+ this.expect(), // will be closed in expect -> listener -> unsub
286
+ this.send(data),
287
+ ]);
288
+
289
+ // console.log('Fetch', this.id, this.contexts, this.ownContexts);
290
+
291
+ this.close('fetch');
292
+
293
+ return res[1];
294
+ }
295
+
296
+ protected async expect() {
297
+ checkClosed(this, 'expect');
298
+
299
+ //FIXME Manual promise type
300
+ return new Promise<MethodReturn<R, M>>((resolve, reject) => {
301
+ const responseListener = this.listen(async (data) => {
302
+ try {
303
+ if ((data as any) instanceof Error) throw data;
304
+ responseListener();
305
+ // console.log('Expect', this.id, this, eventData);
306
+ resolve(data as any);
307
+ } catch (e) {
308
+ reject(e);
309
+ }
310
+ });
311
+ });
312
+ }
313
+ }
314
+
315
+ class ResponseContext<R, M extends keyof R> extends Context<R, M> {
316
+ withMessage<M2 extends keyof R>(message: M2, id?: string): ResponseContext<R, M2> {
317
+ return new ResponseContext<R, M2>(this.dialog, message, id, this);
318
+ }
319
+
320
+ listen(callback: Listener<R, M, MethodArg<R, M>, ResponseContext<R, M>>): () => void {
321
+ return super.listen(callback);
322
+ }
323
+
324
+ send(data?: MethodReturn<R, M>): MethodReturn<R, M> {
325
+ return super.send(data) as any;
326
+ }
327
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "allowSyntheticDefaultImports": true,
5
+ "esModuleInterop": true,
6
+ "forceConsistentCasingInFileNames": true,
7
+ "isolatedModules": true,
8
+ "jsx": "preserve",
9
+ "target": "es2018",
10
+ "lib": ["dom", "dom.iterable", "esnext", "webworker"],
11
+ "module": "esnext",
12
+ "moduleResolution": "node",
13
+ "resolveJsonModule": true,
14
+ "skipLibCheck": true,
15
+ "strict": false,
16
+ "strictNullChecks": true,
17
+ "incremental": true,
18
+ "outDir": "./build",
19
+ "declaration": true,
20
+ "declarationDir": "./build",
21
+ "rootDir": "src"
22
+ },
23
+ "include": ["src"]
24
+ }
@@ -0,0 +1 @@
1
+ {"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/typescript/lib/lib.es2024.d.ts","../../node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.webworker.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2024.collection.d.ts","../../node_modules/typescript/lib/lib.es2024.object.d.ts","../../node_modules/typescript/lib/lib.es2024.promise.d.ts","../../node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2024.string.d.ts","../../node_modules/typescript/lib/lib.esnext.array.d.ts","../../node_modules/typescript/lib/lib.esnext.collection.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","./src/cache.ts","../../node_modules/colors/safe.d.ts","./src/measure.ts","./src/mutex.ts","./src/worker.ts","./src/index.ts","../../node_modules/@types/estree/index.d.ts","../../node_modules/@types/json-schema/index.d.ts","../../node_modules/@types/json5/index.d.ts","../../node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/compatibility/index.d.ts","../../node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/undici-types/header.d.ts","../../node_modules/undici-types/readable.d.ts","../../node_modules/undici-types/file.d.ts","../../node_modules/undici-types/fetch.d.ts","../../node_modules/undici-types/formdata.d.ts","../../node_modules/undici-types/connector.d.ts","../../node_modules/undici-types/client.d.ts","../../node_modules/undici-types/errors.d.ts","../../node_modules/undici-types/dispatcher.d.ts","../../node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/undici-types/global-origin.d.ts","../../node_modules/undici-types/pool-stats.d.ts","../../node_modules/undici-types/pool.d.ts","../../node_modules/undici-types/handlers.d.ts","../../node_modules/undici-types/balanced-pool.d.ts","../../node_modules/undici-types/agent.d.ts","../../node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/undici-types/mock-agent.d.ts","../../node_modules/undici-types/mock-client.d.ts","../../node_modules/undici-types/mock-pool.d.ts","../../node_modules/undici-types/mock-errors.d.ts","../../node_modules/undici-types/proxy-agent.d.ts","../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/undici-types/retry-handler.d.ts","../../node_modules/undici-types/retry-agent.d.ts","../../node_modules/undici-types/api.d.ts","../../node_modules/undici-types/interceptors.d.ts","../../node_modules/undici-types/util.d.ts","../../node_modules/undici-types/cookies.d.ts","../../node_modules/undici-types/patch.d.ts","../../node_modules/undici-types/websocket.d.ts","../../node_modules/undici-types/eventsource.d.ts","../../node_modules/undici-types/filereader.d.ts","../../node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/undici-types/content-type.d.ts","../../node_modules/undici-types/cache.d.ts","../../node_modules/undici-types/index.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/dom-events.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/@types/pngjs/index.d.ts","../../node_modules/@types/rsvp/index.d.ts","../../node_modules/@types/psd/psd.d.ts","../../node_modules/@types/psd/index.d.ts","../../node_modules/@types/react/global.d.ts","../../node_modules/csstype/index.d.ts","../../node_modules/@types/react/index.d.ts"],"fileIdsList":[[94,136],[94,133,136],[94,135,136],[136],[94,136,141,171],[94,136,137,142,148,149,156,168,179],[94,136,137,138,148,156],[89,90,91,94,136],[94,136,139,180],[94,136,140,141,149,157],[94,136,141,168,176],[94,136,142,144,148,156],[94,135,136,143],[94,136,144,145],[94,136,148],[94,136,146,148],[94,135,136,148],[94,136,148,149,150,168,179],[94,136,148,149,150,163,168,171],[94,131,136,184],[94,131,136,144,148,151,156,168,179],[94,136,148,149,151,152,156,168,176,179],[94,136,151,153,168,176,179],[92,93,94,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185],[94,136,148,154],[94,136,155,179,184],[94,136,144,148,156,168],[94,136,157],[94,136,158],[94,135,136,159],[94,133,134,135,136,137,138,139,140,141,142,143,144,145,146,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185],[94,136,161],[94,136,162],[94,136,148,163,164],[94,136,163,165,180,182],[94,136,148,168,169,170,171],[94,136,168,170],[94,136,168,169],[94,136,171],[94,136,172],[94,133,136,168],[94,136,148,174,175],[94,136,174,175],[94,136,141,156,168,176],[94,136,177],[94,136,156,178],[94,136,151,162,179],[94,136,141,180],[94,136,168,181],[94,136,155,182],[94,136,183],[94,136,141,148,150,159,168,179,182,184],[94,136,168,185],[94,136,168,185,186],[94,136,186,187,188,189,190],[94,136,191,192],[94,103,107,136,179],[94,103,136,168,179],[94,98,136],[94,100,103,136,176,179],[94,136,156,176],[94,136,186],[94,98,136,186],[94,100,103,136,156,179],[94,95,96,99,102,136,148,168,179],[94,103,110,136],[94,95,101,136],[94,103,124,125,136],[94,99,103,136,171,179,186],[94,124,136,186],[94,97,98,136,186],[94,103,136],[94,97,98,99,100,101,102,103,104,105,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,125,126,127,128,129,130,136],[94,103,118,136],[94,103,110,111,136],[94,101,103,111,112,136],[94,102,136],[94,95,98,103,136],[94,103,107,111,112,136],[94,107,136],[94,101,103,106,136,179],[94,95,100,103,110,136],[94,136,168],[94,98,103,124,136,184,186],[80,82,83,84,94,136],[81,94,136]],"fileInfos":[{"version":"e41c290ef7dd7dab3493e6cbe5909e0148edf4a8dad0271be08edec368a0f7b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"e12a46ce14b817d4c9e6b2b478956452330bf00c9801b79de46f7a1815b5bd40","impliedFormat":1},{"version":"4fd3f3422b2d2a3dfd5cdd0f387b3a8ec45f006c6ea896a4cb41264c2100bb2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"69e65d976bf166ce4a9e6f6c18f94d2424bf116e90837ace179610dbccad9b42","affectsGlobalScope":true,"impliedFormat":1},{"version":"35b3160b7e8925d6f4754642efbfe5db73ad2a4b3bec7f570f57fc38705d5f0f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"62bb211266ee48b2d0edf0d8d1b191f0c24fc379a82bd4c1692a082c540bc6b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"f1e2a172204962276504466a6393426d2ca9c54894b1ad0a6c9dad867a65f876","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"bab26767638ab3557de12c900f0b91f710c7dc40ee9793d5a27d32c04f0bf646","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"61d6a2092f48af66dbfb220e31eea8b10bc02b6932d6e529005fd2d7b3281290","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"f7f24c76f35d1e51500e8bf032c8811d3f9cff5246cef1f7f8cf10a3b4860416","signature":"3acec413ebe4d9e2ce3b66f6bc21b8b488359a0e6bb619e6324b9011c5db0eb6"},{"version":"31c0a538946283248909d07a00e23d571f4a3d86778650119de24ef585a56d45","impliedFormat":1},{"version":"6addbfe1f6458d486270e9b3003a4a90ea3bb67e11a0b0e10f0b08ab5b98fcc7","signature":"3782d3e33f6f6b1d13a3364a6b13299f07c9eeaa86cdf880728ade5487ee9e22"},{"version":"7ebd4c6a28470afe57f887713e736df55269a78f1c930eb04e887ab0465b9198","signature":"38a0259de5e9fb2d3e6707d2797d9dbd3ca005a1e4d69a43ebc1f6bfa05acd23"},{"version":"504383950787bfb0118ab99a773511892b5ee99143ac406d0fe29f17ca38c3c1","signature":"9ab3a05f873fe08b6e4a93b3d64efc6e57ca9d7d8ade658c4e162d8c23cdf703"},"65562fbe278655080ab7eb266a0b213b59eb278ce9c0d66e09d3cf00b16b0813",{"version":"785b9d575b49124ce01b46f5b9402157c7611e6532effa562ac6aebec0074dfc","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1},{"version":"70521b6ab0dcba37539e5303104f29b721bfb2940b2776da4cc818c07e1fefc1","affectsGlobalScope":true,"impliedFormat":1},{"version":"030e350db2525514580ed054f712ffb22d273e6bc7eddc1bb7eda1e0ba5d395e","affectsGlobalScope":true,"impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fd06258805d26c72f5997e07a23155d322d5f05387adb3744a791fe6a0b042d","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"24bd580b5743dc56402c440dc7f9a4f5d592ad7a419f25414d37a7bfe11e342b","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"6bdc71028db658243775263e93a7db2fd2abfce3ca569c3cca5aee6ed5eb186d","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"81184fe8e67d78ac4e5374650f0892d547d665d77da2b2f544b5d84729c4a15d","affectsGlobalScope":true,"impliedFormat":1},{"version":"f52e8dacc97d71dcc96af29e49584353f9c54cb916d132e3e768d8b8129c928d","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"76103716ba397bbb61f9fa9c9090dca59f39f9047cb1352b2179c5d8e7f4e8d0","impliedFormat":1},{"version":"53eac70430b30089a3a1959d8306b0f9cfaf0de75224b68ef25243e0b5ad1ca3","affectsGlobalScope":true,"impliedFormat":1},{"version":"4314c7a11517e221f7296b46547dbc4df047115b182f544d072bdccffa57fc72","impliedFormat":1},{"version":"115971d64632ea4742b5b115fb64ed04bcaae2c3c342f13d9ba7e3f9ee39c4e7","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"a40826e8476694e90da94aa008283a7de50d1dafd37beada623863f1901cb7fb","impliedFormat":1},{"version":"86956cc2eb9dd371d6fab493d326a574afedebf76eef3fa7833b8e0d9b52d6f1","affectsGlobalScope":true,"impliedFormat":1},{"version":"24642567d3729bcc545bacb65ee7c0db423400c7f1ef757cab25d05650064f98","impliedFormat":1},{"version":"e6f5a38687bebe43a4cef426b69d34373ef68be9a6b1538ec0a371e69f309354","impliedFormat":1},{"version":"a6bf63d17324010ca1fbf0389cab83f93389bb0b9a01dc8a346d092f65b3605f","impliedFormat":1},{"version":"e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"88bc59b32d0d5b4e5d9632ac38edea23454057e643684c3c0b94511296f2998c","affectsGlobalScope":true,"impliedFormat":1},{"version":"e9ad08a376ac84948fcca0013d6f1d4ae4f9522e26b91f87945b97c99d7cc30b","impliedFormat":1},{"version":"eaf9ee1d90a35d56264f0bf39842282c58b9219e112ac7d0c1bce98c6c5da672","impliedFormat":1},{"version":"c15c4427ae7fd1dcd7f312a8a447ac93581b0d4664ddf151ecd07de4bf2bb9d7","impliedFormat":1},{"version":"5135bdd72cc05a8192bd2e92f0914d7fc43ee077d1293dc622a049b7035a0afb","impliedFormat":1},{"version":"4f80de3a11c0d2f1329a72e92c7416b2f7eab14f67e92cac63bb4e8d01c6edc8","impliedFormat":1},{"version":"6d386bc0d7f3afa1d401afc3e00ed6b09205a354a9795196caed937494a713e6","impliedFormat":1},{"version":"75c3400359d59fae5aed4c4a59fcd8a9760cf451e25dc2174cb5e08b9d4803e2","affectsGlobalScope":true,"impliedFormat":1},{"version":"94c4187083503a74f4544503b5a30e2bd7af0032dc739b0c9a7ce87f8bddc7b9","impliedFormat":1},{"version":"b1b6ee0d012aeebe11d776a155d8979730440082797695fc8e2a5c326285678f","impliedFormat":1},{"version":"45875bcae57270aeb3ebc73a5e3fb4c7b9d91d6b045f107c1d8513c28ece71c0","impliedFormat":1},{"version":"3eb62baae4df08c9173e6903d3ca45942ccec8c3659b0565684a75f3292cffbb","affectsGlobalScope":true,"impliedFormat":1},{"version":"a85683ef86875f4ad4c6b7301bbcc63fb379a8d80d3d3fd735ee57f48ef8a47e","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"c6b4e0a02545304935ecbf7de7a8e056a31bb50939b5b321c9d50a405b5a0bba","impliedFormat":1},{"version":"fab29e6d649aa074a6b91e3bdf2bff484934a46067f6ee97a30fcd9762ae2213","impliedFormat":1},{"version":"8145e07aad6da5f23f2fcd8c8e4c5c13fb26ee986a79d03b0829b8fce152d8b2","impliedFormat":1},{"version":"e1120271ebbc9952fdc7b2dd3e145560e52e06956345e6fdf91d70ca4886464f","impliedFormat":1},{"version":"15c5e91b5f08be34a78e3d976179bf5b7a9cc28dc0ef1ffebffeb3c7812a2dca","impliedFormat":1},{"version":"a8f06c2382a30b7cb89ad2dfc48fc3b2b490f3dafcd839dadc008e4e5d57031d","impliedFormat":1},{"version":"553870e516f8c772b89f3820576152ebc70181d7994d96917bb943e37da7f8a7","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"93452d394fdd1dc551ec62f5042366f011a00d342d36d50793b3529bfc9bd633","impliedFormat":1},{"version":"745c4240220559bd340c8aeb6e3c5270a709d3565e934dc22a69c304703956bc","affectsGlobalScope":true,"impliedFormat":1},{"version":"2754d8221d77c7b382096651925eb476f1066b3348da4b73fe71ced7801edada","impliedFormat":1},{"version":"9212c6e9d80cb45441a3614e95afd7235a55a18584c2ed32d6c1aca5a0c53d93","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef91efa0baea5d0e0f0f27b574a8bc100ce62a6d7e70220a0d58af6acab5e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"282fd2a1268a25345b830497b4b7bf5037a5e04f6a9c44c840cb605e19fea841","impliedFormat":1},{"version":"5360a27d3ebca11b224d7d3e38e3e2c63f8290cb1fcf6c3610401898f8e68bc3","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"7d6ff413e198d25639f9f01f16673e7df4e4bd2875a42455afd4ecc02ef156da","affectsGlobalScope":true,"impliedFormat":1},{"version":"6bd91a2a356600dee28eb0438082d0799a18a974a6537c4410a796bab749813c","affectsGlobalScope":true,"impliedFormat":1},{"version":"f689c4237b70ae6be5f0e4180e8833f34ace40529d1acc0676ab8fb8f70457d7","impliedFormat":1},{"version":"ae25afbbf1ed5df63a177d67b9048bf7481067f1b8dc9c39212e59db94fc9fc6","impliedFormat":1},{"version":"ac5ed35e649cdd8143131964336ab9076937fa91802ec760b3ea63b59175c10a","impliedFormat":1},{"version":"52a8e7e8a1454b6d1b5ad428efae3870ffc56f2c02d923467f2940c454aa9aec","affectsGlobalScope":true,"impliedFormat":1},{"version":"78dc0513cc4f1642906b74dda42146bcbd9df7401717d6e89ea6d72d12ecb539","impliedFormat":1},{"version":"ad90122e1cb599b3bc06a11710eb5489101be678f2920f2322b0ac3e195af78d","impliedFormat":1},{"version":"90ac19cb97ae85c7ccfd0c04322b02ce088bda9de7b42cc081cbb3674fe5446d","impliedFormat":1},{"version":"11eab43f6a9918a6458a8c16899e040205034bed9769e85267b08924da1fdd24","impliedFormat":1},{"version":"c72c980f13596679a06abe3aecaaa7d2bb639f3208537de2a5a6836e0100499b","impliedFormat":1},{"version":"e20e6e7ba421fe1ef044be272fa38e6f0f37c8dd309a6915de704594e6ba24a3","impliedFormat":1},{"version":"36a2e4c9a67439aca5f91bb304611d5ae6e20d420503e96c230cf8fcdc948d94","affectsGlobalScope":true,"impliedFormat":1},{"version":"8a8eb4ebffd85e589a1cc7c178e291626c359543403d58c9cd22b81fab5b1fb9","impliedFormat":1},{"version":"1d0efd1dd185c3dd81eac37f6a393b34bfbf569e55117f5d6c5006c91cb4b68f","impliedFormat":1}],"root":[80,[82,85]],"options":{"allowJs":true,"allowSyntheticDefaultImports":true,"declaration":true,"declarationDir":"./build","esModuleInterop":true,"jsx":1,"module":99,"outDir":"./build","rootDir":"./src","skipLibCheck":true,"strict":false,"strictNullChecks":true,"target":5},"referencedMap":[[86,1],[87,1],[88,1],[133,2],[134,2],[135,3],[94,4],[136,5],[137,6],[138,7],[89,1],[92,8],[90,1],[91,1],[139,9],[140,10],[141,11],[142,12],[143,13],[144,14],[145,14],[147,15],[146,16],[148,17],[149,18],[150,19],[132,20],[93,1],[151,21],[152,22],[153,23],[186,24],[154,25],[155,26],[156,27],[157,28],[158,29],[159,30],[160,31],[161,32],[162,33],[163,34],[164,34],[165,35],[166,1],[167,1],[168,36],[170,37],[169,38],[171,39],[172,40],[173,41],[174,42],[175,43],[176,44],[177,45],[178,46],[179,47],[180,48],[181,49],[182,50],[183,51],[184,52],[185,53],[187,54],[190,55],[189,1],[191,1],[193,56],[188,1],[81,1],[192,1],[78,1],[79,1],[13,1],[14,1],[17,1],[16,1],[2,1],[18,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[25,1],[3,1],[26,1],[27,1],[4,1],[28,1],[32,1],[29,1],[30,1],[31,1],[33,1],[34,1],[35,1],[5,1],[36,1],[37,1],[38,1],[39,1],[6,1],[43,1],[40,1],[41,1],[42,1],[44,1],[7,1],[45,1],[50,1],[51,1],[46,1],[47,1],[48,1],[49,1],[8,1],[55,1],[52,1],[53,1],[54,1],[56,1],[9,1],[57,1],[58,1],[59,1],[61,1],[60,1],[62,1],[63,1],[10,1],[64,1],[65,1],[66,1],[11,1],[67,1],[68,1],[69,1],[70,1],[71,1],[1,1],[72,1],[73,1],[12,1],[76,1],[75,1],[74,1],[77,1],[15,1],[110,57],[120,58],[109,57],[130,59],[101,60],[100,61],[129,62],[123,63],[128,64],[103,65],[117,66],[102,67],[126,68],[98,69],[97,62],[127,70],[99,71],[104,72],[105,1],[108,72],[95,1],[131,73],[121,74],[112,75],[113,76],[115,77],[111,78],[114,79],[124,62],[106,80],[107,81],[116,82],[96,83],[119,74],[118,72],[122,1],[125,84],[80,1],[85,85],[82,86],[83,1],[84,1]],"version":"5.7.2"}
package/turbo.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "extends": ["//"],
4
+ "tasks": {
5
+ "clean": {
6
+ "cache": false
7
+ },
8
+ "build": {
9
+ "outputs": ["build/**/*"]
10
+ },
11
+ "start": {
12
+ "persistent": true,
13
+ "cache": false
14
+ },
15
+ "wait": {
16
+ "cache": false
17
+ }
18
+ }
19
+ }