fusee-framework 2.7.0 → 2.7.1
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/README.md +56 -2
- package/bin/create-fusee-linux +0 -0
- package/bin/create-fusee-mac-arm64 +0 -0
- package/bin/create-fusee-mac-intel +0 -0
- package/bin/create-fusee-win.exe +0 -0
- package/framework/auto-import-preset.js +20 -12
- package/framework/auto-imports.d.ts +68 -39
- package/framework/core/compiler.js +310 -310
- package/framework/core/component-core.js +445 -0
- package/framework/core/component.js +11 -440
- package/framework/core/composable.js +29 -29
- package/framework/core/h.js +588 -557
- package/framework/core/jsx-helpers.js +11 -2
- package/framework/core/jsx-runtime.js +73 -73
- package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm +0 -0
- package/framework/core/store.js +333 -333
- package/framework/globals.js +42 -0
- package/framework/index.js +22 -55
- package/framework/router/file-router.js +184 -184
- package/framework/server/actions.js +183 -183
- package/framework/server/generate-manifest.js +3 -3
- package/framework/types/component.d.ts +97 -86
- package/framework/types/index.d.ts +118 -117
- package/package.json +83 -80
- package/framework/core/rust-compiler/Cargo.toml +0 -31
- package/framework/core/rust-compiler/README.md +0 -69
- package/framework/core/rust-compiler/pkg/README.md +0 -69
- package/framework/core/rust-compiler/pkg/fusee_compiler.d.ts +0 -6
- package/framework/core/rust-compiler/pkg/fusee_compiler.js +0 -9
- package/framework/core/rust-compiler/pkg/fusee_compiler_bg.js +0 -137
- package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm.d.ts +0 -11
- package/framework/core/rust-compiler/pkg/package.json +0 -18
- package/framework/core/rust-compiler/src/ast.rs +0 -274
- package/framework/core/rust-compiler/src/errors.rs +0 -204
- package/framework/core/rust-compiler/src/generator.rs +0 -583
- package/framework/core/rust-compiler/src/lexer.rs +0 -414
- package/framework/core/rust-compiler/src/lib.rs +0 -87
- package/framework/core/rust-compiler/src/main_compiler.rs +0 -165
- package/framework/core/rust-compiler/src/parser.rs +0 -516
- package/framework/core/rust-compiler/src/ssr_generator.rs +0 -688
- package/framework/core/rust-compiler/src/transformer.rs +0 -562
- package/framework/core/rust-compiler/src/utils.rs +0 -10
- package/framework/engine-go/actions.go +0 -112
- package/framework/engine-go/cmd/server/main.go +0 -233
- package/framework/engine-go/comet/comet.go +0 -41
- package/framework/engine-go/comet/fragment.go +0 -51
- package/framework/engine-go/dispatcher.go +0 -120
- package/framework/engine-go/elements.go +0 -248
- package/framework/engine-go/evalexpr/evalexpr.go +0 -733
- package/framework/engine-go/go.mod +0 -3
- package/framework/engine-go/hydration.go +0 -43
- package/framework/engine-go/load-helpers.go +0 -29
- package/framework/engine-go/manifest.go +0 -41
- package/framework/engine-go/reactive.go +0 -123
- package/framework/engine-go/render.go +0 -635
- package/framework/engine-go/reqcontext.go +0 -48
- package/framework/engine-go/router.go +0 -85
- package/framework/engine-go/rustast/rustast.go +0 -317
- package/framework/engine-go/ssr.go +0 -103
- package/framework/engine-go/static-assets.go +0 -139
- package/framework/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
|
@@ -1,440 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
setEffectHook(eff => {
|
|
13
|
-
if (currentInstance) currentInstance._effects.push(eff)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
/** Returns the component instance currently running setup or a lifecycle hook. */
|
|
17
|
-
export function getCurrentInstance() {
|
|
18
|
-
return currentInstance
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** Sets the active component instance for framework internals and composables. */
|
|
22
|
-
export function setCurrentInstance(instance) {
|
|
23
|
-
currentInstance = instance
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Global accessor hook for di.js execution context guard
|
|
27
|
-
globalThis.__FUSEE_GET_CURRENT_INSTANCE__ = getCurrentInstance
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Resolves received props against a declared schema, validating types,
|
|
31
|
-
* filling in default values, and checking for missing required props.
|
|
32
|
-
*/
|
|
33
|
-
function resolveProps(schema, received) {
|
|
34
|
-
const isArray = Array.isArray(schema)
|
|
35
|
-
const resolved = {}
|
|
36
|
-
|
|
37
|
-
const normalizedSchema = {}
|
|
38
|
-
if (isArray) {
|
|
39
|
-
schema.forEach(k => normalizedSchema[k.toLowerCase()] = k)
|
|
40
|
-
} else {
|
|
41
|
-
for (const key of Object.keys(schema)) {
|
|
42
|
-
normalizedSchema[key.toLowerCase()] = key
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
for (const receivedKey of Object.keys(received)) {
|
|
47
|
-
const schemaKey = isArray
|
|
48
|
-
? schema.find(k => k.toLowerCase() === receivedKey.toLowerCase())
|
|
49
|
-
: normalizedSchema[receivedKey.toLowerCase()]
|
|
50
|
-
|
|
51
|
-
if (!schemaKey) {
|
|
52
|
-
console.warn(`[framework] Unknown prop "${receivedKey}"`)
|
|
53
|
-
continue
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const descriptor = Object.getOwnPropertyDescriptor(received, receivedKey)
|
|
57
|
-
if (descriptor && descriptor.get) {
|
|
58
|
-
Object.defineProperty(resolved, schemaKey, {
|
|
59
|
-
get: descriptor.get,
|
|
60
|
-
enumerable: true,
|
|
61
|
-
configurable: true
|
|
62
|
-
})
|
|
63
|
-
} else {
|
|
64
|
-
resolved[schemaKey] = received[receivedKey]
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (!isArray) {
|
|
69
|
-
for (const [key, config] of Object.entries(schema)) {
|
|
70
|
-
if (!(key in resolved)) {
|
|
71
|
-
if (config.required) {
|
|
72
|
-
console.error(`[framework] Required prop "${key}" is missing`)
|
|
73
|
-
}
|
|
74
|
-
if (config.default !== undefined) {
|
|
75
|
-
resolved[key] = typeof config.default === 'function'
|
|
76
|
-
? config.default()
|
|
77
|
-
: config.default
|
|
78
|
-
}
|
|
79
|
-
} else if (config.type) {
|
|
80
|
-
const value = resolved[key]
|
|
81
|
-
const expectedType = config.type.name
|
|
82
|
-
const actualType = typeof value
|
|
83
|
-
const typeMap = { String: 'string', Number: 'number', Boolean: 'boolean' }
|
|
84
|
-
if (typeMap[expectedType] && actualType !== typeMap[expectedType]) {
|
|
85
|
-
console.warn(`[framework] Prop "${key}" expected ${expectedType} but got ${actualType}`)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return resolved
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** Creates a batched event emitter that safely dispatches payloads to component listeners. */
|
|
95
|
-
function createEmit(listeners) {
|
|
96
|
-
return function emit(eventName, ...args) {
|
|
97
|
-
const handler = listeners[eventName]
|
|
98
|
-
if (typeof handler === 'function') {
|
|
99
|
-
batch(() => handler(...args))
|
|
100
|
-
} else if (handler !== undefined) {
|
|
101
|
-
console.warn(`[framework] emit("${eventName}"): listener is not a function`)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Parses named template slots and returns their content grouped by slot name. */
|
|
107
|
-
export function parseSlots(slotHTML) {
|
|
108
|
-
const slots = { default: '' }
|
|
109
|
-
if (!slotHTML || !slotHTML.trim()) return slots
|
|
110
|
-
|
|
111
|
-
const namedSlotRe = /<template\s+slot="([^"]+)"[^>]*>([\s\S]*?)<\/template>/gi
|
|
112
|
-
let remaining = slotHTML
|
|
113
|
-
let match
|
|
114
|
-
|
|
115
|
-
while ((match = namedSlotRe.exec(slotHTML)) !== null) {
|
|
116
|
-
slots[match[1]] = match[2].trim()
|
|
117
|
-
remaining = remaining.replace(match[0], '')
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const defaultContent = remaining.trim()
|
|
121
|
-
if (defaultContent) slots.default = defaultContent
|
|
122
|
-
|
|
123
|
-
return slots
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/** Replaces slot outlets in a component template with supplied slot content. */
|
|
127
|
-
function resolveSlots(template, slots) {
|
|
128
|
-
let result = template.replace(/<slot\s+name="([^"]+)"\s*>[\s\S]*?<\/slot>/gi, (match, name) => {
|
|
129
|
-
return slots[name] ?? ''
|
|
130
|
-
})
|
|
131
|
-
result = result.replace(/<slot\s*>[\s\S]*?<\/slot>/gi, () => {
|
|
132
|
-
return slots.default ?? ''
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
result = result.replace(/<slot\s+name="([^"]+)"\s*\/>/gi, (_, name) => slots[name] ?? '')
|
|
136
|
-
result = result.replace(/<slot\s*\/>/gi, () => slots.default ?? '')
|
|
137
|
-
return result
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/** Registers a callback to run after the component has rendered. */
|
|
141
|
-
export function onMount(fn) {
|
|
142
|
-
if (currentInstance) currentInstance._mountHooks.push(fn)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** Registers a callback to run when the component is unmounted. */
|
|
146
|
-
export function onUnmount(fn) {
|
|
147
|
-
if (currentInstance) currentInstance._unmountHooks.push(fn)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/** Creates a component factory with setup, rendering, props, slots, and lifecycle state. */
|
|
151
|
-
export function defineComponent(options) {
|
|
152
|
-
return Object.assign(function ComponentFactory(props = {}, { listeners = {}, slots = {}, parent = null } = {}) {
|
|
153
|
-
const effectiveParent = parent || currentInstance
|
|
154
|
-
|
|
155
|
-
const parentInjector = (effectiveParent && effectiveParent._injector) || rootInjector
|
|
156
|
-
const parentProvides = effectiveParent ? (effectiveParent.provides || effectiveParent._provides || null) : null
|
|
157
|
-
const parentApp = effectiveParent ? (effectiveParent._app || (effectiveParent._provides ? effectiveParent : null)) : (options._app || null)
|
|
158
|
-
const parentComponents = effectiveParent ? (effectiveParent._components || effectiveParent.components || null) : (parentApp ? (parentApp._components || parentApp.components || null) : {})
|
|
159
|
-
|
|
160
|
-
const rawMergedComponents = {
|
|
161
|
-
...(parentComponents || {}),
|
|
162
|
-
...(options.components || {})
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const mergedComponents = new Proxy(rawMergedComponents, {
|
|
166
|
-
get(target, prop, receiver) {
|
|
167
|
-
if (typeof prop !== 'string') return Reflect.get(target, prop, receiver)
|
|
168
|
-
if (prop in target) return target[prop]
|
|
169
|
-
const lower = prop.toLowerCase()
|
|
170
|
-
for (const key of Object.keys(target)) {
|
|
171
|
-
if (key.toLowerCase() === lower) {
|
|
172
|
-
return target[key]
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return undefined
|
|
176
|
-
},
|
|
177
|
-
has(target, prop) {
|
|
178
|
-
if (typeof prop !== 'string') return Reflect.has(target, prop)
|
|
179
|
-
if (prop in target) return true
|
|
180
|
-
const lower = prop.toLowerCase()
|
|
181
|
-
for (const key of Object.keys(target)) {
|
|
182
|
-
if (key.toLowerCase() === lower) return true
|
|
183
|
-
}
|
|
184
|
-
return false
|
|
185
|
-
}
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
const instance = {
|
|
189
|
-
props: options.props ? resolveProps(options.props, props) : props,
|
|
190
|
-
_mountHooks: [],
|
|
191
|
-
_unmountHooks: [],
|
|
192
|
-
_effects: [],
|
|
193
|
-
_element: null,
|
|
194
|
-
_parent: effectiveParent,
|
|
195
|
-
_app: parentApp,
|
|
196
|
-
_components: mergedComponents,
|
|
197
|
-
provides: parentProvides ? Object.create(parentProvides) : Object.create(null),
|
|
198
|
-
_injector: parentInjector,
|
|
199
|
-
_ownsInjector: false,
|
|
200
|
-
_host: options._host || null,
|
|
201
|
-
_detachContext: null
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const emit = createEmit(listeners)
|
|
205
|
-
|
|
206
|
-
const previousInstance = currentInstance
|
|
207
|
-
currentInstance = instance
|
|
208
|
-
let result
|
|
209
|
-
try {
|
|
210
|
-
result = runInContext(instance._injector, () => {
|
|
211
|
-
return options.setup ? options.setup(instance.props, { emit, slots }) : {}
|
|
212
|
-
})
|
|
213
|
-
instance.state = result
|
|
214
|
-
if (result && typeof result === 'object') {
|
|
215
|
-
result._instance = instance
|
|
216
|
-
// _nativeSlots: rendered into a shadow root, where the browser distributes slots.
|
|
217
|
-
if (options._nativeSlots) result._slots = NATIVE_SLOT_OUTLETS
|
|
218
|
-
}
|
|
219
|
-
} finally {
|
|
220
|
-
currentInstance = previousInstance
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function render(container) {
|
|
224
|
-
const prevInstance = currentInstance
|
|
225
|
-
currentInstance = instance
|
|
226
|
-
try {
|
|
227
|
-
instance._element = container
|
|
228
|
-
// Before mounting the template, so custom elements connecting during it can find this scope.
|
|
229
|
-
if (!instance._detachContext) instance._detachContext = attachContextResponder(container, instance)
|
|
230
|
-
|
|
231
|
-
if (options.render) {
|
|
232
|
-
const nodes = options.render(result, mergedComponents)
|
|
233
|
-
container.innerHTML = ''
|
|
234
|
-
|
|
235
|
-
function mountNode(fnode) {
|
|
236
|
-
if (!fnode || !fnode.node) return
|
|
237
|
-
container.appendChild(fnode.node)
|
|
238
|
-
|
|
239
|
-
if (fnode.effects) {
|
|
240
|
-
instance._effects.push(...fnode.effects)
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (fnode.children) {
|
|
244
|
-
for (const child of fnode.children) {
|
|
245
|
-
mountNode(child)
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
for (const node of nodes) {
|
|
251
|
-
mountNode(node)
|
|
252
|
-
}
|
|
253
|
-
} else {
|
|
254
|
-
const template = result?.template || ''
|
|
255
|
-
const resolvedTemplate = options._nativeSlots ? template : resolveSlots(template, slots)
|
|
256
|
-
const { effects } = mountTemplate(
|
|
257
|
-
resolvedTemplate,
|
|
258
|
-
container,
|
|
259
|
-
result,
|
|
260
|
-
mergedComponents
|
|
261
|
-
)
|
|
262
|
-
instance._effects.push(...effects)
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
for (const hook of instance._mountHooks)
|
|
266
|
-
hook()
|
|
267
|
-
|
|
268
|
-
return instance
|
|
269
|
-
} finally {
|
|
270
|
-
currentInstance = prevInstance
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function unmount() {
|
|
275
|
-
for (const hook of instance._unmountHooks) hook()
|
|
276
|
-
const effects = instance._effects
|
|
277
|
-
for (let i = effects.length - 1; i >= 0; i--) {
|
|
278
|
-
const cleanup = effects[i]
|
|
279
|
-
if (typeof cleanup === 'function') cleanup()
|
|
280
|
-
}
|
|
281
|
-
instance._effects = []
|
|
282
|
-
if (instance._detachContext) {
|
|
283
|
-
instance._detachContext()
|
|
284
|
-
instance._detachContext = null
|
|
285
|
-
}
|
|
286
|
-
if (instance._element) {
|
|
287
|
-
instance._element.innerHTML = ''
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return { render, unmount, instance }
|
|
292
|
-
}, { _options: options })
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/** Provides a value or dependency injection configuration down to descendant components. */
|
|
296
|
-
export function provide(key, value) {
|
|
297
|
-
if (!currentInstance) return
|
|
298
|
-
|
|
299
|
-
const provideKey = (key && typeof key === 'object' && key.provide) ? key.provide : key
|
|
300
|
-
currentInstance.provides[provideKey] = value
|
|
301
|
-
|
|
302
|
-
if (!currentInstance._ownsInjector) {
|
|
303
|
-
currentInstance._injector = new EnvironmentInjector([], currentInstance._injector)
|
|
304
|
-
currentInstance._ownsInjector = true
|
|
305
|
-
replaceActiveInjector(currentInstance._injector)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (value === undefined && key && key.provide) {
|
|
309
|
-
currentInstance._injector.provide(key)
|
|
310
|
-
} else if (value && typeof value === 'object' && (value.useClass || value.useFactory || value.useExisting)) {
|
|
311
|
-
currentInstance._injector.provide({ provide: key, ...value })
|
|
312
|
-
} else {
|
|
313
|
-
currentInstance._injector.provide({ provide: key, useValue: value })
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/** Defines an asynchronous component wrapper that handles lazy loading, placeholders, and error states. */
|
|
318
|
-
export function defineAsyncComponent(loaderOrOptions) {
|
|
319
|
-
const options = typeof loaderOrOptions === 'function'
|
|
320
|
-
? { loader: loaderOrOptions }
|
|
321
|
-
: loaderOrOptions
|
|
322
|
-
|
|
323
|
-
return function AsyncComponentFactory(props = {}, { listeners = {}, slots = {}, parent = null } = {}) {
|
|
324
|
-
const effectiveParent = parent || currentInstance
|
|
325
|
-
const parentInjector = (effectiveParent && effectiveParent._injector) || rootInjector
|
|
326
|
-
const parentProvides = effectiveParent
|
|
327
|
-
? (effectiveParent.provides || effectiveParent._provides || null)
|
|
328
|
-
: null
|
|
329
|
-
const parentApp = effectiveParent ? effectiveParent._app : null
|
|
330
|
-
const parentComponents = effectiveParent ? effectiveParent._components : (parentApp ? parentApp._components : {})
|
|
331
|
-
|
|
332
|
-
const instance = {
|
|
333
|
-
props,
|
|
334
|
-
_mountHooks: [],
|
|
335
|
-
_unmountHooks: [],
|
|
336
|
-
_effects: [],
|
|
337
|
-
_element: null,
|
|
338
|
-
_parent: effectiveParent,
|
|
339
|
-
_app: parentApp,
|
|
340
|
-
_components: parentComponents,
|
|
341
|
-
provides: parentProvides ? Object.create(parentProvides) : Object.create(null),
|
|
342
|
-
_injector: parentInjector,
|
|
343
|
-
_ownsInjector: false
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
let childApi = null
|
|
347
|
-
let loadingApi = null
|
|
348
|
-
let isUnmounted = false
|
|
349
|
-
|
|
350
|
-
function render(container) {
|
|
351
|
-
const prevInstance = currentInstance
|
|
352
|
-
currentInstance = instance
|
|
353
|
-
try {
|
|
354
|
-
instance._element = container
|
|
355
|
-
|
|
356
|
-
if (options.loadingComponent) {
|
|
357
|
-
loadingApi = options.loadingComponent({}, { parent: instance })
|
|
358
|
-
loadingApi.render(container)
|
|
359
|
-
} else {
|
|
360
|
-
container.innerHTML = '<!-- async component boundary -->'
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
Promise.resolve(options.loader())
|
|
364
|
-
.then(comp => {
|
|
365
|
-
if (isUnmounted) return
|
|
366
|
-
let ComponentFn = comp.default || comp
|
|
367
|
-
|
|
368
|
-
if (typeof ComponentFn === 'object' && ComponentFn !== null) {
|
|
369
|
-
ComponentFn = Object.values(ComponentFn).find(v => typeof v === 'function') || ComponentFn
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (loadingApi) {
|
|
373
|
-
loadingApi.unmount()
|
|
374
|
-
loadingApi = null
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
childApi = ComponentFn(props, { listeners, slots, parent: instance })
|
|
378
|
-
|
|
379
|
-
container.innerHTML = ''
|
|
380
|
-
childApi.render(container)
|
|
381
|
-
})
|
|
382
|
-
.catch(err => {
|
|
383
|
-
console.error('[framework] Failed to load async component:', err)
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
return instance
|
|
387
|
-
} finally {
|
|
388
|
-
currentInstance = prevInstance
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function unmount() {
|
|
393
|
-
isUnmounted = true
|
|
394
|
-
if (loadingApi) loadingApi.unmount()
|
|
395
|
-
if (childApi) childApi.unmount()
|
|
396
|
-
if (instance._element && !childApi && !loadingApi) {
|
|
397
|
-
instance._element.innerHTML = ''
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return { render, unmount, instance }
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/** Resolves and injects a provided value or dependency from the current component's provider tree or global injector. */
|
|
406
|
-
export function inject(key, defaultValue, options) {
|
|
407
|
-
const instance = getCurrentInstance()
|
|
408
|
-
|
|
409
|
-
let actualOptions = undefined
|
|
410
|
-
let actualDefaultValue = undefined
|
|
411
|
-
|
|
412
|
-
if (defaultValue && typeof defaultValue === 'object' &&
|
|
413
|
-
('optional' in defaultValue || 'skipSelf' in defaultValue || 'self' in defaultValue)) {
|
|
414
|
-
actualOptions = defaultValue
|
|
415
|
-
} else {
|
|
416
|
-
actualDefaultValue = defaultValue
|
|
417
|
-
if (options && typeof options === 'object') {
|
|
418
|
-
actualOptions = options
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const provided = resolveProvided(instance, key, actualOptions)
|
|
423
|
-
if (provided.found) return provided.value
|
|
424
|
-
|
|
425
|
-
// Inside a custom element, providers outside fusée (e.g. @lit/context) answer next.
|
|
426
|
-
const host = actualOptions?.self ? null : findInstanceHost(instance)
|
|
427
|
-
if (host) {
|
|
428
|
-
const requested = requestContext(host, key)
|
|
429
|
-
if (requested.found) return requested.value
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
try {
|
|
433
|
-
return diInject(key, actualOptions !== undefined ? actualOptions : actualDefaultValue)
|
|
434
|
-
} catch (err) {
|
|
435
|
-
if (actualDefaultValue !== undefined) {
|
|
436
|
-
return actualDefaultValue
|
|
437
|
-
}
|
|
438
|
-
throw err
|
|
439
|
-
}
|
|
440
|
-
}
|
|
1
|
+
// Components with string templates: defineComponent() brings the runtime template compiler.
|
|
2
|
+
// Everything else lives in component-core.js, which compiled-only code can import alone.
|
|
3
|
+
import { mountTemplate } from './compiler.js'
|
|
4
|
+
import { createComponentDefinition } from './component-core.js'
|
|
5
|
+
|
|
6
|
+
export * from './component-core.js'
|
|
7
|
+
|
|
8
|
+
/** Creates a component factory with setup, rendering (string template or compiled render), props, slots, and lifecycle state. */
|
|
9
|
+
export function defineComponent(options) {
|
|
10
|
+
return createComponentDefinition(options, mountTemplate)
|
|
11
|
+
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { getCurrentInstance } from './component.js'
|
|
2
|
-
|
|
3
|
-
/** Marks a function as a composable while preserving its name and call shape. */
|
|
4
|
-
export function defineComposable(fn) {
|
|
5
|
-
const composable = function (...args) {
|
|
6
|
-
return fn(...args)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
composable._isComposable = true
|
|
10
|
-
|
|
11
|
-
Object.defineProperty(composable, 'name', {
|
|
12
|
-
value: fn.name || 'composable',
|
|
13
|
-
configurable: true
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
return composable
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Warns when a composable runs outside component setup and returns the instance. */
|
|
20
|
-
export function assertSetupContext(name) {
|
|
21
|
-
const instance = getCurrentInstance()
|
|
22
|
-
if (!instance) {
|
|
23
|
-
console.warn(
|
|
24
|
-
`[framework] ${name ? name + ' ' : ''}composable was called outside of setup(). ` +
|
|
25
|
-
`Lifecycle hooks (onMount, onUnmount) and injections will not work.`
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
return instance
|
|
29
|
-
}
|
|
1
|
+
import { getCurrentInstance } from './component-core.js'
|
|
2
|
+
|
|
3
|
+
/** Marks a function as a composable while preserving its name and call shape. */
|
|
4
|
+
export function defineComposable(fn) {
|
|
5
|
+
const composable = function (...args) {
|
|
6
|
+
return fn(...args)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
composable._isComposable = true
|
|
10
|
+
|
|
11
|
+
Object.defineProperty(composable, 'name', {
|
|
12
|
+
value: fn.name || 'composable',
|
|
13
|
+
configurable: true
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
return composable
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Warns when a composable runs outside component setup and returns the instance. */
|
|
20
|
+
export function assertSetupContext(name) {
|
|
21
|
+
const instance = getCurrentInstance()
|
|
22
|
+
if (!instance) {
|
|
23
|
+
console.warn(
|
|
24
|
+
`[framework] ${name ? name + ' ' : ''}composable was called outside of setup(). ` +
|
|
25
|
+
`Lifecycle hooks (onMount, onUnmount) and injections will not work.`
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
return instance
|
|
29
|
+
}
|