Skip to content

Commit 0e77278

Browse files
committed
fix: watch files change, more logs
1 parent 5831f54 commit 0e77278

8 files changed

Lines changed: 66 additions & 18 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import type { Uri } from 'vscode'
2+
import { SUPPORTED_DOCUMENT_PATTERN } from '#constants'
3+
import { isSupportedDependencyDocument } from '#extractors'
4+
import { logger } from '#state'
5+
import { getWorkspaceContextState } from '#utils/workspace'
6+
import { useActiveTextEditor, useDocumentText, useFileSystemWatcher, watch } from 'reactive-vscode'
7+
import { workspace } from 'vscode'
8+
9+
export function useWorkspaceContext() {
10+
workspace.onDidChangeWorkspaceFolders(({ removed }) => {
11+
removed.forEach((folder) => {
12+
getWorkspaceContextState.delete(folder.uri)
13+
logger.info(`[workspace-context] delete workspace folder cache: ${folder.uri.path}`)
14+
})
15+
})
16+
17+
async function deleteCacheByUri(uri: Uri) {
18+
const ctx = await getWorkspaceContextState(uri)
19+
if (!ctx)
20+
return
21+
22+
ctx.loadPackageManifestInfo.delete(uri)
23+
ctx.loadWorkspaceCatalogInfo.delete(uri)
24+
logger.info(`[workspace-context] delete cache: ${uri.path}`)
25+
}
26+
27+
const activeEditor = useActiveTextEditor()
28+
const activeDocumentText = useDocumentText(() => activeEditor.value?.document)
29+
30+
watch(activeDocumentText, async () => {
31+
const document = activeEditor.value?.document
32+
if (!document || !isSupportedDependencyDocument(document))
33+
return
34+
35+
deleteCacheByUri(document.uri)
36+
}, { flush: 'pre' })
37+
38+
const { onDidChange, onDidDelete } = useFileSystemWatcher(SUPPORTED_DOCUMENT_PATTERN)
39+
40+
onDidChange(deleteCacheByUri)
41+
onDidDelete(deleteCacheByUri)
42+
}

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useWorkspaceContext } from '#composables/workspace-context'
12
import { defineExtension, useCommands } from 'reactive-vscode'
23
import { openFileInNpmx } from './commands/open-file-in-npmx'
34
import { openInBrowser } from './commands/open-in-browser'
@@ -12,6 +13,8 @@ import { logger } from './state'
1213
export const { activate, deactivate } = defineExtension(() => {
1314
logger.info(`${displayName} Activated, v${version}`)
1415

16+
useWorkspaceContext()
17+
1518
useDiagnostics()
1619
useCodeActions()
1720
useHover()

src/providers/completion-item/version.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { CompletionItemProvider, Position, TextDocument } from 'vscode'
22
import { PRERELEASE_PATTERN } from '#constants'
33
import { config } from '#state'
4-
import { getPackageInfo } from '#utils/api/package'
54
import { offsetRangeToRange } from '#utils/ast'
65
import { formatUpgradeVersion } from '#utils/version'
76
import { getResolvedDependencyByOffset } from '#utils/workspace'
@@ -17,7 +16,7 @@ export class VersionCompletionItemProvider implements CompletionItemProvider {
1716
if (info.resolvedProtocol !== 'npm')
1817
return
1918

20-
const pkg = await getPackageInfo(info.resolvedName)
19+
const pkg = await info.packageInfo()
2120
if (!pkg)
2221
return
2322

src/providers/diagnostics/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { config, logger } from '#state'
88
import { offsetRangeToRange } from '#utils/ast'
99
import { getResolvedDependencies } from '#utils/workspace'
1010
import { debounce } from 'perfect-debounce'
11-
import { computed, useActiveTextEditor, useDisposable, useDocumentText, useFileSystemWatcher, watch } from 'reactive-vscode'
11+
import { computed, nextTick, useActiveTextEditor, useDisposable, useDocumentText, useFileSystemWatcher, watch } from 'reactive-vscode'
1212
import { languages, TabInputText, window, workspace } from 'vscode'
1313
import { displayName } from '../../generated-meta'
1414
import { checkDeprecation } from './rules/deprecation'
@@ -57,6 +57,7 @@ export function useDiagnostics() {
5757
}
5858

5959
async function collectDiagnostics(document: TextDocument) {
60+
await nextTick()
6061
logger.info(`[diagnostics] collect: ${document.uri.path}`)
6162
diagnosticCollection.set(document.uri, [])
6263

src/providers/document-link/npmx.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import type { DocumentLink, DocumentLinkProvider, TextDocument } from 'vscode'
2-
import { config } from '#state'
2+
import { config, logger } from '#state'
33
import { offsetRangeToRange } from '#utils/ast'
44
import { npmxPackageUrl } from '#utils/links'
55
import { getResolvedDependencies } from '#utils/workspace'
66
import { Uri, DocumentLink as VscodeDocumentLink } from 'vscode'
77

88
export class NpmxDocumentLinkProvider implements DocumentLinkProvider {
99
async provideDocumentLinks(document: TextDocument): Promise<DocumentLink[]> {
10+
logger.info('[document-link] set document links')
1011
const dependencies = await getResolvedDependencies(document.uri)
1112
if (!dependencies)
1213
return []

src/utils/memoize.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type MemoizeReturn<R> = R extends Promise<infer V> ? Promise<V | undefined> : R
2020

2121
export interface MemoizedFunction<P, V> {
2222
(params: P): MemoizeReturn<V>
23-
deleteByKey: (key: MemoizeKey) => void
23+
delete: (params: P) => void
2424
}
2525

2626
export function memoize<P, V>(fn: (params: P) => V, options: MemoizeOptions<P> = {}): MemoizedFunction<P, V> {
@@ -77,12 +77,6 @@ export function memoize<P, V>(fn: (params: P) => V, options: MemoizeOptions<P> =
7777
})
7878
}
7979

80-
function deleteByKey(key: MemoizeKey): void {
81-
cache.delete(key)
82-
pending.delete(key)
83-
versions.set(key, getVersion(key) + 1)
84-
}
85-
8680
const cachedFn = function cachedFn(params: P) {
8781
const key = getKey(params)
8882
const keyVersion = getVersion(key)
@@ -121,7 +115,12 @@ export function memoize<P, V>(fn: (params: P) => V, options: MemoizeOptions<P> =
121115
}
122116
} as MemoizedFunction<P, V>
123117

124-
cachedFn.deleteByKey = deleteByKey
118+
cachedFn.delete = (p: P) => {
119+
const key = getKey(p)
120+
cache.delete(key)
121+
pending.delete(key)
122+
versions.set(key, getVersion(key) + 1)
123+
}
125124

126125
return cachedFn
127126
}

src/utils/workspace.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ function createResolvedDependencyInfo(
4242
catalogs?: CatalogsInfo,
4343
): ResolvedDependencyInfo {
4444
const resolution = resolveDependencySpec(dependency.rawName, dependency.rawSpec, catalogs)
45+
4546
const packageInfo = lazyInit(
46-
() => resolution.resolvedProtocol === 'npm'
47-
? getPackageInfo(resolution.resolvedName).then((pkg) => pkg ?? null)
48-
: Promise.resolve(null),
47+
async () => resolution.resolvedProtocol === 'npm'
48+
? await getPackageInfo(resolution.resolvedName) ?? null
49+
: null,
4950
)
5051

5152
return {
@@ -75,6 +76,7 @@ export const getWorkspaceContextState = memoize<Uri, Promise<WorkspaceContextSta
7576

7677
const loadWorkspaceCatalogInfo = memoize(async (uri: Uri): Promise<WithResolvedDependencyInfo<WorkspaceCatalogInfo> | undefined> => {
7778
const path = uri.path
79+
logger.info(`[workspace-context] load workspace catalog info: ${path}`)
7880

7981
for (const entry of workspaceCatalogExtractorEntries) {
8082
if (!path.endsWith(`/${entry.basename}`))
@@ -91,7 +93,7 @@ export const getWorkspaceContextState = memoize<Uri, Promise<WorkspaceContextSta
9193
dependencies: info.dependencies.map((dependency) => createResolvedDependencyInfo(dependency)),
9294
}
9395
}
94-
}, { ttl: false, maxSize: Number.POSITIVE_INFINITY, fallbackToCachedOnError: false })
96+
}, { getKey: (uri) => uri.path, ttl: false, maxSize: Number.POSITIVE_INFINITY, fallbackToCachedOnError: false })
9597

9698
let catalogs: CatalogsInfo | undefined
9799

@@ -115,6 +117,7 @@ export const getWorkspaceContextState = memoize<Uri, Promise<WorkspaceContextSta
115117
if (!isPackageManifestPath(uri.path))
116118
return
117119

120+
logger.info(`[workspace-context] load package manifest info: ${uri.path}`)
118121
const text = await getDocumentText(uri)
119122

120123
const info = packageManifestExtractorEntry.extractor.getPackageManifestInfo(text)
@@ -125,7 +128,7 @@ export const getWorkspaceContextState = memoize<Uri, Promise<WorkspaceContextSta
125128
...info,
126129
dependencies: info.dependencies.map((dependency) => createResolvedDependencyInfo(dependency, catalogs)),
127130
}
128-
}, { ttl: false, maxSize: Number.POSITIVE_INFINITY, fallbackToCachedOnError: false }),
131+
}, { getKey: (uri) => uri.path, ttl: false, maxSize: Number.POSITIVE_INFINITY, fallbackToCachedOnError: false }),
129132
loadWorkspaceCatalogInfo,
130133
}
131134
}, {

tests/utils/memoize.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ describe('memoize', () => {
115115
const memoized = memoize(fn, { ttl: 0 })
116116

117117
const stalePromise = memoized('key')
118-
memoized.deleteByKey('key')
118+
memoized.delete('key')
119119
const freshPromise = memoized('key')
120120

121121
expect(fn).toHaveBeenCalledTimes(2)

0 commit comments

Comments
 (0)