UNPKG

@solid/community-server

Version:

Community Solid Server: an open and modular implementation of the Solid specifications

101 lines 4.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateCachedRepresentationSize = calculateCachedRepresentationSize; exports.readStream = readStream; exports.cachedToRepresentation = cachedToRepresentation; exports.representationToCached = representationToCached; exports.duplicateRepresentation = duplicateRepresentation; const node_stream_1 = require("node:stream"); const global_logger_factory_1 = require("global-logger-factory"); const BasicRepresentation_1 = require("../http/representation/BasicRepresentation"); const RepresentationMetadata_1 = require("../http/representation/RepresentationMetadata"); const ErrorUtil_1 = require("./errors/ErrorUtil"); const NotImplementedHttpError_1 = require("./errors/NotImplementedHttpError"); const StreamUtil_1 = require("./StreamUtil"); const logger = (0, global_logger_factory_1.getLoggerFor)('CacheUtil'); /** * Function that can be used as `sizeCalculation` for an LRU cache storing {@link CachedRepresentation}s. * The length of the data is used, so in the case of an array, the size of the entries is not taken into account. * * @param cached - The cached entry to determine the size of. */ function calculateCachedRepresentationSize(cached) { // Needs to be a positive integer return cached.data.length + 1; } /** * Reads a data stream into an array or buffer, depending on if it is in object mode or not. * * @param stream - Data stream to read. */ async function readStream(stream) { if (stream.readableObjectMode) { const data = []; for await (const obj of stream) { data.push(obj); } return data; } const chunks = []; for await (const chunk of stream) { if (typeof chunk === 'string') { chunks.push(Buffer.from(chunk)); } else if (Buffer.isBuffer(chunk)) { chunks.push(chunk); } else { throw new NotImplementedHttpError_1.NotImplementedHttpError(`Unexpected ${typeof chunk} chunk: ${chunk}`); } } return Buffer.concat(chunks); } /** * Generates a {@link Representation} based on a {@link CachedRepresentation}. * The generated value is not linked to the {@link CachedRepresentation}, * so any changes to it will not impact the original. * * @param cached - {@link CachedRepresentation} to create a representation from */ function cachedToRepresentation(cached) { // Copy the metadata quads to prevent changes to the original cached metadata const metadata = new RepresentationMetadata_1.RepresentationMetadata(cached.metadata); return new BasicRepresentation_1.BasicRepresentation((0, StreamUtil_1.guardedStreamFrom)(cached.data, { objectMode: Array.isArray(cached.data) }), metadata); } /** * Generates a {@link CachedRepresentation} based on a {@link Representation}. * The generated value is not linked to the {@link Representation}, * so any changes to it will not impact the original. * * Returns undefined if there was an error, implying the data was not fully read. * * @param representation - Representation to convert. */ async function representationToCached(representation) { try { const data = await readStream(representation.data); const metadata = new RepresentationMetadata_1.RepresentationMetadata(representation.metadata); return { data, metadata }; } catch (error) { // This just means the request was not interested in the data and closed the stream if (error.message !== 'Premature close') { logger.error(`Unable to cache representation for ${representation.metadata.identifier.value}: ${(0, ErrorUtil_1.createErrorMessage)(error)}`); } } } /** * Generates 2 {@link Representation}s from a single one. * After this the input representation should not be used any more. * * @param representation - Representation to duplicate. */ function duplicateRepresentation(representation) { const stream1 = (0, StreamUtil_1.pipeSafely)(representation.data, new node_stream_1.PassThrough({ objectMode: representation.data.readableObjectMode })); const stream2 = (0, StreamUtil_1.pipeSafely)(representation.data, new node_stream_1.PassThrough({ objectMode: representation.data.readableObjectMode })); return [ new BasicRepresentation_1.BasicRepresentation(stream1, new RepresentationMetadata_1.RepresentationMetadata(representation.metadata)), new BasicRepresentation_1.BasicRepresentation(stream2, new RepresentationMetadata_1.RepresentationMetadata(representation.metadata)), ]; } //# sourceMappingURL=CacheUtil.js.map