-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpreview-workspace-graph.js
More file actions
90 lines (70 loc) · 1.87 KB
/
preview-workspace-graph.js
File metadata and controls
90 lines (70 loc) · 1.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const normalizeImportSpecifier = value =>
typeof value === 'string' && value.trim().length > 0 ? value.trim() : null
const normalizeGraphEntry = entry => {
if (!entry || typeof entry !== 'object') {
return null
}
if (typeof entry.tabId !== 'string' || entry.tabId.length === 0) {
return null
}
const imports = Array.isArray(entry.imports)
? entry.imports.map(normalizeImportSpecifier).filter(Boolean)
: []
return {
tabId: entry.tabId,
contentHash: typeof entry.contentHash === 'string' ? entry.contentHash : '',
imports,
lastUpdated:
typeof entry.lastUpdated === 'number' && Number.isFinite(entry.lastUpdated)
? entry.lastUpdated
: Date.now(),
}
}
export const createPreviewWorkspaceGraphCache = () => {
const byTabId = new Map()
const upsert = entry => {
const normalized = normalizeGraphEntry(entry)
if (!normalized) {
throw new TypeError('Graph entry is invalid.')
}
byTabId.set(normalized.tabId, normalized)
return normalized
}
const get = tabId => {
if (typeof tabId !== 'string' || tabId.length === 0) {
return null
}
return byTabId.get(tabId) ?? null
}
const getDependents = targetImportSpecifier => {
const normalizedSpecifier = normalizeImportSpecifier(targetImportSpecifier)
if (!normalizedSpecifier) {
return []
}
const dependents = []
for (const entry of byTabId.values()) {
if (entry.imports.includes(normalizedSpecifier)) {
dependents.push(entry)
}
}
return dependents
}
const remove = tabId => {
if (typeof tabId !== 'string' || tabId.length === 0) {
return false
}
return byTabId.delete(tabId)
}
const clear = () => {
byTabId.clear()
}
const list = () => [...byTabId.values()]
return {
upsert,
get,
getDependents,
remove,
clear,
list,
}
}