ripple 0.4.1 → 0.4.3
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 +162 -0
- package/package.json +9 -3
- package/src/constants.js +4 -0
- package/src/jsx-runtime.d.ts +2 -1
- package/src/runtime/array.js +15 -9
- package/src/runtime/index-client.js +25 -7
- package/src/runtime/index-server.js +1 -0
- package/src/runtime/internal/client/attributes.js +313 -0
- package/src/runtime/internal/client/blocks.js +4 -14
- package/src/runtime/internal/client/component.js +2 -5
- package/src/runtime/internal/client/composite.js +14 -6
- package/src/runtime/internal/client/constants.js +12 -6
- package/src/runtime/internal/client/context.js +3 -2
- package/src/runtime/internal/client/css.js +11 -26
- package/src/runtime/internal/client/errors.js +188 -0
- package/src/runtime/internal/client/events.js +79 -34
- package/src/runtime/internal/client/expression.js +21 -116
- package/src/runtime/internal/client/for.js +272 -222
- package/src/runtime/internal/client/head.js +4 -3
- package/src/runtime/internal/client/html.js +5 -3
- package/src/runtime/internal/client/hydrate.js +484 -0
- package/src/runtime/internal/client/hydration-enabled.js +7 -0
- package/src/runtime/internal/client/hydration.js +16 -97
- package/src/runtime/internal/client/if.js +13 -9
- package/src/runtime/internal/client/index.js +16 -8
- package/src/runtime/internal/client/operations.js +12 -9
- package/src/runtime/internal/client/portal.js +3 -2
- package/src/runtime/internal/client/render.js +75 -321
- package/src/runtime/internal/client/root-boundary-enabled.js +7 -0
- package/src/runtime/internal/client/runtime.js +129 -362
- package/src/runtime/internal/client/template-ns.js +47 -0
- package/src/runtime/internal/client/template.js +63 -140
- package/src/runtime/internal/client/track-async.js +356 -0
- package/src/runtime/internal/client/try.js +133 -319
- package/src/runtime/internal/client/types.d.ts +48 -24
- package/src/runtime/internal/server/index.js +38 -33
- package/src/runtime/internal/server/prerender.js +27 -0
- package/src/server/index.js +1 -0
- package/src/utils/class-name.js +28 -0
- package/tests/client/basic/basic.errors.test.tsrx +3 -3
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.tsrx.snap +0 -2
- package/tests/client/compiler/compiler.basic.test.tsrx +4 -4
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +3 -3
- package/tests/client/composite/composite.props.test.tsrx +10 -10
- package/tests/client/derived-release.test.tsrx +3 -3
- package/tests/client/for-item.test.tsrx +443 -0
- package/tests/client/for-selector.test.tsrx +95 -0
- package/tests/hydration/compiled/client/basic.js +97 -123
- package/tests/hydration/compiled/client/composite.js +5 -5
- package/tests/hydration/compiled/client/events.js +84 -79
- package/tests/hydration/compiled/client/for.js +229 -233
- package/tests/hydration/compiled/client/fragment-cursor.js +781 -481
- package/tests/hydration/compiled/client/head.js +23 -26
- package/tests/hydration/compiled/client/hmr.js +4 -4
- package/tests/hydration/compiled/client/html-in-template.js +5 -5
- package/tests/hydration/compiled/client/html.js +174 -208
- package/tests/hydration/compiled/client/if-children.js +71 -70
- package/tests/hydration/compiled/client/if-fragment-controlflow.js +46 -46
- package/tests/hydration/compiled/client/if.js +26 -26
- package/tests/hydration/compiled/client/mixed-control-flow.js +63 -105
- package/tests/hydration/compiled/client/nested-control-flow.js +170 -390
- package/tests/hydration/compiled/client/portal.js +10 -10
- package/tests/hydration/compiled/client/reactivity.js +36 -50
- package/tests/hydration/compiled/client/return.js +2 -2
- package/tests/hydration/compiled/client/streaming.js +34 -40
- package/tests/hydration/compiled/client/switch.js +25 -25
- package/tests/hydration/compiled/client/track-async-serialization.js +41 -41
- package/tests/hydration/compiled/client/try.js +15 -15
- package/tests/hydration/compiled/client/typed-text.js +8 -19
- package/tests/hydration/compiled/server/basic.js +6 -6
- package/tests/hydration/compiled/server/events.js +13 -61
- package/tests/hydration/compiled/server/for.js +23 -31
- package/tests/hydration/compiled/server/fragment-cursor.js +214 -366
- package/tests/hydration/compiled/server/head.js +6 -6
- package/tests/hydration/compiled/server/hmr.js +1 -1
- package/tests/hydration/compiled/server/html.js +1 -1
- package/tests/hydration/compiled/server/if-children.js +9 -9
- package/tests/hydration/compiled/server/if.js +5 -5
- package/tests/hydration/compiled/server/mixed-control-flow.js +4 -4
- package/tests/hydration/compiled/server/portal.js +1 -1
- package/tests/hydration/compiled/server/reactivity.js +9 -9
- package/tests/hydration/compiled/server/streaming.js +9 -9
- package/tests/hydration/compiled/server/switch.js +4 -4
- package/tests/hydration/compiled/server/track-async-serialization.js +16 -16
- package/tests/hydration/compiled/server/try.js +4 -4
- package/tests/hydration/compiled/server/typed-text.js +1 -1
- package/tests/hydration/components/fragment-cursor.tsrx +60 -0
- package/tests/hydration/components/track-async-serialization.tsrx +2 -2
- package/tests/hydration/fragment-cursor.test.js +34 -1
- package/tests/hydration/track-async-serialization.test.js +1 -1
- package/tests/server/basic.components.test.tsrx +3 -3
- package/tests/server/basic.test.tsrx +23 -0
- package/tests/server/track-async-serialization.test.tsrx +6 -6
- package/tests/utils/tracked-types.test.js +3 -3
- package/types/index.d.ts +8 -8
- package/types/server.d.ts +17 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/** @import { Block } from '#client' */
|
|
2
|
+
|
|
3
|
+
import { block, branch, destroy_block, ref } from './blocks.js';
|
|
4
|
+
import { DESTROYED, REF_PROP, RENDER_BLOCK } from './constants.js';
|
|
5
|
+
import { isRefProp as is_ref_prop } from '@tsrx/core/runtime/ref';
|
|
6
|
+
import { is_ripple_object } from './utils.js';
|
|
7
|
+
import {
|
|
8
|
+
get_descriptors,
|
|
9
|
+
get_own_property_symbols,
|
|
10
|
+
get_prototype_of,
|
|
11
|
+
} from '@tsrx/core/runtime/language-helpers';
|
|
12
|
+
import { event_listener } from './events.js';
|
|
13
|
+
import { get_attribute_event_name, is_event_attribute } from '@tsrx/core/runtime/events';
|
|
14
|
+
import { get } from './runtime.js';
|
|
15
|
+
import { normalize_css_property_name } from '@tsrx/core/runtime/html';
|
|
16
|
+
import { set_class_value } from './render.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Dynamic attributes, styles and spreads. Apart from `render.js`, so that an
|
|
20
|
+
* app whose attributes are all static or class/text/value writes never loads
|
|
21
|
+
* the attribute tables these helpers consult.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** @type {Map<string, string[]>} */
|
|
25
|
+
var setters_cache = new Map();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {Element} element
|
|
29
|
+
* @returns {string[]}
|
|
30
|
+
*/
|
|
31
|
+
function get_setters(element) {
|
|
32
|
+
var setters = setters_cache.get(element.nodeName);
|
|
33
|
+
if (setters) return setters;
|
|
34
|
+
setters_cache.set(element.nodeName, (setters = []));
|
|
35
|
+
|
|
36
|
+
var descriptors;
|
|
37
|
+
var proto = element; // In the case of custom elements there might be setters on the instance
|
|
38
|
+
var element_proto = Element.prototype;
|
|
39
|
+
|
|
40
|
+
// Stop at Element, from there on there's only unnecessary setters we're not interested in
|
|
41
|
+
// Do not use constructor.name here as that's unreliable in some browser environments
|
|
42
|
+
while (element_proto !== proto) {
|
|
43
|
+
descriptors = get_descriptors(proto);
|
|
44
|
+
|
|
45
|
+
for (var key in descriptors) {
|
|
46
|
+
if (descriptors[key].set) {
|
|
47
|
+
setters.push(key);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
proto = get_prototype_of(proto);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return setters;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {Element} element
|
|
59
|
+
* @param {any} value
|
|
60
|
+
* @param {Record<string, string | number | null | undefined> | undefined} prev
|
|
61
|
+
* @returns {void}
|
|
62
|
+
*/
|
|
63
|
+
export function set_style(element, value, prev = {}) {
|
|
64
|
+
if (value == null) {
|
|
65
|
+
element.removeAttribute('style');
|
|
66
|
+
} else if (typeof value !== 'string') {
|
|
67
|
+
apply_styles(/** @type {HTMLElement} */ (element), value, prev);
|
|
68
|
+
} else {
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
element.style.cssText = value;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {Element} element
|
|
76
|
+
* @param {string} attribute
|
|
77
|
+
* @param {any} value
|
|
78
|
+
* @returns {void}
|
|
79
|
+
*/
|
|
80
|
+
export function set_attribute(element, attribute, value) {
|
|
81
|
+
if (value == null) {
|
|
82
|
+
element.removeAttribute(attribute);
|
|
83
|
+
} else if (typeof value !== 'string' && get_setters(element).includes(attribute)) {
|
|
84
|
+
/** @type {any} */ (element)[attribute] = value;
|
|
85
|
+
} else {
|
|
86
|
+
element.setAttribute(attribute, value);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @param {HTMLElement} element
|
|
92
|
+
* @param {Record<string, string | number | null | undefined>} new_styles
|
|
93
|
+
* @param {Record<string, string | number | null | undefined>} prev
|
|
94
|
+
*/
|
|
95
|
+
function apply_styles(element, new_styles, prev) {
|
|
96
|
+
const style = element.style;
|
|
97
|
+
|
|
98
|
+
// Apply new styles
|
|
99
|
+
for (const key in new_styles) {
|
|
100
|
+
const css_prop = normalize_css_property_name(key);
|
|
101
|
+
const raw_value = new_styles[key];
|
|
102
|
+
const value = raw_value == null ? null : String(raw_value);
|
|
103
|
+
|
|
104
|
+
if (!(key in prev) || prev[key] !== value) {
|
|
105
|
+
style.setProperty(css_prop, value);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Remove properties that were in prev but not in new_styles
|
|
110
|
+
for (const key in prev) {
|
|
111
|
+
if (!(key in new_styles)) {
|
|
112
|
+
const css_prop = normalize_css_property_name(key);
|
|
113
|
+
style.removeProperty(css_prop);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Helper function to set a single attribute
|
|
120
|
+
* @param {Element} element
|
|
121
|
+
* @param {string} key
|
|
122
|
+
* @param {any} value
|
|
123
|
+
* @param {Record<string, (() => void) | undefined>} remove_listeners
|
|
124
|
+
* @param {Record<string | symbol, any>} prev
|
|
125
|
+
*/
|
|
126
|
+
function set_attribute_helper(element, key, value, remove_listeners, prev) {
|
|
127
|
+
if (key === 'class') {
|
|
128
|
+
const is_html = element.namespaceURI === 'http://www.w3.org/1999/xhtml';
|
|
129
|
+
set_class_value(/** @type {HTMLElement} */ (element), value, undefined, is_html);
|
|
130
|
+
} else if (key === 'innerHTML') {
|
|
131
|
+
element.removeAttribute('innerhtml');
|
|
132
|
+
/** @type {HTMLElement} */ (element).innerHTML = value == null ? '' : String(value);
|
|
133
|
+
} else if (key === 'style') {
|
|
134
|
+
set_style(element, value, prev.style);
|
|
135
|
+
} else if (key === '#class') {
|
|
136
|
+
// Special case for the scope classes of an element that spreads props:
|
|
137
|
+
// one token per scope hash and applied theme.
|
|
138
|
+
element.classList.add(...String(value).split(' ').filter(Boolean));
|
|
139
|
+
} else if (typeof key === 'string' && is_event_attribute(key)) {
|
|
140
|
+
// Handle event handlers in spread props
|
|
141
|
+
if (remove_listeners[key]) {
|
|
142
|
+
remove_listeners[key]();
|
|
143
|
+
remove_listeners[key] = undefined;
|
|
144
|
+
}
|
|
145
|
+
if (value != null) {
|
|
146
|
+
const event_name = get_attribute_event_name(key, value);
|
|
147
|
+
remove_listeners[key] = event_listener(event_name, element, value);
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
set_attribute(element, key, value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {Element} element
|
|
156
|
+
* @param {() => Record<string | symbol, any>} fn
|
|
157
|
+
* @returns {() => void}
|
|
158
|
+
*/
|
|
159
|
+
export function apply_element_spread(element, fn) {
|
|
160
|
+
/** @type {Record<string | symbol, any>} */
|
|
161
|
+
var prev = {};
|
|
162
|
+
/** @type {Record<string | symbol, Block | undefined>} */
|
|
163
|
+
var effects = {};
|
|
164
|
+
/** @type {Record<string | symbol, (() => void) | undefined>} */
|
|
165
|
+
var remove_listeners = {};
|
|
166
|
+
|
|
167
|
+
/** @type {Record<symbol, any>} */
|
|
168
|
+
var prev_symbols = {};
|
|
169
|
+
/** @type {Record<string, any>} */
|
|
170
|
+
var prev_ref_props = {};
|
|
171
|
+
|
|
172
|
+
return () => {
|
|
173
|
+
var next = fn();
|
|
174
|
+
var current_symbols = /** @type {Record<symbol, any>} */ ({});
|
|
175
|
+
|
|
176
|
+
for (const symbol of get_own_property_symbols(next)) {
|
|
177
|
+
if (symbol.description !== REF_PROP) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const ref_fn = next[symbol];
|
|
181
|
+
current_symbols[symbol] = ref_fn;
|
|
182
|
+
|
|
183
|
+
if (
|
|
184
|
+
!(symbol in prev_symbols) ||
|
|
185
|
+
ref_fn !== prev_symbols[symbol] ||
|
|
186
|
+
(effects[symbol] && (effects[symbol].f & DESTROYED) !== 0)
|
|
187
|
+
) {
|
|
188
|
+
if (effects[symbol] && (effects[symbol].f & DESTROYED) === 0) {
|
|
189
|
+
destroy_block(effects[symbol]);
|
|
190
|
+
}
|
|
191
|
+
effects[symbol] = create_spread_ref_effect(element, ref_fn);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
for (const symbol of get_own_property_symbols(prev_symbols)) {
|
|
196
|
+
if (!(symbol in current_symbols) && effects[symbol]) {
|
|
197
|
+
destroy_block(/** @type {Block} */ (effects[symbol]));
|
|
198
|
+
effects[symbol] = undefined;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
prev_symbols = current_symbols;
|
|
203
|
+
|
|
204
|
+
/** @type {Record<string, any>} */
|
|
205
|
+
var current_ref_props = {};
|
|
206
|
+
var keys = spread_keys(next);
|
|
207
|
+
|
|
208
|
+
for (const key of keys) {
|
|
209
|
+
const ref_fn = next[key];
|
|
210
|
+
if (!is_ref_prop(ref_fn)) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
current_ref_props[key] = ref_fn;
|
|
215
|
+
|
|
216
|
+
if (
|
|
217
|
+
!(key in prev_ref_props) ||
|
|
218
|
+
ref_fn !== prev_ref_props[key] ||
|
|
219
|
+
(effects[key] && (effects[key].f & DESTROYED) !== 0)
|
|
220
|
+
) {
|
|
221
|
+
if (effects[key] && (effects[key].f & DESTROYED) === 0) {
|
|
222
|
+
destroy_block(effects[key]);
|
|
223
|
+
}
|
|
224
|
+
effects[key] = create_spread_ref_effect(element, ref_fn);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
for (const key in prev_ref_props) {
|
|
229
|
+
if (!(key in current_ref_props) && effects[key]) {
|
|
230
|
+
destroy_block(/** @type {Block} */ (effects[key]));
|
|
231
|
+
effects[key] = undefined;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
prev_ref_props = current_ref_props;
|
|
236
|
+
|
|
237
|
+
for (let key in remove_listeners) {
|
|
238
|
+
// Remove event listeners that are no longer present
|
|
239
|
+
if ((!keys.includes(key) || is_ref_prop(next[key])) && remove_listeners[key]) {
|
|
240
|
+
remove_listeners[key]();
|
|
241
|
+
remove_listeners[key] = undefined;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
for (const key in prev) {
|
|
246
|
+
if (!keys.includes(key) || is_ref_prop(next[key])) {
|
|
247
|
+
if (key === '#class') {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
set_attribute_helper(element, key, null, remove_listeners, prev);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** @type {typeof prev} */
|
|
255
|
+
const current = {};
|
|
256
|
+
for (const key of keys) {
|
|
257
|
+
if (key === 'children') continue;
|
|
258
|
+
|
|
259
|
+
let value = next[key];
|
|
260
|
+
if (is_ref_prop(value)) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
if (is_ripple_object(value)) {
|
|
264
|
+
value = get(value);
|
|
265
|
+
}
|
|
266
|
+
current[key] = value;
|
|
267
|
+
|
|
268
|
+
if (key in prev && prev[key] === value && key !== '#class') {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
set_attribute_helper(element, key, value, remove_listeners, prev);
|
|
273
|
+
}
|
|
274
|
+
prev = current;
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* The keys an element spread applies: every prop of a props instance, or the
|
|
280
|
+
* enumerable keys of a plain object.
|
|
281
|
+
* @param {Record<string | symbol, any>} next
|
|
282
|
+
* @returns {string[]}
|
|
283
|
+
*/
|
|
284
|
+
function spread_keys(next) {
|
|
285
|
+
/** @type {string[]} */
|
|
286
|
+
var keys = [];
|
|
287
|
+
for (var key in next) keys.push(key);
|
|
288
|
+
return keys;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Keep spread refs in a branch block so ordinary spread updates do not destroy
|
|
293
|
+
* and recreate the ref block before `apply_element_spread` can compare the
|
|
294
|
+
* previous and current ref values.
|
|
295
|
+
*
|
|
296
|
+
* @param {Element} element
|
|
297
|
+
* @param {any} ref_fn
|
|
298
|
+
* @returns {Block}
|
|
299
|
+
*/
|
|
300
|
+
function create_spread_ref_effect(element, ref_fn) {
|
|
301
|
+
return branch(() => {
|
|
302
|
+
ref(element, () => ref_fn);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* A render block that applies a spread of attributes to an element.
|
|
307
|
+
* @param {any} element
|
|
308
|
+
* @param {any} fn
|
|
309
|
+
* @param {number} [flags]
|
|
310
|
+
*/
|
|
311
|
+
export function render_spread(element, fn, flags = 0) {
|
|
312
|
+
return block(RENDER_BLOCK | flags, apply_element_spread(element, fn));
|
|
313
|
+
}
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
} from './constants.js';
|
|
19
19
|
import { hydrating } from './hydration.js';
|
|
20
20
|
import { next_sibling } from './operations.js';
|
|
21
|
-
import { apply_element_spread } from './render.js';
|
|
22
21
|
import { is_array } from '@tsrx/core/runtime/language-helpers';
|
|
23
22
|
import {
|
|
24
23
|
active_block,
|
|
@@ -34,15 +33,15 @@ import {
|
|
|
34
33
|
untrack,
|
|
35
34
|
} from './runtime.js';
|
|
36
35
|
import { is_ripple_object } from './utils.js';
|
|
36
|
+
import { effect_orphan } from './errors.js';
|
|
37
|
+
import { HYDRATION } from 'ripple/internal/client/hydration-enabled';
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* @param {Function} fn
|
|
40
41
|
*/
|
|
41
42
|
export function user_effect(fn) {
|
|
42
43
|
if (active_block === null) {
|
|
43
|
-
|
|
44
|
-
'effect() must be called within an active context, such as a component or effect',
|
|
45
|
-
);
|
|
44
|
+
effect_orphan();
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
var component = active_component;
|
|
@@ -85,15 +84,6 @@ export function render(fn, state, flags = 0) {
|
|
|
85
84
|
return block;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
/**
|
|
89
|
-
* @param {any} element
|
|
90
|
-
* @param {any} fn
|
|
91
|
-
* @param {number} [flags]
|
|
92
|
-
*/
|
|
93
|
-
export function render_spread(element, fn, flags = 0) {
|
|
94
|
-
return block(RENDER_BLOCK | flags, apply_element_spread(element, fn));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
87
|
/**
|
|
98
88
|
* @param {Function} fn
|
|
99
89
|
* @param {number} [flags]
|
|
@@ -117,7 +107,7 @@ function noop() {}
|
|
|
117
107
|
* @param {Node} anchor
|
|
118
108
|
*/
|
|
119
109
|
export function own_anchor(node, anchor) {
|
|
120
|
-
if (anchor === node || hydrating) return;
|
|
110
|
+
if (anchor === node || (HYDRATION && hydrating)) return;
|
|
121
111
|
branch(noop, 0, { start: anchor, end: anchor });
|
|
122
112
|
}
|
|
123
113
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { is_tsrx_element } from '../../element.js';
|
|
4
4
|
import { render_value } from './expression.js';
|
|
5
5
|
import { active_block } from './runtime.js';
|
|
6
|
+
import { component_invalid } from './errors.js';
|
|
6
7
|
|
|
7
8
|
export { render_component } from './runtime.js';
|
|
8
9
|
|
|
@@ -21,9 +22,5 @@ export function render_tsrx_element(value, anchor, block = active_block) {
|
|
|
21
22
|
* @returns {never}
|
|
22
23
|
*/
|
|
23
24
|
export function throw_invalid_component_type(value) {
|
|
24
|
-
|
|
25
|
-
throw new TypeError('Invalid component type: received a TSRXElement value.');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
throw new TypeError('Invalid component type: expected a component function.');
|
|
25
|
+
component_invalid(is_tsrx_element(value));
|
|
29
26
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/** @import { Block } from '#client' */
|
|
2
|
+
import { component_invalid } from './errors.js';
|
|
2
3
|
|
|
3
|
-
import { branch, destroy_block, render
|
|
4
|
+
import { branch, destroy_block, render } from './blocks.js';
|
|
5
|
+
import { render_spread } from './attributes.js';
|
|
4
6
|
import { COMPOSITE_BLOCK, DEFAULT_NAMESPACE, NAMESPACE_URI } from './constants.js';
|
|
5
7
|
import { hydrate_node, hydrate_next, hydrating, set_hydrate_node } from './hydration.js';
|
|
6
8
|
import { first_child } from './operations.js';
|
|
7
9
|
import { active_block, active_namespace, get, untrack, with_ns } from './runtime.js';
|
|
8
10
|
import { top_element_to_ns } from './utils.js';
|
|
11
|
+
import { install_ns_templates } from './template-ns.js';
|
|
9
12
|
import { is_tsrx_element } from '../../element.js';
|
|
10
13
|
import { render_component } from './component.js';
|
|
14
|
+
import { HYDRATION } from 'ripple/internal/client/hydration-enabled';
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* @typedef {Function | string | null | undefined | false} CompositeTarget
|
|
@@ -19,7 +23,7 @@ import { render_component } from './component.js';
|
|
|
19
23
|
* @returns {void}
|
|
20
24
|
*/
|
|
21
25
|
export function composite(get_component, node, get_props) {
|
|
22
|
-
if (hydrating) {
|
|
26
|
+
if (HYDRATION && hydrating) {
|
|
23
27
|
// During hydration, `node` may already point at the first real SSR node
|
|
24
28
|
// (e.g. layout children). Only skip forward when we are on an empty
|
|
25
29
|
// comment anchor from a client template placeholder.
|
|
@@ -49,16 +53,20 @@ export function composite(get_component, node, get_props) {
|
|
|
49
53
|
render_component(component, anchor, props);
|
|
50
54
|
});
|
|
51
55
|
} else if (is_tsrx_element(component)) {
|
|
52
|
-
|
|
56
|
+
component_invalid(true);
|
|
53
57
|
} else if (component != null) {
|
|
54
58
|
// Custom element - only create if component is not null/undefined
|
|
55
59
|
const ns = top_element_to_ns(component, active_namespace);
|
|
60
|
+
if (ns !== DEFAULT_NAMESPACE) {
|
|
61
|
+
// Templates cloned inside the element parse in its namespace.
|
|
62
|
+
install_ns_templates();
|
|
63
|
+
}
|
|
56
64
|
var run = () => {
|
|
57
65
|
var block = /** @type {Block} */ (active_block);
|
|
58
66
|
|
|
59
67
|
/** @type {Element} */
|
|
60
68
|
var element;
|
|
61
|
-
if (hydrating) {
|
|
69
|
+
if (HYDRATION && hydrating) {
|
|
62
70
|
// Claim the SSR-rendered element instead of creating a new one.
|
|
63
71
|
element = /** @type {Element} */ (hydrate_node);
|
|
64
72
|
} else {
|
|
@@ -86,7 +94,7 @@ export function composite(get_component, node, get_props) {
|
|
|
86
94
|
if (is_tsrx_element(props.children)) {
|
|
87
95
|
/** @type {Node} */
|
|
88
96
|
var child_anchor;
|
|
89
|
-
if (hydrating) {
|
|
97
|
+
if (HYDRATION && hydrating) {
|
|
90
98
|
// The server renders children directly inside the element with no
|
|
91
99
|
// extra markers; descend the cursor so they claim those nodes.
|
|
92
100
|
child_anchor = /** @type {Node} */ (first_child(element));
|
|
@@ -101,7 +109,7 @@ export function composite(get_component, node, get_props) {
|
|
|
101
109
|
props.children.render(child_anchor, block, props.children.p);
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
if (hydrating) {
|
|
112
|
+
if (HYDRATION && hydrating) {
|
|
105
113
|
// Reset the cursor to the claimed element so sibling traversal
|
|
106
114
|
// continues after it.
|
|
107
115
|
set_hydrate_node(element);
|
|
@@ -29,11 +29,17 @@ export var SELECTOR = 1 << 23;
|
|
|
29
29
|
export var RELEASED = 1 << 24;
|
|
30
30
|
/** A block whose latest run created deriveds that are recorded for release (see `release_deriveds`). */
|
|
31
31
|
export var CREATES_DERIVEDS = 1 << 25;
|
|
32
|
+
/**
|
|
33
|
+
* A list item block that carries its body's render block itself (see the
|
|
34
|
+
* runtime's `item`): a branch block for its DOM range, and a reaction that
|
|
35
|
+
* re-runs the body's update function.
|
|
36
|
+
*/
|
|
37
|
+
export var ITEM_BLOCK = 1 << 26;
|
|
32
38
|
|
|
33
39
|
export var CONTROL_FLOW_BLOCK = FOR_BLOCK | IF_BLOCK | SWITCH_BLOCK | TRY_BLOCK | COMPOSITE_BLOCK;
|
|
34
40
|
|
|
35
41
|
/** @type {unique symbol} */
|
|
36
|
-
export const UNINITIALIZED = Symbol(
|
|
42
|
+
export const UNINITIALIZED = Symbol();
|
|
37
43
|
/** @type {unique symbol} */
|
|
38
44
|
export const TRACKED_ARRAY = Symbol();
|
|
39
45
|
/** @type {unique symbol} */
|
|
@@ -52,13 +58,13 @@ export const NAMESPACE_URI = {
|
|
|
52
58
|
mathml: 'http://www.w3.org/1998/Math/MathML',
|
|
53
59
|
};
|
|
54
60
|
/** @type {unique symbol} */
|
|
55
|
-
export const TRACKED_UPDATED = Symbol(
|
|
61
|
+
export const TRACKED_UPDATED = Symbol();
|
|
56
62
|
/** @type {unique symbol} */
|
|
57
|
-
export const SUSPENSE_PENDING = Symbol(
|
|
63
|
+
export const SUSPENSE_PENDING = Symbol();
|
|
58
64
|
/** @type {unique symbol} */
|
|
59
|
-
export const SUSPENSE_REJECTED = Symbol(
|
|
65
|
+
export const SUSPENSE_REJECTED = Symbol();
|
|
60
66
|
/** @type {unique symbol} */
|
|
61
|
-
export const ASYNC_DERIVED_READ_THROWN = Symbol(
|
|
67
|
+
export const ASYNC_DERIVED_READ_THROWN = Symbol();
|
|
62
68
|
|
|
63
69
|
/** The hoisted render function a module-level component carries (see `render_component`). */
|
|
64
|
-
export const RENDER_ENTRY = Symbol(
|
|
70
|
+
export const RENDER_ENTRY = Symbol();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** @import { Component, ContextEntry } from '#client' */
|
|
2
|
+
import { context_orphan } from './errors.js';
|
|
2
3
|
|
|
3
4
|
import { active_component } from './runtime.js';
|
|
4
5
|
|
|
@@ -18,7 +19,7 @@ export class Context {
|
|
|
18
19
|
const component = active_component;
|
|
19
20
|
|
|
20
21
|
if (component === null) {
|
|
21
|
-
|
|
22
|
+
context_orphan(false);
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
// A component inherits its parent's chain of set entries when it is
|
|
@@ -45,7 +46,7 @@ export class Context {
|
|
|
45
46
|
const component = active_component;
|
|
46
47
|
|
|
47
48
|
if (component === null) {
|
|
48
|
-
|
|
49
|
+
context_orphan(true);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
component.c = { k: this, v: value, n: component.c };
|
|
@@ -24,49 +24,34 @@ function remove() {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Calls back once every stylesheet link has loaded (or failed).
|
|
28
|
+
* @param {() => void} callback
|
|
28
29
|
* @returns {void}
|
|
29
30
|
*/
|
|
30
31
|
function remove_when_css_loaded(callback) {
|
|
31
|
-
/** @type {HTMLLinkElement
|
|
32
|
-
|
|
33
|
-
/** @type {NodeListOf<HTMLLinkElement>} */ (
|
|
34
|
-
document.querySelectorAll('link[rel="stylesheet"]')
|
|
35
|
-
),
|
|
32
|
+
var links = /** @type {NodeListOf<HTMLLinkElement>} */ (
|
|
33
|
+
document.querySelectorAll('link[rel="stylesheet"]')
|
|
36
34
|
);
|
|
37
|
-
|
|
35
|
+
var remaining = links.length;
|
|
38
36
|
|
|
39
37
|
if (remaining === 0) {
|
|
40
38
|
callback();
|
|
41
39
|
return;
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
remaining
|
|
46
|
-
if (remaining === 0) {
|
|
47
|
-
// clean up all listeners
|
|
48
|
-
links.forEach((link) => {
|
|
49
|
-
link.removeEventListener('load', onLoad);
|
|
50
|
-
link.removeEventListener('error', onError);
|
|
51
|
-
});
|
|
42
|
+
var done = () => {
|
|
43
|
+
if (--remaining === 0) {
|
|
52
44
|
callback();
|
|
53
45
|
}
|
|
54
46
|
};
|
|
55
47
|
|
|
56
|
-
|
|
57
|
-
done();
|
|
58
|
-
}
|
|
59
|
-
function onError() {
|
|
60
|
-
done();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
links.forEach((link) => {
|
|
48
|
+
for (var link of links) {
|
|
64
49
|
if (link.sheet) {
|
|
65
50
|
// already loaded (possibly cached)
|
|
66
51
|
done();
|
|
67
52
|
} else {
|
|
68
|
-
link.addEventListener('load',
|
|
69
|
-
link.addEventListener('error',
|
|
53
|
+
link.addEventListener('load', done, { once: true });
|
|
54
|
+
link.addEventListener('error', done, { once: true });
|
|
70
55
|
}
|
|
71
|
-
}
|
|
56
|
+
}
|
|
72
57
|
}
|