@lovelaces-io/storyteller 0.3.0 → 0.4.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/AGENTS.md +42 -1
- package/README.md +30 -0
- package/dist/index.cjs +454 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -515
- package/dist/index.d.ts +55 -515
- package/dist/index.js +440 -17
- package/dist/index.js.map +1 -1
- package/dist/store/file.cjs +513 -0
- package/dist/store/file.cjs.map +1 -0
- package/dist/store/file.d.cts +29 -0
- package/dist/store/file.d.ts +29 -0
- package/dist/store/file.js +478 -0
- package/dist/store/file.js.map +1 -0
- package/dist/stories-BgN4BSoZ.d.cts +744 -0
- package/dist/stories-BgN4BSoZ.d.ts +744 -0
- package/llms.txt +11 -1
- package/package.json +16 -9
package/dist/index.d.cts
CHANGED
|
@@ -1,515 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* - `text` — colorized console output for a person watching
|
|
5
|
-
* - `ndjson` — one JSON object per line for a program reading
|
|
6
|
-
*/
|
|
7
|
-
type OutputFormat = "text" | "ndjson";
|
|
8
|
-
/**
|
|
9
|
-
* A level written any of the ways people and agents actually write it.
|
|
10
|
-
* `report("...", { level: "warn" })` should not be a type error.
|
|
11
|
-
*/
|
|
12
|
-
type LevelInput = StoryLevel | "info" | "information" | "warn" | "warning" | "oops" | "error";
|
|
13
|
-
/**
|
|
14
|
-
* Resolve any accepted level spelling to a stored level label.
|
|
15
|
-
*
|
|
16
|
-
* @param input - A level in any accepted spelling
|
|
17
|
-
* @returns The canonical StoryLevel, defaulting to Information
|
|
18
|
-
*/
|
|
19
|
-
declare function toStoryLevel(input?: LevelInput): StoryLevel;
|
|
20
|
-
/**
|
|
21
|
-
* Read an environment variable, tolerating runtimes that have no environment at all.
|
|
22
|
-
*
|
|
23
|
-
* @param name - Variable name
|
|
24
|
-
* @returns The trimmed value, or undefined when unset or unavailable
|
|
25
|
-
*/
|
|
26
|
-
declare function readEnvironmentValue(name: string): string | undefined;
|
|
27
|
-
/**
|
|
28
|
-
* Resolve the minimum level to deliver, from an explicit option then `STORYTELLER_LEVEL`.
|
|
29
|
-
*
|
|
30
|
-
* @param requested - Explicit level, if the caller set one
|
|
31
|
-
* @returns The threshold level, defaulting to Information (deliver everything)
|
|
32
|
-
*/
|
|
33
|
-
declare function resolveMinimumLevel(requested?: StoryLevel | string): StoryLevel;
|
|
34
|
-
/**
|
|
35
|
-
* Check whether a level clears the configured minimum.
|
|
36
|
-
*
|
|
37
|
-
* @param level - The emission's level
|
|
38
|
-
* @param minimum - The configured threshold
|
|
39
|
-
*/
|
|
40
|
-
declare function meetsLevel(level: StoryLevel, minimum: StoryLevel): boolean;
|
|
41
|
-
/**
|
|
42
|
-
* Resolve which default audience to register, from an explicit option then
|
|
43
|
-
* `STORYTELLER_FORMAT`.
|
|
44
|
-
*
|
|
45
|
-
* Deliberately not inferred from whether stdout is a TTY: output that silently
|
|
46
|
-
* changes shape when a process is piped is a debugging afternoon nobody asked for.
|
|
47
|
-
*
|
|
48
|
-
* @param requested - Explicit format, if the caller set one
|
|
49
|
-
* @returns The format, defaulting to text
|
|
50
|
-
*/
|
|
51
|
-
declare function resolveOutputFormat(requested?: OutputFormat): OutputFormat;
|
|
52
|
-
/**
|
|
53
|
-
* Resolve whether to colorize, from an explicit option then `STORYTELLER_COLOR`.
|
|
54
|
-
*
|
|
55
|
-
* @param requested - Explicit choice, if the caller set one
|
|
56
|
-
* @returns Whether colors should be used, defaulting to true
|
|
57
|
-
*/
|
|
58
|
-
declare function resolveColors(requested?: boolean): boolean;
|
|
59
|
-
|
|
60
|
-
/** A value that survives JSON.stringify with no loss and no throwing */
|
|
61
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
62
|
-
[key: string]: JsonValue;
|
|
63
|
-
};
|
|
64
|
-
type NormalizeOptions = {
|
|
65
|
-
/** How many levels deep to descend before replacing the value with a truncation marker */
|
|
66
|
-
maxDepth?: number;
|
|
67
|
-
/** How many array entries to keep before truncating */
|
|
68
|
-
maxArrayLength?: number;
|
|
69
|
-
/** How many object properties to keep before truncating */
|
|
70
|
-
maxProperties?: number;
|
|
71
|
-
/** How many characters of a string to keep before truncating */
|
|
72
|
-
maxStringLength?: number;
|
|
73
|
-
/** Property names whose values are replaced with the redaction marker */
|
|
74
|
-
redactKeys?: string[];
|
|
75
|
-
/** Set false to keep secret-shaped values as-is */
|
|
76
|
-
redact?: boolean;
|
|
77
|
-
};
|
|
78
|
-
/** Marker written in place of a value that matched a redacted key name */
|
|
79
|
-
declare const REDACTED = "[redacted]";
|
|
80
|
-
/**
|
|
81
|
-
* Property names whose values are replaced with {@link REDACTED}.
|
|
82
|
-
* Matching ignores case and separators, so `apiKey`, `api_key` and `API-KEY` all match.
|
|
83
|
-
*/
|
|
84
|
-
declare const DEFAULT_REDACT_KEYS: string[];
|
|
85
|
-
/**
|
|
86
|
-
* Convert any value into a JSON-safe structure suitable for a story record.
|
|
87
|
-
*
|
|
88
|
-
* Handles the shapes real code actually holds — errors, dates, maps, sets, class
|
|
89
|
-
* instances, binary buffers, circular references, throwing getters — and never throws,
|
|
90
|
-
* so a hostile object logged by a caller cannot break the delivery pipeline.
|
|
91
|
-
*
|
|
92
|
-
* Data dropped for size is replaced with an explicit `@truncated` marker rather than
|
|
93
|
-
* disappearing silently, so a consumer can tell the difference between "this was empty"
|
|
94
|
-
* and "this was too big".
|
|
95
|
-
*
|
|
96
|
-
* @param input - Any value
|
|
97
|
-
* @param options - Depth, size and redaction limits
|
|
98
|
-
* @returns A value that JSON.stringify can always serialize
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```ts
|
|
102
|
-
* normalizeValue({ user: new Map([["id", 1]]), apiKey: "sk-live-abc" });
|
|
103
|
-
* // { user: { "@type": "Map", entries: { id: 1 } }, apiKey: "[redacted]" }
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
declare function normalizeValue(input: unknown, options?: NormalizeOptions): JsonValue;
|
|
107
|
-
/**
|
|
108
|
-
* Convert an unknown thrown value into a serializable StoryError,
|
|
109
|
-
* following the `cause` chain and collecting AggregateError members.
|
|
110
|
-
*
|
|
111
|
-
* @param rawError - Any thrown or rejected value
|
|
112
|
-
* @param options - Depth, size and redaction limits applied to attached data
|
|
113
|
-
* @returns A StoryError safe to store and serialize
|
|
114
|
-
*/
|
|
115
|
-
declare function normalizeError(rawError: unknown, options?: NormalizeOptions): StoryError;
|
|
116
|
-
|
|
117
|
-
/** Human-readable level labels stored in story records */
|
|
118
|
-
type StoryLevel = "Information" | "Warning" | "Error";
|
|
119
|
-
/**
|
|
120
|
-
* A stored context value. Always JSON-safe — whatever the caller passed in has
|
|
121
|
-
* already been through the normalizer by the time it reaches a record.
|
|
122
|
-
*/
|
|
123
|
-
type StoryContextValue = JsonValue;
|
|
124
|
-
/** Context accepted from callers. Anything goes; the normalizer makes it storable. */
|
|
125
|
-
type StoryContextInput = unknown;
|
|
126
|
-
type StoryError = {
|
|
127
|
-
name?: string;
|
|
128
|
-
message?: string;
|
|
129
|
-
stack?: string;
|
|
130
|
-
cause?: JsonValue;
|
|
131
|
-
/** Members of an AggregateError */
|
|
132
|
-
errors?: StoryError[];
|
|
133
|
-
};
|
|
134
|
-
/** Origin as stored on a record */
|
|
135
|
-
type StoryOrigin = {
|
|
136
|
-
who?: StoryContextValue;
|
|
137
|
-
what?: StoryContextValue;
|
|
138
|
-
where?: StoryContextValue;
|
|
139
|
-
};
|
|
140
|
-
/** Origin as accepted from callers */
|
|
141
|
-
type StoryOriginInput = {
|
|
142
|
-
who?: StoryContextInput;
|
|
143
|
-
what?: StoryContextInput;
|
|
144
|
-
where?: StoryContextInput;
|
|
145
|
-
};
|
|
146
|
-
type StoryNote = {
|
|
147
|
-
timestamp: string;
|
|
148
|
-
/**
|
|
149
|
-
* Position within the story, assigned when the note is taken. Gap-free from 0.
|
|
150
|
-
* Optional so records written before sequencing existed still typecheck.
|
|
151
|
-
*/
|
|
152
|
-
sequence?: number;
|
|
153
|
-
note: string;
|
|
154
|
-
/** Omitted when the note carries the story's default Information level */
|
|
155
|
-
level?: StoryLevel;
|
|
156
|
-
who?: StoryContextValue;
|
|
157
|
-
what?: StoryContextValue;
|
|
158
|
-
where?: StoryContextValue;
|
|
159
|
-
error?: StoryError;
|
|
160
|
-
};
|
|
161
|
-
type StoryEventBase = {
|
|
162
|
-
timestamp: string;
|
|
163
|
-
level: StoryLevel;
|
|
164
|
-
title: string;
|
|
165
|
-
/**
|
|
166
|
-
* Correlates every note emission with the story it belongs to. Always set on
|
|
167
|
-
* events this library builds; optional so older stored records still typecheck.
|
|
168
|
-
*/
|
|
169
|
-
storyId?: string;
|
|
170
|
-
/**
|
|
171
|
-
* The story this one is a chapter of. Absent on a top-level story.
|
|
172
|
-
* Following this field reconstructs the tree of a nested run.
|
|
173
|
-
*/
|
|
174
|
-
parentStoryId?: string;
|
|
175
|
-
origin?: StoryOrigin;
|
|
176
|
-
notes: StoryNote[];
|
|
177
|
-
durationMs?: number;
|
|
178
|
-
/**
|
|
179
|
-
* How many emissions were dropped for back-pressure while this story was being
|
|
180
|
-
* collected. Present only when something was actually lost, so the loss shows up
|
|
181
|
-
* in the record instead of vanishing.
|
|
182
|
-
*/
|
|
183
|
-
droppedEmissions?: number;
|
|
184
|
-
error?: StoryError;
|
|
185
|
-
};
|
|
186
|
-
type ReportOptions = {
|
|
187
|
-
timezone?: string;
|
|
188
|
-
locale?: string;
|
|
189
|
-
detail?: "brief" | "normal" | "full";
|
|
190
|
-
noteLimit?: number;
|
|
191
|
-
showData?: boolean;
|
|
192
|
-
colors?: boolean;
|
|
193
|
-
};
|
|
194
|
-
/** @deprecated Use ReportOptions instead */
|
|
195
|
-
type StorySummaryOptions = ReportOptions;
|
|
196
|
-
type PreviewOptions = ReportOptions & {
|
|
197
|
-
title?: string;
|
|
198
|
-
level?: StoryLevel;
|
|
199
|
-
error?: unknown;
|
|
200
|
-
};
|
|
201
|
-
/** @deprecated Use PreviewOptions instead */
|
|
202
|
-
type StoryPreviewOptions = PreviewOptions;
|
|
203
|
-
type ReportNote = {
|
|
204
|
-
timestamp: string;
|
|
205
|
-
when: string;
|
|
206
|
-
note: string;
|
|
207
|
-
text: string;
|
|
208
|
-
who?: StoryContextValue;
|
|
209
|
-
what?: StoryContextValue;
|
|
210
|
-
where?: StoryContextValue;
|
|
211
|
-
error?: StoryError;
|
|
212
|
-
};
|
|
213
|
-
/** @deprecated Use ReportNote instead */
|
|
214
|
-
type StorySummaryNote = ReportNote;
|
|
215
|
-
type StoryReport = {
|
|
216
|
-
title: string;
|
|
217
|
-
level: StoryLevel;
|
|
218
|
-
when: string;
|
|
219
|
-
durationMs?: number;
|
|
220
|
-
duration?: string;
|
|
221
|
-
origin?: StoryEventBase["origin"];
|
|
222
|
-
notes: ReportNote[];
|
|
223
|
-
error?: StoryError;
|
|
224
|
-
};
|
|
225
|
-
/** @deprecated Use StoryReport instead */
|
|
226
|
-
type StorySummaryData = StoryReport;
|
|
227
|
-
type FormattedReport = {
|
|
228
|
-
text: string;
|
|
229
|
-
data: StoryReport;
|
|
230
|
-
};
|
|
231
|
-
/** @deprecated Use FormattedReport instead */
|
|
232
|
-
type StorySummary = FormattedReport;
|
|
233
|
-
type StoryEvent = StoryEventBase & {
|
|
234
|
-
kind: "story";
|
|
235
|
-
summarize: (options?: ReportOptions) => FormattedReport;
|
|
236
|
-
};
|
|
237
|
-
/** @deprecated Use StoryEvent — the story-shaped emission */
|
|
238
|
-
type StoryEmission = StoryEvent;
|
|
239
|
-
/** The two things an audience can hear */
|
|
240
|
-
type EmissionKind = "note" | "story";
|
|
241
|
-
/**
|
|
242
|
-
* A single beat, delivered the moment it happens when narration is live.
|
|
243
|
-
*
|
|
244
|
-
* `storyId` and `sequence` are what make streaming lossless: a consumer holding
|
|
245
|
-
* the beats of a story can order and group them back into the record that
|
|
246
|
-
* collected narration would have produced.
|
|
247
|
-
*/
|
|
248
|
-
type NoteEmission = StoryNote & {
|
|
249
|
-
kind: "note";
|
|
250
|
-
storyId: string;
|
|
251
|
-
parentStoryId?: string;
|
|
252
|
-
sequence: number;
|
|
253
|
-
level: StoryLevel;
|
|
254
|
-
origin?: StoryOrigin;
|
|
255
|
-
};
|
|
256
|
-
type Emission = NoteEmission | StoryEvent;
|
|
257
|
-
type AudienceMember = {
|
|
258
|
-
name: string;
|
|
259
|
-
/**
|
|
260
|
-
* Which emission kinds this audience wants. Defaults to `["story"]`, so an
|
|
261
|
-
* audience written before live narration existed keeps hearing only stories.
|
|
262
|
-
*/
|
|
263
|
-
hears?: EmissionKind[];
|
|
264
|
-
/**
|
|
265
|
-
* Declared with method syntax deliberately. TypeScript checks method parameters
|
|
266
|
-
* bivariantly, so an audience written as `hear: (event: StoryEvent) => void`
|
|
267
|
-
* still compiles. That would be unsound if such an audience could receive a note
|
|
268
|
-
* emission — it cannot, because `hears` defaults to stories only.
|
|
269
|
-
*/
|
|
270
|
-
accepts?(emission: Emission): boolean;
|
|
271
|
-
hear(emission: Emission): void | Promise<void>;
|
|
272
|
-
};
|
|
273
|
-
/**
|
|
274
|
-
* How a storyteller narrates.
|
|
275
|
-
*
|
|
276
|
-
* - `collected` — beats are buffered and leave as one story record (the default)
|
|
277
|
-
* - `live` — each beat is emitted as it happens, and the story still lands at the end
|
|
278
|
-
*
|
|
279
|
-
* Live narration adds emissions, it never removes them: a consumer that only wants
|
|
280
|
-
* beats says so with `hears: ["note"]` rather than by silencing the record.
|
|
281
|
-
*/
|
|
282
|
-
type Narration = "collected" | "live";
|
|
283
|
-
/** @deprecated `both` is now the behavior of `live` — beats stream and the story still lands */
|
|
284
|
-
type NarrationInput = Narration | "both";
|
|
285
|
-
type NoteData = {
|
|
286
|
-
who?: StoryContextInput;
|
|
287
|
-
what?: StoryContextInput;
|
|
288
|
-
where?: StoryContextInput;
|
|
289
|
-
error?: unknown;
|
|
290
|
-
/** Level for this beat alone. Defaults to Information. */
|
|
291
|
-
level?: LevelInput;
|
|
292
|
-
/** Emit this beat immediately even when narration is collected */
|
|
293
|
-
live?: boolean;
|
|
294
|
-
/** Deliver this beat only to the named audiences */
|
|
295
|
-
to?: string[];
|
|
296
|
-
};
|
|
297
|
-
type FinishOptions = {
|
|
298
|
-
/** Defaults to Information */
|
|
299
|
-
level?: LevelInput;
|
|
300
|
-
/** The error that ended the story, normalized onto the record */
|
|
301
|
-
error?: unknown;
|
|
302
|
-
};
|
|
303
|
-
type ChapterOptions = {
|
|
304
|
-
/** Merged over the parent's origin */
|
|
305
|
-
origin?: StoryOriginInput;
|
|
306
|
-
/** Defaults to the parent's setting */
|
|
307
|
-
narration?: NarrationInput;
|
|
308
|
-
/** Defaults to the parent's setting */
|
|
309
|
-
level?: LevelInput;
|
|
310
|
-
/** Defaults to the parent's handler */
|
|
311
|
-
onAudienceError?: AudienceErrorHandler;
|
|
312
|
-
/** Defaults to the parent's bound */
|
|
313
|
-
maxInFlight?: number;
|
|
314
|
-
};
|
|
315
|
-
type StorytellerOptions = {
|
|
316
|
-
origin?: StoryOriginInput;
|
|
317
|
-
audiences?: AudienceMember[];
|
|
318
|
-
/** Defaults to `STORYTELLER_NARRATION`, then `collected` */
|
|
319
|
-
narration?: NarrationInput;
|
|
320
|
-
/**
|
|
321
|
-
* Which default audience to register: colorized text for a person, NDJSON for a
|
|
322
|
-
* program. Defaults to `STORYTELLER_FORMAT`, then `text`.
|
|
323
|
-
*/
|
|
324
|
-
format?: OutputFormat;
|
|
325
|
-
/**
|
|
326
|
-
* Share another storyteller's audience registry instead of creating one.
|
|
327
|
-
* Audiences added to it later reach this storyteller too. When given, no
|
|
328
|
-
* default audience is registered — the registry already has whatever it has.
|
|
329
|
-
*/
|
|
330
|
-
audience?: AudienceRegistry;
|
|
331
|
-
/** The story this one is a chapter of. Set by `chapter()`. */
|
|
332
|
-
parentStoryId?: string;
|
|
333
|
-
/**
|
|
334
|
-
* Drop emissions below this level before they reach any audience.
|
|
335
|
-
* Defaults to `STORYTELLER_LEVEL`, then Information (deliver everything).
|
|
336
|
-
*/
|
|
337
|
-
level?: LevelInput;
|
|
338
|
-
/**
|
|
339
|
-
* Called when an audience throws or rejects. Without one, a single throttled
|
|
340
|
-
* warning per audience goes to the console — a logging library that loses
|
|
341
|
-
* records in silence is worse than one that complains.
|
|
342
|
-
*/
|
|
343
|
-
onAudienceError?: AudienceErrorHandler;
|
|
344
|
-
/**
|
|
345
|
-
* Cap on deliveries in flight to a single audience at once. Live narration is
|
|
346
|
-
* fire-and-forget, so a slow audience would otherwise grow an unbounded queue.
|
|
347
|
-
* Past the cap, emissions are dropped and counted on the closing story.
|
|
348
|
-
*/
|
|
349
|
-
maxInFlight?: number;
|
|
350
|
-
};
|
|
351
|
-
/** Called when an audience member throws or rejects while hearing an emission */
|
|
352
|
-
type AudienceErrorHandler = (error: unknown, member: AudienceMember, emission: Emission) => void;
|
|
353
|
-
/** Manages the set of audience members that receive story events */
|
|
354
|
-
declare class AudienceRegistry {
|
|
355
|
-
private members;
|
|
356
|
-
/** Register an audience member, replacing any existing member with the same name */
|
|
357
|
-
add(member: AudienceMember): this;
|
|
358
|
-
/** Remove an audience member by name */
|
|
359
|
-
remove(name: string): this;
|
|
360
|
-
/** Return all registered audience members */
|
|
361
|
-
getAll(): AudienceMember[];
|
|
362
|
-
/** Return only the audience members matching the given names */
|
|
363
|
-
getOnly(names: string[]): AudienceMember[];
|
|
364
|
-
/** Check if an audience member is registered by name */
|
|
365
|
-
has(name: string): boolean;
|
|
366
|
-
/** List the names of all registered audience members */
|
|
367
|
-
names(): string[];
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Collects timestamped notes and emits them as one structured story — and, when
|
|
371
|
-
* narration is live, emits each note the moment it is taken.
|
|
372
|
-
*
|
|
373
|
-
* @example
|
|
374
|
-
* ```ts
|
|
375
|
-
* const story = new Storyteller({ origin: { who: "api-server" }, narration: "live" });
|
|
376
|
-
* story.report("Request received", { what: { path: "/checkout" } });
|
|
377
|
-
* story.report("Validated cart");
|
|
378
|
-
* story.finish("Checkout started");
|
|
379
|
-
* ```
|
|
380
|
-
*/
|
|
381
|
-
declare class Storyteller {
|
|
382
|
-
readonly audience: AudienceRegistry;
|
|
383
|
-
private readonly origin?;
|
|
384
|
-
private readonly parentStoryId?;
|
|
385
|
-
private notes;
|
|
386
|
-
private narration;
|
|
387
|
-
private readonly minimumLevel;
|
|
388
|
-
private readonly onAudienceError;
|
|
389
|
-
private readonly maxInFlight;
|
|
390
|
-
/** Deliveries currently awaiting each audience, keyed by audience name */
|
|
391
|
-
private readonly inFlight;
|
|
392
|
-
/** Emissions dropped for back-pressure since the current story began */
|
|
393
|
-
private droppedEmissions;
|
|
394
|
-
/** Identifies the story currently being collected; regenerated after each telling */
|
|
395
|
-
private storyId;
|
|
396
|
-
/** Position of the next note within the current story */
|
|
397
|
-
private nextSequence;
|
|
398
|
-
constructor(options?: StorytellerOptions);
|
|
399
|
-
/**
|
|
400
|
-
* Switch between collected and live narration at runtime.
|
|
401
|
-
* Takes effect on the next note; already-buffered notes are not replayed.
|
|
402
|
-
*
|
|
403
|
-
* @param narration - `collected` to buffer, `live` to emit each note as it happens
|
|
404
|
-
* @returns `this` for chaining
|
|
405
|
-
*/
|
|
406
|
-
narrate(narration: NarrationInput): this;
|
|
407
|
-
/** The id of the story currently being collected */
|
|
408
|
-
get currentStoryId(): string;
|
|
409
|
-
/**
|
|
410
|
-
* Start a chapter: a child storyteller whose stories are linked back to this
|
|
411
|
-
* one by `parentStoryId`.
|
|
412
|
-
*
|
|
413
|
-
* Real work nests — an agent spawns subtasks, a batch runs per-item operations.
|
|
414
|
-
* A chapter keeps each of those a complete story in its own right while leaving
|
|
415
|
-
* the run reconstructable as a tree.
|
|
416
|
-
*
|
|
417
|
-
* The child shares this storyteller's audience registry, so audiences added
|
|
418
|
-
* later reach it too, and inherits narration, level and delivery settings.
|
|
419
|
-
* Its stories are separate records — a chapter is not folded into the parent's
|
|
420
|
-
* notes.
|
|
421
|
-
*
|
|
422
|
-
* @param options - Origin to merge over the parent's, and any setting to override
|
|
423
|
-
* @returns A child Storyteller
|
|
424
|
-
*
|
|
425
|
-
* @example
|
|
426
|
-
* ```ts
|
|
427
|
-
* for (const account of accounts) {
|
|
428
|
-
* const chapter = story.chapter({ origin: { what: account.id } });
|
|
429
|
-
* chapter.report("Fetching invoices");
|
|
430
|
-
* chapter.finish(`Synced ${account.id}`);
|
|
431
|
-
* }
|
|
432
|
-
* ```
|
|
433
|
-
*/
|
|
434
|
-
chapter(options?: ChapterOptions): Storyteller;
|
|
435
|
-
/**
|
|
436
|
-
* Report a beat of the current story.
|
|
437
|
-
*
|
|
438
|
-
* In collected narration the beat is buffered and leaves with the story. In live
|
|
439
|
-
* narration it is emitted the moment you call this, so whoever is tuned in sees
|
|
440
|
-
* the work as it happens.
|
|
441
|
-
*
|
|
442
|
-
* Accepts anything, not just a string — pass an error, an API response, a Map, a
|
|
443
|
-
* class instance — and the value is normalized into a storable shape with the note
|
|
444
|
-
* text derived from it.
|
|
445
|
-
*
|
|
446
|
-
* @param input - What happened: a message, or any value to describe
|
|
447
|
-
* @param data - Optional context: who did it, what was involved, where it happened, any error
|
|
448
|
-
* @returns `this` for chaining
|
|
449
|
-
*
|
|
450
|
-
* @example
|
|
451
|
-
* ```ts
|
|
452
|
-
* story.report("Card charged", { what: { amount: "$42" }, where: "stripe" });
|
|
453
|
-
* story.report(await response.json());
|
|
454
|
-
* ```
|
|
455
|
-
*/
|
|
456
|
-
report(input: unknown, data?: NoteData): this;
|
|
457
|
-
/** Clear all accumulated notes without emitting a story, and start a new story id */
|
|
458
|
-
reset(): this;
|
|
459
|
-
/** Preview the current notes as a formatted report without emitting or clearing them */
|
|
460
|
-
summarize(options?: PreviewOptions): FormattedReport;
|
|
461
|
-
/**
|
|
462
|
-
* Finish the story: emit everything collected so far as one record, and start fresh.
|
|
463
|
-
*
|
|
464
|
-
* @param title - What the story was about
|
|
465
|
-
* @param options - Level, and the error that ended it
|
|
466
|
-
* @returns A one-shot handle whose `.to()` overrides the audience list — call it
|
|
467
|
-
* synchronously, delivery happens on the next microtask
|
|
468
|
-
*
|
|
469
|
-
* @example
|
|
470
|
-
* ```ts
|
|
471
|
-
* story.finish("Sync complete");
|
|
472
|
-
* story.finish("Sync failed", { level: "oops", error }).to("db");
|
|
473
|
-
* ```
|
|
474
|
-
*/
|
|
475
|
-
finish(title: string, options?: FinishOptions): {
|
|
476
|
-
to: (...names: string[]) => void;
|
|
477
|
-
};
|
|
478
|
-
/** @deprecated Use `finish(title)`. Removed at 1.0. */
|
|
479
|
-
tell(title: string): {
|
|
480
|
-
to: (...names: string[]) => void;
|
|
481
|
-
};
|
|
482
|
-
/** @deprecated Use `finish(title, { level: "warn" })`. Removed at 1.0. */
|
|
483
|
-
warn(title: string): {
|
|
484
|
-
to: (...names: string[]) => void;
|
|
485
|
-
};
|
|
486
|
-
/** @deprecated Use `finish(title, { level: "oops", error })`. Removed at 1.0. */
|
|
487
|
-
oops(title: string, error?: unknown): {
|
|
488
|
-
to: (...names: string[]) => void;
|
|
489
|
-
};
|
|
490
|
-
/** @deprecated Use `report()`. Removed at 1.0. */
|
|
491
|
-
note(input: unknown, data?: NoteData): this;
|
|
492
|
-
/** Emit a single note to the audiences listening for notes */
|
|
493
|
-
private emitNote;
|
|
494
|
-
/** Build a story event and schedule delivery, returning a handle to override the audience list */
|
|
495
|
-
private createDelivery;
|
|
496
|
-
/** Assemble the story event from current notes and start a fresh story */
|
|
497
|
-
private buildEvent;
|
|
498
|
-
/** Begin a new story: fresh id, sequence back to zero */
|
|
499
|
-
private startNewStory;
|
|
500
|
-
/** Deliver an emission to the audience members listening for its kind */
|
|
501
|
-
private deliver;
|
|
502
|
-
/** Run an audience's accepts() without letting a throw from it lose the emission */
|
|
503
|
-
private acceptsSafely;
|
|
504
|
-
/**
|
|
505
|
-
* Hand an emission to one audience, keeping its failures and its slowness
|
|
506
|
-
* contained: a throw is reported rather than swallowed, and a backlog is dropped
|
|
507
|
-
* rather than grown without limit.
|
|
508
|
-
*/
|
|
509
|
-
private hearSafely;
|
|
510
|
-
/** Report an audience failure without ever letting it reach caller code */
|
|
511
|
-
private handleAudienceError;
|
|
512
|
-
}
|
|
1
|
+
import { S as StoryEventBase, R as ReportOptions, F as FormattedReport, a as StoryOriginInput, N as NarrationInput, b as Storyteller, A as AudienceMember, E as EmissionKind, c as StoryEvent, d as StoryLevel, e as StoryStore, f as StoryOrigin, J as JsonValue, g as StoryError } from './stories-BgN4BSoZ.cjs';
|
|
2
|
+
export { v as AnyAudienceMember, B as AudienceErrorHandler, D as AudienceRegistry, O as CanonicalRow, C as ChapterOptions, H as DEFAULT_REDACT_KEYS, $ as DurationInput, t as Emission, u as EmissionOf, y as FinishOptions, L as LevelInput, w as Narration, G as NormalizeOptions, x as NoteData, s as NoteEmission, a4 as OutputFormat, P as PreviewOptions, M as REDACTED, m as ReportNote, Q as StoredStory, a0 as StoriesOptions, i as StoryContextInput, h as StoryContextValue, r as StoryEmission, j as StoryNote, l as StoryPreviewOptions, T as StoryQuery, a3 as StoryQueryBuilder, o as StoryReport, q as StorySummary, p as StorySummaryData, n as StorySummaryNote, k as StorySummaryOptions, z as StorytellerOptions, U as ToStoredStoryOptions, V as applyQuery, W as canonicalRow, X as flattenOrigin, Y as matchesQuery, a8 as meetsLevel, K as normalizeError, I as normalizeValue, a1 as parseDuration, a6 as readEnvironmentValue, aa as resolveColors, a7 as resolveMinimumLevel, a9 as resolveOutputFormat, a2 as stories, Z as storySearchText, _ as toStoredStory, a5 as toStoryLevel } from './stories-BgN4BSoZ.cjs';
|
|
513
3
|
|
|
514
4
|
/**
|
|
515
5
|
* Format a story event into a human-readable report with optional colors.
|
|
@@ -570,7 +60,7 @@ type ConsoleAudienceOptions = {
|
|
|
570
60
|
* story.audience.add(consoleAudience());
|
|
571
61
|
* ```
|
|
572
62
|
*/
|
|
573
|
-
declare function consoleAudience(options?: ConsoleAudienceOptions): AudienceMember
|
|
63
|
+
declare function consoleAudience(options?: ConsoleAudienceOptions): AudienceMember<EmissionKind>;
|
|
574
64
|
|
|
575
65
|
/**
|
|
576
66
|
* Create an audience that stores warn and oops stories via your insert function.
|
|
@@ -623,7 +113,57 @@ type NdjsonAudienceOptions = {
|
|
|
623
113
|
* story.audience.add(ndjsonAudience({ stream: process.stderr }));
|
|
624
114
|
* ```
|
|
625
115
|
*/
|
|
626
|
-
declare function ndjsonAudience(options?: NdjsonAudienceOptions): AudienceMember
|
|
116
|
+
declare function ndjsonAudience(options?: NdjsonAudienceOptions): AudienceMember<EmissionKind>;
|
|
117
|
+
|
|
118
|
+
type MemoryStoreOptions = {
|
|
119
|
+
/**
|
|
120
|
+
* How many stories to keep before the oldest are forgotten. A process that
|
|
121
|
+
* runs for a month must not grow without bound. Default 10 000.
|
|
122
|
+
*/
|
|
123
|
+
capacity?: number;
|
|
124
|
+
};
|
|
125
|
+
type MemoryStore = StoryStore & {
|
|
126
|
+
/** How many stories are kept right now */
|
|
127
|
+
readonly size: number;
|
|
128
|
+
/** Forget everything */
|
|
129
|
+
clear(): void;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* The reference StoryStore: a Map, no dependencies, browser-safe.
|
|
133
|
+
*
|
|
134
|
+
* Every other adapter is measured against this one — same query, same
|
|
135
|
+
* results. It is also the right store for tests, for a CLI run that reads its
|
|
136
|
+
* own stories back before exiting, and for a browser session.
|
|
137
|
+
*/
|
|
138
|
+
declare function memoryStore(options?: MemoryStoreOptions): MemoryStore;
|
|
139
|
+
|
|
140
|
+
type StoreAudienceOptions = {
|
|
141
|
+
/** Register under a different name, e.g. to feed two stores */
|
|
142
|
+
name?: string;
|
|
143
|
+
/** Minimum level to keep. Default: everything. */
|
|
144
|
+
level?: StoryLevel;
|
|
145
|
+
/** A further filter, on top of the level */
|
|
146
|
+
accepts?: (event: StoryEvent) => boolean;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* The bridge from delivery to persistence: every story the audience hears is
|
|
150
|
+
* appended to the store, unchanged.
|
|
151
|
+
*
|
|
152
|
+
* Keeps everything by default. Storage that only keeps failures cannot answer
|
|
153
|
+
* "what happened", only "what broke" — and a store has `prune()` for the rest.
|
|
154
|
+
*
|
|
155
|
+
* A store that rejects is reported through `onAudienceError`, like any other
|
|
156
|
+
* audience failure; nothing propagates into the code that told the story.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* const stories = memoryStore();
|
|
161
|
+
* story.audience.add(storeAudience(stories));
|
|
162
|
+
* // later
|
|
163
|
+
* await stories.query({ failed: true, since: new Date(Date.now() - 3_600_000) });
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
declare function storeAudience(store: StoryStore, options?: StoreAudienceOptions): AudienceMember;
|
|
627
167
|
|
|
628
168
|
type StoryReportOptions = {
|
|
629
169
|
timezone?: string;
|
|
@@ -664,4 +204,4 @@ declare function summarizeContext(note: {
|
|
|
664
204
|
error?: StoryError;
|
|
665
205
|
}): string | undefined;
|
|
666
206
|
|
|
667
|
-
export { ANSI,
|
|
207
|
+
export { ANSI, AudienceMember, type ConsoleAudienceOptions, EmissionKind, FormattedReport, JsonValue, type LineWriter, type MemoryStore, type MemoryStoreOptions, NarrationInput, type NdjsonAudienceOptions, ReportOptions, type StoreAudienceOptions, StoryError, StoryEvent, StoryEventBase, StoryLevel, StoryOrigin, StoryOriginInput, type StoryReportOptions, StoryStore, Storyteller, consoleAudience, dbAudience, formatDuration, formatOrigin, formatStory, getLevelColor, memoryStore, ndjsonAudience, storeAudience, summarizeContext, summarizeStory, useStoryteller, writeStoryReport };
|