@fulgurjs/federation 0.7.1 → 0.8.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/CHANGELOG.md +29 -0
- package/README.md +129 -5
- package/client.d.ts +29 -0
- package/dist/chunk-CK42RK2O.js +38 -0
- package/dist/{chunk-6EGDSX3S.js → chunk-P4DGTHMF.js} +1 -1
- package/dist/context.cjs +88 -0
- package/dist/context.d.cts +55 -0
- package/dist/context.d.ts +55 -0
- package/dist/context.js +50 -0
- package/dist/index.cjs +2 -2
- package/dist/index.js +2 -2
- package/dist/runtime.js +1 -1
- package/dist/vue.js +5 -35
- package/docs//350/277/201/347/247/273/346/214/207/345/215/227.md +65 -0
- package/package.json +10 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.1(2026-09-21)
|
|
4
|
+
|
|
5
|
+
### 文档(0.8.0 使用文档补齐,零运行时变化)
|
|
6
|
+
|
|
7
|
+
- **README 新增 §9.1「乾坤功能融合三件套 + 联邦诊断面板」**:A 保活(`keepAlive: true` 页面级配置、include 白名单与 max=8 语义、默认关的原因)/ B 骨架屏(内置自动,无需配置)/ C 空闲预载(`PREFETCH_REMOTES` 开关)/ D 诊断面板(`/fulgurjs-demo` 六块内容表)/ E IDE 说明。
|
|
8
|
+
- **README §9 方法模块补端到端示例**(exposes 声明 → api.ts 纯函数 → loadRemote 调用三步)。
|
|
9
|
+
- **迁移指南新增「三E 乾坤融合三件套 + 诊断面板」速查表**(配置入口/默认值/行为),含 IDE 提示。
|
|
10
|
+
- **IDE 说明**(同入每应用 `src/fulgurjs/README.md` 模板):`types/*.d.ts` 生成物在 VSCode/Volar 打开时可能显示跨工程「找不到模块 '@/...'」波浪线(推断项目检查工程外 .vue 的显示问题)——命令行 `vue-tsc --noEmit` 走本应用 tsconfig 为 0 错误,构建不受影响;升级后 context 导入报 ts(2307) 为 IDE 旧包缓存,Restart TS Server 即消。
|
|
11
|
+
- 修复:集成器 pages.ts 模板注释与现场对齐(`defineAsyncComponent` 不支持 `name` 选项的表述清理)。
|
|
12
|
+
|
|
13
|
+
## 0.8.0(2026-09-20)
|
|
14
|
+
|
|
15
|
+
### 新增(跨应用传值与方法引用收编 + 乾坤功能融合,设计文档 docs/跨应用传值与方法引用设计方案-2026-09-20.md 定稿实施)
|
|
16
|
+
|
|
17
|
+
- **`@fulgurjs/federation/context` 新子路径(~2KB 独立文件,与 `./vue` 同模式)**:
|
|
18
|
+
- `provideFulgurjsAppContext(config)`——宿主桥一次性写入跨应用上下文(merge 语义,幂等可多次,后写覆盖);
|
|
19
|
+
- `getFulgurjsAppContext()`——读快照(传输层快照 + 函数引用,非响应式,与乾坤 props 同语义;嵌套对象如 `events` 引用共享);
|
|
20
|
+
- `requireFulgurjsAppContext(...keys)`——远程 boot 显式校验消费:缺任一键 → **`CC-001`** 三段式抛错(got/expected/example 指向宿主桥),页面无运行时单例(独立直开远程页)→ **`CC-002`** 显式(修法 = 经宿主联邦加载);
|
|
21
|
+
- `FulgurjsAppContext` 类型(标准字段表:`user` / `token` / `getToken` / `store` / `hostApp` / `locale` / `events` + `[key: string]` 项目扩展位)随子路径与 `client.d.ts` 双发布。
|
|
22
|
+
- **方法引用一等公民两条通道**:① context 携带函数引用(`getToken` / `events.main.getDictItems` 高频热路径直调、子应用反向注册 `events.bpm.formEvent`);② exposes 方法模块 `loadRemote('remote/api')`(低频/重逻辑跨应用调用,dts 类型直连自动覆盖)。
|
|
23
|
+
- **架构边界(gzip 红线不破)**:runtime.js 逻辑 0.8.0 **零改动**(仅版本常量随版本走)——context 子路径内部经 `globalThis.__FULGURJS_RUNTIME__` 单例委托运行时既有方法,存储与旧 W4(`__FULGURJS_APP_CONFIG__`)同一份。
|
|
24
|
+
- **旧名 deprecated**:`provideFulgurjsAppConfig / getFulgurjsAppConfig` 继续可用(存储同一份),`client.d.ts` 与 README 标 `@deprecated` 指向新名,0.9 删除。
|
|
25
|
+
- **错误码总表 30 → 32**:新增 CC 段(`CC-001` context 必需字段缺失 / `CC-002` 运行时单例不可用)。
|
|
26
|
+
|
|
27
|
+
### 文档(乾坤功能融合配套,全部宿主/模板侧,插件 runtime 零改动)
|
|
28
|
+
|
|
29
|
+
- README 特性声明新增「CSP 友好(原生 ESM 无 eval)」;新增 §9 AppContext API 参考(字段表/时序契约/方法模块规范);迁移指南新增「跨应用传值」节与「页面卸载清理清单」节(乾坤 unmount 强制清理的联邦等价物:`onUnmounted` 摘除 window 级监听/定时器/context.events 反向注册)。
|
|
30
|
+
- 乾坤功能融合三件套(保活 keep-alive 白名单 / 页面加载骨架屏 / 空闲预载编排)与联邦诊断面板均为**集成器模板/宿主项目侧**能力,用法见迁移指南与 `fulgurjs.config.ts` 模板注释;调研依据见 docs/qiankun功能融合调研-2026-09-20.md(16 项逐项对照:9 项已有、4 项与架构哲学冲突不搬、3 项值得搬 + inspector 概念轻量化落地)。
|
|
31
|
+
|
|
3
32
|
## 0.7.1(2026-09-20)
|
|
4
33
|
|
|
5
34
|
### 修复(TS 子路径类型兼容,mes-zc testbed 用户 IDE 实测暴露)
|
package/README.md
CHANGED
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
- **HMR 全链路**:remote 改动 → host 页面热更,L1 组件热替换 / L2 状态保留 / L3 错误覆盖与恢复
|
|
33
33
|
- **零报错纪律**:配置问题启动瞬间三段式报错;联邦失败显式抛错(错误码 + 可执行修复建议),**无任何静默兜底路径**
|
|
34
34
|
- **CLI(主包内置 bin)**:`fulgurjs init`——`fulgurjs.config.ts` 单配置驱动的迁移生成器(模板 = 真实工程验证形态:vite 配置/路由表/桥/联邦启动器/NGINX conf 全量编码,锚点补丁幂等可续跑);`fulgurjs doctor`——部署面体检(remoteEntry/manifest/HTML 缓存头与形态、CORS、chunk 抽样可达、版本 skew 预演、`--dev` 端口探测)
|
|
35
|
-
-
|
|
35
|
+
- **跨应用传值与方法引用(0.8.0 起)**:`@fulgurjs/federation/context` 子路径——`provideFulgurjsAppContext` / `getFulgurjsAppContext` / `requireFulgurjsAppContext`(缺键 `CC-001` 三段式、独立直开远程页 `CC-002` 显式)。宿主桥一次写入页面级单例(user/token/getToken/store/hostApp/locale/events 标准字段 + 项目扩展位),远程 boot 显式校验消费;方法引用两条通道 = context 携带函数引用(热路径直调)+ exposes 方法模块 `loadRemote('remote/api')`(低频重逻辑)。旧名 `provideFulgurjsAppConfig/getFulgurjsAppConfig` 保留为 deprecated 别名(存储同一份,0.9 删)。数据语义 = 传输层快照 + 函数引用,非响应式(与乾坤 props 同语义;"实时"靠函数引用拉取 / 宿主 pinia 共享 / 登录刷新三通道)
|
|
36
36
|
- **Vue 直渲染(0.7.0 起)**:`remoteComponent('remote/X')`(`@fulgurjs/federation/vue` 子路径)——`defineAsyncComponent + loadRemote` 的标准封装,加载失败显式错误占位(错误码+根因+修法),runtime.js 零框架依赖零体积增量
|
|
37
|
-
-
|
|
37
|
+
- **CSP 友好**:原生 ESM 加载路径全程无 `eval` / `new Function`,可在严格 CSP(无 `unsafe-eval`)下运行
|
|
38
|
+
- **全链路错误码体系(32 码)**:CFG/DEV/BLD/MFU/CC 五段 + 手册 §8 码表防漂移校验
|
|
38
39
|
|
|
39
40
|
## 安装
|
|
40
41
|
|
|
@@ -248,8 +249,8 @@ import { loadRemote, provideFulgurjsAppConfig } from 'virtual:fulgurjs-runtime'
|
|
|
248
249
|
| `registerShare` | `(scope, name, version, get, opts?) => void` | 手工注册共享模块(一般由 init 模块自动完成) |
|
|
249
250
|
| `initSharing` | `(scopeName?) => ShareScopeMap` | 初始化共享作用域(一般由 init 模块自动完成) |
|
|
250
251
|
| `registerPlugins` | `(plugins: RuntimePlugin[]) => void` | 注册运行时插件(见下) |
|
|
251
|
-
| `provideFulgurjsAppConfig` | `(config: Record<string, any>) => void` |
|
|
252
|
-
| `getFulgurjsAppConfig` | `() => Record<string, any>` |
|
|
252
|
+
| `provideFulgurjsAppConfig` | `(config: Record<string, any>) => void` | **@deprecated(0.8.0)** 改用 `@fulgurjs/federation/context` 的 `provideFulgurjsAppContext`(存储同一份;见 §9) |
|
|
253
|
+
| `getFulgurjsAppConfig` | `() => Record<string, any>` | **@deprecated(0.8.0)** 改用 `@fulgurjs/federation/context` 的 `getFulgurjsAppContext`(存储同一份;见 §9) |
|
|
253
254
|
| `getRuntime` | `() => FulgurjsRuntime` | 取运行时单例本体(与 `__FULGURJS_RUNTIME__` 同一实例) |
|
|
254
255
|
| `version` | `string` | 运行时/插件版本(跨源副本一致性诊断用) |
|
|
255
256
|
| `unwrapDefault` | `(ns: any) => any` | ESM/CJS default interop 工具 |
|
|
@@ -366,7 +367,7 @@ export default defineFulgurjsConfig({
|
|
|
366
367
|
| `fulgurjs init --config <path>` | 校验配置(CFG 三段式报错)+ 输出各应用 `federation()` 粘贴块、NGINX no-cache 站点模板、8 条通用核对清单 |
|
|
367
368
|
| `fulgurjs doctor --base <URL> --apps <a,b,c>` | 部署体检:remoteEntry/manifest/index.html 的 200/no-cache/JS 形态、CORS、chunk 抽样可达、版本 skew 预演。`--dev` 检查 dev 容器入口;`--json` 输出 JSON(CI 断言);`--chunk-sample N` 控制抽样数(默认 16)。**退出码:有 FAIL 即 1**,可直接做 CI 门禁 |
|
|
368
369
|
|
|
369
|
-
### 6. 错误码总表(
|
|
370
|
+
### 6. 错误码总表(32 个)
|
|
370
371
|
|
|
371
372
|
| 段 | 码 | 含义 |
|
|
372
373
|
|---|---|---|
|
|
@@ -400,6 +401,8 @@ export default defineFulgurjsConfig({
|
|
|
400
401
|
| | `MFU-008` | 未知远程 |
|
|
401
402
|
| | `MFU-009` | 加载到的模块没有任何导出 |
|
|
402
403
|
| | `MFU-010` | singleton 共享版本漂移(使用作用域版本,告警) |
|
|
404
|
+
| CC 跨应用上下文 | `CC-001` | AppContext 必需字段缺失(三段式:got/expected/example,修法指向宿主桥 `provideFulgurjsAppContext`) |
|
|
405
|
+
| | `CC-002` | 运行时单例不可用(独立直开远程页;修法 = 经宿主联邦加载,时序契约 bridge → federatedBoot → loadRemote) |
|
|
403
406
|
|
|
404
407
|
每个码的完整排查文案见 [`docs/manual.html`](https://github.com/chenmingye/fulgurjs-federation/blob/master/docs/manual.html) §8;`fulgurjs doctor` 可提前把部署面的 MFU-001 类问题拦在上线前。
|
|
405
408
|
|
|
@@ -443,6 +446,127 @@ const FederatedAmisForm = remoteComponent('cku-mes-admin/AmisFormRouterPage', {
|
|
|
443
446
|
- `vue` 为**可选 peerDependency**(`peerDependenciesMeta.optional`):仅使用 `./vue` 子路径时才需要安装 Vue;runtime.js 保持框架无关(不 import vue),体积零增量;
|
|
444
447
|
- 运行时实例经 `globalThis.__FULGURJS_RUNTIME__` 页面级单例复用,与 `virtual:fulgurjs-runtime` 的导入殊途同归,无需额外接线。
|
|
445
448
|
|
|
449
|
+
### 9. `FulgurjsAppContext` — 跨应用传值与方法引用(`@fulgurjs/federation/context`,0.8.0 起)
|
|
450
|
+
|
|
451
|
+
宿主向子应用传值、子应用向宿主反向注册方法,一律走这条一等公民通道(对标乾坤 `props`,但带类型与错误契约)——不再各自挂 `window.*` 裸口子。
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
// —— 宿主桥(host/src/fulgurjs/host/bridge.ts):登录完成后一次性提供 ——
|
|
455
|
+
import { provideFulgurjsAppContext } from '@fulgurjs/federation/context'
|
|
456
|
+
|
|
457
|
+
provideFulgurjsAppContext({
|
|
458
|
+
user, // 宿主登录用户原始形态
|
|
459
|
+
token, getToken, // token 快照 + 取最新 token(拉取式防过期)
|
|
460
|
+
store: piniaInstance, // 宿主 pinia:子应用 useUserStore(ctx.store) 共享响应式状态
|
|
461
|
+
hostApp: app, // 宿主 Vue App 实例:全局组件/指令注册目标
|
|
462
|
+
locale, // EP locale 等 UI 配置
|
|
463
|
+
events: { main: mainEvents }, // 事件/方法池:宿主提供 main;子应用反向注册 bpm.* / lowcode.*
|
|
464
|
+
formUrl: '/flowable', baseUrl: '/meszc', // 项目扩展位(自定义键)
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
// —— 远程 boot(exposes/federatedBoot.ts):显式校验消费 ——
|
|
468
|
+
import { requireFulgurjsAppContext } from '@fulgurjs/federation/context'
|
|
469
|
+
|
|
470
|
+
const { store, user, hostApp } = requireFulgurjsAppContext('store', 'user', 'hostApp')
|
|
471
|
+
// 缺任一键 → [fulgurjs:CC-001] 三段式抛错(got / expected / example 指向宿主桥);
|
|
472
|
+
// 页面无运行时单例(独立直开远程页)→ [fulgurjs:CC-002] 显式,修法 = 经宿主联邦加载。
|
|
473
|
+
|
|
474
|
+
// —— 远程页面读点 ——
|
|
475
|
+
import { getFulgurjsAppContext } from '@fulgurjs/federation/context'
|
|
476
|
+
const dict = getFulgurjsAppContext().events?.main?.getDictItems?.('sex')
|
|
477
|
+
|
|
478
|
+
// —— 子应用反向注册方法给宿主(页面 onUnmounted 时记得摘除,见迁移指南「页面卸载清理清单」)——
|
|
479
|
+
getFulgurjsAppContext().events!.bpm = { formEvent, formSubmitEvent }
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
标准字段表:
|
|
483
|
+
|
|
484
|
+
| 字段 | 类型 | 语义 | 写方 |
|
|
485
|
+
|---|---|---|---|
|
|
486
|
+
| `user` | `Record<string, any>` | 宿主登录用户原始形态 | 宿主桥(只读约定) |
|
|
487
|
+
| `token` | `string \| undefined` | 当前 token 快照 | 宿主桥(只读约定) |
|
|
488
|
+
| `getToken` | `() => string \| undefined` | **取最新 token**(拉取式防过期) | 宿主桥(只读约定) |
|
|
489
|
+
| `store` | `unknown`(运行时为宿主 pinia) | 子应用挂载/读取宿主共享响应式状态 | 宿主桥(只读约定) |
|
|
490
|
+
| `hostApp` | Vue App 实例(同 realm 直引用) | 全局组件/指令注册目标 | 宿主桥(只读约定) |
|
|
491
|
+
| `locale` | `unknown` | EP locale 等 UI 配置 | 宿主桥(只读约定) |
|
|
492
|
+
| `events` | `Record<string, any>` | 事件/方法池:`events.main.*` 宿主提供、`events.bpm.*` / `events.lowcode.*` 子应用反向注册 | 宿主桥建池,子应用挂载 |
|
|
493
|
+
| (扩展位) | `[key: string]: unknown` | `formUrl` / `baseUrl` 等项目自定义键 | 宿主桥;远程 boot 只增不改宿主键 |
|
|
494
|
+
|
|
495
|
+
变更语义与时序契约:
|
|
496
|
+
|
|
497
|
+
- `provide` = 顶层 merge(后写覆盖,幂等可多次);约定「宿主先写标准字段,远程只增不改宿主键」;嵌套对象(如 `events`)是**引用共享**,子应用挂属性即时可见(同 realm 直引用);
|
|
498
|
+
- 时序契约:**bridge(provide)→ federatedBoot(require)→ 页面 loadRemote**——违反即在 boot 处显式失败(CC-001),不静默;
|
|
499
|
+
- 数据语义 = **传输层快照 + 函数引用,非响应式**(与乾坤 props 同语义)。"实时"由三条正规通道承担:① `getToken()` / `events.main.*` 函数引用每次调用执行宿主最新闭包;② `context.store` 把宿主 pinia 递给子应用(共享响应式实例);③ 登录态变更 = 重新登录 = 页面刷新 = bridge 重跑全新 context。context 本体不做 Vue reactive(runtime 框架无关 + gzip 红线 + 跨包 proxy 双份陷阱);"中途变更需通知"的场景 0.9 预留 `onAppContextChange` 订阅。
|
|
500
|
+
|
|
501
|
+
方法引用两条通道:
|
|
502
|
+
|
|
503
|
+
| 通道 | 语义 | 适用 |
|
|
504
|
+
|---|---|---|
|
|
505
|
+
| **context 携带函数引用** | 同步直调(bridge 先于一切页面加载) | 高频热路径(`getToken` / `getDictItems` / `getFileAccessHttpUrl`)、子应用反向注册(`formEvent`) |
|
|
506
|
+
| **exposes 方法模块** | `exposes: { './api': './src/fulgurjs/exposes/api.ts' }` → `const { xxx } = await loadRemote('remote/api')` | 低频/重逻辑跨应用调用;任意 expose 任意消费;dts 类型直连自动覆盖 |
|
|
507
|
+
|
|
508
|
+
方法模块规范:`src/fulgurjs/exposes/` 下的 `api.ts` 导出纯函数/服务对象(不挂 Vue 组件);依赖宿主单例的函数(如 defHttp 走 shared)直接写,联邦协商保证同模块图。
|
|
509
|
+
|
|
510
|
+
端到端示例(提供方 admin,消费方任意应用):
|
|
511
|
+
|
|
512
|
+
```ts
|
|
513
|
+
// ① 提供方 vite.config.ts:exposes 加一条
|
|
514
|
+
exposes: { './api': './src/fulgurjs/exposes/api.ts' }
|
|
515
|
+
|
|
516
|
+
// ② 提供方 src/fulgurjs/exposes/api.ts:导出纯函数
|
|
517
|
+
import { defHttp } from '/@/utils/http/axios'
|
|
518
|
+
export function getDictItems(dictCode: string) {
|
|
519
|
+
return defHttp.get({ url: '/sys/dict/getDictItems/' + dictCode }, {})
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// ③ 消费方(任意页面,类型直连自动覆盖):
|
|
523
|
+
const { getDictItems } = await loadRemote('cku-mes-admin/api')
|
|
524
|
+
const res = await getDictItems('sex')
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
存储说明:context 与旧 W4 存储(`__FULGURJS_APP_CONFIG__`)是**同一份**——旧名 `provideFulgurjsAppConfig / getFulgurjsAppConfig`(`virtual:fulgurjs-runtime`)继续可用但已标 `@deprecated`(0.9 删除);runtime.js 逻辑 0.8.0 零改动,全部新 API 落在 context 子路径(~2KB 独立文件)。
|
|
528
|
+
|
|
529
|
+
### 9.1 乾坤功能融合三件套 + 联邦诊断面板(0.8.0,全部宿主/模板侧,runtime 零改动)
|
|
530
|
+
|
|
531
|
+
以下能力由 `fulgurjs init` 集成器生成的模板直接带出(迁移指南「三E」有面向迁移者的同款说明);手工集成的项目按下面的接入点自行落位。
|
|
532
|
+
|
|
533
|
+
#### A. 联邦页面保活(多 tab 切走切回状态不丢)
|
|
534
|
+
|
|
535
|
+
- **配置**:页面路由表条目加 `keepAlive: true`(集成器项目改 `fulgurjs.config.ts` 的 `host.pages` 后重跑 init 并**删除已生成产物**;手工项目直接改 `src/fulgurjs/host/pages.ts` 的页面表):
|
|
536
|
+
|
|
537
|
+
```ts
|
|
538
|
+
{ route: '/flowable/bpm/task/todo', name: 'BpmTodoTask', title: '待办任务', keepAlive: true },
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
- **机制**:宿主 LayoutContent 联邦分支外包 `<keep-alive :include="fulgurjsKeepAliveNames" :max="8">`——include 白名单 = `keepAlive: true` 页面的 spec 清洗名,`max=8` 原生 LRU 防内存失控。**默认全部关闭**:重型组件(vxe-table/表单设计器)缓存成本高,按页显式开启。
|
|
542
|
+
- **行为**:切走再切回,表单/筛选/滚动位置原样保留(组件 deactivate 而非销毁);跳转参数(fullPath)不同视为不同缓存条目。
|
|
543
|
+
|
|
544
|
+
#### B. 页面加载骨架屏(默认开启,无需配置)
|
|
545
|
+
|
|
546
|
+
页面组件工厂的异步组件内置 `loadingComponent`(4 条渐变动画骨架条,`delay: 200ms` 防闪)——首次进入联邦页/冷启动预构建窗口期间内容区显示骨架而非白屏。
|
|
547
|
+
|
|
548
|
+
#### C. 空闲预载(默认开启,可关闭)
|
|
549
|
+
|
|
550
|
+
宿主桥登录完成后 `requestIdleCallback` 逐个 `preloadRemote(remote, { mode: 'prefetch' })`(低优先级不抢带宽)——首次点开子应用菜单不再等 chunk 下载。**开关**:`src/fulgurjs/host/bridge.ts` 顶部 `PREFETCH_REMOTES: string[]`(remote 名数组,置空 `[]` 即关闭)。预载失败走 MFU-007 语义(`fulgurjs:error` 事件 + console 警告,不阻断业务)。
|
|
551
|
+
|
|
552
|
+
#### D. 联邦诊断面板(免登录页 `/fulgurjs-demo`)
|
|
553
|
+
|
|
554
|
+
演示页升级为运行时诊断面板(源自乾坤 v3 inspector 概念的轻量化,不做浏览器扩展),六块信息实时读取:
|
|
555
|
+
|
|
556
|
+
| 块 | 内容 |
|
|
557
|
+
|---|---|
|
|
558
|
+
| ① 方法模块调用演示 | 按钮实调 `loadRemote('cku-mes-admin/api')` → `getDictItems('sex')` 并显示结果(方法引用通道②的活样例) |
|
|
559
|
+
| ② remotes 状态 | 各 remote 的 entry / 加载状态 / 容器加载耗时 |
|
|
560
|
+
| ③ shared 协商 | 共享键 → version ← 提供方(多版本并存可见) |
|
|
561
|
+
| ④ context 快照 | AppContext 每个键的值形态(函数引用/对象/字符串,含 events 池) |
|
|
562
|
+
| ⑤ fulgurjs:error 历史日志 | window 事件累积(时间戳 + remote + 错误消息),本轮会话零错误则显示"无错误" |
|
|
563
|
+
| ⑥ 远程资源加载耗时 | performance resource 中 fulgurjs/remoteEntry/chunk 相关条目与耗时 |
|
|
564
|
+
|
|
565
|
+
#### E. IDE 说明(`src/fulgurjs/` 目录的红波浪线)
|
|
566
|
+
|
|
567
|
+
- `types/` 下的 `*.d.ts` 是**插件每次 dev 自动生成**的类型直连声明(勿手改):内部 `export * from '../../../cku-mes-xxx/src/***.vue'` 指向**兄弟工程的源码**。命令行 `vue-tsc --noEmit`(走本应用 tsconfig,skipLibCheck 生效)为 **0 错误**;但 **VSCode/Volar 在打开这些 d.ts 时**可能把工程外 .vue 用推断项目(inferred project,无 tsconfig 上下文)展开检查,显示大片"找不到模块 '@/...'"——**仅编辑器显示问题,不影响命令行检查与构建**,不打开 `types/` 生成物即无感。
|
|
568
|
+
- 升级插件版本后若 `import '@fulgurjs/federation/context'` 报 ts(2307):是 IDE 的 TS 服务缓存了旧包——`Restart TS Server`(⌘⇧P)或重开窗口即可。
|
|
569
|
+
|
|
446
570
|
## ⚠️ 首次使用避坑指南(真实迁移项目踩坑实录)
|
|
447
571
|
|
|
448
572
|
以下每一条都在真实企业工程(qiankun → 联邦迁移,3 万模块级)中实际踩到过:
|
package/client.d.ts
CHANGED
|
@@ -57,6 +57,31 @@ declare module 'virtual:fulgurjs-runtime' {
|
|
|
57
57
|
fallback?: () => Promise<any>
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* 跨应用上下文标准字段表(0.8.0,docs/跨应用传值与方法引用设计方案-2026-09-20.md §4.3)。
|
|
62
|
+
* 值 API 在 '@fulgurjs/federation/context' 子路径(runtime.js 不导出 context 函数,
|
|
63
|
+
* 此处仅类型随虚拟模块声明供 type-only import);读写约定:宿主桥先写标准字段,
|
|
64
|
+
* 远程 boot 只增不改宿主键;嵌套对象(如 events)引用共享。
|
|
65
|
+
*/
|
|
66
|
+
export interface FulgurjsAppContext {
|
|
67
|
+
/** 宿主登录用户原始形态(只读约定) */
|
|
68
|
+
user: Record<string, any>
|
|
69
|
+
/** 当前 token 快照(只读约定;实时取值用 getToken) */
|
|
70
|
+
token?: string
|
|
71
|
+
/** 取最新 token(拉取式防过期) */
|
|
72
|
+
getToken?: () => string | undefined
|
|
73
|
+
/** 宿主 pinia 实例:子应用 useUserStore(ctx.store) 拿共享响应式状态 */
|
|
74
|
+
store?: unknown
|
|
75
|
+
/** 宿主 Vue App 实例(同 realm 直引用):全局组件/指令注册目标 */
|
|
76
|
+
hostApp?: unknown
|
|
77
|
+
/** EP locale 等 UI 配置(原 W4 字段) */
|
|
78
|
+
locale?: unknown
|
|
79
|
+
/** 事件/方法池:events.main.* 宿主提供、events.bpm.* / events.lowcode.* 子应用反向注册 */
|
|
80
|
+
events?: Record<string, any>
|
|
81
|
+
/** 项目扩展位(formUrl/baseUrl 等自定义键) */
|
|
82
|
+
[key: string]: unknown
|
|
83
|
+
}
|
|
84
|
+
|
|
60
85
|
/** 运行时单例(与 globalThis.__FULGURJS_RUNTIME__ 同一实例,方法面冻结) */
|
|
61
86
|
export interface FulgurjsRuntime {
|
|
62
87
|
shareScopeMap: Record<string, Record<string, Record<string, ShareEntry>>>
|
|
@@ -76,7 +101,9 @@ declare module 'virtual:fulgurjs-runtime' {
|
|
|
76
101
|
getContainer(name: string): Promise<{ name: string; init: (scope: unknown) => void | Promise<void>; get: (module: string) => Promise<any> }>
|
|
77
102
|
preloadRemote(spec: string, opts?: PreloadRemoteOptions): Promise<void>
|
|
78
103
|
parseSpec(spec: string): { remote: string; module: string }
|
|
104
|
+
/** @deprecated 0.8.0 起改用 '@fulgurjs/federation/context' 的 provideFulgurjsAppContext(存储同一份,新名语义更准) */
|
|
79
105
|
provideFulgurjsAppConfig(config: Record<string, any>): void
|
|
106
|
+
/** @deprecated 0.8.0 起改用 '@fulgurjs/federation/context' 的 getFulgurjsAppContext(存储同一份,新名语义更准) */
|
|
80
107
|
getFulgurjsAppConfig(): Record<string, any>
|
|
81
108
|
}
|
|
82
109
|
|
|
@@ -102,7 +129,9 @@ declare module 'virtual:fulgurjs-runtime' {
|
|
|
102
129
|
): Promise<{ name: string; init: (scope: unknown) => void | Promise<void>; get: (module: string) => Promise<any> }>
|
|
103
130
|
export function preloadRemote(spec: string, opts?: PreloadRemoteOptions): Promise<void>
|
|
104
131
|
export function parseSpec(spec: string): { remote: string; module: string }
|
|
132
|
+
/** @deprecated 0.8.0 起改用 '@fulgurjs/federation/context' 的 provideFulgurjsAppContext(存储同一份,新名语义更准) */
|
|
105
133
|
export function provideFulgurjsAppConfig(config: Record<string, any>): void
|
|
134
|
+
/** @deprecated 0.8.0 起改用 '@fulgurjs/federation/context' 的 getFulgurjsAppContext(存储同一份,新名语义更准) */
|
|
106
135
|
export function getFulgurjsAppConfig(): Record<string, any>
|
|
107
136
|
/** 兜底解包:命名空间有 default 取 default,否则原样返回 */
|
|
108
137
|
export function unwrapDefault<T>(ns: { default?: T } | T): T
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/runtime/errors.ts
|
|
2
|
+
var FulgurjsError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
details;
|
|
5
|
+
constructor(code, message, details) {
|
|
6
|
+
super(`[fulgurjs:${code}] ${message}`);
|
|
7
|
+
this.name = "FulgurjsError";
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.details = details;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var ErrorCodes = {
|
|
13
|
+
/** 远程容器加载失败(网络/超时/重试耗尽/熔断) */
|
|
14
|
+
REMOTE_LOAD_FAILED: "MFU-001",
|
|
15
|
+
/** remoteEntry 自报名与 remotes 配置的名称不匹配 */
|
|
16
|
+
REMOTE_NAME_MISMATCH: "MFU-002",
|
|
17
|
+
/** strictVersion 开启且共享版本不满足 */
|
|
18
|
+
SHARE_STRICT_VERSION: "MFU-003",
|
|
19
|
+
/** 共享模块缺失且无本地 fallback(import: false) */
|
|
20
|
+
SHARE_NOT_AVAILABLE: "MFU-004",
|
|
21
|
+
/** 同一容器用不同 share scope 重复 init */
|
|
22
|
+
CONTAINER_REINIT_CONFLICT: "MFU-005",
|
|
23
|
+
/** 请求的模块未被该远程 exposes */
|
|
24
|
+
MODULE_NOT_EXPOSED: "MFU-006",
|
|
25
|
+
/** 预加载失败 */
|
|
26
|
+
PRELOAD_FAILED: "MFU-007",
|
|
27
|
+
/** 未知远程 */
|
|
28
|
+
REMOTE_UNKNOWN: "MFU-008",
|
|
29
|
+
/** 加载到的模块没有任何导出(常见:exposes 指向了不导出内容的文件) */
|
|
30
|
+
EMPTY_EXPORTS: "MFU-009",
|
|
31
|
+
/** singleton 共享协商版本与消费方 requiredVersion 不一致(使用作用域版本,仅告警) */
|
|
32
|
+
SINGLETON_SKEW: "MFU-010"
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
FulgurjsError,
|
|
37
|
+
ErrorCodes
|
|
38
|
+
};
|
package/dist/context.cjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/context.ts
|
|
21
|
+
var context_exports = {};
|
|
22
|
+
__export(context_exports, {
|
|
23
|
+
ContextErrorCodes: () => ContextErrorCodes,
|
|
24
|
+
getFulgurjsAppContext: () => getFulgurjsAppContext,
|
|
25
|
+
provideFulgurjsAppContext: () => provideFulgurjsAppContext,
|
|
26
|
+
requireFulgurjsAppContext: () => requireFulgurjsAppContext
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(context_exports);
|
|
29
|
+
|
|
30
|
+
// src/runtime/errors.ts
|
|
31
|
+
var FulgurjsError = class extends Error {
|
|
32
|
+
code;
|
|
33
|
+
details;
|
|
34
|
+
constructor(code, message, details) {
|
|
35
|
+
super(`[fulgurjs:${code}] ${message}`);
|
|
36
|
+
this.name = "FulgurjsError";
|
|
37
|
+
this.code = code;
|
|
38
|
+
this.details = details;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// src/context.ts
|
|
43
|
+
var ContextErrorCodes = {
|
|
44
|
+
/** context 必需字段缺失(三段式,修法指向宿主桥) */
|
|
45
|
+
CONTEXT_MISSING_KEY: "CC-001",
|
|
46
|
+
/** 运行时单例不可用(独立直开远程页,修法=经宿主联邦加载) */
|
|
47
|
+
CONTEXT_NO_RUNTIME: "CC-002"
|
|
48
|
+
};
|
|
49
|
+
function requireRuntime() {
|
|
50
|
+
const rt = globalThis.__FULGURJS_RUNTIME__;
|
|
51
|
+
if (!rt || typeof rt.provideFulgurjsAppConfig !== "function") {
|
|
52
|
+
throw new FulgurjsError(
|
|
53
|
+
ContextErrorCodes.CONTEXT_NO_RUNTIME,
|
|
54
|
+
"fulgurjs runtime singleton not found on this page (globalThis.__FULGURJS_RUNTIME__ is undefined).\n \u6839\u56E0: \u5F53\u524D\u9875\u9762\u6CA1\u6709\u7ECF\u5BBF\u4E3B\u7684\u8054\u90A6\u8FD0\u884C\u65F6\u52A0\u8F7D\uFF08\u72EC\u7ACB\u76F4\u5F00\u8FDC\u7A0B\u9875\uFF0C\u6216\u5BBF\u4E3B\u6865\u665A\u4E8E\u672C\u8C03\u7528\u6267\u884C\uFF09\u3002\n \u4FEE\u6CD5: \u2460 \u4ECE\u5BBF\u4E3B\u5E94\u7528\u7684\u8054\u90A6\u8DEF\u7531\u6253\u5F00\u672C\u9875\u9762\uFF08\u5BBF\u4E3B bridge \u4F1A\u5148\u52A0\u8F7D\u8FD0\u884C\u65F6\u5E76\u63D0\u4F9B context\uFF09\uFF1B\n \u2461 \u82E5\u4F60\u662F\u5BBF\u4E3B\u6865\u4F5C\u8005\uFF1A\u628A provideFulgurjsAppContext \u653E\u5728 bridge \u521D\u59CB\u5316\u5C3E\u90E8\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 federatedBoot \u2192 loadRemote\uFF09\u3002",
|
|
55
|
+
{ runtime: false }
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return rt;
|
|
59
|
+
}
|
|
60
|
+
function provideFulgurjsAppContext(config) {
|
|
61
|
+
requireRuntime().provideFulgurjsAppConfig(config);
|
|
62
|
+
}
|
|
63
|
+
function getFulgurjsAppContext() {
|
|
64
|
+
return requireRuntime().getFulgurjsAppConfig();
|
|
65
|
+
}
|
|
66
|
+
function requireFulgurjsAppContext(...keys) {
|
|
67
|
+
const ctx = getFulgurjsAppContext();
|
|
68
|
+
const missing = keys.filter((k) => ctx[k] === void 0);
|
|
69
|
+
if (missing.length === 0) return ctx;
|
|
70
|
+
const got = Object.keys(ctx);
|
|
71
|
+
const err = new FulgurjsError(
|
|
72
|
+
ContextErrorCodes.CONTEXT_MISSING_KEY,
|
|
73
|
+
`AppContext missing required key(s): ${missing.map((k) => `"${k}"`).join(", ")}
|
|
74
|
+
got: ${got.length ? got.map((k) => `"${k}"`).join(", ") : "(empty \u2014 \u5BBF\u4E3B\u6865\u4ECE\u672A\u8C03\u7528 provideFulgurjsAppContext?)"}
|
|
75
|
+
expected: \u5BBF\u4E3B\u6865\u5FC5\u987B\u5728\u4EFB\u4F55\u8FDC\u7A0B\u9875\u9762\u52A0\u8F7D\u524D\u63D0\u4F9B ${missing.map((k) => `"${k}"`).join(" / ")}
|
|
76
|
+
example: host/src/fulgurjs/host/bridge.ts \u2192 provideFulgurjsAppContext({ ${keys.join(", ")}, ... })
|
|
77
|
+
\u4FEE\u6CD5: \u68C0\u67E5\u5BBF\u4E3B\u5E94\u7528 fulgurjs bridge \u662F\u5426\u5347\u7EA7\u5230 0.8.0 context \u5F62\u6001\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 federatedBoot \u2192 loadRemote\uFF09`,
|
|
78
|
+
{ missing, got }
|
|
79
|
+
);
|
|
80
|
+
throw err;
|
|
81
|
+
}
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
ContextErrorCodes,
|
|
85
|
+
getFulgurjsAppContext,
|
|
86
|
+
provideFulgurjsAppContext,
|
|
87
|
+
requireFulgurjsAppContext
|
|
88
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CC 段错误码(context 子路径自持):src/runtime/ 对 v0.7.1 零 diff 红线,
|
|
3
|
+
* 不回填 runtime/errors.ts 的 ErrorCodes 总表(README 错误码总表同步 CC 段)。
|
|
4
|
+
*/
|
|
5
|
+
declare const ContextErrorCodes: {
|
|
6
|
+
/** context 必需字段缺失(三段式,修法指向宿主桥) */
|
|
7
|
+
readonly CONTEXT_MISSING_KEY: "CC-001";
|
|
8
|
+
/** 运行时单例不可用(独立直开远程页,修法=经宿主联邦加载) */
|
|
9
|
+
readonly CONTEXT_NO_RUNTIME: "CC-002";
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 跨应用上下文标准字段表(§4.3)。
|
|
13
|
+
*
|
|
14
|
+
* 读写约定:宿主桥先写标准字段;远程 boot 只增不改宿主键;
|
|
15
|
+
* 嵌套对象(如 events)是引用共享,子应用挂属性即时可见(同 realm 直引用)。
|
|
16
|
+
*/
|
|
17
|
+
interface FulgurjsAppContext {
|
|
18
|
+
/** 宿主登录用户原始形态(只读约定) */
|
|
19
|
+
user: Record<string, any>;
|
|
20
|
+
/** 当前 token 快照(只读约定;实时取值用 getToken) */
|
|
21
|
+
token?: string;
|
|
22
|
+
/** 取最新 token(拉取式防过期) */
|
|
23
|
+
getToken?: () => string | undefined;
|
|
24
|
+
/** 宿主 pinia 实例:子应用 useUserStore(ctx.store) 拿共享响应式状态 */
|
|
25
|
+
store?: unknown;
|
|
26
|
+
/** 宿主 Vue App 实例(同 realm 直引用):全局组件/指令注册目标 */
|
|
27
|
+
hostApp?: unknown;
|
|
28
|
+
/** EP locale 等 UI 配置(原 W4 字段) */
|
|
29
|
+
locale?: unknown;
|
|
30
|
+
/** 事件/方法池:events.main.* 宿主提供、events.bpm.* / events.lowcode.* 子应用反向注册 */
|
|
31
|
+
events?: Record<string, any>;
|
|
32
|
+
/** 项目扩展位(formUrl/baseUrl 等自定义键) */
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 宿主写入跨应用上下文(merge 语义,幂等可多次调用,后写覆盖同键)。
|
|
37
|
+
*
|
|
38
|
+
* 宿主桥(host/src/fulgurjs/host/bridge.ts)在登录完成后调用一次:
|
|
39
|
+
* provideFulgurjsAppContext({ user, token, getToken, store, hostApp, locale, events: { main: mainEvents }, ... })
|
|
40
|
+
*/
|
|
41
|
+
declare function provideFulgurjsAppContext(config: Partial<FulgurjsAppContext> & Record<string, unknown>): void;
|
|
42
|
+
/**
|
|
43
|
+
* 读上下文快照(传输层快照:顶层 merge 结果 + 嵌套对象引用共享)。
|
|
44
|
+
* 页面无运行时单例(独立直开远程页)→ CC-002 显式抛错,不静默回空。
|
|
45
|
+
*/
|
|
46
|
+
declare function getFulgurjsAppContext(): FulgurjsAppContext;
|
|
47
|
+
/**
|
|
48
|
+
* 显式校验读取(远程 boot 消费入口):任一键缺失 → CC-001 三段式。
|
|
49
|
+
*
|
|
50
|
+
* 用法:const { store, user, hostApp } = requireFulgurjsAppContext('store', 'user', 'hostApp')
|
|
51
|
+
* 时序契约:宿主 bridge 先 provide,远程 federatedBoot 后 require——违反即在 boot 处显式失败。
|
|
52
|
+
*/
|
|
53
|
+
declare function requireFulgurjsAppContext(...keys: string[]): FulgurjsAppContext;
|
|
54
|
+
|
|
55
|
+
export { ContextErrorCodes, type FulgurjsAppContext, getFulgurjsAppContext, provideFulgurjsAppContext, requireFulgurjsAppContext };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CC 段错误码(context 子路径自持):src/runtime/ 对 v0.7.1 零 diff 红线,
|
|
3
|
+
* 不回填 runtime/errors.ts 的 ErrorCodes 总表(README 错误码总表同步 CC 段)。
|
|
4
|
+
*/
|
|
5
|
+
declare const ContextErrorCodes: {
|
|
6
|
+
/** context 必需字段缺失(三段式,修法指向宿主桥) */
|
|
7
|
+
readonly CONTEXT_MISSING_KEY: "CC-001";
|
|
8
|
+
/** 运行时单例不可用(独立直开远程页,修法=经宿主联邦加载) */
|
|
9
|
+
readonly CONTEXT_NO_RUNTIME: "CC-002";
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 跨应用上下文标准字段表(§4.3)。
|
|
13
|
+
*
|
|
14
|
+
* 读写约定:宿主桥先写标准字段;远程 boot 只增不改宿主键;
|
|
15
|
+
* 嵌套对象(如 events)是引用共享,子应用挂属性即时可见(同 realm 直引用)。
|
|
16
|
+
*/
|
|
17
|
+
interface FulgurjsAppContext {
|
|
18
|
+
/** 宿主登录用户原始形态(只读约定) */
|
|
19
|
+
user: Record<string, any>;
|
|
20
|
+
/** 当前 token 快照(只读约定;实时取值用 getToken) */
|
|
21
|
+
token?: string;
|
|
22
|
+
/** 取最新 token(拉取式防过期) */
|
|
23
|
+
getToken?: () => string | undefined;
|
|
24
|
+
/** 宿主 pinia 实例:子应用 useUserStore(ctx.store) 拿共享响应式状态 */
|
|
25
|
+
store?: unknown;
|
|
26
|
+
/** 宿主 Vue App 实例(同 realm 直引用):全局组件/指令注册目标 */
|
|
27
|
+
hostApp?: unknown;
|
|
28
|
+
/** EP locale 等 UI 配置(原 W4 字段) */
|
|
29
|
+
locale?: unknown;
|
|
30
|
+
/** 事件/方法池:events.main.* 宿主提供、events.bpm.* / events.lowcode.* 子应用反向注册 */
|
|
31
|
+
events?: Record<string, any>;
|
|
32
|
+
/** 项目扩展位(formUrl/baseUrl 等自定义键) */
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 宿主写入跨应用上下文(merge 语义,幂等可多次调用,后写覆盖同键)。
|
|
37
|
+
*
|
|
38
|
+
* 宿主桥(host/src/fulgurjs/host/bridge.ts)在登录完成后调用一次:
|
|
39
|
+
* provideFulgurjsAppContext({ user, token, getToken, store, hostApp, locale, events: { main: mainEvents }, ... })
|
|
40
|
+
*/
|
|
41
|
+
declare function provideFulgurjsAppContext(config: Partial<FulgurjsAppContext> & Record<string, unknown>): void;
|
|
42
|
+
/**
|
|
43
|
+
* 读上下文快照(传输层快照:顶层 merge 结果 + 嵌套对象引用共享)。
|
|
44
|
+
* 页面无运行时单例(独立直开远程页)→ CC-002 显式抛错,不静默回空。
|
|
45
|
+
*/
|
|
46
|
+
declare function getFulgurjsAppContext(): FulgurjsAppContext;
|
|
47
|
+
/**
|
|
48
|
+
* 显式校验读取(远程 boot 消费入口):任一键缺失 → CC-001 三段式。
|
|
49
|
+
*
|
|
50
|
+
* 用法:const { store, user, hostApp } = requireFulgurjsAppContext('store', 'user', 'hostApp')
|
|
51
|
+
* 时序契约:宿主 bridge 先 provide,远程 federatedBoot 后 require——违反即在 boot 处显式失败。
|
|
52
|
+
*/
|
|
53
|
+
declare function requireFulgurjsAppContext(...keys: string[]): FulgurjsAppContext;
|
|
54
|
+
|
|
55
|
+
export { ContextErrorCodes, type FulgurjsAppContext, getFulgurjsAppContext, provideFulgurjsAppContext, requireFulgurjsAppContext };
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FulgurjsError
|
|
3
|
+
} from "./chunk-CK42RK2O.js";
|
|
4
|
+
|
|
5
|
+
// src/context.ts
|
|
6
|
+
var ContextErrorCodes = {
|
|
7
|
+
/** context 必需字段缺失(三段式,修法指向宿主桥) */
|
|
8
|
+
CONTEXT_MISSING_KEY: "CC-001",
|
|
9
|
+
/** 运行时单例不可用(独立直开远程页,修法=经宿主联邦加载) */
|
|
10
|
+
CONTEXT_NO_RUNTIME: "CC-002"
|
|
11
|
+
};
|
|
12
|
+
function requireRuntime() {
|
|
13
|
+
const rt = globalThis.__FULGURJS_RUNTIME__;
|
|
14
|
+
if (!rt || typeof rt.provideFulgurjsAppConfig !== "function") {
|
|
15
|
+
throw new FulgurjsError(
|
|
16
|
+
ContextErrorCodes.CONTEXT_NO_RUNTIME,
|
|
17
|
+
"fulgurjs runtime singleton not found on this page (globalThis.__FULGURJS_RUNTIME__ is undefined).\n \u6839\u56E0: \u5F53\u524D\u9875\u9762\u6CA1\u6709\u7ECF\u5BBF\u4E3B\u7684\u8054\u90A6\u8FD0\u884C\u65F6\u52A0\u8F7D\uFF08\u72EC\u7ACB\u76F4\u5F00\u8FDC\u7A0B\u9875\uFF0C\u6216\u5BBF\u4E3B\u6865\u665A\u4E8E\u672C\u8C03\u7528\u6267\u884C\uFF09\u3002\n \u4FEE\u6CD5: \u2460 \u4ECE\u5BBF\u4E3B\u5E94\u7528\u7684\u8054\u90A6\u8DEF\u7531\u6253\u5F00\u672C\u9875\u9762\uFF08\u5BBF\u4E3B bridge \u4F1A\u5148\u52A0\u8F7D\u8FD0\u884C\u65F6\u5E76\u63D0\u4F9B context\uFF09\uFF1B\n \u2461 \u82E5\u4F60\u662F\u5BBF\u4E3B\u6865\u4F5C\u8005\uFF1A\u628A provideFulgurjsAppContext \u653E\u5728 bridge \u521D\u59CB\u5316\u5C3E\u90E8\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 federatedBoot \u2192 loadRemote\uFF09\u3002",
|
|
18
|
+
{ runtime: false }
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return rt;
|
|
22
|
+
}
|
|
23
|
+
function provideFulgurjsAppContext(config) {
|
|
24
|
+
requireRuntime().provideFulgurjsAppConfig(config);
|
|
25
|
+
}
|
|
26
|
+
function getFulgurjsAppContext() {
|
|
27
|
+
return requireRuntime().getFulgurjsAppConfig();
|
|
28
|
+
}
|
|
29
|
+
function requireFulgurjsAppContext(...keys) {
|
|
30
|
+
const ctx = getFulgurjsAppContext();
|
|
31
|
+
const missing = keys.filter((k) => ctx[k] === void 0);
|
|
32
|
+
if (missing.length === 0) return ctx;
|
|
33
|
+
const got = Object.keys(ctx);
|
|
34
|
+
const err = new FulgurjsError(
|
|
35
|
+
ContextErrorCodes.CONTEXT_MISSING_KEY,
|
|
36
|
+
`AppContext missing required key(s): ${missing.map((k) => `"${k}"`).join(", ")}
|
|
37
|
+
got: ${got.length ? got.map((k) => `"${k}"`).join(", ") : "(empty \u2014 \u5BBF\u4E3B\u6865\u4ECE\u672A\u8C03\u7528 provideFulgurjsAppContext?)"}
|
|
38
|
+
expected: \u5BBF\u4E3B\u6865\u5FC5\u987B\u5728\u4EFB\u4F55\u8FDC\u7A0B\u9875\u9762\u52A0\u8F7D\u524D\u63D0\u4F9B ${missing.map((k) => `"${k}"`).join(" / ")}
|
|
39
|
+
example: host/src/fulgurjs/host/bridge.ts \u2192 provideFulgurjsAppContext({ ${keys.join(", ")}, ... })
|
|
40
|
+
\u4FEE\u6CD5: \u68C0\u67E5\u5BBF\u4E3B\u5E94\u7528 fulgurjs bridge \u662F\u5426\u5347\u7EA7\u5230 0.8.0 context \u5F62\u6001\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 federatedBoot \u2192 loadRemote\uFF09`,
|
|
41
|
+
{ missing, got }
|
|
42
|
+
);
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
ContextErrorCodes,
|
|
47
|
+
getFulgurjsAppContext,
|
|
48
|
+
provideFulgurjsAppContext,
|
|
49
|
+
requireFulgurjsAppContext
|
|
50
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -43,7 +43,7 @@ var import_node_fs = __toESM(require("fs"), 1);
|
|
|
43
43
|
var import_node_path = __toESM(require("path"), 1);
|
|
44
44
|
|
|
45
45
|
// src/version.ts
|
|
46
|
-
var RUNTIME_VERSION = "0.
|
|
46
|
+
var RUNTIME_VERSION = "0.8.1";
|
|
47
47
|
|
|
48
48
|
// src/options.ts
|
|
49
49
|
var DEFAULT_FILENAME = "fulgurjs-remoteEntry.js";
|
|
@@ -1274,7 +1274,7 @@ function syncViteCacheMarker(root, pluginVersion, log) {
|
|
|
1274
1274
|
}
|
|
1275
1275
|
|
|
1276
1276
|
// src/runtime-code.gen.ts
|
|
1277
|
-
var runtime_code_gen_default = 'var Q=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function O(t){let n=Q.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function ee(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),w=/^\\d+$/.test(m);if(y&&w){let $=Number(l)-Number(m);if($!==0)return $}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=O(t),r=O(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function k(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!O(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!k(t,`>=${m}`)||!k(t,`<=${y}`))}let r=O(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ne(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function ie(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ae(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let w of o.slice(0,3))if(/^\\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function se(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=se(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FulgurjsError",this.code=n,this.details=r}},R={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var F="0.7.1";var U=15e3,P=2,ce=5,le=3e4;function fe(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={};function y(e){m={...m,...e},typeof globalThis<"u"&&(globalThis.__FULGURJS_APP_CONFIG__=m)}function w(){return m}let $={},D=()=>{for(let e of o)try{e.init?.($)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},N=e=>t[e]??={};function j(e){try{$.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function H(e="default"){return N(e),t}function K(e,i,a,u,E={}){let s=N(e||"default"),c=s[i]??={};c[a]||(c[a]={version:a,get:u,from:E.from??"unknown",eager:!!E.eager,loaded:!!E.loaded})}function x(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:U,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function q(e){x([e])}function G(e){o.push(...e),D()}async function z(e,i={}){let a=i.shareScope||"default",u=i.shareKey||e,s=N(a)[u]||{},c=Object.keys(s),d=i.requiredVersion,f=c.filter(p=>d===void 0||d===!1||k(p,d)),b;if(i.singleton&&c.length>0){let p=c.filter(h=>s[h].loaded);if(b=[...p.length?p:c].sort(v).pop(),c.length>1||!f.includes(b)){let h=s[b],T=`singleton skew "${u}": req "${d??"any"}" use ${b} from ${h.from}`;if(i.strictVersion){let M=new g(R.SHARE_STRICT_VERSION,T,{shareKey:u,requiredVersion:d});throw j({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${T}`)}}else if(b=[...f].sort(v).pop(),!b){if(i.strictVersion){let h=new g(R.SHARE_STRICT_VERSION,`no satisfying version for "${u}" (required "${d}") in share scope "${a}"`);throw j({remote:u,error:h}),h}if(i.fallback)return i.fallback();let p=new g(R.SHARE_NOT_AVAILABLE,`shared "${u}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:u,requiredVersion:d});throw j({remote:u,error:p}),p}let _=s[b];if($.resolveShare){let p=await $.resolveShare({shareKey:u,shareScope:a,requiredVersion:d,picked:_,available:Object.values(s)});p&&(_=p)}return _.loaded=!0,_.get()}function J(e,i,a){return new Promise((u,E)=>{let s=setTimeout(()=>E(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(c=>{clearTimeout(s),u(c)},c=>{clearTimeout(s),E(c)})})}let W=e=>new Promise(i=>setTimeout(i,e));function I(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:R.REMOTE_NAME_MISMATCH})}}async function L(e,i){return J(import(e),i.timeout??U,`load remoteEntry ${e}`)}async function C(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let u=e.breakerState;if(u.openUntil>Date.now()){let s=new g(R.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(u.openUntil).toISOString()}`,{remote:e.name});throw j({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let E=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return I(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return I(h,e),h});let c,d,f=!1,b=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=b;h++){let T=performance.now();try{c=await p(),e.lastLoadMs=Math.round(performance.now()-T),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<b&&await W(200*2**h)}}if(f)break}if(!f||!c){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(R.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}I(c,e);let _=l.get(c);if(_&&_!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${_}", cannot re-init with "${a}"`);return typeof c.init=="function"&&await c.init(t),l.set(c,a),e.container=c,e.state="loaded",e.debug.status="loaded",u.fails=0,c})();e.containerPromise=E;try{return await E}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),u.fails+=1,u.fails>=ce&&(u.openUntil=Date.now()+le,u.fails=0),s instanceof g)throw j({remote:e.name,error:s}),s;if(s?.code)throw j({remote:e.name,error:s}),s;let c=new g(R.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw j({remote:e.name,error:c}),c}}function A(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:B(e.slice(i+1))}}function B(e){return e?e.startsWith(".")?e:`./${e}`:""}async function X(e,i){let{remote:a,module:u}=A(e);$.beforeLoadRemote?.({remote:a,module:u});let E=n.get(a);if(!E)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await C(E,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if(!u)return s;let c=`${a}@${E.shareScope||"default"}#${u}`;r.has(c)||r.set(c,s.get(u).catch(f=>{throw r.delete(c),f instanceof g||f?.code?f:new g(R.REMOTE_LOAD_FAILED,`failed to load module "${u}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:u})}));let d;try{d=await r.get(c)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if($.afterLoadRemote?.({remote:a,module:u,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(R.EMPTY_EXPORTS,`no exports: ${u} @ ${a}`,{remote:a,module:u});j({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function Y(e){let i=n.get(e);if(!i)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function Z(e,i={}){let{remote:a}=A(e),u=n.get(a);if(!u)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let E=i.mode??"preload",s=(c,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${c}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=c,E==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(u.manifestUrl){let c=await fetch(u.manifestUrl,{cache:"no-cache"});if(c.ok){let d=await c.json();s(u.entry,"modulepreload");let f=d.exposes??{};for(let b of Object.keys(f)){let _=f[b];_?.file&&s(new URL(_.file,u.entry).href,"modulepreload");for(let p of _?.css??[])s(new URL(p,u.entry).href,"style")}return}}s(u.entry,"modulepreload")}catch(c){j({remote:a,error:new g(R.PRELOAD_FAILED,String(c?.message??c),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:H,registerShare:K,registerRemotes:x,registerRemote:q,registerPlugins:G,loadShare:z,loadRemote:X,getContainer:Y,preloadRemote:Z,parseSpec:A,provideFulgurjsAppConfig:y,getFulgurjsAppConfig:w}}var V=globalThis,S=V.__FULGURJS_RUNTIME__??fe();V.__FULGURJS_RUNTIME__=S;try{Object.freeze(S)}catch{}var Re=F;function Se(){return S}var we=S.initSharing,be=S.registerShare,_e=S.registerRemotes,je=S.registerRemote,$e=S.registerPlugins,Me=S.loadShare,ve=S.loadRemote,Te=S.getContainer,Oe=S.preloadRemote,ke=S.shareScopeMap,Ne=S.provideFulgurjsAppConfig,Ie=S.getFulgurjsAppConfig;function Ae(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var xe=S;export{xe as default,Te as getContainer,Ie as getFulgurjsAppConfig,Se as getRuntime,we as initSharing,ve as loadRemote,Me as loadShare,Oe as preloadRemote,Ne as provideFulgurjsAppConfig,$e as registerPlugins,je as registerRemote,_e as registerRemotes,be as registerShare,S as runtime,ke as shareScopeMap,Ae as unwrapDefault,Re as version};\n';
|
|
1277
|
+
var runtime_code_gen_default = 'var Q=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function O(t){let n=Q.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function ee(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),w=/^\\d+$/.test(m);if(y&&w){let $=Number(l)-Number(m);if($!==0)return $}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=O(t),r=O(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function k(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!O(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!k(t,`>=${m}`)||!k(t,`<=${y}`))}let r=O(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ne(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function ie(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ae(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let w of o.slice(0,3))if(/^\\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function se(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=se(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FulgurjsError",this.code=n,this.details=r}},R={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var F="0.8.1";var U=15e3,P=2,ce=5,le=3e4;function fe(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={};function y(e){m={...m,...e},typeof globalThis<"u"&&(globalThis.__FULGURJS_APP_CONFIG__=m)}function w(){return m}let $={},D=()=>{for(let e of o)try{e.init?.($)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},N=e=>t[e]??={};function j(e){try{$.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function H(e="default"){return N(e),t}function K(e,i,a,u,E={}){let s=N(e||"default"),c=s[i]??={};c[a]||(c[a]={version:a,get:u,from:E.from??"unknown",eager:!!E.eager,loaded:!!E.loaded})}function x(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:U,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function q(e){x([e])}function G(e){o.push(...e),D()}async function z(e,i={}){let a=i.shareScope||"default",u=i.shareKey||e,s=N(a)[u]||{},c=Object.keys(s),d=i.requiredVersion,f=c.filter(p=>d===void 0||d===!1||k(p,d)),b;if(i.singleton&&c.length>0){let p=c.filter(h=>s[h].loaded);if(b=[...p.length?p:c].sort(v).pop(),c.length>1||!f.includes(b)){let h=s[b],T=`singleton skew "${u}": req "${d??"any"}" use ${b} from ${h.from}`;if(i.strictVersion){let M=new g(R.SHARE_STRICT_VERSION,T,{shareKey:u,requiredVersion:d});throw j({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${T}`)}}else if(b=[...f].sort(v).pop(),!b){if(i.strictVersion){let h=new g(R.SHARE_STRICT_VERSION,`no satisfying version for "${u}" (required "${d}") in share scope "${a}"`);throw j({remote:u,error:h}),h}if(i.fallback)return i.fallback();let p=new g(R.SHARE_NOT_AVAILABLE,`shared "${u}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:u,requiredVersion:d});throw j({remote:u,error:p}),p}let _=s[b];if($.resolveShare){let p=await $.resolveShare({shareKey:u,shareScope:a,requiredVersion:d,picked:_,available:Object.values(s)});p&&(_=p)}return _.loaded=!0,_.get()}function J(e,i,a){return new Promise((u,E)=>{let s=setTimeout(()=>E(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(c=>{clearTimeout(s),u(c)},c=>{clearTimeout(s),E(c)})})}let W=e=>new Promise(i=>setTimeout(i,e));function I(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:R.REMOTE_NAME_MISMATCH})}}async function L(e,i){return J(import(e),i.timeout??U,`load remoteEntry ${e}`)}async function C(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let u=e.breakerState;if(u.openUntil>Date.now()){let s=new g(R.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(u.openUntil).toISOString()}`,{remote:e.name});throw j({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let E=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return I(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return I(h,e),h});let c,d,f=!1,b=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=b;h++){let T=performance.now();try{c=await p(),e.lastLoadMs=Math.round(performance.now()-T),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<b&&await W(200*2**h)}}if(f)break}if(!f||!c){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(R.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}I(c,e);let _=l.get(c);if(_&&_!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${_}", cannot re-init with "${a}"`);return typeof c.init=="function"&&await c.init(t),l.set(c,a),e.container=c,e.state="loaded",e.debug.status="loaded",u.fails=0,c})();e.containerPromise=E;try{return await E}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),u.fails+=1,u.fails>=ce&&(u.openUntil=Date.now()+le,u.fails=0),s instanceof g)throw j({remote:e.name,error:s}),s;if(s?.code)throw j({remote:e.name,error:s}),s;let c=new g(R.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw j({remote:e.name,error:c}),c}}function A(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:B(e.slice(i+1))}}function B(e){return e?e.startsWith(".")?e:`./${e}`:""}async function X(e,i){let{remote:a,module:u}=A(e);$.beforeLoadRemote?.({remote:a,module:u});let E=n.get(a);if(!E)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await C(E,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if(!u)return s;let c=`${a}@${E.shareScope||"default"}#${u}`;r.has(c)||r.set(c,s.get(u).catch(f=>{throw r.delete(c),f instanceof g||f?.code?f:new g(R.REMOTE_LOAD_FAILED,`failed to load module "${u}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:u})}));let d;try{d=await r.get(c)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if($.afterLoadRemote?.({remote:a,module:u,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(R.EMPTY_EXPORTS,`no exports: ${u} @ ${a}`,{remote:a,module:u});j({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function Y(e){let i=n.get(e);if(!i)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function Z(e,i={}){let{remote:a}=A(e),u=n.get(a);if(!u)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let E=i.mode??"preload",s=(c,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${c}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=c,E==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(u.manifestUrl){let c=await fetch(u.manifestUrl,{cache:"no-cache"});if(c.ok){let d=await c.json();s(u.entry,"modulepreload");let f=d.exposes??{};for(let b of Object.keys(f)){let _=f[b];_?.file&&s(new URL(_.file,u.entry).href,"modulepreload");for(let p of _?.css??[])s(new URL(p,u.entry).href,"style")}return}}s(u.entry,"modulepreload")}catch(c){j({remote:a,error:new g(R.PRELOAD_FAILED,String(c?.message??c),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:H,registerShare:K,registerRemotes:x,registerRemote:q,registerPlugins:G,loadShare:z,loadRemote:X,getContainer:Y,preloadRemote:Z,parseSpec:A,provideFulgurjsAppConfig:y,getFulgurjsAppConfig:w}}var V=globalThis,S=V.__FULGURJS_RUNTIME__??fe();V.__FULGURJS_RUNTIME__=S;try{Object.freeze(S)}catch{}var Re=F;function Se(){return S}var we=S.initSharing,be=S.registerShare,_e=S.registerRemotes,je=S.registerRemote,$e=S.registerPlugins,Me=S.loadShare,ve=S.loadRemote,Te=S.getContainer,Oe=S.preloadRemote,ke=S.shareScopeMap,Ne=S.provideFulgurjsAppConfig,Ie=S.getFulgurjsAppConfig;function Ae(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var xe=S;export{xe as default,Te as getContainer,Ie as getFulgurjsAppConfig,Se as getRuntime,we as initSharing,ve as loadRemote,Me as loadShare,Oe as preloadRemote,Ne as provideFulgurjsAppConfig,$e as registerPlugins,je as registerRemote,_e as registerRemotes,be as registerShare,S as runtime,ke as shareScopeMap,Ae as unwrapDefault,Re as version};\n';
|
|
1278
1278
|
|
|
1279
1279
|
// src/index.ts
|
|
1280
1280
|
function readRuntimeCode() {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RUNTIME_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-P4DGTHMF.js";
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
6
|
import path5 from "path";
|
|
@@ -1238,7 +1238,7 @@ function syncViteCacheMarker(root, pluginVersion, log) {
|
|
|
1238
1238
|
}
|
|
1239
1239
|
|
|
1240
1240
|
// src/runtime-code.gen.ts
|
|
1241
|
-
var runtime_code_gen_default = 'var Q=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function O(t){let n=Q.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function ee(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),w=/^\\d+$/.test(m);if(y&&w){let $=Number(l)-Number(m);if($!==0)return $}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=O(t),r=O(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function k(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!O(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!k(t,`>=${m}`)||!k(t,`<=${y}`))}let r=O(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ne(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function ie(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ae(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let w of o.slice(0,3))if(/^\\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function se(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=se(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FulgurjsError",this.code=n,this.details=r}},R={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var F="0.7.1";var U=15e3,P=2,ce=5,le=3e4;function fe(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={};function y(e){m={...m,...e},typeof globalThis<"u"&&(globalThis.__FULGURJS_APP_CONFIG__=m)}function w(){return m}let $={},D=()=>{for(let e of o)try{e.init?.($)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},N=e=>t[e]??={};function j(e){try{$.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function H(e="default"){return N(e),t}function K(e,i,a,u,E={}){let s=N(e||"default"),c=s[i]??={};c[a]||(c[a]={version:a,get:u,from:E.from??"unknown",eager:!!E.eager,loaded:!!E.loaded})}function x(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:U,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function q(e){x([e])}function G(e){o.push(...e),D()}async function z(e,i={}){let a=i.shareScope||"default",u=i.shareKey||e,s=N(a)[u]||{},c=Object.keys(s),d=i.requiredVersion,f=c.filter(p=>d===void 0||d===!1||k(p,d)),b;if(i.singleton&&c.length>0){let p=c.filter(h=>s[h].loaded);if(b=[...p.length?p:c].sort(v).pop(),c.length>1||!f.includes(b)){let h=s[b],T=`singleton skew "${u}": req "${d??"any"}" use ${b} from ${h.from}`;if(i.strictVersion){let M=new g(R.SHARE_STRICT_VERSION,T,{shareKey:u,requiredVersion:d});throw j({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${T}`)}}else if(b=[...f].sort(v).pop(),!b){if(i.strictVersion){let h=new g(R.SHARE_STRICT_VERSION,`no satisfying version for "${u}" (required "${d}") in share scope "${a}"`);throw j({remote:u,error:h}),h}if(i.fallback)return i.fallback();let p=new g(R.SHARE_NOT_AVAILABLE,`shared "${u}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:u,requiredVersion:d});throw j({remote:u,error:p}),p}let _=s[b];if($.resolveShare){let p=await $.resolveShare({shareKey:u,shareScope:a,requiredVersion:d,picked:_,available:Object.values(s)});p&&(_=p)}return _.loaded=!0,_.get()}function J(e,i,a){return new Promise((u,E)=>{let s=setTimeout(()=>E(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(c=>{clearTimeout(s),u(c)},c=>{clearTimeout(s),E(c)})})}let W=e=>new Promise(i=>setTimeout(i,e));function I(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:R.REMOTE_NAME_MISMATCH})}}async function L(e,i){return J(import(e),i.timeout??U,`load remoteEntry ${e}`)}async function C(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let u=e.breakerState;if(u.openUntil>Date.now()){let s=new g(R.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(u.openUntil).toISOString()}`,{remote:e.name});throw j({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let E=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return I(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return I(h,e),h});let c,d,f=!1,b=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=b;h++){let T=performance.now();try{c=await p(),e.lastLoadMs=Math.round(performance.now()-T),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<b&&await W(200*2**h)}}if(f)break}if(!f||!c){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(R.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}I(c,e);let _=l.get(c);if(_&&_!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${_}", cannot re-init with "${a}"`);return typeof c.init=="function"&&await c.init(t),l.set(c,a),e.container=c,e.state="loaded",e.debug.status="loaded",u.fails=0,c})();e.containerPromise=E;try{return await E}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),u.fails+=1,u.fails>=ce&&(u.openUntil=Date.now()+le,u.fails=0),s instanceof g)throw j({remote:e.name,error:s}),s;if(s?.code)throw j({remote:e.name,error:s}),s;let c=new g(R.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw j({remote:e.name,error:c}),c}}function A(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:B(e.slice(i+1))}}function B(e){return e?e.startsWith(".")?e:`./${e}`:""}async function X(e,i){let{remote:a,module:u}=A(e);$.beforeLoadRemote?.({remote:a,module:u});let E=n.get(a);if(!E)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await C(E,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if(!u)return s;let c=`${a}@${E.shareScope||"default"}#${u}`;r.has(c)||r.set(c,s.get(u).catch(f=>{throw r.delete(c),f instanceof g||f?.code?f:new g(R.REMOTE_LOAD_FAILED,`failed to load module "${u}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:u})}));let d;try{d=await r.get(c)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if($.afterLoadRemote?.({remote:a,module:u,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(R.EMPTY_EXPORTS,`no exports: ${u} @ ${a}`,{remote:a,module:u});j({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function Y(e){let i=n.get(e);if(!i)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function Z(e,i={}){let{remote:a}=A(e),u=n.get(a);if(!u)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let E=i.mode??"preload",s=(c,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${c}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=c,E==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(u.manifestUrl){let c=await fetch(u.manifestUrl,{cache:"no-cache"});if(c.ok){let d=await c.json();s(u.entry,"modulepreload");let f=d.exposes??{};for(let b of Object.keys(f)){let _=f[b];_?.file&&s(new URL(_.file,u.entry).href,"modulepreload");for(let p of _?.css??[])s(new URL(p,u.entry).href,"style")}return}}s(u.entry,"modulepreload")}catch(c){j({remote:a,error:new g(R.PRELOAD_FAILED,String(c?.message??c),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:H,registerShare:K,registerRemotes:x,registerRemote:q,registerPlugins:G,loadShare:z,loadRemote:X,getContainer:Y,preloadRemote:Z,parseSpec:A,provideFulgurjsAppConfig:y,getFulgurjsAppConfig:w}}var V=globalThis,S=V.__FULGURJS_RUNTIME__??fe();V.__FULGURJS_RUNTIME__=S;try{Object.freeze(S)}catch{}var Re=F;function Se(){return S}var we=S.initSharing,be=S.registerShare,_e=S.registerRemotes,je=S.registerRemote,$e=S.registerPlugins,Me=S.loadShare,ve=S.loadRemote,Te=S.getContainer,Oe=S.preloadRemote,ke=S.shareScopeMap,Ne=S.provideFulgurjsAppConfig,Ie=S.getFulgurjsAppConfig;function Ae(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var xe=S;export{xe as default,Te as getContainer,Ie as getFulgurjsAppConfig,Se as getRuntime,we as initSharing,ve as loadRemote,Me as loadShare,Oe as preloadRemote,Ne as provideFulgurjsAppConfig,$e as registerPlugins,je as registerRemote,_e as registerRemotes,be as registerShare,S as runtime,ke as shareScopeMap,Ae as unwrapDefault,Re as version};\n';
|
|
1241
|
+
var runtime_code_gen_default = 'var Q=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function O(t){let n=Q.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function ee(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),w=/^\\d+$/.test(m);if(y&&w){let $=Number(l)-Number(m);if($!==0)return $}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=O(t),r=O(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function k(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!O(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!k(t,`>=${m}`)||!k(t,`<=${y}`))}let r=O(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ne(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function ie(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ae(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let w of o.slice(0,3))if(/^\\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function se(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=se(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FulgurjsError",this.code=n,this.details=r}},R={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var F="0.8.1";var U=15e3,P=2,ce=5,le=3e4;function fe(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={};function y(e){m={...m,...e},typeof globalThis<"u"&&(globalThis.__FULGURJS_APP_CONFIG__=m)}function w(){return m}let $={},D=()=>{for(let e of o)try{e.init?.($)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},N=e=>t[e]??={};function j(e){try{$.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function H(e="default"){return N(e),t}function K(e,i,a,u,E={}){let s=N(e||"default"),c=s[i]??={};c[a]||(c[a]={version:a,get:u,from:E.from??"unknown",eager:!!E.eager,loaded:!!E.loaded})}function x(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:U,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function q(e){x([e])}function G(e){o.push(...e),D()}async function z(e,i={}){let a=i.shareScope||"default",u=i.shareKey||e,s=N(a)[u]||{},c=Object.keys(s),d=i.requiredVersion,f=c.filter(p=>d===void 0||d===!1||k(p,d)),b;if(i.singleton&&c.length>0){let p=c.filter(h=>s[h].loaded);if(b=[...p.length?p:c].sort(v).pop(),c.length>1||!f.includes(b)){let h=s[b],T=`singleton skew "${u}": req "${d??"any"}" use ${b} from ${h.from}`;if(i.strictVersion){let M=new g(R.SHARE_STRICT_VERSION,T,{shareKey:u,requiredVersion:d});throw j({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${T}`)}}else if(b=[...f].sort(v).pop(),!b){if(i.strictVersion){let h=new g(R.SHARE_STRICT_VERSION,`no satisfying version for "${u}" (required "${d}") in share scope "${a}"`);throw j({remote:u,error:h}),h}if(i.fallback)return i.fallback();let p=new g(R.SHARE_NOT_AVAILABLE,`shared "${u}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:u,requiredVersion:d});throw j({remote:u,error:p}),p}let _=s[b];if($.resolveShare){let p=await $.resolveShare({shareKey:u,shareScope:a,requiredVersion:d,picked:_,available:Object.values(s)});p&&(_=p)}return _.loaded=!0,_.get()}function J(e,i,a){return new Promise((u,E)=>{let s=setTimeout(()=>E(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(c=>{clearTimeout(s),u(c)},c=>{clearTimeout(s),E(c)})})}let W=e=>new Promise(i=>setTimeout(i,e));function I(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:R.REMOTE_NAME_MISMATCH})}}async function L(e,i){return J(import(e),i.timeout??U,`load remoteEntry ${e}`)}async function C(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let u=e.breakerState;if(u.openUntil>Date.now()){let s=new g(R.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(u.openUntil).toISOString()}`,{remote:e.name});throw j({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let E=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return I(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return I(h,e),h});let c,d,f=!1,b=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=b;h++){let T=performance.now();try{c=await p(),e.lastLoadMs=Math.round(performance.now()-T),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<b&&await W(200*2**h)}}if(f)break}if(!f||!c){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(R.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}I(c,e);let _=l.get(c);if(_&&_!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${_}", cannot re-init with "${a}"`);return typeof c.init=="function"&&await c.init(t),l.set(c,a),e.container=c,e.state="loaded",e.debug.status="loaded",u.fails=0,c})();e.containerPromise=E;try{return await E}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),u.fails+=1,u.fails>=ce&&(u.openUntil=Date.now()+le,u.fails=0),s instanceof g)throw j({remote:e.name,error:s}),s;if(s?.code)throw j({remote:e.name,error:s}),s;let c=new g(R.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw j({remote:e.name,error:c}),c}}function A(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:B(e.slice(i+1))}}function B(e){return e?e.startsWith(".")?e:`./${e}`:""}async function X(e,i){let{remote:a,module:u}=A(e);$.beforeLoadRemote?.({remote:a,module:u});let E=n.get(a);if(!E)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await C(E,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if(!u)return s;let c=`${a}@${E.shareScope||"default"}#${u}`;r.has(c)||r.set(c,s.get(u).catch(f=>{throw r.delete(c),f instanceof g||f?.code?f:new g(R.REMOTE_LOAD_FAILED,`failed to load module "${u}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:u})}));let d;try{d=await r.get(c)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if($.afterLoadRemote?.({remote:a,module:u,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(R.EMPTY_EXPORTS,`no exports: ${u} @ ${a}`,{remote:a,module:u});j({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function Y(e){let i=n.get(e);if(!i)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function Z(e,i={}){let{remote:a}=A(e),u=n.get(a);if(!u)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let E=i.mode??"preload",s=(c,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${c}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=c,E==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(u.manifestUrl){let c=await fetch(u.manifestUrl,{cache:"no-cache"});if(c.ok){let d=await c.json();s(u.entry,"modulepreload");let f=d.exposes??{};for(let b of Object.keys(f)){let _=f[b];_?.file&&s(new URL(_.file,u.entry).href,"modulepreload");for(let p of _?.css??[])s(new URL(p,u.entry).href,"style")}return}}s(u.entry,"modulepreload")}catch(c){j({remote:a,error:new g(R.PRELOAD_FAILED,String(c?.message??c),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:H,registerShare:K,registerRemotes:x,registerRemote:q,registerPlugins:G,loadShare:z,loadRemote:X,getContainer:Y,preloadRemote:Z,parseSpec:A,provideFulgurjsAppConfig:y,getFulgurjsAppConfig:w}}var V=globalThis,S=V.__FULGURJS_RUNTIME__??fe();V.__FULGURJS_RUNTIME__=S;try{Object.freeze(S)}catch{}var Re=F;function Se(){return S}var we=S.initSharing,be=S.registerShare,_e=S.registerRemotes,je=S.registerRemote,$e=S.registerPlugins,Me=S.loadShare,ve=S.loadRemote,Te=S.getContainer,Oe=S.preloadRemote,ke=S.shareScopeMap,Ne=S.provideFulgurjsAppConfig,Ie=S.getFulgurjsAppConfig;function Ae(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var xe=S;export{xe as default,Te as getContainer,Ie as getFulgurjsAppConfig,Se as getRuntime,we as initSharing,ve as loadRemote,Me as loadShare,Oe as preloadRemote,Ne as provideFulgurjsAppConfig,$e as registerPlugins,je as registerRemote,_e as registerRemotes,be as registerShare,S as runtime,ke as shareScopeMap,Ae as unwrapDefault,Re as version};\n';
|
|
1242
1242
|
|
|
1243
1243
|
// src/index.ts
|
|
1244
1244
|
function readRuntimeCode() {
|
package/dist/runtime.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var Q=/^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/;function O(t){let n=Q.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function ee(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\d+$/.test(l),w=/^\d+$/.test(m);if(y&&w){let $=Number(l)-Number(m);if($!==0)return $}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=O(t),r=O(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function k(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!O(t)?.pre.length;let o=n.split(/\s+-\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!k(t,`>=${m}`)||!k(t,`<=${y}`))}let r=O(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ne(t){let n=[],o=t.trim().split(/\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function ie(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ae(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let w of o.slice(0,3))if(/^\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function se(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=se(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FulgurjsError",this.code=n,this.details=r}},R={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var F="0.
|
|
1
|
+
var Q=/^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/;function O(t){let n=Q.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function ee(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\d+$/.test(l),w=/^\d+$/.test(m);if(y&&w){let $=Number(l)-Number(m);if($!==0)return $}else{if(y!==w)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=O(t),r=O(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:ee(o.pre,r.pre)}var re=/^[a-z]+[+:-]/i;function k(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||re.test(o)?!0:o.split("||").some(r=>te(t,r.trim()))}function te(t,n){if(!n||n==="*")return!O(t)?.pre.length;let o=n.split(/\s+-\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!k(t,`>=${m}`)||!k(t,`<=${y}`))}let r=O(t);if(!r)return!1;let l=ne(n);if(l===null)return!0;for(let m of l)if(!ue(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ne(t){let n=[],o=t.trim().split(/\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],w=oe(m,y);if(w===null)return null;n.push(...w)}return n}function oe(t,n){let o=ae(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=ie(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function ie(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ae(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let w of o.slice(0,3))if(/^\d+$/.test(w))r.push(Number(w)),l++;else{if(w==="x"||w==="X"||w==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function se(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=se(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FulgurjsError",this.code=n,this.details=r}},R={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var F="0.8.1";var U=15e3,P=2,ce=5,le=3e4;function fe(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={};function y(e){m={...m,...e},typeof globalThis<"u"&&(globalThis.__FULGURJS_APP_CONFIG__=m)}function w(){return m}let $={},D=()=>{for(let e of o)try{e.init?.($)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},N=e=>t[e]??={};function j(e){try{$.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function H(e="default"){return N(e),t}function K(e,i,a,u,E={}){let s=N(e||"default"),c=s[i]??={};c[a]||(c[a]={version:a,get:u,from:E.from??"unknown",eager:!!E.eager,loaded:!!E.loaded})}function x(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:U,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function q(e){x([e])}function G(e){o.push(...e),D()}async function z(e,i={}){let a=i.shareScope||"default",u=i.shareKey||e,s=N(a)[u]||{},c=Object.keys(s),d=i.requiredVersion,f=c.filter(p=>d===void 0||d===!1||k(p,d)),b;if(i.singleton&&c.length>0){let p=c.filter(h=>s[h].loaded);if(b=[...p.length?p:c].sort(v).pop(),c.length>1||!f.includes(b)){let h=s[b],T=`singleton skew "${u}": req "${d??"any"}" use ${b} from ${h.from}`;if(i.strictVersion){let M=new g(R.SHARE_STRICT_VERSION,T,{shareKey:u,requiredVersion:d});throw j({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${T}`)}}else if(b=[...f].sort(v).pop(),!b){if(i.strictVersion){let h=new g(R.SHARE_STRICT_VERSION,`no satisfying version for "${u}" (required "${d}") in share scope "${a}"`);throw j({remote:u,error:h}),h}if(i.fallback)return i.fallback();let p=new g(R.SHARE_NOT_AVAILABLE,`shared "${u}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:u,requiredVersion:d});throw j({remote:u,error:p}),p}let _=s[b];if($.resolveShare){let p=await $.resolveShare({shareKey:u,shareScope:a,requiredVersion:d,picked:_,available:Object.values(s)});p&&(_=p)}return _.loaded=!0,_.get()}function J(e,i,a){return new Promise((u,E)=>{let s=setTimeout(()=>E(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(c=>{clearTimeout(s),u(c)},c=>{clearTimeout(s),E(c)})})}let W=e=>new Promise(i=>setTimeout(i,e));function I(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:R.REMOTE_NAME_MISMATCH})}}async function L(e,i){return J(import(e),i.timeout??U,`load remoteEntry ${e}`)}async function C(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let u=e.breakerState;if(u.openUntil>Date.now()){let s=new g(R.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(u.openUntil).toISOString()}`,{remote:e.name});throw j({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let E=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return I(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return I(h,e),h});let c,d,f=!1,b=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=b;h++){let T=performance.now();try{c=await p(),e.lastLoadMs=Math.round(performance.now()-T),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<b&&await W(200*2**h)}}if(f)break}if(!f||!c){let p=[];throw/^https?:\/\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(R.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}
|
|
2
2
|
`+p.join(`
|
|
3
3
|
`),{remote:e.name})}I(c,e);let _=l.get(c);if(_&&_!==a)throw new g(R.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${_}", cannot re-init with "${a}"`);return typeof c.init=="function"&&await c.init(t),l.set(c,a),e.container=c,e.state="loaded",e.debug.status="loaded",u.fails=0,c})();e.containerPromise=E;try{return await E}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),u.fails+=1,u.fails>=ce&&(u.openUntil=Date.now()+le,u.fails=0),s instanceof g)throw j({remote:e.name,error:s}),s;if(s?.code)throw j({remote:e.name,error:s}),s;let c=new g(R.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw j({remote:e.name,error:c}),c}}function A(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:B(e.slice(i+1))}}function B(e){return e?e.startsWith(".")?e:`./${e}`:""}async function X(e,i){let{remote:a,module:u}=A(e);$.beforeLoadRemote?.({remote:a,module:u});let E=n.get(a);if(!E)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await C(E,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\u663E\u5F0F\u964D\u7EA7\uFF0C\u9519\u8BEF\u5DF2\u900F\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if(!u)return s;let c=`${a}@${E.shareScope||"default"}#${u}`;r.has(c)||r.set(c,s.get(u).catch(f=>{throw r.delete(c),f instanceof g||f?.code?f:new g(R.REMOTE_LOAD_FAILED,`failed to load module "${u}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:u})}));let d;try{d=await r.get(c)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\u663E\u5F0F\u964D\u7EA7\uFF0C\u9519\u8BEF\u5DF2\u900F\u51FA)`,f),j({remote:a,error:f}),await i.fallbackModule();throw f}if($.afterLoadRemote?.({remote:a,module:u,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(R.EMPTY_EXPORTS,`no exports: ${u} @ ${a}`,{remote:a,module:u});j({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function Y(e){let i=n.get(e);if(!i)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function Z(e,i={}){let{remote:a}=A(e),u=n.get(a);if(!u)throw new g(R.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let E=i.mode??"preload",s=(c,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${c}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=c,E==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(u.manifestUrl){let c=await fetch(u.manifestUrl,{cache:"no-cache"});if(c.ok){let d=await c.json();s(u.entry,"modulepreload");let f=d.exposes??{};for(let b of Object.keys(f)){let _=f[b];_?.file&&s(new URL(_.file,u.entry).href,"modulepreload");for(let p of _?.css??[])s(new URL(p,u.entry).href,"style")}return}}s(u.entry,"modulepreload")}catch(c){j({remote:a,error:new g(R.PRELOAD_FAILED,String(c?.message??c),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:H,registerShare:K,registerRemotes:x,registerRemote:q,registerPlugins:G,loadShare:z,loadRemote:X,getContainer:Y,preloadRemote:Z,parseSpec:A,provideFulgurjsAppConfig:y,getFulgurjsAppConfig:w}}var V=globalThis,S=V.__FULGURJS_RUNTIME__??fe();V.__FULGURJS_RUNTIME__=S;try{Object.freeze(S)}catch{}var Re=F;function Se(){return S}var we=S.initSharing,be=S.registerShare,_e=S.registerRemotes,je=S.registerRemote,$e=S.registerPlugins,Me=S.loadShare,ve=S.loadRemote,Te=S.getContainer,Oe=S.preloadRemote,ke=S.shareScopeMap,Ne=S.provideFulgurjsAppConfig,Ie=S.getFulgurjsAppConfig;function Ae(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var xe=S;export{xe as default,Te as getContainer,Ie as getFulgurjsAppConfig,Se as getRuntime,we as initSharing,ve as loadRemote,Me as loadShare,Oe as preloadRemote,Ne as provideFulgurjsAppConfig,$e as registerPlugins,je as registerRemote,_e as registerRemotes,be as registerShare,S as runtime,ke as shareScopeMap,Ae as unwrapDefault,Re as version};
|
package/dist/vue.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
ErrorCodes,
|
|
3
|
+
FulgurjsError
|
|
4
|
+
} from "./chunk-CK42RK2O.js";
|
|
5
|
+
import "./chunk-P4DGTHMF.js";
|
|
2
6
|
|
|
3
7
|
// src/vue.ts
|
|
4
8
|
import { defineAsyncComponent, defineComponent, h } from "vue";
|
|
@@ -201,40 +205,6 @@ function testComparator(v, versionStr, c) {
|
|
|
201
205
|
return baseOk;
|
|
202
206
|
}
|
|
203
207
|
|
|
204
|
-
// src/runtime/errors.ts
|
|
205
|
-
var FulgurjsError = class extends Error {
|
|
206
|
-
code;
|
|
207
|
-
details;
|
|
208
|
-
constructor(code, message, details) {
|
|
209
|
-
super(`[fulgurjs:${code}] ${message}`);
|
|
210
|
-
this.name = "FulgurjsError";
|
|
211
|
-
this.code = code;
|
|
212
|
-
this.details = details;
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
var ErrorCodes = {
|
|
216
|
-
/** 远程容器加载失败(网络/超时/重试耗尽/熔断) */
|
|
217
|
-
REMOTE_LOAD_FAILED: "MFU-001",
|
|
218
|
-
/** remoteEntry 自报名与 remotes 配置的名称不匹配 */
|
|
219
|
-
REMOTE_NAME_MISMATCH: "MFU-002",
|
|
220
|
-
/** strictVersion 开启且共享版本不满足 */
|
|
221
|
-
SHARE_STRICT_VERSION: "MFU-003",
|
|
222
|
-
/** 共享模块缺失且无本地 fallback(import: false) */
|
|
223
|
-
SHARE_NOT_AVAILABLE: "MFU-004",
|
|
224
|
-
/** 同一容器用不同 share scope 重复 init */
|
|
225
|
-
CONTAINER_REINIT_CONFLICT: "MFU-005",
|
|
226
|
-
/** 请求的模块未被该远程 exposes */
|
|
227
|
-
MODULE_NOT_EXPOSED: "MFU-006",
|
|
228
|
-
/** 预加载失败 */
|
|
229
|
-
PRELOAD_FAILED: "MFU-007",
|
|
230
|
-
/** 未知远程 */
|
|
231
|
-
REMOTE_UNKNOWN: "MFU-008",
|
|
232
|
-
/** 加载到的模块没有任何导出(常见:exposes 指向了不导出内容的文件) */
|
|
233
|
-
EMPTY_EXPORTS: "MFU-009",
|
|
234
|
-
/** singleton 共享协商版本与消费方 requiredVersion 不一致(使用作用域版本,仅告警) */
|
|
235
|
-
SINGLETON_SKEW: "MFU-010"
|
|
236
|
-
};
|
|
237
|
-
|
|
238
208
|
// src/runtime/index.ts
|
|
239
209
|
var DEFAULT_TIMEOUT = 15e3;
|
|
240
210
|
var DEFAULT_RETRIES = 2;
|
|
@@ -76,6 +76,71 @@ const FederatedBusinessForm = remoteComponent('cku-mes-admin/FormRouterPage')
|
|
|
76
76
|
`(globalThis as any).__FULGURJS_RUNTIME__` 直取全局单例仅剩"独立访问远程页 vs 联邦加载"的 realm
|
|
77
77
|
检测等特殊场景(0.7.0 删除 iframe 乾坤旧通道后,常规集成已无此类需求)。
|
|
78
78
|
|
|
79
|
+
## 三C、跨应用传值:FulgurjsAppContext(0.8.0 起)
|
|
80
|
+
|
|
81
|
+
原 qiankun `props` / `globalState` / `window.*` 裸口子,0.8.0 起统一收编为 context 一等公民通道(对标乾坤 props,带类型与错误契约):
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// 宿主桥(admin/src/fulgurjs/host/bridge.ts)——登录完成后一次性提供
|
|
85
|
+
import { provideFulgurjsAppContext } from '@fulgurjs/federation/context'
|
|
86
|
+
provideFulgurjsAppContext({
|
|
87
|
+
user, token, getToken, store, hostApp, locale,
|
|
88
|
+
events: { main: mainEvents }, // 方法池:宿主提供 main.*,子应用反向注册 bpm.* / lowcode.*
|
|
89
|
+
formUrl: '/flowable', baseUrl: '/meszc', // 项目扩展位
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// 远程启动引导(xxx/src/fulgurjs/exposes/federatedBoot.ts)——显式校验消费
|
|
93
|
+
import { requireFulgurjsAppContext } from '@fulgurjs/federation/context'
|
|
94
|
+
const { store, user, hostApp } = requireFulgurjsAppContext('store', 'user', 'hostApp')
|
|
95
|
+
// 缺键 → [fulgurjs:CC-001](三段式,指向宿主桥);独立直开远程页 → [fulgurjs:CC-002]
|
|
96
|
+
|
|
97
|
+
// 页面读点(替代 window.mainAppProps?.xxx)
|
|
98
|
+
import { getFulgurjsAppContext } from '@fulgurjs/federation/context'
|
|
99
|
+
const dict = getFulgurjsAppContext().events?.main?.getDictItems?.('sex')
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
要点:
|
|
103
|
+
|
|
104
|
+
- **时序契约**:bridge(provide)→ federatedBoot(require)→ 页面 loadRemote;违反即在 boot 显式失败(CC-001),无静默;
|
|
105
|
+
- **数据语义**:传输层快照 + 函数引用,非响应式(与乾坤 props 同语义)。"实时"三通道 = ①函数引用拉取(`getToken()` / `events.main.*` 每次执行宿主最新闭包)②宿主 pinia 共享响应式(`useUserStore(ctx.store)`)③登录变更 = 刷新重跑;
|
|
106
|
+
- **嵌套对象(events)是引用共享**:子应用挂属性即时可见(同 realm 直引用);
|
|
107
|
+
- **方法引用两条通道**:高频热路径(token/字典/文件 URL、反向注册)走 context 函数引用;低频/重逻辑跨应用调用走 exposes 方法模块——远程 `src/fulgurjs/exposes/api.ts` 导出纯函数(不挂 Vue 组件),对面 `await loadRemote('remote/api')`;
|
|
108
|
+
- 旧名 `provideFulgurjsAppConfig / getFulgurjsAppConfig` 存储同一份,已标 `@deprecated`(0.9 删),存量代码请迁新名。
|
|
109
|
+
|
|
110
|
+
## 三D、页面卸载清理清单(0.8.0 起)
|
|
111
|
+
|
|
112
|
+
乾坤 `unmount` 会强制子应用清理 window 级资源;联邦**组件级**卸载不会自动清——以下资源必须在页面组件 `onUnmounted` 里自行摘除,否则切走再切回会重复注册/重复触发:
|
|
113
|
+
|
|
114
|
+
| 资源 | 清理方式 |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `context.events.bpm.xxx = fn` 反向注册 | `onUnmounted(() => { delete getFulgurjsAppContext().events?.bpm?.xxx })` |
|
|
117
|
+
| `window.addEventListener(...)` | 记住函数引用,`onUnmounted` 里 `removeEventListener` |
|
|
118
|
+
| `setInterval` / `setTimeout` | `onUnmounted` 里 `clearInterval` / `clearTimeout` |
|
|
119
|
+
| `window.__FULGURJS_INFO__.errors.push(...)` 之外的自挂全局 | 同理显式删除 |
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { onUnmounted } from 'vue'
|
|
123
|
+
const onBpmEvent = (e: unknown) => { /* ... */ }
|
|
124
|
+
getFulgurjsAppContext().events!.bpm!.formEvent = onBpmEvent
|
|
125
|
+
onUnmounted(() => {
|
|
126
|
+
const events = getFulgurjsAppContext().events
|
|
127
|
+
if (events?.bpm?.formEvent === onBpmEvent) delete events.bpm.formEvent
|
|
128
|
+
})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
> 轻量提醒而非插件机制:绝大多数页面只有数据请求(随组件销毁自然结束),无需任何清理;有上述全局副作用的页面按清单逐项过一遍即可。
|
|
132
|
+
|
|
133
|
+
## 三E、乾坤融合三件套 + 联邦诊断面板(0.8.0 起,`fulgurjs init` 模板直接带出)
|
|
134
|
+
|
|
135
|
+
| 能力 | 配置入口 | 默认 | 行为 |
|
|
136
|
+
|---|---|---|---|
|
|
137
|
+
| **A 保活**(多 tab 状态保留) | 页面表条目 `keepAlive: true`(手工项目改 `src/fulgurjs/host/pages.ts`;集成器项目改 `fulgurjs.config.ts` 后删产物重跑 init) | 全关 | LayoutContent 联邦分支 `<keep-alive :include :max="8">`,白名单页切走切回状态保留;重型组件(vxe-table/表单设计器)按需开启 |
|
|
138
|
+
| **B 骨架屏** | 无(工厂内置) | 开 | 异步页面组件 `loadingComponent`(渐变骨架条,delay 200ms 防闪),冷启动/切页不再白屏 |
|
|
139
|
+
| **C 空闲预载** | `bridge.ts` 顶部 `PREFETCH_REMOTES: string[]`(置空 `[]` 关闭) | 开(全部 remote) | 登录后 `requestIdleCallback` 逐个 `preloadRemote(prefetch)`,首开子应用不等 chunk;失败 MFU-007 不阻断 |
|
|
140
|
+
| **D 诊断面板** | 无(免登录路由 `/fulgurjs-demo`) | 有 | 六块:方法模块调用演示 / remotes 状态 / shared 协商 / context 快照 / fulgurjs:error 历史日志 / 资源加载耗时 |
|
|
141
|
+
|
|
142
|
+
**IDE 提示**:`src/fulgurjs/types/*.d.ts` 为插件自动生成的跨工程类型直连(勿手改)——VSCode 打开这些生成物时可能显示大片"找不到模块 '@/...'"(Volar 以推断项目检查工程外 .vue 所致),命令行 `vue-tsc --noEmit` 走本应用 tsconfig 为 0 错误,构建不受影响;升级插件后 context 导入报 ts(2307) 时 `Restart TS Server` 清缓存。
|
|
143
|
+
|
|
79
144
|
## 四、乾坤下线顺序
|
|
80
145
|
|
|
81
146
|
1. 联邦模式全量验收(本清单)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fulgurjs/federation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vite Module Federation with full Webpack MF parity. Dev & production, no compromise.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
"import": "./dist/vue.js",
|
|
29
29
|
"require": "./dist/vue.cjs"
|
|
30
30
|
},
|
|
31
|
+
"./context": {
|
|
32
|
+
"types": "./dist/context.d.ts",
|
|
33
|
+
"import": "./dist/context.js",
|
|
34
|
+
"require": "./dist/context.cjs"
|
|
35
|
+
},
|
|
31
36
|
"./client": {
|
|
32
37
|
"types": "./client.d.ts"
|
|
33
38
|
},
|
|
@@ -43,6 +48,9 @@
|
|
|
43
48
|
],
|
|
44
49
|
"vue": [
|
|
45
50
|
"dist/vue.d.ts"
|
|
51
|
+
],
|
|
52
|
+
"context": [
|
|
53
|
+
"dist/context.d.ts"
|
|
46
54
|
]
|
|
47
55
|
}
|
|
48
56
|
},
|
|
@@ -62,7 +70,7 @@
|
|
|
62
70
|
"docs/vite-upstream-issue-irregexp.md"
|
|
63
71
|
],
|
|
64
72
|
"scripts": {
|
|
65
|
-
"build": "cp ../../README.md README.md && mkdir -p docs && cp ../../docs/manual.html ../../docs/迁移指南.md ../../docs/webpack-mf-对照与缺口.md ../../docs/沙箱边界审计.md ../../docs/P5-vite7-8兼容矩阵.md ../../docs/vite-upstream-issue-irregexp.md docs/ && cp ../../CHANGELOG.md CHANGELOG.md && cp ../../DESIGN.md DESIGN.md && rm -rf examples && cp -r ../../examples examples && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime.mjs && tsup src/index.ts src/pages.ts src/config.ts src/vue.ts --format esm,cjs --dts --external vite --target node18 --clean && esbuild src/cli.ts --bundle --format=esm --target=node18 --platform=node --outfile=dist/cli.js && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js",
|
|
73
|
+
"build": "cp ../../README.md README.md && mkdir -p docs && cp ../../docs/manual.html ../../docs/迁移指南.md ../../docs/webpack-mf-对照与缺口.md ../../docs/沙箱边界审计.md ../../docs/P5-vite7-8兼容矩阵.md ../../docs/vite-upstream-issue-irregexp.md docs/ && cp ../../CHANGELOG.md CHANGELOG.md && cp ../../DESIGN.md DESIGN.md && rm -rf examples && cp -r ../../examples examples && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime.mjs && tsup src/index.ts src/pages.ts src/config.ts src/vue.ts src/context.ts --format esm,cjs --dts --external vite --target node18 --clean && esbuild src/cli.ts --bundle --format=esm --target=node18 --platform=node --outfile=dist/cli.js && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js",
|
|
66
74
|
"dev": "tsup --watch",
|
|
67
75
|
"test": "vitest run",
|
|
68
76
|
"typecheck": "tsc --noEmit"
|