diff --git a/.changeset/perfect-islands-type.md b/.changeset/perfect-islands-type.md new file mode 100644 index 00000000..10030a2e --- /dev/null +++ b/.changeset/perfect-islands-type.md @@ -0,0 +1,5 @@ +--- +"@capsizecss/unpack": patch +--- + +Reduces `@capsizecss/unpack` install size by using a lighter weight package for extracting font file metrics diff --git a/.changeset/silver-buttons-bake.md b/.changeset/silver-buttons-bake.md new file mode 100644 index 00000000..35bbdd58 --- /dev/null +++ b/.changeset/silver-buttons-bake.md @@ -0,0 +1,15 @@ +--- +"@capsizecss/unpack": major +--- + +This package is now ESM-only. + +In most projects you can continue to use the package as before. CommonJS (CJS) projects using Node.js <20, should update to use a dynamic import: + +```js +// For CJS projects before Node 20 +const { fromBuffer } = await import('@capsizecss/unpack'); + +// For all other projects +import { fromBuffer } from '@capsizecss/unpack'; +``` diff --git a/README.md b/README.md index fe40c3df..0ec71ada 100644 --- a/README.md +++ b/README.md @@ -401,7 +401,7 @@ See the [package](packages/unpack/README.md) for documentation. ## Thanks - [Vincent De Oliveira](https://twitter.com/iamvdo) for writing [Deep dive CSS: font metrics, line-height and vertical-align](https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align), which provided the research needed to build all this. -- [Devon Govett](https://github.com/devongovett) for creating [Fontkit](https://github.com/foliojs/fontkit), which does all the heavy lifting of extracting the font metrics under the covers. +- [Devon Govett](https://github.com/devongovett) for creating [Fontkit](https://github.com/foliojs/fontkit). A [fork of Fontkit](https://github.com/delucis/fontkitten) does all the heavy lifting of extracting the font metrics under the covers. - [SEEK](https://www.seek.com.au) for giving us the space to do interesting work. ## License diff --git a/packages/unpack/README.md b/packages/unpack/README.md index 178f0078..3a92c6b2 100644 --- a/packages/unpack/README.md +++ b/packages/unpack/README.md @@ -100,7 +100,7 @@ The font metrics object returned contains the following properties: ## Thanks -- [Devon Govett](https://github.com/devongovett) for creating [Fontkit](https://github.com/foliojs/fontkit), which does all the heavy lifting of extracting the font metrics under the covers. +- [Devon Govett](https://github.com/devongovett) for creating [Fontkit](https://github.com/foliojs/fontkit). A [fork of Fontkit](https://github.com/delucis/fontkitten) does all the heavy lifting of extracting the font metrics under the covers. - [SEEK](https://www.seek.com.au) for giving us the space to do interesting work. ## License diff --git a/packages/unpack/package.json b/packages/unpack/package.json index 58f1c0eb..9bb79e30 100644 --- a/packages/unpack/package.json +++ b/packages/unpack/package.json @@ -23,17 +23,16 @@ "name": "Michael Taranto", "homepage": "https://github.com/michaeltaranto" }, + "type": "module", "exports": { ".": { "@capsizecss/src": "./src/index.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.cjs" + "default": "./dist/index.mjs" }, "./package.json": "./package.json" }, - "main": "./dist/index.cjs", "module": "./dist/index.mjs", - "types": "./dist/index.d.cts", + "types": "./dist/index.d.mts", "files": [ "dist" ], @@ -42,10 +41,9 @@ "generate": "tsx scripts/generate-weightings" }, "dependencies": { - "fontkit": "^2.0.2" + "fontkitten": "^1.0.0" }, "devDependencies": { - "@types/fontkit": "^2.0.1", "@types/node": "^22.18.8", "fast-xml-parser": "^4.3.2", "sort-keys": "^5.0.0", @@ -57,11 +55,9 @@ }, "publishConfig": { "exports": { - ".": { - "import": "./dist/index.mjs", - "require": "./dist/index.cjs" - }, + ".": "./dist/index.mjs", "./package.json": "./package.json" } - } + }, + "main": "./dist/index.mjs" } diff --git a/packages/unpack/scripts/generate-weightings.ts b/packages/unpack/scripts/generate-weightings.ts index 00721eb7..a03b6834 100644 --- a/packages/unpack/scripts/generate-weightings.ts +++ b/packages/unpack/scripts/generate-weightings.ts @@ -1,8 +1,11 @@ -import fs from 'fs/promises'; -import path from 'path'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; import { XMLParser } from 'fast-xml-parser'; import sortKeys from 'sort-keys'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + type WikiNewsFeed = { feed: { doc: { diff --git a/packages/unpack/src/index.ts b/packages/unpack/src/index.ts index 43ac367b..7e2c6aee 100644 --- a/packages/unpack/src/index.ts +++ b/packages/unpack/src/index.ts @@ -1,5 +1,9 @@ -import * as fontkit from 'fontkit'; -import type { Font as FontKitFont } from 'fontkit'; +import { + create, + type Font as FontKitFont, + type FontCollection, +} from 'fontkitten'; +import { readFile } from 'node:fs/promises'; import weightings from './weightings'; @@ -83,17 +87,14 @@ const unpackMetricsFromFont = (font: FontKitFont) => { export type Font = ReturnType; -const handleCollectionErrors = ({ - font, - postscriptName, - apiName, - apiParamName, -}: { - font: FontKitFont | null; - postscriptName?: string; - apiName: string; - apiParamName: string; -}) => { +function handleCollectionErrors( + font: FontKitFont | FontCollection | null, + { + postscriptName, + apiName, + apiParamName, + }: { postscriptName?: string; apiName: string; apiParamName: string }, +): asserts font is FontKitFont { if (postscriptName && font === null) { throw new Error( [ @@ -108,7 +109,7 @@ const handleCollectionErrors = ({ ); } - if (font !== null && 'fonts' in font && Array.isArray(font.fonts)) { + if (font !== null && font.isCollection) { const availableNames = font.fonts.map((f) => f.postscriptName); throw new Error( [ @@ -126,25 +127,18 @@ const handleCollectionErrors = ({ ].join('\n'), ); } -}; +} interface Options { postscriptName?: string; } -export const fromFile = (path: string, options?: Options): Promise => { - const { postscriptName } = options || {}; - - return fontkit.open(path, postscriptName).then((font) => { - handleCollectionErrors({ - font, - postscriptName, - apiName: 'fromFile', - apiParamName: 'path', - }); - - return unpackMetricsFromFont(font); - }); +export const fromFile = async ( + path: string, + options?: Options, +): Promise => { + const buffer = await readFile(path); + return _fromBuffer(buffer, 'fromFile', 'path', options); }; const _fromBuffer = async ( @@ -155,10 +149,9 @@ const _fromBuffer = async ( ) => { const { postscriptName } = options || {}; - const fontkitFont = fontkit.create(buffer, postscriptName); + const fontkitFont = create(buffer, postscriptName); - handleCollectionErrors({ - font: fontkitFont, + handleCollectionErrors(fontkitFont, { postscriptName, apiName, apiParamName, diff --git a/packages/unpack/tsdown.config.ts b/packages/unpack/tsdown.config.ts index 8a42d6a5..da0caf5b 100644 --- a/packages/unpack/tsdown.config.ts +++ b/packages/unpack/tsdown.config.ts @@ -1,4 +1,7 @@ import { defineConfig } from 'tsdown'; import { baseConfig } from '../../tsdown.base.config.ts'; -export default defineConfig(baseConfig); +export default defineConfig({ + ...baseConfig, + format: ['esm'], +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ade06b0..6c7543c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,13 +102,10 @@ importers: packages/unpack: dependencies: - fontkit: - specifier: ^2.0.2 - version: 2.0.2 + fontkitten: + specifier: ^1.0.0 + version: 1.0.0 devDependencies: - '@types/fontkit': - specifier: ^2.0.1 - version: 2.0.1 '@types/node': specifier: ^22.18.8 version: 22.18.8 @@ -1914,9 +1911,6 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.4.12': - resolution: {integrity: sha512-R6RmwS9Dld5lNvwKlPn62+piU+WDG1sMfsnfJioXCciyko/gZ0DQ4Mqglhq1iGU1nQ/RcGkAwfMH+elMSkJH3Q==} - '@swc/types@0.1.25': resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} @@ -1965,9 +1959,6 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/fontkit@2.0.1': - resolution: {integrity: sha512-B5Jk560iAlWJ56yV1yBUH8Ek9LykCzb3N0FwJHtbH/Vmd/E1QN/Isen4SAtBb2UEWpZid4GjLm1Fih1xM0MbXA==} - '@types/hast@2.3.4': resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} @@ -2351,9 +2342,6 @@ packages: brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - brotli@1.3.3: - resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} - browser-resolve@2.0.0: resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==} @@ -2524,10 +2512,6 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - clone@2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -2757,9 +2741,6 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - dfa@1.2.0: - resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} - diff@8.0.2: resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} engines: {node: '>=0.3.1'} @@ -3122,8 +3103,9 @@ packages: resolution: {integrity: sha512-a8Ge6cdKh9za/GZR/qtigTAk7SrGore56EFcoMshClsh7FLk1zwszc/ltuMfKhx56qeuyL/jWQ4J4axou0iJ9w==} engines: {node: '>=10'} - fontkit@2.0.2: - resolution: {integrity: sha512-jc4k5Yr8iov8QfS6u8w2CnHWVmbOGtdBtOXMze5Y+QD966Rx6PEVWXSEGwXlsDlKtu1G12cJjcsybnqhSk/+LA==} + fontkitten@1.0.0: + resolution: {integrity: sha512-b0RdzQeztiiUFWEDzq6Ka26qkNVNLCehoRtifOIGNbQ4CfxyYRh73fyWaQX/JshPVcueITOEeoSWPy5XQv8FUg==} + engines: {node: '>=20'} for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -3956,9 +3938,6 @@ packages: resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} engines: {node: '>=14.16'} - pako@0.2.9: - resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} - pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -4344,9 +4323,6 @@ packages: resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} engines: {node: '>=4'} - restructure@3.0.0: - resolution: {integrity: sha512-Xj8/MEIhhfj9X2rmD9iJ4Gga9EFqVlpMj3vfLnV2r/Mh5jRMryNV+6lWh9GdJtDBcBSPIqzRdfBQ3wDtNFv/uw==} - reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -4849,12 +4825,6 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - unicode-properties@1.4.1: - resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} - - unicode-trie@2.0.0: - resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} - universal-user-agent@6.0.0: resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} @@ -7038,10 +7008,6 @@ snapshots: '@swc/counter@0.1.3': {} - '@swc/helpers@0.4.12': - dependencies: - tslib: 2.8.1 - '@swc/types@0.1.25': dependencies: '@swc/counter': 0.1.3 @@ -7108,10 +7074,6 @@ snapshots: '@types/estree@1.0.8': {} - '@types/fontkit@2.0.1': - dependencies: - '@types/node': 22.18.8 - '@types/hast@2.3.4': dependencies: '@types/unist': 2.0.6 @@ -7606,10 +7568,6 @@ snapshots: brorand@1.1.0: {} - brotli@1.3.3: - dependencies: - base64-js: 1.5.1 - browser-resolve@2.0.0: dependencies: resolve: 1.22.1 @@ -7797,8 +7755,6 @@ snapshots: clone@1.0.4: {} - clone@2.1.2: {} - color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -8020,8 +7976,6 @@ snapshots: detect-node-es@1.1.0: {} - dfa@1.2.0: {} - diff@8.0.2: {} diffie-hellman@5.0.3: @@ -8404,17 +8358,9 @@ snapshots: dependencies: tslib: 2.8.1 - fontkit@2.0.2: + fontkitten@1.0.0: dependencies: - '@swc/helpers': 0.4.12 - brotli: 1.3.3 - clone: 2.1.2 - dfa: 1.2.0 - fast-deep-equal: 3.1.3 - restructure: 3.0.0 tiny-inflate: 1.0.3 - unicode-properties: 1.4.1 - unicode-trie: 2.0.0 for-each@0.3.3: dependencies: @@ -9249,8 +9195,6 @@ snapshots: registry-url: 6.0.1 semver: 7.7.3 - pako@0.2.9: {} - pako@1.0.11: {} parent-module@1.0.1: @@ -9662,8 +9606,6 @@ snapshots: onetime: 2.0.1 signal-exit: 3.0.7 - restructure@3.0.0: {} - reusify@1.0.4: {} rimraf@2.7.1: @@ -10258,16 +10200,6 @@ snapshots: undici-types@6.21.0: {} - unicode-properties@1.4.1: - dependencies: - base64-js: 1.5.1 - unicode-trie: 2.0.0 - - unicode-trie@2.0.0: - dependencies: - pako: 0.2.9 - tiny-inflate: 1.0.3 - universal-user-agent@6.0.0: {} universalify@0.1.2: {}