@databuddy/sdk 2.3.29 → 2.4.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.
package/README.md CHANGED
@@ -71,14 +71,13 @@ All options are type-safe and documented in `DatabuddyConfig`:
71
71
  | `trackAttributes` | boolean | `false` | Track data-* attributes on elements. |
72
72
  | `trackOutgoingLinks` | boolean | `false` | Track clicks on outgoing links. |
73
73
  | `trackInteractions` | boolean | `false` | Track user interactions. |
74
- | `trackScrollDepth` | boolean | `false` | Track scroll depth. |
75
74
  | `trackPerformance` | boolean | `true` | Track page performance metrics. |
76
75
  | `trackWebVitals` | boolean | `false` | Track Web Vitals metrics. |
77
76
  | `trackErrors` | boolean | `false` | Track JavaScript errors. |
78
77
  | `ignoreBotDetection` | boolean | `false` | Ignore bot detection. |
79
78
  | `usePixel` | boolean | `false` | Use pixel tracking instead of script. |
80
79
  | `samplingRate` | number | `1.0` | Sampling rate (0.0–1.0). |
81
- | `enableRetries` | boolean | `false` | Enable retries for failed requests. |
80
+ | `enableRetries` | boolean | `true` | Enable retries for failed requests. |
82
81
  | `maxRetries` | number | `3` | Max retries. |
83
82
  | `initialRetryDelay` | number | `500` | Initial retry delay (ms). |
84
83
  | `enableBatching` | boolean | `true` | Enable event batching. |
@@ -1,5 +1,5 @@
1
- import { D as DatabuddyConfig } from '../shared/@databuddy/sdk.BsF1xr6_.mjs';
2
- export { B as BaseEventProperties, n as DataAttributes, m as DatabuddyTracker, l as EventName, E as EventProperties, k as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, o as SetGlobalPropertiesFunction, T as TrackFunction, c as clear, f as flush, d as getAnonymousId, e as getSessionId, g as getTracker, h as getTrackingIds, j as getTrackingParams, i as isTrackerAvailable, t as track, a as trackCustomEvent, b as trackError } from '../shared/@databuddy/sdk.BsF1xr6_.mjs';
1
+ import { D as DatabuddyConfig } from '../shared/@databuddy/sdk.DOtKE9NQ.mjs';
2
+ export { B as BaseEventProperties, a as DataAttributes, b as DatabuddyTracker, E as EventName, c as EventProperties, d as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, e as SetGlobalPropertiesFunction, T as TrackFunction, f as clear, g as flush, h as getAnonymousId, i as getSessionId, j as getTracker, k as getTrackingIds, l as getTrackingParams, m as isTrackerAvailable, t as track, n as trackCustomEvent, o as trackError } from '../shared/@databuddy/sdk.DOtKE9NQ.mjs';
3
3
 
4
4
  /**
5
5
  * Auto-detect Databuddy client ID from environment variables
@@ -1,5 +1,5 @@
1
- import { D as DatabuddyConfig } from '../shared/@databuddy/sdk.BsF1xr6_.js';
2
- export { B as BaseEventProperties, n as DataAttributes, m as DatabuddyTracker, l as EventName, E as EventProperties, k as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, o as SetGlobalPropertiesFunction, T as TrackFunction, c as clear, f as flush, d as getAnonymousId, e as getSessionId, g as getTracker, h as getTrackingIds, j as getTrackingParams, i as isTrackerAvailable, t as track, a as trackCustomEvent, b as trackError } from '../shared/@databuddy/sdk.BsF1xr6_.js';
1
+ import { D as DatabuddyConfig } from '../shared/@databuddy/sdk.DOtKE9NQ.js';
2
+ export { B as BaseEventProperties, a as DataAttributes, b as DatabuddyTracker, E as EventName, c as EventProperties, d as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, e as SetGlobalPropertiesFunction, T as TrackFunction, f as clear, g as flush, h as getAnonymousId, i as getSessionId, j as getTracker, k as getTrackingIds, l as getTrackingParams, m as isTrackerAvailable, t as track, n as trackCustomEvent, o as trackError } from '../shared/@databuddy/sdk.DOtKE9NQ.js';
3
3
 
4
4
  /**
5
5
  * Auto-detect Databuddy client ID from environment variables
@@ -1,4 +1,4 @@
1
- export { c as createScript, i as isScriptInjected } from '../shared/@databuddy/sdk.urY7MmVr.mjs';
1
+ export { c as createScript, i as isScriptInjected } from '../shared/@databuddy/sdk.P9GHqNXr.mjs';
2
2
 
3
3
  function detectClientId(providedClientId) {
4
4
  if (providedClientId) {
@@ -1,4 +1,4 @@
1
- import { e as FlagsManager, f as FlagsManagerOptions, U as UserContext, d as FlagResult, b as FlagState, F as FlagsConfig } from '../shared/@databuddy/sdk.CdLp6SQb.mjs';
1
+ import { d as FlagsManager, F as FlagsConfig, S as StorageInterface, e as FlagsManagerOptions, c as FlagResult, U as UserContext, a as FlagState, f as FlagsSnapshot } from '../shared/@databuddy/sdk.rnu91OSC.mjs';
2
2
 
3
3
  interface Logger {
4
4
  info(msg: string, data?: Record<string, unknown>): void;
@@ -115,83 +115,53 @@ interface BatchEventResponse {
115
115
  error?: string;
116
116
  }
117
117
 
118
- /**
119
- * Server-side flags manager
120
- * Optimized for server environments with:
121
- * - Request-level deduplication
122
- * - Request batching
123
- * - Stale-while-revalidate caching
124
- * - No persistent storage (stateless)
125
- */
126
- declare class ServerFlagsManager implements FlagsManager {
127
- private config;
128
- private readonly onFlagsUpdate?;
129
- private readonly onConfigUpdate?;
130
- /** In-memory cache with stale tracking */
118
+ declare abstract class BaseFlagsManager implements FlagsManager {
119
+ protected config: FlagsConfig;
120
+ protected readonly storage?: StorageInterface;
131
121
  private readonly cache;
132
- /** In-flight requests for deduplication */
133
- private readonly inFlight;
134
- /** Request batcher */
135
122
  private batcher;
136
- /** Ready state */
137
123
  private ready;
138
- /** Init promise for awaiting */
139
- private readonly initPromise;
124
+ private readonly listeners;
125
+ private snapshot;
140
126
  constructor(options: FlagsManagerOptions);
141
- private withDefaults;
142
- private initialize;
143
- /**
144
- * Wait for initialization to complete
145
- */
146
- waitForInit(): Promise<void>;
147
- private getFromCache;
148
- private getBatcher;
149
- /**
150
- * Get a flag with deduplication, batching, and SWR caching
151
- */
127
+ protected shouldSkipFetch(): boolean;
128
+ protected onCacheUpdated(): void;
129
+ protected onFlagEvaluated(_key: string, _result: FlagResult): void;
130
+ protected runInit(): Promise<void>;
131
+ private hydrate;
132
+ protected persist(): void;
133
+ private ttls;
134
+ private validEntry;
135
+ private ensureBatcher;
136
+ protected batchDelay(): number;
137
+ private pruneStaleKeys;
138
+ private revalidate;
152
139
  getFlag(key: string, user?: UserContext): Promise<FlagResult>;
153
- private revalidateFlag;
154
- /**
155
- * Fetch all flags for a user
156
- */
157
140
  fetchAllFlags(user?: UserContext): Promise<void>;
158
- /**
159
- * Check if flag is enabled (synchronous)
160
- */
161
141
  isEnabled(key: string): FlagState;
162
- /**
163
- * Get flag value (synchronous)
164
- */
165
142
  getValue<T = boolean | string | number>(key: string, defaultValue?: T): T;
166
- /**
167
- * Update user context
168
- */
169
143
  updateUser(user: UserContext): void;
170
- /**
171
- * Refresh flags
172
- */
173
144
  refresh(forceClear?: boolean): Promise<void>;
174
- /**
175
- * Update config
176
- */
177
145
  updateConfig(config: FlagsConfig): void;
178
- /**
179
- * Get all cached flags
180
- */
181
146
  getMemoryFlags(): Record<string, FlagResult>;
182
- /**
183
- * Check if ready
184
- */
185
147
  isReady(): boolean;
186
- /**
187
- * Cleanup resources
188
- */
189
148
  destroy(): void;
149
+ subscribe: (cb: () => void) => (() => void);
150
+ getSnapshot: () => FlagsSnapshot;
151
+ protected enrichUser(user: UserContext): UserContext;
152
+ protected emit(): void;
153
+ private resetBatcher;
154
+ protected revalidateStale(): void;
155
+ }
156
+
157
+ declare class ServerFlagsManager extends BaseFlagsManager {
158
+ private readonly initPromise;
159
+ constructor(options: FlagsManagerOptions);
160
+ protected batchDelay(): number;
161
+ waitForInit(): Promise<void>;
190
162
  }
191
163
 
192
164
  /**
193
- * Create a ServerFlagsManager with in-memory caching
194
- *
195
165
  * @example
196
166
  * ```typescript
197
167
  * import { createServerFlagsManager } from '@databuddy/sdk/node';
@@ -205,22 +175,6 @@ declare class ServerFlagsManager implements FlagsManager {
205
175
  * ```
206
176
  */
207
177
  declare function createServerFlagsManager(config: FlagsConfig): ServerFlagsManager;
208
- /**
209
- * Alias for createServerFlagsManager (for backwards compatibility)
210
- *
211
- * @example
212
- * ```typescript
213
- * import { createServerFlagsManagerInMemory } from '@databuddy/sdk/node';
214
- *
215
- * const manager = createServerFlagsManagerInMemory({
216
- * clientId: process.env.DATABUDDY_CLIENT_ID!,
217
- * });
218
- *
219
- * await manager.waitForInit();
220
- * const flag = await manager.getFlag('my-feature');
221
- * ```
222
- */
223
- declare function createServerFlagsManagerInMemory(config: FlagsConfig): ServerFlagsManager;
224
178
 
225
179
  /** biome-ignore-all lint/performance/noBarrelFile: im a big fan of barrels */
226
180
 
@@ -253,10 +207,10 @@ declare class Databuddy {
253
207
  * properties: { plan: 'pro', source: 'web' }
254
208
  * });
255
209
  *
256
- * // With website scope
210
+ * // With website scope (use your public client id from the dashboard)
257
211
  * await client.track({
258
212
  * name: 'page_view',
259
- * websiteId: 'website-uuid',
213
+ * websiteId: 'your-public-client-id',
260
214
  * properties: { path: '/pricing' }
261
215
  * });
262
216
  * ```
@@ -376,5 +330,5 @@ declare class Databuddy {
376
330
  private addToDeduplicationCache;
377
331
  }
378
332
 
379
- export { Databuddy, ServerFlagsManager, createServerFlagsManager, createServerFlagsManagerInMemory, Databuddy as db };
333
+ export { Databuddy, ServerFlagsManager, createServerFlagsManager, Databuddy as db };
380
334
  export type { BatchEventInput, BatchEventResponse, CustomEventInput, DatabuddyConfig, EventResponse, GlobalProperties, Logger, Middleware };
@@ -1,4 +1,4 @@
1
- import { e as FlagsManager, f as FlagsManagerOptions, U as UserContext, d as FlagResult, b as FlagState, F as FlagsConfig } from '../shared/@databuddy/sdk.CdLp6SQb.js';
1
+ import { d as FlagsManager, F as FlagsConfig, S as StorageInterface, e as FlagsManagerOptions, c as FlagResult, U as UserContext, a as FlagState, f as FlagsSnapshot } from '../shared/@databuddy/sdk.rnu91OSC.js';
2
2
 
3
3
  interface Logger {
4
4
  info(msg: string, data?: Record<string, unknown>): void;
@@ -115,83 +115,53 @@ interface BatchEventResponse {
115
115
  error?: string;
116
116
  }
117
117
 
118
- /**
119
- * Server-side flags manager
120
- * Optimized for server environments with:
121
- * - Request-level deduplication
122
- * - Request batching
123
- * - Stale-while-revalidate caching
124
- * - No persistent storage (stateless)
125
- */
126
- declare class ServerFlagsManager implements FlagsManager {
127
- private config;
128
- private readonly onFlagsUpdate?;
129
- private readonly onConfigUpdate?;
130
- /** In-memory cache with stale tracking */
118
+ declare abstract class BaseFlagsManager implements FlagsManager {
119
+ protected config: FlagsConfig;
120
+ protected readonly storage?: StorageInterface;
131
121
  private readonly cache;
132
- /** In-flight requests for deduplication */
133
- private readonly inFlight;
134
- /** Request batcher */
135
122
  private batcher;
136
- /** Ready state */
137
123
  private ready;
138
- /** Init promise for awaiting */
139
- private readonly initPromise;
124
+ private readonly listeners;
125
+ private snapshot;
140
126
  constructor(options: FlagsManagerOptions);
141
- private withDefaults;
142
- private initialize;
143
- /**
144
- * Wait for initialization to complete
145
- */
146
- waitForInit(): Promise<void>;
147
- private getFromCache;
148
- private getBatcher;
149
- /**
150
- * Get a flag with deduplication, batching, and SWR caching
151
- */
127
+ protected shouldSkipFetch(): boolean;
128
+ protected onCacheUpdated(): void;
129
+ protected onFlagEvaluated(_key: string, _result: FlagResult): void;
130
+ protected runInit(): Promise<void>;
131
+ private hydrate;
132
+ protected persist(): void;
133
+ private ttls;
134
+ private validEntry;
135
+ private ensureBatcher;
136
+ protected batchDelay(): number;
137
+ private pruneStaleKeys;
138
+ private revalidate;
152
139
  getFlag(key: string, user?: UserContext): Promise<FlagResult>;
153
- private revalidateFlag;
154
- /**
155
- * Fetch all flags for a user
156
- */
157
140
  fetchAllFlags(user?: UserContext): Promise<void>;
158
- /**
159
- * Check if flag is enabled (synchronous)
160
- */
161
141
  isEnabled(key: string): FlagState;
162
- /**
163
- * Get flag value (synchronous)
164
- */
165
142
  getValue<T = boolean | string | number>(key: string, defaultValue?: T): T;
166
- /**
167
- * Update user context
168
- */
169
143
  updateUser(user: UserContext): void;
170
- /**
171
- * Refresh flags
172
- */
173
144
  refresh(forceClear?: boolean): Promise<void>;
174
- /**
175
- * Update config
176
- */
177
145
  updateConfig(config: FlagsConfig): void;
178
- /**
179
- * Get all cached flags
180
- */
181
146
  getMemoryFlags(): Record<string, FlagResult>;
182
- /**
183
- * Check if ready
184
- */
185
147
  isReady(): boolean;
186
- /**
187
- * Cleanup resources
188
- */
189
148
  destroy(): void;
149
+ subscribe: (cb: () => void) => (() => void);
150
+ getSnapshot: () => FlagsSnapshot;
151
+ protected enrichUser(user: UserContext): UserContext;
152
+ protected emit(): void;
153
+ private resetBatcher;
154
+ protected revalidateStale(): void;
155
+ }
156
+
157
+ declare class ServerFlagsManager extends BaseFlagsManager {
158
+ private readonly initPromise;
159
+ constructor(options: FlagsManagerOptions);
160
+ protected batchDelay(): number;
161
+ waitForInit(): Promise<void>;
190
162
  }
191
163
 
192
164
  /**
193
- * Create a ServerFlagsManager with in-memory caching
194
- *
195
165
  * @example
196
166
  * ```typescript
197
167
  * import { createServerFlagsManager } from '@databuddy/sdk/node';
@@ -205,22 +175,6 @@ declare class ServerFlagsManager implements FlagsManager {
205
175
  * ```
206
176
  */
207
177
  declare function createServerFlagsManager(config: FlagsConfig): ServerFlagsManager;
208
- /**
209
- * Alias for createServerFlagsManager (for backwards compatibility)
210
- *
211
- * @example
212
- * ```typescript
213
- * import { createServerFlagsManagerInMemory } from '@databuddy/sdk/node';
214
- *
215
- * const manager = createServerFlagsManagerInMemory({
216
- * clientId: process.env.DATABUDDY_CLIENT_ID!,
217
- * });
218
- *
219
- * await manager.waitForInit();
220
- * const flag = await manager.getFlag('my-feature');
221
- * ```
222
- */
223
- declare function createServerFlagsManagerInMemory(config: FlagsConfig): ServerFlagsManager;
224
178
 
225
179
  /** biome-ignore-all lint/performance/noBarrelFile: im a big fan of barrels */
226
180
 
@@ -253,10 +207,10 @@ declare class Databuddy {
253
207
  * properties: { plan: 'pro', source: 'web' }
254
208
  * });
255
209
  *
256
- * // With website scope
210
+ * // With website scope (use your public client id from the dashboard)
257
211
  * await client.track({
258
212
  * name: 'page_view',
259
- * websiteId: 'website-uuid',
213
+ * websiteId: 'your-public-client-id',
260
214
  * properties: { path: '/pricing' }
261
215
  * });
262
216
  * ```
@@ -376,5 +330,5 @@ declare class Databuddy {
376
330
  private addToDeduplicationCache;
377
331
  }
378
332
 
379
- export { Databuddy, ServerFlagsManager, createServerFlagsManager, createServerFlagsManagerInMemory, Databuddy as db };
333
+ export { Databuddy, ServerFlagsManager, createServerFlagsManager, Databuddy as db };
380
334
  export type { BatchEventInput, BatchEventResponse, CustomEventInput, DatabuddyConfig, EventResponse, GlobalProperties, Logger, Middleware };
@@ -1,4 +1,4 @@
1
- import { l as logger, i as isCacheValid, b as buildQueryParams, R as RequestBatcher, D as DEFAULT_RESULT, g as getCacheKey, a as isCacheStale, c as createCacheEntry, f as fetchAllFlags } from '../shared/@databuddy/sdk.CALvx07o.mjs';
1
+ import { a as BaseFlagsManager } from '../shared/@databuddy/sdk.Ugr1p2j9.mjs';
2
2
 
3
3
  function createLogger(debug = false) {
4
4
  return createConsoleLogger(debug);
@@ -62,256 +62,24 @@ class EventQueue {
62
62
  }
63
63
  }
64
64
 
65
- class ServerFlagsManager {
66
- config;
67
- onFlagsUpdate;
68
- onConfigUpdate;
69
- /** In-memory cache with stale tracking */
70
- cache = /* @__PURE__ */ new Map();
71
- /** In-flight requests for deduplication */
72
- inFlight = /* @__PURE__ */ new Map();
73
- /** Request batcher */
74
- batcher = null;
75
- /** Ready state */
76
- ready = false;
77
- /** Init promise for awaiting */
65
+ class ServerFlagsManager extends BaseFlagsManager {
78
66
  initPromise;
79
67
  constructor(options) {
80
- this.config = this.withDefaults(options.config);
81
- this.onFlagsUpdate = options.onFlagsUpdate;
82
- this.onConfigUpdate = options.onConfigUpdate;
83
- logger.setDebug(this.config.debug ?? false);
84
- logger.debug("ServerFlagsManager initialized", {
85
- clientId: this.config.clientId,
86
- hasUser: Boolean(this.config.user)
87
- });
88
- this.initPromise = this.initialize();
68
+ super(options);
69
+ this.config.autoFetch = options.config.autoFetch ?? false;
70
+ this.config.skipStorage = true;
71
+ this.initPromise = this.runInit();
89
72
  }
90
- withDefaults(config) {
91
- return {
92
- clientId: config.clientId,
93
- apiUrl: config.apiUrl ?? "https://api.databuddy.cc",
94
- user: config.user,
95
- disabled: config.disabled ?? false,
96
- debug: config.debug ?? false,
97
- skipStorage: true,
98
- // Always skip storage on server
99
- isPending: config.isPending,
100
- autoFetch: config.autoFetch ?? false,
101
- environment: config.environment,
102
- cacheTtl: config.cacheTtl ?? 6e4,
103
- // 1 minute
104
- staleTime: config.staleTime ?? 3e4
105
- // 30 seconds
106
- };
107
- }
108
- async initialize() {
109
- if (this.config.autoFetch && !this.config.isPending) {
110
- await this.fetchAllFlags();
111
- }
112
- this.ready = true;
73
+ batchDelay() {
74
+ return 5;
113
75
  }
114
- /**
115
- * Wait for initialization to complete
116
- */
117
76
  async waitForInit() {
118
77
  await this.initPromise;
119
78
  }
120
- getFromCache(key) {
121
- const cached = this.cache.get(key);
122
- if (isCacheValid(cached)) {
123
- return cached;
124
- }
125
- if (cached) {
126
- this.cache.delete(key);
127
- }
128
- return null;
129
- }
130
- getBatcher() {
131
- if (!this.batcher) {
132
- const apiUrl = this.config.apiUrl ?? "https://api.databuddy.cc";
133
- const params = buildQueryParams(this.config);
134
- this.batcher = new RequestBatcher(apiUrl, params, 5);
135
- }
136
- return this.batcher;
137
- }
138
- /**
139
- * Get a flag with deduplication, batching, and SWR caching
140
- */
141
- async getFlag(key, user) {
142
- if (this.config.disabled) {
143
- return DEFAULT_RESULT;
144
- }
145
- if (this.config.isPending) {
146
- return { ...DEFAULT_RESULT, reason: "SESSION_PENDING" };
147
- }
148
- const cacheKey = getCacheKey(key, user ?? this.config.user);
149
- const cached = this.getFromCache(cacheKey);
150
- if (cached) {
151
- if (isCacheStale(cached)) {
152
- this.revalidateFlag(key, cacheKey);
153
- }
154
- return cached.result;
155
- }
156
- const existing = this.inFlight.get(cacheKey);
157
- if (existing) {
158
- logger.debug(`Deduplicating request: ${key}`);
159
- return existing;
160
- }
161
- const promise = this.getBatcher().request(key);
162
- this.inFlight.set(cacheKey, promise);
163
- try {
164
- const result = await promise;
165
- const ttl = this.config.cacheTtl ?? 6e4;
166
- const staleTime = this.config.staleTime ?? ttl / 2;
167
- this.cache.set(cacheKey, createCacheEntry(result, ttl, staleTime));
168
- return result;
169
- } finally {
170
- this.inFlight.delete(cacheKey);
171
- }
172
- }
173
- async revalidateFlag(key, cacheKey) {
174
- if (this.inFlight.has(cacheKey)) {
175
- return;
176
- }
177
- const promise = this.getBatcher().request(key);
178
- this.inFlight.set(cacheKey, promise);
179
- try {
180
- const result = await promise;
181
- const ttl = this.config.cacheTtl ?? 6e4;
182
- const staleTime = this.config.staleTime ?? ttl / 2;
183
- this.cache.set(cacheKey, createCacheEntry(result, ttl, staleTime));
184
- logger.debug(`Revalidated flag: ${key}`);
185
- } catch (err) {
186
- logger.error(`Revalidation error: ${key}`, err);
187
- } finally {
188
- this.inFlight.delete(cacheKey);
189
- }
190
- }
191
- /**
192
- * Fetch all flags for a user
193
- */
194
- async fetchAllFlags(user) {
195
- if (this.config.disabled || this.config.isPending) {
196
- return;
197
- }
198
- const apiUrl = this.config.apiUrl ?? "https://api.databuddy.cc";
199
- const params = buildQueryParams(this.config, user);
200
- try {
201
- const flags = await fetchAllFlags(apiUrl, params);
202
- const ttl = this.config.cacheTtl ?? 6e4;
203
- const staleTime = this.config.staleTime ?? ttl / 2;
204
- for (const [key, result] of Object.entries(flags)) {
205
- const cacheKey = getCacheKey(key, user ?? this.config.user);
206
- this.cache.set(cacheKey, createCacheEntry(result, ttl, staleTime));
207
- }
208
- this.ready = true;
209
- this.onFlagsUpdate?.(flags);
210
- logger.debug(`Fetched ${Object.keys(flags).length} flags`);
211
- } catch (err) {
212
- logger.error("Bulk fetch error:", err);
213
- }
214
- }
215
- /**
216
- * Check if flag is enabled (synchronous)
217
- */
218
- isEnabled(key) {
219
- const cacheKey = getCacheKey(key, this.config.user);
220
- const cached = this.getFromCache(cacheKey);
221
- if (cached) {
222
- return {
223
- on: cached.result.enabled,
224
- enabled: cached.result.enabled,
225
- status: cached.result.reason === "ERROR" ? "error" : "ready",
226
- loading: false,
227
- isLoading: false,
228
- isReady: true,
229
- value: cached.result.value,
230
- variant: cached.result.variant
231
- };
232
- }
233
- const loading = this.inFlight.has(cacheKey);
234
- return {
235
- on: false,
236
- enabled: false,
237
- status: "loading",
238
- loading,
239
- isLoading: loading,
240
- isReady: false
241
- };
242
- }
243
- /**
244
- * Get flag value (synchronous)
245
- */
246
- getValue(key, defaultValue) {
247
- const cacheKey = getCacheKey(key, this.config.user);
248
- const cached = this.getFromCache(cacheKey);
249
- if (cached) {
250
- return cached.result.value;
251
- }
252
- return defaultValue ?? false;
253
- }
254
- /**
255
- * Update user context
256
- */
257
- updateUser(user) {
258
- this.config = { ...this.config, user };
259
- this.batcher?.destroy();
260
- this.batcher = null;
261
- this.onConfigUpdate?.(this.config);
262
- }
263
- /**
264
- * Refresh flags
265
- */
266
- async refresh(forceClear = false) {
267
- if (forceClear) {
268
- this.cache.clear();
269
- }
270
- await this.fetchAllFlags();
271
- }
272
- /**
273
- * Update config
274
- */
275
- updateConfig(config) {
276
- this.config = this.withDefaults(config);
277
- this.batcher?.destroy();
278
- this.batcher = null;
279
- this.onConfigUpdate?.(this.config);
280
- }
281
- /**
282
- * Get all cached flags
283
- */
284
- getMemoryFlags() {
285
- const flags = {};
286
- for (const [key, entry] of this.cache) {
287
- const flagKey = key.split(":")[0];
288
- flags[flagKey] = entry.result;
289
- }
290
- return flags;
291
- }
292
- /**
293
- * Check if ready
294
- */
295
- isReady() {
296
- return this.ready;
297
- }
298
- /**
299
- * Cleanup resources
300
- */
301
- destroy() {
302
- this.batcher?.destroy();
303
- this.cache.clear();
304
- this.inFlight.clear();
305
- }
306
79
  }
307
80
 
308
81
  function createServerFlagsManager(config) {
309
- return new ServerFlagsManager({
310
- config
311
- });
312
- }
313
- function createServerFlagsManagerInMemory(config) {
314
- return createServerFlagsManager(config);
82
+ return new ServerFlagsManager({ config });
315
83
  }
316
84
 
317
85
  const DEFAULT_API_URL = "https://basket.databuddy.cc";
@@ -383,10 +151,10 @@ class Databuddy {
383
151
  * properties: { plan: 'pro', source: 'web' }
384
152
  * });
385
153
  *
386
- * // With website scope
154
+ * // With website scope (use your public client id from the dashboard)
387
155
  * await client.track({
388
156
  * name: 'page_view',
389
- * websiteId: 'website-uuid',
157
+ * websiteId: 'your-public-client-id',
390
158
  * properties: { path: '/pricing' }
391
159
  * });
392
160
  * ```
@@ -800,4 +568,4 @@ class Databuddy {
800
568
  }
801
569
  }
802
570
 
803
- export { Databuddy, ServerFlagsManager, createServerFlagsManager, createServerFlagsManagerInMemory, Databuddy as db };
571
+ export { Databuddy, ServerFlagsManager, createServerFlagsManager, Databuddy as db };