diff --git a/src/bl/polyfill/polyfill-bl.ts b/src/bl/polyfill/polyfill-bl.ts index 67bdc7f..bb9fe0e 100644 --- a/src/bl/polyfill/polyfill-bl.ts +++ b/src/bl/polyfill/polyfill-bl.ts @@ -22,7 +22,7 @@ export class PolyfillBl implements IPolyfillBl { */ async getPolyfills(request: IPolyfillRequest): Promise { // Check if a polyfill set exists within the cache for the request features and the user agent of the request - let featureSet = await this.cacheRegistry.getPolyfillFeatureSet(request.features, request.userAgent, request.context); + let featureSet = await this.cacheRegistry.getPolyfillFeatureSet(request.features, request); // If not, resolve and order the required polyfills if (featureSet == null) { @@ -37,7 +37,7 @@ export class PolyfillBl implements IPolyfillBl { ); // Store them within the cache - await this.cacheRegistry.setPolyfillFeatureSet(request.features, featureSet, request.userAgent, request.context); + await this.cacheRegistry.setPolyfillFeatureSet(request.features, featureSet, request); } else { this.logger.debug("Matched Polyfill Set in cache!"); } @@ -45,7 +45,7 @@ export class PolyfillBl implements IPolyfillBl { this.logger.debug(featureSet); // Check if a Set has already been registered for this combination - const existingSet = await this.cacheRegistry.get(featureSet, request.context, request.encoding); + const existingSet = await this.cacheRegistry.get(featureSet, request); if (existingSet != null) { this.logger.debug("Matched Polyfills in cache!"); // If it has, just return that one @@ -57,9 +57,9 @@ export class PolyfillBl implements IPolyfillBl { // Add the polyfills to the registry const [minifiedResult, brotliResult, zlibResult] = await Promise.all([ - this.cacheRegistry.set(featureSet, minified, request.context), - this.cacheRegistry.set(featureSet, brotli, request.context, ContentEncodingKind.BROTLI), - this.cacheRegistry.set(featureSet, zlib, request.context, ContentEncodingKind.GZIP) + this.cacheRegistry.set(featureSet, minified, {...request, encoding: undefined}), + this.cacheRegistry.set(featureSet, brotli, {...request, encoding: ContentEncodingKind.BROTLI}), + this.cacheRegistry.set(featureSet, zlib, {...request, encoding: ContentEncodingKind.GZIP}) ]); // Return the joined Buffer diff --git a/src/service/registry/cache-registry/cache-registry-service.ts b/src/service/registry/cache-registry/cache-registry-service.ts index bdc12b4..0cb6846 100644 --- a/src/service/registry/cache-registry/cache-registry-service.ts +++ b/src/service/registry/cache-registry/cache-registry-service.ts @@ -1,19 +1,17 @@ import {ICacheRegistryService} from "./i-cache-registry-service"; import {IFileSaver} from "@wessberg/filesaver"; import {IPolyfillFeature, IPolyfillFeatureInput} from "../../../polyfill/i-polyfill-feature"; -import {ContentEncodingKind} from "../../../encoding/content-encoding-kind"; import {getPolyfillIdentifier, getPolyfillSetIdentifier} from "../../../util/polyfill/polyfill-util"; import {join} from "path"; import {constant} from "../../../constant/constant"; import {IFileLoader} from "@wessberg/fileloader"; -import {IMemoryRegistryService} from "../polyfill-registry/i-memory-registry-service"; +import {IMemoryRegistryService, PolyfillCachingContext} from "../polyfill-registry/i-memory-registry-service"; import {PolyfillName} from "../../../polyfill/polyfill-name"; import {coerce, gt} from "semver"; import {IConfig} from "../../../config/i-config"; import {IRegistryGetResult} from "../polyfill-registry/i-registry-get-result"; import {ILoggerService} from "../../logger/i-logger-service"; import {PolyfillDictEntry} from "../../../polyfill/polyfill-dict"; -import {PolyfillContext} from "../../../polyfill/polyfill-context"; /** * A class that can cache generated Polyfills on disk @@ -42,67 +40,67 @@ export class CacheRegistryService implements ICacheRegistryService { /** * Gets the contents for the polyfill with the given name and with the given encoding */ - async get(name: IPolyfillFeature | Set, context: PolyfillContext, encoding?: ContentEncodingKind): Promise { + async get(name: IPolyfillFeature | Set, context: PolyfillCachingContext): Promise { // Attempt to fetch it from the in-memory registry - const memoryHit = await this.memoryRegistry.get(name, context, encoding); + const memoryHit = await this.memoryRegistry.get(name, context); if (memoryHit != null) return memoryHit; // Otherwise, attempt to get it from cache - const buffer = await this.getFromCache(this.getCachePath(name, context, encoding)); + const buffer = await this.getFromCache(this.getCachePath(name, context)); // If not possible, return undefined if (buffer == null) return undefined; // Otherwise, store it in the memory registry and return the Buffer - return await this.memoryRegistry.set(name, buffer, context, encoding); + return await this.memoryRegistry.set(name, buffer, context); } /** * Gets the Set of Polyfill feature inputs that matches the given input */ - async getPolyfillFeatureSet(input: Set, userAgent: string, context: PolyfillContext): Promise | undefined> { + async getPolyfillFeatureSet(input: Set, context: PolyfillCachingContext): Promise | undefined> { // Attempt to fetch it from the in-memory registry - const memoryHit = await this.memoryRegistry.getPolyfillFeatureSet(input, userAgent, context); + const memoryHit = await this.memoryRegistry.getPolyfillFeatureSet(input, context); if (memoryHit != null) return memoryHit; // Otherwise, attempt to get it from cache - const buffer = await this.getFromCache(this.getCachePathForPolyfillSet(input, userAgent, context)); + const buffer = await this.getFromCache(this.getCachePathForPolyfillSet(input, context)); // If not possible, return undefined if (buffer == null) return undefined; // Otherwise, store it in the memory registry and return the Buffer - return await this.memoryRegistry.setPolyfillFeatureSet(input, new Set(JSON.parse(buffer.toString())), userAgent, context); + return await this.memoryRegistry.setPolyfillFeatureSet(input, new Set(JSON.parse(buffer.toString())), context); } /** * Returns true if a polyfill wil the given name exists */ - async has(name: IPolyfillFeature | Set, context: PolyfillContext, encoding?: ContentEncodingKind): Promise { - return (await this.get(name, context, encoding)) != null; + async has(name: IPolyfillFeature | Set, context: PolyfillCachingContext): Promise { + return (await this.get(name, context)) != null; } /** * Returns true if there is a PolyfillFeature Set in the cache that matches the given input Set */ - async hasPolyfillFeatureSet(input: Set, userAgent: string, context: PolyfillContext): Promise { - return (await this.getPolyfillFeatureSet(input, userAgent, context)) != null; + async hasPolyfillFeatureSet(input: Set, context: PolyfillCachingContext): Promise { + return (await this.getPolyfillFeatureSet(input, context)) != null; } /** * Sets the contents for the polyfill with the given name and of the given encoding */ - async set(name: IPolyfillFeature | Set, contents: Buffer, context: PolyfillContext, encoding?: ContentEncodingKind): Promise { + async set(name: IPolyfillFeature | Set, contents: Buffer, context: PolyfillCachingContext): Promise { // Add it to the memory cache as well as the disk cache - await this.writeToCache(this.getCachePath(name, context, encoding), contents); - return await this.memoryRegistry.set(name, contents, context, encoding); + await this.writeToCache(this.getCachePath(name, context), contents); + return await this.memoryRegistry.set(name, contents, context); } /** * Sets the given PolyfillFeature Set for the given Set of PolyfillFeature inputs */ - async setPolyfillFeatureSet(input: Set, polyfillSet: Set, userAgent: string, context: PolyfillContext): Promise> { + async setPolyfillFeatureSet(input: Set, polyfillSet: Set, context: PolyfillCachingContext): Promise> { // Add it to the memory cache as well as the disk cache - await this.writeToCache(this.getCachePathForPolyfillSet(input, userAgent, context), Buffer.from(JSON.stringify([...polyfillSet]))); - return await this.memoryRegistry.setPolyfillFeatureSet(input, polyfillSet, userAgent, context); + await this.writeToCache(this.getCachePathForPolyfillSet(input, context), Buffer.from(JSON.stringify([...polyfillSet]))); + return await this.memoryRegistry.setPolyfillFeatureSet(input, polyfillSet, context); } /** @@ -225,14 +223,14 @@ export class CacheRegistryService implements ICacheRegistryService { /** * Gets the cache path to the given name and encoding */ - private getCachePath(name: IPolyfillFeature | Set, context: PolyfillContext, encoding?: ContentEncodingKind): string { - return join(constant.path.cacheRoot, getPolyfillIdentifier(name, context, encoding)); + private getCachePath(name: IPolyfillFeature | Set, context: PolyfillCachingContext): string { + return join(constant.path.cacheRoot, getPolyfillIdentifier(name, context)); } /** * Gets the cache path to the given Polyfill Feature Set */ - private getCachePathForPolyfillSet(input: Set, userAgent: string, context: PolyfillContext): string { - return join(constant.path.cacheRoot, getPolyfillSetIdentifier(input, userAgent, context)); + private getCachePathForPolyfillSet(input: Set, context: PolyfillCachingContext): string { + return join(constant.path.cacheRoot, getPolyfillSetIdentifier(input, context)); } } diff --git a/src/service/registry/polyfill-registry/i-memory-registry-service.ts b/src/service/registry/polyfill-registry/i-memory-registry-service.ts index 9f91d27..1b68a8f 100644 --- a/src/service/registry/polyfill-registry/i-memory-registry-service.ts +++ b/src/service/registry/polyfill-registry/i-memory-registry-service.ts @@ -1,13 +1,14 @@ -import {ContentEncodingKind} from "../../../encoding/content-encoding-kind"; import {IPolyfillFeature, IPolyfillFeatureInput} from "../../../polyfill/i-polyfill-feature"; import {IRegistryGetResult} from "./i-registry-get-result"; -import {PolyfillContext} from "../../../polyfill/polyfill-context"; +import {IPolyfillRequest} from "../../../polyfill/i-polyfill-request"; + +export interface PolyfillCachingContext extends Omit {} export interface IMemoryRegistryService { - get(name: IPolyfillFeature | Set, context: PolyfillContext, encoding?: ContentEncodingKind): Promise; - getPolyfillFeatureSet(input: Set, userAgent: string, context: PolyfillContext): Promise | undefined>; - set(name: IPolyfillFeature | Set, contents: Buffer, context: PolyfillContext, encoding?: ContentEncodingKind): Promise; - setPolyfillFeatureSet(input: Set, polyfillSet: Set, userAgent: string, context: PolyfillContext): Promise>; - has(name: IPolyfillFeature | Set, context: PolyfillContext, encoding?: ContentEncodingKind): Promise; - hasPolyfillFeatureSet(input: Set, userAgent: string, context: PolyfillContext): Promise; + get(name: IPolyfillFeature | Set, context: PolyfillCachingContext): Promise; + getPolyfillFeatureSet(input: Set, context: PolyfillCachingContext): Promise | undefined>; + set(name: IPolyfillFeature | Set, contents: Buffer, context: PolyfillCachingContext): Promise; + setPolyfillFeatureSet(input: Set, polyfillSet: Set, context: PolyfillCachingContext): Promise>; + has(name: IPolyfillFeature | Set, context: PolyfillCachingContext): Promise; + hasPolyfillFeatureSet(input: Set, context: PolyfillCachingContext): Promise; } diff --git a/src/service/registry/polyfill-registry/memory-registry-service.ts b/src/service/registry/polyfill-registry/memory-registry-service.ts index 426b93c..975d484 100644 --- a/src/service/registry/polyfill-registry/memory-registry-service.ts +++ b/src/service/registry/polyfill-registry/memory-registry-service.ts @@ -1,9 +1,7 @@ -import {IMemoryRegistryService} from "./i-memory-registry-service"; -import {ContentEncodingKind} from "../../../encoding/content-encoding-kind"; +import {IMemoryRegistryService, PolyfillCachingContext} from "./i-memory-registry-service"; import {IPolyfillFeature, IPolyfillFeatureInput} from "../../../polyfill/i-polyfill-feature"; import {getPolyfillIdentifier, getPolyfillSetIdentifier} from "../../../util/polyfill/polyfill-util"; import {IRegistryGetResult} from "./i-registry-get-result"; -import {PolyfillContext} from "../../../polyfill/polyfill-context"; /** * A Registry of polyfills living in-memory @@ -24,8 +22,8 @@ export class MemoryRegistryService implements IMemoryRegistryService { /** * Gets the contents for the polyfill with the given name and with the given encoding */ - async get(name: IPolyfillFeature | Set, context: PolyfillContext, encoding?: ContentEncodingKind): Promise { - const checksum = getPolyfillIdentifier(name, context, encoding); + async get(name: IPolyfillFeature | Set, context: PolyfillCachingContext): Promise { + const checksum = getPolyfillIdentifier(name, context); const buffer = this.registeredPolyfills.get(checksum); return buffer == null ? undefined : {buffer, checksum}; @@ -34,30 +32,30 @@ export class MemoryRegistryService implements IMemoryRegistryService { /** * Gets the Set of Polyfill feature inputs that matches the given input */ - async getPolyfillFeatureSet(input: Set, userAgent: string, context: PolyfillContext): Promise | undefined> { - const checksum = getPolyfillSetIdentifier(input, userAgent, context); + async getPolyfillFeatureSet(input: Set, context: PolyfillCachingContext): Promise | undefined> { + const checksum = getPolyfillSetIdentifier(input, context); return this.registeredPolyfillSets.get(checksum); } /** * Returns true if a polyfill wil the given name exists */ - async has(name: IPolyfillFeature | Set, context: PolyfillContext, encoding?: ContentEncodingKind): Promise { - return this.registeredPolyfills.has(getPolyfillIdentifier(name, context, encoding)); + async has(name: IPolyfillFeature | Set, context: PolyfillCachingContext): Promise { + return this.registeredPolyfills.has(getPolyfillIdentifier(name, context)); } /** * Returns true if a Set of PolyfillFeatures exist in cache for the given PolyfillFeature input Set */ - async hasPolyfillFeatureSet(input: Set, userAgent: string, context: PolyfillContext): Promise { - return this.registeredPolyfillSets.has(getPolyfillSetIdentifier(input, userAgent, context)); + async hasPolyfillFeatureSet(input: Set, context: PolyfillCachingContext): Promise { + return this.registeredPolyfillSets.has(getPolyfillSetIdentifier(input, context)); } /** * Sets the contents for the polyfill with the given name and of the given encoding */ - async set(name: IPolyfillFeature | Set, buffer: Buffer, context: PolyfillContext, encoding?: ContentEncodingKind): Promise { - const checksum = getPolyfillIdentifier(name, context, encoding); + async set(name: IPolyfillFeature | Set, buffer: Buffer, context: PolyfillCachingContext): Promise { + const checksum = getPolyfillIdentifier(name, context); this.registeredPolyfills.set(checksum, buffer); return {buffer, checksum}; @@ -66,8 +64,8 @@ export class MemoryRegistryService implements IMemoryRegistryService { /** * Sets the given PolyfillFeature Set for the given Set of PolyfillFeature inputs */ - async setPolyfillFeatureSet(input: Set, polyfillSet: Set, userAgent: string, context: PolyfillContext): Promise> { - const checksum = getPolyfillSetIdentifier(input, userAgent, context); + async setPolyfillFeatureSet(input: Set, polyfillSet: Set, context: PolyfillCachingContext): Promise> { + const checksum = getPolyfillSetIdentifier(input, context); this.registeredPolyfillSets.set(checksum, polyfillSet); return polyfillSet; diff --git a/src/util/polyfill/polyfill-util.ts b/src/util/polyfill/polyfill-util.ts index 8c76b6e..661e164 100644 --- a/src/util/polyfill/polyfill-util.ts +++ b/src/util/polyfill/polyfill-util.ts @@ -17,6 +17,7 @@ import {IPolyfillLibraryDictEntry, IPolyfillLocalDictEntry} from "../../polyfill // @ts-ignore import toposort from "toposort"; import {POLYFILL_CONTEXTS, PolyfillContext} from "../../polyfill/polyfill-context"; +import {PolyfillCachingContext} from "../../service/registry/polyfill-registry/i-memory-registry-service"; /** * Traces all polyfill names that matches the given name. It may be an alias, and it may refer to additional aliases @@ -48,25 +49,24 @@ export function traceAllPolyfillNamesForPolyfillName(name: PolyfillName): Set | Set, - context: PolyfillContext, - encoding?: string + context: PolyfillCachingContext ): string { const shasum = createHash("sha1"); const normalizedName = name instanceof Set ? name : new Set([name]); const sortedName = [...normalizedName].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); const namePart = sortedName.map(part => `${part.name}${JSON.stringify(part.meta)}${context}`).join(","); - shasum.update(`[${namePart}].${encoding == null ? "" : encoding}`); + shasum.update(`[${namePart}].${context.sourcemap}.${context.minify}.${context.encoding || "none"}`); return shasum.digest("hex"); } /** * Returns a stringified key as a function of the given Set of polyfill feature inputs */ -export function getPolyfillSetIdentifier(polyfills: Set, userAgent: string, context: PolyfillContext): string { +export function getPolyfillSetIdentifier(polyfills: Set, context: PolyfillCachingContext): string { const shasum = createHash("sha1"); const sortedName = [...polyfills].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); const namePart = sortedName.map(part => `${part.name}${JSON.stringify(part.meta)}${JSON.stringify(part.force)}${JSON.stringify(context)}`).join(","); - shasum.update(`[${namePart}].${userAgent}`); + shasum.update(`[${namePart}].${context.userAgent}.${context.context}`); return shasum.digest("hex"); }