Merge branch 'main' of https://git.eigen.co.id/eigen/fe-monorepo-template into core/page-provider
This commit is contained in:
@@ -116,7 +116,7 @@ const theme = await appStorage.getItem('THEME'); // Plaintext on disk
|
||||
|
||||
## 🔄 Offline-First Document Storage (PouchDB & CouchDB)
|
||||
|
||||
For complex, document-oriented data that requires fault-tolerance, offline support, and bi-directional cloud synchronization, we use the `PouchDatabaseManager`. This layer is powered by [PouchDB](https://pouchdb.com/) syncing to [CouchDB](https://couchdb.apache.org/).
|
||||
For complex, document-oriented data that requires fault-tolerance, offline support, and bi-directional cloud synchronization, we use the `PouchDBManager`. This layer is powered by [PouchDB](https://pouchdb.com/) syncing to [CouchDB](https://couchdb.apache.org/).
|
||||
|
||||
### Architecture
|
||||
|
||||
@@ -134,7 +134,7 @@ graph TD
|
||||
end
|
||||
|
||||
subgraph CoreStorage ["@repo/core-storage Engine"]
|
||||
MGR[PouchDatabaseManager Factory]
|
||||
MGR[PouchDBManager Factory]
|
||||
L_SALES[(Local PouchDB: Sales)]
|
||||
L_INV[(Local PouchDB: Inventory)]
|
||||
end
|
||||
@@ -168,13 +168,13 @@ graph TD
|
||||
|
||||
### 1. Initialization (IoC Factory)
|
||||
|
||||
The `PouchDatabaseManager` acts as a central singleton. It registers and manages all database instances. If a remote URL is provided, it automatically handles background synchronization.
|
||||
The `PouchDBManager` acts as a central singleton. It registers and manages all database instances. If a remote URL is provided, it automatically handles background synchronization.
|
||||
|
||||
```typescript
|
||||
import { PouchDatabaseManager } from '@repo/core-storage';
|
||||
import { PouchDBManager } from '@repo/core-storage';
|
||||
import type { Item } from './types';
|
||||
|
||||
export const dbManager = new PouchDatabaseManager();
|
||||
export const dbManager = new PouchDBManager();
|
||||
|
||||
export const itemDB = dbManager.register<Item>({
|
||||
localName: 'items_db',
|
||||
@@ -184,7 +184,7 @@ export const itemDB = dbManager.register<Item>({
|
||||
|
||||
### 2. CRUD & MongoDB-style Queries
|
||||
|
||||
The registered database returns a `PouchDatabaseWrapper`. This wrapper fully abstracts the raw PouchDB API into clean, Promise-based helpers, auto-handling `_rev` conflicts.
|
||||
The registered database returns a `PouchService` instance. This wrapper fully abstracts the raw PouchDB API into clean, Promise-based helpers, auto-handling `_rev` conflicts.
|
||||
|
||||
| Method | Description |
|
||||
|---|---|
|
||||
@@ -231,6 +231,38 @@ export function InventoryList() {
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Envelope Pattern (`PouchEnvelopeDBManager`)
|
||||
|
||||
If you want to store multiple types of entities (e.g. `items`, `bookings`, `activities`) in a single CouchDB/PouchDB database to simplify sync setup, use the **Envelope Pattern**.
|
||||
|
||||
Instead of `PouchDBManager`, instantiate a `PouchEnvelopeDBManager`. It provides the exact same `PouchService` API (CRUD + Find), but automatically wraps documents into an envelope format internally: `{ _id: "entityName:businessId", entity: "entityName", data: { ... } }`.
|
||||
|
||||
```typescript
|
||||
import { PouchEnvelopeDBManager } from '@repo/core-storage';
|
||||
import type { ItemEntity, BookingEntity } from './types';
|
||||
|
||||
export const envelopeDbManager = new PouchEnvelopeDBManager();
|
||||
|
||||
// Registers to the SAME database 'master_db', but scoped to 'item'
|
||||
export const itemDB = envelopeDbManager.register<ItemEntity>({
|
||||
localName: 'master_db',
|
||||
remoteUrl: 'http://admin:pass@localhost:5984/master_db'
|
||||
}, 'item');
|
||||
|
||||
// Registers to the SAME database 'master_db', but scoped to 'booking'
|
||||
export const bookingDB = envelopeDbManager.register<BookingEntity>({
|
||||
localName: 'master_db',
|
||||
remoteUrl: 'http://admin:pass@localhost:5984/master_db'
|
||||
}, 'booking');
|
||||
|
||||
// API usage remains identical!
|
||||
await itemDB.create({ _id: '123', name: 'Widget' }); // Stored as "item:123"
|
||||
const items = await itemDB.getAll(); // Only returns documents where entity === 'item'
|
||||
|
||||
// Unique to PouchEnvelopeService: Cross-field keyword searching
|
||||
const results = await itemDB.search('widget keyword', ['data.name', 'data.sku']);
|
||||
```
|
||||
|
||||
### ✅ Do's and ❌ Don'ts for PouchDB
|
||||
|
||||
* **✅ DO use `.onChange()`** to make your UI reactive to background cloud syncs.
|
||||
|
||||
Reference in New Issue
Block a user