Skip to content

Write binary files given to ready() as bytes in both Workers #65

Closed

Description

@kazupon

Summary

  • Goal: Binary files (ArrayBuffers) passed to ready({ files }) reach the virtual filesystems of both Workers with their bytes, as the type and documentation of VrowzerConfig.files promise.
  • Current gap: The runtime sends the initial files to both Workers as text, and both Workers write them with { encoding: 'utf8' }.
    • The Web Worker receives them in V_WW_SETUP's files.
    • The Service Worker receives them in V_FS_INIT's files.
    • An ArrayBuffer written this way becomes the string [object ArrayBuffer].
  • Effect:
    • Every binary file given to ready() is corrupted: images, fonts, WASM, and so on.
    • Public images given to ready() are now served (since #64), but with that content.
    • Binary files added later with addFile() or updateFile() are not affected.
  • Request: Send binary initial files to both Workers as binary, write them as bytes, and keep the caller's buffers usable.
  • Verification status: Reproduced in Node.js with the built @vrowzer/fs subscriber, which is what the Service Worker uses (see Details).
    • The Web Worker side was found by reading the code. It writes the files the same way.
    • Not checked in a browser.
  • Related: Found while working on #62. A fix may use FileSystemPublisher.initFiles(), which has its own bug (#63).

Details

Current implementation, verification, requested behavior, and acceptance criteria

Current implementation

Reviewed at 750be3a.

Verification

I ran the following with Node.js v24.21.0. It used the built @vrowzer/fs (packages/fs/dist), built from ba60d7b. @vrowzer/fs is unchanged in 750be3a.

const subscriber = createFileSystemSubscriber(fs)
const bytes = [0x89, 0x50, 0x4e, 0x47, 0x00, 0xff, 0x10]

// What the runtime sends to the Service Worker for ready({ files })
subscriber.handleMessage({ type: 'V_FS_INIT', files: { '/public/init.png': new Uint8Array(bytes).buffer } })
;[...fs.readFileSync('/public/init.png')]
// [91, 111, 98, 106, 101, 99, 116, 32, 65, 114, 114, 97, 121, 66, 117, 102, 102, 101, 114, 93]
// = "[object ArrayBuffer]"

// What addFile() sends
subscriber.handleMessage({ type: 'V_FS_WRITE', path: '/public/write.png', encoding: 'binary', content: new Uint8Array(bytes).buffer })
;[...fs.readFileSync('/public/write.png')]
// [137, 80, 78, 71, 0, 255, 16]

Requested behavior

  • Binary files given to ready() are written as bytes in both Workers.
  • The caller's ArrayBuffers stay usable. Each Worker gets its own copy, as addFile() does since #61.
  • Text files are sent as before.

One possible approach:

  • Split config.files into text and binary files in initialize().
  • For the Service Worker, send the binary files in V_FS_INIT.binaryFiles, with a copy for each target. Either send them directly, or fix Copy binary files for each target in FileSystemPublisher.initFiles() #63 first and use initFiles().
  • For the Web Worker, either:
    • send the binary files in V_WW_SETUP and write them as bytes in setupVirtualFiles(), or
    • send them with V_FS_WRITE after setup.

Acceptance criteria

  • A binary file given to ready() is served by the Service Worker with the same bytes. This includes a public image, and a file served by the static middleware.
  • The Web Worker reads the same bytes, for example when it inlines the file with ?inline.
  • After ready(), the caller's ArrayBuffers keep their size and content.
  • A test covers this in the browser.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions