mirror of
https://github.com/duhanbalci/dreport.git
synced 2026-07-02 02:49:16 +00:00
140 lines
3.8 KiB
TypeScript
140 lines
3.8 KiB
TypeScript
import { ref, watch, type Ref } from 'vue'
|
||
import type { Template } from '../core/types'
|
||
import type { LayoutResult, LayoutMapEntry } from '../core/layout-types'
|
||
|
||
export type { LayoutMapEntry }
|
||
|
||
export function useLayoutEngine(
|
||
template: Ref<Template>,
|
||
data: Ref<Record<string, unknown>>,
|
||
layoutVersion?: Ref<number>,
|
||
) {
|
||
const layout = ref<LayoutResult | null>(null)
|
||
const error = ref<string | null>(null)
|
||
const computing = ref(false)
|
||
|
||
// Uyumluluk: InteractionOverlay'ın beklediği flat layout map (id → ElementLayout)
|
||
const layoutMap = ref<Record<string, LayoutMapEntry>>({})
|
||
|
||
let worker: Worker | null = null
|
||
let requestId = 0
|
||
|
||
function initWorker() {
|
||
worker = new Worker(new URL('../workers/layout.worker.ts', import.meta.url), {
|
||
type: 'module',
|
||
})
|
||
|
||
worker.onmessage = (e: MessageEvent<any>) => {
|
||
const msg = e.data
|
||
|
||
// Barcode yanıtları
|
||
if (msg.type === 'barcode-result' || msg.type === 'barcode-error') {
|
||
handleBarcodeResponse(msg)
|
||
return
|
||
}
|
||
|
||
if (msg.id !== requestId) return
|
||
|
||
computing.value = false
|
||
if (msg.type === 'result' && msg.layout) {
|
||
layout.value = msg.layout
|
||
error.value = null
|
||
|
||
// Flat map oluştur: id → LayoutMapEntry (pageIndex dahil)
|
||
const map: Record<string, LayoutMapEntry> = {}
|
||
for (const page of msg.layout.pages) {
|
||
for (const el of page.elements) {
|
||
if (!map[el.id]) {
|
||
map[el.id] = { ...el, pageIndex: page.page_index }
|
||
}
|
||
}
|
||
}
|
||
layoutMap.value = map
|
||
} else if (msg.type === 'error') {
|
||
error.value = msg.error ?? 'Bilinmeyen layout hatası'
|
||
}
|
||
}
|
||
|
||
worker.onerror = () => {
|
||
computing.value = false
|
||
error.value = 'Worker hatası — yeniden başlatılıyor'
|
||
worker?.terminate()
|
||
worker = null
|
||
setTimeout(initWorker, 500)
|
||
}
|
||
}
|
||
|
||
function compute() {
|
||
if (!worker) initWorker()
|
||
requestId++
|
||
computing.value = true
|
||
worker!.postMessage({
|
||
type: 'compile',
|
||
templateJson: JSON.stringify(template.value),
|
||
dataJson: JSON.stringify(data.value),
|
||
id: requestId,
|
||
})
|
||
}
|
||
|
||
// template veya data değiştiğinde yeniden hesapla.
|
||
// layoutVersion verilmişse sadece onu izle (cheap integer comparison).
|
||
// Verilmemişse eski davranış: deep watch (geriye uyumluluk).
|
||
if (layoutVersion) {
|
||
watch(
|
||
layoutVersion,
|
||
() => {
|
||
compute()
|
||
},
|
||
{ immediate: true },
|
||
)
|
||
} else {
|
||
watch(
|
||
[template, data],
|
||
() => {
|
||
compute()
|
||
},
|
||
{ immediate: true, deep: true },
|
||
)
|
||
}
|
||
|
||
// --- Barcode üretimi (WASM üzerinden) ---
|
||
let barcodeReqId = 0
|
||
const barcodeCallbacks = new Map<number, (result: { width: number; height: number; rgba: ArrayBuffer } | null) => void>()
|
||
|
||
function generateBarcode(format: string, value: string, width: number, height: number, includeText: boolean = false): Promise<{ width: number; height: number; rgba: ArrayBuffer } | null> {
|
||
if (!worker) initWorker()
|
||
return new Promise(resolve => {
|
||
barcodeReqId++
|
||
const id = barcodeReqId + 100000 // compile id'leriyle çakışmasın
|
||
barcodeCallbacks.set(id, resolve)
|
||
worker!.postMessage({ type: 'barcode', format, value, width, height, includeText, id })
|
||
})
|
||
}
|
||
|
||
function handleBarcodeResponse(msg: any) {
|
||
if (msg.type === 'barcode-result' || msg.type === 'barcode-error') {
|
||
const cb = barcodeCallbacks.get(msg.id)
|
||
if (cb) {
|
||
barcodeCallbacks.delete(msg.id)
|
||
cb(msg.type === 'barcode-result' ? { width: msg.width, height: msg.height, rgba: msg.rgba } : null)
|
||
}
|
||
}
|
||
}
|
||
|
||
function dispose() {
|
||
worker?.terminate()
|
||
worker = null
|
||
barcodeCallbacks.clear()
|
||
}
|
||
|
||
return {
|
||
layout,
|
||
layoutMap,
|
||
error,
|
||
computing,
|
||
compute,
|
||
generateBarcode,
|
||
dispose,
|
||
}
|
||
}
|