{"_id":"@dstny/faro-instrumentation-replay","name":"@dstny/faro-instrumentation-replay","dist-tags":{"latest":"2.8.1-dstny.4"},"versions":{"2.8.1-dstny.4":{"name":"@dstny/faro-instrumentation-replay","packageManager":"yarn@4.17.0","version":"2.8.1-dstny.4","description":"Faro instrumentation for session replay with rrweb","keywords":["observability","apm","rum","dem","session-replay","@grafana/rrweb","browser"],"license":"Apache-2.0","author":{"name":"Grafana Labs"},"homepage":"https://github.com/grafana/faro-web-sdk","repository":{"type":"git","url":"git+https://github.com/grafana/faro-web-sdk.git","directory":"experimental/instrumentation-replay"},"main":"./dist/cjs/index.js","module":"./dist/esm/index.js","types":"./dist/types/index.d.ts","scripts":{"start":"yarn watch","build":"run-s 'build:*'","build:compile":"run-p 'build:compile:*'","build:compile:cjs":"tsc --build tsconfig.cjs.json","build:compile:esm":"tsc --build tsconfig.esm.json","build:compile:bundle":"run-s 'build:compile:bundle:*'","build:compile:bundle:create":"rollup -c ./rollup.config.js","build:compile:bundle:remove-extras":"rimraf dist/bundle/dist","watch":"run-s watch:compile","watch:compile":"yarn build:compile:cjs -w","clean":"rimraf dist/ yarn-error.log","quality":"run-s 'quality:*'","quality:test":"jest","quality:format":"prettier --cache --cache-location=../../.cache/prettier/webSessionReplay --ignore-path ../../.prettierignore -w \"./**/*.{js,jsx,ts,tsx,css,scss,md,yaml,yml,json}\"","quality:lint":"run-s quality:lint:eslint quality:lint:prettier quality:lint:md","quality:lint:eslint":"eslint --cache --cache-location ../../.cache/eslint/webSessionReplay \"./**/*.{js,jsx,ts,tsx}\"","quality:lint:prettier":"prettier --cache --cache-location=../../.cache/prettier/webSessionReplay --ignore-path ../../.prettierignore -c \"./**/*.{js,jsx,ts,tsx,css,scss,md,yaml,yml,json}\"","quality:lint:md":"markdownlint README.md","quality:lint:fix":"run-s 'quality:lint:fix:*'","quality:lint:fix:eslint":"eslint --fix --cache --cache-location ../../.cache/eslint/webSessionReplay \"./**/*.{js,jsx,ts,tsx}\"","quality:lint:fix:prettier":"prettier --cache --cache-location=../../.cache/prettier/webSessionReplay --ignore-path ../../.prettierignore -w \"./**/*.{js,jsx,ts,tsx,css,scss,md,yaml,yml,json}\"","quality:circular-deps":"madge --circular ."},"dependencies":{"@dstny/faro-core":"^2.8.1-dstny.4","@grafana/rrweb":"2.0.0-grafana.2","@grafana/rrweb-types":"2.0.0-grafana.2"},"publishConfig":{"access":"public"},"gitHead":"8c05bded54d03038c1da901f957cce1f7021dd5e","_id":"@dstny/faro-instrumentation-replay@2.8.1-dstny.4","bugs":{"url":"https://github.com/grafana/faro-web-sdk/issues"},"_nodeVersion":"22.12.0","_npmVersion":"lerna/9.0.7/node@v22.12.0+x64 (linux)","dist":{"integrity":"sha512-IpzS1wT6QSzRaT9PXg+XxRVUzFAw+7pq71Nue21amDAx7mEWZwc2rIFlb7uSrWkz/Wy5quIbzjkqq9aTNfxmjA==","shasum":"e4a64e53c93ca606ad51dd73a505aef910aa5603","tarball":"https://registry.npmjs.org/@dstny/faro-instrumentation-replay/-/faro-instrumentation-replay-2.8.1-dstny.4.tgz","fileCount":3,"unpackedSize":22544,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDYBrMB71NK16CIWxH6bZf7JhaHUE2oB6iZMgKgsvYmKAiEAysOldcflKTaEbYoLPgEHp/+LrS9qGm92mxiG/DYIamA="}]},"_npmUser":{"name":"gbo.dstny","email":"gerik.bonaert@dstny.com"},"directories":{},"maintainers":[{"name":"made.dstny","email":"maxime.destreel@dstny.com"},{"name":"gbo.dstny","email":"gerik.bonaert@dstny.com"},{"name":"kilinccagatay","email":"cagatay.kilinc@destiny.eu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/faro-instrumentation-replay_2.8.1-dstny.4_1787039613718_0.25163685609851494"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T07:53:33.616Z","2.8.1-dstny.4":"2026-08-18T07:53:33.855Z","modified":"2026-08-18T07:53:34.175Z"},"maintainers":[{"name":"made.dstny","email":"maxime.destreel@dstny.com"},{"name":"gbo.dstny","email":"gerik.bonaert@dstny.com"},{"name":"kilinccagatay","email":"cagatay.kilinc@destiny.eu"}],"description":"Faro instrumentation for session replay with rrweb","homepage":"https://github.com/grafana/faro-web-sdk","keywords":["observability","apm","rum","dem","session-replay","@grafana/rrweb","browser"],"repository":{"type":"git","url":"git+https://github.com/grafana/faro-web-sdk.git","directory":"experimental/instrumentation-replay"},"author":{"name":"Grafana Labs"},"bugs":{"url":"https://github.com/grafana/faro-web-sdk/issues"},"license":"Apache-2.0","readme":"# @dstny/faro-instrumentation-replay\n\nFaro instrumentation for session replay with rrweb.\n\n## Installation\n\n```bash\nnpm install @dstny/faro-instrumentation-replay\n```\n\n## Usage\n\n```typescript\nimport { ReplayInstrumentation } from '@dstny/faro-instrumentation-replay';\nimport { getWebInstrumentations, initializeFaro } from '@dstny/faro-web-sdk';\n\ninitializeFaro({\n  url: 'https://your-faro-endpoint.com',\n  instrumentations: [\n    ...getWebInstrumentations(),\n    new ReplayInstrumentation({\n      maskInputOptions: {\n        password: true,\n        email: true,\n      },\n      maskAllInputs: false,\n      recordAfter: 'load',\n      recordCrossOriginIframes: false,\n    }),\n  ],\n});\n```\n\n## Configuration Options\n\n### Privacy & Masking Options\n\n| Key                | Type                                              | Default              | Description                                                                                                                              |\n| ------------------ | ------------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |\n| `maskAllInputs`    | `boolean`                                         | `true`               | Mask all input content as `*`                                                                                                            |\n| `maskInputOptions` | `MaskInputOptions`                                | `{ password: true }` | Selectively mask specific input types (used only when `maskAllInputs` is `false`)                                                        |\n| `maskInputFn`      | `(value: string, element: HTMLElement) => string` | `undefined`          | Customize mask input content recording logic                                                                                             |\n| `maskTextSelector` | `string`                                          | `'*'`                | CSS selector for elements whose text content should be masked                                                                            |\n| `blockSelector`    | `string`                                          | `undefined`          | CSS selector for elements that should be blocked from recording. Blocked elements are replaced with a placeholder of the same dimensions |\n| `ignoreSelector`   | `string`                                          | `undefined`          | CSS selector for elements whose input events should be ignored                                                                           |\n\n#### `maskInputOptions`\n\n| Key              | Type      | Description           |\n| ---------------- | --------- | --------------------- |\n| `password`       | `boolean` | Password inputs       |\n| `text`           | `boolean` | Text inputs           |\n| `email`          | `boolean` | Email inputs          |\n| `tel`            | `boolean` | Telephone inputs      |\n| `number`         | `boolean` | Number inputs         |\n| `search`         | `boolean` | Search inputs         |\n| `url`            | `boolean` | URL inputs            |\n| `date`           | `boolean` | Date inputs           |\n| `datetime-local` | `boolean` | Datetime-local inputs |\n| `month`          | `boolean` | Month inputs          |\n| `week`           | `boolean` | Week inputs           |\n| `time`           | `boolean` | Time inputs           |\n| `color`          | `boolean` | Color inputs          |\n| `range`          | `boolean` | Range inputs          |\n| `textarea`       | `boolean` | Textarea elements     |\n| `select`         | `boolean` | Select dropdowns      |\n\n### Recording Options\n\n| Key                        | Type                           | Default  | Description                                                                                                                                     |\n| -------------------------- | ------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |\n| `samplingRate`             | `number`                       | `1`      | Fraction of globally-sampled sessions that will be recorded. Applied on top of `sessionTracking.samplingRate`. Out-of-range values are clamped. |\n| `recordAfter`              | `'load' \\| 'DOMContentLoaded'` | `'load'` | When to start recording if the document is not ready yet                                                                                        |\n| `recordCrossOriginIframes` | `boolean`                      | `false`  | Whether to record cross-origin iframes. rrweb must be injected in each child iframe for this to work                                            |\n| `recordCanvas`             | `boolean`                      | `false`  | Whether to record canvas element content                                                                                                        |\n| `collectFonts`             | `boolean`                      | `false`  | Whether to collect fonts used in the website                                                                                                    |\n| `inlineImages`             | `boolean`                      | `false`  | Whether to record image content                                                                                                                 |\n| `inlineStylesheet`         | `boolean`                      | `false`  | Whether to inline stylesheets in the recording events                                                                                           |\n\n#### Sub-sampling example\n\n```typescript\ninitializeFaro({\n  url: 'https://your-faro-endpoint.com',\n  sessionTracking: {\n    samplingRate: 1.0, // collect telemetry (logs, errors, web-vitals) for all sessions\n  },\n  instrumentations: [\n    ...getWebInstrumentations(),\n    new ReplayInstrumentation({\n      samplingRate: 0.1, // record replay for only 10% of sessions\n    }),\n  ],\n});\n// Effective replay coverage: 1.0 × 0.1 = 10% of globally-sampled sessions\n```\n\n### Hooks\n\n| Key          | Type                                                           | Default     | Description                                                                                   |\n| ------------ | -------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------- |\n| `beforeSend` | `(event: eventWithTime) => eventWithTime \\| null \\| undefined` | `undefined` | Transform or filter events before they are sent. Return `null` or `undefined` to skip sending |\n\n## Privacy and Security\n\nThis instrumentation records user interactions on your website. Make sure to:\n\n1. **Review masking options for your use case** - By default, all input values and text content are masked.\n   If needed, you can make masking more selective with `maskAllInputs`, `maskInputOptions`, and `maskTextSelector`\n2. **Use CSS selectors** - Use `maskTextSelector` to mask sensitive content, `blockSelector` to completely exclude elements\n3. **Implement filtering** - Use the `beforeSend` hook to filter or transform events before sending\n4. **Review your privacy policy** - Ensure you have proper user consent for session recording\n5. **Test your configuration** - Verify no sensitive information is captured in recordings\n\n### Example: Advanced Privacy Configuration\n\n```typescript\nnew ReplayInstrumentation({\n  // Disable global input masking and use selective masking rules instead\n  maskAllInputs: false,\n  // Mask all text and email inputs, but allow number inputs\n  maskInputOptions: {\n    password: true,\n    text: true,\n    email: true,\n    tel: true,\n    textarea: true,\n  },\n  // Mask elements with specific CSS classes\n  maskTextSelector: '.sensitive-data, .pii',\n  // Block elements completely from recording\n  blockSelector: '.payment-form, .credit-card-info',\n  // Ignore certain elements (won't be recorded at all)\n  ignoreSelector: '.analytics-widget',\n  // Filter or transform events before sending\n  beforeSend: (event) => {\n    // Example: Skip events that might contain sensitive data\n    if (event.type === 3 && event.data?.source === 'CanvasMutation') {\n      return null; // Skip this event\n    }\n    return event; // Send the event as-is\n  },\n});\n```\n","readmeFilename":"README.md","_rev":"1-bc1f3831ff6de916825cc65de2c41221"}