1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-05-13 07:42:46 -04:00
Files
DankMaterialShell/.agents/skills/dms-plugin-dev/references/data-persistence-guide.md
T

4.8 KiB

Data Persistence Guide

DMS plugins have three tiers of data persistence, each suited for different use cases.

Tier 1: Plugin Data (Settings)

Persisted to settings.json. Use for user preferences and configuration.

Saving

pluginService.savePluginData(pluginId, "key", value)

Loading

var value = pluginService.loadPluginData(pluginId, "key", defaultValue)

Reactive Access via pluginData

PluginComponent has a reactive pluginData property that auto-loads from settings:

PluginComponent {
    property string displayText: pluginData?.text || "Default"
    property bool showIcon: pluginData?.showIcon !== undefined ? pluginData.showIcon : true
}

Reacting to Settings Changes

When settings are changed (e.g., from the settings UI), react with Connections:

Connections {
    target: pluginService
    function onPluginDataChanged(changedId) {
        if (changedId !== pluginId) return
        displayText = pluginService.loadPluginData(pluginId, "text", "Default")
        showIcon = pluginService.loadPluginData(pluginId, "showIcon", true)
    }
}

Tier 2: Plugin State

Persisted to a separate state file. Use for runtime state that should survive restarts but is not user-configurable (history, cache, counters).

Saving

pluginService.savePluginState(pluginId, "key", value)

Loading

var state = pluginService.loadPluginState(pluginId, "key", defaultValue)

Additional Methods

pluginService.clearPluginState(pluginId)
pluginService.removePluginStateKey(pluginId, "key")

Example: Persistent History

Item {
    property var history: []

    Component.onCompleted: {
        history = pluginService?.loadPluginState(pluginId, "history", []) || []
    }

    function addToHistory(entry) {
        history.unshift({
            text: entry,
            timestamp: Date.now()
        })
        if (history.length > 100) history = history.slice(0, 100)
        pluginService?.savePluginState(pluginId, "history", history)
    }

    function clearHistory() {
        history = []
        pluginService?.removePluginStateKey(pluginId, "history")
    }
}

Tier 3: Global Variables (Runtime Only)

NOT persisted. Shared across all instances of a plugin. Use for cross-instance state synchronization (multi-monitor consistency, multi-instance widgets).

Using PluginGlobalVar Component

import qs.Modules.Plugins

PluginComponent {
    PluginGlobalVar {
        id: globalCounter
        varName: "counter"
        defaultValue: 0
    }

    horizontalBarPill: Component {
        StyledRect {
            // ...
            StyledText {
                text: "Count: " + globalCounter.value
            }

            MouseArea {
                onClicked: globalCounter.set(globalCounter.value + 1)
            }
        }
    }
}

PluginGlobalVar properties:

Property Type Description
varName string Required: name of the global variable
defaultValue any Optional: default if not set
value any Readonly: current value

Methods:

  • set(newValue) - update the value (triggers reactivity across all instances)

Using PluginService API Directly

import qs.Services

property int counter: PluginService.getGlobalVar("myPlugin", "counter", 0)

Connections {
    target: PluginService
    function onGlobalVarChanged(pluginId, varName) {
        if (pluginId === "myPlugin" && varName === "counter") {
            counter = PluginService.getGlobalVar("myPlugin", "counter", 0)
        }
    }
}

function increment() {
    var current = PluginService.getGlobalVar("myPlugin", "counter", 0)
    PluginService.setGlobalVar("myPlugin", "counter", current + 1)
}

Decision Matrix

Need API Persisted Scope
User preferences (API keys, themes, intervals) savePluginData / loadPluginData Yes (settings.json) Per plugin
Runtime state (history, cache, counters) savePluginState / loadPluginState Yes (state file) Per plugin
Cross-instance sync (multi-monitor data) PluginGlobalVar or getGlobalVar/setGlobalVar No (runtime only) All instances
Quick reactive reads from settings pluginData property N/A (read-only) Per instance

Important Notes

  1. pluginData is reactive - bindings update automatically when data changes
  2. Global vars are NOT persistent - they reset when the shell restarts
  3. State vs Data - data is for user-facing settings, state is for internal runtime data
  4. Null safety - always check pluginService is not null before calling methods
  5. Signal namespacing - global var signals include pluginId to filter for your plugin
  6. Performance - global vars are efficient for frequent updates; settings writes are batched