Skip to content

Commit

Permalink
cache-file-working
Browse files Browse the repository at this point in the history
  • Loading branch information
samueljd committed Sep 10, 2024
1 parent d69fde3 commit b046173
Show file tree
Hide file tree
Showing 18 changed files with 3,034 additions and 236 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Autogrpha-DB/
/app/**/*.map
/.next
.next
.yalc
yalc.lock

# testing
/coverage
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,14 @@
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "5.0.1",
"sj-usfm-grammar": "^3.0.2",
"styled-components": "^5.3.6",
"tc-ui-toolkit": "5.3.3",
"translation-helps-rcl": "3.5.12",
"typescript": "^4.9.5",
"use-deep-compare": "^1.1.0",
"usfm-editor": "0.8.7",
"usfm-grammar": "^2.3.0",
"usfm-grammar": "3.0.0-alpha.4",
"uuid": "^8.3.2",
"wavesurfer.js": "^6.6.4",
"webpack-node-externals": "^3.0.0",
Expand All @@ -241,6 +242,7 @@
},
"optionalDependencies": {
"bufferutil": "^4.0.6",
"react-icons": "4.10.1",
"scripture-resources-rcl": "5.1.0",
"utf-8-validate": "^5.0.9"
},
Expand All @@ -252,4 +254,4 @@
"word-aligner": "$word-aligner",
"@mui/lab": "$@mui/lab"
}
}
}
142 changes: 142 additions & 0 deletions renderer/src/components/EditorPage/LexicalEditor/cacheUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import * as path from 'path';
import * as crypto from 'crypto';
import { convertUsfmToUsj } from './conversionUtils';

let fs;

// Wrap the fs assignment in a function that checks if window is defined
function initFS() {
if (typeof window !== 'undefined' && window.require) {
fs = window.require('fs');
}
}

// Call initFS immediately
initFS();

// async function getWorkspaceFolderPath() {
// const userProfile = await localforage.getItem('userProfile');
// const projectName = await localforage.getItem('currentProject');
// const userName = userProfile?.username;
// const newpath = await localforage.getItem('userPath');
// const CACHE_DIR = path.join(newpath, packageInfo.name, 'users', userName, 'project_cache', projectName);
// console.log({ CACHE_DIR });
// return CACHE_DIR;
// }

// const CACHE_DIR = await getWorkspaceFolderPath();

// const CACHE_FILE_NAME = 'fileCacheMap.json'; // File name to store the cache mapping
// // Ensure cache directory exists
// if (!fs.existsSync(CACHE_DIR)) {
// console.log('Creating cache directory:', CACHE_DIR);
// fs.mkdirSync(CACHE_DIR, { recursive: true });
// }

export function getMd5Hash(content) {
return crypto.createHash('md5').update(content).digest('hex');
}

export function getCacheFilePath(hash, projectCachePath) {
console.log({ hash, projectCachePath });
return path.join(projectCachePath, `${hash}.json`);
}

export function isCacheValid(hash, projectCachePath) {
if (!fs) { return false; }
const cacheFilePath = getCacheFilePath(hash, projectCachePath);
return fs.existsSync(cacheFilePath);
}

export function readCache(hash, projectCachePath) {
if (!fs) { throw new Error('File system not available'); }
const cacheFilePath = path.join(projectCachePath, `${hash}.json`);
console.log(JSON.parse(fs.readFileSync(cacheFilePath, 'utf8')));
return JSON.parse(fs.readFileSync(cacheFilePath, 'utf8'));
}

export function writeCache(hash, data, projectCachePath) {
console.log({});
if (!fs) {
console.error('File system not available');
return;
}
const cacheFilePath = getCacheFilePath(hash, projectCachePath);
fs.writeFileSync(cacheFilePath, JSON.stringify(data), 'utf8');
}

export function deleteOldCacheFile(hash, projectCachePath) {
const cacheFilePath = getCacheFilePath(hash, projectCachePath);
if (fs.existsSync(cacheFilePath)) {
fs.unlinkSync(cacheFilePath);
}
}

export function getCacheMapFromFile(fileCacheMapPath) {
if (fileCacheMapPath) {
try {
if (fs.existsSync(fileCacheMapPath)) {
const fileContent = fs.readFileSync(fileCacheMapPath, 'utf-8');
return JSON.parse(fileContent);
}
} catch (error) {
console.error('Error reading cache file:', error);
}
}

return {};
}

export function updateCacheMapToFile(fileCacheMapPath, filePath, hash) {
if (fileCacheMapPath) {
const cacheMap = getCacheMapFromFile(fileCacheMapPath);
cacheMap[filePath] = hash;
try {
fs.mkdirSync(path.dirname(fileCacheMapPath), { recursive: true });
fs.writeFileSync(fileCacheMapPath, JSON.stringify(cacheMap));
} catch (error) {
console.error('Error writing cache file:', error);
}
}
}

export async function handleCache(filePath, usfmContent, projectCachePath, fileCacheMapPath) {
console.log({ usfmContent });
const newHash = getMd5Hash(usfmContent);
const fileCacheMap = getCacheMapFromFile(fileCacheMapPath);

const oldHash = fileCacheMap[filePath];
if (oldHash && isCacheValid(oldHash, projectCachePath) && oldHash === newHash) {
console.log('Cache hit');
return { usj: await readCache(oldHash, projectCachePath) };
}
console.log('Cache miss or content changed');
if (oldHash) {
deleteOldCacheFile(oldHash, projectCachePath);
}
const { usj, error } = await convertUsfmToUsj(usfmContent);
if (error) {
console.error('Error parsing USFM', error);
return { error };
}
console.log({ newHash, usj });
writeCache(newHash, usj, projectCachePath);
updateCacheMapToFile(fileCacheMapPath, filePath, newHash);
return { usj };
}

export async function updateCache(filePath, usj, usfm, fileCacheMapPath, projectCachePath) {
const newHash = getMd5Hash(usfm);
const fileCacheMap = getCacheMapFromFile(fileCacheMapPath);
const oldHash = fileCacheMap[filePath];

if (oldHash && isCacheValid(oldHash, projectCachePath) && oldHash === newHash) {
writeCache(oldHash, usj, projectCachePath);
} else {
if (oldHash) {
deleteOldCacheFile(oldHash, projectCachePath);
}
writeCache(newHash, usj, projectCachePath);
updateCacheMapToFile(fileCacheMapPath, filePath, newHash);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import USFMParser from 'sj-usfm-grammar';

let usfmParserInstance;
let usfmParserInitialized;

export async function initializeParser() {
if (!usfmParserInstance) {
if (!usfmParserInitialized) {
usfmParserInitialized = await USFMParser.init();
}
await usfmParserInitialized;
usfmParserInstance = new USFMParser();
}
return usfmParserInstance;
}

export async function convertUsfmToUsj(usfm) {
if (!usfmParserInstance) {
usfmParserInstance = await initializeParser();
}
try {
const usj = usfmParserInstance.usfmToUsj(usfm);
return { usj };
} catch (e) {
return { usj: { content: [] }, error: e };
}
}

export async function convertUsjToUsfm(usj) {
if (!usfmParserInstance) {
usfmParserInstance = await initializeParser();
}
const usfm = usfmParserInstance.usjToUsfm(usj);
return usfm;
}

initializeParser()
.then(() => {
console.log('USFM Parser initialized successfully');
})
.catch((err) => {
console.error('Error initializing USFM Parser:', err);
});
14 changes: 14 additions & 0 deletions renderer/src/components/EditorPage/LexicalEditor/updateAndSave.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { getCachePaths } from '../TextEditor/hooks/useReadUsfmFile';
import { convertUsjToUsfm } from './conversionUtils';
import { updateCache } from './cacheUtils';
import { saveToFile } from '../TextEditor/hooks/saveToFile';

export async function updateCacheNSaveFile(usj, bookId) {
const usfm = await convertUsjToUsfm(usj);
const { filePath, projectCachePath, fileCacheMapPath } = await getCachePaths(bookId);
updateCache(filePath, usj, usfm, fileCacheMapPath, projectCachePath);
if (usfm) {
await saveToFile(usfm, bookId);
console.log('file saved');
}
}
72 changes: 72 additions & 0 deletions renderer/src/components/EditorPage/LexicalEditor/useUsfmGrammar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {
useState, useEffect, useRef, useCallback,
} from 'react';
import { USFMParser } from 'usfm-grammar';

// Hook to initialize the parser
export const useUSFMParser = () => {
const [usfmParser, setUsfmParser] = useState();

useEffect(() => {
const initParser = async () => {
await USFMParser.init();
const usfmParser = new USFMParser();
console.log({ usfmParser });
setUsfmParser(usfmParser);
};
initParser();
}, []);

return { USFMParser: usfmParser };
};

// Hook for USFM to USJ conversion
export const useUsfmToUsj = () => {
const parserRef = useUSFMParser();
console.log({ parserRef });
const [usj, setUsj] = useState(null);
const [error, setError] = useState(null);

const convert = useCallback((usfm) => {
console.log('inside the hook ======>', { usfm });
if (parserRef.current) {
try {
const result = parserRef.current.usfmToUsj(usfm);
console.log({ result });
setUsj(result);
setError(null);
} catch (err) {
setError(err.message);
setUsj(null);
}
} else {
setError('Parser not initialized');
}
}, [parserRef]);

return { usj, error, convert };
};

// Hook for USJ to USFM conversion
export const useUsjToUsfm = () => {
const parserRef = useUSFMParser();
const [usfm, setUsfm] = useState(null);
const [error, setError] = useState(null);

const convert = useCallback((usj) => {
if (parserRef.current) {
try {
const result = parserRef.current.usjToUsfm(usj);
setUsfm(result);
setError(null);
} catch (err) {
setError(err.message);
setUsfm(null);
}
} else {
setError('Parser not initialized');
}
}, [parserRef]);

return { usfm, error, convert };
};
73 changes: 73 additions & 0 deletions renderer/src/components/EditorPage/LexicalEditor/useUsjHook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// import { useState, useEffect, useRef } from 'react';
// import { USFMParser } from 'usfm-grammar';

// export const useUSFMParser = () => {
// const [isReady, setIsReady] = useState(false);
// const parserRef = useRef(null);

// useEffect(() => {
// const initializeParser = async () => {
// if (!parserRef.current) {
// await USFMParser.init();
// parserRef.current = new USFMParser();
// setIsReady(true);
// }
// };

// initializeParser();
// }, []);

// const usfmToUsj = (usfmString) => {
// if (!isReady) {
// throw new Error('USFM Parser is not initialized yet');
// }
// return parserRef.current.usfmToUsj(usfmString);
// };

// const usjToUsfm = (usjObject) => {
// if (!isReady) {
// throw new Error('USFM Parser is not initialized yet');
// }
// return parserRef.current.usjToUsfm(usjObject);
// };

// return { isReady, usfmToUsj, usjToUsfm };
// };

// // export default useUSFMParser;

import { useState, useEffect, useCallback } from 'react';
import { USFMParser } from 'usfm-grammar';

export const useUSFMParser = () => {
const [parser, setParser] = useState(null);

useEffect(() => {
const initializeParser = async () => {
if (!parser) {
await USFMParser.init();
setParser(new USFMParser());
}
};

initializeParser();
}, [parser]);

const usfmToUsj = useCallback((usfmString) => {
if (!parser) {
throw new Error('USFM Parser is not initialized yet');
}
return parser.usfmToUsj(usfmString);
}, [parser]);

const usjToUsfm = useCallback((usjObject) => {
if (!parser) {
throw new Error('USFM Parser is not initialized yet');
}
return parser.usjToUsfm(usjObject);
}, [parser]);

return { isReady: !!parser, usfmToUsj, usjToUsfm };
};

export default useUSFMParser;
Loading

0 comments on commit b046173

Please sign in to comment.