@logbrew/sdk 0.1.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 ADDED
@@ -0,0 +1,225 @@
1
+ # @logbrew/sdk
2
+
3
+ Public JavaScript SDK for creating LogBrew event batches, validating them locally, and flushing them through a transport.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @logbrew/sdk
9
+ pnpm add @logbrew/sdk
10
+ npm --prefix node_modules/@logbrew/sdk/examples run
11
+ npm --prefix node_modules/@logbrew/sdk/examples run list
12
+ npm --prefix node_modules/@logbrew/sdk/examples run help
13
+ npm --prefix node_modules/@logbrew/sdk/examples run readme-example
14
+ npm --prefix node_modules/@logbrew/sdk/examples run readme-example:cjs
15
+ npm --prefix node_modules/@logbrew/sdk/examples run real-user-smoke
16
+ npm --prefix node_modules/@logbrew/sdk/examples run real-user-smoke:cjs
17
+ pnpm --dir node_modules/@logbrew/sdk/examples run
18
+ pnpm --dir node_modules/@logbrew/sdk/examples run list
19
+ pnpm --dir node_modules/@logbrew/sdk/examples run help
20
+ pnpm --dir node_modules/@logbrew/sdk/examples run readme-example
21
+ pnpm --dir node_modules/@logbrew/sdk/examples run readme-example:cjs
22
+ pnpm --dir node_modules/@logbrew/sdk/examples run real-user-smoke
23
+ pnpm --dir node_modules/@logbrew/sdk/examples run real-user-smoke:cjs
24
+ node node_modules/@logbrew/sdk/examples/index.mjs --help
25
+ node node_modules/@logbrew/sdk/examples/index.mjs --list
26
+ node node_modules/@logbrew/sdk/examples/index.mjs readme-example
27
+ node node_modules/@logbrew/sdk/examples/index.mjs readme-example:cjs
28
+ node node_modules/@logbrew/sdk/examples/index.mjs real-user-smoke
29
+ node node_modules/@logbrew/sdk/examples/index.mjs
30
+ node node_modules/@logbrew/sdk/examples/index.mjs real-user-smoke:cjs
31
+ node node_modules/@logbrew/sdk/examples/readme-example.mjs
32
+ node node_modules/@logbrew/sdk/examples/readme-example.cjs
33
+ node node_modules/@logbrew/sdk/examples/real-user-smoke.mjs
34
+ node node_modules/@logbrew/sdk/examples/real-user-smoke.cjs
35
+ ```
36
+
37
+ The package supports both ESM `import` and CommonJS `require`.
38
+ The shipped package also includes `.d.ts` and `.d.cts` declarations so ESM and CommonJS TypeScript consumers can install it directly without a separate build step.
39
+ The packed tarball and installed package both ship `README.md`, package metadata, an explicit ESM/CommonJS `exports` map, runnable `examples/readme-example.mjs`, `examples/readme-example.cjs`, `examples/real-user-smoke.mjs`, and `examples/real-user-smoke.cjs` files, a tiny `examples/package.json` helper surface, a packaged `examples/index.mjs` launcher, declaration comments in `index.d.ts`, and the CommonJS `index.d.cts` declaration path that TypeScript-aware tools can inspect. Those packed and installed README, example, and declaration surfaces should still include the normal `npm` and `pnpm` install commands, the fake `LOGBREW_API_KEY` placeholder guidance, the `previewJson()` usage note, the optional `parseTraceparent()`, `createTraceparent()`, `spanAttributesFromTraceparent()`, `installLogBrewConsoleCapture()`, `createLogBrewPinoDestination()`, and `createLogBrewWinstonTransport()` guidance, the helper discovery commands, helper runtime commands, and launcher commands shown above, and the typed API docs for shapes like `ReleaseAttributes`, `SpanAttributes`, `TraceparentContext`, `TraceparentInput`, `TraceparentSpanInput`, `Event`, `ConsoleCaptureConfig`, `ConsoleCaptureHandle`, `PinoDestinationConfig`, `PinoDestinationHandle`, `PinoLogRecord`, `WinstonTransportConfig`, `WinstonTransportHandle`, `WinstonLogInfo`, `SdkError`, `TransportError`, `TransportResponse`, `alwaysAccept()`, `lastBody()`, `pendingEvents()`, `flush()`, and `shutdown()`. Real installs should also start from a package-manager-native app bootstrap, using `npm init -y` on the npm path and `pnpm init` on the pnpm path, then rewrite the temp app `package.json` dependencies plus the lockfiles so they point back to the packed `.tgz` with the expected file target and integrity metadata, while npm’s own `npm pack --dry-run --json` and `npm pack --json` outputs still report the expected tarball name, integrity, shasum, and file list, and those generated lockfiles should retain that same tarball integrity value before recreating the install through `npm ci` and `pnpm install --frozen-lockfile`. The temp app should also survive a package-manager-native removal step, with `npm uninstall @logbrew/sdk` and `pnpm remove @logbrew/sdk` dropping the SDK from `package.json`, the top-level installed-package list, and `node_modules` before the tarball is added back. The consumer graph should also stay explicit in package-manager-native output, with plain `npm ls @logbrew/sdk` and `pnpm ls @logbrew/sdk` showing the direct installed SDK tree a user reads in the terminal, `npm explain @logbrew/sdk` showing the direct root-project edge, `pnpm why @logbrew/sdk` showing the temp app dependency relationship, plain `npm list --depth=0` and `pnpm list --depth=0` showing the top-level installed dependency summary, and `npm list --json --depth=0` plus `pnpm list --json --depth=0` still listing the temp app and direct installed dependencies, while small installed-user script entries in the temp app still exercise the shipped package through `npm run` and `pnpm run`, including a TypeScript typecheck script that compiles both an ESM `.ts` consumer and a CommonJS `.cts` consumer plus a script that mirrors the published README example before and after reinstall. The installed package should also let a consumer run the shipped README-style and stronger happy-path ESM and CommonJS example files directly from `node_modules/@logbrew/sdk/examples/`, and it now ships a small Node launcher at `node node_modules/@logbrew/sdk/examples/index.mjs` so users can discover packaged examples through `--help`, list them through `--list`, run the default no-argument `real-user-smoke` path, or select named examples like `readme-example` and `real-user-smoke` without going through package-manager scripts. The helper commands in `node_modules/@logbrew/sdk/examples/package.json` should still be discoverable enough that plain `npm --prefix node_modules/@logbrew/sdk/examples run` and `pnpm --dir node_modules/@logbrew/sdk/examples run` list the available example entrypoints before users run `npm --prefix node_modules/@logbrew/sdk/examples run help`, where that help output should print copy-pasteable installed-user commands for both npm and pnpm across the README and `real-user-smoke` default, ESM, and CommonJS example paths, including `npm --prefix node_modules/@logbrew/sdk/examples run readme-example` or `pnpm --dir node_modules/@logbrew/sdk/examples run readme-example`, `npm --prefix node_modules/@logbrew/sdk/examples run readme-example:esm` or `pnpm --dir node_modules/@logbrew/sdk/examples run readme-example:esm`, `npm --prefix node_modules/@logbrew/sdk/examples run readme-example:cjs` or `pnpm --dir node_modules/@logbrew/sdk/examples run readme-example:cjs`, `npm --prefix node_modules/@logbrew/sdk/examples run real-user-smoke` or `pnpm --dir node_modules/@logbrew/sdk/examples run real-user-smoke`, `npm --prefix node_modules/@logbrew/sdk/examples run real-user-smoke:esm` or `pnpm --dir node_modules/@logbrew/sdk/examples run real-user-smoke:esm`, and `npm --prefix node_modules/@logbrew/sdk/examples run real-user-smoke:cjs` or `pnpm --dir node_modules/@logbrew/sdk/examples run real-user-smoke:cjs`, while the launcher surface itself should still reveal `node node_modules/@logbrew/sdk/examples/index.mjs --help`, `node node_modules/@logbrew/sdk/examples/index.mjs --list`, `node node_modules/@logbrew/sdk/examples/index.mjs`, `node node_modules/@logbrew/sdk/examples/index.mjs readme-example`, `node node_modules/@logbrew/sdk/examples/index.mjs real-user-smoke`, and `node node_modules/@logbrew/sdk/examples/index.mjs real-user-smoke:cjs`.
40
+
41
+ ## Example
42
+
43
+ ```js
44
+ import { LogBrewClient, RecordingTransport } from "@logbrew/sdk";
45
+
46
+ const client = LogBrewClient.create({
47
+ apiKey: "LOGBREW_API_KEY",
48
+ sdkName: "logbrew-js",
49
+ sdkVersion: "0.1.0"
50
+ });
51
+
52
+ client.release("evt_release_001", "2026-06-02T10:00:00Z", {
53
+ version: "1.2.3",
54
+ commit: "abc123def456",
55
+ notes: "Public release marker"
56
+ });
57
+ client.environment("evt_environment_001", "2026-06-02T10:00:01Z", {
58
+ name: "production",
59
+ region: "global"
60
+ });
61
+ client.issue("evt_issue_001", "2026-06-02T10:00:02Z", {
62
+ title: "Checkout timeout",
63
+ level: "error",
64
+ message: "Request timed out after retry budget"
65
+ });
66
+ client.log("evt_log_001", "2026-06-02T10:00:03Z", {
67
+ message: "worker started",
68
+ level: "info",
69
+ logger: "job-runner"
70
+ });
71
+ client.span("evt_span_001", "2026-06-02T10:00:04Z", {
72
+ name: "GET /health",
73
+ traceId: "trace_001",
74
+ spanId: "span_001",
75
+ status: "ok",
76
+ durationMs: 12.5
77
+ });
78
+ client.action("evt_action_001", "2026-06-02T10:00:05Z", {
79
+ name: "deploy",
80
+ status: "success"
81
+ });
82
+
83
+ console.log(client.previewJson());
84
+
85
+ const transport = RecordingTransport.alwaysAccept();
86
+ const response = await client.shutdown(transport);
87
+ console.error(JSON.stringify({ ok: true, status: response.statusCode, attempts: response.attempts, events: 6 }));
88
+ ```
89
+
90
+ ## W3C Trace Context
91
+
92
+ Use `parseTraceparent()`, `createTraceparent()`, and `spanAttributesFromTraceparent()` when a JavaScript service needs to continue trace context from OpenTelemetry-compatible services or pass a W3C `traceparent` value downstream.
93
+
94
+ ```js
95
+ import {
96
+ createTraceparent,
97
+ LogBrewClient,
98
+ RecordingTransport,
99
+ spanAttributesFromTraceparent
100
+ } from "@logbrew/sdk";
101
+
102
+ const client = LogBrewClient.create({
103
+ apiKey: "LOGBREW_API_KEY",
104
+ sdkName: "checkout-api",
105
+ sdkVersion: "1.0.0"
106
+ });
107
+
108
+ const incomingTraceparent = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01";
109
+ const span = spanAttributesFromTraceparent(incomingTraceparent, {
110
+ name: "POST /checkout",
111
+ spanId: "b7ad6b7169203331",
112
+ status: "ok",
113
+ durationMs: 18.4,
114
+ metadata: { service: "checkout" }
115
+ });
116
+ client.span("evt_checkout_span", "2026-06-02T10:00:04Z", span);
117
+
118
+ const downstreamTraceparent = createTraceparent({
119
+ traceId: span.traceId,
120
+ spanId: span.spanId,
121
+ traceFlags: "01"
122
+ });
123
+ await fetch("https://example.invalid/payments", {
124
+ headers: { traceparent: downstreamTraceparent }
125
+ });
126
+
127
+ await client.flush(RecordingTransport.alwaysAccept());
128
+ ```
129
+
130
+ The helpers validate the W3C `version-traceId-parentSpanId-traceFlags` shape, reject all-zero trace/span ids, normalize valid ids to lowercase, expose the sampled flag from `traceFlags`, and keep span metadata primitive-only. They do not install OpenTelemetry or patch HTTP clients; use them when you need explicit interop in code you own.
131
+
132
+ ## Console Capture
133
+
134
+ If an app already uses `console.info()`, `console.warn()`, or `console.error()`, install explicit capture on the console object you own:
135
+
136
+ ```js
137
+ import { installLogBrewConsoleCapture, LogBrewClient, RecordingTransport } from "@logbrew/sdk";
138
+
139
+ const client = LogBrewClient.create({
140
+ apiKey: "LOGBREW_API_KEY",
141
+ sdkName: "checkout-web",
142
+ sdkVersion: "1.0.0"
143
+ });
144
+ const transport = RecordingTransport.alwaysAccept();
145
+ const capture = installLogBrewConsoleCapture({
146
+ client,
147
+ console,
148
+ transport,
149
+ levels: ["warn", "error"],
150
+ logger: "console",
151
+ metadata: { service: "checkout" }
152
+ });
153
+
154
+ console.warn("cart queued", { orderId: 42 });
155
+ console.error("checkout failed", new Error("database unavailable"));
156
+ await capture.flush();
157
+ capture.uninstall();
158
+ ```
159
+
160
+ Console capture is opt-in. It calls the original console method first, captures only the configured levels, returns `uninstall()` so apps can stop capture cleanly, and omits error stack text unless `includeErrorStack: true` is set.
161
+
162
+ ## Pino Destination
163
+
164
+ If a Node app already uses Pino, pass the dependency-free LogBrew destination as Pino's output stream:
165
+
166
+ ```js
167
+ import pino from "pino";
168
+ import { createLogBrewPinoDestination, LogBrewClient, RecordingTransport } from "@logbrew/sdk";
169
+
170
+ const client = LogBrewClient.create({
171
+ apiKey: "LOGBREW_API_KEY",
172
+ sdkName: "checkout-api",
173
+ sdkVersion: "1.0.0"
174
+ });
175
+ const transport = RecordingTransport.alwaysAccept();
176
+ const destination = createLogBrewPinoDestination({
177
+ client,
178
+ transport,
179
+ logger: "pino",
180
+ metadata: { service: "checkout" }
181
+ });
182
+
183
+ const logger = pino(destination);
184
+ logger.warn({ orderId: 42 }, "checkout slow");
185
+ logger.error(new Error("payment failed"), "checkout failed");
186
+ await destination.flush();
187
+ ```
188
+
189
+ The Pino adapter reads JSON log lines, maps `trace`/`debug`/`info`/`warn`/`error`/`fatal` into LogBrew levels, captures primitive Pino fields as `context.*`, captures serialized error name/message, skips noisy runtime defaults, and omits stack text unless `includeErrorStack: true` is set. It does not patch Pino or replace application logger ownership.
190
+
191
+ ## Winston Transport
192
+
193
+ If a Node app already uses Winston, add the dependency-free LogBrew transport to the app-owned logger:
194
+
195
+ ```js
196
+ import winston from "winston";
197
+ import { createLogBrewWinstonTransport, LogBrewClient, RecordingTransport } from "@logbrew/sdk";
198
+
199
+ const client = LogBrewClient.create({
200
+ apiKey: "LOGBREW_API_KEY",
201
+ sdkName: "checkout-api",
202
+ sdkVersion: "1.0.0"
203
+ });
204
+ const transport = RecordingTransport.alwaysAccept();
205
+ const logbrewTransport = createLogBrewWinstonTransport({
206
+ client,
207
+ transport,
208
+ logger: "winston",
209
+ metadata: { service: "checkout" }
210
+ });
211
+
212
+ const logger = winston.createLogger({
213
+ level: "info",
214
+ format: winston.format.combine(winston.format.errors({ stack: true }), winston.format.timestamp()),
215
+ transports: [logbrewTransport]
216
+ });
217
+
218
+ logger.warn("checkout slow", { orderId: 42 });
219
+ logger.error(new Error("payment failed"));
220
+ await logbrewTransport.flush();
221
+ ```
222
+
223
+ The Winston adapter receives Winston `info` objects, maps `debug`/`silly` to `debug`, `warn` to `warning`, `error`/`fatal` to `error`, and other common Winston levels to `info`. It captures primitive info fields as `context.*`, captures nested `err`/`error` objects or formatted error stack name/message, omits stack text unless `includeErrorStack: true` is set, and exposes `onError` for capture failures. It does not mutate Winston globals or replace the app's logger.
224
+
225
+ Use a clearly fake placeholder like `LOGBREW_API_KEY` in local examples and tests. Call `flush` or `shutdown` to send queued events through a transport, and use `previewJson()` when you want a stable local JSON preview without sending anything.
@@ -0,0 +1,123 @@
1
+ import process from "node:process";
2
+
3
+ const repoPrefix = "cd js/logbrew-js";
4
+ const repoExamplesPrefix = "cd js/logbrew-js/examples";
5
+ const repoNpmHelperPrefix = "npm run";
6
+ const repoPnpmHelperPrefix = "pnpm run";
7
+ const installedHelperPrefix = "npm --prefix node_modules/@logbrew/sdk/examples run";
8
+ const installedPnpmHelperPrefix = "pnpm --dir node_modules/@logbrew/sdk/examples run";
9
+ const installedLauncherPrefix = "node node_modules/@logbrew/sdk/examples/index.mjs";
10
+ const repoLauncherPrefix = "node examples/index.mjs";
11
+
12
+ const examples = {
13
+ "readme-example": new URL("./readme-example.mjs", import.meta.url),
14
+ "readme-example:esm": new URL("./readme-example.mjs", import.meta.url),
15
+ "readme-example:cjs": new URL("./readme-example.cjs", import.meta.url),
16
+ "real-user-smoke": new URL("./real-user-smoke.mjs", import.meta.url),
17
+ "real-user-smoke:esm": new URL("./real-user-smoke.mjs", import.meta.url),
18
+ "real-user-smoke:cjs": new URL("./real-user-smoke.cjs", import.meta.url)
19
+ };
20
+
21
+ function isInstalledPackageContext() {
22
+ return import.meta.url.includes("/node_modules/@logbrew/sdk/examples/");
23
+ }
24
+
25
+ function exampleCommands() {
26
+ if (!isInstalledPackageContext()) {
27
+ return {
28
+ "readme-example": `${repoPrefix} && ${repoLauncherPrefix} readme-example`,
29
+ "readme-example:esm": `${repoPrefix} && ${repoLauncherPrefix} readme-example:esm`,
30
+ "readme-example:cjs": `${repoPrefix} && ${repoLauncherPrefix} readme-example:cjs`,
31
+ "real-user-smoke": `${repoPrefix} && ${repoLauncherPrefix} real-user-smoke`,
32
+ "real-user-smoke:esm": `${repoPrefix} && ${repoLauncherPrefix} real-user-smoke:esm`,
33
+ "real-user-smoke:cjs": `${repoPrefix} && ${repoLauncherPrefix} real-user-smoke:cjs`,
34
+ "default (real-user-smoke)": `${repoPrefix} && ${repoLauncherPrefix}`
35
+ };
36
+ }
37
+
38
+ return {
39
+ "readme-example": `${installedLauncherPrefix} readme-example`,
40
+ "readme-example:esm": `${installedLauncherPrefix} readme-example:esm`,
41
+ "readme-example:cjs": `${installedLauncherPrefix} readme-example:cjs`,
42
+ "real-user-smoke": `${installedLauncherPrefix} real-user-smoke`,
43
+ "real-user-smoke:esm": `${installedLauncherPrefix} real-user-smoke:esm`,
44
+ "real-user-smoke:cjs": `${installedLauncherPrefix} real-user-smoke:cjs`,
45
+ "default (real-user-smoke)": installedLauncherPrefix
46
+ };
47
+ }
48
+
49
+ function helperCommands() {
50
+ if (!isInstalledPackageContext()) {
51
+ return {
52
+ "readme-example": `${repoExamplesPrefix} && ${repoNpmHelperPrefix} readme-example | ${repoExamplesPrefix} && ${repoPnpmHelperPrefix} readme-example`,
53
+ "readme-example:esm": `${repoExamplesPrefix} && ${repoNpmHelperPrefix} readme-example:esm | ${repoExamplesPrefix} && ${repoPnpmHelperPrefix} readme-example:esm`,
54
+ "readme-example:cjs": `${repoExamplesPrefix} && ${repoNpmHelperPrefix} readme-example:cjs | ${repoExamplesPrefix} && ${repoPnpmHelperPrefix} readme-example:cjs`,
55
+ "real-user-smoke": `${repoExamplesPrefix} && ${repoNpmHelperPrefix} real-user-smoke | ${repoExamplesPrefix} && ${repoPnpmHelperPrefix} real-user-smoke`,
56
+ "real-user-smoke:esm": `${repoExamplesPrefix} && ${repoNpmHelperPrefix} real-user-smoke:esm | ${repoExamplesPrefix} && ${repoPnpmHelperPrefix} real-user-smoke:esm`,
57
+ "real-user-smoke:cjs": `${repoExamplesPrefix} && ${repoNpmHelperPrefix} real-user-smoke:cjs | ${repoExamplesPrefix} && ${repoPnpmHelperPrefix} real-user-smoke:cjs`
58
+ };
59
+ }
60
+
61
+ return {
62
+ "readme-example": `${installedHelperPrefix} readme-example | ${installedPnpmHelperPrefix} readme-example`,
63
+ "readme-example:esm": `${installedHelperPrefix} readme-example:esm | ${installedPnpmHelperPrefix} readme-example:esm`,
64
+ "readme-example:cjs": `${installedHelperPrefix} readme-example:cjs | ${installedPnpmHelperPrefix} readme-example:cjs`,
65
+ "real-user-smoke": `${installedHelperPrefix} real-user-smoke | ${installedPnpmHelperPrefix} real-user-smoke`,
66
+ "real-user-smoke:esm": `${installedHelperPrefix} real-user-smoke:esm | ${installedPnpmHelperPrefix} real-user-smoke:esm`,
67
+ "real-user-smoke:cjs": `${installedHelperPrefix} real-user-smoke:cjs | ${installedPnpmHelperPrefix} real-user-smoke:cjs`
68
+ };
69
+ }
70
+
71
+ function printList() {
72
+ for (const [name, command] of Object.entries(exampleCommands())) {
73
+ console.log(`${name} -> ${command}`);
74
+ }
75
+ }
76
+
77
+ function printHelp() {
78
+ if (isInstalledPackageContext()) {
79
+ console.log("Usage: node node_modules/@logbrew/sdk/examples/index.mjs [--list] [example]");
80
+ console.log("Run the packaged LogBrew SDK JavaScript examples that ship with the installed package.");
81
+ } else {
82
+ console.log("Usage: node examples/index.mjs [--list] [example]");
83
+ console.log("Run the repo-checkout LogBrew SDK JavaScript examples before install.");
84
+ }
85
+ console.log("");
86
+ console.log("Launcher commands:");
87
+ for (const [name, command] of Object.entries(exampleCommands())) {
88
+ console.log(` ${name} -> ${command}`);
89
+ }
90
+ console.log("");
91
+ console.log("Package-manager helper commands:");
92
+ for (const [name, command] of Object.entries(helperCommands())) {
93
+ console.log(` ${name} -> ${command}`);
94
+ }
95
+ }
96
+
97
+ async function main(argv = process.argv.slice(2)) {
98
+ if (argv.includes("--help") || argv.includes("-h")) {
99
+ printHelp();
100
+ return 0;
101
+ }
102
+
103
+ if (argv.includes("--list")) {
104
+ printList();
105
+ return 0;
106
+ }
107
+
108
+ const [example = "real-user-smoke"] = argv;
109
+ const target = examples[example];
110
+ if (!target) {
111
+ console.error(`unknown example: ${example}`);
112
+ printHelp();
113
+ return 1;
114
+ }
115
+
116
+ await import(target.href);
117
+ return 0;
118
+ }
119
+
120
+ const exitCode = await main();
121
+ if (exitCode !== 0) {
122
+ process.exit(exitCode);
123
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "private": true,
3
+ "type": "module",
4
+ "scripts": {
5
+ "help": "node ./index.mjs --help",
6
+ "list": "node ./index.mjs --list",
7
+ "readme-example": "node ./index.mjs readme-example",
8
+ "readme-example:esm": "node ./index.mjs readme-example:esm",
9
+ "readme-example:cjs": "node ./index.mjs readme-example:cjs",
10
+ "real-user-smoke": "node ./index.mjs real-user-smoke",
11
+ "real-user-smoke:esm": "node ./index.mjs real-user-smoke:esm",
12
+ "real-user-smoke:cjs": "node ./index.mjs real-user-smoke:cjs"
13
+ }
14
+ }
@@ -0,0 +1,59 @@
1
+ let sdk;
2
+ try {
3
+ sdk = require("@logbrew/sdk");
4
+ } catch (error) {
5
+ if (error && error.code === "MODULE_NOT_FOUND") {
6
+ sdk = require("../index.cjs");
7
+ } else {
8
+ throw error;
9
+ }
10
+ }
11
+
12
+ const { LogBrewClient, RecordingTransport } = sdk;
13
+
14
+ const client = LogBrewClient.create({
15
+ apiKey: "LOGBREW_API_KEY",
16
+ sdkName: "logbrew-js",
17
+ sdkVersion: "0.1.0"
18
+ });
19
+
20
+ client.release("evt_release_001", "2026-06-02T10:00:00Z", {
21
+ version: "1.2.3",
22
+ commit: "abc123def456",
23
+ notes: "Public release marker"
24
+ });
25
+ client.environment("evt_environment_001", "2026-06-02T10:00:01Z", {
26
+ name: "production",
27
+ region: "global"
28
+ });
29
+ client.issue("evt_issue_001", "2026-06-02T10:00:02Z", {
30
+ title: "Checkout timeout",
31
+ level: "error",
32
+ message: "Request timed out after retry budget"
33
+ });
34
+ client.log("evt_log_001", "2026-06-02T10:00:03Z", {
35
+ message: "worker started",
36
+ level: "info",
37
+ logger: "job-runner"
38
+ });
39
+ client.span("evt_span_001", "2026-06-02T10:00:04Z", {
40
+ name: "GET /health",
41
+ traceId: "trace_001",
42
+ spanId: "span_001",
43
+ status: "ok",
44
+ durationMs: 12.5
45
+ });
46
+ client.action("evt_action_001", "2026-06-02T10:00:05Z", {
47
+ name: "deploy",
48
+ status: "success"
49
+ });
50
+
51
+ console.log(client.previewJson());
52
+
53
+ const transport = RecordingTransport.alwaysAccept();
54
+ client.shutdown(transport).then((response) => {
55
+ console.error(JSON.stringify({ ok: true, status: response.statusCode, attempts: response.attempts, events: 6 }));
56
+ }).catch((error) => {
57
+ console.error(error);
58
+ process.exit(1);
59
+ });
@@ -0,0 +1,51 @@
1
+ const sdk = await import("@logbrew/sdk").catch(async (error) => {
2
+ if (error && error.code === "ERR_MODULE_NOT_FOUND") {
3
+ return import("../index.js");
4
+ }
5
+ throw error;
6
+ });
7
+
8
+ const { LogBrewClient, RecordingTransport } = sdk;
9
+
10
+ const client = LogBrewClient.create({
11
+ apiKey: "LOGBREW_API_KEY",
12
+ sdkName: "logbrew-js",
13
+ sdkVersion: "0.1.0"
14
+ });
15
+
16
+ client.release("evt_release_001", "2026-06-02T10:00:00Z", {
17
+ version: "1.2.3",
18
+ commit: "abc123def456",
19
+ notes: "Public release marker"
20
+ });
21
+ client.environment("evt_environment_001", "2026-06-02T10:00:01Z", {
22
+ name: "production",
23
+ region: "global"
24
+ });
25
+ client.issue("evt_issue_001", "2026-06-02T10:00:02Z", {
26
+ title: "Checkout timeout",
27
+ level: "error",
28
+ message: "Request timed out after retry budget"
29
+ });
30
+ client.log("evt_log_001", "2026-06-02T10:00:03Z", {
31
+ message: "worker started",
32
+ level: "info",
33
+ logger: "job-runner"
34
+ });
35
+ client.span("evt_span_001", "2026-06-02T10:00:04Z", {
36
+ name: "GET /health",
37
+ traceId: "trace_001",
38
+ spanId: "span_001",
39
+ status: "ok",
40
+ durationMs: 12.5
41
+ });
42
+ client.action("evt_action_001", "2026-06-02T10:00:05Z", {
43
+ name: "deploy",
44
+ status: "success"
45
+ });
46
+
47
+ console.log(client.previewJson());
48
+
49
+ const transport = RecordingTransport.alwaysAccept();
50
+ const response = await client.shutdown(transport);
51
+ console.error(JSON.stringify({ ok: true, status: response.statusCode, attempts: response.attempts, events: 6 }));
@@ -0,0 +1,59 @@
1
+ let sdk;
2
+ try {
3
+ sdk = require("@logbrew/sdk");
4
+ } catch (error) {
5
+ if (error && error.code === "MODULE_NOT_FOUND") {
6
+ sdk = require("../index.cjs");
7
+ } else {
8
+ throw error;
9
+ }
10
+ }
11
+
12
+ const { LogBrewClient, RecordingTransport } = sdk;
13
+
14
+ const client = LogBrewClient.create({
15
+ apiKey: "LOGBREW_API_KEY",
16
+ sdkName: "smoke-app-cjs",
17
+ sdkVersion: "0.1.0"
18
+ });
19
+
20
+ client.release("evt_release_001", "2026-06-02T10:00:00Z", {
21
+ version: "1.2.3",
22
+ commit: "abc123def456",
23
+ notes: "Public release marker"
24
+ });
25
+ client.environment("evt_environment_001", "2026-06-02T10:00:01Z", {
26
+ name: "production",
27
+ region: "global"
28
+ });
29
+ client.issue("evt_issue_001", "2026-06-02T10:00:02Z", {
30
+ title: "Checkout timeout",
31
+ level: "error",
32
+ message: "Request timed out after retry budget"
33
+ });
34
+ client.log("evt_log_001", "2026-06-02T10:00:03Z", {
35
+ message: "worker started",
36
+ level: "info",
37
+ logger: "job-runner"
38
+ });
39
+ client.span("evt_span_001", "2026-06-02T10:00:04Z", {
40
+ name: "GET /health",
41
+ traceId: "trace_001",
42
+ spanId: "span_001",
43
+ status: "ok",
44
+ durationMs: 12.5
45
+ });
46
+ client.action("evt_action_001", "2026-06-02T10:00:05Z", {
47
+ name: "deploy",
48
+ status: "success"
49
+ });
50
+
51
+ console.log(client.previewJson());
52
+
53
+ const transport = RecordingTransport.alwaysAccept();
54
+ client.shutdown(transport).then((response) => {
55
+ console.error(JSON.stringify({ ok: true, status: response.statusCode, attempts: response.attempts, events: 6 }));
56
+ }).catch((error) => {
57
+ console.error(error);
58
+ process.exit(1);
59
+ });
@@ -0,0 +1,51 @@
1
+ const sdk = await import("@logbrew/sdk").catch(async (error) => {
2
+ if (error && error.code === "ERR_MODULE_NOT_FOUND") {
3
+ return import("../index.js");
4
+ }
5
+ throw error;
6
+ });
7
+
8
+ const { LogBrewClient, RecordingTransport } = sdk;
9
+
10
+ const client = LogBrewClient.create({
11
+ apiKey: "LOGBREW_API_KEY",
12
+ sdkName: "smoke-app",
13
+ sdkVersion: "0.1.0"
14
+ });
15
+
16
+ client.release("evt_release_001", "2026-06-02T10:00:00Z", {
17
+ version: "1.2.3",
18
+ commit: "abc123def456",
19
+ notes: "Public release marker"
20
+ });
21
+ client.environment("evt_environment_001", "2026-06-02T10:00:01Z", {
22
+ name: "production",
23
+ region: "global"
24
+ });
25
+ client.issue("evt_issue_001", "2026-06-02T10:00:02Z", {
26
+ title: "Checkout timeout",
27
+ level: "error",
28
+ message: "Request timed out after retry budget"
29
+ });
30
+ client.log("evt_log_001", "2026-06-02T10:00:03Z", {
31
+ message: "worker started",
32
+ level: "info",
33
+ logger: "job-runner"
34
+ });
35
+ client.span("evt_span_001", "2026-06-02T10:00:04Z", {
36
+ name: "GET /health",
37
+ traceId: "trace_001",
38
+ spanId: "span_001",
39
+ status: "ok",
40
+ durationMs: 12.5
41
+ });
42
+ client.action("evt_action_001", "2026-06-02T10:00:05Z", {
43
+ name: "deploy",
44
+ status: "success"
45
+ });
46
+
47
+ console.log(client.previewJson());
48
+
49
+ const transport = RecordingTransport.alwaysAccept();
50
+ const response = await client.shutdown(transport);
51
+ console.error(JSON.stringify({ ok: true, status: response.statusCode, attempts: response.attempts, events: 6 }));