@pagepocket/lib 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @pagepocket/lib
2
+
3
+ Library for rewriting captured HTML into an offline-ready snapshot. It downloads
4
+ assets, rewrites HTML/CSS/JS references to local URLs, and injects replay/preload
5
+ scripts.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @pagepocket/lib
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```ts
16
+ import { PagePocket } from "@pagepocket/lib";
17
+
18
+ const pagepocket = new PagePocket(htmlString, requestsJSON, {
19
+ assetsDirName: "example_files",
20
+ baseUrl: "https://example.com",
21
+ requestsPath: "example.requests.json"
22
+ });
23
+
24
+ const html = await pagepocket.put();
25
+ ```
26
+
27
+ ## API
28
+
29
+ ```ts
30
+ type PagePocketOptions = {
31
+ assetsDirName?: string;
32
+ baseUrl?: string;
33
+ requestsPath?: string;
34
+ };
35
+ ```
36
+
37
+ - `assetsDirName`: folder name for downloaded assets.
38
+ - `baseUrl`: used to resolve relative URLs.
39
+ - `requestsPath`: path to the `*.requests.json` file referenced by replay.
40
+
41
+ `put()` returns the rewritten HTML string.
42
+
43
+ ## Notes
44
+
45
+ - Uses `@pagepocket/uni-fs` for file IO so it works in Node and OPFS contexts.
@@ -36,7 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.rewriteCssUrls = void 0;
37
37
  const URL_PATTERN = /url\(\s*(['"]?)([^'")]+)\1\s*\)/g;
38
38
  const rewriteCssUrls = async (input) => {
39
- const { readText, write } = await Promise.resolve().then(() => __importStar(require("uni-fs")));
39
+ const { readText, write } = await Promise.resolve().then(() => __importStar(require("@pagepocket/uni-fs")));
40
40
  const original = await readText(input.filename, input.extension);
41
41
  let updated = "";
42
42
  let lastIndex = 0;
@@ -98,16 +98,13 @@ const collectSrcsetUrls = (items, baseUrl) => {
98
98
  return urls;
99
99
  };
100
100
  const downloadResources = async (input) => {
101
- const { write, exists } = await Promise.resolve().then(() => __importStar(require("uni-fs")));
101
+ const { write, exists } = await Promise.resolve().then(() => __importStar(require("@pagepocket/uni-fs")));
102
102
  const resourceMap = new Map();
103
103
  const resourceMeta = [];
104
104
  let downloadedCount = 0;
105
105
  let failedCount = 0;
106
106
  const srcsetUrls = collectSrcsetUrls(input.srcsetItems, input.baseUrl);
107
- const candidateUrls = [
108
- ...input.resourceUrls.map((resource) => resource.url),
109
- ...srcsetUrls
110
- ];
107
+ const candidateUrls = [...input.resourceUrls.map((resource) => resource.url), ...srcsetUrls];
111
108
  for (const candidate of candidateUrls) {
112
109
  if (shouldSkipUrl(candidate)) {
113
110
  continue;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { PagePocket } from "./pagepocket";
2
2
  export type { PagePocketOptions } from "./pagepocket";
3
- export type { FetchRecord, NetworkRecord, LighterceptorNetworkRecord, SnapshotData } from "./types";
3
+ export type { FetchRecord, NetworkRecord, CapturedNetworkRecord, SnapshotData, NetworkInterceptorAdapter } from "./types";
4
4
  export { buildReplayScript } from "./replay-script";
5
5
  export { buildPreloadScript } from "./preload";
6
- export { findFaviconDataUrl, mapLighterceptorRecords, toDataUrlFromRecord } from "./network-records";
6
+ export { findFaviconDataUrl, mapCapturedNetworkRecords, toDataUrlFromRecord } from "./network-records";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toDataUrlFromRecord = exports.mapLighterceptorRecords = exports.findFaviconDataUrl = exports.buildPreloadScript = exports.buildReplayScript = exports.PagePocket = void 0;
3
+ exports.toDataUrlFromRecord = exports.mapCapturedNetworkRecords = exports.findFaviconDataUrl = exports.buildPreloadScript = exports.buildReplayScript = exports.PagePocket = void 0;
4
4
  var pagepocket_1 = require("./pagepocket");
5
5
  Object.defineProperty(exports, "PagePocket", { enumerable: true, get: function () { return pagepocket_1.PagePocket; } });
6
6
  var replay_script_1 = require("./replay-script");
@@ -9,5 +9,5 @@ var preload_1 = require("./preload");
9
9
  Object.defineProperty(exports, "buildPreloadScript", { enumerable: true, get: function () { return preload_1.buildPreloadScript; } });
10
10
  var network_records_1 = require("./network-records");
11
11
  Object.defineProperty(exports, "findFaviconDataUrl", { enumerable: true, get: function () { return network_records_1.findFaviconDataUrl; } });
12
- Object.defineProperty(exports, "mapLighterceptorRecords", { enumerable: true, get: function () { return network_records_1.mapLighterceptorRecords; } });
12
+ Object.defineProperty(exports, "mapCapturedNetworkRecords", { enumerable: true, get: function () { return network_records_1.mapCapturedNetworkRecords; } });
13
13
  Object.defineProperty(exports, "toDataUrlFromRecord", { enumerable: true, get: function () { return network_records_1.toDataUrlFromRecord; } });
@@ -1,4 +1,4 @@
1
- import type { LighterceptorNetworkRecord, NetworkRecord } from "./types";
1
+ import type { CapturedNetworkRecord, NetworkRecord } from "./types";
2
2
  export declare const toDataUrlFromRecord: (record: NetworkRecord) => string | null;
3
3
  export declare const findFaviconDataUrl: (records: NetworkRecord[]) => string | null;
4
- export declare const mapLighterceptorRecords: (records: LighterceptorNetworkRecord[] | undefined) => NetworkRecord[];
4
+ export declare const mapCapturedNetworkRecords: (records: CapturedNetworkRecord[] | undefined) => NetworkRecord[];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapLighterceptorRecords = exports.findFaviconDataUrl = exports.toDataUrlFromRecord = void 0;
3
+ exports.mapCapturedNetworkRecords = exports.findFaviconDataUrl = exports.toDataUrlFromRecord = void 0;
4
4
  const getHeaderValue = (headers, name) => {
5
5
  for (const key in headers) {
6
6
  if (key.toLowerCase() === name.toLowerCase()) {
@@ -61,7 +61,7 @@ const findFaviconDataUrl = (records) => {
61
61
  return null;
62
62
  };
63
63
  exports.findFaviconDataUrl = findFaviconDataUrl;
64
- const mapLighterceptorRecords = (records) => {
64
+ const mapCapturedNetworkRecords = (records) => {
65
65
  if (!records)
66
66
  return [];
67
67
  return records.map((record) => {
@@ -80,4 +80,4 @@ const mapLighterceptorRecords = (records) => {
80
80
  };
81
81
  });
82
82
  };
83
- exports.mapLighterceptorRecords = mapLighterceptorRecords;
83
+ exports.mapCapturedNetworkRecords = mapCapturedNetworkRecords;
@@ -1,9 +1,13 @@
1
- import type { SnapshotData } from "./types";
1
+ import type { NetworkInterceptorAdapter, SnapshotData } from "./types";
2
2
  export type PagePocketOptions = {
3
3
  assetsDirName?: string;
4
4
  baseUrl?: string;
5
5
  requestsPath?: string;
6
6
  };
7
+ interface PageContent extends PagePocketOptions {
8
+ content: string;
9
+ title: string;
10
+ }
7
11
  type RequestsInput = SnapshotData | string;
8
12
  export declare class PagePocket {
9
13
  private htmlString;
@@ -13,6 +17,7 @@ export declare class PagePocket {
13
17
  downloadedCount: number;
14
18
  failedCount: number;
15
19
  constructor(htmlString: string, requestsJSON: RequestsInput, options?: PagePocketOptions);
16
- put(): Promise<string>;
20
+ static fromNetworkIntercetor(htmlString: string, url: string, interceptorAdapter: NetworkInterceptorAdapter, options?: PagePocketOptions): Promise<PagePocket>;
21
+ put(): Promise<PageContent>;
17
22
  }
18
23
  export {};
@@ -19,7 +19,7 @@ const safeFilename = (input) => {
19
19
  const parseRequestsJson = (requestsJSON) => {
20
20
  const snapshot = typeof requestsJSON === "string" ? JSON.parse(requestsJSON) : requestsJSON;
21
21
  const rawNetworkRecords = (snapshot.networkRecords || []);
22
- const mappedNetworkRecords = (0, network_records_1.mapLighterceptorRecords)(rawNetworkRecords);
22
+ const mappedNetworkRecords = (0, network_records_1.mapCapturedNetworkRecords)(rawNetworkRecords);
23
23
  return {
24
24
  snapshot,
25
25
  networkRecords: mappedNetworkRecords
@@ -34,6 +34,9 @@ class PagePocket {
34
34
  this.requestsJSON = requestsJSON;
35
35
  this.options = options ?? {};
36
36
  }
37
+ static async fromNetworkIntercetor(htmlString, url, interceptorAdapter, options) {
38
+ return new PagePocket(htmlString, await interceptorAdapter.run(url), options);
39
+ }
37
40
  async put() {
38
41
  const { snapshot, networkRecords } = parseRequestsJson(this.requestsJSON);
39
42
  const safeTitle = safeFilename(snapshot.title || "snapshot");
@@ -67,7 +70,13 @@ class PagePocket {
67
70
  requestsPath,
68
71
  faviconDataUrl
69
72
  });
70
- return $.html();
73
+ return {
74
+ content: $.html(),
75
+ title: safeTitle,
76
+ assetsDirName,
77
+ requestsPath,
78
+ baseUrl
79
+ };
71
80
  }
72
81
  }
73
82
  exports.PagePocket = PagePocket;
@@ -1,7 +1,7 @@
1
1
  import type { CheerioAPI } from "cheerio";
2
+ import type { DownloadedResource } from "./download-resources";
2
3
  import { type ResourceReference, type SrcsetReference } from "./resources";
3
4
  import type { NetworkRecord } from "./types";
4
- import type { DownloadedResource } from "./download-resources";
5
5
  type RewriteLinksInput = {
6
6
  $: CheerioAPI;
7
7
  resourceUrls: ResourceReference[];
@@ -105,7 +105,7 @@ const buildNetworkLookup = (records) => {
105
105
  return networkRecordByUrl;
106
106
  };
107
107
  const rewriteLinks = async (input) => {
108
- const { readAsURL } = await Promise.resolve().then(() => __importStar(require("uni-fs")));
108
+ const { readAsURL } = await Promise.resolve().then(() => __importStar(require("@pagepocket/uni-fs")));
109
109
  const networkRecordByUrl = buildNetworkLookup(input.networkRecords);
110
110
  const { baseOrigin, baseDir } = buildLinkBase(input.baseUrl);
111
111
  const localUrlCache = new Map();
package/dist/types.d.ts CHANGED
@@ -24,19 +24,19 @@ export type NetworkRecord = {
24
24
  error?: string;
25
25
  timestamp: number;
26
26
  };
27
- export type LighterceptorResponseRecord = {
27
+ export type CapturedResponseRecord = {
28
28
  status: number;
29
29
  statusText: string;
30
30
  headers: Record<string, string>;
31
31
  body: string;
32
32
  bodyEncoding: "text" | "base64";
33
33
  };
34
- export type LighterceptorNetworkRecord = {
34
+ export type CapturedNetworkRecord = {
35
35
  url: string;
36
36
  source?: string;
37
37
  method: string;
38
38
  timestamp: number;
39
- response?: LighterceptorResponseRecord;
39
+ response?: CapturedResponseRecord;
40
40
  error?: string;
41
41
  };
42
42
  export type SnapshotData = {
@@ -44,7 +44,7 @@ export type SnapshotData = {
44
44
  title: string;
45
45
  capturedAt: string;
46
46
  fetchXhrRecords: FetchRecord[];
47
- networkRecords: LighterceptorNetworkRecord[];
47
+ networkRecords: CapturedNetworkRecord[];
48
48
  resources: Array<{
49
49
  url: string;
50
50
  localPath: string;
@@ -52,3 +52,6 @@ export type SnapshotData = {
52
52
  size?: number;
53
53
  }>;
54
54
  };
55
+ export interface NetworkInterceptorAdapter {
56
+ run(url: string): Promise<SnapshotData>;
57
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pagepocket/lib",
3
- "version": "0.4.0",
4
- "description": "",
3
+ "version": "0.4.2",
4
+ "description": "Library for rewriting HTML snapshots and inlining local resources.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
@@ -12,7 +12,7 @@
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
14
  "cheerio": "^1.0.0-rc.12",
15
- "uni-fs": "npm:@pagepocket/uni-fs@0.4.0"
15
+ "@pagepocket/uni-fs": "0.4.2"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/node": "^20.11.30",