@pmate/chat-sdk 0.12.0-next.52 → 0.12.0-next.53
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/lib/runtime/readIndex.d.ts +3 -0
- package/lib/runtime/readIndex.js +26 -15
- package/package.json +1 -1
|
@@ -127,6 +127,9 @@ export declare class IndexedDbReadIndex implements ReadIndexPersistence {
|
|
|
127
127
|
constructor(factory?: IDBFactory, name?: string, storageScope?: string | undefined, migrateLegacy?: boolean, metadataOnly?: boolean);
|
|
128
128
|
private transaction;
|
|
129
129
|
private key;
|
|
130
|
+
/** Keyset pages avoid materializing a second, unbounded array of durable rows.
|
|
131
|
+
* Keep the caller's transaction so every page belongs to one consistent view. */
|
|
132
|
+
private readPages;
|
|
130
133
|
private hydrate;
|
|
131
134
|
private loadCurrent;
|
|
132
135
|
private loadStored;
|
package/lib/runtime/readIndex.js
CHANGED
|
@@ -269,22 +269,33 @@ export class IndexedDbReadIndex {
|
|
|
269
269
|
throw new Error("READ_STORAGE_UNAVAILABLE");
|
|
270
270
|
}
|
|
271
271
|
key(appId, profileId) { return this.storageScope === undefined ? [appId, profileId] : [appId, profileId, this.storageScope]; }
|
|
272
|
+
/** Keyset pages avoid materializing a second, unbounded array of durable rows.
|
|
273
|
+
* Keep the caller's transaction so every page belongs to one consistent view. */
|
|
274
|
+
async readPages(table, owner, key, visit) {
|
|
275
|
+
let after;
|
|
276
|
+
for (;;) {
|
|
277
|
+
const rows = await table.where(":id").between(after ?? [owner, Dexie.minKey], [owner, Dexie.maxKey], !after, true).limit(128).toArray();
|
|
278
|
+
for (const row of rows)
|
|
279
|
+
visit(row);
|
|
280
|
+
if (rows.length < 128)
|
|
281
|
+
return;
|
|
282
|
+
after = key(rows[rows.length - 1]);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
272
285
|
async hydrate(current, key) {
|
|
273
286
|
if (current.normalized) {
|
|
274
287
|
const owner = JSON.stringify(key);
|
|
275
|
-
const [threads, messages, positions] = await Promise.all([
|
|
276
|
-
this.threadRows.where("owner").equals(owner).toArray(),
|
|
277
|
-
this.messageRows.where("owner").equals(owner).toArray(),
|
|
278
|
-
this.positionRows.where("owner").equals(owner).toArray(),
|
|
279
|
-
]);
|
|
280
288
|
const byThread = new Map();
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
289
|
+
const byPosition = new Map(), byId = new Map();
|
|
290
|
+
await Promise.all([
|
|
291
|
+
this.readPages(this.threadRows, owner, row => [row.owner, row.id], row => byId.set(row.id, row)),
|
|
292
|
+
this.readPages(this.messageRows, owner, row => [row.owner, row.thread, row.id], row => {
|
|
293
|
+
if (!byThread.has(row.thread))
|
|
294
|
+
byThread.set(row.thread, new Map());
|
|
295
|
+
byThread.get(row.thread).set(row.id, row.value);
|
|
296
|
+
}),
|
|
297
|
+
this.readPages(this.positionRows, owner, row => [row.owner, row.id], row => byPosition.set(row.id, row)),
|
|
298
|
+
]);
|
|
288
299
|
const { normalized: _normalized, threadOrder, ...state } = current;
|
|
289
300
|
const result = { ...state, threads: (threadOrder ?? []).map(id => {
|
|
290
301
|
const row = byId.get(id);
|
|
@@ -494,8 +505,8 @@ export class IndexedDbReadIndex {
|
|
|
494
505
|
// Cursors are the mutable cross-document view. Refresh their small rows,
|
|
495
506
|
// while message metadata remains targeted; otherwise a later batch based
|
|
496
507
|
// on an older snapshot could regress a different conversation's progress.
|
|
497
|
-
const
|
|
498
|
-
|
|
508
|
+
const positionById = new Map();
|
|
509
|
+
await this.readPages(this.positionRows, owner, row => [row.owner, row.id], row => positionById.set(row.id, row));
|
|
499
510
|
if (base.threads.some(thread => !positionById.has(thread.id)))
|
|
500
511
|
return undefined;
|
|
501
512
|
const positions = sourceIds.map(id => positionById.get(id));
|
|
@@ -538,7 +549,7 @@ export class IndexedDbReadIndex {
|
|
|
538
549
|
await this.positionRows.bulkPut(writes);
|
|
539
550
|
if (JSON.stringify(header.pending) !== JSON.stringify(result.pending) || JSON.stringify(header.observedReadIntents) !== JSON.stringify(result.observedReadIntents))
|
|
540
551
|
await this.profiles.put({ ...header, pending: result.pending, observedReadIntents: result.observedReadIntents }, key);
|
|
541
|
-
const byId = new Map(
|
|
552
|
+
const byId = new Map(positionById);
|
|
542
553
|
result.threads.forEach(thread => byId.set(thread.id, thread));
|
|
543
554
|
let changed = false;
|
|
544
555
|
const threads = base.threads.map(thread => {
|
package/package.json
CHANGED