@pagepocket/lib 0.7.1 → 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.
- package/README.md +7 -6
- package/dist/build-snapshot-from-bundle.d.ts +23 -0
- package/dist/build-snapshot-from-bundle.js +68 -0
- package/dist/builtin-blacklist.js +3 -6
- package/dist/bundle/from-network-store.d.ts +10 -0
- package/dist/bundle/from-network-store.js +26 -0
- package/dist/bundle/types.d.ts +32 -0
- package/dist/bundle/types.js +2 -0
- package/dist/capture/index.d.ts +14 -0
- package/dist/capture/index.js +86 -0
- package/dist/capture/memory-content-store.d.ts +4 -0
- package/dist/capture/memory-content-store.js +42 -0
- package/dist/capture/types.d.ts +61 -0
- package/dist/capture/types.js +2 -0
- package/dist/content-store.js +3 -8
- package/dist/content-type.d.ts +1 -1
- package/dist/content-type.js +2 -28
- package/dist/core/_impl/completion.d.ts +4 -0
- package/dist/core/_impl/completion.js +29 -0
- package/dist/core/_impl/content-store.d.ts +21 -0
- package/dist/core/_impl/content-store.js +91 -0
- package/dist/core/_impl/debug.d.ts +1 -0
- package/dist/core/_impl/debug.js +16 -0
- package/dist/core/_impl/inflight-tracker.d.ts +19 -0
- package/dist/core/_impl/inflight-tracker.js +48 -0
- package/dist/core/_impl/pagepocket.d.ts +27 -0
- package/dist/core/_impl/pagepocket.js +155 -0
- package/dist/core/capture/_impl/memory-content-store.d.ts +4 -0
- package/dist/core/capture/_impl/memory-content-store.js +42 -0
- package/dist/core/capture/_impl/types.d.ts +61 -0
- package/dist/core/capture/_impl/types.js +2 -0
- package/dist/core/capture/internal/memory-content-store.d.ts +4 -0
- package/dist/core/capture/internal/memory-content-store.js +42 -0
- package/dist/core/capture/internal/types.d.ts +61 -0
- package/dist/core/capture/internal/types.js +2 -0
- package/dist/core/capture/memory-content-store.d.ts +4 -0
- package/dist/core/capture/memory-content-store.js +38 -0
- package/dist/core/capture/types.d.ts +61 -0
- package/dist/core/capture/types.js +1 -0
- package/dist/core/completion.d.ts +4 -0
- package/dist/core/completion.js +23 -0
- package/dist/core/content-store.d.ts +21 -0
- package/dist/core/content-store.js +54 -0
- package/dist/core/debug.d.ts +1 -0
- package/dist/core/debug.js +12 -0
- package/dist/core/file-tree-merge.d.ts +2 -0
- package/dist/core/file-tree-merge.js +27 -0
- package/dist/core/file-tree.d.ts +36 -0
- package/dist/core/file-tree.js +1 -0
- package/dist/core/inflight-tracker.d.ts +19 -0
- package/dist/core/inflight-tracker.js +44 -0
- package/dist/core/internal/completion.d.ts +4 -0
- package/dist/core/internal/completion.js +29 -0
- package/dist/core/internal/content-store.d.ts +21 -0
- package/dist/core/internal/content-store.js +91 -0
- package/dist/core/internal/debug.d.ts +1 -0
- package/dist/core/internal/debug.js +16 -0
- package/dist/core/internal/inflight-tracker.d.ts +19 -0
- package/dist/core/internal/inflight-tracker.js +48 -0
- package/dist/core/internal/pagepocket.d.ts +27 -0
- package/dist/core/internal/pagepocket.js +155 -0
- package/dist/core/pagepocket.d.ts +38 -0
- package/dist/core/pagepocket.js +57 -0
- package/dist/core/plugin/_impl/context.d.ts +47 -0
- package/dist/core/plugin/_impl/context.js +142 -0
- package/dist/core/plugin/_impl/runner.d.ts +12 -0
- package/dist/core/plugin/_impl/runner.js +232 -0
- package/dist/core/plugin/_impl/types.d.ts +108 -0
- package/dist/core/plugin/_impl/types.js +2 -0
- package/dist/core/plugin/context.d.ts +47 -0
- package/dist/core/plugin/context.js +205 -0
- package/dist/core/plugin/internal/context.d.ts +47 -0
- package/dist/core/plugin/internal/context.js +142 -0
- package/dist/core/plugin/internal/runner.d.ts +12 -0
- package/dist/core/plugin/internal/runner.js +232 -0
- package/dist/core/plugin/internal/types.d.ts +108 -0
- package/dist/core/plugin/internal/types.js +2 -0
- package/dist/core/plugin/runner-utils.d.ts +9 -0
- package/dist/core/plugin/runner-utils.js +29 -0
- package/dist/core/plugin/runner.d.ts +12 -0
- package/dist/core/plugin/runner.js +118 -0
- package/dist/core/plugin/types.d.ts +117 -0
- package/dist/core/plugin/types.js +1 -0
- package/dist/core/runtime/types.d.ts +14 -0
- package/dist/core/runtime/types.js +2 -0
- package/dist/css-rewrite.js +1 -5
- package/dist/debug.d.ts +0 -1
- package/dist/debug.js +3 -5
- package/dist/files/types.d.ts +41 -0
- package/dist/files/types.js +2 -0
- package/dist/hack-html.js +20 -13
- package/dist/hackers/index.d.ts +1 -1
- package/dist/hackers/index.js +24 -27
- package/dist/hackers/preload-fetch.d.ts +1 -1
- package/dist/hackers/preload-fetch.js +1 -4
- package/dist/hackers/preload-xhr.d.ts +1 -1
- package/dist/hackers/preload-xhr.js +1 -4
- package/dist/hackers/replay-beacon.d.ts +1 -1
- package/dist/hackers/replay-beacon.js +1 -4
- package/dist/hackers/replay-block-text-fragment.d.ts +1 -1
- package/dist/hackers/replay-block-text-fragment.js +1 -4
- package/dist/hackers/replay-css-proxy.d.ts +1 -1
- package/dist/hackers/replay-css-proxy.js +9 -12
- package/dist/hackers/replay-dom-rewrite.d.ts +1 -1
- package/dist/hackers/replay-dom-rewrite.js +165 -154
- package/dist/hackers/replay-eventsource.d.ts +1 -1
- package/dist/hackers/replay-eventsource.js +1 -4
- package/dist/hackers/replay-fetch.d.ts +1 -1
- package/dist/hackers/replay-fetch.js +1 -4
- package/dist/hackers/replay-history-path.d.ts +1 -1
- package/dist/hackers/replay-history-path.js +1 -4
- package/dist/hackers/replay-svg-image.d.ts +1 -1
- package/dist/hackers/replay-svg-image.js +1 -4
- package/dist/hackers/replay-websocket.d.ts +1 -1
- package/dist/hackers/replay-websocket.js +1 -4
- package/dist/hackers/replay-xhr.d.ts +1 -1
- package/dist/hackers/replay-xhr.js +1 -4
- package/dist/hackers/types.js +1 -2
- package/dist/index.d.ts +29 -13
- package/dist/index.js +23 -44
- package/dist/kind-map.d.ts +68 -0
- package/dist/kind-map.js +58 -0
- package/dist/network-store.js +12 -1
- package/dist/pagepocket.d.ts +19 -4
- package/dist/pagepocket.js +36 -102
- package/dist/path-resolver.d.ts +1 -2
- package/dist/path-resolver.js +9 -16
- package/dist/plugin/builtins/build-snapshot-plugin.d.ts +5 -0
- package/dist/plugin/builtins/build-snapshot-plugin.js +84 -0
- package/dist/plugin/builtins/replace-elements-plugin.d.ts +8 -0
- package/dist/plugin/builtins/replace-elements-plugin.js +13 -0
- package/dist/plugin/builtins/to-directory-plugin.d.ts +7 -0
- package/dist/plugin/builtins/to-directory-plugin.js +20 -0
- package/dist/plugin/builtins/to-zip-plugin.d.ts +5 -0
- package/dist/plugin/builtins/to-zip-plugin.js +19 -0
- package/dist/plugin/context.d.ts +47 -0
- package/dist/plugin/context.js +142 -0
- package/dist/plugin/runner.d.ts +12 -0
- package/dist/plugin/runner.js +232 -0
- package/dist/plugin/types.d.ts +108 -0
- package/dist/plugin/types.js +2 -0
- package/dist/plugins/build-files-from-capture.d.ts +5 -0
- package/dist/plugins/build-files-from-capture.js +85 -0
- package/dist/plugins/build-warc.d.ts +5 -0
- package/dist/plugins/build-warc.js +225 -0
- package/dist/plugins/builtins/manifest.d.ts +2 -0
- package/dist/plugins/builtins/manifest.js +42 -0
- package/dist/plugins/builtins/snapshot-directory.d.ts +2 -0
- package/dist/plugins/builtins/snapshot-directory.js +24 -0
- package/dist/plugins/builtins/snapshot-zip.d.ts +2 -0
- package/dist/plugins/builtins/snapshot-zip.js +25 -0
- package/dist/plugins/capture-http-lighterceptor.d.ts +5 -0
- package/dist/plugins/capture-http-lighterceptor.js +85 -0
- package/dist/plugins/capture-http-puppeteer.d.ts +5 -0
- package/dist/plugins/capture-http-puppeteer.js +85 -0
- package/dist/plugins/host.d.ts +37 -0
- package/dist/plugins/host.js +105 -0
- package/dist/plugins/index.d.ts +6 -0
- package/dist/plugins/index.js +11 -0
- package/dist/plugins/ordering.d.ts +2 -0
- package/dist/plugins/ordering.js +19 -0
- package/dist/plugins/types.d.ts +51 -0
- package/dist/plugins/types.js +2 -0
- package/dist/preload.js +3 -7
- package/dist/replace-elements/actions.d.ts +5 -0
- package/dist/replace-elements/actions.js +86 -0
- package/dist/replace-elements/match.d.ts +5 -0
- package/dist/replace-elements/match.js +46 -0
- package/dist/replace-elements/normalize.d.ts +21 -0
- package/dist/replace-elements/normalize.js +50 -0
- package/dist/replace-elements.d.ts +1 -1
- package/dist/replace-elements.js +5 -185
- package/dist/replay/match-api.d.ts +10 -0
- package/dist/replay/match-api.js +162 -0
- package/dist/replay/templates/match-api-source.d.ts +1 -0
- package/dist/replay/templates/match-api-source.js +137 -0
- package/dist/replay/templates/replay-script-template.d.ts +5 -0
- package/dist/replay/templates/replay-script-template.js +337 -0
- package/dist/replay/templates/resource-proxy-script.d.ts +1 -0
- package/dist/replay/templates/resource-proxy-script.js +274 -0
- package/dist/replay-script.d.ts +3 -10
- package/dist/replay-script.js +11 -625
- package/dist/resource-filter.d.ts +1 -1
- package/dist/resource-filter.js +1 -5
- package/dist/resource-proxy/escape-percent.d.ts +1 -0
- package/dist/resource-proxy/escape-percent.js +12 -0
- package/dist/resource-proxy/multimap.d.ts +3 -0
- package/dist/resource-proxy/multimap.js +18 -0
- package/dist/resource-proxy/pathname-variants.d.ts +3 -0
- package/dist/resource-proxy/pathname-variants.js +54 -0
- package/dist/resource-proxy.d.ts +4 -2
- package/dist/resource-proxy.js +48 -117
- package/dist/resources.js +4 -42
- package/dist/rewrite-links/js-imports.d.ts +3 -0
- package/dist/rewrite-links/js-imports.js +56 -0
- package/dist/rewrite-links/link-rel.d.ts +2 -0
- package/dist/rewrite-links/link-rel.js +10 -0
- package/dist/rewrite-links/meta-refresh.d.ts +3 -0
- package/dist/rewrite-links/meta-refresh.js +22 -0
- package/dist/rewrite-links/skip.d.ts +1 -0
- package/dist/rewrite-links/skip.js +10 -0
- package/dist/rewrite-links/srcset.d.ts +3 -0
- package/dist/rewrite-links/srcset.js +63 -0
- package/dist/rewrite-links/url-resolve.d.ts +3 -0
- package/dist/rewrite-links/url-resolve.js +13 -0
- package/dist/rewrite-links.d.ts +3 -3
- package/dist/rewrite-links.js +31 -240
- package/dist/snapshot-builder/api.d.ts +3 -0
- package/dist/snapshot-builder/api.js +6 -0
- package/dist/snapshot-builder/build-snapshot.d.ts +3 -0
- package/dist/snapshot-builder/build-snapshot.js +138 -0
- package/dist/snapshot-builder/capture-index/index-capture.d.ts +13 -0
- package/dist/snapshot-builder/capture-index/index-capture.js +168 -0
- package/dist/snapshot-builder/capture-index/index.d.ts +2 -0
- package/dist/snapshot-builder/capture-index/index.js +1 -0
- package/dist/snapshot-builder/capture-index/types.d.ts +12 -0
- package/dist/snapshot-builder/capture-index/types.js +1 -0
- package/dist/snapshot-builder/capture-index.d.ts +12 -0
- package/dist/snapshot-builder/capture-index.js +173 -0
- package/dist/snapshot-builder/emit-document.d.ts +24 -0
- package/dist/snapshot-builder/emit-document.js +50 -0
- package/dist/snapshot-builder/grouping.d.ts +8 -0
- package/dist/snapshot-builder/grouping.js +87 -0
- package/dist/snapshot-builder/http.d.ts +6 -0
- package/dist/snapshot-builder/http.js +28 -0
- package/dist/snapshot-builder/index.d.ts +4 -0
- package/dist/snapshot-builder/index.js +2 -0
- package/dist/snapshot-builder/path-map.d.ts +3 -0
- package/dist/snapshot-builder/path-map.js +35 -0
- package/dist/snapshot-builder/resources-path.d.ts +23 -0
- package/dist/snapshot-builder/resources-path.js +47 -0
- package/dist/snapshot-builder/rewrite-resource.d.ts +18 -0
- package/dist/snapshot-builder/rewrite-resource.js +52 -0
- package/dist/snapshot-builder/types.d.ts +37 -0
- package/dist/snapshot-builder/types.js +2 -0
- package/dist/snapshot-builder.d.ts +12 -8
- package/dist/snapshot-builder.js +252 -27
- package/dist/types.d.ts +122 -78
- package/dist/types.js +4 -2
- package/dist/units/contracts-bridge.d.ts +76 -0
- package/dist/units/contracts-bridge.js +6 -0
- package/dist/units/index.d.ts +4 -0
- package/dist/units/index.js +2 -0
- package/dist/units/runner.d.ts +11 -0
- package/dist/units/runner.js +270 -0
- package/dist/units/types.d.ts +39 -0
- package/dist/units/types.js +1 -0
- package/dist/utils/streams.d.ts +2 -0
- package/dist/utils/streams.js +29 -0
- package/dist/utils.d.ts +35 -1
- package/dist/utils.js +107 -29
- package/dist/v3/contracts-bridge.d.ts +69 -0
- package/dist/v3/contracts-bridge.js +5 -0
- package/dist/v3/index.d.ts +4 -0
- package/dist/v3/index.js +2 -0
- package/dist/v3/runner.d.ts +20 -0
- package/dist/v3/runner.js +245 -0
- package/dist/v3/types.d.ts +39 -0
- package/dist/v3/types.js +1 -0
- package/dist/writers.js +3 -1
- package/package.json +11 -3
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { runCapture } from "../units/index.js";
|
|
2
|
+
export class PagePocket {
|
|
3
|
+
constructor(target, options) {
|
|
4
|
+
this.target = target;
|
|
5
|
+
this.options = options ?? {};
|
|
6
|
+
}
|
|
7
|
+
static fromURL(url, options) {
|
|
8
|
+
return new PagePocket({ kind: "url", url }, options);
|
|
9
|
+
}
|
|
10
|
+
static fromPuppeteerPage(page, options) {
|
|
11
|
+
return new PagePocket({ kind: "puppeteer-page", page }, options);
|
|
12
|
+
}
|
|
13
|
+
static fromCDPTab(tabId, options) {
|
|
14
|
+
return new PagePocket({ kind: "cdp-tab", tabId }, options);
|
|
15
|
+
}
|
|
16
|
+
static fromHTMLString(htmlString, options) {
|
|
17
|
+
const { baseUrl, url, ...rest } = options;
|
|
18
|
+
return new PagePocket({ kind: "html", htmlString, baseUrl, ...(url ? { url } : {}) }, rest);
|
|
19
|
+
}
|
|
20
|
+
static fromDocument(doc, options) {
|
|
21
|
+
const serialize = options.serialize ??
|
|
22
|
+
((value) => {
|
|
23
|
+
if (value && typeof value === "object" && "documentElement" in value) {
|
|
24
|
+
const el = value.documentElement;
|
|
25
|
+
if (el && typeof el.outerHTML === "string") {
|
|
26
|
+
return el.outerHTML;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
throw new Error("fromDocument requires options.serialize(doc) or doc.documentElement.outerHTML");
|
|
30
|
+
});
|
|
31
|
+
const htmlString = serialize(doc);
|
|
32
|
+
const { baseUrl, url, serialize: _serialize, ...rest } = options;
|
|
33
|
+
return new PagePocket({ kind: "html", htmlString, baseUrl, ...(url ? { url } : {}) }, rest);
|
|
34
|
+
}
|
|
35
|
+
async capture(options) {
|
|
36
|
+
const entry = this.target.kind === "url"
|
|
37
|
+
? { kind: "url", url: this.target.url }
|
|
38
|
+
: this.target.kind === "puppeteer-page"
|
|
39
|
+
? { kind: "puppeteer-page", page: this.target.page }
|
|
40
|
+
: this.target.kind === "cdp-tab"
|
|
41
|
+
? { kind: "cdp-tab", tabId: this.target.tabId }
|
|
42
|
+
: {
|
|
43
|
+
kind: "html-string",
|
|
44
|
+
baseUrl: this.target.baseUrl,
|
|
45
|
+
htmlString: this.target.htmlString,
|
|
46
|
+
...(this.target.url ? { url: this.target.url } : {})
|
|
47
|
+
};
|
|
48
|
+
const result = await runCapture({
|
|
49
|
+
entry,
|
|
50
|
+
pocketOptions: this.options,
|
|
51
|
+
options,
|
|
52
|
+
units: options.units,
|
|
53
|
+
plugins: options.plugins
|
|
54
|
+
});
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { NetworkEvent } from "@pagepocket/interceptor";
|
|
2
|
+
import type { ReplaceElementsConfig } from "../../../types";
|
|
3
|
+
import type { CaptureWithPluginsOptions, HtmlArtifact, PagePocketCaptureResult, PagePocketContext, PagePocketPlugin } from "./types";
|
|
4
|
+
type Hook<TArgs extends unknown[] = []> = (...args: TArgs) => void | Promise<void>;
|
|
5
|
+
type FinalizeHook = () => void | PagePocketCaptureResult | Promise<void | PagePocketCaptureResult>;
|
|
6
|
+
export type HookRegistries = {
|
|
7
|
+
init: Array<Hook>;
|
|
8
|
+
html: Array<Hook<[payload: {
|
|
9
|
+
html: HtmlArtifact;
|
|
10
|
+
}]>>;
|
|
11
|
+
beforeNetwork: Array<Hook>;
|
|
12
|
+
networkEvent: Array<Hook<[event: NetworkEvent]>>;
|
|
13
|
+
afterNetwork: Array<Hook>;
|
|
14
|
+
finalize: Array<FinalizeHook>;
|
|
15
|
+
};
|
|
16
|
+
export type DeferredTracker = {
|
|
17
|
+
defer(promise: Promise<unknown>): void;
|
|
18
|
+
awaitAll(): Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
type HtmlBarrier = {
|
|
21
|
+
whenHtml(): Promise<HtmlArtifact>;
|
|
22
|
+
resolveHtml(html: HtmlArtifact): void;
|
|
23
|
+
rejectHtml(error: Error): void;
|
|
24
|
+
};
|
|
25
|
+
type HtmlHooksDoneBarrier = {
|
|
26
|
+
whenDone(): Promise<void>;
|
|
27
|
+
resolve(): void;
|
|
28
|
+
reject(error: Error): void;
|
|
29
|
+
};
|
|
30
|
+
export type PagePocketContextInternal = PagePocketContext & {
|
|
31
|
+
_hooks: HookRegistries;
|
|
32
|
+
_deferred: DeferredTracker;
|
|
33
|
+
_replaceElements: ReplaceElementsConfig[];
|
|
34
|
+
_htmlBarrier: HtmlBarrier;
|
|
35
|
+
_htmlHooksDoneBarrier: HtmlHooksDoneBarrier;
|
|
36
|
+
_isFinished(): boolean;
|
|
37
|
+
_setFinished(): void;
|
|
38
|
+
};
|
|
39
|
+
export declare const createDeferredTracker: () => DeferredTracker;
|
|
40
|
+
export declare const createHookRegistries: () => HookRegistries;
|
|
41
|
+
export declare const createPagePocketContext: (input: {
|
|
42
|
+
entry: PagePocketContext["entry"];
|
|
43
|
+
options: CaptureWithPluginsOptions;
|
|
44
|
+
pocketOptions: PagePocketContext["pocketOptions"];
|
|
45
|
+
}) => PagePocketContextInternal;
|
|
46
|
+
export declare const resolveEnabledPlugins: (plugins: PagePocketPlugin[], ctx: PagePocketContext) => Promise<PagePocketPlugin[]>;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveEnabledPlugins = exports.createPagePocketContext = exports.createHookRegistries = exports.createDeferredTracker = void 0;
|
|
4
|
+
const createBarrier = () => {
|
|
5
|
+
let resolve = null;
|
|
6
|
+
let reject = null;
|
|
7
|
+
const promise = new Promise((res, rej) => {
|
|
8
|
+
resolve = res;
|
|
9
|
+
reject = rej;
|
|
10
|
+
});
|
|
11
|
+
return {
|
|
12
|
+
promise,
|
|
13
|
+
resolve: (value) => resolve?.(value),
|
|
14
|
+
reject: (error) => reject?.(error)
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
const createHtmlBarrier = (ctxRef) => {
|
|
18
|
+
const barrier = createBarrier();
|
|
19
|
+
return {
|
|
20
|
+
whenHtml: async () => {
|
|
21
|
+
if (ctxRef.html) {
|
|
22
|
+
return ctxRef.html;
|
|
23
|
+
}
|
|
24
|
+
return barrier.promise;
|
|
25
|
+
},
|
|
26
|
+
resolveHtml: (html) => {
|
|
27
|
+
barrier.resolve(html);
|
|
28
|
+
},
|
|
29
|
+
rejectHtml: (error) => {
|
|
30
|
+
barrier.reject(error);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
const createHtmlHooksDoneBarrier = () => {
|
|
35
|
+
const barrier = createBarrier();
|
|
36
|
+
return {
|
|
37
|
+
whenDone: async () => barrier.promise,
|
|
38
|
+
resolve: () => barrier.resolve(undefined),
|
|
39
|
+
reject: (error) => barrier.reject(error)
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const createDeferredTracker = () => {
|
|
43
|
+
const promises = new Set();
|
|
44
|
+
return {
|
|
45
|
+
defer(promise) {
|
|
46
|
+
promises.add(promise);
|
|
47
|
+
promise.finally(() => promises.delete(promise));
|
|
48
|
+
},
|
|
49
|
+
async awaitAll() {
|
|
50
|
+
await Promise.allSettled(Array.from(promises));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
exports.createDeferredTracker = createDeferredTracker;
|
|
55
|
+
const createHookRegistries = () => ({
|
|
56
|
+
init: [],
|
|
57
|
+
html: [],
|
|
58
|
+
beforeNetwork: [],
|
|
59
|
+
networkEvent: [],
|
|
60
|
+
afterNetwork: [],
|
|
61
|
+
finalize: []
|
|
62
|
+
});
|
|
63
|
+
exports.createHookRegistries = createHookRegistries;
|
|
64
|
+
const createPagePocketContext = (input) => {
|
|
65
|
+
const state = {};
|
|
66
|
+
const hooks = (0, exports.createHookRegistries)();
|
|
67
|
+
const deferred = (0, exports.createDeferredTracker)();
|
|
68
|
+
const replaceElements = [];
|
|
69
|
+
let finished = false;
|
|
70
|
+
const ctx = {
|
|
71
|
+
entry: input.entry,
|
|
72
|
+
options: input.options,
|
|
73
|
+
pocketOptions: input.pocketOptions,
|
|
74
|
+
state,
|
|
75
|
+
_hooks: hooks,
|
|
76
|
+
_deferred: deferred,
|
|
77
|
+
_replaceElements: replaceElements,
|
|
78
|
+
_isFinished: () => finished,
|
|
79
|
+
_setFinished: () => {
|
|
80
|
+
finished = true;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const htmlBarrier = createHtmlBarrier(ctx);
|
|
84
|
+
const htmlHooksDoneBarrier = createHtmlHooksDoneBarrier();
|
|
85
|
+
ctx._htmlBarrier = htmlBarrier;
|
|
86
|
+
ctx._htmlHooksDoneBarrier = htmlHooksDoneBarrier;
|
|
87
|
+
ctx.whenHtml = async () => htmlBarrier.whenHtml();
|
|
88
|
+
ctx.whenHtmlHooksDone = async () => {
|
|
89
|
+
await htmlBarrier.whenHtml();
|
|
90
|
+
return htmlHooksDoneBarrier.whenDone();
|
|
91
|
+
};
|
|
92
|
+
ctx.onInit = (handler) => {
|
|
93
|
+
hooks.init.push(handler);
|
|
94
|
+
};
|
|
95
|
+
ctx.onHtml = (handler) => {
|
|
96
|
+
hooks.html.push(handler);
|
|
97
|
+
};
|
|
98
|
+
ctx.onBeforeNetwork = (handler) => {
|
|
99
|
+
hooks.beforeNetwork.push(handler);
|
|
100
|
+
};
|
|
101
|
+
ctx.onNetworkEvent = (handler) => {
|
|
102
|
+
hooks.networkEvent.push(handler);
|
|
103
|
+
};
|
|
104
|
+
ctx.onAfterNetwork = (handler) => {
|
|
105
|
+
hooks.afterNetwork.push(handler);
|
|
106
|
+
};
|
|
107
|
+
ctx.onFinalize = (handler) => {
|
|
108
|
+
hooks.finalize.push(handler);
|
|
109
|
+
};
|
|
110
|
+
ctx.setHtml = (next) => {
|
|
111
|
+
ctx.html = next;
|
|
112
|
+
htmlBarrier.resolveHtml(next);
|
|
113
|
+
};
|
|
114
|
+
ctx.addReplaceElements = (rules) => {
|
|
115
|
+
replaceElements.push(rules);
|
|
116
|
+
};
|
|
117
|
+
ctx.finish = (result) => {
|
|
118
|
+
if (finished) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
ctx.result = result;
|
|
122
|
+
finished = true;
|
|
123
|
+
};
|
|
124
|
+
ctx.defer = (promise) => {
|
|
125
|
+
deferred.defer(promise);
|
|
126
|
+
};
|
|
127
|
+
return ctx;
|
|
128
|
+
};
|
|
129
|
+
exports.createPagePocketContext = createPagePocketContext;
|
|
130
|
+
const resolveEnabledPlugins = async (plugins, ctx) => {
|
|
131
|
+
const enabled = [];
|
|
132
|
+
for (const plugin of plugins) {
|
|
133
|
+
const gate = plugin.enabled;
|
|
134
|
+
if (gate === false) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// Default enabled when gate is undefined.
|
|
138
|
+
enabled.push(plugin);
|
|
139
|
+
}
|
|
140
|
+
return enabled;
|
|
141
|
+
};
|
|
142
|
+
exports.resolveEnabledPlugins = resolveEnabledPlugins;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InterceptTarget, NetworkEvent } from "@pagepocket/interceptor";
|
|
2
|
+
import type { CaptureWithPluginsOptions, PagePocketCaptureResult } from "./types";
|
|
3
|
+
type RunnerInput = {
|
|
4
|
+
pocket: {
|
|
5
|
+
interceptedRequestEvents(): AsyncIterable<NetworkEvent>;
|
|
6
|
+
};
|
|
7
|
+
pocketOptions: import("../../../types").PagePocketOptions;
|
|
8
|
+
target: InterceptTarget;
|
|
9
|
+
options: CaptureWithPluginsOptions;
|
|
10
|
+
};
|
|
11
|
+
export declare const captureWithPlugins: (input: RunnerInput) => Promise<PagePocketCaptureResult>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.captureWithPlugins = void 0;
|
|
4
|
+
const completion_1 = require("../../completion");
|
|
5
|
+
const debug_1 = require("../../debug");
|
|
6
|
+
const inflight_tracker_1 = require("../../inflight-tracker");
|
|
7
|
+
const context_1 = require("./context");
|
|
8
|
+
const runHandlersSequentially = async (handlers, args, ctx) => {
|
|
9
|
+
for (const handler of handlers) {
|
|
10
|
+
if (ctx._isFinished()) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
await handler(...args);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const runFinalizeHandlers = async (ctx) => {
|
|
17
|
+
for (const handler of ctx._hooks.finalize) {
|
|
18
|
+
if (ctx._isFinished()) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const result = await handler();
|
|
22
|
+
if (result) {
|
|
23
|
+
ctx.finish(result);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const pluginLabel = (plugin) => {
|
|
29
|
+
const ctor = plugin.constructor;
|
|
30
|
+
const ctorName = ctor && typeof ctor.name === "string" ? ctor.name : undefined;
|
|
31
|
+
return {
|
|
32
|
+
name: plugin.name,
|
|
33
|
+
ctorName,
|
|
34
|
+
enabled: plugin.enabled
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const captureWithPlugins = async (input) => {
|
|
38
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] capture start", {
|
|
39
|
+
targetKind: input.target.kind,
|
|
40
|
+
adapter: input.options.interceptor?.name,
|
|
41
|
+
pluginCount: input.options.plugins.length
|
|
42
|
+
});
|
|
43
|
+
const plugins = input.options.plugins;
|
|
44
|
+
const ctx = (0, context_1.createPagePocketContext)({
|
|
45
|
+
entry: input.target.kind === "url"
|
|
46
|
+
? { kind: "url", url: input.target.url }
|
|
47
|
+
: input.target.kind === "puppeteer-page"
|
|
48
|
+
? { kind: "puppeteer-page", page: input.target.page }
|
|
49
|
+
: input.target.kind === "cdp-tab"
|
|
50
|
+
? { kind: "cdp-tab", tabId: input.target.tabId }
|
|
51
|
+
: input.target.kind === "html"
|
|
52
|
+
? { kind: "html-string", baseUrl: input.target.baseUrl, url: input.target.url }
|
|
53
|
+
: (() => {
|
|
54
|
+
throw new Error(`Unsupported target kind: ${input.target.kind}`);
|
|
55
|
+
})(),
|
|
56
|
+
options: input.options,
|
|
57
|
+
pocketOptions: input.pocketOptions
|
|
58
|
+
});
|
|
59
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] plugins configured", plugins.map(pluginLabel));
|
|
60
|
+
const allPlugins = await (0, context_1.resolveEnabledPlugins)(plugins, ctx);
|
|
61
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] plugins enabled", allPlugins.map(pluginLabel));
|
|
62
|
+
for (const plugin of allPlugins) {
|
|
63
|
+
if (ctx._isFinished()) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] plugin.apply start", pluginLabel(plugin));
|
|
67
|
+
await plugin.apply(ctx);
|
|
68
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] plugin.apply done", pluginLabel(plugin));
|
|
69
|
+
}
|
|
70
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=init start", { count: ctx._hooks.init.length });
|
|
71
|
+
await runHandlersSequentially(ctx._hooks.init, [], ctx);
|
|
72
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=init done");
|
|
73
|
+
const interceptor = input.options.interceptor;
|
|
74
|
+
if (!interceptor) {
|
|
75
|
+
// HTML-only flow.
|
|
76
|
+
if (input.target.kind !== "html") {
|
|
77
|
+
throw new Error("options.interceptor is required for non-HTML entrypoints.");
|
|
78
|
+
}
|
|
79
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=html (no interceptor) start");
|
|
80
|
+
ctx.setHtml({
|
|
81
|
+
htmlString: input.target.htmlString,
|
|
82
|
+
baseUrl: input.target.baseUrl,
|
|
83
|
+
url: input.target.url,
|
|
84
|
+
contentType: "text/html"
|
|
85
|
+
});
|
|
86
|
+
try {
|
|
87
|
+
await runHandlersSequentially(ctx._hooks.html, [{ html: ctx.html }], ctx);
|
|
88
|
+
ctx._htmlHooksDoneBarrier.resolve();
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
92
|
+
ctx._htmlHooksDoneBarrier.reject(err);
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
95
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=html (no interceptor) done");
|
|
96
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=finalize start", {
|
|
97
|
+
count: ctx._hooks.finalize.length
|
|
98
|
+
});
|
|
99
|
+
await runFinalizeHandlers(ctx);
|
|
100
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=finalize done", { resultKind: ctx.result?.kind });
|
|
101
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] awaiting deferred work");
|
|
102
|
+
await ctx._deferred.awaitAll();
|
|
103
|
+
if (!ctx.result) {
|
|
104
|
+
throw new Error("No plugin produced a terminal result.");
|
|
105
|
+
}
|
|
106
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] capture done", { resultKind: ctx.result.kind });
|
|
107
|
+
return ctx.result;
|
|
108
|
+
}
|
|
109
|
+
const completionStrategies = (0, completion_1.normalizeCompletion)(input.options.completion);
|
|
110
|
+
const idleMs = input.options.timeoutMs ?? 5000;
|
|
111
|
+
const maxDurationMs = input.options.maxDurationMs;
|
|
112
|
+
const completion = completionStrategies.length > 0
|
|
113
|
+
? completionStrategies
|
|
114
|
+
: [(0, completion_1.networkIdle)(idleMs), ...(maxDurationMs !== undefined ? [(0, completion_1.timeout)(maxDurationMs)] : [])];
|
|
115
|
+
let stopped = false;
|
|
116
|
+
const inflightTracker = new inflight_tracker_1.InflightTracker();
|
|
117
|
+
const onEvent = async (event) => {
|
|
118
|
+
inflightTracker.handleEvent(event);
|
|
119
|
+
await runHandlersSequentially(ctx._hooks.networkEvent, [event], ctx);
|
|
120
|
+
};
|
|
121
|
+
const handlers = {
|
|
122
|
+
onEvent(event) {
|
|
123
|
+
if (ctx._isFinished()) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
input.pocket._emitNetworkEvent(event);
|
|
127
|
+
void onEvent(event);
|
|
128
|
+
},
|
|
129
|
+
onError(error) {
|
|
130
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] interceptor error", error);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=session start");
|
|
134
|
+
const session = await interceptor.start(input.target, handlers, {
|
|
135
|
+
timeoutMs: input.options.timeoutMs,
|
|
136
|
+
maxDurationMs: input.options.maxDurationMs
|
|
137
|
+
});
|
|
138
|
+
try {
|
|
139
|
+
if (input.target.kind === "url" && session.navigate) {
|
|
140
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=navigate start", { url: input.target.url });
|
|
141
|
+
await session.navigate(input.target.url);
|
|
142
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=navigate done");
|
|
143
|
+
}
|
|
144
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=waitForHtml start");
|
|
145
|
+
const html = await session.waitForHtml();
|
|
146
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=waitForHtml done", {
|
|
147
|
+
url: html.url,
|
|
148
|
+
baseUrl: html.baseUrl,
|
|
149
|
+
contentType: html.contentType,
|
|
150
|
+
htmlBytes: html.htmlString.length
|
|
151
|
+
});
|
|
152
|
+
ctx.setHtml(html);
|
|
153
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=html start", { count: ctx._hooks.html.length });
|
|
154
|
+
try {
|
|
155
|
+
await runHandlersSequentially(ctx._hooks.html, [{ html }], ctx);
|
|
156
|
+
ctx._htmlHooksDoneBarrier.resolve();
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
160
|
+
ctx._htmlHooksDoneBarrier.reject(err);
|
|
161
|
+
throw err;
|
|
162
|
+
}
|
|
163
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=html done");
|
|
164
|
+
if (ctx._isFinished()) {
|
|
165
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] early finish after html", {
|
|
166
|
+
resultKind: ctx.result?.kind
|
|
167
|
+
});
|
|
168
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=finalize start", {
|
|
169
|
+
count: ctx._hooks.finalize.length
|
|
170
|
+
});
|
|
171
|
+
await runFinalizeHandlers(ctx);
|
|
172
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=finalize done", { resultKind: ctx.result?.kind });
|
|
173
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] awaiting deferred work");
|
|
174
|
+
await ctx._deferred.awaitAll();
|
|
175
|
+
if (!ctx.result) {
|
|
176
|
+
throw new Error("No plugin produced a terminal result.");
|
|
177
|
+
}
|
|
178
|
+
return ctx.result;
|
|
179
|
+
}
|
|
180
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=beforeNetwork start", {
|
|
181
|
+
count: ctx._hooks.beforeNetwork.length
|
|
182
|
+
});
|
|
183
|
+
await runHandlersSequentially(ctx._hooks.beforeNetwork, [], ctx);
|
|
184
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=beforeNetwork done");
|
|
185
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=startCapture start");
|
|
186
|
+
await session.startCapture();
|
|
187
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=startCapture done");
|
|
188
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=completion wait start", {
|
|
189
|
+
strategies: completion.length
|
|
190
|
+
});
|
|
191
|
+
if (completion.length === 1) {
|
|
192
|
+
await completion[0].wait({
|
|
193
|
+
now: () => Date.now(),
|
|
194
|
+
getStats: () => inflightTracker.getStats()
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
await Promise.race(completion.map((strategy) => strategy.wait({
|
|
199
|
+
now: () => Date.now(),
|
|
200
|
+
getStats: () => inflightTracker.getStats()
|
|
201
|
+
})));
|
|
202
|
+
}
|
|
203
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=completion wait done");
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
if (!stopped) {
|
|
207
|
+
stopped = true;
|
|
208
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=session stop start");
|
|
209
|
+
await session.stop();
|
|
210
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=session stop done");
|
|
211
|
+
}
|
|
212
|
+
input.pocket._closeNetworkEventStream();
|
|
213
|
+
}
|
|
214
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=afterNetwork start", {
|
|
215
|
+
count: ctx._hooks.afterNetwork.length
|
|
216
|
+
});
|
|
217
|
+
await runHandlersSequentially(ctx._hooks.afterNetwork, [], ctx);
|
|
218
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=afterNetwork done");
|
|
219
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=finalize start", {
|
|
220
|
+
count: ctx._hooks.finalize.length
|
|
221
|
+
});
|
|
222
|
+
await runFinalizeHandlers(ctx);
|
|
223
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] phase=finalize done", { resultKind: ctx.result?.kind });
|
|
224
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] awaiting deferred work");
|
|
225
|
+
await ctx._deferred.awaitAll();
|
|
226
|
+
if (!ctx.result) {
|
|
227
|
+
throw new Error("No plugin produced a terminal result.");
|
|
228
|
+
}
|
|
229
|
+
(0, debug_1.debugLog)("[pagepocket][plugin-runner] capture done", { resultKind: ctx.result.kind });
|
|
230
|
+
return ctx.result;
|
|
231
|
+
};
|
|
232
|
+
exports.captureWithPlugins = captureWithPlugins;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { NetworkEvent, NetworkInterceptorAdapter } from "@pagepocket/interceptor";
|
|
2
|
+
import type { ContentStore, PagePocketOptions, PathResolver, ReplaceElementsConfig, ResourceFilter } from "../../../types";
|
|
3
|
+
export type HtmlArtifact = {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
contentType?: string;
|
|
7
|
+
htmlString: string;
|
|
8
|
+
};
|
|
9
|
+
export type EntryInfo = {
|
|
10
|
+
kind: "url";
|
|
11
|
+
url: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "puppeteer-page";
|
|
14
|
+
page: unknown;
|
|
15
|
+
url?: string;
|
|
16
|
+
} | {
|
|
17
|
+
kind: "cdp-tab";
|
|
18
|
+
tabId: number;
|
|
19
|
+
url?: string;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "html-string";
|
|
22
|
+
baseUrl: string;
|
|
23
|
+
url?: string;
|
|
24
|
+
} | {
|
|
25
|
+
kind: "document";
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
url?: string;
|
|
28
|
+
};
|
|
29
|
+
export type PagePocketCaptureResult = {
|
|
30
|
+
kind: "raw";
|
|
31
|
+
outputDir: string;
|
|
32
|
+
meta?: unknown;
|
|
33
|
+
} | {
|
|
34
|
+
kind: "zip";
|
|
35
|
+
zip: {
|
|
36
|
+
data: Uint8Array | Blob;
|
|
37
|
+
outputPath: string;
|
|
38
|
+
};
|
|
39
|
+
meta?: unknown;
|
|
40
|
+
} | {
|
|
41
|
+
kind: "html";
|
|
42
|
+
html: string;
|
|
43
|
+
meta?: unknown;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "text";
|
|
46
|
+
text: string;
|
|
47
|
+
meta?: unknown;
|
|
48
|
+
} | {
|
|
49
|
+
kind: "custom";
|
|
50
|
+
value: unknown;
|
|
51
|
+
};
|
|
52
|
+
export interface CaptureWithPluginsOptions {
|
|
53
|
+
/** Needed only if plugins rely on network interception. */
|
|
54
|
+
interceptor?: NetworkInterceptorAdapter;
|
|
55
|
+
/** Plugins are executed sequentially in this order. */
|
|
56
|
+
plugins: PagePocketPlugin[];
|
|
57
|
+
/** Network completion. */
|
|
58
|
+
completion?: import("../../../types").CompletionStrategy | import("../../../types").CompletionStrategy[];
|
|
59
|
+
timeoutMs?: number;
|
|
60
|
+
maxDurationMs?: number;
|
|
61
|
+
/** Snapshot-related config (used by BuildSnapshotPlugin). */
|
|
62
|
+
filter?: ResourceFilter;
|
|
63
|
+
blacklist?: RegExp[];
|
|
64
|
+
pathResolver?: PathResolver;
|
|
65
|
+
contentStore?: ContentStore;
|
|
66
|
+
rewriteEntry?: boolean;
|
|
67
|
+
rewriteCSS?: boolean;
|
|
68
|
+
limits?: {
|
|
69
|
+
maxTotalBytes?: number;
|
|
70
|
+
maxSingleResourceBytes?: number;
|
|
71
|
+
maxResources?: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export interface PagePocketPlugin {
|
|
75
|
+
readonly name: string;
|
|
76
|
+
enabled?: boolean;
|
|
77
|
+
/** Register hook handlers on the context. */
|
|
78
|
+
apply(ctx: PagePocketContext): void | Promise<void>;
|
|
79
|
+
}
|
|
80
|
+
export interface PagePocketContext extends Record<string, unknown> {
|
|
81
|
+
entry: EntryInfo;
|
|
82
|
+
options: CaptureWithPluginsOptions;
|
|
83
|
+
pocketOptions: PagePocketOptions;
|
|
84
|
+
/** plugin shared mutable bag */
|
|
85
|
+
state: Record<string, unknown>;
|
|
86
|
+
html?: HtmlArtifact;
|
|
87
|
+
whenHtml(): Promise<HtmlArtifact>;
|
|
88
|
+
whenHtmlHooksDone(): Promise<void>;
|
|
89
|
+
onInit(handler: () => void | Promise<void>): void;
|
|
90
|
+
onHtml(handler: (payload: {
|
|
91
|
+
html: HtmlArtifact;
|
|
92
|
+
}) => void | Promise<void>): void;
|
|
93
|
+
onBeforeNetwork(handler: () => void | Promise<void>): void;
|
|
94
|
+
onNetworkEvent(handler: (event: NetworkEvent) => void | Promise<void>): void;
|
|
95
|
+
onAfterNetwork(handler: () => void | Promise<void>): void;
|
|
96
|
+
onFinalize(handler: () => void | PagePocketCaptureResult | Promise<void | PagePocketCaptureResult>): void;
|
|
97
|
+
/** Allow plugins to update the HTML artifact. */
|
|
98
|
+
setHtml(next: HtmlArtifact): void;
|
|
99
|
+
/** Register replaceElements rules for snapshot build. */
|
|
100
|
+
addReplaceElements(rules: ReplaceElementsConfig): void;
|
|
101
|
+
/** optional: broadcast network events */
|
|
102
|
+
network?: {
|
|
103
|
+
subscribe(): AsyncIterable<NetworkEvent>;
|
|
104
|
+
};
|
|
105
|
+
result?: PagePocketCaptureResult;
|
|
106
|
+
finish(result: PagePocketCaptureResult): void;
|
|
107
|
+
defer(promise: Promise<unknown>): void;
|
|
108
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { NetworkEvent } from "../../types.js";
|
|
2
|
+
import type { ReplaceElementsConfig } from "../../types.js";
|
|
3
|
+
import type { CaptureWithPluginsOptions, HtmlArtifact, PagePocketCaptureResult, PagePocketContext, PagePocketPlugin } from "./types.js";
|
|
4
|
+
type Hook<TArgs extends unknown[] = []> = (...args: TArgs) => void | Promise<void>;
|
|
5
|
+
type FinalizeHook = () => void | PagePocketCaptureResult | Promise<void | PagePocketCaptureResult>;
|
|
6
|
+
export type HookRegistries = {
|
|
7
|
+
init: Array<Hook>;
|
|
8
|
+
html: Array<Hook<[payload: {
|
|
9
|
+
html: HtmlArtifact;
|
|
10
|
+
}]>>;
|
|
11
|
+
beforeNetwork: Array<Hook>;
|
|
12
|
+
networkEvent: Array<Hook<[event: NetworkEvent]>>;
|
|
13
|
+
afterNetwork: Array<Hook>;
|
|
14
|
+
finalize: Array<FinalizeHook>;
|
|
15
|
+
};
|
|
16
|
+
export type DeferredTracker = {
|
|
17
|
+
defer(promise: Promise<unknown>): void;
|
|
18
|
+
awaitAll(): Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
type HtmlBarrier = {
|
|
21
|
+
whenHtml(): Promise<HtmlArtifact>;
|
|
22
|
+
resolveHtml(html: HtmlArtifact): void;
|
|
23
|
+
rejectHtml(error: Error): void;
|
|
24
|
+
};
|
|
25
|
+
type HtmlHooksDoneBarrier = {
|
|
26
|
+
whenDone(): Promise<void>;
|
|
27
|
+
resolve(): void;
|
|
28
|
+
reject(error: Error): void;
|
|
29
|
+
};
|
|
30
|
+
export type PagePocketContextInternal = PagePocketContext & {
|
|
31
|
+
_hooks: HookRegistries;
|
|
32
|
+
_deferred: DeferredTracker;
|
|
33
|
+
_replaceElements: ReplaceElementsConfig[];
|
|
34
|
+
_htmlBarrier: HtmlBarrier;
|
|
35
|
+
_htmlHooksDoneBarrier: HtmlHooksDoneBarrier;
|
|
36
|
+
_isFinished(): boolean;
|
|
37
|
+
_setFinished(): void;
|
|
38
|
+
};
|
|
39
|
+
export declare const createDeferredTracker: () => DeferredTracker;
|
|
40
|
+
export declare const createHookRegistries: () => HookRegistries;
|
|
41
|
+
export declare const createPagePocketContext: (input: {
|
|
42
|
+
entry: PagePocketContext["entry"];
|
|
43
|
+
options: CaptureWithPluginsOptions;
|
|
44
|
+
pocketOptions: PagePocketContext["pocketOptions"];
|
|
45
|
+
}) => PagePocketContextInternal;
|
|
46
|
+
export declare const resolveEnabledPlugins: (plugins: PagePocketPlugin[], _ctx: PagePocketContext) => Promise<PagePocketPlugin[]>;
|
|
47
|
+
export {};
|