import { readFileSync, writeFileSync } from 'node:fs'; import { join, resolve } from 'node:path'; import { pathToFileURL } from 'node:url'; // Executed independently in the page and the embedded PDF worker. export function installMapCompat() { 'use strict'; const { has, get, set } = Map.prototype; if (typeof Map.prototype.getOrInsertComputed !== 'function') { Object.defineProperty(Map.prototype, 'getOrInsertComputed', { configurable: true, writable: true, value: function getOrInsertComputed(key, callback) { const exists = has.call(this, key); if (typeof callback !== 'function') throw new TypeError('callback must be callable'); if (exists) return get.call(this, key); if (key === 0) key = 0; // Canonicalize -0 before invoking callback. const value = callback(key); set.call(this, key, value); return value; }, }); } if (typeof Map.prototype.getOrInsert !== 'function') { Object.defineProperty(Map.prototype, 'getOrInsert', { configurable: true, writable: true, value: function getOrInsert(key, value) { if (has.call(this, key)) return get.call(this, key); set.call(this, key, value); return value; }, }); } } const newline = String.fromCharCode(10); export const prelude = '/* dsh-mgr: webview-map-compat */' + newline + '(' + installMapCompat.toString() + ')();' + newline; export const workerPrefix = 'var _dsh_pdf_worker_default = '; export function patchPdfClient(source, version, pluginVersion) { if (version !== '0.2.1-rc.2' || pluginVersion !== version) { throw new Error('unsupported DSH/documentpreview version for WebView compatibility patch'); } if (source.includes('dsh-mgr: webview-map-compat')) throw new Error('WebView compatibility patch already applied'); const lines = source.split(newline); const targets = lines.filter(line => line.trimStart().startsWith(workerPrefix)); if (targets.length !== 1 || !source.includes('this.#methodPromises.getOrInsertComputed(')) { throw new Error('expected PDF.js method cache and exactly one embedded worker'); } const target = targets[0]; // Preserve the JS string literal verbatim (it can contain non-JSON escapes). const worker = target.trim().slice(workerPrefix.length, -1); if (!worker.includes('getOrInsertComputed') || !worker.includes('pdfjsVersion = 6.3.289')) { throw new Error('unexpected embedded PDF.js worker'); } // A page-level polyfill cannot cross into the worker realm. return prelude + source.replace(target, () => workerPrefix + JSON.stringify(prelude) + ' + ' + worker + ';'); } export function install(root = '/usr/local/lib/node_modules/@deepseek-ai/dsh') { const plugin = join(root, 'node_modules/@deepseek-ai/dsh-client-ui-sidebar-documentpreview'); const version = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version; const pluginVersion = JSON.parse(readFileSync(join(plugin, 'package.json'), 'utf8')).version; const file = join(plugin, 'lib/client.pdf.js'); writeFileSync(file, patchPdfClient(readFileSync(file, 'utf8'), version, pluginVersion)); } if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) install();