Skip to content

Commit 355d27e

Browse files
authored
chore: install reactotron-core-types and update usage (#48)
* Update package dependencies to include reactotron-core-contract version 0.2.5 in package.json and package-lock.json * Refactor timeline item types to use CommandType constants from reactotron-core-contract - Updated TimelineItem types in various components to utilize CommandType for better type safety and consistency. - Re-exported types from reactotron-core-contract in app/types.ts for convenience. - Adjusted type guards in Timeline components to check against CommandType values instead of string literals. - Enhanced StateSubscription type to align with the contract's structure.
1 parent 46aa5ce commit 355d27e

File tree

11 files changed

+93
-54
lines changed

11 files changed

+93
-54
lines changed

app/components/DetailPanel.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
Linking,
1111
} from "react-native"
1212
import { themed } from "../theme/theme"
13-
import { TimelineItem } from "../types"
13+
import { CommandType } from "reactotron-core-contract"
14+
import type { TimelineItem } from "../types"
1415
import { TreeViewWithProvider } from "./TreeView"
1516
import ActionButton from "./ActionButton"
1617
import { Tooltip } from "./Tooltip"
@@ -44,9 +45,9 @@ export function DetailPanel({ selectedItem, onClose }: DetailPanelProps) {
4445

4546
const getHeaderTitle = () => {
4647
switch (selectedItem.type) {
47-
case "log":
48+
case CommandType.Log:
4849
return "Log Details"
49-
case "display":
50+
case CommandType.Display:
5051
return "Display Details"
5152
default:
5253
return "Network Details"
@@ -55,12 +56,11 @@ export function DetailPanel({ selectedItem, onClose }: DetailPanelProps) {
5556

5657
const renderDetailContent = () => {
5758
switch (selectedItem.type) {
58-
case "log":
59+
case CommandType.Log:
5960
return <LogDetailContent item={selectedItem} />
60-
case "display":
61+
case CommandType.Display:
6162
return <DisplayDetailContent item={selectedItem} />
62-
case "api.request":
63-
case "api.response":
63+
case CommandType.ApiResponse:
6464
return <NetworkDetailContent item={selectedItem} />
6565
default:
6666
return null
@@ -113,7 +113,11 @@ export function DetailPanel({ selectedItem, onClose }: DetailPanelProps) {
113113
)
114114
}
115115

116-
function DisplayDetailContent({ item }: { item: TimelineItem & { type: "display" } }) {
116+
function DisplayDetailContent({
117+
item,
118+
}: {
119+
item: TimelineItem & { type: typeof CommandType.Display }
120+
}) {
117121
const { payload } = item
118122
const { name, image, preview, ...rest } = payload
119123

@@ -183,7 +187,7 @@ function DisplayDetailContent({ item }: { item: TimelineItem & { type: "display"
183187
/**
184188
* Renders detailed content for log timeline items including level, message, stack trace, and metadata.
185189
*/
186-
function LogDetailContent({ item }: { item: TimelineItem & { type: "log" } }) {
190+
function LogDetailContent({ item }: { item: TimelineItem & { type: typeof CommandType.Log } }) {
187191
const { payload } = item
188192

189193
return (
@@ -234,7 +238,7 @@ function LogDetailContent({ item }: { item: TimelineItem & { type: "log" } }) {
234238
function NetworkDetailContent({
235239
item,
236240
}: {
237-
item: TimelineItem & { type: "api.request" | "api.response" }
241+
item: TimelineItem & { type: typeof CommandType.ApiResponse }
238242
}) {
239243
const { payload } = item
240244

app/components/TimelineDisplayItem.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { TimelineItemDisplay } from "../types"
1+
import { CommandType } from "reactotron-core-contract"
2+
import type { TimelineItemDisplay } from "../types"
23
import { TimelineItem } from "./TimelineItem"
34

45
type TimelineDisplayItemProps = {
@@ -18,7 +19,7 @@ export function TimelineDisplayItem({
1819
const { payload, date, deltaTime, important } = item
1920

2021
// Type guard to ensure this is a display item
21-
if (item.type !== "display") return null
22+
if (item.type !== CommandType.Display) return null
2223

2324
return (
2425
<TimelineItem

app/components/TimelineLogItem.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { MenuListEntry } from "../utils/useActionMenu"
2-
import { TimelineItemLog } from "../types"
2+
import { CommandType } from "reactotron-core-contract"
3+
import type { TimelineItemLog } from "../types"
34
import { TimelineItem } from "./TimelineItem"
45
import IRClipboard from "../native/IRClipboard/NativeIRClipboard"
56

@@ -16,7 +17,7 @@ export function TimelineLogItem({ item, isSelected = false, onSelect }: Timeline
1617
const { payload, date, deltaTime, important } = item
1718

1819
// Type guard to ensure this is a log item
19-
if (item.type !== "log") return null
20+
if (item.type !== CommandType.Log) return null
2021

2122
// Determine log level and color
2223
let level: string = "DEBUG"

app/components/TimelineNetworkItem.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { TimelineItemNetwork } from "../types"
1+
import { CommandType } from "reactotron-core-contract"
2+
import type { TimelineItemNetwork } from "../types"
23
import { TimelineItem } from "./TimelineItem"
34
import { useTheme } from "../theme/theme"
45
import type { MenuListEntry } from "../utils/useActionMenu"
@@ -19,7 +20,7 @@ export function TimelineNetworkItem({
1920
onSelect,
2021
}: TimelineNetworkItemProps) {
2122
// Type guard to ensure this is a network item
22-
if (item.type !== "api.response") return null
23+
if (item.type !== CommandType.ApiResponse) return null
2324

2425
const { payload, date, deltaTime, important } = item
2526

app/components/TimelineToolbar.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
export type FilterType = "all" | "log" | "display" | "api.request" | "api.response"
1+
import { CommandType } from "reactotron-core-contract"
2+
3+
export type FilterType =
4+
| "all"
5+
| typeof CommandType.Log
6+
| typeof CommandType.Display
7+
| typeof CommandType.ApiResponse
28
// export type LogLevel = "all" | "debug" | "warn" | "error"
39
// export type SortBy = "time-newest" | "time-oldest" | "type" | "level"
410

app/screens/StateScreen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { TreeViewWithProvider } from "../components/TreeView"
66
import { useState } from "react"
77
import { Divider } from "../components/Divider"
88
import { useKeyboardEvents } from "../utils/system"
9-
import { StateSubscription } from "app/types"
9+
import type { StateSubscription } from "app/types"
1010
import { Icon } from "../components/Icon"
1111

1212
export function StateScreen() {

app/screens/TimelineScreen.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useGlobal } from "../state/useGlobal"
2-
import { TimelineItem } from "../types"
2+
import { CommandType } from "reactotron-core-contract"
3+
import type { TimelineItem } from "../types"
34
import { TimelineLogItem } from "../components/TimelineLogItem"
45
import { TimelineNetworkItem } from "../components/TimelineNetworkItem"
56
import { TimelineDisplayItem } from "../components/TimelineDisplayItem"
@@ -37,13 +38,13 @@ const TimelineItemRenderer = ({
3738
onSelectItem(item)
3839
}
3940

40-
if (item.type === "log") {
41+
if (item.type === CommandType.Log) {
4142
return <TimelineLogItem item={item} isSelected={isSelected} onSelect={handleSelectItem} />
4243
}
43-
if (item.type === "display") {
44+
if (item.type === CommandType.Display) {
4445
return <TimelineDisplayItem item={item} isSelected={isSelected} onSelect={handleSelectItem} />
4546
}
46-
if (item.type === "api.response") {
47+
if (item.type === CommandType.ApiResponse) {
4748
return <TimelineNetworkItem item={item} isSelected={isSelected} onSelect={handleSelectItem} />
4849
}
4950
console.tron.log("Unknown item", item)
@@ -53,11 +54,11 @@ const TimelineItemRenderer = ({
5354
function getTimelineTypes(activeItem: MenuItemId): FilterType[] {
5455
switch (activeItem) {
5556
case "logs":
56-
return ["log", "display"]
57+
return [CommandType.Log, CommandType.Display]
5758
case "network":
58-
return ["api.request", "api.response"]
59+
return [CommandType.ApiResponse]
5960
default:
60-
return ["log", "display", "api.request", "api.response"]
61+
return [CommandType.Log, CommandType.Display, CommandType.ApiResponse]
6162
}
6263
}
6364

app/state/connectToServer.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getUUID } from "../utils/random/getUUID"
2-
import { StateSubscription, TimelineItem } from "../types"
2+
import { CommandType } from "reactotron-core-contract"
3+
import type { StateSubscription, TimelineItem } from "../types"
34
import { withGlobal } from "./useGlobal"
45
import { isSafeKey, sanitizeValue } from "../utils/sanitize"
56

@@ -86,12 +87,12 @@ export function connectToServer(props: { port: number } = { port: 9292 }): Unsub
8687
}
8788

8889
if (data.type === "command" && data.cmd) {
89-
if (data.cmd.type === "clear") setTimelineItems([])
90+
if (data.cmd.type === CommandType.Clear) setTimelineItems([])
9091

9192
if (
92-
data.cmd.type === "log" ||
93-
data.cmd.type === "api.response" ||
94-
data.cmd.type === "display"
93+
data.cmd.type === CommandType.Log ||
94+
data.cmd.type === CommandType.ApiResponse ||
95+
data.cmd.type === CommandType.Display
9596
) {
9697
// Add a unique ID to the timeline item
9798
data.cmd.id = `${data.cmd.clientId}-${data.cmd.messageId}`
@@ -106,7 +107,7 @@ export function connectToServer(props: { port: number } = { port: 9292 }): Unsub
106107
} else {
107108
console.tron.log("unknown command", data.cmd)
108109
}
109-
if (data.cmd.type === "state.values.change") {
110+
if (data.cmd.type === CommandType.StateValuesChange) {
110111
console.log("state.values.change", data.cmd)
111112
data.cmd.payload.changes.forEach((change: StateSubscription) => {
112113
if (!isSafeKey(data.cmd.clientId) || !isSafeKey(change.path)) {

app/types.ts

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
// Import types from the official Reactotron contract package
2+
import { CommandType } from "reactotron-core-contract"
3+
import type {
4+
ErrorStackFrame,
5+
ErrorLogPayload,
6+
CommandTypeKey,
7+
StateValuesChangePayload,
8+
StateValuesSubscribePayload,
9+
StateKeysRequestPayload,
10+
StateValuesRequestPayload,
11+
StateBackupRequestPayload,
12+
StateRestoreRequestPayload,
13+
Command,
14+
} from "reactotron-core-contract"
15+
116
/**
217
* ClientData is data describing a particular client
318
* (usually a React Native app running on a simulator or device).
@@ -34,19 +49,24 @@ export type ClientData = {
3449
address: string
3550
}
3651

37-
export interface ErrorStackFrame {
38-
fileName: string
39-
functionName: string
40-
lineNumber: number
41-
columnNumber: number | null
42-
}
43-
44-
export interface ErrorLogPayload {
45-
level: "error"
46-
message: string
47-
stack: Error["stack"] | string[] | ErrorStackFrame[]
52+
// Re-export types from reactotron-core-contract for convenience
53+
export type {
54+
ErrorStackFrame,
55+
ErrorLogPayload,
56+
CommandTypeKey,
57+
Command,
58+
StateValuesChangePayload,
59+
StateValuesSubscribePayload,
60+
StateKeysRequestPayload,
61+
StateValuesRequestPayload,
62+
StateBackupRequestPayload,
63+
StateRestoreRequestPayload,
4864
}
65+
export { CommandType }
4966

67+
// Extended LogPayload to support debug level with objects
68+
// Note: We extend the contract's LogPayload to allow Record<string, any> for debug messages
69+
// The contract only supports string messages, but we need richer debugging capabilities
5070
export type LogPayload =
5171
| {
5272
level: "debug"
@@ -81,13 +101,17 @@ export interface NetworkResponse {
81101
}
82102

83103
export interface NetworkPayload {
84-
type: "api.request" | "api.response"
104+
type: typeof CommandType.ApiResponse
85105
request?: NetworkRequest
86106
response?: NetworkResponse
87107
error?: string
88108
}
89109

90-
// Unified timeline item type
110+
/**
111+
* TimelineItem types are app-specific representations of commands received from reactotron-core-server.
112+
* While they share similarities with the Command type from reactotron-core-contract, they are
113+
* tailored for this macOS app's UI needs (e.g., date as string for serialization, additional id field).
114+
*/
91115
export type TimelineItemBase = {
92116
id: string
93117
important: boolean
@@ -99,23 +123,22 @@ export type TimelineItemBase = {
99123
}
100124

101125
export type TimelineItemLog = TimelineItemBase & {
102-
type: "log"
126+
type: typeof CommandType.Log
103127
payload: LogPayload
104128
}
105129

106130
export type TimelineItemNetwork = TimelineItemBase & {
107-
type: "api.request" | "api.response"
131+
type: typeof CommandType.ApiResponse
108132
payload: NetworkPayload
109133
}
110134

111135
export type TimelineItemDisplay = TimelineItemBase & {
112-
type: "display"
136+
type: typeof CommandType.Display
113137
payload: DisplayPayload
114138
}
115139

116140
export type TimelineItem = TimelineItemLog | TimelineItemNetwork | TimelineItemDisplay
117141

118-
export type StateSubscription = {
119-
path: string
120-
value: any
121-
}
142+
// StateSubscription represents a single state path/value pair tracked by the app
143+
// This is derived from the contract's StateValuesChangePayload structure
144+
export type StateSubscription = StateValuesChangePayload["changes"][number]

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)