Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃悰 BUG: D1 via miniflare doesn't accept Buffer type for blobs #5771

Open
sdarnell opened this issue May 7, 2024 · 0 comments
Open

馃悰 BUG: D1 via miniflare doesn't accept Buffer type for blobs #5771

sdarnell opened this issue May 7, 2024 · 0 comments
Labels
bug Something that isn't working

Comments

@sdarnell
Copy link

sdarnell commented May 7, 2024

Which Cloudflare product(s) does this pertain to?

D1, Miniflare

What version(s) of the tool(s) are you using?

3.53.1 [Wrangler]

What version of Node are you using?

20.10.0

What operating system and version are you using?

Mac Sonoma 14.4.1

Describe the Bug

Observed behavior

When testing D1 locally with Miniflare blob columns are not handled correctly.

If I pass in a Unit8Array I can write to the blob column just fine.
But if I pass a Buffer, there's an assert in Miniflare's marshalling code (devalue handler).

Here's the code, see src/routes/api/d1/[id]/+server.ts:

	// Passing a Uint8Array works fine
	// const data = new Uint8Array([99, 88, 77]);
	const data = Buffer.from(new Uint8Array([99, 88, 77]));

	const result = await DB.prepare('INSERT INTO users (id, email, data) VALUES(?, ?, ?)')
		.bind(1, 'test@example.com', data).run();

The assert on the console is:

Error [AssertionError]: false == true
    at new AssertionError (node-internal:internal_assertionerror:419:15)
    at assert (node-internal:internal_assert:49:15)
    at ArrayBufferView (file:///username/work/folder/d1-buffer/cf-svelte/node_modules/miniflare/src/workers/core/devalue.ts:95:3)
    at hydrate (file:////username/work/folder/d1-buffer/cf-svelte/node_modules/.pnpm/devalue@4.3.2/node_modules/devalue/src/parse.js:60:32)
    at hydrate (file:////username/work/folder/d1-buffer/cf-svelte/node_modules/.pnpm/devalue@4.3.2/node_modules/devalue/src/parse.js:115:17)
    at unflatten (file:////usernamel/work/folder/d1-buffer/cf-svelte/node_modules/.pnpm/devalue@4.3.2/node_modules/devalue/src/parse.js:132:9)
    at parse (file:////username/work/folder/d1-buffer/cf-svelte/node_modules/.pnpm/devalue@4.3.2/node_modules/devalue/src/parse.js:16:9)
    at parseWithReadableStreams (file:///Users/stephendarnell/work/folder/d1-buffer/cf-svelte/node_modules/miniflare/src/workers/core/devalue.ts:313:9)
    at #fetch (file:////username/work/folder/d1-buffer/cf-svelte/node_modules/miniflare/src/workers/core/proxy.worker.ts:244:12)
    at async ProxyServer.fetch (file:////username/work/folder/d1-buffer/cf-svelte/node_modules/miniflare/src/workers/core/proxy.worker.ts:128:11) {
  [cause]: undefined
} 

The repro repository is: https://github.com/sdarnell/cf-svelte branch bugs/d1-buffer

A second related issue (happy to raise separately) is that the data returned from a blob seems to be a regular array, when I think it would be most sensibly be a ArrayBuffer/Uint8Array.

console.log(`Data Typeof ${typeof data} isArray ${Array.isArray(data)} ctor ${data.constructor.name}`);
console.log(`Instanceof ArrayBuffer ${data instanceof ArrayBuffer} isView ${ArrayBuffer.isView(data)}`);

produces:

Data Typeof object isArray true ctor Array
Instanceof ArrayBuffer false isView false

Which suggests to me that it is a plain old JS array.

Expected behavior

The expected behaviour is that the Buffer should be handled the same as the Uint8Array().

Note that switching to Uint8Array would be much more convenient and sensible to me, but I'm using Drizzle (not included in the repro), and the Drizzle types require a Buffer. Though if I jimmy the types and pass a Unit8Array regardless (fingers in ears, la la la) it seems to work ok.

I haven't found a good CF examples or documentation of what the allowable, required types are.
There is : https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/#type-conversion
which says that ArrayBuffer will be converted to BLOB. But clearly there are lots of other array variants.

Drizzle documentation/examples for blobs are near non-existent.

It's also unclear whether the CF runtime in production has a Buffer type.

Steps to reproduce

Please provide the following:

  • A minimal working subset of your worker code

The repro repository is: https://github.com/sdarnell/cf-svelte branch bugs/d1-buffer

  • A minimal working subset of your wrangler.toml

File is in the repo:

[[d1_databases]]
binding = "DB"
database_name = "test-db"
database_id = "f6c5717c-3866-45d3-b4e7-20b332e359e0"
preview_database_id = "0a83bfd7-9827-44f8-9ad4-a0fe906818c3"
  • Commands used to start your local dev server, including custom env and cli args

See README.md but npm run dev runs a simple sveltekit project with buttons in the UI to issue read/write/delete commands to D1.

Beforehand you will need to apply the migrations (trivial single table).

npm run migration:apply
  • Steps to be performed in the browser, curl commands, or a test we can run that reliably fails (at least a percent of the time)

A git repo we can clone and run a test suit on, or which has a README with step-by-step instructions, is even better. In this case, please use the field below to provide a link to the minimal repro.

Please provide a link to a minimal reproduction

https://github.com/sdarnell/cf-svelte/tree/bugs/d1-buffer

Please provide any relevant error logs

Stack trace of assertion in main issue.

@sdarnell sdarnell added the bug Something that isn't working label May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something that isn't working
Projects
Status: Untriaged
Development

No branches or pull requests

1 participant