@tstdl/base 0.88.0-alpha1 → 0.88.0-alpha3

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 (78) hide show
  1. package/authentication/index.d.ts +1 -0
  2. package/authentication/index.js +1 -0
  3. package/browser/index.d.ts +1 -0
  4. package/browser/index.js +1 -0
  5. package/data-structures/index.d.ts +1 -0
  6. package/data-structures/index.js +1 -0
  7. package/http/client/adapters/index.d.ts +1 -0
  8. package/http/client/adapters/index.js +1 -0
  9. package/http/client/index.d.ts +2 -0
  10. package/http/client/index.js +2 -0
  11. package/mail/clients/index.d.ts +1 -0
  12. package/mail/clients/index.js +1 -0
  13. package/mail/index.d.ts +2 -0
  14. package/mail/index.js +2 -0
  15. package/mail/mail.service.d.ts +1 -1
  16. package/mail/mail.service.js +1 -1
  17. package/mail/module.d.ts +1 -1
  18. package/mail/module.js +1 -1
  19. package/mail/repositories/index.d.ts +1 -0
  20. package/mail/repositories/index.js +1 -0
  21. package/mail/repositories/mail-log.repository.d.ts +4 -0
  22. package/mail/{mail-log.repository.js → repositories/mail-log.repository.js} +1 -1
  23. package/mail/repositories/mongo/index.d.ts +1 -0
  24. package/mail/repositories/mongo/index.js +1 -0
  25. package/mail/repositories/{mongo-mail-log.repository.d.ts → mongo/mongo-mail-log.repository.d.ts} +6 -6
  26. package/mail/repositories/{mongo-mail-log.repository.js → mongo/mongo-mail-log.repository.js} +3 -3
  27. package/package.json +103 -6
  28. package/random/number-generator/index.d.ts +2 -0
  29. package/random/number-generator/index.js +2 -0
  30. package/random/number-generator/utils.d.ts +1 -0
  31. package/random/number-generator/utils.js +5 -0
  32. package/rpc/endpoints/index.d.ts +1 -0
  33. package/rpc/endpoints/index.js +1 -0
  34. package/rpc/endpoints/message-port.rpc-endpoint.js +1 -1
  35. package/signals/implementation/api.d.ts +1 -18
  36. package/signals/implementation/api.js +1 -10
  37. package/signals/implementation/computed.js +42 -94
  38. package/signals/implementation/effect.d.ts +1 -1
  39. package/signals/implementation/effect.js +16 -15
  40. package/signals/implementation/graph.d.ts +118 -73
  41. package/signals/implementation/graph.js +235 -156
  42. package/signals/implementation/signal.js +58 -81
  43. package/signals/implementation/watch.d.ts +2 -18
  44. package/signals/implementation/watch.js +37 -54
  45. package/sse/index.d.ts +1 -0
  46. package/sse/index.js +1 -0
  47. package/templates/providers/index.d.ts +2 -0
  48. package/templates/providers/index.js +2 -0
  49. package/templates/renderers/index.d.ts +4 -0
  50. package/templates/renderers/index.js +4 -0
  51. package/templates/resolvers/index.d.ts +3 -0
  52. package/templates/resolvers/index.js +3 -0
  53. package/templates/types/index.d.ts +1 -0
  54. package/templates/types/index.js +1 -0
  55. package/text/dynamic-text.model.js +3 -5
  56. package/theme/adapters/index.d.ts +2 -0
  57. package/theme/adapters/index.js +2 -0
  58. package/utils/index.d.ts +8 -0
  59. package/utils/index.js +8 -0
  60. package/async-iterator-symbol.d.ts +0 -1
  61. package/async-iterator-symbol.js +0 -6
  62. package/mail/mail-log.repository.d.ts +0 -4
  63. package/notification/api.d.ts +0 -15
  64. package/notification/api.js +0 -28
  65. package/notification/models/index.d.ts +0 -2
  66. package/notification/models/index.js +0 -2
  67. package/notification/models/notification-channel-job.model.d.ts +0 -3
  68. package/notification/models/notification-channel-job.model.js +0 -1
  69. package/notification/models/notification.model.d.ts +0 -45
  70. package/notification/models/notification.model.js +0 -103
  71. package/notification/module.d.ts +0 -9
  72. package/notification/module.js +0 -10
  73. package/notification/notification-channel.service.d.ts +0 -5
  74. package/notification/notification-channel.service.js +0 -2
  75. package/notification/notification.repository.d.ts +0 -5
  76. package/notification/notification.repository.js +0 -2
  77. package/notification/notification.service.d.ts +0 -8
  78. package/notification/notification.service.js +0 -36
@@ -5,7 +5,7 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { Watch } from './watch.js';
8
+ import { watch } from './watch.js';
9
9
  /**
10
10
  * Tracks all effects registered within a given application and runs them via `flush`.
11
11
  */
@@ -13,12 +13,12 @@ export class EffectManager {
13
13
  all = new Set();
14
14
  queue = new Set();
15
15
  pendingFlush;
16
- create(effectFn, { allowSignalWrites = false } = {}) {
17
- const watch = new Watch(effectFn, (watch) => {
18
- if (!this.all.has(watch)) {
16
+ create(effectFn, allowSignalWrites) {
17
+ const w = watch(effectFn, () => {
18
+ if (!this.all.has(w)) {
19
19
  return;
20
20
  }
21
- this.queue.add(watch);
21
+ this.queue.add(w);
22
22
  if (!this.pendingFlush) {
23
23
  this.pendingFlush = true;
24
24
  queueMicrotask(() => {
@@ -27,24 +27,25 @@ export class EffectManager {
27
27
  });
28
28
  }
29
29
  }, allowSignalWrites);
30
- this.all.add(watch);
31
- watch.notify();
30
+ this.all.add(w);
31
+ // Effects start dirty.
32
+ w.notify();
32
33
  const destroy = () => {
33
- watch.cleanup();
34
- this.all.delete(watch);
35
- this.queue.delete(watch);
34
+ w.cleanup();
35
+ this.all.delete(w);
36
+ this.queue.delete(w);
36
37
  };
37
38
  return {
38
39
  destroy
39
40
  };
40
41
  }
41
42
  flush() {
42
- if (this.queue.size == 0) {
43
+ if (this.queue.size === 0) {
43
44
  return;
44
45
  }
45
- for (const watch of this.queue) {
46
- this.queue.delete(watch);
47
- watch.run();
46
+ for (const w of this.queue) {
47
+ this.queue.delete(w);
48
+ w.run();
48
49
  }
49
50
  }
50
51
  get isQueueEmpty() {
@@ -56,5 +57,5 @@ const effectManager = new EffectManager();
56
57
  * Create a global `Effect` for the given reactive function.
57
58
  */
58
59
  export function effect(effectFn, options) {
59
- return effectManager.create(effectFn, options);
60
+ return effectManager.create(effectFn, options?.allowSignalWrites ?? false);
60
61
  }
@@ -5,104 +5,149 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ type Version = number & {
9
+ __brand: 'Version';
10
+ };
8
11
  export declare function setActiveConsumer(consumer: ReactiveNode | null): ReactiveNode | null;
12
+ export declare const REACTIVE_NODE: {
13
+ version: Version;
14
+ dirty: boolean;
15
+ producerNode: undefined;
16
+ producerLastReadVersion: undefined;
17
+ producerIndexOfThis: undefined;
18
+ nextProducerIndex: number;
19
+ liveConsumerNode: undefined;
20
+ liveConsumerIndexOfThis: undefined;
21
+ consumerAllowSignalWrites: boolean;
22
+ consumerIsAlwaysLive: boolean;
23
+ producerMustRecompute: () => boolean;
24
+ producerRecomputeValue: () => void;
25
+ consumerMarkedDirty: () => void;
26
+ };
9
27
  /**
10
- * A node in the reactive graph.
28
+ * A producer and/or consumer which participates in the reactive graph.
11
29
  *
12
- * Nodes can be producers of reactive values, consumers of other reactive values, or both.
30
+ * Producer `ReactiveNode`s which are accessed when a consumer `ReactiveNode` is the
31
+ * `activeConsumer` are tracked as dependencies of that consumer.
13
32
  *
14
- * Producers are nodes that produce values, and can be depended upon by consumer nodes.
33
+ * Certain consumers are also tracked as "live" consumers and create edges in the other direction,
34
+ * from producer to consumer. These edges are used to propagate change notifications when a
35
+ * producer's value is updated.
15
36
  *
16
- * Producers expose a monotonic `valueVersion` counter, and are responsible for incrementing this
17
- * version when their value semantically changes. Some producers may produce their values lazily and
18
- * thus at times need to be polled for potential updates to their value (and by extension their
19
- * `valueVersion`). This is accomplished via the `onProducerUpdateValueVersion` method for
20
- * implemented by producers, which should perform whatever calculations are necessary to ensure
21
- * `valueVersion` is up to date.
22
- *
23
- * Consumers are nodes that depend on the values of producers and are notified when those values
24
- * might have changed.
25
- *
26
- * Consumers do not wrap the reads they consume themselves, but rather can be set as the active
27
- * reader via `setActiveConsumer`. Reads of producers that happen while a consumer is active will
28
- * result in those producers being added as dependencies of that consumer node.
29
- *
30
- * The set of dependencies of a consumer is dynamic. Implementers expose a monotonically increasing
31
- * `trackingVersion` counter, which increments whenever the consumer is about to re-run any reactive
32
- * reads it needs and establish a new set of dependencies as a result.
33
- *
34
- * Producers store the last `trackingVersion` they've seen from `Consumer`s which have read them.
35
- * This allows a producer to identify whether its record of the dependency is current or stale, by
36
- * comparing the consumer's `trackingVersion` to the version at which the dependency was
37
- * last observed.
37
+ * A `ReactiveNode` may be both a producer and consumer.
38
38
  */
39
- export declare abstract class ReactiveNode {
40
- private readonly id;
41
- /**
42
- * A cached weak reference to this node, which will be used in `ReactiveEdge`s.
43
- */
44
- private readonly ref;
45
- /**
46
- * Edges to producers on which this node depends (in its consumer capacity).
47
- */
48
- private readonly producers;
49
- /**
50
- * Edges to consumers on which this node depends (in its producer capacity).
51
- */
52
- private readonly consumers;
39
+ export interface ReactiveNode {
53
40
  /**
54
- * Monotonically increasing counter representing a version of this `Consumer`'s
55
- * dependencies.
56
- */
57
- protected trackingVersion: number;
58
- /**
59
- * Monotonically increasing counter which increases when the value of this `Producer`
60
- * semantically changes.
41
+ * Version of the value that this node produces.
42
+ *
43
+ * This is incremented whenever a new value is produced by this node which is not equal to the
44
+ * previous value (by whatever definition of equality is in use).
61
45
  */
62
- protected valueVersion: number;
46
+ version: Version;
63
47
  /**
64
- * Whether signal writes should be allowed while this `ReactiveNode` is the current consumer.
48
+ * Whether this node (in its consumer capacity) is dirty.
49
+ *
50
+ * Only live consumers become dirty, when receiving a change notification from a dependency
51
+ * producer.
65
52
  */
66
- protected abstract readonly consumerAllowSignalWrites: boolean;
53
+ dirty: boolean;
67
54
  /**
68
- * Called for consumers whenever one of their dependencies notifies that it might have a new
69
- * value.
55
+ * Producers which are dependencies of this consumer.
56
+ *
57
+ * Uses the same indices as the `producerLastReadVersion` and `producerIndexOfThis` arrays.
70
58
  */
71
- protected abstract onConsumerDependencyMayHaveChanged(): void;
59
+ producerNode: ReactiveNode[] | undefined;
72
60
  /**
73
- * Called for producers when a dependent consumer is checking if the producer's value has actually
74
- * changed.
61
+ * `Version` of the value last read by a given producer.
62
+ *
63
+ * Uses the same indices as the `producerNode` and `producerIndexOfThis` arrays.
75
64
  */
76
- protected abstract onProducerUpdateValueVersion(): void;
65
+ producerLastReadVersion: Version[] | undefined;
77
66
  /**
78
- * Polls dependencies of a consumer to determine if they have actually changed.
67
+ * Index of `this` (consumer) in each producer's `liveConsumers` array.
68
+ *
69
+ * This value is only meaningful if this node is live (`liveConsumers.length > 0`). Otherwise
70
+ * these indices are stale.
79
71
  *
80
- * If this returns `false`, then even though the consumer may have previously been notified of a
81
- * change, the values of its dependencies have not actually changed and the consumer should not
82
- * rerun any reactions.
72
+ * Uses the same indices as the `producerNode` and `producerLastReadVersion` arrays.
83
73
  */
84
- protected consumerPollProducersForChange(): boolean;
74
+ producerIndexOfThis: number[] | undefined;
85
75
  /**
86
- * Notify all consumers of this producer that its value may have changed.
76
+ * Index into the producer arrays that the next dependency of this node as a consumer will use.
77
+ *
78
+ * This index is zeroed before this node as a consumer begins executing. When a producer is read,
79
+ * it gets inserted into the producers arrays at this index. There may be an existing dependency
80
+ * in this location which may or may not match the incoming producer, depending on whether the
81
+ * same producers were read in the same order as the last computation.
87
82
  */
88
- protected producerMayHaveChanged(): void;
83
+ nextProducerIndex: number;
89
84
  /**
90
- * Mark that this producer node has been accessed in the current reactive context.
85
+ * Array of consumers of this producer that are "live" (they require push notifications).
86
+ *
87
+ * `liveConsumerNode.length` is effectively our reference count for this node.
91
88
  */
92
- protected producerAccessed(): void;
89
+ liveConsumerNode: ReactiveNode[] | undefined;
93
90
  /**
94
- * Whether this consumer currently has any producers registered.
91
+ * Index of `this` (producer) in each consumer's `producerNode` array.
92
+ *
93
+ * Uses the same indices as the `liveConsumerNode` array.
95
94
  */
96
- protected get hasProducers(): boolean;
95
+ liveConsumerIndexOfThis: number[] | undefined;
97
96
  /**
98
- * Whether this `ReactiveNode` in its producer capacity is currently allowed to initiate updates,
99
- * based on the current consumer context.
97
+ * Whether writes to signals are allowed when this consumer is the `activeConsumer`.
98
+ *
99
+ * This is used to enforce guardrails such as preventing writes to writable signals in the
100
+ * computation function of computed signals, which is supposed to be pure.
100
101
  */
101
- protected get producerUpdatesAllowed(): boolean;
102
+ consumerAllowSignalWrites: boolean;
103
+ readonly consumerIsAlwaysLive: boolean;
102
104
  /**
103
- * Checks if a `Producer` has a current value which is different than the value
104
- * last seen at a specific version by a `Consumer` which recorded a dependency on
105
- * this `Producer`.
105
+ * Tracks whether producers need to recompute their value independently of the reactive graph (for
106
+ * example, if no initial value has been computed).
106
107
  */
107
- private producerPollStatus;
108
+ producerMustRecompute(node: unknown): boolean;
109
+ producerRecomputeValue(node: unknown): void;
110
+ consumerMarkedDirty(node: unknown): void;
108
111
  }
112
+ /**
113
+ * Called by implementations when a producer's signal is read.
114
+ */
115
+ export declare function producerAccessed(node: ReactiveNode): void;
116
+ /**
117
+ * Ensure this producer's `version` is up-to-date.
118
+ */
119
+ export declare function producerUpdateValueVersion(node: ReactiveNode): void;
120
+ /**
121
+ * Propagate a dirty notification to live consumers of this producer.
122
+ */
123
+ export declare function producerNotifyConsumers(node: ReactiveNode): void;
124
+ /**
125
+ * Whether this `ReactiveNode` in its producer capacity is currently allowed to initiate updates,
126
+ * based on the current consumer context.
127
+ */
128
+ export declare function producerUpdatesAllowed(): boolean;
129
+ export declare function consumerMarkDirty(node: ReactiveNode): void;
130
+ /**
131
+ * Prepare this consumer to run a computation in its reactive context.
132
+ *
133
+ * Must be called by subclasses which represent reactive computations, before those computations
134
+ * begin.
135
+ */
136
+ export declare function consumerBeforeComputation(node: ReactiveNode | null): ReactiveNode | null;
137
+ /**
138
+ * Finalize this consumer's state after a reactive computation has run.
139
+ *
140
+ * Must be called by subclasses which represent reactive computations, after those computations
141
+ * have finished.
142
+ */
143
+ export declare function consumerAfterComputation(node: ReactiveNode | null, prevConsumer: ReactiveNode | null): void;
144
+ /**
145
+ * Determine whether this consumer has any dependencies which have changed since the last time
146
+ * they were read.
147
+ */
148
+ export declare function consumerPollProducersForChange(node: ReactiveNode): boolean;
149
+ /**
150
+ * Disconnect this consumer from the graph.
151
+ */
152
+ export declare function consumerDestroy(node: ReactiveNode): void;
153
+ export {};