rename stuff

proxied-state-each-blocks
Rich Harris 10 months ago committed by Dominic Gannaway
parent fcfce74dd3
commit fb6043e03f

@ -1,17 +1,17 @@
import { effect_active, get, set, increment, source } from './runtime.js'; import { effect_active, get, set, increment, source } from './runtime.js';
/** @typedef {{ p: MagicObject | null; s: Map<string | symbol, import('./types').SourceSignal<any>>; v: import('./types').SourceSignal<number>; a: boolean }} Magic */ /** @typedef {{ p: StateObject | null; s: Map<string | symbol, import('./types').SourceSignal<any>>; v: import('./types').SourceSignal<number>; a: boolean }} Metadata */
/** @typedef {Record<string | symbol, any> & { [MAGIC_SYMBOL]: Magic }} MagicObject */ /** @typedef {Record<string | symbol, any> & { [STATE_SYMBOL]: Metadata }} StateObject */
export const MAGIC_SYMBOL = Symbol(); export const STATE_SYMBOL = Symbol();
export const MAGIC_EACH_SYMBOL = Symbol(); export const STATE_EACH_SYMBOL = Symbol();
const object_prototype = Object.prototype; const object_prototype = Object.prototype;
const array_prototype = Array.prototype; const array_prototype = Array.prototype;
const get_prototype_of = Object.getPrototypeOf; const get_prototype_of = Object.getPrototypeOf;
/** /**
* @template {MagicObject} T * @template {StateObject} T
* @param {T} value * @param {T} value
* @returns {T} * @returns {T}
*/ */
@ -20,33 +20,51 @@ export function magic(value) {
} }
/** /**
* @template {MagicObject} T * @template {StateObject} T
* @template {MagicObject} P * @template {StateObject} P
* @param {T} value * @param {T} value
* @param {P | null} parent * @param {P | null} parent
* @returns {T} * @returns {T}
*/ */
function wrap(value, parent) { function wrap(value, parent) {
if (value && typeof value === 'object') { if (value && typeof value === 'object' && !(STATE_SYMBOL in value)) {
const prototype = get_prototype_of(value); const prototype = get_prototype_of(value);
// TODO handle Map and Set as well // TODO handle Map and Set as well
if (prototype === object_prototype || prototype === array_prototype) { if (prototype === object_prototype || prototype === array_prototype) {
return proxy(value, parent); // @ts-expect-error
value[STATE_SYMBOL] = init(value, parent);
// @ts-expect-error not sure how to fix this
return new Proxy(value, handler);
} }
} }
return value; return value;
} }
/** @type {ProxyHandler<MagicObject>} */ /**
* @param {StateObject} value
* @param {StateObject | null} parent
* @returns {Metadata}
*/
function init(value, parent) {
return {
p: parent,
s: new Map(),
v: source(0),
a: Array.isArray(value)
};
}
/** @type {ProxyHandler<StateObject>} */
const handler = { const handler = {
get(target, prop, receiver) { get(target, prop, receiver) {
if (prop === MAGIC_EACH_SYMBOL) { if (prop === STATE_EACH_SYMBOL) {
return parent; return parent;
} }
const metadata = target[MAGIC_SYMBOL]; const metadata = target[STATE_SYMBOL];
let s = metadata.s.get(prop); let s = metadata.s.get(prop);
// if we're reading a property in a reactive context, create a source, // if we're reading a property in a reactive context, create a source,
@ -59,7 +77,7 @@ const handler = {
return s !== undefined ? get(s) : target[prop]; return s !== undefined ? get(s) : target[prop];
}, },
set(target, prop, value) { set(target, prop, value) {
const metadata = target[MAGIC_SYMBOL]; const metadata = target[STATE_SYMBOL];
const s = metadata.s.get(prop); const s = metadata.s.get(prop);
if (s !== undefined) set(s, wrap(value, target)); if (s !== undefined) set(s, wrap(value, target));
@ -78,7 +96,7 @@ const handler = {
return true; return true;
}, },
deleteProperty(target, prop) { deleteProperty(target, prop) {
const metadata = target[MAGIC_SYMBOL]; const metadata = target[STATE_SYMBOL];
const s = metadata.s.get(prop); const s = metadata.s.get(prop);
if (s !== undefined) set(s, undefined); if (s !== undefined) set(s, undefined);
@ -88,48 +106,17 @@ const handler = {
return delete target[prop]; return delete target[prop];
}, },
has(target, prop) { has(target, prop) {
if (prop === MAGIC_SYMBOL) return true; if (prop === STATE_SYMBOL) return true;
const metadata = target[MAGIC_SYMBOL]; const metadata = target[STATE_SYMBOL];
get(metadata.v); get(metadata.v);
return Reflect.has(target, prop); return Reflect.has(target, prop);
}, },
ownKeys(target) { ownKeys(target) {
const metadata = target[MAGIC_SYMBOL]; const metadata = target[STATE_SYMBOL];
get(metadata.v); get(metadata.v);
return Reflect.ownKeys(target); return Reflect.ownKeys(target);
} }
}; };
/**
* @template {MagicObject} T
* @template {MagicObject} P
* @param {T} value
* @param {P | null} parent
* @returns {T}
*/
function proxy(value, parent) {
if (MAGIC_SYMBOL in value) return value;
// @ts-expect-error
value[MAGIC_SYMBOL] = init(value, parent);
// @ts-expect-error not sure how to fix this
return new Proxy(value, handler);
}
/**
* @param {MagicObject} value
* @param {MagicObject | null} parent
* @returns {Magic}
*/
function init(value, parent) {
return {
p: parent,
s: new Map(),
v: source(0),
a: Array.isArray(value)
};
}

@ -13,7 +13,7 @@ import {
EACH_IS_PROXIED, EACH_IS_PROXIED,
EACH_ITEM_REACTIVE EACH_ITEM_REACTIVE
} from '../../constants.js'; } from '../../constants.js';
import { MAGIC_SYMBOL } from './magic.js'; import { STATE_SYMBOL } from './magic.js';
const NEW_BLOCK = -1; const NEW_BLOCK = -1;
const MOVED_BLOCK = 99999999; const MOVED_BLOCK = 99999999;
@ -183,7 +183,7 @@ export function reconcile_indexed_array(
flags, flags,
apply_transitions apply_transitions
) { ) {
var is_proxied_array = MAGIC_SYMBOL in array; var is_proxied_array = STATE_SYMBOL in array;
var a_blocks = each_block.v; var a_blocks = each_block.v;
var active_transitions = each_block.s; var active_transitions = each_block.s;
@ -289,7 +289,7 @@ export function reconcile_tracked_array(
) { ) {
var a_blocks = each_block.v; var a_blocks = each_block.v;
const is_computed_key = keys !== null; const is_computed_key = keys !== null;
var is_proxied_array = MAGIC_SYMBOL in array; var is_proxied_array = STATE_SYMBOL in array;
var active_transitions = each_block.s; var active_transitions = each_block.s;
if (is_proxied_array) { if (is_proxied_array) {

Loading…
Cancel
Save