@signaltree/core 5.1.6 → 6.0.1

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 (84) hide show
  1. package/README.md +76 -76
  2. package/dist/enhancers/batching/{lib/batching.js → batching.js} +45 -17
  3. package/dist/enhancers/devtools/{lib/devtools.js → devtools.js} +83 -98
  4. package/dist/enhancers/effects/effects.js +66 -0
  5. package/dist/enhancers/entities/entities.js +51 -0
  6. package/dist/enhancers/memoization/{lib/memoization.js → memoization.js} +33 -23
  7. package/dist/enhancers/presets/lib/presets.js +5 -65
  8. package/dist/enhancers/serialization/{lib/serialization.js → serialization.js} +12 -18
  9. package/dist/enhancers/time-travel/{lib/time-travel.js → time-travel.js} +62 -24
  10. package/dist/enhancers/time-travel/utils.js +11 -0
  11. package/dist/index.js +8 -8
  12. package/dist/lib/async-helpers.js +6 -6
  13. package/dist/lib/presets.js +21 -0
  14. package/dist/lib/signal-tree.js +156 -496
  15. package/dist/lib/types.js +1 -1
  16. package/dist/lib/utils.js +40 -2
  17. package/package.json +1 -6
  18. package/src/enhancers/batching/batching.d.ts +11 -0
  19. package/src/enhancers/batching/index.d.ts +1 -1
  20. package/src/enhancers/devtools/{lib/devtools.d.ts → devtools.d.ts} +10 -19
  21. package/src/enhancers/devtools/devtools.types.d.ts +1 -0
  22. package/src/enhancers/devtools/index.d.ts +1 -1
  23. package/src/enhancers/effects/effects.d.ts +9 -0
  24. package/src/enhancers/effects/effects.types.d.ts +1 -0
  25. package/src/enhancers/effects/index.d.ts +1 -0
  26. package/src/enhancers/entities/entities.d.ts +11 -0
  27. package/src/enhancers/entities/entities.types.d.ts +1 -0
  28. package/src/enhancers/entities/index.d.ts +1 -1
  29. package/src/enhancers/index.d.ts +3 -3
  30. package/src/enhancers/memoization/index.d.ts +1 -1
  31. package/src/enhancers/memoization/memoization.d.ts +54 -0
  32. package/src/enhancers/memoization/memoization.types.d.ts +1 -0
  33. package/src/enhancers/presets/lib/presets.d.ts +3 -6
  34. package/src/enhancers/serialization/index.d.ts +1 -1
  35. package/src/{serialization.d.ts → enhancers/serialization/serialization.d.ts} +17 -8
  36. package/src/enhancers/test-helpers/types-equals.d.ts +2 -0
  37. package/src/enhancers/time-travel/index.d.ts +1 -1
  38. package/src/enhancers/time-travel/time-travel.d.ts +10 -0
  39. package/src/enhancers/time-travel/time-travel.types.d.ts +1 -0
  40. package/src/enhancers/time-travel/utils.d.ts +2 -0
  41. package/src/enhancers/types.d.ts +1 -74
  42. package/src/enhancers/typing/helpers-types.d.ts +2 -0
  43. package/src/index.d.ts +7 -8
  44. package/src/lib/async-helpers.d.ts +2 -2
  45. package/src/lib/dev-proxy.d.ts +3 -0
  46. package/src/lib/presets.d.ts +34 -0
  47. package/src/lib/signal-tree.d.ts +2 -7
  48. package/src/lib/types.d.ts +121 -90
  49. package/src/lib/utils.d.ts +4 -0
  50. package/dist/deep-clone.js +0 -80
  51. package/dist/enhancers/computed/lib/computed.js +0 -21
  52. package/dist/enhancers/entities/lib/entities.js +0 -66
  53. package/dist/lib/performance/diff-engine.js +0 -156
  54. package/dist/lib/performance/path-index.js +0 -156
  55. package/dist/lib/performance/update-engine.js +0 -188
  56. package/src/async-helpers.d.ts +0 -8
  57. package/src/batching.d.ts +0 -16
  58. package/src/computed.d.ts +0 -12
  59. package/src/constants.d.ts +0 -14
  60. package/src/devtools.d.ts +0 -77
  61. package/src/diff-engine.d.ts +0 -33
  62. package/src/enhancers/batching/lib/batching.d.ts +0 -16
  63. package/src/enhancers/computed/index.d.ts +0 -1
  64. package/src/enhancers/computed/lib/computed.d.ts +0 -12
  65. package/src/enhancers/entities/lib/entities.d.ts +0 -17
  66. package/src/enhancers/memoization/lib/memoization.d.ts +0 -65
  67. package/src/enhancers/presets/test-setup.d.ts +0 -3
  68. package/src/enhancers/serialization/lib/serialization.d.ts +0 -59
  69. package/src/enhancers/time-travel/lib/time-travel.d.ts +0 -36
  70. package/src/enhancers/time-travel/lib/utils.d.ts +0 -1
  71. package/src/entities.d.ts +0 -28
  72. package/src/memoization.d.ts +0 -65
  73. package/src/memory-manager.d.ts +0 -30
  74. package/src/path-index.d.ts +0 -25
  75. package/src/path-notifier.d.ts +0 -12
  76. package/src/presets.d.ts +0 -11
  77. package/src/security-validator.d.ts +0 -33
  78. package/src/signal-tree.d.ts +0 -8
  79. package/src/test-setup.d.ts +0 -3
  80. package/src/time-travel.d.ts +0 -36
  81. package/src/types.d.ts +0 -436
  82. package/src/update-engine.d.ts +0 -32
  83. package/src/utils.d.ts +0 -1
  84. /package/src/{entity-signal.d.ts → enhancers/batching/batching.types.d.ts} +0 -0
package/src/types.d.ts DELETED
@@ -1,436 +0,0 @@
1
- import { Signal, WritableSignal } from '@angular/core';
2
-
3
- import type { SecurityValidatorConfig } from './security/security-validator';
4
- export type NotFn<T> = T extends (...args: unknown[]) => unknown ? never : T;
5
- declare module '@angular/core' {
6
- interface WritableSignal<T> {
7
- (value: NotFn<T>): void;
8
- (updater: (current: T) => T): void;
9
- }
10
- }
11
- export type Primitive =
12
- | string
13
- | number
14
- | boolean
15
- | null
16
- | undefined
17
- | bigint
18
- | symbol;
19
- export type BuiltInObject =
20
- | Date
21
- | RegExp
22
- | ((...args: unknown[]) => unknown)
23
- | Map<unknown, unknown>
24
- | Set<unknown>
25
- | WeakMap<object, unknown>
26
- | WeakSet<object>
27
- | ArrayBuffer
28
- | DataView
29
- | Error
30
- | Promise<unknown>
31
- | Uint16Array
32
- | Int32Array
33
- | Uint32Array
34
- | Float32Array
35
- | Float64Array
36
- | BigInt64Array
37
- | BigUint64Array
38
- | URL
39
- | URLSearchParams
40
- | FormData
41
- | Blob
42
- | File
43
- | Headers
44
- | Request
45
- | Response
46
- | AbortController
47
- | AbortSignal;
48
- export type Unwrap<T> = [T] extends [WritableSignal<infer U>]
49
- ? U
50
- : [T] extends [Signal<infer U>]
51
- ? U
52
- : [T] extends [BuiltInObject]
53
- ? T
54
- : [T] extends [readonly unknown[]]
55
- ? T
56
- : [T] extends [EntityMapMarker<infer E, infer K>]
57
- ? EntitySignal<E, K>
58
- : [T] extends [object]
59
- ? {
60
- [K in keyof T]: Unwrap<T[K]>;
61
- }
62
- : T;
63
- export interface NodeAccessor<T> {
64
- (): T;
65
- (value: T): void;
66
- (updater: (current: T) => T): void;
67
- }
68
- export type AccessibleNode<T> = NodeAccessor<T> & TreeNode<T>;
69
- export type CallableWritableSignal<T> = WritableSignal<T> & {
70
- (value: NotFn<T>): void;
71
- (updater: (current: T) => T): void;
72
- };
73
- export type TreeNode<T> = {
74
- [K in keyof T]: [T[K]] extends [EntityMapMarker<infer E, infer Key>]
75
- ? EntitySignal<E, Key>
76
- : [T[K]] extends [readonly unknown[]]
77
- ? CallableWritableSignal<T[K]>
78
- : [T[K]] extends [object]
79
- ? [T[K]] extends [Signal<unknown>]
80
- ? T[K]
81
- : [T[K]] extends [BuiltInObject]
82
- ? CallableWritableSignal<T[K]>
83
- : [T[K]] extends [(...args: unknown[]) => unknown]
84
- ? CallableWritableSignal<T[K]>
85
- : AccessibleNode<T[K]>
86
- : CallableWritableSignal<T[K]>;
87
- };
88
- export type RemoveSignalMethods<T> = T extends infer U ? U : never;
89
- export type DeepPath<
90
- T,
91
- Prefix extends string = '',
92
- Depth extends readonly number[] = []
93
- > = Depth['length'] extends 5
94
- ? never
95
- : {
96
- [K in keyof T]: K extends string
97
- ? T[K] extends readonly unknown[]
98
- ? `${Prefix}${K}`
99
- : T[K] extends object
100
- ? T[K] extends Signal<unknown>
101
- ? never
102
- : T[K] extends BuiltInObject
103
- ? never
104
- : T[K] extends (...args: unknown[]) => unknown
105
- ? never
106
- : `${Prefix}${K}` | DeepPath<T[K], `${Prefix}${K}.`, [...Depth, 1]>
107
- : never
108
- : never;
109
- }[keyof T];
110
- export type DeepAccess<
111
- T,
112
- Path extends string
113
- > = Path extends `${infer First}.${infer Rest}`
114
- ? First extends keyof T
115
- ? DeepAccess<T[First] & object, Rest>
116
- : never
117
- : Path extends keyof T
118
- ? T[Path]
119
- : never;
120
- export interface EnhancerMeta {
121
- name?: string;
122
- requires?: string[];
123
- provides?: string[];
124
- }
125
- export type Enhancer<Input = unknown, Output = unknown> = (
126
- input: Input
127
- ) => Output;
128
- export type EnhancerWithMeta<Input = unknown, Output = unknown> = Enhancer<
129
- Input,
130
- Output
131
- > & {
132
- metadata?: EnhancerMeta;
133
- };
134
- export declare const ENHANCER_META: unique symbol;
135
- export type ChainResult<
136
- Start,
137
- E extends Array<EnhancerWithMeta<unknown, unknown>>
138
- > = E extends [infer H, ...infer R]
139
- ? H extends EnhancerWithMeta<SignalTree<unknown>, infer O>
140
- ? R extends Array<EnhancerWithMeta<unknown, unknown>>
141
- ? ChainResult<O, R>
142
- : O
143
- : H extends EnhancerWithMeta<infer I, infer O>
144
- ? Start extends I
145
- ? R extends Array<EnhancerWithMeta<unknown, unknown>>
146
- ? ChainResult<O, R>
147
- : O
148
- : unknown
149
- : unknown
150
- : Start;
151
- export interface WithMethod<T> {
152
- (): SignalTree<T>;
153
- <O>(enhancer: (input: SignalTree<T>) => O): O;
154
- <O1, O2>(e1: (input: SignalTree<T>) => O1, e2: (input: O1) => O2): O2;
155
- <O1, O2, O3>(
156
- e1: (input: SignalTree<T>) => O1,
157
- e2: (input: O1) => O2,
158
- e3: (input: O2) => O3
159
- ): O3;
160
- <O>(enhancer: EnhancerWithMeta<SignalTree<T>, O>): O;
161
- <O1, O2>(
162
- e1: EnhancerWithMeta<SignalTree<T>, O1>,
163
- e2: EnhancerWithMeta<O1, O2>
164
- ): O2;
165
- <O1, O2, O3>(
166
- e1: EnhancerWithMeta<SignalTree<T>, O1>,
167
- e2: EnhancerWithMeta<O1, O2>,
168
- e3: EnhancerWithMeta<O2, O3>
169
- ): O3;
170
- }
171
- export type SignalTree<T> = NodeAccessor<T> & {
172
- state: TreeNode<T>;
173
- $: TreeNode<T>;
174
- with: WithMethod<T>;
175
- destroy(): void;
176
- dispose?(): void;
177
- effect(fn: (tree: T) => void): void;
178
- subscribe(fn: (tree: T) => void): () => void;
179
- batch(updater: (tree: T) => void): void;
180
- batchUpdate(updater: (current: T) => Partial<T>): void;
181
- memoize<R>(fn: (tree: T) => R, cacheKey?: string): Signal<R>;
182
- memoizedUpdate(updater: (current: T) => Partial<T>, cacheKey?: string): void;
183
- clearMemoCache(key?: string): void;
184
- getCacheStats(): {
185
- size: number;
186
- hitRate: number;
187
- totalHits: number;
188
- totalMisses: number;
189
- keys: string[];
190
- };
191
- optimize(): void;
192
- clearCache(): void;
193
- invalidatePattern(pattern: string): number;
194
- updateOptimized?(
195
- updates: Partial<T>,
196
- options?: {
197
- batch?: boolean;
198
- batchSize?: number;
199
- maxDepth?: number;
200
- ignoreArrayOrder?: boolean;
201
- equalityFn?: (a: unknown, b: unknown) => boolean;
202
- }
203
- ): {
204
- changed: boolean;
205
- duration: number;
206
- changedPaths: string[];
207
- stats?: {
208
- totalPaths: number;
209
- optimizedPaths: number;
210
- batchedUpdates: number;
211
- };
212
- };
213
- entities<
214
- E extends {
215
- id: string | number;
216
- }
217
- >(
218
- entityKey?: keyof T
219
- ): EntityHelpers<E>;
220
- undo(): void;
221
- redo(): void;
222
- getHistory(): TimeTravelEntry<T>[];
223
- resetHistory(): void;
224
- jumpTo?: (index: number) => void;
225
- canUndo?: () => boolean;
226
- canRedo?: () => boolean;
227
- getCurrentIndex?: () => number;
228
- };
229
- export type TreePreset = 'basic' | 'performance' | 'development' | 'production';
230
- export interface TreeConfig {
231
- batchUpdates?: boolean;
232
- useMemoization?: boolean;
233
- enableTimeTravel?: boolean;
234
- useLazySignals?: boolean;
235
- useShallowComparison?: boolean;
236
- maxCacheSize?: number;
237
- trackPerformance?: boolean;
238
- treeName?: string;
239
- enableDevTools?: boolean;
240
- debugMode?: boolean;
241
- useStructuralSharing?: boolean;
242
- security?: SecurityValidatorConfig;
243
- }
244
- export interface EntityConfig<E, K extends string | number = string> {
245
- selectId?: (entity: E) => K;
246
- hooks?: {
247
- beforeAdd?: (entity: E) => E | false;
248
- beforeUpdate?: (id: K, changes: Partial<E>) => Partial<E> | false;
249
- beforeRemove?: (id: K, entity: E) => boolean;
250
- };
251
- }
252
- declare const ENTITY_MAP_BRAND: unique symbol;
253
- export interface EntityMapMarker<E, K extends string | number> {
254
- readonly [ENTITY_MAP_BRAND]: {
255
- __entity: E;
256
- __key: K;
257
- };
258
- readonly __isEntityMap: true;
259
- readonly __entityMapConfig?: EntityConfig<E, K>;
260
- }
261
- export declare function entityMap<
262
- E,
263
- K extends string | number = E extends {
264
- id: infer I extends string | number;
265
- }
266
- ? I
267
- : string
268
- >(config?: EntityConfig<E, K>): EntityMapMarker<E, K>;
269
- export interface MutationOptions {
270
- onError?: (error: Error) => void;
271
- }
272
- export interface AddOptions<E, K> extends MutationOptions {
273
- selectId?: (entity: E) => K;
274
- }
275
- export interface AddManyOptions<E, K> extends AddOptions<E, K> {
276
- mode?: 'strict' | 'skip' | 'overwrite';
277
- }
278
- export interface TapHandlers<E, K extends string | number> {
279
- onAdd?: (entity: E, id: K) => void;
280
- onUpdate?: (id: K, changes: Partial<E>, entity: E) => void;
281
- onRemove?: (id: K, entity: E) => void;
282
- onChange?: () => void;
283
- }
284
- export interface InterceptContext<T> {
285
- block(reason?: string): void;
286
- transform(value: T): void;
287
- readonly blocked: boolean;
288
- readonly blockReason: string | undefined;
289
- }
290
- export interface InterceptHandlers<E, K extends string | number> {
291
- onAdd?: (entity: E, ctx: InterceptContext<E>) => void | Promise<void>;
292
- onUpdate?: (
293
- id: K,
294
- changes: Partial<E>,
295
- ctx: InterceptContext<Partial<E>>
296
- ) => void | Promise<void>;
297
- onRemove?: (
298
- id: K,
299
- entity: E,
300
- ctx: InterceptContext<void>
301
- ) => void | Promise<void>;
302
- }
303
- export type EntityNode<E> = {
304
- (): E;
305
- (value: E): void;
306
- (updater: (current: E) => E): void;
307
- } & {
308
- [P in keyof E]: E[P] extends object
309
- ? E[P] extends readonly unknown[]
310
- ? CallableWritableSignal<E[P]>
311
- : EntityNode<E[P]>
312
- : CallableWritableSignal<E[P]>;
313
- };
314
- export interface EntitySignal<E, K extends string | number = string> {
315
- byId(id: K): EntityNode<E> | undefined;
316
- byIdOrFail(id: K): EntityNode<E>;
317
- readonly all: Signal<E[]>;
318
- readonly count: Signal<number>;
319
- readonly ids: Signal<K[]>;
320
- has(id: K): Signal<boolean>;
321
- readonly isEmpty: Signal<boolean>;
322
- readonly map: Signal<ReadonlyMap<K, E>>;
323
- where(predicate: (entity: E) => boolean): Signal<E[]>;
324
- find(predicate: (entity: E) => boolean): Signal<E | undefined>;
325
- addOne(entity: E, opts?: AddOptions<E, K>): K;
326
- addMany(entities: E[], opts?: AddManyOptions<E, K>): K[];
327
- updateOne(id: K, changes: Partial<E>, opts?: MutationOptions): void;
328
- updateMany(ids: K[], changes: Partial<E>, opts?: MutationOptions): void;
329
- updateWhere(predicate: (entity: E) => boolean, changes: Partial<E>): number;
330
- upsertOne(entity: E, opts?: AddOptions<E, K>): K;
331
- upsertMany(entities: E[], opts?: AddOptions<E, K>): K[];
332
- removeOne(id: K, opts?: MutationOptions): void;
333
- removeMany(ids: K[], opts?: MutationOptions): void;
334
- removeWhere(predicate: (entity: E) => boolean): number;
335
- clear(): void;
336
- removeAll(): void;
337
- setAll(entities: E[], opts?: AddOptions<E, K>): void;
338
- tap(handlers: TapHandlers<E, K>): () => void;
339
- intercept(handlers: InterceptHandlers<E, K>): () => void;
340
- }
341
- export interface EntityHelpers<
342
- E extends {
343
- id: string | number;
344
- }
345
- > {
346
- add(entity: E): void;
347
- update(id: E['id'], updates: Partial<E>): void;
348
- remove(id: E['id']): void;
349
- upsert(entity: E): void;
350
- selectById(id: E['id']): Signal<E | undefined>;
351
- selectBy(predicate: (entity: E) => boolean): Signal<E[]>;
352
- selectIds(): Signal<Array<string | number>>;
353
- selectAll(): Signal<E[]>;
354
- selectTotal(): Signal<number>;
355
- clear(): void;
356
- }
357
- export interface LoggingConfig {
358
- name?: string;
359
- filter?: (path: string) => boolean;
360
- collapsed?: boolean;
361
- onLog?: (entry: LogEntry) => void;
362
- }
363
- export interface LogEntry {
364
- path: string;
365
- prev: unknown;
366
- value: unknown;
367
- timestamp: number;
368
- }
369
- export interface ValidationConfig<T> {
370
- validators: Array<{
371
- match: (path: string) => boolean;
372
- validate: (value: T, path: string) => void | never;
373
- }>;
374
- onError?: (error: Error, path: string) => void;
375
- }
376
- export interface PersistenceConfig {
377
- key: string;
378
- storage?: Storage;
379
- debounceMs?: number;
380
- filter?: (path: string) => boolean;
381
- serialize?: (state: unknown) => string;
382
- deserialize?: (json: string) => unknown;
383
- }
384
- export interface DevToolsConfig {
385
- name?: string;
386
- maxAge?: number;
387
- features?: {
388
- jump?: boolean;
389
- skip?: boolean;
390
- reorder?: boolean;
391
- };
392
- }
393
- export type EntityType<T> = T extends EntitySignal<
394
- infer E,
395
- infer K extends string | number
396
- >
397
- ? E
398
- : never;
399
- export type EntityKeyType<T> = T extends EntitySignal<
400
- unknown,
401
- infer K extends string | number
402
- >
403
- ? K
404
- : never;
405
- export type IsEntityMap<T> = T extends EntityMapMarker<
406
- unknown,
407
- infer K extends string | number
408
- >
409
- ? true
410
- : false;
411
- export type EntityAwareTreeNode<T> = {
412
- [K in keyof T]: T[K] extends EntityMapMarker<infer E, infer Key>
413
- ? EntitySignal<E, Key>
414
- : T[K] extends object
415
- ? EntityAwareTreeNode<T[K]>
416
- : CallableWritableSignal<T[K]>;
417
- };
418
- export type PathHandler = (value: unknown, prev: unknown, path: string) => void;
419
- export type PathInterceptor = (
420
- ctx: {
421
- path: string;
422
- value: unknown;
423
- prev: unknown;
424
- blocked: boolean;
425
- blockReason?: string;
426
- },
427
- next: () => void
428
- ) => void | Promise<void>;
429
- export interface TimeTravelEntry<T> {
430
- action: string;
431
- timestamp: number;
432
- state: T;
433
- payload?: unknown;
434
- }
435
- export declare function isSignalTree<T>(value: unknown): value is SignalTree<T>;
436
- export {};
@@ -1,32 +0,0 @@
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
- }
package/src/utils.d.ts DELETED
@@ -1 +0,0 @@
1
- export { deepClone, deepEqual } from '@signaltree/shared';