IndexedDB storage layer and repositories for Brazen user scripts
이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greasyfork.org/scripts/587030/1875981/Brazen%20Framework%20-%20IndexedDB%20Storage.js을(를) 사용하여 포함하는 라이브러리입니다.
Required for latest-stack apps that use IndexedDB persistence through Configuration Manager. One IndexedDB database per script (scriptPrefix with trailing dash stripped, e.g. brazen-r34xxx). Replaces localStorage/GM aggregate blobs for settings, tags, bookmarks, and download ledger.
Greasy Fork: reserved script id 583968 (unpublished — override locally for testing; see greasyfork-urls.md) · Requires: Utilities · Load before: Configuration Manager
Apps do not open the database directly. Use BrazenConfigurationManager.initialize(), getRepos(), and field APIs wired by the configuration manager.
| Scenario | This module |
|---|---|
New Brazen app with async initialize() + IDB persistence |
Yes — @require before Configuration Manager |
| Legacy app on driver-only Configuration Manager 3.x | No — keep local/GM drivers until migrated |
| IDB unavailable (private mode, blocked storage) | CM sets isIdbBlocked(); persistence disabled, read-only UI |
Seed script-specific data during first-time setup via setScriptSetup() on the configuration manager:
this._configurationManager.setScriptSetup(async (repos, cm) => {
// Seed apis / tagTypes documents (example)
let apis = await repos.storage.get(IDB_STORE_APIS, 'apis')
if (!apis?.entries?.length) {
await repos.storage.put(IDB_STORE_APIS, {
id: 'apis',
entries: [{ entryId: 1, name: 'gelbooru', label: 'Gelbooru' }],
})
}
})
Legacy local/GM data is imported automatically during setup by BrazenLegacyImporter when present.
BrazenConfigurationManager
└── BrazenStorageRepositories(scriptPrefix)
├── storage → BrazenIndexedDBStorage (open, CRUD, health, zip)
├── meta → MetaRepository (revision, setup lock, entryId counters)
├── settings → SettingsRepository (non-tag field blobs)
├── tags → TagRepository (registry + compile → tagRuleSets)
├── tagRules → TagRuleRepository (row-per-rule by group)
├── bookmarks → BookmarkRepository
└── ledger → LedgerRepository
| Store | Shape | Role |
|---|---|---|
meta |
singleton | revisionId, setup flags, per-store next*EntryId counters, compilePendingGroups |
settings |
singleton document | Non-tag config fields (camelCase properties) |
apis |
singleton + entries[] |
Site/API entities |
tagTypes |
singleton + entries[] |
Canonical and alias tag types |
tags |
row per tag | Append-only registry (name immutable, case-sensitive) |
tagRules |
row per rule | Raw lines by group (blacklist, explored, …) |
tagRuleSets |
singleton | Compiled rawLines + optimized per tag-domain field |
bookmarks |
row per bookmark | Numeric entryId, sortOrder, label/tags/url |
ledgerEntries |
row per post id | Download duplicate ledger (postId unique) |
| CM method | Role |
|---|---|
async initialize() |
Open DB, setup or normal phase, hydrate fields |
getRepos() |
BrazenStorageRepositories instance |
isStorageReady() / isIdbBlocked() / canPersist() |
Runtime gates |
toggleTagRule(fieldKey, tagName) |
Sidebar-style sole-tag toggle (writes tagRules, compiles) |
clearTagRules(fieldKey) |
Clear all rules in a tag group |
scheduleTagRuleCompile(groups) / ensureTagRuleSetsCompiled() |
Two-phase compile pipeline |
async save() / async backup() / async restore() |
Persistence + v3 zip bundle |
Direct repository use (advanced, e.g. bookmark widget per-op):
let repos = this._configurationManager.getRepos()
await repos.bookmarks.add({ label: '…', tags: '…', url: '…', sortOrder: 0 })
let rows = await repos.bookmarks.listAll()
tagRules rows (sidebar toggle, settings Apply, or legacy import).meta.compilePendingGroups.tagRuleSets.*.optimized (compliance hot path reads compiled data only).| lines are expanded on import via expandOrRuleLine().manifest.json (CONFIG_BACKUP_VERSION = 3).postId (newer claimedAt wins).meta.revisionId bumps on writes. Configuration Manager listens to visibilitychange only (no BroadcastChannel) and reloads changed fields when revision differs.
LocalStorageDriver / GmStorageDriver used only inside BrazenLegacyImporter during setupasync init(), IDB-blocked banner, compliance after compileWorkspace technical reference: BrazenIndexedDBStorage.spec.md