preact icon indicating copy to clipboard operation
preact copied to clipboard

Fix event bubbling can break in test conditions (#4161)

Open nbalatsk-oracle opened this issue 1 year ago • 15 comments

This should fix #4161.

The idea is to use a global counter that will increment on event dispatch only, so it’s less likely that the globalCounter will overflow and the order of _attached/_dispatched is going to be guaranteed.

nbalatsk-oracle avatar Dec 15 '23 01:12 nbalatsk-oracle

📊 Tachometer Benchmark Results

Summary

duration

  • 02_replace1k: unsure 🔍 -1% - +1% (-0.97ms - +1.08ms)
    preact-local vs preact-main
  • 03_update10th1k_x16: unsure 🔍 -4% - +3% (-1.31ms - +1.21ms)
    preact-local vs preact-main
  • 07_create10k: unsure 🔍 -1% - +1% (-5.12ms - +4.43ms)
    preact-local vs preact-main
  • filter_list: unsure 🔍 -3% - +8% (-0.51ms - +1.29ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -4% - +1% (-2.92ms - +0.94ms)
    preact-local vs preact-main
  • many_updates: unsure 🔍 -1% - +3% (-0.15ms - +0.43ms)
    preact-local vs preact-main
  • text_update: unsure 🔍 -5% - +4% (-0.12ms - +0.10ms)
    preact-local vs preact-main
  • todo: unsure 🔍 -1% - +1% (-0.18ms - +0.24ms)
    preact-local vs preact-main

usedJSHeapSize

  • 02_replace1k: faster ✔ 0% - 1% (0.01ms - 0.02ms)
    preact-local vs preact-main
  • 03_update10th1k_x16: faster ✔ 0% - 1% (0.01ms - 0.03ms)
    preact-local vs preact-main
  • 07_create10k: faster ✔ 1% - 1% (0.24ms - 0.24ms)
    preact-local vs preact-main
  • filter_list: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • hydrate1k: faster ✔ 1% - 1% (0.03ms - 0.05ms)
    preact-local vs preact-main
  • many_updates: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • text_update: unsure 🔍 -1% - +5% (-0.01ms - +0.04ms)
    preact-local vs preact-main
  • todo: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-main

Results

02_replace1k
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 80
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main72.60ms - 73.82ms-unsure 🔍
-1% - +1%
-1.08ms - +0.97ms
faster ✔
1% - 3%
0.44ms - 2.03ms
preact-local72.45ms - 74.09msunsure 🔍
-1% - +1%
-0.97ms - +1.08ms
-faster ✔
0% - 3%
0.22ms - 2.14ms
preact-hooks73.94ms - 74.95msslower ❌
1% - 3%
0.44ms - 2.03ms
slower ❌
0% - 3%
0.22ms - 2.14ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main3.40ms - 3.40ms-slower ❌
0% - 1%
0.01ms - 0.02ms
unsure 🔍
-0% - -0%
-0.00ms - -0.00ms
preact-local3.38ms - 3.39msfaster ✔
0% - 1%
0.01ms - 0.02ms
-faster ✔
0% - 1%
0.02ms - 0.02ms
preact-hooks3.41ms - 3.41msunsure 🔍
+0% - +0%
+0.00ms - +0.00ms
slower ❌
0% - 1%
0.02ms - 0.02ms
-

run-warmup-0

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main29.44ms - 30.26ms-unsure 🔍
-1% - +3%
-0.35ms - +0.74ms
unsure 🔍
-4% - +0%
-1.29ms - +0.09ms
preact-local29.30ms - 30.02msunsure 🔍
-2% - +1%
-0.74ms - +0.35ms
-faster ✔
0% - 5%
0.13ms - 1.45ms
preact-hooks29.89ms - 31.00msunsure 🔍
-0% - +4%
-0.09ms - +1.29ms
slower ❌
0% - 5%
0.13ms - 1.45ms
-

run-warmup-1

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main39.93ms - 41.41ms-unsure 🔍
-4% - +1%
-1.52ms - +0.52ms
faster ✔
1% - 5%
0.31ms - 2.12ms
preact-local40.48ms - 41.87msunsure 🔍
-1% - +4%
-0.52ms - +1.52ms
-unsure 🔍
-4% - +0%
-1.58ms - +0.16ms
preact-hooks41.36ms - 42.40msslower ❌
1% - 5%
0.31ms - 2.12ms
unsure 🔍
-0% - +4%
-0.16ms - +1.58ms
-

run-warmup-2

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main26.37ms - 27.00ms-unsure 🔍
-1% - +3%
-0.21ms - +0.73ms
slower ❌
0% - 3%
0.13ms - 0.84ms
preact-local26.08ms - 26.77msunsure 🔍
-3% - +1%
-0.73ms - +0.21ms
-unsure 🔍
-1% - +2%
-0.17ms - +0.61ms
preact-hooks26.03ms - 26.37msfaster ✔
0% - 3%
0.13ms - 0.84ms
unsure 🔍
-2% - +1%
-0.61ms - +0.17ms
-

run-warmup-3

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main24.58ms - 25.72ms-unsure 🔍
-3% - +3%
-0.67ms - +0.85ms
unsure 🔍
-1% - +6%
-0.19ms - +1.45ms
preact-local24.55ms - 25.57msunsure 🔍
-3% - +3%
-0.85ms - +0.67ms
-unsure 🔍
-1% - +5%
-0.24ms - +1.33ms
preact-hooks23.92ms - 25.11msunsure 🔍
-6% - +1%
-1.45ms - +0.19ms
unsure 🔍
-5% - +1%
-1.33ms - +0.24ms
-

run-warmup-4

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main26.73ms - 28.32ms-slower ❌
7% - 15%
1.78ms - 3.62ms
unsure 🔍
-2% - +5%
-0.41ms - +1.34ms
preact-local24.35ms - 25.29msfaster ✔
7% - 13%
1.78ms - 3.62ms
-faster ✔
6% - 10%
1.64ms - 2.83ms
preact-hooks26.69ms - 27.43msunsure 🔍
-5% - +1%
-1.34ms - +0.41ms
slower ❌
6% - 12%
1.64ms - 2.83ms
-

run-final

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main22.66ms - 23.32ms-slower ❌
1% - 5%
0.28ms - 1.18ms
faster ✔
3% - 7%
0.66ms - 1.76ms
preact-local21.95ms - 22.57msfaster ✔
1% - 5%
0.28ms - 1.18ms
-faster ✔
6% - 10%
1.40ms - 2.48ms
preact-hooks23.76ms - 24.64msslower ❌
3% - 8%
0.66ms - 1.76ms
slower ❌
6% - 11%
1.40ms - 2.48ms
-
03_update10th1k_x16
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 60
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main34.59ms - 36.36ms-unsure 🔍
-3% - +4%
-1.21ms - +1.31ms
unsure 🔍
-4% - +3%
-1.49ms - +1.13ms
preact-local34.53ms - 36.32msunsure 🔍
-4% - +3%
-1.31ms - +1.21ms
-unsure 🔍
-4% - +3%
-1.54ms - +1.09ms
preact-hooks34.69ms - 36.62msunsure 🔍
-3% - +4%
-1.13ms - +1.49ms
unsure 🔍
-3% - +4%
-1.09ms - +1.54ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main3.37ms - 3.38ms-slower ❌
0% - 1%
0.01ms - 0.03ms
unsure 🔍
-0% - +0%
-0.01ms - +0.01ms
preact-local3.35ms - 3.36msfaster ✔
0% - 1%
0.01ms - 0.03ms
-faster ✔
0% - 1%
0.01ms - 0.03ms
preact-hooks3.37ms - 3.38msunsure 🔍
-0% - +0%
-0.01ms - +0.01ms
slower ❌
0% - 1%
0.01ms - 0.03ms
-
07_create10k
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 50
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main883.22ms - 888.11ms-unsure 🔍
-1% - +1%
-4.43ms - +5.12ms
unsure 🔍
-1% - +0%
-9.01ms - +2.22ms
preact-local881.22ms - 889.42msunsure 🔍
-1% - +1%
-5.12ms - +4.43ms
-unsure 🔍
-1% - +0%
-10.25ms - +2.76ms
preact-hooks884.01ms - 894.12msunsure 🔍
-0% - +1%
-2.22ms - +9.01ms
unsure 🔍
-0% - +1%
-2.76ms - +10.25ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main26.40ms - 26.40ms-slower ❌
1% - 1%
0.24ms - 0.24ms
slower ❌
1% - 1%
0.22ms - 0.22ms
preact-local26.16ms - 26.17msfaster ✔
1% - 1%
0.24ms - 0.24ms
-unsure 🔍
-0% - -0%
-0.02ms - -0.02ms
preact-hooks26.19ms - 26.19msfaster ✔
1% - 1%
0.22ms - 0.22ms
unsure 🔍
+0% - +0%
+0.02ms - +0.02ms
-
filter_list
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 90
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main16.58ms - 16.78ms-unsure 🔍
-7% - +3%
-1.29ms - +0.51ms
unsure 🔍
-1% - +1%
-0.12ms - +0.16ms
preact-local16.17ms - 17.96msunsure 🔍
-3% - +8%
-0.51ms - +1.29ms
-unsure 🔍
-3% - +8%
-0.49ms - +1.30ms
preact-hooks16.57ms - 16.76msunsure 🔍
-1% - +1%
-0.16ms - +0.12ms
unsure 🔍
-8% - +3%
-1.30ms - +0.49ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main1.42ms - 1.42ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
faster ✔
2% - 2%
0.02ms - 0.03ms
preact-local1.42ms - 1.42msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-faster ✔
2% - 2%
0.02ms - 0.03ms
preact-hooks1.44ms - 1.45msslower ❌
2% - 2%
0.02ms - 0.03ms
slower ❌
2% - 2%
0.02ms - 0.03ms
-
hydrate1k
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 50
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main79.60ms - 82.16ms-unsure 🔍
-1% - +4%
-0.94ms - +2.92ms
unsure 🔍
-1% - +4%
-0.44ms - +3.26ms
preact-local78.44ms - 81.34msunsure 🔍
-4% - +1%
-2.92ms - +0.94ms
-unsure 🔍
-2% - +3%
-1.55ms - +2.39ms
preact-hooks78.14ms - 80.81msunsure 🔍
-4% - +1%
-3.26ms - +0.44ms
unsure 🔍
-3% - +2%
-2.39ms - +1.55ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main6.10ms - 6.10ms-slower ❌
1% - 1%
0.03ms - 0.05ms
unsure 🔍
+0% - +0%
+0.01ms - +0.03ms
preact-local6.05ms - 6.07msfaster ✔
1% - 1%
0.03ms - 0.05ms
-faster ✔
0% - 1%
0.01ms - 0.03ms
preact-hooks6.08ms - 6.09msunsure 🔍
-0% - -0%
-0.03ms - -0.01ms
slower ❌
0% - 1%
0.01ms - 0.03ms
-
many_updates
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 50
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main16.55ms - 16.60ms-unsure 🔍
-3% - +1%
-0.43ms - +0.15ms
unsure 🔍
-0% - +0%
-0.02ms - +0.04ms
preact-local16.43ms - 17.00msunsure 🔍
-1% - +3%
-0.15ms - +0.43ms
-unsure 🔍
-1% - +3%
-0.14ms - +0.44ms
preact-hooks16.55ms - 16.59msunsure 🔍
-0% - +0%
-0.04ms - +0.02ms
unsure 🔍
-3% - +1%
-0.44ms - +0.14ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main4.52ms - 4.52ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
faster ✔
0% - 1%
0.02ms - 0.02ms
preact-local4.52ms - 4.52msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-faster ✔
0% - 1%
0.02ms - 0.02ms
preact-hooks4.54ms - 4.54msslower ❌
0% - 1%
0.02ms - 0.02ms
slower ❌
0% - 1%
0.02ms - 0.02ms
-
text_update
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 60
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main2.42ms - 2.57ms-unsure 🔍
-4% - +5%
-0.10ms - +0.12ms
faster ✔
5% - 16%
0.13ms - 0.45ms
preact-local2.41ms - 2.57msunsure 🔍
-5% - +4%
-0.12ms - +0.10ms
-faster ✔
5% - 16%
0.14ms - 0.46ms
preact-hooks2.65ms - 2.93msslower ❌
5% - 18%
0.13ms - 0.45ms
slower ❌
5% - 19%
0.14ms - 0.46ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main0.80ms - 0.80ms-unsure 🔍
-5% - +1%
-0.04ms - +0.01ms
faster ✔
2% - 3%
0.02ms - 0.03ms
preact-local0.79ms - 0.84msunsure 🔍
-1% - +5%
-0.01ms - +0.04ms
-unsure 🔍
-4% - +2%
-0.04ms - +0.02ms
preact-hooks0.82ms - 0.83msslower ❌
2% - 3%
0.02ms - 0.03ms
unsure 🔍
-2% - +4%
-0.02ms - +0.04ms
-
todo
  • Browser: chrome-headless 122.0.6261.128
  • Sample size: 50
  • Built by: Benchmarks #1360
  • Commit: 1749ffd

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main26.86ms - 27.16ms-unsure 🔍
-1% - +1%
-0.24ms - +0.18ms
faster ✔
3% - 5%
0.70ms - 1.29ms
preact-local26.89ms - 27.18msunsure 🔍
-1% - +1%
-0.18ms - +0.24ms
-faster ✔
2% - 4%
0.67ms - 1.26ms
preact-hooks27.75ms - 28.26msslower ❌
3% - 5%
0.70ms - 1.29ms
slower ❌
2% - 5%
0.67ms - 1.26ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main0.88ms - 0.88ms-unsure 🔍
-0% - -0%
-0.00ms - -0.00ms
faster ✔
3% - 3%
0.03ms - 0.03ms
preact-local0.88ms - 0.88msunsure 🔍
+0% - +0%
+0.00ms - +0.00ms
-faster ✔
3% - 3%
0.03ms - 0.03ms
preact-hooks0.91ms - 0.91msslower ❌
3% - 3%
0.03ms - 0.03ms
slower ❌
3% - 3%
0.03ms - 0.03ms
-

tachometer-reporter-action v2 for Benchmarks

github-actions[bot] avatar Dec 15 '23 01:12 github-actions[bot]

Yes, I tested issue #3927 that was closed by #4126. Works fine.

nbalatsk-oracle avatar Dec 15 '23 22:12 nbalatsk-oracle

Coverage Status

coverage: 99.47% (-0.1%) from 99.601% when pulling 1749ffdd0ce2282f480d4a909a0fe1de60fc4cb0 on nbalatsk-oracle:main into bc7c5515599634a427334eb03236ddf19e13e618 on preactjs:main.

coveralls avatar Dec 29 '23 07:12 coveralls

Hi guys, I've refreshed my branch with the latest code. Let me know if you have any comments.

nbalatsk-oracle avatar Jan 09 '24 17:01 nbalatsk-oracle

@JoviDeCroock I have seen that you have gone for the 32-bit integer solution, as opposed to just counting from Number.MIN_SAFE_INTEGER upwards.

With 32-bit integers, there is a slight chance that it rolls over if many events are fired and if you have a system that runs for a long time (kiosk systems?). If I understand the code correctly, every event attached before MaxInt32 wouldn't be fired after rolling over.

Counting upwards from Number.MIN_SAFE_INTEGER however, you would practically never reach Number.MAX_SAFE_INTEGER. Even with 10,000 events a second, this would take 57,123 years.

sschultze avatar Jan 29 '24 08:01 sschultze

@sschultze this isn't my PR just my comment 😅

JoviDeCroock avatar Jan 29 '24 08:01 JoviDeCroock

@JoviDeCroock Sorry 😅

sschultze avatar Jan 29 '24 08:01 sschultze

@nbalatsk-oracle @JoviDeCroock What about using BigInt for the counter if the browser supports it? BigInts have an arbitrary size and will never overflow, and also no strange things happen if they get very large, giving some peace of mind.

The performance cost should be negligible. On my computer, 10 million increments of a BigInt take 151ms.

Initialization for the counter could go like this:

let counter = window.BigInt ? BigInt(0) : 0;

The ++ operand and the comparison would work fine on both number and bigint, so no need for another case distinction.

sschultze avatar Jan 29 '24 10:01 sschultze

@ritschwumm @JoviDeCroock do we want to use BigInt for the counter as suggested by @sschultze? Do you any concerns for performance?

nbalatsk-oracle avatar Jan 29 '24 20:01 nbalatsk-oracle

@nbalatsk-oracle can't the rollover be made negligible by just comparing for equality with the previous value? then the only problem left is when 2^32 events happen "at the same instant"...

ritschwumm avatar Jan 30 '24 14:01 ritschwumm

Probably another issue, but isn't it problematic that, even in the original code, the _attached property is added to the event handler function? The same event handler might be added to multiple nodes, potentially leading to internal mess-up. Even I re-use event handlers in my code (e.g. for list items differentiated by a data-key attribute), and my UI is not that special.

I also noticed that in the minified version, _attached is shortened to u. Couldn't it happen that there's a conflict between the minified name and the "official" properties of the function?

sschultze avatar Jan 30 '24 15:01 sschultze

@nbalatsk-oracle can't the rollover be made negligible by just comparing for equality with the previous value? then the only problem left is when 2^32 events happen "at the same instant"...

@ritschwumm I don't think that's how the current proposed code changes are working. The idea is that the counter is incremented when an event listener is newly attached for the first time during a render cycle. All event listeners that are newly attached during that render cycle will share the same counter value; all event listeners attached during previous renders will have lower counter values, all event listeners attached in future renders will have higher counter values. As a result, event listeners attached during the 0th render cycle appear indistinguishable from event listeners attached during the 2^32nd render cycle, hence the "rollover" issue.

jramanat-oracle avatar Jan 30 '24 15:01 jramanat-oracle

Probably another issue, but isn't it problematic that, even in the original code, the _attached property is added to the event handler function? The same event handler might be added to multiple nodes, potentially leading to internal mess-up. Even I re-use event handlers in my code (e.g. for list items differentiated by a data-key attribute), and my UI is not that special.

@sschultze Is it really a problem? It seems that it does not really matter that the handler is shared as long as the _attached/_dispatched order is correct. Even if _attached is updated by some DOM mutation (new elements are added that share the same handler), the event will not propagate to those updated elements. What is the use-case where we want it?  And if you trigger an event on one of those older elements the event should work because the order of the _attached/_dispatched pair is still correct. Right?

nbalatsk-oracle avatar Jan 30 '24 22:01 nbalatsk-oracle

@sschultze Is it really a problem? It seems that it does not really matter that the handler is shared as long as the _attached/_dispatched order is correct. Even if _attached is updated by some DOM mutation (new elements are added that share the same handler), the event will not propagate to those updated elements. What is the use-case where we want it?  And if you trigger an event on one of those older elements the event should work because the order of the _attached/_dispatched pair is still correct. Right?

@nbalatsk-oracle You are right. Even though adding the same event handler in multiple places was probably not thought of when writing the original _attached/_dispatched workaround (or perhaps it was thought of, i don't know), in practice this shouldn't be a problem as the order will still be correct.

I mean, I can't say for sure - I'm not deep enough into the internal workings of Preact to guarantee that there isn't some weird edge case where still would still create a problem.

I did however write the following test code which re-uses the same event handler handleButtonClick and aggressively creates new DOM nodes, just for a quick validation, and it works fine. No click event is ignored.

import { JSX, useCallback, useState } from 'preact/compat';

interface SectionProps {
    readonly onButtonClick: JSX.MouseEventHandler<HTMLButtonElement>;
}

function Section(props: SectionProps) {
    return (
        <div>
            <button onClick={props.onButtonClick}>Add Section</button>
        </div>
    );
}

let domNodeCreationCounter = 0;

export function PreactTest(props: {}) {
    const [count, setCount] = useState(1);

    const handleButtonClick = useCallback(() => {
        setCount(oldCount => oldCount + 1);
    }, []);

    // console.log((handleButtonClick as any).u); - shows ._attached in the minified version that I use

    return (
        <div key={domNodeCreationCounter++}> {/* Should create new DOM nodes every time */}
            {Array(count).fill(0).map((_, index) => (
                <Section key={index} onButtonClick={handleButtonClick} />
            ))}
        </div>
    );
}

Perhaps it would make sense to add a "warning comment" for anyone who updates the code later? Saying that the property is added to the function itself, even though it might be added to multiple nodes, but as you say this still doesn't create a problem as the _attached/_dispatched order is still okay?

sschultze avatar Jan 31 '24 07:01 sschultze

@nbalatsk-oracle A thought experiment: If it would indeed be 100% safe to share event handlers between nodes, and still always get the correct behavior here, then it would - as a consequence - also be safe to share the same one event handler for everything in the application. Meaning there's really only one event handler function for everything in the application in this theoretical scenario.

In this scenario, the _attached property would always be set in the same function object.

If this would still lead to the correct behavior, than _attached could be a (module-)global variable, and not be attached to the event handler functions in the first place.

What I want to say by this is:

  • either event handlers can really be shared between nodes and still get 100% correct behavior, in which case _attached could also be made a (module-)global variable
  • or neither the original nor the corrected workaround provide a 100% solution.

In any case, especially if we get the overflow problem away (e.g. with the bigint proposal), the new code definitely provides better results that the old code relying on Date. (The Date-based workaround not only makes problems in the test scenario, but also if the users changes their system date/time while the app is running.)

sschultze avatar Jan 31 '24 09:01 sschultze

Updated the code to use BigInt for the counters to avoid overflow and added a few comments to _attached/_detached usage.

nbalatsk-oracle avatar Feb 25 '24 21:02 nbalatsk-oracle

@JoviDeCroock @developit @andrewiggins @marvinhagemeister Just curious if you might be able to provide any indication on the likelihood of moving forward with the approach in this PR or if there are other approaches to this problem that you might like to see investigated? Our product is currently blocked from moving forward from preact 10.17.1 due to https://github.com/preactjs/preact/issues/4161 so we're very interested in finding some acceptable resolution. Happy to explore other options if there's a preference, thanks!

jramanat-oracle avatar Mar 04 '24 15:03 jramanat-oracle