@equinor/fusion-framework-module-context

中文文档
9.1.0发布于 2026/11/12ISCTypeScriptES Module近 30 天下载 1.4万
中文使用文档
文档目录19 节
  1. 何时使用
  2. 如何融为一体
  3. 文档
  4. 关键概念
  5. 快开始
  6. 操作遥测
  7. 配置
  8. 配置参考
  9. URL 中的背景运行
  10. 宣布路线战略
  11. 自定义URL形状
  12. 如何运作(供参考)
  13. 活动
  14. 错误
  15. 测试
  16. 默认
  17. 生成决定性上下文定着
  18. 公用事业
  19. 软件包出口

@ equinor/ 组合- 框架- 模块- 文本

融合框架的背景模块。 管理基于Fusion的应用程序和门户网站中的活性上下文(项目,设施,合同等),提供查询,验证,解析,以及从框出父子同步.

何时使用

当您的应用程序或门户需要时使用此模块:

  • 设置、 读取或清除活性上下文( 如选择工程)
  • 搜索和过滤 Fusion 上下文 API 中可用的上下文项目
  • 验证某一上下文项目是否匹配允许的上下文类型
  • 跨越父子提供方边界的解析上下文(门户网站 )
  • 通过从 URL 路径取出上下文ID来进行深链接

应用程序开发者 通常使用高级 @equinor/fusion-framework-react-app/context 包件, 包到底 模块带有反应钩和提供者.

门户开发者 将使用 @equinor/fusion-framework-react/context 在门户一级也是为了同样的目的.

如何融为一体

一个上下文模块从不孤立地生活。 这取决于 @equinor/fusion-framework-module-services 用于默认 HTTP 客户端的模块,可选 用途 @equinor/fusion-framework-module-event 发送和聆听背景变化事件, 并选择通过 @equinor/fusion-framework-module-navigation 改为 从路径中解决上下文。 这些不需要人工设置—— enableContext 需求 仅限 services· ; event 财务报告和审定财务报表 navigation 当您到场时会自动拾取.

模块也是 默认的层次意识: 当一个门户网站和一个App同时启用时 上下文, App 实例自动连接到 Portal 上下文 —— 除了两侧启用模块外,不需要接线。 见 生命周期 确切的说,同步是如何工作的 当它可以被推翻或致残.

文档

专题说明
数据模型形状 ContextItem,上下文类型如何相互联系,以及查询/相关参数
生命周期setCurrentContext校验/解析决定流程、启动时自动初始文本解析以及父/子背景传播
食谱OData 查询参数、 路径重写、 接受上下文类型家族以及自定义搜索错误

关键概念

概念说明
背景项目代表单个上下文实体(项目,设施等)的打出的记录.
提供背景运行时服务曝光查询,设置,验证,解析,以及事件API.
背景模块配置器流利地用于配置上下文类型,过滤器,客户端和钩子.
启用内容在模块配置器上注册模块的助手.
背景决议当上下文类型不符合所配置的类型时,自动查找相关上下文项目.
父连接双向同步介于父端门户上下文和子端应用上下文之间.

快开始

import { enableContext } from '@equinor/fusion-framework-module-context';

export const configure = (configurator) => {
  enableContext(configurator, (builder) => {
    // only accept ProjectMaster context items
    builder.setContextType(['ProjectMaster']);
  });
};

初始化后, 从模块实例中访问提供者 :

// observe context changes
modules.context.currentContext$.subscribe((ctx) => {
  console.log('context changed', ctx);
});

// search for context items
const items = await modules.context.queryContextAsync('Johan');

// set context by item
await modules.context.setCurrentContextAsync(items[0]);

// set context by ID
await modules.context.setCurrentContextByIdAsync('7fd97952-...');

// clear the active context
modules.context.clearCurrentContext();

操作遥测

IContextProvider 扩展 TelemetryConnectable。供应商使用 telemetry.scope('context')回到了懒惰的工厂 以古老的习俗 提供商,并关闭处置的共享手柄; 选择/分辨率观察仍保留在上下文模块中.

当主机注册遥测时, 每个队列 setCurrentContext 任务报告1 fusion.context.select.duration 结果。 每一份决议尝试报告 fusion.context.resolve.duration,无论来自选择,一个直接 resolveContext编号 :resolveContextAsync 调用或配置的解析器( n)by: 'item'),或 从后面的搜索 setCurrentContextById (单位:千美元)by: 'id':

  • failure 有理无据 validation 验证失败而解析被禁;
  • cancelled 有理无据 listener 当 onSetContextResolve, (中文(简体) ), onSetContextResolved 或者说 onCurrentContextChange 听众的电话 preventDefault()· ;
  • cancelled 当更新的任务取代任务时,调用者不订阅,或者 处理供应商(理由 disposed) (中文(简体) ).

未验证的重设当前项目被跳过, 并且没有报告 . 背景标识,标题和值从不导出,背景行为不变. 同步解析器工厂故障记录并同步重投, 不包含 更改错误对象。 最终 onCurrentContextChange 否决权记录的取消 即刻,包括现有的去除-误差路径;遥测不改变 这条路的呼叫者行为. 见 操作遥测。 。 。 .

配置

所有配置流经 enableContext → ContextModuleConfigurator数字 :

enableContext(configurator, (builder) => {
  // restrict accepted context types
  builder.setContextType(['ProjectMaster', 'Facility']);

  // post-query filter
  builder.setContextFilter((items) => items.filter((i) => i.isActive));

  // custom parameter mapping for the search API
  builder.setContextParameterFn(({ search, type }) => ({
    search,
    filter: { type },
  }));

  // custom validation logic
  builder.setValidateContext(function (item) {
    return item !== null && this.validateContext(item);
  });

  // custom context resolution
  builder.setResolveContext(function (item) {
    return this.relatedContexts({ item, filter: { type: ['ProjectMaster'] } });
  });

  // connect (or disconnect) from parent context
  // when enabled (default), onParentContextChanged fires before mirroring the parent's context locally
  builder.connectParentContext(false);

  // path ↔ context integration
  // the default resolver uses extractContextIdFromPath to pull a GUID from the URL,
  // then fetches the matching context item — see resolveInitialContext in utils
  builder.setContextPathExtractor((path) => path.split('/')[2]);
  builder.setContextPathGenerator((ctx, path) =>
    path.replace(/\/context\/[^/]+/, `/context/${ctx.id}`),
  );

  // provide a fully custom context client
  builder.setContextClient({
    get: (args) => fetch(`/api/context/${args.id}`).then((r) => r.json()),
    query: (args) => fetch(`/api/context?q=${args.search}`).then((r) => r.json()),
  });
});

配置参考

构建方法目的
setContextType(types)用于验证的上下文类型ID
setContextFilter(fn)冲洗后结果过滤器
setContextParameterFn(fn)地图搜索 + 类型到 API 查询参数
setValidateContext(fn)自定义验证( O)this = 供应商)
setResolveContext(fn)自定义分辨率( O)this = 供应商)
connectParentContext(bool)启用/ 残疾父上下文同步( 火) onParentContextChanged 页:1
setContextPathExtractor(fn)从 URL 路径提取上下文 ID
setContextPathGenerator(fn)从上下文项目生成 URL 路径
setResolveInitialContext(fn)覆盖初始上下文解析度( 默认使用) extractContextIdFromPath → resolveContextFromPath(中文(简体) )
setContextClient(client)自定义获取/取用/相关客户端

URL 中的背景运行

门户网站将活动上下文自动与浏览器 URL同步 通过 @equinor/fusion-framework-plugin-context-navigation 插件 。 作为应用 开发者,您控制 怎么样 上下文通过声明路径在您的 URL 中出现 在您的应用程序列表中的策略 .

宣布路线战略

设定 contextRouting 在你的清单 build.options数字 :

// app.manifest.config.ts
{
  "build": {
    "options": {
      "contextRouting": "query"
    }
  }
}
数值URL 形状何时使用
'path' (或省略)/apps/{appKey}/{contextId}/sub-route默认——没有复杂路径路径的简单应用程序
'query'/apps/{appKey}/route?$contextId={id}与上下文路径段相冲突的嵌入路线的应用程序

有自定义 URL 形状的应用程序可以省略 contextRouting 并登记自定义钩(见下文). 明确 contextRouting: 'query' 总是选择查询路由,即使注册了自定义钩.

[注] 何时 contextRouting 未设定( 或设定为 null),门户默认为 路径适配器 将上下文编码为应用程序键后的一个路径段. 如果您的应用程序也注册自定义钩( I)setContextPathExtractor 编号 : setContextPathGenerator),自定义适配器优先于路径 用于路径路由或在没有宣布策略时的适配器。 明确 contextRouting: 'query' 选择查询适配器.

自定义URL形状

如果您的应用程序对上下文使用非标准的 URL 版式( 如. /route-a/{contextId}, (中文(简体) ), 注册自定义钩子而不是(或除此之外)声明 contextRouting数字 :

enableContext(configurator, (builder) => {
  builder.setContextType(['ProjectMaster']);

  // Tell the portal how to find the context id in your URL
  builder.setContextPathExtractor((path) => {
    const segments = path.split('/').filter(Boolean);
    return segments[1]; // e.g. /route-a/{contextId}
  });

  // Tell the portal how to build a URL with context
  builder.setContextPathGenerator((context, path) => {
    const segments = path.split('/').filter(Boolean);
    const route = segments[0] ?? '';
    return `/${route}/${context.id}`;
  });
});

这些钩子注册后,门户的自定义适配器会自动使用它们—— 没有 contextRouting 名单中需要声明.

如何运作(供参考)

门户的上下文导航插件读取 contextRouting 从你的应用软件 在运行时显示并选择适当的 URL 适配器。 你不安装 或自行配置插件——门户处理。 您的应用程序只需要 宣布其倾向.

活动

上下文模块通过 @equinor/fusion-framework-module-event 系统。 所有事件都属于 ContextProvider 来源.

活动何时可取消
onCurrentContextChange在更新当前上下文之前对
onCurrentContextChanged在当前环境发生变化后没有
onParentContextChanged在本地镜像父上下文更改之前对
onSetContextResolve在上下文解析开始前对
onSetContextResolved上下文解析完成后对
onSetContextValidationFailed当验证失败( 没有解析)没有
onSetContextResolveFailed解析失败时出错没有
modules.event.addEventListener('onCurrentContextChanged', (e) => {
  console.log('previous:', e.detail.previous);
  console.log('next:', e.detail.next);
});

错误

模块导出 FusionContextSearchError (从) @equinor/fusion-framework-module-context/errors.js与搜索有关的失败:

import { FusionContextSearchError } from '@equinor/fusion-framework-module-context/errors.js';

try {
  await modules.context.queryContextAsync('...');
} catch (err) {
  if (err instanceof FusionContextSearchError) {
    console.error(err.title, err.description);
  }
}

测试

@equinor/fusion-framework-module-context/mock 提供 enableContextMock,一个目的所建的测试双人由一串种子上下文项的内存支撑——没有上下文 API,没有HTTP模拟,不需要服务发现模拟. 真实 ContextProvider 行为validateContext, (中文(简体) ), resolveContext,父文本传播)仍然运行在种子数据上;只有数据源被替换.

默认

  • 上下文池开始为空, 没有选择当前上下文 .
  • 查询空池不返回项目 .
  • 查找一个未种子的ID会抛出一个错误,将ID和种子方法命名.
  • 关联的context lookup使用种子池,排除源项,并按所请求的类型过滤.
  • setCurrentContext 既种子项目,又选择初始应用分辨率; setContexts 只有种子项目.
import { enableContextMock } from '@equinor/fusion-framework-module-context/mock';

enableContextMock(configurator, (mock) => {
  mock.setCurrentContext({ id: 'my-ctx', type: { id: 'ProjectMaster' }, value: {} });
});
  • 友好层 —— 说 setCurrentContext, (中文(简体) ), setContexts, (中文(简体) ), addContext, (中文(简体) ), setRelatedContexts ——常见案例的上下文域词汇:种子一个已知项目,取回.
  • 逃逸舱门 —— 说 setResolver – 自定义的原始解析函数 resolveContext 策略或形状 友好层没有覆盖.

使用时 @equinor/fusion-framework/mock, (中文(简体) ), FrameworkMockConfigurator.context 返回相同的配置符,所以种子直接通过 configurator.context 不需要回电.

这是在测试中伪造上下文数据的两种方法之一. 另一个是直接嘲笑上下文 API的 HTTP 响应(与 configurator.http.addMiddleware(...)可选配对 @equinor/fusion-framework-module-http/mock是因为 createOpenApiMockMiddleware 用于直接从上下文的 OpenAPI spec 中获取的假冒数据 ) —— 用于练习真实 ContextModuleConfigurator/服务/HTTP管道,而不是取而代之. 到达 enableContextMock (d) 当试验需要覆盖管道本身时,HTTP中间器件的伸展范围。 用于实际种子数据的固定发电机(createContextItemFactory, (中文(简体) ), createContextItems可从下列网址获取: @equinor/fusion-framework-module-context/mock/fixtures。 。 。 .

生成决定性上下文定着

可选 /mock/fixtures 进入点用途 @faker-js/faker 产生现实但 可重复标题和可读标识。 仅在导入此切入点时安装 Faker .

import { enableContextMock } from '@equinor/fusion-framework-module-context/mock';
import { createContextItems } from '@equinor/fusion-framework-module-context/mock/fixtures';

const [project, contract] = createContextItems([
  { type: 'ProjectMaster' },
  { type: 'Contract', parentTypeIds: ['ProjectMaster'] },
]);

enableContextMock(configurator, (mock) => {
  mock.setContexts([project, contract]);
  mock.setCurrentContext(project);
});

使用 createContextItemFactory(prefix?) 用于一种类型的相继固定装置。 使用 createContextItems 用于多个类型和父/子类型元数据。 生成值为 确定/ id; 使用 setRelatedContexts 当每个特定项目的关系必须不同时.

公用事业

可向下列机构提供其他帮助: @equinor/fusion-framework-module-context/utils数字 :

导出目的
enableContext在配置器上注册上下文模块
resolveInitialContext默认初始文本解析器( path ) – 父倒置)
extractContextIdFromPath从 URL 路径中提取一个 GUID 格式上下文 ID
resolveContextFromPath从 URL 路径获取上下文项的解析器函数

软件包出口

指定者说明
@equinor/fusion-framework-module-context主要条目——模块,提供者,配置器,类型
@equinor/fusion-framework-module-context/errors.jsFusionContextSearchError
@equinor/fusion-framework-module-context/utils路径解析和启用的功能
@equinor/fusion-framework-module-context/mockenableContextMock, (中文(简体) ), ContextMockConfigurator - 模拟测试双倍
@equinor/fusion-framework-module-context/mock/fixtures生产上下文种子的固定工厂

版本与发布记录

@equinor/fusion-framework-module-context 共发布 195 个版本,首次发布于 2022/10/26;过去 12 个月发布了 17 个版本。

版本发布日期距今
9.1.0latest2026/11/121 天前
9.1.0-next.1next2026/11/112 天前
9.1.0-next.02026/10/2816 天前
9.0.32026/10/2717 天前
9.0.3-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85atrusted-publishing-202610152026/10/1629 天前
9.0.22026/10/121 个月前

其他发布通道:apploader → 6.0.4-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9,cli-search-index → 7.0.3-cli-search-index.0,msal-v5 → 7.0.3-msal-v5.0,trusted-publishing-20261015 → 9.0.3-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85a,next → 9.1.0-next.1。

关于 @equinor/fusion-framework-module-context 的常见问题

如何安装 @equinor/fusion-framework-module-context?

在项目目录运行 npm install @equinor/fusion-framework-module-context,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:rxjs(^7.0.0)、semver(^7.0.0)、@types/semver(^7.0.0)、@equinor/fusion-framework-module(^6.2.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@equinor/fusion-framework-module-context 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@equinor/fusion-framework-module-context 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@equinor/fusion-framework-module-context 可以商用吗?

@equinor/fusion-framework-module-context 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@equinor/fusion-framework-module-context 的下载量有多少?

根据 npm 官方下载统计,@equinor/fusion-framework-module-context 在 2026/10/14 – 2026/11/12 这 30 天内被下载 14,276 次,日均约 476 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@equinor/fusion-framework-module-context 还在维护吗?

最新版本 9.1.0 发布于 2026/11/12(1 天前);至今共发布 195 个版本,其中过去 12 个月发布了 17 个;首次发布于 2022/10/26。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。