-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.d.ts
executable file
·1083 lines (919 loc) · 41.4 KB
/
index.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
168
169
170
171
172
173
174
175
176
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Type definitions for react-reconciler 0.26
// Project: https://reactjs.org/
// Definitions by: Nathan Bierema <https://github.com/Methuselah96>
// Zhang Haocong <https://github.com/zhanghaocong>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
// @ts-ignore
import { Component, ReactNode } from 'react';
declare function ReactReconciler<
Type,
Props,
Container,
Instance,
TextInstance,
SuspenseInstance,
HydratableInstance,
PublicInstance,
HostContext,
UpdatePayload,
ChildSet,
TimeoutHandle,
NoTimeout
>(
config: ReactReconciler.HostConfig<
// tslint:disable:no-unnecessary-generics
Type,
Props,
Container,
Instance,
TextInstance,
SuspenseInstance,
HydratableInstance,
PublicInstance,
HostContext,
UpdatePayload,
ChildSet,
TimeoutHandle,
NoTimeout
// tslint:enable:no-unnecessary-generics
>,
): ReactReconciler.Reconciler<
Container,
Instance,
TextInstance,
SuspenseInstance,
PublicInstance
>;
declare namespace ReactReconciler {
interface HostConfig<
Type,
Props,
Container,
Instance,
TextInstance,
SuspenseInstance,
HydratableInstance,
PublicInstance,
HostContext,
UpdatePayload,
_ChildSet, // TODO Placeholder for undocumented API
TimeoutHandle,
NoTimeout
> {
// -------------------
// Modes
// -------------------
// tslint:disable:max-line-length
/**
*
* The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.
*
* If your target platform is similar to the DOM and has methods similar to `appendChild`, `removeChild`, and so on, you'll want to use the **mutation mode**. This is the same mode used by React DOM, React ART, and the classic React Native renderer.
*
* ```js
* const HostConfig = {
* // ...
* supportsMutation: true,
* // ...
* }
* ```
*/
// tslint:enable:max-line-length
supportsMutation: boolean;
// tslint:disable:max-line-length
/**
* If your target platform has immutable trees, you'll want the **persistent mode** instead. In that mode, existing nodes are never mutated, and instead every change clones the parent tree and then replaces the whole parent tree at the root. This is the node used by the new React Native renderer, codenamed "Fabric".
*
* ```js
* const HostConfig = {
* // ...
* supportsPersistence: true,
* // ...
* }
* ```
*
* Depending on the mode, the reconciler will call different methods on your host config.
*
* If you're not sure which one you want, you likely need the mutation mode.
*/
// tslint:enable:max-line-length
supportsPersistence: boolean;
// -------------------
// Core Methods
// -------------------
// tslint:disable:max-line-length
/**
* This method should return a newly created node. For example, the DOM renderer would call `document.createElement(type)` here and then set the properties from `props`.
*
* You can use `rootContainer` to access the root container associated with that tree. For example, in the DOM renderer, this is useful to get the correct `document` reference that the root belongs to.
*
* The `hostContext` parameter lets you keep track of some information about your current place in the tree. To learn more about it, see `getChildHostContext` below.
*
* The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields, be aware that it may change significantly between versions. You're taking on additional maintenance risk by reading from it, and giving up all guarantees if you write something to it.
*
* This method happens **in the render phase**. It can (and usually should) mutate the node it has just created before returning it, but it must not modify any other nodes. It must not register any event handlers on the parent tree. This is because an instance being created doesn't guarantee it would be placed in the tree — it could be left unused and later collected by GC. If you need to do something when an instance is definitely in the tree, look at `commitMount` instead.
*/
// tslint:enable:max-line-length
createInstance(
type: Type,
props: Props,
rootContainer: Container,
hostContext: HostContext,
internalHandle: OpaqueHandle,
): Instance;
// tslint:disable:max-line-length
/**
* Same as `createInstance`, but for text nodes. If your renderer doesn't support text nodes, you can throw here.
*/
// tslint:enable:max-line-length
createTextInstance(
text: string,
rootContainer: Container,
hostContext: HostContext,
internalHandle: OpaqueHandle,
): TextInstance;
// tslint:disable:max-line-length
/**
* This method should mutate the `parentInstance` and add the child to its list of children. For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.
*
* This method happens **in the render phase**. It can mutate `parentInstance` and `child`, but it must not modify any other nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.
*/
// tslint:enable:max-line-length
appendInitialChild(parentInstance: Instance, child: Instance | TextInstance): void;
// tslint:disable:max-line-length
/**
* In this method, you can perform some final mutations on the `instance`. Unlike with `createInstance`, by the time `finalizeInitialChildren` is called, all the initial children have already been added to the `instance`, but the instance itself has not yet been connected to the tree on the screen.
*
* This method happens **in the render phase**. It can mutate `instance`, but it must not modify any other nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.
*
* There is a second purpose to this method. It lets you specify whether there is some work that needs to happen when the node is connected to the tree on the screen. If you return `true`, the instance will receive a `commitMount` call later. See its documentation below.
*
* If you don't want to do anything here, you should return `false`.
*/
// tslint:enable:max-line-length
finalizeInitialChildren(
instance: Instance,
type: Type,
props: Props,
rootContainer: Container,
hostContext: HostContext,
): boolean;
// tslint:disable:max-line-length
/**
* React calls this method so that you can compare the previous and the next props, and decide whether you need to update the underlying instance or not. If you don't need to update it, return `null`. If you need to update it, you can return an arbitrary object representing the changes that need to happen. Then in `commitUpdate` you would need to apply those changes to the instance.
*
* This method happens **in the render phase**. It should only *calculate* the update — but not apply it! For example, the DOM renderer returns an array that looks like `[prop1, value1, prop2, value2, ...]` for all props that have actually changed. And only in `commitUpdate` it applies those changes. You should calculate as much as you can in `prepareUpdate` so that `commitUpdate` can be very fast and straightforward.
*
* See the meaning of `rootContainer` and `hostContext` in the `createInstance` documentation.
*/
// tslint:enable:max-line-length
prepareUpdate(
instance: Instance,
type: Type,
oldProps: Props,
newProps: Props,
rootContainer: Container,
hostContext: HostContext,
): UpdatePayload | null;
// tslint:disable:max-line-length
/**
* Some target platforms support setting an instance's text content without manually creating a text node. For example, in the DOM, you can set `node.textContent` instead of creating a text node and appending it.
*
* If you return `true` from this method, React will assume that this node's children are text, and will not create nodes for them. It will instead rely on you to have filled that text during `createInstance`. This is a performance optimization. For example, the DOM renderer returns `true` only if `type` is a known text-only parent (like `'textarea'`) or if `props.children` has a `'string'` type. If you return `true`, you will need to implement `resetTextContent` too.
*
* If you don't want to do anything here, you should return `false`.
*
* This method happens **in the render phase**. Do not mutate the tree from it.
*/
// tslint:enable:max-line-length
shouldSetTextContent(type: Type, props: Props): boolean;
// tslint:disable:max-line-length
/**
* This method lets you return the initial host context from the root of the tree. See `getChildHostContext` for the explanation of host context.
*
* If you don't intend to use host context, you can return `null`.
*
* This method happens **in the render phase**. Do not mutate the tree from it.
*/
// tslint:enable:max-line-length
getRootHostContext(rootContainer: Container): HostContext | null;
// tslint:disable:max-line-length
/**
* Host context lets you track some information about where you are in the tree so that it's available inside `createInstance` as the `hostContext` parameter. For example, the DOM renderer uses it to track whether it's inside an HTML or an SVG tree, because `createInstance` implementation needs to be different for them.
*
* If the node of this `type` does not influence the context you want to pass down, you can return `parentHostContext`. Alternatively, you can return any custom object representing the information you want to pass down.
*
* If you don't want to do anything here, return `parentHostContext`.
*
* This method happens **in the render phase**. Do not mutate the tree from it.
*/
// tslint:enable:max-line-length
getChildHostContext(parentHostContext: HostContext, type: Type, rootContainer: Container): HostContext;
// tslint:disable:max-line-length
/**
* Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But in some cases it might make sense to only expose some part of it.
*
* If you don't want to do anything here, return `instance`.
*/
// tslint:enable:max-line-length
getPublicInstance(instance: Instance | TextInstance): PublicInstance;
// tslint:disable:max-line-length
/**
* This method lets you store some information before React starts making changes to the tree on the screen. For example, the DOM renderer stores the current text selection so that it can later restore it. This method is mirrored by `resetAfterCommit`.
*
* Even if you don't want to do anything here, you need to return `null` from it.
*/
// tslint:enable:max-line-length
prepareForCommit(containerInfo: Container): Record<string, any> | null;
// tslint:disable:max-line-length
/**
* This method is called right after React has performed the tree mutations. You can use it to restore something you've stored in `prepareForCommit` — for example, text selection.
*
* You can leave it empty.
*/
// tslint:enable:max-line-length
resetAfterCommit(containerInfo: Container): void;
/**
* This method is called for a container that's used as a portal target. Usually you can leave it empty.
*/
preparePortalMount(containerInfo: Container): void;
/**
* You can proxy this to `performance.now()` or its equivalent in your environment.
*/
now(): number;
/**
* You can proxy this to `setTimeout` or its equivalent in your environment.
*/
scheduleTimeout(fn: (...args: unknown[]) => unknown, delay?: number): TimeoutHandle;
/**
* You can proxy this to `clearTimeout` or its equivalent in your environment.
*/
cancelTimeout(id: TimeoutHandle): void;
/**
* This is a property (not a function) that should be set to something that can never be a valid timeout ID. For example, you can set it to `-1`.
*/
noTimeout: NoTimeout;
// tslint:disable:max-line-length
/**
* This is a property (not a function) that should be set to `true` if your renderer is the main one on the page. For example, if you're writing a renderer for the Terminal, it makes sense to set it to `true`, but if your renderer is used *on top of* React DOM or some other existing renderer, set it to `false`.
*/
// tslint:enable:max-line-length
isPrimaryRenderer: boolean;
// -------------------
// Mutation Methods
// (optional)
// If you're using React in mutation mode (you probably do), you'll need to implement a few more methods.
// -------------------
// tslint:disable:max-line-length
/**
* This method should mutate the `parentInstance` and add the child to its list of children. For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.
*
* Although this method currently runs in the commit phase, you still should not mutate any other nodes in it. If you need to do some additional work when a node is definitely connected to the visible tree, look at `commitMount`.
*/
// tslint:enable:max-line-length
appendChild?(parentInstance: Instance, child: Instance | TextInstance): void;
// tslint:disable:max-line-length
/**
* Same as `appendChild`, but for when a node is attached to the root container. This is useful if attaching to the root has a slightly different implementation, or if the root container nodes are of a different type than the rest of the tree.
*/
// tslint:enable:max-line-length
appendChildToContainer?(container: Container, child: Instance | TextInstance): void;
// tslint:disable:max-line-length
/**
* This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list of its children. For example, in the DOM this would translate to a `parentInstance.insertBefore(child, beforeChild)` call.
*
* Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is expected that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts of the tree from it.
*/
// tslint:enable:max-line-length
insertBefore?(parentInstance: Instance, child: Instance | TextInstance, beforeChild: Instance | TextInstance | SuspenseInstance): void;
// tslint:disable:max-line-length
/**
* Same as `insertBefore`, but for when a node is attached to the root container. This is useful if attaching to the root has a slightly different implementation, or if the root container nodes are of a different type than the rest of the tree.
*/
// tslint:enable:max-line-length
insertInContainerBefore?(
container: Container,
child: Instance | TextInstance,
beforeChild: Instance | TextInstance | SuspenseInstance,
): void;
// tslint:disable:max-line-length
/**
* This method should mutate the `parentInstance` to remove the `child` from the list of its children.
*
* React will only call it for the top-level node that is being removed. It is expected that garbage collection would take care of the whole subtree. You are not expected to traverse the child tree in it.
*/
// tslint:enable:max-line-length
removeChild?(parentInstance: Instance, child: Instance | TextInstance | SuspenseInstance): void;
// tslint:disable:max-line-length
/**
* Same as `removeChild`, but for when a node is detached from the root container. This is useful if attaching to the root has a slightly different implementation, or if the root container nodes are of a different type than the rest of the tree.
*/
// tslint:enable:max-line-length
removeChildFromContainer?(container: Container, child: Instance | TextInstance | SuspenseInstance): void;
// tslint:disable:max-line-length
/**
* If you returned `true` from `shouldSetTextContent` for the previous props, but returned `false` from `shouldSetTextContent` for the next props, React will call this method so that you can clear the text content you were managing manually. For example, in the DOM you could set `node.textContent = ''`.
*
* If you never return `true` from `shouldSetTextContent`, you can leave it empty.
*/
// tslint:enable:max-line-length
resetTextContent?(instance: Instance): void;
/**
* This method should mutate the `textInstance` and update its text content to `nextText`.
*
* Here, `textInstance` is a node created by `createTextInstance`.
*/
commitTextUpdate?(textInstance: TextInstance, oldText: string, newText: string): void;
// tslint:disable:max-line-length
/**
* This method is only called if you returned `true` from `finalizeInitialChildren` for this instance.
*
* It lets you do some additional work after the node is actually attached to the tree on the screen for the first time. For example, the DOM renderer uses it to trigger focus on nodes with the `autoFocus` attribute.
*
* Note that `commitMount` does not mirror `removeChild` one to one because `removeChild` is only called for the top-level removed node. This is why ideally `commitMount` should not mutate any nodes other than the `instance` itself. For example, if it registers some events on some node above, it will be your responsibility to traverse the tree in `removeChild` and clean them up, which is not ideal.
*
* The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields, be aware that it may change significantly between versions. You're taking on additional maintenance risk by reading from it, and giving up all guarantees if you write something to it.
*
* If you never return `true` from `finalizeInitialChildren`, you can leave it empty.
*/
// tslint:enable:max-line-length
commitMount?(
instance: Instance,
type: Type,
props: Props,
internalInstanceHandle: OpaqueHandle,
): void;
// tslint:disable:max-line-length
/**
* This method should mutate the `instance` according to the set of changes in `updatePayload`. Here, `updatePayload` is the object that you've returned from `prepareUpdate` and has an arbitrary structure that makes sense for your renderer. For example, the DOM renderer returns an update payload like `[prop1, value1, prop2, value2, ...]` from `prepareUpdate`, and that structure gets passed into `commitUpdate`. Ideally, all the diffing and calculation should happen inside `prepareUpdate` so that `commitUpdate` can be fast and straightforward.
*
* The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields, be aware that it may change significantly between versions. You're taking on additional maintenance risk by reading from it, and giving up all guarantees if you write something to it.
*/
// tslint:enable:max-line-length
commitUpdate?(
instance: Instance,
updatePayload: UpdatePayload,
type: Type,
prevProps: Props,
nextProps: Props,
internalHandle: OpaqueHandle,
): void;
// tslint:disable:max-line-length
/**
* This method should make the `instance` invisible without removing it from the tree. For example, it can apply visual styling to hide it. It is used by Suspense to hide the tree while the fallback is visible.
*/
// tslint:enable:max-line-length
hideInstance?(instance: Instance): void;
/**
* Same as `hideInstance`, but for nodes created by `createTextInstance`.
*/
hideTextInstance?(textInstance: TextInstance): void;
/**
* This method should make the `instance` visible, undoing what `hideInstance` did.
*/
unhideInstance?(instance: Instance, props: Props): void;
/**
* Same as `unhideInstance`, but for nodes created by `createTextInstance`.
*/
unhideTextInstance?(textInstance: TextInstance, text: string): void;
/**
* This method should mutate the `container` root node and remove all children from it.
*/
clearContainer?(container: Container): void;
// tslint:disable:max-line-length
// -------------------
// Persistence Methods
// (optional)
// If you use the persistent mode instead of the mutation mode, you would still need the "Core Methods". However, instead of the Mutation Methods above you will implement a different set of methods that performs cloning nodes and replacing them at the root level. You can find a list of them in the "Persistence" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js). File an issue if you need help.
// -------------------
// tslint:enable:max-line-length
cloneInstance?: any;
cloneFundamentalInstance?: any;
createContainerChildSet?: any;
appendChildToContainerChildSet?: any;
finalizeContainerChildren?: any;
replaceContainerChildren?: any;
cloneHiddenInstance?: any;
cloneHiddenTextInstance?: any;
// tslint:disable:max-line-length
// -------------------
// Hydration Methods
// (optional)
// You can optionally implement hydration to "attach" to the existing tree during the initial render instead of creating it from scratch. For example, the DOM renderer uses this to attach to an HTML markup.
//
// To support hydration, you need to declare `supportsHydration: true` and then implement the methods in the "Hydration" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js). File an issue if you need help.
// -------------------
// tslint:enable:max-line-length
supportsHydration: boolean;
canHydrateInstance?(
instance: HydratableInstance,
type: Type,
props: Props,
): null | Instance;
canHydrateTextInstance?(
instance: HydratableInstance,
text: string,
): null | TextInstance;
canHydrateSuspenseInstance?(
instance: HydratableInstance,
): null | SuspenseInstance;
isSuspenseInstancePending?(instance: SuspenseInstance): boolean;
isSuspenseInstanceFallback?(instance: SuspenseInstance): boolean;
registerSuspenseInstanceRetry?(
instance: SuspenseInstance,
callback: () => void,
): void;
getNextHydratableSibling?(
instance: HydratableInstance,
): null | HydratableInstance;
getFirstHydratableChild?(
parentInstance: Container | Instance,
): null | HydratableInstance;
hydrateInstance?(
instance: Instance,
type: Type,
props: Props,
rootContainerInstance: Container,
hostContext: HostContext,
internalInstanceHandle: any,
): null | any[];
hydrateTextInstance?(
textInstance: TextInstance,
text: string,
internalInstanceHandle: any,
): boolean;
hydrateSuspenseInstance?(
suspenseInstance: SuspenseInstance,
internalInstanceHandle: any,
): void;
getNextHydratableInstanceAfterSuspenseInstance?(
suspenseInstance: SuspenseInstance,
): null | HydratableInstance;
// Returns the SuspenseInstance if this node is a direct child of a
// SuspenseInstance. I.e. if its previous sibling is a Comment with
// SUSPENSE_x_START_DATA. Otherwise, null.
getParentSuspenseInstance?(
targetInstance: any,
): null | SuspenseInstance;
commitHydratedContainer?(container: Container): void;
commitHydratedSuspenseInstance?(
suspenseInstance: SuspenseInstance,
): void;
didNotMatchHydratedContainerTextInstance?(
parentContainer: Container,
textInstance: TextInstance,
text: string,
): void;
didNotMatchHydratedTextInstance?(
parentType: Type,
parentProps: Props,
parentInstance: Instance,
textInstance: TextInstance,
text: string,
): void;
didNotHydrateContainerInstance?(
parentContainer: Container,
instance: HydratableInstance,
): void;
didNotHydrateInstance?(
parentType: Type,
parentProps: Props,
parentInstance: Instance,
instance: HydratableInstance,
): void;
didNotFindHydratableContainerInstance?(
parentContainer: Container,
type: Type,
props: Props,
): void;
didNotFindHydratableContainerTextInstance?(
parentContainer: Container,
text: string,
): void;
didNotFindHydratableContainerSuspenseInstance?(
parentContainer: Container,
): void;
didNotFindHydratableInstance?(
parentType: Type,
parentProps: Props,
parentInstance: Instance,
type: Type,
props: Props,
): void;
didNotFindHydratableTextInstance?(
parentType: Type,
parentProps: Props,
parentInstance: Instance,
text: string,
): void;
didNotFindHydratableSuspenseInstance?(
parentType: Type,
parentProps: Props,
parentInstance: Instance,
): void;
}
interface Thenable<T> {
then(resolve: () => T, reject?: () => T): T;
}
type RootTag = 0 | 1 | 2;
type WorkTag =
| 0
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
| 13
| 14
| 15
| 16
| 17
| 18
| 19
| 20
| 21
| 22
| 23
| 24;
type HookType =
| "useState"
| "useReducer"
| "useContext"
| "useRef"
| "useEffect"
| "useLayoutEffect"
| "useCallback"
| "useMemo"
| "useImperativeHandle"
| "useDebugValue"
| "useDeferredValue"
| "useTransition"
| "useMutableSource"
| "useOpaqueIdentifier"
| "useCacheRefresh";
interface Source {
fileName: string;
lineNumber: number;
}
// TODO: Ideally these types would be opaque but that doesn't work well with
// our reconciler fork infra, since these leak into non-reconciler packages.
type LanePriority =
| 0
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
| 13
| 14
| 15
| 16
| 17;
type Lanes = number;
type Lane = number;
type Flags = number;
type TypeOfMode = number;
interface ReactProvider<T> {
$$typeof: symbol | number;
type: ReactProviderType<T>;
key: null | string;
ref: null;
props: {
value: T;
children?: ReactNode;
};
}
interface ReactProviderType<T> {
$$typeof: symbol | number;
_context: ReactContext<T>;
}
interface ReactConsumer<T> {
$$typeof: symbol | number;
type: ReactContext<T>;
key: null | string;
ref: null;
props: {
children: (value: T) => ReactNode;
unstable_observedBits?: number;
};
}
interface ReactContext<T> {
$$typeof: symbol | number;
Consumer: ReactContext<T>;
Provider: ReactProviderType<T>;
_calculateChangedBits: ((a: T, b: T) => number) | null;
_currentValue: T;
_currentValue2: T;
_threadCount: number;
// DEV only
_currentRenderer?: {
[key: string]: any;
} | null;
_currentRenderer2?: {
[key: string]: any;
} | null;
// This value may be added by application code
// to improve DEV tooling display names
displayName?: string;
}
interface ReactPortal {
$$typeof: symbol | number;
key: null | string;
containerInfo: any;
children: ReactNode;
// TODO: figure out the API for cross-renderer implementation.
implementation: any;
}
interface RefObject {
current: any;
}
interface ContextDependency<T> {
context: ReactContext<T>;
observedBits: number;
next: ContextDependency<unknown> | null;
}
interface Dependencies {
lanes: Lanes;
firstContext: ContextDependency<unknown> | null;
}
interface Fiber {
// These first fields are conceptually members of an Instance. This used to
// be split into a separate type and intersected with the other Fiber fields,
// but until Flow fixes its intersection bugs, we've merged them into a
// single type.
// An Instance is shared between all versions of a component. We can easily
// break this out into a separate object to avoid copying so much to the
// alternate versions of the tree. We put this on a single object for now to
// minimize the number of objects created during the initial render.
// Tag identifying the type of fiber.
tag: WorkTag;
// Unique identifier of this child.
key: null | string;
// The value of element.type which is used to preserve the identity during
// reconciliation of this child.
elementType: any;
// The resolved function/class/ associated with this fiber.
type: any;
// The local state associated with this fiber.
stateNode: any;
// Conceptual aliases
// parent : Instance -> return The parent happens to be the same as the
// return fiber since we've merged the fiber and instance.
// Remaining fields belong to Fiber
// The Fiber to return to after finishing processing this one.
// This is effectively the parent, but there can be multiple parents (two)
// so this is only the parent of the thing we're currently processing.
// It is conceptually the same as the return address of a stack frame.
return: Fiber | null;
// Singly Linked List Tree Structure.
child: Fiber | null;
sibling: Fiber | null;
index: number;
// The ref last used to attach this node.
// I'll avoid adding an owner field for prod and model that as functions.
ref:
| null
| (((handle: unknown) => void) & {
_stringRef?: string | null;
})
| RefObject;
// Input is the data coming into process this fiber. Arguments. Props.
pendingProps: any; // This type will be more specific once we overload the tag.
memoizedProps: any; // The props used to create the output.
// A queue of state updates and callbacks.
updateQueue: unknown;
// The state used to create the output
memoizedState: any;
// Dependencies (contexts, events) for this fiber, if it has any
dependencies: Dependencies | null;
// Bitfield that describes properties about the fiber and its subtree. E.g.
// the ConcurrentMode flag indicates whether the subtree should be async-by-
// default. When a fiber is created, it inherits the mode of its
// parent. Additional flags can be set at creation time, but after that the
// value should remain unchanged throughout the fiber's lifetime, particularly
// before its child fibers are created.
mode: TypeOfMode;
// Effect
flags: Flags;
subtreeFlags: Flags;
deletions: Fiber[] | null;
// Singly linked list fast path to the next fiber with side-effects.
nextEffect: Fiber | null;
// The first and last fiber with side-effect within this subtree. This allows
// us to reuse a slice of the linked list when we reuse the work done within
// this fiber.
firstEffect: Fiber | null;
lastEffect: Fiber | null;
lanes: Lanes;
childLanes: Lanes;
// This is a pooled version of a Fiber. Every fiber that gets updated will
// eventually have a pair. There are cases when we can clean up pairs to save
// memory if we need to.
alternate: Fiber | null;
// Time spent rendering this Fiber and its descendants for the current update.
// This tells us how well the tree makes use of sCU for memoization.
// It is reset to 0 each time we render and only updated when we don't bailout.
// This field is only set when the enableProfilerTimer flag is enabled.
actualDuration?: number;
// If the Fiber is currently active in the "render" phase,
// This marks the time at which the work began.
// This field is only set when the enableProfilerTimer flag is enabled.
actualStartTime?: number;
// Duration of the most recent render time for this Fiber.
// This value is not updated when we bailout for memoization purposes.
// This field is only set when the enableProfilerTimer flag is enabled.
selfBaseDuration?: number;
// Sum of base times for all descendants of this Fiber.
// This value bubbles up during the "complete" phase.
// This field is only set when the enableProfilerTimer flag is enabled.
treeBaseDuration?: number;
// Conceptual aliases
// workInProgress : Fiber -> alternate The alternate used for reuse happens
// to be the same as work in progress.
// __DEV__ only
_debugID?: number;
_debugSource?: Source | null;
_debugOwner?: Fiber | null;
_debugIsCurrentlyTiming?: boolean;
_debugNeedsRemount?: boolean;
// Used to verify that the order of hooks does not change between renders.
_debugHookTypes?: HookType[] | null;
}
type FiberRoot = any;
// Concurrent related struct
type MutableSource = any;
type OpaqueHandle = any;
type OpaqueRoot = any;
// 0 is PROD, 1 is DEV.
// Might add PROFILE later.
type BundleType = 0 | 1;
interface DevToolsConfig<Instance, TextInstance, RendererInspectionConfig> {
bundleType: BundleType;
version: string;
rendererPackageName: string;
// Note: this actually *does* depend on Fiber internal fields.
// Used by "inspect clicked DOM element" in React DevTools.
findFiberByHostInstance?: ((
instance: Instance | TextInstance,
) => Fiber | null);
rendererConfig?: RendererInspectionConfig;
}
interface SuspenseHydrationCallbacks<SuspenseInstance> {
onHydrated?: ((suspenseInstance: SuspenseInstance) => void);
onDeleted?: ((suspenseInstance: SuspenseInstance) => void);
}
interface ComponentSelector {
$$typeof: symbol | number;
value: React$AbstractComponent<never, unknown>;
}
interface HasPsuedoClassSelector {
$$typeof: symbol | number;
value: Selector[];
}
interface RoleSelector {
$$typeof: symbol | number;
value: string;
}
interface TextSelector {
$$typeof: symbol | number;
value: string;
}
interface TestNameSelector {
$$typeof: symbol | number;
value: string;
}
type Selector =
| ComponentSelector
| HasPsuedoClassSelector
| RoleSelector
| TextSelector
| TestNameSelector;
// TODO can not find React$AbstractComponent def
type React$AbstractComponent<Config, Instance = any> = any;
interface BoundingRect {
x: number;
y: number;
width: number;
height: number;
}
type IntersectionObserverOptions = any;
interface Reconciler<
Container,
Instance,
TextInstance,
SuspenseInstance,
PublicInstance
> {
createContainer(
containerInfo: Container,
tag: RootTag,
hydrate: boolean,
hydrationCallbacks: null | SuspenseHydrationCallbacks<SuspenseInstance>,
): OpaqueRoot;
updateContainer(
element: ReactNode,
container: OpaqueRoot,
parentComponent?: Component<any, any> | null,
callback?: (() => void) | null,
): Lane;
batchedEventUpdates<A, R>(fn: (a: A) => R, a: A): R;
batchedUpdates<A, R>(fn: (a: A) => R, a: A): R;
unbatchedUpdates<A, R>(fn: (a: A) => R, a: A): R;
deferredUpdates<A>(fn: () => A): A;
discreteUpdates<A, B, C, D, R>(
fn: (arg0: A, arg1: B, arg2: C) => R,
a: A,
b: B,
c: C,
// tslint:disable-next-line:no-unnecessary-generics
d: D,
): R;
flushDiscreteUpdates(): void;
flushControlled(fn: () => any): void;
flushSync<A, R>(fn: (a: A) => R, a: A): R;
flushPassiveEffects(): boolean;
readonly IsThisRendererActing: { current: boolean };
getPublicRootInstance(
container: OpaqueRoot,
): Component<any, any> | PublicInstance | null;
attemptSynchronousHydration(fiber: Fiber): void;
attemptUserBlockingHydration(fiber: Fiber): void;
attemptContinuousHydration(fiber: Fiber): void;
attemptHydrationAtCurrentPriority(fiber: Fiber): void;