@allstak/react 0.3.1 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  /**
4
- * Minimal HTTP transport for React Native. Uses the global `fetch` (always
5
- * present in RN >= 0.60) with a 3s timeout. Failed sends fall into a small
6
- * in-memory ring buffer that we retry on the next successful flush.
4
+ * Fail-open HTTP transport for browser/React. Telemetry sends are best-effort:
5
+ * they use a short timeout, never reject into the host app, and fall into a
6
+ * bounded in-memory ring buffer with circuit-breaker backoff when AllStak is
7
+ * unavailable.
7
8
  *
8
9
  * No window, no AbortController fallback shims — RN exposes both natively.
9
10
  */
@@ -12,10 +13,17 @@ declare class HttpTransport {
12
13
  private apiKey;
13
14
  private buffer;
14
15
  private flushing;
16
+ private consecutiveFailures;
17
+ private circuitOpenUntil;
15
18
  constructor(baseUrl: string, apiKey: string);
16
19
  send(path: string, payload: unknown): Promise<void>;
20
+ private enqueueOrDispatch;
21
+ private dispatch;
17
22
  private doFetch;
23
+ private push;
24
+ private scheduleFlush;
18
25
  private flushBuffer;
26
+ private recordFailure;
19
27
  getBufferSize(): number;
20
28
  /**
21
29
  * Wait for the in-flight retry-buffer to drain. Resolves `true` if the
@@ -303,9 +311,44 @@ interface HttpTrackingOptions {
303
311
  maxBodyBytes?: number;
304
312
  }
305
313
 
314
+ /**
315
+ * Idempotent instrumentation of `globalThis.fetch` and `console.warn/error`
316
+ * to feed breadcrumbs into the AllStak client. Safe to call once at init.
317
+ *
318
+ * - `instrumentFetch`: wraps fetch and records a breadcrumb per request
319
+ * (success and failure). Skips requests targeting the SDK's own ingest
320
+ * host so the wrap never recurses. Preserves the original return type
321
+ * and rethrows fetch errors after the breadcrumb is recorded.
322
+ * - `instrumentConsole`: wraps `console.warn` and `console.error` to
323
+ * record `log`-type breadcrumbs at the corresponding level.
324
+ *
325
+ * Both patches use a flag on the wrapper function so a second call is a
326
+ * no-op — important because hot-module-reload in dev would otherwise
327
+ * stack patches and double-fire breadcrumbs.
328
+ */
329
+ type AddBreadcrumbFn$1 = (type: string, msg: string, level?: string, data?: Record<string, unknown>) => void;
330
+ declare function instrumentFetch(addBreadcrumb: AddBreadcrumbFn$1, ownBaseUrl?: string): void;
331
+ /**
332
+ * Per-console-method capture flags. Defaults: warn + error captured,
333
+ * log + info NOT captured (typical React apps emit thousands of debug
334
+ * lines per session — flooding the dashboard with them creates pure
335
+ * noise, so they're opt-in).
336
+ *
337
+ * <AllStakProvider captureConsole={{ log: true, info: true }} />
338
+ */
339
+ interface ConsoleCaptureOptions {
340
+ log?: boolean;
341
+ info?: boolean;
342
+ warn?: boolean;
343
+ error?: boolean;
344
+ }
345
+ declare function instrumentConsole(addBreadcrumb: AddBreadcrumbFn$1, options?: ConsoleCaptureOptions): void;
346
+ /** @internal — for tests. Resets the wrap-once flag. */
347
+ declare function __resetConsoleInstrumentationFlagForTest(): void;
348
+
306
349
  declare const INGEST_HOST = "https://api.allstak.sa";
307
350
  declare const SDK_NAME = "allstak-react";
308
- declare const SDK_VERSION = "0.3.0";
351
+ declare const SDK_VERSION = "0.3.1";
309
352
 
310
353
  interface AllStakConfig {
311
354
  /** Project API key (`ask_live_…`). Required. */
@@ -342,8 +385,22 @@ interface AllStakConfig {
342
385
  autoCaptureBrowserErrors?: boolean;
343
386
  /** Wrap `globalThis.fetch` to record HTTP breadcrumbs. Default: true */
344
387
  autoBreadcrumbsFetch?: boolean;
345
- /** Wrap `console.warn` and `console.error` to record log breadcrumbs. Default: true */
388
+ /** Wrap `console.*` methods to record log breadcrumbs. Default: true.
389
+ * Per-method capture is controlled by `captureConsole` (warn + error
390
+ * default on, log + info default off). */
346
391
  autoBreadcrumbsConsole?: boolean;
392
+ /**
393
+ * Per-console-method capture flags. Defaults: warn + error captured,
394
+ * log + info NOT captured (to avoid breadcrumb spam from typical app
395
+ * logging). Set `{ log: true, info: true }` to opt-in.
396
+ */
397
+ captureConsole?: ConsoleCaptureOptions;
398
+ /**
399
+ * Auto-capture Web Vitals (CLS, LCP, INP, FCP, TTFB) via the browser's
400
+ * PerformanceObserver. Default: true. Each metric ships as a
401
+ * `web_vitals` log on the next backend flush.
402
+ */
403
+ autoWebVitals?: boolean;
347
404
  /** Wrap `history.pushState`/`replaceState` and listen to `popstate` for SPA navigation breadcrumbs. Default: true */
348
405
  autoBreadcrumbsNavigation?: boolean;
349
406
  /**
@@ -440,6 +497,7 @@ declare class AllStakClient {
440
497
  private _instrumentAxios;
441
498
  private onErrorHandler;
442
499
  private onRejectionHandler;
500
+ private webVitals;
443
501
  constructor(config: AllStakConfig);
444
502
  /** Manually instrument an axios instance. No-op when HTTP tracking is off. */
445
503
  instrumentAxios<T = any>(axios: T): T;
@@ -576,6 +634,80 @@ declare const AllStak: {
576
634
  /** @internal */ _getInstance(): AllStakClient | null;
577
635
  };
578
636
 
637
+ interface AllStakProviderProps {
638
+ children: React.ReactNode;
639
+ apiKey: string;
640
+ environment?: string;
641
+ release?: string;
642
+ host?: string;
643
+ user?: {
644
+ id?: string;
645
+ email?: string;
646
+ };
647
+ tags?: Record<string, string>;
648
+ debug?: boolean;
649
+ enableHttpTracking?: boolean;
650
+ httpTracking?: AllStakConfig['httpTracking'];
651
+ /**
652
+ * Per-console-method capture flags. Defaults: warn + error captured,
653
+ * log + info NOT captured (to avoid breadcrumb spam from typical app
654
+ * logging). Set `{ log: true, info: true }` to opt-in.
655
+ */
656
+ captureConsole?: AllStakConfig['captureConsole'];
657
+ sampleRate?: number;
658
+ beforeSend?: AllStakConfig['beforeSend'];
659
+ replay?: AllStakConfig['replay'];
660
+ tracesSampleRate?: number;
661
+ service?: string;
662
+ dist?: string;
663
+ /** Default true. Capture window error + unhandledrejection. */
664
+ autoCaptureBrowserErrors?: boolean;
665
+ /** Default true. Wrap fetch for breadcrumbs. */
666
+ autoBreadcrumbsFetch?: boolean;
667
+ /** Default true. Wrap console for breadcrumbs (per-method via captureConsole). */
668
+ autoBreadcrumbsConsole?: boolean;
669
+ /** Default true. Patch history.pushState/replaceState + popstate listener. */
670
+ autoBreadcrumbsNavigation?: boolean;
671
+ /** Default true. Collect Web Vitals via PerformanceObserver. */
672
+ autoWebVitals?: boolean;
673
+ /**
674
+ * Tear down the SDK when the provider unmounts. Default `false`.
675
+ *
676
+ * Most apps mount `AllStakProvider` once at the root and never unmount
677
+ * it. Setting this to `true` risks disabling telemetry if the provider
678
+ * re-mounts (Fast Refresh in dev, route key changes, React 18 Strict
679
+ * Mode double-mount, etc.) — there is a brief window between unmount
680
+ * and remount where captures throw.
681
+ *
682
+ * Leave at the default unless you genuinely need to dispose the SDK.
683
+ */
684
+ destroyOnUnmount?: boolean;
685
+ fallback?: React.ReactNode | ((props: {
686
+ error: Error;
687
+ resetError: () => void;
688
+ }) => React.ReactNode);
689
+ onError?: (error: Error, componentStack?: string) => void;
690
+ }
691
+ declare function AllStakProvider({ children, apiKey, environment, release, host, user, tags, debug, enableHttpTracking, httpTracking, captureConsole, sampleRate, beforeSend, replay, tracesSampleRate, service, dist, autoCaptureBrowserErrors, autoBreadcrumbsFetch, autoBreadcrumbsConsole, autoBreadcrumbsNavigation, autoWebVitals, destroyOnUnmount, fallback, onError, }: AllStakProviderProps): React.ReactElement;
692
+ /**
693
+ * Convenience hook — exposes the most common capture/context APIs with
694
+ * a stable identity so components don't have to import the namespace.
695
+ */
696
+ declare function useAllStak(): {
697
+ captureException: (error: Error, ctx?: Record<string, unknown>) => void;
698
+ captureMessage: (msg: string, level?: "fatal" | "error" | "warning" | "info") => void;
699
+ setUser: (user: {
700
+ id?: string;
701
+ email?: string;
702
+ }) => void;
703
+ setTag: (key: string, value: string) => void;
704
+ setContext: (name: string, ctx: Record<string, unknown> | null) => void;
705
+ addBreadcrumb: (type: string, message: string, level?: string, data?: Record<string, unknown>) => void;
706
+ flush: (timeoutMs?: number) => Promise<boolean>;
707
+ };
708
+ /** @internal — for tests. Resets the module-level remount-guard. */
709
+ declare function __resetProviderInstanceForTest(): void;
710
+
579
711
  /**
580
712
  * Browser navigation breadcrumbs — minimal fallback that doesn't depend on
581
713
  * any specific router library. Wraps `history.pushState`/`replaceState` and
@@ -588,41 +720,77 @@ declare const AllStak: {
588
720
  * For framework-specific instrumentation (React Router's `useNavigate`,
589
721
  * Next's `router.events`), bind manually with `AllStak.addBreadcrumb`.
590
722
  */
591
- type AddBreadcrumbFn$1 = (type: string, msg: string, level?: string, data?: Record<string, unknown>) => void;
592
- declare function instrumentBrowserNavigation(addBreadcrumb: AddBreadcrumbFn$1): void;
723
+ type AddBreadcrumbFn = (type: string, msg: string, level?: string, data?: Record<string, unknown>) => void;
724
+ declare function instrumentBrowserNavigation(addBreadcrumb: AddBreadcrumbFn): void;
593
725
  declare function instrumentReactRouter(location: {
594
726
  pathname: string;
595
727
  search?: string;
596
- }, addBreadcrumb?: AddBreadcrumbFn$1): void;
597
- declare function instrumentNextRouter(url: string, addBreadcrumb?: AddBreadcrumbFn$1): void;
728
+ }, addBreadcrumb?: AddBreadcrumbFn): void;
729
+ declare function instrumentNextRouter(url: string, addBreadcrumb?: AddBreadcrumbFn): void;
598
730
 
599
731
  /**
600
- * Idempotent instrumentation of `globalThis.fetch` and `console.warn/error`
601
- * to feed breadcrumbs into the AllStak client. Safe to call once at init.
732
+ * Lightweight Web Vitals collection via the browser's PerformanceObserver.
602
733
  *
603
- * - `instrumentFetch`: wraps fetch and records a breadcrumb per request
604
- * (success and failure). Skips requests targeting the SDK's own ingest
605
- * host so the wrap never recurses. Preserves the original return type
606
- * and rethrows fetch errors after the breadcrumb is recorded.
607
- * - `instrumentConsole`: wraps `console.warn` and `console.error` to
608
- * record `log`-type breadcrumbs at the corresponding level.
734
+ * Captures CLS, LCP, INP, FCP, TTFB without pulling in the `web-vitals`
735
+ * package as a runtime dependency. Each metric is shipped as a single
736
+ * `web_vital` log on the SDK's `/ingest/v1/logs` channel so the
737
+ * dashboard can chart them alongside other logs.
609
738
  *
610
- * Both patches use a flag on the wrapper function so a second call is a
611
- * no-op important because hot-module-reload in dev would otherwise
612
- * stack patches and double-fire breadcrumbs.
739
+ * Privacy: only numeric values + the metric name are sent. No URLs,
740
+ * referrers, or user-identifiable data.
741
+ *
742
+ * Browser compatibility: PerformanceObserver is available in every
743
+ * evergreen browser (Chrome 51+, Safari 11+, Firefox 57+, Edge 79+).
744
+ * Older browsers silently no-op via the `typeof PerformanceObserver`
745
+ * guard.
746
+ *
747
+ * - **CLS** (Cumulative Layout Shift) — layout-shift entries with
748
+ * `hadRecentInput=false`, summed for the session
749
+ * - **LCP** (Largest Contentful Paint) — biggest paint entry's startTime
750
+ * - **INP** (Interaction to Next Paint) — longest event-timing duration
751
+ * - **FCP** (First Contentful Paint) — first paint named `first-contentful-paint`
752
+ * - **TTFB** (Time to First Byte) — `responseStart - requestStart` from the
753
+ * navigation timing entry
613
754
  */
614
- type AddBreadcrumbFn = (type: string, msg: string, level?: string, data?: Record<string, unknown>) => void;
615
- declare function instrumentFetch(addBreadcrumb: AddBreadcrumbFn, ownBaseUrl?: string): void;
616
- declare function instrumentConsole(addBreadcrumb: AddBreadcrumbFn): void;
755
+ type VitalsReporter = (metric: {
756
+ name: string;
757
+ value: number;
758
+ id?: string;
759
+ }) => void;
760
+ interface WebVitalsHandle {
761
+ /** Disconnects all observers. Idempotent. */
762
+ destroy(): void;
763
+ }
764
+ /**
765
+ * Start collecting Web Vitals. Returns a handle whose `destroy()` cleans
766
+ * up all PerformanceObservers. Safe no-op on non-browser runtimes.
767
+ */
768
+ declare function startWebVitals(report: VitalsReporter): WebVitalsHandle;
769
+ /** @internal — reset the started flag so tests can re-init. */
770
+ declare function __resetWebVitalsFlagForTest(): void;
617
771
 
618
772
  /**
619
773
  * @allstak/react — standalone React SDK.
620
774
  *
621
775
  * Self-contained: no @allstak/js or @allstak-io/* dependencies. Ships its own
622
776
  * AllStak client (init/capture/breadcrumbs/transport) plus React-specific
623
- * helpers (ErrorBoundary, useAllStak hook, withAllStakProfiler HOC).
777
+ * helpers (Provider, ErrorBoundary, useAllStak hook, withAllStakProfiler HOC).
778
+ *
779
+ * Recommended usage (one-liner):
780
+ *
781
+ * import { AllStakProvider } from '@allstak/react';
782
+ *
783
+ * export function App() {
784
+ * return (
785
+ * <AllStakProvider apiKey="ask_live_..." environment="production" debug>
786
+ * <AppRoot />
787
+ * </AllStakProvider>
788
+ * );
789
+ * }
624
790
  *
625
- * Usage:
791
+ * Advanced / manual usage:
792
+ *
793
+ * import { AllStak } from '@allstak/react';
626
794
  * AllStak.init({ apiKey, environment, release });
627
795
  * <AllStakErrorBoundary>...</AllStakErrorBoundary>
628
796
  * const { captureException } = useAllStak();
@@ -650,23 +818,9 @@ declare class AllStakErrorBoundary extends React.Component<AllStakErrorBoundaryP
650
818
  render(): React.ReactNode;
651
819
  }
652
820
  /**
653
- * Convenience hook exposes the most common capture/context APIs with a
654
- * stable identity so components don't have to import the namespace.
655
- */
656
- declare function useAllStak(): {
657
- captureException: (error: Error, ctx?: Record<string, unknown>) => void;
658
- captureMessage: (msg: string, level?: "fatal" | "error" | "warning" | "info") => void;
659
- setUser: (user: {
660
- id?: string;
661
- email?: string;
662
- }) => void;
663
- setTag: (key: string, value: string) => void;
664
- addBreadcrumb: (type: string, message: string, level?: string, data?: Record<string, unknown>) => void;
665
- };
666
- /**
667
- * HOC: drops a navigation breadcrumb when a component mounts. Useful for
668
- * marking screen boundaries without a router.
821
+ * HOC: drops a navigation breadcrumb when a component mounts. Useful
822
+ * for marking screen boundaries without a router.
669
823
  */
670
824
  declare function withAllStakProfiler<P extends object>(Component: React.ComponentType<P>, name?: string): React.FC<P>;
671
825
 
672
- export { AllStak, AllStakClient, type AllStakConfig, AllStakErrorBoundary, type AllStakErrorBoundaryProps, type Breadcrumb, type HttpRequestEvent, HttpRequestModule, type HttpTrackingOptions, INGEST_HOST, type ReplayOptions, ReplayRecorder, SDK_NAME, SDK_VERSION, Scope, instrumentBrowserNavigation, instrumentConsole, instrumentFetch, instrumentNextRouter, instrumentReactRouter, useAllStak, withAllStakProfiler };
826
+ export { AllStak, AllStakClient, type AllStakConfig, AllStakErrorBoundary, type AllStakErrorBoundaryProps, AllStakProvider, type AllStakProviderProps, type Breadcrumb, type ConsoleCaptureOptions, type HttpRequestEvent, HttpRequestModule, type HttpTrackingOptions, INGEST_HOST, type ReplayOptions, ReplayRecorder, SDK_NAME, SDK_VERSION, Scope, type WebVitalsHandle, __resetConsoleInstrumentationFlagForTest, __resetProviderInstanceForTest, __resetWebVitalsFlagForTest, instrumentBrowserNavigation, instrumentConsole, instrumentFetch, instrumentNextRouter, instrumentReactRouter, startWebVitals, useAllStak, withAllStakProfiler };