slackmark-node 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -5
- package/dist/index.js.map +1 -1
- package/dist/katex-renderer.d.ts.map +1 -1
- package/dist/puppeteer-render-runtime.d.ts.map +1 -1
- package/dist/puppeteer.d.ts +1 -0
- package/dist/puppeteer.d.ts.map +1 -1
- package/dist/puppeteer.js +35 -4
- package/dist/puppeteer.js.map +1 -1
- package/dist/renderers.d.ts +1 -0
- package/dist/renderers.d.ts.map +1 -1
- package/dist/renderers.js +34 -3
- package/dist/renderers.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["resolver","ConfigurationError","DEFAULT_MAX_SOURCE_CHARS","DEFAULT_MAX_OUTPUT_BYTES","DEFAULT_MAX_WIDTH","DEFAULT_MAX_HEIGHT","DEFAULT_DEVICE_SCALE_FACTOR","DEFAULT_BACKGROUND_COLOR","DEFAULT_VIEWPORT_WIDTH","DEFAULT_VIEWPORT_HEIGHT","browserGlobal","validateOptions","validatePositiveInteger","validatePositiveFinite","browserGlobal","validatePositiveInteger","OperationAbortedError","OperationDeadlineExceededError","OperationShutdownError","ConfigurationError","OperationShutdownError","requireSignal","OperationErrorCode","OperationDeadlineExceededError","validatePositiveInteger","validateNonNegativeInteger","OperationShutdownError","OperationShutdownError","OperationErrorCode","ConfigurationError"],"sources":["../src/errors.ts","../src/katex-assets.ts","../src/image-output.ts","../src/node-options.ts","../src/katex-renderer.ts","../src/mermaid-assets.ts","../src/mermaid-renderer.ts","../src/operation-control.ts","../src/puppeteer-render-runtime.ts","../src/status.ts","../src/upload-scheduler.ts","../src/create-node-converter.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 { createHash } from \"node:crypto\";\n\nimport { NodeRenderError, NodeRenderErrorCode, NodeRenderStage } from \"./errors.js\";\n\nconst PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);\nconst PNG_WIDTH_OFFSET = 16;\nconst PNG_HEIGHT_OFFSET = 20;\nconst PNG_HEADER_BYTES = 24;\nconst PNG_IHDR = new Uint8Array([73, 72, 68, 82]);\nconst PNG_IHDR_OFFSET = 12;\n\nexport interface ImageLimits {\n readonly maxOutputBytes: number;\n readonly maxWidth: number;\n readonly maxHeight: number;\n}\n\nexport function deterministicPngFilename(\n prefix: string,\n source: string,\n optionsFingerprint: string,\n): string {\n const digest = createHash(\"sha256\")\n .update(prefix)\n .update(\"\\0\")\n .update(optionsFingerprint)\n .update(\"\\0\")\n .update(source)\n .digest(\"hex\")\n .slice(0, 16);\n return `${prefix}-${digest}.png`;\n}\n\nexport function assertSourceLimit(source: string, maxSourceChars: number): void {\n if (source.length > maxSourceChars) {\n throw new NodeRenderError(\n NodeRenderErrorCode.SourceLimit,\n `Render source exceeds ${String(maxSourceChars)} characters`,\n { stage: NodeRenderStage.SourceValidation, retryable: false },\n );\n }\n}\n\nexport function assertPngLimits(data: Uint8Array, limits: ImageLimits): void {\n if (data.byteLength > limits.maxOutputBytes) {\n throw new NodeRenderError(\n NodeRenderErrorCode.OutputLimit,\n `Rendered image exceeds ${String(limits.maxOutputBytes)} bytes`,\n { stage: NodeRenderStage.OutputValidation, retryable: false },\n );\n }\n const dimensions = readPngDimensions(data);\n if (dimensions === undefined) {\n throw new NodeRenderError(\n NodeRenderErrorCode.RenderFailed,\n \"Renderer returned invalid PNG data\",\n { stage: NodeRenderStage.OutputValidation, retryable: false },\n );\n }\n if (dimensions.width > limits.maxWidth || dimensions.height > limits.maxHeight) {\n throw new NodeRenderError(\n NodeRenderErrorCode.DimensionLimit,\n `Rendered image exceeds ${String(limits.maxWidth)}x${String(limits.maxHeight)} pixels`,\n { stage: NodeRenderStage.Layout, retryable: false },\n );\n }\n}\n\nfunction readPngDimensions(\n data: Uint8Array,\n): { readonly width: number; readonly height: number } | undefined {\n if (data.byteLength < PNG_HEADER_BYTES) {\n return undefined;\n }\n for (const [index, byte] of PNG_SIGNATURE.entries()) {\n if (data[index] !== byte) {\n return undefined;\n }\n }\n for (const [index, byte] of PNG_IHDR.entries()) {\n if (data[PNG_IHDR_OFFSET + index] !== byte) {\n return undefined;\n }\n }\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const width = view.getUint32(PNG_WIDTH_OFFSET);\n const height = view.getUint32(PNG_HEIGHT_OFFSET);\n return width > 0 && height > 0 ? { width, height } : undefined;\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 isOperationError,\n type BytesImage,\n type BytesImageRenderer,\n type OperationContext,\n type RenderRequest,\n} from \"slackmark\";\n\nimport { NodeRenderError, NodeRenderErrorCode, NodeRenderStage } from \"./errors.js\";\nimport { assertPngLimits, assertSourceLimit, deterministicPngFilename } from \"./image-output.js\";\nimport type { ImageLimits } from \"./image-output.js\";\nimport type { KatexAssetLoader } from \"./katex-assets.js\";\nimport { assertNodeMethod, invalidNodeOptions, snapshotNodeOptions } from \"./node-options.js\";\nimport type { RenderRuntime } from \"./puppeteer-render-runtime.js\";\n\nconst DEFAULT_MAX_SOURCE_CHARS = 20_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 10 * 1024 * 1024;\nconst DEFAULT_MAX_WIDTH = 4096;\nconst DEFAULT_MAX_HEIGHT = 4096;\nconst DEFAULT_MAX_EXPAND = 1000;\nconst DEFAULT_MAX_SIZE = 50;\nconst DEFAULT_FONT_SIZE_PX = 20;\nconst DEFAULT_PADDING_PX = 16;\nconst DEFAULT_DEVICE_SCALE_FACTOR = 2;\nconst DEFAULT_BACKGROUND_COLOR = \"white\";\nconst DEFAULT_VIEWPORT_WIDTH = 1280;\nconst DEFAULT_VIEWPORT_HEIGHT = 720;\nconst KATEX_LANGUAGES: ReadonlySet<string> = new Set([\"katex\", \"latex\", \"math\", \"tex\"]);\nconst KATEX_SHELL =\n \"<!doctype html><html><head><meta charset=\\\"utf-8\\\"><meta http-equiv=\\\"Content-Security-Policy\\\" content=\\\"default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; font-src data:; img-src 'none'; connect-src 'none'; worker-src 'none';\\\"></head><body><div id=\\\"math\\\"></div></body></html>\";\nconst KATEX_LAYOUT_CSS =\n \"html,body{margin:0;padding:0}#math{display:inline-block;box-sizing:border-box}.katex-display{margin:0}\";\n\nexport interface KatexRendererOptions {\n readonly runtime: RenderRuntime;\n readonly assets: KatexAssetLoader;\n readonly backgroundColor?: string | undefined;\n readonly deviceScaleFactor?: number | undefined;\n readonly fontSizePx?: number | undefined;\n readonly paddingPx?: number | undefined;\n readonly maxExpand?: number | undefined;\n readonly maxSize?: number | undefined;\n readonly maxSourceChars?: number | undefined;\n readonly maxOutputBytes?: number | undefined;\n readonly maxWidth?: number | undefined;\n readonly maxHeight?: number | undefined;\n}\n\n/**\n * Renders display TeX with KaTeX, local fonts, and an isolated browser screenshot.\n */\nexport class KatexRenderer implements BytesImageRenderer {\n readonly id: string;\n readonly output: \"bytes\";\n private readonly runtime: RenderRuntime;\n private readonly assets: KatexAssetLoader;\n private readonly backgroundColor: string;\n private readonly deviceScaleFactor: number;\n private readonly fontSizePx: number;\n private readonly paddingPx: number;\n private readonly maxExpand: number;\n private readonly maxSize: number;\n private readonly maxSourceChars: number;\n private readonly imageLimits: ImageLimits;\n private readonly optionsFingerprint: string;\n\n constructor(options: KatexRendererOptions) {\n const validated = snapshotNodeOptions(\n options,\n [\n \"runtime\",\n \"assets\",\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"fontSizePx\",\n \"paddingPx\",\n \"maxExpand\",\n \"maxSize\",\n \"maxSourceChars\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"KatexRenderer\",\n );\n assertNodeMethod(validated.runtime, \"run\", \"RenderRuntime\");\n assertNodeMethod(validated.assets, \"loadScript\", \"KatexAssetLoader\");\n assertNodeMethod(validated.assets, \"loadCss\", \"KatexAssetLoader\");\n this.id = \"katex\";\n this.output = \"bytes\";\n this.runtime = validated.runtime;\n this.assets = validated.assets;\n this.backgroundColor = validated.backgroundColor ?? DEFAULT_BACKGROUND_COLOR;\n this.deviceScaleFactor = validated.deviceScaleFactor ?? DEFAULT_DEVICE_SCALE_FACTOR;\n this.fontSizePx = validated.fontSizePx ?? DEFAULT_FONT_SIZE_PX;\n this.paddingPx = validated.paddingPx ?? DEFAULT_PADDING_PX;\n this.maxExpand = validated.maxExpand ?? DEFAULT_MAX_EXPAND;\n this.maxSize = validated.maxSize ?? DEFAULT_MAX_SIZE;\n this.maxSourceChars = validated.maxSourceChars ?? DEFAULT_MAX_SOURCE_CHARS;\n this.imageLimits = {\n maxOutputBytes: validated.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES,\n maxWidth: validated.maxWidth ?? DEFAULT_MAX_WIDTH,\n maxHeight: validated.maxHeight ?? DEFAULT_MAX_HEIGHT,\n };\n this.optionsFingerprint = [\n this.backgroundColor,\n String(this.deviceScaleFactor),\n String(this.fontSizePx),\n String(this.paddingPx),\n String(this.maxExpand),\n String(this.maxSize),\n String(this.maxSourceChars),\n String(this.imageLimits.maxOutputBytes),\n String(this.imageLimits.maxWidth),\n String(this.imageLimits.maxHeight),\n ].join(\":\");\n\n validateOptions({\n backgroundColor: this.backgroundColor,\n deviceScaleFactor: this.deviceScaleFactor,\n fontSizePx: this.fontSizePx,\n paddingPx: this.paddingPx,\n maxExpand: this.maxExpand,\n maxSize: this.maxSize,\n maxSourceChars: this.maxSourceChars,\n imageLimits: this.imageLimits,\n });\n }\n\n canRender(request: RenderRequest): boolean {\n return KATEX_LANGUAGES.has(request.lang.trim().toLowerCase());\n }\n\n async render(request: RenderRequest, context: OperationContext): Promise<BytesImage | null> {\n if (!this.canRender(request)) {\n return null;\n }\n assertSourceLimit(request.source, this.maxSourceChars);\n\n let data: Uint8Array;\n try {\n data = await this.runtime.run(async (context) => {\n const script = await this.assets.loadScript();\n const css = await this.assets.loadCss();\n const page = await context.newPage();\n await page.setViewport({\n width: DEFAULT_VIEWPORT_WIDTH,\n height: DEFAULT_VIEWPORT_HEIGHT,\n deviceScaleFactor: this.deviceScaleFactor,\n });\n await page.setContent(KATEX_SHELL, { waitUntil: \"domcontentloaded\" });\n await page.addStyleTag({ content: `${css}\\n${KATEX_LAYOUT_CSS}` });\n await page.addScriptTag({ content: script });\n await page.$eval(\n \"body\",\n (body, backgroundColor) => {\n body.style.background = backgroundColor;\n },\n this.backgroundColor,\n );\n await page.$eval(\n \"#math\",\n (container, values) => {\n const browserGlobal = globalThis as typeof globalThis & {\n katex?: {\n renderToString(source: string, options: Readonly<Record<string, unknown>>): string;\n };\n };\n const katex = browserGlobal.katex;\n if (katex === undefined) {\n throw new Error(\"KaTeX browser harness failed to initialize\");\n }\n container.innerHTML = katex.renderToString(values.source, {\n displayMode: true,\n globalGroup: false,\n maxExpand: values.maxExpand,\n maxSize: values.maxSize,\n output: \"html\",\n strict: \"ignore\",\n throwOnError: true,\n trust: false,\n });\n container.setAttribute(\n \"style\",\n `font-size:${String(values.fontSizePx)}px;padding:${String(values.paddingPx)}px`,\n );\n },\n {\n source: request.source,\n maxExpand: this.maxExpand,\n maxSize: this.maxSize,\n fontSizePx: this.fontSizePx,\n paddingPx: this.paddingPx,\n },\n );\n await page.evaluate(async () => {\n await document.fonts.ready;\n });\n\n const element = await page.$(\"#math\");\n if (element === null) {\n throw new Error(\"KaTeX screenshot element is missing\");\n }\n const box = await element.boundingBox();\n if (box === null) {\n throw new Error(\"KaTeX screenshot element has no dimensions\");\n }\n const pixelWidth = Math.ceil(box.width * this.deviceScaleFactor);\n const pixelHeight = Math.ceil(box.height * this.deviceScaleFactor);\n if (pixelWidth > this.imageLimits.maxWidth || pixelHeight > this.imageLimits.maxHeight) {\n throw new NodeRenderError(\n NodeRenderErrorCode.DimensionLimit,\n `Rendered image exceeds ${String(this.imageLimits.maxWidth)}x${String(this.imageLimits.maxHeight)} pixels`,\n { stage: NodeRenderStage.Layout, retryable: false },\n );\n }\n return element.screenshot({\n type: \"png\",\n omitBackground: this.backgroundColor === \"transparent\",\n });\n }, context);\n } catch (error) {\n if (isOperationError(error)) {\n throw error;\n }\n if (error instanceof NodeRenderError) {\n const sanitizedRenderFailure =\n error.code === NodeRenderErrorCode.RenderFailed && error.cause === undefined;\n if (error.code !== NodeRenderErrorCode.RenderFailed || sanitizedRenderFailure) {\n throw error;\n }\n }\n throw new NodeRenderError(NodeRenderErrorCode.RenderFailed, \"KaTeX rendering failed\", {\n stage: \"render\",\n retryable: false,\n });\n }\n assertPngLimits(data, this.imageLimits);\n\n return {\n kind: \"bytes\",\n data,\n mimeType: \"image/png\",\n filename: deterministicPngFilename(\"math\", request.source, this.optionsFingerprint),\n altText: request.altText,\n };\n }\n}\n\nfunction validateOptions(renderer: {\n readonly backgroundColor: string;\n readonly deviceScaleFactor: number;\n readonly fontSizePx: number;\n readonly paddingPx: number;\n readonly maxExpand: number;\n readonly maxSize: number;\n readonly maxSourceChars: number;\n readonly imageLimits: ImageLimits;\n}): void {\n if (typeof renderer.backgroundColor !== \"string\" || renderer.backgroundColor.length === 0) {\n throw invalidNodeOptions(\"backgroundColor must be a nonempty string\");\n }\n validatePositiveFinite(renderer.deviceScaleFactor, \"deviceScaleFactor\");\n validatePositiveFinite(renderer.fontSizePx, \"fontSizePx\");\n validateNonNegativeFinite(renderer.paddingPx, \"paddingPx\");\n validatePositiveInteger(renderer.maxExpand, \"maxExpand\");\n validatePositiveFinite(renderer.maxSize, \"maxSize\");\n validatePositiveInteger(renderer.maxSourceChars, \"maxSourceChars\");\n validatePositiveInteger(renderer.imageLimits.maxOutputBytes, \"maxOutputBytes\");\n validatePositiveInteger(renderer.imageLimits.maxWidth, \"maxWidth\");\n validatePositiveInteger(renderer.imageLimits.maxHeight, \"maxHeight\");\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 validatePositiveFinite(value: number, name: string): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidNodeOptions(`${name} must be positive`);\n }\n}\n\nfunction validateNonNegativeFinite(value: number, name: string): void {\n if (!Number.isFinite(value) || value < 0) {\n throw invalidNodeOptions(`${name} must be non-negative`);\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 type { HTTPRequest } from \"puppeteer\";\nimport {\n isOperationError,\n type BytesImage,\n type BytesImageRenderer,\n type OperationContext,\n type RenderRequest,\n} from \"slackmark\";\n\nimport { NodeRenderError, NodeRenderErrorCode } from \"./errors.js\";\nimport { assertPngLimits, assertSourceLimit, deterministicPngFilename } from \"./image-output.js\";\nimport type { ImageLimits } from \"./image-output.js\";\nimport type { MermaidAssetLoader } from \"./mermaid-assets.js\";\nimport { assertNodeMethod, invalidNodeOptions, snapshotNodeOptions } from \"./node-options.js\";\nimport type { RenderRuntime } from \"./puppeteer-render-runtime.js\";\n\nconst DEFAULT_MAX_SOURCE_CHARS = 50_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 10 * 1024 * 1024;\nconst DEFAULT_MAX_WIDTH = 4096;\nconst DEFAULT_MAX_HEIGHT = 4096;\nconst DEFAULT_MAX_EDGES = 500;\nconst DEFAULT_DEVICE_SCALE_FACTOR = 2;\nconst DEFAULT_BACKGROUND_COLOR = \"white\";\nconst DEFAULT_VIEWPORT_WIDTH = 1280;\nconst DEFAULT_VIEWPORT_HEIGHT = 720;\nconst MERMAID_SHELL =\n \"<!doctype html><html><head><meta charset=\\\"utf-8\\\"><meta http-equiv=\\\"Content-Security-Policy\\\" content=\\\"default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src 'none'; font-src 'none'; connect-src 'none'; worker-src 'none'; object-src 'none'; frame-src 'none';\\\"></head><body><div id=\\\"diagram\\\"></div></body></html>\";\nconst SECURE_MERMAID_KEYS = [\n \"secure\",\n \"securityLevel\",\n \"startOnLoad\",\n \"maxTextSize\",\n \"suppressErrorRendering\",\n \"maxEdges\",\n \"deterministicIds\",\n \"deterministicIDSeed\",\n \"layout\",\n];\n\nexport type MermaidTheme = \"base\" | \"dark\" | \"default\" | \"forest\" | \"neutral\";\nconst MERMAID_THEMES: ReadonlySet<string> = new Set([\n \"base\",\n \"dark\",\n \"default\",\n \"forest\",\n \"neutral\",\n]);\n\nexport interface MermaidRendererOptions {\n readonly runtime: RenderRuntime;\n readonly assets: MermaidAssetLoader;\n readonly theme?: MermaidTheme | undefined;\n readonly backgroundColor?: string | undefined;\n readonly deviceScaleFactor?: number | undefined;\n readonly maxSourceChars?: number | undefined;\n readonly maxEdges?: number | undefined;\n readonly maxOutputBytes?: number | undefined;\n readonly maxWidth?: number | undefined;\n readonly maxHeight?: number | undefined;\n}\n\nexport class MermaidRenderer implements BytesImageRenderer {\n readonly id: string;\n readonly output: \"bytes\";\n private readonly runtime: RenderRuntime;\n private readonly assets: MermaidAssetLoader;\n private readonly theme: MermaidTheme;\n private readonly backgroundColor: string;\n private readonly deviceScaleFactor: number;\n private readonly maxSourceChars: number;\n private readonly maxEdges: number;\n private readonly imageLimits: ImageLimits;\n private readonly optionsFingerprint: string;\n\n constructor(options: MermaidRendererOptions) {\n const validated = snapshotNodeOptions(\n options,\n [\n \"runtime\",\n \"assets\",\n \"theme\",\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"maxSourceChars\",\n \"maxEdges\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"MermaidRenderer\",\n );\n assertNodeMethod(validated.runtime, \"run\", \"RenderRuntime\");\n assertNodeMethod(validated.assets, \"loadScript\", \"MermaidAssetLoader\");\n this.id = \"mermaid\";\n this.output = \"bytes\";\n this.runtime = validated.runtime;\n this.assets = validated.assets;\n this.theme = validated.theme ?? \"default\";\n this.backgroundColor = validated.backgroundColor ?? DEFAULT_BACKGROUND_COLOR;\n this.deviceScaleFactor = validated.deviceScaleFactor ?? DEFAULT_DEVICE_SCALE_FACTOR;\n this.maxSourceChars = validated.maxSourceChars ?? DEFAULT_MAX_SOURCE_CHARS;\n this.maxEdges = validated.maxEdges ?? DEFAULT_MAX_EDGES;\n this.imageLimits = {\n maxOutputBytes: validated.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES,\n maxWidth: validated.maxWidth ?? DEFAULT_MAX_WIDTH,\n maxHeight: validated.maxHeight ?? DEFAULT_MAX_HEIGHT,\n };\n this.optionsFingerprint = [\n this.theme,\n this.backgroundColor,\n String(this.deviceScaleFactor),\n String(this.maxSourceChars),\n String(this.maxEdges),\n String(this.imageLimits.maxOutputBytes),\n String(this.imageLimits.maxWidth),\n String(this.imageLimits.maxHeight),\n ].join(\":\");\n validateOptions({\n theme: this.theme,\n backgroundColor: this.backgroundColor,\n deviceScaleFactor: this.deviceScaleFactor,\n maxSourceChars: this.maxSourceChars,\n maxEdges: this.maxEdges,\n imageLimits: this.imageLimits,\n });\n }\n\n canRender(request: RenderRequest): boolean {\n return request.lang.trim().toLowerCase() === \"mermaid\";\n }\n\n async render(request: RenderRequest, context: OperationContext): Promise<BytesImage | null> {\n if (!this.canRender(request)) {\n return null;\n }\n assertSourceLimit(request.source, this.maxSourceChars);\n\n let data: Uint8Array;\n try {\n data = await this.runtime.run(async (context) => {\n const script = await this.assets.loadScript();\n const page = await context.newPage();\n await page.setRequestInterception(true);\n page.on(\"request\", blockRequest);\n await page.setViewport({\n width: DEFAULT_VIEWPORT_WIDTH,\n height: DEFAULT_VIEWPORT_HEIGHT,\n deviceScaleFactor: this.deviceScaleFactor,\n });\n await page.setContent(MERMAID_SHELL, { waitUntil: \"domcontentloaded\" });\n await page.addScriptTag({ content: script });\n await page.evaluate(\n async (input) => {\n const browserGlobal = globalThis as typeof globalThis & {\n mermaid?: {\n initialize(config: Readonly<Record<string, unknown>>): void;\n parse(source: string, options: { suppressErrors: boolean }): Promise<unknown>;\n render(\n id: string,\n source: string,\n container: Element,\n ): Promise<{ readonly svg: string }>;\n };\n };\n const mermaid = browserGlobal.mermaid;\n const container = document.querySelector(\"#diagram\");\n if (mermaid === undefined || container === null) {\n throw new Error(\"Mermaid browser harness failed to initialize\");\n }\n mermaid.initialize({\n deterministicIds: true,\n deterministicIDSeed: \"slackmark-node\",\n layout: \"dagre\",\n logLevel: \"fatal\",\n maxEdges: input.maxEdges,\n maxTextSize: input.maxSourceChars,\n secure: input.secureKeys,\n securityLevel: \"strict\",\n startOnLoad: false,\n suppressErrorRendering: true,\n theme: input.theme,\n });\n await mermaid.parse(input.source, { suppressErrors: false });\n const rendered = await mermaid.render(\"slackmark-diagram\", input.source, container);\n container.innerHTML = rendered.svg;\n document.body.style.background = input.backgroundColor;\n },\n {\n source: request.source,\n theme: this.theme,\n backgroundColor: this.backgroundColor,\n maxSourceChars: this.maxSourceChars,\n maxEdges: this.maxEdges,\n secureKeys: SECURE_MERMAID_KEYS,\n },\n );\n const element = await page.$(\"#diagram svg\");\n if (element === null) {\n throw new Error(\"Mermaid produced no SVG\");\n }\n const box = await element.boundingBox();\n if (box === null) {\n throw new Error(\"Mermaid SVG has no dimensions\");\n }\n const pixelWidth = Math.ceil(box.width * this.deviceScaleFactor);\n const pixelHeight = Math.ceil(box.height * this.deviceScaleFactor);\n if (pixelWidth > this.imageLimits.maxWidth || pixelHeight > this.imageLimits.maxHeight) {\n throw new NodeRenderError(\n NodeRenderErrorCode.DimensionLimit,\n \"Rendered Mermaid image exceeds configured dimensions\",\n { stage: \"layout\", retryable: false },\n );\n }\n return element.screenshot({\n type: \"png\",\n omitBackground: this.backgroundColor === \"transparent\",\n });\n }, context);\n } catch (error) {\n if (isOperationError(error)) {\n throw error;\n }\n if (error instanceof NodeRenderError) {\n if (error.code !== NodeRenderErrorCode.RenderFailed) {\n throw error;\n }\n }\n throw new NodeRenderError(NodeRenderErrorCode.RenderFailed, \"Mermaid rendering failed\", {\n stage: \"render\",\n retryable: false,\n });\n }\n assertPngLimits(data, this.imageLimits);\n return {\n kind: \"bytes\",\n data,\n mimeType: \"image/png\",\n filename: deterministicPngFilename(\"mermaid\", request.source, this.optionsFingerprint),\n altText: request.altText,\n };\n }\n}\n\nfunction blockRequest(request: HTTPRequest): void {\n void request.abort(\"blockedbyclient\");\n}\n\nfunction validateOptions(renderer: {\n readonly theme: MermaidTheme;\n readonly backgroundColor: string;\n readonly deviceScaleFactor: number;\n readonly maxSourceChars: number;\n readonly maxEdges: number;\n readonly imageLimits: ImageLimits;\n}): void {\n if (typeof renderer.theme !== \"string\" || !MERMAID_THEMES.has(renderer.theme)) {\n throw invalidNodeOptions(\"theme must be base, dark, default, forest, or neutral\");\n }\n if (typeof renderer.backgroundColor !== \"string\" || renderer.backgroundColor.length === 0) {\n throw invalidNodeOptions(\"backgroundColor must be a nonempty string\");\n }\n validatePositiveFinite(renderer.deviceScaleFactor, \"deviceScaleFactor\");\n validatePositiveInteger(renderer.maxSourceChars, \"maxSourceChars\");\n validatePositiveInteger(renderer.maxEdges, \"maxEdges\");\n validatePositiveInteger(renderer.imageLimits.maxOutputBytes, \"maxOutputBytes\");\n validatePositiveInteger(renderer.imageLimits.maxWidth, \"maxWidth\");\n validatePositiveInteger(renderer.imageLimits.maxHeight, \"maxHeight\");\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 validatePositiveFinite(value: number, name: string): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidNodeOptions(`${name} must be positive`);\n }\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","export const NodeConverterState = {\n Open: \"open\",\n Closing: \"closing\",\n Closed: \"closed\",\n CloseFailed: \"close-failed\",\n} as const;\n\nexport type NodeConverterState = (typeof NodeConverterState)[keyof typeof NodeConverterState];\n\nexport interface NodeWorkStatus {\n readonly accepting: boolean;\n readonly active: number;\n readonly queued: number;\n readonly retainedBytes: number;\n}\n\nexport interface NodeConverterStatus {\n readonly state: NodeConverterState;\n readonly activeOperations: number;\n readonly render: NodeWorkStatus;\n readonly upload: NodeWorkStatus;\n}\n","import {\n OperationShutdownError,\n type BytesImage,\n type OperationContext,\n type SlackUploader,\n} from \"slackmark\";\nimport { SlackUploadError, SlackUploadStage } from \"slackmark/slack\";\n\nimport { OperationScope, operationReason, raceWithContext } from \"./operation-control.js\";\nimport type { CloseBehavior, WorkQueueStatus } from \"./puppeteer-render-runtime.js\";\n\nexport interface UploadSchedulerOptions {\n readonly concurrency: number;\n readonly maxQueueSize: number;\n}\n\ninterface PendingUpload {\n start(): void;\n reject(error: unknown): void;\n}\n\nexport class UploadScheduler {\n private readonly concurrency: number;\n private readonly maxQueueSize: number;\n private readonly pending: PendingUpload[];\n private readonly activeScopes: Set<OperationScope>;\n private readonly idleResolvers: Array<() => void>;\n private active: number;\n private retainedBytes: number;\n private closePromise: Promise<void> | undefined;\n private closeBehavior: CloseBehavior | undefined;\n private accepting: boolean;\n\n constructor(options: UploadSchedulerOptions) {\n this.concurrency = options.concurrency;\n this.maxQueueSize = options.maxQueueSize;\n this.pending = [];\n this.activeScopes = new Set();\n this.idleResolvers = [];\n this.active = 0;\n this.retainedBytes = 0;\n this.closePromise = undefined;\n this.closeBehavior = undefined;\n this.accepting = true;\n validatePositiveInteger(this.concurrency, \"upload.concurrency\");\n validateNonNegativeInteger(this.maxQueueSize, \"upload.maxQueueSize\");\n }\n\n schedule(\n uploader: SlackUploader,\n image: BytesImage,\n operation: OperationContext,\n ): ReturnType<SlackUploader[\"upload\"]> {\n if (!this.accepting) {\n return Promise.reject(new OperationShutdownError(\"upload_admission\"));\n }\n if (this.active >= this.concurrency && this.pending.length >= this.maxQueueSize) {\n return Promise.reject(queueError());\n }\n let scope: OperationScope;\n try {\n scope = new OperationScope(operation, \"upload\");\n } catch (error) {\n return Promise.reject(error);\n }\n this.retainedBytes += image.data.byteLength;\n return new Promise<Awaited<ReturnType<SlackUploader[\"upload\"]>>>((resolve, reject) => {\n let pending: PendingUpload;\n const abortWhileQueued = (): void => {\n const index = this.pending.indexOf(pending);\n if (index >= 0) {\n this.pending.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(uploader, image, scope, resolve, reject);\n },\n reject: (error: unknown): void => {\n scope.context.signal?.removeEventListener(\"abort\", abortWhileQueued);\n scope.cleanup();\n this.retainedBytes -= image.data.byteLength;\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.active < this.concurrency) {\n this.active += 1;\n pending.start();\n return;\n }\n scope.context.signal?.addEventListener(\"abort\", abortWhileQueued, { once: true });\n this.pending.push(pending);\n });\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, \"upload_close\");\n this.accepting = false;\n this.closeBehavior = behavior;\n if (behavior === \"cancel\") {\n const shutdown = new OperationShutdownError(\"upload\");\n for (const pending of this.pending.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"upload\");\n }\n }\n this.closePromise = raceWithContext(this.waitForIdle(), closeScope.context)\n .catch((error: unknown) => {\n this.closeBehavior = \"cancel\";\n const shutdown = new OperationShutdownError(\"upload\");\n for (const pending of this.pending.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"upload\");\n }\n throw error;\n })\n .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.active,\n queued: this.pending.length,\n retainedBytes: this.retainedBytes,\n });\n }\n\n private startUnderlying(\n uploader: SlackUploader,\n image: BytesImage,\n scope: OperationScope,\n resolve: (\n value:\n | Awaited<ReturnType<SlackUploader[\"upload\"]>>\n | PromiseLike<Awaited<ReturnType<SlackUploader[\"upload\"]>>>,\n ) => void,\n reject: (reason?: unknown) => void,\n ): void {\n const underlying = Promise.resolve().then(() => uploader.upload(image, scope.context));\n void underlying.then(\n (value) => {\n resolve(value);\n this.finishUnderlying(scope, image.data.byteLength);\n return undefined;\n },\n (error: unknown) => {\n reject(error);\n this.finishUnderlying(scope, image.data.byteLength);\n return undefined;\n },\n );\n }\n\n private finishUnderlying(scope: OperationScope, byteLength: number): void {\n scope.cleanup();\n this.activeScopes.delete(scope);\n this.active -= 1;\n this.retainedBytes -= byteLength;\n const next = this.pending.shift();\n if (next !== undefined && this.closeBehavior !== \"cancel\") {\n this.active += 1;\n next.start();\n } else if (next !== undefined) {\n next.reject(new OperationShutdownError(\"upload\"));\n }\n if (this.active === 0 && this.pending.length === 0) {\n for (const resolve of this.idleResolvers.splice(0)) {\n resolve();\n }\n }\n }\n\n private waitForIdle(): Promise<void> {\n if (this.active === 0 && this.pending.length === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n}\n\nexport class ScheduledSlackUploader implements SlackUploader {\n private readonly scheduler: UploadScheduler;\n private readonly uploader: SlackUploader;\n\n constructor(scheduler: UploadScheduler, uploader: SlackUploader) {\n this.scheduler = scheduler;\n this.uploader = uploader;\n }\n\n upload(image: BytesImage, operation: OperationContext): ReturnType<SlackUploader[\"upload\"]> {\n return this.scheduler.schedule(this.uploader, image, operation);\n }\n}\n\nfunction queueError(): SlackUploadError {\n return new SlackUploadError(\"Slack upload queue is full\", {\n stage: SlackUploadStage.Admission,\n code: \"upload_queue_full\",\n retryable: true,\n });\n}\n\nfunction requireSignal(operation: OperationContext): AbortSignal {\n if (operation.signal === undefined) {\n throw new OperationShutdownError(\"upload\");\n }\n return operation.signal;\n}\n\nfunction validatePositiveInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new RangeError(`${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 new RangeError(`${name} must be a non-negative integer`);\n }\n}\n","import {\n ConfigurationError,\n OperationErrorCode,\n OperationShutdownError,\n RecordingReceiptCollector,\n attachReceipts,\n createConverter,\n isConfigurationError,\n isOperationError,\n lockReceiptSnapshot,\n resolveCapabilities,\n type ConversionMessagesResult,\n type ConversionResult,\n type ConvertOptions,\n type ImageRenderer,\n type OperationContext,\n type OperationOptions,\n type ReceiptCollector,\n type SlackMarkConverter,\n type SlackUploader,\n type UploadReceipt,\n} from \"slackmark\";\nimport type { LaunchOptions } from \"puppeteer\";\n\nimport { LocalKatexAssetLoader } from \"./katex-assets.js\";\nimport { KatexRenderer } from \"./katex-renderer.js\";\nimport type { KatexRendererOptions } from \"./katex-renderer.js\";\nimport { LocalMermaidAssetLoader } from \"./mermaid-assets.js\";\nimport { MermaidRenderer } from \"./mermaid-renderer.js\";\nimport type { MermaidRendererOptions } from \"./mermaid-renderer.js\";\nimport { NodeShutdownTimeoutError } from \"./errors.js\";\nimport { snapshotNodeOptions } from \"./node-options.js\";\nimport { createOperationScope, isPlainObject, type OperationScope } from \"./operation-control.js\";\nimport {\n PuppeteerBrowserLauncher,\n PuppeteerRenderRuntime,\n type CloseBehavior,\n type RenderRuntime,\n} from \"./puppeteer-render-runtime.js\";\nimport { NodeConverterState, type NodeConverterStatus } from \"./status.js\";\nimport { ScheduledSlackUploader, UploadScheduler } from \"./upload-scheduler.js\";\n\nconst DEFAULT_CLOSE_TIMEOUT_MS = 5_000;\nconst CORE_OPTION_KEYS = [\n \"capabilities\",\n \"capabilityOverrides\",\n \"overflow\",\n \"strategy\",\n \"enableMath\",\n \"enableInlineMath\",\n \"enableFrontmatter\",\n \"mentionResolvers\",\n] as const;\n\ntype NodeConversionDefaults = Omit<\n ConvertOptions,\n \"renderers\" | \"uploader\" | \"signal\" | \"timeoutMs\"\n>;\n\nexport interface NodeRenderingOptions {\n readonly concurrency?: number | undefined;\n readonly maxQueueSize?: number | undefined;\n readonly launchOptions?: LaunchOptions | undefined;\n readonly mermaid?: Omit<MermaidRendererOptions, \"runtime\" | \"assets\"> | undefined;\n readonly math?: Omit<KatexRendererOptions, \"runtime\" | \"assets\"> | undefined;\n}\n\nexport interface NodeUploadOptions {\n readonly concurrency?: number | undefined;\n readonly maxQueueSize?: number | undefined;\n}\n\nexport interface CreateNodeConverterOptions extends NodeConversionDefaults {\n readonly rendering?: NodeRenderingOptions | undefined;\n readonly upload?: NodeUploadOptions | undefined;\n readonly additionalRenderers?: ReadonlyArray<ImageRenderer> | undefined;\n readonly uploader?: SlackUploader | undefined;\n}\n\nexport type NodeConvertOptions = NodeConversionDefaults &\n OperationOptions & {\n readonly uploader?: SlackUploader | undefined;\n };\n\nexport interface NodeCloseOptions extends OperationOptions {\n readonly behavior?: CloseBehavior | undefined;\n}\n\nexport interface NodeConverter extends AsyncDisposable {\n convert(markdown: string, options?: NodeConvertOptions): Promise<ConversionResult>;\n convertToMessages(\n markdown: string,\n options?: NodeConvertOptions,\n ): Promise<ConversionMessagesResult>;\n warmup(options?: OperationOptions): Promise<void>;\n close(options?: NodeCloseOptions): Promise<void>;\n status(): NodeConverterStatus;\n}\n\nexport interface ManagedNodeConverterDeps {\n readonly converter: SlackMarkConverter;\n readonly runtime: RenderRuntime;\n readonly defaultUploader: SlackUploader | undefined;\n readonly uploadScheduler: UploadScheduler;\n readonly warmupOperation: (operation: OperationContext) => Promise<void>;\n}\n\nexport class ManagedNodeConverter implements NodeConverter {\n private readonly converter: SlackMarkConverter;\n private readonly runtime: RenderRuntime;\n private readonly defaultUploader: SlackUploader | undefined;\n private readonly uploadScheduler: UploadScheduler;\n private readonly warmupOperation: (operation: OperationContext) => Promise<void>;\n private readonly activeScopes: Set<OperationScope>;\n private readonly activeReceipts: Map<OperationScope, RecordingReceiptCollector>;\n private readonly idleResolvers: Array<() => void>;\n private activeOperations: number;\n private closePromise: Promise<void> | undefined;\n private state: NodeConverterStatus[\"state\"];\n\n constructor(deps: ManagedNodeConverterDeps) {\n this.converter = deps.converter;\n this.runtime = deps.runtime;\n this.defaultUploader = deps.defaultUploader;\n this.uploadScheduler = deps.uploadScheduler;\n this.warmupOperation = deps.warmupOperation;\n this.activeScopes = new Set();\n this.activeReceipts = new Map();\n this.idleResolvers = [];\n this.activeOperations = 0;\n this.closePromise = undefined;\n this.state = NodeConverterState.Open;\n }\n\n convert(markdown: string, options: NodeConvertOptions = {}): Promise<ConversionResult> {\n try {\n const normalized = normalizeNodeConvertOptions(options);\n return this.runTracked(\n { signal: normalized.signal, timeoutMs: normalized.timeoutMs },\n (operation, receipts) =>\n this.converter.convertWithContext(\n markdown,\n prepareConversionOptions(normalized, this.defaultUploader, this.uploadScheduler),\n operation,\n receipts,\n ),\n );\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n }\n\n convertToMessages(\n markdown: string,\n options: NodeConvertOptions = {},\n ): Promise<ConversionMessagesResult> {\n try {\n const normalized = normalizeNodeConvertOptions(options);\n return this.runTracked(\n { signal: normalized.signal, timeoutMs: normalized.timeoutMs },\n (operation, receipts) =>\n this.converter.convertToMessagesWithContext(\n markdown,\n prepareConversionOptions(normalized, this.defaultUploader, this.uploadScheduler),\n operation,\n receipts,\n ),\n );\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n }\n\n warmup(options: OperationOptions = {}): Promise<void> {\n try {\n return this.runTracked(options, (operation) => this.warmupOperation(operation));\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n }\n\n close(options: NodeCloseOptions = {}): Promise<void> {\n if (this.closePromise !== undefined) {\n return this.closePromise;\n }\n let behavior: CloseBehavior;\n let scope: OperationScope;\n try {\n validateCloseOptions(options);\n behavior = options.behavior ?? \"drain\";\n scope = createOperationScope(\n {\n signal: options.signal,\n timeoutMs: options.timeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS,\n },\n \"close\",\n );\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n this.state = NodeConverterState.Closing;\n if (behavior === \"cancel\") {\n for (const active of this.activeScopes) {\n active.abortForShutdown(\"conversion\");\n }\n }\n const closingReceipts = [...this.activeReceipts.values()];\n this.closePromise = this.finishClose(scope, behavior, closingReceipts);\n return this.closePromise;\n }\n\n status(): NodeConverterStatus {\n return Object.freeze({\n state: this.state,\n activeOperations: this.activeOperations,\n render: this.runtime.status(),\n upload: this.uploadScheduler.status(),\n });\n }\n\n [Symbol.asyncDispose](): Promise<void> {\n return this.close({ behavior: \"cancel\", timeoutMs: DEFAULT_CLOSE_TIMEOUT_MS });\n }\n\n private runTracked<T>(\n options: OperationOptions,\n operation: (context: OperationContext, receipts: ReceiptCollector) => Promise<T>,\n ): Promise<T> {\n if (this.state !== NodeConverterState.Open) {\n return Promise.reject(new OperationShutdownError(\"conversion_admission\"));\n }\n const scope = createOperationScope(options, \"conversion\");\n const receipts = new RecordingReceiptCollector();\n this.activeScopes.add(scope);\n this.activeReceipts.set(scope, receipts);\n this.activeOperations += 1;\n const underlying = Promise.resolve().then(() => operation(scope.context, receipts));\n void underlying.then(\n () => {\n receipts.settle();\n this.finishTracked(scope);\n return undefined;\n },\n () => {\n receipts.settle();\n this.finishTracked(scope);\n return undefined;\n },\n );\n return scope.race(underlying).catch((error: unknown) => {\n throw lockReceiptSnapshot(attachReceipts(error, receipts.all(), receipts.settled()));\n });\n }\n\n private finishTracked(scope: OperationScope): void {\n scope.cleanup();\n this.activeScopes.delete(scope);\n this.activeReceipts.delete(scope);\n this.activeOperations -= 1;\n if (this.activeOperations === 0) {\n for (const resolve of this.idleResolvers.splice(0)) {\n resolve();\n }\n }\n }\n\n private async finishClose(\n scope: OperationScope,\n behavior: CloseBehavior,\n closingReceipts: ReadonlyArray<RecordingReceiptCollector>,\n ): Promise<void> {\n try {\n await scope.race(this.waitForIdle());\n await Promise.all([\n this.uploadScheduler.close(scope.context, behavior),\n this.runtime.close(scope.context, behavior),\n ]);\n this.state = NodeConverterState.Closed;\n } catch (error) {\n this.state = NodeConverterState.CloseFailed;\n for (const active of this.activeScopes) {\n active.abortForShutdown(\"conversion\");\n }\n const cleanupContext: OperationContext = {\n signal: undefined,\n deadlineMs: Date.now() + DEFAULT_CLOSE_TIMEOUT_MS,\n };\n void Promise.allSettled([\n this.uploadScheduler.close(cleanupContext, \"cancel\"),\n this.runtime.close(cleanupContext, \"cancel\"),\n ]);\n const receiptSnapshot = collectReceiptSnapshot(closingReceipts);\n const settledReceipts = collectSettledReceipts(closingReceipts);\n if (isOperationError(error) && error.code === OperationErrorCode.DeadlineExceeded) {\n throw new NodeShutdownTimeoutError(this.status(), receiptSnapshot, settledReceipts);\n }\n throw attachReceipts(error, receiptSnapshot, settledReceipts);\n } finally {\n scope.cleanup();\n }\n }\n\n private waitForIdle(): Promise<void> {\n if (this.activeOperations === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n}\n\nexport function createNodeConverter(options: CreateNodeConverterOptions = {}): NodeConverter {\n try {\n validateNodeFactoryOptions(options);\n const launcher = new PuppeteerBrowserLauncher();\n const runtime = new PuppeteerRenderRuntime({\n launcher,\n launchOptions: options.rendering?.launchOptions,\n concurrency: options.rendering?.concurrency,\n maxQueueSize: options.rendering?.maxQueueSize,\n });\n const mermaidAssets = new LocalMermaidAssetLoader();\n const katexAssets = new LocalKatexAssetLoader();\n const builtInRenderers: ReadonlyArray<ImageRenderer> = [\n new MermaidRenderer({\n ...options.rendering?.mermaid,\n runtime,\n assets: mermaidAssets,\n }),\n new KatexRenderer({\n ...options.rendering?.math,\n runtime,\n assets: katexAssets,\n }),\n ];\n const additionalRenderers = Object.freeze([...(options.additionalRenderers ?? [])]);\n validateRendererIdentities(builtInRenderers, additionalRenderers);\n const converter = createConverter({\n ...pickConversionDefaults(options),\n enableMath: options.enableMath ?? true,\n renderers: [...builtInRenderers, ...additionalRenderers],\n });\n const uploadScheduler = new UploadScheduler({\n concurrency: options.upload?.concurrency ?? 2,\n maxQueueSize: options.upload?.maxQueueSize ?? 16,\n });\n return new ManagedNodeConverter({\n converter,\n runtime,\n defaultUploader: options.uploader,\n uploadScheduler,\n warmupOperation: (operation) =>\n runtime.run(async () => {\n await Promise.all([\n mermaidAssets.loadScript(),\n katexAssets.loadScript(),\n katexAssets.loadCss(),\n ]);\n }, operation),\n });\n } catch (error) {\n if (isConfigurationError(error)) {\n throw error;\n }\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n throw new ConfigurationError(`Invalid slackmark-node configuration${detail}`, {\n code: \"invalid_node_configuration\",\n stage: \"configuration\",\n cause: error,\n });\n }\n}\n\nfunction prepareConversionOptions(\n options: NodeConvertOptions,\n defaultUploader: SlackUploader | undefined,\n scheduler: UploadScheduler,\n): ConvertOptions {\n const {\n signal: _signal,\n timeoutMs: _timeoutMs,\n uploader: perCallUploader,\n ...conversionOptions\n } = options;\n const uploader = perCallUploader ?? defaultUploader;\n return {\n ...conversionOptions,\n uploader: uploader === undefined ? undefined : new ScheduledSlackUploader(scheduler, uploader),\n };\n}\n\nfunction pickConversionDefaults(options: NodeConversionDefaults): NodeConversionDefaults {\n return {\n capabilities: options.capabilities,\n capabilityOverrides: options.capabilityOverrides,\n overflow: options.overflow,\n strategy: options.strategy,\n enableMath: options.enableMath,\n enableInlineMath: options.enableInlineMath,\n enableFrontmatter: options.enableFrontmatter,\n mentionResolvers: options.mentionResolvers,\n };\n}\n\nfunction validateNodeFactoryOptions(options: CreateNodeConverterOptions): void {\n validateKnownPlainObject(\n options,\n [...CORE_OPTION_KEYS, \"rendering\", \"upload\", \"additionalRenderers\", \"uploader\"],\n \"options\",\n );\n if (options.rendering !== undefined) {\n validateKnownPlainObject(\n options.rendering,\n [\"concurrency\", \"maxQueueSize\", \"launchOptions\", \"mermaid\", \"math\"],\n \"rendering\",\n );\n if (options.rendering.mermaid !== undefined) {\n validateKnownPlainObject(\n options.rendering.mermaid,\n [\n \"theme\",\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"maxSourceChars\",\n \"maxEdges\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"rendering.mermaid\",\n );\n }\n if (options.rendering.math !== undefined) {\n validateKnownPlainObject(\n options.rendering.math,\n [\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"fontSizePx\",\n \"paddingPx\",\n \"maxExpand\",\n \"maxSize\",\n \"maxSourceChars\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"rendering.math\",\n );\n }\n }\n if (options.upload !== undefined) {\n validateKnownPlainObject(options.upload, [\"concurrency\", \"maxQueueSize\"], \"upload\");\n }\n resolveCapabilities(options.capabilities, options.capabilityOverrides);\n if (options.enableMath !== undefined && typeof options.enableMath !== \"boolean\") {\n throw new ConfigurationError(\"enableMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableInlineMath !== undefined && typeof options.enableInlineMath !== \"boolean\") {\n throw new ConfigurationError(\"enableInlineMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableFrontmatter !== undefined && typeof options.enableFrontmatter !== \"boolean\") {\n throw new ConfigurationError(\"enableFrontmatter must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (\n options.overflow !== undefined &&\n options.overflow !== \"degrade\" &&\n options.overflow !== \"split\"\n ) {\n throw new ConfigurationError('overflow must be \"degrade\" or \"split\"', {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (\n options.strategy !== undefined &&\n options.strategy !== \"rich-text-first\" &&\n options.strategy !== \"markdown-block\"\n ) {\n throw new ConfigurationError('strategy must be \"rich-text-first\" or \"markdown-block\"', {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n validateMentionResolvers(options.mentionResolvers);\n if (options.additionalRenderers !== undefined && !Array.isArray(options.additionalRenderers)) {\n throw new ConfigurationError(\"additionalRenderers must be an array\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n validateUploader(options.uploader);\n}\n\nfunction validateMentionResolvers(value: unknown): void {\n if (value === undefined) {\n return;\n }\n validateKnownPlainObject(value, [\"resolveUser\", \"resolveChannel\"], \"mentionResolvers\");\n try {\n const resolveUser = Reflect.get(value as object, \"resolveUser\");\n const resolveChannel = Reflect.get(value as object, \"resolveChannel\");\n if (\n (resolveUser !== undefined && typeof resolveUser !== \"function\") ||\n (resolveChannel !== undefined && typeof resolveChannel !== \"function\")\n ) {\n throw new TypeError(\"mention resolvers must be functions\");\n }\n } catch (cause) {\n throw new ConfigurationError(\"mentionResolvers is invalid\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction normalizeNodeConvertOptions(options: NodeConvertOptions): NodeConvertOptions {\n const normalized = snapshotNodeOptions(\n options,\n [...CORE_OPTION_KEYS, \"uploader\", \"signal\", \"timeoutMs\"],\n \"conversion options\",\n );\n validateUploader(normalized.uploader);\n return normalized;\n}\n\nfunction validateCloseOptions(options: NodeCloseOptions): void {\n validateKnownPlainObject(options, [\"behavior\", \"signal\", \"timeoutMs\"], \"close options\");\n if (\n options.behavior !== undefined &&\n options.behavior !== \"drain\" &&\n options.behavior !== \"cancel\"\n ) {\n throw new ConfigurationError('close.behavior must be \"drain\" or \"cancel\"', {\n code: \"invalid_close_behavior\",\n stage: \"configuration\",\n });\n }\n}\n\nfunction validateKnownPlainObject(\n value: unknown,\n allowed: ReadonlyArray<string>,\n label: string,\n): void {\n if (!isPlainObject(value)) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n const allowedKeys = new Set(allowed);\n for (const key of Object.keys(value as object)) {\n if (!allowedKeys.has(key)) {\n throw new ConfigurationError(`Unknown ${label} option: ${key}`, {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n }\n}\n\nfunction validateUploader(uploader: SlackUploader | undefined): void {\n if (uploader === undefined) {\n return;\n }\n try {\n if (\n (typeof uploader !== \"object\" && typeof uploader !== \"function\") ||\n uploader === null ||\n typeof Reflect.get(uploader, \"upload\") !== \"function\"\n ) {\n throw new TypeError(\"upload must be a function\");\n }\n } catch (cause) {\n throw new ConfigurationError(\"uploader is invalid\", {\n code: \"invalid_uploader\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction validateRendererIdentities(\n builtIns: ReadonlyArray<ImageRenderer>,\n additional: ReadonlyArray<ImageRenderer>,\n): void {\n const ids = new Set<string>();\n for (const renderer of [...builtIns, ...additional]) {\n let id: unknown;\n let output: unknown;\n let canRender: unknown;\n let render: unknown;\n try {\n id = Reflect.get(renderer as object, \"id\");\n output = Reflect.get(renderer as object, \"output\");\n canRender = Reflect.get(renderer as object, \"canRender\");\n render = Reflect.get(renderer as object, \"render\");\n } catch (cause) {\n throw new ConfigurationError(\"Renderer id could not be read\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n cause,\n });\n }\n if (\n typeof id !== \"string\" ||\n id.length === 0 ||\n (output !== \"url\" && output !== \"bytes\" && output !== \"both\") ||\n typeof canRender !== \"function\" ||\n typeof render !== \"function\"\n ) {\n throw new ConfigurationError(\"Renderer descriptor is invalid\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n if (ids.has(id)) {\n throw new ConfigurationError(`Duplicate renderer id: ${id}`, {\n code: \"duplicate_renderer_id\",\n stage: \"configuration\",\n });\n }\n ids.add(id);\n }\n}\n\nfunction collectReceiptSnapshot(\n collectors: ReadonlyArray<RecordingReceiptCollector>,\n): ReadonlyArray<UploadReceipt> {\n return Object.freeze(collectors.flatMap((collector) => collector.all()));\n}\n\nasync function collectSettledReceipts(\n collectors: ReadonlyArray<RecordingReceiptCollector>,\n): Promise<ReadonlyArray<UploadReceipt>> {\n try {\n const settled = await Promise.all(collectors.map((collector) => collector.settled()));\n return Object.freeze(settled.flat());\n } catch {\n return collectReceiptSnapshot(collectors);\n }\n}\n\nfunction normalizeConfigurationError(error: unknown): unknown {\n return isConfigurationError(error)\n ? error\n : new ConfigurationError(\"Node converter options could not be read\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n cause: error,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["resolver","ConfigurationError","DEFAULT_MAX_SOURCE_CHARS","DEFAULT_MAX_OUTPUT_BYTES","DEFAULT_MAX_WIDTH","DEFAULT_MAX_HEIGHT","DEFAULT_DEVICE_SCALE_FACTOR","DEFAULT_BACKGROUND_COLOR","DEFAULT_VIEWPORT_WIDTH","DEFAULT_VIEWPORT_HEIGHT","browserGlobal","validateOptions","validatePositiveInteger","validatePositiveFinite","browserGlobal","validatePositiveInteger","OperationAbortedError","OperationDeadlineExceededError","OperationShutdownError","ConfigurationError","OperationShutdownError","requireSignal","OperationErrorCode","OperationDeadlineExceededError","validatePositiveInteger","validateNonNegativeInteger","OperationShutdownError","OperationShutdownError","OperationErrorCode","ConfigurationError"],"sources":["../src/errors.ts","../src/katex-assets.ts","../src/image-output.ts","../src/node-options.ts","../src/katex-renderer.ts","../src/mermaid-assets.ts","../src/mermaid-renderer.ts","../src/operation-control.ts","../src/puppeteer-render-runtime.ts","../src/status.ts","../src/upload-scheduler.ts","../src/create-node-converter.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 { createHash } from \"node:crypto\";\n\nimport { NodeRenderError, NodeRenderErrorCode, NodeRenderStage } from \"./errors.js\";\n\nconst PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);\nconst PNG_WIDTH_OFFSET = 16;\nconst PNG_HEIGHT_OFFSET = 20;\nconst PNG_HEADER_BYTES = 24;\nconst PNG_IHDR = new Uint8Array([73, 72, 68, 82]);\nconst PNG_IHDR_OFFSET = 12;\n\nexport interface ImageLimits {\n readonly maxOutputBytes: number;\n readonly maxWidth: number;\n readonly maxHeight: number;\n}\n\nexport function deterministicPngFilename(\n prefix: string,\n source: string,\n optionsFingerprint: string,\n): string {\n const digest = createHash(\"sha256\")\n .update(prefix)\n .update(\"\\0\")\n .update(optionsFingerprint)\n .update(\"\\0\")\n .update(source)\n .digest(\"hex\")\n .slice(0, 16);\n return `${prefix}-${digest}.png`;\n}\n\nexport function assertSourceLimit(source: string, maxSourceChars: number): void {\n if (source.length > maxSourceChars) {\n throw new NodeRenderError(\n NodeRenderErrorCode.SourceLimit,\n `Render source exceeds ${String(maxSourceChars)} characters`,\n { stage: NodeRenderStage.SourceValidation, retryable: false },\n );\n }\n}\n\nexport function assertPngLimits(data: Uint8Array, limits: ImageLimits): void {\n if (data.byteLength > limits.maxOutputBytes) {\n throw new NodeRenderError(\n NodeRenderErrorCode.OutputLimit,\n `Rendered image exceeds ${String(limits.maxOutputBytes)} bytes`,\n { stage: NodeRenderStage.OutputValidation, retryable: false },\n );\n }\n const dimensions = readPngDimensions(data);\n if (dimensions === undefined) {\n throw new NodeRenderError(\n NodeRenderErrorCode.RenderFailed,\n \"Renderer returned invalid PNG data\",\n { stage: NodeRenderStage.OutputValidation, retryable: false },\n );\n }\n if (dimensions.width > limits.maxWidth || dimensions.height > limits.maxHeight) {\n throw new NodeRenderError(\n NodeRenderErrorCode.DimensionLimit,\n `Rendered image exceeds ${String(limits.maxWidth)}x${String(limits.maxHeight)} pixels`,\n { stage: NodeRenderStage.Layout, retryable: false },\n );\n }\n}\n\nfunction readPngDimensions(\n data: Uint8Array,\n): { readonly width: number; readonly height: number } | undefined {\n if (data.byteLength < PNG_HEADER_BYTES) {\n return undefined;\n }\n for (const [index, byte] of PNG_SIGNATURE.entries()) {\n if (data[index] !== byte) {\n return undefined;\n }\n }\n for (const [index, byte] of PNG_IHDR.entries()) {\n if (data[PNG_IHDR_OFFSET + index] !== byte) {\n return undefined;\n }\n }\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const width = view.getUint32(PNG_WIDTH_OFFSET);\n const height = view.getUint32(PNG_HEIGHT_OFFSET);\n return width > 0 && height > 0 ? { width, height } : undefined;\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 isOperationError,\n type BytesImage,\n type BytesImageRenderer,\n type OperationContext,\n type RenderRequest,\n} from \"slackmark\";\n\nimport {\n isNodeRenderError,\n NodeRenderError,\n NodeRenderErrorCode,\n NodeRenderStage,\n} from \"./errors.js\";\nimport { assertPngLimits, assertSourceLimit, deterministicPngFilename } from \"./image-output.js\";\nimport type { ImageLimits } from \"./image-output.js\";\nimport type { KatexAssetLoader } from \"./katex-assets.js\";\nimport { assertNodeMethod, invalidNodeOptions, snapshotNodeOptions } from \"./node-options.js\";\nimport type { RenderRuntime } from \"./puppeteer-render-runtime.js\";\n\nconst DEFAULT_MAX_SOURCE_CHARS = 20_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 10 * 1024 * 1024;\nconst DEFAULT_MAX_WIDTH = 4096;\nconst DEFAULT_MAX_HEIGHT = 4096;\nconst DEFAULT_MAX_EXPAND = 1000;\nconst DEFAULT_MAX_SIZE = 50;\nconst DEFAULT_FONT_SIZE_PX = 20;\nconst DEFAULT_PADDING_PX = 16;\nconst DEFAULT_DEVICE_SCALE_FACTOR = 2;\nconst DEFAULT_BACKGROUND_COLOR = \"white\";\nconst DEFAULT_VIEWPORT_WIDTH = 1280;\nconst DEFAULT_VIEWPORT_HEIGHT = 720;\nconst KATEX_LANGUAGES: ReadonlySet<string> = new Set([\"katex\", \"latex\", \"math\", \"tex\"]);\nconst KATEX_SHELL =\n \"<!doctype html><html><head><meta charset=\\\"utf-8\\\"><meta http-equiv=\\\"Content-Security-Policy\\\" content=\\\"default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; font-src data:; img-src 'none'; connect-src 'none'; worker-src 'none';\\\"></head><body><div id=\\\"math\\\"></div></body></html>\";\nconst KATEX_LAYOUT_CSS =\n \"html,body{margin:0;padding:0}#math{display:inline-block;box-sizing:border-box}.katex-display{margin:0}\";\n\nexport interface KatexRendererOptions {\n readonly runtime: RenderRuntime;\n readonly assets: KatexAssetLoader;\n readonly backgroundColor?: string | undefined;\n readonly deviceScaleFactor?: number | undefined;\n readonly fontSizePx?: number | undefined;\n readonly paddingPx?: number | undefined;\n readonly maxExpand?: number | undefined;\n readonly maxSize?: number | undefined;\n readonly maxSourceChars?: number | undefined;\n readonly maxOutputBytes?: number | undefined;\n readonly maxWidth?: number | undefined;\n readonly maxHeight?: number | undefined;\n}\n\n/**\n * Renders display TeX with KaTeX, local fonts, and an isolated browser screenshot.\n */\nexport class KatexRenderer implements BytesImageRenderer {\n readonly id: string;\n readonly output: \"bytes\";\n private readonly runtime: RenderRuntime;\n private readonly assets: KatexAssetLoader;\n private readonly backgroundColor: string;\n private readonly deviceScaleFactor: number;\n private readonly fontSizePx: number;\n private readonly paddingPx: number;\n private readonly maxExpand: number;\n private readonly maxSize: number;\n private readonly maxSourceChars: number;\n private readonly imageLimits: ImageLimits;\n private readonly optionsFingerprint: string;\n\n constructor(options: KatexRendererOptions) {\n const validated = snapshotNodeOptions(\n options,\n [\n \"runtime\",\n \"assets\",\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"fontSizePx\",\n \"paddingPx\",\n \"maxExpand\",\n \"maxSize\",\n \"maxSourceChars\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"KatexRenderer\",\n );\n assertNodeMethod(validated.runtime, \"run\", \"RenderRuntime\");\n assertNodeMethod(validated.assets, \"loadScript\", \"KatexAssetLoader\");\n assertNodeMethod(validated.assets, \"loadCss\", \"KatexAssetLoader\");\n this.id = \"katex\";\n this.output = \"bytes\";\n this.runtime = validated.runtime;\n this.assets = validated.assets;\n this.backgroundColor = validated.backgroundColor ?? DEFAULT_BACKGROUND_COLOR;\n this.deviceScaleFactor = validated.deviceScaleFactor ?? DEFAULT_DEVICE_SCALE_FACTOR;\n this.fontSizePx = validated.fontSizePx ?? DEFAULT_FONT_SIZE_PX;\n this.paddingPx = validated.paddingPx ?? DEFAULT_PADDING_PX;\n this.maxExpand = validated.maxExpand ?? DEFAULT_MAX_EXPAND;\n this.maxSize = validated.maxSize ?? DEFAULT_MAX_SIZE;\n this.maxSourceChars = validated.maxSourceChars ?? DEFAULT_MAX_SOURCE_CHARS;\n this.imageLimits = {\n maxOutputBytes: validated.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES,\n maxWidth: validated.maxWidth ?? DEFAULT_MAX_WIDTH,\n maxHeight: validated.maxHeight ?? DEFAULT_MAX_HEIGHT,\n };\n this.optionsFingerprint = [\n this.backgroundColor,\n String(this.deviceScaleFactor),\n String(this.fontSizePx),\n String(this.paddingPx),\n String(this.maxExpand),\n String(this.maxSize),\n String(this.maxSourceChars),\n String(this.imageLimits.maxOutputBytes),\n String(this.imageLimits.maxWidth),\n String(this.imageLimits.maxHeight),\n ].join(\":\");\n\n validateOptions({\n backgroundColor: this.backgroundColor,\n deviceScaleFactor: this.deviceScaleFactor,\n fontSizePx: this.fontSizePx,\n paddingPx: this.paddingPx,\n maxExpand: this.maxExpand,\n maxSize: this.maxSize,\n maxSourceChars: this.maxSourceChars,\n imageLimits: this.imageLimits,\n });\n }\n\n canRender(request: RenderRequest): boolean {\n return KATEX_LANGUAGES.has(request.lang.trim().toLowerCase());\n }\n\n async render(request: RenderRequest, context: OperationContext): Promise<BytesImage | null> {\n if (!this.canRender(request)) {\n return null;\n }\n assertSourceLimit(request.source, this.maxSourceChars);\n\n let data: Uint8Array;\n try {\n data = await this.runtime.run(async (context) => {\n const script = await this.assets.loadScript();\n const css = await this.assets.loadCss();\n const page = await context.newPage();\n await page.setViewport({\n width: DEFAULT_VIEWPORT_WIDTH,\n height: DEFAULT_VIEWPORT_HEIGHT,\n deviceScaleFactor: this.deviceScaleFactor,\n });\n await page.setContent(KATEX_SHELL, { waitUntil: \"domcontentloaded\" });\n await page.addStyleTag({ content: `${css}\\n${KATEX_LAYOUT_CSS}` });\n await page.addScriptTag({ content: script });\n await page.$eval(\n \"body\",\n (body, backgroundColor) => {\n body.style.background = backgroundColor;\n },\n this.backgroundColor,\n );\n await page.$eval(\n \"#math\",\n (container, values) => {\n const browserGlobal = globalThis as typeof globalThis & {\n katex?: {\n renderToString(source: string, options: Readonly<Record<string, unknown>>): string;\n };\n };\n const katex = browserGlobal.katex;\n if (katex === undefined) {\n throw new Error(\"KaTeX browser harness failed to initialize\");\n }\n container.innerHTML = katex.renderToString(values.source, {\n displayMode: true,\n globalGroup: false,\n maxExpand: values.maxExpand,\n maxSize: values.maxSize,\n output: \"html\",\n strict: \"ignore\",\n throwOnError: true,\n trust: false,\n });\n container.setAttribute(\n \"style\",\n `font-size:${String(values.fontSizePx)}px;padding:${String(values.paddingPx)}px`,\n );\n },\n {\n source: request.source,\n maxExpand: this.maxExpand,\n maxSize: this.maxSize,\n fontSizePx: this.fontSizePx,\n paddingPx: this.paddingPx,\n },\n );\n await page.evaluate(async () => {\n await document.fonts.ready;\n });\n\n const element = await page.$(\"#math\");\n if (element === null) {\n throw new Error(\"KaTeX screenshot element is missing\");\n }\n const box = await element.boundingBox();\n if (box === null) {\n throw new Error(\"KaTeX screenshot element has no dimensions\");\n }\n const pixelWidth = Math.ceil(box.width * this.deviceScaleFactor);\n const pixelHeight = Math.ceil(box.height * this.deviceScaleFactor);\n if (pixelWidth > this.imageLimits.maxWidth || pixelHeight > this.imageLimits.maxHeight) {\n throw new NodeRenderError(\n NodeRenderErrorCode.DimensionLimit,\n `Rendered image exceeds ${String(this.imageLimits.maxWidth)}x${String(this.imageLimits.maxHeight)} pixels`,\n { stage: NodeRenderStage.Layout, retryable: false },\n );\n }\n return element.screenshot({\n type: \"png\",\n omitBackground: this.backgroundColor === \"transparent\",\n });\n }, context);\n } catch (error) {\n if (isOperationError(error)) {\n throw error;\n }\n if (isNodeRenderError(error)) {\n const sanitizedRenderFailure =\n error.code === NodeRenderErrorCode.RenderFailed && error.cause === undefined;\n if (error.code !== NodeRenderErrorCode.RenderFailed || sanitizedRenderFailure) {\n throw error;\n }\n }\n throw new NodeRenderError(NodeRenderErrorCode.RenderFailed, \"KaTeX rendering failed\", {\n stage: \"render\",\n retryable: false,\n });\n }\n assertPngLimits(data, this.imageLimits);\n\n return {\n kind: \"bytes\",\n data,\n mimeType: \"image/png\",\n filename: deterministicPngFilename(\"math\", request.source, this.optionsFingerprint),\n altText: request.altText,\n };\n }\n}\n\nfunction validateOptions(renderer: {\n readonly backgroundColor: string;\n readonly deviceScaleFactor: number;\n readonly fontSizePx: number;\n readonly paddingPx: number;\n readonly maxExpand: number;\n readonly maxSize: number;\n readonly maxSourceChars: number;\n readonly imageLimits: ImageLimits;\n}): void {\n if (typeof renderer.backgroundColor !== \"string\" || renderer.backgroundColor.length === 0) {\n throw invalidNodeOptions(\"backgroundColor must be a nonempty string\");\n }\n validatePositiveFinite(renderer.deviceScaleFactor, \"deviceScaleFactor\");\n validatePositiveFinite(renderer.fontSizePx, \"fontSizePx\");\n validateNonNegativeFinite(renderer.paddingPx, \"paddingPx\");\n validatePositiveInteger(renderer.maxExpand, \"maxExpand\");\n validatePositiveFinite(renderer.maxSize, \"maxSize\");\n validatePositiveInteger(renderer.maxSourceChars, \"maxSourceChars\");\n validatePositiveInteger(renderer.imageLimits.maxOutputBytes, \"maxOutputBytes\");\n validatePositiveInteger(renderer.imageLimits.maxWidth, \"maxWidth\");\n validatePositiveInteger(renderer.imageLimits.maxHeight, \"maxHeight\");\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 validatePositiveFinite(value: number, name: string): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidNodeOptions(`${name} must be positive`);\n }\n}\n\nfunction validateNonNegativeFinite(value: number, name: string): void {\n if (!Number.isFinite(value) || value < 0) {\n throw invalidNodeOptions(`${name} must be non-negative`);\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 type { HTTPRequest } from \"puppeteer\";\nimport {\n isOperationError,\n type BytesImage,\n type BytesImageRenderer,\n type OperationContext,\n type RenderRequest,\n} from \"slackmark\";\n\nimport { isNodeRenderError, NodeRenderError, NodeRenderErrorCode } from \"./errors.js\";\nimport { assertPngLimits, assertSourceLimit, deterministicPngFilename } from \"./image-output.js\";\nimport type { ImageLimits } from \"./image-output.js\";\nimport type { MermaidAssetLoader } from \"./mermaid-assets.js\";\nimport { assertNodeMethod, invalidNodeOptions, snapshotNodeOptions } from \"./node-options.js\";\nimport type { RenderRuntime } from \"./puppeteer-render-runtime.js\";\n\nconst DEFAULT_MAX_SOURCE_CHARS = 50_000;\nconst DEFAULT_MAX_OUTPUT_BYTES = 10 * 1024 * 1024;\nconst DEFAULT_MAX_WIDTH = 4096;\nconst DEFAULT_MAX_HEIGHT = 4096;\nconst DEFAULT_MAX_EDGES = 500;\nconst DEFAULT_DEVICE_SCALE_FACTOR = 2;\nconst DEFAULT_BACKGROUND_COLOR = \"white\";\nconst DEFAULT_VIEWPORT_WIDTH = 1280;\nconst DEFAULT_VIEWPORT_HEIGHT = 720;\nconst MERMAID_SHELL =\n \"<!doctype html><html><head><meta charset=\\\"utf-8\\\"><meta http-equiv=\\\"Content-Security-Policy\\\" content=\\\"default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src 'none'; font-src 'none'; connect-src 'none'; worker-src 'none'; object-src 'none'; frame-src 'none';\\\"></head><body><div id=\\\"diagram\\\"></div></body></html>\";\nconst SECURE_MERMAID_KEYS = [\n \"secure\",\n \"securityLevel\",\n \"startOnLoad\",\n \"maxTextSize\",\n \"suppressErrorRendering\",\n \"maxEdges\",\n \"deterministicIds\",\n \"deterministicIDSeed\",\n \"layout\",\n];\n\nexport type MermaidTheme = \"base\" | \"dark\" | \"default\" | \"forest\" | \"neutral\";\nconst MERMAID_THEMES: ReadonlySet<string> = new Set([\n \"base\",\n \"dark\",\n \"default\",\n \"forest\",\n \"neutral\",\n]);\n\nexport interface MermaidRendererOptions {\n readonly runtime: RenderRuntime;\n readonly assets: MermaidAssetLoader;\n readonly theme?: MermaidTheme | undefined;\n readonly backgroundColor?: string | undefined;\n readonly deviceScaleFactor?: number | undefined;\n readonly maxSourceChars?: number | undefined;\n readonly maxEdges?: number | undefined;\n readonly maxOutputBytes?: number | undefined;\n readonly maxWidth?: number | undefined;\n readonly maxHeight?: number | undefined;\n}\n\nexport class MermaidRenderer implements BytesImageRenderer {\n readonly id: string;\n readonly output: \"bytes\";\n private readonly runtime: RenderRuntime;\n private readonly assets: MermaidAssetLoader;\n private readonly theme: MermaidTheme;\n private readonly backgroundColor: string;\n private readonly deviceScaleFactor: number;\n private readonly maxSourceChars: number;\n private readonly maxEdges: number;\n private readonly imageLimits: ImageLimits;\n private readonly optionsFingerprint: string;\n\n constructor(options: MermaidRendererOptions) {\n const validated = snapshotNodeOptions(\n options,\n [\n \"runtime\",\n \"assets\",\n \"theme\",\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"maxSourceChars\",\n \"maxEdges\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"MermaidRenderer\",\n );\n assertNodeMethod(validated.runtime, \"run\", \"RenderRuntime\");\n assertNodeMethod(validated.assets, \"loadScript\", \"MermaidAssetLoader\");\n this.id = \"mermaid\";\n this.output = \"bytes\";\n this.runtime = validated.runtime;\n this.assets = validated.assets;\n this.theme = validated.theme ?? \"default\";\n this.backgroundColor = validated.backgroundColor ?? DEFAULT_BACKGROUND_COLOR;\n this.deviceScaleFactor = validated.deviceScaleFactor ?? DEFAULT_DEVICE_SCALE_FACTOR;\n this.maxSourceChars = validated.maxSourceChars ?? DEFAULT_MAX_SOURCE_CHARS;\n this.maxEdges = validated.maxEdges ?? DEFAULT_MAX_EDGES;\n this.imageLimits = {\n maxOutputBytes: validated.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES,\n maxWidth: validated.maxWidth ?? DEFAULT_MAX_WIDTH,\n maxHeight: validated.maxHeight ?? DEFAULT_MAX_HEIGHT,\n };\n this.optionsFingerprint = [\n this.theme,\n this.backgroundColor,\n String(this.deviceScaleFactor),\n String(this.maxSourceChars),\n String(this.maxEdges),\n String(this.imageLimits.maxOutputBytes),\n String(this.imageLimits.maxWidth),\n String(this.imageLimits.maxHeight),\n ].join(\":\");\n validateOptions({\n theme: this.theme,\n backgroundColor: this.backgroundColor,\n deviceScaleFactor: this.deviceScaleFactor,\n maxSourceChars: this.maxSourceChars,\n maxEdges: this.maxEdges,\n imageLimits: this.imageLimits,\n });\n }\n\n canRender(request: RenderRequest): boolean {\n return request.lang.trim().toLowerCase() === \"mermaid\";\n }\n\n async render(request: RenderRequest, context: OperationContext): Promise<BytesImage | null> {\n if (!this.canRender(request)) {\n return null;\n }\n assertSourceLimit(request.source, this.maxSourceChars);\n\n let data: Uint8Array;\n try {\n data = await this.runtime.run(async (context) => {\n const script = await this.assets.loadScript();\n const page = await context.newPage();\n await page.setRequestInterception(true);\n page.on(\"request\", blockRequest);\n await page.setViewport({\n width: DEFAULT_VIEWPORT_WIDTH,\n height: DEFAULT_VIEWPORT_HEIGHT,\n deviceScaleFactor: this.deviceScaleFactor,\n });\n await page.setContent(MERMAID_SHELL, { waitUntil: \"domcontentloaded\" });\n await page.addScriptTag({ content: script });\n await page.evaluate(\n async (input) => {\n const browserGlobal = globalThis as typeof globalThis & {\n mermaid?: {\n initialize(config: Readonly<Record<string, unknown>>): void;\n parse(source: string, options: { suppressErrors: boolean }): Promise<unknown>;\n render(\n id: string,\n source: string,\n container: Element,\n ): Promise<{ readonly svg: string }>;\n };\n };\n const mermaid = browserGlobal.mermaid;\n const container = document.querySelector(\"#diagram\");\n if (mermaid === undefined || container === null) {\n throw new Error(\"Mermaid browser harness failed to initialize\");\n }\n mermaid.initialize({\n deterministicIds: true,\n deterministicIDSeed: \"slackmark-node\",\n layout: \"dagre\",\n logLevel: \"fatal\",\n maxEdges: input.maxEdges,\n maxTextSize: input.maxSourceChars,\n secure: input.secureKeys,\n securityLevel: \"strict\",\n startOnLoad: false,\n suppressErrorRendering: true,\n theme: input.theme,\n });\n await mermaid.parse(input.source, { suppressErrors: false });\n const rendered = await mermaid.render(\"slackmark-diagram\", input.source, container);\n container.innerHTML = rendered.svg;\n document.body.style.background = input.backgroundColor;\n },\n {\n source: request.source,\n theme: this.theme,\n backgroundColor: this.backgroundColor,\n maxSourceChars: this.maxSourceChars,\n maxEdges: this.maxEdges,\n secureKeys: SECURE_MERMAID_KEYS,\n },\n );\n const element = await page.$(\"#diagram svg\");\n if (element === null) {\n throw new Error(\"Mermaid produced no SVG\");\n }\n const box = await element.boundingBox();\n if (box === null) {\n throw new Error(\"Mermaid SVG has no dimensions\");\n }\n const pixelWidth = Math.ceil(box.width * this.deviceScaleFactor);\n const pixelHeight = Math.ceil(box.height * this.deviceScaleFactor);\n if (pixelWidth > this.imageLimits.maxWidth || pixelHeight > this.imageLimits.maxHeight) {\n throw new NodeRenderError(\n NodeRenderErrorCode.DimensionLimit,\n \"Rendered Mermaid image exceeds configured dimensions\",\n { stage: \"layout\", retryable: false },\n );\n }\n return element.screenshot({\n type: \"png\",\n omitBackground: this.backgroundColor === \"transparent\",\n });\n }, context);\n } catch (error) {\n if (isOperationError(error)) {\n throw error;\n }\n if (isNodeRenderError(error)) {\n if (error.code !== NodeRenderErrorCode.RenderFailed) {\n throw error;\n }\n }\n throw new NodeRenderError(NodeRenderErrorCode.RenderFailed, \"Mermaid rendering failed\", {\n stage: \"render\",\n retryable: false,\n });\n }\n assertPngLimits(data, this.imageLimits);\n return {\n kind: \"bytes\",\n data,\n mimeType: \"image/png\",\n filename: deterministicPngFilename(\"mermaid\", request.source, this.optionsFingerprint),\n altText: request.altText,\n };\n }\n}\n\nfunction blockRequest(request: HTTPRequest): void {\n void request.abort(\"blockedbyclient\");\n}\n\nfunction validateOptions(renderer: {\n readonly theme: MermaidTheme;\n readonly backgroundColor: string;\n readonly deviceScaleFactor: number;\n readonly maxSourceChars: number;\n readonly maxEdges: number;\n readonly imageLimits: ImageLimits;\n}): void {\n if (typeof renderer.theme !== \"string\" || !MERMAID_THEMES.has(renderer.theme)) {\n throw invalidNodeOptions(\"theme must be base, dark, default, forest, or neutral\");\n }\n if (typeof renderer.backgroundColor !== \"string\" || renderer.backgroundColor.length === 0) {\n throw invalidNodeOptions(\"backgroundColor must be a nonempty string\");\n }\n validatePositiveFinite(renderer.deviceScaleFactor, \"deviceScaleFactor\");\n validatePositiveInteger(renderer.maxSourceChars, \"maxSourceChars\");\n validatePositiveInteger(renderer.maxEdges, \"maxEdges\");\n validatePositiveInteger(renderer.imageLimits.maxOutputBytes, \"maxOutputBytes\");\n validatePositiveInteger(renderer.imageLimits.maxWidth, \"maxWidth\");\n validatePositiveInteger(renderer.imageLimits.maxHeight, \"maxHeight\");\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 validatePositiveFinite(value: number, name: string): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidNodeOptions(`${name} must be positive`);\n }\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","export const NodeConverterState = {\n Open: \"open\",\n Closing: \"closing\",\n Closed: \"closed\",\n CloseFailed: \"close-failed\",\n} as const;\n\nexport type NodeConverterState = (typeof NodeConverterState)[keyof typeof NodeConverterState];\n\nexport interface NodeWorkStatus {\n readonly accepting: boolean;\n readonly active: number;\n readonly queued: number;\n readonly retainedBytes: number;\n}\n\nexport interface NodeConverterStatus {\n readonly state: NodeConverterState;\n readonly activeOperations: number;\n readonly render: NodeWorkStatus;\n readonly upload: NodeWorkStatus;\n}\n","import {\n OperationShutdownError,\n type BytesImage,\n type OperationContext,\n type SlackUploader,\n} from \"slackmark\";\nimport { SlackUploadError, SlackUploadStage } from \"slackmark/slack\";\n\nimport { OperationScope, operationReason, raceWithContext } from \"./operation-control.js\";\nimport type { CloseBehavior, WorkQueueStatus } from \"./puppeteer-render-runtime.js\";\n\nexport interface UploadSchedulerOptions {\n readonly concurrency: number;\n readonly maxQueueSize: number;\n}\n\ninterface PendingUpload {\n start(): void;\n reject(error: unknown): void;\n}\n\nexport class UploadScheduler {\n private readonly concurrency: number;\n private readonly maxQueueSize: number;\n private readonly pending: PendingUpload[];\n private readonly activeScopes: Set<OperationScope>;\n private readonly idleResolvers: Array<() => void>;\n private active: number;\n private retainedBytes: number;\n private closePromise: Promise<void> | undefined;\n private closeBehavior: CloseBehavior | undefined;\n private accepting: boolean;\n\n constructor(options: UploadSchedulerOptions) {\n this.concurrency = options.concurrency;\n this.maxQueueSize = options.maxQueueSize;\n this.pending = [];\n this.activeScopes = new Set();\n this.idleResolvers = [];\n this.active = 0;\n this.retainedBytes = 0;\n this.closePromise = undefined;\n this.closeBehavior = undefined;\n this.accepting = true;\n validatePositiveInteger(this.concurrency, \"upload.concurrency\");\n validateNonNegativeInteger(this.maxQueueSize, \"upload.maxQueueSize\");\n }\n\n schedule(\n uploader: SlackUploader,\n image: BytesImage,\n operation: OperationContext,\n ): ReturnType<SlackUploader[\"upload\"]> {\n if (!this.accepting) {\n return Promise.reject(new OperationShutdownError(\"upload_admission\"));\n }\n if (this.active >= this.concurrency && this.pending.length >= this.maxQueueSize) {\n return Promise.reject(queueError());\n }\n let scope: OperationScope;\n try {\n scope = new OperationScope(operation, \"upload\");\n } catch (error) {\n return Promise.reject(error);\n }\n this.retainedBytes += image.data.byteLength;\n return new Promise<Awaited<ReturnType<SlackUploader[\"upload\"]>>>((resolve, reject) => {\n let pending: PendingUpload;\n const abortWhileQueued = (): void => {\n const index = this.pending.indexOf(pending);\n if (index >= 0) {\n this.pending.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(uploader, image, scope, resolve, reject);\n },\n reject: (error: unknown): void => {\n scope.context.signal?.removeEventListener(\"abort\", abortWhileQueued);\n scope.cleanup();\n this.retainedBytes -= image.data.byteLength;\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.active < this.concurrency) {\n this.active += 1;\n pending.start();\n return;\n }\n scope.context.signal?.addEventListener(\"abort\", abortWhileQueued, { once: true });\n this.pending.push(pending);\n });\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, \"upload_close\");\n this.accepting = false;\n this.closeBehavior = behavior;\n if (behavior === \"cancel\") {\n const shutdown = new OperationShutdownError(\"upload\");\n for (const pending of this.pending.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"upload\");\n }\n }\n this.closePromise = raceWithContext(this.waitForIdle(), closeScope.context)\n .catch((error: unknown) => {\n this.closeBehavior = \"cancel\";\n const shutdown = new OperationShutdownError(\"upload\");\n for (const pending of this.pending.splice(0)) {\n pending.reject(shutdown);\n }\n for (const scope of this.activeScopes) {\n scope.abortForShutdown(\"upload\");\n }\n throw error;\n })\n .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.active,\n queued: this.pending.length,\n retainedBytes: this.retainedBytes,\n });\n }\n\n private startUnderlying(\n uploader: SlackUploader,\n image: BytesImage,\n scope: OperationScope,\n resolve: (\n value:\n | Awaited<ReturnType<SlackUploader[\"upload\"]>>\n | PromiseLike<Awaited<ReturnType<SlackUploader[\"upload\"]>>>,\n ) => void,\n reject: (reason?: unknown) => void,\n ): void {\n const underlying = Promise.resolve().then(() => uploader.upload(image, scope.context));\n void underlying.then(\n (value) => {\n resolve(value);\n this.finishUnderlying(scope, image.data.byteLength);\n return undefined;\n },\n (error: unknown) => {\n reject(error);\n this.finishUnderlying(scope, image.data.byteLength);\n return undefined;\n },\n );\n }\n\n private finishUnderlying(scope: OperationScope, byteLength: number): void {\n scope.cleanup();\n this.activeScopes.delete(scope);\n this.active -= 1;\n this.retainedBytes -= byteLength;\n const next = this.pending.shift();\n if (next !== undefined && this.closeBehavior !== \"cancel\") {\n this.active += 1;\n next.start();\n } else if (next !== undefined) {\n next.reject(new OperationShutdownError(\"upload\"));\n }\n if (this.active === 0 && this.pending.length === 0) {\n for (const resolve of this.idleResolvers.splice(0)) {\n resolve();\n }\n }\n }\n\n private waitForIdle(): Promise<void> {\n if (this.active === 0 && this.pending.length === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n}\n\nexport class ScheduledSlackUploader implements SlackUploader {\n private readonly scheduler: UploadScheduler;\n private readonly uploader: SlackUploader;\n\n constructor(scheduler: UploadScheduler, uploader: SlackUploader) {\n this.scheduler = scheduler;\n this.uploader = uploader;\n }\n\n upload(image: BytesImage, operation: OperationContext): ReturnType<SlackUploader[\"upload\"]> {\n return this.scheduler.schedule(this.uploader, image, operation);\n }\n}\n\nfunction queueError(): SlackUploadError {\n return new SlackUploadError(\"Slack upload queue is full\", {\n stage: SlackUploadStage.Admission,\n code: \"upload_queue_full\",\n retryable: true,\n });\n}\n\nfunction requireSignal(operation: OperationContext): AbortSignal {\n if (operation.signal === undefined) {\n throw new OperationShutdownError(\"upload\");\n }\n return operation.signal;\n}\n\nfunction validatePositiveInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new RangeError(`${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 new RangeError(`${name} must be a non-negative integer`);\n }\n}\n","import {\n ConfigurationError,\n OperationErrorCode,\n OperationShutdownError,\n RecordingReceiptCollector,\n attachReceipts,\n createConverter,\n isConfigurationError,\n isOperationError,\n lockReceiptSnapshot,\n resolveCapabilities,\n type ConversionMessagesResult,\n type ConversionResult,\n type ConvertOptions,\n type ImageRenderer,\n type OperationContext,\n type OperationOptions,\n type ReceiptCollector,\n type SlackMarkConverter,\n type SlackUploader,\n type UploadReceipt,\n} from \"slackmark\";\nimport type { LaunchOptions } from \"puppeteer\";\n\nimport { LocalKatexAssetLoader } from \"./katex-assets.js\";\nimport { KatexRenderer } from \"./katex-renderer.js\";\nimport type { KatexRendererOptions } from \"./katex-renderer.js\";\nimport { LocalMermaidAssetLoader } from \"./mermaid-assets.js\";\nimport { MermaidRenderer } from \"./mermaid-renderer.js\";\nimport type { MermaidRendererOptions } from \"./mermaid-renderer.js\";\nimport { NodeShutdownTimeoutError } from \"./errors.js\";\nimport { snapshotNodeOptions } from \"./node-options.js\";\nimport { createOperationScope, isPlainObject, type OperationScope } from \"./operation-control.js\";\nimport {\n PuppeteerBrowserLauncher,\n PuppeteerRenderRuntime,\n type CloseBehavior,\n type RenderRuntime,\n} from \"./puppeteer-render-runtime.js\";\nimport { NodeConverterState, type NodeConverterStatus } from \"./status.js\";\nimport { ScheduledSlackUploader, UploadScheduler } from \"./upload-scheduler.js\";\n\nconst DEFAULT_CLOSE_TIMEOUT_MS = 5_000;\nconst CORE_OPTION_KEYS = [\n \"capabilities\",\n \"capabilityOverrides\",\n \"overflow\",\n \"strategy\",\n \"enableMath\",\n \"enableInlineMath\",\n \"enableFrontmatter\",\n \"mentionResolvers\",\n] as const;\n\ntype NodeConversionDefaults = Omit<\n ConvertOptions,\n \"renderers\" | \"uploader\" | \"signal\" | \"timeoutMs\"\n>;\n\nexport interface NodeRenderingOptions {\n readonly concurrency?: number | undefined;\n readonly maxQueueSize?: number | undefined;\n readonly launchOptions?: LaunchOptions | undefined;\n readonly mermaid?: Omit<MermaidRendererOptions, \"runtime\" | \"assets\"> | undefined;\n readonly math?: Omit<KatexRendererOptions, \"runtime\" | \"assets\"> | undefined;\n}\n\nexport interface NodeUploadOptions {\n readonly concurrency?: number | undefined;\n readonly maxQueueSize?: number | undefined;\n}\n\nexport interface CreateNodeConverterOptions extends NodeConversionDefaults {\n readonly rendering?: NodeRenderingOptions | undefined;\n readonly upload?: NodeUploadOptions | undefined;\n readonly additionalRenderers?: ReadonlyArray<ImageRenderer> | undefined;\n readonly uploader?: SlackUploader | undefined;\n}\n\nexport type NodeConvertOptions = NodeConversionDefaults &\n OperationOptions & {\n readonly uploader?: SlackUploader | undefined;\n };\n\nexport interface NodeCloseOptions extends OperationOptions {\n readonly behavior?: CloseBehavior | undefined;\n}\n\nexport interface NodeConverter extends AsyncDisposable {\n convert(markdown: string, options?: NodeConvertOptions): Promise<ConversionResult>;\n convertToMessages(\n markdown: string,\n options?: NodeConvertOptions,\n ): Promise<ConversionMessagesResult>;\n warmup(options?: OperationOptions): Promise<void>;\n close(options?: NodeCloseOptions): Promise<void>;\n status(): NodeConverterStatus;\n}\n\nexport interface ManagedNodeConverterDeps {\n readonly converter: SlackMarkConverter;\n readonly runtime: RenderRuntime;\n readonly defaultUploader: SlackUploader | undefined;\n readonly uploadScheduler: UploadScheduler;\n readonly warmupOperation: (operation: OperationContext) => Promise<void>;\n}\n\nexport class ManagedNodeConverter implements NodeConverter {\n private readonly converter: SlackMarkConverter;\n private readonly runtime: RenderRuntime;\n private readonly defaultUploader: SlackUploader | undefined;\n private readonly uploadScheduler: UploadScheduler;\n private readonly warmupOperation: (operation: OperationContext) => Promise<void>;\n private readonly activeScopes: Set<OperationScope>;\n private readonly activeReceipts: Map<OperationScope, RecordingReceiptCollector>;\n private readonly idleResolvers: Array<() => void>;\n private activeOperations: number;\n private closePromise: Promise<void> | undefined;\n private state: NodeConverterStatus[\"state\"];\n\n constructor(deps: ManagedNodeConverterDeps) {\n this.converter = deps.converter;\n this.runtime = deps.runtime;\n this.defaultUploader = deps.defaultUploader;\n this.uploadScheduler = deps.uploadScheduler;\n this.warmupOperation = deps.warmupOperation;\n this.activeScopes = new Set();\n this.activeReceipts = new Map();\n this.idleResolvers = [];\n this.activeOperations = 0;\n this.closePromise = undefined;\n this.state = NodeConverterState.Open;\n }\n\n convert(markdown: string, options: NodeConvertOptions = {}): Promise<ConversionResult> {\n try {\n const normalized = normalizeNodeConvertOptions(options);\n return this.runTracked(\n { signal: normalized.signal, timeoutMs: normalized.timeoutMs },\n (operation, receipts) =>\n this.converter.convertWithContext(\n markdown,\n prepareConversionOptions(normalized, this.defaultUploader, this.uploadScheduler),\n operation,\n receipts,\n ),\n );\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n }\n\n convertToMessages(\n markdown: string,\n options: NodeConvertOptions = {},\n ): Promise<ConversionMessagesResult> {\n try {\n const normalized = normalizeNodeConvertOptions(options);\n return this.runTracked(\n { signal: normalized.signal, timeoutMs: normalized.timeoutMs },\n (operation, receipts) =>\n this.converter.convertToMessagesWithContext(\n markdown,\n prepareConversionOptions(normalized, this.defaultUploader, this.uploadScheduler),\n operation,\n receipts,\n ),\n );\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n }\n\n warmup(options: OperationOptions = {}): Promise<void> {\n try {\n return this.runTracked(options, (operation) => this.warmupOperation(operation));\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n }\n\n close(options: NodeCloseOptions = {}): Promise<void> {\n if (this.closePromise !== undefined) {\n return this.closePromise;\n }\n let behavior: CloseBehavior;\n let scope: OperationScope;\n try {\n validateCloseOptions(options);\n behavior = options.behavior ?? \"drain\";\n scope = createOperationScope(\n {\n signal: options.signal,\n timeoutMs: options.timeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS,\n },\n \"close\",\n );\n } catch (error) {\n return Promise.reject(normalizeConfigurationError(error));\n }\n this.state = NodeConverterState.Closing;\n if (behavior === \"cancel\") {\n for (const active of this.activeScopes) {\n active.abortForShutdown(\"conversion\");\n }\n }\n const closingReceipts = [...this.activeReceipts.values()];\n this.closePromise = this.finishClose(scope, behavior, closingReceipts);\n return this.closePromise;\n }\n\n status(): NodeConverterStatus {\n return Object.freeze({\n state: this.state,\n activeOperations: this.activeOperations,\n render: this.runtime.status(),\n upload: this.uploadScheduler.status(),\n });\n }\n\n [Symbol.asyncDispose](): Promise<void> {\n return this.close({ behavior: \"cancel\", timeoutMs: DEFAULT_CLOSE_TIMEOUT_MS });\n }\n\n private runTracked<T>(\n options: OperationOptions,\n operation: (context: OperationContext, receipts: ReceiptCollector) => Promise<T>,\n ): Promise<T> {\n if (this.state !== NodeConverterState.Open) {\n return Promise.reject(new OperationShutdownError(\"conversion_admission\"));\n }\n const scope = createOperationScope(options, \"conversion\");\n const receipts = new RecordingReceiptCollector();\n this.activeScopes.add(scope);\n this.activeReceipts.set(scope, receipts);\n this.activeOperations += 1;\n const underlying = Promise.resolve().then(() => operation(scope.context, receipts));\n void underlying.then(\n () => {\n receipts.settle();\n this.finishTracked(scope);\n return undefined;\n },\n () => {\n receipts.settle();\n this.finishTracked(scope);\n return undefined;\n },\n );\n return scope.race(underlying).catch((error: unknown) => {\n throw lockReceiptSnapshot(attachReceipts(error, receipts.all(), receipts.settled()));\n });\n }\n\n private finishTracked(scope: OperationScope): void {\n scope.cleanup();\n this.activeScopes.delete(scope);\n this.activeReceipts.delete(scope);\n this.activeOperations -= 1;\n if (this.activeOperations === 0) {\n for (const resolve of this.idleResolvers.splice(0)) {\n resolve();\n }\n }\n }\n\n private async finishClose(\n scope: OperationScope,\n behavior: CloseBehavior,\n closingReceipts: ReadonlyArray<RecordingReceiptCollector>,\n ): Promise<void> {\n try {\n await scope.race(this.waitForIdle());\n await Promise.all([\n this.uploadScheduler.close(scope.context, behavior),\n this.runtime.close(scope.context, behavior),\n ]);\n this.state = NodeConverterState.Closed;\n } catch (error) {\n this.state = NodeConverterState.CloseFailed;\n for (const active of this.activeScopes) {\n active.abortForShutdown(\"conversion\");\n }\n const cleanupContext: OperationContext = {\n signal: undefined,\n deadlineMs: Date.now() + DEFAULT_CLOSE_TIMEOUT_MS,\n };\n void Promise.allSettled([\n this.uploadScheduler.close(cleanupContext, \"cancel\"),\n this.runtime.close(cleanupContext, \"cancel\"),\n ]);\n const receiptSnapshot = collectReceiptSnapshot(closingReceipts);\n const settledReceipts = collectSettledReceipts(closingReceipts);\n if (isOperationError(error) && error.code === OperationErrorCode.DeadlineExceeded) {\n throw new NodeShutdownTimeoutError(this.status(), receiptSnapshot, settledReceipts);\n }\n throw attachReceipts(error, receiptSnapshot, settledReceipts);\n } finally {\n scope.cleanup();\n }\n }\n\n private waitForIdle(): Promise<void> {\n if (this.activeOperations === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n}\n\nexport function createNodeConverter(options: CreateNodeConverterOptions = {}): NodeConverter {\n try {\n validateNodeFactoryOptions(options);\n const launcher = new PuppeteerBrowserLauncher();\n const runtime = new PuppeteerRenderRuntime({\n launcher,\n launchOptions: options.rendering?.launchOptions,\n concurrency: options.rendering?.concurrency,\n maxQueueSize: options.rendering?.maxQueueSize,\n });\n const mermaidAssets = new LocalMermaidAssetLoader();\n const katexAssets = new LocalKatexAssetLoader();\n const builtInRenderers: ReadonlyArray<ImageRenderer> = [\n new MermaidRenderer({\n ...options.rendering?.mermaid,\n runtime,\n assets: mermaidAssets,\n }),\n new KatexRenderer({\n ...options.rendering?.math,\n runtime,\n assets: katexAssets,\n }),\n ];\n const additionalRenderers = Object.freeze([...(options.additionalRenderers ?? [])]);\n validateRendererIdentities(builtInRenderers, additionalRenderers);\n const converter = createConverter({\n ...pickConversionDefaults(options),\n enableMath: options.enableMath ?? true,\n renderers: [...builtInRenderers, ...additionalRenderers],\n });\n const uploadScheduler = new UploadScheduler({\n concurrency: options.upload?.concurrency ?? 2,\n maxQueueSize: options.upload?.maxQueueSize ?? 16,\n });\n return new ManagedNodeConverter({\n converter,\n runtime,\n defaultUploader: options.uploader,\n uploadScheduler,\n warmupOperation: (operation) =>\n runtime.run(async () => {\n await Promise.all([\n mermaidAssets.loadScript(),\n katexAssets.loadScript(),\n katexAssets.loadCss(),\n ]);\n }, operation),\n });\n } catch (error) {\n if (isConfigurationError(error)) {\n throw error;\n }\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n throw new ConfigurationError(`Invalid slackmark-node configuration${detail}`, {\n code: \"invalid_node_configuration\",\n stage: \"configuration\",\n cause: error,\n });\n }\n}\n\nfunction prepareConversionOptions(\n options: NodeConvertOptions,\n defaultUploader: SlackUploader | undefined,\n scheduler: UploadScheduler,\n): ConvertOptions {\n const {\n signal: _signal,\n timeoutMs: _timeoutMs,\n uploader: perCallUploader,\n ...conversionOptions\n } = options;\n const uploader = perCallUploader ?? defaultUploader;\n return {\n ...conversionOptions,\n uploader: uploader === undefined ? undefined : new ScheduledSlackUploader(scheduler, uploader),\n };\n}\n\nfunction pickConversionDefaults(options: NodeConversionDefaults): NodeConversionDefaults {\n return {\n capabilities: options.capabilities,\n capabilityOverrides: options.capabilityOverrides,\n overflow: options.overflow,\n strategy: options.strategy,\n enableMath: options.enableMath,\n enableInlineMath: options.enableInlineMath,\n enableFrontmatter: options.enableFrontmatter,\n mentionResolvers: options.mentionResolvers,\n };\n}\n\nfunction validateNodeFactoryOptions(options: CreateNodeConverterOptions): void {\n validateKnownPlainObject(\n options,\n [...CORE_OPTION_KEYS, \"rendering\", \"upload\", \"additionalRenderers\", \"uploader\"],\n \"options\",\n );\n if (options.rendering !== undefined) {\n validateKnownPlainObject(\n options.rendering,\n [\"concurrency\", \"maxQueueSize\", \"launchOptions\", \"mermaid\", \"math\"],\n \"rendering\",\n );\n if (options.rendering.mermaid !== undefined) {\n validateKnownPlainObject(\n options.rendering.mermaid,\n [\n \"theme\",\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"maxSourceChars\",\n \"maxEdges\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"rendering.mermaid\",\n );\n }\n if (options.rendering.math !== undefined) {\n validateKnownPlainObject(\n options.rendering.math,\n [\n \"backgroundColor\",\n \"deviceScaleFactor\",\n \"fontSizePx\",\n \"paddingPx\",\n \"maxExpand\",\n \"maxSize\",\n \"maxSourceChars\",\n \"maxOutputBytes\",\n \"maxWidth\",\n \"maxHeight\",\n ],\n \"rendering.math\",\n );\n }\n }\n if (options.upload !== undefined) {\n validateKnownPlainObject(options.upload, [\"concurrency\", \"maxQueueSize\"], \"upload\");\n }\n resolveCapabilities(options.capabilities, options.capabilityOverrides);\n if (options.enableMath !== undefined && typeof options.enableMath !== \"boolean\") {\n throw new ConfigurationError(\"enableMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableInlineMath !== undefined && typeof options.enableInlineMath !== \"boolean\") {\n throw new ConfigurationError(\"enableInlineMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableFrontmatter !== undefined && typeof options.enableFrontmatter !== \"boolean\") {\n throw new ConfigurationError(\"enableFrontmatter must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (\n options.overflow !== undefined &&\n options.overflow !== \"degrade\" &&\n options.overflow !== \"split\"\n ) {\n throw new ConfigurationError('overflow must be \"degrade\" or \"split\"', {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (\n options.strategy !== undefined &&\n options.strategy !== \"rich-text-first\" &&\n options.strategy !== \"markdown-block\"\n ) {\n throw new ConfigurationError('strategy must be \"rich-text-first\" or \"markdown-block\"', {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n validateMentionResolvers(options.mentionResolvers);\n if (options.additionalRenderers !== undefined && !Array.isArray(options.additionalRenderers)) {\n throw new ConfigurationError(\"additionalRenderers must be an array\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n validateUploader(options.uploader);\n}\n\nfunction validateMentionResolvers(value: unknown): void {\n if (value === undefined) {\n return;\n }\n validateKnownPlainObject(value, [\"resolveUser\", \"resolveChannel\"], \"mentionResolvers\");\n try {\n const resolveUser = Reflect.get(value as object, \"resolveUser\");\n const resolveChannel = Reflect.get(value as object, \"resolveChannel\");\n if (\n (resolveUser !== undefined && typeof resolveUser !== \"function\") ||\n (resolveChannel !== undefined && typeof resolveChannel !== \"function\")\n ) {\n throw new TypeError(\"mention resolvers must be functions\");\n }\n } catch (cause) {\n throw new ConfigurationError(\"mentionResolvers is invalid\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction normalizeNodeConvertOptions(options: NodeConvertOptions): NodeConvertOptions {\n const normalized = snapshotNodeOptions(\n options,\n [...CORE_OPTION_KEYS, \"uploader\", \"signal\", \"timeoutMs\"],\n \"conversion options\",\n );\n validateUploader(normalized.uploader);\n return normalized;\n}\n\nfunction validateCloseOptions(options: NodeCloseOptions): void {\n validateKnownPlainObject(options, [\"behavior\", \"signal\", \"timeoutMs\"], \"close options\");\n if (\n options.behavior !== undefined &&\n options.behavior !== \"drain\" &&\n options.behavior !== \"cancel\"\n ) {\n throw new ConfigurationError('close.behavior must be \"drain\" or \"cancel\"', {\n code: \"invalid_close_behavior\",\n stage: \"configuration\",\n });\n }\n}\n\nfunction validateKnownPlainObject(\n value: unknown,\n allowed: ReadonlyArray<string>,\n label: string,\n): void {\n if (!isPlainObject(value)) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n const allowedKeys = new Set(allowed);\n for (const key of Object.keys(value as object)) {\n if (!allowedKeys.has(key)) {\n throw new ConfigurationError(`Unknown ${label} option: ${key}`, {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n }\n}\n\nfunction validateUploader(uploader: SlackUploader | undefined): void {\n if (uploader === undefined) {\n return;\n }\n try {\n if (\n (typeof uploader !== \"object\" && typeof uploader !== \"function\") ||\n uploader === null ||\n typeof Reflect.get(uploader, \"upload\") !== \"function\"\n ) {\n throw new TypeError(\"upload must be a function\");\n }\n } catch (cause) {\n throw new ConfigurationError(\"uploader is invalid\", {\n code: \"invalid_uploader\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction validateRendererIdentities(\n builtIns: ReadonlyArray<ImageRenderer>,\n additional: ReadonlyArray<ImageRenderer>,\n): void {\n const ids = new Set<string>();\n for (const renderer of [...builtIns, ...additional]) {\n let id: unknown;\n let output: unknown;\n let canRender: unknown;\n let render: unknown;\n try {\n id = Reflect.get(renderer as object, \"id\");\n output = Reflect.get(renderer as object, \"output\");\n canRender = Reflect.get(renderer as object, \"canRender\");\n render = Reflect.get(renderer as object, \"render\");\n } catch (cause) {\n throw new ConfigurationError(\"Renderer id could not be read\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n cause,\n });\n }\n if (\n typeof id !== \"string\" ||\n id.length === 0 ||\n (output !== \"url\" && output !== \"bytes\" && output !== \"both\") ||\n typeof canRender !== \"function\" ||\n typeof render !== \"function\"\n ) {\n throw new ConfigurationError(\"Renderer descriptor is invalid\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n if (ids.has(id)) {\n throw new ConfigurationError(`Duplicate renderer id: ${id}`, {\n code: \"duplicate_renderer_id\",\n stage: \"configuration\",\n });\n }\n ids.add(id);\n }\n}\n\nfunction collectReceiptSnapshot(\n collectors: ReadonlyArray<RecordingReceiptCollector>,\n): ReadonlyArray<UploadReceipt> {\n return Object.freeze(collectors.flatMap((collector) => collector.all()));\n}\n\nasync function collectSettledReceipts(\n collectors: ReadonlyArray<RecordingReceiptCollector>,\n): Promise<ReadonlyArray<UploadReceipt>> {\n try {\n const settled = await Promise.all(collectors.map((collector) => collector.settled()));\n return Object.freeze(settled.flat());\n } catch {\n return collectReceiptSnapshot(collectors);\n }\n}\n\nfunction normalizeConfigurationError(error: unknown): unknown {\n return isConfigurationError(error)\n ? error\n : new ConfigurationError(\"Node converter options could not be read\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n cause: error,\n });\n}\n"],"mappings":"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"}
|