跳到主要内容

rxdb-devtools

RxDB 与浏览器 DevTools Extension 之间的开发期连接器。它通过当前页面的 window.postMessage 发送事件、数据库摘要、实体查询结果和分支操作结果。

只在开发环境启用​

这个包暴露了数据库检查、查询、分支变更和断开能力,禁止在生产构建中初始化。

if (import.meta.env.DEV && typeof window !== 'undefined') {
const { getDevToolsConnector } = await import('@aiao/rxdb-devtools');
getDevToolsConnector().init(rxdb, getEntityMetadata);
}

调用方负责确保生产 bundle 不执行 init()。enabled: false 可用于测试或显式关闭,但不能替代构建期的开发环境门禁。

生命周期​

  • getDevToolsConnector() 返回页面级 connector 单例。
  • init(rxdb, getEntityMetadata) 注册 RxDB 实例、读取实体 metadata、监听 RxDB 事件并发送 HANDSHAKE。
  • DevTools 返回 HANDSHAKE_ACK 后,connector 发送实时事件,并刷新握手前的内存事件缓冲区。
  • 对同一个 RxDB 对象重复 init() 是幂等操作,不会重复握手、读取 metadata 或注册监听。
  • 当前协议明确只支持一个 RxDB 实例。第二个不同实例会在读取其 metadata、修改映射或注册监听前抛错。
  • disconnect() 只断开 connector 通信、清理监听和缓冲区,不调用 rxdb.disconnectAll()。
  • DISCONNECT_RXDB 或 window.__AIAO_RXDB_DEVTOOLS__.disconnectRxdb() 会请求关闭 RxDB:
    • graceful:disconnectAll() 成功,随后清理实例和监听;
    • forced:graceful 失败,但本地 Worker 终止或 SharedWorker port 关闭成功,随后清理;
    • failed:关闭、超时或强制释放失败,保留实例、监听和全局 helper,允许重试;
    • not-connected:当前没有已注册实例。

SSR​

init() 和 disconnect() 在没有 window 的环境中是 no-op。仍建议把动态导入和初始化放在浏览器开发环境分支内,避免服务端无意义加载。

通信与威胁模型​

connector 只接受:

  • event.source === window;
  • event.origin 为空或等于当前页面 origin;
  • 完整且无额外字段的 message envelope;
  • 已知消息类型、合法方向和对应命令 payload。

这些检查用于拒绝 malformed 消息,不是身份认证。任何能在同一页面执行 JavaScript 的脚本,都可能构造一条完全合法的 window.postMessage 命令。把 token 放进同一个可观察、可重放的 postMessage 通道只会制造安全幻觉,因此本包不实现这种 token。

真正可信的 capability 需要 Extension 在隔离边界中建立不可由页面脚本伪造的通道;这涉及包外 Extension 协议,当前未实现。在此之前,只能把本包视为开发工具,并把页面上的第三方脚本视为同等可信。

危险命令​

  • DISCONNECT_RXDB:关闭当前 RxDB 实例;
  • QUERY_ENTITY:读取指定实体,limit 仅允许缺省或 1..1000 的安全整数;
  • SWITCH_BRANCH:切换分支;
  • CREATE_BRANCH:创建分支;
  • DELETE_BRANCH:删除分支。

malformed envelope 或 payload 会被静默拒绝,不会进入命令 handler,也不会把非法 limit 回退成默认值。

加密字段策略​

getEntityMetadata 返回的 encryptedPropertyMap 是唯一加密字段来源。connector 在初始化时建立字段映射,并执行以下规则:

  • QUERY_ENTITY 的结果中,metadata 声明的顶层字段始终替换为 [encrypted];
  • 事件 entities[].patch、entities[].inversePatch、entities[].data 使用同一遮罩规则;
  • 非敏感字段保持不变;
  • 只解释顶层字段名,不解析 profile.ssn 一类嵌套路径;嵌套对象中的同名字段不会被递归替换;
  • 不提供明文 opt-in,DevTools 永远不会通过本协议请求返回 metadata 声明字段的明文;
  • serializer 仍会遮罩符合已知加密 envelope 格式的字符串。

如果 metadata 漏报字段,connector 无法猜测其敏感性。实体 metadata 的正确性属于上游安全契约。

bigint / binary wire 表示​

QUERY_ENTITY、EVENT、history/change、conflict 和分支响应共用只读 serializer。该表示只服务 DevTools 通信与展示,不用于实体写回或 change 持久化:

type DevToolsBigIntValue = { $rxdb: 1; type: 'bigint'; value: string };
type DevToolsBinaryValue = {
$rxdb: 1;
type: 'binary';
encoding: 'base64url';
value: string;
byteLength: number;
};
  • bigint 使用精确十进制字符串;
  • binary 复制当前 Uint8Array 视图后编码为无 padding 的 base64url;
  • serializer 不修改实体、patch 或输入字节;
  • metadata 声明的加密字段先替换为 [encrypted],再进入 serializer,因此不会暴露明文或 binary 长度;
  • 面板只识别 $rxdb: 1 的合法已知 envelope,其他版本显示 unsupported,不会猜测解码。

Fileoverview​

RxDB DevTools 集成包 —— 页面侧连接器与 window.postMessage 线协议。

Remarks​

入口导出的是协议的完整表面:连接器 + 消息类型 + 类型守卫 + 消息工厂。 DevTools 扩展与本包共用这一套定义,任何一侧自己重写协议形状都会在版本漂移时 静默失配(一侧多一个字段,另一侧的 guard 把整条消息判非法却不报错)。 因此新增消息类型时,types.ts 与本文件必须一并更新。

Classes​

ClassDescription
DevToolsConnectorRxDB DevTools 连接器。
EventBuffer事件缓冲区 在 DevTools 断开连接时缓存事件,重连后 flush
SequenceGenerator序列号生成器类 生成单调递增的序列号,用于事件排序

Interfaces​

InterfaceDescription
BranchesMessage分支列表响应。
ClearMessage清除 DevTools 事件消息。
ConnectorDatabasePortsdatabase 领域的接入口;三项缺一不可。
ConnectorProviderPorts装配页内 provider 接缝的输入。
ConnectorProviderRegistry页内装配出来的 registry。
CreateBranchMessage创建分支命令。
DbInfoEntityDB_INFO 中单个实体的摘要。
DbInfoMessage数据库信息响应。
DbInfoPayload数据库信息响应载荷。
DeleteBranchMessage删除分支命令。
DevToolsAuthorizationInput一次操作授权的输入;三项配置全部来自本地,domain / operation 来自 wire。
DevToolsBigIntValue仅供 DevTools wire protocol 使用的精确 bigint 表示。
DevToolsBinaryValue仅供 DevTools wire protocol 使用的二进制表示。
DevToolsChunkSink分块传输的字节下沉口。
DevToolsChunkSource分块传输的字节来源;DevToolsChunkSink 的反向。
DevToolsClock协议时钟端口。
DevToolsConnectorEndpointconnector 侧 v2 端点。
DevToolsConnectorEndpointPorts端点的构造端口。
DevToolsConnectorNegotiationconnector 协商机。
DevToolsConnectorNegotiationPortsconnector 协商机的构造端口。
DevToolsConnectorTransportconnector 传输层的最小抽象。
DevToolsEntityMetadataDevTools 实际读取的实体元数据子集。
DevToolsErrorFramePayloadERROR 载荷;requestId 为 null 表示 session 级错误,无对应请求。
DevToolsErrorOptions创建错误 envelope 时的可选项。
DevToolsErrorPayload对外错误 envelope。
DevToolsEventPayloadEVENT 载荷。
DevToolsFilesProviderWithSource同时具备出站字节源与入站落盘口的 files provider。
DevToolsHandshakeCapabilitiesconnector 在 HANDSHAKE 中告知的能力面。
DevToolsInvalidDateValue仅供 DevTools wire protocol 使用的非法 Date 表示。
DevToolsMessage基础消息结构。
DevToolsNativeEntry一条原生目录项。
DevToolsNativeFilesProvider原生 files provider;在 DevToolsFilesProviderWithSource 之上多一个快照回收入口。
DevToolsNativeFilesProviderPorts原生 files provider 的构造端口。
DevToolsNativeFilesystemprovider 需要宿主提供的最小文件能力。
DevToolsNativeSnapshotPorts原生快照来源的构造端口。
DevToolsOpfsFilesProviderOPFS files provider;额外暴露与 transferId 绑定的 sink 工厂。
DevToolsOpfsFilesProviderPortsOPFS provider 的构造端口。
DevToolsOptionsRxDB DevTools 配置选项。
DevToolsPanelDownloadRequest一次下载调用的入参。
DevToolsPanelEndpointpanel 数据面客户端。
DevToolsPanelEndpointPortspanel 数据面客户端的构造端口。
DevToolsPanelNegotiationpanel 协商机。
DevToolsPanelNegotiationPortspanel 协商机的构造端口。
DevToolsPanelUploadRequest一次上传调用的入参。
DevToolsPanelUploadSource上传的字节来源。
DevToolsProtocolHelloPayloadPROTOCOL_HELLO 载荷。
DevToolsProvider一个领域的 provider 实现。
DevToolsProviderDescriptorprovider descriptor;每个领域最多一份。
DevToolsProviderLimitsprovider 声明的资源限制。
DevToolsProviderOptions页内 provider 装配中需要宿主显式注入的那一部分。
DevToolsProviderRegistry端点访问 provider 的全部接缝。
DevToolsRequestPayloadREQUEST 载荷;params 的领域形状由 provider 层校验,wire 层只保证键存在。
DevToolsResponsePayloadRESPONSE 载荷。
DevToolsRxdbDatabaseProviderdatabase provider;额外暴露订阅回收入口。
DevToolsRxdbDatabaseProviderPortsdatabase provider 的构造端口。
DevToolsSnapshotCursor分页游标;三个绑定条件(session、snapshot、页边界)里的后两个由它承载。
DevToolsSnapshotEntry快照的一条原始条目;side 由读取它的端口决定,不由条目自己声明。
DevToolsSnapshotLockstorage 全局独占锁。
DevToolsSnapshotPage一页快照记录。
DevToolsSnapshotPorts构造快照仓库所需的外部依赖。
DevToolsSnapshotSource快照的物化来源,由持有 storage 全局独占锁的一方实现。
DevToolsSnapshotStore一个 session 的快照仓库;同时最多持有一份活跃快照。
DevToolsTransferChunkPayloadTRANSFER_CHUNK 载荷。
DevToolsTransferIdPayloadTRANSFER_COMPLETE / TRANSFER_CANCEL 载荷。
DevToolsTransferStartPayloadTRANSFER_START 载荷。
DevToolsV2Envelope单一消息类型的 v2 envelope。
DevToolsV2EnvelopeShape外层校验通过、payload 尚未校验的 v2 消息形状。
DevToolsV2HandshakeAckPayloadv2 HANDSHAKE_ACK 载荷。
DevToolsV2HandshakePayloadv2 HANDSHAKE 载荷。
DevToolsV2MessageOptionscreateDevToolsV2Message 的固定字段。
DevToolsV2PayloadMap消息类型到载荷类型的映射。
DevToolsVersionManagerDevTools 实际调用的分支写操作子集。
DisconnectRxdbMessage请求断开 RxDB 实例。
DisconnectRxdbResultMessage断开 RxDB 实例的结果。
DisconnectRxdbResultPayload断开 RxDB 实例的结果载荷。
EntityDataMessage实体查询结果。
EntityDataPayload实体查询结果载荷。
EventMessage事件消息。
GetBranchesMessage获取分支列表命令。
HandshakeAckMessage握手确认消息。
HandshakeMessage握手消息。
HandshakePayload握手载荷:协议版本 + 本页授予的能力档。
InspectDbMessage数据库检查命令。
PingMessageDevTools 状态探测消息。
QueryEntityMessage实体查询命令。
QueryEntityPayload实体查询命令参数。
SerializedEvent序列化后的 RxDB 事件。
SwitchBranchMessage切换分支命令。

Type Aliases​

Type AliasDescription
AnyDevToolsMessage所有合法 RxDB DevTools 消息。
DevToolsAuthorization授权结论。
DevToolsCancelTimer取消一个已登记的定时任务。
DevToolsCapability页面授予 DevTools 的命令能力档位。
DevToolsCommandMessage所有允许进入页面命令处理器的消息。
DevToolsConnectorNegotiationMessageconnector 协商机会发出的消息:eager legacy 握手,或 v2 帧。
DevToolsConnectorNegotiationStateconnector 协商机的状态。
DevToolsControlPlaneErrorCode控制面错误码。
DevToolsEntityErrorCodeDEVTOOLS_ENTITY_ERROR_CODES 的联合类型。
DevToolsErrorCodev2 对外可见的全部错误码。
DevToolsErrorOrigin错误的来源平台。
DevToolsMutationPolicyowner 是否为写操作单独开口。
DevToolsOpfsEntry一条目录项;entries 只在目录上出现。
DevToolsPanelDownloadResult一次下载的结果。
DevToolsPanelNegotiationMessagepanel 协商机会发出的消息:v2 帧,或 v1 facade 里的 legacy ACK。
DevToolsPanelNegotiationStatepanel 协商机的状态。
DevToolsPanelRequestResult一次请求的结果;永不 reject——错误是值,调用方不需要 try/catch。
DevToolsPanelUploadResult一次上传的结果。
DevToolsProviderDomainprovider 领域。
DevToolsProviderErrorCodeprovider 数据面错误码。
DevToolsProviderKind领域到语义 kind 的映射。
DevToolsProviderOperation领域到操作名的映射。
DevToolsProviderResult一次 provider 调用的结果。
DevToolsProviderRuntimeprovider 运行时。
DevToolsRxDBDevTools 实际使用的 RxDB 能力子集。
DevToolsSnapshotCaptureResult一次快照物化的结果。
DevToolsSnapshotLockResult一次锁内任务的结果。
DevToolsSnapshotRecord快照的规范记录:[side, logicalPath, id, size, contentVersion]。
DevToolsSnapshotResult一次快照请求的结果。
DevToolsSnapshotSide一条快照记录来自元数据还是文件本体。
DevToolsUnavailableReasonprovider 不可用的原因。
DevToolsV2Directionv2 帧的传输方向。
DevToolsV2Message全部 v2 消息的判别联合。
DevToolsV2MessageTypev2 消息类型。
DevToolsWireValueDevTools wire protocol 支持的带版本非 JSON 值。
DisconnectMessage页面或 DevTools 发起的通信断开消息。
DisconnectStatusRxDB 断开结果状态。
GetEntityMetadataFn实体元数据读取函数。
MessageDirectionRxDB DevTools 消息方向。
MessageOfType按消息类型取出对应的消息定义。
MessageTypeRxDB DevTools 消息类型。

Variables​

VariableDescription
CONNECTOR_MUTATION_POLICY页内 connector 的默认写入开关。
DEVTOOLS_BROWSER_OPFS_MAX_TRANSFER_BYTES浏览器 OPFS 固定的 maxTransferBytes(50 MiB)。
DEVTOOLS_BROWSER_SETTINGS_DESCRIPTOR浏览器 settings provider 的 descriptor。
DEVTOOLS_CAPABILITIES全部 capability 档位,按权限从窄到宽。
DEVTOOLS_CONTROL_PLANE_ERROR_CODES控制面错误码(恰好 12 个)。
DEVTOOLS_DEFAULT_PAGE_SIZE分页默认页大小。
DEVTOOLS_ENTITY_ERROR_CODESENTITY_DATA 的结构化错误码。
DEVTOOLS_MAX_CHUNK_BYTES单个 chunk 解码后的最大字节数(256 KiB)。按解码后字节数计算,不是 base64 串长。
DEVTOOLS_MAX_ERROR_MESSAGE_LENGTH对外错误 message 的最大字符数。
DEVTOOLS_MAX_IDENTIFIER_LENGTHrequestId / transferId 的最大字符数。
DEVTOOLS_MAX_INFLIGHT_REQUESTS单 session 在途 request 上限。
DEVTOOLS_MAX_INFLIGHT_TRANSFERS单 session 在途 transfer 上限。
DEVTOOLS_MAX_PAGE_SIZE分页最大页大小。
DEVTOOLS_MAX_PROTOCOL_VERSION协议版本号上界。
DEVTOOLS_MAX_REQUEST_TOMBSTONES单 session 终态 request ID 墓碑上限。
DEVTOOLS_MAX_SNAPSHOT_BYTES单个 snapshot 的最大规范记录字节数(32 MiB);不计 transport envelope。
DEVTOOLS_MAX_SNAPSHOT_EPOCH_RETRIESsnapshot 因 capture epoch 变化而重试的最大次数。
DEVTOOLS_MAX_SNAPSHOT_RECORDS单个 snapshot 的最大记录条数;超过立即报错,不截断。
DEVTOOLS_MAX_SUPPORTED_VERSIONSPROTOCOL_HELLO.supportedVersions 的最大长度。
DEVTOOLS_MAX_TRANSFER_BYTES_LIMITmaxTransferBytes 的绝对上界(1 GiB)。
DEVTOOLS_MAX_TRANSFER_TOMBSTONES单 session 终态 transfer ID 墓碑上限。
DEVTOOLS_MESSAGE_REQUIRED_CAPABILITY每种消息类型所需的最低档位。
DEVTOOLS_MIN_CHUNK_BYTES单个 chunk 解码后的最小字节数;空 chunk 一律非法。
DEVTOOLS_MIN_PROTOCOL_VERSION协议版本号下界。
DEVTOOLS_NEGOTIATION_WINDOW_MS版本决策窗口,单位毫秒。
DEVTOOLS_OPERATION_REQUIRED_CAPABILITY每个操作所需的最低档位。
DEVTOOLS_PLATFORM_ERROR_KEYS本模块登记的全部平台错误码,按来源分组。
DEVTOOLS_PROTOCOL_VERSIONDevTools 页面协议版本,随不兼容的 envelope/载荷变更递增。
DEVTOOLS_PROTOCOL_VERSION_V2v2 协议版本号。
DEVTOOLS_PROVIDER_DOMAINSprovider 领域。
DEVTOOLS_PROVIDER_ERROR_CODESprovider 数据面错误码(恰好 18 个)。
DEVTOOLS_PROVIDER_ERROR_RETRYABLE每个 provider 错误码是否值得对端重试。
DEVTOOLS_PROVIDER_KINDS每个领域允许的语义 kind。
DEVTOOLS_PROVIDER_OPERATIONS每个领域可声明的操作,顺序即协议定义顺序。
DEVTOOLS_PROVIDER_RUNTIMESprovider 运行时;只用于显示,不得参与行为判定。
DEVTOOLS_REQUEST_TIMEOUT_MS非流式 request 的端到端时限,单位毫秒;从通过 guard 起算。
DEVTOOLS_SNAPSHOT_CURSOR_IDLE_MSsnapshot cursor 的无活动释放时限,单位毫秒。
DEVTOOLS_SNAPSHOT_TIMEOUT_MSsnapshot 端到端时限,单位毫秒;覆盖等锁、物化、epoch 重试与资源登记。
DEVTOOLS_TRANSFER_IDLE_TIMEOUT_MStransfer 的 idle 时限,单位毫秒。
DEVTOOLS_TRANSFER_TOTAL_TIMEOUT_MStransfer 的总时长上限,单位毫秒;从 START 通过 guard 起算。
DEVTOOLS_UNAVAILABLE_REASONSkind: 'unavailable' 时必须携带的共享 reason code。
DEVTOOLS_V2_MESSAGE_DIRECTIONS每种消息允许的方向;'both' 表示双向。
DEVTOOLS_V2_MESSAGE_TYPESv2 消息类型。
DEVTOOLS_WIRE_VERSIONDevTools wire value 契约版本。
RXDB_DEVTOOLS_MESSAGERxDB DevTools 消息来源标识符。
RXDB_EVENT_TYPES实际订阅的事件类型(RXDB_EVENT_SUBSCRIPTIONS 中值为 true 的键)。

Functions​

FunctionDescription
authorizeMessage判断一条消息类型在给定档位下是否可以收发。
authorizeOperation对一次操作请求做三层授权。
createConnectorNegotiation创建 connector 侧协商机。
createConnectorProviders按本页实际具备的能力装配 provider 接缝。
createDevToolsBrowserSettingsProvider建一个浏览器 settings provider。
createDevToolsConnectorEndpoint创建 connector 侧 v2 端点。
createDevToolsDesktopSettingsDescriptor桌面 settings provider 的 descriptor。
createDevToolsDesktopSettingsProvider建一个桌面 settings provider。
createDevToolsError创建对外错误 envelope。
createDevToolsNativeFilesProvider建一个原生文件后端的 files provider。
createDevToolsNativeSnapshotSource建一个原生宿主的快照物化来源。
createDevToolsOpfsFilesProvider建一个浏览器 OPFS 的 files provider。
createDevToolsPanelEndpoint创建 panel 侧数据面客户端。
createDevToolsReadOnlySettingsProvider用给定 descriptor 建一个只读 settings provider。
createDevToolsRxdbDatabaseProvider建一个 RxDB database provider。
createDevToolsSnapshotStore创建一个 session 级快照仓库。
createDevToolsV2Message构造一条 v2 消息。
createMessage创建 RxDB DevTools 消息。
createPanelNegotiation创建 panel 侧协商机。
createProviderError按共享的可重试性表构造一个 provider 错误。
createSessionId生成 canonical UUID v4 作为 sessionId。
createSystemClock基于宿主 Date.now / setTimeout 的真实时钟。
createWindowConnectorTransport浏览器实现:window 总线 + MessageChannel 私有端口。
decodeCanonicalBase64解码 RFC 4648 标准 base64,并要求输入是该字节序列的规范编码。
encodeCanonicalBase64把字节序列编码为 RFC 4648 标准 base64(带规范 padding)。
getDevToolsConnector获取或创建全局 RxDB DevTools 连接器。
isCanonicalUuidV4判断值是否为 canonical(小写、带连字符)UUID v4。
isControlPlaneErrorCode判断值是否为控制面错误码。
isDevToolsCapability判断值是否为合法的 capability 档位。
isDevToolsCommandMessage判断合法消息是否为允许进入页面处理器的命令。
isDevToolsErrorPayload判断值是否为合法的对外错误 envelope。
isDevToolsIdentifier判断值是否为合法的 requestId / transferId。
isDevToolsMessage严格校验消息 envelope、方向、已知类型和命令 payload。
isDevToolsProviderDescriptor判断值是否为合法的 provider descriptor。
isDevToolsProviderDescriptorSet判断值是否为合法的 descriptor 集合:每个领域最多一份。
isDevToolsProviderDomain判断值是否为已知的 provider 领域。
isDevToolsV2Envelope宽外层 guard:判断值是否为一条 v2 消息的外壳,不校验 payload。
isDevToolsV2Message严内层 guard:判断值是否为一条完全合法的 v2 消息。
isMaxTransferBytes判断值是否为合法的 maxTransferBytes(0~1 GiB 的非负 safe integer)。
isMutatingOperation判断一个操作是否会改变持久状态。
isPageSize判断值是否为合法的 pageSize(1~500)。
isProviderErrorCode判断值是否为 provider 错误码。
isRedactedErrorMessage判断值是否为符合脱敏要求的错误说明。
isSupportedVersionList判断值是否为合法的 PROTOCOL_HELLO.supportedVersions。
isValidPathSegment判断一个路径段是否合法。
isWithinTransferLimit判断声明的总字节数是否在协商上限之内。
joinLogicalPath把已校验的段拼回逻辑路径。
mapPlatformError把一个平台异常映射成 provider 错误载荷。
parseLogicalPath把 wire 上的路径切成已校验的段。
resetDevToolsConnector重置全局 RxDB DevTools 连接器。
resolveBrowserOpfsRoot探测本页是否具备 OPFS。
resolveNegotiatedTransferLimit协商出实际生效的 transfer 上限。
satisfiesCapability判断实际档位是否达到所需档位。
saveFileThroughPage用页面自己的下载路径保存一个文件。
serialize序列化 RxDB 事件
serializeDevToolsValue将运行时值转换为脱离原对象且 JSON 安全的 DevTools wire 值。
snapshotRecordBytes一条规范记录的字节数。
splitLogicalPath把路径拆成「父目录段 + 末段」。
totalSnapshotBytes一批规范记录的字节总量。