@heystack/otel 0.3.2 → 0.3.4

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 CHANGED
@@ -157,6 +157,8 @@ As belt-and-suspenders the exporter also drops any span whose HTTP target points
157
157
 
158
158
  ## Migration / versioning
159
159
 
160
+ - **`0.3.4`** — **type-inference fix (Workers).** Restores `instrument()`'s ability to infer the handler's concrete `Env` type. In 0.3.3 the signature was `instrument<E = unknown, H extends WorkerHandler<E>>`, so `E` defaulted to `unknown` and was never recovered from the handler — under `strictFunctionTypes` a Worker typed `fetch(req, env: Env, ctx)` then failed to compile (`TS2345: 'Env' is not assignable to 'unknown'`) unless the caller passed `instrument<Env>(...)` explicitly. 0.3.4 infers `E` from the handler argument (`instrument<H extends WorkerHandler<any>>(...): Instrumented<EnvOf<H>, H>`), so a bare `instrument(handler, cfg)` type-checks again. Runtime behaviour is unchanged; no `0.3.3` consumer needs the explicit type arg after upgrading.
161
+ - **`0.3.3`** — `/next` uses bare, exports-mapped dynamic imports so the OpenNext (Cloudflare Pages) build resolves the workers entry correctly (fixes a build break). Workers/Node paths unchanged.
160
162
  - **`0.3.2`** — runtime-correctness fixes:
161
163
  - **ContextManager registered (CRITICAL).** 0.3.1's `suppressTracing` was a no-op because no ContextManager was registered, so the exporter's ingest POST could still be re-traced into a feedback loop. 0.3.2 registers an `AsyncLocalStorageContextManager` (Node + workerd under `nodejs_compat`; sync stack-manager fallback otherwise) so suppression works — and as a bonus you get cross-`await` span parenting + per-request context isolation. **Workers now require `nodejs_compat`.** New dependency: `@opentelemetry/context-async-hooks`.
162
164
  - **Hostname-accurate self-span filter** (no sibling-domain false positives; `host:port` now matched; more host-only attrs covered).
package/dist/next.js CHANGED
@@ -44,13 +44,23 @@ export async function registerHeystack(o) {
44
44
  // path (and a workers build must not bundle the node path) — the import is
45
45
  // runtime-selected per environment. `@vite-ignore` covers Vite/Rollup;
46
46
  // `webpackIgnore` covers Next/Turbopack/webpack.
47
+ //
48
+ // IMPORTANT: use the BARE package subpath ("@heystack/otel/workers"), NOT a
49
+ // relative "./workers.js". With the ignore hints the specifier is left as a
50
+ // literal runtime import; Next relocates this code into a server chunk and
51
+ // OpenNext's esbuild re-bundles it. A relative path would then resolve
52
+ // against the CHUNK dir (where no workers.js exists) and the build fails
53
+ // (issue: 0.3.2 broke OpenNext builds this way). A bare specifier resolves
54
+ // through Node's exports map / node_modules from anywhere, surviving both
55
+ // Next chunk relocation and OpenNext's re-bundle. The exports map points
56
+ // "./workers" → "./dist/workers.js" and "./node" → "./dist/node.js".
47
57
  const { initHeystackWorkers } = await import(
48
- /* @vite-ignore */ /* webpackIgnore: true */ "./workers.js");
58
+ /* @vite-ignore */ /* webpackIgnore: true */ "@heystack/otel/workers");
49
59
  initHeystackWorkers({ apiKey, service: o.service, endpoint: o.endpoint });
50
60
  }
51
61
  else {
52
62
  const { initHeystack } = await import(
53
- /* @vite-ignore */ /* webpackIgnore: true */ "./node.js");
63
+ /* @vite-ignore */ /* webpackIgnore: true */ "@heystack/otel/node");
54
64
  initHeystack({
55
65
  apiKey,
56
66
  service: o.service,
package/dist/workers.d.ts CHANGED
@@ -253,5 +253,20 @@ type Instrumented<E, H> = Omit<H, "fetch" | "queue" | "scheduled"> & (H extends
253
253
  } ? {
254
254
  scheduled: (controller: ScheduledController, env: E, ctx: ExecutionContext) => Promise<void>;
255
255
  } : unknown);
256
- export declare function instrument<E = unknown, H extends WorkerHandler<E> = WorkerHandler<E>>(handler: H, config: WorkersConfig): Instrumented<E, H>;
256
+ /**
257
+ * Recover a handler's concrete env type from whichever traced entrypoint it
258
+ * declares (`fetch`, else `queue`, else `scheduled`). This lets `instrument()`
259
+ * infer the env from the handler argument itself rather than requiring the
260
+ * caller to pass it explicitly — a Worker typed `fetch(req, env: Env, ctx)`
261
+ * type-checks with a bare `instrument(handler, cfg)` call. Falls back to
262
+ * `unknown` for a handler with no recognised entrypoint.
263
+ */
264
+ type EnvOf<H> = H extends {
265
+ fetch: (req: Request, env: infer E, ctx: ExecutionContext) => unknown;
266
+ } ? E : H extends {
267
+ queue: (batch: MessageBatch, env: infer E, ctx: ExecutionContext) => unknown;
268
+ } ? E : H extends {
269
+ scheduled: (controller: ScheduledController, env: infer E, ctx: ExecutionContext) => unknown;
270
+ } ? E : unknown;
271
+ export declare function instrument<H extends WorkerHandler<any>>(handler: H, config: WorkersConfig): Instrumented<EnvOf<H>, H>;
257
272
  export type { Span };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heystack/otel",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Runtime-aware OpenTelemetry tracing that exports to Heystack (Node, Next.js, Workers).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,9 @@
18
18
  "build": "tsc -p tsconfig.build.json",
19
19
  "test": "vitest run",
20
20
  "typecheck": "tsc --noEmit",
21
- "prepublishOnly": "pnpm build"
21
+ "validate": "node scripts/validate-entries.mjs",
22
+ "check": "pnpm typecheck && pnpm build && pnpm validate && pnpm test",
23
+ "prepublishOnly": "pnpm build && pnpm validate"
22
24
  },
23
25
  "dependencies": {
24
26
  "@opentelemetry/api": "^1.9.0",