diff options
Diffstat (limited to 'src/file-size-preloader.js')
-rw-r--r-- | src/file-size-preloader.js | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/src/file-size-preloader.js b/src/file-size-preloader.js index 4eadde7b..b2a55407 100644 --- a/src/file-size-preloader.js +++ b/src/file-size-preloader.js @@ -18,8 +18,10 @@ // are very, very fast. import {stat} from 'node:fs/promises'; +import {relative, resolve, sep} from 'node:path'; import {logWarn} from '#cli'; +import {filterMultipleArrays, transposeArrays} from '#sugar'; export default class FileSizePreloader { #paths = []; @@ -31,6 +33,10 @@ export default class FileSizePreloader { hadErrored = false; + constructor({prefix = ''} = {}) { + this.prefix = prefix; + } + loadPaths(...paths) { this.#paths.push(...paths.filter((p) => !this.#paths.includes(p))); return this.#startLoadingPaths(); @@ -45,9 +51,9 @@ export default class FileSizePreloader { return this.#loadingPromise; } - this.#loadingPromise = new Promise((resolve) => { - this.#resolveLoadingPromise = resolve; - }); + ({promise: this.#loadingPromise, + resolve: this.#resolveLoadingPromise} = + Promise.withResolvers()); this.#loadNextPath(); @@ -96,9 +102,54 @@ export default class FileSizePreloader { } getSizeOfPath(path) { + let size = this.#getSizeOfPath(path); + if (size || !this.prefix) return size; + const path2 = resolve(this.prefix, path); + if (path2 === path) return null; + return this.#getSizeOfPath(path2); + } + + #getSizeOfPath(path) { const index = this.#paths.indexOf(path); if (index === -1) return null; if (index > this.#loadedPathIndex) return null; return this.#sizes[index]; } + + saveAsCache() { + const entries = + transposeArrays([ + this.#paths.slice(0, this.#loadedPathIndex) + .map(path => relative(this.prefix, path)), + + this.#sizes.slice(0, this.#loadedPathIndex), + ]); + + // Do not be alarmed: This cannot be meaningfully moved to + // the top because stringifyCache sorts alphabetically lol + entries.push(['_separator', sep]); + + return Object.fromEntries(entries); + } + + loadFromCache(cache) { + const {_separator: cacheSep, ...rest} = cache; + const entries = Object.entries(rest); + let [newPaths, newSizes] = transposeArrays(entries); + + if (sep !== cacheSep) { + newPaths = newPaths.map(p => p.split(cacheSep).join(sep)); + } + + newPaths = newPaths.map(p => resolve(this.prefix, p)); + + filterMultipleArrays( + newPaths, + newSizes, + path => !this.#paths.includes(path)); + + this.#paths.splice(this.#loadedPathIndex + 1, 0, ...newPaths); + this.#sizes.splice(this.#loadedPathIndex + 1, 0, ...newSizes); + this.#loadedPathIndex += entries.length; + } } |