@fireproof/core 0.19.5-dev → 0.19.8-dev-alldocs
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{chunk-QHSXUST7.js → chunk-5UFCF36O.js} +3 -3
 - package/{chunk-HCXR2M5B.js → chunk-DG6XSV44.js} +175 -7
 - package/chunk-DG6XSV44.js.map +1 -0
 - package/{chunk-H3A2HMMM.js → chunk-OWQAHX2V.js} +2 -2
 - package/chunk-OWQAHX2V.js.map +1 -0
 - package/{chunk-7OGPZSGT.js → chunk-PRQHQG4I.js} +2 -2
 - package/index.cjs +248 -191
 - package/index.cjs.map +1 -1
 - package/index.d.cts +174 -68
 - package/index.d.ts +174 -68
 - package/index.global.js +24688 -0
 - package/index.global.js.map +1 -0
 - package/index.js +60 -127
 - package/index.js.map +1 -1
 - package/metafile-cjs.json +1 -1
 - package/metafile-esm.json +1 -1
 - package/metafile-iife.json +1 -0
 - package/{node-sys-container-E7LADX2Z.js → node-sys-container-TTGEC66A.js} +2 -2
 - package/package.json +1 -1
 - package/{sqlite-data-store-YS4U7AQ4.js → sqlite-data-store-MA55LVQE.js} +4 -4
 - package/{sqlite-meta-store-FJZSZG4R.js → sqlite-meta-store-UNQKVYRM.js} +4 -4
 - package/{sqlite-wal-store-6JZ4URNS.js → sqlite-wal-store-KVUOC4PO.js} +4 -4
 - package/{store-file-HMHPQTUV.js → store-file-WD746RSY.js} +3 -3
 - package/{store-indexdb-MRVZG4OG.js → store-indexdb-NG45BU3Q.js} +4 -4
 - package/{store-sql-5XMJ5OWJ.js → store-sql-QVFNIGND.js} +7 -69
 - package/store-sql-QVFNIGND.js.map +1 -0
 - package/tests/blockstore/loader.test.ts +265 -0
 - package/tests/blockstore/store.test.ts +164 -0
 - package/tests/blockstore/transaction.test.ts +121 -0
 - package/tests/fireproof/config.test.ts +212 -0
 - package/tests/fireproof/crdt.test.ts +434 -0
 - package/tests/fireproof/database.test.ts +466 -0
 - package/tests/fireproof/fireproof.test.ts +602 -0
 - package/tests/fireproof/hello.test.ts +54 -0
 - package/tests/fireproof/indexer.test.ts +389 -0
 - package/tests/helpers.ts +81 -0
 - package/tests/react/useFireproof.test.tsx +19 -0
 - package/tests/www/gallery.html +132 -0
 - package/tests/www/iife.html +42 -0
 - package/tests/www/todo-aws.html +232 -0
 - package/tests/www/todo-ipfs.html +213 -0
 - package/tests/www/todo-local.html +214 -0
 - package/tests/www/todo-netlify.html +227 -0
 - package/tests/www/todo.html +236 -0
 - package/chunk-H3A2HMMM.js.map +0 -1
 - package/chunk-HCXR2M5B.js.map +0 -1
 - package/store-sql-5XMJ5OWJ.js.map +0 -1
 - /package/{chunk-QHSXUST7.js.map → chunk-5UFCF36O.js.map} +0 -0
 - /package/{chunk-7OGPZSGT.js.map → chunk-PRQHQG4I.js.map} +0 -0
 - /package/{node-sys-container-E7LADX2Z.js.map → node-sys-container-TTGEC66A.js.map} +0 -0
 - /package/{sqlite-data-store-YS4U7AQ4.js.map → sqlite-data-store-MA55LVQE.js.map} +0 -0
 - /package/{sqlite-meta-store-FJZSZG4R.js.map → sqlite-meta-store-UNQKVYRM.js.map} +0 -0
 - /package/{sqlite-wal-store-6JZ4URNS.js.map → sqlite-wal-store-KVUOC4PO.js.map} +0 -0
 - /package/{store-file-HMHPQTUV.js.map → store-file-WD746RSY.js.map} +0 -0
 - /package/{store-indexdb-MRVZG4OG.js.map → store-indexdb-NG45BU3Q.js.map} +0 -0
 
| 
         @@ -0,0 +1,232 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <!doctype html>
         
     | 
| 
      
 2 
     | 
    
         
            +
            <html lang="en">
         
     | 
| 
      
 3 
     | 
    
         
            +
              <head>
         
     | 
| 
      
 4 
     | 
    
         
            +
                <meta charset="UTF-8" />
         
     | 
| 
      
 5 
     | 
    
         
            +
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
         
     | 
| 
      
 6 
     | 
    
         
            +
                <title>Fireproof Test</title>
         
     | 
| 
      
 7 
     | 
    
         
            +
                <script src="./fireproof.iife.js"></script>
         
     | 
| 
      
 8 
     | 
    
         
            +
                <script src="./connect.iife.js"></script>
         
     | 
| 
      
 9 
     | 
    
         
            +
                <script type="text/javascript">
         
     | 
| 
      
 10 
     | 
    
         
            +
                  function todoApp() {
         
     | 
| 
      
 11 
     | 
    
         
            +
                    const actorTag = Math.random().toString(36).substring(2, 7);
         
     | 
| 
      
 12 
     | 
    
         
            +
                    const { fireproof, index } = Fireproof;
         
     | 
| 
      
 13 
     | 
    
         
            +
                    const { connect } = FireproofConnect;
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    // console.log('connect', connect)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    let dbName;
         
     | 
| 
      
 18 
     | 
    
         
            +
                    let db;
         
     | 
| 
      
 19 
     | 
    
         
            +
                    let cx;
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    let dbUnsubscribe = false;
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    function setupDb(name, newDb, newConn) {
         
     | 
| 
      
 24 
     | 
    
         
            +
                      const input = document.querySelector("#todo");
         
     | 
| 
      
 25 
     | 
    
         
            +
                      input.disabled = true;
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                      if (dbUnsubscribe) {
         
     | 
| 
      
 28 
     | 
    
         
            +
                        dbUnsubscribe();
         
     | 
| 
      
 29 
     | 
    
         
            +
                      }
         
     | 
| 
      
 30 
     | 
    
         
            +
                      if (newDb) {
         
     | 
| 
      
 31 
     | 
    
         
            +
                        // console.log('new db', newDb, newConn)
         
     | 
| 
      
 32 
     | 
    
         
            +
                        name = newDb.name;
         
     | 
| 
      
 33 
     | 
    
         
            +
                        dbName = newDb.name;
         
     | 
| 
      
 34 
     | 
    
         
            +
                        db = newDb;
         
     | 
| 
      
 35 
     | 
    
         
            +
                        cx = newConn;
         
     | 
| 
      
 36 
     | 
    
         
            +
                        const input = document.querySelector("#list");
         
     | 
| 
      
 37 
     | 
    
         
            +
                        input.value = dbName;
         
     | 
| 
      
 38 
     | 
    
         
            +
                      } else {
         
     | 
| 
      
 39 
     | 
    
         
            +
                        dbName = name;
         
     | 
| 
      
 40 
     | 
    
         
            +
                        db = fireproof(name, { autoCompact: 100 });
         
     | 
| 
      
 41 
     | 
    
         
            +
                        cx = connect.awsFree(db);
         
     | 
| 
      
 42 
     | 
    
         
            +
                        cx.ready.then(async () => {
         
     | 
| 
      
 43 
     | 
    
         
            +
                          const span = document.querySelector("#cxInfo");
         
     | 
| 
      
 44 
     | 
    
         
            +
                          span.innerText = `📡`;
         
     | 
| 
      
 45 
     | 
    
         
            +
                          span.addEventListener("click", () => {
         
     | 
| 
      
 46 
     | 
    
         
            +
                            cx.refresh();
         
     | 
| 
      
 47 
     | 
    
         
            +
                          });
         
     | 
| 
      
 48 
     | 
    
         
            +
                        });
         
     | 
| 
      
 49 
     | 
    
         
            +
                      }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                      window.db = db;
         
     | 
| 
      
 52 
     | 
    
         
            +
                      window.cx = cx;
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      db.changes([], { limit: 1 }).then((changes) => {
         
     | 
| 
      
 55 
     | 
    
         
            +
                        if (changes.clock.length > 0) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                          input.disabled = false;
         
     | 
| 
      
 57 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 58 
     | 
    
         
            +
                          cx.ready.then(async () => {
         
     | 
| 
      
 59 
     | 
    
         
            +
                            input.disabled = false;
         
     | 
| 
      
 60 
     | 
    
         
            +
                          });
         
     | 
| 
      
 61 
     | 
    
         
            +
                        }
         
     | 
| 
      
 62 
     | 
    
         
            +
                      });
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                      dbUnsubscribe = db.subscribe(redraw);
         
     | 
| 
      
 65 
     | 
    
         
            +
                      return db;
         
     | 
| 
      
 66 
     | 
    
         
            +
                    }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    let doing;
         
     | 
| 
      
 69 
     | 
    
         
            +
                    const redraw = async () => {
         
     | 
| 
      
 70 
     | 
    
         
            +
                      if (doing) {
         
     | 
| 
      
 71 
     | 
    
         
            +
                        return doing;
         
     | 
| 
      
 72 
     | 
    
         
            +
                      }
         
     | 
| 
      
 73 
     | 
    
         
            +
                      doing = doRedraw().finally(() => (doing = null));
         
     | 
| 
      
 74 
     | 
    
         
            +
                      return doing;
         
     | 
| 
      
 75 
     | 
    
         
            +
                    };
         
     | 
| 
      
 76 
     | 
    
         
            +
                    window.redraw = redraw;
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                    let compactor = "🚗";
         
     | 
| 
      
 79 
     | 
    
         
            +
                    function drawInfo() {
         
     | 
| 
      
 80 
     | 
    
         
            +
                      document.querySelector("#carLog").innerText =
         
     | 
| 
      
 81 
     | 
    
         
            +
                        ` ⏰ ${db._crdt.clock.head.length} ${compactor} ${cx.loader.carLog.length} 📩 ${cx.loader.remoteWAL.walState.operations.length}`;
         
     | 
| 
      
 82 
     | 
    
         
            +
                    }
         
     | 
| 
      
 83 
     | 
    
         
            +
                    const doRedraw = async () => {
         
     | 
| 
      
 84 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 85 
     | 
    
         
            +
                      const result = await db.allDocs();
         
     | 
| 
      
 86 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 87 
     | 
    
         
            +
                      document.querySelector("ul").innerHTML = "";
         
     | 
| 
      
 88 
     | 
    
         
            +
                      for (const row of result.rows) {
         
     | 
| 
      
 89 
     | 
    
         
            +
                        // const doc = await db.get(row.id);
         
     | 
| 
      
 90 
     | 
    
         
            +
                        const doc = row.value;
         
     | 
| 
      
 91 
     | 
    
         
            +
                        const checkbox = document.createElement("input");
         
     | 
| 
      
 92 
     | 
    
         
            +
                        checkbox.setAttribute("type", "checkbox");
         
     | 
| 
      
 93 
     | 
    
         
            +
                        if (doc.completed) {
         
     | 
| 
      
 94 
     | 
    
         
            +
                          checkbox.setAttribute("checked", true);
         
     | 
| 
      
 95 
     | 
    
         
            +
                        }
         
     | 
| 
      
 96 
     | 
    
         
            +
                        checkbox.onchange = async (e) => {
         
     | 
| 
      
 97 
     | 
    
         
            +
                          e.target.indeterminate = true;
         
     | 
| 
      
 98 
     | 
    
         
            +
                          const clicks = doc.clicks || 0;
         
     | 
| 
      
 99 
     | 
    
         
            +
                          doc.clicks = clicks + 1;
         
     | 
| 
      
 100 
     | 
    
         
            +
                          doc.completed = !doc.completed;
         
     | 
| 
      
 101 
     | 
    
         
            +
                          await db.put(doc);
         
     | 
| 
      
 102 
     | 
    
         
            +
                        };
         
     | 
| 
      
 103 
     | 
    
         
            +
                        const textSpan = document.createElement("span");
         
     | 
| 
      
 104 
     | 
    
         
            +
                        textSpan.innerText = `${doc.actor}:${doc.clicks || 0} ${doc.task}`;
         
     | 
| 
      
 105 
     | 
    
         
            +
                        const li = document.createElement("li");
         
     | 
| 
      
 106 
     | 
    
         
            +
                        li.appendChild(checkbox);
         
     | 
| 
      
 107 
     | 
    
         
            +
                        li.appendChild(textSpan);
         
     | 
| 
      
 108 
     | 
    
         
            +
                        document.querySelector("ul").appendChild(li);
         
     | 
| 
      
 109 
     | 
    
         
            +
                      }
         
     | 
| 
      
 110 
     | 
    
         
            +
                    };
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    async function initialize() {
         
     | 
| 
      
 113 
     | 
    
         
            +
                      ps = new URLSearchParams(location.search);
         
     | 
| 
      
 114 
     | 
    
         
            +
                      const listQ = ps.get("list");
         
     | 
| 
      
 115 
     | 
    
         
            +
                      setupDb(listQ || "my-list");
         
     | 
| 
      
 116 
     | 
    
         
            +
                      const input = document.querySelector("#list");
         
     | 
| 
      
 117 
     | 
    
         
            +
                      input.value = dbName;
         
     | 
| 
      
 118 
     | 
    
         
            +
                      redraw();
         
     | 
| 
      
 119 
     | 
    
         
            +
                    }
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                    async function openDashboard(e) {
         
     | 
| 
      
 122 
     | 
    
         
            +
                      db.openDashboard();
         
     | 
| 
      
 123 
     | 
    
         
            +
                    }
         
     | 
| 
      
 124 
     | 
    
         
            +
                    window.openDashboard = openDashboard;
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                    async function changeList(e) {
         
     | 
| 
      
 127 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 128 
     | 
    
         
            +
                      const input = document.querySelector("#list");
         
     | 
| 
      
 129 
     | 
    
         
            +
                      dbName = input.value;
         
     | 
| 
      
 130 
     | 
    
         
            +
                      history.pushState(null, "", location.pathname + "?list=" + encodeURIComponent(dbName));
         
     | 
| 
      
 131 
     | 
    
         
            +
                      setupDb(dbName);
         
     | 
| 
      
 132 
     | 
    
         
            +
                      redraw();
         
     | 
| 
      
 133 
     | 
    
         
            +
                    }
         
     | 
| 
      
 134 
     | 
    
         
            +
                    window.changeList = changeList;
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                    async function createTodoClick(e) {
         
     | 
| 
      
 137 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 138 
     | 
    
         
            +
                      const input = document.querySelector("#todo");
         
     | 
| 
      
 139 
     | 
    
         
            +
                      input.disabled = true;
         
     | 
| 
      
 140 
     | 
    
         
            +
                      const ok = await db.put({
         
     | 
| 
      
 141 
     | 
    
         
            +
                        actor: actorTag,
         
     | 
| 
      
 142 
     | 
    
         
            +
                        created: Date.now(),
         
     | 
| 
      
 143 
     | 
    
         
            +
                        task: input.value,
         
     | 
| 
      
 144 
     | 
    
         
            +
                        completed: false,
         
     | 
| 
      
 145 
     | 
    
         
            +
                      });
         
     | 
| 
      
 146 
     | 
    
         
            +
                      input.disabled = false;
         
     | 
| 
      
 147 
     | 
    
         
            +
                      input.value = "";
         
     | 
| 
      
 148 
     | 
    
         
            +
                    }
         
     | 
| 
      
 149 
     | 
    
         
            +
                    window.createTodoClick = createTodoClick;
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                    let worker;
         
     | 
| 
      
 152 
     | 
    
         
            +
                    async function startWorker() {
         
     | 
| 
      
 153 
     | 
    
         
            +
                      const button = document.querySelector("#robot");
         
     | 
| 
      
 154 
     | 
    
         
            +
                      button.innerText = "🦾";
         
     | 
| 
      
 155 
     | 
    
         
            +
                      const dcs = await db.allDocs();
         
     | 
| 
      
 156 
     | 
    
         
            +
                      console.log("start worker", dcs.rows.length);
         
     | 
| 
      
 157 
     | 
    
         
            +
                      // worker = setInterval(async () => {
         
     | 
| 
      
 158 
     | 
    
         
            +
                      //   dcs.rows.map((r) => db.put({ ...r.value, clicks: (r.value.clicks || 0) + 1, completed: Math.random() > 0.5 }))
         
     | 
| 
      
 159 
     | 
    
         
            +
                      // }, 5000)
         
     | 
| 
      
 160 
     | 
    
         
            +
                      goWorker(dcs);
         
     | 
| 
      
 161 
     | 
    
         
            +
                    }
         
     | 
| 
      
 162 
     | 
    
         
            +
                    const goWorker = (dcs) => {
         
     | 
| 
      
 163 
     | 
    
         
            +
                      const timeout = 10 + db._crdt.clock.head.length * (Math.floor(Math.random() * 2000) + 2000);
         
     | 
| 
      
 164 
     | 
    
         
            +
                      // console.log('go worker', timeout)
         
     | 
| 
      
 165 
     | 
    
         
            +
                      worker = setTimeout(async () => {
         
     | 
| 
      
 166 
     | 
    
         
            +
                        await Promise.all(
         
     | 
| 
      
 167 
     | 
    
         
            +
                          dcs.rows.slice(0, 5).map((r) => {
         
     | 
| 
      
 168 
     | 
    
         
            +
                            r.value.clicks = r.value.clicks || 0;
         
     | 
| 
      
 169 
     | 
    
         
            +
                            r.value.clicks += 1;
         
     | 
| 
      
 170 
     | 
    
         
            +
                            r.value.completed = Math.random() > 0.5;
         
     | 
| 
      
 171 
     | 
    
         
            +
                            db.put({ ...r.value });
         
     | 
| 
      
 172 
     | 
    
         
            +
                          }),
         
     | 
| 
      
 173 
     | 
    
         
            +
                        );
         
     | 
| 
      
 174 
     | 
    
         
            +
                        goWorker(dcs);
         
     | 
| 
      
 175 
     | 
    
         
            +
                      }, timeout);
         
     | 
| 
      
 176 
     | 
    
         
            +
                    };
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                    const stopWorker = () => {
         
     | 
| 
      
 179 
     | 
    
         
            +
                      const button = document.querySelector("#robot");
         
     | 
| 
      
 180 
     | 
    
         
            +
                      button.innerText = "🤖";
         
     | 
| 
      
 181 
     | 
    
         
            +
                      console.log("stop worker");
         
     | 
| 
      
 182 
     | 
    
         
            +
                      clearTimeout(worker);
         
     | 
| 
      
 183 
     | 
    
         
            +
                    };
         
     | 
| 
      
 184 
     | 
    
         
            +
                    const toggleWorker = (e) => {
         
     | 
| 
      
 185 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 186 
     | 
    
         
            +
                      if (worker) {
         
     | 
| 
      
 187 
     | 
    
         
            +
                        stopWorker();
         
     | 
| 
      
 188 
     | 
    
         
            +
                      } else {
         
     | 
| 
      
 189 
     | 
    
         
            +
                        startWorker(e);
         
     | 
| 
      
 190 
     | 
    
         
            +
                      }
         
     | 
| 
      
 191 
     | 
    
         
            +
                    };
         
     | 
| 
      
 192 
     | 
    
         
            +
                    window.toggleWorker = toggleWorker;
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                    async function doCompact(e) {
         
     | 
| 
      
 195 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 196 
     | 
    
         
            +
                      compactor = "🚕";
         
     | 
| 
      
 197 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 198 
     | 
    
         
            +
                      await db.compact();
         
     | 
| 
      
 199 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 200 
     | 
    
         
            +
                      compactor = "🚗";
         
     | 
| 
      
 201 
     | 
    
         
            +
                    }
         
     | 
| 
      
 202 
     | 
    
         
            +
                    window.doCompact = doCompact;
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                    window.onload = initialize;
         
     | 
| 
      
 205 
     | 
    
         
            +
                    window.db = db;
         
     | 
| 
      
 206 
     | 
    
         
            +
                  }
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                  todoApp();
         
     | 
| 
      
 209 
     | 
    
         
            +
                </script>
         
     | 
| 
      
 210 
     | 
    
         
            +
              </head>
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
              <body>
         
     | 
| 
      
 213 
     | 
    
         
            +
                <h1><a href="https://use-fireproof.com/">Fireproof</a> Test App</h1>
         
     | 
| 
      
 214 
     | 
    
         
            +
                Database:
         
     | 
| 
      
 215 
     | 
    
         
            +
                <input title="Change list" type="text" name="list" id="list" />
         
     | 
| 
      
 216 
     | 
    
         
            +
                <button onclick="changeList(event)">Switch</button>
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                <p>
         
     | 
| 
      
 219 
     | 
    
         
            +
                  This version of the Fireprof test app uses AWS S3 as the storage backend. Click the 📡 to refresh the latest data from other
         
     | 
| 
      
 220 
     | 
    
         
            +
                  clients.
         
     | 
| 
      
 221 
     | 
    
         
            +
                </p>
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                <button id="robot" onclick="toggleWorker(event)">🤖</button>
         
     | 
| 
      
 224 
     | 
    
         
            +
                <span id="carLog" onclick="doCompact(event)"></span>
         
     | 
| 
      
 225 
     | 
    
         
            +
                <span id="cxInfo"></span>
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                <h3>Todos</h3>
         
     | 
| 
      
 228 
     | 
    
         
            +
                <input title="Create a todo" type="text" name="todo" id="todo" />
         
     | 
| 
      
 229 
     | 
    
         
            +
                <button onclick="createTodoClick(event)">Create Todo</button>
         
     | 
| 
      
 230 
     | 
    
         
            +
                <ul></ul>
         
     | 
| 
      
 231 
     | 
    
         
            +
              </body>
         
     | 
| 
      
 232 
     | 
    
         
            +
            </html>
         
     | 
| 
         @@ -0,0 +1,213 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <!doctype html>
         
     | 
| 
      
 2 
     | 
    
         
            +
            <html lang="en">
         
     | 
| 
      
 3 
     | 
    
         
            +
              <head>
         
     | 
| 
      
 4 
     | 
    
         
            +
                <meta charset="UTF-8" />
         
     | 
| 
      
 5 
     | 
    
         
            +
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
         
     | 
| 
      
 6 
     | 
    
         
            +
                <title>Fireproof Test</title>
         
     | 
| 
      
 7 
     | 
    
         
            +
                <script src="./fireproof.iife.js?14345"></script>
         
     | 
| 
      
 8 
     | 
    
         
            +
                <script src="./ipfs.iife.js"></script>
         
     | 
| 
      
 9 
     | 
    
         
            +
                <script type="text/javascript">
         
     | 
| 
      
 10 
     | 
    
         
            +
                  function todoApp() {
         
     | 
| 
      
 11 
     | 
    
         
            +
                    const actorTag = Math.random().toString(36).substring(2, 7);
         
     | 
| 
      
 12 
     | 
    
         
            +
                    const { fireproof, index } = Fireproof;
         
     | 
| 
      
 13 
     | 
    
         
            +
                    const { connect } = FireproofConnectUCAN;
         
     | 
| 
      
 14 
     | 
    
         
            +
                    console.log("fireproofconnect", connect);
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    let dbName;
         
     | 
| 
      
 17 
     | 
    
         
            +
                    let db;
         
     | 
| 
      
 18 
     | 
    
         
            +
                    let cx;
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    let dbUnsubscribe = false;
         
     | 
| 
      
 21 
     | 
    
         
            +
                    function setupDb(name, newDb, newConn) {
         
     | 
| 
      
 22 
     | 
    
         
            +
                      const input = document.querySelector("#todo");
         
     | 
| 
      
 23 
     | 
    
         
            +
                      input.disabled = true;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                      if (dbUnsubscribe) {
         
     | 
| 
      
 26 
     | 
    
         
            +
                        dbUnsubscribe();
         
     | 
| 
      
 27 
     | 
    
         
            +
                      }
         
     | 
| 
      
 28 
     | 
    
         
            +
                      if (newDb) {
         
     | 
| 
      
 29 
     | 
    
         
            +
                        // console.log('new db', newDb, newConn)
         
     | 
| 
      
 30 
     | 
    
         
            +
                        name = newDb.name;
         
     | 
| 
      
 31 
     | 
    
         
            +
                        dbName = newDb.name;
         
     | 
| 
      
 32 
     | 
    
         
            +
                        db = newDb;
         
     | 
| 
      
 33 
     | 
    
         
            +
                        cx = newConn;
         
     | 
| 
      
 34 
     | 
    
         
            +
                        const input = document.querySelector("#list");
         
     | 
| 
      
 35 
     | 
    
         
            +
                        input.value = dbName;
         
     | 
| 
      
 36 
     | 
    
         
            +
                      } else {
         
     | 
| 
      
 37 
     | 
    
         
            +
                        dbName = name;
         
     | 
| 
      
 38 
     | 
    
         
            +
                        db = fireproof(name);
         
     | 
| 
      
 39 
     | 
    
         
            +
                        cx = connect.ipfs(db, "todo-test");
         
     | 
| 
      
 40 
     | 
    
         
            +
                      }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                      window.db = db;
         
     | 
| 
      
 43 
     | 
    
         
            +
                      window.cx = cx;
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                      cx.ready.then(async () => {
         
     | 
| 
      
 46 
     | 
    
         
            +
                        input.disabled = false;
         
     | 
| 
      
 47 
     | 
    
         
            +
                        console.log("ready", cx.authorized, cx);
         
     | 
| 
      
 48 
     | 
    
         
            +
                        if (cx.authorized) {
         
     | 
| 
      
 49 
     | 
    
         
            +
                          document.querySelector("#login").hidden = true;
         
     | 
| 
      
 50 
     | 
    
         
            +
                          document.querySelector("#authorized").hidden = false;
         
     | 
| 
      
 51 
     | 
    
         
            +
                          // console.log('authorized', await cx.shareToken())
         
     | 
| 
      
 52 
     | 
    
         
            +
                          // document.querySelector('#agent').innerText = await cx.shareToken()
         
     | 
| 
      
 53 
     | 
    
         
            +
                          document.querySelector("#account-email").innerText = await cx.accountEmail();
         
     | 
| 
      
 54 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 55 
     | 
    
         
            +
                          input.disabled = false;
         
     | 
| 
      
 56 
     | 
    
         
            +
                          document.querySelector("#login").hidden = false;
         
     | 
| 
      
 57 
     | 
    
         
            +
                          document.querySelector("#authorized").hidden = true;
         
     | 
| 
      
 58 
     | 
    
         
            +
                        }
         
     | 
| 
      
 59 
     | 
    
         
            +
                      });
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                      dbUnsubscribe = db.subscribe(redraw);
         
     | 
| 
      
 62 
     | 
    
         
            +
                      return db;
         
     | 
| 
      
 63 
     | 
    
         
            +
                    }
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    let doing;
         
     | 
| 
      
 66 
     | 
    
         
            +
                    const redraw = async () => {
         
     | 
| 
      
 67 
     | 
    
         
            +
                      if (doing) {
         
     | 
| 
      
 68 
     | 
    
         
            +
                        return doing;
         
     | 
| 
      
 69 
     | 
    
         
            +
                      }
         
     | 
| 
      
 70 
     | 
    
         
            +
                      doing = doRedraw().finally(() => (doing = null));
         
     | 
| 
      
 71 
     | 
    
         
            +
                      return doing;
         
     | 
| 
      
 72 
     | 
    
         
            +
                    };
         
     | 
| 
      
 73 
     | 
    
         
            +
                    window.redraw = redraw;
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    const doRedraw = async () => {
         
     | 
| 
      
 76 
     | 
    
         
            +
                      const result = await db.query("created", { includeDocs: true });
         
     | 
| 
      
 77 
     | 
    
         
            +
                      document.querySelector("ul").innerHTML = "";
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      for (const row of result.rows) {
         
     | 
| 
      
 80 
     | 
    
         
            +
                        // const doc = await db.get(row.id);
         
     | 
| 
      
 81 
     | 
    
         
            +
                        const doc = row.doc;
         
     | 
| 
      
 82 
     | 
    
         
            +
                        const checkbox = document.createElement("input");
         
     | 
| 
      
 83 
     | 
    
         
            +
                        checkbox.setAttribute("type", "checkbox");
         
     | 
| 
      
 84 
     | 
    
         
            +
                        if (doc.completed) {
         
     | 
| 
      
 85 
     | 
    
         
            +
                          checkbox.setAttribute("checked", true);
         
     | 
| 
      
 86 
     | 
    
         
            +
                        }
         
     | 
| 
      
 87 
     | 
    
         
            +
                        checkbox.onchange = async (e) => {
         
     | 
| 
      
 88 
     | 
    
         
            +
                          e.target.indeterminate = true;
         
     | 
| 
      
 89 
     | 
    
         
            +
                          doc.completed = !doc.completed;
         
     | 
| 
      
 90 
     | 
    
         
            +
                          await db.put(doc);
         
     | 
| 
      
 91 
     | 
    
         
            +
                        };
         
     | 
| 
      
 92 
     | 
    
         
            +
                        const textSpan = document.createElement("span");
         
     | 
| 
      
 93 
     | 
    
         
            +
                        textSpan.innerText = doc.actor + ": " + doc.task;
         
     | 
| 
      
 94 
     | 
    
         
            +
                        const li = document.createElement("li");
         
     | 
| 
      
 95 
     | 
    
         
            +
                        li.appendChild(checkbox);
         
     | 
| 
      
 96 
     | 
    
         
            +
                        li.appendChild(textSpan);
         
     | 
| 
      
 97 
     | 
    
         
            +
                        document.querySelector("ul").appendChild(li);
         
     | 
| 
      
 98 
     | 
    
         
            +
                      }
         
     | 
| 
      
 99 
     | 
    
         
            +
                    };
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                    async function initialize() {
         
     | 
| 
      
 102 
     | 
    
         
            +
                      ps = new URLSearchParams(location.search);
         
     | 
| 
      
 103 
     | 
    
         
            +
                      const listQ = ps.get("list");
         
     | 
| 
      
 104 
     | 
    
         
            +
                      setupDb(listQ || "my-list");
         
     | 
| 
      
 105 
     | 
    
         
            +
                      const input = document.querySelector("#list");
         
     | 
| 
      
 106 
     | 
    
         
            +
                      input.value = dbName;
         
     | 
| 
      
 107 
     | 
    
         
            +
                      redraw();
         
     | 
| 
      
 108 
     | 
    
         
            +
                    }
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                    async function openDashboard(e) {
         
     | 
| 
      
 111 
     | 
    
         
            +
                      db.openDashboard();
         
     | 
| 
      
 112 
     | 
    
         
            +
                    }
         
     | 
| 
      
 113 
     | 
    
         
            +
                    window.openDashboard = openDashboard;
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                    async function verifyEmail(e) {
         
     | 
| 
      
 116 
     | 
    
         
            +
                      const input = document.querySelector("#email");
         
     | 
| 
      
 117 
     | 
    
         
            +
                      input.disabled = true;
         
     | 
| 
      
 118 
     | 
    
         
            +
                      const val = input.value;
         
     | 
| 
      
 119 
     | 
    
         
            +
                      const area = document.querySelector("#login");
         
     | 
| 
      
 120 
     | 
    
         
            +
                      area.innerHTML = "Sending verification email to " + val + "...";
         
     | 
| 
      
 121 
     | 
    
         
            +
                      await cx.authorize(input.value);
         
     | 
| 
      
 122 
     | 
    
         
            +
                      // setTimeout(() => {
         
     | 
| 
      
 123 
     | 
    
         
            +
                      //   setupDb(dbName);
         
     | 
| 
      
 124 
     | 
    
         
            +
                      // }, 1100)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    }
         
     | 
| 
      
 126 
     | 
    
         
            +
                    window.verifyEmail = verifyEmail;
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                    async function changeList(e) {
         
     | 
| 
      
 129 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 130 
     | 
    
         
            +
                      const input = document.querySelector("#list");
         
     | 
| 
      
 131 
     | 
    
         
            +
                      dbName = input.value;
         
     | 
| 
      
 132 
     | 
    
         
            +
                      history.pushState(null, "", location.pathname + "?list=" + encodeURIComponent(dbName));
         
     | 
| 
      
 133 
     | 
    
         
            +
                      setupDb(dbName);
         
     | 
| 
      
 134 
     | 
    
         
            +
                      redraw();
         
     | 
| 
      
 135 
     | 
    
         
            +
                    }
         
     | 
| 
      
 136 
     | 
    
         
            +
                    window.changeList = changeList;
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                    async function createTodoClick(e) {
         
     | 
| 
      
 139 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                      const input = document.querySelector("#todo");
         
     | 
| 
      
 142 
     | 
    
         
            +
                      const ok = await db.put({ actor: actorTag, created: Date.now(), task: input.value, completed: false });
         
     | 
| 
      
 143 
     | 
    
         
            +
                      input.value = "";
         
     | 
| 
      
 144 
     | 
    
         
            +
                    }
         
     | 
| 
      
 145 
     | 
    
         
            +
                    window.createTodoClick = createTodoClick;
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                    window.doShareWith = async (e) => {
         
     | 
| 
      
 148 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 149 
     | 
    
         
            +
                      e.target.disabled = true;
         
     | 
| 
      
 150 
     | 
    
         
            +
                      const input = document.querySelector("#share");
         
     | 
| 
      
 151 
     | 
    
         
            +
                      const did = await cx.shareWith(input.value);
         
     | 
| 
      
 152 
     | 
    
         
            +
                      document.querySelector("#share-code").innerText = did;
         
     | 
| 
      
 153 
     | 
    
         
            +
                    };
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                    window.doJoin = async (e) => {
         
     | 
| 
      
 156 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 157 
     | 
    
         
            +
                      e.target.disabled = true;
         
     | 
| 
      
 158 
     | 
    
         
            +
                      const input = document.querySelector("#join");
         
     | 
| 
      
 159 
     | 
    
         
            +
                      const { database: newDb, connection: newConn } = await cx.joinShared(input.value);
         
     | 
| 
      
 160 
     | 
    
         
            +
                      setupDb(null, newDb, newConn);
         
     | 
| 
      
 161 
     | 
    
         
            +
                    };
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                    window.onload = initialize;
         
     | 
| 
      
 164 
     | 
    
         
            +
                    window.db = db;
         
     | 
| 
      
 165 
     | 
    
         
            +
                  }
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  todoApp();
         
     | 
| 
      
 168 
     | 
    
         
            +
                </script>
         
     | 
| 
      
 169 
     | 
    
         
            +
              </head>
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
              <body>
         
     | 
| 
      
 172 
     | 
    
         
            +
                <h1>Fireproof Todos</h1>
         
     | 
| 
      
 173 
     | 
    
         
            +
                List:
         
     | 
| 
      
 174 
     | 
    
         
            +
                <input type="text" name="list" id="list" />
         
     | 
| 
      
 175 
     | 
    
         
            +
                <button onclick="changeList(event)">Change List</button>
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                <div id="login">
         
     | 
| 
      
 178 
     | 
    
         
            +
                  <p>Work locally or verify your email address to sync.</p>
         
     | 
| 
      
 179 
     | 
    
         
            +
                  Email: <input title="email" placeholder="name@example.com" name="email" id="email" />
         
     | 
| 
      
 180 
     | 
    
         
            +
                  <button onclick="verifyEmail(event)">Verify email</button>
         
     | 
| 
      
 181 
     | 
    
         
            +
                </div>
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                <p>
         
     | 
| 
      
 184 
     | 
    
         
            +
                  Fireproof stores data locally and encrypts it before sending it to the cloud. This demo uses web3.storage, but you can easily
         
     | 
| 
      
 185 
     | 
    
         
            +
                  run Fireproof on S3 or another provider.
         
     | 
| 
      
 186 
     | 
    
         
            +
                  <a href="https://use-fireproof.com/">Learn more in the Fireproof developer docs.</a>
         
     | 
| 
      
 187 
     | 
    
         
            +
                </p>
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                <div id="authorized" hidden>
         
     | 
| 
      
 190 
     | 
    
         
            +
                  <p>Logged in as <span id="account-email">loading...</span></p>
         
     | 
| 
      
 191 
     | 
    
         
            +
                  <button onclick="openDashboard(event)">🔥 Import to Dashboard</button>
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                  <p>
         
     | 
| 
      
 194 
     | 
    
         
            +
                    Share this list to someone's share id: <input title="share" placeholder="did:key:..." name="share" id="share" />
         
     | 
| 
      
 195 
     | 
    
         
            +
                    <button onclick="doShareWith(event)">Share</button>
         
     | 
| 
      
 196 
     | 
    
         
            +
                    <code id="share-code"></code>
         
     | 
| 
      
 197 
     | 
    
         
            +
                  </p>
         
     | 
| 
      
 198 
     | 
    
         
            +
                  <p>
         
     | 
| 
      
 199 
     | 
    
         
            +
                    Join a shared list: <input title="join" placeholder="bafy..." name="join" id="join" />
         
     | 
| 
      
 200 
     | 
    
         
            +
                    <button onclick="doJoin(event)">Join</button>
         
     | 
| 
      
 201 
     | 
    
         
            +
                  </p>
         
     | 
| 
      
 202 
     | 
    
         
            +
                  <p>
         
     | 
| 
      
 203 
     | 
    
         
            +
                    Request access to other lists by sharing your share id:<br />
         
     | 
| 
      
 204 
     | 
    
         
            +
                    <code id="agent"></code>
         
     | 
| 
      
 205 
     | 
    
         
            +
                  </p>
         
     | 
| 
      
 206 
     | 
    
         
            +
                </div>
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                <h3>Todos</h3>
         
     | 
| 
      
 209 
     | 
    
         
            +
                <input title="Create a todo" type="text" name="todo" id="todo" />
         
     | 
| 
      
 210 
     | 
    
         
            +
                <button onclick="createTodoClick(event)">Create Todo</button>
         
     | 
| 
      
 211 
     | 
    
         
            +
                <ul></ul>
         
     | 
| 
      
 212 
     | 
    
         
            +
              </body>
         
     | 
| 
      
 213 
     | 
    
         
            +
            </html>
         
     | 
| 
         @@ -0,0 +1,214 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <!doctype html>
         
     | 
| 
      
 2 
     | 
    
         
            +
            <html lang="en">
         
     | 
| 
      
 3 
     | 
    
         
            +
              <head>
         
     | 
| 
      
 4 
     | 
    
         
            +
                <meta charset="UTF-8" />
         
     | 
| 
      
 5 
     | 
    
         
            +
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
         
     | 
| 
      
 6 
     | 
    
         
            +
                <title>Fireproof Test</title>
         
     | 
| 
      
 7 
     | 
    
         
            +
                <script src="./fireproof.iife.js"></script>
         
     | 
| 
      
 8 
     | 
    
         
            +
                <script type="text/javascript">
         
     | 
| 
      
 9 
     | 
    
         
            +
                  function todoApp() {
         
     | 
| 
      
 10 
     | 
    
         
            +
                    const actorTag = Math.random().toString(36).substring(2, 7);
         
     | 
| 
      
 11 
     | 
    
         
            +
                    const { fireproof, index } = Fireproof;
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    // console.log('connect', connect)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    let dbName;
         
     | 
| 
      
 16 
     | 
    
         
            +
                    let db;
         
     | 
| 
      
 17 
     | 
    
         
            +
                    let cx;
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    let dbUnsubscribe = false;
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    function setupDb(name, newDb) {
         
     | 
| 
      
 22 
     | 
    
         
            +
                      const input = document.querySelector("#todo");
         
     | 
| 
      
 23 
     | 
    
         
            +
                      input.disabled = true;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                      if (dbUnsubscribe) {
         
     | 
| 
      
 26 
     | 
    
         
            +
                        dbUnsubscribe();
         
     | 
| 
      
 27 
     | 
    
         
            +
                      }
         
     | 
| 
      
 28 
     | 
    
         
            +
                      if (newDb) {
         
     | 
| 
      
 29 
     | 
    
         
            +
                        // console.log('new db', newDb, newConn)
         
     | 
| 
      
 30 
     | 
    
         
            +
                        name = newDb.name;
         
     | 
| 
      
 31 
     | 
    
         
            +
                        dbName = newDb.name;
         
     | 
| 
      
 32 
     | 
    
         
            +
                        db = newDb;
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                        const input = document.querySelector("#list");
         
     | 
| 
      
 35 
     | 
    
         
            +
                        input.value = dbName;
         
     | 
| 
      
 36 
     | 
    
         
            +
                      } else {
         
     | 
| 
      
 37 
     | 
    
         
            +
                        dbName = name;
         
     | 
| 
      
 38 
     | 
    
         
            +
                        db = fireproof(name, { autoCompact: 100 });
         
     | 
| 
      
 39 
     | 
    
         
            +
                      }
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                      window.db = db;
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                      db.changes([], { limit: 1 }).then((changes) => {
         
     | 
| 
      
 44 
     | 
    
         
            +
                        input.disabled = false;
         
     | 
| 
      
 45 
     | 
    
         
            +
                      });
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                      dbUnsubscribe = db.subscribe(redraw);
         
     | 
| 
      
 48 
     | 
    
         
            +
                      return db;
         
     | 
| 
      
 49 
     | 
    
         
            +
                    }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    let doing;
         
     | 
| 
      
 52 
     | 
    
         
            +
                    const redraw = async () => {
         
     | 
| 
      
 53 
     | 
    
         
            +
                      if (doing) {
         
     | 
| 
      
 54 
     | 
    
         
            +
                        return doing;
         
     | 
| 
      
 55 
     | 
    
         
            +
                      }
         
     | 
| 
      
 56 
     | 
    
         
            +
                      doing = doRedraw().finally(() => (doing = null));
         
     | 
| 
      
 57 
     | 
    
         
            +
                      return doing;
         
     | 
| 
      
 58 
     | 
    
         
            +
                    };
         
     | 
| 
      
 59 
     | 
    
         
            +
                    window.redraw = redraw;
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                    let compactor = "🚗";
         
     | 
| 
      
 62 
     | 
    
         
            +
                    function drawInfo() {
         
     | 
| 
      
 63 
     | 
    
         
            +
                      document.querySelector("#carLog").innerText = ` ⏰ ${db._crdt.clock.head.length} ${compactor}`;
         
     | 
| 
      
 64 
     | 
    
         
            +
                    }
         
     | 
| 
      
 65 
     | 
    
         
            +
                    const doRedraw = async () => {
         
     | 
| 
      
 66 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 67 
     | 
    
         
            +
                      const result = await db.allDocs().catch((e) => {
         
     | 
| 
      
 68 
     | 
    
         
            +
                        console.error("allDocs error", e, ` ⏰ ${db._crdt.clock.head.length} ${compactor}`);
         
     | 
| 
      
 69 
     | 
    
         
            +
                        return { rows: [] };
         
     | 
| 
      
 70 
     | 
    
         
            +
                      });
         
     | 
| 
      
 71 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 72 
     | 
    
         
            +
                      document.querySelector("ul").innerHTML = "";
         
     | 
| 
      
 73 
     | 
    
         
            +
                      for (const row of result.rows) {
         
     | 
| 
      
 74 
     | 
    
         
            +
                        // const doc = await db.get(row.id);
         
     | 
| 
      
 75 
     | 
    
         
            +
                        const doc = row.value;
         
     | 
| 
      
 76 
     | 
    
         
            +
                        const checkbox = document.createElement("input");
         
     | 
| 
      
 77 
     | 
    
         
            +
                        checkbox.setAttribute("type", "checkbox");
         
     | 
| 
      
 78 
     | 
    
         
            +
                        if (doc.completed) {
         
     | 
| 
      
 79 
     | 
    
         
            +
                          checkbox.setAttribute("checked", true);
         
     | 
| 
      
 80 
     | 
    
         
            +
                        }
         
     | 
| 
      
 81 
     | 
    
         
            +
                        checkbox.onchange = async (e) => {
         
     | 
| 
      
 82 
     | 
    
         
            +
                          e.target.indeterminate = true;
         
     | 
| 
      
 83 
     | 
    
         
            +
                          const clicks = doc.clicks || 0;
         
     | 
| 
      
 84 
     | 
    
         
            +
                          doc.clicks = clicks + 1;
         
     | 
| 
      
 85 
     | 
    
         
            +
                          doc.completed = !doc.completed;
         
     | 
| 
      
 86 
     | 
    
         
            +
                          await db.put(doc);
         
     | 
| 
      
 87 
     | 
    
         
            +
                        };
         
     | 
| 
      
 88 
     | 
    
         
            +
                        const textSpan = document.createElement("span");
         
     | 
| 
      
 89 
     | 
    
         
            +
                        textSpan.innerText = `${doc.actor}:${doc.clicks || 0} ${doc.task}`;
         
     | 
| 
      
 90 
     | 
    
         
            +
                        const li = document.createElement("li");
         
     | 
| 
      
 91 
     | 
    
         
            +
                        li.appendChild(checkbox);
         
     | 
| 
      
 92 
     | 
    
         
            +
                        li.appendChild(textSpan);
         
     | 
| 
      
 93 
     | 
    
         
            +
                        document.querySelector("ul").appendChild(li);
         
     | 
| 
      
 94 
     | 
    
         
            +
                      }
         
     | 
| 
      
 95 
     | 
    
         
            +
                    };
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    async function initialize() {
         
     | 
| 
      
 98 
     | 
    
         
            +
                      ps = new URLSearchParams(location.search);
         
     | 
| 
      
 99 
     | 
    
         
            +
                      const listQ = ps.get("list");
         
     | 
| 
      
 100 
     | 
    
         
            +
                      setupDb(listQ || "my-list");
         
     | 
| 
      
 101 
     | 
    
         
            +
                      const input = document.querySelector("#list");
         
     | 
| 
      
 102 
     | 
    
         
            +
                      input.value = dbName;
         
     | 
| 
      
 103 
     | 
    
         
            +
                      redraw();
         
     | 
| 
      
 104 
     | 
    
         
            +
                    }
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                    async function openDashboard(e) {
         
     | 
| 
      
 107 
     | 
    
         
            +
                      db.openDashboard();
         
     | 
| 
      
 108 
     | 
    
         
            +
                    }
         
     | 
| 
      
 109 
     | 
    
         
            +
                    window.openDashboard = openDashboard;
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                    async function changeList(e) {
         
     | 
| 
      
 112 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 113 
     | 
    
         
            +
                      const input = document.querySelector("#list");
         
     | 
| 
      
 114 
     | 
    
         
            +
                      dbName = input.value;
         
     | 
| 
      
 115 
     | 
    
         
            +
                      history.pushState(null, "", location.pathname + "?list=" + encodeURIComponent(dbName));
         
     | 
| 
      
 116 
     | 
    
         
            +
                      setupDb(dbName);
         
     | 
| 
      
 117 
     | 
    
         
            +
                      redraw();
         
     | 
| 
      
 118 
     | 
    
         
            +
                    }
         
     | 
| 
      
 119 
     | 
    
         
            +
                    window.changeList = changeList;
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                    async function createTodoClick(e) {
         
     | 
| 
      
 122 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 123 
     | 
    
         
            +
                      const input = document.querySelector("#todo");
         
     | 
| 
      
 124 
     | 
    
         
            +
                      input.disabled = true;
         
     | 
| 
      
 125 
     | 
    
         
            +
                      const ok = await db.put({
         
     | 
| 
      
 126 
     | 
    
         
            +
                        actor: actorTag,
         
     | 
| 
      
 127 
     | 
    
         
            +
                        created: Date.now(),
         
     | 
| 
      
 128 
     | 
    
         
            +
                        task: input.value,
         
     | 
| 
      
 129 
     | 
    
         
            +
                        completed: false,
         
     | 
| 
      
 130 
     | 
    
         
            +
                      });
         
     | 
| 
      
 131 
     | 
    
         
            +
                      input.disabled = false;
         
     | 
| 
      
 132 
     | 
    
         
            +
                      input.value = "";
         
     | 
| 
      
 133 
     | 
    
         
            +
                    }
         
     | 
| 
      
 134 
     | 
    
         
            +
                    window.createTodoClick = createTodoClick;
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                    let worker;
         
     | 
| 
      
 137 
     | 
    
         
            +
                    async function startWorker() {
         
     | 
| 
      
 138 
     | 
    
         
            +
                      const button = document.querySelector("#robot");
         
     | 
| 
      
 139 
     | 
    
         
            +
                      button.innerText = "🦾";
         
     | 
| 
      
 140 
     | 
    
         
            +
                      const dcs = await db.allDocs();
         
     | 
| 
      
 141 
     | 
    
         
            +
                      console.log("start worker", dcs.rows.length);
         
     | 
| 
      
 142 
     | 
    
         
            +
                      // worker = setInterval(async () => {
         
     | 
| 
      
 143 
     | 
    
         
            +
                      //   dcs.rows.map((r) => db.put({ ...r.value, clicks: (r.value.clicks || 0) + 1, completed: Math.random() > 0.5 }))
         
     | 
| 
      
 144 
     | 
    
         
            +
                      // }, 5000)
         
     | 
| 
      
 145 
     | 
    
         
            +
                      goWorker(dcs);
         
     | 
| 
      
 146 
     | 
    
         
            +
                    }
         
     | 
| 
      
 147 
     | 
    
         
            +
                    const goWorker = (dcs) => {
         
     | 
| 
      
 148 
     | 
    
         
            +
                      const timeout = 10 + Math.pow(db._crdt.clock.head.length, 2) * (Math.floor(Math.random() * 50) + 50);
         
     | 
| 
      
 149 
     | 
    
         
            +
                      console.log("go worker", timeout / 1000);
         
     | 
| 
      
 150 
     | 
    
         
            +
                      worker = setTimeout(async () => {
         
     | 
| 
      
 151 
     | 
    
         
            +
                        await Promise.all(
         
     | 
| 
      
 152 
     | 
    
         
            +
                          dcs.rows.slice(0, 5).map((r) => {
         
     | 
| 
      
 153 
     | 
    
         
            +
                            r.value.clicks = r.value.clicks || 0;
         
     | 
| 
      
 154 
     | 
    
         
            +
                            r.value.clicks += 1;
         
     | 
| 
      
 155 
     | 
    
         
            +
                            r.value.completed = Math.random() > 0.5;
         
     | 
| 
      
 156 
     | 
    
         
            +
                            db.put({ ...r.value });
         
     | 
| 
      
 157 
     | 
    
         
            +
                          }),
         
     | 
| 
      
 158 
     | 
    
         
            +
                        );
         
     | 
| 
      
 159 
     | 
    
         
            +
                        goWorker(dcs);
         
     | 
| 
      
 160 
     | 
    
         
            +
                      }, timeout);
         
     | 
| 
      
 161 
     | 
    
         
            +
                    };
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                    const stopWorker = () => {
         
     | 
| 
      
 164 
     | 
    
         
            +
                      const button = document.querySelector("#robot");
         
     | 
| 
      
 165 
     | 
    
         
            +
                      button.innerText = "🤖";
         
     | 
| 
      
 166 
     | 
    
         
            +
                      console.log("stop worker");
         
     | 
| 
      
 167 
     | 
    
         
            +
                      clearTimeout(worker);
         
     | 
| 
      
 168 
     | 
    
         
            +
                    };
         
     | 
| 
      
 169 
     | 
    
         
            +
                    const toggleWorker = (e) => {
         
     | 
| 
      
 170 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 171 
     | 
    
         
            +
                      if (worker) {
         
     | 
| 
      
 172 
     | 
    
         
            +
                        stopWorker();
         
     | 
| 
      
 173 
     | 
    
         
            +
                      } else {
         
     | 
| 
      
 174 
     | 
    
         
            +
                        startWorker(e);
         
     | 
| 
      
 175 
     | 
    
         
            +
                      }
         
     | 
| 
      
 176 
     | 
    
         
            +
                    };
         
     | 
| 
      
 177 
     | 
    
         
            +
                    window.toggleWorker = toggleWorker;
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                    async function doCompact(e) {
         
     | 
| 
      
 180 
     | 
    
         
            +
                      e.preventDefault();
         
     | 
| 
      
 181 
     | 
    
         
            +
                      compactor = "🚕";
         
     | 
| 
      
 182 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 183 
     | 
    
         
            +
                      await db.compact();
         
     | 
| 
      
 184 
     | 
    
         
            +
                      drawInfo();
         
     | 
| 
      
 185 
     | 
    
         
            +
                      compactor = "🚗";
         
     | 
| 
      
 186 
     | 
    
         
            +
                    }
         
     | 
| 
      
 187 
     | 
    
         
            +
                    window.doCompact = doCompact;
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                    window.onload = initialize;
         
     | 
| 
      
 190 
     | 
    
         
            +
                    window.db = db;
         
     | 
| 
      
 191 
     | 
    
         
            +
                  }
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                  todoApp();
         
     | 
| 
      
 194 
     | 
    
         
            +
                </script>
         
     | 
| 
      
 195 
     | 
    
         
            +
              </head>
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
              <body>
         
     | 
| 
      
 198 
     | 
    
         
            +
                <h1><a href="https://use-fireproof.com/">Fireproof</a> Test App</h1>
         
     | 
| 
      
 199 
     | 
    
         
            +
                Database:
         
     | 
| 
      
 200 
     | 
    
         
            +
                <input title="Change list" type="text" name="list" id="list" />
         
     | 
| 
      
 201 
     | 
    
         
            +
                <button onclick="changeList(event)">Switch</button>
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                <p>This version of the Fireprof test app uses PartyKit as the storage backend. Refresh is automatic and live.</p>
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                <button id="robot" onclick="toggleWorker(event)">🤖</button>
         
     | 
| 
      
 206 
     | 
    
         
            +
                <span id="carLog" onclick="doCompact(event)"></span>
         
     | 
| 
      
 207 
     | 
    
         
            +
                <span id="cxInfo"></span>
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                <h3>Todos</h3>
         
     | 
| 
      
 210 
     | 
    
         
            +
                <input title="Create a todo" type="text" name="todo" id="todo" />
         
     | 
| 
      
 211 
     | 
    
         
            +
                <button onclick="createTodoClick(event)">Create Todo</button>
         
     | 
| 
      
 212 
     | 
    
         
            +
                <ul></ul>
         
     | 
| 
      
 213 
     | 
    
         
            +
              </body>
         
     | 
| 
      
 214 
     | 
    
         
            +
            </html>
         
     |