### Initialize WabacLiveProxy Source: https://github.com/webrecorder/wabac.js/blob/main/examples/live-proxy/index.html Instantiate and initialize the WabacLiveProxy. This is the basic setup required to start using the live proxy functionality. ```javascript new WabacLiveProxy().init(); ``` -------------------------------- ### Extend Service Worker with Custom API and Replay Logic Source: https://context7.com/webrecorder/wabac.js/llms.txt Extend wabac.js with a custom Service Worker by subclassing `SWReplay`, `API`, or `SWCollections`. This example shows how to extend the `API` with a custom endpoint and the `SWReplay` engine with custom configuration options like `coHeaders` and `liveRedirectOnNotFound`. ```typescript // my-sw.ts import { SWReplay, API, SWCollections } from "@webrecorder/wabac/swlib"; import type { SWCollections as SWCollectionsType } from "@webrecorder/wabac/swlib"; // Extend the API with a custom endpoint class MyAPI extends API { override get routes() { return { ...super.routes, myEndpoint: "my/custom/:id", }; } override async handleApi(request: Request, params: Record, event: FetchEvent) { if (params["_route"] === "myEndpoint") { const coll = await this.collections.getColl(params["id"] as string); if (!coll) return { error: "not_found" }; return { id: coll.name, metadata: coll.metadata }; } return super.handleApi(request, params, event); } } // Extend the replay engine with custom config class MySWReplay extends SWReplay { constructor() { super({ ApiClass: MyAPI, defaultConfig: { injectScripts: ["https://cdn.example.com/my-inject.js"], coHeaders: true, // add CORS headers to all replayed responses injectRelCanon: true, // inject into HTML liveRedirectOnNotFound: true, // redirect to live web when URL not in archive }, }); } } // Initialize at SW top level self.sw = new MySWReplay(); ``` -------------------------------- ### Get Collection Info Source: https://context7.com/webrecorder/wabac.js/llms.txt Fetches basic or full information about a specific collection, including pages and verification status. ```APIDOC ## GET /w/api/c/ ### Description Retrieves information about a specific collection identified by `collId`. The `all` query parameter can be used to fetch full details including pages, lists, curatedPages, and verification status. ### Method GET ### Endpoint /w/api/c/ ### Parameters #### Path Parameters - **collId** (string) - Required - The unique identifier of the collection. #### Query Parameters - **all** (boolean) - Optional - If set to `1`, returns full collection details. ### Response #### Success Response (200) - **pages** (array) - List of pages in the collection (if `all=1`). - **verify** (object) - Verification status of the collection (if `all=1`). - Other collection-specific fields. ### Response Example ```json { "id": "my-archive", "title": "My Archive", "numPages": 150, "pages": [...], "verify": { ... } } ``` ``` -------------------------------- ### Get Curated Page List Source: https://context7.com/webrecorder/wabac.js/llms.txt Retrieves a specific curated list of pages from a collection. ```APIDOC ## GET /w/api/c//curated/ ### Description Fetches a specific curated list of pages identified by `listId` from a given collection. ### Method GET ### Endpoint /w/api/c//curated/ ### Parameters #### Path Parameters - **collId** (string) - Required - The unique identifier of the collection. - **listId** (string) - Required - The identifier of the curated list. ### Response #### Success Response (200) - **curated** (array) - An array of curated page objects. ``` -------------------------------- ### Get Capture Timestamps Source: https://context7.com/webrecorder/wabac.js/llms.txt Retrieves all capture timestamps for a specific URL within a collection. ```APIDOC ## GET /w/api/c//ts/ ### Description Retrieves all recorded capture timestamps for a given URL within a specific collection. ### Method GET ### Endpoint /w/api/c//ts/ ### Parameters #### Path Parameters - **collId** (string) - Required - The unique identifier of the collection. #### Query Parameters - **url** (string) - Required - The URL for which to retrieve timestamps. ### Response #### Success Response (200) - **timestamps** (array) - An array of strings, each representing a capture timestamp in `YYYYMMDDHHMMSS` format. ### Response Example ```json { "timestamps": [ "20230101120000", "20230102130000" ] } ``` ``` -------------------------------- ### Initialize Live Proxy with Ad Blocker Source: https://github.com/webrecorder/wabac.js/blob/main/examples/live-proxy/index-adblock.html Instantiate and initialize the Live Proxy with a specified collection name and adblock list URL. Ensure the adblock list is correctly formatted and accessible. ```javascript new WabacLiveProxy({ collName: "liveproxy-no-ads", adblockUrl: "./adblock.gz", }).init(); ``` -------------------------------- ### Initialize and Use ZipRangeReader Source: https://context7.com/webrecorder/wabac.js/llms.txt Demonstrates initializing ZipRangeReader with a loader, parsing the central directory, listing entries, and reading specific files. Use this to access WACZ archive contents. ```typescript import { ZipRangeReader } from "@webrecorder/wabac"; import { createLoader } from "@webrecorder/wabac"; const loader = await createLoader({ url: "https://example.com/archive.wacz" }); const reader = new ZipRangeReader(loader); await reader.load(); // parses the ZIP central directory // List all entries: const entries = reader.entries; Object.keys(entries).forEach(path => { const entry = entries[path]; console.log(path, entry.compressedSize, entry.uncompressedSize); }); // Read a specific file from the ZIP (e.g. the WACZ datapackage): const datapackageText = await reader.loadFile("datapackage.json", { computeHash: false }); const datapackage = JSON.parse(new TextDecoder().decode(datapackageText)); // Read with SHA-256 integrity check: const { reader: stream, hasher } = await reader.loadFileFromReader( entries["indexes/index.cdx.gz"], /* compressed= */ true, ); ``` -------------------------------- ### Initialize and Use FuzzyMatcher Source: https://context7.com/webrecorder/wabac.js/llms.txt Shows how to initialize FuzzyMatcher with default or custom rules for canonicalizing URLs. Use this to match archived responses despite volatile query parameters. ```typescript import { FuzzyMatcher } from "@webrecorder/wabac"; const matcher = new FuzzyMatcher(); // uses DEFAULT_RULES // Produce the list of canonical URLs to try for a lookup: const reqUrl = "https://www.youtube.com/get_video_info?video_id=abc123&eurl=https%3A%2F%2Fyoutube.googleapis.com%2F&c=WEB&cbr=Chrome&cplayer=UNIPLAYER&html5=1&_=1700000000000"; const canonUrls = matcher.getFuzzyCanonsWithArgs(reqUrl); // → ["//youtube.fuzzy.replayweb.page/get_video_info?video_id=abc123"] // The archive lookup tries these simplified URLs if the exact URL misses. // After a prefix lookup returns candidates, pick the best one: const candidates = [ { url: "https://cdn.example.com/video.mp4?itag=18&id=XYZ&expire=1699000000", status: 200 }, { url: "https://cdn.example.com/video.mp4?itag=18&id=XYZ&expire=1700000000", status: 200 }, ]; const { prefix, rule } = matcher.getRuleFor(reqUrl); const best = matcher.fuzzyCompareUrls(reqUrl, candidates, rule); console.log(best?.url); // picks the closest match by Levenshtein + query param scoring // Custom rules override defaults: const custom = new FuzzyMatcher([ { match: /api\.example\.com\/items\?id=(\w+)&ts=\d+/, replace: "https://api.example.com/items?id=$1", maxResults: 5, }, ]); ``` -------------------------------- ### Initialize and Use Rewriter for Response Transformation Source: https://context7.com/webrecorder/wabac.js/llms.txt Construct a Rewriter instance with configuration for URL and content rewriting. Use the rewrite method to process an ArchiveResponse and ArchiveRequest, then obtain a standard Response object. ```typescript import { Rewriter } from "@webrecorder/wabac"; import { ArchiveRequest } from "@webrecorder/wabac"; import { ArchiveResponse } from "@webrecorder/wabac"; // Construct a rewriter for a single request/response pair const rewriter = new Rewriter({ baseUrl: "https://example.com/page.html", prefix: "https://myapp.example.com/w/my-coll/20230601120000mp_/", responseUrl: "https://example.com/page.html", // actual URL after redirects decode: true, // decompress gzip/brotli content-encoding urlRewrite: true, // rewrite URLs in content contentRewrite: true, // rewrite JS/CSS/HTML bodies headInsertFunc: (url) => { // Return HTML to inject after for every HTML response return ` `; }, workerInsertFunc: (isModule) => { // Return JS to prepend to every Web Worker script return isModule ? `import '/static/wombatWorkers.js';` : `importScripts('/static/wombatWorkers.js');`; }, }); // Rewrite a response const archiveRequest: ArchiveRequest = /* ... */; const archiveResponse: ArchiveResponse = /* ... */; const rewritten = await rewriter.rewrite(archiveResponse, archiveRequest); // rewritten.makeResponse() returns a standard Response object ``` -------------------------------- ### Initialize SWReplay Service Worker Source: https://context7.com/webrecorder/wabac.js/llms.txt Instantiate SWReplay at the top level of your Service Worker scope. Options can be passed via the SW registration URL's query string to customize behavior like replay prefix, stats tracking, caching, script injection, adblock lists, and not-found templates. ```typescript // sw.ts (or your custom sw entry point) import { SWReplay } from "@webrecorder/wabac/swlib"; // Instantiate once at the top level of the SW scope. // All options are optional — passed via the SW registration URL's query string. // ?replayPrefix=w (default replay path prefix) // ?stats=1 (enable stats tracking) // ?allowCache=1 (cache rewritten responses in CacheStorage) // ?injectScripts=custom.js,banner.js // ?adblockUrl=https://cdn.example.com/easylist.txt // ?notFoundTemplateUrl=./404.html // ?useHashCheck=1 (verify WACZ zip integrity) const sw = new SWReplay({ // Override the API class to add custom endpoints // ApiClass: MyCustomAPI, // Supply static file overrides // staticData: new Map([["https://example.com/static/app.js", { type: "text/javascript", content: "..." }]]), // Default extra config applied to every collection defaultConfig: { injectScripts: ["https://annotations.example.com/inject.js"], noPostToGet: false, convertPostToGet: false, }, }); // The SW now intercepts all fetch events under its scope and routes: // /w//// → archive lookup + rewrite // /w/api/c/ → JSON collection info // /static/* → wombat.js, wombatWorkers.js, etc. ``` -------------------------------- ### Create Loader for Google Drive Files Source: https://context7.com/webrecorder/wabac.js/llms.txt Load files from Google Drive using `createLoader` by specifying a `googledrive://` URL. Provide authentication headers and optionally a public proxy URL in the `extra` configuration. ```typescript // Google Drive (uses googleapis.com or a public proxy URL) const driveLoader = await createLoader({ url: "googledrive://", headers: { Authorization: "Bearer " }, size: 102400, extra: { publicUrl: "https://drive.google.com/uc?export=download&id=" }, }); ``` -------------------------------- ### Create Collection Source: https://context7.com/webrecorder/wabac.js/llms.txt Creates a new, empty, writable collection with optional metadata and configuration. ```APIDOC ## POST /w/api/c/create ### Description Creates a new empty collection. Allows specifying initial metadata and configuration options. ### Method POST ### Endpoint /w/api/c/create ### Request Body - **metadata** (object) - Optional - Contains `title` and `description` for the collection. - **extraConfig** (object) - Optional - Configuration options, e.g., `convertPostToGet`. ### Request Example ```json { "metadata": { "title": "My Recording", "description": "Captured 2024-01-01" }, "extraConfig": { "convertPostToGet": true } } ``` ### Response #### Success Response (200) - **id** (string) - The unique identifier of the newly created collection. - **type** (string) - The type of the collection. - Other collection details. ``` -------------------------------- ### Create Loader for Local Files via File System Access API Source: https://context7.com/webrecorder/wabac.js/llms.txt Use `createLoader` with the `fileHandle` option to load local files through the File System Access API. This allows direct access to files selected by the user. ```typescript // Local file via File System Access API const [fileHandle] = await window.showOpenFilePicker(); const fileLoader = await createLoader({ url: "file:///local/archive.warc.gz", extra: { fileHandle }, }); ``` -------------------------------- ### Initialize and Use CollectionLoader Source: https://context7.com/webrecorder/wabac.js/llms.txt Demonstrates using CollectionLoader to manage IndexedDB collections outside of Service Workers. Use this for creating, loading, updating, and deleting collections in Web Workers or Node.js environments. ```typescript import { CollectionLoader } from "@webrecorder/wabac/swlib"; const loader = new CollectionLoader(); // Create a new empty writable collection (returns a collection-like object): const coll = await loader.initNewColl( { title: "My Archive", description: "Captured pages" }, { convertPostToGet: true }, // extraConfig "archive", // type ); console.log("New collection id:", coll.name); // Load all persisted collections: await loader.loadAll(/* optional comma-separated "name:dbname" pairs for extra colls */ ""); // Load a single collection by name: const existing = await loader.loadColl("some-id"); // Update metadata: await loader.updateMetadata("some-id", { title: "Renamed Archive" }); // Update HTTP auth headers (e.g. after OAuth refresh): await loader.updateAuth("some-id", { Authorization: "Bearer new-token" }); // Delete a collection and its IndexedDB: const ok = await loader.deleteColl("some-id"); console.log("Deleted:", ok); ``` -------------------------------- ### Create Collection - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Creates a new, empty, writable collection. Supports custom metadata and configuration options like 'convertPostToGet'. ```typescript // POST /w/api/c/create — create an empty writable collection fetch("/w/api/c/create", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ metadata: { title: "My Recording", description: "Captured 2024-01-01" }, extraConfig: { convertPostToGet: true }, }), }).then(r => r.json()); // → { id, type, ... } ``` -------------------------------- ### Create Loader for In-Memory ArrayBuffer Source: https://context7.com/webrecorder/wabac.js/llms.txt Use `createLoader` with an `arrayBuffer` in the `extra` configuration to create a loader from an existing ArrayBuffer. This is the fastest option when the data is already in memory. ```typescript // In-memory ArrayBuffer (fastest; used when the full file was already downloaded) const buffer = new Uint8Array(await fetch("archive.wacz").then(r => r.arrayBuffer())); const memLoader = await createLoader({ url: "https://example.com/archive.wacz", extra: { arrayBuffer: buffer }, }); ``` -------------------------------- ### Create HTTP Loader with Range Requests Source: https://context7.com/webrecorder/wabac.js/llms.txt Instantiate a loader for HTTP/HTTPS URLs using `createLoader`. This loader supports Range requests for partial content retrieval and includes retry logic for specific HTTP status codes. ```typescript import { createLoader } from "@webrecorder/wabac"; // HTTP/HTTPS — uses Range requests, retries on 429/503 with exponential backoff const httpLoader = await createLoader({ url: "https://example.com/archive.wacz", headers: { Authorization: "Bearer token123" }, }); const { response, abort } = await httpLoader.doInitialFetch( /* tryHead */ true, /* skipRange */ false ); console.log("Size:", httpLoader.length); // bytes const chunk = await httpLoader.getRange(0, 4096, /* streaming */ false); // chunk is Uint8Array ``` -------------------------------- ### Manage Collections with SWCollections Source: https://context7.com/webrecorder/wabac.js/llms.txt Use SWCollections to manage archives, typically created internally by SWReplay. You can subclass it to customize collection creation. The message-based API allows adding, removing, and listing collections from the main thread. ```typescript import { SWCollections } from "@webrecorder/wabac/swlib"; // Typically created internally by SWReplay, but can be subclassed: class MyCollections extends SWCollections { override _createCollection(opts) { // Customize per-collection setup return new MyCollection(opts, this.prefixes, this.defaultConfig); } } // Message-based API (called from the main thread): navigator.serviceWorker.controller?.postMessage({ msg_type: "addColl", name: "my-archive", file: { sourceUrl: "https://example.com/archive.wacz", // or: sourceUrl: "file:///local/path.warc.gz" (requires FileSystemFileHandle) // or: sourceUrl: "googledrive://" // or: sourceUrl: "ipfs://" }, extraConfig: { injectScripts: ["https://cdn.example.com/banner.js"], }, skipExisting: false, // set true to reuse existing DB }); // Listen for progress and completion: navigator.serviceWorker.addEventListener("message", (e) => { if (e.data.msg_type === "collProgress") { // { name, percent, error, currentSize, totalSize } console.log(`${e.data.name}: ${e.data.percent}%`); } if (e.data.msg_type === "collAdded") { // { name, sourceUrl } console.log("Collection ready:", e.data.name); // Replay URL is now: /w/// } }); // Remove a collection: navigator.serviceWorker.controller?.postMessage({ msg_type: "removeColl", name: "my-archive", }); // List all: navigator.serviceWorker.controller?.postMessage({ msg_type: "listAll", }); ``` -------------------------------- ### Create Loader for IPFS Content Source: https://context7.com/webrecorder/wabac.js/llms.txt Load content from IPFS using `createLoader` with an `ipfs://` URL. This functionality delegates to the `auto-js-ipfs` library. ```typescript // IPFS (delegates to auto-js-ipfs) const ipfsLoader = await createLoader({ url: "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", }); ``` -------------------------------- ### createLoader Function Source: https://context7.com/webrecorder/wabac.js/llms.txt The `createLoader` function acts as a factory, returning the appropriate `BaseLoader` subclass based on the URL scheme. These loaders support `getRange(offset, length)` for random-access reads, essential for WACZ zip parsing. ```APIDOC ## createLoader ### Description Returns the appropriate `BaseLoader` subclass based on the URL scheme. Loaders support `getRange(offset, length)` for random-access reads (required by WACZ zip parsing). ### Parameters - `options` (object): Configuration options for the loader. - `url` (string): The URL of the archive to load. Supports various schemes like `http://`, `https://`, `file://`, `googledrive://`, `ipfs://`, or a local path. - `headers` (object, optional): Headers to include in requests (e.g., `Authorization`). - `size` (number, optional): The size of the archive in bytes (useful for protocols like Google Drive where size might not be immediately available). - `extra` (object, optional): Additional protocol-specific options. - For `file://`: `{ fileHandle: FileSystemFileHandle }` for File System Access API. - For `googledrive://`: `{ publicUrl: string }` for a public download URL. - For in-memory loading: `{ arrayBuffer: ArrayBuffer }` containing the archive data. ### Returns - A `BaseLoader` instance configured for the specified URL. ### Loader Methods - `doInitialFetch(tryHead, skipRange)`: Performs the initial fetch to get metadata and potentially the first chunk of data. - `getRange(offset, length, streaming)`: Reads a specific range of bytes from the archive. - `length`: Property returning the total size of the archive in bytes. ### Example Usage ```typescript import { createLoader } from "@webrecorder/wabac"; // HTTP/HTTPS Loader const httpLoader = await createLoader({ url: "https://example.com/archive.wacz", headers: { Authorization: "Bearer token123" }, }); const chunk = await httpLoader.getRange(0, 4096); console.log("Size:", httpLoader.length); // Local File Loader (File System Access API) const [fileHandle] = await window.showOpenFilePicker(); const fileLoader = await createLoader({ url: "file:///local/archive.warc.gz", extra: { fileHandle }, }); // Google Drive Loader const driveLoader = await createLoader({ url: "googledrive://", headers: { Authorization: "Bearer " }, size: 102400, extra: { publicUrl: "https://drive.google.com/uc?export=download&id=" }, }); // IPFS Loader const ipfsLoader = await createLoader({ url: "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", }); // In-memory ArrayBuffer Loader const buffer = new Uint8Array(await fetch("archive.wacz").then(r => r.arrayBuffer())); const memLoader = await createLoader({ url: "https://example.com/archive.wacz", extra: { arrayBuffer: buffer }, }); ``` ``` -------------------------------- ### Utility Functions for Timestamp Conversion and Hashing Source: https://context7.com/webrecorder/wabac.js/llms.txt Provides utility functions for timestamp conversion, digest computation, and collection data helpers. Use `getTSMillis` and `tsToDate` for Wayback-style timestamps, `getStatusText` for HTTP status, `digestMessage` for SHA-256 hashing, and `randomId` for generating IDs. `addProxyAllowPaths` is used to permit additional paths through the proxy. ```typescript import { getTSMillis, tsToDate, getStatusText, digestMessage, randomId, getCollData, addProxyAllowPaths, } from "@webrecorder/wabac"; // Convert ISO 8601 to Wayback-style timestamp (17 digits): getTSMillis("2023-06-01T12:00:00.000Z"); // → "20230601120000000" // Parse Wayback timestamp back to Date: tsToDate("20230601120000"); // → Date(2023-06-01T12:00:00Z) // HTTP status text: getStatusText(206); // → "Partial Content" // SHA-256 digest of a string (async): const hash = await digestMessage("hello world", "sha-256"); // → "b94d27b9934d3e08a52e52d7da7dabfac484efe04294e576" // Random URL-safe ID (used for unnamed collections): randomId(); // → "a3f8c2e1b9d74" // Allow additional paths through the proxy (for injected scripts): addProxyAllowPaths([ "https://annotations.example.com/", "https://cdn.example.com/banner.js", ]); ``` -------------------------------- ### CollectionLoader Source: https://context7.com/webrecorder/wabac.js/llms.txt Manages the IndexedDB `collDB` store and can be used outside a Service Worker to load, list, and delete collections. ```APIDOC ## CollectionLoader — Collection Persistence (Non-SW Contexts) `CollectionLoader` manages the IndexedDB `collDB` store and can be used outside a Service Worker to load/list/delete collections (e.g. from a Web Worker or Node.js test environment). ```typescript import { CollectionLoader } from "@webrecorder/wabac/swlib"; const loader = new CollectionLoader(); // Create a new empty writable collection (returns a collection-like object): const coll = await loader.initNewColl( { title: "My Archive", description: "Captured pages" }, { convertPostToGet: true }, // extraConfig "archive", // type ); console.log("New collection id:", coll.name); // Load all persisted collections: await loader.loadAll(/* optional comma-separated "name:dbname" pairs for extra colls */ ""); // Load a single collection by name: const existing = await loader.loadColl("some-id"); // Update metadata: await loader.updateMetadata("some-id", { title: "Renamed Archive" }); // Update HTTP auth headers (e.g. after OAuth refresh): await loader.updateAuth("some-id", { Authorization: "Bearer new-token" }); // Delete a collection and its IndexedDB: const ok = await loader.deleteColl("some-id"); console.log("Deleted:", ok); ``` ``` -------------------------------- ### List Collections - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Fetches a list of all non-live collections. Can be filtered by type prefix like 'wacz'. ```typescript // All endpoints relative to the SW scope, e.g. https://app.example.com/ // GET /w/api/coll-index — list all non-live collections // GET /w/api/coll-index?filter=wacz — filter by type prefix fetch("/w/api/coll-index").then(r => r.json()).then(({ colls }) => { colls.forEach(c => console.log(c.id, c.title, c.numPages)); }); ``` -------------------------------- ### Rewrite HLS Manifests Source: https://context7.com/webrecorder/wabac.js/llms.txt The `rewriteHLS` function from `@webrecorder/wabac` is used to rewrite HLS (.m3u8) manifest files. It transforms playlist URLs to use the specified rewrite prefix. ```typescript // HLS manifest rewrite: import { rewriteHLS } from "@webrecorder/wabac"; const m3u8 = `#EXTM3U #EXT-X-STREAM-INF:BANDWIDTH=800000 https://cdn.example.com/low.m3u8`; const rewrittenHLS = rewriteHLS(m3u8, { prefix: "https://myapp.example.com/w/my-coll/20230601120000mp_/", baseUrl: "https://cdn.example.com/master.m3u8", }); ``` -------------------------------- ### Retrieve Collection Info - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Fetches basic or full information about a specific collection, including pages and verification status when 'all=1' is used. ```typescript // GET /w/api/c/ — basic info // GET /w/api/c/?all=1 — full info: pages, lists, curatedPages, verify fetch("/w/api/c/my-archive?all=1").then(r => r.json()).then(data => { console.log(data.pages, data.verify); }); ``` -------------------------------- ### Retrieve Curated Page List - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Fetches a specific curated list of pages from a collection. ```typescript // GET /w/api/c//curated/ — curated page list fetch("/w/api/c/my-archive/curated/1").then(r => r.json()); // → { curated: [...] } ``` -------------------------------- ### Conditional Redirect on Not Found Source: https://github.com/webrecorder/wabac.js/blob/main/src/templates/notFound.html Redirects to the live URL if `redirectOnNotFound` is enabled. This is useful for handling broken links or missing archives. ```javascript if (window.redirectOnNotFound) { document.querySelector("redirectMessage").style.display = "initial"; window.top.location.href = window.requestURL; } ``` -------------------------------- ### List Collection URLs - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Fetches URLs from a collection, with options to filter by a specific URL, MIME type, or count. ```typescript // GET /w/api/c//urls?url=https://example.com&count=50 // GET /w/api/c//urls?mime=text/html&count=100 fetch("/w/api/c/my-archive/urls?url=https://example.com&prefix=1&count=20") .then(r => r.json()); // → { urls: [{ url, ts, status, mime }, ...] } ``` -------------------------------- ### Register LiveProxy Collection with SW Message API Source: https://context7.com/webrecorder/wabac.js/llms.txt Register a live-proxy collection using the Service Worker message API. This forwards requests to the live web via a CORS proxy and serves them as if from an archive. Configure optional script injection and a proxy banner. ```typescript import { LiveProxy } from "@webrecorder/wabac/swlib"; // Register a live-proxy collection via the SW message API: navigator.serviceWorker.controller?.postMessage({ msg_type: "addColl", name: "live", file: { sourceUrl: "proxy:https://example.com/", }, extraConfig: { // CORS proxy that forwards requests and adds CORS headers prefix: "https://wabac-cors-proxy.example.com/proxy/", // Optional: inject scripts into every proxied page injectScripts: ["https://annotations.example.com/viewer.js"], // Optional: show a banner iframe proxyBannerUrl: "https://ui.example.com/banner.html", }, type: "live", }); // Pages are now accessible at: // /w/live/20230601120000mp_/https://example.com/ // Any URL under example.com is fetched live through the proxy and rewritten. ``` -------------------------------- ### List Collections Source: https://context7.com/webrecorder/wabac.js/llms.txt Retrieves a list of all non-live collections. Supports filtering by type, such as 'wacz'. ```APIDOC ## GET /w/api/coll-index ### Description Lists all non-live collections. Can be filtered by type using the `filter` query parameter. ### Method GET ### Endpoint /w/api/coll-index ### Query Parameters - **filter** (string) - Optional - Filters collections by type prefix (e.g., `wacz`). ### Response #### Success Response (200) - **colls** (array) - An array of collection objects, each containing `id`, `title`, and `numPages`. ### Response Example ```json { "colls": [ { "id": "coll1", "title": "Archive 1", "numPages": 100 }, { "id": "coll2", "title": "Archive 2", "numPages": 50 } ] } ``` ``` -------------------------------- ### List Collection Pages Source: https://context7.com/webrecorder/wabac.js/llms.txt Retrieves a list of pages within a collection, supporting pagination and search for MultiWACZ archives. ```APIDOC ## GET /w/api/c//pages ### Description Retrieves all pages within a specified collection. Supports searching for pages by keyword and paginating results for large collections or MultiWACZ archives. ### Method GET ### Endpoint /w/api/c//pages ### Parameters #### Path Parameters - **collId** (string) - Required - The unique identifier of the collection. #### Query Parameters - **search** (string) - Optional - Keyword to search for within page titles or URLs. - **page** (integer) - Optional - The page number for pagination (default is 1). - **pageSize** (integer) - Optional - The number of items per page (default is 25). ### Response #### Success Response (200) - **pages** (array) - An array of page objects, each containing `url`, `title`, and `ts`. - **total** (integer) - The total number of pages matching the query. ### Response Example ```json { "pages": [ { "url": "https://example.com/page1", "title": "Page 1", "ts": "20230101120000" }, { "url": "https://example.com/page2", "title": "Page 2", "ts": "20230101120500" } ], "total": 150 } ``` ``` -------------------------------- ### List Capture Timestamps - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Retrieves all capture timestamps for a specific URL within a collection. ```typescript // GET /w/api/c//ts/?url=https://example.com — all capture timestamps fetch("/w/api/c/my-archive/ts/?url=https://example.com") .then(r => r.json()); // → { timestamps: ["20230101120000", ...] } ``` -------------------------------- ### List Collection Pages - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Retrieves all pages within a collection. Supports paginated searching with parameters for search terms, page number, and page size. ```typescript // GET /w/api/c//pages — all pages // GET /w/api/c//pages?search=cats&page=2&pageSize=25 — paginated search (MultiWACZ) fetch("/w/api/c/my-archive/pages").then(r => r.json()).then(({ pages, total }) => { pages.forEach(p => console.log(p.url, p.title, p.ts)); }); ``` -------------------------------- ### ZipRangeReader Source: https://context7.com/webrecorder/wabac.js/llms.txt Reads the ZIP central directory from a BaseLoader and provides random-access decompression for individual entries. It is the foundation of WACZ on-demand loading. ```APIDOC ## ZipRangeReader — WACZ / ZIP Random-Access Reader `ZipRangeReader` reads the ZIP central directory from a `BaseLoader` and provides random-access decompression for individual entries. It is the foundation of WACZ on-demand loading. ```typescript import { ZipRangeReader } from "@webrecorder/wabac"; import { createLoader } from "@webrecorder/wabac"; const loader = await createLoader({ url: "https://example.com/archive.wacz" }); const reader = new ZipRangeReader(loader); await reader.load(); // parses the ZIP central directory // List all entries: const entries = reader.entries; Object.keys(entries).forEach(path => { const entry = entries[path]; console.log(path, entry.compressedSize, entry.uncompressedSize); }); // Read a specific file from the ZIP (e.g. the WACZ datapackage): const datapackageText = await reader.loadFile("datapackage.json", { computeHash: false }); const datapackage = JSON.parse(new TextDecoder().decode(datapackageText)); // Read with SHA-256 integrity check: const { reader: stream, hasher } = await reader.loadFileFromReader( entries["indexes/index.cdx.gz"], /* compressed= */ true, ); ``` ``` -------------------------------- ### List Collection URLs Source: https://context7.com/webrecorder/wabac.js/llms.txt Retrieves a list of URLs within a collection, with options to filter by URL, MIME type, and count. ```APIDOC ## GET /w/api/c//urls ### Description Retrieves a list of URLs stored within a collection. Allows filtering by a specific URL, MIME type, and limiting the number of results. ### Method GET ### Endpoint /w/api/c//urls ### Parameters #### Path Parameters - **collId** (string) - Required - The unique identifier of the collection. #### Query Parameters - **url** (string) - Optional - Filters URLs that match this specific URL. - **mime** (string) - Optional - Filters URLs by their MIME type (e.g., `text/html`). - **prefix** (boolean) - Optional - If set to `1`, matches URLs with the provided `url` as a prefix. - **count** (integer) - Optional - The maximum number of URLs to return. ### Response #### Success Response (200) - **urls** (array) - An array of URL objects, each containing `url`, `ts`, `status`, and `mime`. ### Response Example ```json { "urls": [ { "url": "https://example.com", "ts": "20230101120000", "status": 200, "mime": "text/html" }, { "url": "https://example.com/about", "ts": "20230101120100", "status": 200, "mime": "text/html" } ] } ``` ``` -------------------------------- ### FuzzyMatcher Source: https://context7.com/webrecorder/wabac.js/llms.txt Canonicalizes request URLs so that volatile query parameters do not prevent matching an archived response. It ships with built-in rules for common platforms and generic patterns. ```APIDOC ## FuzzyMatcher — Fuzzy URL Lookup `FuzzyMatcher` canonicalizes request URLs so that volatile query parameters (cache-busters, OAuth tokens, CDN signatures) do not prevent matching an archived response. It ships with built-in rules for YouTube, Twitter/X, Facebook, Vimeo, and generic patterns (UTM params, JSONP callbacks, cache-buster `_` / `cb` params). ```typescript import { FuzzyMatcher } from "@webrecorder/wabac"; const matcher = new FuzzyMatcher(); // uses DEFAULT_RULES // Produce the list of canonical URLs to try for a lookup: const reqUrl = "https://www.youtube.com/get_video_info?video_id=abc123&eurl=https%3A%2F%2Fyoutube.googleapis.com%2F&c=WEB&cbr=Chrome&cplayer=UNIPLAYER&html5=1&_=1700000000000"; const canonUrls = matcher.getFuzzyCanonsWithArgs(reqUrl); // → ["//youtube.fuzzy.replayweb.page/get_video_info?video_id=abc123"] // The archive lookup tries these simplified URLs if the exact URL misses. // After a prefix lookup returns candidates, pick the best one: const candidates = [ { url: "https://cdn.example.com/video.mp4?itag=18&id=XYZ&expire=1699000000", status: 200 }, { url: "https://cdn.example.com/video.mp4?itag=18&id=XYZ&expire=1700000000", status: 200 }, ]; const { prefix, rule } = matcher.getRuleFor(reqUrl); const best = matcher.fuzzyCompareUrls(reqUrl, candidates, rule); console.log(best?.url); // picks the closest match by Levenshtein + query param scoring // Custom rules override defaults: const custom = new FuzzyMatcher([ { match: /api\.example\.com\/items\?id=(\w+)&ts=\d+/, replace: "https://api.example.com/items?id=$1", maxResults: 5, }, ]); ``` ``` -------------------------------- ### Perform JavaScript Rewriting Source: https://context7.com/webrecorder/wabac.js/llms.txt Use `rewriteJS` for rewriting JavaScript code. This method delegates to JSRewriter and uses AST parsing. Provide necessary options like `prefix` and `baseUrl` for accurate rewriting. ```typescript // JS rewrite delegates to JSRewriter (acorn AST-based): const rewrittenJS = rewriter.rewriteJS( `window.location.href = "https://example.com/other";`, { prefix: "/w/my-coll/20230601120000mp_/", baseUrl: "https://example.com/page.html" } ); ``` -------------------------------- ### Perform CSS-Only Rewriting Source: https://context7.com/webrecorder/wabac.js/llms.txt The `rewriteCSS` method synchronously rewrites CSS content, transforming background URLs and import statements to use the configured rewrite prefix. Ensure the Rewriter is configured for URL rewriting. ```typescript // CSS-only rewrite (synchronous): const rewrittenCSS = rewriter.rewriteCSS( `body { background: url('/images/bg.png'); } @import "/shared.css";` ); // → `body { background: url('/w/my-coll/.../mp_//example.com/images/bg.png'); } // @import "/w/my-coll/.../mp_//example.com/shared.css";` ``` -------------------------------- ### Update Collection Metadata - Webrecorder API Source: https://context7.com/webrecorder/wabac.js/llms.txt Updates the metadata of a collection, such as its title or description. ```typescript // POST /w/api/c//metadata — update title/description/etc fetch("/w/api/c/my-archive/metadata", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title: "Updated Title", desc: "..." }), }); ``` -------------------------------- ### Determine Rewriting Mode for MIME Type Source: https://context7.com/webrecorder/wabac.js/llms.txt The `getRewriteMode` method helps determine how a given request/response pair should be rewritten based on its MIME type. This is useful for conditional rewriting logic. ```typescript // Determine the rewrite mode for a MIME type: const mode = rewriter.getRewriteMode(archiveRequest, archiveResponse); // → "html" | "css" | "js" | "js-worker" | "json" | "jsonp" | "hls" | "dash" | "" ``` -------------------------------- ### Rewrite a Single URL String Source: https://context7.com/webrecorder/wabac.js/llms.txt Use the `rewriteUrl` method to transform a single URL according to the Rewriter's configuration. This is useful for rewriting individual links or resource paths. ```typescript // Rewrite a single URL string: const rwUrl = rewriter.rewriteUrl("https://cdn.example.com/app.js"); // → "https://myapp.example.com/w/my-coll/20230601120000mp_/https://cdn.example.com/app.js" ``` -------------------------------- ### Update Not Found Page Content Source: https://github.com/webrecorder/wabac.js/blob/main/src/templates/notFound.html Updates the content of the not found page with the requested URL and error message. This snippet is used to inform the user about the missing page and provide a link to the live version. ```javascript document.querySelector("#url").innerText = window.requestURL; document.querySelector("#msg").innerText = window.errorMsg; document.querySelector("#livelink").href = window.requestURL; ``` -------------------------------- ### Notify Parent Frame of Archive Not Found Source: https://github.com/webrecorder/wabac.js/blob/main/src/templates/notFound.html Sends a message to the parent frame indicating that an archived page was not found. This is only done if the current frame is the top-level frame and not embedded within another Wombat instance. ```javascript let isTop = true; try { if (window.parent._WB_wombat_location) { isTop = false; } } catch (e) {} if (isTop) { document.querySelector("#goback").style.display = ""; window.parent.postMessage( { wb_type: "archive-not-found", url: window.requestURL, ts: $REQUEST_TS, }, "*", ); } ``` -------------------------------- ### Rewriter Class Source: https://context7.com/webrecorder/wabac.js/llms.txt The Rewriter class transforms archived HTTP responses by rewriting embedded URLs and inserting the wombat.js bootstrap snippet into HTML. It supports various content types including HTML, CSS, JavaScript, JSON, and media manifests. ```APIDOC ## Rewriter ### Description Transforms archived HTTP responses so all embedded URLs are routed back through the SW's replay prefix, and inserts the wombat.js bootstrap snippet into HTML ``. It handles HTML, CSS, JavaScript, JSON, JSONP, HLS (`.m3u8`), and MPEG-DASH (`.mpd`). ### Constructor `new Rewriter(options)` ### Options - `baseUrl` (string): The base URL of the page being rewritten. - `prefix` (string): The replay prefix to use for rewriting URLs. - `responseUrl` (string): The actual URL of the response after redirects. - `decode` (boolean): Whether to decompress gzip/brotli content-encoding. - `urlRewrite` (boolean): Whether to rewrite URLs in content. - `contentRewrite` (boolean): Whether to rewrite JS/CSS/HTML bodies. - `headInsertFunc` (function): A function that returns HTML to inject after `` for every HTML response. - `workerInsertFunc` (function): A function that returns JS to prepend to every Web Worker script. ### Methods - `rewrite(archiveResponse, archiveRequest)`: Rewrites an entire HTTP response. - `rewriteUrl(url)`: Rewrites a single URL string. - `getRewriteMode(archiveRequest, archiveResponse)`: Determines the rewrite mode for a given MIME type. - `rewriteCSS(cssString)`: Rewrites CSS content synchronously. - `rewriteJS(jsString, options)`: Rewrites JavaScript content. ### Example Usage ```typescript import { Rewriter } from "@webrecorder/wabac"; const rewriter = new Rewriter({ baseUrl: "https://example.com/page.html", prefix: "https://myapp.example.com/w/my-coll/20230601120000mp_/", responseUrl: "https://example.com/page.html", decode: true, urlRewrite: true, contentRewrite: true, headInsertFunc: (url) => ``, workerInsertFunc: (isModule) => isModule ? `import '/static/wombatWorkers.js';` : `importScripts('/static/wombatWorkers.js');`, }); const rewritten = await rewriter.rewrite(archiveResponse, archiveRequest); const rwUrl = rewriter.rewriteUrl("https://cdn.example.com/app.js"); const rewrittenCSS = rewriter.rewriteCSS(`body { background: url('/images/bg.png'); } @import "/shared.css";`); const rewrittenJS = rewriter.rewriteJS(`window.location.href = "https://example.com/other";`, { prefix: "/w/my-coll/20230601120000mp_", baseUrl: "https://example.com/page.html" }); ``` ```