Skip to content

Commit 987e1dd

Browse files
authored
Experimental implementation of the Web FileSystem api (#4116)
1 parent ea0e68e commit 987e1dd

20 files changed

+1505
-46
lines changed

samples/webfs/README.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Web File System API Example
2+
3+
To run the example on http://localhost:8080
4+
5+
```sh
6+
$ ./workerd serve config.capnp
7+
```
8+
9+
To run using bazel
10+
11+
```sh
12+
$ bazel run //src/workerd/server:workerd -- serve ~/cloudflare/workerd/samples/helloworld_esm/config.capnp
13+
```
14+
15+
To create a standalone binary that can be run:
16+
17+
```sh
18+
$ ./workerd compile config.capnp > helloworld
19+
20+
$ ./helloworld
21+
```
22+
23+
To test:
24+
25+
```sh
26+
% curl http://localhost:8080
27+
Hello World
28+
```

samples/webfs/config.capnp

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Imports the base schema for workerd configuration files.
2+
3+
# Refer to the comments in /src/workerd/server/workerd.capnp for more details.
4+
5+
using Workerd = import "/workerd/workerd.capnp";
6+
7+
# A constant of type Workerd.Config defines the top-level configuration for an
8+
# instance of the workerd runtime. A single config file can contain multiple
9+
# Workerd.Config definitions and must have at least one.
10+
const helloWorldExample :Workerd.Config = (
11+
12+
# Every workerd instance consists of a set of named services. A worker, for instance,
13+
# is a type of service. Other types of services can include external servers, the
14+
# ability to talk to a network, or accessing a disk directory. Here we create a single
15+
# worker service. The configuration details for the worker are defined below.
16+
services = [ (name = "main", worker = .helloWorld) ],
17+
18+
# Each configuration defines the sockets on which the server will listen.
19+
# Here, we create a single socket that will listen on localhost port 8080, and will
20+
# dispatch to the "main" service that we defined above.
21+
sockets = [ ( name = "http", address = "*:8080", http = (), service = "main" ) ]
22+
);
23+
24+
# The definition of the actual helloWorld worker exposed using the "main" service.
25+
# In this example the worker is implemented as an ESM module (see worker.js).
26+
# The compatibilityDate is required. For more details on compatibility dates see:
27+
# https://developers.cloudflare.com/workers/platform/compatibility-dates/
28+
29+
const helloWorld :Workerd.Worker = (
30+
modules = [
31+
(name = "worker", esModule = embed "worker.js")
32+
],
33+
compatibilityDate = "2025-05-01",
34+
compatibilityFlags = ["enable_web_file_system", "experimental"]
35+
);

samples/webfs/worker.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2017-2023 Cloudflare, Inc.
2+
// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3+
// https://opensource.org/licenses/Apache-2.0
4+
5+
const dir = await navigator.storage.getDirectory();
6+
const bundle = await dir.getDirectoryHandle("tmp");
7+
const file = await bundle.getFileHandle("foo", { create: true });
8+
const handle = await file.createSyncAccessHandle();
9+
10+
const enc = new TextEncoder();
11+
handle.write(enc.encode("Hello World"));
12+
handle.write(enc.encode("!!!\n"));
13+
console.log(handle.getSize());
14+
handle.close();
15+
16+
const data = await file.getFile();
17+
console.log(await data.text());
18+
19+
export default {
20+
async fetch(req, env) {
21+
return new Response("Hello World\n");
22+
}
23+
};

src/workerd/api/BUILD.bazel

+6
Original file line numberDiff line numberDiff line change
@@ -710,3 +710,9 @@ wd_test(
710710
args = ["--experimental"],
711711
data = ["tests/disable-importable-env-test.js"],
712712
)
713+
714+
wd_test(
715+
src = "tests/webfs-test.wd-test",
716+
args = ["--experimental"],
717+
data = ["tests/webfs-test.js"],
718+
)

0 commit comments

Comments
 (0)