@better-logger/core 0.7.0 โ†’ 0.8.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 (2) hide show
  1. package/README.md +170 -216
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # @better-logger/core
1
+ # better-logger
2
2
 
3
- > Track what your app *did*, not what it *said*.
3
+ **Track what your app *did*, not what it *said*.**
4
4
 
5
5
  Execution flow debugger for modern apps. Zero deps. Works everywhere. <10KB.
6
6
 
@@ -8,11 +8,9 @@ Execution flow debugger for modern apps. Zero deps. Works everywhere. <10KB.
8
8
  npm install @better-logger/core
9
9
  ```
10
10
 
11
- ---
11
+ ## Stop debugging like this:
12
12
 
13
- Stop debugging like this:
14
-
15
- ```ts
13
+ ```typescript
16
14
  console.log('start')
17
15
  console.log('user', user)
18
16
  console.log('after db')
@@ -21,273 +19,229 @@ console.log('done')
21
19
 
22
20
  And trying to mentally reconstruct what happened, in what order, and how long each thing took.
23
21
 
24
- Your app is not a list of messages.
22
+ ## Your app is not a list of messages. It's a flow.
25
23
 
26
- It's a **flow**.
24
+ ```typescript
25
+ import { better } from '@better-logger/core'
27
26
 
28
- ---
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)
29
31
 
30
- ## What you actually get
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()
38
+ ```
39
+
40
+ **What you get:**
31
41
 
32
42
  ```
33
43
  ๐Ÿš€ [flow:user-onboarding] [auth] (tid: a1b2c3d4)
34
44
  โ†’ create-user
35
45
  data: { email: "test@example.com" }
36
46
  โœ“ create-user (45ms)
37
- โ†’ generate-ai-profile
38
- โœ“ generate-ai-profile (410ms)
39
- โ†’ save-db
40
- โœ— save-db (error: timeout)
41
- ๐Ÿ [flow:user-onboarding] failed (532ms)
42
- ```
43
-
44
- ```ts
45
- import { createFlow } from '@better-logger/core'
46
-
47
- const flow = createFlow('user-onboarding', { tags: ['auth'] })
48
-
49
- const s1 = flow.step('create-user', { email })
50
- await createUser(email)
51
- s1.success()
52
-
53
- const s2 = flow.step('save-db')
54
- await saveUser()
55
- s2.fail(new Error('timeout'))
56
-
57
- flow.fail(new Error('save-db failed'))
47
+ ๐Ÿ [flow:user-onboarding] success (45ms)
58
48
  ```
59
49
 
60
- You didn't write logs.
61
-
62
- You defined the **execution**.
63
-
64
- better-logger turns your code into a timeline of what actually happened.
65
-
66
- Output is deferred until `flow.success()` / `flow.fail()` โ€” one atomic write, zero interleaving, even in async chaos.
67
-
68
- ---
69
-
70
50
  ## Why this exists
71
51
 
72
52
  Debugging today is broken:
73
53
 
74
- - `console.log` โ†’ flat noise, no structure
75
- - No automatic timing
76
- - No context propagation
77
- - Async flows become impossible to follow
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` |
78
61
 
79
- You don't debug code.
62
+ ## Quick Start
80
63
 
81
- You debug **guesses about what happened**.
64
+ ### 1. Drop-in replacement
82
65
 
83
- better-logger removes the guesswork. Instead of scattering `console.log` across your code and reconstructing timelines mentally, you define the flow upfront and get a structured narrative back โ€” with timing, context, and clear failure markers.
66
+ Replace `console.log` with `better.log`:
84
67
 
85
- ---
68
+ ```typescript
69
+ // Before
70
+ console.log('Server started on port 3000')
71
+ console.error('Database connection failed', error)
86
72
 
87
- ## What changes
73
+ // After
74
+ import { better } from '@better-logger/core'
88
75
 
89
- Instead of guessing:
90
- - "did this run?"
91
- - "what ran first?"
92
- - "where did it fail?"
93
- - "why is it slow?"
94
-
95
- You **see**:
96
-
97
- - ๐Ÿง  A full execution narrative
98
- - โฑ Exact timing for every step
99
- - ๐ŸŒณ Nested flows (real hierarchy, not flat logs)
100
- - ๐Ÿงพ Data at the moment it mattered
101
- - ๐Ÿงต Shared context across the entire flow
102
- - ๐Ÿท Tags to group and filter
103
- - ๐Ÿงฑ Guaranteed consistency โ€” no race-condition bugs
104
- - ๐Ÿ”’ Immutable render snapshots โ€” output can't be corrupted
105
-
106
- This replaces `console.log` for anything non-trivial.
107
-
108
- ---
109
-
110
- ## Why not just use something else?
111
-
112
- | Tool | Reality |
113
- |------|--------|
114
- | `console.log` | You reconstruct flows manually like it's 2005 |
115
- | `pino` / `winston` | Built for shipping logs, not understanding execution |
116
- | `debug` | Namespaces โ‰  structure |
117
- | OpenTelemetry | Powerful, but heavy and not built for everyday debugging |
118
-
119
- **@better-logger/core** sits in the missing gap:
76
+ better.log('Server started on port 3000')
77
+ better.log.error('Database connection failed', error)
78
+ ```
120
79
 
121
- โ†’ instant, local, zero-config execution tracing
80
+ That's it. You now get structured, timed output for free.
122
81
 
123
- ---
82
+ ### 2. When you need structure
124
83
 
125
- ## Usage
84
+ For important operations, use explicit flows:
126
85
 
127
- ```ts
128
- const flow = createFlow('request', { tags: ['api'] })
86
+ ```typescript
87
+ const flow = better.flow('process-payment', { tags: ['billing'] })
88
+ flow.setContext({ orderId: 'ord-123', userId: 'user-456' })
129
89
 
130
- const step = flow.step('db')
131
- await db.query()
132
- step.success()
90
+ const step = flow.step('charge-card', { amount: 99.99 })
91
+ const result = await paymentGateway.charge({ amount: 99.99 })
92
+ step.success(result)
133
93
 
134
94
  flow.success()
95
+ better.log(`Payment processed: ${result.transactionId}`)
135
96
  ```
136
97
 
137
- That's it.
138
-
139
- ---
140
-
141
- ## How it works
142
-
143
- ```mermaid
144
- graph TD
145
- Start[createFlow] --> Step[step]
146
- Step --> Complete[success / fail]
147
- Complete --> FlowEnd[flow.success / flow.fail]
148
- FlowEnd --> Render[Atomic Render]
149
- ```
150
-
151
- ---
152
-
153
- ## When should you use this
154
-
155
- Use it when:
156
-
157
- - your flow has more than 2 steps
158
- - async logic gets confusing
159
- - debugging requires more than one `console.log`
160
- - timing matters
161
- - you need to know "what ran" and "what didn't"
98
+ ### 3. Async made easy
162
99
 
163
- If a single `console.log` feels enough, you don't need this.
100
+ ```typescript
101
+ const flow = better.flow('data-export')
164
102
 
165
- If it doesn'tโ€ฆ this replaces it.
166
-
167
- ---
168
-
169
- ## Advanced
170
-
171
- ### Child Flows
172
-
173
- ```ts
174
- const flow = createFlow('request')
103
+ const data = await flow.run('fetch-data', async () => {
104
+ return await db.users.find({})
105
+ })
175
106
 
176
- const ai = flow.child('ai-call')
177
- const s = ai.step('generate')
178
- await generate()
179
- s.success()
180
- ai.success()
107
+ const file = await flow.run('generate-file', async () => {
108
+ return await exportToCSV(data)
109
+ })
181
110
 
182
111
  flow.success()
183
112
  ```
184
113
 
185
- ```
186
- ๐Ÿš€ [flow:request] (tid: a1b2c3d4)
187
- โ””โ”€ ๐Ÿš€ [flow:ai-call] (tid: x9y8z7w6)
188
- โ†’ generate
189
- โœ“ generate (210ms)
190
- ๐Ÿ [flow:ai-call] success (215ms)
191
- ๐Ÿ [flow:request] success (340ms)
192
- ```
193
-
194
- ### Context Propagation
114
+ ## API Reference
195
115
 
196
- ```ts
197
- flow.setContext({ userId: 'abc', requestId: 'xyz' })
198
- // Available across all steps and child flows
199
- ```
200
-
201
- ### Silent Mode
202
-
203
- ```ts
204
- const flow = createFlow('task', { enabled: false })
205
- // Near-zero overhead. All operations are no-ops.
206
- ```
207
-
208
- ### Max Steps Guard
116
+ ### `better.log()` โ€” The simple way
209
117
 
210
- ```ts
211
- const flow = createFlow('batch', { maxSteps: 1000 })
212
- // Prevents memory blowups from runaway loops
118
+ ```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)
213
124
  ```
214
125
 
215
- ### Subscribe (DevTools / Testing)
126
+ ### `better.flow()` โ€” The structured way
216
127
 
217
- ```ts
218
- import { subscribe, toJSON } from '@better-logger/core'
219
-
220
- subscribe((trace) => {
221
- // Frozen snapshot of every completed flow
222
- console.log(toJSON(trace))
128
+ ```typescript
129
+ const flow = better.flow('name', {
130
+ tags: ['tag1', 'tag2'], // Indexing labels
131
+ maxSteps: 100, // Safety limit
132
+ initialContext: { key: 'value' } // Shared metadata
223
133
  })
224
- ```
225
134
 
226
- ### JSON Output
135
+ flow.setContext({ userId: 'abc' }) // Add context
136
+ flow.getContext() // Get context copy
227
137
 
228
- ```ts
229
- import { toJSON } from '@better-logger/core'
138
+ flow.step('step-name', data) // Create step
139
+ .success() // Mark success
140
+ .fail(error) // Mark failure
230
141
 
231
- const json = toJSON(flow)
232
- // { version: 1, flow: { id, name, state, status, tags, steps, context, ... } }
142
+ flow.success() // Complete flow
143
+ flow.fail(error) // Fail flow
233
144
  ```
234
145
 
235
- Portable, structured trace for tooling, testing, and future integrations.
146
+ ### `better.flow.run()` โ€” Async helper
236
147
 
237
- ---
238
-
239
- ## Features
240
-
241
- ### Core
242
- `createFlow` ยท `step` ยท `success/fail` ยท `child` ยท `toJSON`
243
-
244
- ### Advanced
245
- Context propagation ยท Tags ยท Inline data snapshots ยท Subscribe event tap ยท Deferred atomic rendering ยท Immutable snapshots
246
-
247
- ### Safety
248
- Guarded finalization ยท `maxSteps` overflow protection ยท Lifecycle states (`running` โ†’ `completed`) ยท Safe data serializer (circular refs, deep nesting) ยท NoOp singletons (zero-allocation silent mode)
249
-
250
- ---
251
-
252
- ## What's not included
253
-
254
- - โŒ Log levels (debug, info, warn)
255
- - โŒ Transports (file, HTTP, Elasticsearch)
256
- - โŒ SaaS dashboards
257
- - โŒ Auto-instrumentation
258
-
259
- This is a developer debugging tool, not observability infrastructure.
260
-
261
- ---
262
-
263
- ## Roadmap
264
-
265
- | Version | Focus |
266
- |---------|-------|
267
- | **V1** | Core flow debugger โ€” this release |
268
- | **V2** | Custom renderers, `flow.run()` async helper, flow sampling |
269
- | **V3** | Browser DevTools timeline panel |
270
- | **V4+** | Python / Go / Rust ports, shared tracing schema |
271
-
272
- ---
273
-
274
- ## Organization
148
+ ```typescript
149
+ const result = await flow.run('async-step', async () => {
150
+ return await fetchData() // Auto-completes step on success/fail
151
+ })
152
+ ```
275
153
 
276
- Published under the **@better-logger** org, owned by [0xmilord](https://github.com/0xmilord).
154
+ ### Configuration
277
155
 
278
- ```bash
279
- npm install @better-logger/core
156
+ ```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
280
163
  ```
281
164
 
282
- All packages in this org share the same execution tracing schema.
165
+ ## Real-World Examples
283
166
 
284
- ---
167
+ We've included 10 comprehensive examples showing better-logger in real applications:
285
168
 
286
- ## Test Coverage
169
+ | Example | What it shows |
170
+ |---------|--------------|
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 |
287
181
 
288
- **100%** across all metrics โ€” statements, branches, functions, lines.
182
+ ## Features
289
183
 
290
- [View detailed coverage report](./COVERAGE.md) | [Testing Strategy](./docs/TESTING-STRATEGY.md)
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 references โ€” won'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)
218
+
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)
225
+ ```
226
+
227
+ **Migration effort:** 10 minutes to replace all console.log. Hours to days to adopt flows strategically where they add value.
228
+
229
+ ## What's NOT included
230
+
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
235
+
236
+ ## Package Health
237
+
238
+ | Metric | Value |
239
+ |--------|-------|
240
+ | Bundle size | <10KB minified |
241
+ | Dependencies | 0 |
242
+ | Test coverage | 100% |
243
+ | TypeScript | Full support |
244
+ | Runtimes | Node 18+, Browser, Edge |
291
245
 
292
246
  ## License
293
247
 
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.7.0"
55
+ "version": "0.8.0"
56
56
  }