Skip to content

Commit ebcadcf

Browse files
atkgithub-actions[bot]
authored andcommitted
Format
1 parent b1d58e3 commit ebcadcf

File tree

10 files changed

+180
-132
lines changed

10 files changed

+180
-132
lines changed

packages/filesystem/README.md

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111

1212
A primitive that allows to manage different file system access methods:
1313

14-
* `createFileSystem` - Provides a reactive interface to one of the file system adapters - a convenience method that calls the correct wrapper
15-
* `createSyncFileSystem` - Wraps a synchronous file system adapter like `makeNoFileSystem` or `makeVirtualFileSystem` in a reactive interface
16-
* `createAsyncFileSystem` - Adds a reactive layer to an asynchronous file system adapter
17-
* `makeNoFileSystem` - Adapter that provides a synchronous mock file system
18-
* `makeNoAsyncFileSystem` - Adapter that provides an asynchronous mock file system
19-
* `makeVirtualFileSystem` - Adapter that provides a virtual file system that doubles as FsMap for `typescript-vfs` with its `.toMap()` method.
20-
* `makeWebAccessFileSystem` (client only) - Adapter that provides access to the actual filesystem in the browser using a directory picker
21-
* `makeNodeFileSystem` (server only) - Adapter that abstracts the node fs/promises module for the use with this primitive
22-
* `makeTauriFileSystem` (tauri with fs access enabled only) - Adapter that connects to the tauri fs module
23-
* `makeChokidarWatcher` - (experimental): use chokidar to watch for file system changes and trigger reactive updates
14+
- `createFileSystem` - Provides a reactive interface to one of the file system adapters - a convenience method that calls the correct wrapper
15+
- `createSyncFileSystem` - Wraps a synchronous file system adapter like `makeNoFileSystem` or `makeVirtualFileSystem` in a reactive interface
16+
- `createAsyncFileSystem` - Adds a reactive layer to an asynchronous file system adapter
17+
- `makeNoFileSystem` - Adapter that provides a synchronous mock file system
18+
- `makeNoAsyncFileSystem` - Adapter that provides an asynchronous mock file system
19+
- `makeVirtualFileSystem` - Adapter that provides a virtual file system that doubles as FsMap for `typescript-vfs` with its `.toMap()` method.
20+
- `makeWebAccessFileSystem` (client only) - Adapter that provides access to the actual filesystem in the browser using a directory picker
21+
- `makeNodeFileSystem` (server only) - Adapter that abstracts the node fs/promises module for the use with this primitive
22+
- `makeTauriFileSystem` (tauri with fs access enabled only) - Adapter that connects to the tauri fs module
23+
- `makeChokidarWatcher` - (experimental): use chokidar to watch for file system changes and trigger reactive updates
2424

2525
## Installation
2626

@@ -94,36 +94,43 @@ createEffect(() => console.log("/", fs.readdir("/")));
9494
createEffect(() => console.log("/src/index.ts", fs.readFile("/src/index.ts")));
9595

9696
// isomorphic file system reader with lazy evaluation
97-
const Item = (props: { path: string, fs: SyncFileSystem | AsyncFileSystem }) => {
97+
const Item = (props: { path: string; fs: SyncFileSystem | AsyncFileSystem }) => {
9898
const itemType = () => props.fs.getType(props.path);
9999
const name = () => getItemName(props.path);
100100
const [open, setOpen] = createSignal(false);
101-
const content = () => open()
102-
? itemType() === "dir"
103-
? props.fs.readdir(props.path)
104-
: props.fs.readFile(props.path)
105-
: undefined;
106-
107-
return <>
108-
<button onClick={() => setOpen(!open())}>{open() ? "-" : "+"}</button>
109-
{itemType() === "dir" ? "[DIR]" : "[FILE]"} {name()}
110-
<Switch>
111-
<Match when={open() && itemType() === "file"}>
112-
<pre>{content()?.()}</pre>
113-
</Match>
114-
<Match when={open() && itemType() === "dir"}>
115-
<For each={content() || []}>
116-
{(entry) => <div><Item path={entry} fs={props.fs} /></div>}
117-
</For>
118-
</Match>
119-
</Switch>
120-
</>
101+
const content = () =>
102+
open()
103+
? itemType() === "dir"
104+
? props.fs.readdir(props.path)
105+
: props.fs.readFile(props.path)
106+
: undefined;
107+
108+
return (
109+
<>
110+
<button onClick={() => setOpen(!open())}>{open() ? "-" : "+"}</button>
111+
{itemType() === "dir" ? "[DIR]" : "[FILE]"} {name()}
112+
<Switch>
113+
<Match when={open() && itemType() === "file"}>
114+
<pre>{content()?.()}</pre>
115+
</Match>
116+
<Match when={open() && itemType() === "dir"}>
117+
<For each={content() || []}>
118+
{entry => (
119+
<div>
120+
<Item path={entry} fs={props.fs} />
121+
</div>
122+
)}
123+
</For>
124+
</Match>
125+
</Switch>
126+
</>
127+
);
121128
};
122129
```
123130

124131
## Demo
125132

126-
You may view a working example of createFileSystem/makeVirtualFileSystem/makeWebAccessFileSystem here:
133+
You may view a working example of createFileSystem/makeVirtualFileSystem/makeWebAccessFileSystem here:
127134
https://solidjs-community.github.io/solid-primitives/filesystem/
128135

129136
## Changelog

packages/filesystem/dev/index.html

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,35 @@
11
<!DOCTYPE html>
22
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta name="theme-color" content="#000000" />
7+
<title>Solid App</title>
8+
<style>
9+
html {
10+
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
11+
}
312

4-
<head>
5-
<meta charset="utf-8" />
6-
<meta name="viewport" content="width=device-width, initial-scale=1" />
7-
<meta name="theme-color" content="#000000" />
8-
<title>Solid App</title>
9-
<style>
10-
html {
11-
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
12-
}
13+
body {
14+
padding: 0;
15+
margin: 0;
16+
}
1317

14-
body {
15-
padding: 0;
16-
margin: 0;
17-
}
18+
a,
19+
button {
20+
cursor: pointer;
21+
}
1822

19-
a,
20-
button {
21-
cursor: pointer;
22-
}
23+
* {
24+
margin: 0;
25+
}
26+
</style>
27+
</head>
2328

24-
* {
25-
margin: 0;
26-
}
27-
</style>
28-
</head>
29-
30-
<body>
31-
<noscript>You need to enable JavaScript to run this app.</noscript>
32-
<div id="root"></div>
33-
34-
<script src="/index.tsx" type="module"></script>
35-
</body>
29+
<body>
30+
<noscript>You need to enable JavaScript to run this app.</noscript>
31+
<div id="root"></div>
3632

33+
<script src="/index.tsx" type="module"></script>
34+
</body>
3735
</html>

packages/filesystem/dev/index.tsx

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,49 +14,64 @@ import {
1414
makeVirtualFileSystem,
1515
makeWebAccessFileSystem,
1616
SyncFileSystem,
17-
getItemName
17+
getItemName,
1818
} from "../src/index";
1919
import "uno.css";
2020

21-
const FsFile = (props: { fs: SyncFileSystem | AsyncFileSystem, path: string }) => {
21+
const FsFile = (props: { fs: SyncFileSystem | AsyncFileSystem; path: string }) => {
2222
const [open, setOpen] = createSignal(false);
23-
const content = createMemo((prev) => prev || open() ? props.fs.readFile(props.path) : undefined);
23+
const content = createMemo(prev => (prev || open() ? props.fs.readFile(props.path) : undefined));
2424
const setContent = (data: string) => props.fs.writeFile(props.path, data);
25-
return <div>
26-
<p>
27-
<button onClick={() => setOpen(!open())}>{open() ? "-" : "+"}</button>
28-
{getItemName(props.path)}
29-
</p>
30-
<Show when={open()}>
31-
<textarea value={content()} onInput={(ev) => setContent(ev.currentTarget.value)} />
32-
</Show>
33-
</div>
34-
}
25+
return (
26+
<div>
27+
<p>
28+
<button onClick={() => setOpen(!open())}>{open() ? "-" : "+"}</button>
29+
{getItemName(props.path)}
30+
</p>
31+
<Show when={open()}>
32+
<textarea value={content()} onInput={ev => setContent(ev.currentTarget.value)} />
33+
</Show>
34+
</div>
35+
);
36+
};
3537

36-
const FsDir = (props: { fs: SyncFileSystem | AsyncFileSystem, path: string }) => {
38+
const FsDir = (props: { fs: SyncFileSystem | AsyncFileSystem; path: string }) => {
3739
const [open, setOpen] = createSignal(props.path === "/");
3840
const [name, setName] = createSignal("");
3941
const list = () => open() && props.fs.readdir(props.path);
4042
return (
4143
<>
42-
<div><button onClick={() => setOpen(!open())}>{open() ? "-" : "+"}</button> {getItemName(props.path) || "/"} <input onInput={(ev) => setName(ev.currentTarget.value)} />
44+
<div>
45+
<button onClick={() => setOpen(!open())}>{open() ? "-" : "+"}</button>{" "}
46+
{getItemName(props.path) || "/"} <input onInput={ev => setName(ev.currentTarget.value)} />
4347
<Show when={name() !== ""}>
44-
<button onClick={() => props.fs.writeFile(`${props.path === "/" ? "" : props.path}/${name()}`, "")}>
48+
<button
49+
onClick={() =>
50+
props.fs.writeFile(`${props.path === "/" ? "" : props.path}/${name()}`, "")
51+
}
52+
>
4553
New File
4654
</button>
47-
<button onClick={() => props.fs.mkdir(`${props.path === "/" ? "" : props.path}/${name()}`)}>
55+
<button
56+
onClick={() => props.fs.mkdir(`${props.path === "/" ? "" : props.path}/${name()}`)}
57+
>
4858
New Dir
4959
</button>
5060
</Show>
5161
</div>
5262
<Show when={list() !== undefined}>
5363
<ul>
5464
<For each={list()!}>
55-
{(item) => (
65+
{item => (
5666
<li>
5767
<Show
5868
when={props.fs.getType(item) === "dir"}
59-
fallback={<FsFile fs={props.fs} path={`${props.path === "/" ? "" : props.path}/${item}`} />}
69+
fallback={
70+
<FsFile
71+
fs={props.fs}
72+
path={`${props.path === "/" ? "" : props.path}/${item}`}
73+
/>
74+
}
6075
>
6176
<FsDir fs={props.fs} path={item} />
6277
</Show>
@@ -70,27 +85,43 @@ const FsDir = (props: { fs: SyncFileSystem | AsyncFileSystem, path: string }) =>
7085
};
7186

7287
const App: Component = () => {
73-
const ofs = makeVirtualFileSystem({
74-
src: { "index.ts": "console.log(0);\n" },
75-
}, localStorage);
88+
const ofs = makeVirtualFileSystem(
89+
{
90+
src: { "index.ts": "console.log(0);\n" },
91+
},
92+
localStorage,
93+
);
7694
const vfs = createFileSystem(ofs);
7795
const [startAfs, setStartAfs] = createSignal(false);
78-
const [afs] = createResource(startAfs, async () => createFileSystem(makeWebAccessFileSystem({ mode: "readwrite" })))
96+
const [afs] = createResource(startAfs, async () =>
97+
createFileSystem(makeWebAccessFileSystem({ mode: "readwrite" })),
98+
);
7999
return (
80-
<div class="p-24 box-border w-full min-h-screen flex flex-col justify-center items-center space-y-4 bg-gray-800 text-white">
100+
<div class="box-border flex min-h-screen w-full flex-col items-center justify-center space-y-4 bg-gray-800 p-24 text-white">
81101
<div class="wrapper-v">
82102
<div>
83-
<ErrorBoundary fallback={(err, reset) => <div>Error: {err} <button onClick={reset}>reset</button></div>}>
103+
<ErrorBoundary
104+
fallback={(err, reset) => (
105+
<div>
106+
Error: {err} <button onClick={reset}>reset</button>
107+
</div>
108+
)}
109+
>
84110
<h4>FileSystem primitive</h4>
85111
<p>Object virtual file system (localStorage persistence)</p>
86112
<FsDir fs={vfs} path="/" />
87-
<Show when={!afs.loading && !afs.error && afs()} fallback={
88-
<button disabled={afs.loading} onClick={() => setStartAfs(true)}>
89-
Request directory access
90-
</button>
91-
}>
113+
<Show
114+
when={!afs.loading && !afs.error && afs()}
115+
fallback={
116+
<button disabled={afs.loading} onClick={() => setStartAfs(true)}>
117+
Request directory access
118+
</button>
119+
}
120+
>
92121
<p>Web Filesystem Access file system</p>
93-
<p><em>Warning!</em> This can overwrite or delete actual files!</p>
122+
<p>
123+
<em>Warning!</em> This can overwrite or delete actual files!
124+
</p>
94125
<FsDir fs={afs()!} path="/" />
95126
</Show>
96127
</ErrorBoundary>

packages/filesystem/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
"chokidar": "^3.5.3"
7575
},
7676
"peerDependenciesMeta": {
77-
"chokidar": { "optional": true }
77+
"chokidar": {
78+
"optional": true
79+
}
7880
}
7981
}

packages/filesystem/src/adapter-vfs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export type ObjectFileSystemItem = ObjectFileSystem | string | undefined;
99
* @param initial optional object to prefill the file system
1010
* @param storage optional localStorage/localForage type storage
1111
* @param key optional key in the storage
12-
*
12+
*
1313
* ⚠ Warning! localStorage is limited to 5MB; use [localforage](https://localforage.github.io/localForage/) instead if you need more.
1414
*/
1515
export const makeVirtualFileSystem = (

packages/filesystem/src/adapter-web.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { AsyncFileSystemAdapter } from "./types";
55
/**
66
* Adapter that provides access to the actual filesystem in the browser using a directory picker
77
* receives the options for showDirectoryPicker(options: DirectoryPickerOptions) as optional argument
8-
*
8+
*
99
* relies on https://wicg.github.io/file-system-access/ - basic api (https://caniuse.com/native-filesystem-api)
1010
*/
1111
export const makeWebAccessFileSystem = process.env.SSR
@@ -110,4 +110,3 @@ export const makeWebAccessFileSystem = process.env.SSR
110110
};
111111
}
112112
: () => Promise.resolve(makeNoAsyncFileSystem());
113-

0 commit comments

Comments
 (0)