@zenfs/core 0.1.0 → 0.2.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.
Files changed (44) hide show
  1. package/dist/ApiError.d.ts +51 -14
  2. package/dist/ApiError.js +60 -34
  3. package/dist/FileIndex.d.ts +32 -35
  4. package/dist/FileIndex.js +93 -109
  5. package/dist/backends/AsyncMirror.d.ts +42 -43
  6. package/dist/backends/AsyncMirror.js +146 -133
  7. package/dist/backends/AsyncStore.d.ts +29 -28
  8. package/dist/backends/AsyncStore.js +139 -189
  9. package/dist/backends/InMemory.d.ts +16 -13
  10. package/dist/backends/InMemory.js +29 -14
  11. package/dist/backends/Locked.d.ts +8 -28
  12. package/dist/backends/Locked.js +44 -148
  13. package/dist/backends/OverlayFS.d.ts +26 -34
  14. package/dist/backends/OverlayFS.js +208 -371
  15. package/dist/backends/SyncStore.d.ts +54 -72
  16. package/dist/backends/SyncStore.js +159 -161
  17. package/dist/backends/backend.d.ts +45 -29
  18. package/dist/backends/backend.js +83 -13
  19. package/dist/backends/index.d.ts +6 -7
  20. package/dist/backends/index.js +5 -6
  21. package/dist/browser.min.js +5 -7
  22. package/dist/browser.min.js.map +4 -4
  23. package/dist/emulation/callbacks.d.ts +36 -67
  24. package/dist/emulation/callbacks.js +90 -46
  25. package/dist/emulation/constants.js +1 -1
  26. package/dist/emulation/promises.d.ts +228 -129
  27. package/dist/emulation/promises.js +414 -172
  28. package/dist/emulation/shared.d.ts +10 -10
  29. package/dist/emulation/shared.js +18 -20
  30. package/dist/emulation/sync.d.ts +25 -25
  31. package/dist/emulation/sync.js +187 -73
  32. package/dist/file.d.ts +166 -170
  33. package/dist/file.js +199 -218
  34. package/dist/filesystem.d.ts +68 -241
  35. package/dist/filesystem.js +59 -383
  36. package/dist/index.d.ts +7 -44
  37. package/dist/index.js +13 -52
  38. package/dist/inode.d.ts +37 -28
  39. package/dist/inode.js +123 -65
  40. package/dist/stats.d.ts +21 -19
  41. package/dist/stats.js +35 -56
  42. package/dist/utils.d.ts +26 -9
  43. package/dist/utils.js +73 -102
  44. package/package.json +4 -3
package/dist/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ErrorCode, ApiError } from './ApiError.js';
1
+ import { ApiError, ErrorCode } from './ApiError.js';
2
2
  import * as path from './emulation/path.js';
3
3
  /**
4
4
  * Synchronous recursive makedir.
@@ -19,10 +19,9 @@ function _min(d0, d1, d2, bx, ay) {
19
19
  }
20
20
  /**
21
21
  * Calculates levenshtein distance.
22
- * @param a
23
- * @param b
22
+ * @internal
24
23
  */
25
- function levenshtein(a, b) {
24
+ export function levenshtein(a, b) {
26
25
  if (a === b) {
27
26
  return 0;
28
27
  }
@@ -88,86 +87,6 @@ function levenshtein(a, b) {
88
87
  }
89
88
  return dd;
90
89
  }
91
- /**
92
- * Checks that the given options object is valid for the file system options.
93
- * @internal
94
- */
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;
121
- }
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;
132
- }
133
- else {
134
- typeMatches = typeof providedValue === opt.type;
135
- }
136
- if (!typeMatches) {
137
- // Validators may be synchronous.
138
- if (callbackCalled) {
139
- return;
140
- }
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);
148
- }
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;
158
- }
159
- }
160
- }
161
- }
162
- // Otherwise: All good!
163
- }
164
- }
165
- }
166
- loopEnded = true;
167
- if (pendingValidators === 0 && !callbackCalled) {
168
- return;
169
- }
170
- }
171
90
  /** Waits n ms. */
172
91
  export function wait(ms) {
173
92
  return new Promise(resolve => {
@@ -198,34 +117,86 @@ export function toPromise(fn) {
198
117
  */
199
118
  export const setImmediate = typeof globalThis.setImmediate == 'function' ? globalThis.setImmediate : cb => setTimeout(cb, 0);
200
119
  /**
120
+ * Encodes a string into a buffer
201
121
  * @internal
202
122
  */
203
- export const ROOT_NODE_ID = '/';
123
+ export function encode(input, encoding = 'utf8') {
124
+ switch (encoding) {
125
+ case 'ascii':
126
+ return new TextEncoder().encode(input).map(v => v & 0x7f);
127
+ case 'latin1':
128
+ case 'binary':
129
+ case 'utf8':
130
+ case 'utf-8':
131
+ case 'base64':
132
+ case 'base64url':
133
+ case 'hex':
134
+ return new TextEncoder().encode(input);
135
+ case 'utf16le':
136
+ case 'ucs2':
137
+ case 'ucs-2':
138
+ return new TextEncoder().encode(input).slice(0, -1);
139
+ default:
140
+ throw new ApiError(ErrorCode.EINVAL, 'Invalid encoding: ' + encoding);
141
+ }
142
+ }
204
143
  /**
144
+ * Decodes a string from a buffer
205
145
  * @internal
206
- * Used for caching text decoders
207
146
  */
208
- const decoderCache = new Map();
209
- const textEncoder = new globalThis.TextEncoder();
210
- export function encode(input, encoding = 'utf8') {
211
- return textEncoder.encode(input);
212
- }
213
147
  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));
148
+ switch (encoding) {
149
+ case 'ascii':
150
+ case 'utf8':
151
+ case 'utf-8':
152
+ return new TextDecoder().decode(input);
153
+ case 'latin1':
154
+ case 'binary':
155
+ return new TextDecoder('latin1').decode(input);
156
+ case 'utf16le':
157
+ case 'ucs2':
158
+ case 'ucs-2':
159
+ let utf16leString = '';
160
+ for (let i = 0; i < input.length; i += 2) {
161
+ const code = input[i] | (input[i + 1] << 8);
162
+ utf16leString += String.fromCharCode(code);
163
+ }
164
+ return utf16leString;
165
+ case 'base64':
166
+ return btoa(Array.from(input)
167
+ .map(v => String.fromCharCode(v))
168
+ .join(''));
169
+ case 'base64url':
170
+ return decode(input, 'base64').replace('/', '_').replace('+', '-');
171
+ case 'hex':
172
+ return Array.from(input)
173
+ .map(e => e.toString(16))
174
+ .join('');
175
+ default:
176
+ throw new ApiError(ErrorCode.EINVAL, 'Invalid encoding: ' + encoding);
217
177
  }
218
- return decoderCache.get(encoding)(input);
219
178
  }
220
179
  /**
221
- * Generates a random ID.
180
+ * Decodes a directory listing
222
181
  * @internal
223
182
  */
224
- export function randomUUID() {
225
- // From http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
226
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
227
- const r = (Math.random() * 16) | 0;
228
- const v = c === 'x' ? r : (r & 0x3) | 0x8;
229
- return v.toString(16);
183
+ export function decodeDirListing(data) {
184
+ return JSON.parse(decode(data), (k, v) => {
185
+ if (k == '') {
186
+ return v;
187
+ }
188
+ return BigInt(v);
230
189
  });
231
190
  }
191
+ /**
192
+ * Encodes a directory listing
193
+ * @internal
194
+ */
195
+ export function encodeDirListing(data) {
196
+ return encode(JSON.stringify(data, (k, v) => {
197
+ if (k == '') {
198
+ return v;
199
+ }
200
+ return v.toString();
201
+ }));
202
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A filesystem in your browser",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist",
@@ -36,10 +36,11 @@
36
36
  "scripts": {
37
37
  "format": "prettier --write src test",
38
38
  "format:check": "prettier --check src test",
39
- "lint": "eslint src test",
39
+ "lint": "eslint src test && tsc -p tsconfig.json --noEmit",
40
40
  "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest",
41
- "build": "node scripts/build.mjs",
41
+ "build": "node scripts/build.js",
42
42
  "build:docs": "typedoc --out docs --name ZenFS src/index.ts",
43
+ "dev": "node scripts/build.js --watch",
43
44
  "prepublishOnly": "npm run build"
44
45
  },
45
46
  "dependencies": {