diff --git a/.cspell/template-words.txt b/.cspell/template-words.txt index 5868e11a1..e049c6a00 100644 --- a/.cspell/template-words.txt +++ b/.cspell/template-words.txt @@ -1,6 +1,5 @@ # Words found in our template code brower -coreconcepts elif endfor endlayoutblock diff --git a/11ty-extensions/markdown-it-config.js b/11ty-extensions/markdown-it-config.js index f6e84a885..0a11e4ea8 100644 --- a/11ty-extensions/markdown-it-config.js +++ b/11ty-extensions/markdown-it-config.js @@ -13,7 +13,7 @@ function composeAttributeString(token, defaultAttrs ={}) { //convert token.attrs to an object and merge with defaultAttrs const attrs = token.attrs ? token.attrs.reduce((acc, attr) => { acc[attr[0]] = attr[1]; return acc; }, {}) : {}; const mergedAttrs = Object.assign({}, defaultAttrs, attrs); - + return Object.keys(mergedAttrs).reduce((acc, key) => acc + ` ${key}="${mergedAttrs[key]}"`, ""); } @@ -77,22 +77,22 @@ const validateDetailsBlock = (params) => { /* End Details Block code */ /** - * Configures Markdown-it lib plugins etc. Meant to be called from .eleventy.js - * @param {*} eleventyConfig + * Configures Markdown-it lib plugins etc. Meant to be called from .eleventy.js + * @param {*} eleventyConfig */ module.exports = function(eleventyConfig) { eleventyConfig.amendLibrary("md", (mdLib) => { mdLib.set({ typographer: true }); - + //Configure markdown-it plugins mdLib.use(markdownItAttrs); mdLib.use(markdownItAnchor, { tabIndex: false, slugify: s => slugify(s) }); - mdLib.use(markdownItContainer, "coreconcepts-intro"); - mdLib.use(markdownItContainer, "coreconcepts-orientation"); - mdLib.use(markdownItContainer, "coreconcepts-storysequence"); + mdLib.use(markdownItContainer, "learn-intro"); + mdLib.use(markdownItContainer, "learn-orientation"); + mdLib.use(markdownItContainer, "learn-storysequence"); mdLib.use(markdownItContainer, "h-author"); mdLib.use(markdownItContainer, "output-block"); - + // Admonitions mdLib.use(markdownItContainer, "tip", { marker: "!", render: composeGenericAdmonitionRenderFunc("tip") }); mdLib.use(markdownItContainer, "note", { marker: "!", render: composeGenericAdmonitionRenderFunc("note") }); @@ -104,5 +104,5 @@ module.exports = function(eleventyConfig) { // Create a specialized synonym for details block with a class of "dig-deeper" mdLib.use(markdownItContainer, "dig-deeper", { marker: "!", render: composeDetailsBlockRenderFunc("dig-deeper") }); }); - + } \ No newline at end of file diff --git a/11ty-markdown-changes.md b/11ty-markdown-changes.md index b729b1e98..38beeddd5 100644 --- a/11ty-markdown-changes.md +++ b/11ty-markdown-changes.md @@ -11,9 +11,9 @@ ## Divs - No more `markdown=1`, instead leave a blank line after. - - coreconcepts-intro, coreconcepts-orientation, and coreconcepts-storysequence divs have been created as MD containers. Use: + - learn-intro, learn-orientation, and learn-storysequence divs have been created as MD containers. Use: ``` - ::: coreconcepts-intro + ::: learn-intro words words ::: ``` @@ -37,7 +37,7 @@ ## Center an Image ``` -![](/assets/img/concepts/8.8-assigned-capability.png) +![](/assets/img/learn/8.8-assigned-capability.png) {.center} ``` Note: The new line after the image is required to put the class in the enclosing `

` @@ -46,7 +46,7 @@ Note: The new line after the image is required to put the class in the enclosing Obviously it would be optimal to actually resize the image. But you can tweak the max-width with the classes `sz10p` (10%) through `sz200p` (200%) ``` -![](/assets/img/concepts/8.1-calls.png){.sz50p} +![](/assets/img/learn/8.1-calls.png){.sz50p} ``` ## Items to add to README diff --git a/README.md b/README.md index 7adce323f..79e9e7e50 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Additionally the following `markdown-it` plugins have been added: There are of course more details. See the docs at [markdown-it-attrs](https://github.com/arve0/markdown-it-attrs) for more. - [markdown-it-container](https://github.com/markdown-it/markdown-it-container) Plugin for creating block-level custom containers. For example: ``` - ::: coreconcepts-intro + ::: learn-intro Blah blah ::: ``` @@ -80,7 +80,7 @@ Additionally the following `markdown-it` plugins have been added: renders as ``` -

+

Blah blah

``` @@ -88,10 +88,10 @@ Additionally the following `markdown-it` plugins have been added: Each container type needs to be configured in `markdown-it-config.js` for examples and to add more. This one provides a lot of flexibility. ## Site search and indexing -The site uses the [Pagefind](https://pagefind.app/) library to index the contents of the site and to find search results upon request. -The documentation is quite good. One thing to note; pages are indexed based on the inclusion of the `data-pagefind-body` -attribute on a page. It is included on all of the main pages (all but the Design System). If you need to remove some or all of a page -from indexing you can use the `data-pagefind-ignore` attribute. See (https://pagefind.app/docs/indexing/) for details. +The site uses the [Pagefind](https://pagefind.app/) library to index the contents of the site and to find search results upon request. +The documentation is quite good. One thing to note; pages are indexed based on the inclusion of the `data-pagefind-body` +attribute on a page. It is included on all of the main pages (all but the Design System). If you need to remove some or all of a page +from indexing you can use the `data-pagefind-ignore` attribute. See (https://pagefind.app/docs/indexing/) for details. ## Setup for Dev - `npm install` diff --git a/netlify.toml b/netlify.toml index 0dbedb97e..b7f8a4dcb 100644 --- a/netlify.toml +++ b/netlify.toml @@ -48,27 +48,27 @@ # so let's redirect them. [[redirects]] from = "/docs/concepts/3_private_data/" - to = "/concepts/3_source_chain/" + to = "/learn/3_source_chain/" status = 301 [[redirects]] from = "/docs/concepts/4_public_data_on_the_dht/" - to = "/concepts/4_dht/" + to = "/learn/4_dht/" status = 301 [[redirects]] from = "/docs/concepts/5_linking_data_together/" - to = "/concepts/5_links_anchors/" + to = "/learn/5_links_anchors/" status = 301 [[redirects]] from = "/docs/concepts/6_modifying_and_deleting_data/" - to = "/concepts/6_crud_actions/" + to = "/learn/6_crud_actions/" status = 301 [[redirects]] from = "/docs/concepts/8_node_to_node_messaging/" - to = "/concepts/8_calls_capabilities/" + to = "/learn/8_calls_capabilities/" status = 301 [[redirects]] @@ -112,10 +112,16 @@ to = "/resources/glossary/" status = 301 +# The Core Concepts guide has been renamed to Learn. +[[redirects]] + from = "/concepts/*" + to = "/learn/:splat" + status = 302 + # The front page for the core concepts has been removed. [[redirects]] - from = "/concepts/" - to = "/concepts/1_the_basics/" + from = "/learn/" + to = "/learn/1_the_basics/" # Keeping this as a 302 in case we decide we want a front page again. status = 302 diff --git a/src/assets/img/concepts/1.1-architecture-comparison.png b/src/assets/img/learn/1.1-architecture-comparison.png similarity index 100% rename from src/assets/img/concepts/1.1-architecture-comparison.png rename to src/assets/img/learn/1.1-architecture-comparison.png diff --git a/src/assets/img/concepts/10.1-countersigning.png b/src/assets/img/learn/10.1-countersigning.png similarity index 100% rename from src/assets/img/concepts/10.1-countersigning.png rename to src/assets/img/learn/10.1-countersigning.png diff --git a/src/assets/img/concepts/10.10-validate.png b/src/assets/img/learn/10.10-validate.png similarity index 100% rename from src/assets/img/concepts/10.10-validate.png rename to src/assets/img/learn/10.10-validate.png diff --git a/src/assets/img/concepts/10.11-authorities-collect.png b/src/assets/img/learn/10.11-authorities-collect.png similarity index 100% rename from src/assets/img/concepts/10.11-authorities-collect.png rename to src/assets/img/learn/10.11-authorities-collect.png diff --git a/src/assets/img/concepts/10.12-authorities-distribute.png b/src/assets/img/learn/10.12-authorities-distribute.png similarity index 100% rename from src/assets/img/concepts/10.12-authorities-distribute.png rename to src/assets/img/learn/10.12-authorities-distribute.png diff --git a/src/assets/img/concepts/10.13-commit-and-publish.png b/src/assets/img/learn/10.13-commit-and-publish.png similarity index 100% rename from src/assets/img/concepts/10.13-commit-and-publish.png rename to src/assets/img/learn/10.13-commit-and-publish.png diff --git a/src/assets/img/concepts/10.14-enzyme.png b/src/assets/img/learn/10.14-enzyme.png similarity index 100% rename from src/assets/img/concepts/10.14-enzyme.png rename to src/assets/img/learn/10.14-enzyme.png diff --git a/src/assets/img/concepts/10.15-m-of-n-witnesses.png b/src/assets/img/learn/10.15-m-of-n-witnesses.png similarity index 100% rename from src/assets/img/concepts/10.15-m-of-n-witnesses.png rename to src/assets/img/learn/10.15-m-of-n-witnesses.png diff --git a/src/assets/img/concepts/10.2-entry-exchange.png b/src/assets/img/learn/10.2-entry-exchange.png similarity index 100% rename from src/assets/img/concepts/10.2-entry-exchange.png rename to src/assets/img/learn/10.2-entry-exchange.png diff --git a/src/assets/img/concepts/10.3-preflight.png b/src/assets/img/learn/10.3-preflight.png similarity index 100% rename from src/assets/img/concepts/10.3-preflight.png rename to src/assets/img/learn/10.3-preflight.png diff --git a/src/assets/img/concepts/10.4-preflight-send.png b/src/assets/img/learn/10.4-preflight-send.png similarity index 100% rename from src/assets/img/concepts/10.4-preflight-send.png rename to src/assets/img/learn/10.4-preflight-send.png diff --git a/src/assets/img/concepts/10.5-preflight-inspection.png b/src/assets/img/learn/10.5-preflight-inspection.png similarity index 100% rename from src/assets/img/concepts/10.5-preflight-inspection.png rename to src/assets/img/learn/10.5-preflight-inspection.png diff --git a/src/assets/img/concepts/10.6-bob-lock.png b/src/assets/img/learn/10.6-bob-lock.png similarity index 100% rename from src/assets/img/concepts/10.6-bob-lock.png rename to src/assets/img/learn/10.6-bob-lock.png diff --git a/src/assets/img/concepts/10.7-alice-lock.png b/src/assets/img/learn/10.7-alice-lock.png similarity index 100% rename from src/assets/img/concepts/10.7-alice-lock.png rename to src/assets/img/learn/10.7-alice-lock.png diff --git a/src/assets/img/concepts/10.8-countersigning-session.png b/src/assets/img/learn/10.8-countersigning-session.png similarity index 100% rename from src/assets/img/concepts/10.8-countersigning-session.png rename to src/assets/img/learn/10.8-countersigning-session.png diff --git a/src/assets/img/concepts/10.9-trial-commit.png b/src/assets/img/learn/10.9-trial-commit.png similarity index 100% rename from src/assets/img/concepts/10.9-trial-commit.png rename to src/assets/img/learn/10.9-trial-commit.png diff --git a/src/assets/img/concepts/2.1-mutual-execution.png b/src/assets/img/learn/2.1-mutual-execution.png similarity index 100% rename from src/assets/img/concepts/2.1-mutual-execution.png rename to src/assets/img/learn/2.1-mutual-execution.png diff --git a/src/assets/img/concepts/2.10-whole-stack.png b/src/assets/img/learn/2.10-whole-stack.png similarity index 100% rename from src/assets/img/concepts/2.10-whole-stack.png rename to src/assets/img/learn/2.10-whole-stack.png diff --git a/src/assets/img/concepts/2.2-data-integrity-membrane.png b/src/assets/img/learn/2.2-data-integrity-membrane.png similarity index 100% rename from src/assets/img/concepts/2.2-data-integrity-membrane.png rename to src/assets/img/learn/2.2-data-integrity-membrane.png diff --git a/src/assets/img/concepts/2.3-process-membrane.png b/src/assets/img/learn/2.3-process-membrane.png similarity index 100% rename from src/assets/img/concepts/2.3-process-membrane.png rename to src/assets/img/learn/2.3-process-membrane.png diff --git a/src/assets/img/concepts/2.4-client.png b/src/assets/img/learn/2.4-client.png similarity index 100% rename from src/assets/img/concepts/2.4-client.png rename to src/assets/img/learn/2.4-client.png diff --git a/src/assets/img/concepts/2.5-conductor.png b/src/assets/img/learn/2.5-conductor.png similarity index 100% rename from src/assets/img/concepts/2.5-conductor.png rename to src/assets/img/learn/2.5-conductor.png diff --git a/src/assets/img/concepts/2.6-happ.png b/src/assets/img/learn/2.6-happ.png similarity index 100% rename from src/assets/img/concepts/2.6-happ.png rename to src/assets/img/learn/2.6-happ.png diff --git a/src/assets/img/concepts/2.7-cells-in-slots.png b/src/assets/img/learn/2.7-cells-in-slots.png similarity index 100% rename from src/assets/img/concepts/2.7-cells-in-slots.png rename to src/assets/img/learn/2.7-cells-in-slots.png diff --git a/src/assets/img/concepts/2.8-dna-in-cell.png b/src/assets/img/learn/2.8-dna-in-cell.png similarity index 100% rename from src/assets/img/concepts/2.8-dna-in-cell.png rename to src/assets/img/learn/2.8-dna-in-cell.png diff --git a/src/assets/img/concepts/2.9-zomes-in-dna.png b/src/assets/img/learn/2.9-zomes-in-dna.png similarity index 100% rename from src/assets/img/concepts/2.9-zomes-in-dna.png rename to src/assets/img/learn/2.9-zomes-in-dna.png diff --git a/src/assets/img/concepts/3.1-key-generation.png b/src/assets/img/learn/3.1-key-generation.png similarity index 100% rename from src/assets/img/concepts/3.1-key-generation.png rename to src/assets/img/learn/3.1-key-generation.png diff --git a/src/assets/img/concepts/3.2-source-chain-as-journal.png b/src/assets/img/learn/3.2-source-chain-as-journal.png similarity index 100% rename from src/assets/img/concepts/3.2-source-chain-as-journal.png rename to src/assets/img/learn/3.2-source-chain-as-journal.png diff --git a/src/assets/img/concepts/3.3-genesis-records-1-and-2.png b/src/assets/img/learn/3.3-genesis-records-1-and-2.png similarity index 100% rename from src/assets/img/concepts/3.3-genesis-records-1-and-2.png rename to src/assets/img/learn/3.3-genesis-records-1-and-2.png diff --git a/src/assets/img/concepts/3.4-genesis-records-3-and-4.png b/src/assets/img/learn/3.4-genesis-records-3-and-4.png similarity index 100% rename from src/assets/img/concepts/3.4-genesis-records-3-and-4.png rename to src/assets/img/learn/3.4-genesis-records-3-and-4.png diff --git a/src/assets/img/concepts/3.5-commit.png b/src/assets/img/learn/3.5-commit.png similarity index 100% rename from src/assets/img/concepts/3.5-commit.png rename to src/assets/img/learn/3.5-commit.png diff --git a/src/assets/img/concepts/3.6-action.png b/src/assets/img/learn/3.6-action.png similarity index 100% rename from src/assets/img/concepts/3.6-action.png rename to src/assets/img/learn/3.6-action.png diff --git a/src/assets/img/concepts/3.7-prev-action.png b/src/assets/img/learn/3.7-prev-action.png similarity index 100% rename from src/assets/img/concepts/3.7-prev-action.png rename to src/assets/img/learn/3.7-prev-action.png diff --git a/src/assets/img/concepts/4.1-network.png b/src/assets/img/learn/4.1-network.png similarity index 100% rename from src/assets/img/concepts/4.1-network.png rename to src/assets/img/learn/4.1-network.png diff --git a/src/assets/img/concepts/4.10-gossip-resilience.png b/src/assets/img/learn/4.10-gossip-resilience.png similarity index 100% rename from src/assets/img/concepts/4.10-gossip-resilience.png rename to src/assets/img/learn/4.10-gossip-resilience.png diff --git a/src/assets/img/concepts/4.11-retrieval.png b/src/assets/img/learn/4.11-retrieval.png similarity index 100% rename from src/assets/img/concepts/4.11-retrieval.png rename to src/assets/img/learn/4.11-retrieval.png diff --git a/src/assets/img/concepts/4.12-healthy-network.png b/src/assets/img/learn/4.12-healthy-network.png similarity index 100% rename from src/assets/img/concepts/4.12-healthy-network.png rename to src/assets/img/learn/4.12-healthy-network.png diff --git a/src/assets/img/concepts/4.13-partition.png b/src/assets/img/learn/4.13-partition.png similarity index 100% rename from src/assets/img/concepts/4.13-partition.png rename to src/assets/img/learn/4.13-partition.png diff --git a/src/assets/img/concepts/4.14-resilience-building.png b/src/assets/img/learn/4.14-resilience-building.png similarity index 100% rename from src/assets/img/concepts/4.14-resilience-building.png rename to src/assets/img/learn/4.14-resilience-building.png diff --git a/src/assets/img/concepts/4.15-partition-healing.png b/src/assets/img/learn/4.15-partition-healing.png similarity index 100% rename from src/assets/img/concepts/4.15-partition-healing.png rename to src/assets/img/learn/4.15-partition-healing.png diff --git a/src/assets/img/concepts/4.2-public-entry-commit.png b/src/assets/img/learn/4.2-public-entry-commit.png similarity index 100% rename from src/assets/img/concepts/4.2-public-entry-commit.png rename to src/assets/img/learn/4.2-public-entry-commit.png diff --git a/src/assets/img/concepts/4.3-private-entry-commit.png b/src/assets/img/learn/4.3-private-entry-commit.png similarity index 100% rename from src/assets/img/concepts/4.3-private-entry-commit.png rename to src/assets/img/learn/4.3-private-entry-commit.png diff --git a/src/assets/img/concepts/4.4-address-space-and-neighborhoods.png b/src/assets/img/learn/4.4-address-space-and-neighborhoods.png similarity index 100% rename from src/assets/img/concepts/4.4-address-space-and-neighborhoods.png rename to src/assets/img/learn/4.4-address-space-and-neighborhoods.png diff --git a/src/assets/img/concepts/4.5-alice-neighborhood.png b/src/assets/img/learn/4.5-alice-neighborhood.png similarity index 100% rename from src/assets/img/concepts/4.5-alice-neighborhood.png rename to src/assets/img/learn/4.5-alice-neighborhood.png diff --git a/src/assets/img/concepts/4.7-alice-publish-address-calculation.png b/src/assets/img/learn/4.7-alice-publish-address-calculation.png similarity index 100% rename from src/assets/img/concepts/4.7-alice-publish-address-calculation.png rename to src/assets/img/learn/4.7-alice-publish-address-calculation.png diff --git a/src/assets/img/concepts/4.8-authority-resolution.png b/src/assets/img/learn/4.8-authority-resolution.png similarity index 100% rename from src/assets/img/concepts/4.8-authority-resolution.png rename to src/assets/img/learn/4.8-authority-resolution.png diff --git a/src/assets/img/concepts/4.9-gossip-publish.png b/src/assets/img/learn/4.9-gossip-publish.png similarity index 100% rename from src/assets/img/concepts/4.9-gossip-publish.png rename to src/assets/img/learn/4.9-gossip-publish.png diff --git a/src/assets/img/concepts/5.1-links.png b/src/assets/img/learn/5.1-links.png similarity index 100% rename from src/assets/img/concepts/5.1-links.png rename to src/assets/img/learn/5.1-links.png diff --git a/src/assets/img/concepts/5.2-alice.png b/src/assets/img/learn/5.2-alice.png similarity index 100% rename from src/assets/img/concepts/5.2-alice.png rename to src/assets/img/learn/5.2-alice.png diff --git a/src/assets/img/concepts/5.3-alice-username.png b/src/assets/img/learn/5.3-alice-username.png similarity index 100% rename from src/assets/img/concepts/5.3-alice-username.png rename to src/assets/img/learn/5.3-alice-username.png diff --git a/src/assets/img/concepts/5.4-usernames-anchor.png b/src/assets/img/learn/5.4-usernames-anchor.png similarity index 100% rename from src/assets/img/concepts/5.4-usernames-anchor.png rename to src/assets/img/learn/5.4-usernames-anchor.png diff --git a/src/assets/img/concepts/5.5-alice-album.png b/src/assets/img/learn/5.5-alice-album.png similarity index 100% rename from src/assets/img/concepts/5.5-alice-album.png rename to src/assets/img/learn/5.5-alice-album.png diff --git a/src/assets/img/concepts/5.6-album-tracks.png b/src/assets/img/learn/5.6-album-tracks.png similarity index 100% rename from src/assets/img/concepts/5.6-album-tracks.png rename to src/assets/img/learn/5.6-album-tracks.png diff --git a/src/assets/img/concepts/5.7-album-genres.png b/src/assets/img/learn/5.7-album-genres.png similarity index 100% rename from src/assets/img/concepts/5.7-album-genres.png rename to src/assets/img/learn/5.7-album-genres.png diff --git a/src/assets/img/concepts/5.8-genres-anchor.png b/src/assets/img/learn/5.8-genres-anchor.png similarity index 100% rename from src/assets/img/concepts/5.8-genres-anchor.png rename to src/assets/img/learn/5.8-genres-anchor.png diff --git a/src/assets/img/concepts/5.9-graph-database.png b/src/assets/img/learn/5.9-graph-database.png similarity index 100% rename from src/assets/img/concepts/5.9-graph-database.png rename to src/assets/img/learn/5.9-graph-database.png diff --git a/src/assets/img/concepts/6.1-crud.png b/src/assets/img/learn/6.1-crud.png similarity index 100% rename from src/assets/img/concepts/6.1-crud.png rename to src/assets/img/learn/6.1-crud.png diff --git a/src/assets/img/concepts/7.1-validation.png b/src/assets/img/learn/7.1-validation.png similarity index 100% rename from src/assets/img/concepts/7.1-validation.png rename to src/assets/img/learn/7.1-validation.png diff --git a/src/assets/img/concepts/7.10-gossip-to-authorities.png b/src/assets/img/learn/7.10-gossip-to-authorities.png similarity index 100% rename from src/assets/img/concepts/7.10-gossip-to-authorities.png rename to src/assets/img/learn/7.10-gossip-to-authorities.png diff --git a/src/assets/img/concepts/7.11-authorities-validate.png b/src/assets/img/learn/7.11-authorities-validate.png similarity index 100% rename from src/assets/img/concepts/7.11-authorities-validate.png rename to src/assets/img/learn/7.11-authorities-validate.png diff --git a/src/assets/img/concepts/7.12-hold.png b/src/assets/img/learn/7.12-hold.png similarity index 100% rename from src/assets/img/concepts/7.12-hold.png rename to src/assets/img/learn/7.12-hold.png diff --git a/src/assets/img/concepts/7.13-respond-validation-receipts.png b/src/assets/img/learn/7.13-respond-validation-receipts.png similarity index 100% rename from src/assets/img/concepts/7.13-respond-validation-receipts.png rename to src/assets/img/learn/7.13-respond-validation-receipts.png diff --git a/src/assets/img/concepts/7.14-gossip-to-authorities.png b/src/assets/img/learn/7.14-gossip-to-authorities.png similarity index 100% rename from src/assets/img/concepts/7.14-gossip-to-authorities.png rename to src/assets/img/learn/7.14-gossip-to-authorities.png diff --git a/src/assets/img/concepts/7.15-validate.png b/src/assets/img/learn/7.15-validate.png similarity index 100% rename from src/assets/img/concepts/7.15-validate.png rename to src/assets/img/learn/7.15-validate.png diff --git a/src/assets/img/concepts/7.16-warrant.png b/src/assets/img/learn/7.16-warrant.png similarity index 100% rename from src/assets/img/concepts/7.16-warrant.png rename to src/assets/img/learn/7.16-warrant.png diff --git a/src/assets/img/concepts/7.17-gossip-warrant.png b/src/assets/img/learn/7.17-gossip-warrant.png similarity index 100% rename from src/assets/img/concepts/7.17-gossip-warrant.png rename to src/assets/img/learn/7.17-gossip-warrant.png diff --git a/src/assets/img/concepts/7.18-ejection.png b/src/assets/img/learn/7.18-ejection.png similarity index 100% rename from src/assets/img/concepts/7.18-ejection.png rename to src/assets/img/learn/7.18-ejection.png diff --git a/src/assets/img/concepts/7.2-commit.png b/src/assets/img/learn/7.2-commit.png similarity index 100% rename from src/assets/img/concepts/7.2-commit.png rename to src/assets/img/learn/7.2-commit.png diff --git a/src/assets/img/concepts/7.3-validate.png b/src/assets/img/learn/7.3-validate.png similarity index 100% rename from src/assets/img/concepts/7.3-validate.png rename to src/assets/img/learn/7.3-validate.png diff --git a/src/assets/img/concepts/7.4-validation-success.png b/src/assets/img/learn/7.4-validation-success.png similarity index 100% rename from src/assets/img/concepts/7.4-validation-success.png rename to src/assets/img/learn/7.4-validation-success.png diff --git a/src/assets/img/concepts/7.5-persist-and-publish.png b/src/assets/img/learn/7.5-persist-and-publish.png similarity index 100% rename from src/assets/img/concepts/7.5-persist-and-publish.png rename to src/assets/img/learn/7.5-persist-and-publish.png diff --git a/src/assets/img/concepts/7.6-commit.png b/src/assets/img/learn/7.6-commit.png similarity index 100% rename from src/assets/img/concepts/7.6-commit.png rename to src/assets/img/learn/7.6-commit.png diff --git a/src/assets/img/concepts/7.7-validate.png b/src/assets/img/learn/7.7-validate.png similarity index 100% rename from src/assets/img/concepts/7.7-validate.png rename to src/assets/img/learn/7.7-validate.png diff --git a/src/assets/img/concepts/7.8-validation-failure.png b/src/assets/img/learn/7.8-validation-failure.png similarity index 100% rename from src/assets/img/concepts/7.8-validation-failure.png rename to src/assets/img/learn/7.8-validation-failure.png diff --git a/src/assets/img/concepts/7.9-return-error.png b/src/assets/img/learn/7.9-return-error.png similarity index 100% rename from src/assets/img/concepts/7.9-return-error.png rename to src/assets/img/learn/7.9-return-error.png diff --git a/src/assets/img/concepts/8.1-calls.png b/src/assets/img/learn/8.1-calls.png similarity index 100% rename from src/assets/img/concepts/8.1-calls.png rename to src/assets/img/learn/8.1-calls.png diff --git a/src/assets/img/concepts/8.2-client-call.png b/src/assets/img/learn/8.2-client-call.png similarity index 100% rename from src/assets/img/concepts/8.2-client-call.png rename to src/assets/img/learn/8.2-client-call.png diff --git a/src/assets/img/concepts/8.3-inter-zome-call.png b/src/assets/img/learn/8.3-inter-zome-call.png similarity index 100% rename from src/assets/img/concepts/8.3-inter-zome-call.png rename to src/assets/img/learn/8.3-inter-zome-call.png diff --git a/src/assets/img/concepts/8.4-bridge-call.png b/src/assets/img/learn/8.4-bridge-call.png similarity index 100% rename from src/assets/img/concepts/8.4-bridge-call.png rename to src/assets/img/learn/8.4-bridge-call.png diff --git a/src/assets/img/concepts/8.5-remote-call.png b/src/assets/img/learn/8.5-remote-call.png similarity index 100% rename from src/assets/img/concepts/8.5-remote-call.png rename to src/assets/img/learn/8.5-remote-call.png diff --git a/src/assets/img/concepts/8.6-unrestricted-capability.png b/src/assets/img/learn/8.6-unrestricted-capability.png similarity index 100% rename from src/assets/img/concepts/8.6-unrestricted-capability.png rename to src/assets/img/learn/8.6-unrestricted-capability.png diff --git a/src/assets/img/concepts/8.7-transferrable-capability.png b/src/assets/img/learn/8.7-transferrable-capability.png similarity index 100% rename from src/assets/img/concepts/8.7-transferrable-capability.png rename to src/assets/img/learn/8.7-transferrable-capability.png diff --git a/src/assets/img/concepts/8.8-assigned-capability.png b/src/assets/img/learn/8.8-assigned-capability.png similarity index 100% rename from src/assets/img/concepts/8.8-assigned-capability.png rename to src/assets/img/learn/8.8-assigned-capability.png diff --git a/src/assets/img/concepts/8.9-author-capability.png b/src/assets/img/learn/8.9-author-capability.png similarity index 100% rename from src/assets/img/concepts/8.9-author-capability.png rename to src/assets/img/learn/8.9-author-capability.png diff --git a/src/assets/img/concepts/9.1-signals.png b/src/assets/img/learn/9.1-signals.png similarity index 100% rename from src/assets/img/concepts/9.1-signals.png rename to src/assets/img/learn/9.1-signals.png diff --git a/src/assets/img/concepts/9.2-client-signal.png b/src/assets/img/learn/9.2-client-signal.png similarity index 100% rename from src/assets/img/concepts/9.2-client-signal.png rename to src/assets/img/learn/9.2-client-signal.png diff --git a/src/assets/img/concepts/9.3-remote-signal.png b/src/assets/img/learn/9.3-remote-signal.png similarity index 100% rename from src/assets/img/concepts/9.3-remote-signal.png rename to src/assets/img/learn/9.3-remote-signal.png diff --git a/src/custom/script.js b/src/custom/script.js index 7587c08a8..16f4f3460 100644 --- a/src/custom/script.js +++ b/src/custom/script.js @@ -1,3 +1,3 @@ -if (document.location.pathname.indexOf("/concepts/") == 0) { - document.body.className = "page-concepts"; +if (document.location.pathname.indexOf("/learn/") == 0) { + document.body.className = "page-learn"; } \ No newline at end of file diff --git a/src/custom/style.css b/src/custom/style.css index 7ba4e6704..592bc5f3a 100644 --- a/src/custom/style.css +++ b/src/custom/style.css @@ -93,25 +93,25 @@ code, kbd, pre { font-family: 'Roboto Mono', 'Courier New', Courier, monospace; .md-sidebar.md-sidebar--primary nav.md-nav:not(.md-nav--primary) .md-nav__list .md-nav__item.md-nav__item--active .md-nav__list .md-nav__item.md-nav__item--active, .md-sidebar.md-sidebar--primary nav.md-nav:not(.md-nav--primary) .md-nav__list .md-nav__item .md-nav__item, .md-sidebar.md-sidebar--primary nav.md-nav:not(.md-nav--primary) .md-nav__list .md-nav__item .md-nav__item:hover, .md-sidebar.md-sidebar--primary nav.md-nav:not(.md-nav--primary) .md-nav__list .md-nav__item.md-nav__item--active .md-nav__item:hover { background: #F1F1F1 !important; } .md-nav__link--active, .md-nav__link:hover, .md-nav__link:active, .md-nav__link:focus { color: rgba(0,0,0,.87) !important; } - body.page-concepts .md-sidebar.md-sidebar--primary li { position: relative; } - body.page-concepts .md-sidebar.md-sidebar--primary li a { padding-left: 43px; font-weight: normal; } - body.page-concepts .md-sidebar.md-sidebar--primary li:first-child a { padding-left: 10px; font-weight: bold; } - body.page-concepts .md-sidebar.md-sidebar--primary li:before { width: 28px; text-align: center; font-weight: bold; font-size: 16px; letter-spacing: -.5px; text-align: center; position: absolute; top: 10px; left: 8px; pointer-events: none; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(2):before { content: '01'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(3):before { content: '02'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(4):before { content: '03'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(5):before { content: '04'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(6):before { content: '05'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(7):before { content: '06'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(8):before { content: '07'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(9):before { content: '08'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(10):before { content: '09'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(11):before { content: '10'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(12):before { content: '11'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(13):before { content: '12'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(14):before { content: '13'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(15):before { content: '14'; } - body.page-concepts .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(16):before { content: '15'; } + body.page-learn .md-sidebar.md-sidebar--primary li { position: relative; } + body.page-learn .md-sidebar.md-sidebar--primary li a { padding-left: 43px; font-weight: normal; } + body.page-learn .md-sidebar.md-sidebar--primary li:first-child a { padding-left: 10px; font-weight: bold; } + body.page-learn .md-sidebar.md-sidebar--primary li:before { width: 28px; text-align: center; font-weight: bold; font-size: 16px; letter-spacing: -.5px; text-align: center; position: absolute; top: 10px; left: 8px; pointer-events: none; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(2):before { content: '01'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(3):before { content: '02'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(4):before { content: '03'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(5):before { content: '04'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(6):before { content: '05'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(7):before { content: '06'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(8):before { content: '07'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(9):before { content: '08'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(10):before { content: '09'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(11):before { content: '10'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(12):before { content: '11'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(13):before { content: '12'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(14):before { content: '13'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(15):before { content: '14'; } + body.page-learn .md-sidebar.md-sidebar--primary .md-nav__list li:nth-of-type(16):before { content: '15'; } } @media only screen and (max-width: 76.1875em) { @@ -147,23 +147,23 @@ article img { display: table; margin-left: auto; margin-right: auto; } .md-content { margin-left: 13.8rem; } } -/* Core Concepts */ - -.md-typeset .coreconcepts-intro { font-size: .98rem; border-left: .2rem solid rgba(0,0,0,.2); padding-left: 0.6rem; font-weight: 500; line-height: 1.55; } -.md-typeset .coreconcepts-intro p { letter-spacing: -.3px; } -.md-typeset .coreconcepts-orientation { margin: 2.2rem 0; padding: 1.6rem 1.2rem 1.8rem; background: #F8F8F8; position: relative; } -.md-typeset .coreconcepts-orientation :first-child { margin-top: 0; } -.md-typeset .coreconcepts-orientation :last-child { margin-bottom: 0; } -.md-typeset .coreconcepts-orientation h2, .md-typeset .coreconcepts-orientation h3 { position: relative; } -.md-typeset .coreconcepts-orientation a { font-weight: 500; letter-spacing: -.3px; } -.md-typeset .coreconcepts-orientation i { position: absolute; left: -40px; top: 13px; font-size: 28px; color: #3915ad; } -.md-typeset .coreconcepts-orientation ol { margin-bottom: -12px; margin-left: 0; } -.md-typeset .coreconcepts-storysequence > ol { margin-left: 0; } -.md-typeset .coreconcepts-storysequence > ol > li { list-style: none; padding: 0.6rem; background: #F8F8F8; margin: 1rem 0; } -.md-typeset .coreconcepts-storysequence > ol > li > img { margin-bottom: 1rem; } +/* Learn */ + +.md-typeset .learn-intro { font-size: .98rem; border-left: .2rem solid rgba(0,0,0,.2); padding-left: 0.6rem; font-weight: 500; line-height: 1.55; } +.md-typeset .learn-intro p { letter-spacing: -.3px; } +.md-typeset .learn-orientation { margin: 2.2rem 0; padding: 1.6rem 1.2rem 1.8rem; background: #F8F8F8; position: relative; } +.md-typeset .learn-orientation :first-child { margin-top: 0; } +.md-typeset .learn-orientation :last-child { margin-bottom: 0; } +.md-typeset .learn-orientation h2, .md-typeset .learn-orientation h3 { position: relative; } +.md-typeset .learn-orientation a { font-weight: 500; letter-spacing: -.3px; } +.md-typeset .learn-orientation i { position: absolute; left: -40px; top: 13px; font-size: 28px; color: #3915ad; } +.md-typeset .learn-orientation ol { margin-bottom: -12px; margin-left: 0; } +.md-typeset .learn-storysequence > ol { margin-left: 0; } +.md-typeset .learn-storysequence > ol > li { list-style: none; padding: 0.6rem; background: #F8F8F8; margin: 1rem 0; } +.md-typeset .learn-storysequence > ol > li > img { margin-bottom: 1rem; } @media (max-width: 1600px) { - .md-typeset .coreconcepts-orientation i { left: -36px; top: 12px; font-size: 26px; } + .md-typeset .learn-orientation i { left: -36px; top: 12px; font-size: 26px; } } /* Tables */ diff --git a/src/pages/_data/navigation/footerLinks.json5 b/src/pages/_data/navigation/footerLinks.json5 index 055b4e7cf..ddee79bbc 100644 --- a/src/pages/_data/navigation/footerLinks.json5 +++ b/src/pages/_data/navigation/footerLinks.json5 @@ -4,7 +4,7 @@ title: "Developers", links: [ { title: "Get Started", url: "/get-started/" }, - { title: "Core Concepts", url: "/concepts/1_the_basics/" }, + { title: "Learn", url: "/learn/1_the_basics/" }, { title: "Resources", url: "/resources/" }, ] }, diff --git a/src/pages/_data/navigation/headerNav.json5 b/src/pages/_data/navigation/headerNav.json5 index 13617a54b..ffc151e0b 100644 --- a/src/pages/_data/navigation/headerNav.json5 +++ b/src/pages/_data/navigation/headerNav.json5 @@ -1,7 +1,7 @@ { links: [ { title: "Get Started", url: "/get-started/", class:"" }, - { title: "Core Concepts", url: "/concepts/1_the_basics/", class:"" }, + { title: "Learn", url: "/learn/1_the_basics/", class:"" }, { title: "Resources", url: "/resources/", class:"" }, { title: "Get Involved", url: "/get-involved/", class:"" }, ] diff --git a/src/pages/_data/navigation/mainNav.json5 b/src/pages/_data/navigation/mainNav.json5 index 87c2dab93..a962a4701 100644 --- a/src/pages/_data/navigation/mainNav.json5 +++ b/src/pages/_data/navigation/mainNav.json5 @@ -8,17 +8,17 @@ { title: "Setup For a Local Event", url: "/get-started/at-an-event/" }, ] }, - { title: "Core Concepts", url: "/concepts/1_the_basics/", children: [ - { title: "Application Architecture", url: "/concepts/2_application_architecture/" }, - { title: "Source Chain", url: "/concepts/3_source_chain/" }, - { title: "DHT", url: "/concepts/4_dht/" }, - { title: "Links and Anchors", url: "/concepts/5_links_anchors/" }, - { title: "CRUD Actions", url: "/concepts/6_crud_actions/" }, - { title: "Validation", url: "/concepts/7_validation/" }, - { title: "Calls and Capabilities", url: "/concepts/8_calls_capabilities/" }, - { title: "Signals", url: "/concepts/9_signals/" }, - { title: "Countersigning", url: "/concepts/10_countersigning/" }, - { title: "Lifecycle Events", url: "/concepts/11_lifecycle_events/" }, + { title: "Learn", url: "/learn/1_the_basics/", children: [ + { title: "Application Architecture", url: "/learn/2_application_architecture/" }, + { title: "Source Chain", url: "/learn/3_source_chain/" }, + { title: "DHT", url: "/learn/4_dht/" }, + { title: "Links and Anchors", url: "/learn/5_links_anchors/" }, + { title: "CRUD Actions", url: "/learn/6_crud_actions/" }, + { title: "Validation", url: "/learn/7_validation/" }, + { title: "Calls and Capabilities", url: "/learn/8_calls_capabilities/" }, + { title: "Signals", url: "/learn/9_signals/" }, + { title: "Countersigning", url: "/learn/10_countersigning/" }, + { title: "Lifecycle Events", url: "/learn/11_lifecycle_events/" }, ] }, { title: "Resources", url: "/resources/", children: [ diff --git a/src/pages/_includes/widgets/home-tiles.njk b/src/pages/_includes/widgets/home-tiles.njk index 751a25e0e..9e41a9e86 100644 --- a/src/pages/_includes/widgets/home-tiles.njk +++ b/src/pages/_includes/widgets/home-tiles.njk @@ -8,10 +8,10 @@
{% endlinkTile %} - {% linkTile "/concepts/1_the_basics/", "home-tile" %} + {% linkTile "/learn/1_the_basics/", "home-tile" %} {{ craneIcon() }}
-

Core Concepts

+

Learn

Introducing Holochain basics

{% endlinkTile %} diff --git a/src/pages/ds/containers.md b/src/pages/ds/containers.md index 8eb8c68ac..00d4fa15b 100644 --- a/src/pages/ds/containers.md +++ b/src/pages/ds/containers.md @@ -79,18 +79,18 @@ Can wrap around code fences to prevent Copy buttons form being added to the code ## Site content specific containers All the below just apply a specific class to a surrounding div. These were implemented for very specific site style needs. More such can be created if need be. -- ### coreconcepts-intro - ::: coreconcepts-intro +- ### learn-intro + ::: learn-intro Sit amet tellus cras adipiscing enim eu turpis egestas. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris ultrices eros in cursus turpis massa tincidunt dui ut ornare lectus sit. ::: -- ### coreconcepts-orientation - ::: coreconcepts-orientation +- ### learn-orientation + ::: learn-orientation Sit amet tellus cras adipiscing enim eu turpis egestas. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris ultrices eros in cursus turpis massa tincidunt dui ut ornare lectus sit. ::: -- ### coreconcepts-storysequence - ::: coreconcepts-storysequence +- ### learn-storysequence + ::: learn-storysequence Sit amet tellus cras adipiscing enim eu turpis egestas. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris ultrices eros in cursus turpis massa tincidunt dui ut ornare lectus sit. ::: diff --git a/src/pages/get-involved.md b/src/pages/get-involved.md index 9ff4a5f80..c8ec2761e 100644 --- a/src/pages/get-involved.md +++ b/src/pages/get-involved.md @@ -6,7 +6,7 @@ Regardless of your experience level as a developer, we encourage you to get invo ### Jump in and get your feet wet -* Read through our [Core Concepts](/concepts/1_the_basics/) +* Read through our [Learn guide](/learn/1_the_basics/) * Track development progress with the biweekly [Holochain Dev Pulse](https://blog.holochain.org/tag/dev-pulse/){target=_blank} ### Connect and contribute diff --git a/src/pages/get-started/index.md b/src/pages/get-started/index.md index 6b0f08b7e..3ffe4a6b6 100644 --- a/src/pages/get-started/index.md +++ b/src/pages/get-started/index.md @@ -39,7 +39,7 @@ tocData: href: 6-next-steps --- -Welcome to the Getting Started with Holochain guide! This guide will walk you through the process of installing the Holochain development tools and creating a simple forum application. By the end of this guide, you'll be familiar with the core concepts of Holochain and have a basic understanding of how to develop peer-to-peer applications using the Holochain framework. +Welcome to the Getting Started with Holochain guide! This guide will walk you through the process of installing the Holochain development tools and creating a simple forum application. By the end of this guide, you'll be familiar with the [core concepts](/learn/1_the_basics/) of Holochain and have a basic understanding of how to develop peer-to-peer applications using the Holochain framework. ## How to use this guide @@ -47,7 +47,7 @@ Follow this guide step by step. All steps are essential to create the example ap * The examples below use `$` to represent your terminal prompt in a UNIX-like OS, though it may have been customized in your OS to appear differently. * We assume that you are reading this guide because you are a developer new to Holochain but interested in actually building peer-to-peer distributed applications using a framework that is agent-centric, that provides intrinsic data integrity, is scalable, and when deployed, end-user code runs just on the devices of the participants without relying on centralized servers or blockchain tokens or other points of centralized control. -* We assume that you've at least skimmed [Holochain's Core Concepts](/concepts/1_the_basics/) or are ready to pop over there when needed. +* We assume that you've at least skimmed [Holochain's Learn guide](/learn/1_the_basics/) or are ready to pop over there when needed. * Because Holochain's DNA's are written in Rust, we assume you have at least a basic familiarity with the language. Note, however, that this guide will take you through everything you need to do, step-by-step, so you can follow the steps and learn Rust later. Additionally, Holochain DNAs rarely need to take advantage of the more complicated aspects of the language, so don't let Rust's learning curve scare you. * If you're new to Rust, you can start your learning journey by reading chapters 1 to 11 in the [Rust Book](https://doc.rust-lang.org/book/) and doing the accompanying [Rustlings exercises](https://github.com/rust-lang/rustlings/). * We also assume that you have basic familiarity with the Unix command line. @@ -579,7 +579,7 @@ Just as with a centralized application, we aren't just going to add this data in The bits of shared information that all the peers in a network are holding are collectively called a distributed hash table, or DHT. We'll explain more about the DHT later. -If you want to learn more, check out [The Source Chain: A Personal Data Journal](/concepts/3_source_chain/) and [The DHT: A Shared, Distributed Graph Database](/concepts/4_dht/). You'll also get to see it all in action in a later step, when you run your hApp for the first time. +If you want to learn more, check out [The Source Chain: A Personal Data Journal](/learn/3_source_chain/) and [The DHT: A Shared, Distributed Graph Database](/learn/4_dht/). You'll also get to see it all in action in a later step, when you run your hApp for the first time. !!! @@ -740,9 +740,9 @@ Multiple participants can mark a single entry as updated or deleted at the same **By default, the scaffolding tool generates a `create_' function in your coordinator zome for an entry type** because creating new data is a fundamental part of any application, and it reflects the core principle of Holochain's agent-centric approach --- the ability to make changes to your own application's state. -Similarly, when a public entry is published, it becomes accessible to other agents in the network. Public entries are meant to be shared and discovered by others, so **a `read_' function is provided by default** to ensure that agents can easily access and retrieve publicly shared entries. (The content of _private_ entries, however, are not shared to the network.) For more info on entries, see: the **Core Concepts sections on [Source Chains](/concepts/3_source_chain/) and [DHT](/concepts/4_dht/)**. +Similarly, when a public entry is published, it becomes accessible to other agents in the network. Public entries are meant to be shared and discovered by others, so **a `read_' function is provided by default** to ensure that agents can easily access and retrieve publicly shared entries. (The content of _private_ entries, however, are not shared to the network.) For more info on entries, see the Learn sections on [Source Chains](/learn/3_source_chain/) and [DHT](/learn/4_dht/). -Developers decide whether to let the scaffolding tool generate `update_` and `delete_` functions based on their specific application requirements. More details in the Core Concepts section on [CRUD](/concepts/6_crud_actions/). +Developers decide whether to let the scaffolding tool generate `update_` and `delete_` functions based on their specific application requirements. More details in the Learn section on [CRUD](/learn/6_crud_actions/). !!! @@ -828,7 +828,7 @@ Whereas `EntryHash` is used to uniquely identify, store, and efficiently retriev **Use `AgentPubKey` when** you want to link to an agent (such as associating a profile or icon with them) or retrieve information about their history (such as scanning their source chain for posts and comments). -You can check out the Core Concepts to dive a bit deeper into [how the distributed hash table helps](/concepts/4_dht/) to not only make these entries and actions available but helps to ensure that agents haven't gone back to try and change their own histories after the fact. But for now, let's dive into links. +You can check out the Learn guide to dive a bit deeper into [how the distributed hash table helps](/learn/4_dht/) to not only make these entries and actions available but helps to ensure that agents haven't gone back to try and change their own histories after the fact. But for now, let's dive into links. !!! @@ -900,7 +900,7 @@ After storing the action in the local source chain, the agent then publishes the **Lookup**: To look up and retrieve links in a Holochain app, agents can perform a `get_links` query on a base DHT address. This operation involves asking the DHT peers responsible for that address for any link metadata of a given link type attached to it, with an optional "starts-with" query on the link tag. The peers return a list of links matching the query, which contain the addresses of the targets, and the link types and tags. The agent can then retrieve the actual target data by performing a [`get`](https://docs.rs/hdk/latest/hdk/entry/fn.get.html) query on the target address, which may be an `EntryHash`, `ActionHash`, or `AgentPubKey` (or an empty result, in the case of data that doesn't exist on the DHT). -For more information and examples, read the Core Concepts section on [Links and Anchors](/concepts/5_links_anchors/). +For more information and examples, read the Learn section on [Links and Anchors](/learn/5_links_anchors/). !!! @@ -985,7 +985,7 @@ Hierarchical paths serve another useful purpose. On the DHT, where every node is The examples of granular collections and type-ahead search indexes breaks up those anchors into increasingly smaller branches, so that each leaf node in the tree --- and hence each peer --- only has to store a small number of links. -The scaffolding tool doesn't have any feature for building anchors and trees beyond simple one-anchor collections, but if you'd like to know more, you can read the Core Concepts section on [Links and Anchors](/concepts/5_links_anchors/) and the SDK reference for [`hash_path`](https://docs.rs/hdk/latest/hdk/hash_path/index.html) and [`anchor`](https://docs.rs/hdk/latest/hdk/hash_path/anchor/index.html). +The scaffolding tool doesn't have any feature for building anchors and trees beyond simple one-anchor collections, but if you'd like to know more, you can read the Learn section on [Links and Anchors](/learn/5_links_anchors/) and the SDK reference for [`hash_path`](https://docs.rs/hdk/latest/hdk/hash_path/index.html) and [`anchor`](https://docs.rs/hdk/latest/hdk/hash_path/anchor/index.html). !!! @@ -1015,7 +1015,7 @@ When you start the hApp with `npm start`, this launches Holochain in sandbox mod These application windows allow us to test multiple agents in a Holochain network interacting with one another. It is all running on our one device, but the two conductors behave very much the same as separate agents on different machines would, minus network lag. -Remember that a **conductor** is a Holochain runtime process executing on your computer. For more details see the [Application Architecture](/concepts/2_application_architecture/) section in the Core Concepts guide. +Remember that a **conductor** is a Holochain runtime process executing on your computer. For more details see the [Application Architecture](/learn/2_application_architecture/) section in the Learn guide. These three windows together will let us interact with our hApp as we are building it. @@ -1274,7 +1274,7 @@ For the purpose of this hApp, we're not interested in agent-to-posts relationshi !!! -You may also notice that only Alice's UI showed the new post, while Bob's didn't. Just as with a traditional web app, database changes don't automatically send out a notification to everyone who is interested. (Alice's UI sees the changes because it knows how to update its own state for local changes.) You can create this functionality using a feature called [signals](/concepts/9_signals/), but let's keep things simple for now. Right-click anywhere in Bob's UI then choose "Reload" from the menu, and you'll see that the changes have been copied from Alice's app instance to Bob's --- all without a database server in the middle! +You may also notice that only Alice's UI showed the new post, while Bob's didn't. Just as with a traditional web app, database changes don't automatically send out a notification to everyone who is interested. (Alice's UI sees the changes because it knows how to update its own state for local changes.) You can create this functionality using a feature called [signals](/learn/9_signals/), but let's keep things simple for now. Right-click anywhere in Bob's UI then choose "Reload" from the menu, and you'll see that the changes have been copied from Alice's app instance to Bob's --- all without a database server in the middle! Let's edit that post. In Alice's UI window, click the edit adjacent to the post content (it should look like a pencil icon). The post content will be replaced by an editing form. @@ -1821,7 +1821,7 @@ Now that you have successfully built a basic forum application using Holochain a The official Holochain developer documentation is a valuable resource for deepening your understanding of Holochain concepts, techniques, and best practices. Be sure to explore the documentation thoroughly: -* [Holochain Core Concepts](/concepts/1_the_basics/) +* [Learn Holochain](/learn/1_the_basics/) * [Holochain Developer Kit (HDK) reference](https://docs.rs/hdk/latest/hdk) #### Community resources diff --git a/src/pages/get-started/install-advanced.md b/src/pages/get-started/install-advanced.md index 7e2b5ad44..5791e7622 100644 --- a/src/pages/get-started/install-advanced.md +++ b/src/pages/get-started/install-advanced.md @@ -4,7 +4,7 @@ hide: - toc --- -::: coreconcepts-intro +::: learn-intro This guide assumes that you've already followed the [quick installation guide](/get-started/) and want to learn more about the set up. It describes how to manually recreate and maintain the development environment, use your default shell and preferred code editor with Nix, explains how to install specific versions of Holochain, and discusses why we use `nix develop` in the first place. ::: diff --git a/src/pages/get-started/install-without-nix.md b/src/pages/get-started/install-without-nix.md index 37ee3ef38..fd43b2752 100644 --- a/src/pages/get-started/install-without-nix.md +++ b/src/pages/get-started/install-without-nix.md @@ -4,7 +4,7 @@ hide: - toc --- -::: coreconcepts-intro +::: learn-intro If you ended up here because you ran into problems with the [Nix based quick installation guide](/get-started/), we would greatly appreciate if you let us know what went wrong by [creating a bug report](https://github.com/holochain/docs-pages/issues/new/choose) so that we can look into it. ::: diff --git a/src/pages/get-started/upgrade-holochain.md b/src/pages/get-started/upgrade-holochain.md index a531ebe12..38548d6b0 100644 --- a/src/pages/get-started/upgrade-holochain.md +++ b/src/pages/get-started/upgrade-holochain.md @@ -4,7 +4,7 @@ hide: - toc --- -::: coreconcepts-intro +::: learn-intro For existing hApps that have been written for Holochain version 0.1, these are steps to upgrade to Holochain version 0.2. ::: @@ -72,8 +72,8 @@ whenever you update your Cargo dependencies to the latest HDI/HDK versions. Check if your `flake.nix` still contains the Node.js package that was included by the scaffolding. It will look something like ```nix -packages = [ - pkgs.nodejs-18_x +packages = [ + pkgs.nodejs-18_x ]; ``` diff --git a/src/pages/concepts/10_countersigning.md b/src/pages/learn/10_countersigning.md similarity index 93% rename from src/pages/concepts/10_countersigning.md rename to src/pages/learn/10_countersigning.md index 92d1ab81b..094388f4e 100644 --- a/src/pages/concepts/10_countersigning.md +++ b/src/pages/learn/10_countersigning.md @@ -2,11 +2,11 @@ title: "Countersigning: Reaching Agreement Between Peers" --- -::: coreconcepts-intro +::: learn-intro Although there's no global consensus in a Holochain application, it's sometimes useful for two or more parties to record shared agreements. Countersigning allows them to coordinate the writing of a single entry across all their source chains. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [Differences between Holochain, client/server, and blockchain](#agreement-versus-consensus) @@ -20,7 +20,7 @@ Although there's no global consensus in a Holochain application, it's sometimes A lot of human interactions involve formal transactions of one sort or another. These are usually conducted in a peer-to-peer way --- that is, as an exchange of information among the people who are directly involved. Payments, legal agreements, property transfers, and even chess moves require parties to reach a **shared understanding** of the states of one another's worlds, then coordinate a **shared change** to those states. Because this is such a common pattern, we built it right into Holochain. ::: -![](/assets/img/concepts/10.1-countersigning.png){.sz80p} {.center} +![](/assets/img/learn/10.1-countersigning.png){.sz80p} {.center} ## Agreement versus consensus @@ -45,13 +45,13 @@ In order to safely coordinate the writing of a single new action to both of thei Here's a more in-depth look at this process. Keep in mind that it's meant to be an automated process, finished within a few seconds while Alice and Bob are both online. Any human agreement (such as negotiating meeting times, contract terms, or transaction amount) should happen beforehand. -::: coreconcepts-storysequence +::: learn-storysequence -![](/assets/img/concepts/10.2-entry-exchange.png){.sz80p} {.center} +![](/assets/img/learn/10.2-entry-exchange.png){.sz80p} {.center} Alice and Bob exchange the details needed to create the entry that will be countersigned. -![](/assets/img/concepts/10.3-preflight.png){.sz80p} {.center} +![](/assets/img/learn/10.3-preflight.png){.sz80p} {.center} Alice creates a **preflight request** containing: @@ -61,39 +61,39 @@ Alice creates a **preflight request** containing: * A stub of the action to go along with the entry, which contains its action type and entry type (currently create-entry and update-entry actions can be countersigned; in the future delete-entry, create-link, and delete-link actions will be too) * Optional arbitrary application data -![](/assets/img/concepts/10.4-preflight-send.png){.sz80p} {.center} +![](/assets/img/learn/10.4-preflight-send.png){.sz80p} {.center} Alice sends the preflight request to Bob for approval. (You can implement this any way you like, but a [remote call](../8_calls_capabilities/) is probably the best.) At this stage, it's expected that Bob is able to independently construct the data that will go into the countersigned entry, based perhaps on his history with Alice or the optional application data, to determine whether the request is something he wants to accept. Acceptance could be automated, or it could request Bob's intervention via a signal to his UI. -![](/assets/img/concepts/10.5-preflight-inspection.png){.sz80p} {.center} +![](/assets/img/learn/10.5-preflight-inspection.png){.sz80p} {.center} Bob's conductor attempts to accept the preflight request, which involves checking whether it is possible to write a countersigned record (that is, there are no incomplete countersigning sessions or pending source chain writes, and Alice's specified time window doesn't conflict with Bob's system clock). If everything looks good, Bob's conductor locks his source chain. -![](/assets/img/concepts/10.6-bob-lock.png){.sz80p} {.center} +![](/assets/img/learn/10.6-bob-lock.png){.sz80p} {.center} Bob's conductor produces a **preflight response**, containing his signature on the request and the record ID at which his source chain is currently locked. Bob sends this preflight response back to Alice. -![](/assets/img/concepts/10.7-alice-lock.png){.sz80p} {.center} +![](/assets/img/learn/10.7-alice-lock.png){.sz80p} {.center} Alice receives Bob's preflight response, then tries to generate a preflight response herself from the request she created. Now her own source chain is locked as well. -![](/assets/img/concepts/10.8-countersigning-session.png){.sz80p} {.center} +![](/assets/img/learn/10.8-countersigning-session.png){.sz80p} {.center} Alice compiles both the preflight responses into a **countersigning session** structure, containing the original agreed-upon preflight request and all the responses. She shares it with Bob (again, this could be done with a remote call). -![](/assets/img/concepts/10.9-trial-commit.png){.sz80p} {.center} +![](/assets/img/learn/10.9-trial-commit.png){.sz80p} {.center} Alice and Bob both create the entry to be countersigned on their own machines, which contains both the countersigning session data structure and the app data they'd previously agreed on. Then they do a trial run of committing the entry. -![](/assets/img/concepts/10.10-validate.png){.sz80p} {.center} +![](/assets/img/learn/10.10-validate.png){.sz80p} {.center} At this point Alice and Bob's conductors take over completely from the cells. As with any commit, they attempt to validate the new action. But with a countersigned action, each participant's conductor validates it multiple times --- once from their own perspective, and once from the perspective of all the other parties. This is possible because Alice and Bob both have the same countersigning session data structure, which contains the current states of both of their source chains. If this step didn't happen, DHT validating authorities would [warrant](../7_validation/#invalid-entry) all parties for neglect, not just the one for whom the action was invalid. -![](/assets/img/concepts/10.11-authorities-collect.png){.sz80p} {.center} +![](/assets/img/learn/10.11-authorities-collect.png){.sz80p} {.center} Once validation is finished, Alice and Bob both do a trial run of publishing the operations generated by the new action to the DHT --- but only the [store entry operations](../4_dht/#a-cloud-of-witnesses). The authorities collect the data but don't integrate it into their DHT stores; right now they're simply acting as witnesses who wait until they've seen the operations from both Alice and Bob. -![](/assets/img/concepts/10.12-authorities-distribute.png){.sz80p} {.center} +![](/assets/img/learn/10.12-authorities-distribute.png){.sz80p} {.center} Once the authorities have collected all the data, they send the full set of actions back to both of them. @@ -101,14 +101,14 @@ Once the authorities have collected all the data, they send the full set of acti If Alice and Bob reach the end of the time window without receiving this action set, their conductors discard the new action and unlock their source chains as if nothing had happened. Likewise, the authorities discard the pre-published data if they don't collect all the required signatures within the time window. There is no built-in feature to retry an expired session, but it could be built into the application. !!! -![](/assets/img/concepts/10.13-commit-and-publish.png){.sz80p} {.center} +![](/assets/img/learn/10.13-commit-and-publish.png){.sz80p} {.center} When Alice and Bob's conductors each receive the full set of actions, they finally unlock their source chains, commit the actions, and publish _all_ the resulting operations to the DHT as normal. This creates a permanent, public record of all parts of the transaction. ::: ## Enzymatic countersigning -![](/assets/img/concepts/10.14-enzyme.png){.sz80p} {.center} +![](/assets/img/learn/10.14-enzyme.png){.sz80p} {.center} Normally, counterparties publish their actions to a DHT neighborhood and hope that there are enough honest and reliable validation authorities there to collect and return a full set of signed actions to everyone. But this can put them at risk; if the neighborhood contains authorities who either are malicious, have slow network connections, or have inaccurate clocks, it's possible for some counterparties to see all signatures within the time window while others do not. This would cause some to complete the session and others to back out, leading to inconsistent state on the DHT and even apparent evidence of source chain revisions. @@ -120,7 +120,7 @@ Note that this still carries the same risks as allowing DHT authorities to be wi ## M-of-N optional witnesses -![](/assets/img/concepts/10.15-m-of-n-witnesses.png){.sz80p} {.center} +![](/assets/img/learn/10.15-m-of-n-witnesses.png){.sz80p} {.center} A countersigning session initiator can also nominate **optional witnesses** to sign the transaction. This can be used for anything that requires a quorum of signatures from a larger pool of potential signers, but shouldn't fail if not all signers are available at the same time. The quorum can be specified in the preflight, but it must be greater than 50%. One of the witnesses must be an enzyme who collects all the required and optional signatures, in order to create a definitive list of which optional witnesses participated. diff --git a/src/pages/concepts/11_lifecycle_events.md b/src/pages/learn/11_lifecycle_events.md similarity index 99% rename from src/pages/concepts/11_lifecycle_events.md rename to src/pages/learn/11_lifecycle_events.md index c4a171f71..3f2c245ed 100644 --- a/src/pages/concepts/11_lifecycle_events.md +++ b/src/pages/learn/11_lifecycle_events.md @@ -2,11 +2,11 @@ title: "Lifecycle events: reacting to external triggers" --- -::: coreconcepts-intro +::: learn-intro In the course of its existence, the conductor triggers **lifecycle events**, to which a cell can respond with specially named callbacks. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn * [How to tell the conductor about the entry types your zome defines](#entry-type-definition-callbacks) diff --git a/src/pages/concepts/1_the_basics.md b/src/pages/learn/1_the_basics.md similarity index 97% rename from src/pages/concepts/1_the_basics.md rename to src/pages/learn/1_the_basics.md index 64e63858d..b7e54ac1d 100644 --- a/src/pages/concepts/1_the_basics.md +++ b/src/pages/learn/1_the_basics.md @@ -1,12 +1,12 @@ --- -title: "Holochain Core Concepts: What is Holochain?" +title: "Learn Holochain: What is Holochain?" --- -::: coreconcepts-intro +::: learn-intro Holochain is an open-source application development framework and peer-to-peer networking protocol. It allows you to create **actually serverless applications** with high levels of **security, reliability, and performance**. Every participant runs the application on their own device, creates and stores their own data, and talks directly to other participants. The security of the application is supported by both cryptography and peer accountability. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [The problem with centralized architectures](#the-problem-with-centralized-architectures) @@ -18,7 +18,7 @@ Holochain is an open-source application development framework and peer-to-peer n You'll understand how Holochain is different from centralized architectures, and how this difference can make your applications more robust, secure, and affordable. ::: -![](/assets/img/concepts/1.1-architecture-comparison.png){.sz80p} {.center} +![](/assets/img/learn/1.1-architecture-comparison.png){.sz80p} {.center} ## The problem with centralized architectures diff --git a/src/pages/concepts/2_application_architecture.md b/src/pages/learn/2_application_architecture.md similarity index 95% rename from src/pages/concepts/2_application_architecture.md rename to src/pages/learn/2_application_architecture.md index 325a1a3ad..31d264321 100644 --- a/src/pages/concepts/2_application_architecture.md +++ b/src/pages/learn/2_application_architecture.md @@ -2,10 +2,10 @@ title: Application Architecture --- -::: coreconcepts-intro +::: learn-intro Applications built with Holochain are highly **modular**. This makes it easy to share code and [compose](https://en.wikipedia.org/wiki/Composability) smaller pieces together into larger wholes. Each functional part of a Holochain application, called a **DNA**, has its own application logic, isolated peer-to-peer network, and shared database. -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [Agent-centricity](#agent-centricity) @@ -20,7 +20,7 @@ A good understanding of the components of the tech stack will equip you to archi Perhaps Holochain's most important difference is that applications are completely centered around the individual --- and, because it's made for networked applications, around groups of individuals. The purpose of a Holochain application is to create a network where people (or bots) can interact freely with each other, playing by a shared set of rules. This is possible because everyone, whether human or bot, is **running their own copy of the application** and connecting directly to their peers. -![Four participants, running the same hApp, communicating directly with each other using their copy of the hApp.](/assets/img/concepts/2.1-mutual-execution.png){.sz80p} {.center} +![Four participants, running the same hApp, communicating directly with each other using their copy of the hApp.](/assets/img/learn/2.1-mutual-execution.png){.sz80p} {.center} So the term 'user' doesn't feel quite right for Holochain, where the ones who use the application are also the ones who keep it alive. Let's call them 'agents' --- or better yet, 'participants'. We'll also sometimes call their devices 'nodes' or 'peers' when they're operating within a network. @@ -28,11 +28,11 @@ How do you know other participants are playing by the same rules as you? As we e These data integrity rules create a membrane between a participant and her peers. They define what data she can and can't create, and they help her recognize rule-breakers. -![Four participants using a hApp. A membrane surrounds one participant's hApp, allowing her to safely produce and accept good data, and reject bad data.](/assets/img/concepts/2.2-data-integrity-membrane.png){.sz80p} {.center} +![Four participants using a hApp. A membrane surrounds one participant's hApp, allowing her to safely produce and accept good data, and reject bad data.](/assets/img/learn/2.2-data-integrity-membrane.png){.sz80p} {.center} There's another membrane, which sits between a participant and her copy of the application. The application's public functions define the processes that can be used to access, interpret, and create data, as well as communicate with other participants and applications. Her copy of the application makes those functions available to any client on her machine that wants to act on her behalf, such as a UI or a scheduled script. Those functions are also made available to her peers in the same network so she can delegate some of her agency to them. The application developer can give her tools to control access to these functions using [capability-based security](../8_calls_capabilities/). -![One participant's copy of the hApp. A membrane surrounds her hApp. On her device, three clients are successfully calling the hApp's functions while a malware is rejected. From the network, two peers try to call her hApp's functions; one succeeds while another fails.](/assets/img/concepts/2.3-process-membrane.png){.sz80p} {.center} +![One participant's copy of the hApp. A membrane surrounds her hApp. On her device, three clients are successfully calling the hApp's functions while a malware is rejected. From the network, two peers try to call her hApp's functions; one succeeds while another fails.](/assets/img/learn/2.3-process-membrane.png){.sz80p} {.center} ## Layers of the application stack @@ -46,7 +46,7 @@ Now let's quickly introduce all the terms, so you're familiar with them when you ### Client -![Three clients --- a GUI, a bot running on a schedule, and a shell script --- call a hApp's functions and receive signals from it.](/assets/img/concepts/2.4-client.png){.sz80p} {.center} +![Three clients --- a GUI, a bot running on a schedule, and a shell script --- call a hApp's functions and receive signals from it.](/assets/img/learn/2.4-client.png){.sz80p} {.center} A **client** on the participant's device, such as a UI or utility script, talks to their Holochain conductor and its running hApps via [remote procedure calls (RPCs)](https://en.wikipedia.org/wiki/Remote_procedure_call) over [WebSocket](https://en.wikipedia.org/wiki/WebSocket). A hApp can also send [signals](../9_signals/) back to the client; signals are useful for real-time event notifications. @@ -54,7 +54,7 @@ The client is like the front end of a traditional app and can be written with wh ### Conductor -![A participant's conductor hosts multiple hApps for her, mediating the connections between the hApp and her clients, as well as between the hApp and other participants' conductors running the same hApp.](/assets/img/concepts/2.5-conductor.png){.sz80p} {.center} +![A participant's conductor hosts multiple hApps for her, mediating the connections between the hApp and her clients, as well as between the hApp and other participants' conductors running the same hApp.](/assets/img/learn/2.5-conductor.png){.sz80p} {.center} The hApp is hosted in the participant's **conductor**. It's the runtime that sandboxes and executes hApp code, handles cryptographic signing, manages data flow and storage, and handles connections both locally with clients and remotely with peers. When the conductor receives a function call, it routes it to the right function in the right hApp. @@ -64,13 +64,13 @@ The conductor also has a keyring which manages the participant's cryptographic i ### hApp -![A hApp with roles ready to be populated by cells.](/assets/img/concepts/2.6-happ.png){.sz60p} {.center} +![A hApp with roles ready to be populated by cells.](/assets/img/learn/2.6-happ.png){.sz60p} {.center} A Holochain application or **hApp** is a bundled suite of functionality, such as chat, accounting, or project management. A hApp is often made of multiple components, each providing an aspect of functionality or 'role'. ### Cell -![A hApp with each of its roles populated by zero, one, or more matching cells.](/assets/img/concepts/2.7-cells-in-slots.png){.sz60p} {.center} +![A hApp with each of its roles populated by zero, one, or more matching cells.](/assets/img/learn/2.7-cells-in-slots.png){.sz60p} {.center} **Cells** fill roles in a hApp. Each cell is a combination of a participant's unique cryptographic key pair (their **agent ID**) and a DNA. Within one participant's instance of a hApp, all cells share the same agent ID. Each cell acts as the participant's personal **agent** --- every piece of data that it creates or message it sends, it does so from the [perspective of that agent](../3_source_chain/). @@ -80,7 +80,7 @@ As a bundle of running code, a cell exposes the functions you write as its publi ### DNA -![A cell containing a DNA.](/assets/img/concepts/2.8-dna-in-cell.png){.sz80p} {.center} +![A cell containing a DNA.](/assets/img/learn/2.8-dna-in-cell.png){.sz80p} {.center} The bundle of executable code running in a cell is called a **DNA**. You can think of it like a [microservice](https://en.wikipedia.org/wiki/Microservices) that creates an access and integrity layer around personal and shared data. It serves as the 'rules of the game' against which peers can do validation and enforcement. Each DNA implements the code that fills a particular role in a hApp. @@ -100,7 +100,7 @@ If you're finding it hard to keep cells and DNAs separate in your mind, remember ### Zome -![A close-up of a DNA, showing multiple executable zome modules exposing their public functions.](/assets/img/concepts/2.9-zomes-in-dna.png){.sz80p} {.center} +![A close-up of a DNA, showing multiple executable zome modules exposing their public functions.](/assets/img/learn/2.9-zomes-in-dna.png){.sz80p} {.center} The executable code modules in a DNA are called **zomes** (short for chromosomes), each with its own name like `profile` or `chat`. The zomes define the core logic in a DNA. @@ -121,7 +121,7 @@ All functions in your DNA start with a fresh memory state which is cleared once ## In summary -![The entire stack of one participant's hApp. See following text for full image description.](/assets/img/concepts/2.10-whole-stack.png){.sz80p} {.center} +![The entire stack of one participant's hApp. See following text for full image description.](/assets/img/learn/2.10-whole-stack.png){.sz80p} {.center} That's the entire stack of a Holochain hApp. Let's review, this time from the inside out: diff --git a/src/pages/concepts/3_source_chain.md b/src/pages/learn/3_source_chain.md similarity index 96% rename from src/pages/concepts/3_source_chain.md rename to src/pages/learn/3_source_chain.md index 3898882bf..fb042557f 100644 --- a/src/pages/concepts/3_source_chain.md +++ b/src/pages/learn/3_source_chain.md @@ -2,11 +2,11 @@ title: "The Source Chain: A Personal Data Journal" --- -::: coreconcepts-intro +::: learn-intro Each participant in a Holochain network creates and stores their own data in a journal called a **source chain**. Each journal entry is cryptographically signed by its author and is immutable once written. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [How agent identities are created](#agent-identity) @@ -25,7 +25,7 @@ Let's take a look at one single node and see what's happening from the participa Back in [the basics](..//1_the_basics/), we said that one of Holochain's pillars is 'intrinsic data integrity.' The first stone in this pillar is [**public key cryptography**](https://en.wikipedia.org/wiki/Public-key_cryptography), which allows each participant to create and authenticate her own identifier without a central password database. If you've ever used [SSH](https://en.wikipedia.org/wiki/Secure_Shell), you're already familiar with this. -![](/assets/img/concepts/3.1-key-generation.png){.sz60p} {.center} +![](/assets/img/learn/3.1-key-generation.png){.sz60p} {.center} When you join a hApp's network, you create an identifier for yourself by generating a **public/private key pair**. This key pair does a few things for you: @@ -46,7 +46,7 @@ All your key pairs are stored in an encrypted, password-protected key manager on ## Source chain: your own data store -![](/assets/img/concepts/3.2-source-chain-as-journal.png){.sz60p} {.center} +![](/assets/img/learn/3.2-source-chain-as-journal.png){.sz60p} {.center} The next stone in the pillar is a chronological journal of every action that the participant has performed in her copy of the app --- creating, updating, or deleting public or private data, linking data together, and more. Only she has the authority to write to it; it lives on her device and each entry must be signed by her private key. This journal is called a **source chain** because every piece of data in an app has its origin in someone's journal. @@ -56,9 +56,9 @@ It's most helpful to think of an action as just that --- the _act of changing ap This journal starts with three special system records, followed optionally by some app data, and one final system record: -![](/assets/img/concepts/3.3-genesis-records-1-and-2.png){.sz60p} {.center} +![](/assets/img/learn/3.3-genesis-records-1-and-2.png){.sz60p} {.center} -![](/assets/img/concepts/3.4-genesis-records-3-and-4.png){.sz60p} {.center} +![](/assets/img/learn/3.4-genesis-records-3-and-4.png){.sz60p} {.center} 1. The **DNA hash**. Because the DNA's executable code constitutes the 'rules of the game' for a network of participants, this record claims that your Holochain runtime has seen and is abiding by those rules. 2. The agent's **membrane proof**. When a cell tries to join a network, it shares this entry with the existing peers, who check it and determine whether the cell should be allowed to join them. Examples: an invite code, an employee ID signed by the HR department, or a proof of paid subscription fees. @@ -89,7 +89,7 @@ Finally, when an atomic commit succeeds, the conductor calls an optional **post- If the integrity of your data is so important, what might happen if a third party tried to mess with it en route to your true love or business partner? The answer is, _not much_. Let's take a look at why. -![](/assets/img/concepts/3.5-commit.png){.sz60p} {.center} +![](/assets/img/learn/3.5-commit.png){.sz60p} {.center} 1. When a function in the DNA wants to store a user action, it creates a record containing the details of that action and a reference to the previous record. 2. Then the conductor calls the DNA's validation function for that record. If it fails validation, it returns an error to the client. @@ -101,11 +101,11 @@ This lets us detect [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Ma Let's take a closer look at the action. It includes the hash of the previous action, a timestamp, and the entry's type. -![](/assets/img/concepts/3.6-action.png){.sz80p} {.center} +![](/assets/img/learn/3.6-action.png){.sz80p} {.center} Let's look even more closely at that first line in the action. -![](/assets/img/concepts/3.7-prev-action.png){.sz60p} {.center} +![](/assets/img/learn/3.7-prev-action.png){.sz60p} {.center} This hash is the unique cryptographic 'fingerprint' for the previous record's data. This is what ensures the integrity of the entire source chain. Each record points back to its previous entry. With a paper journal, it's obvious when someone's ripped out a page, glued a new page in, or taped a sheet of paper over an existing page. This chain of hashes is the digital equivalent: if anyone modifies so much as a single character in a record, it and all subsequent records will be invalidated unless they recreate all the hashes and signatures. diff --git a/src/pages/concepts/4_dht.md b/src/pages/learn/4_dht.md similarity index 92% rename from src/pages/concepts/4_dht.md rename to src/pages/learn/4_dht.md index 074297e6d..d84efb2b2 100644 --- a/src/pages/concepts/4_dht.md +++ b/src/pages/learn/4_dht.md @@ -2,11 +2,11 @@ title: "The DHT: A Shared, Distributed Graph Database" --- -::: coreconcepts-intro +::: learn-intro Agents share records of their actions, including any data meant to be shared with the group, in a [**distributed hash table (DHT)**](https://en.wikipedia.org/wiki/Distributed_hash_table). This database provides redundancy and availability for data and gives the network the power to detect and take action against corruption. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [The downsides and risks of self-owned data](#self-owned-data-isn-t-enough) @@ -32,15 +32,15 @@ And finally, in cases where the validity of a given piece of data depends on a b ## The distributed hash table, a public data store -![](/assets/img/concepts/4.1-network.png){.sz80p} {.center} +![](/assets/img/learn/4.1-network.png){.sz80p} {.center} In a Holochain network, you share your source chain actions and public entries with a random selection of your peers, who witness, validate, and hold copies of them. -![](/assets/img/concepts/4.2-public-entry-commit.png){.sz80p} {.center} +![](/assets/img/learn/4.2-public-entry-commit.png){.sz80p} {.center} When you commit a record with private data, the entry data stays in your source chain, but the record's action portion is still shared. -![](/assets/img/concepts/4.3-private-entry-commit.png){.sz80p} {.center} +![](/assets/img/learn/4.3-private-entry-commit.png){.sz80p} {.center} Every DNA has its own private, encrypted network of peers who [**gossip**](https://en.wikipedia.org/wiki/Gossip_protocol) with one another about new peers, new data, integrity breaches, and network health. @@ -61,33 +61,33 @@ Databases that spread their data among a bunch of machines have a performance pr Every peer knows about all of its closest neighbors and a few faraway acquaintances. Using these connections, they can find any other agent in the DHT with just a few hops. This makes it fairly quick to find the data. -![](/assets/img/concepts/4.4-address-space-and-neighborhoods.png){.sz80p} {.center} +![](/assets/img/learn/4.4-address-space-and-neighborhoods.png){.sz80p} {.center} Let's see how this works with a very small address space. Instead of public keys and hashes, we're just going to use letters of the alphabet, where the first letter of a word is its address. -::: coreconcepts-storysequence +::: learn-storysequence -![](/assets/img/concepts/4.5-alice-neighborhood.png){.sz80p} {.center} +![](/assets/img/learn/4.5-alice-neighborhood.png){.sz80p} {.center} Alice lives at address A. Her neighbors to the left are Diana and Fred, and her neighbors to the right are Zoƫ and Walter. -![](/assets/img/concepts/4.7-alice-publish-address-calculation.png){.sz80p} {.center} +![](/assets/img/learn/4.7-alice-publish-address-calculation.png){.sz80p} {.center} Alice creates an entry containing the word "molecule", whose address is M. -![](/assets/img/concepts/4.8-authority-resolution.png){.sz80p} {.center} +![](/assets/img/learn/4.8-authority-resolution.png){.sz80p} {.center} Of all of Alice's neighbors, Fred is closest to that address, so she asks him to store it. Fred hasn't claimed authority for that address, so he tells Alice about his neighbor Louise. -![](/assets/img/concepts/4.9-gossip-publish.png){.sz80p} {.center} +![](/assets/img/learn/4.9-gossip-publish.png){.sz80p} {.center} Alice shares the entry with Louise, who agrees to store it because her neighborhood covers M. -![](/assets/img/concepts/4.10-gossip-resilience.png){.sz80p} {.center} +![](/assets/img/learn/4.10-gossip-resilience.png){.sz80p} {.center} Louise shares it with her neighbor, Norman, in case she goes offline. -![](/assets/img/concepts/4.11-retrieval.png){.sz80p} {.center} +![](/assets/img/learn/4.11-retrieval.png){.sz80p} {.center} Rosie is a word collector who learns that an interesting new word lives at address is M. She asks her neighbor, Norman, if he has it. Louise has already given him a copy, so he delivers it to Rosie. @@ -103,21 +103,21 @@ Using information about their neighbors' uptime, cooperating agents work hard to Let's see how this plays out in the real world. -::: coreconcepts-storysequence +::: learn-storysequence -![](/assets/img/concepts/4.12-healthy-network.png){.sz80p} {.center} +![](/assets/img/learn/4.12-healthy-network.png){.sz80p} {.center} An island is connected to the mainland by a radio link. They communicate with each other using a Holochain app. -![](/assets/img/concepts/4.13-partition.png){.sz80p} {.center} +![](/assets/img/learn/4.13-partition.png){.sz80p} {.center} A hurricane blows through and wipes out both radio towers. The islanders can't talk to the mainlanders, and vice versa, so some DHT neighbors are unreachable. But everyone can still talk to their physical neighbors. None of the data is lost, but not all of it is available to each side. -![](/assets/img/concepts/4.14-resilience-building.png){.sz80p} {.center} +![](/assets/img/learn/4.14-resilience-building.png){.sz80p} {.center} On both sides, all agents attempt to improve resilience by enlarging their arcs. Meanwhile, they operate as usual, talking with one another and creating new data. -![](/assets/img/concepts/4.15-partition-healing.png){.sz80p} {.center} +![](/assets/img/learn/4.15-partition-healing.png){.sz80p} {.center} The radio towers are rebuilt, the network partition heals, and new data syncs up across the DHT. At this point everyone has the option of shrinking their arc sizes and prune overly redundant data (although experience has shown them that it might be best to overcompensate in case another hurricane comes around). diff --git a/src/pages/concepts/5_links_anchors.md b/src/pages/learn/5_links_anchors.md similarity index 93% rename from src/pages/concepts/5_links_anchors.md rename to src/pages/learn/5_links_anchors.md index 1312d29e9..b52e2b57f 100644 --- a/src/pages/concepts/5_links_anchors.md +++ b/src/pages/learn/5_links_anchors.md @@ -2,11 +2,11 @@ title: "Links and Anchors: Connecting DHT Data Together" --- -::: coreconcepts-intro +::: learn-intro Data on the DHT is connected via one-way **links**. They allow you to create a graph database, making information easy to discover. **Anchors** serve as starting points for link discovery. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [Why it's hard to find data in a DHT](#the-difficulty-of-looking-for-data-especially-when-you-don-t-know-what-you-re-looking-for) @@ -21,7 +21,7 @@ DHTs and graph databases are different from familiar data stores, like relationa ## The difficulty of looking for data (especially when you don't know what you're looking for) -![](/assets/img/concepts/5.1-links.png){.sz80p} {.center} +![](/assets/img/learn/5.1-links.png){.sz80p} {.center} Deriving addresses directly from the content of your data has some advantages --- you can ignore the physical location of data and ask for it by its content address. This means no more broken links. It also means that a malicious third party can't sneak something nasty into the data they're serving you --- if it doesn't match the hash or author's signature, it's been tampered with. @@ -67,37 +67,37 @@ Neither the base nor the target of a link need to have any data stored at their Take note of the arrowheads below; you'll see that many are bidirectional. In Holochain, however, a link is unidirectional. This means that, for a bidirectional link, two links must be created in opposite directions to each other. !!! -::: coreconcepts-storysequence +::: learn-storysequence -![](/assets/img/concepts/5.2-alice.png){.sz80p} {.center} +![](/assets/img/learn/5.2-alice.png){.sz80p} {.center} Alice is a singer/songwriter who excels at the ukulele and wants to share her music with the world. She joins the app and chooses to register the username "@alice_ukulele". She checks if it's already been taken by calculating its address and looking for an existing username DHT entry with that address. -![](/assets/img/concepts/5.3-alice-username.png){.sz80p} {.center} +![](/assets/img/learn/5.3-alice-username.png){.sz80p} {.center} That entry doesn't exist, so she creates it and links it to her agent address. Now, users who know her username can find her agent address. -![](/assets/img/concepts/5.4-usernames-anchor.png){.sz80p} {.center} +![](/assets/img/learn/5.4-usernames-anchor.png){.sz80p} {.center} Alice wants to show up in the public directory of artists, so she links her username entry to the "_all_users_" anchor, a string constant that's hard-coded into the app. Now the app can discover her username, along with all others, by retrieving all the links on "_all_users_". -![](/assets/img/concepts/5.5-alice-album.png){.sz80p} {.center} +![](/assets/img/learn/5.5-alice-album.png){.sz80p} {.center} Alice creates an entry for her debut EP album and links it to her agent address. Now listeners who discover her agent address can find the albums she's published. -![](/assets/img/concepts/5.6-album-tracks.png){.sz80p} {.center} +![](/assets/img/learn/5.6-album-tracks.png){.sz80p} {.center} She uploads all the tracks and links them to the album entry. -![](/assets/img/concepts/5.7-album-genres.png){.sz80p} {.center} +![](/assets/img/learn/5.7-album-genres.png){.sz80p} {.center} Now she wants people to be able to find her album by genre, so she selects or creates a few applicable genre tags (they're anchors too) and links her album to them. -![](/assets/img/concepts/5.8-genres-anchor.png){.sz80p} {.center} +![](/assets/img/learn/5.8-genres-anchor.png){.sz80p} {.center} Those genre tags are linked to an "_all_genres_" anchor, another hard-coded constant. Listeners can query this anchor to get the full list of genres. -![](/assets/img/concepts/5.9-graph-database.png){.sz80p} {.center} +![](/assets/img/learn/5.9-graph-database.png){.sz80p} {.center} Alice's entries, now linked to one another and other existing entries on the DHT, form a graph that allows listeners to discover her and her music from a number of different starting points. ::: diff --git a/src/pages/concepts/6_crud_actions.md b/src/pages/learn/6_crud_actions.md similarity index 98% rename from src/pages/concepts/6_crud_actions.md rename to src/pages/learn/6_crud_actions.md index a38ae2546..34dbe8f5b 100644 --- a/src/pages/concepts/6_crud_actions.md +++ b/src/pages/learn/6_crud_actions.md @@ -2,10 +2,10 @@ title: "CRUD Actions: Modifying and Deleting Data" --- -::: coreconcepts-intro +::: learn-intro Holochain allows agents to 'mutate' immutable data by publishing special **delete** and **update** actions to the DHT. -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [Why you can't delete or modify DHT data](#public-immutable-databases) @@ -17,7 +17,7 @@ Holochain allows agents to 'mutate' immutable data by publishing special **delet Immutable public data is a surprising feature of Holochain and many other distributed systems. It's important to understand the consequences in order to make informed design decisions that respect your users' privacy and storage space. ::: -![](/assets/img/concepts/6.1-crud.png){.sz80p} {.center} +![](/assets/img/learn/6.1-crud.png){.sz80p} {.center} ## Public, immutable databases diff --git a/src/pages/concepts/7_validation.md b/src/pages/learn/7_validation.md similarity index 94% rename from src/pages/concepts/7_validation.md rename to src/pages/learn/7_validation.md index e9f8c0f87..ecdcf6c50 100644 --- a/src/pages/concepts/7_validation.md +++ b/src/pages/learn/7_validation.md @@ -2,11 +2,11 @@ title: "Validation: Assuring Data Integrity" --- -::: coreconcepts-intro +::: learn-intro Holochain DNAs can specify **validation rules** for DHT operations. This empowers agents to check the integrity of the data they see. When called upon to validate data, it allows them to identify corrupt peers, author a **warrant** against them as proof of their actions, and take personal defensive action against them. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [Why validation matters](#validation-the-beating-heart-of-holochain) @@ -22,7 +22,7 @@ Holochain DNAs can specify **validation rules** for DHT operations. This empower Data validation rules are the core of a Holochain app. They deserve the bulk of your attention while you're writing your DNA. ::: -![](/assets/img/concepts/7.1-validation.png){.sz80p} {.center} +![](/assets/img/learn/7.1-validation.png){.sz80p} {.center} ## Validation: the beating heart of Holochain @@ -82,40 +82,40 @@ When you **commit a record**, your conductor is responsible for making sure you' #### Valid entry -::: coreconcepts-storysequence -![](/assets/img/concepts/7.2-commit.png){.sz80p} {.center} +::: learn-storysequence +![](/assets/img/learn/7.2-commit.png){.sz80p} {.center} Alice calls the `publish_word` zome function with the string `"eggplant"`. The function commits that word to her source chain. The conductor 'stages' the commit in the function's scratch space and returns the creation action's record hash to the `publish_word` function. The function continues executing and passes a return value back to the conductor, which holds onto it for now. -![](/assets/img/concepts/7.3-validate.png){.sz80p} {.center} +![](/assets/img/learn/7.3-validate.png){.sz80p} {.center} After the function has finished, Alice's conductor [converts this record into DHT operations](../4_dht/#a-cloud-of-witnesses), looks up the integrity zome that defines the `word` entry type, and calls that zome's validation function on each of the operations. -![](/assets/img/concepts/7.4-validation-success.png){.sz80p} {.center} +![](/assets/img/learn/7.4-validation-success.png){.sz80p} {.center} The validation function simply checks that the entry data contained in the action is only one word long, returning `Valid`. -![](/assets/img/concepts/7.5-persist-and-publish.png){.sz80p} {.center} +![](/assets/img/learn/7.5-persist-and-publish.png){.sz80p} {.center} Her conductor commits the entry to her source chain, clears out the scratch space, and passes the `publish_word` function's return value back to the client. The operations are then sent to the appropriate DHT authorities for validation and integration into their shards. ::: #### Invalid entry -::: coreconcepts-storysequence -![](/assets/img/concepts/7.6-commit.png){.sz80p} {.center} +::: learn-storysequence +![](/assets/img/learn/7.6-commit.png){.sz80p} {.center} Alice calls the same zome function with the string `"orca whales"`. Again, the function calls `create_entry` and the commit is staged to the scratch space. -![](/assets/img/concepts/7.7-validate.png){.sz80p} {.center} +![](/assets/img/learn/7.7-validate.png){.sz80p} {.center} Again, the conductor converts the committed action into operations calls the validation function on each of them. -![](/assets/img/concepts/7.8-validation-failure.png){.sz80p} {.center} +![](/assets/img/learn/7.8-validation-failure.png){.sz80p} {.center} This time, the validation function sees two words. It returns `Invalid("too many words")`. -![](/assets/img/concepts/7.9-return-error.png){.sz80p} {.center} +![](/assets/img/learn/7.9-return-error.png){.sz80p} {.center} Instead of committing the entry, the conductor passes this error message back to the client instead of whatever the `publish_word` function's return value was. ::: @@ -130,20 +130,20 @@ Here are the two scenarios above from the perspective of a DHT authority. #### Valid entry -::: coreconcepts-storysequence -![](/assets/img/concepts/7.10-gossip-to-authorities.png){.sz80p} {.center} +::: learn-storysequence +![](/assets/img/learn/7.10-gossip-to-authorities.png){.sz80p} {.center} As authorities for the address `E`, Diana and Fred receive a copy of a store-entry operation that stores the `"eggplant"` entry at that address. -![](/assets/img/concepts/7.11-authorities-validate.png){.sz80p} {.center} +![](/assets/img/learn/7.11-authorities-validate.png){.sz80p} {.center} Their conductors call the appropriate validation function. -![](/assets/img/concepts/7.12-hold.png){.sz80p} {.center} +![](/assets/img/learn/7.12-hold.png){.sz80p} {.center} The operation is valid, so they store the entry and action in their personal DHT stores, along with their **validation receipts** attesting its validity. -![](/assets/img/concepts/7.13-respond-validation-receipts.png){.sz80p} {.center} +![](/assets/img/learn/7.13-respond-validation-receipts.png){.sz80p} {.center} They both send a copy of their receipts back to Alice. Later on, they share the operation with their neighbors for resilience. ::: @@ -156,24 +156,24 @@ You may remember from our [exploration of the DHT](../4_dht/) that the 'store en Let's say Alice has taken off her guard rails --- she's hacked her Holochain software to bypass the validation rules. -::: coreconcepts-storysequence -![](/assets/img/concepts/7.14-gossip-to-authorities.png){.sz80p} {.center} +::: learn-storysequence +![](/assets/img/learn/7.14-gossip-to-authorities.png){.sz80p} {.center} Norman and Rosie receive a copy of Alice's 'store entry' operation for `"orca whales"`. -![](/assets/img/concepts/7.15-validate.png){.sz80p} {.center} +![](/assets/img/learn/7.15-validate.png){.sz80p} {.center} Their conductors call the validation function. -![](/assets/img/concepts/7.16-warrant.png){.sz80p} {.center} +![](/assets/img/learn/7.16-warrant.png){.sz80p} {.center} The operation is invalid. They create, sign, and store a **warrant** (a claim that the operation is invalid). -![](/assets/img/concepts/7.17-gossip-warrant.png){.sz80p} {.center} +![](/assets/img/learn/7.17-gossip-warrant.png){.sz80p} {.center} Norman and Rosie add Alice to their permanent block lists and remove her data from their DHT shards. When anyone asks for the data at the entry's address, they return the warrant instead. -![](/assets/img/concepts/7.18-ejection.png){.sz80p} {.center} +![](/assets/img/learn/7.18-ejection.png){.sz80p} {.center} Eventually, everyone knows that Alice is a 'bad actor' who has hacked her app. They all ignore her whenever she tries to talk to them, which effectively ejects her from the DHT. diff --git a/src/pages/concepts/8_calls_capabilities.md b/src/pages/learn/8_calls_capabilities.md similarity index 95% rename from src/pages/concepts/8_calls_capabilities.md rename to src/pages/learn/8_calls_capabilities.md index e87086f41..7d70c4155 100644 --- a/src/pages/concepts/8_calls_capabilities.md +++ b/src/pages/learn/8_calls_capabilities.md @@ -2,11 +2,11 @@ title: "Calls and Capabilities: Communicate With Other Components And Peers" --- -::: coreconcepts-intro +::: learn-intro Application components can **call a cell's functions**. On one agent's device, clients can call functions in cells, and cells in the same conductor can call each other's functions. Within one DHT, cells can call other agents' cells, allowing agents to delegate their agency to others. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [Who can call whose functions](#client-inter-zome-bridge-and-remote-calls-who-can-call-whom) @@ -18,7 +18,7 @@ Application components can **call a cell's functions**. On one agent's device, c Web 2.0 flourished thanks in part to 'mashups', applications that combined the functionality of multiple publicly accessible APIs in new and creative ways. Holochain enables a richer sharing of functionality and data between apps, anchoring the experience in the end-user's agency. This increases application development velocity and encourages the development of standard, shared component libraries. Remote calls, on the other hand, allow agents in one app to interact privately without publishing any data to the DHT. ::: -![](/assets/img/concepts/8.1-calls.png){.sz80p} {.center} +![](/assets/img/learn/8.1-calls.png){.sz80p} {.center} ## Client, inter-zome, bridge, and remote calls: who can call whom @@ -26,19 +26,19 @@ You might remember from [Application Architecture](../2_application_architecture ### Client call -![](/assets/img/concepts/8.2-client-call.png){.sz80p} {.center} +![](/assets/img/learn/8.2-client-call.png){.sz80p} {.center} An agent makes things happen in her cell by calling one of its public functions through the **app interface**, which is a WebSocket port that the conductor makes available on the agent's device. The thing making the calls is a client of some sort --- a GUI, a shell script, a long-running service, anything that can speak WebSocket. The important thing to remember is that, because the conductor only exposes the app interface on the local machine, the client has to live on the local machine too. This protects the cell from being accessed by anyone other than its owner. ### Inter-zome call -![](/assets/img/concepts/8.3-inter-zome-call.png){.sz80p} {.center} +![](/assets/img/learn/8.3-inter-zome-call.png){.sz80p} {.center} Although zomes are libraries in one DNA, they don't have direct access to each other's functions. They can still call each other, though, via the `call` host function. ### Bridge call -![](/assets/img/concepts/8.4-bridge-call.png){.sz80p} {.center} +![](/assets/img/learn/8.4-bridge-call.png){.sz80p} {.center} A bridge call allows different cells in a hApp to communicate with each other. This works only within a conductor, not across a network, and is useful for combining the functionality of multiple DNAs into one app. Because Holochain is centered around the agent, it makes more sense to say "Alice's app components are talking to each other" than "app A is talking to app B". @@ -46,7 +46,7 @@ As we've seen, a client can talk to cells too, and it could certainly take respo ### Remote call -![](/assets/img/concepts/8.5-remote-call.png){.sz80p} {.center} +![](/assets/img/learn/8.5-remote-call.png){.sz80p} {.center} A remote call allows agents running the same DNA to call each other's functions. When Bob's cell makes a remote call to Alice's cell, it's Alice's cell doing the work, which means that everything that happens --- reads and writes, signals, and even calls to other cells --- _happens from Alice's perspective_. Essentially she's delegating a bit of her agency to him. @@ -65,15 +65,15 @@ At first sight, this seems pretty risky. Giving your agency away to someone else Holochain uses a variation of [capability-based security](https://wikipedia.org/wiki/Capability_based_security) to protect a cell's exposed zome functions. In this model, one agent is in complete control of a resource but can delegate control to another agent via public zome functions protected by 'capability tokens'. While traditional capability-based security doesn't care who's making the call as long as they can produce the token, we've expanded that model a little bit by adding more **access types**: -![](/assets/img/concepts/8.6-unrestricted-capability.png){.sz80p} {.center} +![](/assets/img/learn/8.6-unrestricted-capability.png){.sz80p} {.center} An **unrestricted** capability lets anybody call a function without producing a token. -![](/assets/img/concepts/8.7-transferrable-capability.png){.sz80p} {.center} +![](/assets/img/learn/8.7-transferrable-capability.png){.sz80p} {.center} A **transferable** capability lets anybody call a function if they can present a valid capability token (this is identical to traditional capability-based security). -![](/assets/img/concepts/8.8-assigned-capability.png){.sz80p} {.center} +![](/assets/img/learn/8.8-assigned-capability.png){.sz80p} {.center} An **assigned** capability only allows agents with a valid capability token to call a function, but only if they've signed the call with a recognized public key. @@ -83,7 +83,7 @@ In order to use a transferable or assigned grant, a caller must have already rec #### Author grant -![](/assets/img/concepts/8.9-author-capability.png){.sz80p} {.center} +![](/assets/img/learn/8.9-author-capability.png){.sz80p} {.center} There is one special case: if the public key of the caller and the callee match, such as with calls between zomes in a single DNA, cells in a single hApp, or UIs hosted in the Holochain Launcher, the conductor applies the **author** grant and no explicit capability grant is needed. diff --git a/src/pages/concepts/9_signals.md b/src/pages/learn/9_signals.md similarity index 95% rename from src/pages/concepts/9_signals.md rename to src/pages/learn/9_signals.md index 5d61236b0..4fd78dd42 100644 --- a/src/pages/concepts/9_signals.md +++ b/src/pages/learn/9_signals.md @@ -2,11 +2,11 @@ title: "Signals: Communicating without waiting for a response" --- -::: coreconcepts-intro +::: learn-intro A DNA usually only receives function calls from the outside world and returns a response. But a DNA can also push **signals** to a listening client on the agent's device, or another agent on the same network. ::: -::: coreconcepts-orientation +::: learn-orientation ### What you'll learn 1. [When signals are useful](#when-are-signals-useful) @@ -19,7 +19,7 @@ A DNA usually only receives function calls from the outside world and returns a Signals reduce the need for a client to regularly poll a zome function to retrieve new data, making UIs much more responsive and performant. They can also trigger automatic actions in a cell or client without needing human intervention. ::: -![](/assets/img/concepts/9.1-signals.png){.sz80p} {.center} +![](/assets/img/learn/9.1-signals.png){.sz80p} {.center} ## When are signals useful? @@ -35,7 +35,7 @@ There are two kinds of signals. One goes to the client; the other goes to anothe ### Local signals -![](/assets/img/concepts/9.2-client-signal.png){.sz80p} {.center} +![](/assets/img/learn/9.2-client-signal.png){.sz80p} {.center} When a UI or other client wants to keep up to date on something without initiating any action, they can listen for local signals on the same WebSocket connection they use to make zome calls. The DNA can emit these signals as part of a zome function or other callback. For instance, in [Calls and Capabilities](../8_calls_capabilities/) when Alice calls Bob's `receive_publish_post_permission`, it would be nice to let Bob know he's received that permission. So that function emits a signal to his UI to let him know he's able to publish the article on her behalf now. @@ -43,7 +43,7 @@ You would typically use this in functions that are not called by a client, such ### Remote signals -![](/assets/img/concepts/9.3-remote-signal.png){.sz80p} {.center} +![](/assets/img/learn/9.3-remote-signal.png){.sz80p} {.center} Not every peer-to-peer interaction on the DHT needs a response. In cases where Bob doesn't need to know whether his message was received, he can simply send a signal rather than making a remote call. diff --git a/src/pages/resources/index.md b/src/pages/resources/index.md index 86e33e242..98836013d 100644 --- a/src/pages/resources/index.md +++ b/src/pages/resources/index.md @@ -4,7 +4,7 @@ title: Holochain Programming Resources ## Rust HDK -When you write a Holochain application, the part that lives in Holochain is called a [DNA](../concepts/2_application_architecture/#layers-of-the-application-stack). It runs in a WebAssembly sandbox and talks to the host, or conductor, through the host API. The Rust HDK (Holochain Development Kit) makes it easy for you to write your DNAs in the Rust programming language. +When you write a Holochain application, the part that lives in Holochain is called a [DNA](/learn/2_application_architecture/#layers-of-the-application-stack). It runs in a WebAssembly sandbox and talks to the host, or conductor, through the host API. The Rust HDK (Holochain Development Kit) makes it easy for you to write your DNAs in the Rust programming language. * **[HDK reference](https://docs.rs/hdk){target=_blank}** diff --git a/src/scss/_debug.scss b/src/scss/_debug.scss index 5e8281351..1ad852b28 100644 --- a/src/scss/_debug.scss +++ b/src/scss/_debug.scss @@ -1,8 +1,8 @@ -.h-tile-container, .home-tiles, +.h-tile-container, .home-tiles, // .h-tile, .tile-hero, -.coreconcepts-intro, -.coreconcepts-orientation, +.learn-intro, +.learn-orientation, .h-tile-container-3, .tile-tabs, .tabcontent, .content_linux, .content_macos, .content_windows, .h-author {