refactor(mobile): move service to database package (#3817)

This commit is contained in:
Stephen Zhou 2025-05-26 15:56:23 +08:00 committed by GitHub
parent 6923d0e773
commit 94bb3afef8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 236 additions and 202 deletions

View File

@ -2,7 +2,7 @@ import { persistQueryClient } from "@tanstack/react-query-persist-client"
import { kvStoragePersister, queryClient } from "../lib/query-client"
export { hydrateDatabaseToStore } from "../services"
export { hydrateDatabaseToStore } from "../store"
export const hydrateSettings = () => {}
export const hydrateQueryClient = () => {
persistQueryClient({

View File

@ -1,30 +0,0 @@
import { db } from "@follow/database/src/db"
import { feedsTable } from "@follow/database/src/schemas"
import type { FeedSchema } from "@follow/database/src/schemas/types"
import { feedActions } from "../store/feed/store"
import type { Hydratable, Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class FeedServiceStatic implements Hydratable, Resetable {
async reset() {
await db.delete(feedsTable).execute()
}
async upsertMany(feed: FeedSchema[]) {
if (feed.length === 0) return
await db
.insert(feedsTable)
.values(feed)
.onConflictDoUpdate({
target: [feedsTable.id],
set: conflictUpdateAllExcept(feedsTable, ["id"]),
})
}
async hydrate() {
const feeds = await db.query.feedsTable.findMany()
feedActions.upsertManyInSession(feeds)
}
}
export const FeedService = new FeedServiceStatic()

View File

@ -1,28 +0,0 @@
import { CollectionService } from "./collection"
import { EntryService } from "./entry"
import { FeedService } from "./feed"
import { ImagesService } from "./image"
import { InboxService } from "./inbox"
import type { Hydratable } from "./internal/base"
import { ListService } from "./list"
import { SubscriptionService } from "./subscription"
import { TranslationService } from "./translation"
import { UnreadService } from "./unread"
import { UserService } from "./user"
const hydrates: Hydratable[] = [
FeedService,
SubscriptionService,
InboxService,
ListService,
UnreadService,
UserService,
EntryService,
CollectionService,
ImagesService,
TranslationService,
]
export const hydrateDatabaseToStore = async () => {
await Promise.all(hydrates.map((h) => h.hydrate()))
}

View File

@ -1,9 +1,10 @@
import type { FeedViewType } from "@follow/constants"
import type { CollectionSchema } from "@follow/database/src/schemas/types"
import { CollectionService } from "@follow/database/src/services/collection"
import { apiClient } from "@/src/lib/api-fetch"
import { CollectionService } from "@/src/services/collection"
import type { Hydratable } from "../internal/base"
import { createTransaction, createZustandStore } from "../internal/helper"
interface CollectionState {
@ -81,7 +82,12 @@ class CollectionSyncService {
}
}
class CollectionActions {
class CollectionActions implements Hydratable {
async hydrate() {
const collections = await CollectionService.getCollectionAll()
collectionActions.upsertManyInSession(collections)
}
async upsertManyInSession(collections: CollectionSchema[]) {
const state = useCollectionStore.getState()
const nextCollections: CollectionState["collections"] = {

View File

@ -1,16 +1,18 @@
import { FeedViewType } from "@follow/constants"
import { EntryService } from "@follow/database/src/services/entry"
import { debounce } from "es-toolkit/compat"
import { fetch as expoFetch } from "expo/fetch"
import { getGeneralSettings } from "@/src/atoms/settings/general"
import { apiClient } from "@/src/lib/api-fetch"
import { getCookie } from "@/src/lib/auth"
import { dbStoreMorph } from "@/src/morph/db-store"
import { honoMorph } from "@/src/morph/hono"
import { storeDbMorph } from "@/src/morph/store-db"
import { EntryService } from "@/src/services/entry"
import { collectionActions } from "../collection/store"
import { feedActions } from "../feed/store"
import type { Hydratable } from "../internal/base"
import { createImmerSetter, createTransaction, createZustandStore } from "../internal/helper"
import { getSubscription } from "../subscription/getter"
import { getDefaultCategory } from "../subscription/utils"
@ -56,7 +58,16 @@ export const useEntryStore = createZustandStore<EntryState>("entry")(() => defau
const immerSet = createImmerSetter(useEntryStore)
class EntryActions {
class EntryActions implements Hydratable {
async hydrate() {
const entries = await EntryService.getEntryAll()
const { unreadOnly } = getGeneralSettings()
entryActions.upsertManyInSession(
entries.map((e) => dbStoreMorph.toEntryModel(e)),
{ unreadOnly },
)
}
private addEntryIdToView({
draft,
feedId,

View File

@ -1,8 +1,9 @@
import type { FeedSchema } from "@follow/database/src/schemas/types"
import { FeedService } from "@follow/database/src/services/feed"
import { apiClient } from "@/src/lib/api-fetch"
import { FeedService } from "@/src/services/feed"
import type { Hydratable } from "../internal/base"
import { createImmerSetter, createTransaction, createZustandStore } from "../internal/helper"
import type { FeedModel } from "./types"
@ -18,7 +19,12 @@ const set = useFeedStore.setState
const immerSet = createImmerSetter(useFeedStore)
// const get = useFeedStore.getState
// const distanceTime = 1000 * 60 * 60 * 9
class FeedActions {
class FeedActions implements Hydratable {
async hydrate() {
const feeds = await FeedService.getFeedAll()
feedActions.upsertManyInSession(feeds)
}
clear() {
set({ feeds: {} })
}

View File

@ -1,8 +1,8 @@
import type { ImageSchema } from "@follow/database/src/schemas/types"
import { ImagesService } from "@follow/database/src/services/image"
import ImageColors from "react-native-image-colors"
import { ImagesService } from "@/src/services/image"
import type { Hydratable } from "../internal/base"
import { createImmerSetter, createTransaction, createZustandStore } from "../internal/helper"
import { getImageInfo } from "./getters"
@ -33,7 +33,12 @@ class ImageSyncService {
}
}
class ImageActions {
class ImageActions implements Hydratable {
async hydrate() {
const images = await ImagesService.getImageAll()
imageActions.upsertManyInSession(images)
}
upsertManyInSession(images: ImageModel[]) {
immerSet((state) => {
for (const image of images) {

View File

@ -1,7 +1,7 @@
import type { InboxSchema } from "@follow/database/src/schemas/types"
import { InboxService } from "@follow/database/src/services/inbox"
import { InboxService } from "@/src/services/inbox"
import type { Hydratable } from "../internal/base"
import { createTransaction, createZustandStore } from "../internal/helper"
interface InboxState {
@ -16,7 +16,11 @@ export const useInboxStore = createZustandStore<InboxState>("inbox")(() => defau
// const get = useInboxStore.getState
const set = useInboxStore.setState
class InboxActions {
class InboxActions implements Hydratable {
async hydrate() {
const inboxes = await InboxService.getInbox()
inboxActions.upsertManyInSession(inboxes)
}
async upsertManyInSession(inboxes: InboxSchema[]) {
const state = useInboxStore.getState()
const nextInboxes: InboxState["inboxes"] = {

View File

@ -0,0 +1,29 @@
import { collectionActions } from "./collection/store"
import { entryActions } from "./entry/store"
import { feedActions } from "./feed/store"
import { imageActions } from "./image/store"
import { inboxActions } from "./inbox/store"
import type { Hydratable } from "./internal/base"
import { listActions } from "./list/store"
import { subscriptionActions } from "./subscription/store"
import { translationActions } from "./translation/store"
import { unreadActions } from "./unread/store"
import { userActions } from "./user/store"
/// keep-sorted
const hydrates: Hydratable[] = [
collectionActions,
entryActions,
feedActions,
imageActions,
inboxActions,
listActions,
subscriptionActions,
translationActions,
unreadActions,
userActions,
]
export const hydrateDatabaseToStore = async () => {
await Promise.all(hydrates.map((h) => h.hydrate()))
}

View File

@ -1,7 +1,3 @@
export interface Hydratable {
hydrate: () => Promise<void>
}
export interface Resetable {
reset: () => Promise<void>
}

View File

@ -1,11 +1,12 @@
import type { ListSchema } from "@follow/database/src/schemas/types"
import { ListService } from "@follow/database/src/services/list"
import { apiClient } from "@/src/lib/api-fetch"
import { honoMorph } from "@/src/morph/hono"
import { storeDbMorph } from "@/src/morph/store-db"
import { ListService } from "@/src/services/list"
import { feedActions } from "../feed/store"
import type { Hydratable } from "../internal/base"
import { createImmerSetter, createTransaction, createZustandStore } from "../internal/helper"
import { getList } from "./getters"
import type { CreateListModel } from "./types"
@ -29,7 +30,17 @@ export const useListStore = createZustandStore<ListState>("list")(() => defaultS
const get = useListStore.getState
const set = useListStore.setState
const immerSet = createImmerSetter(useListStore)
class ListActions {
class ListActions implements Hydratable {
async hydrate() {
const lists = await ListService.getListAll()
listActions.upsertManyInSession(
lists.map((list) => ({
...list,
feedIds: JSON.parse(list.feedIds || "[]") as string[],
})),
)
}
upsertManyInSession(lists: ListModel[]) {
const state = get()

View File

@ -1,15 +1,17 @@
import { FeedViewType } from "@follow/constants"
import type { SubscriptionSchema } from "@follow/database/src/schemas/types"
import { SubscriptionService } from "@follow/database/src/services/subscription"
import { tracker } from "@follow/tracker"
import { apiClient } from "@/src/lib/api-fetch"
import { toast } from "@/src/lib/toast"
import { dbStoreMorph } from "@/src/morph/db-store"
import { honoMorph } from "@/src/morph/hono"
import { buildSubscriptionDbId, storeDbMorph } from "@/src/morph/store-db"
import { SubscriptionService } from "@/src/services/subscription"
import { feedActions } from "../feed/store"
import { inboxActions } from "../inbox/store"
import type { Hydratable } from "../internal/base"
import { createImmerSetter, createTransaction, createZustandStore } from "../internal/helper"
import { listActions } from "../list/store"
import { whoami } from "../user/getters"
@ -66,7 +68,13 @@ export const useSubscriptionStore = createZustandStore<SubscriptionState>("subsc
const get = useSubscriptionStore.getState
const immerSet = createImmerSetter(useSubscriptionStore)
class SubscriptionActions {
class SubscriptionActions implements Hydratable {
async hydrate() {
const subscriptions = await SubscriptionService.getSubscriptionAll()
subscriptionActions.upsertManyInSession(
subscriptions.map((s) => dbStoreMorph.toSubscriptionModel(s)),
)
}
async upsertManyInSession(subscriptions: SubscriptionModel[]) {
immerSet((draft) => {
for (const subscription of subscriptions) {

View File

@ -1,8 +1,8 @@
import type { SummarySchema } from "@follow/database/src/schemas/types"
import { summaryService } from "@follow/database/src/services/summary"
import { getActionLanguage } from "@/src/atoms/settings/general"
import { apiClient } from "@/src/lib/api-fetch"
import { summaryService } from "@/src/services/summary"
import { getEntry } from "../entry/getter"
import { createImmerSetter, createZustandStore } from "../internal/helper"

View File

@ -1,11 +1,12 @@
import type { TranslationSchema } from "@follow/database/src/schemas/types"
import { TranslationService } from "@follow/database/src/services/translation"
import { apiClient } from "@/src/lib/api-fetch"
import type { SupportedLanguages } from "@/src/lib/language"
import { checkLanguage } from "@/src/lib/translation"
import { TranslationService } from "@/src/services/translation"
import { getEntry } from "../entry/getter"
import type { Hydratable } from "../internal/base"
import { createImmerSetter, createZustandStore } from "../internal/helper"
import type { EntryTranslation, TranslationFieldArray } from "./types"
import { translationFields } from "./types"
@ -24,7 +25,12 @@ export const useTranslationStore = createZustandStore<TranslationState>("transla
const get = useTranslationStore.getState
const immerSet = createImmerSetter(useTranslationStore)
class TranslationActions {
class TranslationActions implements Hydratable {
async hydrate() {
const translations = await TranslationService.getTranslationAll()
translationActions.upsertManyInSession(translations)
}
upsertManyInSession(translations: TranslationModel[]) {
translations.forEach((translation) => {
immerSet((state) => {

View File

@ -1,14 +1,15 @@
import type { FeedViewType } from "@follow/constants"
import type { UnreadSchema } from "@follow/database/src/schemas/types"
import { EntryService } from "@follow/database/src/services/entry"
import { UnreadService } from "@follow/database/src/services/unread"
import { getGeneralSettings } from "@/src/atoms/settings/general"
import { apiClient } from "@/src/lib/api-fetch"
import { setBadgeCountAsyncWithPermission } from "@/src/lib/permission"
import { EntryService } from "@/src/services/entry"
import { UnreadService } from "@/src/services/unread"
import { getEntry } from "../entry/getter"
import { entryActions } from "../entry/store"
import type { Hydratable } from "../internal/base"
import { createTransaction, createZustandStore } from "../internal/helper"
import { getListFeedIds } from "../list/getters"
import { getSubscriptionByView } from "../subscription/getter"
@ -185,7 +186,11 @@ class UnreadSyncService {
}
}
class UnreadActions {
class UnreadActions implements Hydratable {
async hydrate() {
const unreads = await UnreadService.getUnreadAll()
unreadActions.upsertManyInSession(unreads)
}
upsertManyInSession(unreads: UnreadSchema[], options?: UnreadUpdateOptions) {
const state = useUnreadStore.getState()
const nextData = options?.reset ? {} : { ...state.data }

View File

@ -1,13 +1,14 @@
import { UserRole } from "@follow/constants"
import type { UserSchema } from "@follow/database/src/schemas/types"
import { UserService } from "@follow/database/src/services/user"
import type { AuthSession } from "@follow/shared"
import { apiClient } from "@/src/lib/api-fetch"
import { changeEmail, sendVerificationEmail, twoFactor, updateUser } from "@/src/lib/auth"
import { toast } from "@/src/lib/toast"
import { honoMorph } from "@/src/morph/hono"
import { UserService } from "@/src/services/user"
import type { Hydratable } from "../internal/base"
import { createImmerSetter, createTransaction, createZustandStore } from "../internal/helper"
import type { UserProfileEditable } from "./types"
@ -171,7 +172,11 @@ class UserSyncService {
}
}
class UserActions {
class UserActions implements Hydratable {
async hydrate() {
const users = await UserService.getUserAll()
userActions.upsertManyInSession(users)
}
upsertManyInSession(users: UserModel[]) {
immerSet((state) => {
for (const user of users) {

View File

@ -1,13 +1,12 @@
import { db } from "@follow/database/src/db"
import { collectionsTable } from "@follow/database/src/schemas"
import type { CollectionSchema } from "@follow/database/src/schemas/types"
import { eq, inArray } from "drizzle-orm"
import { collectionActions } from "../store/collection/store"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { collectionsTable } from "../schemas"
import type { CollectionSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class CollectionServiceStatic implements Hydratable, Resetable {
class CollectionServiceStatic implements Resetable {
async reset() {
await db.delete(collectionsTable).execute()
}
@ -31,9 +30,8 @@ class CollectionServiceStatic implements Hydratable, Resetable {
return db.query.collectionsTable.findMany({ where: inArray(collectionsTable.entryId, entryId) })
}
async hydrate() {
const collections = await db.query.collectionsTable.findMany()
collectionActions.upsertManyInSession(collections)
getCollectionAll() {
return db.query.collectionsTable.findMany()
}
}

View File

@ -1,16 +1,17 @@
import { db } from "@follow/database/src/db"
import { entriesTable } from "@follow/database/src/schemas"
import type { EntrySchema } from "@follow/database/src/schemas/types"
import { and, between, eq, inArray, or } from "drizzle-orm"
import { getGeneralSettings } from "../atoms/settings/general"
import { dbStoreMorph } from "../morph/db-store"
import { entryActions } from "../store/entry/store"
import type { PublishAtTimeRangeFilter } from "../store/unread/types"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { entriesTable } from "../schemas"
import type { EntrySchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class EntryServiceStatic implements Hydratable, Resetable {
interface PublishAtTimeRangeFilter {
startTime: number
endTime: number
}
class EntryServiceStatic implements Resetable {
async reset() {
await db.delete(entriesTable).execute()
}
@ -59,13 +60,8 @@ class EntryServiceStatic implements Hydratable, Resetable {
return db.query.entriesTable.findMany({ where: inArray(entriesTable.id, entryId) })
}
async hydrate() {
const entries = await db.query.entriesTable.findMany()
const { unreadOnly } = getGeneralSettings()
entryActions.upsertManyInSession(
entries.map((e) => dbStoreMorph.toEntryModel(e)),
{ unreadOnly },
)
getEntryAll() {
return db.query.entriesTable.findMany()
}
}

View File

@ -0,0 +1,27 @@
import { db } from "../db"
import { feedsTable } from "../schemas"
import type { FeedSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class FeedServiceStatic implements Resetable {
async reset() {
await db.delete(feedsTable).execute()
}
async upsertMany(feed: FeedSchema[]) {
if (feed.length === 0) return
await db
.insert(feedsTable)
.values(feed)
.onConflictDoUpdate({
target: [feedsTable.id],
set: conflictUpdateAllExcept(feedsTable, ["id"]),
})
}
getFeedAll() {
return db.query.feedsTable.findMany()
}
}
export const FeedService = new FeedServiceStatic()

View File

@ -1,19 +1,13 @@
import { db } from "@follow/database/src/db"
import { imagesTable } from "@follow/database/src/schemas"
import type { ImageSchema } from "@follow/database/src/schemas/types"
import { imageActions } from "../store/image/store"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { imagesTable } from "../schemas"
import type { ImageSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class ImageServiceStatic implements Hydratable, Resetable {
class ImageServiceStatic implements Resetable {
async reset() {
await db.delete(imagesTable).execute()
}
async hydrate() {
const images = await db.query.imagesTable.findMany()
imageActions.upsertManyInSession(images)
}
async upsertMany(imageColors: ImageSchema[]) {
if (imageColors.length === 0) return
@ -25,6 +19,10 @@ class ImageServiceStatic implements Hydratable, Resetable {
set: conflictUpdateAllExcept(imagesTable, ["url"]),
})
}
async getImageAll() {
return db.query.imagesTable.findMany()
}
}
export const ImagesService = new ImageServiceStatic()

View File

@ -1,22 +1,16 @@
import { db } from "@follow/database/src/db"
import { inboxesTable } from "@follow/database/src/schemas"
import type { InboxSchema } from "@follow/database/src/schemas/types"
import { inboxActions } from "../store/inbox/store"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { inboxesTable } from "../schemas"
import type { InboxSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class InboxServiceStatic implements Hydratable, Resetable {
class InboxServiceStatic implements Resetable {
async reset() {
await db.delete(inboxesTable).execute()
}
async getInbox(): Promise<InboxSchema[]> {
return await db.select().from(inboxesTable)
}
async hydrate() {
const inboxes = await db.query.inboxesTable.findMany()
inboxActions.upsertManyInSession(inboxes)
}
async upsertMany(inboxes: InboxSchema[]) {
if (inboxes.length === 0) return

View File

@ -0,0 +1,3 @@
export interface Resetable {
reset: () => Promise<void>
}

View File

@ -1,25 +1,16 @@
import { db } from "@follow/database/src/db"
import { listsTable } from "@follow/database/src/schemas"
import type { ListSchema } from "@follow/database/src/schemas/types"
import { eq } from "drizzle-orm"
import { listActions } from "../store/list/store"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { listsTable } from "../schemas"
import type { ListSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class ListServiceStatic implements Hydratable, Resetable {
class ListServiceStatic implements Resetable {
async reset() {
await db.delete(listsTable).execute()
}
async hydrate() {
const lists = await db.query.listsTable.findMany()
listActions.upsertManyInSession(
lists.map((list) => ({
...list,
feedIds: JSON.parse(list.feedIds || "[]") as string[],
})),
)
}
async upsertMany(lists: ListSchema[]) {
if (lists.length === 0) return
await db
@ -34,6 +25,10 @@ class ListServiceStatic implements Hydratable, Resetable {
async deleteList(params: { listId: string }) {
await db.delete(listsTable).where(eq(listsTable.id, params.listId))
}
getListAll() {
return db.query.listsTable.findMany()
}
}
export const ListService = new ListServiceStatic()

View File

@ -1,19 +1,16 @@
import type { FeedViewType } from "@follow/constants/src/enums"
import { db } from "@follow/database/src/db"
import {
feedsTable,
inboxesTable,
listsTable,
subscriptionsTable,
} from "@follow/database/src/schemas"
import type { SubscriptionSchema } from "@follow/database/src/schemas/types"
import type { FeedViewType } from "@follow/constants"
import { and, eq, inArray, notInArray, sql } from "drizzle-orm"
import { dbStoreMorph } from "../morph/db-store"
import { subscriptionActions } from "../store/subscription/store"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { feedsTable, inboxesTable, listsTable, subscriptionsTable } from "../schemas"
import type { SubscriptionSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
class SubscriptionServiceStatic implements Resetable {
getSubscriptionAll() {
return db.query.subscriptionsTable.findMany()
}
class SubscriptionServiceStatic implements Hydratable, Resetable {
async reset() {
await db.delete(subscriptionsTable).execute()
}
@ -42,12 +39,6 @@ class SubscriptionServiceStatic implements Hydratable, Resetable {
.set(subscription)
.where(eq(subscriptionsTable.id, subscription.id))
}
async hydrate() {
const subscriptions = await db.query.subscriptionsTable.findMany()
subscriptionActions.upsertManyInSession(
subscriptions.map((s) => dbStoreMorph.toSubscriptionModel(s)),
)
}
async deleteNotExists(existsIds: string[], view?: FeedViewType) {
const notExistsIds = await db.query.subscriptionsTable.findMany({

View File

@ -1,8 +1,9 @@
import { db } from "@follow/database/src/db"
import { summariesTable } from "@follow/database/src/schemas"
import type { SummarySchema } from "@follow/database/src/schemas/types"
import { eq } from "drizzle-orm"
import { db } from "../db"
import { summariesTable } from "../schemas"
import type { SummarySchema } from "../schemas/types"
class SummaryServiceStatic {
async insertSummary(data: Omit<SummarySchema, "createdAt">) {
const updateExceptEmpty = Object.fromEntries(

View File

@ -1,16 +1,15 @@
import { db } from "@follow/database/src/db"
import { translationsTable } from "@follow/database/src/schemas"
import type { TranslationSchema } from "@follow/database/src/schemas/types"
import { eq } from "drizzle-orm"
import { translationActions } from "../store/translation/store"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { translationsTable } from "../schemas"
import type { TranslationSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
class TranslationServiceStatic implements Hydratable, Resetable {
async hydrate() {
const translations = await db.query.translationsTable.findMany()
translationActions.upsertManyInSession(translations)
class TranslationServiceStatic implements Resetable {
getTranslationAll() {
return db.query.translationsTable.findMany()
}
async reset() {
await db.delete(translationsTable).execute()
}

View File

@ -1,19 +1,20 @@
import { db } from "@follow/database/src/db"
import { unreadTable } from "@follow/database/src/schemas"
import type { UnreadSchema } from "@follow/database/src/schemas/types"
import { unreadActions } from "../store/unread/store"
import type { UnreadUpdateOptions } from "../store/unread/types"
import type { Hydratable, Resetable } from "./internal/base"
import { db } from "../db"
import { unreadTable } from "../schemas"
import type { UnreadSchema } from "../schemas/types"
import type { Resetable } from "./internal/base"
import { conflictUpdateAllExcept } from "./internal/utils"
class UnreadServiceStatic implements Hydratable, Resetable {
interface UnreadUpdateOptions {
reset?: boolean
}
class UnreadServiceStatic implements Resetable {
async reset() {
await db.delete(unreadTable).execute()
}
async hydrate() {
const unreads = await db.query.unreadTable.findMany()
unreadActions.upsertManyInSession(unreads)
async getUnreadAll() {
return db.query.unreadTable.findMany()
}
async upsertMany(unreads: UnreadSchema[], options?: UnreadUpdateOptions) {

View File

@ -1,13 +1,15 @@
import { db } from "@follow/database/src/db"
import { usersTable } from "@follow/database/src/schemas"
import type { UserSchema } from "@follow/database/src/schemas/types"
import { eq } from "drizzle-orm"
import { userActions } from "../store/user/store"
import type { Hydratable } from "./internal/base"
import { db } from "../db"
import { usersTable } from "../schemas"
import type { UserSchema } from "../schemas/types"
import { conflictUpdateAllExcept } from "./internal/utils"
class UserServiceStatic implements Hydratable {
class UserServiceStatic {
getUserAll() {
return db.query.usersTable.findMany()
}
async upsertMany(users: UserSchema[]) {
await db
.insert(usersTable)
@ -18,11 +20,6 @@ class UserServiceStatic implements Hydratable {
})
}
async hydrate() {
const users = await db.query.usersTable.findMany()
userActions.upsertManyInSession(users)
}
async removeCurrentUser() {
await db.update(usersTable).set({ isMe: false }).where(eq(usersTable.isMe, true))
}