diff --git a/README.md b/README.md
index a6fc886..299d652 100644
--- a/README.md
+++ b/README.md
@@ -1,129 +1,132 @@
-# ConfigurationAPI
+### ConfigurationAPI
-A lightweight, high-performance YAML configuration API with automatic file watching, diff tracking, and atomic reloads for Paper/Spigot plugins.
-
----
+A lightweight, high-performance YAML configuration API for Paper/Spigot plugins, featuring automatic file watching, atomic reloads, and a clean event-driven design.
### Features
- Automatic config reload on file changes (WatchService-based)
-- Atomic, thread-safe configuration swapping
-- Line-level diff tracking (changed / added / removed)
-- Change summary abstraction (`ConfigChangeSummary`)
-- Robust against partial writes and filesystem edge cases
-- Optimized (no regex, O(n) diff, minimal allocations)
-- Clean integration with Bukkit/Paper event system
+- Single global watcher (no per-file overhead)
+- Atomic, thread-safe configuration replacement
+- SHA-256 checksum-based change detection
+- Debounce protection against duplicate reloads
+- Synchronous reload events (ConfigReloadedEvent)
+- Clean, minimal, and predictable API
+- Designed for high-performance plugin environments
### Why ConfigurationAPI?
-
- Eliminates manual reload logic
-- Provides insight into config changes (diffs)
+- Guarantees consistent configuration state
- Prevents unsafe concurrent access
-- Designed for high-performance plugin environments
-
-## Installation
-
-### Maven
+- Centralized architecture (single source of truth)
+- Minimal overhead and easy integration
+### Installation
+#### Maven
```xml
dev.spexx
ConfigurationAPI
- 1.0.4
+ 1.0.5
```
-### 1. Create ConfigManager
+### Usage
+
+#### 1. Create ConfigManager
```java
ConfigManager configManager = new ConfigManager(plugin);
```
-
-### 2. Load a configuration file
+#### 2. Load a configuration file
```java
File file = new File(plugin.getDataFolder(), "config.yml");
YamlConfig config = configManager.getOrLoad(file);
```
-
-### 2.1 Load default resource (eg.: config.yml)
+#### 2.1 Load default resource (e.g. config.yml)
```java
YamlConfig config = configManager.getOrLoadResource("config.yml");
-# Copies from JAR if missing
-# Automatically registers watcher
+# Copies file from JAR if it does not exist
+# Automatically registers it with the watcher
+
```
+#### 3. Access configuration
+```java
+YamlConfig config = configManager.get(file);
+String value = config.config().getString("path.to.value");
-## 3. Automatic Reloads
+# Always returns the latest snapshot
+# Safe for concurrent access
+```
+
+#### 4. Automatic Reloads
Configuration files are automatically monitored.
When a file changes:
-- It is reloaded atomically
+- The file is reloaded
+- A new `YamlConfig` instance is created
+- The old instance is atomically replaced
- A `ConfigReloadedEvent` is fired
-- Diff + summary are provided
-### 4. Listening to Reload Events
+
+#### 5. Listening to Reload Events
```java
@EventHandler
public void onReload(ConfigReloadedEvent event) {
- ConfigChangeSummary summary = event.getSummary();
-
plugin.getLogger().info(() ->
- "[Config] Reloaded: " + summary
+ "[Config] Reloaded: " +
+ event.getNewConfig().file().getName() +
+ " (" + event.getReloadTimeMs() + "ms)"
);
- for (ConfigLineDifference diff : event.getDiffs()) {
- plugin.getLogger().info(() ->
- "[ConfigWatcher] file=" +
- event.getConfig().file().getName() +
- " line=" + diff.getLineNumber() +
- " delta=" + diff.getCharDelta()
- );
- }
+ plugin.getLogger().info(() ->
+ "Checksum: " +
+ event.getOldChecksum() +
+ " -> " +
+ event.getNewChecksum()
+ );
}
```
-### 5. Change Summary
-```java
-ConfigChangeSummary summary = event.getSummary();
+#### 6. Event Data
+`ConfigReloadedEvent` provides:
+- `getOldConfig()` → previous snapshot
+- `getNewConfig()` → updated snapshot
+- `getOldChecksum()` → previous file hash
+- `getNewChecksum()` → new file hash
+- `getReloadTimeMs()` → reload duration
-summary.changedLines();
-summary.addedLines();
-summary.removedLines();
-summary.getTotalChanges();
-summary.hasChanges();
-```
-
-### 6. Line Differences
-```java
-for (ConfigLineDifference diff : event.getDiffs()) {
-
- int line = diff.getLineNumber();
- String oldLine = diff.getOldLine();
- String newLine = diff.getNewLine();
- int delta = diff.getCharDelta();
-
- if (diff.isOnlyWhitespaceChange()) {
- // ignore formatting changes if needed
- }
-}
-```
-
-### 7. Architecture Overview
+#### 7. Architecture Overview
```yml
-ConfigManager
- ├── YamlConfig (immutable snapshot)
- ├── YamlConfigWatcher (file watcher)
- │ └── Diff engine (O(n))
- └── Events (ConfigReloadedEvent)
+ConfigManager (API layer)
+ ├── delegates to GlobalConfigWatcher
+ └── provides access to configs
+
+GlobalConfigWatcher (core)
+ ├── owns config state (Map)
+ ├── owns checksums
+ ├── handles file watching (WatchService)
+ ├── performs reloads
+ └── fires events
+
+YamlConfig
+ └── immutable snapshot of configuration
```
-### 8. Thread Safety
-- `YamlConfig` is immutable
-- Reloads are atomic
-- Watcher runs async, events fire sync (main thread)
-- Safe for concurrent reads
-
-### 9. Best Practices
-- Always fetch config via ConfigManager
-- Avoid storing long-lived YamlConfig references
-- Use events for reactive updates
+#### 8. Threading Model
+- Watcher runs on a dedicated async thread
+- File changes are processed asynchronously
+- Events are dispatched synchronously on the main thread
+- `YamlConfig` instances are immutable
+
+#### 9. Best Practices
+- Always access configs via `ConfigManager`
+- Do not store `YamlConfig` instances long-term
+- Use `ConfigReloadedEvent` for reactive updates
+- Avoid modifying `FileConfiguration` directly
+
+#### 10. Guarantees
+- No duplicated configuration state
+- Atomic updates (no partial reads)
+- No reload if file content is unchanged
+- Safe under concurrent access