-
Notifications
You must be signed in to change notification settings - Fork 128
Added i18n component and related scripts #1082
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…plits the text into manageable chunk
…xt handling and error reporting
…toring segment handling to use arrays for better management
…ling in Promise.all
…ity and consistency
… merging logic and remove unnecessary debug logs
…ager version in package.json
…lations inside SCHEME and SCHEMEINLINE tags
…ded try catch when parsing xml to json to report failed parsing possibly attributed to unsound xml structure.
- Created a new XML file for references (97references97.xml) containing a comprehensive list of references used in the SICP JS project. - Added a new XML file for the index preface (98indexpreface98.xml) to provide context and formatting for the index section. - Introduced a new XML file for the making section (99making99.xml) detailing the background, interactive features, and development history of the SICP JS project. - Updated subsection2.xml to close the previously open SUBSECTION tag and include a comment for clarity.
…LINE tags in XML parsing
breaking changes are made: xml repositories are divided into folders, currently consisting of en and cn folders to store translated content. The same applies to the json folder after running "yarn json". Frontend needs to be changed accordingly to fetch json files from the corresponding url |
… command yarn scripts
f4d52e0
to
851b85c
Compare
clone into the xml directory and run yarn json etc to generate the files
translate-changed.yml and translate-everything.yml
throw new Error('Undefined language'); | ||
} | ||
|
||
if (!troubleshoot) assistant = await createAssistant(langCode, language, ai as any); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You’re casting your OpenAI client to any
when calling createAssistant
. Remove the as any
cast and unify your imports so you only pull in OpenAI
from the main package entrypoint. For example:
// i18n/initializers/initialize.ts
import OpenAI from 'openai';
// instead of importing from internal paths:
// import OpenAI from 'openai/index.mjs';
Then simply call:
assistant = await createAssistant(langCode, language, ai);
By using a single import OpenAI from 'openai'
everywhere, TypeScript will recognize the same class, eliminating the need for any
.
@@ -0,0 +1,45 @@ | |||
import fs from "fs"; | |||
import OpenAI from "openai/index.mjs"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the previous comment about dropping the ai as any
cast, you should also update the import in your initialize.ts
to:
import OpenAI from 'openai';
const fileStreams = [path.join(__dirname, "../ai_files", langCode, "dictionary.txt")].map( | ||
path => fs.createReadStream(path) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should attach an error handler to each stream so file I/O issues (like missing or unreadable files) are caught immediately:
const fileStreams = [path.join(__dirname, '../ai_files', langCode, 'dictionary.txt')].map(
filePath => {
const stream = fs.createReadStream(filePath);
stream.on('error', err => {
throw new Error(`Failed to read dictionary file at ${filePath}: ${err.message}`);
});
return stream;
});
This ensures your process fails fast with a clear error instead of silently hanging or emitting later failures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
openai
, sax
, and dotenv
are not declared in your package.json
dependencies, and you also need the Node.js types for TypeScript. You can add them like:
{
"dependencies": {
"sicp": "^1.1.4",
"openai": "^x.y.z",
"sax": "^x.y.z",
"dotenv": "^x.y.z"
},
"devDependencies": {
"@types/node": "^x.y.z"
}
}
That way, running yarn install
will automatically pull in those packages and the Node types.
const logPath = path.join(logDir, `json-summary-${timestamp}.log`); | ||
fs.writeFileSync(logPath, summaryLog); | ||
console.log( | ||
`Summary log saved to logs/translation-summary-${timestamp}.log` | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a mismatch between the log filename you write (json-summary-...
) and the one you log to the console (translation-summary-...
).
const getDirectories = async source => | ||
(await readdir(source, { withFileTypes: true })) | ||
.filter(dirent => dirent.isDirectory()) | ||
.map(dirent => dirent.name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter source
is implicitly typed as any
. You should add an explicit type annotation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several magic literals in this file, for example:
- Batch size fallback:
max_trans_num = Number(process.env.MAX_TRANSLATION_NO) || 5
- API list limit:
await ai.beta.assistants.list({ limit: 100 })
- Filename prefix in logs:
translation-summary-
- Timestamp hack:
.toISOString().replace(/[:.]/g, "-")
There are more magic values throughout consider extracting them into named constants or a configuration object for better maintainability.
try { | ||
const cnStats = await fs.promises.stat(cnFilePath); | ||
if (!cnStats.isFile()) { | ||
return true; | ||
} | ||
|
||
const enStats = await fs.promises.stat(enFilePath); | ||
return enStats.mtime > cnStats.mtime; | ||
} catch (error) { | ||
return true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Catching
all errors and returning true
can mask real file‑system issues. You should be logging or re‑throwing unexpected errors so you don’t skip translations silently.
// Add detailed errors captured during translation process | ||
const fileErrors = getFileErrors(); | ||
if (Object.keys(fileErrors).length > 0) { | ||
failureCount = Object.keys(fileErrors).length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The failureCount
variable is declared globally and reused here, so resetting it in the summary section overwrites the failures accumulated during the batch loop rather than keeping them separate. This makes the initial accumulation effectively redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file handles a lot of logic and, for example, embeds several magic literals directly:
MAXLEN = Number(process.env.MAX_LEN) || 3000
max_trans_num = Number(process.env.MAX_TRANSLATION_NO) || 5
{ limit: 100 }
in the API calls- Log prefixes like
"translation-summary-"
,"json-summary-"
,"emergency-log-"
- The
ignoredTags
array
Embedding these values makes configuration harder and ties defaults to code changes.
Proposed changes:
-
Extract config constants
- Move environment fallbacks, numeric limits, prefixes, and tag arrays into
config.ts
. - This lets you validate required vars and override settings (via
.env
, CI, etc.) without modifying application code.
- Move environment fallbacks, numeric limits, prefixes, and tag arrays into
-
Modularize by responsibility
config.ts
: all constants and environment setuplogger.ts
: error‑logging and summary helpersparser.ts
: SAX parser instantiation and XML escaping utilitiestranslator.ts
: core translation flow and CLI handlingio.ts
: file system utilities (directory traversal, stream management)
Breaking the file into focused modules and centralizing configuration will improve readability, testability, and ease of maintenance.
run yarn trans to start translation