Skip to content

About

TLDR;

  • Magnetar is a state management library.
    A library that brings a simple syntax for reading and writing data and allows you to easily work with this data in your app like a global store.

  • Magnetar has 2-way sync database integration for Google Firestore (and others coming). You do not need to learn to work with the database SDK.
    — Whenever you modify data in your local cache store, Magnetar will update your database on the server.
    — Whenever the server has changes, Magnetar will reflect those in your local cache store.

  • Magnetar's main focus is to be the cache as representation of your database.

  • Magnetar is framework-agnostic. It can be used with Vue/React/Angular/Vanilla JS projects.

  • Magnetar is modular. It works with plugins that provide capabilities so you can only include what you actually need.

  • Magnetar has plugins for Vue 2 & Vue 3 that offer built-in reactivity.
    Just like Vuex, displaying data in Vue just works as you would expect and is reactive on local cache/server changes. (Magnetar does not rely on Vuex)

Learn by Example

Here is a hypothetical example of a To Do list powered by Magnetar that uses the Vue 3 and Firestore plugins.

html
<script setup>
  import { onCreated, computed } from 'vue'
  // magnetar is instantiated with the firestore and vue 2 plugins
  // (See the Setup chapter)
  import { magnetar } from './my-magnetar-setup.js'

  /**
   * A module for data in firestore, at path 'todo-items'
   */
  const todoItemsModule = magnetar.collection('todo-items')

  onCreated(() => {
    // fetch all documents from Firestore & continue to watch for any changes
    // will keep cached data up to date when changes on database occur
    todoItemsModule.stream()
  })

  /**
   * Displays the cached data of your module (data comes in via the stream)
   */
  const items = computed(() => {
    // in magnetar, the collection `.data` is a JS Map
    return todoItemsModule.data.values()
  })

  /**
   * Adds a new item to the cached data & makes API call to Firestore
   * UI is reflected automatically
   */
  function addItem(newData) {
    todoItemsModule.insert(newData)
  }

  /**
   * Edits an item in the cached data & makes API call to Firestore
   * UI is reflected automatically
   */
  function editItem(id, newData) {
    todoItemsModule.doc(id).merge(newData)
  }

  /**
   * Deletes an item from the cached data & makes API call to Firestore
   * UI is reflected automatically
   */
  function deleteItem(id) {
    todoItemsModule.delete(id)
  }

  // This example is the top level component representing a todo list
  // it holds the logic to display your UI and act on user interaction
</script>

<template>
  <!-- the TodoItem and AddNewTodoItem are hypothetical UI components -->
  <!-- they should emit events based on user input -->
  <div class="my-todo-list">
    <TodoItem v-for="item in items" :key="item.id" @edit-item="editItem" @delete-item="deleteItem">
      {{ item.name }}
    </TodoItem>

    <AddNewTodoItem @add-item="addItem" />
  </div>
</template>