ripple 0.3.128 → 0.4.1
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 +294 -0
- package/package.json +11 -4
- package/src/jsx-runtime.d.ts +12 -2
- 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 +173 -91
- 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 +9 -0
- 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 +45 -25
- package/src/runtime/internal/client/for.js +409 -129
- 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 +4 -12
- package/src/runtime/internal/client/operations.js +40 -61
- package/src/runtime/internal/client/portal.js +163 -85
- package/src/runtime/internal/client/render.js +44 -43
- package/src/runtime/internal/client/rpc.js +3 -3
- package/src/runtime/internal/client/runtime.js +592 -433
- package/src/runtime/internal/client/selector.js +5 -2
- 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 +56 -23
- 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 +329 -277
- 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 +123 -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 +73 -38
- 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 +14 -14
- 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 +184 -171
- package/tests/hydration/compiled/client/for.js +1472 -1132
- package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
- package/tests/hydration/compiled/client/head.js +254 -201
- 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 -404
- package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1277
- package/tests/hydration/compiled/client/portal.js +87 -95
- package/tests/hydration/compiled/client/reactivity.js +135 -101
- 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 +66 -18
- package/tests/hydration/compiled/server/for.js +117 -41
- package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
- package/tests/hydration/compiled/server/head.js +20 -20
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +70 -238
- 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 -14
- 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 +70 -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/jsx-runtime-types.test.js +67 -2
- package/tests/utils/tracked-types.test.js +117 -0
- package/tests/utils/vite-plugin-config.test.js +23 -0
- package/types/index.d.ts +49 -9
- 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/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +0 -12
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +0 -46
- 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,6 +1,7 @@
|
|
|
1
1
|
import { output_push, noop, tsrx_element } from './internal/server/index.js';
|
|
2
2
|
|
|
3
3
|
export { Fragment } from '../jsx-runtime.js';
|
|
4
|
+
export { set_transport as setTransport } from './internal/server/transport.js';
|
|
4
5
|
export { Context } from './internal/server/context.js';
|
|
5
6
|
export {
|
|
6
7
|
untrack,
|
|
@@ -1,4 +1,4 @@
|
|
|
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,
|
|
@@ -11,10 +11,12 @@ import {
|
|
|
11
11
|
RENDER_BLOCK,
|
|
12
12
|
ROOT_BLOCK,
|
|
13
13
|
TRY_BLOCK,
|
|
14
|
+
DETACHED_BLOCK,
|
|
14
15
|
HEAD_BLOCK,
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
IF_BLOCK,
|
|
17
|
+
CREATES_DERIVEDS,
|
|
17
18
|
} from './constants.js';
|
|
19
|
+
import { hydrating } from './hydration.js';
|
|
18
20
|
import { next_sibling } from './operations.js';
|
|
19
21
|
import { apply_element_spread } from './render.js';
|
|
20
22
|
import { is_array } from '@tsrx/core/runtime/language-helpers';
|
|
@@ -22,8 +24,9 @@ import {
|
|
|
22
24
|
active_block,
|
|
23
25
|
active_component,
|
|
24
26
|
active_reaction,
|
|
25
|
-
create_component_ctx,
|
|
26
27
|
is_block_dirty,
|
|
28
|
+
release_deriveds,
|
|
29
|
+
take_created_deriveds,
|
|
27
30
|
remove_dependencies,
|
|
28
31
|
run_block,
|
|
29
32
|
run_teardown,
|
|
@@ -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,87 +135,90 @@ 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
|
|
195
205
|
*/
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
function clear_set_ref(s) {
|
|
207
|
+
s.f(null);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @param {() => (void | (() => void))} fn
|
|
212
|
+
* @returns {Block}
|
|
213
|
+
*/
|
|
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
|
|
|
200
224
|
/** Creation counter: a parent always has a lower id than its descendants. */
|
|
@@ -223,6 +247,27 @@ function push_block(block, parent_block) {
|
|
|
223
247
|
* @returns {Block}
|
|
224
248
|
*/
|
|
225
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) {
|
|
226
271
|
/** @type {Block} */
|
|
227
272
|
var block = {
|
|
228
273
|
co: co || active_component,
|
|
@@ -244,15 +289,17 @@ export function block(flags, fn, state = null, co) {
|
|
|
244
289
|
(/** @type {Derived} */ (active_reaction).blocks ??= []).push(block);
|
|
245
290
|
}
|
|
246
291
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
+
}
|
|
256
303
|
}
|
|
257
304
|
|
|
258
305
|
return block;
|
|
@@ -306,6 +353,23 @@ export function unlink_block(block) {
|
|
|
306
353
|
}
|
|
307
354
|
}
|
|
308
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
|
+
|
|
309
373
|
/**
|
|
310
374
|
* @param {Block} block
|
|
311
375
|
*/
|
|
@@ -395,8 +459,8 @@ export function remove_block_dom(node, end) {
|
|
|
395
459
|
export function move_block(block, target) {
|
|
396
460
|
var f = block.f;
|
|
397
461
|
|
|
398
|
-
// Only
|
|
399
|
-
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) {
|
|
400
464
|
var s = block.s;
|
|
401
465
|
if (s !== null && s.start !== null) {
|
|
402
466
|
var node = s.start;
|
|
@@ -407,6 +471,10 @@ export function move_block(block, target) {
|
|
|
407
471
|
target.append(node);
|
|
408
472
|
node = next;
|
|
409
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
|
+
}
|
|
410
478
|
return true;
|
|
411
479
|
}
|
|
412
480
|
}
|
|
@@ -424,8 +492,8 @@ export function move_block(block, target) {
|
|
|
424
492
|
}
|
|
425
493
|
|
|
426
494
|
/**
|
|
427
|
-
* Resolve the first DOM node owned by a block. A block normally
|
|
428
|
-
* 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
|
|
429
497
|
* root scope renders its content through a descendant block instead of a
|
|
430
498
|
* synthesized `<!>` wrapper, so its own `s.start` is null. In that case we
|
|
431
499
|
* descend into child blocks to find the real first node. Returns null when the
|
|
@@ -435,7 +503,7 @@ export function move_block(block, target) {
|
|
|
435
503
|
*/
|
|
436
504
|
export function get_first_node(block) {
|
|
437
505
|
var f = block.f;
|
|
438
|
-
if ((f & BRANCH_BLOCK) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
506
|
+
if ((f & (BRANCH_BLOCK | IF_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
439
507
|
var s = block.s;
|
|
440
508
|
if (s !== null && s.start !== null) {
|
|
441
509
|
return s.start;
|
|
@@ -459,10 +527,11 @@ export function get_first_node(block) {
|
|
|
459
527
|
*/
|
|
460
528
|
export function get_last_node(block) {
|
|
461
529
|
var f = block.f;
|
|
462
|
-
if ((f & BRANCH_BLOCK) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
530
|
+
if ((f & (BRANCH_BLOCK | IF_BLOCK)) !== 0 && (f & TRY_BLOCK) === 0) {
|
|
463
531
|
var s = block.s;
|
|
464
532
|
if (s !== null && s.start !== null) {
|
|
465
|
-
|
|
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;
|
|
466
535
|
}
|
|
467
536
|
}
|
|
468
537
|
var child = block.last;
|
|
@@ -484,8 +553,15 @@ export function destroy_block(block, remove_dom = true) {
|
|
|
484
553
|
var f = (block.f |= DESTROYED);
|
|
485
554
|
var removed = false;
|
|
486
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
|
+
}
|
|
562
|
+
|
|
487
563
|
if (
|
|
488
|
-
(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) ||
|
|
489
565
|
(f & HEAD_BLOCK) !== 0
|
|
490
566
|
) {
|
|
491
567
|
var s = block.s;
|
|
@@ -502,6 +578,12 @@ export function destroy_block(block, remove_dom = true) {
|
|
|
502
578
|
if (block.d !== null) {
|
|
503
579
|
remove_dependencies(block);
|
|
504
580
|
}
|
|
581
|
+
if ((f & CREATES_DERIVEDS) !== 0) {
|
|
582
|
+
var deriveds = take_created_deriveds(block);
|
|
583
|
+
if (deriveds !== null) {
|
|
584
|
+
release_deriveds(deriveds);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
505
587
|
|
|
506
588
|
var parent = block.p;
|
|
507
589
|
|
|
@@ -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,6 +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
|
+
// Content rendered outside the parent's DOM range (`<head>`, a portal target).
|
|
15
|
+
export var DETACHED_BLOCK = 1 << 14;
|
|
14
16
|
export var CONTAINS_TEARDOWN = 1 << 15;
|
|
15
17
|
export var BLOCK_HAS_RUN = 1 << 16;
|
|
16
18
|
export var TRACKED = 1 << 17;
|
|
@@ -23,6 +25,10 @@ export var SCHEDULED = 1 << 22;
|
|
|
23
25
|
// A per-key match value created by a selector; its map entry is dropped once
|
|
24
26
|
// the last subscriber unlinks.
|
|
25
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');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import { Component } from '#client' */
|
|
1
|
+
/** @import { Component, ContextEntry } from '#client' */
|
|
2
2
|
|
|
3
3
|
import { active_component } from './runtime.js';
|
|
4
4
|
|
|
@@ -16,25 +16,25 @@ export class Context {
|
|
|
16
16
|
|
|
17
17
|
get() {
|
|
18
18
|
const component = active_component;
|
|
19
|
-
const context = this;
|
|
20
19
|
|
|
21
20
|
if (component === null) {
|
|
22
21
|
throw new Error('No active component found, cannot get context');
|
|
23
22
|
}
|
|
24
|
-
/** @type {Component | null} */
|
|
25
|
-
let current_component = component;
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
// A component inherits its parent's chain of set entries when it is
|
|
25
|
+
// created, so only the values that were set are visited, not every
|
|
26
|
+
// ancestor; the most recent set of a context is nearest the head.
|
|
27
|
+
/** @type {ContextEntry | null} */
|
|
28
|
+
let entry = component.c;
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
while (entry !== null) {
|
|
31
|
+
if (entry.k === this) {
|
|
32
|
+
return entry.v;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
current_component = current_component.p;
|
|
34
|
+
entry = entry.n;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
return
|
|
37
|
+
return this._v;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -43,19 +43,12 @@ export class Context {
|
|
|
43
43
|
*/
|
|
44
44
|
set(value) {
|
|
45
45
|
const component = active_component;
|
|
46
|
-
const context = this;
|
|
47
46
|
|
|
48
47
|
if (component === null) {
|
|
49
48
|
throw new Error('No active component found, cannot set context');
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (current_context === null) {
|
|
55
|
-
current_context = component.c = new Map();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
current_context.set(context, value);
|
|
51
|
+
component.c = { k: this, v: value, n: component.c };
|
|
59
52
|
}
|
|
60
53
|
}
|
|
61
54
|
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { DEV } from 'esm-env';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function remove_styles() {
|
|
3
|
+
/**
|
|
4
|
+
* Removes the server's inline styles once the client stylesheets are in.
|
|
5
|
+
* Schedule it with `requestAnimationFrame`: the removal already waits for a
|
|
6
|
+
* frame after the stylesheets load, and starting from a frame keeps mounting
|
|
7
|
+
* and hydrating free of stylesheet queries.
|
|
8
|
+
*/
|
|
9
|
+
export function remove_styles() {
|
|
12
10
|
if (DEV) {
|
|
13
11
|
const styles = document.querySelector('style[data-vite-dev-id]');
|
|
14
12
|
if (styles) {
|