@parcel/core
Version:
142 lines (120 loc) • 3.81 kB
JavaScript
// @flow strict-local
import type {AST, Blob} from '@parcel/types';
import type {Asset, Dependency, ParcelOptions} from './types';
import {Readable} from 'stream';
import SourceMap from '@parcel/source-map';
import {bufferStream, blobToStream, streamFromPromise} from '@parcel/utils';
import {generateFromAST} from './assetUtils';
import {deserializeRaw} from './serializer';
export default class CommittedAsset {
value: Asset;
options: ParcelOptions;
content: ?Promise<Buffer | string>;
mapBuffer: ?Promise<?Buffer>;
map: ?Promise<?SourceMap>;
ast: ?Promise<AST>;
idBase: ?string;
generatingPromise: ?Promise<void>;
constructor(value: Asset, options: ParcelOptions) {
this.value = value;
this.options = options;
}
getContent(): Blob | Promise<Buffer | string> {
if (this.content == null) {
if (this.value.contentKey != null) {
if (this.value.isLargeBlob) {
return this.options.cache.getStream(this.value.contentKey);
} else {
return this.options.cache.getBlob(this.value.contentKey);
}
} else if (this.value.astKey != null) {
return streamFromPromise(
generateFromAST(this).then(({content}) => {
if (!(content instanceof Readable)) {
this.content = Promise.resolve(content);
}
return content;
}),
);
} else {
throw new Error('Asset has no content');
}
}
return this.content;
}
async getCode(): Promise<string> {
let content;
if (this.content == null && this.value.contentKey != null) {
this.content = this.options.cache.getBlob(this.value.contentKey);
content = await this.content;
} else {
content = await this.getContent();
}
if (typeof content === 'string' || content instanceof Buffer) {
return content.toString();
} else if (content != null) {
this.content = bufferStream(content);
return (await this.content).toString();
}
return '';
}
async getBuffer(): Promise<Buffer> {
let content = await this.getContent();
if (content == null) {
return Buffer.alloc(0);
} else if (typeof content === 'string' || content instanceof Buffer) {
return Buffer.from(content);
}
this.content = bufferStream(content);
return this.content;
}
getStream(): Readable {
let content = this.getContent();
return content instanceof Promise
? streamFromPromise(content)
: blobToStream(content);
}
getMapBuffer(): Promise<?Buffer> {
let mapKey = this.value.mapKey;
if (mapKey != null && this.mapBuffer == null) {
this.mapBuffer = (async () => {
try {
return await this.options.cache.getBlob(mapKey);
} catch (err) {
if (err.code === 'ENOENT' && this.value.astKey != null) {
return (await generateFromAST(this)).map?.toBuffer();
} else {
throw err;
}
}
})();
}
return this.mapBuffer ?? Promise.resolve();
}
getMap(): Promise<?SourceMap> {
if (this.map == null) {
this.map = (async () => {
let mapBuffer = await this.getMapBuffer();
if (mapBuffer) {
// Get sourcemap from flatbuffer
return new SourceMap(this.options.projectRoot, mapBuffer);
}
})();
}
return this.map;
}
getAST(): Promise<?AST> {
if (this.value.astKey == null) {
return Promise.resolve(null);
}
if (this.ast == null) {
this.ast = this.options.cache
.getBlob(this.value.astKey)
.then(serializedAst => deserializeRaw(serializedAst));
}
return this.ast;
}
getDependencies(): Array<Dependency> {
return Array.from(this.value.dependencies.values());
}
}