@signaltree/core 7.1.5 → 7.3.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.
Files changed (102) hide show
  1. package/README.md +392 -0
  2. package/dist/constants.js +6 -0
  3. package/dist/deep-equal.js +41 -0
  4. package/dist/enhancers/batching/batching.js +230 -0
  5. package/dist/enhancers/devtools/devtools.js +318 -0
  6. package/dist/enhancers/effects/effects.js +66 -0
  7. package/dist/enhancers/entities/entities.js +7 -0
  8. package/dist/enhancers/index.js +72 -0
  9. package/dist/enhancers/memoization/memoization.js +420 -0
  10. package/dist/enhancers/presets/lib/presets.js +27 -0
  11. package/dist/enhancers/serialization/constants.js +15 -0
  12. package/dist/enhancers/serialization/serialization.js +656 -0
  13. package/dist/enhancers/time-travel/time-travel.js +283 -0
  14. package/dist/enhancers/time-travel/utils.js +11 -0
  15. package/dist/enhancers/utils/copy-tree-properties.js +20 -0
  16. package/dist/index.js +27 -0
  17. package/dist/is-built-in-object.js +23 -0
  18. package/dist/lib/async-helpers.js +77 -0
  19. package/dist/lib/constants.js +56 -0
  20. package/dist/lib/edit-session.js +84 -0
  21. package/dist/lib/entity-signal.js +544 -0
  22. package/dist/lib/internals/batch-scope.js +8 -0
  23. package/dist/lib/internals/derived-types.js +6 -0
  24. package/dist/lib/internals/materialize-markers.js +72 -0
  25. package/dist/lib/internals/merge-derived.js +59 -0
  26. package/dist/lib/markers/derived.js +6 -0
  27. package/dist/lib/markers/entity-map.js +41 -0
  28. package/dist/lib/markers/form.js +310 -0
  29. package/dist/lib/markers/status.js +71 -0
  30. package/dist/lib/markers/stored.js +213 -0
  31. package/dist/lib/memory/memory-manager.js +164 -0
  32. package/dist/lib/path-notifier.js +178 -0
  33. package/dist/lib/presets.js +20 -0
  34. package/dist/lib/security/security-validator.js +121 -0
  35. package/dist/lib/signal-tree.js +416 -0
  36. package/dist/lib/types.js +3 -0
  37. package/dist/lib/utils.js +264 -0
  38. package/dist/lru-cache.js +64 -0
  39. package/dist/parse-path.js +13 -0
  40. package/package.json +1 -1
  41. package/src/enhancers/batching/batching.d.ts +10 -0
  42. package/src/enhancers/batching/batching.types.d.ts +1 -0
  43. package/src/enhancers/batching/index.d.ts +1 -0
  44. package/src/enhancers/batching/test-setup.d.ts +3 -0
  45. package/src/enhancers/devtools/devtools.d.ts +68 -0
  46. package/src/enhancers/devtools/devtools.types.d.ts +1 -0
  47. package/src/enhancers/devtools/index.d.ts +1 -0
  48. package/src/enhancers/devtools/test-setup.d.ts +3 -0
  49. package/src/enhancers/effects/effects.d.ts +9 -0
  50. package/src/enhancers/effects/effects.types.d.ts +1 -0
  51. package/src/enhancers/effects/index.d.ts +1 -0
  52. package/src/enhancers/entities/entities.d.ts +7 -0
  53. package/src/enhancers/entities/entities.types.d.ts +1 -0
  54. package/src/enhancers/entities/index.d.ts +1 -0
  55. package/src/enhancers/entities/test-setup.d.ts +3 -0
  56. package/src/enhancers/index.d.ts +3 -0
  57. package/src/enhancers/memoization/index.d.ts +1 -0
  58. package/src/enhancers/memoization/memoization.d.ts +54 -0
  59. package/src/enhancers/memoization/memoization.types.d.ts +1 -0
  60. package/src/enhancers/memoization/test-setup.d.ts +3 -0
  61. package/src/enhancers/presets/index.d.ts +1 -0
  62. package/src/enhancers/presets/lib/presets.d.ts +8 -0
  63. package/src/enhancers/serialization/constants.d.ts +14 -0
  64. package/src/enhancers/serialization/index.d.ts +2 -0
  65. package/src/enhancers/serialization/serialization.d.ts +68 -0
  66. package/src/enhancers/serialization/test-setup.d.ts +3 -0
  67. package/src/enhancers/test-helpers/types-equals.d.ts +2 -0
  68. package/src/enhancers/time-travel/index.d.ts +1 -0
  69. package/src/enhancers/time-travel/test-setup.d.ts +3 -0
  70. package/src/enhancers/time-travel/time-travel.d.ts +10 -0
  71. package/src/enhancers/time-travel/time-travel.types.d.ts +1 -0
  72. package/src/enhancers/time-travel/utils.d.ts +2 -0
  73. package/src/enhancers/types.d.ts +1 -0
  74. package/src/enhancers/typing/helpers-types.d.ts +2 -0
  75. package/src/enhancers/utils/copy-tree-properties.d.ts +1 -0
  76. package/src/index.d.ts +27 -0
  77. package/src/lib/async-helpers.d.ts +8 -0
  78. package/src/lib/constants.d.ts +41 -0
  79. package/src/lib/dev-proxy.d.ts +3 -0
  80. package/src/lib/edit-session.d.ts +21 -0
  81. package/src/lib/entity-signal.d.ts +1 -0
  82. package/src/lib/internals/batch-scope.d.ts +3 -0
  83. package/src/lib/internals/builder-types.d.ts +13 -0
  84. package/src/lib/internals/derived-types.d.ts +19 -0
  85. package/src/lib/internals/materialize-markers.d.ts +5 -0
  86. package/src/lib/internals/merge-derived.d.ts +4 -0
  87. package/src/lib/markers/derived.d.ts +9 -0
  88. package/src/lib/markers/entity-map.d.ts +19 -0
  89. package/src/lib/markers/form.d.ts +86 -0
  90. package/src/lib/markers/index.d.ts +4 -0
  91. package/src/lib/markers/status.d.ts +32 -0
  92. package/src/lib/markers/stored.d.ts +35 -0
  93. package/src/lib/memory/memory-manager.d.ts +30 -0
  94. package/src/lib/path-notifier.d.ts +34 -0
  95. package/src/lib/performance/diff-engine.d.ts +33 -0
  96. package/src/lib/performance/path-index.d.ts +25 -0
  97. package/src/lib/performance/update-engine.d.ts +32 -0
  98. package/src/lib/presets.d.ts +34 -0
  99. package/src/lib/security/security-validator.d.ts +33 -0
  100. package/src/lib/signal-tree.d.ts +6 -0
  101. package/src/lib/types.d.ts +301 -0
  102. package/src/lib/utils.d.ts +25 -0
@@ -0,0 +1,19 @@
1
+ import { Signal } from '@angular/core';
2
+ import { isEntityMapMarker } from '../utils';
3
+ export { isEntityMapMarker };
4
+ import type { EntityConfig, EntityMapMarker, EntitySignal } from '../types';
5
+ export interface ComputedSliceConfig<E, R> {
6
+ compute: (entities: E[]) => R;
7
+ }
8
+ export type EntitySignalWithSlices<E, K extends string | number, Slices extends Record<string, unknown>> = EntitySignal<E, K> & {
9
+ [P in keyof Slices]: Signal<Slices[P]>;
10
+ };
11
+ export interface EntityMapBuilder<E, K extends string | number, Slices extends Record<string, unknown> = Record<string, never>> extends EntityMapMarker<E, K> {
12
+ __computedSlices?: EntityMapComputedSlices<E>;
13
+ __sliceTypes?: Slices;
14
+ computed<N extends string, R>(name: N, compute: (entities: E[]) => R): EntityMapBuilder<E, K, Slices & Record<N, R>>;
15
+ build(): EntityMapMarkerWithSlices<E, K, Slices>;
16
+ }
17
+ export declare function entityMap<E, K extends string | number = E extends {
18
+ id: infer I extends string | number;
19
+ } ? I : string>(config?: EntityConfig<E, K>): EntityMapBuilder<E, K, Record<string, never>>;
@@ -0,0 +1,86 @@
1
+ import { Signal } from '@angular/core';
2
+ export declare const FORM_MARKER: unique symbol;
3
+ export type Validator<T> = (value: T) => string | null;
4
+ export type AsyncValidator<T> = (value: T) => Promise<string | null>;
5
+ export interface WizardStepConfig {
6
+ fields?: string[];
7
+ validate?: () => Promise<boolean> | boolean;
8
+ canSkip?: boolean;
9
+ }
10
+ export interface WizardConfig {
11
+ steps: string[];
12
+ stepConfig?: Record<string, WizardStepConfig>;
13
+ stepFields?: Record<string, string[]>;
14
+ }
15
+ export interface FormConfig<T extends Record<string, unknown>> {
16
+ initial: T;
17
+ persist?: string;
18
+ storage?: Storage | null;
19
+ persistDebounceMs?: number;
20
+ validators?: Partial<Record<keyof T, Validator<unknown> | Validator<unknown>[]>>;
21
+ asyncValidators?: Partial<Record<keyof T, AsyncValidator<unknown>>>;
22
+ wizard?: WizardConfig;
23
+ equalityFn?: (a: unknown, b: unknown) => boolean;
24
+ }
25
+ export interface FormMarker<T extends Record<string, unknown>> {
26
+ [FORM_MARKER]: true;
27
+ config: FormConfig<T>;
28
+ }
29
+ export interface FormWizard {
30
+ currentStep: Signal<number>;
31
+ stepName: Signal<string>;
32
+ steps: Signal<string[]>;
33
+ canNext: Signal<boolean>;
34
+ canPrev: Signal<boolean>;
35
+ isLastStep: Signal<boolean>;
36
+ isFirstStep: Signal<boolean>;
37
+ next(): Promise<boolean>;
38
+ prev(): void;
39
+ goTo(step: number | string): Promise<boolean>;
40
+ reset(): void;
41
+ }
42
+ export type FormFields<T> = {
43
+ [K in keyof T]: T[K] extends Record<string, unknown> ? FormFields<T[K]> & {
44
+ (): T[K];
45
+ set(value: T[K]): void;
46
+ } : {
47
+ (): T[K];
48
+ set(value: T[K]): void;
49
+ update(fn: (current: T[K]) => T[K]): void;
50
+ };
51
+ };
52
+ export interface FormSignal<T extends Record<string, unknown>> {
53
+ $: FormFields<T>;
54
+ (): T;
55
+ set(values: Partial<T>): void;
56
+ patch(values: Partial<T>): void;
57
+ reset(): void;
58
+ clear(): void;
59
+ valid: Signal<boolean>;
60
+ dirty: Signal<boolean>;
61
+ submitting: Signal<boolean>;
62
+ touched: Signal<Record<keyof T, boolean>>;
63
+ errors: Signal<Partial<Record<keyof T, string | null>>>;
64
+ errorList: Signal<string[]>;
65
+ validate(): Promise<boolean>;
66
+ validateField(field: keyof T): Promise<boolean>;
67
+ touch(field: keyof T): void;
68
+ touchAll(): void;
69
+ submit<R>(handler: (values: T) => Promise<R>): Promise<R | null>;
70
+ wizard?: FormWizard;
71
+ persistNow(): void;
72
+ reload(): void;
73
+ clearStorage(): void;
74
+ }
75
+ export declare function form<T extends Record<string, unknown>>(config: FormConfig<T>): FormMarker<T>;
76
+ export declare function isFormMarker(value: unknown): value is FormMarker<Record<string, unknown>>;
77
+ export declare const validators: {
78
+ required: (message?: string) => (value: unknown) => string | null;
79
+ minLength: (min: number, message?: string) => (value: unknown) => string | null;
80
+ maxLength: (max: number, message?: string) => (value: unknown) => string | null;
81
+ min: (min: number, message?: string) => (value: unknown) => string | null;
82
+ max: (max: number, message?: string) => (value: unknown) => string | null;
83
+ email: (message?: string) => (value: unknown) => string | null;
84
+ pattern: (regex: RegExp, message?: string) => (value: unknown) => string | null;
85
+ when: <T>(condition: (form: T) => boolean, validator: Validator<unknown>) => (value: unknown, form?: T) => string | null;
86
+ };
@@ -0,0 +1,4 @@
1
+ export { isDerivedMarker, getDerivedMarkerSymbol, type DerivedMarker, type DerivedType, } from './derived';
2
+ export { status, isStatusMarker, createStatusSignal, LoadingState, STATUS_MARKER, type StatusMarker, type StatusSignal, type StatusConfig, } from './status';
3
+ export { stored, isStoredMarker, createStoredSignal, createStorageKeys, clearStoragePrefix, STORED_MARKER, type StoredMarker, type StoredSignal, type StoredOptions, type MigrationFn, } from './stored';
4
+ export { form, isFormMarker, createFormSignal, validators, FORM_MARKER, type FormMarker, type FormSignal, type FormConfig, type FormFields, type FormWizard, type WizardConfig, type WizardStepConfig, type Validator, type AsyncValidator, } from './form';
@@ -0,0 +1,32 @@
1
+ import { Signal, WritableSignal } from '@angular/core';
2
+ export declare const STATUS_MARKER: unique symbol;
3
+ export declare enum LoadingState {
4
+ NotLoaded = "NOT_LOADED",
5
+ Loading = "LOADING",
6
+ Loaded = "LOADED",
7
+ Error = "ERROR"
8
+ }
9
+ export interface StatusConfig {
10
+ initialState?: LoadingState;
11
+ }
12
+ export interface StatusMarker<E = Error> {
13
+ [STATUS_MARKER]: true;
14
+ initialState: LoadingState;
15
+ readonly __errorType?: E;
16
+ }
17
+ export interface StatusSignal<E = Error> {
18
+ state: WritableSignal<LoadingState>;
19
+ error: WritableSignal<E | null>;
20
+ isNotLoaded: Signal<boolean>;
21
+ isLoading: Signal<boolean>;
22
+ isLoaded: Signal<boolean>;
23
+ isError: Signal<boolean>;
24
+ setNotLoaded(): void;
25
+ setLoading(): void;
26
+ setLoaded(): void;
27
+ setError(error: E): void;
28
+ reset(): void;
29
+ }
30
+ export declare function status<E = Error>(initialState?: LoadingState): StatusMarker<E>;
31
+ export declare function isStatusMarker(value: unknown): value is StatusMarker;
32
+ export declare function createStatusSignal<E = Error>(marker: StatusMarker<E>): StatusSignal<E>;
@@ -0,0 +1,35 @@
1
+ export declare const STORED_MARKER: unique symbol;
2
+ export type MigrationFn<T> = (oldData: unknown, oldVersion: number) => T;
3
+ export interface StoredOptions<T> {
4
+ serialize?: (value: T) => string;
5
+ deserialize?: (stored: string) => T;
6
+ storage?: Storage | null;
7
+ debounceMs?: number;
8
+ version?: number;
9
+ migrate?: MigrationFn<T>;
10
+ clearOnMigrationFailure?: boolean;
11
+ }
12
+ type StorageKeyMap<T, Prefix extends string> = {
13
+ [K in keyof T]: T[K] extends string ? `${Prefix}:${T[K] & string}` : T[K] extends object ? StorageKeyMap<T[K], `${Prefix}:${K & string}`> : never;
14
+ };
15
+ export declare function createStorageKeys<T extends object, P extends string>(prefix: P, keys: T): StorageKeyMap<T, P>;
16
+ export declare function clearStoragePrefix(prefix: string, storage?: Storage): void;
17
+ export interface StoredMarker<T> {
18
+ [STORED_MARKER]: true;
19
+ key: string;
20
+ defaultValue: T;
21
+ options: StoredOptions<T>;
22
+ }
23
+ export interface StoredSignal<T> {
24
+ (): T;
25
+ set(value: T): void;
26
+ update(fn: (current: T) => T): void;
27
+ clear(): void;
28
+ reload(): void;
29
+ readonly key: string;
30
+ readonly version: number;
31
+ }
32
+ export declare function stored<T>(key: string, defaultValue: T, options?: StoredOptions<T>): StoredMarker<T>;
33
+ export declare function isStoredMarker(value: unknown): value is StoredMarker<unknown>;
34
+ export declare function createStoredSignal<T>(marker: StoredMarker<T>): StoredSignal<T>;
35
+ export {};
@@ -0,0 +1,30 @@
1
+ import type { WritableSignal } from '@angular/core';
2
+ export interface MemoryStats {
3
+ cachedSignals: number;
4
+ cleanedUpSignals: number;
5
+ peakCachedSignals: number;
6
+ manualDisposes: number;
7
+ estimatedMemoryBytes: number;
8
+ }
9
+ export interface MemoryManagerConfig {
10
+ enableAutoCleanup?: boolean;
11
+ debugMode?: boolean;
12
+ onCleanup?: (path: string, stats: MemoryStats) => void;
13
+ }
14
+ export declare class SignalMemoryManager {
15
+ private cache;
16
+ private registry;
17
+ private config;
18
+ private stats;
19
+ constructor(config?: MemoryManagerConfig);
20
+ cacheSignal<T>(path: string, signal: WritableSignal<T>): void;
21
+ getSignal(path: string): WritableSignal<unknown> | undefined;
22
+ hasSignal(path: string): boolean;
23
+ removeSignal(path: string): boolean;
24
+ private handleCleanup;
25
+ getStats(): MemoryStats;
26
+ dispose(): void;
27
+ getCachedPaths(): string[];
28
+ clearStale(): number;
29
+ resetStats(): void;
30
+ }
@@ -0,0 +1,34 @@
1
+ export type PathNotifierInterceptor = (value: unknown, prev: unknown, path: string) => {
2
+ block?: boolean;
3
+ transform?: unknown;
4
+ };
5
+ export declare class PathNotifier {
6
+ private subscribers;
7
+ private interceptors;
8
+ private batchingEnabled;
9
+ private pendingFlush;
10
+ private pending;
11
+ private firstValues;
12
+ private flushCallbacks;
13
+ constructor(options?: {
14
+ batching?: boolean;
15
+ });
16
+ setBatchingEnabled(enabled: boolean): void;
17
+ isBatchingEnabled(): boolean;
18
+ subscribe(pattern: string, handler: PathNotifierHandler): () => void;
19
+ intercept(pattern: string, interceptor: PathNotifierInterceptor): () => void;
20
+ notify(path: string, value: unknown, prev: unknown): {
21
+ blocked: boolean;
22
+ value: unknown;
23
+ };
24
+ private _runNotify;
25
+ private flush;
26
+ flushSync(): void;
27
+ onFlush(callback: () => void): () => void;
28
+ hasPending(): boolean;
29
+ private matches;
30
+ clear(): void;
31
+ getSubscriberCount(): number;
32
+ getInterceptorCount(): number;
33
+ }
34
+ export declare function getPathNotifier(): PathNotifier;
@@ -0,0 +1,33 @@
1
+ import type { Path } from './path-index';
2
+ export declare enum ChangeType {
3
+ ADD = "add",
4
+ UPDATE = "update",
5
+ DELETE = "delete",
6
+ REPLACE = "replace"
7
+ }
8
+ export interface Change {
9
+ type: ChangeType;
10
+ path: Path;
11
+ value?: unknown;
12
+ oldValue?: unknown;
13
+ }
14
+ export interface Diff {
15
+ changes: Change[];
16
+ hasChanges: boolean;
17
+ }
18
+ export interface DiffOptions {
19
+ maxDepth?: number;
20
+ detectDeletions?: boolean;
21
+ ignoreArrayOrder?: boolean;
22
+ equalityFn?: (a: unknown, b: unknown) => boolean;
23
+ keyValidator?: (key: string) => boolean;
24
+ }
25
+ export declare class DiffEngine {
26
+ private defaultOptions;
27
+ diff(current: unknown, updates: unknown, options?: DiffOptions): Diff;
28
+ private traverse;
29
+ private diffArrays;
30
+ private diffArraysOrdered;
31
+ private diffArraysUnordered;
32
+ private stringify;
33
+ }
@@ -0,0 +1,25 @@
1
+ import type { WritableSignal } from '@angular/core';
2
+ export type PathSegment = string | number;
3
+ export type Path = PathSegment[];
4
+ export declare class PathIndex<T extends object = WritableSignal<any>> {
5
+ private root;
6
+ private pathCache;
7
+ private stats;
8
+ set(path: Path, signal: T): void;
9
+ get(path: Path): T | null;
10
+ has(path: Path): boolean;
11
+ getByPrefix(prefix: Path): Map<string, T>;
12
+ delete(path: Path): boolean;
13
+ clear(): void;
14
+ getStats(): {
15
+ hits: number;
16
+ misses: number;
17
+ sets: number;
18
+ cleanups: number;
19
+ hitRate: number;
20
+ cacheSize: number;
21
+ };
22
+ buildFromTree(tree: unknown, path?: Path): void;
23
+ private pathToString;
24
+ private collectDescendants;
25
+ }
@@ -0,0 +1,32 @@
1
+ import { PathIndex } from './path-index';
2
+ import type { DiffOptions } from './diff-engine';
3
+ export interface UpdateOptions extends DiffOptions {
4
+ batch?: boolean;
5
+ batchSize?: number;
6
+ }
7
+ export interface UpdateResult {
8
+ changed: boolean;
9
+ duration: number;
10
+ changedPaths: string[];
11
+ stats?: {
12
+ totalPaths: number;
13
+ optimizedPaths: number;
14
+ batchedUpdates: number;
15
+ };
16
+ }
17
+ export declare class OptimizedUpdateEngine {
18
+ private pathIndex;
19
+ private diffEngine;
20
+ constructor(tree: unknown);
21
+ update(tree: unknown, updates: unknown, options?: UpdateOptions): UpdateResult;
22
+ rebuildIndex(tree: unknown): void;
23
+ getIndexStats(): ReturnType<PathIndex['getStats']>;
24
+ private createPatches;
25
+ private createPatch;
26
+ private calculatePriority;
27
+ private sortPatches;
28
+ private applyPatches;
29
+ private batchApplyPatches;
30
+ private applyPatch;
31
+ private isEqual;
32
+ }
@@ -0,0 +1,34 @@
1
+ import type { ISignalTree, TreeConfig, BatchingConfig, MemoizationConfig, TimeTravelConfig, DevToolsConfig, BatchingMethods, MemoizationMethods, TimeTravelMethods, DevToolsMethods, EffectsMethods, EntitiesEnabled } from './types';
2
+ export interface DevTreeConfig extends TreeConfig {
3
+ effects?: Record<string, never>;
4
+ batching?: BatchingConfig;
5
+ memoization?: MemoizationConfig;
6
+ timeTravel?: TimeTravelConfig;
7
+ devTools?: DevToolsConfig;
8
+ entities?: Record<string, never>;
9
+ }
10
+ export interface ProdTreeConfig extends TreeConfig {
11
+ effects?: Record<string, never>;
12
+ batching?: BatchingConfig;
13
+ memoization?: MemoizationConfig;
14
+ entities?: Record<string, never>;
15
+ }
16
+ export interface MinimalTreeConfig extends TreeConfig {
17
+ effects?: Record<string, never>;
18
+ }
19
+ export type FullSignalTree<T> = ISignalTree<T> & EffectsMethods<T> & BatchingMethods & MemoizationMethods<T> & EntitiesEnabled & TimeTravelMethods & DevToolsMethods;
20
+ export type ProdSignalTree<T> = ISignalTree<T> & EffectsMethods<T> & BatchingMethods & MemoizationMethods<T> & EntitiesEnabled;
21
+ export type MinimalSignalTree<T> = ISignalTree<T> & EffectsMethods<T>;
22
+ export declare function createDevTree<T extends object>(initialState: T, config?: DevTreeConfig): FullSignalTree<T>;
23
+ export declare function createDevTree(): {
24
+ enhancer: <T>(tree: ISignalTree<T>) => ISignalTree<T> & EffectsMethods<T> & BatchingMethods<T> & MemoizationMethods<T> & EntitiesEnabled & TimeTravelMethods<T> & DevToolsMethods;
25
+ };
26
+ export declare function createProdTree<T extends object>(initialState: T, config?: ProdTreeConfig): ProdSignalTree<T>;
27
+ export declare function createMinimalTree<T extends object>(initialState: T, config?: MinimalTreeConfig): MinimalSignalTree<T>;
28
+ export declare const devTree: typeof createDevTree;
29
+ export declare const prodTree: typeof createProdTree;
30
+ export declare const minimalTree: typeof createMinimalTree;
31
+ export declare function buildTree<T extends object>(initialState: T, config?: TreeConfig): {
32
+ add<R>(enhancer: (t: ISignalTree<T>) => R): any;
33
+ done(): ISignalTree<T>;
34
+ };
@@ -0,0 +1,33 @@
1
+ export type SecurityEventType = 'dangerous-key-blocked' | 'xss-attempt-blocked' | 'function-value-blocked' | 'validation-error';
2
+ export interface SecurityEvent {
3
+ type: SecurityEventType;
4
+ key?: string;
5
+ value?: unknown;
6
+ reason: string;
7
+ timestamp: number;
8
+ }
9
+ export interface SecurityValidatorConfig {
10
+ preventPrototypePollution?: boolean;
11
+ preventXSS?: boolean;
12
+ preventFunctions?: boolean;
13
+ customDangerousKeys?: string[];
14
+ onSecurityEvent?: (event: SecurityEvent) => void;
15
+ sanitizationMode?: 'strict' | 'permissive';
16
+ }
17
+ export declare class SecurityValidator {
18
+ private readonly config;
19
+ private readonly dangerousKeys;
20
+ constructor(config?: SecurityValidatorConfig);
21
+ validateKey(key: string): void;
22
+ validateValue<T>(value: T): T;
23
+ private sanitize;
24
+ validateKeyValue<T>(key: string, value: T): T;
25
+ isDangerousKey(key: string): boolean;
26
+ getConfig(): Readonly<Required<SecurityValidatorConfig>>;
27
+ }
28
+ export declare const SecurityPresets: {
29
+ strict: () => SecurityValidator;
30
+ standard: () => SecurityValidator;
31
+ permissive: () => SecurityValidator;
32
+ disabled: () => SecurityValidator;
33
+ };
@@ -0,0 +1,6 @@
1
+ import { SignalTreeBuilder } from './internals/builder-types';
2
+ import { ProcessDerived } from './internals/derived-types';
3
+ import type { TreeNode, TreeConfig, NodeAccessor } from './types';
4
+ export declare function isNodeAccessor(value: unknown): value is NodeAccessor<unknown>;
5
+ export declare function signalTree<T extends object, TDerived extends object>(initialState: T, derivedFactory: ($: TreeNode<T>) => TDerived): SignalTreeBuilder<T, TreeNode<T> & ProcessDerived<TDerived>>;
6
+ export declare function signalTree<T extends object>(initialState: T, config?: TreeConfig): SignalTreeBuilder<T, TreeNode<T>>;