@arbidocs/react 0.5.89 → 0.5.90

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.
@@ -96,7 +96,7 @@ function createLocalFeatureStore({
96
96
  storage = defaultStorage(),
97
97
  migrate
98
98
  }) {
99
- const listeners3 = /* @__PURE__ */ new Set();
99
+ const listeners4 = /* @__PURE__ */ new Set();
100
100
  const read = () => {
101
101
  try {
102
102
  return storage?.getItem(key) ?? null;
@@ -110,7 +110,7 @@ function createLocalFeatureStore({
110
110
  } catch {
111
111
  }
112
112
  };
113
- const notify2 = () => listeners3.forEach((listener) => listener());
113
+ const notify2 = () => listeners4.forEach((listener) => listener());
114
114
  const saved = parseValues(read());
115
115
  let values = saved ?? {};
116
116
  let hydrated = saved !== null || !migrate;
@@ -132,8 +132,8 @@ function createLocalFeatureStore({
132
132
  notify2();
133
133
  },
134
134
  subscribe(listener) {
135
- listeners3.add(listener);
136
- return () => listeners3.delete(listener);
135
+ listeners4.add(listener);
136
+ return () => listeners4.delete(listener);
137
137
  },
138
138
  isHydrated: () => hydrated,
139
139
  hydrated: () => ready
@@ -668,6 +668,253 @@ function applyCallEvent(queryClient, event, options = {}) {
668
668
  return false;
669
669
  }
670
670
  }
671
+ var OfflineMailLockedError = class extends Error {
672
+ constructor() {
673
+ super("Sign in to open the mail saved on this device");
674
+ this.name = "OfflineMailLockedError";
675
+ }
676
+ };
677
+ var sealer = client.createOfflineSealer("arbi-offline-mail-v1", {
678
+ locked: () => new OfflineMailLockedError()
679
+ });
680
+ var forgetOfflineMailKeys = sealer.forget;
681
+ var sealBytes = sealer.sealBytes;
682
+ var openBytes = sealer.openBytes;
683
+ var sealJson = sealer.sealJson;
684
+ var openJson = sealer.openJson;
685
+ var blind = sealer.blind;
686
+
687
+ // src/offline-store/store.ts
688
+ var DB_VERSION = 1;
689
+ var RECORDS = "records";
690
+ var META = "meta";
691
+ function promisify(request) {
692
+ return new Promise((resolve, reject) => {
693
+ request.onsuccess = () => resolve(request.result);
694
+ request.onerror = () => reject(request.error);
695
+ });
696
+ }
697
+ function createRecordStore(dbName) {
698
+ let dbPromise = null;
699
+ function openDB() {
700
+ if (dbPromise) return dbPromise;
701
+ dbPromise = new Promise((resolve, reject) => {
702
+ const request = indexedDB.open(dbName, DB_VERSION);
703
+ request.onerror = () => {
704
+ dbPromise = null;
705
+ reject(request.error);
706
+ };
707
+ request.onsuccess = () => {
708
+ const db = request.result;
709
+ db.onversionchange = () => {
710
+ db.close();
711
+ dbPromise = null;
712
+ };
713
+ resolve(db);
714
+ };
715
+ request.onupgradeneeded = () => {
716
+ const db = request.result;
717
+ if (!db.objectStoreNames.contains(RECORDS)) {
718
+ const records = db.createObjectStore(RECORDS, { keyPath: "key" });
719
+ records.createIndex("bucket", "bucket");
720
+ records.createIndex("kind", "kind");
721
+ }
722
+ if (!db.objectStoreNames.contains(META)) db.createObjectStore(META, { keyPath: "key" });
723
+ };
724
+ });
725
+ return dbPromise;
726
+ }
727
+ async function run(store2, mode, fn) {
728
+ const db = await openDB();
729
+ return promisify(fn(db.transaction(store2, mode).objectStore(store2)));
730
+ }
731
+ async function scan(pick) {
732
+ const db = await openDB();
733
+ const store2 = db.transaction(RECORDS, "readonly").objectStore(RECORDS);
734
+ return new Promise((resolve, reject) => {
735
+ const out = [];
736
+ const cursor = store2.openCursor();
737
+ cursor.onerror = () => reject(cursor.error);
738
+ cursor.onsuccess = () => {
739
+ const c = cursor.result;
740
+ if (!c) return resolve(out);
741
+ out.push(pick(c.value));
742
+ c.continue();
743
+ };
744
+ });
745
+ }
746
+ const self = {
747
+ dbName,
748
+ async putRecord(record) {
749
+ await run(RECORDS, "readwrite", (s) => s.put(record));
750
+ },
751
+ async getRecord(key) {
752
+ return await run(RECORDS, "readonly", (s) => s.get(key));
753
+ },
754
+ async hasRecord(key) {
755
+ return await run(RECORDS, "readonly", (s) => s.count(key)) > 0;
756
+ },
757
+ async deleteRecords(keys) {
758
+ if (keys.length === 0) return;
759
+ const db = await openDB();
760
+ const tx = db.transaction(RECORDS, "readwrite");
761
+ const store2 = tx.objectStore(RECORDS);
762
+ for (const key of keys) store2.delete(key);
763
+ await new Promise((resolve, reject) => {
764
+ tx.oncomplete = () => resolve();
765
+ tx.onerror = () => reject(tx.error);
766
+ tx.onabort = () => reject(tx.error);
767
+ });
768
+ },
769
+ async recordsInBucket(bucket) {
770
+ return await run(
771
+ RECORDS,
772
+ "readonly",
773
+ (s) => s.index("bucket").getAll(bucket)
774
+ );
775
+ },
776
+ async recordsOfKind(kind) {
777
+ return await run(
778
+ RECORDS,
779
+ "readonly",
780
+ (s) => s.index("kind").getAll(kind)
781
+ );
782
+ },
783
+ allRecordSizes() {
784
+ return scan(({ key, kind, size }) => ({ key, kind, size }));
785
+ },
786
+ allRecordAccess() {
787
+ return scan(({ key, kind, lastAccess }) => ({ key, kind, lastAccess }));
788
+ },
789
+ async touchRecord(key) {
790
+ const record = await self.getRecord(key);
791
+ if (record) await self.putRecord({ ...record, lastAccess: Date.now() });
792
+ },
793
+ async getMeta(key) {
794
+ const row = await run(META, "readonly", (s) => s.get(key));
795
+ return row?.value;
796
+ },
797
+ async setMeta(key, value) {
798
+ await run(META, "readwrite", (s) => s.put({ key, value }));
799
+ },
800
+ async deleteDatabase() {
801
+ const db = await dbPromise?.catch(() => null);
802
+ db?.close();
803
+ dbPromise = null;
804
+ await new Promise((resolve, reject) => {
805
+ const request = indexedDB.deleteDatabase(dbName);
806
+ request.onsuccess = () => resolve();
807
+ request.onerror = () => reject(request.error);
808
+ request.onblocked = () => {
809
+ };
810
+ });
811
+ }
812
+ };
813
+ return self;
814
+ }
815
+
816
+ // src/mail/offline/store.ts
817
+ var OFFLINE_MAIL_DB = "arbi-offline-mail";
818
+ var store = createRecordStore(OFFLINE_MAIL_DB);
819
+ var putRecord = store.putRecord;
820
+ var getRecord = store.getRecord;
821
+ var hasRecord = store.hasRecord;
822
+ var deleteRecords = store.deleteRecords;
823
+ var recordsInBucket = store.recordsInBucket;
824
+ var recordsOfKind = store.recordsOfKind;
825
+ var allRecordSizes = store.allRecordSizes;
826
+ var touchRecord = store.touchRecord;
827
+ var getMeta = store.getMeta;
828
+ var setMeta = store.setMeta;
829
+ var deleteOfflineMailDatabase = store.deleteDatabase;
830
+
831
+ // src/mail/offline/settings.ts
832
+ var DEFAULT_OFFLINE_MAIL_SETTINGS = {
833
+ enabled: true,
834
+ scope: "7d",
835
+ attachmentCapMb: 25,
836
+ quotaMb: 1024
837
+ };
838
+ var SCOPE_DAYS = {
839
+ "1d": 1,
840
+ "7d": 7,
841
+ "30d": 30,
842
+ "90d": 90
843
+ };
844
+ var DAY_MS = 24 * 60 * 60 * 1e3;
845
+ function offlineWindowStart(settings, now = Date.now()) {
846
+ return now - SCOPE_DAYS[settings.scope] * DAY_MS;
847
+ }
848
+ function inOfflineWindow(settings, receivedAt, now = Date.now()) {
849
+ const at = receivedAt ? Date.parse(receivedAt) || 0 : 0;
850
+ return settings.enabled && (!at || at >= offlineWindowStart(settings, now));
851
+ }
852
+ function normalize(saved) {
853
+ const merged = { ...DEFAULT_OFFLINE_MAIL_SETTINGS, ...saved };
854
+ const scope = merged.scope;
855
+ if (scope in SCOPE_DAYS) return merged;
856
+ const longer = scope === "365d" || scope === "all";
857
+ return { ...merged, scope: longer ? "90d" : DEFAULT_OFFLINE_MAIL_SETTINGS.scope };
858
+ }
859
+ var STORAGE_PREFIX = "arbi-offline-mail-settings:";
860
+ var SIGNED_OUT = { ...DEFAULT_OFFLINE_MAIL_SETTINGS, enabled: false };
861
+ function getOfflineMailSettings(userExtId) {
862
+ if (!userExtId) return SIGNED_OUT;
863
+ const key = STORAGE_PREFIX + userExtId;
864
+ try {
865
+ const raw = localStorage.getItem(key);
866
+ return raw ? normalize(JSON.parse(raw)) : DEFAULT_OFFLINE_MAIL_SETTINGS;
867
+ } catch {
868
+ return DEFAULT_OFFLINE_MAIL_SETTINGS;
869
+ }
870
+ }
871
+ function setOfflineMailSettings(userExtId, patch) {
872
+ const next = { ...getOfflineMailSettings(userExtId), ...patch };
873
+ if (userExtId) {
874
+ try {
875
+ localStorage.setItem(STORAGE_PREFIX + userExtId, JSON.stringify(next));
876
+ } catch {
877
+ }
878
+ }
879
+ notifyOfflineMailChange("settings");
880
+ return next;
881
+ }
882
+ var listeners3 = /* @__PURE__ */ new Set();
883
+ var CHANNEL = "arbi-offline-mail";
884
+ var channel = null;
885
+ function getChannel() {
886
+ if (channel || typeof BroadcastChannel === "undefined") return channel;
887
+ channel = new BroadcastChannel(CHANNEL);
888
+ channel.onmessage = (event) => {
889
+ for (const listener of listeners3) listener(event.data);
890
+ };
891
+ return channel;
892
+ }
893
+ function notifyOfflineMailChange(change) {
894
+ for (const listener of listeners3) listener(change);
895
+ try {
896
+ getChannel()?.postMessage(change);
897
+ } catch {
898
+ }
899
+ }
900
+ function onOfflineMailChange(listener) {
901
+ getChannel();
902
+ listeners3.add(listener);
903
+ return () => listeners3.delete(listener);
904
+ }
905
+
906
+ // src/mail/offline/wipe.ts
907
+ var OWNER_KEY = "owner";
908
+ async function wipeOfflineMail() {
909
+ forgetOfflineMailKeys();
910
+ await deleteOfflineMailDatabase();
911
+ notifyOfflineMailChange("wiped");
912
+ }
913
+ async function claimOfflineMail(userExtId) {
914
+ const owner = await getMeta(OWNER_KEY);
915
+ if (owner && owner !== userExtId) await wipeOfflineMail();
916
+ await setMeta(OWNER_KEY, userExtId);
917
+ }
671
918
  function toProfileView(profile) {
672
919
  return {
673
920
  ...profile,
@@ -803,6 +1050,8 @@ function arbiAccountClient(arbi, overrides = {}) {
803
1050
  } finally {
804
1051
  chunk7RUVJZZG_cjs.clearSealedDrafts();
805
1052
  chunkRLSBRZ6Z_cjs.clearChatArtifacts();
1053
+ await wipeOfflineMail().catch(() => {
1054
+ });
806
1055
  }
807
1056
  },
808
1057
  requestDeletion: () => arbi.account.requestDeletion(),
@@ -2493,10 +2742,12 @@ exports.HISTORY_LIMIT = HISTORY_LIMIT;
2493
2742
  exports.LIVE_SEGMENTER = LIVE_SEGMENTER;
2494
2743
  exports.MAX_AVATAR_FILE_BYTES = MAX_AVATAR_FILE_BYTES;
2495
2744
  exports.MUTED_DEDUPE_MS = MUTED_DEDUPE_MS;
2745
+ exports.OFFLINE_MAIL_DB = OFFLINE_MAIL_DB;
2496
2746
  exports.PLAYBACK_LOOKAHEAD_MS = PLAYBACK_LOOKAHEAD_MS;
2497
2747
  exports.READ_ONLY_MEETING_TEXT = READ_ONLY_MEETING_TEXT;
2498
2748
  exports.RECORDING_CHUNK_MS = RECORDING_CHUNK_MS;
2499
2749
  exports.RECORDING_SEGMENTER = RECORDING_SEGMENTER;
2750
+ exports.SCOPE_DAYS = SCOPE_DAYS;
2500
2751
  exports.SEGMENT_FRAME_MS = SEGMENT_FRAME_MS;
2501
2752
  exports.SEGMENT_ID_PATTERN = SEGMENT_ID_PATTERN;
2502
2753
  exports.SEGMENT_PRE_ROLL_MS = SEGMENT_PRE_ROLL_MS;
@@ -2507,6 +2758,7 @@ exports.UPLOAD_ATTEMPTS = UPLOAD_ATTEMPTS;
2507
2758
  exports.UPLOAD_BACKOFF_MS = UPLOAD_BACKOFF_MS;
2508
2759
  exports.acceptRing = acceptRing;
2509
2760
  exports.addConversationToList = addConversationToList;
2761
+ exports.allRecordSizes = allRecordSizes;
2510
2762
  exports.appendToThread = appendToThread;
2511
2763
  exports.applyAgentDmStatus = applyAgentDmStatus;
2512
2764
  exports.applyCallEvent = applyCallEvent;
@@ -2515,6 +2767,7 @@ exports.applyChatMessage = applyChatMessage;
2515
2767
  exports.applyChatRead = applyChatRead;
2516
2768
  exports.applyChatUpdated = applyChatUpdated;
2517
2769
  exports.arbiAccountClient = arbiAccountClient;
2770
+ exports.blind = blind;
2518
2771
  exports.buildMeetingChatBody = buildMeetingChatBody;
2519
2772
  exports.cachedChat = cachedChat;
2520
2773
  exports.cachedChats = cachedChats;
@@ -2525,6 +2778,7 @@ exports.chatByExtId = chatByExtId;
2525
2778
  exports.chatHasLiveCall = chatHasLiveCall;
2526
2779
  exports.chatLiveCallId = chatLiveCallId;
2527
2780
  exports.chatTranscriptRef = chatTranscriptRef;
2781
+ exports.claimOfflineMail = claimOfflineMail;
2528
2782
  exports.clearMeetingChatCache = clearMeetingChatCache;
2529
2783
  exports.clearTrackUploaders = clearTrackUploaders;
2530
2784
  exports.clockTime = clockTime;
@@ -2533,6 +2787,7 @@ exports.compositeTrack = compositeTrack;
2533
2787
  exports.conversationKeyForCall = conversationKeyForCall;
2534
2788
  exports.createLocalFeatureStore = createLocalFeatureStore;
2535
2789
  exports.createMutedNotifier = createMutedNotifier;
2790
+ exports.createRecordStore = createRecordStore;
2536
2791
  exports.createTrackCutter = createTrackCutter;
2537
2792
  exports.cutAtPauses = cutAtPauses;
2538
2793
  exports.declineRing = declineRing;
@@ -2541,6 +2796,7 @@ exports.decodeCaptionPacket = decodeCaptionPacket;
2541
2796
  exports.decodeMono16k = decodeMono16k;
2542
2797
  exports.decryptPart = decryptPart;
2543
2798
  exports.deleteChatMessage = deleteChatMessage;
2799
+ exports.deleteRecords = deleteRecords;
2544
2800
  exports.dropFromThread = dropFromThread;
2545
2801
  exports.encodeCallChatPacket = encodeCallChatPacket;
2546
2802
  exports.encodeCaptionPacket = encodeCaptionPacket;
@@ -2554,8 +2810,13 @@ exports.fileSafe = fileSafe;
2554
2810
  exports.findConversation = findConversation;
2555
2811
  exports.floatToWav = floatToWav;
2556
2812
  exports.formatTranscriptMarkdown = formatTranscriptMarkdown;
2813
+ exports.getMeta = getMeta;
2814
+ exports.getOfflineMailSettings = getOfflineMailSettings;
2557
2815
  exports.getOpenChat = getOpenChat;
2816
+ exports.getRecord = getRecord;
2817
+ exports.hasRecord = hasRecord;
2558
2818
  exports.hasRecordingTranscript = hasRecordingTranscript;
2819
+ exports.inOfflineWindow = inOfflineWindow;
2559
2820
  exports.invalidateCall = invalidateCall;
2560
2821
  exports.invalidateConversationDetails = invalidateConversationDetails;
2561
2822
  exports.invalidateConversationLists = invalidateConversationLists;
@@ -2580,8 +2841,13 @@ exports.newPacketId = newPacketId;
2580
2841
  exports.newSegmentId = newSegmentId;
2581
2842
  exports.newTrackKey = newTrackKey;
2582
2843
  exports.nextSeqAfter = nextSeqAfter;
2844
+ exports.notifyOfflineMailChange = notifyOfflineMailChange;
2845
+ exports.offlineWindowStart = offlineWindowStart;
2583
2846
  exports.onCallEvent = onCallEvent;
2847
+ exports.onOfflineMailChange = onOfflineMailChange;
2848
+ exports.openBytes = openBytes;
2584
2849
  exports.openCall = openCall;
2850
+ exports.openJson = openJson;
2585
2851
  exports.openQuestion = openQuestion;
2586
2852
  exports.openRecording = openRecording;
2587
2853
  exports.parseWebinarPacket = parseWebinarPacket;
@@ -2595,9 +2861,12 @@ exports.persistTranscriptSegment = persistTranscriptSegment;
2595
2861
  exports.playheadAt = playheadAt;
2596
2862
  exports.postRecordingDocsToThread = postRecordingDocsToThread;
2597
2863
  exports.postTranscriptToThread = postTranscriptToThread;
2864
+ exports.putRecord = putRecord;
2598
2865
  exports.readLocalFeature = readLocalFeature;
2599
2866
  exports.recordingFiles = recordingFiles;
2600
2867
  exports.recordingWindowsOf = recordingWindowsOf;
2868
+ exports.recordsInBucket = recordsInBucket;
2869
+ exports.recordsOfKind = recordsOfKind;
2601
2870
  exports.rejoinAsAudience = rejoinAsAudience;
2602
2871
  exports.removeChat = removeChat;
2603
2872
  exports.removeConversationFromLists = removeConversationFromLists;
@@ -2605,8 +2874,12 @@ exports.resetCallSession = resetCallSession;
2605
2874
  exports.resolveMeetingChat = resolveMeetingChat;
2606
2875
  exports.saveRecordingFilesToThread = saveRecordingFilesToThread;
2607
2876
  exports.schedulePart = schedulePart;
2877
+ exports.sealBytes = sealBytes;
2878
+ exports.sealJson = sealJson;
2608
2879
  exports.sealQuestionText = sealQuestionText;
2609
2880
  exports.serverCallsExperimental = serverCallsExperimental;
2881
+ exports.setMeta = setMeta;
2882
+ exports.setOfflineMailSettings = setOfflineMailSettings;
2610
2883
  exports.setOpenChat = setOpenChat;
2611
2884
  exports.sortTranscriptMessages = sortTranscriptMessages;
2612
2885
  exports.sortedParts = sortedParts;
@@ -2631,6 +2904,7 @@ exports.threadTranscriptText = threadTranscriptText;
2631
2904
  exports.timelineDurationMs = timelineDurationMs;
2632
2905
  exports.timelineOf = timelineOf;
2633
2906
  exports.toProfileView = toProfileView;
2907
+ exports.touchRecord = touchRecord;
2634
2908
  exports.trackUploaderFor = trackUploaderFor;
2635
2909
  exports.transcribeRecording = transcribeRecording;
2636
2910
  exports.transcriptPersistRole = transcriptPersistRole;
@@ -2666,7 +2940,8 @@ exports.useServerCallsExperimental = useServerCallsExperimental;
2666
2940
  exports.useUpdateProfile = useUpdateProfile;
2667
2941
  exports.useUpdateUserSettings = useUpdateUserSettings;
2668
2942
  exports.useUserSettings = useUserSettings;
2943
+ exports.wipeOfflineMail = wipeOfflineMail;
2669
2944
  exports.wrapTrackKey = wrapTrackKey;
2670
2945
  exports.writeSamples = writeSamples;
2671
- //# sourceMappingURL=chunk-EOKCXEYN.cjs.map
2672
- //# sourceMappingURL=chunk-EOKCXEYN.cjs.map
2946
+ //# sourceMappingURL=chunk-X4HGUBWU.cjs.map
2947
+ //# sourceMappingURL=chunk-X4HGUBWU.cjs.map