Open MeirionHughes opened 12 months ago
Yeah that's a bug. I'm guessing it's caused by class properties not being enumerable. Or more generally, the assumption that an encoding is a plain object (which is my bad).
The encoding is cloned as { ...options }
here and thus won't include class methods: https://github.com/Level/transcoder/blob/8963603dc4a7c1c599beb85bad3e09788e0235d1/index.js#L111
yeah I assumed it was cloning issue.
I also notice that in Encoding class, it rebinds the option encode and decode functions 'this'. I have configured custom encoder class that changes the decoding (option to skip certain certain parts of the encoded binary and not decode them), and has its own this context - so I suspect that won't work either.
I can get around this either by wrapping object + closures and/or deriving from abstract class Encoding.
function safeOptions(base, name) {
const options = { name: name || base.name, format: base.format };
options.encode = base.encode ? function (...args) { return base.encode(...args) } : null;
options.decode = base.decode ? function (...args) { return base.decode(...args) } : null;
return options;
}
switch (detectFormat(options)) {
case 'view': return new ViewFormat(safeOptions(options, name))
case 'utf8': return new UTF8Format(safeOptions(options, name))
case 'buffer': return new BufferFormat(safeOptions(options, name))
default: {
throw new TypeError("Format must be one of 'buffer', 'view', 'utf8'")
}
}
lets the test (with a class) pass; not sure if you'd rather do it differently
I'd be okay with a short-term solution like that (and to later refactor it). I don't have capacity atm to think about alternatives.
I'm not sure if this would be a bug as its a new code-base afterall; but its certainly a deviation from the leveldown way, where this worked.