@tracepanel/js 0.0.0-stage → 0.3.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +271 -2
  3. package/dist/agent.d.ts +42 -0
  4. package/dist/agent.js +298 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/api.d.ts +11 -0
  7. package/dist/api.js +34 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/browser.d.ts +25 -0
  10. package/dist/browser.js +438 -0
  11. package/dist/browser.js.map +1 -0
  12. package/dist/bullmq.d.ts +7 -0
  13. package/dist/bullmq.js +86 -0
  14. package/dist/bullmq.js.map +1 -0
  15. package/dist/bun.d.ts +15 -0
  16. package/dist/bun.js +114 -0
  17. package/dist/bun.js.map +1 -0
  18. package/dist/calls.d.ts +20 -0
  19. package/dist/calls.js +145 -0
  20. package/dist/calls.js.map +1 -0
  21. package/dist/cli.d.ts +2 -0
  22. package/dist/cli.js +39 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/config.d.ts +29 -0
  25. package/dist/config.js +48 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/console.d.ts +6 -0
  28. package/dist/console.js +44 -0
  29. package/dist/console.js.map +1 -0
  30. package/dist/explain.d.ts +25 -0
  31. package/dist/explain.js +145 -0
  32. package/dist/explain.js.map +1 -0
  33. package/dist/express.d.ts +2 -0
  34. package/dist/express.js +77 -0
  35. package/dist/express.js.map +1 -0
  36. package/dist/frameworks.d.ts +2 -0
  37. package/dist/frameworks.js +39 -0
  38. package/dist/frameworks.js.map +1 -0
  39. package/dist/headers.d.ts +2 -0
  40. package/dist/headers.js +42 -0
  41. package/dist/headers.js.map +1 -0
  42. package/dist/index.d.ts +5 -0
  43. package/dist/index.js +3 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/logs.d.ts +8 -0
  46. package/dist/logs.js +54 -0
  47. package/dist/logs.js.map +1 -0
  48. package/dist/model.d.ts +68 -0
  49. package/dist/model.js +41 -0
  50. package/dist/model.js.map +1 -0
  51. package/dist/next-widget.d.ts +3 -0
  52. package/dist/next-widget.js +17 -0
  53. package/dist/next-widget.js.map +1 -0
  54. package/dist/next.d.ts +2 -0
  55. package/dist/next.js +16 -0
  56. package/dist/next.js.map +1 -0
  57. package/dist/nuxt-plugin.d.ts +24 -0
  58. package/dist/nuxt-plugin.js +39 -0
  59. package/dist/nuxt-plugin.js.map +1 -0
  60. package/dist/nuxt.d.ts +10 -0
  61. package/dist/nuxt.js +16 -0
  62. package/dist/nuxt.js.map +1 -0
  63. package/dist/processor.d.ts +105 -0
  64. package/dist/processor.js +491 -0
  65. package/dist/processor.js.map +1 -0
  66. package/dist/register.d.ts +1 -0
  67. package/dist/register.js +5 -0
  68. package/dist/register.js.map +1 -0
  69. package/dist/runtime.d.ts +17 -0
  70. package/dist/runtime.js +27 -0
  71. package/dist/runtime.js.map +1 -0
  72. package/dist/setup.d.ts +10 -0
  73. package/dist/setup.js +102 -0
  74. package/dist/setup.js.map +1 -0
  75. package/dist/sql.d.ts +3 -0
  76. package/dist/sql.js +18 -0
  77. package/dist/sql.js.map +1 -0
  78. package/dist/stack.d.ts +13 -0
  79. package/dist/stack.js +66 -0
  80. package/dist/stack.js.map +1 -0
  81. package/dist/vite.d.ts +36 -0
  82. package/dist/vite.js +139 -0
  83. package/dist/vite.js.map +1 -0
  84. package/dist/widget.d.ts +26 -0
  85. package/dist/widget.js +70 -0
  86. package/dist/widget.js.map +1 -0
  87. package/package.json +125 -4
package/dist/widget.js ADDED
@@ -0,0 +1,70 @@
1
+ // What a response gives the widget: the trace's id and timing in headers, and widget.min.js in an HTML page.
2
+ import { runtimeLabel } from "./processor.js";
3
+ function escapeHtml(text) {
4
+ return text.replace(/[&<>"]/g, (char) => `&#${char.charCodeAt(0)};`);
5
+ }
6
+ /** The headers and the script tag for the active request, or undefined outside one. */
7
+ export function badge(tracepanel, request) {
8
+ const { method, status, startedMs, page, framework } = request;
9
+ const timing = tracepanel.processor.timing(request.url === undefined ? undefined : { method: request.method, url: request.url });
10
+ if (!timing)
11
+ return undefined;
12
+ let consoleUrl = tracepanel.console.get();
13
+ if (!consoleUrl && page && tracepanel.starter.ensure()) {
14
+ // The first page of a fresh project: its agent is starting (once), so the page gets the widget too.
15
+ consoleUrl = tracepanel.console.get();
16
+ }
17
+ // From the request's start as the trace saw it: a framework's own server started it before any of the app's code.
18
+ const totalMs = performance.now() - Math.min(startedMs, timing.startedMs);
19
+ const noun = timing.queries === 1 ? "query" : "queries";
20
+ const headers = {
21
+ "Tracepanel-Id": timing.id,
22
+ // The agent finds the issues: the widget asks the console for them once the trace is stored.
23
+ "Server-Timing": `db;dur=${timing.dbMs.toFixed(1)};desc="${timing.queries} ${noun}", app;dur=${Math.max(totalMs - timing.dbMs, 0).toFixed(1)}, total;dur=${totalMs.toFixed(1)}, tracepanel-issues;desc="pending"`,
24
+ };
25
+ if (consoleUrl)
26
+ headers["Tracepanel-Url"] = `${consoleUrl}#/t/${timing.id}`;
27
+ const scriptAttrs = page && consoleUrl
28
+ ? {
29
+ src: `${consoleUrl}widget.min.js`,
30
+ "data-tracepanel-api": consoleUrl,
31
+ "data-tracepanel-id": timing.id,
32
+ "data-tracepanel-method": method,
33
+ "data-tracepanel-status": String(status),
34
+ "data-tracepanel-total": totalMs.toFixed(1),
35
+ "data-tracepanel-db": timing.dbMs.toFixed(1),
36
+ "data-tracepanel-queries": String(timing.queries),
37
+ "data-tracepanel-issues": "pending",
38
+ "data-tracepanel-runtime": runtimeLabel(framework),
39
+ }
40
+ : undefined;
41
+ const script = scriptAttrs
42
+ ? `<script ${Object.entries(scriptAttrs)
43
+ .map(([name, value]) => `${name}="${escapeHtml(value)}"`)
44
+ .join(" ")}></script>`
45
+ : undefined;
46
+ return { headers, script, scriptAttrs };
47
+ }
48
+ const EXPOSED = ["Tracepanel-Id", "Tracepanel-Name", "Tracepanel-Url", "Server-Timing"];
49
+ /**
50
+ * Access-Control-Expose-Headers with Tracepanel's added, for a CORS response (one with Access-Control-Allow-Origin):
51
+ * a page on another origin, an SPA on Vite's dev server, can read the trace's id then. Undefined for other responses.
52
+ */
53
+ export function exposedHeaders(allowOrigin, existing) {
54
+ if (allowOrigin === undefined || allowOrigin === null)
55
+ return undefined;
56
+ const names = String(existing ?? "")
57
+ .split(",")
58
+ .map((name) => name.trim())
59
+ .filter(Boolean);
60
+ return [...new Set([...names, ...EXPOSED])].join(", ");
61
+ }
62
+ /** The tag first in <head>, so the widget wraps fetch before the page's scripts keep a reference to it. */
63
+ export function inject(page, tag) {
64
+ const head = /<head[^>]*>/i.exec(page);
65
+ if (head)
66
+ return page.slice(0, head.index + head[0].length) + tag + page.slice(head.index + head[0].length);
67
+ const body = page.toLowerCase().lastIndexOf("</body>");
68
+ return body >= 0 ? page.slice(0, body) + tag + page.slice(body) : page;
69
+ }
70
+ //# sourceMappingURL=widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget.js","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,127 @@
1
1
  {
2
2
  "name": "@tracepanel/js",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.3.0",
4
+ "description": "Traces and logs for Node.js and Bun apps (Express, NestJS, Next.js, Nuxt, Bun.serve): every request with its SQL, logs and errors, N+1 queries found",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "packageManager": "pnpm@12.11.0",
8
+ "engines": {
9
+ "node": ">=20.19"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./register": {
17
+ "types": "./dist/register.d.ts",
18
+ "default": "./dist/register.js"
19
+ },
20
+ "./express": {
21
+ "types": "./dist/express.d.ts",
22
+ "default": "./dist/express.js"
23
+ },
24
+ "./next": {
25
+ "types": "./dist/next.d.ts",
26
+ "default": "./dist/next.js"
27
+ },
28
+ "./next/widget": {
29
+ "types": "./dist/next-widget.d.ts",
30
+ "default": "./dist/next-widget.js"
31
+ },
32
+ "./nuxt": {
33
+ "types": "./dist/nuxt.d.ts",
34
+ "default": "./dist/nuxt.js"
35
+ },
36
+ "./bun": {
37
+ "types": "./dist/bun.d.ts",
38
+ "default": "./dist/bun.js"
39
+ },
40
+ "./vite": {
41
+ "types": "./dist/vite.d.ts",
42
+ "default": "./dist/vite.js"
43
+ },
44
+ "./browser": {
45
+ "types": "./dist/browser.d.ts",
46
+ "default": "./dist/browser.js"
47
+ }
48
+ },
49
+ "bin": {
50
+ "tracepanel": "dist/cli.js"
51
+ },
52
+ "files": [
53
+ "dist",
54
+ "README.md",
55
+ "LICENSE"
56
+ ],
57
+ "scripts": {
58
+ "build": "tsc -p tsconfig.build.json",
59
+ "typecheck": "tsc --noEmit",
60
+ "test": "vitest run",
61
+ "lint": "biome check . && tsc --noEmit",
62
+ "fmt": "biome check --write ."
63
+ },
64
+ "dependencies": {
65
+ "@opentelemetry/api": "^1.9.1",
66
+ "@opentelemetry/instrumentation": "^0.223.0",
67
+ "@opentelemetry/instrumentation-express": "^0.71.0",
68
+ "@opentelemetry/instrumentation-http": "^0.223.0",
69
+ "@opentelemetry/instrumentation-ioredis": "^0.71.0",
70
+ "@opentelemetry/instrumentation-mongodb": "^0.76.0",
71
+ "@opentelemetry/instrumentation-mysql2": "^0.69.0",
72
+ "@opentelemetry/instrumentation-nestjs-core": "^0.69.0",
73
+ "@opentelemetry/instrumentation-pg": "^0.75.0",
74
+ "@opentelemetry/instrumentation-redis": "^0.71.0",
75
+ "@opentelemetry/instrumentation-undici": "^0.33.0",
76
+ "@opentelemetry/sdk-trace-base": "^2.12.0",
77
+ "@opentelemetry/sdk-trace-node": "^2.12.0",
78
+ "@prisma/instrumentation": "^7.10.0",
79
+ "@tracepanel/agent": "0.3.0",
80
+ "import-in-the-middle": "^3.5.2"
81
+ },
82
+ "peerDependencies": {
83
+ "express": ">=4.18",
84
+ "react": ">=18",
85
+ "@types/express": ">=4.17"
86
+ },
87
+ "peerDependenciesMeta": {
88
+ "express": {
89
+ "optional": true
90
+ },
91
+ "react": {
92
+ "optional": true
93
+ },
94
+ "@types/express": {
95
+ "optional": true
96
+ }
97
+ },
98
+ "devDependencies": {
99
+ "@biomejs/biome": "2.5.15",
100
+ "@opentelemetry/context-async-hooks": "^2.12.0",
101
+ "@types/express": "^5.0.6",
102
+ "@types/node": "^26.6.5",
103
+ "@types/pg": "^8.23.1",
104
+ "@types/react": "^19.3.0",
105
+ "express": "^5.3.0",
106
+ "happy-dom": "^21.0.1",
107
+ "pg": "^8.23.1",
108
+ "typescript": "^7.0.2",
109
+ "vitest": "^5.0.0"
110
+ },
111
+ "keywords": [
112
+ "bun",
113
+ "express",
114
+ "n+1",
115
+ "nestjs",
116
+ "nextjs",
117
+ "nuxt",
118
+ "opentelemetry",
119
+ "sql",
120
+ "tracing"
121
+ ],
122
+ "repository": {
123
+ "type": "git",
124
+ "url": "git+https://github.com/tracepanel/tracepanel-js.git"
125
+ },
126
+ "homepage": "https://tracepanel.dev"
127
+ }