mirror of
https://github.com/hanzoai/insights-js.git
synced 2026-10-30 18:34:19 +00:00
* perf(react-native): coalesce storage writes with a debounce window RN persists the whole storage blob on every change, so a burst of captures re-serializes a growing blob N times (O(n^2)) and does N disk writes. Batch writes into a 100ms window while keeping the in-memory copy current; event flush, AppState background, shutdown, and login/logout still drain synchronously so the queue and identity stay durable. Refine captureException durability. Drain both storage pipelines to disk only when the exception is fatal (tagged via $exception_level), rather than unconditionally on every captureException: console autocapture turns every console.error/warn into a captureException, so an unconditional drain would re-introduce write amplification. Handled exceptions persist via the normal debounce. Soften the durability comments to say writes are initiated (best-effort, async) rather than guaranteed to land before a crash. - Drain on optIn() / optOut(). Consent must be durable: a hard-kill within the debounce window before any flush/background/shutdown would lose the OptedOut write, and the optedOut getter falls back to !defaultOptIn so capture silently resumes for a user who explicitly opted out. Same crash-window the PR closes for logout/identify. - New storage test: the debounced write fires on its own after the window. Every other functional test forced the write via waitForPersist, so a regression where the timer never armed would ship green. - New storage test: the timer is not reset by later mutations (arm-once, no starvation). Guards against a textbook clear-and-reschedule debounce. - Refined the fatal-exception assertion to check the parsed events queue for an item whose message.event is \$exception, rather than a substring match that could pass on only the level tag round-tripping. - Trimmed the verbose drain-site comments and centralized the waitForPersist contract on the method doc (addresses the PR feedback). - Updated the changeset to note custom-storage write-timing and the ~100ms loss window.
77 lines
2.7 KiB
TypeScript
77 lines
2.7 KiB
TypeScript
import { Tabs } from 'expo-router'
|
|
import React from 'react'
|
|
import { Platform } from 'react-native'
|
|
|
|
import { HapticTab } from '@/components/HapticTab'
|
|
import { IconSymbol } from '@/components/ui/IconSymbol'
|
|
import TabBarBackground from '@/components/ui/TabBarBackground'
|
|
import { Colors } from '@/constants/Colors'
|
|
import { useColorScheme } from '@/hooks/useColorScheme'
|
|
|
|
export default function TabLayout() {
|
|
const colorScheme = useColorScheme()
|
|
|
|
return (
|
|
<Tabs
|
|
screenOptions={{
|
|
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
|
headerShown: false,
|
|
tabBarButton: HapticTab,
|
|
tabBarBackground: TabBarBackground,
|
|
tabBarStyle: Platform.select({
|
|
ios: {
|
|
// Use a transparent background on iOS to show the blur effect
|
|
position: 'absolute',
|
|
},
|
|
default: {},
|
|
}),
|
|
}}
|
|
>
|
|
<Tabs.Screen
|
|
name="index"
|
|
options={{
|
|
title: 'Home',
|
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="explore"
|
|
options={{
|
|
title: 'Explore',
|
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="error-tracking"
|
|
options={{
|
|
title: 'Error Tracking',
|
|
tabBarIcon: ({ color }) => (
|
|
<IconSymbol size={28} name="exclamationmark.warninglight" color={color} />
|
|
),
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="tracing-headers"
|
|
options={{
|
|
title: 'Tracing Headers',
|
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="link" color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="logs"
|
|
options={{
|
|
title: 'Logs',
|
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="text.bubble.fill" color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="storage-burst"
|
|
options={{
|
|
title: 'Storage',
|
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="list.bullet.rectangle" color={color} />,
|
|
}}
|
|
/>
|
|
</Tabs>
|
|
)
|
|
}
|