graph.d.d.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /**
  2. * @license Angular v20.1.0
  3. * (c) 2010-2025 Google LLC. https://angular.io/
  4. * License: MIT
  5. */
  6. /**
  7. * A comparison function which can determine if two values are equal.
  8. */
  9. type ValueEqualityFn<T> = (a: T, b: T) => boolean;
  10. /**
  11. * The default equality function used for `signal` and `computed`, which uses referential equality.
  12. */
  13. declare function defaultEquals<T>(a: T, b: T): boolean;
  14. type Version = number & {
  15. __brand: 'Version';
  16. };
  17. type ReactiveHookFn = (node: ReactiveNode) => void;
  18. /**
  19. * Symbol used to tell `Signal`s apart from other functions.
  20. *
  21. * This can be used to auto-unwrap signals in various cases, or to auto-wrap non-signal values.
  22. */
  23. declare const SIGNAL: unique symbol;
  24. declare function setActiveConsumer(consumer: ReactiveNode | null): ReactiveNode | null;
  25. declare function getActiveConsumer(): ReactiveNode | null;
  26. declare function isInNotificationPhase(): boolean;
  27. interface Reactive {
  28. [SIGNAL]: ReactiveNode;
  29. }
  30. declare function isReactive(value: unknown): value is Reactive;
  31. declare const REACTIVE_NODE: ReactiveNode;
  32. /**
  33. * A producer and/or consumer which participates in the reactive graph.
  34. *
  35. * Producer `ReactiveNode`s which are accessed when a consumer `ReactiveNode` is the
  36. * `activeConsumer` are tracked as dependencies of that consumer.
  37. *
  38. * Certain consumers are also tracked as "live" consumers and create edges in the other direction,
  39. * from producer to consumer. These edges are used to propagate change notifications when a
  40. * producer's value is updated.
  41. *
  42. * A `ReactiveNode` may be both a producer and consumer.
  43. */
  44. interface ReactiveNode {
  45. /**
  46. * Version of the value that this node produces.
  47. *
  48. * This is incremented whenever a new value is produced by this node which is not equal to the
  49. * previous value (by whatever definition of equality is in use).
  50. */
  51. version: Version;
  52. /**
  53. * Epoch at which this node is verified to be clean.
  54. *
  55. * This allows skipping of some polling operations in the case where no signals have been set
  56. * since this node was last read.
  57. */
  58. lastCleanEpoch: Version;
  59. /**
  60. * Whether this node (in its consumer capacity) is dirty.
  61. *
  62. * Only live consumers become dirty, when receiving a change notification from a dependency
  63. * producer.
  64. */
  65. dirty: boolean;
  66. /**
  67. * Producers which are dependencies of this consumer.
  68. *
  69. * Uses the same indices as the `producerLastReadVersion` and `producerIndexOfThis` arrays.
  70. */
  71. producerNode: ReactiveNode[] | undefined;
  72. /**
  73. * `Version` of the value last read by a given producer.
  74. *
  75. * Uses the same indices as the `producerNode` and `producerIndexOfThis` arrays.
  76. */
  77. producerLastReadVersion: Version[] | undefined;
  78. /**
  79. * Index of `this` (consumer) in each producer's `liveConsumers` array.
  80. *
  81. * This value is only meaningful if this node is live (`liveConsumers.length > 0`). Otherwise
  82. * these indices are stale.
  83. *
  84. * Uses the same indices as the `producerNode` and `producerLastReadVersion` arrays.
  85. */
  86. producerIndexOfThis: number[] | undefined;
  87. /**
  88. * Index into the producer arrays that the next dependency of this node as a consumer will use.
  89. *
  90. * This index is zeroed before this node as a consumer begins executing. When a producer is read,
  91. * it gets inserted into the producers arrays at this index. There may be an existing dependency
  92. * in this location which may or may not match the incoming producer, depending on whether the
  93. * same producers were read in the same order as the last computation.
  94. */
  95. nextProducerIndex: number;
  96. /**
  97. * Array of consumers of this producer that are "live" (they require push notifications).
  98. *
  99. * `liveConsumerNode.length` is effectively our reference count for this node.
  100. */
  101. liveConsumerNode: ReactiveNode[] | undefined;
  102. /**
  103. * Index of `this` (producer) in each consumer's `producerNode` array.
  104. *
  105. * Uses the same indices as the `liveConsumerNode` array.
  106. */
  107. liveConsumerIndexOfThis: number[] | undefined;
  108. /**
  109. * Whether writes to signals are allowed when this consumer is the `activeConsumer`.
  110. *
  111. * This is used to enforce guardrails such as preventing writes to writable signals in the
  112. * computation function of computed signals, which is supposed to be pure.
  113. */
  114. consumerAllowSignalWrites: boolean;
  115. readonly consumerIsAlwaysLive: boolean;
  116. /**
  117. * Tracks whether producers need to recompute their value independently of the reactive graph (for
  118. * example, if no initial value has been computed).
  119. */
  120. producerMustRecompute(node: unknown): boolean;
  121. producerRecomputeValue(node: unknown): void;
  122. consumerMarkedDirty(node: unknown): void;
  123. /**
  124. * Called when a signal is read within this consumer.
  125. */
  126. consumerOnSignalRead(node: unknown): void;
  127. /**
  128. * A debug name for the reactive node. Used in Angular DevTools to identify the node.
  129. */
  130. debugName?: string;
  131. /**
  132. * Kind of node. Example: 'signal', 'computed', 'input', 'effect'.
  133. *
  134. * ReactiveNode has this as 'unknown' by default, but derived node types should override this to
  135. * make available the kind of signal that particular instance of a ReactiveNode represents.
  136. *
  137. * Used in Angular DevTools to identify the kind of signal.
  138. */
  139. kind: string;
  140. }
  141. /**
  142. * Called by implementations when a producer's signal is read.
  143. */
  144. declare function producerAccessed(node: ReactiveNode): void;
  145. /**
  146. * Increment the global epoch counter.
  147. *
  148. * Called by source producers (that is, not computeds) whenever their values change.
  149. */
  150. declare function producerIncrementEpoch(): void;
  151. /**
  152. * Ensure this producer's `version` is up-to-date.
  153. */
  154. declare function producerUpdateValueVersion(node: ReactiveNode): void;
  155. /**
  156. * Propagate a dirty notification to live consumers of this producer.
  157. */
  158. declare function producerNotifyConsumers(node: ReactiveNode): void;
  159. /**
  160. * Whether this `ReactiveNode` in its producer capacity is currently allowed to initiate updates,
  161. * based on the current consumer context.
  162. */
  163. declare function producerUpdatesAllowed(): boolean;
  164. declare function consumerMarkDirty(node: ReactiveNode): void;
  165. declare function producerMarkClean(node: ReactiveNode): void;
  166. /**
  167. * Prepare this consumer to run a computation in its reactive context.
  168. *
  169. * Must be called by subclasses which represent reactive computations, before those computations
  170. * begin.
  171. */
  172. declare function consumerBeforeComputation(node: ReactiveNode | null): ReactiveNode | null;
  173. /**
  174. * Finalize this consumer's state after a reactive computation has run.
  175. *
  176. * Must be called by subclasses which represent reactive computations, after those computations
  177. * have finished.
  178. */
  179. declare function consumerAfterComputation(node: ReactiveNode | null, prevConsumer: ReactiveNode | null): void;
  180. /**
  181. * Determine whether this consumer has any dependencies which have changed since the last time
  182. * they were read.
  183. */
  184. declare function consumerPollProducersForChange(node: ReactiveNode): boolean;
  185. /**
  186. * Disconnect this consumer from the graph.
  187. */
  188. declare function consumerDestroy(node: ReactiveNode): void;
  189. declare function runPostProducerCreatedFn(node: ReactiveNode): void;
  190. declare function setPostProducerCreatedFn(fn: ReactiveHookFn | null): ReactiveHookFn | null;
  191. export { REACTIVE_NODE, SIGNAL, consumerAfterComputation, consumerBeforeComputation, consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, defaultEquals, getActiveConsumer, isInNotificationPhase, isReactive, producerAccessed, producerIncrementEpoch, producerMarkClean, producerNotifyConsumers, producerUpdateValueVersion, producerUpdatesAllowed, runPostProducerCreatedFn, setActiveConsumer, setPostProducerCreatedFn };
  192. export type { Reactive, ReactiveHookFn, ReactiveNode, ValueEqualityFn };