fusee-framework 1.5.3 → 1.7.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.
Files changed (115) hide show
  1. package/README.md +30 -13
  2. package/app/benchmark/benchmark.js +633 -0
  3. package/app/benchmark/index.html +102 -0
  4. package/app/benchmark/styles.css +249 -0
  5. package/app/components/Counter.js +17 -7
  6. package/app/components/Counter.ts +1 -1
  7. package/app/components/CounterSection.js +3 -4
  8. package/app/main.js +29 -62
  9. package/app/main.ts +72 -63
  10. package/app/pages/404.js +16 -0
  11. package/app/pages/[...all].js +35 -0
  12. package/app/pages/[...all].ts +35 -0
  13. package/app/pages/_layout.js +26 -0
  14. package/app/pages/_layout.ts +26 -0
  15. package/app/pages/about.js +23 -0
  16. package/app/pages/about.ts +29 -0
  17. package/app/pages/composables.js +158 -0
  18. package/app/pages/composables.ts +158 -0
  19. package/app/pages/dynamic.js +40 -0
  20. package/app/pages/dynamic.ts +40 -0
  21. package/app/pages/index.js +117 -0
  22. package/app/pages/index.ts +78 -0
  23. package/app/pages/login.ts +21 -0
  24. package/app/pages/objects/[id].js +56 -0
  25. package/app/pages/objects/[id].ts +56 -0
  26. package/app/pages/posts/[category]/[slug].js +56 -0
  27. package/app/pages/posts/[category]/[slug].ts +56 -0
  28. package/app/pages/router-example.js +56 -0
  29. package/app/pages/router-example.ts +56 -0
  30. package/app/pages/test-for.js +65 -0
  31. package/app/pages/test-for.ts +80 -0
  32. package/app/pages/users/[id].js +24 -0
  33. package/app/pages/users/[id].ts +46 -0
  34. package/app/pages/users/index.js +22 -0
  35. package/app/pages/users/index.ts +29 -0
  36. package/app/pages/users.js +43 -0
  37. package/app/pages/users.ts +78 -0
  38. package/app/routes/About.js +1 -1
  39. package/app/routes/About.ts +1 -1
  40. package/app/routes/AuthRoutes.ts +41 -0
  41. package/app/routes/Home.js +9 -0
  42. package/app/routes/NotFound.js +16 -0
  43. package/app/routes/NotFound.ts +16 -0
  44. package/app/routes/RouterExample.js +56 -0
  45. package/app/routes/RouterExample.ts +56 -0
  46. package/app/routes/WildcardDemo.js +35 -0
  47. package/app/routes/WildcardDemo.ts +35 -0
  48. package/auto-imports.d.ts +1 -0
  49. package/bin/create-fusee-linux +0 -0
  50. package/bin/create-fusee-mac-arm64 +0 -0
  51. package/bin/create-fusee-mac-intel +0 -0
  52. package/bin/create-fusee-win.exe +0 -0
  53. package/bin/create-fusee.exe +0 -0
  54. package/bin/index.js +38 -0
  55. package/create-fusee-go/cmd/generate.go +72 -0
  56. package/create-fusee-go/cmd/init.go +38 -0
  57. package/create-fusee-go/cmd/root.go +121 -0
  58. package/create-fusee-go/go.mod +10 -0
  59. package/create-fusee-go/go.sum +10 -0
  60. package/create-fusee-go/internal/assets/assets.go +78 -0
  61. package/create-fusee-go/internal/assets/embed/framework/auto-import-preset.js +9 -0
  62. package/create-fusee-go/internal/assets/embed/framework/core/compiler.js +253 -0
  63. package/create-fusee-go/internal/assets/embed/framework/core/component.js +266 -0
  64. package/create-fusee-go/internal/assets/embed/framework/core/composable.js +27 -0
  65. package/create-fusee-go/internal/assets/embed/framework/core/directives.js +875 -0
  66. package/create-fusee-go/internal/assets/embed/framework/core/evaluator.js +153 -0
  67. package/create-fusee-go/internal/assets/embed/framework/core/event-delegation.js +191 -0
  68. package/create-fusee-go/internal/assets/embed/framework/core/signal.js +412 -0
  69. package/create-fusee-go/internal/assets/embed/framework/core/store.js +81 -0
  70. package/create-fusee-go/internal/assets/embed/framework/index.d.ts +3 -0
  71. package/create-fusee-go/internal/assets/embed/framework/index.js +10 -0
  72. package/create-fusee-go/internal/assets/embed/framework/router/file-router.js +177 -0
  73. package/create-fusee-go/internal/assets/embed/framework/router/router.js +462 -0
  74. package/create-fusee-go/internal/assets/embed/framework/types/compiler.d.ts +15 -0
  75. package/create-fusee-go/internal/assets/embed/framework/types/component.d.ts +88 -0
  76. package/create-fusee-go/internal/assets/embed/framework/types/composable.d.ts +14 -0
  77. package/create-fusee-go/internal/assets/embed/framework/types/directives.d.ts +55 -0
  78. package/create-fusee-go/internal/assets/embed/framework/types/evaluator.d.ts +13 -0
  79. package/create-fusee-go/internal/assets/embed/framework/types/event-delegation.d.ts +32 -0
  80. package/create-fusee-go/internal/assets/embed/framework/types/index.d.ts +22 -0
  81. package/create-fusee-go/internal/assets/embed/framework/types/router.d.ts +32 -0
  82. package/create-fusee-go/internal/assets/embed/framework/types/signal.d.ts +79 -0
  83. package/create-fusee-go/internal/assets/embed/framework/types/store.d.ts +8 -0
  84. package/create-fusee-go/internal/assets/templates/Counter.tmpl +26 -0
  85. package/create-fusee-go/internal/assets/templates/component.tmpl +11 -0
  86. package/create-fusee-go/internal/assets/templates/components/Loading.tmpl +24 -0
  87. package/create-fusee-go/internal/assets/templates/index.html.tmpl +15 -0
  88. package/create-fusee-go/internal/assets/templates/main.tmpl +14 -0
  89. package/create-fusee-go/internal/assets/templates/package.json.tmpl +14 -0
  90. package/create-fusee-go/internal/assets/templates/page.tmpl +12 -0
  91. package/create-fusee-go/internal/assets/templates/pages/about.tmpl +20 -0
  92. package/create-fusee-go/internal/assets/templates/pages/index.tmpl +22 -0
  93. package/create-fusee-go/internal/assets/templates/pages/layout.tmpl +18 -0
  94. package/create-fusee-go/internal/assets/templates/tsconfig.json.tmpl +14 -0
  95. package/create-fusee-go/internal/assets/templates/vite.config.js.tmpl +18 -0
  96. package/create-fusee-go/main.go +7 -0
  97. package/framework/auto-import-preset.js +1 -1
  98. package/framework/core/compiler.js +252 -249
  99. package/framework/core/component.js +265 -260
  100. package/framework/core/directives.js +875 -632
  101. package/framework/core/evaluator.js +153 -70
  102. package/framework/core/event-delegation.js +191 -0
  103. package/framework/core/signal.js +412 -404
  104. package/framework/index.js +10 -11
  105. package/framework/router/file-router.js +177 -0
  106. package/framework/router/router.js +462 -80
  107. package/framework/types/component.d.ts +0 -4
  108. package/framework/types/event-delegation.d.ts +32 -0
  109. package/framework/types/index.d.ts +3 -0
  110. package/framework/types/router.d.ts +32 -15
  111. package/framework/types/signal.d.ts +1 -0
  112. package/index.html +638 -563
  113. package/package.json +5 -3
  114. package/tsconfig.json +1 -0
  115. /package/{framework → create-fusee-go/internal/assets/embed/framework}/bin/create-fusee.js +0 -0
@@ -1,261 +1,266 @@
1
- import { effect, setEffectHook, batch } from './signal.js'
2
- import { mountTemplate } from './compiler.js'
3
-
4
- let currentInstance = null
5
-
6
- setEffectHook(eff => {
7
- if (currentInstance) currentInstance._effects.push(eff)
8
- })
9
-
10
- export function getCurrentInstance() {
11
- return currentInstance
12
- }
13
-
14
- export function setCurrentInstance(instance) {
15
- currentInstance = instance
16
- }
17
-
18
- function resolveProps(schema, received) {
19
- const isArray = Array.isArray(schema)
20
- const resolved = {}
21
-
22
- const normalizedSchema = {}
23
- if (isArray) {
24
- schema.forEach(k => normalizedSchema[k.toLowerCase()] = k)
25
- } else {
26
- for (const key of Object.keys(schema)) {
27
- normalizedSchema[key.toLowerCase()] = key
28
- }
29
- }
30
-
31
- for (const receivedKey of Object.keys(received)) {
32
- const schemaKey = isArray
33
- ? schema.find(k => k.toLowerCase() === receivedKey.toLowerCase())
34
- : normalizedSchema[receivedKey.toLowerCase()]
35
-
36
- if (!schemaKey) {
37
- console.warn(`[framework] Unknown prop "${receivedKey}"`)
38
- continue
39
- }
40
-
41
- const descriptor = Object.getOwnPropertyDescriptor(received, receivedKey)
42
- if (descriptor && descriptor.get) {
43
- Object.defineProperty(resolved, schemaKey, {
44
- get: descriptor.get,
45
- enumerable: true,
46
- configurable: true
47
- })
48
- } else {
49
- resolved[schemaKey] = received[receivedKey]
50
- }
51
- }
52
-
53
- if (!isArray) {
54
- for (const [key, config] of Object.entries(schema)) {
55
- if (!(key in resolved)) {
56
- if (config.required) {
57
- console.error(`[framework] Required prop "${key}" is missing`)
58
- }
59
- if (config.default !== undefined) {
60
- resolved[key] = typeof config.default === 'function'
61
- ? config.default()
62
- : config.default
63
- }
64
- } else if (config.type) {
65
- const value = resolved[key]
66
- const expectedType = config.type.name
67
- const actualType = typeof value
68
- const typeMap = { String: 'string', Number: 'number', Boolean: 'boolean' }
69
- if (typeMap[expectedType] && actualType !== typeMap[expectedType]) {
70
- console.warn(`[framework] Prop "${key}" expected ${expectedType} but got ${actualType}`)
71
- }
72
- }
73
- }
74
- }
75
-
76
- return resolved
77
- }
78
-
79
- function createEmit(listeners) {
80
- return function emit(eventName, ...args) {
81
- const handler = listeners[eventName]
82
- if (typeof handler === 'function') {
83
- batch(() => handler(...args))
84
- } else if (handler !== undefined) {
85
- console.warn(`[framework] emit("${eventName}"): listener is not a function`)
86
- }
87
- }
88
- }
89
-
90
- export function parseSlots(slotHTML) {
91
- const slots = { default: '' }
92
- if (!slotHTML || !slotHTML.trim()) return slots
93
-
94
- const namedSlotRe = /<template\s+slot="([^"]+)"[^>]*>([\s\S]*?)<\/template>/gi
95
- let remaining = slotHTML
96
- let match
97
-
98
- while ((match = namedSlotRe.exec(slotHTML)) !== null) {
99
- slots[match[1]] = match[2].trim()
100
- remaining = remaining.replace(match[0], '')
101
- }
102
-
103
- const defaultContent = remaining.trim()
104
- if (defaultContent) slots.default = defaultContent
105
-
106
- return slots
107
- }
108
-
109
- function resolveSlots(template, slots) {
110
- let result = template.replace(/<slot\s+name="([^"]+)"\s*>[\s\S]*?<\/slot>/gi, (match, name) => {
111
- return slots[name] ?? ''
112
- })
113
- result = result.replace(/<slot\s*>[\s\S]*?<\/slot>/gi, () => {
114
- return slots.default ?? ''
115
- })
116
-
117
- result = result.replace(/<slot\s+name="([^"]+)"\s*\/>/gi, (_, name) => slots[name] ?? '')
118
- result = result.replace(/<slot\s*\/>/gi, () => slots.default ?? '')
119
- return result
120
- }
121
-
122
- export function onMount(fn) {
123
- if (currentInstance) currentInstance._mountHooks.push(fn)
124
- }
125
-
126
- export function onUnmount(fn) {
127
- if (currentInstance) currentInstance._unmountHooks.push(fn)
128
- }
129
-
130
- export function defineComponent(options) {
131
- return function ComponentFactory(props = {}, { listeners = {}, slots = {}, parent = null } = {}) {
132
- const instance = {
133
- props: options.props ? resolveProps(options.props, props) : props,
134
- _mountHooks: [],
135
- _unmountHooks: [],
136
- _effects: [],
137
- _element: null,
138
- _provides: {},
139
- _parent: parent,
140
- }
141
-
142
- const emit = createEmit(listeners)
143
-
144
- currentInstance = instance
145
- const result = options.setup(instance.props, { emit, slots })
146
- instance.state = result
147
- result._instance = instance
148
- currentInstance = null
149
-
150
- function render(container) {
151
- instance._element = container
152
-
153
- const resolvedTemplate = resolveSlots(result.template, slots)
154
-
155
- const { effects } = mountTemplate(
156
- resolvedTemplate,
157
- container,
158
- result,
159
- options.components || {}
160
- )
161
-
162
- instance._effects.push(...effects)
163
- for (const hook of instance._mountHooks) hook()
164
-
165
- return instance
166
- }
167
-
168
- function unmount() {
169
- for (const hook of instance._unmountHooks) hook()
170
- for (const e of instance._effects) {
171
- if (typeof e === 'function') e()
172
- }
173
- if (instance._element) instance._element.innerHTML = ''
174
- }
175
-
176
- return { render, unmount, instance }
177
- }
178
- }
179
-
180
- export function provide(key, value) {
181
- if (!currentInstance) return
182
- currentInstance._provides[key] = value
183
- }
184
-
185
- export function inject(key) {
186
- let parent = currentInstance?._parent
187
- while (parent) {
188
- if (key in parent._provides) return parent._provides[key];
189
- parent = parent._parent;
190
- }
191
- return null;
192
- }
193
-
194
- export function defineAsyncComponent(loaderOrOptions) {
195
- const options = typeof loaderOrOptions === 'function'
196
- ? { loader: loaderOrOptions }
197
- : loaderOrOptions
198
-
199
- return function AsyncComponentFactory(props = {}, { listeners = {}, slots = {}, parent = null } = {}) {
200
- const instance = {
201
- props,
202
- _mountHooks: [],
203
- _unmountHooks: [],
204
- _effects: [],
205
- _element: null,
206
- _provides: {},
207
- _parent: parent,
208
- }
209
-
210
- let childApi = null
211
- let loadingApi = null
212
- let isUnmounted = false
213
-
214
- function render(container) {
215
- instance._element = container
216
-
217
- if (options.loadingComponent) {
218
- loadingApi = options.loadingComponent({}, { parent })
219
- loadingApi.render(container)
220
- } else {
221
- container.innerHTML = '<!-- async component boundary -->'
222
- }
223
-
224
- Promise.resolve(options.loader())
225
- .then(comp => {
226
- if (isUnmounted) return
227
- let ComponentFn = comp.default || comp
228
-
229
- if (typeof ComponentFn === 'object' && ComponentFn !== null) {
230
- ComponentFn = Object.values(ComponentFn).find(v => typeof v === 'function') || ComponentFn
231
- }
232
-
233
- if (loadingApi) {
234
- loadingApi.unmount()
235
- loadingApi = null
236
- }
237
-
238
- childApi = ComponentFn(props, { listeners, slots, parent })
239
-
240
- container.innerHTML = ''
241
- childApi.render(container)
242
- })
243
- .catch(err => {
244
- console.error('[framework] Failed to load async component:', err)
245
- })
246
-
247
- return instance
248
- }
249
-
250
- function unmount() {
251
- isUnmounted = true
252
- if (loadingApi) loadingApi.unmount()
253
- if (childApi) childApi.unmount()
254
- if (instance._element && !childApi && !loadingApi) {
255
- instance._element.innerHTML = ''
256
- }
257
- }
258
-
259
- return { render, unmount, instance }
260
- }
1
+ import { effect, setEffectHook, batch } from './signal.js'
2
+ import { mountTemplate } from './compiler.js'
3
+
4
+ let currentInstance = null
5
+
6
+ setEffectHook(eff => {
7
+ if (currentInstance) currentInstance._effects.push(eff)
8
+ })
9
+
10
+ export function getCurrentInstance() {
11
+ return currentInstance
12
+ }
13
+
14
+ export function setCurrentInstance(instance) {
15
+ currentInstance = instance
16
+ }
17
+
18
+ function resolveProps(schema, received) {
19
+ const isArray = Array.isArray(schema)
20
+ const resolved = {}
21
+
22
+ const normalizedSchema = {}
23
+ if (isArray) {
24
+ schema.forEach(k => normalizedSchema[k.toLowerCase()] = k)
25
+ } else {
26
+ for (const key of Object.keys(schema)) {
27
+ normalizedSchema[key.toLowerCase()] = key
28
+ }
29
+ }
30
+
31
+ for (const receivedKey of Object.keys(received)) {
32
+ const schemaKey = isArray
33
+ ? schema.find(k => k.toLowerCase() === receivedKey.toLowerCase())
34
+ : normalizedSchema[receivedKey.toLowerCase()]
35
+
36
+ if (!schemaKey) {
37
+ console.warn(`[framework] Unknown prop "${receivedKey}"`)
38
+ continue
39
+ }
40
+
41
+ const descriptor = Object.getOwnPropertyDescriptor(received, receivedKey)
42
+ if (descriptor && descriptor.get) {
43
+ Object.defineProperty(resolved, schemaKey, {
44
+ get: descriptor.get,
45
+ enumerable: true,
46
+ configurable: true
47
+ })
48
+ } else {
49
+ resolved[schemaKey] = received[receivedKey]
50
+ }
51
+ }
52
+
53
+ if (!isArray) {
54
+ for (const [key, config] of Object.entries(schema)) {
55
+ if (!(key in resolved)) {
56
+ if (config.required) {
57
+ console.error(`[framework] Required prop "${key}" is missing`)
58
+ }
59
+ if (config.default !== undefined) {
60
+ resolved[key] = typeof config.default === 'function'
61
+ ? config.default()
62
+ : config.default
63
+ }
64
+ } else if (config.type) {
65
+ const value = resolved[key]
66
+ const expectedType = config.type.name
67
+ const actualType = typeof value
68
+ const typeMap = { String: 'string', Number: 'number', Boolean: 'boolean' }
69
+ if (typeMap[expectedType] && actualType !== typeMap[expectedType]) {
70
+ console.warn(`[framework] Prop "${key}" expected ${expectedType} but got ${actualType}`)
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return resolved
77
+ }
78
+
79
+ function createEmit(listeners) {
80
+ return function emit(eventName, ...args) {
81
+ const handler = listeners[eventName]
82
+ if (typeof handler === 'function') {
83
+ batch(() => handler(...args))
84
+ } else if (handler !== undefined) {
85
+ console.warn(`[framework] emit("${eventName}"): listener is not a function`)
86
+ }
87
+ }
88
+ }
89
+
90
+ export function parseSlots(slotHTML) {
91
+ const slots = { default: '' }
92
+ if (!slotHTML || !slotHTML.trim()) return slots
93
+
94
+ const namedSlotRe = /<template\s+slot="([^"]+)"[^>]*>([\s\S]*?)<\/template>/gi
95
+ let remaining = slotHTML
96
+ let match
97
+
98
+ while ((match = namedSlotRe.exec(slotHTML)) !== null) {
99
+ slots[match[1]] = match[2].trim()
100
+ remaining = remaining.replace(match[0], '')
101
+ }
102
+
103
+ const defaultContent = remaining.trim()
104
+ if (defaultContent) slots.default = defaultContent
105
+
106
+ return slots
107
+ }
108
+
109
+ function resolveSlots(template, slots) {
110
+ let result = template.replace(/<slot\s+name="([^"]+)"\s*>[\s\S]*?<\/slot>/gi, (match, name) => {
111
+ return slots[name] ?? ''
112
+ })
113
+ result = result.replace(/<slot\s*>[\s\S]*?<\/slot>/gi, () => {
114
+ return slots.default ?? ''
115
+ })
116
+
117
+ result = result.replace(/<slot\s+name="([^"]+)"\s*\/>/gi, (_, name) => slots[name] ?? '')
118
+ result = result.replace(/<slot\s*\/>/gi, () => slots.default ?? '')
119
+ return result
120
+ }
121
+
122
+ export function onMount(fn) {
123
+ if (currentInstance) currentInstance._mountHooks.push(fn)
124
+ }
125
+
126
+ export function onUnmount(fn) {
127
+ if (currentInstance) currentInstance._unmountHooks.push(fn)
128
+ }
129
+
130
+ export function defineComponent(options) {
131
+ return function ComponentFactory(props = {}, { listeners = {}, slots = {}, parent = null } = {}) {
132
+ const instance = {
133
+ props: options.props ? resolveProps(options.props, props) : props,
134
+ _mountHooks: [],
135
+ _unmountHooks: [],
136
+ _effects: [],
137
+ _element: null,
138
+ _provides: {},
139
+ _parent: parent,
140
+ }
141
+
142
+ const emit = createEmit(listeners)
143
+
144
+ currentInstance = instance
145
+ const result = options.setup(instance.props, { emit, slots })
146
+ instance.state = result
147
+ result._instance = instance
148
+ currentInstance = null
149
+
150
+ function render(container) {
151
+ instance._element = container
152
+
153
+ const resolvedTemplate = resolveSlots(result.template, slots)
154
+
155
+ const { effects } = mountTemplate(
156
+ resolvedTemplate,
157
+ container,
158
+ result,
159
+ options.components || {}
160
+ )
161
+
162
+ instance._effects.push(...effects)
163
+ for (const hook of instance._mountHooks) hook()
164
+
165
+ return instance
166
+ }
167
+
168
+ function unmount() {
169
+ for (const hook of instance._unmountHooks) hook()
170
+ const effects = instance._effects
171
+ for (let i = effects.length - 1; i >= 0; i--) {
172
+ const cleanup = effects[i]
173
+ if (typeof cleanup === 'function') cleanup()
174
+ }
175
+ instance._effects = []
176
+ if (instance._element) {
177
+ instance._element.innerHTML = ''
178
+ }
179
+ }
180
+
181
+ return { render, unmount, instance }
182
+ }
183
+ }
184
+
185
+ export function provide(key, value) {
186
+ if (!currentInstance) return
187
+ currentInstance._provides[key] = value
188
+ }
189
+
190
+ export function inject(key) {
191
+ let parent = currentInstance?._parent
192
+ while (parent) {
193
+ if (key in parent._provides) return parent._provides[key];
194
+ parent = parent._parent;
195
+ }
196
+ return null;
197
+ }
198
+
199
+ export function defineAsyncComponent(loaderOrOptions) {
200
+ const options = typeof loaderOrOptions === 'function'
201
+ ? { loader: loaderOrOptions }
202
+ : loaderOrOptions
203
+
204
+ return function AsyncComponentFactory(props = {}, { listeners = {}, slots = {}, parent = null } = {}) {
205
+ const instance = {
206
+ props,
207
+ _mountHooks: [],
208
+ _unmountHooks: [],
209
+ _effects: [],
210
+ _element: null,
211
+ _provides: {},
212
+ _parent: parent,
213
+ }
214
+
215
+ let childApi = null
216
+ let loadingApi = null
217
+ let isUnmounted = false
218
+
219
+ function render(container) {
220
+ instance._element = container
221
+
222
+ if (options.loadingComponent) {
223
+ loadingApi = options.loadingComponent({}, { parent })
224
+ loadingApi.render(container)
225
+ } else {
226
+ container.innerHTML = '<!-- async component boundary -->'
227
+ }
228
+
229
+ Promise.resolve(options.loader())
230
+ .then(comp => {
231
+ if (isUnmounted) return
232
+ let ComponentFn = comp.default || comp
233
+
234
+ if (typeof ComponentFn === 'object' && ComponentFn !== null) {
235
+ ComponentFn = Object.values(ComponentFn).find(v => typeof v === 'function') || ComponentFn
236
+ }
237
+
238
+ if (loadingApi) {
239
+ loadingApi.unmount()
240
+ loadingApi = null
241
+ }
242
+
243
+ childApi = ComponentFn(props, { listeners, slots, parent })
244
+
245
+ container.innerHTML = ''
246
+ childApi.render(container)
247
+ })
248
+ .catch(err => {
249
+ console.error('[framework] Failed to load async component:', err)
250
+ })
251
+
252
+ return instance
253
+ }
254
+
255
+ function unmount() {
256
+ isUnmounted = true
257
+ if (loadingApi) loadingApi.unmount()
258
+ if (childApi) childApi.unmount()
259
+ if (instance._element && !childApi && !loadingApi) {
260
+ instance._element.innerHTML = ''
261
+ }
262
+ }
263
+
264
+ return { render, unmount, instance }
265
+ }
261
266
  }