Initial commit: MangaReader iOS App
✨ Features: - App iOS completa para leer manga sin publicidad - Scraper con WKWebView para manhwaweb.com - Sistema de descargas offline - Lector con zoom y navegación - Favoritos y progreso de lectura - Compatible con iOS 15+ y Sideloadly/3uTools 📦 Contenido: - Backend Node.js con Puppeteer (opcional) - App iOS con SwiftUI - Scraper de capítulos e imágenes - Sistema de almacenamiento local - Testing completo - Documentación exhaustiva 🧪 Prueba: Capítulo 789 de One Piece descargado exitosamente - 21 páginas descargadas - 4.68 MB total - URLs verificadas y funcionales 🎉 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
124
backend/node_modules/undici/lib/util/runtime-features.js
generated
vendored
Normal file
124
backend/node_modules/undici/lib/util/runtime-features.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
'use strict'
|
||||
|
||||
/** @typedef {`node:${string}`} NodeModuleName */
|
||||
|
||||
/** @type {Record<NodeModuleName, () => any>} */
|
||||
const lazyLoaders = {
|
||||
__proto__: null,
|
||||
'node:crypto': () => require('node:crypto'),
|
||||
'node:sqlite': () => require('node:sqlite'),
|
||||
'node:worker_threads': () => require('node:worker_threads'),
|
||||
'node:zlib': () => require('node:zlib')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeModuleName} moduleName
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function detectRuntimeFeatureByNodeModule (moduleName) {
|
||||
try {
|
||||
lazyLoaders[moduleName]()
|
||||
return true
|
||||
} catch (err) {
|
||||
if (err.code !== 'ERR_UNKNOWN_BUILTIN_MODULE' && err.code !== 'ERR_NO_CRYPTO') {
|
||||
throw err
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeModuleName} moduleName
|
||||
* @param {string} property
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function detectRuntimeFeatureByExportedProperty (moduleName, property) {
|
||||
const module = lazyLoaders[moduleName]()
|
||||
return typeof module[property] !== 'undefined'
|
||||
}
|
||||
|
||||
const runtimeFeaturesByExportedProperty = /** @type {const} */ (['markAsUncloneable', 'zstd'])
|
||||
|
||||
/** @type {Record<RuntimeFeatureByExportedProperty, [NodeModuleName, string]>} */
|
||||
const exportedPropertyLookup = {
|
||||
markAsUncloneable: ['node:worker_threads', 'markAsUncloneable'],
|
||||
zstd: ['node:zlib', 'createZstdDecompress']
|
||||
}
|
||||
|
||||
/** @typedef {typeof runtimeFeaturesByExportedProperty[number]} RuntimeFeatureByExportedProperty */
|
||||
|
||||
const runtimeFeaturesAsNodeModule = /** @type {const} */ (['crypto', 'sqlite'])
|
||||
/** @typedef {typeof runtimeFeaturesAsNodeModule[number]} RuntimeFeatureByNodeModule */
|
||||
|
||||
const features = /** @type {const} */ ([
|
||||
...runtimeFeaturesAsNodeModule,
|
||||
...runtimeFeaturesByExportedProperty
|
||||
])
|
||||
|
||||
/** @typedef {typeof features[number]} Feature */
|
||||
|
||||
/**
|
||||
* @param {Feature} feature
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function detectRuntimeFeature (feature) {
|
||||
if (runtimeFeaturesAsNodeModule.includes(/** @type {RuntimeFeatureByNodeModule} */ (feature))) {
|
||||
return detectRuntimeFeatureByNodeModule(`node:${feature}`)
|
||||
} else if (runtimeFeaturesByExportedProperty.includes(/** @type {RuntimeFeatureByExportedProperty} */ (feature))) {
|
||||
const [moduleName, property] = exportedPropertyLookup[feature]
|
||||
return detectRuntimeFeatureByExportedProperty(moduleName, property)
|
||||
}
|
||||
throw new TypeError(`unknown feature: ${feature}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @name RuntimeFeatures
|
||||
*/
|
||||
class RuntimeFeatures {
|
||||
/** @type {Map<Feature, boolean>} */
|
||||
#map = new Map()
|
||||
|
||||
/**
|
||||
* Clears all cached feature detections.
|
||||
*/
|
||||
clear () {
|
||||
this.#map.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Feature} feature
|
||||
* @returns {boolean}
|
||||
*/
|
||||
has (feature) {
|
||||
return (
|
||||
this.#map.get(feature) ?? this.#detectRuntimeFeature(feature)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Feature} feature
|
||||
* @param {boolean} value
|
||||
*/
|
||||
set (feature, value) {
|
||||
if (features.includes(feature) === false) {
|
||||
throw new TypeError(`unknown feature: ${feature}`)
|
||||
}
|
||||
this.#map.set(feature, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Feature} feature
|
||||
* @returns {boolean}
|
||||
*/
|
||||
#detectRuntimeFeature (feature) {
|
||||
const result = detectRuntimeFeature(feature)
|
||||
this.#map.set(feature, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new RuntimeFeatures()
|
||||
|
||||
module.exports.runtimeFeatures = instance
|
||||
module.exports.default = instance
|
||||
Reference in New Issue
Block a user