@pulse-js/core 0.2.1 → 0.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.
- package/README.md +43 -118
- package/dist/index.cjs +346 -62
- package/dist/index.d.cts +167 -31
- package/dist/index.d.ts +167 -31
- package/dist/index.js +338 -61
- package/package.json +4 -2
package/dist/index.d.cts
CHANGED
|
@@ -179,9 +179,9 @@ interface GuardState<T> {
|
|
|
179
179
|
/** The value returned by the evaluator (only if status is 'ok'). */
|
|
180
180
|
value?: T;
|
|
181
181
|
/** The reason why the guard failed. */
|
|
182
|
-
reason?:
|
|
182
|
+
reason?: GuardReason;
|
|
183
183
|
/** The last known failure reason, persisted even during 'pending'. */
|
|
184
|
-
lastReason?:
|
|
184
|
+
lastReason?: GuardReason;
|
|
185
185
|
/** The timestamp when the status last changed. */
|
|
186
186
|
updatedAt?: number;
|
|
187
187
|
}
|
|
@@ -191,14 +191,14 @@ interface GuardState<T> {
|
|
|
191
191
|
interface GuardExplanation {
|
|
192
192
|
name: string;
|
|
193
193
|
status: GuardStatus;
|
|
194
|
-
reason?:
|
|
195
|
-
lastReason?:
|
|
194
|
+
reason?: GuardReason;
|
|
195
|
+
lastReason?: GuardReason;
|
|
196
196
|
value?: any;
|
|
197
197
|
dependencies: Array<{
|
|
198
198
|
name: string;
|
|
199
199
|
type: 'source' | 'guard';
|
|
200
200
|
status?: GuardStatus;
|
|
201
|
-
reason?:
|
|
201
|
+
reason?: GuardReason;
|
|
202
202
|
}>;
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
@@ -237,9 +237,9 @@ interface Guard<T = boolean> {
|
|
|
237
237
|
* Returns the failure reason message if the guard is in the 'fail' state.
|
|
238
238
|
* Useful for displaying semantic error messages in the UI.
|
|
239
239
|
*
|
|
240
|
-
* @returns The error message or undefined.
|
|
240
|
+
* @returns The error message object or undefined.
|
|
241
241
|
*/
|
|
242
|
-
reason():
|
|
242
|
+
reason(): GuardReason | undefined;
|
|
243
243
|
/**
|
|
244
244
|
* Returns a snapshot of the full internal state of the guard.
|
|
245
245
|
* Useful for adapters (like React) to synchronize with the guard.
|
|
@@ -302,6 +302,14 @@ declare function guardOk<T>(value: T): T;
|
|
|
302
302
|
declare function guard<T = boolean>(nameOrFn?: string | (() => T | Promise<T>), fn?: () => T | Promise<T>): Guard<T>;
|
|
303
303
|
declare namespace guard {
|
|
304
304
|
var map: <T, U>(source: Source<T>, mapper: (value: T) => U | Promise<U>, name?: string) => Guard<U>;
|
|
305
|
+
var select: <T extends object, U>(pulseObj: T, selector: (obj: T) => U | Promise<U>, name?: string) => Guard<U>;
|
|
306
|
+
var from: <T>(getValue: () => {
|
|
307
|
+
value?: T;
|
|
308
|
+
isLoading?: boolean;
|
|
309
|
+
error?: any;
|
|
310
|
+
} | T, options?: {
|
|
311
|
+
name?: string;
|
|
312
|
+
}) => Guard<T | undefined>;
|
|
305
313
|
}
|
|
306
314
|
|
|
307
315
|
/**
|
|
@@ -367,6 +375,139 @@ declare function guardAny(nameOrGuards: string | Guard<any>[], maybeGuards?: Gua
|
|
|
367
375
|
*/
|
|
368
376
|
declare function guardNot(nameOrTarget: string | Guard<any> | (() => any), maybeTarget?: Guard<any> | (() => any)): Guard<boolean>;
|
|
369
377
|
|
|
378
|
+
/**
|
|
379
|
+
* Pulse Signal - Low-level reactive primitive
|
|
380
|
+
*
|
|
381
|
+
* Internal building block for fine-grained reactivity.
|
|
382
|
+
* Signals are the foundation for both `source()` and `pulse()` APIs.
|
|
383
|
+
*
|
|
384
|
+
* @internal
|
|
385
|
+
*/
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* A reactive signal holding a value.
|
|
389
|
+
* @template T The type of value held by the signal.
|
|
390
|
+
*/
|
|
391
|
+
interface Signal<T> {
|
|
392
|
+
/** Get the current value, auto-tracking if inside a Guard. */
|
|
393
|
+
get(): T;
|
|
394
|
+
/** Set a new value, notifying all dependents. */
|
|
395
|
+
set(value: T): void;
|
|
396
|
+
/** Update value using a transformer function. */
|
|
397
|
+
update(fn: (current: T) => T): void;
|
|
398
|
+
/** Subscribe to value changes. */
|
|
399
|
+
subscribe(listener: Subscriber<T>): () => void;
|
|
400
|
+
/** Get value without tracking (break dependency). */
|
|
401
|
+
peek(): T;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Batch multiple reactive updates into a single notification cycle.
|
|
405
|
+
* Reduces unnecessary re-evaluations when updating multiple signals.
|
|
406
|
+
*
|
|
407
|
+
* @param fn Function containing multiple signal updates.
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```ts
|
|
411
|
+
* batch(() => {
|
|
412
|
+
* count.set(1);
|
|
413
|
+
* name.set('Alice');
|
|
414
|
+
* // Dependents notified only once after both updates
|
|
415
|
+
* });
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
declare function batch(fn: () => void): void;
|
|
419
|
+
/**
|
|
420
|
+
* Creates a low-level reactive signal.
|
|
421
|
+
*
|
|
422
|
+
* Signals automatically track dependencies when read inside a Guard context.
|
|
423
|
+
* When the signal value changes, all dependent Guards are re-evaluated.
|
|
424
|
+
*
|
|
425
|
+
* @template T The type of value to store.
|
|
426
|
+
* @param initialValue The initial value.
|
|
427
|
+
* @param equals Optional equality function (defaults to ===).
|
|
428
|
+
* @returns A reactive Signal.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```ts
|
|
432
|
+
* const count = createSignal(0);
|
|
433
|
+
* count.get(); // 0
|
|
434
|
+
* count.set(5);
|
|
435
|
+
* count.get(); // 5
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
declare function createSignal<T>(initialValue: T, equals?: (a: T, b: T) => boolean): Signal<T>;
|
|
439
|
+
/**
|
|
440
|
+
* Effect tracking - run a function when its dependencies change.
|
|
441
|
+
* Similar to Solid's createEffect or Vue's watchEffect.
|
|
442
|
+
*
|
|
443
|
+
* @param fn The effect function to run.
|
|
444
|
+
* @returns Cleanup function to stop the effect.
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```ts
|
|
448
|
+
* const count = createSignal(0);
|
|
449
|
+
* const cleanup = effect(() => {
|
|
450
|
+
* console.log('Count changed:', count.get());
|
|
451
|
+
* });
|
|
452
|
+
* // Later: cleanup() to stop
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
declare function effect(fn: () => void | (() => void)): () => void;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Metadata attached to pulse objects for internal tracking.
|
|
459
|
+
*/
|
|
460
|
+
interface PulseMeta<T> {
|
|
461
|
+
signals: Map<string | symbol, Signal<any>>;
|
|
462
|
+
subscribers: Set<Subscriber<T>>;
|
|
463
|
+
dependents: Set<Trackable>;
|
|
464
|
+
name?: string;
|
|
465
|
+
target: T;
|
|
466
|
+
}
|
|
467
|
+
declare const PULSE_META: unique symbol;
|
|
468
|
+
/**
|
|
469
|
+
* Represents a reactive Pulse Object.
|
|
470
|
+
*/
|
|
471
|
+
type PulseObject<T extends object> = T & {
|
|
472
|
+
/** @internal */
|
|
473
|
+
[PULSE_META]: PulseMeta<T>;
|
|
474
|
+
/** Subscribe to any property change on this object. */
|
|
475
|
+
$subscribe(listener: Subscriber<T>): () => void;
|
|
476
|
+
/** Take a non-reactive snapshot of the current state. */
|
|
477
|
+
$snapshot(): T;
|
|
478
|
+
/** Access the raw target object. */
|
|
479
|
+
$raw: T;
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Configuration options for pulse objects.
|
|
483
|
+
*/
|
|
484
|
+
interface PulseOptions {
|
|
485
|
+
/** Optional name for registry and debugging. */
|
|
486
|
+
name?: string;
|
|
487
|
+
/** Whether to recursively wrap nested objects (default: true). */
|
|
488
|
+
deep?: boolean;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Creates a reactive Pulse Object from a plain JavaScript object.
|
|
492
|
+
*
|
|
493
|
+
* Pulse Objects use Proxies to automatically track property access and mutations.
|
|
494
|
+
* They are ideal for managing complex state structures without manual source calls.
|
|
495
|
+
*/
|
|
496
|
+
declare function pulse<T extends object>(target: T, options?: PulseOptions): PulseObject<T>;
|
|
497
|
+
/**
|
|
498
|
+
* Check if a value is a Pulse Object.
|
|
499
|
+
*/
|
|
500
|
+
declare function isPulseObject(value: any): value is PulseObject<any>;
|
|
501
|
+
/**
|
|
502
|
+
* Get the raw (non-reactive) object from a Pulse Object.
|
|
503
|
+
*/
|
|
504
|
+
declare function toRaw<T extends object>(pulseObj: PulseObject<T>): T;
|
|
505
|
+
/**
|
|
506
|
+
* Create a readonly view of a Pulse Object.
|
|
507
|
+
* Attempts to write will throw in development.
|
|
508
|
+
*/
|
|
509
|
+
declare function readonly<T extends object>(pulseObj: PulseObject<T>): Readonly<T>;
|
|
510
|
+
|
|
370
511
|
/**
|
|
371
512
|
* Serialized state of guards for transfer from server to client.
|
|
372
513
|
*/
|
|
@@ -421,40 +562,35 @@ type PulseUnit = Source<any> | Guard<any>;
|
|
|
421
562
|
* Root Registry for Pulse.
|
|
422
563
|
*
|
|
423
564
|
* Tracks all registered Units (Sources and Guards) globally for DevTools.
|
|
424
|
-
*
|
|
425
|
-
* **IMPORTANT**: Only units with explicit names are registered and visible in DevTools.
|
|
426
|
-
* Unnamed units work perfectly but are not tracked to avoid HMR instability.
|
|
427
|
-
*
|
|
428
|
-
* @example
|
|
429
|
-
* ```ts
|
|
430
|
-
* // ✅ Visible in DevTools
|
|
431
|
-
* const count = source(0, { name: 'count' });
|
|
432
|
-
*
|
|
433
|
-
* // ❌ Not visible in DevTools (but works fine)
|
|
434
|
-
* const temp = source(0);
|
|
435
|
-
* ```
|
|
565
|
+
* Uses the Proxy of Identity pattern to maintain stable references during HMR.
|
|
436
566
|
*/
|
|
437
567
|
declare class Registry {
|
|
438
|
-
private
|
|
568
|
+
private targets;
|
|
569
|
+
private proxies;
|
|
439
570
|
private listeners;
|
|
440
571
|
private currentGeneration;
|
|
441
572
|
private cleanupScheduled;
|
|
573
|
+
private hmrDebounce;
|
|
442
574
|
/**
|
|
443
|
-
*
|
|
575
|
+
* Registers a unit and returns a stable Identity Proxy.
|
|
576
|
+
*
|
|
577
|
+
* If a unit with the same UID already exists, it updates the internal
|
|
578
|
+
* target of the existing proxy and returns that same proxy.
|
|
444
579
|
*/
|
|
445
|
-
|
|
580
|
+
register<T extends PulseUnit>(unit: T): T;
|
|
446
581
|
/**
|
|
447
|
-
*
|
|
448
|
-
* Uses mark-and-sweep: units that were re-registered have current generation,
|
|
449
|
-
* units that weren't are from old generation and should be removed.
|
|
582
|
+
* Schedules cleanup of units that weren't re-registered.
|
|
450
583
|
*/
|
|
584
|
+
private scheduleCleanup;
|
|
451
585
|
private cleanupDeadUnits;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
*/
|
|
455
|
-
register(unit: PulseUnit): void;
|
|
586
|
+
private notifyListeners;
|
|
587
|
+
get(nameOrUid: string): PulseUnit | undefined;
|
|
456
588
|
getAll(): PulseUnit[];
|
|
457
|
-
|
|
589
|
+
getAllWithMeta(): Array<{
|
|
590
|
+
unit: PulseUnit;
|
|
591
|
+
uid: string;
|
|
592
|
+
}>;
|
|
593
|
+
onRegister(listener: (unit: PulseUnit, event?: 'add' | 'update' | 'remove') => void): () => void;
|
|
458
594
|
reset(): void;
|
|
459
595
|
}
|
|
460
596
|
declare const PulseRegistry: Registry;
|
|
@@ -489,4 +625,4 @@ declare const extendedGuard: typeof guard & {
|
|
|
489
625
|
compute: typeof compute;
|
|
490
626
|
};
|
|
491
627
|
|
|
492
|
-
export { type Guard, type GuardExplanation, type GuardNode, type GuardReason, type GuardState, type GuardStatus, type HydrationState, type InferGuardType, PulseRegistry, type PulseUnit, type Source, type SourceOptions, type Subscriber, type Trackable, compute, evaluate, getCurrentGuard, extendedGuard as guard, guardFail, guardOk, hydrate, registerGuardForHydration, runInContext, source };
|
|
628
|
+
export { type Guard, type GuardExplanation, type GuardNode, type GuardReason, type GuardState, type GuardStatus, type HydrationState, type InferGuardType, type PulseObject, type PulseOptions, PulseRegistry, type PulseUnit, type Signal, type Source, type SourceOptions, type Subscriber, type Trackable, batch, compute, createSignal, effect, evaluate, getCurrentGuard, extendedGuard as guard, guardFail, guardOk, hydrate, isPulseObject, pulse, readonly, registerGuardForHydration, runInContext, source, toRaw };
|
package/dist/index.d.ts
CHANGED
|
@@ -179,9 +179,9 @@ interface GuardState<T> {
|
|
|
179
179
|
/** The value returned by the evaluator (only if status is 'ok'). */
|
|
180
180
|
value?: T;
|
|
181
181
|
/** The reason why the guard failed. */
|
|
182
|
-
reason?:
|
|
182
|
+
reason?: GuardReason;
|
|
183
183
|
/** The last known failure reason, persisted even during 'pending'. */
|
|
184
|
-
lastReason?:
|
|
184
|
+
lastReason?: GuardReason;
|
|
185
185
|
/** The timestamp when the status last changed. */
|
|
186
186
|
updatedAt?: number;
|
|
187
187
|
}
|
|
@@ -191,14 +191,14 @@ interface GuardState<T> {
|
|
|
191
191
|
interface GuardExplanation {
|
|
192
192
|
name: string;
|
|
193
193
|
status: GuardStatus;
|
|
194
|
-
reason?:
|
|
195
|
-
lastReason?:
|
|
194
|
+
reason?: GuardReason;
|
|
195
|
+
lastReason?: GuardReason;
|
|
196
196
|
value?: any;
|
|
197
197
|
dependencies: Array<{
|
|
198
198
|
name: string;
|
|
199
199
|
type: 'source' | 'guard';
|
|
200
200
|
status?: GuardStatus;
|
|
201
|
-
reason?:
|
|
201
|
+
reason?: GuardReason;
|
|
202
202
|
}>;
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
@@ -237,9 +237,9 @@ interface Guard<T = boolean> {
|
|
|
237
237
|
* Returns the failure reason message if the guard is in the 'fail' state.
|
|
238
238
|
* Useful for displaying semantic error messages in the UI.
|
|
239
239
|
*
|
|
240
|
-
* @returns The error message or undefined.
|
|
240
|
+
* @returns The error message object or undefined.
|
|
241
241
|
*/
|
|
242
|
-
reason():
|
|
242
|
+
reason(): GuardReason | undefined;
|
|
243
243
|
/**
|
|
244
244
|
* Returns a snapshot of the full internal state of the guard.
|
|
245
245
|
* Useful for adapters (like React) to synchronize with the guard.
|
|
@@ -302,6 +302,14 @@ declare function guardOk<T>(value: T): T;
|
|
|
302
302
|
declare function guard<T = boolean>(nameOrFn?: string | (() => T | Promise<T>), fn?: () => T | Promise<T>): Guard<T>;
|
|
303
303
|
declare namespace guard {
|
|
304
304
|
var map: <T, U>(source: Source<T>, mapper: (value: T) => U | Promise<U>, name?: string) => Guard<U>;
|
|
305
|
+
var select: <T extends object, U>(pulseObj: T, selector: (obj: T) => U | Promise<U>, name?: string) => Guard<U>;
|
|
306
|
+
var from: <T>(getValue: () => {
|
|
307
|
+
value?: T;
|
|
308
|
+
isLoading?: boolean;
|
|
309
|
+
error?: any;
|
|
310
|
+
} | T, options?: {
|
|
311
|
+
name?: string;
|
|
312
|
+
}) => Guard<T | undefined>;
|
|
305
313
|
}
|
|
306
314
|
|
|
307
315
|
/**
|
|
@@ -367,6 +375,139 @@ declare function guardAny(nameOrGuards: string | Guard<any>[], maybeGuards?: Gua
|
|
|
367
375
|
*/
|
|
368
376
|
declare function guardNot(nameOrTarget: string | Guard<any> | (() => any), maybeTarget?: Guard<any> | (() => any)): Guard<boolean>;
|
|
369
377
|
|
|
378
|
+
/**
|
|
379
|
+
* Pulse Signal - Low-level reactive primitive
|
|
380
|
+
*
|
|
381
|
+
* Internal building block for fine-grained reactivity.
|
|
382
|
+
* Signals are the foundation for both `source()` and `pulse()` APIs.
|
|
383
|
+
*
|
|
384
|
+
* @internal
|
|
385
|
+
*/
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* A reactive signal holding a value.
|
|
389
|
+
* @template T The type of value held by the signal.
|
|
390
|
+
*/
|
|
391
|
+
interface Signal<T> {
|
|
392
|
+
/** Get the current value, auto-tracking if inside a Guard. */
|
|
393
|
+
get(): T;
|
|
394
|
+
/** Set a new value, notifying all dependents. */
|
|
395
|
+
set(value: T): void;
|
|
396
|
+
/** Update value using a transformer function. */
|
|
397
|
+
update(fn: (current: T) => T): void;
|
|
398
|
+
/** Subscribe to value changes. */
|
|
399
|
+
subscribe(listener: Subscriber<T>): () => void;
|
|
400
|
+
/** Get value without tracking (break dependency). */
|
|
401
|
+
peek(): T;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Batch multiple reactive updates into a single notification cycle.
|
|
405
|
+
* Reduces unnecessary re-evaluations when updating multiple signals.
|
|
406
|
+
*
|
|
407
|
+
* @param fn Function containing multiple signal updates.
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```ts
|
|
411
|
+
* batch(() => {
|
|
412
|
+
* count.set(1);
|
|
413
|
+
* name.set('Alice');
|
|
414
|
+
* // Dependents notified only once after both updates
|
|
415
|
+
* });
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
declare function batch(fn: () => void): void;
|
|
419
|
+
/**
|
|
420
|
+
* Creates a low-level reactive signal.
|
|
421
|
+
*
|
|
422
|
+
* Signals automatically track dependencies when read inside a Guard context.
|
|
423
|
+
* When the signal value changes, all dependent Guards are re-evaluated.
|
|
424
|
+
*
|
|
425
|
+
* @template T The type of value to store.
|
|
426
|
+
* @param initialValue The initial value.
|
|
427
|
+
* @param equals Optional equality function (defaults to ===).
|
|
428
|
+
* @returns A reactive Signal.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```ts
|
|
432
|
+
* const count = createSignal(0);
|
|
433
|
+
* count.get(); // 0
|
|
434
|
+
* count.set(5);
|
|
435
|
+
* count.get(); // 5
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
declare function createSignal<T>(initialValue: T, equals?: (a: T, b: T) => boolean): Signal<T>;
|
|
439
|
+
/**
|
|
440
|
+
* Effect tracking - run a function when its dependencies change.
|
|
441
|
+
* Similar to Solid's createEffect or Vue's watchEffect.
|
|
442
|
+
*
|
|
443
|
+
* @param fn The effect function to run.
|
|
444
|
+
* @returns Cleanup function to stop the effect.
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```ts
|
|
448
|
+
* const count = createSignal(0);
|
|
449
|
+
* const cleanup = effect(() => {
|
|
450
|
+
* console.log('Count changed:', count.get());
|
|
451
|
+
* });
|
|
452
|
+
* // Later: cleanup() to stop
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
declare function effect(fn: () => void | (() => void)): () => void;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Metadata attached to pulse objects for internal tracking.
|
|
459
|
+
*/
|
|
460
|
+
interface PulseMeta<T> {
|
|
461
|
+
signals: Map<string | symbol, Signal<any>>;
|
|
462
|
+
subscribers: Set<Subscriber<T>>;
|
|
463
|
+
dependents: Set<Trackable>;
|
|
464
|
+
name?: string;
|
|
465
|
+
target: T;
|
|
466
|
+
}
|
|
467
|
+
declare const PULSE_META: unique symbol;
|
|
468
|
+
/**
|
|
469
|
+
* Represents a reactive Pulse Object.
|
|
470
|
+
*/
|
|
471
|
+
type PulseObject<T extends object> = T & {
|
|
472
|
+
/** @internal */
|
|
473
|
+
[PULSE_META]: PulseMeta<T>;
|
|
474
|
+
/** Subscribe to any property change on this object. */
|
|
475
|
+
$subscribe(listener: Subscriber<T>): () => void;
|
|
476
|
+
/** Take a non-reactive snapshot of the current state. */
|
|
477
|
+
$snapshot(): T;
|
|
478
|
+
/** Access the raw target object. */
|
|
479
|
+
$raw: T;
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Configuration options for pulse objects.
|
|
483
|
+
*/
|
|
484
|
+
interface PulseOptions {
|
|
485
|
+
/** Optional name for registry and debugging. */
|
|
486
|
+
name?: string;
|
|
487
|
+
/** Whether to recursively wrap nested objects (default: true). */
|
|
488
|
+
deep?: boolean;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Creates a reactive Pulse Object from a plain JavaScript object.
|
|
492
|
+
*
|
|
493
|
+
* Pulse Objects use Proxies to automatically track property access and mutations.
|
|
494
|
+
* They are ideal for managing complex state structures without manual source calls.
|
|
495
|
+
*/
|
|
496
|
+
declare function pulse<T extends object>(target: T, options?: PulseOptions): PulseObject<T>;
|
|
497
|
+
/**
|
|
498
|
+
* Check if a value is a Pulse Object.
|
|
499
|
+
*/
|
|
500
|
+
declare function isPulseObject(value: any): value is PulseObject<any>;
|
|
501
|
+
/**
|
|
502
|
+
* Get the raw (non-reactive) object from a Pulse Object.
|
|
503
|
+
*/
|
|
504
|
+
declare function toRaw<T extends object>(pulseObj: PulseObject<T>): T;
|
|
505
|
+
/**
|
|
506
|
+
* Create a readonly view of a Pulse Object.
|
|
507
|
+
* Attempts to write will throw in development.
|
|
508
|
+
*/
|
|
509
|
+
declare function readonly<T extends object>(pulseObj: PulseObject<T>): Readonly<T>;
|
|
510
|
+
|
|
370
511
|
/**
|
|
371
512
|
* Serialized state of guards for transfer from server to client.
|
|
372
513
|
*/
|
|
@@ -421,40 +562,35 @@ type PulseUnit = Source<any> | Guard<any>;
|
|
|
421
562
|
* Root Registry for Pulse.
|
|
422
563
|
*
|
|
423
564
|
* Tracks all registered Units (Sources and Guards) globally for DevTools.
|
|
424
|
-
*
|
|
425
|
-
* **IMPORTANT**: Only units with explicit names are registered and visible in DevTools.
|
|
426
|
-
* Unnamed units work perfectly but are not tracked to avoid HMR instability.
|
|
427
|
-
*
|
|
428
|
-
* @example
|
|
429
|
-
* ```ts
|
|
430
|
-
* // ✅ Visible in DevTools
|
|
431
|
-
* const count = source(0, { name: 'count' });
|
|
432
|
-
*
|
|
433
|
-
* // ❌ Not visible in DevTools (but works fine)
|
|
434
|
-
* const temp = source(0);
|
|
435
|
-
* ```
|
|
565
|
+
* Uses the Proxy of Identity pattern to maintain stable references during HMR.
|
|
436
566
|
*/
|
|
437
567
|
declare class Registry {
|
|
438
|
-
private
|
|
568
|
+
private targets;
|
|
569
|
+
private proxies;
|
|
439
570
|
private listeners;
|
|
440
571
|
private currentGeneration;
|
|
441
572
|
private cleanupScheduled;
|
|
573
|
+
private hmrDebounce;
|
|
442
574
|
/**
|
|
443
|
-
*
|
|
575
|
+
* Registers a unit and returns a stable Identity Proxy.
|
|
576
|
+
*
|
|
577
|
+
* If a unit with the same UID already exists, it updates the internal
|
|
578
|
+
* target of the existing proxy and returns that same proxy.
|
|
444
579
|
*/
|
|
445
|
-
|
|
580
|
+
register<T extends PulseUnit>(unit: T): T;
|
|
446
581
|
/**
|
|
447
|
-
*
|
|
448
|
-
* Uses mark-and-sweep: units that were re-registered have current generation,
|
|
449
|
-
* units that weren't are from old generation and should be removed.
|
|
582
|
+
* Schedules cleanup of units that weren't re-registered.
|
|
450
583
|
*/
|
|
584
|
+
private scheduleCleanup;
|
|
451
585
|
private cleanupDeadUnits;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
*/
|
|
455
|
-
register(unit: PulseUnit): void;
|
|
586
|
+
private notifyListeners;
|
|
587
|
+
get(nameOrUid: string): PulseUnit | undefined;
|
|
456
588
|
getAll(): PulseUnit[];
|
|
457
|
-
|
|
589
|
+
getAllWithMeta(): Array<{
|
|
590
|
+
unit: PulseUnit;
|
|
591
|
+
uid: string;
|
|
592
|
+
}>;
|
|
593
|
+
onRegister(listener: (unit: PulseUnit, event?: 'add' | 'update' | 'remove') => void): () => void;
|
|
458
594
|
reset(): void;
|
|
459
595
|
}
|
|
460
596
|
declare const PulseRegistry: Registry;
|
|
@@ -489,4 +625,4 @@ declare const extendedGuard: typeof guard & {
|
|
|
489
625
|
compute: typeof compute;
|
|
490
626
|
};
|
|
491
627
|
|
|
492
|
-
export { type Guard, type GuardExplanation, type GuardNode, type GuardReason, type GuardState, type GuardStatus, type HydrationState, type InferGuardType, PulseRegistry, type PulseUnit, type Source, type SourceOptions, type Subscriber, type Trackable, compute, evaluate, getCurrentGuard, extendedGuard as guard, guardFail, guardOk, hydrate, registerGuardForHydration, runInContext, source };
|
|
628
|
+
export { type Guard, type GuardExplanation, type GuardNode, type GuardReason, type GuardState, type GuardStatus, type HydrationState, type InferGuardType, type PulseObject, type PulseOptions, PulseRegistry, type PulseUnit, type Signal, type Source, type SourceOptions, type Subscriber, type Trackable, batch, compute, createSignal, effect, evaluate, getCurrentGuard, extendedGuard as guard, guardFail, guardOk, hydrate, isPulseObject, pulse, readonly, registerGuardForHydration, runInContext, source, toRaw };
|