Skip to content

Commit fa5214e

Browse files
WilsontheWolfRealShadowNova
authored andcommitted
feat: add @joshdb/indexeddb
1 parent 93f64b6 commit fa5214e

19 files changed

+4024
-107
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: indexeddb
2+
org: joshdb
3+
packagePath: packages/indexeddb
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
json: 'docs/api.json'

packages/indexeddb/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.

packages/indexeddb/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<div align="center">
2+
3+
![Josh Logo](https://evie.codes/josh-light.png)
4+
5+
# @joshdb/indexeddb
6+
7+
**A provider for `@joshdb/core`**
8+
9+
[![GitHub](https://img.shields.io/github/license/josh-development/providers)](https://github.com/josh-development/providers/blob/main/LICENSE.md)
10+
[![codecov](https://codecov.io/gh/josh-development/providers/branch/main/graph/badge.svg?token=JnJcjxqT3k)](https://codecov.io/gh/josh-development/providers)
11+
[![npm](https://img.shields.io/npm/v/@joshdb/indexeddb?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/@joshdb/indexeddb)
12+
13+
[![Support Server](https://discord.com/api/guilds/298508738623438848/embed.png?style=banner2)](https://discord.gg/N7ZKH3P)
14+
15+
</div>
16+
17+
## Description
18+
19+
A Josh provider
20+
21+
## Features
22+
23+
- Written in TypeScript
24+
- Offers CommonJS and ESM bundles
25+
- Fully tested
26+
27+
## Installation
28+
29+
You can use the following command to install this package, or replace `npm install` with your package manager of choice.
30+
31+
```sh
32+
npm install @joshdb/indexeddb
33+
```

packages/indexeddb/cliff.toml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
[changelog]
2+
header = """
3+
# Changelog
4+
5+
All notable changes to this project will be documented in this file.
6+
7+
"""
8+
body = """
9+
{% if version %}\
10+
# [{{ version | trim_start_matches(pat="v") }}]\
11+
{% if previous %}\
12+
{% if previous.version %}\
13+
(https://github.com/josh-development/utilities/compare/{{ previous.version }}...{{ version }})\
14+
{% else %}\
15+
(https://github.com/josh-development/utilities/tree/{{ version }})\
16+
{% endif %}\
17+
{% endif %} \
18+
- ({{ timestamp | date(format="%Y-%m-%d") }})
19+
{% else %}\
20+
# [unreleased]
21+
{% endif %}\
22+
{% for group, commits in commits | group_by(attribute="group") %}
23+
## {{ group | upper_first }}
24+
{% for commit in commits %}
25+
- {% if commit.scope %}\
26+
**{{commit.scope}}:** \
27+
{% endif %}\
28+
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}](https://github.com/josh-development/utilities/commit/{{ commit.id }}))\
29+
{% if commit.breaking %}\
30+
31+
32+
{% raw %} {% endraw %} ### 💥 Breaking Changes:
33+
\
34+
{% for breakingChange in commit.footers %}\
35+
{% raw %} {% endraw %} - {{ breakingChange }}
36+
\
37+
{% endfor %}\
38+
{% endif %}\
39+
{% endfor %}
40+
{% endfor %}
41+
42+
"""
43+
trim = true
44+
footer = ""
45+
46+
[git]
47+
conventional_commits = true
48+
filter_unconventional = true
49+
commit_parsers = [
50+
{ message = "^feat", group = "🚀 Features" },
51+
{ message = "^fix", group = "🐛 Bug Fixes" },
52+
{ message = "^docs", group = "📝 Documentation" },
53+
{ message = "^perf", group = "🏃 Performance" },
54+
{ message = "^refactor", group = "🏠 Refactor" },
55+
{ message = ".*deprecated", body = ".*deprecated", group = "🚨 Deprecation" },
56+
{ message = "^revert", skip = true },
57+
{ message = "^style", group = "🪞 Styling" },
58+
{ message = "^test", group = "🧪 Testing" },
59+
{ message = "^chore", skip = true },
60+
{ message = "^ci", skip = true },
61+
{ body = ".*security", group = "🛡️ Security" },
62+
]
63+
filter_commits = true
64+
tag_pattern = "@joshdb/indexeddb@[0-9]*"
65+
ignore_tags = ""
66+
topo_order = false
67+
sort_commits = "newest"

packages/indexeddb/jest.config.mjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/** @type {import('@jest/types').Config.InitialOptions} */
2+
const config = {
3+
displayName: 'unit test',
4+
preset: 'ts-jest',
5+
testMatch: ['<rootDir>/tests/**/*.test.ts'],
6+
collectCoverageFrom: ['<rootDir>/src/**/*.ts'],
7+
setupFilesAfterEnv: ['jest-extended/all'],
8+
globals: {
9+
'ts-jest': {
10+
tsconfig: '<rootDir>/tests/tsconfig.json'
11+
}
12+
},
13+
coveragePathIgnorePatterns: []
14+
};
15+
16+
export default config;

packages/indexeddb/package.json

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"name": "@joshdb/indexeddb",
3+
"version": "2.0.0",
4+
"description": "A Josh provider",
5+
"author": "Évelyne Lachance <[email protected]> (https://evie.codes/)",
6+
"contributors": [
7+
"WilsontheWolf (https://wilson.antti.codes/)",
8+
"DanCodes <[email protected]> (https://dancodes.online/)"
9+
],
10+
"license": "Apache-2.0",
11+
"main": "dist/index.js",
12+
"module": "dist/index.mjs",
13+
"browser": "dist/index.umd.js",
14+
"unpkg": "dist/index.umd.js",
15+
"types": "dist/index.d.ts",
16+
"exports": {
17+
"import": "./dist/index.mjs",
18+
"require": "./dist/index.js",
19+
"types": "./dist/index.d.ts"
20+
},
21+
"sideEffects": false,
22+
"scripts": {
23+
"test": "jest --verbose",
24+
"docs": "typedoc-json-parser",
25+
"lint": "eslint src tests --ext ts --fix -c ../../.eslintrc",
26+
"build": "rollup -c rollup.config.ts",
27+
"prepack": "rollup-type-bundler",
28+
"bump": "cliff-jumper",
29+
"check-update": "cliff-jumper --dry-run"
30+
},
31+
"dependencies": {
32+
"@joshdb/provider": "1.1.0-next.24ef775.0",
33+
"property-helpers": "^1.1.0"
34+
},
35+
"devDependencies": {
36+
"@favware/cliff-jumper": "^1.8.5",
37+
"@favware/rollup-type-bundler": "^1.0.9",
38+
"fake-indexeddb": "^4.0.0",
39+
"jest": "^28.1.3",
40+
"typedoc": "^0.23.9",
41+
"typedoc-json-parser": "^2.0.1"
42+
},
43+
"repository": {
44+
"type": "git",
45+
"url": "git+https://github.com/josh-development/providers.git"
46+
},
47+
"files": [
48+
"dist",
49+
"!dist/*tsbuildinfo"
50+
],
51+
"engines": {
52+
"node": ">=16.6.0",
53+
"npm": ">=7.0.0"
54+
},
55+
"keywords": [],
56+
"bugs": {
57+
"url": "https://github.com/josh-development/providers/issues"
58+
},
59+
"homepage": "https://josh.evie.dev",
60+
"publishConfig": {
61+
"access": "public"
62+
}
63+
}

packages/indexeddb/rollup.config.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { resolve } from 'path';
2+
import cleaner from 'rollup-plugin-cleaner';
3+
import typescript from 'rollup-plugin-typescript2';
4+
import versionInjector from 'rollup-plugin-version-injector';
5+
6+
export default {
7+
input: 'src/index.ts',
8+
output: [
9+
{
10+
file: './dist/index.js',
11+
format: 'cjs',
12+
exports: 'named',
13+
sourcemap: true
14+
},
15+
{
16+
file: './dist/index.mjs',
17+
format: 'es',
18+
exports: 'named',
19+
sourcemap: true
20+
},
21+
{
22+
file: './dist/index.umd.js',
23+
format: 'umd',
24+
name: 'JoshIndexedDBProvider',
25+
exports: 'named',
26+
sourcemap: true,
27+
globals: {
28+
'@joshdb/provider': 'JoshProvider'
29+
}
30+
}
31+
],
32+
external: ['@joshdb/provider'],
33+
plugins: [cleaner({ targets: ['./dist'] }), typescript({ tsconfig: resolve(process.cwd(), 'src', 'tsconfig.json') }), versionInjector()]
34+
};

packages/indexeddb/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './lib/IndexedDBProvider';
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
export default class DbHandler {
2+
private idb: IDBFactory;
3+
private db!: IDBDatabase;
4+
5+
public constructor() {
6+
if (!indexedDB) {
7+
throw new Error("Your browser doesn't support a stable version of IndexedDB. Josh is unable to run without one.");
8+
}
9+
10+
this.idb = indexedDB;
11+
}
12+
13+
public init() {
14+
const request = this.idb.open('josh');
15+
16+
return new Promise<void>((resolve, reject) => {
17+
request.onerror = reject;
18+
19+
request.onupgradeneeded = () => {
20+
const db = request.result;
21+
22+
if (!db.objectStoreNames.contains('store')) {
23+
db.createObjectStore('store', { keyPath: 'key' });
24+
}
25+
};
26+
27+
request.onsuccess = () => {
28+
this.db = request.result;
29+
resolve();
30+
};
31+
});
32+
}
33+
34+
public async set(key: string, value: unknown) {
35+
const all = this.open();
36+
const doc = {
37+
key,
38+
value
39+
};
40+
41+
const request = all.put(doc);
42+
43+
await this.handleEvents(request);
44+
}
45+
46+
public async get(key: string) {
47+
const all = this.open();
48+
const request = all.get(key);
49+
const result = await this.handleEvents(request);
50+
51+
// @ts-ignore it exists f you TS
52+
return result?.value;
53+
}
54+
55+
public async getAll() {
56+
const all = this.open();
57+
const request = all.getAll();
58+
const docs = await this.handleEvents(request);
59+
const final = {};
60+
61+
// @ts-ignore TS GO AWAY
62+
docs.forEach((x) => {
63+
// @ts-ignore TS GO AWAY
64+
final[x.key] = x.value;
65+
});
66+
67+
return final;
68+
}
69+
70+
public async getKeys() {
71+
const all = this.open();
72+
const request = all.getAllKeys();
73+
74+
return this.handleEvents(request);
75+
}
76+
77+
public async count() {
78+
const all = this.open();
79+
const request = all.count();
80+
const data = await this.handleEvents(request);
81+
82+
if (typeof data !== 'number') throw new Error('Something is amiss!!!');
83+
84+
return data;
85+
}
86+
87+
public async delete(key: string) {
88+
const all = this.open();
89+
const request = all.delete(key);
90+
91+
return this.handleEvents(request);
92+
}
93+
94+
public async clear() {
95+
const all = this.open();
96+
const request = all.clear();
97+
98+
return this.handleEvents(request);
99+
}
100+
101+
public async has(key: string) {
102+
return (await this.get(key)) !== undefined;
103+
}
104+
105+
private handleEvents(request: IDBRequest) {
106+
return new Promise((res, rej) => {
107+
request.onsuccess = () => {
108+
res(request.result);
109+
};
110+
111+
request.onerror = () => {
112+
rej(new Error(request.error?.toString()));
113+
};
114+
});
115+
}
116+
117+
private open() {
118+
const transaction = this.db.transaction('store', 'readwrite');
119+
const all = transaction.objectStore('store');
120+
121+
return all;
122+
}
123+
}

0 commit comments

Comments
 (0)