zen-fs-config 0.5.20 → 0.5.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,192 +1,219 @@
1
1
  # zen-fs-config
2
2
 
3
- 基于 ZenFS 的分布式配置管理库。以 IndexedDB 为本地主后端(offline-first),用户提供的远程后端作为副本自动同步。支持应用隔离、共享空间、节点本地配置和冲突安全。
3
+ Distributed configuration management library built on [ZenFS](https://github.com/weijia/zen-fs), with IndexedDB as the offline-first local primary backend and user-provided remote backends as replicas that sync automatically. Supports app isolation, shared spaces, node-local config, and conflict-safe operations.
4
4
 
5
5
  **GitHub**: https://github.com/weijia/zen-fs-config
6
6
  **NPM**: `zen-fs-config`
7
- **设计文档**: [DESIGN.md](./DESIGN.md)
7
+ **Design doc**: [DESIGN.md](./DESIGN.md)
8
8
 
9
- ## 安装
9
+ ## Features
10
+
11
+ - **Offline-first** — IndexedDB is always the primary backend; reads and writes work without network
12
+ - **Multi-backend sync** — Add any number of remote replicas (Gitee, GitHub, RemoteStorage, WebDAV, etc.) with automatic bi-directional sync
13
+ - **App isolation** — Each app gets its own namespace under `/{appId}/`
14
+ - **Shared spaces** — Cross-app shared config under `/shared/`
15
+ - **Node-local config** — Per-device settings under `/nodes/{nodeId}/` that never sync
16
+ - **Self-describing topology** — Backend configuration is stored as files in `.meta/backends/`, so re-opening a repo restores everything automatically
17
+ - **Conflict safety** — Conflicts are archived instead of silently overwritten; JSON deep-merge is available as a strategy
18
+ - **Version tracking** — Every config file has a version sidecar with version number and SHA-256 hash
19
+ - **Caching layer** — Optional ETag/TTL caching via `zen-fs-cache` to reduce remote API calls
20
+
21
+ ## Installation
10
22
 
11
23
  ```bash
12
24
  npm install zen-fs-config @zenfs/core @zenfs/dom zen-fs-sync
13
25
  ```
14
26
 
15
- > `@zenfs/dom` 提供 IndexedDB 后端(浏览器环境必需)。`zen-fs-cache` 为可选依赖。
27
+ > `@zenfs/dom` provides the IndexedDB backend (required in browser environments). `zen-fs-cache` is an optional dependency for remote request caching.
28
+
29
+ ## Usage via `<script>` tag (no build step)
30
+
31
+ A self-contained browser bundle is published at `dist/index.browser.js`. It bundles **all** dependencies (`@zenfs/core`, `@zenfs/dom`, `zen-fs-sync`, `zen-fs-cache`) and exposes the library on the global `window.ZenFSConfig`. No npm install, no bundler — just drop it into any HTML page:
32
+
33
+ ```html
34
+ <script src="https://unpkg.com/zen-fs-config/dist/index.browser.js"></script>
35
+ <script>
36
+ (async () => {
37
+ const { createConfigRepo } = window.ZenFSConfig;
38
+
39
+ // IndexedDB primary backend is created automatically
40
+ const repo = await createConfigRepo('my-app');
41
+
42
+ repo.setConfig('greeting.json', { msg: 'hello' });
43
+ const cfg = await repo.getConfig('greeting.json');
44
+ console.log(cfg); // { msg: 'hello' }
45
+ })();
46
+ </script>
47
+ ```
48
+
49
+ > The browser bundle includes a pure-JS SHA-256 fallback, so version tracking works even in non-secure contexts (plain HTTP) where `crypto.subtle` is unavailable.
16
50
 
17
- ## 快速开始
51
+ ## Quick Start
18
52
 
19
- ### 1. 初始化(零参数)
53
+ ### 1. Initialize (zero-configuration)
20
54
 
21
55
  ```typescript
22
56
  import { createConfigRepo } from 'zen-fs-config';
23
57
 
24
- // 不传任何后端参数,自动创建 IndexedDB 本地主后端
58
+ // Creates an IndexedDB primary backend automatically
25
59
  const repo = await createConfigRepo('my-app');
26
60
 
27
- // 读写配置(同步 API,从 IndexedDB 读取)
61
+ // Read/write config (synchronous API, served from IndexedDB)
28
62
  repo.setConfig('/database', { host: 'localhost', port: 5432 });
29
63
  const db = repo.getConfig<{ host: string; port: number }>('/database');
30
64
  ```
31
65
 
32
- ### 2. 设置新的配置
33
-
34
- ```typescript
35
- repo.setConfig('/cache', { ttl: 3600, maxSize: '100MB' });
36
- repo.setConfig('/feature-flags', { newUI: true, beta: false });
37
- ```
38
-
39
- ### 3. 增加数据后端(副本)
66
+ ### 2. Add a remote replica backend
40
67
 
41
68
  ```typescript
42
69
  import { registerBackend } from 'zen-fs-config';
43
70
  import { Gitee } from 'zen-fs-gitee';
44
71
 
45
- // 注册后端类型
72
+ // Register the backend type first
46
73
  registerBackend('Gitee', async (options) => {
47
74
  return Gitee.create(options);
48
75
  });
49
76
 
50
- // 动态添加副本后端,自动与本地 IndexedDB 双向同步
77
+ // Dynamically add a replica — auto-syncs bi-directionally with local IndexedDB
51
78
  await repo.addBackend('gitee-prod', 'Gitee', {
52
79
  token: 'your-token',
53
80
  owner: 'your-name',
54
81
  repo: 'config-repo',
55
82
  branch: 'main',
56
- }, '生产环境 Gitee 配置仓库');
83
+ }, 'Production Gitee config repo');
57
84
  ```
58
85
 
59
- ### 4. 自动同步
86
+ ### 3. Automatic sync
60
87
 
61
88
  ```typescript
62
- // setConfig 写入 IndexedDB 后,自动同步到所有副本后端
89
+ // Writing to IndexedDB triggers auto-sync to all replicas
63
90
  repo.setConfig('/database', { host: 'new-host', port: 5432 });
64
91
 
65
- // 手动触发同步(通常不需要,同步是自动的)
92
+ // Manual flush (usually not needed — sync is automatic)
66
93
  await repo.flush();
67
94
  ```
68
95
 
69
- ### 5. 再次打开时初始化
96
+ ### 4. Re-open on next page load
70
97
 
71
98
  ```typescript
72
- // 重新打开页面时,只需传入 appId
73
- // IndexedDB 中的配置和后端拓扑会自动恢复
99
+ // Just pass the appId — IndexedDB restores everything
74
100
  const repo = await createConfigRepo('my-app');
75
101
 
76
- // 配置直接从 IndexedDB 读取(离线可用)
102
+ // Config is readable immediately (offline)
77
103
  const db = repo.getConfig<{ host: string; port: number }>('/database');
78
104
 
79
- // 已注册的副本后端会自动重新连接并同步
105
+ // Registered replicas reconnect and sync automatically
80
106
  const backends = await repo.getBackends();
81
107
  console.log(backends?.backends.map(b => b.id)); // ['local-idb', 'gitee-prod', ...]
82
108
  ```
83
109
 
84
- ### 带初始后端初始化
110
+ ### Initialize with a backend from the start
85
111
 
86
112
  ```typescript
87
- // 首次初始化时可以直接传入远程后端
88
113
  const repo = await createConfigRepo('my-app', {
89
- primaryBackendId: 'gitee-prod', // 副本后端 ID
114
+ primaryBackendId: 'gitee-prod',
90
115
  backendInfo: {
91
116
  type: 'Gitee',
92
117
  options: { token: 'xxx', owner: 'xxx', repo: 'xxx', branch: 'main' },
93
118
  },
94
- idbStoreName: 'my-app-config', // 自定义 IndexedDB store 名称
119
+ idbStoreName: 'my-app-config', // custom IndexedDB store name
95
120
  });
96
121
 
97
- // 之后重新打开时不需要再传后端参数
122
+ // Next time you don't need to pass backend info again
98
123
  const repo2 = await createConfigRepo('my-app');
99
124
  ```
100
125
 
101
- ## 目录结构
126
+ ## Directory Structure
102
127
 
103
128
  ```
104
129
  /
105
- ├── {appId}/ # 应用私有配置(自动同步到副本)
106
- ├── shared/ # 跨应用共享配置(双向同步)
107
- ├── nodes/{nodeId}/ # 节点本地配置(不同步)
130
+ ├── {appId}/ # App-private config (auto-synced to replicas)
131
+ ├── shared/ # Cross-app shared config (bi-directional sync)
132
+ ├── nodes/{nodeId}/ # Node-local config (never synced)
108
133
  └── .meta/
109
- ├── backends/ # 后端拓扑(每个后端一个文件)
134
+ ├── backends/ # Backend topology (one file per backend)
110
135
  │ ├── local-idb.json
111
136
  │ ├── gitee-prod.json
112
137
  │ └── ...
113
- ├── .deleted/ # 删除墓碑(跨后端删除传播)
114
- └── .conflicts/ # 冲突归档(双方内容都保存)
138
+ ├── .deleted/ # Deletion tombstones (propagate deletes across backends)
139
+ └── .conflicts/ # Conflict archives (both sides preserved)
115
140
  ```
116
141
 
117
- 每个配置文件有 sidecar 版本文件:`db.json` → `.db.json.version`(版本号 + SHA-256 哈希)。
142
+ Each config file has a sidecar version file: `db.json` → `.db.json.version` (version number + SHA-256 hash).
143
+
144
+ ## Core API
118
145
 
119
- ## 核心 API
146
+ ### ConfigRepo
120
147
 
121
- | 方法 | 说明 |
122
- |---|---|
123
- | `createConfigRepo(appId, options?)` | 创建配置仓库。IndexedDB 始终为主后端,`backendInfo` 作为副本 |
124
- | `getConfig<T>(path)` | 同步读取应用配置(从 IndexedDB) |
125
- | `setConfig(path, data)` | 同步写入应用配置(异步持久化 + 自动同步) |
126
- | `addBackend(id, type, options, desc?)` | 动态添加副本后端,自动建立双向同步 |
127
- | `removeBackend(id)` | 移除副本后端,停止同步 |
128
- | `getBackends()` | 读取所有后端拓扑(从 `.meta/backends/*.json` 聚合) |
129
- | `getNodeConfig<T>(nodeId, path)` | 异步读取节点本地配置 |
130
- | `setNodeConfig(nodeId, path, data)` | 异步写入节点本地配置(不同步) |
131
- | `publishNodeConfig(nodeId)` | 将节点配置一次性同步到所有后端 |
132
- | `peekNodeConfig<T>(nodeId, path)` | 只读查看其他节点的已发布配置 |
133
- | `flush()` | 手动触发所有同步 |
134
- | `listConflicts()` | 列出所有冲突归档 |
135
- | `resolveConflict(id, merged)` | 用合并内容解决冲突 |
136
- | `fs.promises.*` | 标准 fs API,chroot 隔离到 `/{appId}/` |
137
- | `dispose()` | 停止同步、释放资源 |
148
+ | Method | Description |
149
+ |--------|-------------|
150
+ | `createConfigRepo(appId, options?)` | Create a config repo. IndexedDB is always primary; `backendInfo` becomes a replica. |
151
+ | `getConfig<T>(path)` | Synchronously read app config (from IndexedDB) |
152
+ | `setConfig(path, data)` | Synchronously write app config (async persistence + auto-sync) |
153
+ | `addBackend(id, type, options, desc?)` | Dynamically add a replica backend with auto bi-directional sync |
154
+ | `removeBackend(id)` | Remove a replica backend and stop syncing |
155
+ | `getBackends()` | Read backend topology (aggregated from `.meta/backends/*.json`) |
156
+ | `getNodeConfig<T>(nodeId, path)` | Asynchronously read node-local config |
157
+ | `setNodeConfig(nodeId, path, data)` | Asynchronously write node-local config (not synced) |
158
+ | `publishNodeConfig(nodeId)` | One-time push of node config to all backends |
159
+ | `peekNodeConfig<T>(nodeId, path)` | Read-only view of another node's published config |
160
+ | `flush()` | Manually trigger all pending syncs |
161
+ | `listConflicts()` | List all archived conflicts |
162
+ | `resolveConflict(id, merged)` | Resolve a conflict with merged content |
163
+ | `fs.promises.*` | Standard fs API, chrooted to `/{appId}/` |
164
+ | `dispose()` | Stop syncing and release resources |
138
165
 
139
- ## 后端注册
166
+ ### Backend Registration
140
167
 
141
- zen-fs-config 内置两个后端:
142
- - **IndexedDB** — 本地主后端(基于 `@zenfs/dom`),无需注册
143
- - **InMemory** — 内存后端(基于 `@zenfs/core`),用于测试
168
+ zen-fs-config includes two built-in backends:
169
+ - **IndexedDB** — local primary backend (based on `@zenfs/dom`), no registration needed
170
+ - **InMemory** — in-memory backend (based on `@zenfs/core`), useful for testing
144
171
 
145
- 注册自定义后端:
172
+ Register custom backends:
146
173
 
147
174
  ```typescript
148
175
  import { registerBackend } from 'zen-fs-config';
149
176
 
150
- // 注册 Gitee 后端
177
+ // Register Gitee backend
151
178
  registerBackend('Gitee', async (options) => {
152
179
  const { Gitee } = await import('zen-fs-gitee');
153
180
  return Gitee.create(options);
154
181
  });
155
182
 
156
- // 注册 S3 后端
157
- registerBackend('S3Bucket', async (options) => {
158
- const { S3Bucket } = await import('@zenfs/core');
159
- return S3Bucket.create(options);
183
+ // Register RemoteStorage backend
184
+ registerBackend('RemoteStorage', async (options) => {
185
+ const { createRemoteStorageFileSystem } = await import('zen-fs-remotestoragejs');
186
+ return createRemoteStorageFileSystem(options);
160
187
  });
161
188
  ```
162
189
 
163
- ## 架构概览
190
+ ## Architecture
164
191
 
165
192
  ```
166
193
  Application code
167
194
  ↓ (reads/writes via standard fs API)
168
- ConfigRepo (this library)
195
+ ConfigRepo
169
196
  ├─ IndexedDB (local primary, always)
170
197
  │ └─ All config operations target IndexedDB first
171
198
  └─ zen-fs-sync → Bi-directional sync
172
- ├─ Replica X (e.g., Gitee)
173
- ├─ Replica Y (e.g., S3)
174
- └─ Replica Z (e.g., RemoteStorage)
199
+ ├─ Replica 1 (e.g. Gitee)
200
+ ├─ Replica 2 (e.g. RemoteStorage)
201
+ └─ Replica 3 (e.g. GitHub)
175
202
  ```
176
203
 
177
- - **IndexedDB 是唯一的主后端**:所有读写操作直接操作 IndexedDB,保证离线可用
178
- - **远程后端是副本**:通过 `addBackend()` 或 `createConfigRepo({ backendInfo })` 添加
179
- - **自动同步**:对 IndexedDB 的修改会自动同步到所有副本后端
180
- - **自描述拓扑**:后端配置存储在 `.meta/backends/` 目录中,每个后端一个 JSON 文件
204
+ - **IndexedDB is the only primary backend** — all reads and writes go directly to IndexedDB, guaranteeing offline availability
205
+ - **Remote backends are replicas** — added via `addBackend()` or `createConfigRepo({ backendInfo })`
206
+ - **Auto-sync** — changes to IndexedDB automatically propagate to all replicas
207
+ - **Self-describing topology** — backend configuration lives in `.meta/backends/`, one JSON file per backend
181
208
 
182
- ## 依赖
209
+ ## Dependencies
183
210
 
184
- | 包 | 说明 | 必需 |
185
- |---|---|---|
186
- | `@zenfs/core >=2.3.0` | ZenFS 虚拟文件系统 | 是 |
187
- | `@zenfs/dom >=1.0.0` | IndexedDB 后端(浏览器) | 是(浏览器) |
188
- | `zen-fs-sync >=0.1.0` | 跨后端同步引擎 | 是 |
189
- | `zen-fs-cache >=1.0.0` | ETag/TTL 缓存层 | 否(可选) |
211
+ | Package | Description | Required |
212
+ |---------|-------------|----------|
213
+ | `@zenfs/core >=2.3.0` | ZenFS virtual file system | Yes |
214
+ | `@zenfs/dom >=1.0.0` | IndexedDB backend (browser) | Yes (browser) |
215
+ | `zen-fs-sync >=0.4.7` | Cross-backend sync engine | Yes |
216
+ | `zen-fs-cache >=1.0.0` | ETag/TTL caching layer | No (optional) |
190
217
 
191
218
  ## License
192
219
 
@@ -0,0 +1,215 @@
1
+ # zen-fs-config
2
+
3
+ 基于 ZenFS 的分布式配置管理库。以 IndexedDB 为本地主后端(offline-first),用户提供的远程后端作为副本自动同步。支持应用隔离、共享空间、节点本地配置和冲突安全。
4
+
5
+ **GitHub**: https://github.com/weijia/zen-fs-config
6
+ **NPM**: `zen-fs-config`
7
+ **设计文档**: [DESIGN.md](./DESIGN.md)
8
+
9
+ ## 安装
10
+
11
+ ```bash
12
+ npm install zen-fs-config @zenfs/core @zenfs/dom zen-fs-sync
13
+ ```
14
+
15
+ > `@zenfs/dom` 提供 IndexedDB 后端(浏览器环境必需)。`zen-fs-cache` 为可选依赖。
16
+
17
+ ## 通过 `<script>` 标签直接使用(无需构建)
18
+
19
+ 包内置了一个自包含的浏览器构建 `dist/index.browser.js`,它把**所有**依赖(`@zenfs/core`、`@zenfs/dom`、`zen-fs-sync`、`zen-fs-cache`)打包在一起,并将库挂载到全局变量 `window.ZenFSConfig`。无需 npm install、无需打包工具,直接放入任意 HTML 页面即可:
20
+
21
+ ```html
22
+ <script src="https://unpkg.com/zen-fs-config/dist/index.browser.js"></script>
23
+ <script>
24
+ (async () => {
25
+ const { createConfigRepo } = window.ZenFSConfig;
26
+
27
+ // 自动创建 IndexedDB 主后端
28
+ const repo = await createConfigRepo('my-app');
29
+
30
+ repo.setConfig('greeting.json', { msg: 'hello' });
31
+ const cfg = await repo.getConfig('greeting.json');
32
+ console.log(cfg); // { msg: 'hello' }
33
+ })();
34
+ </script>
35
+ ```
36
+
37
+ > 浏览器构建包含纯 JS 实现的 SHA-256 回退,因此即使在 `crypto.subtle` 不可用的非安全上下文(普通 HTTP)中,版本追踪也能正常工作。
38
+
39
+ ## 快速开始
40
+
41
+ ### 1. 初始化(零参数)
42
+
43
+ ```typescript
44
+ import { createConfigRepo } from 'zen-fs-config';
45
+
46
+ // 不传任何后端参数,自动创建 IndexedDB 本地主后端
47
+ const repo = await createConfigRepo('my-app');
48
+
49
+ // 读写配置(同步 API,从 IndexedDB 读取)
50
+ repo.setConfig('/database', { host: 'localhost', port: 5432 });
51
+ const db = repo.getConfig<{ host: string; port: number }>('/database');
52
+ ```
53
+
54
+ ### 2. 设置新的配置
55
+
56
+ ```typescript
57
+ repo.setConfig('/cache', { ttl: 3600, maxSize: '100MB' });
58
+ repo.setConfig('/feature-flags', { newUI: true, beta: false });
59
+ ```
60
+
61
+ ### 3. 增加数据后端(副本)
62
+
63
+ ```typescript
64
+ import { registerBackend } from 'zen-fs-config';
65
+ import { Gitee } from 'zen-fs-gitee';
66
+
67
+ // 注册后端类型
68
+ registerBackend('Gitee', async (options) => {
69
+ return Gitee.create(options);
70
+ });
71
+
72
+ // 动态添加副本后端,自动与本地 IndexedDB 双向同步
73
+ await repo.addBackend('gitee-prod', 'Gitee', {
74
+ token: 'your-token',
75
+ owner: 'your-name',
76
+ repo: 'config-repo',
77
+ branch: 'main',
78
+ }, '生产环境 Gitee 配置仓库');
79
+ ```
80
+
81
+ ### 4. 自动同步
82
+
83
+ ```typescript
84
+ // setConfig 写入 IndexedDB 后,自动同步到所有副本后端
85
+ repo.setConfig('/database', { host: 'new-host', port: 5432 });
86
+
87
+ // 手动触发同步(通常不需要,同步是自动的)
88
+ await repo.flush();
89
+ ```
90
+
91
+ ### 5. 再次打开时初始化
92
+
93
+ ```typescript
94
+ // 重新打开页面时,只需传入 appId
95
+ // IndexedDB 中的配置和后端拓扑会自动恢复
96
+ const repo = await createConfigRepo('my-app');
97
+
98
+ // 配置直接从 IndexedDB 读取(离线可用)
99
+ const db = repo.getConfig<{ host: string; port: number }>('/database');
100
+
101
+ // 已注册的副本后端会自动重新连接并同步
102
+ const backends = await repo.getBackends();
103
+ console.log(backends?.backends.map(b => b.id)); // ['local-idb', 'gitee-prod', ...]
104
+ ```
105
+
106
+ ### 带初始后端初始化
107
+
108
+ ```typescript
109
+ // 首次初始化时可以直接传入远程后端
110
+ const repo = await createConfigRepo('my-app', {
111
+ primaryBackendId: 'gitee-prod', // 副本后端 ID
112
+ backendInfo: {
113
+ type: 'Gitee',
114
+ options: { token: 'xxx', owner: 'xxx', repo: 'xxx', branch: 'main' },
115
+ },
116
+ idbStoreName: 'my-app-config', // 自定义 IndexedDB store 名称
117
+ });
118
+
119
+ // 之后重新打开时不需要再传后端参数
120
+ const repo2 = await createConfigRepo('my-app');
121
+ ```
122
+
123
+ ## 目录结构
124
+
125
+ ```
126
+ /
127
+ ├── {appId}/ # 应用私有配置(自动同步到副本)
128
+ ├── shared/ # 跨应用共享配置(双向同步)
129
+ ├── nodes/{nodeId}/ # 节点本地配置(不同步)
130
+ └── .meta/
131
+ ├── backends/ # 后端拓扑(每个后端一个文件)
132
+ │ ├── local-idb.json
133
+ │ ├── gitee-prod.json
134
+ │ └── ...
135
+ ├── .deleted/ # 删除墓碑(跨后端删除传播)
136
+ └── .conflicts/ # 冲突归档(双方内容都保存)
137
+ ```
138
+
139
+ 每个配置文件有 sidecar 版本文件:`db.json` → `.db.json.version`(版本号 + SHA-256 哈希)。
140
+
141
+ ## 核心 API
142
+
143
+ | 方法 | 说明 |
144
+ |---|---|
145
+ | `createConfigRepo(appId, options?)` | 创建配置仓库。IndexedDB 始终为主后端,`backendInfo` 作为副本 |
146
+ | `getConfig<T>(path)` | 同步读取应用配置(从 IndexedDB) |
147
+ | `setConfig(path, data)` | 同步写入应用配置(异步持久化 + 自动同步) |
148
+ | `addBackend(id, type, options, desc?)` | 动态添加副本后端,自动建立双向同步 |
149
+ | `removeBackend(id)` | 移除副本后端,停止同步 |
150
+ | `getBackends()` | 读取所有后端拓扑(从 `.meta/backends/*.json` 聚合) |
151
+ | `getNodeConfig<T>(nodeId, path)` | 异步读取节点本地配置 |
152
+ | `setNodeConfig(nodeId, path, data)` | 异步写入节点本地配置(不同步) |
153
+ | `publishNodeConfig(nodeId)` | 将节点配置一次性同步到所有后端 |
154
+ | `peekNodeConfig<T>(nodeId, path)` | 只读查看其他节点的已发布配置 |
155
+ | `flush()` | 手动触发所有同步 |
156
+ | `listConflicts()` | 列出所有冲突归档 |
157
+ | `resolveConflict(id, merged)` | 用合并内容解决冲突 |
158
+ | `fs.promises.*` | 标准 fs API,chroot 隔离到 `/{appId}/` |
159
+ | `dispose()` | 停止同步、释放资源 |
160
+
161
+ ## 后端注册
162
+
163
+ zen-fs-config 内置两个后端:
164
+ - **IndexedDB** — 本地主后端(基于 `@zenfs/dom`),无需注册
165
+ - **InMemory** — 内存后端(基于 `@zenfs/core`),用于测试
166
+
167
+ 注册自定义后端:
168
+
169
+ ```typescript
170
+ import { registerBackend } from 'zen-fs-config';
171
+
172
+ // 注册 Gitee 后端
173
+ registerBackend('Gitee', async (options) => {
174
+ const { Gitee } = await import('zen-fs-gitee');
175
+ return Gitee.create(options);
176
+ });
177
+
178
+ // 注册 S3 后端
179
+ registerBackend('S3Bucket', async (options) => {
180
+ const { S3Bucket } = await import('@zenfs/core');
181
+ return S3Bucket.create(options);
182
+ });
183
+ ```
184
+
185
+ ## 架构概览
186
+
187
+ ```
188
+ Application code
189
+ ↓ (reads/writes via standard fs API)
190
+ ConfigRepo (this library)
191
+ ├─ IndexedDB (local primary, always)
192
+ │ └─ All config operations target IndexedDB first
193
+ └─ zen-fs-sync → Bi-directional sync
194
+ ├─ Replica X (e.g., Gitee)
195
+ ├─ Replica Y (e.g., S3)
196
+ └─ Replica Z (e.g., RemoteStorage)
197
+ ```
198
+
199
+ - **IndexedDB 是唯一的主后端**:所有读写操作直接操作 IndexedDB,保证离线可用
200
+ - **远程后端是副本**:通过 `addBackend()` 或 `createConfigRepo({ backendInfo })` 添加
201
+ - **自动同步**:对 IndexedDB 的修改会自动同步到所有副本后端
202
+ - **自描述拓扑**:后端配置存储在 `.meta/backends/` 目录中,每个后端一个 JSON 文件
203
+
204
+ ## 依赖
205
+
206
+ | 包 | 说明 | 必需 |
207
+ |---|---|---|
208
+ | `@zenfs/core >=2.3.0` | ZenFS 虚拟文件系统 | 是 |
209
+ | `@zenfs/dom >=1.0.0` | IndexedDB 后端(浏览器) | 是(浏览器) |
210
+ | `zen-fs-sync >=0.1.0` | 跨后端同步引擎 | 是 |
211
+ | `zen-fs-cache >=1.0.0` | ETag/TTL 缓存层 | 否(可选) |
212
+
213
+ ## License
214
+
215
+ MIT