use update_version instead of WeakRef in SvelteSet/SvelteMap (#16324)

pull/16239/head
Rich Harris 2 months ago committed by GitHub
parent e3072c9906
commit 3ab41d6d07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -132,6 +132,8 @@ let write_version = 1;
/** @type {number} Used to version each read of a source of derived to avoid duplicating depedencies inside a reaction */
let read_version = 0;
export let update_version = read_version;
// If we are working with a get() chain that has no active container,
// to prevent memory leaks, we skip adding the reaction.
export let skip_reaction = false;
@ -265,6 +267,7 @@ export function update_reaction(reaction) {
var previous_reaction_sources = source_ownership;
var previous_component_context = component_context;
var previous_untracking = untracking;
var previous_update_version = update_version;
var flags = reaction.f;
@ -278,7 +281,7 @@ export function update_reaction(reaction) {
source_ownership = null;
set_component_context(reaction.ctx);
untracking = false;
read_version++;
update_version = ++read_version;
reaction.f |= EFFECT_IS_UPDATING;
@ -366,6 +369,7 @@ export function update_reaction(reaction) {
source_ownership = previous_reaction_sources;
set_component_context(previous_component_context);
untracking = previous_untracking;
update_version = previous_update_version;
reaction.f ^= EFFECT_IS_UPDATING;
}

@ -2,7 +2,7 @@
import { DEV } from 'esm-env';
import { set, source, state } from '../internal/client/reactivity/sources.js';
import { label, tag } from '../internal/client/dev/tracing.js';
import { active_reaction, get } from '../internal/client/runtime.js';
import { active_reaction, get, update_version } from '../internal/client/runtime.js';
import { increment } from './utils.js';
import { teardown } from '../internal/client/reactivity/effects.js';
@ -57,8 +57,7 @@ export class SvelteMap extends Map {
#sources = new Map();
#version = state(0);
#size = state(0);
/**@type {WeakRef<Reaction> | null} */
#initial_reaction = null;
#update_version = -1;
/**
* @param {Iterable<readonly [K, V]> | null | undefined} [value]
@ -67,10 +66,7 @@ export class SvelteMap extends Map {
super();
if (active_reaction !== null) {
// we use a WeakRef (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef)
// so that if this Map is somehow stored outside of the active reaction,
// it will not prevent the reaction from being garbage collected.
this.#initial_reaction = new WeakRef(active_reaction);
this.#update_version = update_version;
}
if (DEV) {
@ -99,9 +95,10 @@ export class SvelteMap extends Map {
* @returns {Source<T>}
*/
#source(value) {
if (this.#initial_reaction !== null && this.#initial_reaction.deref() === active_reaction) {
if (update_version === this.#update_version) {
return state(value);
}
return source(value);
}

@ -2,7 +2,7 @@
import { DEV } from 'esm-env';
import { source, set, state } from '../internal/client/reactivity/sources.js';
import { label, tag } from '../internal/client/dev/tracing.js';
import { active_reaction, get } from '../internal/client/runtime.js';
import { active_reaction, get, update_version } from '../internal/client/runtime.js';
import { increment } from './utils.js';
import { teardown } from '../internal/client/reactivity/effects.js';
@ -51,9 +51,7 @@ export class SvelteSet extends Set {
#sources = new Map();
#version = state(0);
#size = state(0);
/**@type {WeakRef<Reaction> | null}*/
#initial_reaction = null;
#update_version = -1;
/**
* @param {Iterable<T> | null | undefined} [value]
@ -62,10 +60,7 @@ export class SvelteSet extends Set {
super();
if (active_reaction !== null) {
// we use a WeakRef (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef)
// so that if this Map is somehow stored outside of the active reaction,
// it will not prevent the reaction from being garbage collected.
this.#initial_reaction = new WeakRef(active_reaction);
this.#update_version = update_version;
}
if (DEV) {
@ -96,7 +91,7 @@ export class SvelteSet extends Set {
* @returns {Source<T>}
*/
#source(value) {
if (this.#initial_reaction !== null && this.#initial_reaction.deref() === active_reaction) {
if (this.#update_version === update_version) {
return state(value);
}
return source(value);

Loading…
Cancel
Save