Urbit
  • Introduction
  • Development

    • Getting Started
    • Environment Setup
    • Grants Program
    • Project Repositories
    • Precepts
    • System Overview

      • Arvo
      • Hoon
      • Nock
      • Vere
      • Azimuth
      • Cryptography
      • Arvo

        • Overview
        • Ames

          • Overview
          • Cryptography
          • API Reference
          • Scry Reference
          • Data Types
          • Behn

            • Overview
            • API Reference
            • Scry Reference
            • Examples
            • Clay

              • Overview
              • Architecture
              • Using Clay
              • Data Types
              • Scry Reference
              • API Reference
              • Examples
              • Marks

                • Overview
                • Writing Marks
                • Using Marks
                • Examples
              • Dill

                • Overview
                • API Reference
                • Scry Reference
                • Data Types
                • Eyre

                  • Overview
                  • External API Reference
                  • Internal API Reference
                  • Scry Reference
                  • Data Types
                  • Guide
                  • Ford

                    • Overview
                    • Gall

                      • Overview
                      • API Reference
                      • Data Types
                      • Iris

                        • Overview
                        • API Reference
                        • Data Types
                        • Example
                        • Jael

                          • Overview
                          • API Reference
                          • Scry Reference
                          • Data Types
                          • Examples
                          • Concepts

                            • Scries
                            • Subscriptions
                            • Tutorials

                              • Move Trace
                              • Reference

                                • Cryptography
                                • Filesystem Hierarchy
                              • Userspace

                                • Overview
                                • HTTP API Guide
                                • Gall Guide

                                  • Introduction
                                  • 1. Arvo
                                  • 2. The Agent Core
                                  • 3. Imports and Aliases
                                  • 4. Lifecycle
                                  • 5. Cards
                                  • 6. Pokes
                                  • 7. Structures and Marks
                                  • 8. Subscriptions
                                  • 9. Vanes
                                  • 10. Scries
                                  • 11. Failure
                                  • 12. Next Steps
                                  • Appendix: Types
                                  • Full-Stack Walkthrough

                                    • 1. Introduction
                                    • 2. Types
                                    • 3. Agent
                                    • 4. JSON
                                    • 5. Marks
                                    • 6. Eyre
                                    • 7. React app setup
                                    • 8. React app logic
                                    • 9. Desk and glob
                                    • 10. Summary
                                    • Graph Store

                                      • Graph Store Overview
                                      • Data Structure Overview
                                      • Validator Walkthrough
                                      • Sample Application: Library
                                      • Graph Store - Reference
                                      • Advanced Info
                                      • Threads

                                        • Overview
                                        • HTTP API
                                        • Reference
                                        • Basics

                                          • Fundamentals
                                          • Bind
                                          • Input
                                          • Output
                                          • Summary
                                          • Gall

                                            • Start Thread
                                            • Take Result
                                            • Take Facts
                                            • Stop Thread
                                            • Poke Thread
                                            • Examples

                                              • Fetch JSON
                                              • Child Thread
                                              • Main-loop
                                              • Poke Agent
                                              • Scry
                                              • Take Fact
                                            • Distribution

                                              • Overview
                                              • Guide
                                              • Docket File
                                              • Glob
                                              • Dojo Tools
                                            • Hoon

                                              • Overview
                                              • Hoon School

                                                • 1.1 Introduction
                                                • 1.1.1 Walkthrough: List of Numbers
                                                • 1.2 Nouns
                                                • 1.3 Hoon Syntax
                                                • 1.3.1 Walkthrough: Conditionals
                                                • 1.4 Gates (Hoon Functions)
                                                • 1.4.1 Walkthrough: Recursion
                                                • 1.5 Lists
                                                • 1.5.1 Walkthrough: Fibonacci Sequence
                                                • 1.6 The Subject and Its Legs
                                                • 1.6.1 Walkthrough: Ackermann Function
                                                • 1.7 Arms and Cores
                                                • 1.7.1 Walkthrough: Caesar Cipher
                                                • 1.8 Doors
                                                • 1.8.1 Bank Account
                                                • 1.9 Generators
                                                • 2.1 Atoms, Auras, and Simple Cell Types
                                                • 2.2 Type Checking and Type Inference
                                                • 2.3 Structures and Complex Types
                                                • 2.3.1 Walkthrough: Libraries
                                                • 2.3.2 Molds
                                                • 2.4 Standard Library: Trees, Sets, and Maps
                                                • 2.5 Type Polymorphism
                                                • 2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism
                                                • 2.5.2 Walkthrough: Lead Polymorphism
                                                • 2.6 Behn
                                                • 2.7 Gall
                                                • 2.7.1 Gall Walkthrough: Egg Timer
                                                • Guides

                                                  • CLI apps
                                                  • Parsing
                                                  • JSON
                                                  • Strings
                                                  • Sail (HTML)
                                                  • Writing Aqua Tests
                                                  • Reference

                                                    • Cheat Sheet
                                                    • Irregular forms
                                                    • Hoon Errors
                                                    • Hoon Style Guide
                                                    • Basic Types
                                                    • Advanced Types
                                                    • Auras
                                                    • Runes

                                                      • Atoms and strings
                                                      • Nock . ('dot')
                                                      • Wild ! ('zap')
                                                      • Change Subject = ('tis')
                                                      • Conditionals ? ('wut')
                                                      • Cores | ('bar')
                                                      • Arms + ('lus')
                                                      • Cells : ('col')
                                                      • Calls % ('cen')
                                                      • Casts ^ ('ket')
                                                      • Structures $ ('buc')
                                                      • Make ; ('mic')
                                                      • Hints ~ ('sig')
                                                      • Imports / ('fas')
                                                      • Terminators -- and ==
                                                      • Limbs and wings

                                                        • Limbs
                                                        • Wings
                                                        • Standard library

                                                          • Table of Contents
                                                          • 1a: Basic Arithmetic
                                                          • 1b: Tree Addressing
                                                          • 1c: Molds and Mold-Builders
                                                          • 2a: Unit Logic
                                                          • 2b: List Logic
                                                          • 2c: Bit Arithmetic
                                                          • 2d: Bit Logic
                                                          • 2e: Insecure Hashing
                                                          • 2f: Noun Ordering
                                                          • 2g: Unsigned Powers
                                                          • 2h: Set Logic
                                                          • 2i: Map Logic
                                                          • 2j: Jar and Jug Logic
                                                          • 2k: Queue Logic
                                                          • 2l: Container from Container
                                                          • 2m: Container from Noun
                                                          • 2n: Functional Hacks
                                                          • 2o: Normalizing Containers
                                                          • 2p: Serialization
                                                          • 2q: Molds and Mold-Builders
                                                          • 3a: Modular and Signed Ints
                                                          • 3b: Floating Point
                                                          • 3c: Urbit Time
                                                          • 3d: SHA Hash Family
                                                          • 3e: AES encryption (Removed)
                                                          • 3f: Scrambling
                                                          • 3g: Molds and Mold-Builders
                                                          • 4a: Exotic Bases
                                                          • 4b: Text Processing
                                                          • 4c: Tank Printer
                                                          • 4d: Parsing (Tracing)
                                                          • 4e: Parsing (Combinators)
                                                          • 4f: Parsing (Rule-Builders)
                                                          • 4g: Parsing (Outside Caller)
                                                          • 4h: Parsing (ASCII Glyphs)
                                                          • 4i: Parsing (Useful Idioms)
                                                          • 4j: Parsing (Bases and Base Digits)
                                                          • 4k: Atom Printing
                                                          • 4l: Atom Parsing
                                                          • 4m: Formatting Functions
                                                          • 4n: Virtualization
                                                          • 4o: Molds
                                                          • 5a: Compiler Utilities
                                                          • 5b: Macro Expansion
                                                          • 5c: Compiler Backend & Prettyprinter
                                                          • 5d: Parser
                                                          • 5e: Molds and mold builders
                                                          • 5f: Profiling support
                                                          • Zuse

                                                            • Table of Contents
                                                            • 2d(1-5): To JSON, Wains
                                                            • 2d(6): From JSON
                                                            • 2d(7): From JSON (unit)
                                                            • 2e(2-3): Print & Parse JSON
                                                        • Nock

                                                          • Nock Definition
                                                          • Explanation
                                                          • Example
                                                          • Implementations
                                                          • Vere

                                                            • C Runtime System
                                                            • Land of Nouns
                                                            • API overview by prefix
                                                            • C in Urbit
                                                            • Writing Jets
                                                            • Cryptography
                                                            • Azimuth

                                                              • Overview
                                                              • Urbit HD Wallet
                                                              • Azimuth Data Flow
                                                              • Azimuth.eth
                                                              • Ecliptic.eth
                                                              • Advanced Azimuth Tools
                                                              • Life and Rift
                                                              • Layer 2

                                                                • Layer 2 Overview
                                                                • Layer 2 Actions
                                                                • Transaction Format
                                                                • Rollers
                                                                • Roller HTTP RPC-API
                                                                • Custom Roller Tutorial
                                                              • Glossary

                                                                • Ames
                                                                • Aqua
                                                                • Arm
                                                                • Arvo
                                                                • Atom
                                                                • Azimuth
                                                                • Battery
                                                                • Behn
                                                                • Bridge
                                                                • Censures
                                                                • Ceremony
                                                                • chat
                                                                • Claims
                                                                • Clay
                                                                • Comet
                                                                • Core
                                                                • Delegated Sending
                                                                • Desk
                                                                • Dill
                                                                • Document Proposal
                                                                • Dojo
                                                                • Door
                                                                • Ecliptic
                                                                • Event Log
                                                                • Eyre
                                                                • Ford
                                                                • Galaxy
                                                                • Gall
                                                                • Gate
                                                                • HD Wallet
                                                                • Hoon
                                                                • Invite Tree
                                                                • Iris
                                                                • Jael
                                                                • Jaque
                                                                • Keyfile
                                                                • Landscape
                                                                • Mark
                                                                • Moon
                                                                • Nock
                                                                • Noun
                                                                • OTA Updates
                                                                • Payload
                                                                • pH
                                                                • Pier
                                                                • Pill
                                                                • Planet
                                                                • Proxies
                                                                • Replay
                                                                • Factory Reset
                                                                • Naive rollups
                                                                • Sail/Udon
                                                                • Senate
                                                                • Ship
                                                                • ship.arvo.network
                                                                • Star
                                                                • |sync
                                                                • Trap
                                                                • Upgrade Proposal
                                                                • Vane
                                                                • Vere
                                                                • Voting
                                                                • Wallet-Generator
                                                                Urbit
                                                                • Introduction
                                                                • Development

                                                                  • Getting Started
                                                                  • Environment Setup
                                                                  • Grants Program
                                                                  • Project Repositories
                                                                  • Precepts
                                                                  • System Overview

                                                                    • Arvo
                                                                    • Hoon
                                                                    • Nock
                                                                    • Vere
                                                                    • Azimuth
                                                                    • Cryptography
                                                                    • Arvo

                                                                      • Overview
                                                                      • Ames

                                                                        • Overview
                                                                        • Cryptography
                                                                        • API Reference
                                                                        • Scry Reference
                                                                        • Data Types
                                                                        • Behn

                                                                          • Overview
                                                                          • API Reference
                                                                          • Scry Reference
                                                                          • Examples
                                                                          • Clay

                                                                            • Overview
                                                                            • Architecture
                                                                            • Using Clay
                                                                            • Data Types
                                                                            • Scry Reference
                                                                            • API Reference
                                                                            • Examples
                                                                            • Marks

                                                                              • Overview
                                                                              • Writing Marks
                                                                              • Using Marks
                                                                              • Examples
                                                                            • Dill

                                                                              • Overview
                                                                              • API Reference
                                                                              • Scry Reference
                                                                              • Data Types
                                                                              • Eyre

                                                                                • Overview
                                                                                • External API Reference
                                                                                • Internal API Reference
                                                                                • Scry Reference
                                                                                • Data Types
                                                                                • Guide
                                                                                • Ford

                                                                                  • Overview
                                                                                  • Gall

                                                                                    • Overview
                                                                                    • API Reference
                                                                                    • Data Types
                                                                                    • Iris

                                                                                      • Overview
                                                                                      • API Reference
                                                                                      • Data Types
                                                                                      • Example
                                                                                      • Jael

                                                                                        • Overview
                                                                                        • API Reference
                                                                                        • Scry Reference
                                                                                        • Data Types
                                                                                        • Examples
                                                                                        • Concepts

                                                                                          • Scries
                                                                                          • Subscriptions
                                                                                          • Tutorials

                                                                                            • Move Trace
                                                                                            • Reference

                                                                                              • Cryptography
                                                                                              • Filesystem Hierarchy
                                                                                            • Userspace

                                                                                              • Overview
                                                                                              • HTTP API Guide
                                                                                              • Gall Guide

                                                                                                • Introduction
                                                                                                • 1. Arvo
                                                                                                • 2. The Agent Core
                                                                                                • 3. Imports and Aliases
                                                                                                • 4. Lifecycle
                                                                                                • 5. Cards
                                                                                                • 6. Pokes
                                                                                                • 7. Structures and Marks
                                                                                                • 8. Subscriptions
                                                                                                • 9. Vanes
                                                                                                • 10. Scries
                                                                                                • 11. Failure
                                                                                                • 12. Next Steps
                                                                                                • Appendix: Types
                                                                                                • Full-Stack Walkthrough

                                                                                                  • 1. Introduction
                                                                                                  • 2. Types
                                                                                                  • 3. Agent
                                                                                                  • 4. JSON
                                                                                                  • 5. Marks
                                                                                                  • 6. Eyre
                                                                                                  • 7. React app setup
                                                                                                  • 8. React app logic
                                                                                                  • 9. Desk and glob
                                                                                                  • 10. Summary
                                                                                                  • Graph Store

                                                                                                    • Graph Store Overview
                                                                                                    • Data Structure Overview
                                                                                                    • Validator Walkthrough
                                                                                                    • Sample Application: Library
                                                                                                    • Graph Store - Reference
                                                                                                    • Advanced Info
                                                                                                    • Threads

                                                                                                      • Overview
                                                                                                      • HTTP API
                                                                                                      • Reference
                                                                                                      • Basics

                                                                                                        • Fundamentals
                                                                                                        • Bind
                                                                                                        • Input
                                                                                                        • Output
                                                                                                        • Summary
                                                                                                        • Gall

                                                                                                          • Start Thread
                                                                                                          • Take Result
                                                                                                          • Take Facts
                                                                                                          • Stop Thread
                                                                                                          • Poke Thread
                                                                                                          • Examples

                                                                                                            • Fetch JSON
                                                                                                            • Child Thread
                                                                                                            • Main-loop
                                                                                                            • Poke Agent
                                                                                                            • Scry
                                                                                                            • Take Fact
                                                                                                          • Distribution

                                                                                                            • Overview
                                                                                                            • Guide
                                                                                                            • Docket File
                                                                                                            • Glob
                                                                                                            • Dojo Tools
                                                                                                          • Hoon

                                                                                                            • Overview
                                                                                                            • Hoon School

                                                                                                              • 1.1 Introduction
                                                                                                              • 1.1.1 Walkthrough: List of Numbers
                                                                                                              • 1.2 Nouns
                                                                                                              • 1.3 Hoon Syntax
                                                                                                              • 1.3.1 Walkthrough: Conditionals
                                                                                                              • 1.4 Gates (Hoon Functions)
                                                                                                              • 1.4.1 Walkthrough: Recursion
                                                                                                              • 1.5 Lists
                                                                                                              • 1.5.1 Walkthrough: Fibonacci Sequence
                                                                                                              • 1.6 The Subject and Its Legs
                                                                                                              • 1.6.1 Walkthrough: Ackermann Function
                                                                                                              • 1.7 Arms and Cores
                                                                                                              • 1.7.1 Walkthrough: Caesar Cipher
                                                                                                              • 1.8 Doors
                                                                                                              • 1.8.1 Bank Account
                                                                                                              • 1.9 Generators
                                                                                                              • 2.1 Atoms, Auras, and Simple Cell Types
                                                                                                              • 2.2 Type Checking and Type Inference
                                                                                                              • 2.3 Structures and Complex Types
                                                                                                              • 2.3.1 Walkthrough: Libraries
                                                                                                              • 2.3.2 Molds
                                                                                                              • 2.4 Standard Library: Trees, Sets, and Maps
                                                                                                              • 2.5 Type Polymorphism
                                                                                                              • 2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism
                                                                                                              • 2.5.2 Walkthrough: Lead Polymorphism
                                                                                                              • 2.6 Behn
                                                                                                              • 2.7 Gall
                                                                                                              • 2.7.1 Gall Walkthrough: Egg Timer
                                                                                                              • Guides

                                                                                                                • CLI apps
                                                                                                                • Parsing
                                                                                                                • JSON
                                                                                                                • Strings
                                                                                                                • Sail (HTML)
                                                                                                                • Writing Aqua Tests
                                                                                                                • Reference

                                                                                                                  • Cheat Sheet
                                                                                                                  • Irregular forms
                                                                                                                  • Hoon Errors
                                                                                                                  • Hoon Style Guide
                                                                                                                  • Basic Types
                                                                                                                  • Advanced Types
                                                                                                                  • Auras
                                                                                                                  • Runes

                                                                                                                    • Atoms and strings
                                                                                                                    • Nock . ('dot')
                                                                                                                    • Wild ! ('zap')
                                                                                                                    • Change Subject = ('tis')
                                                                                                                    • Conditionals ? ('wut')
                                                                                                                    • Cores | ('bar')
                                                                                                                    • Arms + ('lus')
                                                                                                                    • Cells : ('col')
                                                                                                                    • Calls % ('cen')
                                                                                                                    • Casts ^ ('ket')
                                                                                                                    • Structures $ ('buc')
                                                                                                                    • Make ; ('mic')
                                                                                                                    • Hints ~ ('sig')
                                                                                                                    • Imports / ('fas')
                                                                                                                    • Terminators -- and ==
                                                                                                                    • Limbs and wings

                                                                                                                      • Limbs
                                                                                                                      • Wings
                                                                                                                      • Standard library

                                                                                                                        • Table of Contents
                                                                                                                        • 1a: Basic Arithmetic
                                                                                                                        • 1b: Tree Addressing
                                                                                                                        • 1c: Molds and Mold-Builders
                                                                                                                        • 2a: Unit Logic
                                                                                                                        • 2b: List Logic
                                                                                                                        • 2c: Bit Arithmetic
                                                                                                                        • 2d: Bit Logic
                                                                                                                        • 2e: Insecure Hashing
                                                                                                                        • 2f: Noun Ordering
                                                                                                                        • 2g: Unsigned Powers
                                                                                                                        • 2h: Set Logic
                                                                                                                        • 2i: Map Logic
                                                                                                                        • 2j: Jar and Jug Logic
                                                                                                                        • 2k: Queue Logic
                                                                                                                        • 2l: Container from Container
                                                                                                                        • 2m: Container from Noun
                                                                                                                        • 2n: Functional Hacks
                                                                                                                        • 2o: Normalizing Containers
                                                                                                                        • 2p: Serialization
                                                                                                                        • 2q: Molds and Mold-Builders
                                                                                                                        • 3a: Modular and Signed Ints
                                                                                                                        • 3b: Floating Point
                                                                                                                        • 3c: Urbit Time
                                                                                                                        • 3d: SHA Hash Family
                                                                                                                        • 3e: AES encryption (Removed)
                                                                                                                        • 3f: Scrambling
                                                                                                                        • 3g: Molds and Mold-Builders
                                                                                                                        • 4a: Exotic Bases
                                                                                                                        • 4b: Text Processing
                                                                                                                        • 4c: Tank Printer
                                                                                                                        • 4d: Parsing (Tracing)
                                                                                                                        • 4e: Parsing (Combinators)
                                                                                                                        • 4f: Parsing (Rule-Builders)
                                                                                                                        • 4g: Parsing (Outside Caller)
                                                                                                                        • 4h: Parsing (ASCII Glyphs)
                                                                                                                        • 4i: Parsing (Useful Idioms)
                                                                                                                        • 4j: Parsing (Bases and Base Digits)
                                                                                                                        • 4k: Atom Printing
                                                                                                                        • 4l: Atom Parsing
                                                                                                                        • 4m: Formatting Functions
                                                                                                                        • 4n: Virtualization
                                                                                                                        • 4o: Molds
                                                                                                                        • 5a: Compiler Utilities
                                                                                                                        • 5b: Macro Expansion
                                                                                                                        • 5c: Compiler Backend & Prettyprinter
                                                                                                                        • 5d: Parser
                                                                                                                        • 5e: Molds and mold builders
                                                                                                                        • 5f: Profiling support
                                                                                                                        • Zuse

                                                                                                                          • Table of Contents
                                                                                                                          • 2d(1-5): To JSON, Wains
                                                                                                                          • 2d(6): From JSON
                                                                                                                          • 2d(7): From JSON (unit)
                                                                                                                          • 2e(2-3): Print & Parse JSON
                                                                                                                      • Nock

                                                                                                                        • Nock Definition
                                                                                                                        • Explanation
                                                                                                                        • Example
                                                                                                                        • Implementations
                                                                                                                        • Vere

                                                                                                                          • C Runtime System
                                                                                                                          • Land of Nouns
                                                                                                                          • API overview by prefix
                                                                                                                          • C in Urbit
                                                                                                                          • Writing Jets
                                                                                                                          • Cryptography
                                                                                                                          • Azimuth

                                                                                                                            • Overview
                                                                                                                            • Urbit HD Wallet
                                                                                                                            • Azimuth Data Flow
                                                                                                                            • Azimuth.eth
                                                                                                                            • Ecliptic.eth
                                                                                                                            • Advanced Azimuth Tools
                                                                                                                            • Life and Rift
                                                                                                                            • Layer 2

                                                                                                                              • Layer 2 Overview
                                                                                                                              • Layer 2 Actions
                                                                                                                              • Transaction Format
                                                                                                                              • Rollers
                                                                                                                              • Roller HTTP RPC-API
                                                                                                                              • Custom Roller Tutorial
                                                                                                                            • Glossary

                                                                                                                              • Ames
                                                                                                                              • Aqua
                                                                                                                              • Arm
                                                                                                                              • Arvo
                                                                                                                              • Atom
                                                                                                                              • Azimuth
                                                                                                                              • Battery
                                                                                                                              • Behn
                                                                                                                              • Bridge
                                                                                                                              • Censures
                                                                                                                              • Ceremony
                                                                                                                              • chat
                                                                                                                              • Claims
                                                                                                                              • Clay
                                                                                                                              • Comet
                                                                                                                              • Core
                                                                                                                              • Delegated Sending
                                                                                                                              • Desk
                                                                                                                              • Dill
                                                                                                                              • Document Proposal
                                                                                                                              • Dojo
                                                                                                                              • Door
                                                                                                                              • Ecliptic
                                                                                                                              • Event Log
                                                                                                                              • Eyre
                                                                                                                              • Ford
                                                                                                                              • Galaxy
                                                                                                                              • Gall
                                                                                                                              • Gate
                                                                                                                              • HD Wallet
                                                                                                                              • Hoon
                                                                                                                              • Invite Tree
                                                                                                                              • Iris
                                                                                                                              • Jael
                                                                                                                              • Jaque
                                                                                                                              • Keyfile
                                                                                                                              • Landscape
                                                                                                                              • Mark
                                                                                                                              • Moon
                                                                                                                              • Nock
                                                                                                                              • Noun
                                                                                                                              • OTA Updates
                                                                                                                              • Payload
                                                                                                                              • pH
                                                                                                                              • Pier
                                                                                                                              • Pill
                                                                                                                              • Planet
                                                                                                                              • Proxies
                                                                                                                              • Replay
                                                                                                                              • Factory Reset
                                                                                                                              • Naive rollups
                                                                                                                              • Sail/Udon
                                                                                                                              • Senate
                                                                                                                              • Ship
                                                                                                                              • ship.arvo.network
                                                                                                                              • Star
                                                                                                                              • |sync
                                                                                                                              • Trap
                                                                                                                              • Upgrade Proposal
                                                                                                                              • Vane
                                                                                                                              • Vere
                                                                                                                              • Voting
                                                                                                                              • Wallet-Generator
                                                                                                                              Urbit/Documentation/Userspace/Full-Stack Walkthrough

                                                                                                                              8. React app logic

                                                                                                                              With the basic things setup, we can now go over the logic of our app. We'll just focus on functions that are related to ship communications using the Urbit object we previously setup, and ignore UI components and other helper functions.

                                                                                                                              State

                                                                                                                              In the previous section we just mentioned the connection status field of our state. Here's the full state of our App:

                                                                                                                              state = {
                                                                                                                                entries: [], // list of journal entries for display
                                                                                                                                drafts: {}, // edits which haven't been submitted yet
                                                                                                                                newDraft: {}, // new entry which hasn't been submitted yet
                                                                                                                                results: [], // search results
                                                                                                                                searchStart: null, // search query start date
                                                                                                                                searchEnd: null, // search query end date
                                                                                                                                resultStart: null, // search results start date
                                                                                                                                resultEnd: null, // search results end date
                                                                                                                                searchTime: null, // time of last search
                                                                                                                                latestUpdate: null, // most recent update we've received
                                                                                                                                entryToDelete: null, // deletion target for confirmation modal
                                                                                                                                status: null, // connection status (con, try, err)
                                                                                                                                errorCount: 0, // number of errors so far
                                                                                                                                errors: new Map(), // list of error messages for display
                                                                                                                              };
                                                                                                                              

                                                                                                                              We'll see how these are used subsequently.

                                                                                                                              Initialize

                                                                                                                              The first thing our app does is call init():

                                                                                                                              init = () => {
                                                                                                                                this.getEntries().then(
                                                                                                                                  (result) => {
                                                                                                                                    this.handleUpdate(result);
                                                                                                                                    this.setState({ latestUpdate: result.time });
                                                                                                                                    this.subscribe();
                                                                                                                                  },
                                                                                                                                  (err) => {
                                                                                                                                    this.setErrorMsg("Connection failed");
                                                                                                                                    this.setState({ status: "err" });
                                                                                                                                  }
                                                                                                                                );
                                                                                                                              };
                                                                                                                              

                                                                                                                              This function just calls getEntries() to retrieve the initial list of journal entries then, if that succeeded, it calls subscribe() to subscribe for new updates. If the initial entry retrieval failed, we set the connection status and save an error message in the errors map. We'll look at what we do with errors later.

                                                                                                                              Getting entries

                                                                                                                              entries screenshot

                                                                                                                              The getEntries function scries our %journal agent for up to 10 entries before the oldest we currently have. We call this initially, and then each time the user scrolls to the bottom of the list.

                                                                                                                              getEntries = async () => {
                                                                                                                                const { entries: e } = this.state;
                                                                                                                                const before = e.length === 0 ? Date.now() : e[e.length - 1].id;
                                                                                                                                const max = 10;
                                                                                                                                const path = `/entries/before/${before}/${max}`;
                                                                                                                                return window.urbit.scry({
                                                                                                                                  app: "journal",
                                                                                                                                  path: path,
                                                                                                                                });
                                                                                                                              };
                                                                                                                              

                                                                                                                              The scry is done with the Urbit.scry method. This function takes two arguments in an object:

                                                                                                                              • app - the agent to scry.
                                                                                                                              • path - the scry path. Note the care is not included - all scries through Eyre are %x scries.

                                                                                                                              The Urbit.scry method only allows JSON results, but note that scries done via direct GET requests allow other marks too.

                                                                                                                              The Urbit.scry method returns a Promise which will contain an HTTP error message if the scry failed. We handle it with a .then expression back in the function that called it, either init() or moreEntries(). If the Promise is successfuly, the results are passed to the handleUpdate function which appends the new entries to the existing ones in state.

                                                                                                                              Subscription

                                                                                                                              A subscription to the /updates path of our %journal agent is opened with our subscribe() function:

                                                                                                                              subscribe = () => {
                                                                                                                                try {
                                                                                                                                  window.urbit.subscribe({
                                                                                                                                    app: "journal",
                                                                                                                                    path: "/updates",
                                                                                                                                    event: this.handleUpdate,
                                                                                                                                    err: () => this.setErrorMsg("Subscription rejected"),
                                                                                                                                    quit: () => this.setErrorMsg("Kicked from subscription"),
                                                                                                                                  });
                                                                                                                                } catch {
                                                                                                                                  this.setErrorMsg("Subscription failed");
                                                                                                                                }
                                                                                                                              };
                                                                                                                              

                                                                                                                              We use the Urbit.subscribe method for this, which takes five arguments in an object:

                                                                                                                              • app - the target agent.
                                                                                                                              • path - the %watch path we're subscribing to.
                                                                                                                              • event - a function to handle each fact the agent sends out. We call our handleUpdate function, which we'll describe below.
                                                                                                                              • err - a function to call if the subscription request is rejected (nacked). We just display an error in this case.
                                                                                                                              • quit - a function to call if we get kicked from the subscription. We also just display an error in this case.

                                                                                                                              Note that the Urbit.subscribe method returns a subscription ID number. Since we only have one subscription in our app which we never close, we don't bother to record it. If your app has multiple subscriptions to manage, you may wish to keep track of these IDs in your app's state.

                                                                                                                              Updates

                                                                                                                              This handleUpdate function handles all updates we receive. It's called whenever an event comes in for our subscription, and it's also called with the results of getEntries and getUpdates (described later).

                                                                                                                              It's a bit complex, but basically it just checks whether the JSON object is add, edit, delete, or entries, and then updates the state appropriately. The object it's receiving is just the $update structure converted to JSON by the mark conversion functions we wrote previously.

                                                                                                                              handleUpdate = (upd) => {
                                                                                                                                const { entries, drafts, results, latestUpdate } = this.state;
                                                                                                                                if (upd.time !== latestUpdate) {
                                                                                                                                  if ("entries" in upd) {
                                                                                                                                    this.setState({ entries: entries.concat(upd.entries) });
                                                                                                                                  } else if ("add" in upd) {
                                                                                                                                    const { time, add } = upd;
                                                                                                                                    const eInd = this.spot(add.id, entries);
                                                                                                                                    const rInd = this.spot(add.id, results);
                                                                                                                                    const toE =
                                                                                                                                      entries.length === 0 || add.id > entries[entries.length - 1].id;
                                                                                                                                    const toR = this.inSearch(add.id, time);
                                                                                                                                    toE && entries.splice(eInd, 0, add);
                                                                                                                                    toR && results.splice(rInd, 0, add);
                                                                                                                                    this.setState({
                                                                                                                                      ...(toE && { entries: entries }),
                                                                                                                                      ...(toR && { results: results }),
                                                                                                                                      latestUpdate: time,
                                                                                                                                    });
                                                                                                                                  } else if ("edit" in upd) {
                                                                                                                                    const { time, edit } = upd;
                                                                                                                                    const eInd = entries.findIndex((e) => e.id === edit.id);
                                                                                                                                    const rInd = results.findIndex((e) => e.id === edit.id);
                                                                                                                                    const toE = eInd !== -1;
                                                                                                                                    const toR = rInd !== -1 && this.inSearch(edit.id, time);
                                                                                                                                    if (toE) entries[eInd] = edit;
                                                                                                                                    if (toR) results[rInd] = edit;
                                                                                                                                    (toE || toR) && delete drafts[edit.id];
                                                                                                                                    this.setState({
                                                                                                                                      ...(toE && { entries: entries }),
                                                                                                                                      ...(toR && { results: results }),
                                                                                                                                      ...((toE || toR) && { drafts: drafts }),
                                                                                                                                      latestUpdate: time,
                                                                                                                                    });
                                                                                                                                  } else if ("del" in upd) {
                                                                                                                                    const { time, del } = upd;
                                                                                                                                    const eInd = entries.findIndex((e) => e.id === del.id);
                                                                                                                                    const rInd = results.findIndex((e) => e.id === del.id);
                                                                                                                                    const toE = eInd !== -1;
                                                                                                                                    const toR = this.inSearch(del.id, time) && rInd !== -1;
                                                                                                                                    toE && entries.splice(eInd, 1);
                                                                                                                                    toR && results.splice(rInd, 1);
                                                                                                                                    (toE || toR) && delete drafts[del.id];
                                                                                                                                    this.setState({
                                                                                                                                      ...(toE && { entries: entries }),
                                                                                                                                      ...(toR && { results: results }),
                                                                                                                                      ...((toE || toR) && { drafts: drafts }),
                                                                                                                                      latestUpdate: time,
                                                                                                                                    });
                                                                                                                                  }
                                                                                                                                }
                                                                                                                              };
                                                                                                                              

                                                                                                                              Add, edit, delete

                                                                                                                              add screenshot

                                                                                                                              When a user writes a new journal entry and hits submit, the submitNew function is called. It uses the Urbit.poke method to poke our %journal agent.

                                                                                                                              submitNew = (id, txt) => {
                                                                                                                                window.urbit.poke({
                                                                                                                                  app: "journal",
                                                                                                                                  mark: "journal-action",
                                                                                                                                  json: { add: { id: id, txt: txt } },
                                                                                                                                  onSuccess: () => this.setState({ newDraft: {} }),
                                                                                                                                  onError: () => this.setErrorMsg("New entry rejected"),
                                                                                                                                });
                                                                                                                              };
                                                                                                                              

                                                                                                                              The Urbit.poke method takes five arguments:

                                                                                                                              • app is the agent to poke.
                                                                                                                              • mark is the mark of the data we're sending. We specify "journal-action", so Eyre will use the /mar/journal/action.hoon mark we created to convert it to a $action structure with a %journal-action mark before it's delivered to our agent.
                                                                                                                              • json is the actual data we're poking our agent with. In this case it's the JSON form of the %add $action.
                                                                                                                              • onSuccess is a callback that fires if we get a positive ack in response. In this case we just clear the draft.
                                                                                                                              • onError is a callback that fires if we get a negative ack (nack) in response, meaning the poke failed. In this case we just set an error message to be displayed.

                                                                                                                              onSuccess and onError are optional, but it's usually desirable to handle these cases.

                                                                                                                              The delete and submitEdit functions are similar to submitNew, but for the %del and %edit actions rather than %add:

                                                                                                                              edit screenshot

                                                                                                                              submitEdit = (id, txt) => {
                                                                                                                                if (txt !== null) {
                                                                                                                                  window.urbit.poke({
                                                                                                                                    app: "journal",
                                                                                                                                    mark: "journal-action",
                                                                                                                                    json: { edit: { id: id, txt: txt } },
                                                                                                                                    onError: () => this.setErrorMsg("Edit rejected"),
                                                                                                                                  });
                                                                                                                                } else this.cancelEdit(id);
                                                                                                                              };
                                                                                                                              

                                                                                                                              delete screenshot

                                                                                                                              delete = (id) => {
                                                                                                                                window.urbit.poke({
                                                                                                                                  app: "journal",
                                                                                                                                  mark: "journal-action",
                                                                                                                                  json: {"del": {"id": id}},
                                                                                                                                  onError: ()=>this.setErrorMsg("Deletion rejected")
                                                                                                                                })
                                                                                                                                this.setState({rmModalShow: false, entryToDelete: null})
                                                                                                                              };
                                                                                                                              

                                                                                                                              Note that whether we're adding, editing or deleting entries, we update our state when we receive the update back on the /updates subscription, not when we poke our agent.

                                                                                                                              Search

                                                                                                                              search screenshot

                                                                                                                              When searching for entries between two dates, the getSearch function is called, which uses the Urbit.scry method to scry for the results in a similar fashion to getEntries, but using the /x/entries/between/[start]/[end] endpoint.

                                                                                                                              getSearch = async () => {
                                                                                                                                const { searchStart: ss, searchEnd: se, latestUpdate: lu } = this.state;
                                                                                                                                if (lu !== null && ss !== null && se !== null) {
                                                                                                                                  let start = ss.getTime();
                                                                                                                                  let end = se.getTime();
                                                                                                                                  if (start < 0) start = 0;
                                                                                                                                  if (end < 0) end = 0;
                                                                                                                                  const path = `/entries/between/${start}/${end}`;
                                                                                                                                  window.urbit
                                                                                                                                    .scry({
                                                                                                                                      app: "journal",
                                                                                                                                      path: path,
                                                                                                                                    })
                                                                                                                                    .then(
                                                                                                                                      (result) => {
                                                                                                                                        this.setState({
                                                                                                                                          searchTime: result.time,
                                                                                                                                          searchStart: null,
                                                                                                                                          searchEnd: null,
                                                                                                                                          resultStart: ss,
                                                                                                                                          resultEnd: se,
                                                                                                                                          results: result.entries,
                                                                                                                                        });
                                                                                                                                      },
                                                                                                                                      (err) => {
                                                                                                                                        this.setErrorMsg("Search failed");
                                                                                                                                      }
                                                                                                                                    );
                                                                                                                                } else {
                                                                                                                                  lu !== null && this.setErrorMsg("Searh failed");
                                                                                                                                }
                                                                                                                              };
                                                                                                                              

                                                                                                                              Error handling

                                                                                                                              When the channel connection is interrupted, the Urbit object will begin trying to reconnect. On each attempt, it sets the connection status to "try", as we specified for the onRetry callback. When this is set, a "reconnecting" message is displayed at the bottom of the screen:

                                                                                                                              reconnecting screenshot

                                                                                                                              If all three reconnection attempts fail, the onError callback is fired and we replace the "reconnecting" message with a "reconnect" button:

                                                                                                                              reconnect screenshot

                                                                                                                              When clicked, the following function is called:

                                                                                                                              reconnect = () => {
                                                                                                                                window.urbit.reset();
                                                                                                                                const latest = this.state.latestUpdate;
                                                                                                                                if (latest === null) {
                                                                                                                                  this.init();
                                                                                                                                } else {
                                                                                                                                  this.getUpdates().then(
                                                                                                                                    (result) => {
                                                                                                                                      result.logs.map((e) => this.handleUpdate(e));
                                                                                                                                      this.subscribe();
                                                                                                                                    },
                                                                                                                                    (err) => {
                                                                                                                                      this.setErrorMsg("Connection failed");
                                                                                                                                      this.setState({ status: "err" });
                                                                                                                                    }
                                                                                                                                  );
                                                                                                                                }
                                                                                                                              };
                                                                                                                              

                                                                                                                              Our reconnect() function first calls the Urbit.reset method. This closes the channel connection, wipes event counts and subscriptions, and generates a new channel ID. We could have tried reconnecting without resetting the connection, but we don't know whether the channel still exists. We could time how long the connection has been down and estimate whether it still exists, but it's easier to just start fresh in this case.

                                                                                                                              Since we've reset the channel, we don't know if we've missed any updates. Rather than having to refresh our whole state, we can use the getUpdates() function to get any missing update:

                                                                                                                              getUpdates = async () => {
                                                                                                                                const { latestUpdate: latest } = this.state;
                                                                                                                                const since = latest === null ? Date.now() : latest;
                                                                                                                                const path = `/updates/since/${since}`;
                                                                                                                                return window.urbit.scry({
                                                                                                                                  app: "journal",
                                                                                                                                  path: path,
                                                                                                                                });
                                                                                                                              };
                                                                                                                              

                                                                                                                              This function uses the Urbit.scry method to scry the /x/updates/since/[since] path, querying the update $log for entries more recent than latestUpdate, which is always set to the last logged action we received. The getUpdates function returns a Promise to the reconnect function above which called it. The reconnect function handles it in a .then expression, where the success case passes each update retrieved to the handleUpdate function, updating our state.

                                                                                                                              Lastly, as well as handling channel connection errors, we also handle errors such as poke nacks or failed scries by printing error messages added to the error map by the setErrorMsg function. You could of course handle nacks, kicks, scry failures, etc differently than just printing an error, it depends on the needs of your app.

                                                                                                                              search failed screenshot

                                                                                                                              Resources

                                                                                                                              • HTTP API Guide - Reference documentation for @urbit/http-api.

                                                                                                                              • React app source code - The source code for the Journal app UI.

                                                                                                                              • @urbit/http-api source code - The source code for the @urbit/http-api NPM package.

                                                                                                                              <-

                                                                                                                              7. React app setup

                                                                                                                              9. Desk and glob

                                                                                                                              ->

                                                                                                                              Edit this page on GitHub