Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/reseau-constellation/bohr-db
Guaranteed specified types in orbit-db databases
https://github.com/reseau-constellation/bohr-db
Last synced: about 1 month ago
JSON representation
Guaranteed specified types in orbit-db databases
- Host: GitHub
- URL: https://github.com/reseau-constellation/bohr-db
- Owner: reseau-constellation
- License: agpl-3.0
- Created: 2023-09-30T14:25:21.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-11-02T01:05:52.000Z (about 1 month ago)
- Last Synced: 2024-11-08T10:04:05.794Z (about 1 month ago)
- Language: TypeScript
- Size: 565 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Bohr-DB
Discrete types for your orbit-dbs.[![Tests Bohr-DB](https://github.com/reseau-constellation/bohr-db/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/reseau-constellation/bohr-db/actions/workflows/tests.yml)
[![codecov](https://codecov.io/gh/reseau-constellation/bohr-db/graph/badge.svg?token=LjBS0gKh6n)](https://codecov.io/gh/reseau-constellation/bohr-db)## Installation
```
$ pnpm add @constl/bohr-db
```
## Introduction
Bohr-DB brings both **TypeScript and runtime-checked types to your orbit-db databases**, so that you can be sure that you'll only receive values that correspond to your specified data schema.Borh-DB uses AJV to check for data validity behind the scenes. It wraps around existing orbit-db databases with a proxy, so you can use typed Borh-DB databases as a **drop-in and type-safe replacement for the original orbit-db databases** in your code.
Note: `KeyValue` also offers the additional property `.allAsJSON()`, which returns a key, value object instead of a list of entries.
## Why is it called Bohr-DB?
...because now your orbits can only take on [deterministic values](https://en.wikipedia.org/wiki/Bohr_model).## Support
Borh-DB currently supports the orbit-db `KeyValue`, as well as the `Feed`, `Set` and `OrderedKeyValue` databases from `@constl/orbit-db-kuiper`. Pull requests for additional db types are of course welcome!## Examples
Below are a few examples of `bohr-db` with `KeyValue` and `Set` databases. See the test folder for examples with other orbit-db database types.### Set
As simple example with `Set`:
```ts
import { createOrbit } from "@orbitdb/core";
import { registerAll } from "@constl/orbit-db-kuiper";import { typedSet } from "@constl/bohr-db";
// Register orbit-db-kuiper database types. IMPORTANT - must call before creating orbit instance !
registerAll();const orbit = await createOrbit({ ipfs })
const db = await orbit.open({ type: "set" });
const typedDB = typedSet({
db,
schema: numericSchema,
}); // Is exactly the same as `db`, but now type-safeconsole.log(typedDB.type) // "set"
// Add valid values
await typedDB.add(1);
await typedDB.add(2);
const all = await typedDB.all(); // [1, 2]// Invalid values are not added
await typedDB.add("not a number") // throws both TypeScript and runtime errors !// Even invalid values somehow added to the log (already present, or received from a peer) will not appear in the data
// Force write invalid value to underlying orbit-db database
await db.add("not a number");
await typedDB.all() // Yay !! Still [1, 2]
```Any `ajv` schema can be used, for more complex data types:
```ts
type structure = {
a: number;
b?: string;
};
const objectSchema: JSONSchemaType = {
type: "object",
properties: {
a: { type: "number" },
b: { type: "string", nullable: true },
},
required: ["a"],
};const db = await orbit.open({ type: "set" });
const typedDB = typedSet({
db,
schema: objectSchema,
});// Valid data
await typedDB.add({ a: 1, b: "c" });// Error !!
await typedDB.add({ a: 1, b: 2 });```
### KeyValue
A more complex example with `KeyValue`:
```ts
import { typedKeyValue } from "@constl/bohr-db";type structure = { a: number, b: { c: string, d?: number } };
const schema: JSONSchemaType> = {
type: "object",
properties: {
a: { type: "number", nullable: true },
b: {
type: "object",
properties: {
c: { type: "string" },
d: { type: "number", nullable: true}
}
nullable: true,
required: []
}
},
required: [],
};const db = await orbit.open({ type: "keyvalue" });
const typedDB = typedKeyValue({
db,
schema: objectSchema,
});// Add valid data
await typedDB.put("a", 1);
await typedDB.put("b", { c: 1, d: "e" });const values = await typedDB.allAsJSON();
// Invalid data
await typedDB.put("a", "text") // Error !!```