├── .gitignore ├── .npmignore ├── src ├── EventIndex.js └── EventStore.js ├── .github └── workflows │ ├── npm-publish.yml │ └── npm-publish-next.yml ├── CONTRIBUTING.md ├── package.json ├── LICENSE ├── example └── index.html ├── readme.md └── CODE_OF_CONDUCT.md /.gitignore: -------------------------------------------------------------------------------- 1 | *sublime* 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *sublime* 2 | node_modules/ 3 | package-lock.json 4 | example 5 | -------------------------------------------------------------------------------- /src/EventIndex.js: -------------------------------------------------------------------------------- 1 | export default class EventIndex { 2 | constructor () { 3 | this._index = null 4 | } 5 | 6 | get () { 7 | return this._index ? this._index.values : [] 8 | } 9 | 10 | updateIndex (oplog) { 11 | this._index = oplog 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Node.js Package 3 | 4 | on: 5 | push: 6 | tags: 7 | - 'v*' 8 | 9 | jobs: 10 | publish-npm: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v2 15 | with: 16 | node-version: 'lts/*' 17 | registry-url: https://registry.npmjs.org/ 18 | - run: npm ci 19 | - run: npm publish 20 | env: 21 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | . 2 | # Contribute 3 | 4 | Please contribute! Here are some things that would be great: 5 | 6 | - [Open an issue!](https://github.com/orbitdb/orbit-db-eventstore/issues/new) 7 | - Open a pull request! 8 | - Say hi! :wave: 9 | 10 | Please note that we have a [Code of Conduct](CODE_OF_CONDUCT.md), and that all activity in the [@OrbitDB](https://github.com/orbitdb) organization falls under it. Read it before you contribute, as being part of this community means that you agree to abide by it. Thanks. 11 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish-next.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Node.js Package (next tag) 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | publish-npm: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: 'lts/*' 17 | registry-url: https://registry.npmjs.org/ 18 | - run: npm ci 19 | - run: | 20 | npm version prerelease --no-git-tag-version \ 21 | --preid=`git rev-parse --short HEAD` 22 | npm publish --tag next 23 | env: 24 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "orbit-db-eventstore", 3 | "version": "2.0.0", 4 | "description": "Eventlog for orbit-db", 5 | "type": "module", 6 | "main": "src/EventStore.js", 7 | "homepage": "https://github.com/orbitdb/orbit-db-eventstore", 8 | "bugs": "https://github.com/orbitdb/orbit-db-eventstore/issues", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/orbitdb/orbit-db-eventstore" 12 | }, 13 | "scripts": { 14 | "lint": "standard", 15 | "lint:fix": "standard --fix" 16 | }, 17 | "keywords": [ 18 | "orbitdb", 19 | "orbit-db", 20 | "eventstore" 21 | ], 22 | "author": "Haad", 23 | "license": "MIT", 24 | "peerDependencies": { 25 | "orbit-db-store": "*" 26 | }, 27 | "localMaintainers": [ 28 | "haad ", 29 | "shamb0t ", 30 | "hajamark " 31 | ], 32 | "devDependencies": { 33 | "standard": "^17.0.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2018 Protocol Labs Inc. 4 | Copyright (c) 2018 Haja Networks Oy 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
Loading...
7 | 8 | 9 | 10 | 11 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/EventStore.js: -------------------------------------------------------------------------------- 1 | import Store from 'orbit-db-store' 2 | import EventIndex from './EventIndex.js' 3 | 4 | // TODO: generalize the Iterator functions and spin to its own module 5 | 6 | export default class EventStore extends Store { 7 | constructor (ipfs, id, dbname, options = {}) { 8 | if (options.Index === undefined) Object.assign(options, { Index: EventIndex }) 9 | super(ipfs, id, dbname, options) 10 | this._type = 'eventlog' 11 | this.events.on('log.op.ADD', (address, hash, payload) => { 12 | this.events.emit('db.append', payload.value) 13 | }) 14 | } 15 | 16 | add (data, options = {}) { 17 | return this._addOperation({ 18 | op: 'ADD', 19 | key: null, 20 | value: data 21 | }, options) 22 | } 23 | 24 | get (hash) { 25 | return this.iterator({ gte: hash, limit: 1 }).collect()[0] 26 | } 27 | 28 | iterator (options) { 29 | const messages = this._query(options) 30 | let currentIndex = 0 31 | const iterator = { 32 | [Symbol.iterator] () { 33 | return this 34 | }, 35 | next () { 36 | let item = { value: null, done: true } 37 | if (currentIndex < messages.length) { 38 | item = { value: messages[currentIndex], done: false } 39 | currentIndex++ 40 | } 41 | return item 42 | }, 43 | collect: () => messages 44 | } 45 | 46 | return iterator 47 | } 48 | 49 | _query (opts) { 50 | if (!opts) opts = {} 51 | 52 | const amount = opts.limit ? (opts.limit > -1 ? opts.limit : this._index.get().length) : 1 // Return 1 if no limit is provided 53 | const events = this._index.get().slice() 54 | let result = [] 55 | 56 | if (opts.gt || opts.gte) { 57 | // Greater than case 58 | result = this._read(events, opts.gt ? opts.gt : opts.gte, amount, !!opts.gte) 59 | } else { 60 | // Lower than and lastN case, search latest first by reversing the sequence 61 | result = this._read(events.reverse(), opts.lt ? opts.lt : opts.lte, amount, opts.lte || !opts.lt).reverse() 62 | } 63 | 64 | if (opts.reverse) { 65 | result.reverse() 66 | } 67 | 68 | return result 69 | } 70 | 71 | _read (ops, hash, amount, inclusive) { 72 | // Find the index of the gt/lt hash, or start from the beginning of the array if not found 73 | const index = ops.map((e) => e.hash).indexOf(hash) 74 | let startIndex = Math.max(index, 0) 75 | // If gte/lte is set, we include the given hash, if not, start from the next element 76 | startIndex += inclusive ? 0 : 1 77 | // Slice the array to its requested size 78 | const res = ops.slice(startIndex).slice(0, amount) 79 | return res 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # orbit-db-eventstore 2 | 3 | [![npm version](https://badge.fury.io/js/orbit-db-eventstore.svg)](https://badge.fury.io/js/orbit-db-eventstore) 4 | [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/orbitdb/Lobby) [![Matrix](https://img.shields.io/badge/matrix-%23orbitdb%3Apermaweb.io-blue.svg)](https://riot.permaweb.io/#/room/#orbitdb:permaweb.io) 5 | 6 | > Append-Only Log database for orbit-db 7 | 8 | An append-only log with traversable history. Useful for *"latest N"* use cases or as a message queue. 9 | 10 | Used in [orbit-db](https://github.com/haadcode/orbit-db). 11 | 12 | ## Table of Contents 13 | 14 | - [Install](#install) 15 | - [Usage](#usage) 16 | - [API](#api) 17 | - [Contributing](#contributing) 18 | - [License](#license) 19 | 20 | ## Install 21 | 22 | This project uses [npm](https://npmjs.com) and [nodejs](https://nodejs.org) 23 | 24 | ```sh 25 | npm install orbit-db ipfs 26 | ``` 27 | 28 | ## Usage 29 | 30 | First, create an instance of OrbitDB: 31 | 32 | ```javascript 33 | import * as IPFS from 'ipfs' 34 | import OrbitDB from 'orbit-db' 35 | 36 | const ipfs = new IPFS() 37 | const orbitdb = await OrbitDB.createInstance(ipfs) 38 | ``` 39 | 40 | Get a log database and add an entry to it: 41 | 42 | ```javascript 43 | const log = await orbitdb.eventlog('haad.posts') 44 | log.add({ name: 'hello world' }) 45 | .then(() => { 46 | const items = log.iterator().collect().map(e => e.payload.value) 47 | items.forEach(e => console.log(e.name)) 48 | // "hello world" 49 | }) 50 | ``` 51 | 52 | Later, when the database contains data, load the history and query when ready: 53 | 54 | ```javascript 55 | const log = await orbitdb.eventlog('haad.posts') 56 | log.events.on('ready', () => { 57 | const items = log.iterator().collect().map(e => e.payload.value) 58 | items.forEach(e => console.log(e.name)) 59 | // "hello world" 60 | }) 61 | ``` 62 | 63 | See [example/index.html](https://github.com/haadcode/orbit-db-eventstore/blob/master/example/index.html) for a detailed example. Note that to run this example, you need to have a local [IPFS daemon](https://dist.ipfs.io/go-ipfs/floodsub-2) [running](https://ipfs.io/docs/getting-started/) at port 5001. 64 | 65 | ## API 66 | 67 | See [orbit-db's API Documenations](https://github.com/haadcode/orbit-db/blob/master/API.md#eventlogname) for full details. 68 | 69 | ## Contributing 70 | 71 | If you think this could be better, please [open an issue](https://github.com/orbitdb/orbit-db-eventstore/issues/new)! 72 | 73 | Please note that all interactions in @orbitdb fall under our [Code of Conduct](CODE_OF_CONDUCT.md). 74 | 75 | Note that tests for this module are in the [`orbit-db`](https://github.com/orbitdb/orbit-db) repository. 76 | 77 | ## License 78 | 79 | [MIT](LICENSE) © 2016-2020 Protocol Labs Inc., Haja Networks Oy 80 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [community@orbitdb.org](mailto:community@orbitdb.org), which goes to all members of the @OrbitDB community team, or to [richardlitt@orbitdb.org](mailto:richardlitt@orbitdb.org), which goes only to [@RichardLitt](https://github.com/RichardLitt) or to [haadcode@orbitdb.org](mailto:haadcode@orbitdb.org), which goes only to [@haadcode](https://github.com/haadcode). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | --------------------------------------------------------------------------------