Skip to content

Commit

Permalink
feat(scripts): add compression script as library
Browse files Browse the repository at this point in the history
  • Loading branch information
MrWook committed Sep 30, 2024
1 parent cb25ca2 commit b7c642f
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packages/libraries/dictionaryCompression/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.


12 changes: 12 additions & 0 deletions packages/libraries/dictionaryCompression/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# @zxcvbn-ts/dictionary-compression

This repository provides utilities for compression and decompression to optimize the bundle size of zxcvbn-ts language packages. It helps reduce the package size for both NPM downloads and client-side usage.

## Purpose
The primary goal of this repository is to centralize the compression logic used across all zxcvbn-ts language packages. This avoids duplication of code and ensures that language packages remain lightweight.

## Usage
By default, all zxcvbn-ts language packages already include this functionality. As a user of zxcvbn-ts, you do not need to interact with or directly use this repository. It serves as a shared resource for the language packages themselves, not for end-users.

## Why This Repository?
Without this repository, each zxcvbn-ts language package would need to include its own compression and decompression logic, leading to larger bundle sizes. By consolidating this logic here, we ensure a more efficient and maintainable approach to handling language package compression.
32 changes: 32 additions & 0 deletions packages/libraries/dictionaryCompression/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@zxcvbn-ts/dictionary-compression",
"version": "4.0.0-beta.0",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"description": "dictionary-compression helper for zxcvbn-ts language packages",
"license": "MIT",
"homepage": "https://github.com/zxcvbn-ts/zxcvbn",
"repository": {
"type": "git",
"url": "https://github.com/zxcvbn-ts/zxcvbn.git"
},
"author": "zxcvbn-ts",
"files": [
"dist",
"src"
],
"publishConfig": {
"access": "public"
},
"dependencies": {
"@alttiri/base85": "1.8.0",
"fflate": "^0.8.2"
},
"keywords": [
"zxcvbn-ts",
"language",
"compression",
"decompression"
]
}
52 changes: 52 additions & 0 deletions packages/libraries/dictionaryCompression/src/compress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { compressSync, strToU8 } from 'fflate'
import { encodeBase85 } from '@alttiri/base85'

const isCompactDoubleQuotedString = (string: string) => {
// eslint-disable-next-line no-control-regex
return !string.match(/[\x00-\x1f\u2028\u2029\\"]/)
}

const compressWithPrefix = (parsed: string[]) => {
if (!Array.isArray(parsed)) {
return parsed
}
if (
!parsed.every(
(entry) =>
typeof entry === 'string' && isCompactDoubleQuotedString(entry),
)
) {
// Should be rare enough, so don't bother escape them.
return parsed
}

const deltas: string[] = []
let last = ''
parsed.forEach((entry) => {
let prefixLen = 0
const maxPrefixLen = Math.min(entry.length, last.length, 25)
while (
prefixLen < maxPrefixLen &&
entry.charAt(prefixLen) === last.charAt(prefixLen)
) {
prefixLen += 1
}
deltas.push(String.fromCharCode(65 + prefixLen) + entry.slice(prefixLen))
last = entry
})

return deltas
}

export default function compress(data: string[]) {
const compressedWithPrefix = compressWithPrefix(data)
const compressedWithGzip = compressSync(
strToU8(compressedWithPrefix.join('')),
{
level: 9,
mem: 12,
},
)

return encodeBase85(compressedWithGzip)
}
19 changes: 19 additions & 0 deletions packages/libraries/dictionaryCompression/src/decompress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { decompressSync, strFromU8 } from 'fflate'
import { decodeBase85 } from '@alttiri/base85'

export default function decompress(encodedString: string) {
const decoded = decodeBase85(encodedString)
const decompressedBuffer = decompressSync(decoded)
const decompressedArray = strFromU8(decompressedBuffer).split(/([A-Z])/g)
const decompressedData = []
let last = ''
let i
for (i = 1; i < decompressedArray.length; i += 2) {
last =
last.slice(0, decompressedArray[i].charCodeAt(0) - 65) +
decompressedArray[i + 1]
decompressedData.push(last)
}

return decompressedData
}
4 changes: 4 additions & 0 deletions packages/libraries/dictionaryCompression/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import compress from './compress'
import decompress from './decompress'

export { compress, decompress }
7 changes: 7 additions & 0 deletions packages/libraries/dictionaryCompression/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"lib": ["es2018", "dom"],
"types": ["node", "jest"]
}
}

0 comments on commit b7c642f

Please sign in to comment.