Skip to content

Commit f85a3cf

Browse files
committed
[Flight] Add rudimentary FS binding
1 parent 1b5ca99 commit f85a3cf

File tree

11 files changed

+224
-0
lines changed

11 files changed

+224
-0
lines changed

packages/react-fs/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# react-fs
2+
3+
This package is meant to be used alongside yet-to-be-released, experimental React features. It's unlikely to be useful in any other context.
4+
5+
**Do not use in a real application.** We're publishing this early for
6+
demonstration purposes.
7+
8+
**Use it at your own risk.**
9+
10+
# No, Really, It Is Unstable
11+
12+
The API ~~may~~ will change wildly between versions.

packages/react-fs/index.browser.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
throw new Error(
11+
'This entry point is not yet supported in the browser environment',
12+
);

packages/react-fs/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
'use strict';
11+
12+
export * from './index.node';

packages/react-fs/index.node.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
'use strict';
11+
12+
export * from './src/ReactFilesystem';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
if (process.env.NODE_ENV === 'production') {
4+
module.exports = require('./cjs/react-fs.browser.production.min.js');
5+
} else {
6+
module.exports = require('./cjs/react-fs.browser.development.js');
7+
}

packages/react-fs/npm/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
module.exports = require('./index.node');

packages/react-fs/npm/index.node.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
if (process.env.NODE_ENV === 'production') {
4+
module.exports = require('./cjs/react-fs.node.production.min.js');
5+
} else {
6+
module.exports = require('./cjs/react-fs.node.development.js');
7+
}

packages/react-fs/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"private": true,
3+
"name": "react-fs",
4+
"description": "React bindings for the filesystem",
5+
"version": "0.0.0",
6+
"repository": {
7+
"type" : "git",
8+
"url" : "https://github.com/facebook/react.git",
9+
"directory": "packages/react-fs"
10+
},
11+
"files": [
12+
"LICENSE",
13+
"README.md",
14+
"build-info.json",
15+
"index.js",
16+
"index.node.js",
17+
"index.browser.js",
18+
"cjs/"
19+
],
20+
"browser": {
21+
"./index.js": "./index.browser.js"
22+
}
23+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import type {Wakeable, Thenable} from 'shared/ReactTypes';
11+
12+
import {unstable_getCacheForType} from 'react';
13+
import * as fs from 'fs/promises';
14+
15+
const Pending = 0;
16+
const Resolved = 1;
17+
const Rejected = 2;
18+
19+
type PendingResult = {|
20+
status: 0,
21+
value: Wakeable,
22+
|};
23+
24+
type ResolvedResult<T> = {|
25+
status: 1,
26+
value: T,
27+
|};
28+
29+
type RejectedResult = {|
30+
status: 2,
31+
value: mixed,
32+
|};
33+
34+
type Result<T> = PendingResult | ResolvedResult<T> | RejectedResult;
35+
36+
function toResult<T>(thenable: Thenable<T>): Result<T> {
37+
const result: Result<T> = {
38+
status: Pending,
39+
value: thenable,
40+
};
41+
thenable.then(
42+
value => {
43+
if (result.status === Pending) {
44+
const resolvedResult = ((result: any): ResolvedResult<T>);
45+
resolvedResult.status = Resolved;
46+
resolvedResult.value = value;
47+
}
48+
},
49+
err => {
50+
if (result.status === Pending) {
51+
const rejectedResult = ((result: any): RejectedResult);
52+
rejectedResult.status = Rejected;
53+
rejectedResult.value = err;
54+
}
55+
},
56+
);
57+
return result;
58+
}
59+
60+
function readResult<T>(result: Result<T>): T {
61+
if (result.status === Resolved) {
62+
return result.value;
63+
} else {
64+
throw result.value;
65+
}
66+
}
67+
68+
function createReadFileCache(): Map<string, Result<Buffer>> {
69+
return new Map();
70+
}
71+
72+
export function readFile(
73+
path: string,
74+
options:
75+
| string
76+
| {
77+
encoding?: string | null,
78+
// Ignored:
79+
flag?: string,
80+
signal?: mixed,
81+
},
82+
): string | Buffer {
83+
const map = unstable_getCacheForType(createReadFileCache);
84+
let entry = map.get(path);
85+
if (!entry) {
86+
const thenable = fs.readFile(path);
87+
entry = toResult(thenable);
88+
map.set(path, entry);
89+
}
90+
const result: Buffer = readResult(entry);
91+
if (!options) {
92+
return result;
93+
}
94+
const encoding = typeof options === 'string' ? options : options.encoding;
95+
if (typeof encoding !== 'string') {
96+
return result;
97+
}
98+
const textCache =
99+
(result: any)._reactTextCache || ((result: any)._reactTextCache = []);
100+
for (let i = 0; i < textCache.length; i += 2) {
101+
if (textCache[i] === encoding) {
102+
return textCache[i + 1];
103+
}
104+
}
105+
const text = result.toString((encoding: any));
106+
textCache.push(encoding, text);
107+
return text;
108+
}

scripts/flow/environment.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ declare module 'EventListener' {
7070
declare function __webpack_chunk_load__(id: string): Promise<mixed>;
7171
declare function __webpack_require__(id: string): any;
7272

73+
declare module 'fs/promises' {
74+
declare var readFile: (
75+
path: string,
76+
options?:
77+
| ?string
78+
| {
79+
encoding?: ?string,
80+
},
81+
) => Promise<Buffer>;
82+
}
7383
declare module 'pg' {
7484
declare var Pool: (
7585
options: mixed,

0 commit comments

Comments
 (0)