Skip to content

Commit

Permalink
fix(dx): reload page if store circular import detected
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <[email protected]>
  • Loading branch information
Innei committed Oct 24, 2024
1 parent ab43626 commit f60fc6f
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 62 deletions.
6 changes: 1 addition & 5 deletions apps/renderer/src/store/entry/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { imageActions } from "../image"
import { inboxActions } from "../inbox"
import { getSubscriptionByFeedId } from "../subscription"
import { feedUnreadActions } from "../unread"
import { createZustandStore, doMutationAndTransaction, reloadWhenHotUpdate } from "../utils/helper"
import { createZustandStore, doMutationAndTransaction } from "../utils/helper"
import { internal_batchMarkRead } from "./helper"
import type { EntryState, FlatEntryModel } from "./types"

Expand Down Expand Up @@ -479,7 +479,3 @@ class EntryActions {
export const entryActions = new EntryActions()

export const getEntry = (entryId: string) => useEntryStore.getState().flatMapEntries[entryId]

if (import.meta.env.DEV) {
reloadWhenHotUpdate(import.meta.hot)
}
6 changes: 1 addition & 5 deletions apps/renderer/src/store/feed/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { FeedService } from "~/services"

import { getSubscriptionByFeedId } from "../subscription"
import { userActions } from "../user"
import { createZustandStore, reloadWhenHotUpdate } from "../utils/helper"
import { createZustandStore } from "../utils/helper"
import type { FeedQueryParams, FeedState } from "./types"

export const useFeedStore = createZustandStore<FeedState>("feed")(() => ({
Expand Down Expand Up @@ -151,7 +151,3 @@ export const getPreferredTitle = (
const subscription = getSubscriptionByFeedId(feed.id)
return subscription?.title || feed.title
}

if (import.meta.env.DEV) {
reloadWhenHotUpdate(import.meta.hot)
}
6 changes: 1 addition & 5 deletions apps/renderer/src/store/inbox/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { runTransactionInScope } from "~/database"
import { apiClient } from "~/lib/api-fetch"
import { InboxService } from "~/services/inbox"

import { createImmerSetter, createZustandStore, reloadWhenHotUpdate } from "../utils/helper"
import { createImmerSetter, createZustandStore } from "../utils/helper"
import type { InboxState } from "./types"

export const useInboxStore = createZustandStore<InboxState>("inbox")(() => ({
Expand Down Expand Up @@ -70,7 +70,3 @@ class InboxActionStatic {
}

export const inboxActions = new InboxActionStatic()

if (import.meta.env.DEV) {
reloadWhenHotUpdate(import.meta.hot)
}
6 changes: 1 addition & 5 deletions apps/renderer/src/store/list/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { apiClient } from "~/lib/api-fetch"
import { ListService } from "~/services/list"

import { feedActions } from "../feed"
import { createImmerSetter, createZustandStore, reloadWhenHotUpdate } from "../utils/helper"
import { createImmerSetter, createZustandStore } from "../utils/helper"
import type { ListState } from "./types"

export const useListStore = createZustandStore<ListState>("list")(() => ({
Expand Down Expand Up @@ -98,7 +98,3 @@ class ListActionStatic {
}

export const listActions = new ListActionStatic()

if (import.meta.env.DEV) {
reloadWhenHotUpdate(import.meta.hot)
}
11 changes: 1 addition & 10 deletions apps/renderer/src/store/subscription/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@ import { feedActions, getFeedById } from "../feed"
import { inboxActions } from "../inbox"
import { listActions } from "../list"
import { feedUnreadActions } from "../unread"
import {
createImmerSetter,
createZustandStore,
doMutationAndTransaction,
reloadWhenHotUpdate,
} from "../utils/helper"
import { createImmerSetter, createZustandStore, doMutationAndTransaction } from "../utils/helper"
import { subscriptionCategoryExistSelector } from "./selector"

export type SubscriptionFlatModel = Omit<SubscriptionModel, "feeds"> & {
Expand Down Expand Up @@ -508,7 +503,3 @@ export const isListSubscription = (feedId?: FeedId) => {

export const subscriptionCategoryExist = (name: string) =>
subscriptionCategoryExistSelector(name)(get())

if (import.meta.env.DEV) {
reloadWhenHotUpdate(import.meta.hot)
}
6 changes: 1 addition & 5 deletions apps/renderer/src/store/unread/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { FeedViewType } from "@follow/constants"
import { apiClient } from "~/lib/api-fetch"
import { FeedUnreadService } from "~/services"

import { createZustandStore, reloadWhenHotUpdate } from "../utils/helper"
import { createZustandStore } from "../utils/helper"

interface UnreadState {
data: Record<string, number>
Expand Down Expand Up @@ -108,7 +108,3 @@ class FeedUnreadActions {
}

export const feedUnreadActions = new FeedUnreadActions()

if (import.meta.env.DEV) {
reloadWhenHotUpdate(import.meta.hot)
}
6 changes: 1 addition & 5 deletions apps/renderer/src/store/user/store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { UserModel } from "@follow/models/types"
import { produce } from "immer"

import { createZustandStore, reloadWhenHotUpdate } from "../utils/helper"
import { createZustandStore } from "../utils/helper"

interface UserStoreState {
users: Record<string, UserModel>
Expand Down Expand Up @@ -48,7 +48,3 @@ class UserActions {
}

export const userActions = new UserActions()

if (import.meta.env.DEV) {
reloadWhenHotUpdate(import.meta.hot)
}
8 changes: 0 additions & 8 deletions apps/renderer/src/store/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,3 @@ export function createImmerSetter<T>(useStore: UseBoundStore<StoreApi<T>>) {
}),
)
}

export const reloadWhenHotUpdate = (hot: any) => {
if (hot) {
hot.accept(() => {
window.location.reload()
})
}
}
58 changes: 44 additions & 14 deletions plugins/vite/hmr.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,59 @@
import { red, yellow } from "kolorist"
import type { HmrContext, Plugin } from "vite"

function hasCircularDependency(mod: any, server: any, visited = new Set()): boolean {
if (visited.has(mod.id)) return true
visited.add(mod.id)
function isNodeWithinCircularImports(
node: any,
nodeChain: any[],
currentChain: any[] = [node],
traversedModules = new Set<any>(),
): boolean {
if (traversedModules.has(node)) {
return false
}
traversedModules.add(node)

for (const importer of node.importers) {
if (importer === node) continue

const importers = server.moduleGraph.getModulesByFile(mod.file) || new Set()
for (const importer of importers) {
if (hasCircularDependency(importer, server, new Set(visited))) {
const importerIndex = nodeChain.indexOf(importer)
if (importerIndex !== -1) {
const importChain = [
importer,
...[...currentChain].reverse(),
...nodeChain.slice(importerIndex, -1).reverse(),
]
console.warn(
yellow(`Circular imports detected: ${importChain.map((m) => m.file).join(" -> ")}`),
)
return true
}
}

if (!currentChain.includes(importer)) {
const result = isNodeWithinCircularImports(
importer,
nodeChain,
currentChain.concat(importer),
traversedModules,
)
if (result) return result
}
}
return false
}

export const circularImportRefreshPlugin = (): Plugin => ({
name: "circular-import-refresh",
handleHotUpdate({ file, server }: HmrContext) {
if (file.includes("store")) {
const mod = server.moduleGraph.getModuleById(file)
if (mod && hasCircularDependency(mod, server)) {
console.warn(`Circular dependency detected in ${file}. Performing full page refresh.`)
server.ws.send({ type: "full-reload" })
return []
}
const mod = server.moduleGraph.getModuleById(file)
if (mod && isNodeWithinCircularImports(mod, [mod])) {
console.error(
red(
`Circular dependency detected in ${file} involving store files. Performing full page refresh.`,
),
)

server.ws.send({ type: "full-reload" })
return []
}
},
})

0 comments on commit f60fc6f

Please sign in to comment.