redux-connected-devtools 1.0.2 → 1.0.4

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 (167) hide show
  1. package/dist/components/DevInspector/DevInspector.js +12 -0
  2. package/{src/components/DevInspector/DevInspector.style.tsx → dist/components/DevInspector/DevInspector.style.js} +1 -3
  3. package/dist/components/DevList/DevList.js +24 -0
  4. package/{src/components/DevList/DevList.style.tsx → dist/components/DevList/DevList.style.js} +2 -4
  5. package/dist/components/DevMenu/DevMenu.js +25 -0
  6. package/{src/components/DevMenu/DevMenu.style.tsx → dist/components/DevMenu/DevMenu.style.js} +15 -19
  7. package/dist/components/DevPanel/DevPanel.js +38 -0
  8. package/dist/components/DevPanel/DevPanel.style.js +22 -0
  9. package/dist/components/DevtoolsApp/DevtoolsApp.js +17 -0
  10. package/dist/components/DevtoolsApp/DevtoolsApp.style.js +11 -0
  11. package/dist/components/Icon/AllIcons.js +18 -0
  12. package/dist/components/Icon/Icon.js +9 -0
  13. package/dist/components/Icon/Icon.style.js +10 -0
  14. package/{src/components/JourneyRow/JourneyRow.tsx → dist/components/JourneyRow/JourneyRow.js} +9 -32
  15. package/{src/components/JourneyRow/JourneyRow.style.tsx → dist/components/JourneyRow/JourneyRow.style.js} +7 -12
  16. package/dist/components/JsonViewer/JsonViewer.js +7 -0
  17. package/{src/components/JsonViewer/JsonViewer.style.tsx → dist/components/JsonViewer/JsonViewer.style.js} +1 -2
  18. package/dist/components/Lifecycle/Lifecycle.js +15 -0
  19. package/{src/components/Lifecycle/Lifecycle.style.tsx → dist/components/Lifecycle/Lifecycle.style.js} +1 -2
  20. package/dist/components/RequestDetails/RequestDetails.js +10 -0
  21. package/dist/components/RequestDetails/RequestDetails.style.js +16 -0
  22. package/dist/components/RequestJourney/RequestJourney.js +14 -0
  23. package/dist/components/RequestJourney/RequestJourney.style.js +26 -0
  24. package/dist/components/RequestRow/RequestRow.js +9 -0
  25. package/{src/components/RequestRow/RequestRow.style.tsx → dist/components/RequestRow/RequestRow.style.js} +6 -10
  26. package/dist/components/Size/Size.js +10 -0
  27. package/dist/components/Size/Size.style.js +5 -0
  28. package/{src/components/Time/Time.tsx → dist/components/Time/Time.js} +3 -17
  29. package/{src/components/Time/Time.style.tsx → dist/components/Time/Time.style.js} +4 -7
  30. package/dist/containers/DevMenuContainer.js +11 -0
  31. package/dist/containers/DevPanelContainer.js +6 -0
  32. package/dist/containers/DevtoolsAppContainer.js +24 -0
  33. package/{src/containers/EndpointConfigsContainer.tsx → dist/containers/EndpointConfigsContainer.js} +2 -5
  34. package/{src/containers/EndpointStatusContainer.tsx → dist/containers/EndpointStatusContainer.js} +2 -5
  35. package/{src/containers/GlobalSettingsContainer.tsx → dist/containers/GlobalSettingsContainer.js} +2 -5
  36. package/{src/containers/GlobalStatsContainer.tsx → dist/containers/GlobalStatsContainer.js} +2 -5
  37. package/{src/containers/LifecycleApiErrorContainer.tsx → dist/containers/LifecycleApiErrorContainer.js} +2 -4
  38. package/dist/containers/LifecycleFailedContainer.js +9 -0
  39. package/{src/containers/LifecycleGeneralErrorContainer.tsx → dist/containers/LifecycleGeneralErrorContainer.js} +2 -4
  40. package/{src/containers/LifecycleInQueueContainer.tsx → dist/containers/LifecycleInQueueContainer.js} +2 -4
  41. package/{src/containers/LifecyclePendingApiContainer.tsx → dist/containers/LifecyclePendingApiContainer.js} +2 -4
  42. package/{src/containers/LifecyclePostActionContainer.tsx → dist/containers/LifecyclePostActionContainer.js} +2 -4
  43. package/{src/containers/LifecycleReceivedContainer.tsx → dist/containers/LifecycleReceivedContainer.js} +2 -4
  44. package/{src/data/devComponents.tsx → dist/data/devComponents.js} +3 -4
  45. package/{src/data/devRoutes.ts → dist/data/devRoutes.js} +23 -28
  46. package/dist/dts/components/DevInspector/DevInspector.d.ts +7 -0
  47. package/dist/dts/components/DevInspector/DevInspector.style.d.ts +1 -0
  48. package/dist/dts/components/DevList/DevList.d.ts +9 -0
  49. package/dist/dts/components/DevList/DevList.style.d.ts +2 -0
  50. package/dist/dts/components/DevMenu/DevMenu.d.ts +12 -0
  51. package/dist/dts/components/DevMenu/DevMenu.style.d.ts +7 -0
  52. package/dist/dts/components/DevPanel/DevPanel.d.ts +6 -0
  53. package/dist/dts/components/DevPanel/DevPanel.style.d.ts +3 -0
  54. package/dist/dts/components/DevtoolsApp/DevtoolsApp.d.ts +10 -0
  55. package/dist/dts/components/DevtoolsApp/DevtoolsApp.style.d.ts +1 -0
  56. package/dist/dts/components/Icon/AllIcons.d.ts +8 -0
  57. package/dist/dts/components/Icon/Icon.d.ts +10 -0
  58. package/dist/dts/components/Icon/Icon.style.d.ts +3 -0
  59. package/dist/dts/components/JourneyRow/JourneyRow.d.ts +7 -0
  60. package/dist/dts/components/JourneyRow/JourneyRow.style.d.ts +5 -0
  61. package/dist/dts/components/JsonViewer/JsonViewer.d.ts +7 -0
  62. package/dist/dts/components/JsonViewer/JsonViewer.style.d.ts +3 -0
  63. package/dist/dts/components/Lifecycle/Lifecycle.d.ts +7 -0
  64. package/dist/dts/components/Lifecycle/Lifecycle.style.d.ts +1 -0
  65. package/dist/dts/components/RequestDetails/RequestDetails.d.ts +7 -0
  66. package/dist/dts/components/RequestDetails/RequestDetails.style.d.ts +4 -0
  67. package/dist/dts/components/RequestJourney/RequestJourney.d.ts +7 -0
  68. package/dist/dts/components/RequestJourney/RequestJourney.style.d.ts +1 -0
  69. package/dist/dts/components/RequestRow/RequestRow.d.ts +11 -0
  70. package/dist/dts/components/RequestRow/RequestRow.style.d.ts +6 -0
  71. package/dist/dts/components/Size/Size.d.ts +6 -0
  72. package/dist/dts/components/Size/Size.style.d.ts +1 -0
  73. package/dist/dts/components/Time/Time.d.ts +6 -0
  74. package/dist/dts/components/Time/Time.style.d.ts +3 -0
  75. package/dist/dts/containers/DevMenuContainer.d.ts +8 -0
  76. package/dist/dts/containers/DevPanelContainer.d.ts +6 -0
  77. package/dist/dts/containers/DevtoolsAppContainer.d.ts +7 -0
  78. package/dist/dts/containers/EndpointConfigsContainer.d.ts +3 -0
  79. package/dist/dts/containers/EndpointStatusContainer.d.ts +3 -0
  80. package/dist/dts/containers/GlobalSettingsContainer.d.ts +3 -0
  81. package/dist/dts/containers/GlobalStatsContainer.d.ts +3 -0
  82. package/dist/dts/containers/LifecycleApiErrorContainer.d.ts +3 -0
  83. package/dist/dts/containers/LifecycleFailedContainer.d.ts +3 -0
  84. package/dist/dts/containers/LifecycleGeneralErrorContainer.d.ts +3 -0
  85. package/dist/dts/containers/LifecycleInQueueContainer.d.ts +3 -0
  86. package/dist/dts/containers/LifecyclePendingApiContainer.d.ts +3 -0
  87. package/dist/dts/containers/LifecyclePostActionContainer.d.ts +3 -0
  88. package/dist/dts/containers/LifecycleReceivedContainer.d.ts +3 -0
  89. package/dist/dts/data/devComponents.d.ts +4 -0
  90. package/dist/dts/data/devRoutes.d.ts +8 -0
  91. package/dist/dts/hooks/useStoreSize.d.ts +7 -0
  92. package/dist/dts/index.d.ts +1 -0
  93. package/dist/dts/store/selectors.d.ts +2235 -0
  94. package/dist/dts/types.d.ts +0 -0
  95. package/dist/dts/utils/date.d.ts +4 -0
  96. package/dist/dts/utils/download.d.ts +1 -0
  97. package/dist/hooks/useStoreSize.js +16 -0
  98. package/dist/index.d.ts +1 -0
  99. package/dist/index.js +1 -0
  100. package/dist/redux-connected-devtools.es.js +992 -0
  101. package/dist/redux-connected-devtools.es.js.map +1 -0
  102. package/dist/redux-connected-devtools.umd.js +247 -0
  103. package/dist/redux-connected-devtools.umd.js.map +1 -0
  104. package/dist/store/selectors.js +143 -0
  105. package/dist/types.js +1 -0
  106. package/dist/utils/date.js +8 -0
  107. package/dist/utils/download.js +17 -0
  108. package/package.json +29 -13
  109. package/.env +0 -2
  110. package/.prettierrc.js +0 -10
  111. package/.vscode/settings.json +0 -12
  112. package/.vscode/tasks.json +0 -33
  113. package/index.html +0 -58
  114. package/jest.config.js +0 -8
  115. package/public/devtools.html +0 -8
  116. package/public/icon.png +0 -0
  117. package/public/manifest.json +0 -29
  118. package/public/options.html +0 -12
  119. package/public/panel.html +0 -39
  120. package/public/popup.html +0 -12
  121. package/src/__tests__/sum.ts +0 -9
  122. package/src/background.ts +0 -49
  123. package/src/components/DevInspector/DevInspector.scss +0 -2
  124. package/src/components/DevInspector/DevInspector.tsx +0 -34
  125. package/src/components/DevList/DevList.scss +0 -2
  126. package/src/components/DevList/DevList.tsx +0 -62
  127. package/src/components/DevMenu/DevMenu.scss +0 -2
  128. package/src/components/DevMenu/DevMenu.tsx +0 -76
  129. package/src/components/DevPanel/DevPanel.scss +0 -2
  130. package/src/components/DevPanel/DevPanel.style.tsx +0 -16
  131. package/src/components/DevPanel/DevPanel.tsx +0 -51
  132. package/src/components/JourneyRow/JourneyRow.scss +0 -2
  133. package/src/components/JsonViewer/JsonViewer.scss +0 -2
  134. package/src/components/JsonViewer/JsonViewer.tsx +0 -24
  135. package/src/components/Lifecycle/Lifecycle.scss +0 -2
  136. package/src/components/Lifecycle/Lifecycle.tsx +0 -31
  137. package/src/components/LogsViewer/LogsViewer.scss +0 -2
  138. package/src/components/LogsViewer/LogsViewer.style.tsx +0 -5
  139. package/src/components/LogsViewer/LogsViewer.tsx +0 -14
  140. package/src/components/RequestDetails/RequestDetails.scss +0 -2
  141. package/src/components/RequestDetails/RequestDetails.style.tsx +0 -20
  142. package/src/components/RequestDetails/RequestDetails.tsx +0 -60
  143. package/src/components/RequestJourney/RequestJourney.scss +0 -2
  144. package/src/components/RequestJourney/RequestJourney.style.tsx +0 -6
  145. package/src/components/RequestJourney/RequestJourney.tsx +0 -33
  146. package/src/components/RequestRow/RequestRow.scss +0 -2
  147. package/src/components/RequestRow/RequestRow.tsx +0 -37
  148. package/src/components/Time/Time.scss +0 -2
  149. package/src/containers/DevMenuContainer.tsx +0 -28
  150. package/src/containers/DevPanelContainer.tsx +0 -10
  151. package/src/content_script.ts +0 -19
  152. package/src/devtools.tsx +0 -29
  153. package/src/index.ts +0 -1
  154. package/src/injected_script.ts +0 -9
  155. package/src/options.tsx +0 -77
  156. package/src/panel.tsx +0 -30
  157. package/src/popup.tsx +0 -63
  158. package/src/store/initialState.ts +0 -42
  159. package/src/store/selectors.ts +0 -205
  160. package/src/sum.ts +0 -3
  161. package/src/types.ts +0 -1
  162. package/src/utils/date.ts +0 -3
  163. package/tsconfig.json +0 -24
  164. package/vite.config.ts +0 -45
  165. package/webpack/webpack.common.js +0 -46
  166. package/webpack/webpack.dev.js +0 -7
  167. package/webpack/webpack.prod.js +0 -6
@@ -0,0 +1,992 @@
1
+ import React, { useState, useMemo, useRef, useEffect } from "react";
2
+ import styled from "styled-components";
3
+ import { useSelector, Provider } from "react-redux";
4
+ import classnames from "classnames";
5
+ import { createSelector } from "reselect";
6
+ import { connectedSelectors, LifecycleStatus, clearCompletedRequests, clearFailedRequests } from "redux-connected";
7
+ import bytes from "bytes";
8
+ import { FixedSizeList } from "react-window";
9
+ import { debounce } from "shared-base";
10
+ const Download = (props) => {
11
+ const { size = 24 } = props;
12
+ return /* @__PURE__ */ React.createElement("svg", {
13
+ xmlns: "http://www.w3.org/2000/svg",
14
+ viewBox: "0 0 24 24",
15
+ width: `${size}px`,
16
+ height: `${size}px`,
17
+ fill: "currentColor"
18
+ }, /* @__PURE__ */ React.createElement("path", {
19
+ d: "M0 0h24v24H0z",
20
+ fill: "none"
21
+ }), /* @__PURE__ */ React.createElement("path", {
22
+ d: "M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"
23
+ }));
24
+ };
25
+ const Close = (props) => {
26
+ const { size = 24 } = props;
27
+ return /* @__PURE__ */ React.createElement("svg", {
28
+ xmlns: "http://www.w3.org/2000/svg",
29
+ viewBox: "0 0 24 24",
30
+ width: `${size}px`,
31
+ height: `${size}px`,
32
+ fill: "currentColor"
33
+ }, /* @__PURE__ */ React.createElement("path", {
34
+ d: "M0 0h24v24H0z",
35
+ fill: "none"
36
+ }), /* @__PURE__ */ React.createElement("path", {
37
+ d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
38
+ }));
39
+ };
40
+ const ClearAll = (props) => {
41
+ const { size = 24 } = props;
42
+ return /* @__PURE__ */ React.createElement("svg", {
43
+ xmlns: "http://www.w3.org/2000/svg",
44
+ viewBox: "0 0 24 24",
45
+ width: `${size}px`,
46
+ height: `${size}px`,
47
+ fill: "currentColor"
48
+ }, /* @__PURE__ */ React.createElement("path", {
49
+ d: "M0 0h24v24H0z",
50
+ fill: "none"
51
+ }), /* @__PURE__ */ React.createElement("path", {
52
+ d: "M5 13h14v-2H5v2zm-2 4h14v-2H3v2zM7 7v2h14V7H7z"
53
+ }));
54
+ };
55
+ const allIcons = {
56
+ close: Close,
57
+ clearAll: ClearAll,
58
+ download: Download
59
+ };
60
+ const Container$d = styled.div`
61
+ margin: 0 3px;
62
+ color: ${(props) => {
63
+ var _a;
64
+ return (_a = props.color) != null ? _a : "inherit";
65
+ }};
66
+ cursor: pointer;
67
+
68
+ &:hover {
69
+ color: gold;
70
+ }
71
+ `;
72
+ function Icon(props) {
73
+ const { name, size = 20, color } = props;
74
+ const Cmp = allIcons[name];
75
+ return /* @__PURE__ */ React.createElement(Container$d, {
76
+ className: "Icon-container",
77
+ "data-testid": "Icon-container",
78
+ color,
79
+ onClick: props.onClick
80
+ }, /* @__PURE__ */ React.createElement(Cmp, {
81
+ size
82
+ }));
83
+ }
84
+ const Container$c = styled.div`
85
+ flex: 1;
86
+ background-color: #223;
87
+ z-index: 3;
88
+ color: #eee;
89
+ display: flex;
90
+ flex-direction: column;
91
+ min-width: 880px;
92
+ min-height: 880px;
93
+ `;
94
+ const Container$b = styled.div`
95
+ width: 190px;
96
+ ${(props) => props.theme.borderRight("1px solid rgba(255, 255, 255, 0.2)")}
97
+ box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
98
+ `;
99
+ const MenuGroup = styled.div`
100
+ border-bottom: 1px solid rgba(255, 255, 255, 0.2);
101
+ `;
102
+ const MenuGroupTitle = styled.div`
103
+ font-size: 13px;
104
+ padding: 5px 10px;
105
+ color: rgba(255, 255, 255, 0.5);
106
+ border-bottom: 1px solid rgba(255, 255, 255, 0.2);
107
+ background-color: rgba(0, 0, 0, 0.1);
108
+ `;
109
+ const MenuItem = styled.div`
110
+ display: flex;
111
+ flex-direction: row;
112
+ align-items: center;
113
+ padding: 6px 10px;
114
+ font-size: 14px;
115
+ color: rgba(255, 255, 255, 0.89);
116
+ background-color: transparent;
117
+
118
+ &.selected {
119
+ color: gold;
120
+ background-color: rgba(255, 255, 255, 0.05);
121
+ }
122
+
123
+ &:hover {
124
+ background-color: rgba(255, 255, 255, 0.1);
125
+ cursor: pointer;
126
+ }
127
+ `;
128
+ const Title = styled.div`
129
+ flex: 1;
130
+ `;
131
+ const Badge = styled.div`
132
+ background-color: rgba(0, 0, 80, 0.3);
133
+ padding: 0 4px;
134
+ font-size: 12px;
135
+ border-radius: 7px;
136
+ border: 1px solid #334;
137
+ color: cyan;
138
+ `;
139
+ const BadgeTotal = styled(Badge)`
140
+ color: #555;
141
+ `;
142
+ function DevMenu(props) {
143
+ const { groups, items, selectedId, badges, badgesTotal } = props;
144
+ function renderItem(item) {
145
+ const { title, id } = item;
146
+ const selected = id === selectedId;
147
+ const badge = badges[id];
148
+ const badgeTotal = badgesTotal[id];
149
+ return /* @__PURE__ */ React.createElement(MenuItem, {
150
+ key: item.id,
151
+ className: classnames({ selected }),
152
+ onClick: () => props.onClick(item)
153
+ }, /* @__PURE__ */ React.createElement(Title, null, title), badgeTotal > 0 && badgeTotal !== badge && /* @__PURE__ */ React.createElement(BadgeTotal, null, badgeTotal), badge > 0 && /* @__PURE__ */ React.createElement(Badge, null, badge));
154
+ }
155
+ function renderItems(groupItems) {
156
+ return groupItems.map((item) => renderItem(item));
157
+ }
158
+ function renderGroup(group) {
159
+ const groupItems = items.filter((item) => item.group === group);
160
+ return /* @__PURE__ */ React.createElement(MenuGroup, {
161
+ key: group
162
+ }, /* @__PURE__ */ React.createElement(MenuGroupTitle, null, group), renderItems(groupItems));
163
+ }
164
+ function renderGroups() {
165
+ return groups.map((group) => renderGroup(group));
166
+ }
167
+ return /* @__PURE__ */ React.createElement(Container$b, {
168
+ className: "DevMenu-container",
169
+ "data-testid": "DevMenu-container"
170
+ }, renderGroups());
171
+ }
172
+ const devRoutes = [
173
+ {
174
+ id: "lifecycleReceived",
175
+ title: "1. Received",
176
+ group: "lifecycle",
177
+ componentId: "LifecycleReceived"
178
+ },
179
+ {
180
+ id: "lifecycleInQueue",
181
+ title: "2. In queue",
182
+ group: "lifecycle",
183
+ componentId: "LifecycleInQueue"
184
+ },
185
+ {
186
+ id: "lifecyclePendingApi",
187
+ title: "3. Pending API",
188
+ group: "lifecycle",
189
+ componentId: "LifecyclePendingApi"
190
+ },
191
+ {
192
+ id: "lifecyclePostAction",
193
+ title: "4. Post action",
194
+ group: "lifecycle",
195
+ componentId: "LifecyclePostAction"
196
+ },
197
+ {
198
+ id: "lifecycleGeneralError",
199
+ title: "e1. General errors",
200
+ group: "errors",
201
+ componentId: "LifecycleGeneralError"
202
+ },
203
+ {
204
+ id: "lifecycleApiError",
205
+ title: "e2. API errors",
206
+ group: "errors",
207
+ componentId: "LifecycleApiError"
208
+ },
209
+ {
210
+ id: "lifecycleFailed",
211
+ title: "e3. Failed requests (after retries)",
212
+ group: "errors",
213
+ componentId: "LifecycleFailed"
214
+ },
215
+ {
216
+ id: "endpointStatus",
217
+ title: "Endpoint status",
218
+ group: "settings & stats",
219
+ componentId: "EndpointStatus"
220
+ },
221
+ {
222
+ id: "settingsGlobal",
223
+ title: "Global settings",
224
+ group: "settings & stats",
225
+ componentId: "GlobalSettings"
226
+ },
227
+ {
228
+ id: "settingsEndpoints",
229
+ title: "Endpoints configs",
230
+ group: "settings & stats",
231
+ componentId: "EndpointConfigs"
232
+ },
233
+ {
234
+ id: "statsGlobal",
235
+ title: "Global stats",
236
+ group: "settings & stats",
237
+ componentId: "GlobalStats"
238
+ }
239
+ ];
240
+ const getGroups = () => {
241
+ const output = [];
242
+ devRoutes.forEach((group) => {
243
+ if (!output.includes(group.group)) {
244
+ output.push(group.group);
245
+ }
246
+ });
247
+ return output;
248
+ };
249
+ const devGroups = getGroups();
250
+ const $requests = createSelector(
251
+ connectedSelectors.$requests,
252
+ (requests) => {
253
+ return requests.map((request) => {
254
+ var _a;
255
+ const { items } = request;
256
+ const lastPoint = (_a = items[items.length - 1]) != null ? _a : {};
257
+ const journeyWithDelta = items.map((point, index) => {
258
+ var _a2;
259
+ const nextPoint = (_a2 = items[index + 1]) != null ? _a2 : point;
260
+ const delta = nextPoint.timestamp - point.timestamp;
261
+ return {
262
+ ...point,
263
+ delta
264
+ };
265
+ });
266
+ return {
267
+ ...request,
268
+ items: journeyWithDelta,
269
+ lastPointTimestamp: lastPoint.timestamp,
270
+ lastPointStatus: lastPoint.status
271
+ };
272
+ }).sort((a, b) => {
273
+ if (a.lastPointTimestamp === b.lastPointTimestamp) {
274
+ return 0;
275
+ }
276
+ return a.lastPointTimestamp > b.lastPointTimestamp ? -1 : 1;
277
+ });
278
+ }
279
+ );
280
+ const $requestsReceived = createSelector($requests, (requests) => {
281
+ return requests.filter((request) => {
282
+ const { items } = request;
283
+ const lastPoint = items[items.length - 1];
284
+ return lastPoint && lastPoint.status === LifecycleStatus.RECEIVED;
285
+ });
286
+ });
287
+ const $requestsReceivedPast = createSelector($requests, (requests) => {
288
+ return requests.filter((request) => {
289
+ const { items } = request;
290
+ return items.find((point) => point.status === LifecycleStatus.RECEIVED);
291
+ });
292
+ });
293
+ const $requestsInQueue = createSelector($requests, (requests) => {
294
+ return requests.filter((request) => {
295
+ const { items } = request;
296
+ const lastPoint = items[items.length - 1];
297
+ return lastPoint && lastPoint.status === LifecycleStatus.IN_QUEUE;
298
+ });
299
+ });
300
+ const $requestsInQueuePast = createSelector($requests, (requests) => {
301
+ return requests.filter((request) => {
302
+ const { items } = request;
303
+ return items.find((point) => point.status === LifecycleStatus.IN_QUEUE);
304
+ });
305
+ });
306
+ const $requestsPendingApi = createSelector($requests, (requests) => {
307
+ return requests.filter((request) => {
308
+ const { items } = request;
309
+ const lastPoint = items[items.length - 1];
310
+ return lastPoint && lastPoint.status === LifecycleStatus.PENDING_API_RESPONSE;
311
+ });
312
+ });
313
+ const $requestsPendingApiPast = createSelector($requests, (requests) => {
314
+ return requests.filter((request) => {
315
+ const { items } = request;
316
+ return items.find(
317
+ (point) => point.status === LifecycleStatus.PENDING_API_RESPONSE
318
+ );
319
+ });
320
+ });
321
+ const $requestsPostAction = createSelector($requests, (requests) => {
322
+ return requests.filter((request) => {
323
+ const { items } = request;
324
+ const lastPoint = items[items.length - 1];
325
+ return lastPoint && lastPoint.status === LifecycleStatus.POST_ACTION;
326
+ });
327
+ });
328
+ const $requestsPostActionPast = createSelector($requests, (requests) => {
329
+ return requests.filter((request) => {
330
+ const { items } = request;
331
+ return items.find(
332
+ (point) => point.status === LifecycleStatus.POST_ACTION
333
+ );
334
+ });
335
+ });
336
+ const $requestsGeneralError = createSelector($requests, (requests) => {
337
+ return requests.filter((request) => {
338
+ const { items } = request;
339
+ const lastPoint = items[items.length - 1];
340
+ return lastPoint && lastPoint.status === LifecycleStatus.GENERAL_ERROR;
341
+ });
342
+ });
343
+ const $requestsGeneralErrorPast = createSelector(
344
+ $requests,
345
+ (requests) => {
346
+ return requests.filter((request) => {
347
+ const { items } = request;
348
+ return items.find(
349
+ (point) => point.status === LifecycleStatus.GENERAL_ERROR
350
+ );
351
+ });
352
+ }
353
+ );
354
+ const $requestsApiError = createSelector($requests, (requests) => {
355
+ return requests.filter((request) => {
356
+ const { items } = request;
357
+ const lastPoint = items[items.length - 1];
358
+ return lastPoint && lastPoint.status === LifecycleStatus.API_ERROR;
359
+ });
360
+ });
361
+ const $requestsFailed = createSelector($requests, (requests) => {
362
+ return requests.filter((request) => {
363
+ const { items } = request;
364
+ return items.find((point) => point.status === LifecycleStatus.FAILED);
365
+ });
366
+ });
367
+ const $requestsApiErrorPast = createSelector($requests, (requests) => {
368
+ return requests.filter((request) => {
369
+ const { items } = request;
370
+ return items.find(
371
+ (point) => point.status === LifecycleStatus.API_ERROR
372
+ );
373
+ });
374
+ });
375
+ const $menuBadges = createSelector(
376
+ $requestsReceived,
377
+ $requestsInQueue,
378
+ $requestsGeneralError,
379
+ $requestsPendingApi,
380
+ $requestsApiError,
381
+ $requestsFailed,
382
+ $requestsPostAction,
383
+ (requestsReceived, requestsInQueue, requestsGeneralError, requestsPendingApi, requestsApiError, requestsFailed, requestsPostAction) => {
384
+ return {
385
+ lifecycleReceived: requestsReceived.length,
386
+ lifecycleInQueue: requestsInQueue.length,
387
+ lifecycleGeneralError: requestsGeneralError.length,
388
+ lifecyclePendingApi: requestsPendingApi.length,
389
+ lifecycleApiError: requestsApiError.length,
390
+ lifecycleFailed: requestsFailed.length,
391
+ lifecyclePostAction: requestsPostAction.length
392
+ };
393
+ }
394
+ );
395
+ const $menuBadgesTotal = createSelector(
396
+ $requestsReceivedPast,
397
+ $requestsInQueuePast,
398
+ $requestsGeneralErrorPast,
399
+ $requestsPendingApiPast,
400
+ $requestsApiErrorPast,
401
+ $requestsFailed,
402
+ $requestsPostActionPast,
403
+ (requestsReceived, requestsInQueue, requestsGeneralError, requestsPendingApi, requestsApiError, requestsFailed, requestsPostAction) => {
404
+ return {
405
+ lifecycleReceived: requestsReceived.length,
406
+ lifecycleInQueue: requestsInQueue.length,
407
+ lifecycleGeneralError: requestsGeneralError.length,
408
+ lifecyclePendingApi: requestsPendingApi.length,
409
+ lifecycleApiError: requestsApiError.length,
410
+ lifecycleFailed: requestsFailed.length,
411
+ lifecyclePostAction: requestsPostAction.length
412
+ };
413
+ }
414
+ );
415
+ function DevMenuContainer(props) {
416
+ const badges = useSelector($menuBadges);
417
+ const badgesTotal = useSelector($menuBadgesTotal);
418
+ return /* @__PURE__ */ React.createElement(DevMenu, {
419
+ groups: devGroups,
420
+ items: devRoutes,
421
+ badges,
422
+ badgesTotal,
423
+ selectedId: props.selectedId,
424
+ onClick: props.onClick
425
+ });
426
+ }
427
+ const Container$a = styled.div`
428
+ flex: 1;
429
+ color: #eee;
430
+ background-color: #232332;
431
+ display: flex;
432
+ flex-direction: row;
433
+ `;
434
+ const Content = styled.div`
435
+ flex: 1;
436
+ background-color: rgba(0, 0, 0, 0.15);
437
+ display: flex;
438
+ flex-direction: column;
439
+ `;
440
+ const Actions = styled.div`
441
+ position: absolute;
442
+ bottom: 5px;
443
+ ${(props) => props.theme.left("10px")}
444
+ display: flex;
445
+ flex-direction: row;
446
+ align-items: center;
447
+ `;
448
+ const Container$9 = styled.div`
449
+ flex: 1;
450
+ display: flex;
451
+ flex-direction: column;
452
+ `;
453
+ const Container$8 = styled.div`
454
+ flex: 1;
455
+ border-top: 1px solid #333;
456
+ max-height: 380px;
457
+ overflow-y: scroll;
458
+
459
+ &::-webkit-scrollbar {
460
+ width: 8px;
461
+ }
462
+
463
+ /* Track */
464
+ &::-webkit-scrollbar-track {
465
+ background: #333;
466
+ }
467
+
468
+ /* Handle */
469
+ &::-webkit-scrollbar-thumb {
470
+ background: #555;
471
+ }
472
+
473
+ /* Handle on hover */
474
+ &::-webkit-scrollbar-thumb:hover {
475
+ background: #666;
476
+ }
477
+ `;
478
+ const timestamp = () => new Date().getTime();
479
+ let startOfTime = timestamp();
480
+ const resetStartOfTime = () => {
481
+ startOfTime = timestamp();
482
+ };
483
+ const getMinutes = () => {
484
+ return new Date().getMinutes();
485
+ };
486
+ const Container$7 = styled.div`
487
+ display: flex;
488
+ flex-direction: row;
489
+ align-items: flex-start;
490
+ font-family: monospace;
491
+ color: #99a;
492
+ `;
493
+ const Full = styled.div`
494
+ font-size: 24px;
495
+ `;
496
+ const Fraction = styled.div`
497
+ font-size: 12px;
498
+ `;
499
+ function Time(props) {
500
+ const { value } = props;
501
+ const relativeValue = (value - startOfTime) / 1e3;
502
+ const full = Math.floor(relativeValue);
503
+ const fraction = (relativeValue - full).toFixed(3).split(".").pop();
504
+ return /* @__PURE__ */ React.createElement(Container$7, {
505
+ className: "Time-container",
506
+ "data-testid": "Time-container"
507
+ }, /* @__PURE__ */ React.createElement(Full, null, full), /* @__PURE__ */ React.createElement(Fraction, null, fraction));
508
+ }
509
+ const Container$6 = styled.div`
510
+ flex: 1;
511
+ display: flex;
512
+ flex-direction: row;
513
+ align-items: center;
514
+ padding: 10px 20px;
515
+
516
+ &:nth-child(2n-1) {
517
+ background-color: rgba(0, 0, 0, 0.2);
518
+ }
519
+
520
+ &:hover {
521
+ background-color: rgba(0, 0, 0, 0.3);
522
+ cursor: pointer;
523
+ }
524
+ `;
525
+ const Status = styled.div`
526
+ color: #aaa;
527
+ `;
528
+ const DataIcon = styled.div`
529
+ background-color: #000;
530
+ padding: 3px 7px;
531
+ font-size: 13px;
532
+ font-weight: bold;
533
+ color: purple;
534
+ border-radius: 5px;
535
+ ${(props) => props.theme.marginLeft("10px")}
536
+ `;
537
+ const Delta = styled.div`
538
+ font-size: 13px;
539
+ width: 60px;
540
+ font-weight: bold;
541
+ color: olive;
542
+ ${(props) => props.theme.marginRight("10px")}
543
+ text-align: center;
544
+ font-family: monospace;
545
+ `;
546
+ const Flex = styled.div`
547
+ flex: 1;
548
+ `;
549
+ const statusMap = {
550
+ [LifecycleStatus.RECEIVED]: "Received",
551
+ [LifecycleStatus.POST_ACTION_OPTIMISTIC]: "Post action (optimistic)",
552
+ [LifecycleStatus.IN_QUEUE]: "In queue",
553
+ [LifecycleStatus.GENERAL_ERROR]: "General error",
554
+ [LifecycleStatus.PENDING_API_RESPONSE]: "Pending API",
555
+ [LifecycleStatus.API_ERROR]: "API error",
556
+ [LifecycleStatus.POST_ACTION]: "Post action",
557
+ [LifecycleStatus.FAILED]: "Failed"
558
+ };
559
+ function JourneyRow(props) {
560
+ const { point } = props;
561
+ const { status, timestamp: timestamp2, data, delta = "" } = point;
562
+ function printPoint() {
563
+ console.log(data);
564
+ }
565
+ function renderDataIcon() {
566
+ if (!data) {
567
+ return null;
568
+ }
569
+ return /* @__PURE__ */ React.createElement(DataIcon, null, "D");
570
+ }
571
+ function renderDelta() {
572
+ if (!delta) {
573
+ return null;
574
+ }
575
+ return /* @__PURE__ */ React.createElement(Delta, null, "+", delta.toLocaleString());
576
+ }
577
+ return /* @__PURE__ */ React.createElement(Container$6, {
578
+ className: "JourneyRow-container",
579
+ "data-testid": "JourneyRow-container",
580
+ onClick: printPoint
581
+ }, /* @__PURE__ */ React.createElement(Status, null, statusMap[status]), renderDataIcon(), /* @__PURE__ */ React.createElement(Flex, null), renderDelta(), /* @__PURE__ */ React.createElement(Time, {
582
+ value: timestamp2
583
+ }));
584
+ }
585
+ function RequestJourney(props) {
586
+ const { item } = props;
587
+ function renderItem(point, index) {
588
+ return /* @__PURE__ */ React.createElement(JourneyRow, {
589
+ key: index,
590
+ point
591
+ });
592
+ }
593
+ function renderItems() {
594
+ return item.items.map(
595
+ (point, index) => renderItem(point, index)
596
+ );
597
+ }
598
+ return /* @__PURE__ */ React.createElement(Container$8, {
599
+ className: "RequestJourney-container",
600
+ "data-testid": "RequestJourney-container"
601
+ }, renderItems());
602
+ }
603
+ const Container$5 = styled.div`
604
+ flex: 1;
605
+ padding: 20px;
606
+ `;
607
+ const Table = styled.table``;
608
+ const Tr = styled.tr``;
609
+ const Td = styled.td`
610
+ color: goldenrod;
611
+
612
+ &:first-child {
613
+ color: #778;
614
+ text-align: right;
615
+ ${(props) => props.theme.paddingRight("10px")}
616
+ }
617
+ `;
618
+ const Container$4 = styled.div`
619
+ flex: 1;
620
+ max-height: 850px;
621
+ overflow: auto;
622
+ padding: 0 25px;
623
+ max-width: ${(props) => props.width ? props.width + "px" : "680px"};
624
+ color: #ccc;
625
+ line-height: 26px;
626
+
627
+ &::-webkit-scrollbar {
628
+ width: 8px;
629
+ height: 7px;
630
+ }
631
+
632
+ /* Track */
633
+ &::-webkit-scrollbar-track {
634
+ background: #333;
635
+ }
636
+
637
+ /* Handle */
638
+ &::-webkit-scrollbar-thumb {
639
+ background: #555;
640
+ }
641
+
642
+ /* Handle on hover */
643
+ &::-webkit-scrollbar-thumb:hover {
644
+ background: #666;
645
+ }
646
+ `;
647
+ function JsonViewer(props) {
648
+ const { json, width } = props;
649
+ return /* @__PURE__ */ React.createElement(Container$4, {
650
+ className: "JsonViewer-container",
651
+ "data-testid": "JsonViewer-container",
652
+ width
653
+ }, /* @__PURE__ */ React.createElement("pre", null, JSON.stringify(json, null, 4)));
654
+ }
655
+ function RequestDetails(props) {
656
+ const { item } = props;
657
+ return /* @__PURE__ */ React.createElement(Container$5, {
658
+ className: "RequestDetails-container",
659
+ "data-testid": "RequestDetails-container"
660
+ }, /* @__PURE__ */ React.createElement(Table, null, /* @__PURE__ */ React.createElement("tbody", null, /* @__PURE__ */ React.createElement(Tr, null, /* @__PURE__ */ React.createElement(Td, null, "sequence"), /* @__PURE__ */ React.createElement(Td, null, item.sequence)), /* @__PURE__ */ React.createElement(Tr, null, /* @__PURE__ */ React.createElement(Td, null, "id"), /* @__PURE__ */ React.createElement(Td, null, item.shortId)), /* @__PURE__ */ React.createElement(Tr, null, /* @__PURE__ */ React.createElement(Td, null, "apiVerb"), /* @__PURE__ */ React.createElement(Td, null, item.argsApiVerb)), /* @__PURE__ */ React.createElement(Tr, null, /* @__PURE__ */ React.createElement(Td, null, "connection"), /* @__PURE__ */ React.createElement(Td, null, item.argsConnectionType)), /* @__PURE__ */ React.createElement(Tr, null, /* @__PURE__ */ React.createElement(Td, null, "duration"), /* @__PURE__ */ React.createElement(Td, null, item.apiDuration)), /* @__PURE__ */ React.createElement(Tr, null, /* @__PURE__ */ React.createElement(Td, null, "nodeName"), /* @__PURE__ */ React.createElement(Td, null, item.argsNodeName)), /* @__PURE__ */ React.createElement(Tr, null, /* @__PURE__ */ React.createElement(Td, null, "responseSize"), /* @__PURE__ */ React.createElement(Td, null, item.apiResponseSize && bytes(item.apiResponseSize))))), /* @__PURE__ */ React.createElement(JsonViewer, {
661
+ width: 290,
662
+ json: item.originalAction
663
+ }));
664
+ }
665
+ function DevInspector(props) {
666
+ const { item } = props;
667
+ if (!item) {
668
+ return /* @__PURE__ */ React.createElement(Container$9, {
669
+ className: "DevInspector-container",
670
+ "data-testid": "DevInspector-container"
671
+ });
672
+ }
673
+ return /* @__PURE__ */ React.createElement(Container$9, {
674
+ className: "DevInspector-container",
675
+ "data-testid": "DevInspector-container"
676
+ }, /* @__PURE__ */ React.createElement(RequestDetails, {
677
+ item
678
+ }), /* @__PURE__ */ React.createElement(RequestJourney, {
679
+ item
680
+ }));
681
+ }
682
+ const Container$3 = styled.div`
683
+ flex: 1;
684
+
685
+ .list {
686
+ &::-webkit-scrollbar {
687
+ width: 8px;
688
+ }
689
+
690
+ /* Track */
691
+ &::-webkit-scrollbar-track {
692
+ background: #333;
693
+ }
694
+
695
+ /* Handle */
696
+ &::-webkit-scrollbar-thumb {
697
+ background: #555;
698
+ }
699
+
700
+ /* Handle on hover */
701
+ &::-webkit-scrollbar-thumb:hover {
702
+ background: #666;
703
+ }
704
+ }
705
+ `;
706
+ const Empty = styled.div`
707
+ color: #456;
708
+ margin: 30px;
709
+ font-size: 17px;
710
+ text-align: center;
711
+ text-shadow: 1px 3px 3px rgba(0, 0, 0, 0.2);
712
+ `;
713
+ function DevList(props) {
714
+ const { row: Cmp, items, selectedRow } = props;
715
+ const Item = (rowInfo) => {
716
+ const { index, style } = rowInfo;
717
+ const item = items[index];
718
+ const className = classnames({ selected: item.id === (selectedRow == null ? void 0 : selectedRow.id) });
719
+ return /* @__PURE__ */ React.createElement(Cmp, {
720
+ onClick: props.onClick,
721
+ className,
722
+ index,
723
+ style,
724
+ item
725
+ });
726
+ };
727
+ function renderEmpty() {
728
+ return /* @__PURE__ */ React.createElement(Empty, null, "Empty list");
729
+ }
730
+ function renderList() {
731
+ if (items.length === 0) {
732
+ return renderEmpty();
733
+ }
734
+ return /* @__PURE__ */ React.createElement(FixedSizeList, {
735
+ height: 850,
736
+ itemCount: items.length,
737
+ itemSize: 68,
738
+ width: 350,
739
+ className: "list"
740
+ }, Item);
741
+ }
742
+ return /* @__PURE__ */ React.createElement(Container$3, {
743
+ className: "DevList-container",
744
+ "data-testid": "DevList-container"
745
+ }, renderList());
746
+ }
747
+ const Container$2 = styled.div`
748
+ flex: 1;
749
+ display: flex;
750
+ flex-direction: row;
751
+ align-items: center;
752
+ padding: 10px;
753
+ max-width: 90%;
754
+ background-color: ${(props) => props.index % 2 === 1 ? "rgba(0, 0, 0, 0.2)" : "transparent"};
755
+
756
+ &:hover {
757
+ background-color: rgba(0, 0, 0, 0.7);
758
+ cursor: pointer;
759
+ }
760
+ `;
761
+ const Col = styled.div`
762
+ &:first-child {
763
+ flex: 1;
764
+ }
765
+ `;
766
+ const Id = styled.div`
767
+ color: goldenrod;
768
+ font-size: 16px;
769
+ `;
770
+ const Type = styled.div`
771
+ color: brown;
772
+ `;
773
+ function RequestRow(props) {
774
+ var _a;
775
+ const { index, style, item, className } = props;
776
+ const { sequence, createdTS } = item;
777
+ return /* @__PURE__ */ React.createElement(Container$2, {
778
+ className: `DevListRow-container ${className}`,
779
+ "data-testid": "DevListRow-container",
780
+ style,
781
+ index,
782
+ onClick: () => props.onClick(item)
783
+ }, /* @__PURE__ */ React.createElement(Col, null, /* @__PURE__ */ React.createElement(Id, null, sequence), /* @__PURE__ */ React.createElement(Type, null, (_a = item.originalAction) == null ? void 0 : _a.type)), /* @__PURE__ */ React.createElement(Col, null, /* @__PURE__ */ React.createElement(Time, {
784
+ value: createdTS
785
+ })));
786
+ }
787
+ const Container$1 = styled.div`
788
+ flex: 1;
789
+ display: flex;
790
+ `;
791
+ function Lifecycle(props) {
792
+ const { requests } = props;
793
+ const [item, setItem] = useState();
794
+ function onClick(newItem) {
795
+ setItem(newItem);
796
+ }
797
+ return /* @__PURE__ */ React.createElement(Container$1, {
798
+ className: "Lifecycle-container",
799
+ "data-testid": "Lifecycle-container"
800
+ }, /* @__PURE__ */ React.createElement(DevList, {
801
+ items: requests,
802
+ row: RequestRow,
803
+ onClick,
804
+ selectedRow: item
805
+ }), /* @__PURE__ */ React.createElement(DevInspector, {
806
+ item
807
+ }));
808
+ }
809
+ function LifecycleReceivedContainer() {
810
+ const requests = useSelector($requestsReceivedPast);
811
+ return /* @__PURE__ */ React.createElement(Lifecycle, {
812
+ requests
813
+ });
814
+ }
815
+ function GlobalStatsContainer() {
816
+ const json = useSelector(connectedSelectors.$apiGlobalStatsRaw);
817
+ return /* @__PURE__ */ React.createElement(JsonViewer, {
818
+ json
819
+ });
820
+ }
821
+ function EndpointConfigsContainer() {
822
+ const json = useSelector(connectedSelectors.$endpointsConfigRaw);
823
+ return /* @__PURE__ */ React.createElement(JsonViewer, {
824
+ json
825
+ });
826
+ }
827
+ function GlobalSettingsContainer() {
828
+ const json = useSelector(connectedSelectors.$apiGlobalSettingsRaw);
829
+ return /* @__PURE__ */ React.createElement(JsonViewer, {
830
+ json
831
+ });
832
+ }
833
+ function EndpointStatusContainer() {
834
+ const json = useSelector(connectedSelectors.$endpointsStateRaw);
835
+ return /* @__PURE__ */ React.createElement(JsonViewer, {
836
+ json
837
+ });
838
+ }
839
+ function LifecycleInQueueContainer() {
840
+ const requests = useSelector($requestsInQueuePast);
841
+ return /* @__PURE__ */ React.createElement(Lifecycle, {
842
+ requests
843
+ });
844
+ }
845
+ function LifecycleGeneralErrorContainer() {
846
+ const requests = useSelector($requestsGeneralErrorPast);
847
+ return /* @__PURE__ */ React.createElement(Lifecycle, {
848
+ requests
849
+ });
850
+ }
851
+ function LifecyclePendingApiContainer() {
852
+ const requests = useSelector($requestsPendingApiPast);
853
+ return /* @__PURE__ */ React.createElement(Lifecycle, {
854
+ requests
855
+ });
856
+ }
857
+ function LifecycleApiErrorContainer() {
858
+ const requests = useSelector($requestsApiErrorPast);
859
+ return /* @__PURE__ */ React.createElement(Lifecycle, {
860
+ requests
861
+ });
862
+ }
863
+ function LifecyclePostActionContainer() {
864
+ const requests = useSelector($requestsPostActionPast);
865
+ return /* @__PURE__ */ React.createElement(Lifecycle, {
866
+ requests
867
+ });
868
+ }
869
+ function LifecycleFailedContainer() {
870
+ const requests = useSelector($requestsFailed);
871
+ return /* @__PURE__ */ React.createElement(Lifecycle, {
872
+ requests
873
+ });
874
+ }
875
+ const devComponents = {
876
+ LifecycleReceived: LifecycleReceivedContainer,
877
+ LifecycleInQueue: LifecycleInQueueContainer,
878
+ LifecycleGeneralError: LifecycleGeneralErrorContainer,
879
+ LifecyclePendingApi: LifecyclePendingApiContainer,
880
+ LifecycleApiError: LifecycleApiErrorContainer,
881
+ LifecycleFailed: LifecycleFailedContainer,
882
+ LifecyclePostAction: LifecyclePostActionContainer,
883
+ GlobalSettings: GlobalSettingsContainer,
884
+ GlobalStats: GlobalStatsContainer,
885
+ EndpointConfigs: EndpointConfigsContainer,
886
+ EndpointStatus: EndpointStatusContainer
887
+ };
888
+ function DevPanel(props) {
889
+ const [route, setRoute] = useState(devRoutes[0]);
890
+ function renderRoute() {
891
+ const Cmp = devComponents[route.componentId];
892
+ return /* @__PURE__ */ React.createElement(Cmp, {
893
+ key: route.id
894
+ });
895
+ }
896
+ return /* @__PURE__ */ React.createElement(Container$a, {
897
+ className: "DevPanel-container",
898
+ "data-testid": "DevPanel-container"
899
+ }, /* @__PURE__ */ React.createElement(DevMenuContainer, {
900
+ selectedId: route.id,
901
+ onClick: (item) => setRoute(item)
902
+ }), /* @__PURE__ */ React.createElement(Actions, null, props.children), /* @__PURE__ */ React.createElement(Content, null, renderRoute()));
903
+ }
904
+ function DevPanelContainer(props) {
905
+ return /* @__PURE__ */ React.createElement(DevPanel, null, props.children);
906
+ }
907
+ const Container = styled.div`
908
+ color: olive;
909
+ margin: 0 5px;
910
+ `;
911
+ function Size(props) {
912
+ const { size = 0 } = props;
913
+ const sizeText = useMemo(() => bytes(size), [size]);
914
+ return /* @__PURE__ */ React.createElement(Container, {
915
+ className: "Size-container",
916
+ "data-testid": "Size-container"
917
+ }, !size ? "-" : sizeText);
918
+ }
919
+ function DevtoolsApp(props) {
920
+ const { connectedStore, storeSizeInBytes, isDarkMode } = props;
921
+ const ref = useRef(null);
922
+ const className = classnames("DevtoolsApp-container", {
923
+ darkMode: isDarkMode
924
+ });
925
+ return /* @__PURE__ */ React.createElement(Container$c, {
926
+ ref,
927
+ className,
928
+ "data-testid": "DevtoolsApp-container"
929
+ }, /* @__PURE__ */ React.createElement(Provider, {
930
+ store: connectedStore
931
+ }, /* @__PURE__ */ React.createElement(DevPanelContainer, null, /* @__PURE__ */ React.createElement(Size, {
932
+ size: storeSizeInBytes
933
+ }), /* @__PURE__ */ React.createElement(Icon, {
934
+ name: "clearAll",
935
+ onClick: () => props.clearRequests()
936
+ }), /* @__PURE__ */ React.createElement(Icon, {
937
+ name: "download",
938
+ onClick: props.downloadState
939
+ }))));
940
+ }
941
+ const download = (filename, json) => {
942
+ const data = JSON.stringify(json, null, 4);
943
+ const blob = new Blob([data], { type: "text/csv" });
944
+ if (window.navigator.msSaveOrOpenBlob) {
945
+ window.navigator.msSaveBlob(blob, filename);
946
+ } else {
947
+ const elem = window.document.createElement("a");
948
+ elem.href = window.URL.createObjectURL(blob);
949
+ elem.download = filename;
950
+ document.body.appendChild(elem);
951
+ elem.click();
952
+ document.body.removeChild(elem);
953
+ }
954
+ };
955
+ const useStoreSize = (store) => {
956
+ const [storeSize, setStoreSize] = useState();
957
+ const calculateSize = debounce(() => {
958
+ const state = store.getState();
959
+ const size = JSON.stringify(state).length;
960
+ setStoreSize(size);
961
+ }, 500);
962
+ useEffect(() => {
963
+ store.subscribe(() => {
964
+ calculateSize();
965
+ });
966
+ }, [store]);
967
+ return storeSize;
968
+ };
969
+ function DevtoolsAppContainer(props) {
970
+ const { connectedStore, isDarkMode } = props;
971
+ const storeSizeInBytes = useStoreSize(connectedStore);
972
+ function clearRequests() {
973
+ connectedStore.dispatch(clearCompletedRequests());
974
+ connectedStore.dispatch(clearFailedRequests());
975
+ resetStartOfTime();
976
+ }
977
+ function downloadState() {
978
+ const state = connectedStore.getState();
979
+ const minutes = getMinutes();
980
+ const filename = `state_${minutes}.json`;
981
+ download(filename, state);
982
+ }
983
+ return /* @__PURE__ */ React.createElement(DevtoolsApp, {
984
+ connectedStore,
985
+ clearRequests,
986
+ downloadState,
987
+ storeSizeInBytes,
988
+ isDarkMode
989
+ });
990
+ }
991
+ export { DevtoolsAppContainer as DevtoolsApp };
992
+ //# sourceMappingURL=redux-connected-devtools.es.js.map