@liquidmetal-ai/raindrop 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,205 @@
1
+ import { timestampMs } from '@bufbuild/protobuf/wkt';
2
+ export function formatLogAttribute(key, value, displayValue) {
3
+ // Format common attributes nicely
4
+ if (key === 'http.status') {
5
+ const statusCode = parseInt(value);
6
+ const statusEmoji = statusCode >= 200 && statusCode < 300 ? '✅' : statusCode >= 400 ? '❌' : '⚠️';
7
+ return `${key}: ${statusEmoji} ${value}`;
8
+ }
9
+ else if (key === 'http.method' || key === 'http.url') {
10
+ return `${key}: ${value}`;
11
+ }
12
+ else if (key === 'query') {
13
+ // SQL query formatting
14
+ return `🗄️ SQL Query: ${value}`;
15
+ }
16
+ else if (key === 'rows_read') {
17
+ return `📊 Rows Read: ${value}`;
18
+ }
19
+ else if (key === 'rows_written') {
20
+ return `✍️ Rows Written: ${value}`;
21
+ }
22
+ else if (key === 'db') {
23
+ return `🏦 Database: ${value}`;
24
+ }
25
+ else if (key === 'error') {
26
+ if (value && value !== 'undefined') {
27
+ return `❌ Error: ${value}`;
28
+ }
29
+ return null; // Don't display undefined errors
30
+ }
31
+ else if (key === 'fields' || key === 'meta') {
32
+ // Special handling for structured data - show key metrics inline
33
+ try {
34
+ const parsed = JSON.parse(displayValue);
35
+ if (key === 'meta' && parsed) {
36
+ // Extract key database metrics
37
+ const metrics = [];
38
+ if (parsed.duration)
39
+ metrics.push(`${parsed.duration}ms`);
40
+ if (parsed.rows_read)
41
+ metrics.push(`${parsed.rows_read} rows read`);
42
+ if (parsed.rows_written && parsed.rows_written > 0)
43
+ metrics.push(`${parsed.rows_written} rows written`);
44
+ if (parsed.served_by_region)
45
+ metrics.push(`${parsed.served_by_region}`);
46
+ if (parsed.size_after)
47
+ metrics.push(`DB: ${(parsed.size_after / 1024).toFixed(1)}KB`);
48
+ if (metrics.length > 0) {
49
+ return `📊 ${key}: ${metrics.join(', ')}`;
50
+ }
51
+ else {
52
+ return `${key}: ${JSON.stringify(parsed, (_, v) => typeof v === 'bigint' ? v.toString() : v)}`;
53
+ }
54
+ }
55
+ else {
56
+ // For fields or other structured data, show condensed
57
+ return `${key}: ${JSON.stringify(parsed, (_, v) => typeof v === 'bigint' ? v.toString() : v)}`;
58
+ }
59
+ }
60
+ catch {
61
+ return `${key}: ${displayValue}`;
62
+ }
63
+ }
64
+ else {
65
+ return `${key}: ${displayValue}`;
66
+ }
67
+ }
68
+ export function displayEventAttributes(event, logger, indentLevel = ' ') {
69
+ // Show attributes with better formatting
70
+ if (event.attributes && Object.keys(event.attributes).length > 0) {
71
+ Object.entries(event.attributes).forEach(([key, value]) => {
72
+ if (value !== undefined && value !== null) {
73
+ // Parse JSON strings and format objects properly
74
+ let displayValue = value;
75
+ try {
76
+ const parsed = JSON.parse(value);
77
+ if (typeof parsed === 'object' && parsed !== null) {
78
+ displayValue = JSON.stringify(parsed, (_, v) => {
79
+ if (typeof v === 'bigint') {
80
+ return v.toString();
81
+ }
82
+ return v;
83
+ }, 2);
84
+ }
85
+ }
86
+ catch {
87
+ // Not JSON, use as is
88
+ }
89
+ const formattedAttribute = formatLogAttribute(key, value, displayValue);
90
+ if (formattedAttribute) {
91
+ logger.log(`${indentLevel}${formattedAttribute}`);
92
+ }
93
+ }
94
+ });
95
+ }
96
+ }
97
+ export function displayTraceGroupedEvents(events, logger) {
98
+ // Group events by trace ID
99
+ const eventsByTrace = new Map();
100
+ events.forEach((event) => {
101
+ const traceId = event.trace?.eventId || 'unknown';
102
+ if (!eventsByTrace.has(traceId)) {
103
+ eventsByTrace.set(traceId, []);
104
+ }
105
+ const traceEvents = eventsByTrace.get(traceId);
106
+ if (traceEvents) {
107
+ traceEvents.push(event);
108
+ }
109
+ });
110
+ // Display each trace group
111
+ for (const [traceId, traceEvents] of eventsByTrace) {
112
+ if (traceEvents.length === 0)
113
+ continue;
114
+ // Sort events by event order (execution sequence) within trace
115
+ // If eventOrder is not available, fall back to start time
116
+ traceEvents.sort((a, b) => {
117
+ // First try to sort by eventOrder if available
118
+ if (a.eventOrder !== undefined && b.eventOrder !== undefined) {
119
+ return a.eventOrder - b.eventOrder;
120
+ }
121
+ // Fall back to start time if eventOrder is not available
122
+ const aTime = a.trace?.startTime ? timestampMs(a.trace.startTime) : 0;
123
+ const bTime = b.trace?.startTime ? timestampMs(b.trace.startTime) : 0;
124
+ return aTime - bTime;
125
+ });
126
+ const firstEvent = traceEvents[0];
127
+ const lastEvent = traceEvents[traceEvents.length - 1];
128
+ // Calculate trace duration
129
+ const startTime = firstEvent.trace?.startTime ? timestampMs(firstEvent.trace.startTime) : 0;
130
+ const endTime = lastEvent.trace?.endTime ? timestampMs(lastEvent.trace.endTime) :
131
+ (lastEvent.trace?.startTime ? timestampMs(lastEvent.trace.startTime) : 0);
132
+ const traceDuration = endTime > startTime ? ` (${endTime - startTime}ms total)` : '';
133
+ const timestamp = firstEvent.trace?.startTime
134
+ ? new Date(timestampMs(firstEvent.trace.startTime)).toLocaleString()
135
+ : 'Unknown time';
136
+ // Show trace header
137
+ logger.log(`[${timestamp}] 🔗 Trace: ${traceId}${traceDuration}`);
138
+ // Show context info once per trace
139
+ if (firstEvent.organization?.id || firstEvent.application?.name) {
140
+ const contextParts = [];
141
+ if (firstEvent.organization?.id)
142
+ contextParts.push(`Org: ${firstEvent.organization.id}`);
143
+ if (firstEvent.application?.name)
144
+ contextParts.push(`App: ${firstEvent.application.name}`);
145
+ if (firstEvent.application?.version?.id)
146
+ contextParts.push(`v${firstEvent.application.version.id}`);
147
+ if (firstEvent.script?.name)
148
+ contextParts.push(`Script: ${firstEvent.script.name}`);
149
+ logger.log(` ${contextParts.join(', ')}`);
150
+ }
151
+ // Display each event in the trace
152
+ traceEvents.forEach((event, index) => {
153
+ const eventName = event.name || 'Event';
154
+ const status = event.status || 'ok';
155
+ const statusEmoji = status === 'error' ? '❌' : '✅';
156
+ // Calculate individual event duration
157
+ let duration = '';
158
+ if (event.trace?.endTime && event.trace?.startTime) {
159
+ const durationMs = timestampMs(event.trace.endTime) - timestampMs(event.trace.startTime);
160
+ duration = ` (${durationMs}ms)`;
161
+ }
162
+ logger.log(` ${index + 1}. ${statusEmoji} ${eventName}${duration}`);
163
+ // Show attributes with proper indentation for grouped events
164
+ displayEventAttributes(event, logger, ' ');
165
+ });
166
+ logger.log(''); // Empty line between traces
167
+ }
168
+ }
169
+ export function displayIndividualEvents(events, logger) {
170
+ events.forEach((event) => {
171
+ // Format timestamp from trace info
172
+ const timestamp = event.trace?.startTime
173
+ ? new Date(timestampMs(event.trace.startTime)).toLocaleString()
174
+ : 'Unknown time';
175
+ const eventName = event.name || 'Event';
176
+ const traceId = event.trace?.eventId || 'N/A';
177
+ const status = event.status || 'ok';
178
+ // Calculate duration if end time is available
179
+ let duration = '';
180
+ if (event.trace?.endTime && event.trace?.startTime) {
181
+ const durationMs = timestampMs(event.trace.endTime) - timestampMs(event.trace.startTime);
182
+ duration = ` (${durationMs}ms)`;
183
+ }
184
+ // Format status with emoji
185
+ const statusEmoji = status === 'error' ? '❌' : '✅';
186
+ logger.log(`[${timestamp}] ${statusEmoji} ${eventName}${duration}`);
187
+ logger.log(` Trace: ${traceId}`);
188
+ // Show attributes with proper indentation for individual events
189
+ displayEventAttributes(event, logger, ' ');
190
+ // Show organization/application context if present
191
+ if (event.organization?.id) {
192
+ logger.log(` Organization: ${event.organization.id}`);
193
+ }
194
+ if (event.application?.name) {
195
+ logger.log(` Application: ${event.application.name}`);
196
+ if (event.application.version?.id) {
197
+ logger.log(` Version: ${event.application.version.id}`);
198
+ }
199
+ }
200
+ if (event.script?.name) {
201
+ logger.log(` Script: ${event.script.name}`);
202
+ }
203
+ logger.log(''); // Empty line for readability
204
+ });
205
+ }
@@ -1 +1 @@
1
- {"root":["../src/base-command.ts","../src/build.test.ts","../src/build.ts","../src/codegen.test.ts","../src/codegen.ts","../src/config.test.ts","../src/config.ts","../src/deploy.ts","../src/index.test.ts","../src/index.ts","../src/status.ts","../src/strict-client.ts","../src/trace.ts","../src/commands/tail.ts","../src/commands/annotation/get.ts","../src/commands/annotation/list.ts","../src/commands/annotation/put.ts","../src/commands/auth/list.ts","../src/commands/auth/login.ts","../src/commands/auth/logout.ts","../src/commands/auth/select.ts","../src/commands/bucket/create-credential.ts","../src/commands/bucket/delete-credential.ts","../src/commands/bucket/get-credential.ts","../src/commands/bucket/list-credentials.ts","../src/commands/build/branch.ts","../src/commands/build/checkout.ts","../src/commands/build/clone.ts","../src/commands/build/delete.ts","../src/commands/build/deploy.ts","../src/commands/build/find.ts","../src/commands/build/generate.ts","../src/commands/build/init.ts","../src/commands/build/list.ts","../src/commands/build/sandbox.ts","../src/commands/build/start.ts","../src/commands/build/status.ts","../src/commands/build/stop.ts","../src/commands/build/unsandbox.ts","../src/commands/build/upload.ts","../src/commands/build/validate.ts","../src/commands/build/env/get.ts","../src/commands/build/env/set.ts","../src/commands/build/tools/check.ts","../src/commands/build/tools/fmt.ts","../src/commands/object/delete.ts","../src/commands/object/get.ts","../src/commands/object/list.ts","../src/commands/object/put.ts","../src/commands/query/chunk-search.ts","../src/commands/query/document.ts","../src/commands/query/events.ts","../src/commands/query/search.ts"],"version":"5.8.3"}
1
+ {"root":["../src/base-command.ts","../src/build.test.ts","../src/build.ts","../src/codegen.test.ts","../src/codegen.ts","../src/config.test.ts","../src/config.ts","../src/deploy.ts","../src/index.test.ts","../src/index.ts","../src/log-helpers.ts","../src/status.ts","../src/strict-client.ts","../src/trace.ts","../src/commands/tail.ts","../src/commands/annotation/get.ts","../src/commands/annotation/list.ts","../src/commands/annotation/put.ts","../src/commands/auth/list.ts","../src/commands/auth/login.ts","../src/commands/auth/logout.ts","../src/commands/auth/select.ts","../src/commands/bucket/create-credential.ts","../src/commands/bucket/delete-credential.ts","../src/commands/bucket/get-credential.ts","../src/commands/bucket/list-credentials.ts","../src/commands/build/branch.ts","../src/commands/build/checkout.ts","../src/commands/build/clone.ts","../src/commands/build/delete.ts","../src/commands/build/deploy.ts","../src/commands/build/find.ts","../src/commands/build/generate.ts","../src/commands/build/init.ts","../src/commands/build/list.ts","../src/commands/build/sandbox.ts","../src/commands/build/start.ts","../src/commands/build/status.ts","../src/commands/build/stop.ts","../src/commands/build/unsandbox.ts","../src/commands/build/upload.ts","../src/commands/build/validate.ts","../src/commands/build/env/get.ts","../src/commands/build/env/set.ts","../src/commands/build/tools/check.ts","../src/commands/build/tools/fmt.ts","../src/commands/logs/query.ts","../src/commands/logs/tail.ts","../src/commands/object/delete.ts","../src/commands/object/get.ts","../src/commands/object/list.ts","../src/commands/object/put.ts","../src/commands/query/chunk-search.ts","../src/commands/query/document.ts","../src/commands/query/events.ts","../src/commands/query/search.ts"],"version":"5.8.3"}