@glassanalytics/browser 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.
@@ -0,0 +1,163 @@
1
+ import { Value, FlagDefinition } from '@glassanalytics/core';
2
+
3
+ type FlagValue = string | boolean | undefined;
4
+ /** Options for flag reads (`SDK.md` §8). */
5
+ interface FlagOptions {
6
+ /** Suppress the `$exposure` event for this read (e.g. internal checks). */
7
+ trackExposure?: boolean;
8
+ /** Value to return when the flag is unknown. */
9
+ fallback?: FlagValue;
10
+ }
11
+ /** `glass.init()` config (`SDK.md` §2). */
12
+ interface GlassConfig {
13
+ /** Required. Publishable client key, scoped to one project (write-only). */
14
+ projectKey: string;
15
+ /** Where batches POST. */
16
+ ingestHost?: string;
17
+ /** Control-plane host for flag bootstrap / SDK config. */
18
+ apiHost?: string;
19
+ replay?: boolean;
20
+ autocapture?: boolean;
21
+ errors?: boolean;
22
+ /** Opt-in: capture `console.error`/`console.warn` as breadcrumbs/errors (§5). Default off. */
23
+ captureConsole?: boolean;
24
+ /** Fraction of sessions recorded (client-side). */
25
+ sampleRate?: number;
26
+ consent?: 'implied' | 'opt-in' | 'opt-out';
27
+ maskAllInputs?: boolean;
28
+ maskTextSelector?: string;
29
+ blockSelector?: string;
30
+ respectDoNotTrack?: boolean;
31
+ flushIntervalMs?: number;
32
+ flushAt?: number;
33
+ /** Last chance to mutate/drop before transmit (§9). */
34
+ beforeSend?: (event: GlassEvent) => GlassEvent | null;
35
+ /** Server-rendered resolved flag values for this user (no flicker, §8). */
36
+ bootstrapFlags?: Record<string, FlagValue>;
37
+ /**
38
+ * Optional flag DEFINITIONS for local (offline / property-aware) bucketing via
39
+ * `@glassanalytics/core` evaluateFlag. The hosted server intentionally does NOT leak the
40
+ * rule set, so this is for self-host / advanced setups that ship definitions.
41
+ */
42
+ flagDefinitions?: FlagDefinition[];
43
+ }
44
+ interface GlassEvent {
45
+ type: 'track' | 'identify' | 'group' | 'error' | 'exposure';
46
+ event?: string;
47
+ seq: number;
48
+ t_client: string;
49
+ props?: Record<string, Value>;
50
+ }
51
+
52
+ /**
53
+ * The Glass browser client (`SDK.md` §3). One small object: identity, events,
54
+ * errors, replay and flags. Non-blocking by construction; nothing here should
55
+ * ever be on the app's critical path.
56
+ */
57
+ declare class Glass {
58
+ private cfg;
59
+ private transport;
60
+ private replay;
61
+ private deviceId;
62
+ private sessionId;
63
+ private userId;
64
+ private traits;
65
+ private groupCtx;
66
+ private superProps;
67
+ private seq;
68
+ private lastActivity;
69
+ private flags;
70
+ private flagsLoaded;
71
+ private flagListeners;
72
+ private optedOut;
73
+ private started;
74
+ /** Calls made before init() are queued and replayed once started (`SDK.md` §2). */
75
+ private preInitQueue;
76
+ /** Removers for every listener/patch we install, so shutdown() leaves no trace. */
77
+ private teardowns;
78
+ init(config: GlassConfig): void;
79
+ private afterConsent;
80
+ /** Register a DOM listener and remember how to remove it on shutdown(). */
81
+ private addListener;
82
+ /**
83
+ * Flush on tab hide (`SDK.md` §10). `visibilitychange`→hidden is the most
84
+ * reliable "user is leaving" signal on mobile (where `pagehide`/`unload` are
85
+ * unreliable), so we drain the buffer with a beacon while we still can.
86
+ */
87
+ private installVisibilityFlush;
88
+ private loadDeviceId;
89
+ private loadSession;
90
+ private persistSession;
91
+ private touchSession;
92
+ /** Queue a call made before init() so nothing is lost; returns true if deferred. */
93
+ private deferred;
94
+ identify(userId: string, traits?: Record<string, Value>): void;
95
+ reset(): void;
96
+ getDeviceId(): string;
97
+ getSessionId(): string;
98
+ getSessionReplayUrl(): string;
99
+ groupIdentify(type: string, key: string, traits?: Record<string, Value>): void;
100
+ /** Alias for `groupIdentify` (`SDK.md` API parity). */
101
+ group(type: string, key: string, traits?: Record<string, Value>): void;
102
+ register(props: Record<string, Value>): void;
103
+ unregister(key: string): void;
104
+ track(event: string, props?: Record<string, Value>): void;
105
+ private emit;
106
+ /** Device/screen context attached to EVERY event (`SDK.md` §4). */
107
+ private contextProps;
108
+ private pageProps;
109
+ captureException(error: unknown, context?: Record<string, Value>): void;
110
+ /** Breadcrumb with optional category (`SDK.md` API parity). */
111
+ addBreadcrumb(arg: string | {
112
+ category?: string;
113
+ message: string;
114
+ data?: Record<string, Value>;
115
+ }, data?: Record<string, Value>): void;
116
+ private installErrorHandlers;
117
+ /**
118
+ * Opt-in console capture (`SDK.md` §5): mirror `console.error`/`console.warn`
119
+ * into Glass (errors as exceptions, warnings as breadcrumbs) while ALWAYS
120
+ * calling through to the original console, so we never swallow the developer's
121
+ * own logs. Restored verbatim on shutdown().
122
+ */
123
+ private installConsoleCapture;
124
+ private rageWindow;
125
+ private installAutocapture;
126
+ /** Stable, value-free descriptor of a clicked element. */
127
+ private elementProps;
128
+ /** Three+ clicks within 1s at roughly one spot = a rage click (frustration signal). */
129
+ private detectRageClick;
130
+ /** SPA route changes: patch History + listen to popstate, de-duping same-URL. */
131
+ private lastPath;
132
+ private installSpaPageviews;
133
+ startSessionRecording(): void;
134
+ stopSessionRecording(): void;
135
+ reloadFeatureFlags(): Promise<void>;
136
+ onFlagsLoaded(fn: (flags: Record<string, FlagValue>) => void): void;
137
+ /**
138
+ * Resolve a flag value with precedence: locally-evaluated definition (if the
139
+ * app shipped one, so targeting reflects CURRENT properties) → server/bootstrap
140
+ * resolved value → fallback.
141
+ */
142
+ private resolve;
143
+ /** Local bucketing via @glassanalytics/core when definitions were provided to init(). */
144
+ private evaluateLocal;
145
+ isFeatureEnabledSync(key: string, opts?: FlagOptions): boolean;
146
+ isFeatureEnabled(key: string, opts?: FlagOptions): Promise<boolean>;
147
+ getFeatureFlagSync(key: string, opts?: FlagOptions): FlagValue;
148
+ getFeatureFlag(key: string, opts?: FlagOptions): Promise<FlagValue>;
149
+ getVariantSync(key: string, opts?: FlagOptions): FlagValue;
150
+ getVariant(key: string, opts?: FlagOptions): Promise<FlagValue>;
151
+ /** Fire a `$exposure` once per (flag, value) so experiment analysis is honest (§8). */
152
+ private exposedKeys;
153
+ private exposure;
154
+ optIn(): void;
155
+ optOut(): void;
156
+ hasConsent(): boolean;
157
+ flush(): Promise<void>;
158
+ shutdown(): void;
159
+ }
160
+ /** Default singleton, mirroring the ergonomic `glass.init(...)` usage in `SDK.md`. */
161
+ declare const glass: Glass;
162
+
163
+ export { type FlagOptions, type FlagValue, Glass, type GlassConfig, type GlassEvent, glass as default, glass };