playlist-data-engine 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +352 -0
- package/dist/__vite-browser-external-DYxpcVy9.js +4 -0
- package/dist/constants/DefaultClasses.d.ts +46 -0
- package/dist/constants/DefaultClasses.d.ts.map +1 -0
- package/dist/constants/DefaultEnchantments.d.ts +337 -0
- package/dist/constants/DefaultEnchantments.d.ts.map +1 -0
- package/dist/constants/DefaultEnemies.d.ts +83 -0
- package/dist/constants/DefaultEnemies.d.ts.map +1 -0
- package/dist/constants/DefaultEquipment.d.ts +23 -0
- package/dist/constants/DefaultEquipment.d.ts.map +1 -0
- package/dist/constants/DefaultFeatures.d.ts +22 -0
- package/dist/constants/DefaultFeatures.d.ts.map +1 -0
- package/dist/constants/DefaultRaces.d.ts +102 -0
- package/dist/constants/DefaultRaces.d.ts.map +1 -0
- package/dist/constants/DefaultSkills.d.ts +26 -0
- package/dist/constants/DefaultSkills.d.ts.map +1 -0
- package/dist/constants/DefaultSpells.d.ts +41 -0
- package/dist/constants/DefaultSpells.d.ts.map +1 -0
- package/dist/constants/EncounterBalance.d.ts +208 -0
- package/dist/constants/EncounterBalance.d.ts.map +1 -0
- package/dist/constants/EnemyEquipment.d.ts +71 -0
- package/dist/constants/EnemyEquipment.d.ts.map +1 -0
- package/dist/constants/EnemyRarity.d.ts +79 -0
- package/dist/constants/EnemyRarity.d.ts.map +1 -0
- package/dist/constants/EnemyTemplates/Construct.d.ts +63 -0
- package/dist/constants/EnemyTemplates/Construct.d.ts.map +1 -0
- package/dist/constants/EnemyTemplates/Dragon.d.ts +68 -0
- package/dist/constants/EnemyTemplates/Dragon.d.ts.map +1 -0
- package/dist/constants/EnemyTemplates/Elemental.d.ts +64 -0
- package/dist/constants/EnemyTemplates/Elemental.d.ts.map +1 -0
- package/dist/constants/EnemyTemplates/Fiend.d.ts +62 -0
- package/dist/constants/EnemyTemplates/Fiend.d.ts.map +1 -0
- package/dist/constants/EnemyTemplates/Monstrosity.d.ts +63 -0
- package/dist/constants/EnemyTemplates/Monstrosity.d.ts.map +1 -0
- package/dist/constants/EnemyTemplates/Undead.d.ts +61 -0
- package/dist/constants/EnemyTemplates/Undead.d.ts.map +1 -0
- package/dist/constants/ItemTemplates.d.ts +40 -0
- package/dist/constants/ItemTemplates.d.ts.map +1 -0
- package/dist/constants/MagicItems.d.ts +30 -0
- package/dist/constants/MagicItems.d.ts.map +1 -0
- package/dist/constants/SpellSlots.d.ts +30 -0
- package/dist/constants/SpellSlots.d.ts.map +1 -0
- package/dist/constants/StatScaling.d.ts +113 -0
- package/dist/constants/StatScaling.d.ts.map +1 -0
- package/dist/core/analysis/AudioAnalyzer.d.ts +599 -0
- package/dist/core/analysis/AudioAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/ColorExtractor.d.ts +64 -0
- package/dist/core/analysis/ColorExtractor.d.ts.map +1 -0
- package/dist/core/analysis/EssentiaPitchDetector.d.ts +282 -0
- package/dist/core/analysis/EssentiaPitchDetector.d.ts.map +1 -0
- package/dist/core/analysis/LevelSerializer.d.ts +265 -0
- package/dist/core/analysis/LevelSerializer.d.ts.map +1 -0
- package/dist/core/analysis/MelodyContourAnalyzer.d.ts +283 -0
- package/dist/core/analysis/MelodyContourAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/MultiBandAnalyzer.d.ts +214 -0
- package/dist/core/analysis/MultiBandAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/MusicClassifier.d.ts +524 -0
- package/dist/core/analysis/MusicClassifier.d.ts.map +1 -0
- package/dist/core/analysis/PitchAnalyzer.d.ts +266 -0
- package/dist/core/analysis/PitchAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/PitchDetector.d.ts +251 -0
- package/dist/core/analysis/PitchDetector.d.ts.map +1 -0
- package/dist/core/analysis/SpectrumScanner.d.ts +52 -0
- package/dist/core/analysis/SpectrumScanner.d.ts.map +1 -0
- package/dist/core/analysis/beat/BeatInterpolator.d.ts +477 -0
- package/dist/core/analysis/beat/BeatInterpolator.d.ts.map +1 -0
- package/dist/core/analysis/beat/BeatMapGenerator.d.ts +170 -0
- package/dist/core/analysis/beat/BeatMapGenerator.d.ts.map +1 -0
- package/dist/core/analysis/beat/BeatStream.d.ts +316 -0
- package/dist/core/analysis/beat/BeatStream.d.ts.map +1 -0
- package/dist/core/analysis/beat/BeatSubdivider.d.ts +205 -0
- package/dist/core/analysis/beat/BeatSubdivider.d.ts.map +1 -0
- package/dist/core/analysis/beat/BeatTracker.d.ts +137 -0
- package/dist/core/analysis/beat/BeatTracker.d.ts.map +1 -0
- package/dist/core/analysis/beat/CompositeStreamGenerator.d.ts +180 -0
- package/dist/core/analysis/beat/CompositeStreamGenerator.d.ts.map +1 -0
- package/dist/core/analysis/beat/DensityAnalyzer.d.ts +246 -0
- package/dist/core/analysis/beat/DensityAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/beat/DifficultyVariantGenerator.d.ts +1082 -0
- package/dist/core/analysis/beat/DifficultyVariantGenerator.d.ts.map +1 -0
- package/dist/core/analysis/beat/GrooveAnalyzer.d.ts +192 -0
- package/dist/core/analysis/beat/GrooveAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/beat/OnsetStrengthEnvelope.d.ts +133 -0
- package/dist/core/analysis/beat/OnsetStrengthEnvelope.d.ts.map +1 -0
- package/dist/core/analysis/beat/PhraseAnalyzer.d.ts +230 -0
- package/dist/core/analysis/beat/PhraseAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/beat/RhythmQuantizer.d.ts +399 -0
- package/dist/core/analysis/beat/RhythmQuantizer.d.ts.map +1 -0
- package/dist/core/analysis/beat/RhythmicBalancer.d.ts +262 -0
- package/dist/core/analysis/beat/RhythmicBalancer.d.ts.map +1 -0
- package/dist/core/analysis/beat/StreamScorer.d.ts +275 -0
- package/dist/core/analysis/beat/StreamScorer.d.ts.map +1 -0
- package/dist/core/analysis/beat/TempoAwareQuantizer.d.ts +256 -0
- package/dist/core/analysis/beat/TempoAwareQuantizer.d.ts.map +1 -0
- package/dist/core/analysis/beat/TempoDetector.d.ts +220 -0
- package/dist/core/analysis/beat/TempoDetector.d.ts.map +1 -0
- package/dist/core/analysis/beat/TransientDetector.d.ts +303 -0
- package/dist/core/analysis/beat/TransientDetector.d.ts.map +1 -0
- package/dist/core/analysis/beat/beatKeyHelpers.d.ts +180 -0
- package/dist/core/analysis/beat/beatKeyHelpers.d.ts.map +1 -0
- package/dist/core/analysis/beat/index.d.ts +41 -0
- package/dist/core/analysis/beat/index.d.ts.map +1 -0
- package/dist/core/analysis/beat/utils/audioUtils.d.ts +204 -0
- package/dist/core/analysis/beat/utils/audioUtils.d.ts.map +1 -0
- package/dist/core/analysis/beat/utils/beatInterpolationDebug.d.ts +404 -0
- package/dist/core/analysis/beat/utils/beatInterpolationDebug.d.ts.map +1 -0
- package/dist/core/analysis/beat/utils/subdivideBeatMap.d.ts +61 -0
- package/dist/core/analysis/beat/utils/subdivideBeatMap.d.ts.map +1 -0
- package/dist/core/analysis/beat/utils/unifyBeatMap.d.ts +33 -0
- package/dist/core/analysis/beat/utils/unifyBeatMap.d.ts.map +1 -0
- package/dist/core/analysis/index.d.ts +18 -0
- package/dist/core/analysis/index.d.ts.map +1 -0
- package/dist/core/combat/AI/AICombatRunner.d.ts +108 -0
- package/dist/core/combat/AI/AICombatRunner.d.ts.map +1 -0
- package/dist/core/combat/AI/CombatAI.d.ts +179 -0
- package/dist/core/combat/AI/CombatAI.d.ts.map +1 -0
- package/dist/core/combat/AI/CombatMetricsTracker.d.ts +30 -0
- package/dist/core/combat/AI/CombatMetricsTracker.d.ts.map +1 -0
- package/dist/core/combat/Analysis/BalanceValidator.d.ts +170 -0
- package/dist/core/combat/Analysis/BalanceValidator.d.ts.map +1 -0
- package/dist/core/combat/Analysis/ComparativeAnalyzer.d.ts +231 -0
- package/dist/core/combat/Analysis/ComparativeAnalyzer.d.ts.map +1 -0
- package/dist/core/combat/Analysis/DifficultyCalculator.d.ts +203 -0
- package/dist/core/combat/Analysis/DifficultyCalculator.d.ts.map +1 -0
- package/dist/core/combat/Analysis/ParameterSweep.d.ts +201 -0
- package/dist/core/combat/Analysis/ParameterSweep.d.ts.map +1 -0
- package/dist/core/combat/AttackResolver.d.ts +220 -0
- package/dist/core/combat/AttackResolver.d.ts.map +1 -0
- package/dist/core/combat/CombatEngine.d.ts +388 -0
- package/dist/core/combat/CombatEngine.d.ts.map +1 -0
- package/dist/core/combat/DiceRoller.d.ts +115 -0
- package/dist/core/combat/DiceRoller.d.ts.map +1 -0
- package/dist/core/combat/InitiativeRoller.d.ts +62 -0
- package/dist/core/combat/InitiativeRoller.d.ts.map +1 -0
- package/dist/core/combat/PartyAnalyzer.d.ts +215 -0
- package/dist/core/combat/PartyAnalyzer.d.ts.map +1 -0
- package/dist/core/combat/SeededDiceRoller.d.ts +120 -0
- package/dist/core/combat/SeededDiceRoller.d.ts.map +1 -0
- package/dist/core/combat/Simulation/CombatSimulator.d.ts +366 -0
- package/dist/core/combat/Simulation/CombatSimulator.d.ts.map +1 -0
- package/dist/core/combat/SpellCaster.d.ts +113 -0
- package/dist/core/combat/SpellCaster.d.ts.map +1 -0
- package/dist/core/config/index.d.ts +24 -0
- package/dist/core/config/index.d.ts.map +1 -0
- package/dist/core/config/progressionConfig.d.ts +73 -0
- package/dist/core/config/progressionConfig.d.ts.map +1 -0
- package/dist/core/config/sensorConfig.d.ts +134 -0
- package/dist/core/config/sensorConfig.d.ts.map +1 -0
- package/dist/core/equipment/BoxOpener.d.ts +175 -0
- package/dist/core/equipment/BoxOpener.d.ts.map +1 -0
- package/dist/core/equipment/EquipmentEffectApplier.d.ts +189 -0
- package/dist/core/equipment/EquipmentEffectApplier.d.ts.map +1 -0
- package/dist/core/equipment/EquipmentModifier.d.ts +327 -0
- package/dist/core/equipment/EquipmentModifier.d.ts.map +1 -0
- package/dist/core/equipment/EquipmentSpawnHelper.d.ts +246 -0
- package/dist/core/equipment/EquipmentSpawnHelper.d.ts.map +1 -0
- package/dist/core/equipment/EquipmentValidator.d.ts +173 -0
- package/dist/core/equipment/EquipmentValidator.d.ts.map +1 -0
- package/dist/core/extensions/ExtensionManager.d.ts +517 -0
- package/dist/core/extensions/ExtensionManager.d.ts.map +1 -0
- package/dist/core/extensions/WeightedSelector.d.ts +156 -0
- package/dist/core/extensions/WeightedSelector.d.ts.map +1 -0
- package/dist/core/extensions/index.d.ts +11 -0
- package/dist/core/extensions/index.d.ts.map +1 -0
- package/dist/core/extensions/initializeDefaults.d.ts +170 -0
- package/dist/core/extensions/initializeDefaults.d.ts.map +1 -0
- package/dist/core/features/FeatureEffectApplier.d.ts +102 -0
- package/dist/core/features/FeatureEffectApplier.d.ts.map +1 -0
- package/dist/core/features/FeatureQuery.d.ts +368 -0
- package/dist/core/features/FeatureQuery.d.ts.map +1 -0
- package/dist/core/features/FeatureTypes.d.ts +199 -0
- package/dist/core/features/FeatureTypes.d.ts.map +1 -0
- package/dist/core/features/FeatureValidator.d.ts +149 -0
- package/dist/core/features/FeatureValidator.d.ts.map +1 -0
- package/dist/core/features/index.d.ts +12 -0
- package/dist/core/features/index.d.ts.map +1 -0
- package/dist/core/generation/AbilityScoreCalculator.d.ts +83 -0
- package/dist/core/generation/AbilityScoreCalculator.d.ts.map +1 -0
- package/dist/core/generation/AppearanceGenerator.d.ts +32 -0
- package/dist/core/generation/AppearanceGenerator.d.ts.map +1 -0
- package/dist/core/generation/BeatConverter.d.ts +127 -0
- package/dist/core/generation/BeatConverter.d.ts.map +1 -0
- package/dist/core/generation/ButtonMapper.d.ts +346 -0
- package/dist/core/generation/ButtonMapper.d.ts.map +1 -0
- package/dist/core/generation/ButtonPatternLibrary.d.ts +92 -0
- package/dist/core/generation/ButtonPatternLibrary.d.ts.map +1 -0
- package/dist/core/generation/CRLevelConverter.d.ts +242 -0
- package/dist/core/generation/CRLevelConverter.d.ts.map +1 -0
- package/dist/core/generation/CharacterGenerator.d.ts +194 -0
- package/dist/core/generation/CharacterGenerator.d.ts.map +1 -0
- package/dist/core/generation/ClassSuggester.d.ts +184 -0
- package/dist/core/generation/ClassSuggester.d.ts.map +1 -0
- package/dist/core/generation/EnemyEquipmentGenerator.d.ts +151 -0
- package/dist/core/generation/EnemyEquipmentGenerator.d.ts.map +1 -0
- package/dist/core/generation/EnemyGenerator.d.ts +595 -0
- package/dist/core/generation/EnemyGenerator.d.ts.map +1 -0
- package/dist/core/generation/EquipmentGenerator.d.ts +204 -0
- package/dist/core/generation/EquipmentGenerator.d.ts.map +1 -0
- package/dist/core/generation/LegendaryGenerator.d.ts +213 -0
- package/dist/core/generation/LegendaryGenerator.d.ts.map +1 -0
- package/dist/core/generation/LevelGenerator.d.ts +390 -0
- package/dist/core/generation/LevelGenerator.d.ts.map +1 -0
- package/dist/core/generation/NamingEngine.d.ts +136 -0
- package/dist/core/generation/NamingEngine.d.ts.map +1 -0
- package/dist/core/generation/PitchBeatLinker.d.ts +150 -0
- package/dist/core/generation/PitchBeatLinker.d.ts.map +1 -0
- package/dist/core/generation/RaceSelector.d.ts +58 -0
- package/dist/core/generation/RaceSelector.d.ts.map +1 -0
- package/dist/core/generation/RhythmGenerator.d.ts +597 -0
- package/dist/core/generation/RhythmGenerator.d.ts.map +1 -0
- package/dist/core/generation/SkillAssigner.d.ts +78 -0
- package/dist/core/generation/SkillAssigner.d.ts.map +1 -0
- package/dist/core/generation/SpellManager.d.ts +132 -0
- package/dist/core/generation/SpellManager.d.ts.map +1 -0
- package/dist/core/generation/SpellcastingGenerator.d.ts +255 -0
- package/dist/core/generation/SpellcastingGenerator.d.ts.map +1 -0
- package/dist/core/generation/index.d.ts +41 -0
- package/dist/core/generation/index.d.ts.map +1 -0
- package/dist/core/parser/MetadataExtractor.d.ts +66 -0
- package/dist/core/parser/MetadataExtractor.d.ts.map +1 -0
- package/dist/core/parser/PlaylistParser.d.ts +45 -0
- package/dist/core/parser/PlaylistParser.d.ts.map +1 -0
- package/dist/core/playback/SubdivisionPlaybackController.d.ts +333 -0
- package/dist/core/playback/SubdivisionPlaybackController.d.ts.map +1 -0
- package/dist/core/playback/index.d.ts +5 -0
- package/dist/core/playback/index.d.ts.map +1 -0
- package/dist/core/progression/CharacterUpdater.d.ts +203 -0
- package/dist/core/progression/CharacterUpdater.d.ts.map +1 -0
- package/dist/core/progression/LevelUpProcessor.d.ts +234 -0
- package/dist/core/progression/LevelUpProcessor.d.ts.map +1 -0
- package/dist/core/progression/PrestigeSystem.d.ts +217 -0
- package/dist/core/progression/PrestigeSystem.d.ts.map +1 -0
- package/dist/core/progression/RhythmXPCalculator.d.ts +182 -0
- package/dist/core/progression/RhythmXPCalculator.d.ts.map +1 -0
- package/dist/core/progression/SessionTracker.d.ts +169 -0
- package/dist/core/progression/SessionTracker.d.ts.map +1 -0
- package/dist/core/progression/XPCalculator.d.ts +128 -0
- package/dist/core/progression/XPCalculator.d.ts.map +1 -0
- package/dist/core/progression/stat/StatIncreaseStrategy.d.ts +97 -0
- package/dist/core/progression/stat/StatIncreaseStrategy.d.ts.map +1 -0
- package/dist/core/progression/stat/StatManager.d.ts +179 -0
- package/dist/core/progression/stat/StatManager.d.ts.map +1 -0
- package/dist/core/sensors/EnvironmentalSensors.d.ts +301 -0
- package/dist/core/sensors/EnvironmentalSensors.d.ts.map +1 -0
- package/dist/core/sensors/GamingPlatformSensors.d.ts +162 -0
- package/dist/core/sensors/GamingPlatformSensors.d.ts.map +1 -0
- package/dist/core/sensors/GeolocationProvider.d.ts +156 -0
- package/dist/core/sensors/GeolocationProvider.d.ts.map +1 -0
- package/dist/core/sensors/MotionDetector.d.ts +58 -0
- package/dist/core/sensors/MotionDetector.d.ts.map +1 -0
- package/dist/core/sensors/SteamAPIClient.d.ts +108 -0
- package/dist/core/sensors/SteamAPIClient.d.ts.map +1 -0
- package/dist/core/sensors/WeatherAPIClient.d.ts +360 -0
- package/dist/core/sensors/WeatherAPIClient.d.ts.map +1 -0
- package/dist/core/sensors/schemas/weather.schema.d.ts +144 -0
- package/dist/core/sensors/schemas/weather.schema.d.ts.map +1 -0
- package/dist/core/skills/SkillQuery.d.ts +159 -0
- package/dist/core/skills/SkillQuery.d.ts.map +1 -0
- package/dist/core/skills/SkillTypes.d.ts +233 -0
- package/dist/core/skills/SkillTypes.d.ts.map +1 -0
- package/dist/core/skills/SkillValidator.d.ts +146 -0
- package/dist/core/skills/SkillValidator.d.ts.map +1 -0
- package/dist/core/skills/index.d.ts +11 -0
- package/dist/core/skills/index.d.ts.map +1 -0
- package/dist/core/spells/SpellQuery.d.ts +194 -0
- package/dist/core/spells/SpellQuery.d.ts.map +1 -0
- package/dist/core/spells/SpellTypes.d.ts +71 -0
- package/dist/core/spells/SpellTypes.d.ts.map +1 -0
- package/dist/core/spells/SpellValidator.d.ts +129 -0
- package/dist/core/spells/SpellValidator.d.ts.map +1 -0
- package/dist/core/spells/index.d.ts +11 -0
- package/dist/core/spells/index.d.ts.map +1 -0
- package/dist/core/types/AudioProfile.d.ts +143 -0
- package/dist/core/types/AudioProfile.d.ts.map +1 -0
- package/dist/core/types/BeatMap.d.ts +1825 -0
- package/dist/core/types/BeatMap.d.ts.map +1 -0
- package/dist/core/types/ButtonMapping.d.ts +345 -0
- package/dist/core/types/ButtonMapping.d.ts.map +1 -0
- package/dist/core/types/Character.d.ts +397 -0
- package/dist/core/types/Character.d.ts.map +1 -0
- package/dist/core/types/ChartedBeatMap.d.ts +169 -0
- package/dist/core/types/ChartedBeatMap.d.ts.map +1 -0
- package/dist/core/types/Combat.d.ts +268 -0
- package/dist/core/types/Combat.d.ts.map +1 -0
- package/dist/core/types/CombatAI.d.ts +143 -0
- package/dist/core/types/CombatAI.d.ts.map +1 -0
- package/dist/core/types/Enemy.d.ts +447 -0
- package/dist/core/types/Enemy.d.ts.map +1 -0
- package/dist/core/types/Environmental.d.ts +213 -0
- package/dist/core/types/Environmental.d.ts.map +1 -0
- package/dist/core/types/Equipment.d.ts +309 -0
- package/dist/core/types/Equipment.d.ts.map +1 -0
- package/dist/core/types/ISessionTracker.d.ts +48 -0
- package/dist/core/types/ISessionTracker.d.ts.map +1 -0
- package/dist/core/types/LevelExport.d.ts +366 -0
- package/dist/core/types/LevelExport.d.ts.map +1 -0
- package/dist/core/types/Playlist.d.ts +70 -0
- package/dist/core/types/Playlist.d.ts.map +1 -0
- package/dist/core/types/Prestige.d.ts +94 -0
- package/dist/core/types/Prestige.d.ts.map +1 -0
- package/dist/core/types/Progression.d.ts +214 -0
- package/dist/core/types/Progression.d.ts.map +1 -0
- package/dist/core/types/RhythmXP.d.ts +398 -0
- package/dist/core/types/RhythmXP.d.ts.map +1 -0
- package/dist/core/utils/AbilityConstants.d.ts +31 -0
- package/dist/core/utils/AbilityConstants.d.ts.map +1 -0
- package/dist/core/utils/EffectApplierUtils.d.ts +56 -0
- package/dist/core/utils/EffectApplierUtils.d.ts.map +1 -0
- package/dist/core/utils/ImageValidator.d.ts +66 -0
- package/dist/core/utils/ImageValidator.d.ts.map +1 -0
- package/dist/core/utils/PrerequisiteValidator.d.ts +88 -0
- package/dist/core/utils/PrerequisiteValidator.d.ts.map +1 -0
- package/dist/essentia-wasm.es-BUEnKUts.js +2990 -0
- package/dist/essentia.js-model.es-CGA0xotH.js +306 -0
- package/dist/index.d.ts +176 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/playlist-data-engine.js +124 -0
- package/dist/playlist-data-engine.mjs +49251 -0
- package/dist/utils/EnchantmentLibrary.d.ts +378 -0
- package/dist/utils/EnchantmentLibrary.d.ts.map +1 -0
- package/dist/utils/arweaveGatewayManager.d.ts +485 -0
- package/dist/utils/arweaveGatewayManager.d.ts.map +1 -0
- package/dist/utils/arweaveUtils.d.ts +118 -0
- package/dist/utils/arweaveUtils.d.ts.map +1 -0
- package/dist/utils/constants.d.ts +439 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/equipmentConstants.d.ts +60 -0
- package/dist/utils/equipmentConstants.d.ts.map +1 -0
- package/dist/utils/hash.d.ts +33 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +192 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/magicItemExamples.d.ts +46 -0
- package/dist/utils/magicItemExamples.d.ts.map +1 -0
- package/dist/utils/playlistUtils.d.ts +149 -0
- package/dist/utils/playlistUtils.d.ts.map +1 -0
- package/dist/utils/random.d.ts +34 -0
- package/dist/utils/random.d.ts.map +1 -0
- package/dist/utils/sensorDashboard.d.ts +60 -0
- package/dist/utils/sensorDashboard.d.ts.map +1 -0
- package/dist/utils/validators.d.ts +189 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/vite.svg +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arweave Gateway Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages gateway fallback for Arweave URLs. When a file fails to load on one gateway,
|
|
5
|
+
* automatically tries alternate gateways. Uses in-memory caching to remember working
|
|
6
|
+
* gateways for each transaction ID.
|
|
7
|
+
*
|
|
8
|
+
* Design decisions:
|
|
9
|
+
* - Parallel gateway checking (race all gateways + Wayfinder, first to respond wins)
|
|
10
|
+
* - localStorage persistence for active gateway across sessions
|
|
11
|
+
* - 5 second timeout per gateway check
|
|
12
|
+
* - 2 hour cache TTL
|
|
13
|
+
* - Active gateway is reused without HEAD checks; only real fetch failures trigger fallback
|
|
14
|
+
*
|
|
15
|
+
* @module utils/arweaveGatewayManager
|
|
16
|
+
*/
|
|
17
|
+
import type { GatewayConfig } from './arweaveUtils.js';
|
|
18
|
+
/**
|
|
19
|
+
* Configuration for the gateway cache entry
|
|
20
|
+
*/
|
|
21
|
+
export interface GatewayCache {
|
|
22
|
+
/** The 43-character Arweave transaction ID */
|
|
23
|
+
txId: string;
|
|
24
|
+
/** The gateway that was found to work for this txId */
|
|
25
|
+
workingGateway: GatewayConfig;
|
|
26
|
+
/** Timestamp when this cache entry was created (ms since epoch) */
|
|
27
|
+
timestamp: number;
|
|
28
|
+
/** Time-to-live in milliseconds */
|
|
29
|
+
ttl: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Result of a gateway URL resolution
|
|
33
|
+
*/
|
|
34
|
+
export interface GatewayCheckResult {
|
|
35
|
+
/** The working URL that can be used to fetch the resource */
|
|
36
|
+
workingUrl: string;
|
|
37
|
+
/** The gateway that provided the working URL */
|
|
38
|
+
gateway: GatewayConfig;
|
|
39
|
+
/** Whether this result came from cache */
|
|
40
|
+
cached: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Configuration options for ArweaveGatewayManager
|
|
44
|
+
*/
|
|
45
|
+
export interface ArweaveGatewayManagerConfig {
|
|
46
|
+
/** List of gateways to try in priority order */
|
|
47
|
+
gateways?: GatewayConfig[];
|
|
48
|
+
/** Timeout for each gateway check in milliseconds (default: 5000) */
|
|
49
|
+
timeout?: number;
|
|
50
|
+
/** Cache TTL in milliseconds (default: 7200000 = 2 hours) */
|
|
51
|
+
cacheTTL?: number;
|
|
52
|
+
/** Threshold in ms above which a fetch is considered "slow" (default: 8000) */
|
|
53
|
+
slowResponseThreshold?: number;
|
|
54
|
+
/** Number of consecutive slow responses before proactive gateway rotation (default: 3) */
|
|
55
|
+
maxSlowResponses?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Options for prefetching URLs
|
|
59
|
+
*/
|
|
60
|
+
export interface PrefetchOptions {
|
|
61
|
+
/** Maximum number of concurrent gateway checks (default: 5) */
|
|
62
|
+
concurrency?: number;
|
|
63
|
+
/** Whether to continue on errors (default: true) */
|
|
64
|
+
continueOnError?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Result of prefetching a single URL
|
|
68
|
+
*/
|
|
69
|
+
export interface PrefetchResultEntry {
|
|
70
|
+
/** The original URL that was prefetched */
|
|
71
|
+
url: string;
|
|
72
|
+
/** The transaction ID extracted from the URL */
|
|
73
|
+
txId: string;
|
|
74
|
+
/** Whether the prefetch succeeded */
|
|
75
|
+
success: boolean;
|
|
76
|
+
/** The working gateway (if successful) */
|
|
77
|
+
gateway?: GatewayConfig;
|
|
78
|
+
/** Error message (if failed) */
|
|
79
|
+
error?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Result of prefetching multiple URLs
|
|
83
|
+
*/
|
|
84
|
+
export interface PrefetchResult {
|
|
85
|
+
/** Total number of URLs processed */
|
|
86
|
+
total: number;
|
|
87
|
+
/** Number of successful prefetches */
|
|
88
|
+
succeeded: number;
|
|
89
|
+
/** Number of failed prefetches */
|
|
90
|
+
failed: number;
|
|
91
|
+
/** Number of URLs skipped (not Arweave URLs) */
|
|
92
|
+
skipped: number;
|
|
93
|
+
/** Detailed results for each URL */
|
|
94
|
+
entries: PrefetchResultEntry[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Statistics about the gateway cache
|
|
98
|
+
*/
|
|
99
|
+
export interface CacheStats {
|
|
100
|
+
/** Number of entries in the cache */
|
|
101
|
+
size: number;
|
|
102
|
+
/** List of cached transaction IDs */
|
|
103
|
+
txIds: string[];
|
|
104
|
+
/** Cache hit count (since last clear) */
|
|
105
|
+
hitCount: number;
|
|
106
|
+
/** Cache miss count (since last clear) */
|
|
107
|
+
missCount: number;
|
|
108
|
+
/** Cache TTL in milliseconds */
|
|
109
|
+
ttl: number;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Health statistics for a single gateway
|
|
113
|
+
*/
|
|
114
|
+
export interface GatewayHealthStats {
|
|
115
|
+
/** Gateway hostname */
|
|
116
|
+
host: string;
|
|
117
|
+
/** Current priority (lower = higher priority) */
|
|
118
|
+
priority: number;
|
|
119
|
+
/** Original priority from configuration */
|
|
120
|
+
originalPriority: number;
|
|
121
|
+
/** Number of successful checks */
|
|
122
|
+
successCount: number;
|
|
123
|
+
/** Number of failed checks */
|
|
124
|
+
failureCount: number;
|
|
125
|
+
/** Total number of checks */
|
|
126
|
+
totalChecks: number;
|
|
127
|
+
/** Success rate (0-1) */
|
|
128
|
+
successRate: number;
|
|
129
|
+
/** Average response time in milliseconds */
|
|
130
|
+
averageResponseTime: number;
|
|
131
|
+
/** Last successful check timestamp (ms since epoch) */
|
|
132
|
+
lastSuccess: number | null;
|
|
133
|
+
/** Last failure timestamp (ms since epoch) */
|
|
134
|
+
lastFailure: number | null;
|
|
135
|
+
/** Whether the gateway is currently considered healthy */
|
|
136
|
+
isHealthy: boolean;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Result of running a health check on all gateways
|
|
140
|
+
*/
|
|
141
|
+
export interface HealthCheckResult {
|
|
142
|
+
/** Timestamp when the health check was performed */
|
|
143
|
+
timestamp: number;
|
|
144
|
+
/** Health stats for each gateway */
|
|
145
|
+
gateways: GatewayHealthStats[];
|
|
146
|
+
/** List of healthy gateway hosts */
|
|
147
|
+
healthyGateways: string[];
|
|
148
|
+
/** List of unhealthy gateway hosts */
|
|
149
|
+
unhealthyGateways: string[];
|
|
150
|
+
/** Gateway with the best response time (if any) */
|
|
151
|
+
fastestGateway: string | null;
|
|
152
|
+
/** Total time taken for the health check in ms */
|
|
153
|
+
totalTime: number;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Options for running a health check
|
|
157
|
+
*/
|
|
158
|
+
export interface HealthCheckOptions {
|
|
159
|
+
/** Transaction ID to use for health check (default: a well-known stable txId) */
|
|
160
|
+
txId?: string;
|
|
161
|
+
/** Whether to adjust priorities based on results (default: false) */
|
|
162
|
+
adjustPriorities?: boolean;
|
|
163
|
+
/** Minimum number of checks before considering adjusting priorities (default: 3) */
|
|
164
|
+
minChecksForAdjustment?: number;
|
|
165
|
+
/** Threshold for considering a gateway healthy (success rate, default: 0.5) */
|
|
166
|
+
healthyThreshold?: number;
|
|
167
|
+
/** Maximum response time to consider a gateway "fast" in ms (default: 2000) */
|
|
168
|
+
fastThreshold?: number;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* ArweaveGatewayManager class
|
|
172
|
+
*
|
|
173
|
+
* Manages gateway fallback for Arweave URLs with caching support.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* import { arweaveGatewayManager } from 'playlist-data-engine';
|
|
178
|
+
*
|
|
179
|
+
* // Resolve an Arweave URL to a working gateway
|
|
180
|
+
* const workingUrl = await arweaveGatewayManager.resolveUrl('https://arweave.net/abc123...');
|
|
181
|
+
* // Returns working URL from first responding gateway
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export declare class ArweaveGatewayManager {
|
|
185
|
+
private gateways;
|
|
186
|
+
private timeout;
|
|
187
|
+
private cacheTTL;
|
|
188
|
+
private cache;
|
|
189
|
+
private logger;
|
|
190
|
+
/** Cache hit counter for statistics */
|
|
191
|
+
private hitCount;
|
|
192
|
+
/** Cache miss counter for statistics */
|
|
193
|
+
private missCount;
|
|
194
|
+
/** Health tracking data for each gateway (keyed by host) */
|
|
195
|
+
private healthData;
|
|
196
|
+
/** Original gateway priorities (for potential reset) */
|
|
197
|
+
private originalPriorities;
|
|
198
|
+
/** Maximum number of response time records to keep per gateway */
|
|
199
|
+
private readonly MAX_HEALTH_RECORDS;
|
|
200
|
+
/** AR.IO Wayfinder client for dynamic routing */
|
|
201
|
+
private wayfinder;
|
|
202
|
+
/** The currently active dynamic gateway. Used globally to prevent constant switching. */
|
|
203
|
+
private activeGateway;
|
|
204
|
+
/** Time of the most recent successful resolve/fetch for the active gateway (ms) */
|
|
205
|
+
private lastFetchTiming;
|
|
206
|
+
/** Number of consecutive slow fetch responses from the active gateway */
|
|
207
|
+
private consecutiveSlowResponses;
|
|
208
|
+
/** Threshold in ms above which a fetch is considered "slow" (default: 8000) */
|
|
209
|
+
private readonly slowResponseThreshold;
|
|
210
|
+
/** Number of consecutive slow responses before proactive gateway rotation (default: 3) */
|
|
211
|
+
private readonly maxSlowResponses;
|
|
212
|
+
constructor(config?: ArweaveGatewayManagerConfig);
|
|
213
|
+
/**
|
|
214
|
+
* Resolve an Arweave URL to a working gateway URL
|
|
215
|
+
*
|
|
216
|
+
* If the URL is not an Arweave URL, returns it unchanged.
|
|
217
|
+
* If cached, returns the cached working URL.
|
|
218
|
+
* Otherwise, tries each gateway in priority order until one works.
|
|
219
|
+
* If all gateways fail, returns the original URL.
|
|
220
|
+
*
|
|
221
|
+
* @param url - The URL to resolve
|
|
222
|
+
* @returns A working URL (or original URL if all gateways fail)
|
|
223
|
+
*/
|
|
224
|
+
resolveUrlOld(url: string): Promise<string>;
|
|
225
|
+
/**
|
|
226
|
+
* Wrap a promise with a timeout to prevent hanging indefinitely.
|
|
227
|
+
* Useful for third-party calls (e.g., Wayfinder) that have no built-in timeout.
|
|
228
|
+
*/
|
|
229
|
+
private withTimeout;
|
|
230
|
+
/**
|
|
231
|
+
* Resolve an Arweave URL to a working gateway URL.
|
|
232
|
+
*
|
|
233
|
+
* Strategy: try static gateways first with real fetch checks (not HEAD),
|
|
234
|
+
* fall back to Wayfinder only if all static gateways fail.
|
|
235
|
+
*
|
|
236
|
+
* @param url - The URL to resolve
|
|
237
|
+
* @param signal - Optional AbortSignal to cancel in-flight gateway checks
|
|
238
|
+
* @returns A working URL (or original URL if all gateways fail or signal is aborted)
|
|
239
|
+
*/
|
|
240
|
+
resolveUrl(url: string, signal?: AbortSignal): Promise<string>;
|
|
241
|
+
/**
|
|
242
|
+
* Report that the active gateway failed a real fetch.
|
|
243
|
+
*
|
|
244
|
+
* Call this when the URL returned by resolveUrl() actually fails to load
|
|
245
|
+
* (e.g. fetch() returns a 4xx/5xx or throws). This clears the active gateway
|
|
246
|
+
* and finds a new one, persisting the result to localStorage.
|
|
247
|
+
*
|
|
248
|
+
* When reason is 'user-cancel-fast', the active gateway is preserved since
|
|
249
|
+
* the user intentionally cancelled and the gateway is likely fine.
|
|
250
|
+
*
|
|
251
|
+
* @param url - The URL that failed
|
|
252
|
+
* @param options - Optional signal for cancellation and reason to distinguish failure types
|
|
253
|
+
* @returns A new working URL (or original if all gateways fail or user cancelled quickly)
|
|
254
|
+
*/
|
|
255
|
+
reportGatewayFailure(url: string, options?: {
|
|
256
|
+
signal?: AbortSignal;
|
|
257
|
+
reason?: 'load-error' | 'user-cancel-slow' | 'user-cancel-fast';
|
|
258
|
+
excludeHost?: string;
|
|
259
|
+
}): Promise<string>;
|
|
260
|
+
/**
|
|
261
|
+
* Report that a fetch succeeded with timing data.
|
|
262
|
+
*
|
|
263
|
+
* Callers invoke this after a successful fetch to feed timing data back to the manager.
|
|
264
|
+
* If the fetch was fast, the consecutive slow counter resets. If slow, it increments
|
|
265
|
+
* and may trigger proactive gateway rotation on the next resolveUrl() call.
|
|
266
|
+
*
|
|
267
|
+
* @param timingMs - The time the fetch took in milliseconds
|
|
268
|
+
*/
|
|
269
|
+
reportFetchSuccess(timingMs: number): void;
|
|
270
|
+
/**
|
|
271
|
+
* Check a single gateway and set it as active if it works.
|
|
272
|
+
* Returns the working URL, or null if the check failed.
|
|
273
|
+
*/
|
|
274
|
+
private checkAndSetGateway;
|
|
275
|
+
/**
|
|
276
|
+
* Try remaining fallback gateways (everything except arweave.net).
|
|
277
|
+
* Returns the URL of the first gateway that responds, or null if all fail.
|
|
278
|
+
*/
|
|
279
|
+
private tryFallbackGateways;
|
|
280
|
+
/**
|
|
281
|
+
* Try Wayfinder as a last resort when all static gateways fail.
|
|
282
|
+
* Returns the URL of a working Wayfinder-selected gateway, or null if it fails.
|
|
283
|
+
*/
|
|
284
|
+
private tryWayfinder;
|
|
285
|
+
/**
|
|
286
|
+
* Set the active gateway, cache it for the txId, and persist to localStorage.
|
|
287
|
+
*/
|
|
288
|
+
private setActiveGateway;
|
|
289
|
+
/**
|
|
290
|
+
* Load the persisted active gateway from localStorage.
|
|
291
|
+
*/
|
|
292
|
+
private loadPersistedGateway;
|
|
293
|
+
/**
|
|
294
|
+
* Persist the active gateway to localStorage.
|
|
295
|
+
*/
|
|
296
|
+
private persistGateway;
|
|
297
|
+
/**
|
|
298
|
+
* Clear the persisted gateway from localStorage.
|
|
299
|
+
*/
|
|
300
|
+
private clearPersistedGateway;
|
|
301
|
+
/**
|
|
302
|
+
* Check if a gateway can serve a transaction
|
|
303
|
+
*
|
|
304
|
+
* Uses a HEAD request with timeout to check if the gateway responds.
|
|
305
|
+
* Handles CORS errors gracefully (treats as failure, not exception).
|
|
306
|
+
*
|
|
307
|
+
* @param txId - The transaction ID to check
|
|
308
|
+
* @param gateway - The gateway to check
|
|
309
|
+
* @param pathSuffix - Optional path suffix to append after txId
|
|
310
|
+
* @param signal - Optional external AbortSignal to cancel the check
|
|
311
|
+
* @returns true if the gateway can serve the transaction
|
|
312
|
+
*/
|
|
313
|
+
checkGateway(txId: string, gateway: GatewayConfig, pathSuffix?: string, signal?: AbortSignal): Promise<boolean>;
|
|
314
|
+
/**
|
|
315
|
+
* Get the cached working gateway for a transaction ID
|
|
316
|
+
*
|
|
317
|
+
* @param txId - The transaction ID to look up
|
|
318
|
+
* @returns The cached gateway config, or null if not cached or expired
|
|
319
|
+
*/
|
|
320
|
+
getCachedGateway(txId: string): GatewayConfig | null;
|
|
321
|
+
/**
|
|
322
|
+
* Cache a working gateway for a transaction ID
|
|
323
|
+
*
|
|
324
|
+
* @param txId - The transaction ID
|
|
325
|
+
* @param gateway - The working gateway to cache
|
|
326
|
+
*/
|
|
327
|
+
setCache(txId: string, gateway: GatewayConfig): void;
|
|
328
|
+
/**
|
|
329
|
+
* Clear all cached gateway entries
|
|
330
|
+
*/
|
|
331
|
+
clearCache(): void;
|
|
332
|
+
/**
|
|
333
|
+
* Prefetch and cache gateways for multiple URLs in parallel
|
|
334
|
+
*
|
|
335
|
+
* This is useful for warming up the cache at app startup with known model URLs.
|
|
336
|
+
* URLs are resolved in parallel with configurable concurrency.
|
|
337
|
+
*
|
|
338
|
+
* @param urls - Array of URLs to prefetch (non-Arweave URLs are skipped)
|
|
339
|
+
* @param options - Prefetch options
|
|
340
|
+
* @returns Result summary with success/failure counts and details
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```ts
|
|
344
|
+
* const result = await arweaveGatewayManager.prefetchUrls([
|
|
345
|
+
* 'https://arweave.net/abc123.../model.json',
|
|
346
|
+
* 'https://arweave.net/def456.../model.json',
|
|
347
|
+
* ]);
|
|
348
|
+
* console.log(`Prefetched ${result.succeeded}/${result.total} URLs`);
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
prefetchUrls(urls: string[], options?: PrefetchOptions): Promise<PrefetchResult>;
|
|
352
|
+
/**
|
|
353
|
+
* Get statistics about the gateway cache
|
|
354
|
+
*
|
|
355
|
+
* @returns Cache statistics including size, entries, and hit/miss counts
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* ```ts
|
|
359
|
+
* const stats = arweaveGatewayManager.getCacheStats();
|
|
360
|
+
* console.log(`Cache has ${stats.size} entries, hit rate: ${stats.hitCount / (stats.hitCount + stats.missCount)}`);
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
getCacheStats(): CacheStats;
|
|
364
|
+
/**
|
|
365
|
+
* Get all cached gateway entries (for debugging)
|
|
366
|
+
*
|
|
367
|
+
* @returns Array of all cache entries (including expired ones)
|
|
368
|
+
*/
|
|
369
|
+
getCacheEntries(): GatewayCache[];
|
|
370
|
+
/**
|
|
371
|
+
* Check if a cache entry is still valid
|
|
372
|
+
*
|
|
373
|
+
* @param cache - The cache entry to check
|
|
374
|
+
* @returns true if the entry is still within its TTL
|
|
375
|
+
*/
|
|
376
|
+
private isCacheValid;
|
|
377
|
+
/**
|
|
378
|
+
* Get the average response time for a gateway from health data.
|
|
379
|
+
* Returns 0 if no records exist (indicates no history).
|
|
380
|
+
*
|
|
381
|
+
* @param host - Gateway hostname
|
|
382
|
+
* @returns Average response time in ms, or 0 if no data
|
|
383
|
+
*/
|
|
384
|
+
/**
|
|
385
|
+
* Get the failure rate for a gateway based on health data.
|
|
386
|
+
*
|
|
387
|
+
* @param host - Gateway hostname
|
|
388
|
+
* @returns Object with failure rate (0-1) and total check count
|
|
389
|
+
*/
|
|
390
|
+
private getFailureRate;
|
|
391
|
+
private getAverageResponseTime;
|
|
392
|
+
/**
|
|
393
|
+
* Record a gateway response for health tracking
|
|
394
|
+
*
|
|
395
|
+
* @param host - Gateway hostname
|
|
396
|
+
* @param responseTime - Response time in milliseconds
|
|
397
|
+
* @param success - Whether the check was successful
|
|
398
|
+
*/
|
|
399
|
+
private recordGatewayResponse;
|
|
400
|
+
/**
|
|
401
|
+
* Report real fetch timing data for a gateway.
|
|
402
|
+
*
|
|
403
|
+
* Callers invoke this after an actual data-transfer fetch (not just a HEAD check)
|
|
404
|
+
* to feed real performance data into health tracking. This is separate from the
|
|
405
|
+
* HEAD-based timing recorded by checkGateway(), and gives a more accurate picture
|
|
406
|
+
* of actual download performance.
|
|
407
|
+
*
|
|
408
|
+
* @param host - Gateway hostname that served the fetch
|
|
409
|
+
* @param timingMs - Time the full fetch took in milliseconds
|
|
410
|
+
* @param success - Whether the fetch succeeded
|
|
411
|
+
*/
|
|
412
|
+
reportFetchTiming(host: string, timingMs: number, success: boolean): void;
|
|
413
|
+
/**
|
|
414
|
+
* Get health statistics for a specific gateway
|
|
415
|
+
*
|
|
416
|
+
* @param host - Gateway hostname
|
|
417
|
+
* @returns Health statistics for the gateway, or undefined if not tracked
|
|
418
|
+
*/
|
|
419
|
+
getGatewayHealth(host: string): GatewayHealthStats | undefined;
|
|
420
|
+
/**
|
|
421
|
+
* Get health statistics for all gateways
|
|
422
|
+
*
|
|
423
|
+
* @returns Array of health statistics for each gateway
|
|
424
|
+
*/
|
|
425
|
+
getAllGatewayHealth(): GatewayHealthStats[];
|
|
426
|
+
/**
|
|
427
|
+
* Adjust gateway priorities based on health data
|
|
428
|
+
*
|
|
429
|
+
* This method reorders gateways based on:
|
|
430
|
+
* 1. Health status (healthy gateways first)
|
|
431
|
+
* 2. Average response time (faster gateways first among healthy)
|
|
432
|
+
* 3. Success rate (higher success rate first)
|
|
433
|
+
*
|
|
434
|
+
* @param options - Options for priority adjustment
|
|
435
|
+
* @returns The new gateway order after adjustment
|
|
436
|
+
*/
|
|
437
|
+
adjustGatewayPriorities(options?: {
|
|
438
|
+
/** Minimum number of checks required before adjusting (default: 3) */
|
|
439
|
+
minChecks?: number;
|
|
440
|
+
/** Threshold for considering a gateway healthy (default: 0.5) */
|
|
441
|
+
healthyThreshold?: number;
|
|
442
|
+
}): GatewayConfig[];
|
|
443
|
+
/**
|
|
444
|
+
* Run a health check on all gateways
|
|
445
|
+
*
|
|
446
|
+
* Tests each gateway by making a HEAD request to a known transaction.
|
|
447
|
+
* Optionally adjusts priorities based on results.
|
|
448
|
+
*
|
|
449
|
+
* @param options - Health check options
|
|
450
|
+
* @returns Health check results
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```ts
|
|
454
|
+
* const result = await arweaveGatewayManager.runHealthCheck({
|
|
455
|
+
* adjustPriorities: true,
|
|
456
|
+
* });
|
|
457
|
+
* console.log(`Fastest gateway: ${result.fastestGateway}`);
|
|
458
|
+
* console.log(`Healthy gateways: ${result.healthyGateways.join(', ')}`);
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
runHealthCheck(options?: HealthCheckOptions): Promise<HealthCheckResult>;
|
|
462
|
+
/**
|
|
463
|
+
* Reset gateway priorities to their original values
|
|
464
|
+
*/
|
|
465
|
+
resetGatewayPriorities(): void;
|
|
466
|
+
/**
|
|
467
|
+
* Clear all health tracking data
|
|
468
|
+
*/
|
|
469
|
+
clearHealthData(): void;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Singleton instance of ArweaveGatewayManager
|
|
473
|
+
*
|
|
474
|
+
* Uses default configuration. For custom configuration, create a new instance.
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```ts
|
|
478
|
+
* import { arweaveGatewayManager } from 'playlist-data-engine';
|
|
479
|
+
*
|
|
480
|
+
* // Use the singleton
|
|
481
|
+
* const url = await arweaveGatewayManager.resolveUrl('https://arweave.net/abc...');
|
|
482
|
+
* ```
|
|
483
|
+
*/
|
|
484
|
+
export declare const arweaveGatewayManager: ArweaveGatewayManager;
|
|
485
|
+
//# sourceMappingURL=arweaveGatewayManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arweaveGatewayManager.d.ts","sourceRoot":"","sources":["../../src/utils/arweaveGatewayManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arweave URL Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for parsing and constructing Arweave gateway URLs.
|
|
5
|
+
* Supports multiple gateways for fallback functionality.
|
|
6
|
+
*
|
|
7
|
+
* @module utils/arweaveUtils
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for an Arweave gateway
|
|
11
|
+
*/
|
|
12
|
+
export interface GatewayConfig {
|
|
13
|
+
/** Gateway hostname (e.g., 'arweave.net') */
|
|
14
|
+
host: string;
|
|
15
|
+
/** Protocol to use (default: 'https') */
|
|
16
|
+
protocol: 'http' | 'https';
|
|
17
|
+
/** Priority order for gateway selection (lower = higher priority) */
|
|
18
|
+
priority: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parsed information from an Arweave URL
|
|
22
|
+
*/
|
|
23
|
+
export interface ArweaveUrlInfo {
|
|
24
|
+
/** The 43-character Arweave transaction ID */
|
|
25
|
+
txId: string;
|
|
26
|
+
/** The original URL that was parsed */
|
|
27
|
+
originalUrl: string;
|
|
28
|
+
/** Additional path after the txId (e.g., '/model.json', '/image.png') */
|
|
29
|
+
pathSuffix: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Default gateway configurations in priority order
|
|
33
|
+
*/
|
|
34
|
+
export declare const DEFAULT_GATEWAYS: GatewayConfig[];
|
|
35
|
+
/**
|
|
36
|
+
* Known Arweave gateway hosts for URL detection
|
|
37
|
+
*/
|
|
38
|
+
export declare const KNOWN_GATEWAY_HOSTS: readonly ["arweave.net", "ar.io", "ardrive.net", "turbo-gateway.com"];
|
|
39
|
+
/**
|
|
40
|
+
* Check if a URL is an Arweave URL
|
|
41
|
+
*
|
|
42
|
+
* Detects:
|
|
43
|
+
* - `ar://` protocol URLs
|
|
44
|
+
* - URLs containing known Arweave gateway hosts
|
|
45
|
+
*
|
|
46
|
+
* @param url - The URL to check
|
|
47
|
+
* @returns True if the URL is an Arweave URL
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* isArweaveUrl('ar://abc123...'); // true
|
|
52
|
+
* isArweaveUrl('https://arweave.net/abc123...'); // true
|
|
53
|
+
* isArweaveUrl('https://example.com/audio.mp3'); // false
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function isArweaveUrl(url: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Parse an Arweave URL to extract transaction ID and any path suffix
|
|
59
|
+
*
|
|
60
|
+
* Handles both formats:
|
|
61
|
+
* - `ar://{txId}` - Native Arweave protocol
|
|
62
|
+
* - `ar://{txId}/path/to/file` - Native protocol with path suffix
|
|
63
|
+
* - `https://arweave.net/{txId}` - HTTP gateway URL
|
|
64
|
+
* - `https://arweave.net/{txId}/path/to/file` - HTTP gateway with path suffix
|
|
65
|
+
*
|
|
66
|
+
* @param url - The Arweave URL to parse
|
|
67
|
+
* @returns Parsed URL info or null if not a valid Arweave URL
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* parseArweaveUrl('ar://abc123...');
|
|
72
|
+
* // { txId: 'abc123...', originalUrl: 'ar://abc123...', pathSuffix: '' }
|
|
73
|
+
*
|
|
74
|
+
* parseArweaveUrl('https://arweave.net/abc123.../model.json');
|
|
75
|
+
* // { txId: 'abc123...', originalUrl: '...', pathSuffix: '/model.json' }
|
|
76
|
+
*
|
|
77
|
+
* parseArweaveUrl('https://example.com/audio.mp3');
|
|
78
|
+
* // null
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function parseArweaveUrl(url: string): ArweaveUrlInfo | null;
|
|
82
|
+
/**
|
|
83
|
+
* Construct a gateway URL from a transaction ID and gateway config
|
|
84
|
+
*
|
|
85
|
+
* @param txId - The 43-character Arweave transaction ID
|
|
86
|
+
* @param gateway - The gateway configuration to use
|
|
87
|
+
* @param pathSuffix - Optional path suffix to append after txId (e.g., '/file.jpg')
|
|
88
|
+
* @returns The constructed gateway URL
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* constructGatewayUrl('abc123...', { host: 'arweave.net', protocol: 'https', priority: 1 });
|
|
93
|
+
* // 'https://arweave.net/abc123...'
|
|
94
|
+
*
|
|
95
|
+
* constructGatewayUrl('abc123...', { host: 'arweave.net', protocol: 'https', priority: 1 }, '/model.json');
|
|
96
|
+
* // 'https://arweave.net/abc123.../model.json'
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export declare function constructGatewayUrl(txId: string, gateway: GatewayConfig, pathSuffix?: string): string;
|
|
100
|
+
/**
|
|
101
|
+
* Get all gateway URLs for a transaction ID in priority order
|
|
102
|
+
*
|
|
103
|
+
* @param txId - The 43-character Arweave transaction ID
|
|
104
|
+
* @param gateways - Array of gateway configs (defaults to DEFAULT_GATEWAYS)
|
|
105
|
+
* @param pathSuffix - Optional path suffix to append after txId (e.g., '/file.jpg')
|
|
106
|
+
* @returns Array of gateway URLs in priority order
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* getAllGatewayUrls('abc123...');
|
|
111
|
+
* // ['https://arweave.net/abc123...', 'https://ar.io/abc123...', ...]
|
|
112
|
+
*
|
|
113
|
+
* getAllGatewayUrls('abc123...', DEFAULT_GATEWAYS, '/model.json');
|
|
114
|
+
* // ['https://arweave.net/abc123.../model.json', ...]
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare function getAllGatewayUrls(txId: string, gateways?: GatewayConfig[], pathSuffix?: string): string[];
|
|
118
|
+
//# sourceMappingURL=arweaveUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arweaveUtils.d.ts","sourceRoot":"","sources":["../../src/utils/arweaveUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,aAAa,EAK3C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,uEAKtB,CAAC;AAQX;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAajD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CA8DlE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,GAAE,MAAW,GAAG,MAAM,CAGzG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,aAAa,EAAqB,EAC5C,UAAU,GAAE,MAAW,GACxB,MAAM,EAAE,CAIV"}
|