core: use db event manager

This commit is contained in:
Ammar Ahmed
2026-02-16 13:11:45 +05:00
parent 6b02144b30
commit d3c9744e65
21 changed files with 151 additions and 102 deletions

View File

@@ -76,6 +76,7 @@ import { IconButton } from "../ui/icon-button";
import { SvgView } from "../ui/svg";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import { db } from "../../common/database";
const Steps = {
select: 1,
@@ -139,7 +140,7 @@ const PayWall = (props: NavigationProps<"PayWall">) => {
}, [isFocused, step]);
useEffect(() => {
const sub = EV.subscribe(
const sub = db.eventManager.subscribe(
EVENTS.userSubscriptionUpdated,
(sub: User["subscription"]) => {
if (sub.plan === SubscriptionPlan.FREE) return;
@@ -1006,8 +1007,8 @@ const PricingPlanCard = ({
: "monthly"
}`
: pricingPlans.isGithubRelease
? (WebPlan?.period as string)
: (product?.productId as string)
? (WebPlan?.period as string)
: (product?.productId as string)
);
setStep(Steps.buy);
}}

View File

@@ -722,24 +722,39 @@ export const useAppEvents = () => {
useEffect(() => {
const subscriptions = [
EV.subscribe(EVENTS.syncCheckStatus, onCheckSyncStatus),
EV.subscribe(EVENTS.syncAborted, onSyncAborted),
EV.subscribe(EVENTS.appRefreshRequested, onSyncComplete),
db.eventManager.subscribe(EVENTS.syncCheckStatus, onCheckSyncStatus),
db.eventManager.subscribe(EVENTS.syncAborted, onSyncAborted),
db.eventManager.subscribe(EVENTS.appRefreshRequested, onSyncComplete),
db.eventManager.subscribe(EVENTS.userLoggedOut, onLogout),
db.eventManager.subscribe(EVENTS.userEmailConfirmed, onUserEmailVerified),
EV.subscribe(EVENTS.userSessionExpired, onUserSessionExpired),
db.eventManager.subscribe(
EVENTS.userSessionExpired,
onUserSessionExpired
),
db.eventManager.subscribe(
EVENTS.userSubscriptionUpdated,
onUserSubscriptionStatusChanged
),
EV.subscribe(EVENTS.fileDownload, onDownloadingAttachmentProgress),
EV.subscribe(EVENTS.fileUpload, onUploadingAttachmentProgress),
EV.subscribe(EVENTS.fileDownloaded, onDownloadedAttachmentProgress),
EV.subscribe(EVENTS.fileUploaded, onUploadedAttachmentProgress),
EV.subscribe(EVENTS.downloadCanceled, (data) => {
db.eventManager.subscribe(
EVENTS.fileDownload,
onDownloadingAttachmentProgress
),
db.eventManager.subscribe(
EVENTS.fileUpload,
onUploadingAttachmentProgress
),
db.eventManager.subscribe(
EVENTS.fileDownloaded,
onDownloadedAttachmentProgress
),
db.eventManager.subscribe(
EVENTS.fileUploaded,
onUploadedAttachmentProgress
),
db.eventManager.subscribe(EVENTS.downloadCanceled, (data) => {
useAttachmentStore.getState().setDownloading(data);
}),
EV.subscribe(EVENTS.uploadCanceled, (data) => {
db.eventManager.subscribe(EVENTS.uploadCanceled, (data) => {
useAttachmentStore.getState().setUploading(data);
}),
EV.subscribe(EVENTS.migrationStarted, (name) => {
@@ -765,7 +780,7 @@ export const useAppEvents = () => {
return;
endProgress();
}),
EV.subscribe(EVENTS.vaultLocked, async () => {
db.eventManager.subscribe(EVENTS.vaultLocked, async () => {
// Lock all notes in all tabs...
for (const tab of useTabStore.getState().tabs) {
const noteId = useTabStore.getState().getTab(tab.id)?.session?.noteId;
@@ -797,7 +812,6 @@ export const useAppEvents = () => {
return () => {
emitterSubscriptions.forEach((sub) => sub?.remove?.());
subscriptions.forEach((sub) => sub?.unsubscribe?.());
EV.unsubscribeAll();
};
}, [onSyncComplete, onUserUpdated]);

View File

@@ -29,7 +29,6 @@ export type SyncProgressEventType = {
const useSyncProgress = () => {
const [progress, setProgress] = useState<SyncProgressEventType>();
const EV = db.eventManager;
const onProgress = useCallback(
({ type, current, total }: SyncProgressEventType) => {
@@ -42,13 +41,13 @@ const useSyncProgress = () => {
setProgress(undefined);
};
useEffect(() => {
EV?.subscribe(EVENTS.syncProgress, onProgress);
EV?.subscribe(EVENTS.syncCompleted, onSyncComplete);
db.eventManager.subscribe(EVENTS.syncProgress, onProgress);
db.eventManager.subscribe(EVENTS.syncCompleted, onSyncComplete);
return () => {
EV?.unsubscribe(EVENTS.syncProgress, onProgress);
EV?.unsubscribe(EVENTS.syncCompleted, onSyncComplete);
db.eventManager.unsubscribe(EVENTS.syncProgress, onProgress);
db.eventManager.unsubscribe(EVENTS.syncCompleted, onSyncComplete);
};
}, [EV, onProgress]);
}, [onProgress]);
return {
progress

View File

@@ -31,7 +31,7 @@ import {
} from "./common";
import { AppEventManager, AppEvents } from "./common/app-events";
import { db } from "./common/db";
import { EV, EVENTS } from "@notesnook/core";
import { EVENTS } from "@notesnook/core";
import { registerKeyMap } from "./common/key-map";
import { updateStatus, removeStatus, getStatus } from "./hooks/use-status";
import { hashNavigate } from "./navigation";
@@ -113,7 +113,7 @@ export default function AppEffects() {
}
}
const fileDownloadEvents = EV.subscribeMulti(
const fileDownloadEvents = db.eventManager.subscribeMulti(
[EVENTS.fileDownloaded, EVENTS.fileDownload],
({ total, current }: { total: number; current: number }) => {
handleDownloadUploadProgress("download", total, current);
@@ -121,7 +121,7 @@ export default function AppEffects() {
null
);
const fileUploadEvents = EV.subscribeMulti(
const fileUploadEvents = db.eventManager.subscribeMulti(
[EVENTS.fileUploaded, EVENTS.fileUpload],
({ total, current }: { total: number; current: number }) => {
handleDownloadUploadProgress("upload", total, current);

View File

@@ -68,7 +68,6 @@ import { showFeatureNotAllowedToast } from "../../common/toasts";
import { UpgradeDialog } from "../../dialogs/buy-dialog/upgrade-dialog";
import { ConfirmDialog } from "../../dialogs/confirm";
import { strings } from "@notesnook/intl";
import { AppEventManager, AppEvents } from "../../common/app-events";
export type OnChangeHandler = (
content: () => string,

View File

@@ -23,7 +23,7 @@ import { Loading, Refresh } from "../icons";
import { db } from "../../common/db";
import { writeText } from "clipboard-polyfill";
import { showToast } from "../../utils/toast";
import { EV, EVENTS, hosts, MonographAnalytics } from "@notesnook/core";
import { EVENTS, hosts } from "@notesnook/core";
import { useStore } from "../../stores/monograph-store";
import { Note } from "@notesnook/core";
import { strings } from "@notesnook/intl";
@@ -67,7 +67,7 @@ function PublishView(props: PublishViewProps) {
}, [monograph?.id, monographAnalytics]);
useEffect(() => {
const fileDownloadedEvent = EV.subscribe(
const fileDownloadedEvent = db.eventManager.subscribe(
EVENTS.fileDownloaded,
({ total, current, groupId }) => {
if (!groupId || !groupId.includes(note.id)) return;

View File

@@ -1,4 +1,4 @@
import { EV, EVENTS } from "@notesnook/core";
import { EVENTS } from "@notesnook/core";
import { useEffect, useState } from "react";
import Vault from "../common/vault";
import { db } from "../common/db";
@@ -7,8 +7,8 @@ export function useVault() {
const [isLocked, setIsLocked] = useState(!db.vault.unlocked);
useEffect(() => {
EV.subscribe(EVENTS.vaultLocked, () => setIsLocked(true));
EV.subscribe(EVENTS.vaultUnlocked, () => setIsLocked(false));
db.eventManager.subscribe(EVENTS.vaultLocked, () => setIsLocked(true));
db.eventManager.subscribe(EVENTS.vaultUnlocked, () => setIsLocked(false));
}, []);
return {

View File

@@ -30,7 +30,7 @@ import { store as settingStore } from "./setting-store";
import BaseStore from "./index";
import { showToast } from "../utils/toast";
import { Notice } from "../common/notices";
import { EV, EVENTS, SYNC_CHECK_IDS, SyncOptions } from "@notesnook/core";
import { EVENTS, SYNC_CHECK_IDS, SyncOptions } from "@notesnook/core";
import { logger } from "../utils/logger";
import Config from "../utils/config";
import {
@@ -92,7 +92,7 @@ class AppStore extends BaseStore<AppStore> {
});
this.get().sync({ type: "full" });
EV.subscribe(EVENTS.appRefreshRequested, () => this.refresh());
db.eventManager.subscribe(EVENTS.appRefreshRequested, () => this.refresh());
db.eventManager.subscribe(EVENTS.syncCompleted, () => this.refresh());
db.eventManager.subscribe(EVENTS.syncProgress, ({ type, current }) => {
@@ -105,7 +105,7 @@ class AppStore extends BaseStore<AppStore> {
});
});
EV.subscribe(EVENTS.syncCheckStatus, async (type) => {
db.eventManager.subscribe(EVENTS.syncCheckStatus, async (type) => {
const { isAutoSyncEnabled, isSyncEnabled } = this.get();
switch (type) {
case SYNC_CHECK_IDS.sync:

View File

@@ -23,7 +23,7 @@ import { store as appStore } from "./app-store";
import { useStore as useSettingStore } from "./setting-store";
import { db } from "../common/db";
import BaseStore from ".";
import { EV, EVENTS } from "@notesnook/core";
import { EVENTS } from "@notesnook/core";
import { logger } from "../utils/logger";
import Config from "../utils/config";
import { setDocumentTitle } from "../utils/dom";
@@ -255,7 +255,7 @@ class EditorStore extends BaseStore<EditorStore> {
closeTabs(...tabs.map((s) => s.id));
});
EV.subscribe(EVENTS.vaultLocked, () => {
db.eventManager.subscribe(EVENTS.vaultLocked, () => {
this.set((state) => {
state.sessions = state.sessions.map((session) => {
if (isLockedSession(session)) {

View File

@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import createStore from "../common/store";
import { db } from "../common/db";
import BaseStore from "./index";
import { EV, EVENTS } from "@notesnook/core";
import { EVENTS } from "@notesnook/core";
import Config from "../utils/config";
import { hashNavigate } from "../navigation";
import { AuthenticatorType, User } from "@notesnook/core";
@@ -39,7 +39,7 @@ class UserStore extends BaseStore<UserStore> {
counter = 0;
init = () => {
EV.subscribe(EVENTS.userSessionExpired, async () => {
db.eventManager.subscribe(EVENTS.userSessionExpired, async () => {
Config.set("sessionExpired", true);
window.location.replace("/sessionexpired");
});
@@ -53,7 +53,8 @@ class UserStore extends BaseStore<UserStore> {
user,
isLoggedIn: true
});
if (Config.get("sessionExpired")) EV.publish(EVENTS.userSessionExpired);
if (Config.get("sessionExpired"))
db.eventManager.publish(EVENTS.userSessionExpired);
});
if (Config.get("sessionExpired")) return;

View File

@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import "../app.css";
import { useEffect, useState } from "react";
import { Box, Button, Flex, Text } from "@theme-ui/components";
import { hardNavigate, hashNavigate, useQueryParams } from "../navigation";
import { hardNavigate, useQueryParams } from "../navigation";
import { Support } from "../components/icons";
import { HeadlessAuth } from "./auth";
import {
@@ -39,7 +39,8 @@ import { isUserSubscribed } from "../hooks/use-is-user-premium";
import { PLAN_METADATA } from "../dialogs/buy-dialog/plans";
import { planToAvailability } from "@notesnook/common";
import { FeatureCaption } from "../dialogs/buy-dialog/feature-caption";
import { EV, EVENTS } from "@notesnook/core";
import { EVENTS } from "@notesnook/core";
import { db } from "../common/db";
export type Plan = z.infer<typeof PlanSchema>;
@@ -119,9 +120,12 @@ function Checkout() {
useEffect(() => {
if (currentStep === 2) {
const event = EV.subscribe(EVENTS.userSubscriptionUpdated, () => {
hardNavigate("/notes#/welcome");
});
const event = db.eventManager.subscribe(
EVENTS.userSubscriptionUpdated,
() => {
hardNavigate("/notes#/welcome");
}
);
return () => {
event.unsubscribe();
};

View File

@@ -24,7 +24,8 @@ import {
FeatureResult,
isFeatureAvailable
} from "../utils/index.js";
import { EV, EVENTS } from "@notesnook/core";
import { EVENTS } from "@notesnook/core";
import { database } from "../database.js";
export function useIsFeatureAvailable<TId extends FeatureId>(
id: TId | undefined,
@@ -36,7 +37,7 @@ export function useIsFeatureAvailable<TId extends FeatureId>(
if (!id) return;
isFeatureAvailable(id, value).then((result) => setResult(result));
const userSubscriptionUpdated = EV.subscribe(
const userSubscriptionUpdated = database.eventManager.subscribe(
EVENTS.userSubscriptionUpdated,
() => {
isFeatureAvailable(id, value).then((result) => setResult(result));
@@ -59,7 +60,7 @@ export function useAreFeaturesAvailable<TIds extends FeatureId[]>(
useEffect(() => {
areFeaturesAvailable(ids, values).then((result) => setResult(result));
const userSubscriptionUpdated = EV.subscribe(
const userSubscriptionUpdated = database.eventManager.subscribe(
EVENTS.userSubscriptionUpdated,
() => {
areFeaturesAvailable(ids, values).then((result) => setResult(result));

View File

@@ -30,7 +30,7 @@ import Lookup from "./lookup.js";
import { Content } from "../collections/content.js";
import Backup from "../database/backup.js";
import Hosts from "../utils/constants.js";
import { EV, EVENTS } from "../common.js";
import { EVENTS } from "../common.js";
import { LegacySettings } from "../collections/legacy-settings.js";
import Migrations from "./migrations.js";
import UserManager from "./user-manager.js";
@@ -126,7 +126,11 @@ class Database {
);
return (
this._fs ||
(this._fs = new FileStorage(this.options.fs, this.tokenManager))
(this._fs = new FileStorage(
this.options.fs,
this.tokenManager,
this.eventManager
))
);
};
@@ -191,7 +195,7 @@ class Database {
options!: Options;
eventSource?: EventSource | null;
tokenManager = new TokenManager(this.kv);
tokenManager = new TokenManager(this.kv, this.eventManager);
mfa = new MFAManager(this.tokenManager);
subscriptions = new Subscriptions(this);
circle = new Circle(this);
@@ -293,10 +297,13 @@ class Database {
this.connectSSE,
this
);
EV.subscribe(EVENTS.tokenRefreshed, () => this.connectSSE());
EV.subscribe(EVENTS.attachmentDeleted, async (attachment: Attachment) => {
await this.fs().cancel(attachment.hash);
});
this.eventManager.subscribe(EVENTS.tokenRefreshed, () => this.connectSSE());
this.eventManager.subscribe(
EVENTS.attachmentDeleted,
async (attachment: Attachment) => {
await this.fs().cancel(attachment.hash);
}
);
this.eventManager.subscribe(EVENTS.userLoggedOut, async () => {
await this.monographs.clear();
await this.fs().clear();

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { Cipher } from "@notesnook/crypto";
import Database from "../index.js";
import { CURRENT_DATABASE_VERSION, EV, EVENTS } from "../../common.js";
import { CURRENT_DATABASE_VERSION, EVENTS } from "../../common.js";
import { logger } from "../../logger.js";
import {
SyncItem,
@@ -48,7 +48,7 @@ class Collector {
): AsyncGenerator<SyncTransferItem, void, unknown> {
const key = await this.db.user.getEncryptionKey();
if (!key || !key.key || !key.salt) {
EV.publish(EVENTS.userSessionExpired);
this.db.eventManager.publish(EVENTS.userSessionExpired);
throw new Error("User encryption key not generated. Please relogin.");
}

View File

@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import {
checkSyncStatus,
CURRENT_DATABASE_VERSION,
EV,
EVENTS,
sendSyncProgressEvent,
SYNC_CHECK_IDS
@@ -55,7 +54,6 @@ import {
import { DownloadableFile } from "../../database/fs.js";
import { SyncDevices } from "./devices.js";
import { DefaultColors } from "../../collections/colors.js";
import { Monographs } from "../monographs.js";
enum LogLevel {
/** Log level for very low severity diagnostic messages. */
@@ -103,7 +101,7 @@ export default class SyncManager {
async start(options: SyncOptions) {
try {
if (await checkSyncStatus(SYNC_CHECK_IDS.autoSync))
if (await checkSyncStatus(this.db.eventManager, SYNC_CHECK_IDS.autoSync))
await this.sync.autoSync.start();
await this.sync.start(options);
return true;
@@ -176,7 +174,7 @@ class Sync {
await this.createConnection(options);
if (!this.connection) return;
if (!(await checkSyncStatus(SYNC_CHECK_IDS.sync))) {
if (!(await checkSyncStatus(this.db.eventManager, SYNC_CHECK_IDS.sync))) {
await this.connection.stop();
return;
}
@@ -206,7 +204,9 @@ class Sync {
await this.stop(options);
if (!(await checkSyncStatus(SYNC_CHECK_IDS.autoSync))) {
if (
!(await checkSyncStatus(this.db.eventManager, SYNC_CHECK_IDS.autoSync))
) {
await this.connection.stop();
this.autoSync.stop();
}
@@ -418,7 +418,7 @@ class Sync {
const { HubConnectionBuilder, HttpTransportType, JsonHubProtocol } =
await import("@microsoft/signalr");
const tokenManager = new TokenManager(this.db.kv);
const tokenManager = new TokenManager(this.db.kv, this.db.eventManager);
this.connection = new HubConnectionBuilder()
.withUrl(`${Constants.API_HOST}/hubs/sync/v2`, {
accessTokenFactory: async () => {
@@ -519,7 +519,7 @@ class Sync {
this.logger.error(
new Error("User encryption key not generated. Please relogin.")
);
EV.publish(EVENTS.userSessionExpired);
this.db.eventManager.publish(EVENTS.userSessionExpired);
return;
}
return key;

View File

@@ -19,10 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import http from "../utils/http.js";
import constants from "../utils/constants.js";
import { EV, EVENTS } from "../common.js";
import { EVENTS } from "../common.js";
import { withTimeout, Mutex } from "async-mutex";
import { logger } from "../logger.js";
import { KVStorageAccessor } from "../interfaces.js";
import EventManager from "../utils/event-manager.js";
export type Token = {
access_token: string;
@@ -55,7 +56,10 @@ class TokenManager {
new Error("Timed out while refreshing access token.")
);
constructor(private readonly storage: KVStorageAccessor) {}
constructor(
private readonly storage: KVStorageAccessor,
private readonly eventManager: EventManager
) {}
async getToken(renew = true, forceRenew = false): Promise<Token | undefined> {
const token = await this.storage().read("token");
@@ -92,12 +96,16 @@ class TokenManager {
scopes: Scope[] = ["notesnook.sync", "IdentityServerApi"],
forceRenew = false
) {
return await getSafeToken(async () => {
const token = await this.getToken(true, forceRenew);
if (!token || !token.scope) return;
if (!scopes.some((s) => token.scope.includes(s))) return;
return token.access_token;
}, "Error getting access token:");
return await getSafeToken(
async () => {
const token = await this.getToken(true, forceRenew);
if (!token || !token.scope) return;
if (!scopes.some((s) => token.scope.includes(s))) return;
return token.access_token;
},
"Error getting access token:",
this.eventManager
);
}
async _refreshToken(forceRenew = false) {
@@ -112,7 +120,7 @@ class TokenManager {
const { refresh_token, scope } = token;
if (!refresh_token || !scope) {
EV.publish(EVENTS.userSessionExpired);
this.eventManager.publish(EVENTS.userSessionExpired);
this.logger.error(new Error("Token not found."));
return;
}
@@ -127,7 +135,7 @@ class TokenManager {
}
);
await this.saveToken(refreshTokenResponse);
EV.publish(EVENTS.tokenRefreshed);
this.eventManager.publish(EVENTS.tokenRefreshed);
});
}
@@ -163,7 +171,11 @@ class TokenManager {
}
export default TokenManager;
async function getSafeToken<T>(action: () => Promise<T>, errorMessage: string) {
async function getSafeToken<T>(
action: () => Promise<T>,
errorMessage: string,
eventManager: EventManager
) {
try {
return await action();
} catch (e) {
@@ -172,7 +184,7 @@ async function getSafeToken<T>(action: () => Promise<T>, errorMessage: string) {
e instanceof Error &&
(e.message === "invalid_grant" || e.message === "invalid_client")
) {
EV.publish(EVENTS.userSessionExpired);
eventManager.publish(EVENTS.userSessionExpired);
}
throw e;
}

View File

@@ -46,7 +46,7 @@ class UserManager {
private cachedMonographPasswordsKey?: SerializedKey;
private cachedInboxKeys?: SerializedKeyPair;
constructor(private readonly db: Database) {
this.tokenManager = new TokenManager(this.db.kv);
this.tokenManager = new TokenManager(db.kv, db.eventManager);
EV.subscribe(EVENTS.userUnauthorized, async (url: string) => {
if (url.includes("/connect/token") || !(await HealthCheck.auth())) return;
@@ -80,7 +80,7 @@ class UserManager {
password: hashedPassword,
client_id: "notesnook"
});
EV.publish(EVENTS.userSignedUp);
this.db.eventManager.publish(EVENTS.userSignedUp);
return await this._login({ email, password, hashedPassword });
}

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { Cipher } from "@notesnook/crypto";
import Database from "./index.js";
import { EV, EVENTS } from "../common.js";
import { EVENTS } from "../common.js";
import { isCipher } from "../utils/crypto.js";
import { Note, NoteContent } from "../types.js";
import { logger } from "../logger.js";
@@ -48,7 +48,7 @@ export default class Vault {
}
private startEraser() {
EV.publish(EVENTS.vaultUnlocked);
this.db.eventManager.publish(EVENTS.vaultUnlocked);
clearTimeout(this.erasureTimeout);
this.erasureTimeout = setTimeout(() => {
this.lock();
@@ -80,7 +80,7 @@ export default class Vault {
async lock() {
this.password = undefined;
EV.publish(EVENTS.vaultLocked);
this.db.eventManager.publish(EVENTS.vaultLocked);
return true;
}

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { ICollection } from "./collection.js";
import { getId } from "../utils/id.js";
import { EV, EVENTS } from "../common.js";
import { EVENTS } from "../common.js";
import dataurl from "../utils/dataurl.js";
import dayjs from "dayjs";
import {
@@ -48,7 +48,7 @@ export class Attachments implements ICollection {
db.sanitizer
);
EV.subscribe(
db.eventManager.subscribe(
EVENTS.fileDownloaded,
async ({
success,
@@ -68,7 +68,7 @@ export class Attachments implements ICollection {
const src = await this.read(filename, getOutputType(attachment));
if (!src) return;
EV.publish(EVENTS.mediaAttachmentDownloaded, {
this.db.eventManager.publish(EVENTS.mediaAttachmentDownloaded, {
groupId,
hash: attachment.hash,
attachmentType: getAttachmentType(attachment),
@@ -77,7 +77,7 @@ export class Attachments implements ICollection {
}
);
EV.subscribe(
db.eventManager.subscribe(
EVENTS.fileUploaded,
async ({
success,

View File

@@ -28,11 +28,14 @@ export const SYNC_CHECK_IDS = {
export type SyncStatusEvent = keyof typeof SYNC_CHECK_IDS;
export async function checkSyncStatus(type: string) {
const results = await EV.publishWithResult<{ type: string; result: boolean }>(
EVENTS.syncCheckStatus,
type
);
export async function checkSyncStatus(
eventManager: EventManager,
type: string
) {
const results = await eventManager.publishWithResult<{
type: string;
result: boolean;
}>(EVENTS.syncCheckStatus, type);
if (typeof results === "boolean") return results;
else if (typeof results === "undefined") return true;
return results.some((r) => r.type === type && r.result === true);
@@ -44,23 +47,23 @@ export type SyncProgressEvent = {
};
export function sendSyncProgressEvent(
EV: EventManager,
eventManager: EventManager,
type: string,
current: number
) {
EV.publish(EVENTS.syncProgress, {
eventManager.publish(EVENTS.syncProgress, {
type,
current
} as SyncProgressEvent);
}
export function sendMigrationProgressEvent(
EV: EventManager,
eventManager: EventManager,
collection: string,
total: number,
current?: number
) {
EV.publish(EVENTS.migrationProgress, {
eventManager.publish(EVENTS.migrationProgress, {
collection,
total,
current: current === undefined ? total : current

View File

@@ -24,8 +24,9 @@ import {
IFileStorage
} from "../interfaces.js";
import { DataFormat, SerializedKey } from "@notesnook/crypto";
import { EV, EVENTS } from "../common.js";
import { EVENTS } from "../common.js";
import { logger } from "../logger.js";
import EventManager from "../utils/event-manager.js";
export type FileStorageAccessor = () => FileStorage;
export type DownloadableFile = {
@@ -48,7 +49,8 @@ export class FileStorage {
constructor(
private readonly fs: IFileStorage,
private readonly tokenManager: TokenManager
private readonly tokenManager: TokenManager,
private readonly eventManager: EventManager
) {}
async queueDownloads(
@@ -70,7 +72,7 @@ export class FileStorage {
for (const file of files as QueueItem[]) {
current++;
if (!group.has(file.filename)) {
EV.publish(EVENTS.fileDownloaded, {
this.eventManager.publish(EVENTS.fileDownloaded, {
success: false,
groupId,
filename: file.filename,
@@ -93,7 +95,7 @@ export class FileStorage {
const { filename, chunkSize } = file;
if (await this.exists(filename)) {
EV.publish(EVENTS.fileDownloaded, {
this.eventManager.publish(EVENTS.fileDownloaded, {
success: true,
groupId,
filename,
@@ -104,7 +106,7 @@ export class FileStorage {
continue;
}
EV.publish(EVENTS.fileDownload, {
this.eventManager.publish(EVENTS.fileDownload, {
total,
current,
groupId,
@@ -128,7 +130,7 @@ export class FileStorage {
this.downloads.set(filename, file);
const result = await file.operation;
if (eventData)
EV.publish(EVENTS.fileDownloaded, {
this.eventManager.publish(EVENTS.fileDownloaded, {
success: result,
total,
current,
@@ -180,7 +182,7 @@ export class FileStorage {
group.delete(filename);
});
EV.publish(EVENTS.fileUpload, {
this.eventManager.publish(EVENTS.fileUpload, {
total,
current,
groupId,
@@ -189,7 +191,7 @@ export class FileStorage {
this.uploads.set(filename, file);
const result = await file.operation;
EV.publish(EVENTS.fileUploaded, {
this.eventManager.publish(EVENTS.fileUploaded, {
error,
success: result,
total,
@@ -256,10 +258,16 @@ export class FileStorage {
if (queue.type === "download") {
this.groups.downloads.delete(groupId);
EV.publish(EVENTS.downloadCanceled, { groupId, canceled: true });
this.eventManager.publish(EVENTS.downloadCanceled, {
groupId,
canceled: true
});
} else if (queue.type === "upload") {
this.groups.uploads.delete(groupId);
EV.publish(EVENTS.uploadCanceled, { groupId, canceled: true });
this.eventManager.publish(EVENTS.uploadCanceled, {
groupId,
canceled: true
});
}
}
}