pull/10582/head
Rich Harris 2 years ago
parent c7895db461
commit 34dbee71fc

@ -1,6 +1,6 @@
import { createClassComponent } from '../../legacy/legacy-client.js'; import { createClassComponent } from '../../legacy/legacy-client.js';
import { destroy_signal } from './runtime.js'; import { destroy_signal } from './runtime.js';
import { render_effect } from './reactivity/effects.js'; import { render_effect } from './reactivity/computations.js';
import { open, close } from './render.js'; import { open, close } from './render.js';
import { define_property } from './utils.js'; import { define_property } from './utils.js';

@ -10,7 +10,7 @@ import {
flushSync, flushSync,
push_destroy_fn push_destroy_fn
} from '../../runtime.js'; } from '../../runtime.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/computations.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../../transitions.js';
/** @returns {import('../../types.js').AwaitBlock} */ /** @returns {import('../../types.js').AwaitBlock} */

@ -24,7 +24,7 @@ import {
push_destroy_fn, push_destroy_fn,
set_signal_value set_signal_value
} from '../../runtime.js'; } from '../../runtime.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/computations.js';
import { source, mutable_source } from '../../reactivity/sources.js'; import { source, mutable_source } from '../../reactivity/sources.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../../transitions.js';
import { is_array } from '../../utils.js'; import { is_array } from '../../utils.js';

@ -7,7 +7,7 @@ import {
} from '../../hydration.js'; } from '../../hydration.js';
import { remove } from '../../reconciler.js'; import { remove } from '../../reconciler.js';
import { current_block, destroy_signal, execute_effect, push_destroy_fn } from '../../runtime.js'; import { current_block, destroy_signal, execute_effect, push_destroy_fn } from '../../runtime.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/computations.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../../transitions.js';
/** @returns {import('../../types.js').IfBlock} */ /** @returns {import('../../types.js').IfBlock} */

@ -8,7 +8,7 @@ import {
execute_effect, execute_effect,
push_destroy_fn push_destroy_fn
} from '../../runtime.js'; } from '../../runtime.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/computations.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../../transitions.js';
import { safe_not_equal } from '../../reactivity/equality.js'; import { safe_not_equal } from '../../reactivity/equality.js';

@ -8,7 +8,7 @@ import {
batch_inspect, batch_inspect,
current_component_context current_component_context
} from './runtime.js'; } from './runtime.js';
import { effect_active } from './reactivity/effects.js'; import { effect_active } from './reactivity/computations.js';
import { import {
array_prototype, array_prototype,
define_property, define_property,

@ -1,19 +1,25 @@
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { import {
CLEAN,
DERIVED,
DIRTY, DIRTY,
EFFECT, EFFECT,
MANAGED, MANAGED,
PRE_EFFECT, PRE_EFFECT,
RENDER_EFFECT, RENDER_EFFECT,
UNINITIALIZED,
UNOWNED,
create_computation_signal, create_computation_signal,
current_block, current_block,
current_component_context, current_component_context,
current_consumer,
current_effect, current_effect,
destroy_signal, destroy_signal,
flush_local_render_effects, flush_local_render_effects,
push_reference, push_reference,
schedule_effect schedule_effect
} from '../runtime.js'; } from '../runtime.js';
import { default_equals, safe_equal } from './equality.js';
/** /**
* @param {import('../types.js').EffectType} type * @param {import('../types.js').EffectType} type
@ -178,3 +184,35 @@ export function managed_render_effect(init, block = current_block, sync = true)
const flags = RENDER_EFFECT | MANAGED; const flags = RENDER_EFFECT | MANAGED;
return internal_create_effect(flags, /** @type {any} */ (init), sync, block, true); return internal_create_effect(flags, /** @type {any} */ (init), sync, block, true);
} }
/**
* @template V
* @param {() => V} init
* @returns {import('../types.js').ComputationSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function derived(init) {
const is_unowned = current_effect === null;
const flags = is_unowned ? DERIVED | UNOWNED : DERIVED;
const signal = /** @type {import('../types.js').ComputationSignal<V>} */ (
create_computation_signal(flags | CLEAN, UNINITIALIZED, current_block)
);
signal.i = init;
signal.e = default_equals;
if (current_consumer !== null) {
push_reference(current_consumer, signal);
}
return signal;
}
/**
* @template V
* @param {() => V} init
* @returns {import('../types.js').ComputationSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function derived_safe_equal(init) {
const signal = derived(init);
signal.e = safe_equal;
return signal;
}

@ -43,7 +43,7 @@ import {
pop, pop,
deep_read deep_read
} from './runtime.js'; } from './runtime.js';
import { render_effect, effect, managed_effect } from './reactivity/effects.js'; import { render_effect, effect, managed_effect } from './reactivity/computations.js';
import { import {
current_hydration_fragment, current_hydration_fragment,
get_hydration_fragment, get_hydration_fragment,

@ -19,9 +19,9 @@ import {
} from '../../constants.js'; } from '../../constants.js';
import { STATE_SYMBOL, unstate } from './proxy.js'; import { STATE_SYMBOL, unstate } from './proxy.js';
import { EACH_BLOCK, IF_BLOCK } from './block.js'; import { EACH_BLOCK, IF_BLOCK } from './block.js';
import { pre_effect, user_effect } from './reactivity/effects.js'; import { derived, pre_effect, user_effect } from './reactivity/computations.js';
import { mutable_source, source } from './reactivity/sources.js'; import { mutable_source, source } from './reactivity/sources.js';
import { default_equals, safe_equal, safe_not_equal } from './reactivity/equality.js'; import { safe_equal, safe_not_equal } from './reactivity/equality.js';
export const SOURCE = 1; export const SOURCE = 1;
export const DERIVED = 1 << 1; export const DERIVED = 1 << 1;
@ -29,7 +29,7 @@ export const EFFECT = 1 << 2;
export const PRE_EFFECT = 1 << 3; export const PRE_EFFECT = 1 << 3;
export const RENDER_EFFECT = 1 << 4; export const RENDER_EFFECT = 1 << 4;
export const MANAGED = 1 << 6; export const MANAGED = 1 << 6;
const UNOWNED = 1 << 7; export const UNOWNED = 1 << 7;
export const CLEAN = 1 << 8; export const CLEAN = 1 << 8;
export const DIRTY = 1 << 9; export const DIRTY = 1 << 9;
export const MAYBE_DIRTY = 1 << 10; export const MAYBE_DIRTY = 1 << 10;
@ -69,7 +69,7 @@ let flush_count = 0;
// Handle signal reactivity tree dependencies and consumer // Handle signal reactivity tree dependencies and consumer
/** @type {null | import('./types.js').ComputationSignal} */ /** @type {null | import('./types.js').ComputationSignal} */
let current_consumer = null; export let current_consumer = null;
/** @type {null | import('./types.js').EffectSignal} */ /** @type {null | import('./types.js').EffectSignal} */
export let current_effect = null; export let current_effect = null;
@ -1252,38 +1252,6 @@ export function destroy_signal(signal) {
} }
} }
/**
* @template V
* @param {() => V} init
* @returns {import('./types.js').ComputationSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function derived(init) {
const is_unowned = current_effect === null;
const flags = is_unowned ? DERIVED | UNOWNED : DERIVED;
const signal = /** @type {import('./types.js').ComputationSignal<V>} */ (
create_computation_signal(flags | CLEAN, UNINITIALIZED, current_block)
);
signal.i = init;
signal.e = default_equals;
if (current_consumer !== null) {
push_reference(current_consumer, signal);
}
return signal;
}
/**
* @template V
* @param {() => V} init
* @returns {import('./types.js').ComputationSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function derived_safe_equal(init) {
const signal = derived(init);
signal.e = safe_equal;
return signal;
}
/** /**
* Use `untrack` to prevent something from being treated as an `$effect`/`$derived` dependency. * Use `untrack` to prevent something from being treated as an `$effect`/`$derived` dependency.
* *

@ -11,7 +11,7 @@ import {
} from './block.js'; } from './block.js';
import { destroy_each_item_block, get_first_element } from './dom/blocks/each.js'; import { destroy_each_item_block, get_first_element } from './dom/blocks/each.js';
import { append_child, empty } from './operations.js'; import { append_child, empty } from './operations.js';
import { effect, managed_effect, managed_pre_effect } from './reactivity/effects.js'; import { effect, managed_effect, managed_pre_effect } from './reactivity/computations.js';
import { import {
current_block, current_block,
current_effect, current_effect,

@ -4,8 +4,6 @@ export {
set, set,
set_sync, set_sync,
invalidate_inner_signals, invalidate_inner_signals,
derived,
derived_safe_equal,
prop, prop,
flushSync, flushSync,
bubble_event, bubble_event,
@ -37,7 +35,7 @@ export { await_block as await } from './client/dom/blocks/await.js';
export { if_block as if } from './client/dom/blocks/if.js'; export { if_block as if } from './client/dom/blocks/if.js';
export { key_block as key } from './client/dom/blocks/key.js'; export { key_block as key } from './client/dom/blocks/key.js';
export * from './client/dom/blocks/each.js'; export * from './client/dom/blocks/each.js';
export * from './client/reactivity/effects.js'; export * from './client/reactivity/computations.js';
export * from './client/reactivity/sources.js'; export * from './client/reactivity/sources.js';
export * from './client/reactivity/equality.js'; export * from './client/reactivity/equality.js';
export * from './client/render.js'; export * from './client/render.js';

@ -1,6 +1,11 @@
import { describe, assert, it } from 'vitest'; import { describe, assert, it } from 'vitest';
import * as $ from '../../src/internal/client/runtime'; import * as $ from '../../src/internal/client/runtime';
import { effect, render_effect, user_effect } from '../../src/internal/client/reactivity/effects'; import {
derived,
effect,
render_effect,
user_effect
} from '../../src/internal/client/reactivity/computations';
import { source } from '../../src/internal/client/reactivity/sources'; import { source } from '../../src/internal/client/reactivity/sources';
import type { ComputationSignal } from '../../src/internal/client/types'; import type { ComputationSignal } from '../../src/internal/client/types';
@ -39,7 +44,7 @@ describe('signals', () => {
const log: string[] = []; const log: string[] = [];
let count = source(0); let count = source(0);
let double = $.derived(() => $.get(count) * 2); let double = derived(() => $.get(count) * 2);
effect(() => { effect(() => {
log.push(`${$.get(count)}:${$.get(double)}`); log.push(`${$.get(count)}:${$.get(double)}`);
}); });
@ -56,7 +61,7 @@ describe('signals', () => {
const log: string[] = []; const log: string[] = [];
let count = source(0); let count = source(0);
let double = $.derived(() => $.get(count) * 2); let double = derived(() => $.get(count) * 2);
effect(() => { effect(() => {
log.push(`A:${$.get(count)}:${$.get(double)}`); log.push(`A:${$.get(count)}:${$.get(double)}`);
@ -77,7 +82,7 @@ describe('signals', () => {
const log: string[] = []; const log: string[] = [];
let count = source(0); let count = source(0);
let double = $.derived(() => $.get(count) * 2); let double = derived(() => $.get(count) * 2);
effect(() => { effect(() => {
log.push(`A:${$.get(double)}`); log.push(`A:${$.get(double)}`);
@ -98,7 +103,7 @@ describe('signals', () => {
const log: number[] = []; const log: number[] = [];
let count = source(0); let count = source(0);
let double = $.derived(() => $.get(count) * 2); let double = derived(() => $.get(count) * 2);
effect(() => { effect(() => {
log.push($.get(double)); log.push($.get(double));
@ -116,8 +121,8 @@ describe('signals', () => {
const log: number[] = []; const log: number[] = [];
let count = source(0); let count = source(0);
let double = $.derived(() => $.get(count) * 2); let double = derived(() => $.get(count) * 2);
let quadruple = $.derived(() => $.get(double) * 2); let quadruple = derived(() => $.get(double) * 2);
effect(() => { effect(() => {
log.push($.get(quadruple)); log.push($.get(quadruple));
@ -140,11 +145,11 @@ describe('signals', () => {
const A = source(0); const A = source(0);
const B = source(0); const B = source(0);
const C = $.derived(() => ($.get(A) % 2) + ($.get(B) % 2)); const C = derived(() => ($.get(A) % 2) + ($.get(B) % 2));
const D = $.derived(() => numbers.map((i) => i + ($.get(A) % 2) - ($.get(B) % 2))); const D = derived(() => numbers.map((i) => i + ($.get(A) % 2) - ($.get(B) % 2)));
const E = $.derived(() => hard($.get(C) + $.get(A) + $.get(D)[0]!, 'E')); const E = derived(() => hard($.get(C) + $.get(A) + $.get(D)[0]!, 'E'));
const F = $.derived(() => hard($.get(D)[0]! && $.get(B), 'F')); const F = derived(() => hard($.get(D)[0]! && $.get(B), 'F'));
const G = $.derived(() => $.get(C) + ($.get(C) || $.get(E) % 2) + $.get(D)[0]! + $.get(F)); const G = derived(() => $.get(C) + ($.get(C) || $.get(E) % 2) + $.get(D)[0]! + $.get(F));
effect(() => { effect(() => {
res.push(hard($.get(G), 'H')); res.push(hard($.get(G), 'H'));
}); });
@ -180,10 +185,10 @@ describe('signals', () => {
let count = source(0); let count = source(0);
const read = () => { const read = () => {
const x = $.derived(() => ({ count: $.get(count) })); const x = derived(() => ({ count: $.get(count) }));
return $.get(x); return $.get(x);
}; };
const derivedCount = $.derived(() => read().count); const derivedCount = derived(() => read().count);
user_effect(() => { user_effect(() => {
log.push($.get(derivedCount)); log.push($.get(derivedCount));
}); });
@ -208,9 +213,9 @@ describe('signals', () => {
const a = source(0); const a = source(0);
const b = source(0); const b = source(0);
const c = $.derived(() => { const c = derived(() => {
const a_2 = $.derived(() => $.get(a) + '!'); const a_2 = derived(() => $.get(a) + '!');
const b_2 = $.derived(() => $.get(b) + '?'); const b_2 = derived(() => $.get(b) + '?');
nested.push(a_2, b_2); nested.push(a_2, b_2);
return { a: $.get(a_2), b: $.get(b_2) }; return { a: $.get(a_2), b: $.get(b_2) };
@ -236,7 +241,7 @@ describe('signals', () => {
// outside of test function so that they are unowned signals // outside of test function so that they are unowned signals
let count = source(0); let count = source(0);
let calc = $.derived(() => { let calc = derived(() => {
if ($.get(count) >= 2) { if ($.get(count) >= 2) {
return 'limit'; return 'limit';
} }
@ -265,7 +270,7 @@ describe('signals', () => {
}; };
}); });
let no_deps = $.derived(() => { let no_deps = derived(() => {
return []; return [];
}); });
@ -287,7 +292,7 @@ describe('signals', () => {
}); });
let some_state = source({}); let some_state = source({});
let some_deps = $.derived(() => { let some_deps = derived(() => {
return [$.get(some_state)]; return [$.get(some_state)];
}); });

Loading…
Cancel
Save