@remit/data-ports 0.0.54 → 0.0.55
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/package.json +1 -1
- package/src/id.test.ts +29 -3
- package/src/id.ts +12 -2
package/package.json
CHANGED
package/src/id.test.ts
CHANGED
|
@@ -199,8 +199,34 @@ describe("deriveCalendarSuggestionId", () => {
|
|
|
199
199
|
});
|
|
200
200
|
});
|
|
201
201
|
|
|
202
|
+
describe("deriveThreadId", () => {
|
|
203
|
+
const ROOT = "<root@example.com>";
|
|
204
|
+
|
|
205
|
+
// #1017: the account is not part of the name, so every mailbox connected to
|
|
206
|
+
// one config resolves the same root header to one conversation. Keyed on the
|
|
207
|
+
// account, a reply sent from the second account opened a thread of its own.
|
|
208
|
+
it("gives one root header one thread across the accounts of a config", () => {
|
|
209
|
+
assert.equal(deriveThreadId("cfg-1", ROOT), deriveThreadId("cfg-1", ROOT));
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("separates two account configs holding the same conversation", () => {
|
|
213
|
+
assert.notEqual(
|
|
214
|
+
deriveThreadId("cfg-1", ROOT),
|
|
215
|
+
deriveThreadId("cfg-2", ROOT),
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("separates two conversations under one config", () => {
|
|
220
|
+
assert.notEqual(
|
|
221
|
+
deriveThreadId("cfg-1", ROOT),
|
|
222
|
+
deriveThreadId("cfg-1", "<other@example.com>"),
|
|
223
|
+
);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
202
227
|
describe("derived ids are stored primary keys: a changed value orphans every row already written and needs a migration, never a new expectation here", () => {
|
|
203
228
|
const ACCOUNT = "account-golden";
|
|
229
|
+
const ACCOUNT_CONFIG = "account-config-golden";
|
|
204
230
|
const MESSAGE = "message-golden";
|
|
205
231
|
const MAILBOX = "mailbox-golden";
|
|
206
232
|
const ABSENT_HEADER_SOURCE = {
|
|
@@ -259,10 +285,10 @@ describe("derived ids are stored primary keys: a changed value orphans every row
|
|
|
259
285
|
);
|
|
260
286
|
});
|
|
261
287
|
|
|
262
|
-
it("deriveThreadId pins the thread primary key, lowercased root header included", () => {
|
|
288
|
+
it("deriveThreadId pins the thread primary key, keyed on the account config, lowercased root header included", () => {
|
|
263
289
|
assert.equal(
|
|
264
|
-
deriveThreadId(
|
|
265
|
-
"
|
|
290
|
+
deriveThreadId(ACCOUNT_CONFIG, "<Golden.Root@Example.COM>"),
|
|
291
|
+
"3tl03sgy85b60rfb15u6vtiex",
|
|
266
292
|
);
|
|
267
293
|
});
|
|
268
294
|
|
package/src/id.ts
CHANGED
|
@@ -150,12 +150,22 @@ export const deriveCopyMessageId = (
|
|
|
150
150
|
REMIT_NAMESPACE,
|
|
151
151
|
);
|
|
152
152
|
|
|
153
|
+
/**
|
|
154
|
+
* Identity of a conversation (issue #1017). Keyed on the account config, not on
|
|
155
|
+
* the account: two mailboxes connected to one config hold the same conversation,
|
|
156
|
+
* and keying on the account gave each of them its own thread rooted at the same
|
|
157
|
+
* header — so a reply sent from the second account opened a conversation of one
|
|
158
|
+
* beside the one it answered.
|
|
159
|
+
*
|
|
160
|
+
* Messages stay per account (`deriveMessageId`). Each account keeps its own copy
|
|
161
|
+
* of a mail, and the copies meet in one thread through the shared root header.
|
|
162
|
+
*/
|
|
153
163
|
export const deriveThreadId = (
|
|
154
|
-
|
|
164
|
+
accountConfigId: string,
|
|
155
165
|
rootMessageIdHeader: string,
|
|
156
166
|
): string =>
|
|
157
167
|
base36uuidv5(
|
|
158
|
-
`thread:${
|
|
168
|
+
`thread:${accountConfigId}:${rootMessageIdHeader.toLowerCase()}`,
|
|
159
169
|
REMIT_NAMESPACE,
|
|
160
170
|
);
|
|
161
171
|
|