@buoy-gg/redux 2.1.11 → 2.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +58 -0
- package/lib/commonjs/index.js +1 -179
- package/lib/commonjs/preset.js +1 -98
- package/lib/commonjs/redux/components/ReduxActionButton.js +1 -129
- package/lib/commonjs/redux/components/ReduxActionDetailContent.js +1 -380
- package/lib/commonjs/redux/components/ReduxActionDetailView.js +1 -401
- package/lib/commonjs/redux/components/ReduxActionInfoView.js +1 -838
- package/lib/commonjs/redux/components/ReduxActionItem.js +1 -366
- package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +1 -134
- package/lib/commonjs/redux/components/ReduxIcon.js +1 -18
- package/lib/commonjs/redux/components/ReduxModal.js +1 -530
- package/lib/commonjs/redux/components/index.js +1 -52
- package/lib/commonjs/redux/hooks/index.js +1 -25
- package/lib/commonjs/redux/hooks/useAutoInstrumentRedux.js +1 -197
- package/lib/commonjs/redux/hooks/useReduxActions.js +1 -75
- package/lib/commonjs/redux/index.js +1 -49
- package/lib/commonjs/redux/utils/autoInstrument.js +1 -270
- package/lib/commonjs/redux/utils/buoyReduxMiddleware.js +1 -166
- package/lib/commonjs/redux/utils/createReduxHistoryAdapter.js +1 -146
- package/lib/commonjs/redux/utils/index.js +1 -111
- package/lib/commonjs/redux/utils/reduxActionStore.js +1 -358
- package/lib/module/index.js +1 -87
- package/lib/module/preset.js +1 -94
- package/lib/module/redux/components/ReduxActionButton.js +1 -126
- package/lib/module/redux/components/ReduxActionDetailContent.js +1 -376
- package/lib/module/redux/components/ReduxActionDetailView.js +1 -397
- package/lib/module/redux/components/ReduxActionInfoView.js +1 -833
- package/lib/module/redux/components/ReduxActionItem.js +1 -362
- package/lib/module/redux/components/ReduxDetailViewToggle.js +1 -129
- package/lib/module/redux/components/ReduxIcon.js +1 -8
- package/lib/module/redux/components/ReduxModal.js +1 -525
- package/lib/module/redux/components/index.js +1 -7
- package/lib/module/redux/hooks/index.js +1 -4
- package/lib/module/redux/hooks/useAutoInstrumentRedux.js +1 -193
- package/lib/module/redux/hooks/useReduxActions.js +1 -71
- package/lib/module/redux/index.js +1 -13
- package/lib/module/redux/utils/autoInstrument.js +1 -260
- package/lib/module/redux/utils/buoyReduxMiddleware.js +1 -157
- package/lib/module/redux/utils/createReduxHistoryAdapter.js +1 -142
- package/lib/module/redux/utils/index.js +1 -8
- package/lib/module/redux/utils/reduxActionStore.js +1 -354
- package/package.json +12 -12
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxActionButton.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxIcon.d.ts.map +0 -1
- package/lib/typescript/redux/components/ReduxModal.d.ts.map +0 -1
- package/lib/typescript/redux/components/index.d.ts.map +0 -1
- package/lib/typescript/redux/hooks/index.d.ts.map +0 -1
- package/lib/typescript/redux/hooks/useAutoInstrumentRedux.d.ts.map +0 -1
- package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +0 -1
- package/lib/typescript/redux/index.d.ts.map +0 -1
- package/lib/typescript/redux/types/index.d.ts.map +0 -1
- package/lib/typescript/redux/utils/autoInstrument.d.ts.map +0 -1
- package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts.map +0 -1
- package/lib/typescript/redux/utils/createReduxHistoryAdapter.d.ts.map +0 -1
- package/lib/typescript/redux/utils/index.d.ts.map +0 -1
- package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +0 -1
|
@@ -1,358 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.reduxActionStore = void 0;
|
|
7
|
-
/**
|
|
8
|
-
* Redux action store - captures and stores Redux Toolkit actions
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
// ============================================
|
|
12
|
-
// Helper Functions for Enhanced Data
|
|
13
|
-
// ============================================
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Get action category from type string
|
|
17
|
-
*/
|
|
18
|
-
function getActionCategory(type) {
|
|
19
|
-
if (type.startsWith("@@")) return "internal";
|
|
20
|
-
if (type.includes("/pending")) return "pending";
|
|
21
|
-
if (type.includes("/fulfilled")) return "fulfilled";
|
|
22
|
-
if (type.includes("/rejected")) return "rejected";
|
|
23
|
-
if (type.includes("/executeQuery")) return "query";
|
|
24
|
-
if (type.includes("/executeMutation")) return "mutation";
|
|
25
|
-
return "action";
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Parse action type to extract slice and action names
|
|
30
|
-
*/
|
|
31
|
-
function parseActionType(type) {
|
|
32
|
-
// Handle internal actions
|
|
33
|
-
if (type.startsWith("@@")) {
|
|
34
|
-
const parts = type.split("/");
|
|
35
|
-
return {
|
|
36
|
-
sliceName: null,
|
|
37
|
-
actionName: parts[parts.length - 1] || type
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Handle RTK pattern: "sliceName/actionName" or "sliceName/actionName/status"
|
|
42
|
-
const parts = type.split("/");
|
|
43
|
-
if (parts.length >= 2) {
|
|
44
|
-
const sliceName = parts[0];
|
|
45
|
-
// For async thunks, action name might be "fetchUser/pending" -> we want "fetchUser"
|
|
46
|
-
let actionName = parts[1];
|
|
47
|
-
|
|
48
|
-
// If it's an async status, use the base action name
|
|
49
|
-
if (parts.length >= 3 && ["pending", "fulfilled", "rejected"].includes(parts[parts.length - 1])) {
|
|
50
|
-
actionName = parts.slice(1, -1).join("/");
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
sliceName,
|
|
54
|
-
actionName: actionName.toUpperCase()
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
sliceName: null,
|
|
59
|
-
actionName: type.toUpperCase()
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Format payload preview for display
|
|
65
|
-
*/
|
|
66
|
-
function formatPayloadPreview(payload, maxLength = 40) {
|
|
67
|
-
if (payload === undefined) return "";
|
|
68
|
-
if (payload === null) return "null";
|
|
69
|
-
try {
|
|
70
|
-
if (typeof payload === "string") {
|
|
71
|
-
return payload.length > maxLength ? `"${payload.slice(0, maxLength - 3)}..."` : `"${payload}"`;
|
|
72
|
-
}
|
|
73
|
-
if (typeof payload === "number" || typeof payload === "boolean") {
|
|
74
|
-
return String(payload);
|
|
75
|
-
}
|
|
76
|
-
if (Array.isArray(payload)) {
|
|
77
|
-
if (payload.length === 0) return "[]";
|
|
78
|
-
const preview = JSON.stringify(payload);
|
|
79
|
-
return preview.length > maxLength ? `[${payload.length} items]` : preview;
|
|
80
|
-
}
|
|
81
|
-
if (typeof payload === "object") {
|
|
82
|
-
const keys = Object.keys(payload);
|
|
83
|
-
if (keys.length === 0) return "{}";
|
|
84
|
-
|
|
85
|
-
// Try to create a meaningful preview
|
|
86
|
-
const preview = JSON.stringify(payload);
|
|
87
|
-
if (preview.length <= maxLength) return preview;
|
|
88
|
-
|
|
89
|
-
// Show key count
|
|
90
|
-
return `{ ${keys.length} keys }`;
|
|
91
|
-
}
|
|
92
|
-
return String(payload).slice(0, maxLength);
|
|
93
|
-
} catch {
|
|
94
|
-
return "[complex]";
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Calculate state diff summary
|
|
100
|
-
*/
|
|
101
|
-
function getStateDiffSummary(prevState, nextState) {
|
|
102
|
-
if (prevState === nextState) {
|
|
103
|
-
return {
|
|
104
|
-
summary: "no change",
|
|
105
|
-
changedCount: 0
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Handle non-objects
|
|
110
|
-
if (typeof prevState !== "object" || typeof nextState !== "object" || prevState === null || nextState === null) {
|
|
111
|
-
return {
|
|
112
|
-
summary: "changed",
|
|
113
|
-
changedCount: 1
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
const prevKeys = Object.keys(prevState);
|
|
117
|
-
const nextKeys = Object.keys(nextState);
|
|
118
|
-
const added = nextKeys.filter(k => !prevKeys.includes(k)).length;
|
|
119
|
-
const removed = prevKeys.filter(k => !nextKeys.includes(k)).length;
|
|
120
|
-
|
|
121
|
-
// Check which existing keys changed
|
|
122
|
-
let changed = 0;
|
|
123
|
-
for (const key of prevKeys) {
|
|
124
|
-
if (nextKeys.includes(key) && prevState[key] !== nextState[key]) {
|
|
125
|
-
changed++;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
const parts = [];
|
|
129
|
-
if (added > 0) parts.push(`+${added}`);
|
|
130
|
-
if (removed > 0) parts.push(`-${removed}`);
|
|
131
|
-
if (changed > 0) parts.push(`~${changed}`);
|
|
132
|
-
const totalChanged = added + removed + changed;
|
|
133
|
-
if (parts.length === 0) {
|
|
134
|
-
return {
|
|
135
|
-
summary: "nested change",
|
|
136
|
-
changedCount: 1
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
return {
|
|
140
|
-
summary: `${parts.join(" ")} ${totalChanged === 1 ? "key" : "keys"}`,
|
|
141
|
-
changedCount: totalChanged
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Extract RTK async thunk metadata
|
|
147
|
-
*/
|
|
148
|
-
function extractMeta(action) {
|
|
149
|
-
const meta = action.meta;
|
|
150
|
-
if (!meta) return undefined;
|
|
151
|
-
return {
|
|
152
|
-
requestId: meta.requestId,
|
|
153
|
-
requestStatus: meta.requestStatus,
|
|
154
|
-
arg: meta.arg,
|
|
155
|
-
rejectedWithValue: meta.rejectedWithValue,
|
|
156
|
-
aborted: meta.aborted,
|
|
157
|
-
condition: meta.condition
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// ============================================
|
|
162
|
-
// Redux Action Store
|
|
163
|
-
// ============================================
|
|
164
|
-
|
|
165
|
-
class ReduxActionStore {
|
|
166
|
-
actions = [];
|
|
167
|
-
listeners = new Set();
|
|
168
|
-
maxActions = 200;
|
|
169
|
-
idCounter = 0;
|
|
170
|
-
isEnabled = true;
|
|
171
|
-
addAction(action, prevState, nextState, duration) {
|
|
172
|
-
if (!this.isEnabled) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
const actionType = action.type || "";
|
|
176
|
-
|
|
177
|
-
// Skip actions without a proper type (e.g., thunk functions)
|
|
178
|
-
if (!actionType) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
const hasStateChange = prevState !== nextState;
|
|
182
|
-
|
|
183
|
-
// Enhanced data extraction
|
|
184
|
-
const category = getActionCategory(actionType);
|
|
185
|
-
const {
|
|
186
|
-
sliceName,
|
|
187
|
-
actionName
|
|
188
|
-
} = parseActionType(actionType);
|
|
189
|
-
const meta = extractMeta(action);
|
|
190
|
-
const payloadPreview = formatPayloadPreview(action.payload);
|
|
191
|
-
const {
|
|
192
|
-
summary: diffSummary,
|
|
193
|
-
changedCount: changedKeysCount
|
|
194
|
-
} = getStateDiffSummary(prevState, nextState);
|
|
195
|
-
const isSlowAction = (duration ?? 0) > 16; // Frame budget
|
|
196
|
-
|
|
197
|
-
const reduxAction = {
|
|
198
|
-
id: `${Date.now()}-${++this.idCounter}`,
|
|
199
|
-
type: actionType,
|
|
200
|
-
payload: action.payload,
|
|
201
|
-
action,
|
|
202
|
-
timestamp: Date.now(),
|
|
203
|
-
prevState,
|
|
204
|
-
nextState,
|
|
205
|
-
duration,
|
|
206
|
-
hasStateChange,
|
|
207
|
-
// Enhanced fields
|
|
208
|
-
category,
|
|
209
|
-
sliceName,
|
|
210
|
-
actionName,
|
|
211
|
-
meta,
|
|
212
|
-
error: action.error,
|
|
213
|
-
payloadPreview,
|
|
214
|
-
diffSummary,
|
|
215
|
-
changedKeysCount,
|
|
216
|
-
isSlowAction
|
|
217
|
-
};
|
|
218
|
-
this.actions = [reduxAction, ...this.actions].slice(0, this.maxActions);
|
|
219
|
-
this.notifyListeners();
|
|
220
|
-
}
|
|
221
|
-
getActions() {
|
|
222
|
-
return [...this.actions];
|
|
223
|
-
}
|
|
224
|
-
getActionById(id) {
|
|
225
|
-
return this.actions.find(a => a.id === id);
|
|
226
|
-
}
|
|
227
|
-
clearActions() {
|
|
228
|
-
this.actions = [];
|
|
229
|
-
this.notifyListeners();
|
|
230
|
-
}
|
|
231
|
-
setEnabled(enabled) {
|
|
232
|
-
this.isEnabled = enabled;
|
|
233
|
-
}
|
|
234
|
-
getEnabled() {
|
|
235
|
-
return this.isEnabled;
|
|
236
|
-
}
|
|
237
|
-
subscribe(listener) {
|
|
238
|
-
this.listeners.add(listener);
|
|
239
|
-
return () => {
|
|
240
|
-
this.listeners.delete(listener);
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
notifyListeners() {
|
|
244
|
-
const actions = this.getActions();
|
|
245
|
-
this.listeners.forEach(listener => listener(actions));
|
|
246
|
-
}
|
|
247
|
-
setMaxActions(max) {
|
|
248
|
-
this.maxActions = max;
|
|
249
|
-
if (this.actions.length > max) {
|
|
250
|
-
this.actions = this.actions.slice(0, max);
|
|
251
|
-
this.notifyListeners();
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
getStats() {
|
|
255
|
-
const total = this.actions.length;
|
|
256
|
-
const withChanges = this.actions.filter(a => a.hasStateChange).length;
|
|
257
|
-
const actionTypes = new Set(this.actions.map(a => a.type));
|
|
258
|
-
|
|
259
|
-
// Calculate average duration
|
|
260
|
-
const durations = this.actions.filter(a => a.duration !== undefined).map(a => a.duration);
|
|
261
|
-
const avgDuration = durations.length > 0 ? durations.reduce((sum, d) => sum + d, 0) / durations.length : 0;
|
|
262
|
-
return {
|
|
263
|
-
totalActions: total,
|
|
264
|
-
actionsWithChanges: withChanges,
|
|
265
|
-
actionsWithoutChanges: total - withChanges,
|
|
266
|
-
uniqueActionTypes: actionTypes.size,
|
|
267
|
-
averageDuration: Math.round(avgDuration * 100) / 100
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
filterActions(filter) {
|
|
271
|
-
let filtered = [...this.actions];
|
|
272
|
-
if (filter.searchText) {
|
|
273
|
-
const search = filter.searchText.toLowerCase();
|
|
274
|
-
filtered = filtered.filter(a => a.type.toLowerCase().includes(search));
|
|
275
|
-
}
|
|
276
|
-
if (filter.actionTypes && filter.actionTypes.length > 0) {
|
|
277
|
-
filtered = filtered.filter(a => filter.actionTypes.includes(a.type));
|
|
278
|
-
}
|
|
279
|
-
if (filter.onlyWithChanges) {
|
|
280
|
-
filtered = filtered.filter(a => a.hasStateChange);
|
|
281
|
-
}
|
|
282
|
-
return filtered;
|
|
283
|
-
}
|
|
284
|
-
getUniqueActionTypes() {
|
|
285
|
-
return Array.from(new Set(this.actions.map(a => a.type))).sort();
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Find related async actions by requestId
|
|
290
|
-
*/
|
|
291
|
-
getRelatedActions(requestId) {
|
|
292
|
-
return this.actions.filter(a => a.meta?.requestId === requestId).sort((a, b) => a.timestamp - b.timestamp); // Sort chronologically
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Get all actions that share a requestId with the given action
|
|
297
|
-
*/
|
|
298
|
-
getLinkedActions(action) {
|
|
299
|
-
if (!action.meta?.requestId) return [];
|
|
300
|
-
return this.getRelatedActions(action.meta.requestId);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Get count of linked actions for a given action
|
|
305
|
-
*/
|
|
306
|
-
getLinkedActionsCount(action) {
|
|
307
|
-
if (!action.meta?.requestId) return 0;
|
|
308
|
-
return this.actions.filter(a => a.meta?.requestId === action.meta?.requestId).length;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Calculate total duration for an async operation (pending to resolution)
|
|
313
|
-
*/
|
|
314
|
-
getAsyncOperationDuration(requestId) {
|
|
315
|
-
const related = this.getRelatedActions(requestId);
|
|
316
|
-
if (related.length < 2) return null;
|
|
317
|
-
const pending = related.find(a => a.category === "pending");
|
|
318
|
-
const resolution = related.find(a => a.category === "fulfilled" || a.category === "rejected");
|
|
319
|
-
if (pending && resolution) {
|
|
320
|
-
return resolution.timestamp - pending.timestamp;
|
|
321
|
-
}
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Get the base action type (without /pending, /fulfilled, /rejected suffix)
|
|
327
|
-
*/
|
|
328
|
-
getBaseActionType(type) {
|
|
329
|
-
const parts = type.split("/");
|
|
330
|
-
if (parts.length >= 2) {
|
|
331
|
-
const lastPart = parts[parts.length - 1];
|
|
332
|
-
if (["pending", "fulfilled", "rejected"].includes(lastPart)) {
|
|
333
|
-
return parts.slice(0, -1).join("/");
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
return type;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Get sequential index for an async operation (1, 2, 3, etc.)
|
|
341
|
-
* Based on order of when pending actions first appeared
|
|
342
|
-
*/
|
|
343
|
-
getAsyncOperationIndex(requestId) {
|
|
344
|
-
// Get all unique requestIds with their first timestamp
|
|
345
|
-
const requestIdTimestamps = new Map();
|
|
346
|
-
for (const action of this.actions) {
|
|
347
|
-
if (action.meta?.requestId && !requestIdTimestamps.has(action.meta.requestId)) {
|
|
348
|
-
requestIdTimestamps.set(action.meta.requestId, action.timestamp);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// Sort by timestamp (oldest first) and find index
|
|
353
|
-
const sortedIds = Array.from(requestIdTimestamps.entries()).sort((a, b) => a[1] - b[1]).map(([id]) => id);
|
|
354
|
-
const index = sortedIds.indexOf(requestId);
|
|
355
|
-
return index >= 0 ? index + 1 : 0;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
const reduxActionStore = exports.reduxActionStore = new ReduxActionStore();
|
|
1
|
+
"use strict";function getActionCategory(t){return t.startsWith("@@")?"internal":t.includes("/pending")?"pending":t.includes("/fulfilled")?"fulfilled":t.includes("/rejected")?"rejected":t.includes("/executeQuery")?"query":t.includes("/executeMutation")?"mutation":"action"}function parseActionType(t){if(t.startsWith("@@")){const e=t.split("/");return{sliceName:null,actionName:e[e.length-1]||t}}const e=t.split("/");if(e.length>=2){const t=e[0];let n=e[1];return e.length>=3&&["pending","fulfilled","rejected"].includes(e[e.length-1])&&(n=e.slice(1,-1).join("/")),{sliceName:t,actionName:n.toUpperCase()}}return{sliceName:null,actionName:t.toUpperCase()}}function formatPayloadPreview(t,e=40){if(void 0===t)return"";if(null===t)return"null";try{if("string"==typeof t)return t.length>e?`"${t.slice(0,e-3)}..."`:`"${t}"`;if("number"==typeof t||"boolean"==typeof t)return String(t);if(Array.isArray(t)){if(0===t.length)return"[]";const n=JSON.stringify(t);return n.length>e?`[${t.length} items]`:n}if("object"==typeof t){const n=Object.keys(t);if(0===n.length)return"{}";const i=JSON.stringify(t);return i.length<=e?i:`{ ${n.length} keys }`}return String(t).slice(0,e)}catch{return"[complex]"}}function getStateDiffSummary(t,e){if(t===e)return{summary:"no change",changedCount:0};if("object"!=typeof t||"object"!=typeof e||null===t||null===e)return{summary:"changed",changedCount:1};const n=Object.keys(t),i=Object.keys(e),s=i.filter(t=>!n.includes(t)).length,r=n.filter(t=>!i.includes(t)).length;let o=0;for(const s of n)i.includes(s)&&t[s]!==e[s]&&o++;const a=[];s>0&&a.push(`+${s}`),r>0&&a.push(`-${r}`),o>0&&a.push(`~${o}`);const c=s+r+o;return 0===a.length?{summary:"nested change",changedCount:1}:{summary:`${a.join(" ")} ${1===c?"key":"keys"}`,changedCount:c}}function extractMeta(t){const e=t.meta;if(e)return{requestId:e.requestId,requestStatus:e.requestStatus,arg:e.arg,rejectedWithValue:e.rejectedWithValue,aborted:e.aborted,condition:e.condition}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.reduxActionStore=void 0;class ReduxActionStore{actions=[];listeners=new Set;maxActions=200;idCounter=0;isEnabled=!0;addAction(t,e,n,i){if(!this.isEnabled)return;const s=t.type||"";if(!s)return;const r=e!==n,o=getActionCategory(s),{sliceName:a,actionName:c}=parseActionType(s),u=extractMeta(t),l=formatPayloadPreview(t.payload),{summary:d,changedCount:h}=getStateDiffSummary(e,n),f=(i??0)>16,g={id:`${Date.now()}-${++this.idCounter}`,type:s,payload:t.payload,action:t,timestamp:Date.now(),prevState:e,nextState:n,duration:i,hasStateChange:r,category:o,sliceName:a,actionName:c,meta:u,error:t.error,payloadPreview:l,diffSummary:d,changedKeysCount:h,isSlowAction:f};this.actions=[g,...this.actions].slice(0,this.maxActions),this.notifyListeners()}getActions(){return[...this.actions]}getActionById(t){return this.actions.find(e=>e.id===t)}clearActions(){this.actions=[],this.notifyListeners()}setEnabled(t){this.isEnabled=t}getEnabled(){return this.isEnabled}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}notifyListeners(){const t=this.getActions();this.listeners.forEach(e=>e(t))}setMaxActions(t){this.maxActions=t,this.actions.length>t&&(this.actions=this.actions.slice(0,t),this.notifyListeners())}getStats(){const t=this.actions.length,e=this.actions.filter(t=>t.hasStateChange).length,n=new Set(this.actions.map(t=>t.type)),i=this.actions.filter(t=>void 0!==t.duration).map(t=>t.duration),s=i.length>0?i.reduce((t,e)=>t+e,0)/i.length:0;return{totalActions:t,actionsWithChanges:e,actionsWithoutChanges:t-e,uniqueActionTypes:n.size,averageDuration:Math.round(100*s)/100}}filterActions(t){let e=[...this.actions];if(t.searchText){const n=t.searchText.toLowerCase();e=e.filter(t=>t.type.toLowerCase().includes(n))}return t.actionTypes&&t.actionTypes.length>0&&(e=e.filter(e=>t.actionTypes.includes(e.type))),t.onlyWithChanges&&(e=e.filter(t=>t.hasStateChange)),e}getUniqueActionTypes(){return Array.from(new Set(this.actions.map(t=>t.type))).sort()}getRelatedActions(t){return this.actions.filter(e=>e.meta?.requestId===t).sort((t,e)=>t.timestamp-e.timestamp)}getLinkedActions(t){return t.meta?.requestId?this.getRelatedActions(t.meta.requestId):[]}getLinkedActionsCount(t){return t.meta?.requestId?this.actions.filter(e=>e.meta?.requestId===t.meta?.requestId).length:0}getAsyncOperationDuration(t){const e=this.getRelatedActions(t);if(e.length<2)return null;const n=e.find(t=>"pending"===t.category),i=e.find(t=>"fulfilled"===t.category||"rejected"===t.category);return n&&i?i.timestamp-n.timestamp:null}getBaseActionType(t){const e=t.split("/");if(e.length>=2){const t=e[e.length-1];if(["pending","fulfilled","rejected"].includes(t))return e.slice(0,-1).join("/")}return t}getAsyncOperationIndex(t){const e=new Map;for(const t of this.actions)t.meta?.requestId&&!e.has(t.meta.requestId)&&e.set(t.meta.requestId,t.timestamp);const n=Array.from(e.entries()).sort((t,e)=>t[1]-e[1]).map(([t])=>t).indexOf(t);return n>=0?n+1:0}}const reduxActionStore=exports.reduxActionStore=new ReduxActionStore;
|
package/lib/module/index.js
CHANGED
|
@@ -1,87 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @buoy-gg/redux
|
|
5
|
-
*
|
|
6
|
-
* Redux Toolkit DevTools for React Native
|
|
7
|
-
*
|
|
8
|
-
* PUBLIC API - Only these exports are supported for external use.
|
|
9
|
-
* Internal stores are not exported to prevent bypassing the tool's
|
|
10
|
-
* intended usage patterns.
|
|
11
|
-
*
|
|
12
|
-
* ZERO-CONFIG: Just install this package - that's it!
|
|
13
|
-
* The Redux DevTools automatically instruments your store when
|
|
14
|
-
* FloatingDevTools mounts. No middleware, no configuration needed.
|
|
15
|
-
*
|
|
16
|
-
* @example Zero-config setup (just install and use!)
|
|
17
|
-
* ```tsx
|
|
18
|
-
* // 1. Install: npm install @buoy-gg/redux
|
|
19
|
-
*
|
|
20
|
-
* // 2. Your existing Redux setup (NO CHANGES NEEDED!)
|
|
21
|
-
* const store = configureStore({ reducer: rootReducer });
|
|
22
|
-
*
|
|
23
|
-
* // 3. Your app with FloatingDevTools (Redux tool auto-detected!)
|
|
24
|
-
* <Provider store={store}>
|
|
25
|
-
* <App />
|
|
26
|
-
* <FloatingDevTools /> // Redux tool appears automatically!
|
|
27
|
-
* </Provider>
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* That's it! The Redux tool will auto-detect your store and capture actions.
|
|
31
|
-
*
|
|
32
|
-
* @example Advanced: Manual middleware (only if you need more control)
|
|
33
|
-
* ```tsx
|
|
34
|
-
* // For time-travel or custom options, you can optionally use middleware:
|
|
35
|
-
* import { buoyReduxMiddleware, withBuoyDevTools } from '@buoy-gg/redux';
|
|
36
|
-
*
|
|
37
|
-
* const store = configureStore({
|
|
38
|
-
* reducer: withBuoyDevTools(rootReducer), // Enables time-travel
|
|
39
|
-
* middleware: (getDefaultMiddleware) =>
|
|
40
|
-
* getDefaultMiddleware().concat(buoyReduxMiddleware),
|
|
41
|
-
* });
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
// =============================================================================
|
|
46
|
-
// PRESET (Primary entry point for users)
|
|
47
|
-
// =============================================================================
|
|
48
|
-
export { reduxToolPreset, createReduxTool } from "./preset";
|
|
49
|
-
|
|
50
|
-
// =============================================================================
|
|
51
|
-
// MIDDLEWARE (Optional - for manual setup if preferred over auto-instrumentation)
|
|
52
|
-
// =============================================================================
|
|
53
|
-
export { buoyReduxMiddleware, createBuoyReduxMiddleware, withBuoyDevTools, jumpToState, replayAction, BUOY_JUMP_TO_STATE, BUOY_REPLAY_ACTION } from "./redux/utils/buoyReduxMiddleware";
|
|
54
|
-
|
|
55
|
-
// =============================================================================
|
|
56
|
-
// AUTO-INSTRUMENTATION (For programmatic store instrumentation)
|
|
57
|
-
// =============================================================================
|
|
58
|
-
export { instrumentStore, uninstrumentStore, isStoreInstrumented, isAutoInstrumentActive, getActiveStore } from "./redux/utils/autoInstrument";
|
|
59
|
-
// =============================================================================
|
|
60
|
-
// HISTORY ADAPTER (For universal history devtools)
|
|
61
|
-
// =============================================================================
|
|
62
|
-
export { createReduxHistoryAdapter, reduxHistoryAdapter } from "./redux/utils/createReduxHistoryAdapter";
|
|
63
|
-
|
|
64
|
-
// =============================================================================
|
|
65
|
-
// HOOKS (For consuming Redux action data)
|
|
66
|
-
// =============================================================================
|
|
67
|
-
export { useReduxActions } from "./redux/hooks/useReduxActions";
|
|
68
|
-
// Auto-instrumentation hooks (for advanced use cases)
|
|
69
|
-
export { useAutoInstrumentRedux, useReduxAvailability } from "./redux/hooks/useAutoInstrumentRedux";
|
|
70
|
-
// =============================================================================
|
|
71
|
-
// COMPONENTS (For custom UI implementations)
|
|
72
|
-
// =============================================================================
|
|
73
|
-
export { ReduxModal, FREE_TIER_ACTION_LIMIT } from "./redux/components/ReduxModal";
|
|
74
|
-
export { ReduxActionItem } from "./redux/components/ReduxActionItem";
|
|
75
|
-
export { ReduxActionDetailView } from "./redux/components/ReduxActionDetailView";
|
|
76
|
-
export { ReduxActionDetailContent, ReduxActionDetailFooter } from "./redux/components/ReduxActionDetailContent";
|
|
77
|
-
export { ReduxIcon } from "./redux/components/ReduxIcon";
|
|
78
|
-
|
|
79
|
-
// =============================================================================
|
|
80
|
-
// TYPES
|
|
81
|
-
// =============================================================================
|
|
82
|
-
|
|
83
|
-
// =============================================================================
|
|
84
|
-
// INTERNAL EXPORTS (For @buoy-gg/* packages only - not part of public API)
|
|
85
|
-
// =============================================================================
|
|
86
|
-
/** @internal */
|
|
87
|
-
export { reduxActionStore } from "./redux/utils/reduxActionStore";
|
|
1
|
+
"use strict";export{reduxToolPreset,createReduxTool}from"./preset";export{buoyReduxMiddleware,createBuoyReduxMiddleware,withBuoyDevTools,jumpToState,replayAction,BUOY_JUMP_TO_STATE,BUOY_REPLAY_ACTION}from"./redux/utils/buoyReduxMiddleware";export{instrumentStore,uninstrumentStore,isStoreInstrumented,isAutoInstrumentActive,getActiveStore}from"./redux/utils/autoInstrument";export{createReduxHistoryAdapter,reduxHistoryAdapter}from"./redux/utils/createReduxHistoryAdapter";export{useReduxActions}from"./redux/hooks/useReduxActions";export{useAutoInstrumentRedux,useReduxAvailability}from"./redux/hooks/useAutoInstrumentRedux";export{ReduxModal,FREE_TIER_ACTION_LIMIT}from"./redux/components/ReduxModal";export{ReduxActionItem}from"./redux/components/ReduxActionItem";export{ReduxActionDetailView}from"./redux/components/ReduxActionDetailView";export{ReduxActionDetailContent,ReduxActionDetailFooter}from"./redux/components/ReduxActionDetailContent";export{ReduxIcon}from"./redux/components/ReduxIcon";export{reduxActionStore}from"./redux/utils/reduxActionStore";
|
package/lib/module/preset.js
CHANGED
|
@@ -1,94 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Pre-configured Redux DevTools preset for FloatingDevTools
|
|
5
|
-
*
|
|
6
|
-
* ZERO-CONFIG: This preset is auto-discovered by FloatingDevTools!
|
|
7
|
-
* You do NOT need to import or configure anything - just install @buoy-gg/redux
|
|
8
|
-
* and the Redux tool will appear automatically in your FloatingDevTools.
|
|
9
|
-
*
|
|
10
|
-
* @example Automatic (recommended - no code needed!)
|
|
11
|
-
* ```tsx
|
|
12
|
-
* // Just install: npm install @buoy-gg/redux
|
|
13
|
-
* // The Redux tool appears automatically in FloatingDevTools!
|
|
14
|
-
*
|
|
15
|
-
* <Provider store={store}>
|
|
16
|
-
* <App />
|
|
17
|
-
* <FloatingDevTools /> // Redux tool is auto-detected
|
|
18
|
-
* </Provider>
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* @example Manual (only for custom configuration)
|
|
22
|
-
* ```tsx
|
|
23
|
-
* import { createReduxTool } from '@buoy-gg/redux';
|
|
24
|
-
*
|
|
25
|
-
* // Only use this if you need to customize the tool
|
|
26
|
-
* const customReduxTool = createReduxTool({
|
|
27
|
-
* name: "STATE",
|
|
28
|
-
* iconColor: "#9945FF",
|
|
29
|
-
* });
|
|
30
|
-
*
|
|
31
|
-
* <FloatingDevTools apps={[customReduxTool]} />
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
import { ReduxModal } from "./redux/components/ReduxModal";
|
|
36
|
-
import { ReduxIcon } from "./redux/components/ReduxIcon";
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Pre-configured Redux DevTools preset for FloatingDevTools.
|
|
40
|
-
* Includes:
|
|
41
|
-
* - Live action monitoring
|
|
42
|
-
* - Action/state inspection
|
|
43
|
-
* - State diff visualization
|
|
44
|
-
* - Filter by action type
|
|
45
|
-
*/
|
|
46
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
47
|
-
export const reduxToolPreset = {
|
|
48
|
-
id: "redux",
|
|
49
|
-
name: "REDUX",
|
|
50
|
-
description: "Redux action & state inspector",
|
|
51
|
-
slot: "both",
|
|
52
|
-
icon: ({
|
|
53
|
-
size
|
|
54
|
-
}) => /*#__PURE__*/_jsx(ReduxIcon, {
|
|
55
|
-
size: size
|
|
56
|
-
}),
|
|
57
|
-
component: ReduxModal,
|
|
58
|
-
props: {
|
|
59
|
-
enableSharedModalDimensions: false
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create a custom Redux DevTools configuration.
|
|
65
|
-
* Use this if you want to override default settings.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```tsx
|
|
69
|
-
* import { createReduxTool } from '@buoy-gg/redux';
|
|
70
|
-
*
|
|
71
|
-
* const myReduxTool = createReduxTool({
|
|
72
|
-
* name: "STATE",
|
|
73
|
-
* iconColor: "#9945FF", // Purple color
|
|
74
|
-
* });
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
export function createReduxTool(options) {
|
|
78
|
-
return {
|
|
79
|
-
id: options?.id || "redux",
|
|
80
|
-
name: options?.name || "REDUX",
|
|
81
|
-
description: options?.description || "Redux action & state inspector",
|
|
82
|
-
slot: "both",
|
|
83
|
-
icon: ({
|
|
84
|
-
size
|
|
85
|
-
}) => /*#__PURE__*/_jsx(ReduxIcon, {
|
|
86
|
-
size: size,
|
|
87
|
-
color: options?.iconColor
|
|
88
|
-
}),
|
|
89
|
-
component: ReduxModal,
|
|
90
|
-
props: {
|
|
91
|
-
enableSharedModalDimensions: options?.enableSharedModalDimensions !== undefined ? options.enableSharedModalDimensions : false
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
1
|
+
"use strict";import{ReduxModal}from"./redux/components/ReduxModal";import{ReduxIcon}from"./redux/components/ReduxIcon";import{jsx as _jsx}from"react/jsx-runtime";export const reduxToolPreset={id:"redux",name:"REDUX",description:"Redux action & state inspector",slot:"both",icon:({size:e})=>_jsx(ReduxIcon,{size:e}),component:ReduxModal,props:{enableSharedModalDimensions:!1}};export function createReduxTool(e){return{id:e?.id||"redux",name:e?.name||"REDUX",description:e?.description||"Redux action & state inspector",slot:"both",icon:({size:o})=>_jsx(ReduxIcon,{size:o,color:e?.iconColor}),component:ReduxModal,props:{enableSharedModalDimensions:void 0!==e?.enableSharedModalDimensions&&e.enableSharedModalDimensions}}}
|
|
@@ -1,126 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* ReduxActionButton
|
|
5
|
-
*
|
|
6
|
-
* Generic action button for Redux DevTools footer
|
|
7
|
-
* Matches React Query DevTools ActionButton styling
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { TouchableOpacity, Text, View, StyleSheet } from "react-native";
|
|
11
|
-
import { buoyColors } from "@buoy-gg/shared-ui";
|
|
12
|
-
|
|
13
|
-
// Button color configurations matching React Query pattern
|
|
14
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
-
const buttonConfigs = {
|
|
16
|
-
replay: {
|
|
17
|
-
color: buoyColors.success,
|
|
18
|
-
backgroundColor: buoyColors.success + "15",
|
|
19
|
-
borderColor: buoyColors.success + "40",
|
|
20
|
-
textColor: buoyColors.success
|
|
21
|
-
},
|
|
22
|
-
copy: {
|
|
23
|
-
color: buoyColors.primary,
|
|
24
|
-
backgroundColor: buoyColors.primary + "15",
|
|
25
|
-
borderColor: buoyColors.primary + "40",
|
|
26
|
-
textColor: buoyColors.primary
|
|
27
|
-
},
|
|
28
|
-
jump: {
|
|
29
|
-
color: buoyColors.warning,
|
|
30
|
-
backgroundColor: buoyColors.warning + "15",
|
|
31
|
-
borderColor: buoyColors.warning + "40",
|
|
32
|
-
textColor: buoyColors.warning
|
|
33
|
-
},
|
|
34
|
-
skip: {
|
|
35
|
-
color: buoyColors.textSecondary,
|
|
36
|
-
backgroundColor: buoyColors.textSecondary + "26",
|
|
37
|
-
borderColor: buoyColors.textSecondary + "59",
|
|
38
|
-
textColor: buoyColors.textSecondary
|
|
39
|
-
},
|
|
40
|
-
clear: {
|
|
41
|
-
color: buoyColors.error,
|
|
42
|
-
backgroundColor: buoyColors.error + "15",
|
|
43
|
-
borderColor: buoyColors.error + "40",
|
|
44
|
-
textColor: buoyColors.error
|
|
45
|
-
},
|
|
46
|
-
diff: {
|
|
47
|
-
color: buoyColors.info,
|
|
48
|
-
backgroundColor: buoyColors.info + "15",
|
|
49
|
-
borderColor: buoyColors.info + "40",
|
|
50
|
-
textColor: buoyColors.info
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
export function ReduxActionButton({
|
|
54
|
-
onPress,
|
|
55
|
-
text,
|
|
56
|
-
type,
|
|
57
|
-
disabled = false
|
|
58
|
-
}) {
|
|
59
|
-
const config = buttonConfigs[type];
|
|
60
|
-
return /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
61
|
-
disabled: disabled,
|
|
62
|
-
onPress: onPress,
|
|
63
|
-
style: [styles.button, {
|
|
64
|
-
backgroundColor: disabled ? buoyColors.textMuted + "1A" : config.backgroundColor,
|
|
65
|
-
borderColor: disabled ? buoyColors.textMuted + "33" : config.borderColor,
|
|
66
|
-
opacity: disabled ? 0.5 : 1
|
|
67
|
-
}],
|
|
68
|
-
activeOpacity: 0.7,
|
|
69
|
-
accessibilityRole: "button",
|
|
70
|
-
accessibilityLabel: text,
|
|
71
|
-
accessibilityState: {
|
|
72
|
-
disabled
|
|
73
|
-
},
|
|
74
|
-
children: [/*#__PURE__*/_jsx(View, {
|
|
75
|
-
style: [styles.dot, {
|
|
76
|
-
backgroundColor: disabled ? buoyColors.textMuted : config.color
|
|
77
|
-
}]
|
|
78
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
79
|
-
style: [styles.text, {
|
|
80
|
-
color: disabled ? buoyColors.textMuted : config.textColor
|
|
81
|
-
}],
|
|
82
|
-
children: text
|
|
83
|
-
})]
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
const styles = StyleSheet.create({
|
|
87
|
-
button: {
|
|
88
|
-
flexDirection: "row",
|
|
89
|
-
alignItems: "center",
|
|
90
|
-
justifyContent: "center",
|
|
91
|
-
borderRadius: 6,
|
|
92
|
-
borderWidth: 1,
|
|
93
|
-
paddingHorizontal: 12,
|
|
94
|
-
paddingVertical: 6,
|
|
95
|
-
height: 25,
|
|
96
|
-
minWidth: 80,
|
|
97
|
-
shadowOffset: {
|
|
98
|
-
width: 0,
|
|
99
|
-
height: 1
|
|
100
|
-
},
|
|
101
|
-
shadowOpacity: 0.2,
|
|
102
|
-
shadowRadius: 2,
|
|
103
|
-
elevation: 2
|
|
104
|
-
},
|
|
105
|
-
dot: {
|
|
106
|
-
width: 5,
|
|
107
|
-
height: 5,
|
|
108
|
-
borderRadius: 3,
|
|
109
|
-
marginRight: 6,
|
|
110
|
-
shadowColor: buoyColors.text,
|
|
111
|
-
shadowOffset: {
|
|
112
|
-
width: 0,
|
|
113
|
-
height: 0
|
|
114
|
-
},
|
|
115
|
-
shadowOpacity: 0.6,
|
|
116
|
-
shadowRadius: 2
|
|
117
|
-
},
|
|
118
|
-
text: {
|
|
119
|
-
fontSize: 10,
|
|
120
|
-
fontWeight: "600",
|
|
121
|
-
letterSpacing: 0.5,
|
|
122
|
-
textTransform: "uppercase",
|
|
123
|
-
fontFamily: "monospace",
|
|
124
|
-
height: 12
|
|
125
|
-
}
|
|
126
|
-
});
|
|
1
|
+
"use strict";import{TouchableOpacity,Text,View,StyleSheet}from"react-native";import{buoyColors}from"@buoy-gg/shared-ui";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const buttonConfigs={replay:{color:buoyColors.success,backgroundColor:buoyColors.success+"15",borderColor:buoyColors.success+"40",textColor:buoyColors.success},copy:{color:buoyColors.primary,backgroundColor:buoyColors.primary+"15",borderColor:buoyColors.primary+"40",textColor:buoyColors.primary},jump:{color:buoyColors.warning,backgroundColor:buoyColors.warning+"15",borderColor:buoyColors.warning+"40",textColor:buoyColors.warning},skip:{color:buoyColors.textSecondary,backgroundColor:buoyColors.textSecondary+"26",borderColor:buoyColors.textSecondary+"59",textColor:buoyColors.textSecondary},clear:{color:buoyColors.error,backgroundColor:buoyColors.error+"15",borderColor:buoyColors.error+"40",textColor:buoyColors.error},diff:{color:buoyColors.info,backgroundColor:buoyColors.info+"15",borderColor:buoyColors.info+"40",textColor:buoyColors.info}};export function ReduxActionButton({onPress:o,text:r,type:t,disabled:e=!1}){const s=buttonConfigs[t];return _jsxs(TouchableOpacity,{disabled:e,onPress:o,style:[styles.button,{backgroundColor:e?buoyColors.textMuted+"1A":s.backgroundColor,borderColor:e?buoyColors.textMuted+"33":s.borderColor,opacity:e?.5:1}],activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:r,accessibilityState:{disabled:e},children:[_jsx(View,{style:[styles.dot,{backgroundColor:e?buoyColors.textMuted:s.color}]}),_jsx(Text,{style:[styles.text,{color:e?buoyColors.textMuted:s.textColor}],children:r})]})}const styles=StyleSheet.create({button:{flexDirection:"row",alignItems:"center",justifyContent:"center",borderRadius:6,borderWidth:1,paddingHorizontal:12,paddingVertical:6,height:25,minWidth:80,shadowOffset:{width:0,height:1},shadowOpacity:.2,shadowRadius:2,elevation:2},dot:{width:5,height:5,borderRadius:3,marginRight:6,shadowColor:buoyColors.text,shadowOffset:{width:0,height:0},shadowOpacity:.6,shadowRadius:2},text:{fontSize:10,fontWeight:"600",letterSpacing:.5,textTransform:"uppercase",fontFamily:"monospace",height:12}});
|