@better-logger/core 0.8.0 → 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 0xmilord
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,101 +1,168 @@
1
1
  # better-logger
2
2
 
3
- **Track what your app *did*, not what it *said*.**
4
-
5
- Execution flow debugger for modern apps. Zero deps. Works everywhere. <10KB.
3
+ **console.log is broken. better.log fixes it.**
4
+
5
+ <p align="center">
6
+ <!-- Workflow Status -->
7
+ <a href="https://github.com/0xmilord/better-logger/actions/workflows/better-logger-ci.yml">
8
+ <img src="https://github.com/0xmilord/better-logger/actions/workflows/better-logger-ci.yml/badge.svg" alt="CI Status">
9
+ </a>
10
+ <a href="https://github.com/0xmilord/better-logger/actions/workflows/bundle-size.yml">
11
+ <img src="https://github.com/0xmilord/better-logger/actions/workflows/bundle-size.yml/badge.svg" alt="Bundle Size">
12
+ </a>
13
+
14
+ <!-- Package Info -->
15
+ <a href="https://www.npmjs.com/package/@better-logger/core">
16
+ <img src="https://img.shields.io/npm/v/@better-logger/core?color=0366d6&label=version" alt="npm version">
17
+ </a>
18
+ <a href="https://www.npmjs.com/package/@better-logger/core">
19
+ <img src="https://img.shields.io/npm/dw/@better-logger/core?color=0366d6" alt="npm downloads">
20
+ </a>
21
+ <a href="https://www.npmjs.com/package/@better-logger/core">
22
+ <img src="https://img.shields.io/bundlephobia/minzip/@better-logger/core?color=0366d6&label=gzip" alt="Bundle Size">
23
+ </a>
24
+
25
+ <!-- Code Quality -->
26
+ <a href="https://github.com/0xmilord/better-logger/blob/main/LICENSE">
27
+ <img src="https://img.shields.io/npm/l/@better-logger/core?color=0366d6" alt="License">
28
+ </a>
29
+ <a href="https://github.com/0xmilord/better-logger">
30
+ <img src="https://img.shields.io/github/last-commit/0xmilord/better-logger?color=0366d6" alt="Last Commit">
31
+ </a>
32
+ <a href="https://github.com/0xmilord/better-logger/issues">
33
+ <img src="https://img.shields.io/github/issues/0xmilord/better-logger?color=0366d6" alt="Issues">
34
+ </a>
35
+ <a href="https://github.com/0xmilord/better-logger/pulls">
36
+ <img src="https://img.shields.io/github/issues-pr/0xmilord/better-logger?color=0366d6" alt="Pull Requests">
37
+ </a>
38
+
39
+ <!-- Ecosystem -->
40
+ <a href="https://marketplace.visualstudio.com/items?itemName=0xmilord.better-logger">
41
+ <img src="https://img.shields.io/badge/vscode-extension-0366d6" alt="VS Code Extension">
42
+ </a>
43
+ <a href="https://0xmilord.github.io/better-logger/">
44
+ <img src="https://img.shields.io/badge/docs-site-0366d6" alt="Documentation">
45
+ </a>
46
+ </p>
47
+
48
+ <p align="center">
49
+ <strong>Zero Dependencies · 3.8KB Gzipped · 280 Tests · 96% Coverage · 8 Framework Integrations</strong>
50
+ </p>
51
+
52
+ ---
53
+
54
+ You wouldn't debug a multi-step process with sticky notes.
55
+ Stop debugging your app with console.log.
6
56
 
7
57
  ```bash
8
58
  npm install @better-logger/core
9
59
  ```
10
60
 
11
- ## Stop debugging like this:
61
+ ## The Problem
12
62
 
13
63
  ```typescript
64
+ // console.log — flat noise, no structure
14
65
  console.log('start')
15
66
  console.log('user', user)
16
67
  console.log('after db')
68
+ console.log('payment', payment)
17
69
  console.log('done')
18
70
  ```
19
71
 
20
- And trying to mentally reconstruct what happened, in what order, and how long each thing took.
72
+ And then trying to mentally reconstruct:
73
+ - What ran first?
74
+ - How long did each thing take?
75
+ - Where did it fail?
76
+ - What were the values at each step?
21
77
 
22
- ## Your app is not a list of messages. It's a flow.
78
+ ## The Solution
23
79
 
24
80
  ```typescript
25
81
  import { better } from '@better-logger/core'
26
82
 
27
- // Replace console.log zero learning curve
28
- better.log('User created', { email: 'test@example.com' })
29
- better.log.warn('Slow query detected', { duration: 250 })
30
- better.log.error('Payment failed', error)
31
-
32
- // When you need structure
33
- const flow = better.flow('user-onboarding', { tags: ['auth'] })
34
- const step = flow.step('create-user', { email })
35
- await createUser(email)
36
- step.success()
37
- flow.success()
83
+ // Same code. Better output.
84
+ better.log('start')
85
+ better.log('user', user)
86
+ better.log('after db')
87
+ better.log('payment', payment)
88
+ better.log('done')
38
89
  ```
39
90
 
40
91
  **What you get:**
41
92
 
42
93
  ```
43
- 🚀 [flow:user-onboarding] [auth] (tid: a1b2c3d4)
44
- create-user
94
+ 🚀 [flow:default] (tid: abc123)
95
+ start
96
+ ✓ start (12ms)
97
+ → user
45
98
  data: { email: "test@example.com" }
46
- create-user (45ms)
47
- 🏁 [flow:user-onboarding] success (45ms)
99
+ ✓ user (45ms)
100
+ after db
101
+ ✓ after db (210ms)
102
+ → payment
103
+ data: { amount: 99.99 }
104
+ ✓ payment (183ms)
105
+ → done
106
+ ✓ done (0ms)
107
+ 🏁 [flow:default] success (450ms)
48
108
  ```
49
109
 
50
- ## Why this exists
110
+ **Automatic timing. Context propagation. Hierarchical grouping. Zero config.**
51
111
 
52
- Debugging today is broken:
112
+ ## Why better.log?
53
113
 
54
- | Problem | better-logger solution |
55
- |---------|----------------------|
56
- | `console.log` flat noise, no structure | Hierarchical flows with automatic timing |
57
- | No automatic timing | Every step and flow tracks duration |
58
- | No context propagation | `flow.setContext()` shares metadata across all steps |
59
- | Async flows become impossible to follow | Deferred atomic rendering — one output per flow |
60
- | Need to learn new API | `better.log()` is `console.log()` just add `.log` |
114
+ | Feature | console.log | pino | winston | better.log |
115
+ |---------|-------------|------|---------|------------|
116
+ | Drop-in replacement | | | | |
117
+ | Auto-flow grouping | | | | |
118
+ | Automatic timing | | Manual | Manual | |
119
+ | Context propagation | | Manual | Manual | |
120
+ | Hierarchical output | | | | |
121
+ | Zero dependencies | ✅ | ❌ | ❌ | ✅ |
122
+ | Bundle size | 0KB | 30KB | 100KB | **8KB** |
123
+ | TypeScript support | ❌ | ✅ | ✅ | ✅ |
124
+ | Browser support | ✅ | ❌ | ❌ | ✅ |
125
+ | Structured output | ❌ | ✅ | ✅ | ✅ |
126
+ | Auto-error tracking | ❌ | ❌ | ❌ | ✅ |
61
127
 
62
128
  ## Quick Start
63
129
 
64
- ### 1. Drop-in replacement
65
-
66
- Replace `console.log` with `better.log`:
130
+ ### Replace console.log
67
131
 
68
132
  ```typescript
133
+ import { better } from '@better-logger/core'
134
+
69
135
  // Before
70
- console.log('Server started on port 3000')
71
- console.error('Database connection failed', error)
136
+ console.log('User created:', user)
137
+ console.error('Payment failed:', error)
72
138
 
73
139
  // After
74
- import { better } from '@better-logger/core'
75
-
76
- better.log('Server started on port 3000')
77
- better.log.error('Database connection failed', error)
140
+ better.log('User created:', user)
141
+ better.log.error('Payment failed:', error)
78
142
  ```
79
143
 
80
- That's it. You now get structured, timed output for free.
144
+ ### Severity tagging
81
145
 
82
- ### 2. When you need structure
146
+ ```typescript
147
+ better.log.info('Server started', { port: 3000 })
148
+ better.log.warn('Slow query', { duration: 250 })
149
+ better.log.error('Connection failed', error)
150
+ ```
83
151
 
84
- For important operations, use explicit flows:
152
+ ### When you need structure
85
153
 
86
154
  ```typescript
87
- const flow = better.flow('process-payment', { tags: ['billing'] })
88
- flow.setContext({ orderId: 'ord-123', userId: 'user-456' })
155
+ const flow = better.flow('checkout', { tags: ['payment'] })
156
+ flow.setContext({ userId: 'user-123' })
89
157
 
90
158
  const step = flow.step('charge-card', { amount: 99.99 })
91
159
  const result = await paymentGateway.charge({ amount: 99.99 })
92
160
  step.success(result)
93
161
 
94
162
  flow.success()
95
- better.log(`Payment processed: ${result.transactionId}`)
96
163
  ```
97
164
 
98
- ### 3. Async made easy
165
+ ### Async helper
99
166
 
100
167
  ```typescript
101
168
  const flow = better.flow('data-export')
@@ -104,144 +171,150 @@ const data = await flow.run('fetch-data', async () => {
104
171
  return await db.users.find({})
105
172
  })
106
173
 
107
- const file = await flow.run('generate-file', async () => {
108
- return await exportToCSV(data)
109
- })
110
-
111
174
  flow.success()
112
175
  ```
113
176
 
114
177
  ## API Reference
115
178
 
116
- ### `better.log()` The simple way
179
+ ### Core (90% of users need only this)
117
180
 
118
181
  ```typescript
119
- better.log('message') // Simple message
120
- better.log('message', data) // Message with data
121
- better.log.info('message', data) // Info (same as log)
122
- better.log.warn('message', data) // Warning (auto-tags flow)
123
- better.log.error('message', error) // Error (fails flow)
182
+ better.log('message') // Simple message
183
+ better.log('message', data) // Message with data
184
+ better.log.warn('warning', data) // Warning (auto-tags flow)
185
+ better.log.error('error', error) // Error (fails flow)
186
+
187
+ better.flow('name', options) // Explicit flow
188
+ better.setEnabled(false) // Disable all logging
189
+ better.subscribe(fn) // Listen for flow completions
190
+ better.toJSON(flow) // Export flow as JSON
124
191
  ```
125
192
 
126
- ### `better.flow()` — The structured way
193
+ ### Transports (Production)
127
194
 
128
195
  ```typescript
129
- const flow = better.flow('name', {
130
- tags: ['tag1', 'tag2'], // Indexing labels
131
- maxSteps: 100, // Safety limit
132
- initialContext: { key: 'value' } // Shared metadata
133
- })
134
-
135
- flow.setContext({ userId: 'abc' }) // Add context
136
- flow.getContext() // Get context copy
137
-
138
- flow.step('step-name', data) // Create step
139
- .success() // Mark success
140
- .fail(error) // Mark failure
141
-
142
- flow.success() // Complete flow
143
- flow.fail(error) // Fail flow
196
+ better.log.toFile('app.log') // File transport
197
+ better.log.toStream(process.stdout) // Stream transport
198
+ better.log.toHttp('https://api.example.com/log') // HTTP transport
144
199
  ```
145
200
 
146
- ### `better.flow.run()` — Async helper
201
+ ### Production Features
147
202
 
148
203
  ```typescript
149
- const result = await flow.run('async-step', async () => {
150
- return await fetchData() // Auto-completes step on success/fail
151
- })
204
+ better.log.redact(['password', 'ssn']) // PII redaction
205
+ better.log.async(true) // Non-blocking async
206
+ better.log.flush() // Force complete
152
207
  ```
153
208
 
154
209
  ### Configuration
155
210
 
156
211
  ```typescript
157
- better.log.setIdleTimeout(200) // Auto-complete timeout (ms)
158
- better.log.setFlowName('my-app') // Default flow name
159
- better.log.setDefaultTags(['app', 'v3']) // Tags on all flows
160
- better.log.flush() // Force complete current flow
161
- better.setEnabled(false) // Disable all logging
162
- better.isEnabled() // Check if enabled
212
+ better.setIdleTimeout(200) // Auto-complete timeout
213
+ better.setFlowName('my-app') // Default flow name
214
+ better.setDefaultTags(['app', 'v3']) // Tags on all flows
163
215
  ```
164
216
 
165
217
  ## Real-World Examples
166
218
 
167
- We've included 10 comprehensive examples showing better-logger in real applications:
219
+ We've included 11 comprehensive examples:
168
220
 
169
221
  | Example | What it shows |
170
222
  |---------|--------------|
171
- | `01-express-rest-api.js` | Express middleware, CRUD endpoints, error handling |
172
- | `02-background-job-processor.js` | Job queue, retry logic, nested flows |
173
- | `03-authentication-flow.js` | Login, token refresh, password reset, security logging |
174
- | `04-ecommerce-order-processing.js` | Multi-step checkout, inventory, payment, shipping |
175
- | `05-cli-tool.js` | CLI commands, progress tracking, file processing |
176
- | `06-api-integration-client.js` | HTTP client, retry logic, rate limiting, batch ops |
177
- | `07-microservice-distributed-tracing.js` | Trace context, downstream calls, health checks |
178
- | `08-testing-utilities.js` | Test runner, assertions, performance testing |
179
- | `09-data-pipeline.js` | ETL pipelines, transforms, validation, aggregation |
180
- | `10-full-application.js` | Complete Node.js app with all patterns combined |
181
-
182
- ## Features
183
-
184
- ### Zero Friction
185
- - `better.log()` is a drop-in for `console.log()`
186
- - No configuration needed — import and use immediately
187
- - Auto-flow management groups rapid calls together
188
- - Idle timeout auto-completes flows (100ms default)
189
-
190
- ### Structured Output
191
- - Hierarchical flows with visual nesting
192
- - Automatic timing for every step and flow
193
- - Context propagation across all steps
194
- - Tags for filtering and grouping
195
- - JSON export for downstream systems
196
-
197
- ### Production-Grade
198
- - Zero dependencies nothing to break
199
- - <10KB bundle won't bloat your app
200
- - Works in Node.js 18+, browsers, Edge runtimes
201
- - Full TypeScript support
202
- - 100% test coverage
203
-
204
- ### Forgiving
205
- - Call methods after completion silent no-ops
206
- - Pass any data type handled gracefully
207
- - Circular referenceswon't crash
208
- - Concurrent flows no interleaving
209
- - Error anywhere — won't break your app
210
-
211
- ## Migration from console.log
212
-
213
- ```typescript
214
- // Before
215
- console.log('User created:', user)
216
- console.warn('Slow query', { duration: 250 })
217
- console.error('Payment failed:', error)
223
+ | `examples/01-express-rest-api.js` | Express middleware, CRUD, error handling |
224
+ | `examples/02-background-job-processor.js` | Job queue, retry logic, nested flows |
225
+ | `examples/03-authentication-flow.js` | Login, token refresh, password reset |
226
+ | `examples/04-ecommerce-order-processing.js` | Multi-step checkout, payments, shipping |
227
+ | `examples/05-cli-tool.js` | CLI commands, progress, dry-run |
228
+ | `examples/06-api-integration-client.js` | HTTP client, retry, rate limiting |
229
+ | `examples/07-microservice-distributed-tracing.js` | Trace context, downstream calls |
230
+ | `examples/08-testing-utilities.js` | Test runner, assertions, perf tests |
231
+ | `examples/09-data-pipeline.js` | ETL stages, transforms, aggregation |
232
+ | `examples/10-full-application.js` | Complete Node.js app with all patterns |
233
+ | `examples/11-angular-app.js` | Angular service, HTTP interceptor, error handler |
234
+
235
+ Framework integrations (13 total):
236
+
237
+ | Package | Framework | Install | When to use this vs Core |
238
+ |---------|-----------|---------|--------------------------|
239
+ | `@better-logger/express` | Express.js | `npm i @better-logger/express` | **Auto-logging** for every request vs manual middleware. |
240
+ | `@better-logger/fastify` | Fastify | `npm i @better-logger/fastify` | **Plugin** with hooks vs manual `app.addHook`. |
241
+ | `@package/koa` | Koa | `npm i @better-logger/koa` | **Middleware** + error handler vs manual `ctx` logic. |
242
+ | `@better-logger/hono` | Hono (Edge) | `npm i @better-logger/hono` | **Edge-compatible** middleware for Cloudflare/Vercel. |
243
+ | `@better-logger/nestjs` | NestJS | `npm i @better-logger/nestjs` | **Module + Interceptor** + Exception filter integration. |
244
+ | `@better-logger/nextjs` | Next.js | `npm i @better-logger/nextjs` | **Plugin** for API routes and server components. |
245
+ | `@better-logger/react` | React | `npm i @better-logger/react` | **Hooks** for lifecycle and error boundaries. |
246
+ | `@better-logger/angular` | Angular | `npm i @better-logger/angular` | **Service** + HTTP interceptor + error handler. |
247
+ | `@better-logger/vue` | Vue 2/3 | `npm i @better-logger/vue` | **Plugin** + composable for lifecycle tracking. |
248
+ | `@better-logger/svelte` | Svelte | `npm i @better-logger/svelte` | **Function** for component and async tracking. |
249
+ | `@better-logger/sveltekit` | SvelteKit | `npm i @better-logger/sveltekit` | **Server hook** for routes and API endpoints. |
250
+ | `@better-logger/astro` | Astro | `npm i @better-logger/astro` | **Integration** for build and dev server logging. |
251
+ | `@better-logger/cli` | CLI Tools | `npm i @better-logger/cli` | **Helpers** for progress bars, tables, commands. |
252
+
253
+ ## Performance
254
+
255
+ | Metric | better.log | console.log | pino | winston |
256
+ |--------|-----------|-------------|------|---------|
257
+ | Simple message | 89ms | 45ms | 38ms | 120ms |
258
+ | With data | 142ms | 78ms | 65ms | 180ms |
259
+ | Async mode | 52ms | | — | — |
260
+ | Bundle size | **8KB** | 0KB | 30KB | 100KB |
261
+
262
+ **better.log is fast enough for 95% of use cases.** For high-throughput, use async mode.
263
+
264
+ See [BENCHMARKS.md](docs/BENCHMARKS.md) for full benchmarks.
265
+
266
+ ## Migration
267
+
268
+ ### From console.log
218
269
 
219
- // After (literally just add "better.")
220
- import { better } from '@better-logger/core'
221
-
222
- better.log('User created:', user)
223
- better.log.warn('Slow query', { duration: 250 })
224
- better.log.error('Payment failed:', error)
270
+ ```bash
271
+ npx @better-logger/codemod .
225
272
  ```
226
273
 
227
- **Migration effort:** 10 minutes to replace all console.log. Hours to days to adopt flows strategically where they add value.
274
+ Or manually: Replace `console.log` `better.log`, `console.error` `better.log.error`.
228
275
 
229
- ## What's NOT included
276
+ ### From pino/winston
230
277
 
231
- - Log levels (debug, info, warn, error) — execution tracing ≠ log routing
232
- - ❌ Transport layers (file, HTTP, Elasticsearch) — zero-config philosophy
233
- - ❌ SaaS dashboards — we emit data, we don't host it
234
- - ❌ Auto-instrumentation — devs control what they trace
278
+ See [Migration Guides](docs/MIGRATE-FROM-PINO.md), [docs/MIGRATE-FROM-WINSTON.md](docs/MIGRATE-FROM-WINSTON.md).
235
279
 
236
280
  ## Package Health
237
281
 
238
282
  | Metric | Value |
239
283
  |--------|-------|
240
- | Bundle size | <10KB minified |
241
- | Dependencies | 0 |
242
- | Test coverage | 100% |
243
- | TypeScript | Full support |
244
- | Runtimes | Node 18+, Browser, Edge |
284
+ | **Tests** | 280 passing |
285
+ | **Coverage** | 96.61% |
286
+ | **Bundle size** | 10.73KB (3.8KB gzipped) |
287
+ | **Dependencies** | 0 |
288
+ | **TypeScript** | Full support |
289
+ | **Runtimes** | Node 18+, Browser, Edge |
290
+
291
+ ## Ecosystem
292
+
293
+ | Package | Purpose |
294
+ |---------|---------|
295
+ | `@better-logger/core` | Core library |
296
+ | `packages/express/` | Express middleware |
297
+ | `packages/fastify/` | Fastify plugin |
298
+ | `packages/koa/` | Koa middleware |
299
+ | `packages/hono/` | Hono/Edge middleware |
300
+ | `packages/nestjs/` | NestJS module |
301
+ | `packages/nextjs/` | Next.js plugin |
302
+ | `packages/react/` | React hooks |
303
+ | `packages/angular/` | Angular service |
304
+ | `packages/vue/` | Vue 2/3 plugin |
305
+ | `packages/svelte/` | Svelte functions |
306
+ | `packages/sveltekit/` | SvelteKit hooks |
307
+ | `packages/astro/` | Astro integration |
308
+ | `packages/cli/` | CLI helpers |
309
+ | `packages/eslint-plugin/` | ESLint rules |
310
+ | `packages/vscode/` | VS Code snippets |
311
+
312
+ ## What's NOT included
313
+
314
+ - ❌ Log levels (debug, info, warn, error) — execution tracing ≠ log routing
315
+ - ❌ Transport layers — we emit data, you decide where it goes
316
+ - ❌ SaaS dashboards — we don't host your logs
317
+ - ❌ Auto-instrumentation — you control what gets traced
245
318
 
246
319
  ## License
247
320
 
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var I=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ie=Object.prototype.hasOwnProperty;var se=(e,r)=>{for(var t in r)I(e,t,{get:r[t],enumerable:!0})},ae=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oe(r))!ie.call(e,i)&&i!==t&&I(e,i,{get:()=>r[i],enumerable:!(n=ne(r,i))||n.enumerable});return e};var le=e=>ae(I({},"__esModule",{value:!0}),e);var ve={};se(ve,{NOOP_FLOW:()=>c,NOOP_STEP:()=>m,better:()=>d,createFlow:()=>k,getRenderer:()=>A,isEnabled:()=>x,normalizeError:()=>f,safeSerialize:()=>p,setClock:()=>j,setEnabled:()=>b,setIdGenerator:()=>Z,setRenderer:()=>G,subscribe:()=>H,toJSON:()=>J});module.exports=le(ve);function f(e){return e===void 0?{name:"Error",message:"Unknown error"}:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e=="string"?{name:"Error",message:e}:{name:"Error",message:String(e)}}var y=class{constructor(r,t){this._trace=r;this._clock=t;this._completed=!1}get isCompleted(){return this._completed}get trace(){return this._trace}success(){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="success")}fail(r){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="error",this._trace.error=f(r))}};var g=()=>{},m={success:g,fail:g},c={step:()=>m,child:()=>c,tag:g,tags:()=>[],setContext:g,getContext:()=>({}),success:g,fail:g,run:(e,r)=>{try{let t=r();return t instanceof Promise?t:Promise.resolve(t)}catch(t){return Promise.reject(t)}}};function U(e){let r=new WeakMap;function t(n){if(n===null||typeof n!="object")return n;if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(r.has(n))return r.get(n);if(Array.isArray(n)){let s=[];r.set(n,s);for(let o=0;o<n.length;o++)s.push(t(n[o]));return s}let i={};r.set(n,i);for(let s of Object.keys(n))i[s]=t(n[s]);return i}return t(e)}function R(e){if(e===null||typeof e!="object")return e;if(Object.freeze(e),Array.isArray(e))for(let r of e)R(r);else for(let r of Object.keys(e)){let t=e[r];t&&typeof t=="object"&&!Object.isFrozen(t)&&R(t)}return e}function z(e){let r=U(e);return R(r)}var O=new Set;function H(e){return O.add(e),()=>{O.delete(e)}}function ce(e){if(O.size!==0)for(let r of O)try{r(e)}catch{}}var C=class e{constructor(r,t,n,i,s){this._trace=r;this._clock=t;this._idGen=n;this._renderer=i;this._options=s;this._completed=!1;this._sequence=0}get isCompleted(){return this._completed}get trace(){return this._trace}step(r,t){if(this._completed)return m;let n=this._options.maxSteps;if(n!==void 0&&this._trace.steps.length>=n)return this._trace.meta===void 0?this._trace.meta={maxStepsExceeded:!0}:this._trace.meta.maxStepsExceeded=!0,m;let i={id:this._idGen.generate(),name:r,sequence:this._sequence++,state:"running",status:"pending",start:this._clock.now(),data:t,children:[]};return this._trace.steps.push(i),new y(i,this._clock)}child(r){if(this._completed)return c;if(this._options.enabled===!1)return c;let t={id:this._idGen.generate(),name:r,parentId:this._trace.id,state:"running",status:void 0,tags:[],start:this._clock.now(),context:{...this._trace.context},steps:[]};return new e(t,this._clock,this._idGen,this._renderer,{...this._options})}tag(r){this._completed||this._trace.tags.includes(r)||this._trace.tags.push(r)}tags(){return[...this._trace.tags]}setContext(r){this._completed||Object.assign(this._trace.context,r)}getContext(){return{...this._trace.context}}success(){this._finalize("success")}fail(r){this._trace.error=f(r),this._finalize("error")}run(r,t){if(this._completed)return Promise.resolve(t());let n=this.step(r);return Promise.resolve(t()).then(i=>(n.success(),i),i=>{throw n.fail(i),i})}_finalize(r){if(this._completed)return;this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status=r;let t=z(this._trace);ce(t),this._renderer.render(t)}};var h=class{generate(){return Math.random().toString(36).slice(2,10)}};var _=class{now(){return Date.now()}};function p(e,r){let t=r?.maxDepth??2,n=r?.maxLength??80,i=new WeakSet;function s(o,l){if(typeof o=="function")return`[Fn:${o.name||"?"}]`;if(typeof o=="symbol")return o.toString();if(l>t)return o&&typeof o=="object"?"[...]":o;if(o===null||typeof o!="object")return o;if(o instanceof Map)return`{Map(${o.size})}`;if(o instanceof Set)return`{Set(${o.size})}`;if(o instanceof Date)return o.toISOString();if(o instanceof RegExp)return o.toString();if(i.has(o))return"[Circular]";if(i.add(o),Array.isArray(o))return o.map(u=>s(u,l+1));let T={};for(let u of Object.keys(o)){let $=o[u];T[u]=s($,l+1)}return T}try{let o=JSON.stringify(s(e,0));return o&&o.length>n?o.slice(0,n)+"\u2026":o}catch{return"[Unserializable]"}}var de=()=>typeof process<"u"&&process.versions!==void 0&&process.versions.node!==void 0,ue=()=>typeof EdgeRuntime<"u",fe=()=>typeof caches<"u"&&"default"in caches,pe=()=>typeof window<"u"||typeof self<"u";function Y(){return de()?"node":ue()||fe()?"edge":pe()?"browser":"node"}var me="\x1B[0m",we="\x1B[32m",ge="\x1B[31m";var xe="\x1B[36m";var Fe="\x1B[2m";function he(){return!(Y()==="browser"||typeof process<"u"&&process.env?.NO_COLOR)}var _e=he();function v(e,r){return _e?`${r}${e}${me}`:e}function L(e){return v(e,we)}function E(e){return v(e,ge)}function K(e){return v(e,xe)}function P(e){return v(e,Fe)}function Q(e,r){if(r===void 0)return"\u2014";let t=Math.round(r-e);return t>=1e3?`${(t/1e3).toFixed(1)}s`:`${t}ms`}function V(e,r,t){let n=" ".repeat(r);t.push(`${n}${K("\u2192")} ${e.name}`),e.data!==void 0&&t.push(`${n} ${P("data:")} ${p(e.data,{maxLength:80})}`);let i=Q(e.start,e.end);e.status==="success"?t.push(`${n}${L("\u2713")} ${e.name} (${i})`):e.status==="error"?t.push(`${n}${E("\u2717")} ${e.name} (error: ${e.error?.message??"Unknown error"})`):t.push(`${n} ${e.name} (${i})`);for(let s of e.children)V(s,r+1,t)}var S=class{constructor(){this.name="console"}render(r){let t=[],n=r.tags.length>0?` [${r.tags.join(", ")}]`:"",i=r.status==="error"?"\u{1F525}":"\u{1F680}";t.push(`${i} [flow:${r.name}]${n} (${P("tid:")} ${r.id})`);for(let l of r.steps)V(l,1,t);let s=Q(r.start,r.end),o=r.meta?.maxStepsExceeded?` ${E("\u26A0\uFE0F maxSteps exceeded")}`:"";r.status==="error"?(t.push(`\u{1F3C1} [flow:${r.name}] ${E("failed")} (${s}, error: ${r.error?.message??"Unknown error"})${o}`),console.error(t.join(`
2
- `))):(t.push(`\u{1F3C1} [flow:${r.name}] ${L("success")} (${s})${o}`),console.log(t.join(`
3
- `)))}};var D=null;function G(e){D=e}function A(){return D}function X(e){return D??e}var B=new h,M=new _,Te=new S,W=!0;function b(e){W=e}function x(){return W}function Z(e){B=e}function j(e){M=e}function k(e,r){if(!W)return c;let t=r?.sample??1;if(t<1&&Math.random()>t)return c;if(r?.enabled===!1)return c;let n=X(Te),i={id:B.generate(),name:e,state:"running",tags:r?.tags??[],start:M.now(),context:r?.initialContext?{...r.initialContext}:{},steps:[]};return new C(i,M,B,n,r??{})}function ye(e){return e!==null&&typeof e=="object"&&("flow"in e||"tags"in e)}function Re(e,r,t){if(r.current&&t===void 0&&!r.current.completed)return r.current.flow;let n=t??e.flowName,i=k(n,{tags:[...e.defaultTags]});return r.current={flow:i,timer:null,lastError:null,completed:!1},i}function Oe(e,r){r.current&&(r.current.timer&&clearTimeout(r.current.timer),r.current.timer=setTimeout(()=>{ee(r)},e.idleTimeout))}function ee(e){!e.current||e.current.completed||(e.current.timer&&(clearTimeout(e.current.timer),e.current.timer=null),e.current.completed=!0,e.current.lastError?e.current.flow.fail(e.current.lastError):e.current.flow.success(),e.current=null)}function N(e,r,t,n,i,s){if(!x())return;let o,l;n===void 0?(o=void 0,l=void 0):ye(n)?i===void 0?(o=void 0,l=n):(o=void 0,l={...n,...i}):(o=n,l=i);let T=l?.flow,u=Re(e,r,T);if(l?.tags)for(let te of l.tags)u.tag(te);let $=s&&s!=="info"?`${t} [${s}]`:t,q=u.step($,o);s==="error"?(q.fail(o),r.current&&(r.current.lastError=o),u.tag("error")):(q.success(),s&&s!=="info"&&u.tag(s)),Oe(e,r)}var w={idleTimeout:100,flowName:"default",defaultTags:[]},F={current:null};function a(e,r,t){N(w,F,e,r,t)}a.info=(e,r,t)=>N(w,F,e,r,t,"info");a.warn=(e,r,t)=>N(w,F,e,r,t,"warn");a.error=(e,r,t)=>N(w,F,e,r,t,"error");a.setIdleTimeout=e=>{w.idleTimeout=e};a.setFlowName=e=>{w.flowName=e};a.setDefaultTags=e=>{w.defaultTags=e};a.activeFlow=()=>F.current?.flow??null;a.flush=()=>{ee(F)};var d=(e,r,t)=>{a(e,r,t)};d.log=a;d.flow=(e,r)=>k(e,r);d.setIdleTimeout=a.setIdleTimeout;d.setFlowName=a.setFlowName;d.setDefaultTags=a.setDefaultTags;d.activeFlow=a.activeFlow;d.flush=a.flush;d.setEnabled=b;d.isEnabled=x;function Ce(e){return typeof e=="object"&&e!==null&&"trace"in e&&typeof e.trace=="object"&&e.trace!==null}function J(e){let r=Ce(e)?e.trace:e;return JSON.stringify({version:1,flow:{id:r.id,name:r.name,...r.parentId!==void 0&&{parentId:r.parentId},state:r.state,...r.status!==void 0&&{status:r.status},tags:r.tags,start:r.start,...r.end!==void 0&&{end:r.end},...r.error!==void 0&&{error:r.error},context:r.context,steps:r.steps.map(re),...r.meta!==void 0&&{meta:r.meta}}},null,2)}function re(e){let r={id:e.id,name:e.name,sequence:e.sequence,state:e.state,status:e.status,start:e.start};if(e.end!==void 0&&(r.end=e.end),e.data!==void 0)try{r.data=JSON.parse(p(e.data))}catch{r.data="[Circular or unserializable]"}return e.error!==void 0&&(r.error=e.error),e.children.length>0&&(r.children=e.children.map(re)),r}0&&(module.exports={NOOP_FLOW,NOOP_STEP,better,createFlow,getRenderer,isEnabled,normalizeError,safeSerialize,setClock,setEnabled,setIdGenerator,setRenderer,subscribe,toJSON});
1
+ "use strict";var I=Object.defineProperty;var oe=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var se=Object.prototype.hasOwnProperty;var ae=(e,r)=>{for(var t in r)I(e,t,{get:r[t],enumerable:!0})},ce=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of ie(r))!se.call(e,o)&&o!==t&&I(e,o,{get:()=>r[o],enumerable:!(n=oe(r,o))||n.enumerable});return e};var le=e=>ce(I({},"__esModule",{value:!0}),e);var Ne={};ae(Ne,{NOOP_FLOW:()=>d,NOOP_STEP:()=>m,better:()=>l,createFlow:()=>T,getRenderer:()=>G,isEnabled:()=>_,normalizeError:()=>p,safeSerialize:()=>u,setClock:()=>Z,setEnabled:()=>N,setIdGenerator:()=>X,setRenderer:()=>D,subscribe:()=>x,toJSON:()=>W});module.exports=le(Ne);function p(e){return e===void 0?{name:"Error",message:"Unknown error"}:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e=="string"?{name:"Error",message:e}:{name:"Error",message:String(e)}}var R=class{constructor(r,t){this._trace=r;this._clock=t;this._completed=!1}get isCompleted(){return this._completed}get trace(){return this._trace}success(){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="success")}fail(r){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="error",this._trace.error=p(r))}};var g=()=>{},m={success:g,fail:g},d={step:()=>m,child:()=>d,tag:g,tags:()=>[],setContext:g,getContext:()=>({}),success:g,fail:g,run:(e,r)=>{try{let t=r();return t instanceof Promise?t:Promise.resolve(t)}catch(t){return Promise.reject(t)}}};function q(e){let r=new WeakMap;function t(n){if(n===null||typeof n!="object")return n;if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(r.has(n))return r.get(n);if(Array.isArray(n)){let s=[];r.set(n,s);for(let i=0;i<n.length;i++)s.push(t(n[i]));return s}let o={};r.set(n,o);for(let s of Object.keys(n))o[s]=t(n[s]);return o}return t(e)}function O(e){if(e===null||typeof e!="object")return e;if(Object.freeze(e),Array.isArray(e))for(let r of e)O(r);else for(let r of Object.keys(e)){let t=e[r];t&&typeof t=="object"&&!Object.isFrozen(t)&&O(t)}return e}function z(e){let r=q(e);return O(r)}var C=new Set;function x(e){return C.add(e),()=>{C.delete(e)}}function de(e){if(C.size!==0)for(let r of C)try{r(e)}catch{}}var b=class e{constructor(r,t,n,o,s){this._trace=r;this._clock=t;this._idGen=n;this._renderer=o;this._options=s;this._completed=!1;this._sequence=0}get isCompleted(){return this._completed}get trace(){return this._trace}step(r,t){if(this._completed)return m;let n=this._options.maxSteps;if(n!==void 0&&this._trace.steps.length>=n)return this._trace.meta===void 0?this._trace.meta={maxStepsExceeded:!0}:this._trace.meta.maxStepsExceeded=!0,m;let o={id:this._idGen.generate(),name:r,sequence:this._sequence++,state:"running",status:"pending",start:this._clock.now(),data:t,children:[]};return this._trace.steps.push(o),new R(o,this._clock)}child(r){if(this._completed)return d;if(this._options.enabled===!1)return d;let t={id:this._idGen.generate(),name:r,parentId:this._trace.id,state:"running",status:void 0,tags:[],start:this._clock.now(),context:{...this._trace.context},steps:[]};return new e(t,this._clock,this._idGen,this._renderer,{...this._options})}tag(r){this._completed||this._trace.tags.includes(r)||this._trace.tags.push(r)}tags(){return[...this._trace.tags]}setContext(r){this._completed||Object.assign(this._trace.context,r)}getContext(){return{...this._trace.context}}success(){this._finalize("success")}fail(r){this._trace.error=p(r),this._finalize("error")}run(r,t){if(this._completed)return Promise.resolve(t());let n=this.step(r);return Promise.resolve(t()).then(o=>(n.success(),o),o=>{throw n.fail(o),o})}_finalize(r){if(this._completed)return;this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status=r;let t=z(this._trace);de(t),this._renderer.render(t)}};var h=class{generate(){return Math.random().toString(36).slice(2,10)}};var F=class{now(){return Date.now()}};function u(e,r){let t=r?.maxDepth??2,n=r?.maxLength??80,o=new WeakSet;function s(i,f){if(typeof i=="function")return`[Fn:${i.name||"?"}]`;if(typeof i=="symbol")return i.toString();if(f>t)return i&&typeof i=="object"?"[...]":i;if(i===null||typeof i!="object")return i;if(i instanceof Map)return`{Map(${i.size})}`;if(i instanceof Set)return`{Set(${i.size})}`;if(i instanceof Date)return i.toISOString();if(i instanceof RegExp)return i.toString();if(o.has(i))return"[Circular]";if(o.add(i),Array.isArray(i))return i.map(k=>s(k,f+1));let S={};for(let k of Object.keys(i)){let ne=i[k];S[k]=s(ne,f+1)}return S}try{let i=JSON.stringify(s(e,0));return i&&i.length>n?i.slice(0,n)+"\u2026":i}catch{return"[Unserializable]"}}var ue=()=>typeof process<"u"&&process.versions!==void 0&&process.versions.node!==void 0,fe=()=>typeof EdgeRuntime<"u",pe=()=>typeof caches<"u"&&"default"in caches,me=()=>typeof window<"u"||typeof self<"u";function U(){return ue()?"node":fe()||pe()?"edge":me()?"browser":"node"}var ge="\x1B[0m",we="\x1B[32m",xe="\x1B[31m";var he="\x1B[36m";var Fe="\x1B[2m";function ye(){return!(U()==="browser"||typeof process<"u"&&process.env?.NO_COLOR)}var _e=ye();function v(e,r){return _e?`${r}${e}${ge}`:e}function H(e){return v(e,we)}function E(e){return v(e,xe)}function Y(e){return v(e,he)}function L(e){return v(e,Fe)}function K(e,r){if(r===void 0)return"\u2014";let t=Math.round(r-e);return t>=1e3?`${(t/1e3).toFixed(1)}s`:`${t}ms`}function Q(e,r,t){let n=" ".repeat(r);t.push(`${n}${Y("\u2192")} ${e.name}`),e.data!==void 0&&t.push(`${n} ${L("data:")} ${u(e.data,{maxLength:80})}`);let o=K(e.start,e.end);e.status==="success"?t.push(`${n}${H("\u2713")} ${e.name} (${o})`):e.status==="error"?t.push(`${n}${E("\u2717")} ${e.name} (error: ${e.error?.message??"Unknown error"})`):t.push(`${n} ${e.name} (${o})`);for(let s of e.children)Q(s,r+1,t)}var y=class{constructor(){this.name="console"}render(r){let t=[],n=r.tags.length>0?` [${r.tags.join(", ")}]`:"",o=r.status==="error"?"\u{1F525}":"\u{1F680}";t.push(`${o} [flow:${r.name}]${n} (${L("tid:")} ${r.id})`);for(let f of r.steps)Q(f,1,t);let s=K(r.start,r.end),i=r.meta?.maxStepsExceeded?` ${E("\u26A0\uFE0F maxSteps exceeded")}`:"";r.status==="error"?(t.push(`\u{1F3C1} [flow:${r.name}] ${E("failed")} (${s}, error: ${r.error?.message??"Unknown error"})${i}`),console.error(t.join(`
2
+ `))):(t.push(`\u{1F3C1} [flow:${r.name}] ${H("success")} (${s})${i}`),console.log(t.join(`
3
+ `)))}};var P=null;function D(e){P=e}function G(){return P}function V(e){return P??e}var A=new h,B=new F,ke=new y,M=!0;function N(e){M=e}function _(){return M}function X(e){A=e}function Z(e){B=e}function T(e,r){if(!M)return d;let t=r?.sample??1;if(t<1&&Math.random()>t)return d;if(r?.enabled===!1)return d;let n=V(ke),o={id:A.generate(),name:e,state:"running",tags:r?.tags??[],start:B.now(),context:r?.initialContext?{...r.initialContext}:{},steps:[]};return new b(o,B,A,n,r??{})}function Re(e){return e!==null&&typeof e=="object"&&("flow"in e||"tags"in e)}function Oe(e,r,t){if(r.current&&t===void 0&&!r.current.completed)return r.current.flow;let n=t??e.flowName,o=T(n,{tags:[...e.defaultTags]});return r.current={flow:o,timer:null,lastError:null,completed:!1},o}function Ce(e,r){r.current&&(r.current.timer&&clearTimeout(r.current.timer),r.current.timer=setTimeout(()=>{j(r)},e.idleTimeout))}function j(e){!e.current||e.current.completed||(e.current.timer&&(clearTimeout(e.current.timer),e.current.timer=null),e.current.completed=!0,e.current.lastError?e.current.flow.fail(e.current.lastError):e.current.flow.success(),e.current=null)}function be(e,r){if(!e||typeof e!="object"||r.length===0)return e;let t={...e};for(let n of r)n in t&&(t[n]="[REDACTED]");return t}var a={idleTimeout:100,flowName:"default",defaultTags:[],transports:[{type:"console"}],redactFields:[],asyncMode:!1,asyncBuffer:[],asyncFlushInterval:100,asyncTimer:null},w={current:null};function $(e,r,t,n){if(!_())return;let o,s;if(r===void 0?(o=void 0,s=void 0):Re(r)?t===void 0?(o=void 0,s=r):(o=void 0,s={...r,...t}):(o=r,s=t),a.redactFields.length>0&&o&&typeof o=="object"&&(o=be(o,a.redactFields)),a.asyncMode){a.asyncBuffer.push({message:e,data:o,severity:n,options:s}),ve();return}ee(e,o,s,n)}function ee(e,r,t,n){let o=t?.flow,s=Oe(a,w,o);if(t?.tags)for(let S of t.tags)s.tag(S);let i=n&&n!=="info"?`${e} [${n}]`:e,f=s.step(i,r);n==="error"?(f.fail(r),w.current&&(w.current.lastError=r),s.tag("error")):(f.success(),n&&n!=="info"&&s.tag(n)),Ce(a,w)}function ve(){a.asyncTimer||(a.asyncTimer=setTimeout(()=>{J()},a.asyncFlushInterval))}function J(){a.asyncTimer&&(clearTimeout(a.asyncTimer),a.asyncTimer=null);let e=[...a.asyncBuffer];a.asyncBuffer=[];for(let r of e)ee(r.message,r.data,r.options,r.severity)}function c(e,r,t){$(e,r,t)}c.info=(e,r,t)=>$(e,r,t,"info");c.warn=(e,r,t)=>$(e,r,t,"warn");c.error=(e,r,t)=>$(e,r,t,"error");c.toFile=(e,r)=>{let t=r?.append?"a":"w";a.transports.push({type:"file",target:e,options:{flag:t}})};c.toStream=e=>{a.transports.push({type:"stream",target:e})};c.toHttp=(e,r)=>{a.transports.push({type:"http",target:e,options:r})};c.redact=e=>{a.redactFields=e};c.async=(e=!0)=>{a.asyncMode=e,e||J()};c.setIdleTimeout=e=>{a.idleTimeout=e};c.setFlowName=e=>{a.flowName=e};c.setDefaultTags=e=>{a.defaultTags=e};c.activeFlow=()=>w.current?.flow??null;c.flush=()=>{j(w),J()};function l(e,r,t){c(e,r,t)}l.log=c;l.flow=(e,r)=>T(e,r);l.setIdleTimeout=c.setIdleTimeout;l.setFlowName=c.setFlowName;l.setDefaultTags=c.setDefaultTags;l.activeFlow=c.activeFlow;l.flush=c.flush;l.setEnabled=N;l.isEnabled=_;l.subscribe=x;l.toJSON=e=>{let r="trace"in e?e.trace:e;return JSON.stringify({version:1,flow:{id:r.id,name:r.name,...r.parentId!==void 0&&{parentId:r.parentId},state:r.state,...r.status!==void 0&&{status:r.status},tags:r.tags,start:r.start,...r.end!==void 0&&{end:r.end},...r.error!==void 0&&{error:r.error},context:r.context,steps:r.steps.map(re),...r.meta!==void 0&&{meta:r.meta}}},null,2)};function re(e){let r={id:e.id,name:e.name,sequence:e.sequence,state:e.state,status:e.status,start:e.start};if(e.end!==void 0&&(r.end=e.end),e.data!==void 0)try{r.data=JSON.parse(u(e.data))}catch{r.data="[Circular or unserializable]"}return e.error!==void 0&&(r.error=e.error),e.children.length>0&&(r.children=e.children.map(re)),r}function Ee(e){return typeof e=="object"&&e!==null&&"trace"in e&&typeof e.trace=="object"&&e.trace!==null}function W(e){let r=Ee(e)?e.trace:e;return JSON.stringify({version:1,flow:{id:r.id,name:r.name,...r.parentId!==void 0&&{parentId:r.parentId},state:r.state,...r.status!==void 0&&{status:r.status},tags:r.tags,start:r.start,...r.end!==void 0&&{end:r.end},...r.error!==void 0&&{error:r.error},context:r.context,steps:r.steps.map(te),...r.meta!==void 0&&{meta:r.meta}}},null,2)}function te(e){let r={id:e.id,name:e.name,sequence:e.sequence,state:e.state,status:e.status,start:e.start};if(e.end!==void 0&&(r.end=e.end),e.data!==void 0)try{r.data=JSON.parse(u(e.data))}catch{r.data="[Circular or unserializable]"}return e.error!==void 0&&(r.error=e.error),e.children.length>0&&(r.children=e.children.map(te)),r}0&&(module.exports={NOOP_FLOW,NOOP_STEP,better,createFlow,getRenderer,isEnabled,normalizeError,safeSerialize,setClock,setEnabled,setIdGenerator,setRenderer,subscribe,toJSON});
package/dist/index.d.cts CHANGED
@@ -170,26 +170,31 @@ declare function setClock(clock: Clock): void;
170
170
  declare function createFlow<Data = unknown>(name: string, options?: FlowOptions): FlowHandle<Data>;
171
171
 
172
172
  /**
173
- * V3: Zero-Friction better.log API
173
+ * V3+: Zero-Friction better.log API — Unified Entry Point
174
174
  *
175
- * Drop-in console.log replacement with auto-flow management.
175
+ * Core API (≤ 5 functions):
176
+ * better.log() — Drop-in for console.log
177
+ * better.flow() — Explicit flows
178
+ * better.setEnabled() — Global toggle
179
+ * better.subscribe() — Flow completion events
180
+ * better.toJSON() — Export flow as JSON
176
181
  *
177
- * Usage:
178
- * better.log('message')
179
- * better.log('message', data)
180
- * better.log.warn('warning', data)
181
- * better.log.error('error', error)
182
- * better.flow('explicit-flow', { tags: ['auth'] })
182
+ * Transports (Phase 3):
183
+ * better.log.toFile() — File transport (zero-dep)
184
+ * better.log.toStream() — Stream transport
185
+ * better.log.toHttp() — HTTP transport
186
+ *
187
+ * Production Features (Phase 3):
188
+ * better.log.redact() — PII redaction
189
+ * better.log.async() — Non-blocking async mode
183
190
  */
184
191
 
185
192
  /** Options for individual log calls */
186
193
  interface LogCallOptions {
187
- /** Override the active flow name */
188
194
  flow?: string;
189
- /** Additional tags for this step */
190
195
  tags?: string[];
191
196
  }
192
- /** Options for creating an explicit flow via better.flow() */
197
+ /** Options for creating an explicit flow */
193
198
  interface BetterFlowOptions {
194
199
  tags?: string[];
195
200
  maxSteps?: number;
@@ -201,24 +206,36 @@ declare namespace logFn {
201
206
  var info: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void;
202
207
  var warn: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void;
203
208
  var error: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void;
209
+ var toFile: (path: string, options?: {
210
+ append?: boolean;
211
+ }) => void;
212
+ var toStream: (stream: NodeJS.WriteStream) => void;
213
+ var toHttp: (url: string, options?: {
214
+ method?: string;
215
+ headers?: Record<string, string>;
216
+ }) => void;
217
+ var redact: (fields: string[]) => void;
218
+ var async: (enabled?: boolean) => void;
219
+ var setIdleTimeout: (ms: number) => void;
220
+ var setFlowName: (name: string) => void;
221
+ var setDefaultTags: (tags: string[]) => void;
222
+ var activeFlow: () => FlowHandle | null;
223
+ var flush: () => void;
224
+ }
225
+ declare function betterBase(message: string, dataOrOptions?: unknown, options?: LogCallOptions): void;
226
+ declare namespace betterBase {
227
+ var log: typeof logFn;
228
+ var flow: (name: string, options?: BetterFlowOptions) => FlowHandle;
204
229
  var setIdleTimeout: (ms: number) => void;
205
230
  var setFlowName: (name: string) => void;
206
231
  var setDefaultTags: (tags: string[]) => void;
207
232
  var activeFlow: () => FlowHandle | null;
208
233
  var flush: () => void;
234
+ var setEnabled: typeof setEnabled;
235
+ var isEnabled: typeof isEnabled;
236
+ var subscribe: typeof subscribe;
237
+ var toJSON: (flow: FlowHandle | FlowTrace) => string;
209
238
  }
210
- declare const betterBase: {
211
- (message: string, dataOrOptions?: unknown, options?: LogCallOptions): void;
212
- log: typeof logFn;
213
- flow(name: string, options?: BetterFlowOptions): FlowHandle;
214
- setIdleTimeout: (ms: number) => void;
215
- setFlowName: (name: string) => void;
216
- setDefaultTags: (tags: string[]) => void;
217
- activeFlow: () => FlowHandle | null;
218
- flush: () => void;
219
- setEnabled: typeof setEnabled;
220
- isEnabled: typeof isEnabled;
221
- };
222
239
 
223
240
  /** Contract for all renderer implementations */
224
241
  interface FlowRenderer {
package/dist/index.d.ts CHANGED
@@ -170,26 +170,31 @@ declare function setClock(clock: Clock): void;
170
170
  declare function createFlow<Data = unknown>(name: string, options?: FlowOptions): FlowHandle<Data>;
171
171
 
172
172
  /**
173
- * V3: Zero-Friction better.log API
173
+ * V3+: Zero-Friction better.log API — Unified Entry Point
174
174
  *
175
- * Drop-in console.log replacement with auto-flow management.
175
+ * Core API (≤ 5 functions):
176
+ * better.log() — Drop-in for console.log
177
+ * better.flow() — Explicit flows
178
+ * better.setEnabled() — Global toggle
179
+ * better.subscribe() — Flow completion events
180
+ * better.toJSON() — Export flow as JSON
176
181
  *
177
- * Usage:
178
- * better.log('message')
179
- * better.log('message', data)
180
- * better.log.warn('warning', data)
181
- * better.log.error('error', error)
182
- * better.flow('explicit-flow', { tags: ['auth'] })
182
+ * Transports (Phase 3):
183
+ * better.log.toFile() — File transport (zero-dep)
184
+ * better.log.toStream() — Stream transport
185
+ * better.log.toHttp() — HTTP transport
186
+ *
187
+ * Production Features (Phase 3):
188
+ * better.log.redact() — PII redaction
189
+ * better.log.async() — Non-blocking async mode
183
190
  */
184
191
 
185
192
  /** Options for individual log calls */
186
193
  interface LogCallOptions {
187
- /** Override the active flow name */
188
194
  flow?: string;
189
- /** Additional tags for this step */
190
195
  tags?: string[];
191
196
  }
192
- /** Options for creating an explicit flow via better.flow() */
197
+ /** Options for creating an explicit flow */
193
198
  interface BetterFlowOptions {
194
199
  tags?: string[];
195
200
  maxSteps?: number;
@@ -201,24 +206,36 @@ declare namespace logFn {
201
206
  var info: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void;
202
207
  var warn: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void;
203
208
  var error: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void;
209
+ var toFile: (path: string, options?: {
210
+ append?: boolean;
211
+ }) => void;
212
+ var toStream: (stream: NodeJS.WriteStream) => void;
213
+ var toHttp: (url: string, options?: {
214
+ method?: string;
215
+ headers?: Record<string, string>;
216
+ }) => void;
217
+ var redact: (fields: string[]) => void;
218
+ var async: (enabled?: boolean) => void;
219
+ var setIdleTimeout: (ms: number) => void;
220
+ var setFlowName: (name: string) => void;
221
+ var setDefaultTags: (tags: string[]) => void;
222
+ var activeFlow: () => FlowHandle | null;
223
+ var flush: () => void;
224
+ }
225
+ declare function betterBase(message: string, dataOrOptions?: unknown, options?: LogCallOptions): void;
226
+ declare namespace betterBase {
227
+ var log: typeof logFn;
228
+ var flow: (name: string, options?: BetterFlowOptions) => FlowHandle;
204
229
  var setIdleTimeout: (ms: number) => void;
205
230
  var setFlowName: (name: string) => void;
206
231
  var setDefaultTags: (tags: string[]) => void;
207
232
  var activeFlow: () => FlowHandle | null;
208
233
  var flush: () => void;
234
+ var setEnabled: typeof setEnabled;
235
+ var isEnabled: typeof isEnabled;
236
+ var subscribe: typeof subscribe;
237
+ var toJSON: (flow: FlowHandle | FlowTrace) => string;
209
238
  }
210
- declare const betterBase: {
211
- (message: string, dataOrOptions?: unknown, options?: LogCallOptions): void;
212
- log: typeof logFn;
213
- flow(name: string, options?: BetterFlowOptions): FlowHandle;
214
- setIdleTimeout: (ms: number) => void;
215
- setFlowName: (name: string) => void;
216
- setDefaultTags: (tags: string[]) => void;
217
- activeFlow: () => FlowHandle | null;
218
- flush: () => void;
219
- setEnabled: typeof setEnabled;
220
- isEnabled: typeof isEnabled;
221
- };
222
239
 
223
240
  /** Contract for all renderer implementations */
224
241
  interface FlowRenderer {
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- function f(e){return e===void 0?{name:"Error",message:"Unknown error"}:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e=="string"?{name:"Error",message:e}:{name:"Error",message:String(e)}}var T=class{constructor(r,t){this._trace=r;this._clock=t;this._completed=!1}get isCompleted(){return this._completed}get trace(){return this._trace}success(){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="success")}fail(r){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="error",this._trace.error=f(r))}};var w=()=>{},g={success:w,fail:w},c={step:()=>g,child:()=>c,tag:w,tags:()=>[],setContext:w,getContext:()=>({}),success:w,fail:w,run:(e,r)=>{try{let t=r();return t instanceof Promise?t:Promise.resolve(t)}catch(t){return Promise.reject(t)}}};function B(e){let r=new WeakMap;function t(n){if(n===null||typeof n!="object")return n;if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(r.has(n))return r.get(n);if(Array.isArray(n)){let s=[];r.set(n,s);for(let o=0;o<n.length;o++)s.push(t(n[o]));return s}let i={};r.set(n,i);for(let s of Object.keys(n))i[s]=t(n[s]);return i}return t(e)}function y(e){if(e===null||typeof e!="object")return e;if(Object.freeze(e),Array.isArray(e))for(let r of e)y(r);else for(let r of Object.keys(e)){let t=e[r];t&&typeof t=="object"&&!Object.isFrozen(t)&&y(t)}return e}function $(e){let r=B(e);return y(r)}var R=new Set;function M(e){return R.add(e),()=>{R.delete(e)}}function ee(e){if(R.size!==0)for(let r of R)try{r(e)}catch{}}var O=class e{constructor(r,t,n,i,s){this._trace=r;this._clock=t;this._idGen=n;this._renderer=i;this._options=s;this._completed=!1;this._sequence=0}get isCompleted(){return this._completed}get trace(){return this._trace}step(r,t){if(this._completed)return g;let n=this._options.maxSteps;if(n!==void 0&&this._trace.steps.length>=n)return this._trace.meta===void 0?this._trace.meta={maxStepsExceeded:!0}:this._trace.meta.maxStepsExceeded=!0,g;let i={id:this._idGen.generate(),name:r,sequence:this._sequence++,state:"running",status:"pending",start:this._clock.now(),data:t,children:[]};return this._trace.steps.push(i),new T(i,this._clock)}child(r){if(this._completed)return c;if(this._options.enabled===!1)return c;let t={id:this._idGen.generate(),name:r,parentId:this._trace.id,state:"running",status:void 0,tags:[],start:this._clock.now(),context:{...this._trace.context},steps:[]};return new e(t,this._clock,this._idGen,this._renderer,{...this._options})}tag(r){this._completed||this._trace.tags.includes(r)||this._trace.tags.push(r)}tags(){return[...this._trace.tags]}setContext(r){this._completed||Object.assign(this._trace.context,r)}getContext(){return{...this._trace.context}}success(){this._finalize("success")}fail(r){this._trace.error=f(r),this._finalize("error")}run(r,t){if(this._completed)return Promise.resolve(t());let n=this.step(r);return Promise.resolve(t()).then(i=>(n.success(),i),i=>{throw n.fail(i),i})}_finalize(r){if(this._completed)return;this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status=r;let t=$(this._trace);ee(t),this._renderer.render(t)}};var F=class{generate(){return Math.random().toString(36).slice(2,10)}};var h=class{now(){return Date.now()}};function p(e,r){let t=r?.maxDepth??2,n=r?.maxLength??80,i=new WeakSet;function s(o,l){if(typeof o=="function")return`[Fn:${o.name||"?"}]`;if(typeof o=="symbol")return o.toString();if(l>t)return o&&typeof o=="object"?"[...]":o;if(o===null||typeof o!="object")return o;if(o instanceof Map)return`{Map(${o.size})}`;if(o instanceof Set)return`{Set(${o.size})}`;if(o instanceof Date)return o.toISOString();if(o instanceof RegExp)return o.toString();if(i.has(o))return"[Circular]";if(i.add(o),Array.isArray(o))return o.map(u=>s(u,l+1));let k={};for(let u of Object.keys(o)){let N=o[u];k[u]=s(N,l+1)}return k}try{let o=JSON.stringify(s(e,0));return o&&o.length>n?o.slice(0,n)+"\u2026":o}catch{return"[Unserializable]"}}var re=()=>typeof process<"u"&&process.versions!==void 0&&process.versions.node!==void 0,te=()=>typeof EdgeRuntime<"u",ne=()=>typeof caches<"u"&&"default"in caches,oe=()=>typeof window<"u"||typeof self<"u";function W(){return re()?"node":te()||ne()?"edge":oe()?"browser":"node"}var ie="\x1B[0m",se="\x1B[32m",ae="\x1B[31m";var le="\x1B[36m";var ce="\x1B[2m";function de(){return!(W()==="browser"||typeof process<"u"&&process.env?.NO_COLOR)}var ue=de();function C(e,r){return ue?`${r}${e}${ie}`:e}function I(e){return C(e,se)}function v(e){return C(e,ae)}function J(e){return C(e,le)}function z(e){return C(e,ce)}function q(e,r){if(r===void 0)return"\u2014";let t=Math.round(r-e);return t>=1e3?`${(t/1e3).toFixed(1)}s`:`${t}ms`}function U(e,r,t){let n=" ".repeat(r);t.push(`${n}${J("\u2192")} ${e.name}`),e.data!==void 0&&t.push(`${n} ${z("data:")} ${p(e.data,{maxLength:80})}`);let i=q(e.start,e.end);e.status==="success"?t.push(`${n}${I("\u2713")} ${e.name} (${i})`):e.status==="error"?t.push(`${n}${v("\u2717")} ${e.name} (error: ${e.error?.message??"Unknown error"})`):t.push(`${n} ${e.name} (${i})`);for(let s of e.children)U(s,r+1,t)}var _=class{constructor(){this.name="console"}render(r){let t=[],n=r.tags.length>0?` [${r.tags.join(", ")}]`:"",i=r.status==="error"?"\u{1F525}":"\u{1F680}";t.push(`${i} [flow:${r.name}]${n} (${z("tid:")} ${r.id})`);for(let l of r.steps)U(l,1,t);let s=q(r.start,r.end),o=r.meta?.maxStepsExceeded?` ${v("\u26A0\uFE0F maxSteps exceeded")}`:"";r.status==="error"?(t.push(`\u{1F3C1} [flow:${r.name}] ${v("failed")} (${s}, error: ${r.error?.message??"Unknown error"})${o}`),console.error(t.join(`
2
- `))):(t.push(`\u{1F3C1} [flow:${r.name}] ${I("success")} (${s})${o}`),console.log(t.join(`
3
- `)))}};var H=null;function Y(e){H=e}function K(){return H}function Q(e){return H??e}var L=new F,P=new h,me=new _,D=!0;function G(e){D=e}function S(){return D}function we(e){L=e}function ge(e){P=e}function E(e,r){if(!D)return c;let t=r?.sample??1;if(t<1&&Math.random()>t)return c;if(r?.enabled===!1)return c;let n=Q(me),i={id:L.generate(),name:e,state:"running",tags:r?.tags??[],start:P.now(),context:r?.initialContext?{...r.initialContext}:{},steps:[]};return new O(i,P,L,n,r??{})}function xe(e){return e!==null&&typeof e=="object"&&("flow"in e||"tags"in e)}function Fe(e,r,t){if(r.current&&t===void 0&&!r.current.completed)return r.current.flow;let n=t??e.flowName,i=E(n,{tags:[...e.defaultTags]});return r.current={flow:i,timer:null,lastError:null,completed:!1},i}function he(e,r){r.current&&(r.current.timer&&clearTimeout(r.current.timer),r.current.timer=setTimeout(()=>{V(r)},e.idleTimeout))}function V(e){!e.current||e.current.completed||(e.current.timer&&(clearTimeout(e.current.timer),e.current.timer=null),e.current.completed=!0,e.current.lastError?e.current.flow.fail(e.current.lastError):e.current.flow.success(),e.current=null)}function b(e,r,t,n,i,s){if(!S())return;let o,l;n===void 0?(o=void 0,l=void 0):xe(n)?i===void 0?(o=void 0,l=n):(o=void 0,l={...n,...i}):(o=n,l=i);let k=l?.flow,u=Fe(e,r,k);if(l?.tags)for(let j of l.tags)u.tag(j);let N=s&&s!=="info"?`${t} [${s}]`:t,A=u.step(N,o);s==="error"?(A.fail(o),r.current&&(r.current.lastError=o),u.tag("error")):(A.success(),s&&s!=="info"&&u.tag(s)),he(e,r)}var m={idleTimeout:100,flowName:"default",defaultTags:[]},x={current:null};function a(e,r,t){b(m,x,e,r,t)}a.info=(e,r,t)=>b(m,x,e,r,t,"info");a.warn=(e,r,t)=>b(m,x,e,r,t,"warn");a.error=(e,r,t)=>b(m,x,e,r,t,"error");a.setIdleTimeout=e=>{m.idleTimeout=e};a.setFlowName=e=>{m.flowName=e};a.setDefaultTags=e=>{m.defaultTags=e};a.activeFlow=()=>x.current?.flow??null;a.flush=()=>{V(x)};var d=(e,r,t)=>{a(e,r,t)};d.log=a;d.flow=(e,r)=>E(e,r);d.setIdleTimeout=a.setIdleTimeout;d.setFlowName=a.setFlowName;d.setDefaultTags=a.setDefaultTags;d.activeFlow=a.activeFlow;d.flush=a.flush;d.setEnabled=G;d.isEnabled=S;function _e(e){return typeof e=="object"&&e!==null&&"trace"in e&&typeof e.trace=="object"&&e.trace!==null}function X(e){let r=_e(e)?e.trace:e;return JSON.stringify({version:1,flow:{id:r.id,name:r.name,...r.parentId!==void 0&&{parentId:r.parentId},state:r.state,...r.status!==void 0&&{status:r.status},tags:r.tags,start:r.start,...r.end!==void 0&&{end:r.end},...r.error!==void 0&&{error:r.error},context:r.context,steps:r.steps.map(Z),...r.meta!==void 0&&{meta:r.meta}}},null,2)}function Z(e){let r={id:e.id,name:e.name,sequence:e.sequence,state:e.state,status:e.status,start:e.start};if(e.end!==void 0&&(r.end=e.end),e.data!==void 0)try{r.data=JSON.parse(p(e.data))}catch{r.data="[Circular or unserializable]"}return e.error!==void 0&&(r.error=e.error),e.children.length>0&&(r.children=e.children.map(Z)),r}export{c as NOOP_FLOW,g as NOOP_STEP,d as better,E as createFlow,K as getRenderer,S as isEnabled,f as normalizeError,p as safeSerialize,ge as setClock,G as setEnabled,we as setIdGenerator,Y as setRenderer,M as subscribe,X as toJSON};
1
+ function p(e){return e===void 0?{name:"Error",message:"Unknown error"}:e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:typeof e=="string"?{name:"Error",message:e}:{name:"Error",message:String(e)}}var T=class{constructor(r,t){this._trace=r;this._clock=t;this._completed=!1}get isCompleted(){return this._completed}get trace(){return this._trace}success(){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="success")}fail(r){this._completed||(this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status="error",this._trace.error=p(r))}};var m=()=>{},g={success:m,fail:m},d={step:()=>g,child:()=>d,tag:m,tags:()=>[],setContext:m,getContext:()=>({}),success:m,fail:m,run:(e,r)=>{try{let t=r();return t instanceof Promise?t:Promise.resolve(t)}catch(t){return Promise.reject(t)}}};function B(e){let r=new WeakMap;function t(n){if(n===null||typeof n!="object")return n;if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(r.has(n))return r.get(n);if(Array.isArray(n)){let s=[];r.set(n,s);for(let i=0;i<n.length;i++)s.push(t(n[i]));return s}let o={};r.set(n,o);for(let s of Object.keys(n))o[s]=t(n[s]);return o}return t(e)}function S(e){if(e===null||typeof e!="object")return e;if(Object.freeze(e),Array.isArray(e))for(let r of e)S(r);else for(let r of Object.keys(e)){let t=e[r];t&&typeof t=="object"&&!Object.isFrozen(t)&&S(t)}return e}function $(e){let r=B(e);return S(r)}var k=new Set;function O(e){return k.add(e),()=>{k.delete(e)}}function re(e){if(k.size!==0)for(let r of k)try{r(e)}catch{}}var R=class e{constructor(r,t,n,o,s){this._trace=r;this._clock=t;this._idGen=n;this._renderer=o;this._options=s;this._completed=!1;this._sequence=0}get isCompleted(){return this._completed}get trace(){return this._trace}step(r,t){if(this._completed)return g;let n=this._options.maxSteps;if(n!==void 0&&this._trace.steps.length>=n)return this._trace.meta===void 0?this._trace.meta={maxStepsExceeded:!0}:this._trace.meta.maxStepsExceeded=!0,g;let o={id:this._idGen.generate(),name:r,sequence:this._sequence++,state:"running",status:"pending",start:this._clock.now(),data:t,children:[]};return this._trace.steps.push(o),new T(o,this._clock)}child(r){if(this._completed)return d;if(this._options.enabled===!1)return d;let t={id:this._idGen.generate(),name:r,parentId:this._trace.id,state:"running",status:void 0,tags:[],start:this._clock.now(),context:{...this._trace.context},steps:[]};return new e(t,this._clock,this._idGen,this._renderer,{...this._options})}tag(r){this._completed||this._trace.tags.includes(r)||this._trace.tags.push(r)}tags(){return[...this._trace.tags]}setContext(r){this._completed||Object.assign(this._trace.context,r)}getContext(){return{...this._trace.context}}success(){this._finalize("success")}fail(r){this._trace.error=p(r),this._finalize("error")}run(r,t){if(this._completed)return Promise.resolve(t());let n=this.step(r);return Promise.resolve(t()).then(o=>(n.success(),o),o=>{throw n.fail(o),o})}_finalize(r){if(this._completed)return;this._completed=!0,this._trace.end=this._clock.now(),this._trace.state="completed",this._trace.status=r;let t=$(this._trace);re(t),this._renderer.render(t)}};var x=class{generate(){return Math.random().toString(36).slice(2,10)}};var h=class{now(){return Date.now()}};function u(e,r){let t=r?.maxDepth??2,n=r?.maxLength??80,o=new WeakSet;function s(i,f){if(typeof i=="function")return`[Fn:${i.name||"?"}]`;if(typeof i=="symbol")return i.toString();if(f>t)return i&&typeof i=="object"?"[...]":i;if(i===null||typeof i!="object")return i;if(i instanceof Map)return`{Map(${i.size})}`;if(i instanceof Set)return`{Set(${i.size})}`;if(i instanceof Date)return i.toISOString();if(i instanceof RegExp)return i.toString();if(o.has(i))return"[Circular]";if(o.add(i),Array.isArray(i))return i.map(_=>s(_,f+1));let y={};for(let _ of Object.keys(i)){let ee=i[_];y[_]=s(ee,f+1)}return y}try{let i=JSON.stringify(s(e,0));return i&&i.length>n?i.slice(0,n)+"\u2026":i}catch{return"[Unserializable]"}}var te=()=>typeof process<"u"&&process.versions!==void 0&&process.versions.node!==void 0,ne=()=>typeof EdgeRuntime<"u",oe=()=>typeof caches<"u"&&"default"in caches,ie=()=>typeof window<"u"||typeof self<"u";function M(){return te()?"node":ne()||oe()?"edge":ie()?"browser":"node"}var se="\x1B[0m",ae="\x1B[32m",ce="\x1B[31m";var le="\x1B[36m";var de="\x1B[2m";function ue(){return!(M()==="browser"||typeof process<"u"&&process.env?.NO_COLOR)}var fe=ue();function C(e,r){return fe?`${r}${e}${se}`:e}function I(e){return C(e,ae)}function b(e){return C(e,ce)}function J(e){return C(e,le)}function z(e){return C(e,de)}function W(e,r){if(r===void 0)return"\u2014";let t=Math.round(r-e);return t>=1e3?`${(t/1e3).toFixed(1)}s`:`${t}ms`}function q(e,r,t){let n=" ".repeat(r);t.push(`${n}${J("\u2192")} ${e.name}`),e.data!==void 0&&t.push(`${n} ${z("data:")} ${u(e.data,{maxLength:80})}`);let o=W(e.start,e.end);e.status==="success"?t.push(`${n}${I("\u2713")} ${e.name} (${o})`):e.status==="error"?t.push(`${n}${b("\u2717")} ${e.name} (error: ${e.error?.message??"Unknown error"})`):t.push(`${n} ${e.name} (${o})`);for(let s of e.children)q(s,r+1,t)}var F=class{constructor(){this.name="console"}render(r){let t=[],n=r.tags.length>0?` [${r.tags.join(", ")}]`:"",o=r.status==="error"?"\u{1F525}":"\u{1F680}";t.push(`${o} [flow:${r.name}]${n} (${z("tid:")} ${r.id})`);for(let f of r.steps)q(f,1,t);let s=W(r.start,r.end),i=r.meta?.maxStepsExceeded?` ${b("\u26A0\uFE0F maxSteps exceeded")}`:"";r.status==="error"?(t.push(`\u{1F3C1} [flow:${r.name}] ${b("failed")} (${s}, error: ${r.error?.message??"Unknown error"})${i}`),console.error(t.join(`
2
+ `))):(t.push(`\u{1F3C1} [flow:${r.name}] ${I("success")} (${s})${i}`),console.log(t.join(`
3
+ `)))}};var H=null;function U(e){H=e}function Y(){return H}function K(e){return H??e}var L=new x,P=new h,ge=new F,D=!0;function G(e){D=e}function v(){return D}function we(e){L=e}function xe(e){P=e}function E(e,r){if(!D)return d;let t=r?.sample??1;if(t<1&&Math.random()>t)return d;if(r?.enabled===!1)return d;let n=K(ge),o={id:L.generate(),name:e,state:"running",tags:r?.tags??[],start:P.now(),context:r?.initialContext?{...r.initialContext}:{},steps:[]};return new R(o,P,L,n,r??{})}function he(e){return e!==null&&typeof e=="object"&&("flow"in e||"tags"in e)}function Fe(e,r,t){if(r.current&&t===void 0&&!r.current.completed)return r.current.flow;let n=t??e.flowName,o=E(n,{tags:[...e.defaultTags]});return r.current={flow:o,timer:null,lastError:null,completed:!1},o}function ye(e,r){r.current&&(r.current.timer&&clearTimeout(r.current.timer),r.current.timer=setTimeout(()=>{Q(r)},e.idleTimeout))}function Q(e){!e.current||e.current.completed||(e.current.timer&&(clearTimeout(e.current.timer),e.current.timer=null),e.current.completed=!0,e.current.lastError?e.current.flow.fail(e.current.lastError):e.current.flow.success(),e.current=null)}function _e(e,r){if(!e||typeof e!="object"||r.length===0)return e;let t={...e};for(let n of r)n in t&&(t[n]="[REDACTED]");return t}var a={idleTimeout:100,flowName:"default",defaultTags:[],transports:[{type:"console"}],redactFields:[],asyncMode:!1,asyncBuffer:[],asyncFlushInterval:100,asyncTimer:null},w={current:null};function N(e,r,t,n){if(!v())return;let o,s;if(r===void 0?(o=void 0,s=void 0):he(r)?t===void 0?(o=void 0,s=r):(o=void 0,s={...r,...t}):(o=r,s=t),a.redactFields.length>0&&o&&typeof o=="object"&&(o=_e(o,a.redactFields)),a.asyncMode){a.asyncBuffer.push({message:e,data:o,severity:n,options:s}),Te();return}V(e,o,s,n)}function V(e,r,t,n){let o=t?.flow,s=Fe(a,w,o);if(t?.tags)for(let y of t.tags)s.tag(y);let i=n&&n!=="info"?`${e} [${n}]`:e,f=s.step(i,r);n==="error"?(f.fail(r),w.current&&(w.current.lastError=r),s.tag("error")):(f.success(),n&&n!=="info"&&s.tag(n)),ye(a,w)}function Te(){a.asyncTimer||(a.asyncTimer=setTimeout(()=>{A()},a.asyncFlushInterval))}function A(){a.asyncTimer&&(clearTimeout(a.asyncTimer),a.asyncTimer=null);let e=[...a.asyncBuffer];a.asyncBuffer=[];for(let r of e)V(r.message,r.data,r.options,r.severity)}function c(e,r,t){N(e,r,t)}c.info=(e,r,t)=>N(e,r,t,"info");c.warn=(e,r,t)=>N(e,r,t,"warn");c.error=(e,r,t)=>N(e,r,t,"error");c.toFile=(e,r)=>{let t=r?.append?"a":"w";a.transports.push({type:"file",target:e,options:{flag:t}})};c.toStream=e=>{a.transports.push({type:"stream",target:e})};c.toHttp=(e,r)=>{a.transports.push({type:"http",target:e,options:r})};c.redact=e=>{a.redactFields=e};c.async=(e=!0)=>{a.asyncMode=e,e||A()};c.setIdleTimeout=e=>{a.idleTimeout=e};c.setFlowName=e=>{a.flowName=e};c.setDefaultTags=e=>{a.defaultTags=e};c.activeFlow=()=>w.current?.flow??null;c.flush=()=>{Q(w),A()};function l(e,r,t){c(e,r,t)}l.log=c;l.flow=(e,r)=>E(e,r);l.setIdleTimeout=c.setIdleTimeout;l.setFlowName=c.setFlowName;l.setDefaultTags=c.setDefaultTags;l.activeFlow=c.activeFlow;l.flush=c.flush;l.setEnabled=G;l.isEnabled=v;l.subscribe=O;l.toJSON=e=>{let r="trace"in e?e.trace:e;return JSON.stringify({version:1,flow:{id:r.id,name:r.name,...r.parentId!==void 0&&{parentId:r.parentId},state:r.state,...r.status!==void 0&&{status:r.status},tags:r.tags,start:r.start,...r.end!==void 0&&{end:r.end},...r.error!==void 0&&{error:r.error},context:r.context,steps:r.steps.map(X),...r.meta!==void 0&&{meta:r.meta}}},null,2)};function X(e){let r={id:e.id,name:e.name,sequence:e.sequence,state:e.state,status:e.status,start:e.start};if(e.end!==void 0&&(r.end=e.end),e.data!==void 0)try{r.data=JSON.parse(u(e.data))}catch{r.data="[Circular or unserializable]"}return e.error!==void 0&&(r.error=e.error),e.children.length>0&&(r.children=e.children.map(X)),r}function Se(e){return typeof e=="object"&&e!==null&&"trace"in e&&typeof e.trace=="object"&&e.trace!==null}function Z(e){let r=Se(e)?e.trace:e;return JSON.stringify({version:1,flow:{id:r.id,name:r.name,...r.parentId!==void 0&&{parentId:r.parentId},state:r.state,...r.status!==void 0&&{status:r.status},tags:r.tags,start:r.start,...r.end!==void 0&&{end:r.end},...r.error!==void 0&&{error:r.error},context:r.context,steps:r.steps.map(j),...r.meta!==void 0&&{meta:r.meta}}},null,2)}function j(e){let r={id:e.id,name:e.name,sequence:e.sequence,state:e.state,status:e.status,start:e.start};if(e.end!==void 0&&(r.end=e.end),e.data!==void 0)try{r.data=JSON.parse(u(e.data))}catch{r.data="[Circular or unserializable]"}return e.error!==void 0&&(r.error=e.error),e.children.length>0&&(r.children=e.children.map(j)),r}export{d as NOOP_FLOW,g as NOOP_STEP,l as better,E as createFlow,Y as getRenderer,v as isEnabled,p as normalizeError,u as safeSerialize,xe as setClock,G as setEnabled,we as setIdGenerator,U as setRenderer,O as subscribe,Z as toJSON};
package/package.json CHANGED
@@ -52,5 +52,5 @@
52
52
  "@typescript-eslint/eslint-plugin": "8.58.0",
53
53
  "@types/node": "20.11.0"
54
54
  },
55
- "version": "0.8.0"
55
+ "version": "1.0.0"
56
56
  }