Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Contributing

This guide provides instructions for contributing to this project.

## Developing

### Local Setup

This project uses Yarn as the package manager.

1. Fork and clone the repo.
1. Install the dependencies.

```shell
yarn install
```

1. Build all the modules

```shell
yarn prepack
```

### Structure

The four published packages are provided in the `packages` directory. Example applications
for the supported platforms are in the examples directory.
2 changes: 1 addition & 1 deletion docs/attachment.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Example usage for capacitor-sqlite (which has escaping issues with certain chara
import { escapeBlob, unescapeBlob } from 'pouchdb-adapter-sqlite-core';
export const db = new DB('cap', {
adapter: 'sqlite',
sqliteImplementation: 'capicator',
sqliteImplementation: 'capacitor',
serializer: {
serialize: (data) => escapeBlob(data),
deserialize: (data) => unescapeBlob(data),
Expand Down
58 changes: 13 additions & 45 deletions examples/capacitor-react-vite/README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,22 @@
# React + TypeScript + Vite
# React + Capacitor - Example PouchDB SQLite App

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
This example shows the use of the pouchdb-adaptor-sqlite plugin in a simple
React application wrapped with Capacitor.

Currently, two official plugins are available:
The example implements a simple list manager, with list items stored in a PouchDB.

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
The database is initialised in src/db.ts, SQLite is only used on mobile platforms
for simplicity.

## Expanding the ESLint configuration
To build:

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default tseslint.config({
extends: [
// Remove ...tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,
],
languageOptions: {
// other options...
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
},
})
```shell
yarn build
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
Sync to Android/IOS, then open the project to build the app:

export default tseslint.config({
plugins: {
// Add the react-x and react-dom plugins
'react-x': reactX,
'react-dom': reactDom,
},
rules: {
// other rules...
// Enable its recommended typescript rules
...reactX.configs['recommended-typescript'].rules,
...reactDom.configs.recommended.rules,
},
})
```shell
npx cap sync
npx cap open android
```
5 changes: 1 addition & 4 deletions examples/capacitor-react-vite/capacitor.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'capica-react-vite',
appName: 'capacitor-react-vite',
webDir: 'dist',
server: {
url: 'http://192.168.0.104:5173/',
},
plugins: {
CapacitorSQLite: {
iosDatabaseLocation: 'Library/CapacitorDatabase',
Expand Down
4 changes: 2 additions & 2 deletions examples/capacitor-react-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"@types/pouchdb": "^6.4.2",
"jeep-sqlite": "^2.8.0",
"pouchdb": "^9.0.0",
"pouchdb-adapter-capacitor-sqlite": "workspace:^",
"pouchdb-adapter-sqlite-core": "workspace:^",
"pouchdb-adapter-capacitor-sqlite": "1.1.2",
"pouchdb-adapter-sqlite-core": "1.1.2",
"pouchdb-core": "^9.0.0",
"pouchdb-find": "^9.0.0",
"pouchdb-replication": "^9.0.0",
Expand Down
68 changes: 33 additions & 35 deletions examples/capacitor-react-vite/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useEffect, useState } from 'react';
import './App.css';
import { db } from './db';
import { db, getAllDocuments, storeDocument } from './db';

function App() {
const [docs, setDocs] = useState<any[]>([]);
const [url, seturl] = useState<string>('');
const [message, setMessage] = useState('');

useEffect(() => {
const init = async () => {
const res = await db.allDocs({ include_docs: true, attachments: true, binary: true });
Expand All @@ -13,45 +14,42 @@ function App() {
init();
}, []);

const storeMessage = async () => {
if (message.trim() === '') return;
const newDoc = {
_id: new Date().toISOString(),
message,
};
await storeDocument(newDoc);
const updatedDocs = await getAllDocuments();
setDocs(updatedDocs);
setMessage('');
};

return (
<div className="App">
<h1>PouchDB Capicator SQLite Test</h1>
<img src={url} />
<button
onClick={async () => {
const doc = await db.get('8b9a4e2fbe3250a9b9294945c507cd98', {
attachments: true,
binary: true,
});
console.log(doc);

const atts = doc._attachments!;
console.log(Object.getPrototypeOf(atts));
const d: Blob = (atts['04.png'] as any).data as Blob;

const url = URL.createObjectURL(d);
seturl(url);
}}
>
retry
</button>
<button
onClick={async () => {
db.destroy();
}}
>
retry
</button>
<p>Status: {docs.length}</p>
<h2>Documents:</h2>
<h1>PouchDB capacitor SQLite Test</h1>

<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Enter a message"
/>
<button
type="button"
onClick={storeMessage}
>Save</button>


<h2>Stored Messages:</h2>
<ul>
{docs.map((doc) => (
<li key={doc._id}>
{doc._id}: {JSON.stringify(doc, null, 2)}
</li>
<li key={doc._id}>{doc.message}</li>
))}
</ul>
</div>
</div>

);
}

Expand Down
56 changes: 35 additions & 21 deletions examples/capacitor-react-vite/src/db.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
import {Capacitor} from '@capacitor/core';
import PouchDB from 'pouchdb';
import capicatorSQLiteAdapter from 'pouchdb-adapter-capacitor-sqlite';
import sqlitePlugn from 'pouchdb-adapter-sqlite-core';
import capacitorSQLiteAdapter from 'pouchdb-adapter-capacitor-sqlite';
import sqlitePlugin from 'pouchdb-adapter-sqlite-core';
import { escapeBlob, unescapeBlob } from 'pouchdb-adapter-sqlite-core';
import { OpenConfig } from 'pouchdb-adapter-sqlite-core/interface';

const DB = PouchDB.plugin(sqlitePlugn).plugin(capicatorSQLiteAdapter);
export const remotedb = new PouchDB('http://192.168.0.104:8080/couchdb/example', {
auth: {
username: 'admin',
password: '123456',
},
});
const DB = PouchDB.plugin(sqlitePlugin).plugin(capacitorSQLiteAdapter);

export const db = new DB('capp2', {
const config: OpenConfig = {
adapter: 'sqlite',
sqliteImplementation: 'capicator',
sqliteImplementation: 'capacitor',
serializer: {
serialize: (data) => {
serialize: async (data) => {
return escapeBlob(data);
},
deserialize: (data) => {
deserialize: async (data) => {
return unescapeBlob(data);
},
},
});
};

export const sync = db.sync(remotedb, { live: true, retry: true });
export let db: PouchDB.Database;

sync.on('change', () => {
console.log('get change');
});
// use browser pouchdb if we're on web, otherwise use capacitor-sqlite
if (Capacitor.getPlatform() === 'web') {
db = new PouchDB('capp2');
} else {
db = new DB('capp2', config);
}

const test = async () => {
// .... do something you want
export const storeDocument = async (doc: any) => {
try {
const response = await db.put(doc);
console.log('Document stored successfully:', response);
} catch (error) {
console.error('Error storing document:', error);
}
};
test();

export const getAllDocuments = async () => {
try {
const result = await db.allDocs({ include_docs: true, attachments: true, binary: true });
return result.rows.map((row) => row.doc);
} catch (error) {
console.error('Error retrieving documents:', error);
return [];
}
};

Loading