@uniweb/runtime 0.5.15 → 0.5.17
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/package.json +2 -2
- package/src/index.jsx +59 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/runtime",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.17",
|
|
4
4
|
"description": "Minimal runtime for loading Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"node": ">=20.19"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@uniweb/core": "0.4.
|
|
34
|
+
"@uniweb/core": "0.4.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@vitejs/plugin-react": "^4.5.2",
|
package/src/index.jsx
CHANGED
|
@@ -130,6 +130,42 @@ async function loadFoundation(source) {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Load extensions (secondary foundations) in parallel
|
|
135
|
+
* @param {Array<string|Object>} urls - Extension URLs or {url, cssUrl} objects
|
|
136
|
+
* @param {Object} uniwebInstance - The Uniweb instance to register extensions on
|
|
137
|
+
*/
|
|
138
|
+
async function loadExtensions(urls, uniwebInstance) {
|
|
139
|
+
if (!urls?.length) return
|
|
140
|
+
|
|
141
|
+
// Resolve extension URLs against base path for subdirectory deployments
|
|
142
|
+
// e.g., /effects/foundation.js → /templates/extensions/effects/foundation.js
|
|
143
|
+
const basePath = import.meta.env?.BASE_URL || '/'
|
|
144
|
+
function resolveUrl(source) {
|
|
145
|
+
if (basePath === '/') return source
|
|
146
|
+
if (typeof source === 'string' && source.startsWith('/')) {
|
|
147
|
+
return basePath + source.slice(1)
|
|
148
|
+
}
|
|
149
|
+
if (typeof source === 'object' && source.url?.startsWith('/')) {
|
|
150
|
+
return { ...source, url: basePath + source.url.slice(1) }
|
|
151
|
+
}
|
|
152
|
+
return source
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const results = await Promise.allSettled(
|
|
156
|
+
urls.map(url => loadFoundation(resolveUrl(url)))
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
for (let i = 0; i < results.length; i++) {
|
|
160
|
+
if (results[i].status === 'fulfilled') {
|
|
161
|
+
uniwebInstance.registerExtension(results[i].value)
|
|
162
|
+
console.log(`[Runtime] Extension loaded: ${urls[i]}`)
|
|
163
|
+
} else {
|
|
164
|
+
console.warn(`[Runtime] Extension failed to load: ${urls[i]}`, results[i].reason)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
133
169
|
/**
|
|
134
170
|
* Map friendly family names to react-icons codes
|
|
135
171
|
* The existing CDN uses react-icons structure: /{familyCode}/{familyCode}-{name}.svg
|
|
@@ -411,6 +447,12 @@ async function initRuntime(foundationSource, options = {}) {
|
|
|
411
447
|
uniwebInstance.setFoundationConfig(foundation.capabilities)
|
|
412
448
|
}
|
|
413
449
|
|
|
450
|
+
// Load extensions (secondary foundations)
|
|
451
|
+
const extensions = configData?.config?.extensions
|
|
452
|
+
if (extensions?.length) {
|
|
453
|
+
await loadExtensions(extensions, uniwebInstance)
|
|
454
|
+
}
|
|
455
|
+
|
|
414
456
|
// Render the app
|
|
415
457
|
render({ development, basename })
|
|
416
458
|
|
|
@@ -452,15 +494,23 @@ async function initRuntime(foundationSource, options = {}) {
|
|
|
452
494
|
/**
|
|
453
495
|
* Simplified entry point for sites
|
|
454
496
|
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
497
|
+
* Template main.js calls this with config + foundation/styles promises:
|
|
498
|
+
*
|
|
499
|
+
* start({
|
|
500
|
+
* config: __FOUNDATION_CONFIG__,
|
|
501
|
+
* styles: import('#foundation/styles'),
|
|
502
|
+
* foundation: import('#foundation')
|
|
503
|
+
* })
|
|
504
|
+
*
|
|
505
|
+
* In runtime mode, the foundation/styles promises resolve to noop modules
|
|
506
|
+
* (configured by the site Vite plugin) and are ignored.
|
|
458
507
|
*
|
|
459
508
|
* @param {Object} options
|
|
509
|
+
* @param {Object} options.config - Build-time config from __FOUNDATION_CONFIG__
|
|
460
510
|
* @param {Promise} options.foundation - Promise from import('#foundation')
|
|
461
511
|
* @param {Promise} options.styles - Promise from import('#foundation/styles')
|
|
462
512
|
*/
|
|
463
|
-
async function start({ foundation, styles } = {}) {
|
|
513
|
+
async function start({ config, foundation, styles } = {}) {
|
|
464
514
|
// Try __DATA__ first (dynamic backends inject combined config + content)
|
|
465
515
|
const data = await decodeData()
|
|
466
516
|
|
|
@@ -472,15 +522,14 @@ async function start({ foundation, styles } = {}) {
|
|
|
472
522
|
)
|
|
473
523
|
}
|
|
474
524
|
|
|
475
|
-
//
|
|
476
|
-
const config
|
|
477
|
-
typeof __FOUNDATION_CONFIG__ !== 'undefined' ? __FOUNDATION_CONFIG__ : { mode: 'bundled' }
|
|
525
|
+
// Use provided config, or fall back to bundled mode
|
|
526
|
+
const mode = config?.mode ?? 'bundled'
|
|
478
527
|
|
|
479
|
-
if (
|
|
480
|
-
// Runtime mode
|
|
528
|
+
if (mode === 'runtime') {
|
|
529
|
+
// Runtime mode - foundation loaded from URL
|
|
481
530
|
return initRuntime({ url: config.url, cssUrl: config.cssUrl })
|
|
482
531
|
} else {
|
|
483
|
-
// Bundled mode -
|
|
532
|
+
// Bundled mode - use the provided foundation/styles promises
|
|
484
533
|
const [foundationModule] = await Promise.all([foundation, styles])
|
|
485
534
|
return initRuntime(foundationModule)
|
|
486
535
|
}
|