@nuasite/cms 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -0
- package/dist/editor.js +10967 -10736
- package/package.json +1 -1
- package/src/collection-scanner.ts +203 -29
- package/src/dev-middleware.ts +86 -45
- package/src/editor/components/collections-browser.tsx +3 -11
- package/src/editor/components/create-page-modal.tsx +22 -10
- package/src/editor/components/fields.tsx +30 -8
- package/src/editor/components/frontmatter-fields.tsx +22 -4
- package/src/editor/components/link-edit-popover.tsx +232 -0
- package/src/editor/components/markdown-editor-overlay.tsx +16 -12
- package/src/editor/components/markdown-inline-editor.tsx +25 -52
- package/src/editor/components/mdx-block-view.tsx +21 -17
- package/src/editor/components/prop-editor.tsx +10 -5
- package/src/editor/hooks/useLinkPopover.ts +64 -0
- package/src/editor/milkdown-utils.ts +21 -0
- package/src/field-types.ts +111 -27
- package/src/handlers/api-routes.ts +10 -16
- package/src/index.ts +2 -0
- package/src/manifest-writer.ts +15 -0
- package/src/types.ts +19 -0
- package/src/vite-plugin.ts +18 -72
- package/src/content-invalidator.ts +0 -134
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vite SSR module cache invalidation + content-sync coordination.
|
|
3
|
-
*
|
|
4
|
-
* Astro's content layer chain (chokidar → glob loader → syncData → data store
|
|
5
|
-
* → fs.watch → invalidateModule) is racy and unreliable under several conditions:
|
|
6
|
-
*
|
|
7
|
-
* - Native fs.watch on Linux dies after the first atomic rename of the watched
|
|
8
|
-
* file (Astro writes data-store.json via writeFile-tmp + rename).
|
|
9
|
-
* - Vite's bundled chokidar 3.6.0 misses the same atomic-write events.
|
|
10
|
-
* - `invalidateModule(astro:data-layer-content)` alone does not propagate up
|
|
11
|
-
* the import graph, so route modules that already cached `getCollection`
|
|
12
|
-
* references keep returning stale data.
|
|
13
|
-
*
|
|
14
|
-
* This module exposes two things:
|
|
15
|
-
*
|
|
16
|
-
* - `invalidateContentCache(server)` — walks the SSR module graph from
|
|
17
|
-
* `astro:data-layer-content` upward and invalidates every transitive
|
|
18
|
-
* importer, then broadcasts `full-reload` to the client.
|
|
19
|
-
* - `notifyContentStoreUpdated` / `awaitNextContentStoreUpdate` — a shared
|
|
20
|
-
* rendezvous between the fs.watch plugin (which observes data-store.json
|
|
21
|
-
* writes) and the CMS API middleware (which needs to hold the HTTP
|
|
22
|
-
* response until the store is fresh). Keeps invalidation on a single path.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
interface SsrModuleNode {
|
|
26
|
-
id: string | null
|
|
27
|
-
importers: Set<SsrModuleNode>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface SsrModuleGraph {
|
|
31
|
-
getModuleById(id: string): SsrModuleNode | undefined
|
|
32
|
-
invalidateModule(
|
|
33
|
-
mod: SsrModuleNode,
|
|
34
|
-
seen?: Set<SsrModuleNode>,
|
|
35
|
-
timestamp?: number,
|
|
36
|
-
isHmr?: boolean,
|
|
37
|
-
): void
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface SsrEnvironment {
|
|
41
|
-
moduleGraph: SsrModuleGraph
|
|
42
|
-
hot: { send: (event: string, data?: unknown) => void }
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interface ClientEnvironment {
|
|
46
|
-
hot: { send: (payload: { type: string; path: string }) => void }
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface ViteServerLike {
|
|
50
|
-
environments: { ssr: SsrEnvironment; client: ClientEnvironment }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Astro exposes the content data store as a virtual module whose resolved id
|
|
54
|
-
// is `\0astro:data-layer-content` (see astro/dist/content/consts.js). Earlier
|
|
55
|
-
// versions of this file used `\0astro:data-store`, which does not exist and
|
|
56
|
-
// silently reduced `invalidateContentCache` to a no-op full-reload broadcast.
|
|
57
|
-
const DATA_STORE_VIRTUAL_ID = '\0astro:data-layer-content'
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Invalidate the SSR `astro:data-layer-content` virtual module and every
|
|
61
|
-
* module that (transitively) imports it. After this returns, the next request
|
|
62
|
-
* that imports any of these modules will re-execute and read fresh content.
|
|
63
|
-
*
|
|
64
|
-
* Also broadcasts `full-reload` so any connected browser refreshes.
|
|
65
|
-
*/
|
|
66
|
-
export function invalidateContentCache(server: ViteServerLike): void {
|
|
67
|
-
const ssr = server.environments.ssr
|
|
68
|
-
const dataStoreMod = ssr.moduleGraph.getModuleById(DATA_STORE_VIRTUAL_ID)
|
|
69
|
-
if (dataStoreMod) {
|
|
70
|
-
const seen = new Set<SsrModuleNode>()
|
|
71
|
-
const ts = Date.now()
|
|
72
|
-
const walk = (mod: SsrModuleNode) => {
|
|
73
|
-
if (seen.has(mod)) return
|
|
74
|
-
seen.add(mod)
|
|
75
|
-
ssr.moduleGraph.invalidateModule(mod, seen, ts, true)
|
|
76
|
-
for (const importer of mod.importers) {
|
|
77
|
-
walk(importer)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
walk(dataStoreMod)
|
|
81
|
-
}
|
|
82
|
-
ssr.hot.send('astro:content-changed', {})
|
|
83
|
-
server.environments.client.hot.send({ type: 'full-reload', path: '*' })
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// ---------------------------------------------------------------------------
|
|
87
|
-
// Content-sync rendezvous
|
|
88
|
-
// ---------------------------------------------------------------------------
|
|
89
|
-
//
|
|
90
|
-
// The CMS API middleware writes a content file and then needs to hold the HTTP
|
|
91
|
-
// response until Astro has actually re-synced the data store — otherwise the
|
|
92
|
-
// browser reloads into a stale render. The fs.watch plugin is the component
|
|
93
|
-
// that observes the data-store.json write, so it is also the component that
|
|
94
|
-
// resolves these waiters.
|
|
95
|
-
|
|
96
|
-
type StoreUpdateResolver = () => void
|
|
97
|
-
const pendingStoreUpdateWaiters = new Set<StoreUpdateResolver>()
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Called by the data-store fs.watch plugin after it has invalidated the SSR
|
|
101
|
-
* module cache in response to a data-store.json write. Wakes every middleware
|
|
102
|
-
* caller currently parked in `awaitNextContentStoreUpdate`.
|
|
103
|
-
*/
|
|
104
|
-
export function notifyContentStoreUpdated(): void {
|
|
105
|
-
if (pendingStoreUpdateWaiters.size === 0) return
|
|
106
|
-
const resolvers = Array.from(pendingStoreUpdateWaiters)
|
|
107
|
-
pendingStoreUpdateWaiters.clear()
|
|
108
|
-
for (const resolve of resolvers) resolve()
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Park until the next data-store.json write has been fully processed (store
|
|
113
|
-
* reloaded on disk, SSR module graph invalidated). Resolves with `true` on
|
|
114
|
-
* success or `false` if the timeout elapses first — callers should treat
|
|
115
|
-
* timeout as "best-effort, proceed anyway".
|
|
116
|
-
*
|
|
117
|
-
* The timeout fallback exists because some edits legitimately do not change
|
|
118
|
-
* the data store (e.g. whitespace-only edits are skipped by Astro's atomic
|
|
119
|
-
* write comparator), in which case no fs.watch event will ever fire.
|
|
120
|
-
*/
|
|
121
|
-
export function awaitNextContentStoreUpdate(timeoutMs: number): Promise<boolean> {
|
|
122
|
-
return new Promise((resolve) => {
|
|
123
|
-
const resolver = () => {
|
|
124
|
-
clearTimeout(timer)
|
|
125
|
-
pendingStoreUpdateWaiters.delete(resolver)
|
|
126
|
-
resolve(true)
|
|
127
|
-
}
|
|
128
|
-
const timer = setTimeout(() => {
|
|
129
|
-
pendingStoreUpdateWaiters.delete(resolver)
|
|
130
|
-
resolve(false)
|
|
131
|
-
}, timeoutMs)
|
|
132
|
-
pendingStoreUpdateWaiters.add(resolver)
|
|
133
|
-
})
|
|
134
|
-
}
|