Skip to content

Commit

Permalink
src, lib: fixup lint and format issues for DataQueue/Blob
Browse files Browse the repository at this point in the history
Co-authored-by: flakey5 <73616808+flakey5@users.noreply.github.com>
PR-URL: #45258
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
jasnell and flakey5 committed Feb 20, 2023
1 parent 950cec4 commit 71fb06f
Show file tree
Hide file tree
Showing 18 changed files with 1,251 additions and 1,127 deletions.
48 changes: 39 additions & 9 deletions doc/api/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,6 @@ When operating on file handles, the mode cannot be changed from what it was set
to with [`fsPromises.open()`][]. Therefore, this is equivalent to
[`filehandle.writeFile()`][].

#### `filehandle.blob()`
<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
Returns a {Blob} whose data is backed by this file.

#### `filehandle.chmod(mode)`

<!-- YAML
Expand Down Expand Up @@ -3333,6 +3324,45 @@ a colon, Node.js will open a file system stream, as described by
Functions based on `fs.open()` exhibit this behavior as well:
`fs.writeFile()`, `fs.readFile()`, etc.
### `fs.openAsBlob(path[, options])`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental
* `path` {string|Buffer|URL}
* `options` {Object}
* `type` {string} An optional mime type for the blob.
* Return: {Promise} containing {Blob}
Returns a {Blob} whose data is backed by the given file.
The file must not be modified after the {Blob} is created. Any modifications
will cause reading the {Blob} data to fail with a `DOMException`.
error. Synchronous stat operations on the file when the `Blob` is created, and
before each read in order to detect whether the file data has been modified
on disk.
```mjs
import { openAsBlob } from 'node:fs';

const blob = await openAsBlob('the.file.txt');
const ab = await blob.arrayBuffer();
blob.stream();
```
```cjs
const { openAsBlob } = require('node:fs');

(async () => {
const blob = await openAsBlob('the.file.txt');
const ab = await blob.arrayBuffer();
blob.stream();
})();
```
### `fs.opendir(path[, options], callback)`
<!-- YAML
Expand Down
19 changes: 19 additions & 0 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const {
ObjectDefineProperties,
ObjectDefineProperty,
Promise,
PromiseResolve,
ReflectApply,
SafeMap,
SafeSet,
Expand Down Expand Up @@ -62,6 +63,9 @@ const { isArrayBufferView } = require('internal/util/types');
// it's re-initialized after deserialization.

const binding = internalBinding('fs');

const { createBlobFromFilePath } = require('internal/blob');

const { Buffer } = require('buffer');
const {
aggregateTwoErrors,
Expand Down Expand Up @@ -586,6 +590,20 @@ function openSync(path, flags, mode) {
return result;
}

/**
* @param {string | Buffer | URL } path
* @returns {Promise<Blob>}
*/
function openAsBlob(path, options = kEmptyObject) {
validateObject(options, 'options');
const type = options.type || '';
validateString(type, 'options.type');
// The underlying implementation here returns the Blob synchronously for now.
// To give ourselves flexibility to maybe return the Blob asynchronously,
// this API returns a Promise.
return PromiseResolve(createBlobFromFilePath(getValidatedPath(path), { type }));
}

/**
* Reads file from the specified `fd` (file descriptor).
* @param {number} fd
Expand Down Expand Up @@ -3022,6 +3040,7 @@ module.exports = fs = {
mkdtempSync,
open,
openSync,
openAsBlob,
readdir,
readdirSync,
read,
Expand Down
48 changes: 36 additions & 12 deletions lib/internal/blob.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayBuffer,
ArrayFrom,
MathMax,
MathMin,
Expand All @@ -21,7 +22,7 @@ const {

const {
createBlob: _createBlob,
createBlobFromFileHandle: _createBlobFromFileHandle,
createBlobFromFilePath: _createBlobFromFilePath,
concat,
getDataObject,
} = internalBinding('blob');
Expand All @@ -48,6 +49,7 @@ const {
customInspectSymbol: kInspect,
kEmptyObject,
kEnumerableProperty,
lazyDOMException,
} = require('internal/util');
const { inspect } = require('internal/util/inspect');

Expand All @@ -58,14 +60,17 @@ const {
ERR_INVALID_THIS,
ERR_BUFFER_TOO_LARGE,
},
errnoException,
} = require('internal/errors');

const {
isUint32,
validateDictionary,
} = require('internal/validators');

const {
CountQueuingStrategy,
} = require('internal/webstreams/queuingstrategies');

const kHandle = Symbol('kHandle');
const kType = Symbol('kType');
const kLength = Symbol('kLength');
Expand Down Expand Up @@ -265,16 +270,23 @@ class Blob {
return PromiseResolve(new ArrayBuffer(0));
}

const { promise, resolve } = createDeferredPromise();
const { promise, resolve, reject } = createDeferredPromise();
const reader = this[kHandle].getReader();
const buffers = [];
const readNext = () => {
reader.pull((status, buffer) => {
if (status === -1) {
if (status === 0) {
// EOS, concat & resolve
// buffer should be undefined here
resolve(concat(buffers));
return;
} else if (status < 0) {
// The read could fail for many different reasons when reading
// from a non-memory resident blob part (e.g. file-backed blob).
// The error details the system error code.
const error = lazyDOMException('The blob could not be read', 'NotReadableError');
reject(error);
return;
}
if (buffer !== undefined)
buffers.push(buffer);
Expand Down Expand Up @@ -319,7 +331,7 @@ class Blob {
},
pull(c) {
const { promise, resolve, reject } = createDeferredPromise();
this.pendingPulls.push({resolve, reject});
this.pendingPulls.push({ resolve, reject });
reader.pull((status, buffer) => {
// If pendingPulls is empty here, the stream had to have
// been canceled, and we don't really care about the result.
Expand All @@ -328,18 +340,24 @@ class Blob {
return;
}
const pending = this.pendingPulls.shift();
if (status === -1 || (status === 0 && buffer === undefined)) {
if (status === 0) {
// EOS
c.close();
pending.resolve();
return;
} else if (status < 0) {
const error = errnoException(status, 'read');
// The read could fail for many different reasons when reading
// from a non-memory resident blob part (e.g. file-backed blob).
// The error details the system error code.
const error = lazyDOMException('The blob could not be read', 'NotReadableError');

c.error(error);
pending.reject(error);
return;
}
c.enqueue(new Uint8Array(buffer));
if (buffer !== undefined) {
c.enqueue(new Uint8Array(buffer));
}
pending.resolve();
});
return promise;
Expand Down Expand Up @@ -422,16 +440,22 @@ function resolveObjectURL(url) {
}
}

function createBlobFromFileHandle(handle) {
const [blob, length] = _createBlobFromFileHandle(handle);
return createBlob(blob, length);
// TODO(@jasnell): Now that the File class exists, we might consider having
// this return a `File` instead of a `Blob`.
function createBlobFromFilePath(path, options) {
const maybeBlob = _createBlobFromFilePath(path);
if (maybeBlob === undefined) {
return lazyDOMException('The blob could not be read', 'NotReadableError');
}
const { 0: blob, 1: length } = maybeBlob;
return createBlob(blob, length, options?.type);
}

module.exports = {
Blob,
ClonedBlob,
createBlob,
createBlobFromFileHandle,
createBlobFromFilePath,
isBlob,
kHandle,
resolveObjectURL,
Expand Down
10 changes: 0 additions & 10 deletions lib/internal/fs/promises.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ const {
S_IFREG
} = constants;

const { createBlobFromFileHandle } = require('internal/blob');

const binding = internalBinding('fs');
const { Buffer } = require('buffer');

Expand Down Expand Up @@ -312,14 +310,6 @@ class FileHandle extends EventEmitterMixin(JSTransferable) {
return new WriteStream(undefined, { ...options, fd: this });
}

/**
* @typedef {import('../blob').Blob} Blob
* @returns {Blob}
*/
blob() {
return createBlobFromFileHandle(this[kHandle]);
}

[kTransfer]() {
if (this[kClosePromise] || this[kRefs] > 1) {
throw lazyDOMException('Cannot transfer FileHandle while in use',
Expand Down
86 changes: 43 additions & 43 deletions src/async_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,49 +31,49 @@

namespace node {

#define NODE_ASYNC_NON_CRYPTO_PROVIDER_TYPES(V) \
V(NONE) \
V(DIRHANDLE) \
V(DNSCHANNEL) \
V(ELDHISTOGRAM) \
V(FILEHANDLE) \
V(FILEHANDLECLOSEREQ) \
V(BLOBREADER) \
V(FSEVENTWRAP) \
V(FSREQCALLBACK) \
V(FSREQPROMISE) \
V(GETADDRINFOREQWRAP) \
V(GETNAMEINFOREQWRAP) \
V(HEAPSNAPSHOT) \
V(HTTP2SESSION) \
V(HTTP2STREAM) \
V(HTTP2PING) \
V(HTTP2SETTINGS) \
V(HTTPINCOMINGMESSAGE) \
V(HTTPCLIENTREQUEST) \
V(JSSTREAM) \
V(JSUDPWRAP) \
V(MESSAGEPORT) \
V(PIPECONNECTWRAP) \
V(PIPESERVERWRAP) \
V(PIPEWRAP) \
V(PROCESSWRAP) \
V(PROMISE) \
V(QUERYWRAP) \
V(SHUTDOWNWRAP) \
V(SIGNALWRAP) \
V(STATWATCHER) \
V(STREAMPIPE) \
V(TCPCONNECTWRAP) \
V(TCPSERVERWRAP) \
V(TCPWRAP) \
V(TTYWRAP) \
V(UDPSENDWRAP) \
V(UDPWRAP) \
V(SIGINTWATCHDOG) \
V(WORKER) \
V(WORKERHEAPSNAPSHOT) \
V(WRITEWRAP) \
#define NODE_ASYNC_NON_CRYPTO_PROVIDER_TYPES(V) \
V(NONE) \
V(DIRHANDLE) \
V(DNSCHANNEL) \
V(ELDHISTOGRAM) \
V(FILEHANDLE) \
V(FILEHANDLECLOSEREQ) \
V(BLOBREADER) \
V(FSEVENTWRAP) \
V(FSREQCALLBACK) \
V(FSREQPROMISE) \
V(GETADDRINFOREQWRAP) \
V(GETNAMEINFOREQWRAP) \
V(HEAPSNAPSHOT) \
V(HTTP2SESSION) \
V(HTTP2STREAM) \
V(HTTP2PING) \
V(HTTP2SETTINGS) \
V(HTTPINCOMINGMESSAGE) \
V(HTTPCLIENTREQUEST) \
V(JSSTREAM) \
V(JSUDPWRAP) \
V(MESSAGEPORT) \
V(PIPECONNECTWRAP) \
V(PIPESERVERWRAP) \
V(PIPEWRAP) \
V(PROCESSWRAP) \
V(PROMISE) \
V(QUERYWRAP) \
V(SHUTDOWNWRAP) \
V(SIGNALWRAP) \
V(STATWATCHER) \
V(STREAMPIPE) \
V(TCPCONNECTWRAP) \
V(TCPSERVERWRAP) \
V(TCPWRAP) \
V(TTYWRAP) \
V(UDPSENDWRAP) \
V(UDPWRAP) \
V(SIGINTWATCHDOG) \
V(WORKER) \
V(WORKERHEAPSNAPSHOT) \
V(WRITEWRAP) \
V(ZLIB)

#if HAVE_OPENSSL
Expand Down
Loading

0 comments on commit 71fb06f

Please sign in to comment.