@graffiti-garden/implementation-decentralized 0.1.0 → 0.1.1

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.
@@ -138,6 +138,7 @@ export class Inboxes {
138
138
  body: Uint8Array<ArrayBuffer> | undefined,
139
139
  inboxToken?: string | null,
140
140
  cursor?: string,
141
+ signal?: AbortSignal,
141
142
  ) {
142
143
  const response = await fetchWithErrorHandling(
143
144
  `${inboxUrl}/${type}${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ""}`,
@@ -152,6 +153,7 @@ export class Inboxes {
152
153
  : {}),
153
154
  },
154
155
  body,
156
+ signal,
155
157
  },
156
158
  );
157
159
  const retryAfterHeader = response.headers.get("Retry-After");
@@ -414,13 +416,11 @@ export class Inboxes {
414
416
  );
415
417
 
416
418
  // First cache the messages with their labels
417
- await Promise.all(
418
- labeledMessages.map((m: LabeledMessageBase) =>
419
- cache.messages.set(
420
- getMessageCacheKey(inboxUrl, m[LABELED_MESSAGE_ID_KEY]),
421
- m,
422
- ),
423
- ),
419
+ await cache.messages.setMany(
420
+ labeledMessages.map((m: LabeledMessageBase) => [
421
+ getMessageCacheKey(inboxUrl, m[LABELED_MESSAGE_ID_KEY]),
422
+ m,
423
+ ]),
424
424
  );
425
425
  // Then store all the messageids
426
426
  messageIds = [
@@ -439,22 +439,38 @@ export class Inboxes {
439
439
  // Update how many we've seen
440
440
  cacheNumSeen += labeledMessages.length;
441
441
 
442
+ // Fetch the next page while the caller processes the current page.
443
+ const prefetchController = new AbortController();
444
+ // Otherwise get another response (after waiting for rate-limit)
445
+ const nextPage = hasMore
446
+ ? waitFor(waitTil)
447
+ .then(() => this.fetchMessageBatch(
448
+ inboxUrl,
449
+ type,
450
+ undefined, // Body is never past the first time
451
+ inboxToken,
452
+ cursor,
453
+ prefetchController.signal,
454
+ ))
455
+ // A consumer may stop before awaiting this request.
456
+ .then((value) => ({ value }), (error) => ({ error }))
457
+ : null;
458
+
442
459
  // Return the values
443
- for (const m of labeledMessages) yield m;
460
+ let consumedPage = false;
461
+ try {
462
+ for (const m of labeledMessages) yield m;
463
+ consumedPage = true;
464
+ } finally {
465
+ if (!consumedPage) prefetchController.abort();
466
+ }
444
467
 
445
468
  if (!hasMore) break;
446
469
 
447
- // Otherwise get another response (after waiting for rate-limit)
448
- await waitFor(waitTil);
449
- const out = await this.fetchMessageBatch(
450
- inboxUrl,
451
- type,
452
- undefined, // Body is never past the first time
453
- inboxToken,
454
- cursor,
455
- );
456
- response = out.response;
457
- waitTil = out.waitTil;
470
+ const out = await nextPage!;
471
+ if ("error" in out) throw out.error;
472
+ response = out.value.response;
473
+ waitTil = out.value.waitTil;
458
474
  }
459
475
 
460
476
  const outputCursor: infer_<typeof CursorSchema> = {
@@ -619,6 +635,7 @@ type Cache = {
619
635
  messages: {
620
636
  get(k: string): Promise<LabeledMessageBase | null | undefined>;
621
637
  set(k: string, value: LabeledMessageBase | null): Promise<void>;
638
+ setMany(entries: [string, LabeledMessageBase][]): Promise<void>;
622
639
  del(k: string): Promise<void>;
623
640
  };
624
641
  messageIds: {
@@ -684,6 +701,14 @@ async function createCache(): Promise<Cache> {
684
701
  set: async (k, v) => {
685
702
  await db.put("m", v, k);
686
703
  },
704
+ setMany: async (entries) => {
705
+ if (entries.length === 0) return;
706
+ const tx = db.transaction("m", "readwrite");
707
+ await Promise.all([
708
+ ...entries.map(([k, v]) => tx.store.put(v, k)),
709
+ tx.done,
710
+ ]);
711
+ },
687
712
  del: (k) => db.delete("m", k),
688
713
  },
689
714
  messageIds: {
@@ -712,6 +737,9 @@ async function createCache(): Promise<Cache> {
712
737
  messages: {
713
738
  get: async (k) => m.get(k),
714
739
  set: async (k, v) => void m.set(k, v),
740
+ setMany: async (entries) => {
741
+ for (const [k, v] of entries) m.set(k, v);
742
+ },
715
743
  del: async (k) => void m.delete(k),
716
744
  },
717
745
  messageIds: {
@@ -133,7 +133,7 @@ export interface GraffitiDecentralizedOptions {
133
133
  defaultInboxEndpoints?: string[];
134
134
  }
135
135
 
136
- const CONCURRENCY = 16;
136
+ const CONCURRENCY = 128;
137
137
  const LOCAL_STORAGE_REMEMBERED_HANDLE_KEY = "graffiti-login-remembered-handle";
138
138
 
139
139
  export class GraffitiDecentralized implements Graffiti {