move source code

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

@ -21,12 +21,11 @@ import {
current_block,
destroy_signal,
execute_effect,
mutable_source,
push_destroy_fn,
set_signal_value,
source
set_signal_value
} from '../../runtime.js';
import { render_effect } from '../../reactivity/effects.js';
import { source, mutable_source } from '../../reactivity/sources.js';
import { trigger_transitions } from '../../transitions.js';
import { is_array } from '../../utils.js';

@ -6,11 +6,11 @@ import {
current_block,
destroy_signal,
execute_effect,
push_destroy_fn,
safe_not_equal
push_destroy_fn
} from '../../runtime.js';
import { render_effect } from '../../reactivity/effects.js';
import { trigger_transitions } from '../../transitions.js';
import { safe_not_equal } from '../../reactivity/equality.js';
/** @returns {import('../../types.js').KeyBlock} */
function create_key_block() {

@ -3,10 +3,8 @@ import {
get,
set,
update,
source,
updating_derived,
UNINITIALIZED,
mutable_source,
batch_inspect,
current_component_context
} from './runtime.js';
@ -22,6 +20,7 @@ import {
object_prototype
} from './utils.js';
import { add_owner, check_ownership, strip_owner } from './dev/ownership.js';
import { mutable_source, source } from './reactivity/sources.js';
export const STATE_SYMBOL = Symbol('$state');

@ -0,0 +1,30 @@
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
export function default_equals(a, b) {
return a === b;
}
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
export function safe_not_equal(a, b) {
// eslint-disable-next-line eqeqeq
return a != a
? // eslint-disable-next-line eqeqeq
b == b
: a !== b || (a !== null && typeof a === 'object') || typeof a === 'function';
}
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
export function safe_equal(a, b) {
return !safe_not_equal(a, b);
}

@ -0,0 +1,75 @@
/**
* @template V
* @param {V} initial_value
* @returns {import('../types.js').SourceSignal<V>}
*/
import { DEV } from 'esm-env';
import { CLEAN, SOURCE, current_component_context } from '../runtime.js';
import { default_equals, safe_equal } from './equality.js';
/**
* @template V
* @param {V} initial_value
* @returns {import('../types.js').SourceSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function source(initial_value) {
return create_source_signal(SOURCE | CLEAN, initial_value);
}
/**
* @template V
* @param {V} initial_value
* @returns {import('../types.js').SourceSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function mutable_source(initial_value) {
const s = source(initial_value);
s.e = safe_equal;
// bind the signal to the component context, in case we need to
// track updates to trigger beforeUpdate/afterUpdate callbacks
if (current_component_context) {
(current_component_context.d ??= []).push(s);
}
return s;
}
/**
* @template V
* @param {import('../types.js').SignalFlags} flags
* @param {V} value
* @returns {import('../types.js').SourceSignal<V> | import('../types.js').SourceSignal<V> & import('../types.js').SourceSignalDebug}
*/
function create_source_signal(flags, value) {
if (DEV) {
return {
// consumers
c: null,
// equals
e: default_equals,
// flags
f: flags,
// value
v: value,
// write version
w: 0,
// this is for DEV only
inspect: new Set()
};
}
return {
// consumers
c: null,
// equals
e: default_equals,
// flags
f: flags,
// value
v: value,
// write version
w: 0
};
}

@ -20,6 +20,8 @@ import {
import { STATE_SYMBOL, unstate } from './proxy.js';
import { EACH_BLOCK, IF_BLOCK } from './block.js';
import { pre_effect, user_effect } from './reactivity/effects.js';
import { mutable_source, source } from './reactivity/sources.js';
import { default_equals, safe_equal, safe_not_equal } from './reactivity/equality.js';
export const SOURCE = 1;
export const DERIVED = 1 << 1;
@ -145,52 +147,6 @@ export function batch_inspect(target, prop, receiver) {
};
}
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
export function default_equals(a, b) {
return a === b;
}
/**
* @template V
* @param {import('./types.js').SignalFlags} flags
* @param {V} value
* @returns {import('./types.js').SourceSignal<V> | import('./types.js').SourceSignal<V> & import('./types.js').SourceSignalDebug}
*/
function create_source_signal(flags, value) {
if (DEV) {
return {
// consumers
c: null,
// equals
e: default_equals,
// flags
f: flags,
// value
v: value,
// write version
w: 0,
// this is for DEV only
inspect: new Set()
};
}
return {
// consumers
c: null,
// equals
e: default_equals,
// flags
f: flags,
// value
v: value,
// write version
w: 0
};
}
/**
* @template V
* @param {import('./types.js').SignalFlags} flags
@ -1328,35 +1284,6 @@ export function derived_safe_equal(init) {
return signal;
}
/**
* @template V
* @param {V} initial_value
* @returns {import('./types.js').SourceSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function source(initial_value) {
return create_source_signal(SOURCE | CLEAN, initial_value);
}
/**
* @template V
* @param {V} initial_value
* @returns {import('./types.js').SourceSignal<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
export function mutable_source(initial_value) {
const s = source(initial_value);
s.e = safe_equal;
// bind the signal to the component context, in case we need to
// track updates to trigger beforeUpdate/afterUpdate callbacks
if (current_component_context) {
(current_component_context.d ??= []).push(s);
}
return s;
}
/**
* Use `untrack` to prevent something from being treated as an `$effect`/`$derived` dependency.
*
@ -1542,28 +1469,6 @@ export function prop(props, key, flags, initial) {
};
}
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
export function safe_not_equal(a, b) {
// eslint-disable-next-line eqeqeq
return a != a
? // eslint-disable-next-line eqeqeq
b == b
: a !== b || (a !== null && typeof a === 'object') || typeof a === 'function';
}
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
export function safe_equal(a, b) {
return !safe_not_equal(a, b);
}
/** @returns {Map<unknown, unknown>} */
export function get_or_init_context_map() {
const component_context = current_component_context;

@ -1,5 +1,4 @@
import { EACH_INDEX_REACTIVE } from '../../constants.js';
import { source, untrack } from './runtime.js';
import { untrack } from './runtime.js';
import { is_array } from './utils.js';
/** regex of all html void element names */

@ -4,14 +4,11 @@ export {
set,
set_sync,
invalidate_inner_signals,
source,
mutable_source,
derived,
derived_safe_equal,
prop,
flushSync,
bubble_event,
safe_equal,
tick,
untrack,
update,
@ -41,6 +38,8 @@ export { if_block as if } from './client/dom/blocks/if.js';
export { key_block as key } from './client/dom/blocks/key.js';
export * from './client/dom/blocks/each.js';
export * from './client/reactivity/effects.js';
export * from './client/reactivity/sources.js';
export * from './client/reactivity/equality.js';
export * from './client/render.js';
export * from './client/validate.js';
export { raf } from './client/timing.js';

@ -1,6 +1,7 @@
import { describe, assert, it } from 'vitest';
import * as $ from '../../src/internal/client/runtime';
import { effect, render_effect, user_effect } from '../../src/internal/client/reactivity/effects';
import { source } from '../../src/internal/client/reactivity/sources';
import type { ComputationSignal } from '../../src/internal/client/types';
/**
@ -37,7 +38,7 @@ describe('signals', () => {
test('effect with state and derived in it', () => {
const log: string[] = [];
let count = $.source(0);
let count = source(0);
let double = $.derived(() => $.get(count) * 2);
effect(() => {
log.push(`${$.get(count)}:${$.get(double)}`);
@ -54,7 +55,7 @@ describe('signals', () => {
test('multiple effects with state and derived in it#1', () => {
const log: string[] = [];
let count = $.source(0);
let count = source(0);
let double = $.derived(() => $.get(count) * 2);
effect(() => {
@ -75,7 +76,7 @@ describe('signals', () => {
test('multiple effects with state and derived in it#2', () => {
const log: string[] = [];
let count = $.source(0);
let count = source(0);
let double = $.derived(() => $.get(count) * 2);
effect(() => {
@ -96,7 +97,7 @@ describe('signals', () => {
test('derived from state', () => {
const log: number[] = [];
let count = $.source(0);
let count = source(0);
let double = $.derived(() => $.get(count) * 2);
effect(() => {
@ -114,7 +115,7 @@ describe('signals', () => {
test('derived from derived', () => {
const log: number[] = [];
let count = $.source(0);
let count = source(0);
let double = $.derived(() => $.get(count) * 2);
let quadruple = $.derived(() => $.get(double) * 2);
@ -137,8 +138,8 @@ describe('signals', () => {
const fib = (n: number): number => (n < 2 ? 1 : fib(n - 1) + fib(n - 2));
const hard = (n: number, l: string) => n + fib(16);
const A = $.source(0);
const B = $.source(0);
const A = source(0);
const B = source(0);
const C = $.derived(() => ($.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'));
@ -177,7 +178,7 @@ describe('signals', () => {
test('effects correctly handle unowned derived values that do not change', () => {
const log: number[] = [];
let count = $.source(0);
let count = source(0);
const read = () => {
const x = $.derived(() => ({ count: $.get(count) }));
return $.get(x);
@ -205,8 +206,8 @@ describe('signals', () => {
return () => {
const nested: ComputationSignal<string>[] = [];
const a = $.source(0);
const b = $.source(0);
const a = source(0);
const b = source(0);
const c = $.derived(() => {
const a_2 = $.derived(() => $.get(a) + '!');
const b_2 = $.derived(() => $.get(b) + '?');
@ -234,7 +235,7 @@ describe('signals', () => {
});
// outside of test function so that they are unowned signals
let count = $.source(0);
let count = source(0);
let calc = $.derived(() => {
if ($.get(count) >= 2) {
return 'limit';
@ -285,7 +286,7 @@ describe('signals', () => {
};
});
let some_state = $.source({});
let some_state = source({});
let some_deps = $.derived(() => {
return [$.get(some_state)];
});
@ -310,7 +311,7 @@ describe('signals', () => {
test('schedules rerun when writing to signal before reading it', (runes) => {
if (!runes) return () => {};
const value = $.source({ count: 0 });
const value = source({ count: 0 });
user_effect(() => {
$.set(value, { count: 0 });
$.get(value);

Loading…
Cancel
Save