@safaricom-mxl/effect-sdk 0.0.22 → 0.0.24

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
@@ -13,12 +13,12 @@ pnpm add @safaricom-mxl/effect-sdk effect @effect/opentelemetry
13
13
  Use `@safaricom-mxl/effect-sdk/server` (or the package root in Node / SSR, which resolves to the server build):
14
14
 
15
15
  ```typescript
16
- import { Mxl } from "@safaricom-mxl/effect-sdk/server";
17
- import { Effect } from "effect";
16
+ import { Mxl } from '@safaricom-mxl/effect-sdk/server';
17
+ import { Effect } from 'effect';
18
18
 
19
- const ObservabilityLive = Mxl.layer({ serviceName: "mxl-basket" });
19
+ const ObservabilityLive = Mxl.layer({ serviceName: 'mxl-basket' });
20
20
 
21
- const program = Effect.log("Hello!").pipe(Effect.withSpan("hello"));
21
+ const program = Effect.log('Hello!').pipe(Effect.withSpan('hello'));
22
22
 
23
23
  Effect.runPromise(program.pipe(Effect.provide(ObservabilityLive)));
24
24
  ```
@@ -28,35 +28,56 @@ Effect.runPromise(program.pipe(Effect.provide(ObservabilityLive)));
28
28
  Server `MxlEvents.track` buffers product events and flushes NDJSON to Basket `POST /events` (or `POST /v1/events` when `eventsPath` is set). Send `mxl-client-id`. Send `mxl-api-key` when configured.
29
29
 
30
30
  ```typescript
31
- import { MxlEvents, MxlFlush } from "@safaricom-mxl/effect-sdk/server";
31
+ import { MxlEvents, MxlFlush } from '@safaricom-mxl/effect-sdk/server';
32
32
 
33
33
  const telemetry = MxlFlush.make({
34
34
  clientId: process.env.MXL_CLIENT_ID,
35
35
  ingestUrl: process.env.MXL_BASKET_URL,
36
- serviceName: "billing",
36
+ serviceName: 'billing',
37
37
  });
38
38
 
39
- telemetry.track("plan_started", { userId: "user_1" });
39
+ telemetry.track('plan_started', { userId: 'user_1' });
40
40
  await telemetry.flush();
41
41
  ```
42
42
 
43
43
  Browser `track` dual-writes a product line to `/events` and a session row to `/sessionEvents` with `type: "custom"`. `identify` / increment / decrement go through `POST /track`. `@safaricom-mxl/effect-sdk/client` is an alias of `./browser`.
44
44
 
45
45
  ```typescript
46
- import { identify, MxlFlush, track } from "@safaricom-mxl/effect-sdk/browser";
46
+ import { identify, MxlFlush, track } from '@safaricom-mxl/effect-sdk/browser';
47
47
 
48
48
  const telemetry = MxlFlush.make({
49
- clientId: "client_1",
50
- ingestUrl: "https://basket.example",
51
- serviceName: "web",
49
+ clientId: 'client_1',
50
+ ingestUrl: 'https://basket.example',
51
+ serviceName: 'web',
52
52
  });
53
53
 
54
- identify({ id: "user_1", email: "a@b.com" });
55
- track("checkout_completed", { plan: "pro" });
54
+ identify({ id: 'user_1', email: 'a@b.com' });
55
+ track('checkout_completed', { plan: 'pro' });
56
56
  ```
57
57
 
58
58
  Cloudflare workers use `./cloudflare`. `make()` is module-scope; `flush(env)` resolves `MXL_CLIENT_ID` / `MXL_API_KEY` lazily and is safe inside `waitUntil`. Replay posts `/sessionReplays/meta` and `/sessionReplays/blob`, and stands down when `@safaricom-mxl/web-sdk` already owns the page.
59
59
 
60
+ ## Foldkit
61
+
62
+ `@safaricom-mxl/effect-sdk/foldkit` instruments a Foldkit app: Command spans parented under a navigation, scrubbed command args, crash reports, and slow `update`/`view`/`patch` phases. It sits on the browser flushable tracer.
63
+
64
+ ```typescript
65
+ import { MxlFoldkit } from '@safaricom-mxl/effect-sdk/foldkit';
66
+
67
+ const telemetry = MxlFoldkit.make({
68
+ endpoint: 'http://127.0.0.1:4318',
69
+ serviceName: 'acme-web',
70
+ });
71
+
72
+ Runtime.run(
73
+ Runtime.makeApplication(
74
+ telemetry.instrument({ Model, init, update, view, resources, routing }),
75
+ ),
76
+ );
77
+ ```
78
+
79
+ `MapleFoldkit` is a type and namespace alias of `MxlFoldkit`.
80
+
60
81
  Do not import `@safaricom-mxl/effect-sdk/server` from browser code. The package root (`"."`) resolves to the server build under Node/default conditions.
61
82
 
62
83
  ### Environment variables
@@ -1,90 +1,7 @@
1
- import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
2
- import { Effect, Layer } from "effect";
3
- //#region src/shared/product-event.d.ts
4
- interface TrackProps {
5
- readonly [key: string]: unknown;
6
- }
7
- //#endregion
8
- //#region src/shared/identity.d.ts
9
- interface MapleIdentity {
10
- readonly email?: string | undefined;
11
- readonly groupId?: string | undefined;
12
- readonly groupName?: string | undefined;
13
- readonly id: string;
14
- readonly traits?: Record<string, unknown> | undefined;
15
- }
16
- type IdentifyInput = string | MapleIdentity | null | undefined;
17
- //#endregion
18
- //#region src/browser/analytics.d.ts
19
- interface PrivacyOptions {
20
- readonly requireConsent?: boolean | undefined;
21
- }
22
- export declare const setConsent: (granted: boolean) => void;
23
- export declare const identify: (input?: IdentifyInput) => void;
24
- export declare const clearIdentity: () => void;
25
- export declare const track: (name: string, props?: TrackProps) => void;
26
- export declare const increment: (property: string, value?: number) => void;
27
- export declare const decrement: (property: string, value?: number) => void;
28
- //#endregion
29
- //#region src/browser/replay.d.ts
30
- interface ClientReplayConfig {
31
- readonly enabled?: boolean | undefined;
32
- readonly maskAllInputs?: boolean | undefined;
33
- readonly maskAllText?: boolean | undefined;
34
- readonly sampleRate?: number | undefined;
35
- }
36
- declare namespace layer_d_exports {
37
- export { MxlBrowserConfig, clearIdentity$1 as clearIdentity, identify$1 as identify, layer, stampUserIdOnSpan, track$1 as track };
38
- }
39
- interface MxlBrowserConfig {
40
- readonly apiKey?: string | undefined;
41
- readonly attributes?: Record<string, string> | undefined;
42
- readonly clientId?: string | undefined;
43
- readonly disabled?: boolean | undefined;
44
- readonly endpoint?: string | undefined;
45
- readonly environment?: string | undefined;
46
- readonly headers?: Record<string, string> | undefined;
47
- readonly ingestUrl?: string | undefined;
48
- readonly privacy?: PrivacyOptions | undefined;
49
- readonly replay?: ClientReplayConfig | undefined;
50
- readonly serviceName?: string | undefined;
51
- readonly serviceVersion?: string | undefined;
52
- }
53
- declare const stampUserIdOnSpan: (span: {
54
- setAttribute: (key: string, value: string) => unknown;
55
- }) => void;
56
- /**
57
- * Browser Effect observability layer backed by OpenTelemetry WebSdk.
58
- *
59
- * Returns a no-op layer when `disabled` is true or no OTLP endpoint is configured.
60
- */
61
- declare const layer: (config?: MxlBrowserConfig) => Layer.Layer<never, never, never>;
62
- declare const identify$1: (input?: IdentifyInput) => Effect.Effect<void, never, never>;
63
- declare const clearIdentity$1: Effect.Effect<void, never, never>;
64
- declare const track$1: (name: string, props?: TrackProps) => Effect.Effect<void, never, never>;
65
- declare namespace flushable_d_exports {
66
- export { FlushableTelemetry, MxlBrowserFlushableConfig, attachProcessor, make };
67
- }
68
- interface MxlBrowserFlushableConfig extends MxlBrowserConfig {
69
- readonly autoFlushInterval?: number | false | undefined;
70
- readonly captureGlobalErrors?: boolean | undefined;
71
- readonly flushOnUnload?: boolean | undefined;
72
- }
73
- interface FlushableTelemetry {
74
- readonly captureException: (error: unknown, options?: {
75
- readonly attributes?: Record<string, string>;
76
- readonly name?: string;
77
- }) => void;
78
- readonly dispose: () => Promise<void>;
79
- readonly flush: () => Promise<void>;
80
- readonly layer: Layer.Layer<never>;
81
- }
82
- declare const attachProcessor: (telemetry: FlushableTelemetry, processor: BatchSpanProcessor) => void;
83
- declare const make: (config?: MxlBrowserFlushableConfig) => FlushableTelemetry;
84
- //#endregion
85
- //#region src/shared/dependency-spans.d.ts
86
- type DbSystem = "clickhouse" | "postgresql" | "redis";
87
- type DependencySpanKind = "client" | "producer" | "consumer";
1
+ import { _ as IdentifyInput, a as layer_d_exports, b as MapleSpanOptions, c as replayRecordOptions, d as decrement, f as identify, g as TrackProps, h as track, i as MxlBrowserConfig, l as PrivacyOptions, m as setConsent, n as MxlBrowserFlushableConfig, o as ClientReplayConfig, p as increment, r as flushable_d_exports, s as ReplayRecordOptions, t as FlushableTelemetry, u as clearIdentity, v as MapleIdentity, x as MxlSpanOptions, y as FinishedSpan } from "../flushable-SCVrRJX3.js";
2
+ import { Effect } from "effect";
3
+ type DbSystem = 'clickhouse' | 'postgresql' | 'redis';
4
+ type DependencySpanKind = 'client' | 'producer' | 'consumer';
88
5
  interface QueueTraceContextCarrier {
89
6
  readonly traceparent?: string | undefined;
90
7
  readonly tracestate?: string | undefined;
@@ -105,6 +22,50 @@ export declare function withDependencySpan<A, E, R>(name: string, attributes: Re
105
22
  export declare function withDependencySpan<A, E, R>(name: string, options: WithDependencySpanOptions, program: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>;
106
23
  /** Promise-based dependency span for non-Effect code paths. */
107
24
  export declare function withPromiseDependencySpan<T>(name: string, attributes: Record<string, string>, operation: () => Promise<T>, kind?: DependencySpanKind): Promise<T>;
108
- //#endregion
109
- export { type ClientReplayConfig, type DbSystem, type DependencySpanKind, type FlushableTelemetry, type IdentifyInput, type MapleIdentity, layer_d_exports as Mxl, type MxlBrowserConfig, type MxlBrowserFlushableConfig, flushable_d_exports as MxlFlush, type PrivacyOptions, type QueueTraceContextCarrier, type TrackProps, type WithDependencySpanOptions };
25
+ /**
26
+ * URL redaction for everything that leaves the page carrying a URL: session
27
+ * entry/exit URLs, event rows, network events, rrweb meta events and span
28
+ * attributes.
29
+ *
30
+ * Magic links, password resets and OAuth implicit flows put credentials in the
31
+ * query string or fragment, and a page view is captured on exactly those
32
+ * pages. Values of credential-shaped parameters are therefore replaced by
33
+ * default; the host app can add its own `sanitizeUrl` on top.
34
+ */
35
+ type UrlSanitizer = (url: string) => string;
36
+ /**
37
+ * Register a host-app sanitizer. Additive, like the consent gates: an SDK
38
+ * initialized without one must not remove the one another SDK was given.
39
+ */
40
+ export declare function addUrlSanitizer(sanitizer: UrlSanitizer): void;
41
+ /** Test seam. */
42
+ export declare function resetUrlSanitizersForTests(): void;
43
+ /** Redact credential-shaped query and fragment parameters, keeping the URL's form. */
44
+ export declare function redactUrl(url: string): string;
45
+ /**
46
+ * The URL as it may leave the page: default redaction, then every registered
47
+ * host sanitizer. A sanitizer that throws or returns a non-string yields the
48
+ * default-redacted URL rather than the raw one.
49
+ */
50
+ export declare function scrubUrl(url: string): string;
51
+ interface BrowserNavigator {
52
+ readonly userAgent?: string;
53
+ readonly language?: string;
54
+ readonly onLine?: boolean;
55
+ }
56
+ interface BrowserDocument {
57
+ readonly visibilityState?: string;
58
+ }
59
+ export declare const browserNavigator: () => BrowserNavigator | undefined;
60
+ export declare const browserDocument: () => BrowserDocument | undefined;
61
+ /** Resource attributes every browser preset sends: the SDK, the user agent, language and time zone. */
62
+ export declare const browserResourceAttributes: () => {
63
+ 'telemetry.sdk.name': string;
64
+ 'telemetry.sdk.language': string;
65
+ 'telemetry.sdk.version': string;
66
+ 'user_agent.original'?: string | undefined;
67
+ 'browser.language'?: string | undefined;
68
+ 'mxl.browser.timezone'?: string | undefined;
69
+ };
70
+ export { type ClientReplayConfig, type DbSystem, type DependencySpanKind, type FinishedSpan, type FlushableTelemetry, type IdentifyInput, type MapleIdentity, type MapleSpanOptions, layer_d_exports as Mxl, type MxlBrowserConfig, type MxlBrowserFlushableConfig, flushable_d_exports as MxlFlush, type MxlSpanOptions, type PrivacyOptions, type QueueTraceContextCarrier, type ReplayRecordOptions, type TrackProps, type UrlSanitizer, type WithDependencySpanOptions, clearIdentity, decrement, identify, increment, replayRecordOptions, setConsent, track };
110
71
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/product-event.ts","../../src/shared/identity.ts","../../src/browser/analytics.ts","../../src/browser/replay.ts","../../src/browser/layer.ts","../../src/browser/flushable.ts","../../src/shared/dependency-spans.ts"],"mappings":";;;UAoBiB;YACL;;;;UCrBK;WACN;WACA;WACA;WACA;WACA,SAAS;;KAGR,yBAAyB;;;UCMpB;WACN;;qBA4HE,aAAU;qBAOV,WAAQ,QAAY;qBA+BpB;qBAiDA,QAAK,cAAgB,QAAU;qBAiC/B,YAAS,kBAAoB;qBAI7B,YAAS,kBAAoB;;;UCpQzB;WACN;WACA;WACA;WACA;;;;;UCgBM;WACN;WACA,aAAa;WACb;WACA;WACA;WACA;WACA,UAAU;WACV;WACA,UAAU;WACV,SAAS;WACT;WACA;;cAGE,oBAAiB;EAC5B,eAAe,aAAa;;;;;;;cA+CjB,QAAK,SAAY,qBAAgB,MAAA;cAmDjC,aAAQ,QAAY,kBAAa,OAAA;cAGjC,iBAAa,OAAA;cAEb,UAAK,cAAgB,QAAU,eAAU,OAAA;;;;UCrIrC,kCAAkC;WACxC;WACA;WACA;;UAGM;WACN,mBACP,gBACA;aAAqB,aAAa;aAAiC;;WAE5D,eAAe;WACf,aAAa;WACb,OAAO,MAAM;;cAMX,kBAAe,WACf,oBAAkB,WAClB;cAKA,OAAI,SACP,8BACP;;;KC5BS;KAEA;UAIK;WACN;WACA;WACA;;wBAGK,uBACd,UAAU,UACV,qBACC;wBASa,4BACd,yBACA,uBACC;wBAQa,4BACd,0BACC;wBAOa,4BACd,eACA,uBACC;wBAQa,qBACd,oBACA,oBACC;wBAUa,qBAAqB;wBASrB,8BACd,mBAAmB;UAiCJ;WACN,aAAa;WACb,OAAO;;wBAGF,mBAAmB,GAAG,GAAG,GACvC,cACA,YAAY,wBACZ,SAAS,OAAO,OAAO,GAAG,GAAG,KAC5B,OAAO,OAAO,GAAG,GAAG;wBACP,mBAAmB,GAAG,GAAG,GACvC,cACA,SAAS,2BACT,SAAS,OAAO,OAAO,GAAG,GAAG,KAC5B,OAAO,OAAO,GAAG,GAAG;;wBA2BD,0BAA0B,GAC9C,cACA,YAAY,wBACZ,iBAAiB,QAAQ,IACzB,OAAM,qBACL,QAAQ"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/dependency-spans.ts","../../src/shared/url-privacy.ts","../../src/browser/browser-globals.ts"],"mappings":";;KASY;KAEA;UAIK;WACN;WACA;WACA;;wBAGK,uBACd,UAAU,UACV,qBACC;wBASa,4BACd,yBACA,uBACC;wBAQa,4BACd,0BACC;wBAOa,4BACd,eACA,uBACC;wBAQa,qBACd,oBACA,oBACC;wBAUa,qBAAqB;wBASrB,8BACd,mBAAmB;UAiCJ;WACN,aAAa;WACb,OAAO;;wBAGF,mBAAmB,GAAG,GAAG,GACvC,cACA,YAAY,wBACZ,SAAS,OAAO,OAAO,GAAG,GAAG,KAC5B,OAAO,OAAO,GAAG,GAAG;wBACP,mBAAmB,GAAG,GAAG,GACvC,cACA,SAAS,2BACT,SAAS,OAAO,OAAO,GAAG,GAAG,KAC5B,OAAO,OAAO,GAAG,GAAG;;wBA2BD,0BAA0B,GAC9C,cACA,YAAY,wBACZ,iBAAiB,QAAQ,IACzB,OAAM,qBACL,QAAQ;;;;;;;;;;;KC3JC,gBAAgB;;;;;wBAuBZ,gBAAgB,WAAW;;wBAK3B;;wBAqCA,UAAU;;;;;;wBA6BV,SAAS;UClGf;WACC;WACA;WACA;;UAGD;WACC;;qBAGE,wBAAuB;qBAGvB,uBAAsB;;qBAItB"}