@fireproof/core 0.18.0 → 0.19.0-dev-use-fix

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. package/README.md +29 -15
  2. package/chunk-AZVWSRER.js +208 -0
  3. package/chunk-AZVWSRER.js.map +1 -0
  4. package/chunk-H3A2HMMM.js +164 -0
  5. package/chunk-H3A2HMMM.js.map +1 -0
  6. package/chunk-NZNG6TQT.js +370 -0
  7. package/chunk-NZNG6TQT.js.map +1 -0
  8. package/chunk-VZGT7ZYP.js +22 -0
  9. package/chunk-VZGT7ZYP.js.map +1 -0
  10. package/chunk-ZHO4NMWL.js +39 -0
  11. package/chunk-ZHO4NMWL.js.map +1 -0
  12. package/index.cjs +4706 -0
  13. package/index.cjs.map +1 -0
  14. package/index.d.cts +1012 -0
  15. package/index.d.ts +1012 -0
  16. package/index.js +2856 -0
  17. package/index.js.map +1 -0
  18. package/metafile-cjs.json +1 -0
  19. package/metafile-esm.json +1 -0
  20. package/node-sys-container-E7LADX2Z.js +29 -0
  21. package/node-sys-container-E7LADX2Z.js.map +1 -0
  22. package/package.json +23 -109
  23. package/sqlite-data-store-3ST7XOLX.js +120 -0
  24. package/sqlite-data-store-3ST7XOLX.js.map +1 -0
  25. package/sqlite-meta-store-QOIMCSJ7.js +137 -0
  26. package/sqlite-meta-store-QOIMCSJ7.js.map +1 -0
  27. package/sqlite-wal-store-JFBQPOYT.js +123 -0
  28. package/sqlite-wal-store-JFBQPOYT.js.map +1 -0
  29. package/store-file-CSS5THFH.js +193 -0
  30. package/store-file-CSS5THFH.js.map +1 -0
  31. package/store-indexdb-DR4HELVP.js +20 -0
  32. package/store-indexdb-DR4HELVP.js.map +1 -0
  33. package/store-sql-BG6SMGQJ.js +344 -0
  34. package/store-sql-BG6SMGQJ.js.map +1 -0
  35. package/tests/blockstore/loader.test.ts +265 -0
  36. package/tests/blockstore/store.test.ts +164 -0
  37. package/tests/blockstore/transaction.test.ts +121 -0
  38. package/tests/fireproof/config.test.ts +212 -0
  39. package/tests/fireproof/crdt.test.ts +434 -0
  40. package/tests/fireproof/database.test.ts +466 -0
  41. package/tests/fireproof/fireproof.test.ts +602 -0
  42. package/tests/fireproof/hello.test.ts +54 -0
  43. package/tests/fireproof/indexer.test.ts +389 -0
  44. package/tests/helpers.ts +81 -0
  45. package/tests/react/useFireproof.test.tsx +19 -0
  46. package/tests/www/gallery.html +132 -0
  47. package/tests/www/iife.html +42 -0
  48. package/tests/www/todo-aws.html +232 -0
  49. package/tests/www/todo-ipfs.html +213 -0
  50. package/tests/www/todo-local.html +214 -0
  51. package/tests/www/todo-netlify.html +227 -0
  52. package/tests/www/todo.html +236 -0
  53. package/dist/browser/fireproof.cjs +0 -1172
  54. package/dist/browser/fireproof.cjs.map +0 -1
  55. package/dist/browser/fireproof.d.cts +0 -268
  56. package/dist/browser/fireproof.d.ts +0 -268
  57. package/dist/browser/fireproof.global.js +0 -24178
  58. package/dist/browser/fireproof.global.js.map +0 -1
  59. package/dist/browser/fireproof.js +0 -1147
  60. package/dist/browser/fireproof.js.map +0 -1
  61. package/dist/browser/metafile-cjs.json +0 -1
  62. package/dist/browser/metafile-esm.json +0 -1
  63. package/dist/browser/metafile-iife.json +0 -1
  64. package/dist/memory/fireproof.cjs +0 -1172
  65. package/dist/memory/fireproof.cjs.map +0 -1
  66. package/dist/memory/fireproof.d.cts +0 -268
  67. package/dist/memory/fireproof.d.ts +0 -268
  68. package/dist/memory/fireproof.global.js +0 -24178
  69. package/dist/memory/fireproof.global.js.map +0 -1
  70. package/dist/memory/fireproof.js +0 -1147
  71. package/dist/memory/fireproof.js.map +0 -1
  72. package/dist/memory/metafile-cjs.json +0 -1
  73. package/dist/memory/metafile-esm.json +0 -1
  74. package/dist/memory/metafile-iife.json +0 -1
  75. package/dist/node/fireproof.cjs +0 -1172
  76. package/dist/node/fireproof.cjs.map +0 -1
  77. package/dist/node/fireproof.d.cts +0 -268
  78. package/dist/node/fireproof.d.ts +0 -268
  79. package/dist/node/fireproof.global.js +0 -38540
  80. package/dist/node/fireproof.global.js.map +0 -1
  81. package/dist/node/fireproof.js +0 -1138
  82. package/dist/node/fireproof.js.map +0 -1
  83. package/dist/node/metafile-cjs.json +0 -1
  84. package/dist/node/metafile-esm.json +0 -1
  85. package/dist/node/metafile-iife.json +0 -1
@@ -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>