@tannyuld/ridbf
v0.0.1
Published
Readonly Index based DB Fetcher - A readonly wrapper for native IDB api with checksum integrity check, and direct server fetch.
Readme
RIDBF - Readonly Indexed Database Fetcher
This is an experimental, minimal, and straightforward native IDB API wrapper that grants fetch capabilities.
Why?
Because I wanted a way to use GitHub Pages to host a dynamic blog site that does more than just parse static files.
How to use it?
Structure your data using a domain type and a corresponding schema.
The schema is a const object of type RIDBSchema<T>, where the generic parameter T is the respective domain type.
The field names in the schema must match those of the domain type.
The order of the fields determines the order in which data is parsed from the raw file.
interface BlogPost {
title: string,
date: Date,
tags?: string[],
content: string
}
export const BlogPostSchema: RIDBSchema<BlogPost> = [
"title",
"date",
"tags",
"content",
] as const;Any field can be indexed by wrapping it in an object, where the key is the field name and the value is of type IDBIndexParameters.
export const BlogPostSchema: RIDBSchema<BlogPost> = [
{ title: {unique: false} },
"date",
"tags",
"content",
] as const;In the example above, the title field is set as a non-unique index.
Open a handle using the RIDBHandle.open(...) function.
const handle = RIDBHandle.open("blogpost", BlogPostSchema);The fetch method can be used to retrieve data from the same host server.
const handle = RIDBHandle.open("blogpost", BlogPostSchema);
await handle.fetch();The fetch method initially requests a file called blogpost.ridbi (Readonly Indexed Database Integrity), which contains an integrity control string. This can literally be anything, a simple integer or a SHA-256 checksum. After the integrity file is fetched from the server, the method compares it against the last valid stored integrity string. If they do not match, it fetches the blogpost.ridb file from the server and saves the parsed result into the browser's IndexedDB. The next time it runs, if the integrity check matches, the locally cached IndexedDB data is used instead.
Fetch method, initially request a file called blogpost.ridbi (Readonly indexed database integrity) which has some integrity control string. It can be literaly anything, an simple integer, a SHA-256 Cheksum. After integrity file is fetched from the server, fetch method compare it with the last valid integrity. If they don't match, then it fetches blogpost.ridb file from the server and save the result to idb of browser. Next time if integrity check match, indexed database is used.
Here are example .ridb and .ridbi files for the BlogPost example.
This is my first blogpost using ridbf!
2026-6-4
[First,TS,js,ridb]
This is my first blogpost using ridb package built with ts.
And the best part of it it support multiline fields. [\]
But it does not support complex types like .md or images. [\]
Maybe on a day which I am not lazy, I will implement it.[\]
Second post#2
2026-06-04
This is just to demonstrate with ridb, so this post isn't that important. It is so insignificant that I didn't even add any tags.
Third demo post#3
2026-06-04
[Demo]
This demo is to demonstrate, how html elements are renderd inside an actual html page. So here are some nice tips about hobby gardening.
<p>Spring is here again, and that means it is time to get back out into the garden. Over the years I have picked up a handful of habits that make a real difference, so I thought I would gather my favorites into a single list.</p>[\]
[\]
<h2>The List</h2>[\]
<ol>[\]
<li>Test your soil before planting anything.</li>[\]
<li>Water in the early morning to reduce evaporation.</li>[\]
<li>Mulch generously to retain moisture and suppress weeds.</li>[\]
<li>Rotate crops each season to keep the soil healthy.</li>[\]
<li>Choose plants suited to your local climate.</li>[\]
<li>Prune dead or damaged growth regularly.</li>[\]
<li>Attract pollinators with a mix of flowering plants.</li>[\]
<li>Avoid overwatering; check soil moisture with your finger first.</li>[\]
<li>Compost kitchen scraps to enrich your soil naturally.</li>[\]
<li>Be patient — most gardens take a few seasons to hit their stride.</li>[\]
</ol>[\]
[\]
<p>None of these tips are complicated on their own, but together they add up to a garden that is healthier and easier to maintain. Happy planting!</p>[\]This is how blogpost.ridbi file looks like for the example.
b8084eafa26d8ebfed980eb9e46f57c24dc0f5cae4164ef100bc6b30572817f6Note that while I use a SHA-256 checksum here, you don't have to. You just need to ensure that whenever the data file changes, the integrity string changes as well.
Every line corresponds to a field in the schema.
A field can be skipped by leaving the line empty.
Multiple lines can be merged into a single field using the \ character at the end of merging lines except for the first line.
The # character denotes a comment, and any line starting with it is skipped entirely.
All of these special characters can be escaped with an extra \. For example:
All of these signs can be escaped with an extra \, an example of this:
#This line is skipped
\#This line is not skipped and starts with #
This line and the next line will be merged together.
Second line.\
Following line will not merged with this one.
This is an indipendent line.\\Sometimes cached integrity or data files can cause problems. Therefore, the handle can be opened with custom fetch properties like this:
const handle = RIDBHandle.open("blogpost", BlogPostSchema, { dataCache: CacheType.NoCache, integrityCache: CacheType.NoCache });It also supports a custom path for the server it is fetching from:
const handle = RIDBHandle.open("blogpost", BlogPostSchema, { customPath: "../db/blogpost_file"});The handle can then be used as a wrapper for all read operations:
const handle = RIDBHandle.open("blogpost", BlogPostSchema);
await handle.fetch();
const allBlogs: BlogPost[] = await handle.findAll();
const firstBlog: BlogPost = await handle.findById(0);
// Only indexed fields on the schema can be used as index fields for this method.
const findByIndex: BlogPost = await handle.findByIndex("title", "My very first blogpost.");