@pinegrow/vite-plugin 3.0.0-beta.139 → 3.0.0-beta.140

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.
Files changed (5) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +70 -70
  3. package/dist/vue/index.js +310 -298
  4. package/package.json +48 -48
  5. package/types.d.ts +100 -100
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2022-present, Pinegrow
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2022-present, Pinegrow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,70 +1,70 @@
1
- <!-- [![@pinegrow/vite-plugin](https://tailwindcss.nuxtjs.org/social-card.png)](https://tailwindcss.nuxtjs.org) -->
2
-
3
- # Pinegrow Vite Plugin
4
-
5
- [![npm version][npm-version-src]][npm-version-href]
6
- [![npm downloads][npm-downloads-src]][npm-downloads-href]
7
- [![License][license-src]][license-href]
8
-
9
- [Vite](https://vitejs.dev) plugin for [Pinegrow](https://pinegrow.com) ⚡️
10
-
11
- Pinegrow Vite Plugin enables connection and interaction between your Vite Dev-Server and Pinegrow apps (currently only Vue Designer).
12
-
13
- - [📖 &nbsp;Documentation](https://pinegrow.com/vue-designer)
14
-
15
- ## Features
16
-
17
- - 🎨&nbsp; Visually live-design your Vite-powered apps (Vue, Nuxt, Iles, Astro, etc)
18
- - ⚙️&nbsp; Smartly integrates into your Vite workflow in dev-mode only
19
- - ✨&nbsp; No lock-in, Pinegrow is an open-tool ❤️
20
-
21
- ## Quick Setup
22
-
23
- 1. Install: Add `@pinegrow/vite-plugin` to your project
24
-
25
- ```bash
26
- # Using npm
27
- npm install --save-dev @pinegrow/vite-plugin
28
-
29
- # Using pnpm
30
- pnpm add --save-dev @pinegrow/vite-plugin
31
- ```
32
-
33
- 2. Configure: Add `liveDesigner()` to your Vite Plugins array `vite.config.{ts,js}`
34
-
35
- ```js
36
- //vite.config.js (or) vite.config.ts
37
-
38
- import { defineConfig } from 'vite'
39
- import vue from '@vitejs/plugin-vue'
40
- import { liveDesigner } from '@pinegrow/vite-plugin'
41
-
42
- export default defineConfig({
43
- plugins: [
44
- liveDesigner({
45
- //...
46
- }),
47
- vue(),
48
- //...
49
- ],
50
- //...
51
- })
52
- ```
53
-
54
- Now, open your project in your Pinegrow app (currently only Vue Designer). ✨
55
-
56
- ## License
57
-
58
- [MIT License](./LICENSE)
59
-
60
- Copyright (c) Pinegrow
61
-
62
- <!-- Badges -->
63
-
64
- [npm-version-src]: https://img.shields.io/npm/v/@pinegrow/vite-plugin/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
65
- [npm-version-href]: https://npmjs.com/package/@pinegrow/vite-plugin
66
- [npm-downloads-src]: https://img.shields.io/npm/dm/@pinegrow/vite-plugin.svg?style=flat&colorA=18181B&colorB=28CF8D
67
- [npm-downloads-href]: https://npmjs.com/package/@pinegrow/vite-plugin
68
- [license-src]: https://img.shields.io/npm/l/@pinegrow/vite-plugin.svg?style=flat&colorA=18181B&colorB=28CF8D
69
- [license-href]: https://npmjs.com/package/@pinegrow/vite-plugin
70
-
1
+ <!-- [![@pinegrow/vite-plugin](https://tailwindcss.nuxtjs.org/social-card.png)](https://tailwindcss.nuxtjs.org) -->
2
+
3
+ # Pinegrow Vite Plugin
4
+
5
+ [![npm version][npm-version-src]][npm-version-href]
6
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
7
+ [![License][license-src]][license-href]
8
+
9
+ [Vite](https://vitejs.dev) plugin for [Pinegrow](https://pinegrow.com) ⚡️
10
+
11
+ Pinegrow Vite Plugin enables connection and interaction between your Vite Dev-Server and Pinegrow apps (currently only Vue Designer).
12
+
13
+ - [📖 &nbsp;Documentation](https://pinegrow.com/vue-designer)
14
+
15
+ ## Features
16
+
17
+ - 🎨&nbsp; Visually live-design your Vite-powered apps (Vue, Nuxt, Iles, Astro, etc)
18
+ - ⚙️&nbsp; Smartly integrates into your Vite workflow in dev-mode only
19
+ - ✨&nbsp; No lock-in, Pinegrow is an open-tool ❤️
20
+
21
+ ## Quick Setup
22
+
23
+ 1. Install: Add `@pinegrow/vite-plugin` to your project
24
+
25
+ ```bash
26
+ # Using npm
27
+ npm install --save-dev @pinegrow/vite-plugin
28
+
29
+ # Using pnpm
30
+ pnpm add --save-dev @pinegrow/vite-plugin
31
+ ```
32
+
33
+ 2. Configure: Add `liveDesigner()` to your Vite Plugins array `vite.config.{ts,js}`
34
+
35
+ ```js
36
+ //vite.config.js (or) vite.config.ts
37
+
38
+ import { defineConfig } from 'vite'
39
+ import vue from '@vitejs/plugin-vue'
40
+ import { liveDesigner } from '@pinegrow/vite-plugin'
41
+
42
+ export default defineConfig({
43
+ plugins: [
44
+ liveDesigner({
45
+ //...
46
+ }),
47
+ vue(),
48
+ //...
49
+ ],
50
+ //...
51
+ })
52
+ ```
53
+
54
+ Now, open your project in your Pinegrow app (currently only Vue Designer). ✨
55
+
56
+ ## License
57
+
58
+ [MIT License](./LICENSE)
59
+
60
+ Copyright (c) Pinegrow
61
+
62
+ <!-- Badges -->
63
+
64
+ [npm-version-src]: https://img.shields.io/npm/v/@pinegrow/vite-plugin/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
65
+ [npm-version-href]: https://npmjs.com/package/@pinegrow/vite-plugin
66
+ [npm-downloads-src]: https://img.shields.io/npm/dm/@pinegrow/vite-plugin.svg?style=flat&colorA=18181B&colorB=28CF8D
67
+ [npm-downloads-href]: https://npmjs.com/package/@pinegrow/vite-plugin
68
+ [license-src]: https://img.shields.io/npm/l/@pinegrow/vite-plugin.svg?style=flat&colorA=18181B&colorB=28CF8D
69
+ [license-href]: https://npmjs.com/package/@pinegrow/vite-plugin
70
+
package/dist/vue/index.js CHANGED
@@ -1,298 +1,310 @@
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 {
2
+ onBeforeMount,
3
+ onMounted,
4
+ onBeforeUnmount,
5
+ getCurrentInstance,
6
+ ref,
7
+ reactive,
8
+ onUpdated,
9
+ computed,
10
+ watch,
11
+ } from 'vue'
12
+
13
+ export function usePinegrow() {
14
+ const initCache = () => {
15
+ // conditional
16
+ const winObj = window
17
+
18
+ if (!(winObj?.process?.client && winObj.process.client !== true)) {
19
+ if (!winObj.pinegrow) {
20
+ // conditional
21
+ // console.log('Cache initialized by Pinegrow Vue Plugin!')
22
+ const elCache = reactive(new Map())
23
+
24
+ const enrichWithComponentName = (elCacheObj, localFile) => {
25
+ return {
26
+ name: elCacheObj.instance.type.__name || '',
27
+ localFile,
28
+ ...elCacheObj,
29
+ }
30
+ }
31
+
32
+ winObj.pinegrow = {
33
+ elCache,
34
+ watchFromContext: watch,
35
+ computedFromContext: computed,
36
+ // // Uncomment these two to test locally
37
+ // elCacheErrHandlerFn,
38
+ // elUpdateHanderFn,
39
+ // rootFragmentToPgIdComputed,
40
+ // pgIdToElComputed,
41
+ // localComponentToElComputed,
42
+ // appTree,
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ // pgId & key can be optional
49
+ const pgUpdateElCache = (hook, pgId, rootEl, key, localFile) => async vnode => {
50
+ if (!vnode) return
51
+ if (window?.process?.client && process?.client !== true) return
52
+ if (!window.pinegrow) initCache()
53
+
54
+ let el = vnode.el
55
+
56
+ const instance = vnode.component || vnode.ctx || el.__vueParentComponent
57
+
58
+ if (!el || !instance) return
59
+
60
+ try {
61
+ if ((key !== null && key !== undefined) || (vnode.key !== null && vnode.key !== undefined)) {
62
+ key = vnode.key || key
63
+ }
64
+
65
+ localFile = localFile || vnode.type.__file
66
+
67
+ let isRootFragment = false
68
+ let isFragment = el.nodeType !== 1
69
+ let firstEl,
70
+ lastEl,
71
+ isIsland = false,
72
+ childVNodes = []
73
+
74
+ // May be an iles Island that wraps components with client directives
75
+ if (localFile) {
76
+ if (localFile.includes('node_modules/iles') && localFile.includes('Island.vue')) {
77
+ // Retain localFiles of iles island to apply to child elements
78
+ isIsland = true
79
+ }
80
+
81
+ if (localFile.includes('node_modules')) {
82
+ // Ignore SFCs from node_modules
83
+ localFile = null
84
+ }
85
+ }
86
+
87
+ const localFileFromInstance = instance.type.__file
88
+ if (
89
+ localFileFromInstance &&
90
+ localFileFromInstance.includes('node_modules/iles') &&
91
+ localFileFromInstance.includes('Island.vue')
92
+ ) {
93
+ // Retain localFiles of iles island to apply to child elements
94
+ isIsland = true
95
+
96
+ localFile = instance.props.component?.__file || instance.props.importFrom
97
+ }
98
+
99
+ // // 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.
100
+ // if (hook === 'unmounted') {
101
+ // if (pinegrow.elCache.has(el)) {
102
+ // pinegrow.elCache.delete(el)
103
+ // }
104
+ // for (let [key, value] of pinegrow.elCache.entries()) {
105
+ // if (value.rootEl === rootEl) {
106
+ // pinegrow.elCache.delete(key)
107
+ // }
108
+ // }
109
+ // return
110
+ // }
111
+
112
+ // Text/comment node
113
+ if (isFragment) {
114
+ if (!rootEl) {
115
+ // root Fragment
116
+ isRootFragment = true
117
+ }
118
+
119
+ function isFragmentEl(instance) {
120
+ // return appRecord.options.types.Fragment === instance.subTree?.type
121
+ return instance.subTree.el.nodeType !== 1
122
+ }
123
+
124
+ function getRootVNodesFromComponentInstance(instance) {
125
+ if (isFragmentEl(instance)) {
126
+ return getFragmentRootVNodes(instance.subTree)
127
+ }
128
+ if (!instance.subTree) return []
129
+ return [instance.subTree]
130
+ }
131
+
132
+ function getFragmentRootVNodes(vnode) {
133
+ if (!vnode.children) return []
134
+ // children is v-if when the vnode has a condition
135
+ if (!Array.isArray(vnode.children)) return []
136
+
137
+ const list = []
138
+
139
+ for (let i = 0, l = vnode.children.length; i < l; i++) {
140
+ const childVnode = vnode.children[i]
141
+ if (childVnode.component) {
142
+ list.push(...getRootVNodesFromComponentInstance(childVnode.component))
143
+ } else if (childVnode) {
144
+ list.push(childVnode)
145
+ }
146
+ }
147
+
148
+ return list
149
+ }
150
+
151
+ childVNodes = getRootVNodesFromComponentInstance(instance)
152
+
153
+ if (!childVNodes.length) {
154
+ // For NuxtLayout, no childVNodes are returned, the subTree.children is in fact an object {ctx: {}, default: f}
155
+ if (el.nextElementSibling) {
156
+ const childEl = el.nextElementSibling
157
+ firstEl = lastEl = childEl
158
+ const childInstance = childEl.$ || childEl.__vueParentComponent
159
+ const childVNode = childInstance?.vnode // or subTree?
160
+ if (childVNode) {
161
+ childVNodes.push(childVNode)
162
+ }
163
+ }
164
+ }
165
+
166
+ if (childVNodes.length) {
167
+ // Filter out recursive vnodes text1 -> div, text1 (happens when text1 is the closest to a fragment with div & slot)
168
+ childVNodes = childVNodes.filter(childVNode => childVNode.el !== el)
169
+
170
+ if (childVNodes.length) {
171
+ if (childVNodes.length === 1) {
172
+ firstEl = lastEl = childVNodes[0].el
173
+ } else {
174
+ firstEl = childVNodes[0].el
175
+ lastEl = childVNodes[childVNodes.length - 1].el
176
+ }
177
+
178
+ if (firstEl && firstEl.nodeType !== 1) {
179
+ firstEl = firstEl.nextElementSibling
180
+ }
181
+ if (lastEl && lastEl.nodeType !== 1) {
182
+ lastEl = lastEl.nextElementSibling
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ if (isIsland && !isRootFragment) {
189
+ return
190
+ }
191
+
192
+ let elCacheObj = {
193
+ el,
194
+ isRootFragment,
195
+ rootEl,
196
+ vnode,
197
+ instance,
198
+ isFragment,
199
+ firstEl,
200
+ lastEl,
201
+ pgId,
202
+ key,
203
+ localFile,
204
+ isIsland,
205
+ }
206
+
207
+ let prevElCacheNodes = pinegrow.elCache.get(el)
208
+
209
+ if (prevElCacheNodes) {
210
+ let index = prevElCacheNodes.findIndex(elCacheObj => elCacheObj.instance.uid === instance.uid)
211
+
212
+ if (index > -1) {
213
+ const prevElCacheObj = prevElCacheNodes[index]
214
+ elCacheObj.localFile = elCacheObj.localFile || prevElCacheObj.localFile
215
+ elCacheObj.pgId = elCacheObj.pgId || prevElCacheObj.pgId
216
+ prevElCacheNodes[index] = elCacheObj
217
+ } else {
218
+ prevElCacheNodes.push(elCacheObj)
219
+ }
220
+ pinegrow.elCache.set(el, prevElCacheNodes)
221
+ } else {
222
+ pinegrow.elCache.set(el, [elCacheObj])
223
+ childVNodes.forEach(childVNode => {
224
+ pgUpdateElCache(hook, pgId, isRootFragment ? el : rootEl, key)(childVNode)
225
+ })
226
+ }
227
+
228
+ if (pinegrow.elUpdateHanderFn) {
229
+ pinegrow.elUpdateHanderFn(el)
230
+ }
231
+ } catch (err) {
232
+ console.log(err)
233
+ if (pinegrow.elCacheErrHandlerFn) {
234
+ pinegrow.elCacheErrHandlerFn(vnode, hook, rootEl, pgId, key, el, instance, err.message)
235
+ }
236
+ }
237
+ }
238
+
239
+ const elUpdateHanderFn = el => {
240
+ // if (pinegrow.elCache.has(el)) {
241
+ // const { pgId } = pinegrow.elCache.get(el)
242
+ // if (pgId) {
243
+ // // console.log(`Reselect ${pgId}`)
244
+ // }
245
+ // }
246
+ }
247
+
248
+ const elCacheErrHandlerFn = () => {
249
+ if (message) {
250
+ // console.log(message)
251
+ }
252
+ }
253
+
254
+ const cleanupCache = () => {
255
+ // for (let [key, value] of pinegrow.elCache.entries()) {
256
+ // if (value.isFragment && !value.firstEl) {
257
+ // console.log(value)
258
+ // }
259
+ // }
260
+ for (let [el, elCacheNodes] of pinegrow.elCache.entries()) {
261
+ // if (!el.isConnected) {
262
+ // pinegrow.elCache.delete(el)
263
+ // continue
264
+ // }
265
+ const cleanedUpElCacheNodes = elCacheNodes.filter(
266
+ elCacheObj => !elCacheObj.instance.isUnmounted // || elCacheObj.localFile
267
+ )
268
+ if (cleanedUpElCacheNodes.length) {
269
+ if (cleanedUpElCacheNodes.length !== elCacheNodes.length) {
270
+ pinegrow.elCache.set(el, cleanedUpElCacheNodes)
271
+ }
272
+ } else {
273
+ pinegrow.elCache.delete(el)
274
+ }
275
+ }
276
+ }
277
+
278
+ // Local Component
279
+ const rootVNode = ref(null)
280
+
281
+ const mountLocalComponent = () => {
282
+ const instance = getCurrentInstance()
283
+ const vnode = instance?.vnode
284
+ const el = vnode?.el
285
+ const localFile = instance.type.__file && !instance.type.__file.includes('node_modules') && instance.type.__file
286
+ if (instance && vnode && el) {
287
+ rootVNode.value = vnode
288
+ pgUpdateElCache('mounted', null, null, null, localFile)(vnode)
289
+ }
290
+ }
291
+
292
+ const unmountLocalComponent = () => {
293
+ if (rootVNode.value) {
294
+ pgUpdateElCache('unmounted')(rootVNode.value)
295
+ }
296
+ cleanupCache()
297
+ }
298
+
299
+ onBeforeMount(() => initCache())
300
+ onMounted(() => {
301
+ mountLocalComponent()
302
+ })
303
+ onBeforeUnmount(() => unmountLocalComponent())
304
+ onUpdated(() => {
305
+ mountLocalComponent()
306
+ })
307
+
308
+ return { pgUpdateElCache }
309
+ }
310
+
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
- {
2
- "name": "@pinegrow/vite-plugin",
3
- "version": "3.0.0-beta.139",
4
- "description": "Pinegrow Vite Plugin",
5
- "type": "module",
6
- "files": [
7
- "dist",
8
- "./types.d.ts"
9
- ],
10
- "main": "./dist/index.cjs",
11
- "module": "./dist/index.cjs",
12
- "types": "./types.d.ts",
13
- "exports": {
14
- ".": {
15
- "import": "./dist/index.cjs",
16
- "require": "./dist/index.cjs"
17
- },
18
- "./dev": {
19
- "import": "./src/index.js",
20
- "require": "./src/index.js"
21
- },
22
- "./vue": {
23
- "import": "./dist/vue/index.js"
24
- },
25
- "./pgia": {
26
- "import": "./dist/pgia/index.js"
27
- }
28
- },
29
- "keywords": [
30
- "pinegrow",
31
- "vue-designer",
32
- "vite-plugin",
33
- "@pinegrow/vite-plugin"
34
- ],
35
- "author": "Pinegrow (http://pinegrow.com/)",
36
- "license": "MIT",
37
- "scripts": {
38
- "build:vite-plugin": "webpack -- --env mode=production vite",
39
- "build:vite-plugin:dev": "webpack -- --env mode=development vite",
40
- "publish-beta": "npm run increment-beta-version && npm publish",
41
- "increment-beta-version": "npm version prerelease --preid=beta"
42
- },
43
- "dependencies": {
44
- "@vue/compiler-sfc": "^3.2.45",
45
- "magic-string": "^0.27.0",
46
- "node-html-parser": "^5.2.0"
47
- }
48
- }
1
+ {
2
+ "name": "@pinegrow/vite-plugin",
3
+ "version": "3.0.0-beta.140",
4
+ "description": "Pinegrow Vite Plugin",
5
+ "type": "module",
6
+ "files": [
7
+ "dist",
8
+ "./types.d.ts"
9
+ ],
10
+ "main": "./dist/index.cjs",
11
+ "module": "./dist/index.cjs",
12
+ "types": "./types.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/index.cjs",
16
+ "require": "./dist/index.cjs"
17
+ },
18
+ "./dev": {
19
+ "import": "./src/index.js",
20
+ "require": "./src/index.js"
21
+ },
22
+ "./vue": {
23
+ "import": "./dist/vue/index.js"
24
+ },
25
+ "./pgia": {
26
+ "import": "./dist/pgia/index.js"
27
+ }
28
+ },
29
+ "keywords": [
30
+ "pinegrow",
31
+ "vue-designer",
32
+ "vite-plugin",
33
+ "@pinegrow/vite-plugin"
34
+ ],
35
+ "author": "Pinegrow (http://pinegrow.com/)",
36
+ "license": "MIT",
37
+ "scripts": {
38
+ "build:vite-plugin": "webpack -- --env mode=production vite",
39
+ "build:vite-plugin:dev": "webpack -- --env mode=development vite",
40
+ "publish-beta": "npm run increment-beta-version && npm publish",
41
+ "increment-beta-version": "npm version prerelease --preid=beta"
42
+ },
43
+ "dependencies": {
44
+ "@vue/compiler-sfc": "^3.2.45",
45
+ "magic-string": "^0.27.0",
46
+ "node-html-parser": "^5.2.0"
47
+ }
48
+ }
package/types.d.ts CHANGED
@@ -1,100 +1,100 @@
1
- import type { PinegrowTailwindCSSModuleOptions } from '@pinegrow/tailwindcss-plugin'
2
- import type { PluginOption as VitePluginOption } from 'vite'
3
-
4
- interface PinegrowExternalPlugin {
5
- /**
6
- * Display name in Props Panel and Library Panels
7
- * Eg, "My Awesome Lib 3.3.1", defaults to key if not provided
8
- */
9
- name?: string
10
- /**
11
- * Unique key that doesn't conflict with other pinegrow frameworks
12
- * Run `Object.values(pinegrow.getFrameworks()).map(fx => fx.key)` in Vue Designer's devtools console for existing keys
13
- *
14
- * Allowed characters - alphanumeric with hyphens or period, no spaces
15
- * Eg, 'my-awesome-lib'
16
- */
17
- key: string
18
- /**
19
- * Web-types of component library (or) pinegrow commonjs plugin
20
- * Must return an absolute path
21
- *
22
- * Use path functions according to the project module type (commonjs/module)
23
- * For eg, path.resolve(__dirname, '../relative-path/my-lib.cjs')
24
- * (or)
25
- * import { fileURLToPath, URL } from 'node:url'
26
- * fileURLToPath(new URL('./relative-path/web-types.json', import.meta.url)) // web-types of component library
27
- * fileURLToPath(new URL('./relative-path/my-lib.cjs', import.meta.url)) // pinegrow commonjs plugin
28
- */
29
- pluginPath: string
30
- }
31
-
32
- export interface LiveDesignerOptions {
33
- /**
34
- * Absolute path to the root of a monorepo.
35
- * Relative path from the project root to the root of a monorepo.
36
- */
37
- repoRoot?: string
38
-
39
- /**
40
- * Absolute path to a custom config file (for eg, vite-dev.config.js).
41
- * Relative path from the project root to a custom config file (for eg, vite-dev.config.js).
42
- */
43
- configPath?: string
44
-
45
- /**
46
- * Key of the devtools exposed on the window object.
47
- * For instructions, check Config Panel in Vue Designer
48
- */
49
- devtoolsKey?: string
50
-
51
- /**
52
- * Preferred format for icons in icon-picker - https://github.com/antfu/icones/blob/main/src/utils/case.ts
53
- * To see the different formats, go to https://icones.js.org/collection/mdi, turn off name copying mode if active, select an icon. In the bottom drawer, next to the icon-name & copy icon, there is dropup icon. Click the drop-up to see the different formats.
54
- * * @default 'unocss' // For eg, i-material-symbols-home
55
- *
56
- */
57
- iconPreferredCase?:
58
- | 'unocss'
59
- | 'bare'
60
- | 'barePascal'
61
- | 'iconify'
62
- | 'dash'
63
- | 'camel'
64
- | 'pascal'
65
- | 'component'
66
- | 'componentKebab'
67
-
68
- /**
69
- * Router history modes - 'html5', 'hash'
70
- * @default 'html5'
71
- */
72
-
73
- routerHistoryMode?: string //
74
-
75
- /**
76
- * Array of Pinegrow plugins (npm package names)
77
- * To use file-based Pinegrow Plugins, provide the absolute path of the plugin file, for eg, [path.resolve(__dirname, './pg-plugin/index.js')] as pluginPath, along with a unique key
78
- */
79
- plugins?: PinegrowExternalPlugin[] | string | string[]
80
-
81
- /**
82
- * Pinegrow TailwindCSS plugin options
83
- */
84
- tailwindcss?: PinegrowTailwindCSSModuleOptions
85
- }
86
-
87
- interface PinegrowVitePlugin<VitePluginOption> {
88
- /**
89
- * Pinegrow Live Designer options
90
- * For details, check https://pinegrow.com/vue-designer
91
- */
92
- liveDesigner?: {
93
- [key in string]?: any
94
- } & LiveDesignerOptions
95
- }
96
-
97
- declare function export_default(liveDesigner: LiveDesignerOptions): PinegrowVitePlugin
98
-
99
- export { PinegrowVitePlugin, LiveDesignerOptions, export_default as default, export_default as liveDesigner }
100
-
1
+ import type { PinegrowTailwindCSSModuleOptions } from '@pinegrow/tailwindcss-plugin'
2
+ import type { PluginOption as VitePluginOption } from 'vite'
3
+
4
+ interface PinegrowExternalPlugin {
5
+ /**
6
+ * Display name in Props Panel and Library Panels
7
+ * Eg, "My Awesome Lib 3.3.1", defaults to key if not provided
8
+ */
9
+ name?: string
10
+ /**
11
+ * Unique key that doesn't conflict with other pinegrow frameworks
12
+ * Run `Object.values(pinegrow.getFrameworks()).map(fx => fx.key)` in Vue Designer's devtools console for existing keys
13
+ *
14
+ * Allowed characters - alphanumeric with hyphens or period, no spaces
15
+ * Eg, 'my-awesome-lib'
16
+ */
17
+ key: string
18
+ /**
19
+ * Web-types of component library (or) pinegrow commonjs plugin
20
+ * Must return an absolute path
21
+ *
22
+ * Use path functions according to the project module type (commonjs/module)
23
+ * For eg, path.resolve(__dirname, '../relative-path/my-lib.cjs')
24
+ * (or)
25
+ * import { fileURLToPath, URL } from 'node:url'
26
+ * fileURLToPath(new URL('./relative-path/web-types.json', import.meta.url)) // web-types of component library
27
+ * fileURLToPath(new URL('./relative-path/my-lib.cjs', import.meta.url)) // pinegrow commonjs plugin
28
+ */
29
+ pluginPath: string
30
+ }
31
+
32
+ export interface LiveDesignerOptions {
33
+ /**
34
+ * Absolute path to the root of a monorepo.
35
+ * Relative path from the project root to the root of a monorepo.
36
+ */
37
+ repoRoot?: string
38
+
39
+ /**
40
+ * Absolute path to a custom config file (for eg, vite-dev.config.js).
41
+ * Relative path from the project root to a custom config file (for eg, vite-dev.config.js).
42
+ */
43
+ configPath?: string
44
+
45
+ /**
46
+ * Key of the devtools exposed on the window object.
47
+ * For instructions, check Config Panel in Vue Designer
48
+ */
49
+ devtoolsKey?: string
50
+
51
+ /**
52
+ * Preferred format for icons in icon-picker - https://github.com/antfu/icones/blob/main/src/utils/case.ts
53
+ * To see the different formats, go to https://icones.js.org/collection/mdi, turn off name copying mode if active, select an icon. In the bottom drawer, next to the icon-name & copy icon, there is dropup icon. Click the drop-up to see the different formats.
54
+ * * @default 'unocss' // For eg, i-material-symbols-home
55
+ *
56
+ */
57
+ iconPreferredCase?:
58
+ | 'unocss'
59
+ | 'bare'
60
+ | 'barePascal'
61
+ | 'iconify'
62
+ | 'dash'
63
+ | 'camel'
64
+ | 'pascal'
65
+ | 'component'
66
+ | 'componentKebab'
67
+
68
+ /**
69
+ * Router history modes - 'html5', 'hash'
70
+ * @default 'html5'
71
+ */
72
+
73
+ routerHistoryMode?: string //
74
+
75
+ /**
76
+ * Array of Pinegrow plugins (npm package names)
77
+ * To use file-based Pinegrow Plugins, provide the absolute path of the plugin file, for eg, [path.resolve(__dirname, './pg-plugin/index.js')] as pluginPath, along with a unique key
78
+ */
79
+ plugins?: PinegrowExternalPlugin[] | string | string[]
80
+
81
+ /**
82
+ * Pinegrow TailwindCSS plugin options
83
+ */
84
+ tailwindcss?: PinegrowTailwindCSSModuleOptions
85
+ }
86
+
87
+ interface PinegrowVitePlugin<VitePluginOption> {
88
+ /**
89
+ * Pinegrow Live Designer options
90
+ * For details, check https://pinegrow.com/vue-designer
91
+ */
92
+ liveDesigner?: {
93
+ [key in string]?: any
94
+ } & LiveDesignerOptions
95
+ }
96
+
97
+ declare function export_default(liveDesigner: LiveDesignerOptions): PinegrowVitePlugin
98
+
99
+ export { PinegrowVitePlugin, LiveDesignerOptions, export_default as default, export_default as liveDesigner }
100
+