@tirs/core
v0.2.11
Published
Tirs capture runtime: dormant console + network capture for Customer Care recordings. Ships as capture.js on the CDN.
Readme
@tirs/core
The Tirs capture runtime. It records the console output and network activity of your web app during a Tirs Customer Care recording session, so a screen recording submitted by your customer arrives with the technical context needed to debug it — every request, response, and console line, time-aligned with the video.
What it does
- Patches
console.*,fetch,XMLHttpRequestandnavigator.sendBeacononce, at startup. - Stays dormant until a Tirs care link opens your site: no data is collected, no UI is rendered, and the SDK makes no network requests of its own — ever. Its idle cost is one boolean check per intercepted call.
- During a recording it captures requests and responses (with bodies), console lines at every level, uncaught errors and unhandled promise rejections (with stacks), and single-page-app navigations.
- If the customer has your site open in other tabs, those tabs join the same session automatically, so the tab where the problem lives is captured too.
- When the recording stops, the captured activity is handed to the Tirs recorder for upload and the runtime returns to dormant.
How to use
If you install via the script tags from the Tirs app (Customer care → Domains & Install), you don't need this package — the tags include it.
For bundled installs:
npm i @tirs/core @tirs/care @tirs/recorderimport { init } from '@tirs/core';
import { care } from '@tirs/care';
import { mountRecorder } from '@tirs/recorder';
const tirs = init({
key: 'YOUR-KEY', // from Customer care → Domains & Install
plugins: [care()],
});
mountRecorder(tirs);Call init() as early in your app's startup as possible — the runtime can only capture
network calls made after it initializes.
Optional configuration
Every option is optional; the defaults are chosen to be safe on a production site.
| Option | Type | Default | What it does |
| --- | --- | --- | --- |
| key | string | — | Your workspace key. Identifies the install; it is not a secret and is safe in page source. |
| redact | boolean | true | Scrub PII from captured logs before anything leaves the page — tokens, passwords, emails, cards, IBANs, phone numbers, keys. Turn off only if you have your own guarantees. |
| preroll | number (ms) | 0 | Keep a rolling window of activity from before recording starts. 0 means nothing is retained while dormant. |
| denyUrls | (RegExp \| string)[] | [] | Never capture request/response bodies for matching URLs. Strings match literally. The request itself is still logged (method, URL, status) — only the body is withheld. |
| captureBodies | boolean | true | false records metadata only: no request or response bodies at all, anywhere. |
| maxBodyBytes | number | 65536 | Per-body cap. Larger bodies are truncated and marked. |
| debug | boolean | false | Log the SDK's own lifecycle to the console. Useful while installing. |
| appUrl | string | Tirs app | Override the Tirs app origin. Only needed for self-hosted deployments. |
| plugins | TirsPlugin[] | [] | Capabilities to attach; pass care() from @tirs/care. |
init({
key: 'YOUR-KEY',
plugins: [care()],
preroll: 30_000,
denyUrls: [/\/auth\//, '/billing/'],
maxBodyBytes: 32_000,
});preroll is worth a look. The seconds before your customer hits record are usually where
the bug actually happened. preroll: 30000 keeps a rolling 30-second window of console and
network activity that gets included when a recording starts. It costs a small, capped amount of
memory while idle; 0 keeps the SDK completely inert.
Script-tag configuration
The same options are available as data- attributes when you install via script tags:
| Attribute | Example | Maps to |
| --- | --- | --- |
| data-tirs-key | "pk_abc123" | key |
| data-tirs-redact | "false" | redact |
| data-tirs-preroll | "30000" | preroll |
| data-tirs-deny | "/auth/,/billing/" | denyUrls — comma-separated, matched literally |
| data-tirs-bodies | "false" | captureBodies |
| data-tirs-max-body | "32000" | maxBodyBytes |
| data-tirs-debug | "true" | debug |
| data-tirs-app | "https://…" | appUrl |
<script src="https://cdn.try-trs.com/v1/capture.js"
data-tirs-key="YOUR-KEY"
data-tirs-preroll="30000"
data-tirs-deny="/auth/,/billing/"></script>The key can also be supplied as <meta name="tirs:key" content="YOUR-KEY" /> for installs
where the script tag can't carry attributes (tag managers, some CMS embeds).
Runtime API
tirs.status(); // 'dormant' | 'armed' | 'capturing' | 'finalizing'
tirs.on('session-start', () => {}); // also: 'session-stop', 'status' — returns an unsubscribe fn
tirs.stop(); // abort a live capture and drop all buffers
tirs.destroy(); // remove the runtime entirelyLimits
Fixed safety rails, so a long or noisy session can never grow without bound: 2 000 network entries and 5 000 console entries (oldest dropped first, and the output records how many were dropped), an 8 MB total budget across all captured bodies, and a 5-minute maximum session length. Pre-roll bodies are capped harder than in-session ones so idle memory stays negligible.
Privacy & safety defaults
Built to run on production sites: PII redaction is on by default, captured data is hard-capped, body capture can be disabled per-URL or entirely, and nothing is ever collected outside an active, customer-initiated recording session.
MIT © Tirs
