@asaidimu/utils-artifacts 8.1.1 → 8.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.
Files changed (3) hide show
  1. package/index.d.mts +40 -7
  2. package/index.d.ts +40 -7
  3. package/package.json +2 -2
package/index.d.mts CHANGED
@@ -85,6 +85,17 @@ interface ReactiveSelector<S> {
85
85
  */
86
86
  subscribe: (callback: (state: S) => void) => () => void;
87
87
  }
88
+ interface ActionWatcher {
89
+ /** Unique identifier for the action */
90
+ name: string;
91
+ /** Function to get the current computed value of the action. */
92
+ status: () => boolean;
93
+ /**
94
+ * Subscribes a callback function to run whenever the action's status changes.
95
+ * Returns an unsubscribe function.
96
+ */
97
+ subscribe: (callback: () => void) => () => void;
98
+ }
88
99
  /**
89
100
  * Interface defining the contract for the core data state store.
90
101
  * T must be an object type.
@@ -139,6 +150,28 @@ interface DataStore<T extends object> {
139
150
  * @returns An unsubscribe function.
140
151
  */
141
152
  watch(path: string | Array<string>, callback: (state: T) => void): () => void;
153
+ /**
154
+ * Subscribes to execution‑status changes of a registered action.
155
+ *
156
+ * The provided callback is called **every time** the action transitions
157
+ * between idle and running (i.e. on `action:start`, `action:complete`, or
158
+ * `action:error` for the given name). The current status can also be read
159
+ * synchronously with `isActionRunning(name)`.
160
+ *
161
+ * **Deferred listener teardown**
162
+ * To avoid unnecessary churn when subscriptions are rapidly created and
163
+ * destroyed, the underlying event listeners are not removed immediately
164
+ * on unsubscribe. Instead, a *pending reset* is queued via `queueMicrotask`.
165
+ * If a new subscription for the same action arrives before that microtask
166
+ * executes, the reset is silently cancelled and the already‑established
167
+ * listeners are reused. This keeps the subscription infrastructure stable
168
+ * and prevents cascading notifications that could otherwise arise from
169
+ * repeated subscribe‑unsubscribe‑subscribe cycles.
170
+ *
171
+ * @param name - The name of the action to watch.
172
+ * @returns An ActionWatcher
173
+ */
174
+ watchAction(name: string): ActionWatcher;
142
175
  /**
143
176
  * Executes an operation function within a transaction block.
144
177
  * All state updates (`set` or actions) within the transaction are batched and applied atomically (all or nothing).
@@ -326,7 +359,7 @@ type ArtifactStreamContext<TState, TArtifact> = {
326
359
  * @template TState The type of the global state managed by the DataStore.
327
360
  * @template TArtifact The type of the artifact being created by the factory.
328
361
  */
329
- interface ArtifactFactoryContext<TRegistry extends Record<string, any>, TState extends object, TArtifact> {
362
+ type ArtifactFactoryContext<TRegistry extends Record<string, any>, TState extends object, TArtifact, TExtra extends Record<string, any> = {}> = TExtra & {
330
363
  /**
331
364
  * Returns the current global state object. This is a non-reactive read;
332
365
  * changes to the state will not automatically invalidate the artifact
@@ -379,7 +412,7 @@ interface ArtifactFactoryContext<TRegistry extends Record<string, any>, TState e
379
412
  * An AbortSignal that indicates if the artifacts has been unregistered
380
413
  */
381
414
  signal: AbortSignal;
382
- }
415
+ };
383
416
  /**
384
417
  * A function that performs cleanup or disposal logic for an artifact, potentially asynchronously.
385
418
  * Used for `onCleanup` and `onDispose` callbacks.
@@ -463,7 +496,7 @@ type KeyedResolvedArtifact<TRegistry, K extends keyof TRegistry> = ResolvedArtif
463
496
  * @param context The context for creating the artifact.
464
497
  * @returns The artifact instance or a Promise resolving to it.
465
498
  */
466
- type ArtifactFactory<TRegistry extends Record<string, any>, TState extends object, TArtifact> = (context: ArtifactFactoryContext<TRegistry, TState, TArtifact>) => TArtifact | Promise<TArtifact>;
499
+ type ArtifactFactory<TRegistry extends Record<string, any>, TState extends object, TArtifact, TExtra extends Record<string, any> = {}> = (context: ArtifactFactoryContext<TRegistry, TState, TArtifact, TExtra>) => TArtifact | Promise<TArtifact>;
467
500
  type ArtifactInstance<R> = R extends PromiseLike<infer T> ? T : R;
468
501
  /**
469
502
  * An interface for observing changes to an artifact without direct resolution,
@@ -511,11 +544,11 @@ interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
511
544
  * @template TArtifact The resolved type of the artifact instance.
512
545
  * @template TRegistry The type mapping of all artifacts in the container.
513
546
  */
514
- interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends object = any> {
547
+ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends object = any, TExtra extends Record<string, any> = {}> {
515
548
  /** The unique key identifying this artifact within the registry. */
516
549
  key: keyof TRegistry;
517
550
  /** The factory function responsible for creating the artifact's instance. */
518
- factory: ArtifactFactory<TRegistry, TState, TArtifact>;
551
+ factory: ArtifactFactory<TRegistry, TState, TArtifact, TExtra>;
519
552
  /**
520
553
  * The scope of the artifact, determining its lifecycle and sharing strategy.
521
554
  * Defaults to `ArtifactScopes.Singleton`.
@@ -581,7 +614,7 @@ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string,
581
614
  * @template T The type that contains a factory property.
582
615
  */
583
616
  type ArtifactValue<T> = T extends {
584
- factory: ArtifactFactory<any, any, infer TArtifact>;
617
+ factory: (...args: any[]) => infer TArtifact;
585
618
  } ? TArtifact : never;
586
619
  /**
587
620
  * Infers the complete Artifact Registry type from a map of artifact configuration objects.
@@ -592,7 +625,7 @@ type ArtifactValue<T> = T extends {
592
625
  * @template T A map where keys are artifact names and values are their configurations.
593
626
  */
594
627
  type InferRegistry<T extends Record<string, {
595
- factory: ArtifactFactory<any, any, any>;
628
+ factory: (...args: any[]) => any;
596
629
  [key: string]: any;
597
630
  }>> = {
598
631
  [K in keyof T]: ArtifactValue<T[K]>;
package/index.d.ts CHANGED
@@ -85,6 +85,17 @@ interface ReactiveSelector<S> {
85
85
  */
86
86
  subscribe: (callback: (state: S) => void) => () => void;
87
87
  }
88
+ interface ActionWatcher {
89
+ /** Unique identifier for the action */
90
+ name: string;
91
+ /** Function to get the current computed value of the action. */
92
+ status: () => boolean;
93
+ /**
94
+ * Subscribes a callback function to run whenever the action's status changes.
95
+ * Returns an unsubscribe function.
96
+ */
97
+ subscribe: (callback: () => void) => () => void;
98
+ }
88
99
  /**
89
100
  * Interface defining the contract for the core data state store.
90
101
  * T must be an object type.
@@ -139,6 +150,28 @@ interface DataStore<T extends object> {
139
150
  * @returns An unsubscribe function.
140
151
  */
141
152
  watch(path: string | Array<string>, callback: (state: T) => void): () => void;
153
+ /**
154
+ * Subscribes to execution‑status changes of a registered action.
155
+ *
156
+ * The provided callback is called **every time** the action transitions
157
+ * between idle and running (i.e. on `action:start`, `action:complete`, or
158
+ * `action:error` for the given name). The current status can also be read
159
+ * synchronously with `isActionRunning(name)`.
160
+ *
161
+ * **Deferred listener teardown**
162
+ * To avoid unnecessary churn when subscriptions are rapidly created and
163
+ * destroyed, the underlying event listeners are not removed immediately
164
+ * on unsubscribe. Instead, a *pending reset* is queued via `queueMicrotask`.
165
+ * If a new subscription for the same action arrives before that microtask
166
+ * executes, the reset is silently cancelled and the already‑established
167
+ * listeners are reused. This keeps the subscription infrastructure stable
168
+ * and prevents cascading notifications that could otherwise arise from
169
+ * repeated subscribe‑unsubscribe‑subscribe cycles.
170
+ *
171
+ * @param name - The name of the action to watch.
172
+ * @returns An ActionWatcher
173
+ */
174
+ watchAction(name: string): ActionWatcher;
142
175
  /**
143
176
  * Executes an operation function within a transaction block.
144
177
  * All state updates (`set` or actions) within the transaction are batched and applied atomically (all or nothing).
@@ -326,7 +359,7 @@ type ArtifactStreamContext<TState, TArtifact> = {
326
359
  * @template TState The type of the global state managed by the DataStore.
327
360
  * @template TArtifact The type of the artifact being created by the factory.
328
361
  */
329
- interface ArtifactFactoryContext<TRegistry extends Record<string, any>, TState extends object, TArtifact> {
362
+ type ArtifactFactoryContext<TRegistry extends Record<string, any>, TState extends object, TArtifact, TExtra extends Record<string, any> = {}> = TExtra & {
330
363
  /**
331
364
  * Returns the current global state object. This is a non-reactive read;
332
365
  * changes to the state will not automatically invalidate the artifact
@@ -379,7 +412,7 @@ interface ArtifactFactoryContext<TRegistry extends Record<string, any>, TState e
379
412
  * An AbortSignal that indicates if the artifacts has been unregistered
380
413
  */
381
414
  signal: AbortSignal;
382
- }
415
+ };
383
416
  /**
384
417
  * A function that performs cleanup or disposal logic for an artifact, potentially asynchronously.
385
418
  * Used for `onCleanup` and `onDispose` callbacks.
@@ -463,7 +496,7 @@ type KeyedResolvedArtifact<TRegistry, K extends keyof TRegistry> = ResolvedArtif
463
496
  * @param context The context for creating the artifact.
464
497
  * @returns The artifact instance or a Promise resolving to it.
465
498
  */
466
- type ArtifactFactory<TRegistry extends Record<string, any>, TState extends object, TArtifact> = (context: ArtifactFactoryContext<TRegistry, TState, TArtifact>) => TArtifact | Promise<TArtifact>;
499
+ type ArtifactFactory<TRegistry extends Record<string, any>, TState extends object, TArtifact, TExtra extends Record<string, any> = {}> = (context: ArtifactFactoryContext<TRegistry, TState, TArtifact, TExtra>) => TArtifact | Promise<TArtifact>;
467
500
  type ArtifactInstance<R> = R extends PromiseLike<infer T> ? T : R;
468
501
  /**
469
502
  * An interface for observing changes to an artifact without direct resolution,
@@ -511,11 +544,11 @@ interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
511
544
  * @template TArtifact The resolved type of the artifact instance.
512
545
  * @template TRegistry The type mapping of all artifacts in the container.
513
546
  */
514
- interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends object = any> {
547
+ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends object = any, TExtra extends Record<string, any> = {}> {
515
548
  /** The unique key identifying this artifact within the registry. */
516
549
  key: keyof TRegistry;
517
550
  /** The factory function responsible for creating the artifact's instance. */
518
- factory: ArtifactFactory<TRegistry, TState, TArtifact>;
551
+ factory: ArtifactFactory<TRegistry, TState, TArtifact, TExtra>;
519
552
  /**
520
553
  * The scope of the artifact, determining its lifecycle and sharing strategy.
521
554
  * Defaults to `ArtifactScopes.Singleton`.
@@ -581,7 +614,7 @@ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string,
581
614
  * @template T The type that contains a factory property.
582
615
  */
583
616
  type ArtifactValue<T> = T extends {
584
- factory: ArtifactFactory<any, any, infer TArtifact>;
617
+ factory: (...args: any[]) => infer TArtifact;
585
618
  } ? TArtifact : never;
586
619
  /**
587
620
  * Infers the complete Artifact Registry type from a map of artifact configuration objects.
@@ -592,7 +625,7 @@ type ArtifactValue<T> = T extends {
592
625
  * @template T A map where keys are artifact names and values are their configurations.
593
626
  */
594
627
  type InferRegistry<T extends Record<string, {
595
- factory: ArtifactFactory<any, any, any>;
628
+ factory: (...args: any[]) => any;
596
629
  [key: string]: any;
597
630
  }>> = {
598
631
  [K in keyof T]: ArtifactValue<T[K]>;
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-artifacts",
3
- "version": "8.1.1",
3
+ "version": "8.1.2",
4
4
  "description": "Reactive artifact container.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
7
7
  "types": "index.d.ts",
8
8
  "dependencies": {
9
- "@asaidimu/utils-events": "^1.1.0"
9
+ "@asaidimu/utils-events": "1.1.0"
10
10
  },
11
11
  "keywords": [
12
12
  "typescript",