ripple 0.2.85 → 0.2.87
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 +3 -1
- package/src/compiler/scope.js +2 -0
- package/src/compiler/types/index.d.ts +5 -0
- package/src/runtime/array.js +12 -5
- package/src/runtime/index-client.js +0 -1
- package/src/runtime/index-server.js +18 -3
- package/src/runtime/internal/client/blocks.js +209 -205
- package/src/runtime/internal/client/composite.js +9 -0
- package/src/runtime/internal/client/events.js +219 -189
- package/src/runtime/internal/client/for.js +97 -13
- package/src/runtime/internal/client/if.js +11 -0
- package/src/runtime/internal/client/operations.js +7 -2
- package/src/runtime/internal/client/portal.js +15 -4
- package/src/runtime/internal/client/render.js +48 -6
- package/src/runtime/internal/client/runtime.js +101 -87
- package/src/runtime/internal/client/template.js +8 -5
- package/src/runtime/internal/client/try.js +42 -4
- package/src/runtime/internal/client/utils.js +18 -3
- package/src/runtime/internal/server/context.js +2 -0
- package/src/runtime/internal/server/index.js +39 -3
- package/src/runtime/internal/server/types.d.ts +21 -0
- package/src/runtime/map.js +37 -2
- package/src/runtime/set.js +22 -9
- package/src/utils/builders.js +1 -0
- package/tests/client/basic.test.ripple +21 -0
- package/tests/client/ref.test.ripple +33 -2
- package/types/index.d.ts +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { is_passive_event } from '../../../utils/events.js';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
active_block,
|
|
4
|
+
active_reaction,
|
|
5
|
+
set_active_block,
|
|
6
|
+
set_active_reaction,
|
|
7
|
+
set_tracking,
|
|
8
|
+
tracking,
|
|
9
9
|
} from './runtime.js';
|
|
10
10
|
import { array_from, define_property, is_array } from './utils.js';
|
|
11
11
|
|
|
@@ -35,136 +35,136 @@ export function on(element, type, handler, options = {}) {
|
|
|
35
35
|
* @returns {void}
|
|
36
36
|
*/
|
|
37
37
|
export function handle_event_propagation(event) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
38
|
+
var handler_element = this;
|
|
39
|
+
var owner_document = /** @type {Node} */ (handler_element).ownerDocument;
|
|
40
|
+
var event_name = event.type;
|
|
41
|
+
var path = event.composedPath?.() || [];
|
|
42
|
+
var current_target = /** @type {null | Element} */ (path[0] || event.target);
|
|
43
|
+
|
|
44
|
+
// composedPath contains list of nodes the event has propagated through.
|
|
45
|
+
// We check __root to skip all nodes below it in case this is a
|
|
46
|
+
// parent of the __root node, which indicates that there's nested
|
|
47
|
+
// mounted apps. In this case we don't want to trigger events multiple times.
|
|
48
|
+
var path_idx = 0;
|
|
49
|
+
|
|
50
|
+
// @ts-expect-error is added below
|
|
51
|
+
var handled_at = event.__root;
|
|
52
|
+
|
|
53
|
+
if (handled_at) {
|
|
54
|
+
var at_idx = path.indexOf(handled_at);
|
|
55
|
+
if (
|
|
56
|
+
at_idx !== -1 &&
|
|
57
|
+
(handler_element === document || handler_element === /** @type {any} */ (window))
|
|
58
|
+
) {
|
|
59
|
+
// This is the fallback document listener or a window listener, but the event was already handled
|
|
60
|
+
// -> ignore, but set handle_at to document/window so that we're resetting the event
|
|
61
|
+
// chain in case someone manually dispatches the same event object again.
|
|
62
|
+
// @ts-expect-error
|
|
63
|
+
event.__root = handler_element;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// We're deliberately not skipping if the index is higher, because
|
|
68
|
+
// someone could create an event programmatically and emit it multiple times,
|
|
69
|
+
// in which case we want to handle the whole propagation chain properly each time.
|
|
70
|
+
// (this will only be a false negative if the event is dispatched multiple times and
|
|
71
|
+
// the fallback document listener isn't reached in between, but that's super rare)
|
|
72
|
+
var handler_idx = path.indexOf(handler_element);
|
|
73
|
+
if (handler_idx === -1) {
|
|
74
|
+
// handle_idx can theoretically be -1 (happened in some JSDOM testing scenarios with an event listener on the window object)
|
|
75
|
+
// so guard against that, too, and assume that everything was handled at this point.
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (at_idx <= handler_idx) {
|
|
80
|
+
path_idx = at_idx;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
current_target = /** @type {Element} */ (path[path_idx] || event.target);
|
|
85
|
+
// there can only be one delegated event per element, and we either already handled the current target,
|
|
86
|
+
// or this is the very first target in the chain which has a non-delegated listener, in which case it's safe
|
|
87
|
+
// to handle a possible delegated event on it later (through the root delegation listener for example).
|
|
88
|
+
if (current_target === handler_element) return;
|
|
89
|
+
|
|
90
|
+
// Proxy currentTarget to correct target
|
|
91
|
+
define_property(event, 'currentTarget', {
|
|
92
|
+
configurable: true,
|
|
93
|
+
get() {
|
|
94
|
+
return current_target || owner_document;
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
var previous_block = active_block;
|
|
99
|
+
var previous_reaction = active_reaction;
|
|
100
|
+
var previous_tracking = tracking;
|
|
101
|
+
|
|
102
|
+
set_active_block(null);
|
|
103
|
+
set_active_reaction(null);
|
|
104
|
+
set_tracking(false);
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
/**
|
|
108
|
+
* @type {unknown}
|
|
109
|
+
*/
|
|
110
|
+
var throw_error;
|
|
111
|
+
/**
|
|
112
|
+
* @type {unknown[]}
|
|
113
|
+
*/
|
|
114
|
+
var other_errors = [];
|
|
115
|
+
|
|
116
|
+
while (current_target !== null) {
|
|
117
|
+
/** @type {null | Element} */
|
|
118
|
+
var parent_element =
|
|
119
|
+
current_target.assignedSlot ||
|
|
120
|
+
current_target.parentNode ||
|
|
121
|
+
/** @type {any} */ (current_target).host ||
|
|
122
|
+
null;
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
// @ts-expect-error
|
|
126
|
+
var delegated = current_target['__' + event_name];
|
|
127
|
+
|
|
128
|
+
if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
|
|
129
|
+
if (is_array(delegated)) {
|
|
130
|
+
var [fn, block, ...data] = delegated;
|
|
131
|
+
fn.apply(current_target, [event, ...data, block]);
|
|
132
|
+
} else {
|
|
133
|
+
delegated.call(current_target, event);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (throw_error) {
|
|
138
|
+
other_errors.push(error);
|
|
139
|
+
} else {
|
|
140
|
+
throw_error = error;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (event.cancelBubble || parent_element === handler_element || parent_element === null) {
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
current_target = parent_element;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (throw_error) {
|
|
150
|
+
for (let error of other_errors) {
|
|
151
|
+
// Throw the rest of the errors, one-by-one on a microtask
|
|
152
|
+
queueMicrotask(() => {
|
|
153
|
+
throw error;
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
throw throw_error;
|
|
157
|
+
}
|
|
158
|
+
} finally {
|
|
159
|
+
set_active_block(previous_block);
|
|
160
|
+
// @ts-expect-error is used above
|
|
161
|
+
event.__root = handler_element;
|
|
162
|
+
// @ts-ignore remove proxy on currentTarget
|
|
163
|
+
delete event.currentTarget;
|
|
164
|
+
set_active_block(previous_block);
|
|
165
|
+
set_active_reaction(previous_reaction);
|
|
166
|
+
set_tracking(previous_tracking);
|
|
167
|
+
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
/**
|
|
@@ -174,73 +174,103 @@ export function handle_event_propagation(event) {
|
|
|
174
174
|
* @param {AddEventListenerOptions} [options]
|
|
175
175
|
*/
|
|
176
176
|
function create_event(event_name, dom, handler, options = {}) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
177
|
+
/** @this {any} */
|
|
178
|
+
function target_handler(/** @type {Event} */ event) {
|
|
179
|
+
var previous_block = active_block;
|
|
180
|
+
var previous_reaction = active_reaction;
|
|
181
|
+
var previous_tracking = tracking;
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
set_active_block(null);
|
|
185
|
+
set_active_reaction(null);
|
|
186
|
+
set_tracking(false);
|
|
187
|
+
|
|
188
|
+
if (!options.capture) {
|
|
189
|
+
// Only call in the bubble phase, else delegated events would be called before the capturing events
|
|
190
|
+
handle_event_propagation.call(dom, event);
|
|
191
|
+
}
|
|
192
|
+
if (!event.cancelBubble) {
|
|
193
|
+
return handler?.call(this, event);
|
|
194
|
+
}
|
|
195
|
+
} finally {
|
|
196
|
+
set_active_block(previous_block);
|
|
197
|
+
set_active_reaction(previous_reaction);
|
|
198
|
+
set_tracking(previous_tracking);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
dom.addEventListener(event_name, target_handler, options);
|
|
203
|
+
|
|
204
|
+
return target_handler;
|
|
204
205
|
}
|
|
205
206
|
|
|
207
|
+
/**
|
|
208
|
+
* @param {string} event_name
|
|
209
|
+
* @param {Element} dom
|
|
210
|
+
* @param {EventListener} [handler]
|
|
211
|
+
* @param {boolean} [capture]
|
|
212
|
+
* @param {boolean} [passive]
|
|
213
|
+
* @returns {void}
|
|
214
|
+
*/
|
|
206
215
|
export function event(event_name, dom, handler, capture, passive) {
|
|
207
|
-
|
|
208
|
-
|
|
216
|
+
var options = { capture, passive };
|
|
217
|
+
create_event(event_name, dom, handler, options);
|
|
209
218
|
}
|
|
210
219
|
|
|
220
|
+
/**
|
|
221
|
+
* @param {Array<string>} events
|
|
222
|
+
* @returns {void}
|
|
223
|
+
*/
|
|
211
224
|
export function delegate(events) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
225
|
+
for (var i = 0; i < events.length; i++) {
|
|
226
|
+
all_registered_events.add(events[i]);
|
|
227
|
+
}
|
|
215
228
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
229
|
+
for (var fn of root_event_handles) {
|
|
230
|
+
fn(events);
|
|
231
|
+
}
|
|
219
232
|
}
|
|
220
233
|
|
|
234
|
+
/** @param {Element} target */
|
|
221
235
|
export function handle_root_events(target) {
|
|
222
|
-
|
|
236
|
+
var registered_events = new Set();
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @typedef {Object} EventHandleOptions
|
|
240
|
+
* @property {boolean} [passive]
|
|
241
|
+
*/
|
|
223
242
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
243
|
+
/**
|
|
244
|
+
* @typedef {(
|
|
245
|
+
* events: Array<string>
|
|
246
|
+
* ) => void} EventHandle
|
|
247
|
+
*/
|
|
227
248
|
|
|
228
|
-
|
|
229
|
-
|
|
249
|
+
/** @type {EventHandle} */
|
|
250
|
+
var event_handle = (/** @type {Array<string>} */ events) => {
|
|
251
|
+
for (var i = 0; i < events.length; i++) {
|
|
252
|
+
var event_name = events[i];
|
|
230
253
|
|
|
231
|
-
|
|
254
|
+
if (registered_events.has(event_name)) continue;
|
|
255
|
+
registered_events.add(event_name);
|
|
232
256
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
};
|
|
257
|
+
/** @type {boolean} */
|
|
258
|
+
var passive = is_passive_event(event_name);
|
|
236
259
|
|
|
237
|
-
|
|
238
|
-
|
|
260
|
+
/** @type {EventHandleOptions} */
|
|
261
|
+
var options = { passive };
|
|
262
|
+
|
|
263
|
+
target.addEventListener(event_name, handle_event_propagation, options);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
239
266
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
267
|
+
event_handle(array_from(all_registered_events));
|
|
268
|
+
root_event_handles.add(event_handle);
|
|
269
|
+
|
|
270
|
+
return () => {
|
|
271
|
+
for (var event_name of registered_events) {
|
|
272
|
+
target.removeEventListener(event_name, handle_event_propagation);
|
|
273
|
+
}
|
|
274
|
+
root_event_handles.delete(event_handle);
|
|
275
|
+
};
|
|
246
276
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** @import { Block } from '#client' */
|
|
2
|
+
|
|
1
3
|
import { IS_CONTROLLED, IS_INDEXED } from '../../../constants.js';
|
|
2
4
|
import { branch, destroy_block, destroy_block_children, render } from './blocks.js';
|
|
3
5
|
import { FOR_BLOCK, TRACKED_ARRAY } from './constants.js';
|
|
@@ -5,6 +7,15 @@ import { create_text, next_sibling } from './operations.js';
|
|
|
5
7
|
import { active_block, set, tracked, untrack } from './runtime.js';
|
|
6
8
|
import { array_from, is_array } from './utils.js';
|
|
7
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @template V
|
|
12
|
+
* @param {Node} anchor
|
|
13
|
+
* @param {V} value
|
|
14
|
+
* @param {number} index
|
|
15
|
+
* @param {(anchor: Node, value: V, index?: any) => Block} render_fn
|
|
16
|
+
* @param {boolean} is_indexed
|
|
17
|
+
* @returns {Block}
|
|
18
|
+
*/
|
|
8
19
|
function create_item(anchor, value, index, render_fn, is_indexed) {
|
|
9
20
|
var b = branch(() => {
|
|
10
21
|
var tracked_index;
|
|
@@ -31,6 +42,11 @@ function create_item(anchor, value, index, render_fn, is_indexed) {
|
|
|
31
42
|
return b;
|
|
32
43
|
}
|
|
33
44
|
|
|
45
|
+
/**
|
|
46
|
+
* @param {Block} block
|
|
47
|
+
* @param {Element} anchor
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*/
|
|
34
50
|
function move(block, anchor) {
|
|
35
51
|
var node = block.s.start;
|
|
36
52
|
var end = block.s.end;
|
|
@@ -40,7 +56,7 @@ function move(block, anchor) {
|
|
|
40
56
|
return;
|
|
41
57
|
}
|
|
42
58
|
while (node !== null) {
|
|
43
|
-
var next_node = /** @type {
|
|
59
|
+
var next_node = /** @type {Node} */ (next_sibling(node));
|
|
44
60
|
anchor.before(node);
|
|
45
61
|
node = next_node;
|
|
46
62
|
if (node === end) {
|
|
@@ -50,6 +66,11 @@ function move(block, anchor) {
|
|
|
50
66
|
}
|
|
51
67
|
}
|
|
52
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @template V
|
|
71
|
+
* @param {V[] | Iterable<V>} collection
|
|
72
|
+
* @returns {V[]}
|
|
73
|
+
*/
|
|
53
74
|
function collection_to_array(collection) {
|
|
54
75
|
var array = is_array(collection) ? collection : collection == null ? [] : array_from(collection);
|
|
55
76
|
|
|
@@ -62,10 +83,18 @@ function collection_to_array(collection) {
|
|
|
62
83
|
return array;
|
|
63
84
|
}
|
|
64
85
|
|
|
86
|
+
/**
|
|
87
|
+
* @template V
|
|
88
|
+
* @param {Element} node
|
|
89
|
+
* @param {() => V[] | Iterable<V>} get_collection
|
|
90
|
+
* @param {(anchor: Node, value: V, index?: any) => Block} render_fn
|
|
91
|
+
* @param {number} flags
|
|
92
|
+
* @returns {void}
|
|
93
|
+
*/
|
|
65
94
|
export function for_block(node, get_collection, render_fn, flags) {
|
|
66
95
|
var is_controlled = (flags & IS_CONTROLLED) !== 0;
|
|
67
96
|
var is_indexed = (flags & IS_INDEXED) !== 0;
|
|
68
|
-
var anchor = node;
|
|
97
|
+
var anchor = /** @type {Element | Text} */ (node);
|
|
69
98
|
|
|
70
99
|
if (is_controlled) {
|
|
71
100
|
anchor = node.appendChild(create_text());
|
|
@@ -82,9 +111,16 @@ export function for_block(node, get_collection, render_fn, flags) {
|
|
|
82
111
|
}, FOR_BLOCK);
|
|
83
112
|
}
|
|
84
113
|
|
|
114
|
+
/**
|
|
115
|
+
* @template V
|
|
116
|
+
* @param {Element | Text} anchor
|
|
117
|
+
* @param {Block} block
|
|
118
|
+
* @param {V[]} array
|
|
119
|
+
* @returns {void}
|
|
120
|
+
*/
|
|
85
121
|
function reconcile_fast_clear(anchor, block, array) {
|
|
86
122
|
var state = block.s;
|
|
87
|
-
var parent_node = anchor.parentNode;
|
|
123
|
+
var parent_node = /** @type {Element} */ (anchor.parentNode);
|
|
88
124
|
parent_node.textContent = '';
|
|
89
125
|
destroy_block_children(block);
|
|
90
126
|
parent_node.append(anchor);
|
|
@@ -92,13 +128,48 @@ function reconcile_fast_clear(anchor, block, array) {
|
|
|
92
128
|
state.blocks = [];
|
|
93
129
|
}
|
|
94
130
|
|
|
131
|
+
/**
|
|
132
|
+
* @param {Block} block
|
|
133
|
+
* @param {number} index
|
|
134
|
+
* @returns {void}
|
|
135
|
+
*/
|
|
95
136
|
function update_index(block, index) {
|
|
96
137
|
set(block.s.i, index, block);
|
|
97
138
|
}
|
|
98
139
|
|
|
140
|
+
/**
|
|
141
|
+
* @template V
|
|
142
|
+
* @param {Element | Text} anchor
|
|
143
|
+
* @param {Block} block
|
|
144
|
+
* @param {V[]} b
|
|
145
|
+
* @param {(anchor: Node, value: V, index?: any) => Block} render_fn
|
|
146
|
+
* @param {boolean} is_controlled
|
|
147
|
+
* @param {boolean} is_indexed
|
|
148
|
+
* @returns {void}
|
|
149
|
+
*/
|
|
99
150
|
function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
|
|
100
151
|
var state = block.s;
|
|
101
152
|
|
|
153
|
+
// Variables used in conditional branches - declare with initial values
|
|
154
|
+
/** @type {number} */
|
|
155
|
+
var a_start = 0;
|
|
156
|
+
/** @type {number} */
|
|
157
|
+
var b_start = 0;
|
|
158
|
+
/** @type {number} */
|
|
159
|
+
var a_left = 0;
|
|
160
|
+
/** @type {number} */
|
|
161
|
+
var b_left = 0;
|
|
162
|
+
/** @type {Int32Array} */
|
|
163
|
+
var sources = new Int32Array(0);
|
|
164
|
+
/** @type {boolean} */
|
|
165
|
+
var moved = false;
|
|
166
|
+
/** @type {number} */
|
|
167
|
+
var pos = 0;
|
|
168
|
+
/** @type {number} */
|
|
169
|
+
var patched = 0;
|
|
170
|
+
/** @type {number} */
|
|
171
|
+
var i = 0;
|
|
172
|
+
|
|
102
173
|
if (state === null) {
|
|
103
174
|
state = block.s = {
|
|
104
175
|
array: [],
|
|
@@ -187,15 +258,15 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
|
|
|
187
258
|
destroy_block(a_blocks[j++]);
|
|
188
259
|
}
|
|
189
260
|
} else {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
261
|
+
a_start = j;
|
|
262
|
+
b_start = j;
|
|
263
|
+
a_left = a_end - j + 1;
|
|
264
|
+
b_left = b_end - j + 1;
|
|
265
|
+
sources = new Int32Array(b_left + 1);
|
|
266
|
+
moved = false;
|
|
267
|
+
pos = 0;
|
|
268
|
+
patched = 0;
|
|
269
|
+
i = 0;
|
|
199
270
|
|
|
200
271
|
fast_path_removal = is_controlled && a_left === a_length;
|
|
201
272
|
|
|
@@ -321,10 +392,16 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
|
|
|
321
392
|
state.blocks = b_blocks;
|
|
322
393
|
}
|
|
323
394
|
|
|
395
|
+
/** @type {Int32Array} */
|
|
324
396
|
let result;
|
|
397
|
+
/** @type {Int32Array} */
|
|
325
398
|
let p;
|
|
326
399
|
let maxLen = 0;
|
|
327
400
|
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
|
401
|
+
/**
|
|
402
|
+
* @param {Int32Array} arr
|
|
403
|
+
* @returns {Int32Array}
|
|
404
|
+
*/
|
|
328
405
|
function lis_algorithm(arr) {
|
|
329
406
|
let arrI = 0;
|
|
330
407
|
let i = 0;
|
|
@@ -386,6 +463,13 @@ function lis_algorithm(arr) {
|
|
|
386
463
|
return seq;
|
|
387
464
|
}
|
|
388
465
|
|
|
466
|
+
/**
|
|
467
|
+
* @template V
|
|
468
|
+
* @template K
|
|
469
|
+
* @param {V[] | Iterable<V>} collection
|
|
470
|
+
* @param {(item: V) => K} key_fn
|
|
471
|
+
* @returns {V[]}
|
|
472
|
+
*/
|
|
389
473
|
export function keyed(collection, key_fn) {
|
|
390
474
|
var block = active_block;
|
|
391
475
|
if (block === null || (block.f & FOR_BLOCK) === 0) {
|
|
@@ -404,7 +488,7 @@ export function keyed(collection, key_fn) {
|
|
|
404
488
|
var state = block.s;
|
|
405
489
|
|
|
406
490
|
if (state === null) {
|
|
407
|
-
return
|
|
491
|
+
return b_array;
|
|
408
492
|
}
|
|
409
493
|
|
|
410
494
|
var a_array = state.array;
|
|
@@ -1,17 +1,28 @@
|
|
|
1
|
+
/** @import { Block } from '#client' */
|
|
2
|
+
|
|
1
3
|
import { branch, destroy_block, render } from './blocks.js';
|
|
2
4
|
import { IF_BLOCK, UNINITIALIZED } from './constants.js';
|
|
3
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @param {Node} node
|
|
8
|
+
* @param {(set_branch: (fn: (anchor: Node) => void, flag?: boolean) => void) => void} fn
|
|
9
|
+
* @returns {void}
|
|
10
|
+
*/
|
|
4
11
|
export function if_block(node, fn) {
|
|
5
12
|
var anchor = node;
|
|
6
13
|
var has_branch = false;
|
|
14
|
+
/** @type {any} */
|
|
7
15
|
var condition = UNINITIALIZED;
|
|
16
|
+
/** @type {Block | null} */
|
|
8
17
|
var b = null;
|
|
9
18
|
|
|
19
|
+
/** @type {(fn: (anchor: Node) => void, flag?: boolean) => void} */
|
|
10
20
|
var set_branch = (fn, flag = true) => {
|
|
11
21
|
has_branch = true;
|
|
12
22
|
update_branch(flag, fn);
|
|
13
23
|
};
|
|
14
24
|
|
|
25
|
+
/** @type {(new_condition: any, fn: ((anchor: Node) => void) | null) => void} */
|
|
15
26
|
var update_branch = (new_condition, fn) => {
|
|
16
27
|
if (condition === (condition = new_condition)) return;
|
|
17
28
|
|