@symbiote-native/react 0.2.8 → 0.4.0
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/README.md +5 -5
- package/build/bootstrap.js +5 -6
- package/build/components/activity-indicator/index.android.js +5 -7
- package/build/components/activity-indicator/shared.js +1 -1
- package/build/components/button.js +1 -1
- package/build/components/flat-list/index.js +5 -2
- package/build/components/input-accessory-view/index.js +6 -1
- package/build/components/keyboard-avoiding-view/index.js +32 -12
- package/build/components/modal/index.d.ts +3 -2
- package/build/components/modal/index.js +1 -1
- package/build/components/pressable/index.d.ts +1 -1
- package/build/components/pressable/index.js +1 -1
- package/build/components/scroll-view/index.android.js +16 -8
- package/build/components/scroll-view/index.ios.js +13 -11
- package/build/components/scroll-view/shared.js +58 -9
- package/build/components/scroll-view/sticky-header.d.ts +11 -2
- package/build/components/scroll-view/sticky-header.js +60 -20
- package/build/components/section-list/index.js +4 -6
- package/build/components/text-input/index.js +7 -2
- package/build/components/touchable/index.d.ts +2 -0
- package/build/components/touchable/index.js +130 -28
- package/build/components/virtualized-list/index.js +87 -22
- package/build/components/virtualized-section-list/index.d.ts +5 -0
- package/build/components/virtualized-section-list/index.js +24 -4
- package/build/components.js +2 -2
- package/build/create-portal/index.js +1 -1
- package/build/create-tunnel/index.js +15 -21
- package/build/hooks/use-color-scheme.d.ts +1 -1
- package/build/hooks/use-color-scheme.js +1 -1
- package/build/hooks/use-window-dimensions.d.ts +1 -1
- package/build/hooks/use-window-dimensions.js +1 -1
- package/build/host-config.js +13 -5
- package/build/host-instance.js +5 -6
- package/build/index.d.ts +12 -37
- package/build/index.js +16 -26
- package/build/modules/animated/create-animated-component.js +27 -66
- package/build/modules/animated/index.d.ts +1 -1
- package/build/modules/animated/index.js +1 -1
- package/build/modules/status-bar/index.ios.js +1 -1
- package/build/render.js +30 -2
- package/metro-css-parser.cjs +7 -12
- package/package.json +5 -5
- package/build/modules/action-sheet-ios.d.ts +0 -2
- package/build/modules/action-sheet-ios.js +0 -4
- package/build/modules/alert.d.ts +0 -2
- package/build/modules/alert.js +0 -5
- package/build/modules/app-state.d.ts +0 -2
- package/build/modules/app-state.js +0 -3
- package/build/modules/appearance.d.ts +0 -2
- package/build/modules/appearance.js +0 -3
- package/build/modules/back-handler.d.ts +0 -2
- package/build/modules/back-handler.js +0 -3
- package/build/modules/dimensions.d.ts +0 -2
- package/build/modules/dimensions.js +0 -3
- package/build/modules/i18n-manager.d.ts +0 -2
- package/build/modules/i18n-manager.js +0 -4
- package/build/modules/keyboard.d.ts +0 -2
- package/build/modules/keyboard.js +0 -3
- package/build/modules/layout-animation.d.ts +0 -2
- package/build/modules/layout-animation.js +0 -3
- package/build/modules/linking.d.ts +0 -2
- package/build/modules/linking.js +0 -4
- package/build/modules/permissions-android.d.ts +0 -2
- package/build/modules/permissions-android.js +0 -3
- package/build/modules/settings.d.ts +0 -1
- package/build/modules/settings.js +0 -4
- package/build/modules/share.d.ts +0 -2
- package/build/modules/share.js +0 -4
- package/build/modules/text-input-state.d.ts +0 -1
- package/build/modules/text-input-state.js +0 -3
- package/build/modules/toast-android.d.ts +0 -1
- package/build/modules/toast-android.js +0 -4
- package/build/modules/vibration.d.ts +0 -1
- package/build/modules/vibration.js +0 -4
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// useImperativeHandle + the per-entry render dispatch). Lower layer in RN's
|
|
7
7
|
// SectionList -> VirtualizedSectionList -> VirtualizedList stack.
|
|
8
8
|
import { createElement, useImperativeHandle, useRef, } from 'react';
|
|
9
|
-
import { dlog, Platform } from '@symbiote-native/engine';
|
|
9
|
+
import { dlog, Platform, } from '@symbiote-native/engine';
|
|
10
10
|
import { flattenSections, resolveStickySectionHeaders, scrollLocationToFlatIndex, sectionEntryKey, unwrapEntryItem, } from '@symbiote-native/components';
|
|
11
11
|
import { VirtualizedList, } from '../virtualized-list/index.js';
|
|
12
12
|
function resolveSeparator(component) {
|
|
@@ -20,7 +20,10 @@ export function VirtualizedSectionList(props) {
|
|
|
20
20
|
const { ref, sections, renderItem, renderSectionHeader, renderSectionFooter, SectionSeparatorComponent,
|
|
21
21
|
// Pulled out of `rest`: the user's separator is typed on ItemT, but the inner VirtualizedList
|
|
22
22
|
// streams ISectionEntry<ItemT>, so we wrap it to unwrap each entry back to its ItemT.
|
|
23
|
-
ItemSeparatorComponent, keyExtractor,
|
|
23
|
+
ItemSeparatorComponent, keyExtractor,
|
|
24
|
+
// Also pulled out of `rest`: the inner list streams entries, the user's callback expects
|
|
25
|
+
// sections. See entryItemLayout below.
|
|
26
|
+
getItemLayout, stickySectionHeadersEnabled, ...rest } = props;
|
|
24
27
|
const { entries, headerIndices } = flattenSections(sections, SectionSeparatorComponent !== undefined);
|
|
25
28
|
// RN sticks section headers by default only on iOS; Android does not unless asked. headerIndices
|
|
26
29
|
// are the flat positions of every section header; VirtualizedList forwards the in-window ones.
|
|
@@ -58,10 +61,14 @@ export function VirtualizedSectionList(props) {
|
|
|
58
61
|
const renderEntry = (info) => {
|
|
59
62
|
const entry = info.item;
|
|
60
63
|
if (entry.kind === 'header') {
|
|
61
|
-
return renderSectionHeader
|
|
64
|
+
return renderSectionHeader
|
|
65
|
+
? renderSectionHeader({ section: entry.section })
|
|
66
|
+
: undefined;
|
|
62
67
|
}
|
|
63
68
|
if (entry.kind === 'footer') {
|
|
64
|
-
return renderSectionFooter
|
|
69
|
+
return renderSectionFooter
|
|
70
|
+
? renderSectionFooter({ section: entry.section })
|
|
71
|
+
: undefined;
|
|
65
72
|
}
|
|
66
73
|
if (entry.kind === 'section-separator') {
|
|
67
74
|
return resolveSeparator(SectionSeparatorComponent);
|
|
@@ -83,6 +90,18 @@ export function VirtualizedSectionList(props) {
|
|
|
83
90
|
trailingItem: unwrapEntryItem(entryProps.trailingItem),
|
|
84
91
|
});
|
|
85
92
|
const entryKeyExtractor = (entry, index) => sectionEntryKey(entry, index, keyExtractor);
|
|
93
|
+
// Hand the callback `sections`, not the entries: RN's inner VirtualizedList gets
|
|
94
|
+
// `data={this.props.sections}` (VirtualizedSectionList.js:216) while ours streams the FLATTENED
|
|
95
|
+
// entries, so the same user code would otherwise see a different argument here than on RN.
|
|
96
|
+
//
|
|
97
|
+
// UPSTREAM-DIVERGENCE(react-native): the flat INDEX matches RN's (two rows per section, header
|
|
98
|
+
// and footer) only while SectionSeparatorComponent is unset. With it, flattenSections emits an
|
|
99
|
+
// extra 'section-separator' row per boundary that RN renders inside the neighbouring cell, so
|
|
100
|
+
// indices shift by one per boundary from the second section on. Deliberate - that row is how this
|
|
101
|
+
// adapter paints the separator; a caller combining the two must account for it.
|
|
102
|
+
const entryItemLayout = getItemLayout === undefined
|
|
103
|
+
? undefined
|
|
104
|
+
: (_entries, index) => getItemLayout(sections, index);
|
|
86
105
|
return createElement((VirtualizedList), {
|
|
87
106
|
ref: listRef,
|
|
88
107
|
data: entries,
|
|
@@ -90,6 +109,7 @@ export function VirtualizedSectionList(props) {
|
|
|
90
109
|
getItemCount: () => entries.length,
|
|
91
110
|
renderItem: renderEntry,
|
|
92
111
|
keyExtractor: entryKeyExtractor,
|
|
112
|
+
getItemLayout: entryItemLayout,
|
|
93
113
|
stickyHeaderIndices,
|
|
94
114
|
ItemSeparatorComponent: entrySeparatorComponent,
|
|
95
115
|
...rest,
|
package/build/components.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// reconciler maps those to shared's mutation API, which resolves them to Fabric
|
|
4
4
|
// view names at commit.
|
|
5
5
|
import { createElement } from 'react';
|
|
6
|
-
import { resolveAccessibilityProps, } from '@symbiote-native/components';
|
|
6
|
+
import { resolveAccessibilityProps, resolveTextProps, } from '@symbiote-native/components';
|
|
7
7
|
// RN's modern `id` is just a W3C-named alias for `nativeID`: View.js copies it over
|
|
8
8
|
// (`processedProps.nativeID = id`), so `id` wins when both are set. We fold it here and
|
|
9
9
|
// blank the alias so a raw `id` never reaches Fabric (every non-function prop passes
|
|
@@ -14,4 +14,4 @@ function resolveId({ id, ...rest }) {
|
|
|
14
14
|
return { ...rest, nativeID: id };
|
|
15
15
|
}
|
|
16
16
|
export const View = props => createElement('symbiote-view', resolveAccessibilityProps(resolveId(props)));
|
|
17
|
-
export const Text = props => createElement('symbiote-text', resolveAccessibilityProps(props));
|
|
17
|
+
export const Text = props => createElement('symbiote-text', resolveTextProps(resolveAccessibilityProps(props)));
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// call site (e.g. a ref to a persistent "overlay host" View near your app root) — not a second,
|
|
11
11
|
// independently-mounted SymbioteSurface. Cross-surface targets aren't wired: resetAfterCommit only
|
|
12
12
|
// fires for the primary root's own container, so a different surface's tree would never repaint.
|
|
13
|
-
import { isSymbioteNode, SymbioteSurface } from '@symbiote-native/engine';
|
|
13
|
+
import { isSymbioteNode, SymbioteSurface, } from '@symbiote-native/engine';
|
|
14
14
|
import reconciler from '../host-config.js';
|
|
15
15
|
export function createPortal(children, container, key) {
|
|
16
16
|
if (!(container instanceof SymbioteSurface) && !isSymbioteNode(container)) {
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// createTunnel
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// instance"). The fix is the one the ecosystem already settled on: don't reach into a
|
|
7
|
-
// foreign surface's commit machinery — let that surface commit ITSELF, normally, by reading
|
|
2
|
+
// createTunnel - the cross-surface answer to createPortal's same-surface-only scope. A real
|
|
3
|
+
// createPortal cannot reach across two separate reconciler roots (see
|
|
4
|
+
// github.com/facebook/react/issues/17147); the fix, same as pmndrs/tunnel-rat, is to not
|
|
5
|
+
// reach into a foreign surface's commit machinery - let that surface commit itself, reading
|
|
8
6
|
// from a store it's already subscribed to.
|
|
9
7
|
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
// should PAINT the content (e.g. a persistent overlay-host surface); `In` lives ANYWHERE, same
|
|
22
|
-
// surface or a totally different one, and never touches a Fabric node directly, so there is
|
|
23
|
-
// no "target must already be mounted" guard to satisfy at all.
|
|
24
|
-
import { Fragment, useEffect, useId, useSyncExternalStore } from 'react';
|
|
8
|
+
// In and Out are COMPONENTS (Context.Provider/Consumer shape), never hooks - this is
|
|
9
|
+
// load-bearing, not just ergonomics. An earlier hook-based version caused a real infinite
|
|
10
|
+
// render loop on device (silent white screen, no thrown error): notify() re-renders
|
|
11
|
+
// whichever component's useSyncExternalStore subscription fired, and when that was the same
|
|
12
|
+
// component calling useTunnelIn, its own effect re-notified itself forever - this custom
|
|
13
|
+
// renderer's synchronous commit loop has no "Maximum update depth exceeded" guard. As
|
|
14
|
+
// separate components, notify() only forces Out's own render scope, so the update has
|
|
15
|
+
// nowhere to bounce back to. `Out` lives in whichever surface should PAINT the content; `In`
|
|
16
|
+
// lives anywhere - same surface or a different one - and never touches a Fabric node
|
|
17
|
+
// directly, so there's no "target must already be mounted" guard to satisfy.
|
|
18
|
+
import { Fragment, useEffect, useId, useSyncExternalStore, } from 'react';
|
|
25
19
|
export function createTunnel() {
|
|
26
20
|
const items = new Map();
|
|
27
21
|
const listeners = new Set();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type IColorSchemeName } from '
|
|
1
|
+
import { type IColorSchemeName } from '@symbiote-native/engine';
|
|
2
2
|
export declare function useColorScheme(): IColorSchemeName | null;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// on change. Mirrors RN's Libraries/Utilities/useColorScheme.js: a thin
|
|
3
3
|
// useSyncExternalStore over Appearance's change event + current scheme read.
|
|
4
4
|
import { useSyncExternalStore } from 'react';
|
|
5
|
-
import { Appearance } from '
|
|
5
|
+
import { Appearance } from '@symbiote-native/engine';
|
|
6
6
|
const subscribe = (onStoreChange) => {
|
|
7
7
|
const subscription = Appearance.addChangeListener(onStoreChange);
|
|
8
8
|
return () => subscription.remove();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type IDisplayMetrics } from '
|
|
1
|
+
import { type IDisplayMetrics } from '@symbiote-native/engine';
|
|
2
2
|
export declare function useWindowDimensions(): IDisplayMetrics;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// subscribing to close the gap between the render-time get and the effect-time
|
|
5
5
|
// listener. Only the window metrics changing triggers a re-render.
|
|
6
6
|
import { useEffect, useState } from 'react';
|
|
7
|
-
import { Dimensions } from '
|
|
7
|
+
import { Dimensions, } from '@symbiote-native/engine';
|
|
8
8
|
export function useWindowDimensions() {
|
|
9
9
|
const [dimensions, setDimensions] = useState(() => Dimensions.get('window'));
|
|
10
10
|
useEffect(() => {
|
package/build/host-config.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// canary: a known-good driver exercising shared end to end.
|
|
5
5
|
import createReconciler from 'react-reconciler';
|
|
6
6
|
import { createContext } from 'react';
|
|
7
|
-
import { appendChild, createElement, createRawText, insertBefore, removeChild, routeProp, setText, SymbioteSurface, } from '@symbiote-native/engine';
|
|
7
|
+
import { appendChild, createElement, createRawText, insertBefore, removeChild, routeProp, setNodeHidden, setText, SymbioteSurface, } from '@symbiote-native/engine';
|
|
8
8
|
import { DefaultEventPriority, DiscreteEventPriority, NoEventPriority, } from './reconciler-constants.js';
|
|
9
9
|
import { toPublicInstance } from './host-instance.js';
|
|
10
10
|
// Intrinsic JSX type -> Fabric component name. The name table + resolver live once in
|
|
@@ -70,7 +70,9 @@ const reconciler = createReconciler({
|
|
|
70
70
|
getRootHostContext: () => ({ isInsideText: false }),
|
|
71
71
|
getChildHostContext(parentHostContext, type) {
|
|
72
72
|
const isInsideText = descriptorFor(type).isText;
|
|
73
|
-
return parentHostContext.isInsideText === isInsideText
|
|
73
|
+
return parentHostContext.isInsideText === isInsideText
|
|
74
|
+
? parentHostContext
|
|
75
|
+
: { isInsideText };
|
|
74
76
|
},
|
|
75
77
|
getPublicInstance: instance => toPublicInstance(instance),
|
|
76
78
|
prepareForCommit: () => null,
|
|
@@ -134,8 +136,12 @@ const reconciler = createReconciler({
|
|
|
134
136
|
resetTextContent: () => { },
|
|
135
137
|
hideTextInstance: node => setText(node, ''),
|
|
136
138
|
unhideTextInstance: (node, text) => setText(node, text),
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
// `Activity mode="hidden"` and a re-suspending `Suspense` both reach the tree through these.
|
|
140
|
+
// They were no-ops, so hidden content went on painting — stacked on top of whatever replaced
|
|
141
|
+
// it — and only the mount/unmount half of Activity appeared to work. The engine owns the
|
|
142
|
+
// reversible half (see setNodeHidden): the author's own style stays untouched underneath.
|
|
143
|
+
hideInstance: node => setNodeHidden(node, true),
|
|
144
|
+
unhideInstance: node => setNodeHidden(node, false),
|
|
139
145
|
beforeActiveInstanceBlur: () => { },
|
|
140
146
|
afterActiveInstanceBlur: () => { },
|
|
141
147
|
detachDeletedInstance: () => { },
|
|
@@ -146,7 +152,9 @@ const reconciler = createReconciler({
|
|
|
146
152
|
currentUpdatePriority = priority;
|
|
147
153
|
},
|
|
148
154
|
getCurrentUpdatePriority: () => currentUpdatePriority,
|
|
149
|
-
resolveUpdatePriority: () => currentUpdatePriority !== NoEventPriority
|
|
155
|
+
resolveUpdatePriority: () => currentUpdatePriority !== NoEventPriority
|
|
156
|
+
? currentUpdatePriority
|
|
157
|
+
: DefaultEventPriority,
|
|
150
158
|
maySuspendCommit: () => false,
|
|
151
159
|
NotPendingTransition: null,
|
|
152
160
|
// react's Context IS the runtime value react-reconciler's ReactContext wants
|
package/build/host-instance.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
// The public instance a host ref hands back and the ref -> tag lookup. toPublicInstance and
|
|
2
|
-
// IHostInstance
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// native tag" lookup over the engine's getNativeTag.
|
|
1
|
+
// The public instance a host ref hands back, and the ref -> tag lookup. toPublicInstance and
|
|
2
|
+
// IHostInstance live in @symbiote-native/engine (every adapter inherits the same public instance);
|
|
3
|
+
// this module re-exports them so the React surface (findNodeHandle + IHostInstance, host-config's
|
|
4
|
+
// toPublicInstance graft) is unchanged. findNodeHandle stays React-specific: it is the
|
|
5
|
+
// RN-shaped "ref -> native tag" lookup over the engine's getNativeTag.
|
|
7
6
|
import { getNativeTag, isSymbioteNode, toPublicInstance, } from '@symbiote-native/engine';
|
|
8
7
|
export { toPublicInstance };
|
|
9
8
|
// The committed native tag of a host ref (or a bare tag, idempotent). RN's
|
package/build/index.d.ts
CHANGED
|
@@ -7,13 +7,11 @@ export type { IImageProps, IImageSource, IImageSourceProp, IResizeMode, IImageSi
|
|
|
7
7
|
export { ImageBackground } from './components/image-background';
|
|
8
8
|
export type { IImageBackgroundProps } from './components/image-background';
|
|
9
9
|
export { ScrollView } from './components/scroll-view';
|
|
10
|
-
export type { IScrollViewProps, IScrollViewHandle } from './components/scroll-view';
|
|
10
|
+
export type { IScrollViewProps, IScrollViewHandle, } from './components/scroll-view';
|
|
11
11
|
export { TextInput } from './components/text-input';
|
|
12
|
-
export type { ITextInputProps, ITextInputHandle } from './components/text-input';
|
|
12
|
+
export type { ITextInputProps, ITextInputHandle, } from './components/text-input';
|
|
13
13
|
export { InputAccessoryView } from './components/input-accessory-view';
|
|
14
14
|
export type { IInputAccessoryViewProps } from './components/input-accessory-view';
|
|
15
|
-
export { Keyboard, KEYBOARD_EVENT } from './modules/keyboard';
|
|
16
|
-
export type { IKeyboardEventName } from './modules/keyboard';
|
|
17
15
|
export { KeyboardAvoidingView } from './components/keyboard-avoiding-view';
|
|
18
16
|
export type { IKeyboardAvoidingViewProps, IKeyboardAvoidingBehavior, } from './components/keyboard-avoiding-view';
|
|
19
17
|
export { StatusBar } from './modules/status-bar';
|
|
@@ -37,12 +35,12 @@ export type { IButtonProps } from './components/button';
|
|
|
37
35
|
export { FlatList } from './components/flat-list';
|
|
38
36
|
export type { IFlatListProps, IFlatListHandle } from './components/flat-list';
|
|
39
37
|
export { SectionList } from './components/section-list';
|
|
40
|
-
export type { ISectionListProps, ISectionListHandle, ISection } from './components/section-list';
|
|
38
|
+
export type { ISectionListProps, ISectionListHandle, ISection, } from './components/section-list';
|
|
41
39
|
export { VirtualizedSectionList } from './components/virtualized-section-list';
|
|
42
40
|
export type { IVirtualizedSectionListProps, IVirtualizedSectionListHandle, } from './components/virtualized-section-list';
|
|
43
41
|
export { VirtualizedList } from './components/virtualized-list';
|
|
44
42
|
export type { IVirtualizedListProps, IVirtualizedListHandle, IViewToken, IViewableItemsChangedInfo, IViewabilityConfig, IViewabilityConfigCallbackPair, } from './components/virtualized-list';
|
|
45
|
-
export type { IViewStyle, ITextStyle, IFlexAlign, IFlexJustify } from './utils/styles';
|
|
43
|
+
export type { IViewStyle, ITextStyle, IFlexAlign, IFlexJustify, } from './utils/styles';
|
|
46
44
|
export { mount, unmount } from './render';
|
|
47
45
|
export { createPortal, type IPortalContainer } from './create-portal';
|
|
48
46
|
export { createTunnel, type ITunnel } from './create-tunnel';
|
|
@@ -53,46 +51,23 @@ export { AppRegistry, setHostRegistrar } from './modules/app-registry';
|
|
|
53
51
|
export type { IComponentProvider, IAppParameters, IRunnable, IHostRegistrar, IWrapperComponentProvider, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from './modules/app-registry';
|
|
54
52
|
export { Animated, createAnimatedComponent } from './modules/animated';
|
|
55
53
|
export { Platform, StyleSheet } from '@symbiote-native/engine';
|
|
56
|
-
export { PlatformColor, DynamicColorIOS, processColor } from '@symbiote-native/engine';
|
|
54
|
+
export { PlatformColor, DynamicColorIOS, processColor, } from '@symbiote-native/engine';
|
|
57
55
|
export type { IColorValue, IOpaqueColorValue, IDynamicColorIOSTuple, } from '@symbiote-native/engine';
|
|
58
|
-
export { setNativeViewConfigSource } from '@symbiote-native/engine';
|
|
59
|
-
export
|
|
56
|
+
export { setNativeViewConfigSource, setColorProcessor, setDeviceEventSource, } from '@symbiote-native/engine';
|
|
57
|
+
export { dlog, isDebug } from '@symbiote-native/engine';
|
|
58
|
+
export type { INativeViewConfig, INativeViewConfigSource, } from '@symbiote-native/engine';
|
|
60
59
|
export type { IPlatformStatic, IPlatformOSType, IPlatformConstantsIOS, IPlatformConstantsAndroid, IPlatformSelectSpec, } from '@symbiote-native/engine';
|
|
61
|
-
export { Dimensions } from '
|
|
62
|
-
export type { IDisplayMetrics, IDisplayMetricsAndroid, IDimensionsPayload, IDimensionsSet, IDimensionsKey, IDimensionsChangeListener, IDimensionsStatic, } from '
|
|
63
|
-
export { PixelRatio } from '@symbiote-native/engine';
|
|
64
|
-
export type { IPixelRatioStatic } from '@symbiote-native/engine';
|
|
60
|
+
export { Alert, Share, ActionSheetIOS, Linking, Vibration, ToastAndroid, Settings, I18nManager, Dimensions, Appearance, AppState, Keyboard, KEYBOARD_EVENT, BackHandler, PermissionsAndroid, PERMISSIONS, RESULTS, LayoutAnimation, PixelRatio, } from '@symbiote-native/engine';
|
|
61
|
+
export type { IAlertType, IAlertButtonStyle, IAlertButton, IAlertButtons, IAlertOptions, IShareContent, IShareOptions, IShareAction, IActionSheetIOSOptions, IShareActionSheetIOSOptions, IShareActionSheetError, IUrlEvent, II18nManagerConstants, IDisplayMetrics, IDisplayMetricsAndroid, IDimensionsPayload, IDimensionsSet, IDimensionsKey, IDimensionsChangeListener, IDimensionsStatic, IColorSchemeName, IColorSchemePreference, IAppStateStatus, IAppStateEvent, IKeyboardEventName, IKeyboardEvent, IKeyboardMetrics, IBackPressEventName, IBackPressHandler, IPermission, IPermissionStatus, IRationale, ILayoutAnimationType, ILayoutAnimationProperty, ILayoutAnimationConfig, ILayoutAnimationAnim, IPixelRatioStatic, } from '@symbiote-native/engine';
|
|
65
62
|
export { useWindowDimensions } from './hooks/use-window-dimensions';
|
|
66
|
-
export { Appearance } from './modules/appearance';
|
|
67
|
-
export type { IColorSchemeName, IColorSchemePreference } from './modules/appearance';
|
|
68
63
|
export { useColorScheme } from './hooks/use-color-scheme';
|
|
69
|
-
export { AppState } from './modules/app-state';
|
|
70
|
-
export type { IAppStateStatus, IAppStateEvent } from './modules/app-state';
|
|
71
|
-
export { Alert } from './modules/alert';
|
|
72
|
-
export type { IAlertType, IAlertButtonStyle, IAlertButton, IAlertButtons, IAlertOptions, } from './modules/alert';
|
|
73
|
-
export { ActionSheetIOS } from './modules/action-sheet-ios';
|
|
74
|
-
export type { IActionSheetIOSOptions, IShareActionSheetIOSOptions, IShareActionSheetError, } from './modules/action-sheet-ios';
|
|
75
|
-
export { Linking } from './modules/linking';
|
|
76
|
-
export type { IUrlEvent } from './modules/linking';
|
|
77
|
-
export { Vibration } from './modules/vibration';
|
|
78
|
-
export { Share } from './modules/share';
|
|
79
|
-
export type { IShareContent, IShareOptions, IShareAction } from './modules/share';
|
|
80
64
|
export { AccessibilityInfo } from './modules/accessibility-info';
|
|
81
65
|
export type { IAccessibilityChangeEvent, IAccessibilityChangeEventName, IAccessibilityChangeEventHandler, IAccessibilityAnnouncementFinishedEvent, IAnnounceForAccessibilityOptions, IAccessibilityEventType, } from './modules/accessibility-info';
|
|
82
|
-
export { I18nManager } from './modules/i18n-manager';
|
|
83
|
-
export type { II18nManagerConstants } from './modules/i18n-manager';
|
|
84
|
-
export { Settings } from './modules/settings';
|
|
85
66
|
export { PanResponder } from '@symbiote-native/engine';
|
|
86
67
|
export type { IPanResponderGestureState, IPanResponderCallbacks, IGestureResponderHandlers, IPanResponderInstance, } from '@symbiote-native/engine';
|
|
87
|
-
export { LayoutAnimation } from './modules/layout-animation';
|
|
88
|
-
export type { ILayoutAnimationType, ILayoutAnimationProperty, ILayoutAnimationConfig, ILayoutAnimationAnim, } from './modules/layout-animation';
|
|
89
68
|
export { InteractionManager } from '@symbiote-native/engine';
|
|
90
69
|
export type { IInteractionEvent, ISimpleTask, IPromiseTask, ITask, IHandle, } from '@symbiote-native/engine';
|
|
91
|
-
export { BackHandler } from './modules/back-handler';
|
|
92
|
-
export type { IBackPressEventName, IBackPressHandler } from './modules/back-handler';
|
|
93
|
-
export { ToastAndroid } from './modules/toast-android';
|
|
94
|
-
export { PermissionsAndroid, PERMISSIONS, RESULTS } from './modules/permissions-android';
|
|
95
|
-
export type { IPermission, IPermissionStatus, IRationale } from './modules/permissions-android';
|
|
96
70
|
export { TouchableNativeFeedback } from './components/touchable-native-feedback';
|
|
97
71
|
export type { ITouchableNativeFeedbackProps, INativeFeedbackBackground, IThemeAttrBackground, IRippleBackground, } from './components/touchable-native-feedback';
|
|
98
|
-
export type { ISymbioteEvent } from '@symbiote-native/engine';
|
|
72
|
+
export type { ISymbioteEvent, ISymbioteNode, IRootTag, } from '@symbiote-native/engine';
|
|
73
|
+
export type { ICellLayout, ISeparatorProps, ISeparators, IModalOrientationChangeEvent, IPressableAndroidRippleConfig, IEnterKeyHint, IInputMode, ISubmitBehavior, ITextInputSelection, IImageStatics, } from '@symbiote-native/components';
|
package/build/index.js
CHANGED
|
@@ -7,7 +7,6 @@ export { ImageBackground } from './components/image-background/index.js';
|
|
|
7
7
|
export { ScrollView } from './components/scroll-view';
|
|
8
8
|
export { TextInput } from './components/text-input/index.js';
|
|
9
9
|
export { InputAccessoryView } from './components/input-accessory-view/index.js';
|
|
10
|
-
export { Keyboard, KEYBOARD_EVENT } from './modules/keyboard.js';
|
|
11
10
|
export { KeyboardAvoidingView } from './components/keyboard-avoiding-view/index.js';
|
|
12
11
|
export { StatusBar } from './modules/status-bar';
|
|
13
12
|
export { Switch } from './components/switch';
|
|
@@ -50,38 +49,29 @@ export { Platform, StyleSheet } from '@symbiote-native/engine';
|
|
|
50
49
|
// Color utilities: PlatformColor / DynamicColorIOS build opaque platform colors;
|
|
51
50
|
// processColor runs a color through the injected platform processor. All pure /
|
|
52
51
|
// seam-backed, so they live in shared and the adapter re-exports them.
|
|
53
|
-
export { PlatformColor, DynamicColorIOS, processColor } from '@symbiote-native/engine';
|
|
54
|
-
//
|
|
55
|
-
// RN's ViewConfig registry
|
|
52
|
+
export { PlatformColor, DynamicColorIOS, processColor, } from '@symbiote-native/engine';
|
|
53
|
+
// The three app-entry seams, wired once on a real host, so the barrel exposes them together.
|
|
54
|
+
// setNativeViewConfigSource hands the engine RN's ViewConfig registry, which is how third-party
|
|
55
|
+
// Fabric views auto-derive their metadata:
|
|
56
56
|
// setNativeViewConfigSource(name => ReactNativeViewConfigRegistry.get(name))
|
|
57
|
-
export { setNativeViewConfigSource } from '@symbiote-native/engine';
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
export {
|
|
61
|
-
|
|
57
|
+
export { setNativeViewConfigSource, setColorProcessor, setDeviceEventSource, } from '@symbiote-native/engine';
|
|
58
|
+
// Diagnostics, gated by DEBUG (<keep_logs_gate_behind_DEBUG>): app code logs through the same
|
|
59
|
+
// seam the engine does instead of a bare console.log.
|
|
60
|
+
export { dlog, isDebug } from '@symbiote-native/engine';
|
|
61
|
+
// Imperative runtime modules: the SAME module every adapter shares, re-exported straight from
|
|
62
|
+
// @symbiote-native/engine so app code names only @symbiote-native/react (RN's single import
|
|
63
|
+
// root). Thin JS over getNativeModule + device events, no Fabric component of their own.
|
|
64
|
+
export { Alert, Share, ActionSheetIOS, Linking, Vibration, ToastAndroid, Settings, I18nManager, Dimensions, Appearance, AppState, Keyboard, KEYBOARD_EVENT, BackHandler, PermissionsAndroid, PERMISSIONS, RESULTS, LayoutAnimation, PixelRatio, } from '@symbiote-native/engine';
|
|
65
|
+
// React lifecycle over those core device-state modules.
|
|
62
66
|
export { useWindowDimensions } from './hooks/use-window-dimensions.js';
|
|
63
|
-
export { Appearance } from './modules/appearance.js';
|
|
64
67
|
export { useColorScheme } from './hooks/use-color-scheme.js';
|
|
65
|
-
export { AppState } from './modules/app-state.js';
|
|
66
|
-
export { Alert } from './modules/alert.js';
|
|
67
|
-
export { ActionSheetIOS } from './modules/action-sheet-ios.js';
|
|
68
|
-
export { Linking } from './modules/linking.js';
|
|
69
|
-
export { Vibration } from './modules/vibration.js';
|
|
70
|
-
export { Share } from './modules/share.js';
|
|
71
68
|
export { AccessibilityInfo } from './modules/accessibility-info';
|
|
72
|
-
export { I18nManager } from './modules/i18n-manager.js';
|
|
73
|
-
export { Settings } from './modules/settings.js';
|
|
74
69
|
// Interaction subsystems: gestures, deferred work, and layout transitions.
|
|
75
70
|
export { PanResponder } from '@symbiote-native/engine';
|
|
76
|
-
export { LayoutAnimation } from './modules/layout-animation.js';
|
|
77
71
|
// InteractionManager is pure JS, so it lives in shared; re-exported here so app code
|
|
78
72
|
// names only @symbiote-native/react (RN's single import root).
|
|
79
73
|
export { InteractionManager } from '@symbiote-native/engine';
|
|
80
|
-
// Android-only surface (the second-platform pass)
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
// can only be confirmed on a real device/simulator, not headless tests.
|
|
84
|
-
export { BackHandler } from './modules/back-handler.js';
|
|
85
|
-
export { ToastAndroid } from './modules/toast-android.js';
|
|
86
|
-
export { PermissionsAndroid, PERMISSIONS, RESULTS } from './modules/permissions-android.js';
|
|
74
|
+
// Android-only surface (the second-platform pass): a thin JS shim over an Android Fabric view,
|
|
75
|
+
// inert on iOS (no native view -> degrades to a plain container). The Android-only MODULES
|
|
76
|
+
// (ToastAndroid, PermissionsAndroid, BackHandler) sit in the engine block above.
|
|
87
77
|
export { TouchableNativeFeedback } from './components/touchable-native-feedback/index.js';
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
// and detaches on unmount / when the leaf identity changes. The per-frame path is
|
|
14
14
|
// then: value.setValue / animation -> flushValue -> AnimatedProps.update() ->
|
|
15
15
|
// setNativeProps(node, partial).
|
|
16
|
-
import { createElement, useEffect,
|
|
17
|
-
import {
|
|
16
|
+
import { createElement, useEffect, useRef, } from 'react';
|
|
17
|
+
import { createAnimatedLeafLifecycle, isSymbioteNode, isNativeAnimatedAvailable, reduceProps, readPassthroughStyle, resolveHostNode, } from '@symbiote-native/engine';
|
|
18
18
|
// A ref can be a function or a `.current` object; assign through both forms without
|
|
19
19
|
// casting so a forwarded ref from the caller still receives the instance. Framework-
|
|
20
20
|
// ref-specific, so it stays per-adapter (the rest of the wrap helpers are shared).
|
|
@@ -33,77 +33,36 @@ export function createAnimatedComponent(Component) {
|
|
|
33
33
|
// Native driving is opt-in per the passthrough prop AND requires a real native module;
|
|
34
34
|
// headless / unsupported hosts keep the JS flush path (and the existing JS smokes green).
|
|
35
35
|
const wantsNative = passthrough != null && isNativeAnimatedAvailable();
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
|
|
36
|
+
// The leaf lifecycle - build/swap/bind/detach, native event rebinding, and the
|
|
37
|
+
// rebuild-vs-skip decision - is the engine's, shared by every adapter
|
|
38
|
+
// (core/engine/src/animated/leaf-lifecycle.ts). React owns only WHEN to run it.
|
|
39
|
+
//
|
|
40
|
+
// This used to be `useMemo(() => new AnimatedProps(rest), [rest])`, which reads like the same
|
|
41
|
+
// guard but never was one: `rest` comes out of a rest-destructure, so it is a fresh object on
|
|
42
|
+
// every render and the memo's dependency always differed. The real content check now lives in
|
|
43
|
+
// the shared lifecycle.
|
|
44
|
+
const lifecycleRef = useRef(null);
|
|
45
|
+
lifecycleRef.current ??= createAnimatedLeafLifecycle('react');
|
|
46
|
+
const lifecycle = lifecycleRef.current;
|
|
47
|
+
// The committed host node, captured by the ref below - a native event binds to the node's
|
|
48
|
+
// tag, not the AnimatedProps leaf.
|
|
45
49
|
const nodeRef = useRef(null);
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// hits zero, so detaching the old leaf before the new one is attached would kill a
|
|
50
|
-
// running native-driven animation on any unrelated re-render. Detaching here (not
|
|
51
|
-
// in a cleanup, which React runs BEFORE the next setup) keeps the new-before-old
|
|
52
|
-
// order, mirroring RN's AnimatedComponent._attachProps.
|
|
50
|
+
// Reconcile after every commit. No dependency array on purpose: the props object is rebuilt
|
|
51
|
+
// by every render anyway, so a dependency list could only ever say "always" - the real
|
|
52
|
+
// rebuild-vs-skip decision is the lifecycle's, and it compares CONTENT by key identity.
|
|
53
53
|
useEffect(() => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (previous !== null && previous !== animatedProps) {
|
|
58
|
-
previous.__detach();
|
|
59
|
-
}
|
|
60
|
-
}, [animatedProps]);
|
|
61
|
-
// Native-driver trigger. Runs after attach: push the leaf -> style -> transform
|
|
62
|
-
// -> interpolation -> value chain native so the props animate on the UI thread (no JS lag).
|
|
63
|
-
// Cascades down to the source value; the scroll event attaches to that same value
|
|
64
|
-
// (idempotent). __makeNative is idempotent, so re-firing on a leaf swap is safe.
|
|
54
|
+
lifecycle.reconcile(rest, isSymbioteNode(nodeRef.current) ? nodeRef.current : null, wantsNative);
|
|
55
|
+
});
|
|
56
|
+
// Final teardown: detach the last-attached leaf and any native event bindings on unmount.
|
|
65
57
|
useEffect(() => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}, [animatedProps, wantsNative]);
|
|
69
|
-
// Final teardown: detach the last-attached leaf when the component unmounts.
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
return () => {
|
|
72
|
-
if (attached.current !== null) {
|
|
73
|
-
attached.current.__detach();
|
|
74
|
-
attached.current = null;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
}, []);
|
|
78
|
-
// Native-attach any Animated.event prop, e.g. onScroll={Animated.event(…,
|
|
79
|
-
// {useNativeDriver:true})}, to the committed node, so the event drives its values on
|
|
80
|
-
// the UI thread. attachNativeEventHandler no-ops (returns undefined) unless the prop is
|
|
81
|
-
// a native event handler with a committed tag, so the JS path stays the fallback. The
|
|
82
|
-
// __makeNative cascade then carries the bound interpolations/props native too. Keyed on
|
|
83
|
-
// animatedProps (rebuilt with rest) so a new inline event re-attaches; cleanup detaches.
|
|
84
|
-
useEffect(() => {
|
|
85
|
-
const node = nodeRef.current;
|
|
86
|
-
if (node === null)
|
|
87
|
-
return;
|
|
88
|
-
const detachers = [];
|
|
89
|
-
for (const key of Object.keys(rest)) {
|
|
90
|
-
const attachment = attachNativeEventHandler(node, key, rest[key]);
|
|
91
|
-
if (attachment !== undefined)
|
|
92
|
-
detachers.push(attachment.detach);
|
|
93
|
-
}
|
|
94
|
-
return () => {
|
|
95
|
-
for (const detach of detachers)
|
|
96
|
-
detach();
|
|
97
|
-
};
|
|
98
|
-
}, [animatedProps]);
|
|
58
|
+
return () => lifecycle.teardown();
|
|
59
|
+
}, [lifecycle]);
|
|
99
60
|
// Callback ref: when the base component mounts, capture its public instance, resolve
|
|
100
61
|
// it to the underlying host node (unwrapping a scroll-container handle), record THAT
|
|
101
62
|
// for the event-attach effect and bind it to the leaf, but forward the ORIGINAL
|
|
102
63
|
// instance to the caller, who expects the component's public handle (scrollTo, …).
|
|
103
64
|
const captureRef = (instance) => {
|
|
104
|
-
|
|
105
|
-
nodeRef.current = node;
|
|
106
|
-
animatedProps.setNativeView(node);
|
|
65
|
+
nodeRef.current = resolveHostNode(instance);
|
|
107
66
|
assignRef(forwardedRef, instance);
|
|
108
67
|
};
|
|
109
68
|
// Reduced props are P-shaped (animated nodes already replaced by values); add the
|
|
@@ -115,7 +74,9 @@ export function createAnimatedComponent(Component) {
|
|
|
115
74
|
const passthroughStyle = readPassthroughStyle(passthrough);
|
|
116
75
|
if (passthroughStyle !== undefined) {
|
|
117
76
|
reduced.style =
|
|
118
|
-
reduced.style === undefined
|
|
77
|
+
reduced.style === undefined
|
|
78
|
+
? passthroughStyle
|
|
79
|
+
: [reduced.style, passthroughStyle];
|
|
119
80
|
}
|
|
120
81
|
const childProps = Object.assign(Object.create(null), reduced, { ref: captureRef });
|
|
121
82
|
return createElement(Component, childProps);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnimatedValue, AnimatedValueXY, AnimatedColor, timing, spring, decay, parallel, sequence, stagger, loop, delay, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent } from '@symbiote-native/engine';
|
|
2
2
|
import { createAnimatedComponent } from './create-animated-component';
|
|
3
3
|
export { createAnimatedComponent } from './create-animated-component';
|
|
4
|
-
export { AnimatedProps, AnimatedStyle, AnimatedTransform } from '@symbiote-native/engine';
|
|
4
|
+
export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
|
|
5
5
|
export declare const Animated: {
|
|
6
6
|
Value: typeof AnimatedValue;
|
|
7
7
|
ValueXY: typeof AnimatedValueXY;
|
|
@@ -14,7 +14,7 @@ import { AnimatedMock } from '@symbiote-native/engine';
|
|
|
14
14
|
export { createAnimatedComponent } from './create-animated-component.js';
|
|
15
15
|
// The pure graph leaves now live in @symbiote-native/engine (they extend AnimatedWithChildren,
|
|
16
16
|
// no React); re-exported here so @symbiote-native/react's Animated surface is unchanged.
|
|
17
|
-
export { AnimatedProps, AnimatedStyle, AnimatedTransform } from '@symbiote-native/engine';
|
|
17
|
+
export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
|
|
18
18
|
// View/Text/Image are pure host primitives, so wrap them eagerly.
|
|
19
19
|
const AnimatedView = createAnimatedComponent(View);
|
|
20
20
|
const AnimatedText = createAnimatedComponent(Text);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// it, which is also what a bare '@symbiote-native/engine' import resolves to under vitest — so
|
|
11
11
|
// this file's own engine import is already vitest-correct, no platform-selection subtlety here.
|
|
12
12
|
import { useEffect } from 'react';
|
|
13
|
-
import { applyStatusBarProps, statusBarImperative } from '@symbiote-native/engine';
|
|
13
|
+
import { applyStatusBarProps, statusBarImperative, } from '@symbiote-native/engine';
|
|
14
14
|
// StatusBar renders null and applies its props to the native module in an effect,
|
|
15
15
|
// on mount and on every prop change. Simplification vs RN: RN maintains a
|
|
16
16
|
// prop-merge stack so nested StatusBars compose (deepest/last wins). This module
|
package/build/render.js
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
// Mount a React element tree onto a Fabric surface. The native host hands us a
|
|
2
2
|
// rootTag (via AppRegistry.registerRunnable); we create a surface for it and let
|
|
3
3
|
// the reconciler drive shared, which commits into nativeFabricUIManager.
|
|
4
|
-
import { createSurface, disposeRoot, setEventDispatcher, dlog, } from '@symbiote-native/engine';
|
|
4
|
+
import { createSurface, disposeRoot, setEventDispatcher, dlog, reportUncaughtError, } from '@symbiote-native/engine';
|
|
5
5
|
import reconciler, { withDiscretePriority } from './host-config.js';
|
|
6
6
|
import { LegacyRoot } from './reconciler-constants.js';
|
|
7
7
|
const noop = () => { };
|
|
8
|
+
function errorReporter(origin) {
|
|
9
|
+
return (error, info) => {
|
|
10
|
+
reportUncaughtError(error, { origin, componentStack: info.componentStack });
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const onUncaughtError = errorReporter('react render (no error boundary)');
|
|
14
|
+
// A boundary handled it, so it does NOT reach the native redbox — it goes to , off unless
|
|
15
|
+
// DEBUG is set.
|
|
16
|
+
//
|
|
17
|
+
// This deliberately DIVERGES from upstream, whose nativeOnCaughtError calls the same
|
|
18
|
+
// showErrorDialog as the uncaught path. The argument for upstream's choice is that the boundary
|
|
19
|
+
// decides what the USER sees, not whether the developer hears. The argument against, and the one
|
|
20
|
+
// this project takes: writing an ErrorBoundary IS the developer saying "I know this can throw and
|
|
21
|
+
// I am handling it here". Answering that with a full-screen redbox over the fallback the app just
|
|
22
|
+
// rendered contradicts the thing the app asked for, and it is the only adapter here that did it —
|
|
23
|
+
// Solid's ErrorBoundary is silent, and its canary reads as correct next to React's alarming one.
|
|
24
|
+
// An UNCAUGHT error still hits the redbox; the difference is exactly whether someone claimed it.
|
|
25
|
+
const onCaughtError = (error, info) => {
|
|
26
|
+
dlog(() => `react render (caught by error boundary): ${String(error)}${info.componentStack ?? ''}`);
|
|
27
|
+
};
|
|
28
|
+
// React recovered on its own (a concurrent render retried and succeeded), so this is not fatal -
|
|
29
|
+
// but it is still a real error the app swallowed a first render over. RN keeps React's
|
|
30
|
+
// defaultOnRecoverableError here, which reports it globally.
|
|
31
|
+
const onRecoverableError = errorReporter('react render (recovered)');
|
|
8
32
|
// A native event runs the listener (which may call setState) outside React's
|
|
9
33
|
// loop. Run it at discrete priority so the update takes the sync lane, then
|
|
10
34
|
// flush that work synchronously to paint the result.
|
|
@@ -41,7 +65,11 @@ export function mount(rootTag, element) {
|
|
|
41
65
|
// first) starts clean. Otherwise the stale container double-drives the surface.
|
|
42
66
|
teardown(rootTag);
|
|
43
67
|
const surface = createSurface(rootTag);
|
|
44
|
-
const container = reconciler.createContainer(surface, LegacyRoot, null, false, null, 'symbiote',
|
|
68
|
+
const container = reconciler.createContainer(surface, LegacyRoot, null, false, null, 'symbiote', onUncaughtError, onCaughtError, onRecoverableError,
|
|
69
|
+
// onDefaultTransitionIndicator - the ONE that is genuinely a no-op. RN's own renderer says
|
|
70
|
+
// so in as many words: "Native doesn't have a default indicator" (ReactFabric.js's
|
|
71
|
+
// nativeOnDefaultTransitionIndicator).
|
|
72
|
+
noop, null);
|
|
45
73
|
containers.set(rootTag, container);
|
|
46
74
|
// react-reconciler 0.33 exposes updateContainerSync + flushSyncWork for an
|
|
47
75
|
// immediate render/commit; @types 0.32 still lists the older updateContainer /
|