stream-chat-react-native-core
Version:
The official React Native and Expo components for Stream Chat, a service for building chat applications
142 lines (102 loc) • 4.55 kB
text/typescript
import { AbstractOfflineDB, StreamChat } from 'stream-chat';
import type {
DBGetAppSettingsType,
DBGetChannelsForQueryType,
DBGetChannelsType,
DBGetLastSyncedAtType,
DBUpsertAppSettingsType,
DBUpsertUserSyncStatusType,
} from 'stream-chat';
import * as api from './apis';
import { SqliteClient, SqliteClientError } from './SqliteClient';
export class OfflineDB extends AbstractOfflineDB {
constructor({
client,
getEncryptionKey,
maxSyncEventsLimit,
}: {
client: StreamChat;
/**
* Supplies the SQLCipher key the offline database is opened with. See
* {@link SqliteClient.getEncryptionKey} for the stability requirement.
*/
getEncryptionKey?: () => Promise<string | undefined>;
maxSyncEventsLimit?: number | false;
}) {
super({
client,
syncMaxEventCount: maxSyncEventsLimit === false ? undefined : maxSyncEventsLimit,
});
// Assigned unconditionally: SqliteClient holds this statically, so leaving a
// previous instance's getter in place would keep encrypting after the caller
// stopped asking for it.
SqliteClient.getEncryptionKey = getEncryptionKey;
}
upsertCidsForQuery = api.upsertCidsForQuery;
upsertChannels = api.upsertChannels;
// TODO: Rename currentUserId -> userId in the next major version as it is technically breaking.
upsertUserSyncStatus = ({ userId, lastSyncedAt, execute }: DBUpsertUserSyncStatusType) =>
api.upsertUserSyncStatus({ currentUserId: userId, execute, lastSyncedAt });
// TODO: Rename currentUserId -> userId in the next major version as it is technically breaking.
upsertAppSettings = ({ appSettings, userId, execute }: DBUpsertAppSettingsType) =>
api.upsertAppSettings({ appSettings, currentUserId: userId, execute });
upsertPoll = api.upsertPoll;
upsertDraft = api.upsertDraft;
getDraft = api.getDraft;
deleteDraft = api.deleteDraft;
upsertChannelData = api.upsertChannelData;
upsertReads = api.upsertReads;
upsertMessages = api.upsertMessages;
upsertMembers = api.upsertMembers;
updateMessage = api.updateMessage;
// TODO: Rename currentUserId -> userId in the next major version as it is technically breaking.
getChannels = ({ cids, userId }: DBGetChannelsType) =>
api.getChannels({ channelIds: cids, currentUserId: userId });
// TODO: Rename currentUserId -> userId in the next major version as it is technically breaking.
getChannelsForQuery = ({ userId, filters, options, sort }: DBGetChannelsForQueryType) =>
api.getChannelsForFilterSort({ currentUserId: userId, filters, options, sort });
getAllChannelCids = api.getAllChannelIds;
// TODO: Rename currentUserId -> userId in the next major version as it is technically breaking.
getLastSyncedAt = ({ userId }: DBGetLastSyncedAtType) =>
api.getLastSyncedAt({ currentUserId: userId });
getAppSettings = ({ userId }: DBGetAppSettingsType) =>
api.getAppSettings({ currentUserId: userId });
getReactions = api.getReactionsForFilterSort;
addPendingTask = api.addPendingTask;
updatePendingTask = api.updatePendingTask;
deletePendingTask = api.deletePendingTask;
deleteReaction = api.deleteReaction;
deleteMember = api.deleteMember;
deleteChannel = api.deleteChannel;
deleteMessagesForChannel = api.deleteMessagesForChannel;
dropPendingTasks = api.dropPendingTasks;
hardDeleteMessage = api.deleteMessage;
softDeleteMessage = api.softDeleteMessage;
getPendingTasks = api.getPendingTasks;
updateReaction = api.updateReaction;
insertReaction = api.insertReaction;
channelExists = api.channelExists;
resetDB = SqliteClient.resetDB;
executeSqlBatch = SqliteClient.executeSqlBatch;
/**
* Why the most recent {@link initializeDB} failed, if it did.
*
* `AbstractOfflineDB.init` catches whatever `initializeDB` throws and does not
* re-throw it, so a caller has no way to see the reason. Recording it here on the
* way out gives the caller something to read back once `init` has settled. Kept on
* the instance rather than a static so two clients cannot overwrite each other.
*/
initializationError: SqliteClientError | undefined;
initializeDB = async () => {
this.initializationError = undefined;
try {
return await SqliteClient.initializeDatabase();
} catch (error) {
if (error instanceof SqliteClientError) {
this.initializationError = error;
}
// Re-thrown so `AbstractOfflineDB.init` still marks the database uninitialized.
throw error;
}
};
}