Browse Source

Version 0.2.0

master v0.2.0
Ezerous 4 years ago
parent
commit
4398029136
  1. 14
      package.json
  2. 1
      src/Breeze.js
  3. 29
      src/breezeStatus/breezeStatusReducer.js
  4. 4
      src/breezeStatus/breezeStatusSaga.js
  5. 4
      src/constants.js
  6. 20
      src/index.js
  7. 20
      src/ipfs/ipfsReducer.js
  8. 2
      src/misc/mergeUtils.js
  9. 5
      src/orbit/orbitActions.js
  10. 2
      src/orbit/orbitConstants.js
  11. 18
      src/orbit/orbitMiddleware.js
  12. 28
      src/orbit/orbitReducer.js
  13. 72
      src/orbit/orbitSaga.js
  14. 61
      src/orbit/orbitStatusSaga.js
  15. 2
      src/orbit/orbitUtils.js
  16. 816
      yarn.lock

14
package.json

@ -1,17 +1,17 @@
{ {
"name": "@ezerous/breeze", "name": "@ezerous/breeze",
"version": "0.1.1", "version": "0.2.0",
"description": "A reactive data-store for OrbitDB.", "description": "A reactive data-store for OrbitDB.",
"license": "MIT", "license": "MIT",
"author": "Ezerous <ezerous@gmail.com>", "author": "Ezerous <ezerous@gmail.com>",
"main": "src/index.js", "main": "src/index.js",
"repository": "github:Ezerous/breeze", "repository": "github:Ezerous/breeze",
"dependencies": { "dependencies": {
"deepmerge": "4.2.2", "deepmerge": "~4.2.2",
"ipfs": "0.50.1", "ipfs": "~0.50.2",
"is-plain-object": "4.1.1", "is-plain-object": "~5.0.0",
"orbit-db": "0.25.1", "orbit-db": "~0.26.0",
"orbit-db-identity-provider": "0.3.1", "orbit-db-identity-provider": "~0.3.1",
"redux-saga": "1.1.3" "redux-saga": "~1.1.3"
} }
} }

1
src/Breeze.js

@ -25,7 +25,6 @@ class Breeze {
this.web3 = options.web3; this.web3 = options.web3;
this.ipfs = {} // To be initialized in ipfsSaga this.ipfs = {} // To be initialized in ipfsSaga
this.orbit = {} // To be initialized in orbitSaga this.orbit = {} // To be initialized in orbitSaga
this.orbitDatabases = {};
this.ipfsOptions = options.ipfs; this.ipfsOptions = options.ipfs;
this.orbitOptions = options.orbit; this.orbitOptions = options.orbit;

29
src/breezeStatus/breezeStatusReducer.js

@ -1,20 +1,33 @@
import * as BreezeActions from './breezeActions' import { STATUS_INITIALIZING, STATUS_INITIALIZED, STATUS_FAILED } from "../constants";
import { BREEZE_INITIALIZING,BREEZE_INITIALIZED, BREEZE_FAILED } from "./breezeActions";
const initialState = { const initialState = {
initialized: false status: STATUS_INITIALIZING
} }
const breezeStatusReducer = (state = initialState, action) => { const breezeStatusReducer = (state = initialState, action) => {
/* /*
* Breeze Status * Breeze Status
*/ */
if (action.type === BreezeActions.BREEZE_INITIALIZED) { switch (action.type) {
return { case BREEZE_INITIALIZING:
...state, return {
initialized: true ...state,
} status: STATUS_INITIALIZING
};
case BREEZE_INITIALIZED:
return {
...state,
status: STATUS_INITIALIZED
};
case BREEZE_FAILED:
return {
...state,
status: STATUS_FAILED
};
default:
return state;
} }
return state
} }
export default breezeStatusReducer export default breezeStatusReducer

4
src/breezeStatus/breezeStatusSaga.js

@ -6,7 +6,7 @@ import { addOrbitIdentityProvider } from '../orbit/orbitSaga';
const LOGGING_PREFIX = 'breezeStatusSaga: '; const LOGGING_PREFIX = 'breezeStatusSaga: ';
export function * initializeBreeze (action) { function * initializeBreeze (action) {
try { try {
const { breeze } = action; const { breeze } = action;
@ -31,7 +31,7 @@ export function * initializeBreeze (action) {
} }
function * breezeStatusSaga () { function * breezeStatusSaga () {
yield takeLatest(BreezeActions.BREEZE_INITIALIZING, initializeBreeze) yield takeLatest(BreezeActions.BREEZE_INITIALIZING, initializeBreeze);
} }
export default breezeStatusSaga export default breezeStatusSaga

4
src/constants.js

@ -0,0 +1,4 @@
// Status
export const STATUS_INITIALIZING = 'initializing';
export const STATUS_INITIALIZED = 'initialized';
export const STATUS_FAILED = 'failed';

20
src/index.js

@ -1,7 +1,7 @@
import Breeze from './Breeze.js' import Breeze from './Breeze.js'
import breezeStatusReducer from './breezeStatus/breezeStatusReducer'; import breezeStatusReducer from './breezeStatus/breezeStatusReducer';
import ipfsReducer from "./ipfs/ipfsReducer"; import ipfsReducer from './ipfs/ipfsReducer';
import orbitReducer from "./orbit/orbitReducer"; import orbitReducer from './orbit/orbitReducer';
import breezeStatusSaga from './breezeStatus/breezeStatusSaga'; import breezeStatusSaga from './breezeStatus/breezeStatusSaga';
import orbitSaga from "./orbit/orbitSaga"; import orbitSaga from "./orbit/orbitSaga";
@ -9,9 +9,8 @@ import orbitSaga from "./orbit/orbitSaga";
import * as BreezeActions from './breezeStatus/breezeActions' import * as BreezeActions from './breezeStatus/breezeActions'
import * as OrbitActions from './orbit/orbitActions' import * as OrbitActions from './orbit/orbitActions'
import * as orbitTypes from './orbit/constants' import * as breezeConstants from './constants'
import orbitMiddleware from "./orbit/orbitMiddleware"; import * as orbitConstants from './orbit/orbitConstants'
import orbitStatusSaga from "./orbit/orbitStatusSaga";
const breezeReducers = { const breezeReducers = {
breezeStatus: breezeStatusReducer, breezeStatus: breezeStatusReducer,
@ -19,14 +18,9 @@ const breezeReducers = {
orbit: orbitReducer orbit: orbitReducer
} }
const breezeMiddlewares = [
orbitMiddleware
]
const breezeSagas = [ const breezeSagas = [
breezeStatusSaga, breezeStatusSaga,
orbitSaga, orbitSaga
orbitStatusSaga
] ]
const breezeActions = { const breezeActions = {
@ -36,10 +30,10 @@ const breezeActions = {
export { export {
Breeze, Breeze,
breezeConstants,
breezeActions, breezeActions,
breezeReducers, breezeReducers,
breezeMiddlewares,
breezeSagas, breezeSagas,
orbitTypes orbitConstants
} }

20
src/ipfs/ipfsReducer.js

@ -1,15 +1,29 @@
import { IPFS_INITIALIZED } from "./ipfsActions"; import { IPFS_INITIALIZING , IPFS_INITIALIZED, IPFS_FAILED } from "./ipfsActions";
import { STATUS_INITIALIZING, STATUS_INITIALIZED, STATUS_FAILED } from "../constants";
const initialState = { const initialState = {
initialized: false, status: STATUS_INITIALIZING
}; };
const ipfsReducer = (state = initialState, action) => { const ipfsReducer = (state = initialState, action) => {
/*
* IPFS Status
*/
switch (action.type) { switch (action.type) {
case IPFS_INITIALIZING:
return {
...state,
status: STATUS_INITIALIZING
};
case IPFS_INITIALIZED: case IPFS_INITIALIZED:
return { return {
...state, ...state,
initialized: true, status: STATUS_INITIALIZED
};
case IPFS_FAILED:
return {
...state,
status: STATUS_FAILED
}; };
default: default:
return state; return state;

2
src/misc/mergeUtils.js

@ -1,5 +1,5 @@
const merge = require('deepmerge'); const merge = require('deepmerge');
import isPlainObject from 'is-plain-object'; import { isPlainObject } from 'is-plain-object';
export default function (defaultOptions, customOptions) { export default function (defaultOptions, customOptions) {
return merge(defaultOptions, customOptions, { return merge(defaultOptions, customOptions, {

5
src/orbit/orbitActions.js

@ -1,9 +1,14 @@
// OrbitDB Status
export const ORBIT_INITIALIZING = 'ORBIT_INITIALIZING'; export const ORBIT_INITIALIZING = 'ORBIT_INITIALIZING';
export const ORBIT_INITIALIZED = 'ORBIT_INITIALIZED'; export const ORBIT_INITIALIZED = 'ORBIT_INITIALIZED';
export const ORBIT_INIT_FAILED = 'ORBIT_INIT_FAILED'; export const ORBIT_INIT_FAILED = 'ORBIT_INIT_FAILED';
// Identity Provider Status
export const ORBIT_IDENTITY_PROVIDER_ADD = 'ORBIT_IDENTITY_PROVIDER_ADD'; export const ORBIT_IDENTITY_PROVIDER_ADD = 'ORBIT_IDENTITY_PROVIDER_ADD';
export const ORBIT_IDENTITY_PROVIDER_ADDED = 'ORBIT_IDENTITY_PROVIDER_ADDED'; export const ORBIT_IDENTITY_PROVIDER_ADDED = 'ORBIT_IDENTITY_PROVIDER_ADDED';
export const ORBIT_IDENTITY_PROVIDER_FAILED = 'ORBIT_IDENTITY_PROVIDER_FAILED'; export const ORBIT_IDENTITY_PROVIDER_FAILED = 'ORBIT_IDENTITY_PROVIDER_FAILED';
// Database Status
export const ORBIT_DATABASE_CREATING = 'ORBIT_DATABASE_CREATING'; export const ORBIT_DATABASE_CREATING = 'ORBIT_DATABASE_CREATING';
export const ORBIT_DATABASE_CREATED = 'ORBIT_DATABASE_CREATED'; export const ORBIT_DATABASE_CREATED = 'ORBIT_DATABASE_CREATED';
export const ORBIT_DATABASE_FAILED = 'ORBIT_DATABASE_FAILED'; export const ORBIT_DATABASE_FAILED = 'ORBIT_DATABASE_FAILED';

2
src/orbit/constants.js → src/orbit/orbitConstants.js

@ -5,7 +5,7 @@ export const ORBIT_TYPE_KEYVALUE = 'keyvalue';
export const ORBIT_TYPE_DOCS = 'docs'; export const ORBIT_TYPE_DOCS = 'docs';
export const ORBIT_TYPE_COUNTER = 'counter'; export const ORBIT_TYPE_COUNTER = 'counter';
// OrbitDB statuses // OrbitDB Databases status
export const DB_STATUS_INIT = 'init'; export const DB_STATUS_INIT = 'init';
export const DB_STATUS_READY = 'ready'; export const DB_STATUS_READY = 'ready';
export const DB_STATUS_REPLICATING = 'replicating'; export const DB_STATUS_REPLICATING = 'replicating';

18
src/orbit/orbitMiddleware.js

@ -1,18 +0,0 @@
import {ORBIT_DATABASE_CREATED} from "./orbitActions";
import {BREEZE_INITIALIZED} from "../breezeStatus/breezeActions";
export const orbitMiddleware = breezeInstance => () => next => action => {
const { type } = action
if (type === BREEZE_INITIALIZED)
breezeInstance = action.breeze
if (type === ORBIT_DATABASE_CREATED) {
const { database } = action;
breezeInstance.orbitDatabases[database.id] = database;
}
return next(action);
}
const initializedMiddleware = orbitMiddleware(undefined)
export default initializedMiddleware

28
src/orbit/orbitReducer.js

@ -3,26 +3,41 @@ import {
ORBIT_DATABASE_READY, ORBIT_DATABASE_READY,
ORBIT_DATABASE_REPLICATED, ORBIT_DATABASE_REPLICATED,
ORBIT_DATABASE_REPLICATING, ORBIT_DATABASE_REPLICATING,
ORBIT_INITIALIZED ORBIT_INITIALIZING,
ORBIT_INITIALIZED,
ORBIT_INIT_FAILED
} from "./orbitActions"; } from "./orbitActions";
import { import {
DB_STATUS_INIT, DB_STATUS_INIT,
DB_STATUS_READY, DB_STATUS_READY,
DB_STATUS_REPLICATED, DB_STATUS_REPLICATED,
DB_STATUS_REPLICATING DB_STATUS_REPLICATING,
} from "./constants"; } from "./orbitConstants";
import {STATUS_INITIALIZING, STATUS_INITIALIZED, STATUS_FAILED } from "../constants";
const initialState = { const initialState = {
initialized: false, status: STATUS_INITIALIZING,
databases: {} databases: {}
}; };
const orbitReducer = (state = initialState, action) => { const orbitReducer = (state = initialState, action) => {
switch (action.type) { switch (action.type) {
case ORBIT_INITIALIZING:
return {
...state,
status: STATUS_INITIALIZING
};
case ORBIT_INITIALIZED: case ORBIT_INITIALIZED:
return { return {
...state, ...state,
initialized: true, status: STATUS_INITIALIZED
};
case ORBIT_INIT_FAILED:
return {
...state,
status: STATUS_FAILED
}; };
case ORBIT_DATABASE_CREATED: case ORBIT_DATABASE_CREATED:
return newDatabasesStatus(state, action, DB_STATUS_INIT); return newDatabasesStatus(state, action, DB_STATUS_INIT);
@ -44,7 +59,8 @@ function newDatabasesStatus (state, action, status) {
...state.databases, ...state.databases,
[action.database.id]: { [action.database.id]: {
...state[action.database.id], ...state[action.database.id],
status status,
timestamp: action.timestamp
} }
} }
} }

72
src/orbit/orbitSaga.js

@ -1,11 +1,16 @@
import {all, call, put, take, takeLatest} from 'redux-saga/effects' import { all, call, put, spawn, take, takeEvery, takeLatest } from 'redux-saga/effects'
import { eventChannel } from 'redux-saga';
import OrbitDB from 'orbit-db'; import OrbitDB from 'orbit-db';
import Identities from 'orbit-db-identity-provider' import Identities from 'orbit-db-identity-provider'
import { import {
ORBIT_DATABASE_CREATED, ORBIT_DATABASE_CREATED,
ORBIT_DATABASE_CREATING, ORBIT_DATABASE_CREATING,
ORBIT_DATABASE_FAILED, ORBIT_DATABASE_FAILED,
ORBIT_DATABASE_LISTEN, ORBIT_DATABASE_LISTEN,
ORBIT_DATABASE_READY,
ORBIT_DATABASE_REPLICATED,
ORBIT_DATABASE_REPLICATING,
ORBIT_IDENTITY_PROVIDER_ADD, ORBIT_IDENTITY_PROVIDER_ADD,
ORBIT_IDENTITY_PROVIDER_ADDED, ORBIT_IDENTITY_PROVIDER_ADDED,
ORBIT_IDENTITY_PROVIDER_FAILED, ORBIT_IDENTITY_PROVIDER_FAILED,
@ -14,10 +19,11 @@ import {
ORBIT_INITIALIZING ORBIT_INITIALIZING
} from './orbitActions'; } from './orbitActions';
import { resolveOrbitDBTypeFun} from "./orbitUtils"; import { resolveOrbitDBTypeFun} from './orbitUtils';
const LOGGING_PREFIX = 'orbitSaga: '; const LOGGING_PREFIX = 'orbitSaga: ';
/* /*
* Add Orbit Identity Provider * Add Orbit Identity Provider
*/ */
@ -31,12 +37,12 @@ export function * addOrbitIdentityProvider(identityProvider) {
yield put({ type: ORBIT_IDENTITY_PROVIDER_ADDED }); yield put({ type: ORBIT_IDENTITY_PROVIDER_ADDED });
} catch (error) { } catch (error) {
yield put({ type: ORBIT_IDENTITY_PROVIDER_FAILED, error }); yield put({ type: ORBIT_IDENTITY_PROVIDER_FAILED, error });
console.error(LOGGING_PREFIX + 'EthereumIdentityProvider adding error:'); console.error(LOGGING_PREFIX + 'IdentityProvider adding error:');
console.error(error); console.error(error);
} }
} }
export function * initOrbit(action) { function * initOrbit(action) {
try { try {
let { breeze, id } = action; let { breeze, id } = action;
const { ipfs } = breeze; const { ipfs } = breeze;
@ -48,7 +54,7 @@ export function * initOrbit(action) {
breeze.orbit = orbit; breeze.orbit = orbit;
// Create our own initial databases, as given in the options // Create initial databases from options
yield all(databases.map(db => { yield all(databases.map(db => {
return call(createDatabase, { orbit, db }); return call(createDatabase, { orbit, db });
})); }));
@ -66,13 +72,16 @@ export function * initOrbit(action) {
/* /*
* Creates an orbit database given a name and a type as its parameters * Creates an orbit database given a name and a type as its parameters
*/ */
export function * createDatabase({orbit, db}) { function * createDatabase({ orbit, db }) {
try { try {
const dbTypeFun = resolveOrbitDBTypeFun(orbit, db.type); const dbTypeFun = resolveOrbitDBTypeFun(orbit, db.type);
const createdDB = yield call([orbit, dbTypeFun], db.name); const createdDB = yield call([orbit, dbTypeFun], db.name);
yield put({ type: ORBIT_DATABASE_CREATED, database: createdDB }); yield put({ type: ORBIT_DATABASE_CREATED, database: createdDB, timestamp: +new Date });
// Event channel setup
yield spawn(callListenForOrbitDatabaseEvent, { database: createdDB });
// Wait for event channel setup before loading // Wait for event channel setup before loading
yield take(action => action.type === ORBIT_DATABASE_LISTEN && action.id === createdDB.id); yield take(action => action.type === ORBIT_DATABASE_LISTEN && action.id === createdDB.id);
@ -82,14 +91,59 @@ export function * createDatabase({orbit, db}) {
return createdDB; return createdDB;
} catch (error) { } catch (error) {
yield put({ type: ORBIT_DATABASE_FAILED, error }); yield put({ type: ORBIT_DATABASE_FAILED, error });
console.error(LOGGING_PREFIX + 'OrbitDB identity provider adding error:'); console.error(LOGGING_PREFIX + 'OrbitDB database creation error:');
console.error(error); console.error(error);
} }
} }
/*
* Database Events
* See also https://redux-saga.js.org/docs/advanced/Channels.html
*/
function createOrbitDatabaseChannel (database){
return eventChannel(emit => {
const onReady = () => {
emit({ type: ORBIT_DATABASE_READY, database, timestamp: +new Date });
};
const onReplicate = () => {
emit({ type: ORBIT_DATABASE_REPLICATING, database, timestamp: +new Date });
};
const onReplicated = () => {
emit({ type: ORBIT_DATABASE_REPLICATED, database, timestamp: +new Date });
};
const eventListener = database.events
.once('ready', onReady)
.on('replicate', onReplicate)
.on('replicated', onReplicated)
return () => {
eventListener.removeListener('ready',onReady)
eventListener.removeListener('replicate',onReplicate)
eventListener.removeListener('replicated',onReplicated)
};
})
}
function * callListenForOrbitDatabaseEvent ({ database }) {
const orbitDatabaseChannel = yield call(createOrbitDatabaseChannel, database);
yield put({type: ORBIT_DATABASE_LISTEN, id: database.id});
try {
while (true) {
let event = yield take(orbitDatabaseChannel);
yield put(event);
}
} finally {
orbitDatabaseChannel.close();
}
}
function * orbitSaga () { function * orbitSaga () {
yield takeLatest(ORBIT_INITIALIZING, initOrbit); yield takeLatest(ORBIT_INITIALIZING, initOrbit);
yield takeLatest(ORBIT_DATABASE_CREATING, createDatabase); yield takeEvery(ORBIT_DATABASE_CREATING, createDatabase);
} }
export default orbitSaga export default orbitSaga

61
src/orbit/orbitStatusSaga.js

@ -1,61 +0,0 @@
import { call, put, take, takeEvery } from 'redux-saga/effects'
import {eventChannel} from "@redux-saga/core";
import {
ORBIT_DATABASE_CREATED,
ORBIT_DATABASE_LISTEN,
ORBIT_DATABASE_READY,
ORBIT_DATABASE_REPLICATED,
ORBIT_DATABASE_REPLICATING
} from './orbitActions';
/*
* Database Events
* See also https://redux-saga.js.org/docs/advanced/Channels.html
*/
function createOrbitDatabaseChannel (database){
return eventChannel(emit => {
const onReady = () => {
emit({ type: ORBIT_DATABASE_READY, database });
};
const onReplicate = () => {
emit({ type: ORBIT_DATABASE_REPLICATING, database });
};
const onReplicated = () => {
emit({ type: ORBIT_DATABASE_REPLICATED, database });
};
const eventListener = database.events
.on('ready', onReady)
.on('replicate', onReplicate)
.on('replicated', onReplicated)
return () => {
eventListener.removeListener('ready',onReady)
eventListener.removeListener('replicate',onReplicate)
eventListener.removeListener('replicated',onReplicated)
};
})
}
export function * callListenForOrbitDatabaseEvent ({database}) {
const orbitDatabaseChannel = yield call(createOrbitDatabaseChannel, database)
yield put({type: ORBIT_DATABASE_LISTEN, id: database.id});
try {
while (true) {
let event = yield take(orbitDatabaseChannel);
yield put(event);
}
} finally {
orbitDatabaseChannel.close();
}
}
function * orbitStatusSaga () {
yield takeEvery(ORBIT_DATABASE_CREATED, callListenForOrbitDatabaseEvent);
}
export default orbitStatusSaga

2
src/orbit/orbitUtils.js

@ -1,4 +1,4 @@
import * as orbitTypes from "./constants"; import * as orbitTypes from "./orbitConstants";
export function resolveOrbitDBTypeFun(orbitdb, type){ export function resolveOrbitDBTypeFun(orbitdb, type){
let dbTypeFun; let dbTypeFun;

816
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save