From 6c689a3c7cd71c0a4d067b42e0738f8fc9658b1d Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 20 Jun 2025 11:50:55 -0500 Subject: [PATCH] Update compression file --- src/state/queries/nudges/compression.ts | 47 ++++++++++++++++++++----- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/state/queries/nudges/compression.ts b/src/state/queries/nudges/compression.ts index bc88b03c0b..9fd430b74e 100644 --- a/src/state/queries/nudges/compression.ts +++ b/src/state/queries/nudges/compression.ts @@ -1,26 +1,55 @@ +/* + * This module provides functions to pack and unpack flags into a compact + * binary format for storage in our NUX system. Given the max length of 300 + * characters, and a 6-bit encoding scheme, we can store up to 1800 flags in a + * single string. + */ + +const TRUTHY = '1' +const FALSY = '0' + +/** + * Total number of characters that flags can be packed. This corresponds to the + * max-length of a NUX. + */ const MAX_FLAGS = 300 -const FLAGS_PER_CHAR = 6 + +/** + * Length of binary string chunks used to encode flags. + */ +const CHAR_CODE_LENGTH = 6 export function pack(flags: Record) { const values = Object.values(flags) + if (values.length > MAX_FLAGS) { throw new Error(`Too many flags. Maximum supported is ${MAX_FLAGS}`) } - const compacted = values.map(value => value ? '1' : '0').join('') - // split into chunks of 6 values - const encoded = (compacted.match(/.{1,6}/g) || []) - .map(chunk => String.fromCharCode(parseInt(chunk.padEnd(6, '0'), 2))) + + /* + * Splits `compactBinaryNotation` string into 6 char chunks of 0s and 1s. + */ + const compactBinaryNotation = values + .map(value => (value ? TRUTHY : FALSY)) .join('') + const matcher = new RegExp(`.{1,${CHAR_CODE_LENGTH}}`, 'g') + const encoded = (compactBinaryNotation.match(matcher) || []) + .map(chunk => + String.fromCharCode(parseInt(chunk.padEnd(CHAR_CODE_LENGTH, '0'), 2)), + ) + .join('') + return encoded } export function unpack(encoded: string, keys: K[]) { - const binary = encoded.split('') - .map(char => char.charCodeAt(0).toString(2).padEnd(6, '0')) + const compactBinaryNotation = encoded + .split('') + .map(char => char.charCodeAt(0).toString(2).padEnd(CHAR_CODE_LENGTH, '0')) .join('') + return keys.reduce((obj, key, i) => { - obj[key] = binary[i] === '1' + obj[key] = compactBinaryNotation[i] === TRUTHY return obj }, {} as Record) } -