{"_id":"@dysonic/web-replay-core","_rev":"2-9a60bc5aed09715645112a44e4cf314c","name":"@dysonic/web-replay-core","dist-tags":{"beta":"0.1.0-beta.0","latest":"0.1.0"},"versions":{"0.1.0-beta.0":{"name":"@dysonic/web-replay-core","version":"0.1.0-beta.0","license":"MIT","_id":"@dysonic/web-replay-core@0.1.0-beta.0","maintainers":[{"name":"yuanhongboo","email":"yuanhongboo@gmail.com"}],"dist":{"shasum":"c1a6bcf6d7f1bb20ecfaeb74c89be9ded8edada2","tarball":"https://registry.npmjs.org/@dysonic/web-replay-core/-/web-replay-core-0.1.0-beta.0.tgz","fileCount":5,"integrity":"sha512-ut2+132HwNNmSVdj+I2v27Z8/5l/7zLUvZ1QVyQSiejAFZEphNLBEN9loj51ubo9Qm54F9A7j6anzzJ1DKVy6w==","signatures":[{"sig":"MEYCIQD4bz3Quy1CotGEFrOdRccTeE/IG7JdNqi90Vh8ugZuIwIhALx5wEF3AmZ8J4uoyucAj7OUhgu31MKYXjtPEbkc+UgC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15793},"main":"dist/index.cjs.js","_from":"file:dysonic-web-replay-core-0.1.0-beta.0.tgz","types":"dist/index.d.ts","module":"dist/index.esm.js","scripts":{"test":"ts-node-script ../../tools/scripts/test.ts --verbose --color","build":"npm run build:cjs && npm run build:esm","clean":"rimraf dist && rimraf coverage","prebuild":"rimraf dist","build:cjs":"ts-node-script ../../tools/scripts/build.ts --mode cjs","build:esm":"ts-node-script ../../tools/scripts/build.ts --mode esm","test:coverage":"ts-node-script ../../tools/scripts/test.ts --coverage"},"_npmUser":{"name":"yuanhongboo","email":"yuanhongboo@gmail.com"},"_resolved":"/private/var/folders/81/zd5db0kd52j_qlwm_kvz2zzc0000gn/T/fa07a265150ae1ea2e1822b58c3c6dc9/dysonic-web-replay-core-0.1.0-beta.0.tgz","_integrity":"sha512-ut2+132HwNNmSVdj+I2v27Z8/5l/7zLUvZ1QVyQSiejAFZEphNLBEN9loj51ubo9Qm54F9A7j6anzzJ1DKVy6w==","_npmVersion":"10.8.2","description":"Shared core primitives for web replay capture and export","directories":{},"sideEffects":false,"_nodeVersion":"18.20.8","publishConfig":{"registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/web-replay-core_0.1.0-beta.0_1773427488904_0.8384676785773388","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@dysonic/web-replay-core","version":"0.1.0","description":"Shared core primitives for web replay capture and export","license":"MIT","main":"dist/index.cjs.js","module":"dist/index.esm.js","types":"dist/index.d.ts","sideEffects":false,"publishConfig":{"registry":"https://registry.npmjs.org"},"scripts":{"build":"npm run build:cjs && npm run build:esm","build:cjs":"ts-node-script ../../tools/scripts/build.ts --mode cjs","build:esm":"ts-node-script ../../tools/scripts/build.ts --mode esm","test":"ts-node-script ../../tools/scripts/test.ts --verbose --color","test:coverage":"ts-node-script ../../tools/scripts/test.ts --coverage","clean":"rimraf dist && rimraf coverage","prebuild":"rimraf dist"},"_id":"@dysonic/web-replay-core@0.1.0","_integrity":"sha512-m5+wh5iOlo0zPvI1AhFhv9VhmmVTW90SyjX6xSbc+kVxaNG4XP1aZ4viWA8/C7ZqHHIG7k0DLKdIYROwY5KpDg==","_resolved":"/tmp/dd7d447f63074589058cd3a99f5955ad/dysonic-web-replay-core-0.1.0.tgz","_from":"file:dysonic-web-replay-core-0.1.0.tgz","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-m5+wh5iOlo0zPvI1AhFhv9VhmmVTW90SyjX6xSbc+kVxaNG4XP1aZ4viWA8/C7ZqHHIG7k0DLKdIYROwY5KpDg==","shasum":"89cb7956d2907fde829e3f54a2b21a0979b99859","tarball":"https://registry.npmjs.org/@dysonic/web-replay-core/-/web-replay-core-0.1.0.tgz","fileCount":5,"unpackedSize":15786,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDiaWJkeZEWO4N2x7VGs+Np4wDpSod5edzRsORWKKRd7QIgSmqfSQ4uOoMn4EmzWBWyt28X3uTskN9yO0IGXARnAu0="}]},"_npmUser":{"name":"yuanhongboo","email":"yuanhongboo@gmail.com"},"directories":{},"maintainers":[{"name":"yuanhongboo","email":"yuanhongboo@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/web-replay-core_0.1.0_1773430617850_0.7905896799315268"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-13T18:44:48.785Z","modified":"2026-03-13T19:36:58.157Z","0.1.0-beta.0":"2026-03-13T18:44:49.055Z","0.1.0":"2026-03-13T19:36:58.002Z"},"license":"MIT","description":"Shared core primitives for web replay capture and export","maintainers":[{"name":"yuanhongboo","email":"yuanhongboo@gmail.com"}],"readme":"# @dysonic/web-replay-core\n\nShared core primitives for the web-replay monorepo. Provides recording lifecycle management, circular event buffering, and privacy masking utilities that all other packages build on.\n\n## Installation\n\n```bash\nnpm install @dysonic/web-replay-core\n```\n\n## Core Concepts\n\n### RecorderCore\n\nThe central orchestrator. It wires together a `RecorderAdapter` (the event source) and a `SessionBuffer` (the ring buffer), and tracks session metadata.\n\n```typescript\nimport { RecorderCore } from '@dysonic/web-replay-core';\n\nconst recorder = new RecorderCore(\n  {\n    source: 'pc-sdk',       // 'extension' | 'h5-sdk' | 'pc-sdk'\n    maxMinutes: 5,          // keep up to 5 minutes of events (max 10)\n    maxBytes: 5 * 1024 * 1024, // keep up to 5 MB of events\n    maskRules: [],          // optional CSS-selector-based masking rules\n  },\n  // optional context overrides:\n  {\n    getPageUrl: () => window.location.href,\n    getPageTitle: () => document.title,\n    getUserAgent: () => navigator.userAgent,\n    getViewport: () => ({ width: window.innerWidth, height: window.innerHeight }),\n    getSessionId: () => 'my-custom-id',\n  },\n);\n```\n\n#### Lifecycle\n\n```typescript\nrecorder.start(adapter);          // begin recording; adapter supplies events\nrecorder.pause();                 // stop buffering events (adapter stays active)\nrecorder.resume();                // resume buffering\nrecorder.stop();                  // tear down adapter; buffer is retained\nrecorder.clear();                 // discard buffered events\nconst envelope = recorder.flush(); // export a ReplayEnvelope snapshot\nrecorder.getState();              // { active: boolean, paused: boolean }\n```\n\n#### Custom events\n\n```typescript\nrecorder.addCustomEvent('error', { message: 'Something broke', lineno: 42 });\nrecorder.addCustomEvent('network', { url: '/api/data', status: 200, durationMs: 120 });\nrecorder.addCustomEvent('route', { action: 'pushState', url: '/new-page' });\nrecorder.addCustomEvent('lifecycle', { visibility: 'hidden' });\n```\n\n### RecorderAdapter\n\nThe interface that bridges an event source (e.g. rrweb) to `RecorderCore`. Implement `start` and return a cleanup function.\n\n```typescript\nimport { RecorderAdapter } from '@dysonic/web-replay-core';\n\nconst myAdapter: RecorderAdapter<MyEvent> = {\n  start(emit) {\n    const unsubscribe = myEventSource.on('event', (e) => emit(e));\n    return unsubscribe; // called by recorder.stop()\n  },\n};\n```\n\n### RingBuffer / SessionBuffer\n\n`RingBuffer<TEvent>` is the underlying time- and size-bounded circular buffer. `SessionBuffer` wraps two `RingBuffer` instances — one for rrweb events and one for custom events — and provides the `export()` method that produces a `ReplayEnvelope`.\n\n```typescript\nimport { RingBuffer, SessionBuffer } from '@dysonic/web-replay-core';\n\nconst buf = new RingBuffer<MyEvent>({ maxMinutes: 5, maxBytes: 5_242_880 });\nbuf.push({ timestamp: Date.now(), sizeEstimate: 256, event: myEvent });\nbuf.list();     // events within the configured window\nbuf.snapshot(); // { records, totalBytes }\nbuf.clear();\n```\n\n### ReplayEnvelope\n\nThe exported data format. Produced by `recorder.flush()` or `sessionBuffer.export()`.\n\n```typescript\ninterface ReplayEnvelope<TEvent> {\n  format: string;          // 'web-replay-debugger'\n  schemaVersion: string;   // '1.0.0'\n  meta: SessionMeta;\n  rrwebEvents: TEvent[];\n  customEvents: CustomEvent[];\n  exportedAt: number;      // Unix ms timestamp\n}\n```\n\n### Privacy utilities\n\n```typescript\nimport { shouldMaskField, maskText, maskValue } from '@dysonic/web-replay-core';\n\nshouldMaskField('password');   // true — matches built-in sensitive pattern\nmaskText('secret123');         // '***'\nmaskValue('phone', '13800000000', maskRules, '#login-form input');\n```\n\nBuilt-in sensitive field pattern matches: `password`, `passwd`, `pwd`, `phone`, `mobile`, `idcard`, `identity`, `token`.\n\n## Configuration defaults\n\n| Option | Default | Max |\n|---|---|---|\n| `maxMinutes` | `5` | `10` |\n| `maxBytes` | `5 MB` | — |\n| Mask replacement | `'***'` | — |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}