Brazen Framework - Download Manager

Cross-tab download queue, resolution pipeline, and immediate downloads for Brazen user scripts

Tätä skriptiä ei tulisi asentaa suoraan. Se on kirjasto muita skriptejä varten sisällytettäväksi metadirektiivillä // @require https://update.greasyfork.org/scripts/587126/1877599/Brazen%20Framework%20-%20Download%20Manager.js.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

Advertisement:

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

Advertisement:

Tekijä
brazenvoid
Versio
1.1.5
Luotu
15.7.2026
Päivitetty
16.7.2026
Size
109 kt
Lisenssi
GPL-3.0-only

Brazen Framework — Download Manager (developer guide)

Cross-tab batch downloads, page resolution, immediate GM_download orchestration, optional tag discovery review, and human-interaction rate-limit handling. Apps extend BrazenFramework, call configureDownloadManager() after configureDock(), and @require this module after Framework core.

Greasy Fork: Download Manager · Requires: Framework core, IndexedDB Storage (v1.1.0+ download queue stores) · Grant on this module: GM_download


When to use / when not to use

  • Use when your app needs cross-tab download queues, search-tile selection enqueue, media-page immediate download, token-based paths, duplicate-ledger integration, or tag-discovery review before filenames are built.
  • Do not use for a single fire-and-forget GM_download with no queue, no cross-tab state, and no path tokens — that is rare; most Brazen apps still benefit from ledger + path helpers here.
  • Requires a dockconfigureDownloadManager() throws if configureDock() was not called first.
  • Requires IndexedDB — queue rows and shared state live in IDB via Configuration Manager repositories; when IDB is blocked, persistence gates apply.

Quick start

Load order (after Framework core):

// @require … Brazen Framework - Framework.js
// @require … Brazen Framework - Download Manager.js

In the app constructor (after configureDock):

this.configureDock({ orientations: ['right'], scriptName: 'My App', showBranding: true })

this.configureDownloadManager({
  enableConfigKey: 'enable-download-manager',
  downloadPaths: {
    folderConfigKey: 'download-folder',
    filenamePatternConfigKey: 'filename-pattern',
    subfolderPatternConfigKey: 'subfolder-pattern',
    defaultFolder: 'my-downloads',
    getPatternResolver: () => ({
      chips, tagTypes, ignore, substitutions, unknownDefault,
    }),
    extractMediaData: (el) => ({ id, md5, ext }),
    extractTagGroups: () => ({ author: [], character: [], general: [] }),
    extractTagIncidences: () => ({ 'tag name': 12 }), // optional; discovery panel counts
    appendExtension: true,
    nameFallback: (data) => data.id || 'media',
  },
  pages: {
    search: {
      roles: ['selection'],
      itemSelector: 'span.thumb',
      resolveItem: (item) => ({ itemId, sourceUrl }),
      setItemProgress: (item, progress) => { /* optional tile overlay */ },
    },
    media: {
      roles: ['enqueueMedia', 'immediateDownload'],
      defaultDownloadType: 'post',
    },
  },
  downloadTypes: {
    post: {
      resolveFromSearch: (ctx) => ({ nextUrl: ctx.sourceUrl }),
      resolveFromMedia: (doc, ctx) => ({ mediaUrl, tagGroups, downloadId, data }),
    },
  },
  getQueueItemId: (ctx) => ctx.itemId,
  resolutionInitiationGapMs: 2000,
  downloadInitiationGapMs: 2000,
})

BrazenDownloadManager.initialize() runs from Framework init() after Configuration Manager setup.


Configuration shape

Top-level keys

Key Role
enableConfigKey Flag field key for Enable Download Manager (auto-registered unless enabled: true)
enableDefault Default for enable flag when auto-registered
enabled When true, skip enable-flag registration and treat manager as always on
selectionModeDefaultConfigKey Optional override for Start in Selection Mode (OPTION_DOWNLOAD_SELECTION_MODE_DEFAULT)
downloadPaths Path/token extraction and pattern resolver (see below)
pages Named page configs with roles (see below)
downloadTypes Per-type resolution handlers (resolveFromSearch, resolveFromMedia, …)
getQueueItemId (context) => string stable queue id
resolutionInitiationGapMs ms between resolution fetches (default 2000)
downloadInitiationGapMs ms between GM_download calls (default 2000; replaces Framework downloadsDelay)
tagDiscovery Optional review panel config (see below)
rateLimitHandlers Per-context rate-limit strategies (see below)

downloadPaths

Key Role
folderConfigKey / filenamePatternConfigKey / subfolderPatternConfigKey Configuration Manager keys for folder and patterns
defaultFolder Fallback root folder
getPatternResolver () => { chips, tagTypes, ignore, substitutions, unknownDefault, … } — tag-type tokens use registry attributes when TagRuntime is warmed
extractMediaData(el) Metadata object for pattern chips (id, md5, ext, …)
extractTagGroups() { typeKey: string[] } tag lists for path tokens
extractTagIncidences() Optional { tagName: count } map for discovery panel incidence meta
appendExtension Append data.ext to filename when set
nameFallback(data) When pattern resolves empty

Path helpers (buildDownloadPathFromPatterns, buildDownloadPath, sanitizePathSegment, substitution parse/map) live on the manager instance — use getDownloadManager() from the app.

pages and roles

Each pages[pageName] entry:

Key Role
roles Capability flags for the active page (see table)
itemSelector Search tiles for selection mode
resolveItem(item) { itemId, sourceUrl, … } for enqueue
defaultDownloadType Fallback type key for media enqueue
setItemProgress(item, progress) Optional hook for per-tile pipeline UI
Role Enables
selection Selection mode + click-to-enqueue on search tiles
enqueueMedia Media-page add/remove queue toggle
immediateDownload downloadImmediate() on media pages
tagDiscoveryToggle Dock tag-discovery mode button

Query with isDownloadPageRole('selection') (delegated on Framework).

tagDiscovery (optional)

Key Role
discoverAt Steps that scan pattern-relevant types, e.g. ['resolution', 'immediate']
tagTypes Panel grouping: { label, rowClass, color } per type — colors via View Layer applyTagDiscoveryTypeColors
panel Extra options forwarded to renderTagDiscoveryPanelContent (section labels, groupOrder, …)
actions Incidence options for tag-attribute buttons (buildUrl, field keys, CSS, explore gate) — framework owns button chrome
isTagKnown(tagName) Optional override; default checks tag registry

When discovery is on, unknown tags block the pipeline and open #bv-tag-discovery-panel. Confirm promotes types; Skip drops the item without confirming; Open media opens the source URL. State fields discoveryPanelTags and discoveryPanelKnownTags persist in downloadManagerState.

rateLimitHandlers

Keyed by context (resolution, download, …). Each context may define:

Handler Role
humanInteraction { detect(ctx), openUrl?(ctx), confirmTitle?, confirmMessage?, confirmLabel?, reopenLabel? } — opens verification tab (brazen_hi=1 query + hash, rel=opener), sets humanInteractionBlocked + humanInteractionOpenUrl, shows processor-leader panel. Runs before timedReload.
timedReload { detect(doc, ctx), reloadDelayMs? } — document detect only (not bare HTTP 429)

reopenLabel defaults to Reopen verification tab on the human-interaction panel. humanInteractionOpenUrl is stored in shared DM state for Reopen.

Initiation gaps

resolutionInitiationGapMs and downloadInitiationGapMs pace resolution fetches and GM_download respectively (defaults 2000 each; configure independently per app). Both use separate in-tab clocks hydrated from lastResolutionInitiationAt / lastDownloadInitiationAt in shared state so concurrent IDB writes cannot erase the gap. Resolution paces before every fetch attempt (including rate-limit retries). Confirming a human-interaction rate limit stamps only the blocked pipeline's clock so the next initiation waits a full gap without affecting the other queue.


Public API

Framework delegates most calls; you can also use this.getDownloadManager() for path helpers.

Queue and download

Method Role
downloadImmediate({ mediaElement, removeMediaOnSuccess?, source? }) Immediate download; registers path tags; optional discovery gate
enqueueDownload(context) Add to resolution queue; returns whether added
dequeueDownload(itemId) Remove from either queue
isQueued(itemId) Cross-tab pipeline membership
toggleDownloadManagerPaused() Start/pause download queue only; no-op when download pending is 0
clearDownloadQueue() Wipe download queue only; clears download-context human-interaction block
toggleCurrentMediaQueued() Media-page enqueue toggle
toggleSelectionMode() Local session selection mode (search)

Tag discovery

Method Role
confirmTagDiscoveryMappings() Confirm types; promote resolution item or run pending immediate
skipTagDiscoveryInclusion() Skip review — drop item and clear selection progress; do not confirm types
openTagDiscoveryMedia() Open media URL for item under review
toggleTagDiscoveryMode() Cross-tab discovery enable toggle

Progress and status

Method Role
getDownloadManagerProgress() { resolution: {current, total}, download: {current, total} }
getDownloadQueueCount() Dock counter; excludes resolution queue when discovery mode is on
getPendingPipelineCount() Non-terminal items in both queues
isDownloadManagerEnabled() Enable flag + dock active
isDownloadPageRole(role) Page role gate
isDownloadManagerLeaderTab() This tab owns processingTabId
isDownloadManagerRunning() Pipeline active (queues, blocked state, or in-tab processing)

Human interaction

Method Role
BrazenDownloadManager.peekHumanInteractionBlockedMirror(scriptPrefix) Static. Sync localStorage mirror — usable in Phase-1 page ops before initialize()
BrazenDownloadManager.peekHumanInteractionBlockedIdb(scriptPrefix) Static. Async IndexedDB read of humanInteractionBlocked — Phase-1 fallback when query/hash/mirror/opener were stripped
BrazenDownloadManager.hasBrazenHumanInteractionMarker() Static. Query or hash still has brazen_hi
BrazenDownloadManager.isQueueOpenedVerificationTab() Static. Same-origin opener (queue-opened tab)
BrazenDownloadManager.shouldSilenceMediaCloudflarePrompt(scriptPrefix, instance?) Static. Whether a challenge page should stay silent
handleMediaCloudflarePage(options?) Phase-1 Cloudflare / challenge page: silence queue tabs; standalone shows themed Done — reload pane
shouldSilenceMediaCloudflarePrompt() Instance wrapper around the static silence gate
isHumanInteractionBlockedSync() Instance: IDB state humanInteractionBlocked

Path and substitution helpers (getDownloadManager())

Method Role
buildDownloadPathFromPatterns(data, tagGroups) Token path assembly
buildDownloadPath(folder, name) Sanitized folder + filename
sanitizePathSegment(segment) Illegal char strip + entity decode
decodeHtmlEntities(text) DOM textarea decode
parseDownloadTagSubstitutionLines(lines, normalizeToken) Substitution parser
buildDownloadTagSubstitutionMap(rules) Map<subject, replacement>

Processors and leadership

One leader tab (processingTabId) runs resolution then download loops when not blocked.

Behaviour Detail
paused Pauses the download queue only. Resolution auto-runs on enqueue. Start/Pause disabled when download queue is empty. When download queue drains to 0, paused returns to true.
Leadership Heartbeat processingHeartbeatAt (~3 s) + sync localStorage mirror. Stale steal ~12 s or immediate after pagehide mirror clear. Steal requeues in-flight resolving / downloading rows.
Claims Items move queuedresolving / downloading before work; in-tab lock is synchronous before any await.
Ledger Duplicate claim at download time in Download Manager when Skip or Hide is on; ledgerClaimed on download rows prevents double-claim after lock steal.
UI cadence Queue/state puts do not rebuild dock; one UI reset per resolution/download task. Full _syncFromStorage on init, enqueue, Start, tab focus.

Tag discovery UI

Scans pattern-relevant tag types only. Always registers path tags via _registerResolvedTagGroups (discovery on → seen-only; off → confirm as typeEntryId). Panel lists unknown then known tags with incidence counts; framework maps tag-attribute actions internally. Reload / tab focus restores panel when review pending.

Human-interaction panel

Shown only on the processor-leader tab when humanInteractionBlocked. Verification tab stays silent (brazen_hi query + hash, localStorage mirror, preserved window.opener, or peekHumanInteractionBlockedIdb). Done — resume clears block; Reopen uses humanInteractionOpenUrl. Cross-tab enqueue while blocked still writes queued rows; processors resume after confirm.


Integration notes

Topic Detail
Grant @grant GM_download on this module (and typically on the app too)
Load order After Framework core; before app script
Dock Manager registers dock fields (selection, enqueue, start/pause, clear, progress, discovery). Apps pushField enable key on the rail.
Ledger Constructor downloadDuplicateLedger on Framework; claims happen in Download Manager — see Framework developer guide
View Layer Progress slot, item progress overlays, discovery/human-interaction panels — View Layer
IndexedDB downloadResolutionQueue, downloadQueue, downloadManagerStateIndexedDB Storage

Public API reference (index)

  • Setup: configureDownloadManager, getDownloadManager
  • Queue: downloadImmediate, enqueueDownload, dequeueDownload, isQueued, toggleDownloadManagerPaused, clearDownloadQueue, toggleSelectionMode, toggleCurrentMediaQueued
  • Discovery: confirmTagDiscoveryMappings, skipTagDiscoveryInclusion, openTagDiscoveryMedia, toggleTagDiscoveryMode
  • Status: getDownloadManagerProgress, getDownloadQueueCount, isDownloadPageRole, isDownloadManagerEnabled, isDownloadManagerLeaderTab, handleMediaCloudflarePage, shouldSilenceMediaCloudflarePrompt, peekHumanInteractionBlockedMirror, peekHumanInteractionBlockedIdb, hasBrazenHumanInteractionMarker, isQueueOpenedVerificationTab, isHumanInteractionBlockedSync
  • Paths: buildDownloadPathFromPatterns, parseDownloadTagSubstitutionLines, buildDownloadTagSubstitutionMap, buildDownloadPath