@lovelaces-io/storyteller 0.1.0 → 0.2.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/README.md +72 -73
- package/dist/index.cjs +227 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +119 -36
- package/dist/index.d.ts +119 -36
- package/dist/index.js +225 -174
- package/dist/index.js.map +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,8 +1,42 @@
|
|
|
1
1
|
# Storyteller
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@lovelaces-io/storyteller)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](package.json)
|
|
6
|
+
|
|
3
7
|
Lightweight TypeScript logging library that treats logs as **stories** — grouped notes emitted as a single structured event.
|
|
4
8
|
|
|
5
|
-
Zero dependencies.
|
|
9
|
+
Zero dependencies. TypeScript-first. One record per story.
|
|
10
|
+
|
|
11
|
+
## Why Storyteller?
|
|
12
|
+
|
|
13
|
+
**Before:** 47 scattered `console.log` lines. Something broke. Good luck figuring out what happened.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
[14:30:00] User clicked checkout
|
|
17
|
+
[14:30:00] Validating cart...
|
|
18
|
+
[14:30:01] Cart valid
|
|
19
|
+
[14:30:01] Charging card...
|
|
20
|
+
[14:30:03] ERROR: gateway timeout
|
|
21
|
+
[14:30:03] Retrying...
|
|
22
|
+
[14:30:04] Charge succeeded
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**After:** One story. One record. The whole picture.
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"level": "Warning",
|
|
30
|
+
"title": "Payment retry succeeded",
|
|
31
|
+
"durationMs": 4000,
|
|
32
|
+
"notes": [
|
|
33
|
+
{ "timestamp": "14:30:00", "note": "User clicked checkout" },
|
|
34
|
+
{ "timestamp": "14:30:01", "note": "Cart validated", "what": { "items": 3 } },
|
|
35
|
+
{ "timestamp": "14:30:03", "note": "Card declined", "error": { "message": "gateway timeout" } },
|
|
36
|
+
{ "timestamp": "14:30:04", "note": "Retry succeeded" }
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
```
|
|
6
40
|
|
|
7
41
|
## Install
|
|
8
42
|
|
|
@@ -10,44 +44,41 @@ Zero dependencies. ~24 kB packed. TypeScript-first.
|
|
|
10
44
|
npm install @lovelaces-io/storyteller
|
|
11
45
|
```
|
|
12
46
|
|
|
13
|
-
##
|
|
47
|
+
## Quick Start
|
|
14
48
|
|
|
15
49
|
```ts
|
|
16
50
|
import { Storyteller } from "@lovelaces-io/storyteller";
|
|
17
51
|
|
|
18
52
|
const story = new Storyteller({
|
|
19
|
-
origin: {
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
// Collect notes as things happen
|
|
23
|
-
story.note("User submitted payment", {
|
|
24
|
-
who: { id: "user:413" },
|
|
25
|
-
what: { amount: 49.99, currency: "USD" },
|
|
53
|
+
origin: { who: "checkout-service", where: { app: "web" } },
|
|
26
54
|
});
|
|
27
55
|
|
|
28
|
-
story.note("
|
|
29
|
-
|
|
30
|
-
where: { service: "payments" },
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Tell the story when it's done
|
|
56
|
+
story.note("User submitted payment", { what: { amount: 49.99 } });
|
|
57
|
+
story.note("Charging card", { where: "stripe" });
|
|
34
58
|
story.tell("Payment completed");
|
|
35
59
|
```
|
|
36
60
|
|
|
37
|
-
Notes are
|
|
61
|
+
Notes are collected, sorted chronologically, and emitted as one structured event to your audiences.
|
|
62
|
+
|
|
63
|
+
## Two Output Modes
|
|
64
|
+
|
|
65
|
+
| Mode | What it is | Use it for |
|
|
66
|
+
|------|-----------|------------|
|
|
67
|
+
| **Story** (JSON) | Clean serializable record | DB storage, monitoring, audit logs |
|
|
68
|
+
| **Report** (text) | Colorized human-readable output | Console, log files, debugging |
|
|
69
|
+
|
|
70
|
+
`JSON.stringify(event)` gives you the story record. `formatStory(event)` gives you the report.
|
|
38
71
|
|
|
39
72
|
## Three Levels
|
|
40
73
|
|
|
41
74
|
```ts
|
|
42
|
-
story.tell("Payment completed"); //
|
|
43
|
-
story.warn("Payment slow but succeeded"); //
|
|
75
|
+
story.tell("Payment completed"); // all good
|
|
76
|
+
story.warn("Payment slow but succeeded"); // heads up
|
|
44
77
|
story.oops("Payment failed", new Error()); // something broke
|
|
45
78
|
```
|
|
46
79
|
|
|
47
80
|
## Context on Every Note
|
|
48
81
|
|
|
49
|
-
Every note can carry `who`, `what`, `where`, and `error`:
|
|
50
|
-
|
|
51
82
|
```ts
|
|
52
83
|
story.note("Write failed", {
|
|
53
84
|
who: { id: "user:99" },
|
|
@@ -57,83 +88,51 @@ story.note("Write failed", {
|
|
|
57
88
|
});
|
|
58
89
|
```
|
|
59
90
|
|
|
60
|
-
## Audiences
|
|
91
|
+
## Audiences — Who Hears Your Stories
|
|
61
92
|
|
|
62
|
-
Stories are delivered to **audiences**. Console is included by default.
|
|
93
|
+
Stories are delivered to **audiences**. Console is included by default.
|
|
63
94
|
|
|
64
95
|
```ts
|
|
65
96
|
import { dbAudience } from "@lovelaces-io/storyteller";
|
|
66
97
|
|
|
67
|
-
//
|
|
98
|
+
// Store warn and oops events in your database
|
|
68
99
|
story.audience.add(
|
|
69
100
|
dbAudience(async (event) => await db.insert("logs", event))
|
|
70
101
|
);
|
|
71
102
|
|
|
72
|
-
// Target specific audiences
|
|
103
|
+
// Target specific audiences
|
|
73
104
|
story.oops("Critical failure", error).to("console", "db");
|
|
74
105
|
```
|
|
75
106
|
|
|
76
|
-
##
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
Story: Dashboard status
|
|
92
|
-
Level: tell
|
|
93
|
-
Time: Mar 22, 2026, 3:42:18 PM (12ms)
|
|
94
|
-
Origin: checkout / Payment
|
|
95
|
-
Notes:
|
|
96
|
-
3:42:18 PM — User submitted payment
|
|
97
|
-
3:42:18 PM — Charging card
|
|
98
|
-
```
|
|
107
|
+
## Quick Reference
|
|
108
|
+
|
|
109
|
+
| Method | Returns | Description |
|
|
110
|
+
|--------|---------|-------------|
|
|
111
|
+
| `note(text, context?)` | `this` | Add a timestamped note with optional who/what/where/error |
|
|
112
|
+
| `tell(title)` | `{ to }` | Tell a success story |
|
|
113
|
+
| `warn(title)` | `{ to }` | Tell a cautionary story |
|
|
114
|
+
| `oops(title, error?)` | `{ to }` | Tell an error story |
|
|
115
|
+
| `reset()` | `this` | Clear notes without telling a story |
|
|
116
|
+
| `summarize(options?)` | `FormattedReport` | Preview current notes as a formatted report |
|
|
117
|
+
| `audience.add(member)` | `this` | Register an audience |
|
|
118
|
+
| `audience.remove(name)` | `this` | Unregister an audience |
|
|
119
|
+
| `audience.has(name)` | `boolean` | Check if an audience is listening |
|
|
120
|
+
| `audience.names()` | `string[]` | List who's listening |
|
|
99
121
|
|
|
100
122
|
## Shared Instance
|
|
101
123
|
|
|
102
|
-
Use `useStoryteller()` for cross-component logging into the same story:
|
|
103
|
-
|
|
104
124
|
```ts
|
|
105
125
|
import { useStoryteller } from "@lovelaces-io/storyteller";
|
|
106
126
|
|
|
107
|
-
|
|
108
|
-
const story = useStoryteller({ origin: { where: { app: "admin" } } });
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Structured Output
|
|
112
|
-
|
|
113
|
-
Every story is a typed, serializable JSON object — designed for humans and machines:
|
|
114
|
-
|
|
115
|
-
```json
|
|
116
|
-
{
|
|
117
|
-
"timestamp": "2026-03-22T14:15:03.421Z",
|
|
118
|
-
"level": "oops",
|
|
119
|
-
"title": "Payment failed",
|
|
120
|
-
"origin": { "where": { "app": "checkout", "page": "Payment" } },
|
|
121
|
-
"notes": [
|
|
122
|
-
{
|
|
123
|
-
"timestamp": "2026-03-22T14:15:02.218Z",
|
|
124
|
-
"note": "User submitted payment",
|
|
125
|
-
"who": { "id": "user:413" }
|
|
126
|
-
}
|
|
127
|
-
],
|
|
128
|
-
"error": { "name": "Error", "message": "gateway timeout" }
|
|
129
|
-
}
|
|
127
|
+
const story = useStoryteller({ origin: { who: "worker" } });
|
|
130
128
|
```
|
|
131
129
|
|
|
132
130
|
## Docs
|
|
133
131
|
|
|
134
132
|
- [API Reference](docs/API.md) — full signatures and examples
|
|
135
|
-
- [How It Works](docs/HOW-IT-WORKS.md) — narrative guide
|
|
133
|
+
- [How It Works](docs/HOW-IT-WORKS.md) — narrative guide
|
|
136
134
|
- [Changelog](CHANGELOG.md)
|
|
135
|
+
- [For AI Agents](AGENTS.md) — guidance for AI coding assistants
|
|
137
136
|
|
|
138
137
|
## License
|
|
139
138
|
|