@pinegrow/vite-plugin 3.0.73-alpha.1 → 3.0.73-alpha.6

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.
@@ -8,14 +8,44 @@ export interface AstroRuntimeBridgeOptions {
8
8
  export interface AstroElCacheEntry {
9
9
  el: Element
10
10
  framework: 'astro'
11
+ entryKind: 'source-node' | 'component-boundary' | 'page-root'
12
+ treeScopes: {
13
+ pageTree: boolean
14
+ appTree: boolean
15
+ }
11
16
  isAstro: true
17
+ isAstroSourceDomEntry: boolean
18
+ isAstroComponent: boolean
19
+ isAppTreeComponent: boolean
20
+ isAstroPageRoot?: boolean
12
21
  sourceId: string
13
- pgId: string
14
- key: string
22
+ pgId: string | null
23
+ key: string | null
15
24
  localFile: string | null
16
25
  sourceFile: string | null
17
26
  nodeType: string | null
18
27
  name: string
28
+ source: {
29
+ id: string
30
+ file: string | null
31
+ range: {
32
+ start: number | null
33
+ end: number | null
34
+ status: string
35
+ }
36
+ nodeType: string | null
37
+ name: string
38
+ }
39
+ component: {
40
+ file: string
41
+ name: string
42
+ kind: string
43
+ } | null
44
+ owners: Array<{
45
+ kind: string
46
+ file: string
47
+ name?: string
48
+ }>
19
49
  sourceRange: {
20
50
  start: number | null
21
51
  end: number | null
@@ -32,11 +62,53 @@ export interface AstroElCacheEntry {
32
62
  isIsland: false
33
63
  rootEl: null
34
64
  firstEl: Element
35
- lastEl: Element
36
- instance: null
65
+ lastEl: Element | null
66
+ instance: {
67
+ uid: string
68
+ isMounted: boolean
69
+ isUnmounted: boolean
70
+ type: {
71
+ __name?: string
72
+ __file?: string | null
73
+ }
74
+ props: Record<string, unknown>
75
+ attrs: Record<string, unknown>
76
+ slots: Record<string, unknown>
77
+ subTree: {
78
+ el: Element
79
+ }
80
+ appContext: unknown
81
+ }
37
82
  vnode: null
38
83
  }
39
84
 
85
+ export type AstroComponentEntry = AstroElCacheEntry & {
86
+ entryKind: 'component-boundary' | 'page-root'
87
+ treeScopes: {
88
+ pageTree: false
89
+ appTree: true
90
+ }
91
+ isAstroSourceDomEntry: false
92
+ isAstroComponent: true
93
+ isAppTreeComponent: true
94
+ pgId: null
95
+ key: null
96
+ localFile: string
97
+ sourceFile: string
98
+ nodeType: 'component-file'
99
+ component: {
100
+ file: string
101
+ name: string
102
+ kind: string
103
+ }
104
+ }
105
+
106
+ export function createAstroComponentEntries(input: {
107
+ entries: AstroElCacheEntry[]
108
+ manifest: unknown
109
+ root?: Document | Element
110
+ }): AstroComponentEntry[]
111
+
40
112
  export function createAstroElCacheEntry(input: {
41
113
  element: Element
42
114
  manifest: unknown
@@ -25,13 +25,20 @@ const createFallbackWatch = (source, callback, options = {}) => {
25
25
  return () => {}
26
26
  }
27
27
 
28
- const createAstroSyntheticInstance = (manifest, node) => ({
28
+ const createAstroSyntheticInstance = (node, element) => ({
29
29
  uid: `astro:${node.id}`,
30
30
  isMounted: true,
31
31
  isUnmounted: false,
32
+ parent: null,
32
33
  type: {
33
34
  __name: node.name || 'AstroElement',
34
- __file: manifest.sourceFile || null,
35
+ __file: null,
36
+ },
37
+ props: {},
38
+ attrs: {},
39
+ slots: {},
40
+ subTree: {
41
+ el: element,
35
42
  },
36
43
  appContext: null,
37
44
  })
@@ -51,6 +58,13 @@ const isMapLike = value =>
51
58
  typeof value.delete === 'function' &&
52
59
  typeof value.entries === 'function'
53
60
 
61
+ const createReactiveMap = (pinegrow, value) => {
62
+ const map = isMapLike(value) ? value : new Map()
63
+ const reactiveFromContext = pinegrow?.reactiveFromContext
64
+
65
+ return typeof reactiveFromContext === 'function' ? reactiveFromContext(map) : map
66
+ }
67
+
54
68
  const getMarkerAttribute = (manifest, options = {}) =>
55
69
  options.markerAttribute || manifest?.marker?.attribute || defaultMarkerAttribute
56
70
 
@@ -58,6 +72,57 @@ const getManifestSourceKey = manifest => manifest?.sourceFile || manifest?.id ||
58
72
 
59
73
  const normalizeElCacheEntries = entries => Array.isArray(entries) ? entries : []
60
74
 
75
+ const normalizePathLike = value => `${value || ''}`.replace(/\\/g, '/')
76
+
77
+ const getBasename = value => {
78
+ if (!value) {
79
+ return ''
80
+ }
81
+
82
+ return normalizePathLike(value).split('/').pop() || ''
83
+ }
84
+
85
+ const isAstroPageSourceFile = sourceFile =>
86
+ /(^|\/)src\/pages\/.+\.astro$/i.test(normalizePathLike(sourceFile))
87
+
88
+ const getRootElement = root => {
89
+ if (!root) {
90
+ return null
91
+ }
92
+
93
+ if (root.documentElement) {
94
+ return root.documentElement
95
+ }
96
+
97
+ if (root.body) {
98
+ return root.body
99
+ }
100
+
101
+ if (root.firstElementChild) {
102
+ return root.firstElementChild
103
+ }
104
+
105
+ return root.nodeType === 1 ? root : null
106
+ }
107
+
108
+ const createAstroComponentSyntheticInstance = (manifest, componentId, element) => ({
109
+ uid: componentId,
110
+ isMounted: true,
111
+ isUnmounted: false,
112
+ parent: null,
113
+ type: {
114
+ __name: getBasename(manifest?.sourceFile) || 'AstroComponent',
115
+ __file: manifest?.sourceFile || null,
116
+ },
117
+ props: {},
118
+ attrs: {},
119
+ slots: {},
120
+ subTree: {
121
+ el: element,
122
+ },
123
+ appContext: null,
124
+ })
125
+
61
126
  const createNodeIndex = manifest => {
62
127
  const index = new Map()
63
128
 
@@ -96,14 +161,31 @@ const createAstroElCacheEntry = ({ element, manifest, node }) => {
96
161
  return {
97
162
  el: element,
98
163
  framework: astroFrameworkKey,
164
+ entryKind: 'source-node',
165
+ treeScopes: {
166
+ pageTree: true,
167
+ appTree: false,
168
+ },
99
169
  isAstro: true,
170
+ isAstroSourceDomEntry: true,
171
+ isAstroComponent: false,
172
+ isAppTreeComponent: false,
100
173
  sourceId: node.id,
101
174
  pgId: node.id,
102
175
  key: node.id,
103
- localFile: manifest.sourceFile || null,
176
+ localFile: null,
104
177
  sourceFile: manifest.sourceFile || null,
105
178
  nodeType: node.type || null,
106
179
  name: node.name || '',
180
+ source: {
181
+ id: node.id,
182
+ file: manifest.sourceFile || null,
183
+ range: sourceRange,
184
+ nodeType: node.type || null,
185
+ name: node.name || '',
186
+ },
187
+ component: null,
188
+ owners: [],
107
189
  sourceRange,
108
190
  sourceStart: sourceRange.start,
109
191
  sourceEnd: sourceRange.end,
@@ -117,11 +199,99 @@ const createAstroElCacheEntry = ({ element, manifest, node }) => {
117
199
  rootEl: null,
118
200
  firstEl: element,
119
201
  lastEl: element,
120
- instance: createAstroSyntheticInstance(manifest, node),
202
+ instance: createAstroSyntheticInstance(node, element),
121
203
  vnode: null,
122
204
  }
123
205
  }
124
206
 
207
+ const createAstroComponentEntry = ({ entries, manifest, root }) => {
208
+ const sourceFile = manifest?.sourceFile
209
+ const rootElement = getRootElement(root)
210
+ const isPageFile = isAstroPageSourceFile(sourceFile)
211
+ const isPageRoot = isPageFile && rootElement
212
+
213
+ if (!sourceFile || (!entries.length && !isPageRoot)) {
214
+ return null
215
+ }
216
+
217
+ const firstEntry = entries[0]
218
+ const lastEntry = entries[entries.length - 1]
219
+ const componentId = `astro-component:${sourceFile}`
220
+ const firstEl = isPageRoot ? rootElement : firstEntry.firstEl || firstEntry.el
221
+ const lastEl = isPageRoot ? null : lastEntry.lastEl || lastEntry.el
222
+ const componentName = getBasename(sourceFile)
223
+ const entryKind = isPageRoot ? 'page-root' : 'component-boundary'
224
+
225
+ return {
226
+ el: firstEl,
227
+ framework: astroFrameworkKey,
228
+ entryKind,
229
+ treeScopes: {
230
+ pageTree: false,
231
+ appTree: true,
232
+ },
233
+ isAstro: true,
234
+ isAstroSourceDomEntry: false,
235
+ isAstroComponent: true,
236
+ isAppTreeComponent: true,
237
+ isAstroPageRoot: Boolean(isPageRoot),
238
+ sourceId: componentId,
239
+ pgId: null,
240
+ key: null,
241
+ localFile: sourceFile,
242
+ sourceFile,
243
+ nodeType: 'component-file',
244
+ name: componentName,
245
+ source: {
246
+ id: componentId,
247
+ file: sourceFile,
248
+ range: {
249
+ start: null,
250
+ end: null,
251
+ status: 'component-file',
252
+ },
253
+ nodeType: 'component-file',
254
+ name: componentName,
255
+ },
256
+ component: {
257
+ file: sourceFile,
258
+ name: componentName,
259
+ kind: isPageFile ? 'page' : 'component',
260
+ },
261
+ owners: [],
262
+ sourceRange: {
263
+ start: null,
264
+ end: null,
265
+ status: 'component-file',
266
+ },
267
+ sourceStart: null,
268
+ sourceEnd: null,
269
+ sourceRangeStatus: 'component-file',
270
+ marker: null,
271
+ editability: {
272
+ mode: 'inspect',
273
+ operations: ['select', 'open-source-file'],
274
+ reasons: ['astro-component-file'],
275
+ },
276
+ attributes: [],
277
+ state: Array.isArray(manifest.state) ? manifest.state : [],
278
+ isFragment: false,
279
+ isRootFragment: false,
280
+ isIsland: false,
281
+ rootEl: null,
282
+ firstEl,
283
+ lastEl,
284
+ instance: createAstroComponentSyntheticInstance(manifest, componentId, firstEl),
285
+ vnode: null,
286
+ }
287
+ }
288
+
289
+ const createAstroComponentEntries = ({ entries, manifest, root }) => {
290
+ const componentEntry = createAstroComponentEntry({ entries, manifest, root })
291
+
292
+ return componentEntry ? [componentEntry] : []
293
+ }
294
+
125
295
  const scanAstroSourceDomMarkers = (root, manifest, options = {}) => {
126
296
  const markerAttribute = getMarkerAttribute(manifest, options)
127
297
  const entries = []
@@ -132,6 +302,7 @@ const scanAstroSourceDomMarkers = (root, manifest, options = {}) => {
132
302
  status: 'unavailable',
133
303
  markerAttribute,
134
304
  entries,
305
+ componentEntries: [],
135
306
  missing,
136
307
  reason: manifest?.reason || 'Astro source manifest is unavailable.',
137
308
  }
@@ -142,6 +313,7 @@ const scanAstroSourceDomMarkers = (root, manifest, options = {}) => {
142
313
  status: 'unavailable',
143
314
  markerAttribute,
144
315
  entries,
316
+ componentEntries: [],
145
317
  missing,
146
318
  reason: 'A DOM root with querySelectorAll() is required.',
147
319
  }
@@ -165,6 +337,7 @@ const scanAstroSourceDomMarkers = (root, manifest, options = {}) => {
165
337
  status: 'ready',
166
338
  markerAttribute,
167
339
  entries,
340
+ componentEntries: createAstroComponentEntries({ entries, manifest, root }),
168
341
  missing,
169
342
  }
170
343
  }
@@ -194,17 +367,16 @@ const ensurePinegrowAstroBridge = (win = getDefaultWindow()) => {
194
367
  win.pinegrow.watchFromContext = createFallbackWatch
195
368
  }
196
369
 
197
- if (!isMapLike(win.pinegrow.elCache)) {
198
- win.pinegrow.elCache = new Map()
199
- }
370
+ win.pinegrow.elCache = createReactiveMap(win.pinegrow, win.pinegrow.elCache)
200
371
 
201
372
  if (!win.pinegrow.astro) {
202
373
  win.pinegrow.astro = {}
203
374
  }
204
375
 
205
- if (!isMapLike(win.pinegrow.astro.sourceManifests)) {
206
- win.pinegrow.astro.sourceManifests = new Map()
207
- }
376
+ win.pinegrow.astro.sourceManifests = createReactiveMap(
377
+ win.pinegrow,
378
+ win.pinegrow.astro.sourceManifests
379
+ )
208
380
 
209
381
  return win.pinegrow
210
382
  }
@@ -283,7 +455,9 @@ const refreshAstroElCache = (manifest, options = {}) => {
283
455
  : removeAstroEntriesForManifest(pinegrow.elCache, manifest)
284
456
  const updatedElements = new Set(removal.elements)
285
457
 
286
- scan.entries.forEach(entry => {
458
+ const cacheEntries = [...scan.entries, ...(scan.componentEntries || [])]
459
+
460
+ cacheEntries.forEach(entry => {
287
461
  upsertAstroEntry(pinegrow.elCache, entry)
288
462
  updatedElements.add(entry.el)
289
463
  })
@@ -302,7 +476,7 @@ const refreshAstroElCache = (manifest, options = {}) => {
302
476
 
303
477
  return {
304
478
  ...scan,
305
- cached: scan.entries.length,
479
+ cached: cacheEntries.length,
306
480
  removed: removal.removed,
307
481
  }
308
482
  }
@@ -318,6 +492,7 @@ const createAstroRuntimeBridge = (manifest, options = {}) => ({
318
492
  })
319
493
 
320
494
  export {
495
+ createAstroComponentEntries,
321
496
  createAstroElCacheEntry,
322
497
  createAstroRuntimeBridge,
323
498
  ensurePinegrowAstroBridge,