Minor fixes and removing google analytics

This commit is contained in:
Richard Ramos 2020-03-20 13:49:04 -04:00
parent aa86c508ed
commit 8710bebd23
22 changed files with 1218 additions and 5449 deletions

View File

@ -1 +1 @@
subspace.status.im
subspace.embarklabs.io

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -2,14 +2,14 @@
## General
### `new Subspace(web3Provider [, options])`
### `new Subspace(web3 [, options])`
Constructor.
**Parameters**
1. `web3Provider` - `Object`: a valid web3 provider.
1. `web3` - `Object`: a `web3.js` object.
2. `options` - `Object` (optional): Options used to initialize Subspace
- `dbFilename` - `String` (optional): Name of the database where the information will be stored (default `'subspace.db'`)
- `callInterval` - `Number` (optional): - Interval of time in milliseconds to poll a contract/address to determine changes in state or balance (default: `undefined`. Obtains data every block. If using a HttpProvider, the default is: `1000`)
- `callInterval` - Interval of time in milliseconds to query a contract/address to determine changes in state or balance. It's only used with HttpProviders (default: `undefined`. Obtains data every block using the average block time as an interval).
- `refreshLastNBlocks` - Ignores last N blocks (from current block), stored in the local db and refresh them via a web3 subscription. Useful for possible reorgs (default: 12),
- `disableSubscriptions` - Subspace by default will attempt to use websocket subscriptions if the current provider supports them, otherwise it will use polling because it asumes the provider is an HttpProvider. This functionality can be disabled by passing true to this option. (default: undefined)

View File

@ -1,23 +1,17 @@
# apollo-client
To use **Subspace** with `apollo-client`, a composed `ApolloLink` must be defined using the `apollo-link-rxjs` and `reactive-graphl` npm packages. Notice that the `addTypename` option of `InMemoryCache` must be set `false`.
To use **Subspace** with `apollo-client`, a `ReactiveSchemaLink` from `apollo-link-reactive-schema` must be used with a custom schema.
```js
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink } from "apollo-link";
import { rxjs as rxJsLink } from "apollo-link-rxjs";
import { graphql } from "reactive-graphql";
import {InMemoryCache} from "apollo-cache-inmemory";
import ApolloClient from "apollo-client";
import {ReactiveSchemaLink} from "apollo-link-reactive-schema";
const schema = makeExecutableSchema({typeDefs, resolvers});
const client = new ApolloClient({
// If addTypename:true, the query will fail due to __typename
// being added to the schema. reactive-graphql does not
// support __typename at this moment.
cache: new InMemoryCache({ addTypename: false }),
link: ApolloLink.from([
rxJsLink({}),
new ApolloLink(operation => graphql(schema, operation.query))
])
cache: new InMemoryCache(),
link: new ReactiveSchemaLink({schema)})
});
```
### Example
@ -25,17 +19,16 @@ const client = new ApolloClient({
```js{35-45}
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink } from "apollo-link";
import { rxjs as rxJsLink } from "apollo-link-rxjs";
import { graphql } from "reactive-graphql";
import {ReactiveSchemaLink} from "apollo-link-reactive-schema";
import Subspace from "@embarklabs/subspace";
// ...
// Initialize Subspace
const subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)
const subspace = new Subspace(web3);
await subspace.init();
const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance
const MyContractInstance = ...; // TODO: obtain a web3.eth.Contract instance
const typeDefs = `
type MyEvent {
@ -49,28 +42,20 @@ const typeDefs = `
const resolvers = {
Query: {
myEvents: () => {
return subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})
}
myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})
}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const client = new ApolloClient({
// If addTypename:true, the query will fail due to __typename
// being added to the schema. reactive-graphql does not
// support __typename at this moment.
cache: new InMemoryCache({ addTypename: false }),
link: ApolloLink.from([
rxJsLink({}),
new ApolloLink(operation => graphql(schema, operation.query))
])
cache: new InMemoryCache(),
link: new ReactiveSchemaLink({schema)})
});
```
<div class="c-notification">
Using react-apollo
A practical example can also be found in `examples/react-apollo`.
<h3>Using Apollo with Subspace</h3>
A practical example can also be found in <code>examples/react-apollo</code>.
</div>

View File

@ -1,4 +1,3 @@
---
title: Getting Started
---
@ -26,18 +25,18 @@ const Subspace = require('@embarklabs/subspace');
## Connecting to a web3 provider
To interact with the EVM, **Subspace** requires a valid Web3 provider.
To interact with the EVM, **Subspace** requires a valid Web3 object, connected to a provider
```js
const subspace = new Subspace(web3.currentProvider);
const subspace = new Subspace(web3);
await subspace.init();
```
In addition to the provider, `Subspace` also accepts an `options` object with settings that can change its behavior:
- `dbFilename` - Name of the database where the information will be stored (default `'subspace.db'`)
- `callInterval` - Interval of time in milliseconds to query a contract/address to determine changes in state or balance (default: `undefined`. Obtains data every block).
- `callInterval` - Interval of time in milliseconds to query a contract/address to determine changes in state or balance. It's only used with HttpProviders (default: `undefined`. Obtains data every block using the average block time as an interval).
- `refreshLastNBlocks` - Ignores last N blocks (from current block), stored in the local db and refresh them via a web3 subscription. Useful for possible reorgs (default: 12),
- `disableSubscriptions` - Subspace by default will attempt to use websocket subscriptions if the current provider supports them, otherwise it will use polling because it asumes the provider is an HttpProvider. This functionality can be disabled by passing true to this option. (default: undefined)
- `disableSubscriptions` - Subspace by default will attempt to use websocket subscriptions if the current provider supports them, otherwise it will use polling because it asumes the provider is an HttpProvider. This functionality can be disabled by passing true to this option. (default: `undefined`)
## Enhancing your contract objects
@ -57,8 +56,8 @@ const myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})
Once it's initialized, you can use **Subspace**'s methods to track the contract state, events and balances. These functions return RxJS Observables which you can subscribe to, and obtain and transform the observed data via operators.
<div class="c-notification">
What is an Observable?
The `Observable` type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:
<h3>What is an Observable?</h3>
The <code>Observable</code> type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:
- Compositional: Observables can be composed with higher-order combinators.
- Lazy: Observables do not start emitting data until an observer has subscribed.
</div>
@ -72,8 +71,9 @@ You can track changes to a contract state variable, by specifying the view funct
const stateObservable$ = Contract.methods.functionName(functionArgs).track();
```
<div class="c-notification">Tracking the public variables of a contract
State variables implicity create a `view` function when they're defined as `public`. The `functionName` would be the same as the variable name, and `functionArgs` will have a value when the type is a `mapping` or `array` (since these require an index value to query them).
<div class="c-notification">
<h3>Tracking the public variables of a contract</h3>
State variables implicity create a <code>view</code> function when they're defined as <code>public</code>. The <code>functionName</code> would be the same as the variable name, and <code>functionArgs</code> will have a value when the type is a <code>mapping</code> or array (since these require an index value to query them).
</div>
Example:
@ -93,13 +93,13 @@ The subscription will be triggered whenever the title changes
## Tracking events
You can track events and react to their returned values.
```js
const eventObservable$ = Contract.event.eventName().track();
const eventObservable$ = Contract.event.eventName.track();
```
Example:
```js
const rating$ = Product.events.Rating().track().map("rating")).pipe(map(x => parseInt(x)));
const rating$ = Product.events.Rating.track().map("rating")).pipe(map(x => parseInt(x)));
rating$.subscribe((rating) => console.log("rating received: " + rating));
@ -117,7 +117,7 @@ For e.g: if you needed to get the average rating of the last 5 events:
```js
import { $average, $latest } from "@embarklabs/subspace";
const rating$ = Product.events.Rating().track().map("rating")).pipe(map(x => parseInt(x)));
const rating$ = Product.events.Rating.track().map("rating")).pipe(map(x => parseInt(x)));
rating$.pipe($latest(5), $average()).subscribe((rating) => {
console.log("average rating of the last 5 events is " + rating)
@ -154,7 +154,7 @@ const myBalanceObservable$ = Contract.trackBalance(tokenAddress);
```
<div class="c-notification c-notification--warning">
Balances are returned as a string containing the value in *wei*.
Balances are returned as a string containing the value in <strong>wei</strong>.
</div>
@ -217,7 +217,7 @@ If **Subspace** is not needed anymore, you need can invoke `close()` to dispose
subspace.close();
```
<div class="c-notification c-notification--warning">
What about subscriptions created with our observables?
Any subscription created via the tracking methods must be unsubscribed manually (in the current version).
<h3>What about subscriptions created with our observables?</h3>
<code>close()</code> will dispose any web3 subscription created when using a Subspace tracking method, however any subscription to an observable must still be unsubscribed manually. The npm package <code>subsink</code> can be used to clear all the observables' subscriptions at once.
</div>

View File

@ -1,110 +1,114 @@
# React
We provide a higher-order component to connect to enhance presentational components to react to any observable (not limited to those generated by **Subspace**).
Subspace also provides a set of components that simplifies its usage within React projects through the `@embarklabs/subspace-react` package.
### Install
You can install it through npm or yarn:
```
npm install --save @embarklabs/subspace-react web3 rxjs # RxJS and Web3.js are needed peer-dependencies
```
### Usage
#### SubspaceProvider
To use most of the `subspace-react` components, you need to wrap your app with the `<SubspaceProvider web3={web3} />` component. This will make Subspace available to any nested components that accesses it via the `useSubspace` hook or has been wrapped in the `withSubspace` higher order component. Any React component might use Subspace so it makes sense to add the provider near the top level of your dApp. The `SubspaceProvider` requires a web3 object
```js
import { observe } from '@embarklabs/subspace/react';
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import MyApp from './MyApp'
import { SubspaceProvider } from '@embarklabs/subspace-react';
const web3 = new Web3("ws://localhost:8545");
const rootElement = document.getElementById('root')
ReactDOM.render(
<SubspaceProvider web3={web3}>
<MyApp />
</SubspaceProvider>,
rootElement
);
```
#### useSubspace
Rather than relying on global variables or passing Subspace through props, The easiest way to access Subspace features is via the `useSubspace` hook. Be sure that your entire dApp is wrapped with a `<SubspaceProvider />` to have it available througout the component tree.
```js
// index.js
import React from 'react'
import { useSubspace } from '@embarklabs/subspace-react';
const MyComponent = () => {
const subspace = useSubspace();
// do something....
// subspace.trackBalance(web3.eth.defaultAccount);
return ...;
}
export default MyComponent
```
#### withSubspace
This higher order component is provided as an alternative to the `useSubspace` hook. This injects the `subspace` property with an already initialized Subspace instance. Just like with the hook, your entire dApp needs to be wrapped with a `<SubspaceProvider />`.
```js
// index.js
import React from 'react'
import { withSubspace } from '@embarklabs/subspace-react';
const MyComponent = (props) => {
// do something....
// props.subspace.trackBalance(web3.eth.defaultAccount);
return ...;
}
export default withSubspace(MyComponent);
```
#### observe
Useful to make your component subscribe to any observable props it receives when the component is mounted and automatically unsubscribes when the component is unmounted. It can be used with any kind of observables.
```js
import { observe } from '@embarklabs/subspace-react';
const ObserverComponent = observe(WrappedComponent);
```
This enhanced component will subscribe to any observable property it receives when the component is mounted and automatically unsubscribe when the component is unmounted.
### Example
<div class="c-notification">
This example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)
</div>
#### MyComponentObserver.js
##### Example usage:
```js
import React from "react";
import ReactDOM from 'react-dom';
import {observe} from "@embarklabs/subspace/react";
const MyComponent = ({eventData}) => {
const MyComponent = ({eventData}) => {
// Handle initial state when no data is available
if (!eventData) {
return <p>No data</p>;
}
return <p>{eventData.someReturnedValue}</p>
return <p>Value: {eventData.someReturnValue}</p>
};
// MyComponent will now observe any observable prop it receives
// and update its state whenever the observable emits an event
export default observe(MyComponent);
```
#### App.js
```js
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import Subspace from '@embarklabs/subspace';
const MyEnhancedComponent = observe(MyComponent);
import MyComponentObserver from './MyComponentObserver';
class App extends Component {
state = {
myEventObservable$: null
}
async componentDidMount() {
const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance
const subspace = new Subspace("wss://localhost:8545"); // Use a valid provider (geth, parity, infura...)
await subspace.init()
const myEventObservable$ = subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });
this.setState({ myEventObservable$ });
}
render() {
return <MyComponentObserver eventData={this.state.myEventObservable$} />;
}
const SomeOtherComponent = () => {
const myObservable$ = MyContractInstance.events.MyEvent.track({fromBlock: 1});
return <MyEnhancedComponent myProp={myObservable$} />;
}
export default App;
```
<div class="c-notification c-notification--warning">
Handling Contract Objects
The variable `MyContractInstance` is a `web3.eth.Contract` object pointing to a deployed contract address. You can use a DApp framework like [Embark](https://embark.status.im/docs/contracts_javascript.html) to easily import that contract instance: `import { MyContract } from './embarkArtifacts/contracts';`, or use web3.js directly (just like in the example [source code](https://github.com/embarklabs/subspace/blob/master/examples/react/src/MyContract.js#L36-L42))
<h3>Handling Contract Objects</h3>
The variable <code>MyContractInstance</code> is a <code>web3.eth.Contract</code> object pointing to a deployed contract address that has been enhanced with <code>subspace.contract()</code>. You can use a DApp framework like <a href="https://embark.status.im/docs/contracts_javascript.html" />Embark</a> to easily import that contract instance: <code>import { MyContract } from './embarkArtifacts/contracts';</code>.
</div>
#### index.js
```js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
```
```js
import { observe } from "@embarklabs/subspace/react";
const ProductComponent = ({ maxRating, minRating, averageRating }) => {
return <ul>
<li><b>minimum rating: </b> {minRating}</li>
<li><b>maximum rating: </b> {maxRating}</li>
<li><b>average rating: </b> {averageRating}</li>
</ul>;
};
const ReactiveProductComponent = observe(ProductComponent);
const Product = subspace.contract({abi, address});
const rating$ = Product.events.Rating.track().map("rating").pipe(map(x => parseInt(x)));
ReactDOM.render(
<ReactiveProductComponent
maxRating={rating$.pipe($max())}
minRating={rating$.pipe($min())}
averageRating={rating$.pipe($average())}
/>,
document.getElementById('hello-example')
);
```
<div class="c-notification">
To learn more about how to use <code>subspace-react</code>, there are full working examples available in <a href="https://github.com/embark-framework/subspace/tree/master/examples/" target="_blank">Github</a>
</div>

View File

@ -14,7 +14,7 @@ const gql = require("graphql-tag");
const { graphql } = require("reactive-graphql");
const run = async () => {
const subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)
const subspace = new Subspace(web3);
await subspace.init();
const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance
@ -31,9 +31,7 @@ const run = async () => {
const resolvers = {
Query: {
myEvents: () => {
return subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })
}
myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })
}
};
@ -59,5 +57,5 @@ run();
```
<div class="c-notification">
This example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/reactive-graphql)
This example is available in <a href="https://github.com/embarklabs/subspace/tree/master/examples/reactive-graphql" target="_blank">Github</a>
</div>

View File

@ -25,7 +25,7 @@ const myEpic = action$ =>
```
<div class="c-notification">
An example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux-observable)
An example is available in <a href="https://github.com/embarklabs/subspace/tree/master/examples/redux-observable" target="_blank">Github</a>
</div>
#### Further read

View File

@ -6,7 +6,7 @@
Here's a simple example on how to setup **Subspace** to work with `redux`:
<div class="c-notification">
This example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux)
This example is available in <a href="https://github.com/embarklabs/subspace/tree/master/examples/redux" target="_blank">Github</a>
</div>
#### index.js
@ -19,7 +19,7 @@ import { myAction } from './actions';
const run = async () => {
const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance
const subspace = new Subspace("ws://localhost:8545"); // Use a valid provider (geth, parity, infura...)
const subspace = new Subspace(web3);
await subspace.init();
subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 })
@ -30,8 +30,9 @@ const run = async () => {
run();
```
<div class="c-notification c-notification--warning">Handling Contract Objects
The variable `MyContractInstance` is a `web3.eth.Contract` object pointing to a deployed contract address. You can use a DApp framework like [Embark](https://embark.status.im/docs/contracts_javascript.html) to easily import that contract instance: `import { MyContract } from './embarkArtifacts/contracts';`, or use web3.js directly (just like in the example [source code](https://github.com/embarklabs/subspace/blob/master/examples/redux/src/MyContract.js#L36-L42))
<div class="c-notification c-notification--warning">
<h3>Handling Contract Objects</h3>
The variable <code>MyContractInstance</code> is a <code>web3.eth.Contract</code> object pointing to a deployed contract address. You can use a DApp framework like <a href="https://embark.status.im/docs/contracts_javascript.html">Embark</a> to easily import that contract instance: <code>import { MyContract } from './embarkArtifacts/contracts';</code>, or use web3.js directly (just like in the example <a href="https://github.com/embarklabs/subspace/blob/master/examples/redux/src/MyContract.js#L36-L42" target="_blank">source code</a>)
</div>
#### store.js
@ -73,6 +74,6 @@ export const myAction = eventData => ({type: MY_ACTION, eventData});
```
<div class="c-notification">
Using React and Redux
A practical example can also be found in `examples/react-redux`.
<h3>Using React and Redux</h3>
A practical example can also be found in <code>examples/react-redux</code>.
</div>

View File

@ -4,7 +4,7 @@ Vue provides the official npm package `vue-rx` that provides RxJS integration, w
### Example
<div class="c-notification">
This example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/vue)
This example is available in <a href="https://github.com/embark-framework/subspace/tree/master/examples/vue" target="_blank">Github</a>
</div>
@ -56,7 +56,7 @@ export default {
created: async function(){
this.MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance
const subspace = new Subspace("wss://localhost:8545"); // Use a valid provider (geth, parity, infura...)
const subspace = new Subspace(web3);
await subspace.init();
this.myEventObservable$ = subspace.trackEvent(this.MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });

View File

@ -48,7 +48,6 @@ widgets:
- recent_posts
# Miscellaneous
google_analytics:
favicon: /favicon.png
twitter:
google_plus:
@ -60,7 +59,6 @@ google_plus:
- **fancybox** - Enable [Fancybox]
- **sidebar** - Sidebar style. You can choose `left`, `right`, `bottom` or `false`.
- **widgets** - Widgets displaying in sidebar
- **google_analytics** - Google Analytics ID
- **favicon** - Favicon path
- **twitter** - Twiiter ID
- **google_plus** - Google+ ID

View File

@ -28,8 +28,6 @@ archive_type: 'monthly'
show_count: false
# Miscellaneous
google_analytics:
gauges_analytics:
favicon: /favicon.png
twitter:
google_plus:

View File

@ -22,4 +22,4 @@
<% } %>
<%- js('js/script') %>
<%- partial('gauges-analytics') %>

View File

@ -0,0 +1,16 @@
<!-- Fathom - simple website analytics - https://github.com/usefathom/fathom -->
<script type="text/javascript">
(function(f, a, t, h, o, m){
a[h]=a[h]||function(){
(a[h].q=a[h].q||[]).push(arguments)
};
o=f.createElement('script'),
m=f.getElementsByTagName('script')[0];
o.async=1; o.src=t; o.id='fathom-script';
m.parentNode.insertBefore(o,m)
})(document, window, '//fathom.status.im/tracker.js', 'fathom');
fathom('set', 'siteId', 'DNONS');
fathom('trackPageview');
</script>
<!-- / Fathom -->

View File

@ -1,18 +0,0 @@
<% if (theme.gauges_analytics){ %>
<!-- Gaug.es Analytics -->
<script type="text/javascript">
var _gauges = _gauges || [];
(function() {
var t = document.createElement('script');
t.type = 'text/javascript';
t.async = true;
t.id = 'gauges-tracker';
t.setAttribute('data-site-id', '<%= theme.gauges_analytics %>');
t.setAttribute('data-track-path', 'https://track.gaug.es/track.gif');
t.src = 'https://d36ee2fcip1434.cloudfront.net/track.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(t, s);
})();
</script>
<!-- End Gaug.es Analytics -->
<% } %>

View File

@ -1,14 +0,0 @@
<% if (theme.google_analytics){ %>
<!-- Google Analytics -->
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '<%= theme.google_analytics %>', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
<% } %>

View File

@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<%- partial('google-analytics') %>
<%- partial('analytics') %>
<%
var title = page.title;

View File

@ -0,0 +1,16 @@
<!-- Fathom - simple website analytics - https://github.com/usefathom/fathom -->
<script type="text/javascript">
(function(f, a, t, h, o, m){
a[h]=a[h]||function(){
(a[h].q=a[h].q||[]).push(arguments)
};
o=f.createElement('script'),
m=f.getElementsByTagName('script')[0];
o.async=1; o.src=t; o.id='fathom-script';
m.parentNode.insertBefore(o,m)
})(document, window, '//fathom.status.im/tracker.js', 'fathom');
fathom('set', 'siteId', 'DNONS');
fathom('trackPageview');
</script>
<!-- / Fathom -->

View File

@ -54,6 +54,9 @@
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<%- partial('analytics') %>
<script>
/*!
* jQuery.anchorScroll jQuery Plugin v1.0

View File

@ -7,4 +7,8 @@
background-color: get-color(yellow, 300);
border-color: get-color(yellow, 900);
}
h3 {
margin-top: 0;
}
}

1096
yarn.lock

File diff suppressed because it is too large Load Diff