{"_id":"@common-sense/trace-iq","_rev":"2-529d0ff8f5e29580ca5aecc5c3b8b2eb","name":"@common-sense/trace-iq","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@common-sense/trace-iq","version":"0.1.0","license":"MIT","_id":"@common-sense/trace-iq@0.1.0","maintainers":[{"name":"jacobspc","email":"jacob.pcyr@gmail.com"}],"dist":{"shasum":"2481034f6b57d41a42cbeab1b41a74d71322b57c","tarball":"https://registry.npmjs.org/@common-sense/trace-iq/-/trace-iq-0.1.0.tgz","fileCount":76,"integrity":"sha512-Jk+/W+FyPqDVN7uLJLXBAdh2YkHMZNqK/ni//h3h/1/2sJS6Dlli8yM26NFgKT+jeSj9PB+Xd4KM4l8oBq0JFg==","signatures":[{"sig":"MEQCICldZmVOcZJ0WzXCgElPQ5F9M3S6A8B+P98Daj986T0HAiB0vEHdG6npx6XzzESw9C7YQE2/oBuLdJIzIaw3PrXSKQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":93596},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./traceid":{"types":"./dist/traceid/index.d.ts","default":"./dist/traceid/index.js"},"./traceparent":{"types":"./dist/traceparent/index.d.ts","default":"./dist/traceparent/index.js"}},"gitHead":"f4d3b41b023896b3a0eab0bbd5550dd3f4725960","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","clean":"rm -rf dist","prepare":"npm run build"},"_npmUser":{"name":"jacobspc","email":"jacob.pcyr@gmail.com"},"_npmVersion":"10.8.2","description":"Lightweight W3C traceparent + async context utilities for Node.js","directories":{},"_nodeVersion":"20.19.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.6.3","@types/node":"^20.11.30"},"_npmOperationalInternal":{"tmp":"tmp/trace-iq_0.1.0_1757988859773_0.06961550810488526","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@common-sense/trace-iq","version":"0.1.1","publishConfig":{"access":"public"},"description":"Lightweight W3C traceparent + async context utilities for Node.js","repository":{"type":"git","url":"git+https://github.com/JacobPC/trace-iq.git"},"homepage":"https://github.com/JacobPC/trace-iq#readme","author":{"name":"JacobPC"},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./traceparent":{"types":"./dist/traceparent/index.d.ts","default":"./dist/traceparent/index.js"},"./traceid":{"types":"./dist/traceid/index.d.ts","default":"./dist/traceid/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","clean":"rm -rf dist","prepare":"npm run build","test":"vitest run"},"license":"MIT","engines":{"node":">=18.0.0"},"devDependencies":{"vitest":"^1.6.0","typescript":"^5.6.3","@types/node":"^20.11.30"},"_id":"@common-sense/trace-iq@0.1.1","gitHead":"a425bf988034bb5d500f9ca7c812d1de05053c7c","bugs":{"url":"https://github.com/JacobPC/trace-iq/issues"},"_nodeVersion":"20.19.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-nMP0M8iIMJqmgNzH+Bc9HB14cMGnL6Glbx7ww4e3Ybh7/usXxzPXmknDdwO26ZKa02KwcAbzb2/LayGiPYE9UA==","shasum":"c9b61994a6627760d32263b644aa68e05b9dec34","tarball":"https://registry.npmjs.org/@common-sense/trace-iq/-/trace-iq-0.1.1.tgz","fileCount":76,"unpackedSize":93778,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCo9aySc98ffTwn62Lw/V1pY1HSeK/z813lBwkHw0dnjAIgchZDCuC30dC3x9bXEeCoo+G6hcUt04XZfPbGYELA3MM="}]},"_npmUser":{"name":"jacobspc","email":"jacob.pcyr@gmail.com"},"directories":{},"maintainers":[{"name":"jacobspc","email":"jacob.pcyr@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/trace-iq_0.1.1_1758114519704_0.7694610390826226"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-16T02:14:19.674Z","modified":"2025-09-17T13:08:40.094Z","0.1.0":"2025-09-16T02:14:19.982Z","0.1.1":"2025-09-17T13:08:39.873Z"},"license":"MIT","description":"Lightweight W3C traceparent + async context utilities for Node.js","maintainers":[{"name":"jacobspc","email":"jacob.pcyr@gmail.com"}],"readme":"## @common-sense/trace-iq\n\nTiny, framework-agnostic tracing for Node.js with two simple modes:\n- W3C `traceparent` (spec-compliant, distributed)\n- Minimal `trace-id` (simple, local correlation)\n\nPlug-and-play for Express, NestJS, Koa, and Fastify with async context propagation and structured logging helpers.\n\n### Why\n- Keep tracing simple and standardized (W3C `traceparent`).\n- Zero vendor lock-in, no heavy dependencies.\n- Copy/paste integration in minutes, great DX.\n\n### How it works\n- Choose ONE mode per service:\n  - Traceparent mode: W3C-compatible tracing with `traceparent`/`tracestate` headers.\n  - Trace-id mode: Lightweight hex `trace-id` header for simple correlation.\n- Async context: Propagates the active trace across async/await, Promises, timers.\n- HTTP: Middlewares read incoming headers, set outgoing headers, and open a new child span (traceparent) or reuse/generate an id (trace-id).\n- Logging: Structured JSON enriched with the active mode’s context.\n\n### Install\n```bash\nnpm install @common-sense/trace-iq\n```\n\nNode 18+. Works without `@types/node`. For decorators, enable `\"experimentalDecorators\": true` in your tsconfig.\n\n---\n\n## Choose your mode (pick one)\n\n### A) Traceparent (W3C)\nUse the `traceparent` entrypoint for best separation and tree-shaking. Generate, parse, child spans\n```ts\nimport { TraceParent } from '@common-sense/trace-iq/traceparent';\n\nconst root = TraceParent.generate();\nconst parsed = TraceParent.parse('00-<trace-id>-<span-id>-01');\nconst child = root.child();\n```\n\nRun code with trace context\n```ts\nimport { runWithTrace, getCurrentTrace } from '@common-sense/trace-iq/traceparent';\n\nconst trace = TraceParent.generate();\nawait runWithTrace(trace, async () => {\n  const current = getCurrentTrace(); // { traceId, spanId, ... }\n});\n```\n\n---\n\nHTTP integrations\n\nExpress\n```ts\nimport express from 'express';\nimport { expressTracingMiddleware } from '@common-sense/trace-iq/traceparent';\n\nconst app = express();\napp.use(expressTracingMiddleware());\n```\n\nNestJS\nRegister a global interceptor; optionally inject `TraceService` anywhere to access the current trace.\n```ts\nimport { Module } from '@nestjs/common';\nimport { APP_INTERCEPTOR } from '@nestjs/core';\nimport { TraceInterceptor, TraceService } from '@common-sense/trace-iq/traceparent';\n\n@Module({\n  providers: [\n    TraceService,\n    { provide: APP_INTERCEPTOR, useClass: TraceInterceptor },\n  ],\n})\nexport class AppModule {}\n```\n\nKoa\n```ts\nimport Koa from 'koa';\nimport { koaTracingMiddleware } from '@common-sense/trace-iq/traceparent';\n\nconst app = new Koa();\napp.use(koaTracingMiddleware());\n```\n\nFastify\n```ts\nimport Fastify from 'fastify';\nimport { fastifyTracingPlugin } from '@common-sense/trace-iq/traceparent';\n\nconst app = Fastify();\napp.register(fastifyTracingPlugin);\n```\n\nNode http (no framework)\n```ts\nimport http from 'node:http';\nimport { withHttpTracing } from '@common-sense/trace-iq/traceparent';\n\nconst server = http.createServer(\n  withHttpTracing(async (req, res) => {\n    // getCurrentTrace() works here\n    res.end('ok');\n  })\n);\nserver.listen(3000);\n```\n\n---\n\nLogging\n\nStructured JSON (batteries-included)\n```ts\nimport { createConsoleJsonLogger, emitStructuredLog } from '@common-sense/trace-iq';\n\nconst logger = createConsoleJsonLogger();\nemitStructuredLog(logger, 'info', 'user.created', { userId: '123' });\n// => { timestamp, level: 'info', message: 'user.created', traceId, spanId, userId }\n```\n\nInject trace into existing loggers\nWinston\n```ts\nimport winston from 'winston';\nimport { createWinstonTraceFormat } from '@common-sense/trace-iq';\n\nconst logger = winston.createLogger({\n  level: 'info',\n  format: winston.format.combine(createWinstonTraceFormat(), winston.format.json()),\n  transports: [new winston.transports.Console()],\n});\n```\n\nPino\n```ts\nimport pino from 'pino';\nimport { getPinoBaseBindings, pinoChildWithTrace } from '@common-sense/trace-iq';\n\nconst logger = pino({ base: { ...getPinoBaseBindings() } });\nconst reqLogger = pinoChildWithTrace(logger);\n```\n\nBunyan\n```ts\nimport bunyan from 'bunyan';\nimport { bunyanChildWithTrace } from '@common-sense/trace-iq';\n\nconst logger = bunyan.createLogger({ name: 'app' });\nconst reqLogger = bunyanChildWithTrace(logger);\n```\n\nDecorators and function wrapper\n```ts\nimport { LogExecution, logFunction } from '@common-sense/trace-iq';\n\nclass Service {\n  @LogExecution({ includeArgs: true })\n  async doWork(userId: string) {\n    // ...\n  }\n}\n\nconst wrapped = logFunction(async () => { /* ... */ }, { includeArgs: true });\n```\n\n---\n\n### B) Simple trace-id\nUse the `traceid` entrypoint for a minimal setup. Generate and run with trace-id\n```ts\nimport { runWithTraceId, getCurrentTraceId } from '@common-sense/trace-iq/traceid';\n\nawait runWithTraceId(undefined, async () => {\n  console.log(getCurrentTraceId());\n});\n```\n\nHTTP integrations (trace-id header)\n```ts\n// Express\nimport { expressTraceIdMiddleware } from '@common-sense/trace-iq/traceid';\napp.use(expressTraceIdMiddleware());\n\n// Koa\nimport { koaTraceIdMiddleware } from '@common-sense/trace-iq/traceid';\napp.use(koaTraceIdMiddleware());\n\n// Fastify\nimport { fastifyTraceIdPlugin } from '@common-sense/trace-iq/traceid';\nfastify.register(fastifyTraceIdPlugin);\n\n// NestJS\nimport { APP_INTERCEPTOR } from '@nestjs/core';\nimport { TraceIdInterceptor } from '@common-sense/trace-iq/traceid';\nproviders: [{ provide: APP_INTERCEPTOR, useClass: TraceIdInterceptor }]\n```\n\nHTTP clients\n```ts\nimport { withTraceIdFetch, withTraceIdAxios } from '@common-sense/trace-iq/traceid';\n```\n\nLogging uses the active mode automatically; if `traceparent` is set, logs include `traceId`+`spanId`, else they include `traceId` only.\n\n---\n\n## API (quick reference)\n- Traceparent mode: `TraceParent.generate()`, `TraceParent.parse()`, `TraceParent#child()`, `runWithTrace()`\n- Trace-id mode: `generateTraceIdHex32()`, `runWithTraceId()`\n- HTTP (traceparent): `expressTracingMiddleware()`, `koaTracingMiddleware()`, `fastifyTracingPlugin`, `withHttpTracing()`\n- HTTP (trace-id): `expressTraceIdMiddleware()`, `koaTraceIdMiddleware()`, `fastifyTraceIdPlugin`, `withTraceIdHttp()`\n- HTTP clients: `withTracingFetch()`, `withTracingAxios()`, `withTraceIdFetch()`, `withTraceIdAxios()`\n- Logging: `createConsoleJsonLogger()`, `emitStructuredLog()`, `createWinstonTraceFormat()`, `getPinoBaseBindings()`, `pinoChildWithTrace()`, `bunyanChildWithTrace()`, `LogExecution()`\n\n---\n\n## Notes\n- Pick one mode per service; do not register both sets of middlewares.\n- W3C `traceparent` format: `version-traceId-spanId-flags` (lowercase hex). Non-zero IDs, version not `ff`.\n- If you use decorators, enable `\"experimentalDecorators\": true` in your tsconfig.\n\n\n","readmeFilename":"README.md","homepage":"https://github.com/JacobPC/trace-iq#readme","repository":{"type":"git","url":"git+https://github.com/JacobPC/trace-iq.git"},"author":{"name":"JacobPC"},"bugs":{"url":"https://github.com/JacobPC/trace-iq/issues"}}