├── .cspell ├── custom-words.txt ├── holochain-words.txt ├── template-words.txt └── words-that-should-exist.txt ├── .eleventyignore ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── incorrect-information.md ├── issue_template.md └── workflows │ └── spellcheck.yaml ├── .gitignore ├── 11ty-extensions ├── card-shortcodes.js ├── eleventy-transforms.js ├── index.js ├── layout-block-shortcodes.js ├── markdown-it-config.js └── nunjucks-exts.js ├── 11ty-markdown-changes.md ├── CNAME ├── LICENSE ├── README.md ├── code_test_4 └── web-happ.yaml ├── cspell.json ├── eleventy.config.js ├── netlify.toml ├── package-lock.json ├── package.json ├── rollup.config.js ├── src ├── assets │ ├── files │ │ └── RRDHT-whitepaper-final.pdf │ ├── img │ │ ├── concepts │ │ │ ├── 1.1-architecture-comparison.png │ │ │ ├── 10.1-countersigning.png │ │ │ ├── 10.10-validate.png │ │ │ ├── 10.11-authorities-collect.png │ │ │ ├── 10.12-authorities-distribute.png │ │ │ ├── 10.13-commit-and-publish.png │ │ │ ├── 10.14-enzyme.png │ │ │ ├── 10.15-m-of-n-witnesses.png │ │ │ ├── 10.2-entry-exchange.png │ │ │ ├── 10.3-preflight.png │ │ │ ├── 10.4-preflight-send.png │ │ │ ├── 10.5-preflight-inspection.png │ │ │ ├── 10.6-bob-lock.png │ │ │ ├── 10.7-alice-lock.png │ │ │ ├── 10.8-countersigning-session.png │ │ │ ├── 10.9-trial-commit.png │ │ │ ├── 2.1-mutual-execution.png │ │ │ ├── 2.10-whole-stack.png │ │ │ ├── 2.2-data-integrity-membrane.png │ │ │ ├── 2.3-process-membrane.png │ │ │ ├── 2.4-client.png │ │ │ ├── 2.5-conductor.png │ │ │ ├── 2.6-happ.png │ │ │ ├── 2.7-cells-in-slots.png │ │ │ ├── 2.8-dna-in-cell.png │ │ │ ├── 2.9-zomes-in-dna.png │ │ │ ├── 3.1-key-generation.png │ │ │ ├── 3.2-source-chain-as-journal.png │ │ │ ├── 3.3-genesis-records-1-and-2.png │ │ │ ├── 3.4-genesis-records-3-and-4.png │ │ │ ├── 3.5-commit.png │ │ │ ├── 3.6-action.png │ │ │ ├── 3.7-prev-action.png │ │ │ ├── 4.1-network.png │ │ │ ├── 4.10-gossip-resilience.png │ │ │ ├── 4.11-retrieval.png │ │ │ ├── 4.12-healthy-network.png │ │ │ ├── 4.13-partition.png │ │ │ ├── 4.14-resilience-building.png │ │ │ ├── 4.15-partition-healing.png │ │ │ ├── 4.2-public-entry-commit.png │ │ │ ├── 4.3-private-entry-commit.png │ │ │ ├── 4.4-address-space-and-neighborhoods.png │ │ │ ├── 4.5-alice-neighborhood.png │ │ │ ├── 4.7-alice-publish-address-calculation.png │ │ │ ├── 4.8-authority-resolution.png │ │ │ ├── 4.9-gossip-publish.png │ │ │ ├── 5.1-links.png │ │ │ ├── 5.2-alice.png │ │ │ ├── 5.3-alice-username.png │ │ │ ├── 5.4-usernames-anchor.png │ │ │ ├── 5.5-alice-album.png │ │ │ ├── 5.6-album-tracks.png │ │ │ ├── 5.7-album-genres.png │ │ │ ├── 5.8-genres-anchor.png │ │ │ ├── 5.9-graph-database.png │ │ │ ├── 6.1-crud.png │ │ │ ├── 7.1-validation.png │ │ │ ├── 7.10-gossip-to-authorities.png │ │ │ ├── 7.11-authorities-validate.png │ │ │ ├── 7.12-hold.png │ │ │ ├── 7.13-respond-validation-receipts.png │ │ │ ├── 7.14-gossip-to-authorities.png │ │ │ ├── 7.15-validate.png │ │ │ ├── 7.16-warrant.png │ │ │ ├── 7.17-gossip-warrant.png │ │ │ ├── 7.18-ejection.png │ │ │ ├── 7.2-commit.png │ │ │ ├── 7.3-validate.png │ │ │ ├── 7.4-validation-success.png │ │ │ ├── 7.5-persist-and-publish.png │ │ │ ├── 7.6-commit.png │ │ │ ├── 7.7-validate.png │ │ │ ├── 7.8-validation-failure.png │ │ │ ├── 7.9-return-error.png │ │ │ ├── 8.1-calls.png │ │ │ ├── 8.2-client-call.png │ │ │ ├── 8.3-inter-zome-call.png │ │ │ ├── 8.4-bridge-call.png │ │ │ ├── 8.5-remote-call.png │ │ │ ├── 8.6-unrestricted-capability.png │ │ │ ├── 8.7-transferrable-capability.png │ │ │ ├── 8.8-assigned-capability.png │ │ │ ├── 8.9-author-capability.png │ │ │ ├── 9.1-signals.png │ │ │ ├── 9.2-client-signal.png │ │ │ └── 9.3-remote-signal.png │ │ ├── favicon.ico │ │ ├── get-started │ │ │ ├── 1-running-app-first-look.png │ │ │ ├── 10-comment-components.png │ │ │ ├── 2-look-for-hellos.png │ │ │ ├── 3-two-uis-and-playground.png │ │ │ ├── 4-no-posts-found.png │ │ │ ├── 5-create-post-component.png │ │ │ ├── 6-playground-first-post.png │ │ │ ├── 7-edit-post.png │ │ │ ├── 8-playground-after-edits.png │ │ │ └── 9-playground-after-delete.png │ │ ├── google-chrome.png │ │ ├── google-chrome.webp │ │ ├── holochain-gym.jpg │ │ ├── holochain-logo-black-1300.png │ │ ├── holochain-logo-black-1300.webp │ │ ├── holochain-logo-black.png │ │ ├── holochain-logo-black.webp │ │ ├── holochain-logo-small.png │ │ ├── holochain-logo-white.png │ │ ├── icon-apple.svg │ │ ├── icon-linux.svg │ │ ├── icon-windows.svg │ │ ├── logo_light-2x.png │ │ └── playground-simulator.jpg │ └── webFonts │ │ ├── URWFormBold │ │ ├── font.woff │ │ └── font.woff2 │ │ ├── URWFormBoldItalic │ │ ├── font.woff │ │ └── font.woff2 │ │ ├── URWFormExtraBold │ │ ├── font.woff │ │ └── font.woff2 │ │ ├── URWFormExtraBoldItalic │ │ ├── font.woff │ │ └── font.woff2 │ │ ├── URWFormItalic │ │ ├── font.woff │ │ └── font.woff2 │ │ └── URWFormRegular │ │ ├── font.woff │ │ └── font.woff2 ├── client-side │ ├── index.ts │ ├── page-search.ts │ └── types.d.ts ├── custom │ ├── icon-apple.svg │ ├── icon-linux.svg │ ├── icon-windows.svg │ ├── script.js │ └── style.css ├── pages │ ├── 404.njk │ ├── _data │ │ ├── eleventyComputed.js │ │ ├── navigation.js │ │ └── navigation │ │ │ ├── footerLinks.json5 │ │ │ ├── headerNav.json5 │ │ │ └── mainNav.json5 │ ├── _includes │ │ ├── base-layout.njk │ │ ├── default-page-layout.njk │ │ ├── ds-layout.njk │ │ ├── parts │ │ │ ├── footer.njk │ │ │ ├── head.njk │ │ │ ├── header.njk │ │ │ └── templates.njk │ │ └── widgets │ │ │ ├── analytics.njk │ │ │ ├── assorted-bits.njk │ │ │ ├── home-tiles.njk │ │ │ ├── navigation.njk │ │ │ ├── svg-icons.njk │ │ │ └── unsupported-brower-warning.njk │ ├── build │ │ ├── application-structure.md │ │ ├── callbacks-and-lifecycle-hooks.md │ │ ├── calling-zome-functions.md │ │ ├── capabilities.md │ │ ├── cell-introspection.md │ │ ├── cloning.md │ │ ├── connecting-a-front-end.md │ │ ├── connecting-the-parts.md │ │ ├── crud-patterns.md │ │ ├── cryptography-functions.md │ │ ├── dht-operations.md │ │ ├── dnas.md │ │ ├── entries.md │ │ ├── genesis-self-check-callback.md │ │ ├── happs.md │ │ ├── identifiers.md │ │ ├── index.md │ │ ├── links-paths-and-anchors.md │ │ ├── miscellaneous-host-functions.md │ │ ├── must-get-host-functions.md │ │ ├── querying-source-chains.md │ │ ├── signals.md │ │ ├── using-the-host-api.md │ │ ├── validate-callback.md │ │ ├── validation-receipts.md │ │ ├── validation.md │ │ ├── working-with-data.md │ │ ├── zome-functions.md │ │ └── zomes.md │ ├── concepts │ │ ├── 10_countersigning.md │ │ ├── 11_lifecycle_events.md │ │ ├── 1_the_basics.md │ │ ├── 2_application_architecture.md │ │ ├── 3_source_chain.md │ │ ├── 4_dht.md │ │ ├── 5_links_anchors.md │ │ ├── 6_crud_actions.md │ │ ├── 7_validation.md │ │ ├── 8_calls_capabilities.md │ │ └── 9_signals.md │ ├── ds │ │ ├── code-fences.md │ │ ├── containers.md │ │ └── index.md │ ├── favicon.ico │ ├── get-involved.md │ ├── get-started │ │ ├── 2-hello-world.md │ │ ├── 3-forum-app-tutorial.md │ │ ├── 4-packaging-and-distribution.md │ │ ├── at-an-event.md │ │ ├── distribute-your-app.md │ │ ├── index.md │ │ ├── install-advanced.md │ │ └── install-without-nix.md │ ├── index.njk │ ├── pages.json │ ├── resources │ │ ├── glossary.md │ │ ├── index.md │ │ └── upgrade │ │ │ ├── index.md │ │ │ ├── upgrade-holochain-0.2.md │ │ │ ├── upgrade-holochain-0.3.md │ │ │ ├── upgrade-holochain-0.4.md │ │ │ ├── upgrade-holochain-0.5.md │ │ │ └── upgrade-new-holonix.md │ └── search.njk └── scss │ ├── _base-element-styles.scss │ ├── _debug.scss │ ├── _fonts.scss │ ├── _footer.scss │ ├── _header.scss │ ├── _mermaid-diagrams.scss │ ├── _navigation.scss │ ├── _svg-icons.scss │ ├── _values.scss │ ├── _widgets.scss │ ├── page-specific │ ├── _default-page-type.scss │ ├── _ds-layout-type.scss │ ├── _home.scss │ ├── _install.scss │ └── _search.scss │ └── site.scss └── tsconfig.json /.cspell/custom-words.txt: -------------------------------------------------------------------------------- 1 | # Words that are neither common nor directly related to Holochain but appear in 2 | # Dev Portal content 3 | adwaita 4 | agent-centricity 5 | Anwaar 6 | Automerge 7 | automerge 8 | binaryen 9 | buildinputs 10 | builtins 11 | Brisebois 12 | Burmeister 13 | Cachix 14 | cdylib 15 | CRDT 16 | d'Aoust 17 | Diffie 18 | ECDH 19 | fixt 20 | gnused 21 | Hellerstein 22 | imdb 23 | IMDB 24 | identicon 25 | identicons 26 | iostream 27 | iostreams 28 | IPFS 29 | keccak 30 | keypair 31 | Kleppmann 32 | libasound 33 | libatk 34 | libcups 35 | libgtk 36 | libnss 37 | libsodium 38 | libsodium's 39 | Multihash 40 | multihash 41 | NixOS 42 | nixpkgs 43 | pkgs 44 | POSIX 45 | pubkey 46 | QUIC 47 | rustc 48 | rustflags 49 | rustup 50 | secretbox 51 | seedable 52 | setgid 53 | setuid 54 | struct 55 | structs 56 | subl 57 | Tauri 58 | Ulhaq 59 | Wahlstrom 60 | wamr 61 | WASI 62 | WASM 63 | Wasmer 64 | wasmer 65 | WebRTC 66 | webview 67 | webviews 68 | workdir 69 | # Some annoying bits of a hash in a code sample 70 | Evxr 71 | OIGW 72 | Jagd 73 | Slmaip -------------------------------------------------------------------------------- /.cspell/holochain-words.txt: -------------------------------------------------------------------------------- 1 | # Words that are distinctly Holochainy 2 | Darksoil 3 | DeepKey 4 | dnas 5 | dpki 6 | DPKI 7 | hApp 8 | hApps 9 | hcterm 10 | # Apparently abbrevs don't get a pass if they're possessive. 11 | HDK's 12 | Holo 13 | Holo's 14 | Holochain 15 | Holochain's 16 | Holonix 17 | kitsune 18 | Lightningrod 19 | memproof 20 | memproofs 21 | Mythosthesia 22 | sharded 23 | Snapmail 24 | Tryorama 25 | unsharded 26 | webhapp 27 | zome 28 | zome's 29 | zomes 30 | zomes' -------------------------------------------------------------------------------- /.cspell/template-words.txt: -------------------------------------------------------------------------------- 1 | # Words found in our template code 2 | brower 3 | # Silly thing that pops up in Mermaid diagrams 4 | CAID 5 | coreconcepts 6 | elif 7 | endfor 8 | endlayoutblock 9 | endlink 10 | endmacro 11 | endrenderlayoutblock 12 | gtag 13 | # Silly thing that pops up in Mermaid diagrams 14 | kafe 15 | katex 16 | layoutblock 17 | MSIE 18 | newblock 19 | pagefind 20 | rocketship 21 | renderlayoutblock 22 | srcset 23 | storystep 24 | surpress 25 | -------------------------------------------------------------------------------- /.cspell/words-that-should-exist.txt: -------------------------------------------------------------------------------- 1 | # Common words that should appear in the default dictionaries but don't 2 | affordance 3 | affordances 4 | automations 5 | backlink 6 | backlinks 7 | birthdate 8 | chrono 9 | composability 10 | counterparties 11 | counterparties' 12 | counterparty 13 | counterparty's 14 | filesystem 15 | filesystems 16 | hashable 17 | howto 18 | howtos 19 | ified 20 | interoperating 21 | lifecycle 22 | lifecycles 23 | passcode 24 | permissioned 25 | permissivity 26 | redistributable 27 | reserialize 28 | runtimes 29 | sandboxed 30 | sandboxing 31 | scaffolder 32 | snapshotted 33 | spacebar 34 | todo 35 | todos 36 | unforgeable 37 | uninstallation 38 | uninstantiated 39 | unvalidated -------------------------------------------------------------------------------- /.eleventyignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .history/ 3 | _site/ -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: A Holochain tool is not working 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. Ubuntu 18.2] 28 | - Holochain version `holochain --version` 29 | - HC version `hc --version` 30 | - HDK version [e.g. inside my_app/zomes/my_zome/code/Cargo.toml `hdk = "0.0.38-alpha14" 31 | `] 32 | 33 | **Additional context** 34 | Add any other context about the problem here. 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/incorrect-information.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Incorrect information 3 | about: Something in our documentation is incorrect 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## What is incorrect 11 | 12 | ## Link to page 13 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### What is the URL of the page with the issue? 2 | 3 | ### What specific instruction was incorrect, or did not work for you? 4 | 5 | ### What are the details of your platform? 6 | Operating System: 7 | Computer Model: 8 | -------------------------------------------------------------------------------- /.github/workflows/spellcheck.yaml: -------------------------------------------------------------------------------- 1 | name: 'Check spelling' 2 | on: # rebuild any PRs and main branch changes 3 | pull_request: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | spellcheck: # run the action 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - name: 'Get dictionaries' 14 | run: | 15 | npm install @cspell/dict-lorem-ipsum 16 | npm install @cspell/dict-rust 17 | - uses: streetsidesoftware/cspell-action@v5 18 | with: 19 | root: 'src' 20 | files: '**/*.{json5,njk,md}' 21 | incremental_files_only: false 22 | 23 | ci_pass: 24 | if: ${{ always() }} 25 | runs-on: "ubuntu-latest" 26 | needs: 27 | - spellcheck 28 | steps: 29 | - name: check status 30 | uses: re-actors/alls-green@release/v1 31 | with: 32 | jobs: ${{ toJSON(needs) }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | _site 3 | # Local Netlify folder 4 | .netlify 5 | 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # TypeScript v1 declaration files 50 | typings/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Microbundle cache 62 | .rpt2_cache/ 63 | .rts2_cache_cjs/ 64 | .rts2_cache_es/ 65 | .rts2_cache_umd/ 66 | 67 | # Optional REPL history 68 | .node_repl_history 69 | 70 | # Output of 'npm pack' 71 | *.tgz 72 | 73 | # Yarn Integrity file 74 | .yarn-integrity 75 | 76 | # dotenv environment variables file 77 | .env 78 | .env.test 79 | 80 | # parcel-bundler cache (https://parceljs.org/) 81 | .cache 82 | 83 | # Next.js build output 84 | .next 85 | 86 | # Nuxt.js build / generate output 87 | .nuxt 88 | dist 89 | 90 | # Gatsby files 91 | .cache/ 92 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 93 | # https://nextjs.org/blog/next-9-1#public-directory-support 94 | # public 95 | 96 | # vuepress build output 97 | .vuepress/dist 98 | 99 | # Serverless directories 100 | .serverless/ 101 | 102 | # FuseBox cache 103 | .fusebox/ 104 | 105 | # DynamoDB Local files 106 | .dynamodb/ 107 | 108 | # TernJS port file 109 | .tern-port 110 | 111 | # My 11ty specifics 112 | _site/ 113 | client-side-compiled/ 114 | styles-compiled/ 115 | 116 | # A place to put a local scaffolded DNA so you can test code for the build guide 117 | # without having to have two projects/folderss open in your editor. 118 | code_test*/ 119 | -------------------------------------------------------------------------------- /11ty-extensions/card-shortcodes.js: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | 4 | export default function(eleventyConfig) { 5 | 6 | /** 7 | * Returns markup for a link tile card 8 | * @param href The url to set the href of the link to 9 | * @param classStringAddition (Optional) Class names to add to the card 10 | * @param iconPath (Optional) src relative path to the SVG icon file to insert into the head-space 11 | */ 12 | eleventyConfig.addPairedShortcode('linkTile', function(content, href, classStringAddition = null, iconPath = "") { 13 | const addedClassString = !!classStringAddition ? `link-tile ${classStringAddition}` : "link-tile"; 14 | 15 | let optionalSvgTag = ""; 16 | if (!!iconPath) { 17 | if (path.extname(iconPath) != '.svg') { 18 | throw new Error("linkTile shortcode can only render an svg icon"); 19 | } 20 | 21 | let conditionedFilePath = iconPath; 22 | if (iconPath.indexOf(".") !== 0) { 23 | const srcDir = `${eleventyConfig.dir.input}/` 24 | conditionedFilePath = `${srcDir}/${iconPath}`; 25 | } 26 | 27 | const svgData = fs.readFileSync(conditionedFilePath); 28 | optionalSvgTag = svgData.toString(); 29 | } 30 | 31 | return ` 32 |
${optionalSvgTag}
33 |
${content}
34 |
`; 35 | }); 36 | }; -------------------------------------------------------------------------------- /11ty-extensions/eleventy-transforms.js: -------------------------------------------------------------------------------- 1 | // The posthtml package just exports a function that receives a list of plugins 2 | // and returns a PostHTML engine instance. We're adding plugins later, so we 3 | // just call the function. 4 | import postHtmlSetup from "posthtml"; 5 | const postHtml = postHtmlSetup(); 6 | import htmlMin from "html-minifier-terser"; 7 | import { noopener } from "posthtml-noopener"; 8 | import dom from "fauxdom"; 9 | import he from "he"; 10 | import hljsOrig from "highlight.js"; 11 | // Add Svelte language formatting support to highlight.js 12 | import svelte from "highlight.svelte/dist/index.mjs"; 13 | hljsOrig.registerLanguage('svelte', svelte); 14 | // Allow diff *and* original highlighting language 15 | import hljsCodeDiff from "highlightjs-code-diff"; 16 | const hljs = hljsCodeDiff(hljsOrig); 17 | 18 | export default function(eleventyConfig) { 19 | 20 | eleventyConfig.addTransform("addRelNoopener", async function(content) { 21 | const noopenerInst = noopener(); 22 | 23 | if (this.page.outputPath.endsWith(".html")) { 24 | const result = await postHtml.use(noopenerInst).process(content); 25 | return result.html; 26 | } 27 | 28 | return content; 29 | }); 30 | 31 | eleventyConfig.addTransform("htmlmin", async function(content) { 32 | if (this.page.outputPath.endsWith(".html")) { 33 | return htmlMin.minify(content, { 34 | useShortDoctype: true, 35 | removeComments: true, 36 | collapseWhitespace: true, 37 | minifyJS: true, 38 | minifyCSS: true 39 | }); 40 | } 41 | 42 | return content; 43 | }); 44 | 45 | eleventyConfig.addTransform("highlight", async function(content) { 46 | if (this.page.outputPath.endsWith(".html")) { 47 | const document = new dom(content); 48 | const preBlocks = document.querySelectorAll('pre:has(code)'); 49 | preBlocks.forEach((pre) => { 50 | pre.className += ' hljs-container'; 51 | const code = pre.querySelector('code'); 52 | const maybeLanguage = code.className.match(/(?<=\blanguage-)[\:A-Za-z0-9_-]+/); 53 | let blockText = he.decode(code.textContent); 54 | // Erase cspell directives from sample code. 55 | blockText = blockText.replace(/(#|\/\/|\/\*)\s+(cspell|spell-?checker):\s*[a-z-]+(\s+\*\/)?/gmi, ""); 56 | if (maybeLanguage) { 57 | if (maybeLanguage[0].substring(0, 5) == 'diff:') { 58 | // This is a diff, and we want to show it differently -- 59 | // add tabs that let you switch between diff and final version. 60 | 61 | // First, make a copy of the code block. 62 | const preForAppliedDiff = pre.cloneNode(true); 63 | const codeForAppliedDiff = preForAppliedDiff.querySelector('code'); 64 | 65 | // Then find its target language. We don't check whether there's a 66 | // match because we already know there is. 67 | const languageForAppliedDiff = codeForAppliedDiff.className.match(/(?<=\blanguage-diff:)[A-Za-z0-9_-]+/)[0]; 68 | 69 | // Change the language class name of the new code block so it's 70 | // not a diff anymore. 71 | codeForAppliedDiff.className = codeForAppliedDiff.className.replace(`language-diff:`, `language-`); 72 | 73 | // Apply the diff. 74 | const diffAppliedCode = blockText 75 | .split(/\r?\n/) 76 | .reduce( 77 | (acc, line) => { 78 | if ([" ", "+"].includes(line.substring(0, 1))) { 79 | acc = `${acc ? acc + "\n" : acc}${line.substring(1)}`; 80 | } 81 | return acc; 82 | }, 83 | "" 84 | ); 85 | 86 | // Replace the raw code with the highlighted, diff-applied code. 87 | codeForAppliedDiff.innerHTML = hljs.highlight(diffAppliedCode, {language: languageForAppliedDiff}).value; 88 | codeForAppliedDiff.className += ' hljs'; 89 | 90 | // And highlight the original diff using diff+language highlighting. 91 | code.innerHTML = hljs.highlight(blockText, {language: maybeLanguage[0]}).value; 92 | code.className += ' hljs'; 93 | 94 | // Now that we've got both of them, put them in a container that 95 | // lets us tab between the two of them. 96 | pre.classList.add("diff-diff"); 97 | preForAppliedDiff.classList.add("diff-final"); 98 | const tabContainer = document.createElement('div'); 99 | tabContainer.className = "diff-container"; 100 | tabContainer.innerHTML = ` 101 |
102 | 103 |
104 |
${pre.outerHTML}
105 |
${preForAppliedDiff.outerHTML}
106 | `; 107 | 108 | // Now replace the original code block with the diff+applied version. 109 | pre.replaceWith(tabContainer); 110 | } else { 111 | code.innerHTML = hljs.highlight(blockText, {language: maybeLanguage[0]}).value; 112 | } 113 | } else { 114 | code.innerHTML = hljs.highlightAuto(blockText).value; 115 | } 116 | code.className += ' hljs'; 117 | }); 118 | return document.innerHTML; 119 | } 120 | return content; 121 | }); 122 | }; -------------------------------------------------------------------------------- /11ty-extensions/index.js: -------------------------------------------------------------------------------- 1 | import CustomMarkdownIt from "./markdown-it-config.js"; 2 | import LayoutBlockShortcodes from "./layout-block-shortcodes.js"; 3 | import CardShortcodes from "./card-shortcodes.js"; 4 | import NunjucksExt from "./nunjucks-exts.js"; 5 | import Transforms from "./eleventy-transforms.js"; 6 | 7 | export default function(eleventyConfig) { 8 | // The markdown-it-config.js file isn't set up as an Eleventy extension. 9 | // Instead, it just loads up Markdown-it and adds extensions, then exports 10 | // that extended config. This is so it can be used by both Eleventy here, and 11 | // by the TOC generator in /src/pages/_data/eleventyComputed.js 12 | eleventyConfig.setLibrary("md", CustomMarkdownIt); 13 | LayoutBlockShortcodes(eleventyConfig); 14 | CardShortcodes(eleventyConfig); 15 | NunjucksExt(eleventyConfig); 16 | Transforms(eleventyConfig); 17 | }; -------------------------------------------------------------------------------- /11ty-extensions/layout-block-shortcodes.js: -------------------------------------------------------------------------------- 1 | export default function(eleventyConfig) { 2 | const layoutBlockContent = {}; 3 | 4 | /** 5 | * Stores the content for a layout block for a given page. 6 | * @param {string} blockName Name of block 7 | * @param {*} page Page object 8 | * @param {string} content 9 | */ 10 | const storeLayoutContent = (blockName, page, content) => { 11 | layoutBlockContent[blockName] = layoutBlockContent[blockName] || {}; 12 | layoutBlockContent[blockName][page.inputPath] = content; 13 | }; 14 | 15 | const getLayoutContent = (blockName, page, defaultContent = "") => { 16 | const contentForBlockName = layoutBlockContent[blockName]; 17 | const contentForBlockNameOnPage = contentForBlockName ? contentForBlockName[page.inputPath] : null; 18 | return contentForBlockNameOnPage || defaultContent; 19 | }; 20 | 21 | /** 22 | * Called in Layout to render page specified content 23 | * @param {string} content The slot data in the pair. Used as default. Can be empty. 24 | * @param {string} name Layout Block name 25 | */ 26 | eleventyConfig.addPairedShortcode('renderlayoutblock', function(content, name) { 27 | //console.log('renderlayoutblock', name, this.page); 28 | 29 | return getLayoutContent(name, this.page, content); 30 | }); 31 | 32 | 33 | /** 34 | * Called in page to specify content to insert into block in layout creagted with renderlayoutblock. 35 | * @param {string} content 36 | * @param {string} name Layout Block name 37 | */ 38 | eleventyConfig.addPairedShortcode('layoutblock', function(content, name) { 39 | //console.log('layoutblock', this.page); 40 | 41 | storeLayoutContent(name, this.page, content); 42 | return ''; 43 | }); 44 | }; -------------------------------------------------------------------------------- /11ty-extensions/markdown-it-config.js: -------------------------------------------------------------------------------- 1 | import markdownIt from "markdown-it"; 2 | import markdownItAttrs from "markdown-it-attrs"; 3 | import markdownItContainer from "markdown-it-container"; 4 | import markdownItAnchor from "markdown-it-anchor"; 5 | import slugify from '@sindresorhus/slugify'; 6 | 7 | // This config is shared by Eleventy and by the TOC generator in /src/pages/_data/eleventyComputed.js 8 | // which is why it has no Eleventy stuff in it like the other files in this 9 | // folder. 10 | 11 | /** 12 | * Composes the attributes string for an html tag from the markdown-it-container token and default attributes 13 | * @param {*} token token from markdown-it-container 14 | * @param {*} defaultAttrs attributes to be merged in with token.attrs 15 | * @returns attributes string for the html tag 16 | */ 17 | function composeAttributeString(token, defaultAttrs ={}) { 18 | //convert token.attrs to an object and merge with defaultAttrs 19 | const attrs = token.attrs ? token.attrs.reduce((acc, attr) => { acc[attr[0]] = attr[1]; return acc; }, {}) : {}; 20 | const mergedAttrs = Object.assign({}, defaultAttrs, attrs); 21 | 22 | return Object.keys(mergedAttrs).reduce((acc, key) => acc + ` ${key}="${mergedAttrs[key]}"`, ""); 23 | } 24 | 25 | /* Start Admonition code */ 26 | 27 | function generateContainerTitleRegex(blockName) { 28 | return new RegExp("^" + blockName + "\\s+(.*)$"); 29 | } 30 | 31 | const renderAdmonition = (name, tokens, idx) => { 32 | const titleMatcher = tokens[idx].info.trim().match(generateContainerTitleRegex(name)); 33 | const nameCapitalized = name.charAt(0).toUpperCase() + name.slice(1); 34 | const title = titleMatcher ? titleMatcher[1] : (nameCapitalized); 35 | 36 | //If the opening tag 37 | if(tokens[idx].nesting === 1) { 38 | const titleTag = title ? `

${ title }

` : ''; 39 | const attrString = composeAttributeString(tokens[idx], { class: `admonition ${name}` }); 40 | 41 | return `
${titleTag}` + '\n\n
'; 42 | } else { 43 | return '\n
\n'; 44 | } 45 | }; 46 | 47 | /** 48 | * Wires up a generic markdownItContainer render function for a specified admonition. 49 | * @param {string} admonitionName The "tag" of the admonition to be rendered 50 | * @returns render function for the admonition type that works with markdownItContainer 51 | */ 52 | function composeGenericAdmonitionRenderFunc(admonitionName) { 53 | return function(tokens, idx) { return renderAdmonition(admonitionName, tokens, idx); } 54 | } 55 | 56 | /* End Admonition code */ 57 | 58 | /* Start Details Block code */ 59 | 60 | function composeDetailsBlockRenderFunc(blockName = "details") { 61 | return function(tokens, idx) { return renderDetailsBlock(blockName, tokens, idx); } 62 | } 63 | 64 | const renderDetailsBlock = (blockName, tokens, idx) => { 65 | if(tokens[idx].nesting === 1) { 66 | const summary = tokens[idx].info.trim().match(generateContainerTitleRegex(blockName)); 67 | const attrDefaults = { id: slugify(summary[1]) }; 68 | if (blockName) { 69 | attrDefaults['class'] = `details ${blockName}`; 70 | } 71 | const attrString = composeAttributeString(tokens[idx], attrDefaults); 72 | 73 | const summaryTag = summary ? `${ summary[1] }` : ''; 74 | return `
${summaryTag}` + '\n\n
'; 75 | } else { 76 | return '\n
\n'; 77 | } 78 | }; 79 | 80 | const validateDetailsBlock = (params) => { 81 | const validationResults = params.trim().match(/^details\s+(.*)$/); 82 | return validationResults; 83 | } 84 | 85 | /* End Details Block code */ 86 | 87 | // Set up the Markdown-it parser here. 88 | 89 | const mdLib = markdownIt(); 90 | 91 | // Set up sane defaults; most of these are borrowed from 11ty's defaults. 92 | mdLib.set({ 93 | html: true, 94 | linkify: true, 95 | typographer: true 96 | }); 97 | mdLib.disable("code"); 98 | 99 | //Configure markdown-it plugins 100 | mdLib.use(markdownItAttrs); 101 | mdLib.use(markdownItAnchor, { 102 | tabIndex: false, 103 | slugify: s => slugify(s), 104 | permalink: markdownItAnchor.permalink.headerLink(), 105 | }); 106 | mdLib.use(markdownItContainer, "intro"); 107 | mdLib.use(markdownItContainer, "orientation"); 108 | mdLib.use(markdownItContainer, "storystep"); 109 | mdLib.use(markdownItContainer, "h-author"); 110 | mdLib.use(markdownItContainer, "topic-list"); 111 | mdLib.use(markdownItContainer, "output-block"); 112 | 113 | // Admonitions 114 | mdLib.use(markdownItContainer, "tip", { marker: "!", render: composeGenericAdmonitionRenderFunc("tip") }); 115 | mdLib.use(markdownItContainer, "note", { marker: "!", render: composeGenericAdmonitionRenderFunc("note") }); 116 | mdLib.use(markdownItContainer, "info", { marker: "!", render: composeGenericAdmonitionRenderFunc("info") }); 117 | mdLib.use(markdownItContainer, "learn", { marker: "!", render: composeGenericAdmonitionRenderFunc("learn") }); 118 | 119 | // Details block 120 | mdLib.use(markdownItContainer, "details", { marker: "!", render: composeDetailsBlockRenderFunc() }); 121 | // Create a specialized synonym for details block with a class of "dig-deeper" 122 | mdLib.use(markdownItContainer, "dig-deeper", { marker: "!", render: composeDetailsBlockRenderFunc("dig-deeper") }); 123 | 124 | export default mdLib; -------------------------------------------------------------------------------- /11ty-extensions/nunjucks-exts.js: -------------------------------------------------------------------------------- 1 | 2 | export default function(eleventyConfig) { 3 | 4 | eleventyConfig.addNunjucksGlobal("callMacroByName", function(name) { 5 | if (!name) { 6 | return; 7 | } 8 | 9 | const otherArgs = [...arguments].slice(1); 10 | const member = this.ctx[name]; 11 | if (typeof member === "function") { 12 | return member(...otherArgs); 13 | } 14 | }); 15 | 16 | eleventyConfig.addNunjucksGlobal("ConsoleLog", function() { 17 | console.log(...arguments); 18 | }); 19 | 20 | }; -------------------------------------------------------------------------------- /11ty-markdown-changes.md: -------------------------------------------------------------------------------- 1 | 2 | ## Titles go in Front Matter 3 | - H1s will be in higher level layouts. Do not include in md body. 4 | - Page title should go in Front Matter at top of MD file. 5 | Example: 6 | ``` 7 | --- 8 | title: Create a New App 9 | --- 10 | ``` 11 | 12 | ## Divs 13 | - No more `markdown=1`, instead leave a blank line after. 14 | - Core Concepts intro and orientation divs have had their `coreconcepts-` prefixes removed and can now be created as MD containers. `coreconcepts-storysequence` blocks have been replaced with individual `storystep` blocks around each step in a story sequence. Use: 15 | ``` 16 | ::: intro 17 | words words 18 | ::: 19 | ``` 20 | If you need to nest containers add an additional `:` on each outer layer. 21 | 22 | ## Admonitions 23 | - Do NOT indent contents of Admonitions 24 | - Admonitions must be closed with `!!!` 25 | - You can add a title (Example: ```!!! note Run in `nix-shell https://holochain.love` ```), Otherwise it will use the name of the Admonition. 26 | 27 | ## Code Fences 28 | - Include language (i.e.: `bash`) always. 29 | - If you want to surpress the copy button wrap the code block in a `::: output-block` container 30 | - Code blocks meant to be copied and pasted into a terminal should use `shell` rather than `bash`; they'll automatically get styled with a non-copyable `$` at the beginning of the first line. 31 | 32 | ## Open in new window 33 | - add `{target=_blank}` after link markdown parens 34 | 35 | ## Button for link 36 | - add `{.btn-purple}` after link markdown parens 37 | 38 | ## Center an Image 39 | ``` 40 | ![](/assets/img/concepts/8.8-assigned-capability.png) 41 | {.center} 42 | ``` 43 | Note: The new line after the image is required to put the class in the enclosing `

` 44 | 45 | ## Tweak the size of an image 46 | Obviously it would be optimal to actually resize the image. But you can tweak the max-width with the classes 47 | `sz10p` (10%) through `sz200p` (200%) 48 | ``` 49 | ![](/assets/img/concepts/8.1-calls.png){.sz50p} 50 | ``` 51 | 52 | ## Table of contents 53 | An on-page table of contents is generated automatically for every page from all `h2` to `h6` elements that have `id` attributes. If you don't want this to happen, put `tocData: false` in your page's front matter. You can also selectively prevent a header from being included in the table of contents by either suppressing its ID attribute or adding a `data-no-toc` attribute: 54 | 55 | ```markdown 56 | ## I am a header that shouldn't appear in the TOC {data-no-toc} 57 | ``` 58 | 59 | If you want to craft a custom table of contents, instead assign a nested array to `tocData` that looks like this: 60 | 61 | ```yaml 62 | tocData: 63 | - text: First section header 64 | href: first-section-header 65 | children: 66 | - text: Subsection header 1 67 | href: subsection-header-1 68 | - text: Subsection header 2 69 | href: subsection-header-2 70 | - text: Second section header 71 | href: second-section-header 72 | - text: Conclusion 73 | href: conclusion 74 | ``` 75 | 76 | There are two things to note about the above: 77 | 78 | * IDs are automatically generated for all headers; they'll be the slug of the header text. You can override a header's ID with a `{#custom-id}` attribute. 79 | * Although the `href` property suggests it should be a resolvable URL, don't put the `#` at the beginning of its value. 80 | 81 | ## Items to add to README 82 | - using callMacroByName 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | developer.holochain.org -------------------------------------------------------------------------------- /code_test_4/web-happ.yaml: -------------------------------------------------------------------------------- 1 | manifest_version: '1' 2 | name: blup 3 | ui: 4 | bundled: ./path/to/my/ui.zip 5 | happ_manifest: 6 | bundled: ./path/to/my/happ-bundle.happ 7 | -------------------------------------------------------------------------------- /cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "import": ["@cspell/dict-lorem-ipsum/cspell-ext.json", "@cspell/dict-rust/cspell-ext.json"], 3 | "dictionaries": ["holochain", "words-that-should-exist", "custom", "template", "html", "css", "softwareTerms", "lorem-ipsum", "rust"], 4 | "dictionaryDefinitions": [ 5 | { 6 | "name": "holochain", 7 | "path": "./.cspell/holochain-words.txt" 8 | }, 9 | { 10 | "name": "words-that-should-exist", 11 | "path": "./.cspell/words-that-should-exist.txt" 12 | }, 13 | { 14 | "name": "custom", 15 | "path": "./.cspell/custom-words.txt" 16 | }, 17 | { 18 | "name": "template", 19 | "path": "./.cspell/template-words.txt" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /eleventy.config.js: -------------------------------------------------------------------------------- 1 | import { EleventyRenderPlugin } from "@11ty/eleventy"; 2 | import externalLinks from "@aloskutov/eleventy-plugin-external-links"; 3 | 4 | import registerExtensions from "./11ty-extensions/index.js"; 5 | 6 | export default function(eleventyConfig) { 7 | 8 | eleventyConfig.addPassthroughCopy({"./src/assets/": "assets"}); 9 | eleventyConfig.addPassthroughCopy({"./node_modules/font-awesome/css": "assets/font-awesome/css"}); 10 | eleventyConfig.addPassthroughCopy({"./node_modules/font-awesome/fonts": "assets/font-awesome/fonts"}); 11 | eleventyConfig.addPassthroughCopy({"./node_modules/highlight.js/styles/atom-one-light.min.css": "styles/highlight.js-atom-one-light.min.css"}); 12 | 13 | eleventyConfig.addPassthroughCopy({"./client-side-compiled/**/*": "scripts"}); 14 | eleventyConfig.addPassthroughCopy({"./styles-compiled/**/*": "styles"}); 15 | eleventyConfig.addPassthroughCopy({"./src/copy-to-root/*": "."}); 16 | 17 | /* If you have any libs being pulled from node_modules you might do it like below */ 18 | eleventyConfig.addPassthroughCopy({"./node_modules/lunr/lunr.min.js": "scripts/libs/lunr.min.js"}); 19 | 20 | eleventyConfig.setUseGitIgnore(false); 21 | eleventyConfig.setDataDeepMerge(false); 22 | 23 | eleventyConfig.addPlugin(EleventyRenderPlugin); 24 | eleventyConfig.addPlugin(externalLinks, {overwrite: false}); 25 | 26 | eleventyConfig.setServerOptions({ 27 | showAllHosts: true 28 | }); 29 | 30 | eleventyConfig.setWatchThrottleWaitTime(100); 31 | 32 | registerExtensions(eleventyConfig); 33 | 34 | return { 35 | dir: { 36 | input: "src/pages", 37 | } 38 | } 39 | }; -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | # Enable broken link checking in Netlify CI 2 | # Disabling for now so I can configure per environment. 3 | # [[plugins]] 4 | # package = "netlify-plugin-checklinks" 5 | # [plugins.inputs] 6 | # entryPoints = [ 7 | # "*.html", 8 | # ] 9 | 10 | # recursive = true 11 | # pretty = true 12 | # checkExternal = false 13 | 14 | [[headers]] 15 | for = "/*" 16 | [headers.values] 17 | Access-Control-Allow-Origin = "*" 18 | 19 | # These first rules are a bit fiddly -- we explicitly redirect URLs that we know should 20 | # point to the Redux docs, rather than redirecting to `/`, then to `/redirect-to-redux-site.html`, 21 | # which ends up breaking things on the Redux site side. 22 | [[redirects]] 23 | from = "/docs/guide/*" 24 | to = "/redirect-to-redux-site.html#!docs/guide/:splat" 25 | # We may use this path for a new guidebook. 26 | status = 302 27 | 28 | [[redirects]] 29 | from = "/docs/tutorials/*" 30 | to = "/redirect-to-redux-site.html#!docs/tutorials/:splat" 31 | # Holding open the possibility of tutorials too. 32 | status = 302 33 | 34 | [[redirects]] 35 | from = "/docs/create-new-app/" 36 | to = "/redirect-to-redux-site.html#!docs/create-new-app/" 37 | status = 302 38 | 39 | [[redirects]] 40 | from = "/resources/happ-bundle/" 41 | to = "/redirect-to-redux-site.html#!docs/resources/happ-bundle/" 42 | # There will eventually be a new hApp bundle format that will get documented, 43 | # and I intend to put it under `/resources`. 44 | status = 302 45 | 46 | # Some of the core concepts' titles and URLs have changed, 47 | # but fortunately they map to new core concepts (sometimes roughly, sometimes exactly) 48 | # so let's redirect them. 49 | [[redirects]] 50 | from = "/docs/concepts/3_private_data/" 51 | to = "/concepts/3_source_chain/" 52 | status = 301 53 | 54 | [[redirects]] 55 | from = "/docs/concepts/4_public_data_on_the_dht/" 56 | to = "/concepts/4_dht/" 57 | status = 301 58 | 59 | [[redirects]] 60 | from = "/docs/concepts/5_linking_data_together/" 61 | to = "/concepts/5_links_anchors/" 62 | status = 301 63 | 64 | [[redirects]] 65 | from = "/docs/concepts/6_modifying_and_deleting_data/" 66 | to = "/concepts/6_crud_actions/" 67 | status = 301 68 | 69 | [[redirects]] 70 | from = "/docs/concepts/8_node_to_node_messaging/" 71 | to = "/concepts/8_calls_capabilities/" 72 | status = 301 73 | 74 | [[redirects]] 75 | from = "/references/*" 76 | to = "/resources/:splat" 77 | status = 301 78 | 79 | # Once upon a time, we had a landing page and all the actual docs were in /docs. 80 | [[redirects]] 81 | from = "/docs/*" 82 | to = "/:splat" 83 | status = 301 84 | 85 | # Super old install URL; used to be incorrectly linked from the blog's CTAs. 86 | [[redirects]] 87 | from = "/start.html" 88 | to = "/quick-start/" 89 | status = 301 90 | 91 | # This is just for the nix guide, which is now called the advanced install guide. 92 | [[redirects]] 93 | from = "/docs/nix/" 94 | to = "/install-advanced/" 95 | status = 301 96 | 97 | # The rrDHT paper got finalised, so let's redirect to the final copy. 98 | [[redirects]] 99 | from = "/assets/files/RRDHT-draft-Nov-2019.pdf" 100 | to = "/assets/files/RRDHT-whitepaper-final.pdf" 101 | status = 301 102 | 103 | # The quick start guide used to live at /install/ 104 | [[redirects]] 105 | from = "/install/" 106 | to = "/get-started/" 107 | status = 301 108 | 109 | # Glossary has been moved to the resources path. 110 | [[redirects]] 111 | from = "/glossary/" 112 | to = "/resources/glossary/" 113 | status = 301 114 | 115 | # The front page for the core concepts has been removed. 116 | [[redirects]] 117 | from = "/concepts/" 118 | to = "/concepts/1_the_basics/" 119 | # Keeping this as a 302 in case we decide we want a front page again. 120 | status = 302 121 | 122 | # Shuffled some things around August 2023 123 | [[redirects]] 124 | from = "/get-building/*" 125 | to = "/get-started/:splat" 126 | status = 301 127 | 128 | [[redirects]] 129 | from = "/quick-start/" 130 | to = "/get-started/" 131 | status = 301 132 | 133 | # The first upgrade guide lived under getting started. It has been moved to its own area. 134 | [[redirects]] 135 | from = "/get-started/upgrade-holochain/" 136 | to = "/resources/upgrade/" 137 | status = 301 138 | 139 | # Every time there's a new breaking release that achieves 'recommended' status, 140 | # update this temporary redirect. /resources/upgrade/latest/ isn't in the site nav, 141 | # but it is a handy URL we can hand out without needing to look up what the proper URL is. 142 | # TODO(upgrade): change following version number 143 | [[redirects]] 144 | from = "/resources/upgrade/latest/" 145 | to = "/resources/upgrade/upgrade-holochain-0.5/" 146 | status = 302 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "holochain-docs-pages", 3 | "version": "1.0.0", 4 | "description": "11ty project for generating the Holochain documentation", 5 | "main": "index.cjs", 6 | "type": "module", 7 | "engines": { 8 | "node": ">=20" 9 | }, 10 | "directories": { 11 | "doc": "docs" 12 | }, 13 | "scripts": { 14 | "build:search-index": "npx pagefind --site _site --glob \"**/*.html\"", 15 | "build:web": "ELEVENTY_ENV=production npx @11ty/eleventy", 16 | "serve:web": "ELEVENTY_ENV=development npx @11ty/eleventy --serve --incremental", 17 | "serve:web-prod": "ELEVENTY_ENV=production BROWERSYNC=off npx @11ty/eleventy --serve", 18 | "debug:web": "DEBUG=Eleventy* ELEVENTY_ENV=development npx @11ty/eleventy --serve", 19 | "build:sass": "npx sass src/scss:styles-compiled", 20 | "watch:sass": "npx sass --watch src/scss:styles-compiled", 21 | "post:css": "npx postcss styles-compiled/site.css > styles-compiled/site.min.css", 22 | "min:js": "npx uglify-js _site/scripts/main.bundled.js --output _site/scripts/main.min.js", 23 | "bundle:js": "rollup -c rollup.config.js", 24 | "watch:js": "rollup -c rollup.config.js -w", 25 | "dev": "npm run build && npm-run-all -p serve:web watch:sass watch:js", 26 | "dev-no-js": "npm run build:sass && npm-run-all -p serve:web watch:sass", 27 | "build": "npm-run-all -s clean:site build:sass post:css clean:js bundle:js build:web build:search-index", 28 | "serve-as-prod": "npm-run-all -s clean:site build:sass post:css clean:js bundle:js serve:web-prod", 29 | "clean:js": "rm -rf client-side-compiled", 30 | "clean:css": "rm -rf styles-compiled", 31 | "clean:site": "rm -rf _site", 32 | "clean": "npm-run-all clean:site clean:js clean:css", 33 | "update-browserlist": "npx browserslist@latest --update-db" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "git+https://github.com/holochain/docs-pages.git" 38 | }, 39 | "author": "", 40 | "license": "GPL-3.0-or-later", 41 | "bugs": { 42 | "url": "https://github.com/holochain/docs-pages/issues" 43 | }, 44 | "homepage": "https://github.com/holochain/docs-pages#readme", 45 | "devDependencies": { 46 | "@11ty/eleventy": "^3.0.0-alpha.1", 47 | "@aloskutov/eleventy-plugin-external-links": "^2.1.1", 48 | "@rollup/plugin-terser": "^0.4.4", 49 | "@rollup/plugin-typescript": "^11.1.5", 50 | "@sindresorhus/slugify": "1.1.2", 51 | "@types/lunr": "^2.3.4", 52 | "@types/markdown-it": "^12.2.3", 53 | "autoprefixer": "^10.4.13", 54 | "cssnano": "^5.1.14", 55 | "fauxdom": "^1.1.1", 56 | "he": "^1.2.0", 57 | "highlight.js": "^11.9.0", 58 | "highlight.svelte": "^0.1.2", 59 | "highlightjs-code-diff": "^1.0.0", 60 | "html-minifier-terser": "^7.2.0", 61 | "html-to-text": "^8.2.1", 62 | "json5": "^2.2.3", 63 | "lunr": "^2.3.9", 64 | "markdown-it-anchor": "^8.6.6", 65 | "markdown-it-attrs": "^4.1.4", 66 | "markdown-it-container": "^3.0.0", 67 | "npm-run-all": "^4.1.5", 68 | "postcss": "^8.4.18", 69 | "postcss-cli": "^10.0.0", 70 | "posthtml": "^0.16.6", 71 | "posthtml-noopener": "^1.0.5", 72 | "rollup": "^3.2.5", 73 | "sass": "^1.56.0", 74 | "tslib": "^2.6.2", 75 | "typescript": "^4.8.4", 76 | "uglify-js": "^3.17.4" 77 | }, 78 | "dependencies": { 79 | "pagefind": "^1.3.0" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from '@rollup/plugin-typescript'; 2 | import terser from '@rollup/plugin-terser'; 3 | 4 | export default [ 5 | { 6 | input: 'src/client-side/index.ts', 7 | output: { 8 | file: '_site/scripts/index.min.js', 9 | sourcemap: '_site/scripts/index.min.js.map', 10 | inlineDynamicImports: true, 11 | }, 12 | plugins: [ 13 | typescript(), 14 | terser(), 15 | ], 16 | }, 17 | { 18 | input: 'src/client-side/page-search.ts', 19 | output: { 20 | file: '_site/scripts/page-search.min.js', 21 | sourcemap: '_site/scripts/page-search.min.js.map', 22 | }, 23 | plugins: [ 24 | typescript(), 25 | terser(), 26 | ], 27 | }, 28 | ] -------------------------------------------------------------------------------- /src/assets/files/RRDHT-whitepaper-final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/files/RRDHT-whitepaper-final.pdf -------------------------------------------------------------------------------- /src/assets/img/concepts/1.1-architecture-comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/1.1-architecture-comparison.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.1-countersigning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.1-countersigning.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.10-validate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.10-validate.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.11-authorities-collect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.11-authorities-collect.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.12-authorities-distribute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.12-authorities-distribute.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.13-commit-and-publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.13-commit-and-publish.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.14-enzyme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.14-enzyme.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.15-m-of-n-witnesses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.15-m-of-n-witnesses.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.2-entry-exchange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.2-entry-exchange.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.3-preflight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.3-preflight.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.4-preflight-send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.4-preflight-send.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.5-preflight-inspection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.5-preflight-inspection.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.6-bob-lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.6-bob-lock.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.7-alice-lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.7-alice-lock.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.8-countersigning-session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.8-countersigning-session.png -------------------------------------------------------------------------------- /src/assets/img/concepts/10.9-trial-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/10.9-trial-commit.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.1-mutual-execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.1-mutual-execution.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.10-whole-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.10-whole-stack.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.2-data-integrity-membrane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.2-data-integrity-membrane.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.3-process-membrane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.3-process-membrane.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.4-client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.4-client.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.5-conductor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.5-conductor.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.6-happ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.6-happ.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.7-cells-in-slots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.7-cells-in-slots.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.8-dna-in-cell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.8-dna-in-cell.png -------------------------------------------------------------------------------- /src/assets/img/concepts/2.9-zomes-in-dna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/2.9-zomes-in-dna.png -------------------------------------------------------------------------------- /src/assets/img/concepts/3.1-key-generation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/3.1-key-generation.png -------------------------------------------------------------------------------- /src/assets/img/concepts/3.2-source-chain-as-journal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/3.2-source-chain-as-journal.png -------------------------------------------------------------------------------- /src/assets/img/concepts/3.3-genesis-records-1-and-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/3.3-genesis-records-1-and-2.png -------------------------------------------------------------------------------- /src/assets/img/concepts/3.4-genesis-records-3-and-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/3.4-genesis-records-3-and-4.png -------------------------------------------------------------------------------- /src/assets/img/concepts/3.5-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/3.5-commit.png -------------------------------------------------------------------------------- /src/assets/img/concepts/3.6-action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/3.6-action.png -------------------------------------------------------------------------------- /src/assets/img/concepts/3.7-prev-action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/3.7-prev-action.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.1-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.1-network.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.10-gossip-resilience.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.10-gossip-resilience.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.11-retrieval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.11-retrieval.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.12-healthy-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.12-healthy-network.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.13-partition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.13-partition.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.14-resilience-building.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.14-resilience-building.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.15-partition-healing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.15-partition-healing.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.2-public-entry-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.2-public-entry-commit.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.3-private-entry-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.3-private-entry-commit.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.4-address-space-and-neighborhoods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.4-address-space-and-neighborhoods.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.5-alice-neighborhood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.5-alice-neighborhood.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.7-alice-publish-address-calculation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.7-alice-publish-address-calculation.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.8-authority-resolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.8-authority-resolution.png -------------------------------------------------------------------------------- /src/assets/img/concepts/4.9-gossip-publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/4.9-gossip-publish.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.1-links.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.1-links.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.2-alice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.2-alice.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.3-alice-username.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.3-alice-username.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.4-usernames-anchor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.4-usernames-anchor.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.5-alice-album.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.5-alice-album.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.6-album-tracks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.6-album-tracks.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.7-album-genres.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.7-album-genres.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.8-genres-anchor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.8-genres-anchor.png -------------------------------------------------------------------------------- /src/assets/img/concepts/5.9-graph-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/5.9-graph-database.png -------------------------------------------------------------------------------- /src/assets/img/concepts/6.1-crud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/6.1-crud.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.1-validation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.1-validation.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.10-gossip-to-authorities.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.10-gossip-to-authorities.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.11-authorities-validate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.11-authorities-validate.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.12-hold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.12-hold.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.13-respond-validation-receipts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.13-respond-validation-receipts.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.14-gossip-to-authorities.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.14-gossip-to-authorities.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.15-validate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.15-validate.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.16-warrant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.16-warrant.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.17-gossip-warrant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.17-gossip-warrant.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.18-ejection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.18-ejection.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.2-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.2-commit.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.3-validate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.3-validate.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.4-validation-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.4-validation-success.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.5-persist-and-publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.5-persist-and-publish.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.6-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.6-commit.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.7-validate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.7-validate.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.8-validation-failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.8-validation-failure.png -------------------------------------------------------------------------------- /src/assets/img/concepts/7.9-return-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/7.9-return-error.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.1-calls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.1-calls.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.2-client-call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.2-client-call.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.3-inter-zome-call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.3-inter-zome-call.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.4-bridge-call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.4-bridge-call.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.5-remote-call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.5-remote-call.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.6-unrestricted-capability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.6-unrestricted-capability.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.7-transferrable-capability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.7-transferrable-capability.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.8-assigned-capability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.8-assigned-capability.png -------------------------------------------------------------------------------- /src/assets/img/concepts/8.9-author-capability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/8.9-author-capability.png -------------------------------------------------------------------------------- /src/assets/img/concepts/9.1-signals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/9.1-signals.png -------------------------------------------------------------------------------- /src/assets/img/concepts/9.2-client-signal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/9.2-client-signal.png -------------------------------------------------------------------------------- /src/assets/img/concepts/9.3-remote-signal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/concepts/9.3-remote-signal.png -------------------------------------------------------------------------------- /src/assets/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/favicon.ico -------------------------------------------------------------------------------- /src/assets/img/get-started/1-running-app-first-look.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/1-running-app-first-look.png -------------------------------------------------------------------------------- /src/assets/img/get-started/10-comment-components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/10-comment-components.png -------------------------------------------------------------------------------- /src/assets/img/get-started/2-look-for-hellos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/2-look-for-hellos.png -------------------------------------------------------------------------------- /src/assets/img/get-started/3-two-uis-and-playground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/3-two-uis-and-playground.png -------------------------------------------------------------------------------- /src/assets/img/get-started/4-no-posts-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/4-no-posts-found.png -------------------------------------------------------------------------------- /src/assets/img/get-started/5-create-post-component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/5-create-post-component.png -------------------------------------------------------------------------------- /src/assets/img/get-started/6-playground-first-post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/6-playground-first-post.png -------------------------------------------------------------------------------- /src/assets/img/get-started/7-edit-post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/7-edit-post.png -------------------------------------------------------------------------------- /src/assets/img/get-started/8-playground-after-edits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/8-playground-after-edits.png -------------------------------------------------------------------------------- /src/assets/img/get-started/9-playground-after-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/get-started/9-playground-after-delete.png -------------------------------------------------------------------------------- /src/assets/img/google-chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/google-chrome.png -------------------------------------------------------------------------------- /src/assets/img/google-chrome.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/google-chrome.webp -------------------------------------------------------------------------------- /src/assets/img/holochain-gym.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/holochain-gym.jpg -------------------------------------------------------------------------------- /src/assets/img/holochain-logo-black-1300.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/holochain-logo-black-1300.png -------------------------------------------------------------------------------- /src/assets/img/holochain-logo-black-1300.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/holochain-logo-black-1300.webp -------------------------------------------------------------------------------- /src/assets/img/holochain-logo-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/holochain-logo-black.png -------------------------------------------------------------------------------- /src/assets/img/holochain-logo-black.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/holochain-logo-black.webp -------------------------------------------------------------------------------- /src/assets/img/holochain-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/holochain-logo-small.png -------------------------------------------------------------------------------- /src/assets/img/holochain-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/holochain-logo-white.png -------------------------------------------------------------------------------- /src/assets/img/icon-apple.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 29 | 31 | 51 | 55 | 56 | -------------------------------------------------------------------------------- /src/assets/img/icon-windows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/assets/img/logo_light-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/logo_light-2x.png -------------------------------------------------------------------------------- /src/assets/img/playground-simulator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/img/playground-simulator.jpg -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormBold/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormBold/font.woff -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormBold/font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormBold/font.woff2 -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormBoldItalic/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormBoldItalic/font.woff -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormBoldItalic/font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormBoldItalic/font.woff2 -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormExtraBold/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormExtraBold/font.woff -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormExtraBold/font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormExtraBold/font.woff2 -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormExtraBoldItalic/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormExtraBoldItalic/font.woff -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormExtraBoldItalic/font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormExtraBoldItalic/font.woff2 -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormItalic/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormItalic/font.woff -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormItalic/font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormItalic/font.woff2 -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormRegular/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormRegular/font.woff -------------------------------------------------------------------------------- /src/assets/webFonts/URWFormRegular/font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/assets/webFonts/URWFormRegular/font.woff2 -------------------------------------------------------------------------------- /src/client-side/index.ts: -------------------------------------------------------------------------------- 1 | function copyCodeBlockClickHandler(e: Event) { 2 | const button = e.target as HTMLButtonElement; 3 | const codeEl = button.parentElement?.querySelector("code"); 4 | if (!codeEl) { return; } 5 | navigator.clipboard.writeText(codeEl.innerText); 6 | } 7 | 8 | function addCopyButtonsToCodeSections() { 9 | const copyButtonTemplate = document.querySelector("#copy-button-template"); 10 | 11 | const codeElms = document.querySelectorAll('pre > code'); 12 | codeElms.forEach((codeEl: Element) => { 13 | // If there is a output-block class as an ancestor anywhere then don't add button 14 | if (codeEl.closest('.output-block')) { 15 | return; 16 | } 17 | 18 | const copyButtonFrag = copyButtonTemplate?.content.cloneNode(true); 19 | 20 | if (copyButtonFrag) { 21 | const preEl = codeEl.parentElement!; 22 | // insert the copyButtonFrag right before the code fence 23 | preEl.parentElement?.insertBefore(copyButtonFrag, preEl); 24 | const codeFenceWrapper = preEl.previousElementSibling!; 25 | // move the preEl into the new Node 26 | codeFenceWrapper.appendChild(preEl); 27 | const btnEl = codeFenceWrapper.querySelector("button[data-purpose]")!; 28 | btnEl.addEventListener("click", copyCodeBlockClickHandler); 29 | } 30 | }); 31 | } 32 | 33 | addCopyButtonsToCodeSections(); 34 | 35 | function setupDiffTabsClickHandler() { 36 | const diffContainers = document.querySelectorAll('.diff-container'); 37 | diffContainers.forEach((container: Element) => { 38 | // Show diff by default. 39 | container.dataset.selected = 'diff'; 40 | // Set up handlers to toggle between them. 41 | container.querySelector('.diff-show-diff')?.addEventListener('click', () => { 42 | container.dataset.selected = 'diff'; 43 | }); 44 | container.querySelector('.diff-show-final')?.addEventListener('click', () => { 45 | container.dataset.selected = 'final'; 46 | }); 47 | }); 48 | } 49 | 50 | setupDiffTabsClickHandler(); 51 | 52 | /** 53 | * Sets up the hamburger menu to show/hide the navigation 54 | */ 55 | function setUpMenuToggle() { 56 | const buttons = document.querySelectorAll('.hamburger-activate'); 57 | 58 | const openedClassName = "opened"; 59 | buttons.forEach((btn) => { 60 | btn.addEventListener("click", () => { 61 | // Handle button change 62 | const isOpen = btn.classList.contains(openedClassName); 63 | btn.classList.toggle(openedClassName, !isOpen); 64 | btn.setAttribute("aria-expanded", isOpen.toString()); 65 | 66 | // Handle the desired effect 67 | const sideBarEl = document.querySelector(".default-page-type .side-bar"); 68 | sideBarEl?.classList.toggle("show", !isOpen); 69 | 70 | }) 71 | }) 72 | } 73 | 74 | setUpMenuToggle(); 75 | 76 | /** 77 | * Sets up the Navigation open child buttons 78 | */ 79 | function setupNavHandlers() { 80 | document.querySelectorAll("button[data-children-opener]").forEach((btn) => { 81 | btn.addEventListener("click", (e: Event) => { 82 | // Handle the open/close state 83 | const openedChildLevels = document.querySelectorAll("ul.nav-child-level.open"); 84 | const clickedChildLevel = btn.parentElement?.querySelector("ul.nav-child-level"); 85 | const currentStateOpen = clickedChildLevel?.classList.contains("open"); 86 | 87 | openedChildLevels.forEach((ul) => ul.classList.remove("open")); 88 | clickedChildLevel?.classList.toggle("open", !currentStateOpen); 89 | 90 | // Handle the arrow direction 91 | const openedButtons = document.querySelectorAll("#main-nav ul.nav-top-level > li > button.up-arrow"); 92 | openedButtons.forEach((btn) => btn.classList.remove("up-arrow")); 93 | btn.classList.toggle("up-arrow", !currentStateOpen); 94 | }); 95 | }); 96 | } 97 | 98 | setupNavHandlers(); 99 | 100 | function openModalIFrame(url:string) { 101 | const template = document.querySelector('#modal-iframe-template'); 102 | 103 | const frag = template?.content.cloneNode(true) as DocumentFragment; 104 | if (frag) { 105 | const div = frag.querySelector(".modal-iframe"); 106 | const iframe = frag.querySelector(".modal-iframe iframe"); 107 | const closeBtn = frag.querySelector(".modal-iframe .modal-iframe-close"); 108 | if (div && iframe && closeBtn) { 109 | iframe.src = url; 110 | closeBtn.addEventListener("click", (e) => { 111 | document.querySelector(".modal-iframe")?.remove(); 112 | }); 113 | document.body.appendChild(frag); 114 | } 115 | } 116 | } 117 | 118 | document.querySelector(".take-the-survey")?.addEventListener("click", (e) => { 119 | e.preventDefault(); 120 | openModalIFrame("https://form.typeform.com/to/AL0HFFy8"); 121 | }); 122 | 123 | const inPageToc = document.querySelector("#in-page-toc"); 124 | if (inPageToc) { 125 | const tocLinks = inPageToc.querySelectorAll("li > a"); 126 | 127 | const setCurrentSection = (sectionId: string) => { 128 | tocLinks.forEach((link) => { 129 | link.classList.toggle("current", link.getAttribute("href") === `#${sectionId}`); 130 | }); 131 | } 132 | 133 | //set up intersection observer to highlight the current section 134 | const observerCallback = (entries: IntersectionObserverEntry[]) => { 135 | if (entries[0].isIntersecting) { 136 | setCurrentSection(entries[0].target.id); 137 | } 138 | }; 139 | 140 | const observer = new IntersectionObserver(observerCallback, { rootMargin: "0px 0px 0px 0px" }); 141 | 142 | tocLinks.forEach((link) => { 143 | const linkId = link.getAttribute("href")?.replace("#", ""); 144 | const htag = document.querySelector(`[id="${linkId}"]`); 145 | if (htag) { 146 | observer.observe(htag); 147 | } else { 148 | console.warn("No htag found for link", link); 149 | } 150 | }); 151 | } 152 | 153 | const openDetailsOnFragmentIdNavigation = () => { 154 | if (location.hash) { 155 | const targetedDetailsElement = document.querySelector("details" + location.hash); 156 | if (targetedDetailsElement) { 157 | targetedDetailsElement.setAttribute("open", "open"); 158 | } 159 | } 160 | }; 161 | 162 | // Open details elements when they have an ID that's navigated to. 163 | openDetailsOnFragmentIdNavigation(); 164 | window.addEventListener("hashchange", openDetailsOnFragmentIdNavigation); 165 | 166 | // Load MyFonts counter for URW Form fonts asynchronously, not in JS. 167 | // This is a workaround for a weird error thrown by netlify-plugin-checklinks. 168 | fetch("//hello.myfonts.net/count/3e423c"); -------------------------------------------------------------------------------- /src/client-side/page-search.ts: -------------------------------------------------------------------------------- 1 | const debounce = (callback: (...params: any[]) => any, waitTime: number) => { 2 | let timeoutId: number | null = null; 3 | 4 | return (...args: any[]) => { 5 | if (timeoutId) { 6 | window.clearTimeout(timeoutId); 7 | } 8 | 9 | timeoutId = window.setTimeout(() => { 10 | callback.apply(null, args); 11 | }, waitTime); 12 | }; 13 | } 14 | 15 | /** Query string parameter name holding the current search */ 16 | const PagefindSearchKey = "pagefind-search"; 17 | 18 | function setupPagefindUI() { 19 | const pagefindUIInstance = new PagefindUI({ 20 | element: "#search", 21 | showImages: false, 22 | showSubResults: true 23 | }); 24 | 25 | const searchInput = window.document.querySelector("#search .pagefind-ui__search-input")!; 26 | const pagefindSearchQString = (new URL(window.location.toString())).searchParams.get(PagefindSearchKey); 27 | 28 | if (pagefindSearchQString) { 29 | pagefindUIInstance.triggerSearch(pagefindSearchQString); 30 | } 31 | 32 | const debouncedInputHandler = debounce(() => updateSearchQueryString(searchInput?.value), 1000); 33 | 34 | // Clear the query string if it is empty 35 | searchInput?.addEventListener("input", (e: Event) => { 36 | if (searchInput.value === "") { 37 | updateSearchQueryString(""); 38 | } else { 39 | debouncedInputHandler(); 40 | } 41 | }); 42 | 43 | // if the Enter key is clicked then append the search to the QueryString 44 | searchInput?.addEventListener("keydown", (e: KeyboardEvent) => { 45 | if (e.code === "Enter") { 46 | updateSearchQueryString(searchInput.value); 47 | } 48 | }); 49 | 50 | // Clear the query string if clear button clicked 51 | window.document.querySelector("#search .pagefind-ui__search-clear")?.addEventListener("click", () => { 52 | updateSearchQueryString(""); 53 | }); 54 | 55 | searchInput?.focus(); 56 | 57 | function updateSearchQueryString(term: string) { 58 | const url = new URL(window.location.toString()); 59 | if (term.trim() == "") { 60 | url.searchParams.delete(PagefindSearchKey); 61 | } else if (url.searchParams.get(PagefindSearchKey) !== term) { 62 | url.searchParams.set(PagefindSearchKey, term); 63 | } 64 | history.pushState({}, "", url); 65 | } 66 | } 67 | 68 | setupPagefindUI(); -------------------------------------------------------------------------------- /src/client-side/types.d.ts: -------------------------------------------------------------------------------- 1 | declare class PagefindUIClass { 2 | constructor(opts: any); 3 | triggerSearch(term: string); 4 | } 5 | 6 | declare var PagefindUI = PagefindUIClass; -------------------------------------------------------------------------------- /src/custom/icon-apple.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 29 | 31 | 51 | 55 | 56 | -------------------------------------------------------------------------------- /src/custom/icon-windows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/custom/script.js: -------------------------------------------------------------------------------- 1 | if (document.location.pathname.indexOf("/concepts/") == 0) { 2 | document.body.className = "page-concepts"; 3 | } -------------------------------------------------------------------------------- /src/pages/404.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: Oops! 3 | permalink: 404.html 4 | layout: "" 5 | --- 6 | 7 | 8 | 9 | 10 | 11 | {% if site.environment == "production" %} 12 | 13 | {% else %} 14 | 15 | {% endif %} 16 | {{ title }} 17 | 44 | 45 | 46 |

{{ title }}

47 |

404 - Page not found

48 |

The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.

49 | Go to Homepage 50 | 51 | -------------------------------------------------------------------------------- /src/pages/_data/eleventyComputed.js: -------------------------------------------------------------------------------- 1 | import CustomMarkdownIt from "../../../11ty-extensions/markdown-it-config.js"; 2 | import DOM from "fauxdom"; 3 | 4 | // This file generates on-page TOC for every Markdown page that doesn't disable 5 | // this feature via a `tocData` property in the front matter. 6 | // See the `Table of contents` section of `/11ty-markdown-changes.md` for info. 7 | // 8 | // Note that this passes the `data.page.rawInput` data property through 9 | // Markdown-it so it has access to the HTML for generating the outline. 10 | // `rawInput` is a new property as of 11ty 3.0.0: https://github.com/11ty/eleventy/issues/1206#issuecomment-1885269900 11 | // So that means it parses every Markdown page twice. Yes, I know that's a 12 | // performance hit, but 11ty doesn't let you generate computed data from the 13 | // content _after_ it's been converted to HTML. 14 | 15 | function generateOutline(content) { 16 | const doc = new DOM(content); 17 | let headers = doc.querySelectorAll(":is(h2, h3, h4, h5, h6)[id]:not([data-no-toc])") 18 | .map(el => { 19 | return { 20 | level: Number(el.tagName.substring(1, 2)), 21 | text: el.textContent.trim(), 22 | href: el.id 23 | }; 24 | }); 25 | 26 | function buildOutlineRecursive(headers, currentLevel = 2) { 27 | const nestedSection = []; 28 | 29 | if (headers.length) { 30 | for (let i = 0; i < headers.length; i++) { 31 | const header = headers[i]; 32 | 33 | if (header.level < currentLevel) { 34 | break; 35 | } 36 | 37 | if (header.level == currentLevel) { 38 | let node = { 39 | text: header.text, 40 | href: header.href 41 | }; 42 | 43 | let children = buildOutlineRecursive( 44 | headers.slice(i + 1), 45 | header.level + 1 46 | ); 47 | 48 | if (children.length) { 49 | node.children = children; 50 | } 51 | 52 | nestedSection.push(node); 53 | } 54 | } 55 | } 56 | 57 | return nestedSection; 58 | } 59 | 60 | return buildOutlineRecursive(headers); 61 | } 62 | 63 | export default { 64 | generatedTocData: function(data) { 65 | if (data.page.templateSyntax.endsWith("md") && data.tocData === undefined) { 66 | const html = CustomMarkdownIt.render(data.page.rawInput); 67 | return generateOutline(html); 68 | } 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /src/pages/_data/navigation.js: -------------------------------------------------------------------------------- 1 | import JSON5 from "json5"; 2 | import fs from "fs"; 3 | import path from "path"; 4 | import { fileURLToPath } from "url"; 5 | 6 | function loadJson5(filename) { 7 | const content = fs.readFileSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), filename), 'utf8'); 8 | try { 9 | return JSON5.parse(content); 10 | } catch (err) { 11 | err.message = filename + ': ' + err.message; 12 | throw err; 13 | } 14 | } 15 | 16 | const footerLinks = loadJson5("./navigation/footerLinks.json5"); 17 | const mainNav = loadJson5("./navigation/mainNav.json5"); 18 | const headerNav = loadJson5("./navigation/headerNav.json5"); 19 | 20 | function findTopLinkRecordFor(nav, url) { 21 | function urlInNodeOrChildren(item) { 22 | if (item.url === url) { return true; } 23 | return item.hasChildren && item.children.some(urlInNodeOrChildren); 24 | }; 25 | 26 | return nav.children.find(urlInNodeOrChildren); 27 | } 28 | 29 | // Iteratively add the `hasChildren` property and `getActiveParentLink` method 30 | // to a nav node. 31 | function mapNavChildren(item) { 32 | return { 33 | ...item, 34 | children: item.children && item.children.length > 0 && item.children.map(mapNavChildren), 35 | hasChildren: item.children && item.children.length > 0, 36 | getActiveParentLink(pageUrlRendering) { 37 | return findTopLinkRecordFor(this, pageUrlRendering); 38 | }, 39 | }; 40 | } 41 | 42 | const mainNavObj = mapNavChildren(mainNav); 43 | 44 | const headerNavObj = mapNavChildren(headerNav); 45 | 46 | export default { 47 | footerNav: { 48 | ...footerLinks 49 | }, 50 | mainNav: mainNavObj, 51 | headerNav: headerNavObj 52 | }; -------------------------------------------------------------------------------- /src/pages/_data/navigation/footerLinks.json5: -------------------------------------------------------------------------------- 1 | { 2 | columns: [ 3 | { 4 | title: "Developers", 5 | links: [ 6 | { title: "Get Started", url: "/get-started/" }, 7 | { title: "Learn", url: "/concepts/1_the_basics/" }, 8 | { title: "Build", url: "/build/" }, 9 | { title: "Resources", url: "/resources/" }, 10 | ] 11 | }, 12 | 13 | { 14 | title: "Resources", 15 | links: [ 16 | { title: "HDK", url: "https://docs.rs/hdk", external: true }, 17 | { title: "HDI", url: "https://docs.rs/hdi", external: true }, 18 | { title: "App API", url: "https://docs.rs/holochain_conductor_api/latest/holochain_conductor_api/enum.AppRequest.html", external: true }, 19 | { title: "Admin API", url: "https://docs.rs/holochain_conductor_api/latest/holochain_conductor_api/enum.AdminRequest.html", external: true }, 20 | { title: "Client (Javascript)", url: "https://github.com/holochain/holochain-client-js", external: true }, 21 | { title: "Client (Rust)", url: "https://github.com/holochain/holochain-client-rust", external: true }, 22 | { title: "hc dev tool", url: "https://github.com/holochain/holochain/tree/main/crates/hc", external: true }, 23 | { title: "Glossary", url: "/resources/glossary" }, 24 | ] 25 | }, 26 | 27 | { 28 | title: "Community", 29 | links: [ 30 | { title: "Discord", url: "https://discord.com/invite/k55DS5dmPH", external: true }, 31 | { title: "GitHub", url: "https://github.com/holochain/holochain", external: true }, 32 | { title: "Holochain on Twitter", url: "https://twitter.com/holochain", svgSnippet: "twitterLogo", class:"no-away", external: true }, 33 | { title: "Reddit", url: "https://www.reddit.com/r/holochain/", external: true }, 34 | { title: "Code of Conduct", url: "https://www.holochain.org/get-involved/", external: true }, 35 | { title: "Get Involved", url: "/get-involved/" }, 36 | ] 37 | }, 38 | 39 | { 40 | title: "About", 41 | links: [ 42 | { title: "Holochain", url: "https://www.holochain.org/", external: true }, 43 | { title: "Holo.host", url: "https://www.holo.host", external: true }, 44 | { title: "Technical Papers", url: "https://holo.host/whitepapers/ ", external: true }, 45 | { title: "Roadmap", url: "https://www.holochain.org/roadmap", external: true }, 46 | { title: "Blog", url: "https://blog.holochain.org/", external: true }, 47 | { title: "Jobs", url: "https://holochain.org/careers/ ", external: true }, 48 | ] 49 | }, 50 | 51 | { 52 | title: "Dev UX", 53 | class: "newsletter", 54 | links: [ 55 | { title: "

We want to keep improving the developer experience. You can help us by answering 6 questions.

" }, 56 | { title: "Take the Survey", url: "#", class: "btn take-the-survey", external: true }, 57 | ] 58 | } 59 | ], 60 | 61 | bottomRow: 62 | { 63 | links: [ 64 | { title: "Holochain.org", url: "https://www.holochain.org/", image: "/assets/img/logo_light-2x.png", class:"hc-logo-link no-away", external: true }, 65 | { title: "Privacy", url: "https://www.holochain.org/privacy-policy/ ", external: true }, 66 | { title: "|" }, 67 | { title: "Terms of Use", url: "https://www.holochain.org/intellectual-property/ ", external: true }, 68 | { 69 | type: "icon-list", 70 | class: "icon-list", 71 | links: [ 72 | // { title: "Holochain on Mastodon", url: "", svgSnippet: "mastodonIcon", class:"no-away", external: true }, 73 | { title: "Holochain on Reddit", url: "https://www.reddit.com/r/holochain/", svgSnippet: "redditIcon", class:"no-away", external: true }, 74 | { title: "Holochain on Discord", url: "https://discord.com/invite/k55DS5dmPH", svgSnippet: "discordMarkIcon", class:"no-away", external: true }, 75 | { title: "Holochain on GitHub", url: "https://github.com/holochain", svgSnippet: "githubLogo", class:"no-away", external: true }, 76 | { title: "Holochain on YouTube", url: "https://www.youtube.com/channel/UC9fNJMIQ9mQ4u9oyoVIqtDQ", svgSnippet: "youtubeMarkIcon", class:"no-away", external: true }, 77 | { title: "Holochain on Twitter", url: "https://twitter.com/holochain", svgSnippet: "twitterLogo", class:"no-away", external: true }, 78 | ] 79 | }, 80 | ] 81 | }, 82 | } -------------------------------------------------------------------------------- /src/pages/_data/navigation/headerNav.json5: -------------------------------------------------------------------------------- 1 | { 2 | children: [ 3 | { title: "Get Started", url: "/get-started/", class:"" }, 4 | { title: "Learn", url: "/concepts/1_the_basics/", class:"" }, 5 | { title: "Build", url: "/build", class:"" }, 6 | { title: "Resources", url: "/resources/", class:"" }, 7 | { title: "Get Involved", url: "/get-involved/", class:"" }, 8 | ] 9 | } -------------------------------------------------------------------------------- /src/pages/_data/navigation/mainNav.json5: -------------------------------------------------------------------------------- 1 | { 2 | children: [ 3 | { title: "Get Started", url: "/get-started/", children: [ 4 | { title: "1. Install Holochain Development Environment", url: "/get-started/#2-installing-holochain-development-environment" }, 5 | { title: "2. Hello World", url: "/get-started/2-hello-world/" }, 6 | { title: "3. Forum App Tutorial", url: "/get-started/3-forum-app-tutorial/" }, 7 | { title: "4. Packaging & Distribution", url: "/get-started/4-packaging-and-distribution/" }, 8 | { title: "Dev Tools Setup Tips", url: "/get-started/install-advanced/" }, 9 | { title: "Setup Without Nix", url: "/get-started/install-without-nix/" }, 10 | { title: "Distribute your App", url: "/get-started/distribute-your-app/" }, 11 | { title: "Setup For a Local Event", url: "/get-started/at-an-event/" }, 12 | ] 13 | }, 14 | { title: "Learn", url: "/concepts/1_the_basics/", children: [ 15 | { title: "Application Architecture", url: "/concepts/2_application_architecture/" }, 16 | { title: "Source Chain", url: "/concepts/3_source_chain/" }, 17 | { title: "DHT", url: "/concepts/4_dht/" }, 18 | { title: "Links and Anchors", url: "/concepts/5_links_anchors/" }, 19 | { title: "CRUD Actions", url: "/concepts/6_crud_actions/" }, 20 | { title: "Validation", url: "/concepts/7_validation/" }, 21 | { title: "Calls and Capabilities", url: "/concepts/8_calls_capabilities/" }, 22 | { title: "Signals", url: "/concepts/9_signals/" }, 23 | { title: "Countersigning", url: "/concepts/10_countersigning/" }, 24 | { title: "Lifecycle Events", url: "/concepts/11_lifecycle_events/" }, 25 | ] 26 | }, 27 | { title: "Build", url: "/build/", children: [ 28 | { title: "Application Structure", url: "/build/application-structure/", children: [ 29 | { title: "Zomes", url: "/build/zomes/", children: [ 30 | { title: "Lifecycle Events and Callbacks", url: "/build/callbacks-and-lifecycle-hooks/" }, 31 | { title: "Zome Functions", url: "/build/zome-functions/" }, 32 | ]}, 33 | { title: "DNAs", url: "/build/dnas/" }, 34 | { title: "hApps", url: "/build/happs/" }, 35 | { title: "Cloning", url: "/build/cloning/" }, 36 | ]}, 37 | { title: "Working with Data", url: "/build/working-with-data/", children: [ 38 | { title: "Identifiers", url: "/build/identifiers/" }, 39 | { title: "Entries", url: "/build/entries/" }, 40 | { title: "Links, Paths, and Anchors", url: "/build/links-paths-and-anchors/" }, 41 | { title: "Querying Source Chains", url: "/build/querying-source-chains/" }, 42 | { title: "Validation Receipts", url: "/build/validation-receipts/" }, 43 | ]}, 44 | { title: "Using the Host API", url: "/build/using-the-host-api/", children: [ 45 | { title: "Cell Introspection", url: "/build/cell-introspection/" }, 46 | { title: "Cryptography Functions", url: "/build/cryptography-functions/" }, 47 | { title: "Miscellaneous Host Functions", url: "/build/miscellaneous-host-functions/" }, 48 | ]}, 49 | { title: "Connecting the Parts", url: "/build/connecting-the-parts/", children: [ 50 | { title: "Front End", url: "/build/connecting-a-front-end/" }, 51 | { title: "Calling Zome Functions", url: "/build/calling-zome-functions/" }, 52 | { title: "Capabilities", url: "/build/capabilities/" }, 53 | { title: "Signals", url: "/build/signals/" }, 54 | ]}, 55 | { title: "Validation", url: "/build/validation/", children: [ 56 | { title: "Genesis Self-Check Callback", url: "/build/genesis-self-check-callback/" }, 57 | { title: "Validate Callback", url: "/build/validate-callback/" }, 58 | { title: "must_get_* Host Functions", url: "/build/must-get-host-functions/" }, 59 | { title: "DHT Operations", url: "/build/dht-operations/" }, 60 | ]}, 61 | ] 62 | }, 63 | { title: "Resources", url: "/resources/", children: [ 64 | { title: "Upgrade Guides", url: "/resources/upgrade/" }, 65 | { title: "HDK", url: "https://docs.rs/hdk", external: true }, 66 | { title: "HDI", url: "https://docs.rs/hdi", external: true }, 67 | { title: "App API", url: "https://docs.rs/holochain_conductor_api/latest/holochain_conductor_api/enum.AppRequest.html", external: true }, 68 | { title: "Admin API", url: "https://docs.rs/holochain_conductor_api/latest/holochain_conductor_api/enum.AdminRequest.html", external: true }, 69 | { title: "Client (Javascript)", url: "https://github.com/holochain/holochain-client-js", external: true}, 70 | { title: "Client (Rust)", url: "https://github.com/holochain/holochain-client-rust", external: true}, 71 | { title: "hc dev tool", url: "https://github.com/holochain/holochain/tree/main/crates/hc", external: true }, 72 | { title: "Glossary", url: "/resources/glossary/" }, 73 | ] 74 | }, 75 | { title: "Get Involved", url: "/get-involved/" }, 76 | ] 77 | } 78 | -------------------------------------------------------------------------------- /src/pages/_includes/base-layout.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% include "parts/head.njk" %} 4 | 5 | 6 | {% include "parts/header.njk" %} 7 | {% renderlayoutblock "abovePageWrap" %}{% endrenderlayoutblock %} 8 | 9 | {{ content | safe }} 10 | 11 | {% renderlayoutblock "belowPageWrap" %}{% endrenderlayoutblock %} 12 | 13 | {% include "parts/footer.njk" %} 14 | {% include "parts/templates.njk" %} 15 | {% include "widgets/unsupported-brower-warning.njk" %} 16 | 17 | -------------------------------------------------------------------------------- /src/pages/_includes/default-page-layout.njk: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base-layout.njk 3 | layoutId: default-page-type 4 | surpressH1InLayout: false 5 | --- 6 | {% from "widgets/navigation.njk" import mainNavTree, tocBlock %} 7 | 8 |
9 | {% if not surpressH1InLayout %} 10 |

{{ title }}

11 | {% endif %} 12 | {{ content | safe }} 13 |
14 | 19 | 20 |
21 | 22 | -------------------------------------------------------------------------------- /src/pages/_includes/ds-layout.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% include "parts/head.njk" %} 4 | 5 | 6 |
7 |

{{ title }}

8 | {{ content | safe }} 9 |
10 | 11 | {% include "parts/templates.njk" %} 12 | 13 | -------------------------------------------------------------------------------- /src/pages/_includes/parts/footer.njk: -------------------------------------------------------------------------------- 1 | {% from "widgets/svg-icons.njk" import discordMarkIcon, twitterLogo, githubLogo, youtubeMarkIcon, redditIcon, mastodonIcon %} 2 | 3 | {% macro footerLink(link) %} 4 | {% set classAttr = 'class="'+ link.class + '"' if link.class else '' %} 5 | {% if link.image %} 6 | 7 | 8 | 9 | {% else %} 10 | {{ link.title }} 11 | {% endif %} 12 | {% endmacro %} 13 | 14 | {% macro footerElement(d) %} 15 | {% set classAttr = 'class="'+ d.class + '"' if d.class else '' %} 16 |
  • 17 | {% if d.type === "icon-list" %} 18 | 28 | {% elif d.url %} 29 | {{ footerLink(d) }} 30 | {% else %} 31 | {# Just some text #} 32 | {{ d.title | safe }} 33 | {% endif %} 34 |
  • 35 | {% endmacro %} 36 | 37 | -------------------------------------------------------------------------------- /src/pages/_includes/parts/head.njk: -------------------------------------------------------------------------------- 1 | 2 | {% include "../widgets/analytics.njk" %} 3 | 4 | 5 | 6 | {{ title }} 7 | 8 | 14 | 15 | {% if site.environment == "production" %} 16 | 17 | {% else %} 18 | 19 | {% endif %} 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/pages/_includes/parts/header.njk: -------------------------------------------------------------------------------- 1 | {% from "widgets/svg-icons.njk" import discordMarkIcon, homeIcon, githubLogo, mdiSearch %} 2 | {% from "widgets/assorted-bits.njk" import hamburgerButton %} 3 | {% from "widgets/navigation.njk" import headerNavList %} 4 | -------------------------------------------------------------------------------- /src/pages/_includes/parts/templates.njk: -------------------------------------------------------------------------------- 1 | {% from "widgets/svg-icons.njk" import mdiClose %} 2 | 8 | 9 | -------------------------------------------------------------------------------- /src/pages/_includes/widgets/analytics.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/pages/_includes/widgets/assorted-bits.njk: -------------------------------------------------------------------------------- 1 | {% macro hamburgerButton(buttonId = "menu-toggle") %} 2 | 9 | {% endmacro %} -------------------------------------------------------------------------------- /src/pages/_includes/widgets/home-tiles.njk: -------------------------------------------------------------------------------- 1 | {% from "widgets/svg-icons.njk" import rocketshipIcon, lightBulbIcon, craneIcon, toolPanelIcon, personReadingIcon %} 2 |
    3 | {% linkTile "/get-started/", "home-tile" %} 4 | {{ rocketshipIcon() }} 5 |
    6 |

    Get Started

    7 |

    Install Holochain and create an app

    8 |
    9 | {% endlinkTile %} 10 | 11 | {% linkTile "/concepts/1_the_basics/", "home-tile" %} 12 | {{ lightBulbIcon() }} 13 |
    14 |

    Core Concepts

    15 |

    Introducing Holochain basics

    16 |
    17 | {% endlinkTile %} 18 | 19 | {% linkTile "/build/", "home-tile" %} 20 | {{ craneIcon() }} 21 |
    22 |

    Build Guide

    23 |

    Learn how to write and deploy Holochain applications

    24 |
    25 | {% endlinkTile %} 26 | 27 | {% linkTile "/resources/", "home-tile" %} 28 | {{ toolPanelIcon() }} 29 |
    30 |

    Resources

    31 |

    Howtos, references, examples, tools, libraries, and more

    32 |
    33 | {% endlinkTile %} 34 | 35 | {% linkTile "https://discord.gg/MwPvM4Vffg", "home-tile" %} 36 | {{ personReadingIcon() }} 37 |
    38 |

    Discord Community

    39 |

    Discuss Holochain

    40 |
    41 | {% endlinkTile %} 42 |
    -------------------------------------------------------------------------------- /src/pages/_includes/widgets/navigation.njk: -------------------------------------------------------------------------------- 1 | {% from "widgets/svg-icons.njk" import downArrowHead, mdiSearch %} 2 | 3 | @{% macro children(navData, isCurrentParent, page) %} 4 | 19 | {% endmacro %} 20 | 21 | @{% macro mainNavTree(mainNavData, page) %} 22 | {% set activeParent = mainNavData.getActiveParentLink(page.url) %} 23 | 48 | {% endmacro %} 49 | 50 | @{% macro headerNavList(headerNavData, page) %} 51 | {% set activeParent = headerNavData.getActiveParentLink(page.url) %} 52 | 61 | {% endmacro %} 62 | 63 | {% macro tocBlock(tocData) %} 64 | {% if tocData and tocData|length %} 65 | 84 | {% endif %} 85 | {% endmacro %} -------------------------------------------------------------------------------- /src/pages/_includes/widgets/unsupported-brower-warning.njk: -------------------------------------------------------------------------------- 1 | {% from "widgets/svg-icons.njk" import edgeIcon, firefoxIcon %} 2 | 3 | 20 | 21 |
    22 |
    23 |
    24 | It looks like you are using Internet Explorer. While the basic content is available, 25 | this is no longer a supported browser by the manufacturer, and no attention is being given to having IE work well here. 26 |
    27 |
    28 |
    29 |
    30 | Firefox, Edge and Chrome are all excellent browsers to use instead. 31 | Click one of the icons below to download. 32 |
    33 | 43 |
    44 |
    45 |
    46 | 47 | -------------------------------------------------------------------------------- /src/pages/build/application-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Application Structure 3 | --- 4 | 5 | ::: topic-list 6 | ### In this section {data-no-toc} 7 | 8 | * Application Structure (this page) 9 | * [Zomes](/build/zomes/) --- integrity vs coordinator, how to structure and compile 10 | * [Lifecycle Events and Callbacks](/build/callbacks-and-lifecycle-hooks/) --- writing functions that respond to events in a hApp's lifecycle 11 | * [Zome Functions](/build/zome-functions/) --- writing your hApp's back-end API 12 | * [DNAs](/build/dnas/) --- what they're used for, how to specify and bundle 13 | * [hApps](/build/happs/) --- headless vs UI-based, how to bundle and distribute 14 | * [Cloning](/build/cloning/) --- working with clones of a DNA 15 | ::: 16 | 17 | ::: intro 18 | There are a few basic units of composability and packaging you'll need to know about when you're structuring your hApp. Each has different purposes, and the way you break up your code makes a difference to how it works in terms of access, privacy, participant responsibilities, and code reuse. 19 | ::: 20 | 21 | ## Zomes, DNAs, and hApps 22 | 23 | ### Zome 24 | 25 | The smallest unit in a hApp is called a **zome** (a play on DNA chromosomes). It's the actual binary code that runs in Holochain's [WebAssembly](https://webassembly.org/) sandbox. 26 | 27 | !!! info Why WebAssembly? 28 | 29 | We chose WebAssembly because: 30 | 31 | * A [number of languages](https://github.com/appcypher/awesome-wasm-langs) can already be compiled to WebAssembly, which we hope will mean Holochain can support many languages on the back end in the future (currently we only supply a back-end SDK for Rust.) 32 | * It's small and fast --- it can get compiled to machine code for near-native speed. 33 | * Holochain is written in Rust, and Rust has an excellent WebAssembly engine called [Wasmer](https://wasmer.io/) that works on all the major operating systems. 34 | * It provides a secure sandbox to run untrusted code within. 35 | 36 | !!! 37 | 38 | A zome has access to Holochain via the **host API** and also exposes functions of its own. Some of these functions are **callbacks** and some of them you invent yourself to create your back end's API. 39 | 40 | There are two kinds of zome: 41 | 42 | * An **integrity zome** defines a set of data types --- your application's schema --- and validation rules for operations that create, update, or delete data of those types; in other words, your data model. 43 | * A **coordinator zome** defines a set of functions for interacting with data, peers, and other coordinator zomes. 44 | 45 | Zomes are usually created as pairs --- an integrity zome that defines a data model and a coordinator zome that defines functions for operating on this model. You don't have to do it this way though; coordinator zomes don't need an integrity zome if they don't manipulate data, or they can depend on multiple integrity zomes, or multiple coordinators can depend on the same integrity zome. 46 | 47 | If you mean for your zomes to be reused by other projects, you can share them via a public Git repository or [crates.io](https://crates.io) (tag your crates with `#holochain` so others can find them). 48 | 49 | [Read more on the Zomes page](/build/zomes/). 50 | 51 | ### DNA 52 | 53 | One or more zomes are bundled into a **DNA**, including at least one integrity zome. When two or more agents install and run a DNA, a new peer-to-peer network is created among them to interact and store shared data. 54 | 55 | **A DNA, and the network created for it, is uniquely defined by its integrity zomes, plus any modifiers.** The hash of the integrity zomes plus modifiers is called the **DNA hash**, and is the unique identifier for the network. 56 | 57 | !!! info Why are coordinator zomes not included in the DNA hash? 58 | 59 | Coordinator zomes are bundled with a DNA, but they don't contribute to its hash's uniqueness. That's because they don't constitute the 'rules of the game' for a network like integrity zomes do. 60 | 61 | This means you can hot-swap coordinators as you fix bugs and add features, without changing the DNA hash and creating a new network, which we sometimes call **forking**. The only things that should cause a fork are changes to integrity code. 62 | 63 | !!! 64 | 65 | Because each DNA has its own separate peer network and data store, you can use the DNA concept to come up with creative approaches to [privacy](https://dialnet.unirioja.es/servlet/articulo?codigo=8036267) and access, separation of responsibilities, or data retention. 66 | 67 | [Read more on the DNAs page](/build/dnas/). 68 | 69 | ### hApp {#happ} 70 | 71 | One or more DNAs come together in a **hApp** (Holochain app). Each DNA fills a named **role** in the hApp, and you can think of it like a [microservice](https://en.wikipedia.org/wiki/Microservices). 72 | 73 | Each agent generates their own public/private key pair when they install a hApp. Their public key acts as their **agent ID** which identifies them as a participant in all the networks created for all the DNAs in the hApp. When a DNA is activated, it's bound to this key pair and becomes a **cell**. 74 | 75 | The hApp can specify two provisioning strategies for its DNAs: 76 | 77 | * A cell can be instantiated at app installation time. 78 | * A new cell can be **cloned** from an existing DNA at any time _after the hApp is installed_, with an optional limit on the number of clones. 79 | 80 | A hApp can optionally include a web-based UI that [supporting Holochain runtimes](/get-started/4-packaging-and-distribution/#runtimes) can serve to the user. 81 | 82 | !!! info A hApp always runs locally {#local} 83 | 84 | The big difference with peer-to-peer stacks like Holochain is that **all the code** --- both the back end and the front end --- **runs on the devices of the participants themselves**. 85 | 86 | That means that a DNA doesn't exist as some piece of code that runs 'out there somewhere' --- instead it runs from the perspective of an individual. DNA + agent = cell. 87 | 88 | There can still be bots or system-level services that do automated tasks. Those functions just have to be handled by one of the agents, and that agent doesn't have to be a human. 89 | 90 | !!! 91 | 92 | [Read more on the hApps page](/build/happs/). 93 | 94 | ## Further reading 95 | 96 | * Core Concepts: [Application Architecture](/concepts/2_application_architecture) -------------------------------------------------------------------------------- /src/pages/build/connecting-a-front-end.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Connecting a Front End" 3 | --- 4 | 5 | ::: intro 6 | Front ends connect to a hApp via the **application API** over a local [WebSocket](https://en.wikipedia.org/wiki/WebSocket) interface. They can call [**zome functions**](/build/zome-functions/) and listen to [**signals**](/concepts/9_signals/), and can also do some app management tasks like **cloning** a cell and getting info about the hApp. 7 | ::: 8 | 9 | ## Where a front end runs 10 | 11 | The most important thing to remember about a hApp is that it runs in the Holochain conductor **on each of the devices of the agents themselves**, whether those agents are humans, bots, or headless services. Holochain itself is just an engine for a hApp's back end, so it exposes the hApp's API (its zome functions) and lets front ends connect to the hApp via a WebSocket interface. 12 | 13 | This interface is **only exposed to processes on the local device**, not to external network adapters. This helps prevent unauthorized agents from accessing the hApp. It also means the front end must be distributed with the hApp and a Holochain runtime. 14 | 15 | Some Holochain runtimes bundle the conductor and a front end host that serves your HTML/JavaScript-based runtimes. Take a look at the [Packaging and Distribution](/get-started/4-packaging-and-distribution/) page from the Get Started guide for the choices. 16 | 17 | The Holonix dev environment comes with a runtime called `hc-launch`, which starts Holochain, installs your hApp, and displays a UI for you. The scaffolding tool generates an NPM script that compiles and bundles your back end into a [`.happ` file](/build/happs/#package-a-happ-for-distribution) and starts two instances of the hApp with `hc-launch`. In the root of your project folder, enter: 18 | 19 | ```bash 20 | npm run start 21 | ``` 22 | 23 | (If you're using a different package manager, change this command to suit.) 24 | 25 | ## Front-end libraries 26 | 27 | Holochain provides front-end client libraries for [JavaScript](https://github.com/holochain/holochain-client-js) and [Rust](https://github.com/holochain/holochain-client-rust). The scaffolding tool generates JavaScript-based UIs that are meant to be served as a single-page app, so we'll focus on JavaScript for this documentation --- or more specifically TypeScript, because that's what the client library is written in. 28 | 29 | ## Connect to a hApp with the JavaScript client {#connect-to-a-happ-with-the-javascript-client} 30 | 31 | You connect to the application API with the client's [`AppWebsocket.connect`](https://github.com/holochain/holochain-client-js/blob/main/docs/client.appwebsocket.connect.md) method, which returns a Promise<[AppWebsocket](https://github.com/holochain/holochain-client-js/blob/main/docs/client.appwebsocket.md)>. 32 | 33 | If you've been using the scaffolding tool with the UI option, all the code to establish a connection to a hApp is already written for you. You can get it to build reasonable bootstrap code for Lit, React, Svelte, and Vue that makes the client available to child components once it's connected to a hApp. 34 | 35 | But for now, we're going to give you a simple TypeScript example, inspired by the `ui/index.html` file from a hApp scaffolded with the `vanilla` UI option. We'll call on the function in all the following examples, so that we don't have to create a connection every time. 36 | 37 | ```typescript 38 | import { AppWebsocket, HolochainError } from '@holochain/client'; 39 | 40 | const getHolochainClient = (() => { 41 | let client: AppWebsocket | undefined; 42 | 43 | return async () => { 44 | if (client === undefined) { 45 | client = await AppWebsocket.connect(); 46 | console.log("Connected to Holochain! hApp ID is ${client.installedAppId}"); 47 | } 48 | return client; 49 | }; 50 | })(); 51 | 52 | getHolochainClient().catch((error: HolochainError) => console.error(`Connection failure, name ${error.name}, message ${error.message}`)); 53 | ``` 54 | 55 | You'll notice that you don't have to pass a connection URI to the client. That's because, at time of writing, all Holochain runtimes that serve a web-based UI will inject a constant into the page that contains the URI, and the client will look for that value. So the scaffolding tool expects you'll be distributing your hApp with one of these runtimes. Check out the [`AppWebsocket.connect` documentation](https://github.com/holochain/holochain-client-js/blob/main/docs/client.appwebsocket.connect.md) if you're building a front end that runs separately from a Holochain runtime. 56 | 57 | ## Reference 58 | 59 | * [`AppWebsocket`](https://github.com/holochain/holochain-client-js/blob/main/docs/client.appwebsocket.md) 60 | * [`AppWebsocket.connect`](https://github.com/holochain/holochain-client-js/blob/main/docs/client.appwebsocket.connect.md) 61 | 62 | ## Further reading 63 | 64 | * [Core Concepts: Application Architecture](/concepts/2_application_architecture/) -------------------------------------------------------------------------------- /src/pages/build/connecting-the-parts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Connecting the Parts" 3 | --- 4 | 5 | ::: topic-list 6 | ### In this section {data-no-toc} 7 | 8 | * Connecting the parts (this page) 9 | * [Front end](/build/connecting-a-front-end/) --- establishing a WebSocket connection from JavaScript 10 | * [Calling zome functions](/build/calling-zome-functions) --- examples for front ends, cell-to-cell, and agent-to-agent 11 | * [Capabilities](/build/capabilities/) --- how to manage access to a cell's zome functions 12 | * [Signals](/build/signals/) --- receiving notifications from cells 13 | ::: 14 | 15 | ::: intro 16 | Your hApp back end's public interface consists of all the [**zome functions**](/build/zome-functions/) of all the [**cells**](/concepts/2_application_architecture/#cell) instantiated from all the [**DNAs**](/build/dnas/) that fill the hApp's [**roles**](/build/application-structure/#happ). It is accessible to locally running processes and to network peers, and is secured by a form of [**capability-based security**](/build/capabilities/), adapted for peer-to-peer applications. 17 | 18 | The back end can also send out [**signals**](/build/signals/) that can be received either by UIs or remote peers. 19 | ::: 20 | 21 | ## What processes can connect to a hApp? {#what-processes-can-connect-to-a-happ} 22 | 23 | It's worth mentioning again that **all the components of a hApp backend [run on the devices of the individual agents](/build/application-structure/#local)** as cells representing those agents' autonomy --- their capacity to write their own data to their own source chains. 24 | 25 | With that in mind, these are the kinds of processes that can make calls to a cell's zome functions: 26 | 27 | 1. another coordinator zome in the same cell 28 | 2. another cell in the same hApp on the agent's device 29 | 3. an external client, such as a UI, script, or system service, on the agent's device 30 | 4. another peer in the same network as the cell (that is, sharing the same DNA hash) 31 | 32 | Of these, only number 3, an external client, can listen to local signals emitted by a zome function. (There's another kind of signal, a remote signal, that's sent between peers in a network. It's actually just a zome function with a special name.) 33 | 34 | ### How does a process connect? 35 | 36 | For cases 1 and 2 above, the Holochain conductor handles inter-process communication between cells. For case 3, Holochain exposes a WebSocket interface for clients to call. And for case 4, the two peers' conductors handle the zome call over the network. 37 | 38 | ## Securing zome functions against unauthorized access 39 | 40 | An agent naturally doesn't want any remote peer calling any of their zome functions, and even local processes should be restricted in case of poorly written DNAs or malware processes on the machine. Holochain uses a modified form of [capability-based security](https://en.wikipedia.org/wiki/Capability-based_security) to secure zome function access. 41 | 42 | Capability-based security, in short, says that you should never give out direct access to a resource such as a file or network connection. Instead you mediate access to that resource and give out 'handles' that represent a set of privileges. Holochain expands on this idea by adding the ability to restrict resource access to a certain group of agents, represented by their private keys. 43 | 44 | [Read more about Holochain's capability security system.](/build/capabilities/) 45 | 46 | ## Sending signals for reactive, event-based programming 47 | 48 | Zome functions can [send out signals](/build/signals/), either locally to front ends or remotely to other agents in the same network. This lets you write programs that react to activity rather than having to poll a function for updates. 49 | 50 | ## Further reading 51 | 52 | * [Core Concepts: Application Architecture](/concepts/2_application_architecture/) 53 | * [Core Concepts: Calls and Capabilities](/concepts/8_calls_capabilities/) 54 | * [Core Concepts: Signals](/concepts/9_signals/) -------------------------------------------------------------------------------- /src/pages/build/crud-patterns.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/pages/build/crud-patterns.md -------------------------------------------------------------------------------- /src/pages/build/genesis-self-check-callback.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Genesis Self-Check Callback" 3 | --- 4 | 5 | ::: intro 6 | To enforce access control for a network, a DNA can require a [**membrane proof**](/concepts/3_source_chain/#source-chain-your-own-data-store), which is a piece of data that gets entered by the user and written to their [**source chain**](/concepts/3_source_chain/). The `genesis_self_check` function can guard against user entry error and help prevent them from being accidentally marked as a bad actor. 7 | ::: 8 | 9 | ## Membrane proof: a joining code for a network 10 | 11 | While a [network seed](/build/dnas/#network-seed) acts like a network-wide passcode, you might need to enforce more fine-grained membership control. You can do this by writing validation code for the contents of the[`AgentValidationPkg`](https://docs.rs/holochain_integrity_types/latest/holochain_integrity_types/action/enum.Action.html#variant.AgentValidationPkg) record. This [**genesis record**](/resources/glossary/#genesis-records) contains data that the user enters on app installation. 12 | 13 | A membrane proof can be basic, like an invite code, or it can be something complex like a signature from an agent that has authority to admit members. 14 | 15 | !!! info Membership control isn't implemented yet 16 | This feature is not fully implemented. Currently, validators merely record a validation failure and supply it on request. Our plan is to connect membrane proof validation outcomes to block lists, so agents can reject connection attempts from a peer with an invalid membrane proof. 17 | !!! 18 | 19 | ## The need for basic pre-validation 20 | 21 | Most useful membrane proofs will require access to network data in order to fully validate them. But an agent can't self-validate their own membership proof at genesis time, because they haven't joined the network yet. This creates a minor problem; they may accidentally type or paste their membrane proof wrong, but won't find out until they try to join the network and get blocked by their peers. 22 | 23 | To reduce the risk, you can define a `genesis_self_check` function that checks the membrane proof before network communications start. This function is limited --- it naturally doesn't have access to DHT data -- but it can be a useful guard against basic data entry errors. 24 | 25 | ## Define a `genesis_self_check` callback 26 | 27 | `genesis_self_check` must take a single argument of type [`GenesisSelfCheckData`](https://docs.rs/hdi/latest/hdi/prelude/type.GenesisSelfCheckData.html) and return a value of type [`ValidateCallbackResult`](https://docs.rs/hdi/latest/hdi/prelude/enum.ValidateCallbackResult.html) wrapped in an `ExternResult`. 28 | 29 | Here's an example that checks that the membrane proof exists and is the right length: 30 | 31 | ```rust 32 | use hdi::prelude::*; 33 | 34 | #[hdk_extern] 35 | pub fn genesis_self_check(data: GenesisSelfCheckData) -> ExternResult { 36 | if let Some(membrane_proof) = data.membrane_proof { 37 | if membrane_proof.bytes().len() == 64 { 38 | return Ok(ValidateCallbackResult::Valid); 39 | } 40 | return Ok(ValidateCallbackResult::Invalid("Membrane proof is not the right length. Please check it and enter it again.".into())); 41 | } 42 | Ok(ValidateCallbackResult::Invalid("This network needs a membrane proof to join.".into())) 43 | } 44 | ``` 45 | 46 | This more complex example deserializes an Ed25519 signature and checks that it matches the agent's public key and the public key of an agent with the authority to admit members, which is taken from the DNA's [`properties` block](/build/dnas/#use-dna-properties). {#joining-certificate} 47 | 48 | ```rust 49 | use hdi::prelude::*; 50 | use base64::*; 51 | 52 | // A type for deserializing the DNA properties that this integrity zome needs. 53 | // This struct lets a network creator specify who gets to create joining 54 | // certificates. 55 | #[dna_properties] 56 | pub struct DnaProperties { 57 | // Because the DNA properties are given as YAML, this field should be a 58 | // string that someone can paste in. 59 | authorized_joining_certificate_issuer: AgentPubKeyB64, 60 | } 61 | 62 | #[hdk_extern] 63 | pub fn genesis_self_check(data: GenesisSelfCheckData) -> ExternResult { 64 | let Some(membrane_proof) = data.membrane_proof else { 65 | return Ok(ValidateCallbackResult::Invalid("This network needs a membrane proof to join.".into())); 66 | } 67 | 68 | // Accept a string, because this is something a user can paste into a 69 | // form field. 70 | let Ok(cert: Signature) = std::str::from_utf8(membrane_proof.bytes()) 71 | // Expect it to be Base64-encoded; convert it into raw bytes. 72 | .and_then(|s| BASE64_STANDARD::decode(s)) 73 | // And then into a Signature. 74 | .and_then(|b| b.try_into()) 75 | else { 76 | return Ok(ValidateCallbackResult::Invalid("Couldn't decode membrane proof into joining certificate.")); 77 | } 78 | 79 | // Check the certificate against the signing authority. 80 | let dna_props = DnaProperties::try_from_dna_properties()?; 81 | let cert_is_valid = verify_signature( 82 | dna_props.authorized_joining_certificate_issuer, 83 | cert, 84 | data.agent_key 85 | )?; 86 | if cert_is_valid { 87 | return Ok(ValidateCallbackResult::Valid); 88 | } else { 89 | return Ok(ValidateCallbackResult::Invalid("Joining certificate wasn't valid. Please try entering it again or asking the certificate issuer for a new one.")); 90 | } 91 | } 92 | ``` 93 | 94 | ## Fully validating a membrane proof 95 | 96 | Your `validate` callback also needs to validate a membrane proof in order to actually enforce network access. At the very least, it should apply the same rules as `genesis_self_check` does, and add on any checks that require DHT data. We'll explore this in full on the [`validate` callback](/build/validate-callback/#validate-agent-joining) page. 97 | 98 | ## Reference 99 | 100 | * [`holochain_integrity_types::action::AgentValidationPkg`](https://docs.rs/holochain_integrity_types/latest/holochain_integrity_types/action/enum.Action.html#variant.AgentValidationPkg) 101 | * [`holochain_integrity_types::genesis::GenesisSelfCheckData`](https://docs.rs/holochain_integrity_types/latest/holochain_integrity_types/genesis/type.GenesisSelfCheckData.html) 102 | * [`holochain_integrity_types::validate::ValidateCallbackResult`](https://docs.rs/holochain_integrity_types/latest/holochain_integrity_types/genesis/type.GenesisSelfCheckData.html) 103 | * [`holochain_derive::dna_properties`](https://docs.rs/hdk_derive/latest/hdk_derive/attr.dna_properties.html) 104 | 105 | ## Further reading 106 | 107 | * [Core Concepts: Genesis self-check](/concepts/7_validation/#genesis-self-check) 108 | * [Build Guide: Validation](/build/validation/) -------------------------------------------------------------------------------- /src/pages/build/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Holochain Build Guide 3 | --- 4 | 5 | !!! note In progress 6 | This guide is under construction. Expect more content to be rapidly published in the first half of 2025. 7 | !!! 8 | 9 | ::: intro 10 | This Build Guide organizes everything you need to know about developing Holochain applications into individual topics. Each topic page stands alone as a comprehensive guide to using a given feature or implementing a given functionality. There are lots of code examples which make it clear how to do something yet are generic enough to be universally useful. These examples may not cover every single use case, though, so we'll point you to the reference documentation often. 11 | ::: 12 | 13 | ## Holochain: a very brief overview 14 | 15 | Holochain is a framework for building **peer-to-peer applications**, in which every participant runs the application code on their own device and connects directly to other participants (called their **peers**) to exchange data. 16 | 17 | Holochain's first basic concept is the **agent**, which represents a human or automated participant in a peer-to-peer network. An agent identifies themselves with a self-generated public/private key pair, called their **agent ID**. 18 | 19 | Holochain's second basic concept is the **DNA**, which is a chunk of application back-end code. When you write a Holochain application (which we call a **hApp**), you're writing code that runs sandboxed in a Holochain runtime (called a **conductor**) and responds to function calls from Holochain itself or from external processes such as a UI, system service, or other DNA on the same device, or another peer on the same network. 20 | 21 | When an agent ID is bound to a **DNA**, the live DNA instance is called a **cell** and forms a network with other cells running the same DNA. This network is separate from all other networks formed by other DNAs. 22 | 23 | Now that you've got some basic concepts and the terms we use for them, it's time to dive into application development. 24 | 25 | ## Application structure 26 | 27 | ::: topic-list 28 | * [Overview](/build/application-structure/) --- an overview of Holochain's modularity and composability units 29 | * [Zomes](/build/zomes/) --- integrity vs coordinator, how to structure and compile 30 | * [Lifecycle Events and Callbacks](/build/callbacks-and-lifecycle-hooks/) --- writing functions that respond to events in a hApp's lifecycle 31 | * [Zome Functions](/build/zome-functions/) --- writing your hApp's back-end API 32 | * [DNAs](/build/dnas/) --- what they're used for, how to specify and bundle 33 | * [hApps](/build/happs/) --- headless vs UI-based, how to bundle and distribute 34 | * [Cloning](/build/cloning/) --- working with clones of a DNA 35 | ::: 36 | 37 | ## Working with data 38 | 39 | ::: topic-list 40 | * [Overview](/build/working-with-data/) --- general concepts related to working with data in Holochain 41 | * [Identifiers](/build/identifiers) --- working with hashes and other unique IDs 42 | * [Entries](/build/entries/) --- defining, creating, reading, updating, and deleting data 43 | * [Links, Paths, and Anchors](/build/links-paths-and-anchors/) --- creating relationships between data 44 | * [Querying Source Chains](/build/querying-source-chains/) --- getting data from an agent's history 45 | * [Validation Receipts](/build/validation-receipts/) --- discovering the propagation state of data 46 | ::: 47 | 48 | ## Using the host API 49 | 50 | ::: topic-list 51 | * [Overview](/build/using-the-host-api/) --- accessing host features from a zome 52 | * [Cell Introspection](/build/cell-introspection/) --- finding out info about the DNA, zome, agent, and calling context 53 | * [Cryptography functions](/build/cryptography-functions/) --- key generation, signatures, hashing, and encryption 54 | * [Miscellaneous host functions](/build/miscellaneous-host-functions/) --- system time, logging, randomness 55 | ::: 56 | 57 | ## Connecting the parts 58 | 59 | ::: topic-list 60 | * [Overview](/build/connecting-the-parts/) --- zome calls, capabilities, and signals 61 | * [Front end](/build/connecting-a-front-end/) --- establishing a WebSocket connection from JavaScript 62 | * [Calling zome functions](/build/calling-zome-functions/) --- examples for front ends, cell-to-cell, and agent-to-agent 63 | * [Capabilities](/build/capabilities/) --- how to manage access to a cell's zome functions 64 | * [Signals](/build/signals) --- receiving notifications from cells 65 | ::: 66 | 67 | ## Validation 68 | 69 | ::: topic-list 70 | * [Overview](/build/validation/) --- The purpose of validation in a hApp, abilities, requirements and constraints, determinism 71 | * [Genesis Self-Check Callback](/build/genesis-self-check-callback/) --- Purpose and use cases 72 | * [Validate Callback](/build/validate-callback/) --- Writing validation routines for various needs 73 | * [`must_get_*` Host Functions](/build/must-get-host-functions/) --- Deterministically retrieving DHT data for use in validation 74 | * [DHT operations](/build/dht-operations/) --- advanced details on the underlying data structure used in DHT replication and validation 75 | -------------------------------------------------------------------------------- /src/pages/build/miscellaneous-host-functions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Miscellaneous Host functions" 3 | --- 4 | 5 | ::: intro 6 | This page contains all the host API functions that don't fit into other categories. It covers system time, randomness, and logging. 7 | ::: 8 | 9 | ## Get the system time 10 | 11 | You can get the agent's current system time with the [`sys_time`](https://docs.rs/hdk/latest/hdk/time/fn.sys_time.html) host function, which takes no arguments and returns a result containing a [`Timestamp`](https://docs.rs/kitsune_p2p_timestamp/latest/kitsune_p2p_timestamp/struct.Timestamp.html). _**Note**: This function is only available to coordinator zomes._ 12 | 13 | ```rust 14 | use hdk::prelude::*; 15 | 16 | fn get_time() -> ExternResult { 17 | sys_time() 18 | } 19 | ``` 20 | 21 | ## Generate some random bytes 22 | 23 | To generate some random bytes, use the [`random_bytes`](https://docs.rs/hdk/latest/hdk/random/fn.random_bytes.html) host function, It takes the number of bytes you want and returns a result containing the bytes, wrapped in a [`Bytes`](https://docs.rs/hdk/latest/hdk/prelude/type.Bytes.html) struct. _**Note**: This function is only available to coordinator zomes._ 24 | 25 | ```rust 26 | use hdk::prelude::*; 27 | 28 | fn roll_die(sides: u8) -> ExternResult { 29 | match sides { 30 | 0 => Err(wasm_error!("Can't roll a die with zero sides")), 31 | _ => Ok(random_bytes(1)?[0] % sides + 1), 32 | } 33 | } 34 | 35 | fn reasonably_random_unique_id() -> ExternResult> { 36 | Ok(random_bytes(32)?.into_vec()) 37 | } 38 | ``` 39 | 40 | !!! info `random_bytes` uses the host operating system's random number generator 41 | Holochain just uses whatever random number generator the host operating system provides. The bytes are open in memory as they're passed to the caller, and they're not provably random or repeatable/seedable. Read the [`random_bytes` Rust documentation](https://docs.rs/hdk/latest/hdk/random/fn.random_bytes.html) to help you decide if this function is appropriate for your use case. 42 | !!! 43 | 44 | ## Log things in your zomes 45 | 46 | You can emit log messages from your zomes using Rust's [`tracing`](https://docs.rs/tracing/latest/tracing/) crate. The HDK includes a tracing subscriber that forwards all your tracing calls to the host. This subscriber is active in any public function marked with the `#[hdk_extern]` macro. 47 | 48 | ```rust 49 | use hdi::prelude::*; 50 | 51 | #[hdk_extern] 52 | pub fn foo() -> ExternResult<()> { 53 | trace!("I am a trace message"); 54 | debug!("I am a debug message"); 55 | info!("I am an info message"); 56 | warn!("I am a warning message"); 57 | error!("I am an error message"); 58 | } 59 | ``` 60 | 61 | To set the logging level appropriate to your needs, set the `WASM_LOG` environment variable just like you'd set the `RUST_LOG` environment variable. The host re-emits the messages to its own tracing subscriber (typically this means outputting them to stdout). 62 | 63 | ```bash 64 | WASM_LOG=info hc-spin workdir/my-app.webhapp 65 | ``` 66 | 67 | When the `foo` zome function is called, you'll see: 68 | 69 | ::: output-block 70 | ```text 71 | [hc-spin] | [hc sandbox]: 2025-03-28T21:17:59.566029Z INFO movies:dnas/movies/zomes/coordinator/movies/src/lib.rs:443 I am an info message 72 | [hc-spin] | [hc sandbox]: 2025-03-28T21:17:59.566102Z WARN movies:dnas/movies/zomes/coordinator/movies/src/lib.rs:444 I am a warning message 73 | [hc-spin] | [hc sandbox]: 2025-03-28T21:17:59.566155Z ERROR movies:dnas/movies/zomes/coordinator/movies/src/lib.rs:445 I am an error message 74 | ``` 75 | ::: 76 | 77 | ## Reference 78 | 79 | * [`hdk::time::sys_time`](https://docs.rs/hdk/latest/hdk/time/fn.sys_time.html) 80 | * [`hdk::random::random_bytes`](https://docs.rs/hdk/latest/hdk/random/fn.random_bytes.html) 81 | * [`hdk::trace` module documentation](https://docs.rs/hdk/latest/hdk/trace/index.html) 82 | * [`tracing` crate documentation](https://docs.rs/tracing/latest/tracing/) -------------------------------------------------------------------------------- /src/pages/build/using-the-host-api.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Using the Host API" 3 | --- 4 | 5 | ::: topic-list 6 | ### In this section {data-no-toc} 7 | 8 | * Using the Host API (this page) 9 | * [Cell Introspection](/build/cell-introspection/) --- finding out info about the DNA, zome, agent, and calling context 10 | * [Cryptography functions](/build/cryptography-functions/) --- key generation, signatures, hashing, and encryption 11 | * [Miscellaneous host functions](/build/miscellaneous-host-functions/) --- system time, logging, randomness 12 | ::: 13 | 14 | ::: intro 15 | Holochain hosts back-end code (**zomes**) in a WebAssembly virtual machine and provides a **host API** to them, which the **HDK** library makes easy to use. It allows agents to read and write data, interact with other cells, and access various other host features. 16 | ::: 17 | 18 | ## Accessing the host 19 | 20 | Holochain creates a **sandbox** for zomes to run in, so they can't access the host computer's functionality directly. It exposes a minimal interface for data access, introspection, peer-to-peer interactions, and interop between code modules. You use the HDK (or a minimal subset, the HDI library) to access the host API. The sandbox is implemented as a WebAssembly host, and your zome is a WebAssembly guest. 21 | 22 | !!! info Holochain doesn't expose standard WASM host APIs 23 | Holochain's host API is a small feature set written explicitly for interacting with Holochain's feature set. It doesn't include the WebAssembly JavaScript API or the WebAssembly System Interface (WASI). 24 | !!! 25 | 26 | A lot of this is covered elsewhere already --- [Working with Data](/build/working-with-data/) and [Validation](/build/validation/) talk about data access functions, and [Connecting the Parts](/build/connecting-the-parts/) talks about interop. 27 | 28 | There are a few other functions that don't fall into those categories, so we'll cover them here in three categories: **introspection**, **cryptography**, and **miscellaneous functions**. -------------------------------------------------------------------------------- /src/pages/concepts/9_signals.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Signals: Communicating without waiting for a response" 3 | --- 4 | 5 | ::: intro 6 | 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. 7 | ::: 8 | 9 | ::: orientation 10 | ### What you'll learn 11 | 12 | 1. [When signals are useful](#when-are-signals-useful) 13 | 2. [Where you can send a signal to](#local-and-remote-signals) 14 | 3. [What signals should not be used for](#when-not-to-use-signals) 15 | 4. [What the future holds](#the-future-pub-sub) 16 | 17 | ### Why it matters 18 | 19 | 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. 20 | ::: 21 | 22 | ![](/assets/img/concepts/9.1-signals.png){.sz80p} {.center} 23 | 24 | ## When are signals useful? 25 | 26 | Most connected applications are heavily interactive. Chat messages appear, notification badges change, documents show real-time updates from collaborators, your opponent moves her knight, and so on. This aliveness is the heartbeat of the modern app. 27 | 28 | So far we've only described a DNA as a collection of functions that you can call. And it is. You can make your app feel fairly responsive by having the UI regularly poll a function such as `get_messages_for_chat_channel`, but this feels old-fashioned and can hurt performance. 29 | 30 | **Signals** extend a DNA's communication ability beyond mere function calls, allowing a cell to broadcast messages to local clients or remote cells. Just like [zome function calls](../8_calls_capabilities/), they pass information to a receiver. But unlike zome function calls, they don't expect the receiver to respond. Like most other payloads, the information is just bytes and can contain any sort of data you like. 31 | 32 | ## Local and remote signals 33 | 34 | There are two kinds of signals. One goes to the client; the other goes to another agent on a DHT. 35 | 36 | ### Local signals 37 | 38 | ![](/assets/img/concepts/9.2-client-signal.png){.sz80p} {.center} 39 | 40 | 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. 41 | 42 | You would typically use this in functions that are not called by a client, such as functions that are meant to be called remotely by other agents in the network, by bridged cells on the user's own machine, or by lifecycle event callbacks such as scheduled functions and post-commit callbacks. 43 | 44 | ### Remote signals 45 | 46 | ![](/assets/img/concepts/9.3-remote-signal.png){.sz80p} {.center} 47 | 48 | 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. 49 | 50 | This is a lot faster too --- if Bob needs to send a message to fifty people, with remote calls he'd have to make a call to each recipient, wait for a response or a timeout, and move on to the next. Remote signals, on the other hand, let him specify multiple recipients, send off the message, and move on with function execution. The conductor will send it off to all recipients in parallel. 51 | 52 | ## When not to use signals 53 | 54 | As signals don't receive a response, there's no way to tell whether the recipient has actually received the message or acted upon it. It's not safe to use a signal for mission-critical message delivery such as within a [countersigning](../10_countersigning) session. If you do use it to facilitate important activities, make sure there's also a slower but more dependable way of accessing the message's information. For remote signals, this could include Bob following up with Alice via remote calls or publishing the signal data to the DHT; for local signals that update the UI, the UI could also poll for new source chain or DHT data on a slower interval. 55 | 56 | ## The future: pub/sub 57 | 58 | Signals are a fairly simple construct right now, and it's likely that your app will have complex performance or security requirements that mean not all signals should be broadcast everywhere. We intend to introduce a [publish/subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) model to signals so that clients and remote cells can ask to receive certain messages and not others, while DNA code can approve or reject those requests. We also plan to implement signals for DHT events, such as new entries, [CRUD actions](../6_crud_actions/), or [links](../5_links_anchors/) on a base. 59 | 60 | ## Key takeaways 61 | 62 | * Signals allow a cell to communicate with listeners without expecting a response. 63 | * Signals can be used to avoid 64 | * A signal doesn't have guaranteed delivery because there's no way to tell whether it's been received. 65 | * A signal is simply a message payload consisting of arbitrary bytes. 66 | * Local signals are emitted over the WebSocket application interface to listening clients, and are most useful when emitted from a function call that wasn't triggered by the listening client. 67 | * Remote signals are emitted over the network transport to listening cells within the same network. 68 | 69 | ### Next Up 70 | 71 | [Learn about countersigning →](../10_countersigning/){.btn-purple} -------------------------------------------------------------------------------- /src/pages/ds/code-fences.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Holochain Dev Portal Design System - Code Fences 3 | layout: ds-layout.njk 4 | layoutId: ds-layout-type 5 | pageStyleId: design-system-code-fences 6 | --- 7 | 8 | Examples of code fence look and feel 9 | 10 |
    11 | 12 | ## Code Blocks 13 | 14 | ### With Copy button 15 | 16 | Single line 17 | ```shell 18 | nix run github:/holochain/holochain#hc-scaffold -- web-app 19 | ``` 20 | 21 | Multiple line 22 | ```text 23 | ? Choose UI framework: › 24 | ❯ Vue 25 | Svelte 26 | Lit 27 | ``` 28 | 29 | ### Without Copy button 30 | 31 | To surpress the copy button you can wrap the code block in a `::: output-block` container 32 | 33 | Single line 34 | ::: output-block 35 | ```shell 36 | nix run github:/holochain/holochain#hc-scaffold -- web-app 37 | ``` 38 | 39 | Multiple line 40 | ```text 41 | ? Choose UI framework: › 42 | ❯ Vue 43 | Svelte 44 | Lit 45 | ``` 46 | ::: 47 | 48 |
    -------------------------------------------------------------------------------- /src/pages/ds/containers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Holochain Dev Portal Design System - Code Fences 3 | layout: ds-layout.njk 4 | layoutId: ds-layout-type 5 | pageStyleId: design-system-containers 6 | --- 7 | 8 | !!! note 9 | To avoid the meta-ness of trying to code-fence markdown, please look at the source .md files for how to write the markdown. The browser version will serve as reference of what it will look like. Also note that most of these elements are not standard md so they will not show up in their final expression in the Github or VS Code previews. 10 | !!! 11 | 12 | There are a number of custom extensions to the `markdown-it-container` plugin that we have implemented. 13 | Note: `markdown-it-container` requires that each container be specifically implemented, so you can't just use `!!! newblock` or similar. 14 | 15 | Accept as noted attribute blocks (exp: `{#an-id .a-class target=_blank}`) will be honored and express as attributes in the resulting tag. 16 | 17 | ## Details 18 | Render a Detail/Summary block. 19 | !!! details The summary text 20 | 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 21 | !!! 22 | 23 | The contents of the details tag after the summary tag is wrapped in a div with a class of `details-content`. If an attributes block is applied to the `details` line the attributes are applied to overall `
    ` tag. 24 | 25 | Details synonyms: These get the block name as an extra class name. 26 | !!! dig-deeper The Dig Deeper summary text 27 | 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 28 | !!! 29 | 30 | ## Output Block 31 | Can wrap around code fences to prevent Copy buttons form being added to the code block. See [Code Fences](../code-fences/) for details. 32 | 33 | ## Admonitions 34 | 35 | - ### Tip 36 | #### No Title 37 | !!! tip {#tip} 38 | Tip contents 39 | !!! 40 | 41 | #### With a Title 42 | !!! tip Very Impressive Title Text 43 | Tip contents 44 | !!! 45 | 46 | - ### Note 47 | #### No Title 48 | !!! note 49 | Note contents 50 | !!! 51 | 52 | #### With a Title 53 | !!! note Very Impressive Title Text 54 | Note contents 55 | !!! 56 | 57 | - ### Info 58 | #### No Title 59 | !!! info 60 | Info contents 61 | !!! 62 | 63 | #### With a Title 64 | !!! info Very Impressive Title Text 65 | Info contents 66 | !!! 67 | 68 | - ### Learn 69 | #### No Title 70 | !!! learn 71 | Learn contents 72 | !!! 73 | 74 | #### With a Title 75 | !!! learn Very Impressive Title Text 76 | Learn contents 77 | !!! 78 | 79 | ## Site content specific containers 80 | 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. 81 | 82 | - ### intro 83 | ::: intro 84 | 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. 85 | ::: 86 | 87 | - ### orientation 88 | ::: orientation 89 | 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. 90 | ::: 91 | 92 | - ### storystep 93 | ::: storystep 94 | 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. 95 | ::: 96 | 97 | -------------------------------------------------------------------------------- /src/pages/ds/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Holochain Dev Portal Design System 3 | layout: ds-layout.njk 4 | layoutId: ds-layout-type 5 | pageStyleId: design-system 6 | --- 7 | 8 | A collection of design elements used in the Dev Portal for reference and UX review. Not intended to be linked to in public sources. 9 | 10 | !!! note 11 | To avoid the meta-ness of trying to code-fence markdown, please look at the source .md files for how to write the markdown. The browser version will serve as reference of what it will look like. Also note that most of these elements are not standard md so they will not show up in their final expression in the Github or VS Code previews. 12 | !!! 13 | 14 | [Code Fences](./code-fences/) 15 | 16 | [Containers](./containers/) -------------------------------------------------------------------------------- /src/pages/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holochain/docs-pages/13eafef227d00c7b1e16e9f902944040a2ce6644/src/pages/favicon.ico -------------------------------------------------------------------------------- /src/pages/get-involved.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Get Involved 3 | --- 4 | 5 | Regardless of your experience level as a developer, we encourage you to get involved and stay connected. Here are a few ways to start: 6 | 7 | ### Jump in and get your feet wet 8 | 9 | * Read through our [Core Concepts](/concepts/1_the_basics/) 10 | * Track development progress with the biweekly [Holochain Dev Pulse](https://blog.holochain.org/tag/dev-pulse/) 11 | 12 | ### Connect and contribute 13 | 14 | * Discuss everything related to Holochain and hApp development in the [DEV.HC channel on Discord](https://discord.gg/MwPvM4Vffg) 15 | * Contribute to the conversation on our [Holochain Developer Forum](https://forum.holochain.org/) 16 | * Sign up for the [Holochain Blog](http://blog.holochain.org#subscribe) to stay up to date 17 | * Follow us on social media ([Facebook](https://www.facebook.com/holochain.design) and [Twitter](https://twitter.com/holochain)) 18 | -------------------------------------------------------------------------------- /src/pages/get-started/at-an-event.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Set Up For a Local Event 3 | --- 4 | 5 | ## Prepare your development environment 6 | 7 | If you have not already done so, please follow the first step in the [Get Started](/get-started/) guide which asks you to run the `setup.sh` script. Then you should come back to this page and configure the local cache before proceeding with verifying your Nix setup in the quick start guide. 8 | 9 | The rest of this guide assumes you have either done this or created an equivalent environment manually. 10 | 11 | ## Configure Nix to use a local cache 12 | 13 | 14 | The quick start `setup.sh` script configures Nix to use `https://holochain-ci.cachix.org` as a cache. This significantly speeds up launching the Holonix development environment. It works well for individuals, but at live events it requires a lot of bandwidth with multiple people downloading large amounts of files at the same time. To improve the experience for everyone, a cache can be provided locally. This section shows you how to connect to the local cache. 15 | 16 | The event hosts need to provide you with a cache name. This will be unique per event! Replace `` with the provided name in the command below. 17 | 18 | At a command line: 19 | 20 | ```shell 21 | bash <(curl https://holochain.github.io/holochain/configure-cache.sh) use 22 | ``` 23 | 24 | The script will tell you what it's changing and may ask for confirmation for some changes. It may also prompt for your password if it needs to make changes to files owned by the root user. 25 | 26 | At the end of the event, you shouldn't keep these configuration changes. You can run another command to remove all the configuration that the first command added. 27 | 28 | At a command line: 29 | 30 | ```shell 31 | bash <(curl https://holochain.github.io/holochain/configure-cache.sh) cleanup 32 | ``` 33 | -------------------------------------------------------------------------------- /src/pages/get-started/distribute-your-app.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Distribute your App 3 | --- 4 | 5 | ## Packaging a Web-hApp archive 6 | 7 | At some stage in the app development you'll want to deploy your hApp for others to use it. For this, you will need to package it into a `.webhapp` file that contains both the back-end and the front-end code of your hApp. 8 | 9 | If you've created the hApp with the `hc scaffold` cli tool, all you need to do is: 10 | 11 | ```shell 12 | npm run package 13 | ``` 14 | 15 | The app bundle ending in `.webhapp` will be available in the project root's `workdir` folder. Now you can deploy it to a place where users can download it or directly share it with peers you want to use it with. 16 | 17 | To bundle manually and for extended details on Web-hApps, refer to the packaging steps in the [Github repo of the Holochain Launcher](https://github.com/holochain/launcher#packaging-a-web-happ). 18 | 19 | ## Installing the app using the Holochain Launcher 20 | 21 | Holochain provides the Holochain Launcher, a graphical user interface, to install, run and administrate hApps. [Download Holochain Launcher](https://github.com/holochain/launcher/releases) 22 | 23 | To publicly share your bundled hApp through the Holochain Launcher, follow the [instructions on how to publish it to the DevHub](https://github.com/holochain/launcher#publishing-and-updating-an-app-in-the-devhub) in the README of the Holochain Launcher. 24 | 25 | Another option is to [install a hApp locally from an app bundle on the file system](https://github.com/holochain/launcher#installing-a-holochain-app-happ). Other users will need to obtain the bundled app file and install it to their Launcher. -------------------------------------------------------------------------------- /src/pages/get-started/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Get Started 3 | --- 4 | 5 | Welcome to the Getting Started with Holochain guide! This is a four-page guide which 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. 6 | 7 | ## How to use this guide 8 | 9 | Follow this guide step by step. All steps are essential to create the example applications. No additional code or steps are needed. 10 | 11 | There's a lot of additional explanation that isn't necessary for building the application, but it'll help you understand what you're doing in more depth. Look for the book icon and the 'Learn more' heading. 12 | 13 | * 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. 14 | * We assume that you are reading this guide because you're a developer who's new to Holochain but is interested in actually building peer-to-peer distributed applications using a framework that is agent-centric, that provides intrinsic data integrity, is scalable, and runs just on the devices of the participants without relying on centralized servers, blockchain tokens, or other points of centralized control. 15 | * 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. 16 | * Because Holochain's DNAs 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. 17 | * 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/). 18 | * We also assume that you have basic familiarity with the Unix command line. 19 | 20 | ## 1. Introduction to Holochain 21 | 22 | Holochain is a framework for building peer-to-peer distributed applications, also known as hApps. It emphasizes agent-centric architecture, intrinsic data integrity, and scalability. Holochain enables developers to build applications that run on just the devices of the participants without relying on centralized servers or blockchain tokens. 23 | 24 | ## 2. Installing Holochain development environment 25 | 26 | In this section, we'll walk you through the step-by-step process of installing Holochain, its dependencies, and developer tools on your system so that you can develop hApps. 27 | 28 | ### 2.1. Hardware requirements 29 | 30 | Before you install the Holochain development environment, make sure your system meets the following hardware requirements: 31 | 32 | * 8GB+ RAM (16GB+ recommended) 33 | * 4+ cores CPU (6+ cores recommended) 34 | * 30GB+ available disk space 35 | * High-speed internet connection 36 | 37 | This may seem like a lot; it's mainly due to Rust's compiler, which requires a lot of system resources. 38 | 39 | ### 2.2. Windows prerequisite: WSL2 {#2-2-windows-prerequisite-wsl2} 40 | 41 | For Windows users, please note that the Nix package manager, which is used to install and manage the Holochain development environment, only supports macOS and Linux. You'll need to [install Linux under Windows with WSL2 (Windows Subsystem for Linux)](https://learn.microsoft.com/en-us/windows/wsl/install) (recommended) or dual-boot a Linux OS alongside your [Windows 10](https://www.freecodecamp.org/news/how-to-dual-boot-windows-10-and-ubuntu-linux-dual-booting-tutorial/) or [Windows 11](https://www.xda-developers.com/dual-boot-windows-11-linux/) OS to proceed. 42 | 43 | Holochain is supported in WSL2 via the Ubuntu distribution. 44 | 45 | You'll also need to install a few packages if you want to run two dev tools, `hc spin` and `hc launch`, which start your app's back end and open its GUI in Electron or Tauri webviews: 46 | 47 | ```shell 48 | sudo apt install -y libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libgtk-3-dev libasound2t64 adwaita-icon-theme 49 | ``` 50 | 51 | Read more about these fixes in the [Dev Tools Setup guide](/get-started/install-advanced/#opening-your-happs-gui-in-ubuntu-on-wsl2). 52 | 53 | ### 2.3. Set up development environment 54 | 55 | Once you've ensured that your system meets the hardware requirements and set up WSL2 on Windows or a dual-boot Linux OS (if applicable), you can proceed with the installation of the Nix package manager and the binary package cache for Holochain. 56 | 57 | Open a command-line terminal ([on Linux](https://ubuntu.com/tutorials/command-line-for-beginners#3-opening-a-terminal), [on macOS](https://support.apple.com/en-gb/guide/terminal/pht23b129fed/mac)) and run the following command: 58 | 59 | ```shell 60 | bash <(curl https://holochain.github.io/holochain/setup.sh) 61 | ``` 62 | 63 | This command downloads the setup script and runs it, installing the Nix package manager and setting up a package cache for Holochain. 64 | 65 | ### 2.4. Verify installation 66 | 67 | In a new terminal session type: 68 | 69 | 70 | 71 | ```shell 72 | nix run --refresh -j0 -v "github:holochain/holonix?ref=main-0.5#hc-scaffold" -- --version 73 | ``` 74 | 75 | Look out for binaries being copied from `holochain-ci.cachix.org`: 76 | 77 | ::: output-block 78 | ```text 79 | downloading 'https://holochain-ci.cachix.org/nar/.nar.zst'... 80 | ``` 81 | ::: 82 | 83 | It proves that the package cache is configured correctly. 84 | 85 | At the end of the output, Holochain's scaffolding tool should print its version string, which will be something like this: 86 | 87 | 88 | ::: output-block 89 | ```text 90 | holochain_scaffolding_cli 0.500.0 91 | ``` 92 | ::: 93 | 94 | Congratulations! The Holochain development environment is now set up successfully on your system. 95 | 96 | ### Next up 97 | 98 | Now it's time to download, compile, and try an example Holochain application. 99 | 100 | [Try 'Hello World' →](/get-started/2-hello-world/){.btn-purple} -------------------------------------------------------------------------------- /src/pages/get-started/install-without-nix.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Setup without Nix (currently unsupported) 3 | hide: 4 | - toc 5 | --- 6 | 7 | ::: intro 8 | 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. 9 | ::: 10 | 11 | !!! note Unsupported 12 | Holonix is the recommended way to set up your development environment. 13 | **We don't provide support for installing Holochain without Holonix.** 14 | !!! 15 | 16 | ## Install Holochain without Holonix 17 | 18 | In case you don't want to use Holonix to set up your development environment, here are the steps provided to install Holochain binaries directly 19 | from the crate registry. At first the required Rust toolchain and features are installed, followed by the actual Holochain dependencies. 20 | 21 | 22 | ### Ubuntu-based Linux distributions 23 | 24 | #### Install the Rust toolchain and build dependencies 25 | 26 | 1. Follow the official [Rust toolchain installation](https://www.rust-lang.org/tools/install) 27 | 2. Install the required target to build WebAssembly binaries 28 | ```shell 29 | rustup target add wasm32-unknown-unknown 30 | ``` 31 | 3. Linux build tools 32 | ```shell 33 | sudo apt-get install build-essential 34 | ``` 35 | 4. OpenSSL 36 | ```shell 37 | sudo apt-get install libssl-dev 38 | ``` 39 | 5. Build dependency for Cargo libraries 40 | ```shell 41 | sudo apt-get install pkg-config 42 | ``` 43 | 44 | #### Install Holochain binaries 45 | 46 | The following commands will compile and install the binaries into your user's profile. 47 | It will overwrite any pre-existing binaries, also in the case where its already the latest version. 48 | 49 | ```shell 50 | cargo install --force holochain 51 | ``` 52 | ```shell 53 | cargo install --force holochain_cli 54 | ``` 55 | ```shell 56 | cargo install --force lair_keystore 57 | ``` 58 | ```shell 59 | cargo install --force holochain_cli_launch 60 | ``` 61 | ```shell 62 | cargo install --force holochain_scaffolding_cli 63 | ``` -------------------------------------------------------------------------------- /src/pages/index.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: Holochain Developer Portal 3 | layout: default-page-layout.njk 4 | pageStyleId: home-page 5 | surpressH1InLayout: true 6 | --- 7 | 8 | {% layoutblock "abovePageWrap" %} 9 | 16 | 17 |
    18 |
    19 | 20 | 21 | 22 | 23 | 24 |
    25 | 26 |

    Holochain

    27 |

    A framework for building distributed P2P apps

    28 | Get Started 29 |
    30 | {% endlayoutblock %} 31 | 32 | {% include "src/pages/_includes/widgets/home-tiles.njk" %} 33 | 34 |
    35 | 36 |
    37 |
    38 |

    Serverless

    39 |

    The community is the infrastructure. Scale with the popularity of your app.

    40 |
    41 | 42 |
    43 |

    Connectable

    44 |

    Access other Holochain apps as if they were part of your codebase. No HTTP client, just function calls with optional access control.

    45 |
    46 | 47 |
    48 |

    Resilient

    49 |

    Compute and data live at the edges, which means there’s no infrastructure for you to maintain and defend.

    50 |
    51 |
    52 | 53 |
    -------------------------------------------------------------------------------- /src/pages/pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "default-page-layout.njk" 3 | } -------------------------------------------------------------------------------- /src/pages/resources/upgrade/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Upgrade Guides 3 | hide: 4 | - toc 5 | --- 6 | 7 | ### Upgrade Guides 8 | 9 | Upgrading between versions of Holochain can be a bit tricky! While Holochain is in beta, you can expect breaking changes between minor versions. To make upgrading your hApp easier, we create guides to help you move from one Holochain version to the next. 10 | 11 | 12 | 13 | * [Upgrading to the new Holonix](/resources/upgrade/upgrade-new-holonix/) (all Holochain versions) 14 | * [Holochain Upgrade 0.4 → 0.5](/resources/upgrade/upgrade-holochain-0.5/) 15 | * [Holochain Upgrade 0.3 → 0.4](/resources/upgrade/upgrade-holochain-0.4/) 16 | * [Holochain Upgrade 0.2 → 0.3](/resources/upgrade/upgrade-holochain-0.3/) 17 | * [Holochain Upgrade 0.1 → 0.2](/resources/upgrade/upgrade-holochain-0.2/) 18 | -------------------------------------------------------------------------------- /src/pages/resources/upgrade/upgrade-new-holonix.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Upgrade to the new Holonix 3 | --- 4 | 5 | ::: intro 6 | In the third quarter of 2024, we released a new [Holonix](/get-started/install-advanced/#holonix-the-holochain-app-development-environment), our development environment based on [Nix](https://nixos.org) that gives you all the dependencies to build hApps. 7 | 8 | The new Holonix is simpler and more modular, which means that it's easier to configure it for your needs and preferences. 9 | ::: 10 | 11 | ## Upgrade an existing project 12 | 13 | The previous and the new Holonix distributions are both based on Nix's [flakes](https://wiki.nixos.org/wiki/Flakes) feature. Fortunately, this means it's easy to upgrade. First back up and remove your project's existing flake files: 14 | 15 | ```bash 16 | mv flake.nix flake.nix.backup 17 | mv flake.lock flake.lock.backup 18 | ``` 19 | 20 | Then create a new flake file: 21 | 22 | 23 | 24 | ```bash 25 | nix flake init -t github:holochain/holonix?ref=main-0.5 26 | ``` 27 | 28 | For most projects, that's all you need! If you have specific needs, such as targeting a specific Holochain version or release series, specifying build flags, or adding more Nix packages, read the [Holonix readme](https://github.com/holochain/holonix/tree/main/README.md). -------------------------------------------------------------------------------- /src/pages/search.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: Search - Holochain Docs 3 | layout: default-page-layout.njk 4 | pageStyleId: search 5 | --- 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/scss/_base-element-styles.scss: -------------------------------------------------------------------------------- 1 | img { 2 | width: unset; 3 | max-width: 100%; 4 | } 5 | 6 | p, ol, ul, dl, details, pre, blockquote, table, figure, figcaption, h4, h5, h6, .diff-container { 7 | margin: 1.5em 0; 8 | line-height: 1.5; 9 | } 10 | 11 | ul ol, ol ol, ol ul, ul ul { 12 | margin: 0; 13 | } 14 | 15 | h1, h2, h3 { 16 | margin: 1.2em 0; 17 | line-height: 1.2; 18 | } 19 | 20 | @mixin btn-base($color: currentColor, $bg-color: white, $hover-color: white, $hover-bg-color: $cl-brand-green) { 21 | padding: 8px 16px; 22 | border-radius: 5px; 23 | color: $color; 24 | background-color: $bg-color; 25 | text-decoration: none; 26 | 27 | &:hover { 28 | color: $hover-color; 29 | background-color: $hover-bg-color; 30 | } 31 | } 32 | 33 | // Applicable to an a or button element 34 | .btn { 35 | @include btn-base; 36 | } 37 | 38 | .btn-green-outline { 39 | @include btn-base; 40 | border: $cl-brand-green solid 1px; 41 | } 42 | 43 | .btn-purple { 44 | @include btn-base(white, $cl-brand-purple, $cl-brand-purple, $cl-gray); 45 | } 46 | 47 | a { 48 | color: $cl-main-text; 49 | 50 | svg { 51 | height: 100%; 52 | } 53 | 54 | &.header-anchor { 55 | text-decoration: none; 56 | color: inherit; 57 | 58 | &:hover, &:focus { 59 | text-decoration: underline; 60 | 61 | &::before { 62 | display: block; 63 | float: left; 64 | width: 0.75em; 65 | margin-left: -0.75em; 66 | content: '#'; 67 | } 68 | } 69 | } 70 | 71 | .main-area & { 72 | @include externalLinkIcon($cl-main-text); 73 | } 74 | } 75 | 76 | button { 77 | &.clear-btn { 78 | border: none; 79 | background: none; 80 | } 81 | } 82 | 83 | /* Utility Classes */ 84 | .left { 85 | text-align: left; 86 | } 87 | 88 | .center { 89 | text-align: center; 90 | } 91 | 92 | .right { 93 | text-align: right; 94 | } 95 | 96 | img { 97 | @for $p from 1 through 20 { 98 | &.sz#{$p}0p { 99 | max-width: $p * 10%; 100 | } 101 | } 102 | } 103 | 104 | table { 105 | width: 100%; 106 | border-collapse: collapse; 107 | } 108 | 109 | th { 110 | background: $cl-light-gray; 111 | color: white; 112 | border-right-color: rgba(white, 0.5); 113 | } 114 | 115 | th, td { 116 | text-align: left; 117 | vertical-align: top; 118 | border-right: 1px solid; 119 | padding: 0 0.5em; 120 | 121 | &:last-child { 122 | border-right: none; 123 | } 124 | } 125 | 126 | td { 127 | border-right-color: rgba(black, 0.5); 128 | } 129 | 130 | tr:nth-child(even) { 131 | background: rgba($cl-gray, 0.5); 132 | } -------------------------------------------------------------------------------- /src/scss/_debug.scss: -------------------------------------------------------------------------------- 1 | 2 | .h-tile-container, .home-tiles, 3 | // .h-tile, .tile-hero, 4 | .intro, 5 | .orientation, 6 | .h-tile-container-3, .tile-tabs, 7 | .tabcontent, .content_linux, .content_macos, .content_windows, 8 | .h-author { 9 | outline: black solid 1px; 10 | } 11 | 12 | .fas, .fa-thunderstorm, .fa-atom { 13 | color: red; 14 | } 15 | -------------------------------------------------------------------------------- /src/scss/_fonts.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "URW Form"; 3 | font-weight: 700; 4 | font-style: normal; 5 | src: url('/assets/webFonts/URWFormBold/font.woff2') format('woff2'), 6 | url('/assets/webFonts/URWFormBold/font.woff') format('woff'); 7 | } 8 | @font-face { 9 | font-family: "URW Form"; 10 | font-weight: 700; 11 | font-style: italic; 12 | src: url('/assets/webFonts/URWFormBoldItalic/font.woff2') format('woff2'), 13 | url('/assets/webFonts/URWFormBoldItalic/font.woff') format('woff'); 14 | } 15 | @font-face { 16 | font-family: "URW Form"; 17 | font-weight: 800; 18 | font-style: normal; 19 | src: url('/assets/webFonts/URWFormExtraBold/font.woff2') format('woff2'), 20 | url('/assets/webFonts/URWFormExtraBold/font.woff') format('woff'); 21 | } 22 | @font-face { 23 | font-family: "URW Form"; 24 | font-weight: 800; 25 | font-style: italic; 26 | src: url('/assets/webFonts/URWFormExtraBoldItalic/font.woff2') format('woff2'), 27 | url('/assets/webFonts/URWFormExtraBoldItalic/font.woff') format('woff'); 28 | } 29 | 30 | 31 | @import url('https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,400;0,700;1,400;1,700&display=swap'); 32 | 33 | // global font sizes vars 34 | $fs-extra-smaller: 13px; 35 | $fs-smaller: 14px; 36 | $fs-primary: 18px; 37 | $fs-bigger: 20px; 38 | $fs-even-bigger: 24px; 39 | 40 | // local font sizes 41 | $fs-footer-col-header: 14px; 42 | $fs-footer-smaller: $fs-smaller; 43 | 44 | html { 45 | font-size: 62.5%; 46 | 47 | body { 48 | font-family: Mulish; 49 | font-size: $fs-primary; 50 | } 51 | 52 | h1, h2, h3, h4 { 53 | font-family: 'URW Form'; 54 | font-weight: 800; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | $footer-nav-img-height: 14px; 2 | $footer-nav-header-to-links: 14px; 3 | 4 | #page-footer { 5 | grid-area: footer; 6 | padding: 50px $sz-mobile-hor-padding 40px; 7 | background: $cl-footer-bg; 8 | color: white; 9 | z-index: 1; 10 | 11 | nav { 12 | font-size: $fs-footer-smaller; 13 | 14 | ul { 15 | padding: 0; 16 | margin: 0; 17 | 18 | li { 19 | list-style: none; 20 | margin-bottom: unset; 21 | 22 | a { 23 | color: white; 24 | text-decoration: none; 25 | 26 | &.btn { 27 | //TODO: Create a standard reverse-btn 28 | @include btn-base(black); 29 | background-color: white; 30 | margin-top: 32px; 31 | border-color: black; 32 | 33 | &:hover { 34 | color: white; 35 | } 36 | } 37 | 38 | //@include externalLinkIcon; 39 | } 40 | } 41 | 42 | &.icon-list { 43 | display: flex; 44 | gap: $sp-icon-list-gap; 45 | 46 | li { 47 | 48 | a { 49 | height: $footer-nav-img-height; 50 | display: block; 51 | 52 | svg { 53 | height: $footer-nav-img-height; 54 | } 55 | } 56 | } 57 | } 58 | } 59 | 60 | #page-footer-columns { 61 | display: grid; 62 | grid-template-columns: repeat(1, max-content); 63 | justify-content: center; 64 | 65 | color: white; 66 | row-gap: 30px; 67 | margin: 0 auto; 68 | margin-bottom: 100px; 69 | 70 | .nav-column { 71 | h2 { 72 | color: $cl-other-green; 73 | font-size: $fs-footer-col-header; 74 | margin-bottom: $footer-nav-header-to-links; 75 | margin-top: 0; 76 | } 77 | 78 | &.newsletter { 79 | max-width: 200px; 80 | 81 | p { 82 | margin-bottom: 20px; 83 | } 84 | } 85 | } 86 | 87 | @media screen and (min-width: 500px) { 88 | grid-template-columns: repeat(6, 1fr); 89 | justify-items: center; 90 | 91 | .nav-column { 92 | &:nth-child(1) { grid-area: 1 / 1 / 2 / 3; } 93 | &:nth-child(2) { grid-area: 1 / 3 / 2 / 5; } 94 | &:nth-child(3) { grid-area: 1 / 5 / 2 / 7; } 95 | &:nth-child(4) { grid-area: 2 / 1 / 3 / 4; } 96 | &:nth-child(5) { grid-area: 2 / 4 / 3 / 7; } 97 | } 98 | } 99 | 100 | @include mq-full { 101 | display: flex; 102 | justify-content: space-between; 103 | gap: 20px; 104 | } 105 | } 106 | 107 | hr { 108 | margin: 0 auto; 109 | width: 100%; 110 | background-color: rgba($cl-gray, 0.5); 111 | color: transparent; 112 | } 113 | 114 | #page-footer-bottom { 115 | margin-top: 16px; 116 | 117 | > ul { 118 | display: grid; 119 | justify-items: center; 120 | grid-template-columns: 1fr repeat(3, max-content) 1fr; 121 | grid-template-areas: 122 | "... hc-logo hc-logo hc-logo ..." 123 | "... privacy sep tou ..." 124 | "... icons icons icons ..."; 125 | 126 | > li { 127 | a.hc-logo-link { 128 | img { 129 | height: 30px; 130 | } 131 | } 132 | 133 | &:nth-child(1) { grid-area: hc-logo; } 134 | &:nth-child(2) { grid-area: privacy; } 135 | &:nth-child(3) { grid-area: sep; } 136 | &:nth-child(4) { grid-area: tou; } 137 | &:nth-child(5) { grid-area: icons; } 138 | 139 | &:last-child { 140 | margin-top: 20px; 141 | } 142 | } 143 | } 144 | 145 | @include mq-full { 146 | > ul { 147 | display: flex; 148 | flex-wrap: wrap; 149 | gap: 10px; 150 | align-items: center; 151 | justify-content: center; 152 | 153 | > li { 154 | a.hc-logo-link { 155 | margin-right: 30px; 156 | } 157 | 158 | &:last-child { 159 | margin-top: 0; 160 | margin-left: auto; 161 | } 162 | } 163 | } 164 | } 165 | } 166 | } 167 | 168 | @include mq-full { 169 | padding: 50px $sz-full-hor-padding 40px; 170 | } 171 | } -------------------------------------------------------------------------------- /src/scss/_header.scss: -------------------------------------------------------------------------------- 1 | $top-nav-img-height: 24px; 2 | $cl-header-bar-primary: black; 3 | 4 | header#page-header { 5 | grid-area: header; 6 | 7 | #page-header-top { 8 | display: flex; 9 | justify-content: space-between; 10 | font-size: 18px; 11 | padding: 24px $sz-mobile-hor-padding 20px; 12 | 13 | a { 14 | text-decoration: none; 15 | } 16 | 17 | #logo-space { 18 | display: flex; 19 | flex-shrink: 0; 20 | 21 | #home-link { 22 | img { 23 | height: $top-nav-img-height; 24 | padding: 0 10px 0 2px; 25 | } 26 | } 27 | 28 | @include mq-full { 29 | flex-direction: column; 30 | } 31 | } 32 | 33 | #header-nav { 34 | display: flex; 35 | justify-content: center; 36 | align-items: center; 37 | 38 | ul { 39 | display: flex; 40 | // column-gap: 20px; 41 | justify-content: flex-end; 42 | list-style-type: none; 43 | margin-bottom: -17px; 44 | 45 | li { 46 | //min-width: 130px; 47 | flex-shrink: 0; 48 | 49 | a { 50 | margin-left: 24px; 51 | font-weight: 400; 52 | font-variation-settings: "wght" 400; 53 | padding-bottom: 6px; 54 | border-bottom: 2px solid transparent; 55 | transition: all .75s; 56 | } 57 | 58 | &[data-is-current-parent] { 59 | a { 60 | border-bottom-color: $cl-brand-purple; 61 | } 62 | } 63 | 64 | &:hover { 65 | a { 66 | border-bottom-color: $cl-brand-green; 67 | font-variation-settings: "wght" 700; 68 | } 69 | } 70 | } 71 | } 72 | 73 | @include mq-mobile { 74 | display: none; 75 | } 76 | } 77 | 78 | @include hamburgerMenu(); 79 | 80 | @include mq-full { 81 | padding: 24px $sz-full-hor-padding 20px; 82 | } 83 | } 84 | 85 | #page-header-bar { 86 | background: $header-gradiant; 87 | padding: 8px; 88 | color: $cl-header-bar-primary; 89 | display: flex; 90 | justify-content: space-between; 91 | 92 | #other-nav { 93 | margin-left: auto; 94 | //Sets to flex in mq-full 95 | display: none; 96 | align-items: center; 97 | gap: 10px; 98 | 99 | a { 100 | height: $top-nav-img-height; 101 | 102 | svg { 103 | height: $top-nav-img-height; 104 | width: $top-nav-img-height; 105 | } 106 | } 107 | } 108 | 109 | @include mq-full { 110 | background: none; 111 | padding: 10px $sz-full-hor-padding; 112 | 113 | #other-nav { 114 | display: flex; 115 | } 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /src/scss/_mermaid-diagrams.scss: -------------------------------------------------------------------------------- 1 | .mermaid-flowchart { 2 | font-size: 14px; 3 | fill: #333; 4 | margin-left: auto; 5 | margin-right: auto; 6 | 7 | .error-icon { 8 | fill: #552222; 9 | } 10 | 11 | .error-text { 12 | fill: #552222; 13 | stroke: #552222; 14 | } 15 | 16 | .edge-thickness-normal { 17 | stroke-width: 2px; 18 | } 19 | 20 | .edge-thickness-thick { 21 | stroke-width: 3.5px; 22 | } 23 | 24 | .edge-pattern-solid { 25 | stroke-dasharray: 0; 26 | } 27 | 28 | .edge-pattern-dashed { 29 | stroke-dasharray: 3; 30 | } 31 | 32 | .edge-pattern-dotted { 33 | stroke-dasharray: 2; 34 | } 35 | 36 | .marker { 37 | fill: #333333; 38 | stroke: #333333; 39 | } 40 | 41 | .marker.cross { 42 | stroke: #333333; 43 | } 44 | 45 | svg { 46 | font-size: 16px; 47 | } 48 | 49 | .label { 50 | color: #333; 51 | } 52 | 53 | .cluster-label text { 54 | fill: #333; 55 | } 56 | 57 | .cluster-label span, p { 58 | color: #333; 59 | } 60 | 61 | .label text, span, p { 62 | fill: #333; 63 | color: #333; 64 | } 65 | 66 | .node { 67 | rect, circle, ellipse, polygon, path { 68 | fill: #ececff; 69 | stroke: #9370db; 70 | stroke-width: 1px; 71 | } 72 | 73 | .katex path { 74 | fill: #000; 75 | stroke: #000; 76 | stroke-width: 1px; 77 | } 78 | 79 | .label { 80 | text-align: center; 81 | } 82 | 83 | &.clickable { 84 | cursor: pointer; 85 | } 86 | } 87 | 88 | .flowchart-label text { 89 | text-anchor: middle; 90 | } 91 | 92 | .arrowheadPath { 93 | fill: #333333; 94 | } 95 | 96 | .edgePath .path { 97 | stroke: #333333; 98 | stroke-width: 2px; 99 | } 100 | 101 | .flowchart-link { 102 | stroke: #333333; 103 | fill: none; 104 | } 105 | 106 | .edgeLabel { 107 | background-color: #e8e8e8; 108 | text-align: center; 109 | 110 | rect { 111 | opacity: 0.5; 112 | background-color: #e8e8e8; 113 | fill: #e8e8e8; 114 | } 115 | } 116 | 117 | .labelBkg { 118 | background-color: rgba(232, 232, 232, 0.85); 119 | } 120 | 121 | .cluster { 122 | rect { 123 | fill: #ffffde; 124 | stroke: #aaaa33; 125 | stroke-width: 1px; 126 | } 127 | 128 | text { 129 | fill: #333; 130 | } 131 | } 132 | 133 | .cluster span, p { 134 | color: #333; 135 | } 136 | 137 | div.mermaidTooltip { 138 | position: absolute; 139 | text-align: center; 140 | max-width: 200px; 141 | padding: 2px; 142 | font-size: 12px; 143 | background: hsl(80, 100%, 96.2745098039%); 144 | border: 1px solid #aaaa33; 145 | border-radius: 2px; 146 | pointer-events: none; 147 | z-index: 100; 148 | } 149 | 150 | .flowchartTitleText { 151 | text-anchor: middle; 152 | font-size: 18px; 153 | fill: #333; 154 | } 155 | 156 | .nodeLabel * { 157 | margin: 0; 158 | } 159 | 160 | /* External references, used on the working with data page and others */ 161 | .external > * { 162 | stroke-dasharray: 3 3 !important; 163 | fill: transparent !important; 164 | 165 | span { 166 | stroke-dasharray: 3 3 !important; 167 | fill: transparent !important; 168 | } 169 | } 170 | 171 | /* Original actions, for diagrams showing the relationships of CRUD actions */ 172 | .original > * { 173 | fill: #F2F2F2 !important; 174 | stroke: #AAA !important; 175 | 176 | span { 177 | fill: #F2F2F2 !important; 178 | stroke: #AAA !important; 179 | } 180 | } 181 | } -------------------------------------------------------------------------------- /src/scss/_navigation.scss: -------------------------------------------------------------------------------- 1 | @mixin navBarList() { 2 | $current-page-highlight-padding: 10px; 3 | 4 | nav#main-nav { 5 | padding: 18px 34px; 6 | 7 | ul { 8 | list-style: none; 9 | margin: 0; 10 | padding: 0; 11 | 12 | // Default for all links in tree 13 | $link-color: #5B5477; 14 | 15 | 16 | #mobile-search { 17 | svg { 18 | height: 24px; 19 | } 20 | 21 | @include mq-full { 22 | display: none; 23 | } 24 | } 25 | 26 | a { 27 | color: $link-color; 28 | display: inline-block; 29 | transition: all .75s; 30 | text-decoration: none; 31 | 32 | @include externalLinkIcon($link-color); 33 | 34 | &:hover { 35 | font-variation-settings: "wght" 700; 36 | color: black; 37 | } 38 | } 39 | 40 | // Add a span so that we can use the border to indicate current page and 41 | // control the size of the indicator independent of the box size of the a tag 42 | .nav-label span { 43 | display: inline-flex; 44 | align-items: flex-end; 45 | padding-left: $current-page-highlight-padding; 46 | border-left: 4px solid transparent; 47 | 48 | svg { 49 | margin: 0 0 6px 6px; 50 | } 51 | } 52 | 53 | li { 54 | margin-bottom: unset; 55 | 56 | &[data-is-current-parent="true"] { 57 | > a { 58 | color: black; 59 | font-weight: 700; 60 | } 61 | } 62 | 63 | &[aria-current="page"] { 64 | > a { 65 | color: black; 66 | font-weight: 700; 67 | 68 | span { 69 | border-left-color: $cl-brand-green; 70 | } 71 | } 72 | } 73 | } 74 | 75 | &.nav-top-level { 76 | > li { 77 | > a { 78 | padding: 8px 0; 79 | text-transform: uppercase; 80 | } 81 | 82 | button { 83 | cursor: pointer; 84 | 85 | svg { 86 | transition: all 0.25s; 87 | } 88 | 89 | &.up-arrow { 90 | svg { 91 | transform: rotateZ(180deg); 92 | } 93 | } 94 | } 95 | } 96 | 97 | ul.nav-child-level { 98 | display: none; 99 | 100 | /* Because we want the whole row in which the nav link sits to be 101 | clickable, we can't rely on just adding a blanket margin to 102 | .nav-child-level. Instead, we add increasing padding to nested 103 | block-display wrappers, which means we have to do it manually for each 104 | nesting level. This imposes a limit on how many nesting levels to 105 | support, because we don't want to repeat the below code infinitely. */ 106 | .nav-label { 107 | padding: 3px 0 4px 12px; 108 | } 109 | 110 | div.nav-label { 111 | font-style: italic; 112 | } 113 | 114 | ul.nav-child-level { 115 | .nav-label { 116 | padding-left: 24px; 117 | } 118 | 119 | ul.nav-child-level { 120 | .nav-label { 121 | padding-left: 36px; 122 | } 123 | 124 | ul.nav-child-level { 125 | .nav-label { 126 | padding-left: 48px; 127 | } 128 | 129 | /* I think that's enough levels of nesting, don't you? */ 130 | ul.nav-child-level { 131 | .nav-label { 132 | padding-left: 60px; 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | &.open { 140 | display: block; 141 | } 142 | } 143 | } 144 | } 145 | } 146 | } 147 | 148 | @mixin inPageToc() { 149 | #in-page-toc { 150 | position: sticky; 151 | top: 0; 152 | 153 | padding: 18px 34px; 154 | 155 | h2 { 156 | margin: 0; 157 | font-size: 18px; 158 | font-weight: 500; 159 | } 160 | 161 | ul { 162 | list-style: none; 163 | margin-top: 10px; 164 | padding: 0; 165 | 166 | li { 167 | margin-bottom: 10px; 168 | 169 | a { 170 | color: #5B5477; 171 | display: inline-block; 172 | transition: all .75s; 173 | text-decoration: none; 174 | 175 | &:hover { 176 | font-variation-settings: "wght" 700; 177 | color: black; 178 | } 179 | 180 | &.current { 181 | font-weight: 700; 182 | } 183 | } 184 | 185 | & > ul { 186 | margin-top: 10px; 187 | padding-left: 20px; 188 | } 189 | } 190 | } 191 | } 192 | } -------------------------------------------------------------------------------- /src/scss/_values.scss: -------------------------------------------------------------------------------- 1 | /* Colors */ 2 | $cl-brand-purple: #8719F6; 3 | $cl-brand-green: #0EDDD3; 4 | $cl-other-green: #74FAD2; 5 | $cl-lightest-gray: #f7f7f7; 6 | $cl-gray: #d0d0d7; 7 | $cl-light-gray: #575656; 8 | 9 | /* Usage colors */ 10 | $cl-main-text: black; 11 | $cl-footer-bg: black; 12 | 13 | // Font sizes defined in _fonts 14 | 15 | // Spacing 16 | $sp-icon-list-gap: 16px; 17 | 18 | /* Breakpoints & Widths */ 19 | $default-max-content-width: 1200px; 20 | $mobile-width: 900px; 21 | // Tablet width? Do we care? 22 | 23 | // $sz-full-hor-padding: 70px; 24 | $sz-full-hor-padding: 0px; 25 | $sz-mobile-hor-padding: 30px; 26 | 27 | /* Explicit heights */ 28 | $footer-large-screen-height: 200px; 29 | 30 | 31 | /* Gradients */ 32 | $header-gradiant: linear-gradient(90deg,#4720e3,#345ede 32.81%,#0dddd3); 33 | $blue-to-light-purple-grad: linear-gradient(180deg,#4720e3,#b748ff 68.44%); 34 | $blue-to-light-blue-grad: linear-gradient(180deg,#415bed,#13d0d7 44.86%); 35 | 36 | 37 | @mixin mq-full { 38 | @media screen and (min-width: $mobile-width) { 39 | @content; 40 | } 41 | } 42 | 43 | /* Still a full computer but a smallish one */ 44 | @mixin mq-smallish { 45 | @media screen and (max-width: $default-max-content-width) { 46 | @content; 47 | } 48 | } 49 | 50 | @mixin mq-mobile { 51 | @media screen and (max-width: $mobile-width) { 52 | @content; 53 | } 54 | } -------------------------------------------------------------------------------- /src/scss/page-specific/_default-page-type.scss: -------------------------------------------------------------------------------- 1 | $cl-sidebar-bg: $cl-lightest-gray; 2 | 3 | &.default-page-type { 4 | background-color: white; 5 | display: grid; 6 | 7 | //Mobile set up default 8 | grid-template-columns: minmax(0, 1fr); 9 | grid-template-rows: [header-start] min-content 10 | [header-cl-bar-start] 44px 11 | [header-cl-bar-end main-r1-start] min-content 12 | [main-r2-start] 1fr 13 | [main-end footer-start] min-content [footer-end]; 14 | grid-template-areas: 15 | "header" 16 | "header" 17 | "mainArea" 18 | "footer"; 19 | 20 | .main-area { 21 | grid-area: mainArea; 22 | background-color: white; 23 | padding: 0 $sz-mobile-hor-padding 20px; 24 | } 25 | 26 | .side-bar { 27 | grid-area: mainArea; 28 | z-index: -1; 29 | background-color: $cl-sidebar-bg; 30 | margin-bottom: 0; 31 | margin-top: 0; 32 | height: 100%; 33 | 34 | @include navBarList; 35 | @include inPageToc; 36 | 37 | &.show { 38 | z-index: 10; 39 | } 40 | } 41 | 42 | .header-full-bg { 43 | display: none; 44 | background: $header-gradiant; 45 | grid-area: header-cl-bar-start / vp-left / header-cl-bar-end / vp-right; 46 | z-index: -1; 47 | } 48 | 49 | .footer-full-bg { 50 | display: none; 51 | background-color: black; 52 | grid-area: footer-start / vp-left / footer-end / vp-right; 53 | } 54 | 55 | .sidebar-right-bg { 56 | display: none; 57 | background-color: $cl-sidebar-bg; 58 | grid-area: main-r1-start / sidebar-begin / main-end / vp-right; 59 | z-index: -1; 60 | } 61 | 62 | @include mq-full { 63 | grid-template-columns: [vp-left] minmax(50px, 1fr) minmax(0, 50em) [sidebar-begin] 20em [sidebar-end] minmax(50px, 1fr) [vp-right]; 64 | grid-template-areas: 65 | "... header header ..." 66 | "... header header ..." 67 | "... mainArea sideBar ..." 68 | "... footer footer ..."; 69 | //column-gap: 50px; 70 | 71 | .main-area { 72 | background-color: transparent; 73 | padding: 0 50px 30px $sz-full-hor-padding; 74 | } 75 | 76 | .side-bar { 77 | grid-area: sideBar; 78 | z-index: unset; 79 | } 80 | 81 | .header-full-bg, .footer-full-bg, .sidebar-right-bg { 82 | display: block; 83 | } 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /src/scss/page-specific/_ds-layout-type.scss: -------------------------------------------------------------------------------- 1 | &.ds-layout-type { 2 | 3 | .main-area { 4 | margin: 40px; 5 | 6 | .code-blocks { 7 | max-width: 500px; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /src/scss/page-specific/_home.scss: -------------------------------------------------------------------------------- 1 | 2 | &.home-page { 3 | position: relative; 4 | grid-template-areas: 5 | "... header header ..." 6 | "... header header ..." 7 | "greeting greeting greeting greeting" 8 | "... mainArea mainArea ..." 9 | "... footer footer ..."; 10 | 11 | #page-bg { 12 | display: none; 13 | position: absolute; 14 | right: 0; 15 | top: 930px; 16 | 17 | @include mq-full { 18 | display: block; 19 | } 20 | } 21 | 22 | hr { 23 | width: 90%; 24 | } 25 | 26 | #greeting { 27 | grid-area: greeting; 28 | // Will be set to flex by mq-full 29 | display: none; 30 | flex-direction: column; 31 | align-items: center; 32 | position: relative; 33 | color: white; 34 | padding: 19px 0 60px; 35 | 36 | &-bg { 37 | background-color: black; 38 | position: absolute; 39 | top: 0; bottom: 0; right: 0; left: 0; 40 | z-index: -1; 41 | overflow: hidden; 42 | } 43 | 44 | h1 { 45 | font-size: 32px; 46 | margin-bottom: 16px; 47 | } 48 | 49 | p { 50 | margin: 0; 51 | } 52 | 53 | .btn { 54 | //TODO: Create a standard reverse-btn 55 | @include btn-base(black); 56 | margin-top: 32px; 57 | } 58 | } 59 | 60 | @media screen and (min-width: 500px) { 61 | .main-area { 62 | padding: 0 70px; 63 | } 64 | } 65 | 66 | #home-tiles { 67 | display: grid; 68 | gap: 30px; 69 | padding: 30px 0; 70 | color: black; 71 | 72 | .home-tile { 73 | text-decoration: none; 74 | background-color: white; 75 | 76 | .content-wrapper { 77 | padding-left: 40px; 78 | display: flex; 79 | align-items: center; 80 | 81 | .text-wrapper { 82 | display: flex; 83 | flex-direction: column; 84 | align-items: flex-start; 85 | justify-content: flex-start; 86 | margin-left: 24px; 87 | 88 | h2 { 89 | border-bottom: 2px solid $cl-brand-purple; 90 | margin: 0; 91 | font-size: 28px; 92 | } 93 | } 94 | } 95 | } 96 | 97 | @include mq-full { 98 | gap: 70px; 99 | grid-template-columns: 1fr 1fr; 100 | padding: 60px 50px; 101 | } 102 | } 103 | 104 | #qualities { 105 | display: grid; 106 | grid-template-columns: 1fr; 107 | gap: 60px; 108 | padding: 0 $sz-mobile-hor-padding; 109 | 110 | @include mq-full { 111 | grid-template-columns: 1fr 1fr 1fr; 112 | padding: 0 $sz-full-hor-padding; 113 | margin: 80px 200px 80px 0; 114 | } 115 | } 116 | 117 | hr { 118 | background-color: #CECCD8; 119 | border: 0; 120 | height: 1px; 121 | 122 | &#last { 123 | margin-bottom: 200px; 124 | } 125 | } 126 | 127 | @include mq-full { 128 | #greeting { 129 | display: flex; 130 | } 131 | 132 | .side-bar, .sidebar-right-bg { 133 | display: none; 134 | } 135 | } 136 | } -------------------------------------------------------------------------------- /src/scss/page-specific/_install.scss: -------------------------------------------------------------------------------- 1 | 2 | &.install { 3 | #tiles { 4 | display: grid; 5 | gap: 20px; 6 | 7 | .tile { 8 | position: relative; 9 | padding: 20px; 10 | border: 1px solid #e7e7e7; 11 | box-shadow: 1px 2px 5px 0 rgba(0,0,0,.05); 12 | 13 | img.os-img { 14 | height: 21px; 15 | } 16 | 17 | &::after { 18 | content: ''; 19 | width: 100%; 20 | height: 0; 21 | opacity: 0; 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | background: #00ffce; 26 | transition: all 0.25s; 27 | } 28 | 29 | &.active, &:hover { 30 | &:not(.disabled) { 31 | &::after { 32 | height: 5px; 33 | opacity: 1; 34 | } 35 | } 36 | } 37 | } 38 | 39 | @media (min-width: $mobile-width) { 40 | grid-template-columns: 1fr 1fr 1fr; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/scss/page-specific/_search.scss: -------------------------------------------------------------------------------- 1 | &.search { 2 | .main-area { 3 | min-height: 500px; 4 | } 5 | } -------------------------------------------------------------------------------- /src/scss/site.scss: -------------------------------------------------------------------------------- 1 | @import 'values'; 2 | @import 'fonts'; 3 | @import 'svg-icons'; 4 | @import 'base-element-styles'; 5 | @import 'mermaid-diagrams'; 6 | 7 | // @import 'debug'; 8 | 9 | * { 10 | box-sizing: border-box; 11 | } 12 | 13 | html, body { 14 | margin: 0; 15 | padding: 0; 16 | height: 100%; 17 | scroll-behavior: smooth; 18 | } 19 | 20 | body { 21 | display: flex; 22 | flex-direction: column; 23 | 24 | @import 'widgets'; 25 | @import 'header'; 26 | @import 'navigation'; 27 | 28 | 29 | // two section content, right side bar, main chunk on left. 30 | @import 'page-specific/default-page-type'; 31 | @import 'page-specific/ds-layout-type'; 32 | 33 | // } 34 | 35 | @import 'footer'; 36 | 37 | @import 'page-specific/home'; 38 | @import 'page-specific/search'; 39 | @import 'page-specific/install'; 40 | } 41 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "sourceMap": true, 8 | "outDir": "client-side-compiled", 9 | "skipLibCheck": true, 10 | "lib": ["es6", "dom", "es2016"] 11 | }, 12 | "include": [ 13 | "src/client-side/**/*.ts" 14 | ], 15 | "exclude": [ 16 | "**/node_modules" 17 | ] 18 | } --------------------------------------------------------------------------------