@finatic/client 0.9.1 → 0.9.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/README.md +243 -47
- package/dist/index.d.ts +12 -6
- package/dist/index.js +95 -69
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -69
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -9
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import pRetry, { AbortError } from 'p-retry';
|
|
2
|
-
import pino from 'pino';
|
|
3
|
-
import NodeCache from 'node-cache';
|
|
4
2
|
import * as z from 'zod';
|
|
5
3
|
import globalAxios from 'axios';
|
|
6
4
|
|
|
@@ -72,14 +70,12 @@ async function retryApiCall(fn, options = {}, config) {
|
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
/**
|
|
75
|
-
* Structured logger utility with browser-safe
|
|
73
|
+
* Structured logger utility with browser-safe console logging (Phase 2C).
|
|
76
74
|
*
|
|
77
75
|
* Generated - do not edit directly.
|
|
78
76
|
*
|
|
79
|
-
* This logger
|
|
80
|
-
* in browser environments (Vite, Next.js, etc.).
|
|
77
|
+
* This logger uses browser console APIs for all logging in browser environments.
|
|
81
78
|
*/
|
|
82
|
-
// @ts-ignore - pino types available via @types/pino
|
|
83
79
|
let _loggerInstance = null;
|
|
84
80
|
/**
|
|
85
81
|
* Get environment variable from various sources (browser and Node.js).
|
|
@@ -124,30 +120,6 @@ function isProduction() {
|
|
|
124
120
|
return true;
|
|
125
121
|
return false;
|
|
126
122
|
}
|
|
127
|
-
/**
|
|
128
|
-
* Detect if we're in a browser environment.
|
|
129
|
-
*/
|
|
130
|
-
function isBrowser() {
|
|
131
|
-
// Check for window object (browser)
|
|
132
|
-
if (typeof window !== 'undefined') {
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
// Check for globalThis in browser-like environments
|
|
136
|
-
if (typeof globalThis !== 'undefined') {
|
|
137
|
-
// In browsers, process might be polyfilled but process.stdout won't exist
|
|
138
|
-
try {
|
|
139
|
-
const proc = globalThis.process;
|
|
140
|
-
if (proc && typeof proc.stdout === 'undefined') {
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
// If we can't check, assume browser if window exists
|
|
146
|
-
return typeof window !== 'undefined';
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
123
|
/**
|
|
152
124
|
* Get or create a logger instance with browser-safe fallback.
|
|
153
125
|
*/
|
|
@@ -155,36 +127,13 @@ function getLogger(config) {
|
|
|
155
127
|
if (_loggerInstance) {
|
|
156
128
|
return _loggerInstance;
|
|
157
129
|
}
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
return getBrowserSafeLogger(config);
|
|
161
|
-
}
|
|
162
|
-
// Try to use pino first (Node.js environments)
|
|
163
|
-
try {
|
|
164
|
-
const logLevel = (config?.logLevel || getEnvVar('FINATIC_LOG_LEVEL') || 'error');
|
|
165
|
-
const pinoConfig = {
|
|
166
|
-
level: logLevel === 'silent' ? 'silent' : logLevel,
|
|
167
|
-
...(config?.structuredLogging !== false && {
|
|
168
|
-
formatters: {
|
|
169
|
-
level: (label) => {
|
|
170
|
-
return { level: label };
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
timestamp: true,
|
|
174
|
-
}),
|
|
175
|
-
};
|
|
176
|
-
_loggerInstance = pino(pinoConfig);
|
|
177
|
-
return _loggerInstance;
|
|
178
|
-
}
|
|
179
|
-
catch (error) {
|
|
180
|
-
// Fallback to browser-safe logger if pino fails
|
|
181
|
-
return getBrowserSafeLogger(config, error);
|
|
182
|
-
}
|
|
130
|
+
// Client SDK always uses browser-safe logger (no pino)
|
|
131
|
+
return getBrowserSafeLogger(config);
|
|
183
132
|
}
|
|
184
133
|
/**
|
|
185
|
-
* Browser-safe logger
|
|
134
|
+
* Browser-safe logger for Client SDK.
|
|
186
135
|
*/
|
|
187
|
-
function getBrowserSafeLogger(config
|
|
136
|
+
function getBrowserSafeLogger(config) {
|
|
188
137
|
// Log level hierarchy (matching pino's numeric levels)
|
|
189
138
|
const LOG_LEVELS = {
|
|
190
139
|
silent: 0,
|
|
@@ -215,7 +164,7 @@ function getBrowserSafeLogger(config, pinoError) {
|
|
|
215
164
|
};
|
|
216
165
|
const logLevel = getEffectiveLogLevel();
|
|
217
166
|
const structuredLogging = config?.structuredLogging ?? false;
|
|
218
|
-
|
|
167
|
+
isProduction();
|
|
219
168
|
/**
|
|
220
169
|
* Check if we should log at this level.
|
|
221
170
|
*/
|
|
@@ -348,10 +297,6 @@ function getBrowserSafeLogger(config, pinoError) {
|
|
|
348
297
|
}
|
|
349
298
|
},
|
|
350
299
|
};
|
|
351
|
-
// Only warn about fallback logger if pino failed (not if we're in browser)
|
|
352
|
-
if (pinoError && !isProd) {
|
|
353
|
-
console.warn('[Finatic SDK] Using fallback logger due to pino initialization error:', pinoError);
|
|
354
|
-
}
|
|
355
300
|
_loggerInstance = fallbackLogger;
|
|
356
301
|
return _loggerInstance;
|
|
357
302
|
}
|
|
@@ -419,11 +364,96 @@ function handleError(error, requestId) {
|
|
|
419
364
|
}
|
|
420
365
|
|
|
421
366
|
/**
|
|
422
|
-
* Response caching utility with
|
|
367
|
+
* Response caching utility with browser-compatible Map-based cache (Phase 2B).
|
|
423
368
|
*
|
|
424
369
|
* Generated - do not edit directly.
|
|
425
370
|
*/
|
|
426
|
-
|
|
371
|
+
class MapBasedCache {
|
|
372
|
+
constructor(maxSize = 1000, defaultTtl = 300) {
|
|
373
|
+
this.cleanupInterval = null;
|
|
374
|
+
this.cache = new Map();
|
|
375
|
+
this.maxSize = maxSize;
|
|
376
|
+
this.defaultTtl = defaultTtl;
|
|
377
|
+
this.startCleanup();
|
|
378
|
+
}
|
|
379
|
+
startCleanup() {
|
|
380
|
+
// Clean up expired entries every minute
|
|
381
|
+
if (typeof window !== 'undefined') {
|
|
382
|
+
this.cleanupInterval = window.setInterval(() => {
|
|
383
|
+
this.cleanup();
|
|
384
|
+
}, 60000);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
cleanup() {
|
|
388
|
+
const now = Date.now();
|
|
389
|
+
const keysToDelete = [];
|
|
390
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
391
|
+
if (entry.expires < now) {
|
|
392
|
+
keysToDelete.push(key);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
keysToDelete.forEach(key => this.cache.delete(key));
|
|
396
|
+
}
|
|
397
|
+
evictLRU() {
|
|
398
|
+
if (this.cache.size < this.maxSize) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
// Simple LRU: remove oldest entry (first in Map)
|
|
402
|
+
const firstKey = this.cache.keys().next().value;
|
|
403
|
+
if (firstKey) {
|
|
404
|
+
this.cache.delete(firstKey);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
get(key) {
|
|
408
|
+
const entry = this.cache.get(key);
|
|
409
|
+
if (!entry) {
|
|
410
|
+
return undefined;
|
|
411
|
+
}
|
|
412
|
+
// Check if expired
|
|
413
|
+
if (entry.expires < Date.now()) {
|
|
414
|
+
this.cache.delete(key);
|
|
415
|
+
return undefined;
|
|
416
|
+
}
|
|
417
|
+
return entry.value;
|
|
418
|
+
}
|
|
419
|
+
set(key, value, ttl) {
|
|
420
|
+
// Evict if at max size
|
|
421
|
+
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
|
|
422
|
+
this.evictLRU();
|
|
423
|
+
}
|
|
424
|
+
const expires = Date.now() + (ttl || this.defaultTtl) * 1000;
|
|
425
|
+
this.cache.set(key, { value, expires });
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
del(key) {
|
|
429
|
+
return this.cache.delete(key) ? 1 : 0;
|
|
430
|
+
}
|
|
431
|
+
clear() {
|
|
432
|
+
this.cache.clear();
|
|
433
|
+
}
|
|
434
|
+
keys() {
|
|
435
|
+
return Array.from(this.cache.keys());
|
|
436
|
+
}
|
|
437
|
+
has(key) {
|
|
438
|
+
const entry = this.cache.get(key);
|
|
439
|
+
if (!entry) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
// Check if expired
|
|
443
|
+
if (entry.expires < Date.now()) {
|
|
444
|
+
this.cache.delete(key);
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
destroy() {
|
|
450
|
+
if (this.cleanupInterval !== null && typeof window !== 'undefined') {
|
|
451
|
+
window.clearInterval(this.cleanupInterval);
|
|
452
|
+
this.cleanupInterval = null;
|
|
453
|
+
}
|
|
454
|
+
this.cache.clear();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
427
457
|
let _cacheInstance = null;
|
|
428
458
|
/**
|
|
429
459
|
* Get or create cache instance.
|
|
@@ -435,11 +465,7 @@ function getCache(config) {
|
|
|
435
465
|
if (_cacheInstance) {
|
|
436
466
|
return _cacheInstance;
|
|
437
467
|
}
|
|
438
|
-
_cacheInstance = new
|
|
439
|
-
stdTTL: config.cacheTtl || 300,
|
|
440
|
-
maxKeys: config.cacheMaxSize || 1000,
|
|
441
|
-
useClones: false,
|
|
442
|
-
});
|
|
468
|
+
_cacheInstance = new MapBasedCache(config.cacheMaxSize || 1000, config.cacheTtl || 300);
|
|
443
469
|
return _cacheInstance;
|
|
444
470
|
}
|
|
445
471
|
/**
|