aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/workers/crawlerWorker.ts81
-rw-r--r--packages/db/index.ts14
-rw-r--r--packages/trpc/routers/bookmarks.ts50
3 files changed, 80 insertions, 65 deletions
diff --git a/apps/workers/crawlerWorker.ts b/apps/workers/crawlerWorker.ts
index e297c404..c0e1bd1b 100644
--- a/apps/workers/crawlerWorker.ts
+++ b/apps/workers/crawlerWorker.ts
@@ -26,7 +26,7 @@ import StealthPlugin from "puppeteer-extra-plugin-stealth";
import { withTimeout } from "utils";
import type { ZCrawlLinkRequest } from "@hoarder/shared/queues";
-import { db } from "@hoarder/db";
+import { db, HoarderDBTransaction } from "@hoarder/db";
import {
assets,
AssetTypes,
@@ -544,27 +544,20 @@ async function crawlAndParseUrl(
})
.where(eq(bookmarkLinks.id, bookmarkId));
- if (screenshotAssetId) {
- if (oldScreenshotAssetId) {
- await txn.delete(assets).where(eq(assets.id, oldScreenshotAssetId));
- }
- await txn.insert(assets).values({
- id: screenshotAssetId,
- assetType: AssetTypes.LINK_SCREENSHOT,
- bookmarkId,
- });
- }
-
- if (imageAssetId) {
- if (oldImageAssetId) {
- await txn.delete(assets).where(eq(assets.id, oldImageAssetId));
- }
- await txn.insert(assets).values({
- id: imageAssetId,
- assetType: AssetTypes.LINK_BANNER_IMAGE,
- bookmarkId,
- });
- }
+ await updateAsset(
+ screenshotAssetId,
+ oldScreenshotAssetId,
+ bookmarkId,
+ AssetTypes.LINK_SCREENSHOT,
+ txn,
+ );
+ await updateAsset(
+ imageAssetId,
+ oldImageAssetId,
+ bookmarkId,
+ AssetTypes.LINK_BANNER_IMAGE,
+ txn,
+ );
});
// Delete the old assets if any
@@ -587,19 +580,16 @@ async function crawlAndParseUrl(
);
await db.transaction(async (txn) => {
- if (oldFullPageArchiveAssetId) {
- await txn
- .delete(assets)
- .where(eq(assets.id, oldFullPageArchiveAssetId));
- }
- await txn.insert(assets).values({
- id: fullPageArchiveAssetId,
- assetType: AssetTypes.LINK_FULL_PAGE_ARCHIVE,
+ await updateAsset(
+ fullPageArchiveAssetId,
+ oldFullPageArchiveAssetId,
bookmarkId,
- });
+ AssetTypes.LINK_FULL_PAGE_ARCHIVE,
+ txn,
+ );
});
if (oldFullPageArchiveAssetId) {
- deleteAsset({ userId, assetId: oldFullPageArchiveAssetId }).catch(
+ await deleteAsset({ userId, assetId: oldFullPageArchiveAssetId }).catch(
() => ({}),
);
}
@@ -673,3 +663,30 @@ async function runCrawler(job: Job<ZCrawlLinkRequest, void>) {
// Do the archival as a separate last step as it has the potential for failure
await archivalLogic();
}
+
+/**
+ * Removes the old asset and adds a new one instead
+ * @param newAssetId the new assetId to add
+ * @param oldAssetId the old assetId to remove (if it exists)
+ * @param bookmarkId the id of the bookmark the asset belongs to
+ * @param assetType the type of the asset
+ * @param txn the transaction where this update should happen in
+ */
+async function updateAsset(
+ newAssetId: string | null,
+ oldAssetId: string | undefined,
+ bookmarkId: string,
+ assetType: AssetTypes,
+ txn: HoarderDBTransaction,
+) {
+ if (newAssetId) {
+ if (oldAssetId) {
+ await txn.delete(assets).where(eq(assets.id, oldAssetId));
+ }
+ await txn.insert(assets).values({
+ id: newAssetId,
+ assetType,
+ bookmarkId,
+ });
+ }
+}
diff --git a/packages/db/index.ts b/packages/db/index.ts
index 433d8db2..b86665d2 100644
--- a/packages/db/index.ts
+++ b/packages/db/index.ts
@@ -1,3 +1,17 @@
+import Database from "better-sqlite3";
+import { ExtractTablesWithRelations } from "drizzle-orm";
+import { SQLiteTransaction } from "drizzle-orm/sqlite-core";
+
+import * as schema from "./schema";
+
export { db } from "./drizzle";
export * as schema from "./schema";
export { SqliteError } from "better-sqlite3";
+
+// This is exported here to avoid leaking better-sqlite types outside of this package.
+export type HoarderDBTransaction = SQLiteTransaction<
+ "sync",
+ Database.RunResult,
+ typeof schema,
+ ExtractTablesWithRelations<typeof schema>
+>;
diff --git a/packages/trpc/routers/bookmarks.ts b/packages/trpc/routers/bookmarks.ts
index 2175f704..8644bbcf 100644
--- a/packages/trpc/routers/bookmarks.ts
+++ b/packages/trpc/routers/bookmarks.ts
@@ -73,39 +73,23 @@ export const ensureBookmarkOwnership = experimental_trpcMiddleware<{
return opts.next();
});
-function assetTypeToBookmarkField(
- asset:
- | {
- id: string;
- assetType: AssetTypes;
- }
- | undefined,
-) {
- if (!asset) {
- return undefined;
- }
- switch (asset.assetType) {
- case AssetTypes.LINK_SCREENSHOT:
- return { screenshotAssetId: asset.id };
- case AssetTypes.LINK_FULL_PAGE_ARCHIVE:
- return { fullPageArchiveAssetId: asset.id };
- case AssetTypes.LINK_BANNER_IMAGE:
- return { imageAssetId: asset.id };
- }
+interface Asset {
+ id: string;
+ assetType: AssetTypes;
}
-function getBookmarkAssets(assets: { id: string; assetType: AssetTypes }[]) {
- return {
- ...assetTypeToBookmarkField(
- assets.find((a) => a.assetType == AssetTypes.LINK_SCREENSHOT),
- ),
- ...assetTypeToBookmarkField(
- assets.find((a) => a.assetType == AssetTypes.LINK_FULL_PAGE_ARCHIVE),
- ),
- ...assetTypeToBookmarkField(
- assets.find((a) => a.assetType == AssetTypes.LINK_BANNER_IMAGE),
- ),
- };
+const ASSET_TYE_MAPPING: Record<AssetTypes, string> = {
+ [AssetTypes.LINK_SCREENSHOT]: "screenshotAssetId",
+ [AssetTypes.LINK_FULL_PAGE_ARCHIVE]: "fullPageArchiveAssetId",
+ [AssetTypes.LINK_BANNER_IMAGE]: "imageAssetId",
+};
+
+function mapAssetsToBookmarkFields(assets: Asset | Asset[] = []) {
+ const assetsArray = Array.isArray(assets) ? assets : [assets];
+ return assetsArray.reduce((result: Record<string, string>, asset: Asset) => {
+ result[ASSET_TYE_MAPPING[asset.assetType]] = asset.id;
+ return result;
+ }, {});
}
async function getBookmark(ctx: AuthedContext, bookmarkId: string) {
@@ -196,7 +180,7 @@ function toZodSchema(bookmark: BookmarkQueryReturnType): ZBookmark {
if (link) {
content = {
type: "link",
- ...getBookmarkAssets(assets),
+ ...mapAssetsToBookmarkFields(assets),
...link,
};
} else if (text) {
@@ -616,7 +600,7 @@ export const bookmarksAppRouter = router({
if (row.assets) {
acc[bookmarkId].content = {
...acc[bookmarkId].content,
- ...assetTypeToBookmarkField(row.assets),
+ ...mapAssetsToBookmarkFields(row.assets),
};
}