Dexie.js

Fiddle with Dexie.js

by David Fahlander

HTML

<!-- ES Module Dependencies -->
<script type="importmap">
{
  "imports": {
    "dexie": "https://esm.sh/dexie@4",
    "dexie-cloud-addon": "https://esm.sh/dexie-cloud-addon@4?external=dexie",
    "uuid": "https://esm.sh/uuid@14"
  }
}
</script>

<!-- Some HTML for the log window -->
<a href="http://dexie.org/docs/API-Reference" target="_new">Dexie API Reference (new tab)</a>
<div class="header">
<h3>Log</h3>
<div>
  <button id="loginButton">Login</button>
  <button id="deleteFriendsButton">Delete all friends</button>
</div>
</div>
<textarea id="log"></textarea>

<!-- Just a simple log function... --> 
<script>
  function log(txt) {document.getElementById('log').value+=txt+"\n";}
</script>

<!-- Button actions --> 
<script type="module">
  import Dexie from "dexie";
  
  document.getElementById('deleteFriendsButton').onclick = async () => {
    const db = Dexie.connections[0];
    const friendCount = await db.friends.count();
    await db.friends.clear();
    //document.getElementById('log').value = "";
    log(`Deleted ${friendCount} friends. Now nada friends left :(`);
    log("Click ↻ Run to run the script again!");
  }

  document.getElementById('loginButton').onclick = async () => {
    const db = Dexie.connections[0];
    try {
      if (db.cloud?.currentUser?.value?.isLoggedIn) {
        log(`Already logged in as ${db.cloud.currentUserId}.`);
        log(`Delete database using Devtools to start over...`);
      } else if (db.cloud) {
        await db.cloud?.login();
        location.reload();
      } else {
        log(`Cannot login when just using vanilla Dexie`);
      }
    } catch (e) {
      log("Failed to login: " + e);
    }
  }
</script>

CSS

textarea#log
{
    width: 100%;
    height: 1000px;
}

.header {
  display: flex;
  align-items: center;      /* Vertically center items */
  justify-content: space-between; /* Push items apart */
}

.header h3 {
  margin: 0; /* Remove default margin if needed */
}

JavaScript

import Dexie from "dexie";
import dexieCloud from "dexie-cloud-addon";
import {v7 as uuidv7} from "uuid";

log("Using dexie@" + Dexie.semVer);

//
// Vanilla Dexie
//
class FriendDB extends Dexie {
  constructor() {
    super("FriendDB");
    this.version(1).stores({
      // "friends" table
      //   Primary key: id
      //   Indexes: name and age
      friends: `id, name, age`
    })
  }
}

//
// If you want Dexie with sync:
//
class SyncedFriendDB extends Dexie {
  constructor() {
    super("FriendDB", { addons: [dexieCloud]});
    log("Using dexie-cloud-addon@" + this.cloud.version);
    this.version(1).stores({
      friends: `id, name, age`
    })
    this.cloud.configure({
      // databaseUrl: Create your own via `npx dexie-cloud create`
      databaseUrl: "https://zluol5mr1.dexie.cloud"
    })
  }
}

//
//
// Instanciate db
//
//
//const db = new FriendDB(); // Use this line instead for vanilla Dexie
const db = new SyncedFriendDB(); 

//
//
// Query Database
//
//
try {
  const friendCount = await db.friends.count();
  if (friendCount >= 3) {
    log(`We already have ${friendCount} friends \\O/  No need to create more!`);
  } else {
    log("Too few friends. Create one more...");
    await db.friends.add({
      id: uuidv7(), // Universially unique ID, time-ordered
      name: "Foo",
      age: 42 + friendCount, // ..whatever
    });
  }
  const friends = await db.friends.where("age").between(40, 65).toArray();

  log("Found friends: " + JSON.stringify(friends, null, 2));
} catch (e) {
  log(''+e);
}