@buoy-gg/console 7.0.40 → 7.0.42

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 (108) hide show
  1. package/README.md +11 -65
  2. package/lib/commonjs/components/ConsoleIcon.js +1 -19
  3. package/lib/commonjs/components/ConsoleLogList.js +1 -152
  4. package/lib/commonjs/components/ConsoleModal.js +1 -48
  5. package/lib/commonjs/components/ConsoleRoot.js +1 -37
  6. package/lib/commonjs/devtools/ConsoleBody.js +1 -234
  7. package/lib/commonjs/devtools/ConsoleHeader.js +1 -114
  8. package/lib/commonjs/devtools/ConsoleMessageRow.js +1 -356
  9. package/lib/commonjs/devtools/ConsoleValue.js +1 -254
  10. package/lib/commonjs/devtools/ConsoleView.js +1 -54
  11. package/lib/commonjs/devtools/consoleFilter.js +1 -125
  12. package/lib/commonjs/devtools/consoleFormat.js +1 -313
  13. package/lib/commonjs/devtools/origin.js +1 -191
  14. package/lib/commonjs/devtools/theme.js +1 -152
  15. package/lib/commonjs/devtools/useConsoleController.js +1 -82
  16. package/lib/commonjs/devtools/useConsoleMessages.js +1 -241
  17. package/lib/commonjs/hooks/useConsoleLogs.js +1 -23
  18. package/lib/commonjs/index.js +1 -181
  19. package/lib/commonjs/preset.js +1 -63
  20. package/lib/commonjs/store/consoleLogStore.js +6 -587
  21. package/lib/commonjs/store/sanitize.js +1 -83
  22. package/lib/commonjs/sync/consoleSyncAdapter.js +1 -86
  23. package/lib/module/components/ConsoleIcon.js +1 -12
  24. package/lib/module/components/ConsoleLogList.js +1 -147
  25. package/lib/module/components/ConsoleModal.js +1 -44
  26. package/lib/module/components/ConsoleRoot.js +1 -33
  27. package/lib/module/devtools/ConsoleBody.js +1 -229
  28. package/lib/module/devtools/ConsoleHeader.js +1 -109
  29. package/lib/module/devtools/ConsoleMessageRow.js +1 -352
  30. package/lib/module/devtools/ConsoleValue.js +1 -249
  31. package/lib/module/devtools/ConsoleView.js +1 -49
  32. package/lib/module/devtools/consoleFilter.js +1 -119
  33. package/lib/module/devtools/consoleFormat.js +1 -309
  34. package/lib/module/devtools/origin.js +1 -183
  35. package/lib/module/devtools/theme.js +1 -143
  36. package/lib/module/devtools/useConsoleController.js +1 -79
  37. package/lib/module/devtools/useConsoleMessages.js +1 -238
  38. package/lib/module/hooks/useConsoleLogs.js +1 -19
  39. package/lib/module/index.js +1 -52
  40. package/lib/module/preset.js +1 -61
  41. package/lib/module/store/consoleLogStore.js +6 -573
  42. package/lib/module/store/sanitize.js +1 -77
  43. package/lib/module/sync/consoleSyncAdapter.js +1 -82
  44. package/lib/web/index.mjs +17 -0
  45. package/package.json +39 -5
  46. package/lib/commonjs/components/ConsoleIcon.js.map +0 -1
  47. package/lib/commonjs/components/ConsoleLogList.js.map +0 -1
  48. package/lib/commonjs/components/ConsoleModal.js.map +0 -1
  49. package/lib/commonjs/components/ConsoleRoot.js.map +0 -1
  50. package/lib/commonjs/devtools/ConsoleBody.js.map +0 -1
  51. package/lib/commonjs/devtools/ConsoleHeader.js.map +0 -1
  52. package/lib/commonjs/devtools/ConsoleMessageRow.js.map +0 -1
  53. package/lib/commonjs/devtools/ConsoleValue.js.map +0 -1
  54. package/lib/commonjs/devtools/ConsoleView.js.map +0 -1
  55. package/lib/commonjs/devtools/consoleFilter.js.map +0 -1
  56. package/lib/commonjs/devtools/consoleFormat.js.map +0 -1
  57. package/lib/commonjs/devtools/origin.js.map +0 -1
  58. package/lib/commonjs/devtools/theme.js.map +0 -1
  59. package/lib/commonjs/devtools/useConsoleController.js.map +0 -1
  60. package/lib/commonjs/devtools/useConsoleMessages.js.map +0 -1
  61. package/lib/commonjs/hooks/useConsoleLogs.js.map +0 -1
  62. package/lib/commonjs/index.js.map +0 -1
  63. package/lib/commonjs/preset.js.map +0 -1
  64. package/lib/commonjs/store/consoleLogStore.js.map +0 -1
  65. package/lib/commonjs/store/sanitize.js.map +0 -1
  66. package/lib/commonjs/sync/consoleSyncAdapter.js.map +0 -1
  67. package/lib/module/components/ConsoleIcon.js.map +0 -1
  68. package/lib/module/components/ConsoleLogList.js.map +0 -1
  69. package/lib/module/components/ConsoleModal.js.map +0 -1
  70. package/lib/module/components/ConsoleRoot.js.map +0 -1
  71. package/lib/module/devtools/ConsoleBody.js.map +0 -1
  72. package/lib/module/devtools/ConsoleHeader.js.map +0 -1
  73. package/lib/module/devtools/ConsoleMessageRow.js.map +0 -1
  74. package/lib/module/devtools/ConsoleValue.js.map +0 -1
  75. package/lib/module/devtools/ConsoleView.js.map +0 -1
  76. package/lib/module/devtools/consoleFilter.js.map +0 -1
  77. package/lib/module/devtools/consoleFormat.js.map +0 -1
  78. package/lib/module/devtools/origin.js.map +0 -1
  79. package/lib/module/devtools/theme.js.map +0 -1
  80. package/lib/module/devtools/useConsoleController.js.map +0 -1
  81. package/lib/module/devtools/useConsoleMessages.js.map +0 -1
  82. package/lib/module/hooks/useConsoleLogs.js.map +0 -1
  83. package/lib/module/index.js.map +0 -1
  84. package/lib/module/preset.js.map +0 -1
  85. package/lib/module/store/consoleLogStore.js.map +0 -1
  86. package/lib/module/store/sanitize.js.map +0 -1
  87. package/lib/module/sync/consoleSyncAdapter.js.map +0 -1
  88. package/lib/typescript/components/ConsoleIcon.d.ts.map +0 -1
  89. package/lib/typescript/components/ConsoleLogList.d.ts.map +0 -1
  90. package/lib/typescript/components/ConsoleModal.d.ts.map +0 -1
  91. package/lib/typescript/components/ConsoleRoot.d.ts.map +0 -1
  92. package/lib/typescript/devtools/ConsoleBody.d.ts.map +0 -1
  93. package/lib/typescript/devtools/ConsoleHeader.d.ts.map +0 -1
  94. package/lib/typescript/devtools/ConsoleMessageRow.d.ts.map +0 -1
  95. package/lib/typescript/devtools/ConsoleValue.d.ts.map +0 -1
  96. package/lib/typescript/devtools/ConsoleView.d.ts.map +0 -1
  97. package/lib/typescript/devtools/consoleFilter.d.ts.map +0 -1
  98. package/lib/typescript/devtools/consoleFormat.d.ts.map +0 -1
  99. package/lib/typescript/devtools/origin.d.ts.map +0 -1
  100. package/lib/typescript/devtools/theme.d.ts.map +0 -1
  101. package/lib/typescript/devtools/useConsoleController.d.ts.map +0 -1
  102. package/lib/typescript/devtools/useConsoleMessages.d.ts.map +0 -1
  103. package/lib/typescript/hooks/useConsoleLogs.d.ts.map +0 -1
  104. package/lib/typescript/index.d.ts.map +0 -1
  105. package/lib/typescript/preset.d.ts.map +0 -1
  106. package/lib/typescript/store/consoleLogStore.d.ts.map +0 -1
  107. package/lib/typescript/store/sanitize.d.ts.map +0 -1
  108. package/lib/typescript/sync/consoleSyncAdapter.d.ts.map +0 -1
@@ -1,83 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.SNAPSHOT_STRING_LIMIT = void 0;
7
- exports.capString = capString;
8
- exports.sanitizeArgs = sanitizeArgs;
9
- /**
10
- * sanitizeArgs — deep-convert captured console arguments into JSON-safe values.
11
- *
12
- * Captured `args` can hold Errors, functions, bigints, symbols, and circular
13
- * references. Both the external-sync snapshot (device → desktop) and the
14
- * preserve-log persistence need plain JSON, so this produces a structural copy
15
- * (objects/arrays preserved so they stay expandable) with cycles broken.
16
- *
17
- * Strings are capped: a single `console.log` of a multi-MB payload (API dump,
18
- * base64, …) used to ride every snapshot uncapped and drop the whole console
19
- * panel at the 2MB emit budget.
20
- */
21
-
22
- const MAX_DEPTH = 6;
23
- const MAX_ARRAY = 100;
24
- const MAX_KEYS = 100;
25
-
26
- /** Max chars of one string on the wire / in the persisted buffer. */
27
- const SNAPSHOT_STRING_LIMIT = exports.SNAPSHOT_STRING_LIMIT = 2 * 1024;
28
- function capString(value, limit = SNAPSHOT_STRING_LIMIT) {
29
- if (value.length <= limit) return value;
30
- return `${value.slice(0, limit)}… [${value.length - limit} more]`;
31
- }
32
- function sanitizeValue(value, depth, seen) {
33
- if (value === null) return null;
34
- // Checked inline rather than through a `const t = typeof value` alias: the
35
- // alias does not narrow `value`, so the string branch could not be handed to
36
- // a `(s: string)` function without a cast — which is how this file stopped
37
- // compiling.
38
- if (typeof value === "string") return capString(value);
39
- if (typeof value === "boolean") return value;
40
- if (typeof value === "number") return Number.isFinite(value) ? value : String(value);
41
- if (typeof value === "undefined") return "undefined";
42
- if (typeof value === "bigint") return `${String(value)}n`;
43
- if (typeof value === "function") {
44
- return `ƒ ${value.name || "(anonymous)"}`;
45
- }
46
- if (typeof value === "symbol") return value.toString();
47
- if (value instanceof Error) {
48
- return {
49
- name: value.name,
50
- message: capString(value.message),
51
- stack: value.stack ? capString(value.stack, 4 * 1024) : value.stack
52
- };
53
- }
54
- if (depth >= MAX_DEPTH) return Array.isArray(value) ? "[Array]" : "{…}";
55
- const obj = value;
56
- if (seen.has(obj)) return "[Circular]";
57
- seen.add(obj);
58
- try {
59
- if (Array.isArray(value)) {
60
- const out = value.slice(0, MAX_ARRAY).map(v => sanitizeValue(v, depth + 1, seen));
61
- if (value.length > MAX_ARRAY) out.push(`… ${value.length - MAX_ARRAY} more`);
62
- return out;
63
- }
64
- const out = {};
65
- for (const key of Object.keys(obj).slice(0, MAX_KEYS)) {
66
- try {
67
- out[key] = sanitizeValue(obj[key], depth + 1, seen);
68
- } catch {
69
- out[key] = "[Unserializable]";
70
- }
71
- }
72
- return out;
73
- } finally {
74
- seen.delete(obj);
75
- }
76
- }
77
-
78
- /** Deep-sanitize an array of console arguments into JSON-safe values. */
79
- function sanitizeArgs(args) {
80
- const seen = new WeakSet();
81
- return args.map(arg => sanitizeValue(arg, 0, seen));
82
- }
83
- //# sourceMappingURL=sanitize.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SNAPSHOT_STRING_LIMIT=void 0;exports.capString=capString;exports.sanitizeArgs=sanitizeArgs;const MAX_DEPTH=6;const MAX_ARRAY=100;const MAX_KEYS=100;const SNAPSHOT_STRING_LIMIT=exports.SNAPSHOT_STRING_LIMIT=2*1024;function capString(r,t=SNAPSHOT_STRING_LIMIT){if(r.length<=t)return r;return`${r.slice(0,t)}\u2026 [${r.length-t} more]`}function sanitizeValue(r,t,n){if(r===null)return null;if(typeof r==="string")return capString(r);if(typeof r==="boolean")return r;if(typeof r==="number")return Number.isFinite(r)?r:String(r);if(typeof r==="undefined")return"undefined";if(typeof r==="bigint")return`${String(r)}n`;if(typeof r==="function"){return`\u0192 ${r.name||"(anonymous)"}`}if(typeof r==="symbol")return r.toString();if(r instanceof Error){return{name:r.name,message:capString(r.message),stack:r.stack?capString(r.stack,4*1024):r.stack}}if(t>=MAX_DEPTH)return Array.isArray(r)?"[Array]":"{\u2026}";const o=r;if(n.has(o))return"[Circular]";n.add(o);try{if(Array.isArray(r)){const i=r.slice(0,MAX_ARRAY).map(e=>sanitizeValue(e,t+1,n));if(r.length>MAX_ARRAY)i.push(`\u2026 ${r.length-MAX_ARRAY} more`);return i}const s={};for(const i of Object.keys(o).slice(0,MAX_KEYS)){try{s[i]=sanitizeValue(o[i],t+1,n)}catch{s[i]="[Unserializable]"}}return s}finally{n.delete(o)}}function sanitizeArgs(r){const t=new WeakSet;return r.map(n=>sanitizeValue(n,0,t))}
@@ -1,86 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.consoleSyncAdapter = void 0;
7
- var _consoleLogStore = require("../store/consoleLogStore");
8
- var _sharedUi = require("@buoy-gg/shared-ui");
9
- var _sanitize = require("../store/sanitize");
10
- /**
11
- * consoleSyncAdapter — streams captured console entries from the device to the
12
- * desktop dashboard via @buoy-gg/external-sync.
13
- *
14
- * Structurally matches external-sync's `ToolSyncAdapter` WITHOUT importing the
15
- * package (so console has no hard dependency on external-sync, matching how the
16
- * other tools' adapters are written). Auto-discovery in @buoy-gg/core picks it
17
- * up by the export name and announces the "console" capability.
18
- *
19
- * Snapshots MUST be JSON-serializable. Captured `args` can hold Errors,
20
- * functions, bigints, and circular references, so we deep-sanitize them into
21
- * plain JSON values (objects/arrays preserved so they stay expandable on the
22
- * dashboard). Oversized strings and the pre-rendered `message` are capped so
23
- * a single fat `console.log` cannot drop the whole panel at the 2MB emit
24
- * budget; the on-device store keeps the raw args.
25
- */
26
-
27
- /** Soft cap so a burst of fat logs still fits under the 2MB emit budget. */
28
- const MAX_SNAPSHOT_BYTES = 1.5 * 1024 * 1024;
29
- /** One entry's args/message after string caps; fatter args collapse to a stub. */
30
- const MAX_ENTRY_BYTES = 16 * 1024;
31
- const ARGS_OMITTED = Object.freeze({
32
- __buoyTruncated: true,
33
- note: "Log payload omitted — inspect it on-device."
34
- });
35
-
36
- /**
37
- * Per-entry wire cache. A captured entry is never mutated — the store only
38
- * appends and trims — so keying on identity is correct and self-invalidating.
39
- *
40
- * This is the whole cost of the tool. `sanitizeArgs` deep-copies every arg to
41
- * make it JSON-safe, and without a cache that copy is redone for all 1000
42
- * entries on every snapshot, ~5x/sec: measured at 12.6ms per tick on ordinary
43
- * object logs, and it was that expensive BEFORE any of the size guards
44
- * existed. Converting each entry once removes it from the hot path entirely.
45
- */
46
- const toWireEntry = (0, _sharedUi.memoByIdentity)(entry => {
47
- const wired = {
48
- ...entry,
49
- args: (0, _sanitize.sanitizeArgs)(entry.args),
50
- message: (0, _sanitize.capString)(entry.message),
51
- stack: entry.stack ? (0, _sanitize.capString)(entry.stack, 4 * 1024) : entry.stack
52
- };
53
- // One walk decides both "is this entry too fat" and what it costs the
54
- // snapshot budget.
55
- return (0, _sharedUi.sizeOrStub)(wired, MAX_ENTRY_BYTES, () => ({
56
- ...wired,
57
- args: [ARGS_OMITTED]
58
- }));
59
- });
60
- function newestFitting(entries) {
61
- return (0, _sharedUi.newestFitting)(entries, {
62
- toWire: toWireEntry,
63
- budget: MAX_SNAPSHOT_BYTES,
64
- baseBytes: 16 // {"entries":[]}
65
- });
66
- }
67
- const consoleSyncAdapter = exports.consoleSyncAdapter = (0, _sharedUi.createSyncAdapter)({
68
- version: 1,
69
- getSnapshot() {
70
- return {
71
- entries: newestFitting((0, _consoleLogStore.getEntries)())
72
- };
73
- },
74
- subscribe(onChange) {
75
- return (0, _consoleLogStore.subscribe)(onChange);
76
- },
77
- actions: {
78
- clearEntries() {
79
- (0, _consoleLogStore.clearEntries)();
80
- return {
81
- cleared: true
82
- };
83
- }
84
- }
85
- });
86
- //# sourceMappingURL=consoleSyncAdapter.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.consoleSyncAdapter=void 0;var _consoleLogStore=require("../store/consoleLogStore");var _sharedUi=require("@buoy-gg/shared-ui");var _sanitize=require("../store/sanitize");const MAX_SNAPSHOT_BYTES=1.5*1024*1024;const MAX_ENTRY_BYTES=16*1024;const ARGS_OMITTED=Object.freeze({__buoyTruncated:true,note:"Log payload omitted \u2014 inspect it on-device."});const toWireEntry=(0,_sharedUi.memoByIdentity)(e=>{const t={...e,args:(0,_sanitize.sanitizeArgs)(e.args),message:(0,_sanitize.capString)(e.message),stack:e.stack?(0,_sanitize.capString)(e.stack,4*1024):e.stack};return(0,_sharedUi.sizeOrStub)(t,MAX_ENTRY_BYTES,()=>({...t,args:[ARGS_OMITTED]}))});function newestFitting(e){return(0,_sharedUi.newestFitting)(e,{toWire:toWireEntry,budget:MAX_SNAPSHOT_BYTES,baseBytes:16})}const consoleSyncAdapter=exports.consoleSyncAdapter=(0,_sharedUi.createSyncAdapter)({version:1,getSnapshot(){return{entries:newestFitting((0,_consoleLogStore.getEntries)())}},subscribe(e){return(0,_consoleLogStore.subscribe)(e)},actions:{clearEntries(){(0,_consoleLogStore.clearEntries)();return{cleared:true}}}});
@@ -1,12 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * ConsoleIcon — the original terminal artwork rendered as a transparent PNG.
5
- *
6
- * shared-ui re-exports the native/web raster components from floating-tools-core.
7
- * Source: shared/icons/console.json. Regenerate density assets with
8
- * scripts/export-console-icon.cjs, then scripts/sync-raster-icons.cjs.
9
- */
10
-
11
- export { ConsoleIcon, CONSOLE_ICON_COLOR } from "@buoy-gg/shared-ui";
12
- //# sourceMappingURL=ConsoleIcon.js.map
1
+ "use strict";export{ConsoleIcon,CONSOLE_ICON_COLOR}from"@buoy-gg/shared-ui";
@@ -1,147 +1 @@
1
- "use strict";
2
-
3
- import React from "react";
4
- import { View, Text, FlatList, TouchableOpacity, StyleSheet } from "react-native";
5
- import { useConsoleLogs } from "../hooks/useConsoleLogs";
6
- import { night, ToolEmptyState, monoFont } from "@buoy-gg/shared-ui";
7
- import { clearEntries } from "../store/consoleLogStore";
8
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
- const LEVEL_COLOR = {
10
- verbose: "#9b9b9b",
11
- info: night.color.text,
12
- warning: "#e2c08d",
13
- error: "#f48771"
14
- };
15
- function formatTime(ts) {
16
- const d = new Date(ts);
17
- const pad = (n, len = 2) => String(n).padStart(len, "0");
18
- return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${pad(d.getMilliseconds(), 3)}`;
19
- }
20
-
21
- /**
22
- * Basic console log list — a flat, newest-last stream of captured entries.
23
- * This is the proof-of-concept view; it will be replaced by a 1:1 port of
24
- * Chrome DevTools' console once capture is verified.
25
- */
26
- export function ConsoleLogList() {
27
- const {
28
- logs
29
- } = useConsoleLogs();
30
- const renderItem = ({
31
- item
32
- }) => /*#__PURE__*/_jsxs(View, {
33
- style: styles.row,
34
- children: [/*#__PURE__*/_jsx(Text, {
35
- style: styles.time,
36
- children: formatTime(item.timestamp)
37
- }), /*#__PURE__*/_jsx(Text, {
38
- style: [styles.level, {
39
- color: LEVEL_COLOR[item.level]
40
- }],
41
- children: item.level.toUpperCase()
42
- }), /*#__PURE__*/_jsx(Text, {
43
- style: [styles.message, {
44
- color: LEVEL_COLOR[item.level]
45
- }],
46
- numberOfLines: 3,
47
- children: item.message
48
- })]
49
- });
50
- return /*#__PURE__*/_jsxs(View, {
51
- style: styles.container,
52
- children: [/*#__PURE__*/_jsxs(View, {
53
- style: styles.header,
54
- children: [/*#__PURE__*/_jsxs(Text, {
55
- style: styles.headerTitle,
56
- children: ["Console (", logs.length, ")"]
57
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
58
- onPress: () => clearEntries(),
59
- style: styles.clearButton,
60
- children: /*#__PURE__*/_jsx(Text, {
61
- style: styles.clearText,
62
- children: "Clear"
63
- })
64
- })]
65
- }), /*#__PURE__*/_jsx(FlatList, {
66
- data: logs,
67
- keyExtractor: item => String(item.id),
68
- renderItem: renderItem,
69
- ListEmptyComponent: /*#__PURE__*/_jsx(ToolEmptyState, {
70
- testID: "buoy-console-empty"
71
- // printing = "console streaming; logs arriving" — armed and
72
- // waiting for the first line.
73
- ,
74
- otto: "printing",
75
- title: "No console logs captured yet",
76
- message: "console.log, .warn and .error from your app land here as they run."
77
- }),
78
- contentContainerStyle: logs.length === 0 ? styles.emptyContainer : undefined
79
- })]
80
- });
81
- }
82
- const styles = StyleSheet.create({
83
- container: {
84
- flex: 1,
85
- // Transparent so the night sheet's star field shows through.
86
- backgroundColor: "transparent"
87
- },
88
- header: {
89
- flexDirection: "row",
90
- alignItems: "center",
91
- justifyContent: "space-between",
92
- paddingHorizontal: 12,
93
- paddingVertical: 8,
94
- borderBottomWidth: StyleSheet.hairlineWidth,
95
- borderBottomColor: night.color.border
96
- },
97
- headerTitle: {
98
- color: night.color.text,
99
- fontSize: 13,
100
- fontWeight: "600"
101
- },
102
- clearButton: {
103
- paddingHorizontal: 10,
104
- paddingVertical: 4,
105
- borderRadius: 4,
106
- backgroundColor: night.color.surfaceElevated
107
- },
108
- clearText: {
109
- color: night.color.text,
110
- fontSize: 12
111
- },
112
- row: {
113
- flexDirection: "row",
114
- paddingHorizontal: 12,
115
- paddingVertical: 4,
116
- borderBottomWidth: StyleSheet.hairlineWidth,
117
- borderBottomColor: night.color.separator,
118
- gap: 8
119
- },
120
- time: {
121
- color: night.color.textTertiary,
122
- fontSize: 11,
123
- fontVariant: ["tabular-nums"],
124
- minWidth: 86
125
- },
126
- level: {
127
- fontSize: 11,
128
- fontWeight: "700",
129
- minWidth: 44
130
- },
131
- message: {
132
- flex: 1,
133
- fontSize: 12,
134
- fontFamily: monoFont
135
- },
136
- empty: {
137
- color: night.color.textTertiary,
138
- fontSize: 13,
139
- textAlign: "center"
140
- },
141
- emptyContainer: {
142
- flexGrow: 1,
143
- alignItems: "center",
144
- justifyContent: "center"
145
- }
146
- });
147
- //# sourceMappingURL=ConsoleLogList.js.map
1
+ "use strict";import S from"react";import{View as s,Text as i,FlatList as p,TouchableOpacity as f,StyleSheet as c}from"react-native";import{useConsoleLogs as h}from"../hooks/useConsoleLogs";import{night as o,ToolEmptyState as y,monoFont as u}from"@buoy-gg/shared-ui";import{clearEntries as x}from"../store/consoleLogStore";import{jsx as r,jsxs as a}from"react/jsx-runtime";const d={verbose:"#9b9b9b",info:o.color.text,warning:"#e2c08d",error:"#f48771"};function b(l){const n=new Date(l);const e=(m,g=2)=>String(m).padStart(g,"0");return`${e(n.getHours())}:${e(n.getMinutes())}:${e(n.getSeconds())}.${e(n.getMilliseconds(),3)}`}export function ConsoleLogList(){const{logs:l}=h();const n=({item:e})=>a(s,{style:t.row,children:[r(i,{style:t.time,children:b(e.timestamp)}),r(i,{style:[t.level,{color:d[e.level]}],children:e.level.toUpperCase()}),r(i,{style:[t.message,{color:d[e.level]}],numberOfLines:3,children:e.message})]});return a(s,{style:t.container,children:[a(s,{style:t.header,children:[a(i,{style:t.headerTitle,children:["Console (",l.length,")"]}),r(f,{onPress:()=>x(),style:t.clearButton,children:r(i,{style:t.clearText,children:"Clear"})})]}),r(p,{data:l,keyExtractor:e=>String(e.id),renderItem:n,ListEmptyComponent:r(y,{testID:"buoy-console-empty",otto:"printing",title:"No console logs captured yet",message:"console.log, .warn and .error from your app land here as they run."}),contentContainerStyle:l.length===0?t.emptyContainer:void 0})]})}const t=c.create({container:{flex:1,backgroundColor:"transparent"},header:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:8,borderBottomWidth:c.hairlineWidth,borderBottomColor:o.color.border},headerTitle:{color:o.color.text,fontSize:13,fontWeight:"600"},clearButton:{paddingHorizontal:10,paddingVertical:4,borderRadius:4,backgroundColor:o.color.surfaceElevated},clearText:{color:o.color.text,fontSize:12},row:{flexDirection:"row",paddingHorizontal:12,paddingVertical:4,borderBottomWidth:c.hairlineWidth,borderBottomColor:o.color.separator,gap:8},time:{color:o.color.textTertiary,fontSize:11,fontVariant:["tabular-nums"],minWidth:86},level:{fontSize:11,fontWeight:"700",minWidth:44},message:{flex:1,fontSize:12,fontFamily:u},empty:{color:o.color.textTertiary,fontSize:13,textAlign:"center"},emptyContainer:{flexGrow:1,alignItems:"center",justifyContent:"center"}});
@@ -1,44 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * ConsoleModal
5
- *
6
- * Bottom-sheet wrapper for the console, rendered by FloatingDevTools when the
7
- * Console tool is opened. The controls live in the shared ModalHeader
8
- * (`customContent`) — matching Network/Events — and the body is the log list.
9
- */
10
-
11
- import { JsModal } from "@buoy-gg/shared-ui";
12
- import { useConsoleController } from "../devtools/useConsoleController";
13
- import { ConsoleHeader } from "../devtools/ConsoleHeader";
14
- import { ConsoleBody } from "../devtools/ConsoleBody";
15
- import { jsx as _jsx } from "react/jsx-runtime";
16
- export function ConsoleModal({
17
- visible,
18
- onClose,
19
- onBack,
20
- onMinimize,
21
- persistenceKey
22
- }) {
23
- const c = useConsoleController();
24
- return /*#__PURE__*/_jsx(JsModal, {
25
- visible: visible,
26
- onClose: onClose,
27
- onMinimize: onMinimize,
28
- persistenceKey: persistenceKey,
29
- header: {
30
- showToggleButton: true,
31
- customContent: /*#__PURE__*/_jsx(ConsoleHeader, {
32
- c: c,
33
- onBack: onBack
34
- })
35
- },
36
- enablePersistence: true,
37
- initialMode: "bottomSheet",
38
- disableScrollWrapper: true,
39
- children: /*#__PURE__*/_jsx(ConsoleBody, {
40
- c: c
41
- })
42
- });
43
- }
44
- //# sourceMappingURL=ConsoleModal.js.map
1
+ "use strict";import{JsModal as l}from"@buoy-gg/shared-ui";import{useConsoleController as m}from"../devtools/useConsoleController";import{ConsoleHeader as c}from"../devtools/ConsoleHeader";import{ConsoleBody as a}from"../devtools/ConsoleBody";import{jsx as o}from"react/jsx-runtime";export function ConsoleModal({visible:r,onClose:t,onBack:n,onMinimize:s,persistenceKey:i}){const e=m();return o(l,{visible:r,onClose:t,onMinimize:s,persistenceKey:i,header:{showToggleButton:true,customContent:o(c,{c:e,onBack:n})},enablePersistence:true,initialMode:"bottomSheet",disableScrollWrapper:true,children:o(a,{c:e})})}
@@ -1,33 +1 @@
1
- "use strict";
2
-
3
- import { useEffect } from "react";
4
- import { getAccountAccess, subscribeAccountAccess } from "@buoy-gg/shared-ui";
5
- import { installConsoleCapture, uninstallConsoleCapture, initConsolePersistence, clearEntries } from "../store/consoleLogStore";
6
- let owners = 0;
7
- /** Bounded private startup capture; persistence begins only after admission. */
8
- export function ConsoleRoot() {
9
- useEffect(() => {
10
- ++owners;
11
- let active = true;
12
- const reconcile = () => {
13
- if (!active) return;
14
- const access = getAccountAccess();
15
- if (access.status === "locked") {
16
- uninstallConsoleCapture();
17
- clearEntries();
18
- return;
19
- }
20
- installConsoleCapture();
21
- if (access.status === "admitted") void initConsolePersistence();
22
- };
23
- const off = subscribeAccountAccess(reconcile);
24
- reconcile();
25
- return () => {
26
- active = false;
27
- off();
28
- if (--owners === 0) uninstallConsoleCapture();
29
- };
30
- }, []);
31
- return null;
32
- }
33
- //# sourceMappingURL=ConsoleRoot.js.map
1
+ "use strict";import{useEffect as c}from"react";import{getAccountAccess as i,subscribeAccountAccess as u}from"@buoy-gg/shared-ui";import{installConsoleCapture as l,uninstallConsoleCapture as o,initConsolePersistence as f,clearEntries as a}from"../store/consoleLogStore";let r=0;export function ConsoleRoot(){c(()=>{++r;let t=true;const e=()=>{if(!t)return;const s=i();if(s.status==="locked"){o();a();return}l();if(s.status==="admitted")void f()};const n=u(e);e();return()=>{t=false;n();if(--r===0)o()}},[]);return null}
@@ -1,229 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * ConsoleBody — the modal body. Renders the virtualized log list, or (when a
5
- * header action selected it) a back-navigable Log levels / Console settings
6
- * sub-view, mirroring how Network swaps its body to a filter sub-view.
7
- */
8
-
9
- import React, { useCallback, useRef, useSyncExternalStore } from "react";
10
- import { View, Text, FlatList, TouchableOpacity, ScrollView, StyleSheet } from "react-native";
11
- import { night, Check, LOG_LIST_PRESET } from "@buoy-gg/shared-ui";
12
- import { ConsoleMessageRow } from "./ConsoleMessageRow";
13
- import { ALL_LEVELS, DEFAULT_LEVELS, LEVEL_LABEL, LEVEL_ORDER } from "./consoleFilter";
14
- import { getPreserveLog, setPreserveLog, subscribePreserveLog } from "../store/consoleLogStore";
15
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
- export function ConsoleBody({
17
- c
18
- }) {
19
- if (c.view === "filters") return /*#__PURE__*/_jsx(FiltersView, {
20
- c: c
21
- });
22
- return /*#__PURE__*/_jsx(ConsoleList, {
23
- c: c
24
- });
25
- }
26
-
27
- // ─── Log list ────────────────────────────────────────────────────────────────
28
-
29
- function ConsoleList({
30
- c
31
- }) {
32
- const listRef = useRef(null);
33
- const stickToBottom = useRef(true);
34
- const renderItem = useCallback(({
35
- item
36
- }) => /*#__PURE__*/_jsx(ConsoleMessageRow, {
37
- row: item,
38
- showTimestamps: c.showTimestamps,
39
- onToggleGroup: c.onToggleGroup,
40
- onToggleCluster: c.onToggleCluster
41
- }), [c.showTimestamps, c.onToggleGroup, c.onToggleCluster]);
42
- return /*#__PURE__*/_jsx(FlatList, {
43
- ref: listRef,
44
- data: c.rows,
45
- keyExtractor: item => item.key,
46
- renderItem: renderItem,
47
- style: styles.list,
48
- ...LOG_LIST_PRESET,
49
- onContentSizeChange: () => {
50
- if (stickToBottom.current) listRef.current?.scrollToEnd({
51
- animated: false
52
- });
53
- },
54
- onScroll: e => {
55
- const {
56
- contentOffset,
57
- contentSize,
58
- layoutMeasurement
59
- } = e.nativeEvent;
60
- const distanceFromBottom = contentSize.height - (contentOffset.y + layoutMeasurement.height);
61
- stickToBottom.current = distanceFromBottom < 40;
62
- },
63
- scrollEventThrottle: 100
64
- });
65
- }
66
-
67
- // ─── Sub-views ───────────────────────────────────────────────────────────────
68
-
69
- function CheckRow({
70
- on,
71
- label,
72
- subtext,
73
- onPress
74
- }) {
75
- return /*#__PURE__*/_jsxs(TouchableOpacity, {
76
- style: styles.row,
77
- onPress: onPress,
78
- activeOpacity: 0.7,
79
- children: [/*#__PURE__*/_jsx(View, {
80
- style: [styles.checkbox, on && styles.checkboxOn],
81
- children: on ? /*#__PURE__*/_jsx(Check, {
82
- size: 12,
83
- color: night.color.onAccent,
84
- strokeWidth: 3
85
- }) : null
86
- }), /*#__PURE__*/_jsxs(View, {
87
- style: styles.rowTextCol,
88
- children: [/*#__PURE__*/_jsx(Text, {
89
- style: styles.rowLabel,
90
- children: label
91
- }), subtext ? /*#__PURE__*/_jsx(Text, {
92
- style: styles.rowSubtext,
93
- children: subtext
94
- }) : null]
95
- })]
96
- });
97
- }
98
- function SectionLabel({
99
- text
100
- }) {
101
- return /*#__PURE__*/_jsx(Text, {
102
- style: styles.sectionLabel,
103
- children: text
104
- });
105
- }
106
- function FiltersView({
107
- c
108
- }) {
109
- const preserveLog = useSyncExternalStore(subscribePreserveLog, getPreserveLog, getPreserveLog);
110
- const toggle = level => c.setLevelsMask({
111
- ...c.levelsMask,
112
- [level]: !c.levelsMask[level]
113
- });
114
- return /*#__PURE__*/_jsxs(ScrollView, {
115
- style: styles.subView,
116
- contentContainerStyle: styles.subViewContent,
117
- children: [/*#__PURE__*/_jsx(SectionLabel, {
118
- text: "Log levels"
119
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
120
- style: styles.presetRow,
121
- onPress: () => c.setLevelsMask({
122
- ...DEFAULT_LEVELS
123
- }),
124
- children: /*#__PURE__*/_jsx(Text, {
125
- style: styles.presetText,
126
- children: "Default (hide verbose)"
127
- })
128
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
129
- style: styles.presetRow,
130
- onPress: () => c.setLevelsMask({
131
- ...ALL_LEVELS
132
- }),
133
- children: /*#__PURE__*/_jsx(Text, {
134
- style: styles.presetText,
135
- children: "All levels"
136
- })
137
- }), LEVEL_ORDER.map(level => /*#__PURE__*/_jsx(CheckRow, {
138
- on: c.levelsMask[level],
139
- label: LEVEL_LABEL[level],
140
- onPress: () => toggle(level)
141
- }, level)), /*#__PURE__*/_jsx(View, {
142
- style: styles.divider
143
- }), /*#__PURE__*/_jsx(SectionLabel, {
144
- text: "Settings"
145
- }), /*#__PURE__*/_jsx(CheckRow, {
146
- on: c.showTimestamps,
147
- label: "Show timestamps",
148
- onPress: () => c.setShowTimestamps(s => !s)
149
- }), /*#__PURE__*/_jsx(CheckRow, {
150
- on: preserveLog,
151
- label: "Preserve log",
152
- subtext: "Do not clear log on reload",
153
- onPress: () => setPreserveLog(!preserveLog)
154
- })]
155
- });
156
- }
157
- const styles = StyleSheet.create({
158
- list: {
159
- flex: 1,
160
- // Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
161
- backgroundColor: "transparent"
162
- },
163
- subView: {
164
- flex: 1,
165
- // Transparent so the night sheet's star field shows through.
166
- backgroundColor: "transparent"
167
- },
168
- subViewContent: {
169
- padding: 12
170
- },
171
- sectionLabel: {
172
- color: night.color.textTertiary,
173
- fontSize: 11,
174
- textTransform: "uppercase",
175
- letterSpacing: 0.5,
176
- marginTop: 4,
177
- marginBottom: 4,
178
- paddingHorizontal: 8
179
- },
180
- presetRow: {
181
- paddingVertical: 10,
182
- paddingHorizontal: 8
183
- },
184
- presetText: {
185
- color: night.color.accent,
186
- fontSize: 14,
187
- fontWeight: "600"
188
- },
189
- divider: {
190
- height: StyleSheet.hairlineWidth,
191
- backgroundColor: night.color.border,
192
- marginVertical: 6
193
- },
194
- row: {
195
- flexDirection: "row",
196
- alignItems: "center",
197
- paddingVertical: 10,
198
- paddingHorizontal: 8,
199
- gap: 12
200
- },
201
- rowTextCol: {
202
- flexDirection: "column",
203
- flex: 1
204
- },
205
- rowLabel: {
206
- color: night.color.text,
207
- fontSize: 14
208
- },
209
- rowSubtext: {
210
- color: night.color.textTertiary,
211
- fontSize: 12,
212
- marginTop: 1
213
- },
214
- checkbox: {
215
- width: 18,
216
- height: 18,
217
- borderRadius: 4,
218
- borderWidth: 1,
219
- borderColor: night.color.fillTertiary,
220
- alignItems: "center",
221
- justifyContent: "center"
222
- },
223
- // Solid accent (not accentSoft) so the onAccent check glyph stays legible.
224
- checkboxOn: {
225
- backgroundColor: night.color.accent,
226
- borderColor: night.color.accent
227
- }
228
- });
229
- //# sourceMappingURL=ConsoleBody.js.map
1
+ "use strict";import A,{useCallback as T,useRef as h,useSyncExternalStore as y}from"react";import{View as c,Text as a,FlatList as S,TouchableOpacity as d,ScrollView as C,StyleSheet as m}from"react-native";import{night as n,Check as k,LOG_LIST_PRESET as E}from"@buoy-gg/shared-ui";import{ConsoleMessageRow as v}from"./ConsoleMessageRow";import{ALL_LEVELS as V,DEFAULT_LEVELS as R,LEVEL_LABEL as P,LEVEL_ORDER as z}from"./consoleFilter";import{getPreserveLog as p,setPreserveLog as M,subscribePreserveLog as _}from"../store/consoleLogStore";import{jsx as o,jsxs as g}from"react/jsx-runtime";export function ConsoleBody({c:e}){if(e.view==="filters")return o(D,{c:e});return o(O,{c:e})}function O({c:e}){const s=h(null);const l=h(true);const r=T(({item:i})=>o(v,{row:i,showTimestamps:e.showTimestamps,onToggleGroup:e.onToggleGroup,onToggleCluster:e.onToggleCluster}),[e.showTimestamps,e.onToggleGroup,e.onToggleCluster]);return o(S,{ref:s,data:e.rows,keyExtractor:i=>i.key,renderItem:r,style:t.list,...E,onContentSizeChange:()=>{if(l.current)s.current?.scrollToEnd({animated:false})},onScroll:i=>{const{contentOffset:b,contentSize:w,layoutMeasurement:x}=i.nativeEvent;const L=w.height-(b.y+x.height);l.current=L<40},scrollEventThrottle:100})}function u({on:e,label:s,subtext:l,onPress:r}){return g(d,{style:t.row,onPress:r,activeOpacity:.7,children:[o(c,{style:[t.checkbox,e&&t.checkboxOn],children:e?o(k,{size:12,color:n.color.onAccent,strokeWidth:3}):null}),g(c,{style:t.rowTextCol,children:[o(a,{style:t.rowLabel,children:s}),l?o(a,{style:t.rowSubtext,children:l}):null]})]})}function f({text:e}){return o(a,{style:t.sectionLabel,children:e})}function D({c:e}){const s=y(_,p,p);const l=r=>e.setLevelsMask({...e.levelsMask,[r]:!e.levelsMask[r]});return g(C,{style:t.subView,contentContainerStyle:t.subViewContent,children:[o(f,{text:"Log levels"}),o(d,{style:t.presetRow,onPress:()=>e.setLevelsMask({...R}),children:o(a,{style:t.presetText,children:"Default (hide verbose)"})}),o(d,{style:t.presetRow,onPress:()=>e.setLevelsMask({...V}),children:o(a,{style:t.presetText,children:"All levels"})}),z.map(r=>o(u,{on:e.levelsMask[r],label:P[r],onPress:()=>l(r)},r)),o(c,{style:t.divider}),o(f,{text:"Settings"}),o(u,{on:e.showTimestamps,label:"Show timestamps",onPress:()=>e.setShowTimestamps(r=>!r)}),o(u,{on:s,label:"Preserve log",subtext:"Do not clear log on reload",onPress:()=>M(!s)})]})}const t=m.create({list:{flex:1,backgroundColor:"transparent"},subView:{flex:1,backgroundColor:"transparent"},subViewContent:{padding:12},sectionLabel:{color:n.color.textTertiary,fontSize:11,textTransform:"uppercase",letterSpacing:.5,marginTop:4,marginBottom:4,paddingHorizontal:8},presetRow:{paddingVertical:10,paddingHorizontal:8},presetText:{color:n.color.accent,fontSize:14,fontWeight:"600"},divider:{height:m.hairlineWidth,backgroundColor:n.color.border,marginVertical:6},row:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:8,gap:12},rowTextCol:{flexDirection:"column",flex:1},rowLabel:{color:n.color.text,fontSize:14},rowSubtext:{color:n.color.textTertiary,fontSize:12,marginTop:1},checkbox:{width:18,height:18,borderRadius:4,borderWidth:1,borderColor:n.color.fillTertiary,alignItems:"center",justifyContent:"center"},checkboxOn:{backgroundColor:n.color.accent,borderColor:n.color.accent}});