@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.
@@ -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 };