snapshot maps

better-snapshot
Rich Harris 8 months ago
parent 05987bc714
commit ee702d153f

@ -16,3 +16,4 @@ export const EFFECT_RAN = 1 << 13;
export const EFFECT_TRANSPARENT = 1 << 14;
export const STATE_SYMBOL = Symbol('$state');
export const STATE_SNAPSHOT_SYMBOL = Symbol('$state.snapshot');

@ -1,4 +1,4 @@
import { STATE_SYMBOL } from '../constants.js';
import { STATE_SNAPSHOT_SYMBOL, STATE_SYMBOL } from '../constants.js';
import { array_prototype, get_prototype_of, is_array, object_prototype } from '../utils.js';
/**
@ -13,17 +13,22 @@ export function snapshot(value, deep = false, values = new Map()) {
return value;
}
var unwrapped = /** @type {T} */ (values.get(value));
if (unwrapped !== undefined) {
return unwrapped;
}
if (STATE_SNAPSHOT_SYMBOL in value) {
// @ts-expect-error
return value[STATE_SNAPSHOT_SYMBOL](deep);
}
var proto = get_prototype_of(value);
if (
(proto === object_prototype || proto === array_prototype) &&
(deep || STATE_SYMBOL in value)
) {
var unwrapped = /** @type {T} */ (values.get(value));
if (unwrapped !== undefined) {
return unwrapped;
}
if (is_array(value)) {
var length = value.length;
var array = Array(length);

@ -15,7 +15,8 @@ import {
BRANCH_EFFECT,
STATE_SYMBOL,
BLOCK_EFFECT,
ROOT_EFFECT
ROOT_EFFECT,
STATE_SNAPSHOT_SYMBOL
} from './constants.js';
import { flush_tasks } from './dom/task.js';
import { add_owner } from './dev/ownership.js';
@ -1137,6 +1138,12 @@ export function deep_read(value, visited = new Set()) {
!visited.has(value)
) {
visited.add(value);
if (STATE_SNAPSHOT_SYMBOL in value) {
value[STATE_SNAPSHOT_SYMBOL](true);
return;
}
for (let key in value) {
try {
deep_read(value[key], visited);
@ -1144,6 +1151,7 @@ export function deep_read(value, visited = new Set()) {
// continue
}
}
const proto = get_prototype_of(value);
if (
proto !== Object.prototype &&

@ -3,6 +3,8 @@ import { source, set } from '../internal/client/reactivity/sources.js';
import { get } from '../internal/client/runtime.js';
import { UNINITIALIZED } from '../constants.js';
import { map } from './utils.js';
import { STATE_SNAPSHOT_SYMBOL } from '../internal/client/constants.js';
import { snapshot } from '../internal/client/reactivity/snapshot.js';
/**
* @template K
@ -155,4 +157,15 @@ export class ReactiveMap extends Map {
get size() {
return get(this.#size);
}
/** @param {boolean} deep */
[STATE_SNAPSHOT_SYMBOL](deep) {
return new Map(
map(
this.#sources.entries(),
([key, source]) => /** @type {[K, V]} */ ([key, snapshot(get(source), deep)]),
'Map Iterator'
)
);
}
}

Loading…
Cancel
Save