From 8710bebd239cb762c8b4fcae36f24ba215587e09 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 20 Mar 2020 13:49:04 -0400 Subject: [PATCH] Minor fixes and removing google analytics --- packages/site/CNAME | 2 +- packages/site/db.json | 2 +- packages/site/package-lock.json | 5204 ----------------- packages/site/source/packages/docs/api.md | 6 +- .../source/packages/docs/apollo-client.md | 49 +- .../source/packages/docs/getting-started.md | 30 +- packages/site/source/packages/docs/react.md | 172 +- .../source/packages/docs/reactive-graphql.md | 8 +- .../source/packages/docs/redux-observable.md | 2 +- packages/site/source/packages/docs/redux.md | 13 +- packages/site/source/packages/docs/vue.md | 4 +- packages/site/themes/landscape/README.md | 2 - packages/site/themes/landscape/_config.yml | 2 - .../layout/_partial/after-footer.ejs | 2 +- .../landscape/layout/_partial/analytics.ejs | 16 + .../layout/_partial/gauges-analytics.ejs | 18 - .../layout/_partial/google-analytics.ejs | 14 - .../themes/landscape/layout/_partial/head.ejs | 2 +- .../subspace/layout/partial/analytics.ejs | 16 + .../themes/subspace/layout/partial/footer.ejs | 3 + .../source/css/components/_notification.scss | 4 + yarn.lock | 1096 +++- 22 files changed, 1218 insertions(+), 5449 deletions(-) delete mode 100644 packages/site/package-lock.json create mode 100644 packages/site/themes/landscape/layout/_partial/analytics.ejs delete mode 100644 packages/site/themes/landscape/layout/_partial/gauges-analytics.ejs delete mode 100644 packages/site/themes/landscape/layout/_partial/google-analytics.ejs create mode 100644 packages/site/themes/subspace/layout/partial/analytics.ejs diff --git a/packages/site/CNAME b/packages/site/CNAME index c212bfc..ace3b30 100644 --- a/packages/site/CNAME +++ b/packages/site/CNAME @@ -1 +1 @@ -subspace.status.im +subspace.embarklabs.io diff --git a/packages/site/db.json b/packages/site/db.json index 20e1e6d..9a710ff 100644 --- a/packages/site/db.json +++ b/packages/site/db.json @@ -1 +1 @@ -{"meta":{"version":1,"warehouse":"3.0.2"},"models":{"Asset":[{"_id":"source/packages/docs/CNAME","path":"CNAME","modified":0,"renderable":0},{"_id":"source/packages/docs/d1.png","path":"d1.png","modified":0,"renderable":0},{"_id":"source/packages/docs/d2.png","path":"d2.png","modified":0,"renderable":0},{"_id":"source/packages/docs/d4.png","path":"d4.png","modified":0,"renderable":0},{"_id":"source/packages/docs/d3.png","path":"d3.png","modified":0,"renderable":0},{"_id":"themes/subspace/source/css/application.scss","path":"css/application.scss","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/accounting-calculator.svg","path":"icons/accounting-calculator.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/book-address.svg","path":"icons/book-address.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/contactless-payment.svg","path":"icons/contactless-payment.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/close.svg","path":"icons/close.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/cloud-lock.svg","path":"icons/cloud-lock.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-give.svg","path":"icons/crypto-currency-bitcoin-give.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-lock.svg","path":"icons/crypto-currency-bitcoin-lock.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/facebook.svg","path":"icons/facebook.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/gauge-dashboard-1-alternate.svg","path":"icons/gauge-dashboard-1-alternate.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/credit-card-1.svg","path":"icons/credit-card-1.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/gesture-tap-2.svg","path":"icons/gesture-tap-2.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/navigation-menu.svg","path":"icons/navigation-menu.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/half-circles.svg","path":"icons/half-circles.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/twitter.svg","path":"icons/twitter.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/github.svg","path":"icons/github.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/embark-logo.svg","path":"images/embark-logo.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/favicon.png","path":"images/favicon.png","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/circles.png","path":"images/circles.png","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/logo.svg","path":"images/logo.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/javascripts/scripts.js","path":"javascripts/scripts.js","modified":0,"renderable":1},{"_id":"themes/subspace/source/fonts/LICENSE.txt","path":"fonts/LICENSE.txt","modified":0,"renderable":1},{"_id":"themes/subspace/source/javascripts/jquery.js","path":"javascripts/jquery.js","modified":0,"renderable":1},{"_id":"themes/subspace/source/css/utilities/text-color.scss","path":"css/utilities/text-color.scss","modified":0,"renderable":1},{"_id":"themes/subspace/source/css/utilities/text-size.scss","path":"css/utilities/text-size.scss","modified":0,"renderable":1},{"_id":"themes/subspace/source/fonts/Roboto-Regular.ttf","path":"fonts/Roboto-Regular.ttf","modified":0,"renderable":1},{"_id":"themes/subspace/source/fonts/Roboto-Bold.ttf","path":"fonts/Roboto-Bold.ttf","modified":0,"renderable":1}],"Cache":[{"_id":"source/packages/docs/integrations.md","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642530738},{"_id":"source/packages/docs/CNAME","hash":"545c29d0214716b4d25f490ba92f7fc192267fa9","modified":1584642530729},{"_id":"source/packages/docs/api.md","hash":"7531c18af676e980ac9ae61b5ea8fe4d18b88fba","modified":1584642530730},{"_id":"source/packages/docs/apollo-client.md","hash":"ed45908ea3d645c5022ccaf35c4f83d4622decd5","modified":1584642530730},{"_id":"source/packages/docs/getting-started.md","hash":"0a107c070e1a0c1d6a6defd69207046d32791ed6","modified":1584642530738},{"_id":"source/packages/docs/how-it-works.md","hash":"d63d4586abfc27e244c79fadc6bd511177000f93","modified":1584642530738},{"_id":"source/packages/docs/react.md","hash":"85fd2bfded2d0ce30e87ea2cbae38bfd08e01456","modified":1584642530738},{"_id":"source/packages/docs/index.md","hash":"c7f9f58861a13ea8feab62f9b1bdd77dbda50332","modified":1584642530738},{"_id":"source/packages/docs/reactive-graphql.md","hash":"9624093db72703fc9e660018a769c6ed3ea95857","modified":1584642530738},{"_id":"source/packages/docs/integrations-overview.md","hash":"27810364f74ec73eb6dad0c8de9d72d9b8b51819","modified":1584642530738},{"_id":"source/packages/docs/redux.md","hash":"e25db183bbeeabb1ff94cae21b98a61e7078e3ca","modified":1584642530739},{"_id":"source/packages/docs/redux-observable.md","hash":"1b46806cb638bd3066058bd9b81227eb7410000d","modified":1584642530739},{"_id":"source/packages/docs/tutorial.md","hash":"baadad45a3c4192b5b32636c0552e32f00e75076","modified":1584642530739},{"_id":"source/packages/docs/readme.md","hash":"87edb67efc2d3ff34adb4cdaf253af19602ad901","modified":1584642530739},{"_id":"source/packages/docs/vue.md","hash":"d79683cdd68c06d2206a9c846059d195d37a3e57","modified":1584642530739},{"_id":"source/packages/docs/d1.png","hash":"615cbb4801559261ddeaedcda06679dd13ff8f26","modified":1584642530731},{"_id":"themes/subspace/languages/en.yml","hash":"52b19a8059904b1c4d7024cb5f2e7a8071b0ab57","modified":1584642530754},{"_id":"themes/subspace/languages/.DS_Store","hash":"d76a2d7ac0d577c6351a42a52cde25f60bbe2e26","modified":1584642530754},{"_id":"themes/subspace/layout/about-us.ejs","hash":"906fffa56cbe7211846775e0b4844db1825230a7","modified":1584642530754},{"_id":"themes/subspace/layout/layout.ejs","hash":"38e9ef77f035f17fb6c4a46d3f2204d2c5f51459","modified":1584642530755},{"_id":"themes/subspace/layout/index.ejs","hash":"b104f0b2eaae87f8c90a6cdafc18e2f5c699d02a","modified":1584642530755},{"_id":"themes/subspace/layout/page.ejs","hash":"e006206018c66a2c2937215010c9c3cd705f05ad","modified":1584642530755},{"_id":"themes/subspace/layout/404.ejs","hash":"52679437dd54e18877ce4d3d6d9989b3515ff6bf","modified":1584642530754},{"_id":"source/packages/docs/d2.png","hash":"87c8eaa980edbe019c706ab8463148227bd25192","modified":1584642530733},{"_id":"source/packages/docs/d4.png","hash":"5cc6b8b2d141e41719bf9ace46d2be80d8236a69","modified":1584642530737},{"_id":"source/packages/docs/d3.png","hash":"ca19a6ae5bf461a92af770d0ed7e82170c27da4a","modified":1584642530735},{"_id":"themes/subspace/layout/partial/head.ejs","hash":"7b788f51a2f5cc3891dd2bc9db8590580a6c47da","modified":1584642530755},{"_id":"themes/subspace/source/css/application.scss","hash":"424452ff93d472ea4097d60437a5c2fb8be74e49","modified":1584642530756},{"_id":"themes/subspace/layout/partial/header.ejs","hash":"a6cbefc575f7d67895463ffce2813eee00cdc1d0","modified":1584642530756},{"_id":"themes/subspace/source/css/.DS_Store","hash":"6d11537ea7ac951519f8387948002c67d58ac9ef","modified":1584642530756},{"_id":"themes/subspace/layout/partial/footer.ejs","hash":"cb235b6e4dee4efa299b1b5c2097e95523b029e4","modified":1584642530755},{"_id":"themes/subspace/layout/partial/mailpopup.ejs","hash":"edb6ea1449c8f419c1f6cd3fa0f3f6bac709675d","modified":1584642530756},{"_id":"themes/subspace/layout/partial/header-short.ejs","hash":"fcf71590daa7f07a0d898a9cd432faebb7b06ea9","modified":1584642530755},{"_id":"themes/subspace/source/icons/accounting-calculator.svg","hash":"7891b12b3fd13594b3ae17c10b3523208265be33","modified":1584642530762},{"_id":"themes/subspace/source/icons/book-address.svg","hash":"e2635b49f36833ec0f3373d53e3c5819a3446c24","modified":1584642530762},{"_id":"themes/subspace/source/icons/contactless-payment.svg","hash":"6674a6a6c06539d7be7bcb2459448d4895541051","modified":1584642530763},{"_id":"themes/subspace/source/icons/close.svg","hash":"07c332a892c2b2a107bf53a055425064006b7161","modified":1584642530763},{"_id":"themes/subspace/source/icons/cloud-lock.svg","hash":"b76429f6da1aaa8a1f1d1e72ae7167899976e7aa","modified":1584642530763},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-give.svg","hash":"a07cb23aa2c7b81167289cfee51450e110dd46d2","modified":1584642530763},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-lock.svg","hash":"27219b9e068b7dc5323217e3f49bad16f6555470","modified":1584642530763},{"_id":"themes/subspace/source/icons/facebook.svg","hash":"0cf65e7228226ff7aa72c74d35368db7599c884b","modified":1584642530763},{"_id":"themes/subspace/source/icons/gauge-dashboard-1-alternate.svg","hash":"4ab202003ecb28775848f4b6fa61a45b4cdc8a7c","modified":1584642530763},{"_id":"themes/subspace/source/icons/credit-card-1.svg","hash":"2c6082035b515eff854f84905cca61a53275aa8e","modified":1584642530763},{"_id":"themes/subspace/source/icons/gesture-tap-2.svg","hash":"8e9a60be2d1080c184f8863d8059472ae1051432","modified":1584642530763},{"_id":"themes/subspace/source/icons/navigation-menu.svg","hash":"d6b4d9e2da8849ac362bcb8d634725b921ebf46c","modified":1584642530764},{"_id":"themes/subspace/source/icons/half-circles.svg","hash":"0be6efb2cd315348a5f2f1404da205d11d5e78c3","modified":1584642530764},{"_id":"themes/subspace/source/icons/twitter.svg","hash":"dab32630d9eb04c293f9c4775271953d57eb8642","modified":1584642530764},{"_id":"themes/subspace/source/images/.DS_Store","hash":"df2fbeb1400acda0909a32c1cf6bf492f1121e07","modified":1584642530764},{"_id":"themes/subspace/source/icons/github.svg","hash":"4ad3447484a193da8e10d9705ebb598de10873e6","modified":1584642530764},{"_id":"themes/subspace/source/images/embark-logo.svg","hash":"682af62e01cd85c11235bd2258b8f87ee9b44afb","modified":1584642530765},{"_id":"themes/subspace/source/images/favicon.png","hash":"7f0c4305cd9711e9dd20ac94a5559f4d67a9fe9b","modified":1584642530765},{"_id":"themes/subspace/source/images/circles.png","hash":"ca3ed456a67c9c329e638990b9a8805a2f33c68c","modified":1584642530764},{"_id":"themes/subspace/source/images/logo.svg","hash":"e7d3c651b56c2bb890b567a67dd860fc96ad6579","modified":1584642530765},{"_id":"themes/subspace/source/javascripts/scripts.js","hash":"1f0ee8c12b179a9607cb1848710254652a7332b2","modified":1584642530766},{"_id":"themes/subspace/source/css/components/_footer.scss","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642530756},{"_id":"themes/subspace/source/fonts/LICENSE.txt","hash":"47b573e3824cd5e02a1a3ae99e2735b49e0256e4","modified":1584642530761},{"_id":"themes/subspace/source/javascripts/jquery.js","hash":"9592732de681f4365e9b7016dc5cf76e2a55ee9b","modified":1584642530765},{"_id":"themes/subspace/source/css/components/_accentbox.scss","hash":"d29f556f2e24edec1332ccc00e86426015de422a","modified":1584642530756},{"_id":"themes/subspace/source/css/components/_button.scss","hash":"0888de9a954f5bfb3b84bbfdeed13372d250f69d","modified":1584642530756},{"_id":"themes/subspace/source/css/components/_ghostbox.scss","hash":"1105139aba422228bc5a64863d28d8405d700d15","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_header.scss","hash":"e83d6db7e7c928f4d7d5fd2d57643fe1a551cffc","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_icons.scss","hash":"cb036eb40ed0c2525ca1918e59d73d6a592272ba","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_logo.scss","hash":"c3734c435890094b95a9f340337dbfc682bc1e1a","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_notification.scss","hash":"86462fdffee06124b3d071f35632ae67f2f955fe","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_prism-highlighting.scss","hash":"f8471f2667d53a43cb3b6003d7ecafc811283c24","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_spotlightbox.scss","hash":"2a38ea8c753890d1683b435e33e8377fb17671dc","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_teaser.scss","hash":"c653e382a5a7074f5f86b89c6640a56e083b8471","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_user.scss","hash":"b3663cc7b8c0afdf5f8a69031da7ac3365e844a9","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_whisperbox.scss","hash":"3852852e8644c71b6604915342a10abbfd681d4b","modified":1584642530758},{"_id":"themes/subspace/source/css/objects/_actionbar.scss","hash":"195c09931d611dbfcaf9822413504ebb0e77076b","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_popup.scss","hash":"ccacb82e0b24378a96841d7a480e6530630d882d","modified":1584642530757},{"_id":"themes/subspace/source/css/objects/_content.scss","hash":"4ef659a6c260c847813fabb8718f990c5c126792","modified":1584642530758},{"_id":"themes/subspace/source/css/objects/_distance.scss","hash":"7ad96acdb01f35bbd8941d61f59b055568c6e545","modified":1584642530758},{"_id":"themes/subspace/source/css/objects/_heading.scss","hash":"6569220491e75b751070f2b589fea348745e27d1","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_list.scss","hash":"ed672664d7e4a2f041ce3e3dcc6b3c9f3ebbfa7e","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_media.scss","hash":"be25ab7a3c1e3bccfaaa5fdbeeccf9308694921d","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_navigation.scss","hash":"64e3b33422ccccf702e630125a9b3ca52999c2d6","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_grid.scss","hash":"4dc75ce1b1d58e4ca6624db8115ffd196c996733","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_side-navigation.scss","hash":"231d32b8a6137f3bd4d4ac2aa24476620f558f61","modified":1584642530759},{"_id":"themes/subspace/source/css/settings/_config.scss","hash":"a27b23a9d0e1a77c4361c4cb1f7ad0468906bbb3","modified":1584642530759},{"_id":"themes/subspace/source/css/settings/_preset.scss","hash":"36ed217633bf1a18f5221299e0f60277271eecb4","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/.DS_Store","hash":"5fcb0ec5a267305e0c44b7fa11ae2793b4f428c6","modified":1584642530758},{"_id":"themes/subspace/source/css/settings/_typography.scss","hash":"6cd55798081c53c48e7ad0324a0799b53fc5ff17","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_column.scss","hash":"9e79a4e3b4ab33091af14704d35ca2ab4263b741","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-brand-color.scss","hash":"5e773a10bb143a2b423287b7faff79ac5ce3fcac","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-color.scss","hash":"c7b667b92df7fa246be2f32f395ebbde23ea0355","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-font.scss","hash":"b2895a7ef8c26ba6b34c34f1f2fb2ea5449f89cd","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-index.scss","hash":"72281c30f7e3db2060898d3c9b250bc6c8829216","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-layout-color.scss","hash":"8e57145b98219bc874041197bde973193e2ff7a8","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-notification-color.scss","hash":"761e671fe7cbd70c190254818c8e55e6d3d7ee90","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-semantic-color.scss","hash":"316f7baaa9aeac4f891901882479b37230b5c591","modified":1584642530761},{"_id":"themes/subspace/source/css/tools/_get-spacing.scss","hash":"fc5b46752f7e37da64ddad94392450d7d4f40a87","modified":1584642530761},{"_id":"themes/subspace/source/css/tools/_list-reset.scss","hash":"ed3aa5ee39890dd0454c695e1bf0a45f751c5b04","modified":1584642530761},{"_id":"themes/subspace/source/css/tools/_respond.scss","hash":"ba73d16c16235365bea5da78df0672d990ba4579","modified":1584642530761},{"_id":"themes/subspace/source/css/utilities/text-color.scss","hash":"414a963b70ee7a6250a247bdbd03f2e67e5bbdcd","modified":1584642530761},{"_id":"themes/subspace/source/css/utilities/text-size.scss","hash":"93494af1f3f44293fc9357bd726eadedf76d9516","modified":1584642530761},{"_id":"themes/subspace/source/fonts/Roboto-Regular.ttf","hash":"dd1b1db13ff1f72138c134c62f38fef83749f36a","modified":1584642530762},{"_id":"themes/subspace/source/fonts/Roboto-Bold.ttf","hash":"0ce37ced9c5fcac9bdc452a432c1258870ba4677","modified":1584642530762},{"_id":"public/integrations.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/api.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/apollo-client.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/getting-started.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/how-it-works.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/reactive-graphql.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/react.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/integrations-overview.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/redux.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/tutorial.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/redux-observable.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/readme.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/vue.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/integrations.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/api.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/apollo-client.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/getting-started.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/how-it-works.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/index.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/reactive-graphql.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/react.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/integrations-overview.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/redux.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/redux-observable.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/tutorial.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/readme.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/vue.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/index.html","hash":"f78940c9cc6789a8ebe9e87f038b29570a7551ee","modified":1584642922115},{"_id":"public/CNAME","hash":"545c29d0214716b4d25f490ba92f7fc192267fa9","modified":1584642922115},{"_id":"public/icons/accounting-calculator.svg","hash":"7891b12b3fd13594b3ae17c10b3523208265be33","modified":1584642922115},{"_id":"public/icons/book-address.svg","hash":"e2635b49f36833ec0f3373d53e3c5819a3446c24","modified":1584642922115},{"_id":"public/icons/contactless-payment.svg","hash":"6674a6a6c06539d7be7bcb2459448d4895541051","modified":1584642922115},{"_id":"public/icons/close.svg","hash":"07c332a892c2b2a107bf53a055425064006b7161","modified":1584642922115},{"_id":"public/icons/cloud-lock.svg","hash":"b76429f6da1aaa8a1f1d1e72ae7167899976e7aa","modified":1584642922115},{"_id":"public/icons/crypto-currency-bitcoin-give.svg","hash":"a07cb23aa2c7b81167289cfee51450e110dd46d2","modified":1584642922115},{"_id":"public/icons/crypto-currency-bitcoin-lock.svg","hash":"27219b9e068b7dc5323217e3f49bad16f6555470","modified":1584642922115},{"_id":"public/icons/facebook.svg","hash":"0cf65e7228226ff7aa72c74d35368db7599c884b","modified":1584642922115},{"_id":"public/icons/gesture-tap-2.svg","hash":"8e9a60be2d1080c184f8863d8059472ae1051432","modified":1584642922115},{"_id":"public/icons/gauge-dashboard-1-alternate.svg","hash":"4ab202003ecb28775848f4b6fa61a45b4cdc8a7c","modified":1584642922115},{"_id":"public/icons/credit-card-1.svg","hash":"2c6082035b515eff854f84905cca61a53275aa8e","modified":1584642922115},{"_id":"public/icons/navigation-menu.svg","hash":"d6b4d9e2da8849ac362bcb8d634725b921ebf46c","modified":1584642922115},{"_id":"public/icons/half-circles.svg","hash":"0be6efb2cd315348a5f2f1404da205d11d5e78c3","modified":1584642922115},{"_id":"public/icons/twitter.svg","hash":"dab32630d9eb04c293f9c4775271953d57eb8642","modified":1584642922115},{"_id":"public/icons/github.svg","hash":"4ad3447484a193da8e10d9705ebb598de10873e6","modified":1584642922115},{"_id":"public/images/embark-logo.svg","hash":"682af62e01cd85c11235bd2258b8f87ee9b44afb","modified":1584642922115},{"_id":"public/images/favicon.png","hash":"7f0c4305cd9711e9dd20ac94a5559f4d67a9fe9b","modified":1584642922115},{"_id":"public/images/logo.svg","hash":"e7d3c651b56c2bb890b567a67dd860fc96ad6579","modified":1584642922115},{"_id":"public/images/circles.png","hash":"ca3ed456a67c9c329e638990b9a8805a2f33c68c","modified":1584642922115},{"_id":"public/fonts/LICENSE.txt","hash":"47b573e3824cd5e02a1a3ae99e2735b49e0256e4","modified":1584642922115},{"_id":"public/javascripts/scripts.js","hash":"1f0ee8c12b179a9607cb1848710254652a7332b2","modified":1584642922115},{"_id":"public/css/utilities/text-size.css","hash":"6340d74612d186555e471c57175a5f0a3f661cdc","modified":1584642922115},{"_id":"public/css/utilities/text-color.css","hash":"3d763e25e9078d5375b4fd0d9b100aa1b8a91d93","modified":1584642922115},{"_id":"public/javascripts/jquery.js","hash":"9592732de681f4365e9b7016dc5cf76e2a55ee9b","modified":1584642922115},{"_id":"public/css/application.css","hash":"e7e477ef203d3d902df2518d63ef12731d0a50f8","modified":1584642922115},{"_id":"public/d1.png","hash":"615cbb4801559261ddeaedcda06679dd13ff8f26","modified":1584642922115},{"_id":"public/fonts/Roboto-Bold.ttf","hash":"0ce37ced9c5fcac9bdc452a432c1258870ba4677","modified":1584642922115},{"_id":"public/d4.png","hash":"5cc6b8b2d141e41719bf9ace46d2be80d8236a69","modified":1584642922115},{"_id":"public/d3.png","hash":"ca19a6ae5bf461a92af770d0ed7e82170c27da4a","modified":1584642922115},{"_id":"public/fonts/Roboto-Regular.ttf","hash":"dd1b1db13ff1f72138c134c62f38fef83749f36a","modified":1584642922115},{"_id":"public/d2.png","hash":"87c8eaa980edbe019c706ab8463148227bd25192","modified":1584642922115},{"_id":"source/packages/docs/_data/sidebar.yml","hash":"09bc83728b4dc7a9db44fdfce15769972c1eec3a","modified":1584642530730},{"_id":"source/packages/docs/_posts/hello-world.md","hash":"7d98d6592de80fdcd2949bd7401cec12afd98cdf","modified":1584642530730},{"_id":"source/packages/docs/.DS_Store","hash":"078fc163bb0c365b31f211f49a5e78e2703b3f12","modified":1584643079469}],"Category":[],"Data":[{"_id":"sidebar","data":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}],"Page":[{"_content":"","source":"integrations.md","raw":"","date":"2020-03-19T18:30:37.782Z","updated":"2020-03-19T18:28:50.738Z","path":"integrations.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcks00005cbn2gap6jkg","content":"","site":{"data":{}},"excerpt":"","more":""},{"_content":"# API\n\n## General\n\n### `new Subspace(web3Provider [, options])`\nConstructor. \n\n**Parameters**\n1. `web3Provider` - `Object`: a valid web3 provider.\n2. `options` - `Object` (optional): Options used to initialize Subspace\n\t- `dbFilename` - `String` (optional): Name of the database where the information will be stored (default `'subspace.db'`)\n\t- `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`)\n - `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),\n - `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)\n\n\n### `init()`\nInitializes **Subspace**\n\n**Returns**\n`Promise` that once it's resolved, will mean that **Subspace** is available to use\n\n### `close()`\nDispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution.\n\n### `contract(instance|{abi,address})`\nAdds a `track` method to the web3 contract objects. You can obtain this functionality by passing a `web3.eth.Contract` instance, or the `abi` and `address` of your contract\n\n**Returns**\n`web3.eth.Contract` object enhanced with `.track()` functions for methods and events.\n\n## Contract methods\n\n### `myContract.events.MyEvent.track([options])`\nTrack a contract event.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n\n### `myContract.methods.myMethod([param1[, ...]]).track([callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n\n### `myContract.trackBalance(address [, tokenAddress])`\nTrack a contract's balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n\n## Blocks, gas price and block time\n\n### `trackBlock()`\nReceive the block information for any new block. It's the reactive equivalent to `web3.eth.getBlock(\"latest\")`.\n\n**Returns**\n`RxJS Observable` which will stream a block object for the latest block received\n\n### `trackBlockNumber()`\nReturns the latest block number. It's the reactive equivalent to `web3.eth.getBlockNumber`.\n\n**Returns**\n`RxJS Observable` with the latest block number\n\n### `trackGasPrice()`\nReturns the current gas price oracle. It's the reactive equivalent to `web3.eth.getGasPrice`.\n\n**Returns**\n`RxJS Observable` with the average gas price in wei.\n\n### `trackAverageBlocktime()`\nAverage block time of the last 10 blocks.\n\n**Returns**\n`RxJS Observable` with the moving average block time of the last 10 blocks. The time is returned in milliseconds:\n\n\n## Low level API for data tracking\n\nThese are used in case you don't want to decorate your web3 contract objects, or if you want to track the balance for an specific address.\n\n### `trackEvent(contractObject, eventName [, options])`\nTrack a contract event.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `eventName` - `String`: The name of the event to subscribe.\n3. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n### `trackProperty(contractObject, functionName [, functionArgs] [, callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `functionName` - `String`: Name of the function or variable whose values will be tracked.\n3. `functionArgs` - `Array` (optional): Array of arguments that the tracked function receives\n4. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n### `trackBalance(address [, tokenAddress])`\nTrack balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n### `trackLogs(options [, abi])`\nTracks incoming logs, filtered by the given options.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of logs\n - `address` - `String|Array` (optional): An address or a list of addresses to only get logs from particular account(s).\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `topics` - `Array` (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, '0x00...']. You can also pass another array for each topic with options for that topic e.g. [null, ['option1', 'option2']].\n2. `abi` - `Array` (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.\n\n**Returns**\n`RxJS Observable` which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.","source":"api.md","raw":"# API\n\n## General\n\n### `new Subspace(web3Provider [, options])`\nConstructor. \n\n**Parameters**\n1. `web3Provider` - `Object`: a valid web3 provider.\n2. `options` - `Object` (optional): Options used to initialize Subspace\n\t- `dbFilename` - `String` (optional): Name of the database where the information will be stored (default `'subspace.db'`)\n\t- `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`)\n - `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),\n - `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)\n\n\n### `init()`\nInitializes **Subspace**\n\n**Returns**\n`Promise` that once it's resolved, will mean that **Subspace** is available to use\n\n### `close()`\nDispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution.\n\n### `contract(instance|{abi,address})`\nAdds a `track` method to the web3 contract objects. You can obtain this functionality by passing a `web3.eth.Contract` instance, or the `abi` and `address` of your contract\n\n**Returns**\n`web3.eth.Contract` object enhanced with `.track()` functions for methods and events.\n\n## Contract methods\n\n### `myContract.events.MyEvent.track([options])`\nTrack a contract event.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n\n### `myContract.methods.myMethod([param1[, ...]]).track([callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n\n### `myContract.trackBalance(address [, tokenAddress])`\nTrack a contract's balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n\n## Blocks, gas price and block time\n\n### `trackBlock()`\nReceive the block information for any new block. It's the reactive equivalent to `web3.eth.getBlock(\"latest\")`.\n\n**Returns**\n`RxJS Observable` which will stream a block object for the latest block received\n\n### `trackBlockNumber()`\nReturns the latest block number. It's the reactive equivalent to `web3.eth.getBlockNumber`.\n\n**Returns**\n`RxJS Observable` with the latest block number\n\n### `trackGasPrice()`\nReturns the current gas price oracle. It's the reactive equivalent to `web3.eth.getGasPrice`.\n\n**Returns**\n`RxJS Observable` with the average gas price in wei.\n\n### `trackAverageBlocktime()`\nAverage block time of the last 10 blocks.\n\n**Returns**\n`RxJS Observable` with the moving average block time of the last 10 blocks. The time is returned in milliseconds:\n\n\n## Low level API for data tracking\n\nThese are used in case you don't want to decorate your web3 contract objects, or if you want to track the balance for an specific address.\n\n### `trackEvent(contractObject, eventName [, options])`\nTrack a contract event.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `eventName` - `String`: The name of the event to subscribe.\n3. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n### `trackProperty(contractObject, functionName [, functionArgs] [, callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `functionName` - `String`: Name of the function or variable whose values will be tracked.\n3. `functionArgs` - `Array` (optional): Array of arguments that the tracked function receives\n4. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n### `trackBalance(address [, tokenAddress])`\nTrack balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n### `trackLogs(options [, abi])`\nTracks incoming logs, filtered by the given options.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of logs\n - `address` - `String|Array` (optional): An address or a list of addresses to only get logs from particular account(s).\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `topics` - `Array` (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, '0x00...']. You can also pass another array for each topic with options for that topic e.g. [null, ['option1', 'option2']].\n2. `abi` - `Array` (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.\n\n**Returns**\n`RxJS Observable` which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.","date":"2020-03-19T18:30:40.087Z","updated":"2020-03-19T18:28:50.730Z","path":"api.html","title":"","comments":1,"layout":"page","_id":"ck7z3hckv00015cbn10hj90nw","content":"

API

General

new Subspace(web3Provider [, options])

Constructor.

\n

Parameters

\n
    \n
  1. web3Provider - Object: a valid web3 provider.
  2. \n
  3. options - Object (optional): Options used to initialize Subspace
      \n
    • dbFilename - String (optional): Name of the database where the information will be stored (default 'subspace.db')
    • \n
    • 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)
    • \n
    • 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),
    • \n
    • 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)
    • \n
    \n
  4. \n
\n

init()

Initializes Subspace

\n

Returns
Promise that once it’s resolved, will mean that Subspace is available to use

\n

close()

Dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution.

\n

contract(instance|{abi,address})

Adds a track method to the web3 contract objects. You can obtain this functionality by passing a web3.eth.Contract instance, or the abi and address of your contract

\n

Returns
web3.eth.Contract object enhanced with .track() functions for methods and events.

\n

Contract methods

myContract.events.MyEvent.track([options])

Track a contract event.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

myContract.methods.myMethod([param1[, ...]]).track([callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

myContract.trackBalance(address [, tokenAddress])

Track a contract’s balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

Blocks, gas price and block time

trackBlock()

Receive the block information for any new block. It’s the reactive equivalent to web3.eth.getBlock("latest").

\n

Returns
RxJS Observable which will stream a block object for the latest block received

\n

trackBlockNumber()

Returns the latest block number. It’s the reactive equivalent to web3.eth.getBlockNumber.

\n

Returns
RxJS Observable with the latest block number

\n

trackGasPrice()

Returns the current gas price oracle. It’s the reactive equivalent to web3.eth.getGasPrice.

\n

Returns
RxJS Observable with the average gas price in wei.

\n

trackAverageBlocktime()

Average block time of the last 10 blocks.

\n

Returns
RxJS Observable with the moving average block time of the last 10 blocks. The time is returned in milliseconds:

\n

Low level API for data tracking

These are used in case you don’t want to decorate your web3 contract objects, or if you want to track the balance for an specific address.

\n

trackEvent(contractObject, eventName [, options])

Track a contract event.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. eventName - String: The name of the event to subscribe.
  4. \n
  5. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  6. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

trackProperty(contractObject, functionName [, functionArgs] [, callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. functionName - String: Name of the function or variable whose values will be tracked.
  4. \n
  5. functionArgs - Array (optional): Array of arguments that the tracked function receives
  6. \n
  7. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  8. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

trackBalance(address [, tokenAddress])

Track balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

trackLogs(options [, abi])

Tracks incoming logs, filtered by the given options.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of logs
      \n
    • address - String|Array (optional): An address or a list of addresses to only get logs from particular account(s).
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • topics - Array (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, ‘0x00…’]. You can also pass another array for each topic with options for that topic e.g. [null, [‘option1’, ‘option2’]].
    • \n
    \n
  2. \n
  3. abi - Array (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.
  4. \n
\n

Returns
RxJS Observable which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.

\n","site":{"data":{}},"excerpt":"","more":"

API

General

new Subspace(web3Provider [, options])

Constructor.

\n

Parameters

\n
    \n
  1. web3Provider - Object: a valid web3 provider.
  2. \n
  3. options - Object (optional): Options used to initialize Subspace
      \n
    • dbFilename - String (optional): Name of the database where the information will be stored (default 'subspace.db')
    • \n
    • 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)
    • \n
    • 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),
    • \n
    • 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)
    • \n
    \n
  4. \n
\n

init()

Initializes Subspace

\n

Returns
Promise that once it’s resolved, will mean that Subspace is available to use

\n

close()

Dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution.

\n

contract(instance|{abi,address})

Adds a track method to the web3 contract objects. You can obtain this functionality by passing a web3.eth.Contract instance, or the abi and address of your contract

\n

Returns
web3.eth.Contract object enhanced with .track() functions for methods and events.

\n

Contract methods

myContract.events.MyEvent.track([options])

Track a contract event.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

myContract.methods.myMethod([param1[, ...]]).track([callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

myContract.trackBalance(address [, tokenAddress])

Track a contract’s balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

Blocks, gas price and block time

trackBlock()

Receive the block information for any new block. It’s the reactive equivalent to web3.eth.getBlock("latest").

\n

Returns
RxJS Observable which will stream a block object for the latest block received

\n

trackBlockNumber()

Returns the latest block number. It’s the reactive equivalent to web3.eth.getBlockNumber.

\n

Returns
RxJS Observable with the latest block number

\n

trackGasPrice()

Returns the current gas price oracle. It’s the reactive equivalent to web3.eth.getGasPrice.

\n

Returns
RxJS Observable with the average gas price in wei.

\n

trackAverageBlocktime()

Average block time of the last 10 blocks.

\n

Returns
RxJS Observable with the moving average block time of the last 10 blocks. The time is returned in milliseconds:

\n

Low level API for data tracking

These are used in case you don’t want to decorate your web3 contract objects, or if you want to track the balance for an specific address.

\n

trackEvent(contractObject, eventName [, options])

Track a contract event.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. eventName - String: The name of the event to subscribe.
  4. \n
  5. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  6. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

trackProperty(contractObject, functionName [, functionArgs] [, callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. functionName - String: Name of the function or variable whose values will be tracked.
  4. \n
  5. functionArgs - Array (optional): Array of arguments that the tracked function receives
  6. \n
  7. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  8. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

trackBalance(address [, tokenAddress])

Track balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

trackLogs(options [, abi])

Tracks incoming logs, filtered by the given options.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of logs
      \n
    • address - String|Array (optional): An address or a list of addresses to only get logs from particular account(s).
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • topics - Array (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, ‘0x00…’]. You can also pass another array for each topic with options for that topic e.g. [null, [‘option1’, ‘option2’]].
    • \n
    \n
  2. \n
  3. abi - Array (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.
  4. \n
\n

Returns
RxJS Observable which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.

\n"},{"_content":"# apollo-client\nTo 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`.\n\n```js\nimport { ApolloClient } from \"apollo-client\";\nimport { InMemoryCache } from \"apollo-cache-inmemory\";\nimport { ApolloLink } from \"apollo-link\";\nimport { rxjs as rxJsLink } from \"apollo-link-rxjs\";\nimport { graphql } from \"reactive-graphql\";\n\nconst client = new ApolloClient({\n // If addTypename:true, the query will fail due to __typename\n // being added to the schema. reactive-graphql does not\n // support __typename at this moment.\n cache: new InMemoryCache({ addTypename: false }),\n link: ApolloLink.from([\n rxJsLink({}),\n new ApolloLink(operation => graphql(schema, operation.query))\n ])\n});\n```\n\n### Example\n\n```js{35-45}\nimport { ApolloClient } from \"apollo-client\";\nimport { InMemoryCache } from \"apollo-cache-inmemory\";\nimport { ApolloLink } from \"apollo-link\";\nimport { rxjs as rxJsLink } from \"apollo-link-rxjs\";\nimport { graphql } from \"reactive-graphql\";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\nconst typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n`;\n\nconst resolvers = {\n Query: {\n myEvents: () => {\n return subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n }\n }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n // If addTypename:true, the query will fail due to __typename\n // being added to the schema. reactive-graphql does not\n // support __typename at this moment.\n cache: new InMemoryCache({ addTypename: false }),\n link: ApolloLink.from([\n rxJsLink({}),\n new ApolloLink(operation => graphql(schema, operation.query))\n ])\n});\n```\n\n\n
\nUsing react-apollo\nA practical example can also be found in `examples/react-apollo`.\n
","source":"apollo-client.md","raw":"# apollo-client\nTo 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`.\n\n```js\nimport { ApolloClient } from \"apollo-client\";\nimport { InMemoryCache } from \"apollo-cache-inmemory\";\nimport { ApolloLink } from \"apollo-link\";\nimport { rxjs as rxJsLink } from \"apollo-link-rxjs\";\nimport { graphql } from \"reactive-graphql\";\n\nconst client = new ApolloClient({\n // If addTypename:true, the query will fail due to __typename\n // being added to the schema. reactive-graphql does not\n // support __typename at this moment.\n cache: new InMemoryCache({ addTypename: false }),\n link: ApolloLink.from([\n rxJsLink({}),\n new ApolloLink(operation => graphql(schema, operation.query))\n ])\n});\n```\n\n### Example\n\n```js{35-45}\nimport { ApolloClient } from \"apollo-client\";\nimport { InMemoryCache } from \"apollo-cache-inmemory\";\nimport { ApolloLink } from \"apollo-link\";\nimport { rxjs as rxJsLink } from \"apollo-link-rxjs\";\nimport { graphql } from \"reactive-graphql\";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\nconst typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n`;\n\nconst resolvers = {\n Query: {\n myEvents: () => {\n return subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n }\n }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n // If addTypename:true, the query will fail due to __typename\n // being added to the schema. reactive-graphql does not\n // support __typename at this moment.\n cache: new InMemoryCache({ addTypename: false }),\n link: ApolloLink.from([\n rxJsLink({}),\n new ApolloLink(operation => graphql(schema, operation.query))\n ])\n});\n```\n\n\n
\nUsing react-apollo\nA practical example can also be found in `examples/react-apollo`.\n
","date":"2020-03-19T18:30:40.090Z","updated":"2020-03-19T18:28:50.730Z","path":"apollo-client.html","title":"","comments":1,"layout":"page","_id":"ck7z3hckw00025cbn4pfweo5k","content":"

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.

\n\n\n
import { ApolloClient } from "apollo-client";\nimport { InMemoryCache } from "apollo-cache-inmemory";\nimport { ApolloLink } from "apollo-link";\nimport { rxjs as rxJsLink } from "apollo-link-rxjs";\nimport { graphql } from "reactive-graphql";\n\nconst client = new ApolloClient({\n  // If addTypename:true, the query will fail due to __typename\n  // being added to the schema. reactive-graphql does not\n  // support __typename at this moment.\n  cache: new InMemoryCache({ addTypename: false }),\n  link: ApolloLink.from([\n          rxJsLink({}),\n          new ApolloLink(operation => graphql(schema, operation.query))\n        ])\n});\n
\n\n\n\n

Example

\n\n
import { ApolloClient } from "apollo-client";\nimport { InMemoryCache } from "apollo-cache-inmemory";\nimport { ApolloLink } from "apollo-link";\nimport { rxjs as rxJsLink } from "apollo-link-rxjs";\nimport { graphql } from "reactive-graphql";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\nconst typeDefs = `\n  type MyEvent {\n    someValue: Int\n    anotherValue: String\n  }\n  type Query {\n    myEvents: MyEvent!\n  }\n`;\n\nconst resolvers = {\n  Query: {\n    myEvents: () => {\n      return subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n    }\n  }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n  // If addTypename:true, the query will fail due to __typename\n  // being added to the schema. reactive-graphql does not\n  // support __typename at this moment.\n  cache: new InMemoryCache({ addTypename: false }),\n  link: ApolloLink.from([\n          rxJsLink({}),\n          new ApolloLink(operation => graphql(schema, operation.query))\n        ])\n});\n
\n\n\n\n
\nUsing react-apollo\nA practical example can also be found in `examples/react-apollo`.\n
","site":{"data":{}},"excerpt":"","more":"

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.

\n\n\n
import { ApolloClient } from "apollo-client";\nimport { InMemoryCache } from "apollo-cache-inmemory";\nimport { ApolloLink } from "apollo-link";\nimport { rxjs as rxJsLink } from "apollo-link-rxjs";\nimport { graphql } from "reactive-graphql";\n\nconst client = new ApolloClient({\n  // If addTypename:true, the query will fail due to __typename\n  // being added to the schema. reactive-graphql does not\n  // support __typename at this moment.\n  cache: new InMemoryCache({ addTypename: false }),\n  link: ApolloLink.from([\n          rxJsLink({}),\n          new ApolloLink(operation => graphql(schema, operation.query))\n        ])\n});\n
\n\n\n\n

Example

\n\n
import { ApolloClient } from "apollo-client";\nimport { InMemoryCache } from "apollo-cache-inmemory";\nimport { ApolloLink } from "apollo-link";\nimport { rxjs as rxJsLink } from "apollo-link-rxjs";\nimport { graphql } from "reactive-graphql";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\nconst typeDefs = `\n  type MyEvent {\n    someValue: Int\n    anotherValue: String\n  }\n  type Query {\n    myEvents: MyEvent!\n  }\n`;\n\nconst resolvers = {\n  Query: {\n    myEvents: () => {\n      return subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n    }\n  }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n  // If addTypename:true, the query will fail due to __typename\n  // being added to the schema. reactive-graphql does not\n  // support __typename at this moment.\n  cache: new InMemoryCache({ addTypename: false }),\n  link: ApolloLink.from([\n          rxJsLink({}),\n          new ApolloLink(operation => graphql(schema, operation.query))\n        ])\n});\n
\n\n\n\n
\nUsing react-apollo\nA practical example can also be found in `examples/react-apollo`.\n
"},{"title":"Getting Started","_content":"# Getting Started\n\n## Installation\n**Subspace** can be used in browser, node and native script environments. To get started install the package `@embarklabs/subspace` using `npm` or `yarn` by executing this command in your project directory:\n```bash\n# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n```\n\n## Importing the library\n\n```js\n// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace'; \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n```\n\n\n## Connecting to a web3 provider\nTo interact with the EVM, **Subspace** requires a valid Web3 provider. \n\n```js\nconst subspace = new Subspace(web3.currentProvider);\nawait subspace.init();\n```\n\nIn addition to the provider, `Subspace` also accepts an `options` object with settings that can change its behavior:\n- `dbFilename` - Name of the database where the information will be stored (default `'subspace.db'`)\n- `callInterval` - Interval of time in milliseconds to query a contract/address to determine changes in state or balance (default: `undefined`. Obtains data every block).\n- `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),\n- `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)\n\n\n## Enhancing your contract objects\nSubspace provides a method to enhance your web3 Contract objects: `subspace.contract(instance|{abi,address})`. Calling this method will return a new contract object decorated with a `.track()` method for your contract view functions and events.\n\n```js\nconst myRxContract = subspace.contract(myContractInstance);\n```\n\nYou can also instantiate a contract directly by passing the contract ABI and its address:\n\n```js\nconst myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n```\n\n## Reacting to data\nOnce 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.\n\n
\nWhat is an Observable?\nThe `Observable` type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n#### Further read\n- [RxJS Observables](https://rxjs-dev.firebaseapp.com/guide/observable)\n\n## Tracking state\nYou can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract. \n```js\nconst stateObservable$ = Contract.methods.functionName(functionArgs).track();\n```\n\n
Tracking the public variables of a contract\nState 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).\n
\n\nExample:\n\n```js\nconst productTitle$ = ProductList.methods.products(0).track().map(\"title\");\nproductTitle$.subscribe((title) => console.log(\"product title is \" + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, \"products\", [0], {from: web3.eth.defaultAccount});\n...\n```\n\nThe subscription will be triggered whenever the title changes\n\n## Tracking events\nYou can track events and react to their returned values.\n```js\nconst eventObservable$ = Contract.event.eventName().track();\n```\n\nExample:\n\n```js\nconst rating$ = Product.events.Rating().track().map(\"rating\")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log(\"rating received: \" + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, \"Rating\", {fromBlock: 0});\n...\n```\n\n**Event Sourcing**\n\nYou can easily do event sourcing with subspace.\n\nFor e.g: if you needed to get the average rating of the last 5 events:\n\n```js\nimport { $average, $latest } from \"@embarklabs/subspace\";\n\nconst rating$ = Product.events.Rating().track().map(\"rating\")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n console.log(\"average rating of the last 5 events is \" + rating)\n});\n```\n\n## Tracking balances\nYou can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the `callInterval` configured. \n\nTracking ETH balance in an address:\n\n```js\nconst address = \"0x0001020304050607080900010203040506070809\";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking ETH balance in a Contract:\n\n```js\nContract.trackBalance().subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking an ERC20 balance in a Contract:\n\n```js\nconst tokenAddress = \"0x744d70fdbe2ba4cf95131626614a1763df805b9e\"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n```\n\n
\nBalances are returned as a string containing the value in *wei*.\n
\n\n\n\n## Getting block data, gas prices and block time\nSubspace also provides a way to always receive the latest block object: \n```js\nsubspace.trackBlock().subscribe(block => {\n console.log(\"The latest block data: \", block);\n});\n```\n\nIf you don't need all the block information, but just the block number, you can use instead:\n```js\nsubspace.trackBlockNumber().subscribe(blockNumber => {\n console.log(\"The latest block number: \", blockNumber);\n});\n```\n\nYou can also access the average block time. This takes in account only the last 10 blocks:\n\n```js\nsubspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n console.log(\"The average block time in milliseconds is: \", blocktimeMS);\n});\n```\n\nFinally, if you want to obtain the most up to date median gas price:\n\n```js\nsubspace.trackGasPrice().subscribe(gasPrice => {\n console.log(\"Gas price in wei\", gasPrice);\n});\n```\n\n\n## Subscriptions\nOnce you have an `Observable`, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.\n\nSubscriptions can be disposed by executing the method `unsubscribe()` liberating the resource held by it:\n\n```js\nconst myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n console.log(\"The balance is: \", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n```\n\n#### Further read\n- [RxJS Subscriptions](https://rxjs-dev.firebaseapp.com/guide/subscription)\n\n## Cleanup\nIf **Subspace** is not needed anymore, you need can invoke `close()` to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution, thus avoiding any potential memory leak.\n\n```\nsubspace.close();\n```\n
\nWhat about subscriptions created with our observables?\nAny subscription created via the tracking methods must be unsubscribed manually (in the current version).\n
\n\n","source":"getting-started.md","raw":"\n---\ntitle: Getting Started\n---\n# Getting Started\n\n## Installation\n**Subspace** can be used in browser, node and native script environments. To get started install the package `@embarklabs/subspace` using `npm` or `yarn` by executing this command in your project directory:\n```bash\n# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n```\n\n## Importing the library\n\n```js\n// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace'; \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n```\n\n\n## Connecting to a web3 provider\nTo interact with the EVM, **Subspace** requires a valid Web3 provider. \n\n```js\nconst subspace = new Subspace(web3.currentProvider);\nawait subspace.init();\n```\n\nIn addition to the provider, `Subspace` also accepts an `options` object with settings that can change its behavior:\n- `dbFilename` - Name of the database where the information will be stored (default `'subspace.db'`)\n- `callInterval` - Interval of time in milliseconds to query a contract/address to determine changes in state or balance (default: `undefined`. Obtains data every block).\n- `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),\n- `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)\n\n\n## Enhancing your contract objects\nSubspace provides a method to enhance your web3 Contract objects: `subspace.contract(instance|{abi,address})`. Calling this method will return a new contract object decorated with a `.track()` method for your contract view functions and events.\n\n```js\nconst myRxContract = subspace.contract(myContractInstance);\n```\n\nYou can also instantiate a contract directly by passing the contract ABI and its address:\n\n```js\nconst myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n```\n\n## Reacting to data\nOnce 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.\n\n
\nWhat is an Observable?\nThe `Observable` type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n#### Further read\n- [RxJS Observables](https://rxjs-dev.firebaseapp.com/guide/observable)\n\n## Tracking state\nYou can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract. \n```js\nconst stateObservable$ = Contract.methods.functionName(functionArgs).track();\n```\n\n
Tracking the public variables of a contract\nState 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).\n
\n\nExample:\n\n```js\nconst productTitle$ = ProductList.methods.products(0).track().map(\"title\");\nproductTitle$.subscribe((title) => console.log(\"product title is \" + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, \"products\", [0], {from: web3.eth.defaultAccount});\n...\n```\n\nThe subscription will be triggered whenever the title changes\n\n## Tracking events\nYou can track events and react to their returned values.\n```js\nconst eventObservable$ = Contract.event.eventName().track();\n```\n\nExample:\n\n```js\nconst rating$ = Product.events.Rating().track().map(\"rating\")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log(\"rating received: \" + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, \"Rating\", {fromBlock: 0});\n...\n```\n\n**Event Sourcing**\n\nYou can easily do event sourcing with subspace.\n\nFor e.g: if you needed to get the average rating of the last 5 events:\n\n```js\nimport { $average, $latest } from \"@embarklabs/subspace\";\n\nconst rating$ = Product.events.Rating().track().map(\"rating\")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n console.log(\"average rating of the last 5 events is \" + rating)\n});\n```\n\n## Tracking balances\nYou can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the `callInterval` configured. \n\nTracking ETH balance in an address:\n\n```js\nconst address = \"0x0001020304050607080900010203040506070809\";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking ETH balance in a Contract:\n\n```js\nContract.trackBalance().subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking an ERC20 balance in a Contract:\n\n```js\nconst tokenAddress = \"0x744d70fdbe2ba4cf95131626614a1763df805b9e\"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n```\n\n
\nBalances are returned as a string containing the value in *wei*.\n
\n\n\n\n## Getting block data, gas prices and block time\nSubspace also provides a way to always receive the latest block object: \n```js\nsubspace.trackBlock().subscribe(block => {\n console.log(\"The latest block data: \", block);\n});\n```\n\nIf you don't need all the block information, but just the block number, you can use instead:\n```js\nsubspace.trackBlockNumber().subscribe(blockNumber => {\n console.log(\"The latest block number: \", blockNumber);\n});\n```\n\nYou can also access the average block time. This takes in account only the last 10 blocks:\n\n```js\nsubspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n console.log(\"The average block time in milliseconds is: \", blocktimeMS);\n});\n```\n\nFinally, if you want to obtain the most up to date median gas price:\n\n```js\nsubspace.trackGasPrice().subscribe(gasPrice => {\n console.log(\"Gas price in wei\", gasPrice);\n});\n```\n\n\n## Subscriptions\nOnce you have an `Observable`, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.\n\nSubscriptions can be disposed by executing the method `unsubscribe()` liberating the resource held by it:\n\n```js\nconst myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n console.log(\"The balance is: \", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n```\n\n#### Further read\n- [RxJS Subscriptions](https://rxjs-dev.firebaseapp.com/guide/subscription)\n\n## Cleanup\nIf **Subspace** is not needed anymore, you need can invoke `close()` to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution, thus avoiding any potential memory leak.\n\n```\nsubspace.close();\n```\n
\nWhat about subscriptions created with our observables?\nAny subscription created via the tracking methods must be unsubscribed manually (in the current version).\n
\n\n","date":"2020-03-19T18:30:37.769Z","updated":"2020-03-19T18:28:50.738Z","path":"getting-started.html","comments":1,"layout":"page","_id":"ck7z3hcl300035cbn6eyxc67o","content":"

Getting Started

Installation

Subspace can be used in browser, node and native script environments. To get started install the package @embarklabs/subspace using npm or yarn by executing this command in your project directory:

\n\n\n
# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n
\n\n\n\n

Importing the library

\n\n
// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace';  \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n
\n\n\n\n

Connecting to a web3 provider

To interact with the EVM, Subspace requires a valid Web3 provider.

\n\n\n
const subspace = new Subspace(web3.currentProvider);\nawait subspace.init();\n
\n\n\n\n

In addition to the provider, Subspace also accepts an options object with settings that can change its behavior:

\n\n

Enhancing your contract objects

Subspace provides a method to enhance your web3 Contract objects: subspace.contract(instance|{abi,address}). Calling this method will return a new contract object decorated with a .track() method for your contract view functions and events.

\n\n\n
const myRxContract = subspace.contract(myContractInstance);\n
\n\n\n\n

You can also instantiate a contract directly by passing the contract ABI and its address:

\n\n\n
const myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n
\n\n\n\n

Reacting to data

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.

\n
\nWhat is an Observable?\nThe `Observable` type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n

Further read

\n

Tracking state

You can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract.

\n\n\n
const stateObservable$ = Contract.methods.functionName(functionArgs).track();\n
\n\n\n\n
Tracking the public variables of a contract\nState 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).\n
\n\n

Example:

\n\n\n
const productTitle$ = ProductList.methods.products(0).track().map("title");\nproductTitle$.subscribe((title) => console.log("product title is " + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, "products", [0], {from: web3.eth.defaultAccount});\n...\n
\n\n\n\n

The subscription will be triggered whenever the title changes

\n

Tracking events

You can track events and react to their returned values.

\n\n\n
const eventObservable$ = Contract.event.eventName().track();\n
\n\n\n\n

Example:

\n\n\n
const rating$ = Product.events.Rating().track().map("rating")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log("rating received: " + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, "Rating", {fromBlock: 0});\n...\n
\n\n\n\n

Event Sourcing

\n

You can easily do event sourcing with subspace.

\n

For e.g: if you needed to get the average rating of the last 5 events:

\n\n\n
import { $average, $latest } from "@embarklabs/subspace";\n\nconst rating$ = Product.events.Rating().track().map("rating")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n  console.log("average rating of the last 5 events is " + rating)\n});\n
\n\n\n\n

Tracking balances

You can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the callInterval configured.

\n

Tracking ETH balance in an address:

\n\n\n
const address = "0x0001020304050607080900010203040506070809";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking ETH balance in a Contract:

\n\n\n
Contract.trackBalance().subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking an ERC20 balance in a Contract:

\n\n\n
const tokenAddress = "0x744d70fdbe2ba4cf95131626614a1763df805b9e"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n
\n\n\n\n
\nBalances are returned as a string containing the value in *wei*.\n
\n\n\n\n

Getting block data, gas prices and block time

Subspace also provides a way to always receive the latest block object:

\n\n\n
subspace.trackBlock().subscribe(block => {\n  console.log("The latest block data: ", block);\n});\n
\n\n\n\n

If you don’t need all the block information, but just the block number, you can use instead:

\n\n\n
subspace.trackBlockNumber().subscribe(blockNumber => {\n  console.log("The latest block number: ", blockNumber);\n});\n
\n\n\n\n

You can also access the average block time. This takes in account only the last 10 blocks:

\n\n\n
subspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n  console.log("The average block time in milliseconds is: ", blocktimeMS);\n});\n
\n\n\n\n

Finally, if you want to obtain the most up to date median gas price:

\n\n\n
subspace.trackGasPrice().subscribe(gasPrice => {\n  console.log("Gas price in wei", gasPrice);\n});\n
\n\n\n\n

Subscriptions

Once you have an Observable, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.

\n

Subscriptions can be disposed by executing the method unsubscribe() liberating the resource held by it:

\n\n\n
const myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n  console.log("The balance is: ", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n
\n\n\n\n

Further read

\n

Cleanup

If Subspace is not needed anymore, you need can invoke close() to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution, thus avoiding any potential memory leak.

\n\n\n
subspace.close();\n
\n\n
\nWhat about subscriptions created with our observables?\nAny subscription created via the tracking methods must be unsubscribed manually (in the current version).\n
\n\n","site":{"data":{}},"excerpt":"","more":"

Getting Started

Installation

Subspace can be used in browser, node and native script environments. To get started install the package @embarklabs/subspace using npm or yarn by executing this command in your project directory:

\n\n\n
# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n
\n\n\n\n

Importing the library

\n\n
// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace';  \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n
\n\n\n\n

Connecting to a web3 provider

To interact with the EVM, Subspace requires a valid Web3 provider.

\n\n\n
const subspace = new Subspace(web3.currentProvider);\nawait subspace.init();\n
\n\n\n\n

In addition to the provider, Subspace also accepts an options object with settings that can change its behavior:

\n\n

Enhancing your contract objects

Subspace provides a method to enhance your web3 Contract objects: subspace.contract(instance|{abi,address}). Calling this method will return a new contract object decorated with a .track() method for your contract view functions and events.

\n\n\n
const myRxContract = subspace.contract(myContractInstance);\n
\n\n\n\n

You can also instantiate a contract directly by passing the contract ABI and its address:

\n\n\n
const myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n
\n\n\n\n

Reacting to data

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.

\n
\nWhat is an Observable?\nThe `Observable` type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n

Further read

\n

Tracking state

You can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract.

\n\n\n
const stateObservable$ = Contract.methods.functionName(functionArgs).track();\n
\n\n\n\n
Tracking the public variables of a contract\nState 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).\n
\n\n

Example:

\n\n\n
const productTitle$ = ProductList.methods.products(0).track().map("title");\nproductTitle$.subscribe((title) => console.log("product title is " + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, "products", [0], {from: web3.eth.defaultAccount});\n...\n
\n\n\n\n

The subscription will be triggered whenever the title changes

\n

Tracking events

You can track events and react to their returned values.

\n\n\n
const eventObservable$ = Contract.event.eventName().track();\n
\n\n\n\n

Example:

\n\n\n
const rating$ = Product.events.Rating().track().map("rating")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log("rating received: " + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, "Rating", {fromBlock: 0});\n...\n
\n\n\n\n

Event Sourcing

\n

You can easily do event sourcing with subspace.

\n

For e.g: if you needed to get the average rating of the last 5 events:

\n\n\n
import { $average, $latest } from "@embarklabs/subspace";\n\nconst rating$ = Product.events.Rating().track().map("rating")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n  console.log("average rating of the last 5 events is " + rating)\n});\n
\n\n\n\n

Tracking balances

You can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the callInterval configured.

\n

Tracking ETH balance in an address:

\n\n\n
const address = "0x0001020304050607080900010203040506070809";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking ETH balance in a Contract:

\n\n\n
Contract.trackBalance().subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking an ERC20 balance in a Contract:

\n\n\n
const tokenAddress = "0x744d70fdbe2ba4cf95131626614a1763df805b9e"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n
\n\n\n\n
\nBalances are returned as a string containing the value in *wei*.\n
\n\n\n\n

Getting block data, gas prices and block time

Subspace also provides a way to always receive the latest block object:

\n\n\n
subspace.trackBlock().subscribe(block => {\n  console.log("The latest block data: ", block);\n});\n
\n\n\n\n

If you don’t need all the block information, but just the block number, you can use instead:

\n\n\n
subspace.trackBlockNumber().subscribe(blockNumber => {\n  console.log("The latest block number: ", blockNumber);\n});\n
\n\n\n\n

You can also access the average block time. This takes in account only the last 10 blocks:

\n\n\n
subspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n  console.log("The average block time in milliseconds is: ", blocktimeMS);\n});\n
\n\n\n\n

Finally, if you want to obtain the most up to date median gas price:

\n\n\n
subspace.trackGasPrice().subscribe(gasPrice => {\n  console.log("Gas price in wei", gasPrice);\n});\n
\n\n\n\n

Subscriptions

Once you have an Observable, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.

\n

Subscriptions can be disposed by executing the method unsubscribe() liberating the resource held by it:

\n\n\n
const myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n  console.log("The balance is: ", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n
\n\n\n\n

Further read

\n

Cleanup

If Subspace is not needed anymore, you need can invoke close() to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution, thus avoiding any potential memory leak.

\n\n\n
subspace.close();\n
\n\n
\nWhat about subscriptions created with our observables?\nAny subscription created via the tracking methods must be unsubscribed manually (in the current version).\n
\n\n"},{"_content":"# How it works?\n\n### Setup\n![First Usage - Setup](./d1.png)\n1. A ÐApp requests `Subspace` to track an event, property, or balance.\n2. `Subspace` creates a observable for that event, and a web3 subscription to retrieve events from the chain\n3. The ÐApp subscribes to the observable to receive events.\n\n### Receiving events\n![First Usage - Receiving events](./d2.png)\nDepending on the filter parameters used to track the events, once an event is found, it is stored in `localStorage` and it is also pushed to the observable which delivers it to the ÐApp subscription.\n\n### Tracking already known events \nAfter restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of `Subspace` will change: \n![Second Usage - Setup](./d3.png)\n1. The Dapp will request `Subspace` to track an event it already knows, creating an observable and subscription for that event\n2. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again. \n\n![Second Usage - Receiving events](./d4.png)\nThe web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step\n","source":"how-it-works.md","raw":"# How it works?\n\n### Setup\n![First Usage - Setup](./d1.png)\n1. A ÐApp requests `Subspace` to track an event, property, or balance.\n2. `Subspace` creates a observable for that event, and a web3 subscription to retrieve events from the chain\n3. The ÐApp subscribes to the observable to receive events.\n\n### Receiving events\n![First Usage - Receiving events](./d2.png)\nDepending on the filter parameters used to track the events, once an event is found, it is stored in `localStorage` and it is also pushed to the observable which delivers it to the ÐApp subscription.\n\n### Tracking already known events \nAfter restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of `Subspace` will change: \n![Second Usage - Setup](./d3.png)\n1. The Dapp will request `Subspace` to track an event it already knows, creating an observable and subscription for that event\n2. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again. \n\n![Second Usage - Receiving events](./d4.png)\nThe web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step\n","date":"2020-03-19T18:30:37.772Z","updated":"2020-03-19T18:28:50.738Z","path":"how-it-works.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl400045cbnewgsc9im","content":"

How it works?

Setup

\"First

\n
    \n
  1. A ÐApp requests Subspace to track an event, property, or balance.
  2. \n
  3. Subspace creates a observable for that event, and a web3 subscription to retrieve events from the chain
  4. \n
  5. The ÐApp subscribes to the observable to receive events.
  6. \n
\n

Receiving events

\"First
Depending on the filter parameters used to track the events, once an event is found, it is stored in localStorage and it is also pushed to the observable which delivers it to the ÐApp subscription.

\n

Tracking already known events

After restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of Subspace will change:
\"Second

\n
    \n
  1. The Dapp will request Subspace to track an event it already knows, creating an observable and subscription for that event
  2. \n
  3. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again.
  4. \n
\n

\"Second
The web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step

\n","site":{"data":{}},"excerpt":"","more":"

How it works?

Setup

\"First

\n
    \n
  1. A ÐApp requests Subspace to track an event, property, or balance.
  2. \n
  3. Subspace creates a observable for that event, and a web3 subscription to retrieve events from the chain
  4. \n
  5. The ÐApp subscribes to the observable to receive events.
  6. \n
\n

Receiving events

\"First
Depending on the filter parameters used to track the events, once an event is found, it is stored in localStorage and it is also pushed to the observable which delivers it to the ÐApp subscription.

\n

Tracking already known events

After restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of Subspace will change:
\"Second

\n
    \n
  1. The Dapp will request Subspace to track an event it already knows, creating an observable and subscription for that event
  2. \n
  3. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again.
  4. \n
\n

\"Second
The web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step

\n"},{"title":"Homepage","_content":"","source":"index.md","raw":"title: Homepage\n---\n","date":"2020-03-19T18:30:37.775Z","updated":"2020-03-19T18:28:50.738Z","path":"index.html","comments":1,"layout":"page","_id":"ck7z3hcl400055cbn8ipl2hj7","content":"","site":{"data":{}},"excerpt":"","more":""},{"_content":"# reactive-graphql\n\nUsing `reactive-graphql` you can execute GraphQL queries against **Subspace** observables after you create your own type definitions and resolvers.\n\n### Example\n\n\n```js\nconst Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require(\"graphql-tools\");\nconst gql = require(\"graphql-tag\");\nconst { graphql } = require(\"reactive-graphql\");\n\nconst run = async () => {\n const subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\n await subspace.init();\n\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n `;\n\n const resolvers = {\n Query: {\n myEvents: () => {\n return subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n }\n }\n };\n\n const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n const query = gql`\n query {\n myEvents {\n someValue\n anotherValue\n }\n }\n `;\n\n const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n stream.subscribe(data => {\n console.log(data);\n })\n\n}\n\nrun();\n```\n\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/reactive-graphql)\n
","source":"reactive-graphql.md","raw":"# reactive-graphql\n\nUsing `reactive-graphql` you can execute GraphQL queries against **Subspace** observables after you create your own type definitions and resolvers.\n\n### Example\n\n\n```js\nconst Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require(\"graphql-tools\");\nconst gql = require(\"graphql-tag\");\nconst { graphql } = require(\"reactive-graphql\");\n\nconst run = async () => {\n const subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\n await subspace.init();\n\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n `;\n\n const resolvers = {\n Query: {\n myEvents: () => {\n return subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n }\n }\n };\n\n const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n const query = gql`\n query {\n myEvents {\n someValue\n anotherValue\n }\n }\n `;\n\n const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n stream.subscribe(data => {\n console.log(data);\n })\n\n}\n\nrun();\n```\n\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/reactive-graphql)\n
","date":"2020-03-19T18:30:46.250Z","updated":"2020-03-19T18:28:50.738Z","path":"reactive-graphql.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl500065cbn1hki9bhm","content":"

reactive-graphql

Using reactive-graphql you can execute GraphQL queries against Subspace observables after you create your own type definitions and resolvers.

\n

Example

\n\n
const Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require("graphql-tools");\nconst gql = require("graphql-tag");\nconst { graphql } = require("reactive-graphql");\n\nconst run = async () => {\n  const subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\n  await subspace.init();\n\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const typeDefs = `\n    type MyEvent {\n      someValue: Int\n      anotherValue: String\n    }\n    type Query {\n      myEvents: MyEvent!\n    }\n  `;\n\n  const resolvers = {\n    Query: {\n      myEvents: () => {\n        return subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n      }\n    }\n  };\n\n  const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n  const query = gql`\n    query {\n      myEvents {\n        someValue\n        anotherValue\n      }\n    }\n  `;\n\n  const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n  stream.subscribe(data => {\n    console.log(data);\n  })\n\n}\n\nrun();\n
\n\n\n\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/reactive-graphql)\n
","site":{"data":{}},"excerpt":"","more":"

reactive-graphql

Using reactive-graphql you can execute GraphQL queries against Subspace observables after you create your own type definitions and resolvers.

\n

Example

\n\n
const Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require("graphql-tools");\nconst gql = require("graphql-tag");\nconst { graphql } = require("reactive-graphql");\n\nconst run = async () => {\n  const subspace = new Subspace(web3.currentProvider); // Use a valid provider (geth, parity, infura...)\n  await subspace.init();\n\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const typeDefs = `\n    type MyEvent {\n      someValue: Int\n      anotherValue: String\n    }\n    type Query {\n      myEvents: MyEvent!\n    }\n  `;\n\n  const resolvers = {\n    Query: {\n      myEvents: () => {\n        return subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n      }\n    }\n  };\n\n  const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n  const query = gql`\n    query {\n      myEvents {\n        someValue\n        anotherValue\n      }\n    }\n  `;\n\n  const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n  stream.subscribe(data => {\n    console.log(data);\n  })\n\n}\n\nrun();\n
\n\n\n\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/reactive-graphql)\n
"},{"_content":"# React\nWe provide a higher-order component to connect to enhance presentational components to react to any observable (not limited to those generated by **Subspace**). \n\n### Usage\n```js\nimport { observe } from '@embarklabs/subspace/react';\n\nconst ObserverComponent = observe(WrappedComponent);\n```\n\nThis enhanced component will subscribe to any observable property it receives when the component is mounted and automatically unsubscribe when the component is unmounted.\n\n### Example\n\n
\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n
\n\n\n#### MyComponentObserver.js\n```js\nimport React from \"react\";\nimport ReactDOM from 'react-dom';\nimport {observe} from \"@embarklabs/subspace/react\";\n\nconst MyComponent = ({eventData}) => {\n // Handle initial state when no data is available\n if (!eventData) {\n return

No data

;\n }\n \n return

{eventData.someReturnedValue}

\n};\n\n// MyComponent will now observe any observable prop it receives\n// and update its state whenever the observable emits an event\nexport default observe(MyComponent);\n```\n\n#### App.js\n```js\nimport React, {Component} from 'react';\nimport ReactDOM from 'react-dom';\nimport Subspace from '@embarklabs/subspace';\n\nimport MyComponentObserver from './MyComponentObserver';\n\nclass App extends Component {\n state = {\n myEventObservable$: null\n }\n\n async componentDidMount() {\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const subspace = new Subspace(\"wss://localhost:8545\"); // Use a valid provider (geth, parity, infura...)\n await subspace.init()\n \n const myEventObservable$ = subspace.trackEvent(MyContractInstance, \"MyEvent\", {filter: {}, fromBlock: 1 });\n this.setState({ myEventObservable$ });\n }\n\n render() {\n return ;\n }\n}\n\nexport default App;\n```\n\n
\nHandling Contract Objects\nThe 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))\n
\n\n#### index.js\n```js\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nReactDOM.render(, document.getElementById('root'));\n```\n\n\n```js\nimport { observe } from \"@embarklabs/subspace/react\";\n\nconst ProductComponent = ({ maxRating, minRating, averageRating }) => {\n return
    \n
  • minimum rating: {minRating}
  • \n
  • maximum rating: {maxRating}
  • \n
  • average rating: {averageRating}
  • \n
;\n};\n\nconst ReactiveProductComponent = observe(ProductComponent);\n\nconst Product = subspace.contract({abi, address});\nconst rating$ = Product.events.Rating.track().map(\"rating\").pipe(map(x => parseInt(x)));\n\nReactDOM.render(\n ,\n document.getElementById('hello-example')\n);\n```\n","source":"react.md","raw":"# React\nWe provide a higher-order component to connect to enhance presentational components to react to any observable (not limited to those generated by **Subspace**). \n\n### Usage\n```js\nimport { observe } from '@embarklabs/subspace/react';\n\nconst ObserverComponent = observe(WrappedComponent);\n```\n\nThis enhanced component will subscribe to any observable property it receives when the component is mounted and automatically unsubscribe when the component is unmounted.\n\n### Example\n\n
\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n
\n\n\n#### MyComponentObserver.js\n```js\nimport React from \"react\";\nimport ReactDOM from 'react-dom';\nimport {observe} from \"@embarklabs/subspace/react\";\n\nconst MyComponent = ({eventData}) => {\n // Handle initial state when no data is available\n if (!eventData) {\n return

No data

;\n }\n \n return

{eventData.someReturnedValue}

\n};\n\n// MyComponent will now observe any observable prop it receives\n// and update its state whenever the observable emits an event\nexport default observe(MyComponent);\n```\n\n#### App.js\n```js\nimport React, {Component} from 'react';\nimport ReactDOM from 'react-dom';\nimport Subspace from '@embarklabs/subspace';\n\nimport MyComponentObserver from './MyComponentObserver';\n\nclass App extends Component {\n state = {\n myEventObservable$: null\n }\n\n async componentDidMount() {\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const subspace = new Subspace(\"wss://localhost:8545\"); // Use a valid provider (geth, parity, infura...)\n await subspace.init()\n \n const myEventObservable$ = subspace.trackEvent(MyContractInstance, \"MyEvent\", {filter: {}, fromBlock: 1 });\n this.setState({ myEventObservable$ });\n }\n\n render() {\n return ;\n }\n}\n\nexport default App;\n```\n\n
\nHandling Contract Objects\nThe 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))\n
\n\n#### index.js\n```js\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nReactDOM.render(, document.getElementById('root'));\n```\n\n\n```js\nimport { observe } from \"@embarklabs/subspace/react\";\n\nconst ProductComponent = ({ maxRating, minRating, averageRating }) => {\n return
    \n
  • minimum rating: {minRating}
  • \n
  • maximum rating: {maxRating}
  • \n
  • average rating: {averageRating}
  • \n
;\n};\n\nconst ReactiveProductComponent = observe(ProductComponent);\n\nconst Product = subspace.contract({abi, address});\nconst rating$ = Product.events.Rating.track().map(\"rating\").pipe(map(x => parseInt(x)));\n\nReactDOM.render(\n ,\n document.getElementById('hello-example')\n);\n```\n","date":"2020-03-19T18:30:46.246Z","updated":"2020-03-19T18:28:50.738Z","path":"react.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl600075cbn76084luf","content":"

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).

\n

Usage

\n\n
import { observe } from '@embarklabs/subspace/react';\n\nconst ObserverComponent = observe(WrappedComponent);\n
\n\n\n\n

This enhanced component will subscribe to any observable property it receives when the component is mounted and automatically unsubscribe when the component is unmounted.

\n

Example

\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n
\n\n\n

MyComponentObserver.js

\n\n
import React from "react";\nimport ReactDOM from 'react-dom';\nimport {observe} from "@embarklabs/subspace/react";\n\nconst MyComponent = ({eventData}) => {\n  // Handle initial state when no data is available\n  if (!eventData) {\n    return <p>No data</p>;\n  }\n  \n  return <p>{eventData.someReturnedValue}</p>\n};\n\n// MyComponent will now observe any observable prop it receives\n// and update its state whenever the observable emits an event\nexport default observe(MyComponent);\n
\n\n\n\n

App.js

\n\n
import React, {Component} from 'react';\nimport ReactDOM from 'react-dom';\nimport Subspace from '@embarklabs/subspace';\n\nimport MyComponentObserver from './MyComponentObserver';\n\nclass App extends Component {\n  state = {\n    myEventObservable$: null\n  }\n\n  async componentDidMount() {\n    const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n    const subspace = new Subspace("wss://localhost:8545"); // Use a valid provider (geth, parity, infura...)\n    await subspace.init()\n    \n    const myEventObservable$ = subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });\n    this.setState({ myEventObservable$ });\n  }\n\n  render() {\n    return <MyComponentObserver eventData={this.state.myEventObservable$} />;\n  }\n}\n\nexport default App;\n
\n\n\n\n
\nHandling Contract Objects\nThe 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))\n
\n\n

index.js

\n\n
import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nReactDOM.render(<App />, document.getElementById('root'));\n
\n\n\n\n\n\n
import { observe } from "@embarklabs/subspace/react";\n\nconst ProductComponent = ({ maxRating, minRating, averageRating }) => {\n  return <ul>\n    <li><b>minimum rating: </b> {minRating}</li>\n    <li><b>maximum rating: </b> {maxRating}</li>\n    <li><b>average rating: </b> {averageRating}</li>\n  </ul>;\n};\n\nconst ReactiveProductComponent = observe(ProductComponent);\n\nconst Product = subspace.contract({abi, address});\nconst rating$ = Product.events.Rating.track().map("rating").pipe(map(x => parseInt(x)));\n\nReactDOM.render(\n  <ReactiveProductComponent\n    maxRating={rating$.pipe($max())}\n    minRating={rating$.pipe($min())}\n    averageRating={rating$.pipe($average())}\n  />,\n  document.getElementById('hello-example')\n);\n
\n\n\n","site":{"data":{}},"excerpt":"","more":"

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).

\n

Usage

\n\n
import { observe } from '@embarklabs/subspace/react';\n\nconst ObserverComponent = observe(WrappedComponent);\n
\n\n\n\n

This enhanced component will subscribe to any observable property it receives when the component is mounted and automatically unsubscribe when the component is unmounted.

\n

Example

\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n
\n\n\n

MyComponentObserver.js

\n\n
import React from "react";\nimport ReactDOM from 'react-dom';\nimport {observe} from "@embarklabs/subspace/react";\n\nconst MyComponent = ({eventData}) => {\n  // Handle initial state when no data is available\n  if (!eventData) {\n    return <p>No data</p>;\n  }\n  \n  return <p>{eventData.someReturnedValue}</p>\n};\n\n// MyComponent will now observe any observable prop it receives\n// and update its state whenever the observable emits an event\nexport default observe(MyComponent);\n
\n\n\n\n

App.js

\n\n
import React, {Component} from 'react';\nimport ReactDOM from 'react-dom';\nimport Subspace from '@embarklabs/subspace';\n\nimport MyComponentObserver from './MyComponentObserver';\n\nclass App extends Component {\n  state = {\n    myEventObservable$: null\n  }\n\n  async componentDidMount() {\n    const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n    const subspace = new Subspace("wss://localhost:8545"); // Use a valid provider (geth, parity, infura...)\n    await subspace.init()\n    \n    const myEventObservable$ = subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });\n    this.setState({ myEventObservable$ });\n  }\n\n  render() {\n    return <MyComponentObserver eventData={this.state.myEventObservable$} />;\n  }\n}\n\nexport default App;\n
\n\n\n\n
\nHandling Contract Objects\nThe 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))\n
\n\n

index.js

\n\n
import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nReactDOM.render(<App />, document.getElementById('root'));\n
\n\n\n\n\n\n
import { observe } from "@embarklabs/subspace/react";\n\nconst ProductComponent = ({ maxRating, minRating, averageRating }) => {\n  return <ul>\n    <li><b>minimum rating: </b> {minRating}</li>\n    <li><b>maximum rating: </b> {maxRating}</li>\n    <li><b>average rating: </b> {averageRating}</li>\n  </ul>;\n};\n\nconst ReactiveProductComponent = observe(ProductComponent);\n\nconst Product = subspace.contract({abi, address});\nconst rating$ = Product.events.Rating.track().map("rating").pipe(map(x => parseInt(x)));\n\nReactDOM.render(\n  <ReactiveProductComponent\n    maxRating={rating$.pipe($max())}\n    minRating={rating$.pipe($min())}\n    averageRating={rating$.pipe($average())}\n  />,\n  document.getElementById('hello-example')\n);\n
\n\n\n"},{"_content":"# Integrations with other frameworks\n\n**Subspace** does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate **Subspace** with various frontend frameworks and libraries","source":"integrations-overview.md","raw":"# Integrations with other frameworks\n\n**Subspace** does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate **Subspace** with various frontend frameworks and libraries","date":"2020-03-19T18:30:37.779Z","updated":"2020-03-19T18:28:50.738Z","path":"integrations-overview.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl600085cbn32fk804l","content":"

Integrations with other frameworks

Subspace does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate Subspace with various frontend frameworks and libraries

\n","site":{"data":{}},"excerpt":"","more":"

Integrations with other frameworks

Subspace does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate Subspace with various frontend frameworks and libraries

\n"},{"_content":"# redux \n\n**Subspace** can be used with [redux](https://redux.js.org/). **Subspace** returns [`Observables`](https://rxjs-dev.firebaseapp.com/guide/observable), which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.\n\n### Example\nHere's a simple example on how to setup **Subspace** to work with `redux`:\n\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux)\n
\n\n#### index.js\n```js\nimport store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const subspace = new Subspace(\"ws://localhost:8545\"); // Use a valid provider (geth, parity, infura...)\n await subspace.init();\n \n subspace.trackEvent(MyContractInstance, \"MyEvent\", {filter: {}, fromBlock: 1 })\n .subscribe(eventData => {\n store.dispatch(myAction(eventData));\n });\n}\n\nrun();\n```\n
Handling Contract Objects\nThe 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))\n
\n\n#### store.js\n```js\nimport { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n```\n\n#### reducer.js\n```js\nimport { MY_ACTION } from \"./constants\";\n\nconst initialState = { \n data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n switch (action.type) {\n case MY_ACTION:\n return { data: action.eventData };\n default:\n return state;\n }\n};\n```\n\n#### constants.js\n```js\nexport const MY_ACTION = 'MY_ACTION';\n```\n\n#### actions.js\n```js\nimport {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n```\n\n
\nUsing React and Redux\nA practical example can also be found in `examples/react-redux`.\n
","source":"redux.md","raw":"# redux \n\n**Subspace** can be used with [redux](https://redux.js.org/). **Subspace** returns [`Observables`](https://rxjs-dev.firebaseapp.com/guide/observable), which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.\n\n### Example\nHere's a simple example on how to setup **Subspace** to work with `redux`:\n\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux)\n
\n\n#### index.js\n```js\nimport store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const subspace = new Subspace(\"ws://localhost:8545\"); // Use a valid provider (geth, parity, infura...)\n await subspace.init();\n \n subspace.trackEvent(MyContractInstance, \"MyEvent\", {filter: {}, fromBlock: 1 })\n .subscribe(eventData => {\n store.dispatch(myAction(eventData));\n });\n}\n\nrun();\n```\n
Handling Contract Objects\nThe 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))\n
\n\n#### store.js\n```js\nimport { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n```\n\n#### reducer.js\n```js\nimport { MY_ACTION } from \"./constants\";\n\nconst initialState = { \n data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n switch (action.type) {\n case MY_ACTION:\n return { data: action.eventData };\n default:\n return state;\n }\n};\n```\n\n#### constants.js\n```js\nexport const MY_ACTION = 'MY_ACTION';\n```\n\n#### actions.js\n```js\nimport {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n```\n\n
\nUsing React and Redux\nA practical example can also be found in `examples/react-redux`.\n
","date":"2020-03-19T18:30:46.258Z","updated":"2020-03-19T18:28:50.739Z","path":"redux.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl700095cbn0x9h37v1","content":"

redux

Subspace can be used with redux. Subspace returns Observables, which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.

\n

Example

Here’s a simple example on how to setup Subspace to work with redux:

\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux)\n
\n\n

index.js

\n\n
import store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const subspace = new Subspace("ws://localhost:8545"); // Use a valid provider (geth, parity, infura...)\n  await subspace.init();\n    \n  subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 })\n             .subscribe(eventData => {\n               store.dispatch(myAction(eventData));\n             });\n}\n\nrun();\n
\n\n
Handling Contract Objects\nThe 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))\n
\n\n

store.js

\n\n
import { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n
\n\n\n\n

reducer.js

\n\n
import { MY_ACTION } from "./constants";\n\nconst initialState = { \n  data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n  switch (action.type) {\n    case MY_ACTION:\n      return { data: action.eventData };\n    default:\n      return state;\n  }\n};\n
\n\n\n\n

constants.js

\n\n
export const MY_ACTION = 'MY_ACTION';\n
\n\n\n\n

actions.js

\n\n
import {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n
\n\n\n\n
\nUsing React and Redux\nA practical example can also be found in `examples/react-redux`.\n
","site":{"data":{}},"excerpt":"","more":"

redux

Subspace can be used with redux. Subspace returns Observables, which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.

\n

Example

Here’s a simple example on how to setup Subspace to work with redux:

\n
\nThis example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux)\n
\n\n

index.js

\n\n
import store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const subspace = new Subspace("ws://localhost:8545"); // Use a valid provider (geth, parity, infura...)\n  await subspace.init();\n    \n  subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 })\n             .subscribe(eventData => {\n               store.dispatch(myAction(eventData));\n             });\n}\n\nrun();\n
\n\n
Handling Contract Objects\nThe 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))\n
\n\n

store.js

\n\n
import { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n
\n\n\n\n

reducer.js

\n\n
import { MY_ACTION } from "./constants";\n\nconst initialState = { \n  data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n  switch (action.type) {\n    case MY_ACTION:\n      return { data: action.eventData };\n    default:\n      return state;\n  }\n};\n
\n\n\n\n

constants.js

\n\n
export const MY_ACTION = 'MY_ACTION';\n
\n\n\n\n

actions.js

\n\n
import {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n
\n\n\n\n
\nUsing React and Redux\nA practical example can also be found in `examples/react-redux`.\n
"},{"_content":"# redux-observable\n\n[redux-observables](https://redux-observable.js.org/) can be used to manage side effects via `Epics` (their core primitive to receive and create stream of actions). **Subspace** can be configured inside these epics. \n\nIt's recommended to compose these epics by using [mergeMap](https://www.learnrxjs.io/operators/transformation/mergemap.html) or [switchMap](https://www.learnrxjs.io/operators/transformation/switchmap.html) operators.\n\nHere's an example on how to use **Subspace** to subscribe to an Event when the action `SOME_ACTION` is dispatched, and then it will trigger `myAction` when the observable emits a value.\n\n```js\n// ...\n\nconst myEpic = action$ =>\n action$.pipe(\n ofType(\"SOME_ACTION\"), // Execute when the action type is 'INIT'\n switchMap(action =>\n subspace\n .trackEvent(MyContract, \"MyEventName\", { filter: {}, fromBlock: 1})\n .pipe(\n map(myAction) // Trigger redux action: MY_ACTION with the eventData\n )\n )\n );\n\n// ...\n```\n\n
\nAn example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux-observable)\n
\n\n#### Further read\n- [Epics](https://redux-observable.js.org/docs/basics/Epics.html)\n\n","source":"redux-observable.md","raw":"# redux-observable\n\n[redux-observables](https://redux-observable.js.org/) can be used to manage side effects via `Epics` (their core primitive to receive and create stream of actions). **Subspace** can be configured inside these epics. \n\nIt's recommended to compose these epics by using [mergeMap](https://www.learnrxjs.io/operators/transformation/mergemap.html) or [switchMap](https://www.learnrxjs.io/operators/transformation/switchmap.html) operators.\n\nHere's an example on how to use **Subspace** to subscribe to an Event when the action `SOME_ACTION` is dispatched, and then it will trigger `myAction` when the observable emits a value.\n\n```js\n// ...\n\nconst myEpic = action$ =>\n action$.pipe(\n ofType(\"SOME_ACTION\"), // Execute when the action type is 'INIT'\n switchMap(action =>\n subspace\n .trackEvent(MyContract, \"MyEventName\", { filter: {}, fromBlock: 1})\n .pipe(\n map(myAction) // Trigger redux action: MY_ACTION with the eventData\n )\n )\n );\n\n// ...\n```\n\n
\nAn example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux-observable)\n
\n\n#### Further read\n- [Epics](https://redux-observable.js.org/docs/basics/Epics.html)\n\n","date":"2020-03-19T18:30:46.255Z","updated":"2020-03-19T18:28:50.739Z","path":"redux-observable.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl8000a5cbn6njw8eta","content":"

redux-observable

redux-observables can be used to manage side effects via Epics (their core primitive to receive and create stream of actions). Subspace can be configured inside these epics.

\n

It’s recommended to compose these epics by using mergeMap or switchMap operators.

\n

Here’s an example on how to use Subspace to subscribe to an Event when the action SOME_ACTION is dispatched, and then it will trigger myAction when the observable emits a value.

\n\n\n
// ...\n\nconst myEpic = action$ =>\n  action$.pipe(\n    ofType("SOME_ACTION"),  // Execute when the action type is 'INIT'\n    switchMap(action =>\n      subspace\n        .trackEvent(MyContract, "MyEventName", { filter: {}, fromBlock: 1})\n        .pipe(\n          map(myAction) // Trigger redux action: MY_ACTION with the eventData\n        )\n    )\n  );\n\n// ...\n
\n\n\n\n
\nAn example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux-observable)\n
\n\n

Further read

\n","site":{"data":{}},"excerpt":"","more":"

redux-observable

redux-observables can be used to manage side effects via Epics (their core primitive to receive and create stream of actions). Subspace can be configured inside these epics.

\n

It’s recommended to compose these epics by using mergeMap or switchMap operators.

\n

Here’s an example on how to use Subspace to subscribe to an Event when the action SOME_ACTION is dispatched, and then it will trigger myAction when the observable emits a value.

\n\n\n
// ...\n\nconst myEpic = action$ =>\n  action$.pipe(\n    ofType("SOME_ACTION"),  // Execute when the action type is 'INIT'\n    switchMap(action =>\n      subspace\n        .trackEvent(MyContract, "MyEventName", { filter: {}, fromBlock: 1})\n        .pipe(\n          map(myAction) // Trigger redux action: MY_ACTION with the eventData\n        )\n    )\n  );\n\n// ...\n
\n\n\n\n
\nAn example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux-observable)\n
\n\n

Further read

\n"},{"_content":"# Creating a reactive ÐApp with React and Subspace\n\nSee example DApp at [https://github.com/embark-framework/subspace/tree/master/examples/react-example1](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n\n","source":"tutorial.md","raw":"# Creating a reactive ÐApp with React and Subspace\n\nSee example DApp at [https://github.com/embark-framework/subspace/tree/master/examples/react-example1](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n\n","date":"2020-03-19T18:30:46.261Z","updated":"2020-03-19T18:28:50.739Z","path":"tutorial.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl8000b5cbn9b5ccrit","content":"

Creating a reactive ÐApp with React and Subspace

See example DApp at https://github.com/embark-framework/subspace/tree/master/examples/react-example1

\n","site":{"data":{}},"excerpt":"","more":"

Creating a reactive ÐApp with React and Subspace

See example DApp at https://github.com/embark-framework/subspace/tree/master/examples/react-example1

\n"},{"home":true,"heroImage":"/assets/img/logo.svg","heroText":" ","actionText":"Get Started","actionLink":"/getting-started/","footer":"MIT Licensed | Subspace is part of the Status Network","features":[{"title":"Automatic Syncing","details":"Subspace takes care of syncing under the hood, syncing exactly what you need when you need it. It saves the state to a local database ensuring the DApp always syncs from the last known point even after reloading the DApp."},{"title":"Reactive","details":"Subspace embraces reactive programming with RxJS. It provides methods to track and subscribe to events, contract state & balances, and react to changes via observables."},{"title":"Framework Agnostic","details":"Subspace is framework agnostic and integrates well with your favourite frameworks, from React to Angular. It works in the browser and in nodejs."}],"_content":"\n---\n\n\n","source":"readme.md","raw":"---\nhome: true\nheroImage: /assets/img/logo.svg\nheroText: \" \"\nactionText: Get Started\nactionLink: /getting-started/\nfooter: MIT Licensed | Subspace is part of the Status Network \nfeatures:\n- title: Automatic Syncing\n details: Subspace takes care of syncing under the hood, syncing exactly what you need when you need it. It saves the state to a local database ensuring the DApp always syncs from the last known point even after reloading the DApp.\n- title: Reactive\n details: Subspace embraces reactive programming with RxJS. It provides methods to track and subscribe to events, contract state & balances, and react to changes via observables.\n- title: Framework Agnostic\n details: Subspace is framework agnostic and integrates well with your favourite frameworks, from React to Angular. It works in the browser and in nodejs.\n\n---\n\n---\n\n\n","date":"2020-03-19T18:30:46.253Z","updated":"2020-03-19T18:28:50.739Z","path":"readme.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcl9000c5cbnenkva87k","content":"
\n\n","site":{"data":{}},"excerpt":"","more":"
\n\n"},{"_content":"# Vue\nVue provides the official npm package `vue-rx` that provides RxJS integration, which simplifies the use of Subspace with Vue.js\n\n### Example\n\n
\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/vue)\n
\n\n\n#### MyComponent.vue\n```js\n\n\n\n```\n\n#### App.vue\n```js\n\n\n\n```\n\n\n\n#### Further read\n- [vue-rx](https://www.npmjs.com/package/vue-rx)\n","source":"vue.md","raw":"# Vue\nVue provides the official npm package `vue-rx` that provides RxJS integration, which simplifies the use of Subspace with Vue.js\n\n### Example\n\n
\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/vue)\n
\n\n\n#### MyComponent.vue\n```js\n\n\n\n```\n\n#### App.vue\n```js\n\n\n\n```\n\n\n\n#### Further read\n- [vue-rx](https://www.npmjs.com/package/vue-rx)\n","date":"2020-03-19T18:30:46.263Z","updated":"2020-03-19T18:28:50.739Z","path":"vue.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcla000d5cbnbcbx0pk7","content":"

Vue

Vue provides the official npm package vue-rx that provides RxJS integration, which simplifies the use of Subspace with Vue.js

\n

Example

\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/vue)\n
\n\n\n

MyComponent.vue

\n\n
<template>\n  <ul v-if="!!eventData$">\n    <li><b>someValue: </b> {{eventData$.someValue}}</li>\n    <li><b>anotherValue: </b> {{eventData$.anotherValue}}</li>\n  </ul>\n</template>\n\n<script>\nexport default {\n  name: 'MyComponent',\n  props: {\n    eventData: Object\n  },\n  subscriptions() { // provide Rx observables\n    return {\n      eventData$: this.eventData\n    }\n  }\n}\n</script>\n
\n\n\n\n

App.vue

\n\n
<template>\n  <div id="app">\n    <button v-on:click="createTrx">Create a Transaction</button>\n    <MyComponent v-bind:event-data="myEventObservable$" v-if="!!myEventObservable$" />\n  </div>\n</template>\n\n<script>\nimport MyComponent from './components/MyComponent.vue';\nimport Subspace from "@embarklabs/subspace";\n\nexport default {\n  name: 'app',\n  data: function(){\n    return {\n      myEventObservable$: null,\n      MyContractInstance: null\n    };\n  },\n  created: async function(){\n    this.MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n    const subspace = new Subspace("wss://localhost:8545"); // Use a valid provider (geth, parity, infura...)\n    await subspace.init();\n\n    this.myEventObservable$ = subspace.trackEvent(this.MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });\n  }, \n  methods: {\n    createTrx: function(){\n      this.MyContractInstance.methods\n        .myFunction()\n        .send({ from: web3.eth.defaultAccount });\n    }\n  },\n  components: {\n    MyComponent\n  }\n}\n</script>\n
\n\n\n\n

Further read

\n","site":{"data":{}},"excerpt":"","more":"

Vue

Vue provides the official npm package vue-rx that provides RxJS integration, which simplifies the use of Subspace with Vue.js

\n

Example

\nThis example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/vue)\n
\n\n\n

MyComponent.vue

\n\n
<template>\n  <ul v-if="!!eventData$">\n    <li><b>someValue: </b> {{eventData$.someValue}}</li>\n    <li><b>anotherValue: </b> {{eventData$.anotherValue}}</li>\n  </ul>\n</template>\n\n<script>\nexport default {\n  name: 'MyComponent',\n  props: {\n    eventData: Object\n  },\n  subscriptions() { // provide Rx observables\n    return {\n      eventData$: this.eventData\n    }\n  }\n}\n</script>\n
\n\n\n\n

App.vue

\n\n
<template>\n  <div id="app">\n    <button v-on:click="createTrx">Create a Transaction</button>\n    <MyComponent v-bind:event-data="myEventObservable$" v-if="!!myEventObservable$" />\n  </div>\n</template>\n\n<script>\nimport MyComponent from './components/MyComponent.vue';\nimport Subspace from "@embarklabs/subspace";\n\nexport default {\n  name: 'app',\n  data: function(){\n    return {\n      myEventObservable$: null,\n      MyContractInstance: null\n    };\n  },\n  created: async function(){\n    this.MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n    const subspace = new Subspace("wss://localhost:8545"); // Use a valid provider (geth, parity, infura...)\n    await subspace.init();\n\n    this.myEventObservable$ = subspace.trackEvent(this.MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });\n  }, \n  methods: {\n    createTrx: function(){\n      this.MyContractInstance.methods\n        .myFunction()\n        .send({ from: web3.eth.defaultAccount });\n    }\n  },\n  components: {\n    MyComponent\n  }\n}\n</script>\n
\n\n\n\n

Further read

\n"}],"Post":[{"title":"Hello World","_content":"Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues).\n\n## Quick Start\n\n### Create a new post\n\n``` bash\n$ hexo new \"My New Post\"\n```\n\nMore info: [Writing](https://hexo.io/docs/writing.html)\n\n### Run server\n\n``` bash\n$ hexo server\n```\n\nMore info: [Server](https://hexo.io/docs/server.html)\n\n### Generate static files\n\n``` bash\n$ hexo generate\n```\n\nMore info: [Generating](https://hexo.io/docs/generating.html)\n\n### Deploy to remote sites\n\n``` bash\n$ hexo deploy\n```\n\nMore info: [Deployment](https://hexo.io/docs/one-command-deployment.html)\n","source":"_posts/hello-world.md","raw":"---\ntitle: Hello World\n---\nWelcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues).\n\n## Quick Start\n\n### Create a new post\n\n``` bash\n$ hexo new \"My New Post\"\n```\n\nMore info: [Writing](https://hexo.io/docs/writing.html)\n\n### Run server\n\n``` bash\n$ hexo server\n```\n\nMore info: [Server](https://hexo.io/docs/server.html)\n\n### Generate static files\n\n``` bash\n$ hexo generate\n```\n\nMore info: [Generating](https://hexo.io/docs/generating.html)\n\n### Deploy to remote sites\n\n``` bash\n$ hexo deploy\n```\n\nMore info: [Deployment](https://hexo.io/docs/one-command-deployment.html)\n","slug":"hello-world","published":1,"date":"2020-03-19T18:28:50.730Z","updated":"2020-03-19T18:28:50.730Z","comments":1,"layout":"post","photos":[],"link":"","_id":"ck7z3ielc00008pbn2mijc29u","content":"

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

\n

Quick Start

Create a new post

\n\n
$ hexo new "My New Post"\n
\n\n\n\n

More info: Writing

\n

Run server

\n\n
$ hexo server\n
\n\n\n\n

More info: Server

\n

Generate static files

\n\n
$ hexo generate\n
\n\n\n\n

More info: Generating

\n

Deploy to remote sites

\n\n
$ hexo deploy\n
\n\n\n\n

More info: Deployment

\n","site":{"data":{}},"excerpt":"","more":"

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

\n

Quick Start

Create a new post

\n\n
$ hexo new "My New Post"\n
\n\n\n\n

More info: Writing

\n

Run server

\n\n
$ hexo server\n
\n\n\n\n

More info: Server

\n

Generate static files

\n\n
$ hexo generate\n
\n\n\n\n

More info: Generating

\n

Deploy to remote sites

\n\n
$ hexo deploy\n
\n\n\n\n

More info: Deployment

\n"}],"PostAsset":[],"PostCategory":[],"PostTag":[],"Tag":[]}} \ No newline at end of file +{"meta":{"version":1,"warehouse":"3.0.2"},"models":{"Asset":[{"_id":"source/packages/docs/CNAME","path":"CNAME","modified":0,"renderable":0},{"_id":"source/packages/docs/d1.png","path":"d1.png","modified":0,"renderable":0},{"_id":"source/packages/docs/d2.png","path":"d2.png","modified":0,"renderable":0},{"_id":"source/packages/docs/d4.png","path":"d4.png","modified":0,"renderable":0},{"_id":"source/packages/docs/d3.png","path":"d3.png","modified":0,"renderable":0},{"_id":"themes/subspace/source/css/application.scss","path":"css/application.scss","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/accounting-calculator.svg","path":"icons/accounting-calculator.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/book-address.svg","path":"icons/book-address.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/contactless-payment.svg","path":"icons/contactless-payment.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/close.svg","path":"icons/close.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/cloud-lock.svg","path":"icons/cloud-lock.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-give.svg","path":"icons/crypto-currency-bitcoin-give.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-lock.svg","path":"icons/crypto-currency-bitcoin-lock.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/facebook.svg","path":"icons/facebook.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/gauge-dashboard-1-alternate.svg","path":"icons/gauge-dashboard-1-alternate.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/credit-card-1.svg","path":"icons/credit-card-1.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/gesture-tap-2.svg","path":"icons/gesture-tap-2.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/navigation-menu.svg","path":"icons/navigation-menu.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/half-circles.svg","path":"icons/half-circles.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/twitter.svg","path":"icons/twitter.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/icons/github.svg","path":"icons/github.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/embark-logo.svg","path":"images/embark-logo.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/favicon.png","path":"images/favicon.png","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/circles.png","path":"images/circles.png","modified":0,"renderable":1},{"_id":"themes/subspace/source/images/logo.svg","path":"images/logo.svg","modified":0,"renderable":1},{"_id":"themes/subspace/source/javascripts/scripts.js","path":"javascripts/scripts.js","modified":0,"renderable":1},{"_id":"themes/subspace/source/fonts/LICENSE.txt","path":"fonts/LICENSE.txt","modified":0,"renderable":1},{"_id":"themes/subspace/source/javascripts/jquery.js","path":"javascripts/jquery.js","modified":0,"renderable":1},{"_id":"themes/subspace/source/css/utilities/text-color.scss","path":"css/utilities/text-color.scss","modified":0,"renderable":1},{"_id":"themes/subspace/source/css/utilities/text-size.scss","path":"css/utilities/text-size.scss","modified":0,"renderable":1},{"_id":"themes/subspace/source/fonts/Roboto-Regular.ttf","path":"fonts/Roboto-Regular.ttf","modified":0,"renderable":1},{"_id":"themes/subspace/source/fonts/Roboto-Bold.ttf","path":"fonts/Roboto-Bold.ttf","modified":0,"renderable":1}],"Cache":[{"_id":"source/packages/docs/integrations.md","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642530738},{"_id":"source/packages/docs/CNAME","hash":"545c29d0214716b4d25f490ba92f7fc192267fa9","modified":1584642530729},{"_id":"source/packages/docs/api.md","hash":"ffde01913e2d96ec29385876a11263bc11fabceb","modified":1584723815864},{"_id":"source/packages/docs/apollo-client.md","hash":"cc160f89cce8517911336cee5b25cdf65917deff","modified":1584724636348},{"_id":"source/packages/docs/getting-started.md","hash":"1042b4f008235f64d7ea68bb2c2bda1ead199e55","modified":1584725507304},{"_id":"source/packages/docs/how-it-works.md","hash":"d63d4586abfc27e244c79fadc6bd511177000f93","modified":1584642530738},{"_id":"source/packages/docs/react.md","hash":"9535a6f86f81f41f7fc15abda4fa0b643445ca01","modified":1584724578524},{"_id":"source/packages/docs/index.md","hash":"c7f9f58861a13ea8feab62f9b1bdd77dbda50332","modified":1584642530738},{"_id":"source/packages/docs/reactive-graphql.md","hash":"94b59d798d01c251bdb6a6f68d7ea3488fedb100","modified":1584724721872},{"_id":"source/packages/docs/integrations-overview.md","hash":"27810364f74ec73eb6dad0c8de9d72d9b8b51819","modified":1584642530738},{"_id":"source/packages/docs/redux.md","hash":"a1e05949d04ccb860ecdf1dbbc0c0910eb08dc3a","modified":1584725185944},{"_id":"source/packages/docs/redux-observable.md","hash":"704cffb8c78cdd277e113bc36341b7ea3dc39e76","modified":1584725239448},{"_id":"source/packages/docs/tutorial.md","hash":"baadad45a3c4192b5b32636c0552e32f00e75076","modified":1584642530739},{"_id":"source/packages/docs/readme.md","hash":"87edb67efc2d3ff34adb4cdaf253af19602ad901","modified":1584642530739},{"_id":"source/packages/docs/vue.md","hash":"eae7d13431ff55dcb68392cf78abef0cdb7b4e4e","modified":1584724932780},{"_id":"source/packages/docs/d1.png","hash":"615cbb4801559261ddeaedcda06679dd13ff8f26","modified":1584642530731},{"_id":"themes/subspace/languages/en.yml","hash":"52b19a8059904b1c4d7024cb5f2e7a8071b0ab57","modified":1584642530754},{"_id":"themes/subspace/languages/.DS_Store","hash":"d76a2d7ac0d577c6351a42a52cde25f60bbe2e26","modified":1584642530754},{"_id":"themes/subspace/layout/about-us.ejs","hash":"906fffa56cbe7211846775e0b4844db1825230a7","modified":1584642530754},{"_id":"themes/subspace/layout/layout.ejs","hash":"38e9ef77f035f17fb6c4a46d3f2204d2c5f51459","modified":1584642530755},{"_id":"themes/subspace/layout/index.ejs","hash":"b104f0b2eaae87f8c90a6cdafc18e2f5c699d02a","modified":1584642530755},{"_id":"themes/subspace/layout/page.ejs","hash":"e006206018c66a2c2937215010c9c3cd705f05ad","modified":1584642530755},{"_id":"themes/subspace/layout/404.ejs","hash":"52679437dd54e18877ce4d3d6d9989b3515ff6bf","modified":1584642530754},{"_id":"source/packages/docs/d2.png","hash":"87c8eaa980edbe019c706ab8463148227bd25192","modified":1584642530733},{"_id":"source/packages/docs/d4.png","hash":"5cc6b8b2d141e41719bf9ace46d2be80d8236a69","modified":1584642530737},{"_id":"source/packages/docs/d3.png","hash":"ca19a6ae5bf461a92af770d0ed7e82170c27da4a","modified":1584642530735},{"_id":"themes/subspace/layout/partial/head.ejs","hash":"7b788f51a2f5cc3891dd2bc9db8590580a6c47da","modified":1584642530755},{"_id":"themes/subspace/source/css/application.scss","hash":"424452ff93d472ea4097d60437a5c2fb8be74e49","modified":1584642530756},{"_id":"themes/subspace/layout/partial/header.ejs","hash":"a6cbefc575f7d67895463ffce2813eee00cdc1d0","modified":1584642530756},{"_id":"themes/subspace/source/css/.DS_Store","hash":"6d11537ea7ac951519f8387948002c67d58ac9ef","modified":1584642530756},{"_id":"themes/subspace/layout/partial/footer.ejs","hash":"15e41147f066c4ae9fed03f0f10f7b821a3c54e7","modified":1584726309720},{"_id":"themes/subspace/layout/partial/mailpopup.ejs","hash":"edb6ea1449c8f419c1f6cd3fa0f3f6bac709675d","modified":1584642530756},{"_id":"themes/subspace/layout/partial/header-short.ejs","hash":"fcf71590daa7f07a0d898a9cd432faebb7b06ea9","modified":1584642530755},{"_id":"themes/subspace/source/icons/accounting-calculator.svg","hash":"7891b12b3fd13594b3ae17c10b3523208265be33","modified":1584642530762},{"_id":"themes/subspace/source/icons/book-address.svg","hash":"e2635b49f36833ec0f3373d53e3c5819a3446c24","modified":1584642530762},{"_id":"themes/subspace/source/icons/contactless-payment.svg","hash":"6674a6a6c06539d7be7bcb2459448d4895541051","modified":1584642530763},{"_id":"themes/subspace/source/icons/close.svg","hash":"07c332a892c2b2a107bf53a055425064006b7161","modified":1584642530763},{"_id":"themes/subspace/source/icons/cloud-lock.svg","hash":"b76429f6da1aaa8a1f1d1e72ae7167899976e7aa","modified":1584642530763},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-give.svg","hash":"a07cb23aa2c7b81167289cfee51450e110dd46d2","modified":1584642530763},{"_id":"themes/subspace/source/icons/crypto-currency-bitcoin-lock.svg","hash":"27219b9e068b7dc5323217e3f49bad16f6555470","modified":1584642530763},{"_id":"themes/subspace/source/icons/facebook.svg","hash":"0cf65e7228226ff7aa72c74d35368db7599c884b","modified":1584642530763},{"_id":"themes/subspace/source/icons/gauge-dashboard-1-alternate.svg","hash":"4ab202003ecb28775848f4b6fa61a45b4cdc8a7c","modified":1584642530763},{"_id":"themes/subspace/source/icons/credit-card-1.svg","hash":"2c6082035b515eff854f84905cca61a53275aa8e","modified":1584642530763},{"_id":"themes/subspace/source/icons/gesture-tap-2.svg","hash":"8e9a60be2d1080c184f8863d8059472ae1051432","modified":1584642530763},{"_id":"themes/subspace/source/icons/navigation-menu.svg","hash":"d6b4d9e2da8849ac362bcb8d634725b921ebf46c","modified":1584642530764},{"_id":"themes/subspace/source/icons/half-circles.svg","hash":"0be6efb2cd315348a5f2f1404da205d11d5e78c3","modified":1584642530764},{"_id":"themes/subspace/source/icons/twitter.svg","hash":"dab32630d9eb04c293f9c4775271953d57eb8642","modified":1584642530764},{"_id":"themes/subspace/source/images/.DS_Store","hash":"df2fbeb1400acda0909a32c1cf6bf492f1121e07","modified":1584642530764},{"_id":"themes/subspace/source/icons/github.svg","hash":"4ad3447484a193da8e10d9705ebb598de10873e6","modified":1584642530764},{"_id":"themes/subspace/source/images/embark-logo.svg","hash":"682af62e01cd85c11235bd2258b8f87ee9b44afb","modified":1584642530765},{"_id":"themes/subspace/source/images/favicon.png","hash":"7f0c4305cd9711e9dd20ac94a5559f4d67a9fe9b","modified":1584642530765},{"_id":"themes/subspace/source/images/circles.png","hash":"ca3ed456a67c9c329e638990b9a8805a2f33c68c","modified":1584642530764},{"_id":"themes/subspace/source/images/logo.svg","hash":"e7d3c651b56c2bb890b567a67dd860fc96ad6579","modified":1584642530765},{"_id":"themes/subspace/source/javascripts/scripts.js","hash":"1f0ee8c12b179a9607cb1848710254652a7332b2","modified":1584642530766},{"_id":"themes/subspace/source/css/components/_footer.scss","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642530756},{"_id":"themes/subspace/source/fonts/LICENSE.txt","hash":"47b573e3824cd5e02a1a3ae99e2735b49e0256e4","modified":1584642530761},{"_id":"themes/subspace/source/javascripts/jquery.js","hash":"9592732de681f4365e9b7016dc5cf76e2a55ee9b","modified":1584642530765},{"_id":"themes/subspace/source/css/components/_accentbox.scss","hash":"d29f556f2e24edec1332ccc00e86426015de422a","modified":1584642530756},{"_id":"themes/subspace/source/css/components/_button.scss","hash":"0888de9a954f5bfb3b84bbfdeed13372d250f69d","modified":1584642530756},{"_id":"themes/subspace/source/css/components/_ghostbox.scss","hash":"1105139aba422228bc5a64863d28d8405d700d15","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_header.scss","hash":"e83d6db7e7c928f4d7d5fd2d57643fe1a551cffc","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_icons.scss","hash":"cb036eb40ed0c2525ca1918e59d73d6a592272ba","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_logo.scss","hash":"c3734c435890094b95a9f340337dbfc682bc1e1a","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_notification.scss","hash":"87e1aae9e3097c59833d34e72f7ae8414f667cdb","modified":1584724117876},{"_id":"themes/subspace/source/css/components/_prism-highlighting.scss","hash":"f8471f2667d53a43cb3b6003d7ecafc811283c24","modified":1584642530757},{"_id":"themes/subspace/source/css/components/_spotlightbox.scss","hash":"2a38ea8c753890d1683b435e33e8377fb17671dc","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_teaser.scss","hash":"c653e382a5a7074f5f86b89c6640a56e083b8471","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_user.scss","hash":"b3663cc7b8c0afdf5f8a69031da7ac3365e844a9","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_whisperbox.scss","hash":"3852852e8644c71b6604915342a10abbfd681d4b","modified":1584642530758},{"_id":"themes/subspace/source/css/objects/_actionbar.scss","hash":"195c09931d611dbfcaf9822413504ebb0e77076b","modified":1584642530758},{"_id":"themes/subspace/source/css/components/_popup.scss","hash":"ccacb82e0b24378a96841d7a480e6530630d882d","modified":1584642530757},{"_id":"themes/subspace/source/css/objects/_content.scss","hash":"4ef659a6c260c847813fabb8718f990c5c126792","modified":1584642530758},{"_id":"themes/subspace/source/css/objects/_distance.scss","hash":"7ad96acdb01f35bbd8941d61f59b055568c6e545","modified":1584642530758},{"_id":"themes/subspace/source/css/objects/_heading.scss","hash":"6569220491e75b751070f2b589fea348745e27d1","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_list.scss","hash":"ed672664d7e4a2f041ce3e3dcc6b3c9f3ebbfa7e","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_media.scss","hash":"be25ab7a3c1e3bccfaaa5fdbeeccf9308694921d","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_navigation.scss","hash":"64e3b33422ccccf702e630125a9b3ca52999c2d6","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_grid.scss","hash":"4dc75ce1b1d58e4ca6624db8115ffd196c996733","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/_side-navigation.scss","hash":"231d32b8a6137f3bd4d4ac2aa24476620f558f61","modified":1584642530759},{"_id":"themes/subspace/source/css/settings/_config.scss","hash":"a27b23a9d0e1a77c4361c4cb1f7ad0468906bbb3","modified":1584642530759},{"_id":"themes/subspace/source/css/settings/_preset.scss","hash":"36ed217633bf1a18f5221299e0f60277271eecb4","modified":1584642530759},{"_id":"themes/subspace/source/css/objects/.DS_Store","hash":"5fcb0ec5a267305e0c44b7fa11ae2793b4f428c6","modified":1584642530758},{"_id":"themes/subspace/source/css/settings/_typography.scss","hash":"6cd55798081c53c48e7ad0324a0799b53fc5ff17","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_column.scss","hash":"9e79a4e3b4ab33091af14704d35ca2ab4263b741","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-brand-color.scss","hash":"5e773a10bb143a2b423287b7faff79ac5ce3fcac","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-color.scss","hash":"c7b667b92df7fa246be2f32f395ebbde23ea0355","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-font.scss","hash":"b2895a7ef8c26ba6b34c34f1f2fb2ea5449f89cd","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-index.scss","hash":"72281c30f7e3db2060898d3c9b250bc6c8829216","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-layout-color.scss","hash":"8e57145b98219bc874041197bde973193e2ff7a8","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-notification-color.scss","hash":"761e671fe7cbd70c190254818c8e55e6d3d7ee90","modified":1584642530760},{"_id":"themes/subspace/source/css/tools/_get-semantic-color.scss","hash":"316f7baaa9aeac4f891901882479b37230b5c591","modified":1584642530761},{"_id":"themes/subspace/source/css/tools/_get-spacing.scss","hash":"fc5b46752f7e37da64ddad94392450d7d4f40a87","modified":1584642530761},{"_id":"themes/subspace/source/css/tools/_list-reset.scss","hash":"ed3aa5ee39890dd0454c695e1bf0a45f751c5b04","modified":1584642530761},{"_id":"themes/subspace/source/css/tools/_respond.scss","hash":"ba73d16c16235365bea5da78df0672d990ba4579","modified":1584642530761},{"_id":"themes/subspace/source/css/utilities/text-color.scss","hash":"414a963b70ee7a6250a247bdbd03f2e67e5bbdcd","modified":1584642530761},{"_id":"themes/subspace/source/css/utilities/text-size.scss","hash":"93494af1f3f44293fc9357bd726eadedf76d9516","modified":1584642530761},{"_id":"themes/subspace/source/fonts/Roboto-Regular.ttf","hash":"dd1b1db13ff1f72138c134c62f38fef83749f36a","modified":1584642530762},{"_id":"themes/subspace/source/fonts/Roboto-Bold.ttf","hash":"0ce37ced9c5fcac9bdc452a432c1258870ba4677","modified":1584642530762},{"_id":"public/integrations.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/api.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/apollo-client.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/getting-started.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/how-it-works.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/reactive-graphql.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/react.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/integrations-overview.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/redux.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/tutorial.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/redux-observable.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/readme.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/vue.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/integrations.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/api.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/apollo-client.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/getting-started.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/how-it-works.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/index.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/reactive-graphql.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/react.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/integrations-overview.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/redux.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/redux-observable.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/tutorial.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/readme.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/de/vue.html","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1584642922115},{"_id":"public/index.html","hash":"f78940c9cc6789a8ebe9e87f038b29570a7551ee","modified":1584642922115},{"_id":"public/CNAME","hash":"545c29d0214716b4d25f490ba92f7fc192267fa9","modified":1584642922115},{"_id":"public/icons/accounting-calculator.svg","hash":"7891b12b3fd13594b3ae17c10b3523208265be33","modified":1584642922115},{"_id":"public/icons/book-address.svg","hash":"e2635b49f36833ec0f3373d53e3c5819a3446c24","modified":1584642922115},{"_id":"public/icons/contactless-payment.svg","hash":"6674a6a6c06539d7be7bcb2459448d4895541051","modified":1584642922115},{"_id":"public/icons/close.svg","hash":"07c332a892c2b2a107bf53a055425064006b7161","modified":1584642922115},{"_id":"public/icons/cloud-lock.svg","hash":"b76429f6da1aaa8a1f1d1e72ae7167899976e7aa","modified":1584642922115},{"_id":"public/icons/crypto-currency-bitcoin-give.svg","hash":"a07cb23aa2c7b81167289cfee51450e110dd46d2","modified":1584642922115},{"_id":"public/icons/crypto-currency-bitcoin-lock.svg","hash":"27219b9e068b7dc5323217e3f49bad16f6555470","modified":1584642922115},{"_id":"public/icons/facebook.svg","hash":"0cf65e7228226ff7aa72c74d35368db7599c884b","modified":1584642922115},{"_id":"public/icons/gesture-tap-2.svg","hash":"8e9a60be2d1080c184f8863d8059472ae1051432","modified":1584642922115},{"_id":"public/icons/gauge-dashboard-1-alternate.svg","hash":"4ab202003ecb28775848f4b6fa61a45b4cdc8a7c","modified":1584642922115},{"_id":"public/icons/credit-card-1.svg","hash":"2c6082035b515eff854f84905cca61a53275aa8e","modified":1584642922115},{"_id":"public/icons/navigation-menu.svg","hash":"d6b4d9e2da8849ac362bcb8d634725b921ebf46c","modified":1584642922115},{"_id":"public/icons/half-circles.svg","hash":"0be6efb2cd315348a5f2f1404da205d11d5e78c3","modified":1584642922115},{"_id":"public/icons/twitter.svg","hash":"dab32630d9eb04c293f9c4775271953d57eb8642","modified":1584642922115},{"_id":"public/icons/github.svg","hash":"4ad3447484a193da8e10d9705ebb598de10873e6","modified":1584642922115},{"_id":"public/images/embark-logo.svg","hash":"682af62e01cd85c11235bd2258b8f87ee9b44afb","modified":1584642922115},{"_id":"public/images/favicon.png","hash":"7f0c4305cd9711e9dd20ac94a5559f4d67a9fe9b","modified":1584642922115},{"_id":"public/images/logo.svg","hash":"e7d3c651b56c2bb890b567a67dd860fc96ad6579","modified":1584642922115},{"_id":"public/images/circles.png","hash":"ca3ed456a67c9c329e638990b9a8805a2f33c68c","modified":1584642922115},{"_id":"public/fonts/LICENSE.txt","hash":"47b573e3824cd5e02a1a3ae99e2735b49e0256e4","modified":1584642922115},{"_id":"public/javascripts/scripts.js","hash":"1f0ee8c12b179a9607cb1848710254652a7332b2","modified":1584642922115},{"_id":"public/css/utilities/text-size.css","hash":"6340d74612d186555e471c57175a5f0a3f661cdc","modified":1584642922115},{"_id":"public/css/utilities/text-color.css","hash":"3d763e25e9078d5375b4fd0d9b100aa1b8a91d93","modified":1584642922115},{"_id":"public/javascripts/jquery.js","hash":"9592732de681f4365e9b7016dc5cf76e2a55ee9b","modified":1584642922115},{"_id":"public/css/application.css","hash":"e7e477ef203d3d902df2518d63ef12731d0a50f8","modified":1584642922115},{"_id":"public/d1.png","hash":"615cbb4801559261ddeaedcda06679dd13ff8f26","modified":1584642922115},{"_id":"public/fonts/Roboto-Bold.ttf","hash":"0ce37ced9c5fcac9bdc452a432c1258870ba4677","modified":1584642922115},{"_id":"public/d4.png","hash":"5cc6b8b2d141e41719bf9ace46d2be80d8236a69","modified":1584642922115},{"_id":"public/d3.png","hash":"ca19a6ae5bf461a92af770d0ed7e82170c27da4a","modified":1584642922115},{"_id":"public/fonts/Roboto-Regular.ttf","hash":"dd1b1db13ff1f72138c134c62f38fef83749f36a","modified":1584642922115},{"_id":"public/d2.png","hash":"87c8eaa980edbe019c706ab8463148227bd25192","modified":1584642922115},{"_id":"source/packages/docs/_data/sidebar.yml","hash":"09bc83728b4dc7a9db44fdfce15769972c1eec3a","modified":1584642530730},{"_id":"source/packages/docs/_posts/hello-world.md","hash":"7d98d6592de80fdcd2949bd7401cec12afd98cdf","modified":1584642530730},{"_id":"source/packages/docs/.DS_Store","hash":"078fc163bb0c365b31f211f49a5e78e2703b3f12","modified":1584643079469},{"_id":"themes/subspace/layout/partial/analytics.ejs","hash":"bf68e467c9adc5e07591ddf1e74da824750948f2","modified":1584726372396}],"Category":[],"Data":[{"_id":"sidebar","data":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}],"Page":[{"_content":"","source":"integrations.md","raw":"","date":"2020-03-19T18:30:37.782Z","updated":"2020-03-19T18:28:50.738Z","path":"integrations.html","title":"","comments":1,"layout":"page","_id":"ck7z3hcks00005cbn2gap6jkg","content":"","site":{"data":{}},"excerpt":"","more":""},{"_content":"# API\n\n## General\n\n### `new Subspace(web3 [, options])`\nConstructor. \n\n**Parameters**\n1. `web3` - `Object`: a `web3.js` object.\n2. `options` - `Object` (optional): Options used to initialize Subspace\n\t- `dbFilename` - `String` (optional): Name of the database where the information will be stored (default `'subspace.db'`)\n - `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).\n - `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),\n - `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)\n\n\n### `init()`\nInitializes **Subspace**\n\n**Returns**\n`Promise` that once it's resolved, will mean that **Subspace** is available to use\n\n### `close()`\nDispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution.\n\n### `contract(instance|{abi,address})`\nAdds a `track` method to the web3 contract objects. You can obtain this functionality by passing a `web3.eth.Contract` instance, or the `abi` and `address` of your contract\n\n**Returns**\n`web3.eth.Contract` object enhanced with `.track()` functions for methods and events.\n\n## Contract methods\n\n### `myContract.events.MyEvent.track([options])`\nTrack a contract event.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n\n### `myContract.methods.myMethod([param1[, ...]]).track([callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n\n### `myContract.trackBalance(address [, tokenAddress])`\nTrack a contract's balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n\n## Blocks, gas price and block time\n\n### `trackBlock()`\nReceive the block information for any new block. It's the reactive equivalent to `web3.eth.getBlock(\"latest\")`.\n\n**Returns**\n`RxJS Observable` which will stream a block object for the latest block received\n\n### `trackBlockNumber()`\nReturns the latest block number. It's the reactive equivalent to `web3.eth.getBlockNumber`.\n\n**Returns**\n`RxJS Observable` with the latest block number\n\n### `trackGasPrice()`\nReturns the current gas price oracle. It's the reactive equivalent to `web3.eth.getGasPrice`.\n\n**Returns**\n`RxJS Observable` with the average gas price in wei.\n\n### `trackAverageBlocktime()`\nAverage block time of the last 10 blocks.\n\n**Returns**\n`RxJS Observable` with the moving average block time of the last 10 blocks. The time is returned in milliseconds:\n\n\n## Low level API for data tracking\n\nThese are used in case you don't want to decorate your web3 contract objects, or if you want to track the balance for an specific address.\n\n### `trackEvent(contractObject, eventName [, options])`\nTrack a contract event.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `eventName` - `String`: The name of the event to subscribe.\n3. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n### `trackProperty(contractObject, functionName [, functionArgs] [, callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `functionName` - `String`: Name of the function or variable whose values will be tracked.\n3. `functionArgs` - `Array` (optional): Array of arguments that the tracked function receives\n4. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n### `trackBalance(address [, tokenAddress])`\nTrack balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n### `trackLogs(options [, abi])`\nTracks incoming logs, filtered by the given options.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of logs\n - `address` - `String|Array` (optional): An address or a list of addresses to only get logs from particular account(s).\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `topics` - `Array` (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, '0x00...']. You can also pass another array for each topic with options for that topic e.g. [null, ['option1', 'option2']].\n2. `abi` - `Array` (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.\n\n**Returns**\n`RxJS Observable` which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.","source":"api.md","raw":"# API\n\n## General\n\n### `new Subspace(web3 [, options])`\nConstructor. \n\n**Parameters**\n1. `web3` - `Object`: a `web3.js` object.\n2. `options` - `Object` (optional): Options used to initialize Subspace\n\t- `dbFilename` - `String` (optional): Name of the database where the information will be stored (default `'subspace.db'`)\n - `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).\n - `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),\n - `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)\n\n\n### `init()`\nInitializes **Subspace**\n\n**Returns**\n`Promise` that once it's resolved, will mean that **Subspace** is available to use\n\n### `close()`\nDispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution.\n\n### `contract(instance|{abi,address})`\nAdds a `track` method to the web3 contract objects. You can obtain this functionality by passing a `web3.eth.Contract` instance, or the `abi` and `address` of your contract\n\n**Returns**\n`web3.eth.Contract` object enhanced with `.track()` functions for methods and events.\n\n## Contract methods\n\n### `myContract.events.MyEvent.track([options])`\nTrack a contract event.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n\n### `myContract.methods.myMethod([param1[, ...]]).track([callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n\n### `myContract.trackBalance(address [, tokenAddress])`\nTrack a contract's balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n\n## Blocks, gas price and block time\n\n### `trackBlock()`\nReceive the block information for any new block. It's the reactive equivalent to `web3.eth.getBlock(\"latest\")`.\n\n**Returns**\n`RxJS Observable` which will stream a block object for the latest block received\n\n### `trackBlockNumber()`\nReturns the latest block number. It's the reactive equivalent to `web3.eth.getBlockNumber`.\n\n**Returns**\n`RxJS Observable` with the latest block number\n\n### `trackGasPrice()`\nReturns the current gas price oracle. It's the reactive equivalent to `web3.eth.getGasPrice`.\n\n**Returns**\n`RxJS Observable` with the average gas price in wei.\n\n### `trackAverageBlocktime()`\nAverage block time of the last 10 blocks.\n\n**Returns**\n`RxJS Observable` with the moving average block time of the last 10 blocks. The time is returned in milliseconds:\n\n\n## Low level API for data tracking\n\nThese are used in case you don't want to decorate your web3 contract objects, or if you want to track the balance for an specific address.\n\n### `trackEvent(contractObject, eventName [, options])`\nTrack a contract event.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `eventName` - `String`: The name of the event to subscribe.\n3. `options` - `Object` (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters\n - `filter` - `Object` (optional): Lets you filter events by indexed parameters, e.g. `{filter: {myNumber: [12,13]}}` means all events where `\"myNumber\"` is `12` or `13`.\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `toBlock` - `Number` (optional): The block number to get events up to (Defaults to `\"latest\"`)\n - `topics` - `Array` (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (`topic[0]`) will not be set automatically.\n\n**Returns**\n`RxJS Observable` which will stream the event `returnValues`.\n\n### `trackProperty(contractObject, functionName [, functionArgs] [, callOptions])`\nTrack a constant function / contract state variable on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `contractObject` - `web3.eth.Contract`: An already initialized contract object pointing to an address and containing a valid ABI.\n2. `functionName` - `String`: Name of the function or variable whose values will be tracked.\n3. `functionArgs` - `Array` (optional): Array of arguments that the tracked function receives\n4. `callOptions` - `Object` (optional): The options used for calling.\n - `from` - `String` (optional): The address the call “transaction” should be made from.\n - `gasPrice` - `String` (optional): The gas price in wei to use for this call “transaction”.\n - `gas` - `Number` (optional): The maximum gas provided for this call “transaction” (gas limit).\n\n**Returns**\n`RxJS Observable` which will stream the function / variable values. Data type will depend on the contract function invoked. \n\n### `trackBalance(address [, tokenAddress])`\nTrack balance changes for an address on each block mined, or depending on the `callInterval` option used during **Subspace** initialization.\n\n**Parameters**\n1. `address` - `String`: The address to get the balance of.\n2. `tokenAddress` - `String` (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.\n\n**Returns**\n`RxJS Observable` which will stream a string containing the address balance.\n\n### `trackLogs(options [, abi])`\nTracks incoming logs, filtered by the given options.\n\n**Parameters**\n1. `options` - `Object` (optional): web3 filter options object to limit the number of logs\n - `address` - `String|Array` (optional): An address or a list of addresses to only get logs from particular account(s).\n - `fromBlock` - `Number` (optional): The block number from which to get events on.\n - `topics` - `Array` (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, '0x00...']. You can also pass another array for each topic with options for that topic e.g. [null, ['option1', 'option2']].\n2. `abi` - `Array` (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.\n\n**Returns**\n`RxJS Observable` which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.","date":"2020-03-20T17:03:35.864Z","updated":"2020-03-20T17:03:35.864Z","path":"api.html","_id":"ck7z3hckv00015cbn10hj90nw","title":"","comments":1,"layout":"page","content":"

API

General

new Subspace(web3 [, options])

Constructor.

\n

Parameters

\n
    \n
  1. web3 - Object: a web3.js object.
  2. \n
  3. options - Object (optional): Options used to initialize Subspace
      \n
    • dbFilename - String (optional): Name of the database where the information will be stored (default 'subspace.db')
    • \n
    • 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).
    • \n
    • 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),
    • \n
    • 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)
    • \n
    \n
  4. \n
\n

init()

Initializes Subspace

\n

Returns
Promise that once it’s resolved, will mean that Subspace is available to use

\n

close()

Dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution.

\n

contract(instance|{abi,address})

Adds a track method to the web3 contract objects. You can obtain this functionality by passing a web3.eth.Contract instance, or the abi and address of your contract

\n

Returns
web3.eth.Contract object enhanced with .track() functions for methods and events.

\n

Contract methods

myContract.events.MyEvent.track([options])

Track a contract event.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

myContract.methods.myMethod([param1[, ...]]).track([callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

myContract.trackBalance(address [, tokenAddress])

Track a contract’s balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

Blocks, gas price and block time

trackBlock()

Receive the block information for any new block. It’s the reactive equivalent to web3.eth.getBlock("latest").

\n

Returns
RxJS Observable which will stream a block object for the latest block received

\n

trackBlockNumber()

Returns the latest block number. It’s the reactive equivalent to web3.eth.getBlockNumber.

\n

Returns
RxJS Observable with the latest block number

\n

trackGasPrice()

Returns the current gas price oracle. It’s the reactive equivalent to web3.eth.getGasPrice.

\n

Returns
RxJS Observable with the average gas price in wei.

\n

trackAverageBlocktime()

Average block time of the last 10 blocks.

\n

Returns
RxJS Observable with the moving average block time of the last 10 blocks. The time is returned in milliseconds:

\n

Low level API for data tracking

These are used in case you don’t want to decorate your web3 contract objects, or if you want to track the balance for an specific address.

\n

trackEvent(contractObject, eventName [, options])

Track a contract event.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. eventName - String: The name of the event to subscribe.
  4. \n
  5. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  6. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

trackProperty(contractObject, functionName [, functionArgs] [, callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. functionName - String: Name of the function or variable whose values will be tracked.
  4. \n
  5. functionArgs - Array (optional): Array of arguments that the tracked function receives
  6. \n
  7. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  8. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

trackBalance(address [, tokenAddress])

Track balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

trackLogs(options [, abi])

Tracks incoming logs, filtered by the given options.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of logs
      \n
    • address - String|Array (optional): An address or a list of addresses to only get logs from particular account(s).
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • topics - Array (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, ‘0x00…’]. You can also pass another array for each topic with options for that topic e.g. [null, [‘option1’, ‘option2’]].
    • \n
    \n
  2. \n
  3. abi - Array (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.
  4. \n
\n

Returns
RxJS Observable which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.

\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

API

General

new Subspace(web3 [, options])

Constructor.

\n

Parameters

\n
    \n
  1. web3 - Object: a web3.js object.
  2. \n
  3. options - Object (optional): Options used to initialize Subspace
      \n
    • dbFilename - String (optional): Name of the database where the information will be stored (default 'subspace.db')
    • \n
    • 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).
    • \n
    • 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),
    • \n
    • 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)
    • \n
    \n
  4. \n
\n

init()

Initializes Subspace

\n

Returns
Promise that once it’s resolved, will mean that Subspace is available to use

\n

close()

Dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution.

\n

contract(instance|{abi,address})

Adds a track method to the web3 contract objects. You can obtain this functionality by passing a web3.eth.Contract instance, or the abi and address of your contract

\n

Returns
web3.eth.Contract object enhanced with .track() functions for methods and events.

\n

Contract methods

myContract.events.MyEvent.track([options])

Track a contract event.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

myContract.methods.myMethod([param1[, ...]]).track([callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  2. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

myContract.trackBalance(address [, tokenAddress])

Track a contract’s balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

Blocks, gas price and block time

trackBlock()

Receive the block information for any new block. It’s the reactive equivalent to web3.eth.getBlock("latest").

\n

Returns
RxJS Observable which will stream a block object for the latest block received

\n

trackBlockNumber()

Returns the latest block number. It’s the reactive equivalent to web3.eth.getBlockNumber.

\n

Returns
RxJS Observable with the latest block number

\n

trackGasPrice()

Returns the current gas price oracle. It’s the reactive equivalent to web3.eth.getGasPrice.

\n

Returns
RxJS Observable with the average gas price in wei.

\n

trackAverageBlocktime()

Average block time of the last 10 blocks.

\n

Returns
RxJS Observable with the moving average block time of the last 10 blocks. The time is returned in milliseconds:

\n

Low level API for data tracking

These are used in case you don’t want to decorate your web3 contract objects, or if you want to track the balance for an specific address.

\n

trackEvent(contractObject, eventName [, options])

Track a contract event.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. eventName - String: The name of the event to subscribe.
  4. \n
  5. options - Object (optional): web3 filter options object to limit the number of events based on a block number range, or indexed filters
      \n
    • filter - Object (optional): Lets you filter events by indexed parameters, e.g. {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13.
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • toBlock - Number (optional): The block number to get events up to (Defaults to "latest")
    • \n
    • topics - Array (optional): This allows you to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically.
    • \n
    \n
  6. \n
\n

Returns
RxJS Observable which will stream the event returnValues.

\n

trackProperty(contractObject, functionName [, functionArgs] [, callOptions])

Track a constant function / contract state variable on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. contractObject - web3.eth.Contract: An already initialized contract object pointing to an address and containing a valid ABI.
  2. \n
  3. functionName - String: Name of the function or variable whose values will be tracked.
  4. \n
  5. functionArgs - Array (optional): Array of arguments that the tracked function receives
  6. \n
  7. callOptions - Object (optional): The options used for calling.
      \n
    • from - String (optional): The address the call “transaction” should be made from.
    • \n
    • gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
    • \n
    • gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
    • \n
    \n
  8. \n
\n

Returns
RxJS Observable which will stream the function / variable values. Data type will depend on the contract function invoked.

\n

trackBalance(address [, tokenAddress])

Track balance changes for an address on each block mined, or depending on the callInterval option used during Subspace initialization.

\n

Parameters

\n
    \n
  1. address - String: The address to get the balance of.
  2. \n
  3. tokenAddress - String (optional): If you want to track the balance for an ERC20 contract, here you can specify the token address. Otherwise, Only ETH balances will be returned.
  4. \n
\n

Returns
RxJS Observable which will stream a string containing the address balance.

\n

trackLogs(options [, abi])

Tracks incoming logs, filtered by the given options.

\n

Parameters

\n
    \n
  1. options - Object (optional): web3 filter options object to limit the number of logs
      \n
    • address - String|Array (optional): An address or a list of addresses to only get logs from particular account(s).
    • \n
    • fromBlock - Number (optional): The block number from which to get events on.
    • \n
    • topics - Array (optional): An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, ‘0x00…’]. You can also pass another array for each topic with options for that topic e.g. [null, [‘option1’, ‘option2’]].
    • \n
    \n
  2. \n
  3. abi - Array (optional): Array containing the ABI for the inputs of the logs received. It will automatically decode the logs using this ABI instead of returning the hexadecimal data.
  4. \n
\n

Returns
RxJS Observable which will stream the logs. If the inputs ABI is included in the call, the logs will be automatically decoded.

\n"},{"_content":"# apollo-client\nTo use **Subspace** with `apollo-client`, a `ReactiveSchemaLink` from `apollo-link-reactive-schema` must be used with a custom schema.\n\n```js\nimport {InMemoryCache} from \"apollo-cache-inmemory\";\nimport ApolloClient from \"apollo-client\";\nimport {ReactiveSchemaLink} from \"apollo-link-reactive-schema\";\n\nconst schema = makeExecutableSchema({typeDefs, resolvers});\nconst client = new ApolloClient({\n cache: new InMemoryCache(),\n link: new ReactiveSchemaLink({schema)})\n});\n\n```\n\n### Example\n\n```js{35-45}\nimport { ApolloClient } from \"apollo-client\";\nimport { InMemoryCache } from \"apollo-cache-inmemory\";\nimport {ReactiveSchemaLink} from \"apollo-link-reactive-schema\";\nimport Subspace from \"@embarklabs/subspace\";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3);\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.Contract instance\n\nconst typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n`;\n\nconst resolvers = {\n Query: {\n myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n cache: new InMemoryCache(),\n link: new ReactiveSchemaLink({schema)})\n});\n```\n\n\n
\n

Using Apollo with Subspace

\nA practical example can also be found in examples/react-apollo.\n
","source":"apollo-client.md","raw":"# apollo-client\nTo use **Subspace** with `apollo-client`, a `ReactiveSchemaLink` from `apollo-link-reactive-schema` must be used with a custom schema.\n\n```js\nimport {InMemoryCache} from \"apollo-cache-inmemory\";\nimport ApolloClient from \"apollo-client\";\nimport {ReactiveSchemaLink} from \"apollo-link-reactive-schema\";\n\nconst schema = makeExecutableSchema({typeDefs, resolvers});\nconst client = new ApolloClient({\n cache: new InMemoryCache(),\n link: new ReactiveSchemaLink({schema)})\n});\n\n```\n\n### Example\n\n```js{35-45}\nimport { ApolloClient } from \"apollo-client\";\nimport { InMemoryCache } from \"apollo-cache-inmemory\";\nimport {ReactiveSchemaLink} from \"apollo-link-reactive-schema\";\nimport Subspace from \"@embarklabs/subspace\";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3);\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.Contract instance\n\nconst typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n`;\n\nconst resolvers = {\n Query: {\n myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n cache: new InMemoryCache(),\n link: new ReactiveSchemaLink({schema)})\n});\n```\n\n\n
\n

Using Apollo with Subspace

\nA practical example can also be found in examples/react-apollo.\n
","date":"2020-03-20T17:17:16.348Z","updated":"2020-03-20T17:17:16.348Z","path":"apollo-client.html","_id":"ck7z3hckw00025cbn4pfweo5k","title":"","comments":1,"layout":"page","content":"

apollo-client

To use Subspace with apollo-client, a ReactiveSchemaLink from apollo-link-reactive-schema must be used with a custom schema.

\n\n\n
import {InMemoryCache} from "apollo-cache-inmemory";\nimport ApolloClient from "apollo-client";\nimport {ReactiveSchemaLink} from "apollo-link-reactive-schema";\n\nconst schema = makeExecutableSchema({typeDefs, resolvers});\nconst client = new ApolloClient({\n  cache: new InMemoryCache(),\n  link: new ReactiveSchemaLink({schema)})\n});\n
\n\n\n\n

Example

\n\n
import { ApolloClient } from "apollo-client";\nimport { InMemoryCache } from "apollo-cache-inmemory";\nimport {ReactiveSchemaLink} from "apollo-link-reactive-schema";\nimport Subspace from "@embarklabs/subspace";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3);\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.Contract instance\n\nconst typeDefs = `\n  type MyEvent {\n    someValue: Int\n    anotherValue: String\n  }\n  type Query {\n    myEvents: MyEvent!\n  }\n`;\n\nconst resolvers = {\n  Query: {\n    myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n  }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n  cache: new InMemoryCache(),\n  link: new ReactiveSchemaLink({schema)})\n});\n
\n\n\n\n
\n

Using Apollo with Subspace

\nA practical example can also be found in examples/react-apollo.\n
","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

apollo-client

To use Subspace with apollo-client, a ReactiveSchemaLink from apollo-link-reactive-schema must be used with a custom schema.

\n\n\n
import {InMemoryCache} from "apollo-cache-inmemory";\nimport ApolloClient from "apollo-client";\nimport {ReactiveSchemaLink} from "apollo-link-reactive-schema";\n\nconst schema = makeExecutableSchema({typeDefs, resolvers});\nconst client = new ApolloClient({\n  cache: new InMemoryCache(),\n  link: new ReactiveSchemaLink({schema)})\n});\n
\n\n\n\n

Example

\n\n
import { ApolloClient } from "apollo-client";\nimport { InMemoryCache } from "apollo-cache-inmemory";\nimport {ReactiveSchemaLink} from "apollo-link-reactive-schema";\nimport Subspace from "@embarklabs/subspace";\n\n// ...\n\n// Initialize Subspace\nconst subspace = new Subspace(web3);\nawait subspace.init();\n\nconst MyContractInstance = ...; // TODO: obtain a web3.eth.Contract instance\n\nconst typeDefs = `\n  type MyEvent {\n    someValue: Int\n    anotherValue: String\n  }\n  type Query {\n    myEvents: MyEvent!\n  }\n`;\n\nconst resolvers = {\n  Query: {\n    myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', {filter: {}, fromBlock: 1})\n  }\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst client = new ApolloClient({\n  cache: new InMemoryCache(),\n  link: new ReactiveSchemaLink({schema)})\n});\n
\n\n\n\n
\n

Using Apollo with Subspace

\nA practical example can also be found in examples/react-apollo.\n
"},{"title":"Getting Started","_content":"# Getting Started\n\n## Installation\n**Subspace** can be used in browser, node and native script environments. To get started install the package `@embarklabs/subspace` using `npm` or `yarn` by executing this command in your project directory:\n```bash\n# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n```\n\n## Importing the library\n\n```js\n// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace'; \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n```\n\n\n## Connecting to a web3 provider\nTo interact with the EVM, **Subspace** requires a valid Web3 object, connected to a provider\n\n```js\nconst subspace = new Subspace(web3);\nawait subspace.init();\n```\n\nIn addition to the provider, `Subspace` also accepts an `options` object with settings that can change its behavior:\n- `dbFilename` - Name of the database where the information will be stored (default `'subspace.db'`)\n- `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).\n- `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),\n- `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`)\n\n\n## Enhancing your contract objects\nSubspace provides a method to enhance your web3 Contract objects: `subspace.contract(instance|{abi,address})`. Calling this method will return a new contract object decorated with a `.track()` method for your contract view functions and events.\n\n```js\nconst myRxContract = subspace.contract(myContractInstance);\n```\n\nYou can also instantiate a contract directly by passing the contract ABI and its address:\n\n```js\nconst myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n```\n\n## Reacting to data\nOnce 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.\n\n
\n

What is an Observable?

\nThe Observable type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n#### Further read\n- [RxJS Observables](https://rxjs-dev.firebaseapp.com/guide/observable)\n\n## Tracking state\nYou can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract. \n```js\nconst stateObservable$ = Contract.methods.functionName(functionArgs).track();\n```\n\n
\n

Tracking the public variables of a contract

\nState 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).\n
\n\nExample:\n\n```js\nconst productTitle$ = ProductList.methods.products(0).track().map(\"title\");\nproductTitle$.subscribe((title) => console.log(\"product title is \" + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, \"products\", [0], {from: web3.eth.defaultAccount});\n...\n```\n\nThe subscription will be triggered whenever the title changes\n\n## Tracking events\nYou can track events and react to their returned values.\n```js\nconst eventObservable$ = Contract.event.eventName.track();\n```\n\nExample:\n\n```js\nconst rating$ = Product.events.Rating.track().map(\"rating\")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log(\"rating received: \" + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, \"Rating\", {fromBlock: 0});\n...\n```\n\n**Event Sourcing**\n\nYou can easily do event sourcing with subspace.\n\nFor e.g: if you needed to get the average rating of the last 5 events:\n\n```js\nimport { $average, $latest } from \"@embarklabs/subspace\";\n\nconst rating$ = Product.events.Rating.track().map(\"rating\")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n console.log(\"average rating of the last 5 events is \" + rating)\n});\n```\n\n## Tracking balances\nYou can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the `callInterval` configured. \n\nTracking ETH balance in an address:\n\n```js\nconst address = \"0x0001020304050607080900010203040506070809\";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking ETH balance in a Contract:\n\n```js\nContract.trackBalance().subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking an ERC20 balance in a Contract:\n\n```js\nconst tokenAddress = \"0x744d70fdbe2ba4cf95131626614a1763df805b9e\"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n```\n\n
\nBalances are returned as a string containing the value in wei.\n
\n\n\n\n## Getting block data, gas prices and block time\nSubspace also provides a way to always receive the latest block object: \n```js\nsubspace.trackBlock().subscribe(block => {\n console.log(\"The latest block data: \", block);\n});\n```\n\nIf you don't need all the block information, but just the block number, you can use instead:\n```js\nsubspace.trackBlockNumber().subscribe(blockNumber => {\n console.log(\"The latest block number: \", blockNumber);\n});\n```\n\nYou can also access the average block time. This takes in account only the last 10 blocks:\n\n```js\nsubspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n console.log(\"The average block time in milliseconds is: \", blocktimeMS);\n});\n```\n\nFinally, if you want to obtain the most up to date median gas price:\n\n```js\nsubspace.trackGasPrice().subscribe(gasPrice => {\n console.log(\"Gas price in wei\", gasPrice);\n});\n```\n\n\n## Subscriptions\nOnce you have an `Observable`, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.\n\nSubscriptions can be disposed by executing the method `unsubscribe()` liberating the resource held by it:\n\n```js\nconst myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n console.log(\"The balance is: \", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n```\n\n#### Further read\n- [RxJS Subscriptions](https://rxjs-dev.firebaseapp.com/guide/subscription)\n\n## Cleanup\nIf **Subspace** is not needed anymore, you need can invoke `close()` to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution, thus avoiding any potential memory leak.\n\n```\nsubspace.close();\n```\n
\n

What about subscriptions created with our observables?

\nclose() 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 subsink can be used to clear all the observables' subscriptions at once.\n
\n\n","source":"getting-started.md","raw":"---\ntitle: Getting Started\n---\n# Getting Started\n\n## Installation\n**Subspace** can be used in browser, node and native script environments. To get started install the package `@embarklabs/subspace` using `npm` or `yarn` by executing this command in your project directory:\n```bash\n# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n```\n\n## Importing the library\n\n```js\n// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace'; \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n```\n\n\n## Connecting to a web3 provider\nTo interact with the EVM, **Subspace** requires a valid Web3 object, connected to a provider\n\n```js\nconst subspace = new Subspace(web3);\nawait subspace.init();\n```\n\nIn addition to the provider, `Subspace` also accepts an `options` object with settings that can change its behavior:\n- `dbFilename` - Name of the database where the information will be stored (default `'subspace.db'`)\n- `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).\n- `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),\n- `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`)\n\n\n## Enhancing your contract objects\nSubspace provides a method to enhance your web3 Contract objects: `subspace.contract(instance|{abi,address})`. Calling this method will return a new contract object decorated with a `.track()` method for your contract view functions and events.\n\n```js\nconst myRxContract = subspace.contract(myContractInstance);\n```\n\nYou can also instantiate a contract directly by passing the contract ABI and its address:\n\n```js\nconst myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n```\n\n## Reacting to data\nOnce 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.\n\n
\n

What is an Observable?

\nThe Observable type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n#### Further read\n- [RxJS Observables](https://rxjs-dev.firebaseapp.com/guide/observable)\n\n## Tracking state\nYou can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract. \n```js\nconst stateObservable$ = Contract.methods.functionName(functionArgs).track();\n```\n\n
\n

Tracking the public variables of a contract

\nState 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).\n
\n\nExample:\n\n```js\nconst productTitle$ = ProductList.methods.products(0).track().map(\"title\");\nproductTitle$.subscribe((title) => console.log(\"product title is \" + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, \"products\", [0], {from: web3.eth.defaultAccount});\n...\n```\n\nThe subscription will be triggered whenever the title changes\n\n## Tracking events\nYou can track events and react to their returned values.\n```js\nconst eventObservable$ = Contract.event.eventName.track();\n```\n\nExample:\n\n```js\nconst rating$ = Product.events.Rating.track().map(\"rating\")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log(\"rating received: \" + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, \"Rating\", {fromBlock: 0});\n...\n```\n\n**Event Sourcing**\n\nYou can easily do event sourcing with subspace.\n\nFor e.g: if you needed to get the average rating of the last 5 events:\n\n```js\nimport { $average, $latest } from \"@embarklabs/subspace\";\n\nconst rating$ = Product.events.Rating.track().map(\"rating\")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n console.log(\"average rating of the last 5 events is \" + rating)\n});\n```\n\n## Tracking balances\nYou can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the `callInterval` configured. \n\nTracking ETH balance in an address:\n\n```js\nconst address = \"0x0001020304050607080900010203040506070809\";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking ETH balance in a Contract:\n\n```js\nContract.trackBalance().subscribe((balance) => {\n console.log(\"ETH balance is \", balance)\n});\n```\n\nTracking an ERC20 balance in a Contract:\n\n```js\nconst tokenAddress = \"0x744d70fdbe2ba4cf95131626614a1763df805b9e\"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n```\n\n
\nBalances are returned as a string containing the value in wei.\n
\n\n\n\n## Getting block data, gas prices and block time\nSubspace also provides a way to always receive the latest block object: \n```js\nsubspace.trackBlock().subscribe(block => {\n console.log(\"The latest block data: \", block);\n});\n```\n\nIf you don't need all the block information, but just the block number, you can use instead:\n```js\nsubspace.trackBlockNumber().subscribe(blockNumber => {\n console.log(\"The latest block number: \", blockNumber);\n});\n```\n\nYou can also access the average block time. This takes in account only the last 10 blocks:\n\n```js\nsubspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n console.log(\"The average block time in milliseconds is: \", blocktimeMS);\n});\n```\n\nFinally, if you want to obtain the most up to date median gas price:\n\n```js\nsubspace.trackGasPrice().subscribe(gasPrice => {\n console.log(\"Gas price in wei\", gasPrice);\n});\n```\n\n\n## Subscriptions\nOnce you have an `Observable`, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.\n\nSubscriptions can be disposed by executing the method `unsubscribe()` liberating the resource held by it:\n\n```js\nconst myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n console.log(\"The balance is: \", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n```\n\n#### Further read\n- [RxJS Subscriptions](https://rxjs-dev.firebaseapp.com/guide/subscription)\n\n## Cleanup\nIf **Subspace** is not needed anymore, you need can invoke `close()` to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution, thus avoiding any potential memory leak.\n\n```\nsubspace.close();\n```\n
\n

What about subscriptions created with our observables?

\nclose() 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 subsink can be used to clear all the observables' subscriptions at once.\n
\n\n","date":"2020-03-20T17:31:47.304Z","updated":"2020-03-20T17:31:47.304Z","path":"getting-started.html","_id":"ck7z3hcl300035cbn6eyxc67o","comments":1,"layout":"page","content":"

Getting Started

Installation

Subspace can be used in browser, node and native script environments. To get started install the package @embarklabs/subspace using npm or yarn by executing this command in your project directory:

\n\n\n
# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n
\n\n\n\n

Importing the library

\n\n
// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace';  \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n
\n\n\n\n

Connecting to a web3 provider

To interact with the EVM, Subspace requires a valid Web3 object, connected to a provider

\n\n\n
const subspace = new Subspace(web3);\nawait subspace.init();\n
\n\n\n\n

In addition to the provider, Subspace also accepts an options object with settings that can change its behavior:

\n
    \n
  • dbFilename - Name of the database where the information will be stored (default 'subspace.db')
  • \n
  • 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).
  • \n
  • 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),
  • \n
  • 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)
  • \n
\n

Enhancing your contract objects

Subspace provides a method to enhance your web3 Contract objects: subspace.contract(instance|{abi,address}). Calling this method will return a new contract object decorated with a .track() method for your contract view functions and events.

\n\n\n
const myRxContract = subspace.contract(myContractInstance);\n
\n\n\n\n

You can also instantiate a contract directly by passing the contract ABI and its address:

\n\n\n
const myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n
\n\n\n\n

Reacting to data

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.

\n
\n

What is an Observable?

\nThe Observable type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n

Further read

\n

Tracking state

You can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract.

\n\n\n
const stateObservable$ = Contract.methods.functionName(functionArgs).track();\n
\n\n\n\n
\n

Tracking the public variables of a contract

\nState 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).\n
\n\n

Example:

\n\n\n
const productTitle$ = ProductList.methods.products(0).track().map("title");\nproductTitle$.subscribe((title) => console.log("product title is " + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, "products", [0], {from: web3.eth.defaultAccount});\n...\n
\n\n\n\n

The subscription will be triggered whenever the title changes

\n

Tracking events

You can track events and react to their returned values.

\n\n\n
const eventObservable$ = Contract.event.eventName.track();\n
\n\n\n\n

Example:

\n\n\n
const rating$ = Product.events.Rating.track().map("rating")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log("rating received: " + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, "Rating", {fromBlock: 0});\n...\n
\n\n\n\n

Event Sourcing

\n

You can easily do event sourcing with subspace.

\n

For e.g: if you needed to get the average rating of the last 5 events:

\n\n\n
import { $average, $latest } from "@embarklabs/subspace";\n\nconst rating$ = Product.events.Rating.track().map("rating")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n  console.log("average rating of the last 5 events is " + rating)\n});\n
\n\n\n\n

Tracking balances

You can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the callInterval configured.

\n

Tracking ETH balance in an address:

\n\n\n
const address = "0x0001020304050607080900010203040506070809";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking ETH balance in a Contract:

\n\n\n
Contract.trackBalance().subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking an ERC20 balance in a Contract:

\n\n\n
const tokenAddress = "0x744d70fdbe2ba4cf95131626614a1763df805b9e"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n
\n\n\n\n
\nBalances are returned as a string containing the value in wei.\n
\n\n\n\n

Getting block data, gas prices and block time

Subspace also provides a way to always receive the latest block object:

\n\n\n
subspace.trackBlock().subscribe(block => {\n  console.log("The latest block data: ", block);\n});\n
\n\n\n\n

If you don’t need all the block information, but just the block number, you can use instead:

\n\n\n
subspace.trackBlockNumber().subscribe(blockNumber => {\n  console.log("The latest block number: ", blockNumber);\n});\n
\n\n\n\n

You can also access the average block time. This takes in account only the last 10 blocks:

\n\n\n
subspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n  console.log("The average block time in milliseconds is: ", blocktimeMS);\n});\n
\n\n\n\n

Finally, if you want to obtain the most up to date median gas price:

\n\n\n
subspace.trackGasPrice().subscribe(gasPrice => {\n  console.log("Gas price in wei", gasPrice);\n});\n
\n\n\n\n

Subscriptions

Once you have an Observable, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.

\n

Subscriptions can be disposed by executing the method unsubscribe() liberating the resource held by it:

\n\n\n
const myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n  console.log("The balance is: ", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n
\n\n\n\n

Further read

\n

Cleanup

If Subspace is not needed anymore, you need can invoke close() to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution, thus avoiding any potential memory leak.

\n\n\n
subspace.close();\n
\n\n
\n

What about subscriptions created with our observables?

\nclose() 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 subsink can be used to clear all the observables' subscriptions at once.\n
\n\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

Getting Started

Installation

Subspace can be used in browser, node and native script environments. To get started install the package @embarklabs/subspace using npm or yarn by executing this command in your project directory:

\n\n\n
# Using npm\nnpm install --save @embarklabs/subspace\n\n# Using yarn\nyarn add @embarklabs/subspace \n
\n\n\n\n

Importing the library

\n\n
// ESM (might require babel / browserify)\nimport Subspace from '@embarklabs/subspace';  \n\n// CommonJS\nconst Subspace = require('@embarklabs/subspace'); \n
\n\n\n\n

Connecting to a web3 provider

To interact with the EVM, Subspace requires a valid Web3 object, connected to a provider

\n\n\n
const subspace = new Subspace(web3);\nawait subspace.init();\n
\n\n\n\n

In addition to the provider, Subspace also accepts an options object with settings that can change its behavior:

\n
    \n
  • dbFilename - Name of the database where the information will be stored (default 'subspace.db')
  • \n
  • 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).
  • \n
  • 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),
  • \n
  • 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)
  • \n
\n

Enhancing your contract objects

Subspace provides a method to enhance your web3 Contract objects: subspace.contract(instance|{abi,address}). Calling this method will return a new contract object decorated with a .track() method for your contract view functions and events.

\n\n\n
const myRxContract = subspace.contract(myContractInstance);\n
\n\n\n\n

You can also instantiate a contract directly by passing the contract ABI and its address:

\n\n\n
const myRXContract = subspace.contract({abi: ...., address: '0x1234...CDEF'})\n
\n\n\n\n

Reacting to data

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.

\n
\n

What is an Observable?

\nThe Observable type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:\n- Compositional: Observables can be composed with higher-order combinators.\n- Lazy: Observables do not start emitting data until an observer has subscribed.\n
\n\n

Further read

\n

Tracking state

You can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract.

\n\n\n
const stateObservable$ = Contract.methods.functionName(functionArgs).track();\n
\n\n\n\n
\n

Tracking the public variables of a contract

\nState 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).\n
\n\n

Example:

\n\n\n
const productTitle$ = ProductList.methods.products(0).track().map("title");\nproductTitle$.subscribe((title) => console.log("product title is " + title));\n\n\n// Alternative using Subspace low level API\nconst producTitle$ = subspace.trackProperty(ProductList, "products", [0], {from: web3.eth.defaultAccount});\n...\n
\n\n\n\n

The subscription will be triggered whenever the title changes

\n

Tracking events

You can track events and react to their returned values.

\n\n\n
const eventObservable$ = Contract.event.eventName.track();\n
\n\n\n\n

Example:

\n\n\n
const rating$ = Product.events.Rating.track().map("rating")).pipe(map(x => parseInt(x)));\nrating$.subscribe((rating) => console.log("rating received: " + rating));\n\n\n// Alternative using Subspace low level API\nconst rating$ = subspace.trackEvent(Product, "Rating", {fromBlock: 0});\n...\n
\n\n\n\n

Event Sourcing

\n

You can easily do event sourcing with subspace.

\n

For e.g: if you needed to get the average rating of the last 5 events:

\n\n\n
import { $average, $latest } from "@embarklabs/subspace";\n\nconst rating$ = Product.events.Rating.track().map("rating")).pipe(map(x => parseInt(x)));\n\nrating$.pipe($latest(5), $average()).subscribe((rating) => {\n  console.log("average rating of the last 5 events is " + rating)\n});\n
\n\n\n\n

Tracking balances

You can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the callInterval configured.

\n

Tracking ETH balance in an address:

\n\n\n
const address = "0x0001020304050607080900010203040506070809";\n\nsubspace.trackBalance(address).subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking ETH balance in a Contract:

\n\n\n
Contract.trackBalance().subscribe((balance) => {\n  console.log("ETH balance is ", balance)\n});\n
\n\n\n\n

Tracking an ERC20 balance in a Contract:

\n\n\n
const tokenAddress = "0x744d70fdbe2ba4cf95131626614a1763df805b9e"; // SNT Address\n\nconst myBalanceObservable$ = Contract.trackBalance(tokenAddress);\n
\n\n\n\n
\nBalances are returned as a string containing the value in wei.\n
\n\n\n\n

Getting block data, gas prices and block time

Subspace also provides a way to always receive the latest block object:

\n\n\n
subspace.trackBlock().subscribe(block => {\n  console.log("The latest block data: ", block);\n});\n
\n\n\n\n

If you don’t need all the block information, but just the block number, you can use instead:

\n\n\n
subspace.trackBlockNumber().subscribe(blockNumber => {\n  console.log("The latest block number: ", blockNumber);\n});\n
\n\n\n\n

You can also access the average block time. This takes in account only the last 10 blocks:

\n\n\n
subspace.trackAverageBlocktime().subscribe(blocktimeMS => {\n  console.log("The average block time in milliseconds is: ", blocktimeMS);\n});\n
\n\n\n\n

Finally, if you want to obtain the most up to date median gas price:

\n\n\n
subspace.trackGasPrice().subscribe(gasPrice => {\n  console.log("Gas price in wei", gasPrice);\n});\n
\n\n\n\n

Subscriptions

Once you have an Observable, you may receive a stream of data by creating a subscription. Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.

\n

Subscriptions can be disposed by executing the method unsubscribe() liberating the resource held by it:

\n\n\n
const myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);\nconst subscription = myBalanceObservable$.subscribe(value => { \n  console.log("The balance is: ", value); \n});\n\n// ...\n\nsubscription.unsubscribe();\n
\n\n\n\n

Further read

\n

Cleanup

If Subspace is not needed anymore, you need can invoke close() to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by Subspace during its normal execution, thus avoiding any potential memory leak.

\n\n\n
subspace.close();\n
\n\n
\n

What about subscriptions created with our observables?

\nclose() 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 subsink can be used to clear all the observables' subscriptions at once.\n
\n\n"},{"_content":"# How it works?\n\n### Setup\n![First Usage - Setup](./d1.png)\n1. A ÐApp requests `Subspace` to track an event, property, or balance.\n2. `Subspace` creates a observable for that event, and a web3 subscription to retrieve events from the chain\n3. The ÐApp subscribes to the observable to receive events.\n\n### Receiving events\n![First Usage - Receiving events](./d2.png)\nDepending on the filter parameters used to track the events, once an event is found, it is stored in `localStorage` and it is also pushed to the observable which delivers it to the ÐApp subscription.\n\n### Tracking already known events \nAfter restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of `Subspace` will change: \n![Second Usage - Setup](./d3.png)\n1. The Dapp will request `Subspace` to track an event it already knows, creating an observable and subscription for that event\n2. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again. \n\n![Second Usage - Receiving events](./d4.png)\nThe web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step\n","source":"how-it-works.md","raw":"# How it works?\n\n### Setup\n![First Usage - Setup](./d1.png)\n1. A ÐApp requests `Subspace` to track an event, property, or balance.\n2. `Subspace` creates a observable for that event, and a web3 subscription to retrieve events from the chain\n3. The ÐApp subscribes to the observable to receive events.\n\n### Receiving events\n![First Usage - Receiving events](./d2.png)\nDepending on the filter parameters used to track the events, once an event is found, it is stored in `localStorage` and it is also pushed to the observable which delivers it to the ÐApp subscription.\n\n### Tracking already known events \nAfter restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of `Subspace` will change: \n![Second Usage - Setup](./d3.png)\n1. The Dapp will request `Subspace` to track an event it already knows, creating an observable and subscription for that event\n2. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again. \n\n![Second Usage - Receiving events](./d4.png)\nThe web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step\n","date":"2020-03-20T17:02:58.892Z","updated":"2020-03-09T15:25:14.948Z","path":"how-it-works.html","_id":"ck7z3hcl400045cbnewgsc9im","title":"","comments":1,"layout":"page","content":"

How it works?

Setup

\"First

\n
    \n
  1. A ÐApp requests Subspace to track an event, property, or balance.
  2. \n
  3. Subspace creates a observable for that event, and a web3 subscription to retrieve events from the chain
  4. \n
  5. The ÐApp subscribes to the observable to receive events.
  6. \n
\n

Receiving events

\"First
Depending on the filter parameters used to track the events, once an event is found, it is stored in localStorage and it is also pushed to the observable which delivers it to the ÐApp subscription.

\n

Tracking already known events

After restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of Subspace will change:
\"Second

\n
    \n
  1. The Dapp will request Subspace to track an event it already knows, creating an observable and subscription for that event
  2. \n
  3. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again.
  4. \n
\n

\"Second
The web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step

\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

How it works?

Setup

\"First

\n
    \n
  1. A ÐApp requests Subspace to track an event, property, or balance.
  2. \n
  3. Subspace creates a observable for that event, and a web3 subscription to retrieve events from the chain
  4. \n
  5. The ÐApp subscribes to the observable to receive events.
  6. \n
\n

Receiving events

\"First
Depending on the filter parameters used to track the events, once an event is found, it is stored in localStorage and it is also pushed to the observable which delivers it to the ÐApp subscription.

\n

Tracking already known events

After restarting the ÐApp, either by executing it again in case of a console application or refreshing the browser the behavior of Subspace will change:
\"Second

\n
    \n
  1. The Dapp will request Subspace to track an event it already knows, creating an observable and subscription for that event
  2. \n
  3. It will retrieve events that were previously stored in localStorage and deliver them to the DApp subscription, avoiding having to query the chain for the old events again.
  4. \n
\n

\"Second
The web3 subscription created previously will start from the last known block instead of beginning from scratch. New events will be delivered normally from this step

\n"},{"title":"Homepage","_content":"","source":"index.md","raw":"title: Homepage\n---\n","date":"2020-03-19T18:30:37.775Z","updated":"2020-03-19T18:28:50.738Z","path":"index.html","comments":1,"layout":"page","_id":"ck7z3hcl400055cbn8ipl2hj7","content":"","site":{"data":{}},"excerpt":"","more":""},{"_content":"# reactive-graphql\n\nUsing `reactive-graphql` you can execute GraphQL queries against **Subspace** observables after you create your own type definitions and resolvers.\n\n### Example\n\n\n```js\nconst Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require(\"graphql-tools\");\nconst gql = require(\"graphql-tag\");\nconst { graphql } = require(\"reactive-graphql\");\n\nconst run = async () => {\n const subspace = new Subspace(web3);\n await subspace.init();\n\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n `;\n\n const resolvers = {\n Query: {\n myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n }\n };\n\n const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n const query = gql`\n query {\n myEvents {\n someValue\n anotherValue\n }\n }\n `;\n\n const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n stream.subscribe(data => {\n console.log(data);\n })\n\n}\n\nrun();\n```\n\n
\nThis example is available in Github\n
","source":"reactive-graphql.md","raw":"# reactive-graphql\n\nUsing `reactive-graphql` you can execute GraphQL queries against **Subspace** observables after you create your own type definitions and resolvers.\n\n### Example\n\n\n```js\nconst Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require(\"graphql-tools\");\nconst gql = require(\"graphql-tag\");\nconst { graphql } = require(\"reactive-graphql\");\n\nconst run = async () => {\n const subspace = new Subspace(web3);\n await subspace.init();\n\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const typeDefs = `\n type MyEvent {\n someValue: Int\n anotherValue: String\n }\n type Query {\n myEvents: MyEvent!\n }\n `;\n\n const resolvers = {\n Query: {\n myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n }\n };\n\n const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n const query = gql`\n query {\n myEvents {\n someValue\n anotherValue\n }\n }\n `;\n\n const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n stream.subscribe(data => {\n console.log(data);\n })\n\n}\n\nrun();\n```\n\n
\nThis example is available in Github\n
","date":"2020-03-20T17:18:41.872Z","updated":"2020-03-20T17:18:41.872Z","path":"reactive-graphql.html","_id":"ck7z3hcl500065cbn1hki9bhm","title":"","comments":1,"layout":"page","content":"

reactive-graphql

Using reactive-graphql you can execute GraphQL queries against Subspace observables after you create your own type definitions and resolvers.

\n

Example

\n\n
const Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require("graphql-tools");\nconst gql = require("graphql-tag");\nconst { graphql } = require("reactive-graphql");\n\nconst run = async () => {\n  const subspace = new Subspace(web3);\n  await subspace.init();\n\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const typeDefs = `\n    type MyEvent {\n      someValue: Int\n      anotherValue: String\n    }\n    type Query {\n      myEvents: MyEvent!\n    }\n  `;\n\n  const resolvers = {\n    Query: {\n      myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n    }\n  };\n\n  const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n  const query = gql`\n    query {\n      myEvents {\n        someValue\n        anotherValue\n      }\n    }\n  `;\n\n  const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n  stream.subscribe(data => {\n    console.log(data);\n  })\n\n}\n\nrun();\n
\n\n\n\n
\nThis example is available in Github\n
","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

reactive-graphql

Using reactive-graphql you can execute GraphQL queries against Subspace observables after you create your own type definitions and resolvers.

\n

Example

\n\n
const Subspace = require('@embarklabs/subspace');\nconst MyContract = require('./MyContract');\nconst { pluck } = require('rxjs/operators');\nconst { makeExecutableSchema } = require("graphql-tools");\nconst gql = require("graphql-tag");\nconst { graphql } = require("reactive-graphql");\n\nconst run = async () => {\n  const subspace = new Subspace(web3);\n  await subspace.init();\n\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const typeDefs = `\n    type MyEvent {\n      someValue: Int\n      anotherValue: String\n    }\n    type Query {\n      myEvents: MyEvent!\n    }\n  `;\n\n  const resolvers = {\n    Query: {\n      myEvents: () => subspace.trackEvent(MyContractInstance, 'MyEvent', { filter: {}, fromBlock: 1 })\n    }\n  };\n\n  const schema = makeExecutableSchema({ typeDefs, resolvers });\n\n  const query = gql`\n    query {\n      myEvents {\n        someValue\n        anotherValue\n      }\n    }\n  `;\n\n  const stream = graphql(schema, query).pipe(pluck('data', 'myEvents'));\n  stream.subscribe(data => {\n    console.log(data);\n  })\n\n}\n\nrun();\n
\n\n\n\n
\nThis example is available in Github\n
"},{"_content":"# React\nSubspace also provides a set of components that simplifies its usage within React projects through the `@embarklabs/subspace-react` package.\n\n### Install\nYou can install it through npm or yarn:\n```\nnpm install --save @embarklabs/subspace-react web3 rxjs # RxJS and Web3.js are needed peer-dependencies\n```\n\n### Usage\n\n#### SubspaceProvider\nTo use most of the `subspace-react` components, you need to wrap your app with the `` 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\n\n```js\n// index.js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport MyApp from './MyApp'\nimport { SubspaceProvider } from '@embarklabs/subspace-react';\n\nconst web3 = new Web3(\"ws://localhost:8545\");\n\nconst rootElement = document.getElementById('root')\nReactDOM.render(\n \n \n ,\n rootElement\n);\n```\n\n\n#### useSubspace\nRather 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 `` to have it available througout the component tree.\n```js\n// index.js\nimport React from 'react'\nimport { useSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = () => {\n const subspace = useSubspace();\n\n // do something....\n // subspace.trackBalance(web3.eth.defaultAccount);\n\n return ...;\n}\n\nexport default MyComponent\n```\n\n\n#### withSubspace\nThis 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 ``.\n\n```js\n// index.js\nimport React from 'react'\nimport { withSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = (props) => {\n // do something....\n // props.subspace.trackBalance(web3.eth.defaultAccount);\n\n return ...;\n}\n\nexport default withSubspace(MyComponent);\n```\n\n\n#### observe\n\nUseful 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.\n\n\n```js\nimport { observe } from '@embarklabs/subspace-react';\n\nconst ObserverComponent = observe(WrappedComponent);\n```\n\n##### Example usage:\n```js\nconst MyComponent = ({eventData}) => {\n // Handle initial state when no data is available\n if (!eventData) {\n return

No data

;\n }\n \n return

Value: {eventData.someReturnValue}

\n};\n\n\nconst MyEnhancedComponent = observe(MyComponent);\n\n\nconst SomeOtherComponent = () => {\n const myObservable$ = MyContractInstance.events.MyEvent.track({fromBlock: 1});\n return ;\n}\n```\n\n\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address that has been enhanced with subspace.contract(). You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';.\n
\n\n\n
\nTo learn more about how to use subspace-react, there are full working examples available in Github \n
\n","source":"react.md","raw":"# React\nSubspace also provides a set of components that simplifies its usage within React projects through the `@embarklabs/subspace-react` package.\n\n### Install\nYou can install it through npm or yarn:\n```\nnpm install --save @embarklabs/subspace-react web3 rxjs # RxJS and Web3.js are needed peer-dependencies\n```\n\n### Usage\n\n#### SubspaceProvider\nTo use most of the `subspace-react` components, you need to wrap your app with the `` 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\n\n```js\n// index.js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport MyApp from './MyApp'\nimport { SubspaceProvider } from '@embarklabs/subspace-react';\n\nconst web3 = new Web3(\"ws://localhost:8545\");\n\nconst rootElement = document.getElementById('root')\nReactDOM.render(\n \n \n ,\n rootElement\n);\n```\n\n\n#### useSubspace\nRather 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 `` to have it available througout the component tree.\n```js\n// index.js\nimport React from 'react'\nimport { useSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = () => {\n const subspace = useSubspace();\n\n // do something....\n // subspace.trackBalance(web3.eth.defaultAccount);\n\n return ...;\n}\n\nexport default MyComponent\n```\n\n\n#### withSubspace\nThis 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 ``.\n\n```js\n// index.js\nimport React from 'react'\nimport { withSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = (props) => {\n // do something....\n // props.subspace.trackBalance(web3.eth.defaultAccount);\n\n return ...;\n}\n\nexport default withSubspace(MyComponent);\n```\n\n\n#### observe\n\nUseful 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.\n\n\n```js\nimport { observe } from '@embarklabs/subspace-react';\n\nconst ObserverComponent = observe(WrappedComponent);\n```\n\n##### Example usage:\n```js\nconst MyComponent = ({eventData}) => {\n // Handle initial state when no data is available\n if (!eventData) {\n return

No data

;\n }\n \n return

Value: {eventData.someReturnValue}

\n};\n\n\nconst MyEnhancedComponent = observe(MyComponent);\n\n\nconst SomeOtherComponent = () => {\n const myObservable$ = MyContractInstance.events.MyEvent.track({fromBlock: 1});\n return ;\n}\n```\n\n\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address that has been enhanced with subspace.contract(). You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';.\n
\n\n\n
\nTo learn more about how to use subspace-react, there are full working examples available in Github \n
\n","date":"2020-03-20T17:16:18.524Z","updated":"2020-03-20T17:16:18.524Z","path":"react.html","_id":"ck7z3hcl600075cbn76084luf","title":"","comments":1,"layout":"page","content":"

React

Subspace also provides a set of components that simplifies its usage within React projects through the @embarklabs/subspace-react package.

\n

Install

You can install it through npm or yarn:

\n\n\n
npm install --save @embarklabs/subspace-react web3 rxjs # RxJS and Web3.js are needed peer-dependencies\n
\n\n\n\n

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

\n\n\n
// index.js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport MyApp from './MyApp'\nimport { SubspaceProvider } from '@embarklabs/subspace-react';\n\nconst web3 = new Web3("ws://localhost:8545");\n\nconst rootElement = document.getElementById('root')\nReactDOM.render(\n  <SubspaceProvider web3={web3}>\n    <MyApp />\n  </SubspaceProvider>,\n  rootElement\n);\n
\n\n\n\n

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.

\n\n\n
// index.js\nimport React from 'react'\nimport { useSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = () => {\n  const subspace = useSubspace();\n\n  // do something....\n  // subspace.trackBalance(web3.eth.defaultAccount);\n\n  return ...;\n}\n\nexport default MyComponent\n
\n\n\n\n

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 />.

\n\n\n
// index.js\nimport React from 'react'\nimport { withSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = (props) => {\n  // do something....\n  // props.subspace.trackBalance(web3.eth.defaultAccount);\n\n  return ...;\n}\n\nexport default withSubspace(MyComponent);\n
\n\n\n\n

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.

\n\n\n
import { observe } from '@embarklabs/subspace-react';\n\nconst ObserverComponent = observe(WrappedComponent);\n
\n\n\n\n
Example usage:
\n\n
const MyComponent = ({eventData}) =>  {\n  // Handle initial state when no data is available\n  if (!eventData) {\n    return <p>No data</p>;\n  }\n  \n  return <p>Value: {eventData.someReturnValue}</p>\n};\n\n\nconst MyEnhancedComponent = observe(MyComponent);\n\n\nconst SomeOtherComponent = () => {\n  const myObservable$ = MyContractInstance.events.MyEvent.track({fromBlock: 1});\n  return <MyEnhancedComponent myProp={myObservable$} />;\n}\n
\n\n\n\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address that has been enhanced with subspace.contract(). You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';.\n
\n\n\n
\nTo learn more about how to use subspace-react, there are full working examples available in Github \n
\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

React

Subspace also provides a set of components that simplifies its usage within React projects through the @embarklabs/subspace-react package.

\n

Install

You can install it through npm or yarn:

\n\n\n
npm install --save @embarklabs/subspace-react web3 rxjs # RxJS and Web3.js are needed peer-dependencies\n
\n\n\n\n

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

\n\n\n
// index.js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport MyApp from './MyApp'\nimport { SubspaceProvider } from '@embarklabs/subspace-react';\n\nconst web3 = new Web3("ws://localhost:8545");\n\nconst rootElement = document.getElementById('root')\nReactDOM.render(\n  <SubspaceProvider web3={web3}>\n    <MyApp />\n  </SubspaceProvider>,\n  rootElement\n);\n
\n\n\n\n

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.

\n\n\n
// index.js\nimport React from 'react'\nimport { useSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = () => {\n  const subspace = useSubspace();\n\n  // do something....\n  // subspace.trackBalance(web3.eth.defaultAccount);\n\n  return ...;\n}\n\nexport default MyComponent\n
\n\n\n\n

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 />.

\n\n\n
// index.js\nimport React from 'react'\nimport { withSubspace } from '@embarklabs/subspace-react';\n\nconst MyComponent = (props) => {\n  // do something....\n  // props.subspace.trackBalance(web3.eth.defaultAccount);\n\n  return ...;\n}\n\nexport default withSubspace(MyComponent);\n
\n\n\n\n

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.

\n\n\n
import { observe } from '@embarklabs/subspace-react';\n\nconst ObserverComponent = observe(WrappedComponent);\n
\n\n\n\n
Example usage:
\n\n
const MyComponent = ({eventData}) =>  {\n  // Handle initial state when no data is available\n  if (!eventData) {\n    return <p>No data</p>;\n  }\n  \n  return <p>Value: {eventData.someReturnValue}</p>\n};\n\n\nconst MyEnhancedComponent = observe(MyComponent);\n\n\nconst SomeOtherComponent = () => {\n  const myObservable$ = MyContractInstance.events.MyEvent.track({fromBlock: 1});\n  return <MyEnhancedComponent myProp={myObservable$} />;\n}\n
\n\n\n\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address that has been enhanced with subspace.contract(). You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';.\n
\n\n\n
\nTo learn more about how to use subspace-react, there are full working examples available in Github \n
\n"},{"_content":"# Integrations with other frameworks\n\n**Subspace** does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate **Subspace** with various frontend frameworks and libraries","source":"integrations-overview.md","raw":"# Integrations with other frameworks\n\n**Subspace** does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate **Subspace** with various frontend frameworks and libraries","date":"2020-03-20T17:02:59.624Z","updated":"2020-03-09T15:25:14.948Z","path":"integrations-overview.html","_id":"ck7z3hcl600085cbn32fk804l","title":"","comments":1,"layout":"page","content":"

Integrations with other frameworks

Subspace does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate Subspace with various frontend frameworks and libraries

\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

Integrations with other frameworks

Subspace does not force you to change the architecture of your dApps, making it easy to use on existing projects. In this section you can find some examples and tips on how to integrate Subspace with various frontend frameworks and libraries

\n"},{"_content":"# redux \n\n**Subspace** can be used with [redux](https://redux.js.org/). **Subspace** returns [`Observables`](https://rxjs-dev.firebaseapp.com/guide/observable), which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.\n\n### Example\nHere's a simple example on how to setup **Subspace** to work with `redux`:\n\n
\nThis example is available in Github\n
\n\n#### index.js\n```js\nimport store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const subspace = new Subspace(web3);\n await subspace.init();\n \n subspace.trackEvent(MyContractInstance, \"MyEvent\", {filter: {}, fromBlock: 1 })\n .subscribe(eventData => {\n store.dispatch(myAction(eventData));\n });\n}\n\nrun();\n```\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address. You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';, or use web3.js directly (just like in the example source code)\n
\n\n#### store.js\n```js\nimport { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n```\n\n#### reducer.js\n```js\nimport { MY_ACTION } from \"./constants\";\n\nconst initialState = { \n data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n switch (action.type) {\n case MY_ACTION:\n return { data: action.eventData };\n default:\n return state;\n }\n};\n```\n\n#### constants.js\n```js\nexport const MY_ACTION = 'MY_ACTION';\n```\n\n#### actions.js\n```js\nimport {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n```\n\n
\n

Using React and Redux

\nA practical example can also be found in examples/react-redux.\n
","source":"redux.md","raw":"# redux \n\n**Subspace** can be used with [redux](https://redux.js.org/). **Subspace** returns [`Observables`](https://rxjs-dev.firebaseapp.com/guide/observable), which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.\n\n### Example\nHere's a simple example on how to setup **Subspace** to work with `redux`:\n\n
\nThis example is available in Github\n
\n\n#### index.js\n```js\nimport store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n const subspace = new Subspace(web3);\n await subspace.init();\n \n subspace.trackEvent(MyContractInstance, \"MyEvent\", {filter: {}, fromBlock: 1 })\n .subscribe(eventData => {\n store.dispatch(myAction(eventData));\n });\n}\n\nrun();\n```\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address. You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';, or use web3.js directly (just like in the example source code)\n
\n\n#### store.js\n```js\nimport { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n```\n\n#### reducer.js\n```js\nimport { MY_ACTION } from \"./constants\";\n\nconst initialState = { \n data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n switch (action.type) {\n case MY_ACTION:\n return { data: action.eventData };\n default:\n return state;\n }\n};\n```\n\n#### constants.js\n```js\nexport const MY_ACTION = 'MY_ACTION';\n```\n\n#### actions.js\n```js\nimport {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n```\n\n
\n

Using React and Redux

\nA practical example can also be found in examples/react-redux.\n
","date":"2020-03-20T17:26:25.944Z","updated":"2020-03-20T17:26:25.944Z","path":"redux.html","_id":"ck7z3hcl700095cbn0x9h37v1","title":"","comments":1,"layout":"page","content":"

redux

Subspace can be used with redux. Subspace returns Observables, which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.

\n

Example

Here’s a simple example on how to setup Subspace to work with redux:

\n
\nThis example is available in Github\n
\n\n

index.js

\n\n
import store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const subspace = new Subspace(web3);\n  await subspace.init();\n    \n  subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 })\n             .subscribe(eventData => {\n               store.dispatch(myAction(eventData));\n             });\n}\n\nrun();\n
\n\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address. You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';, or use web3.js directly (just like in the example source code)\n
\n\n

store.js

\n\n
import { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n
\n\n\n\n

reducer.js

\n\n
import { MY_ACTION } from "./constants";\n\nconst initialState = { \n  data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n  switch (action.type) {\n    case MY_ACTION:\n      return { data: action.eventData };\n    default:\n      return state;\n  }\n};\n
\n\n\n\n

constants.js

\n\n
export const MY_ACTION = 'MY_ACTION';\n
\n\n\n\n

actions.js

\n\n
import {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n
\n\n\n\n
\n

Using React and Redux

\nA practical example can also be found in examples/react-redux.\n
","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

redux

Subspace can be used with redux. Subspace returns Observables, which you can subscribe to, and if this subscription has access to the redux store, it will be able to dispatch actions when the observable emits an event.

\n

Example

Here’s a simple example on how to setup Subspace to work with redux:

\n
\nThis example is available in Github\n
\n\n

index.js

\n\n
import store from './store';\nimport web3 from './web3';\nimport Subspace from '@embarklabs/subspace';\nimport { myAction } from './actions';\n\nconst run = async () => {\n  const MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n  const subspace = new Subspace(web3);\n  await subspace.init();\n    \n  subspace.trackEvent(MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 })\n             .subscribe(eventData => {\n               store.dispatch(myAction(eventData));\n             });\n}\n\nrun();\n
\n\n
\n

Handling Contract Objects

\nThe variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address. You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';, or use web3.js directly (just like in the example source code)\n
\n\n

store.js

\n\n
import { createStore } from 'redux';\nimport {myReducer} from './reducer';\n\nexport default store = createStore(myReducer);\n
\n\n\n\n

reducer.js

\n\n
import { MY_ACTION } from "./constants";\n\nconst initialState = { \n  data: {}\n};\n\nexport const myReducer = (state = initialState, action) => {\n  switch (action.type) {\n    case MY_ACTION:\n      return { data: action.eventData };\n    default:\n      return state;\n  }\n};\n
\n\n\n\n

constants.js

\n\n
export const MY_ACTION = 'MY_ACTION';\n
\n\n\n\n

actions.js

\n\n
import {MY_ACTION} from './constants.js';\n\nexport const myAction = eventData => ({type: MY_ACTION, eventData});\n
\n\n\n\n
\n

Using React and Redux

\nA practical example can also be found in examples/react-redux.\n
"},{"_content":"# redux-observable\n\n[redux-observables](https://redux-observable.js.org/) can be used to manage side effects via `Epics` (their core primitive to receive and create stream of actions). **Subspace** can be configured inside these epics. \n\nIt's recommended to compose these epics by using [mergeMap](https://www.learnrxjs.io/operators/transformation/mergemap.html) or [switchMap](https://www.learnrxjs.io/operators/transformation/switchmap.html) operators.\n\nHere's an example on how to use **Subspace** to subscribe to an Event when the action `SOME_ACTION` is dispatched, and then it will trigger `myAction` when the observable emits a value.\n\n```js\n// ...\n\nconst myEpic = action$ =>\n action$.pipe(\n ofType(\"SOME_ACTION\"), // Execute when the action type is 'INIT'\n switchMap(action =>\n subspace\n .trackEvent(MyContract, \"MyEventName\", { filter: {}, fromBlock: 1})\n .pipe(\n map(myAction) // Trigger redux action: MY_ACTION with the eventData\n )\n )\n );\n\n// ...\n```\n\n
\nAn example is available in Github\n
\n\n#### Further read\n- [Epics](https://redux-observable.js.org/docs/basics/Epics.html)\n\n","source":"redux-observable.md","raw":"# redux-observable\n\n[redux-observables](https://redux-observable.js.org/) can be used to manage side effects via `Epics` (their core primitive to receive and create stream of actions). **Subspace** can be configured inside these epics. \n\nIt's recommended to compose these epics by using [mergeMap](https://www.learnrxjs.io/operators/transformation/mergemap.html) or [switchMap](https://www.learnrxjs.io/operators/transformation/switchmap.html) operators.\n\nHere's an example on how to use **Subspace** to subscribe to an Event when the action `SOME_ACTION` is dispatched, and then it will trigger `myAction` when the observable emits a value.\n\n```js\n// ...\n\nconst myEpic = action$ =>\n action$.pipe(\n ofType(\"SOME_ACTION\"), // Execute when the action type is 'INIT'\n switchMap(action =>\n subspace\n .trackEvent(MyContract, \"MyEventName\", { filter: {}, fromBlock: 1})\n .pipe(\n map(myAction) // Trigger redux action: MY_ACTION with the eventData\n )\n )\n );\n\n// ...\n```\n\n
\nAn example is available in Github\n
\n\n#### Further read\n- [Epics](https://redux-observable.js.org/docs/basics/Epics.html)\n\n","date":"2020-03-20T17:27:19.448Z","updated":"2020-03-20T17:27:19.448Z","path":"redux-observable.html","_id":"ck7z3hcl8000a5cbn6njw8eta","title":"","comments":1,"layout":"page","content":"

redux-observable

redux-observables can be used to manage side effects via Epics (their core primitive to receive and create stream of actions). Subspace can be configured inside these epics.

\n

It’s recommended to compose these epics by using mergeMap or switchMap operators.

\n

Here’s an example on how to use Subspace to subscribe to an Event when the action SOME_ACTION is dispatched, and then it will trigger myAction when the observable emits a value.

\n\n\n
// ...\n\nconst myEpic = action$ =>\n  action$.pipe(\n    ofType("SOME_ACTION"),  // Execute when the action type is 'INIT'\n    switchMap(action =>\n      subspace\n        .trackEvent(MyContract, "MyEventName", { filter: {}, fromBlock: 1})\n        .pipe(\n          map(myAction) // Trigger redux action: MY_ACTION with the eventData\n        )\n    )\n  );\n\n// ...\n
\n\n\n\n
\nAn example is available in Github\n
\n\n

Further read

\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

redux-observable

redux-observables can be used to manage side effects via Epics (their core primitive to receive and create stream of actions). Subspace can be configured inside these epics.

\n

It’s recommended to compose these epics by using mergeMap or switchMap operators.

\n

Here’s an example on how to use Subspace to subscribe to an Event when the action SOME_ACTION is dispatched, and then it will trigger myAction when the observable emits a value.

\n\n\n
// ...\n\nconst myEpic = action$ =>\n  action$.pipe(\n    ofType("SOME_ACTION"),  // Execute when the action type is 'INIT'\n    switchMap(action =>\n      subspace\n        .trackEvent(MyContract, "MyEventName", { filter: {}, fromBlock: 1})\n        .pipe(\n          map(myAction) // Trigger redux action: MY_ACTION with the eventData\n        )\n    )\n  );\n\n// ...\n
\n\n\n\n
\nAn example is available in Github\n
\n\n

Further read

\n"},{"_content":"# Creating a reactive ÐApp with React and Subspace\n\nSee example DApp at [https://github.com/embark-framework/subspace/tree/master/examples/react-example1](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n\n","source":"tutorial.md","raw":"# Creating a reactive ÐApp with React and Subspace\n\nSee example DApp at [https://github.com/embark-framework/subspace/tree/master/examples/react-example1](https://github.com/embark-framework/subspace/tree/master/examples/react-example1)\n\n","date":"2020-03-20T17:03:03.488Z","updated":"2020-03-09T15:25:14.948Z","path":"tutorial.html","_id":"ck7z3hcl8000b5cbn9b5ccrit","title":"","comments":1,"layout":"page","content":"

Creating a reactive ÐApp with React and Subspace

See example DApp at https://github.com/embark-framework/subspace/tree/master/examples/react-example1

\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

Creating a reactive ÐApp with React and Subspace

See example DApp at https://github.com/embark-framework/subspace/tree/master/examples/react-example1

\n"},{"home":true,"heroImage":"/assets/img/logo.svg","heroText":" ","actionText":"Get Started","actionLink":"/getting-started/","footer":"MIT Licensed | Subspace is part of the Status Network","features":[{"title":"Automatic Syncing","details":"Subspace takes care of syncing under the hood, syncing exactly what you need when you need it. It saves the state to a local database ensuring the DApp always syncs from the last known point even after reloading the DApp."},{"title":"Reactive","details":"Subspace embraces reactive programming with RxJS. It provides methods to track and subscribe to events, contract state & balances, and react to changes via observables."},{"title":"Framework Agnostic","details":"Subspace is framework agnostic and integrates well with your favourite frameworks, from React to Angular. It works in the browser and in nodejs."}],"_content":"\n---\n\n\n","source":"readme.md","raw":"---\nhome: true\nheroImage: /assets/img/logo.svg\nheroText: \" \"\nactionText: Get Started\nactionLink: /getting-started/\nfooter: MIT Licensed | Subspace is part of the Status Network \nfeatures:\n- title: Automatic Syncing\n details: Subspace takes care of syncing under the hood, syncing exactly what you need when you need it. It saves the state to a local database ensuring the DApp always syncs from the last known point even after reloading the DApp.\n- title: Reactive\n details: Subspace embraces reactive programming with RxJS. It provides methods to track and subscribe to events, contract state & balances, and react to changes via observables.\n- title: Framework Agnostic\n details: Subspace is framework agnostic and integrates well with your favourite frameworks, from React to Angular. It works in the browser and in nodejs.\n\n---\n\n---\n\n\n","date":"2020-03-20T17:03:01.692Z","updated":"2020-03-09T15:25:14.948Z","path":"readme.html","_id":"ck7z3hcl9000c5cbnenkva87k","title":"","comments":1,"layout":"page","content":"
\n\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"
\n\n"},{"_content":"# Vue\nVue provides the official npm package `vue-rx` that provides RxJS integration, which simplifies the use of Subspace with Vue.js\n\n### Example\n\n
\nThis example is available in Github\n
\n\n\n#### MyComponent.vue\n```js\n\n\n\n```\n\n#### App.vue\n```js\n\n\n\n```\n\n\n\n#### Further read\n- [vue-rx](https://www.npmjs.com/package/vue-rx)\n","source":"vue.md","raw":"# Vue\nVue provides the official npm package `vue-rx` that provides RxJS integration, which simplifies the use of Subspace with Vue.js\n\n### Example\n\n
\nThis example is available in Github\n
\n\n\n#### MyComponent.vue\n```js\n\n\n\n```\n\n#### App.vue\n```js\n\n\n\n```\n\n\n\n#### Further read\n- [vue-rx](https://www.npmjs.com/package/vue-rx)\n","date":"2020-03-20T17:22:12.780Z","updated":"2020-03-20T17:22:12.780Z","path":"vue.html","_id":"ck7z3hcla000d5cbnbcbx0pk7","title":"","comments":1,"layout":"page","content":"

Vue

Vue provides the official npm package vue-rx that provides RxJS integration, which simplifies the use of Subspace with Vue.js

\n

Example

\nThis example is available in Github\n
\n\n\n

MyComponent.vue

\n\n
<template>\n  <ul v-if="!!eventData$">\n    <li><b>someValue: </b> {{eventData$.someValue}}</li>\n    <li><b>anotherValue: </b> {{eventData$.anotherValue}}</li>\n  </ul>\n</template>\n\n<script>\nexport default {\n  name: 'MyComponent',\n  props: {\n    eventData: Object\n  },\n  subscriptions() { // provide Rx observables\n    return {\n      eventData$: this.eventData\n    }\n  }\n}\n</script>\n
\n\n\n\n

App.vue

\n\n
<template>\n  <div id="app">\n    <button v-on:click="createTrx">Create a Transaction</button>\n    <MyComponent v-bind:event-data="myEventObservable$" v-if="!!myEventObservable$" />\n  </div>\n</template>\n\n<script>\nimport MyComponent from './components/MyComponent.vue';\nimport Subspace from "@embarklabs/subspace";\n\nexport default {\n  name: 'app',\n  data: function(){\n    return {\n      myEventObservable$: null,\n      MyContractInstance: null\n    };\n  },\n  created: async function(){\n    this.MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n    const subspace = new Subspace(web3);\n    await subspace.init();\n\n    this.myEventObservable$ = subspace.trackEvent(this.MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });\n  }, \n  methods: {\n    createTrx: function(){\n      this.MyContractInstance.methods\n        .myFunction()\n        .send({ from: web3.eth.defaultAccount });\n    }\n  },\n  components: {\n    MyComponent\n  }\n}\n</script>\n
\n\n\n\n

Further read

\n","site":{"data":{"sidebar":{"docs":[{"title":"How it works","path":"how-it-works.html"},{"title":"Getting Started","path":"getting-started.html","children":[{"title":"Installation","path":"#Installation"},{"title":"Importing the library","path":"#Importing-the-library"},{"title":"Connecting to a web3 provider","path":"#Connecting-to-a-web3-provider"},{"title":"Enhancing your contract objects","path":"#Enhancing-your-contract-objects"},{"title":"Reacting to data","path":"#Reacting-to-data"},{"title":"Tracking state","path":"#Tracking-state"},{"title":"Tracking events","path":"#Tracking-events"},{"title":"Tracking balances","path":"#Tracking-balances"},{"title":"Getting block data, gas prices and block time","path":"#Getting-block-data-gas-prices-and-block-time"},{"title":"Subscriptions","path":"#Subscriptions"},{"title":"Cleanup","path":"#Cleanup"}]},{"title":"Integrations","path":"empty","children":[{"title":"Overview","path":"integrations-overview.html"},{"title":"React","path":"react.html"},{"title":"Vue","path":"vue.html"},{"title":"Redux","path":"empty","children":[{"title":"redux","path":"redux.html"},{"title":"redux-observable","path":"redux-observable.html"}]},{"title":"reactive-graphql","path":"reactive-graphql.html"},{"title":"apollo-client","path":"apollo-client.html"}]},{"title":"Tutorial","path":"tutorial.html"},{"title":"API","path":"api.html","children":[{"title":"General","path":"#general"},{"title":"Contract methods","path":"#Contract-methods"},{"title":"Blocks, gas price and block time","path":"#Blocks-gas-price-and-block-time"},{"title":"Low level API for data tracking","path":"#Low-level-API-for-data-tracking"}]}]}}},"excerpt":"","more":"

Vue

Vue provides the official npm package vue-rx that provides RxJS integration, which simplifies the use of Subspace with Vue.js

\n

Example

\nThis example is available in Github\n
\n\n\n

MyComponent.vue

\n\n
<template>\n  <ul v-if="!!eventData$">\n    <li><b>someValue: </b> {{eventData$.someValue}}</li>\n    <li><b>anotherValue: </b> {{eventData$.anotherValue}}</li>\n  </ul>\n</template>\n\n<script>\nexport default {\n  name: 'MyComponent',\n  props: {\n    eventData: Object\n  },\n  subscriptions() { // provide Rx observables\n    return {\n      eventData$: this.eventData\n    }\n  }\n}\n</script>\n
\n\n\n\n

App.vue

\n\n
<template>\n  <div id="app">\n    <button v-on:click="createTrx">Create a Transaction</button>\n    <MyComponent v-bind:event-data="myEventObservable$" v-if="!!myEventObservable$" />\n  </div>\n</template>\n\n<script>\nimport MyComponent from './components/MyComponent.vue';\nimport Subspace from "@embarklabs/subspace";\n\nexport default {\n  name: 'app',\n  data: function(){\n    return {\n      myEventObservable$: null,\n      MyContractInstance: null\n    };\n  },\n  created: async function(){\n    this.MyContractInstance = ...; // TODO: obtain a web3.eth.contract instance\n\n    const subspace = new Subspace(web3);\n    await subspace.init();\n\n    this.myEventObservable$ = subspace.trackEvent(this.MyContractInstance, "MyEvent", {filter: {}, fromBlock: 1 });\n  }, \n  methods: {\n    createTrx: function(){\n      this.MyContractInstance.methods\n        .myFunction()\n        .send({ from: web3.eth.defaultAccount });\n    }\n  },\n  components: {\n    MyComponent\n  }\n}\n</script>\n
\n\n\n\n

Further read

\n"}],"Post":[{"title":"Hello World","_content":"Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues).\n\n## Quick Start\n\n### Create a new post\n\n``` bash\n$ hexo new \"My New Post\"\n```\n\nMore info: [Writing](https://hexo.io/docs/writing.html)\n\n### Run server\n\n``` bash\n$ hexo server\n```\n\nMore info: [Server](https://hexo.io/docs/server.html)\n\n### Generate static files\n\n``` bash\n$ hexo generate\n```\n\nMore info: [Generating](https://hexo.io/docs/generating.html)\n\n### Deploy to remote sites\n\n``` bash\n$ hexo deploy\n```\n\nMore info: [Deployment](https://hexo.io/docs/one-command-deployment.html)\n","source":"_posts/hello-world.md","raw":"---\ntitle: Hello World\n---\nWelcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues).\n\n## Quick Start\n\n### Create a new post\n\n``` bash\n$ hexo new \"My New Post\"\n```\n\nMore info: [Writing](https://hexo.io/docs/writing.html)\n\n### Run server\n\n``` bash\n$ hexo server\n```\n\nMore info: [Server](https://hexo.io/docs/server.html)\n\n### Generate static files\n\n``` bash\n$ hexo generate\n```\n\nMore info: [Generating](https://hexo.io/docs/generating.html)\n\n### Deploy to remote sites\n\n``` bash\n$ hexo deploy\n```\n\nMore info: [Deployment](https://hexo.io/docs/one-command-deployment.html)\n","slug":"hello-world","published":1,"date":"2020-03-19T18:28:50.730Z","updated":"2020-03-19T18:28:50.730Z","comments":1,"layout":"post","photos":[],"link":"","_id":"ck7z3ielc00008pbn2mijc29u","content":"

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

\n

Quick Start

Create a new post

\n\n
$ hexo new "My New Post"\n
\n\n\n\n

More info: Writing

\n

Run server

\n\n
$ hexo server\n
\n\n\n\n

More info: Server

\n

Generate static files

\n\n
$ hexo generate\n
\n\n\n\n

More info: Generating

\n

Deploy to remote sites

\n\n
$ hexo deploy\n
\n\n\n\n

More info: Deployment

\n","site":{"data":{}},"excerpt":"","more":"

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

\n

Quick Start

Create a new post

\n\n
$ hexo new "My New Post"\n
\n\n\n\n

More info: Writing

\n

Run server

\n\n
$ hexo server\n
\n\n\n\n

More info: Server

\n

Generate static files

\n\n
$ hexo generate\n
\n\n\n\n

More info: Generating

\n

Deploy to remote sites

\n\n
$ hexo deploy\n
\n\n\n\n

More info: Deployment

\n"}],"PostAsset":[],"PostCategory":[],"PostTag":[],"Tag":[]}} \ No newline at end of file diff --git a/packages/site/package-lock.json b/packages/site/package-lock.json deleted file mode 100644 index 8d8ad90..0000000 --- a/packages/site/package-lock.json +++ /dev/null @@ -1,5204 +0,0 @@ -{ - "name": "subspace-docs", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" - }, - "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - } - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "autoprefixer": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", - "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", - "requires": { - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001020", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.26", - "postcss-value-parser": "^4.0.2" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-decorators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=" - }, - "babel-plugin-transform-decorators-legacy": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz", - "integrity": "sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA==", - "requires": { - "babel-plugin-syntax-decorators": "^6.1.18", - "babel-runtime": "^6.2.0", - "babel-template": "^6.3.0" - } - }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "browserslist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", - "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", - "requires": { - "caniuse-lite": "^1.0.30001030", - "electron-to-chromium": "^1.3.363", - "node-releases": "^1.1.50" - } - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "camel-case": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", - "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", - "requires": { - "pascal-case": "^3.1.1", - "tslib": "^1.10.0" - } - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001033", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001033.tgz", - "integrity": "sha512-8Ibzxee6ibc5q88cM1usPsMpJOG5CTq0s/dKOmlekPbDGKt+UrnOOTPSjQz3kVo6yL7N4SB5xd+FGLHQmbzh6A==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" - }, - "dependencies": { - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "optional": true - }, - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "readdirp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", - "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", - "requires": { - "picomatch": "^2.0.7" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clipboard": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz", - "integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=", - "optional": true, - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "command-exists": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", - "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "core-decorators": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/core-decorators/-/core-decorators-0.11.2.tgz", - "integrity": "sha1-GyQzFZQa598a8938tX3+6mPIsXE=" - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=" - }, - "cuid": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/cuid/-/cuid-2.1.8.tgz", - "integrity": "sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==" - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "requires": { - "array-find-index": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "dir-resolve": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/dir-resolve/-/dir-resolve-1.0.2.tgz", - "integrity": "sha1-c5Rv3+RmrzHBjddWUunCwwDgZRw=" - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "domhandler": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.0.0.tgz", - "integrity": "sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==", - "requires": { - "domelementtype": "^2.0.1" - } - }, - "domutils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.0.0.tgz", - "integrity": "sha512-n5SelJ1axbO636c2yUtOGia/IcJtVtlhQbFiVDBZHKV5ReJO1ViX7sFEemtuyoAnBxk5meNSYgA8V4s0271efg==", - "requires": { - "dom-serializer": "^0.2.1", - "domelementtype": "^2.0.1", - "domhandler": "^3.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==" - }, - "electron-to-chromium": { - "version": "1.3.375", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.375.tgz", - "integrity": "sha512-zmaFnYVBtfpF8bGRYxgPeVAlXB7N3On8rjBE2ROc6wOpTPpzRWaiHo6KkbJMvlH07CH33uks/TEb6kuMMn8q6A==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "optional": true - } - } - }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "requires": { - "globule": "^1.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "requires": { - "is-glob": "^2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "globule": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", - "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.12", - "minimatch": "~3.0.2" - } - }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "optional": true, - "requires": { - "delegate": "^3.1.2" - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hexo": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hexo/-/hexo-4.2.0.tgz", - "integrity": "sha512-j2Kzgx/eWF0IgSfUEsAAhr0mDaaqR3E1MTus0/Vrs+JpQdMiSlqSbudPf2S9O4FHi5CAzDCuzToGlg2kgoQxcA==", - "requires": { - "abbrev": "^1.1.1", - "archy": "^1.0.0", - "bluebird": "^3.5.2", - "chalk": "^3.0.0", - "hexo-cli": "^3.0.0", - "hexo-front-matter": "^1.0.0", - "hexo-fs": "^2.0.0", - "hexo-i18n": "^1.0.0", - "hexo-log": "^1.0.0", - "hexo-util": "^1.8.0", - "js-yaml": "^3.12.0", - "lodash": "^4.17.11", - "micromatch": "^4.0.2", - "moment": "^2.22.2", - "moment-timezone": "^0.5.21", - "nunjucks": "^3.1.3", - "pretty-hrtime": "^1.0.3", - "resolve": "^1.8.1", - "strip-ansi": "^6.0.0", - "strip-indent": "^3.0.0", - "swig-extras": "0.0.1", - "swig-templates": "^2.0.3", - "text-table": "^0.2.0", - "tildify": "^2.0.0", - "titlecase": "^1.1.2", - "warehouse": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "dependencies": { - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - } - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "hexo-cli": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hexo-cli/-/hexo-cli-3.1.0.tgz", - "integrity": "sha512-Rc2gX2DlsALaFBbfk1XYx2XmeVAX+C7Dxc7UwETZOcu3cbGsf2DpwYTfKQumW3jagi1icA4KgW9aSRPPZZj/zg==", - "requires": { - "abbrev": "^1.1.1", - "acorn": "^7.0.0", - "bluebird": "^3.5.5", - "chalk": "^2.4.2", - "command-exists": "^1.2.8", - "hexo-fs": "^2.0.0", - "hexo-log": "^1.0.0", - "hexo-util": "^1.4.0", - "minimist": "^1.2.0", - "resolve": "^1.11.0", - "tildify": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "hexo-autoprefixer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hexo-autoprefixer/-/hexo-autoprefixer-2.0.0.tgz", - "integrity": "sha512-qiAcD3K8D5PeyPh357CG6Cn+9GmCBNDRbD2ghnTZzfOo+HFLlLWXyPZfqaUZKKdP2iksmj+vYjE5oFsQizkWYw==", - "requires": { - "autoprefixer": "^9.4.3", - "minimatch": "^3.0.2", - "postcss": "^7.0.7" - } - }, - "hexo-bunyan": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hexo-bunyan/-/hexo-bunyan-2.0.0.tgz", - "integrity": "sha512-5XHYu/yJOgPFTC0AaEgFtPPaBJU4jC7R10tITJwTRJk7K93rgSpRV8jF3e0PPlPwXd4FphTawjljH5R8LjmtpQ==", - "requires": { - "moment": "^2.10.6", - "mv": "~2", - "safe-json-stringify": "~1" - } - }, - "hexo-front-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-front-matter/-/hexo-front-matter-1.0.0.tgz", - "integrity": "sha512-Hn8IIzgWWnxYTekrjnA0rxwWMoQHifyrxKMqVibmFaRKf4AQ2V6Xo13Jiso6CDwYfS+OdA41QS5DG1Y+QXA5gw==", - "requires": { - "js-yaml": "^3.13.1" - } - }, - "hexo-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-2.0.0.tgz", - "integrity": "sha512-mtwjfh5IZMXVCoITtoV+LfWbrD7xCWyv8OTIrOmwUW4JR+7EEvuwqu+QDztt4RS0azxUuc1sKVK68Mxfp2AoYQ==", - "requires": { - "bluebird": "^3.5.1", - "chokidar": "^3.0.0", - "escape-string-regexp": "^2.0.0", - "graceful-fs": "^4.1.11" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" - } - } - }, - "hexo-generator-archive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-generator-archive/-/hexo-generator-archive-1.0.0.tgz", - "integrity": "sha512-24TeanDGpMBUIq37DHpSESQbeN6ssZ06edsGSI76tN4Yit50TgsgzP5g5DSu0yJk0jUtHJntysWE8NYAlFXibA==", - "requires": { - "hexo-pagination": "1.0.0" - } - }, - "hexo-generator-category": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-generator-category/-/hexo-generator-category-1.0.0.tgz", - "integrity": "sha512-kmtwT1SHYL2ismbGnYQXNtqLFSeTdtHNbJIqno3LKROpCK8ybST5QVXF1bZI9LkFcXV/H8ilt8gfg4/dNNcQQQ==", - "requires": { - "hexo-pagination": "1.0.0" - } - }, - "hexo-generator-i18n": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/hexo-generator-i18n/-/hexo-generator-i18n-0.0.7.tgz", - "integrity": "sha1-qzwZi9gKBxABGvwucME8W57m7Aw=", - "requires": { - "lodash": "^4.15.0" - } - }, - "hexo-generator-index": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-generator-index/-/hexo-generator-index-1.0.0.tgz", - "integrity": "sha512-L25MdZ7e5ar/F8lIW+zBNNlA4f5A8CBUOYi1IQZCgL3wPVW+AWn66RSM5UVBAbiw5yxDeTHdk0sJYXbhSBaOFQ==", - "requires": { - "hexo-pagination": "1.0.0" - } - }, - "hexo-generator-tag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-generator-tag/-/hexo-generator-tag-1.0.0.tgz", - "integrity": "sha512-JDoB2T1EncRlyGSjuAhkGxRfKkN8tq0i8tFlk9I4q2L6iYxPaUnFenhji0oxufTADC16/IchuPjmMk//dt8Msg==", - "requires": { - "hexo-pagination": "1.0.0" - } - }, - "hexo-i18n": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-i18n/-/hexo-i18n-1.0.0.tgz", - "integrity": "sha512-yw90JHr7ybUHN/QOkpHmlWJj1luVk5/v8CUU5NRA0n4TFp6av8NT7ujZ10GDawgnQEdMHnN5PUfAbNIVGR6axg==", - "requires": { - "sprintf-js": "^1.0.3" - } - }, - "hexo-inject": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-inject/-/hexo-inject-1.0.0.tgz", - "integrity": "sha1-pTVXVgUdWrJ5yCtzfacrEzx+Ju0=", - "requires": { - "babel-plugin-transform-decorators-legacy": "^1.3.4", - "babel-polyfill": "^6.7.2", - "bluebird": "^3.3.4", - "core-decorators": "^0.11.0", - "underscore": "^1.8.3" - } - }, - "hexo-log": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-log/-/hexo-log-1.0.0.tgz", - "integrity": "sha512-XlPzRtnsdrUfTSkLJPACQgWByybB56E79H8xIjGWj0GL+J/VqENsgc+GER0ytFwrP/6YKCerXdaUWOYMcv6aiA==", - "requires": { - "chalk": "^2.4.1", - "hexo-bunyan": "^2.0.0" - } - }, - "hexo-pagination": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-pagination/-/hexo-pagination-1.0.0.tgz", - "integrity": "sha512-miEVFgxchPr2qNWxw0JWpJ9R/Yaf7HjHBZVjvCCcqfbsLyYtCvIfJDxcEwz1sDOC/fLzYPqNnhUI73uNxBHRSA==" - }, - "hexo-prism-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hexo-prism-plugin/-/hexo-prism-plugin-2.3.0.tgz", - "integrity": "sha512-jn8aSVwo8odrZpf2qgETiZeO6cR7D7uDvljHD+CQqWOP97e8LvYAwaFlEvTgJwwKSERZbI5RlwtTOX7CDjz1Mw==", - "requires": { - "dir-resolve": "^1.0.2", - "hexo-fs": "^0.2.1", - "node-prismjs": "^0.1.0", - "prism-themes": "^1.0.0", - "prismjs": "^1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - }, - "dependencies": { - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "requires": { - "fill-range": "^2.1.0" - } - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" - } - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "requires": { - "is-posix-bracket": "^0.1.0" - }, - "dependencies": { - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "requires": { - "is-extglob": "^1.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" - } - } - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "hexo-fs": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-0.2.3.tgz", - "integrity": "sha512-rLB1rMVUW3csAljvJgHfyjemL0BrmcUZfBf9hJe6S0pA53igFa3ON0PFwomvoLs1Wdmjs9Awnw9Tru4PjWFSlQ==", - "requires": { - "bluebird": "^3.4.0", - "chokidar": "^1.5.2", - "escape-string-regexp": "^1.0.5", - "graceful-fs": "^4.1.4" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "requires": { - "is-extglob": "^1.0.0" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "requires": { - "is-equal-shallow": "^0.1.3" - } - } - } - } - } - }, - "hexo-prism-plus": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hexo-prism-plus/-/hexo-prism-plus-1.1.0.tgz", - "integrity": "sha512-lkDJRZDVN3iNpYtuwrI+JFLj3rSa4PeMwz1OlVfUOkY6CyjD/D3dGtW7cTpcxYejr3/JWjusIqWVnUTLpKr4Yw==", - "requires": { - "hexo-fs": "^1.0.0", - "hexo-inject": "^1.0.0", - "hexo-util": "^0.6.3", - "lodash": "^4.17.11" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "hexo-fs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-1.0.2.tgz", - "integrity": "sha512-cbDnYuk6IndW/Fr2RcfZsZXE5wlG6tFoeBgZsHY230sSYalvX4JBPOUrE8As7Agysl+NGMthtr/Drtuliy5foQ==", - "requires": { - "bluebird": "^3.5.1", - "chokidar": "^2.0.4", - "escape-string-regexp": "^1.0.5", - "graceful-fs": "^4.1.11" - } - }, - "hexo-util": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/hexo-util/-/hexo-util-0.6.3.tgz", - "integrity": "sha512-zPxaqCWZz3/25SAB4FlrRtWktJ+Pr+vBiv/nyHpXKgXPt1m70liViKlRwWLqDmRjJ72x6/k4qCEeXHajvcGHUw==", - "requires": { - "bluebird": "^3.4.0", - "camel-case": "^3.0.0", - "cross-spawn": "^4.0.0", - "highlight.js": "^9.4.0", - "html-entities": "^1.2.0", - "striptags": "^2.1.1" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "striptags": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/striptags/-/striptags-2.2.1.tgz", - "integrity": "sha1-TEULcI1BuL85zyTEn/I0/Gqr/TI=" - } - } - }, - "hexo-renderer-ejs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-renderer-ejs/-/hexo-renderer-ejs-1.0.0.tgz", - "integrity": "sha512-O925i69FG4NYO62oWORcPhRZZX0sPx1SXGKUS5DaR/lzajyiXH5i2sqnkj0ya0rNLXIy/D7Xmt7WbFyuQx/kKQ==", - "requires": { - "ejs": "^2.6.1" - } - }, - "hexo-renderer-marked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hexo-renderer-marked/-/hexo-renderer-marked-2.0.0.tgz", - "integrity": "sha512-+LMjgPkJSUAOlWYHJnBXxUHwGqemGNlK/I+JNO4zA5rEHWNWZ9wNAZKd5g0lEVdMAZzAV54gCylXGURgMO4IAw==", - "requires": { - "hexo-util": "1.0.0", - "marked": "^0.7.0", - "strip-indent": "^3.0.0" - }, - "dependencies": { - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "hexo-util": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-util/-/hexo-util-1.0.0.tgz", - "integrity": "sha512-oV1/Y7ablc7e3d2kFFvQ/Ypi/BfL/uDSc1oNaMcxqr/UOH8F0QkHZ0Dmv+yLrEpFNYrrhBA0uavo3e+EqHNjnQ==", - "requires": { - "bluebird": "^3.5.2", - "camel-case": "^3.0.0", - "cross-spawn": "^6.0.5", - "highlight.js": "^9.13.1", - "html-entities": "^1.2.1", - "striptags": "^3.1.1" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - } - } - }, - "hexo-renderer-sass": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/hexo-renderer-sass/-/hexo-renderer-sass-0.4.0.tgz", - "integrity": "sha512-goQ/r8J/2s5XnIp+dSDwWgaxHl6h/VVEsp95Jr/+sYqFfXHXDIC4evC+V1to9ezfQwOS//ZZFQptTZIKTuh8Lg==", - "requires": { - "node-sass": "^4.5.3" - } - }, - "hexo-renderer-stylus": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hexo-renderer-stylus/-/hexo-renderer-stylus-1.1.0.tgz", - "integrity": "sha512-aXfMuro2aQOvpM5pyPEModAPvqYi73VN4t37vGMQCbT0QTmw8YohEmUpO/G/1k6j88ong6344v+A0xrpUGQRnQ==", - "requires": { - "nib": "^1.1.2", - "stylus": "^0.54.5" - } - }, - "hexo-server": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexo-server/-/hexo-server-1.0.0.tgz", - "integrity": "sha512-eSY+a5oiGCG/3T6FrdrNRBkttMLJkM+oitY6ZMFowjcBiG2VNEhQmfWUDOykfvApZs4wPYBb//uXD/58tfe3mA==", - "requires": { - "bluebird": "^3.5.5", - "chalk": "^2.4.2", - "compression": "^1.7.4", - "connect": "^3.7.0", - "mime": "^2.4.3", - "morgan": "^1.9.1", - "open": "^6.3.0", - "serve-static": "^1.14.1" - } - }, - "hexo-util": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/hexo-util/-/hexo-util-1.8.1.tgz", - "integrity": "sha512-gzZmcdpYjG168xunWaxFAtNhBA7il6jeaSLxL2Mj7+XRg86RqZGCgHK00gI35aQvaUPKO3XLmWQl8QyN61fa5w==", - "requires": { - "bluebird": "^3.5.2", - "camel-case": "^4.0.0", - "cross-spawn": "^7.0.0", - "deepmerge": "^4.2.2", - "highlight.js": "^9.13.1", - "htmlparser2": "^4.0.0", - "punycode.js": "^2.1.0", - "striptags": "^3.1.1" - } - }, - "highlight.js": { - "version": "9.18.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz", - "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==" - }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" - }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" - }, - "htmlparser2": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", - "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^3.0.0", - "domutils": "^2.0.0", - "entities": "^2.0.0" - } - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "in-publish": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", - "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=" - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "requires": { - "repeating": "^2.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" - }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-base64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz", - "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz", - "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=", - "requires": { - "nopt": "~2.1.1" - }, - "dependencies": { - "nopt": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz", - "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=", - "requires": { - "abbrev": "1" - } - } - } - }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" - }, - "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" - }, - "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", - "requires": { - "mime-db": "1.43.0" - } - }, - "min-indent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", - "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "moment-timezone": { - "version": "0.5.28", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.28.tgz", - "integrity": "sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw==", - "requires": { - "moment": ">= 2.9.0" - } - }, - "morgan": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", - "requires": { - "basic-auth": "~2.0.0", - "debug": "2.6.9", - "depd": "~1.1.2", - "on-finished": "~2.3.0", - "on-headers": "~1.0.1" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "optional": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "optional": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "optional": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "optional": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "nib": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/nib/-/nib-1.1.2.tgz", - "integrity": "sha1-amnt5AgblcDe+L4CSkyK4MLLtsc=", - "requires": { - "stylus": "0.54.5" - }, - "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "requires": { - "amdefine": ">=0.0.4" - } - }, - "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", - "requires": { - "css-parse": "1.7.x", - "debug": "*", - "glob": "7.0.x", - "mkdirp": "0.5.x", - "sax": "0.5.x", - "source-map": "0.1.x" - } - } - } - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-gyp": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" - } - } - }, - "node-prismjs": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/node-prismjs/-/node-prismjs-0.1.2.tgz", - "integrity": "sha512-WKb6ZbUlPWarzS8jR2UdIbV4lYpt6sOTkIx3u5Ldz55K1Zzs982KyF6aj1zjZbrrx/UGZSZ1e0j28lIzcm3ceg==", - "requires": { - "prismjs": "~1.6.0" - }, - "dependencies": { - "prismjs": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.6.0.tgz", - "integrity": "sha1-EY2V+3pm26InLjQ7NF9SNmWds2U=", - "requires": { - "clipboard": "^1.5.5" - } - } - } - }, - "node-releases": { - "version": "1.1.51", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.51.tgz", - "integrity": "sha512-1eQEs6HFYY1kMXQPOLzCf7HdjReErmvn85tZESMczdCNVWP3Y7URYLBAyYynuI7yef1zj4HN5q+oB2x67QU0lw==", - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "node-sass": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", - "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==", - "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.13.2", - "node-gyp": "^3.8.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "^2.2.4", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "nunjucks": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.0.tgz", - "integrity": "sha512-YS/qEQ6N7qCnUdm6EoYRBfJUdWNT0PpKbbRnogV2XyXbBm2STIP1O6yrdZHgwMVK7fIYUx7i8+yatEixnXSB1w==", - "requires": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "chokidar": "^2.0.0", - "yargs": "^3.32.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "optional": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "optional": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "optional": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "optional": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "optional": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - } - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascal-case": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz", - "integrity": "sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==", - "requires": { - "no-case": "^3.0.3", - "tslib": "^1.10.0" - }, - "dependencies": { - "lower-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", - "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", - "requires": { - "tslib": "^1.10.0" - } - }, - "no-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.3.tgz", - "integrity": "sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==", - "requires": { - "lower-case": "^2.0.1", - "tslib": "^1.10.0" - } - } - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-value-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==" - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" - }, - "prism-themes": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/prism-themes/-/prism-themes-1.3.0.tgz", - "integrity": "sha512-4hDQyNuBRyWVvwHeTH4yY5TIWrl6BHmhoh85kgfTFgwklGerWA3R2RFp7Sg0zPCnQS8SsloKsEIN3ao63KhiIw==" - }, - "prismjs": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.19.0.tgz", - "integrity": "sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw==", - "requires": { - "clipboard": "^2.0.0" - }, - "dependencies": { - "clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", - "optional": true, - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "punycode.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.1.0.tgz", - "integrity": "sha512-LvGUJ9QHiESLM4yn8JuJWicstRcJKRmP46psQw1HvCZ9puLFwYMKJWvkAkP3OHBVzNzZGx/D53EYJrIaKd9gZQ==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - }, - "dependencies": { - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "requires": { - "get-stdin": "^4.0.1" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "rfdc": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", - "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==" - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-json-stringify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", - "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", - "optional": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sass-graph": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", - "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", - "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^7.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - } - } - }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" - }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stdout-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", - "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", - "requires": { - "readable-stream": "^2.0.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "requires": { - "min-indent": "^1.0.0" - } - }, - "striptags": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.1.1.tgz", - "integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0=" - }, - "stylus": { - "version": "0.54.7", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", - "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", - "requires": { - "css-parse": "~2.0.0", - "debug": "~3.1.0", - "glob": "^7.1.3", - "mkdirp": "~0.5.x", - "safer-buffer": "^2.1.2", - "sax": "~1.2.4", - "semver": "^6.0.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "css-parse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", - "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "requires": { - "css": "^2.0.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "swig-extras": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/swig-extras/-/swig-extras-0.0.1.tgz", - "integrity": "sha1-tQP+3jcqucJMasaMr2VrzvGHIyg=", - "requires": { - "markdown": "~0.5.0" - } - }, - "swig-templates": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/swig-templates/-/swig-templates-2.0.3.tgz", - "integrity": "sha512-QojPTuZWdpznSZWZDB63/grsZuDwT/7geMeGlftbJXDoYBIZEnTcKvz4iwYDv3SwfPX9/B4RtGRSXNnm3S2wwg==", - "requires": { - "optimist": "~0.6", - "uglify-js": "2.6.0" - } - }, - "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tildify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==" - }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "optional": true - }, - "titlecase": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/titlecase/-/titlecase-1.1.3.tgz", - "integrity": "sha512-pQX4oiemzjBEELPqgK4WE+q0yhAqjp/yzusGtlSJsOuiDys0RQxggepYmo0BuegIDppYS3b3cpdegRwkpyN3hw==" - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" - }, - "true-case-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", - "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", - "requires": { - "glob": "^7.1.2" - } - }, - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "uglify-js": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.6.0.tgz", - "integrity": "sha1-JeqhzDVQ45QQzu+v0c+7a20V8AE=", - "requires": { - "async": "~0.2.6", - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=" - }, - "underscore": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", - "integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "warehouse": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/warehouse/-/warehouse-3.0.2.tgz", - "integrity": "sha512-NTaUFkDcRKFx477NflL3doMhnmPobpL+uF66s0ozAhjob+UCHcOzE77GvYR1sjyu+LR4SstPz3xGxYLOKQCvMg==", - "requires": { - "JSONStream": "^1.0.7", - "bluebird": "^3.2.2", - "cuid": "^2.1.4", - "graceful-fs": "^4.1.3", - "is-plain-object": "^3.0.0", - "rfdc": "^1.1.4" - }, - "dependencies": { - "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==" - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "requires": { - "camelcase": "^3.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - } - } - } - } -} diff --git a/packages/site/source/packages/docs/api.md b/packages/site/source/packages/docs/api.md index ff6c620..c3f0b8f 100644 --- a/packages/site/source/packages/docs/api.md +++ b/packages/site/source/packages/docs/api.md @@ -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) diff --git a/packages/site/source/packages/docs/apollo-client.md b/packages/site/source/packages/docs/apollo-client.md index 7221dbb..cbb6f2d 100644 --- a/packages/site/source/packages/docs/apollo-client.md +++ b/packages/site/source/packages/docs/apollo-client.md @@ -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)}) }); ```
-Using react-apollo -A practical example can also be found in `examples/react-apollo`. +

Using Apollo with Subspace

+A practical example can also be found in examples/react-apollo.
\ No newline at end of file diff --git a/packages/site/source/packages/docs/getting-started.md b/packages/site/source/packages/docs/getting-started.md index 01d65ab..96d5778 100644 --- a/packages/site/source/packages/docs/getting-started.md +++ b/packages/site/source/packages/docs/getting-started.md @@ -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.
-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: +

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: - Compositional: Observables can be composed with higher-order combinators. - Lazy: Observables do not start emitting data until an observer has subscribed.
@@ -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(); ``` -
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). +
+

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).
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); ```
-Balances are returned as a string containing the value in *wei*. +Balances are returned as a string containing the value in wei.
@@ -217,7 +217,7 @@ If **Subspace** is not needed anymore, you need can invoke `close()` to dispose subspace.close(); ```
-What about subscriptions created with our observables? -Any subscription created via the tracking methods must be unsubscribed manually (in the current version). +

What about subscriptions created with our observables?

+close() 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 subsink can be used to clear all the observables' subscriptions at once.
diff --git a/packages/site/source/packages/docs/react.md b/packages/site/source/packages/docs/react.md index 839e7a2..4435a84 100644 --- a/packages/site/source/packages/docs/react.md +++ b/packages/site/source/packages/docs/react.md @@ -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 `` 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( + + + , + 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 `` 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 ``. + +```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 - -
-This example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/react-example1) -
- - -#### 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

No data

; } - return

{eventData.someReturnedValue}

+ return

Value: {eventData.someReturnValue}

}; -// 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 ; - } +const SomeOtherComponent = () => { + const myObservable$ = MyContractInstance.events.MyEvent.track({fromBlock: 1}); + return ; } - -export default App; ``` +
-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)) +

Handling Contract Objects

+The variable MyContractInstance is a web3.eth.Contract object pointing to a deployed contract address that has been enhanced with subspace.contract(). You can use a DApp framework like Embark to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';.
-#### index.js -```js -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; -ReactDOM.render(, document.getElementById('root')); -``` - - -```js -import { observe } from "@embarklabs/subspace/react"; - -const ProductComponent = ({ maxRating, minRating, averageRating }) => { - return
    -
  • minimum rating: {minRating}
  • -
  • maximum rating: {maxRating}
  • -
  • average rating: {averageRating}
  • -
; -}; - -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( - , - document.getElementById('hello-example') -); -``` +
+To learn more about how to use subspace-react, there are full working examples available in Github +
diff --git a/packages/site/source/packages/docs/reactive-graphql.md b/packages/site/source/packages/docs/reactive-graphql.md index 18e285f..620739b 100644 --- a/packages/site/source/packages/docs/reactive-graphql.md +++ b/packages/site/source/packages/docs/reactive-graphql.md @@ -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(); ```
-This example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/reactive-graphql) +This example is available in Github
\ No newline at end of file diff --git a/packages/site/source/packages/docs/redux-observable.md b/packages/site/source/packages/docs/redux-observable.md index dd57b41..8f1126a 100644 --- a/packages/site/source/packages/docs/redux-observable.md +++ b/packages/site/source/packages/docs/redux-observable.md @@ -25,7 +25,7 @@ const myEpic = action$ => ```
-An example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux-observable) +An example is available in Github
#### Further read diff --git a/packages/site/source/packages/docs/redux.md b/packages/site/source/packages/docs/redux.md index ed58723..da72052 100644 --- a/packages/site/source/packages/docs/redux.md +++ b/packages/site/source/packages/docs/redux.md @@ -6,7 +6,7 @@ Here's a simple example on how to setup **Subspace** to work with `redux`:
-This example is available in [Github](https://github.com/embarklabs/subspace/tree/master/examples/redux) +This example is available in Github
#### 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(); ``` -
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)) +
+

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 to easily import that contract instance: import { MyContract } from './embarkArtifacts/contracts';, or use web3.js directly (just like in the example source code)
#### store.js @@ -73,6 +74,6 @@ export const myAction = eventData => ({type: MY_ACTION, eventData}); ```
-Using React and Redux -A practical example can also be found in `examples/react-redux`. +

Using React and Redux

+A practical example can also be found in examples/react-redux.
\ No newline at end of file diff --git a/packages/site/source/packages/docs/vue.md b/packages/site/source/packages/docs/vue.md index eee81c8..6f94c7f 100644 --- a/packages/site/source/packages/docs/vue.md +++ b/packages/site/source/packages/docs/vue.md @@ -4,7 +4,7 @@ Vue provides the official npm package `vue-rx` that provides RxJS integration, w ### Example
-This example is available in [Github](https://github.com/embark-framework/subspace/tree/master/examples/vue) +This example is available in Github
@@ -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 }); diff --git a/packages/site/themes/landscape/README.md b/packages/site/themes/landscape/README.md index 90ecccd..b11bce3 100644 --- a/packages/site/themes/landscape/README.md +++ b/packages/site/themes/landscape/README.md @@ -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 diff --git a/packages/site/themes/landscape/_config.yml b/packages/site/themes/landscape/_config.yml index ca22374..7bd470d 100644 --- a/packages/site/themes/landscape/_config.yml +++ b/packages/site/themes/landscape/_config.yml @@ -28,8 +28,6 @@ archive_type: 'monthly' show_count: false # Miscellaneous -google_analytics: -gauges_analytics: favicon: /favicon.png twitter: google_plus: diff --git a/packages/site/themes/landscape/layout/_partial/after-footer.ejs b/packages/site/themes/landscape/layout/_partial/after-footer.ejs index ff2d509..fb461ae 100644 --- a/packages/site/themes/landscape/layout/_partial/after-footer.ejs +++ b/packages/site/themes/landscape/layout/_partial/after-footer.ejs @@ -22,4 +22,4 @@ <% } %> <%- js('js/script') %> -<%- partial('gauges-analytics') %> + diff --git a/packages/site/themes/landscape/layout/_partial/analytics.ejs b/packages/site/themes/landscape/layout/_partial/analytics.ejs new file mode 100644 index 0000000..b94f62a --- /dev/null +++ b/packages/site/themes/landscape/layout/_partial/analytics.ejs @@ -0,0 +1,16 @@ + + + + diff --git a/packages/site/themes/landscape/layout/_partial/gauges-analytics.ejs b/packages/site/themes/landscape/layout/_partial/gauges-analytics.ejs deleted file mode 100644 index d64be38..0000000 --- a/packages/site/themes/landscape/layout/_partial/gauges-analytics.ejs +++ /dev/null @@ -1,18 +0,0 @@ -<% if (theme.gauges_analytics){ %> - - - -<% } %> diff --git a/packages/site/themes/landscape/layout/_partial/google-analytics.ejs b/packages/site/themes/landscape/layout/_partial/google-analytics.ejs deleted file mode 100644 index 84e75f0..0000000 --- a/packages/site/themes/landscape/layout/_partial/google-analytics.ejs +++ /dev/null @@ -1,14 +0,0 @@ -<% if (theme.google_analytics){ %> - - - -<% } %> diff --git a/packages/site/themes/landscape/layout/_partial/head.ejs b/packages/site/themes/landscape/layout/_partial/head.ejs index 43d5f93..13b0e0c 100644 --- a/packages/site/themes/landscape/layout/_partial/head.ejs +++ b/packages/site/themes/landscape/layout/_partial/head.ejs @@ -2,7 +2,7 @@ - <%- partial('google-analytics') %> + <%- partial('analytics') %> <% var title = page.title; diff --git a/packages/site/themes/subspace/layout/partial/analytics.ejs b/packages/site/themes/subspace/layout/partial/analytics.ejs new file mode 100644 index 0000000..b94f62a --- /dev/null +++ b/packages/site/themes/subspace/layout/partial/analytics.ejs @@ -0,0 +1,16 @@ + + + + diff --git a/packages/site/themes/subspace/layout/partial/footer.ejs b/packages/site/themes/subspace/layout/partial/footer.ejs index ac2fc47..b8d6857 100644 --- a/packages/site/themes/subspace/layout/partial/footer.ejs +++ b/packages/site/themes/subspace/layout/partial/footer.ejs @@ -54,6 +54,9 @@ integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"> + <%- partial('analytics') %> + +