@plurnk/plurnk-schemes-http 0.1.0 → 0.2.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/SPEC.md CHANGED
@@ -7,7 +7,10 @@
7
7
  ```ts
8
8
  static manifest: SchemeManifest = {
9
9
  name: "http",
10
- channels: { body: "text/markdown", header: "text/markdown" },
10
+ // Seed defaults (pre-fetch placeholders). `body` is retyped per-call via
11
+ // notifyChunk's mimetype arg — to the response Content-Type, or text/html
12
+ // for a rendered page. `header` is always text/plain.
13
+ channels: { body: "application/octet-stream", header: "text/plain" },
11
14
  defaultChannel: "body",
12
15
  category: "data",
13
16
  scope: "session",
@@ -35,13 +38,14 @@ Results use the `passthrough` family (read-only / network shape) — http entrie
35
38
 
36
39
  READ and SEND[200] share one core:
37
40
 
38
- 1. `ctx.subscriptions.open(pathname, handle)` — registers the subscription for cancel routing; returns the run+teardown-composed `AbortSignal`. The handle's `cancel()` aborts a local `AbortController` wired to the `fetch`.
39
- 2. `fetch(url, { signal })` — GET (READ) or POST (SEND[200], body from `SendBody.raw`).
40
- 3. Response status + headers `ctx.subscriptions.notifyChunk("header", )`.
41
- 4. Body chunks → `ctx.subscriptions.notifyChunk("body", chunk)` as they arrive (fused append + stream/event).
42
- 5. `ctx.subscriptions.close("done", "HTTP <status>; <n> bytes")` on clean end; `close("error", reason)` on failure.
41
+ 1. `ctx.subscriptions.open(pathname, handle)` — registers the subscription for cancel routing; returns the run+teardown-composed `AbortSignal`. The handle's `cancel()` aborts a local `AbortController` wired to the `fetch`/render.
42
+ 2. `fetch(url, { signal })` — GET (READ) or POST (SEND[200], body from `SendBody.raw`); read the response `Content-Type`.
43
+ 3. **Render gate (§6):** a GET whose response is HTML routes to the render path; everything else (POST responses, non-HTML bodies) streams raw.
44
+ 4. Response status + headers → `notifyChunk("header", …, "text/plain")`.
45
+ 5. Body → `notifyChunk("body", chunk, mimetype)` labelled with its real type (the response Content-Type, or `text/html` rendered). Byte path streams chunks as they arrive; render path writes the serialized DOM in one chunk.
46
+ 6. `close("done", …)` on clean end; `close("error", reason)` on failure.
43
47
 
44
- Returns `102 Processing` on success (the subscription drives the channel content). The composed signal aborting (loop.cancel) and the local handle (SEND[499]) both tear the fetch down.
48
+ Returns `102 Processing` on success (the subscription drives the channel content). The composed signal aborting (loop.cancel) and the local handle (SEND[499]) both tear the fetch/render down.
45
49
 
46
50
  ## §4 Status mapping
47
51
 
@@ -57,6 +61,18 @@ Returns `102 Processing` on success (the subscription drives the channel content
57
61
 
58
62
  Error results carry a `scheme:http` `TelemetryEvent` (via `Results.error`).
59
63
 
60
- ## §5 No runtime dependencies
64
+ ## §5 Dependencies
61
65
 
62
- `fetch` / `AbortController` / `TextDecoder` / `ReadableStream` are Node ≥25 built-ins. The package declares only peer deps (`@plurnk/plurnk-schemes`, `@plurnk/plurnk-grammar`) — never pulls a transport library.
66
+ The **byte path** is dependency-free: `fetch` / `AbortController` / `TextDecoder` / `ReadableStream` are Node ≥25 built-ins.
67
+
68
+ The **render path** takes one runtime dependency, `playwright`, **lazy-imported** (`Browser.ts`) so only an actual render pays for it — a byte fetch never loads it. The chromium binary is optional: set `PLURNK_HTTP_PLAYWRIGHT_WS` to drive a remote CDP endpoint (shared chromium / Lightpanda / browserless) instead of launching locally. This is the conscious, scoped inversion of the original "no runtime deps" stance — rendering is acquisition, and acquisition is this scheme's job.
69
+
70
+ ## §6 Render lifecycle
71
+
72
+ `Browser` (`export default class`, barrel-exported as a standalone foundation) is the headless-Chromium render engine — ported from rummy.web's WebFetcher, render-only.
73
+
74
+ - **Gate:** a GET whose response `Content-Type` is `text/html` / `application/xhtml+xml` renders; the probe-fetch body is discarded and the browser does its own navigation. POST never renders.
75
+ - **Render:** warm chromium (one per `Browser`), per-run `BrowserContext` keyed on `ctx.runId`, navigate with `waitUntil: "networkidle"` + a salvage path (timed-out-but-rendered pages with substantive body text), serialize the final DOM via `page.content()`.
76
+ - **Body:** the serialized DOM is delivered as one `body` chunk labelled `text/html`; the mimetype layer projects everything (`content`/`symbols`/`deepXml`/embedding) off it. http never cleans or extracts — the body is the faithful, final page (schemes-http#1).
77
+ - **Config:** `PLURNK_HTTP_FETCH_TIMEOUT`, `PLURNK_HTTP_NO_SANDBOX`, `PLURNK_HTTP_CHROMIUM_HEAP_MB`, `PLURNK_HTTP_PLAYWRIGHT_WS`. Idle teardown after 15 min.
78
+ - **Cancel:** the composed `AbortSignal` / SEND[499] handle aborts the render by closing the page (in-flight `goto` rejects promptly).
@@ -0,0 +1,50 @@
1
+ interface PwResponse {
2
+ status(): number;
3
+ statusText(): string;
4
+ headers(): Record<string, string>;
5
+ }
6
+ interface PwPage {
7
+ goto(url: string, opts: {
8
+ waitUntil: "networkidle";
9
+ timeout: number;
10
+ }): Promise<PwResponse | null>;
11
+ content(): Promise<string>;
12
+ evaluate<T>(fn: () => T): Promise<T>;
13
+ close(): Promise<void>;
14
+ }
15
+ interface PwContext {
16
+ newPage(): Promise<PwPage>;
17
+ close(): Promise<void>;
18
+ }
19
+ interface PwBrowser {
20
+ newContext(): Promise<PwContext>;
21
+ on(event: "disconnected", cb: () => void): void;
22
+ close(): Promise<void>;
23
+ }
24
+ export interface ChromiumEngine {
25
+ launch(opts: {
26
+ headless: boolean;
27
+ args: ReadonlyArray<string>;
28
+ }): Promise<PwBrowser>;
29
+ connect(wsEndpoint: string): Promise<PwBrowser>;
30
+ }
31
+ export type ChromiumFactory = () => Promise<ChromiumEngine>;
32
+ export interface RenderResult {
33
+ readonly status: number;
34
+ readonly statusText: string;
35
+ readonly headers: ReadonlyArray<readonly [string, string]>;
36
+ readonly html: string;
37
+ }
38
+ export default class Browser {
39
+ #private;
40
+ constructor(factory?: ChromiumFactory);
41
+ render(url: string, { runId, signal, timeout }: {
42
+ runId: number;
43
+ signal?: AbortSignal;
44
+ timeout?: number;
45
+ }): Promise<RenderResult>;
46
+ closeContext(runId: number): void;
47
+ close(): Promise<void>;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=Browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Browser.d.ts","sourceRoot":"","sources":["../src/Browser.ts"],"names":[],"mappings":"AAmBA,UAAU,UAAU;IAChB,MAAM,IAAI,MAAM,CAAC;IACjB,UAAU,IAAI,MAAM,CAAC;IACrB,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AACD,UAAU,MAAM;IACZ,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,SAAS,EAAE,aAAa,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AACD,UAAU,SAAS;IACf,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AACD,UAAU,SAAS;IACf,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAChD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AACD,MAAM,WAAW,cAAc;IAC3B,MAAM,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACrF,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CACnD;AACD,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;AAO5D,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAwBD,MAAM,CAAC,OAAO,OAAO,OAAO;;gBAWZ,OAAO,GAAE,eAAgC;IAO/C,MAAM,CACR,GAAG,EAAE,MAAM,EACX,EAAE,KAAK,EAAE,MAAM,EAAE,OAAiE,EAAE,EAChF;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9D,OAAO,CAAC,YAAY,CAAC;IAwFxB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAe3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ/B"}
@@ -0,0 +1,176 @@
1
+ // Browser — the headless-Chromium render foundation, ported from
2
+ // rummy.web's WebFetcher (@possumtech/rummy.web, MIT, same author). A
3
+ // STANDALONE foundation, not Http-private: the render scheme drives it now,
4
+ // and a future plurnk browser-troubleshooting MCP sits on the same warm pool.
5
+ //
6
+ // Scope here is render-ONLY: navigate, let JS run + hydration settle, serialize
7
+ // the final DOM. It returns the true rendered page; it never cleans, strips,
8
+ // or extracts — projection (markdown/symbols/deepXml) is the mimetype layer's
9
+ // job, off the faithful body we hand over.
10
+ //
11
+ // Driver is Playwright, lazy-imported so only the render path pays for it (the
12
+ // raw-byte fetch path stays Node-builtin-only). The engine is reached through
13
+ // a minimal structural seam (`ChromiumEngine`) so it can be injected — fakes
14
+ // in unit tests, and a remote CDP endpoint (Lightpanda/browserless/shared
15
+ // chromium) swapped in via env with zero code change.
16
+ // Salvage threshold: a navigation that times out on networkidle but whose DOM
17
+ // already holds this much body text is the chatty-page case (long-poll, ad
18
+ // refresh, a server that never closes the stream) — the page rendered, the
19
+ // network just never settled. Below it we discard: too little to be sure the
20
+ // DOM ever rendered the article rather than a skeleton.
21
+ const SALVAGE_MIN_BODY_CHARS = 200;
22
+ const IDLE_TIMEOUT_MS = 15 * 60 * 1000;
23
+ const DEFAULT_TIMEOUT_MS = 30_000;
24
+ const numEnv = (key, fallback) => {
25
+ const raw = process.env[key];
26
+ if (raw === undefined)
27
+ return fallback;
28
+ const n = Number(raw);
29
+ if (Number.isNaN(n))
30
+ throw new Error(`Browser: ${key}=${raw} is not a number`);
31
+ return n;
32
+ };
33
+ // Default factory: lazy-import the real chromium. The cast bridges Playwright's
34
+ // full type to our structural view at the single trusted library boundary.
35
+ const defaultFactory = async () => (await import("playwright")).chromium;
36
+ export default class Browser {
37
+ #factory;
38
+ #browser = null;
39
+ #launching = null;
40
+ // One BrowserContext per run — cookies / cache / storage scoped to the run
41
+ // that opened it, no cross-run bleed. Closed by closeContext() on run end
42
+ // or abort. The browser process stays warm across all of them.
43
+ #contexts = new Map();
44
+ #idleTimer = null;
45
+ // Inject a factory in tests; production lazy-imports playwright.
46
+ constructor(factory = defaultFactory) {
47
+ this.#factory = factory;
48
+ }
49
+ // Render a URL to its final serialized DOM. Opens a page in the run's
50
+ // context, navigates with the settle+salvage strategy, serializes, closes
51
+ // the page. Throws on navigation failure (the caller maps it to a status).
52
+ async render(url, { runId, signal, timeout = numEnv("PLURNK_HTTP_FETCH_TIMEOUT", DEFAULT_TIMEOUT_MS) }) {
53
+ const context = await this.#getContext(runId);
54
+ const page = await context.newPage();
55
+ // Abort cascades by closing the page — an in-flight goto rejects with
56
+ // "Target closed", surfacing promptly instead of blocking on timeout.
57
+ const onAbort = () => { page.close().catch(() => { }); };
58
+ signal?.addEventListener("abort", onAbort, { once: true });
59
+ // Already aborted before the page opened: the listener won't fire
60
+ // retroactively, so close now — the navigation must not proceed.
61
+ if (signal?.aborted)
62
+ onAbort();
63
+ try {
64
+ const response = await this.#safeGoto(page, url, timeout);
65
+ const html = await page.content();
66
+ return {
67
+ status: response?.status() ?? 200,
68
+ statusText: response?.statusText() ?? "",
69
+ headers: response ? Object.entries(response.headers()) : [],
70
+ html,
71
+ };
72
+ }
73
+ finally {
74
+ signal?.removeEventListener("abort", onAbort);
75
+ await page.close().catch(() => { });
76
+ }
77
+ }
78
+ // page.goto with the salvage path. networkidle timing out while the DOM has
79
+ // already rendered substantive body text is the chatty-page case: the
80
+ // content is there even though the network never settled. readyState is
81
+ // unreliable (a never-ending stream stays `loading` forever); the load-
82
+ // bearing signal is the body's innerText length. Returns the Response on
83
+ // normal completion, null on salvage, and re-throws every other error.
84
+ async #safeGoto(page, url, timeout) {
85
+ try {
86
+ return await page.goto(url, { waitUntil: "networkidle", timeout });
87
+ }
88
+ catch (err) {
89
+ if (!(err instanceof Error) || err.name !== "TimeoutError")
90
+ throw err;
91
+ const bodyLen = await page
92
+ .evaluate(() => document?.body?.innerText?.length ?? 0)
93
+ .catch(() => 0);
94
+ if (bodyLen < SALVAGE_MIN_BODY_CHARS)
95
+ throw err;
96
+ return null;
97
+ }
98
+ }
99
+ // Get-or-launch the warm chromium. Connects to a remote CDP endpoint via
100
+ // PLURNK_HTTP_PLAYWRIGHT_WS if set (shared / Lightpanda / browserless),
101
+ // else launches locally. Single browser across all runs; per-run isolation
102
+ // is at the context layer. Relaunches if chromium dies (OOM/segfault/WS
103
+ // teardown) leaves the handle stale.
104
+ async #getBrowser() {
105
+ this.#touchIdle();
106
+ if (this.#browser)
107
+ return this.#browser;
108
+ this.#launching ??= (async () => {
109
+ const chromium = await this.#factory();
110
+ const ws = process.env.PLURNK_HTTP_PLAYWRIGHT_WS;
111
+ if (ws)
112
+ return chromium.connect(ws);
113
+ const args = [];
114
+ if (process.env.PLURNK_HTTP_NO_SANDBOX === "1")
115
+ args.push("--no-sandbox");
116
+ const heapMb = process.env.PLURNK_HTTP_CHROMIUM_HEAP_MB;
117
+ if (heapMb)
118
+ args.push(`--js-flags=--max-old-space-size=${heapMb}`);
119
+ return chromium.launch({ headless: true, args });
120
+ })();
121
+ const browser = await this.#launching;
122
+ this.#launching = null;
123
+ browser.on("disconnected", () => {
124
+ if (this.#browser === browser) {
125
+ this.#browser = null;
126
+ this.#contexts.clear();
127
+ }
128
+ });
129
+ this.#browser = browser;
130
+ return browser;
131
+ }
132
+ // Get-or-create the run's BrowserContext. Desktop default (no device
133
+ // emulation) — we render the true page, not a mobile-extraction view.
134
+ async #getContext(runId) {
135
+ this.#touchIdle();
136
+ const existing = this.#contexts.get(runId);
137
+ if (existing)
138
+ return existing;
139
+ const browser = await this.#getBrowser();
140
+ const context = await browser.newContext();
141
+ this.#contexts.set(runId, context);
142
+ return context;
143
+ }
144
+ // Drop the run's context (run end or abort). Closing it cascades to any
145
+ // in-flight page in that context. Fire-and-forget.
146
+ closeContext(runId) {
147
+ const context = this.#contexts.get(runId);
148
+ if (!context)
149
+ return;
150
+ this.#contexts.delete(runId);
151
+ context.close().catch(() => { });
152
+ }
153
+ #touchIdle() {
154
+ if (this.#idleTimer)
155
+ clearTimeout(this.#idleTimer);
156
+ this.#idleTimer = setTimeout(() => { this.close().catch(() => { }); }, IDLE_TIMEOUT_MS);
157
+ this.#idleTimer.unref?.();
158
+ }
159
+ // Tear everything down: per-run contexts then the browser. In CDP mode
160
+ // close() disconnects the local handle without shutting the remote down.
161
+ async close() {
162
+ if (this.#idleTimer) {
163
+ clearTimeout(this.#idleTimer);
164
+ this.#idleTimer = null;
165
+ }
166
+ const contexts = [...this.#contexts.values()];
167
+ this.#contexts.clear();
168
+ await Promise.allSettled(contexts.map((c) => c.close()));
169
+ if (this.#browser) {
170
+ await this.#browser.close().catch(() => { });
171
+ this.#browser = null;
172
+ }
173
+ this.#launching = null;
174
+ }
175
+ }
176
+ //# sourceMappingURL=Browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Browser.js","sourceRoot":"","sources":["../src/Browser.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,sEAAsE;AACtE,4EAA4E;AAC5E,8EAA8E;AAC9E,EAAE;AACF,gFAAgF;AAChF,6EAA6E;AAC7E,8EAA8E;AAC9E,2CAA2C;AAC3C,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,0EAA0E;AAC1E,sDAAsD;AA2CtD,8EAA8E;AAC9E,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,wDAAwD;AACxD,MAAM,sBAAsB,GAAG,GAAG,CAAC;AACnC,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACvC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,QAAgB,EAAU,EAAE;IACrD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,GAAG,kBAAkB,CAAC,CAAC;IAC/E,OAAO,CAAC,CAAC;AACb,CAAC,CAAC;AAEF,gFAAgF;AAChF,2EAA2E;AAC3E,MAAM,cAAc,GAAoB,KAAK,IAAI,EAAE,CAC/C,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,QAAqC,CAAC;AAEvE,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,QAAQ,CAAkB;IAC1B,QAAQ,GAAqB,IAAI,CAAC;IAClC,UAAU,GAA8B,IAAI,CAAC;IAC7C,2EAA2E;IAC3E,0EAA0E;IAC1E,+DAA+D;IAC/D,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC;IACzC,UAAU,GAAyC,IAAI,CAAC;IAExD,iEAAiE;IACjE,YAAY,UAA2B,cAAc;QACjD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;IAED,sEAAsE;IACtE,0EAA0E;IAC1E,2EAA2E;IAC3E,KAAK,CAAC,MAAM,CACR,GAAW,EACX,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,EACrB;QAE7D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,sEAAsE;QACtE,sEAAsE;QACtE,MAAM,OAAO,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,kEAAkE;QAClE,iEAAiE;QACjE,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,OAAO;gBACH,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAG;gBACjC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE;gBACxC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;gBAC3D,IAAI;aACP,CAAC;QACN,CAAC;gBAAS,CAAC;YACP,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,sEAAsE;IACtE,wEAAwE;IACxE,wEAAwE;IACxE,yEAAyE;IACzE,uEAAuE;IACvE,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,GAAW,EAAE,OAAe;QACtD,IAAI,CAAC;YACD,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc;gBAAE,MAAM,GAAG,CAAC;YACtE,MAAM,OAAO,GAAG,MAAM,IAAI;iBACrB,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC,CAAC;iBACtD,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,OAAO,GAAG,sBAAsB;gBAAE,MAAM,GAAG,CAAC;YAChD,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,wEAAwE;IACxE,2EAA2E;IAC3E,wEAAwE;IACxE,qCAAqC;IACrC,KAAK,CAAC,WAAW;QACb,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACxC,IAAI,CAAC,UAAU,KAAK,CAAC,KAAK,IAAI,EAAE;YAC5B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;YACjD,IAAI,EAAE;gBAAE,OAAO,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,GAAG;gBAAE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;YACxD,IAAI,MAAM;gBAAE,IAAI,CAAC,IAAI,CAAC,mCAAmC,MAAM,EAAE,CAAC,CAAC;YACnE,OAAO,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC;QACL,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YAC3B,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,qEAAqE;IACrE,sEAAsE;IACtE,KAAK,CAAC,WAAW,CAAC,KAAa;QAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,wEAAwE;IACxE,mDAAmD;IACnD,YAAY,CAAC,KAAa;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,UAAU;QACN,IAAI,IAAI,CAAC,UAAU;YAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;QACvF,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;IAC9B,CAAC;IAED,uEAAuE;IACvE,yEAAyE;IACzE,KAAK,CAAC,KAAK;QACP,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAAC,CAAC;QAC/E,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAAC,CAAC;QACzF,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IAC3B,CAAC;CACJ"}
package/dist/Http.d.ts CHANGED
@@ -1,9 +1,18 @@
1
1
  import type { SchemeCtx, PassthroughResult, SchemeManifest } from "@plurnk/plurnk-schemes";
2
2
  import type { ReadStatement, SendStatement } from "@plurnk/plurnk-grammar";
3
+ import { type RenderResult } from "./Browser.ts";
4
+ interface Renderer {
5
+ render(url: string, opts: {
6
+ runId: number;
7
+ signal?: AbortSignal;
8
+ }): Promise<RenderResult>;
9
+ }
3
10
  export default class Http {
4
11
  #private;
5
12
  static manifest: SchemeManifest;
13
+ constructor(browser?: Renderer);
6
14
  read(statement: ReadStatement, ctx: SchemeCtx): Promise<PassthroughResult>;
7
15
  send(statement: SendStatement, ctx: SchemeCtx): Promise<PassthroughResult>;
8
16
  }
17
+ export {};
9
18
  //# sourceMappingURL=Http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../src/Http.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACR,SAAS,EAET,iBAAiB,EACjB,cAAc,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAW,MAAM,wBAAwB,CAAC;AAMpF,MAAM,CAAC,OAAO,OAAO,IAAI;;IACrB,MAAM,CAAC,QAAQ,EAAE,cAAc,CAe7B;IAII,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAa1E,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA2FnF"}
1
+ {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../src/Http.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACR,SAAS,EAET,iBAAiB,EACjB,cAAc,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAW,MAAM,wBAAwB,CAAC;AACpF,OAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAO1D,UAAU,QAAQ;IACd,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC7F;AAED,MAAM,CAAC,OAAO,OAAO,IAAI;;IACrB,MAAM,CAAC,QAAQ,EAAE,cAAc,CAiB7B;gBAKU,OAAO,GAAE,QAAwB;IAOvC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAa1E,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAiHnF"}
package/dist/Http.js CHANGED
@@ -17,17 +17,21 @@
17
17
  // Network exception: SPEC §5 forbids opening connections "unless specifically
18
18
  // a network scheme." This IS that scheme — `fetch` is the whole point. No
19
19
  // runtime deps: `fetch` and `AbortController` are Node built-ins.
20
+ var _a;
20
21
  import { Results } from "@plurnk/plurnk-schemes";
22
+ import Browser from "./Browser.js";
21
23
  // The channel the response body streams into, and the header metadata channel.
22
24
  const BODY = "body";
23
25
  const HEADER = "header";
24
- export default class Http {
26
+ class Http {
25
27
  static manifest = {
26
28
  name: "http",
27
- // body: the response payload (mimetype is per-call — set from the
28
- // response Content-Type so channels declares the names, the write
29
- // carries the actual mimetype). header: the response status line + headers.
30
- channels: { [BODY]: "text/markdown", [HEADER]: "text/markdown" },
29
+ // Channel mimetypes here are SEED DEFAULTS (pre-fetch placeholders).
30
+ // body is retyped per-call via notifyChunk's mimetype arg to the real
31
+ // response Content-Type, or text/html for a rendered page; octet-stream
32
+ // is the honest "unknown until fetched". header is always the status
33
+ // line + headers (text/plain).
34
+ channels: { [BODY]: "application/octet-stream", [HEADER]: "text/plain" },
31
35
  defaultChannel: BODY,
32
36
  category: "data",
33
37
  scope: "session",
@@ -38,13 +42,20 @@ export default class Http {
38
42
  requiresWeb: true, // excluded under the loop's noWeb flag
39
43
  },
40
44
  };
41
- // READ fetch + stream the response body. Returns 102 Processing; the
42
- // subscription drives the channel content the model sees next turn.
45
+ // The render foundation (lazy chromium). Injectable for tests; one warm
46
+ // pool per Http instance, shared across this scheme's fetches.
47
+ #browser;
48
+ constructor(browser = new Browser()) {
49
+ this.#browser = browser;
50
+ }
51
+ // READ → fetch; an HTML page is rendered, everything else streams raw.
52
+ // Returns 102 Processing; the subscription drives the channel content the
53
+ // model sees next turn.
43
54
  async read(statement, ctx) {
44
55
  if (statement.target === null || statement.target.kind !== "url") {
45
- return Http.#bad(400, "http", "bad_target", "READ requires an http(s):// URL target");
56
+ return _a.#bad(400, "http", "bad_target", "READ requires an http(s):// URL target");
46
57
  }
47
- return Http.#fetchStream(statement.target, ctx, undefined);
58
+ return this.#fetchStream(statement.target, ctx, undefined);
48
59
  }
49
60
  // SEND dispatch — status-code-as-verb (SPEC §3.5).
50
61
  // 200 → request with body (POST), stream response
@@ -54,12 +65,12 @@ export default class Http {
54
65
  // scheme-level no-op here is correct — teardown already happened)
55
66
  async send(statement, ctx) {
56
67
  if (statement.target === null || statement.target.kind !== "url") {
57
- return Http.#bad(400, "http", "bad_target", "SEND requires an http(s):// URL target");
68
+ return _a.#bad(400, "http", "bad_target", "SEND requires an http(s):// URL target");
58
69
  }
59
70
  const status = statement.signal;
60
71
  if (status === 200) {
61
72
  const body = statement.body?.raw ?? "";
62
- return Http.#fetchStream(statement.target, ctx, body);
73
+ return this.#fetchStream(statement.target, ctx, body);
63
74
  }
64
75
  if (status === 410) {
65
76
  const { status: delStatus } = await ctx.entries.delete(statement.target.pathname);
@@ -72,20 +83,22 @@ export default class Http {
72
83
  return { shape: "passthrough", status: 200 };
73
84
  }
74
85
  // Entry-bearing schemes return 501 for status codes they don't interpret.
75
- return Http.#bad(501, "http", "unsupported_send", `SEND[${status}] not supported by http`);
86
+ return _a.#bad(501, "http", "unsupported_send", `SEND[${status}] not supported by http`);
76
87
  }
77
88
  // The streaming core, shared by READ and SEND[200]. Opens the subscription
78
- // (registering the abort handle for SEND[499] routing), fetches, and pumps
79
- // the response body into the BODY channel chunk-by-chunk via the fused
80
- // notifyChunk. Settles via close().
81
- static async #fetchStream(target, ctx, requestBody) {
82
- const url = Http.#urlFrom(target);
89
+ // (registering the abort handle for SEND[499] routing), fetches headers,
90
+ // then EITHER renders (always-render: a GET of an HTML page is re-acquired
91
+ // through the browser and its final DOM becomes the body) OR streams the
92
+ // raw bytes (POST responses and every non-HTML body). Each chunk is labelled
93
+ // with its real mimetype via notifyChunk. Settles via close().
94
+ async #fetchStream(target, ctx, requestBody) {
95
+ const url = _a.#urlFrom(target);
83
96
  const pathname = target.pathname;
84
97
  // Local AbortController for force-cancel from outside (SEND[499]).
85
98
  const local = new AbortController();
86
99
  const handle = { cancel: () => local.abort() };
87
100
  // open() returns the run+teardown-composed signal — fires on loop.cancel
88
- // OR our local teardown. Wire it to the fetch so either path aborts it.
101
+ // OR our local teardown. Wire it so either path aborts the fetch/render.
89
102
  const composed = await ctx.subscriptions.open(pathname, handle);
90
103
  const onAbort = () => local.abort();
91
104
  composed.addEventListener("abort", onAbort, { once: true });
@@ -96,11 +109,24 @@ export default class Http {
96
109
  signal: local.signal,
97
110
  redirect: "follow",
98
111
  });
99
- // Record the response status + headers in the HEADER channel.
100
- const headerLines = [`HTTP ${response.status} ${response.statusText}`];
101
- for (const [k, v] of response.headers)
102
- headerLines.push(`${k}: ${v}`);
103
- await ctx.subscriptions.notifyChunk(HEADER, headerLines.join("\n"));
112
+ const contentType = response.headers.get("content-type") ?? "";
113
+ // Always-render: a GET of an HTML page is re-acquired through the
114
+ // browser so the body is the final rendered DOM. The probe-fetch
115
+ // body is discarded — the browser does its own navigation. A POST
116
+ // never renders (it can't be replayed as a browser navigation).
117
+ const isHtml = requestBody === undefined
118
+ && /^(?:text\/html|application\/xhtml\+xml)\b/i.test(contentType);
119
+ if (isHtml) {
120
+ await response.body?.cancel();
121
+ const result = await this.#browser.render(url, { runId: ctx.runId, signal: local.signal });
122
+ await _a.#writeHeader(ctx, result.status, result.statusText, result.headers);
123
+ await ctx.subscriptions.notifyChunk(BODY, result.html, "text/html");
124
+ await ctx.subscriptions.close("done", `rendered HTTP ${result.status}; ${result.html.length} chars`);
125
+ return { shape: "passthrough", status: 102 };
126
+ }
127
+ // Byte path: stream the body labelled with its real content type.
128
+ await _a.#writeHeader(ctx, response.status, response.statusText, [...response.headers]);
129
+ const bodyMime = contentType.split(";")[0].trim() || "application/octet-stream";
104
130
  if (response.body === null) {
105
131
  await ctx.subscriptions.close("done", `HTTP ${response.status}; empty body`);
106
132
  return { shape: "passthrough", status: 102 };
@@ -109,11 +135,11 @@ export default class Http {
109
135
  const decoder = new TextDecoder();
110
136
  for await (const chunk of response.body) {
111
137
  bytes += chunk.length;
112
- await ctx.subscriptions.notifyChunk(BODY, decoder.decode(chunk, { stream: true }));
138
+ await ctx.subscriptions.notifyChunk(BODY, decoder.decode(chunk, { stream: true }), bodyMime);
113
139
  }
114
140
  const tail = decoder.decode();
115
141
  if (tail.length > 0)
116
- await ctx.subscriptions.notifyChunk(BODY, tail);
142
+ await ctx.subscriptions.notifyChunk(BODY, tail, bodyMime);
117
143
  await ctx.subscriptions.close("done", `HTTP ${response.status}; ${bytes} bytes`);
118
144
  return { shape: "passthrough", status: 102 };
119
145
  }
@@ -121,13 +147,20 @@ export default class Http {
121
147
  const aborted = local.signal.aborted;
122
148
  const reason = aborted ? "aborted" : err instanceof Error ? err.message : String(err);
123
149
  await ctx.subscriptions.close("error", reason);
124
- // 499 for client-cancelled, 502 for upstream/network failure.
125
- return Http.#bad(aborted ? 499 : 502, "http", aborted ? "aborted" : "fetch_failed", reason);
150
+ // 499 for client-cancelled, 502 for upstream/network/render failure.
151
+ return _a.#bad(aborted ? 499 : 502, "http", aborted ? "aborted" : "fetch_failed", reason);
126
152
  }
127
153
  finally {
128
154
  composed.removeEventListener("abort", onAbort);
129
155
  }
130
156
  }
157
+ // Record the response status line + headers into the HEADER channel (text/plain).
158
+ static async #writeHeader(ctx, status, statusText, headers) {
159
+ const lines = [`HTTP ${status} ${statusText}`];
160
+ for (const [k, v] of headers)
161
+ lines.push(`${k}: ${v}`);
162
+ await ctx.subscriptions.notifyChunk(HEADER, lines.join("\n"), "text/plain");
163
+ }
131
164
  // Reconstruct the absolute URL from the parsed UrlPath. `raw` is the
132
165
  // grammar's verbatim URL — authoritative; the decomposed fields are a
133
166
  // convenience. Use raw so query strings / auth / port survive exactly.
@@ -138,4 +171,6 @@ export default class Http {
138
171
  return { shape: "passthrough", status, error: Results.error(scheme, kind, message) };
139
172
  }
140
173
  }
174
+ _a = Http;
175
+ export default Http;
141
176
  //# sourceMappingURL=Http.js.map
package/dist/Http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Http.js","sourceRoot":"","sources":["../src/Http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Http.js","sourceRoot":"","sources":["../src/Http.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { default } from "./Http.ts";
2
2
  export { default as Http } from "./Http.ts";
3
+ export { default as Browser } from "./Browser.ts";
4
+ export type { ChromiumEngine, ChromiumFactory, RenderResult } from "./Browser.ts";
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC;AAI5C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -3,4 +3,7 @@
3
3
  // (plugin discovery scans node_modules/@plurnk/* for `plurnk.kind === "scheme"`).
4
4
  export { default } from "./Http.js";
5
5
  export { default as Http } from "./Http.js";
6
+ // Standalone render foundation — exported so a future plurnk browser-
7
+ // troubleshooting MCP package can sit on the same warm-Chromium pool.
8
+ export { default as Browser } from "./Browser.js";
6
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,0EAA0E;AAC1E,kFAAkF;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,0EAA0E;AAC1E,kFAAkF;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC;AAE5C,sEAAsE;AACtE,sEAAsE;AACtE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plurnk/plurnk-schemes-http",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "http(s):// URI scheme handler for the plurnk agent runtime — fetch + streaming response body.",
5
5
  "keywords": ["plurnk", "scheme", "uri", "http", "https"],
6
6
  "homepage": "https://github.com/plurnk/plurnk-schemes-http#readme",
@@ -44,13 +44,16 @@
44
44
  "build": "npm run build:dist",
45
45
  "prepare": "npm run build"
46
46
  },
47
+ "dependencies": {
48
+ "playwright": "^1.58.2"
49
+ },
47
50
  "peerDependencies": {
48
51
  "@plurnk/plurnk-grammar": "0.21.0",
49
- "@plurnk/plurnk-schemes": "0.4.4"
52
+ "@plurnk/plurnk-schemes": "0.7.0"
50
53
  },
51
54
  "devDependencies": {
52
55
  "@plurnk/plurnk-grammar": "0.21.0",
53
- "@plurnk/plurnk-schemes": "0.4.4",
56
+ "@plurnk/plurnk-schemes": "0.7.0",
54
57
  "@types/node": "^25.8.0",
55
58
  "typescript": "^6.0.3"
56
59
  }