kvdex: DENO_CORE.serialize bug on Deno Deploy?
My code is working on local, but when deployed on Deno Deploy, it throws the following error:
TypeError: DENO_CORE.serialize is not a function
at Object.serialize (https://deno.land/x/kvdex@v0.23.1/src/utils.ts:564:20)
at Collection.setDoc (https://deno.land/x/kvdex@v0.23.1/src/collection.ts:1402:46)
at Collection.setDocument (https://deno.land/x/kvdex@v0.23.1/src/collection.ts:1369:23)
at Collection.add (https://deno.land/x/kvdex@v0.23.1/src/collection.ts:396:23)
at storeGroups (file:///src/kv-storage.ts:41:34)
at Server.handler (file:///src/main.ts:53:11)
at eventLoopTick (ext:core/01_core.js:183:11)
at async Server.#respond (https://deno.land/std@0.208.0/http/server.ts:313:18)
Could it be related to this: https://github.com/denoland/deno/issues/12379 ?
Note: I’m using
const db = kvdex(kv, {
apps: collection(GroupsModel, {
indices: {
urlid: "secondary",
timestamp: "secondary",
},
serialized: true,
idGenerator: () => ulid()
})
});
To define my collection.
About this issue
- Original URL
- State: closed
- Created 7 months ago
- Comments: 23 (14 by maintainers)
Commits related to this issue
- Fix serialization not working on Deno Deploy as per https://github.com/oliver-oloughlin/kvdex/issues/130 and https://github.com/denoland/deno/issues/12379 — committed to juliendorra/esquisse by juliendorra 7 months ago
- kvdex custom serialization has now been fixed "serialize = true => uses deno core by default (json when on deploy) serialize = "core" => always use core serialize = "json" => always use json serializ... — committed to juliendorra/esquisse by juliendorra 7 months ago
You can check out the benchmarks I made here: https://github.com/oliver-oloughlin/kvdex/tree/main/benchmarks/utils
It will definitely be faster than my custom json stringify/parse as it handles checks for every possible KvValue type. But I think it will still be way slower than a lot of other methods, like v8’s serialize (which is what Deno core uses), that serializes to Uint8Array. If you just have JSON data anyway, and it’s not ridiculously large (many 10s or even 100s of MB), I think you’ll be fine, the speed difference won’t be too noticeable. In a previous version of kvdex I used the basic JSON.parse/stringify for large objects, and I was using it in another project where I had data that reached about 150kB, and writing/reading was still done in just a few ms (roughly 5-15ms).
I’m still biased against a magic switch on Deploy, as it will have surprising effects for devs. It would be more consistent and as easy to always be explicit ie. deprecate the boolean.
Replace the true boolean by a “auto” option and I think it would be just perfect!
I have released a new version (v0.24.0) with the discussed changes (+ a few more smaller changes). Serialized collections should now work by default on Deploy, and be configurable between using the default chosen serializer, core, json or custom.
Just for comparison, here are the benchmark results for the json serializer and core serializer (roughly 58MB when serialized):
Yes it works! 🙏 🥳
Enabling your custom function with a flag would be useful! In the meantime maybe an alert in the readme that serialize won’t work as-is on Deno Deploy would be useful for others that might work on local and be surprised when deploying (as Deno Deploy is the go-to deploy option of the ecosystem)
I’ll test using Superserial and see if it could be a recommendation for other devs
JSON.parse and JSON.stringify by itself won’t work, because it only supports JSON values, which are a small subset of all values that can be stored in KV. I do however have a custom parse and stringify function which uses JSON.parse and JSON.stringify with custom replacer/reviver functions that works with all KvValue types. Actually, it’s a solution I used for kvdex before I changed it to use Deno.core instead. The downside is that it’s A LOT slower. I’m currently working on adding it as an extension, so that it available for use, but optional.
Superserial may work, but it’s a third-party library, so I don’t want to make it a default. You can however try using it, check my first answer to see how to set custom serialize/deserialize functions for any collection.
After a quick look it seems like kvfs just saves Uint8Array data as chunks, which I already do in kvdex. That’s not really the issue. The problem that needs solving is being able to take any JavaScript object and serialize it as a Uint8Array, and to do the opposite when deserializing.