@framesquared/core 0.1.0
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/LICENSE +21 -0
- package/dist/index.d.ts +1246 -0
- package/dist/index.js +3108 -0
- package/dist/index.js.map +1 -0
- package/package.json +23 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @framesquared/core – utility functions
|
|
3
|
+
*
|
|
4
|
+
* Pure, side-effect-free helpers (except timer wrappers and generateId).
|
|
5
|
+
* Every function is individually exported so tree-shaking works out of the box.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Returns the value unchanged. Useful as a default transform or callback.
|
|
9
|
+
*/
|
|
10
|
+
declare function identity<T>(value: T): T;
|
|
11
|
+
/**
|
|
12
|
+
* A reusable no-op function.
|
|
13
|
+
*/
|
|
14
|
+
declare function emptyFn(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Copies **own** enumerable properties from `source` to `target`,
|
|
17
|
+
* but only when the property does **not** already exist on `target`
|
|
18
|
+
* (checked via the `in` operator so even `undefined` values are preserved).
|
|
19
|
+
*
|
|
20
|
+
* Returns the mutated `target`.
|
|
21
|
+
*/
|
|
22
|
+
declare function applyIf<T extends object>(target: T, source: Partial<T>): T;
|
|
23
|
+
/**
|
|
24
|
+
* Copies **own** enumerable properties from every `source` to `target`,
|
|
25
|
+
* overwriting any existing values. Sources are applied left-to-right so
|
|
26
|
+
* later sources win.
|
|
27
|
+
*
|
|
28
|
+
* Returns the mutated `target`.
|
|
29
|
+
*/
|
|
30
|
+
declare function apply<T extends object>(target: T, ...sources: Partial<T>[]): T;
|
|
31
|
+
/**
|
|
32
|
+
* Deep-clones `value` using the platform's `structuredClone`.
|
|
33
|
+
*/
|
|
34
|
+
declare function clone<T>(value: T): T;
|
|
35
|
+
/**
|
|
36
|
+
* `true` for plain objects only — `{}`, `Object.create(null)`, and objects
|
|
37
|
+
* whose prototype is `Object.prototype`. Returns `false` for arrays,
|
|
38
|
+
* functions, `null`, class instances (`Date`, `RegExp`, …), and primitives.
|
|
39
|
+
*/
|
|
40
|
+
declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
41
|
+
/**
|
|
42
|
+
* `true` for primitive `string` values only (not `String` wrapper objects).
|
|
43
|
+
*/
|
|
44
|
+
declare function isString(value: unknown): value is string;
|
|
45
|
+
/**
|
|
46
|
+
* `true` for finite numbers and `±Infinity`. Explicitly **excludes** `NaN`.
|
|
47
|
+
*/
|
|
48
|
+
declare function isNumber(value: unknown): value is number;
|
|
49
|
+
/**
|
|
50
|
+
* `true` for primitive `boolean` values only (not `Boolean` wrapper objects).
|
|
51
|
+
*/
|
|
52
|
+
declare function isBoolean(value: unknown): value is boolean;
|
|
53
|
+
/**
|
|
54
|
+
* `true` for any callable — arrows, named functions, async functions,
|
|
55
|
+
* generators, and class constructors.
|
|
56
|
+
*/
|
|
57
|
+
declare function isFunction(value: unknown): value is Function;
|
|
58
|
+
/**
|
|
59
|
+
* Thin wrapper around `Array.isArray` with an `unknown[]` return type.
|
|
60
|
+
*/
|
|
61
|
+
declare function isArray(value: unknown): value is unknown[];
|
|
62
|
+
/**
|
|
63
|
+
* `true` when `value` is neither `undefined` nor `null`.
|
|
64
|
+
*/
|
|
65
|
+
declare function isDefined<T>(value: T | undefined | null): value is T;
|
|
66
|
+
/**
|
|
67
|
+
* `true` for values that are conceptually "empty":
|
|
68
|
+
* `undefined`, `null`, `''`, `[]`, `{}` (plain, no own keys), and `NaN`.
|
|
69
|
+
*/
|
|
70
|
+
declare function isEmpty(value: unknown): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* `true` when `value` implements the iterable protocol (`Symbol.iterator`).
|
|
73
|
+
* Returns `false` for `null`, `undefined`, and non-iterable objects.
|
|
74
|
+
*/
|
|
75
|
+
declare function isIterable(value: unknown): value is Iterable<unknown>;
|
|
76
|
+
/**
|
|
77
|
+
* `true` for all seven primitive types:
|
|
78
|
+
* `string`, `number`, `boolean`, `undefined`, `null`, `symbol`, and `bigint`.
|
|
79
|
+
*/
|
|
80
|
+
declare function isPrimitive(value: unknown): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Walks (and lazily creates) a dot-separated namespace on `root`.
|
|
83
|
+
*
|
|
84
|
+
* ```ts
|
|
85
|
+
* const root = {};
|
|
86
|
+
* namespace(root, 'a.b.c'); // root is now { a: { b: { c: {} } } }
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* Existing intermediate objects are preserved; only missing segments are
|
|
90
|
+
* created as empty plain objects. Returns the **leaf** object.
|
|
91
|
+
*/
|
|
92
|
+
declare function namespace(root: object, path: string): object;
|
|
93
|
+
/**
|
|
94
|
+
* Wrapper around `setTimeout` that returns the numeric timer id.
|
|
95
|
+
*/
|
|
96
|
+
declare function defer(fn: () => void, millis?: number): number;
|
|
97
|
+
/**
|
|
98
|
+
* Wrapper around `setInterval` that returns the numeric timer id.
|
|
99
|
+
*/
|
|
100
|
+
declare function interval(fn: () => void, millis: number): number;
|
|
101
|
+
/**
|
|
102
|
+
* High-resolution timestamp via `performance.now()`.
|
|
103
|
+
*/
|
|
104
|
+
declare function now(): number;
|
|
105
|
+
/**
|
|
106
|
+
* Generates a globally-unique ID string. The counter is monotonically
|
|
107
|
+
* increasing across all prefixes.
|
|
108
|
+
*
|
|
109
|
+
* ```ts
|
|
110
|
+
* generateId(); // "framesquared-1"
|
|
111
|
+
* generateId(); // "framesquared-2"
|
|
112
|
+
* generateId('widget'); // "widget-3"
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
declare function generateId(prefix?: string): string;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @framesquared/core – String utilities
|
|
119
|
+
*/
|
|
120
|
+
/**
|
|
121
|
+
* Capitalizes the first character of `str`.
|
|
122
|
+
*/
|
|
123
|
+
declare function capitalize(str: string): string;
|
|
124
|
+
/**
|
|
125
|
+
* Lowercases the first character of `str`.
|
|
126
|
+
*/
|
|
127
|
+
declare function uncapitalize(str: string): string;
|
|
128
|
+
/**
|
|
129
|
+
* Truncates `value` to `length` characters (including a trailing `"…"` when
|
|
130
|
+
* truncation occurs). When `word` is `true` the cut happens before the last
|
|
131
|
+
* whitespace boundary so words are not split mid-way.
|
|
132
|
+
*/
|
|
133
|
+
declare function ellipsis(value: string, length: number, word?: boolean): string;
|
|
134
|
+
/**
|
|
135
|
+
* Escapes `&`, `<`, `>`, `"`, and `'` to their HTML entity equivalents.
|
|
136
|
+
*/
|
|
137
|
+
declare function escapeHtml(str: string): string;
|
|
138
|
+
/**
|
|
139
|
+
* Reverses {@link escapeHtml}, converting HTML entities back to characters.
|
|
140
|
+
*/
|
|
141
|
+
declare function unescapeHtml(str: string): string;
|
|
142
|
+
/** Alias for {@link escapeHtml}. */
|
|
143
|
+
declare const htmlEncode: typeof escapeHtml;
|
|
144
|
+
/** Alias for {@link unescapeHtml}. */
|
|
145
|
+
declare const htmlDecode: typeof unescapeHtml;
|
|
146
|
+
/**
|
|
147
|
+
* Escapes all RegExp-special characters so the result can be used inside
|
|
148
|
+
* `new RegExp(...)` to match the literal string.
|
|
149
|
+
*/
|
|
150
|
+
declare function escapeRegex(str: string): string;
|
|
151
|
+
/**
|
|
152
|
+
* Replaces `{0}`, `{1}`, … placeholders in `template` with the
|
|
153
|
+
* corresponding positional values (converted via `String()`).
|
|
154
|
+
*/
|
|
155
|
+
declare function format(template: string, ...values: unknown[]): string;
|
|
156
|
+
/**
|
|
157
|
+
* Repeats `str` exactly `count` times.
|
|
158
|
+
*/
|
|
159
|
+
declare function repeat(str: string, count: number): string;
|
|
160
|
+
/**
|
|
161
|
+
* Trims leading and trailing whitespace.
|
|
162
|
+
*/
|
|
163
|
+
declare function trim(str: string): string;
|
|
164
|
+
/**
|
|
165
|
+
* Left-pads `str` to `size` characters using `char` (default `' '`).
|
|
166
|
+
* Only the first character of `char` is used.
|
|
167
|
+
*/
|
|
168
|
+
declare function leftPad(str: string, size: number, char?: string): string;
|
|
169
|
+
/**
|
|
170
|
+
* Returns `value2` when `str === value1`, otherwise returns `value1`.
|
|
171
|
+
*/
|
|
172
|
+
declare function toggle(str: string, value1: string, value2: string): string;
|
|
173
|
+
/**
|
|
174
|
+
* Splits a string into its constituent words, recognising camelCase,
|
|
175
|
+
* PascalCase, snake_case, and kebab-case boundaries.
|
|
176
|
+
*
|
|
177
|
+
* Consecutive uppercase letters are treated as a single acronym, e.g.
|
|
178
|
+
* `"parseHTMLString"` → `["parse", "HTML", "String"]`.
|
|
179
|
+
*/
|
|
180
|
+
declare function splitWords(str: string): string[];
|
|
181
|
+
/**
|
|
182
|
+
* Converts a string to `camelCase`.
|
|
183
|
+
*/
|
|
184
|
+
declare function camelCase(str: string): string;
|
|
185
|
+
/**
|
|
186
|
+
* Converts a string to `kebab-case`.
|
|
187
|
+
*/
|
|
188
|
+
declare function kebabCase(str: string): string;
|
|
189
|
+
/**
|
|
190
|
+
* Converts a string to `PascalCase`.
|
|
191
|
+
*/
|
|
192
|
+
declare function pascalCase(str: string): string;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @framesquared/core – Array utilities
|
|
196
|
+
*/
|
|
197
|
+
/**
|
|
198
|
+
* Normalizes a value to an array.
|
|
199
|
+
*
|
|
200
|
+
* - If already an array, returns it as-is (same reference).
|
|
201
|
+
* - If an iterable (but not a string), spreads it into a new array.
|
|
202
|
+
* - Otherwise wraps it in a single-element array.
|
|
203
|
+
*
|
|
204
|
+
* Strings are intentionally *not* spread into characters — `from("hi")`
|
|
205
|
+
* returns `["hi"]`, not `["h","i"]`.
|
|
206
|
+
*/
|
|
207
|
+
declare function from<T>(value: T | T[] | Iterable<T>): T[];
|
|
208
|
+
/**
|
|
209
|
+
* Returns `true` if `array` contains `item`, using `Array.prototype.includes`
|
|
210
|
+
* (which handles `NaN`).
|
|
211
|
+
*/
|
|
212
|
+
declare function contains<T>(array: T[], item: T): boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Adds `item` to `array` if it is not already present. Mutates and returns
|
|
215
|
+
* the same array reference.
|
|
216
|
+
*/
|
|
217
|
+
declare function include<T>(array: T[], item: T): T[];
|
|
218
|
+
/**
|
|
219
|
+
* Removes the **first** occurrence of `item` from `array`. Mutates and
|
|
220
|
+
* returns the same array reference.
|
|
221
|
+
*/
|
|
222
|
+
declare function remove<T>(array: T[], item: T): T[];
|
|
223
|
+
/**
|
|
224
|
+
* Returns a **new** array with all `null` and `undefined` entries removed.
|
|
225
|
+
*/
|
|
226
|
+
declare function clean<T>(array: (T | null | undefined)[]): T[];
|
|
227
|
+
/**
|
|
228
|
+
* Returns a **new** array with duplicate values removed, preserving the order
|
|
229
|
+
* of first occurrence. Uses a `Set` (strict/reference equality).
|
|
230
|
+
*/
|
|
231
|
+
declare function unique<T>(array: T[]): T[];
|
|
232
|
+
/**
|
|
233
|
+
* Flattens one level deep: `[1, [2, 3], 4]` → `[1, 2, 3, 4]`.
|
|
234
|
+
* Does **not** recurse into deeper nesting.
|
|
235
|
+
*/
|
|
236
|
+
declare function flatten<T>(array: (T | T[])[]): T[];
|
|
237
|
+
/**
|
|
238
|
+
* Extracts the value of `key` from every element.
|
|
239
|
+
*/
|
|
240
|
+
declare function pluck<T, K extends keyof T>(array: T[], key: K): T[K][];
|
|
241
|
+
/**
|
|
242
|
+
* Returns the sum of all elements. Returns `0` for an empty array.
|
|
243
|
+
*/
|
|
244
|
+
declare function sum(array: number[]): number;
|
|
245
|
+
/**
|
|
246
|
+
* Returns the arithmetic mean. Returns `NaN` for an empty array.
|
|
247
|
+
*/
|
|
248
|
+
declare function mean(array: number[]): number;
|
|
249
|
+
/**
|
|
250
|
+
* Returns the minimum element. When no `compareFn` is given, uses `<`.
|
|
251
|
+
* Throws if the array is empty.
|
|
252
|
+
*/
|
|
253
|
+
declare function min<T>(array: T[], compareFn?: (a: T, b: T) => number): T;
|
|
254
|
+
/**
|
|
255
|
+
* Returns the maximum element. When no `compareFn` is given, uses `<`.
|
|
256
|
+
* Throws if the array is empty.
|
|
257
|
+
*/
|
|
258
|
+
declare function max<T>(array: T[], compareFn?: (a: T, b: T) => number): T;
|
|
259
|
+
/**
|
|
260
|
+
* Groups elements by the string/number key returned by `fn`.
|
|
261
|
+
*/
|
|
262
|
+
declare function groupBy<T, K extends string | number>(array: T[], fn: (item: T) => K): Record<K, T[]>;
|
|
263
|
+
/**
|
|
264
|
+
* Splits an array into two: elements that satisfy the predicate and those
|
|
265
|
+
* that don't.
|
|
266
|
+
*/
|
|
267
|
+
declare function partition<T>(array: T[], predicate: (item: T) => boolean): [T[], T[]];
|
|
268
|
+
/**
|
|
269
|
+
* Splits `array` into chunks of at most `size` elements.
|
|
270
|
+
* Throws if `size` is ≤ 0.
|
|
271
|
+
*/
|
|
272
|
+
declare function chunk<T>(array: T[], size: number): T[][];
|
|
273
|
+
/**
|
|
274
|
+
* Returns elements in `array1` that are **not** in `array2`.
|
|
275
|
+
*/
|
|
276
|
+
declare function difference<T>(array1: T[], array2: T[]): T[];
|
|
277
|
+
/**
|
|
278
|
+
* Returns elements that appear in **both** `array1` and `array2`, preserving
|
|
279
|
+
* order from `array1`. Each value appears at most once in the result.
|
|
280
|
+
*/
|
|
281
|
+
declare function intersection<T>(array1: T[], array2: T[]): T[];
|
|
282
|
+
/**
|
|
283
|
+
* Returns a **new** sorted array. `key` may be a property name or an
|
|
284
|
+
* accessor function. Default direction is `'ASC'`.
|
|
285
|
+
*/
|
|
286
|
+
declare function sortBy<T>(array: T[], key: keyof T | ((item: T) => unknown), direction?: 'ASC' | 'DESC'): T[];
|
|
287
|
+
/**
|
|
288
|
+
* Returns the first element for which `fn` returns `true`, or `undefined`.
|
|
289
|
+
*/
|
|
290
|
+
declare function findBy<T>(array: T[], fn: (item: T) => boolean): T | undefined;
|
|
291
|
+
/**
|
|
292
|
+
* Generates a half-open range `[start, end)` with the given `step`
|
|
293
|
+
* (default `1`). A negative step produces a descending range.
|
|
294
|
+
* Throws if `step` is `0`.
|
|
295
|
+
*/
|
|
296
|
+
declare function range(start: number, end: number, step?: number): number[];
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @framesquared/core – Object utilities
|
|
300
|
+
*/
|
|
301
|
+
/**
|
|
302
|
+
* Typed wrapper around `Object.keys`.
|
|
303
|
+
*/
|
|
304
|
+
declare function keys<T extends object>(obj: T): (keyof T)[];
|
|
305
|
+
/**
|
|
306
|
+
* Typed wrapper around `Object.values`.
|
|
307
|
+
*/
|
|
308
|
+
declare function values<T extends object>(obj: T): T[keyof T][];
|
|
309
|
+
/**
|
|
310
|
+
* Typed wrapper around `Object.entries`.
|
|
311
|
+
*/
|
|
312
|
+
declare function entries<T extends object>(obj: T): [keyof T, T[keyof T]][];
|
|
313
|
+
/**
|
|
314
|
+
* Typed wrapper around `Object.fromEntries`.
|
|
315
|
+
*/
|
|
316
|
+
declare function fromEntries<K extends string, V>(items: [K, V][]): Record<K, V>;
|
|
317
|
+
/**
|
|
318
|
+
* Deep-merges own enumerable properties from every `source` into `target`.
|
|
319
|
+
*
|
|
320
|
+
* - Plain objects are recursively merged.
|
|
321
|
+
* - Arrays and non-plain objects are **overwritten** (not merged element-wise).
|
|
322
|
+
* - Mutates and returns `target`.
|
|
323
|
+
*/
|
|
324
|
+
declare function merge<T extends object>(target: T, ...sources: Partial<T>[]): T;
|
|
325
|
+
/**
|
|
326
|
+
* Returns a new object containing only the specified `pickedKeys`.
|
|
327
|
+
*/
|
|
328
|
+
declare function pick<T extends object, K extends keyof T>(obj: T, pickedKeys: K[]): Pick<T, K>;
|
|
329
|
+
/**
|
|
330
|
+
* Returns a new object with the specified `omittedKeys` removed.
|
|
331
|
+
*/
|
|
332
|
+
declare function omit<T extends object, K extends keyof T>(obj: T, omittedKeys: K[]): Omit<T, K>;
|
|
333
|
+
/**
|
|
334
|
+
* Returns a new object with every value transformed by `fn`.
|
|
335
|
+
*/
|
|
336
|
+
declare function mapValues<T extends object, U>(obj: T, fn: (value: T[keyof T], key: keyof T) => U): Record<keyof T, U>;
|
|
337
|
+
/**
|
|
338
|
+
* Returns a new object with every key transformed by `fn`.
|
|
339
|
+
*/
|
|
340
|
+
declare function mapKeys<T extends object>(obj: T, fn: (key: keyof T) => string): Record<string, T[keyof T]>;
|
|
341
|
+
/**
|
|
342
|
+
* Recursively freezes `obj` and all nested objects / arrays.
|
|
343
|
+
* Returns the same reference.
|
|
344
|
+
*/
|
|
345
|
+
declare function freeze<T extends object>(obj: T): Readonly<T>;
|
|
346
|
+
/**
|
|
347
|
+
* Deep structural equality comparison. Handles primitives, plain objects,
|
|
348
|
+
* arrays, `Date`, `RegExp`, and `NaN`.
|
|
349
|
+
*/
|
|
350
|
+
declare function equals(a: unknown, b: unknown): boolean;
|
|
351
|
+
/**
|
|
352
|
+
* Traverses `obj` along the dot-separated `path` and returns the value found.
|
|
353
|
+
* Returns `defaultValue` when the path does not exist (i.e. an intermediate
|
|
354
|
+
* segment is missing). If the final property exists but its value is
|
|
355
|
+
* `undefined`, `undefined` is returned (not `defaultValue`).
|
|
356
|
+
*/
|
|
357
|
+
declare function getNestedValue(obj: object, path: string, defaultValue?: unknown): unknown;
|
|
358
|
+
/**
|
|
359
|
+
* Sets a value at a dot-separated `path`, creating intermediate objects as
|
|
360
|
+
* needed.
|
|
361
|
+
*/
|
|
362
|
+
declare function setNestedValue(obj: object, path: string, value: unknown): void;
|
|
363
|
+
/**
|
|
364
|
+
* Flattens a nested object into a single-level object with dot-separated keys.
|
|
365
|
+
*
|
|
366
|
+
* Arrays and non-plain objects are treated as leaf values (not recursed into).
|
|
367
|
+
*/
|
|
368
|
+
declare function flattenObject(obj: object, prefix?: string): Record<string, unknown>;
|
|
369
|
+
/**
|
|
370
|
+
* Reverse of {@link flattenObject}: expands dot-separated keys into a nested
|
|
371
|
+
* object.
|
|
372
|
+
*/
|
|
373
|
+
declare function unflattenObject(obj: Record<string, unknown>): Record<string, unknown>;
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* @framesquared/core – Function utilities
|
|
377
|
+
*/
|
|
378
|
+
/**
|
|
379
|
+
* Binds `fn` to `scope` with optional pre-filled arguments.
|
|
380
|
+
*/
|
|
381
|
+
declare function bind<T extends Function>(fn: T, scope: unknown, ...args: unknown[]): T;
|
|
382
|
+
/**
|
|
383
|
+
* Returns a function that delays invoking `fn` until `buffer` milliseconds
|
|
384
|
+
* have elapsed since the **last** call. Each new call resets the timer
|
|
385
|
+
* (classic debounce).
|
|
386
|
+
*/
|
|
387
|
+
declare function createBuffered(fn: Function, buffer: number, scope?: unknown): (...args: unknown[]) => void;
|
|
388
|
+
/**
|
|
389
|
+
* Returns a function that always delays invoking `fn` by `delay` ms.
|
|
390
|
+
* Each call schedules its **own** independent timer (unlike debounce).
|
|
391
|
+
*/
|
|
392
|
+
declare function createDelayed(fn: Function, delay: number, scope?: unknown): (...args: unknown[]) => void;
|
|
393
|
+
/**
|
|
394
|
+
* Returns a function that invokes `fn` at most once per `intervalMs`
|
|
395
|
+
* milliseconds. The first call executes immediately.
|
|
396
|
+
*/
|
|
397
|
+
declare function createThrottled(fn: Function, intervalMs: number, scope?: unknown): (...args: unknown[]) => void;
|
|
398
|
+
/**
|
|
399
|
+
* Returns a function that only invokes `fn` once the returned function has
|
|
400
|
+
* been called exactly `count` times. Subsequent calls are no-ops.
|
|
401
|
+
*/
|
|
402
|
+
declare function createBarrier(count: number, fn: Function, scope?: unknown): (...args: unknown[]) => void;
|
|
403
|
+
/**
|
|
404
|
+
* Replaces `obj[methodName]` with a wrapper that calls `fn` **before** the
|
|
405
|
+
* original method. `fn` receives the same arguments as the original.
|
|
406
|
+
*/
|
|
407
|
+
declare function interceptBefore(obj: object, methodName: string, fn: Function): void;
|
|
408
|
+
/**
|
|
409
|
+
* Replaces `obj[methodName]` with a wrapper that calls `fn` **after** the
|
|
410
|
+
* original method. `fn` receives the original method's return value as its
|
|
411
|
+
* single argument. The wrapper still returns the original return value.
|
|
412
|
+
*/
|
|
413
|
+
declare function interceptAfter(obj: object, methodName: string, fn: Function): void;
|
|
414
|
+
/**
|
|
415
|
+
* Returns a function that calls every function in `fns` in order, passing
|
|
416
|
+
* all received arguments to each.
|
|
417
|
+
*/
|
|
418
|
+
declare function createSequence(...fns: Function[]): (...args: unknown[]) => void;
|
|
419
|
+
/**
|
|
420
|
+
* Returns a memoized version of `fn`. By default the first argument
|
|
421
|
+
* (stringified) is used as the cache key. Supply a `hasher` for
|
|
422
|
+
* multi-argument or non-primitive keys.
|
|
423
|
+
*/
|
|
424
|
+
declare function memoize<T extends (...args: any[]) => any>(fn: T, hasher?: (...args: Parameters<T>) => string): T;
|
|
425
|
+
/**
|
|
426
|
+
* Returns a function that invokes `fn` at most once. Subsequent calls
|
|
427
|
+
* return the result of the first invocation.
|
|
428
|
+
*/
|
|
429
|
+
declare function once<T extends (...args: any[]) => any>(fn: T): T;
|
|
430
|
+
/**
|
|
431
|
+
* Returns a function that negates the boolean return value of `fn`.
|
|
432
|
+
*/
|
|
433
|
+
declare function negate<T extends (...args: any[]) => boolean>(fn: T): T;
|
|
434
|
+
/**
|
|
435
|
+
* Right-to-left function composition.
|
|
436
|
+
* `compose(f, g, h)(x)` is equivalent to `f(g(h(x)))`.
|
|
437
|
+
*/
|
|
438
|
+
declare function compose(...fns: Function[]): (...args: unknown[]) => unknown;
|
|
439
|
+
/**
|
|
440
|
+
* Left-to-right function composition (aka pipeline).
|
|
441
|
+
* `pipe(f, g, h)(x)` is equivalent to `h(g(f(x)))`.
|
|
442
|
+
*/
|
|
443
|
+
declare function pipe(...fns: Function[]): (...args: unknown[]) => unknown;
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* @framesquared/core – Base class
|
|
447
|
+
*
|
|
448
|
+
* Foundation for the framesquared class system. Provides:
|
|
449
|
+
* - Config auto-generation (getX / setX / applyX / updateX lifecycle)
|
|
450
|
+
* - callParent() for wrapped methods (set up by define())
|
|
451
|
+
* - destroy() + Symbol.dispose
|
|
452
|
+
* - Mixin tracking via hasMixin()
|
|
453
|
+
*/
|
|
454
|
+
/** Per-instance call-stack entries for callParent(). */
|
|
455
|
+
interface CallStackEntry {
|
|
456
|
+
methodName: string;
|
|
457
|
+
owner: typeof Base;
|
|
458
|
+
}
|
|
459
|
+
declare class Base {
|
|
460
|
+
/** Fully-qualified class name. */
|
|
461
|
+
static $className: string;
|
|
462
|
+
/** Merged config defaults for this class (populated by processClassConfigs). */
|
|
463
|
+
static $configDefs: Record<string, unknown>;
|
|
464
|
+
/** Set of mixin constructors applied to this class (populated by define). */
|
|
465
|
+
static $mixins: Set<typeof Base>;
|
|
466
|
+
/** Per-instance call-stack used by `callParent()`. */
|
|
467
|
+
$callStack: CallStackEntry[];
|
|
468
|
+
/** Tracks which config properties have been explicitly initialized. */
|
|
469
|
+
$configInitialized: Set<string>;
|
|
470
|
+
/**
|
|
471
|
+
* Raw config object passed to the constructor. Decorator-based configs
|
|
472
|
+
* are consumed from here by `addInitializer` callbacks (which run after
|
|
473
|
+
* auto-accessor field initialization).
|
|
474
|
+
*/
|
|
475
|
+
$pendingConfig: Record<string, unknown> | undefined;
|
|
476
|
+
/** Whether `destroy()` has been called. */
|
|
477
|
+
isDestroyed: boolean;
|
|
478
|
+
/**
|
|
479
|
+
* Array of cleanup callbacks. Mixins (and user code) can push
|
|
480
|
+
* functions here; they all run during `destroy()`.
|
|
481
|
+
*/
|
|
482
|
+
$destroyHooks: (() => void)[];
|
|
483
|
+
/** The fully-qualified class name of this instance's constructor. */
|
|
484
|
+
get $className(): string;
|
|
485
|
+
/** Reference to the constructor (like ExtJS's `this.self`). */
|
|
486
|
+
get self(): typeof Base;
|
|
487
|
+
constructor(config?: Record<string, unknown>);
|
|
488
|
+
/**
|
|
489
|
+
* Static factory — creates an instance of the class.
|
|
490
|
+
*/
|
|
491
|
+
static create(this: new (...a: any[]) => Base, ...args: any[]): Base;
|
|
492
|
+
/**
|
|
493
|
+
* Applies the given config properties to this instance. Ensures that
|
|
494
|
+
* config accessors have been generated for the class first.
|
|
495
|
+
*/
|
|
496
|
+
initConfig(config?: Record<string, unknown>): void;
|
|
497
|
+
/**
|
|
498
|
+
* Calls the parent (super) class's implementation of the method that is
|
|
499
|
+
* currently executing. Only works for methods wrapped via `define()`.
|
|
500
|
+
*/
|
|
501
|
+
callParent(args?: unknown[]): unknown;
|
|
502
|
+
/**
|
|
503
|
+
* Returns `true` if the given mixin has been applied to this class (or
|
|
504
|
+
* to any of its ancestors / other mixins).
|
|
505
|
+
*/
|
|
506
|
+
hasMixin(mixin: typeof Base): boolean;
|
|
507
|
+
/**
|
|
508
|
+
* Tears down this instance. Calls `onDestroy()` if defined.
|
|
509
|
+
* Idempotent — second and subsequent calls are no-ops.
|
|
510
|
+
*/
|
|
511
|
+
destroy(): void;
|
|
512
|
+
/**
|
|
513
|
+
* `Symbol.dispose` support — calling `[Symbol.dispose]()` is equivalent
|
|
514
|
+
* to `destroy()`, enabling the TC39 `using` keyword.
|
|
515
|
+
*/
|
|
516
|
+
[Symbol.dispose](): void;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* @framesquared/core – ClassManager + define()
|
|
521
|
+
*
|
|
522
|
+
* Central registry for framesquared classes and the `define()` factory that
|
|
523
|
+
* creates, configures, and registers new classes in a single call.
|
|
524
|
+
*/
|
|
525
|
+
|
|
526
|
+
interface ClassDefinition {
|
|
527
|
+
/** Parent class (defaults to Base). */
|
|
528
|
+
extend?: typeof Base;
|
|
529
|
+
/** Mixins to apply. */
|
|
530
|
+
mixins?: (typeof Base)[];
|
|
531
|
+
/** One or more alias strings for ClassManager lookup. */
|
|
532
|
+
alias?: string | string[];
|
|
533
|
+
/** Config property defaults (auto-generates getX / setX). */
|
|
534
|
+
config?: Record<string, unknown>;
|
|
535
|
+
/** Static members to copy onto the constructor. */
|
|
536
|
+
statics?: Record<string, unknown>;
|
|
537
|
+
/** Any other properties are treated as prototype methods / members. */
|
|
538
|
+
[key: string]: unknown;
|
|
539
|
+
}
|
|
540
|
+
declare class ClassManagerImpl {
|
|
541
|
+
/** className → constructor */
|
|
542
|
+
private classes;
|
|
543
|
+
/** alias → constructor */
|
|
544
|
+
private aliases;
|
|
545
|
+
register(name: string, cls: typeof Base): void;
|
|
546
|
+
get(name: string): typeof Base | undefined;
|
|
547
|
+
getByAlias(alias: string): typeof Base | undefined;
|
|
548
|
+
isRegistered(name: string): boolean;
|
|
549
|
+
/**
|
|
550
|
+
* Returns all registered class names that start with `prefix`.
|
|
551
|
+
*/
|
|
552
|
+
getNamesByPrefix(prefix: string): string[];
|
|
553
|
+
/**
|
|
554
|
+
* Creates an instance by alias, passing remaining args to the constructor.
|
|
555
|
+
*/
|
|
556
|
+
instantiateByAlias(alias: string, ...args: any[]): Base;
|
|
557
|
+
registerAlias(alias: string, cls: typeof Base): void;
|
|
558
|
+
}
|
|
559
|
+
/** Singleton instance. */
|
|
560
|
+
declare const ClassManager: ClassManagerImpl;
|
|
561
|
+
/**
|
|
562
|
+
* Creates a new class, applies mixins, sets up config accessors, wraps
|
|
563
|
+
* methods for `callParent()`, registers with {@link ClassManager}, and
|
|
564
|
+
* returns the ready-to-use constructor.
|
|
565
|
+
*
|
|
566
|
+
* ```ts
|
|
567
|
+
* const Button = define('ui.Button', {
|
|
568
|
+
* extend: Component,
|
|
569
|
+
* mixins: [Focusable],
|
|
570
|
+
* alias: 'widget.button',
|
|
571
|
+
* config: { text: '', disabled: false },
|
|
572
|
+
* onClick() { ... },
|
|
573
|
+
* });
|
|
574
|
+
* ```
|
|
575
|
+
*/
|
|
576
|
+
declare function define(className: string, definition: ClassDefinition): typeof Base;
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* @framesquared/core – Configurator
|
|
580
|
+
*
|
|
581
|
+
* Central metadata registry for the `@config` decorator family.
|
|
582
|
+
* Uses TC39 `context.metadata` (Symbol.metadata) so metadata is
|
|
583
|
+
* available immediately after class definition — no instance needed.
|
|
584
|
+
*/
|
|
585
|
+
interface ConfigMeta {
|
|
586
|
+
/** Property name. */
|
|
587
|
+
name: string;
|
|
588
|
+
/** True when the config MUST be provided at construction time. */
|
|
589
|
+
required: boolean;
|
|
590
|
+
/** Factory function for lazy configs (computed on first access). */
|
|
591
|
+
lazyFactory?: (this: any) => unknown;
|
|
592
|
+
/** True when the getter result should be cached until next set. */
|
|
593
|
+
cached: boolean;
|
|
594
|
+
/** True when object values should be deep-merged with defaults. */
|
|
595
|
+
merge: boolean;
|
|
596
|
+
/** True when a change event should fire (Phase 2 integration). */
|
|
597
|
+
observable: boolean;
|
|
598
|
+
}
|
|
599
|
+
declare class ConfiguratorImpl {
|
|
600
|
+
/**
|
|
601
|
+
* Returns the ConfigMeta for a single config on the given class,
|
|
602
|
+
* walking the prototype chain.
|
|
603
|
+
*/
|
|
604
|
+
getConfigMeta(Ctor: Function, configName: string): ConfigMeta | undefined;
|
|
605
|
+
/**
|
|
606
|
+
* Collects all ConfigMeta entries for `Ctor`, including inherited.
|
|
607
|
+
*/
|
|
608
|
+
getAllConfigMeta(Ctor: Function): ConfigMeta[];
|
|
609
|
+
}
|
|
610
|
+
/** Singleton. */
|
|
611
|
+
declare const Configurator: ConfiguratorImpl;
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* @framesquared/core – TC39 Stage 3 decorators
|
|
615
|
+
*
|
|
616
|
+
* Usage:
|
|
617
|
+
* ```ts
|
|
618
|
+
* @alias('widget.panel')
|
|
619
|
+
* @mixin(Draggable)
|
|
620
|
+
* class Panel extends Base {
|
|
621
|
+
* @config accessor title: string = 'Untitled';
|
|
622
|
+
* @config.required accessor id: string = '';
|
|
623
|
+
* @config.lazy(fn) accessor data: object = {};
|
|
624
|
+
* @config.cached accessor fullName: string = '';
|
|
625
|
+
* @config.merge accessor style: object = {};
|
|
626
|
+
* @observable @config accessor theme: string = 'light';
|
|
627
|
+
* }
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
|
|
631
|
+
interface ConfigDecorator {
|
|
632
|
+
<This extends Base, Value>(target: ClassAccessorDecoratorTarget<This, Value>, context: ClassAccessorDecoratorContext<This, Value>): ClassAccessorDecoratorResult<This, Value>;
|
|
633
|
+
required: <This extends Base, Value>(target: ClassAccessorDecoratorTarget<This, Value>, context: ClassAccessorDecoratorContext<This, Value>) => ClassAccessorDecoratorResult<This, Value>;
|
|
634
|
+
lazy: (factory: (this: any) => unknown) => <This extends Base, Value>(target: ClassAccessorDecoratorTarget<This, Value>, context: ClassAccessorDecoratorContext<This, Value>) => ClassAccessorDecoratorResult<This, Value>;
|
|
635
|
+
cached: <This extends Base, Value>(target: ClassAccessorDecoratorTarget<This, Value>, context: ClassAccessorDecoratorContext<This, Value>) => ClassAccessorDecoratorResult<This, Value>;
|
|
636
|
+
merge: <This extends Base, Value>(target: ClassAccessorDecoratorTarget<This, Value>, context: ClassAccessorDecoratorContext<This, Value>) => ClassAccessorDecoratorResult<This, Value>;
|
|
637
|
+
}
|
|
638
|
+
declare const config: ConfigDecorator;
|
|
639
|
+
/**
|
|
640
|
+
* Marks a `@config` accessor as observable. Stores metadata only;
|
|
641
|
+
* event firing is Phase 2.
|
|
642
|
+
*/
|
|
643
|
+
declare function observable<This extends Base, Value>(_target: ClassAccessorDecoratorTarget<This, Value>, context: ClassAccessorDecoratorContext<This, Value>): void;
|
|
644
|
+
declare function alias(aliasName: string): <T extends abstract new (...args: any[]) => any>(target: T, _context: ClassDecoratorContext<T>) => T;
|
|
645
|
+
declare function mixin(mixinClass: typeof Base): <T extends abstract new (...args: any[]) => any>(target: T, _context: ClassDecoratorContext<T>) => T;
|
|
646
|
+
declare function override(targetClass: typeof Base): <T extends abstract new (...args: any[]) => any>(patchClass: T, _context: ClassDecoratorContext<T>) => T;
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* @framesquared/core – Identifiable mixin
|
|
650
|
+
*
|
|
651
|
+
* Adds an `id` config to any class. If no id is provided, one is
|
|
652
|
+
* auto-generated via `generateId()`. Instances are registered in a
|
|
653
|
+
* global {@link IdentityMap} for lookup by id and automatically
|
|
654
|
+
* removed on destroy.
|
|
655
|
+
*/
|
|
656
|
+
|
|
657
|
+
declare class IdentityMapImpl {
|
|
658
|
+
private map;
|
|
659
|
+
register(id: string, instance: Base): void;
|
|
660
|
+
unregister(id: string): void;
|
|
661
|
+
get(id: string): Base | undefined;
|
|
662
|
+
has(id: string): boolean;
|
|
663
|
+
}
|
|
664
|
+
/** Singleton global identity map. */
|
|
665
|
+
declare const IdentityMap: IdentityMapImpl;
|
|
666
|
+
declare const Identifiable: typeof Base;
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* @framesquared/core – Factoryable
|
|
670
|
+
*
|
|
671
|
+
* Static factory that creates `Base` instances from flexible input:
|
|
672
|
+
*
|
|
673
|
+
* - Config object with `xtype` or `type` → alias lookup via ClassManager
|
|
674
|
+
* - Plain string → treated as an alias
|
|
675
|
+
* - Existing Base instance → returned as-is
|
|
676
|
+
*/
|
|
677
|
+
|
|
678
|
+
declare const Factoryable: {
|
|
679
|
+
/**
|
|
680
|
+
* Creates a `Base` instance from a config descriptor.
|
|
681
|
+
*
|
|
682
|
+
* @param config An object with `xtype`/`type`, a string alias, or
|
|
683
|
+
* an existing `Base` instance.
|
|
684
|
+
*/
|
|
685
|
+
create(config: string | Base | Record<string, any>): Base;
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @framesquared/core – Inheritable mixin
|
|
690
|
+
*
|
|
691
|
+
* Provides hierarchical parent → child config inheritance. Each instance
|
|
692
|
+
* can have an "inherited parent" whose inherited state is merged with the
|
|
693
|
+
* instance's own inherited state. Lookup walks up the chain.
|
|
694
|
+
*/
|
|
695
|
+
|
|
696
|
+
declare const Inheritable: typeof Base;
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* @framesquared/core – Hookable mixin
|
|
700
|
+
*
|
|
701
|
+
* Provides per-instance before/after hook points for any method.
|
|
702
|
+
* Hooks fire in registration order. Adding a hook wraps the method
|
|
703
|
+
* on the instance (not the prototype), so other instances are unaffected.
|
|
704
|
+
*/
|
|
705
|
+
|
|
706
|
+
declare const Hookable: typeof Base;
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* @framesquared/core – Pluggable mixin
|
|
710
|
+
*
|
|
711
|
+
* Adds plugin management to any class. Plugins are instantiated from
|
|
712
|
+
* config objects (using Factoryable semantics) or accepted as instances.
|
|
713
|
+
* All plugins are destroyed when the owner is destroyed.
|
|
714
|
+
*/
|
|
715
|
+
|
|
716
|
+
declare const Pluggable: typeof Base;
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* @framesquared/core – Plugin base class
|
|
720
|
+
*
|
|
721
|
+
* Base class for plugins used with the Pluggable mixin.
|
|
722
|
+
* Each plugin has an `id`, an `init(owner)` lifecycle hook, and
|
|
723
|
+
* is destroyed when its owner is destroyed.
|
|
724
|
+
*/
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Declare the config-generated methods so TypeScript knows about them.
|
|
728
|
+
*/
|
|
729
|
+
interface Plugin {
|
|
730
|
+
getId(): string;
|
|
731
|
+
setId(id: string): void;
|
|
732
|
+
getOwner(): Base | null;
|
|
733
|
+
setOwner(owner: Base | null): void;
|
|
734
|
+
}
|
|
735
|
+
declare class Plugin extends Base {
|
|
736
|
+
static $className: string;
|
|
737
|
+
static $configDefs: Record<string, unknown>;
|
|
738
|
+
/**
|
|
739
|
+
* Initialises this plugin. Called by the Pluggable mixin after the
|
|
740
|
+
* plugin is added to an owner.
|
|
741
|
+
*/
|
|
742
|
+
init(owner: Base): void;
|
|
743
|
+
/**
|
|
744
|
+
* Override of initConfig that ensures an auto-generated id.
|
|
745
|
+
*/
|
|
746
|
+
initConfig(config?: Record<string, unknown>): void;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* @framesquared/core – ExtEvent
|
|
751
|
+
*
|
|
752
|
+
* Represents a fired event. Provides `preventDefault()`,
|
|
753
|
+
* `stopPropagation()`, and `stopEvent()` controls.
|
|
754
|
+
*/
|
|
755
|
+
declare class ExtEvent {
|
|
756
|
+
readonly eventName: string;
|
|
757
|
+
readonly source: unknown;
|
|
758
|
+
readonly timestamp: number;
|
|
759
|
+
defaultPrevented: boolean;
|
|
760
|
+
propagationStopped: boolean;
|
|
761
|
+
constructor(eventName: string, source: unknown);
|
|
762
|
+
preventDefault(): void;
|
|
763
|
+
stopPropagation(): void;
|
|
764
|
+
/** Convenience: prevents default AND stops propagation. */
|
|
765
|
+
stopEvent(): void;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* @framesquared/core – Observable mixin
|
|
770
|
+
*
|
|
771
|
+
* The event system backbone. Mix into any Base subclass to gain full
|
|
772
|
+
* event management: `on`, `un`, `fireEvent`, suspend/resume, relay,
|
|
773
|
+
* managed listeners, and more.
|
|
774
|
+
*/
|
|
775
|
+
|
|
776
|
+
interface ListenerOptions {
|
|
777
|
+
/** Fire only once, then auto-remove. */
|
|
778
|
+
single?: boolean;
|
|
779
|
+
/** Delay in ms before the handler is called. */
|
|
780
|
+
delay?: number;
|
|
781
|
+
/** Buffer (debounce) in ms — resets on each fire. */
|
|
782
|
+
buffer?: number;
|
|
783
|
+
/** Higher priority fires first. Default is 0. */
|
|
784
|
+
priority?: number;
|
|
785
|
+
/** Extra arguments prepended to handler call. */
|
|
786
|
+
args?: unknown[];
|
|
787
|
+
/** Insert at front within the same priority band. */
|
|
788
|
+
prepend?: boolean;
|
|
789
|
+
/** Return a Destroyable handle from `on()`. */
|
|
790
|
+
destroyable?: boolean;
|
|
791
|
+
}
|
|
792
|
+
declare const Observable: typeof Base;
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* @framesquared/core – Destroyable
|
|
796
|
+
*
|
|
797
|
+
* Interface for objects that support deterministic cleanup, plus a
|
|
798
|
+
* utility to combine multiple destroyables into one.
|
|
799
|
+
*/
|
|
800
|
+
interface Destroyable {
|
|
801
|
+
destroy(): void;
|
|
802
|
+
}
|
|
803
|
+
declare const DestroyableUtil: {
|
|
804
|
+
/**
|
|
805
|
+
* Returns a single {@link Destroyable} whose `destroy()` method calls
|
|
806
|
+
* `destroy()` on every item. The combined handle is idempotent — second
|
|
807
|
+
* and subsequent calls are no-ops.
|
|
808
|
+
*/
|
|
809
|
+
combine(...items: Destroyable[]): Destroyable;
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* @framesquared/core – EventDomain
|
|
814
|
+
*
|
|
815
|
+
* A domain groups events by category (e.g. 'component', 'store').
|
|
816
|
+
* Controllers can use `domain.listen({ '#myButton': { click: handler } })`
|
|
817
|
+
* to route events by selector.
|
|
818
|
+
*
|
|
819
|
+
* Selectors:
|
|
820
|
+
* - `#itemId` — matches target.getItemId() === 'itemId'
|
|
821
|
+
* - `ClassName` — matches target.$className === 'ClassName'
|
|
822
|
+
*/
|
|
823
|
+
|
|
824
|
+
/** Selector → { eventName → handler } */
|
|
825
|
+
type ListenerConfig = Record<string, Record<string, Function>>;
|
|
826
|
+
declare class EventDomain {
|
|
827
|
+
readonly name: string;
|
|
828
|
+
private readonly matchFn;
|
|
829
|
+
private registeredListeners;
|
|
830
|
+
constructor(name: string, matchFn: (target: Base) => boolean);
|
|
831
|
+
static register(name: string, domain: EventDomain): void;
|
|
832
|
+
static get(name: string): EventDomain | undefined;
|
|
833
|
+
/**
|
|
834
|
+
* Returns `true` if `target` belongs to this domain.
|
|
835
|
+
*/
|
|
836
|
+
match(target: Base): boolean;
|
|
837
|
+
/**
|
|
838
|
+
* Registers a controller-style listener config.
|
|
839
|
+
*
|
|
840
|
+
* ```ts
|
|
841
|
+
* domain.listen({
|
|
842
|
+
* '#myButton': { click: handler },
|
|
843
|
+
* 'MyApp.view.Panel': { collapse: handler },
|
|
844
|
+
* });
|
|
845
|
+
* ```
|
|
846
|
+
*
|
|
847
|
+
* Returns a {@link Destroyable} that removes all registered listeners.
|
|
848
|
+
*/
|
|
849
|
+
listen(config: ListenerConfig): Destroyable;
|
|
850
|
+
/**
|
|
851
|
+
* Dispatches an event from `source` through this domain.
|
|
852
|
+
* All registered listeners whose selector matches are called.
|
|
853
|
+
*/
|
|
854
|
+
dispatch(source: Base, eventName: string, args: unknown[]): void;
|
|
855
|
+
private matchesSelector;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* @framesquared/core – EventBus
|
|
860
|
+
*
|
|
861
|
+
* Global singleton event bus with publish / subscribe semantics.
|
|
862
|
+
* Supports dot-separated namespaced channels and wildcards:
|
|
863
|
+
*
|
|
864
|
+
* - `"user.login"` — exact match
|
|
865
|
+
* - `"user.*"` — matches one segment after "user."
|
|
866
|
+
* - `"user.**"` — matches one or more segments after "user."
|
|
867
|
+
* - `"**"` — matches any channel
|
|
868
|
+
*/
|
|
869
|
+
|
|
870
|
+
declare class EventBusImpl {
|
|
871
|
+
private subscriptions;
|
|
872
|
+
/**
|
|
873
|
+
* Publishes a message to a channel. All matching subscribers are called.
|
|
874
|
+
*/
|
|
875
|
+
publish(channel: string, ...args: unknown[]): void;
|
|
876
|
+
/**
|
|
877
|
+
* Subscribes to a channel (exact or wildcard pattern).
|
|
878
|
+
* Returns a {@link Destroyable} handle.
|
|
879
|
+
*/
|
|
880
|
+
subscribe(channel: string, handler: Function, scope?: object): Destroyable;
|
|
881
|
+
/**
|
|
882
|
+
* Removes a specific subscription by handler reference.
|
|
883
|
+
*/
|
|
884
|
+
unsubscribe(channel: string, handler: Function): void;
|
|
885
|
+
}
|
|
886
|
+
/** Singleton global event bus. */
|
|
887
|
+
declare const EventBus: EventBusImpl;
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* @framesquared/core – TypedObservable
|
|
891
|
+
*
|
|
892
|
+
* A generic interface that overlays type-safe event signatures on top
|
|
893
|
+
* of the runtime Observable mixin.
|
|
894
|
+
*
|
|
895
|
+
* Usage:
|
|
896
|
+
* ```ts
|
|
897
|
+
* interface PanelEvents {
|
|
898
|
+
* expand: [panel: Panel];
|
|
899
|
+
* collapse: [panel: Panel];
|
|
900
|
+
* resize: [panel: Panel, width: number, height: number];
|
|
901
|
+
* close: [];
|
|
902
|
+
* }
|
|
903
|
+
*
|
|
904
|
+
* class Panel extends Base implements TypedObservable<PanelEvents> { ... }
|
|
905
|
+
*
|
|
906
|
+
* const p = new Panel();
|
|
907
|
+
* p.on('resize', (panel, width, height) => { ... }); // fully typed
|
|
908
|
+
* p.fireEvent('resize', p, 100, 200); // args checked
|
|
909
|
+
* ```
|
|
910
|
+
*
|
|
911
|
+
* The interface only constrains the type checker — at runtime the
|
|
912
|
+
* untyped Observable methods are used.
|
|
913
|
+
*/
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Constraint for event maps. Every key must map to a tuple of handler
|
|
917
|
+
* argument types. Works with both `type` aliases and `interface`s.
|
|
918
|
+
*
|
|
919
|
+
* ```ts
|
|
920
|
+
* interface MyEvents {
|
|
921
|
+
* click: [x: number, y: number];
|
|
922
|
+
* load: [];
|
|
923
|
+
* }
|
|
924
|
+
* ```
|
|
925
|
+
*/
|
|
926
|
+
type EventMap = {};
|
|
927
|
+
/**
|
|
928
|
+
* Overlay interface that narrows Observable's string-based API to a
|
|
929
|
+
* concrete event map `Events`.
|
|
930
|
+
*/
|
|
931
|
+
interface TypedObservable<Events extends {
|
|
932
|
+
[K in keyof Events]: unknown[];
|
|
933
|
+
}> {
|
|
934
|
+
on<E extends keyof Events & string>(eventName: E, handler: (...args: Events[E]) => void | false, scope?: object, options?: ListenerOptions): Destroyable | void;
|
|
935
|
+
un<E extends keyof Events & string>(eventName: E, handler: (...args: Events[E]) => void | false, scope?: object): void;
|
|
936
|
+
addListener<E extends keyof Events & string>(eventName: E, handler: (...args: Events[E]) => void | false, scope?: object, options?: ListenerOptions): Destroyable | void;
|
|
937
|
+
removeListener<E extends keyof Events & string>(eventName: E, handler: (...args: Events[E]) => void | false, scope?: object): void;
|
|
938
|
+
fireEvent<E extends keyof Events & string>(eventName: E, ...args: Events[E]): boolean;
|
|
939
|
+
fireEventArgs<E extends keyof Events & string>(eventName: E, args: Events[E]): boolean;
|
|
940
|
+
hasListener<E extends keyof Events & string>(eventName: E): boolean;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* @framesquared/core – EventManager (DomEvent)
|
|
945
|
+
*
|
|
946
|
+
* Thin layer over native DOM events providing:
|
|
947
|
+
* - Tracked listener registration with bulk cleanup
|
|
948
|
+
* - Event delegation via closest()
|
|
949
|
+
* - DOM-ready callback
|
|
950
|
+
* - Utility helpers for coordinates, keys, stopEvent
|
|
951
|
+
*/
|
|
952
|
+
|
|
953
|
+
declare const EventManager: {
|
|
954
|
+
/**
|
|
955
|
+
* Registers a DOM event listener. The listener is tracked for
|
|
956
|
+
* bulk removal via {@link removeAll}.
|
|
957
|
+
*
|
|
958
|
+
* Returns a {@link Destroyable} handle.
|
|
959
|
+
*/
|
|
960
|
+
on(element: Element | Document, eventName: string, handler: EventListener, options?: AddEventListenerOptions): Destroyable;
|
|
961
|
+
/**
|
|
962
|
+
* Removes a DOM event listener.
|
|
963
|
+
*/
|
|
964
|
+
un(element: Element | Document, eventName: string, handler: EventListener): void;
|
|
965
|
+
/**
|
|
966
|
+
* Event delegation: listens on `element` and fires `handler` only when
|
|
967
|
+
* the event target (or an ancestor up to `element`) matches `selector`.
|
|
968
|
+
*
|
|
969
|
+
* Uses `Element.closest()` — no IE polyfill needed.
|
|
970
|
+
*/
|
|
971
|
+
delegate(element: Element, eventName: string, selector: string, handler: (e: Event, matchedTarget: Element) => void): Destroyable;
|
|
972
|
+
/**
|
|
973
|
+
* Calls `fn` when the DOM is ready. If it's already ready (interactive
|
|
974
|
+
* or complete), fires immediately.
|
|
975
|
+
*/
|
|
976
|
+
onReady(fn: () => void): void;
|
|
977
|
+
/** Prevents default and stops propagation. */
|
|
978
|
+
stopEvent(e: Event): void;
|
|
979
|
+
/** Returns `e.pageX` (or `e.clientX` as fallback). */
|
|
980
|
+
getPageX(e: MouseEvent): number;
|
|
981
|
+
/** Returns `e.pageY` (or `e.clientY` as fallback). */
|
|
982
|
+
getPageY(e: MouseEvent): number;
|
|
983
|
+
/** Returns `e.relatedTarget`. */
|
|
984
|
+
getRelatedTarget(e: MouseEvent): Element | null;
|
|
985
|
+
/** Returns `e.key` (modern key value). */
|
|
986
|
+
getKeyCode(e: KeyboardEvent): string;
|
|
987
|
+
/**
|
|
988
|
+
* Removes all listeners registered via {@link on} and {@link delegate}.
|
|
989
|
+
*/
|
|
990
|
+
removeAll(): void;
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
/**
|
|
994
|
+
* @framesquared/core – GestureRecognizer
|
|
995
|
+
*
|
|
996
|
+
* Detects touch/pointer gestures and dispatches synthetic CustomEvents
|
|
997
|
+
* on the target element. Uses PointerEvent exclusively (no IE).
|
|
998
|
+
*
|
|
999
|
+
* Recognized gestures: tap, doubletap, longpress, swipe, pinch, rotate.
|
|
1000
|
+
*/
|
|
1001
|
+
declare class GestureRecognizer {
|
|
1002
|
+
private el;
|
|
1003
|
+
private pointers;
|
|
1004
|
+
private longpressTimer;
|
|
1005
|
+
private lastTapTime;
|
|
1006
|
+
private destroyed;
|
|
1007
|
+
private initialPinchDistance;
|
|
1008
|
+
private initialPinchAngle;
|
|
1009
|
+
private handleDown;
|
|
1010
|
+
private handleMove;
|
|
1011
|
+
private handleUp;
|
|
1012
|
+
private handleCancel;
|
|
1013
|
+
constructor(element: Element);
|
|
1014
|
+
destroy(): void;
|
|
1015
|
+
private onPointerDown;
|
|
1016
|
+
private onPointerMove;
|
|
1017
|
+
private onPointerUp;
|
|
1018
|
+
private onPointerCancel;
|
|
1019
|
+
private startLongpress;
|
|
1020
|
+
private clearLongpress;
|
|
1021
|
+
private fireSwipe;
|
|
1022
|
+
private recordTwoPointerBaseline;
|
|
1023
|
+
private handleTwoPointerMove;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* @framesquared/core – KeyMap
|
|
1028
|
+
*
|
|
1029
|
+
* Maps key combinations to handlers. Supports modifier keys
|
|
1030
|
+
* (Ctrl, Alt, Shift, Meta) with exact matching.
|
|
1031
|
+
*
|
|
1032
|
+
* ```ts
|
|
1033
|
+
* const km = new KeyMap({
|
|
1034
|
+
* target: myElement,
|
|
1035
|
+
* bindings: [
|
|
1036
|
+
* { key: 'Ctrl+S', handler: onSave, preventDefault: true },
|
|
1037
|
+
* { key: 'Escape', handler: onClose },
|
|
1038
|
+
* ],
|
|
1039
|
+
* });
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
interface KeyBinding {
|
|
1043
|
+
/** Key combo string, e.g. `"Ctrl+Shift+S"`, `"Enter"`, `"Alt+F4"`. */
|
|
1044
|
+
key: string;
|
|
1045
|
+
/** Handler called when the combo matches. */
|
|
1046
|
+
handler: Function;
|
|
1047
|
+
/** Optional `this` scope for the handler. */
|
|
1048
|
+
scope?: object;
|
|
1049
|
+
/** If true, `e.preventDefault()` is called when the combo matches. */
|
|
1050
|
+
preventDefault?: boolean;
|
|
1051
|
+
}
|
|
1052
|
+
interface KeyMapConfig {
|
|
1053
|
+
target: Element;
|
|
1054
|
+
bindings: KeyBinding[];
|
|
1055
|
+
}
|
|
1056
|
+
declare class KeyMap {
|
|
1057
|
+
private target;
|
|
1058
|
+
private parsedBindings;
|
|
1059
|
+
private enabled;
|
|
1060
|
+
private handleKeyDown;
|
|
1061
|
+
constructor(config: KeyMapConfig);
|
|
1062
|
+
private onKeyDown;
|
|
1063
|
+
enable(): void;
|
|
1064
|
+
disable(): void;
|
|
1065
|
+
addBinding(binding: KeyBinding): void;
|
|
1066
|
+
removeBinding(binding: KeyBinding): void;
|
|
1067
|
+
destroy(): void;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* @framesquared/core – AriaManager
|
|
1072
|
+
*
|
|
1073
|
+
* Manages ARIA attributes across the framework. Provides helpers
|
|
1074
|
+
* for setting roles, labels, descriptions, live regions, and
|
|
1075
|
+
* screen reader announcements.
|
|
1076
|
+
*/
|
|
1077
|
+
declare const AriaManager: {
|
|
1078
|
+
setRole(element: Element, role: string): void;
|
|
1079
|
+
setLabel(element: Element, label: string): void;
|
|
1080
|
+
setLabelledBy(element: Element, id: string): void;
|
|
1081
|
+
setDescription(element: Element, description: string): void;
|
|
1082
|
+
setLive(element: Element, mode: "polite" | "assertive" | "off"): void;
|
|
1083
|
+
announce(message: string, priority?: "polite" | "assertive"): void;
|
|
1084
|
+
/** Generate a unique ID for ARIA linking. */
|
|
1085
|
+
generateId(prefix?: string): string;
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* @framesquared/core – FocusManager
|
|
1090
|
+
*
|
|
1091
|
+
* Manages focus trapping for modal dialogs, focus save/restore,
|
|
1092
|
+
* and roving tabindex patterns.
|
|
1093
|
+
*/
|
|
1094
|
+
declare const FocusManager: {
|
|
1095
|
+
/**
|
|
1096
|
+
* Trap focus within a container. Tab/Shift+Tab cycle among
|
|
1097
|
+
* focusable elements inside the container.
|
|
1098
|
+
*/
|
|
1099
|
+
trapFocus(container: HTMLElement): void;
|
|
1100
|
+
/** Release the focus trap. */
|
|
1101
|
+
releaseFocus(): void;
|
|
1102
|
+
isTrapped(): boolean;
|
|
1103
|
+
/** Save the currently focused element for later restoration. */
|
|
1104
|
+
saveFocus(): void;
|
|
1105
|
+
/** Restore focus to the previously saved element. */
|
|
1106
|
+
restoreFocus(): void;
|
|
1107
|
+
/** Reset all state (for tests). */
|
|
1108
|
+
reset(): void;
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* @framesquared/core – Locale
|
|
1113
|
+
*
|
|
1114
|
+
* Manages translations, number/date formatting (via Intl APIs),
|
|
1115
|
+
* plural rules, RTL direction, and locale-aware collation.
|
|
1116
|
+
*/
|
|
1117
|
+
interface NumberFormatOptions {
|
|
1118
|
+
currency?: string;
|
|
1119
|
+
}
|
|
1120
|
+
interface LocaleConfig {
|
|
1121
|
+
language: string;
|
|
1122
|
+
rtl?: boolean;
|
|
1123
|
+
messages: Record<string, string>;
|
|
1124
|
+
dateFormat?: string;
|
|
1125
|
+
timeFormat?: string;
|
|
1126
|
+
numberFormat?: NumberFormatOptions;
|
|
1127
|
+
firstDayOfWeek?: number;
|
|
1128
|
+
pluralRules?: (count: number) => string;
|
|
1129
|
+
}
|
|
1130
|
+
declare class Locale {
|
|
1131
|
+
private _language;
|
|
1132
|
+
private _rtl;
|
|
1133
|
+
private _messages;
|
|
1134
|
+
private _numberFormat;
|
|
1135
|
+
private _firstDayOfWeek;
|
|
1136
|
+
private _pluralRules;
|
|
1137
|
+
private _collator;
|
|
1138
|
+
private _numberFormatter;
|
|
1139
|
+
private _dateFormatter;
|
|
1140
|
+
private _timeFormatter;
|
|
1141
|
+
private _currencyFormatter;
|
|
1142
|
+
constructor(config: LocaleConfig);
|
|
1143
|
+
getLanguage(): string;
|
|
1144
|
+
isRtl(): boolean;
|
|
1145
|
+
getDirection(): 'ltr' | 'rtl';
|
|
1146
|
+
getFirstDayOfWeek(): number;
|
|
1147
|
+
t(key: string, params?: Record<string, unknown>): string;
|
|
1148
|
+
/**
|
|
1149
|
+
* Translate with plural support. Appends the plural category
|
|
1150
|
+
* to the key (e.g., 'items.one', 'items.other').
|
|
1151
|
+
*/
|
|
1152
|
+
tp(key: string, count: number, params?: Record<string, unknown>): string;
|
|
1153
|
+
getPlural(count: number): string;
|
|
1154
|
+
formatNumber(value: number): string;
|
|
1155
|
+
formatCurrency(value: number): string;
|
|
1156
|
+
formatDate(date: Date): string;
|
|
1157
|
+
formatTime(date: Date): string;
|
|
1158
|
+
compare(a: string, b: string): number;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* @framesquared/core – LocaleManager
|
|
1163
|
+
*
|
|
1164
|
+
* Singleton that manages registered locales. setLocale() applies
|
|
1165
|
+
* dir and lang attributes to document.documentElement and fires
|
|
1166
|
+
* 'localechange'.
|
|
1167
|
+
*/
|
|
1168
|
+
|
|
1169
|
+
declare const LocaleManager: {
|
|
1170
|
+
register(locale: Locale): void;
|
|
1171
|
+
setLocale(language: string): void;
|
|
1172
|
+
getLocale(): Locale | null;
|
|
1173
|
+
t(key: string, params?: Record<string, unknown>): string;
|
|
1174
|
+
getDirection(): "ltr" | "rtl";
|
|
1175
|
+
on(event: string, fn: Function): void;
|
|
1176
|
+
off(event: string, fn: Function): void;
|
|
1177
|
+
reset(): void;
|
|
1178
|
+
};
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* @framesquared/core – en-US locale bundle
|
|
1182
|
+
*/
|
|
1183
|
+
|
|
1184
|
+
declare const enUS: Locale;
|
|
1185
|
+
|
|
1186
|
+
/**
|
|
1187
|
+
* @framesquared/core – es-ES locale bundle
|
|
1188
|
+
*/
|
|
1189
|
+
|
|
1190
|
+
declare const esES: Locale;
|
|
1191
|
+
|
|
1192
|
+
/**
|
|
1193
|
+
* @framesquared/core – ar-SA locale bundle
|
|
1194
|
+
*/
|
|
1195
|
+
|
|
1196
|
+
declare const arSA: Locale;
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* @framesquared/core – Sanitizer
|
|
1200
|
+
*
|
|
1201
|
+
* HTML sanitization utility for safe innerHTML usage.
|
|
1202
|
+
* Uses a whitelist approach — only known-safe tags and attributes pass through.
|
|
1203
|
+
* No dependencies on DOMPurify; uses the browser's own DOMParser.
|
|
1204
|
+
*
|
|
1205
|
+
* @example
|
|
1206
|
+
* ```typescript
|
|
1207
|
+
* import { Sanitizer } from '@framesquared/core';
|
|
1208
|
+
*
|
|
1209
|
+
* const clean = Sanitizer.sanitize('<p onclick="alert(1)">Hello <b>world</b></p>');
|
|
1210
|
+
* // Returns: '<p>Hello <b>world</b></p>'
|
|
1211
|
+
* ```
|
|
1212
|
+
*
|
|
1213
|
+
* @since 0.1.0
|
|
1214
|
+
*/
|
|
1215
|
+
declare const Sanitizer: {
|
|
1216
|
+
/**
|
|
1217
|
+
* Sanitize an HTML string by removing dangerous tags and attributes.
|
|
1218
|
+
* Uses a whitelist approach — only known-safe elements pass through.
|
|
1219
|
+
*
|
|
1220
|
+
* @param html - Raw HTML string
|
|
1221
|
+
* @returns Sanitized HTML string safe for innerHTML
|
|
1222
|
+
*/
|
|
1223
|
+
sanitize(html: string): string;
|
|
1224
|
+
/**
|
|
1225
|
+
* Escape HTML special characters for safe text insertion.
|
|
1226
|
+
*
|
|
1227
|
+
* @param text - Raw text
|
|
1228
|
+
* @returns Escaped string safe for HTML context
|
|
1229
|
+
*/
|
|
1230
|
+
escapeHtml(text: string): string;
|
|
1231
|
+
/**
|
|
1232
|
+
* Check if an HTML string contains potentially dangerous content.
|
|
1233
|
+
*
|
|
1234
|
+
* @param html - HTML string to check
|
|
1235
|
+
* @returns true if the HTML appears safe
|
|
1236
|
+
*/
|
|
1237
|
+
isSafe(html: string): boolean;
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* @framesquared/core
|
|
1242
|
+
* Class system, events, and utilities
|
|
1243
|
+
*/
|
|
1244
|
+
declare const VERSION = "0.0.1";
|
|
1245
|
+
|
|
1246
|
+
export { AriaManager, Base, type ClassDefinition, ClassManager, type ConfigMeta, Configurator, type Destroyable, DestroyableUtil, EventBus, EventDomain, EventManager, type EventMap, ExtEvent, Factoryable, FocusManager, GestureRecognizer, Hookable, Identifiable, IdentityMap, Inheritable, type KeyBinding, KeyMap, type KeyMapConfig, type ListenerConfig, type ListenerOptions, Locale, type LocaleConfig, LocaleManager, type NumberFormatOptions, Observable, Pluggable, Plugin, Sanitizer, type TypedObservable, VERSION, alias, apply, applyIf, arSA, bind, camelCase, capitalize, chunk, clean, clone, compose, config, contains, createBarrier, createBuffered, createDelayed, createSequence, createThrottled, defer, define, difference, ellipsis, emptyFn, enUS, entries, equals, esES, escapeHtml, escapeRegex, findBy, flatten, flattenObject, format, freeze, from, fromEntries, generateId, getNestedValue, groupBy, htmlDecode, htmlEncode, identity, include, interceptAfter, interceptBefore, intersection, interval, isArray, isBoolean, isDefined, isEmpty, isFunction, isIterable, isNumber, isObject, isPrimitive, isString, kebabCase, keys, leftPad, mapKeys, mapValues, max, mean, memoize, merge, min, mixin, namespace, negate, now, observable, omit, once, override, partition, pascalCase, pick, pipe, pluck, range, remove, repeat, setNestedValue, sortBy, splitWords, sum, toggle, trim, uncapitalize, unescapeHtml, unflattenObject, unique, values };
|