All Projects → spawnfest → exile

spawnfest / exile

Licence: other
🖥️ ⚡ 🖥️ A Realtime Database-as-a-Service with REST-style resource location and Time Traveling Feature support. Spawnfest 2019 project winner 🏆

Programming Languages

elixir
2628 projects
javascript
184084 projects - #8 most used programming language
HTML
75241 projects
CSS
56736 projects

Labels

Projects that are alternatives of or similar to exile

kawalpemilu-visualized
An interactive data visualization of the result of Indonesia's recent election built using D3.js and KawalPemilu API
Stars: ✭ 40 (-16.67%)
Mutual labels:  2019
mbp-fedora-kernel
No description or website provided.
Stars: ✭ 57 (+18.75%)
Mutual labels:  2019
printfTester
Tester for the ft_printf project of 42 school
Stars: ✭ 94 (+95.83%)
Mutual labels:  2019
gnlTester
Tester for the get_next_line project of 42 school
Stars: ✭ 87 (+81.25%)
Mutual labels:  2019
cissp
CISSP Study Materials PDF and Web Copy for 2021
Stars: ✭ 24 (-50%)
Mutual labels:  2019
Cavemen-GGJ2019
A multiplayer survival game developed during Global Game Jam 2019.
Stars: ✭ 21 (-56.25%)
Mutual labels:  2019
adfsmfa
MFA for ADFS 2022/2019/2016/2012r2
Stars: ✭ 86 (+79.17%)
Mutual labels:  2019
libftTester
Tester for the libft project of 42 school
Stars: ✭ 141 (+193.75%)
Mutual labels:  2019
PyConES-2019-data
PyConES 2019 conferences, attachments and related stuff
Stars: ✭ 18 (-62.5%)
Mutual labels:  2019
EVHS-Programming-Club
The public GitHub repo for the EVHS Programming Club
Stars: ✭ 16 (-66.67%)
Mutual labels:  2019
hacktoberfest-training-2019
A simple repo to promote participations on Hacktoberfest for beginners
Stars: ✭ 13 (-72.92%)
Mutual labels:  2019
Multi-Hop-Knowledge-Paths-Human-Needs
Ranking and Selecting Multi-Hop Knowledge Paths to Better Predict Human Needs
Stars: ✭ 17 (-64.58%)
Mutual labels:  2019
2019
National Novel Generation Month, 2019 edition.
Stars: ✭ 96 (+100%)
Mutual labels:  2019
github-analysis-2019
An analysis of GitHub 2019, for study purpose
Stars: ✭ 22 (-54.17%)
Mutual labels:  2019
CS231n
Solutions to Assignments of CS231n: Convolutional Neural Networks for Visual Recognition(http://cs231n.github.io/)
Stars: ✭ 13 (-72.92%)
Mutual labels:  2019
ml flood
Machine learning to predict floods
Stars: ✭ 50 (+4.17%)
Mutual labels:  2019

Exile

A Realtime Database-As-A-Service with REST style resource location and Time Traveling Feature support.

See it live @ https://exile-web.gigalixirapp.com

Philosophy

An extremely simple to use NoSQL store which follows REST-like resource locators known as paths to locate records and define relations between data.

Getting Started

Development

Run Tests

mix tests

Run Dialyzer

mix dialyzer

Generate and View Docs

mix docs && open doc/index.html

Run App Locally

mix do deps.get, compile
(cd apps/exile_web/assets && npm install)
iex -S mix phx.server
open http://localhost:4000

🎉 You will be presented with an interact REPL to play with the RT Database via JS API!

🎉 You can also interact directly with the store using the Exile Elixir API Directly via the IEX session. See Docs: doc/Exile.html#content

Real Time Database 🖥️ 🖥️

  • Goto https://exile-web.gigalixirapp.com/ (or run locally)
  • Copy the URL (which contains the sandbox token) into another browser window
  • Click subscribe which will listen for changes on the "posts" domain path
  • Create posts in the other window
  • See the Magic as the changes are relayed to all subscribers

An example scenario:

Using Exile to create a blog completely in client JS, submit and edit posts and have them visible to all sessions, and have comments instantly appear in a live fashion in all sessions, WITHOUT ANY SERVER SIDE CODE 😍

API

POST

Create Records

elixir

Exile.post("posts", {author: "holsee", title: "Hello World", body: "...", comments: []})
#=> {:ok, "614e1637-5af1-4bd4-8432-e5ccd3b5cd90"}

javascript

exile.post('posts', {author: 'holsee', title: 'Hello World', body: '...', comments: []})
//=>
{
  reference: 'posts',
  result: 'ok',
  value: '04c7fecd-9e3f-408d-8799-fef8d120d93c'
}
Nested

Create a nested Record

elixir: create a comment on a post

Exile.post("posts/#{post_id}/comments", %{author: "evadne", body: "nice!"})
#=>
{:ok, "cd3c2478-cc50-4010-b54c-7e6e2f534695"}

javascript: create a comment on a post

exile.post(`posts/${post_id}/comments`, {author: 'evadne', body: 'nice!'})
//=>
{
  reference: 'posts/04c7fecd-9e3f-408d-8799-fef8d120d93c/comments',
  result: 'ok',
  value: 'a7cc9516-59d0-4095-970d-25eeb7d0b5be'
}

GET

🔥 Using REST style locator paths you are able to dig into resources which have been dynamically created! 🔥

elixir: get all posts

Exile.get('posts')
# =>
{:ok,
 [
   %{
     id: "88d903d4-4b7e-4735-926d-a54bce4b94cf",
     ts: 1569186483608933000,
     value: %{
       "author" => "holsee",
       "comments" => [
         %{
           id: "cd3c2478-cc50-4010-b54c-7e6e2f534695",
           ts: 1569186483608929000,
           value: %{"author" => "bran", "body" => "Lorem ipsum"}
         }
       ],
       "tags" => ["bill", "ted", "rufus"]
     }
   }
 ]}

elixir: get a specific comment

Exile.get("posts/#{post_id}/comments/#{comment_id}")
#=>
{:ok, %{"author" => "bran", "body" => "Lorem ipsum"}}

elixir: get a specific comment author

Exile.get("posts/#{post_id}/comments/#{comment_id}")
#=>
{:ok, "bran"}

javascript: get all posts

exile.get('posts')
//=>
{
  reference: 'posts',
  result: 'ok',
  value: [
    {
      id: '4874b3dd-6f67-48dd-8b3f-182ead6362a6',
      ts: 1569186089957471700,
      value: {
        author: 'holsee',
        body: '...',
        comments: [
          {
            id: '6748759c-896b-4e5b-93e9-3f49fa4d06cd',
            ts: 1569186089957465000,
            value: {
              author: 'evadne',
              body: 'nice!'
            }
          }
        ],
        title: 'Hello World'
      }
    }
  ]
}

javascript: get all comments on a post

exile.get('posts/${post_id}/comments')
//=>
{
  reference: 'posts/4874b3dd-6f67-48dd-8b3f-182ead6362a6/comments',
  result: 'ok',
  value: [
    {
      id: '6748759c-896b-4e5b-93e9-3f49fa4d06cd',
      ts: 1569186089957465000,
      value: {
        author: 'evadne',
        body: 'nice!'
      }
    }
  ]
}

PUT

Unlike POST operations which create new records, PUT allows you to update values at a locator path.

elixir: update post body

Exile.put("posts/#{post_id}/body", "new body!")
# => :ok

Exile.get("posts/#{post_id}/body")
# =>
{:ok, "new body!"}

DELETE

You can also delete values at the path:

elixir: delete all posts

Exile.delete("posts")
# =>
:ok

javascript: delete all posts

exile.delete('posts')

Subscribe to path (Realtime features 🖥️ 🖥️)

elixir: subscribe to posts, get update event

subscriber_address = self()
Exile.subscribe("posts", subscriber_address)
#=>
:ok

#when post is created or updated receive event:
flush()
#=>
{:exile_event,
 {:update, "posts/e5373a79-8b76-464f-b72a-8182a1ed6230/body",
  {"e5373a79-8b76-464f-b72a-8182a1ed6230", 1569187403304193274,
   %{
     "author" => "holsee",
     "body" => "new body!",
     "comments" => [
       %{
         id: "787b20f6-643f-454d-9a87-f9fd985b4458",
         ts: 1569186933359652898,
         value: %{"author" => "bran", "body" => "Lorem ipsum"}
       }
     ],
     "tags" => ["bill", "ted", "rufus"]
   }}}}

javascript: subscribe to posts, get new item event

exile.subscribe('posts')
#=>
{
  result: 'ok'
}

# when post is created receive event
#=>
{
  event_type: 'new',
  path: '37469d37-21f9-4ea5-b2a9-ebe136d8c3cc:posts',
  record: {
    id: 'd9f0db63-2f3d-422d-b9d7-bccc549d3e65',
    timestamp: 1569187287039046000,
    value: {
      comments: [],
      title: 'Hello World'
    }
  }
}

Time Traveling 🕓🕒🕑

At a storage level records are immutable and every change results in a new version. By default the latest version is returned.

There is no public API support for this (ironically we ran out of time 🥁🤣) but as we have the foundations in place as detailed, we envision an API like the following being completely possible:

get last 10 revisions of a post:

exile.get('posts/${post_id}', {last: 10})

get versions between timestamps:

exile.get('posts/${post_id}', {from: 1569186663, to: 1569187763})
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].