Giter VIP home page Giter VIP logo

exercise-tracker's Introduction

Estate

Introduction ๐ŸŒ„

In a world where bespoke backend software is easily generated, Estate is here to help you build backends at a higher abstraction, and faster than it would take you to prompt GPT to write it for you using traditional backend tooling.

Estate is an open-source TypeScript object database with an embedded AppServer that may be all you need to write powerful real-time SaaS backends and efficient Line-of-Business app backends.

Estate is lightning fast: most backend requests complete in under 200ฮผs (Not including network round-trip).

Quick Walkthrough (10 minutes โฑ๏ธ): Exercise Tracker Demo App

This demo is an example full-stack SaaS app that allows users to track the exercises they do in a shared real-time list. The backend runs in Google Cloud (us-central) and the front-end client (React+Vite) is running in this StackBlitz sandbox.

Key Takeaways

๐Ÿค Curiously Concise Code, where's the boilerplate?

๐Ÿƒ Strongly typed data persistence, end-to-end TypeScript shared type system.

โšก๏ธ Easy-mode real-time server-to-client messaging, update all clients in real-time!

๐Ÿ‘โ€๐Ÿ—จ Data is remotely observable, adding reactive views!

Setup (2 minutes โฑ๏ธ)

  1. Login to the default Estate cluster (aka "Sandbox")
$ estate login

This opens a new browser tab. Click "Continue as Guest" to login anonymously.

  1. Initialize the backend service code directory:
$ cd service
$ estate init .

Enter exercise-tracker when it asks for a name. This makes the service code directory a Service that can be deployed and connected to by clients/front-ends.

  1. Deploy the backend service:
$ estate deploy .

Each time you make changes to your service backend code, you'll need to rerun this command.

  • Inspect:
  • The backend database source code is located in the service/index.ts file.
  • It's only 115 lines of code, yet is an entire backend for this application.
  • How:
  • An Estate Service is a collection of one or more TypeScript POJO classes that extend Worker, Data, or Message. Workers run stateful code on the backend and can be called via autogenerated client-side proxies. Data elements define your app's data model, contain business logic, and are persisted to the database. Messages provide real-time backend-to-client events.
  • With these three types, you can build very powerful backend business logic.

๐Ÿค Curiously concise backend code

  1. Generate code to connect to the service in the front-end/client NPM project:
$ cd ..
$ estate connect . exercise-tracker

Select "pnpm" (press enter) when asked to update node_modules. It will only ask you to do this the first time you make a service connection. This command must be rerun each time the backend service is deployed.

  1. Start Exercise Tracker demo
$ npm run dev

Guided Tour (8 minutes โฑ๏ธ)

  1. In the Exercise Tracker window (๐Ÿ‘‰), click "Add user" and add a user (any name will do).
    • Inspect:
    • The username you entered now exists in the Username drop-down box.
    • A new User Data object was created and saved to the database using the username you supplied.
    • How:
    • The React client code passed the username to the backend by calling a server-side, Worker method at src/pages/create-user.tsx line 16:
10)  const exerciseTracker = estate.getWorker(ExerciseTrackerWorker, "default");
   ...
16)  await exerciseTracker.addUser(username);
  • Line 16 makes a transparent backend call to the Estate backend cluster running the service you deployed.
  • In the backend code, the username argument is passed to the worker method at service/index.ts:
49)  addUser(username: string): User {
         ...
53)      const user = new User(username);
54)      saveData(user);
         ...
     }
  • At line 53, a new instance of the User Data object is instanciated, passing the username to the constructor.
  • The following line saves the new user to the database.
  • If the user didn't have a unique username, saveData would throw an exception.
  • This is because the User class passes the username from its contructor to super, because all Data-derived classes must specify a primary key:
18)  export class User extends Data {
19)      constructor(public username: string) {
20)          super(username);
21)      }
22)  }
  • Data can have any number of properties of any TypeScript type. Each property will be stored in the database when the object is passed to saveData.

๐Ÿƒ Estate makes strongly typed data persistence easy

  1. Click "Open in new Tab" in the top-right (๐Ÿ‘‰).
  2. Right-click the new browser tab and click "Duplicate"
  3. Detach the tab and arrange the windows, so you can see all of them at the same time.
  4. In the Create Exercise form, fill in the fields and click "Create Exercise Log."
    • Inspect:
    • Do you see how the new exercise showed up in the other window instantly?
    • The Message class lets you send strongly typed messages/events from Worker backend code to any number of clients, simultanuosly. This is called a Server-Sent-Event, or SSE.
    • How:
    • A Message is a POJO that extends Message. Any properties you define on the POJO are sent to clients who subscribe to it. The ExercsieAdded message is:
12)  export class ExerciseAdded extends Message {
13)       constructor(public exercise: Exercise) {
14)           super();
15)       }
16)  }
  • Workers send Messages to clients who have subscribed. The client subscribes to recieve all ExerciseAdded messages sent by the worker at src/pages/exercises-list.tsx:
71)   estate.subscribeMessageAsync(exerciseTracker, ExerciseAdded, onExerciseAdded)
  • The ExerciseTrackerWorker sends an ExerciseAdded message at service/index.ts:
76)   addExercise(exercise: Exercise) {
         ...
85)      sendMessage(this, new ExerciseAdded(exercise));
86)   }

โšก๏ธ Estate makes it easy to add real-time capabilities

  1. From the list of exercises, edit an exercise or delete an exercise.
    • Inspect:
    • See how the change shows up in the other windows?
    • How:
    • The React client code subscribes to external updates to Exercise object changes (including deletes) at src/pages/exercises-list.tsx:
80)     estate.subscribeUpdatesAsync(exercises_)
81)         .then(() => {
82)             ...
83)             estate.addUpdateListener(exercises_, onExerciseUpdate);
84)         })
  • Line 80 tells the Estate back the client wants to recieve updates to the exercise Data instances in the exercises_ array.
  • Line 83 tells the Estate browser runtime to call the onExerciseUpdate client function when new updates are recieved. This lets the client code update the view/UI when other clients make changes.

๐Ÿ‘โ€๐Ÿ—จ Estate's Data is remotely observable, adding more real-time goodness

Testers, Needed!

Please check out our GitHub https://github.com/EstateJS/estate (Stars would be very helpful, thanks!)

We're active on Discord! https://discord.gg/ahHffbBkNQ

More Learning

The estate repo contains the client-side packages: https://github.com/EstateJS/estate

The system repo contains the backend platform: https://github.com/EstateJS/system

If you're interested in how the transport protocol works, check out the Google Flatbuffers schemas: https://github.com/EstateJS/system/tree/main/schema

Open-Source License

The framework (Tools SDK, Client runtime) is MIT licensed and the platform is Apache-2 licensed.

exercise-tracker's People

Contributors

imscottirl avatar nick-w-nick avatar

Forkers

acald-creator

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.