diff --git a/.changeset/tidy-runtime-rn-peer.md b/.changeset/tidy-runtime-rn-peer.md new file mode 100644 index 0000000..f1594ec --- /dev/null +++ b/.changeset/tidy-runtime-rn-peer.md @@ -0,0 +1,5 @@ +--- +'@ankhorage/runtime': patch +--- + +Support the React Native 0.86 patch line as a peer while validating the package against the canonical React Native 0.86.3 application baseline. diff --git a/README.md b/README.md index 5958155..71fba57 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # @ankhorage/runtime -![license: MIT](./paradox/badges/license.svg) ![npm: v2.1.0](./paradox/badges/npm.svg) ![runtime: bun](./paradox/badges/runtime.svg) ![typescript: strict](./paradox/badges/typescript.svg) ![eslint: checked](./paradox/badges/eslint.svg) ![prettier: checked](./paradox/badges/prettier.svg) ![build: checked](./paradox/badges/build.svg) ![tests: checked](./paradox/badges/tests.svg) ![docs: paradox](./paradox/badges/docs.svg) +![license: MIT](./paradox/badges/license.svg) ![npm: v2.2.0](./paradox/badges/npm.svg) ![runtime: bun](./paradox/badges/runtime.svg) ![typescript: strict](./paradox/badges/typescript.svg) ![eslint: checked](./paradox/badges/eslint.svg) ![prettier: checked](./paradox/badges/prettier.svg) ![build: checked](./paradox/badges/build.svg) ![tests: checked](./paradox/badges/tests.svg) ![docs: paradox](./paradox/badges/docs.svg) Platform-neutral runtime contracts and helpers for Ankhorage generated apps. diff --git a/bun.lock b/bun.lock index e8a5f96..822f420 100644 --- a/bun.lock +++ b/bun.lock @@ -18,13 +18,13 @@ "@types/react-dom": "^19.2.4", "react": "19.2.3", "react-dom": "19.2.3", - "react-native": "0.86.2", + "react-native": "0.86.3", "react-native-web": "~0.21.0", "typescript": "~6.0.3", }, "peerDependencies": { "react": "19.2.3", - "react-native": "0.86.2", + "react-native": "0.86.x", "react-native-web": "~0.21.0", }, "optionalPeers": [ @@ -261,25 +261,25 @@ "@pkgr/core": ["@pkgr/core@0.3.6", "", {}, "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA=="], - "@react-native/assets-registry": ["@react-native/assets-registry@0.86.2", "", {}, "sha512-vcX/mBjWAVnWofu7KecotquI2unZ/tITwA7OGdq/mdY/zmGXIEvYhfEYyOQij/LRqi9WAL+iizInTBWnxDhK/Q=="], + "@react-native/assets-registry": ["@react-native/assets-registry@0.86.3", "", {}, "sha512-TDhgCZA4wjJg84d5A9swiOQYPIWSKEEVdg9IwMFZDupQzW/F3QoLUrfAJOcalgqTDA9/buTB8awhE3Whwg6u9Q=="], - "@react-native/codegen": ["@react-native/codegen@0.86.2", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.29.0", "hermes-parser": "0.36.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "tinyglobby": "^0.2.15", "yargs": "^17.6.2" } }, "sha512-xKkudsahUJ1n//55g4fXk5BStVqqmZlz8HQveL45ZxcfDnwvhuYe2GymksQANFsSN+slvrarjrfq8kIxJzbceA=="], + "@react-native/codegen": ["@react-native/codegen@0.86.3", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.29.0", "hermes-parser": "0.36.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "tinyglobby": "^0.2.15", "yargs": "^17.6.2" } }, "sha512-Ux4jHi0fh+bdtVEcL0gaPLbY56V+SvFUDl/8sRAE1jdb4k+o7fT/4Nc29yz4X+qfjstkSqObQTMBGhdzxH9JvA=="], - "@react-native/community-cli-plugin": ["@react-native/community-cli-plugin@0.86.2", "", { "dependencies": { "@react-native/dev-middleware": "0.86.2", "debug": "^4.4.0", "invariant": "^2.2.4", "metro": "^0.84.3", "metro-config": "^0.84.3", "metro-core": "^0.84.3", "semver": "^7.1.3" }, "peerDependencies": { "@react-native-community/cli": "*", "@react-native/metro-config": "0.86.2" }, "optionalPeers": ["@react-native-community/cli", "@react-native/metro-config"] }, "sha512-YHXNKoM6Y/HjREySZ5arET2xgiHgg67r1MdwJB//MPJAJ0Xc5g0u6UHxY9VzsHO3Y07dre6s0BinYwjt1SEWvQ=="], + "@react-native/community-cli-plugin": ["@react-native/community-cli-plugin@0.86.3", "", { "dependencies": { "@react-native/dev-middleware": "0.86.3", "debug": "^4.4.0", "invariant": "^2.2.4", "metro": "^0.84.3", "metro-config": "^0.84.3", "metro-core": "^0.84.3", "semver": "^7.1.3" }, "peerDependencies": { "@react-native-community/cli": "*", "@react-native/metro-config": "0.86.3" }, "optionalPeers": ["@react-native-community/cli", "@react-native/metro-config"] }, "sha512-qSDL9LQc5mZSZPNczT95WU9YQuPzxBklgON9vLhhqfI0yWIwKInqFx88dQ/uiEXBtf0yossthaQIqA4Ml6bF6g=="], - "@react-native/debugger-frontend": ["@react-native/debugger-frontend@0.86.2", "", {}, "sha512-KGS1aV5F6cIqpnoIUhLBXyVzy1oAj8jBFGau6vX4Vy0HXRJN7p+68RU7x6NuyraHvQcR14ccMGT5TkFuNjQ4gA=="], + "@react-native/debugger-frontend": ["@react-native/debugger-frontend@0.86.3", "", {}, "sha512-TQmeofQ0PcuylhhlleOeuzHYZfbrgm3gayXzowqUEzgRisTm1D40/J3ggqs7XkQi5HP5ZA3n8dHmKL9vIzPcsw=="], - "@react-native/debugger-shell": ["@react-native/debugger-shell@0.86.2", "", { "dependencies": { "cross-spawn": "^7.0.6", "debug": "^4.4.0", "fb-dotslash": "0.5.8" } }, "sha512-/TaVJ2+gGajZPJGrFaObUQmHmlaxAlfmOPZicl6pNKDUjzSgFMpcLkdTOExvb+USYTVdGX1XwxXyvjQdUO2bvg=="], + "@react-native/debugger-shell": ["@react-native/debugger-shell@0.86.3", "", { "dependencies": { "cross-spawn": "^7.0.6", "debug": "^4.4.0", "fb-dotslash": "0.5.8" } }, "sha512-O4ds+J7xZfxkbih9T+cAGegBdvKSPKYJm/lDgC9CpEjFMkmzWTpVLU3Qsv9sqZuo58z+sGhIcJfPsCFFWHpqbQ=="], - "@react-native/dev-middleware": ["@react-native/dev-middleware@0.86.2", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.86.2", "@react-native/debugger-shell": "0.86.2", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.3.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^7.5.10" } }, "sha512-B7L0vKvg+IcEElT7Vpqh1xj5yJAqWUegjbP+bQRaorJMAYnv11GkliTnZV2AdTDfZQJWgOEx8i8LGkHkUg7bnA=="], + "@react-native/dev-middleware": ["@react-native/dev-middleware@0.86.3", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.86.3", "@react-native/debugger-shell": "0.86.3", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.3.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^7.5.10" } }, "sha512-LiEPTqTg/63bYUnrPyHLfjTDCNhA/+CUqI1+DsA9tYyewtSbULd5awsva6SgE10I+2iMhgKXS3ymkhU/kSCrGA=="], - "@react-native/gradle-plugin": ["@react-native/gradle-plugin@0.86.2", "", {}, "sha512-2F6x14NcHMpVmfTTFKfMkpV5dZedZrLiv6PE+c3vgnesV2bjleUBydr4U+NI8VkI7OwW71L0A5qQ76I9LCrfoQ=="], + "@react-native/gradle-plugin": ["@react-native/gradle-plugin@0.86.3", "", {}, "sha512-lxmx0GqLEWRIpZfpYFXlYVIs3ENQwaW6Vmp6oi29l2GoQJ1wZfFZRdMimDWlGEk8LKfHar3QH3iaPMkTcK9lEQ=="], - "@react-native/js-polyfills": ["@react-native/js-polyfills@0.86.2", "", {}, "sha512-bIwNcGBaQ74shB5z1mRkxOpjikimuwsnOCEkZSzL67Z1FTyK1ObpENfyd2QvcvVW9Cjl+tHuw9ynpBnb2jPoJQ=="], + "@react-native/js-polyfills": ["@react-native/js-polyfills@0.86.3", "", {}, "sha512-eYIJ0es967+tePBFQDnl/gidVFxLns3fnbiK6rxscQrGodvuUO6hwxpQnfNynJ8MjbbndImXihXjcnJdc7SzJg=="], - "@react-native/normalize-colors": ["@react-native/normalize-colors@0.86.2", "", {}, "sha512-EzPFc9Y6lzYOWeso2almwXI7f8+qReHxWvT+algsOczb2UhWXIWXDoSvkdwoSfiwwmGt/ijJgKJoeHlzPkLwRg=="], + "@react-native/normalize-colors": ["@react-native/normalize-colors@0.86.3", "", {}, "sha512-Cv3CDkprb67GrzuaS9BGbBJC/6G4lIw3nyKOHRKTqTTum4bn37y5+R0Z04L8mcbQN85eEohNrRwb7IOM4j6uvg=="], - "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.86.2", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.2.0", "react": "*", "react-native": "0.86.2" }, "optionalPeers": ["@types/react"] }, "sha512-uO0J72gh3EvE+1/GHRk18QRyBDTRHRB0AraAfojsRjbT7VMuJwKrZYaKGshavoaEud6aw00ZB9/8mTMIKjjcAw=="], + "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.86.3", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.2.0", "react": "*", "react-native": "0.86.3" }, "optionalPeers": ["@types/react"] }, "sha512-1j44NEyNn05Ut40vHAmoSWbsIcybFkMAOBTwQt1PrESyfSS+qBoyU1LGIogNva0VIa0rQyEC5PzbA7R4/7Nhyw=="], "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], @@ -651,7 +651,7 @@ "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], - "hermes-compiler": ["hermes-compiler@250829098.0.16", "", {}, "sha512-xsgzk+mUyvt9t1nUbF8USBlYxajTUtPJhVZ86q85s/SEoMKCF+52YZcudb0ENSnV3T3lV9mgB3s6R7+pH90zgw=="], + "hermes-compiler": ["hermes-compiler@250829098.0.17", "", {}, "sha512-qG1PXzTEtriF6oQLZF3vyHhSMxOdW5h2TqqLri0rdpstPustd2fSvRZQMVAPdlhgFwBfYnj3OUZtiO6LjYsEFw=="], "hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="], @@ -967,7 +967,7 @@ "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], - "react-native": ["react-native@0.86.2", "", { "dependencies": { "@react-native/assets-registry": "0.86.2", "@react-native/codegen": "0.86.2", "@react-native/community-cli-plugin": "0.86.2", "@react-native/gradle-plugin": "0.86.2", "@react-native/js-polyfills": "0.86.2", "@react-native/normalize-colors": "0.86.2", "@react-native/virtualized-lists": "0.86.2", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", "babel-plugin-syntax-hermes-parser": "0.36.0", "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", "hermes-compiler": "250829098.0.16", "invariant": "^2.2.4", "memoize-one": "^5.0.0", "metro-runtime": "^0.84.3", "metro-source-map": "^0.84.3", "nullthrows": "^1.1.1", "pretty-format": "^29.7.0", "promise": "^8.3.0", "react-devtools-core": "^6.1.5", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", "scheduler": "0.27.0", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "tinyglobby": "^0.2.15", "whatwg-fetch": "^3.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "peerDependencies": { "@react-native/jest-preset": "0.86.2", "@types/react": "^19.1.1", "react": "^19.2.3" }, "optionalPeers": ["@react-native/jest-preset", "@types/react"], "bin": { "react-native": "cli.js" } }, "sha512-zbJXGZpwfZGA79Z9ob6Atvfx4nAQL8yJBa35s58E4Oo+khPykfQP2sTeumkKbjwajFYfVayg8pj7Il9nIfTk7A=="], + "react-native": ["react-native@0.86.3", "", { "dependencies": { "@react-native/assets-registry": "0.86.3", "@react-native/codegen": "0.86.3", "@react-native/community-cli-plugin": "0.86.3", "@react-native/gradle-plugin": "0.86.3", "@react-native/js-polyfills": "0.86.3", "@react-native/normalize-colors": "0.86.3", "@react-native/virtualized-lists": "0.86.3", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", "babel-plugin-syntax-hermes-parser": "0.36.0", "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", "hermes-compiler": "250829098.0.17", "invariant": "^2.2.4", "memoize-one": "^5.0.0", "metro-runtime": "^0.84.3", "metro-source-map": "^0.84.3", "nullthrows": "^1.1.1", "pretty-format": "^29.7.0", "promise": "^8.3.0", "react-devtools-core": "^6.1.5", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", "scheduler": "0.27.0", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "tinyglobby": "^0.2.15", "whatwg-fetch": "^3.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "peerDependencies": { "@react-native/jest-preset": "0.86.3", "@types/react": "^19.1.1", "react": "^19.2.3" }, "optionalPeers": ["@react-native/jest-preset", "@types/react"], "bin": { "react-native": "cli.js" } }, "sha512-JR5s3bM9ezud+Mw24GlNXNfthqPIKwrQgPPJcam+L97t2sKjjEavhCzBn+fyqZZRcM5+XlhYxpTxVkK7e1n38Q=="], "react-native-web": ["react-native-web@0.21.2", "", { "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", "fbjs": "^3.0.4", "inline-style-prefixer": "^7.0.1", "memoize-one": "^6.0.0", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", "styleq": "^0.1.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg=="], diff --git a/docs/react-native-0.86-migration-audit.md b/docs/react-native-0.86-migration-audit.md index de7a5a9..24d78c3 100644 --- a/docs/react-native-0.86-migration-audit.md +++ b/docs/react-native-0.86-migration-audit.md @@ -4,7 +4,7 @@ This audit covers `@ankhorage/runtime` ownership for roadmap step `[expo 2]`. Ru ## Target baseline -- **CHANGE REQUIRED — consumer and validation baseline.** Exact React and React Native peer/development versions move from React 19.1.0 and RN 0.81.5 to React 19.2.3 and RN 0.86.2. React Native Web is an optional `~0.21.0` peer and a 0.21.2 development dependency. TypeScript validation moves from 5.9 to 6.0.3. +- **CHANGE REQUIRED — consumer and validation baseline.** React remains exactly 19.2.3. Runtime intentionally supports the RN `0.86.x` patch line because it owns no native ABI, while development and validation are pinned to the canonical RN 0.86.3 app baseline. React Native Web is an optional `~0.21.0` peer and a 0.21.2 development dependency. TypeScript validation remains on 6.0.3. - **CHANGE REQUIRED — tooling baseline.** Devtools moves to 1.6.0, Bun remains on the Devtools-owned 1.3.14 policy, repository Node execution declares 24.x, and Node typings move from 25.x to 24.13.3. - **VERIFIED: NO CHANGE REQUIRED — internal package releases.** The current published direct Ankhorage releases remain `@ankhorage/contracts` 8.0.0, `@ankhorage/data-sources` 2.0.0, and `@ankhorage/paradox` 0.1.21. No cross-repository compatibility blocker was found. @@ -21,7 +21,7 @@ This audit covers `@ankhorage/runtime` ownership for roadmap step `[expo 2]`. Ru ## Required audit areas - **VERIFIED: NO CHANGE REQUIRED — removed and deprecated APIs.** Active implementation has no `StyleSheet.absoluteFillObject`, React Native Jest preset, deprecated accessibility focus call, networking interceptor, `ViewUtil`, `AppRegistry` instrumentation hook, legacy bridge API, or removed native/C++ symbol usage. The only React Native imports are `StyleSheet`, `Text`, and `View` for the unknown-component fallback. -- **CHANGE REQUIRED — TypeScript types.** The repository compiles with TypeScript 6.0.3, `@types/react` 19.2.18, RN 0.86.2 declarations, Bun 1.3.14 typings, and Node 24.13.3 typings. Strict settings remain enabled and no suppression or migration compatibility type was added. +- **CHANGE REQUIRED — TypeScript types.** The repository compiles with TypeScript 6.0.3, `@types/react` 19.2.18, RN 0.86.3 declarations, Bun 1.3.14 typings, and Node 24.13.3 typings. Strict settings remain enabled and no suppression or migration compatibility type was added. - **VERIFIED: NO CHANGE REQUIRED — Fabric and New Architecture behavior.** Components are injected as `React.ElementType`; Runtime has no native component registration, TurboModule, bridge, codegen, architecture flag, or legacy renderer branch. - **VERIFIED: NO CHANGE REQUIRED — layout and measurement assumptions.** Runtime forwards manifest props/styles and renders an ordinary error fallback. It does not inspect coordinates, call `measure`/`measureInWindow`, manage safe areas, or depend on edge-to-edge viewport dimensions. - **VERIFIED: NO CHANGE REQUIRED — refs and imperative handles.** Runtime exposes no component ref contract or imperative handle. RN 0.82 DOM-like native refs therefore do not alter the public surface. @@ -45,4 +45,4 @@ React's [library compiler guidance](https://react.dev/reference/react-compiler/c The migration is covered by the repository test suite, explicit React 19.2 context tests, package-isolation/baseline assertions, TypeScript 6 compilation, the React Compiler health check, and the issue-required repository/release gates. The Web compatibility test bundles the real Runtime renderer with `react-native` resolved to RNW 0.21.2 and server-renders injected `View`/`Text` registry entries. The package-isolation test rejects Expo, Expo modules, and `@ankhorage/expo-runtime` in implementation source and all dependency sections. -No owner-first follow-up or external release blocker was discovered in this step. +The RN 0.86 patch peer is the Runtime-owned part of the owner-first graph required by Studio roadmap step `[expo 11]`. Applications remain responsible for selecting one exact RN patch, and Runtime validation proves the current canonical 0.86.3 selection. diff --git a/package.json b/package.json index b68745f..4d22519 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ }, "peerDependencies": { "react": "19.2.3", - "react-native": "0.86.2", + "react-native": "0.86.x", "react-native-web": "~0.21.0" }, "peerDependenciesMeta": { @@ -90,7 +90,7 @@ "@types/react-dom": "^19.2.4", "react": "19.2.3", "react-dom": "19.2.3", - "react-native": "0.86.2", + "react-native": "0.86.3", "react-native-web": "~0.21.0", "typescript": "~6.0.3" }, diff --git a/paradox/badges/npm.svg b/paradox/badges/npm.svg index 1dbf9ac..fd0ade5 100644 --- a/paradox/badges/npm.svg +++ b/paradox/badges/npm.svg @@ -1,7 +1,7 @@ - -npm: v2.1.0 + +npm: v2.2.0 npm -v2.1.0 +v2.2.0 diff --git a/paradox/paradox.json b/paradox/paradox.json index 2fe871b..3f64553 100644 --- a/paradox/paradox.json +++ b/paradox/paradox.json @@ -12,7 +12,7 @@ { "id": "npm", "label": "npm", - "value": "v2.1.0", + "value": "v2.2.0", "color": "cb3837" }, { diff --git a/src/runtimePackageIsolation.test.ts b/src/runtimePackageIsolation.test.ts index 77812a7..e7546c7 100644 --- a/src/runtimePackageIsolation.test.ts +++ b/src/runtimePackageIsolation.test.ts @@ -91,13 +91,13 @@ describe('@ankhorage/runtime platform baseline', () => { expect(packageJson.peerDependencies).toMatchObject({ react: '19.2.3', - 'react-native': '0.86.2', + 'react-native': '0.86.x', 'react-native-web': '~0.21.0', }); expect(packageJson.peerDependenciesMeta?.['react-native-web']?.optional).toBe(true); expect(packageJson.devDependencies).toMatchObject({ react: '19.2.3', - 'react-native': '0.86.2', + 'react-native': '0.86.3', 'react-native-web': '~0.21.0', typescript: '~6.0.3', });