@tldraw/utils 4.0.3 → 4.1.0-canary.0259516ffb8c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +1350 -80
- package/dist-cjs/index.js +5 -5
- package/dist-cjs/lib/ExecutionQueue.js +79 -0
- package/dist-cjs/lib/ExecutionQueue.js.map +2 -2
- package/dist-cjs/lib/PerformanceTracker.js +43 -0
- package/dist-cjs/lib/PerformanceTracker.js.map +2 -2
- package/dist-cjs/lib/array.js +3 -1
- package/dist-cjs/lib/array.js.map +2 -2
- package/dist-cjs/lib/bind.js.map +2 -2
- package/dist-cjs/lib/cache.js +27 -5
- package/dist-cjs/lib/cache.js.map +2 -2
- package/dist-cjs/lib/control.js +12 -0
- package/dist-cjs/lib/control.js.map +2 -2
- package/dist-cjs/lib/debounce.js.map +2 -2
- package/dist-cjs/lib/error.js.map +2 -2
- package/dist-cjs/lib/file.js +76 -11
- package/dist-cjs/lib/file.js.map +2 -2
- package/dist-cjs/lib/function.js.map +2 -2
- package/dist-cjs/lib/hash.js.map +2 -2
- package/dist-cjs/lib/id.js.map +2 -2
- package/dist-cjs/lib/iterable.js.map +2 -2
- package/dist-cjs/lib/json-value.js.map +1 -1
- package/dist-cjs/lib/media/apng.js.map +2 -2
- package/dist-cjs/lib/media/avif.js.map +2 -2
- package/dist-cjs/lib/media/gif.js.map +2 -2
- package/dist-cjs/lib/media/media.js +130 -4
- package/dist-cjs/lib/media/media.js.map +2 -2
- package/dist-cjs/lib/media/png.js +141 -0
- package/dist-cjs/lib/media/png.js.map +2 -2
- package/dist-cjs/lib/media/webp.js +1 -0
- package/dist-cjs/lib/media/webp.js.map +2 -2
- package/dist-cjs/lib/network.js.map +2 -2
- package/dist-cjs/lib/number.js.map +2 -2
- package/dist-cjs/lib/object.js +1 -1
- package/dist-cjs/lib/object.js.map +2 -2
- package/dist-cjs/lib/perf.js.map +2 -2
- package/dist-cjs/lib/reordering.js.map +2 -2
- package/dist-cjs/lib/retry.js.map +2 -2
- package/dist-cjs/lib/sort.js.map +2 -2
- package/dist-cjs/lib/storage.js.map +2 -2
- package/dist-cjs/lib/stringEnum.js.map +2 -2
- package/dist-cjs/lib/throttle.js.map +2 -2
- package/dist-cjs/lib/timers.js +103 -4
- package/dist-cjs/lib/timers.js.map +2 -2
- package/dist-cjs/lib/types.js.map +1 -1
- package/dist-cjs/lib/url.js.map +2 -2
- package/dist-cjs/lib/value.js.map +2 -2
- package/dist-cjs/lib/version.js.map +2 -2
- package/dist-cjs/lib/warn.js.map +2 -2
- package/dist-esm/index.d.mts +1350 -80
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/ExecutionQueue.mjs +79 -0
- package/dist-esm/lib/ExecutionQueue.mjs.map +2 -2
- package/dist-esm/lib/PerformanceTracker.mjs +43 -0
- package/dist-esm/lib/PerformanceTracker.mjs.map +2 -2
- package/dist-esm/lib/array.mjs +3 -1
- package/dist-esm/lib/array.mjs.map +2 -2
- package/dist-esm/lib/bind.mjs.map +2 -2
- package/dist-esm/lib/cache.mjs +27 -5
- package/dist-esm/lib/cache.mjs.map +2 -2
- package/dist-esm/lib/control.mjs +12 -0
- package/dist-esm/lib/control.mjs.map +2 -2
- package/dist-esm/lib/debounce.mjs.map +2 -2
- package/dist-esm/lib/error.mjs.map +2 -2
- package/dist-esm/lib/file.mjs +76 -11
- package/dist-esm/lib/file.mjs.map +2 -2
- package/dist-esm/lib/function.mjs.map +2 -2
- package/dist-esm/lib/hash.mjs.map +2 -2
- package/dist-esm/lib/id.mjs.map +2 -2
- package/dist-esm/lib/iterable.mjs.map +2 -2
- package/dist-esm/lib/media/apng.mjs.map +2 -2
- package/dist-esm/lib/media/avif.mjs.map +2 -2
- package/dist-esm/lib/media/gif.mjs.map +2 -2
- package/dist-esm/lib/media/media.mjs +130 -4
- package/dist-esm/lib/media/media.mjs.map +2 -2
- package/dist-esm/lib/media/png.mjs +141 -0
- package/dist-esm/lib/media/png.mjs.map +2 -2
- package/dist-esm/lib/media/webp.mjs +1 -0
- package/dist-esm/lib/media/webp.mjs.map +2 -2
- package/dist-esm/lib/network.mjs.map +2 -2
- package/dist-esm/lib/number.mjs.map +2 -2
- package/dist-esm/lib/object.mjs.map +2 -2
- package/dist-esm/lib/perf.mjs.map +2 -2
- package/dist-esm/lib/reordering.mjs.map +2 -2
- package/dist-esm/lib/retry.mjs.map +2 -2
- package/dist-esm/lib/sort.mjs.map +2 -2
- package/dist-esm/lib/storage.mjs.map +2 -2
- package/dist-esm/lib/stringEnum.mjs.map +2 -2
- package/dist-esm/lib/throttle.mjs.map +2 -2
- package/dist-esm/lib/timers.mjs +103 -4
- package/dist-esm/lib/timers.mjs.map +2 -2
- package/dist-esm/lib/url.mjs.map +2 -2
- package/dist-esm/lib/value.mjs.map +2 -2
- package/dist-esm/lib/version.mjs.map +2 -2
- package/dist-esm/lib/warn.mjs.map +2 -2
- package/package.json +1 -1
- package/src/lib/ExecutionQueue.test.ts +162 -20
- package/src/lib/ExecutionQueue.ts +110 -1
- package/src/lib/PerformanceTracker.test.ts +124 -0
- package/src/lib/PerformanceTracker.ts +63 -1
- package/src/lib/array.test.ts +263 -1
- package/src/lib/array.ts +183 -14
- package/src/lib/bind.test.ts +47 -0
- package/src/lib/bind.ts +69 -4
- package/src/lib/cache.test.ts +73 -0
- package/src/lib/cache.ts +47 -6
- package/src/lib/control.test.ts +50 -0
- package/src/lib/control.ts +198 -9
- package/src/lib/debounce.ts +28 -3
- package/src/lib/error.test.ts +60 -0
- package/src/lib/error.ts +27 -1
- package/src/lib/file.test.ts +49 -0
- package/src/lib/file.ts +117 -12
- package/src/lib/function.ts +11 -0
- package/src/lib/hash.test.ts +99 -0
- package/src/lib/hash.ts +69 -2
- package/src/lib/id.test.ts +32 -0
- package/src/lib/id.ts +53 -5
- package/src/lib/iterable.test.ts +25 -0
- package/src/lib/iterable.ts +4 -5
- package/src/lib/json-value.ts +71 -4
- package/src/lib/media/apng.test.ts +67 -0
- package/src/lib/media/apng.ts +38 -21
- package/src/lib/media/avif.test.ts +26 -0
- package/src/lib/media/avif.ts +34 -0
- package/src/lib/media/gif.test.ts +52 -0
- package/src/lib/media/gif.ts +25 -2
- package/src/lib/media/media.test.ts +58 -0
- package/src/lib/media/media.ts +220 -11
- package/src/lib/media/png.ts +162 -1
- package/src/lib/media/webp.test.ts +81 -0
- package/src/lib/media/webp.ts +33 -1
- package/src/lib/network.test.ts +38 -0
- package/src/lib/network.ts +6 -0
- package/src/lib/number.test.ts +74 -0
- package/src/lib/number.ts +29 -5
- package/src/lib/object.test.ts +236 -0
- package/src/lib/object.ts +194 -14
- package/src/lib/perf.ts +75 -3
- package/src/lib/reordering.test.ts +168 -0
- package/src/lib/reordering.ts +62 -4
- package/src/lib/retry.test.ts +77 -0
- package/src/lib/retry.ts +47 -1
- package/src/lib/sort.test.ts +36 -0
- package/src/lib/sort.ts +22 -1
- package/src/lib/storage.test.ts +130 -0
- package/src/lib/storage.tsx +54 -8
- package/src/lib/stringEnum.ts +20 -1
- package/src/lib/throttle.ts +46 -8
- package/src/lib/timers.test.ts +75 -0
- package/src/lib/timers.ts +124 -5
- package/src/lib/types.ts +126 -4
- package/src/lib/url.test.ts +44 -0
- package/src/lib/url.ts +40 -1
- package/src/lib/value.test.ts +102 -0
- package/src/lib/value.ts +67 -3
- package/src/lib/version.test.ts +494 -56
- package/src/lib/version.ts +36 -1
- package/src/lib/warn.test.ts +64 -0
- package/src/lib/warn.ts +43 -2
package/dist-cjs/index.d.ts
CHANGED
|
@@ -14,16 +14,54 @@ import { default as uniq } from 'lodash.uniq';
|
|
|
14
14
|
/* Excluded from this release type: assertExists */
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Decorator that binds a method to its class instance (legacy stage-2 TypeScript decorators).
|
|
18
|
+
* When applied to a class method, ensures `this` always refers to the class instance,
|
|
19
|
+
* even when the method is called as a callback or event handler.
|
|
19
20
|
*
|
|
21
|
+
* @param target - The prototype of the class being decorated
|
|
22
|
+
* @param propertyKey - The name of the method being decorated
|
|
23
|
+
* @param descriptor - The property descriptor for the method being decorated
|
|
24
|
+
* @returns The modified property descriptor with bound method access
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* class MyClass {
|
|
28
|
+
* name = 'example';
|
|
29
|
+
*
|
|
30
|
+
* @bind
|
|
31
|
+
* getName() {
|
|
32
|
+
* return this.name;
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* const instance = new MyClass();
|
|
37
|
+
* const callback = instance.getName;
|
|
38
|
+
* console.log(callback()); // 'example' (this is properly bound)
|
|
39
|
+
* ```
|
|
20
40
|
* @public
|
|
21
41
|
*/
|
|
22
42
|
export declare function bind<T extends (...args: any[]) => any>(target: object, propertyKey: string, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T>;
|
|
23
43
|
|
|
24
44
|
/**
|
|
25
|
-
*
|
|
45
|
+
* Decorator that binds a method to its class instance (TC39 decorators standard).
|
|
46
|
+
* When applied to a class method, ensures `this` always refers to the class instance,
|
|
47
|
+
* even when the method is called as a callback or event handler.
|
|
26
48
|
*
|
|
49
|
+
* @param originalMethod - The original method being decorated
|
|
50
|
+
* @param context - The decorator context containing metadata about the method
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* class EventHandler {
|
|
54
|
+
* message = 'Hello World';
|
|
55
|
+
*
|
|
56
|
+
* @bind
|
|
57
|
+
* handleClick() {
|
|
58
|
+
* console.log(this.message);
|
|
59
|
+
* }
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* const handler = new EventHandler();
|
|
63
|
+
* document.addEventListener('click', handler.handleClick); // 'this' is properly bound
|
|
64
|
+
* ```
|
|
27
65
|
* @public
|
|
28
66
|
*/
|
|
29
67
|
export declare function bind<This extends object, T extends (...args: any[]) => any>(originalMethod: T, context: ClassMethodDecoratorContext<This, T>): void;
|
|
@@ -35,12 +73,37 @@ export declare function bind<This extends object, T extends (...args: any[]) =>
|
|
|
35
73
|
/* Excluded from this release type: compact */
|
|
36
74
|
|
|
37
75
|
/**
|
|
38
|
-
*
|
|
76
|
+
* Create a debounced version of a function that delays execution until after a specified wait time.
|
|
39
77
|
*
|
|
40
|
-
*
|
|
78
|
+
* Debouncing ensures that a function is only executed once after a specified delay,
|
|
79
|
+
* even if called multiple times in rapid succession. Each new call resets the timer. The debounced
|
|
80
|
+
* function returns a Promise that resolves with the result of the original function. Includes a
|
|
81
|
+
* cancel method to prevent execution if needed.
|
|
82
|
+
*
|
|
83
|
+
* @param callback - The function to debounce (can be sync or async)
|
|
84
|
+
* @param wait - The delay in milliseconds before executing the function
|
|
85
|
+
* @returns A debounced function that returns a Promise and includes a cancel method
|
|
41
86
|
*
|
|
87
|
+
* @example
|
|
42
88
|
* ```ts
|
|
43
|
-
*
|
|
89
|
+
* // Debounce a search function
|
|
90
|
+
* const searchAPI = (query: string) => fetch(`/search?q=${query}`)
|
|
91
|
+
* const debouncedSearch = debounce(searchAPI, 300)
|
|
92
|
+
*
|
|
93
|
+
* // Multiple rapid calls will only execute the last one after 300ms
|
|
94
|
+
* debouncedSearch('react').then(result => console.log(result))
|
|
95
|
+
* debouncedSearch('react hooks') // This cancels the previous call
|
|
96
|
+
* debouncedSearch('react typescript') // Only this will execute
|
|
97
|
+
*
|
|
98
|
+
* // Cancel pending execution
|
|
99
|
+
* debouncedSearch.cancel()
|
|
100
|
+
*
|
|
101
|
+
* // With async/await
|
|
102
|
+
* const saveData = debounce(async (data: any) => {
|
|
103
|
+
* return await api.save(data)
|
|
104
|
+
* }, 1000)
|
|
105
|
+
*
|
|
106
|
+
* const result = await saveData({name: 'John'})
|
|
44
107
|
* ```
|
|
45
108
|
*
|
|
46
109
|
* @public
|
|
@@ -52,22 +115,88 @@ export declare function debounce<T extends unknown[], U>(callback: (...args: T)
|
|
|
52
115
|
};
|
|
53
116
|
|
|
54
117
|
/**
|
|
55
|
-
*
|
|
118
|
+
* Remove duplicate items from an array.
|
|
119
|
+
*
|
|
120
|
+
* Creates a new array with duplicate items removed. Uses strict equality by default,
|
|
121
|
+
* or a custom equality function if provided. Order of first occurrence is preserved.
|
|
56
122
|
*
|
|
123
|
+
* @param input - The array to deduplicate
|
|
124
|
+
* @param equals - Optional custom equality function to compare items (defaults to strict equality)
|
|
125
|
+
* @returns A new array with duplicate items removed
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* dedupe([1, 2, 2, 3, 1]) // [1, 2, 3]
|
|
130
|
+
* dedupe(['a', 'b', 'a', 'c']) // ['a', 'b', 'c']
|
|
131
|
+
*
|
|
132
|
+
* // With custom equality function
|
|
133
|
+
* const objects = [{id: 1}, {id: 2}, {id: 1}]
|
|
134
|
+
* dedupe(objects, (a, b) => a.id === b.id) // [{id: 1}, {id: 2}]
|
|
135
|
+
* ```
|
|
57
136
|
* @public
|
|
58
137
|
*/
|
|
59
138
|
export declare function dedupe<T>(input: T[], equals?: (a: any, b: any) => boolean): T[];
|
|
60
139
|
|
|
61
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Array of supported video MIME types.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* import { DEFAULT_SUPPORT_VIDEO_TYPES } from '@tldraw/utils'
|
|
146
|
+
*
|
|
147
|
+
* const isVideo = DEFAULT_SUPPORT_VIDEO_TYPES.includes('video/mp4')
|
|
148
|
+
* console.log(isVideo) // true
|
|
149
|
+
* ```
|
|
150
|
+
* @public
|
|
151
|
+
*/
|
|
62
152
|
export declare const DEFAULT_SUPPORT_VIDEO_TYPES: readonly ("video/mp4" | "video/quicktime" | "video/webm")[];
|
|
63
153
|
|
|
64
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* Array of all supported image MIME types, combining static, vector, and animated types.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* import { DEFAULT_SUPPORTED_IMAGE_TYPES } from '@tldraw/utils'
|
|
160
|
+
*
|
|
161
|
+
* const isSupported = DEFAULT_SUPPORTED_IMAGE_TYPES.includes('image/png')
|
|
162
|
+
* console.log(isSupported) // true
|
|
163
|
+
* ```
|
|
164
|
+
* @public
|
|
165
|
+
*/
|
|
65
166
|
export declare const DEFAULT_SUPPORTED_IMAGE_TYPES: readonly ("image/apng" | "image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/svg+xml" | "image/webp")[];
|
|
66
167
|
|
|
67
|
-
/**
|
|
168
|
+
/**
|
|
169
|
+
* Comma-separated string of all supported media MIME types, useful for HTML file input accept attributes.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```ts
|
|
173
|
+
* import { DEFAULT_SUPPORTED_MEDIA_TYPE_LIST } from '@tldraw/utils'
|
|
174
|
+
*
|
|
175
|
+
* // Use in HTML file input for media uploads
|
|
176
|
+
* const input = document.createElement('input')
|
|
177
|
+
* input.type = 'file'
|
|
178
|
+
* input.accept = DEFAULT_SUPPORTED_MEDIA_TYPE_LIST
|
|
179
|
+
* input.addEventListener('change', (e) => {
|
|
180
|
+
* const files = (e.target as HTMLInputElement).files
|
|
181
|
+
* if (files) console.log(`Selected ${files.length} file(s)`)
|
|
182
|
+
* })
|
|
183
|
+
* ```
|
|
184
|
+
* @public
|
|
185
|
+
*/
|
|
68
186
|
export declare const DEFAULT_SUPPORTED_MEDIA_TYPE_LIST: string;
|
|
69
187
|
|
|
70
|
-
/**
|
|
188
|
+
/**
|
|
189
|
+
* Array of all supported media MIME types, combining images and videos.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* import { DEFAULT_SUPPORTED_MEDIA_TYPES } from '@tldraw/utils'
|
|
194
|
+
*
|
|
195
|
+
* const isMediaFile = DEFAULT_SUPPORTED_MEDIA_TYPES.includes('video/mp4')
|
|
196
|
+
* console.log(isMediaFile) // true
|
|
197
|
+
* ```
|
|
198
|
+
* @public
|
|
199
|
+
*/
|
|
71
200
|
export declare const DEFAULT_SUPPORTED_MEDIA_TYPES: readonly ("image/apng" | "image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/svg+xml" | "image/webp" | "video/mp4" | "video/quicktime" | "video/webm")[];
|
|
72
201
|
|
|
73
202
|
/* Excluded from this release type: deleteFromLocalStorage */
|
|
@@ -80,7 +209,21 @@ export declare interface ErrorAnnotations {
|
|
|
80
209
|
extras: Record<string, unknown>;
|
|
81
210
|
}
|
|
82
211
|
|
|
83
|
-
/**
|
|
212
|
+
/**
|
|
213
|
+
* Represents a failed result containing an error.
|
|
214
|
+
*
|
|
215
|
+
* Interface for the error case of a Result type, containing the error information.
|
|
216
|
+
* Used in conjunction with OkResult to create a discriminated union for error handling.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* const failure: ErrorResult<string> = { ok: false, error: 'Something went wrong' }
|
|
221
|
+
* if (!failure.ok) {
|
|
222
|
+
* console.error(failure.error) // 'Something went wrong'
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
* @public
|
|
226
|
+
*/
|
|
84
227
|
export declare interface ErrorResult<E> {
|
|
85
228
|
readonly ok: false;
|
|
86
229
|
readonly error: E;
|
|
@@ -90,7 +233,27 @@ export declare interface ErrorResult<E> {
|
|
|
90
233
|
|
|
91
234
|
/* Excluded from this release type: exhaustiveSwitchError */
|
|
92
235
|
|
|
93
|
-
/**
|
|
236
|
+
/**
|
|
237
|
+
* Expands a type definition to show its full structure in IDE tooltips and error messages.
|
|
238
|
+
* This utility type forces TypeScript to resolve and display the complete type structure
|
|
239
|
+
* instead of showing complex conditional types or intersections as-is.
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```ts
|
|
243
|
+
* type User = { name: string }
|
|
244
|
+
* type WithId = { id: string }
|
|
245
|
+
* type UserWithId = User & WithId
|
|
246
|
+
*
|
|
247
|
+
* // Without Expand, IDE shows: User & WithId
|
|
248
|
+
* // With Expand, IDE shows: { name: string; id: string }
|
|
249
|
+
* type ExpandedUserWithId = Expand<UserWithId>
|
|
250
|
+
*
|
|
251
|
+
* // Useful for complex intersections
|
|
252
|
+
* type ComplexType = Expand<BaseType & Mixin1 & Mixin2>
|
|
253
|
+
* ```
|
|
254
|
+
*
|
|
255
|
+
* @public
|
|
256
|
+
*/
|
|
94
257
|
export declare type Expand<T> = T extends infer O ? {
|
|
95
258
|
[K in keyof O]: O[K];
|
|
96
259
|
} : never;
|
|
@@ -98,41 +261,146 @@ export declare type Expand<T> = T extends infer O ? {
|
|
|
98
261
|
/* Excluded from this release type: fetch_2 */
|
|
99
262
|
|
|
100
263
|
/**
|
|
101
|
-
*
|
|
264
|
+
* Utility class providing helper methods for file and blob operations.
|
|
265
|
+
*
|
|
266
|
+
* FileHelpers contains static methods for common file operations including
|
|
267
|
+
* URL fetching, format conversion, and MIME type manipulation. All methods work with
|
|
268
|
+
* web APIs like fetch, FileReader, and Blob/File objects.
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```ts
|
|
272
|
+
* // Fetch and convert a remote image to data URL
|
|
273
|
+
* const dataUrl = await FileHelpers.urlToDataUrl('https://example.com/image.png')
|
|
274
|
+
*
|
|
275
|
+
* // Convert user-selected file to text
|
|
276
|
+
* const text = await FileHelpers.blobToText(userFile)
|
|
277
|
+
*
|
|
278
|
+
* // Change file MIME type
|
|
279
|
+
* const newFile = FileHelpers.rewriteMimeType(originalFile, 'application/json')
|
|
280
|
+
* ```
|
|
102
281
|
*
|
|
103
282
|
* @public
|
|
104
283
|
*/
|
|
105
284
|
export declare class FileHelpers {
|
|
106
285
|
/**
|
|
107
|
-
*
|
|
286
|
+
* Converts a URL to an ArrayBuffer by fetching the resource.
|
|
287
|
+
*
|
|
288
|
+
* Fetches the resource at the given URL and returns its content as an ArrayBuffer.
|
|
289
|
+
* This is useful for loading binary data like images, videos, or other file types.
|
|
290
|
+
*
|
|
291
|
+
* @param url - The URL of the file to fetch
|
|
292
|
+
* @returns Promise that resolves to the file content as an ArrayBuffer
|
|
293
|
+
* @example
|
|
294
|
+
* ```ts
|
|
295
|
+
* const buffer = await FileHelpers.urlToArrayBuffer('https://example.com/image.png')
|
|
296
|
+
* console.log(buffer.byteLength) // Size of the file in bytes
|
|
297
|
+
* ```
|
|
298
|
+
* @public
|
|
108
299
|
*/
|
|
109
300
|
static urlToArrayBuffer(url: string): Promise<ArrayBuffer>;
|
|
110
|
-
static urlToBlob(url: string): Promise<Blob>;
|
|
111
|
-
static urlToDataUrl(url: string): Promise<string>;
|
|
112
301
|
/**
|
|
113
|
-
*
|
|
302
|
+
* Converts a URL to a Blob by fetching the resource.
|
|
114
303
|
*
|
|
304
|
+
* Fetches the resource at the given URL and returns its content as a Blob object.
|
|
305
|
+
* Blobs are useful for handling file data in web applications.
|
|
306
|
+
*
|
|
307
|
+
* @param url - The URL of the file to fetch
|
|
308
|
+
* @returns Promise that resolves to the file content as a Blob
|
|
115
309
|
* @example
|
|
310
|
+
* ```ts
|
|
311
|
+
* const blob = await FileHelpers.urlToBlob('https://example.com/document.pdf')
|
|
312
|
+
* console.log(blob.type) // 'application/pdf'
|
|
313
|
+
* console.log(blob.size) // Size in bytes
|
|
314
|
+
* ```
|
|
315
|
+
* @public
|
|
316
|
+
*/
|
|
317
|
+
static urlToBlob(url: string): Promise<Blob>;
|
|
318
|
+
/**
|
|
319
|
+
* Converts a URL to a data URL by fetching the resource.
|
|
320
|
+
*
|
|
321
|
+
* Fetches the resource at the given URL and converts it to a base64-encoded data URL.
|
|
322
|
+
* If the URL is already a data URL, it returns the URL unchanged. This is useful for embedding
|
|
323
|
+
* resources directly in HTML or CSS.
|
|
116
324
|
*
|
|
325
|
+
* @param url - The URL of the file to convert, or an existing data URL
|
|
326
|
+
* @returns Promise that resolves to a data URL string
|
|
327
|
+
* @example
|
|
117
328
|
* ```ts
|
|
118
|
-
* const
|
|
329
|
+
* const dataUrl = await FileHelpers.urlToDataUrl('https://example.com/image.jpg')
|
|
330
|
+
* // Returns: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEA...'
|
|
331
|
+
*
|
|
332
|
+
* const existing = await FileHelpers.urlToDataUrl('data:text/plain;base64,SGVsbG8=')
|
|
333
|
+
* // Returns the same data URL unchanged
|
|
119
334
|
* ```
|
|
335
|
+
* @public
|
|
336
|
+
*/
|
|
337
|
+
static urlToDataUrl(url: string): Promise<string>;
|
|
338
|
+
/**
|
|
339
|
+
* Convert a Blob to a base64 encoded data URL.
|
|
340
|
+
*
|
|
341
|
+
* Converts a Blob object to a base64-encoded data URL using the FileReader API.
|
|
342
|
+
* This is useful for displaying images or embedding file content directly in HTML.
|
|
343
|
+
*
|
|
344
|
+
* @param file - The Blob object to convert
|
|
345
|
+
* @returns Promise that resolves to a base64-encoded data URL string
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* const blob = new Blob(['Hello World'], { type: 'text/plain' })
|
|
349
|
+
* const dataUrl = await FileHelpers.blobToDataUrl(blob)
|
|
350
|
+
* // Returns: 'data:text/plain;base64,SGVsbG8gV29ybGQ='
|
|
120
351
|
*
|
|
121
|
-
*
|
|
352
|
+
* // With an image file
|
|
353
|
+
* const imageDataUrl = await FileHelpers.blobToDataUrl(myImageFile)
|
|
354
|
+
* // Can be used directly in img src attribute
|
|
355
|
+
* ```
|
|
356
|
+
* @public
|
|
122
357
|
*/
|
|
123
358
|
static blobToDataUrl(file: Blob): Promise<string>;
|
|
124
359
|
/**
|
|
125
|
-
* Convert a
|
|
360
|
+
* Convert a Blob to a unicode text string.
|
|
126
361
|
*
|
|
127
|
-
*
|
|
362
|
+
* Reads the content of a Blob object as a UTF-8 text string using the FileReader API.
|
|
363
|
+
* This is useful for reading text files or extracting text content from blobs.
|
|
128
364
|
*
|
|
365
|
+
* @param file - The Blob object to convert to text
|
|
366
|
+
* @returns Promise that resolves to the text content as a string
|
|
367
|
+
* @example
|
|
129
368
|
* ```ts
|
|
130
|
-
* const
|
|
131
|
-
*
|
|
369
|
+
* const textBlob = new Blob(['Hello World'], { type: 'text/plain' })
|
|
370
|
+
* const text = await FileHelpers.blobToText(textBlob)
|
|
371
|
+
* console.log(text) // 'Hello World'
|
|
132
372
|
*
|
|
133
|
-
*
|
|
373
|
+
* // With a text file from user input
|
|
374
|
+
* const content = await FileHelpers.blobToText(myTextFile)
|
|
375
|
+
* console.log(content) // File content as string
|
|
376
|
+
* ```
|
|
377
|
+
* @public
|
|
134
378
|
*/
|
|
135
379
|
static blobToText(file: Blob): Promise<string>;
|
|
380
|
+
/**
|
|
381
|
+
* Creates a new Blob or File with a different MIME type.
|
|
382
|
+
*
|
|
383
|
+
* Creates a copy of the given Blob or File with a new MIME type while preserving
|
|
384
|
+
* all other properties. If the current MIME type already matches the new one, returns the
|
|
385
|
+
* original object unchanged. For File objects, preserves the filename.
|
|
386
|
+
*
|
|
387
|
+
* @param blob - The Blob or File object to modify
|
|
388
|
+
* @param newMimeType - The new MIME type to assign
|
|
389
|
+
* @returns A new Blob or File with the updated MIME type
|
|
390
|
+
* @example
|
|
391
|
+
* ```ts
|
|
392
|
+
* // Change a generic blob to a specific image type
|
|
393
|
+
* const blob = new Blob([imageData])
|
|
394
|
+
* const imageBlob = FileHelpers.rewriteMimeType(blob, 'image/png')
|
|
395
|
+
*
|
|
396
|
+
* // Change a file's MIME type while preserving filename
|
|
397
|
+
* const file = new File([data], 'document.txt', { type: 'text/plain' })
|
|
398
|
+
* const jsonFile = FileHelpers.rewriteMimeType(file, 'application/json')
|
|
399
|
+
* console.log(jsonFile.name) // 'document.txt' (preserved)
|
|
400
|
+
* console.log(jsonFile.type) // 'application/json' (updated)
|
|
401
|
+
* ```
|
|
402
|
+
* @public
|
|
403
|
+
*/
|
|
136
404
|
static rewriteMimeType(blob: Blob, newMimeType: string): Blob;
|
|
137
405
|
static rewriteMimeType(blob: File, newMimeType: string): File;
|
|
138
406
|
}
|
|
@@ -148,19 +416,18 @@ export declare class FileHelpers {
|
|
|
148
416
|
/**
|
|
149
417
|
* Get the first item from an iterable Set or Map.
|
|
150
418
|
*
|
|
419
|
+
* @param value - The iterable Set or Map to get the first item from
|
|
420
|
+
* @returns The first value from the Set or Map
|
|
151
421
|
* @example
|
|
152
|
-
*
|
|
153
422
|
* ```ts
|
|
154
|
-
* const A =
|
|
155
|
-
* const B =
|
|
423
|
+
* const A = getFirstFromIterable(new Set([1, 2, 3])) // 1
|
|
424
|
+
* const B = getFirstFromIterable(
|
|
156
425
|
* new Map([
|
|
157
426
|
* ['a', 1],
|
|
158
427
|
* ['b', 2],
|
|
159
428
|
* ])
|
|
160
429
|
* ) // 1
|
|
161
430
|
* ```
|
|
162
|
-
*
|
|
163
|
-
* @param value - The iterable Set or Map.
|
|
164
431
|
* @public
|
|
165
432
|
*/
|
|
166
433
|
export declare function getFirstFromIterable<T = unknown>(set: Map<any, T> | Set<T>): T;
|
|
@@ -172,13 +439,47 @@ export declare function getFirstFromIterable<T = unknown>(set: Map<any, T> | Set
|
|
|
172
439
|
/**
|
|
173
440
|
* Hash an ArrayBuffer using the FNV-1a algorithm.
|
|
174
441
|
*
|
|
442
|
+
* Generates a deterministic hash value for binary data stored in an ArrayBuffer.
|
|
443
|
+
* Processes the buffer byte by byte using the same hashing algorithm as getHashForString.
|
|
444
|
+
* Useful for creating consistent identifiers for binary data like images or files.
|
|
445
|
+
*
|
|
446
|
+
* @param buffer - The ArrayBuffer containing binary data to hash
|
|
447
|
+
* @returns A string representation of the 32-bit hash value
|
|
448
|
+
* @example
|
|
449
|
+
* ```ts
|
|
450
|
+
* // Hash some binary data
|
|
451
|
+
* const data = new Uint8Array([1, 2, 3, 4, 5])
|
|
452
|
+
* const hash = getHashForBuffer(data.buffer)
|
|
453
|
+
* console.log(hash) // '123456789'
|
|
454
|
+
*
|
|
455
|
+
* // Hash image file data
|
|
456
|
+
* const fileBuffer = await file.arrayBuffer()
|
|
457
|
+
* const fileHash = getHashForBuffer(fileBuffer)
|
|
458
|
+
* console.log(fileHash) // Unique hash for the file
|
|
459
|
+
* ```
|
|
175
460
|
* @public
|
|
176
461
|
*/
|
|
177
462
|
export declare function getHashForBuffer(buffer: ArrayBuffer): string;
|
|
178
463
|
|
|
179
464
|
/**
|
|
180
|
-
* Hash
|
|
465
|
+
* Hash an object by converting it to JSON and then hashing the resulting string.
|
|
466
|
+
*
|
|
467
|
+
* Converts the object to a JSON string using JSON.stringify and then applies the same
|
|
468
|
+
* hashing algorithm as getHashForString. Useful for creating consistent hash values
|
|
469
|
+
* for objects, though the hash depends on JSON serialization order.
|
|
470
|
+
*
|
|
471
|
+
* @param obj - The object to hash (any JSON-serializable value)
|
|
472
|
+
* @returns A string representation of the 32-bit hash value
|
|
473
|
+
* @example
|
|
474
|
+
* ```ts
|
|
475
|
+
* const hash1 = getHashForObject({ name: 'John', age: 30 })
|
|
476
|
+
* const hash2 = getHashForObject({ name: 'John', age: 30 })
|
|
477
|
+
* console.log(hash1 === hash2) // true
|
|
181
478
|
*
|
|
479
|
+
* // Arrays work too
|
|
480
|
+
* const arrayHash = getHashForObject([1, 2, 3, 'hello'])
|
|
481
|
+
* console.log(arrayHash) // '-123456789'
|
|
482
|
+
* ```
|
|
182
483
|
* @public
|
|
183
484
|
*/
|
|
184
485
|
export declare function getHashForObject(obj: any): string;
|
|
@@ -186,6 +487,20 @@ export declare function getHashForObject(obj: any): string;
|
|
|
186
487
|
/**
|
|
187
488
|
* Hash a string using the FNV-1a algorithm.
|
|
188
489
|
*
|
|
490
|
+
* Generates a deterministic hash value for a given string using a variant of the FNV-1a
|
|
491
|
+
* (Fowler-Noll-Vo) algorithm. The hash is returned as a string representation of a 32-bit integer.
|
|
492
|
+
*
|
|
493
|
+
* @param string - The input string to hash
|
|
494
|
+
* @returns A string representation of the 32-bit hash value
|
|
495
|
+
* @example
|
|
496
|
+
* ```ts
|
|
497
|
+
* const hash = getHashForString('hello world')
|
|
498
|
+
* console.log(hash) // '-862545276'
|
|
499
|
+
*
|
|
500
|
+
* // Same input always produces same hash
|
|
501
|
+
* const hash2 = getHashForString('hello world')
|
|
502
|
+
* console.log(hash === hash2) // true
|
|
503
|
+
* ```
|
|
189
504
|
* @public
|
|
190
505
|
*/
|
|
191
506
|
export declare function getHashForString(string: string): string;
|
|
@@ -193,6 +508,12 @@ export declare function getHashForString(string: string): string;
|
|
|
193
508
|
/**
|
|
194
509
|
* Get the index above a given index.
|
|
195
510
|
* @param below - The index below.
|
|
511
|
+
* @returns An IndexKey value above the given index.
|
|
512
|
+
* @example
|
|
513
|
+
* ```ts
|
|
514
|
+
* const index = getIndexAbove('a0' as IndexKey)
|
|
515
|
+
* console.log(index) // 'a1'
|
|
516
|
+
* ```
|
|
196
517
|
* @public
|
|
197
518
|
*/
|
|
198
519
|
export declare function getIndexAbove(below?: IndexKey | null | undefined): IndexKey;
|
|
@@ -200,7 +521,13 @@ export declare function getIndexAbove(below?: IndexKey | null | undefined): Inde
|
|
|
200
521
|
/**
|
|
201
522
|
* Get the index below a given index.
|
|
202
523
|
* @param above - The index above.
|
|
203
|
-
*
|
|
524
|
+
* @returns An IndexKey value below the given index.
|
|
525
|
+
* @example
|
|
526
|
+
* ```ts
|
|
527
|
+
* const index = getIndexBelow('a2' as IndexKey)
|
|
528
|
+
* console.log(index) // 'a1'
|
|
529
|
+
* ```
|
|
530
|
+
* @public
|
|
204
531
|
*/
|
|
205
532
|
export declare function getIndexBelow(above?: IndexKey | null | undefined): IndexKey;
|
|
206
533
|
|
|
@@ -208,6 +535,12 @@ export declare function getIndexBelow(above?: IndexKey | null | undefined): Inde
|
|
|
208
535
|
* Get the index between two indices.
|
|
209
536
|
* @param below - The index below.
|
|
210
537
|
* @param above - The index above.
|
|
538
|
+
* @returns A single IndexKey value between below and above.
|
|
539
|
+
* @example
|
|
540
|
+
* ```ts
|
|
541
|
+
* const index = getIndexBetween('a0' as IndexKey, 'a2' as IndexKey)
|
|
542
|
+
* console.log(index) // 'a1'
|
|
543
|
+
* ```
|
|
211
544
|
* @public
|
|
212
545
|
*/
|
|
213
546
|
export declare function getIndexBetween(below: IndexKey | null | undefined, above: IndexKey | null | undefined): IndexKey;
|
|
@@ -215,7 +548,13 @@ export declare function getIndexBetween(below: IndexKey | null | undefined, abov
|
|
|
215
548
|
/**
|
|
216
549
|
* Get n number of indices, starting at an index.
|
|
217
550
|
* @param n - The number of indices to get.
|
|
218
|
-
* @param start -
|
|
551
|
+
* @param start - The index to start at.
|
|
552
|
+
* @returns An array containing the start index plus n additional IndexKey values.
|
|
553
|
+
* @example
|
|
554
|
+
* ```ts
|
|
555
|
+
* const indices = getIndices(3, 'a1' as IndexKey)
|
|
556
|
+
* console.log(indices) // ['a1', 'a2', 'a3', 'a4']
|
|
557
|
+
* ```
|
|
219
558
|
* @public
|
|
220
559
|
*/
|
|
221
560
|
export declare function getIndices(n: number, start?: IndexKey): IndexKey[];
|
|
@@ -224,6 +563,12 @@ export declare function getIndices(n: number, start?: IndexKey): IndexKey[];
|
|
|
224
563
|
* Get a number of indices above an index.
|
|
225
564
|
* @param below - The index below.
|
|
226
565
|
* @param n - The number of indices to get.
|
|
566
|
+
* @returns An array of n IndexKey values above the given index.
|
|
567
|
+
* @example
|
|
568
|
+
* ```ts
|
|
569
|
+
* const indices = getIndicesAbove('a0' as IndexKey, 3)
|
|
570
|
+
* console.log(indices) // ['a1', 'a2', 'a3']
|
|
571
|
+
* ```
|
|
227
572
|
* @public
|
|
228
573
|
*/
|
|
229
574
|
export declare function getIndicesAbove(below: IndexKey | null | undefined, n: number): IndexKey[];
|
|
@@ -232,6 +577,12 @@ export declare function getIndicesAbove(below: IndexKey | null | undefined, n: n
|
|
|
232
577
|
* Get a number of indices below an index.
|
|
233
578
|
* @param above - The index above.
|
|
234
579
|
* @param n - The number of indices to get.
|
|
580
|
+
* @returns An array of n IndexKey values below the given index.
|
|
581
|
+
* @example
|
|
582
|
+
* ```ts
|
|
583
|
+
* const indices = getIndicesBelow('a2' as IndexKey, 2)
|
|
584
|
+
* console.log(indices) // ['a1', 'a0V']
|
|
585
|
+
* ```
|
|
235
586
|
* @public
|
|
236
587
|
*/
|
|
237
588
|
export declare function getIndicesBelow(above: IndexKey | null | undefined, n: number): IndexKey[];
|
|
@@ -241,6 +592,12 @@ export declare function getIndicesBelow(above: IndexKey | null | undefined, n: n
|
|
|
241
592
|
* @param below - The index below.
|
|
242
593
|
* @param above - The index above.
|
|
243
594
|
* @param n - The number of indices to get.
|
|
595
|
+
* @returns An array of n IndexKey values between below and above.
|
|
596
|
+
* @example
|
|
597
|
+
* ```ts
|
|
598
|
+
* const indices = getIndicesBetween('a0' as IndexKey, 'a2' as IndexKey, 2)
|
|
599
|
+
* console.log(indices) // ['a0V', 'a1']
|
|
600
|
+
* ```
|
|
244
601
|
* @public
|
|
245
602
|
*/
|
|
246
603
|
export declare function getIndicesBetween(below: IndexKey | null | undefined, above: IndexKey | null | undefined, n: number): IndexKey[];
|
|
@@ -265,9 +622,18 @@ export declare type IndexKey = string & {
|
|
|
265
622
|
};
|
|
266
623
|
|
|
267
624
|
/**
|
|
268
|
-
* Inverse lerp between two values. Given a value `
|
|
625
|
+
* Inverse lerp between two values. Given a value `t` in the range [a, b], returns a number between
|
|
269
626
|
* 0 and 1.
|
|
270
627
|
*
|
|
628
|
+
* @param a - The start value of the range
|
|
629
|
+
* @param b - The end value of the range
|
|
630
|
+
* @param t - The value within the range [a, b]
|
|
631
|
+
* @returns The normalized position (0-1) of t within the range [a, b]
|
|
632
|
+
* @example
|
|
633
|
+
* ```ts
|
|
634
|
+
* const position = invLerp(0, 100, 25) // 0.25
|
|
635
|
+
* const normalized = invLerp(10, 20, 15) // 0.5
|
|
636
|
+
* ```
|
|
271
637
|
* @public
|
|
272
638
|
*/
|
|
273
639
|
export declare function invLerp(a: number, b: number, t: number): number;
|
|
@@ -276,6 +642,20 @@ export declare function invLerp(a: number, b: number, t: number): number;
|
|
|
276
642
|
* Get whether a value is not undefined.
|
|
277
643
|
*
|
|
278
644
|
* @param value - The value to check.
|
|
645
|
+
* @returns True if the value is not undefined, with proper type narrowing.
|
|
646
|
+
* @example
|
|
647
|
+
* ```ts
|
|
648
|
+
* const maybeString: string | undefined = getValue()
|
|
649
|
+
*
|
|
650
|
+
* if (isDefined(maybeString)) {
|
|
651
|
+
* // TypeScript knows maybeString is string, not undefined
|
|
652
|
+
* console.log(maybeString.toUpperCase())
|
|
653
|
+
* }
|
|
654
|
+
*
|
|
655
|
+
* // Filter undefined values from arrays
|
|
656
|
+
* const values = [1, undefined, 2, undefined, 3]
|
|
657
|
+
* const definedValues = values.filter(isDefined) // [1, 2, 3]
|
|
658
|
+
* ```
|
|
279
659
|
* @public
|
|
280
660
|
*/
|
|
281
661
|
export declare function isDefined<T>(value: T): value is typeof value extends undefined ? never : T;
|
|
@@ -288,33 +668,125 @@ export { isEqualWith }
|
|
|
288
668
|
/* Excluded from this release type: isNativeStructuredClone */
|
|
289
669
|
|
|
290
670
|
/**
|
|
291
|
-
* Get whether a value is null
|
|
671
|
+
* Get whether a value is not null.
|
|
292
672
|
*
|
|
293
673
|
* @param value - The value to check.
|
|
674
|
+
* @returns True if the value is not null, with proper type narrowing.
|
|
675
|
+
* @example
|
|
676
|
+
* ```ts
|
|
677
|
+
* const maybeString: string | null = getValue()
|
|
678
|
+
*
|
|
679
|
+
* if (isNonNull(maybeString)) {
|
|
680
|
+
* // TypeScript knows maybeString is string, not null
|
|
681
|
+
* console.log(maybeString.length)
|
|
682
|
+
* }
|
|
683
|
+
*
|
|
684
|
+
* // Filter null values from arrays
|
|
685
|
+
* const values = ["a", null, "b", null, "c"]
|
|
686
|
+
* const nonNullValues = values.filter(isNonNull) // ["a", "b", "c"]
|
|
687
|
+
* ```
|
|
294
688
|
* @public
|
|
295
689
|
*/
|
|
296
690
|
export declare function isNonNull<T>(value: T): value is typeof value extends null ? never : T;
|
|
297
691
|
|
|
298
692
|
/**
|
|
299
|
-
* Get whether a value is nullish (null
|
|
693
|
+
* Get whether a value is not nullish (not null and not undefined).
|
|
300
694
|
*
|
|
301
695
|
* @param value - The value to check.
|
|
696
|
+
* @returns True if the value is neither null nor undefined, with proper type narrowing.
|
|
697
|
+
* @example
|
|
698
|
+
* ```ts
|
|
699
|
+
* const maybeString: string | null | undefined = getValue()
|
|
700
|
+
*
|
|
701
|
+
* if (isNonNullish(maybeString)) {
|
|
702
|
+
* // TypeScript knows maybeString is string, not null or undefined
|
|
703
|
+
* console.log(maybeString.charAt(0))
|
|
704
|
+
* }
|
|
705
|
+
*
|
|
706
|
+
* // Filter nullish values from arrays
|
|
707
|
+
* const values = ["hello", null, "world", undefined, "!"]
|
|
708
|
+
* const cleanValues = values.filter(isNonNullish) // ["hello", "world", "!"]
|
|
709
|
+
* ```
|
|
302
710
|
* @public
|
|
303
711
|
*/
|
|
304
712
|
export declare function isNonNullish<T>(value: T): value is typeof value extends undefined ? never : typeof value extends null ? never : T;
|
|
305
713
|
|
|
306
|
-
/**
|
|
714
|
+
/**
|
|
715
|
+
* A type representing a JSON array containing any valid JSON values.
|
|
716
|
+
* Arrays can contain mixed types of JSON values including nested arrays and objects.
|
|
717
|
+
*
|
|
718
|
+
* @example
|
|
719
|
+
* ```ts
|
|
720
|
+
* const jsonArray: JsonArray = [
|
|
721
|
+
* "text",
|
|
722
|
+
* 123,
|
|
723
|
+
* true,
|
|
724
|
+
* { nested: "object" },
|
|
725
|
+
* [1, 2, 3]
|
|
726
|
+
* ]
|
|
727
|
+
* ```
|
|
728
|
+
*
|
|
729
|
+
* @public
|
|
730
|
+
*/
|
|
307
731
|
export declare type JsonArray = JsonValue[];
|
|
308
732
|
|
|
309
|
-
/**
|
|
733
|
+
/**
|
|
734
|
+
* A type representing a JSON object with string keys and JSON values.
|
|
735
|
+
* Object values can be undefined to handle optional properties safely.
|
|
736
|
+
*
|
|
737
|
+
* @example
|
|
738
|
+
* ```ts
|
|
739
|
+
* const jsonObject: JsonObject = {
|
|
740
|
+
* required: "value",
|
|
741
|
+
* optional: undefined,
|
|
742
|
+
* nested: {
|
|
743
|
+
* deep: "property"
|
|
744
|
+
* },
|
|
745
|
+
* array: [1, 2, 3]
|
|
746
|
+
* }
|
|
747
|
+
* ```
|
|
748
|
+
*
|
|
749
|
+
* @public
|
|
750
|
+
*/
|
|
310
751
|
export declare interface JsonObject {
|
|
311
752
|
[key: string]: JsonValue | undefined;
|
|
312
753
|
}
|
|
313
754
|
|
|
314
|
-
/**
|
|
755
|
+
/**
|
|
756
|
+
* A type representing JSON primitive values: boolean, null, string, or number.
|
|
757
|
+
* These are the atomic values that can appear in JSON data.
|
|
758
|
+
*
|
|
759
|
+
* @example
|
|
760
|
+
* ```ts
|
|
761
|
+
* const primitives: JsonPrimitive[] = [
|
|
762
|
+
* true,
|
|
763
|
+
* null,
|
|
764
|
+
* "hello",
|
|
765
|
+
* 42
|
|
766
|
+
* ]
|
|
767
|
+
* ```
|
|
768
|
+
*
|
|
769
|
+
* @public
|
|
770
|
+
*/
|
|
315
771
|
export declare type JsonPrimitive = boolean | null | number | string;
|
|
316
772
|
|
|
317
|
-
/**
|
|
773
|
+
/**
|
|
774
|
+
* A type that represents any valid JSON value. This includes primitives (boolean, null, string, number),
|
|
775
|
+
* arrays of JSON values, and objects with string keys and JSON values.
|
|
776
|
+
*
|
|
777
|
+
* @example
|
|
778
|
+
* ```ts
|
|
779
|
+
* const jsonData: JsonValue = {
|
|
780
|
+
* name: "Alice",
|
|
781
|
+
* age: 30,
|
|
782
|
+
* active: true,
|
|
783
|
+
* tags: ["user", "premium"],
|
|
784
|
+
* metadata: null
|
|
785
|
+
* }
|
|
786
|
+
* ```
|
|
787
|
+
*
|
|
788
|
+
* @public
|
|
789
|
+
*/
|
|
318
790
|
export declare type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
|
319
791
|
|
|
320
792
|
/* Excluded from this release type: last */
|
|
@@ -322,20 +794,72 @@ export declare type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
|
|
322
794
|
/**
|
|
323
795
|
* Linear interpolate between two values.
|
|
324
796
|
*
|
|
797
|
+
* @param a - The start value
|
|
798
|
+
* @param b - The end value
|
|
799
|
+
* @param t - The interpolation factor (0-1)
|
|
800
|
+
* @returns The interpolated value
|
|
325
801
|
* @example
|
|
326
|
-
*
|
|
327
802
|
* ```ts
|
|
328
|
-
* const
|
|
803
|
+
* const halfway = lerp(0, 100, 0.5) // 50
|
|
804
|
+
* const quarter = lerp(10, 20, 0.25) // 12.5
|
|
329
805
|
* ```
|
|
330
|
-
*
|
|
331
806
|
* @public
|
|
332
807
|
*/
|
|
333
808
|
export declare function lerp(a: number, b: number, t: number): number;
|
|
334
809
|
|
|
335
|
-
/**
|
|
810
|
+
/**
|
|
811
|
+
* Applies a string transformation algorithm that rearranges and modifies characters.
|
|
812
|
+
*
|
|
813
|
+
* Performs a series of character manipulations on the input string including
|
|
814
|
+
* character repositioning through splicing operations and numeric character transformations.
|
|
815
|
+
* This appears to be a custom encoding/obfuscation function.
|
|
816
|
+
*
|
|
817
|
+
* @param str - The input string to transform
|
|
818
|
+
* @returns The transformed string after applying all manipulations
|
|
819
|
+
* @example
|
|
820
|
+
* ```ts
|
|
821
|
+
* const result = lns('hello123')
|
|
822
|
+
* console.log(result) // Transformed string (exact output depends on algorithm)
|
|
823
|
+
*
|
|
824
|
+
* // Can be used for simple string obfuscation
|
|
825
|
+
* const obfuscated = lns('sensitive-data')
|
|
826
|
+
* console.log(obfuscated) // Obfuscated version
|
|
827
|
+
* ```
|
|
828
|
+
* @public
|
|
829
|
+
*/
|
|
336
830
|
export declare function lns(str: string): string;
|
|
337
831
|
|
|
338
|
-
/**
|
|
832
|
+
/**
|
|
833
|
+
* Automatically makes properties optional if their type includes `undefined`.
|
|
834
|
+
* This transforms properties like `prop: string | undefined` to `prop?: string | undefined`,
|
|
835
|
+
* making the API more ergonomic by not requiring explicit undefined assignments.
|
|
836
|
+
*
|
|
837
|
+
* @example
|
|
838
|
+
* ```ts
|
|
839
|
+
* interface RawConfig {
|
|
840
|
+
* name: string
|
|
841
|
+
* theme: string | undefined
|
|
842
|
+
* debug: boolean | undefined
|
|
843
|
+
* version: number
|
|
844
|
+
* }
|
|
845
|
+
*
|
|
846
|
+
* type Config = MakeUndefinedOptional<RawConfig>
|
|
847
|
+
* // Result: {
|
|
848
|
+
* // name: string
|
|
849
|
+
* // theme?: string | undefined // now optional
|
|
850
|
+
* // debug?: boolean | undefined // now optional
|
|
851
|
+
* // version: number
|
|
852
|
+
* // }
|
|
853
|
+
*
|
|
854
|
+
* const config: Config = {
|
|
855
|
+
* name: 'MyApp',
|
|
856
|
+
* version: 1
|
|
857
|
+
* // theme and debug can be omitted instead of explicitly set to undefined
|
|
858
|
+
* }
|
|
859
|
+
* ```
|
|
860
|
+
*
|
|
861
|
+
* @public
|
|
862
|
+
*/
|
|
339
863
|
export declare type MakeUndefinedOptional<T extends object> = Expand<{
|
|
340
864
|
[P in {
|
|
341
865
|
[K in keyof T]: undefined extends T[K] ? never : K;
|
|
@@ -363,24 +887,65 @@ export declare type MakeUndefinedOptional<T extends object> = Expand<{
|
|
|
363
887
|
*/
|
|
364
888
|
export declare class MediaHelpers {
|
|
365
889
|
/**
|
|
366
|
-
* Load a video from a
|
|
890
|
+
* Load a video element from a URL with cross-origin support.
|
|
891
|
+
*
|
|
892
|
+
* @param src - The URL of the video to load
|
|
893
|
+
* @returns Promise that resolves to the loaded HTMLVideoElement
|
|
894
|
+
* @example
|
|
895
|
+
* ```ts
|
|
896
|
+
* const video = await MediaHelpers.loadVideo('https://example.com/video.mp4')
|
|
897
|
+
* console.log(`Video dimensions: ${video.videoWidth}x${video.videoHeight}`)
|
|
898
|
+
* ```
|
|
367
899
|
* @public
|
|
368
900
|
*/
|
|
369
901
|
static loadVideo(src: string): Promise<HTMLVideoElement>;
|
|
370
|
-
static getVideoFrameAsDataUrl(video: HTMLVideoElement, time?: number): Promise<string>;
|
|
371
902
|
/**
|
|
372
|
-
*
|
|
903
|
+
* Extract a frame from a video element as a data URL.
|
|
904
|
+
*
|
|
905
|
+
* @param video - The HTMLVideoElement to extract frame from
|
|
906
|
+
* @param time - The time in seconds to extract the frame from (default: 0)
|
|
907
|
+
* @returns Promise that resolves to a data URL of the video frame
|
|
908
|
+
* @example
|
|
909
|
+
* ```ts
|
|
910
|
+
* const video = await MediaHelpers.loadVideo('https://example.com/video.mp4')
|
|
911
|
+
* const frameDataUrl = await MediaHelpers.getVideoFrameAsDataUrl(video, 5.0)
|
|
912
|
+
* // Use frameDataUrl as image thumbnail
|
|
913
|
+
* const img = document.createElement('img')
|
|
914
|
+
* img.src = frameDataUrl
|
|
915
|
+
* ```
|
|
373
916
|
* @public
|
|
374
917
|
*/
|
|
375
|
-
static
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
918
|
+
static getVideoFrameAsDataUrl(video: HTMLVideoElement, time?: number): Promise<string>;
|
|
919
|
+
/**
|
|
920
|
+
* Load an image from a URL and get its dimensions along with the image element.
|
|
921
|
+
*
|
|
922
|
+
* @param src - The URL of the image to load
|
|
923
|
+
* @returns Promise that resolves to an object with width, height, and the image element
|
|
924
|
+
* @example
|
|
925
|
+
* ```ts
|
|
926
|
+
* const { w, h, image } = await MediaHelpers.getImageAndDimensions('https://example.com/image.png')
|
|
927
|
+
* console.log(`Image size: ${w}x${h}`)
|
|
928
|
+
* // Image is ready to use
|
|
929
|
+
* document.body.appendChild(image)
|
|
930
|
+
* ```
|
|
931
|
+
* @public
|
|
932
|
+
*/
|
|
933
|
+
static getImageAndDimensions(src: string): Promise<{
|
|
934
|
+
h: number;
|
|
935
|
+
image: HTMLImageElement;
|
|
936
|
+
w: number;
|
|
379
937
|
}>;
|
|
380
938
|
/**
|
|
381
939
|
* Get the size of a video blob
|
|
382
940
|
*
|
|
383
|
-
* @param blob - A
|
|
941
|
+
* @param blob - A Blob containing the video
|
|
942
|
+
* @returns Promise that resolves to an object with width and height properties
|
|
943
|
+
* @example
|
|
944
|
+
* ```ts
|
|
945
|
+
* const file = new File([...], 'video.mp4', { type: 'video/mp4' })
|
|
946
|
+
* const { w, h } = await MediaHelpers.getVideoSize(file)
|
|
947
|
+
* console.log(`Video dimensions: ${w}x${h}`)
|
|
948
|
+
* ```
|
|
384
949
|
* @public
|
|
385
950
|
*/
|
|
386
951
|
static getVideoSize(blob: Blob): Promise<{
|
|
@@ -390,18 +955,103 @@ export declare class MediaHelpers {
|
|
|
390
955
|
/**
|
|
391
956
|
* Get the size of an image blob
|
|
392
957
|
*
|
|
393
|
-
* @param blob - A Blob containing the image
|
|
958
|
+
* @param blob - A Blob containing the image
|
|
959
|
+
* @returns Promise that resolves to an object with width and height properties
|
|
960
|
+
* @example
|
|
961
|
+
* ```ts
|
|
962
|
+
* const file = new File([...], 'image.png', { type: 'image/png' })
|
|
963
|
+
* const { w, h } = await MediaHelpers.getImageSize(file)
|
|
964
|
+
* console.log(`Image dimensions: ${w}x${h}`)
|
|
965
|
+
* ```
|
|
394
966
|
* @public
|
|
395
967
|
*/
|
|
396
968
|
static getImageSize(blob: Blob): Promise<{
|
|
397
969
|
h: number;
|
|
398
970
|
w: number;
|
|
399
971
|
}>;
|
|
972
|
+
/**
|
|
973
|
+
* Check if a media file blob contains animation data.
|
|
974
|
+
*
|
|
975
|
+
* @param file - The Blob to check for animation
|
|
976
|
+
* @returns Promise that resolves to true if the file is animated, false otherwise
|
|
977
|
+
* @example
|
|
978
|
+
* ```ts
|
|
979
|
+
* const file = new File([...], 'animation.gif', { type: 'image/gif' })
|
|
980
|
+
* const animated = await MediaHelpers.isAnimated(file)
|
|
981
|
+
* console.log(animated ? 'Animated' : 'Static')
|
|
982
|
+
* ```
|
|
983
|
+
* @public
|
|
984
|
+
*/
|
|
400
985
|
static isAnimated(file: Blob): Promise<boolean>;
|
|
986
|
+
/**
|
|
987
|
+
* Check if a MIME type represents an animated image format.
|
|
988
|
+
*
|
|
989
|
+
* @param mimeType - The MIME type to check
|
|
990
|
+
* @returns True if the MIME type is an animated image format, false otherwise
|
|
991
|
+
* @example
|
|
992
|
+
* ```ts
|
|
993
|
+
* const isAnimated = MediaHelpers.isAnimatedImageType('image/gif')
|
|
994
|
+
* console.log(isAnimated) // true
|
|
995
|
+
* ```
|
|
996
|
+
* @public
|
|
997
|
+
*/
|
|
401
998
|
static isAnimatedImageType(mimeType: null | string): boolean;
|
|
999
|
+
/**
|
|
1000
|
+
* Check if a MIME type represents a static (non-animated) image format.
|
|
1001
|
+
*
|
|
1002
|
+
* @param mimeType - The MIME type to check
|
|
1003
|
+
* @returns True if the MIME type is a static image format, false otherwise
|
|
1004
|
+
* @example
|
|
1005
|
+
* ```ts
|
|
1006
|
+
* const isStatic = MediaHelpers.isStaticImageType('image/jpeg')
|
|
1007
|
+
* console.log(isStatic) // true
|
|
1008
|
+
* ```
|
|
1009
|
+
* @public
|
|
1010
|
+
*/
|
|
402
1011
|
static isStaticImageType(mimeType: null | string): boolean;
|
|
1012
|
+
/**
|
|
1013
|
+
* Check if a MIME type represents a vector image format.
|
|
1014
|
+
*
|
|
1015
|
+
* @param mimeType - The MIME type to check
|
|
1016
|
+
* @returns True if the MIME type is a vector image format, false otherwise
|
|
1017
|
+
* @example
|
|
1018
|
+
* ```ts
|
|
1019
|
+
* const isVector = MediaHelpers.isVectorImageType('image/svg+xml')
|
|
1020
|
+
* console.log(isVector) // true
|
|
1021
|
+
* ```
|
|
1022
|
+
* @public
|
|
1023
|
+
*/
|
|
403
1024
|
static isVectorImageType(mimeType: null | string): boolean;
|
|
1025
|
+
/**
|
|
1026
|
+
* Check if a MIME type represents any supported image format (static, animated, or vector).
|
|
1027
|
+
*
|
|
1028
|
+
* @param mimeType - The MIME type to check
|
|
1029
|
+
* @returns True if the MIME type is a supported image format, false otherwise
|
|
1030
|
+
* @example
|
|
1031
|
+
* ```ts
|
|
1032
|
+
* const isImage = MediaHelpers.isImageType('image/png')
|
|
1033
|
+
* console.log(isImage) // true
|
|
1034
|
+
* ```
|
|
1035
|
+
* @public
|
|
1036
|
+
*/
|
|
404
1037
|
static isImageType(mimeType: string): boolean;
|
|
1038
|
+
/**
|
|
1039
|
+
* Utility function to create an object URL from a blob, execute a function with it, and automatically clean it up.
|
|
1040
|
+
*
|
|
1041
|
+
* @param blob - The Blob to create an object URL for
|
|
1042
|
+
* @param fn - Function to execute with the object URL
|
|
1043
|
+
* @returns Promise that resolves to the result of the function
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```ts
|
|
1046
|
+
* const result = await MediaHelpers.usingObjectURL(imageBlob, async (url) => {
|
|
1047
|
+
* const { w, h } = await MediaHelpers.getImageAndDimensions(url)
|
|
1048
|
+
* return { width: w, height: h }
|
|
1049
|
+
* })
|
|
1050
|
+
* // Object URL is automatically revoked after function completes
|
|
1051
|
+
* console.log(`Image dimensions: ${result.width}x${result.height}`)
|
|
1052
|
+
* ```
|
|
1053
|
+
* @public
|
|
1054
|
+
*/
|
|
405
1055
|
static usingObjectURL<T>(blob: Blob, fn: (url: string) => Promise<T>): Promise<T>;
|
|
406
1056
|
}
|
|
407
1057
|
|
|
@@ -440,7 +1090,21 @@ export declare function modulate(value: number, rangeA: number[], rangeB: number
|
|
|
440
1090
|
|
|
441
1091
|
/* Excluded from this release type: objectMapValues */
|
|
442
1092
|
|
|
443
|
-
/**
|
|
1093
|
+
/**
|
|
1094
|
+
* Represents a successful result containing a value.
|
|
1095
|
+
*
|
|
1096
|
+
* Interface for the success case of a Result type, containing the computed value.
|
|
1097
|
+
* Used in conjunction with ErrorResult to create a discriminated union for error handling.
|
|
1098
|
+
*
|
|
1099
|
+
* @example
|
|
1100
|
+
* ```ts
|
|
1101
|
+
* const success: OkResult<string> = { ok: true, value: 'Hello World' }
|
|
1102
|
+
* if (success.ok) {
|
|
1103
|
+
* console.log(success.value) // 'Hello World'
|
|
1104
|
+
* }
|
|
1105
|
+
* ```
|
|
1106
|
+
* @public
|
|
1107
|
+
*/
|
|
444
1108
|
export declare interface OkResult<T> {
|
|
445
1109
|
readonly ok: true;
|
|
446
1110
|
readonly value: T;
|
|
@@ -452,44 +1116,307 @@ export declare interface OkResult<T> {
|
|
|
452
1116
|
|
|
453
1117
|
/* Excluded from this release type: partition */
|
|
454
1118
|
|
|
455
|
-
/**
|
|
1119
|
+
/**
|
|
1120
|
+
* A utility class for measuring and tracking frame rate performance during operations.
|
|
1121
|
+
* Provides visual feedback in the browser console with color-coded FPS indicators.
|
|
1122
|
+
*
|
|
1123
|
+
* @example
|
|
1124
|
+
* ```ts
|
|
1125
|
+
* const tracker = new PerformanceTracker()
|
|
1126
|
+
*
|
|
1127
|
+
* tracker.start('render')
|
|
1128
|
+
* renderShapes()
|
|
1129
|
+
* tracker.stop() // Logs performance info to console
|
|
1130
|
+
*
|
|
1131
|
+
* // Check if tracking is active
|
|
1132
|
+
* if (tracker.isStarted()) {
|
|
1133
|
+
* console.log('Still tracking performance')
|
|
1134
|
+
* }
|
|
1135
|
+
* ```
|
|
1136
|
+
*
|
|
1137
|
+
* @public
|
|
1138
|
+
*/
|
|
456
1139
|
export declare class PerformanceTracker {
|
|
457
1140
|
private startTime;
|
|
458
1141
|
private name;
|
|
459
1142
|
private frames;
|
|
460
1143
|
private started;
|
|
461
1144
|
private frame;
|
|
1145
|
+
/**
|
|
1146
|
+
* Records animation frames to calculate frame rate.
|
|
1147
|
+
* Called automatically during performance tracking.
|
|
1148
|
+
*/
|
|
462
1149
|
recordFrame: () => void;
|
|
1150
|
+
/**
|
|
1151
|
+
* Starts performance tracking for a named operation.
|
|
1152
|
+
*
|
|
1153
|
+
* @param name - A descriptive name for the operation being tracked
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
* ```ts
|
|
1157
|
+
* tracker.start('canvas-render')
|
|
1158
|
+
* // ... perform rendering operations
|
|
1159
|
+
* tracker.stop()
|
|
1160
|
+
* ```
|
|
1161
|
+
*/
|
|
463
1162
|
start(name: string): void;
|
|
1163
|
+
/**
|
|
1164
|
+
* Stops performance tracking and logs results to the console.
|
|
1165
|
+
*
|
|
1166
|
+
* Displays the operation name, frame rate, and uses color coding:
|
|
1167
|
+
* - Green background: \> 55 FPS (good performance)
|
|
1168
|
+
* - Yellow background: 30-55 FPS (moderate performance)
|
|
1169
|
+
* - Red background: \< 30 FPS (poor performance)
|
|
1170
|
+
*
|
|
1171
|
+
* @example
|
|
1172
|
+
* ```ts
|
|
1173
|
+
* tracker.start('interaction')
|
|
1174
|
+
* handleUserInteraction()
|
|
1175
|
+
* tracker.stop() // Logs: "Perf Interaction 60 fps"
|
|
1176
|
+
* ```
|
|
1177
|
+
*/
|
|
464
1178
|
stop(): void;
|
|
1179
|
+
/**
|
|
1180
|
+
* Checks whether performance tracking is currently active.
|
|
1181
|
+
*
|
|
1182
|
+
* @returns True if tracking is in progress, false otherwise
|
|
1183
|
+
*
|
|
1184
|
+
* @example
|
|
1185
|
+
* ```ts
|
|
1186
|
+
* if (!tracker.isStarted()) {
|
|
1187
|
+
* tracker.start('new-operation')
|
|
1188
|
+
* }
|
|
1189
|
+
* ```
|
|
1190
|
+
*/
|
|
465
1191
|
isStarted(): boolean;
|
|
466
1192
|
}
|
|
467
1193
|
|
|
468
|
-
/**
|
|
1194
|
+
/**
|
|
1195
|
+
* Utility class for reading and manipulating PNG image files.
|
|
1196
|
+
* Provides methods for parsing PNG chunks, validating PNG format, and modifying PNG metadata.
|
|
1197
|
+
*
|
|
1198
|
+
* @example
|
|
1199
|
+
* ```ts
|
|
1200
|
+
* // Validate PNG file from blob
|
|
1201
|
+
* const blob = new Blob([pngData], { type: 'image/png' })
|
|
1202
|
+
* const view = new DataView(await blob.arrayBuffer())
|
|
1203
|
+
* const isPng = PngHelpers.isPng(view, 0)
|
|
1204
|
+
*
|
|
1205
|
+
* // Parse PNG metadata for image processing
|
|
1206
|
+
* const chunks = PngHelpers.readChunks(view)
|
|
1207
|
+
* const physChunk = PngHelpers.findChunk(view, 'pHYs')
|
|
1208
|
+
*
|
|
1209
|
+
* // Create high-DPI PNG for export
|
|
1210
|
+
* const highDpiBlob = PngHelpers.setPhysChunk(view, 2, { type: 'image/png' })
|
|
1211
|
+
* ```
|
|
1212
|
+
*
|
|
1213
|
+
* @public
|
|
1214
|
+
*/
|
|
469
1215
|
export declare class PngHelpers {
|
|
1216
|
+
/**
|
|
1217
|
+
* Checks if binary data at the specified offset contains a valid PNG file signature.
|
|
1218
|
+
* Validates the 8-byte PNG signature: 89 50 4E 47 0D 0A 1A 0A.
|
|
1219
|
+
*
|
|
1220
|
+
* @param view - DataView containing the binary data to check
|
|
1221
|
+
* @param offset - Byte offset where the PNG signature should start
|
|
1222
|
+
* @returns True if the data contains a valid PNG signature, false otherwise
|
|
1223
|
+
*
|
|
1224
|
+
* @example
|
|
1225
|
+
* ```ts
|
|
1226
|
+
* // Validate PNG from file upload
|
|
1227
|
+
* const file = event.target.files[0]
|
|
1228
|
+
* const buffer = await file.arrayBuffer()
|
|
1229
|
+
* const view = new DataView(buffer)
|
|
1230
|
+
*
|
|
1231
|
+
* if (PngHelpers.isPng(view, 0)) {
|
|
1232
|
+
* console.log('Valid PNG file detected')
|
|
1233
|
+
* // Process PNG file...
|
|
1234
|
+
* } else {
|
|
1235
|
+
* console.error('Not a valid PNG file')
|
|
1236
|
+
* }
|
|
1237
|
+
* ```
|
|
1238
|
+
*/
|
|
470
1239
|
static isPng(view: DataView, offset: number): boolean;
|
|
1240
|
+
/**
|
|
1241
|
+
* Reads the 4-character chunk type identifier from a PNG chunk header.
|
|
1242
|
+
*
|
|
1243
|
+
* @param view - DataView containing the PNG data
|
|
1244
|
+
* @param offset - Byte offset of the chunk type field (after length field)
|
|
1245
|
+
* @returns 4-character string representing the chunk type (e.g., 'IHDR', 'IDAT', 'IEND')
|
|
1246
|
+
*
|
|
1247
|
+
* @example
|
|
1248
|
+
* ```ts
|
|
1249
|
+
* // Read chunk type from PNG header (after 8-byte signature)
|
|
1250
|
+
* const chunkType = PngHelpers.getChunkType(dataView, 8)
|
|
1251
|
+
* console.log(chunkType) // 'IHDR' (Image Header)
|
|
1252
|
+
*
|
|
1253
|
+
* // Read chunk type at a specific position during parsing
|
|
1254
|
+
* let offset = 8 // Skip PNG signature
|
|
1255
|
+
* const chunkLength = dataView.getUint32(offset)
|
|
1256
|
+
* const type = PngHelpers.getChunkType(dataView, offset + 4)
|
|
1257
|
+
* ```
|
|
1258
|
+
*/
|
|
471
1259
|
static getChunkType(view: DataView, offset: number): string;
|
|
1260
|
+
/**
|
|
1261
|
+
* Parses all chunks in a PNG file and returns their metadata.
|
|
1262
|
+
* Skips duplicate IDAT chunks but includes all other chunk types.
|
|
1263
|
+
*
|
|
1264
|
+
* @param view - DataView containing the complete PNG file data
|
|
1265
|
+
* @param offset - Starting byte offset (defaults to 0)
|
|
1266
|
+
* @returns Record mapping chunk types to their metadata (start position, data offset, and size)
|
|
1267
|
+
* @throws Error if the data is not a valid PNG file
|
|
1268
|
+
*
|
|
1269
|
+
* @example
|
|
1270
|
+
* ```ts
|
|
1271
|
+
* // Parse PNG structure for metadata extraction
|
|
1272
|
+
* const view = new DataView(await blob.arrayBuffer())
|
|
1273
|
+
* const chunks = PngHelpers.readChunks(view)
|
|
1274
|
+
*
|
|
1275
|
+
* // Check for specific chunks
|
|
1276
|
+
* const ihdrChunk = chunks['IHDR']
|
|
1277
|
+
* const physChunk = chunks['pHYs']
|
|
1278
|
+
*
|
|
1279
|
+
* if (physChunk) {
|
|
1280
|
+
* console.log(`Found pixel density info at byte ${physChunk.start}`)
|
|
1281
|
+
* } else {
|
|
1282
|
+
* console.log('No pixel density information found')
|
|
1283
|
+
* }
|
|
1284
|
+
* ```
|
|
1285
|
+
*/
|
|
472
1286
|
static readChunks(view: DataView, offset?: number): Record<string, {
|
|
473
1287
|
dataOffset: number;
|
|
474
1288
|
size: number;
|
|
475
1289
|
start: number;
|
|
476
1290
|
}>;
|
|
1291
|
+
/**
|
|
1292
|
+
* Parses the pHYs (physical pixel dimensions) chunk data.
|
|
1293
|
+
* Reads pixels per unit for X and Y axes, and the unit specifier.
|
|
1294
|
+
*
|
|
1295
|
+
* @param view - DataView containing the PNG data
|
|
1296
|
+
* @param offset - Byte offset of the pHYs chunk data
|
|
1297
|
+
* @returns Object with ppux (pixels per unit X), ppuy (pixels per unit Y), and unit specifier
|
|
1298
|
+
*
|
|
1299
|
+
* @example
|
|
1300
|
+
* ```ts
|
|
1301
|
+
* // Extract pixel density information for DPI calculation
|
|
1302
|
+
* const physChunk = PngHelpers.findChunk(dataView, 'pHYs')
|
|
1303
|
+
* if (physChunk) {
|
|
1304
|
+
* const physData = PngHelpers.parsePhys(dataView, physChunk.dataOffset)
|
|
1305
|
+
*
|
|
1306
|
+
* if (physData.unit === 1) { // meters
|
|
1307
|
+
* const dpiX = Math.round(physData.ppux * 0.0254)
|
|
1308
|
+
* const dpiY = Math.round(physData.ppuy * 0.0254)
|
|
1309
|
+
* console.log(`DPI: ${dpiX} x ${dpiY}`)
|
|
1310
|
+
* }
|
|
1311
|
+
* }
|
|
1312
|
+
* ```
|
|
1313
|
+
*/
|
|
477
1314
|
static parsePhys(view: DataView, offset: number): {
|
|
478
1315
|
ppux: number;
|
|
479
1316
|
ppuy: number;
|
|
480
1317
|
unit: number;
|
|
481
1318
|
};
|
|
1319
|
+
/**
|
|
1320
|
+
* Finds a specific chunk type in the PNG file and returns its metadata.
|
|
1321
|
+
*
|
|
1322
|
+
* @param view - DataView containing the PNG file data
|
|
1323
|
+
* @param type - 4-character chunk type to search for (e.g., 'pHYs', 'IDAT')
|
|
1324
|
+
* @returns Chunk metadata object if found, undefined otherwise
|
|
1325
|
+
*
|
|
1326
|
+
* @example
|
|
1327
|
+
* ```ts
|
|
1328
|
+
* // Look for pixel density information in PNG
|
|
1329
|
+
* const physChunk = PngHelpers.findChunk(dataView, 'pHYs')
|
|
1330
|
+
* if (physChunk) {
|
|
1331
|
+
* const physData = PngHelpers.parsePhys(dataView, physChunk.dataOffset)
|
|
1332
|
+
* console.log(`Found pHYs chunk with ${physData.ppux} x ${physData.ppuy} pixels per unit`)
|
|
1333
|
+
* }
|
|
1334
|
+
*
|
|
1335
|
+
* // Check for text metadata
|
|
1336
|
+
* const textChunk = PngHelpers.findChunk(dataView, 'tEXt')
|
|
1337
|
+
* if (textChunk) {
|
|
1338
|
+
* console.log(`Found text metadata at byte ${textChunk.start}`)
|
|
1339
|
+
* }
|
|
1340
|
+
* ```
|
|
1341
|
+
*/
|
|
482
1342
|
static findChunk(view: DataView, type: string): {
|
|
483
1343
|
dataOffset: number;
|
|
484
1344
|
size: number;
|
|
485
1345
|
start: number;
|
|
486
1346
|
};
|
|
1347
|
+
/**
|
|
1348
|
+
* Adds or replaces a pHYs chunk in a PNG file to set pixel density for high-DPI displays.
|
|
1349
|
+
* The method determines insertion point by prioritizing IDAT chunk position over existing pHYs,
|
|
1350
|
+
* creates a properly formatted pHYs chunk with CRC validation, and returns a new Blob.
|
|
1351
|
+
*
|
|
1352
|
+
* @param view - DataView containing the original PNG file data
|
|
1353
|
+
* @param dpr - Device pixel ratio multiplier (defaults to 1)
|
|
1354
|
+
* @param options - Optional Blob constructor options for MIME type and other properties
|
|
1355
|
+
* @returns New Blob containing the PNG with updated pixel density information
|
|
1356
|
+
*
|
|
1357
|
+
* @example
|
|
1358
|
+
* ```ts
|
|
1359
|
+
* // Export PNG with proper pixel density for high-DPI displays
|
|
1360
|
+
* const canvas = document.createElement('canvas')
|
|
1361
|
+
* const ctx = canvas.getContext('2d')
|
|
1362
|
+
* // ... draw content to canvas ...
|
|
1363
|
+
*
|
|
1364
|
+
* canvas.toBlob(async (blob) => {
|
|
1365
|
+
* if (blob) {
|
|
1366
|
+
* const view = new DataView(await blob.arrayBuffer())
|
|
1367
|
+
* // Create 2x DPI version for Retina displays
|
|
1368
|
+
* const highDpiBlob = PngHelpers.setPhysChunk(view, 2, { type: 'image/png' })
|
|
1369
|
+
* // Download or use the blob...
|
|
1370
|
+
* }
|
|
1371
|
+
* }, 'image/png')
|
|
1372
|
+
* ```
|
|
1373
|
+
*/
|
|
487
1374
|
static setPhysChunk(view: DataView, dpr?: number, options?: BlobPropertyBag): Blob;
|
|
488
1375
|
}
|
|
489
1376
|
|
|
490
1377
|
/* Excluded from this release type: promiseWithResolve */
|
|
491
1378
|
|
|
492
|
-
/**
|
|
1379
|
+
/**
|
|
1380
|
+
* Makes all properties in a type and all nested properties optional recursively.
|
|
1381
|
+
* This is useful for creating partial update objects where you only want to specify
|
|
1382
|
+
* some deeply nested properties while leaving others unchanged.
|
|
1383
|
+
*
|
|
1384
|
+
* @example
|
|
1385
|
+
* ```ts
|
|
1386
|
+
* interface User {
|
|
1387
|
+
* name: string
|
|
1388
|
+
* settings: {
|
|
1389
|
+
* theme: string
|
|
1390
|
+
* notifications: {
|
|
1391
|
+
* email: boolean
|
|
1392
|
+
* push: boolean
|
|
1393
|
+
* }
|
|
1394
|
+
* }
|
|
1395
|
+
* }
|
|
1396
|
+
*
|
|
1397
|
+
* type PartialUser = RecursivePartial<User>
|
|
1398
|
+
* // Result: {
|
|
1399
|
+
* // name?: string
|
|
1400
|
+
* // settings?: {
|
|
1401
|
+
* // theme?: string
|
|
1402
|
+
* // notifications?: {
|
|
1403
|
+
* // email?: boolean
|
|
1404
|
+
* // push?: boolean
|
|
1405
|
+
* // }
|
|
1406
|
+
* // }
|
|
1407
|
+
* // }
|
|
1408
|
+
*
|
|
1409
|
+
* const update: PartialUser = {
|
|
1410
|
+
* settings: {
|
|
1411
|
+
* notifications: {
|
|
1412
|
+
* email: false
|
|
1413
|
+
* }
|
|
1414
|
+
* }
|
|
1415
|
+
* }
|
|
1416
|
+
* ```
|
|
1417
|
+
*
|
|
1418
|
+
* @public
|
|
1419
|
+
*/
|
|
493
1420
|
export declare type RecursivePartial<T> = {
|
|
494
1421
|
[P in keyof T]?: RecursivePartial<T[P]>;
|
|
495
1422
|
};
|
|
@@ -500,12 +1427,65 @@ export declare type RecursivePartial<T> = {
|
|
|
500
1427
|
|
|
501
1428
|
/* Excluded from this release type: restoreUniqueId */
|
|
502
1429
|
|
|
503
|
-
/**
|
|
1430
|
+
/**
|
|
1431
|
+
* A discriminated union type for handling success and error cases.
|
|
1432
|
+
*
|
|
1433
|
+
* Represents either a successful result with a value or a failed result with an error.
|
|
1434
|
+
* This pattern provides type-safe error handling without throwing exceptions. The 'ok' property
|
|
1435
|
+
* serves as the discriminant for type narrowing.
|
|
1436
|
+
*
|
|
1437
|
+
* @example
|
|
1438
|
+
* ```ts
|
|
1439
|
+
* function divide(a: number, b: number): Result<number, string> {
|
|
1440
|
+
* if (b === 0) {
|
|
1441
|
+
* return Result.err('Division by zero')
|
|
1442
|
+
* }
|
|
1443
|
+
* return Result.ok(a / b)
|
|
1444
|
+
* }
|
|
1445
|
+
*
|
|
1446
|
+
* const result = divide(10, 2)
|
|
1447
|
+
* if (result.ok) {
|
|
1448
|
+
* console.log(`Result: ${result.value}`) // Result: 5
|
|
1449
|
+
* } else {
|
|
1450
|
+
* console.error(`Error: ${result.error}`)
|
|
1451
|
+
* }
|
|
1452
|
+
* ```
|
|
1453
|
+
* @public
|
|
1454
|
+
*/
|
|
504
1455
|
export declare type Result<T, E> = ErrorResult<E> | OkResult<T>;
|
|
505
1456
|
|
|
506
|
-
/**
|
|
1457
|
+
/**
|
|
1458
|
+
* Utility object for creating Result instances.
|
|
1459
|
+
*
|
|
1460
|
+
* Provides factory methods for creating OkResult and ErrorResult instances.
|
|
1461
|
+
* This is the preferred way to construct Result values for consistent structure.
|
|
1462
|
+
*
|
|
1463
|
+
* @example
|
|
1464
|
+
* ```ts
|
|
1465
|
+
* // Create success result
|
|
1466
|
+
* const success = Result.ok(42)
|
|
1467
|
+
* // success: OkResult<number> = { ok: true, value: 42 }
|
|
1468
|
+
*
|
|
1469
|
+
* // Create error result
|
|
1470
|
+
* const failure = Result.err('Invalid input')
|
|
1471
|
+
* // failure: ErrorResult<string> = { ok: false, error: 'Invalid input' }
|
|
1472
|
+
* ```
|
|
1473
|
+
* @public
|
|
1474
|
+
*/
|
|
507
1475
|
export declare const Result: {
|
|
1476
|
+
/**
|
|
1477
|
+
* Create a failed result containing an error.
|
|
1478
|
+
*
|
|
1479
|
+
* @param error - The error value to wrap
|
|
1480
|
+
* @returns An ErrorResult containing the error
|
|
1481
|
+
*/
|
|
508
1482
|
err<E>(error: E): ErrorResult<E>;
|
|
1483
|
+
/**
|
|
1484
|
+
* Create a successful result containing a value.
|
|
1485
|
+
*
|
|
1486
|
+
* @param value - The success value to wrap
|
|
1487
|
+
* @returns An OkResult containing the value
|
|
1488
|
+
*/
|
|
509
1489
|
ok<T>(value: T): OkResult<T>;
|
|
510
1490
|
};
|
|
511
1491
|
|
|
@@ -513,22 +1493,87 @@ export declare const Result: {
|
|
|
513
1493
|
|
|
514
1494
|
/**
|
|
515
1495
|
* Seeded random number generator, using [xorshift](https://en.wikipedia.org/wiki/Xorshift). The
|
|
516
|
-
* result will always be
|
|
1496
|
+
* result will always be between -1 and 1.
|
|
517
1497
|
*
|
|
518
1498
|
* Adapted from [seedrandom](https://github.com/davidbau/seedrandom).
|
|
519
1499
|
*
|
|
1500
|
+
* @param seed - The seed string for deterministic random generation (defaults to empty string)
|
|
1501
|
+
* @returns A function that will return a random number between -1 and 1 each time it is called
|
|
1502
|
+
* @example
|
|
1503
|
+
* ```ts
|
|
1504
|
+
* const random = rng('my-seed')
|
|
1505
|
+
* const num1 = random() // Always the same for this seed
|
|
1506
|
+
* const num2 = random() // Next number in sequence
|
|
1507
|
+
*
|
|
1508
|
+
* // Different seed produces different sequence
|
|
1509
|
+
* const otherRandom = rng('other-seed')
|
|
1510
|
+
* const different = otherRandom() // Different value
|
|
1511
|
+
* ```
|
|
520
1512
|
* @public
|
|
521
1513
|
*/
|
|
522
1514
|
export declare function rng(seed?: string): () => number;
|
|
523
1515
|
|
|
524
1516
|
/**
|
|
525
|
-
* Rotate the contents of an array.
|
|
1517
|
+
* Rotate the contents of an array by a specified offset.
|
|
1518
|
+
*
|
|
1519
|
+
* Creates a new array with elements shifted to the left by the specified number of positions.
|
|
1520
|
+
* Both positive and negative offsets result in left shifts (elements move left, with elements
|
|
1521
|
+
* from the front wrapping to the back).
|
|
1522
|
+
*
|
|
1523
|
+
* @param arr - The array to rotate
|
|
1524
|
+
* @param offset - The number of positions to shift left (both positive and negative values shift left)
|
|
1525
|
+
* @returns A new array with elements shifted left by the specified offset
|
|
526
1526
|
*
|
|
1527
|
+
* @example
|
|
1528
|
+
* ```ts
|
|
1529
|
+
* rotateArray([1, 2, 3, 4], 1) // [2, 3, 4, 1]
|
|
1530
|
+
* rotateArray([1, 2, 3, 4], -1) // [2, 3, 4, 1]
|
|
1531
|
+
* rotateArray(['a', 'b', 'c'], 2) // ['c', 'a', 'b']
|
|
1532
|
+
* ```
|
|
527
1533
|
* @public
|
|
528
1534
|
*/
|
|
529
1535
|
export declare function rotateArray<T>(arr: T[], offset: number): T[];
|
|
530
1536
|
|
|
531
|
-
/**
|
|
1537
|
+
/**
|
|
1538
|
+
* Safely parses a URL string without throwing exceptions on invalid input.
|
|
1539
|
+
* Returns a URL object for valid URLs or undefined for invalid ones.
|
|
1540
|
+
*
|
|
1541
|
+
* @param url - The URL string to parse
|
|
1542
|
+
* @param baseUrl - Optional base URL to resolve relative URLs against
|
|
1543
|
+
* @returns A URL object if parsing succeeds, undefined if it fails
|
|
1544
|
+
*
|
|
1545
|
+
* @example
|
|
1546
|
+
* ```ts
|
|
1547
|
+
* // Valid absolute URL
|
|
1548
|
+
* const url1 = safeParseUrl('https://example.com')
|
|
1549
|
+
* if (url1) {
|
|
1550
|
+
* console.log(`Valid URL: ${url1.href}`) // "Valid URL: https://example.com/"
|
|
1551
|
+
* }
|
|
1552
|
+
*
|
|
1553
|
+
* // Invalid URL
|
|
1554
|
+
* const url2 = safeParseUrl('not-a-url')
|
|
1555
|
+
* console.log(url2) // undefined
|
|
1556
|
+
*
|
|
1557
|
+
* // Relative URL with base
|
|
1558
|
+
* const url3 = safeParseUrl('/path', 'https://example.com')
|
|
1559
|
+
* if (url3) {
|
|
1560
|
+
* console.log(url3.href) // "https://example.com/path"
|
|
1561
|
+
* }
|
|
1562
|
+
*
|
|
1563
|
+
* // Error handling
|
|
1564
|
+
* function handleUserUrl(input: string) {
|
|
1565
|
+
* const url = safeParseUrl(input)
|
|
1566
|
+
* if (url) {
|
|
1567
|
+
* return url
|
|
1568
|
+
* } else {
|
|
1569
|
+
* console.log('Invalid URL provided')
|
|
1570
|
+
* return null
|
|
1571
|
+
* }
|
|
1572
|
+
* }
|
|
1573
|
+
* ```
|
|
1574
|
+
*
|
|
1575
|
+
* @public
|
|
1576
|
+
*/
|
|
532
1577
|
export declare const safeParseUrl: (url: string, baseUrl?: string | URL) => undefined | URL;
|
|
533
1578
|
|
|
534
1579
|
/* Excluded from this release type: setInLocalStorage */
|
|
@@ -537,7 +1582,28 @@ export declare const safeParseUrl: (url: string, baseUrl?: string | URL) => unde
|
|
|
537
1582
|
|
|
538
1583
|
/* Excluded from this release type: sleep */
|
|
539
1584
|
|
|
540
|
-
/**
|
|
1585
|
+
/**
|
|
1586
|
+
* Compares two objects by their id property for use with Array.sort().
|
|
1587
|
+
* Sorts objects in ascending order based on their id values.
|
|
1588
|
+
*
|
|
1589
|
+
* @param a - First object to compare
|
|
1590
|
+
* @param b - Second object to compare
|
|
1591
|
+
* @returns 1 if a.id \> b.id, -1 if a.id \<= b.id
|
|
1592
|
+
*
|
|
1593
|
+
* @example
|
|
1594
|
+
* ```ts
|
|
1595
|
+
* const items = [
|
|
1596
|
+
* { id: 'c', name: 'Charlie' },
|
|
1597
|
+
* { id: 'a', name: 'Alice' },
|
|
1598
|
+
* { id: 'b', name: 'Bob' },
|
|
1599
|
+
* ]
|
|
1600
|
+
*
|
|
1601
|
+
* const sorted = items.sort(sortById)
|
|
1602
|
+
* // [{ id: 'a', name: 'Alice' }, { id: 'b', name: 'Bob' }, { id: 'c', name: 'Charlie' }]
|
|
1603
|
+
* ```
|
|
1604
|
+
*
|
|
1605
|
+
* @public
|
|
1606
|
+
*/
|
|
541
1607
|
export declare function sortById<T extends {
|
|
542
1608
|
id: any;
|
|
543
1609
|
}>(a: T, b: T): -1 | 1;
|
|
@@ -546,7 +1612,18 @@ export declare function sortById<T extends {
|
|
|
546
1612
|
* Sort by index.
|
|
547
1613
|
* @param a - An object with an index property.
|
|
548
1614
|
* @param b - An object with an index property.
|
|
549
|
-
* @
|
|
1615
|
+
* @returns A number indicating sort order (-1, 0, or 1).
|
|
1616
|
+
* @example
|
|
1617
|
+
* ```ts
|
|
1618
|
+
* const shapes = [
|
|
1619
|
+
* { id: 'b', index: 'a2' as IndexKey },
|
|
1620
|
+
* { id: 'a', index: 'a1' as IndexKey }
|
|
1621
|
+
* ]
|
|
1622
|
+
* const sorted = shapes.sort(sortByIndex)
|
|
1623
|
+
* console.log(sorted) // [{ id: 'a', index: 'a1' }, { id: 'b', index: 'a2' }]
|
|
1624
|
+
* ```
|
|
1625
|
+
* @public
|
|
1626
|
+
*/
|
|
550
1627
|
export declare function sortByIndex<T extends {
|
|
551
1628
|
index: IndexKey;
|
|
552
1629
|
}>(a: T, b: T): -1 | 0 | 1;
|
|
@@ -559,7 +1636,26 @@ export declare function sortByIndex<T extends {
|
|
|
559
1636
|
* Create a deep copy of a value. Uses the structuredClone API if available, otherwise uses JSON.parse(JSON.stringify()).
|
|
560
1637
|
*
|
|
561
1638
|
* @param i - The value to clone.
|
|
562
|
-
* @
|
|
1639
|
+
* @returns A deep copy of the input value.
|
|
1640
|
+
* @example
|
|
1641
|
+
* ```ts
|
|
1642
|
+
* const original = { a: 1, b: { c: 2 } }
|
|
1643
|
+
* const copy = structuredClone(original)
|
|
1644
|
+
*
|
|
1645
|
+
* copy.b.c = 3
|
|
1646
|
+
* console.log(original.b.c) // 2 (unchanged)
|
|
1647
|
+
* console.log(copy.b.c) // 3
|
|
1648
|
+
*
|
|
1649
|
+
* // Works with complex objects
|
|
1650
|
+
* const complexObject = {
|
|
1651
|
+
* date: new Date(),
|
|
1652
|
+
* array: [1, 2, 3],
|
|
1653
|
+
* nested: { deep: { value: "test" } }
|
|
1654
|
+
* }
|
|
1655
|
+
* const cloned = structuredClone(complexObject)
|
|
1656
|
+
* ```
|
|
1657
|
+
* @public
|
|
1658
|
+
*/
|
|
563
1659
|
declare const structuredClone_2: <T>(i: T) => T;
|
|
564
1660
|
export { structuredClone_2 as structuredClone }
|
|
565
1661
|
|
|
@@ -567,21 +1663,140 @@ export { throttle }
|
|
|
567
1663
|
|
|
568
1664
|
/* Excluded from this release type: throttleToNextFrame */
|
|
569
1665
|
|
|
570
|
-
/**
|
|
1666
|
+
/**
|
|
1667
|
+
* A utility class for managing timeouts, intervals, and animation frames with context-based organization and automatic cleanup.
|
|
1668
|
+
* Helps prevent memory leaks by organizing timers into named contexts that can be cleared together.
|
|
1669
|
+
* @example
|
|
1670
|
+
* ```ts
|
|
1671
|
+
* const timers = new Timers()
|
|
1672
|
+
*
|
|
1673
|
+
* // Set timers with context organization
|
|
1674
|
+
* timers.setTimeout('ui', () => console.log('Auto save'), 5000)
|
|
1675
|
+
* timers.setInterval('ui', () => console.log('Refresh'), 1000)
|
|
1676
|
+
* timers.requestAnimationFrame('ui', () => console.log('Render'))
|
|
1677
|
+
*
|
|
1678
|
+
* // Clear all timers for a context
|
|
1679
|
+
* timers.dispose('ui')
|
|
1680
|
+
*
|
|
1681
|
+
* // Or get context-bound functions
|
|
1682
|
+
* const uiTimers = timers.forContext('ui')
|
|
1683
|
+
* uiTimers.setTimeout(() => console.log('Contextual timeout'), 1000)
|
|
1684
|
+
* ```
|
|
1685
|
+
* @public
|
|
1686
|
+
*/
|
|
571
1687
|
export declare class Timers {
|
|
572
1688
|
private timeouts;
|
|
573
1689
|
private intervals;
|
|
574
1690
|
private rafs;
|
|
1691
|
+
/**
|
|
1692
|
+
* Creates a new Timers instance with bound methods for safe callback usage.
|
|
1693
|
+
* @example
|
|
1694
|
+
* ```ts
|
|
1695
|
+
* const timers = new Timers()
|
|
1696
|
+
* // Methods are pre-bound, safe to use as callbacks
|
|
1697
|
+
* element.addEventListener('click', timers.dispose)
|
|
1698
|
+
* ```
|
|
1699
|
+
*/
|
|
575
1700
|
constructor();
|
|
576
|
-
/**
|
|
1701
|
+
/**
|
|
1702
|
+
* Creates a timeout that will be tracked under the specified context.
|
|
1703
|
+
* @param contextId - The context identifier to group this timer under.
|
|
1704
|
+
* @param handler - The function to execute when the timeout expires.
|
|
1705
|
+
* @param timeout - The delay in milliseconds (default: 0).
|
|
1706
|
+
* @param args - Additional arguments to pass to the handler.
|
|
1707
|
+
* @returns The timer ID that can be used with clearTimeout.
|
|
1708
|
+
* @example
|
|
1709
|
+
* ```ts
|
|
1710
|
+
* const timers = new Timers()
|
|
1711
|
+
* const id = timers.setTimeout('autosave', () => save(), 5000)
|
|
1712
|
+
* // Timer will be automatically cleared when 'autosave' context is disposed
|
|
1713
|
+
* ```
|
|
1714
|
+
* @public
|
|
1715
|
+
*/
|
|
577
1716
|
setTimeout(contextId: string, handler: TimerHandler, timeout?: number, ...args: any[]): number;
|
|
578
|
-
/**
|
|
1717
|
+
/**
|
|
1718
|
+
* Creates an interval that will be tracked under the specified context.
|
|
1719
|
+
* @param contextId - The context identifier to group this timer under.
|
|
1720
|
+
* @param handler - The function to execute repeatedly.
|
|
1721
|
+
* @param timeout - The delay in milliseconds between executions (default: 0).
|
|
1722
|
+
* @param args - Additional arguments to pass to the handler.
|
|
1723
|
+
* @returns The interval ID that can be used with clearInterval.
|
|
1724
|
+
* @example
|
|
1725
|
+
* ```ts
|
|
1726
|
+
* const timers = new Timers()
|
|
1727
|
+
* const id = timers.setInterval('refresh', () => updateData(), 1000)
|
|
1728
|
+
* // Interval will be automatically cleared when 'refresh' context is disposed
|
|
1729
|
+
* ```
|
|
1730
|
+
* @public
|
|
1731
|
+
*/
|
|
579
1732
|
setInterval(contextId: string, handler: TimerHandler, timeout?: number, ...args: any[]): number;
|
|
580
|
-
/**
|
|
1733
|
+
/**
|
|
1734
|
+
* Requests an animation frame that will be tracked under the specified context.
|
|
1735
|
+
* @param contextId - The context identifier to group this animation frame under.
|
|
1736
|
+
* @param callback - The function to execute on the next animation frame.
|
|
1737
|
+
* @returns The request ID that can be used with cancelAnimationFrame.
|
|
1738
|
+
* @example
|
|
1739
|
+
* ```ts
|
|
1740
|
+
* const timers = new Timers()
|
|
1741
|
+
* const id = timers.requestAnimationFrame('render', () => draw())
|
|
1742
|
+
* // Animation frame will be automatically cancelled when 'render' context is disposed
|
|
1743
|
+
* ```
|
|
1744
|
+
* @public
|
|
1745
|
+
*/
|
|
581
1746
|
requestAnimationFrame(contextId: string, callback: FrameRequestCallback): number;
|
|
582
|
-
/**
|
|
1747
|
+
/**
|
|
1748
|
+
* Disposes of all timers associated with the specified context.
|
|
1749
|
+
* Clears all timeouts, intervals, and animation frames for the given context ID.
|
|
1750
|
+
* @param contextId - The context identifier whose timers should be cleared.
|
|
1751
|
+
* @returns void
|
|
1752
|
+
* @example
|
|
1753
|
+
* ```ts
|
|
1754
|
+
* const timers = new Timers()
|
|
1755
|
+
* timers.setTimeout('ui', () => console.log('timeout'), 1000)
|
|
1756
|
+
* timers.setInterval('ui', () => console.log('interval'), 500)
|
|
1757
|
+
*
|
|
1758
|
+
* // Clear all 'ui' context timers
|
|
1759
|
+
* timers.dispose('ui')
|
|
1760
|
+
* ```
|
|
1761
|
+
* @public
|
|
1762
|
+
*/
|
|
583
1763
|
dispose(contextId: string): void;
|
|
1764
|
+
/**
|
|
1765
|
+
* Disposes of all timers across all contexts.
|
|
1766
|
+
* Clears every timeout, interval, and animation frame managed by this instance.
|
|
1767
|
+
* @returns void
|
|
1768
|
+
* @example
|
|
1769
|
+
* ```ts
|
|
1770
|
+
* const timers = new Timers()
|
|
1771
|
+
* timers.setTimeout('ui', () => console.log('ui'), 1000)
|
|
1772
|
+
* timers.setTimeout('background', () => console.log('bg'), 2000)
|
|
1773
|
+
*
|
|
1774
|
+
* // Clear everything
|
|
1775
|
+
* timers.disposeAll()
|
|
1776
|
+
* ```
|
|
1777
|
+
* @public
|
|
1778
|
+
*/
|
|
584
1779
|
disposeAll(): void;
|
|
1780
|
+
/**
|
|
1781
|
+
* Returns an object with timer methods bound to a specific context.
|
|
1782
|
+
* Convenient for getting context-specific timer functions without repeatedly passing the contextId.
|
|
1783
|
+
* @param contextId - The context identifier to bind the returned methods to.
|
|
1784
|
+
* @returns An object with setTimeout, setInterval, requestAnimationFrame, and dispose methods bound to the context.
|
|
1785
|
+
* @example
|
|
1786
|
+
* ```ts
|
|
1787
|
+
* const timers = new Timers()
|
|
1788
|
+
* const uiTimers = timers.forContext('ui')
|
|
1789
|
+
*
|
|
1790
|
+
* // These are equivalent to calling timers.setTimeout('ui', ...)
|
|
1791
|
+
* uiTimers.setTimeout(() => console.log('timeout'), 1000)
|
|
1792
|
+
* uiTimers.setInterval(() => console.log('interval'), 500)
|
|
1793
|
+
* uiTimers.requestAnimationFrame(() => console.log('frame'))
|
|
1794
|
+
*
|
|
1795
|
+
* // Dispose only this context
|
|
1796
|
+
* uiTimers.dispose()
|
|
1797
|
+
* ```
|
|
1798
|
+
* @public
|
|
1799
|
+
*/
|
|
585
1800
|
forContext(contextId: string): {
|
|
586
1801
|
dispose: () => void;
|
|
587
1802
|
requestAnimationFrame: (callback: FrameRequestCallback) => number;
|
|
@@ -593,14 +1808,28 @@ export declare class Timers {
|
|
|
593
1808
|
export { uniq }
|
|
594
1809
|
|
|
595
1810
|
/**
|
|
596
|
-
* Generate a unique
|
|
1811
|
+
* Generate a unique ID using a modified nanoid algorithm.
|
|
597
1812
|
*
|
|
598
|
-
*
|
|
1813
|
+
* Generates a cryptographically secure random string ID using URL-safe characters.
|
|
1814
|
+
* The default size is 21 characters, which provides a good balance of uniqueness
|
|
1815
|
+
* and brevity. Uses the global crypto API for secure random number generation.
|
|
599
1816
|
*
|
|
1817
|
+
* @param size - Optional length of the generated ID (defaults to 21 characters)
|
|
1818
|
+
* @returns A unique string identifier
|
|
1819
|
+
* @example
|
|
600
1820
|
* ```ts
|
|
1821
|
+
* // Generate default 21-character ID
|
|
601
1822
|
* const id = uniqueId()
|
|
602
|
-
*
|
|
1823
|
+
* console.log(id) // 'V1StGXR8_Z5jdHi6B-myT'
|
|
603
1824
|
*
|
|
1825
|
+
* // Generate shorter ID
|
|
1826
|
+
* const shortId = uniqueId(10)
|
|
1827
|
+
* console.log(shortId) // 'V1StGXR8_Z'
|
|
1828
|
+
*
|
|
1829
|
+
* // Generate longer ID
|
|
1830
|
+
* const longId = uniqueId(32)
|
|
1831
|
+
* console.log(longId) // 'V1StGXR8_Z5jdHi6B-myTVKahvjdx...'
|
|
1832
|
+
* ```
|
|
604
1833
|
* @public
|
|
605
1834
|
*/
|
|
606
1835
|
export declare function uniqueId(size?: number): string;
|
|
@@ -612,18 +1841,59 @@ export declare function uniqueId(size?: number): string;
|
|
|
612
1841
|
/* Excluded from this release type: warnOnce */
|
|
613
1842
|
|
|
614
1843
|
/**
|
|
615
|
-
* A
|
|
1844
|
+
* A lightweight cache implementation using WeakMap for storing key-value pairs.
|
|
1845
|
+
*
|
|
1846
|
+
* A micro cache that stores computed values associated with object keys.
|
|
1847
|
+
* Uses WeakMap internally, which means keys can be garbage collected when no other
|
|
1848
|
+
* references exist, and only object keys are supported. Provides lazy computation
|
|
1849
|
+
* with memoization.
|
|
1850
|
+
*
|
|
1851
|
+
* @example
|
|
1852
|
+
* ```ts
|
|
1853
|
+
* const cache = new WeakCache<User, string>()
|
|
1854
|
+
* const user = { id: 1, name: 'Alice' }
|
|
1855
|
+
*
|
|
1856
|
+
* // Get cached value, computing it if not present
|
|
1857
|
+
* const displayName = cache.get(user, (u) => `${u.name} (#${u.id})`)
|
|
1858
|
+
* // Returns 'Alice (#1)'
|
|
1859
|
+
*
|
|
1860
|
+
* // Subsequent calls return cached value
|
|
1861
|
+
* const sameName = cache.get(user, (u) => `${u.name} (#${u.id})`)
|
|
1862
|
+
* // Returns 'Alice (#1)' without recomputing
|
|
1863
|
+
* ```
|
|
616
1864
|
* @public
|
|
617
1865
|
*/
|
|
618
1866
|
export declare class WeakCache<K extends object, V> {
|
|
619
|
-
/**
|
|
1867
|
+
/**
|
|
1868
|
+
* The internal WeakMap storage for cached key-value pairs.
|
|
1869
|
+
*
|
|
1870
|
+
* @public
|
|
1871
|
+
*/
|
|
620
1872
|
items: WeakMap<K, V>;
|
|
621
1873
|
/**
|
|
622
|
-
* Get the cached value for a given
|
|
623
|
-
*
|
|
1874
|
+
* Get the cached value for a given key, computing it if not already cached.
|
|
1875
|
+
*
|
|
1876
|
+
* Retrieves the cached value associated with the given key. If no cached
|
|
1877
|
+
* value exists, calls the provided callback function to compute the value, stores it
|
|
1878
|
+
* in the cache, and returns it. Subsequent calls with the same key will return the
|
|
1879
|
+
* cached value without recomputation.
|
|
1880
|
+
*
|
|
1881
|
+
* @param item - The object key to retrieve the cached value for
|
|
1882
|
+
* @param cb - Callback function that computes the value when not already cached
|
|
1883
|
+
* @returns The cached value if it exists, otherwise the newly computed value from the callback
|
|
624
1884
|
*
|
|
625
|
-
* @
|
|
626
|
-
*
|
|
1885
|
+
* @example
|
|
1886
|
+
* ```ts
|
|
1887
|
+
* const cache = new WeakCache<HTMLElement, DOMRect>()
|
|
1888
|
+
* const element = document.getElementById('my-element')!
|
|
1889
|
+
*
|
|
1890
|
+
* // First call computes and caches the bounding rect
|
|
1891
|
+
* const rect1 = cache.get(element, (el) => el.getBoundingClientRect())
|
|
1892
|
+
*
|
|
1893
|
+
* // Second call returns cached value
|
|
1894
|
+
* const rect2 = cache.get(element, (el) => el.getBoundingClientRect())
|
|
1895
|
+
* // rect1 and rect2 are the same object
|
|
1896
|
+
* ```
|
|
627
1897
|
*/
|
|
628
1898
|
get<P extends K>(item: P, cb: (item: P) => V): NonNullable<V>;
|
|
629
1899
|
}
|