@moonwatch/js 0.1.12 → 0.1.14

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/README.md CHANGED
@@ -130,6 +130,42 @@ logger.setGroup(undefined);
130
130
  logger.setTraceId(undefined);
131
131
  ```
132
132
 
133
+ ### Dynamic Trace ID Provider
134
+
135
+ For server-side applications handling concurrent requests, use `setTraceIdProvider` to dynamically resolve the trace ID per log entry. This works with Node.js `AsyncLocalStorage` to associate every log (including intercepted `console.log` calls) with the request that triggered it:
136
+
137
+ ```ts
138
+ import { AsyncLocalStorage } from "node:async_hooks";
139
+ import { randomUUID } from "node:crypto";
140
+ import { createLogger } from "@moonwatch/js";
141
+
142
+ const traceStorage = new AsyncLocalStorage<string>();
143
+
144
+ const logger = createLogger({
145
+ logId: "your-log-file-id",
146
+ apiKey: "your-api-key",
147
+ silent: true,
148
+ });
149
+
150
+ // Register the provider — called on every log to resolve the current trace ID
151
+ logger.setTraceIdProvider(() => traceStorage.getStore());
152
+ logger.interceptConsole();
153
+
154
+ // In your HTTP middleware:
155
+ app.use(async (ctx, next) => {
156
+ const traceId = randomUUID();
157
+ await traceStorage.run(traceId, next);
158
+ });
159
+
160
+ // Now any console.log during a request automatically gets that request's trace ID
161
+ console.log("processing order"); // → trace_id: "the-request-uuid"
162
+ ```
163
+
164
+ The provider is checked on every log call with the following priority:
165
+ 1. Per-call `traceId` (via object form or `ScopedLogger`)
166
+ 2. `traceIdProvider()` return value
167
+ 3. Static `traceId` from config / `setTraceId()`
168
+
133
169
  ## Console Interception
134
170
 
135
171
  Capture existing `console.*` calls without changing application code:
package/dist/index.js CHANGED
@@ -347,7 +347,7 @@ var LEVEL_ORDER = {
347
347
  ERROR: 3,
348
348
  FATAL: 4
349
349
  };
350
- var SDK_VERSION = "0.1.4";
350
+ var SDK_VERSION = "0.1.14";
351
351
  var DEFAULT_BASE_URL = "https://ingest.moonwatch.dev";
352
352
  var BATCH_SIZE = 50;
353
353
  var MAX_BUFFER_SIZE = 1e3;
@@ -788,12 +788,14 @@ ${arg.stack}`;
788
788
  }
789
789
  registerLifecycleHooks() {
790
790
  if (typeof window !== "undefined") {
791
- this._onVisibilityChange = () => {
792
- if (document.visibilityState === "hidden") {
793
- this.flushSync();
794
- }
795
- };
796
- document.addEventListener("visibilitychange", this._onVisibilityChange);
791
+ if (typeof document !== "undefined") {
792
+ this._onVisibilityChange = () => {
793
+ if (document.visibilityState === "hidden") {
794
+ this.flushSync();
795
+ }
796
+ };
797
+ document.addEventListener("visibilitychange", this._onVisibilityChange);
798
+ }
797
799
  this._onBeforeUnload = () => {
798
800
  this.flushSync();
799
801
  };
package/dist/index.mjs CHANGED
@@ -318,7 +318,7 @@ var LEVEL_ORDER = {
318
318
  ERROR: 3,
319
319
  FATAL: 4
320
320
  };
321
- var SDK_VERSION = "0.1.4";
321
+ var SDK_VERSION = "0.1.14";
322
322
  var DEFAULT_BASE_URL = "https://ingest.moonwatch.dev";
323
323
  var BATCH_SIZE = 50;
324
324
  var MAX_BUFFER_SIZE = 1e3;
@@ -759,12 +759,14 @@ ${arg.stack}`;
759
759
  }
760
760
  registerLifecycleHooks() {
761
761
  if (typeof window !== "undefined") {
762
- this._onVisibilityChange = () => {
763
- if (document.visibilityState === "hidden") {
764
- this.flushSync();
765
- }
766
- };
767
- document.addEventListener("visibilitychange", this._onVisibilityChange);
762
+ if (typeof document !== "undefined") {
763
+ this._onVisibilityChange = () => {
764
+ if (document.visibilityState === "hidden") {
765
+ this.flushSync();
766
+ }
767
+ };
768
+ document.addEventListener("visibilitychange", this._onVisibilityChange);
769
+ }
768
770
  this._onBeforeUnload = () => {
769
771
  this.flushSync();
770
772
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonwatch/js",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "JavaScript SDK for Moonwatch",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/dist/init.js DELETED
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- // src/init.ts
5
- var import_fs = require("fs");
6
- var import_path = require("path");
7
- var import_readline = require("readline");
8
- var CLAUDE_MD = "CLAUDE.md";
9
- var CURSORRULES = ".cursorrules";
10
- var MARKER = "@moonwatch/js";
11
- var cwd = process.cwd();
12
- function prompt(question) {
13
- const rl = (0, import_readline.createInterface)({ input: process.stdin, output: process.stdout });
14
- return new Promise((resolve2) => {
15
- rl.question(question, (answer) => {
16
- rl.close();
17
- resolve2(answer.trim());
18
- });
19
- });
20
- }
21
- function findSkillRef() {
22
- const skillPath = (0, import_path.resolve)(__dirname, "..", "SKILL.md");
23
- if ((0, import_fs.existsSync)(skillPath)) {
24
- const relative = (0, import_path.resolve)(cwd) === (0, import_path.resolve)((0, import_path.join)(skillPath, "..", "..")) ? "node_modules/@moonwatch/js/SKILL.md" : skillPath.replace(/\\/g, "/");
25
- return `> See ${relative} for the @moonwatch/js logging workflow.`;
26
- }
27
- return "> See node_modules/@moonwatch/js/SKILL.md for the @moonwatch/js logging workflow.";
28
- }
29
- function appendIfMissing(filename) {
30
- const filepath = (0, import_path.resolve)(cwd, filename);
31
- let content = "";
32
- if ((0, import_fs.existsSync)(filepath)) {
33
- content = (0, import_fs.readFileSync)(filepath, "utf-8");
34
- if (content.includes(MARKER)) {
35
- console.log(` ${filename}: already configured, skipping`);
36
- return false;
37
- }
38
- }
39
- const skillRef = findSkillRef();
40
- const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
41
- (0, import_fs.writeFileSync)(filepath, content + separator + skillRef + "\n", "utf-8");
42
- console.log(` ${filename}: ${content.length > 0 ? "updated" : "created"}`);
43
- return true;
44
- }
45
- function setupClaudeApiKey(apiKey) {
46
- const claudeDir = (0, import_path.join)(cwd, ".claude");
47
- const settingsPath = (0, import_path.join)(claudeDir, "settings.local.json");
48
- let settings = {};
49
- if ((0, import_fs.existsSync)(settingsPath)) {
50
- try {
51
- settings = JSON.parse((0, import_fs.readFileSync)(settingsPath, "utf-8"));
52
- } catch {
53
- }
54
- if (settings.env?.MOONWATCH_API_KEY) {
55
- const existing = settings.env.MOONWATCH_API_KEY;
56
- const masked = existing.slice(0, 6) + "..." + existing.slice(-4);
57
- console.log(` .claude/settings.local.json: API key already set (${masked}), overwriting`);
58
- }
59
- }
60
- if (!(0, import_fs.existsSync)(claudeDir)) {
61
- (0, import_fs.mkdirSync)(claudeDir, { recursive: true });
62
- }
63
- settings.env = settings.env || {};
64
- settings.env.MOONWATCH_API_KEY = apiKey;
65
- (0, import_fs.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
66
- console.log(` .claude/settings.local.json: API key saved`);
67
- return true;
68
- }
69
- async function main() {
70
- console.log("\n@moonwatch/js init\n");
71
- console.log("Setting up AI assistant integration...");
72
- const claudeUpdated = appendIfMissing(CLAUDE_MD);
73
- const cursorUpdated = appendIfMissing(CURSORRULES);
74
- if (!claudeUpdated && !cursorUpdated) {
75
- console.log(" Already set up.\n");
76
- } else {
77
- console.log("");
78
- }
79
- console.log("Setting up Claude Code MCP connection...");
80
- const existingSettings = (0, import_path.join)(cwd, ".claude", "settings.local.json");
81
- let hasKey = false;
82
- if ((0, import_fs.existsSync)(existingSettings)) {
83
- try {
84
- const s = JSON.parse((0, import_fs.readFileSync)(existingSettings, "utf-8"));
85
- hasKey = !!s.env?.MOONWATCH_API_KEY;
86
- } catch {
87
- }
88
- }
89
- if (hasKey) {
90
- const overwrite = await prompt(" API key already configured. Overwrite? (y/N) ");
91
- if (overwrite.toLowerCase() !== "y") {
92
- console.log(" Skipping.\n");
93
- console.log("Done.\n");
94
- return;
95
- }
96
- }
97
- const apiKey = await prompt(" Enter your Moonwatch API key: ");
98
- if (!apiKey) {
99
- console.log(" No key provided, skipping.\n");
100
- } else {
101
- setupClaudeApiKey(apiKey);
102
- console.log("");
103
- }
104
- console.log("Done. Your AI assistant now has access to the Moonwatch workflow guide.\n");
105
- }
106
- main();