UNPKG

12 kBJavaScriptView Raw
1/** @license React v0.15.0
2 * scheduler-tracing.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18Object.defineProperty(exports, '__esModule', { value: true });
19
20// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
21
22
23// In some cases, StrictMode should also double-render lifecycles.
24// This can be confusing for tests though,
25// And it can be bad for performance in production.
26// This feature flag can be used to control the behavior:
27
28
29// To preserve the "Pause on caught exceptions" behavior of the debugger, we
30// replay the begin phase of a failed component inside invokeGuardedCallback.
31
32
33// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
34
35
36// Gather advanced timing metrics for Profiler subtrees.
37
38
39// Trace which interactions trigger each commit.
40var enableSchedulerTracing = true;
41
42// Only used in www builds.
43 // TODO: true? Here it might just be false.
44
45// Only used in www builds.
46
47
48// Only used in www builds.
49
50
51// Disable javascript: URL strings in href for XSS protection.
52
53
54// React Fire: prevent the value and checked attributes from syncing
55// with their related DOM properties
56
57
58// These APIs will no longer be "unstable" in the upcoming 16.7 release,
59// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
60
61
62
63
64// See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information
65// This is a flag so we can fix warnings in RN core before turning it on
66
67
68// Experimental React Flare event system and event components support.
69
70
71// Experimental Host Component support.
72
73
74// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
75
76
77// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
78// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version
79
80// Temporary flag to revert the fix in #15650
81
82
83// For tests, we flush suspense fallbacks in an act scope;
84// *except* in some of our own tests, where we test incremental loading states.
85
86
87// Changes priority of some events like mousemove to user-blocking priority,
88// but without making them discrete. The flag exists in case it causes
89// starvation problems.
90
91
92// Add a callback property to suspense to notify which promises are currently
93// in the update queue. This allows reporting and tracing of what is causing
94// the user to see a loading state.
95
96
97// Part of the simplification of React.createElement so we can eventually move
98// from React.createElement to React.jsx
99// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
100
101var DEFAULT_THREAD_ID = 0;
102
103// Counters used to generate unique IDs.
104var interactionIDCounter = 0;
105var threadIDCounter = 0;
106
107// Set of currently traced interactions.
108// Interactions "stack"–
109// Meaning that newly traced interactions are appended to the previously active set.
110// When an interaction goes out of scope, the previous set (if any) is restored.
111exports.__interactionsRef = null;
112
113// Listener(s) to notify when interactions begin and end.
114exports.__subscriberRef = null;
115
116if (enableSchedulerTracing) {
117 exports.__interactionsRef = {
118 current: new Set()
119 };
120 exports.__subscriberRef = {
121 current: null
122 };
123}
124
125function unstable_clear(callback) {
126 if (!enableSchedulerTracing) {
127 return callback();
128 }
129
130 var prevInteractions = exports.__interactionsRef.current;
131 exports.__interactionsRef.current = new Set();
132
133 try {
134 return callback();
135 } finally {
136 exports.__interactionsRef.current = prevInteractions;
137 }
138}
139
140function unstable_getCurrent() {
141 if (!enableSchedulerTracing) {
142 return null;
143 } else {
144 return exports.__interactionsRef.current;
145 }
146}
147
148function unstable_getThreadID() {
149 return ++threadIDCounter;
150}
151
152function unstable_trace(name, timestamp, callback) {
153 var threadID = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : DEFAULT_THREAD_ID;
154
155 if (!enableSchedulerTracing) {
156 return callback();
157 }
158
159 var interaction = {
160 __count: 1,
161 id: interactionIDCounter++,
162 name: name,
163 timestamp: timestamp
164 };
165
166 var prevInteractions = exports.__interactionsRef.current;
167
168 // Traced interactions should stack/accumulate.
169 // To do that, clone the current interactions.
170 // The previous set will be restored upon completion.
171 var interactions = new Set(prevInteractions);
172 interactions.add(interaction);
173 exports.__interactionsRef.current = interactions;
174
175 var subscriber = exports.__subscriberRef.current;
176 var returnValue = void 0;
177
178 try {
179 if (subscriber !== null) {
180 subscriber.onInteractionTraced(interaction);
181 }
182 } finally {
183 try {
184 if (subscriber !== null) {
185 subscriber.onWorkStarted(interactions, threadID);
186 }
187 } finally {
188 try {
189 returnValue = callback();
190 } finally {
191 exports.__interactionsRef.current = prevInteractions;
192
193 try {
194 if (subscriber !== null) {
195 subscriber.onWorkStopped(interactions, threadID);
196 }
197 } finally {
198 interaction.__count--;
199
200 // If no async work was scheduled for this interaction,
201 // Notify subscribers that it's completed.
202 if (subscriber !== null && interaction.__count === 0) {
203 subscriber.onInteractionScheduledWorkCompleted(interaction);
204 }
205 }
206 }
207 }
208 }
209
210 return returnValue;
211}
212
213function unstable_wrap(callback) {
214 var threadID = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_THREAD_ID;
215
216 if (!enableSchedulerTracing) {
217 return callback;
218 }
219
220 var wrappedInteractions = exports.__interactionsRef.current;
221
222 var subscriber = exports.__subscriberRef.current;
223 if (subscriber !== null) {
224 subscriber.onWorkScheduled(wrappedInteractions, threadID);
225 }
226
227 // Update the pending async work count for the current interactions.
228 // Update after calling subscribers in case of error.
229 wrappedInteractions.forEach(function (interaction) {
230 interaction.__count++;
231 });
232
233 var hasRun = false;
234
235 function wrapped() {
236 var prevInteractions = exports.__interactionsRef.current;
237 exports.__interactionsRef.current = wrappedInteractions;
238
239 subscriber = exports.__subscriberRef.current;
240
241 try {
242 var returnValue = void 0;
243
244 try {
245 if (subscriber !== null) {
246 subscriber.onWorkStarted(wrappedInteractions, threadID);
247 }
248 } finally {
249 try {
250 returnValue = callback.apply(undefined, arguments);
251 } finally {
252 exports.__interactionsRef.current = prevInteractions;
253
254 if (subscriber !== null) {
255 subscriber.onWorkStopped(wrappedInteractions, threadID);
256 }
257 }
258 }
259
260 return returnValue;
261 } finally {
262 if (!hasRun) {
263 // We only expect a wrapped function to be executed once,
264 // But in the event that it's executed more than once–
265 // Only decrement the outstanding interaction counts once.
266 hasRun = true;
267
268 // Update pending async counts for all wrapped interactions.
269 // If this was the last scheduled async work for any of them,
270 // Mark them as completed.
271 wrappedInteractions.forEach(function (interaction) {
272 interaction.__count--;
273
274 if (subscriber !== null && interaction.__count === 0) {
275 subscriber.onInteractionScheduledWorkCompleted(interaction);
276 }
277 });
278 }
279 }
280 }
281
282 wrapped.cancel = function cancel() {
283 subscriber = exports.__subscriberRef.current;
284
285 try {
286 if (subscriber !== null) {
287 subscriber.onWorkCanceled(wrappedInteractions, threadID);
288 }
289 } finally {
290 // Update pending async counts for all wrapped interactions.
291 // If this was the last scheduled async work for any of them,
292 // Mark them as completed.
293 wrappedInteractions.forEach(function (interaction) {
294 interaction.__count--;
295
296 if (subscriber && interaction.__count === 0) {
297 subscriber.onInteractionScheduledWorkCompleted(interaction);
298 }
299 });
300 }
301 };
302
303 return wrapped;
304}
305
306var subscribers = null;
307if (enableSchedulerTracing) {
308 subscribers = new Set();
309}
310
311function unstable_subscribe(subscriber) {
312 if (enableSchedulerTracing) {
313 subscribers.add(subscriber);
314
315 if (subscribers.size === 1) {
316 exports.__subscriberRef.current = {
317 onInteractionScheduledWorkCompleted: onInteractionScheduledWorkCompleted,
318 onInteractionTraced: onInteractionTraced,
319 onWorkCanceled: onWorkCanceled,
320 onWorkScheduled: onWorkScheduled,
321 onWorkStarted: onWorkStarted,
322 onWorkStopped: onWorkStopped
323 };
324 }
325 }
326}
327
328function unstable_unsubscribe(subscriber) {
329 if (enableSchedulerTracing) {
330 subscribers.delete(subscriber);
331
332 if (subscribers.size === 0) {
333 exports.__subscriberRef.current = null;
334 }
335 }
336}
337
338function onInteractionTraced(interaction) {
339 var didCatchError = false;
340 var caughtError = null;
341
342 subscribers.forEach(function (subscriber) {
343 try {
344 subscriber.onInteractionTraced(interaction);
345 } catch (error) {
346 if (!didCatchError) {
347 didCatchError = true;
348 caughtError = error;
349 }
350 }
351 });
352
353 if (didCatchError) {
354 throw caughtError;
355 }
356}
357
358function onInteractionScheduledWorkCompleted(interaction) {
359 var didCatchError = false;
360 var caughtError = null;
361
362 subscribers.forEach(function (subscriber) {
363 try {
364 subscriber.onInteractionScheduledWorkCompleted(interaction);
365 } catch (error) {
366 if (!didCatchError) {
367 didCatchError = true;
368 caughtError = error;
369 }
370 }
371 });
372
373 if (didCatchError) {
374 throw caughtError;
375 }
376}
377
378function onWorkScheduled(interactions, threadID) {
379 var didCatchError = false;
380 var caughtError = null;
381
382 subscribers.forEach(function (subscriber) {
383 try {
384 subscriber.onWorkScheduled(interactions, threadID);
385 } catch (error) {
386 if (!didCatchError) {
387 didCatchError = true;
388 caughtError = error;
389 }
390 }
391 });
392
393 if (didCatchError) {
394 throw caughtError;
395 }
396}
397
398function onWorkStarted(interactions, threadID) {
399 var didCatchError = false;
400 var caughtError = null;
401
402 subscribers.forEach(function (subscriber) {
403 try {
404 subscriber.onWorkStarted(interactions, threadID);
405 } catch (error) {
406 if (!didCatchError) {
407 didCatchError = true;
408 caughtError = error;
409 }
410 }
411 });
412
413 if (didCatchError) {
414 throw caughtError;
415 }
416}
417
418function onWorkStopped(interactions, threadID) {
419 var didCatchError = false;
420 var caughtError = null;
421
422 subscribers.forEach(function (subscriber) {
423 try {
424 subscriber.onWorkStopped(interactions, threadID);
425 } catch (error) {
426 if (!didCatchError) {
427 didCatchError = true;
428 caughtError = error;
429 }
430 }
431 });
432
433 if (didCatchError) {
434 throw caughtError;
435 }
436}
437
438function onWorkCanceled(interactions, threadID) {
439 var didCatchError = false;
440 var caughtError = null;
441
442 subscribers.forEach(function (subscriber) {
443 try {
444 subscriber.onWorkCanceled(interactions, threadID);
445 } catch (error) {
446 if (!didCatchError) {
447 didCatchError = true;
448 caughtError = error;
449 }
450 }
451 });
452
453 if (didCatchError) {
454 throw caughtError;
455 }
456}
457
458exports.unstable_clear = unstable_clear;
459exports.unstable_getCurrent = unstable_getCurrent;
460exports.unstable_getThreadID = unstable_getThreadID;
461exports.unstable_trace = unstable_trace;
462exports.unstable_wrap = unstable_wrap;
463exports.unstable_subscribe = unstable_subscribe;
464exports.unstable_unsubscribe = unstable_unsubscribe;
465 })();
466}