Skip to content

Commit

Permalink
Fix SEGFAULT error by new Intl.Segmenter().segment() in the standal…
Browse files Browse the repository at this point in the history
…one binary

Baking the compatible ICU data with the Node binary.
  • Loading branch information
yhatt committed Sep 25, 2024
1 parent d2c6441 commit 685d793
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@
},
"pkg": {
"scripts": "lib/**/*.js",
"assets": [
"node_modules/vm2/**/*"
]
"assets": ["tmp/icu/icudt*.dat"]
},
"browserslist": [
"> 1% and last 3 versions",
Expand All @@ -61,7 +59,7 @@
"lint:css": "stylelint \"src/**/*.{css,scss}\"",
"prepack": "npm-run-all --parallel check:* lint:* test:coverage --parallel build types",
"preversion": "run-p check:* lint:* test:coverage",
"standalone": "node -e 'fs.rmSync(`bin`,{recursive:true,force:true})' && pkg --out-path ./bin .",
"standalone": "node -e 'fs.rmSync(`bin`,{recursive:true,force:true})' && pkg --options \"icu-data-dir=$(node ./scripts/icu.mjs)\" --out-path ./bin .",
"standalone:pack": "node ./scripts/pack.js",
"test": "jest",
"test:coverage": "jest --coverage",
Expand Down
53 changes: 53 additions & 0 deletions scripts/icu.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* For baking the ICU data into the standalone binary, we need to download the compatible ICU data from the ICU repository. */
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { promisify } from 'node:util'
import yauzl from 'yauzl'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const icuDir = path.join(__dirname, '../tmp/icu')
await fs.promises.mkdir(icuDir, { recursive: true })

const zipFromBuffer = promisify(yauzl.fromBuffer)

// Get the ICU version and endianness
const [icuMajor, icuMinor] = process.versions.icu.split('.')
const icuEndianness = process.config.variables.icu_endianness.toLowerCase()

// Download the ICU data
const response = await fetch(
`https://github.com/unicode-org/icu/releases/download/release-${icuMajor}-${icuMinor}/icu4c-${icuMajor}_${icuMinor}-data-bin-${icuEndianness}.zip`
)

if (!response.ok) {
throw new Error(`Failed to download ICU data: ${response.statusText}`)
}

// Extract the ICU data
const zip = await zipFromBuffer(Buffer.from(await response.arrayBuffer()), {
lazyEntries: true,
})

const icuDat = await new Promise((res, rej) => {
zip.on('error', (err) => rej(err))
zip.on('entry', async (entry) => {
if (/icudt\d+.\.dat/.test(entry.fileName)) {
zip.openReadStream(entry, (err, readStream) => {
if (err) return rej(err)

const output = path.join(icuDir, entry.fileName)

readStream.pipe(fs.createWriteStream(output))
res(output)
})
} else {
zip.readEntry()
}
})
zip.on('end', () => rej(meta))
zip.readEntry()
})

// Print the relative path to the ICU data from the project root
console.log(path.relative(path.join(__dirname, '../'), icuDat))

0 comments on commit 685d793

Please sign in to comment.