Fix Capacitor iOS binary SQLite param handling#905
Fix Capacitor iOS binary SQLite param handling#905swhitt wants to merge 1 commit intopowersync-ja:mainfrom
Conversation
🦋 Changeset detectedLatest commit: 8cea1af The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
7e5ded0 to
e82cba0
Compare
Normalize typed-array payloads before calling Capacitor SQLite's iOS run() path. This avoids the "Error in reading buffer" failure when PowerSync sends line_binary payloads through powersync_control(...).
e82cba0 to
8cea1af
Compare
| return value; | ||
| } | ||
|
|
||
| function uint8ArrayToIOSBuffer(array: Uint8Array): IOSSqliteBufferParam { |
There was a problem hiding this comment.
Thanks for the contribution! It's annoying that this workaround is required, but it is what it is.
This feels so absurdly inefficient that I think we should look into not using line_binary on Capacitor at all. Or maybe we need a hack to encode the blob as hex and then decode it with unhex(?) in SQLite. That's still inefficient and I think we should only do it on platforms where we need it.
Out of curiosity, does this really work on Android or did you just test iOS? Anyway, can we return a regular JSON array here (e.g. return [...array])? That should be slightly more efficient, but it's still not great.
There was a problem hiding this comment.
Re: [...array], I think that'd skip the dict-based buffer path in CapacitorSQLite.swift entirely. The Record<string, number> builds the shape the Swift side expects. Haven't tested Android. Agree on unhex(?) longer-term.
stevensJourney
left a comment
There was a problem hiding this comment.
Thanks for the contribution!
I believe I've seen other reports of a similar issue before, but, we've not been able to reproduce this error on our end in our example-capacitor demo yet.
In our example, we can see binary payloads being sent to the Capacitor Community SQLite plugin. See the screenshot below from opening the Safari dev tools
These payloads work as expected on our end.
I believe the Error in reading buffer comes from here. Which would most likely indicate some casting error - as pointed out in your PR description. The fact that the calls work in our demo is still concerning though - which leads me to believe there might be another factor at play.
Could you perhaps share similar logs, which cause the issue mentioned in the PR? I assume the offending payloads should have a different structure.
One suspect might be if some Buffer polyfill is present in your project. If you do see a difference in the logs - could you share any polyfils of bundler config you might be using.
It would be really nice if we could get to the root cause of this issue. Thanks for your efforts!
|
No Buffer polyfills or custom bundler config here (Next.js 16, static export with a minimal config). I think it's coming from inside The binary payload reaching the Capacitor bridge isn't a plain // bundle.mjs line 10809
var buffer = bufferExports.Buffer.from(message.data);
// line 3868 - Buffer is a prototype-swapped Uint8Array
Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
// line 4626 - custom toJSON
Buffer.prototype.toJSON = function toJSON() {
return { type: "Buffer", data: Array.prototype.slice.call(this._arr || this, 0) };
};Chain: WebSocket The iOS bridge ( A log in print("Buffer read failed: key=\(key), value=\(String(describing: mVal)), type=\(type(of: mVal))")I'll try to add that locally, but probably won't get to it until later this week. Normalizing to a plain |
Fixes #904.
On Capacitor iOS, PowerSync can pass
Uint8Arraypayloads into:The Capacitor SQLite iOS bridge doesn't seem to accept that shape directly, and sync fails with:
This normalizes typed-array payloads at the Capacitor/native SQLite boundary before they hit
run(...).I think that keeps the fix in the right place and doesn't break anything unrelated. The sync layer can still use
Uint8Array, and we only adapt it where the native bridge needs a different shape.Not sure if a changeset makes sense here, but I think probably yes if this lands as a package fix.