Skip to content

feat(kit): extract the protocol into @padosoft/ecr17-kit and adopt @padosoft/native-modules - #24

Open
47PADO47 wants to merge 2 commits into
feat/windows-supportfrom
feat/ecr17-native-kits
Open

47PADO47 wants to merge 2 commits into
feat/windows-supportfrom
feat/ecr17-native-kits

Conversation

@47PADO47

@47PADO47 47PADO47 commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Stacked on #23 (feat/windows-support). Merge that first.

Summary

Splits the module into a native library and a React Native binding, so the protocol can be used by fully native apps (Windows C++, and later Swift/Kotlin, .NET) as well as by React Native.

kit/ — @padosoft/ecr17-kit (new)

A React-free C++20 library, namespace padosoft::ecr17, headers <Ecr17Kit/…>:

  • Protocol core: Lcr, PacketCodec, Ecr17Protocol, Ecr17Response, Ecr17Session and RetryPolicy. Moved unchanged apart from the namespace, plus its own LrcMode.
  • Ecr17Client: auto-connect, the pre-send liveness probe and the money-safe retry policy. This orchestration used to live in HybridEcr17Client, where nothing tested it except RetryPolicy.
  • WinsockTransport: the Winsock code from feat(windows): React Native Windows support (Nitro install DLL + Winsock transport) #23, now a plain C++ Transport with no Nitro. Its loopback tests no longer need Nitro or nitrogen.
  • Packaging:
    • CMake target Ecr17Kit::Ecr17Kit, installable with find_package support;
    • an Ecr17Kit pod (C++ sources, public <Ecr17Kit/…> headers);
    • an Expo config plugin (adds the pod; createNativeKitPlugin from @padosoft/expo);
    • a nativeKit.windows manifest, for the shared Nitro host in the next PR.

package/ — the binding, no protocol logic left

  • HybridEcr17Client maps the Nitro types onto the Kit's Ecr17Client. JS numbers go through toInt, so NaN or out-of-range values now throw instead of hitting undefined behaviour.
  • NativeTransportAdapter exposes the Ecr17Transport HybridObject as a Kit Transport.
  • On Windows, HybridEcr17TransportWindows wraps the Kit's WinsockTransport, keeping the dedicated connect thread.
  • @padosoft/native-modules:
    • Ecr17.podspec is a single nitro_module(…, kit: "Ecr17Kit") call;
    • android/build.gradle applies nitro-module.gradle, and android.packageName moves to react-native.config.js;
    • the Android CMake finds the Kit with Node, and the vcxproj finds it in node_modules or ../kit.

💰 Money safety

RetryPolicy is untouched. The new Client.AFinancialCommandIsNeverResentAfterADrop test replays every financial command against a drop with autoReconnect on. In each case, the command goes out once and the socket is restored.

Deliberately breaking shouldRetryAfterReconnect (dropping safeToRetry) fails two tests.

⚠️ Not published on npm yet

@padosoft/native-modules (1.5.0) and @padosoft/expo (1.11.0) are installed from the padosoft GitHub Packages registry, like @padosoft/config:

  • CI strips them where they aren't needed (scripts/strip-private-deps.mjs).
  • android-build keeps them, so the GESCAT_NPM_TOKEN secret must be able to read padosoft packages.
  • example-windows (npm) needs no registry config: npm resolves the dependencies of file:-linked packages from their own folder, which the root bun install fills.

@padosoft/ecr17-kit itself isn't published yet: changesets will publish it alongside the binding.

Changeset: minor

@padosoft/native-modules is a regular dependency of the binding and the Kit (it has no dependencies or peers), so apps get it automatically: no breaking change. The JS API is unchanged. On iOS, Expo apps add the Kit's config plugin (which uses @padosoft/expo, an optional peer of the Kit, because it peers on expo); bare apps list @padosoft/ecr17-kit as a direct dependency.

Verification

  • ✅ Kit tests: 100/100 on macOS with AddressSanitizer and UndefinedBehaviorSanitizer, including 15 new client tests (cmake -S kit, which is also what cpp-tests now runs).
  • ✅ iOS: the Expo example builds for the simulator, with no Ecr17/Ecr17Kit warnings:
    • expo prebuild -p ios: the Kit's plugin adds the pod;
    • pod install: nitro_module links Ecr17Kit through CocoaPods;
    • xcodebuild: BUILD SUCCEEDED.
  • ✅ The binding's C++ compiles on host clang with -Wall -Wextra, and TS typecheck passes.
  • ⏳ Not run here:
    • Android: the android-build job;
    • Windows (no toolchain here):
      • cmake -S kit -B build-win && cmake --build build-win --config Release && ctest --test-dir build-win -C Release;
      • the example-windows build and deploy;
    • a runtime smoke test against a terminal or fake terminal, on any platform.

The local Copilot review loop from AGENTS.md has not been run.

🤖 Generated with Claude Code

…adosoft/native-modules

- kit/ (@padosoft/ecr17-kit): the React-free C++20 core (namespace padosoft::ecr17,
  headers <Ecr17Kit/...>): LRC, framing, builders, parsers, the ACK/NAK session, and
  Ecr17Client, which now owns auto-connect, the pre-send liveness probe and the
  money-safe retry policy (moved out of HybridEcr17Client). On Windows it also builds
  WinsockTransport (moved from the Nitro transport). CMake target Ecr17Kit::Ecr17Kit,
  Ecr17Kit pod, Expo config plugin, nativeKit.windows manifest.
- Tests: the whole suite moved to kit/ (cmake -S kit). 15 new client tests, including
  one that replays every command against a drop: a financial command is never re-sent.
  The Winsock loopback tests no longer need Nitro.
- package/: HybridEcr17Client maps the Nitro types onto the Kit client;
  NativeTransportAdapter exposes the Ecr17Transport HybridObject as a Kit Transport;
  the Windows HybridObject wraps the Kit's WinsockTransport. Ecr17.podspec is one
  nitro_module(kit: "Ecr17Kit") call, android/build.gradle applies nitro-module.gradle;
  the Android CMake and the Windows vcxproj compile the Kit's sources.
- @padosoft/native-modules and @padosoft/expo come from GitHub Packages (not on npm
  yet); CI strips them where they are not needed.

Verified: kit tests 100/100 on macOS (ASan/UBSan); the Expo example builds for the iOS
simulator (prebuild, pod install, xcodebuild). Not verified: Android build, Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Deploying react-native-ecr17-protocol with  Cloudflare Pages  Cloudflare Pages

Latest commit: b280b77
Status: ✅  Deploy successful!
Preview URL: https://f37b5bbf.react-native-ecr17-protocol.pages.dev
Branch Preview URL: https://feat-ecr17-native-kits.react-native-ecr17-protocol.pages.dev

View logs

@padosoft/native-modules becomes a regular dependency of the binding and the Kit (it
has no dependencies or peers), so consumers get it with the package and the change
is not breaking: the changeset is minor. @padosoft/expo stays an optional peer of the
Kit (it peers on expo); the Expo example lists it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@47PADO47
47PADO47 added this pull request to stack #27 October 5, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant