Architecture

System Overview

Blincr is a co-browsing platform built on Cloudflare Workers. Users install a Chrome extension that captures browsing trails (navigation, clicks, scrolls, selections, clipboard, overlays) and syncs them to a backend that coordinates real-time sessions and persists data.

Component Map

┌─────────────────────────────────────┐
│  Chrome Extension (MV3)             │
│  ├── content.ts    event capture    │
│  ├── background.ts session relay    │
│  ├── popup.ts      controls/tabs    │
│  ├── sidepanel.ts  trail replay     │
│  ├── trail-db.ts   IndexedDB store  │
│  └── plugins/      overlay system   │
│       ├── overlay-manager.ts        │
│       └── comment.ts                │
└────────────┬────────────────────────┘
             │ HTTP / WebSocket
┌────────────▼────────────────────────┐
│  Cloudflare Worker (workers/app.ts) │
│  ├── React Router SSR (dashboard)   │
│  ├── /api/*  REST endpoints         │
│  ├── /mcp    MCP server (agents)    │
│  └── /session/*  DO proxy           │
└──┬──────────┬──────────┬────────────┘
   │          │          │
┌──▼──┐  ┌───▼───┐  ┌───▼────┐
│ D1  │  │  R2   │  │  DO    │
│AUDIT│  │TRAILS │  │SESSION │
│ _DB │  │SNAPS  │  │COORD.  │
└─────┘  └───────┘  └────────┘

Data Flow

  1. Event capture — Content script intercepts DOM events (click, scroll, navigation, selection, clipboard) and sends them via chrome.runtime.sendMessage to the background service worker.
  2. Local storage — Background worker writes events to IndexedDB (blincr-trails database) via trail-db.ts. Trails are available offline.
  3. Session relay — When a live session is active, the background worker forwards events over a WebSocket to the SessionCoordinator Durable Object, which broadcasts to all participants.
  4. Cloud sync — Authenticated users can upload trails to D1 (cloud_trails table) with R2 storage for the full event payload.
  5. Dashboard — React Router app served by the same worker renders trails, audit logs, live sessions, and account settings.

Storage

Binding Service Purpose
AUDIT_DB D1 Users, sessions, credentials, audit log
SESSION_SNAPSHOTS R2 Trail JSON snapshots (trails/{id}.json)
SESSION_COORDINATOR DO Real-time WebSocket session state (SQLite)

Blincrs (standing page watchers)

A blincr is a watcher pinned to a page: it periodically re-fetches the page, extracts a value (CSS text, JSON-LD field, or regex), and alerts the owner when the value changes / crosses a threshold / appears / disappears.

  • blincr-watch-worker (separate deployment, watch-worker/) runs on a */5 * * * * cron. Each tick selects due blincrs (next_check_at <= now, one hit per domain per run for politeness), honors robots.txt, extracts via HTMLRewriter, compares against last_value, and on a crossing writes a blincr_alerts row + a notifications row (kind='blincr_alert', "The trail blinked") with a per-blincr cooldown. Five consecutive failures flag the blincr sight_lost and pause it.
  • Shared pure logic (extractors, comparators, robots parsing) lives in src/blincr-engine.ts (unit-tested, no bindings) so both workers reuse it.
  • The main worker owns CRUD: src/blincrs.ts + /api/user/blincrs* routes, with per-plan quotas resolved through src/entitlements.ts (ARC).
  • Separation rationale: MASTER-PLAN §3.2 — scheduled fetch fan-out runs on its own trigger and must not compete with interactive traffic.

Deployment

  • Worker: npm run deploywrangler deploy workers/deploy-entry.ts (prebuilt dist entry). wrangler.jsonc main points at workers/app.ts (virtual RR build) so react-router dev hot-reloads route loaders; the deploy/preview scripts override the entry on the command line.
  • Watch worker: wrangler deploy -c watch-worker/wrangler.jsonc
  • Dev: wrangler dev (uses wrangler.jsonc)
  • Extension: cd extension && node build.js (esbuild, outputs to extension/dist/)
  • Domain: blincr.com (Cloudflare custom domain)