@pinegrow/vite-plugin 3.0.0-beta.134 → 3.0.0-beta.136

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/dist/vue/index.js CHANGED
@@ -1,298 +1,298 @@
1
- import { onBeforeMount, onMounted, onBeforeUnmount, getCurrentInstance, ref, reactive, computed, onUpdated } from 'vue'
2
-
3
- export function usePinegrow() {
4
- const initCache = () => {
5
- // conditional
6
- const winObj = window
7
-
8
- if (!(winObj?.process?.client && winObj.process.client !== true)) {
9
- if (!winObj.pinegrow) {
10
- // conditional
11
- // console.log('Cache initialized by Pinegrow Vue Plugin!')
12
- const elCache = reactive(new Map())
13
-
14
- const enrichWithComponentName = (elCacheObj, localFile) => {
15
- return {
16
- name: elCacheObj.instance.type.__name || '',
17
- localFile,
18
- ...elCacheObj,
19
- }
20
- }
21
-
22
- winObj.pinegrow = {
23
- elCache,
24
- // // Uncomment these two to test locally
25
- // elCacheErrHandlerFn,
26
- // elUpdateHanderFn,
27
- // rootFragmentToPgIdComputed,
28
- // pgIdToElComputed,
29
- // localComponentToElComputed,
30
- // appTree,
31
- }
32
- }
33
- }
34
- }
35
-
36
- // pgId & key can be optional
37
- const pgUpdateElCache = (hook, pgId, rootEl, key, localFile) => async vnode => {
38
- if (!vnode) return
39
- if (window?.process?.client && process?.client !== true) return
40
- if (!window.pinegrow) initCache()
41
-
42
- let el = vnode.el
43
-
44
- const instance = vnode.component || vnode.ctx || el.__vueParentComponent
45
-
46
- if (!el || !instance) return
47
-
48
- try {
49
- if ((key !== null && key !== undefined) || (vnode.key !== null && vnode.key !== undefined)) {
50
- key = vnode.key || key
51
- }
52
-
53
- localFile = localFile || vnode.type.__file
54
-
55
- let isRootFragment = false
56
- let isFragment = el.nodeType !== 1
57
- let firstEl,
58
- lastEl,
59
- isIsland = false,
60
- childVNodes = []
61
-
62
- // May be an iles Island that wraps components with client directives
63
- if (localFile) {
64
- if (localFile.includes('node_modules/iles') && localFile.includes('Island.vue')) {
65
- // Retain localFiles of iles island to apply to child elements
66
- isIsland = true
67
- }
68
-
69
- if (localFile.includes('node_modules')) {
70
- // Ignore SFCs from node_modules
71
- localFile = null
72
- }
73
- }
74
-
75
- const localFileFromInstance = instance.type.__file
76
- if (
77
- localFileFromInstance &&
78
- localFileFromInstance.includes('node_modules/iles') &&
79
- localFileFromInstance.includes('Island.vue')
80
- ) {
81
- // Retain localFiles of iles island to apply to child elements
82
- isIsland = true
83
-
84
- localFile = instance.props.component?.__file || instance.props.importFrom
85
- }
86
-
87
- // // Computed props anyway filters out unmounted ones, and we use the local components unmounted hooks to cleanup unmounted nodes. Using the unmounted hook seems to be out of sync when el is reused but instance is remounted.
88
- // if (hook === 'unmounted') {
89
- // if (pinegrow.elCache.has(el)) {
90
- // pinegrow.elCache.delete(el)
91
- // }
92
- // for (let [key, value] of pinegrow.elCache.entries()) {
93
- // if (value.rootEl === rootEl) {
94
- // pinegrow.elCache.delete(key)
95
- // }
96
- // }
97
- // return
98
- // }
99
-
100
- // Text/comment node
101
- if (isFragment) {
102
- if (!rootEl) {
103
- // root Fragment
104
- isRootFragment = true
105
- }
106
-
107
- function isFragmentEl(instance) {
108
- // return appRecord.options.types.Fragment === instance.subTree?.type
109
- return instance.subTree.el.nodeType !== 1
110
- }
111
-
112
- function getRootVNodesFromComponentInstance(instance) {
113
- if (isFragmentEl(instance)) {
114
- return getFragmentRootVNodes(instance.subTree)
115
- }
116
- if (!instance.subTree) return []
117
- return [instance.subTree]
118
- }
119
-
120
- function getFragmentRootVNodes(vnode) {
121
- if (!vnode.children) return []
122
- // children is v-if when the vnode has a condition
123
- if (!Array.isArray(vnode.children)) return []
124
-
125
- const list = []
126
-
127
- for (let i = 0, l = vnode.children.length; i < l; i++) {
128
- const childVnode = vnode.children[i]
129
- if (childVnode.component) {
130
- list.push(...getRootVNodesFromComponentInstance(childVnode.component))
131
- } else if (childVnode) {
132
- list.push(childVnode)
133
- }
134
- }
135
-
136
- return list
137
- }
138
-
139
- childVNodes = getRootVNodesFromComponentInstance(instance)
140
-
141
- if (!childVNodes.length) {
142
- // For NuxtLayout, no childVNodes are returned, the subTree.children is in fact an object {ctx: {}, default: f}
143
- if (el.nextElementSibling) {
144
- const childEl = el.nextElementSibling
145
- firstEl = lastEl = childEl
146
- const childInstance = childEl.$ || childEl.__vueParentComponent
147
- const childVNode = childInstance?.vnode // or subTree?
148
- if (childVNode) {
149
- childVNodes.push(childVNode)
150
- }
151
- }
152
- }
153
-
154
- if (childVNodes.length) {
155
- // Filter out recursive vnodes text1 -> div, text1 (happens when text1 is the closest to a fragment with div & slot)
156
- childVNodes = childVNodes.filter(childVNode => childVNode.el !== el)
157
-
158
- if (childVNodes.length) {
159
- if (childVNodes.length === 1) {
160
- firstEl = lastEl = childVNodes[0].el
161
- } else {
162
- firstEl = childVNodes[0].el
163
- lastEl = childVNodes[childVNodes.length - 1].el
164
- }
165
-
166
- if (firstEl && firstEl.nodeType !== 1) {
167
- firstEl = firstEl.nextElementSibling
168
- }
169
- if (lastEl && lastEl.nodeType !== 1) {
170
- lastEl = lastEl.nextElementSibling
171
- }
172
- }
173
- }
174
- }
175
-
176
- if (isIsland && !isRootFragment) {
177
- return
178
- }
179
-
180
- let elCacheObj = {
181
- el,
182
- isRootFragment,
183
- rootEl,
184
- vnode,
185
- instance,
186
- isFragment,
187
- firstEl,
188
- lastEl,
189
- pgId,
190
- key,
191
- localFile,
192
- isIsland,
193
- }
194
-
195
- let prevElCacheNodes = pinegrow.elCache.get(el)
196
-
197
- if (prevElCacheNodes) {
198
- let index = prevElCacheNodes.findIndex(elCacheObj => elCacheObj.instance.uid === instance.uid)
199
-
200
- if (index > -1) {
201
- const prevElCacheObj = prevElCacheNodes[index]
202
- elCacheObj.localFile = elCacheObj.localFile || prevElCacheObj.localFile
203
- elCacheObj.pgId = elCacheObj.pgId || prevElCacheObj.pgId
204
- prevElCacheNodes[index] = elCacheObj
205
- } else {
206
- prevElCacheNodes.push(elCacheObj)
207
- }
208
- pinegrow.elCache.set(el, prevElCacheNodes)
209
- } else {
210
- pinegrow.elCache.set(el, [elCacheObj])
211
- childVNodes.forEach(childVNode => {
212
- pgUpdateElCache(hook, pgId, isRootFragment ? el : rootEl, key)(childVNode)
213
- })
214
- }
215
-
216
- if (pinegrow.elUpdateHanderFn) {
217
- pinegrow.elUpdateHanderFn(el)
218
- }
219
- } catch (err) {
220
- console.log(err)
221
- if (pinegrow.elCacheErrHandlerFn) {
222
- pinegrow.elCacheErrHandlerFn(vnode, hook, rootEl, pgId, key, el, instance, err.message)
223
- }
224
- }
225
- }
226
-
227
- const elUpdateHanderFn = el => {
228
- // if (pinegrow.elCache.has(el)) {
229
- // const { pgId } = pinegrow.elCache.get(el)
230
- // if (pgId) {
231
- // // console.log(`Reselect ${pgId}`)
232
- // }
233
- // }
234
- }
235
-
236
- const elCacheErrHandlerFn = () => {
237
- if (message) {
238
- // console.log(message)
239
- }
240
- }
241
-
242
- const cleanupCache = () => {
243
- // for (let [key, value] of pinegrow.elCache.entries()) {
244
- // if (value.isFragment && !value.firstEl) {
245
- // console.log(value)
246
- // }
247
- // }
248
- for (let [el, elCacheNodes] of pinegrow.elCache.entries()) {
249
- // if (!el.isConnected) {
250
- // pinegrow.elCache.delete(el)
251
- // continue
252
- // }
253
- const cleanedUpElCacheNodes = elCacheNodes.filter(
254
- elCacheObj => !elCacheObj.instance.isUnmounted // || elCacheObj.localFile
255
- )
256
- if (cleanedUpElCacheNodes.length) {
257
- if (cleanedUpElCacheNodes.length !== elCacheNodes.length) {
258
- pinegrow.elCache.set(el, cleanedUpElCacheNodes)
259
- }
260
- } else {
261
- pinegrow.elCache.delete(el)
262
- }
263
- }
264
- }
265
-
266
- // Local Component
267
- const rootVNode = ref(null)
268
-
269
- const mountLocalComponent = () => {
270
- const instance = getCurrentInstance()
271
- const vnode = instance?.vnode
272
- const el = vnode?.el
273
- const localFile = instance.type.__file && !instance.type.__file.includes('node_modules') && instance.type.__file
274
- if (instance && vnode && el) {
275
- rootVNode.value = vnode
276
- pgUpdateElCache('mounted', null, null, null, localFile)(vnode)
277
- }
278
- }
279
-
280
- const unmountLocalComponent = () => {
281
- if (rootVNode.value) {
282
- pgUpdateElCache('unmounted')(rootVNode.value)
283
- }
284
- cleanupCache()
285
- }
286
-
287
- onBeforeMount(() => initCache())
288
- onMounted(() => {
289
- mountLocalComponent()
290
- })
291
- onBeforeUnmount(() => unmountLocalComponent())
292
- onUpdated(() => {
293
- mountLocalComponent()
294
- })
295
-
296
- return { pgUpdateElCache }
297
- }
298
-
1
+ import { onBeforeMount, onMounted, onBeforeUnmount, getCurrentInstance, ref, reactive, computed, onUpdated } from 'vue'
2
+
3
+ export function usePinegrow() {
4
+ const initCache = () => {
5
+ // conditional
6
+ const winObj = window
7
+
8
+ if (!(winObj?.process?.client && winObj.process.client !== true)) {
9
+ if (!winObj.pinegrow) {
10
+ // conditional
11
+ // console.log('Cache initialized by Pinegrow Vue Plugin!')
12
+ const elCache = reactive(new Map())
13
+
14
+ const enrichWithComponentName = (elCacheObj, localFile) => {
15
+ return {
16
+ name: elCacheObj.instance.type.__name || '',
17
+ localFile,
18
+ ...elCacheObj,
19
+ }
20
+ }
21
+
22
+ winObj.pinegrow = {
23
+ elCache,
24
+ // // Uncomment these two to test locally
25
+ // elCacheErrHandlerFn,
26
+ // elUpdateHanderFn,
27
+ // rootFragmentToPgIdComputed,
28
+ // pgIdToElComputed,
29
+ // localComponentToElComputed,
30
+ // appTree,
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ // pgId & key can be optional
37
+ const pgUpdateElCache = (hook, pgId, rootEl, key, localFile) => async vnode => {
38
+ if (!vnode) return
39
+ if (window?.process?.client && process?.client !== true) return
40
+ if (!window.pinegrow) initCache()
41
+
42
+ let el = vnode.el
43
+
44
+ const instance = vnode.component || vnode.ctx || el.__vueParentComponent
45
+
46
+ if (!el || !instance) return
47
+
48
+ try {
49
+ if ((key !== null && key !== undefined) || (vnode.key !== null && vnode.key !== undefined)) {
50
+ key = vnode.key || key
51
+ }
52
+
53
+ localFile = localFile || vnode.type.__file
54
+
55
+ let isRootFragment = false
56
+ let isFragment = el.nodeType !== 1
57
+ let firstEl,
58
+ lastEl,
59
+ isIsland = false,
60
+ childVNodes = []
61
+
62
+ // May be an iles Island that wraps components with client directives
63
+ if (localFile) {
64
+ if (localFile.includes('node_modules/iles') && localFile.includes('Island.vue')) {
65
+ // Retain localFiles of iles island to apply to child elements
66
+ isIsland = true
67
+ }
68
+
69
+ if (localFile.includes('node_modules')) {
70
+ // Ignore SFCs from node_modules
71
+ localFile = null
72
+ }
73
+ }
74
+
75
+ const localFileFromInstance = instance.type.__file
76
+ if (
77
+ localFileFromInstance &&
78
+ localFileFromInstance.includes('node_modules/iles') &&
79
+ localFileFromInstance.includes('Island.vue')
80
+ ) {
81
+ // Retain localFiles of iles island to apply to child elements
82
+ isIsland = true
83
+
84
+ localFile = instance.props.component?.__file || instance.props.importFrom
85
+ }
86
+
87
+ // // Computed props anyway filters out unmounted ones, and we use the local components unmounted hooks to cleanup unmounted nodes. Using the unmounted hook seems to be out of sync when el is reused but instance is remounted.
88
+ // if (hook === 'unmounted') {
89
+ // if (pinegrow.elCache.has(el)) {
90
+ // pinegrow.elCache.delete(el)
91
+ // }
92
+ // for (let [key, value] of pinegrow.elCache.entries()) {
93
+ // if (value.rootEl === rootEl) {
94
+ // pinegrow.elCache.delete(key)
95
+ // }
96
+ // }
97
+ // return
98
+ // }
99
+
100
+ // Text/comment node
101
+ if (isFragment) {
102
+ if (!rootEl) {
103
+ // root Fragment
104
+ isRootFragment = true
105
+ }
106
+
107
+ function isFragmentEl(instance) {
108
+ // return appRecord.options.types.Fragment === instance.subTree?.type
109
+ return instance.subTree.el.nodeType !== 1
110
+ }
111
+
112
+ function getRootVNodesFromComponentInstance(instance) {
113
+ if (isFragmentEl(instance)) {
114
+ return getFragmentRootVNodes(instance.subTree)
115
+ }
116
+ if (!instance.subTree) return []
117
+ return [instance.subTree]
118
+ }
119
+
120
+ function getFragmentRootVNodes(vnode) {
121
+ if (!vnode.children) return []
122
+ // children is v-if when the vnode has a condition
123
+ if (!Array.isArray(vnode.children)) return []
124
+
125
+ const list = []
126
+
127
+ for (let i = 0, l = vnode.children.length; i < l; i++) {
128
+ const childVnode = vnode.children[i]
129
+ if (childVnode.component) {
130
+ list.push(...getRootVNodesFromComponentInstance(childVnode.component))
131
+ } else if (childVnode) {
132
+ list.push(childVnode)
133
+ }
134
+ }
135
+
136
+ return list
137
+ }
138
+
139
+ childVNodes = getRootVNodesFromComponentInstance(instance)
140
+
141
+ if (!childVNodes.length) {
142
+ // For NuxtLayout, no childVNodes are returned, the subTree.children is in fact an object {ctx: {}, default: f}
143
+ if (el.nextElementSibling) {
144
+ const childEl = el.nextElementSibling
145
+ firstEl = lastEl = childEl
146
+ const childInstance = childEl.$ || childEl.__vueParentComponent
147
+ const childVNode = childInstance?.vnode // or subTree?
148
+ if (childVNode) {
149
+ childVNodes.push(childVNode)
150
+ }
151
+ }
152
+ }
153
+
154
+ if (childVNodes.length) {
155
+ // Filter out recursive vnodes text1 -> div, text1 (happens when text1 is the closest to a fragment with div & slot)
156
+ childVNodes = childVNodes.filter(childVNode => childVNode.el !== el)
157
+
158
+ if (childVNodes.length) {
159
+ if (childVNodes.length === 1) {
160
+ firstEl = lastEl = childVNodes[0].el
161
+ } else {
162
+ firstEl = childVNodes[0].el
163
+ lastEl = childVNodes[childVNodes.length - 1].el
164
+ }
165
+
166
+ if (firstEl && firstEl.nodeType !== 1) {
167
+ firstEl = firstEl.nextElementSibling
168
+ }
169
+ if (lastEl && lastEl.nodeType !== 1) {
170
+ lastEl = lastEl.nextElementSibling
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ if (isIsland && !isRootFragment) {
177
+ return
178
+ }
179
+
180
+ let elCacheObj = {
181
+ el,
182
+ isRootFragment,
183
+ rootEl,
184
+ vnode,
185
+ instance,
186
+ isFragment,
187
+ firstEl,
188
+ lastEl,
189
+ pgId,
190
+ key,
191
+ localFile,
192
+ isIsland,
193
+ }
194
+
195
+ let prevElCacheNodes = pinegrow.elCache.get(el)
196
+
197
+ if (prevElCacheNodes) {
198
+ let index = prevElCacheNodes.findIndex(elCacheObj => elCacheObj.instance.uid === instance.uid)
199
+
200
+ if (index > -1) {
201
+ const prevElCacheObj = prevElCacheNodes[index]
202
+ elCacheObj.localFile = elCacheObj.localFile || prevElCacheObj.localFile
203
+ elCacheObj.pgId = elCacheObj.pgId || prevElCacheObj.pgId
204
+ prevElCacheNodes[index] = elCacheObj
205
+ } else {
206
+ prevElCacheNodes.push(elCacheObj)
207
+ }
208
+ pinegrow.elCache.set(el, prevElCacheNodes)
209
+ } else {
210
+ pinegrow.elCache.set(el, [elCacheObj])
211
+ childVNodes.forEach(childVNode => {
212
+ pgUpdateElCache(hook, pgId, isRootFragment ? el : rootEl, key)(childVNode)
213
+ })
214
+ }
215
+
216
+ if (pinegrow.elUpdateHanderFn) {
217
+ pinegrow.elUpdateHanderFn(el)
218
+ }
219
+ } catch (err) {
220
+ console.log(err)
221
+ if (pinegrow.elCacheErrHandlerFn) {
222
+ pinegrow.elCacheErrHandlerFn(vnode, hook, rootEl, pgId, key, el, instance, err.message)
223
+ }
224
+ }
225
+ }
226
+
227
+ const elUpdateHanderFn = el => {
228
+ // if (pinegrow.elCache.has(el)) {
229
+ // const { pgId } = pinegrow.elCache.get(el)
230
+ // if (pgId) {
231
+ // // console.log(`Reselect ${pgId}`)
232
+ // }
233
+ // }
234
+ }
235
+
236
+ const elCacheErrHandlerFn = () => {
237
+ if (message) {
238
+ // console.log(message)
239
+ }
240
+ }
241
+
242
+ const cleanupCache = () => {
243
+ // for (let [key, value] of pinegrow.elCache.entries()) {
244
+ // if (value.isFragment && !value.firstEl) {
245
+ // console.log(value)
246
+ // }
247
+ // }
248
+ for (let [el, elCacheNodes] of pinegrow.elCache.entries()) {
249
+ // if (!el.isConnected) {
250
+ // pinegrow.elCache.delete(el)
251
+ // continue
252
+ // }
253
+ const cleanedUpElCacheNodes = elCacheNodes.filter(
254
+ elCacheObj => !elCacheObj.instance.isUnmounted // || elCacheObj.localFile
255
+ )
256
+ if (cleanedUpElCacheNodes.length) {
257
+ if (cleanedUpElCacheNodes.length !== elCacheNodes.length) {
258
+ pinegrow.elCache.set(el, cleanedUpElCacheNodes)
259
+ }
260
+ } else {
261
+ pinegrow.elCache.delete(el)
262
+ }
263
+ }
264
+ }
265
+
266
+ // Local Component
267
+ const rootVNode = ref(null)
268
+
269
+ const mountLocalComponent = () => {
270
+ const instance = getCurrentInstance()
271
+ const vnode = instance?.vnode
272
+ const el = vnode?.el
273
+ const localFile = instance.type.__file && !instance.type.__file.includes('node_modules') && instance.type.__file
274
+ if (instance && vnode && el) {
275
+ rootVNode.value = vnode
276
+ pgUpdateElCache('mounted', null, null, null, localFile)(vnode)
277
+ }
278
+ }
279
+
280
+ const unmountLocalComponent = () => {
281
+ if (rootVNode.value) {
282
+ pgUpdateElCache('unmounted')(rootVNode.value)
283
+ }
284
+ cleanupCache()
285
+ }
286
+
287
+ onBeforeMount(() => initCache())
288
+ onMounted(() => {
289
+ mountLocalComponent()
290
+ })
291
+ onBeforeUnmount(() => unmountLocalComponent())
292
+ onUpdated(() => {
293
+ mountLocalComponent()
294
+ })
295
+
296
+ return { pgUpdateElCache }
297
+ }
298
+