kometry
v0.4.1
Published
Cross-framework frontend observability (errors, logs, breadcrumbs) with provider schema
Downloads
65
Maintainers
Readme
@komerce/telemetry
Cross-framework observability (errors, logs, breadcrumbs) with typed providers, explicit init, and tree-shakeable subpaths.
One setup flow: createTelemetry in config → telemetry.initClient() / initServer() in entries → bindClient / bindServer. See docs/FLOW.md. Konsep provider, adapter, dan createTelemetry: docs/KONSEP.md.
Install
npm install @komerce/telemetryInstall optional peers for your stack (react, react-router, vue, @angular/core) and monitoring (@sentry/browser, @sentry/node, …) only when needed.
Quick start
Vue 2:
import { createTelemetry } from "@komerce/telemetry/setup";
import { Console } from "@komerce/telemetry/providers/console";
import { vue2 } from "@komerce/telemetry/adapter/vue2";
import { Sentry } from "@komerce/telemetry/providers/sentry/client";
export const telemetry = createTelemetry({
platform: vue2,
appId: "shop",
runtime: "client",
providers: [Console(), Sentry({ dsn: "…" })],
});React Router:
import { createTelemetry } from "@komerce/telemetry/setup";
import { Console } from "@komerce/telemetry/providers/console";
import { reactRouter } from "@komerce/telemetry/adapter/react-router";
import { Sentry } from "@komerce/telemetry/providers/sentry/client";
import "@komerce/telemetry/providers/sentry/react-router";
// telemetry.client.ts — import only from entry.client
export const telemetry = createTelemetry({
platform: reactRouter,
appId: "shop",
runtime: "client",
providers: [
Console(),
Sentry({ dsn: import.meta.env.VITE_SENTRY_DSN }),
],
});
// telemetry.server.ts — import only from entry.server
// import { Sentry } from "@komerce/telemetry/providers/sentry/server";entry.client.ts:
import { bindClient } from "@komerce/telemetry/client";
import { telemetry } from "./telemetry.config";
const init = await telemetry.initClient();
init.listenUnhandledErrors();
bindClient(init.api);Feature code (all providers on the plan for that runtime):
import { log, captureError } from "@komerce/telemetry/client";Sentry only (same bindClient(init.api) — does not call Console/Http):
import { log, captureError } from "@komerce/telemetry/client/sentry";Server: @komerce/telemetry/server and @komerce/telemetry/server/sentry after bindServer(init.api).
Omit providers → default Console() in the plan. captureGlobalErrors defaults to false — call listenUnhandledErrors() explicitly.
See docs/FLOW.md for the full bootstrap diagram. Reference apps: examples/react-router-ssr.
Contributing a new backend: docs/ADDING_A_PROVIDER.md.
Optional providers (import only what you use):
import { Http } from "@komerce/telemetry/providers/http";
import { Callback } from "@komerce/telemetry/providers/callback";
import { Sentry } from "@komerce/telemetry/providers/sentry/client";
// Server: import from "@komerce/telemetry/providers/sentry/server"Subpaths
| Import | Use |
| ------ | --- |
| @komerce/telemetry/setup | createTelemetry + types (framework-agnostic) |
| @komerce/telemetry/providers/console | Console provider |
| @komerce/telemetry/adapter/vue2 | vue2 platform + Vue 2 installers |
| @komerce/telemetry/adapter/vue3 | vue3 platform + Vue 3 installers |
| @komerce/telemetry/adapter/react-router | reactRouter platform + RR UI helpers |
| @komerce/telemetry/client | bindClient, log, captureError, … → all providers |
| @komerce/telemetry/client/sentry | Same bind — log, captureError, … → Sentry only |
| @komerce/telemetry/server | bindServer, server runtime facade → all providers |
| @komerce/telemetry/server/sentry | Same bind — Sentry provider only |
| @komerce/telemetry/providers/sentry/client | Sentry plugin (browser graph only) |
| @komerce/telemetry/providers/sentry/server | Sentry plugin (Node graph only) |
| @komerce/telemetry/providers/sentry/react-router | RR Sentry hydration / server instrumentations |
| @komerce/telemetry/react-router/adapter | RouteErrorReporter, SSR helpers (alias of adapter/react-router) |
Root @komerce/telemetry re-exports core setup for convenience; prefer subpaths in app bundles.
React Router + Sentry
Import @komerce/telemetry/providers/sentry/react-router in config (registers RR Sentry loaders + init extensions). Entry stays minimal — downstream modules read init.extensions when needed:
// hydration.client.tsx — not entry.client.ts
import { init } from "./entry.client";
init.extensions.sentry?.reactRouter?.hydrationProps;
await init.extensions.sentry?.reactRouter?.initLibrarySentry?.();Direct helpers (bypassing init.extensions):
import { getReactRouterSentryHydrationProps } from "@komerce/telemetry/providers/sentry/react-router";Adapters (explicit client)
import { RouteErrorReporter } from "@komerce/telemetry/react-router/adapter";
<RouteErrorReporter client={init.api} />Vue / Angular installers require client: TelemetryClient — no global fallback.
Providers
- Console / Http / Callback — core plugins, schema in
schema/provider-core.ts - Sentry — plugin in
providers/sentry/, schema inproviders/sentry/schema.ts, optional@sentry/*peers - Injected SDK:
Sentry({ inject: { client: SentryBrowser, server: SentryNode } })registers on the plan'sSentryClientRegistry(no globalSymbol.for) - Split DSN/settings:
Sentry({ client: { dsn: "…" }, server: { dsn: "…" }, features: { … } })expands to two providers on the plan
Vue 2 / Webpack 4
Webpack 4 does not read package.json exports. After npm run build, the package emits filesystem shims (e.g. client.js, adapter/vue2.js) that re-export built files under dist/ so subpath imports resolve without aliases.
If you still hit ESM parse errors in node_modules, add to vue.config.js:
module.exports = {
transpileDependencies: ["@komerce/telemetry"],
};For stubborn setups, alias subpaths to the matching dist/**/*.cjs file (see package.json exports require targets).
Scripts
npm run build # tsup + auto-generate webpack 4 shims
npm run typecheck
npm test
npm run test:bundle # shim coverage + client facade + per-entry static graph smokeLicense
MIT
