gutterpress 0.11.10-alpha.3 → 0.11.10-alpha.7

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.
Files changed (59) hide show
  1. package/README.md +24 -46
  2. package/dist/api/index.d.ts +1 -1
  3. package/dist/api/index.js +10 -6
  4. package/dist/{build-wvm8haf3.js → build-v8gn687b.js} +7 -6
  5. package/dist/cdp-jg95s674.js +15 -0
  6. package/dist/cdp-smdx6mr3.js +16 -0
  7. package/dist/{cli-w3khh6re.js → cli-2frrxgf3.js} +283 -1142
  8. package/dist/{cli-xk7qfz4m.js → cli-2k72f0ww.js} +1 -4
  9. package/dist/{cli-d8rdk1y7.js → cli-30j93gzt.js} +11 -335
  10. package/dist/{cli-pfczdbyd.js → cli-5qr3z0qa.js} +10 -404
  11. package/dist/{cli-c41yr7he.js → cli-7fkhgtfn.js} +3 -1
  12. package/dist/cli-kkzka31p.js +261 -0
  13. package/dist/{cli-m3jt4tw6.js → cli-wyry8qbw.js} +2 -2
  14. package/dist/cli.js +12 -14
  15. package/dist/{doctor-py6xbmbf.js → doctor-abftekky.js} +3 -3
  16. package/dist/engine/shared/cdp.d.ts +23 -19
  17. package/dist/engine-3gwctsty.js +24 -0
  18. package/dist/engine-mwshptgf.js +25 -0
  19. package/dist/{ext-tg7ntd0y.js → ext-wr3by4tx.js} +7 -6
  20. package/dist/{index-kqftehgy.js → index-dzp0hc2c.js} +4 -2
  21. package/dist/{index-cgbxryk0.js → index-ns8gav3w.js} +344 -1130
  22. package/dist/{index-fnhak0nh.js → index-qf7y4d85.js} +10 -404
  23. package/dist/index-r4wvy5v3.js +267 -0
  24. package/dist/{index-t43k5rq1.js → index-rzm1phg0.js} +23 -356
  25. package/dist/index.d.ts +0 -1
  26. package/dist/index.js +12 -87
  27. package/dist/lib/build-error.d.ts +4 -5
  28. package/dist/lib/build-preflight.d.ts +1 -35
  29. package/dist/lib/build-runner.d.ts +27 -44
  30. package/dist/lib/chromium.d.ts +5 -1
  31. package/dist/lib/engine.d.ts +3 -18
  32. package/dist/lib/extension-manager.d.ts +2 -2
  33. package/dist/lib/extension-manifest.d.ts +1 -1
  34. package/dist/lib/markdown/assemble.d.ts +2 -9
  35. package/dist/lib/markdown/index.d.ts +2 -4
  36. package/dist/lib/markdown/plugins.d.ts +0 -3
  37. package/dist/lib/npm-plugin-installer.d.ts +6 -1
  38. package/dist/lib/plugin-vendor.d.ts +10 -78
  39. package/dist/lib/source-provider.d.ts +1 -1
  40. package/dist/lib/validation-exec.d.ts +5 -6
  41. package/dist/{new-gbjq78y0.js → new-t0m2yyh6.js} +9 -8
  42. package/dist/{preflight-w78jrtm9.js → preflight-tsy2rmyw.js} +7 -6
  43. package/dist/preview/file-watcher.d.ts +4 -43
  44. package/dist/preview/http-server.d.ts +1 -3
  45. package/dist/{preview-bg93vsz1.js → preview-0bqz31w2.js} +7 -6
  46. package/dist/{preview-shell-gqnc5xxe.js → preview-shell-tqndvhbx.js} +5 -7
  47. package/dist/{publish-we0m2hsn.js → publish-38spy866.js} +7 -6
  48. package/dist/render.d.ts +1 -1
  49. package/dist/render.js +1 -9
  50. package/dist/{source-provider-ta09wegv.js → source-provider-pzmz0br9.js} +1 -1
  51. package/dist/{source-provider-7c2ww3bz.js → source-provider-qbthnmqw.js} +1 -1
  52. package/dist/{validate-1tp3nr50.js → validate-k9yge2rh.js} +7 -6
  53. package/package.json +1 -4
  54. package/dist/audit-gw44spqb.js +0 -69
  55. package/dist/engine-qtfrfbpk.js +0 -41
  56. package/dist/engine-trte2tg2.js +0 -40
  57. package/dist/lib/browser-pool.d.ts +0 -35
  58. package/dist/lib/lint-runner.d.ts +0 -29
  59. package/dist/lint-krdp1yec.js +0 -68
@@ -4,7 +4,7 @@ import {
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "gutterpress",
7
- version: "0.11.10-alpha.3",
7
+ version: "0.11.10-alpha.7",
8
8
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
9
9
  author: "itlackey",
10
10
  license: "MPL-2.0",
@@ -64,11 +64,9 @@ var package_default = {
64
64
  node: ">=22.0.0"
65
65
  },
66
66
  dependencies: {
67
- acorn: "8.16.0",
68
67
  chokidar: "^5.0.0",
69
68
  citty: "^0.2.0",
70
69
  diff3: "0.0.3",
71
- "es-module-lexer": "2.0.0",
72
70
  fflate: "0.8.3",
73
71
  glob: "^13.0.0",
74
72
  htmlhint: "^1.9.2",
@@ -85,7 +83,6 @@ var package_default = {
85
83
  markdownlint: "^0.40.0",
86
84
  "pdf-lib": "^1.17.1",
87
85
  postcss: "^8.5.18",
88
- "puppeteer-core": "^25.0.4",
89
86
  "resolve.exports": "2.0.3",
90
87
  semver: "7.8.0",
91
88
  tar: "7.5.20",
@@ -1,330 +1,6 @@
1
1
  import {
2
- requireChromiumExecutable
3
- } from "./cli-c41yr7he.js";
4
- import {
5
- __require
6
- } from "./cli-37x76zdn.js";
7
-
8
- // src/lib/browser-pool.ts
9
- var RENDER_TIMEOUT_MS = 60 * 60 * 1000;
10
- var browserPromise = null;
11
- async function launchBrowser(timeoutMs) {
12
- const executablePath = await requireChromiumExecutable();
13
- const puppeteer = (await import("puppeteer-core")).default;
14
- const extraChromiumArgs = (process.env.GUTTERPRESS_CHROMIUM_ARGS ?? "").split(/\s+/).filter(Boolean);
15
- return puppeteer.launch({
16
- headless: true,
17
- executablePath,
18
- args: extraChromiumArgs,
19
- protocolTimeout: timeoutMs
20
- });
21
- }
22
- function prewarmBrowser(timeoutMs) {
23
- if (browserPromise)
24
- return;
25
- const p = launchBrowser(timeoutMs);
26
- browserPromise = p;
27
- p.then((browser) => {
28
- browser.on("disconnected", () => {
29
- if (browserPromise === p)
30
- browserPromise = null;
31
- });
32
- }).catch(() => {
33
- if (browserPromise === p)
34
- browserPromise = null;
35
- });
36
- }
37
- async function getBrowser(timeoutMs) {
38
- if (!browserPromise)
39
- prewarmBrowser(timeoutMs);
40
- return browserPromise;
41
- }
42
- async function closeBrowser() {
43
- const p = browserPromise;
44
- browserPromise = null;
45
- if (!p)
46
- return;
47
- try {
48
- const b = await p;
49
- await b.close();
50
- } catch {}
51
- }
52
-
53
- // src/engine/shared/cdp.ts
54
- import { spawn } from "node:child_process";
55
- import { existsSync, mkdtempSync, rmSync } from "node:fs";
56
- import { tmpdir } from "node:os";
57
- import { join } from "node:path";
58
- import WebSocket from "ws";
59
- var CANDIDATES = [
60
- process.env.GUTTERPRESS_CHROMIUM,
61
- process.env.PUPPETEER_EXECUTABLE_PATH,
62
- "/opt/pw-browsers/chromium",
63
- "/usr/bin/chromium",
64
- "/usr/bin/chromium-browser",
65
- "/usr/bin/google-chrome",
66
- "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
67
- ].filter(Boolean);
68
- function findChromium() {
69
- for (const c of CANDIDATES)
70
- if (existsSync(c))
71
- return c;
72
- throw new Error(`No Chromium found. Set GUTTERPRESS_CHROMIUM. Looked in:
73
- ${CANDIDATES.join(`
74
- `)}`);
75
- }
76
- var REQUIRED_MILESTONE = 148;
77
- function assertMilestone(product, origin, hint = "") {
78
- const milestone = Number(/Chrome\/(\d+)/.exec(product)?.[1] ?? 0);
79
- if (milestone < REQUIRED_MILESTONE) {
80
- throw new Error(`The Gutterpress engine requires Chromium ${REQUIRED_MILESTONE}+; found ${product} ${origin}.` + (hint ? `
81
- ${hint}` : ""));
82
- }
83
- }
84
- function readyProbeExpr(timeoutMs) {
85
- return `(async () => {
86
- await document.fonts.ready;
87
- if (window.__gpReadyPending) {
88
- await new Promise((res) => {
89
- const t = setTimeout(res, ${timeoutMs});
90
- document.addEventListener('gp:ready', () => { clearTimeout(t); res(); }, { once: true });
91
- });
92
- }
93
- // two rAFs: let layout settle after fonts swap
94
- await new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)));
95
- return true;
96
- })()`;
97
- }
98
- var DEFAULT_PRINT_OPTS = {
99
- printBackground: true,
100
- preferCSSPageSize: true,
101
- generateTaggedPDF: true,
102
- generateDocumentOutline: true
103
- };
104
- async function launchChromium(opts = {}) {
105
- const bin = findChromium();
106
- const userDataDir = mkdtempSync(join(tmpdir(), "gp-cdp-"));
107
- const args = [
108
- "--remote-debugging-port=0",
109
- `--user-data-dir=${userDataDir}`,
110
- "--no-first-run",
111
- "--no-default-browser-check",
112
- "--disable-gpu",
113
- "--no-sandbox",
114
- "--hide-scrollbars",
115
- "--allow-file-access-from-files",
116
- "--font-render-hinting=none",
117
- ...opts.headless === false ? [] : ["--headless=new"],
118
- ...opts.args ?? [],
119
- "about:blank"
120
- ];
121
- const proc = spawn(bin, args, { stdio: ["ignore", "pipe", "pipe"] });
122
- const wsUrl = await readDevToolsUrl(proc);
123
- const conn = await Connection.open(wsUrl);
124
- const teardown = async () => {
125
- const exited = new Promise((r) => proc.once("exit", () => r()));
126
- try {
127
- await Promise.race([
128
- conn.send("Browser.close").then(() => exited),
129
- new Promise((_, rej) => setTimeout(() => rej(new Error("Browser.close timed out")), 5000))
130
- ]);
131
- } catch {
132
- proc.kill("SIGKILL");
133
- await exited;
134
- }
135
- conn.close();
136
- rmSync(userDataDir, { recursive: true, force: true });
137
- };
138
- return checkMilestoneAndWrap(conn, wsUrl, `at ${bin}`, teardown);
139
- }
140
- async function connectChromium(wsUrl) {
141
- const conn = await Connection.open(wsUrl);
142
- return checkMilestoneAndWrap(conn, wsUrl, "via connected browser", async () => {
143
- conn.close();
144
- }, `Set CHROMIUM_PATH (or PUPPETEER_EXECUTABLE_PATH) to a ${REQUIRED_MILESTONE}+ binary.`);
145
- }
146
- async function checkMilestoneAndWrap(conn, wsUrl, origin, teardown, overrideHint = `Set GUTTERPRESS_CHROMIUM to a ${REQUIRED_MILESTONE}+ binary.`) {
147
- const version = await conn.send("Browser.getVersion", {});
148
- try {
149
- assertMilestone(version.product, origin, overrideHint);
150
- } catch (e) {
151
- await teardown();
152
- throw e;
153
- }
154
- const milestone = Number(/Chrome\/(\d+)/.exec(version.product)?.[1] ?? 0);
155
- return {
156
- wsUrl,
157
- version: version.product,
158
- milestone,
159
- async newPage() {
160
- const { targetId } = await conn.send("Target.createTarget", { url: "about:blank" });
161
- const { sessionId } = await conn.send("Target.attachToTarget", { targetId, flatten: true });
162
- const s = new SessionImpl(conn, sessionId, targetId);
163
- await s.send("Page.enable");
164
- await s.send("Runtime.enable");
165
- return s;
166
- },
167
- close: teardown
168
- };
169
- }
170
- function readDevToolsUrl(proc) {
171
- return new Promise((resolve, reject) => {
172
- let buf = "";
173
- const timer = setTimeout(() => reject(new Error(`Chromium did not report a DevTools URL:
174
- ${buf}`)), 60000);
175
- proc.stderr.on("data", (d) => {
176
- buf += String(d);
177
- const m = /ws:\/\/[^\s]+/.exec(buf);
178
- if (m) {
179
- clearTimeout(timer);
180
- resolve(m[0]);
181
- }
182
- });
183
- proc.once("exit", (code) => {
184
- clearTimeout(timer);
185
- reject(new Error(`Chromium exited (${code}) before listening:
186
- ${buf}`));
187
- });
188
- });
189
- }
190
-
191
- class Connection {
192
- ws;
193
- id = 0;
194
- pending = new Map;
195
- listeners = new Map;
196
- constructor(ws) {
197
- this.ws = ws;
198
- ws.on("message", (raw) => this.dispatch(JSON.parse(String(raw))));
199
- }
200
- static async open(url) {
201
- const ws = new WebSocket(url, { maxPayload: 512 * 1024 * 1024 });
202
- await new Promise((res, rej) => {
203
- ws.once("open", () => res());
204
- ws.once("error", rej);
205
- });
206
- return new Connection(ws);
207
- }
208
- dispatch(msg) {
209
- if (msg.id !== undefined) {
210
- const p = this.pending.get(msg.id);
211
- if (!p)
212
- return;
213
- this.pending.delete(msg.id);
214
- if (msg.error)
215
- p.reject(new Error(`${msg.error.message} (${msg.error.code})`));
216
- else
217
- p.resolve(msg.result);
218
- return;
219
- }
220
- const key = msg.sessionId ? `${msg.sessionId}:${msg.method}` : msg.method;
221
- for (const fn of this.listeners.get(key) ?? [])
222
- fn(msg.params);
223
- for (const fn of this.listeners.get(msg.method) ?? [])
224
- fn(msg.params);
225
- }
226
- send(method, params = {}, sessionId) {
227
- const id = ++this.id;
228
- const payload = { id, method, params };
229
- if (sessionId)
230
- payload.sessionId = sessionId;
231
- return new Promise((resolve, reject) => {
232
- this.pending.set(id, { resolve, reject });
233
- this.ws.send(JSON.stringify(payload));
234
- });
235
- }
236
- on(key, fn) {
237
- let set = this.listeners.get(key);
238
- if (!set)
239
- this.listeners.set(key, set = new Set);
240
- set.add(fn);
241
- return () => set.delete(fn);
242
- }
243
- close() {
244
- this.ws.close();
245
- }
246
- }
247
-
248
- class SessionImpl {
249
- conn;
250
- sessionId;
251
- targetId;
252
- constructor(conn, sessionId, targetId) {
253
- this.conn = conn;
254
- this.sessionId = sessionId;
255
- this.targetId = targetId;
256
- }
257
- send(method, params = {}) {
258
- return this.conn.send(method, params, this.sessionId);
259
- }
260
- on(event, fn) {
261
- return this.conn.on(`${this.sessionId}:${event}`, fn);
262
- }
263
- async evaluate(expression) {
264
- const res = await this.send("Runtime.evaluate", {
265
- expression,
266
- returnByValue: true,
267
- awaitPromise: true
268
- });
269
- if (res.exceptionDetails) {
270
- const e = res.exceptionDetails;
271
- throw new Error(`evaluate failed: ${e.exception?.description ?? e.text}`);
272
- }
273
- return res.result.value;
274
- }
275
- async waitForLoad(fn) {
276
- const done = new Promise((resolve) => {
277
- const off = this.on("Page.loadEventFired", () => {
278
- off();
279
- resolve();
280
- });
281
- });
282
- await fn();
283
- await done;
284
- }
285
- async setContent(html, baseUrl = "http://gutterpress.spike/") {
286
- await this.waitForLoad(async () => {
287
- const { frameTree } = await this.send("Page.getFrameTree");
288
- await this.send("Page.setDocumentContent", {
289
- frameId: frameTree.frame.id,
290
- html
291
- });
292
- });
293
- }
294
- async navigate(url) {
295
- await this.waitForLoad(async () => {
296
- await this.send("Page.navigate", { url });
297
- });
298
- }
299
- async waitForReady(timeoutMs = 15000) {
300
- await this.evaluate(readyProbeExpr(timeoutMs));
301
- }
302
- async printToPDF(opts = {}) {
303
- const res = await this.send("Page.printToPDF", {
304
- ...DEFAULT_PRINT_OPTS,
305
- transferMode: "ReturnAsStream",
306
- ...opts
307
- });
308
- if (!res.stream)
309
- return Uint8Array.from(Buffer.from(res.data, "base64"));
310
- const chunks = [];
311
- try {
312
- for (;; ) {
313
- const c = await this.send("IO.read", { handle: res.stream, size: 8 * 1024 * 1024 });
314
- if (c.data)
315
- chunks.push(Buffer.from(c.data, c.base64Encoded ? "base64" : "binary"));
316
- if (c.eof)
317
- break;
318
- }
319
- } finally {
320
- await this.send("IO.close", { handle: res.stream }).catch(() => {});
321
- }
322
- return new Uint8Array(Buffer.concat(chunks));
323
- }
324
- async close() {
325
- await this.conn.send("Target.closeTarget", { targetId: this.targetId });
326
- }
327
- }
2
+ launchChromium
3
+ } from "./cli-kkzka31p.js";
328
4
 
329
5
  // src/engine/compiler/build.ts
330
6
  import { readFile as readFile2 } from "node:fs/promises";
@@ -1420,10 +1096,10 @@ async function inspectPdf(bytes) {
1420
1096
  }
1421
1097
 
1422
1098
  // src/lib/embedded-assets.ts
1423
- import { existsSync as existsSync2 } from "node:fs";
1099
+ import { existsSync } from "node:fs";
1424
1100
  import { mkdtemp, mkdir, writeFile, readFile } from "node:fs/promises";
1425
- import { tmpdir as tmpdir2 } from "node:os";
1426
- import { dirname, join as join2, resolve } from "node:path";
1101
+ import { tmpdir } from "node:os";
1102
+ import { dirname, join, resolve } from "node:path";
1427
1103
  import { fileURLToPath } from "node:url";
1428
1104
 
1429
1105
  // src/assets/favicon.ico
@@ -1439,7 +1115,7 @@ var preview_interface_default = "./preview-interface-9rwz21yw.js";
1439
1115
  var preview_bridge_default = "./preview-bridge-b4jbtb79.js";
1440
1116
 
1441
1117
  // src/assets/preview/scripts/preview-shell.js
1442
- var preview_shell_default = "./preview-shell-gqnc5xxe.js";
1118
+ var preview_shell_default = "./preview-shell-tqndvhbx.js";
1443
1119
 
1444
1120
  // profiles/CGATS21_CRPC1.icc
1445
1121
  var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
@@ -1586,9 +1262,9 @@ var EMBEDDED_ASSETS = {
1586
1262
  };
1587
1263
  var extractPromise = null;
1588
1264
  async function extractAssets() {
1589
- const root = await mkdtemp(join2(tmpdir2(), "gutterpress-assets-"));
1265
+ const root = await mkdtemp(join(tmpdir(), "gutterpress-assets-"));
1590
1266
  for (const [relPath, srcPath] of Object.entries(EMBEDDED_ASSETS)) {
1591
- const dest = join2(root, relPath);
1267
+ const dest = join(root, relPath);
1592
1268
  await mkdir(dirname(dest), { recursive: true });
1593
1269
  const bytes = await readFile(srcPath);
1594
1270
  await writeFile(dest, bytes);
@@ -1600,7 +1276,7 @@ async function getAssetsDir() {
1600
1276
  if (extractPromise) {
1601
1277
  try {
1602
1278
  const root = await extractPromise;
1603
- if (existsSync2(join2(root, SENTINEL_ASSET))) {
1279
+ if (existsSync(join(root, SENTINEL_ASSET))) {
1604
1280
  return root;
1605
1281
  }
1606
1282
  } catch {}
@@ -1611,7 +1287,7 @@ async function getAssetsDir() {
1611
1287
  }
1612
1288
  async function getAssetPath(relPath) {
1613
1289
  const root = await getAssetsDir();
1614
- return join2(root, relPath);
1290
+ return join(root, relPath);
1615
1291
  }
1616
1292
 
1617
1293
  // src/engine/compiler/tier2.ts
@@ -2921,4 +2597,4 @@ ${lines.length ? lines.join(`
2921
2597
  `);
2922
2598
  }
2923
2599
 
2924
- export { RENDER_TIMEOUT_MS, prewarmBrowser, getBrowser, closeBrowser, getAssetsDir, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, REQUIRED_MILESTONE, assertMilestone, connectChromium, build };
2600
+ export { getAssetsDir, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, build };