slackmark-node 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"katex-renderer.d.ts","sourceRoot":"","sources":["../src/katex-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAKnB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAoBnE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,kBAAkB;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAE5C,YAAY,OAAO,EAAE,oBAAoB,EA6DxC;IAED,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAEzC;IAEK,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAiH1F;CACF"}
1
+ {"version":3,"file":"katex-renderer.d.ts","sourceRoot":"","sources":["../src/katex-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAUnB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAoBnE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,kBAAkB;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAE5C,YAAY,OAAO,EAAE,oBAAoB,EA6DxC;IAED,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAEzC;IAEK,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAiH1F;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer-render-runtime.d.ts","sourceRoot":"","sources":["../src/puppeteer-render-runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"puppeteer-render-runtime.d.ts","sourceRoot":"","sources":["../src/puppeteer-render-runtime.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ export { isNodeRenderError } from "./errors.js";
1
2
  export { LocalKatexAssetLoader } from "./katex-assets.js";
2
3
  export type { KatexAssetLoader } from "./katex-assets.js";
3
4
  export { LocalMermaidAssetLoader } from "./mermaid-assets.js";
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer.d.ts","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACjG,YAAY,EACV,aAAa,EACb,eAAe,EACf,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,6BAA6B,EAC7B,aAAa,EACb,eAAe,GAChB,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"puppeteer.d.ts","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACjG,YAAY,EACV,aAAa,EACb,eAAe,EACf,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,6BAA6B,EAC7B,aAAa,EACb,eAAe,GAChB,MAAM,+BAA+B,CAAC"}
package/dist/puppeteer.js CHANGED
@@ -1,8 +1,19 @@
1
1
  import { createRequire } from "node:module";
2
+ import { ConfigurationError, OperationAbortedError, OperationDeadlineExceededError, OperationErrorCode, OperationShutdownError, cloneOperationError, isOperationError } from "slackmark";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import { dirname, join } from "node:path";
4
- import { ConfigurationError, OperationAbortedError, OperationDeadlineExceededError, OperationErrorCode, OperationShutdownError, cloneOperationError, isOperationError } from "slackmark";
5
5
  //#region src/errors.ts
6
+ /**
7
+ * Registry-keyed marker, not a module-local symbol.
8
+ *
9
+ * Each published entry (`slackmark-node`, `slackmark-node/renderers`,
10
+ * `slackmark-node/puppeteer`) is bundled without code splitting, so every entry carries
11
+ * its own copy of {@link NodeRenderError} and `instanceof` is false for an error that
12
+ * crosses an entry boundary. A renderer always crosses one: the renderers live in
13
+ * `/renderers` and the runtime that throws at them lives in `/puppeteer`. `Symbol.for`
14
+ * keys are shared by every copy, which is what makes {@link isNodeRenderError} reliable.
15
+ */
16
+ const NODE_RENDER_ERROR_BRAND = Symbol.for("slackmark.error.nodeRender");
6
17
  const NodeRenderErrorCode = {
7
18
  AssetMissing: "asset_missing",
8
19
  BrowserBinaryMissing: "browser_binary_missing",
@@ -35,6 +46,14 @@ const NodeRenderStage = {
35
46
  * Sanitized failure from the Node rendering boundary.
36
47
  */
37
48
  var NodeRenderError = class extends Error {
49
+ static {
50
+ Object.defineProperty(this.prototype, NODE_RENDER_ERROR_BRAND, {
51
+ configurable: false,
52
+ enumerable: false,
53
+ value: true,
54
+ writable: false
55
+ });
56
+ }
38
57
  code;
39
58
  stage;
40
59
  retryable;
@@ -51,8 +70,20 @@ var NodeRenderError = class extends Error {
51
70
  this.rendererId = options.rendererId;
52
71
  }
53
72
  };
73
+ /**
74
+ * Identifies a {@link NodeRenderError} from any entry of this package. Prefer this to
75
+ * `instanceof`, which is false across an entry boundary.
76
+ */
77
+ function isNodeRenderError(value) {
78
+ if (typeof value !== "object" || value === null) return false;
79
+ try {
80
+ return Reflect.get(value, NODE_RENDER_ERROR_BRAND) === true;
81
+ } catch {
82
+ return false;
83
+ }
84
+ }
54
85
  function normalizeNodeRenderError(error, code, message, stage = NodeRenderStage.Render, retryable = false) {
55
- return error instanceof NodeRenderError || isOperationError(error) ? error : new NodeRenderError(code, message, {
86
+ return isNodeRenderError(error) || isOperationError(error) ? error : new NodeRenderError(code, message, {
56
87
  stage,
57
88
  retryable,
58
89
  cause: error
@@ -449,7 +480,7 @@ var PuppeteerRenderRuntime = class {
449
480
  if (context !== void 0) try {
450
481
  await cleanupContext();
451
482
  } catch (cleanupError) {
452
- if (outcome.ok || cleanupError instanceof NodeRenderError && cleanupError.stage === "browser_cleanup") outcome = {
483
+ if (outcome.ok || isNodeRenderError(cleanupError) && cleanupError.stage === "browser_cleanup") outcome = {
453
484
  ok: false,
454
485
  error: cleanupError
455
486
  };
@@ -718,6 +749,6 @@ function isMissingBrowserError(error) {
718
749
  return error.message.includes("Could not find Chrome") || error.message.includes("Browser was not found") || error.message.includes("executable doesn't exist");
719
750
  }
720
751
  //#endregion
721
- export { LocalKatexAssetLoader, LocalMermaidAssetLoader, PuppeteerBrowserLauncher, PuppeteerRenderRuntime };
752
+ export { LocalKatexAssetLoader, LocalMermaidAssetLoader, PuppeteerBrowserLauncher, PuppeteerRenderRuntime, isNodeRenderError };
722
753
 
723
754
  //# sourceMappingURL=puppeteer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer.js","names":["resolver"],"sources":["../src/errors.ts","../src/katex-assets.ts","../src/mermaid-assets.ts","../src/node-options.ts","../src/operation-control.ts","../src/puppeteer-render-runtime.ts"],"sourcesContent":["import {\n isOperationError,\n type OperationError,\n type StructuredRendererError,\n type UploadReceipt,\n} from \"slackmark\";\n\nimport type { NodeConverterStatus } from \"./status.js\";\n\nexport const NodeRenderErrorCode = {\n AssetMissing: \"asset_missing\",\n BrowserBinaryMissing: \"browser_binary_missing\",\n BrowserDisconnected: \"browser_disconnected\",\n BrowserFailed: \"browser_failed\",\n CleanupFailed: \"cleanup_failed\",\n CloseFailed: \"close_failed\",\n ContextFailed: \"context_failed\",\n DimensionLimit: \"dimension_limit\",\n OutputLimit: \"output_limit\",\n QueueFull: \"queue_full\",\n RenderFailed: \"render_failed\",\n SourceLimit: \"source_limit\",\n} as const;\n\nexport type NodeRenderErrorCode = (typeof NodeRenderErrorCode)[keyof typeof NodeRenderErrorCode];\n\nexport const NodeRenderStage = {\n Admission: \"admission\",\n AssetLoad: \"asset_load\",\n Browser: \"browser\",\n BrowserCleanup: \"browser_cleanup\",\n BrowserClose: \"browser_close\",\n BrowserLaunch: \"browser_launch\",\n ContextCleanup: \"context_cleanup\",\n ContextCreate: \"context_create\",\n Layout: \"layout\",\n OutputValidation: \"output_validation\",\n Render: \"render\",\n SourceValidation: \"source_validation\",\n} as const;\n\nexport type NodeRenderStage = (typeof NodeRenderStage)[keyof typeof NodeRenderStage];\n\nexport interface NodeRenderErrorOptions {\n readonly stage: NodeRenderStage;\n readonly retryable: boolean;\n readonly rendererId?: string | undefined;\n readonly cause?: unknown;\n}\n\nexport class NodeShutdownTimeoutError extends Error {\n override readonly name: string;\n readonly code: \"shutdown_timeout\";\n readonly stage: \"close\";\n readonly retryable: true;\n readonly status: NodeConverterStatus;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(\n status: NodeConverterStatus,\n receipts: ReadonlyArray<UploadReceipt>,\n settledReceipts: Promise<ReadonlyArray<UploadReceipt>>,\n ) {\n super(\"Node converter shutdown timed out\");\n this.name = \"NodeShutdownTimeoutError\";\n this.code = \"shutdown_timeout\";\n this.stage = \"close\";\n this.retryable = true;\n this.status = status;\n this.receipts = Object.freeze([...receipts]);\n this.settledReceipts = settledReceipts;\n }\n}\n\n/**\n * Sanitized failure from the Node rendering boundary.\n */\nexport class NodeRenderError extends Error implements StructuredRendererError {\n readonly code: NodeRenderErrorCode;\n readonly stage: NodeRenderStage;\n readonly retryable: boolean;\n readonly rendererId: string | undefined;\n\n constructor(\n code: NodeRenderErrorCode,\n message: string,\n options: NodeRenderErrorOptions = {\n stage: \"render\",\n retryable: false,\n },\n ) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = \"NodeRenderError\";\n this.code = code;\n this.stage = options.stage;\n this.retryable = options.retryable;\n this.rendererId = options.rendererId;\n }\n}\n\nexport function normalizeNodeRenderError(\n error: unknown,\n code: NodeRenderErrorCode,\n message: string,\n stage: NodeRenderStage = NodeRenderStage.Render,\n retryable = false,\n): NodeRenderError | OperationError {\n return error instanceof NodeRenderError || isOperationError(error)\n ? error\n : new NodeRenderError(code, message, { stage, retryable, cause: error });\n}\n","import { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nimport { NodeRenderErrorCode, normalizeNodeRenderError } from \"./errors.js\";\n\nconst resolver = createRequire(import.meta.url);\nconst WOFF2_URL_RE = /url\\(fonts\\/([A-Za-z0-9_-]+\\.woff2)\\)/g;\nconst LEGACY_FONT_SOURCE_RE =\n /, url\\(fonts\\/[A-Za-z0-9_-]+\\.(?:woff|ttf)\\) format\\(\"(?:woff|truetype)\"\\)/g;\n\n/**\n * Loads browser-ready KaTeX CSS without external network dependencies.\n */\nexport interface KatexAssetLoader {\n loadCss(): Promise<string>;\n loadScript(): Promise<string>;\n}\n\n/**\n * Reads KaTeX's installed CSS/fonts and embeds WOFF2 files as data URLs once.\n */\nexport class LocalKatexAssetLoader implements KatexAssetLoader {\n private cssPromise: Promise<string> | undefined;\n private scriptPromise: Promise<string> | undefined;\n\n constructor() {\n this.cssPromise = undefined;\n this.scriptPromise = undefined;\n }\n\n loadScript(): Promise<string> {\n this.scriptPromise ??= readFile(resolver.resolve(\"katex/dist/katex.min.js\"), \"utf8\").catch(\n (error: unknown) => {\n this.scriptPromise = undefined;\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.AssetMissing,\n \"Unable to load local KaTeX script\",\n \"asset_load\",\n false,\n );\n },\n );\n return this.scriptPromise;\n }\n\n loadCss(): Promise<string> {\n this.cssPromise ??= this.loadCssFromPackage().catch((error: unknown) => {\n this.cssPromise = undefined;\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.AssetMissing,\n \"Unable to load local KaTeX assets\",\n \"asset_load\",\n false,\n );\n });\n return this.cssPromise;\n }\n\n private async loadCssFromPackage(): Promise<string> {\n const cssPath = resolver.resolve(\"katex/dist/katex.css\");\n const css = await readFile(cssPath, \"utf8\");\n const fontNames = new Set<string>();\n for (const match of css.matchAll(WOFF2_URL_RE)) {\n const fontName = match[1];\n if (fontName !== undefined) {\n fontNames.add(fontName);\n }\n }\n\n const encodedFonts = await Promise.all(\n [...fontNames].map(async (fontName): Promise<readonly [string, string]> => {\n const data = await readFile(join(dirname(cssPath), \"fonts\", fontName));\n return [fontName, data.toString(\"base64\")];\n }),\n );\n\n let embedded = css.replace(LEGACY_FONT_SOURCE_RE, \"\");\n for (const [fontName, base64] of encodedFonts) {\n embedded = embedded.replaceAll(\n `url(fonts/${fontName})`,\n `url(data:font/woff2;base64,${base64})`,\n );\n }\n return embedded;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\n\nimport { NodeRenderError, NodeRenderErrorCode } from \"./errors.js\";\n\nconst resolver = createRequire(import.meta.url);\n\nexport interface MermaidAssetLoader {\n loadScript(): Promise<string>;\n}\n\nexport class LocalMermaidAssetLoader implements MermaidAssetLoader {\n private scriptPromise: Promise<string> | undefined;\n\n constructor() {\n this.scriptPromise = undefined;\n }\n\n loadScript(): Promise<string> {\n this.scriptPromise ??= readFile(resolver.resolve(\"mermaid/dist/mermaid.min.js\"), \"utf8\").catch(\n (error: unknown) => {\n this.scriptPromise = undefined;\n throw new NodeRenderError(\n NodeRenderErrorCode.AssetMissing,\n \"Unable to load Mermaid browser assets\",\n {\n stage: \"asset_load\",\n retryable: false,\n cause: error,\n },\n );\n },\n );\n return this.scriptPromise;\n }\n}\n","import { ConfigurationError } from \"slackmark\";\n\nexport function snapshotNodeOptions<T extends object>(\n options: T,\n allowed: ReadonlyArray<string>,\n label: string,\n): T {\n if (!isPlainNodeObject(options)) {\n throw invalidNodeOptions(`${label} options must be a plain object`);\n }\n const allowedKeys = new Set(allowed);\n const snapshot: Record<string, unknown> = {};\n let keys: ReadonlyArray<string>;\n try {\n keys = Object.keys(options);\n } catch (cause) {\n throw invalidNodeOptions(`${label} options could not be inspected`, cause);\n }\n for (const key of keys) {\n if (!allowedKeys.has(key)) {\n throw invalidNodeOptions(`Unknown ${label} option: ${key}`);\n }\n try {\n snapshot[key] = Reflect.get(options, key);\n } catch (cause) {\n throw invalidNodeOptions(`${label}.${key} could not be read`, cause);\n }\n }\n return Object.freeze(snapshot) as T;\n}\n\nexport function snapshotOpenNodeOptions<T extends object>(options: T, label: string): T {\n let keys: ReadonlyArray<string>;\n try {\n keys = Object.keys(options);\n } catch (cause) {\n throw invalidNodeOptions(`${label} could not be inspected`, cause);\n }\n return snapshotNodeOptions(options, keys, label);\n}\n\nexport function assertNodeMethod(collaborator: unknown, method: string, label: string): void {\n try {\n if (\n (typeof collaborator !== \"object\" && typeof collaborator !== \"function\") ||\n collaborator === null ||\n typeof Reflect.get(collaborator, method) !== \"function\"\n ) {\n throw new TypeError(`${method} must be a function`);\n }\n } catch (cause) {\n throw invalidNodeOptions(`${label} collaborator is invalid`, cause);\n }\n}\n\nexport function invalidNodeOptions(message: string, cause?: unknown): ConfigurationError {\n return new ConfigurationError(message, {\n code: \"invalid_node_configuration\",\n stage: \"configuration\",\n cause,\n });\n}\n\nfunction isPlainNodeObject(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n let prototype: object | null;\n try {\n prototype = Object.getPrototypeOf(value);\n } catch {\n return false;\n }\n return prototype === Object.prototype || prototype === null;\n}\n","import {\n ConfigurationError,\n OperationAbortedError,\n OperationDeadlineExceededError,\n OperationShutdownError,\n cloneOperationError,\n isOperationError,\n type OperationContext,\n type OperationError,\n type OperationOptions,\n} from \"slackmark\";\n\nexport class OperationScope {\n readonly context: OperationContext;\n private readonly parentSignal: AbortSignal | undefined;\n private readonly controller: AbortController;\n private readonly abortFromParent: () => void;\n private readonly deadlineTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(context: OperationContext, stage: string) {\n this.parentSignal = context.signal;\n this.controller = new AbortController();\n this.abortFromParent = (): void => {\n const reason = this.parentSignal?.reason;\n this.controller.abort(\n isOperationError(reason)\n ? cloneOperationError(reason, stage)\n : new OperationAbortedError(stage, { cause: reason }),\n );\n };\n if (this.parentSignal?.aborted === true) {\n this.abortFromParent();\n } else {\n this.parentSignal?.addEventListener(\"abort\", this.abortFromParent, {\n once: true,\n });\n }\n if (context.deadlineMs === undefined) {\n this.deadlineTimer = undefined;\n } else if (context.deadlineMs <= Date.now()) {\n this.deadlineTimer = undefined;\n this.controller.abort(new OperationDeadlineExceededError(stage));\n } else {\n this.deadlineTimer = setTimeout(() => {\n this.controller.abort(new OperationDeadlineExceededError(stage));\n }, context.deadlineMs - Date.now());\n }\n this.context = Object.freeze({\n signal: this.controller.signal,\n deadlineMs: context.deadlineMs,\n });\n }\n\n abortForShutdown(stage: string): void {\n this.controller.abort(new OperationShutdownError(stage));\n }\n\n abort(reason: unknown): void {\n this.controller.abort(reason);\n }\n\n race<T>(promise: Promise<T>): Promise<T> {\n return raceWithContext(promise, this.context);\n }\n\n cleanup(): void {\n if (this.deadlineTimer !== undefined) {\n clearTimeout(this.deadlineTimer);\n }\n this.parentSignal?.removeEventListener(\"abort\", this.abortFromParent);\n }\n}\n\nexport function createOperationScope(\n options: OperationOptions = {},\n stage: string,\n): OperationScope {\n validateOperationOptions(options);\n return new OperationScope(\n {\n signal: options.signal,\n deadlineMs: options.timeoutMs === undefined ? undefined : Date.now() + options.timeoutMs,\n },\n stage,\n );\n}\n\nexport function raceWithContext<T>(promise: Promise<T>, context: OperationContext): Promise<T> {\n const signal = context.signal;\n if (signal?.aborted === true) {\n return Promise.reject(signal.reason ?? new OperationAbortedError(\"operation\"));\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = (): void => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(signal?.reason ?? new OperationAbortedError(\"operation\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n void promise.then(\n (value) => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve(value);\n return undefined;\n },\n (error: unknown) => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nexport function operationReason(signal: AbortSignal): OperationError {\n return isOperationError(signal.reason)\n ? signal.reason\n : new OperationAbortedError(\"operation\", { cause: signal.reason });\n}\n\nfunction validateOperationOptions(options: OperationOptions): void {\n if (!isPlainObject(options)) {\n throw new ConfigurationError(\"Operation options must be a plain object\", {\n code: \"invalid_operation_options\",\n stage: \"configuration\",\n });\n }\n for (const key of Object.keys(options)) {\n if (key !== \"signal\" && key !== \"timeoutMs\") {\n throw new ConfigurationError(`Unknown operation option: ${key}`, {\n code: \"invalid_operation_options\",\n stage: \"configuration\",\n });\n }\n }\n if (\n options.signal !== undefined &&\n (typeof options.signal !== \"object\" ||\n options.signal === null ||\n typeof options.signal.addEventListener !== \"function\" ||\n typeof options.signal.removeEventListener !== \"function\")\n ) {\n throw new ConfigurationError(\"signal must be an AbortSignal\", {\n code: \"invalid_signal\",\n stage: \"configuration\",\n });\n }\n if (\n options.timeoutMs !== undefined &&\n (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0)\n ) {\n throw new ConfigurationError(\"timeoutMs must be positive\", {\n code: \"invalid_timeout\",\n stage: \"configuration\",\n });\n }\n}\n\nexport function isPlainObject(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n","import type { Browser, BrowserContext, BrowserContextOptions, LaunchOptions } from \"puppeteer\";\nimport {\n OperationDeadlineExceededError,\n OperationErrorCode,\n OperationShutdownError,\n isOperationError,\n type OperationContext,\n} from \"slackmark\";\n\nimport { NodeRenderError, NodeRenderErrorCode, normalizeNodeRenderError } from \"./errors.js\";\nimport {\n assertNodeMethod,\n invalidNodeOptions,\n snapshotNodeOptions,\n snapshotOpenNodeOptions,\n} from \"./node-options.js\";\nimport { OperationScope, operationReason, raceWithContext } from \"./operation-control.js\";\nimport type { NodeWorkStatus } from \"./status.js\";\n\nconst DEFAULT_CONCURRENCY = 2;\nconst DEFAULT_MAX_QUEUE_SIZE = 32;\nconst INTERNAL_LAUNCH_TIMEOUT_MS = 10_000;\nconst INTERNAL_CLEANUP_TIMEOUT_MS = 2_000;\nconst DENY_NETWORK_PROXY = \"http://127.0.0.1:9\";\n\nexport type CloseBehavior = \"drain\" | \"cancel\";\n\nexport type WorkQueueStatus = NodeWorkStatus;\n\nexport type PuppeteerRenderJob<T> = (\n context: BrowserContext,\n operation: OperationContext,\n) => Promise<T>;\n\nexport interface BrowserHandle {\n readonly connected: boolean;\n createBrowserContext(options?: BrowserContextOptions): Promise<BrowserContext>;\n close(): Promise<void>;\n forceClose(): Promise<void>;\n on(event: \"disconnected\", handler: () => void): void;\n}\n\nexport interface BrowserLauncher {\n launch(options: LaunchOptions, operation: OperationContext): Promise<BrowserHandle>;\n}\n\nexport interface RenderRuntime {\n run<T>(job: PuppeteerRenderJob<T>, operation: OperationContext): Promise<T>;\n warmup(operation: OperationContext): Promise<void>;\n close(operation: OperationContext, behavior?: CloseBehavior): Promise<void>;\n status(): WorkQueueStatus;\n}\n\nexport interface PuppeteerRenderRuntimeOptions {\n readonly launcher: BrowserLauncher;\n readonly launchOptions?: LaunchOptions | undefined;\n readonly concurrency?: number | undefined;\n readonly maxQueueSize?: number | undefined;\n}\n\ninterface PendingJob {\n start(): void;\n reject(error: unknown): void;\n}\n\nexport class PuppeteerRenderRuntime implements RenderRuntime {\n private readonly launcher: BrowserLauncher;\n private readonly launchOptions: LaunchOptions;\n private readonly concurrency: number;\n private readonly maxQueueSize: number;\n private readonly contextOptions: BrowserContextOptions;\n private readonly pendingJobs: PendingJob[];\n private readonly activeScopes: Set<OperationScope>;\n private readonly idleResolvers: Array<() => void>;\n private activeJobs: number;\n private browserPromise: Promise<BrowserHandle> | undefined;\n private currentBrowser: BrowserHandle | undefined;\n private launchController: AbortController | undefined;\n private readonly launchWaiters: Set<OperationScope>;\n private launchPending: boolean;\n private launchAbandoned: boolean;\n private launchError: unknown;\n private forceCloseBrowser: BrowserHandle | undefined;\n private forceClosePromise: Promise<void> | undefined;\n private closePromise: Promise<void> | undefined;\n private closeBehavior: CloseBehavior | undefined;\n private accepting: boolean;\n\n constructor(options: PuppeteerRenderRuntimeOptions) {\n const validated = snapshotNodeOptions(\n options,\n [\"launcher\", \"launchOptions\", \"concurrency\", \"maxQueueSize\"],\n \"PuppeteerRenderRuntime\",\n );\n assertNodeMethod(validated.launcher, \"launch\", \"BrowserLauncher\");\n const launchOptions =\n validated.launchOptions === undefined\n ? undefined\n : snapshotOpenNodeOptions(validated.launchOptions, \"Puppeteer launchOptions\");\n this.launcher = validated.launcher;\n this.launchOptions = {\n headless: \"shell\",\n ...launchOptions,\n };\n this.concurrency = validated.concurrency ?? DEFAULT_CONCURRENCY;\n this.maxQueueSize = validated.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n this.contextOptions = {\n proxyServer: DENY_NETWORK_PROXY,\n proxyBypassList: [\"<-loopback>\"],\n downloadBehavior: { policy: \"deny\" },\n };\n this.pendingJobs = [];\n this.activeScopes = new Set();\n this.idleResolvers = [];\n this.activeJobs = 0;\n this.browserPromise = undefined;\n this.currentBrowser = undefined;\n this.launchController = undefined;\n this.launchWaiters = new Set();\n this.launchPending = false;\n this.launchAbandoned = false;\n this.launchError = undefined;\n this.forceCloseBrowser = undefined;\n this.forceClosePromise = undefined;\n this.closePromise = undefined;\n this.closeBehavior = undefined;\n this.accepting = true;\n\n validatePositiveInteger(this.concurrency, \"concurrency\");\n validateNonNegativeInteger(this.maxQueueSize, \"maxQueueSize\");\n }\n\n run<T>(job: PuppeteerRenderJob<T>, operation: OperationContext): Promise<T> {\n if (!this.accepting) {\n return Promise.reject(new OperationShutdownError(\"render_admission\"));\n }\n if (this.activeJobs >= this.concurrency && this.pendingJobs.length >= this.maxQueueSize) {\n return Promise.reject(\n new NodeRenderError(\n NodeRenderErrorCode.QueueFull,\n `Render queue is full (max ${String(this.maxQueueSize)} pending)`,\n { stage: \"admission\", retryable: true },\n ),\n );\n }\n\n return new Promise<T>((resolve, reject) => {\n const scope = new OperationScope(operation, \"render\");\n let pending: PendingJob;\n const abortWhileQueued = (): void => {\n const index = this.pendingJobs.indexOf(pending);\n if (index >= 0) {\n this.pendingJobs.splice(index, 1);\n pending.reject(operationReason(requireSignal(scope.context)));\n }\n };\n pending = {\n start: (): void => {\n scope.context.signal?.removeEventListener(\"abort\", abortWhileQueued);\n this.activeScopes.add(scope);\n this.startUnderlying(job, scope, resolve, reject);\n },\n reject: (error: unknown): void => {\n scope.context.signal?.removeEventListener(\"abort\", abortWhileQueued);\n scope.cleanup();\n reject(error);\n },\n };\n if (scope.context.signal?.aborted === true) {\n pending.reject(operationReason(requireSignal(scope.context)));\n return;\n }\n if (this.activeJobs < this.concurrency) {\n this.activeJobs += 1;\n pending.start();\n return;\n }\n scope.context.signal?.addEventListener(\"abort\", abortWhileQueued, { once: true });\n this.pendingJobs.push(pending);\n });\n }\n\n warmup(operation: OperationContext): Promise<void> {\n return this.run(async () => undefined, operation);\n }\n\n close(operation: OperationContext, behavior: CloseBehavior = \"cancel\"): Promise<void> {\n if (this.closePromise !== undefined) {\n return this.closePromise;\n }\n const closeScope = new OperationScope(operation, \"browser_close\");\n this.accepting = false;\n this.closeBehavior = behavior;\n if (behavior === \"cancel\") {\n const shutdown = new OperationShutdownError(\"render\");\n for (const pending of this.pendingJobs.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"render\");\n }\n this.abandonLaunch(shutdown);\n }\n this.closePromise = this.finishClose(closeScope.context).finally(() => {\n closeScope.cleanup();\n });\n return this.closePromise;\n }\n\n status(): WorkQueueStatus {\n return Object.freeze({\n accepting: this.accepting,\n active: this.activeJobs,\n queued: this.pendingJobs.length,\n retainedBytes: 0,\n });\n }\n\n private startUnderlying<T>(\n job: PuppeteerRenderJob<T>,\n scope: OperationScope,\n resolve: (value: T | PromiseLike<T>) => void,\n reject: (error: unknown) => void,\n ): void {\n const underlying = this.executeUnderlying(job, scope);\n void scope.race(underlying).then(resolve, reject);\n void underlying.then(\n () => {\n this.finishUnderlying(scope);\n return undefined;\n },\n () => {\n this.finishUnderlying(scope);\n return undefined;\n },\n );\n }\n\n private async executeUnderlying<T>(\n job: PuppeteerRenderJob<T>,\n scope: OperationScope,\n ): Promise<T> {\n let browser: BrowserHandle | undefined;\n let context: BrowserContext | undefined;\n let contextClosePromise: Promise<void> | undefined;\n let contextCleanupPromise: Promise<void> | undefined;\n let outcome:\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: unknown };\n const closeContext = (): Promise<void> => {\n if (context === undefined) {\n return Promise.resolve();\n }\n contextClosePromise ??= Promise.resolve().then(() => (context as BrowserContext).close());\n return contextClosePromise;\n };\n const cleanupContext = (): Promise<void> => {\n contextCleanupPromise ??= cleanupWithDeadline(closeContext(), async () => {\n await this.forceCloseBrowserOnce(browser);\n });\n return contextCleanupPromise;\n };\n const requestContextClose = (): void => {\n if (context !== undefined) {\n void cleanupContext().catch(() => undefined);\n }\n };\n scope.context.signal?.addEventListener(\"abort\", requestContextClose, { once: true });\n\n try {\n browser = await this.getBrowser(scope);\n throwIfContextEnded(scope.context);\n try {\n context = await browser.createBrowserContext(this.contextOptions);\n } catch (error) {\n if (isBrowserDisconnected(error)) {\n throw error;\n }\n throw new NodeRenderError(\n NodeRenderErrorCode.ContextFailed,\n \"Browser context creation failed\",\n {\n stage: \"context_create\",\n retryable: true,\n cause: error,\n },\n );\n }\n throwIfContextEnded(scope.context);\n outcome = {\n ok: true,\n value: await Promise.resolve().then(() => job(context as BrowserContext, scope.context)),\n };\n } catch (error) {\n if (scope.context.signal?.aborted === true) {\n outcome = {\n ok: false,\n error: operationReason(requireSignal(scope.context)),\n };\n } else if (isBrowserDisconnected(error)) {\n outcome = {\n ok: false,\n error: new NodeRenderError(\n NodeRenderErrorCode.BrowserDisconnected,\n \"Chromium disconnected during rendering\",\n { stage: \"browser\", retryable: true, cause: error },\n ),\n };\n } else {\n outcome = {\n ok: false,\n error: normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.RenderFailed,\n \"Browser rendering failed\",\n \"render\",\n true,\n ),\n };\n }\n }\n\n scope.context.signal?.removeEventListener(\"abort\", requestContextClose);\n if (context !== undefined) {\n try {\n await cleanupContext();\n } catch (cleanupError) {\n if (\n outcome.ok ||\n (cleanupError instanceof NodeRenderError && cleanupError.stage === \"browser_cleanup\")\n ) {\n outcome = { ok: false, error: cleanupError };\n }\n }\n }\n if (outcome.ok) {\n return outcome.value;\n }\n throw outcome.error;\n }\n\n private finishUnderlying(scope: OperationScope): void {\n scope.cleanup();\n this.activeScopes.delete(scope);\n this.activeJobs -= 1;\n const next = this.pendingJobs.shift();\n if (next !== undefined && this.closeBehavior !== \"cancel\") {\n this.activeJobs += 1;\n next.start();\n } else if (next !== undefined) {\n next.reject(new OperationShutdownError(\"render\"));\n }\n if (this.activeJobs === 0 && this.pendingJobs.length === 0) {\n for (const resolve of this.idleResolvers.splice(0)) {\n resolve();\n }\n }\n }\n\n private getBrowser(scope: OperationScope): Promise<BrowserHandle> {\n if (this.browserPromise !== undefined) {\n if (this.launchPending) {\n this.launchWaiters.add(scope);\n if (this.launchError !== undefined) {\n scope.abort(this.launchError);\n }\n }\n return this.browserPromise;\n }\n this.forceCloseBrowser = undefined;\n this.forceClosePromise = undefined;\n this.launchPending = true;\n this.launchAbandoned = false;\n this.launchError = undefined;\n this.launchWaiters.add(scope);\n const launchController = new AbortController();\n this.launchController = launchController;\n const deadlineMs = Date.now() + INTERNAL_LAUNCH_TIMEOUT_MS;\n const launchOperation: OperationContext = {\n signal: launchController.signal,\n deadlineMs,\n };\n const timeout = setTimeout(() => {\n const error = new NodeRenderError(\n NodeRenderErrorCode.BrowserFailed,\n \"Chromium launch deadline exceeded\",\n {\n stage: \"browser_launch\",\n retryable: true,\n },\n );\n this.abandonLaunch(error);\n }, INTERNAL_LAUNCH_TIMEOUT_MS);\n const launched = Promise.resolve().then(() =>\n this.launcher.launch(this.launchOptions, launchOperation),\n );\n let tracked: Promise<BrowserHandle>;\n tracked = Promise.resolve(launched)\n .then(async (browser) => {\n clearTimeout(timeout);\n this.launchPending = false;\n this.launchWaiters.clear();\n if (this.launchAbandoned || !this.accepting) {\n await this.forceCloseHandleOnce(browser);\n if (this.browserPromise === tracked) {\n this.browserPromise = undefined;\n }\n return browser;\n }\n this.currentBrowser = browser;\n browser.on(\"disconnected\", () => {\n if (this.browserPromise === tracked) {\n this.browserPromise = undefined;\n this.currentBrowser = undefined;\n }\n });\n return browser;\n })\n .catch((error: unknown) => {\n clearTimeout(timeout);\n this.launchPending = false;\n this.launchWaiters.clear();\n if (this.browserPromise === tracked) {\n this.browserPromise = undefined;\n }\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.BrowserFailed,\n \"Chromium launch failed\",\n \"browser_launch\",\n true,\n );\n });\n this.browserPromise = tracked;\n return tracked;\n }\n\n private async finishClose(operation: OperationContext): Promise<void> {\n try {\n await raceWithContext(this.waitForIdle(), operation);\n } catch (error) {\n this.closeBehavior = \"cancel\";\n const shutdown = new OperationShutdownError(\"render\");\n for (const pending of this.pendingJobs.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"render\");\n }\n await this.forceCloseBrowserOnce();\n throw error;\n }\n const browserPromise = this.browserPromise;\n if (browserPromise === undefined) {\n return;\n }\n let browser: BrowserHandle;\n try {\n browser = await raceWithContext(browserPromise, operation);\n } catch (error) {\n if (isOperationError(error) && error.code === OperationErrorCode.Shutdown) {\n return;\n }\n await this.forceCloseBrowserOnce();\n throw error;\n }\n if (!browser.connected) {\n return;\n }\n try {\n await raceWithContext(\n cleanupWithDeadline(browser.close(), () => this.forceCloseBrowserOnce(browser)),\n operation,\n );\n } catch (error) {\n await this.forceCloseBrowserOnce(browser);\n if (isOperationError(error)) {\n throw error;\n }\n throw new NodeRenderError(NodeRenderErrorCode.CloseFailed, \"Chromium close failed\", {\n stage: \"browser_close\",\n retryable: true,\n cause: error,\n });\n }\n }\n\n private waitForIdle(): Promise<void> {\n if (this.activeJobs === 0 && this.pendingJobs.length === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n\n private forceCloseBrowserOnce(browser?: BrowserHandle): Promise<void> {\n if (this.launchPending) {\n this.abandonLaunch(new OperationShutdownError(\"browser_close\"));\n return Promise.resolve();\n }\n if (browser !== undefined) {\n return this.forceCloseHandleOnce(browser);\n }\n const browserPromise = this.browserPromise;\n return browserPromise === undefined\n ? Promise.resolve()\n : browserPromise.then(\n (handle) => this.forceCloseHandleOnce(handle),\n () => undefined,\n );\n }\n\n private abandonLaunch(error: unknown): void {\n if (!this.launchPending) {\n return;\n }\n this.launchAbandoned = true;\n this.launchError = error;\n this.launchController?.abort(error);\n for (const waiter of this.launchWaiters) {\n waiter.abort(error);\n }\n }\n\n private forceCloseHandleOnce(browser: BrowserHandle): Promise<void> {\n if (this.currentBrowser === browser) {\n this.currentBrowser = undefined;\n this.browserPromise = undefined;\n }\n if (this.forceCloseBrowser !== browser || this.forceClosePromise === undefined) {\n this.forceCloseBrowser = browser;\n this.forceClosePromise = browser.forceClose().catch((error: unknown) => {\n throw new NodeRenderError(NodeRenderErrorCode.CleanupFailed, \"Browser cleanup failed\", {\n stage: \"browser_cleanup\",\n retryable: true,\n cause: error,\n });\n });\n }\n return this.forceClosePromise;\n }\n}\n\n/**\n * The Puppeteer entry point, injected so the orphan guard below can be exercised without\n * a real Chromium. The default imports `puppeteer` on first launch, not at construction.\n */\nexport type PuppeteerLaunch = (options: LaunchOptions) => Promise<BrowserHandle>;\n\nasync function importPuppeteerAndLaunch(options: LaunchOptions): Promise<BrowserHandle> {\n const { launch } = await import(\"puppeteer\");\n return new PuppeteerBrowserHandle(await launch(options));\n}\n\nexport class PuppeteerBrowserLauncher implements BrowserLauncher {\n private readonly launchBrowser: PuppeteerLaunch;\n\n constructor(launchBrowser: PuppeteerLaunch = importPuppeteerAndLaunch) {\n this.launchBrowser = launchBrowser;\n }\n\n async launch(options: LaunchOptions, operation: OperationContext): Promise<BrowserHandle> {\n const deadlineMs = operation.deadlineMs ?? Date.now() + INTERNAL_LAUNCH_TIMEOUT_MS;\n const timeout = Math.max(1, deadlineMs - Date.now());\n try {\n // `operation.signal` is deliberately not handed to Puppeteer. The launch is shared,\n // so one caller's abort must not kill a browser other callers are waiting on; the\n // runtime decides when a launch is abandoned and this method races that decision.\n const launching = this.launchBrowser({\n ...options,\n timeout: Math.min(options.timeout ?? timeout, timeout),\n });\n try {\n return await raceWithContext(launching, operation);\n } catch (error) {\n // Losing the race abandons the launch, but Chromium is already starting and this\n // is the only reference to it. Kill whatever it produces before reporting the\n // failure, so a cancelled cold start cannot leave a live browser behind and so\n // the runtime — which awaits this promise before finishing `close()` — cannot\n // report `closed` while a browser is still coming up.\n await launching.then(\n (handle) => handle.forceClose().catch(() => undefined),\n () => undefined,\n );\n throw error;\n }\n } catch (error) {\n if (isMissingBrowserError(error)) {\n throw new NodeRenderError(\n NodeRenderErrorCode.BrowserBinaryMissing,\n \"Chromium executable is unavailable\",\n { stage: \"browser_launch\", retryable: false, cause: error },\n );\n }\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.BrowserFailed,\n \"Chromium launch failed\",\n \"browser_launch\",\n true,\n );\n }\n }\n}\n\nclass PuppeteerBrowserHandle implements BrowserHandle {\n private readonly browser: Browser;\n\n constructor(browser: Browser) {\n this.browser = browser;\n }\n\n get connected(): boolean {\n return this.browser.connected;\n }\n\n createBrowserContext(options?: BrowserContextOptions): Promise<BrowserContext> {\n return this.browser.createBrowserContext(options);\n }\n\n close(): Promise<void> {\n return this.browser.close();\n }\n\n async forceClose(): Promise<void> {\n this.browser.process()?.kill(\"SIGKILL\");\n try {\n await this.browser.disconnect();\n } catch {\n // The transport may already be gone after a forced process kill.\n }\n }\n\n on(event: \"disconnected\", handler: () => void): void {\n this.browser.on(event, handler);\n }\n}\n\nfunction cleanupWithDeadline(\n cleanup: Promise<void>,\n forceCleanup: () => Promise<void>,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n // Graceful cleanup can land while the forced teardown it triggered is still\n // running. The resource is released either way, so a late success resolves\n // rather than reporting a healthy render as a cleanup failure.\n let closedGracefully = false;\n const timeout = setTimeout(() => {\n if (settled) {\n return;\n }\n settled = true;\n void forceCleanup().then(() => {\n if (closedGracefully) {\n resolve();\n return undefined;\n }\n reject(\n new NodeRenderError(NodeRenderErrorCode.CleanupFailed, \"Cleanup deadline exceeded\", {\n stage: \"context_cleanup\",\n retryable: true,\n }),\n );\n return undefined;\n }, reject);\n }, INTERNAL_CLEANUP_TIMEOUT_MS);\n void cleanup.then(\n () => {\n closedGracefully = true;\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n resolve();\n }\n return undefined;\n },\n (error: unknown) => {\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n void forceCleanup().then(() => {\n reject(\n new NodeRenderError(\n NodeRenderErrorCode.CleanupFailed,\n \"Browser context cleanup failed\",\n {\n stage: \"context_cleanup\",\n retryable: true,\n cause: error,\n },\n ),\n );\n return undefined;\n }, reject);\n }\n return undefined;\n },\n );\n });\n}\n\nfunction throwIfContextEnded(operation: OperationContext): void {\n if (operation.signal?.aborted === true) {\n throw operationReason(operation.signal);\n }\n if (operation.deadlineMs !== undefined && Date.now() >= operation.deadlineMs) {\n throw new OperationDeadlineExceededError(\"render\");\n }\n}\n\nfunction requireSignal(operation: OperationContext): AbortSignal {\n if (operation.signal === undefined) {\n throw new OperationShutdownError(\"operation\");\n }\n return operation.signal;\n}\n\nfunction isBrowserDisconnected(error: unknown): boolean {\n return (\n error instanceof Error &&\n (error.message.includes(\"disconnected\") ||\n error.message.includes(\"Target closed\") ||\n error.message.includes(\"Connection closed\"))\n );\n}\n\nfunction validatePositiveInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw invalidNodeOptions(`${name} must be a positive integer`);\n }\n}\n\nfunction validateNonNegativeInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw invalidNodeOptions(`${name} must be a non-negative integer`);\n }\n}\n\nfunction isMissingBrowserError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n return (\n error.message.includes(\"Could not find Chrome\") ||\n error.message.includes(\"Browser was not found\") ||\n error.message.includes(\"executable doesn't exist\")\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"puppeteer.js","names":["resolver"],"sources":["../src/errors.ts","../src/katex-assets.ts","../src/mermaid-assets.ts","../src/node-options.ts","../src/operation-control.ts","../src/puppeteer-render-runtime.ts"],"sourcesContent":["import {\n isOperationError,\n type OperationError,\n type StructuredRendererError,\n type UploadReceipt,\n} from \"slackmark\";\n\nimport type { NodeConverterStatus } from \"./status.js\";\n\n/**\n * Registry-keyed marker, not a module-local symbol.\n *\n * Each published entry (`slackmark-node`, `slackmark-node/renderers`,\n * `slackmark-node/puppeteer`) is bundled without code splitting, so every entry carries\n * its own copy of {@link NodeRenderError} and `instanceof` is false for an error that\n * crosses an entry boundary. A renderer always crosses one: the renderers live in\n * `/renderers` and the runtime that throws at them lives in `/puppeteer`. `Symbol.for`\n * keys are shared by every copy, which is what makes {@link isNodeRenderError} reliable.\n */\nconst NODE_RENDER_ERROR_BRAND = Symbol.for(\"slackmark.error.nodeRender\");\n\nexport const NodeRenderErrorCode = {\n AssetMissing: \"asset_missing\",\n BrowserBinaryMissing: \"browser_binary_missing\",\n BrowserDisconnected: \"browser_disconnected\",\n BrowserFailed: \"browser_failed\",\n CleanupFailed: \"cleanup_failed\",\n CloseFailed: \"close_failed\",\n ContextFailed: \"context_failed\",\n DimensionLimit: \"dimension_limit\",\n OutputLimit: \"output_limit\",\n QueueFull: \"queue_full\",\n RenderFailed: \"render_failed\",\n SourceLimit: \"source_limit\",\n} as const;\n\nexport type NodeRenderErrorCode = (typeof NodeRenderErrorCode)[keyof typeof NodeRenderErrorCode];\n\nexport const NodeRenderStage = {\n Admission: \"admission\",\n AssetLoad: \"asset_load\",\n Browser: \"browser\",\n BrowserCleanup: \"browser_cleanup\",\n BrowserClose: \"browser_close\",\n BrowserLaunch: \"browser_launch\",\n ContextCleanup: \"context_cleanup\",\n ContextCreate: \"context_create\",\n Layout: \"layout\",\n OutputValidation: \"output_validation\",\n Render: \"render\",\n SourceValidation: \"source_validation\",\n} as const;\n\nexport type NodeRenderStage = (typeof NodeRenderStage)[keyof typeof NodeRenderStage];\n\nexport interface NodeRenderErrorOptions {\n readonly stage: NodeRenderStage;\n readonly retryable: boolean;\n readonly rendererId?: string | undefined;\n readonly cause?: unknown;\n}\n\nexport class NodeShutdownTimeoutError extends Error {\n override readonly name: string;\n readonly code: \"shutdown_timeout\";\n readonly stage: \"close\";\n readonly retryable: true;\n readonly status: NodeConverterStatus;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(\n status: NodeConverterStatus,\n receipts: ReadonlyArray<UploadReceipt>,\n settledReceipts: Promise<ReadonlyArray<UploadReceipt>>,\n ) {\n super(\"Node converter shutdown timed out\");\n this.name = \"NodeShutdownTimeoutError\";\n this.code = \"shutdown_timeout\";\n this.stage = \"close\";\n this.retryable = true;\n this.status = status;\n this.receipts = Object.freeze([...receipts]);\n this.settledReceipts = settledReceipts;\n }\n}\n\n/**\n * Sanitized failure from the Node rendering boundary.\n */\nexport class NodeRenderError extends Error implements StructuredRendererError {\n static {\n Object.defineProperty(this.prototype, NODE_RENDER_ERROR_BRAND, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n }\n\n readonly code: NodeRenderErrorCode;\n readonly stage: NodeRenderStage;\n readonly retryable: boolean;\n readonly rendererId: string | undefined;\n\n constructor(\n code: NodeRenderErrorCode,\n message: string,\n options: NodeRenderErrorOptions = {\n stage: \"render\",\n retryable: false,\n },\n ) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = \"NodeRenderError\";\n this.code = code;\n this.stage = options.stage;\n this.retryable = options.retryable;\n this.rendererId = options.rendererId;\n }\n}\n\n/**\n * Identifies a {@link NodeRenderError} from any entry of this package. Prefer this to\n * `instanceof`, which is false across an entry boundary.\n */\nexport function isNodeRenderError(value: unknown): value is NodeRenderError {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n try {\n return Reflect.get(value, NODE_RENDER_ERROR_BRAND) === true;\n } catch {\n // A hostile getter must not escape the guard.\n return false;\n }\n}\n\nexport function normalizeNodeRenderError(\n error: unknown,\n code: NodeRenderErrorCode,\n message: string,\n stage: NodeRenderStage = NodeRenderStage.Render,\n retryable = false,\n): NodeRenderError | OperationError {\n return isNodeRenderError(error) || isOperationError(error)\n ? error\n : new NodeRenderError(code, message, { stage, retryable, cause: error });\n}\n","import { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nimport { NodeRenderErrorCode, normalizeNodeRenderError } from \"./errors.js\";\n\nconst resolver = createRequire(import.meta.url);\nconst WOFF2_URL_RE = /url\\(fonts\\/([A-Za-z0-9_-]+\\.woff2)\\)/g;\nconst LEGACY_FONT_SOURCE_RE =\n /, url\\(fonts\\/[A-Za-z0-9_-]+\\.(?:woff|ttf)\\) format\\(\"(?:woff|truetype)\"\\)/g;\n\n/**\n * Loads browser-ready KaTeX CSS without external network dependencies.\n */\nexport interface KatexAssetLoader {\n loadCss(): Promise<string>;\n loadScript(): Promise<string>;\n}\n\n/**\n * Reads KaTeX's installed CSS/fonts and embeds WOFF2 files as data URLs once.\n */\nexport class LocalKatexAssetLoader implements KatexAssetLoader {\n private cssPromise: Promise<string> | undefined;\n private scriptPromise: Promise<string> | undefined;\n\n constructor() {\n this.cssPromise = undefined;\n this.scriptPromise = undefined;\n }\n\n loadScript(): Promise<string> {\n this.scriptPromise ??= readFile(resolver.resolve(\"katex/dist/katex.min.js\"), \"utf8\").catch(\n (error: unknown) => {\n this.scriptPromise = undefined;\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.AssetMissing,\n \"Unable to load local KaTeX script\",\n \"asset_load\",\n false,\n );\n },\n );\n return this.scriptPromise;\n }\n\n loadCss(): Promise<string> {\n this.cssPromise ??= this.loadCssFromPackage().catch((error: unknown) => {\n this.cssPromise = undefined;\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.AssetMissing,\n \"Unable to load local KaTeX assets\",\n \"asset_load\",\n false,\n );\n });\n return this.cssPromise;\n }\n\n private async loadCssFromPackage(): Promise<string> {\n const cssPath = resolver.resolve(\"katex/dist/katex.css\");\n const css = await readFile(cssPath, \"utf8\");\n const fontNames = new Set<string>();\n for (const match of css.matchAll(WOFF2_URL_RE)) {\n const fontName = match[1];\n if (fontName !== undefined) {\n fontNames.add(fontName);\n }\n }\n\n const encodedFonts = await Promise.all(\n [...fontNames].map(async (fontName): Promise<readonly [string, string]> => {\n const data = await readFile(join(dirname(cssPath), \"fonts\", fontName));\n return [fontName, data.toString(\"base64\")];\n }),\n );\n\n let embedded = css.replace(LEGACY_FONT_SOURCE_RE, \"\");\n for (const [fontName, base64] of encodedFonts) {\n embedded = embedded.replaceAll(\n `url(fonts/${fontName})`,\n `url(data:font/woff2;base64,${base64})`,\n );\n }\n return embedded;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\n\nimport { NodeRenderError, NodeRenderErrorCode } from \"./errors.js\";\n\nconst resolver = createRequire(import.meta.url);\n\nexport interface MermaidAssetLoader {\n loadScript(): Promise<string>;\n}\n\nexport class LocalMermaidAssetLoader implements MermaidAssetLoader {\n private scriptPromise: Promise<string> | undefined;\n\n constructor() {\n this.scriptPromise = undefined;\n }\n\n loadScript(): Promise<string> {\n this.scriptPromise ??= readFile(resolver.resolve(\"mermaid/dist/mermaid.min.js\"), \"utf8\").catch(\n (error: unknown) => {\n this.scriptPromise = undefined;\n throw new NodeRenderError(\n NodeRenderErrorCode.AssetMissing,\n \"Unable to load Mermaid browser assets\",\n {\n stage: \"asset_load\",\n retryable: false,\n cause: error,\n },\n );\n },\n );\n return this.scriptPromise;\n }\n}\n","import { ConfigurationError } from \"slackmark\";\n\nexport function snapshotNodeOptions<T extends object>(\n options: T,\n allowed: ReadonlyArray<string>,\n label: string,\n): T {\n if (!isPlainNodeObject(options)) {\n throw invalidNodeOptions(`${label} options must be a plain object`);\n }\n const allowedKeys = new Set(allowed);\n const snapshot: Record<string, unknown> = {};\n let keys: ReadonlyArray<string>;\n try {\n keys = Object.keys(options);\n } catch (cause) {\n throw invalidNodeOptions(`${label} options could not be inspected`, cause);\n }\n for (const key of keys) {\n if (!allowedKeys.has(key)) {\n throw invalidNodeOptions(`Unknown ${label} option: ${key}`);\n }\n try {\n snapshot[key] = Reflect.get(options, key);\n } catch (cause) {\n throw invalidNodeOptions(`${label}.${key} could not be read`, cause);\n }\n }\n return Object.freeze(snapshot) as T;\n}\n\nexport function snapshotOpenNodeOptions<T extends object>(options: T, label: string): T {\n let keys: ReadonlyArray<string>;\n try {\n keys = Object.keys(options);\n } catch (cause) {\n throw invalidNodeOptions(`${label} could not be inspected`, cause);\n }\n return snapshotNodeOptions(options, keys, label);\n}\n\nexport function assertNodeMethod(collaborator: unknown, method: string, label: string): void {\n try {\n if (\n (typeof collaborator !== \"object\" && typeof collaborator !== \"function\") ||\n collaborator === null ||\n typeof Reflect.get(collaborator, method) !== \"function\"\n ) {\n throw new TypeError(`${method} must be a function`);\n }\n } catch (cause) {\n throw invalidNodeOptions(`${label} collaborator is invalid`, cause);\n }\n}\n\nexport function invalidNodeOptions(message: string, cause?: unknown): ConfigurationError {\n return new ConfigurationError(message, {\n code: \"invalid_node_configuration\",\n stage: \"configuration\",\n cause,\n });\n}\n\nfunction isPlainNodeObject(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n let prototype: object | null;\n try {\n prototype = Object.getPrototypeOf(value);\n } catch {\n return false;\n }\n return prototype === Object.prototype || prototype === null;\n}\n","import {\n ConfigurationError,\n OperationAbortedError,\n OperationDeadlineExceededError,\n OperationShutdownError,\n cloneOperationError,\n isOperationError,\n type OperationContext,\n type OperationError,\n type OperationOptions,\n} from \"slackmark\";\n\nexport class OperationScope {\n readonly context: OperationContext;\n private readonly parentSignal: AbortSignal | undefined;\n private readonly controller: AbortController;\n private readonly abortFromParent: () => void;\n private readonly deadlineTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(context: OperationContext, stage: string) {\n this.parentSignal = context.signal;\n this.controller = new AbortController();\n this.abortFromParent = (): void => {\n const reason = this.parentSignal?.reason;\n this.controller.abort(\n isOperationError(reason)\n ? cloneOperationError(reason, stage)\n : new OperationAbortedError(stage, { cause: reason }),\n );\n };\n if (this.parentSignal?.aborted === true) {\n this.abortFromParent();\n } else {\n this.parentSignal?.addEventListener(\"abort\", this.abortFromParent, {\n once: true,\n });\n }\n if (context.deadlineMs === undefined) {\n this.deadlineTimer = undefined;\n } else if (context.deadlineMs <= Date.now()) {\n this.deadlineTimer = undefined;\n this.controller.abort(new OperationDeadlineExceededError(stage));\n } else {\n this.deadlineTimer = setTimeout(() => {\n this.controller.abort(new OperationDeadlineExceededError(stage));\n }, context.deadlineMs - Date.now());\n }\n this.context = Object.freeze({\n signal: this.controller.signal,\n deadlineMs: context.deadlineMs,\n });\n }\n\n abortForShutdown(stage: string): void {\n this.controller.abort(new OperationShutdownError(stage));\n }\n\n abort(reason: unknown): void {\n this.controller.abort(reason);\n }\n\n race<T>(promise: Promise<T>): Promise<T> {\n return raceWithContext(promise, this.context);\n }\n\n cleanup(): void {\n if (this.deadlineTimer !== undefined) {\n clearTimeout(this.deadlineTimer);\n }\n this.parentSignal?.removeEventListener(\"abort\", this.abortFromParent);\n }\n}\n\nexport function createOperationScope(\n options: OperationOptions = {},\n stage: string,\n): OperationScope {\n validateOperationOptions(options);\n return new OperationScope(\n {\n signal: options.signal,\n deadlineMs: options.timeoutMs === undefined ? undefined : Date.now() + options.timeoutMs,\n },\n stage,\n );\n}\n\nexport function raceWithContext<T>(promise: Promise<T>, context: OperationContext): Promise<T> {\n const signal = context.signal;\n if (signal?.aborted === true) {\n return Promise.reject(signal.reason ?? new OperationAbortedError(\"operation\"));\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = (): void => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(signal?.reason ?? new OperationAbortedError(\"operation\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n void promise.then(\n (value) => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve(value);\n return undefined;\n },\n (error: unknown) => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nexport function operationReason(signal: AbortSignal): OperationError {\n return isOperationError(signal.reason)\n ? signal.reason\n : new OperationAbortedError(\"operation\", { cause: signal.reason });\n}\n\nfunction validateOperationOptions(options: OperationOptions): void {\n if (!isPlainObject(options)) {\n throw new ConfigurationError(\"Operation options must be a plain object\", {\n code: \"invalid_operation_options\",\n stage: \"configuration\",\n });\n }\n for (const key of Object.keys(options)) {\n if (key !== \"signal\" && key !== \"timeoutMs\") {\n throw new ConfigurationError(`Unknown operation option: ${key}`, {\n code: \"invalid_operation_options\",\n stage: \"configuration\",\n });\n }\n }\n if (\n options.signal !== undefined &&\n (typeof options.signal !== \"object\" ||\n options.signal === null ||\n typeof options.signal.addEventListener !== \"function\" ||\n typeof options.signal.removeEventListener !== \"function\")\n ) {\n throw new ConfigurationError(\"signal must be an AbortSignal\", {\n code: \"invalid_signal\",\n stage: \"configuration\",\n });\n }\n if (\n options.timeoutMs !== undefined &&\n (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0)\n ) {\n throw new ConfigurationError(\"timeoutMs must be positive\", {\n code: \"invalid_timeout\",\n stage: \"configuration\",\n });\n }\n}\n\nexport function isPlainObject(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n","import type { Browser, BrowserContext, BrowserContextOptions, LaunchOptions } from \"puppeteer\";\nimport {\n OperationDeadlineExceededError,\n OperationErrorCode,\n OperationShutdownError,\n isOperationError,\n type OperationContext,\n} from \"slackmark\";\n\nimport {\n isNodeRenderError,\n NodeRenderError,\n NodeRenderErrorCode,\n normalizeNodeRenderError,\n} from \"./errors.js\";\nimport {\n assertNodeMethod,\n invalidNodeOptions,\n snapshotNodeOptions,\n snapshotOpenNodeOptions,\n} from \"./node-options.js\";\nimport { OperationScope, operationReason, raceWithContext } from \"./operation-control.js\";\nimport type { NodeWorkStatus } from \"./status.js\";\n\nconst DEFAULT_CONCURRENCY = 2;\nconst DEFAULT_MAX_QUEUE_SIZE = 32;\nconst INTERNAL_LAUNCH_TIMEOUT_MS = 10_000;\nconst INTERNAL_CLEANUP_TIMEOUT_MS = 2_000;\nconst DENY_NETWORK_PROXY = \"http://127.0.0.1:9\";\n\nexport type CloseBehavior = \"drain\" | \"cancel\";\n\nexport type WorkQueueStatus = NodeWorkStatus;\n\nexport type PuppeteerRenderJob<T> = (\n context: BrowserContext,\n operation: OperationContext,\n) => Promise<T>;\n\nexport interface BrowserHandle {\n readonly connected: boolean;\n createBrowserContext(options?: BrowserContextOptions): Promise<BrowserContext>;\n close(): Promise<void>;\n forceClose(): Promise<void>;\n on(event: \"disconnected\", handler: () => void): void;\n}\n\nexport interface BrowserLauncher {\n launch(options: LaunchOptions, operation: OperationContext): Promise<BrowserHandle>;\n}\n\nexport interface RenderRuntime {\n run<T>(job: PuppeteerRenderJob<T>, operation: OperationContext): Promise<T>;\n warmup(operation: OperationContext): Promise<void>;\n close(operation: OperationContext, behavior?: CloseBehavior): Promise<void>;\n status(): WorkQueueStatus;\n}\n\nexport interface PuppeteerRenderRuntimeOptions {\n readonly launcher: BrowserLauncher;\n readonly launchOptions?: LaunchOptions | undefined;\n readonly concurrency?: number | undefined;\n readonly maxQueueSize?: number | undefined;\n}\n\ninterface PendingJob {\n start(): void;\n reject(error: unknown): void;\n}\n\nexport class PuppeteerRenderRuntime implements RenderRuntime {\n private readonly launcher: BrowserLauncher;\n private readonly launchOptions: LaunchOptions;\n private readonly concurrency: number;\n private readonly maxQueueSize: number;\n private readonly contextOptions: BrowserContextOptions;\n private readonly pendingJobs: PendingJob[];\n private readonly activeScopes: Set<OperationScope>;\n private readonly idleResolvers: Array<() => void>;\n private activeJobs: number;\n private browserPromise: Promise<BrowserHandle> | undefined;\n private currentBrowser: BrowserHandle | undefined;\n private launchController: AbortController | undefined;\n private readonly launchWaiters: Set<OperationScope>;\n private launchPending: boolean;\n private launchAbandoned: boolean;\n private launchError: unknown;\n private forceCloseBrowser: BrowserHandle | undefined;\n private forceClosePromise: Promise<void> | undefined;\n private closePromise: Promise<void> | undefined;\n private closeBehavior: CloseBehavior | undefined;\n private accepting: boolean;\n\n constructor(options: PuppeteerRenderRuntimeOptions) {\n const validated = snapshotNodeOptions(\n options,\n [\"launcher\", \"launchOptions\", \"concurrency\", \"maxQueueSize\"],\n \"PuppeteerRenderRuntime\",\n );\n assertNodeMethod(validated.launcher, \"launch\", \"BrowserLauncher\");\n const launchOptions =\n validated.launchOptions === undefined\n ? undefined\n : snapshotOpenNodeOptions(validated.launchOptions, \"Puppeteer launchOptions\");\n this.launcher = validated.launcher;\n this.launchOptions = {\n headless: \"shell\",\n ...launchOptions,\n };\n this.concurrency = validated.concurrency ?? DEFAULT_CONCURRENCY;\n this.maxQueueSize = validated.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n this.contextOptions = {\n proxyServer: DENY_NETWORK_PROXY,\n proxyBypassList: [\"<-loopback>\"],\n downloadBehavior: { policy: \"deny\" },\n };\n this.pendingJobs = [];\n this.activeScopes = new Set();\n this.idleResolvers = [];\n this.activeJobs = 0;\n this.browserPromise = undefined;\n this.currentBrowser = undefined;\n this.launchController = undefined;\n this.launchWaiters = new Set();\n this.launchPending = false;\n this.launchAbandoned = false;\n this.launchError = undefined;\n this.forceCloseBrowser = undefined;\n this.forceClosePromise = undefined;\n this.closePromise = undefined;\n this.closeBehavior = undefined;\n this.accepting = true;\n\n validatePositiveInteger(this.concurrency, \"concurrency\");\n validateNonNegativeInteger(this.maxQueueSize, \"maxQueueSize\");\n }\n\n run<T>(job: PuppeteerRenderJob<T>, operation: OperationContext): Promise<T> {\n if (!this.accepting) {\n return Promise.reject(new OperationShutdownError(\"render_admission\"));\n }\n if (this.activeJobs >= this.concurrency && this.pendingJobs.length >= this.maxQueueSize) {\n return Promise.reject(\n new NodeRenderError(\n NodeRenderErrorCode.QueueFull,\n `Render queue is full (max ${String(this.maxQueueSize)} pending)`,\n { stage: \"admission\", retryable: true },\n ),\n );\n }\n\n return new Promise<T>((resolve, reject) => {\n const scope = new OperationScope(operation, \"render\");\n let pending: PendingJob;\n const abortWhileQueued = (): void => {\n const index = this.pendingJobs.indexOf(pending);\n if (index >= 0) {\n this.pendingJobs.splice(index, 1);\n pending.reject(operationReason(requireSignal(scope.context)));\n }\n };\n pending = {\n start: (): void => {\n scope.context.signal?.removeEventListener(\"abort\", abortWhileQueued);\n this.activeScopes.add(scope);\n this.startUnderlying(job, scope, resolve, reject);\n },\n reject: (error: unknown): void => {\n scope.context.signal?.removeEventListener(\"abort\", abortWhileQueued);\n scope.cleanup();\n reject(error);\n },\n };\n if (scope.context.signal?.aborted === true) {\n pending.reject(operationReason(requireSignal(scope.context)));\n return;\n }\n if (this.activeJobs < this.concurrency) {\n this.activeJobs += 1;\n pending.start();\n return;\n }\n scope.context.signal?.addEventListener(\"abort\", abortWhileQueued, { once: true });\n this.pendingJobs.push(pending);\n });\n }\n\n warmup(operation: OperationContext): Promise<void> {\n return this.run(async () => undefined, operation);\n }\n\n close(operation: OperationContext, behavior: CloseBehavior = \"cancel\"): Promise<void> {\n if (this.closePromise !== undefined) {\n return this.closePromise;\n }\n const closeScope = new OperationScope(operation, \"browser_close\");\n this.accepting = false;\n this.closeBehavior = behavior;\n if (behavior === \"cancel\") {\n const shutdown = new OperationShutdownError(\"render\");\n for (const pending of this.pendingJobs.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"render\");\n }\n this.abandonLaunch(shutdown);\n }\n this.closePromise = this.finishClose(closeScope.context).finally(() => {\n closeScope.cleanup();\n });\n return this.closePromise;\n }\n\n status(): WorkQueueStatus {\n return Object.freeze({\n accepting: this.accepting,\n active: this.activeJobs,\n queued: this.pendingJobs.length,\n retainedBytes: 0,\n });\n }\n\n private startUnderlying<T>(\n job: PuppeteerRenderJob<T>,\n scope: OperationScope,\n resolve: (value: T | PromiseLike<T>) => void,\n reject: (error: unknown) => void,\n ): void {\n const underlying = this.executeUnderlying(job, scope);\n void scope.race(underlying).then(resolve, reject);\n void underlying.then(\n () => {\n this.finishUnderlying(scope);\n return undefined;\n },\n () => {\n this.finishUnderlying(scope);\n return undefined;\n },\n );\n }\n\n private async executeUnderlying<T>(\n job: PuppeteerRenderJob<T>,\n scope: OperationScope,\n ): Promise<T> {\n let browser: BrowserHandle | undefined;\n let context: BrowserContext | undefined;\n let contextClosePromise: Promise<void> | undefined;\n let contextCleanupPromise: Promise<void> | undefined;\n let outcome:\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: unknown };\n const closeContext = (): Promise<void> => {\n if (context === undefined) {\n return Promise.resolve();\n }\n contextClosePromise ??= Promise.resolve().then(() => (context as BrowserContext).close());\n return contextClosePromise;\n };\n const cleanupContext = (): Promise<void> => {\n contextCleanupPromise ??= cleanupWithDeadline(closeContext(), async () => {\n await this.forceCloseBrowserOnce(browser);\n });\n return contextCleanupPromise;\n };\n const requestContextClose = (): void => {\n if (context !== undefined) {\n void cleanupContext().catch(() => undefined);\n }\n };\n scope.context.signal?.addEventListener(\"abort\", requestContextClose, { once: true });\n\n try {\n browser = await this.getBrowser(scope);\n throwIfContextEnded(scope.context);\n try {\n context = await browser.createBrowserContext(this.contextOptions);\n } catch (error) {\n if (isBrowserDisconnected(error)) {\n throw error;\n }\n throw new NodeRenderError(\n NodeRenderErrorCode.ContextFailed,\n \"Browser context creation failed\",\n {\n stage: \"context_create\",\n retryable: true,\n cause: error,\n },\n );\n }\n throwIfContextEnded(scope.context);\n outcome = {\n ok: true,\n value: await Promise.resolve().then(() => job(context as BrowserContext, scope.context)),\n };\n } catch (error) {\n if (scope.context.signal?.aborted === true) {\n outcome = {\n ok: false,\n error: operationReason(requireSignal(scope.context)),\n };\n } else if (isBrowserDisconnected(error)) {\n outcome = {\n ok: false,\n error: new NodeRenderError(\n NodeRenderErrorCode.BrowserDisconnected,\n \"Chromium disconnected during rendering\",\n { stage: \"browser\", retryable: true, cause: error },\n ),\n };\n } else {\n outcome = {\n ok: false,\n error: normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.RenderFailed,\n \"Browser rendering failed\",\n \"render\",\n true,\n ),\n };\n }\n }\n\n scope.context.signal?.removeEventListener(\"abort\", requestContextClose);\n if (context !== undefined) {\n try {\n await cleanupContext();\n } catch (cleanupError) {\n if (\n outcome.ok ||\n (isNodeRenderError(cleanupError) && cleanupError.stage === \"browser_cleanup\")\n ) {\n outcome = { ok: false, error: cleanupError };\n }\n }\n }\n if (outcome.ok) {\n return outcome.value;\n }\n throw outcome.error;\n }\n\n private finishUnderlying(scope: OperationScope): void {\n scope.cleanup();\n this.activeScopes.delete(scope);\n this.activeJobs -= 1;\n const next = this.pendingJobs.shift();\n if (next !== undefined && this.closeBehavior !== \"cancel\") {\n this.activeJobs += 1;\n next.start();\n } else if (next !== undefined) {\n next.reject(new OperationShutdownError(\"render\"));\n }\n if (this.activeJobs === 0 && this.pendingJobs.length === 0) {\n for (const resolve of this.idleResolvers.splice(0)) {\n resolve();\n }\n }\n }\n\n private getBrowser(scope: OperationScope): Promise<BrowserHandle> {\n if (this.browserPromise !== undefined) {\n if (this.launchPending) {\n this.launchWaiters.add(scope);\n if (this.launchError !== undefined) {\n scope.abort(this.launchError);\n }\n }\n return this.browserPromise;\n }\n this.forceCloseBrowser = undefined;\n this.forceClosePromise = undefined;\n this.launchPending = true;\n this.launchAbandoned = false;\n this.launchError = undefined;\n this.launchWaiters.add(scope);\n const launchController = new AbortController();\n this.launchController = launchController;\n const deadlineMs = Date.now() + INTERNAL_LAUNCH_TIMEOUT_MS;\n const launchOperation: OperationContext = {\n signal: launchController.signal,\n deadlineMs,\n };\n const timeout = setTimeout(() => {\n const error = new NodeRenderError(\n NodeRenderErrorCode.BrowserFailed,\n \"Chromium launch deadline exceeded\",\n {\n stage: \"browser_launch\",\n retryable: true,\n },\n );\n this.abandonLaunch(error);\n }, INTERNAL_LAUNCH_TIMEOUT_MS);\n const launched = Promise.resolve().then(() =>\n this.launcher.launch(this.launchOptions, launchOperation),\n );\n let tracked: Promise<BrowserHandle>;\n tracked = Promise.resolve(launched)\n .then(async (browser) => {\n clearTimeout(timeout);\n this.launchPending = false;\n this.launchWaiters.clear();\n if (this.launchAbandoned || !this.accepting) {\n await this.forceCloseHandleOnce(browser);\n if (this.browserPromise === tracked) {\n this.browserPromise = undefined;\n }\n return browser;\n }\n this.currentBrowser = browser;\n browser.on(\"disconnected\", () => {\n if (this.browserPromise === tracked) {\n this.browserPromise = undefined;\n this.currentBrowser = undefined;\n }\n });\n return browser;\n })\n .catch((error: unknown) => {\n clearTimeout(timeout);\n this.launchPending = false;\n this.launchWaiters.clear();\n if (this.browserPromise === tracked) {\n this.browserPromise = undefined;\n }\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.BrowserFailed,\n \"Chromium launch failed\",\n \"browser_launch\",\n true,\n );\n });\n this.browserPromise = tracked;\n return tracked;\n }\n\n private async finishClose(operation: OperationContext): Promise<void> {\n try {\n await raceWithContext(this.waitForIdle(), operation);\n } catch (error) {\n this.closeBehavior = \"cancel\";\n const shutdown = new OperationShutdownError(\"render\");\n for (const pending of this.pendingJobs.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"render\");\n }\n await this.forceCloseBrowserOnce();\n throw error;\n }\n const browserPromise = this.browserPromise;\n if (browserPromise === undefined) {\n return;\n }\n let browser: BrowserHandle;\n try {\n browser = await raceWithContext(browserPromise, operation);\n } catch (error) {\n if (isOperationError(error) && error.code === OperationErrorCode.Shutdown) {\n return;\n }\n await this.forceCloseBrowserOnce();\n throw error;\n }\n if (!browser.connected) {\n return;\n }\n try {\n await raceWithContext(\n cleanupWithDeadline(browser.close(), () => this.forceCloseBrowserOnce(browser)),\n operation,\n );\n } catch (error) {\n await this.forceCloseBrowserOnce(browser);\n if (isOperationError(error)) {\n throw error;\n }\n throw new NodeRenderError(NodeRenderErrorCode.CloseFailed, \"Chromium close failed\", {\n stage: \"browser_close\",\n retryable: true,\n cause: error,\n });\n }\n }\n\n private waitForIdle(): Promise<void> {\n if (this.activeJobs === 0 && this.pendingJobs.length === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n\n private forceCloseBrowserOnce(browser?: BrowserHandle): Promise<void> {\n if (this.launchPending) {\n this.abandonLaunch(new OperationShutdownError(\"browser_close\"));\n return Promise.resolve();\n }\n if (browser !== undefined) {\n return this.forceCloseHandleOnce(browser);\n }\n const browserPromise = this.browserPromise;\n return browserPromise === undefined\n ? Promise.resolve()\n : browserPromise.then(\n (handle) => this.forceCloseHandleOnce(handle),\n () => undefined,\n );\n }\n\n private abandonLaunch(error: unknown): void {\n if (!this.launchPending) {\n return;\n }\n this.launchAbandoned = true;\n this.launchError = error;\n this.launchController?.abort(error);\n for (const waiter of this.launchWaiters) {\n waiter.abort(error);\n }\n }\n\n private forceCloseHandleOnce(browser: BrowserHandle): Promise<void> {\n if (this.currentBrowser === browser) {\n this.currentBrowser = undefined;\n this.browserPromise = undefined;\n }\n if (this.forceCloseBrowser !== browser || this.forceClosePromise === undefined) {\n this.forceCloseBrowser = browser;\n this.forceClosePromise = browser.forceClose().catch((error: unknown) => {\n throw new NodeRenderError(NodeRenderErrorCode.CleanupFailed, \"Browser cleanup failed\", {\n stage: \"browser_cleanup\",\n retryable: true,\n cause: error,\n });\n });\n }\n return this.forceClosePromise;\n }\n}\n\n/**\n * The Puppeteer entry point, injected so the orphan guard below can be exercised without\n * a real Chromium. The default imports `puppeteer` on first launch, not at construction.\n */\nexport type PuppeteerLaunch = (options: LaunchOptions) => Promise<BrowserHandle>;\n\nasync function importPuppeteerAndLaunch(options: LaunchOptions): Promise<BrowserHandle> {\n const { launch } = await import(\"puppeteer\");\n return new PuppeteerBrowserHandle(await launch(options));\n}\n\nexport class PuppeteerBrowserLauncher implements BrowserLauncher {\n private readonly launchBrowser: PuppeteerLaunch;\n\n constructor(launchBrowser: PuppeteerLaunch = importPuppeteerAndLaunch) {\n this.launchBrowser = launchBrowser;\n }\n\n async launch(options: LaunchOptions, operation: OperationContext): Promise<BrowserHandle> {\n const deadlineMs = operation.deadlineMs ?? Date.now() + INTERNAL_LAUNCH_TIMEOUT_MS;\n const timeout = Math.max(1, deadlineMs - Date.now());\n try {\n // `operation.signal` is deliberately not handed to Puppeteer. The launch is shared,\n // so one caller's abort must not kill a browser other callers are waiting on; the\n // runtime decides when a launch is abandoned and this method races that decision.\n const launching = this.launchBrowser({\n ...options,\n timeout: Math.min(options.timeout ?? timeout, timeout),\n });\n try {\n return await raceWithContext(launching, operation);\n } catch (error) {\n // Losing the race abandons the launch, but Chromium is already starting and this\n // is the only reference to it. Kill whatever it produces before reporting the\n // failure, so a cancelled cold start cannot leave a live browser behind and so\n // the runtime — which awaits this promise before finishing `close()` — cannot\n // report `closed` while a browser is still coming up.\n await launching.then(\n (handle) => handle.forceClose().catch(() => undefined),\n () => undefined,\n );\n throw error;\n }\n } catch (error) {\n if (isMissingBrowserError(error)) {\n throw new NodeRenderError(\n NodeRenderErrorCode.BrowserBinaryMissing,\n \"Chromium executable is unavailable\",\n { stage: \"browser_launch\", retryable: false, cause: error },\n );\n }\n throw normalizeNodeRenderError(\n error,\n NodeRenderErrorCode.BrowserFailed,\n \"Chromium launch failed\",\n \"browser_launch\",\n true,\n );\n }\n }\n}\n\nclass PuppeteerBrowserHandle implements BrowserHandle {\n private readonly browser: Browser;\n\n constructor(browser: Browser) {\n this.browser = browser;\n }\n\n get connected(): boolean {\n return this.browser.connected;\n }\n\n createBrowserContext(options?: BrowserContextOptions): Promise<BrowserContext> {\n return this.browser.createBrowserContext(options);\n }\n\n close(): Promise<void> {\n return this.browser.close();\n }\n\n async forceClose(): Promise<void> {\n this.browser.process()?.kill(\"SIGKILL\");\n try {\n await this.browser.disconnect();\n } catch {\n // The transport may already be gone after a forced process kill.\n }\n }\n\n on(event: \"disconnected\", handler: () => void): void {\n this.browser.on(event, handler);\n }\n}\n\nfunction cleanupWithDeadline(\n cleanup: Promise<void>,\n forceCleanup: () => Promise<void>,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n // Graceful cleanup can land while the forced teardown it triggered is still\n // running. The resource is released either way, so a late success resolves\n // rather than reporting a healthy render as a cleanup failure.\n let closedGracefully = false;\n const timeout = setTimeout(() => {\n if (settled) {\n return;\n }\n settled = true;\n void forceCleanup().then(() => {\n if (closedGracefully) {\n resolve();\n return undefined;\n }\n reject(\n new NodeRenderError(NodeRenderErrorCode.CleanupFailed, \"Cleanup deadline exceeded\", {\n stage: \"context_cleanup\",\n retryable: true,\n }),\n );\n return undefined;\n }, reject);\n }, INTERNAL_CLEANUP_TIMEOUT_MS);\n void cleanup.then(\n () => {\n closedGracefully = true;\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n resolve();\n }\n return undefined;\n },\n (error: unknown) => {\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n void forceCleanup().then(() => {\n reject(\n new NodeRenderError(\n NodeRenderErrorCode.CleanupFailed,\n \"Browser context cleanup failed\",\n {\n stage: \"context_cleanup\",\n retryable: true,\n cause: error,\n },\n ),\n );\n return undefined;\n }, reject);\n }\n return undefined;\n },\n );\n });\n}\n\nfunction throwIfContextEnded(operation: OperationContext): void {\n if (operation.signal?.aborted === true) {\n throw operationReason(operation.signal);\n }\n if (operation.deadlineMs !== undefined && Date.now() >= operation.deadlineMs) {\n throw new OperationDeadlineExceededError(\"render\");\n }\n}\n\nfunction requireSignal(operation: OperationContext): AbortSignal {\n if (operation.signal === undefined) {\n throw new OperationShutdownError(\"operation\");\n }\n return operation.signal;\n}\n\nfunction isBrowserDisconnected(error: unknown): boolean {\n return (\n error instanceof Error &&\n (error.message.includes(\"disconnected\") ||\n error.message.includes(\"Target closed\") ||\n error.message.includes(\"Connection closed\"))\n );\n}\n\nfunction validatePositiveInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw invalidNodeOptions(`${name} must be a positive integer`);\n }\n}\n\nfunction validateNonNegativeInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw invalidNodeOptions(`${name} must be a non-negative integer`);\n }\n}\n\nfunction isMissingBrowserError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n return (\n error.message.includes(\"Could not find Chrome\") ||\n error.message.includes(\"Browser was not found\") ||\n error.message.includes(\"executable doesn't exist\")\n );\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ export { isNodeRenderError } from "./errors.js";
1
2
  export { KatexRenderer } from "./katex-renderer.js";
2
3
  export type { KatexRendererOptions } from "./katex-renderer.js";
3
4
  export { MermaidRenderer } from "./mermaid-renderer.js";
@@ -1 +1 @@
1
- {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../src/renderers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../src/renderers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/renderers.js CHANGED
@@ -1,6 +1,17 @@
1
1
  import { ConfigurationError, isOperationError } from "slackmark";
2
2
  import { createHash } from "node:crypto";
3
3
  //#region src/errors.ts
4
+ /**
5
+ * Registry-keyed marker, not a module-local symbol.
6
+ *
7
+ * Each published entry (`slackmark-node`, `slackmark-node/renderers`,
8
+ * `slackmark-node/puppeteer`) is bundled without code splitting, so every entry carries
9
+ * its own copy of {@link NodeRenderError} and `instanceof` is false for an error that
10
+ * crosses an entry boundary. A renderer always crosses one: the renderers live in
11
+ * `/renderers` and the runtime that throws at them lives in `/puppeteer`. `Symbol.for`
12
+ * keys are shared by every copy, which is what makes {@link isNodeRenderError} reliable.
13
+ */
14
+ const NODE_RENDER_ERROR_BRAND = Symbol.for("slackmark.error.nodeRender");
4
15
  const NodeRenderErrorCode = {
5
16
  AssetMissing: "asset_missing",
6
17
  BrowserBinaryMissing: "browser_binary_missing",
@@ -33,6 +44,14 @@ const NodeRenderStage = {
33
44
  * Sanitized failure from the Node rendering boundary.
34
45
  */
35
46
  var NodeRenderError = class extends Error {
47
+ static {
48
+ Object.defineProperty(this.prototype, NODE_RENDER_ERROR_BRAND, {
49
+ configurable: false,
50
+ enumerable: false,
51
+ value: true,
52
+ writable: false
53
+ });
54
+ }
36
55
  code;
37
56
  stage;
38
57
  retryable;
@@ -49,6 +68,18 @@ var NodeRenderError = class extends Error {
49
68
  this.rendererId = options.rendererId;
50
69
  }
51
70
  };
71
+ /**
72
+ * Identifies a {@link NodeRenderError} from any entry of this package. Prefer this to
73
+ * `instanceof`, which is false across an entry boundary.
74
+ */
75
+ function isNodeRenderError(value) {
76
+ if (typeof value !== "object" || value === null) return false;
77
+ try {
78
+ return Reflect.get(value, NODE_RENDER_ERROR_BRAND) === true;
79
+ } catch {
80
+ return false;
81
+ }
82
+ }
52
83
  //#endregion
53
84
  //#region src/image-output.ts
54
85
  const PNG_SIGNATURE = new Uint8Array([
@@ -313,7 +344,7 @@ var KatexRenderer = class {
313
344
  }, context);
314
345
  } catch (error) {
315
346
  if (isOperationError(error)) throw error;
316
- if (error instanceof NodeRenderError) {
347
+ if (isNodeRenderError(error)) {
317
348
  const sanitizedRenderFailure = error.code === NodeRenderErrorCode.RenderFailed && error.cause === void 0;
318
349
  if (error.code !== NodeRenderErrorCode.RenderFailed || sanitizedRenderFailure) throw error;
319
350
  }
@@ -508,7 +539,7 @@ var MermaidRenderer = class {
508
539
  }, context);
509
540
  } catch (error) {
510
541
  if (isOperationError(error)) throw error;
511
- if (error instanceof NodeRenderError) {
542
+ if (isNodeRenderError(error)) {
512
543
  if (error.code !== NodeRenderErrorCode.RenderFailed) throw error;
513
544
  }
514
545
  throw new NodeRenderError(NodeRenderErrorCode.RenderFailed, "Mermaid rendering failed", {
@@ -546,6 +577,6 @@ function validatePositiveFinite(value, name) {
546
577
  if (!Number.isFinite(value) || value <= 0) throw invalidNodeOptions(`${name} must be positive`);
547
578
  }
548
579
  //#endregion
549
- export { KatexRenderer, MermaidRenderer };
580
+ export { KatexRenderer, MermaidRenderer, isNodeRenderError };
550
581
 
551
582
  //# sourceMappingURL=renderers.js.map