@cristianmpx/react-import-sheet-headless 1.0.0
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/LICENSE.md +21 -0
- package/README.md +148 -0
- package/dist/chunk-3O6T2NOG.js +2 -0
- package/dist/chunk-3O6T2NOG.js.map +1 -0
- package/dist/chunk-77DDFTT3.js +2 -0
- package/dist/chunk-77DDFTT3.js.map +1 -0
- package/dist/chunk-BCDDC5UG.js +2 -0
- package/dist/chunk-BCDDC5UG.js.map +1 -0
- package/dist/chunk-J2IHY56K.js +2 -0
- package/dist/chunk-J2IHY56K.js.map +1 -0
- package/dist/chunk-UCBBDF6X.js +2 -0
- package/dist/chunk-UCBBDF6X.js.map +1 -0
- package/dist/chunk-WLNB3X2R.js +2 -0
- package/dist/chunk-WLNB3X2R.js.map +1 -0
- package/dist/chunk-XTSACACJ.js +2 -0
- package/dist/chunk-XTSACACJ.js.map +1 -0
- package/dist/chunk-YETPLYYC.js +2 -0
- package/dist/chunk-YETPLYYC.js.map +1 -0
- package/dist/csv-parser-3IGEDABE.js +2 -0
- package/dist/csv-parser-3IGEDABE.js.map +1 -0
- package/dist/csv-parser-ML7A4LF4.js +2 -0
- package/dist/csv-parser-ML7A4LF4.js.map +1 -0
- package/dist/edit.worker.d.ts +5 -0
- package/dist/edit.worker.js +2 -0
- package/dist/edit.worker.js.map +1 -0
- package/dist/index.d.ts +403 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.worker.d.ts +2 -0
- package/dist/parser.worker.js +2 -0
- package/dist/parser.worker.js.map +1 -0
- package/dist/sanitizer.worker.d.ts +2 -0
- package/dist/sanitizer.worker.js +2 -0
- package/dist/sanitizer.worker.js.map +1 -0
- package/dist/transform.worker.d.ts +5 -0
- package/dist/transform.worker.js +2 -0
- package/dist/transform.worker.js.map +1 -0
- package/dist/validator.worker.d.ts +5 -0
- package/dist/validator.worker.js +2 -0
- package/dist/validator.worker.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/ImporterProvider.tsx","../src/core/view/types/persisted-state.ts","../src/providers/ImporterContext.ts","../src/providers/state.ts","../src/providers/useImporterActions.ts","../src/types/metrics.ts","../src/types/change-log.ts","../src/types/importer-state.ts","../src/providers/useImporterStateSetters.ts","../src/providers/usePersistSession.ts","../src/core/view/persist/indexed-db.ts","../src/providers/useImporterContext.ts","../src/hooks/useImporter.ts","../src/core/view/get-rows-with-errors.ts","../src/core/view/get-view-counts.ts","../src/core/view/export/sheet-to-objects.ts","../src/hooks/useImportSheet.ts","../src/core/parser/hooks/useParserWorker.ts","../src/core/parser/worker/worker-url.ts","../src/core/convert/hooks/useConvert.ts","../src/core/convert/build-converted-sheet.ts","../src/core/parser/utils/fuzzy-match.ts","../src/core/convert/match-headers.ts","../src/core/convert/run-convert.ts","../src/hooks/useImporterStatus.ts","../src/hooks/useSheetData.ts","../src/hooks/useSheetEditor.ts","../src/core/editor/hooks/useEditWorker.ts","../src/core/editor/worker/worker-url.ts","../src/core/editor/get-paginated-result.ts","../src/core/view/hooks/useSheetView.ts","../src/core/view/export/sheet-to-csv.ts","../src/core/view/export/sheet-to-json.ts","../src/hooks/useImporterEventTarget.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport { Registry } from '../shared/registry/index.js';\nimport type { ParserEngine, SheetLayout } from '../types/index.js';\nimport { DEFAULT_PERSIST_KEY } from '../core/view/types/persisted-state.js';\nimport { ImporterContext } from './ImporterContext.js';\nimport { initialState } from './state.js';\nimport type { ImporterContextValue, ImporterProviderProps } from './types.js';\nimport { useImporterActions } from './useImporterActions.js';\nimport { useImporterStateSetters } from './useImporterStateSetters.js';\nimport { usePersistSession } from './usePersistSession.js';\n\nexport function ImporterProvider({\n children,\n layout: layoutProp,\n engine: engineProp,\n persist = false,\n persistKey = DEFAULT_PERSIST_KEY,\n onSubmit = null,\n submitKeyMap = null,\n}: ImporterProviderProps) {\n const [state, setState] = useState(initialState);\n const [layout, setLayoutState] = useState<SheetLayout | null>(layoutProp ?? null);\n const [engine, setEngineState] = useState<ParserEngine | null>(engineProp ?? null);\n const progressEventTarget = useMemo(() => new EventTarget(), []);\n const validatorRegistry = useMemo(() => new Registry<(...args: unknown[]) => unknown>(), []);\n const sanitizerRegistry = useMemo(() => new Registry<(...args: unknown[]) => unknown>(), []);\n const transformRegistry = useMemo(() => new Registry<(...args: unknown[]) => unknown>(), []);\n const activeWorkerRef = useRef<Worker | null>(null);\n const phaseTimingsRef = useRef({\n parse: 0,\n sanitize: 0,\n validate: 0,\n transform: 0,\n });\n\n const stateSetters = useImporterStateSetters({ setState, setLayoutState, setEngineState });\n const persistSession = usePersistSession(\n persist,\n persistKey,\n state.rawData,\n state.result,\n stateSetters.setRawData,\n stateSetters.setResult,\n layout?.version ?? null\n );\n\n const actions = useImporterActions({\n setState,\n setLayoutState,\n setEngineState,\n progressEventTarget,\n validatorRegistry,\n sanitizerRegistry,\n transformRegistry,\n activeWorkerRef,\n phaseTimingsRef,\n });\n\n useEffect(() => {\n return () => {\n const worker = activeWorkerRef.current;\n if (worker) {\n worker.terminate();\n activeWorkerRef.current = null;\n }\n };\n }, []);\n\n const value = useMemo<ImporterContextValue>(\n () => ({\n ...state,\n layout,\n engine,\n progressEventTarget,\n ...actions,\n onSubmit: onSubmit ?? null,\n submitKeyMap: submitKeyMap ?? null,\n persist,\n persistKey,\n hasRecoverableSession: persistSession.hasRecoverableSession,\n recoverSession: persistSession.recoverSession,\n clearPersistedState: persistSession.clearPersistedState,\n }),\n [\n state,\n layout,\n engine,\n progressEventTarget,\n onSubmit,\n submitKeyMap,\n actions,\n persist,\n persistKey,\n persistSession.hasRecoverableSession,\n persistSession.recoverSession,\n persistSession.clearPersistedState,\n ]\n );\n\n return <ImporterContext.Provider value={value}>{children}</ImporterContext.Provider>;\n}\n","import type { RawSheet } from '../../../types/raw-sheet.js';\nimport type { Sheet } from '../../../types/sheet.js';\n\nexport const PERSIST_SESSION_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport const PERSIST_STORE_NAME = 'react-import-sheet-persist';\n\nexport const DEFAULT_PERSIST_KEY = 'react-import-sheet-session';\n\nexport const STATE_SCHEMA_VERSION = 1;\n\nexport interface PersistedState {\n readonly rawData: RawSheet;\n readonly sheet: Sheet;\n readonly savedAt: number;\n readonly fileName?: string;\n readonly persistKey?: string;\n readonly layoutVersion?: string | number;\n readonly stateSchemaVersion?: number;\n}\n","import { createContext } from 'react';\r\nimport type { ImporterContextValue } from './types.js';\r\n\r\nexport const ImporterContext = createContext<ImporterContextValue | null>(null);\r\n","import type { ImporterState } from '../types/index.js';\n\nexport const initialState: ImporterState = {\n file: null,\n rawData: null,\n documentHash: null,\n status: 'idle',\n result: null,\n convertedSheet: null,\n sanitizedSheet: null,\n convertResultData: null,\n metrics: null,\n changeLog: [],\n submitDone: false,\n};\n","import { useCallback, useMemo } from 'react';\nimport type { RegistryLevel } from '../shared/registry/index.js';\nimport type { ChangeLogEntry } from '../types/change-log.js';\nimport {\n buildPipelineMetrics,\n IMPORTER_ABORTED_EVENT,\n IMPORTER_PROGRESS_EVENT,\n type ImporterProgressDetail,\n type PipelinePhase,\n} from '../types/index.js';\nimport type { ImporterContextValue, UseImporterActionsDeps } from './types.js';\nimport { useImporterStateSetters } from './useImporterStateSetters.js';\n\nconst INITIAL_PHASE_TIMINGS = {\n parse: 0,\n sanitize: 0,\n validate: 0,\n transform: 0,\n};\n\nexport function useImporterActions(\n deps: UseImporterActionsDeps\n): Omit<\n ImporterContextValue,\n | 'file'\n | 'rawData'\n | 'documentHash'\n | 'status'\n | 'result'\n | 'layout'\n | 'engine'\n | 'progressEventTarget'\n | 'onSubmit'\n | 'submitKeyMap'\n | 'persist'\n | 'persistKey'\n | 'hasRecoverableSession'\n | 'recoverSession'\n | 'clearPersistedState'\n> {\n const {\n setState,\n setLayoutState,\n setEngineState,\n progressEventTarget,\n validatorRegistry,\n sanitizerRegistry,\n transformRegistry,\n activeWorkerRef,\n phaseTimingsRef,\n } = deps;\n\n const stateSetters = useImporterStateSetters({ setState, setLayoutState, setEngineState });\n\n const dispatchProgress = useCallback(\n (detail: ImporterProgressDetail) => {\n progressEventTarget.dispatchEvent(new CustomEvent(IMPORTER_PROGRESS_EVENT, { detail }));\n },\n [progressEventTarget]\n );\n\n const setActiveWorker = useCallback(\n (worker: Worker | null) => {\n activeWorkerRef.current = worker;\n },\n [activeWorkerRef]\n );\n\n const abort = useCallback(() => {\n const worker = activeWorkerRef.current;\n if (worker) {\n worker.terminate();\n activeWorkerRef.current = null;\n }\n setState((prev) => ({ ...prev, status: 'cancelled' }));\n progressEventTarget.dispatchEvent(new CustomEvent(IMPORTER_ABORTED_EVENT));\n }, [activeWorkerRef, progressEventTarget, setState]);\n\n const setPhaseTiming = useCallback(\n (phase: PipelinePhase, ms: number) => {\n phaseTimingsRef.current = { ...phaseTimingsRef.current, [phase]: ms };\n },\n [phaseTimingsRef]\n );\n\n const finalizeMetrics = useCallback(\n (rowCount: number) => {\n const timings = { ...phaseTimingsRef.current };\n const metrics = buildPipelineMetrics(timings, rowCount);\n stateSetters.setMetrics(metrics);\n },\n [phaseTimingsRef, stateSetters]\n );\n\n const addChangeLogEntry = useCallback(\n (entry: ChangeLogEntry) => {\n setState((prev) => ({\n ...prev,\n changeLog: [...prev.changeLog, entry],\n }));\n },\n [setState]\n );\n\n const processFile = useCallback(\n (file: File) => {\n phaseTimingsRef.current = { ...INITIAL_PHASE_TIMINGS };\n setState((prev) => ({\n ...prev,\n file,\n status: 'loading',\n rawData: null,\n documentHash: null,\n result: null,\n convertedSheet: null,\n sanitizedSheet: null,\n convertResultData: null,\n metrics: null,\n changeLog: [],\n submitDone: false,\n }));\n },\n [phaseTimingsRef, setState]\n );\n\n const registerValidator = useCallback(\n (name: string, fn: (...args: unknown[]) => unknown, options: { type: RegistryLevel }) => {\n validatorRegistry.register(name, fn, options);\n },\n [validatorRegistry]\n );\n\n const registerSanitizer = useCallback(\n (name: string, fn: (...args: unknown[]) => unknown, options: { type: RegistryLevel }) => {\n sanitizerRegistry.register(name, fn, options);\n },\n [sanitizerRegistry]\n );\n\n const registerTransform = useCallback(\n (name: string, fn: (...args: unknown[]) => unknown, options: { type: RegistryLevel }) => {\n transformRegistry.register(name, fn, options);\n },\n [transformRegistry]\n );\n\n return useMemo(\n () => ({\n ...stateSetters,\n addChangeLogEntry,\n setPhaseTiming,\n finalizeMetrics,\n processFile,\n registerValidator,\n registerSanitizer,\n registerTransform,\n abort,\n dispatchProgress,\n setActiveWorker,\n }),\n [\n stateSetters,\n addChangeLogEntry,\n setPhaseTiming,\n finalizeMetrics,\n processFile,\n registerValidator,\n registerSanitizer,\n registerTransform,\n abort,\n dispatchProgress,\n setActiveWorker,\n ]\n );\n}\n","export interface PipelineMetricsTimings {\n readonly parse: number;\n readonly sanitize: number;\n readonly validate: number;\n readonly transform: number;\n}\n\nexport interface PipelineMetricsPercentages {\n readonly parse: number;\n readonly sanitize: number;\n readonly validate: number;\n readonly transform: number;\n readonly overhead?: number;\n}\n\nexport interface PipelineMetrics {\n readonly timings: PipelineMetricsTimings;\n readonly percentages?: PipelineMetricsPercentages;\n readonly totalMs: number;\n readonly isSlow: boolean;\n readonly parseTime: string;\n readonly sanitizeTime: string;\n readonly validateTime: string;\n readonly transformTime: string;\n readonly totalTime: string;\n readonly efficiency: string;\n readonly rowCount: number;\n readonly overheadMs?: number;\n}\n\nexport const SLOW_THRESHOLD_MS = 2000;\n\nfunction formatMs(ms: number): string {\n if (ms < 0.01 && ms >= 0) return '0.00ms';\n if (ms < 1) return `${(ms * 1000).toFixed(2)}μs`;\n return `${ms.toFixed(2)}ms`;\n}\n\nexport function buildPipelineMetrics(\n timings: PipelineMetricsTimings,\n rowCount: number,\n overheadMs?: number,\n): PipelineMetrics {\n const totalMs =\n timings.parse + timings.sanitize + timings.validate + timings.transform;\n const isSlow = totalMs > SLOW_THRESHOLD_MS;\n const efficiencyMsPerRow = rowCount > 0 ? totalMs / rowCount : 0;\n const efficiency = `${efficiencyMsPerRow.toFixed(4)}ms/row`;\n\n let percentages: PipelineMetricsPercentages | undefined;\n if (totalMs > 0) {\n const overhead = overheadMs ?? 0;\n const totalWithOverhead = totalMs + overhead;\n percentages = {\n parse: (timings.parse / totalWithOverhead) * 100,\n sanitize: (timings.sanitize / totalWithOverhead) * 100,\n validate: (timings.validate / totalWithOverhead) * 100,\n transform: (timings.transform / totalWithOverhead) * 100,\n overhead: totalWithOverhead > 0 ? (overhead / totalWithOverhead) * 100 : 0,\n };\n }\n\n return {\n timings: { ...timings },\n percentages,\n totalMs,\n isSlow,\n parseTime: formatMs(timings.parse),\n sanitizeTime: formatMs(timings.sanitize),\n validateTime: formatMs(timings.validate),\n transformTime: formatMs(timings.transform),\n totalTime: formatMs(totalMs),\n efficiency,\n rowCount,\n ...(overheadMs !== undefined && overheadMs >= 0 ? { overheadMs } : {}),\n };\n}\n","export interface ChangeLogEntryCellEdit {\n readonly type: 'cell_edit';\n readonly rowIndex: number;\n readonly cellKey: string;\n readonly value: unknown;\n readonly previousValue?: unknown;\n readonly timestamp: number;\n}\n\nexport interface ChangeLogEntryRowRemove {\n readonly type: 'row_remove';\n readonly rowIndex: number;\n readonly timestamp: number;\n}\n\nexport type ChangeLogEntry = ChangeLogEntryCellEdit | ChangeLogEntryRowRemove;\n\nexport function formatChangeLogAsText(entries: readonly ChangeLogEntry[]): string {\n const lines: string[] = [];\n for (const e of entries) {\n if (e.type === 'cell_edit') {\n const prev = e.previousValue !== undefined ? ` (previous: ${String(e.previousValue)})` : '';\n lines.push(\n `Row ${e.rowIndex + 1}, cell \"${e.cellKey}\": set to ${JSON.stringify(e.value)}${prev}`\n );\n } else {\n lines.push(`Row ${e.rowIndex + 1}: removed`);\n }\n }\n return lines.join('\\n');\n}\n","import type { ConvertedSheet } from '../core/convert/types/converted-sheet.js';\nimport type { SanitizedSheet } from '../core/sanitizer/types/sanitized-sheet.js';\nimport type { ChangeLogEntry } from './change-log.js';\nimport type { PipelineMetrics } from './metrics.js';\nimport type { RawSheet } from './raw-sheet.js';\nimport type { Sheet } from './sheet.js';\n\nexport type ImporterStatus =\n | 'idle'\n | 'loading'\n | 'parsing'\n | 'validating'\n | 'transforming'\n | 'success'\n | 'error'\n | 'cancelled';\n\nexport interface ConvertResultData {\n readonly headersFound: readonly string[];\n readonly mismatches: readonly { expected: string; found: string | null; message?: string }[];\n readonly columnOrder: readonly string[];\n readonly headerToFieldMap: Readonly<Record<string, string>>;\n}\n\nexport type PipelinePhase = 'parse' | 'sanitize' | 'validate' | 'transform';\n\nexport interface ImporterState {\n readonly file: File | null;\n readonly rawData: RawSheet | null;\n readonly documentHash: string | null;\n readonly status: ImporterStatus;\n readonly result: Sheet | null;\n readonly convertedSheet: ConvertedSheet | null;\n readonly sanitizedSheet: SanitizedSheet | null;\n readonly convertResultData: ConvertResultData | null;\n readonly metrics: PipelineMetrics | null;\n readonly changeLog: readonly ChangeLogEntry[];\n readonly submitDone: boolean;\n}\n\nexport const IMPORTER_PROGRESS_EVENT = 'importer-progress';\nexport const IMPORTER_ABORTED_EVENT = 'importer-aborted';\n\nexport interface ImporterProgressDetail {\n readonly phase?: string;\n readonly globalPercent?: number;\n readonly localPercent?: number;\n readonly currentRow?: number;\n readonly totalRows?: number;\n readonly rowsProcessed?: number;\n}\n","import { useCallback } from 'react';\nimport type { ImporterState, ImporterStatus } from '../types/index.js';\nimport type { PipelineMetrics } from '../types/index.js';\nimport type { ParserEngine, SheetLayout } from '../types/index.js';\nimport type { ImporterContextValue, UseImporterStateSettersDeps } from './types.js';\n\nexport function useImporterStateSetters(\n deps: UseImporterStateSettersDeps\n): Pick<\n ImporterContextValue,\n | 'setLayout'\n | 'setEngine'\n | 'setFile'\n | 'setRawData'\n | 'setDocumentHash'\n | 'setStatus'\n | 'setResult'\n | 'setConvertedSheet'\n | 'setSanitizedSheet'\n | 'setConvertResultData'\n | 'setMetrics'\n | 'setSubmitDone'\n> {\n const { setState, setLayoutState, setEngineState } = deps;\n\n const setFile = useCallback(\n (file: File | null) => {\n setState((prev) => ({ ...prev, file }));\n },\n [setState]\n );\n\n const setRawData = useCallback(\n (rawData: ImporterState['rawData']) => {\n setState((prev) => ({ ...prev, rawData }));\n },\n [setState]\n );\n\n const setDocumentHash = useCallback(\n (documentHash: string | null) => {\n setState((prev) => ({ ...prev, documentHash }));\n },\n [setState]\n );\n\n const setStatus = useCallback(\n (status: ImporterStatus) => {\n setState((prev) => ({ ...prev, status }));\n },\n [setState]\n );\n\n const setResult = useCallback(\n (result: ImporterState['result']) => {\n setState((prev) => ({ ...prev, result }));\n },\n [setState]\n );\n\n const setConvertedSheet = useCallback(\n (convertedSheet: ImporterState['convertedSheet']) => {\n setState((prev) => ({ ...prev, convertedSheet, convertResultData: null }));\n },\n [setState]\n );\n\n const setSanitizedSheet = useCallback(\n (sanitizedSheet: ImporterState['sanitizedSheet']) => {\n setState((prev) => ({ ...prev, sanitizedSheet }));\n },\n [setState]\n );\n\n const setConvertResultData = useCallback(\n (\n dataOrUpdater:\n | ImporterState['convertResultData']\n | ((prev: ImporterState['convertResultData']) => ImporterState['convertResultData'])\n ) => {\n setState((prev) => ({\n ...prev,\n convertResultData:\n typeof dataOrUpdater === 'function'\n ? dataOrUpdater(prev.convertResultData)\n : dataOrUpdater,\n convertedSheet: typeof dataOrUpdater === 'function' ? prev.convertedSheet : null,\n }));\n },\n [setState]\n );\n\n const setMetrics = useCallback(\n (metrics: PipelineMetrics | null) => {\n setState((prev) => ({ ...prev, metrics }));\n },\n [setState]\n );\n\n const setSubmitDone = useCallback(\n (submitDone: boolean) => {\n setState((prev) => ({ ...prev, submitDone }));\n },\n [setState]\n );\n\n const setLayout = useCallback(\n (next: SheetLayout | null) => {\n setLayoutState(next);\n },\n [setLayoutState]\n );\n\n const setEngine = useCallback(\n (next: ParserEngine | null) => {\n setEngineState(next);\n },\n [setEngineState]\n );\n\n return {\n setLayout,\n setEngine,\n setFile,\n setRawData,\n setDocumentHash,\n setStatus,\n setResult,\n setConvertedSheet,\n setSanitizedSheet,\n setConvertResultData,\n setMetrics,\n setSubmitDone,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { RawSheet } from '../types/raw-sheet.js';\nimport type { Sheet } from '../types/sheet.js';\nimport {\n savePersistedState,\n loadPersistedState,\n clearPersistedState as clearPersistedStateStorage,\n} from '../core/view/persist/indexed-db.js';\nimport {\n STATE_SCHEMA_VERSION,\n type PersistedState as PersistedStateType,\n} from '../core/view/types/persisted-state.js';\n\nconst DEBOUNCE_MS = 2500;\n\nexport function usePersistSession(\n persist: boolean,\n persistKey: string,\n rawData: RawSheet | null,\n result: Sheet | null,\n setRawData: (v: RawSheet | null) => void,\n setResult: (v: Sheet | null) => void,\n layoutVersion: string | number | null,\n) {\n const [recoverableSession, setRecoverableSession] = useState<PersistedStateType | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!persist) return;\n loadPersistedState(persistKey).then((state) => {\n if (!state) return;\n if (\n state.layoutVersion != null &&\n layoutVersion != null &&\n String(state.layoutVersion) !== String(layoutVersion)\n ) {\n return;\n }\n setRecoverableSession(state);\n });\n }, [persist, persistKey, layoutVersion]);\n\n useEffect(() => {\n if (!persist || !rawData || !result) return;\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n debounceRef.current = null;\n const payload: PersistedStateType = {\n rawData,\n sheet: result,\n savedAt: Date.now(),\n layoutVersion: layoutVersion ?? undefined,\n stateSchemaVersion: STATE_SCHEMA_VERSION,\n };\n savePersistedState(persistKey, payload).catch(() => {});\n }, DEBOUNCE_MS);\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [persist, persistKey, rawData, result, layoutVersion]);\n\n const recoverSession = useCallback(async () => {\n if (!persist) return;\n const state = recoverableSession;\n if (!state) return;\n setRawData(state.rawData);\n setResult(state.sheet);\n setRecoverableSession(null);\n }, [persist, recoverableSession, setRawData, setResult]);\n\n const clearPersistedState = useCallback(async () => {\n if (!persist) return;\n await clearPersistedStateStorage(persistKey);\n setRecoverableSession(null);\n }, [persist, persistKey]);\n\n return {\n hasRecoverableSession: persist && recoverableSession != null,\n recoverSession,\n clearPersistedState,\n };\n}\n","import type { PersistedState } from '../types/persisted-state.js';\nimport {\n PERSIST_STORE_NAME,\n PERSIST_SESSION_MAX_AGE_MS,\n} from '../types/persisted-state.js';\n\nfunction openDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open('react-import-sheet-db', 1);\n req.onerror = () => reject(req.error);\n req.onsuccess = () => resolve(req.result);\n req.onupgradeneeded = () => {\n req.result.createObjectStore(PERSIST_STORE_NAME, { keyPath: 'key' });\n };\n });\n}\n\nexport async function savePersistedState(\n key: string,\n state: PersistedState,\n): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(PERSIST_STORE_NAME, 'readwrite');\n const store = tx.objectStore(PERSIST_STORE_NAME);\n const record = { key, ...state };\n const req = store.put(record);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n tx.oncomplete = () => db.close();\n });\n}\n\nexport async function loadPersistedState(\n key: string,\n): Promise<PersistedState | null> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(PERSIST_STORE_NAME, 'readonly');\n const store = tx.objectStore(PERSIST_STORE_NAME);\n const req = store.get(key);\n req.onsuccess = () => {\n db.close();\n const row = req.result as (PersistedState & { key: string }) | undefined;\n if (row == null) {\n resolve(null);\n return;\n }\n const savedAt = row.savedAt;\n if (Date.now() - savedAt > PERSIST_SESSION_MAX_AGE_MS) {\n resolve(null);\n return;\n }\n const { key: _k, ...state } = row;\n resolve(state as PersistedState);\n };\n req.onerror = () => reject(req.error);\n });\n}\n\nexport async function clearPersistedState(key: string): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(PERSIST_STORE_NAME, 'readwrite');\n const store = tx.objectStore(PERSIST_STORE_NAME);\n const req = store.delete(key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n tx.oncomplete = () => db.close();\n });\n}\n","import { useContext } from 'react';\r\nimport { ImporterContext } from './ImporterContext.js';\r\nimport type { ImporterContextValue } from './types.js';\r\n\r\nexport function useImporterContext(): ImporterContextValue {\r\n const context = useContext(ImporterContext);\r\n if (context === null) {\r\n throw new Error('useImporter must be used within an ImporterProvider');\r\n }\r\n return context;\r\n}\r\n","import { useCallback, useEffect, useMemo } from 'react';\nimport { useImporterContext } from '../providers/index.js';\nimport { hasValidationErrors } from '../core/view/get-view-counts.js';\nimport { sheetToObjectsWithKeyMap } from '../core/view/export/sheet-to-objects.js';\nimport type { Sheet } from '../types/sheet.js';\nimport type { UseImporterOptions } from './types.js';\n\nfunction rowsToLayoutObjects(sheet: Sheet): Record<string, unknown>[] {\n return sheet.rows.map((row) =>\n row.cells.reduce((acc, c) => ({ ...acc, [c.key]: c.value }), {} as Record<string, unknown>)\n );\n}\n\nexport function useImporter(options: UseImporterOptions = {}) {\n const ctx = useImporterContext();\n const { layout: layoutOption, engine: engineOption } = options;\n\n useEffect(() => {\n if (layoutOption !== undefined) {\n ctx.setLayout(layoutOption);\n }\n }, [ctx, layoutOption]);\n\n useEffect(() => {\n if (engineOption !== undefined) {\n ctx.setEngine(engineOption);\n }\n }, [ctx, engineOption]);\n\n const canSubmit = useMemo(\n () =>\n Boolean(\n ctx.result &&\n ctx.status === 'success' &&\n !ctx.submitDone &&\n !hasValidationErrors(ctx.result)\n ),\n [ctx.result, ctx.status, ctx.submitDone]\n );\n\n const submit = useCallback(() => {\n if (!ctx.result || ctx.submitDone || hasValidationErrors(ctx.result) || !ctx.onSubmit) return;\n const data = ctx.submitKeyMap\n ? sheetToObjectsWithKeyMap(ctx.result, ctx.submitKeyMap)\n : rowsToLayoutObjects(ctx.result);\n ctx.onSubmit(data);\n ctx.setSubmitDone(true);\n }, [ctx]);\n\n return useMemo(\n () => ({\n processFile: ctx.processFile,\n registerValidator: ctx.registerValidator,\n registerSanitizer: ctx.registerSanitizer,\n registerTransform: ctx.registerTransform,\n abort: ctx.abort,\n metrics: ctx.metrics,\n submit,\n canSubmit,\n submitDone: ctx.submitDone,\n }),\n [\n ctx.processFile,\n ctx.registerValidator,\n ctx.registerSanitizer,\n ctx.registerTransform,\n ctx.abort,\n ctx.metrics,\n submit,\n canSubmit,\n ctx.submitDone,\n ]\n );\n}\n","import type { Sheet, ValidatedRow } from '../../types/sheet.js';\n\nexport function getRowsWithErrors(sheet: Sheet): ValidatedRow[] {\n return sheet.rows.filter((row) => row.errors.length > 0);\n}\n","import type { Sheet } from '../../types/sheet.js';\nimport type { ViewCounts } from './types/index.js';\nimport { getRowsWithErrors } from './get-rows-with-errors.js';\n\nexport function hasValidationErrors(sheet: Sheet | null): boolean {\n if (!sheet) return false;\n return getViewCounts(sheet).totalErrors > 0;\n}\n\nexport function getViewCounts(sheet: Sheet): ViewCounts {\n const totalRows = sheet.rows.length;\n const rowsWithErrors = getRowsWithErrors(sheet);\n const totalErrors =\n sheet.errors.length +\n sheet.rows.reduce(\n (sum, row) =>\n sum + row.errors.length + row.cells.reduce((c, cell) => c + cell.errors.length, 0),\n 0\n );\n return {\n totalRows,\n rowsWithErrors: rowsWithErrors.length,\n totalErrors,\n };\n}\n","import type { Sheet, ValidatedRow } from '../../../types/sheet.js';\n\nexport function getCellValue(row: ValidatedRow, key: string): unknown {\n const cell = row.cells.find((c) => c.key === key);\n return cell?.value;\n}\n\nexport function sheetRowsToObjects<T>(\n rows: readonly ValidatedRow[],\n mapRow: (row: ValidatedRow) => T\n): T[] {\n return rows.map(mapRow);\n}\n\nexport function sheetToObjectsWithKeyMap(\n sheet: Sheet | null,\n keyMap: Readonly<Record<string, string>>\n): Record<string, unknown>[] {\n if (!sheet) return [];\n return sheet.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (const [sheetKey, outputKey] of Object.entries(keyMap)) {\n obj[outputKey] = getCellValue(row, sheetKey);\n }\n return obj;\n });\n}\n","import { useCallback, useEffect } from 'react';\nimport { useImporterContext } from '../providers/index.js';\nimport { useParserWorker } from '../core/parser/hooks/useParserWorker.js';\n\nfunction firstSheetFromResult(\n result: { sheets: Readonly<Record<string, { documentHash: string }>> },\n): { documentHash: string } | null {\n const names = Object.keys(result.sheets);\n if (names.length === 0) return null;\n return result.sheets[names[0] ?? ''] ?? null;\n}\n\nexport function useImportSheet() {\n const ctx = useImporterContext();\n const { load, parseAll, isReady } = useParserWorker();\n\n useEffect(() => {\n const { file, status, engine } = ctx;\n if (!isReady || !file || status !== 'loading') return;\n load(file, { maxRows: 10, fileName: file.name, engine: engine ?? undefined })\n .then((result) => {\n const first = firstSheetFromResult(result);\n if (!first) {\n ctx.setStatus('error');\n return;\n }\n const sheet = result.sheets[Object.keys(result.sheets)[0] ?? ''];\n if (!sheet) {\n ctx.setStatus('error');\n return;\n }\n ctx.setRawData(sheet);\n ctx.setDocumentHash(sheet.documentHash);\n ctx.setStatus('success');\n })\n .catch(() => {\n ctx.setStatus('error');\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- run only when file/status/isReady/load change; ctx setters are stable\n }, [isReady, ctx.file, ctx.status, ctx.setRawData, ctx.setDocumentHash, ctx.setStatus, load]);\n\n const startFullImport = useCallback(() => {\n const { file } = ctx;\n if (!file) return Promise.reject(new Error('No file loaded'));\n ctx.setStatus('loading');\n const t0 = performance.now();\n return parseAll((detail) => ctx.dispatchProgress(detail)).then((result) => {\n const t1 = performance.now();\n ctx.setPhaseTiming('parse', t1 - t0);\n const first = firstSheetFromResult(result);\n if (!first) {\n ctx.setStatus('error');\n return result;\n }\n const sheet = result.sheets[Object.keys(result.sheets)[0] ?? ''];\n if (!sheet) {\n ctx.setStatus('error');\n return result;\n }\n ctx.setRawData(sheet);\n ctx.setDocumentHash(sheet.documentHash);\n ctx.setStatus('success');\n return result;\n });\n }, [ctx, parseAll]);\n\n return { startFullImport };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport * as Comlink from 'comlink';\nimport type { RawParseResult } from '../../../types/raw-sheet.js';\nimport type { ParseOptions } from '../types/index.js';\nimport type { ImporterProgressDetail } from '../../../types/importer-state.js';\nimport { useImporterContext } from '../../../providers/index.js';\nimport { getParserWorkerUrl } from '../worker/worker-url.js';\n\ntype ParserWorkerApi = {\n load: (blob: Blob, options?: ParseOptions) => Promise<RawParseResult>;\n parseAll: (onProgress?: (d: ImporterProgressDetail) => void) => Promise<RawParseResult>;\n};\n\nexport function useParserWorker() {\n const { setActiveWorker, dispatchProgress } = useImporterContext();\n const [workerProxy, setWorkerProxy] = useState<Comlink.Remote<ParserWorkerApi> | null>(null);\n const workerRef = useRef<Worker | null>(null);\n\n useEffect(() => {\n const worker = new Worker(getParserWorkerUrl(), { type: 'module' });\n workerRef.current = worker;\n setActiveWorker(worker);\n const proxy = Comlink.wrap<ParserWorkerApi>(worker);\n queueMicrotask(() => setWorkerProxy(proxy));\n return () => {\n worker.terminate();\n workerRef.current = null;\n setActiveWorker(null);\n };\n }, [setActiveWorker]);\n\n const load = useCallback(\n async (blob: Blob, options: ParseOptions = {}): Promise<RawParseResult> => {\n if (!workerProxy) throw new Error('Parser worker not ready');\n return workerProxy.load(blob, options);\n },\n [workerProxy],\n );\n\n const parseAll = useCallback(\n async (onProgress?: (d: ImporterProgressDetail) => void): Promise<RawParseResult> => {\n if (!workerProxy) throw new Error('Parser worker not ready');\n const progressProxy = onProgress ? Comlink.proxy(onProgress) : undefined;\n return workerProxy.parseAll(progressProxy);\n },\n [workerProxy],\n );\n\n return { load, parseAll, dispatchProgress, isReady: !!workerProxy };\n}\n","export function getParserWorkerUrl(): string {\n return new URL('./parser.worker.js', import.meta.url).href;\n}\n","import { useCallback, useMemo } from 'react';\nimport { useImporterContext } from '../../../providers/index.js';\nimport { runConvert } from '../run-convert.js';\nimport type { ConvertOptions } from '../types/convert-options.js';\nimport type { ConvertResult, ConvertResultApplyResult } from '../types/convert-result.js';\n\nexport function useConvert() {\n const ctx = useImporterContext();\n const { rawData, layout, convertedSheet, convertResultData, setConvertedSheet, setConvertResultData } = ctx;\n\n const convert = useCallback(\n (options?: ConvertOptions) => {\n if (!rawData || !layout) return;\n const result = runConvert(rawData, layout, options, convertResultData ?? undefined);\n if (result.kind === 'success') {\n setConvertedSheet(result.sheet);\n } else {\n setConvertResultData({\n headersFound: result.headersFound,\n mismatches: result.mismatches,\n columnOrder: result.columnOrder,\n headerToFieldMap: result.headerToFieldMap,\n });\n }\n },\n [rawData, layout, convertResultData, setConvertedSheet, setConvertResultData],\n );\n\n const applyMappingImpl = useCallback((): ConvertResultApplyResult | undefined => {\n if (!rawData || !layout || !convertResultData) return undefined;\n const result = runConvert(rawData, layout, {}, {\n columnOrder: convertResultData.columnOrder,\n headerToFieldMap: convertResultData.headerToFieldMap,\n });\n if (result.kind === 'success') {\n setConvertedSheet(result.sheet);\n return { kind: 'success', sheet: result.sheet };\n }\n setConvertResultData({\n headersFound: result.headersFound,\n mismatches: result.mismatches,\n columnOrder: result.columnOrder,\n headerToFieldMap: result.headerToFieldMap,\n });\n return { kind: 'mismatch', result };\n }, [rawData, layout, convertResultData, setConvertedSheet, setConvertResultData]);\n\n const reorderColumns = useCallback(\n (fieldNames: string[]) => {\n setConvertResultData((prev) =>\n prev ? { ...prev, columnOrder: fieldNames } : prev,\n );\n },\n [setConvertResultData],\n );\n\n const renameColumn = useCallback(\n (fileHeader: string, layoutFieldName: string) => {\n setConvertResultData((prev) =>\n prev\n ? {\n ...prev,\n headerToFieldMap: { ...prev.headerToFieldMap, [fileHeader]: layoutFieldName },\n }\n : prev,\n );\n },\n [setConvertResultData],\n );\n\n const convertResult: ConvertResult | null = useMemo(() => {\n if (!convertResultData) return null;\n return {\n kind: 'mismatch',\n headersFound: convertResultData.headersFound,\n mismatches: convertResultData.mismatches,\n columnOrder: [...convertResultData.columnOrder],\n headerToFieldMap: { ...convertResultData.headerToFieldMap },\n reorderColumns,\n renameColumn,\n applyMapping: () =>\n applyMappingImpl() ?? {\n kind: 'mismatch' as const,\n result: { ...convertResultData, kind: 'mismatch' as const },\n },\n };\n }, [convertResultData, reorderColumns, renameColumn, applyMappingImpl]);\n\n return useMemo(\n () => ({\n convert,\n convertedSheet,\n convertResult,\n }),\n [convert, convertedSheet, convertResult],\n );\n}\n","import type { RawSheet } from '../../types/raw-sheet.js';\nimport type { SheetLayout } from '../../types/sheet-layout.js';\nimport type { ConvertedSheet, ConvertedSheetCell, ConvertedSheetRow } from './types/converted-sheet.js';\n\nexport function buildConvertedSheet(\n rawSheet: RawSheet,\n _sheetLayout: SheetLayout,\n columnOrder: readonly string[],\n fieldToHeader: Readonly<Record<string, string | null>>,\n): ConvertedSheet {\n const headers = [...columnOrder];\n const headerIndex = new Map<string, number>();\n rawSheet.headers.forEach((h, i) => headerIndex.set(h, i));\n\n const rows: ConvertedSheetRow[] = rawSheet.rows.map((row) => {\n const cells: ConvertedSheetCell[] = columnOrder.map((fieldName) => {\n const fileHeader = fieldToHeader[fieldName];\n const value =\n fileHeader != null\n ? (() => {\n const idx = headerIndex.get(fileHeader);\n if (idx == null) return null;\n const cell = row.cells[idx];\n return cell?.value ?? null;\n })()\n : null;\n return { key: fieldName, value: value ?? null };\n });\n return { index: row.index, cells };\n });\n\n return {\n name: rawSheet.name,\n filesize: rawSheet.filesize,\n documentHash: rawSheet.documentHash,\n rowsCount: rawSheet.rowsCount,\n headersCount: rawSheet.headersCount,\n headers,\n rows,\n };\n}\n","export function normalize(s: string): string {\n const t = s.trim().toLowerCase();\n return t.normalize('NFD').replace(/\\p{Diacritic}/gu, '');\n}\n\nfunction levenshteinDistance(a: string, b: string): number {\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i++) {\n const curr: number[] = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n curr[j] = Math.min(\n curr[j - 1]! + 1,\n prev[j]! + 1,\n prev[j - 1]! + cost,\n );\n }\n prev = curr;\n }\n return prev[b.length]!;\n}\n\nexport function getSimilarity(s1: string, s2: string): number {\n const a = normalize(s1);\n const b = normalize(s2);\n const longer = a.length >= b.length ? a : b;\n const shorter = a.length < b.length ? a : b;\n if (longer.length === 0) return 1;\n const distance = levenshteinDistance(longer, shorter);\n return (longer.length - distance) / longer.length;\n}\n\nconst DEFAULT_FUZZY_THRESHOLD = 0.8;\n\nexport interface MapHeadersOptions {\n threshold?: number;\n}\n\nexport interface MapHeadersItem {\n key: string;\n matchedHeader: string | null;\n}\n\nexport function mapHeaders(\n rawHeaders: string[],\n expectedKeys: string[],\n options: MapHeadersOptions = {},\n): MapHeadersItem[] {\n const threshold = options.threshold ?? DEFAULT_FUZZY_THRESHOLD;\n const keyScores: { key: string; header: string; score: number }[] = [];\n for (const key of expectedKeys) {\n for (const header of rawHeaders) {\n const score = getSimilarity(key, header);\n if (score >= threshold) {\n keyScores.push({ key, header, score });\n }\n }\n }\n keyScores.sort((x, y) => y.score - x.score);\n\n const assignedKeys = new Set<string>();\n const assignedHeaders = new Set<string>();\n const keyToHeader: Record<string, string | null> = {};\n for (const k of expectedKeys) {\n keyToHeader[k] = null;\n }\n for (const { key, header, score: _ } of keyScores) {\n if (assignedKeys.has(key) || assignedHeaders.has(header)) continue;\n keyToHeader[key] = header;\n assignedKeys.add(key);\n assignedHeaders.add(header);\n }\n\n return expectedKeys.map((key) => ({\n key,\n matchedHeader: keyToHeader[key] ?? null,\n }));\n}\n","import type { RawSheet } from '../../types/raw-sheet.js';\nimport type { SheetLayout } from '../../types/sheet-layout.js';\nimport { mapHeaders } from '../parser/utils/fuzzy-match.js';\nimport type { ColumnMismatch } from './types/column-mismatch.js';\nimport type { ConvertOptions } from './types/convert-options.js';\n\nexport interface MatchHeadersResult {\n readonly fieldToHeader: Readonly<Record<string, string | null>>;\n readonly mismatches: readonly ColumnMismatch[];\n}\n\nfunction defaultNormalize(header: string, caseSensitive: boolean): string {\n const trimmed = header.trim();\n return caseSensitive ? trimmed : trimmed.toLowerCase();\n}\n\nexport function matchHeadersToLayout(\n rawSheet: RawSheet,\n sheetLayout: SheetLayout,\n headerToFieldMap: Readonly<Record<string, string>> = {},\n options: ConvertOptions = {}\n): MatchHeadersResult {\n const caseSensitive = options.caseSensitive ?? false;\n const normalizer = options.normalizer ?? ((h: string) => defaultNormalize(h, caseSensitive));\n const layoutFieldNames = Object.keys(sheetLayout.fields) as string[];\n const fileHeaders = rawSheet.headers as string[];\n const normalizedToFileHeader = new Map<string, string>();\n for (const h of fileHeaders) {\n normalizedToFileHeader.set(normalizer(h), h);\n }\n\n const fieldToHeader: Record<string, string | null> = {};\n const usedFileHeaders = new Set<string>();\n\n for (const [fileHeader, fieldName] of Object.entries(headerToFieldMap)) {\n if (layoutFieldNames.includes(fieldName)) {\n fieldToHeader[fieldName] = fileHeaders.includes(fileHeader) ? fileHeader : null;\n if (fieldToHeader[fieldName]) usedFileHeaders.add(fileHeader);\n }\n }\n\n for (const fieldName of layoutFieldNames) {\n if (fieldToHeader[fieldName] != null) continue;\n const key = normalizer(fieldName);\n const fileHeader = normalizedToFileHeader.get(key);\n if (fileHeader != null && !usedFileHeaders.has(fileHeader)) {\n fieldToHeader[fieldName] = fileHeader;\n usedFileHeaders.add(fileHeader);\n } else {\n fieldToHeader[fieldName] = null;\n }\n }\n\n if (options.fuzzyHeaders === true) {\n const unmatchedFields = layoutFieldNames.filter((f) => fieldToHeader[f] == null);\n const availableHeaders = fileHeaders.filter((h) => !usedFileHeaders.has(h));\n const threshold = options.fuzzyThreshold ?? 0.8;\n const fuzzyResults = mapHeaders(availableHeaders, unmatchedFields, { threshold });\n for (const { key, matchedHeader } of fuzzyResults) {\n if (matchedHeader != null && !usedFileHeaders.has(matchedHeader)) {\n fieldToHeader[key] = matchedHeader;\n usedFileHeaders.add(matchedHeader);\n }\n }\n }\n\n const mismatches: ColumnMismatch[] = [];\n for (const fieldName of layoutFieldNames) {\n const found = fieldToHeader[fieldName];\n if (found == null) {\n const field = sheetLayout.fields[fieldName];\n const required = field?.required !== false;\n mismatches.push({\n expected: fieldName,\n found: null,\n message: `Column '${fieldName}' not found in file`,\n required,\n });\n }\n }\n\n return { fieldToHeader, mismatches };\n}\n","import type { RawSheet } from '../../types/raw-sheet.js';\nimport type { SheetLayout } from '../../types/sheet-layout.js';\nimport { buildConvertedSheet } from './build-converted-sheet.js';\nimport { matchHeadersToLayout } from './match-headers.js';\nimport type { ConvertMismatchData } from './types/convert-mismatch-data.js';\nimport type { ConvertOptions } from './types/convert-options.js';\nimport type { ConvertSuccess } from './types/convert-success.js';\n\nexport type RunConvertExisting = {\n readonly columnOrder: readonly string[];\n readonly headerToFieldMap: Readonly<Record<string, string>>;\n};\n\nexport type RunConvertResult = ConvertSuccess | ConvertMismatchData;\n\nexport function runConvert(\n rawSheet: RawSheet,\n sheetLayout: SheetLayout,\n options: ConvertOptions = {},\n existing?: RunConvertExisting\n): RunConvertResult {\n const layoutFieldNames = Object.keys(sheetLayout.fields) as string[];\n const columnOrder = existing?.columnOrder?.length\n ? (existing.columnOrder as string[])\n : layoutFieldNames;\n const headerToFieldMap = existing?.headerToFieldMap ?? {};\n\n const { fieldToHeader, mismatches } = matchHeadersToLayout(\n rawSheet,\n sheetLayout,\n headerToFieldMap,\n options\n );\n\n const requiredFieldNames = layoutFieldNames.filter(\n (f) => sheetLayout.fields[f]?.required !== false\n );\n const allRequiredMatched = requiredFieldNames.every((f) => fieldToHeader[f] != null);\n const allMatched = mismatches.length === 0;\n\n if (allMatched || allRequiredMatched) {\n const sheet = buildConvertedSheet(rawSheet, sheetLayout, columnOrder, fieldToHeader);\n return { kind: 'success', sheet };\n }\n\n const layoutError = mismatches.some((m) => m.required === true);\n return {\n kind: 'mismatch',\n headersFound: [...rawSheet.headers],\n mismatches,\n columnOrder: [...columnOrder],\n headerToFieldMap: { ...headerToFieldMap },\n layoutError,\n };\n}\n","import { useMemo } from 'react';\r\nimport { useImporterContext } from '../providers/index.js';\r\n\r\nexport function useImporterStatus() {\r\n const ctx = useImporterContext();\r\n return useMemo(\r\n () => ({\r\n status: ctx.status,\r\n progressEventTarget: ctx.progressEventTarget,\r\n }),\r\n [ctx.status, ctx.progressEventTarget],\r\n );\r\n}\r\n","import { useCallback, useMemo } from 'react';\r\nimport type { ValidatedRow } from '../types/sheet.js';\r\nimport { useImporterContext } from '../providers/index.js';\r\nimport {\r\n sheetRowsToObjects,\r\n sheetToObjectsWithKeyMap,\r\n} from '../core/view/export/sheet-to-objects.js';\r\n\r\nexport function useSheetData() {\r\n const ctx = useImporterContext();\r\n const sheet = ctx.result;\r\n const errors = useMemo(() => {\r\n if (!sheet) return [];\r\n return [...sheet.errors];\r\n }, [sheet]);\r\n const toObjects = useCallback(\r\n <T>(mapRow: (row: ValidatedRow) => T): T[] => {\r\n if (!sheet) return [];\r\n return sheetRowsToObjects(sheet.rows, mapRow);\r\n },\r\n [sheet]\r\n );\r\n const toObjectsWithKeyMap = useCallback(\r\n (keyMap: Readonly<Record<string, string>>): Record<string, unknown>[] => {\r\n return sheetToObjectsWithKeyMap(sheet, keyMap);\r\n },\r\n [sheet]\r\n );\r\n return useMemo(\r\n () => ({ sheet, errors, toObjects, toObjectsWithKeyMap }),\r\n [sheet, errors, toObjects, toObjectsWithKeyMap]\r\n );\r\n}\r\n","import { useCallback, useMemo, useRef } from 'react';\nimport { type ChangeLogEntry, formatChangeLogAsText } from '../types/change-log.js';\nimport type { EditCellParams } from '../types/edit.js';\nimport type { PaginatedResult } from '../types/paginated-result.js';\nimport type { ValidatedRow } from '../types/sheet.js';\nimport { useImporterContext } from '../providers/index.js';\nimport { removeRow as removeRowSheet } from '../core/editor/immutable-update.js';\nimport { useEditWorker } from '../core/editor/hooks/useEditWorker.js';\nimport { getPaginatedResult } from '../core/editor/get-paginated-result.js';\nimport { getCellByKey, getRowByIndex } from '../core/editor/resolve.js';\n\nexport interface UseSheetEditorOptions {\n page?: number;\n pageSize?: number;\n debounceMs?: number;\n}\n\nexport function useSheetEditor(options: UseSheetEditorOptions = {}) {\n const {\n result: sheet,\n setResult,\n layout,\n changeLog,\n addChangeLogEntry,\n submitDone,\n } = useImporterContext();\n const { runEdit, isReady } = useEditWorker();\n const canEdit = !submitDone;\n const { page = 1, pageSize = 25, debounceMs } = options;\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const pageData = useMemo((): PaginatedResult<ValidatedRow> => {\n if (!sheet) {\n return { page: 1, pageSize, totalCount: 0, totalPages: 0, rows: [] };\n }\n return getPaginatedResult(sheet, page, pageSize);\n }, [sheet, page, pageSize]);\n\n const totalPages = pageData.totalPages;\n\n const applyEdit = useCallback(\n (params: EditCellParams) => {\n if (!sheet || !layout || submitDone) return Promise.resolve();\n const previousValue =\n getRowByIndex(sheet, params.rowIndex) &&\n getCellByKey(getRowByIndex(sheet, params.rowIndex)!, params.cellKey)?.value;\n return runEdit(sheet, layout, params.rowIndex, params.cellKey, params.value).then(\n (newSheet) => {\n setResult(newSheet);\n queueMicrotask(() => {\n const entry: ChangeLogEntry = {\n type: 'cell_edit',\n rowIndex: params.rowIndex,\n cellKey: params.cellKey,\n value: params.value,\n previousValue,\n timestamp: Date.now(),\n };\n addChangeLogEntry(entry);\n });\n }\n );\n },\n [sheet, layout, submitDone, runEdit, setResult, addChangeLogEntry]\n );\n\n const editCell = useCallback(\n (params: EditCellParams): void | Promise<void> => {\n if (debounceMs != null && debounceMs > 0) {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n debounceRef.current = null;\n applyEdit(params);\n }, debounceMs);\n return;\n }\n return applyEdit(params);\n },\n [debounceMs, applyEdit]\n );\n\n const removeRow = useCallback(\n (rowIndex: number): void => {\n if (!sheet || submitDone) return;\n const newSheet = removeRowSheet(sheet, rowIndex);\n setResult(newSheet);\n queueMicrotask(() => {\n const entry: ChangeLogEntry = {\n type: 'row_remove',\n rowIndex,\n timestamp: Date.now(),\n };\n addChangeLogEntry(entry);\n });\n },\n [sheet, submitDone, setResult, addChangeLogEntry]\n );\n\n const changeLogAsText = useMemo(() => formatChangeLogAsText(changeLog), [changeLog]);\n\n return useMemo(\n () => ({\n sheet,\n editCell,\n removeRow,\n pageData,\n totalPages,\n isReady,\n canEdit,\n changeLog,\n changeLogAsText,\n }),\n [sheet, editCell, removeRow, pageData, totalPages, isReady, canEdit, changeLog, changeLogAsText]\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport * as Comlink from 'comlink';\nimport type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { Sheet } from '../../../types/sheet.js';\nimport { getEditWorkerUrl } from '../worker/worker-url.js';\n\nexport interface EditWorkerOptions {\n signal?: AbortSignal;\n}\n\ntype EditWorkerApi = {\n runEdit: (\n sheet: Sheet,\n sheetLayout: SheetLayout,\n rowIndex: number,\n cellKey: string,\n value: unknown,\n options?: EditWorkerOptions,\n ) => Promise<Sheet>;\n};\n\nexport function useEditWorker() {\n const [workerProxy, setWorkerProxy] = useState<Comlink.Remote<EditWorkerApi> | null>(null);\n const workerRef = useRef<Worker | null>(null);\n\n useEffect(() => {\n const worker = new Worker(getEditWorkerUrl(), { type: 'module' });\n workerRef.current = worker;\n const proxy = Comlink.wrap<EditWorkerApi>(worker);\n queueMicrotask(() => setWorkerProxy(proxy));\n return () => {\n worker.terminate();\n workerRef.current = null;\n };\n }, []);\n\n const runEdit = useCallback(\n async (\n sheet: Sheet,\n sheetLayout: SheetLayout,\n rowIndex: number,\n cellKey: string,\n value: unknown,\n options?: EditWorkerOptions,\n ): Promise<Sheet> => {\n if (!workerProxy) throw new Error('Edit worker not ready');\n return workerProxy.runEdit(\n sheet,\n sheetLayout,\n rowIndex,\n cellKey,\n value,\n options ?? {},\n );\n },\n [workerProxy],\n );\n\n return { runEdit, isReady: !!workerProxy };\n}\n","export function getEditWorkerUrl(): string {\n return new URL('./edit.worker.js', import.meta.url).href;\n}\n","import type { PaginatedResult } from '../../types/paginated-result.js';\nimport type { Sheet, ValidatedRow } from '../../types/sheet.js';\n\nexport function getPaginatedResult(\n sheet: Sheet,\n page: number,\n pageSize: number,\n): PaginatedResult<ValidatedRow> {\n return getPaginatedResultFromRows(sheet.rows, page, pageSize);\n}\n\nexport function getPaginatedResultFromRows<TRow>(\n rows: readonly TRow[],\n page: number,\n pageSize: number,\n): PaginatedResult<TRow> {\n const totalCount = rows.length;\n const totalPages =\n pageSize <= 0 ? 0 : Math.max(1, Math.ceil(totalCount / pageSize));\n const safePage = Math.max(1, Math.min(page, totalPages));\n const start = (safePage - 1) * pageSize;\n const end = Math.min(start + pageSize, totalCount);\n const slice = rows.slice(start, end);\n return {\n page: safePage,\n pageSize,\n totalCount,\n totalPages,\n rows: slice,\n };\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport type { ValidatedRow } from '../../../types/sheet.js';\nimport { useImporterContext } from '../../../providers/index.js';\nimport { useSheetEditor } from '../../../hooks/useSheetEditor.js';\nimport { getPaginatedResultFromRows } from '../../editor/get-paginated-result.js';\nimport { getRowsWithErrors } from '../get-rows-with-errors.js';\nimport { getViewCounts } from '../get-view-counts.js';\nimport { sheetToCSV } from '../export/sheet-to-csv.js';\nimport { sheetToJSON } from '../export/sheet-to-json.js';\nimport type { UseSheetViewOptions, UseSheetViewReturn } from '../types/index.js';\n\nexport function useSheetView(options: UseSheetViewOptions = {}): UseSheetViewReturn<ValidatedRow> {\n const { page: initialPage = 1, defaultPageSize = 25, filterMode = 'all' } = options;\n const [page, setPage] = useState(initialPage);\n const pageSize = defaultPageSize;\n const { sheet, editCell, removeRow, changeLog, changeLogAsText } = useSheetEditor({});\n const ctx = useImporterContext();\n\n const rowsWithErrors = useMemo(() => (sheet ? getRowsWithErrors(sheet) : []), [sheet]);\n const sourceRows = useMemo(\n () => (filterMode === 'errors-only' ? rowsWithErrors : (sheet?.rows ?? [])),\n [filterMode, rowsWithErrors, sheet]\n );\n const totalRows = sourceRows.length;\n\n const getPaginatedResult = useCallback(\n (p?: number, ps?: number) => {\n const pp = p ?? page;\n const pps = ps ?? pageSize;\n return getPaginatedResultFromRows(sourceRows, pp, pps);\n },\n [page, pageSize, sourceRows]\n );\n const paginatedRows = useMemo(\n () => getPaginatedResult(page, pageSize).rows,\n [getPaginatedResult, page, pageSize]\n );\n const getRows = useCallback(\n (page: number, limit: number) => {\n // 1-based page → 0-based start index\n const start = (page - 1) * limit;\n return sourceRows.slice(start, start + limit);\n },\n [sourceRows]\n );\n const counts = useMemo(\n () => (sheet ? getViewCounts(sheet) : { totalRows: 0, rowsWithErrors: 0, totalErrors: 0 }),\n [sheet]\n );\n\n const exportToCSV = useCallback(\n (opts?: Parameters<UseSheetViewReturn['exportToCSV']>[0]) => {\n if (!sheet || !ctx.layout) return '';\n return sheetToCSV(sheet, ctx.layout, opts ?? {});\n },\n [sheet, ctx.layout]\n );\n const exportToJSON = useCallback(\n (opts?: Parameters<UseSheetViewReturn['exportToJSON']>[0]) => {\n if (!sheet) return '[]';\n return sheetToJSON(sheet, ctx.layout ?? null, opts ?? {});\n },\n [sheet, ctx.layout]\n );\n\n const downloadCSV = useCallback(\n async (opts?: Parameters<UseSheetViewReturn['downloadCSV']>[0]) => {\n const content = exportToCSV(opts);\n if (!content) return;\n const blob = new Blob([content], { type: 'text/csv;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = (opts?.filename ?? 'export') + '.csv';\n a.click();\n URL.revokeObjectURL(url);\n },\n [exportToCSV]\n );\n const downloadJSON = useCallback(\n async (opts?: Parameters<UseSheetViewReturn['downloadJSON']>[0]) => {\n const content = exportToJSON(opts);\n const blob = new Blob([content], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = (opts?.filename ?? 'export') + '.json';\n a.click();\n URL.revokeObjectURL(url);\n },\n [exportToJSON]\n );\n\n return useMemo(\n () => ({\n sheet,\n getPaginatedResult,\n paginatedRows,\n page,\n setPage,\n pageSize,\n totalRows,\n getRows,\n rowsWithErrors,\n counts,\n editCell,\n removeRow,\n changeLog,\n changeLogAsText,\n exportToCSV,\n exportToJSON,\n downloadCSV,\n downloadJSON,\n hasRecoverableSession: ctx.hasRecoverableSession,\n recoverSession: ctx.recoverSession,\n clearPersistedState: ctx.clearPersistedState,\n }),\n [\n sheet,\n getPaginatedResult,\n paginatedRows,\n page,\n pageSize,\n totalRows,\n getRows,\n rowsWithErrors,\n counts,\n editCell,\n removeRow,\n changeLog,\n changeLogAsText,\n exportToCSV,\n exportToJSON,\n downloadCSV,\n downloadJSON,\n ctx.hasRecoverableSession,\n ctx.recoverSession,\n ctx.clearPersistedState,\n ]\n );\n}\n","import type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { Sheet } from '../../../types/sheet.js';\nimport type { ExportOptions } from '../types/export-options.js';\n\nconst BOM = '\\uFEFF';\n\nfunction escapeCsvValue(value: string, separator: string): string {\n const needsQuotes =\n value.includes(separator) || value.includes('\"') || value.includes('\\n') || value.includes('\\r');\n if (!needsQuotes) return value;\n return '\"' + value.replace(/\"/g, '\"\"') + '\"';\n}\n\nfunction cellValueToString(value: unknown, formatDates: boolean): string {\n if (value === null || value === undefined) return '';\n if (value instanceof Date) return formatDates ? value.toLocaleString() : value.toISOString();\n return String(value);\n}\n\nexport function sheetToCSV(\n sheet: Sheet,\n sheetLayout: SheetLayout | null,\n options: ExportOptions = {},\n): string {\n const {\n includeHeaders = true,\n csvSeparator = ',',\n formatDatesForExport = false,\n } = options;\n const fieldOrder =\n sheetLayout != null ? Object.keys(sheetLayout.fields) : [];\n const effectiveOrder =\n fieldOrder.length > 0\n ? fieldOrder\n : (sheet.rows[0]?.cells.map((c) => c.key) ?? sheet.headers.slice());\n\n const lines: string[] = [];\n if (includeHeaders && effectiveOrder.length > 0) {\n lines.push(effectiveOrder.map((h) => escapeCsvValue(h, csvSeparator)).join(csvSeparator));\n }\n for (const row of sheet.rows) {\n const values = effectiveOrder.map((key) => {\n const cell = row.cells.find((c) => c.key === key);\n const raw = cell?.value ?? '';\n return escapeCsvValue(cellValueToString(raw, formatDatesForExport), csvSeparator);\n });\n lines.push(values.join(csvSeparator));\n }\n const body = lines.join('\\r\\n');\n return BOM + body;\n}\n","import type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { Sheet } from '../../../types/sheet.js';\nimport type { ExportOptions } from '../types/export-options.js';\n\nfunction cellValueToJson(value: unknown, formatDates: boolean): unknown {\n if (value === null || value === undefined) return null;\n if (value instanceof Date) return formatDates ? value.toLocaleString() : value.toISOString();\n return value;\n}\n\nexport function sheetToJSON(\n sheet: Sheet,\n _sheetLayout: SheetLayout | null,\n options: ExportOptions = {},\n): string {\n const { formatDatesForExport = false } = options;\n const rows = sheet.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (const cell of row.cells) {\n obj[cell.key] = cellValueToJson(cell.value, formatDatesForExport);\n }\n return obj;\n });\n return JSON.stringify(rows, null, 0);\n}\n","import { useCallback, useEffect } from 'react';\r\nimport { IMPORTER_PROGRESS_EVENT } from '../types/index.js';\r\nimport type { ImporterProgressDetail } from '../types/index.js';\r\nimport { useImporterContext } from '../providers/index.js';\r\n\r\nexport function useImporterEventTarget() {\r\n const ctx = useImporterContext();\r\n const target = ctx.progressEventTarget;\r\n\r\n const subscribeToProgress = useCallback(\r\n (callback: (detail: ImporterProgressDetail) => void) => {\r\n const handler = (e: Event) => {\r\n callback((e as CustomEvent<ImporterProgressDetail>).detail);\r\n };\r\n target.addEventListener(IMPORTER_PROGRESS_EVENT, handler);\r\n return () => {\r\n target.removeEventListener(IMPORTER_PROGRESS_EVENT, handler);\r\n };\r\n },\r\n [target],\r\n );\r\n\r\n return { progressEventTarget: target, subscribeToProgress };\r\n}\r\n\r\nexport function useImporterProgressSubscription(\r\n callback: (detail: ImporterProgressDetail) => void,\r\n) {\r\n const { subscribeToProgress } = useImporterEventTarget();\r\n useEffect(() => {\r\n return subscribeToProgress(callback);\r\n }, [subscribeToProgress, callback]);\r\n}\r\n"],"mappings":"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","names":["useEffect","useMemo","useRef","useState","PERSIST_STORE_NAME","DEFAULT_PERSIST_KEY","createContext","ImporterContext","initialState","useCallback","useMemo","formatMs","ms","buildPipelineMetrics","timings","rowCount","overheadMs","totalMs","isSlow","efficiency","percentages","overhead","totalWithOverhead","formatChangeLogAsText","entries","lines","e","prev","IMPORTER_PROGRESS_EVENT","IMPORTER_ABORTED_EVENT","useCallback","useImporterStateSetters","deps","setState","setLayoutState","setEngineState","setFile","file","prev","setRawData","rawData","setDocumentHash","documentHash","setStatus","status","setResult","result","setConvertedSheet","convertedSheet","setSanitizedSheet","sanitizedSheet","setConvertResultData","dataOrUpdater","setMetrics","metrics","setSubmitDone","submitDone","setLayout","next","setEngine","INITIAL_PHASE_TIMINGS","useImporterActions","deps","setState","setLayoutState","setEngineState","progressEventTarget","validatorRegistry","sanitizerRegistry","transformRegistry","activeWorkerRef","phaseTimingsRef","stateSetters","useImporterStateSetters","dispatchProgress","useCallback","detail","IMPORTER_PROGRESS_EVENT","setActiveWorker","worker","abort","prev","IMPORTER_ABORTED_EVENT","setPhaseTiming","phase","ms","finalizeMetrics","rowCount","timings","metrics","buildPipelineMetrics","addChangeLogEntry","entry","processFile","file","registerValidator","name","fn","options","registerSanitizer","registerTransform","useMemo","useCallback","useEffect","useRef","useState","openDb","resolve","reject","req","PERSIST_STORE_NAME","savePersistedState","key","state","db","tx","store","record","loadPersistedState","row","savedAt","_k","clearPersistedState","DEBOUNCE_MS","usePersistSession","persist","persistKey","rawData","result","setRawData","setResult","layoutVersion","recoverableSession","setRecoverableSession","useState","debounceRef","useRef","useEffect","loadPersistedState","state","payload","savePersistedState","recoverSession","useCallback","clearPersistedState","jsx","ImporterProvider","children","layoutProp","engineProp","persist","persistKey","DEFAULT_PERSIST_KEY","onSubmit","submitKeyMap","state","setState","useState","initialState","layout","setLayoutState","engine","setEngineState","progressEventTarget","useMemo","validatorRegistry","Registry","sanitizerRegistry","transformRegistry","activeWorkerRef","useRef","phaseTimingsRef","stateSetters","useImporterStateSetters","persistSession","usePersistSession","actions","useImporterActions","useEffect","worker","value","ImporterContext","useContext","useImporterContext","context","useContext","ImporterContext","useCallback","useEffect","useMemo","getRowsWithErrors","sheet","row","hasValidationErrors","sheet","getViewCounts","totalRows","rowsWithErrors","getRowsWithErrors","totalErrors","sum","row","c","cell","getCellValue","row","key","c","sheetRowsToObjects","rows","mapRow","sheetToObjectsWithKeyMap","sheet","keyMap","obj","sheetKey","outputKey","rowsToLayoutObjects","sheet","row","acc","c","useImporter","options","ctx","useImporterContext","layoutOption","engineOption","useEffect","canSubmit","useMemo","hasValidationErrors","submit","useCallback","data","sheetToObjectsWithKeyMap","useCallback","useEffect","useCallback","useEffect","useRef","useState","Comlink","getParserWorkerUrl","useParserWorker","setActiveWorker","dispatchProgress","useImporterContext","workerProxy","setWorkerProxy","useState","workerRef","useRef","useEffect","worker","getParserWorkerUrl","proxy","load","useCallback","blob","options","parseAll","onProgress","progressProxy","firstSheetFromResult","result","names","useImportSheet","ctx","useImporterContext","load","parseAll","isReady","useParserWorker","useEffect","file","status","engine","sheet","useCallback","t0","detail","t1","useCallback","useMemo","buildConvertedSheet","rawSheet","_sheetLayout","columnOrder","fieldToHeader","headers","headerIndex","h","i","rows","row","cells","fieldName","fileHeader","value","idx","normalize","s","levenshteinDistance","a","b","prev","_","i","curr","j","cost","getSimilarity","s1","s2","longer","shorter","distance","DEFAULT_FUZZY_THRESHOLD","mapHeaders","rawHeaders","expectedKeys","options","threshold","keyScores","key","header","score","x","y","assignedKeys","assignedHeaders","keyToHeader","k","defaultNormalize","header","caseSensitive","trimmed","matchHeadersToLayout","rawSheet","sheetLayout","headerToFieldMap","options","normalizer","h","layoutFieldNames","fileHeaders","normalizedToFileHeader","fieldToHeader","usedFileHeaders","fileHeader","fieldName","key","unmatchedFields","f","availableHeaders","threshold","fuzzyResults","mapHeaders","matchedHeader","mismatches","required","runConvert","rawSheet","sheetLayout","options","existing","layoutFieldNames","columnOrder","headerToFieldMap","fieldToHeader","mismatches","matchHeadersToLayout","allRequiredMatched","f","buildConvertedSheet","layoutError","useConvert","ctx","useImporterContext","rawData","layout","convertedSheet","convertResultData","setConvertedSheet","setConvertResultData","convert","useCallback","options","result","runConvert","applyMappingImpl","reorderColumns","fieldNames","prev","renameColumn","fileHeader","layoutFieldName","convertResult","useMemo","useMemo","useImporterStatus","ctx","useImporterContext","useMemo","useCallback","useMemo","useSheetData","sheet","useImporterContext","errors","useMemo","toObjects","useCallback","mapRow","sheetRowsToObjects","toObjectsWithKeyMap","keyMap","sheetToObjectsWithKeyMap","useCallback","useMemo","useRef","useCallback","useEffect","useRef","useState","Comlink","getEditWorkerUrl","useEditWorker","workerProxy","setWorkerProxy","useState","workerRef","useRef","useEffect","worker","getEditWorkerUrl","proxy","useCallback","sheet","sheetLayout","rowIndex","cellKey","value","options","getPaginatedResult","sheet","page","pageSize","getPaginatedResultFromRows","rows","totalCount","totalPages","safePage","start","end","slice","useSheetEditor","options","sheet","setResult","layout","changeLog","addChangeLogEntry","submitDone","useImporterContext","runEdit","isReady","useEditWorker","canEdit","page","pageSize","debounceMs","debounceRef","useRef","pageData","useMemo","getPaginatedResult","totalPages","applyEdit","useCallback","params","previousValue","getRowByIndex","getCellByKey","newSheet","entry","editCell","removeRow","rowIndex","changeLogAsText","formatChangeLogAsText","useCallback","useMemo","useState","escapeCsvValue","value","separator","cellValueToString","formatDates","sheetToCSV","sheet","sheetLayout","options","includeHeaders","csvSeparator","formatDatesForExport","fieldOrder","effectiveOrder","c","lines","h","row","values","key","raw","cellValueToJson","value","formatDates","sheetToJSON","sheet","_sheetLayout","options","formatDatesForExport","rows","row","obj","cell","useSheetView","options","initialPage","defaultPageSize","filterMode","page","setPage","useState","pageSize","sheet","editCell","removeRow","changeLog","changeLogAsText","useSheetEditor","ctx","useImporterContext","rowsWithErrors","useMemo","getRowsWithErrors","sourceRows","totalRows","getPaginatedResult","useCallback","p","ps","getPaginatedResultFromRows","paginatedRows","getRows","limit","start","counts","getViewCounts","exportToCSV","opts","sheetToCSV","exportToJSON","sheetToJSON","downloadCSV","content","blob","url","a","downloadJSON","useCallback","useEffect","useImporterEventTarget","target","useImporterContext","subscribeToProgress","useCallback","callback","handler","e","IMPORTER_PROGRESS_EVENT","useImporterProgressSubscription","useEffect"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as R}from"./chunk-J2IHY56K.js";import*as k from"comlink";import{sha256 as U}from"js-sha256";var y=256*1024;async function g(e){let t=U.create(),s=0;for(;s<e.size;){let n=await e.slice(s,s+y).arrayBuffer();t.update(new Uint8Array(n)),s+=y}return t.hex()}import*as p from"xlsx";function P(e,t,s,r,n={}){let a=p.read(e,{type:"array",cellDates:!0}),i=n.maxRows,l={};for(let u of a.SheetNames){let d=a.Sheets[u];if(!d)continue;let m=p.utils.sheet_to_json(d,{header:1,defval:null});if(m.length===0){l[u]={name:r??u,filesize:t,documentHash:s,headersCount:0,headers:[],rowsCount:0,rows:[]};continue}let f=m[0].map(o=>o!=null?String(o):""),c=m.slice(1),O=i!=null?Math.min(i,c.length):c.length,x=[];for(let o=0;o<O;o++){let B=c[o],X=f.map((j,E)=>{let L=B?.[E];return{key:j,value:R(L)}});x.push({index:o,cells:X})}l[u]={name:r??u,filesize:t,documentHash:s,headersCount:f.length,rowsCount:c.length,headers:f,rows:x}}return{sheets:l}}var C=["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-excel","application/vnd.oasis.opendocument.spreadsheet"],S="text/csv";function H(e,t){let s=t.fileName??e.name;if(s){let n=s.match(/\.([a-z0-9]+)$/i);if(n)return n[1].toLowerCase()}let r=e.type?.toLowerCase();return r===S?"csv":C.some(n=>r?.startsWith(n)||r===n)?r.includes("spreadsheetml")?"xlsx":"xls":null}function M(e,t){return e==="csv"||t.type===S}function N(e,t){return e==="xlsx"||e==="xls"||e==="ods"?!0:C.some(s=>t.type===s||t.type?.startsWith(s))}async function w(e,t={}){let s=e.size,r=await g(e),n=t.engine==="auto"||t.engine===null||t.engine===void 0?null:t.engine,a=H(e,t);if(n==="csv"||n===null&&M(a,e)){let{parseCsv:i}=await import("./csv-parser-ML7A4LF4.js"),l=t.fileName??e.name??"Sheet1";return i(e,s,r,l,t)}if(n==="xlsx"||n===null&&N(a,e)){let i=await e.arrayBuffer();return P(i,s,r,void 0,t)}throw n!==null?new Error(`Unsupported engine: ${n}. Use 'xlsx', 'csv', or omit for automatic detection.`):new Error(`Unsupported file type: ${a??e.type??"unknown"}. Use .xlsx, .xls, .ods or .csv.`)}var h=null,v={},_={async load(e,t={}){h=e,v={...t};let s={...t,maxRows:t.maxRows??10},r=await w(e,s);return structuredClone(r)},async parseAll(e){if(!h)throw new Error("No file loaded. Call load(blob, options) first.");let t={...v,maxRows:void 0};e&&e({phase:"parsing",localPercent:0});let s=await w(h,t);return e&&e({phase:"parsing",localPercent:100}),structuredClone(s)}};k.expose(_);
|
|
2
|
+
//# sourceMappingURL=parser.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/parser/worker/parser.worker.ts","../src/core/parser/hash.ts","../src/core/parser/engines/xlsx-parser.ts","../src/core/parser/adapter.ts"],"sourcesContent":["import * as Comlink from 'comlink';\nimport type { RawParseResult } from '../../../types/raw-sheet.js';\nimport type { ParseOptions } from '../types/index.js';\nimport { parseSheet } from '../adapter.js';\n\ntype ProgressCallback = (detail: { phase?: string; localPercent?: number; currentRow?: number; totalRows?: number }) => void;\n\nlet storedBlob: Blob | null = null;\nlet storedOptions: ParseOptions = {};\n\nconst api = {\n async load(blob: Blob, options: ParseOptions = {}): Promise<RawParseResult> {\n storedBlob = blob;\n storedOptions = { ...options };\n const previewOptions: ParseOptions = { ...options, maxRows: options.maxRows ?? 10 };\n const result = await parseSheet(blob, previewOptions);\n return structuredClone(result);\n },\n\n async parseAll(onProgress?: ProgressCallback): Promise<RawParseResult> {\n if (!storedBlob) throw new Error('No file loaded. Call load(blob, options) first.');\n const fullOptions: ParseOptions = { ...storedOptions, maxRows: undefined };\n if (onProgress) onProgress({ phase: 'parsing', localPercent: 0 });\n const result = await parseSheet(storedBlob, fullOptions);\n if (onProgress) onProgress({ phase: 'parsing', localPercent: 100 });\n return structuredClone(result);\n },\n};\n\nComlink.expose(api);\n","import { sha256 } from 'js-sha256';\n\nconst CHUNK_SIZE = 256 * 1024;\n\nexport async function streamHashHex(blob: Blob): Promise<string> {\n const hasher = sha256.create();\n let offset = 0;\n while (offset < blob.size) {\n const chunk = blob.slice(offset, offset + CHUNK_SIZE);\n const buffer = await chunk.arrayBuffer();\n hasher.update(new Uint8Array(buffer));\n offset += CHUNK_SIZE;\n }\n return hasher.hex();\n}\n","import * as XLSX from 'xlsx';\nimport type { RawParseResult, RawSheet, RawSheetRow, RawSheetCell } from '../../../../types/raw-sheet.js';\nimport type { ParseOptions } from '../types/index.js';\nimport { toRawSheetCellValue } from './normalize-cell.js';\n\nexport function parseXlsx(\n arrayBuffer: ArrayBuffer,\n filesize: number,\n documentHash: string,\n sheetNameOverride?: string,\n options: ParseOptions = {},\n): RawParseResult {\n const workbook = XLSX.read(arrayBuffer, { type: 'array', cellDates: true });\n const maxRows = options.maxRows;\n const sheets: Record<string, RawSheet> = {};\n\n for (const name of workbook.SheetNames) {\n const sheet = workbook.Sheets[name];\n if (!sheet) continue;\n const rowsArray = XLSX.utils.sheet_to_json<unknown[]>(sheet, { header: 1, defval: null });\n if (rowsArray.length === 0) {\n sheets[name] = {\n name: sheetNameOverride ?? name,\n filesize,\n documentHash,\n headersCount: 0,\n headers: [],\n rowsCount: 0,\n rows: [],\n };\n continue;\n }\n const headerRow = rowsArray[0] as unknown[];\n const headers = headerRow.map((h) => (h != null ? String(h) : ''));\n const dataRows = rowsArray.slice(1);\n const rowsToTake = maxRows != null ? Math.min(maxRows, dataRows.length) : dataRows.length;\n const rows: RawSheetRow[] = [];\n\n for (let i = 0; i < rowsToTake; i++) {\n const rowValues = dataRows[i] as unknown[] | undefined;\n const cells: RawSheetCell[] = headers.map((key, colIndex) => {\n const raw = rowValues?.[colIndex];\n return { key, value: toRawSheetCellValue(raw) };\n });\n rows.push({ index: i, cells });\n }\n\n sheets[name] = {\n name: sheetNameOverride ?? name,\n filesize,\n documentHash,\n headersCount: headers.length,\n rowsCount: dataRows.length,\n headers,\n rows,\n };\n }\n\n return { sheets };\n}\n","import type { RawParseResult } from '../../types/raw-sheet.js';\nimport type { ParseOptions } from './types/index.js';\nimport { streamHashHex } from './hash.js';\nimport { parseXlsx } from './engines/xlsx-parser.js';\n\nconst XLSX_MIMES = [\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/vnd.ms-excel',\n 'application/vnd.oasis.opendocument.spreadsheet',\n];\nconst CSV_MIME = 'text/csv';\n\nfunction getExtension(blob: Blob, options: ParseOptions): string | null {\n const name = options.fileName ?? (blob as File & { name?: string }).name;\n if (name) {\n const match = name.match(/\\.([a-z0-9]+)$/i);\n if (match) return match[1].toLowerCase();\n }\n const type = blob.type?.toLowerCase();\n if (type === CSV_MIME) return 'csv';\n if (XLSX_MIMES.some((m) => type?.startsWith(m) || type === m)) return type.includes('spreadsheetml') ? 'xlsx' : 'xls';\n return null;\n}\n\nfunction isCsv(ext: string | null, blob: Blob): boolean {\n return ext === 'csv' || blob.type === CSV_MIME;\n}\n\nfunction isXlsx(ext: string | null, blob: Blob): boolean {\n if (ext === 'xlsx' || ext === 'xls' || ext === 'ods') return true;\n return XLSX_MIMES.some((m) => blob.type === m || blob.type?.startsWith(m));\n}\n\nexport async function parseSheet(blob: Blob, options: ParseOptions = {}): Promise<RawParseResult> {\n const filesize = blob.size;\n const documentHash = await streamHashHex(blob);\n const engine = options.engine === 'auto' || options.engine === null || options.engine === undefined ? null : options.engine;\n const ext = getExtension(blob, options);\n\n if (engine === 'csv' || (engine === null && isCsv(ext, blob))) {\n const { parseCsv } = await import('./engines/csv-parser.js');\n const sheetName = options.fileName ?? (blob as File & { name?: string }).name ?? 'Sheet1';\n return parseCsv(blob, filesize, documentHash, sheetName, options);\n }\n\n if (engine === 'xlsx' || (engine === null && isXlsx(ext, blob))) {\n const buffer = await blob.arrayBuffer();\n return parseXlsx(buffer, filesize, documentHash, undefined, options);\n }\n\n if (engine !== null) {\n throw new Error(`Unsupported engine: ${engine}. Use 'xlsx', 'csv', or omit for automatic detection.`);\n }\n\n throw new Error(`Unsupported file type: ${ext ?? blob.type ?? 'unknown'}. Use .xlsx, .xls, .ods or .csv.`);\n}\n"],"mappings":"wCAAA,UAAYA,MAAa,UCAzB,OAAS,UAAAC,MAAc,YAEvB,IAAMC,EAAa,IAAM,KAEzB,eAAsBC,EAAcC,EAA6B,CAC/D,IAAMC,EAASJ,EAAO,OAAO,EACzBK,EAAS,EACb,KAAOA,EAASF,EAAK,MAAM,CAEzB,IAAMG,EAAS,MADDH,EAAK,MAAME,EAAQA,EAASJ,CAAU,EACzB,YAAY,EACvCG,EAAO,OAAO,IAAI,WAAWE,CAAM,CAAC,EACpCD,GAAUJ,CACZ,CACA,OAAOG,EAAO,IAAI,CACpB,CCdA,UAAYG,MAAU,OAKf,SAASC,EACdC,EACAC,EACAC,EACAC,EACAC,EAAwB,CAAC,EACT,CAChB,IAAMC,EAAgB,OAAKL,EAAa,CAAE,KAAM,QAAS,UAAW,EAAK,CAAC,EACpEM,EAAUF,EAAQ,QAClBG,EAAmC,CAAC,EAE1C,QAAWC,KAAQH,EAAS,WAAY,CACtC,IAAMI,EAAQJ,EAAS,OAAOG,CAAI,EAClC,GAAI,CAACC,EAAO,SACZ,IAAMC,EAAiB,QAAM,cAAyBD,EAAO,CAAE,OAAQ,EAAG,OAAQ,IAAK,CAAC,EACxF,GAAIC,EAAU,SAAW,EAAG,CAC1BH,EAAOC,CAAI,EAAI,CACb,KAAML,GAAqBK,EAC3B,SAAAP,EACA,aAAAC,EACA,aAAc,EACd,QAAS,CAAC,EACV,UAAW,EACX,KAAM,CAAC,CACT,EACA,QACF,CAEA,IAAMS,EADYD,EAAU,CAAC,EACH,IAAKE,GAAOA,GAAK,KAAO,OAAOA,CAAC,EAAI,EAAG,EAC3DC,EAAWH,EAAU,MAAM,CAAC,EAC5BI,EAAaR,GAAW,KAAO,KAAK,IAAIA,EAASO,EAAS,MAAM,EAAIA,EAAS,OAC7EE,EAAsB,CAAC,EAE7B,QAASC,EAAI,EAAGA,EAAIF,EAAYE,IAAK,CACnC,IAAMC,EAAYJ,EAASG,CAAC,EACtBE,EAAwBP,EAAQ,IAAI,CAACQ,EAAKC,IAAa,CAC3D,IAAMC,EAAMJ,IAAYG,CAAQ,EAChC,MAAO,CAAE,IAAAD,EAAK,MAAOG,EAAoBD,CAAG,CAAE,CAChD,CAAC,EACDN,EAAK,KAAK,CAAE,MAAOC,EAAG,MAAAE,CAAM,CAAC,CAC/B,CAEAX,EAAOC,CAAI,EAAI,CACb,KAAML,GAAqBK,EAC3B,SAAAP,EACA,aAAAC,EACA,aAAcS,EAAQ,OACtB,UAAWE,EAAS,OACpB,QAAAF,EACA,KAAAI,CACF,CACF,CAEA,MAAO,CAAE,OAAAR,CAAO,CAClB,CCtDA,IAAMgB,EAAa,CACjB,oEACA,2BACA,gDACF,EACMC,EAAW,WAEjB,SAASC,EAAaC,EAAYC,EAAsC,CACtE,IAAMC,EAAOD,EAAQ,UAAaD,EAAkC,KACpE,GAAIE,EAAM,CACR,IAAMC,EAAQD,EAAK,MAAM,iBAAiB,EAC1C,GAAIC,EAAO,OAAOA,EAAM,CAAC,EAAE,YAAY,CACzC,CACA,IAAMC,EAAOJ,EAAK,MAAM,YAAY,EACpC,OAAII,IAASN,EAAiB,MAC1BD,EAAW,KAAMQ,GAAMD,GAAM,WAAWC,CAAC,GAAKD,IAASC,CAAC,EAAUD,EAAK,SAAS,eAAe,EAAI,OAAS,MACzG,IACT,CAEA,SAASE,EAAMC,EAAoBP,EAAqB,CACtD,OAAOO,IAAQ,OAASP,EAAK,OAASF,CACxC,CAEA,SAASU,EAAOD,EAAoBP,EAAqB,CACvD,OAAIO,IAAQ,QAAUA,IAAQ,OAASA,IAAQ,MAAc,GACtDV,EAAW,KAAMQ,GAAML,EAAK,OAASK,GAAKL,EAAK,MAAM,WAAWK,CAAC,CAAC,CAC3E,CAEA,eAAsBI,EAAWT,EAAYC,EAAwB,CAAC,EAA4B,CAChG,IAAMS,EAAWV,EAAK,KAChBW,EAAe,MAAMC,EAAcZ,CAAI,EACvCa,EAASZ,EAAQ,SAAW,QAAUA,EAAQ,SAAW,MAAQA,EAAQ,SAAW,OAAY,KAAOA,EAAQ,OAC/GM,EAAMR,EAAaC,EAAMC,CAAO,EAEtC,GAAIY,IAAW,OAAUA,IAAW,MAAQP,EAAMC,EAAKP,CAAI,EAAI,CAC7D,GAAM,CAAE,SAAAc,CAAS,EAAI,KAAM,QAAO,0BAAyB,EACrDC,EAAYd,EAAQ,UAAaD,EAAkC,MAAQ,SACjF,OAAOc,EAASd,EAAMU,EAAUC,EAAcI,EAAWd,CAAO,CAClE,CAEA,GAAIY,IAAW,QAAWA,IAAW,MAAQL,EAAOD,EAAKP,CAAI,EAAI,CAC/D,IAAMgB,EAAS,MAAMhB,EAAK,YAAY,EACtC,OAAOiB,EAAUD,EAAQN,EAAUC,EAAc,OAAWV,CAAO,CACrE,CAEA,MAAIY,IAAW,KACP,IAAI,MAAM,uBAAuBA,CAAM,uDAAuD,EAGhG,IAAI,MAAM,0BAA0BN,GAAOP,EAAK,MAAQ,SAAS,kCAAkC,CAC3G,CHhDA,IAAIkB,EAA0B,KAC1BC,EAA8B,CAAC,EAE7BC,EAAM,CACV,MAAM,KAAKC,EAAYC,EAAwB,CAAC,EAA4B,CAC1EJ,EAAaG,EACbF,EAAgB,CAAE,GAAGG,CAAQ,EAC7B,IAAMC,EAA+B,CAAE,GAAGD,EAAS,QAASA,EAAQ,SAAW,EAAG,EAC5EE,EAAS,MAAMC,EAAWJ,EAAME,CAAc,EACpD,OAAO,gBAAgBC,CAAM,CAC/B,EAEA,MAAM,SAASE,EAAwD,CACrE,GAAI,CAACR,EAAY,MAAM,IAAI,MAAM,iDAAiD,EAClF,IAAMS,EAA4B,CAAE,GAAGR,EAAe,QAAS,MAAU,EACrEO,GAAYA,EAAW,CAAE,MAAO,UAAW,aAAc,CAAE,CAAC,EAChE,IAAMF,EAAS,MAAMC,EAAWP,EAAYS,CAAW,EACvD,OAAID,GAAYA,EAAW,CAAE,MAAO,UAAW,aAAc,GAAI,CAAC,EAC3D,gBAAgBF,CAAM,CAC/B,CACF,EAEQ,SAAOJ,CAAG","names":["Comlink","sha256","CHUNK_SIZE","streamHashHex","blob","hasher","offset","buffer","XLSX","parseXlsx","arrayBuffer","filesize","documentHash","sheetNameOverride","options","workbook","maxRows","sheets","name","sheet","rowsArray","headers","h","dataRows","rowsToTake","rows","i","rowValues","cells","key","colIndex","raw","toRawSheetCellValue","XLSX_MIMES","CSV_MIME","getExtension","blob","options","name","match","type","m","isCsv","ext","isXlsx","parseSheet","filesize","documentHash","streamHashHex","engine","parseCsv","sheetName","buffer","parseXlsx","storedBlob","storedOptions","api","blob","options","previewOptions","result","parseSheet","onProgress","fullOptions"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as y}from"./chunk-YETPLYYC.js";import*as V from"comlink";function H(e){if(e==null||e==="")return null;if(typeof e=="number"&&!Number.isNaN(e))return e;if(typeof e=="string"){let t=Number(e.replace(/,/g,"").trim());return Number.isNaN(t)?null:t}return typeof e=="boolean"?e?1:0:e instanceof Date?e.getTime():null}function W(e){return e==null?"":typeof e=="string"?e:e instanceof Date?e.toISOString():String(e)}function X(e){if(e==null)return!1;if(typeof e=="boolean")return e;if(typeof e=="string"){let t=e.trim().toLowerCase();if(t==="true"||t==="1"||t==="yes")return!0;if(t==="false"||t==="0"||t==="no"||t==="")return!1}return typeof e=="number"?e!==0&&!Number.isNaN(e):!!e}function q(e){if(e==null||e==="")return null;if(e instanceof Date)return Number.isNaN(e.getTime())?null:e;if(typeof e=="number"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}if(typeof e=="string"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}return null}function h(e,t){if(!t)return e;let n=e.value;switch(t){case"number":n=H(e.value);break;case"string":n=W(e.value);break;case"bool":n=X(e.value);break;case"date":n=q(e.value);break;default:break}return{key:e.key,value:n}}function S(e){return typeof e=="string"?{name:e}:{name:e.name,params:e.params}}function C(e,t,n,r){let o=n.sanitizers;if(!o?.length)return e;let i=e;for(let s of o){let{name:l,params:u}=S(s),p=r(l);p&&(i=p(i,t,u))}return i}function R(e,t,n){let r=t.rowSanitizers;if(!r?.length)return e;let o=e;for(let i of r){if(o===null)break;let{name:s,params:l}=S(i),u=n(s);u&&(o=u(o,l))}return o}function v(e,t,n){let r=t.sheetSanitizers;if(!r?.length)return e;let o=e;for(let i of r){let{name:s,params:l}=S(i),u=n(s);u&&(o=u(o,l))}return o}var J=16,K=1;function Q(e,t){let n=0,r=-1;return o=>{let i=Date.now(),s=e>0?Math.floor(o/e*100):100;(i-n>=J||s-r>=K||o>=e)&&e>0&&(n=i,r=s,t({phase:"sanitizing",localPercent:s,currentRow:o,totalRows:e}))}}function w(e,t,n,r){let o=e.rows.length,i=t.fields,s=r?Q(o,r):()=>{},l=[];for(let p=0;p<o;p++){let d=e.rows[p];if(!d)continue;let Y=d.cells.map(g=>{let c=i[g.key],m=h(g,c?.valueType);return c&&(m=C(m,d,c,n.getCellSanitizer)),m}),B={index:d.index,cells:Y},f=R(B,t,n.getRowSanitizer);f!==null&&l.push(f),s(p+1)}let u={...e,rows:l,rowsCount:l.length};return u=v(u,t,n.getSheetSanitizer),r&&r({phase:"sanitizing",localPercent:100,currentRow:o,totalRows:o}),u}var ee="data";function te(e){if(e instanceof Date&&!Number.isNaN(e.getTime()))return e;if(e==null)return null;let t=String(e).trim();if(!t)return null;let n=Date.parse(t);return Number.isNaN(n)?null:new Date(n)}function ne(e){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${r}`}function re(e){let t=String(e.getHours()).padStart(2,"0"),n=String(e.getMinutes()).padStart(2,"0"),r=String(e.getSeconds()).padStart(2,"0");return`${t}:${n}:${r}`}function oe(e){return`${ne(e)}T${re(e)}`}function ie(e,t,n){let r=te(e.value),o=r?oe(r):"";return{key:e.key,value:o}}function z(e){e(ee,ie,{type:"cell"})}var se="data:data";function ae(e){if(e instanceof Date&&!Number.isNaN(e.getTime()))return e;if(e==null)return null;let t=String(e).trim();if(!t)return null;let n=Date.parse(t);return Number.isNaN(n)?null:new Date(n)}function le(e){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${r}`}function ue(e,t,n){let r=ae(e.value),o=r?le(r):"";return{key:e.key,value:o}}function N(e){e(se,ue,{type:"cell"})}var pe="data:year";function Se(e){if(e instanceof Date&&!Number.isNaN(e.getTime()))return e;if(e==null)return null;let t=String(e).trim();if(!t)return null;let n=Date.parse(t);return Number.isNaN(n)?null:new Date(n)}function de(e,t,n){let r=Se(e.value),o=r?r.getFullYear():"";return{key:e.key,value:o}}function k(e){e(pe,de,{type:"cell"})}var ce="data:timestamp";function me(e){if(e==null)return 0;if(typeof e=="number"&&Number.isFinite(e))return e;if(e instanceof Date&&!Number.isNaN(e.getTime()))return e.getTime();let t=Date.parse(String(e).trim());return Number.isNaN(t)?0:t}function fe(e,t,n){return{key:e.key,value:me(e.value)}}function T(e){e(ce,fe,{type:"cell"})}var ge="data:time";function ye(e){if(e instanceof Date&&!Number.isNaN(e.getTime()))return e;if(e==null)return null;let t=String(e).trim();if(!t)return null;let n=Date.parse(t);return Number.isNaN(n)?null:new Date(n)}function he(e){let t=String(e.getHours()).padStart(2,"0"),n=String(e.getMinutes()).padStart(2,"0"),r=String(e.getSeconds()).padStart(2,"0");return`${t}:${n}:${r}`}function Ce(e,t,n){let r=ye(e.value),o=r?he(r):"";return{key:e.key,value:o}}function _(e){e(ge,Ce,{type:"cell"})}var Re="float";function ve(e){if(e==null)return 0;if(typeof e=="number"&&Number.isFinite(e))return e;let t=String(e).replace(/[^\d.-]/g,""),n=parseFloat(t);return Number.isNaN(n)?0:n}function we(e,t,n){return{key:e.key,value:ve(e.value)}}function x(e){e(Re,we,{type:"cell"})}var ze="number";function Ne(e){if(e==null)return 0;if(typeof e=="number"&&Number.isFinite(e))return Math.trunc(e);let t=String(e).replace(/[^\d-]/g,""),n=parseInt(t,10);return Number.isNaN(n)?0:n}function ke(e,t,n){return{key:e.key,value:Ne(e.value)}}function D(e){e(ze,ke,{type:"cell"})}var Te="number:toStringEnd";function _e(e,t,n){return(e==null?"":String(e).trim().replace(/\D/g,"")).padEnd(t,n)}function xe(e,t,n){let{length:r=4,fill:o="0"}=n??{},i=Math.max(0,Number(r)||0),s=typeof o=="string"&&o.length>0?o[0]:"0";return{key:e.key,value:_e(e.value,i,s)}}function I(e){e(Te,xe,{type:"cell"})}var De="number:toStringId";function Ie(e,t,n){return(e==null?"":String(e).trim().replace(/\D/g,"")).slice(-t).padStart(t,n)}function be(e,t,n){let{length:r=4,fill:o="0"}=n??{},i=Math.max(0,Number(r)||0),s=typeof o=="string"&&o.length>0?o[0]:"0";return{key:e.key,value:Ie(e.value,i,s)}}function b(e){e(De,be,{type:"cell"})}var Ee="replace-from-regex";function Pe(e,t,n,r){if(e==null)return"";let o=String(e);if(!t)return o;try{let i=new RegExp(t,n);return o.replace(i,r)}catch{return o}}function Fe(e,t,n){let{pattern:r="",flags:o="g",replacement:i=""}=n??{},s=Pe(e.value,r,o,String(i));return{key:e.key,value:s}}function E(e){e(Ee,Fe,{type:"cell"})}var je="replace-from-str";function Le(e,t,n){if(e==null)return"";let r=String(e);return t===""?r:r.split(t).join(n)}function Ae(e,t,n){let{search:r="",replacement:o=""}=n??{},i=Le(e.value,r,String(o));return{key:e.key,value:i}}function P(e){e(je,Ae,{type:"cell"})}var Me="nullToEmpty";function Oe(e){return e??""}function Ge(e,t,n){return{key:e.key,value:Oe(e.value)}}function F(e){e(Me,Ge,{type:"cell"})}var Ze="string:spaces";function $e(e){return e==null?"":String(e).replace(/\s+/g," ").trim()}function Ue(e,t,n){return{key:e.key,value:$e(e.value)}}function j(e){e(Ze,Ue,{type:"cell"})}var Ve="string:minusculas";function Ye(e){return e==null?"":String(e).toLowerCase()}function Be(e,t,n){return{key:e.key,value:Ye(e.value)}}function L(e){e(Ve,Be,{type:"cell"})}var He="string:maxLength";function We(e,t){if(e==null)return"";let n=String(e);return t>0?n.slice(0,t):n}function Xe(e,t,n){let{maxLength:r=0}=n??{},o=Math.max(0,Number(r)||0);return{key:e.key,value:We(e.value,o)}}function A(e){e(He,Xe,{type:"cell"})}var qe="string:trimAdd";function Je(e){return e==null?"":String(e)}function Ke(e,t,n){let{length:r=0,fill:o=" "}=n??{},i=Math.max(0,Number(r)||0),s=Je(e.value),l=i>0?s.padEnd(i,o):s;return{key:e.key,value:l}}function M(e){e(qe,Ke,{type:"cell"})}var Qe="string:trimPre";function et(e){return e==null?"":String(e)}function tt(e,t,n){let{length:r=0,fill:o=" "}=n??{},i=Math.max(0,Number(r)||0),s=et(e.value),l=i>0?s.padStart(i,o):s;return{key:e.key,value:l}}function O(e){e(Qe,tt,{type:"cell"})}var nt="string:mayusculas";function rt(e){return e==null?"":String(e).toUpperCase()}function ot(e,t,n){return{key:e.key,value:rt(e.value)}}function G(e){e(nt,ot,{type:"cell"})}var it="trim";function st(e){return e==null?"":typeof e=="string"?e.trim():String(e).trim()}function at(e,t,n){return{key:e.key,value:st(e.value)}}function Z(e){e(it,at,{type:"cell"})}var $=new y;function a(e){e((t,n,r)=>$.register(t,n,r))}a(Z);a(D);a(x);a(b);a(I);a(z);a(k);a(N);a(_);a(T);a(L);a(G);a(A);a(M);a(O);a(j);a(F);a(E);a(P);function lt(e){let t=$.get(e);if(!(!t||t.type!=="cell"))return t.fn}function ut(e){}function pt(e){}function U(){return{getCellSanitizer:lt,getRowSanitizer:ut,getSheetSanitizer:pt}}var St={async sanitize(e,t,n,r){let o=U();return w(e,t,o,r)}};V.expose(St);
|
|
2
|
+
//# sourceMappingURL=sanitizer.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/sanitizer/worker/sanitizer.worker.ts","../src/core/sanitizer/runner/casting.ts","../src/core/sanitizer/runner/resolve-sanitizer-ref.ts","../src/core/sanitizer/runner/cell-sanitizers.ts","../src/core/sanitizer/runner/row-sanitizers.ts","../src/core/sanitizer/runner/sheet-sanitizers.ts","../src/core/sanitizer/runner/run-sanitization.ts","../src/utils/controller/date/cell-date-format-sanitizer.ts","../src/utils/controller/date/cell-date-only-sanitizer.ts","../src/utils/controller/date/cell-date-year-sanitizer.ts","../src/utils/controller/date/cell-timestamp-sanitizer.ts","../src/utils/controller/date/cell-time-only-sanitizer.ts","../src/utils/controller/number/cell-number-float-sanitizer.ts","../src/utils/controller/number/cell-number-int-sanitizer.ts","../src/utils/controller/number/cell-number-to-string-end-sanitizer.ts","../src/utils/controller/number/cell-number-to-string-id-sanitizer.ts","../src/utils/controller/replace/cell-replace-regex-sanitizer.ts","../src/utils/controller/replace/cell-replace-str-sanitizer.ts","../src/utils/controller/string/cell-null-to-empty-sanitizer.ts","../src/utils/controller/string/cell-string-collapse-spaces-sanitizer.ts","../src/utils/controller/string/cell-string-lower-sanitizer.ts","../src/utils/controller/string/cell-string-max-length-sanitizer.ts","../src/utils/controller/string/cell-string-pad-end-sanitizer.ts","../src/utils/controller/string/cell-string-pad-start-sanitizer.ts","../src/utils/controller/string/cell-string-upper-sanitizer.ts","../src/utils/controller/string/cell-trim-sanitizer.ts","../src/core/sanitizer/worker/worker-registry.ts"],"sourcesContent":["import * as Comlink from 'comlink';\nimport type { ConvertedSheet } from '../../convert/types/converted-sheet.js';\nimport type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { SanitizedSheet } from '../types/sanitized-sheet.js';\nimport type { SanitizerProgressDetail } from '../types/sanitizer-progress.js';\nimport { runSanitization } from '../runner/run-sanitization.js';\nimport { getSanitizerGetters } from './worker-registry.js';\n\ntype ProgressCallback = (detail: SanitizerProgressDetail) => void;\n\nconst api = {\n async sanitize(\n convertedSheet: ConvertedSheet,\n sheetLayout: SheetLayout,\n _options?: Record<string, unknown>,\n onProgress?: ProgressCallback,\n ): Promise<SanitizedSheet> {\n const getters = getSanitizerGetters();\n return runSanitization(convertedSheet, sheetLayout, getters, onProgress);\n },\n};\n\nComlink.expose(api);\n","import type { FieldValueType } from '../../../types/sheet-layout.js';\nimport type { RawSheetCellValue } from '../../../types/raw-sheet.js';\nimport type { ConvertedSheetCell } from '../../convert/types/converted-sheet.js';\n\nfunction toNumber(v: unknown): number | null {\n if (v === null || v === undefined || v === '') return null;\n if (typeof v === 'number' && !Number.isNaN(v)) return v;\n if (typeof v === 'string') {\n const n = Number(v.replace(/,/g, '').trim());\n return Number.isNaN(n) ? null : n;\n }\n if (typeof v === 'boolean') return v ? 1 : 0;\n if (v instanceof Date) return v.getTime();\n return null;\n}\n\nfunction toString(v: unknown): string {\n if (v === null || v === undefined) return '';\n if (typeof v === 'string') return v;\n if (v instanceof Date) return v.toISOString();\n return String(v);\n}\n\nfunction toBool(v: unknown): boolean {\n if (v === null || v === undefined) return false;\n if (typeof v === 'boolean') return v;\n if (typeof v === 'string') {\n const s = v.trim().toLowerCase();\n if (s === 'true' || s === '1' || s === 'yes') return true;\n if (s === 'false' || s === '0' || s === 'no' || s === '') return false;\n }\n if (typeof v === 'number') return v !== 0 && !Number.isNaN(v);\n return Boolean(v);\n}\n\nfunction toDate(v: unknown): Date | null {\n if (v === null || v === undefined || v === '') return null;\n if (v instanceof Date) return Number.isNaN(v.getTime()) ? null : v;\n if (typeof v === 'number') {\n const d = new Date(v);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n if (typeof v === 'string') {\n const d = new Date(v);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n return null;\n}\n\nexport function applyValueTypeCasting(\n cell: ConvertedSheetCell,\n valueType: FieldValueType | undefined,\n): ConvertedSheetCell {\n if (!valueType) return cell;\n let value: RawSheetCellValue = cell.value;\n switch (valueType) {\n case 'number':\n value = toNumber(cell.value);\n break;\n case 'string':\n value = toString(cell.value);\n break;\n case 'bool':\n value = toBool(cell.value);\n break;\n case 'date':\n value = toDate(cell.value);\n break;\n default:\n break;\n }\n return { key: cell.key, value };\n}\n","import type { ValidatorOrWithParams } from '../../../types/sheet-layout.js';\n\nexport interface ResolvedSanitizerRef {\n readonly name: string;\n readonly params?: Readonly<Record<string, unknown>>;\n}\n\nexport function resolveSanitizerRef(ref: ValidatorOrWithParams): ResolvedSanitizerRef {\n if (typeof ref === 'string') return { name: ref };\n return { name: ref.name, params: ref.params };\n}\n","import type { SheetLayoutField } from '../../../types/sheet-layout.js';\nimport type { ConvertedSheetCell, ConvertedSheetRow } from '../../convert/types/converted-sheet.js';\nimport { resolveSanitizerRef } from './resolve-sanitizer-ref.js';\n\nexport type CellSanitizerFn = (\n cell: ConvertedSheetCell,\n row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>,\n) => ConvertedSheetCell;\n\nexport type GetCellSanitizer = (name: string) => CellSanitizerFn | undefined;\n\nexport function runCellSanitizers(\n cell: ConvertedSheetCell,\n row: ConvertedSheetRow,\n field: SheetLayoutField,\n getSanitizer: GetCellSanitizer,\n): ConvertedSheetCell {\n const list = field.sanitizers;\n if (!list?.length) return cell;\n let current: ConvertedSheetCell = cell;\n for (const ref of list) {\n const { name, params } = resolveSanitizerRef(ref);\n const fn = getSanitizer(name);\n if (fn) current = fn(current, row, params);\n }\n return current;\n}\n","import type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { ConvertedSheetRow } from '../../convert/types/converted-sheet.js';\nimport { resolveSanitizerRef } from './resolve-sanitizer-ref.js';\n\nexport type RowSanitizerFn = (\n row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>,\n) => ConvertedSheetRow | null;\n\nexport type GetRowSanitizer = (name: string) => RowSanitizerFn | undefined;\n\nexport function runRowSanitizers(\n row: ConvertedSheetRow,\n sheetLayout: SheetLayout,\n getSanitizer: GetRowSanitizer,\n): ConvertedSheetRow | null {\n const list = sheetLayout.rowSanitizers;\n if (!list?.length) return row;\n let current: ConvertedSheetRow | null = row;\n for (const ref of list) {\n if (current === null) break;\n const { name, params } = resolveSanitizerRef(ref);\n const fn = getSanitizer(name);\n if (fn) current = fn(current, params);\n }\n return current;\n}\n","import type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { ConvertedSheet } from '../../convert/types/converted-sheet.js';\nimport { resolveSanitizerRef } from './resolve-sanitizer-ref.js';\n\nexport type SheetSanitizerFn = (\n sheet: ConvertedSheet,\n params?: Readonly<Record<string, unknown>>,\n) => ConvertedSheet;\n\nexport type GetSheetSanitizer = (name: string) => SheetSanitizerFn | undefined;\n\nexport function runSheetSanitizers(\n sheet: ConvertedSheet,\n sheetLayout: SheetLayout,\n getSanitizer: GetSheetSanitizer,\n): ConvertedSheet {\n const list = sheetLayout.sheetSanitizers;\n if (!list?.length) return sheet;\n let current = sheet;\n for (const ref of list) {\n const { name, params } = resolveSanitizerRef(ref);\n const fn = getSanitizer(name);\n if (fn) current = fn(current, params);\n }\n return current;\n}\n","import type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { ConvertedSheet, ConvertedSheetRow, ConvertedSheetCell } from '../../convert/types/converted-sheet.js';\nimport type { SanitizedSheet } from '../types/sanitized-sheet.js';\nimport type { SanitizerProgressDetail } from '../types/sanitizer-progress.js';\nimport { applyValueTypeCasting } from './casting.js';\nimport { runCellSanitizers } from './cell-sanitizers.js';\nimport { runRowSanitizers } from './row-sanitizers.js';\nimport { runSheetSanitizers } from './sheet-sanitizers.js';\n\nconst THROTTLE_MS = 16;\nconst THROTTLE_PERCENT = 1;\n\nexport interface SanitizerGetters {\n getCellSanitizer: (name: string) => ((cell: ConvertedSheetCell, row: ConvertedSheetRow, p?: Readonly<Record<string, unknown>>) => ConvertedSheetCell) | undefined;\n getRowSanitizer: (name: string) => ((row: ConvertedSheetRow, p?: Readonly<Record<string, unknown>>) => ConvertedSheetRow | null) | undefined;\n getSheetSanitizer: (name: string) => ((sheet: ConvertedSheet, p?: Readonly<Record<string, unknown>>) => ConvertedSheet) | undefined;\n}\n\nfunction createThrottledProgress(\n totalRows: number,\n onProgress: (d: SanitizerProgressDetail) => void,\n): (processed: number) => void {\n let lastTime = 0;\n let lastPercent = -1;\n return (processed: number) => {\n const now = Date.now();\n const localPercent = totalRows > 0 ? Math.floor((processed / totalRows) * 100) : 100;\n const shouldEmit = now - lastTime >= THROTTLE_MS || localPercent - lastPercent >= THROTTLE_PERCENT || processed >= totalRows;\n if (shouldEmit && totalRows > 0) {\n lastTime = now;\n lastPercent = localPercent;\n onProgress({\n phase: 'sanitizing',\n localPercent,\n currentRow: processed,\n totalRows,\n });\n }\n };\n}\n\nexport function runSanitization(\n convertedSheet: ConvertedSheet,\n sheetLayout: SheetLayout,\n getters: SanitizerGetters,\n onProgress?: (d: SanitizerProgressDetail) => void,\n): SanitizedSheet {\n const totalRows = convertedSheet.rows.length;\n const fields = sheetLayout.fields;\n const reportProgress = onProgress ? createThrottledProgress(totalRows, onProgress) : () => {};\n\n const outRows: ConvertedSheetRow[] = [];\n for (let i = 0; i < totalRows; i++) {\n const row = convertedSheet.rows[i];\n if (!row) continue;\n const cells: ConvertedSheetCell[] = row.cells.map((cell) => {\n const field = fields[cell.key];\n let c = applyValueTypeCasting(cell, field?.valueType);\n if (field) c = runCellSanitizers(c, row, field, getters.getCellSanitizer);\n return c;\n });\n const updatedRow: ConvertedSheetRow = { index: row.index, cells };\n const afterRow = runRowSanitizers(updatedRow, sheetLayout, getters.getRowSanitizer);\n if (afterRow !== null) outRows.push(afterRow);\n reportProgress(i + 1);\n }\n\n let sheet: ConvertedSheet = {\n ...convertedSheet,\n rows: outRows,\n rowsCount: outRows.length,\n };\n sheet = runSheetSanitizers(sheet, sheetLayout, getters.getSheetSanitizer);\n if (onProgress) onProgress({ phase: 'sanitizing', localPercent: 100, currentRow: totalRows, totalRows });\n return sheet as SanitizedSheet;\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const DATE_FORMAT_SANITIZER_ID = 'data';\n\nfunction parseToDate(value: unknown): Date | null {\n if (value instanceof Date && !Number.isNaN(value.getTime())) return value;\n if (value === null || value === undefined) return null;\n const s = String(value).trim();\n if (!s) return null;\n const ms = Date.parse(s);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nfunction toISODateString(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n}\n\nfunction toISOTimeString(d: Date): string {\n const h = String(d.getHours()).padStart(2, '0');\n const min = String(d.getMinutes()).padStart(2, '0');\n const s = String(d.getSeconds()).padStart(2, '0');\n return `${h}:${min}:${s}`;\n}\n\nfunction toFormatted(d: Date): string {\n return `${toISODateString(d)}T${toISOTimeString(d)}`;\n}\n\nexport function cellDateFormatSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const d = parseToDate(cell.value);\n const out = d ? toFormatted(d) : '';\n return { key: cell.key, value: out };\n}\n\nexport function registerDateFormatSanitizer(\n register: (name: string, fn: typeof cellDateFormatSanitizer, options: { type: 'cell' }) => void\n): void {\n register(DATE_FORMAT_SANITIZER_ID, cellDateFormatSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const DATE_ONLY_SANITIZER_ID = 'data:data';\n\nfunction parseToDate(value: unknown): Date | null {\n if (value instanceof Date && !Number.isNaN(value.getTime())) return value;\n if (value === null || value === undefined) return null;\n const s = String(value).trim();\n if (!s) return null;\n const ms = Date.parse(s);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nfunction toISODateString(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n}\n\nexport function cellDateOnlySanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const d = parseToDate(cell.value);\n const out = d ? toISODateString(d) : '';\n return { key: cell.key, value: out };\n}\n\nexport function registerDateOnlySanitizer(\n register: (name: string, fn: typeof cellDateOnlySanitizer, options: { type: 'cell' }) => void\n): void {\n register(DATE_ONLY_SANITIZER_ID, cellDateOnlySanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const DATE_YEAR_SANITIZER_ID = 'data:year';\n\nfunction parseToDate(value: unknown): Date | null {\n if (value instanceof Date && !Number.isNaN(value.getTime())) return value;\n if (value === null || value === undefined) return null;\n const s = String(value).trim();\n if (!s) return null;\n const ms = Date.parse(s);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nexport function cellDateYearSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const d = parseToDate(cell.value);\n const out = d ? d.getFullYear() : '';\n return { key: cell.key, value: out };\n}\n\nexport function registerDateYearSanitizer(\n register: (name: string, fn: typeof cellDateYearSanitizer, options: { type: 'cell' }) => void\n): void {\n register(DATE_YEAR_SANITIZER_ID, cellDateYearSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const TIMESTAMP_SANITIZER_ID = 'data:timestamp';\n\nfunction parseToTimestamp(value: unknown): number {\n if (value === null || value === undefined) return 0;\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (value instanceof Date && !Number.isNaN(value.getTime())) return value.getTime();\n const ms = Date.parse(String(value).trim());\n return Number.isNaN(ms) ? 0 : ms;\n}\n\nexport function cellTimestampSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n return { key: cell.key, value: parseToTimestamp(cell.value) };\n}\n\nexport function registerTimestampSanitizer(\n register: (name: string, fn: typeof cellTimestampSanitizer, options: { type: 'cell' }) => void\n): void {\n register(TIMESTAMP_SANITIZER_ID, cellTimestampSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const TIME_ONLY_SANITIZER_ID = 'data:time';\n\nfunction parseToDate(value: unknown): Date | null {\n if (value instanceof Date && !Number.isNaN(value.getTime())) return value;\n if (value === null || value === undefined) return null;\n const s = String(value).trim();\n if (!s) return null;\n const ms = Date.parse(s);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nfunction toISOTimeString(d: Date): string {\n const h = String(d.getHours()).padStart(2, '0');\n const min = String(d.getMinutes()).padStart(2, '0');\n const s = String(d.getSeconds()).padStart(2, '0');\n return `${h}:${min}:${s}`;\n}\n\nexport function cellTimeOnlySanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const d = parseToDate(cell.value);\n const out = d ? toISOTimeString(d) : '';\n return { key: cell.key, value: out };\n}\n\nexport function registerTimeOnlySanitizer(\n register: (name: string, fn: typeof cellTimeOnlySanitizer, options: { type: 'cell' }) => void\n): void {\n register(TIME_ONLY_SANITIZER_ID, cellTimeOnlySanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const NUMBER_FLOAT_SANITIZER_ID = 'float';\n\nfunction toFloat(value: unknown): number {\n if (value === null || value === undefined) return 0;\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n const s = String(value).replace(/[^\\d.-]/g, '');\n const parsed = parseFloat(s);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\nexport function cellNumberFloatSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n return { key: cell.key, value: toFloat(cell.value) };\n}\n\nexport function registerNumberFloatSanitizer(\n register: (name: string, fn: typeof cellNumberFloatSanitizer, options: { type: 'cell' }) => void\n): void {\n register(NUMBER_FLOAT_SANITIZER_ID, cellNumberFloatSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const NUMBER_INT_SANITIZER_ID = 'number';\n\nfunction toInt(value: unknown): number {\n if (value === null || value === undefined) return 0;\n if (typeof value === 'number' && Number.isFinite(value)) return Math.trunc(value);\n const s = String(value).replace(/[^\\d-]/g, '');\n const parsed = parseInt(s, 10);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\nexport function cellNumberIntSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n return { key: cell.key, value: toInt(cell.value) };\n}\n\nexport function registerNumberIntSanitizer(\n register: (name: string, fn: typeof cellNumberIntSanitizer, options: { type: 'cell' }) => void\n): void {\n register(NUMBER_INT_SANITIZER_ID, cellNumberIntSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const NUMBER_TO_STRING_END_SANITIZER_ID = 'number:toStringEnd';\n\ntype Params = { length?: number; fill?: string };\n\nfunction padEnd(value: unknown, length: number, fill: string): string {\n const raw = value === null || value === undefined ? '' : String(value).trim().replace(/\\D/g, '');\n return raw.padEnd(length, fill);\n}\n\nexport function cellNumberToStringEndSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const { length = 4, fill = '0' } = (params ?? {}) as Params;\n const safeLength = Math.max(0, Number(length) || 0);\n const safeFill = typeof fill === 'string' && fill.length > 0 ? fill[0]! : '0';\n return { key: cell.key, value: padEnd(cell.value, safeLength, safeFill) };\n}\n\nexport function registerNumberToStringEndSanitizer(\n register: (\n name: string,\n fn: typeof cellNumberToStringEndSanitizer,\n options: { type: 'cell' }\n ) => void\n): void {\n register(NUMBER_TO_STRING_END_SANITIZER_ID, cellNumberToStringEndSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const NUMBER_TO_STRING_ID_SANITIZER_ID = 'number:toStringId';\n\ntype Params = { length?: number; fill?: string };\n\nfunction padStart(value: unknown, length: number, fill: string): string {\n const raw = value === null || value === undefined ? '' : String(value).trim().replace(/\\D/g, '');\n const num = raw.slice(-length);\n return num.padStart(length, fill);\n}\n\nexport function cellNumberToStringIdSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const { length = 4, fill = '0' } = (params ?? {}) as Params;\n const safeLength = Math.max(0, Number(length) || 0);\n const safeFill = typeof fill === 'string' && fill.length > 0 ? fill[0]! : '0';\n return { key: cell.key, value: padStart(cell.value, safeLength, safeFill) };\n}\n\nexport function registerNumberToStringIdSanitizer(\n register: (\n name: string,\n fn: typeof cellNumberToStringIdSanitizer,\n options: { type: 'cell' }\n ) => void\n): void {\n register(NUMBER_TO_STRING_ID_SANITIZER_ID, cellNumberToStringIdSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const REPLACE_FROM_REGEX_SANITIZER_ID = 'replace-from-regex';\n\ntype Params = { pattern?: string; flags?: string; replacement?: string };\n\nfunction replaceByRegex(\n value: unknown,\n pattern: string,\n flags: string,\n replacement: string\n): string {\n if (value === null || value === undefined) return '';\n const s = String(value);\n if (!pattern) return s;\n try {\n const re = new RegExp(pattern, flags);\n return s.replace(re, replacement);\n } catch {\n return s;\n }\n}\n\nexport function cellReplaceRegexSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const { pattern = '', flags = 'g', replacement = '' } = (params ?? {}) as Params;\n const out = replaceByRegex(cell.value, pattern, flags, String(replacement));\n return { key: cell.key, value: out };\n}\n\nexport function registerReplaceRegexSanitizer(\n register: (name: string, fn: typeof cellReplaceRegexSanitizer, options: { type: 'cell' }) => void\n): void {\n register(REPLACE_FROM_REGEX_SANITIZER_ID, cellReplaceRegexSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const REPLACE_FROM_STR_SANITIZER_ID = 'replace-from-str';\n\ntype Params = { search?: string; replacement?: string };\n\nfunction replaceByStr(value: unknown, search: string, replacement: string): string {\n if (value === null || value === undefined) return '';\n const s = String(value);\n if (search === '') return s;\n return s.split(search).join(replacement);\n}\n\nexport function cellReplaceStrSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const { search = '', replacement = '' } = (params ?? {}) as Params;\n const out = replaceByStr(cell.value, search, String(replacement));\n return { key: cell.key, value: out };\n}\n\nexport function registerReplaceStrSanitizer(\n register: (name: string, fn: typeof cellReplaceStrSanitizer, options: { type: 'cell' }) => void\n): void {\n register(REPLACE_FROM_STR_SANITIZER_ID, cellReplaceStrSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const NULL_TO_EMPTY_SANITIZER_ID = 'nullToEmpty';\n\nfunction nullToEmpty(value: unknown): string | number | boolean | Date {\n if (value === null || value === undefined) return '';\n return value as string | number | boolean | Date;\n}\n\nexport function cellNullToEmptySanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n return { key: cell.key, value: nullToEmpty(cell.value) };\n}\n\nexport function registerNullToEmptySanitizer(\n register: (name: string, fn: typeof cellNullToEmptySanitizer, options: { type: 'cell' }) => void\n): void {\n register(NULL_TO_EMPTY_SANITIZER_ID, cellNullToEmptySanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const STRING_COLLAPSE_SPACES_SANITIZER_ID = 'string:spaces';\n\nfunction collapseSpaces(value: unknown): string {\n if (value === null || value === undefined) return '';\n return String(value).replace(/\\s+/g, ' ').trim();\n}\n\nexport function cellStringCollapseSpacesSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n return { key: cell.key, value: collapseSpaces(cell.value) };\n}\n\nexport function registerStringCollapseSpacesSanitizer(\n register: (\n name: string,\n fn: typeof cellStringCollapseSpacesSanitizer,\n options: { type: 'cell' }\n ) => void\n): void {\n register(STRING_COLLAPSE_SPACES_SANITIZER_ID, cellStringCollapseSpacesSanitizer, {\n type: 'cell',\n });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const STRING_LOWER_SANITIZER_ID = 'string:minusculas';\n\nfunction toLower(value: unknown): string {\n if (value === null || value === undefined) return '';\n return String(value).toLowerCase();\n}\n\nexport function cellStringLowerSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n return { key: cell.key, value: toLower(cell.value) };\n}\n\nexport function registerStringLowerSanitizer(\n register: (name: string, fn: typeof cellStringLowerSanitizer, options: { type: 'cell' }) => void\n): void {\n register(STRING_LOWER_SANITIZER_ID, cellStringLowerSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const STRING_MAX_LENGTH_SANITIZER_ID = 'string:maxLength';\n\ntype Params = { maxLength?: number };\n\nfunction truncate(value: unknown, maxLength: number): string {\n if (value === null || value === undefined) return '';\n const s = String(value);\n return maxLength > 0 ? s.slice(0, maxLength) : s;\n}\n\nexport function cellStringMaxLengthSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const { maxLength = 0 } = (params ?? {}) as Params;\n const safe = Math.max(0, Number(maxLength) || 0);\n return { key: cell.key, value: truncate(cell.value, safe) };\n}\n\nexport function registerStringMaxLengthSanitizer(\n register: (\n name: string,\n fn: typeof cellStringMaxLengthSanitizer,\n options: { type: 'cell' }\n ) => void\n): void {\n register(STRING_MAX_LENGTH_SANITIZER_ID, cellStringMaxLengthSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const STRING_PAD_END_SANITIZER_ID = 'string:trimAdd';\n\ntype Params = { length?: number; fill?: string };\n\nfunction toStringValue(value: unknown): string {\n if (value === null || value === undefined) return '';\n return String(value);\n}\n\nexport function cellStringPadEndSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const { length = 0, fill = ' ' } = (params ?? {}) as Params;\n const safeLength = Math.max(0, Number(length) || 0);\n const s = toStringValue(cell.value);\n const out = safeLength > 0 ? s.padEnd(safeLength, fill) : s;\n return { key: cell.key, value: out };\n}\n\nexport function registerStringPadEndSanitizer(\n register: (name: string, fn: typeof cellStringPadEndSanitizer, options: { type: 'cell' }) => void\n): void {\n register(STRING_PAD_END_SANITIZER_ID, cellStringPadEndSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const STRING_PAD_START_SANITIZER_ID = 'string:trimPre';\n\ntype Params = { length?: number; fill?: string };\n\nfunction toStringValue(value: unknown): string {\n if (value === null || value === undefined) return '';\n return String(value);\n}\n\nexport function cellStringPadStartSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n const { length = 0, fill = ' ' } = (params ?? {}) as Params;\n const safeLength = Math.max(0, Number(length) || 0);\n const s = toStringValue(cell.value);\n const out = safeLength > 0 ? s.padStart(safeLength, fill) : s;\n return { key: cell.key, value: out };\n}\n\nexport function registerStringPadStartSanitizer(\n register: (\n name: string,\n fn: typeof cellStringPadStartSanitizer,\n options: { type: 'cell' }\n ) => void\n): void {\n register(STRING_PAD_START_SANITIZER_ID, cellStringPadStartSanitizer, { type: 'cell' });\n}\n","import type {\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../../core/convert/types/converted-sheet.js';\n\nexport const STRING_UPPER_SANITIZER_ID = 'string:mayusculas';\n\nfunction toUpper(value: unknown): string {\n if (value === null || value === undefined) return '';\n return String(value).toUpperCase();\n}\n\nexport function cellStringUpperSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>\n): ConvertedSheetCell {\n return { key: cell.key, value: toUpper(cell.value) };\n}\n\nexport function registerStringUpperSanitizer(\n register: (name: string, fn: typeof cellStringUpperSanitizer, options: { type: 'cell' }) => void\n): void {\n register(STRING_UPPER_SANITIZER_ID, cellStringUpperSanitizer, { type: 'cell' });\n}\n","import type { ConvertedSheetCell, ConvertedSheetRow } from '../../../core/convert/types/converted-sheet.js';\n\nexport const TRIM_SANITIZER_ID = 'trim';\n\nfunction trimValue(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value.trim();\n return String(value).trim();\n}\n\nexport function cellTrimSanitizer(\n cell: ConvertedSheetCell,\n _row: ConvertedSheetRow,\n _params?: Readonly<Record<string, unknown>>,\n): ConvertedSheetCell {\n return { key: cell.key, value: trimValue(cell.value) };\n}\n\nexport function registerTrimSanitizer(\n register: (name: string, fn: typeof cellTrimSanitizer, options: { type: 'cell' }) => void,\n): void {\n register(TRIM_SANITIZER_ID, cellTrimSanitizer, { type: 'cell' });\n}\n","import { Registry } from '../../../shared/registry/index.js';\nimport { registerDateFormatSanitizer } from '../../../utils/controller/date/cell-date-format-sanitizer.js';\nimport { registerDateOnlySanitizer } from '../../../utils/controller/date/cell-date-only-sanitizer.js';\nimport { registerDateYearSanitizer } from '../../../utils/controller/date/cell-date-year-sanitizer.js';\nimport { registerTimestampSanitizer } from '../../../utils/controller/date/cell-timestamp-sanitizer.js';\nimport { registerTimeOnlySanitizer } from '../../../utils/controller/date/cell-time-only-sanitizer.js';\nimport { registerNumberFloatSanitizer } from '../../../utils/controller/number/cell-number-float-sanitizer.js';\nimport { registerNumberIntSanitizer } from '../../../utils/controller/number/cell-number-int-sanitizer.js';\nimport { registerNumberToStringEndSanitizer } from '../../../utils/controller/number/cell-number-to-string-end-sanitizer.js';\nimport { registerNumberToStringIdSanitizer } from '../../../utils/controller/number/cell-number-to-string-id-sanitizer.js';\nimport { registerReplaceRegexSanitizer } from '../../../utils/controller/replace/cell-replace-regex-sanitizer.js';\nimport { registerReplaceStrSanitizer } from '../../../utils/controller/replace/cell-replace-str-sanitizer.js';\nimport { registerNullToEmptySanitizer } from '../../../utils/controller/string/cell-null-to-empty-sanitizer.js';\nimport { registerStringCollapseSpacesSanitizer } from '../../../utils/controller/string/cell-string-collapse-spaces-sanitizer.js';\nimport { registerStringLowerSanitizer } from '../../../utils/controller/string/cell-string-lower-sanitizer.js';\nimport { registerStringMaxLengthSanitizer } from '../../../utils/controller/string/cell-string-max-length-sanitizer.js';\nimport { registerStringPadEndSanitizer } from '../../../utils/controller/string/cell-string-pad-end-sanitizer.js';\nimport { registerStringPadStartSanitizer } from '../../../utils/controller/string/cell-string-pad-start-sanitizer.js';\nimport { registerStringUpperSanitizer } from '../../../utils/controller/string/cell-string-upper-sanitizer.js';\nimport { registerTrimSanitizer } from '../../../utils/controller/string/cell-trim-sanitizer.js';\nimport type {\n ConvertedSheet,\n ConvertedSheetCell,\n ConvertedSheetRow,\n} from '../../convert/types/converted-sheet.js';\n\ntype CellSanitizerFn = (\n cell: ConvertedSheetCell,\n row: ConvertedSheetRow,\n p?: Readonly<Record<string, unknown>>\n) => ConvertedSheetCell;\n\ntype RowSanitizerFn = (\n row: ConvertedSheetRow,\n p?: Readonly<Record<string, unknown>>\n) => ConvertedSheetRow | null;\n\ntype SheetSanitizerFn = (\n sheet: ConvertedSheet,\n p?: Readonly<Record<string, unknown>>\n) => ConvertedSheet;\n\nconst registry = new Registry<(...args: unknown[]) => unknown>();\n\nfunction register(\n reg: (r: (n: string, fn: CellSanitizerFn, o: { type: 'cell' }) => void) => void\n): void {\n reg((name, fn, opts) => registry.register(name, fn, opts));\n}\n\nregister(registerTrimSanitizer);\nregister(registerNumberIntSanitizer);\nregister(registerNumberFloatSanitizer);\nregister(registerNumberToStringIdSanitizer);\nregister(registerNumberToStringEndSanitizer);\nregister(registerDateFormatSanitizer);\nregister(registerDateYearSanitizer);\nregister(registerDateOnlySanitizer);\nregister(registerTimeOnlySanitizer);\nregister(registerTimestampSanitizer);\nregister(registerStringLowerSanitizer);\nregister(registerStringUpperSanitizer);\nregister(registerStringMaxLengthSanitizer);\nregister(registerStringPadEndSanitizer);\nregister(registerStringPadStartSanitizer);\nregister(registerStringCollapseSpacesSanitizer);\nregister(registerNullToEmptySanitizer);\nregister(registerReplaceRegexSanitizer);\nregister(registerReplaceStrSanitizer);\n\nfunction getCellSanitizer(name: string): CellSanitizerFn | undefined {\n const entry = registry.get(name);\n if (!entry || entry.type !== 'cell') return undefined;\n return entry.fn as CellSanitizerFn;\n}\n\nfunction getRowSanitizer(_name: string): RowSanitizerFn | undefined {\n return undefined;\n}\n\nfunction getSheetSanitizer(_name: string): SheetSanitizerFn | undefined {\n return undefined;\n}\n\nexport function getSanitizerGetters(): {\n getCellSanitizer: (name: string) => CellSanitizerFn | undefined;\n getRowSanitizer: (name: string) => RowSanitizerFn | undefined;\n getSheetSanitizer: (name: string) => SheetSanitizerFn | undefined;\n} {\n return { getCellSanitizer, getRowSanitizer, getSheetSanitizer };\n}\n"],"mappings":"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","names":["Comlink","toNumber","v","n","toString","toBool","s","toDate","d","applyValueTypeCasting","cell","valueType","value","resolveSanitizerRef","ref","runCellSanitizers","cell","row","field","getSanitizer","list","current","ref","name","params","resolveSanitizerRef","fn","runRowSanitizers","row","sheetLayout","getSanitizer","list","current","ref","name","params","resolveSanitizerRef","fn","runSheetSanitizers","sheet","sheetLayout","getSanitizer","list","current","ref","name","params","resolveSanitizerRef","fn","THROTTLE_MS","THROTTLE_PERCENT","createThrottledProgress","totalRows","onProgress","lastTime","lastPercent","processed","now","localPercent","runSanitization","convertedSheet","sheetLayout","getters","fields","reportProgress","outRows","i","row","cells","cell","field","c","applyValueTypeCasting","runCellSanitizers","updatedRow","afterRow","runRowSanitizers","sheet","runSheetSanitizers","DATE_FORMAT_SANITIZER_ID","parseToDate","value","s","ms","toISODateString","d","y","m","day","toISOTimeString","h","min","toFormatted","cellDateFormatSanitizer","cell","_row","_params","out","registerDateFormatSanitizer","register","DATE_ONLY_SANITIZER_ID","parseToDate","value","s","ms","toISODateString","d","y","m","day","cellDateOnlySanitizer","cell","_row","_params","out","registerDateOnlySanitizer","register","DATE_YEAR_SANITIZER_ID","parseToDate","value","s","ms","cellDateYearSanitizer","cell","_row","_params","d","out","registerDateYearSanitizer","register","TIMESTAMP_SANITIZER_ID","parseToTimestamp","value","ms","cellTimestampSanitizer","cell","_row","_params","registerTimestampSanitizer","register","TIME_ONLY_SANITIZER_ID","parseToDate","value","s","ms","toISOTimeString","d","h","min","cellTimeOnlySanitizer","cell","_row","_params","out","registerTimeOnlySanitizer","register","NUMBER_FLOAT_SANITIZER_ID","toFloat","value","s","parsed","cellNumberFloatSanitizer","cell","_row","_params","registerNumberFloatSanitizer","register","NUMBER_INT_SANITIZER_ID","toInt","value","s","parsed","cellNumberIntSanitizer","cell","_row","_params","registerNumberIntSanitizer","register","NUMBER_TO_STRING_END_SANITIZER_ID","padEnd","value","length","fill","cellNumberToStringEndSanitizer","cell","_row","params","safeLength","safeFill","registerNumberToStringEndSanitizer","register","NUMBER_TO_STRING_ID_SANITIZER_ID","padStart","value","length","fill","cellNumberToStringIdSanitizer","cell","_row","params","safeLength","safeFill","registerNumberToStringIdSanitizer","register","REPLACE_FROM_REGEX_SANITIZER_ID","replaceByRegex","value","pattern","flags","replacement","s","re","cellReplaceRegexSanitizer","cell","_row","params","out","registerReplaceRegexSanitizer","register","REPLACE_FROM_STR_SANITIZER_ID","replaceByStr","value","search","replacement","s","cellReplaceStrSanitizer","cell","_row","params","out","registerReplaceStrSanitizer","register","NULL_TO_EMPTY_SANITIZER_ID","nullToEmpty","value","cellNullToEmptySanitizer","cell","_row","_params","registerNullToEmptySanitizer","register","STRING_COLLAPSE_SPACES_SANITIZER_ID","collapseSpaces","value","cellStringCollapseSpacesSanitizer","cell","_row","_params","registerStringCollapseSpacesSanitizer","register","STRING_LOWER_SANITIZER_ID","toLower","value","cellStringLowerSanitizer","cell","_row","_params","registerStringLowerSanitizer","register","STRING_MAX_LENGTH_SANITIZER_ID","truncate","value","maxLength","s","cellStringMaxLengthSanitizer","cell","_row","params","safe","registerStringMaxLengthSanitizer","register","STRING_PAD_END_SANITIZER_ID","toStringValue","value","cellStringPadEndSanitizer","cell","_row","params","length","fill","safeLength","out","registerStringPadEndSanitizer","register","STRING_PAD_START_SANITIZER_ID","toStringValue","value","cellStringPadStartSanitizer","cell","_row","params","length","fill","safeLength","out","registerStringPadStartSanitizer","register","STRING_UPPER_SANITIZER_ID","toUpper","value","cellStringUpperSanitizer","cell","_row","_params","registerStringUpperSanitizer","register","TRIM_SANITIZER_ID","trimValue","value","cellTrimSanitizer","cell","_row","_params","registerTrimSanitizer","register","registry","Registry","register","reg","name","fn","opts","registerTrimSanitizer","registerNumberIntSanitizer","registerNumberFloatSanitizer","registerNumberToStringIdSanitizer","registerNumberToStringEndSanitizer","registerDateFormatSanitizer","registerDateYearSanitizer","registerDateOnlySanitizer","registerTimeOnlySanitizer","registerTimestampSanitizer","registerStringLowerSanitizer","registerStringUpperSanitizer","registerStringMaxLengthSanitizer","registerStringPadEndSanitizer","registerStringPadStartSanitizer","registerStringCollapseSpacesSanitizer","registerNullToEmptySanitizer","registerReplaceRegexSanitizer","registerReplaceStrSanitizer","getCellSanitizer","entry","getRowSanitizer","_name","getSheetSanitizer","getSanitizerGetters","api","convertedSheet","sheetLayout","_options","onProgress","getters","getSanitizerGetters","runSanitization"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as R,b as S,c as C,d as D,e as P}from"./chunk-WLNB3X2R.js";import"./chunk-YETPLYYC.js";import*as v from"comlink";var x=16,I=1,j=200;function O(r,n){let s=0,e=-1;return a=>{let t=Date.now(),o=r>0?Math.floor(a/r*100):100;(t-s>=x||o-e>=I||a>=r)&&r>0&&(s=t,e=o,n({phase:"transforming",localPercent:o,currentRow:a,totalRows:r}))}}function L(r,n,s){let e=[],a=new Map(n.cells.map(t=>[t.key,t]));for(let t of s.cells){let o=a.get(t.key);o&&o.value!==t.value&&e.push({row:r,col:t.key,newValue:t.value})}return e}async function k(r,n,s,e,a){if(r.errors.length>0)return{deltas:[]};let t=n.fields,o=r.rows.length,d=e?O(o,e):()=>{},f=[];for(let i=0;i<o;i+=j){let h=Math.min(i+j,o);for(let c=i;c<h;c++){let m=r.rows[c];if(!m||m.errors.length>0)continue;let y=[],u=[];for(let l of m.cells){let w=t[l.key];if(!w){u.push(l);continue}let T=R(l,m,w,s.getCellTransform);T!==l.value&&y.push({row:m.index,col:l.key,newValue:T}),u.push({...l,value:T})}let g={...m,cells:u},V=S(g,n,s.getRowTransform),E=L(m.index,g,V);f.push(...y,...E)}d(h)}e&&e({phase:"transforming",localPercent:100,currentRow:o,totalRows:o});let b=D(r,{deltas:f}),p=await C(b,n,s.getSheetTransform,a);f.push(...p.deltas);let G=p.errors.length>0?[...p.errors]:void 0;return{deltas:f,errors:G}}var M={async transform(r,n,s,e){let a=P();return k(r,n,a,e,s?.signal)}};v.expose(M);
|
|
2
|
+
//# sourceMappingURL=transform.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/transform/worker/transform.worker.ts","../src/core/transform/runner/run-transform.ts"],"sourcesContent":["import * as Comlink from 'comlink';\nimport type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { Sheet } from '../../../types/sheet.js';\nimport type { TransformResult } from '../types/transform-delta.js';\nimport type { TransformProgressDetail } from '../types/transform-progress.js';\nimport { runTransform } from '../runner/run-transform.js';\nimport { getTransformGetters } from './worker-registry.js';\n\ntype ProgressCallback = (detail: TransformProgressDetail) => void;\n\nexport interface TransformWorkerOptions {\n signal?: AbortSignal;\n}\n\nconst api = {\n async transform(\n sheet: Sheet,\n sheetLayout: SheetLayout,\n options?: TransformWorkerOptions,\n onProgress?: ProgressCallback,\n ): Promise<TransformResult> {\n const getters = getTransformGetters();\n return runTransform(\n sheet,\n sheetLayout,\n getters,\n onProgress,\n options?.signal,\n );\n },\n};\n\nComlink.expose(api);\n","import type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { Sheet, ValidatedCell, ValidatedRow } from '../../../types/sheet.js';\nimport type { TransformDeltaItem, TransformResult } from '../types/transform-delta.js';\nimport type { TransformProgressDetail } from '../types/transform-progress.js';\nimport { runCellTransforms } from './cell-transforms.js';\nimport { runRowTransforms } from './row-transforms.js';\nimport { runSheetTransforms } from './sheet-transforms.js';\nimport type { GetCellTransform } from './cell-transforms.js';\nimport type { GetRowTransform } from './row-transforms.js';\nimport type { GetSheetTransform } from './sheet-transforms.js';\nimport { applyTransformDelta } from '../delta-applier.js';\n\nconst THROTTLE_MS = 16;\nconst THROTTLE_PERCENT = 1;\nconst CHUNK_SIZE = 200;\n\nexport interface TransformGetters {\n getCellTransform: GetCellTransform;\n getRowTransform: GetRowTransform;\n getSheetTransform: GetSheetTransform;\n}\n\nfunction createThrottledProgress(\n totalRows: number,\n onProgress: (d: TransformProgressDetail) => void,\n): (processed: number) => void {\n let lastTime = 0;\n let lastPercent = -1;\n return (processed: number) => {\n const now = Date.now();\n const localPercent = totalRows > 0 ? Math.floor((processed / totalRows) * 100) : 100;\n const shouldEmit =\n now - lastTime >= THROTTLE_MS ||\n localPercent - lastPercent >= THROTTLE_PERCENT ||\n processed >= totalRows;\n if (shouldEmit && totalRows > 0) {\n lastTime = now;\n lastPercent = localPercent;\n onProgress({\n phase: 'transforming',\n localPercent,\n currentRow: processed,\n totalRows,\n });\n }\n };\n}\n\nfunction diffRowToDeltas(\n rowIndex: number,\n before: ValidatedRow,\n after: ValidatedRow,\n): TransformDeltaItem[] {\n const out: TransformDeltaItem[] = [];\n const beforeCells = new Map(before.cells.map((c) => [c.key, c]));\n for (const cell of after.cells) {\n const prev = beforeCells.get(cell.key);\n if (prev && prev.value !== cell.value) {\n out.push({ row: rowIndex, col: cell.key, newValue: cell.value });\n }\n }\n return out;\n}\n\nexport async function runTransform(\n sheet: Sheet,\n sheetLayout: SheetLayout,\n getters: TransformGetters,\n onProgress?: (d: TransformProgressDetail) => void,\n signal?: AbortSignal,\n): Promise<TransformResult> {\n if (sheet.errors.length > 0) return { deltas: [] };\n const fields = sheetLayout.fields;\n const totalRows = sheet.rows.length;\n const reportProgress = onProgress ? createThrottledProgress(totalRows, onProgress) : () => {};\n const deltas: TransformDeltaItem[] = [];\n\n for (let i = 0; i < totalRows; i += CHUNK_SIZE) {\n const end = Math.min(i + CHUNK_SIZE, totalRows);\n for (let r = i; r < end; r++) {\n const row = sheet.rows[r];\n if (!row || row.errors.length > 0) continue;\n const rowDeltas: TransformDeltaItem[] = [];\n const updatedCells: ValidatedCell[] = [];\n for (const cell of row.cells) {\n const field = fields[cell.key];\n if (!field) {\n updatedCells.push(cell);\n continue;\n }\n const newValue = runCellTransforms(\n cell,\n row,\n field,\n getters.getCellTransform,\n );\n if (newValue !== cell.value) {\n rowDeltas.push({ row: row.index, col: cell.key, newValue });\n }\n updatedCells.push({ ...cell, value: newValue });\n }\n const updatedRow: ValidatedRow = { ...row, cells: updatedCells };\n const afterRow = runRowTransforms(updatedRow, sheetLayout, getters.getRowTransform);\n const rowDiff = diffRowToDeltas(row.index, updatedRow, afterRow);\n deltas.push(...rowDeltas, ...rowDiff);\n }\n reportProgress(end);\n }\n\n if (onProgress) {\n onProgress({ phase: 'transforming', localPercent: 100, currentRow: totalRows, totalRows });\n }\n\n const transformedSheet = applyTransformDelta(sheet, { deltas });\n\n const sheetOut = await runSheetTransforms(\n transformedSheet,\n sheetLayout,\n getters.getSheetTransform,\n signal,\n );\n deltas.push(...sheetOut.deltas);\n const errors = sheetOut.errors.length > 0 ? [...sheetOut.errors] : undefined;\n return { deltas, errors };\n}\n"],"mappings":"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","names":["Comlink","THROTTLE_MS","THROTTLE_PERCENT","CHUNK_SIZE","createThrottledProgress","totalRows","onProgress","lastTime","lastPercent","processed","now","localPercent","diffRowToDeltas","rowIndex","before","after","out","beforeCells","c","cell","prev","runTransform","sheet","sheetLayout","getters","signal","fields","reportProgress","deltas","end","r","row","rowDeltas","updatedCells","field","newValue","runCellTransforms","updatedRow","afterRow","runRowTransforms","rowDiff","transformedSheet","applyTransformDelta","sheetOut","runSheetTransforms","errors","api","sheet","sheetLayout","options","onProgress","getters","getTransformGetters","runTransform"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as f,b as y,c as V,d as u}from"./chunk-XTSACACJ.js";import"./chunk-YETPLYYC.js";import*as h from"comlink";var S=16,D=1;function P(t,a){let o=0,r=-1;return i=>{let l=Date.now(),n=t>0?Math.floor(i/t*100):100;(l-o>=S||n-r>=D||i>=t)&&t>0&&(o=l,r=n,a({phase:"validating",localPercent:n,currentRow:i,totalRows:t}))}}async function g(t,a,o,r,i){let l=t.rows.length,n=a.fields,m=r?P(l,r):()=>{},d=[];for(let p=0;p<l;p++){let s=t.rows[p];if(!s)continue;for(let e of s.cells){let c=n[e.key];if(!c)continue;let v=f(e,s,c,o.getCellValidator);for(let T of v)d.push({rowIndex:s.index,cellKey:e.key,error:T})}let b=y(s,a,o.getRowValidator);for(let e of b)e.cellKey!==void 0&&e.cellKey!==""?d.push({rowIndex:s.index,cellKey:e.cellKey,error:e}):d.push({rowIndex:s.index,error:e});m(p+1)}r&&r({phase:"validating",localPercent:100,currentRow:l,totalRows:l});let w=await V(t,a,o.getTableValidator,i);return d.push(...w),{errors:d}}var j={async validate(t,a,o,r){let i=u();return g(t,a,i,r,o?.signal)}};h.expose(j);
|
|
2
|
+
//# sourceMappingURL=validator.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/validator/worker/validator.worker.ts","../src/core/validator/runner/run-validation.ts"],"sourcesContent":["import * as Comlink from 'comlink';\nimport type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { SanitizedSheet } from '../../sanitizer/types/sanitized-sheet.js';\nimport type { ValidatorDelta } from '../types/validator-delta.js';\nimport type { ValidatorProgressDetail } from '../types/validator-progress.js';\nimport { runValidation } from '../runner/run-validation.js';\nimport { getValidatorGetters } from './worker-registry.js';\n\ntype ProgressCallback = (detail: ValidatorProgressDetail) => void;\n\nexport interface ValidatorWorkerOptions {\n signal?: AbortSignal;\n}\n\nconst api = {\n async validate(\n sanitizedSheet: SanitizedSheet,\n sheetLayout: SheetLayout,\n options?: ValidatorWorkerOptions,\n onProgress?: ProgressCallback,\n ): Promise<ValidatorDelta> {\n const getters = getValidatorGetters();\n return runValidation(\n sanitizedSheet,\n sheetLayout,\n getters,\n onProgress,\n options?.signal,\n );\n },\n};\n\nComlink.expose(api);\n","import type { SheetLayout } from '../../../types/sheet-layout.js';\nimport type { SanitizedSheet } from '../../sanitizer/types/sanitized-sheet.js';\nimport type { ValidatorDelta, ValidatorErrorDeltaItem } from '../types/validator-delta.js';\nimport type { ValidatorProgressDetail } from '../types/validator-progress.js';\nimport { runCellValidators } from './cell-validators.js';\nimport { runRowValidators } from './row-validators.js';\nimport { runTableValidation } from './run-table-validation.js';\nimport type { GetCellValidator } from './cell-validators.js';\nimport type { GetRowValidator } from './row-validators.js';\nimport type { GetTableValidator } from './run-table-validation.js';\n\nconst THROTTLE_MS = 16;\nconst THROTTLE_PERCENT = 1;\n\nexport interface ValidatorGetters {\n getCellValidator: GetCellValidator;\n getRowValidator: GetRowValidator;\n getTableValidator: GetTableValidator;\n}\n\nfunction createThrottledProgress(\n totalRows: number,\n onProgress: (d: ValidatorProgressDetail) => void\n): (processed: number) => void {\n let lastTime = 0;\n let lastPercent = -1;\n return (processed: number) => {\n const now = Date.now();\n const localPercent = totalRows > 0 ? Math.floor((processed / totalRows) * 100) : 100;\n const shouldEmit =\n now - lastTime >= THROTTLE_MS ||\n localPercent - lastPercent >= THROTTLE_PERCENT ||\n processed >= totalRows;\n if (shouldEmit && totalRows > 0) {\n lastTime = now;\n lastPercent = localPercent;\n onProgress({\n phase: 'validating',\n localPercent,\n currentRow: processed,\n totalRows,\n });\n }\n };\n}\n\nexport async function runValidation(\n sanitizedSheet: SanitizedSheet,\n sheetLayout: SheetLayout,\n getters: ValidatorGetters,\n onProgress?: (d: ValidatorProgressDetail) => void,\n signal?: AbortSignal\n): Promise<ValidatorDelta> {\n const totalRows = sanitizedSheet.rows.length;\n const fields = sheetLayout.fields;\n const reportProgress = onProgress ? createThrottledProgress(totalRows, onProgress) : () => {};\n const errors: ValidatorErrorDeltaItem[] = [];\n\n for (let i = 0; i < totalRows; i++) {\n const row = sanitizedSheet.rows[i];\n if (!row) continue;\n for (const cell of row.cells) {\n const field = fields[cell.key];\n if (!field) continue;\n const cellErrors = runCellValidators(cell, row, field, getters.getCellValidator);\n for (const err of cellErrors) {\n errors.push({ rowIndex: row.index, cellKey: cell.key, error: err });\n }\n }\n const rowErrors = runRowValidators(row, sheetLayout, getters.getRowValidator);\n for (const err of rowErrors) {\n if (err.cellKey !== undefined && err.cellKey !== '') {\n errors.push({ rowIndex: row.index, cellKey: err.cellKey, error: err });\n } else {\n errors.push({ rowIndex: row.index, error: err });\n }\n }\n reportProgress(i + 1);\n }\n\n if (onProgress) {\n onProgress({ phase: 'validating', localPercent: 100, currentRow: totalRows, totalRows });\n }\n\n const tableErrors = await runTableValidation(\n sanitizedSheet,\n sheetLayout,\n getters.getTableValidator,\n signal\n );\n errors.push(...tableErrors);\n\n return { errors };\n}\n"],"mappings":"yFAAA,UAAYA,MAAa,UCWzB,IAAMC,EAAc,GACdC,EAAmB,EAQzB,SAASC,EACPC,EACAC,EAC6B,CAC7B,IAAIC,EAAW,EACXC,EAAc,GAClB,OAAQC,GAAsB,CAC5B,IAAMC,EAAM,KAAK,IAAI,EACfC,EAAeN,EAAY,EAAI,KAAK,MAAOI,EAAYJ,EAAa,GAAG,EAAI,KAE/EK,EAAMH,GAAYL,GAClBS,EAAeH,GAAeL,GAC9BM,GAAaJ,IACGA,EAAY,IAC5BE,EAAWG,EACXF,EAAcG,EACdL,EAAW,CACT,MAAO,aACP,aAAAK,EACA,WAAYF,EACZ,UAAAJ,CACF,CAAC,EAEL,CACF,CAEA,eAAsBO,EACpBC,EACAC,EACAC,EACAT,EACAU,EACyB,CACzB,IAAMX,EAAYQ,EAAe,KAAK,OAChCI,EAASH,EAAY,OACrBI,EAAiBZ,EAAaF,EAAwBC,EAAWC,CAAU,EAAI,IAAM,CAAC,EACtFa,EAAoC,CAAC,EAE3C,QAASC,EAAI,EAAGA,EAAIf,EAAWe,IAAK,CAClC,IAAMC,EAAMR,EAAe,KAAKO,CAAC,EACjC,GAAI,CAACC,EAAK,SACV,QAAWC,KAAQD,EAAI,MAAO,CAC5B,IAAME,EAAQN,EAAOK,EAAK,GAAG,EAC7B,GAAI,CAACC,EAAO,SACZ,IAAMC,EAAaC,EAAkBH,EAAMD,EAAKE,EAAOR,EAAQ,gBAAgB,EAC/E,QAAWW,KAAOF,EAChBL,EAAO,KAAK,CAAE,SAAUE,EAAI,MAAO,QAASC,EAAK,IAAK,MAAOI,CAAI,CAAC,CAEtE,CACA,IAAMC,EAAYC,EAAiBP,EAAKP,EAAaC,EAAQ,eAAe,EAC5E,QAAWW,KAAOC,EACZD,EAAI,UAAY,QAAaA,EAAI,UAAY,GAC/CP,EAAO,KAAK,CAAE,SAAUE,EAAI,MAAO,QAASK,EAAI,QAAS,MAAOA,CAAI,CAAC,EAErEP,EAAO,KAAK,CAAE,SAAUE,EAAI,MAAO,MAAOK,CAAI,CAAC,EAGnDR,EAAeE,EAAI,CAAC,CACtB,CAEId,GACFA,EAAW,CAAE,MAAO,aAAc,aAAc,IAAK,WAAYD,EAAW,UAAAA,CAAU,CAAC,EAGzF,IAAMwB,EAAc,MAAMC,EACxBjB,EACAC,EACAC,EAAQ,kBACRC,CACF,EACA,OAAAG,EAAO,KAAK,GAAGU,CAAW,EAEnB,CAAE,OAAAV,CAAO,CAClB,CD/EA,IAAMY,EAAM,CACV,MAAM,SACJC,EACAC,EACAC,EACAC,EACyB,CACzB,IAAMC,EAAUC,EAAoB,EACpC,OAAOC,EACLN,EACAC,EACAG,EACAD,EACAD,GAAS,MACX,CACF,CACF,EAEQ,SAAOH,CAAG","names":["Comlink","THROTTLE_MS","THROTTLE_PERCENT","createThrottledProgress","totalRows","onProgress","lastTime","lastPercent","processed","now","localPercent","runValidation","sanitizedSheet","sheetLayout","getters","signal","fields","reportProgress","errors","i","row","cell","field","cellErrors","runCellValidators","err","rowErrors","runRowValidators","tableErrors","runTableValidation","api","sanitizedSheet","sheetLayout","options","onProgress","getters","getValidatorGetters","runValidation"]}
|