diff --git a/packages/lib/server-only/konva/skia-backend.ts b/packages/lib/server-only/konva/skia-backend.ts new file mode 100644 index 000000000..bdcd4ec64 --- /dev/null +++ b/packages/lib/server-only/konva/skia-backend.ts @@ -0,0 +1,42 @@ +/** + * !: This is a workaround to fix the memory leak in the skia-canvas library. + * !: Internals are ported from the original `konva/skia-backend.js` file. + */ +import { Konva } from 'konva/lib/_CoreInternals'; +import { Canvas, DOMMatrix, Image, Path2D } from 'skia-canvas'; + +// @ts-expect-error skia-canvas satisfies the requirements +global.DOMMatrix = DOMMatrix; + +// @ts-expect-error skia-canvas satisfies the requirements +global.Path2D = Path2D; +Path2D.prototype.toString = () => '[object Path2D]'; + +Konva.Util['createCanvasElement'] = () => { + const node = new Canvas(300, 300); + node.gpu = false; + + if (!('style' in node) || !node['style']) { + Object.assign(node, { style: {} }); + } + + node.toString = () => '[object HTMLCanvasElement]'; + const ctx = node.getContext('2d'); + + Object.defineProperty(ctx, 'canvas', { + get: () => node, + }); + + return node as unknown as HTMLCanvasElement; +}; + +Konva.Util.createImageElement = () => { + const node = new Image(); + node.toString = () => '[object HTMLImageElement]'; + + return node as unknown as HTMLImageElement; +}; + +Konva._renderBackend = 'skia-canvas'; + +export default Konva; diff --git a/packages/lib/server-only/pdf/insert-field-in-pdf-v2.ts b/packages/lib/server-only/pdf/insert-field-in-pdf-v2.ts index 26174911c..8de70e868 100644 --- a/packages/lib/server-only/pdf/insert-field-in-pdf-v2.ts +++ b/packages/lib/server-only/pdf/insert-field-in-pdf-v2.ts @@ -1,5 +1,5 @@ // sort-imports-ignore -import 'konva/skia-backend'; +import '../konva/skia-backend'; import Konva from 'konva'; import path from 'node:path'; @@ -23,6 +23,7 @@ export const insertFieldInPDFV2 = async ({ }: InsertFieldInPDFV2Options) => { const fontPath = path.join(process.cwd(), 'public/fonts'); + // eslint-disable-next-line react-hooks/rules-of-hooks FontLibrary.use({ ['Caveat']: [path.join(fontPath, 'caveat.ttf')], ['Noto Sans']: [path.join(fontPath, 'noto-sans.ttf')],