kle-serial-alt
v0.1.0
Published
Alternative KLE (Keyboard Layout Editor) raw data parser with rx/ry rotation cluster fixes. Drop-in replacement for @ijprest/kle-serial.
Maintainers
Readme
kle-serial-alt
Alternative parser for Keyboard Layout Editor (KLE) raw data, written in TypeScript.
Drop-in replacement for @ijprest/kle-serial with rotation-cluster bugfixes that bring the output in line with KLE's own serial.js.
Why this fork-ish alternative?
@ijprest/kle-serial 0.15.1 (and older) mishandles rx / ry rotation cluster origins:
- The first key of a rotation cluster lands at
(0, 0)instead of(rx, ry) - When only one of
rx/rychanges, the other axis of the cursor is not snapped back to the cluster origin
Both of these break real layouts that declare many single-key rotation clusters (e.g. highly ergonomic designs). kle-serial-alt re-implements the parser so rotation behaviour matches KLE's own runtime.
Install
npm install kle-serial-altPeer: Node 18+ / modern browsers (ESM + CJS builds included).
Usage
import { deserialize, parse, Serial } from 'kle-serial-alt'
// From an already-parsed array
const keyboard = deserialize([
{ name: 'Sample' },
['0,0', '0,1'],
['1,0', '1,1'],
])
// From a JSON / JSON5 string (KLE "Raw data" tab often uses JSON5 syntax)
const fromString = parse(`[
{ name: "Sample" },
["0,0", "0,1",],
["1,0", "1,1",],
]`)
// Compatible namespace for drop-in migration from @ijprest/kle-serial
const alsoOk = Serial.deserialize([...])
for (const k of keyboard.keys) {
console.log(k.x, k.y, k.width, k.rotation_angle, k.labels[0])
}Type exports
import type { Key, Keyboard, KeyboardMetadata } from 'kle-serial-alt'API
deserialize(rows: unknown[]): Keyboard
Parses an array of rows (the native KLE raw shape) and returns a Keyboard.
Throws KleDeserializeError for structurally invalid input (e.g. rotation specified on a non-first key, metadata object not at the head).
parse(json: string): Keyboard
Parses a JSON / JSON5 string. KLE's "Raw data" tab emits JSON5 (unquoted keys, trailing commas), so use parse when you have the raw tab contents. For already-valid JSON, deserialize(JSON.parse(s)) works too.
Serial
Namespace object re-exporting { deserialize, parse } — convenient for drop-in migration from @ijprest/kle-serial via:
// before
import { Serial } from '@ijprest/kle-serial'
// after
import { Serial } from 'kle-serial-alt'Classes
Key— per-key shape matching kle-serial (x,y,width,height,x2,y2,width2,height2,rotation_x,rotation_y,rotation_angle,color,labels[],textColor[],textSize[],decal,ghost,stepped,nub,profile,sm,sb,st).KeyboardMetadata— top-level metadata (name,author,notes,backcolor,switchBrand,switchMount,switchType,radii,css,pcb,plate).Keyboard—{ meta: KeyboardMetadata, keys: Key[] }.
Differences from @ijprest/kle-serial
| Aspect | @ijprest/kle-serial 0.15.1 | kle-serial-alt |
|---|---|---|
| rx resets current.x | ❌ | ✅ |
| ry resets current.y | ❌ | ✅ |
| Only rx specified → current.y snaps to rotation_y | ❌ | ✅ |
| Only ry specified → current.x snaps to rotation_x | ❌ | ✅ |
| Return shape (Key, Keyboard) | matches | matches |
| JSON5 input | via Serial.parse | via parse / Serial.parse |
| License | MIT | MIT |
Field names and the shape of returned objects are otherwise identical, so swapping in kle-serial-alt typically requires only changing the import specifier.
License
MIT — derived in part from kle-serial (MIT, © Ian Prest).
