import { ZlibOptions } from 'zlib' ; import { Extension , ExtensionDescriptor } from '@statoscope/stats/spec/extension' ; import makeResolver , { Resolver } from '@statoscope/helpers/dist/entity-resolver' ; import gzipSize from 'gzip-size' ; const { name , version , author , homepage , description } = require ( '../package.json' ) ; export type Compressor = string | { name : string ; version : string ; } ; export type Size = { compressor ? : Compressor ; size : number ; meta ? : unknown ; } ; export type CompressFunction < TOptions = any > = ( source : Buffer | string , filename : string , options ? : TOptions ) => Size ; export type Format = Extension < Payload > ; export type Resource = { id : string ; size : Size ; } ; export type Compilation = { id : string ; resources : Array < Resource > ; } ; export type Payload = { compilations : Array < Compilation > ; } ; const compressorByType = { gzip ( source , filename , options ? ) { const level = options ?. level ?? 6 ; return { compressor : 'gzip' , size : gzipSize . sync ( source , { level , ... options } ) , meta : { level : 6 , } , } ; } , } ; export type ResolvedCompressor = { compressor : CompressFunction < unknown > ; params ? : unknown ; } ; export type CompressorOrPreset = string | [ 'gzip' , ZlibOptions ? ] | CompressFunction ; export default class Generator { private sizeResolvers : Map < Compilation , Resolver < string , Resource > > = new Map ( ) ; private descriptor : ExtensionDescriptor = { name , version , author , homepage , description , adapter : this . adapter , } ; private payload : Payload = { compilations : [ ] } ; private resolveCompilation = makeResolver ( this . payload . compilations , ( item ) => item . id , null , false ) ; constructor ( private adapter ? ) { } handleResource ( compilationId , resourceId , source , compressor ) { let compilation = this . resolveCompilation ( compilationId ) ; let sizeResolver ; if ( compilation ) { sizeResolver = this . sizeResolvers . get ( compilation ) ; } else { compilation = { id : compilationId , resources : [ ] , } ; sizeResolver = makeResolver ( compilation . resources , ( item ) => item . id , null , false ) ; this . sizeResolvers . set ( compilation , sizeResolver ) ; this . payload . compilations . push ( compilation ) ; } if ( ! sizeResolver ! ( resourceId ) ) { const resolvedCompressor = this . resolveCompressor ( compressor ) ; const size = resolvedCompressor . compressor ( source , resourceId , resolvedCompressor . params ) ; compilation . resources . push ( { id : resourceId , size } ) ; } } get ( ) { return { descriptor : this . descriptor , payload : this . payload } ; } private resolveCompressor ( compressor ) { if ( compressor === 'gzip' ) { compressor = [ compressor ] ; } if ( typeof compressor === 'function' ) { return { compressor } ; } if ( Array . isArray ( compressor ) ) { const [ name , params ] = compressor ; if ( Object . prototype . hasOwnProperty . call ( compressorByType , name ) ) { return { compressor : compressorByType [ name ] , params } ; } } throw new Error ( `Unknown compress ${ compressor }` ) ; } }