https://github.com/compulim/bookstore
A data storage pattern for Azure Blob Storage
https://github.com/compulim/bookstore
Last synced: 4 days ago
JSON representation
A data storage pattern for Azure Blob Storage
- Host: GitHub
- URL: https://github.com/compulim/bookstore
- Owner: compulim
- Created: 2018-03-16T08:24:22.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-03-26T03:29:00.000Z (about 6 years ago)
- Last Synced: 2025-04-21T07:42:37.204Z (29 days ago)
- Language: JavaScript
- Homepage:
- Size: 478 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
```
_ _ _
| |__ ___ ___ | | _____| |_ ___ _ __ ___
| '_ \ / _ \ / _ \| |/ / __| __/ _ \| '__/ _ \
| |_) | (_) | (_) | <\__ \ || (_) | | | __/
|_.__/ \___/ \___/|_|\_\___/\__\___/|_| \___|```
A small data framework for collaborative list editing using Azure Blob Storage and Redis.
# What is different than traditional CRUD + cache?
- Content and summary
- Summary is computed from content, via a summarizer function
- When content is updated, only summary is broadcasted via Redis to other nodes
- List will fetch all summaries, without content
- List is cheap, `O(1)`
- Update is done thru lock-update-unlock pattern with updater function
- Updater function can be programmed as optimistic or pessimistic concurrency
- We believe this model makes concurrency issues a little bit easier to handle`bookstore` is designed to be exposed over Web Socket and Server-Sent Events.
# How to use
For production build, `npm install bookstore`. For development build, `npm install bookstore@master`.
For peer dependencies, you will also need `npm install azure-storage@2 redis`.
```js
const { createBlobService } = require('azure-storage');
const { createClient } = require('redis');
const updateIn = require('simple-update-in');
const createBook, { createPubSubUsingRedis, createStorageUsingAzureStorage } = require('bookstore');const blobService = createBlobService(
process.env.AZURE_STORAGE_ACCOUNT,
process.env.AZURE_STORAGE_ACCESS_KEY
);const publishRedis = createClient();
const subscribeRedis = publishRedis.duplicate();const book = createBook(
({ x, y }) => ({ sum: x + y }),
{
...createPubSubUsingRedis(publishRedis, subscribeRedis, 'blob-container-name'),
...createStorageUsingAzureStorage(blobService, 'blob-container-name')
}
);await book.create('page-0', { x: 1, y: 2 });
// Listing summary of all pages
// { 'page-0': {
// summary: { sum: 3 }
// } }
await book.list();// Getting the content of the page
// { x: 1, y: 2 }
await book.get('page-0');// Update a page
// We use `simple-update-in` and updater function for handling concurrency
await book.update('page-0', content => updateIn(content, ['x'], () => 3));// "change" event emitted when update broadcast on Redis
// Only summaries are sent over Redis
book.subscribe(({ id, summary }) => {
console.log(id); // 'page-0'
console.log(summary); // { sum: 5 }
});// Listing summary of all pages again, with new changes
// { 'page-0': {
// summary: { sum: 5 }
// } }
await book.list();// Delete a page
await book.del('page-0');
```## Peer requirements
Instead of using Blob via Azure Storage and Pub-sub via Redis, you can also use other services as long as they met the requirements:
- Storage
- `create(id, content, summary)`: Create a new blob with content and summary
- `del(id)`: Delete a blob
- `get(id)`: Read a blob content
- `list()`: List all blob summaries, without reading the actual content
- `update(id, updater)`: Update an existing blob via an updater function, using lock to prevent dirty read
- `updater: ({ content, summary }) => ({ content, summary })`
- Pub-sub
- `publish(content)`: Publish to a predefined topic
- `subscribe(callback: content => void): () => void`: Subscribe to a predefined topic via callback, will return a function for unsubscribe
- `callback` will be called if content is updated (via `Object.is`) and summary has kept the same# Contributions
Like us? [Star](https://github.com/compulim/bookstore/stargazers) us.
Want to make it better? [File](https://github.com/compulim/bookstore/issues) us an issue.
Don't like something you see? [Submit](https://github.com/compulim/bookstore/pulls) a pull request.