File size: 2,410 Bytes
1b756c8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { WasmProvider } from './wasm-provider.js';

let cachedGS: any = null;
let loadPromise: Promise<any> | null = null;

export interface GhostscriptInterface {
  convertToPDFA(pdfBuffer: ArrayBuffer, profile: string): Promise<ArrayBuffer>;
  fontToOutline(pdfBuffer: ArrayBuffer): Promise<ArrayBuffer>;
}

export async function loadGhostscript(): Promise<GhostscriptInterface> {
  if (cachedGS) {
    return cachedGS;
  }

  if (loadPromise) {
    return loadPromise;
  }

  loadPromise = (async () => {
    const baseUrl = WasmProvider.getUrl('ghostscript');
    if (!baseUrl) {
      throw new Error(
        'Ghostscript is not configured. Please configure it in Advanced Settings.'
      );
    }

    const normalizedUrl = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;

    try {
      const wrapperUrl = `${normalizedUrl}gs.js`;

      await loadScript(wrapperUrl);

      const globalScope =
        typeof globalThis !== 'undefined' ? globalThis : window;

      if (typeof (globalScope as any).loadGS === 'function') {
        cachedGS = await (globalScope as any).loadGS({
          baseUrl: normalizedUrl,
        });
      } else if (typeof (globalScope as any).GhostscriptWASM === 'function') {
        cachedGS = new (globalScope as any).GhostscriptWASM(normalizedUrl);
        await cachedGS.init?.();
      } else {
        throw new Error(
          'Ghostscript wrapper did not expose expected interface. Expected loadGS() or GhostscriptWASM class.'
        );
      }

      return cachedGS;
    } catch (error: any) {
      loadPromise = null;
      throw new Error(
        `Failed to load Ghostscript from ${normalizedUrl}: ${error.message}`
      );
    }
  })();

  return loadPromise;
}

function loadScript(url: string): Promise<void> {
  return new Promise((resolve, reject) => {
    if (document.querySelector(`script[src="${url}"]`)) {
      resolve();
      return;
    }

    const script = document.createElement('script');
    script.src = url;
    script.type = 'text/javascript';
    script.async = true;

    script.onload = () => resolve();
    script.onerror = () => reject(new Error(`Failed to load script: ${url}`));

    document.head.appendChild(script);
  });
}

export function isGhostscriptAvailable(): boolean {
  return WasmProvider.isConfigured('ghostscript');
}

export function clearGhostscriptCache(): void {
  cachedGS = null;
  loadPromise = null;
}