# STEP-064 RN 纯 Field Renderer 接口 V2 — Codex 任务 v1 ## 0. 任务定位 本任务把 `@navsea/maplibre-particle-rn` 从当前开发期的 Weather/Wind 导向 RN API,整理为正式宿主可使用的**纯 Field Renderer RN SDK**。 目标 RN 包版本: ```text 13.4.1-particle.2 ``` 本任务不是粒子算法升级,不是 WeatherV2 功能扩展,也不是 Native/Core 重构。 核心原则只有一条: > React/宿主负责业务、数据获取、provider、数据类型和显示策略;Particle RN SDK 只接收 canonical Field 并控制 MapLibre Native 图场与粒子渲染。 当前除了 Test App 没有正式消费者,因此本任务**不承担旧 RN 公共 API 兼容责任**,允许直接删除旧接口并同步修改测试宿主。 ## 1. 仓库与当前基线 仓库: ```text /mnt/sda1/MapLibreParticleLab ``` 分支: ```text particle/main ``` 任务书编写时源码基线: ```text f31c0ea1571aa3429ec170fbf38bdecf45c847ae ``` 开始执行时必须重新确认 `git status --short`、当前分支、`HEAD` 与 `origin/particle/main`。若远端已合法推进,先阅读新增提交,不得 reset 或覆盖。 当前工作树存在与本任务无关的 modified/untracked 文件。禁止 `git add .`、`git add -A`,禁止恢复、删除、覆盖或提交这些无关文件。 ## 2. 执行前必须阅读 至少阅读以下实际文件: ```text AGENTS.md PARTICLE_BASELINE.md docs/00_项目规范/01_Codex协作规范_v1.md docs/00_项目规范/02_构建与验证规范_v1.md docs/00_项目规范/03_Step阶段记录规范_v1.md docs/00_项目规范/05_粒子架构原则_v1.md packages/maplibre-particle-rn/package.json packages/maplibre-particle-rn/src/index.ts packages/maplibre-particle-rn/src/types.ts packages/maplibre-particle-rn/src/NativeWeatherRuntimeBridge.ts packages/maplibre-particle-rn/src/weatherV2/* packages/maplibre-particle-rn/app.plugin.js integration/react-native/MapLibreParticlePackageConsumerTestHost/* release/maplibre-particle/release-manifest.json docs/30_设计/MapLibre粒子ReactNative使用说明_v2.md ``` 实现必须依据当前实际源码,不得根据任务书示例猜接口或目录。 ## 3. 冻结的架构边界 ### 3.1 SDK 不理解业务 `@navsea/maplibre-particle-rn` 的正式 RN 公共接口不得出现或要求调用方传入以下业务含义: ```text WeatherV2 ECMWF wind wave rain tide weather layer dataset manifest time_index HTTP URL/provider/cache/retry Route / ETA NavSea 业务状态 ``` 这些全部属于 React/宿主层。 ### 3.2 数据只有一份 同一份 canonical Field 进入 Runtime 一次。图场 Renderer 与 Particle Renderer 是对同一 Field 的两种独立显示方式,不建立两套 Field 数据、不要求重复提交。 逻辑必须保持: ```text Canonical Field ├─ Field Renderer ON / OFF └─ Particle Renderer ON / OFF ``` 宿主可以任意组合两个 Renderer 的显示状态。SDK 不根据业务类型自动决定是否显示粒子。 ### 3.3 本任务不改变 canonical / Native 技术 本任务保持当前已验证 Native/Core 能力: ```text maplibre-particle-field/v1 metadataJson + local file payload float32-le / interleaved-uv Timeline / T0-T1 Runtime Field Window GPU 时间插值 WeatherColorLayer RasterParticleLayer Particle State / Trail Playback / target FPS ``` 不得为了 RN 命名整理修改 C++、shader、JNI、Java/Kotlin WeatherRuntime、MapLibre Native renderer 或 Android AAR 内容。 ## 4. 必做项 A:建立最终 RN 公共 API 新增纯渲染公共入口,建议名称: ```ts FieldRuntime ``` 正式调用方应从包根入口使用它。目标公开方法至少包括: ```text attach() detach() getState() clearFields() submitField() setEnabled() setFieldVisible() setParticleVisible() setTargetFps() setTargetTime() setPlaybackState() setPlaybackSpeed() setFieldColorStops() setParticleColor() setTrailColor() setParticleCount() setParticleLineWidth() setParticleLength() setParticleOpacity() setTrailOpacity() setTrailFade() setFieldOpacity() ``` 这些方法可以在 RN/TS 层薄映射到当前已验证的 Native bridge 方法,不得因此修改 Native 方法名。 公共 API 中不得继续暴露以下旧名称: ```text WeatherRuntime submitWindField clearWindFields setWeatherEnabled setWeatherColorVisible setWeatherColorStops setWeatherColorOpacity setForecastTime ``` 当前内部 `NativeWeatherRuntimeBridge.ts`、TurboModule 名 `WeatherRuntimeBridge`、Native 生成类名等若属于既有 Native ABI/Codegen 接缝,可作为本任务内部实现细节保留;但不得从包根入口继续暴露,也不得要求宿主使用这些名字。 由于没有正式消费者,不建立 deprecated alias,不增加 compatibility wrapper,不同时维护两套公共 API。 ## 5. 必做项 B:公共类型去业务化 将面向宿主的类型改为纯 Field Renderer 语义。 例如当前 `ColorStop.speedMps` 不应继续作为最终 RN 公共命名;建议公开为: ```ts type FieldColorStop = Readonly<{ value: number; red: number; green: number; blue: number; alpha: number; }>; ``` RN 内部可把 `value` 薄转换成当前 Native bridge 所需字段,不修改 Native/Core。 以下现有类型可在确认无业务耦合后继续使用或适当重命名: ```text RuntimeState PlaybackState TargetFps CommandResult FieldSubmitResult RuntimeSnapshot ``` 不得新增: ```text WeatherLayer WindLayer RainLayer WaveLayer TideLayer ProviderType DatasetType ``` `submitField()` 仍只负责把当前 canonical metadata 与本地 binary payload 交给既有 Native ingress。RN SDK 不解析业务类型,也不根据 field 内容决定 Renderer 组合。 当前 canonical metadata 中若存在 Native/Core 已冻结的历史字段名,本任务不为追求命名纯净而修改其 schema;RN 层只把它视为 Native 数据契约,不增加业务解释。 ## 6. 必做项 C:WeatherV2 完全移出正式 package 当前 package 根入口存在: ```ts export * from "./weatherV2"; ``` 且 `packages/maplibre-particle-rn/src/weatherV2/` 内包含 HTTP、manifest、time index、WVECBIN1 decoder 和高层 loader。 这些全部属于宿主业务/数据适配,不属于纯 Renderer SDK。 必须: 1. 从正式 package 根导出删除 WeatherV2 API; 2. 从正式 package 源码中移除 `src/weatherV2/`; 3. 不在 package 内留下其他 provider/network/weather helper 替代品; 4. Consumer Test Host 若仍要验证真实 WeatherV2,可以把必要 WeatherV2 逻辑放到 Test Host 自己的 `src/` 中; 5. Test Host 的业务代码最终只把 canonical Field 交给 `FieldRuntime.submitField()`。 禁止新增诸如 `loadWeatherV2IntoRuntime()`、`loadLayer()`、`WeatherFieldType` 等换名后的业务包装。 ## 7. 必做项 D:MapLibre RN 与 Style Helper 收口 正式 package 不再把自己伪装成完整 MapLibre RN facade。 包根入口应停止: ```ts export * from "@maplibre/maplibre-react-native"; ``` 宿主继续直接安装并使用固定 peer dependency: ```text @maplibre/maplibre-react-native@11.3.6 ``` 宿主地图组件从官方包导入;粒子/图场 Runtime 从 `@navsea/maplibre-particle-rn` 导入。必须确认这不会引入第二份 MLRN native module。 删除业务化的 `particleWeatherIds`、`createParticleWeatherStyle()` 公共命名。建议提供纯渲染命名: ```text particleFieldIds createParticleFieldStyleFragment() ``` Style helper 只能返回/描述 Particle 所需 source + Field layer + Particle layer,不得内置 GSI、WeatherV2 或任何业务底图。 当前 Native attach 依赖的内部 style ID 若仍是: ```text rn-weather-fields rn-weather-color rn-weather-particles ``` 本任务不得为了字符串改名进入 Native/Core。允许 `particleFieldIds` 暂时映射这些既有内部 ID;README 必须要求宿主使用导出的常量/helper,不要自行硬编码这些历史字符串。 ## 8. 必做项 E:RN import 在无 Native module 平台安全 当前 `NativeWeatherRuntimeBridge.ts` 使用 `TurboModuleRegistry.getEnforcing()`,会让不具备 `WeatherRuntimeBridge` 的平台在 import 阶段直接失败。 本任务只在 RN/TS 层解决: - 包根入口被 import 时,不得因为 Native module 缺失立即 throw; - `FieldRuntime` 真正执行 Native 方法时,若 bridge 不存在,应以清楚、稳定的错误失败; - 不为此新增 iOS Native 实现; - 不修改 Android Native bridge ABI; - 不允许静默返回伪 `ACCEPTED` 或伪 Runtime state。 具体实现应依据 RN 0.85.2 TurboModule API 做最小改动。 ## 9. 必做项 F:版本关系必须真实 RN package 版本升级为: ```text @navsea/maplibre-particle-rn@13.4.1-particle.2 ``` 但本任务不修改 Native,因此 Android Native artifact 继续使用当前已验证版本: ```text cc.navsea.maplibre:android-sdk-particle-opengl:13.4.1-particle.1 ``` 不得仅为了数字一致而复制、重编或发布内容相同的 `.2` AAR。 `app.plugin.js` 的 dependency substitution 必须继续解析到 Native `.1` AAR,除非实际调查发现当前正式 AAR 坐标已经合法变化。 更新 release manifest,使其明确区分: ```text RN package version = 13.4.1-particle.2 Native artifact version = 13.4.1-particle.1 ``` 并注明 `.2` 是 RN-only public API revision,Native/Core source 与已验证 `.1` AAR 不变。 不得覆盖或重新上传现有: ```text navsea-maplibre-particle-rn-13.4.1-particle.1.tgz ``` 本任务只生成新的 `.2` 本地 pack 产物供后续验证,不负责正式静态 HTTPS 上传或 release tag。 ## 10. 必做项 G:Consumer Test Host 同步到最终 API 修改: ```text integration/react-native/MapLibreParticlePackageConsumerTestHost/ ``` 要求: - `Map` / `Camera` 改为直接从 `@maplibre/maplibre-react-native` 导入; - Renderer Runtime 只从 `@navsea/maplibre-particle-rn` 导入 `FieldRuntime` 和纯渲染类型/helper; - 本地真实 WeatherV2 测试能力可以继续存在,但 WeatherV2 HTTP、decoder、选帧、临时文件管理全部位于 Test Host 自己的业务目录; - 最终提交给 SDK 的仍是 canonical metadata + local binary file; - Test Host 不得反向依赖 package 内部源码路径; - Test Host UI 可以继续使用 Weather/ECMWF 文案,因为它是测试宿主,不是 SDK 公共接口。 旧 `MapLibreParticleRNTestHost` 属于历史 bridge 验证宿主,不要求为了本任务全部重构;除非它参与当前 package 构建/类型检查并形成 blocker,否则不要扩大范围。 ## 11. 必做项 H:文档更新 保留现有: ```text docs/30_设计/MapLibre粒子ReactNative使用说明_v2.md ``` 作为 `.1` 历史接口说明,不覆盖。 新增: ```text docs/30_设计/MapLibre粒子ReactNative使用说明_v3.md ``` v3 必须以 `13.4.1-particle.2` 最终真实代码为准,说明: - 安装 `.2` RN package 与 MLRN 11.3.6; - RN `.2` 对应 Native AAR `.1`; - Map/Camera 从官方 MLRN 导入; - `FieldRuntime` 全部公共方法、参数和返回值; - canonical Field submission; - 图场与粒子独立显示开关; - Style fragment 如何合入宿主现有 style; - React/宿主负责业务数据,SDK 不负责 provider/network/weather。 同步更新: ```text packages/maplibre-particle-rn/README.md packages/maplibre-particle-rn/CHANGELOG.md packages/maplibre-particle-rn/package.json ``` README 不得继续推荐 WeatherV2 高层 loader,也不得把 SDK 描述成天气客户端。 CHANGELOG 必须明确 `.2`: ```text - RN 公共接口去 Weather/Wind 业务化 - WeatherV2 helper 移出正式 package - 图场与粒子继续消费同一 canonical Field,并可独立开关 - Native/Core/GPU 未修改 - 继续复用 Android AAR 13.4.1-particle.1 ``` ## 12. 明确禁止范围 本任务禁止修改: ```text include/mbgl/** src/mbgl/** platform/android/MapLibreAndroid/** shaders/** CMake / Core renderer Android AAR 内容与 publication 源码 NavSea 仓库 ``` 若实现纯 RN API 时发现必须修改以上任一 Native/Core 文件,立即停止扩大修改,在完成报告中写明 blocker 和原因。 ## 13. 静态与包验证 Codex 必须完成以下非 Android 验证: ```text 1. package TypeScript typecheck 2. Consumer Test Host TypeScript typecheck 3. npm pack 4. tarball 内容审计 5. package 根导出审计 6. 业务语义残留审计 7. git diff --check ``` `npm pack` 生成的新 `.2` tgz 不提交 Git,除非仓库当前发布规则明确要求;不得碰现有未跟踪 `.1` tgz。 包内容必须确认不存在: ```text src/weatherV2/ WeatherV2HttpClient loadWeatherV2WindIntoRuntime decodeWeatherV2WindFrame NavSea 业务源码 Test Host node_modules 临时日志/构建缓存 ``` 允许内部保留 Native ABI 接缝中的 `WeatherRuntimeBridge` 名称和现有 `rn-weather-*` style ID,但这些不得作为新的业务 API 暴露。 ## 14. Android 验证边界 本任务不得执行 Android Gradle、AAR build/publish、APK build/install、ADB 或设备操作。 因为 Native AAR 不变,本任务完成后优先采用既有包含 `.1` Native bridge/AAR 的 Consumer APK,通过 Metro 验证新的 `.2` JS/TS API;只有后续确认 Native 文件或 Android 构建配置实际发生变化时,才需要用户重新编译 APK。 Codex 最终必须给出用户后续最小验证步骤,但不得自行执行 Android 操作。 ## 15. Step、开发记录与完成报告 执行完成后新增/更新: ```text docs/50_Step记录/STEP-064_RN纯FieldRenderer接口V2_v1.md docs/报告/STEP-064_RN纯FieldRenderer接口V2_Codex完成报告_v1.md 粒子开发记录.md ``` Step 状态在未完成人工 Consumer 验证前写为: ```text 进行中(代码完成,待 Consumer 验证) ``` 完成报告可使用: ```text IMPLEMENTED / WAITING_CONSUMER_VALIDATION ``` 不得提前写 RELEASED、CLOSED / PASS 或 Android validated。 ## 16. Git 收尾 完成代码、文档和静态验证后,必须只精确 stage 本任务文件并提交,随后 push: ```text origin/particle/main ``` 禁止把当前已有无关 modified/untracked 文件带入提交。 建议代码提交信息: ```text refactor: make RN particle API field-renderer only ``` 如文档单独提交,建议: ```text docs: record STEP-064 RN field renderer API v2 ``` Push 后必须确认: ```text HEAD == origin/particle/main ``` Push 失败不得声称任务完成。 ## 17. 最终必做清单 - [ ] 确认 `particle/main`、HEAD、远端 HEAD 与工作树 - [ ] 阅读任务要求与当前 `.1` 实际 package/Consumer 源码 - [ ] RN package version 升为 `13.4.1-particle.2` - [ ] 建立 `FieldRuntime` 纯渲染公共入口 - [ ] 公共 API 删除 Weather/Wind 专用名称 - [ ] 不建立旧 API 兼容 wrapper - [ ] `submitField()` / `clearFields()` 继续薄映射既有 Native ingress - [ ] 图场与粒子保持同一 Field、独立显示开关 - [ ] `FieldColorStop.value` 等公共类型去业务化 - [ ] `WeatherV2` 完全移出正式 package - [ ] package 不再 re-export 整个 MLRN - [ ] Style helper 改为纯 Particle Field fragment,不内置业务底图 - [ ] 无 Native module 平台 import package 不立即崩溃 - [ ] Consumer Test Host 改用最终 `.2` API - [ ] WeatherV2 测试逻辑如需保留,仅存在于 Test Host 业务层 - [ ] Native/Core/JNI/shader/AAR 无功能修改 - [ ] Android AAR 继续为 `13.4.1-particle.1` - [ ] release manifest 明确 RN `.2` ↔ Native `.1` - [ ] README、CHANGELOG、React Native 使用说明 v3 更新 - [ ] package/Consumer TypeScript 检查通过 - [ ] `.2` `npm pack` 与 tarball 内容审计通过 - [ ] `git diff --check` 通过 - [ ] 更新 STEP-064、完成报告、粒子开发记录 - [ ] 精确 commit 并 push `origin/particle/main` - [ ] 最终报告 commit hash、message、push result、Final HEAD Codex 不需要在开工前提交实施计划。结束时直接按本清单逐项报告“已完成 / 未完成 / 无法验证”,任何未完成项必须说明原因,不得静默跳过。