@zenfs/core 0.0.12 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/utils.js CHANGED
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { ErrorCode, ApiError } from './ApiError.js';
11
2
  import * as path from './emulation/path.js';
12
3
  /**
@@ -101,83 +92,81 @@ function levenshtein(a, b) {
101
92
  * Checks that the given options object is valid for the file system options.
102
93
  * @internal
103
94
  */
104
- export function checkOptions(backend, opts) {
105
- return __awaiter(this, void 0, void 0, function* () {
106
- const optsInfo = backend.Options;
107
- const fsName = backend.Name;
108
- let pendingValidators = 0;
109
- let callbackCalled = false;
110
- let loopEnded = false;
111
- // Check for required options.
112
- for (const optName in optsInfo) {
113
- if (Object.prototype.hasOwnProperty.call(optsInfo, optName)) {
114
- const opt = optsInfo[optName];
115
- const providedValue = opts && opts[optName];
116
- if (providedValue === undefined || providedValue === null) {
117
- if (!opt.optional) {
118
- // Required option, not provided.
119
- // Any incorrect options provided? Which ones are close to the provided one?
120
- // (edit distance 5 === close)
121
- const incorrectOptions = Object.keys(opts)
122
- .filter(o => !(o in optsInfo))
123
- .map((a) => {
124
- return { str: a, distance: levenshtein(optName, a) };
125
- })
126
- .filter(o => o.distance < 5)
127
- .sort((a, b) => a.distance - b.distance);
128
- // Validators may be synchronous.
129
- if (callbackCalled) {
130
- return;
131
- }
132
- callbackCalled = true;
133
- throw new ApiError(ErrorCode.EINVAL, `[${fsName}] Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided unrecognized option '${incorrectOptions[0].str}'; perhaps you meant to type '${optName}'.` : ''}\nOption description: ${opt.description}`);
95
+ export async function checkOptions(backend, opts) {
96
+ const optsInfo = backend.Options;
97
+ const fsName = backend.Name;
98
+ let pendingValidators = 0;
99
+ let callbackCalled = false;
100
+ let loopEnded = false;
101
+ // Check for required options.
102
+ for (const optName in optsInfo) {
103
+ if (Object.prototype.hasOwnProperty.call(optsInfo, optName)) {
104
+ const opt = optsInfo[optName];
105
+ const providedValue = opts && opts[optName];
106
+ if (providedValue === undefined || providedValue === null) {
107
+ if (!opt.optional) {
108
+ // Required option, not provided.
109
+ // Any incorrect options provided? Which ones are close to the provided one?
110
+ // (edit distance 5 === close)
111
+ const incorrectOptions = Object.keys(opts)
112
+ .filter(o => !(o in optsInfo))
113
+ .map((a) => {
114
+ return { str: a, distance: levenshtein(optName, a) };
115
+ })
116
+ .filter(o => o.distance < 5)
117
+ .sort((a, b) => a.distance - b.distance);
118
+ // Validators may be synchronous.
119
+ if (callbackCalled) {
120
+ return;
134
121
  }
135
- // Else: Optional option, not provided. That is OK.
122
+ callbackCalled = true;
123
+ throw new ApiError(ErrorCode.EINVAL, `[${fsName}] Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided unrecognized option '${incorrectOptions[0].str}'; perhaps you meant to type '${optName}'.` : ''}\nOption description: ${opt.description}`);
124
+ }
125
+ // Else: Optional option, not provided. That is OK.
126
+ }
127
+ else {
128
+ // Option provided! Check type.
129
+ let typeMatches = false;
130
+ if (Array.isArray(opt.type)) {
131
+ typeMatches = opt.type.indexOf(typeof providedValue) !== -1;
136
132
  }
137
133
  else {
138
- // Option provided! Check type.
139
- let typeMatches = false;
140
- if (Array.isArray(opt.type)) {
141
- typeMatches = opt.type.indexOf(typeof providedValue) !== -1;
142
- }
143
- else {
144
- typeMatches = typeof providedValue === opt.type;
134
+ typeMatches = typeof providedValue === opt.type;
135
+ }
136
+ if (!typeMatches) {
137
+ // Validators may be synchronous.
138
+ if (callbackCalled) {
139
+ return;
145
140
  }
146
- if (!typeMatches) {
147
- // Validators may be synchronous.
148
- if (callbackCalled) {
149
- return;
150
- }
151
- callbackCalled = true;
152
- throw new ApiError(ErrorCode.EINVAL, `[${fsName}] Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}\nOption description: ${opt.description}`);
141
+ callbackCalled = true;
142
+ throw new ApiError(ErrorCode.EINVAL, `[${fsName}] Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}\nOption description: ${opt.description}`);
143
+ }
144
+ else if (opt.validator) {
145
+ pendingValidators++;
146
+ try {
147
+ await opt.validator(providedValue);
153
148
  }
154
- else if (opt.validator) {
155
- pendingValidators++;
156
- try {
157
- yield opt.validator(providedValue);
158
- }
159
- catch (e) {
160
- if (!callbackCalled) {
161
- if (e) {
162
- callbackCalled = true;
163
- throw e;
164
- }
165
- pendingValidators--;
166
- if (pendingValidators === 0 && loopEnded) {
167
- return;
168
- }
149
+ catch (e) {
150
+ if (!callbackCalled) {
151
+ if (e) {
152
+ callbackCalled = true;
153
+ throw e;
154
+ }
155
+ pendingValidators--;
156
+ if (pendingValidators === 0 && loopEnded) {
157
+ return;
169
158
  }
170
159
  }
171
160
  }
172
- // Otherwise: All good!
173
161
  }
162
+ // Otherwise: All good!
174
163
  }
175
164
  }
176
- loopEnded = true;
177
- if (pendingValidators === 0 && !callbackCalled) {
178
- return;
179
- }
180
- });
165
+ }
166
+ loopEnded = true;
167
+ if (pendingValidators === 0 && !callbackCalled) {
168
+ return;
169
+ }
181
170
  }
182
171
  /** Waits n ms. */
183
172
  export function wait(ms) {
@@ -212,10 +201,22 @@ export const setImmediate = typeof globalThis.setImmediate == 'function' ? globa
212
201
  * @internal
213
202
  */
214
203
  export const ROOT_NODE_ID = '/';
204
+ /**
205
+ * @internal
206
+ * Used for caching text decoders
207
+ */
208
+ const decoderCache = new Map();
215
209
  const textEncoder = new globalThis.TextEncoder();
216
- export const encode = textEncoder.encode.bind(textEncoder);
217
- const textDecoder = new globalThis.TextDecoder();
218
- export const decode = textDecoder.decode.bind(textDecoder);
210
+ export function encode(input, encoding = 'utf8') {
211
+ return textEncoder.encode(input);
212
+ }
213
+ export function decode(input, encoding = 'utf8') {
214
+ if (!decoderCache.has(encoding)) {
215
+ const textDecoder = new globalThis.TextDecoder(encoding);
216
+ decoderCache.set(encoding, textDecoder.decode.bind(textDecoder));
217
+ }
218
+ return decoderCache.get(encoding)(input);
219
+ }
219
220
  /**
220
221
  * Generates a random ID.
221
222
  * @internal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "0.0.12",
3
+ "version": "0.1.0",
4
4
  "description": "A filesystem in your browser",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist",
@@ -43,7 +43,9 @@
43
43
  "prepublishOnly": "npm run build"
44
44
  },
45
45
  "dependencies": {
46
- "@types/node": "^14.0.0"
46
+ "@types/node": "^14.0.0",
47
+ "@types/readable-stream": "^4.0.10",
48
+ "readable-stream": "^4.5.2"
47
49
  },
48
50
  "devDependencies": {
49
51
  "@jest/globals": "^29.5.0",
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ZenFS
2
2
 
3
- ZenFS is an in-browser file system that emulates the [Node JS file system API](http://nodejs.org/api/fs.html) and supports storing and retrieving files from various backends. ZenFS also integrates nicely into the Emscripten file system.
3
+ ZenFS is an in-browser file system that emulates the [Node JS file system API](http://nodejs.org/api/fs.html) and supports storing and retrieving files from various backends. ZenFS also integrates nicely with other tools.
4
4
 
5
5
  ## Backends
6
6
 
@@ -254,44 +254,6 @@ If you want to use an asynchronous backend, you must wrap it in an `AsyncMirror`
254
254
 
255
255
  Run unit tests with `npm test`.
256
256
 
257
- ### Citing
258
-
259
- ZenFS is a component of the [Doppio](http://doppiojvm.org/) and [Browsix](https://browsix.org/) research projects from the PLASMA lab at the University of Massachusetts Amherst. If you decide to use ZenFS in a project that leads to a publication, please cite the academic papers on [Doppio](https://dl.acm.org/citation.cfm?doid=2594291.2594293) and [Browsix](https://dl.acm.org/citation.cfm?id=3037727):
260
-
261
- > John Vilk and Emery D. Berger. Doppio: Breaking the Browser Language Barrier. In
262
- > _Proceedings of the 35th ACM SIGPLAN Conference on Programming Language Design and Implementation_
263
- > (2014), pp. 508–518.
264
-
265
- ```bibtex
266
- @inproceedings{VilkDoppio,
267
- author = {John Vilk and
268
- Emery D. Berger},
269
- title = {{Doppio: Breaking the Browser Language Barrier}},
270
- booktitle = {Proceedings of the 35th {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation},
271
- pages = {508--518},
272
- year = {2014},
273
- url = {http://doi.acm.org/10.1145/2594291.2594293},
274
- doi = {10.1145/2594291.2594293}
275
- }
276
- ```
277
-
278
- > Bobby Powers, John Vilk, and Emery D. Berger. Browsix: Bridging the Gap Between Unix and the Browser. In _Proceedings of the Twenty-Second International Conference on Architectural Support for Programming Languages and Operating Systems_ (2017), pp. 253–266.
279
-
280
- ```bibtex
281
- @inproceedings{PowersBrowsix,
282
- author = {Bobby Powers and
283
- John Vilk and
284
- Emery D. Berger},
285
- title = {{Browsix: Bridging the Gap Between Unix and the Browser}},
286
- booktitle = {Proceedings of the Twenty-Second International Conference on Architectural
287
- Support for Programming Languages and Operating Systems},
288
- pages = {253--266},
289
- year = {2017},
290
- url = {http://doi.acm.org/10.1145/3037697.3037727},
291
- doi = {10.1145/3037697.3037727}
292
- }
293
- ```
294
-
295
257
  ### License
296
258
 
297
- ZenFS is licensed under the MIT License. See `LICENSE` for details.
259
+ ZenFS is licensed under the MIT License.