@buoy-gg/shared-ui 1.7.7 → 2.1.1

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.
Files changed (137) hide show
  1. package/lib/commonjs/JsModal.js +33 -8
  2. package/lib/commonjs/clipboard/clipboard-impl.js +1 -1
  3. package/lib/commonjs/clipboard/copyToClipboard.js +0 -2
  4. package/lib/commonjs/dataViewer/diffThemes.js +35 -32
  5. package/lib/commonjs/history/HistoryProvider.js +246 -0
  6. package/lib/commonjs/history/components/HistoryEntryRow.js +146 -0
  7. package/lib/commonjs/history/components/HistoryList.js +174 -0
  8. package/lib/commonjs/history/components/index.js +25 -0
  9. package/lib/commonjs/history/index.js +61 -0
  10. package/lib/commonjs/history/types.js +5 -0
  11. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  12. package/lib/commonjs/hooks/useSafeAreaInsets.js +1 -22
  13. package/lib/commonjs/index.js +37 -46
  14. package/lib/commonjs/license/FeatureGate.js +13 -42
  15. package/lib/commonjs/license/index.js +43 -1
  16. package/lib/commonjs/settings/components/BubbleSettingsSection.js +7 -7
  17. package/lib/commonjs/storage/devToolsStorageKeys.js +11 -0
  18. package/lib/commonjs/ui/components/CopyButton.js +14 -29
  19. package/lib/commonjs/ui/components/DevToolsCard.js +106 -0
  20. package/lib/commonjs/ui/components/EventHistoryViewer/EventHistoryViewer.js +2 -1
  21. package/lib/commonjs/ui/components/ExpandablePopover.js +13 -13
  22. package/lib/commonjs/ui/components/index.js +13 -0
  23. package/lib/commonjs/utils/formatting/httpFormatting.js +0 -6
  24. package/lib/commonjs/utils/index.js +0 -31
  25. package/lib/module/JsModal.js +33 -8
  26. package/lib/module/clipboard/clipboard-impl.js +1 -1
  27. package/lib/module/clipboard/copyToClipboard.js +0 -2
  28. package/lib/module/dataViewer/diffThemes.js +35 -32
  29. package/lib/module/history/HistoryProvider.js +237 -0
  30. package/lib/module/history/components/HistoryEntryRow.js +142 -0
  31. package/lib/module/history/components/HistoryList.js +169 -0
  32. package/lib/module/history/components/index.js +8 -0
  33. package/lib/module/history/index.js +15 -0
  34. package/lib/module/history/types.js +3 -0
  35. package/lib/module/hooks/safe-area-impl.js +1 -1
  36. package/lib/module/hooks/useSafeAreaInsets.js +0 -20
  37. package/lib/module/index.js +5 -4
  38. package/lib/module/license/FeatureGate.js +11 -40
  39. package/lib/module/license/index.js +41 -1
  40. package/lib/module/settings/components/BubbleSettingsSection.js +7 -7
  41. package/lib/module/storage/devToolsStorageKeys.js +11 -0
  42. package/lib/module/ui/components/CopyButton.js +12 -28
  43. package/lib/module/ui/components/DevToolsCard.js +102 -0
  44. package/lib/module/ui/components/EventHistoryViewer/EventHistoryViewer.js +2 -1
  45. package/lib/module/ui/components/ExpandablePopover.js +14 -14
  46. package/lib/module/ui/components/index.js +1 -0
  47. package/lib/module/utils/formatting/httpFormatting.js +0 -6
  48. package/lib/module/utils/index.js +0 -1
  49. package/lib/typescript/commonjs/JsModal.d.ts +2 -0
  50. package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
  51. package/lib/typescript/commonjs/clipboard/clipboard-impl.d.ts +1 -1
  52. package/lib/typescript/commonjs/clipboard/copyToClipboard.d.ts.map +1 -1
  53. package/lib/typescript/commonjs/dataViewer/diffThemes.d.ts +1 -1
  54. package/lib/typescript/commonjs/dataViewer/diffThemes.d.ts.map +1 -1
  55. package/lib/typescript/commonjs/history/HistoryProvider.d.ts +56 -0
  56. package/lib/typescript/commonjs/history/HistoryProvider.d.ts.map +1 -0
  57. package/lib/typescript/commonjs/history/components/HistoryEntryRow.d.ts +22 -0
  58. package/lib/typescript/commonjs/history/components/HistoryEntryRow.d.ts.map +1 -0
  59. package/lib/typescript/commonjs/history/components/HistoryList.d.ts +47 -0
  60. package/lib/typescript/commonjs/history/components/HistoryList.d.ts.map +1 -0
  61. package/lib/typescript/commonjs/history/components/index.d.ts +6 -0
  62. package/lib/typescript/commonjs/history/components/index.d.ts.map +1 -0
  63. package/lib/typescript/commonjs/history/index.d.ts +9 -0
  64. package/lib/typescript/commonjs/history/index.d.ts.map +1 -0
  65. package/lib/typescript/commonjs/history/types.d.ts +171 -0
  66. package/lib/typescript/commonjs/history/types.d.ts.map +1 -0
  67. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  68. package/lib/typescript/commonjs/hooks/useSafeAreaInsets.d.ts +0 -13
  69. package/lib/typescript/commonjs/hooks/useSafeAreaInsets.d.ts.map +1 -1
  70. package/lib/typescript/commonjs/index.d.ts +3 -2
  71. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  72. package/lib/typescript/commonjs/license/FeatureGate.d.ts.map +1 -1
  73. package/lib/typescript/commonjs/license/LicenseEntryModal.d.ts +5 -0
  74. package/lib/typescript/commonjs/license/LicenseEntryModal.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/license/index.d.ts +15 -0
  76. package/lib/typescript/commonjs/license/index.d.ts.map +1 -1
  77. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +11 -0
  78. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/ui/components/CopyButton.d.ts +0 -2
  80. package/lib/typescript/commonjs/ui/components/CopyButton.d.ts.map +1 -1
  81. package/lib/typescript/commonjs/ui/components/DevToolsCard.d.ts +54 -0
  82. package/lib/typescript/commonjs/ui/components/DevToolsCard.d.ts.map +1 -0
  83. package/lib/typescript/commonjs/ui/components/EventHistoryViewer/EventHistoryViewer.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/ui/components/index.d.ts +2 -0
  85. package/lib/typescript/commonjs/ui/components/index.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/utils/formatting/httpFormatting.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/utils/index.d.ts +0 -1
  88. package/lib/typescript/commonjs/utils/index.d.ts.map +1 -1
  89. package/lib/typescript/module/JsModal.d.ts +2 -0
  90. package/lib/typescript/module/JsModal.d.ts.map +1 -1
  91. package/lib/typescript/module/clipboard/clipboard-impl.d.ts +1 -1
  92. package/lib/typescript/module/clipboard/copyToClipboard.d.ts.map +1 -1
  93. package/lib/typescript/module/dataViewer/diffThemes.d.ts +1 -1
  94. package/lib/typescript/module/dataViewer/diffThemes.d.ts.map +1 -1
  95. package/lib/typescript/module/history/HistoryProvider.d.ts +56 -0
  96. package/lib/typescript/module/history/HistoryProvider.d.ts.map +1 -0
  97. package/lib/typescript/module/history/components/HistoryEntryRow.d.ts +22 -0
  98. package/lib/typescript/module/history/components/HistoryEntryRow.d.ts.map +1 -0
  99. package/lib/typescript/module/history/components/HistoryList.d.ts +47 -0
  100. package/lib/typescript/module/history/components/HistoryList.d.ts.map +1 -0
  101. package/lib/typescript/module/history/components/index.d.ts +6 -0
  102. package/lib/typescript/module/history/components/index.d.ts.map +1 -0
  103. package/lib/typescript/module/history/index.d.ts +9 -0
  104. package/lib/typescript/module/history/index.d.ts.map +1 -0
  105. package/lib/typescript/module/history/types.d.ts +171 -0
  106. package/lib/typescript/module/history/types.d.ts.map +1 -0
  107. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  108. package/lib/typescript/module/hooks/useSafeAreaInsets.d.ts +0 -13
  109. package/lib/typescript/module/hooks/useSafeAreaInsets.d.ts.map +1 -1
  110. package/lib/typescript/module/index.d.ts +3 -2
  111. package/lib/typescript/module/index.d.ts.map +1 -1
  112. package/lib/typescript/module/license/FeatureGate.d.ts.map +1 -1
  113. package/lib/typescript/module/license/LicenseEntryModal.d.ts +5 -0
  114. package/lib/typescript/module/license/LicenseEntryModal.d.ts.map +1 -1
  115. package/lib/typescript/module/license/index.d.ts +15 -0
  116. package/lib/typescript/module/license/index.d.ts.map +1 -1
  117. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +11 -0
  118. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  119. package/lib/typescript/module/ui/components/CopyButton.d.ts +0 -2
  120. package/lib/typescript/module/ui/components/CopyButton.d.ts.map +1 -1
  121. package/lib/typescript/module/ui/components/DevToolsCard.d.ts +54 -0
  122. package/lib/typescript/module/ui/components/DevToolsCard.d.ts.map +1 -0
  123. package/lib/typescript/module/ui/components/EventHistoryViewer/EventHistoryViewer.d.ts.map +1 -1
  124. package/lib/typescript/module/ui/components/index.d.ts +2 -0
  125. package/lib/typescript/module/ui/components/index.d.ts.map +1 -1
  126. package/lib/typescript/module/utils/formatting/httpFormatting.d.ts.map +1 -1
  127. package/lib/typescript/module/utils/index.d.ts +0 -1
  128. package/lib/typescript/module/utils/index.d.ts.map +1 -1
  129. package/package.json +31 -7
  130. package/scripts/detect-clipboard.js +63 -1
  131. package/scripts/detect-safe-area.js +63 -1
  132. package/lib/commonjs/utils/safeAsyncStorage.js +0 -71
  133. package/lib/module/utils/safeAsyncStorage.js +0 -64
  134. package/lib/typescript/commonjs/utils/safeAsyncStorage.d.ts +0 -35
  135. package/lib/typescript/commonjs/utils/safeAsyncStorage.d.ts.map +0 -1
  136. package/lib/typescript/module/utils/safeAsyncStorage.d.ts +0 -35
  137. package/lib/typescript/module/utils/safeAsyncStorage.d.ts.map +0 -1
@@ -9,7 +9,7 @@ var _reactNative = require("react-native");
9
9
  var _useSafeAreaInsets = require("./hooks/useSafeAreaInsets.js");
10
10
  var _index = require("./ui/gameUI/index.js");
11
11
  var _index2 = require("./ui/components/index.js");
12
- var _safeAsyncStorage = require("./utils/safeAsyncStorage.js");
12
+ var _persistentStorage = require("./utils/persistentStorage.js");
13
13
  var _devToolsStorageKeys = require("./storage/devToolsStorageKeys.js");
14
14
  var _index3 = require("./context/index.js");
15
15
  var _jsxRuntime = require("react/jsx-runtime");
@@ -58,7 +58,7 @@ class ModalStorage {
58
58
  static async save(key, value) {
59
59
  try {
60
60
  this.memoryCache[key] = value;
61
- await (0, _safeAsyncStorage.safeSetItem)(key, JSON.stringify(value));
61
+ await _persistentStorage.persistentStorage.setItem(key, JSON.stringify(value));
62
62
  } catch (error) {
63
63
  // Failed to save modal state
64
64
  }
@@ -78,7 +78,7 @@ class ModalStorage {
78
78
  }
79
79
 
80
80
  // Load from storage (AsyncStorage or memory fallback)
81
- const stored = await (0, _safeAsyncStorage.safeGetItem)(key);
81
+ const stored = await _persistentStorage.persistentStorage.getItem(key);
82
82
  if (stored) {
83
83
  const parsed = JSON.parse(stored);
84
84
  this.memoryCache[key] = parsed;
@@ -339,7 +339,8 @@ const JsModalComponent = ({
339
339
  onMinimize,
340
340
  minimizeTargetPosition,
341
341
  initialModalState,
342
- zIndex
342
+ zIndex,
343
+ disableScrollWrapper = false
343
344
  }) => {
344
345
  const insets = (0, _useSafeAreaInsets.useSafeAreaInsets)();
345
346
  const [isStateLoaded, setIsStateLoaded] = (0, _react.useState)(!enablePersistence);
@@ -429,7 +430,7 @@ const JsModalComponent = ({
429
430
  const loadHintStatus = async () => {
430
431
  try {
431
432
  const hintKey = _devToolsStorageKeys.devToolsStorageKeys.modal.hintAcknowledged();
432
- const acknowledged = await (0, _safeAsyncStorage.safeGetItem)(hintKey);
433
+ const acknowledged = await _persistentStorage.persistentStorage.getItem(hintKey);
433
434
  if (mounted) {
434
435
  // Show hint if not acknowledged yet
435
436
  setShowHint(acknowledged !== "true");
@@ -453,7 +454,7 @@ const JsModalComponent = ({
453
454
  const handleHintAcknowledge = (0, _react.useCallback)(async () => {
454
455
  try {
455
456
  const hintKey = _devToolsStorageKeys.devToolsStorageKeys.modal.hintAcknowledged();
456
- await (0, _safeAsyncStorage.safeSetItem)(hintKey, "true");
457
+ await _persistentStorage.persistentStorage.setItem(hintKey, "true");
457
458
  setShowHint(false);
458
459
  } catch (error) {
459
460
  // Failed to save hint acknowledgment, just hide it locally
@@ -1101,7 +1102,19 @@ const JsModalComponent = ({
1101
1102
  })
1102
1103
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1103
1104
  style: [styles.content, customStyles.content],
1104
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
1105
+ children: [disableScrollWrapper ?
1106
+ /*#__PURE__*/
1107
+ // Render children directly when they manage their own scrolling (FlatList, etc.)
1108
+ (0, _jsxRuntime.jsx)(_reactNative.View, {
1109
+ style: {
1110
+ flex: 1,
1111
+ paddingBottom: footerHeight
1112
+ },
1113
+ children: children
1114
+ }) :
1115
+ /*#__PURE__*/
1116
+ // Wrap in ScrollView for content that needs scrolling
1117
+ (0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
1105
1118
  style: {
1106
1119
  flex: 1
1107
1120
  },
@@ -1190,7 +1203,19 @@ const JsModalComponent = ({
1190
1203
  onAcknowledge: handleHintAcknowledge
1191
1204
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1192
1205
  style: [styles.content, customStyles.content],
1193
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
1206
+ children: [disableScrollWrapper ?
1207
+ /*#__PURE__*/
1208
+ // Render children directly when they manage their own scrolling (FlatList, etc.)
1209
+ (0, _jsxRuntime.jsx)(_reactNative.View, {
1210
+ style: {
1211
+ flex: 1,
1212
+ paddingBottom: footerHeight
1213
+ },
1214
+ children: children
1215
+ }) :
1216
+ /*#__PURE__*/
1217
+ // Wrap in ScrollView for content that needs scrolling
1218
+ (0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
1194
1219
  style: {
1195
1220
  flex: 1
1196
1221
  },
@@ -7,7 +7,7 @@ exports.isClipboardAvailable = exports.clipboardType = exports.clipboardFunction
7
7
  /**
8
8
  * Auto-generated clipboard implementation
9
9
  * Detected: none
10
- * Generated at: 2026-01-03T18:51:49.000Z
10
+ * Generated at: 2026-01-12T04:02:16.197Z
11
11
  *
12
12
  * DO NOT EDIT - This file is generated by scripts/detect-clipboard.js
13
13
  *
@@ -26,9 +26,7 @@ async function copyToClipboard(value) {
26
26
  // This is important when used with virtualized lists or React state
27
27
  try {
28
28
  // For simple objects, use structured clone if available
29
- // @ts-expect-error structuredClone is not defined in the browser
30
29
  if (typeof structuredClone === "function") {
31
- // @ts-expect-error tructuredClone is not defined in the browser
32
30
  const cloned = structuredClone(value);
33
31
  return (0, _safeStringify.safeStringify)(cloned, 2, {
34
32
  depthLimit: 100,
@@ -52,51 +52,54 @@ const gitClassicTheme = exports.gitClassicTheme = {
52
52
 
53
53
  /**
54
54
  * Dev Tools Default Theme
55
- * Clean dark theme using our gameUIColors
55
+ * Clean dark theme matching Buoy website brand colors
56
56
  */
57
57
  const devToolsDefaultTheme = exports.devToolsDefaultTheme = {
58
58
  name: "Dev Tools Default",
59
- description: "Clean dark theme with our game UI colors",
60
- // Use our gameUIColors-inspired dark theme
61
- background: "#0A0E1A",
62
- panelBackground: "#0F1420",
63
- headerBackground: "#141925",
64
- // Diff colors with our cyan/yellow/red scheme
65
- addedBackground: "rgba(74, 255, 159, 0.1)",
66
- removedBackground: "rgba(255, 82, 82, 0.1)",
67
- modifiedBackground: "rgba(0, 184, 230, 0.1)",
59
+ description: "Clean dark theme with Buoy brand colors",
60
+ // Surface colors (matching website dark theme)
61
+ background: "#121212",
62
+ panelBackground: "#1A1A1A",
63
+ headerBackground: "#1A1A1A",
64
+ // Diff colors using website's semantic colors
65
+ // Added: Primary teal (#20C997)
66
+ // Removed: Error red (#EF4444)
67
+ // Modified: Secondary purple (#9B70E0)
68
+ addedBackground: "rgba(32, 201, 151, 0.12)",
69
+ removedBackground: "rgba(239, 68, 68, 0.12)",
70
+ modifiedBackground: "rgba(155, 112, 224, 0.12)",
68
71
  unchangedBackground: "transparent",
69
72
  contextBackground: "rgba(255, 255, 255, 0.02)",
70
73
  // Text colors
71
- addedText: "#4AFF9F",
72
- removedText: "#FF5252",
73
- modifiedText: "#00B8E6",
74
- unchangedText: "#B8BFC9",
74
+ addedText: "#20C997",
75
+ removedText: "#EF4444",
76
+ modifiedText: "#9B70E0",
77
+ unchangedText: "#E0E0E0",
75
78
  // Word-level highlights
76
- addedWordHighlight: "rgba(74, 255, 159, 0.3)",
77
- removedWordHighlight: "rgba(255, 82, 82, 0.3)",
79
+ addedWordHighlight: "rgba(32, 201, 151, 0.3)",
80
+ removedWordHighlight: "rgba(239, 68, 68, 0.3)",
78
81
  // UI elements
79
- lineNumberBackground: "#0A0E1A",
80
- lineNumberText: "#7A8599",
81
- lineNumberBorder: "#1F2937",
82
+ lineNumberBackground: "#121212",
83
+ lineNumberText: "#A0A0A0",
84
+ lineNumberBorder: "#333333",
82
85
  // Markers
83
- markerAddedBackground: "rgba(74, 255, 159, 0.2)",
84
- markerRemovedBackground: "rgba(255, 82, 82, 0.2)",
85
- markerModifiedBackground: "rgba(0, 184, 230, 0.2)",
86
- markerText: "#7A8599",
86
+ markerAddedBackground: "rgba(32, 201, 151, 0.2)",
87
+ markerRemovedBackground: "rgba(239, 68, 68, 0.2)",
88
+ markerModifiedBackground: "rgba(155, 112, 224, 0.2)",
89
+ markerText: "#A0A0A0",
87
90
  // Borders and dividers
88
- borderColor: "#1F2937",
89
- dividerColor: "#1F2937",
91
+ borderColor: "#333333",
92
+ dividerColor: "#333333",
90
93
  // Summary bar
91
- summaryBackground: "#0F1420",
92
- summaryAddedText: "#4AFF9F",
93
- summaryRemovedText: "#FF5252",
94
- summaryModifiedText: "#00B8E6",
94
+ summaryBackground: "#1A1A1A",
95
+ summaryAddedText: "#20C997",
96
+ summaryRemovedText: "#EF4444",
97
+ summaryModifiedText: "#9B70E0",
95
98
  // Empty state
96
- emptyStateText: "#7A8599",
99
+ emptyStateText: "#888888",
97
100
  // Separator
98
- separatorBackground: "#141925",
99
- separatorText: "#7A8599"
101
+ separatorBackground: "#1A1A1A",
102
+ separatorText: "#A0A0A0"
100
103
  };
101
104
 
102
105
  /**
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.HistoryProvider = HistoryProvider;
7
+ exports.useAllHistoryEntries = useAllHistoryEntries;
8
+ exports.useHistoryAdapter = useHistoryAdapter;
9
+ exports.useHistoryAdapters = useHistoryAdapters;
10
+ exports.useHistoryContext = useHistoryContext;
11
+ exports.useHistoryEntryCounts = useHistoryEntryCounts;
12
+ var _react = require("react");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ /**
15
+ * HistoryProvider - Context for Universal History DevTools
16
+ *
17
+ * Manages registered adapters and provides unified access to history
18
+ * from Redux, Zustand, MMKV, React Query, etc.
19
+ */
20
+
21
+ // =============================================================================
22
+ // CONTEXT VALUE
23
+ // =============================================================================
24
+
25
+ const HistoryContext = /*#__PURE__*/(0, _react.createContext)(null);
26
+
27
+ // =============================================================================
28
+ // PROVIDER
29
+ // =============================================================================
30
+
31
+ function HistoryProvider({
32
+ children,
33
+ initialAdapters = []
34
+ }) {
35
+ // Adapter registry
36
+ const [adapterMap, setAdapterMap] = (0, _react.useState)(() => {
37
+ const map = new Map();
38
+ initialAdapters.forEach(reg => {
39
+ map.set(reg.adapter.id, {
40
+ ...reg,
41
+ enabled: reg.enabled ?? true
42
+ });
43
+ });
44
+ return map;
45
+ });
46
+
47
+ // Selected adapter filter
48
+ const [selectedAdapterId, setSelectedAdapterId] = (0, _react.useState)(null);
49
+
50
+ // Refresh trigger
51
+ const [refreshKey, setRefreshKey] = (0, _react.useState)(0);
52
+ const refresh = (0, _react.useCallback)(() => setRefreshKey(k => k + 1), []);
53
+
54
+ // Subscribe to all adapters
55
+ (0, _react.useEffect)(() => {
56
+ const unsubscribes = [];
57
+ adapterMap.forEach(reg => {
58
+ if (reg.enabled) {
59
+ const unsub = reg.adapter.subscribe(refresh);
60
+ unsubscribes.push(unsub);
61
+ }
62
+ });
63
+ return () => {
64
+ unsubscribes.forEach(unsub => unsub());
65
+ };
66
+ }, [adapterMap, refresh]);
67
+
68
+ // Get sorted adapters list
69
+ const adapters = (0, _react.useMemo)(() => {
70
+ return Array.from(adapterMap.values()).filter(reg => reg.enabled).sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100)).map(reg => reg.adapter);
71
+ }, [adapterMap, refreshKey]);
72
+
73
+ // Get adapter by id
74
+ const getAdapter = (0, _react.useCallback)(id => adapterMap.get(id)?.adapter, [adapterMap]);
75
+
76
+ // Register adapter
77
+ const registerAdapter = (0, _react.useCallback)(registration => {
78
+ setAdapterMap(prev => {
79
+ const next = new Map(prev);
80
+ next.set(registration.adapter.id, {
81
+ ...registration,
82
+ enabled: registration.enabled ?? true
83
+ });
84
+ return next;
85
+ });
86
+ }, []);
87
+
88
+ // Unregister adapter
89
+ const unregisterAdapter = (0, _react.useCallback)(id => {
90
+ setAdapterMap(prev => {
91
+ const next = new Map(prev);
92
+ next.delete(id);
93
+ return next;
94
+ });
95
+ }, []);
96
+
97
+ // Get all entries (combined or filtered)
98
+ const getAllEntries = (0, _react.useCallback)(filter => {
99
+ let entries = [];
100
+
101
+ // Collect from all (or selected) adapters
102
+ const sourceAdapters = selectedAdapterId && filter?.sources === undefined ? adapters.filter(a => a.id === selectedAdapterId) : adapters;
103
+ sourceAdapters.forEach(adapter => {
104
+ // Skip if sources filter excludes this adapter
105
+ if (filter?.sources && !filter.sources.includes(adapter.id)) {
106
+ return;
107
+ }
108
+ entries = entries.concat(adapter.getEntries());
109
+ });
110
+
111
+ // Apply filters
112
+ if (filter) {
113
+ entries = applyFilter(entries, filter);
114
+ }
115
+
116
+ // Sort by timestamp (newest first by default)
117
+ entries.sort((a, b) => b.timestamp - a.timestamp);
118
+ return entries;
119
+ }, [adapters, selectedAdapterId, refreshKey]);
120
+
121
+ // Get entry counts per source
122
+ const getEntryCounts = (0, _react.useCallback)(() => {
123
+ const counts = {};
124
+ adapters.forEach(adapter => {
125
+ counts[adapter.id] = adapter.getEntryCount();
126
+ });
127
+ return counts;
128
+ }, [adapters, refreshKey]);
129
+ const value = (0, _react.useMemo)(() => ({
130
+ adapters,
131
+ getAdapter,
132
+ registerAdapter,
133
+ unregisterAdapter,
134
+ getAllEntries,
135
+ getEntryCounts,
136
+ selectedAdapterId,
137
+ setSelectedAdapterId,
138
+ refresh
139
+ }), [adapters, getAdapter, registerAdapter, unregisterAdapter, getAllEntries, getEntryCounts, selectedAdapterId, refresh]);
140
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(HistoryContext.Provider, {
141
+ value: value,
142
+ children: children
143
+ });
144
+ }
145
+
146
+ // =============================================================================
147
+ // HOOKS
148
+ // =============================================================================
149
+
150
+ /**
151
+ * Get the full history context
152
+ */
153
+ function useHistoryContext() {
154
+ const context = (0, _react.useContext)(HistoryContext);
155
+ if (!context) {
156
+ throw new Error("useHistoryContext must be used within a HistoryProvider");
157
+ }
158
+ return context;
159
+ }
160
+
161
+ /**
162
+ * Get all registered adapters
163
+ */
164
+ function useHistoryAdapters() {
165
+ return useHistoryContext().adapters;
166
+ }
167
+
168
+ /**
169
+ * Get a specific adapter by id
170
+ */
171
+ function useHistoryAdapter(id) {
172
+ return useHistoryContext().getAdapter(id);
173
+ }
174
+
175
+ /**
176
+ * Get combined entries from all adapters
177
+ */
178
+ function useAllHistoryEntries(filter) {
179
+ const {
180
+ getAllEntries
181
+ } = useHistoryContext();
182
+ return getAllEntries(filter);
183
+ }
184
+
185
+ /**
186
+ * Get entry counts per source
187
+ */
188
+ function useHistoryEntryCounts() {
189
+ return useHistoryContext().getEntryCounts();
190
+ }
191
+
192
+ // =============================================================================
193
+ // FILTER HELPER
194
+ // =============================================================================
195
+
196
+ function applyFilter(entries, filter) {
197
+ return entries.filter(entry => {
198
+ // Search text
199
+ if (filter.searchText) {
200
+ const search = filter.searchText.toLowerCase();
201
+ if (!entry.label.toLowerCase().includes(search)) {
202
+ return false;
203
+ }
204
+ }
205
+
206
+ // Only with changes
207
+ if (filter.onlyWithChanges && !entry.hasStateChange) {
208
+ return false;
209
+ }
210
+
211
+ // Only errors
212
+ if (filter.onlyErrors && entry.status !== "error") {
213
+ return false;
214
+ }
215
+
216
+ // Time range
217
+ if (filter.afterTimestamp && entry.timestamp < filter.afterTimestamp) {
218
+ return false;
219
+ }
220
+ if (filter.beforeTimestamp && entry.timestamp > filter.beforeTimestamp) {
221
+ return false;
222
+ }
223
+
224
+ // Ignored patterns
225
+ if (filter.ignoredPatterns?.length) {
226
+ for (const pattern of filter.ignoredPatterns) {
227
+ if (new RegExp(pattern).test(entry.label)) {
228
+ return false;
229
+ }
230
+ }
231
+ }
232
+
233
+ // Included patterns (must match at least one)
234
+ if (filter.includedPatterns?.length) {
235
+ let matched = false;
236
+ for (const pattern of filter.includedPatterns) {
237
+ if (new RegExp(pattern).test(entry.label)) {
238
+ matched = true;
239
+ break;
240
+ }
241
+ }
242
+ if (!matched) return false;
243
+ }
244
+ return true;
245
+ });
246
+ }
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.HistoryEntryRow = HistoryEntryRow;
7
+ var _reactNative = require("react-native");
8
+ var _CompactRow = require("../../ui/components/CompactRow.js");
9
+ var _gameUIColors = require("../../ui/gameUI/constants/gameUIColors.js");
10
+ var _jsxRuntime = require("react/jsx-runtime");
11
+ /**
12
+ * HistoryEntryRow - Universal row component for history entries
13
+ *
14
+ * Wraps CompactRow to display entries from any adapter (Redux, Zustand, MMKV, etc.)
15
+ */
16
+
17
+ /**
18
+ * Format timestamp to relative time
19
+ */
20
+ function formatRelativeTime(timestamp) {
21
+ const now = Date.now();
22
+ const diff = now - timestamp;
23
+ if (diff < 1000) return "just now";
24
+ if (diff < 60000) return `${Math.floor(diff / 1000)}s ago`;
25
+ if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
26
+ return `${Math.floor(diff / 3600000)}h ago`;
27
+ }
28
+
29
+ /**
30
+ * Get status color based on entry properties
31
+ */
32
+ function getStatusColor(entry, adapter) {
33
+ // Use adapter color if available
34
+ if (adapter?.color) {
35
+ return adapter.color;
36
+ }
37
+
38
+ // Status-based colors (React Query style)
39
+ if (entry.status === "error") return _gameUIColors.buoyColors.error;
40
+ if (entry.status === "pending") return _gameUIColors.buoyColors.warning;
41
+ if (entry.status === "success") return _gameUIColors.buoyColors.success;
42
+
43
+ // Change-based colors
44
+ if (entry.hasStateChange) return _gameUIColors.buoyColors.success;
45
+
46
+ // Skipped entries
47
+ if (entry.isSkipped) return _gameUIColors.buoyColors.textMuted;
48
+
49
+ // Future entries (after current index)
50
+ if (entry.isInFuture) return _gameUIColors.buoyColors.textMuted + "80";
51
+
52
+ // Source-based fallback colors
53
+ switch (entry.source) {
54
+ case "redux":
55
+ return "#764ABC";
56
+ // Redux purple
57
+ case "zustand":
58
+ return "#443E38";
59
+ // Zustand brown
60
+ case "mmkv":
61
+ return "#4CAF50";
62
+ // Green
63
+ case "async-storage":
64
+ return "#2196F3";
65
+ // Blue
66
+ case "react-query":
67
+ return "#FF4154";
68
+ // React Query red
69
+ case "jotai":
70
+ return "#000000";
71
+ // Black
72
+ case "legend-state":
73
+ return "#7C3AED";
74
+ // Purple
75
+ default:
76
+ return _gameUIColors.buoyColors.textSecondary;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Get status label for display
82
+ */
83
+ function getStatusLabel(entry) {
84
+ if (entry.isSkipped) return "Skipped";
85
+ if (entry.isInFuture) return "Future";
86
+ if (entry.status) {
87
+ return entry.status.charAt(0).toUpperCase() + entry.status.slice(1);
88
+ }
89
+ if (entry.hasStateChange) return "Changed";
90
+ return "Action";
91
+ }
92
+
93
+ /**
94
+ * Get sublabel (source or category)
95
+ */
96
+ function getSublabel(entry, adapter) {
97
+ if (adapter?.name) return adapter.name;
98
+ if (entry.category) return entry.category;
99
+ return entry.source;
100
+ }
101
+ function HistoryEntryRow({
102
+ entry,
103
+ adapter,
104
+ isSelected,
105
+ onPress,
106
+ showSource = true,
107
+ showDuration = true
108
+ }) {
109
+ const statusColor = getStatusColor(entry, adapter);
110
+ const statusLabel = getStatusLabel(entry);
111
+ const sublabel = showSource ? getSublabel(entry, adapter) : undefined;
112
+
113
+ // Build bottom right text (timestamp + optional duration)
114
+ let bottomRightText = formatRelativeTime(entry.timestamp);
115
+ if (showDuration && entry.duration !== undefined) {
116
+ bottomRightText = `${entry.duration.toFixed(1)}ms · ${bottomRightText}`;
117
+ }
118
+
119
+ // Custom badge showing change indicator
120
+ const customBadge = entry.hasStateChange ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
121
+ style: styles.changeBadge,
122
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
123
+ style: styles.changeBadgeText,
124
+ children: "\u26A1"
125
+ })
126
+ }) : undefined;
127
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CompactRow.CompactRow, {
128
+ statusDotColor: statusColor,
129
+ statusLabel: statusLabel,
130
+ statusSublabel: sublabel,
131
+ primaryText: entry.label,
132
+ bottomRightText: bottomRightText,
133
+ customBadge: customBadge,
134
+ isSelected: isSelected,
135
+ onPress: onPress ? () => onPress(entry) : undefined,
136
+ showChevron: !!onPress
137
+ });
138
+ }
139
+ const styles = _reactNative.StyleSheet.create({
140
+ changeBadge: {
141
+ paddingHorizontal: 4
142
+ },
143
+ changeBadgeText: {
144
+ fontSize: 12
145
+ }
146
+ });