tidewave 0.5.4 → 0.6.0

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.
@@ -28,23 +28,31 @@ var __export = (target, all) => {
28
28
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
29
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
30
 
31
- // src/logger/circular-buffer.ts
32
- class CircularBuffer {
33
- buffer;
34
- maxSize;
35
- writeIndex = 0;
36
- count = 0;
37
- constructor(maxSize = 1024) {
38
- this.buffer = new Array(maxSize);
39
- this.maxSize = maxSize;
31
+ // src/logger/tidewave-logger.ts
32
+ import { appendFile, readFile } from "fs/promises";
33
+ import * as path from "path";
34
+ import * as os from "os";
35
+ import * as crypto from "crypto";
36
+
37
+ class TidewaveLogger {
38
+ logFilePath;
39
+ constructor() {
40
+ const cwd = process.cwd();
41
+ const digest = crypto.createHash("md5").update(cwd).digest("hex").slice(0, 16);
42
+ const tempDir = os.tmpdir();
43
+ this.logFilePath = path.join(tempDir, `${digest}.tidewave.ndjson`);
40
44
  }
41
- addLog(log) {
42
- this.buffer[this.writeIndex] = log;
43
- this.writeIndex = (this.writeIndex + 1) % this.maxSize;
44
- this.count = Math.min(this.count + 1, this.maxSize);
45
+ async addLog(log) {
46
+ const line = JSON.stringify(log) + `
47
+ `;
48
+ try {
49
+ await appendFile(this.logFilePath, line, "utf8");
50
+ } catch (error) {
51
+ console.log("[Tidewave] failed to write to log file, error:", error);
52
+ }
45
53
  }
46
- getLogs(options) {
47
- let logs = this.getAllLogs();
54
+ async getLogs(options) {
55
+ let logs = await this.getAllLogs();
48
56
  if (options?.level) {
49
57
  const level = options.level.toUpperCase();
50
58
  logs = logs.filter((log) => log.severityText === level);
@@ -62,34 +70,100 @@ class CircularBuffer {
62
70
  }
63
71
  return logs;
64
72
  }
65
- getAllLogs() {
66
- if (this.count < this.maxSize) {
67
- return this.buffer.slice(0, this.count).filter(Boolean);
73
+ async getAllLogs() {
74
+ try {
75
+ const content = await readFile(this.logFilePath, "utf8");
76
+ return content.split(`
77
+ `).map((line) => {
78
+ try {
79
+ return JSON.parse(line);
80
+ } catch {
81
+ return null;
82
+ }
83
+ }).filter((log) => log !== null);
84
+ } catch (error) {
85
+ console.log("[Tidewave] failed to read from log file, error:", error);
86
+ return [];
68
87
  }
69
- return [...this.buffer.slice(this.writeIndex), ...this.buffer.slice(0, this.writeIndex)].filter(Boolean);
70
88
  }
71
- getStats() {
72
- return {
73
- totalLogs: this.count,
74
- bufferSize: this.maxSize,
75
- bufferUsage: Math.min(this.count / this.maxSize * 100, 100).toFixed(1) + "%"
76
- };
89
+ }
90
+ var tidewaveLogger;
91
+ var init_tidewave_logger = __esm(() => {
92
+ tidewaveLogger = new TidewaveLogger;
93
+ });
94
+
95
+ // src/logger/console-patch.ts
96
+ var exports_console_patch = {};
97
+ __export(exports_console_patch, {
98
+ patchConsole: () => patchConsole
99
+ });
100
+ function stripAnsiCodes(text) {
101
+ return text.replace(ANSI_REGEX, "");
102
+ }
103
+ function patchConsole() {
104
+ const isBrowser = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
105
+ if (isBrowser) {
106
+ return;
77
107
  }
78
- clear() {
79
- this.buffer = new Array(this.maxSize);
80
- this.writeIndex = 0;
81
- this.count = 0;
108
+ if (globalThis.__TIDEWAVE_CONSOLE_PATCHED__) {
109
+ return;
82
110
  }
111
+ const severityMap = {
112
+ log: "INFO",
113
+ info: "INFO",
114
+ warn: "WARN",
115
+ error: "ERROR",
116
+ debug: "DEBUG"
117
+ };
118
+ Object.entries(severityMap).forEach(([method, severity]) => {
119
+ const original = console[method].bind(console);
120
+ console[method] = (...args) => {
121
+ try {
122
+ const body = args.map((arg) => {
123
+ if (typeof arg === "string")
124
+ return arg;
125
+ if (arg instanceof Error) {
126
+ return String(arg.stack);
127
+ }
128
+ if (typeof arg === "object") {
129
+ try {
130
+ return JSON.stringify(arg);
131
+ } catch {
132
+ return String(arg);
133
+ }
134
+ }
135
+ return String(arg);
136
+ }).map(stripAnsiCodes).join(" ");
137
+ const isAllWhitespace = body.match(/^\s+$/);
138
+ if (!isAllWhitespace) {
139
+ tidewaveLogger.addLog({
140
+ timestamp: new Date().toISOString(),
141
+ severityText: severity,
142
+ body,
143
+ attributes: {
144
+ "log.origin": "console",
145
+ "log.method": method
146
+ }
147
+ });
148
+ }
149
+ } catch {}
150
+ original(...args);
151
+ };
152
+ });
153
+ globalThis.__TIDEWAVE_CONSOLE_PATCHED__ = true;
83
154
  }
84
- var circularBuffer;
85
- var init_circular_buffer = __esm(() => {
86
- if (!globalThis.__tidewaveCircularBuffer) {
87
- globalThis.__tidewaveCircularBuffer = new CircularBuffer(1024);
88
- }
89
- circularBuffer = globalThis.__tidewaveCircularBuffer;
155
+ var ANSI_REGEX;
156
+ var init_console_patch = __esm(() => {
157
+ init_tidewave_logger();
158
+ ANSI_REGEX = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
90
159
  });
91
160
 
161
+ // src/next-js/instrumentation.ts
162
+ init_console_patch();
163
+
92
164
  // src/logger/tidewave-span-processor.ts
165
+ init_tidewave_logger();
166
+
93
167
  class TidewaveSpanProcessor {
94
168
  onStart(_span, _parentContext) {}
95
169
  onEnd(span) {
@@ -108,8 +182,8 @@ class TidewaveSpanProcessor {
108
182
  const httpUrl = span.attributes["http.url"];
109
183
  const httpTarget = span.attributes["http.target"];
110
184
  const httpStatusCode = span.attributes["http.status_code"];
111
- const path = route || httpTarget || httpUrl || "unknown";
112
- if (typeof path === "string" && path.startsWith("/tidewave")) {
185
+ const path2 = route || httpTarget || httpUrl || "unknown";
186
+ if (typeof path2 === "string" && path2.startsWith("/tidewave")) {
113
187
  return;
114
188
  }
115
189
  const durationMs = this.calculateDuration(span);
@@ -118,7 +192,7 @@ class TidewaveSpanProcessor {
118
192
  if (spanType === "BaseServer.handleRequest") {
119
193
  const method = httpMethod || "UNKNOWN";
120
194
  const status = httpStatusCode || "unknown";
121
- message = `${method} ${path} ${status} ${durationMs.toFixed(2)}ms`;
195
+ message = `${method} ${path2} ${status} ${durationMs.toFixed(2)}ms`;
122
196
  if (typeof httpStatusCode === "number") {
123
197
  if (httpStatusCode >= 500)
124
198
  severity = "ERROR";
@@ -130,7 +204,7 @@ class TidewaveSpanProcessor {
130
204
  } else if (spanType === "AppRouteRouteHandlers.runHandler") {
131
205
  message = `API route: ${route || "unknown"} (${durationMs.toFixed(2)}ms)`;
132
206
  }
133
- circularBuffer.addLog({
207
+ tidewaveLogger.addLog({
134
208
  timestamp: new Date(span.endTime[0] * 1000 + span.endTime[1] / 1e6).toISOString(),
135
209
  severityText: severity,
136
210
  body: message,
@@ -155,100 +229,27 @@ class TidewaveSpanProcessor {
155
229
  async forceFlush() {}
156
230
  async shutdown() {}
157
231
  }
158
- var init_tidewave_span_processor = __esm(() => {
159
- init_circular_buffer();
160
- });
161
-
162
232
  // src/logger/tidewave-log-record-processor.ts
233
+ init_tidewave_logger();
234
+
163
235
  class TidewaveLogRecordProcessor {
164
236
  onEmit(logRecord, _context) {
165
237
  try {
166
238
  const body = String(logRecord.body || "");
167
- circularBuffer.addLog({
239
+ tidewaveLogger.addLog({
168
240
  timestamp: new Date(logRecord.hrTime[0] * 1000 + logRecord.hrTime[1] / 1e6).toISOString(),
169
241
  severityText: logRecord.severityText || "INFO",
170
242
  body,
171
- attributes: logRecord.attributes,
172
- resource: logRecord.resource?.attributes
243
+ attributes: logRecord.attributes
173
244
  });
174
245
  } catch (_error) {}
175
246
  }
176
247
  async forceFlush() {}
177
248
  async shutdown() {}
178
249
  }
179
- var init_tidewave_log_record_processor = __esm(() => {
180
- init_circular_buffer();
181
- });
182
-
183
- // src/logger/instrumentation.ts
184
- var exports_instrumentation = {};
185
- __export(exports_instrumentation, {
186
- TidewaveSpanProcessor: () => TidewaveSpanProcessor,
187
- TidewaveLogRecordProcessor: () => TidewaveLogRecordProcessor
188
- });
189
- function stripAnsiCodes(text) {
190
- return text.replace(ANSI_REGEX, "");
191
- }
192
- function patchConsole() {
193
- const isBrowser = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
194
- if (isBrowser) {
195
- return;
196
- }
197
- if (globalThis.__TIDEWAVE_CONSOLE_PATCHED__) {
198
- return;
199
- }
200
- const severityMap = {
201
- log: "INFO",
202
- info: "INFO",
203
- warn: "WARN",
204
- error: "ERROR",
205
- debug: "DEBUG"
206
- };
207
- Object.entries(severityMap).forEach(([method, severity]) => {
208
- const original = console[method].bind(console);
209
- console[method] = (...args) => {
210
- try {
211
- const body = args.map((arg) => {
212
- if (typeof arg === "string")
213
- return arg;
214
- if (arg instanceof Error) {
215
- return String(arg.stack);
216
- }
217
- if (typeof arg === "object") {
218
- try {
219
- return JSON.stringify(arg);
220
- } catch {
221
- return String(arg);
222
- }
223
- }
224
- return String(arg);
225
- }).map(stripAnsiCodes).join(" ");
226
- circularBuffer.addLog({
227
- timestamp: new Date().toISOString(),
228
- severityText: severity,
229
- body,
230
- attributes: {
231
- "log.origin": "console",
232
- "log.method": method
233
- }
234
- });
235
- } catch {}
236
- original(...args);
237
- };
238
- });
239
- globalThis.__TIDEWAVE_CONSOLE_PATCHED__ = true;
240
- }
241
- var ANSI_REGEX;
242
- var init_instrumentation = __esm(() => {
243
- init_circular_buffer();
244
- init_tidewave_span_processor();
245
- init_tidewave_log_record_processor();
246
- ANSI_REGEX = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
247
- patchConsole();
248
- });
249
250
 
250
251
  // src/next-js/instrumentation.ts
251
- init_instrumentation();
252
+ patchConsole();
252
253
  export {
253
254
  TidewaveSpanProcessor,
254
255
  TidewaveLogRecordProcessor
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,163 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
+
31
+ // src/logger/tidewave-logger.ts
32
+ import { appendFile, readFile } from "fs/promises";
33
+ import * as path from "path";
34
+ import * as os from "os";
35
+ import * as crypto from "crypto";
36
+
37
+ class TidewaveLogger {
38
+ logFilePath;
39
+ constructor() {
40
+ const cwd = process.cwd();
41
+ const digest = crypto.createHash("md5").update(cwd).digest("hex").slice(0, 16);
42
+ const tempDir = os.tmpdir();
43
+ this.logFilePath = path.join(tempDir, `${digest}.tidewave.ndjson`);
44
+ }
45
+ async addLog(log) {
46
+ const line = JSON.stringify(log) + `
47
+ `;
48
+ try {
49
+ await appendFile(this.logFilePath, line, "utf8");
50
+ } catch (error) {
51
+ console.log("[Tidewave] failed to write to log file, error:", error);
52
+ }
53
+ }
54
+ async getLogs(options) {
55
+ let logs = await this.getAllLogs();
56
+ if (options?.level) {
57
+ const level = options.level.toUpperCase();
58
+ logs = logs.filter((log) => log.severityText === level);
59
+ }
60
+ if (options?.since) {
61
+ const sinceDate = new Date(options.since);
62
+ logs = logs.filter((log) => new Date(log.timestamp) >= sinceDate);
63
+ }
64
+ if (options?.grep) {
65
+ const regex = new RegExp(options.grep, "i");
66
+ logs = logs.filter((log) => regex.test(log.body) || regex.test(JSON.stringify(log.attributes)));
67
+ }
68
+ if (options?.tail) {
69
+ logs = logs.slice(-options.tail);
70
+ }
71
+ return logs;
72
+ }
73
+ async getAllLogs() {
74
+ try {
75
+ const content = await readFile(this.logFilePath, "utf8");
76
+ return content.split(`
77
+ `).map((line) => {
78
+ try {
79
+ return JSON.parse(line);
80
+ } catch {
81
+ return null;
82
+ }
83
+ }).filter((log) => log !== null);
84
+ } catch (error) {
85
+ console.log("[Tidewave] failed to read from log file, error:", error);
86
+ return [];
87
+ }
88
+ }
89
+ }
90
+ var tidewaveLogger;
91
+ var init_tidewave_logger = __esm(() => {
92
+ tidewaveLogger = new TidewaveLogger;
93
+ });
94
+
95
+ // src/logger/console-patch.ts
96
+ var exports_console_patch = {};
97
+ __export(exports_console_patch, {
98
+ patchConsole: () => patchConsole
99
+ });
100
+ function stripAnsiCodes(text) {
101
+ return text.replace(ANSI_REGEX, "");
102
+ }
103
+ function patchConsole() {
104
+ const isBrowser = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
105
+ if (isBrowser) {
106
+ return;
107
+ }
108
+ if (globalThis.__TIDEWAVE_CONSOLE_PATCHED__) {
109
+ return;
110
+ }
111
+ const severityMap = {
112
+ log: "INFO",
113
+ info: "INFO",
114
+ warn: "WARN",
115
+ error: "ERROR",
116
+ debug: "DEBUG"
117
+ };
118
+ Object.entries(severityMap).forEach(([method, severity]) => {
119
+ const original = console[method].bind(console);
120
+ console[method] = (...args) => {
121
+ try {
122
+ const body = args.map((arg) => {
123
+ if (typeof arg === "string")
124
+ return arg;
125
+ if (arg instanceof Error) {
126
+ return String(arg.stack);
127
+ }
128
+ if (typeof arg === "object") {
129
+ try {
130
+ return JSON.stringify(arg);
131
+ } catch {
132
+ return String(arg);
133
+ }
134
+ }
135
+ return String(arg);
136
+ }).map(stripAnsiCodes).join(" ");
137
+ const isAllWhitespace = body.match(/^\s+$/);
138
+ if (!isAllWhitespace) {
139
+ tidewaveLogger.addLog({
140
+ timestamp: new Date().toISOString(),
141
+ severityText: severity,
142
+ body,
143
+ attributes: {
144
+ "log.origin": "console",
145
+ "log.method": method
146
+ }
147
+ });
148
+ }
149
+ } catch {}
150
+ original(...args);
151
+ };
152
+ });
153
+ globalThis.__TIDEWAVE_CONSOLE_PATCHED__ = true;
154
+ }
155
+ var ANSI_REGEX;
156
+ var init_console_patch = __esm(() => {
157
+ init_tidewave_logger();
158
+ ANSI_REGEX = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
159
+ });
160
+
161
+ // src/tanstack.ts
162
+ init_console_patch();
163
+ patchConsole();
package/dist/tools.d.ts CHANGED
@@ -28,18 +28,18 @@ export interface Tools {
28
28
  }
29
29
  export declare const projectEvalInputSchema: z.ZodObject<{
30
30
  code: z.ZodString;
31
- arguments: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodAny, "many">>>;
31
+ arguments: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>>;
32
32
  timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
33
33
  json: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
34
34
  }, "strip", z.ZodTypeAny, {
35
35
  code: string;
36
36
  timeout: number;
37
- arguments: any[];
37
+ arguments: unknown[];
38
38
  json: boolean;
39
39
  }, {
40
40
  code: string;
41
41
  timeout?: number | undefined;
42
- arguments?: any[] | undefined;
42
+ arguments?: unknown[] | undefined;
43
43
  json?: boolean | undefined;
44
44
  }>;
45
45
  export declare const docsInputSchema: z.ZodObject<{
@@ -1,4 +1,3 @@
1
1
  import type { TidewaveConfig } from './core';
2
2
  import type { Plugin } from 'vite';
3
- import './logger/instrumentation';
4
3
  export default function tidewave(config?: TidewaveConfig): Plugin;