runtime-reporter 0.4.1 → 0.4.2

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 +138 -64
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -1,21 +1,116 @@
1
1
  # Runtime Reporter
2
2
 
3
- Structured runtime events for applications and frameworks. A composable foundation for logging, messaging, and runtime reporting.
3
+ Structured runtime reporting that is type-safe, centralized, and production-ready for frameworks and applications
4
4
 
5
- Modern applications often rely on complex logging solutions or ad-hoc messaging systems to understand runtime behavior. These approaches can be difficult to integrate or are tightly coupled to specific environments. Runtime Reporter provides a lightweight, structured runtime event layer designed to simplify logging and messaging while remaining performant, secure, and framework-agnostic.
5
+ ## Why Runtime Reporter?
6
+
7
+ Most projects eventually accumulate:
8
+
9
+ - duplicated log messages
10
+ - inconsistent error wording
11
+ - fragile test assertions
12
+ - accidental exposure of sensitive data
13
+
14
+ Runtime Reporter replaces ad-hoc logging with structured, code-based messaging.
15
+
16
+ ## Who is Runtime Reporter for?
17
+
18
+ Use Runtime Reporter if:
19
+
20
+ - you're building a framework or library
21
+ - you want to avoid exposing sensitive information in production
22
+ - you want stable error codes for debugging and tracing runtime behavior
23
+ - you want to avoid bloat from verbose console messages
24
+ - you want a lightweight tool (~2 KB minified) that is easy to use
25
+ - you want to avoid duplicating message text in tests
6
26
 
7
27
  ## Features
8
28
 
9
- - **Centralized messages**: Define message text once and reference it everywhere using stable message codes.
10
- - **Code-based messaging**: Structured message identifiers make debugging and tracing runtime behavior easier.
11
- - **Security conscious**: Prevent accidental exposure of sensitive data by omitting message definitions in production.
12
- - **Type-safe**: Autocomplete and compile-time validation for message codes and template tokens.
13
- - **Tokenized templates**: Inject runtime data using structured, reusable message templates.
14
- - **Test friendly**: Assert against resolved messages without duplicating message text in tests.
15
- - **Tree-shakeable**: Ship an empty message set in production to minimize bundle size.
16
- - **Small footprint**: ~2 KB minified with negligible runtime overhead.
17
- - **Zero dependencies**: Fully self-contained with no runtime dependencies.
18
- - **Scales with your application**: Works equally well for small projects and large frameworks.
29
+ If you are new to Runtime Reporter, take a moment to explore the its core features.
30
+
31
+ ### Basic usage
32
+
33
+ Getting started is easy. Create a reporter instance with your messages and start logging.
34
+
35
+ ```ts
36
+ import { createReporter } from "runtime-reporter";
37
+
38
+ const reporter = createReporter({
39
+ ERR01: "MyComponent failed at mount",
40
+ });
41
+
42
+ reporter.error("ERR01");
43
+ ```
44
+
45
+ ### Code-based messaging
46
+
47
+ Replace inline strings with centralized, code-based identifiers.
48
+
49
+ ```ts
50
+ // Without runtime-reporter (logs "MyComponent failed at mount")
51
+ console.error("MyComponent failed at mount");
52
+
53
+ // With runtime-reporter (logs "MyComponent failed at mount (ERR01)")
54
+ reporter.error("ERR01");
55
+ ```
56
+
57
+ ### Dynamic messages
58
+
59
+ Inject runtime data into your messages via message templates and tokenized variables.
60
+
61
+ ```ts
62
+ const reporter = createReporter({
63
+ ERR01: "{{ componentName }} failed at {{ phase }}",
64
+ });
65
+
66
+ reporter.error("ERR01", { componentName: "MyComponent", phase: "mount" });
67
+ ```
68
+
69
+ ### Type safety
70
+
71
+ Annotate your messages to get autocomplete and compile-time validation for message codes and token names.
72
+
73
+ ```ts
74
+ const messages: RuntimeReporterMessages<{
75
+ code: "ERR01";
76
+ template: "{{ componentName }} failed at {{ phase }}";
77
+ tokens: "componentName" | "phase";
78
+ }> = {
79
+ ERR01: "{{ componentName }} failed at {{ phase }}",
80
+ };
81
+
82
+ const reporter = createReporter(messages);
83
+
84
+ reporter.error("ERR01", { componentName: "MyComponent", phase: "mount" }); // ✅ Autocomplete
85
+ reporter.error("ERR01", { componentName: "MyComponent" }); // ❌ TypeScript Error: "phase" is required
86
+ reporter.error("ERR02", { componentName: "MyComponent", phase: "mount" }); // ❌ TypeScript Error: "ERR02" is not a valid message code
87
+ ```
88
+
89
+ ### Production builds
90
+
91
+ Pass an empty object to the `createReporter` function in production for better security and a smaller bundle size.
92
+
93
+ ```ts
94
+ const reporter = createReporter(
95
+ process.env.NODE_ENV === "production" ? ({} as typeof messages) : messages
96
+ );
97
+ ```
98
+
99
+ ### Test friendly
100
+
101
+ Assert against resolved messages without duplicating message text in your test environment.
102
+
103
+ ```ts
104
+ it("should log error if component fails to mount", () => {
105
+ vi.spyOn(console, "error").mockImplementation(() => {});
106
+
107
+ render(<MyComponent />);
108
+
109
+ expect(console.error).toHaveBeenCalledWith(
110
+ reporter.message("ERR01", { componentName: "MyComponent", phase: "mount" })
111
+ );
112
+ });
113
+ ```
19
114
 
20
115
  ## Installation
21
116
 
@@ -23,14 +118,14 @@ Modern applications often rely on complex logging solutions or ad-hoc messaging
23
118
  npm install runtime-reporter
24
119
  ```
25
120
 
26
- ## Usage
121
+ ## Quick start
27
122
 
28
- ### 1) Define your messages
29
-
30
- Define your messages by creating an object with the message "schema" (code + template + tokens) and keyed by their codes.
123
+ A copy-and-paste example of how to use Runtime Reporter in your project.
31
124
 
32
125
  ```ts
33
- import type { RuntimeReporterMessages } from "runtime-reporter";
126
+ // src/runtime-reporter.ts
127
+
128
+ import { createReporter, type RuntimeReporterMessages } from "runtime-reporter";
34
129
 
35
130
  const messages: RuntimeReporterMessages<
36
131
  | {
@@ -39,38 +134,34 @@ const messages: RuntimeReporterMessages<
39
134
  tokens: "componentName" | "phase";
40
135
  }
41
136
  | {
42
- code: "INFO01";
43
- template: "Ready";
137
+ code: "ERR02";
138
+ template: "Failed to load configuration";
44
139
  }
45
140
  > = {
46
141
  ERR01: "{{ componentName }} failed at {{ phase }}",
47
- INFO01: "Ready",
142
+ ERR02: "Failed to load configuration",
48
143
  };
49
- ```
50
-
51
- ### 2) Create the reporter
52
144
 
53
- Pass your messages to `createReporter()` to create a reporter instance.
145
+ /** The runtime reporter for <project-name> */
146
+ const reporter = createReporter(messages);
54
147
 
55
- ```ts
56
- import { createReporter } from "runtime-reporter";
57
-
58
- export const reporter = createReporter(
59
- // Pass an empty object in production for better security and a smaller bundle size
60
- process.env.NODE_ENV === "production" ? ({} as typeof messages) : messages
61
- );
148
+ export default reporter;
62
149
  ```
63
150
 
64
- ### 3) Use the reporter
65
-
66
- Call the various reporter methods wherever you need them.
151
+ Once your project's reporter is created, you can import and use it wherever you need it.
67
152
 
68
153
  ```ts
69
- reporter.error("ERR01", { componentName: "Router", phase: "mount" });
70
- // logs: "Router failed at mount (ERR01)"
154
+ // src/my-component.ts
71
155
 
72
- reporter.message("INFO01");
73
- // returns: "Ready (INFO01)"
156
+ import { reporter } from "./runtime-reporter";
157
+
158
+ export function MyComponent() {
159
+ useEffect(() => {
160
+ reporter.error("ERR01", { componentName: "MyComponent", phase: "mount" });
161
+ }, []);
162
+
163
+ return <div>My Component</div>;
164
+ }
74
165
  ```
75
166
 
76
167
  ## API
@@ -148,37 +239,20 @@ reporter.error("ERR01", { componentName: "Router", phase: "mount" });
148
239
  The `message` method returns the resolved string without side effects, allowing you to validate precise messaging without duplicating text.
149
240
 
150
241
  ```ts
151
- import { describe, it, expect, vi } from "vitest";
152
- import { reporter } from "./reporter";
153
-
154
- describe("reporter messages", () => {
155
- it("consoles error ERR01 correctly", () => {
156
- vi.spyOn(console, "error").mockImplementation(() => {});
157
- reporter.error("ERR01", { componentName: "Widget" });
158
-
159
- expect(console.error).toHaveBeenCalledWith(
160
- reporter.message("ERR01", { componentName: "Widget" })
161
- );
162
- });
163
- });
164
- ```
165
-
166
- ### Using the reporter without TypeScript
167
-
168
- You can use the reporter without TypeScript, you will just lose the type safety and autocomplete.
242
+ it("should log error if component fails to mount", () => {
243
+ vi.spyOn(console, "error").mockImplementation(() => {});
169
244
 
170
- ```js
171
- import { createReporter } from "runtime-reporter";
245
+ render(<MyComponent />);
172
246
 
173
- const reporter = createReporter({
174
- ERR01: "{{ componentName }} failed at {{ phase }}",
247
+ expect(console.error).toHaveBeenCalledWith(
248
+ reporter.message("ERR01", { componentName: "MyComponent", phase: "mount" })
249
+ );
175
250
  });
176
-
177
- reporter.error("ERR01", { componentName: "Router", phase: "mount" });
178
- // logs: "Router failed at mount (ERR01)"
179
251
  ```
180
252
 
181
- However, you can still get the same benefits as TypeScript by using JSDoc-style type annotations.
253
+ ### Type safety without TypeScript
254
+
255
+ You can still get the same benefits as TypeScript by using JSDoc-style type annotations.
182
256
 
183
257
  ```js
184
258
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "runtime-reporter",
3
- "version": "0.4.1",
4
- "description": "Structured runtime events for applications and frameworks. A composable foundation for logging, messaging, and runtime reporting.",
3
+ "version": "0.4.2",
4
+ "description": "Structured runtime reporting that is type-safe, centralized, and production-ready.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",