Skip to content

Conversation

@rhashimoto
Copy link
Owner

@rhashimoto rhashimoto commented Jun 19, 2025

See #273

Using Proxy in the Facade implementation is convenient but has a performance cost. It is most noticeable with MemoryVFS and MemoryAsyncVFS; less so with VFS classes where persistent storage API calls (e.g. to OPFS and IndexedDB) become the bottleneck.

This PR replaces the use of Proxy in Facade with handwritten classes that have the same methods as Uint8Array and DataView for a small performance optimization.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @rhashimoto, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on a significant refactoring within the FacadeVFS to enhance performance. By replacing the existing JavaScript Proxy-based wrappers for WebAssembly memory access with custom-built proxy classes, I've aimed to reduce runtime overhead and provide more efficient handling of memory buffers, especially in scenarios where WebAssembly memory is frequently resized.

Highlights

  • Performance Optimization: I've replaced the use of built-in JavaScript Proxy objects within the FacadeVFS implementation with custom, handwritten classes (Uint8ArrayProxy and DataViewProxy). This change aims to reduce the performance overhead associated with Proxy objects, particularly noticeable in VFS implementations that primarily operate in memory, such as MemoryVFS and MemoryAsyncVFS.
  • Custom Buffer Handling for WebAssembly Memory: New Uint8ArrayProxy and DataViewProxy classes have been introduced. These classes mimic the behavior and methods of their native Uint8Array and DataView counterparts, respectively. Crucially, they include logic to automatically reacquire the underlying WebAssembly memory buffer when it is resized or detached, ensuring continued valid access to memory regions.
  • Refactored Memory Access Methods: The internal #makeTypedDataView and #makeDataArray methods in FacadeVFS have been updated. Instead of returning Proxy wrappers around native DataView or Uint8Array objects, they now instantiate and return instances of the newly created DataViewProxy and Uint8ArrayProxy classes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces handwritten proxy classes (Uint8ArrayProxy and DataViewProxy) to replace the standard JavaScript Proxy mechanism for accessing WebAssembly memory in FacadeVFS.js to enhance performance. The new proxies correctly handle WebAssembly memory resizes. The review focuses on ensuring type clarity in JSDoc and addressing // @ts-ignore comments.


// Copy data.
new Uint8Array(file.data, iOffset, pData.byteLength).set(pData);
new Uint8Array(file.data, iOffset, pData.byteLength).set(pData.subarray());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The change from pData to pData.subarray() is important and correct. It highlights that Uint8ArrayProxy is not a true Uint8Array.

Comment on lines +416 to +417
// @ts-ignore
return new DataViewProxy(this._module, byteOffset, type);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider changing the JSDoc return type to DataViewProxy for explicitness, or keep the JSDoc as DataView and add a brief comment explaining why ts-ignore is used (e.g., "DataViewProxy is a compatible subset of DataView"). This also applies to #makeDataArray.

* is resized.
* @param {number} byteOffset
* @param {number} byteLength
* @returns {Uint8Array}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The JSDoc return type is Uint8Array, but the method returns Uint8ArrayProxy. It might be beneficial to briefly echo this in the JSDoc for #makeDataArray.

}

/**
* @param {*} module

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The JSDoc type for the module parameter is {*} which is very generic. To improve type safety and code clarity, consider specifying a more precise type based on its usage within the class.

Suggested change
* @param {*} module
* @param {{ HEAPU8: Uint8Array }} module

return this.#array.subarray(begin, end);
}
toLocaleString(locales, options) {
// @ts-ignore

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Could you confirm if this // @ts-ignore for toLocaleString is due to a TypeScript libdef limitation?

}

/**
* @param {*} module

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to Uint8ArrayProxy, the JSDoc type for the module parameter is {*}. A more specific type would enhance clarity and type safety.

Suggested change
* @param {*} module
* @param {{ HEAPU8: { buffer: ArrayBuffer, byteOffset: number } }} module

@rhashimoto rhashimoto merged commit 4f2b7e8 into master Jun 21, 2025
1 check passed
@rhashimoto rhashimoto deleted the facade-proxy branch June 21, 2025 16:31
xesrevinu pushed a commit to effect-anything/wa-sqlite that referenced this pull request Jul 3, 2025
* Replace Proxy with handwritten proxy for jRead/jWrite buffers.

* Replace Proxy with handwritten proxy for VFS return data.

---------

Co-authored-by: Roy Hashimoto <[email protected]>
stevensJourney added a commit to powersync-ja/wa-sqlite that referenced this pull request Aug 26, 2025
* Update issue templates

* Replace Facade Proxy with handwritten proxy. (rhashimoto#285)

* Replace Proxy with handwritten proxy for jRead/jWrite buffers.

* Replace Proxy with handwritten proxy for VFS return data.

---------

Co-authored-by: Roy Hashimoto <[email protected]>

* Use non-CAPTCHA SQLite download URL. (rhashimoto#289)

* Use non-CAPTCHA SQLite download URL.

* Use consistent Makefile variable bracing.

---------

Co-authored-by: Roy Hashimoto <[email protected]>

* update build

* added changeset

---------

Co-authored-by: Roy Hashimoto <[email protected]>
Co-authored-by: Roy Hashimoto <[email protected]>
rhashimoto added a commit to team-reflect/wa-sqlite that referenced this pull request Sep 24, 2025
* Fix resetting isHandleRequested

* Bump package version.

* Fix hello demo import paths.

* Permit JS booleans to be bound to queries, as integer 0/1 values (rhashimoto#272)

* Permit boolean values to be bound to statements, as 0/1

* Add test for boolean binding

* Using a single TextEncoder for all string conversions

* Export HEAP* module members for recent EMSDK changes.

* Bump tar-fs from 3.0.8 to 3.0.9

Bumps [tar-fs](https://github.com/mafintosh/tar-fs) from 3.0.8 to 3.0.9.
- [Commits](mafintosh/tar-fs@v3.0.8...v3.0.9)

---
updated-dependencies:
- dependency-name: tar-fs
  dependency-version: 3.0.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

* Update SQLite to 3.50.1.

* Bump package version.

* Update issue templates

* Replace Facade Proxy with handwritten proxy. (rhashimoto#285)

* Replace Proxy with handwritten proxy for jRead/jWrite buffers.

* Replace Proxy with handwritten proxy for VFS return data.

---------

Co-authored-by: Roy Hashimoto <[email protected]>

* Use non-CAPTCHA SQLite download URL. (rhashimoto#289)

* Use non-CAPTCHA SQLite download URL.

* Use consistent Makefile variable bracing.

---------

Co-authored-by: Roy Hashimoto <[email protected]>

* Fix WebLocksMixin state initialization. (rhashimoto#293)

* Fix WebLocksMixin state initialization.

* Don't fetch state in WebLocksMixin file control unnecessarily.

* Minor fixes.

---------

Co-authored-by: Roy Hashimoto <[email protected]>

* Bump package version.

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Simon Binder <[email protected]>
Co-authored-by: Roy Hashimoto <[email protected]>
Co-authored-by: Grant Cox <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants