ripple 0.3.7 → 0.3.9
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 +14 -0
- package/package.json +2 -2
- package/src/compiler/phases/1-parse/index.js +48 -349
- package/src/compiler/phases/2-analyze/index.js +343 -52
- package/src/compiler/phases/3-transform/client/index.js +28 -160
- package/src/compiler/phases/3-transform/segments.js +0 -7
- package/src/compiler/phases/3-transform/server/index.js +31 -154
- package/src/compiler/types/acorn.d.ts +1 -1
- package/src/compiler/types/estree.d.ts +1 -1
- package/src/compiler/types/import.d.ts +0 -2
- package/src/compiler/types/index.d.ts +5 -17
- package/src/compiler/types/parse.d.ts +1 -17
- package/src/compiler/utils.js +53 -20
- package/src/runtime/index-client.js +2 -13
- package/src/runtime/index-server.js +2 -2
- package/src/runtime/internal/client/bindings.js +3 -1
- package/src/runtime/internal/client/composite.js +3 -2
- package/src/runtime/internal/client/events.js +1 -1
- package/src/runtime/internal/client/head.js +3 -4
- package/src/runtime/internal/client/index.js +0 -1
- package/src/runtime/internal/client/runtime.js +0 -52
- package/src/runtime/internal/server/index.js +31 -55
- package/tests/client/array/array.copy-within.test.ripple +12 -12
- package/tests/client/array/array.derived.test.ripple +46 -46
- package/tests/client/array/array.iteration.test.ripple +10 -10
- package/tests/client/array/array.mutations.test.ripple +20 -20
- package/tests/client/array/array.to-methods.test.ripple +6 -6
- package/tests/client/async-suspend.test.ripple +5 -5
- package/tests/client/basic/basic.attributes.test.ripple +81 -81
- package/tests/client/basic/basic.collections.test.ripple +9 -9
- package/tests/client/basic/basic.components.test.ripple +28 -28
- package/tests/client/basic/basic.errors.test.ripple +46 -18
- package/tests/client/basic/basic.events.test.ripple +37 -37
- package/tests/client/basic/basic.get-set.test.ripple +6 -6
- package/tests/client/basic/basic.reactivity.test.ripple +58 -203
- package/tests/client/basic/basic.rendering.test.ripple +19 -19
- package/tests/client/basic/basic.utilities.test.ripple +3 -3
- package/tests/client/boundaries.test.ripple +12 -12
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
- package/tests/client/compiler/compiler.basic.test.ripple +46 -27
- package/tests/client/compiler/compiler.tracked-access.test.ripple +2 -2
- package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
- package/tests/client/composite/composite.props.test.ripple +14 -16
- package/tests/client/composite/composite.reactivity.test.ripple +69 -70
- package/tests/client/composite/composite.render.test.ripple +3 -3
- package/tests/client/computed-properties.test.ripple +4 -4
- package/tests/client/date.test.ripple +42 -42
- package/tests/client/dynamic-elements.test.ripple +44 -45
- package/tests/client/events.test.ripple +70 -70
- package/tests/client/for.test.ripple +25 -25
- package/tests/client/head.test.ripple +19 -19
- package/tests/client/html.test.ripple +3 -3
- package/tests/client/input-value.test.ripple +84 -84
- package/tests/client/lazy-destructuring.test.ripple +138 -26
- package/tests/client/map.test.ripple +16 -16
- package/tests/client/media-query.test.ripple +7 -7
- package/tests/client/portal.test.ripple +11 -11
- package/tests/client/ref.test.ripple +4 -4
- package/tests/client/return.test.ripple +52 -52
- package/tests/client/set.test.ripple +6 -6
- package/tests/client/svg.test.ripple +5 -5
- package/tests/client/switch.test.ripple +44 -44
- package/tests/client/try.test.ripple +5 -5
- package/tests/client/url/url.derived.test.ripple +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
- package/tests/hydration/compiled/client/events.js +25 -25
- package/tests/hydration/compiled/client/for.js +70 -66
- package/tests/hydration/compiled/client/head.js +25 -25
- package/tests/hydration/compiled/client/hmr.js +2 -2
- package/tests/hydration/compiled/client/html.js +3 -3
- package/tests/hydration/compiled/client/if-children.js +24 -24
- package/tests/hydration/compiled/client/if.js +18 -18
- package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
- package/tests/hydration/compiled/client/portal.js +3 -3
- package/tests/hydration/compiled/client/reactivity.js +16 -16
- package/tests/hydration/compiled/client/return.js +40 -40
- package/tests/hydration/compiled/client/switch.js +12 -12
- package/tests/hydration/compiled/server/events.js +19 -19
- package/tests/hydration/compiled/server/for.js +41 -41
- package/tests/hydration/compiled/server/head.js +26 -26
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +2 -2
- package/tests/hydration/compiled/server/if-children.js +16 -16
- package/tests/hydration/compiled/server/if.js +11 -11
- package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
- package/tests/hydration/compiled/server/portal.js +2 -2
- package/tests/hydration/compiled/server/reactivity.js +16 -16
- package/tests/hydration/compiled/server/return.js +25 -25
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/components/events.ripple +25 -25
- package/tests/hydration/components/for.ripple +66 -66
- package/tests/hydration/components/head.ripple +16 -16
- package/tests/hydration/components/hmr.ripple +2 -2
- package/tests/hydration/components/html.ripple +3 -3
- package/tests/hydration/components/if-children.ripple +24 -24
- package/tests/hydration/components/if.ripple +18 -18
- package/tests/hydration/components/mixed-control-flow.ripple +9 -9
- package/tests/hydration/components/portal.ripple +3 -3
- package/tests/hydration/components/reactivity.ripple +16 -16
- package/tests/hydration/components/return.ripple +40 -40
- package/tests/hydration/components/switch.ripple +20 -20
- package/tests/server/await.test.ripple +3 -3
- package/tests/server/basic.attributes.test.ripple +34 -34
- package/tests/server/basic.components.test.ripple +10 -10
- package/tests/server/basic.test.ripple +38 -40
- package/tests/server/compiler.test.ripple +22 -0
- package/tests/server/composite.props.test.ripple +12 -14
- package/tests/server/dynamic-elements.test.ripple +15 -15
- package/tests/server/head.test.ripple +11 -11
- package/tests/server/lazy-destructuring.test.ripple +92 -13
- package/tsconfig.typecheck.json +4 -0
- package/types/index.d.ts +0 -19
- package/tests/client/__snapshots__/tracked-expression.test.ripple.snap +0 -34
- package/tests/client/tracked-expression.test.ripple +0 -26
package/src/compiler/utils.js
CHANGED
|
@@ -292,25 +292,25 @@ export function is_component_level_function(context) {
|
|
|
292
292
|
* Returns the matched Ripple tracking call name
|
|
293
293
|
* @param {AST.Expression | AST.Super} callee
|
|
294
294
|
* @param {CommonContext} context
|
|
295
|
-
* @returns {'track' |
|
|
295
|
+
* @returns {'track' | null}
|
|
296
296
|
*/
|
|
297
297
|
export function is_ripple_track_call(callee, context) {
|
|
298
298
|
// Super expressions cannot be Ripple track calls
|
|
299
299
|
if (callee.type === 'Super') return null;
|
|
300
300
|
|
|
301
|
-
if (callee.type === 'Identifier' &&
|
|
302
|
-
return is_ripple_import(callee, context) ?
|
|
301
|
+
if (callee.type === 'Identifier' && callee.name === 'track') {
|
|
302
|
+
return is_ripple_import(callee, context) ? 'track' : null;
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
if (
|
|
306
306
|
callee.type === 'MemberExpression' &&
|
|
307
307
|
callee.object.type === 'Identifier' &&
|
|
308
308
|
callee.property.type === 'Identifier' &&
|
|
309
|
-
|
|
309
|
+
callee.property.name === 'track' &&
|
|
310
310
|
!callee.computed &&
|
|
311
311
|
is_ripple_import(callee, context)
|
|
312
312
|
) {
|
|
313
|
-
return
|
|
313
|
+
return 'track';
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
return null;
|
|
@@ -606,21 +606,8 @@ export function is_element_dynamic(node) {
|
|
|
606
606
|
* @returns {boolean}
|
|
607
607
|
*/
|
|
608
608
|
function is_id_dynamic(node) {
|
|
609
|
-
if (node.type === 'Identifier'
|
|
610
|
-
|
|
611
|
-
return true;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
return false;
|
|
615
|
-
} else if (node.type === 'MemberExpression') {
|
|
616
|
-
if (/** @type {AST.Identifier} */ (node.object).tracked === true) {
|
|
617
|
-
return true;
|
|
618
|
-
}
|
|
619
|
-
if (node.property.type === 'MemberExpression') {
|
|
620
|
-
return is_id_dynamic(node.property);
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
return !!(/** @type {AST.Identifier} */ (node.property).tracked);
|
|
609
|
+
if (node.type === 'Identifier') {
|
|
610
|
+
return !!node.tracked;
|
|
624
611
|
}
|
|
625
612
|
|
|
626
613
|
return false;
|
|
@@ -686,6 +673,52 @@ function normalize_child(node, normalized, context) {
|
|
|
686
673
|
}
|
|
687
674
|
}
|
|
688
675
|
|
|
676
|
+
/**
|
|
677
|
+
* Replaces any lazy subpatterns in a parameter pattern with their generated identifiers.
|
|
678
|
+
* This is used by client and server transforms so nested lazy destructuring can coexist
|
|
679
|
+
* with otherwise normal object/array params.
|
|
680
|
+
* @param {AST.Pattern} pattern
|
|
681
|
+
* @returns {AST.Pattern}
|
|
682
|
+
*/
|
|
683
|
+
export function replace_lazy_param_pattern(pattern) {
|
|
684
|
+
switch (pattern.type) {
|
|
685
|
+
case 'AssignmentPattern':
|
|
686
|
+
return { ...pattern, left: replace_lazy_param_pattern(pattern.left) };
|
|
687
|
+
|
|
688
|
+
case 'ObjectPattern':
|
|
689
|
+
if (pattern.lazy && pattern.metadata?.lazy_id) {
|
|
690
|
+
return /** @type {AST.Pattern} */ (b.id(pattern.metadata.lazy_id));
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
return {
|
|
694
|
+
...pattern,
|
|
695
|
+
properties: pattern.properties.map((property) =>
|
|
696
|
+
property.type === 'RestElement'
|
|
697
|
+
? { ...property, argument: replace_lazy_param_pattern(property.argument) }
|
|
698
|
+
: { ...property, value: replace_lazy_param_pattern(property.value) },
|
|
699
|
+
),
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
case 'ArrayPattern':
|
|
703
|
+
if (pattern.lazy && pattern.metadata?.lazy_id) {
|
|
704
|
+
return /** @type {AST.Pattern} */ (b.id(pattern.metadata.lazy_id));
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
return {
|
|
708
|
+
...pattern,
|
|
709
|
+
elements: pattern.elements.map((element) =>
|
|
710
|
+
element === null ? null : replace_lazy_param_pattern(element),
|
|
711
|
+
),
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
case 'RestElement':
|
|
715
|
+
return { ...pattern, argument: replace_lazy_param_pattern(pattern.argument) };
|
|
716
|
+
|
|
717
|
+
default:
|
|
718
|
+
return pattern;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
689
722
|
/**
|
|
690
723
|
* @param {CommonContext} context
|
|
691
724
|
*/
|
|
@@ -102,13 +102,7 @@ export function hydrate(component, options) {
|
|
|
102
102
|
|
|
103
103
|
export { Context } from './internal/client/context.js';
|
|
104
104
|
|
|
105
|
-
export {
|
|
106
|
-
flush_sync as flushSync,
|
|
107
|
-
track,
|
|
108
|
-
track_split as trackSplit,
|
|
109
|
-
untrack,
|
|
110
|
-
tick,
|
|
111
|
-
} from './internal/client/runtime.js';
|
|
105
|
+
export { flush_sync as flushSync, track, untrack, tick } from './internal/client/runtime.js';
|
|
112
106
|
|
|
113
107
|
export { RippleArray } from './array.js';
|
|
114
108
|
|
|
@@ -165,10 +159,5 @@ import { RippleURL } from './url.js';
|
|
|
165
159
|
import { RippleURLSearchParams } from './url-search-params.js';
|
|
166
160
|
import { RippleDate } from './date.js';
|
|
167
161
|
import { MediaQuery } from './media-query.js';
|
|
168
|
-
import {
|
|
169
|
-
track,
|
|
170
|
-
track_split as trackSplit,
|
|
171
|
-
untrack,
|
|
172
|
-
ref_prop as createRefKey,
|
|
173
|
-
} from './internal/client/runtime.js';
|
|
162
|
+
import { track, untrack, ref_prop as createRefKey } from './internal/client/runtime.js';
|
|
174
163
|
import { user_effect as effect } from './internal/client/blocks.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { get, set, untrack, track
|
|
1
|
+
import { get, set, untrack, track } from './internal/server/index.js';
|
|
2
2
|
|
|
3
3
|
export { Context } from './internal/server/context.js';
|
|
4
4
|
|
|
5
|
-
export { get, set, untrack, track
|
|
5
|
+
export { get, set, untrack, track };
|
|
6
6
|
|
|
7
7
|
function noop() {}
|
|
8
8
|
|
|
@@ -186,7 +186,9 @@ function select_option(select, value, mounting = false) {
|
|
|
186
186
|
|
|
187
187
|
// Otherwise, update the selection
|
|
188
188
|
for (var option of select.options) {
|
|
189
|
-
option.selected = /** @type {string[]} */ (value).includes(
|
|
189
|
+
option.selected = /** @type {string[]} */ (value).includes(
|
|
190
|
+
/** @type {string} */ (get_option_value(option)),
|
|
191
|
+
);
|
|
190
192
|
}
|
|
191
193
|
|
|
192
194
|
return;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { branch, destroy_block, render, render_spread } from './blocks.js';
|
|
4
4
|
import { COMPOSITE_BLOCK, DEFAULT_NAMESPACE, NAMESPACE_URI } from './constants.js';
|
|
5
5
|
import { hydrate_next, hydrating } from './hydration.js';
|
|
6
|
-
import { active_block, active_namespace, with_ns } from './runtime.js';
|
|
6
|
+
import { active_block, active_namespace, get, with_ns } from './runtime.js';
|
|
7
7
|
import { top_element_to_ns } from './utils.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -29,7 +29,8 @@ export function composite(get_component, node, props) {
|
|
|
29
29
|
|
|
30
30
|
render(
|
|
31
31
|
() => {
|
|
32
|
-
|
|
32
|
+
// @ts-ignore — get() handles non-tracked values via is_ripple_object() check
|
|
33
|
+
var component = get(get_component());
|
|
33
34
|
|
|
34
35
|
if (b !== null) {
|
|
35
36
|
destroy_block(b);
|
|
@@ -168,7 +168,7 @@ export function handle_event_propagation(event) {
|
|
|
168
168
|
null;
|
|
169
169
|
|
|
170
170
|
try {
|
|
171
|
-
var delegated = current_target['__' + event_name];
|
|
171
|
+
var delegated = /** @type {Record<string, any>} */ (current_target)['__' + event_name];
|
|
172
172
|
|
|
173
173
|
if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
|
|
174
174
|
if (is_array(delegated)) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** @import { TemplateNode } from '#client' */
|
|
2
1
|
import { render } from './blocks.js';
|
|
3
2
|
import { HEAD_BLOCK } from './constants.js';
|
|
4
3
|
import { COMMENT_NODE } from '../../../constants.js';
|
|
@@ -38,8 +37,8 @@ export function head(hash, render_fn) {
|
|
|
38
37
|
if (head_anchor === null) {
|
|
39
38
|
set_hydrating(false);
|
|
40
39
|
} else {
|
|
41
|
-
var start =
|
|
42
|
-
head_anchor.remove(); // in case this component is repeated
|
|
40
|
+
var start = get_next_sibling(head_anchor);
|
|
41
|
+
/** @type {ChildNode} */ (head_anchor).remove(); // in case this component is repeated
|
|
43
42
|
|
|
44
43
|
set_hydrate_node(start);
|
|
45
44
|
}
|
|
@@ -54,7 +53,7 @@ export function head(hash, render_fn) {
|
|
|
54
53
|
} finally {
|
|
55
54
|
if (was_hydrating) {
|
|
56
55
|
set_hydrating(true);
|
|
57
|
-
set_hydrate_node(
|
|
56
|
+
set_hydrate_node(previous_hydrate_node);
|
|
58
57
|
}
|
|
59
58
|
}
|
|
60
59
|
}
|
|
@@ -426,58 +426,6 @@ export function track(v, get, set, b) {
|
|
|
426
426
|
return tracked(v, b, get, set);
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
/**
|
|
430
|
-
* @param {Record<string|symbol, any>} v
|
|
431
|
-
* @param {(symbol | string)[]} l
|
|
432
|
-
* @param {Block} b
|
|
433
|
-
* @returns {Tracked[]}
|
|
434
|
-
*/
|
|
435
|
-
export function track_split(v, l, b) {
|
|
436
|
-
var is_tracked = is_ripple_object(v);
|
|
437
|
-
|
|
438
|
-
if (is_tracked || typeof v !== 'object' || v === null || is_array(v)) {
|
|
439
|
-
throw new TypeError('Invalid value: expected a non-tracked object');
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/** @type {Tracked[]} */
|
|
443
|
-
var out = [];
|
|
444
|
-
/** @type {Record<string|symbol, any>} */
|
|
445
|
-
var rest = {};
|
|
446
|
-
/** @type {Record<PropertyKey, 1>} */
|
|
447
|
-
var done = {};
|
|
448
|
-
var props = Reflect.ownKeys(v);
|
|
449
|
-
|
|
450
|
-
for (let i = 0, key, t; i < l.length; i++) {
|
|
451
|
-
key = l[i];
|
|
452
|
-
|
|
453
|
-
if (props.includes(key)) {
|
|
454
|
-
if (is_ripple_object(v[key])) {
|
|
455
|
-
t = v[key];
|
|
456
|
-
} else {
|
|
457
|
-
t = tracked(undefined, b);
|
|
458
|
-
t = define_property(t, '__v', /** @type {PropertyDescriptor} */ (get_descriptor(v, key)));
|
|
459
|
-
}
|
|
460
|
-
} else {
|
|
461
|
-
t = tracked(undefined, b);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
out[i] = t;
|
|
465
|
-
done[key] = 1;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
for (let i = 0, key; i < props.length; i++) {
|
|
469
|
-
key = props[i];
|
|
470
|
-
if (done[key]) {
|
|
471
|
-
continue;
|
|
472
|
-
}
|
|
473
|
-
define_property(rest, key, /** @type {PropertyDescriptor} */ (get_descriptor(v, key)));
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
out.push(tracked(rest, b));
|
|
477
|
-
|
|
478
|
-
return out;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
429
|
/**
|
|
482
430
|
* @param {Tracked | Derived} tracked
|
|
483
431
|
* @returns {Dependency}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@import { Component, Dependency, Derived, Tracked } from '#server';
|
|
3
|
-
@import { SSRComponent
|
|
3
|
+
@import { SSRComponent } from 'ripple/server';
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Readable } from 'stream';
|
|
@@ -231,12 +231,12 @@ class Output {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
/** @type {render} */
|
|
234
|
+
/** @type {import('ripple/server').render} */
|
|
235
235
|
export async function render(component) {
|
|
236
236
|
const output = new Output(null, null);
|
|
237
237
|
let head = '';
|
|
238
238
|
let body = '';
|
|
239
|
-
let css = new Set();
|
|
239
|
+
let css = /** @type {Set<string>} */ (new Set());
|
|
240
240
|
|
|
241
241
|
// Reset dev-mode element tracking state at the start of each render
|
|
242
242
|
reset_element_state();
|
|
@@ -262,7 +262,7 @@ export async function render(component) {
|
|
|
262
262
|
return { head, body, css };
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
/** @type {renderToStream} */
|
|
265
|
+
/** @type {import('ripple/server').renderToStream} */
|
|
266
266
|
export function renderToStream(component) {
|
|
267
267
|
const stream = new Readable({
|
|
268
268
|
read() {},
|
|
@@ -702,6 +702,24 @@ function tracked(v, get, set) {
|
|
|
702
702
|
return /** @type {Tracked} */ (new TrackedValue(v, get || set ? { get, set } : empty_get_set));
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
+
/**
|
|
706
|
+
* @param {Record<string, unknown>} obj
|
|
707
|
+
* @param {string[]} exclude_keys
|
|
708
|
+
* @returns {Record<string, unknown>}
|
|
709
|
+
*/
|
|
710
|
+
export function exclude_from_object(obj, exclude_keys) {
|
|
711
|
+
/** @type {Record<string, unknown>} */
|
|
712
|
+
var new_obj = {};
|
|
713
|
+
|
|
714
|
+
for (const key of Object.keys(obj)) {
|
|
715
|
+
if (!exclude_keys.includes(key)) {
|
|
716
|
+
new_obj[key] = obj[key];
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return new_obj;
|
|
721
|
+
}
|
|
722
|
+
|
|
705
723
|
/**
|
|
706
724
|
* @param {any} v
|
|
707
725
|
* @param {(value: any) => any} [get]
|
|
@@ -722,57 +740,6 @@ export function track(v, get, set) {
|
|
|
722
740
|
return tracked(v, get, set);
|
|
723
741
|
}
|
|
724
742
|
|
|
725
|
-
/**
|
|
726
|
-
* @param {Record<string|symbol, any>} v
|
|
727
|
-
* @param {(symbol | string)[]} l
|
|
728
|
-
* @returns {Tracked[]}
|
|
729
|
-
*/
|
|
730
|
-
export function track_split(v, l) {
|
|
731
|
-
var is_tracked = is_ripple_object(v);
|
|
732
|
-
|
|
733
|
-
if (is_tracked || typeof v !== 'object' || v === null || is_array(v)) {
|
|
734
|
-
throw new TypeError('Invalid value: expected a non-tracked object');
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
/** @type {Tracked[]} */
|
|
738
|
-
var out = [];
|
|
739
|
-
/** @type {Record<string|symbol, any>} */
|
|
740
|
-
var rest = {};
|
|
741
|
-
/** @type {Record<PropertyKey, 1>} */
|
|
742
|
-
var done = {};
|
|
743
|
-
var props = Reflect.ownKeys(v);
|
|
744
|
-
|
|
745
|
-
for (let i = 0, key, t; i < l.length; i++) {
|
|
746
|
-
key = l[i];
|
|
747
|
-
|
|
748
|
-
if (props.includes(key)) {
|
|
749
|
-
if (is_ripple_object(v[key])) {
|
|
750
|
-
t = v[key];
|
|
751
|
-
} else {
|
|
752
|
-
t = tracked(undefined);
|
|
753
|
-
t = define_property(t, 'v', /** @type {PropertyDescriptor} */ (get_descriptor(v, key)));
|
|
754
|
-
}
|
|
755
|
-
} else {
|
|
756
|
-
t = tracked(undefined);
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
out[i] = t;
|
|
760
|
-
done[key] = 1;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
for (let i = 0, key; i < props.length; i++) {
|
|
764
|
-
key = props[i];
|
|
765
|
-
if (done[key]) {
|
|
766
|
-
continue;
|
|
767
|
-
}
|
|
768
|
-
define_property(rest, key, /** @type {PropertyDescriptor} */ (get_descriptor(v, key)));
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
out.push(tracked(rest));
|
|
772
|
-
|
|
773
|
-
return out;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
743
|
/**
|
|
777
744
|
* @param {any} _
|
|
778
745
|
* @param {ConstructorParameters<typeof URL>} params
|
|
@@ -865,6 +832,15 @@ export function ripple_object(obj) {
|
|
|
865
832
|
return obj;
|
|
866
833
|
}
|
|
867
834
|
|
|
835
|
+
/**
|
|
836
|
+
* @template K, V
|
|
837
|
+
* @param {Iterable<readonly [K, V]>} [iterable]
|
|
838
|
+
* @returns {Map<K, V>}
|
|
839
|
+
*/
|
|
840
|
+
export function ripple_map(iterable) {
|
|
841
|
+
return new Map(iterable);
|
|
842
|
+
}
|
|
843
|
+
|
|
868
844
|
/**
|
|
869
845
|
* Returns the fallback value if the given value is undefined.
|
|
870
846
|
* @template T
|
|
@@ -4,16 +4,16 @@ describe('RippleArray copyWithin', () => {
|
|
|
4
4
|
it('handles copyWithin operation with reactivity', () => {
|
|
5
5
|
component ArrayTest() {
|
|
6
6
|
let items = new RippleArray(1, 2, 3, 4, 5);
|
|
7
|
-
let firstItem = track(() => items[0]);
|
|
8
|
-
let thirdItem = track(() => items[2]);
|
|
9
|
-
let fourthItem = track(() => items[3]);
|
|
7
|
+
let &[firstItem] = track(() => items[0]);
|
|
8
|
+
let &[thirdItem] = track(() => items[2]);
|
|
9
|
+
let &[fourthItem] = track(() => items[3]);
|
|
10
10
|
|
|
11
11
|
<button onClick={() => items.copyWithin(0, 3)}>{'copy end to start'}</button>
|
|
12
12
|
<button onClick={() => items.copyWithin(2, 0, 2)}>{'copy start to middle'}</button>
|
|
13
13
|
<pre>{JSON.stringify(items)}</pre>
|
|
14
|
-
<pre>{
|
|
15
|
-
<pre>{
|
|
16
|
-
<pre>{
|
|
14
|
+
<pre>{firstItem}</pre>
|
|
15
|
+
<pre>{thirdItem}</pre>
|
|
16
|
+
<pre>{fourthItem}</pre>
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
render(ArrayTest);
|
|
@@ -49,13 +49,13 @@ describe('RippleArray copyWithin', () => {
|
|
|
49
49
|
it('handles copyWithin with negative indexes and reactivity', () => {
|
|
50
50
|
component ArrayTest() {
|
|
51
51
|
let items = new RippleArray(1, 2, 3, 4, 5);
|
|
52
|
-
let secondItem = track(() => items[1]);
|
|
53
|
-
let thirdItem = track(() => items[2]);
|
|
52
|
+
let &[secondItem] = track(() => items[1]);
|
|
53
|
+
let &[thirdItem] = track(() => items[2]);
|
|
54
54
|
|
|
55
55
|
<button onClick={() => items.copyWithin(-4, -2)}>{'copy with negative indexes'}</button>
|
|
56
56
|
<pre>{JSON.stringify(items)}</pre>
|
|
57
|
-
<pre>{
|
|
58
|
-
<pre>{
|
|
57
|
+
<pre>{secondItem}</pre>
|
|
58
|
+
<pre>{thirdItem}</pre>
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
render(ArrayTest);
|
|
@@ -80,12 +80,12 @@ describe('RippleArray copyWithin', () => {
|
|
|
80
80
|
it('handles copyWithin with overlapping ranges', () => {
|
|
81
81
|
component ArrayTest() {
|
|
82
82
|
let items = new RippleArray(1, 2, 3, 4, 5);
|
|
83
|
-
let entries = track(() => Array.from(items.entries()));
|
|
83
|
+
let &[entries] = track(() => Array.from(items.entries()));
|
|
84
84
|
|
|
85
85
|
<button onClick={() => items.copyWithin(2, 1, 4)}>{'copy with overlap'}</button>
|
|
86
86
|
<pre>{JSON.stringify(items)}</pre>
|
|
87
87
|
|
|
88
|
-
for (const [i, value] of
|
|
88
|
+
for (const [i, value] of entries) {
|
|
89
89
|
<pre>{`items[${i}]: ${value}`}</pre>
|
|
90
90
|
}
|
|
91
91
|
}
|