Brazen Framework - IndexedDB Storage

IndexedDB storage layer and repositories for Brazen user scripts

이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greasyfork.org/scripts/587030/1875981/Brazen%20Framework%20-%20IndexedDB%20Storage.js을(를) 사용하여 포함하는 라이브러리입니다.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

작성자
brazenvoid
버전
1.0.0
생성일
2026-07-14
갱신일
2026-07-14
크기
43.9KB
라이선스
GPL-3.0-only

Brazen Framework — IndexedDB Storage (developer guide)

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.


When to use

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

Quick start (script setup hook)

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.


Architecture

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

Database stores (schema v1)

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)

Public surface (via Configuration Manager)

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()

Tag rules pipeline

  1. WritetagRules rows (sidebar toggle, settings Apply, or legacy import).
  2. Mark pending — affected groups added to meta.compilePendingGroups.
  3. Compile — async/microtask: rules → tagRuleSets.*.optimized (compliance hot path reads compiled data only).
  4. OR in new rules — not stored; legacy | lines are expanded on import via expandOrRuleLine().

Backup / restore (v3)

  • Export: zip bundle — one JSON file per store + manifest.json (CONFIG_BACKUP_VERSION = 3).
  • Import: v3 zip or JSON; v2/v1 flat backups still handled by Configuration Manager adapters.
  • Ledger restore: merge by postId (newer claimedAt wins).

Cross-tab sync

meta.revisionId bumps on writes. Configuration Manager listens to visibilitychange only (no BroadcastChannel) and reloads changed fields when revision differs.


Related modules

  • Configuration Manager — field schema, initialize/save, backup UI
  • UtilitiesLocalStorageDriver / GmStorageDriver used only inside BrazenLegacyImporter during setup
  • Framework coreasync init(), IDB-blocked banner, compliance after compile

Workspace technical reference: BrazenIndexedDBStorage.spec.md