@signaltree/core 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -18
- package/fesm2022/signaltree-core.mjs +361 -434
- package/fesm2022/signaltree-core.mjs.map +1 -1
- package/index.d.ts +1 -213
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,69 +1,22 @@
|
|
|
1
1
|
import { Signal, WritableSignal } from '@angular/core';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* SignalTree Core Types - Recursive Typing System
|
|
5
|
-
*
|
|
6
|
-
* COPYRIGHT NOTICE:
|
|
7
|
-
* This file contains proprietary recursive typing innovations protected under
|
|
8
|
-
* the SignalTree license. The DeepSignalify<T> recursive type system and
|
|
9
|
-
* related implementations are exclusive intellectual property of Jonathan D Borgia.
|
|
10
|
-
*
|
|
11
|
-
* Unauthorized extraction, copying, or reimplementation of these recursive typing
|
|
12
|
-
* concepts is strictly prohibited and constitutes copyright infringement.
|
|
13
|
-
*
|
|
14
|
-
* Licensed under Fair Source License - see LICENSE file for complete terms.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* NO MORE StateObject constraint!
|
|
19
|
-
* We don't need this at all - remove it or make it accept anything
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* Primitive types for type checking
|
|
23
|
-
*/
|
|
24
3
|
type Primitive = string | number | boolean | null | undefined | bigint | symbol;
|
|
25
|
-
/**
|
|
26
|
-
* Built-in object types that should be treated as primitive values
|
|
27
|
-
* Enhanced detection for better edge case handling
|
|
28
|
-
*/
|
|
29
4
|
type BuiltInObject = Date | RegExp | ((...args: unknown[]) => unknown) | Map<unknown, unknown> | Set<unknown> | WeakMap<object, unknown> | WeakSet<object> | ArrayBuffer | DataView | Error | Promise<unknown> | URL | URLSearchParams | FormData | Blob | File;
|
|
30
5
|
type IsPrimitive<T> = T extends Primitive ? true : false;
|
|
31
6
|
type IsBuiltInObject<T> = T extends BuiltInObject ? true : false;
|
|
32
|
-
/**
|
|
33
|
-
* Signal detection
|
|
34
|
-
*/
|
|
35
7
|
type IsSignal<T> = T extends Signal<unknown> ? true : false;
|
|
36
8
|
type IsWritableSignal<T> = T extends WritableSignal<unknown> ? true : false;
|
|
37
|
-
/**
|
|
38
|
-
* Enhanced DeepSignalify with better edge case handling
|
|
39
|
-
* Never double-wraps signals and properly handles functions and built-in objects
|
|
40
|
-
*/
|
|
41
9
|
type DeepSignalify<T> = IsSignal<T> extends true ? T : T extends Primitive ? WritableSignal<T> : T extends BuiltInObject ? WritableSignal<T> : T extends readonly (infer U)[] ? WritableSignal<U[]> : T extends (infer U)[] ? WritableSignal<U[]> : T extends object ? T extends (...args: unknown[]) => unknown ? WritableSignal<T> : {
|
|
42
10
|
[K in keyof T]: T[K] extends (infer U)[] ? WritableSignal<U[]> : T[K] extends BuiltInObject ? WritableSignal<T[K]> : T[K] extends object ? T[K] extends Signal<infer TK> ? WritableSignal<TK> : DeepSignalify<T[K]> : WritableSignal<T[K]>;
|
|
43
11
|
} : WritableSignal<T>;
|
|
44
|
-
/**
|
|
45
|
-
* SignalTree type - NO CONSTRAINTS on T
|
|
46
|
-
*/
|
|
47
12
|
type SignalTree<T> = {
|
|
48
|
-
/**
|
|
49
|
-
* The reactive state object with deep signal conversion
|
|
50
|
-
*/
|
|
51
13
|
state: DeepSignalify<T>;
|
|
52
|
-
/**
|
|
53
|
-
* Shorthand alias for state
|
|
54
|
-
*/
|
|
55
14
|
$: DeepSignalify<T>;
|
|
56
|
-
/**
|
|
57
|
-
* Core methods
|
|
58
|
-
*/
|
|
59
15
|
unwrap(): T;
|
|
60
16
|
update(updater: (current: T) => Partial<T>): void;
|
|
61
17
|
effect(fn: (tree: T) => void): void;
|
|
62
18
|
subscribe(fn: (tree: T) => void): () => void;
|
|
63
19
|
destroy(): void;
|
|
64
|
-
/**
|
|
65
|
-
* Pipe method for composition
|
|
66
|
-
*/
|
|
67
20
|
pipe(): SignalTree<T>;
|
|
68
21
|
pipe<R1>(fn1: (tree: SignalTree<T>) => R1): R1;
|
|
69
22
|
pipe<R1, R2>(fn1: (tree: SignalTree<T>) => R1, fn2: (arg: R1) => R2): R2;
|
|
@@ -145,182 +98,17 @@ interface TimeTravelEntry<T> {
|
|
|
145
98
|
payload: unknown;
|
|
146
99
|
}
|
|
147
100
|
|
|
148
|
-
/**
|
|
149
|
-
* SignalTree Core Implementation - Recursive Typing Engine
|
|
150
|
-
*
|
|
151
|
-
* COPYRIGHT NOTICE:
|
|
152
|
-
* This file contains the proprietary recursive typing implementation protected
|
|
153
|
-
* under the SignalTree license. The signal-store pattern, recursive type-runtime
|
|
154
|
-
* alignment, and "initiation defines structure" paradigm are exclusive intellectual
|
|
155
|
-
* property of Jonathan D Borgia.
|
|
156
|
-
*
|
|
157
|
-
* The createSignalStore and createLazySignalTree functions implement patented
|
|
158
|
-
* approaches to recursive type preservation that are strictly protected.
|
|
159
|
-
*
|
|
160
|
-
* Licensed under Fair Source License - see LICENSE file for complete terms.
|
|
161
|
-
*/
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Creates a reactive signal tree with smart progressive enhancement.
|
|
165
|
-
*
|
|
166
|
-
* MAXIMUM FLEXIBILITY: Accepts ANY type T - no StateObject constraint!
|
|
167
|
-
* This is the key difference from constrained approaches.
|
|
168
|
-
*
|
|
169
|
-
* Features auto-enable on first use. Uses intelligent defaults based on
|
|
170
|
-
* environment (development vs production). Enhanced with safety features
|
|
171
|
-
* to prevent common issues like signal double-wrapping.
|
|
172
|
-
*
|
|
173
|
-
* @template T - ANY type (no constraints for maximum flexibility)
|
|
174
|
-
* @param obj - The initial state object to convert into a reactive tree
|
|
175
|
-
* @returns A SignalTree with auto-enabling features
|
|
176
|
-
*
|
|
177
|
-
* @example
|
|
178
|
-
* ```typescript
|
|
179
|
-
* // Works with ANY object - no constraints!
|
|
180
|
-
* const tree = signalTree({
|
|
181
|
-
* count: 0,
|
|
182
|
-
* users: [],
|
|
183
|
-
* metadata: new Map(), // Non-plain objects work!
|
|
184
|
-
* fn: () => 'hello', // Functions work!
|
|
185
|
-
* symbol: Symbol('id') // Symbols work!
|
|
186
|
-
* });
|
|
187
|
-
*
|
|
188
|
-
* // Core functionality always works
|
|
189
|
-
* tree.state.count.set(5);
|
|
190
|
-
* tree.update(state => ({ count: state.count + 1 }));
|
|
191
|
-
*
|
|
192
|
-
* // Composition with pipe
|
|
193
|
-
* tree.pipe(
|
|
194
|
-
* withBatching(),
|
|
195
|
-
* withMemoization(),
|
|
196
|
-
* withTimeTravel()
|
|
197
|
-
* );
|
|
198
|
-
* ```
|
|
199
|
-
*/
|
|
200
101
|
declare function signalTree<T>(obj: T): SignalTree<T>;
|
|
201
|
-
/**
|
|
202
|
-
* Creates a reactive signal tree with preset configuration.
|
|
203
|
-
*
|
|
204
|
-
* Uses predefined configurations for common scenarios while still
|
|
205
|
-
* allowing features to auto-enable as needed.
|
|
206
|
-
*
|
|
207
|
-
* @template T - The state object type, must extend Record<string, unknown>
|
|
208
|
-
* @param obj - The initial state object to convert into a reactive tree
|
|
209
|
-
* @param preset - Preset configuration ('basic', 'performance', 'development', 'production')
|
|
210
|
-
* @returns A SignalTree configured with the specified preset
|
|
211
|
-
*
|
|
212
|
-
* @example
|
|
213
|
-
* ```typescript
|
|
214
|
-
* // Optimized for production
|
|
215
|
-
* const prodTree = signalTree(state, 'production');
|
|
216
|
-
*
|
|
217
|
-
* // Full debugging capabilities
|
|
218
|
-
* const devTree = signalTree(state, 'development');
|
|
219
|
-
*
|
|
220
|
-
* // Maximum performance
|
|
221
|
-
* const perfTree = signalTree(state, 'performance');
|
|
222
|
-
* ```
|
|
223
|
-
*/
|
|
224
102
|
declare function signalTree<T>(obj: T, preset: TreePreset): SignalTree<T>;
|
|
225
|
-
/**
|
|
226
|
-
* Creates a reactive signal tree with custom configuration.
|
|
227
|
-
*
|
|
228
|
-
* Provides full control over feature enablement while maintaining
|
|
229
|
-
* auto-enabling behavior for unspecified features. Enhanced with safety features.
|
|
230
|
-
*
|
|
231
|
-
* @template T - ANY type (no constraints for maximum flexibility)
|
|
232
|
-
* @param obj - The initial state object to convert into a reactive tree
|
|
233
|
-
* @param config - Custom configuration object
|
|
234
|
-
* @returns A SignalTree configured with custom options
|
|
235
|
-
*
|
|
236
|
-
* @example
|
|
237
|
-
* ```typescript
|
|
238
|
-
* // Custom configuration - works with ANY object!
|
|
239
|
-
* const customTree = signalTree({
|
|
240
|
-
* data: state,
|
|
241
|
-
* metadata: new Map(), // Any object type
|
|
242
|
-
* fn: () => 'custom' // Even functions
|
|
243
|
-
* }, {
|
|
244
|
-
* batchUpdates: true,
|
|
245
|
-
* useMemoization: true,
|
|
246
|
-
* maxCacheSize: 500,
|
|
247
|
-
* treeName: 'MyApp'
|
|
248
|
-
* });
|
|
249
|
-
* ```
|
|
250
|
-
*/
|
|
251
103
|
declare function signalTree<T>(obj: T, config: TreeConfig): SignalTree<T>;
|
|
252
|
-
/**
|
|
253
|
-
* Implementation of the signalTree factory function.
|
|
254
|
-
*/
|
|
255
|
-
/**
|
|
256
|
-
* Main SignalTree factory function with superior type inference
|
|
257
|
-
*
|
|
258
|
-
* Key improvements from signal-store.ts approach:
|
|
259
|
-
* 1. Uses Required<T> for better type inference when possible
|
|
260
|
-
* 2. Maintains complete type information through recursion
|
|
261
|
-
* 3. Proper handling of nested objects and arrays
|
|
262
|
-
* 4. No type constraints - maximum flexibility
|
|
263
|
-
*/
|
|
264
104
|
declare function signalTree<T extends Record<string, unknown>>(obj: Required<T>, configOrPreset?: TreeConfig | TreePreset): SignalTree<Required<T>>;
|
|
265
105
|
declare function signalTree<T>(obj: T, configOrPreset?: TreeConfig | TreePreset): SignalTree<T>;
|
|
266
106
|
|
|
267
|
-
/**
|
|
268
|
-
* SignalTree Utility Functions - Recursive Typing Implementation
|
|
269
|
-
*
|
|
270
|
-
* COPYRIGHT NOTICE:
|
|
271
|
-
* This file contains proprietary utility functions for the recursive typing system.
|
|
272
|
-
* The createLazySignalTree function and built-in object detection methods are
|
|
273
|
-
* protected intellectual property of Jonathan D Borgia.
|
|
274
|
-
*
|
|
275
|
-
* Licensed under Fair Source License - see LICENSE file for complete terms.
|
|
276
|
-
*/
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Enhanced equality function inspired by the monolithic implementation.
|
|
280
|
-
* Uses deep equality for arrays and objects, === for primitives.
|
|
281
|
-
* Optimized with early exits and type-specific comparisons.
|
|
282
|
-
*/
|
|
283
107
|
declare function equal<T>(a: T, b: T): boolean;
|
|
284
|
-
/**
|
|
285
|
-
* Creates a terminal signal with the enhanced equality function.
|
|
286
|
-
* This should be used instead of Angular's signal() when you want
|
|
287
|
-
* the same deep equality behavior as signalTree.
|
|
288
|
-
*
|
|
289
|
-
* Inspired by the monolithic implementation's terminal signal creation.
|
|
290
|
-
*/
|
|
291
108
|
declare function terminalSignal<T>(value: T, customEqual?: (a: T, b: T) => boolean): WritableSignal<T>;
|
|
292
|
-
/**
|
|
293
|
-
* Parses a dot-notation path into an array of keys with LRU memoization.
|
|
294
|
-
* Critical for performance when accessing nested properties frequently.
|
|
295
|
-
* Includes proper LRU cache management to prevent memory leaks.
|
|
296
|
-
*
|
|
297
|
-
* @example
|
|
298
|
-
* ```typescript
|
|
299
|
-
* const keys1 = parsePath('user.name'); // Splits and caches
|
|
300
|
-
* const keys2 = parsePath('user.name'); // Returns cached result
|
|
301
|
-
* ```
|
|
302
|
-
*/
|
|
303
109
|
declare function parsePath(path: string): string[];
|
|
304
|
-
/**
|
|
305
|
-
* Creates a lazy signal tree using Proxy for on-demand signal creation.
|
|
306
|
-
* Only creates signals when properties are first accessed, providing
|
|
307
|
-
* massive memory savings for large state objects.
|
|
308
|
-
* Uses WeakMap for memory-safe caching.
|
|
309
|
-
*
|
|
310
|
-
* @param obj - Source object to lazily signalify
|
|
311
|
-
* @param equalityFn - Equality function for signal comparison
|
|
312
|
-
* @param basePath - Base path for nested objects (internal use)
|
|
313
|
-
* @returns Proxied object that creates signals on first access
|
|
314
|
-
*/
|
|
315
110
|
declare function createLazySignalTree<T extends object>(obj: T, equalityFn: (a: unknown, b: unknown) => boolean, basePath?: string): DeepSignalify<T>;
|
|
316
|
-
|
|
317
|
-
* Native deep equality check for arrays and objects.
|
|
318
|
-
* Handles all common cases that lodash.isEqual handles for our use cases.
|
|
319
|
-
*/
|
|
320
|
-
declare function deepEqual<T>(a: T, b: T): boolean;
|
|
321
|
-
/**
|
|
322
|
-
* Shallow equality check for objects and arrays.
|
|
323
|
-
*/
|
|
111
|
+
declare const deepEqual: typeof equal;
|
|
324
112
|
declare function shallowEqual<T>(a: T, b: T): boolean;
|
|
325
113
|
|
|
326
114
|
export { createLazySignalTree, deepEqual, equal, parsePath, shallowEqual, signalTree, terminalSignal };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaltree/core",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Lightweight, type-safe signal-based state management for Angular. Core package providing hierarchical signal trees, basic entity management, and async actions.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/core": "^20.1.0"
|