/
Starolat
/
DeepDive
Обзор
Документация
Войти
/
Starolat
/
DeepDive
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
js/services/ZipCompressionService.js
124 строки
3 KB
Starolat Sergei
feat: добавлено версионирование, cache busting и автоматизация CHANGELOG
03 июл 2026, 13:21
03 июл 2026, 13:21
707cbcd
Код
Авторство
О чём код?
// @ts-check /** * @fileoverview ZipCompressionService — сжатие/распаковка через JSZip. * @module ZipCompressionService * @version 1.0.0 * * Используется в средах, где недоступен нативный zstd (CompressionStream) * и zstd-wasm. JSZip работает на чистом JavaScript и поддерживает DEFLATE. */ /** * @typedef {Object} ZipCapabilities * @property {boolean} compress * @property {boolean} decompress */ const ZIP_ENTRY_NAME = "data.bin"; class ZipCompressionService { constructor() { /** @type {ZipCapabilities|null} */ this._capabilities = null; /** @type {Promise<typeof import('../../lib/jszip.esm.js').default>|null} */ this._jszipPromise = null; } /** * Проверяет доступность JSZip в текущей среде. * @returns {ZipCapabilities} */ getCapabilities() { if (this._capabilities) return this._capabilities; const caps = { compress: false, decompress: false }; if (typeof window !== "undefined") { // Browser: JSZip подключается через index.html и доступен как window.JSZip const jszip = window.JSZip; caps.compress = typeof jszip === "function"; caps.decompress = typeof jszip === "function"; } else { // Node.js: JSZip доступен через CommonJS/ESM импорт из lib/jszip.min.js caps.compress = true; caps.decompress = true; } this._capabilities = caps; return caps; } /** * @returns {boolean} */ isSupported() { const caps = this.getCapabilities(); return caps.compress && caps.decompress; } /** * Сжимает Uint8Array в zip-архив (DEFLATE). * @param {Uint8Array} data * @param {number} [level=6] - уровень сжатия DEFLATE (1-9) * @returns {Promise<Uint8Array>} */ async compress(data, level = 6) { const JSZip = await this._loadJSZip(); const zip = new JSZip(); zip.file(ZIP_ENTRY_NAME, data, { compression: "DEFLATE", compressionOptions: { level: Math.max(1, Math.min(9, level)) }, }); return zip.generateAsync({ type: "uint8array" }); } /** * Распаковывает zip-архив в Uint8Array. * @param {Uint8Array} data * @returns {Promise<Uint8Array>} */ async decompress(data) { const JSZip = await this._loadJSZip(); const zip = await JSZip.loadAsync(data); const entry = zip.file(ZIP_ENTRY_NAME); if (!entry) { // Если в архиве нет data.bin, пробуем первый файл const files = zip.file(/.+/); if (!files.length) { throw new Error("Zip archive is empty"); } return files[0].async("uint8array"); } return entry.async("uint8array"); } /** * @private * @returns {Promise<typeof import('../../lib/jszip.esm.js').default>} */ async _loadJSZip() { if (this._jszipPromise) return this._jszipPromise; this._jszipPromise = (async () => { if (typeof window !== "undefined" && window.JSZip) { return window.JSZip; } const mod = await import("../../lib/jszip.esm.js?__BUILD_ID__"); return mod.default; })(); return this._jszipPromise; } /** * @private * @returns {any|null} */ _resolveJSZip() { if (typeof window !== "undefined" && window.JSZip) return window.JSZip; return null; } } const zipCompressionService = new ZipCompressionService(); export default zipCompressionService;