From 04e0741a3272d187888115d7d89b4d1fac131ccf Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 4 Apr 2024 07:59:59 -0400 Subject: [PATCH 1/5] Update README.md --- README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b9a6f1..6358234 100644 --- a/README.md +++ b/README.md @@ -622,12 +622,29 @@ Note: untrack doesn't get you out of the `notifying` state, which is maintained **Q**: What are Signals offering that `Proxy` doesn't currently handle? -**A**: Proxies must wrap some object. They cannot be used to intercept property access/assignment to primitive values such as numbers, strings, or symbols. -See Prior Implementations [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private), [discussion](https://github.com/proposal-signals/proposal-signals/issues/101#issuecomment-2029802574). The following is valid for a Signal, but not for a Proxy: +**A**: Proxies must wrap some object and do not inherently participate in a reactive graph. the reactive graph is built by objects that know about and discover other reactive data during the calculation of a value. Probies also have a usage limitation: they cannot be used to intercept property access/assignment to primitive values such as numbers, strings, or symbols. +See example prior implementations for the relationship between reactive data atd proxies: [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private), [discussion](https://github.com/proposal-signals/proposal-signals/issues/101#issuecomment-2029802574). The following is valid for a Signal, but not for a Proxy: ```js new Proxy(0, { ... }) // TypeError: Cannot create proxy with a non-object as target or handler new Signal.State(0); // Perfectly valid ``` +in a reactive ui use case, the signal change will show up to the user, but the proxy change will not: +```js +const a = { count: 0 }; +const b = new Proxy(a, {}); +const c = new Signal.State(0); + + +``` +when using a renderer that is optimized for fine-grained reactivity, clicking the button will cause the `c.get` cell to be updated, but `b.count` will forever remain 0, because b is not reactive. #### How do Signals work? From 0ae7423915a0988ab524bebb3c014c4e4e3ddec2 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 4 Apr 2024 08:12:31 -0400 Subject: [PATCH 2/5] Update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6358234..8eea68a 100644 --- a/README.md +++ b/README.md @@ -622,13 +622,20 @@ Note: untrack doesn't get you out of the `notifying` state, which is maintained **Q**: What are Signals offering that `Proxy` doesn't currently handle? -**A**: Proxies must wrap some object and do not inherently participate in a reactive graph. the reactive graph is built by objects that know about and discover other reactive data during the calculation of a value. Probies also have a usage limitation: they cannot be used to intercept property access/assignment to primitive values such as numbers, strings, or symbols. +**A**: Proxies must wrap some object and do not inherently participate in a reactive graph. +Signals are things that can be part of this graph, and are well-behaved as citizens of it. +The reactive graph is built over time by the relationships between reactive data, resulting in what is called 'autotracking'. + +Proxies also have a usage limitation: they cannot be used to intercept property access/assignment to primitive values such as numbers, strings, or symbols. See example prior implementations for the relationship between reactive data atd proxies: [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private), [discussion](https://github.com/proposal-signals/proposal-signals/issues/101#issuecomment-2029802574). The following is valid for a Signal, but not for a Proxy: ```js new Proxy(0, { ... }) // TypeError: Cannot create proxy with a non-object as target or handler new Signal.State(0); // Perfectly valid ``` -in a reactive ui use case, the signal change will show up to the user, but the proxy change will not: + +Reactive objects are completely inert on their own and become special when used in a reactive _context_ that lets them autotrack dependencies. + +In thin example, a reactive ui use case, the signal change will show up to the user, but the proxy change will not: ```js const a = { count: 0 }; const b = new Proxy(a, {}); From 2095a57eafa7734274d2679d1fa1fbf581d22c12 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 4 Apr 2024 08:16:15 -0400 Subject: [PATCH 3/5] Update README.md --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8eea68a..05c87a8 100644 --- a/README.md +++ b/README.md @@ -627,7 +627,7 @@ Signals are things that can be part of this graph, and are well-behaved as citiz The reactive graph is built over time by the relationships between reactive data, resulting in what is called 'autotracking'. Proxies also have a usage limitation: they cannot be used to intercept property access/assignment to primitive values such as numbers, strings, or symbols. -See example prior implementations for the relationship between reactive data atd proxies: [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private), [discussion](https://github.com/proposal-signals/proposal-signals/issues/101#issuecomment-2029802574). The following is valid for a Signal, but not for a Proxy: + The following is valid for a Signal, but not for a Proxy: ```js new Proxy(0, { ... }) // TypeError: Cannot create proxy with a non-object as target or handler new Signal.State(0); // Perfectly valid @@ -635,7 +635,7 @@ new Signal.State(0); // Perfectly valid Reactive objects are completely inert on their own and become special when used in a reactive _context_ that lets them autotrack dependencies. -In thin example, a reactive ui use case, the signal change will show up to the user, but the proxy change will not: +In this example, a reactive ui use case, the signal change will show up to the user, but the proxy change will not: ```js const a = { count: 0 }; const b = new Proxy(a, {}); @@ -651,7 +651,11 @@ const c = new Signal.State(0); }}>change ``` -when using a renderer that is optimized for fine-grained reactivity, clicking the button will cause the `c.get` cell to be updated, but `b.count` will forever remain 0, because b is not reactive. +when using a renderer that is optimized for fine-grained reactivity, clicking the button will cause the `c.get` cell to be updated, but `b.count` will forever remain 0, because `b` (and `b.count`) is not reactive. + +See: +- example prior implementations for the relationship between reactive data atd proxies: [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private) +- [discussion](https://github.com/proposal-signals/proposal-signals/issues/101#issuecomment-2029802574). #### How do Signals work? From 711e201067e1745c4de3b0bd2c93bf382359e2d6 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 5 Apr 2024 08:06:05 -0400 Subject: [PATCH 4/5] Update README.md --- README.md | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 05c87a8..2a7b9c1 100644 --- a/README.md +++ b/README.md @@ -622,36 +622,34 @@ Note: untrack doesn't get you out of the `notifying` state, which is maintained **Q**: What are Signals offering that `Proxy` doesn't currently handle? -**A**: Proxies must wrap some object and do not inherently participate in a reactive graph. -Signals are things that can be part of this graph, and are well-behaved as citizens of it. -The reactive graph is built over time by the relationships between reactive data, resulting in what is called 'autotracking'. +**A**: Proxies must wrap some object and do not inherently participate in a reactive graph. Proxies can be used to change the ergonomics of a reactive data structure. -Proxies also have a usage limitation: they cannot be used to intercept property access/assignment to primitive values such as numbers, strings, or symbols. - The following is valid for a Signal, but not for a Proxy: +In this example, we can use a proxy to make the signal have a getter and setter property instead of using the `get` and `set` methods: ```js -new Proxy(0, { ... }) // TypeError: Cannot create proxy with a non-object as target or handler -new Signal.State(0); // Perfectly valid -``` - -Reactive objects are completely inert on their own and become special when used in a reactive _context_ that lets them autotrack dependencies. - -In this example, a reactive ui use case, the signal change will show up to the user, but the proxy change will not: -```js -const a = { count: 0 }; -const b = new Proxy(a, {}); -const c = new Signal.State(0); +const a = new Signal.State(0); +const b = new Proxy(a, { + get(target, property, receiver) { + if (property === 'value') { + return target.get(): + } + } + set(target, property, value, receiver) { + if (property === 'value') { + target.set(value)! + } + } +}); +// usage in a hypothetical reactive context: ``` -when using a renderer that is optimized for fine-grained reactivity, clicking the button will cause the `c.get` cell to be updated, but `b.count` will forever remain 0, because `b` (and `b.count`) is not reactive. +when using a renderer that is optimized for fine-grained reactivity, clicking the button will cause the `b.value` cell to be updated. See: - example prior implementations for the relationship between reactive data atd proxies: [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private) From 1d754fe2eadfcaa3619a141e87073c5f0fea8f51 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 5 Apr 2024 14:00:04 -0400 Subject: [PATCH 5/5] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2a7b9c1..14009fe 100644 --- a/README.md +++ b/README.md @@ -622,7 +622,7 @@ Note: untrack doesn't get you out of the `notifying` state, which is maintained **Q**: What are Signals offering that `Proxy` doesn't currently handle? -**A**: Proxies must wrap some object and do not inherently participate in a reactive graph. Proxies can be used to change the ergonomics of a reactive data structure. +**A**: Proxies and Signals are complementary and go well together. Proxies let you intercept shallow object operations and signals coordinate a dependency graph (of cells). Backing a Proxy with Signals is a great way to make a nested reactive structure with great ergonomics. In this example, we can use a proxy to make the signal have a getter and setter property instead of using the `get` and `set` methods: ```js @@ -652,7 +652,8 @@ const b = new Proxy(a, { when using a renderer that is optimized for fine-grained reactivity, clicking the button will cause the `b.value` cell to be updated. See: -- example prior implementations for the relationship between reactive data atd proxies: [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private) +- examples of nested reactive structures created with both Signals and Proxies: [signal-utils](https://github.com/NullVoxPopuli/signal-utils/tree/main/src) +- example prior implementations showing the relationship between reactive data atd proxies: [tracked-built-ins](https://github.com/tracked-tools/tracked-built-ins/tree/master/addon/src/-private) - [discussion](https://github.com/proposal-signals/proposal-signals/issues/101#issuecomment-2029802574). #### How do Signals work?