AOSSIE-Org / AOSSIE-Org/IndexedDB-Import-Export

[BUG]: Silent Data Loss for Supported IndexedDB Structured Clone Types (Set, Map, ArrayBuffer, etc.)

オープン
#81 コメント 0 件 リアクション 0 件 担当者 1 名 @Sashang-debug が担当を希望しています GitHub で見る
bug enhancement
主要言語
YAML
スター
7
フォーク
3
平均マージ
3日 55分
マージ済み PR(30日)
8

説明

### Bug Description
The library's stated goal is to provide an export format that "preserves data types that `JSON.stringify` normally corrupts." Currently, the custom `serialize()` function only handles `Uint8Array`, `bigint`, and `Date`.

However, the native **IndexedDB Structured Clone algorithm** supports many more complex types natively, including `Set`, `Map`, `ArrayBuffer`, and other TypedArrays (like `Uint16Array`, `Float32Array`).

Because these objects fail the `isPlainObject` check inside `src/serialization/index.ts`, they bypass the recursive serialization block and are passed back to the user unchanged. When the user eventually runs `JSON.stringify()` on the export data, these types are silently corrupted (e.g., converted into empty `{}` objects). When importing this backup, the original data is permanently lost and replaced with empty objects.

### Steps to Reproduce
1. Create an IndexedDB store that contains a `Set`, `Map`, or `ArrayBuffer`.
2. Export the database using `exportDB()`.
3. Stringify the backup using `JSON.stringify()`.
4. Parse and import the backup using `importDB()`.
5. Observe that the `Set`, `Map`, and `ArrayBuffer` data has been replaced by empty objects `{}`.

### Logs and Screenshots
Here is a minimal reproduction using a Vitest test script:

```typescript
import { describe, it, expect } from 'vitest';
import { serialize, deserialize } from '../src/serialization/index.js';

describe('Unsupported type serialization', () => {
it('corrupts Set, Map, and ArrayBuffer via JSON.stringify', () => {
const data = {
mySet: new Set([1, 2, 3]),
myMap: new Map([['a', 1]]),
myBuffer: new Uint16Array([1, 2, 3]).buffer, // ArrayBuffer
};

const serialized = serialize(data);
const jsonStr = JSON.stringify(serialized);
const parsed = JSON.parse(jsonStr);
const restored = deserialize(parsed);

console.log("Restored:", restored);
expect(restored).not.toEqual(data); // Fails, data is corrupted
});
});
```

**Test Output:**
```javascript
Restored: [Object: null prototype] {
mySet: [Object: null prototype] {},
myMap: [Object: null prototype] {},
myBuffer: [Object: null prototype] {}
}
```

### Environment Details
- **OS:** All
- **Browser:** All
- **Node.js:** >=20

### Impact
High - Major feature is broken

### Recommended Fix
Expand the `SERIALIZATION_TAGS` and add serialization/deserialization branches for standard Structured Clone types:
1. **`Set`**: Convert to `[...value]` and tag as `"set"`.
2. **`Map`**: Convert to `[...value.entries()]` and tag as `"map"`.
3. **`ArrayBuffer`**: Convert to `Uint8Array` -> Base64 and tag as `"buffer"`.

### Code of Conduct
- [x] I have joined the Discord server and will post updates there
- [x] I have searched existing issues to avoid duplicates

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。