ripple 0.4.2 → 0.4.4
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 +164 -0
- package/package.json +10 -4
- package/src/constants.js +6 -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 +439 -0
- package/src/runtime/internal/client/blocks.js +20 -20
- package/src/runtime/internal/client/component.js +2 -5
- package/src/runtime/internal/client/composite.js +295 -95
- package/src/runtime/internal/client/constants.js +14 -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 +25 -120
- package/src/runtime/internal/client/for.js +113 -262
- 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 -81
- package/src/runtime/internal/client/if.js +69 -10
- package/src/runtime/internal/client/index.js +18 -10
- package/src/runtime/internal/client/operations.js +11 -7
- package/src/runtime/internal/client/portal.js +3 -2
- package/src/runtime/internal/client/render.js +42 -325
- package/src/runtime/internal/client/root-boundary-enabled.js +7 -0
- package/src/runtime/internal/client/runtime.js +157 -371
- package/src/runtime/internal/client/template-ns.js +88 -0
- package/src/runtime/internal/client/template.js +118 -139
- 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 +31 -29
- 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 +2 -2
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +3 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +40 -0
- package/tests/client/composite/composite.props.test.tsrx +10 -10
- package/tests/client/css/scoped-styles.test.tsrx +3 -1
- package/tests/client/derived-release.test.tsrx +3 -3
- package/tests/client/for-item.test.tsrx +39 -0
- package/tests/client/for-selector.test.tsrx +95 -0
- package/tests/client/svg.test.tsrx +273 -1
- package/tests/hydration/compiled/client/basic.js +88 -87
- package/tests/hydration/compiled/client/composite.js +15 -6
- package/tests/hydration/compiled/client/events.js +40 -48
- package/tests/hydration/compiled/client/for.js +191 -199
- package/tests/hydration/compiled/client/fragment-cursor.js +633 -334
- package/tests/hydration/compiled/client/head.js +22 -22
- package/tests/hydration/compiled/client/hmr.js +14 -5
- package/tests/hydration/compiled/client/html-in-template.js +5 -5
- package/tests/hydration/compiled/client/html.js +195 -177
- package/tests/hydration/compiled/client/if-children.js +136 -63
- package/tests/hydration/compiled/client/if-fragment-controlflow.js +63 -43
- package/tests/hydration/compiled/client/if.js +78 -30
- package/tests/hydration/compiled/client/mixed-control-flow.js +90 -72
- package/tests/hydration/compiled/client/nested-control-flow.js +266 -307
- package/tests/hydration/compiled/client/portal.js +20 -11
- package/tests/hydration/compiled/client/reactivity.js +29 -29
- package/tests/hydration/compiled/client/return.js +2 -2
- package/tests/hydration/compiled/client/streaming.js +33 -35
- 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 -7
- package/tests/hydration/compiled/server/basic.js +6 -6
- package/tests/hydration/compiled/server/events.js +8 -8
- package/tests/hydration/compiled/server/for.js +22 -22
- package/tests/hydration/compiled/server/fragment-cursor.js +188 -52
- 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/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,356 @@
|
|
|
1
|
+
/** @import { Block, DeferredTrackedEntry, Tracked } from '#client' */
|
|
2
|
+
|
|
3
|
+
import { pause_block, pre_effect } from './blocks.js';
|
|
4
|
+
import {
|
|
5
|
+
ASYNC_DERIVED_READ_THROWN,
|
|
6
|
+
DIRECT_CHILD_BLOCK,
|
|
7
|
+
SUSPENSE_PENDING,
|
|
8
|
+
SUSPENSE_REJECTED,
|
|
9
|
+
TRACKED,
|
|
10
|
+
TRACKED_UPDATED,
|
|
11
|
+
TRY_BLOCK,
|
|
12
|
+
} from './constants.js';
|
|
13
|
+
import { hydrating, track_hash_reference } from './hydration.js';
|
|
14
|
+
import { HYDRATION } from 'ripple/internal/client/hydration-enabled';
|
|
15
|
+
import {
|
|
16
|
+
active_block,
|
|
17
|
+
active_component,
|
|
18
|
+
active_dependency,
|
|
19
|
+
get,
|
|
20
|
+
is_mutating_allowed,
|
|
21
|
+
set_mutating_allowed,
|
|
22
|
+
set_pending_read_handler,
|
|
23
|
+
set_tracking,
|
|
24
|
+
tracked,
|
|
25
|
+
tracking,
|
|
26
|
+
update_tracked_value_clock,
|
|
27
|
+
} from './runtime.js';
|
|
28
|
+
import { is_ripple_object } from './utils.js';
|
|
29
|
+
import {
|
|
30
|
+
begin_boundary_request,
|
|
31
|
+
complete_boundary_request,
|
|
32
|
+
get_boundary_with_catch,
|
|
33
|
+
get_pending_boundary,
|
|
34
|
+
handle_boundary_error,
|
|
35
|
+
register_boundary_deferred,
|
|
36
|
+
register_boundary_paused_block,
|
|
37
|
+
replace_boundary_request,
|
|
38
|
+
} from './try.js';
|
|
39
|
+
import { get_async_track_result } from '../../../utils/async.js';
|
|
40
|
+
import { get_track_async_script_id } from '../../../utils/track-async-serialization.js';
|
|
41
|
+
import { revive } from './transport.js';
|
|
42
|
+
import {
|
|
43
|
+
pending_read_direct,
|
|
44
|
+
track_async_argument,
|
|
45
|
+
track_async_boundary,
|
|
46
|
+
track_async_orphan,
|
|
47
|
+
} from './errors.js';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* `trackAsync()` and everything a pending async read sets in motion: boundary
|
|
51
|
+
* requests, paused blocks, deferred rejections. The runtime reaches it through
|
|
52
|
+
* a handler the first `trackAsync()` installs, so an application without one
|
|
53
|
+
* ships none of it.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
var installed = false;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Complete all deferred boundary requests registered on a tracked value.
|
|
60
|
+
* @param {Tracked} t
|
|
61
|
+
* @param {boolean} [show_resolved=true]
|
|
62
|
+
*/
|
|
63
|
+
function complete_deferred_boundaries(t, show_resolved = true) {
|
|
64
|
+
if (t.d !== null) {
|
|
65
|
+
for (var i = 0; i < t.d.length; i++) {
|
|
66
|
+
var entry = t.d[i];
|
|
67
|
+
complete_boundary_request(entry.b, entry.r, show_resolved);
|
|
68
|
+
}
|
|
69
|
+
t.d = null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A block's run read a pending async value (it threw
|
|
75
|
+
* `ASYNC_DERIVED_READ_THROWN`, and the read was registered as a dependency):
|
|
76
|
+
* the block pauses under its pending boundary until the value settles, and
|
|
77
|
+
* a read straight from a component or boundary body is an error.
|
|
78
|
+
* @param {Block} block
|
|
79
|
+
*/
|
|
80
|
+
function handle_pending_read(block) {
|
|
81
|
+
var is_component_direct = active_component?.b === block;
|
|
82
|
+
var is_try_fn_block =
|
|
83
|
+
block.p !== null && (block.p.f & TRY_BLOCK) !== 0 && (block.f & DIRECT_CHILD_BLOCK) !== 0;
|
|
84
|
+
|
|
85
|
+
if (is_component_direct || is_try_fn_block) {
|
|
86
|
+
pending_read_direct(is_component_direct);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
var boundary = get_pending_boundary(block);
|
|
90
|
+
if (boundary === null) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
pause_block(block);
|
|
94
|
+
register_boundary_paused_block(boundary, block);
|
|
95
|
+
|
|
96
|
+
// Register deferred boundary completions for async tracked deps.
|
|
97
|
+
// This handles the case where a child boundary reads a tracked value
|
|
98
|
+
// whose resolution is managed by a different (parent) boundary.
|
|
99
|
+
var dep = block.d;
|
|
100
|
+
while (dep !== null) {
|
|
101
|
+
var dep_tracked = /** @type {Tracked} */ (dep.t);
|
|
102
|
+
if (
|
|
103
|
+
(dep_tracked.__v === SUSPENSE_PENDING || dep_tracked.__v === SUSPENSE_REJECTED) &&
|
|
104
|
+
(dep_tracked.f & TRACKED) !== 0
|
|
105
|
+
) {
|
|
106
|
+
var deferred_req = begin_boundary_request(boundary);
|
|
107
|
+
var entry = /** @type {DeferredTrackedEntry} */ ({ b: boundary, r: deferred_req });
|
|
108
|
+
if (dep_tracked.d === null) {
|
|
109
|
+
dep_tracked.d = [entry];
|
|
110
|
+
} else {
|
|
111
|
+
dep_tracked.d.push(entry);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
dep = dep.n;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {any} fn
|
|
120
|
+
* @param {Block} b
|
|
121
|
+
* @param {string} hash - Unique hash for SSR serialization/hydration
|
|
122
|
+
* @returns {Tracked | void}
|
|
123
|
+
*/
|
|
124
|
+
export function track_async(fn, b, hash) {
|
|
125
|
+
if (!installed) {
|
|
126
|
+
installed = true;
|
|
127
|
+
set_pending_read_handler(handle_pending_read);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (is_ripple_object(fn)) {
|
|
131
|
+
return fn;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
var target_block = b || active_block;
|
|
135
|
+
if (target_block === null) {
|
|
136
|
+
track_async_orphan();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (typeof fn !== 'function') {
|
|
140
|
+
track_async_argument();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// During hydration, attempt to read serialized data from SSR
|
|
144
|
+
var had_hydration_data = false;
|
|
145
|
+
var hydration_value;
|
|
146
|
+
/** @type {string[] | undefined} */
|
|
147
|
+
var hydration_deps;
|
|
148
|
+
|
|
149
|
+
if (HYDRATION && hydrating) {
|
|
150
|
+
var script_id = get_track_async_script_id(hash);
|
|
151
|
+
var script_el = document.getElementById(script_id);
|
|
152
|
+
if (script_el) {
|
|
153
|
+
var envelope = JSON.parse(/** @type {string} */ (script_el.textContent));
|
|
154
|
+
script_el.remove();
|
|
155
|
+
|
|
156
|
+
if (envelope.ok) {
|
|
157
|
+
had_hydration_data = true;
|
|
158
|
+
hydration_value =
|
|
159
|
+
envelope.payload === undefined ? envelope.value : revive(envelope.payload);
|
|
160
|
+
hydration_deps = envelope.deps;
|
|
161
|
+
} else {
|
|
162
|
+
// trigger the catch block
|
|
163
|
+
throw new Error(envelope.error?.message ?? 'Unknown server error');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
var t = tracked(had_hydration_data ? hydration_value : SUSPENSE_PENDING, target_block, hash);
|
|
169
|
+
|
|
170
|
+
// Capture the call-site block for boundary lookups. target_block is the
|
|
171
|
+
// component's block (passed by compiler), but the actual try/pending/catch
|
|
172
|
+
// boundary is an ancestor of active_block (the block executing trackAsync).
|
|
173
|
+
var call_site_block = /** @type {Block} */ (active_block);
|
|
174
|
+
|
|
175
|
+
var version = 0;
|
|
176
|
+
/** @type {AbortController | null} */
|
|
177
|
+
var abort_controller = null;
|
|
178
|
+
var request_id = 0;
|
|
179
|
+
/** @type {Block | null} */
|
|
180
|
+
var boundary = null;
|
|
181
|
+
|
|
182
|
+
// TODO: decide if instead of insisting on pending, we create our own boundary
|
|
183
|
+
// we currently require a pending block upstream but we could also
|
|
184
|
+
// create a try/pending/catch boundary at mount and hydration like
|
|
185
|
+
// we do on the server so that there is always a boundary present.
|
|
186
|
+
// It can handle global pending when none were provided.
|
|
187
|
+
// Not sure about the catch boundary because if none were provided,
|
|
188
|
+
// the whole app for any error will be unmounted with the catch block rendered
|
|
189
|
+
|
|
190
|
+
// Find boundary from the call-site block.
|
|
191
|
+
boundary = get_pending_boundary(active_block);
|
|
192
|
+
if (boundary === null) {
|
|
193
|
+
track_async_boundary();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// If we hydrated with resolved data, the SSR already completed this request.
|
|
197
|
+
// Otherwise mark a pending request on the boundary for the client-side run.
|
|
198
|
+
if (!had_hydration_data) {
|
|
199
|
+
request_id = begin_boundary_request(boundary);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
pre_effect(() => {
|
|
203
|
+
if (had_hydration_data) {
|
|
204
|
+
// First run after hydration: skip fn() entirely (the SSR already
|
|
205
|
+
// produced the resolved value) and instead register the direct
|
|
206
|
+
// dependencies from the serialized deps list so future dep changes
|
|
207
|
+
// trigger a re-run via the normal async path.
|
|
208
|
+
had_hydration_data = false;
|
|
209
|
+
if (hydration_deps !== undefined) {
|
|
210
|
+
for (var i = 0; i < hydration_deps.length; i++) {
|
|
211
|
+
var dep_ref = track_hash_reference.get(hydration_deps[i]);
|
|
212
|
+
if (dep_ref !== undefined) {
|
|
213
|
+
get(dep_ref);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var current_version = ++version;
|
|
221
|
+
|
|
222
|
+
// Abort previous in-flight request
|
|
223
|
+
if (abort_controller !== null && abort_controller.signal.aborted === false) {
|
|
224
|
+
abort_controller.abort(TRACKED_UPDATED);
|
|
225
|
+
}
|
|
226
|
+
abort_controller = null;
|
|
227
|
+
|
|
228
|
+
// Manage boundary request: replace if in-flight, or begin new if previous completed
|
|
229
|
+
if (request_id > 0 && boundary !== null) {
|
|
230
|
+
request_id = replace_boundary_request(boundary, request_id);
|
|
231
|
+
} else if (boundary !== null) {
|
|
232
|
+
request_id = begin_boundary_request(boundary);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Set to pending before calling fn() in case it's sync.
|
|
236
|
+
if (t.__v !== SUSPENSE_PENDING) {
|
|
237
|
+
update_tracked_value_clock(t, SUSPENSE_PENDING);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Temporarily allow mutations so set() doesn't throw inside the pre-effect
|
|
241
|
+
var previous_is_mutating_allowed = is_mutating_allowed;
|
|
242
|
+
set_mutating_allowed(true);
|
|
243
|
+
|
|
244
|
+
var result;
|
|
245
|
+
try {
|
|
246
|
+
result = fn();
|
|
247
|
+
} catch (e) {
|
|
248
|
+
set_mutating_allowed(previous_is_mutating_allowed);
|
|
249
|
+
if (e === ASYNC_DERIVED_READ_THROWN) {
|
|
250
|
+
// A dependency is still pending or rejected (e.g. chained trackAsync).
|
|
251
|
+
// Check if any dependency is rejected — if so, propagate rejection.
|
|
252
|
+
var dep = active_dependency;
|
|
253
|
+
while (dep !== null) {
|
|
254
|
+
if (dep.t.__v === SUSPENSE_REJECTED) {
|
|
255
|
+
update_tracked_value_clock(t, SUSPENSE_REJECTED);
|
|
256
|
+
complete_deferred_boundaries(t, false);
|
|
257
|
+
if (request_id > 0 && boundary !== null) {
|
|
258
|
+
complete_boundary_request(boundary, request_id, false);
|
|
259
|
+
request_id = 0;
|
|
260
|
+
}
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
dep = dep.n;
|
|
264
|
+
}
|
|
265
|
+
// Dependencies are pending, not rejected — register deferred
|
|
266
|
+
// rejection so that if the boundary goes to catch mode, this
|
|
267
|
+
// tracked value is also set to REJECTED.
|
|
268
|
+
if (request_id > 0 && boundary !== null) {
|
|
269
|
+
register_boundary_deferred(boundary, request_id, () => {
|
|
270
|
+
update_tracked_value_clock(t, SUSPENSE_REJECTED);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
throw e;
|
|
276
|
+
}
|
|
277
|
+
set_mutating_allowed(previous_is_mutating_allowed);
|
|
278
|
+
|
|
279
|
+
// Check if the result is async
|
|
280
|
+
var previous_tracking = tracking;
|
|
281
|
+
set_tracking(false);
|
|
282
|
+
var async_result = get_async_track_result(result);
|
|
283
|
+
set_tracking(previous_tracking);
|
|
284
|
+
|
|
285
|
+
if (async_result === null) {
|
|
286
|
+
// Sync result
|
|
287
|
+
update_tracked_value_clock(t, result);
|
|
288
|
+
if (request_id > 0 && boundary !== null) {
|
|
289
|
+
complete_boundary_request(boundary, request_id);
|
|
290
|
+
request_id = 0;
|
|
291
|
+
}
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Capture per-invocation so async closures (rejection handler, teardown)
|
|
296
|
+
// have a stable reference. The shared abort_controller is only read
|
|
297
|
+
// synchronously at the top of the pre_effect to abort the previous request.
|
|
298
|
+
var current_abort_controller = async_result.abort_controller;
|
|
299
|
+
abort_controller = current_abort_controller;
|
|
300
|
+
|
|
301
|
+
async_result.promise.then(
|
|
302
|
+
(resolved) => {
|
|
303
|
+
if (current_version !== version) {
|
|
304
|
+
// stale
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
update_tracked_value_clock(t, resolved);
|
|
308
|
+
complete_deferred_boundaries(t);
|
|
309
|
+
if (request_id > 0 && boundary !== null) {
|
|
310
|
+
complete_boundary_request(boundary, request_id);
|
|
311
|
+
request_id = 0;
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
(error) => {
|
|
315
|
+
if (current_version !== version) return; // stale
|
|
316
|
+
|
|
317
|
+
var is_internal_abort =
|
|
318
|
+
error === TRACKED_UPDATED || current_abort_controller?.signal?.reason === TRACKED_UPDATED;
|
|
319
|
+
if (is_internal_abort) {
|
|
320
|
+
// Internal abort (superseded by a new request) — don't set rejected
|
|
321
|
+
if (request_id > 0 && boundary !== null) {
|
|
322
|
+
complete_boundary_request(boundary, request_id, false);
|
|
323
|
+
request_id = 0;
|
|
324
|
+
}
|
|
325
|
+
complete_deferred_boundaries(t, false);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
update_tracked_value_clock(t, SUSPENSE_REJECTED);
|
|
330
|
+
complete_deferred_boundaries(t, false);
|
|
331
|
+
|
|
332
|
+
// Route error to catch boundary
|
|
333
|
+
var boundary_with_catch = get_boundary_with_catch(call_site_block);
|
|
334
|
+
if (boundary_with_catch !== null) {
|
|
335
|
+
handle_boundary_error(boundary_with_catch, error);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (request_id > 0 && boundary !== null) {
|
|
339
|
+
var should_show_resolved =
|
|
340
|
+
boundary_with_catch === boundary || boundary === null ? false : true;
|
|
341
|
+
complete_boundary_request(boundary, request_id, should_show_resolved);
|
|
342
|
+
request_id = 0;
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
return () => {
|
|
348
|
+
// Teardown: abort in-flight request when block is destroyed
|
|
349
|
+
if (current_abort_controller !== null && current_abort_controller.signal.aborted === false) {
|
|
350
|
+
current_abort_controller.abort(TRACKED_UPDATED);
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
return t;
|
|
356
|
+
}
|