-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore: fix utf-8 encoding returning buffers #51
Conversation
Updated the description with context. |
I just hit this too while trying to upgrade some really old modules to the latest versions of |
@achingbrain With This PR is not my preferred solution, it's a workaround. If it were semver-patch we could release it right away but it's semver-major (that bubbles up to dependents) so I don't want to rush this. Feedback on Level/memdown#186 is most welcome. |
Yes - with |
Hm, let's reconsider the assertion that this would be semver-major, because I only based that on the fact that the previous back-and-forth changes were semver-major. If we can all agree that the |
Closing in favor of Level/memdown#191. |
@achingbrain I just released |
History:
leveldown
however, may return data as a buffer and we've had to account for this. Let's call this the maybe-string problem. The primary solution has been to passleveldown
a boolean*asBuffer
option. If false,leveldown
returns data as a string.levelup
intoencoding-down
, we didn't take the*asBuffer
options into account (we didn't realize that at the time). Some stores would return a buffer instead of a string. To deal with that, coercion to string was added tolevel-codec
in Fix/utf8 decoding #12 (7.0.0).*asBuffer
logic was restored in asBuffer fix encoding-down#19; we thought coercion was no longer necessary.This PR restores the coercion, to work around an ecosystem quirk:
leveldown
andmemdown
handle strings and buffers differently. Whileleveldown
stores both types as a byte array (meaning you can put a buffer and get back a string if so desired, and vice versa),memdown
stores them as-is (meaning if you put a buffer, you'll get back a buffer; if you put a string, you'll get back a string - simplified). This leads to unexpected behavior.Another issue (which won't be fixed by this PR but is very relevant) is that
memdown
isn't able to compare a string key to a buffer key (or any other type for that matter); you can only safely use one key type in your db. Possible solutions are discussed in Level/memdown#186. Let's call this the mixed-type problem. It is relevant because:memdown
behave likeleveldown
and thus remove the need for thislevel-codec
PR. Before you say "that sounds like the simplest solution", wait...memdown
behave likelevel-js
which doesn't have the maybe-string problem either, albeit for a different reason. It treats strings and buffers as distinct keys and values, even if their bytes are the same. Arguably - especially when viewed outside of the historical context of Level - this is the least-surprising behavior because you get back what you store. Working with binary data is a distinctly different use case from working with utf8 strings. You'll only sometimes have the need to process utf8 data as binary, which you can still do.So, fixing the mixed-type problem might also fix the maybe-string problem, but we could still choose to merge this PR as a short- to medium-term solution.