Skip to content

Instantly share code, notes, and snippets.

@cray0000
Last active September 20, 2024 23:48
Show Gist options
  • Save cray0000/abecb1ca71fd28a1d8efff2be9e0f6c5 to your computer and use it in GitHub Desktop.
Save cray0000/abecb1ca71fd28a1d8efff2be9e0f6c5 to your computer and use it in GitHub Desktop.
FinalizationRegistry mock using WeakRef. For React Native 0.75 New Architecture

Usage

import FinalizationRegistry from './MockFinalizationRegistry.js'

License

MIT

export const REGISTRY_SWEEP_INTERVAL = 10000
// This is a mock implementation of FinalizationRegistry which uses WeakRef to
// track the target objects. It's used in environments where FinalizationRegistry
// is not available but WeakRef is (e.g. React Native >=0.75 on New Architecture).
export class WeakRefBasedFinalizationRegistry {
counter = 0
registrations = new Map()
sweepTimeout
constructor (finalize) {
this.finalize = finalize
}
register (target, value, token) {
this.registrations.set(this.counter, {
targetRef: new WeakRef(target),
tokenRef: token != null ? new WeakRef(token) : undefined,
value
})
this.counter++
this.scheduleSweep()
}
unregister (token) {
if (token == null) return
this.registrations.forEach((registration, key) => {
if (registration.tokenRef?.deref() === token) {
this.registrations.delete(key)
}
})
}
// Bound so it can be used directly as setTimeout callback.
sweep = () => {
clearTimeout(this.sweepTimeout)
this.sweepTimeout = undefined
this.registrations.forEach((registration, key) => {
if (registration.targetRef.deref() !== undefined) return
const value = registration.value
this.registrations.delete(key)
this.finalize(value)
})
if (this.registrations.size > 0) this.scheduleSweep()
}
scheduleSweep () {
if (this.sweepTimeout) return
this.sweepTimeout = setTimeout(this.sweep, REGISTRY_SWEEP_INTERVAL)
}
}
let ExportedFinalizationRegistry
if (typeof FinalizationRegistry !== 'undefined') {
ExportedFinalizationRegistry = FinalizationRegistry
} else if (typeof WeakRef !== 'undefined') {
console.warn('FinalizationRegistry is not available in this environment. ' +
'Using a mock implementation: WeakRefBasedFinalizationRegistry')
ExportedFinalizationRegistry = WeakRefBasedFinalizationRegistry
} else {
throw Error('Neither FinalizationRegistry nor WeakRef are available in this environment')
}
export default ExportedFinalizationRegistry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment