@atlaskit/旗下客户
浏览器- 安全 JavaScript 客户端, 用于从服务器读取评价过的特性旗
BulkEvaluationPayload。 。 。 .
客户端不会在当地获取,投票,订阅或评价国旗规则. 打电话者,通常
@atlaskit/feature-gate-js-client 包装器,获得有效载荷(从地物旗帜服务处获得)
/evalFlags 响应或服务器的靴子),并通过一个
同步供养.
这个包是FFPJavaScript客户端. 在阿特拉斯前端维持
单相机。 其行为由 client-js-* 能力
openspec/specs/
输入 feature-flag-platform 仓库.
安装和导入
yarn add @atlaskit/flag-client
import { FlagClient } from '@atlaskit/flag-client/client';
import type { BulkEvaluationPayload, FlagUser } from '@atlaskit/flag-client/types';
有效载荷形状
BulkEvaluationPayload,供应商返回的,是有效载荷电线格式的结合
客户支持, 受到歧视 vs它目前有一个成员, BulkEvaluationPayloadV1A级
未来计划版本的外形可能完全不同 并且将永远带着它 vs。 。 。 .
A 类 BulkEvaluationPayloadV1 是对象有:
vs(可选):有效载荷计划版本. 唯一支持的版本是"1"和缺席vs被视为"1"。没有vs与原载相同的有效载荷vs: "1"生成相同的旗帜值并详细列出元数据。 任何其他价值,包括null或 编号1,未初始化或替换为invalid_schema_version在其他时间之前 有效载荷被验证.flags(所需):aBulkEvaluationResult,将每个旗帜键映射为 aFlagResult。 。 形状匹配flags地物旗务局成员ffp载荷。 也许是空的.requestContext(要求):对有效载荷的识别特征和属性进行了评估。 它必须 成型良好,但客户端不使用它来读取或细节. 没有它的有效载荷失败 与invalid_payload_shape。 。attributes可选和缺勤attributes保留 作为{}页:1nullattributes以invalid_payload_shape。 。 。 .clientVersion(可选):旗下数据版本,,{ token, updatedAt? },匹配 地物旗帜服务FfpBootstrapPayload.ClientVersion。当存在时,token一定是个 非空字符串和updatedAt一个字符串。 客户把它和有效载荷放在一起,换上replace,而不用于读取或细节.
A 类 null requestContext 或者说 clientVersion 无效。 其他有效载荷成员,例如: status 或者说
targetApp,被忽略,所以一个 ffp 对象可以作为-is通过。 旗下未知成员
结果及其元数据也被忽视.
此输入与服务器 SDK 有意不同 BulkEvaluationPayload 说明
sdks/README.md数字 :
它没有有效载荷水平 status。 。 。 .
每个旗帜结果的元数据也可能携带 holdoutAllocation, (中文(简体) ), segments, (中文(简体) ), targetApps, (中文(简体) ),
flagVersion,以及 errorMessage。当它们出现时,它们必须是物体或 null,以
对象、字符串、字符串和字符串。 A 类 holdoutAllocations 列表从
年长的制片人被忽略了.
初始化
每个目标应用和环境构建一个客户端,然后初始化. 初始化为 同步,每个客户实例一次性,永不抛出.
const client = new FlagClient({
targetApp: 'jira-frontend',
environmentType: 'prod', // 'dev' | 'local' | 'staging' | 'prod'
serviceVersion: appVersion, // optional
});
const user: FlagUser = {
identifiers: { atlassianAccountId: accountId },
attributes: { plan: 'premium' }, // optional
};
const init = client.initialize(() => payload, user);
if (!init.initialized) {
// Reads return safe defaults. The SDK logs the failure reason and a troubleshooting tip.
}
- 构造器选项为实例的寿命设定 .
targetApp财务报告和审定财务报表environmentType需要并且serviceVersion是可选的。 客户端在未验证的情况下复制 运行时间,在施工期间从不投掷,也不用于阅读. 他们识别 客户端在曝光遥测. - 只有在
initialize或者说replace。客户端保持不可改变 它返回的有效载荷的快照. - 失败的原因是
already_initialized, (中文(简体) ),provider_threw, (中文(简体) ),provider_returned_no_payload, (中文(简体) ),invalid_schema_version, (中文(简体) ),invalid_payload_shape,以及payload_capture_failed失败 初始化,不包括already_initialized,可以重审.
用户
存储时, 用户将正常化为被冻结的副本 :
- 非字符串的标识符值被丢弃 .
- 属性值不是字符串、布尔斯或有限数字被丢弃.
- 一个用户,
identifiers,或attributes非对象成员被视为空。 选择attributes等同为{}。 。 。 .
常态化从不失败初始化或替换,空的标识符映射是有效的. 何时
sDK记录一 console.warn(...) 每个呼叫中, 给丢的密钥起名, 但是
从来没有他们的价值观.
客户端将常态化用户从每次初始化尝试中保留下来,但
already_initialized,包括一个失败, 因此曝光遥测可以属性读取
在初始化成功之前.
替换有效载荷和用户
使用 replace 当用户更改时。 它将有效载荷和用户互换;构建器选项
不变.
const outcome = client.replace(() => nextPayload, nextUser);
if (!outcome.replaced) {
// The previous payload and user are still served.
}
replace 失败 not_initialized,没有援引提供者,直到 initialize 已经
成功 。 其其他故障原因与初始化供应商和有效载荷原因相匹配. 任何失败
替换可以保持先前的有效载荷和用户,SDK记录原因和提示.
读取值和细节
输入值读取当有效载荷能为请求的旗帜服务时返回已初始化的旗帜值 和类型。 否则,他们将归还提供的安全违约.
const enabled = client.getBooleanValue('admin-toolbar.enabled', false);
const label = client.getStringValue('button.label', 'Continue');
const maxResults = client.getNumberValue('search.max-results', 25);
const config = client.getObjectValue('ui.config', { density: 'comfortable' });
细节读取返回请求旗的相同选定值和元数据.
const details = client.getBooleanDetails('admin-toolbar.enabled', false);
console.log(details.value);
console.log(details.metadata.matchReason);
console.log(details.metadata.identifierValue); // from the current user
console.log(details.metadata.holdoutAllocation);
identifierValue 在使用结果的当前用户标识符中查找
identifierType,从来没有在有效载荷 requestContext。 。 。 . holdoutAllocation 是结果
分配,或 null 缺席时,和 segments 是结果的列表,或者当
缺席. targetApps, (中文(简体) ), flagVersion,以及 errorMessage 内部保留,不属于
细节元数据.
安全默认和代码默认
客户端返回未初始化时的安全默认值, 旗帜缺失, 请求读取
类型不匹配旗下结果,运行时值形状无法使用,或者结果有
useCodeDefault = true。 。 。 .
对于 useCodeDefault = true,细节读取仍然保留服务器元数据 从有效载荷。 其它
后退大小写使用客户端生成的元数据 : not_initialized, (中文(简体) ), flag_not_found,或
type_mismatch。 。 。 .
对象和数组值
从初始有效载荷状态中选择的对象和阵列值来自客户端的不可改变性 载荷快照。 相对于已回回的初始值的变异尝试不会在以后改变 读取或详细说明元数据。 将返回的对象或阵列克隆在应用代码中变异之前 .
安全默认值由呼叫者提供返回.
曝光遥测
在浏览器中,每个输入的值或细节都会记录一次曝光: OpenTeleometry 日志记录在
共享接触计划(sdks/design/otel-exposure-event-schema.md 在地标-旗-平面图中
存储器). 客户端批量曝光并张贴为OTLP/JSON到旗下遥测.
仅在全局时默认进行曝光记录 window 在建筑中存在。 在节点和
SSR 关闭,除非 enabled: true 通过。 DOM 测试环境,如 jsdom 和 幸福度
定义 window,所以通过 enabled: false 不得在接触后进行试验。 配置为
页:1 exposureLogging 构造器选项 :
const client = new FlagClient({
targetApp: 'jira-frontend',
environmentType: 'prod',
exposureLogging: {
enabled: true, // default: whether a global `window` exists
endpoint: 'https://xp.atlassian.com/ft/v1/logs', // default; or a same-origin path
batchSize: 100, // default: exposures that trigger an immediate delivery
flushIntervalMs: 10_000, // default: how long a queued exposure waits
},
});
失败的选项, 例如 batchSize: 0, (中文(简体) ), endpoint: 'relative/path',或一个 endpoint
带有用户名或密码的 URL 被忽略: 它的默认适用,客户端写一个
console.warn 命名选项,绝不是其值。 建筑从不扔. 残疾客户端确实如此
未检查 endpoint, (中文(简体) ), batchSize,或 flushIntervalMs 将一个配置传递给两个
浏览器和SSR客户端很安静.
什么样的暴露
service.name财务报告和审定财务报表feature_flag.set.id来自targetApp。 。 。 .deployment.environment_type财务报告和审定财务报表deployment.environment.name来自environmentType,以及service.version从serviceVersion。 。 。 .- 仪器范围名称和
atl.feature_flag.sdk.type为:@atlaskit/flag-client,则 范围版本是这个包的版本. - 识别器和属性来自持有的有效载荷
requestContext。当客户持有 没有有效载荷,它们来自当前用户,在失败后initialize用户通过 对它。 细节identifierValue总是来自当前用户. atl.feature_flag.result.source实值bootstrap当读取时,客户端持有 初始有效载荷,包括用于flag_not_found财务报告和审定财务报表type_mismatch,以及fallback改为: 成功前制作的initialize,即使当logExposure后回放时.- 错误原因( E)
not_initialized, (中文(简体) ),flag_not_found, (中文(简体) ),type_mismatch, (中文(简体) ),general_error,以及invalid_context)不带变体或规则,其错误消息从FFP evaluation failed: <reason>。 。 。 .general_error财务报告和审定财务报表invalid_context使用有效载荷errorMessage换成 当它不空虚的时候。 A 类not_initialized信件以原因结尾, 例如(no initialize attempt completed)或最近失败的原因. type_mismatch保留有效载荷旗的版本和目标应用.- 拒绝分配成为
atl.feature_flag.holdout_allocation.*属性holdoutKey, (中文(简体) ),identifierType,以及allocationReason是字符串,与holdout_rule_id仅限 用于字符串holdoutRuleId否则,所有四个都省略.
人工禁止和记录
过 { disableExposureLogging: true } 以跳过自动曝光。 记录一 稍后,
例如,当用户实际看到该特性时 logExposure数字 :
const details = client.getBooleanDetails('new-nav.enabled', false, {
disableExposureLogging: true,
});
// ...later, when the navigation is rendered:
client.logExposure(details);
详细信息,这个客户端 返回,包括浅拷贝, logExposure 记录曝光
读本会制作,标记手册,即使以后 initialize 或者说 replace详细情况
客户端没有返回, 如从 JSON 重建的客户端, 使用调用时的客户端状态 。 这个
当曝光记录被禁用时, 永不丢弃,也不做任何事情.
重复、交付和持久性
- 与队列相同的旗下密钥、变异、规则、匹配理由和标识符曝光
在最后的10分钟 被丢弃。 手动和自动曝光共用这些窗口。 A 类
已经成功
replace结束这一切. - 一个请求是一次飞来飞去的
credentials: 'omit'。网络错误,请求不 30秒内就解决了,429,以及5xx状态在 1 秒后重审, 然后是 2 秒数。 任何其他非2xx状态 :. - 每个客户端都有一个断路器. 在连续三次可重试失败之后,它打开:曝光 保留队列,每60秒发送一个批次,检查端点是否 已经康复了 无法重试的第一个响应关闭它,队列被冲出. 可重试 失败从不减少接触,但从第一次可重试失败一直到交付得到任何 其它结果,客户端只保留了1000个最新曝光的内存.
- 当页面被隐藏时,未交付的曝光被保存到
localStorage开始键下@atlaskit/flag-client:exposures:,每次曝光的队列在隐藏时也会如此。 这个 由同一来源构建的下一个客户端endpoint,以 保存它们的客户端已被配置 。 它一带他们就送他们去, 而不是之后flushIntervalMs除非断路器挡住他们 存储出错 永远不要扔. - 原产地的每个客户都分享
localStorage131,072个UTF-16编码单位的预算(256 KiB), 包含密钥,并且只保存符合其最近曝光的密钥。 彼等受记. 那边 对节省的风险没有单独的限制;只有预算才能决定. - 在成功交付后,客户记录时间
@atlaskit/flag-client:last-delivery最多一小时一次 交货失败时 过去7天没有记录到成功的源头,例如内容屏蔽器拒绝的源头 每个请求,预算是4,096个代码单元(8 KiB)取而代之.
同产和跨产
endpoint 也接受从单一开始的路径 /。客户端解决一次
建筑业 window.location.origin,所以一种产品,其来源路线与Flag相同
遥测完全避免了CORS,就像GASv3那样:
// Delivers to https://<product host>/gateway/api/ft/v1/logs
exposureLogging: { endpoint: '/gateway/api/ft/v1/logs' }
上面的路径是说明性的;使用您产品实际服务的路径. 路径被忽略
当启用客户端时警告 window,来源不透明,路径开始于
// 或者说 /\,或者它解决另一个来源.
没有路径,暴露于交叉来源处 https://xp.atlassian.com/ft/v1/logs 作为
application/json,这需要 CORS 预先飞行。 产品页面的交付取决于
那条航线会回答飞行前的问题.
发展
运行从 platform/ 目录 :
afm test unit packages/measurement/flag-client
afm ts check --project ./packages/measurement/flag-client/tsconfig.app.json
afm lint eslint packages/measurement/flag-client
共享测试向量在 src/__tests__/__fixtures__/ 由特性旗-平台销售
仓库 : bulk-evaluation-fixtures.json 从 sdks/evaluation-test-vectors,以及
exposure-test-vectors/ (只有JSON文件)来自 sdks/exposure-test-vectors。当
共享固定装置的改变.