@mushi-mushi/core 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.
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/index.cjs +680 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +330 -0
- package/dist/index.d.ts +330 -0
- package/dist/index.js +668 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/api-client.ts","../src/pre-filter.ts","../src/logger.ts","../src/queue.ts","../src/environment.ts","../src/reporter-token.ts","../src/session.ts","../src/rate-limiter.ts","../src/pii-scrubber.ts"],"names":["getBackoffDelay","sleep"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { MushiApiClient, MushiApiResponse, MushiReport, MushiReportStatus } from './types';\n\nexport interface ApiClientOptions {\n projectId: string;\n apiKey: string;\n apiEndpoint: string;\n timeout?: number;\n maxRetries?: number;\n}\n\nconst DEFAULT_API_ENDPOINT = 'https://api.mushimushi.dev';\nconst DEFAULT_TIMEOUT = 10_000;\nconst DEFAULT_MAX_RETRIES = 2;\n\nexport function createApiClient(options: ApiClientOptions): MushiApiClient {\n const {\n projectId,\n apiKey,\n apiEndpoint = DEFAULT_API_ENDPOINT,\n timeout = DEFAULT_TIMEOUT,\n maxRetries = DEFAULT_MAX_RETRIES,\n } = options;\n\n const baseUrl = apiEndpoint.replace(/\\/$/, '');\n\n async function request<T>(\n method: string,\n path: string,\n body?: unknown,\n retries = maxRetries,\n ): Promise<MushiApiResponse<T>> {\n const url = `${baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'X-Mushi-Api-Key': apiKey,\n 'X-Mushi-Project': projectId,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timer);\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({}));\n if (response.status >= 500 && retries > 0) {\n await sleep(getBackoffDelay(maxRetries - retries));\n return request<T>(method, path, body, retries - 1);\n }\n return {\n ok: false,\n error: {\n code: `HTTP_${response.status}`,\n message:\n (errorBody as { message?: string }).message || `HTTP ${response.status} error`,\n },\n };\n }\n\n const data = (await response.json()) as T;\n return { ok: true, data };\n } catch (error) {\n clearTimeout(timer);\n\n if (retries > 0 && isRetryable(error)) {\n await sleep(getBackoffDelay(maxRetries - retries));\n return request<T>(method, path, body, retries - 1);\n }\n\n return {\n ok: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Unknown network error',\n },\n };\n }\n }\n\n return {\n async submitReport(report: MushiReport) {\n return request<{ reportId: string }>('POST', '/v1/reports', report);\n },\n\n async getReportStatus(reportId: string) {\n return request<{ status: MushiReportStatus }>('GET', `/v1/reports/${reportId}/status`);\n },\n };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction getBackoffDelay(attempt: number): number {\n return Math.min(1000 * 2 ** attempt + Math.random() * 500, 10_000);\n}\n\nfunction isRetryable(error: unknown): boolean {\n if (error instanceof DOMException && error.name === 'AbortError') return true;\n if (error instanceof TypeError) return true; // network failures\n return false;\n}\n","import type { MushiPreFilterConfig } from './types';\n\nexport interface PreFilterResult {\n passed: boolean;\n reason?: string;\n}\n\nconst DEFAULT_MIN_LENGTH = 10;\nconst DEFAULT_MAX_LENGTH = 2000;\n\nconst SPAM_PATTERNS: RegExp[] = [\n /^(.)\\1{10,}$/, // repeated single character\n /^[A-Z\\s!?]{20,}$/, // all caps shouting\n /^[\\d\\s]+$/, // numbers only\n /^[^a-zA-Z\\u00C0-\\u024F\\u4E00-\\u9FFF\\u3040-\\u309F\\u30A0-\\u30FF]{10,}$/, // no real letters\n /\\b(test|asdf|qwerty|lorem ipsum)\\b/i, // common test strings\n];\n\nconst GIBBERISH_PATTERN = /^[bcdfghjklmnpqrstvwxz]{6,}/i; // consonant-only strings\n\nexport function createPreFilter(config: MushiPreFilterConfig = {}) {\n const {\n enabled = true,\n blockObviousSpam = true,\n minDescriptionLength = DEFAULT_MIN_LENGTH,\n maxDescriptionLength = DEFAULT_MAX_LENGTH,\n } = config;\n\n function check(description: string): PreFilterResult {\n if (!enabled) {\n return { passed: true };\n }\n\n const trimmed = description.trim();\n\n if (trimmed.length < minDescriptionLength) {\n return { passed: false, reason: `Too short (min ${minDescriptionLength} characters)` };\n }\n\n if (trimmed.length > maxDescriptionLength) {\n return { passed: false, reason: `Too long (max ${maxDescriptionLength} characters)` };\n }\n\n if (blockObviousSpam) {\n for (const pattern of SPAM_PATTERNS) {\n if (pattern.test(trimmed)) {\n return { passed: false, reason: 'Detected as spam' };\n }\n }\n\n if (GIBBERISH_PATTERN.test(trimmed)) {\n return { passed: false, reason: 'Detected as gibberish' };\n }\n\n const words = trimmed.split(/\\s+/).filter((w) => w.length > 1);\n if (words.length < 2) {\n return { passed: false, reason: 'Description needs at least 2 words' };\n }\n }\n\n return { passed: true };\n }\n\n function truncate(description: string): string {\n const trimmed = description.trim();\n if (trimmed.length <= maxDescriptionLength) return trimmed;\n return trimmed.slice(0, maxDescriptionLength) + '...';\n }\n\n return { check, truncate };\n}\n","/**\n * FILE: logger.ts\n * PURPOSE: Zero-dependency structured logger for the mushi-mushi SDK ecosystem.\n *\n * OVERVIEW:\n * - Production-grade logging with levels, scoped namespaces, and child loggers\n * - JSON output for server/production, pretty-formatted output for development\n * - Automatic environment detection (browser vs Node vs Deno)\n * - Structured metadata on every log entry\n * - No external dependencies — safe to ship in any SDK bundle\n *\n * USAGE:\n * import { createLogger } from '@mushi-mushi/core'\n * const log = createLogger({ scope: 'mushi:api' })\n * log.info('Request received', { method: 'POST', path: '/v1/reports' })\n * const child = log.child('ingest', { reportId: 'abc' })\n * child.warn('Slow query', { latencyMs: 420 })\n *\n * TECHNICAL DETAILS:\n * - Log levels: debug(10) < info(20) < warn(30) < error(40) < fatal(50) < silent(99)\n * - Format auto-detected: JSON in production/server, pretty in development\n * - Pretty format uses ANSI colors when supported (Node/Deno TTY)\n * - Child loggers inherit parent scope + metadata, can override level\n * - Timestamps are ISO 8601 with millisecond precision\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent'\n\nexport type LogFormat = 'json' | 'pretty' | 'auto'\n\nexport interface LoggerOptions {\n scope: string\n level?: LogLevel\n meta?: Record<string, unknown>\n format?: LogFormat\n}\n\nexport interface Logger {\n debug(msg: string, meta?: Record<string, unknown>): void\n info(msg: string, meta?: Record<string, unknown>): void\n warn(msg: string, meta?: Record<string, unknown>): void\n error(msg: string, meta?: Record<string, unknown>): void\n fatal(msg: string, meta?: Record<string, unknown>): void\n child(scope: string, meta?: Record<string, unknown>): Logger\n setLevel(level: LogLevel): void\n}\n\nexport interface LogEntry {\n ts: string\n level: LogLevel\n scope: string\n msg: string\n [key: string]: unknown\n}\n\nconst LEVEL_VALUE: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n fatal: 50,\n silent: 99,\n}\n\nconst LEVEL_LABEL: Record<string, string> = {\n debug: 'DBG',\n info: 'INF',\n warn: 'WRN',\n error: 'ERR',\n fatal: 'FTL',\n}\n\nconst ANSI = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n cyan: '\\x1b[36m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n white: '\\x1b[37m',\n bgRed: '\\x1b[41m',\n} as const\n\nconst LEVEL_COLOR: Record<string, string> = {\n debug: ANSI.dim,\n info: ANSI.green,\n warn: ANSI.yellow,\n error: ANSI.red,\n fatal: `${ANSI.bgRed}${ANSI.white}${ANSI.bold}`,\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nfunction detectFormat(): 'json' | 'pretty' {\n try {\n if (typeof (globalThis as any).Deno !== 'undefined') return 'json'\n } catch { /* not Deno */ }\n\n const proc = typeof (globalThis as any).process !== 'undefined'\n ? (globalThis as any).process\n : undefined\n\n if (proc?.env) {\n if (proc.env.NODE_ENV === 'production') return 'json'\n if (proc.env.LOG_FORMAT === 'json') return 'json'\n if (proc.env.LOG_FORMAT === 'pretty') return 'pretty'\n if (proc.stdout?.isTTY) return 'pretty'\n }\n\n if (typeof (globalThis as any).window !== 'undefined') return 'pretty'\n\n return 'json'\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nfunction flattenMeta(meta: Record<string, unknown>): string {\n const parts: string[] = []\n for (const [k, v] of Object.entries(meta)) {\n if (v === undefined || v === null) continue\n if (typeof v === 'object') {\n parts.push(`${k}=${JSON.stringify(v)}`)\n } else {\n parts.push(`${k}=${String(v)}`)\n }\n }\n return parts.join(' ')\n}\n\nfunction formatPretty(entry: LogEntry): string {\n const { ts, level, scope, msg, ...rest } = entry\n const time = ts.slice(11, 23)\n const color = LEVEL_COLOR[level] ?? ''\n const label = LEVEL_LABEL[level] ?? level.toUpperCase()\n const metaStr = Object.keys(rest).length > 0 ? ` ${ANSI.dim}${flattenMeta(rest)}${ANSI.reset}` : ''\n\n return `${ANSI.dim}${time}${ANSI.reset} ${color}${label}${ANSI.reset} ${ANSI.cyan}[${scope}]${ANSI.reset} ${msg}${metaStr}`\n}\n\nfunction formatJson(entry: LogEntry): string {\n return JSON.stringify(entry)\n}\n\nfunction emit(level: LogLevel, formatted: string): void {\n switch (level) {\n case 'error':\n case 'fatal':\n console.error(formatted)\n break\n case 'warn':\n console.warn(formatted)\n break\n default:\n console.log(formatted)\n }\n}\n\nfunction buildLogger(\n scope: string,\n minLevel: LogLevel,\n baseMeta: Record<string, unknown>,\n formatter: (entry: LogEntry) => string,\n): Logger {\n let currentLevel = minLevel\n\n function log(level: LogLevel, msg: string, meta?: Record<string, unknown>): void {\n if (LEVEL_VALUE[level] < LEVEL_VALUE[currentLevel]) return\n\n const entry: LogEntry = {\n ts: new Date().toISOString(),\n level,\n scope,\n msg,\n ...baseMeta,\n ...meta,\n }\n\n emit(level, formatter(entry))\n }\n\n return {\n debug: (msg, meta?) => log('debug', msg, meta),\n info: (msg, meta?) => log('info', msg, meta),\n warn: (msg, meta?) => log('warn', msg, meta),\n error: (msg, meta?) => log('error', msg, meta),\n fatal: (msg, meta?) => log('fatal', msg, meta),\n\n child(childScope: string, childMeta?: Record<string, unknown>): Logger {\n return buildLogger(\n `${scope}:${childScope}`,\n currentLevel,\n { ...baseMeta, ...childMeta },\n formatter,\n )\n },\n\n setLevel(level: LogLevel) {\n currentLevel = level\n },\n }\n}\n\n/**\n * Create a structured logger instance.\n *\n * @example\n * const log = createLogger({ scope: 'mushi:api', level: 'info' })\n * log.info('Server started', { port: 3000 })\n *\n * const child = log.child('auth', { userId: 'u-123' })\n * child.warn('Token expired')\n */\nexport function createLogger(options: LoggerOptions): Logger {\n const {\n scope,\n level = 'info',\n meta = {},\n format = 'auto',\n } = options\n\n const resolvedFormat = format === 'auto' ? detectFormat() : format\n const formatter = resolvedFormat === 'json' ? formatJson : formatPretty\n\n return buildLogger(scope, level, meta, formatter)\n}\n\n/**\n * Noop logger that discards all output.\n * Useful when logging should be completely disabled.\n */\nexport const noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n fatal: () => {},\n child: () => noopLogger,\n setLevel: () => {},\n}\n","import type { MushiApiClient, MushiOfflineConfig, MushiReport } from './types';\nimport { createLogger } from './logger';\n\nconst queueLog = createLogger({ scope: 'mushi:queue', level: 'warn' });\n\nconst DB_NAME = 'mushi-mushi';\nconst STORE_NAME = 'offline-reports';\nconst DB_VERSION = 1;\nconst LS_KEY = 'mushi_offline_queue';\nconst BATCH_SIZE = 10;\nconst MAX_BACKOFF_MS = 60_000;\n\nexport interface OfflineQueue {\n enqueue(report: MushiReport): Promise<void>;\n flush(client: MushiApiClient): Promise<{ sent: number; failed: number }>;\n size(): Promise<number>;\n clear(): Promise<void>;\n startAutoSync(client: MushiApiClient): void;\n stopAutoSync(): void;\n}\n\ntype StorageBackend = 'indexeddb' | 'localstorage' | 'none';\n\nexport function createOfflineQueue(config: MushiOfflineConfig = {}): OfflineQueue {\n const { enabled = true, maxQueueSize = 50, syncOnReconnect = true } = config;\n\n let syncCleanup: (() => void) | null = null;\n let backendType: StorageBackend | null = null;\n\n function detectBackend(): StorageBackend {\n if (backendType) return backendType;\n if (typeof indexedDB !== 'undefined') {\n backendType = 'indexeddb';\n } else if (typeof localStorage !== 'undefined') {\n backendType = 'localstorage';\n } else {\n backendType = 'none';\n }\n return backendType;\n }\n\n // --- IndexedDB backend ---\n\n function openDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => {\n backendType = 'localstorage';\n reject(request.error);\n };\n });\n }\n\n async function idbEnqueue(report: MushiReport): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).put({ ...report, queuedAt: new Date().toISOString() });\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async function idbGetAll(): Promise<MushiReport[]> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly');\n const request = tx.objectStore(STORE_NAME).getAll();\n request.onsuccess = () => resolve(request.result as MushiReport[]);\n request.onerror = () => reject(request.error);\n });\n }\n\n async function idbDelete(id: string): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).delete(id);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async function idbSize(): Promise<number> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly');\n const request = tx.objectStore(STORE_NAME).count();\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n\n async function idbClear(): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite');\n tx.objectStore(STORE_NAME).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // --- localStorage fallback ---\n\n function lsRead(): MushiReport[] {\n try {\n const raw = localStorage.getItem(LS_KEY);\n return raw ? JSON.parse(raw) : [];\n } catch {\n return [];\n }\n }\n\n function lsWrite(reports: MushiReport[]): void {\n try {\n localStorage.setItem(LS_KEY, JSON.stringify(reports));\n } catch {\n // localStorage full or unavailable\n }\n }\n\n function lsEnqueue(report: MushiReport): void {\n const reports = lsRead();\n reports.push({ ...report, queuedAt: new Date().toISOString() } as MushiReport);\n lsWrite(reports);\n }\n\n function lsDelete(id: string): void {\n const reports = lsRead().filter((r) => r.id !== id);\n lsWrite(reports);\n }\n\n // --- Unified interface ---\n\n async function enqueue(report: MushiReport): Promise<void> {\n if (!enabled) return;\n\n const currentSize = await size();\n if (currentSize >= maxQueueSize) {\n queueLog.warn('Offline queue full — dropping report', { maxQueueSize });\n return;\n }\n\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n await idbEnqueue(report);\n return;\n } catch {\n // IndexedDB failed, fall through to localStorage\n backendType = 'localstorage';\n }\n }\n\n if (backend === 'localstorage' || backendType === 'localstorage') {\n lsEnqueue(report);\n return;\n }\n }\n\n function getBackoffDelay(attempt: number): number {\n return Math.min(1000 * 2 ** attempt + Math.random() * 500, MAX_BACKOFF_MS);\n }\n\n function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async function flush(client: MushiApiClient): Promise<{ sent: number; failed: number }> {\n if (!enabled) return { sent: 0, failed: 0 };\n\n let reports: MushiReport[];\n const backend = detectBackend();\n\n if (backend === 'indexeddb') {\n try {\n reports = await idbGetAll();\n } catch {\n reports = lsRead();\n }\n } else {\n reports = lsRead();\n }\n\n const batch = reports.slice(0, BATCH_SIZE);\n let sent = 0;\n let failed = 0;\n\n for (let i = 0; i < batch.length; i++) {\n const report = batch[i];\n const result = await client.submitReport(report);\n\n if (result.ok) {\n try {\n if (backend === 'indexeddb') await idbDelete(report.id);\n else lsDelete(report.id);\n } catch {\n lsDelete(report.id);\n }\n sent++;\n } else {\n failed++;\n if (i < batch.length - 1) {\n await sleep(getBackoffDelay(i));\n }\n }\n }\n\n return { sent, failed };\n }\n\n async function size(): Promise<number> {\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n return await idbSize();\n } catch {\n return lsRead().length;\n }\n }\n return lsRead().length;\n }\n\n async function clear(): Promise<void> {\n const backend = detectBackend();\n if (backend === 'indexeddb') {\n try {\n await idbClear();\n } catch {\n // fall through\n }\n }\n try {\n localStorage.removeItem(LS_KEY);\n } catch {\n // unavailable\n }\n }\n\n function startAutoSync(client: MushiApiClient): void {\n if (!enabled || !syncOnReconnect || typeof window === 'undefined') return;\n\n const handler = () => {\n if (navigator.onLine) {\n flush(client).catch(() => {});\n }\n };\n\n window.addEventListener('online', handler);\n syncCleanup = () => window.removeEventListener('online', handler);\n }\n\n function stopAutoSync(): void {\n syncCleanup?.();\n syncCleanup = null;\n }\n\n return { enqueue, flush, size, clear, startAutoSync, stopAutoSync };\n}\n","import type { MushiEnvironment } from './types';\n\nexport function captureEnvironment(): MushiEnvironment {\n const nav = typeof navigator !== 'undefined' ? navigator : undefined;\n const win = typeof window !== 'undefined' ? window : undefined;\n const doc = typeof document !== 'undefined' ? document : undefined;\n\n const connection = nav && 'connection' in nav ? (nav as NavigatorWithConnection).connection : undefined;\n\n return {\n userAgent: nav?.userAgent ?? 'unknown',\n platform: nav?.platform ?? 'unknown',\n language: nav?.language ?? 'en',\n viewport: {\n width: win?.innerWidth ?? 0,\n height: win?.innerHeight ?? 0,\n },\n url: win?.location?.href ?? '',\n referrer: doc?.referrer ?? '',\n timestamp: new Date().toISOString(),\n timezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? 'UTC',\n connection: connection\n ? {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n }\n : undefined,\n deviceMemory: (nav as NavigatorWithDeviceMemory)?.deviceMemory,\n hardwareConcurrency: nav?.hardwareConcurrency,\n };\n}\n\ninterface NetworkInformation {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n}\n\ninterface NavigatorWithConnection extends Navigator {\n connection?: NetworkInformation;\n}\n\ninterface NavigatorWithDeviceMemory extends Navigator {\n deviceMemory?: number;\n}\n","const STORAGE_KEY = 'mushi_reporter_token';\n\nexport function getReporterToken(): string {\n if (typeof localStorage !== 'undefined') {\n const existing = localStorage.getItem(STORAGE_KEY);\n if (existing) return existing;\n }\n\n const token = generateToken();\n\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(STORAGE_KEY, token);\n } catch {\n // localStorage full or unavailable — token is ephemeral\n }\n }\n\n return token;\n}\n\nfunction generateToken(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return `mushi_${crypto.randomUUID()}`;\n }\n\n const bytes = new Uint8Array(16);\n if (typeof crypto !== 'undefined') {\n crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `mushi_${hex}`;\n}\n","const SESSION_KEY = 'mushi_session_id';\n\nlet cachedSessionId: string | null = null;\n\nexport function getSessionId(): string {\n if (cachedSessionId) return cachedSessionId;\n\n if (typeof sessionStorage !== 'undefined') {\n const existing = sessionStorage.getItem(SESSION_KEY);\n if (existing) {\n cachedSessionId = existing;\n return existing;\n }\n }\n\n const id = generateSessionId();\n cachedSessionId = id;\n\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(SESSION_KEY, id);\n } catch {\n // sessionStorage unavailable\n }\n }\n\n return id;\n}\n\nfunction generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).slice(2, 8);\n return `ms_${timestamp}_${random}`;\n}\n","export interface RateLimiterConfig {\n maxBurst?: number;\n refillRate?: number;\n refillIntervalMs?: number;\n}\n\nexport interface RateLimiter {\n tryConsume(): boolean;\n reset(): void;\n availableTokens(): number;\n}\n\nconst DEFAULT_MAX_BURST = 10;\nconst DEFAULT_REFILL_RATE = 1;\nconst DEFAULT_REFILL_INTERVAL_MS = 5_000;\n\nexport function createRateLimiter(config: RateLimiterConfig = {}): RateLimiter {\n const {\n maxBurst = DEFAULT_MAX_BURST,\n refillRate = DEFAULT_REFILL_RATE,\n refillIntervalMs = DEFAULT_REFILL_INTERVAL_MS,\n } = config;\n\n let tokens = maxBurst;\n let lastRefill = Date.now();\n\n function refill() {\n const now = Date.now();\n const elapsed = now - lastRefill;\n const refills = Math.floor(elapsed / refillIntervalMs);\n if (refills > 0) {\n tokens = Math.min(maxBurst, tokens + refills * refillRate);\n lastRefill = now;\n }\n }\n\n function tryConsume(): boolean {\n refill();\n if (tokens > 0) {\n tokens--;\n return true;\n }\n return false;\n }\n\n function reset(): void {\n tokens = maxBurst;\n lastRefill = Date.now();\n }\n\n function availableTokens(): number {\n refill();\n return tokens;\n }\n\n return { tryConsume, reset, availableTokens };\n}\n","export interface PiiScrubberConfig {\n emails?: boolean;\n phones?: boolean;\n creditCards?: boolean;\n ssns?: boolean;\n ipAddresses?: boolean;\n}\n\ninterface PiiPattern {\n key: keyof PiiScrubberConfig;\n regex: RegExp;\n replacement: string;\n}\n\n// Order matters: SSN → CC → email → phone → IP\n// CC must run before phone to prevent phone regex from partially matching CC sequences\nconst ORDERED_PATTERNS: PiiPattern[] = [\n { key: 'ssns', regex: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g, replacement: '[REDACTED_SSN]' },\n { key: 'creditCards', regex: /\\b(?:\\d[ -]*){12,18}\\d\\b/g, replacement: '[REDACTED_CC]' },\n { key: 'emails', regex: /\\b[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}\\b/g, replacement: '[REDACTED_EMAIL]' },\n { key: 'phones', regex: /(?:\\+\\d{1,3}[\\s.-])?\\(?\\d{2,4}\\)?[\\s.-]\\d{3,4}[\\s.-]\\d{3,4}\\b/g, replacement: '[REDACTED_PHONE]' },\n { key: 'ipAddresses', regex: /\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g, replacement: '[REDACTED_IP]' },\n];\n\nconst DEFAULT_CONFIG: PiiScrubberConfig = {\n emails: true,\n phones: true,\n creditCards: true,\n ssns: true,\n ipAddresses: false,\n};\n\nexport function createPiiScrubber(config: PiiScrubberConfig = {}) {\n const merged = { ...DEFAULT_CONFIG, ...config };\n\n const activePatterns = ORDERED_PATTERNS.filter((p) => merged[p.key]);\n\n function scrub(text: string): string {\n if (!text) return text;\n let result = text;\n for (const { regex, replacement } of activePatterns) {\n result = result.replace(new RegExp(regex.source, regex.flags), replacement);\n }\n return result;\n }\n\n function scrubObject<T extends Record<string, unknown>>(obj: T, keys: string[]): T {\n const copy = { ...obj };\n for (const key of keys) {\n if (typeof copy[key] === 'string') {\n (copy as Record<string, unknown>)[key] = scrub(copy[key] as string);\n }\n }\n return copy;\n }\n\n return { scrub, scrubObject };\n}\n\nexport function scrubPii(text: string, config?: PiiScrubberConfig): string {\n return createPiiScrubber(config).scrub(text);\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
interface MushiConfig {
|
|
2
|
+
projectId: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
apiEndpoint?: string;
|
|
5
|
+
sentry?: MushiSentryConfig;
|
|
6
|
+
widget?: MushiWidgetConfig;
|
|
7
|
+
capture?: MushiCaptureConfig;
|
|
8
|
+
proactive?: MushiProactiveConfig;
|
|
9
|
+
preFilter?: MushiPreFilterConfig;
|
|
10
|
+
integrations?: MushiIntegrationsConfig;
|
|
11
|
+
offline?: MushiOfflineConfig;
|
|
12
|
+
rewards?: MushiRewardsConfig;
|
|
13
|
+
debug?: boolean;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface MushiSentryConfig {
|
|
17
|
+
dsn?: string;
|
|
18
|
+
consumeUserFeedback?: boolean;
|
|
19
|
+
enrichWithSeer?: boolean;
|
|
20
|
+
useReplay?: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface MushiWidgetConfig {
|
|
23
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
24
|
+
theme?: 'auto' | 'light' | 'dark';
|
|
25
|
+
triggerText?: string;
|
|
26
|
+
expandedTitle?: string;
|
|
27
|
+
mode?: 'simple' | 'conversational';
|
|
28
|
+
locale?: string;
|
|
29
|
+
zIndex?: number;
|
|
30
|
+
}
|
|
31
|
+
interface MushiCaptureConfig {
|
|
32
|
+
console?: boolean;
|
|
33
|
+
network?: boolean;
|
|
34
|
+
performance?: boolean;
|
|
35
|
+
screenshot?: 'on-report' | 'auto' | 'off';
|
|
36
|
+
elementSelector?: boolean;
|
|
37
|
+
replay?: 'sentry' | 'rrweb' | 'lite' | 'off';
|
|
38
|
+
}
|
|
39
|
+
interface MushiProactiveConfig {
|
|
40
|
+
rageClick?: boolean;
|
|
41
|
+
errorBoundary?: boolean;
|
|
42
|
+
longTask?: boolean;
|
|
43
|
+
apiCascade?: boolean;
|
|
44
|
+
cooldown?: MushiCooldownConfig;
|
|
45
|
+
}
|
|
46
|
+
interface MushiCooldownConfig {
|
|
47
|
+
maxProactivePerSession?: number;
|
|
48
|
+
dismissCooldownHours?: number;
|
|
49
|
+
suppressAfterDismissals?: number;
|
|
50
|
+
}
|
|
51
|
+
interface MushiPreFilterConfig {
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
blockObviousSpam?: boolean;
|
|
54
|
+
minDescriptionLength?: number;
|
|
55
|
+
maxDescriptionLength?: number;
|
|
56
|
+
}
|
|
57
|
+
interface MushiIntegrationsConfig {
|
|
58
|
+
opentelemetry?: {
|
|
59
|
+
traceContext?: boolean;
|
|
60
|
+
};
|
|
61
|
+
vercel?: {
|
|
62
|
+
analyticsId?: string;
|
|
63
|
+
};
|
|
64
|
+
custom?: (report: MushiReportBuilder) => void;
|
|
65
|
+
}
|
|
66
|
+
interface MushiOfflineConfig {
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
maxQueueSize?: number;
|
|
69
|
+
syncOnReconnect?: boolean;
|
|
70
|
+
}
|
|
71
|
+
interface MushiRewardsConfig {
|
|
72
|
+
enabled?: boolean;
|
|
73
|
+
requireAuth?: boolean;
|
|
74
|
+
showNotifications?: boolean;
|
|
75
|
+
webhookOnReward?: string;
|
|
76
|
+
}
|
|
77
|
+
type MushiReportCategory = 'bug' | 'slow' | 'visual' | 'confusing' | 'other';
|
|
78
|
+
type MushiReportStatus = 'pending' | 'submitted' | 'classified' | 'grouped' | 'fixing' | 'fixed' | 'dismissed';
|
|
79
|
+
interface MushiReport {
|
|
80
|
+
id: string;
|
|
81
|
+
projectId: string;
|
|
82
|
+
category: MushiReportCategory;
|
|
83
|
+
description: string;
|
|
84
|
+
userIntent?: string;
|
|
85
|
+
environment: MushiEnvironment;
|
|
86
|
+
consoleLogs?: MushiConsoleEntry[];
|
|
87
|
+
networkLogs?: MushiNetworkEntry[];
|
|
88
|
+
performanceMetrics?: MushiPerformanceMetrics;
|
|
89
|
+
screenshotDataUrl?: string;
|
|
90
|
+
selectedElement?: MushiSelectedElement;
|
|
91
|
+
metadata?: Record<string, unknown>;
|
|
92
|
+
sessionId?: string;
|
|
93
|
+
reporterToken: string;
|
|
94
|
+
appVersion?: string;
|
|
95
|
+
proactiveTrigger?: string;
|
|
96
|
+
sentryEventId?: string;
|
|
97
|
+
sentryReplayId?: string;
|
|
98
|
+
queuedAt?: string;
|
|
99
|
+
createdAt: string;
|
|
100
|
+
}
|
|
101
|
+
interface MushiReportBuilder {
|
|
102
|
+
addMetadata(key: string, value: unknown): void;
|
|
103
|
+
setCategory(category: MushiReportCategory): void;
|
|
104
|
+
setDescription(description: string): void;
|
|
105
|
+
}
|
|
106
|
+
interface MushiEnvironment {
|
|
107
|
+
userAgent: string;
|
|
108
|
+
platform: string;
|
|
109
|
+
language: string;
|
|
110
|
+
viewport: {
|
|
111
|
+
width: number;
|
|
112
|
+
height: number;
|
|
113
|
+
};
|
|
114
|
+
url: string;
|
|
115
|
+
referrer: string;
|
|
116
|
+
timestamp: string;
|
|
117
|
+
timezone: string;
|
|
118
|
+
connection?: {
|
|
119
|
+
effectiveType?: string;
|
|
120
|
+
downlink?: number;
|
|
121
|
+
rtt?: number;
|
|
122
|
+
};
|
|
123
|
+
deviceMemory?: number;
|
|
124
|
+
hardwareConcurrency?: number;
|
|
125
|
+
}
|
|
126
|
+
interface MushiConsoleEntry {
|
|
127
|
+
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
128
|
+
message: string;
|
|
129
|
+
timestamp: number;
|
|
130
|
+
stack?: string;
|
|
131
|
+
}
|
|
132
|
+
interface MushiNetworkEntry {
|
|
133
|
+
method: string;
|
|
134
|
+
url: string;
|
|
135
|
+
status: number;
|
|
136
|
+
duration: number;
|
|
137
|
+
timestamp: number;
|
|
138
|
+
requestHeaders?: Record<string, string>;
|
|
139
|
+
responseHeaders?: Record<string, string>;
|
|
140
|
+
error?: string;
|
|
141
|
+
}
|
|
142
|
+
interface MushiPerformanceMetrics {
|
|
143
|
+
fcp?: number;
|
|
144
|
+
lcp?: number;
|
|
145
|
+
cls?: number;
|
|
146
|
+
fid?: number;
|
|
147
|
+
inp?: number;
|
|
148
|
+
ttfb?: number;
|
|
149
|
+
longTasks?: number;
|
|
150
|
+
}
|
|
151
|
+
interface MushiSelectedElement {
|
|
152
|
+
tagName: string;
|
|
153
|
+
id?: string;
|
|
154
|
+
className?: string;
|
|
155
|
+
textContent?: string;
|
|
156
|
+
xpath?: string;
|
|
157
|
+
rect?: {
|
|
158
|
+
x: number;
|
|
159
|
+
y: number;
|
|
160
|
+
width: number;
|
|
161
|
+
height: number;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
type MushiEventType = 'report:submitted' | 'report:queued' | 'report:sent' | 'report:failed' | 'widget:opened' | 'widget:closed' | 'proactive:triggered' | 'proactive:dismissed';
|
|
165
|
+
type MushiEventHandler = (event: {
|
|
166
|
+
type: MushiEventType;
|
|
167
|
+
data?: unknown;
|
|
168
|
+
}) => void;
|
|
169
|
+
interface MushiSDKInstance {
|
|
170
|
+
report(options?: {
|
|
171
|
+
category?: MushiReportCategory;
|
|
172
|
+
}): void;
|
|
173
|
+
on(event: MushiEventType, handler: MushiEventHandler): () => void;
|
|
174
|
+
setUser(user: {
|
|
175
|
+
id: string;
|
|
176
|
+
email?: string;
|
|
177
|
+
name?: string;
|
|
178
|
+
}): void;
|
|
179
|
+
setMetadata(key: string, value: unknown): void;
|
|
180
|
+
isOpen(): boolean;
|
|
181
|
+
open(): void;
|
|
182
|
+
close(): void;
|
|
183
|
+
destroy(): void;
|
|
184
|
+
}
|
|
185
|
+
interface MushiApiClient {
|
|
186
|
+
submitReport(report: MushiReport): Promise<MushiApiResponse<{
|
|
187
|
+
reportId: string;
|
|
188
|
+
}>>;
|
|
189
|
+
getReportStatus(reportId: string): Promise<MushiApiResponse<{
|
|
190
|
+
status: MushiReportStatus;
|
|
191
|
+
}>>;
|
|
192
|
+
}
|
|
193
|
+
interface MushiApiResponse<T> {
|
|
194
|
+
ok: boolean;
|
|
195
|
+
data?: T;
|
|
196
|
+
error?: {
|
|
197
|
+
code: string;
|
|
198
|
+
message: string;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
interface ApiClientOptions {
|
|
203
|
+
projectId: string;
|
|
204
|
+
apiKey: string;
|
|
205
|
+
apiEndpoint: string;
|
|
206
|
+
timeout?: number;
|
|
207
|
+
maxRetries?: number;
|
|
208
|
+
}
|
|
209
|
+
declare function createApiClient(options: ApiClientOptions): MushiApiClient;
|
|
210
|
+
|
|
211
|
+
interface PreFilterResult {
|
|
212
|
+
passed: boolean;
|
|
213
|
+
reason?: string;
|
|
214
|
+
}
|
|
215
|
+
declare function createPreFilter(config?: MushiPreFilterConfig): {
|
|
216
|
+
check: (description: string) => PreFilterResult;
|
|
217
|
+
truncate: (description: string) => string;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
interface OfflineQueue {
|
|
221
|
+
enqueue(report: MushiReport): Promise<void>;
|
|
222
|
+
flush(client: MushiApiClient): Promise<{
|
|
223
|
+
sent: number;
|
|
224
|
+
failed: number;
|
|
225
|
+
}>;
|
|
226
|
+
size(): Promise<number>;
|
|
227
|
+
clear(): Promise<void>;
|
|
228
|
+
startAutoSync(client: MushiApiClient): void;
|
|
229
|
+
stopAutoSync(): void;
|
|
230
|
+
}
|
|
231
|
+
declare function createOfflineQueue(config?: MushiOfflineConfig): OfflineQueue;
|
|
232
|
+
|
|
233
|
+
declare function captureEnvironment(): MushiEnvironment;
|
|
234
|
+
|
|
235
|
+
declare function getReporterToken(): string;
|
|
236
|
+
|
|
237
|
+
declare function getSessionId(): string;
|
|
238
|
+
|
|
239
|
+
interface RateLimiterConfig {
|
|
240
|
+
maxBurst?: number;
|
|
241
|
+
refillRate?: number;
|
|
242
|
+
refillIntervalMs?: number;
|
|
243
|
+
}
|
|
244
|
+
interface RateLimiter {
|
|
245
|
+
tryConsume(): boolean;
|
|
246
|
+
reset(): void;
|
|
247
|
+
availableTokens(): number;
|
|
248
|
+
}
|
|
249
|
+
declare function createRateLimiter(config?: RateLimiterConfig): RateLimiter;
|
|
250
|
+
|
|
251
|
+
interface PiiScrubberConfig {
|
|
252
|
+
emails?: boolean;
|
|
253
|
+
phones?: boolean;
|
|
254
|
+
creditCards?: boolean;
|
|
255
|
+
ssns?: boolean;
|
|
256
|
+
ipAddresses?: boolean;
|
|
257
|
+
}
|
|
258
|
+
declare function createPiiScrubber(config?: PiiScrubberConfig): {
|
|
259
|
+
scrub: (text: string) => string;
|
|
260
|
+
scrubObject: <T extends Record<string, unknown>>(obj: T, keys: string[]) => T;
|
|
261
|
+
};
|
|
262
|
+
declare function scrubPii(text: string, config?: PiiScrubberConfig): string;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* FILE: logger.ts
|
|
266
|
+
* PURPOSE: Zero-dependency structured logger for the mushi-mushi SDK ecosystem.
|
|
267
|
+
*
|
|
268
|
+
* OVERVIEW:
|
|
269
|
+
* - Production-grade logging with levels, scoped namespaces, and child loggers
|
|
270
|
+
* - JSON output for server/production, pretty-formatted output for development
|
|
271
|
+
* - Automatic environment detection (browser vs Node vs Deno)
|
|
272
|
+
* - Structured metadata on every log entry
|
|
273
|
+
* - No external dependencies — safe to ship in any SDK bundle
|
|
274
|
+
*
|
|
275
|
+
* USAGE:
|
|
276
|
+
* import { createLogger } from '@mushi-mushi/core'
|
|
277
|
+
* const log = createLogger({ scope: 'mushi:api' })
|
|
278
|
+
* log.info('Request received', { method: 'POST', path: '/v1/reports' })
|
|
279
|
+
* const child = log.child('ingest', { reportId: 'abc' })
|
|
280
|
+
* child.warn('Slow query', { latencyMs: 420 })
|
|
281
|
+
*
|
|
282
|
+
* TECHNICAL DETAILS:
|
|
283
|
+
* - Log levels: debug(10) < info(20) < warn(30) < error(40) < fatal(50) < silent(99)
|
|
284
|
+
* - Format auto-detected: JSON in production/server, pretty in development
|
|
285
|
+
* - Pretty format uses ANSI colors when supported (Node/Deno TTY)
|
|
286
|
+
* - Child loggers inherit parent scope + metadata, can override level
|
|
287
|
+
* - Timestamps are ISO 8601 with millisecond precision
|
|
288
|
+
*/
|
|
289
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent';
|
|
290
|
+
type LogFormat = 'json' | 'pretty' | 'auto';
|
|
291
|
+
interface LoggerOptions {
|
|
292
|
+
scope: string;
|
|
293
|
+
level?: LogLevel;
|
|
294
|
+
meta?: Record<string, unknown>;
|
|
295
|
+
format?: LogFormat;
|
|
296
|
+
}
|
|
297
|
+
interface Logger {
|
|
298
|
+
debug(msg: string, meta?: Record<string, unknown>): void;
|
|
299
|
+
info(msg: string, meta?: Record<string, unknown>): void;
|
|
300
|
+
warn(msg: string, meta?: Record<string, unknown>): void;
|
|
301
|
+
error(msg: string, meta?: Record<string, unknown>): void;
|
|
302
|
+
fatal(msg: string, meta?: Record<string, unknown>): void;
|
|
303
|
+
child(scope: string, meta?: Record<string, unknown>): Logger;
|
|
304
|
+
setLevel(level: LogLevel): void;
|
|
305
|
+
}
|
|
306
|
+
interface LogEntry {
|
|
307
|
+
ts: string;
|
|
308
|
+
level: LogLevel;
|
|
309
|
+
scope: string;
|
|
310
|
+
msg: string;
|
|
311
|
+
[key: string]: unknown;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Create a structured logger instance.
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* const log = createLogger({ scope: 'mushi:api', level: 'info' })
|
|
318
|
+
* log.info('Server started', { port: 3000 })
|
|
319
|
+
*
|
|
320
|
+
* const child = log.child('auth', { userId: 'u-123' })
|
|
321
|
+
* child.warn('Token expired')
|
|
322
|
+
*/
|
|
323
|
+
declare function createLogger(options: LoggerOptions): Logger;
|
|
324
|
+
/**
|
|
325
|
+
* Noop logger that discards all output.
|
|
326
|
+
* Useful when logging should be completely disabled.
|
|
327
|
+
*/
|
|
328
|
+
declare const noopLogger: Logger;
|
|
329
|
+
|
|
330
|
+
export { type ApiClientOptions, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, type MushiApiClient, type MushiApiResponse, type MushiCaptureConfig, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiNetworkEntry, type MushiOfflineConfig, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiProactiveConfig, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiRewardsConfig, type MushiSDKInstance, type MushiSelectedElement, type MushiSentryConfig, type MushiWidgetConfig, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getReporterToken, getSessionId, noopLogger, scrubPii };
|