收口移动运行时桥接边界
将 Expo host.getRuntime 回包组装收口到 runtime 模块 让移动 dispatch 只委托运行时请求 同步移动壳结构门禁、架构文档和共享记忆
This commit is contained in:
@@ -42,6 +42,8 @@ const notificationsPath = new URL('../src/host-bridge/notifications.ts', import.
|
||||
const notificationsSource = fs.readFileSync(notificationsPath, 'utf8');
|
||||
const protocolPath = new URL('../src/host-bridge/protocol.ts', import.meta.url);
|
||||
const protocolSource = fs.readFileSync(protocolPath, 'utf8');
|
||||
const hostBridgeRuntimePath = new URL('../src/host-bridge/runtime.ts', import.meta.url);
|
||||
const hostBridgeRuntimeSource = fs.readFileSync(hostBridgeRuntimePath, 'utf8');
|
||||
const sharePath = new URL('../src/host-bridge/share.ts', import.meta.url);
|
||||
const shareSource = fs.readFileSync(sharePath, 'utf8');
|
||||
const bridgeDirPath = new URL('../src/host-bridge/', import.meta.url);
|
||||
@@ -107,6 +109,7 @@ const requiredMobileShellSourceModules = [
|
||||
'host-bridge/network.ts',
|
||||
'host-bridge/notifications.ts',
|
||||
'host-bridge/protocol.ts',
|
||||
'host-bridge/runtime.ts',
|
||||
'host-bridge/scanner.ts',
|
||||
'host-bridge/share.ts',
|
||||
'shell/QrScannerOverlay.tsx',
|
||||
@@ -1771,26 +1774,35 @@ if (!shellAppSource.includes('hostVersion: MOBILE_SHELL_HOST_VERSION')) {
|
||||
throw new Error('mobile shell URL must use the shared mobile shell host version');
|
||||
}
|
||||
|
||||
if (!dispatchSource.includes('hostVersion: MOBILE_SHELL_HOST_VERSION')) {
|
||||
if (!hostBridgeRuntimeSource.includes('hostVersion: MOBILE_SHELL_HOST_VERSION')) {
|
||||
throw new Error('mobile shell runtime response must use the shared mobile shell host version');
|
||||
}
|
||||
|
||||
for (const runtimeSnippet of [
|
||||
'function getMobileRuntimePlatform()',
|
||||
'export function getMobileRuntimePlatform()',
|
||||
"return Platform.OS === 'ios' ? 'ios' : 'android'",
|
||||
'function getRuntime()',
|
||||
'export function getMobileHostBridgeRuntime(): HostBridgeRuntimeResult',
|
||||
'const platform = getMobileRuntimePlatform();',
|
||||
'platform,',
|
||||
'capabilities: resolveMobileHostCapabilities(platform)',
|
||||
"case 'host.getRuntime':",
|
||||
'return ok(request, getRuntime());',
|
||||
]) {
|
||||
if (!dispatchSource.includes(runtimeSnippet)) {
|
||||
if (!hostBridgeRuntimeSource.includes(runtimeSnippet)) {
|
||||
throw new Error(`mobile shell runtime response missing ${runtimeSnippet}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (dispatchSource.includes('capabilities: resolveMobileHostCapabilities(),')) {
|
||||
if (
|
||||
!dispatchSource.includes('getMobileHostBridgeRuntime()') ||
|
||||
dispatchSource.includes('MOBILE_SHELL_HOST_VERSION') ||
|
||||
dispatchSource.includes('HOST_BRIDGE_VERSION') ||
|
||||
dispatchSource.includes('resolveMobileHostCapabilities(') ||
|
||||
dispatchSource.includes('getMobileRuntimePlatform') ||
|
||||
dispatchSource.includes("shell: 'expo_mobile'")
|
||||
) {
|
||||
throw new Error('mobile shell dispatch must delegate host.getRuntime to runtime.ts');
|
||||
}
|
||||
|
||||
if (hostBridgeRuntimeSource.includes('capabilities: resolveMobileHostCapabilities(),')) {
|
||||
throw new Error(
|
||||
'mobile shell runtime capabilities must use the same normalized platform reported in host.getRuntime',
|
||||
);
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import * as Linking from 'expo-linking';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
import {
|
||||
HOST_BRIDGE_VERSION,
|
||||
type HostBridgeRequest,
|
||||
} from '../../../../packages/shared/src/contracts/hostBridge';
|
||||
import { MOBILE_SHELL_HOST_VERSION } from '../shell/runtime';
|
||||
import { resolveMobileHostCapabilities } from './capabilities';
|
||||
import { type HostBridgeRequest } from '../../../../packages/shared/src/contracts/hostBridge';
|
||||
import {
|
||||
captureImageFile,
|
||||
exportAudioFile,
|
||||
@@ -43,6 +37,7 @@ import {
|
||||
reloadMobileHostBridgeWebView,
|
||||
} from './navigation';
|
||||
import { getMobileHostBridgeNetworkStatus } from './network';
|
||||
import { getMobileHostBridgeRuntime } from './runtime';
|
||||
|
||||
let navigation: MobileHostBridgeNavigation | null = null;
|
||||
|
||||
@@ -52,27 +47,12 @@ export function configureMobileHostBridgeNavigation(
|
||||
navigation = nextNavigation;
|
||||
}
|
||||
|
||||
function getMobileRuntimePlatform() {
|
||||
return Platform.OS === 'ios' ? 'ios' : 'android';
|
||||
}
|
||||
|
||||
function getRuntime() {
|
||||
const platform = getMobileRuntimePlatform();
|
||||
return {
|
||||
shell: 'expo_mobile',
|
||||
platform,
|
||||
hostVersion: MOBILE_SHELL_HOST_VERSION,
|
||||
bridgeVersion: HOST_BRIDGE_VERSION,
|
||||
capabilities: resolveMobileHostCapabilities(platform),
|
||||
};
|
||||
}
|
||||
|
||||
export async function dispatchMobileHostBridgeRequest(
|
||||
request: HostBridgeRequest,
|
||||
) {
|
||||
switch (request.method) {
|
||||
case 'host.getRuntime':
|
||||
return ok(request, getRuntime());
|
||||
return ok(request, getMobileHostBridgeRuntime());
|
||||
case 'appearance.getColorScheme':
|
||||
return ok(request, getMobileAppearanceColorScheme());
|
||||
case 'app.openExternalUrl':
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
import {
|
||||
HOST_BRIDGE_VERSION,
|
||||
type HostBridgeRuntimeResult,
|
||||
} from '../../../../packages/shared/src/contracts/hostBridge';
|
||||
import { MOBILE_SHELL_HOST_VERSION } from '../shell/runtime';
|
||||
import { resolveMobileHostCapabilities } from './capabilities';
|
||||
|
||||
export function getMobileRuntimePlatform() {
|
||||
return Platform.OS === 'ios' ? 'ios' : 'android';
|
||||
}
|
||||
|
||||
export function getMobileHostBridgeRuntime(): HostBridgeRuntimeResult {
|
||||
const platform = getMobileRuntimePlatform();
|
||||
return {
|
||||
shell: 'expo_mobile',
|
||||
platform,
|
||||
hostVersion: MOBILE_SHELL_HOST_VERSION,
|
||||
bridgeVersion: HOST_BRIDGE_VERSION,
|
||||
capabilities: resolveMobileHostCapabilities(platform),
|
||||
};
|
||||
}
|
||||
@@ -76,6 +76,7 @@
|
||||
- 2026-06-18 移动壳默认入口:Expo 壳默认 H5 地址固定为 `https://app.genarrative.world/`,开发联调本机 Vite 必须显式设置 `EXPO_PUBLIC_GENARRATIVE_WEB_URL=http://127.0.0.1:3000/`、`http://localhost:3000/` 或 `http://[::1]:3000/`;生产包不得在未配置环境变量时加载设备本机 localhost,也不得通过环境变量把第三方外域 H5 放入带完整 HostBridge 的 WebView。
|
||||
- 2026-06-18 移动壳安装包身份:Expo 移动壳的 iOS bundle identifier 与 Android package 统一固定为 `world.genarrative.mobile`,应用版本固定为 `0.1.0`,iOS `buildNumber` 从字符串 `"1"` 起步,Android `versionCode` 从整数 `1` 起步;后续分发安装包时递增构建号 / versionCode,产品版本号按发布节奏调整。移动壳配置检查会校验 `app.json` 与 `package.json` 版本一致,并拒绝缺失或漂移的包标识,当前不写入假商店元数据、假更新端点或占位渠道 SDK 配置。
|
||||
- 2026-06-19 移动壳 HostBridge 版本运行时来源:Expo 移动壳的 H5 入口 query 和 `host.getRuntime` 回包都读取 `MOBILE_SHELL_HOST_VERSION`,该值必须从移动壳 `app.json` 的 Expo `version` 配置解析,异常配置只回退到与 `app.json` / `package.json` 一致的受检 fallback;配置检查会拒绝 `App.tsx`、`bridge.ts` 或 `runtime.ts` 重新散落硬编码版本,避免安装包版本升级时 H5 首屏上下文与 runtime 回读分叉。
|
||||
- 2026-06-19 移动壳 runtime 桥接边界:Expo `host.getRuntime` 的平台归一、hostVersion、bridgeVersion 和 capability 清单组装统一收口在 `apps/mobile-shell/src/host-bridge/runtime.ts`;`dispatch.ts` 只负责把 `host.getRuntime` 委托给 `getMobileHostBridgeRuntime()`。移动壳配置检查会拒绝分发层重新读取 `MOBILE_SHELL_HOST_VERSION`、`HOST_BRIDGE_VERSION`、`resolveMobileHostCapabilities(...)` 或 `Platform.OS`,避免入口 URL、runtime 回包和能力清单继续分叉。
|
||||
- 2026-06-18 移动壳发布通道边界:Expo 移动壳默认显式关闭 OTA 更新,只允许 `updates.enabled=false`;在真实发布通道、更新端点、签名 / 回滚策略和团队发布流程落地前,不得配置 `runtimeVersion`、release channel、EAS channel、`expo-updates` 插件或移动端 crash / analytics / CodePush 依赖。移动壳配置检查和 Expo public config smoke 会拒绝这些发布通道能力被提前打开,根 `package-lock.json` 也不得解析 `expo-updates`、Sentry、Firebase Analytics、PostHog、Amplitude、Segment、CodePush 等真实发布 / 观测 SDK。
|
||||
- 2026-06-18 移动壳观测与渠道 SDK 初始化边界:移动壳生产入口、HostBridge、启动 URL 和 runtime 配置不得提前初始化 Sentry、Firebase Analytics、PostHog、Amplitude、Segment、CodePush 或 Expo Updates;这些 SDK 必须等真实发布通道、采集字段、用户授权、隐私披露、签名 / 回滚策略和团队发布流程落地后逐项接入。配置检查会同时拒绝相关依赖、锁文件解析、Expo 配置和源码初始化片段;`expo-application` 可能由 Expo 自身传递解析,但项目不得主动 direct 依赖它实现渠道逻辑。
|
||||
- 2026-06-18 桌面图片拖入接入主图槽位:`CreativeImageInputPanel` 在桌面壳声明 `file.imageDropped` 时订阅宿主拖入事件,只在拖入坐标命中当前主图卡片且未被上层元素遮挡时消费事件,避免窗口级拖入被多个创作面板同时接收;成功后仍转换为现有 `File` 上传回调。
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -262,6 +262,7 @@ const expectedMobileHostBridgeFiles = [
|
||||
'network.ts',
|
||||
'notifications.ts',
|
||||
'protocol.ts',
|
||||
'runtime.ts',
|
||||
'scanner.ts',
|
||||
'share.ts',
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user