@pagepocket/build-snapshot-unit 0.8.0

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.
@@ -0,0 +1,7 @@
1
+ import { type PagePocketContext, type PagePocketPlugin } from "@pagepocket/lib";
2
+ export type BuildSnapshotPluginOptions = {};
3
+ export declare class BuildSnapshotPlugin implements PagePocketPlugin {
4
+ readonly name = "plugin:build-snapshot";
5
+ constructor(options?: BuildSnapshotPluginOptions);
6
+ apply(ctx: PagePocketContext): void;
7
+ }
@@ -0,0 +1,62 @@
1
+ import { buildSnapshot, createDefaultPathResolver, createDefaultResourceFilter, debugLog } from "@pagepocket/lib";
2
+ export class BuildSnapshotPlugin {
3
+ constructor(options) {
4
+ this.name = "plugin:build-snapshot";
5
+ void options;
6
+ }
7
+ apply(ctx) {
8
+ const baseFilter = ctx.options.filter ?? createDefaultResourceFilter();
9
+ const blacklist = ctx.options.blacklist ?? [];
10
+ const isBlacklisted = (url) => typeof url === "string" && blacklist.some((pattern) => pattern.test(url));
11
+ const filter = blacklist.length === 0
12
+ ? baseFilter
13
+ : {
14
+ shouldSave(req, res) {
15
+ if (isBlacklisted(req.url)) {
16
+ debugLog("[pagepocket] blacklist match (skip save)", req.url);
17
+ return false;
18
+ }
19
+ return baseFilter.shouldSave(req, res);
20
+ }
21
+ };
22
+ const pathResolver = ctx.options.pathResolver ?? createDefaultPathResolver();
23
+ const rewriteEntry = ctx.options.rewriteEntry ?? true;
24
+ const rewriteCSS = ctx.options.rewriteCSS ?? true;
25
+ const limits = ctx.options.limits;
26
+ ctx.onFinalize(async () => {
27
+ const existingFiles = ctx.files;
28
+ if (existingFiles) {
29
+ return;
30
+ }
31
+ const capture = ctx.capture;
32
+ if (!capture) {
33
+ throw new Error("BuildSnapshotPlugin requires ctx.capture");
34
+ }
35
+ const entryUrl = ctx.entry.kind === "url"
36
+ ? ctx.entry.url
37
+ : ctx.entry.kind === "html-string"
38
+ ? (ctx.entry.url ?? ctx.entry.baseUrl)
39
+ : "";
40
+ const internal = ctx;
41
+ const replaceElements = internal._replaceElements && internal._replaceElements.length > 0
42
+ ? internal._replaceElements
43
+ : undefined;
44
+ const replaceElementsMerged = replaceElements
45
+ ? replaceElements.flat()
46
+ : undefined;
47
+ const files = await buildSnapshot({
48
+ entryUrl,
49
+ createdAt: Date.now(),
50
+ capture,
51
+ filter,
52
+ pathResolver,
53
+ rewriteEntry,
54
+ rewriteCSS,
55
+ replaceElements: replaceElementsMerged,
56
+ limits,
57
+ warnings: []
58
+ });
59
+ ctx.files = files;
60
+ });
61
+ }
62
+ }
@@ -0,0 +1,10 @@
1
+ import { Unit, type FileTree, type UnitPatch } from "@pagepocket/lib";
2
+ export declare class BuildSnapshotUnit extends Unit {
3
+ readonly id = "buildSnapshot";
4
+ readonly kind = "build.snapshot";
5
+ merge(returnValue: UnitPatch, pluginContributedValue?: UnitPatch): UnitPatch;
6
+ run(ctx: import("@pagepocket/lib").UnitContext, rt: import("@pagepocket/lib").UnitRuntime): Promise<{
7
+ files: FileTree;
8
+ html: {};
9
+ } | undefined>;
10
+ }
@@ -0,0 +1,82 @@
1
+ import { buildSnapshot, createDefaultPathResolver, createDefaultResourceFilter, debugLog, mergeFileTrees, Unit } from "@pagepocket/lib";
2
+ export class BuildSnapshotUnit extends Unit {
3
+ constructor() {
4
+ super(...arguments);
5
+ this.id = "buildSnapshot";
6
+ this.kind = "build.snapshot";
7
+ }
8
+ merge(returnValue, pluginContributedValue = {}) {
9
+ const mergedValue = { ...returnValue, ...pluginContributedValue };
10
+ const returnFiles = returnValue.files;
11
+ const pluginFiles = pluginContributedValue.files;
12
+ if (!isFileTree(returnFiles) || !isFileTree(pluginFiles)) {
13
+ return mergedValue;
14
+ }
15
+ return { ...mergedValue, files: mergeFileTrees(returnFiles, pluginFiles) };
16
+ }
17
+ async run(ctx, rt) {
18
+ if (ctx.value.files) {
19
+ return;
20
+ }
21
+ const baseFilter = rt.options.filter ?? createDefaultResourceFilter();
22
+ const blacklist = rt.options.blacklist ?? [];
23
+ const isBlacklisted = (url) => typeof url === "string" && blacklist.some((pattern) => pattern.test(url));
24
+ const filter = blacklist.length === 0
25
+ ? baseFilter
26
+ : {
27
+ shouldSave(req, res) {
28
+ if (isBlacklisted(req.url)) {
29
+ debugLog("[pagepocket] blacklist match (skip save)", req.url);
30
+ return false;
31
+ }
32
+ return baseFilter.shouldSave(req, res);
33
+ }
34
+ };
35
+ const pathResolver = rt.options.pathResolver ?? createDefaultPathResolver();
36
+ const rewriteEntry = rt.options.rewriteEntry ?? true;
37
+ const rewriteCSS = rt.options.rewriteCSS ?? true;
38
+ const limits = rt.options.limits;
39
+ const capture = ctx.value.capture;
40
+ if (!capture) {
41
+ throw new Error("BuildSnapshotUnit requires ctx.value.capture");
42
+ }
43
+ const entryUrl = rt.entry.kind === "url"
44
+ ? rt.entry.url
45
+ : rt.entry.kind === "html-string"
46
+ ? (rt.entry.url ?? rt.entry.baseUrl)
47
+ : "";
48
+ const replaceElements = await rt.elements.compile();
49
+ const replaceElementsFinal = replaceElements.length > 0 ? replaceElements : undefined;
50
+ const files = await buildSnapshot({
51
+ entryUrl,
52
+ createdAt: Date.now(),
53
+ capture,
54
+ filter,
55
+ pathResolver,
56
+ rewriteEntry,
57
+ rewriteCSS,
58
+ replaceElements: replaceElementsFinal,
59
+ limits,
60
+ warnings: []
61
+ });
62
+ const html = ctx.value.html;
63
+ if (!html) {
64
+ throw new Error("BuildSnapshotUnit requires ctx.value.html");
65
+ }
66
+ return { files, html };
67
+ }
68
+ }
69
+ const isFileTree = (v) => {
70
+ if (!v || typeof v !== "object") {
71
+ return false;
72
+ }
73
+ if (!("root" in v)) {
74
+ return false;
75
+ }
76
+ const root = v.root;
77
+ if (!root || typeof root !== "object") {
78
+ return false;
79
+ }
80
+ const r = root;
81
+ return r.kind === "directory" && typeof r.path === "string" && Array.isArray(r.entries);
82
+ };
@@ -0,0 +1 @@
1
+ export { BuildSnapshotUnit } from "./build-snapshot-unit.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { BuildSnapshotUnit } from "./build-snapshot-unit.js";
@@ -0,0 +1,10 @@
1
+ import type { PagePocketContext, PagePocketPlugin } from "@pagepocket/lib";
2
+ export type BuildSnapshotPluginOptions = {
3
+ enabled?: boolean;
4
+ };
5
+ export declare class BuildSnapshotPlugin implements PagePocketPlugin {
6
+ readonly name = "plugin:build-snapshot";
7
+ enabled?: boolean;
8
+ constructor(options?: BuildSnapshotPluginOptions);
9
+ apply(ctx: PagePocketContext): void;
10
+ }
package/dist/plugin.js ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BuildSnapshotPlugin = void 0;
4
+ const lib_1 = require("@pagepocket/lib");
5
+ class BuildSnapshotPlugin {
6
+ constructor(options) {
7
+ this.name = "plugin:build-snapshot";
8
+ this.enabled = options?.enabled;
9
+ }
10
+ apply(ctx) {
11
+ const contentStore = ctx.options.contentStore ?? new lib_1.HybridContentStore();
12
+ const baseFilter = ctx.options.filter ?? (0, lib_1.createDefaultResourceFilter)();
13
+ const blacklist = ctx.options.blacklist ?? [];
14
+ const isBlacklisted = (url) => typeof url === "string" && blacklist.some((pattern) => pattern.test(url));
15
+ const filter = blacklist.length === 0
16
+ ? baseFilter
17
+ : {
18
+ shouldSave(req, res) {
19
+ if (isBlacklisted(req.url)) {
20
+ (0, lib_1.debugLog)("[pagepocket] blacklist match (skip save)", req.url);
21
+ return false;
22
+ }
23
+ return baseFilter.shouldSave(req, res);
24
+ }
25
+ };
26
+ const pathResolver = ctx.options.pathResolver ?? (0, lib_1.createDefaultPathResolver)();
27
+ const rewriteEntry = ctx.options.rewriteEntry ?? true;
28
+ const rewriteCSS = ctx.options.rewriteCSS ?? true;
29
+ const limits = ctx.options.limits;
30
+ const store = new lib_1.NetworkStore({
31
+ contentStore,
32
+ filter,
33
+ limits
34
+ });
35
+ const inflightTracker = new lib_1.InflightTracker({
36
+ shouldIgnore: (event) => {
37
+ if (!isBlacklisted(event.url)) {
38
+ return false;
39
+ }
40
+ (0, lib_1.debugLog)("[pagepocket] blacklist match (ignore inflight)", event.url);
41
+ return true;
42
+ }
43
+ });
44
+ ctx.onNetworkEvent(async (event) => {
45
+ inflightTracker.handleEvent(event);
46
+ await store.handleEvent(event);
47
+ });
48
+ ctx.onFinalize(async () => {
49
+ const existingFiles = ctx.files;
50
+ if (existingFiles) {
51
+ return;
52
+ }
53
+ const entryUrl = ctx.entry.kind === "url"
54
+ ? ctx.entry.url
55
+ : ctx.entry.kind === "html-string"
56
+ ? (ctx.entry.url ?? ctx.entry.baseUrl)
57
+ : "";
58
+ const internal = ctx;
59
+ const replaceElements = internal._replaceElements && internal._replaceElements.length > 0
60
+ ? internal._replaceElements
61
+ : undefined;
62
+ const replaceElementsMerged = replaceElements
63
+ ? replaceElements.flat()
64
+ : undefined;
65
+ const snapshot = await (0, lib_1.buildSnapshot)({
66
+ entryUrl,
67
+ createdAt: Date.now(),
68
+ resources: store.getResources(),
69
+ apiEntries: store.getApiEntries(),
70
+ contentStore,
71
+ pathResolver,
72
+ rewriteEntry,
73
+ rewriteCSS,
74
+ replaceElements: replaceElementsMerged,
75
+ warnings: []
76
+ });
77
+ const files = {
78
+ root: {
79
+ kind: "directory",
80
+ path: "",
81
+ entries: snapshot.files.map((file) => ({
82
+ kind: "file",
83
+ path: file.path,
84
+ source: { kind: "content-ref", ref: file.source }
85
+ }))
86
+ },
87
+ content: snapshot.content
88
+ };
89
+ ctx.files = files;
90
+ });
91
+ }
92
+ }
93
+ exports.BuildSnapshotPlugin = BuildSnapshotPlugin;
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@pagepocket/build-snapshot-unit",
3
+ "version": "0.8.0",
4
+ "description": "PagePocket plugin: build snapshot",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "license": "ISC",
12
+ "dependencies": {
13
+ "@pagepocket/contracts": "0.8.0",
14
+ "@pagepocket/lib": "0.8.0"
15
+ },
16
+ "devDependencies": {
17
+ "typescript": "^5.4.5"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json",
21
+ "test": "node -e \"process.exit(0)\""
22
+ }
23
+ }