fusee-framework 2.7.0 → 2.7.2

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 (61) hide show
  1. package/README.md +98 -26
  2. package/bin/create-fusee-linux +0 -0
  3. package/bin/create-fusee-mac-arm64 +0 -0
  4. package/bin/create-fusee-mac-intel +0 -0
  5. package/bin/create-fusee-win.exe +0 -0
  6. package/framework/auto-import-preset.js +20 -12
  7. package/framework/auto-imports.d.ts +68 -39
  8. package/framework/core/compiler.js +310 -310
  9. package/framework/core/component-core.js +445 -0
  10. package/framework/core/component.js +11 -440
  11. package/framework/core/composable.js +29 -29
  12. package/framework/core/h.js +119 -44
  13. package/framework/core/jsx-helpers.js +11 -2
  14. package/framework/core/jsx-runtime.js +73 -73
  15. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm +0 -0
  16. package/framework/core/store.js +333 -333
  17. package/framework/globals.js +42 -0
  18. package/framework/index.js +22 -55
  19. package/framework/router/file-router.js +184 -184
  20. package/framework/server/actions.js +183 -183
  21. package/framework/server/generate-manifest.js +3 -3
  22. package/framework/types/component.d.ts +97 -86
  23. package/framework/types/index.d.ts +118 -117
  24. package/package.json +83 -80
  25. package/framework/core/rust-compiler/Cargo.toml +0 -31
  26. package/framework/core/rust-compiler/README.md +0 -69
  27. package/framework/core/rust-compiler/pkg/README.md +0 -69
  28. package/framework/core/rust-compiler/pkg/fusee_compiler.d.ts +0 -6
  29. package/framework/core/rust-compiler/pkg/fusee_compiler.js +0 -9
  30. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.js +0 -137
  31. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm.d.ts +0 -11
  32. package/framework/core/rust-compiler/pkg/package.json +0 -18
  33. package/framework/core/rust-compiler/src/ast.rs +0 -274
  34. package/framework/core/rust-compiler/src/errors.rs +0 -204
  35. package/framework/core/rust-compiler/src/generator.rs +0 -583
  36. package/framework/core/rust-compiler/src/lexer.rs +0 -414
  37. package/framework/core/rust-compiler/src/lib.rs +0 -87
  38. package/framework/core/rust-compiler/src/main_compiler.rs +0 -165
  39. package/framework/core/rust-compiler/src/parser.rs +0 -516
  40. package/framework/core/rust-compiler/src/ssr_generator.rs +0 -688
  41. package/framework/core/rust-compiler/src/transformer.rs +0 -562
  42. package/framework/core/rust-compiler/src/utils.rs +0 -10
  43. package/framework/engine-go/actions.go +0 -112
  44. package/framework/engine-go/cmd/server/main.go +0 -233
  45. package/framework/engine-go/comet/comet.go +0 -41
  46. package/framework/engine-go/comet/fragment.go +0 -51
  47. package/framework/engine-go/dispatcher.go +0 -120
  48. package/framework/engine-go/elements.go +0 -248
  49. package/framework/engine-go/evalexpr/evalexpr.go +0 -733
  50. package/framework/engine-go/go.mod +0 -3
  51. package/framework/engine-go/hydration.go +0 -43
  52. package/framework/engine-go/load-helpers.go +0 -29
  53. package/framework/engine-go/manifest.go +0 -41
  54. package/framework/engine-go/reactive.go +0 -123
  55. package/framework/engine-go/render.go +0 -635
  56. package/framework/engine-go/reqcontext.go +0 -48
  57. package/framework/engine-go/router.go +0 -85
  58. package/framework/engine-go/rustast/rustast.go +0 -317
  59. package/framework/engine-go/ssr.go +0 -103
  60. package/framework/engine-go/static-assets.go +0 -139
  61. package/framework/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
@@ -1,184 +1,184 @@
1
- import { signal, batch } from '../core/signal.js'
2
- import { getCurrentInstance } from '../core/component.js'
3
-
4
- const ACTION_BASE_URL = '/__fusee/actions'
5
- const _actionHydrationRegistry = new Map()
6
-
7
- /** Creates a client action proxy from a function or explicit action name. */
8
- export function defineAction(fnOrName, opts = {}) {
9
- const name = opts.name
10
- || (typeof fnOrName === 'function' ? fnOrName.name : fnOrName)
11
-
12
- if (!name) {
13
- throw new Error('[fusee] defineAction() client stub: nu s-a putut determina numele acțiunii')
14
- }
15
-
16
- return createActionProxy(name, opts)
17
- }
18
-
19
- /** Creates a proxy that POSTs action arguments and returns server data. */
20
- export function createActionProxy(name, opts = {}) {
21
- const baseUrl = opts.baseUrl ?? ACTION_BASE_URL
22
-
23
- /** Sends one action invocation to the configured server endpoint. */
24
- async function actionProxy(...args) {
25
- const res = await fetch(`${baseUrl}/${name}`, {
26
- method: 'POST',
27
- headers: {
28
- 'Content-Type': 'application/json',
29
- ...(opts.headers ?? {})
30
- },
31
- body: JSON.stringify({ args })
32
- })
33
-
34
- const json = await res.json()
35
-
36
- if (!res.ok) {
37
- const err = new Error(json.error ?? `Action "${name}" failed (${res.status})`)
38
- err.status = res.status
39
- err.code = json.code
40
- throw err
41
- }
42
-
43
- return json.data
44
- }
45
-
46
- actionProxy._isAction = true
47
- actionProxy._actionName = name
48
-
49
- return actionProxy
50
- }
51
-
52
- /** Wraps an action in reactive pending, data, error, and reset state. */
53
- export function useAction(action, opts = {}) {
54
- if (typeof action !== 'function') {
55
- throw new Error('[fusee] useAction() requires an action function (result of defineAction or createActionProxy)')
56
- }
57
-
58
- const pending = signal(false)
59
- const data = signal(undefined)
60
- const error = signal(undefined)
61
-
62
- const { onSuccess, onError, resetOnCall = true } = opts
63
-
64
- let callId = 0
65
-
66
- /** Executes the action and ignores stale responses from superseded calls. */
67
- async function execute(...args) {
68
- const id = ++callId
69
-
70
- batch(() => {
71
- pending(true)
72
- if (resetOnCall) {
73
- data(undefined)
74
- error(undefined)
75
- }
76
- })
77
-
78
- try {
79
- const result = await action(...args)
80
-
81
- if (id !== callId) return result
82
-
83
- batch(() => {
84
- data(result)
85
- pending(false)
86
- })
87
-
88
- if (typeof onSuccess === 'function') {
89
- onSuccess(result)
90
- }
91
-
92
- return result
93
- } catch (err) {
94
- if (id !== callId) return
95
-
96
- batch(() => {
97
- error(err)
98
- pending(false)
99
- })
100
-
101
- if (typeof onError === 'function') {
102
- onError(err)
103
- } else {
104
- console.error(`[fusee] useAction("${action._actionName ?? '?'}") error:`, err)
105
- }
106
- }
107
- }
108
-
109
- /** Clears action state and invalidates any in-flight result. */
110
- function reset() {
111
- batch(() => {
112
- pending(false)
113
- data(undefined)
114
- error(undefined)
115
- })
116
- callId++
117
- }
118
-
119
- const instance = getCurrentInstance()
120
- if (instance) {
121
- instance._unmountHooks.push(() => {
122
- callId++
123
- })
124
- }
125
-
126
- return { execute, pending, data, error, reset }
127
- }
128
-
129
- /** Stores server-provided action data for client-side hydration. */
130
- export function hydrateAction(actionName, data, opts = {}) {
131
- const key = `action:${actionName}`
132
- _actionHydrationRegistry.set(key, {
133
- data,
134
- timestamp: Date.now(),
135
- staleTime: opts.staleTime ?? 0
136
- })
137
- }
138
-
139
- /** Returns hydrated action data when its configured freshness window is valid. */
140
- export function getHydratedAction(actionName, staleTime) {
141
- const key = `action:${actionName}`
142
- const entry = _actionHydrationRegistry.get(key)
143
- if (!entry) return undefined
144
-
145
- if (staleTime !== undefined && (Date.now() - entry.timestamp) > staleTime) {
146
- return undefined
147
- }
148
- if (entry.staleTime && (Date.now() - entry.timestamp) > entry.staleTime) {
149
- return undefined
150
- }
151
-
152
- return entry.data
153
- }
154
-
155
- /** Clears all hydrated action entries. */
156
- export function clearActionHydration() {
157
- _actionHydrationRegistry.clear()
158
- }
159
-
160
- /** Serializes hydrated action entries for transfer to a client. */
161
- export function extractActionHydration() {
162
- const snapshot = {}
163
- for (const [key, entry] of _actionHydrationRegistry) {
164
- snapshot[key] = {
165
- data: entry.data,
166
- timestamp: entry.timestamp,
167
- staleTime: entry.staleTime
168
- }
169
- }
170
- return snapshot
171
- }
172
-
173
- /** Loads a serialized action hydration snapshot into the client registry. */
174
- export function loadActionHydration(snapshot) {
175
- if (!snapshot || typeof snapshot !== 'object') return
176
-
177
- for (const [key, entry] of Object.entries(snapshot)) {
178
- _actionHydrationRegistry.set(key, {
179
- data: entry.data,
180
- timestamp: entry.timestamp,
181
- staleTime: entry.staleTime
182
- })
183
- }
1
+ import { signal, batch } from '../core/signal.js'
2
+ import { getCurrentInstance } from '../core/component-core.js'
3
+
4
+ const ACTION_BASE_URL = '/__fusee/actions'
5
+ const _actionHydrationRegistry = new Map()
6
+
7
+ /** Creates a client action proxy from a function or explicit action name. */
8
+ export function defineAction(fnOrName, opts = {}) {
9
+ const name = opts.name
10
+ || (typeof fnOrName === 'function' ? fnOrName.name : fnOrName)
11
+
12
+ if (!name) {
13
+ throw new Error('[fusee] defineAction() client stub: nu s-a putut determina numele acțiunii')
14
+ }
15
+
16
+ return createActionProxy(name, opts)
17
+ }
18
+
19
+ /** Creates a proxy that POSTs action arguments and returns server data. */
20
+ export function createActionProxy(name, opts = {}) {
21
+ const baseUrl = opts.baseUrl ?? ACTION_BASE_URL
22
+
23
+ /** Sends one action invocation to the configured server endpoint. */
24
+ async function actionProxy(...args) {
25
+ const res = await fetch(`${baseUrl}/${name}`, {
26
+ method: 'POST',
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ ...(opts.headers ?? {})
30
+ },
31
+ body: JSON.stringify({ args })
32
+ })
33
+
34
+ const json = await res.json()
35
+
36
+ if (!res.ok) {
37
+ const err = new Error(json.error ?? `Action "${name}" failed (${res.status})`)
38
+ err.status = res.status
39
+ err.code = json.code
40
+ throw err
41
+ }
42
+
43
+ return json.data
44
+ }
45
+
46
+ actionProxy._isAction = true
47
+ actionProxy._actionName = name
48
+
49
+ return actionProxy
50
+ }
51
+
52
+ /** Wraps an action in reactive pending, data, error, and reset state. */
53
+ export function useAction(action, opts = {}) {
54
+ if (typeof action !== 'function') {
55
+ throw new Error('[fusee] useAction() requires an action function (result of defineAction or createActionProxy)')
56
+ }
57
+
58
+ const pending = signal(false)
59
+ const data = signal(undefined)
60
+ const error = signal(undefined)
61
+
62
+ const { onSuccess, onError, resetOnCall = true } = opts
63
+
64
+ let callId = 0
65
+
66
+ /** Executes the action and ignores stale responses from superseded calls. */
67
+ async function execute(...args) {
68
+ const id = ++callId
69
+
70
+ batch(() => {
71
+ pending(true)
72
+ if (resetOnCall) {
73
+ data(undefined)
74
+ error(undefined)
75
+ }
76
+ })
77
+
78
+ try {
79
+ const result = await action(...args)
80
+
81
+ if (id !== callId) return result
82
+
83
+ batch(() => {
84
+ data(result)
85
+ pending(false)
86
+ })
87
+
88
+ if (typeof onSuccess === 'function') {
89
+ onSuccess(result)
90
+ }
91
+
92
+ return result
93
+ } catch (err) {
94
+ if (id !== callId) return
95
+
96
+ batch(() => {
97
+ error(err)
98
+ pending(false)
99
+ })
100
+
101
+ if (typeof onError === 'function') {
102
+ onError(err)
103
+ } else {
104
+ console.error(`[fusee] useAction("${action._actionName ?? '?'}") error:`, err)
105
+ }
106
+ }
107
+ }
108
+
109
+ /** Clears action state and invalidates any in-flight result. */
110
+ function reset() {
111
+ batch(() => {
112
+ pending(false)
113
+ data(undefined)
114
+ error(undefined)
115
+ })
116
+ callId++
117
+ }
118
+
119
+ const instance = getCurrentInstance()
120
+ if (instance) {
121
+ instance._unmountHooks.push(() => {
122
+ callId++
123
+ })
124
+ }
125
+
126
+ return { execute, pending, data, error, reset }
127
+ }
128
+
129
+ /** Stores server-provided action data for client-side hydration. */
130
+ export function hydrateAction(actionName, data, opts = {}) {
131
+ const key = `action:${actionName}`
132
+ _actionHydrationRegistry.set(key, {
133
+ data,
134
+ timestamp: Date.now(),
135
+ staleTime: opts.staleTime ?? 0
136
+ })
137
+ }
138
+
139
+ /** Returns hydrated action data when its configured freshness window is valid. */
140
+ export function getHydratedAction(actionName, staleTime) {
141
+ const key = `action:${actionName}`
142
+ const entry = _actionHydrationRegistry.get(key)
143
+ if (!entry) return undefined
144
+
145
+ if (staleTime !== undefined && (Date.now() - entry.timestamp) > staleTime) {
146
+ return undefined
147
+ }
148
+ if (entry.staleTime && (Date.now() - entry.timestamp) > entry.staleTime) {
149
+ return undefined
150
+ }
151
+
152
+ return entry.data
153
+ }
154
+
155
+ /** Clears all hydrated action entries. */
156
+ export function clearActionHydration() {
157
+ _actionHydrationRegistry.clear()
158
+ }
159
+
160
+ /** Serializes hydrated action entries for transfer to a client. */
161
+ export function extractActionHydration() {
162
+ const snapshot = {}
163
+ for (const [key, entry] of _actionHydrationRegistry) {
164
+ snapshot[key] = {
165
+ data: entry.data,
166
+ timestamp: entry.timestamp,
167
+ staleTime: entry.staleTime
168
+ }
169
+ }
170
+ return snapshot
171
+ }
172
+
173
+ /** Loads a serialized action hydration snapshot into the client registry. */
174
+ export function loadActionHydration(snapshot) {
175
+ if (!snapshot || typeof snapshot !== 'object') return
176
+
177
+ for (const [key, entry] of Object.entries(snapshot)) {
178
+ _actionHydrationRegistry.set(key, {
179
+ data: entry.data,
180
+ timestamp: entry.timestamp,
181
+ staleTime: entry.staleTime
182
+ })
183
+ }
184
184
  }
@@ -123,8 +123,8 @@ let elementRuntimeReady = false
123
123
  * Prepares plain Node to import app element modules the way Vite does:
124
124
  * - `fusee-framework` (and subpaths) resolves to this framework copy when normal
125
125
  * resolution fails, as scaffolded apps only map it through a Vite alias;
126
- * - the framework entry is loaded first, which installs fusée's globals, so modules
127
- * written for auto-imports (bare `signal()`, `defineElement()`) work as well.
126
+ * - fusée's opt-in globals are installed first, standing in for Vite's auto-imports, so
127
+ * modules that call the API without importing it (bare `signal()`) work as well.
128
128
  */
129
129
  async function prepareElementRuntime() {
130
130
  if (elementRuntimeReady) return
@@ -146,7 +146,7 @@ async function prepareElementRuntime() {
146
146
  register('data:text/javascript,' + encodeURIComponent(hooks))
147
147
  }
148
148
 
149
- await import(pathToFileURL(path.join(frameworkDir, 'index.js')).href)
149
+ await import(pathToFileURL(path.join(frameworkDir, 'globals.js')).href)
150
150
  }
151
151
 
152
152
  /**
@@ -1,87 +1,98 @@
1
- export type ComponentProps = Record<string, any>
2
- export type EmptyProps = Record<string, never>
3
- export type PropSchema = string[] | Record<string, PropConfig>
4
-
5
- export type PropConfig = {
6
- type?: FunctionConstructor | StringConstructor | NumberConstructor | BooleanConstructor
7
- default?: any | (() => any)
8
- required?: boolean
9
- }
10
-
11
- export type EmitFn = (eventName: string, ...args: any[]) => void
12
-
13
- export type Slots = Record<string, string>
14
-
15
- export type SetupContext = {
16
- emit: EmitFn
17
- slots: Slots
18
- }
19
-
20
- export type ComponentInstance = {
21
- props: ComponentProps
22
- state?: any
23
- provides: Record<string | symbol, any>
24
- _mountHooks: (() => void)[]
25
- _unmountHooks: (() => void)[]
26
- _effects: import('./signal').EffectRunner[]
27
- _element: HTMLElement | null
28
- _parent: ComponentInstance | null
29
- _app: any
30
- _components: Record<string, ComponentFactory<any>>
31
- _injector: import('./di').Injector
32
- _ownsInjector: boolean
33
- }
34
-
35
- export type ComponentResult = {
36
- template: string
37
- [key: string]: any
38
- }
39
-
40
- export type ComponentOptions<TProps = ComponentProps, P = PropSchema> = {
41
- props?: P
42
- components?: Record<string, ComponentFactory<any>>
43
- setup: (props: TProps, ctx: SetupContext) => ComponentResult
44
- render?: (state: any, components: Record<string, ComponentFactory<any>>) => any[]
45
- }
46
-
47
- export type ComponentFactory<TProps = ComponentProps> = (props?: TProps, options?: { listeners?: Record<string, Function>, slots?: Slots, parent?: ComponentInstance | Record<string, any> | null }) => ComponentApi
48
-
49
- export type ComponentApi = {
50
- render: (container: HTMLElement) => ComponentInstance
51
- unmount: () => void
52
- instance: ComponentInstance
53
- }
54
-
55
- export declare function onMount(fn: () => void): void
56
- export declare function onUnmount(fn: () => void): void
57
- export declare function parseSlots(slotHTML: string): Slots
58
- export declare function getCurrentInstance(): ComponentInstance | null
59
- export declare function setCurrentInstance(instance: ComponentInstance | null): void
60
-
61
- export declare function provide<T = any>(key: any, value?: T): void
62
- export { inject } from './di'
63
-
64
- type InferPropType<T> = T extends StringConstructor ? string :
65
- T extends NumberConstructor ? number :
66
- T extends BooleanConstructor ? boolean :
67
- any;
68
-
69
- type InferProps<P> = P extends string[]
70
- ? Record<P[number], any>
71
- : P extends Record<string, PropConfig>
72
- ? {
73
- [K in keyof P]: P[K]['required'] extends true
74
- ? InferPropType<P[K]['type']>
75
- : InferPropType<P[K]['type']> | (P[K] extends { default: any } ? never : undefined)
76
- }
77
- : Record<string, any>;
78
-
79
- export declare function defineComponent<P extends PropSchema = any, TProps = InferProps<P>>(options: ComponentOptions<TProps, P>): ComponentFactory<TProps>
80
- export type AsyncComponentLoader<TProps = ComponentProps> = () => Promise<ComponentFactory<TProps> | { default: ComponentFactory<TProps> } | Record<string, any>>
81
-
82
- export type AsyncComponentOptions<TProps = ComponentProps> = {
83
- loader: AsyncComponentLoader<TProps>
84
- loadingComponent?: ComponentFactory<any>
85
- }
86
-
1
+ export type ComponentProps = Record<string, any>
2
+ export type EmptyProps = Record<string, never>
3
+ export type PropSchema = string[] | Record<string, PropConfig>
4
+
5
+ export type PropConfig = {
6
+ type?: FunctionConstructor | StringConstructor | NumberConstructor | BooleanConstructor
7
+ default?: any | (() => any)
8
+ required?: boolean
9
+ }
10
+
11
+ export type EmitFn = (eventName: string, ...args: any[]) => void
12
+
13
+ export type Slots = Record<string, string>
14
+
15
+ export type SetupContext = {
16
+ emit: EmitFn
17
+ slots: Slots
18
+ }
19
+
20
+ export type ComponentInstance = {
21
+ props: ComponentProps
22
+ state?: any
23
+ provides: Record<string | symbol, any>
24
+ _mountHooks: (() => void)[]
25
+ _unmountHooks: (() => void)[]
26
+ _effects: import('./signal').EffectRunner[]
27
+ _element: HTMLElement | null
28
+ _parent: ComponentInstance | null
29
+ _app: any
30
+ _components: Record<string, ComponentFactory<any>>
31
+ _injector: import('./di').Injector
32
+ _ownsInjector: boolean
33
+ }
34
+
35
+ export type ComponentResult = {
36
+ template: string
37
+ [key: string]: any
38
+ }
39
+
40
+ export type ComponentOptions<TProps = ComponentProps, P = PropSchema> = {
41
+ props?: P
42
+ components?: Record<string, ComponentFactory<any>>
43
+ setup: (props: TProps, ctx: SetupContext) => ComponentResult
44
+ render?: (state: any, components: Record<string, ComponentFactory<any>>) => any[]
45
+ }
46
+
47
+ export type ComponentFactory<TProps = ComponentProps> = (props?: TProps, options?: { listeners?: Record<string, Function>, slots?: Slots, parent?: ComponentInstance | Record<string, any> | null }) => ComponentApi
48
+
49
+ export type ComponentApi = {
50
+ render: (container: HTMLElement) => ComponentInstance
51
+ unmount: () => void
52
+ instance: ComponentInstance
53
+ }
54
+
55
+ export declare function onMount(fn: () => void): void
56
+ export declare function onUnmount(fn: () => void): void
57
+ export declare function parseSlots(slotHTML: string): Slots
58
+ export declare function getCurrentInstance(): ComponentInstance | null
59
+ export declare function setCurrentInstance(instance: ComponentInstance | null): void
60
+
61
+ export declare function provide<T = any>(key: any, value?: T): void
62
+ export { inject } from './di'
63
+
64
+ type InferPropType<T> = T extends StringConstructor ? string :
65
+ T extends NumberConstructor ? number :
66
+ T extends BooleanConstructor ? boolean :
67
+ any;
68
+
69
+ type InferProps<P> = P extends string[]
70
+ ? Record<P[number], any>
71
+ : P extends Record<string, PropConfig>
72
+ ? {
73
+ [K in keyof P]: P[K]['required'] extends true
74
+ ? InferPropType<P[K]['type']>
75
+ : InferPropType<P[K]['type']> | (P[K] extends { default: any } ? never : undefined)
76
+ }
77
+ : Record<string, any>;
78
+
79
+ export declare function defineComponent<P extends PropSchema = any, TProps = InferProps<P>>(options: ComponentOptions<TProps, P>): ComponentFactory<TProps>
80
+
81
+ export type CompiledComponentOptions<TProps = ComponentProps, P = PropSchema> = {
82
+ props?: P
83
+ components?: Record<string, ComponentFactory<any>>
84
+ setup?: (props: TProps, ctx: SetupContext) => Record<string, any>
85
+ /** Compiled render function (a .fusee file's `render`, or JSX). String templates are not supported. */
86
+ render?: (state: any, components: Record<string, ComponentFactory<any>>) => any[]
87
+ }
88
+
89
+ /** Like defineComponent(), for compiled `render` functions only: keeps the runtime template compiler out of the bundle. */
90
+ export declare function defineCompiledComponent<P extends PropSchema = any, TProps = InferProps<P>>(options: CompiledComponentOptions<TProps, P>): ComponentFactory<TProps>
91
+ export type AsyncComponentLoader<TProps = ComponentProps> = () => Promise<ComponentFactory<TProps> | { default: ComponentFactory<TProps> } | Record<string, any>>
92
+
93
+ export type AsyncComponentOptions<TProps = ComponentProps> = {
94
+ loader: AsyncComponentLoader<TProps>
95
+ loadingComponent?: ComponentFactory<any>
96
+ }
97
+
87
98
  export declare function defineAsyncComponent<TProps = ComponentProps>(loaderOrOptions: AsyncComponentLoader<TProps> | AsyncComponentOptions<TProps>): ComponentFactory<TProps>