ripple 0.3.127 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +293 -0
- package/package.json +10 -4
- package/src/runtime/element.js +23 -6
- package/src/runtime/index-client.js +81 -41
- package/src/runtime/index-server.js +1 -0
- package/src/runtime/internal/client/blocks.js +192 -114
- package/src/runtime/internal/client/component.js +4 -30
- package/src/runtime/internal/client/composite.js +12 -13
- package/src/runtime/internal/client/constants.js +14 -5
- package/src/runtime/internal/client/context.js +12 -19
- package/src/runtime/internal/client/css.js +7 -9
- package/src/runtime/internal/client/events.js +178 -90
- package/src/runtime/internal/client/expression.js +185 -124
- package/src/runtime/internal/client/for.js +616 -264
- package/src/runtime/internal/client/head.js +10 -5
- package/src/runtime/internal/client/html.js +1 -0
- package/src/runtime/internal/client/hydration.js +152 -10
- package/src/runtime/internal/client/if.js +239 -50
- package/src/runtime/internal/client/index.js +9 -13
- package/src/runtime/internal/client/operations.js +44 -51
- package/src/runtime/internal/client/portal.js +163 -85
- package/src/runtime/internal/client/render.js +44 -25
- package/src/runtime/internal/client/rpc.js +3 -3
- package/src/runtime/internal/client/runtime.js +799 -576
- package/src/runtime/internal/client/selector.js +77 -0
- package/src/runtime/internal/client/template.js +133 -158
- package/src/runtime/internal/client/transport.js +38 -0
- package/src/runtime/internal/client/try.js +465 -426
- package/src/runtime/internal/client/types.d.ts +65 -21
- package/src/runtime/internal/client/utils.js +1 -3
- package/src/runtime/internal/server/dynamic.js +20 -21
- package/src/runtime/internal/server/index.js +327 -275
- package/src/runtime/internal/server/rpc.js +3 -2
- package/src/runtime/internal/server/transport.js +16 -0
- package/src/runtime/transport.js +21 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +0 -5
- package/tests/client/array/array.copy-within.test.tsrx +12 -12
- package/tests/client/array/array.derived.test.tsrx +46 -46
- package/tests/client/array/array.iteration.test.tsrx +10 -10
- package/tests/client/array/array.mutations.test.tsrx +20 -20
- package/tests/client/array/array.static.test.tsrx +11 -11
- package/tests/client/array/array.to-methods.test.tsrx +6 -6
- package/tests/client/async-suspend.test.tsrx +74 -75
- package/tests/client/basic/basic.attributes.test.tsrx +86 -83
- package/tests/client/basic/basic.collections.test.tsrx +12 -12
- package/tests/client/basic/basic.components.test.tsrx +99 -25
- package/tests/client/basic/basic.errors.test.tsrx +18 -18
- package/tests/client/basic/basic.events.test.tsrx +42 -42
- package/tests/client/basic/basic.get-set.test.tsrx +8 -8
- package/tests/client/basic/basic.reactivity.test.tsrx +97 -29
- package/tests/client/basic/basic.rendering.test.tsrx +25 -25
- package/tests/client/basic/basic.utilities.test.tsrx +3 -3
- package/tests/client/boundaries.test.tsrx +8 -8
- package/tests/client/boxed-locals.test.tsrx +452 -0
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +6 -6
- package/tests/client/compiler/compiler.assignments.test.tsrx +9 -73
- package/tests/client/compiler/compiler.attributes.test.tsrx +23 -23
- package/tests/client/compiler/compiler.basic.test.tsrx +15 -60
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +18 -43
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +2 -2
- package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -1
- package/tests/client/composite/composite.dynamic-components.test.tsrx +77 -6
- package/tests/client/composite/composite.props.test.tsrx +149 -12
- package/tests/client/composite/composite.reactivity.test.tsrx +51 -52
- package/tests/client/composite/composite.render.test.tsrx +26 -9
- package/tests/client/css/scoped-styles.test.tsrx +8 -8
- package/tests/client/date.test.tsrx +42 -42
- package/tests/client/derived-release.test.tsrx +370 -0
- package/tests/client/dynamic-elements.test.tsrx +45 -45
- package/tests/client/events.test.tsrx +97 -71
- package/tests/client/for-selector.test.tsrx +221 -0
- package/tests/client/for-single-root-items.test.tsrx +118 -3
- package/tests/client/for.test.tsrx +332 -31
- package/tests/client/head.test.tsrx +19 -19
- package/tests/client/html.test.tsrx +11 -9
- package/tests/client/if-block.test.tsrx +80 -0
- package/tests/client/map.test.tsrx +16 -16
- package/tests/client/media-query.test.tsrx +7 -7
- package/tests/client/portal.test.tsrx +224 -26
- package/tests/client/primitive-text.test.tsrx +50 -0
- package/tests/client/prop-kind-switch.test.tsrx +141 -0
- package/tests/client/ref.test.tsrx +17 -17
- package/tests/client/return.test.tsrx +26 -3
- package/tests/client/root-boundary.test.tsrx +42 -0
- package/tests/client/scoped-flush.test.tsrx +8 -8
- package/tests/client/set.test.tsrx +6 -6
- package/tests/client/svg.test.tsrx +11 -11
- package/tests/client/switch.test.tsrx +44 -44
- package/tests/client/track-async-hydration.test.tsrx +4 -4
- package/tests/client/try.test.tsrx +151 -83
- package/tests/client/tsx.test.tsrx +43 -40
- package/tests/client/url/url.derived.test.tsrx +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +2 -2
- package/tests/hydration/basic.test.js +74 -1
- package/tests/hydration/build-components.js +22 -1
- package/tests/hydration/compiled/client/basic.js +1142 -713
- package/tests/hydration/compiled/client/composite.js +151 -100
- package/tests/hydration/compiled/client/events.js +190 -150
- package/tests/hydration/compiled/client/for.js +1472 -1126
- package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
- package/tests/hydration/compiled/client/head.js +255 -199
- package/tests/hydration/compiled/client/hmr.js +54 -41
- package/tests/hydration/compiled/client/html-in-template.js +54 -39
- package/tests/hydration/compiled/client/html.js +1633 -1263
- package/tests/hydration/compiled/client/if-children.js +420 -270
- package/tests/hydration/compiled/client/if-fragment-controlflow.js +363 -317
- package/tests/hydration/compiled/client/if.js +229 -219
- package/tests/hydration/compiled/client/mixed-control-flow.js +420 -400
- package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1255
- package/tests/hydration/compiled/client/portal.js +87 -95
- package/tests/hydration/compiled/client/reactivity.js +140 -83
- package/tests/hydration/compiled/client/return.js +28 -19
- package/tests/hydration/compiled/client/streaming.js +390 -306
- package/tests/hydration/compiled/client/switch.js +258 -266
- package/tests/hydration/compiled/client/track-async-serialization.js +448 -280
- package/tests/hydration/compiled/client/try.js +173 -129
- package/tests/hydration/compiled/client/typed-text.js +71 -0
- package/tests/hydration/compiled/fixtures/money.js +10 -0
- package/tests/hydration/compiled/server/basic.js +123 -6
- package/tests/hydration/compiled/server/composite.js +16 -30
- package/tests/hydration/compiled/server/events.js +19 -19
- package/tests/hydration/compiled/server/for.js +109 -49
- package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
- package/tests/hydration/compiled/server/head.js +20 -28
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +71 -247
- package/tests/hydration/compiled/server/if-children.js +107 -15
- package/tests/hydration/compiled/server/if.js +11 -15
- package/tests/hydration/compiled/server/mixed-control-flow.js +8 -8
- package/tests/hydration/compiled/server/portal.js +14 -22
- package/tests/hydration/compiled/server/reactivity.js +14 -46
- package/tests/hydration/compiled/server/streaming.js +19 -19
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/compiled/server/track-async-serialization.js +150 -23
- package/tests/hydration/compiled/server/try.js +8 -8
- package/tests/hydration/compiled/server/typed-text.js +17 -0
- package/tests/hydration/components/basic.tsrx +44 -8
- package/tests/hydration/components/composite.tsrx +2 -2
- package/tests/hydration/components/events.tsrx +25 -25
- package/tests/hydration/components/for.tsrx +115 -67
- package/tests/hydration/components/fragment-cursor.tsrx +650 -0
- package/tests/hydration/components/head.tsrx +16 -16
- package/tests/hydration/components/hmr.tsrx +2 -2
- package/tests/hydration/components/html.tsrx +7 -7
- package/tests/hydration/components/if-children.tsrx +72 -25
- package/tests/hydration/components/if.tsrx +18 -18
- package/tests/hydration/components/mixed-control-flow.tsrx +11 -11
- package/tests/hydration/components/portal.tsrx +3 -3
- package/tests/hydration/components/reactivity.tsrx +16 -16
- package/tests/hydration/components/streaming.tsrx +20 -20
- package/tests/hydration/components/switch.tsrx +20 -20
- package/tests/hydration/components/text-types.ts +4 -0
- package/tests/hydration/components/track-async-serialization.tsrx +80 -26
- package/tests/hydration/components/try.tsrx +8 -8
- package/tests/hydration/components/typed-text.tsrx +22 -0
- package/tests/hydration/fixtures/money.js +10 -0
- package/tests/hydration/for.test.js +36 -0
- package/tests/hydration/fragment-cursor.test.js +111 -0
- package/tests/hydration/if-children.test.js +24 -0
- package/tests/hydration/streaming.test.js +19 -0
- package/tests/hydration/track-async-serialization.test.js +87 -2
- package/tests/hydration/tsconfig.text-types.json +10 -0
- package/tests/hydration/typed-text.test.js +34 -0
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +42 -42
- package/tests/server/basic.components.test.tsrx +64 -8
- package/tests/server/basic.test.tsrx +34 -32
- package/tests/server/compiler.test.tsrx +1 -70
- package/tests/server/composite.props.test.tsrx +6 -6
- package/tests/server/dynamic-elements.test.tsrx +31 -8
- package/tests/server/for.test.tsrx +94 -0
- package/tests/server/head.test.tsrx +11 -11
- package/tests/server/scoped-styles.test.tsrx +2 -2
- package/tests/server/streaming-ssr.test.tsrx +48 -43
- package/tests/server/track-async-serialization.test.tsrx +204 -21
- package/tests/server/try.test.tsrx +48 -48
- package/tests/types/transport.ts +40 -0
- package/tests/utils/vite-plugin-config.test.js +23 -0
- package/types/index.d.ts +48 -7
- package/types/server.d.ts +3 -0
- package/types/transport.d.ts +15 -0
- package/src/runtime/internal/client/switch.js +0 -113
- package/src/utils/errors.js +0 -13
- package/tests/client/lazy-array.test.tsrx +0 -31
- package/tests/client/lazy-destructuring.test.tsrx +0 -438
- package/tests/client/tracked-index-access.test.tsrx +0 -113
- package/tests/server/lazy-destructuring.test.tsrx +0 -595
- package/tests/server/tracked-index-access.test.tsrx +0 -76
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/** @import { Block, Derived, Component } from '#client' */
|
|
1
|
+
/** @import { AppendIntoAnchor, Block, Derived, Component } from '#client' */
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
BLOCK_HAS_RUN,
|
|
5
5
|
BRANCH_BLOCK,
|
|
6
6
|
DERIVED,
|
|
7
|
-
CONTAINS_TEARDOWN,
|
|
8
7
|
DESTROYED,
|
|
9
8
|
EFFECT_BLOCK,
|
|
10
9
|
PAUSED,
|
|
@@ -12,10 +11,12 @@ import {
|
|
|
12
11
|
RENDER_BLOCK,
|
|
13
12
|
ROOT_BLOCK,
|
|
14
13
|
TRY_BLOCK,
|
|
14
|
+
DETACHED_BLOCK,
|
|
15
15
|
HEAD_BLOCK,
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
IF_BLOCK,
|
|
17
|
+
CREATES_DERIVEDS,
|
|
18
18
|
} from './constants.js';
|
|
19
|
+
import { hydrating } from './hydration.js';
|
|
19
20
|
import { next_sibling } from './operations.js';
|
|
20
21
|
import { apply_element_spread } from './render.js';
|
|
21
22
|
import { is_array } from '@tsrx/core/runtime/language-helpers';
|
|
@@ -23,8 +24,10 @@ import {
|
|
|
23
24
|
active_block,
|
|
24
25
|
active_component,
|
|
25
26
|
active_reaction,
|
|
26
|
-
create_component_ctx,
|
|
27
27
|
is_block_dirty,
|
|
28
|
+
release_deriveds,
|
|
29
|
+
take_created_deriveds,
|
|
30
|
+
remove_dependencies,
|
|
28
31
|
run_block,
|
|
29
32
|
run_teardown,
|
|
30
33
|
schedule_update,
|
|
@@ -44,12 +47,9 @@ export function user_effect(fn) {
|
|
|
44
47
|
|
|
45
48
|
var component = active_component;
|
|
46
49
|
if (component !== null && !component.m) {
|
|
50
|
+
// Flat triples, created once the component has rendered (`pop_component`).
|
|
47
51
|
var e = (component.e ??= []);
|
|
48
|
-
e.push(
|
|
49
|
-
b: active_block,
|
|
50
|
-
fn,
|
|
51
|
-
r: active_reaction,
|
|
52
|
-
});
|
|
52
|
+
e.push(fn, active_block, active_reaction);
|
|
53
53
|
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
@@ -78,17 +78,20 @@ export function pre_effect(fn) {
|
|
|
78
78
|
* @param {number} [flags]
|
|
79
79
|
*/
|
|
80
80
|
export function render(fn, state, flags = 0) {
|
|
81
|
-
|
|
81
|
+
// block(), inline: a render block runs at once.
|
|
82
|
+
var block = create_block(RENDER_BLOCK | flags, fn, state);
|
|
83
|
+
run_block(block, true);
|
|
84
|
+
block.f ^= BLOCK_HAS_RUN;
|
|
85
|
+
return block;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
/**
|
|
85
89
|
* @param {any} element
|
|
86
90
|
* @param {any} fn
|
|
87
91
|
* @param {number} [flags]
|
|
88
|
-
* @param {string} [exclude_prop]
|
|
89
92
|
*/
|
|
90
|
-
export function render_spread(element, fn, flags = 0
|
|
91
|
-
return block(RENDER_BLOCK | flags, apply_element_spread(element, fn
|
|
93
|
+
export function render_spread(element, fn, flags = 0) {
|
|
94
|
+
return block(RENDER_BLOCK | flags, apply_element_spread(element, fn));
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
/**
|
|
@@ -100,6 +103,24 @@ export function branch(fn, flags = 0, state = null) {
|
|
|
100
103
|
return block(BRANCH_BLOCK | flags, fn, state);
|
|
101
104
|
}
|
|
102
105
|
|
|
106
|
+
function noop() {}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Gives a text anchor materialized by `resolve_anchor` a branch block of its
|
|
110
|
+
* own, so destroying the enclosing block removes the anchor along with the
|
|
111
|
+
* content: a portal target outlives its content, and nothing else owns a node
|
|
112
|
+
* appended there. Call it after creating the anchored block so block order
|
|
113
|
+
* matches DOM order (the content is inserted before the anchor). A no-op when
|
|
114
|
+
* `anchor` is the node as received (an ordinary anchor belongs to a template)
|
|
115
|
+
* or the SSR marker the sentinel resolves to during hydration.
|
|
116
|
+
* @param {Node | AppendIntoAnchor} node
|
|
117
|
+
* @param {Node} anchor
|
|
118
|
+
*/
|
|
119
|
+
export function own_anchor(node, anchor) {
|
|
120
|
+
if (anchor === node || hydrating) return;
|
|
121
|
+
branch(noop, 0, { start: anchor, end: anchor });
|
|
122
|
+
}
|
|
123
|
+
|
|
103
124
|
/**
|
|
104
125
|
* Wire up a `ref={expr}` attribute. `expr` may be:
|
|
105
126
|
* - a callback function — invoked with the element on mount; if it returns
|
|
@@ -114,89 +135,95 @@ export function branch(fn, flags = 0, state = null) {
|
|
|
114
135
|
* doesn't subscribe to whatever the thunk happens to read. The supported
|
|
115
136
|
* shape is to pass the ref slot itself (`ref={tracker}`); a foot-gun like
|
|
116
137
|
* `ref={tracker.value}` would otherwise read the cell reactively and cause
|
|
117
|
-
* spurious re-runs.
|
|
138
|
+
* spurious re-runs. Read untracked, the value is fixed for the life of the
|
|
139
|
+
* enclosing block, so each ref is a single effect block keyed on its state
|
|
140
|
+
* rather than a render block re-evaluating the thunk.
|
|
118
141
|
*
|
|
119
142
|
* @param {Element} element
|
|
120
143
|
* @param {() => any} get_fn
|
|
121
144
|
* @param {(value: any) => void} [set_fn]
|
|
122
|
-
* @returns {
|
|
145
|
+
* @returns {void}
|
|
123
146
|
*/
|
|
124
147
|
export function ref(element, get_fn, set_fn) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
var ref_value = UNINITIALIZED;
|
|
128
|
-
/** @type {Block | null} */
|
|
129
|
-
var e;
|
|
130
|
-
|
|
131
|
-
return block(RENDER_BLOCK, () => {
|
|
132
|
-
// avoid any reactive reads
|
|
133
|
-
var next = untrack(get_fn);
|
|
134
|
-
if (ref_value !== (ref_value = next)) {
|
|
135
|
-
if (e) {
|
|
136
|
-
destroy_block(e);
|
|
137
|
-
e = null;
|
|
138
|
-
}
|
|
148
|
+
apply_ref(element, untrack(get_fn), set_fn);
|
|
149
|
+
}
|
|
139
150
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
});
|
|
151
|
-
} else if (is_ripple_object(ref_value)) {
|
|
152
|
-
e = branch(() => {
|
|
153
|
-
effect(() => {
|
|
154
|
-
ref_value.value = element;
|
|
155
|
-
return () => {
|
|
156
|
-
ref_value.value = null;
|
|
157
|
-
};
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
} else if (set_fn !== undefined) {
|
|
161
|
-
e = branch(() => {
|
|
162
|
-
effect(() => {
|
|
163
|
-
set_fn(element);
|
|
164
|
-
return () => {
|
|
165
|
-
set_fn(null);
|
|
166
|
-
};
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
}
|
|
151
|
+
/**
|
|
152
|
+
* @param {Element} element
|
|
153
|
+
* @param {any} ref_value
|
|
154
|
+
* @param {((value: any) => void) | undefined} set_fn
|
|
155
|
+
* @returns {void}
|
|
156
|
+
*/
|
|
157
|
+
function apply_ref(element, ref_value, set_fn) {
|
|
158
|
+
if (is_array(ref_value)) {
|
|
159
|
+
for (var i = 0; i < ref_value.length; i++) {
|
|
160
|
+
apply_ref(element, ref_value[i], undefined);
|
|
170
161
|
}
|
|
171
|
-
})
|
|
162
|
+
} else if (typeof ref_value === 'function') {
|
|
163
|
+
block(EFFECT_BLOCK, run_function_ref, { e: element, f: ref_value });
|
|
164
|
+
} else if (is_ripple_object(ref_value)) {
|
|
165
|
+
block(EFFECT_BLOCK, run_tracked_ref, { e: element, t: ref_value });
|
|
166
|
+
} else if (set_fn !== undefined) {
|
|
167
|
+
block(EFFECT_BLOCK, run_set_ref, { e: element, f: set_fn });
|
|
168
|
+
}
|
|
172
169
|
}
|
|
173
170
|
|
|
174
171
|
/**
|
|
175
|
-
*
|
|
176
|
-
* @
|
|
172
|
+
* The callback's return value is the effect's teardown.
|
|
173
|
+
* @param {{ e: Element, f: (element: Element) => any }} s
|
|
177
174
|
*/
|
|
178
|
-
|
|
179
|
-
return
|
|
175
|
+
function run_function_ref(s) {
|
|
176
|
+
return s.f(s.e);
|
|
180
177
|
}
|
|
181
178
|
|
|
182
179
|
/**
|
|
183
|
-
* @param {
|
|
184
|
-
* @param {any} state
|
|
185
|
-
* @returns {Block}
|
|
180
|
+
* @param {{ e: Element, t: { value: any } }} s
|
|
186
181
|
*/
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
function run_tracked_ref(s) {
|
|
183
|
+
s.t.value = s.e;
|
|
184
|
+
return clear_tracked_ref;
|
|
189
185
|
}
|
|
190
186
|
|
|
191
187
|
/**
|
|
192
|
-
*
|
|
193
|
-
* @param {
|
|
194
|
-
|
|
188
|
+
* Teardowns keyed on block state receive it (see `run_teardown`).
|
|
189
|
+
* @param {{ e: Element, t: { value: any } }} s
|
|
190
|
+
*/
|
|
191
|
+
function clear_tracked_ref(s) {
|
|
192
|
+
s.t.value = null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @param {{ e: Element, f: (value: any) => void }} s
|
|
197
|
+
*/
|
|
198
|
+
function run_set_ref(s) {
|
|
199
|
+
s.f(s.e);
|
|
200
|
+
return clear_set_ref;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @param {{ e: Element, f: (value: any) => void }} s
|
|
205
|
+
*/
|
|
206
|
+
function clear_set_ref(s) {
|
|
207
|
+
s.f(null);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @param {() => (void | (() => void))} fn
|
|
212
|
+
* @returns {Block}
|
|
195
213
|
*/
|
|
196
|
-
export function
|
|
197
|
-
|
|
214
|
+
export function root(fn) {
|
|
215
|
+
// create_component_ctx, inline: the root is the first component context.
|
|
216
|
+
return block(
|
|
217
|
+
ROOT_BLOCK,
|
|
218
|
+
fn,
|
|
219
|
+
{ start: null, end: null },
|
|
220
|
+
{ b: active_block, c: null, e: null, m: false, p: active_component },
|
|
221
|
+
);
|
|
198
222
|
}
|
|
199
223
|
|
|
224
|
+
/** Creation counter: a parent always has a lower id than its descendants. */
|
|
225
|
+
var block_id = 0;
|
|
226
|
+
|
|
200
227
|
/**
|
|
201
228
|
* @param {Block} block
|
|
202
229
|
* @param {Block} parent_block
|
|
@@ -220,6 +247,27 @@ function push_block(block, parent_block) {
|
|
|
220
247
|
* @returns {Block}
|
|
221
248
|
*/
|
|
222
249
|
export function block(flags, fn, state = null, co) {
|
|
250
|
+
var block = create_block(flags, fn, state, co);
|
|
251
|
+
|
|
252
|
+
if ((flags & EFFECT_BLOCK) !== 0) {
|
|
253
|
+
schedule_update(block);
|
|
254
|
+
} else {
|
|
255
|
+
run_block(block, true);
|
|
256
|
+
block.f ^= BLOCK_HAS_RUN;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return block;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Allocates a block and links it under the active block without running it.
|
|
264
|
+
* @param {number} flags
|
|
265
|
+
* @param {Function} fn
|
|
266
|
+
* @param {any} [state]
|
|
267
|
+
* @param {Component} [co]
|
|
268
|
+
* @returns {Block}
|
|
269
|
+
*/
|
|
270
|
+
export function create_block(flags, fn, state = null, co) {
|
|
223
271
|
/** @type {Block} */
|
|
224
272
|
var block = {
|
|
225
273
|
co: co || active_component,
|
|
@@ -227,6 +275,7 @@ export function block(flags, fn, state = null, co) {
|
|
|
227
275
|
first: null,
|
|
228
276
|
f: flags,
|
|
229
277
|
fn,
|
|
278
|
+
i: ++block_id,
|
|
230
279
|
last: null,
|
|
231
280
|
next: null,
|
|
232
281
|
p: active_block,
|
|
@@ -240,15 +289,17 @@ export function block(flags, fn, state = null, co) {
|
|
|
240
289
|
(/** @type {Derived} */ (active_reaction).blocks ??= []).push(block);
|
|
241
290
|
}
|
|
242
291
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
292
|
+
var parent_block = active_block;
|
|
293
|
+
if (parent_block !== null) {
|
|
294
|
+
// push_block, inline: block creation is the hot path.
|
|
295
|
+
var parent_last = parent_block.last;
|
|
296
|
+
if (parent_last === null) {
|
|
297
|
+
parent_block.last = parent_block.first = block;
|
|
298
|
+
} else {
|
|
299
|
+
parent_last.next = block;
|
|
300
|
+
block.prev = parent_last;
|
|
301
|
+
parent_block.last = block;
|
|
302
|
+
}
|
|
252
303
|
}
|
|
253
304
|
|
|
254
305
|
return block;
|
|
@@ -262,12 +313,10 @@ export function destroy_block_children(parent, remove_dom = false) {
|
|
|
262
313
|
var block = parent.first;
|
|
263
314
|
parent.first = parent.last = null;
|
|
264
315
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
block = next;
|
|
270
|
-
}
|
|
316
|
+
while (block !== null) {
|
|
317
|
+
var next = block.next;
|
|
318
|
+
destroy_block(block, remove_dom);
|
|
319
|
+
block = next;
|
|
271
320
|
}
|
|
272
321
|
}
|
|
273
322
|
|
|
@@ -278,20 +327,12 @@ export function destroy_block_children(parent, remove_dom = false) {
|
|
|
278
327
|
export function destroy_non_branch_children(parent, remove_dom = false) {
|
|
279
328
|
var block = parent.first;
|
|
280
329
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
) {
|
|
286
|
-
parent.first = parent.last = null;
|
|
287
|
-
} else {
|
|
288
|
-
while (block !== null) {
|
|
289
|
-
var next = block.next;
|
|
290
|
-
if ((block.f & BRANCH_BLOCK) === 0) {
|
|
291
|
-
destroy_block(block, remove_dom);
|
|
292
|
-
}
|
|
293
|
-
block = next;
|
|
330
|
+
while (block !== null) {
|
|
331
|
+
var next = block.next;
|
|
332
|
+
if ((block.f & BRANCH_BLOCK) === 0) {
|
|
333
|
+
destroy_block(block, remove_dom);
|
|
294
334
|
}
|
|
335
|
+
block = next;
|
|
295
336
|
}
|
|
296
337
|
}
|
|
297
338
|
|
|
@@ -312,6 +353,23 @@ export function unlink_block(block) {
|
|
|
312
353
|
}
|
|
313
354
|
}
|
|
314
355
|
|
|
356
|
+
/**
|
|
357
|
+
* Moves `block` to the end of its parent's child list. A block whose content
|
|
358
|
+
* is inserted before an anchor the parent already owns is created after the
|
|
359
|
+
* anchor's block; relinking keeps block order equal to DOM order, which the
|
|
360
|
+
* first/last node descent in `get_first_node`/`get_last_node` relies on.
|
|
361
|
+
* @param {Block} block
|
|
362
|
+
*/
|
|
363
|
+
export function move_block_last(block) {
|
|
364
|
+
var parent = /** @type {Block} */ (block.p);
|
|
365
|
+
if (parent.last === block) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
unlink_block(block);
|
|
369
|
+
block.prev = block.next = null;
|
|
370
|
+
push_block(block, parent);
|
|
371
|
+
}
|
|
372
|
+
|
|
315
373
|
/**
|
|
316
374
|
* @param {Block} block
|
|
317
375
|
*/
|
|
@@ -401,8 +459,8 @@ export function remove_block_dom(node, end) {
|
|
|
401
459
|
export function move_block(block, target) {
|
|
402
460
|
var f = block.f;
|
|
403
461
|
|
|
404
|
-
// Only
|
|
405
|
-
if ((f & BRANCH_BLOCK) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
462
|
+
// Only branch and if blocks (excluding TRY_BLOCK) can have DOM state to move
|
|
463
|
+
if ((f & (BRANCH_BLOCK | IF_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
406
464
|
var s = block.s;
|
|
407
465
|
if (s !== null && s.start !== null) {
|
|
408
466
|
var node = s.start;
|
|
@@ -413,6 +471,10 @@ export function move_block(block, target) {
|
|
|
413
471
|
target.append(node);
|
|
414
472
|
node = next;
|
|
415
473
|
}
|
|
474
|
+
// An if's materialized anchor follows its range.
|
|
475
|
+
if ((f & IF_BLOCK) !== 0 && s.o !== null) {
|
|
476
|
+
move_block(s.o, target);
|
|
477
|
+
}
|
|
416
478
|
return true;
|
|
417
479
|
}
|
|
418
480
|
}
|
|
@@ -430,8 +492,8 @@ export function move_block(block, target) {
|
|
|
430
492
|
}
|
|
431
493
|
|
|
432
494
|
/**
|
|
433
|
-
* Resolve the first DOM node owned by a block. A block normally
|
|
434
|
-
* range in `s.start`/`s.end`, but an optimized single control-flow / component
|
|
495
|
+
* Resolve the first DOM node owned by a block. A branch or if block normally
|
|
496
|
+
* records its range in `s.start`/`s.end`, but an optimized single control-flow / component
|
|
435
497
|
* root scope renders its content through a descendant block instead of a
|
|
436
498
|
* synthesized `<!>` wrapper, so its own `s.start` is null. In that case we
|
|
437
499
|
* descend into child blocks to find the real first node. Returns null when the
|
|
@@ -441,7 +503,7 @@ export function move_block(block, target) {
|
|
|
441
503
|
*/
|
|
442
504
|
export function get_first_node(block) {
|
|
443
505
|
var f = block.f;
|
|
444
|
-
if ((f & BRANCH_BLOCK) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
506
|
+
if ((f & (BRANCH_BLOCK | IF_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
445
507
|
var s = block.s;
|
|
446
508
|
if (s !== null && s.start !== null) {
|
|
447
509
|
return s.start;
|
|
@@ -465,10 +527,11 @@ export function get_first_node(block) {
|
|
|
465
527
|
*/
|
|
466
528
|
export function get_last_node(block) {
|
|
467
529
|
var f = block.f;
|
|
468
|
-
if ((f & BRANCH_BLOCK) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
530
|
+
if ((f & (BRANCH_BLOCK | IF_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
469
531
|
var s = block.s;
|
|
470
532
|
if (s !== null && s.start !== null) {
|
|
471
|
-
|
|
533
|
+
// An if's materialized anchor is its last node.
|
|
534
|
+
return (f & IF_BLOCK) !== 0 && s.o !== null ? s.o.s.end : s.end;
|
|
472
535
|
}
|
|
473
536
|
}
|
|
474
537
|
var child = block.last;
|
|
@@ -487,13 +550,18 @@ export function get_last_node(block) {
|
|
|
487
550
|
* @param {boolean} [remove_dom]
|
|
488
551
|
*/
|
|
489
552
|
export function destroy_block(block, remove_dom = true) {
|
|
490
|
-
block.f
|
|
491
|
-
|
|
553
|
+
var f = (block.f |= DESTROYED);
|
|
492
554
|
var removed = false;
|
|
493
|
-
|
|
555
|
+
|
|
556
|
+
// An ancestor that removed its own range tells its subtree not to bother,
|
|
557
|
+
// but detached content (a portal target, `<head>`) is not inside that
|
|
558
|
+
// range and must still be removed, by this block or by its children.
|
|
559
|
+
if ((f & DETACHED_BLOCK) !== 0) {
|
|
560
|
+
remove_dom = true;
|
|
561
|
+
}
|
|
494
562
|
|
|
495
563
|
if (
|
|
496
|
-
(remove_dom && (f & (BRANCH_BLOCK | ROOT_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0) ||
|
|
564
|
+
(remove_dom && (f & (BRANCH_BLOCK | ROOT_BLOCK | IF_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0) ||
|
|
497
565
|
(f & HEAD_BLOCK) !== 0
|
|
498
566
|
) {
|
|
499
567
|
var s = block.s;
|
|
@@ -507,6 +575,16 @@ export function destroy_block(block, remove_dom = true) {
|
|
|
507
575
|
|
|
508
576
|
run_teardown(block);
|
|
509
577
|
|
|
578
|
+
if (block.d !== null) {
|
|
579
|
+
remove_dependencies(block);
|
|
580
|
+
}
|
|
581
|
+
if ((f & CREATES_DERIVEDS) !== 0) {
|
|
582
|
+
var deriveds = take_created_deriveds(block);
|
|
583
|
+
if (deriveds !== null) {
|
|
584
|
+
release_deriveds(deriveds);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
510
588
|
var parent = block.p;
|
|
511
589
|
|
|
512
590
|
// If the parent doesn't have any children, then skip this work altogether
|
|
@@ -1,36 +1,10 @@
|
|
|
1
|
-
/** @import {
|
|
1
|
+
/** @import { Block } from '#client' */
|
|
2
2
|
|
|
3
3
|
import { is_tsrx_element } from '../../element.js';
|
|
4
4
|
import { render_value } from './expression.js';
|
|
5
|
-
import { active_block
|
|
5
|
+
import { active_block } from './runtime.js';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
* @param {Function} fn
|
|
9
|
-
* @param {Node | AppendIntoAnchor} anchor
|
|
10
|
-
* @param {Record<string, any>} props
|
|
11
|
-
* @param {Block | null} [block=active_block]
|
|
12
|
-
* @returns {void}
|
|
13
|
-
*/
|
|
14
|
-
export function render_component(fn, anchor, props, block = active_block) {
|
|
15
|
-
if (typeof fn !== 'function' || is_tsrx_element(fn)) {
|
|
16
|
-
throw_invalid_component_type(fn);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
run_component(fn, anchor, props, block);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @param {Function} fn
|
|
24
|
-
* @param {Node | AppendIntoAnchor} anchor
|
|
25
|
-
* @param {Record<string, any>} props
|
|
26
|
-
* @param {Block | null} [block=active_block]
|
|
27
|
-
* @returns {void}
|
|
28
|
-
*/
|
|
29
|
-
function run_component(fn, anchor, props, block = active_block) {
|
|
30
|
-
push_component();
|
|
31
|
-
render_value(fn(props), /** @type {ChildNode} */ (anchor), block);
|
|
32
|
-
pop_component();
|
|
33
|
-
}
|
|
7
|
+
export { render_component } from './runtime.js';
|
|
34
8
|
|
|
35
9
|
/**
|
|
36
10
|
* @param {import('../../element.js').TSRXElement} value
|
|
@@ -46,7 +20,7 @@ export function render_tsrx_element(value, anchor, block = active_block) {
|
|
|
46
20
|
* @param {any} value
|
|
47
21
|
* @returns {never}
|
|
48
22
|
*/
|
|
49
|
-
function throw_invalid_component_type(value) {
|
|
23
|
+
export function throw_invalid_component_type(value) {
|
|
50
24
|
if (is_tsrx_element(value)) {
|
|
51
25
|
throw new TypeError('Invalid component type: received a TSRXElement value.');
|
|
52
26
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/** @import { Block } from '#client' */
|
|
2
2
|
|
|
3
|
-
import { exclude_prop_from_object } from '@tsrx/core/runtime/language-helpers';
|
|
4
3
|
import { branch, destroy_block, render, render_spread } from './blocks.js';
|
|
5
4
|
import { COMPOSITE_BLOCK, DEFAULT_NAMESPACE, NAMESPACE_URI } from './constants.js';
|
|
6
5
|
import { hydrate_node, hydrate_next, hydrating, set_hydrate_node } from './hydration.js';
|
|
7
6
|
import { first_child } from './operations.js';
|
|
8
|
-
import { active_block, active_namespace, get, with_ns } from './runtime.js';
|
|
7
|
+
import { active_block, active_namespace, get, untrack, with_ns } from './runtime.js';
|
|
9
8
|
import { top_element_to_ns } from './utils.js';
|
|
10
9
|
import { is_tsrx_element } from '../../element.js';
|
|
11
10
|
import { render_component } from './component.js';
|
|
@@ -14,11 +13,12 @@ import { render_component } from './component.js';
|
|
|
14
13
|
* @typedef {Function | string | null | undefined | false} CompositeTarget
|
|
15
14
|
* @param {() => CompositeTarget} get_component
|
|
16
15
|
* @param {Node} node
|
|
17
|
-
* @param {Record<string, any>} props
|
|
18
|
-
*
|
|
16
|
+
* @param {() => Record<string, any>} get_props the props literal of the call
|
|
17
|
+
* site: read once per rendered component (props are plain values), and
|
|
18
|
+
* re-read as element attributes when the target is a tag
|
|
19
19
|
* @returns {void}
|
|
20
20
|
*/
|
|
21
|
-
export function composite(get_component, node,
|
|
21
|
+
export function composite(get_component, node, get_props) {
|
|
22
22
|
if (hydrating) {
|
|
23
23
|
// During hydration, `node` may already point at the first real SSR node
|
|
24
24
|
// (e.g. layout children). Only skip forward when we are on an empty
|
|
@@ -45,10 +45,8 @@ export function composite(get_component, node, props, exclude_prop) {
|
|
|
45
45
|
if (typeof component === 'function') {
|
|
46
46
|
// Handle as regular component
|
|
47
47
|
b = branch(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
: props;
|
|
51
|
-
render_component(component, anchor, component_props);
|
|
48
|
+
var props = untrack(get_props);
|
|
49
|
+
render_component(component, anchor, props);
|
|
52
50
|
});
|
|
53
51
|
} else if (is_tsrx_element(component)) {
|
|
54
52
|
throw new TypeError('Invalid component type: received a TSRXElement value.');
|
|
@@ -82,9 +80,10 @@ export function composite(get_component, node, props, exclude_prop) {
|
|
|
82
80
|
};
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
render_spread(element,
|
|
83
|
+
render_spread(element, get_props, 0);
|
|
86
84
|
|
|
87
|
-
|
|
85
|
+
var props = untrack(get_props);
|
|
86
|
+
if (is_tsrx_element(props.children)) {
|
|
88
87
|
/** @type {Node} */
|
|
89
88
|
var child_anchor;
|
|
90
89
|
if (hydrating) {
|
|
@@ -97,9 +96,9 @@ export function composite(get_component, node, props, exclude_prop) {
|
|
|
97
96
|
}
|
|
98
97
|
|
|
99
98
|
if (ns !== DEFAULT_NAMESPACE) {
|
|
100
|
-
with_ns(ns, () => props.children.render(child_anchor, block));
|
|
99
|
+
with_ns(ns, () => props.children.render(child_anchor, block, props.children.p));
|
|
101
100
|
} else {
|
|
102
|
-
props.children.render(child_anchor, block);
|
|
101
|
+
props.children.render(child_anchor, block, props.children.p);
|
|
103
102
|
}
|
|
104
103
|
|
|
105
104
|
if (hydrating) {
|
|
@@ -11,7 +11,8 @@ export var ASYNC_BLOCK = 1 << 10;
|
|
|
11
11
|
export var HEAD_BLOCK = 1 << 11;
|
|
12
12
|
export var PRE_EFFECT_BLOCK = 1 << 12;
|
|
13
13
|
export var DIRECT_CHILD_BLOCK = 1 << 13;
|
|
14
|
-
|
|
14
|
+
// Content rendered outside the parent's DOM range (`<head>`, a portal target).
|
|
15
|
+
export var DETACHED_BLOCK = 1 << 14;
|
|
15
16
|
export var CONTAINS_TEARDOWN = 1 << 15;
|
|
16
17
|
export var BLOCK_HAS_RUN = 1 << 16;
|
|
17
18
|
export var TRACKED = 1 << 17;
|
|
@@ -19,10 +20,15 @@ export var DERIVED = 1 << 18;
|
|
|
19
20
|
export var DEFERRED = 1 << 19;
|
|
20
21
|
export var PAUSED = 1 << 20;
|
|
21
22
|
export var DESTROYED = 1 << 21;
|
|
22
|
-
// Marks a block that
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
|
|
23
|
+
// Marks a block that is queued for the next flush.
|
|
24
|
+
export var SCHEDULED = 1 << 22;
|
|
25
|
+
// A per-key match value created by a selector; its map entry is dropped once
|
|
26
|
+
// the last subscriber unlinks.
|
|
27
|
+
export var SELECTOR = 1 << 23;
|
|
28
|
+
// A selector key whose last subscriber left; kept for reuse until a sweep.
|
|
29
|
+
export var RELEASED = 1 << 24;
|
|
30
|
+
/** A block whose latest run created deriveds that are recorded for release (see `release_deriveds`). */
|
|
31
|
+
export var CREATES_DERIVEDS = 1 << 25;
|
|
26
32
|
|
|
27
33
|
export var CONTROL_FLOW_BLOCK = FOR_BLOCK | IF_BLOCK | SWITCH_BLOCK | TRY_BLOCK | COMPOSITE_BLOCK;
|
|
28
34
|
|
|
@@ -53,3 +59,6 @@ export const SUSPENSE_PENDING = Symbol('suspense_pending');
|
|
|
53
59
|
export const SUSPENSE_REJECTED = Symbol('suspense_rejected');
|
|
54
60
|
/** @type {unique symbol} */
|
|
55
61
|
export const ASYNC_DERIVED_READ_THROWN = Symbol('async_derived_read_thrown');
|
|
62
|
+
|
|
63
|
+
/** The hoisted render function a module-level component carries (see `render_component`). */
|
|
64
|
+
export const RENDER_ENTRY = Symbol('render');
|