ripple 0.2.140 → 0.2.142
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/package.json +2 -2
- package/src/compiler/phases/1-parse/index.js +7 -3
- package/src/compiler/phases/2-analyze/index.js +11 -9
- package/src/compiler/phases/3-transform/client/index.js +25 -6
- package/src/compiler/utils.js +22 -11
- package/src/runtime/date.js +1 -1
- package/src/runtime/internal/client/index.js +3 -1
- package/src/runtime/internal/client/render.js +23 -23
- package/src/runtime/internal/client/runtime.js +44 -28
- package/src/runtime/map.js +182 -182
- package/src/runtime/media-query.js +1 -1
- package/src/runtime/proxy.js +279 -279
- package/src/runtime/set.js +168 -168
- package/src/runtime/url-search-params.js +5 -5
- package/src/runtime/url.js +18 -18
- package/tests/client/compiler/compiler.basic.test.ripple +17 -0
- package/tests/client/composite/composite.props.test.ripple +44 -2
- package/types/index.d.ts +1 -1
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.142",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/runtime/index-client.js",
|
|
9
9
|
"main": "src/runtime/index-client.js",
|
|
@@ -81,6 +81,6 @@
|
|
|
81
81
|
"typescript": "^5.9.2"
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
|
-
"ripple": "0.2.
|
|
84
|
+
"ripple": "0.2.142"
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -169,14 +169,18 @@ function RipplePlugin(config) {
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
if (inComponent) {
|
|
172
|
-
//
|
|
173
|
-
//
|
|
172
|
+
// Check if we're inside a nested function (arrow function, function expression, etc.)
|
|
173
|
+
// We need to distinguish between being inside a function vs just being in nested scopes
|
|
174
|
+
// (like for loops, if blocks, JSX elements, etc.)
|
|
175
|
+
const nestedFunctionContext = this.context.some((ctx) => ctx.token === 'function');
|
|
176
|
+
|
|
177
|
+
// Inside nested functions, treat < as relational/generic operator
|
|
174
178
|
// BUT: if the < is followed by /, it's a closing JSX tag, not a less-than operator
|
|
175
179
|
const nextChar =
|
|
176
180
|
this.pos + 1 < this.input.length ? this.input.charCodeAt(this.pos + 1) : -1;
|
|
177
181
|
const isClosingTag = nextChar === 47; // '/'
|
|
178
182
|
|
|
179
|
-
if (
|
|
183
|
+
if (nestedFunctionContext && !isClosingTag) {
|
|
180
184
|
// Inside function - treat as TypeScript generic, not JSX
|
|
181
185
|
++this.pos;
|
|
182
186
|
return this.finishToken(tt.relational, '<');
|
|
@@ -109,7 +109,7 @@ const visitors = {
|
|
|
109
109
|
const parent = context.path.at(-1);
|
|
110
110
|
|
|
111
111
|
if (
|
|
112
|
-
is_reference(node, /** @type {Node} */(parent)) &&
|
|
112
|
+
is_reference(node, /** @type {Node} */ (parent)) &&
|
|
113
113
|
binding &&
|
|
114
114
|
context.state.inside_server_block &&
|
|
115
115
|
context.state.scope.server_block
|
|
@@ -144,7 +144,7 @@ const visitors = {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
if (
|
|
147
|
-
is_reference(node, /** @type {Node} */(parent)) &&
|
|
147
|
+
is_reference(node, /** @type {Node} */ (parent)) &&
|
|
148
148
|
node.tracked &&
|
|
149
149
|
binding?.node !== node
|
|
150
150
|
) {
|
|
@@ -155,7 +155,7 @@ const visitors = {
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
if (
|
|
158
|
-
is_reference(node, /** @type {Node} */(parent)) &&
|
|
158
|
+
is_reference(node, /** @type {Node} */ (parent)) &&
|
|
159
159
|
node.tracked &&
|
|
160
160
|
binding?.node !== node
|
|
161
161
|
) {
|
|
@@ -191,7 +191,7 @@ const visitors = {
|
|
|
191
191
|
error(
|
|
192
192
|
`Directly accessing internal property "${propertyName}" of a tracked object is not allowed. Use \`get(${node.object.name})\` or \`@${node.object.name}\` instead.`,
|
|
193
193
|
context.state.analysis.module.filename,
|
|
194
|
-
node.property
|
|
194
|
+
node.property,
|
|
195
195
|
);
|
|
196
196
|
}
|
|
197
197
|
}
|
|
@@ -205,7 +205,7 @@ const visitors = {
|
|
|
205
205
|
`Accessing a tracked object directly is not allowed, use the \`@\` prefix to read the value inside a tracked object - for example \`@${node.object.name}${node.property.type === 'Identifier' ? `.${node.property.name}` : ''}\``,
|
|
206
206
|
context.state.analysis.module.filename,
|
|
207
207
|
node,
|
|
208
|
-
)
|
|
208
|
+
);
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
|
|
@@ -259,8 +259,11 @@ const visitors = {
|
|
|
259
259
|
const callee = declarator.init.callee;
|
|
260
260
|
// Check if it's a call to `track` or `tracked`
|
|
261
261
|
if (
|
|
262
|
-
(callee.type === 'Identifier' &&
|
|
263
|
-
|
|
262
|
+
(callee.type === 'Identifier' &&
|
|
263
|
+
(callee.name === 'track' || callee.name === 'tracked')) ||
|
|
264
|
+
(callee.type === 'MemberExpression' &&
|
|
265
|
+
callee.property.type === 'Identifier' &&
|
|
266
|
+
(callee.property.name === 'track' || callee.property.name === 'tracked'))
|
|
264
267
|
) {
|
|
265
268
|
binding.metadata = { ...binding.metadata, is_tracked_object: true };
|
|
266
269
|
}
|
|
@@ -623,7 +626,6 @@ const visitors = {
|
|
|
623
626
|
context.state.analysis.module.filename,
|
|
624
627
|
node,
|
|
625
628
|
);
|
|
626
|
-
|
|
627
629
|
},
|
|
628
630
|
|
|
629
631
|
Element(node, context) {
|
|
@@ -829,7 +831,7 @@ const visitors = {
|
|
|
829
831
|
error(
|
|
830
832
|
'`await` is not allowed in client-side control-flow statements',
|
|
831
833
|
context.state.analysis.module.filename,
|
|
832
|
-
node
|
|
834
|
+
node,
|
|
833
835
|
);
|
|
834
836
|
}
|
|
835
837
|
}
|
|
@@ -198,7 +198,7 @@ const visitors = {
|
|
|
198
198
|
...node.metadata,
|
|
199
199
|
original_name: node.name,
|
|
200
200
|
is_capitalized: true,
|
|
201
|
-
}
|
|
201
|
+
},
|
|
202
202
|
};
|
|
203
203
|
return b.member(capitalized_node, b.literal('#v'), true);
|
|
204
204
|
}
|
|
@@ -552,7 +552,7 @@ const visitors = {
|
|
|
552
552
|
...pattern.metadata,
|
|
553
553
|
original_name: pattern.name,
|
|
554
554
|
is_capitalized: true,
|
|
555
|
-
}
|
|
555
|
+
},
|
|
556
556
|
};
|
|
557
557
|
}
|
|
558
558
|
return pattern;
|
|
@@ -560,7 +560,7 @@ const visitors = {
|
|
|
560
560
|
return {
|
|
561
561
|
...pattern,
|
|
562
562
|
elements: pattern.elements.map((element) =>
|
|
563
|
-
element ? capitalize_pattern(element) : element
|
|
563
|
+
element ? capitalize_pattern(element) : element,
|
|
564
564
|
),
|
|
565
565
|
};
|
|
566
566
|
} else if (pattern.type === 'ObjectPattern') {
|
|
@@ -1007,7 +1007,7 @@ const visitors = {
|
|
|
1007
1007
|
let expression = visit(class_attribute.value, { ...state, metadata });
|
|
1008
1008
|
|
|
1009
1009
|
const hash_arg = scoping_hash ? b.literal(scoping_hash) : undefined;
|
|
1010
|
-
const is_html = context.state.
|
|
1010
|
+
const is_html = context.state.namespace === 'html' && node.id.name !== 'svg';
|
|
1011
1011
|
|
|
1012
1012
|
if (metadata.tracking) {
|
|
1013
1013
|
local_updates.push(
|
|
@@ -1379,7 +1379,7 @@ const visitors = {
|
|
|
1379
1379
|
}
|
|
1380
1380
|
|
|
1381
1381
|
const left = object(argument);
|
|
1382
|
-
const binding = context.state.scope.get(left.name);
|
|
1382
|
+
const binding = left && context.state.scope.get(left.name);
|
|
1383
1383
|
const transformers = left && binding?.transform;
|
|
1384
1384
|
|
|
1385
1385
|
if (left === argument) {
|
|
@@ -1896,7 +1896,10 @@ function transform_ts_child(node, context) {
|
|
|
1896
1896
|
},
|
|
1897
1897
|
end: {
|
|
1898
1898
|
line: node.loc.end.line,
|
|
1899
|
-
column:
|
|
1899
|
+
column:
|
|
1900
|
+
closing_tag_start +
|
|
1901
|
+
3 +
|
|
1902
|
+
(node.metadata?.original_name?.length || type_expression.length),
|
|
1900
1903
|
},
|
|
1901
1904
|
};
|
|
1902
1905
|
// Add metadata if this was capitalized
|
|
@@ -2330,6 +2333,22 @@ function create_tsx_with_typescript_support() {
|
|
|
2330
2333
|
|
|
2331
2334
|
return {
|
|
2332
2335
|
...base_tsx,
|
|
2336
|
+
// Custom handler for ArrayPattern to ensure typeAnnotation is visited
|
|
2337
|
+
// esrap's TypeScript handler doesn't visit typeAnnotation for ArrayPattern (only for ObjectPattern)
|
|
2338
|
+
ArrayPattern(node, context) {
|
|
2339
|
+
context.write('[');
|
|
2340
|
+
for (let i = 0; i < node.elements.length; i++) {
|
|
2341
|
+
if (i > 0) context.write(', ');
|
|
2342
|
+
if (node.elements[i]) {
|
|
2343
|
+
context.visit(node.elements[i]);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
context.write(']');
|
|
2347
|
+
// Visit type annotation if present
|
|
2348
|
+
if (node.typeAnnotation) {
|
|
2349
|
+
context.visit(node.typeAnnotation);
|
|
2350
|
+
}
|
|
2351
|
+
},
|
|
2333
2352
|
// Custom handler for FunctionDeclaration to support component->function mapping
|
|
2334
2353
|
// Needed for volar mappings and intellisense on function or component keyword
|
|
2335
2354
|
FunctionDeclaration(node, context) {
|
package/src/compiler/utils.js
CHANGED
|
@@ -201,7 +201,9 @@ export function get_delegated_event(event_name, handler, state) {
|
|
|
201
201
|
if (binding != null) {
|
|
202
202
|
for (const { path } of binding.references) {
|
|
203
203
|
const parent = path.at(-1);
|
|
204
|
-
if (parent === undefined)
|
|
204
|
+
if (parent === undefined) {
|
|
205
|
+
return unhoisted;
|
|
206
|
+
}
|
|
205
207
|
|
|
206
208
|
const grandparent = path.at(-2);
|
|
207
209
|
|
|
@@ -227,7 +229,11 @@ export function get_delegated_event(event_name, handler, state) {
|
|
|
227
229
|
) {
|
|
228
230
|
return unhoisted;
|
|
229
231
|
}
|
|
230
|
-
} else if (
|
|
232
|
+
} else if (
|
|
233
|
+
parent.type !== 'FunctionDeclaration' &&
|
|
234
|
+
parent.type !== 'VariableDeclarator' &&
|
|
235
|
+
parent.type !== 'Attribute'
|
|
236
|
+
) {
|
|
231
237
|
return unhoisted;
|
|
232
238
|
}
|
|
233
239
|
}
|
|
@@ -262,24 +268,29 @@ export function get_delegated_event(event_name, handler, state) {
|
|
|
262
268
|
|
|
263
269
|
const visited_references = new Set();
|
|
264
270
|
const scope = target_function.metadata.scope;
|
|
265
|
-
for (const [reference] of scope.references) {
|
|
271
|
+
for (const [reference, ref_nodes] of scope.references) {
|
|
266
272
|
// Bail out if the arguments keyword is used or $host is referenced
|
|
267
273
|
if (reference === 'arguments') return unhoisted;
|
|
268
274
|
|
|
269
275
|
const binding = scope.get(reference);
|
|
270
276
|
const local_binding = state.scope.get(reference);
|
|
271
277
|
|
|
278
|
+
if (local_binding === null || binding == null) {
|
|
279
|
+
return unhoisted;
|
|
280
|
+
}
|
|
281
|
+
|
|
272
282
|
// If we are referencing a binding that is shadowed in another scope then bail out.
|
|
273
|
-
if (local_binding
|
|
283
|
+
if (local_binding.node !== binding.node) {
|
|
274
284
|
return unhoisted;
|
|
275
285
|
}
|
|
286
|
+
const is_tracked = ref_nodes.some(({ node }) => node.tracked);
|
|
276
287
|
|
|
277
288
|
if (
|
|
278
289
|
binding !== null &&
|
|
279
290
|
// Bail out if the the binding is a rest param
|
|
280
291
|
(binding.declaration_kind === 'rest_param' || // or any normal not reactive bindings that are mutated.
|
|
281
292
|
// Bail out if we reference anything from the EachBlock (for now) that mutates in non-runes mode,
|
|
282
|
-
(binding.kind === 'normal' && binding.updated))
|
|
293
|
+
(binding.kind === 'normal' && !is_tracked && binding.updated))
|
|
283
294
|
) {
|
|
284
295
|
return unhoisted;
|
|
285
296
|
}
|
|
@@ -352,7 +363,7 @@ export function build_hoisted_params(node, context) {
|
|
|
352
363
|
}
|
|
353
364
|
} else {
|
|
354
365
|
for (const param of node.params) {
|
|
355
|
-
params.push(/** @type {Pattern} */(context.visit(param)));
|
|
366
|
+
params.push(/** @type {Pattern} */ (context.visit(param)));
|
|
356
367
|
}
|
|
357
368
|
}
|
|
358
369
|
|
|
@@ -554,7 +565,7 @@ export function is_ripple_import(callee, context) {
|
|
|
554
565
|
* @returns {boolean}
|
|
555
566
|
*/
|
|
556
567
|
export function is_declared_function_within_component(node, context) {
|
|
557
|
-
const component = context.path?.find(/** @param {RippleNode} n */(n) => n.type === 'Component');
|
|
568
|
+
const component = context.path?.find(/** @param {RippleNode} n */ (n) => n.type === 'Component');
|
|
558
569
|
|
|
559
570
|
if (node.type === 'Identifier' && component) {
|
|
560
571
|
const binding = context.state.scope.get(node.name);
|
|
@@ -611,8 +622,8 @@ export function visit_assignment_expression(node, context, build_assignment) {
|
|
|
611
622
|
assignment ??
|
|
612
623
|
b.assignment(
|
|
613
624
|
'=',
|
|
614
|
-
/** @type {Pattern} */(context.visit(path.node)),
|
|
615
|
-
/** @type {Expression} */(context.visit(value)),
|
|
625
|
+
/** @type {Pattern} */ (context.visit(path.node)),
|
|
626
|
+
/** @type {Expression} */ (context.visit(value)),
|
|
616
627
|
)
|
|
617
628
|
);
|
|
618
629
|
});
|
|
@@ -702,8 +713,8 @@ export function build_assignment(operator, left, right, context) {
|
|
|
702
713
|
object,
|
|
703
714
|
b.assignment(
|
|
704
715
|
operator,
|
|
705
|
-
/** @type {Pattern} */(context.visit(left)),
|
|
706
|
-
/** @type {Expression} */(context.visit(right)),
|
|
716
|
+
/** @type {Pattern} */ (context.visit(left)),
|
|
717
|
+
/** @type {Expression} */ (context.visit(right)),
|
|
707
718
|
),
|
|
708
719
|
);
|
|
709
720
|
}
|
package/src/runtime/date.js
CHANGED
|
@@ -64,7 +64,7 @@ export class TrackedDate extends Date {
|
|
|
64
64
|
proto[method] = function (...args) {
|
|
65
65
|
// @ts-ignore
|
|
66
66
|
var result = date_proto[method].apply(this, args);
|
|
67
|
-
set(this.#time, date_proto.getTime.call(this)
|
|
67
|
+
set(this.#time, date_proto.getTime.call(this));
|
|
68
68
|
return result;
|
|
69
69
|
};
|
|
70
70
|
}
|
|
@@ -14,7 +14,7 @@ export {
|
|
|
14
14
|
set_selected,
|
|
15
15
|
} from './render.js';
|
|
16
16
|
|
|
17
|
-
export { render, render_spread, async, ref } from './blocks.js';
|
|
17
|
+
export { render, render_spread, async, ref, branch } from './blocks.js';
|
|
18
18
|
|
|
19
19
|
export { event, delegate } from './events.js';
|
|
20
20
|
|
|
@@ -47,6 +47,8 @@ export {
|
|
|
47
47
|
derived,
|
|
48
48
|
maybe_tracked,
|
|
49
49
|
tick,
|
|
50
|
+
proxy_tracked,
|
|
51
|
+
with_block,
|
|
50
52
|
} from './runtime.js';
|
|
51
53
|
|
|
52
54
|
export { composite } from './composite.js';
|
|
@@ -163,29 +163,29 @@ export function set_attributes(element, attributes) {
|
|
|
163
163
|
* @param {Element} element
|
|
164
164
|
* @param {string} key
|
|
165
165
|
* @param {any} value
|
|
166
|
-
*/
|
|
166
|
+
*/
|
|
167
167
|
function set_attribute_helper(element, key, value) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
168
|
+
if (key === 'class') {
|
|
169
|
+
const is_html = element.namespaceURI === 'http://www.w3.org/1999/xhtml';
|
|
170
|
+
set_class(/** @type {HTMLElement} */ (element), value, undefined, is_html);
|
|
171
|
+
} else if (key === '#class') {
|
|
172
|
+
// Special case for static class when spreading props
|
|
173
|
+
element.classList.add(value);
|
|
174
|
+
} else if (typeof key === 'string' && is_event_attribute(key)) {
|
|
175
|
+
// Handle event handlers in spread props
|
|
176
|
+
const event_name = get_attribute_event_name(key);
|
|
177
|
+
|
|
178
|
+
if (is_delegated(event_name)) {
|
|
179
|
+
// Use delegation for delegated events
|
|
180
|
+
/** @type {any} */ (element)['__' + event_name] = value;
|
|
181
|
+
delegate([event_name]);
|
|
182
|
+
} else {
|
|
183
|
+
// Use addEventListener for non-delegated events
|
|
184
|
+
event(event_name, element, value);
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
set_attribute(element, key, value);
|
|
188
|
+
}
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/**
|
|
@@ -312,7 +312,7 @@ export function apply_element_spread(element, fn) {
|
|
|
312
312
|
for (const symbol of get_own_property_symbols(next)) {
|
|
313
313
|
// Ensure we are not trying to write to a proxied object
|
|
314
314
|
if (TRACKED_OBJECT in next) {
|
|
315
|
-
next = {...next};
|
|
315
|
+
next = { ...next };
|
|
316
316
|
}
|
|
317
317
|
var ref_fn = next[symbol];
|
|
318
318
|
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
import { capture, suspend } from './try.js';
|
|
31
31
|
import {
|
|
32
32
|
define_property,
|
|
33
|
-
|
|
33
|
+
get_descriptor,
|
|
34
34
|
get_own_property_symbols,
|
|
35
35
|
is_array,
|
|
36
36
|
is_tracked_object,
|
|
@@ -135,6 +135,20 @@ export function run_teardown(block) {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
/**
|
|
139
|
+
* @param {Block} block
|
|
140
|
+
* @param {() => void} fn
|
|
141
|
+
*/
|
|
142
|
+
export function with_block(block, fn) {
|
|
143
|
+
var prev_block = active_block;
|
|
144
|
+
active_block = block;
|
|
145
|
+
try {
|
|
146
|
+
return fn();
|
|
147
|
+
} finally {
|
|
148
|
+
active_block = prev_block;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
138
152
|
/**
|
|
139
153
|
* @param {Derived} computed
|
|
140
154
|
*/
|
|
@@ -372,35 +386,34 @@ export function track_split(v, l, b) {
|
|
|
372
386
|
var out = [];
|
|
373
387
|
/** @type {Record<string|symbol, any>} */
|
|
374
388
|
var rest = {};
|
|
375
|
-
/** @type {Record<PropertyKey,
|
|
376
|
-
var
|
|
389
|
+
/** @type {Record<PropertyKey, 1>} */
|
|
390
|
+
var done = {};
|
|
391
|
+
var props = Reflect.ownKeys(v);
|
|
377
392
|
|
|
378
|
-
for (let i = 0, key, t
|
|
393
|
+
for (let i = 0, key, t; i < l.length; i++) {
|
|
379
394
|
key = l[i];
|
|
380
395
|
|
|
381
|
-
if (
|
|
382
|
-
|
|
396
|
+
if (props.includes(key)) {
|
|
397
|
+
if (is_tracked_object(v[key])) {
|
|
398
|
+
t = v[key];
|
|
399
|
+
} else {
|
|
400
|
+
t = tracked(undefined, b);
|
|
401
|
+
t = define_property(t, '__v', /** @type {PropertyDescriptor} */ (get_descriptor(v, key)));
|
|
402
|
+
}
|
|
383
403
|
} else {
|
|
384
404
|
t = tracked(undefined, b);
|
|
385
|
-
exists = !!descriptors[key];
|
|
386
|
-
if (exists) {
|
|
387
|
-
t = define_property(t, '__v', descriptors[key]);
|
|
388
|
-
}
|
|
389
405
|
}
|
|
390
406
|
|
|
391
407
|
out[i] = t;
|
|
392
|
-
|
|
393
|
-
descriptors[key] = null;
|
|
394
|
-
}
|
|
408
|
+
done[key] = 1;
|
|
395
409
|
}
|
|
396
410
|
|
|
397
|
-
var props = Reflect.ownKeys(descriptors);
|
|
398
411
|
for (let i = 0, key; i < props.length; i++) {
|
|
399
412
|
key = props[i];
|
|
400
|
-
if (
|
|
413
|
+
if (done[key]) {
|
|
401
414
|
continue;
|
|
402
415
|
}
|
|
403
|
-
define_property(rest, key,
|
|
416
|
+
define_property(rest, key, /** @type {PropertyDescriptor} */ (get_descriptor(v, key)));
|
|
404
417
|
}
|
|
405
418
|
|
|
406
419
|
out.push(tracked(rest, b));
|
|
@@ -903,34 +916,37 @@ export function flush_sync(fn) {
|
|
|
903
916
|
*/
|
|
904
917
|
export function spread_props(fn, block) {
|
|
905
918
|
var computed = derived(fn, block);
|
|
919
|
+
return proxy_tracked(computed);
|
|
920
|
+
}
|
|
906
921
|
|
|
922
|
+
/**
|
|
923
|
+
* @param {Tracked | Derived} tracked
|
|
924
|
+
* @returns {Object}
|
|
925
|
+
*/
|
|
926
|
+
export function proxy_tracked(tracked) {
|
|
907
927
|
return new Proxy(
|
|
908
928
|
{},
|
|
909
929
|
{
|
|
910
|
-
get(
|
|
911
|
-
const obj =
|
|
930
|
+
get(_, property) {
|
|
931
|
+
const obj = get(tracked);
|
|
912
932
|
return obj[property];
|
|
913
933
|
},
|
|
914
|
-
has(
|
|
934
|
+
has(_, property) {
|
|
915
935
|
if (property === TRACKED_OBJECT) {
|
|
916
936
|
return true;
|
|
917
937
|
}
|
|
918
|
-
const obj =
|
|
938
|
+
const obj = get(tracked);
|
|
919
939
|
return property in obj;
|
|
920
940
|
},
|
|
921
|
-
getOwnPropertyDescriptor(
|
|
922
|
-
const obj =
|
|
941
|
+
getOwnPropertyDescriptor(_, key) {
|
|
942
|
+
const obj = get(tracked);
|
|
923
943
|
|
|
924
944
|
if (key in obj) {
|
|
925
|
-
return
|
|
926
|
-
enumerable: true,
|
|
927
|
-
configurable: true,
|
|
928
|
-
value: obj[key],
|
|
929
|
-
};
|
|
945
|
+
return get_descriptor(obj, key);
|
|
930
946
|
}
|
|
931
947
|
},
|
|
932
948
|
ownKeys() {
|
|
933
|
-
const obj =
|
|
949
|
+
const obj = get(tracked);
|
|
934
950
|
return Reflect.ownKeys(obj);
|
|
935
951
|
},
|
|
936
952
|
},
|