| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-05-01 00:44:30 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-05-01 00:44:30 UTC |
| parent | 6ccd2385782a0c5937d5d5d2a347340f68b4bac6 |
| borogove/persistence/IDB.js | +3 | -5 |
| borogove/persistence/Sqlite.hx | +1 | -1 |
| test/idb.spec.ts | +56 | -0 |
| test/sqlite.spec.ts | +9 | -25 |
diff --git a/borogove/persistence/IDB.js b/borogove/persistence/IDB.js index 10b874c..1117836 100644 --- a/borogove/persistence/IDB.js +++ b/borogove/persistence/IDB.js @@ -586,7 +586,7 @@ export default async (dbname, media, tokenize, stemmer) => { return await hydrateMessage(message); }, - storeMessages(account, messages) { + async storeMessages(account, messages) { return Promise.all(messages.map(m => new Promise(resolve => this.storeMessage(account, m, resolve)) )); @@ -605,7 +605,7 @@ export default async (dbname, media, tokenize, stemmer) => { this.getMessage(account, message.chatId(), message.replyToMessage.serverId, message.replyToMessage.localId) : Promise.resolve(message.replyToMessage) ).then((replyToMessage) => { - message.replyToMessage = replyToMessage; + message.replyToMessage = replyToMessage ?? message.replyToMessage; const tx = db.transaction(["messages", "reactions"], "readwrite"); const store = tx.objectStore("messages"); return Promise.all([ @@ -647,9 +647,7 @@ export default async (dbname, media, tokenize, stemmer) => { event.target.result.continue(); } else { message.reactions = reactions; - const req = store.put(serializeMessage(account, message)); - req.onerror = () => { window.mylog.push("MSG STORE ERROR: " + req.error.name + " " + req.error.message); } - callback(message); + promisifyRequest(store.put(serializeMessage(account, message))).then(() => callback(message)); } }; cursor.onerror = console.error; diff --git a/borogove/persistence/Sqlite.hx b/borogove/persistence/Sqlite.hx index f8831dd..e6168de 100644 --- a/borogove/persistence/Sqlite.hx +++ b/borogove/persistence/Sqlite.hx @@ -394,7 +394,7 @@ class Sqlite implements Persistence implements KeyValueStore { chatIds.push(message.chatId()); localIds.push(message.localId); } - if (message.replyToMessage != null && message.replyToMessage.serverIdBy == null) { + if (message.replyToMessage != null) { replyTos.push({ chatId: message.chatId(), serverId: message.replyToMessage.serverId, localId: message.replyToMessage.localId }); } } diff --git a/test/idb.spec.ts b/test/idb.spec.ts index 7a5ebf6..a77c6fd 100644 --- a/test/idb.spec.ts +++ b/test/idb.spec.ts @@ -866,6 +866,62 @@ test("hydrate message with incomplete replyToMessage", async ({ page }) => { expect(result.replyServerId).toBe("parent"); }); +test("hydrate message with incomplete replyToMessage", async ({ page }) => { + page.route("https://localhost/", (route) => + route.fulfill({ body: "<html></html>" }), + ); + const code = fs.readFileSync("playwright/.cache/borogove.js", "utf8"); + await page.goto("https://localhost/"); + const result = await page.evaluate(async (code) => { + const blob = new Blob([code], { type: "text/javascript" }); + const borogove = await import(URL.createObjectURL(blob)); + + const mediaStore = await borogove.persistence.MediaStoreCache("snikket"); + const persistence = await borogove.persistence.IDB("snikket", mediaStore); + + const builder = new borogove.ChatMessageBuilder({ + serverId: "parent", + serverIdBy: "hatter@example.com", + localId: "loc1", + senderId: "hatter@example.com", + direction: 0, + }); + builder.sortId = "a0"; + builder.to = borogove.JID.parse("alice@example.com"); + builder.from = borogove.JID.parse("hatter@example.com"); + builder.recipients = [builder.to]; + builder.replyTo = [builder.from]; + const parentStub = builder.build(); + + builder.setBody(borogove.Html.text("Hello")); + const parentMsg = builder.build(); + + const builder2 = new borogove.ChatMessageBuilder({ + serverId: "child", + serverIdBy: "hatter@example.com", + localId: "loc2", + senderId: "hatter@example.com", + direction: 0, + }); + builder2.sortId = "a1"; + builder2.to = borogove.JID.parse("alice@example.com"); + builder2.from = borogove.JID.parse("hatter@example.com"); + builder2.recipients = [builder2.to]; + builder2.replyTo = [builder2.from]; + builder2.replyToMessage = parentStub; + const childMsg = builder2.build(); + + await persistence.storeMessages("alice@example.com", [parentMsg]); + const [childStored] = await persistence.storeMessages("alice@example.com", [ + childMsg, + ]); + + return childStored.replyToMessage.body().toPlainText(); + }, code); + + expect(result).toBe("Hello"); +}); + test("storeChats and getChats with status", async ({ page }) => { page.route("https://localhost/", route => route.fulfill({ body: "<html></html>" })); const code = fs.readFileSync("playwright/.cache/borogove.js", "utf8"); diff --git a/test/sqlite.spec.ts b/test/sqlite.spec.ts index f19d4fc..e4cf67d 100644 --- a/test/sqlite.spec.ts +++ b/test/sqlite.spec.ts @@ -1463,43 +1463,27 @@ test.describe("not webkit", () => { localId: "loc2", senderId: "hatter@example.com", direction: 0, - type: borogove.MessageType.MessageChannel, }); builder2.sortId = "a1"; builder2.to = borogove.JID.parse("alice@example.com"); builder2.from = borogove.JID.parse("hatter@example.com"); builder2.recipients = [builder2.to]; builder2.replyTo = [builder2.from]; - builder2.replyToMessage = parentMsg; + builder2.replyToMessage = parentStub; const childMsg = builder2.build(); - try { - await persistence.storeMessages("alice@example.com", [ - parentMsg, - childMsg, - ]); - const retrievedChild = await persistence.getMessage( - "alice@example.com", - "hatter@example.com", - "child", - "loc2", - ); - return { - hasReply: !!retrievedChild.replyToMessage, - replyServerId: retrievedChild.replyToMessage - ? retrievedChild.replyToMessage.serverId - : null, - }; - } catch (e) { - console.error(e, e.result); - throw e.result ? JSON.stringify(e.result) : e.message; - } + await persistence.storeMessages("alice@example.com", [parentMsg]); + const [childStored] = await persistence.storeMessages( + "alice@example.com", + [childMsg], + ); + + return childStored.replyToMessage.body().toPlainText(); }, [code, sqlite, worker1], ); - expect(result.hasReply).toBe(true); - expect(result.replyServerId).toBe("parent"); + expect(result).toBe("Hello"); }); test("storeChats and getChats with status", async ({ page }) => {