simplyflow 0.2.3 → 0.3.1

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/src/state.mjs CHANGED
@@ -2,12 +2,18 @@ const iterate = Symbol('iterate')
2
2
  if (!Symbol.xRay) {
3
3
  Symbol.xRay = Symbol('xRay')
4
4
  }
5
+ if (!Symbol.Signal) {
6
+ Symbol.Signal = Symbol('Signal')
7
+ }
5
8
 
6
9
  const signalHandler = {
7
10
  get: (target, property, receiver) => {
8
11
  if (property===Symbol.xRay) {
9
12
  return target // don't notifyGet here, this is only called by set
10
13
  }
14
+ if (property===Symbol.Signal) {
15
+ return true
16
+ }
11
17
  const value = target?.[property] // Reflect.get fails on a Set.
12
18
  notifyGet(receiver, property)
13
19
  if (typeof value === 'function') {
@@ -116,12 +122,40 @@ const signals = new WeakMap()
116
122
  * to allow reactive functions to be triggered when signal values change.
117
123
  */
118
124
  export function signal(v) {
119
- if (!signals.has(v)) {
125
+ if (v[Symbol.Signal]) { // avoid wrapping a Signal inside a Signal
126
+ let target = v[Symbol.xRay]
127
+ if (!signals.has(target)) {
128
+ signals.set(target, v)
129
+ }
130
+ v = target
131
+ } else if (!signals.has(v)) {
120
132
  signals.set(v, new Proxy(v, signalHandler))
121
133
  }
122
134
  return signals.get(v)
123
135
  }
124
136
 
137
+ /**
138
+ * Lists all effects that are currently listening to changes in
139
+ * the given signal and property
140
+ * returns a list with
141
+ * - effect: the effect function (effect, throttledEffect, clockEffect)
142
+ * - fn: the user provided function to this effect function
143
+ * - signal: the connectedSignal to this user provided function
144
+ * @param Signal signal
145
+ * @param string prop
146
+ * @return array of { effect, fn, signal }
147
+ */
148
+ export function trace(signal, prop) {
149
+ const listeners = getListeners(signal, prop)
150
+ return listeners.map(listener => {
151
+ return {
152
+ effect: listener.effectType,
153
+ fn: listener.effectFunction,
154
+ signal: signals.get(listener.effectFunction)
155
+ }
156
+ })
157
+ }
158
+
125
159
  let batchedListeners = new Set()
126
160
  let batchMode = 0
127
161
  /**
@@ -308,6 +342,8 @@ export function effect(fn) {
308
342
  }
309
343
  // remove all dependencies (signals) from previous runs
310
344
  clearListeners(computeEffect)
345
+ computeEffect.effectFunction = fn
346
+ computeEffect.effectType = effect
311
347
  // record new dependencies on this run
312
348
  computeStack.push(computeEffect)
313
349
  // prevent recursion
@@ -437,6 +473,8 @@ export function throttledEffect(fn, throttleTime) {
437
473
  // remove all dependencies (signals) from previous runs
438
474
  clearListeners(computeEffect)
439
475
  // record new dependencies on this run
476
+ computeEffect.effectFunction = fn
477
+ computeEffect.effectType = throttledEffect
440
478
  computeStack.push(computeEffect)
441
479
  // prevent recursion
442
480
  signalStack.push(connectedSignal)
@@ -493,6 +531,8 @@ export function clockEffect(fn, clock) {
493
531
  if (hasChanged) {
494
532
  // remove all dependencies (signals) from previous runs
495
533
  clearListeners(computeEffect)
534
+ computeEffect.effectFunction = fn
535
+ computeEffect.effectType = clockEffect
496
536
  // record new dependencies on this run
497
537
  computeStack.push(computeEffect)
498
538
  // make sure the clock.time signal is a dependency