ac-storage 0.14.1 → 0.15.1
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/AMBIGUOUS_TESTS_REPORT.md +57 -0
- package/CLAUDE.md +415 -0
- package/COMMENTS_IMPROVEMENT_REPORT.md +259 -0
- package/COMPLETE_TEST_CLEANUP_SUMMARY.md +217 -0
- package/FINAL_TEST_CLEANUP_REPORT.md +116 -0
- package/INCONSISTENT_TESTS_REPORT.md +165 -0
- package/README.md +172 -32
- package/REPORT.md +178 -0
- package/REPORT_2.md +31 -0
- package/TEST_CLEANUP_REPORT.md +81 -0
- package/TEST_COMMENTS_REVIEW.md +283 -0
- package/TEST_REFACTORING_REPORT.md +209 -0
- package/TODO.md +167 -0
- package/_TESTPATH/ac-drop/.acstorage +8 -0
- package/_TESTPATH/access-separation-test/.acstorage +5 -0
- package/_TESTPATH/data-corruption-investigation/data/config.json +4 -0
- package/_TESTPATH/idempotent-test/.acstorage +4 -0
- package/_TESTPATH/idempotent-test/test.json +4 -0
- package/_TESTPATH/invalid-operation-order-test/.acstorage +3 -0
- package/_TESTPATH/release-test/.acstorage +6 -0
- package/_TESTPATH/release-test/dir/file4.json +5 -0
- package/_TESTPATH/release-test/dir/file5.txt +1 -0
- package/_TESTPATH/release-test/file1.json +5 -0
- package/_TESTPATH/release-test/file2.txt +1 -0
- package/_TESTPATH/single-acstorage-corruption/config.json +1263 -0
- package/dist/bundle.cjs +348 -144
- package/dist/bundle.cjs.map +1 -1
- package/dist/bundle.mjs +347 -143
- package/dist/bundle.mjs.map +1 -1
- package/dist/index.d.ts +38 -7
- package/package.json +45 -45
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# 모호한 테스트 보고서
|
|
2
|
+
|
|
3
|
+
## 1. electron-ipc-simulation.test.ts
|
|
4
|
+
|
|
5
|
+
### 제거 권장 (버그 재현용):
|
|
6
|
+
- **라인 240-305**: `test('CRITICAL: 동시 save() 호출로 인한 race condition')`
|
|
7
|
+
- 50번 반복하여 손상 재현 시도
|
|
8
|
+
- json-accessor v0.7에서 이미 해결됨
|
|
9
|
+
|
|
10
|
+
- **라인 631-690**: `test('CRITICAL: 빠른 IPC 요청으로 동시 writeFile 유발')`
|
|
11
|
+
- 100번 반복하여 파일 손상 재현 시도
|
|
12
|
+
- 이미 해결된 문제
|
|
13
|
+
|
|
14
|
+
- **라인 784-820**: `test('문서화: IPC 환경 특유의 문제점')`
|
|
15
|
+
- 단순 console.log만 출력
|
|
16
|
+
- `expect(true).toBe(true)` - 의미 없는 검증
|
|
17
|
+
- 코드 주석이나 문서로 대체 가능
|
|
18
|
+
|
|
19
|
+
### 판단: 3개 테스트 제거하고 나머지 유지
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. storage-move.test.ts
|
|
24
|
+
|
|
25
|
+
### 제거 권장:
|
|
26
|
+
- **라인 97-99**: `test('copy 123')`
|
|
27
|
+
```typescript
|
|
28
|
+
test(`copy 123`, async () => {
|
|
29
|
+
await storage.access('text1:index.txt', 'text');
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
- 의미 없는 테스트명
|
|
33
|
+
- 불완전한 구현 (access만 하고 아무것도 검증 안 함)
|
|
34
|
+
- 작성 중 방치된 것으로 보임
|
|
35
|
+
|
|
36
|
+
### 판단: 해당 테스트 제거
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 3. idempotent-operations.test.ts
|
|
41
|
+
- **명확함**: 멱등성 검증, 유지 권장
|
|
42
|
+
|
|
43
|
+
## 4. 나머지 테스트들
|
|
44
|
+
- **명확함**: 정상적인 기능 테스트
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 요약
|
|
49
|
+
|
|
50
|
+
### 제거 대상 (총 4개 테스트):
|
|
51
|
+
1. `electron-ipc-simulation.test.ts` 내 3개 CRITICAL/문서화 테스트
|
|
52
|
+
2. `storage-move.test.ts` 내 'copy 123' 테스트
|
|
53
|
+
|
|
54
|
+
### 제거 후:
|
|
55
|
+
- 더 명확한 테스트 스위트
|
|
56
|
+
- 실제 기능 검증에 집중
|
|
57
|
+
- 유지보수 부담 감소
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
# AC-Storage - Developer Documentation
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
**AC-Storage** is a TypeScript library that provides a structured, access-controlled file storage management system. It allows developers to define file access permissions upfront and manage JSON, text, and binary files in a type-safe manner with transactional semantics.
|
|
6
|
+
|
|
7
|
+
### Key Features
|
|
8
|
+
|
|
9
|
+
- **Access Control**: Pre-register file paths and access types before use
|
|
10
|
+
- **Multiple File Formats**: Built-in support for JSON, Text, and Binary files
|
|
11
|
+
- **Custom Accessors**: Extensible system for custom file formats
|
|
12
|
+
- **Transactional Semantics**: Commit changes explicitly to filesystem
|
|
13
|
+
- **Caching System**: Optimized access type validation through `.acstorage` cache
|
|
14
|
+
- **Sub-Storage**: Create isolated storage spaces for directory-based operations
|
|
15
|
+
- **Dependency Tracking**: Automatic management of file dependencies
|
|
16
|
+
|
|
17
|
+
## Directory Structure
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
ac-storage/
|
|
21
|
+
├── src/
|
|
22
|
+
│ ├── features/ # Core feature implementations
|
|
23
|
+
│ │ ├── accessors/ # File accessor implementations
|
|
24
|
+
│ │ │ ├── BinaryAccessor/ # Binary file handling
|
|
25
|
+
│ │ │ ├── TextAccessor/ # Text file handling
|
|
26
|
+
│ │ │ ├── JSONAccessor/ # JSON file handling
|
|
27
|
+
│ │ │ ├── CustomAccessor/ # Custom format support
|
|
28
|
+
│ │ │ └── MetaAccessor/ # Directory and root accessors
|
|
29
|
+
│ │ ├── storage/ # Storage management
|
|
30
|
+
│ │ │ ├── ACStorage.ts # Main storage class
|
|
31
|
+
│ │ │ ├── ACSubStorage.ts # Sub-storage implementation
|
|
32
|
+
│ │ │ ├── MemACStorage.ts # In-memory storage
|
|
33
|
+
│ │ │ └── test/ # Storage tests
|
|
34
|
+
│ │ ├── StorageAccessControl/ # Access control logic
|
|
35
|
+
│ │ │ ├── StorageAccessControl.ts
|
|
36
|
+
│ │ │ └── StorageAccessControl.test.ts
|
|
37
|
+
│ │ └── StorageAccess/ # Access type definitions
|
|
38
|
+
│ │ └── StorageAccess.ts
|
|
39
|
+
│ ├── types/ # TypeScript type definitions
|
|
40
|
+
│ ├── errors/ # Error classes
|
|
41
|
+
│ ├── utils/ # Utility functions
|
|
42
|
+
│ └── data/ # Test data
|
|
43
|
+
├── dist/ # Build output
|
|
44
|
+
├── _TESTPATH/ # Test runtime directory
|
|
45
|
+
├── jest.config.ts # Jest test configuration
|
|
46
|
+
├── tsconfig.json # TypeScript configuration
|
|
47
|
+
├── rollup.config.js # Build configuration
|
|
48
|
+
└── package.json # Package metadata
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Architecture
|
|
52
|
+
|
|
53
|
+
### Core Components
|
|
54
|
+
|
|
55
|
+
1. **ACStorage** (`src/features/storage/ACStorage.ts`)
|
|
56
|
+
- Main entry point for storage operations
|
|
57
|
+
- Manages accessor lifecycle and dependencies
|
|
58
|
+
- Handles caching and filesystem synchronization
|
|
59
|
+
- Provides memory management through release/drop operations
|
|
60
|
+
|
|
61
|
+
2. **StorageAccessControl** (`src/features/StorageAccessControl/`)
|
|
62
|
+
- Enforces access permissions
|
|
63
|
+
- Validates file access against registered tree
|
|
64
|
+
- Manages file operations (copy, move)
|
|
65
|
+
- Handles destroy operations for memory cleanup
|
|
66
|
+
|
|
67
|
+
3. **Accessors** (`src/features/accessors/`)
|
|
68
|
+
- Abstract file operations for different formats
|
|
69
|
+
- Each type has a Manager and Accessor class
|
|
70
|
+
- Manager handles lifecycle, Accessor provides API
|
|
71
|
+
|
|
72
|
+
4. **StorageAccess** (`src/features/StorageAccess/`)
|
|
73
|
+
- Factory for creating access type definitions
|
|
74
|
+
- Used in `register()` to define file permissions
|
|
75
|
+
|
|
76
|
+
### Data Flow
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
User Code
|
|
80
|
+
↓
|
|
81
|
+
ACStorage.register() → Define access tree
|
|
82
|
+
↓
|
|
83
|
+
ACStorage.create*() / open*() / access*() → Request file access
|
|
84
|
+
↓
|
|
85
|
+
StorageAccessControl → Validate permissions
|
|
86
|
+
↓
|
|
87
|
+
AccessorManager → Create/load accessor
|
|
88
|
+
↓
|
|
89
|
+
Accessor API → Read/write operations
|
|
90
|
+
↓
|
|
91
|
+
ACStorage.commit() → Persist to filesystem
|
|
92
|
+
↓
|
|
93
|
+
ACStorage.release() → Save and unload from memory (optional)
|
|
94
|
+
ACStorage.drop() → Delete file and unload (alternative)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### File Access Methods
|
|
98
|
+
|
|
99
|
+
AC-Storage provides three distinct methods for accessing files, each with different semantics:
|
|
100
|
+
|
|
101
|
+
#### 1. **create()** - Create Only
|
|
102
|
+
- **Creates** a new file
|
|
103
|
+
- **Throws error** if file already exists (on disk or in memory)
|
|
104
|
+
- Use when you want to ensure you're creating a new file
|
|
105
|
+
|
|
106
|
+
#### 2. **open()** - Load Only
|
|
107
|
+
- **Loads** an existing file
|
|
108
|
+
- **Throws error** if file does not exist
|
|
109
|
+
- Use when you expect the file to already exist
|
|
110
|
+
|
|
111
|
+
#### 3. **access()** - Create or Load (Default)
|
|
112
|
+
- **Creates** file if it doesn't exist
|
|
113
|
+
- **Loads** file if it already exists
|
|
114
|
+
- **Never throws** for existence checks
|
|
115
|
+
- Use for flexible access (most common)
|
|
116
|
+
|
|
117
|
+
#### Access Methods Comparison
|
|
118
|
+
|
|
119
|
+
| Method | Creates if Missing | Loads if Exists | Error if Missing | Error if Exists |
|
|
120
|
+
|--------|-------------------|-----------------|------------------|-----------------|
|
|
121
|
+
| `create()` | ✅ | ❌ | N/A | ✅ |
|
|
122
|
+
| `open()` | ❌ | ✅ | ✅ | N/A |
|
|
123
|
+
| `access()` | ✅ | ✅ | ❌ | ❌ |
|
|
124
|
+
|
|
125
|
+
**Example:**
|
|
126
|
+
```typescript
|
|
127
|
+
// Create only - explicit file creation
|
|
128
|
+
const config = await storage.createAsJSON('config.json');
|
|
129
|
+
config.setOne('version', '1.0');
|
|
130
|
+
|
|
131
|
+
// Open only - explicit file loading
|
|
132
|
+
const existing = await storage.openAsJSON('config.json');
|
|
133
|
+
console.log(existing.getOne('version'));
|
|
134
|
+
|
|
135
|
+
// Access - flexible (creates or loads)
|
|
136
|
+
const flexible = await storage.accessAsJSON('settings.json');
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Available methods for each approach:**
|
|
140
|
+
```typescript
|
|
141
|
+
// CREATE methods
|
|
142
|
+
await storage.create(identifier, accessType)
|
|
143
|
+
await storage.createAsJSON(identifier)
|
|
144
|
+
await storage.createAsText(identifier)
|
|
145
|
+
await storage.createAsBinary(identifier)
|
|
146
|
+
|
|
147
|
+
// OPEN methods
|
|
148
|
+
await storage.open(identifier, accessType)
|
|
149
|
+
await storage.openAsJSON(identifier)
|
|
150
|
+
await storage.openAsText(identifier)
|
|
151
|
+
await storage.openAsBinary(identifier)
|
|
152
|
+
|
|
153
|
+
// ACCESS methods (backward compatible)
|
|
154
|
+
await storage.access(identifier, accessType)
|
|
155
|
+
await storage.accessAsJSON(identifier)
|
|
156
|
+
await storage.accessAsText(identifier)
|
|
157
|
+
await storage.accessAsBinary(identifier)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Memory Management
|
|
161
|
+
|
|
162
|
+
AC-Storage provides two approaches for unloading files from memory:
|
|
163
|
+
|
|
164
|
+
#### 1. **release()** - Save and Unload
|
|
165
|
+
- Commits changes to filesystem
|
|
166
|
+
- Removes accessor from memory
|
|
167
|
+
- **Keeps file on disk**
|
|
168
|
+
- Use when you want to free memory but preserve data
|
|
169
|
+
|
|
170
|
+
#### 2. **drop()** - Delete and Unload
|
|
171
|
+
- **Does NOT commit changes** (uncommitted changes are lost)
|
|
172
|
+
- Removes accessor from memory
|
|
173
|
+
- **Deletes file from disk**
|
|
174
|
+
- Use when you want to completely remove the file
|
|
175
|
+
|
|
176
|
+
#### Comparison Table
|
|
177
|
+
|
|
178
|
+
| Operation | Commits Changes | Removes from Memory | Deletes File |
|
|
179
|
+
|-----------|----------------|---------------------|--------------|
|
|
180
|
+
| `commit()` | ✅ | ❌ | ❌ |
|
|
181
|
+
| `release()` | ✅ | ✅ | ❌ |
|
|
182
|
+
| `drop()` | ❌ | ✅ | ✅ |
|
|
183
|
+
|
|
184
|
+
**Example:**
|
|
185
|
+
```typescript
|
|
186
|
+
// Save and unload from memory (file persists)
|
|
187
|
+
await storage.accessAsJSON('config.json');
|
|
188
|
+
await storage.release('config.json');
|
|
189
|
+
|
|
190
|
+
// Delete file and unload
|
|
191
|
+
await storage.accessAsJSON('temp.json');
|
|
192
|
+
await storage.drop('temp.json');
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Internal Events
|
|
196
|
+
|
|
197
|
+
The library uses an internal event system for lifecycle management:
|
|
198
|
+
|
|
199
|
+
- **`'access'` event**: Fired when a file is accessed
|
|
200
|
+
- **`'destroy'` event**: Fired when a file is dropped (deleted)
|
|
201
|
+
- **Note**: `release()` does NOT trigger destroy event (it's a safe unload)
|
|
202
|
+
|
|
203
|
+
**Usage:**
|
|
204
|
+
```typescript
|
|
205
|
+
storage.addListener('access', (identifier) => {
|
|
206
|
+
console.log(`Accessed: ${identifier}`);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
storage.addListener('destroy', (identifier) => {
|
|
210
|
+
console.log(`Destroyed: ${identifier}`);
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Testing
|
|
215
|
+
|
|
216
|
+
### Test Configuration
|
|
217
|
+
|
|
218
|
+
- **Framework**: Jest with ts-jest
|
|
219
|
+
- **Location**: Tests are colocated with source code
|
|
220
|
+
- **Pattern**: `**/*.(spec|test).ts`
|
|
221
|
+
- **Environment**: Node.js
|
|
222
|
+
|
|
223
|
+
### Test Files
|
|
224
|
+
|
|
225
|
+
#### Accessor Tests
|
|
226
|
+
- `src/features/accessors/BinaryAccessor/binary-accessor.test.ts` - Binary file operations
|
|
227
|
+
- `src/features/accessors/TextAccessor/text-accessor.test.ts` - Text file operations
|
|
228
|
+
- `src/features/accessors/JSONAccessor/json-accesssor.test.ts` - JSON file operations
|
|
229
|
+
|
|
230
|
+
#### Storage Tests
|
|
231
|
+
- `src/features/storage/test/storage.test.ts` - Core storage functionality
|
|
232
|
+
- `src/features/storage/test/storage-accessor.test.ts` - Accessor lifecycle
|
|
233
|
+
- `src/features/storage/test/storage-fs.test.ts` - Filesystem operations
|
|
234
|
+
- `src/features/storage/test/storage-move.test.ts` - Move/copy operations
|
|
235
|
+
- `src/features/storage/test/ac-drop.test.ts` - Drop/destroy operations (memory cleanup)
|
|
236
|
+
- `src/features/storage/test/release.test.ts` - Release operations (save & unload)
|
|
237
|
+
- `src/features/storage/test/access-separation.test.ts` - Create/Open/Access API separation
|
|
238
|
+
- `src/features/storage/test/custom-accessor.test.ts` - Custom accessor support
|
|
239
|
+
- `src/features/storage/test/substorage.test.ts` - Sub-storage functionality
|
|
240
|
+
|
|
241
|
+
#### Access Control Tests
|
|
242
|
+
- `src/features/StorageAccessControl/StorageAccessControl.test.ts` - Access control logic
|
|
243
|
+
|
|
244
|
+
### Running Tests
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Run all tests
|
|
248
|
+
npm test
|
|
249
|
+
|
|
250
|
+
# Run tests in watch mode
|
|
251
|
+
npm test -- --watch
|
|
252
|
+
|
|
253
|
+
# Run tests with coverage
|
|
254
|
+
npm test -- --coverage
|
|
255
|
+
|
|
256
|
+
# Run specific test file
|
|
257
|
+
npm test -- storage.test.ts
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Test Output Location
|
|
261
|
+
|
|
262
|
+
Test artifacts and temporary files are created in:
|
|
263
|
+
- `_TESTPATH/` - Runtime test directory (gitignored)
|
|
264
|
+
- Individual tests may create temporary subdirectories
|
|
265
|
+
|
|
266
|
+
## Building
|
|
267
|
+
|
|
268
|
+
### Build Configuration
|
|
269
|
+
|
|
270
|
+
- **Bundler**: Rollup
|
|
271
|
+
- **Output Formats**:
|
|
272
|
+
- CommonJS: `dist/bundle.cjs`
|
|
273
|
+
- ES Module: `dist/bundle.mjs`
|
|
274
|
+
- TypeScript Declarations: `dist/index.d.ts`
|
|
275
|
+
|
|
276
|
+
### Build Commands
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Build the library
|
|
280
|
+
npm run build
|
|
281
|
+
|
|
282
|
+
# Run playground example
|
|
283
|
+
npm run playground
|
|
284
|
+
|
|
285
|
+
# Publish to npm
|
|
286
|
+
npm run publish-public
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Path Aliases
|
|
290
|
+
|
|
291
|
+
The project uses TypeScript path aliases for cleaner imports:
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
@/* → src/*
|
|
295
|
+
types → src/types/index
|
|
296
|
+
errors → src/errors/index
|
|
297
|
+
features/* → src/features/*
|
|
298
|
+
data/* → src/data/*
|
|
299
|
+
utils → src/utils/index
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Both `tsconfig.json` and `jest.config.ts` must be kept in sync for these aliases.
|
|
303
|
+
|
|
304
|
+
## Development Guidelines
|
|
305
|
+
|
|
306
|
+
### Adding New Accessor Types
|
|
307
|
+
|
|
308
|
+
1. Create accessor directory under `src/features/accessors/`
|
|
309
|
+
2. Implement `IAccessorManager` and accessor interface
|
|
310
|
+
3. Add tests in the same directory
|
|
311
|
+
4. Export from `src/features/accessors/index.ts`
|
|
312
|
+
|
|
313
|
+
### Adding Tests
|
|
314
|
+
|
|
315
|
+
1. Place tests near the code they test
|
|
316
|
+
2. Use `.test.ts` suffix
|
|
317
|
+
3. Follow existing test patterns
|
|
318
|
+
4. Ensure all async operations are properly awaited
|
|
319
|
+
5. Clean up test artifacts in `_TESTPATH/`
|
|
320
|
+
|
|
321
|
+
### Code Style
|
|
322
|
+
|
|
323
|
+
- TypeScript strict mode enabled (with some relaxations)
|
|
324
|
+
- No implicit any allowed for complex types
|
|
325
|
+
- Explicit method overrides required
|
|
326
|
+
- Property access from index signatures restricted
|
|
327
|
+
|
|
328
|
+
## Common Issues
|
|
329
|
+
|
|
330
|
+
### Cache-Related Issues
|
|
331
|
+
|
|
332
|
+
If tests fail due to cache conflicts:
|
|
333
|
+
```bash
|
|
334
|
+
# Clear test cache
|
|
335
|
+
rm -rf _TESTPATH/
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Build Issues
|
|
339
|
+
|
|
340
|
+
If build fails:
|
|
341
|
+
```bash
|
|
342
|
+
# Clean and rebuild
|
|
343
|
+
rm -rf dist/
|
|
344
|
+
npm run build
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Test Failures
|
|
348
|
+
|
|
349
|
+
If tests hang or fail inconsistently:
|
|
350
|
+
- Check for uncommitted accessors
|
|
351
|
+
- Ensure proper cleanup in test teardown
|
|
352
|
+
- Verify `_TESTPATH/` is empty between runs
|
|
353
|
+
|
|
354
|
+
## Dependencies
|
|
355
|
+
|
|
356
|
+
### Runtime Dependencies
|
|
357
|
+
- `@hve/json-accessor` - JSON manipulation
|
|
358
|
+
- `fast-deep-equal` - Deep equality checks
|
|
359
|
+
- `tree-navigate` - Tree structure navigation
|
|
360
|
+
|
|
361
|
+
### Development Dependencies
|
|
362
|
+
- `typescript` - TypeScript compiler
|
|
363
|
+
- `jest` / `ts-jest` - Testing framework
|
|
364
|
+
- `rollup` - Module bundler
|
|
365
|
+
- `tsx` - TypeScript execution for playground
|
|
366
|
+
|
|
367
|
+
## Version
|
|
368
|
+
|
|
369
|
+
Current version: **0.15.0** (unreleased)
|
|
370
|
+
|
|
371
|
+
Last updated: 2025-12-07
|
|
372
|
+
|
|
373
|
+
## Recent Changes
|
|
374
|
+
|
|
375
|
+
### v0.15.0 - Access API Separation & Release API (2025-12-07)
|
|
376
|
+
|
|
377
|
+
**Breaking Changes:**
|
|
378
|
+
- Renamed internal event `'release'` → `'destroy'` (v0.14.1)
|
|
379
|
+
- `storage.addListener('release', ...)` → `storage.addListener('destroy', ...)`
|
|
380
|
+
|
|
381
|
+
**New Features:**
|
|
382
|
+
|
|
383
|
+
1. **File Access Method Separation**
|
|
384
|
+
- `create()` / `createAsJSON()` / `createAsText()` / `createAsBinary()` - Create new files only (error if exists)
|
|
385
|
+
- `open()` / `openAsJSON()` / `openAsText()` / `openAsBinary()` - Load existing files only (error if missing)
|
|
386
|
+
- `access()` / `accessAsJSON()` / `accessAsText()` / `accessAsBinary()` - Flexible access (create or load)
|
|
387
|
+
|
|
388
|
+
2. **Memory Management APIs** (v0.14.1+)
|
|
389
|
+
- `release(identifier)` - Save changes and unload file from memory (file persists)
|
|
390
|
+
- `releaseDir(identifier)` - Save and unload directory from memory
|
|
391
|
+
- `releaseAll()` - Save and unload all files from memory
|
|
392
|
+
|
|
393
|
+
**Internal Changes:**
|
|
394
|
+
- Refactored `getOrCreateAccessor()` to support three access modes: `'create'`, `'open'`, `'access'`
|
|
395
|
+
- Added `getOrCreateAccessorFromAccess()` helper method
|
|
396
|
+
- Added `validateAccess()` to `StorageAccessControl` for permission validation without accessor creation
|
|
397
|
+
- Updated all internal event listeners to use `'destroy'` terminology
|
|
398
|
+
|
|
399
|
+
**Backward Compatibility:**
|
|
400
|
+
- All existing `access*()` methods continue to work with the same behavior
|
|
401
|
+
- No breaking changes to public API (except event name change in v0.14.1)
|
|
402
|
+
|
|
403
|
+
**Example:**
|
|
404
|
+
```typescript
|
|
405
|
+
// New explicit methods
|
|
406
|
+
const config = await storage.createAsJSON('config.json'); // Create only
|
|
407
|
+
const existing = await storage.openAsJSON('config.json'); // Load only
|
|
408
|
+
|
|
409
|
+
// Existing flexible method (backward compatible)
|
|
410
|
+
const flexible = await storage.accessAsJSON('settings.json'); // Create or load
|
|
411
|
+
|
|
412
|
+
// Memory management
|
|
413
|
+
await storage.release('config.json'); // Save and unload (v0.14.1+)
|
|
414
|
+
await storage.drop('temp.json'); // Delete and unload
|
|
415
|
+
```
|