This commit is contained in:
ポール ウェッブ 2019-01-30 16:15:10 -06:00
parent fa29381a5c
commit 1663bc49f8
16 changed files with 219 additions and 83 deletions

View file

@ -11,8 +11,13 @@ import html from "choo/html";
// E X P O R T
export default () => html`
<div class="api__header page__markup">
<h1>lbrycrd APIs</h1>
<div class="api-content__body">
<h2>lbrycrd APIs</h2>
<p>Methods and signatures provided by the <a href="/glossary#lbrycrd">lbrycrd</a> blockchain daemon are documented below. To build, download, or run lbrycrd, see the project <a href="https://github.com/lbryio/lbrycrd/blob/master/README.md">README</a>.</p>
</div>
<div class="api-content__intro">
<p>You can find the repo for this API on GitHub:</p>
<pre><code>https://github.com/lbryio/lbry</code></pre>
</div>
`;

View file

@ -11,8 +11,13 @@ import html from "choo/html";
// E X P O R T
export default () => html`
<div class="api__header page__markup">
<h1>lbry-sdk APIs</h1>
<div class="api-content__body">
<h2>lbry-sdk APIs</h2>
<p>Methods and signatures provided by the <a href="/glossary#lbry-sdk">lbry-sdk</a> daemon are documented below. To build, download, or run the daemon, see the project <a href="https://github.com/lbryio/lbry/blob/master/README.md">README</a>.</p>
</div>
<div class="api-content__intro">
<p>You can find the repo for this API on GitHub:</p>
<pre><code>https://github.com/lbryio/lbrycrd</code></pre>
</div>
`;

View file

@ -9,6 +9,7 @@ import exists from "fs-exists-sync";
import fm from "front-matter";
import fs from "graceful-fs";
import html from "choo/html";
import m from "markdown-it";
import markdownAnchor from "markdown-it-anchor";
import markdownSup from "@module/markdown-it-sup";
import path from "path";
@ -17,7 +18,7 @@ import raw from "choo/html/raw";
// U T I L S
const numberRegex = /^[0-9]/g;
const md = require("markdown-it")({
const md = m({
html: true,
typographer: true
}).use(markdownSup)
@ -32,7 +33,9 @@ const md = require("markdown-it")({
.replace(/\)/g, "")
.replace(/,/g, "");
if (finalString.match(numberRegex)) finalString = `_${finalString}`;
if (finalString.match(numberRegex))
finalString = `_${finalString}`;
return finalString;
}
});

View file

@ -14,23 +14,49 @@ document.getElementById("input-search").value = "";
// Activate search
document.getElementById("input-search").addEventListener("keyup", () => {
if (document.getElementById("input-search").value)
document.querySelector(".api__toc__search__clear").classList.add("active");
document.querySelector(".api-toc__search-clear").classList.add("active");
else
document.querySelector(".api__toc__search__clear").classList.remove("active");
document.querySelector(".api-toc__search-clear").classList.remove("active");
});
// Cancel search
document.querySelector(".api__toc__search__clear").addEventListener("click", () => {
document.querySelector(".api-toc__search-clear").addEventListener("click", () => {
document.getElementById("input-search").value = "";
document.querySelector(".api__toc__search__clear").classList.remove("active");
document.querySelector(".api-toc__search-clear").classList.remove("active");
jets.destroy();
reinitJets();
});
// H E L P E R
// Code toggles
handleApiLanguageToggles("curl");
handleApiLanguageToggles("lbrynet");
handleApiLanguageToggles("python");
// H E L P E R S
function handleApiLanguageToggles(language) {
document.getElementById(`toggle-${language}`).addEventListener("click", () => {
const codeExamples = document.querySelectorAll(`[data-api-example-type="${language}"]`);
const examples = document.querySelectorAll("[data-api-example-type]");
const toggles = document.querySelectorAll("*[id^='toggle-']");
for (const example of examples)
example.classList.remove("active");
for (const example of codeExamples)
example.classList.add("active");
for (const toggle of toggles)
toggle.classList.remove("active");
document.getElementById(`toggle-${language}`).classList.add("active");
});
}
function reinitJets() {
jets = new Jets({

View file

@ -61,7 +61,8 @@ server
next();
})
.ready(err => {
if (err) throw err;
if (err)
throw err;
server.ws.on("connection", socket => {
socket.on("message", data => {

View file

@ -15,7 +15,7 @@
}
}
.api__header {
.api-header {
padding: 2rem;
position: relative;
@ -33,20 +33,20 @@
/*!
* API | Table of Contents
*
* @class .api__toc
* @class .api__toc__search
* @class .api__toc__search__field
* @class .api-toc
* @class .api-toc__search
* @class .api-toc__search-field
*
* @class .api__toc__search__clear
* @class .api-toc__search-clear
* @state {.active}
*
* @class .api__toc__items
* @class .api-toc__items
*
* @class .api__toc__item
* @class .api-toc__item
* @state {:hover}
**/
.api__toc {
.api-toc {
width: 200px; height: calc(100vh - 4rem); // navigation is 4rem tall
bottom: 0; left: 0;
@ -59,11 +59,11 @@
z-index: 3;
}
.api__toc__search {
.api-toc__search {
position: relative;
}
.api__toc__search__field {
.api-toc__search-field {
width: 100%;
padding: 0.25rem calc(2rem + 4px) 0.25rem 0.75rem;
@ -72,7 +72,7 @@
line-height: 2rem;
}
.api__toc__search__clear {
.api-toc__search-clear {
width: 1.25rem; height: 1.25rem;
top: 0.6rem; right: 0.75rem;
@ -97,7 +97,7 @@
}
}
.api__toc__items {
.api-toc__items {
font-size: 0.8rem;
line-height: 1.33;
list-style-type: none;
@ -105,7 +105,7 @@
padding-bottom: 1rem;
}
.api__toc__item {
.api-toc__item {
&:hover {
background-color: $lbry-gray-2;
}
@ -116,12 +116,12 @@
}
}
.api__content {
.api-content {
width: calc(100% - 200px);
float: right;
}
.api__documentation {
.api-documentation {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(50%, 1fr));
@ -182,18 +182,30 @@
}
}
.api__content__body {
.api-content__body {
padding: 2rem;
border-bottom: 1px solid $lbry-gray-1; // rgba($lbry-gray-1, 0.3);
border-bottom: 1px solid $lbry-gray-1;
a {
transition: color 0.2s;
&:not(:hover) {
color: $lbry-teal-3;
}
&:hover {
color: $lbry-teal-5;
}
}
}
.api__content__body__arguments {
.api-content__body-arguments {
border: 1px solid $lbry-gray-2;
border-radius: 3px;
list-style-type: none;
}
.api__content__body__argument {
.api-content__body-argument {
&:not(:last-of-type) {
border-bottom: 1px solid $lbry-gray-2;
}
@ -234,14 +246,56 @@
}
}
.api__content__example {
.api-content__example,
.api-content__intro {
padding: 2rem;
background-color: rgba($lbry-black, 0.9);
border-bottom: 1px solid rgba($lbry-white, 0.1);
color: $lbry-white;
position: relative;
pre {
background-color: $lbry-black;
}
}
.api-content__items {
width: 100%;
padding: 1rem 2rem;
top: 4rem; right: 0;
background-color: $lbry-black;
position: sticky;
z-index: 10;
}
.api-content__item {
padding: 0.25rem 0.75rem;
border-radius: 0.2rem;
display: inline-block;
font-size: 0.8rem;
transition: background-color 0.2s;
&:not(:last-of-type) {
margin-right: 0.5rem;
}
&:not(:hover) {
background-color: $lbry-gray-5;
}
&.active,
&:hover {
background-color: $lbry-teal-4;
}
}
pre {
&[data-api-example-type] {
&:not(.active) {
display: none;
}
}
}

View file

@ -16,7 +16,9 @@ import redirects from "@data/redirects.json";
const blockchainApi = "https://cdn.jsdelivr.net/gh/lbryio/lbrycrd@master/contrib/devtools/generated/api_v1.json";
const cache = new Map();
const sdkApi = "https://cdn.jsdelivr.net/gh/lbryio/lbry@master/docs/api.json";
const sdkApi = process.env.NODE_ENV === "development" ?
"https://cdn.jsdelivr.net/gh/lbryio/lbry@generate_examples/docs/api.json" : // TODO: Remove when `generate_examples` is merged into master
"https://cdn.jsdelivr.net/gh/lbryio/lbry@master/docs/api.json";
@ -36,18 +38,25 @@ export default async(state) => {
return asyncHtml`
<div class="__slate">
<aside class="api__toc">
<div class="api__toc__search">
<input class="api__toc__search__field" id="input-search" placeholder="Search" type="search"/>
<div class="api__toc__search__clear" id="clear-search" title="Clear search query">&times;</div>
<ul class="api__toc__search__results"></ul>
<aside class="api-toc">
<div class="api-toc__search">
<input class="api-toc__search-field" id="input-search" placeholder="Search" type="search"/>
<div class="api-toc__search-clear" id="clear-search" title="Clear search query">&times;</div>
<ul class="api-toc__search-results"></ul>
</div>
<ul class="api__toc__items" id="toc" role="navigation">${createApiSidebar(apiResponse)}</ul>
<ul class="api-toc__items" id="toc" role="navigation">${createApiSidebar(apiResponse)}</ul>
</aside>
<section class="api__content">
${createApiHeader(state.params.wildcard)}
<div class="api__documentation" id="toc-content">
<section class="api-content">
<div class="api-documentation" id="toc-content">
<div>&nbsp;</div>
<nav class="api-content__items">
<button class="api-content__item" id="toggle-curl" type="button">curl</button>
<button class="api-content__item" id="toggle-lbrynet" type="button">lbrynet</button>
<button class="api-content__item" id="toggle-python" type="button">python</button>
</nav>
${createApiHeader(state.params.wildcard)}
${createApiContent(apiResponse)}
</div>
</section>
@ -55,6 +64,10 @@ export default async(state) => {
<script src="/assets/scripts/plugins/jets.js"></script>
<script src="/assets/scripts/api.js"></script>
<script>
document.getElementById("toggle-curl").click();
</script>
`;
}
@ -101,18 +114,17 @@ function createApiContent(apiDetails) {
apiDetailsReturns = JSON.parse(JSON.stringify(apiDetail.returns));
apiContent.push(`
<div class="api__content__body">
<div class="api-content__body">
<h2 id="${apiDetail.name}">${apiDetail.name}</h2>
<p>${apiDetail.description}</p>
${apiDetail.arguments.length ? `<h3>Arguments</h3><ul class="api__content__body__arguments">${renderArguments(apiDetail.arguments).join("")}</ul>` : ""}
${apiDetail.arguments.length ? `<h3>Arguments</h3><ul class="api-content__body-arguments">${renderArguments(apiDetail.arguments).join("")}</ul>` : ""}
<h3>Returns</h3>
<pre><code>${dedent(apiDetailsReturns)}</code></pre>
${!apiDetail.examples || !apiDetail.examples.length ? (`<h3>Returns</h3><pre><code>${dedent(apiDetailsReturns)}</code></pre>`) : ""}
</div>
<div class="api__content__example">
<pre><code>// example(s) for ${apiDetail.name} to come later</code></pre>
<div class="api-content__example">
${apiDetail.examples && apiDetail.examples.length ? renderExamples(apiDetail.examples).join("") : `<pre><code>// example(s) for ${apiDetail.name} to come later</code></pre>`}
</div>
`);
}
@ -138,7 +150,7 @@ function createApiSidebar(apiDetails) {
for (const apiDetail of apiDetails) {
apiSidebar.push(`
<li class="api__toc__item">
<li class="api-toc__item">
<a href="#${apiDetail.name}" title="Go to ${apiDetail.name} section">
${apiDetail.name}
</a>
@ -182,7 +194,7 @@ function renderArguments(args) {
for (const arg of args) {
argumentContent.push(`
<li class="api__content__body__argument">
<li class="api-content__body-argument">
<div class="left">
<strong>${arg.name}</strong><br/>
${arg.is_required === true ? "" : "<span>optional</span>" }<span>${arg.type}</span>
@ -195,3 +207,21 @@ function renderArguments(args) {
return argumentContent;
}
function renderExamples(args) {
const exampleContent = [];
for (const arg of args) {
exampleContent.push(`
<h3>${arg.title}</h3><br/>
<pre data-api-example-type="curl"><code>${arg.curl}</code></pre>
<pre data-api-example-type="lbrynet"><code>${arg.lbrynet}</code></pre>
<pre data-api-example-type="python"><code>${arg.python}</code></pre>
<h3>Output</h3><br/>
<pre><code>${arg.output}</code></pre>
`);
}
return exampleContent;
}

View file

@ -19,7 +19,10 @@ import page404 from "./404";
// E X P O R T
export default (state, emit) => { // eslint-disable-line
const partialPath = state.route === "resources/*" ? `resources/${state.params.wildcard}` : state.params.wildcard;
const partialPath = state.route === "resources/*" ?
`resources/${state.params.wildcard}` :
state.params.wildcard;
const path = `./documents/${partialPath}.md`;
if (!fs.existsSync(path))
@ -46,13 +49,22 @@ export default (state, emit) => { // eslint-disable-line
let pageScript = "";
if (partialPath === "glossary")
pageScript = "<script>" + fs.readFileSync(`${process.cwd()}/app/components/client/glossary-scripts.js`, "utf-8") + "</script>";
pageScript =
"<script>" +
fs.readFileSync(`${process.cwd()}/app/components/client/glossary-scripts.js`, "utf-8") +
"</script>";
if (partialPath === "overview")
pageScript = "<script>" + fs.readFileSync(`${process.cwd()}/app/components/client/ecosystem-scripts.js`, "utf-8") + "</script>";
pageScript =
"<script>" +
fs.readFileSync(`${process.cwd()}/app/components/client/ecosystem-scripts.js`, "utf-8") +
"</script>";
if (partialPath === "playground")
pageScript = "<script>" + fs.readFileSync(`${process.cwd()}/app/components/client/playground-scripts.js`, "utf-8") + "</script>";
pageScript =
"<script>" +
fs.readFileSync(`${process.cwd()}/app/components/client/playground-scripts.js`, "utf-8") +
"</script>";
return html`
<article class="page" itemtype="http://schema.org/BlogPosting">

View file

@ -5,7 +5,7 @@ title: Build
## THIS IS NOT DONE AT ALL AND IF YOU CONTINUE TO READ IT YOU MENTALLY ASSENT TO COMMITTING AT LEAST ONE CHANGE THAT MAKES IT BETTER
## Introduction
Want to build something on top of LBRY? This is the place to get started.
At least, it's the place to get started so long as you have some idea of what LBRY _is_. If you don't, you should read the
@ -18,7 +18,7 @@ Want to build with us rather than on your own? Check out our [Contributing Guide
- You want to build an application that contributes to the world's knowledge, or benefits from global, shared discovery.
- You want to replace an existing centralized service related to digital content distribution with a decentralized or community-controlled one.
- You want to build an application that is [[permissionless]] to interact with.
- You want to further openness, freedom of information, and/or personal choice on the internet.
- You want to further openness, freedom of information, and/or personal choice on the internet.
### When Not to Use LBRY
@ -29,7 +29,7 @@ Want to build with us rather than on your own? Check out our [Contributing Guide
You can build many types of apps. Fat apps, short apps, tall apps, skinny apps!
Most end-user applications will use the [lbry-sdk](https://github.com/lbryio/lbry) as a way of accessing and communicating with the LBRY network. A look at the [APIs](/api/sdk) provided by the SDK will help you understand what facilities the SDK provides.
Most end-user applications will use the [lbry-sdk](https://github.com/lbryio/lbry) as a way of accessing and communicating with the LBRY network. A look at the [APIs](/api/sdk) provided by the SDK will help you understand what facilities the SDK provides.
Some applications do not need to access content available on the network (e.g. a wallet-only app, or a blockchain visualizer). These applications might use [lbrycrd](//github.com/lbryio/lbrycrd), the blockchain daemon, or [chainquery](//github.com/lbryio/lbrycrd), which parses blockchain data into SQL.
@ -40,7 +40,7 @@ Let's look at some specific types of applications and the basic design for each.
#### Full Web Applications
By full web application, we mean a centrally-hosted web application that uses most or all of the suite of capabilities the LBRY protocol provides.
1. Pick your favorite language and stack and do your typical setup to get a "Hello World" application running.
1. Install [lbry-sdk](//github.com/lbryio/lbry). (Docker images? Other convenient ways of doing this?)
1. Bridging basics.

View file

@ -10,9 +10,9 @@ We encourage the submission of changes and additions to this glossary.
### Blob
A Binary Large Object (BLOB) is a collection of binary data stored as a single entity in a database management system. When files are uploaded to the LBRY peer to peer network, they are broken down into 2MB encrypted blobs which are then shared to other peers.
A Binary Large Object (BLOB) is a collection of binary data stored as a single entity in a database management system. When files are uploaded to the LBRY peer to peer network, they are broken down into 2MB encrypted blobs which are then shared to other peers.
A [manifest](#manifest) blob is also created to index the multiple content blobs that were created from the file. A [stream](#stream) is the collection of all these blobs particlar to one published file. See [Encoding](https://spec.lbry.io/#encoding) in the specification.
A [manifest](#manifest) blob is also created to index the multiple content blobs that were created from the file. A [stream](#stream) is the collection of all these blobs particlar to one published file. See [Encoding](https://spec.lbry.io/#encoding) in the specification.
### Block

View file

@ -7,7 +7,7 @@ LBRY Inc. currently releases and maintains three applications:
- [LBRY Desktop](https://github.com/lbryio/lbry-desktop), a desktop browser for the LBRY network based in React and Electron available on Windows, macOS, and Linux.
- [LBRY Android](https://github.com/lbryio/lbry-android), an Android browser for the LBRY network in React Native and available in the playstore.
- [spee.ch](https://github.com/lbryio/spee.ch), a web-based sharing and organizational app designed for self-hosting.
A central idea of LBRY is that there's _not_ a singular way to interact with the network. Anyone can build on top of LBRY in a permissionless manner. LBRY Inc. maintains open-source applications to show what's possible and to give new users a user-friendly to use the network.
### Additional Resources

View file

@ -4,7 +4,7 @@ At this level:
- Metadata stored in the blockchain is interpreted and validated.
- Data referenced by metadata is accessed and distributed via a peer-to-peer network.
- [[Identities]] are created, signed, and validated.
- [[Identities]] are created, signed, and validated.
Data network operations are provided by the [lbrysdk](https://github.com/lbryio/lbry). This SDK also provides local wallet functionality and a set of APIs to facilitate building applications.

View file

@ -1,6 +1,6 @@
# API wrappers for the LBRY blockchain and protocol
This document contains a comprehensive list of all available API wrappers for the LBRY protocol and blockchain. API wrappers allow for easier integration of the LBRY APIs into your codebase. They still require you to run either the [LBRY protocol](https://github.com/lbryio/lbry) or the [LBRY blockchain](https://github.com/lbryio/lbrycrd).
This document contains a comprehensive list of all available API wrappers for the LBRY protocol and blockchain. API wrappers allow for easier integration of the LBRY APIs into your codebase. They still require you to run either the [LBRY protocol](https://github.com/lbryio/lbry) or the [LBRY blockchain](https://github.com/lbryio/lbrycrd).
Interested in creating one for a language not shown below? See our [bounties page](https://lbry.io/bounty/lbry-binding) for details.

View file

@ -4,7 +4,7 @@ This document outlines how to configure daemon settings and what options are ava
## Daemon settings configuration
The easiest way to configure the settings is by editing the `daemon_settings.yml` file (may need to be created) that resides in the default [lbrynet directory](https://lbry.io/faq/lbry-directories). These settings can also be configured via the [settings_set](https://lbry.tech/api/sdk#settings_set) API call. The [settings_get](https://lbry.tech/api/sdk#settings_get) API call can be used to retrieve current values. Currently not all settings are made available via the API calls, see [GitHub issue 1374](https://github.com/lbryio/lbry/issues/1374).
The easiest way to configure the settings is by editing the `daemon_settings.yml` file (may need to be created) that resides in the default [lbrynet directory](https://lbry.io/faq/lbry-directories). These settings can also be configured via the [settings_set](https://lbry.tech/api/sdk#settings_set) API call. The [settings_get](https://lbry.tech/api/sdk#settings_get) API call can be used to retrieve current values. Currently not all settings are made available via the API calls, see [GitHub issue 1374](https://github.com/lbryio/lbry/issues/1374).
Sample daemon_settings.yml file:
```

View file

@ -18,7 +18,7 @@ For this example, we will use claimID `d9317ac7842f88ba442fee749c4f834353c24206`
- start with **claim ID**
- blockchain gets you **metadata** for your claimID
- parsing metadata gets you **sd hash** and fee info
- if there is a fee, pay it using the blockchain
- if there is a fee, pay it using the blockchain
- dht gets you **peers** for the sd hash
- blob exchange gets **sd blob** from peers
- sd blob is parsed to get **content hashes**
@ -60,20 +60,20 @@ The SD blob is JSON-formatted text. It contains a dictionary with the following
```
{
"stream_name": "574c707655476a766d58632e6d7034",
"blobs": [
{
"length": 2097152,
"blob_num": 6,
"blob_hash": "b7e43c102781f978c24bc2bc...",
"iv": "63a6befc3c8d01f662ffad2f2381b357"
},
...
],
"stream_type": "lbryfile",
"key": "ee768c4e642012bb5b2e20cf9b1f997b",
"suggested_file_name": "574c707655476a766d58632e6d7034",
"stream_hash": "6b1f9d5f129e06bb94b2ffdda817a5848c...",
"stream_name": "574c707655476a766d58632e6d7034",
"blobs": [
{
"length": 2097152,
"blob_num": 6,
"blob_hash": "b7e43c102781f978c24bc2bc...",
"iv": "63a6befc3c8d01f662ffad2f2381b357"
},
...
],
"stream_type": "lbryfile",
"key": "ee768c4e642012bb5b2e20cf9b1f997b",
"suggested_file_name": "574c707655476a766d58632e6d7034",
"stream_hash": "6b1f9d5f129e06bb94b2ffdda817a5848c...",
}
```

View file

@ -11,7 +11,7 @@
"dependencies": {
"@babel/polyfill": "^7.2.5",
"@inc/fastify-ws": "^1.1.0",
"@octokit/rest": "^16.13.1",
"@octokit/rest": "^16.13.4",
"@slack/client": "^4.8.0",
"async": "^2.6.1",
"async-es": "^2.6.1",
@ -62,9 +62,9 @@
"@babel/preset-env": "^7.3.1",
"@babel/register": "^7.0.0",
"@inc/eslint-config": "^1.1.2",
"@inc/sasslint-config": "^1.1.2",
"@inc/sasslint-config": "^1.1.3",
"@lbry/color": "^1.1.0",
"@lbry/components": "^1.8.1",
"@lbry/components": "^1.9.0",
"eslint": "^5.12.1",
"husky": "^1.3.1",
"nodemon": "^1.18.9",