@mmstack/primitives 20.13.3 → 20.14.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/index.d.ts CHANGED
@@ -1350,7 +1350,9 @@ type DuplicateKeyPolicy = {
1350
1350
  * when the list is reordered.
1351
1351
  *
1352
1352
  * @param source A `Signal<T[]>` or a function returning `T[]`.
1353
- * @param mapFn The mapping function. Receives the item and its index as a Signal.
1353
+ * @param mapFn The mapping function. Receives the item, its index as a Signal, and the
1354
+ * entry's key (the effective ordinal key when `duplicateKeys` is enabled, otherwise
1355
+ * the raw key) — stable for the lifetime of the mapped entry.
1354
1356
  * @param options Optional configuration:
1355
1357
  * - `onDestroy`: A callback invoked when a mapped item is removed from the array.
1356
1358
  * - `key`: A custom key extractor for identity matching (e.g. `(item) => item.id`)
@@ -1380,7 +1382,7 @@ type DuplicateKeyPolicy = {
1380
1382
  * users.set([users()[1], users()[0]]);
1381
1383
  * ```
1382
1384
  */
1383
- declare function keyArray<T, U, K>(source: Signal<T[]> | (() => T[]), mapFn: (v: T, i: Signal<number>) => U, options?: {
1385
+ declare function keyArray<T, U, K>(source: Signal<T[]> | (() => T[]), mapFn: (v: T, i: Signal<number>, key: K | string) => U, options?: {
1384
1386
  onDestroy?: (value: U) => void;
1385
1387
  /**
1386
1388
  * Optional function to use a custom key for item comparison.
@@ -4161,6 +4163,7 @@ type StoredSignal<T> = WritableSignal<T> & {
4161
4163
  * ```
4162
4164
  */
4163
4165
  declare function stored<T>(fallback: T, { key, store: providedStore, serialize, deserialize, syncTabs, equal, onKeyChange, cleanupOldKey, validate, pause, injector: providedInjector, ...rest }: CreateStoredOptions<T>): StoredSignal<T>;
4166
+ declare function isStored<T = unknown>(value: WritableSignal<T>): value is StoredSignal<T>;
4164
4167
 
4165
4168
  /**
4166
4169
  * The cross-tab transport `tabSync` rides. The default is {@link MessageBus} (a `BroadcastChannel`);
@@ -4348,6 +4351,85 @@ declare function toWritable<T>(source: Signal<T>, set: (value: T) => void, updat
4348
4351
  pure?: boolean;
4349
4352
  }): WritableSignal<T>;
4350
4353
 
4354
+ /**
4355
+ * A member of the writable-signal family that has been wrapped by {@link traced}.
4356
+ * It carries the full surface of the wrapped signal `S` plus a {@link Traced.causedBy}
4357
+ * read that reports the cause recorded at the most recent write.
4358
+ *
4359
+ * @typeParam S - The wrapped writable-signal type (e.g. `WritableSignal`, `MutableSignal`, `DerivedSignal`).
4360
+ * @typeParam C - The type of the captured cause.
4361
+ */
4362
+ type Traced<S extends WritableSignal<unknown>, C> = S & {
4363
+ /**
4364
+ * The cause captured during the most recent synchronous write, or `undefined`
4365
+ * if the last write happened with no ambient cause. This is a plain read, not
4366
+ * a signal — it never creates a reactive dependency and adds zero recomputations.
4367
+ */
4368
+ causedBy(): C | undefined;
4369
+ };
4370
+ /**
4371
+ * Wraps any member of the writable-signal family so that every synchronous write
4372
+ * first records an ambient "cause" (via the caller-provided `capture` function)
4373
+ * and then delegates to the original write, preserving the wrapped signal's exact
4374
+ * write semantics. The recorded cause is exposed through a plain {@link Traced.causedBy}
4375
+ * read, letting a downstream consumer attribute a change to whatever caused it —
4376
+ * without any dependency on a particular telemetry system.
4377
+ *
4378
+ * Capture is **synchronous-only** and last-writer-wins: the cause is whatever
4379
+ * `capture()` returns during the `set`/`update`/`mutate`/`inline` call. A write
4380
+ * performed after an `await` (once the ambient cause has been cleared) records
4381
+ * `undefined`; a write while `capture()` returns `undefined` clears the cause.
4382
+ * `causedBy()` is a plain read, not a signal — reading it never subscribes, and
4383
+ * a cause-only change (a write with a different cause but no dependent-visible
4384
+ * value change) never invalidates a consumer.
4385
+ *
4386
+ * The traced twin behaves like the original except for `causedBy`: it carries the
4387
+ * wrapped signal's surface — `asReadonly`, the `mutate`/`inline` methods of a
4388
+ * mutable, and the `from` of a derived — and the underlying write semantics survive
4389
+ * (a traced `derived` still writes through to its source; a traced `toWritable` still
4390
+ * runs its custom `set`). Reads through the twin stay tracked — consumers subscribe
4391
+ * exactly as they would to the source.
4392
+ *
4393
+ * @typeParam S - The wrapped writable-signal type.
4394
+ * @typeParam C - The type of the captured cause.
4395
+ *
4396
+ * @param sig - The writable signal to trace. Any family member is accepted
4397
+ * (`signal`, `mutable`, `derived`, `toWritable`, `stored`, ...).
4398
+ * @param capture - A function invoked synchronously at the start of every write.
4399
+ * Its return value becomes the current cause; returning `undefined`
4400
+ * clears it.
4401
+ * @param opt - Optional configuration.
4402
+ * @param opt.pure - If `true` (the default), the returned twin is a **new** signal
4403
+ * that reads through to `sig`; `sig` itself is left untouched, so
4404
+ * tracing a shared signal never makes the original writable or
4405
+ * alters its behaviour.
4406
+ *
4407
+ * CAUTION: with `pure: false` the write methods are patched
4408
+ * directly onto the `sig` object you passed in — every other
4409
+ * holder of that signal now records causes on write. Only use it
4410
+ * with a signal you created and own exclusively.
4411
+ *
4412
+ * @returns A {@link Traced} twin of `sig` exposing `causedBy()`.
4413
+ *
4414
+ * @example
4415
+ * // A refetch attributing itself to whatever wrote the query.
4416
+ * let activeCause: string | undefined;
4417
+ * const query = traced(signal(''), () => activeCause);
4418
+ *
4419
+ * activeCause = 'user-typed';
4420
+ * query.set('hello');
4421
+ * query.causedBy(); // 'user-typed'
4422
+ *
4423
+ * @example
4424
+ * // Tracing a shared, read-only-exposed signal without making it writable.
4425
+ * const shared = signal(0);
4426
+ * const twin = traced(shared, () => currentInteraction());
4427
+ * twin === shared; // false — the original is untouched
4428
+ */
4429
+ declare function traced<S extends WritableSignal<unknown>, C>(sig: S, capture: () => C | undefined, opt?: {
4430
+ pure?: boolean;
4431
+ }): Traced<S, C>;
4432
+
4351
4433
  type UntilOptions = {
4352
4434
  /**
4353
4435
  * Optional timeout in milliseconds. If the condition is not met
@@ -4498,5 +4580,5 @@ type CreateHistoryOptions<T> = Omit<CreateSignalOptions<T[]>, 'equal'> & {
4498
4580
  */
4499
4581
  declare function withHistory<T>(sourceOrValue: WritableSignal<T> | T, opt?: CreateHistoryOptions<T>): SignalWithHistory<T>;
4500
4582
 
4501
- export { CONCURRENCY_INSTRUMENTATION, MmActivity, MmTransition, MmViewTransitionName, OP_PROTO_VERSION, PAUSABLE_OPTIONS, PERSISTED_STORE_OPTIONS, POS_SEGMENT, SuspenseBoundary, SuspenseBoundaryBase, UnscopedSuspenseBoundary, activeTransaction, applyOps, batteryStatus, bridgeScopeToPendingTasks, chunked, clipboard, combineWith, compareHlc, compareSiblings, compareTotal, createAttributedPending, createConvergingApply, createForwardingScope, createHlcClock, createStoreContext, createTransaction, createTransitionScope, debounce, debounced, defaultFold, deferredValue, derived, diffOps, distinct, elementSize, elementVisibility, extendStore, filter, filterWith, focusWithin, forkStore, geolocation, getTransitionScope, holdUntilReady, idle, indexArray, injectPaused, injectRegisterResource, injectStartTransaction, injectStartTransition, injectTransitionScope, insertElement, invertBatch, isConflicted, isDerivation, isLeaf, isMutable, isOpaque, isStore, keepPrevious, keyArray, keyedArray, latest, lww, map, mapArray, mapObject, mediaQuery, merge3, mergeThree, mousePosition, moveElement, mutable, mutableStore, nestedEffect, networkStatus, opLog, opSync, opaque, orderedEntries, orientation, pageVisibility, pairwise, pausableComputed, pausableEffect, pausableSignal, perfCustomTracks, persist, persistedStore, pipeable, piped, pointerDrag, policyStrategy, pooled, pooledArray, pooledMap, pooledSet, posBetween, prefersDarkMode, prefersReducedMotion, preserve, projection, provideConcurrencyInstrumentation, provideForwardingTransitionScope, providePausableOptions, providePaused, providePersistedStoreOptions, provideTransitionScope, rebalanceContainer, rebaseOps, reconcile, registerResource, removeElement, resolvePause, scan, scrollPosition, select, sensor, sensors, signalFromEvent, startWith, store, storeHistory, stored, syncedFork, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, until, use, validateEnvelope, windowSize, withHistory };
4502
- export type { AsyncStore, BatteryStatus, ClipboardSignal, Computation, ConcurrencyInstrumentation, Conflicted, ContainerNode, ConvergingApply, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreateLatestOptions, CreateOpLogOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, CreateTransitionScopeOptions, DebouncedSignal, DeferStrategy, DeferredSignal, DeferredValueOptions, DerivedSignal, Dot, DotFrontier, DuplicateKeyPolicy, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, ExtendStoreOptions, FoldFn, FoldPolicyEntry, FoldResult, Fork, ForkStoreOptions, ForkStrategy, ForwardingTransitionScope, Frame, GeolocationOptions, GeolocationSignal, Hlc, HlcClock, IdleOptions, IdleSignal, LatestSignal, MergeContext, MergeFn, MergePolicyEntry, MmTransitionContext, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, OpBatch, OpEnvelope, OpLog, OpLogDriver, OpSync, OpSyncCheckpoint, OpSyncOptions, Opaque, OrderedEntry, PausableOptions, PauseOption, PersistHandle, PersistOptions, PersistedStore, PersistedStoreDefaults, PersistedStoreOptions, PipeableSignal, PointerDragOptions, PointerDragSignal, PointerDragState, PointerModifiers, PointerPoint, ProjectionOptions, RebaseResult, ReconcileFn, ReconcileKey, RegisterCheckpoint, RegisterOptions, ResourceLike, ScreenOrientation, ScreenOrientationState, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SensorRunOptions, SignalFromEventOptions, SignalStore, SignalWithHistory, StoreHistory, StoreHistoryOptions, StoreOp, StoreOptions, StoreTabSyncOptions, StoredSignal, SuspendType, SyncOp, SyncSibling, SyncSignalOptions, SyncedFork, TabSyncBus, ThrottledSignal, Transaction, TransactionRef, TransitionRef, TransitionScope, UntilOptions, UseSource, Vivify, WindowSize, WindowSizeOptions, WindowSizeSignal, WithVivify, WritableSignalStore, toStoreOptions };
4583
+ export { CONCURRENCY_INSTRUMENTATION, MmActivity, MmTransition, MmViewTransitionName, OP_PROTO_VERSION, PAUSABLE_OPTIONS, PERSISTED_STORE_OPTIONS, POS_SEGMENT, SuspenseBoundary, SuspenseBoundaryBase, UnscopedSuspenseBoundary, activeTransaction, applyOps, batteryStatus, bridgeScopeToPendingTasks, chunked, clipboard, combineWith, compareHlc, compareSiblings, compareTotal, createAttributedPending, createConvergingApply, createForwardingScope, createHlcClock, createStoreContext, createTransaction, createTransitionScope, debounce, debounced, defaultFold, deferredValue, derived, diffOps, distinct, elementSize, elementVisibility, extendStore, filter, filterWith, focusWithin, forkStore, geolocation, getTransitionScope, holdUntilReady, idle, indexArray, injectPaused, injectRegisterResource, injectStartTransaction, injectStartTransition, injectTransitionScope, insertElement, invertBatch, isConflicted, isDerivation, isLeaf, isMutable, isOpaque, isStore, isStored, keepPrevious, keyArray, keyedArray, latest, lww, map, mapArray, mapObject, mediaQuery, merge3, mergeThree, mousePosition, moveElement, mutable, mutableStore, nestedEffect, networkStatus, opLog, opSync, opaque, orderedEntries, orientation, pageVisibility, pairwise, pausableComputed, pausableEffect, pausableSignal, perfCustomTracks, persist, persistedStore, pipeable, piped, pointerDrag, policyStrategy, pooled, pooledArray, pooledMap, pooledSet, posBetween, prefersDarkMode, prefersReducedMotion, preserve, projection, provideConcurrencyInstrumentation, provideForwardingTransitionScope, providePausableOptions, providePaused, providePersistedStoreOptions, provideTransitionScope, rebalanceContainer, rebaseOps, reconcile, registerResource, removeElement, resolvePause, scan, scrollPosition, select, sensor, sensors, signalFromEvent, startWith, store, storeHistory, stored, syncedFork, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, traced, until, use, validateEnvelope, windowSize, withHistory };
4584
+ export type { AsyncStore, BatteryStatus, ClipboardSignal, Computation, ConcurrencyInstrumentation, Conflicted, ContainerNode, ConvergingApply, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreateLatestOptions, CreateOpLogOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, CreateTransitionScopeOptions, DebouncedSignal, DeferStrategy, DeferredSignal, DeferredValueOptions, DerivedSignal, Dot, DotFrontier, DuplicateKeyPolicy, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, ExtendStoreOptions, FoldFn, FoldPolicyEntry, FoldResult, Fork, ForkStoreOptions, ForkStrategy, ForwardingTransitionScope, Frame, GeolocationOptions, GeolocationSignal, Hlc, HlcClock, IdleOptions, IdleSignal, LatestSignal, MergeContext, MergeFn, MergePolicyEntry, MmTransitionContext, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, OpBatch, OpEnvelope, OpLog, OpLogDriver, OpSync, OpSyncCheckpoint, OpSyncOptions, Opaque, OrderedEntry, PausableOptions, PauseOption, PersistHandle, PersistOptions, PersistedStore, PersistedStoreDefaults, PersistedStoreOptions, PipeableSignal, PointerDragOptions, PointerDragSignal, PointerDragState, PointerModifiers, PointerPoint, ProjectionOptions, RebaseResult, ReconcileFn, ReconcileKey, RegisterCheckpoint, RegisterOptions, ResourceLike, ScreenOrientation, ScreenOrientationState, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SensorRunOptions, SignalFromEventOptions, SignalStore, SignalWithHistory, StoreHistory, StoreHistoryOptions, StoreOp, StoreOptions, StoreTabSyncOptions, StoredSignal, SuspendType, SyncOp, SyncSibling, SyncSignalOptions, SyncedFork, TabSyncBus, ThrottledSignal, Traced, Transaction, TransactionRef, TransitionRef, TransitionScope, UntilOptions, UseSource, Vivify, WindowSize, WindowSizeOptions, WindowSizeSignal, WithVivify, WritableSignalStore, toStoreOptions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmstack/primitives",
3
- "version": "20.13.3",
3
+ "version": "20.14.0",
4
4
  "keywords": [
5
5
  "angular",
6
6
  "signals",