From 62ea106de1b54af6f267cb2a96896ce1a9b2b046 Mon Sep 17 00:00:00 2001 From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com> Date: Mon, 17 Aug 2026 08:29:44 +0200 Subject: [PATCH 1/5] feat: add headless runtime bindings entrypoint --- src/bindings.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/bindings.ts diff --git a/src/bindings.ts b/src/bindings.ts new file mode 100644 index 0000000..a0a3b5b --- /dev/null +++ b/src/bindings.ts @@ -0,0 +1,23 @@ +export type { RuntimeApiOperationExecutorOptions } from './runtimeApiOperations'; +export { createRuntimeApiOperationExecutor } from './runtimeApiOperations'; +export type { RuntimeApiOperationSelection } from './runtimeApiSelection'; +export { validateRuntimeBindingOperationRef } from './runtimeApiSelection'; +export type { + RuntimeBindingOperationExecutionArgs, + RuntimeBindingOperationExecutionResult, + RuntimeBindingOperationExecutor, + RuntimeBindingOperationKey, + RuntimeBindingOperationResultCache, + RuntimeBindingOperationResultWriter, + RuntimeBindingResolutionArgs, + RuntimeBindingResolutionContext, + RuntimeBindingResolutionResult, +} from './runtimeBindings'; +export { + createRuntimeBindingOperationKey, + resolveBindingInputMap, + resolveRuntimeBindings, + resolveRuntimeBindingsAsync, + resolveRuntimeBindingValue, + resolveRuntimeBindingValueSync, +} from './runtimeBindings'; From c26a23d38de5978f74d08b769c69f0b33a4617f4 Mon Sep 17 00:00:00 2001 From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com> Date: Mon, 17 Aug 2026 08:30:00 +0200 Subject: [PATCH 2/5] feat: publish headless runtime bindings subpath --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 7059e06..e082cc6 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,10 @@ "types": "./dist/index.d.ts", "import": "./dist/index.js" }, + "./bindings": { + "types": "./dist/bindings.d.ts", + "import": "./dist/bindings.js" + }, "./package.json": "./package.json" }, "files": [ From 6387cc9cada9c42da59185ec2a1459b236426f5d Mon Sep 17 00:00:00 2001 From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com> Date: Mon, 17 Aug 2026 08:30:08 +0200 Subject: [PATCH 3/5] test: cover headless runtime bindings entrypoint --- src/bindings.test.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/bindings.test.ts diff --git a/src/bindings.test.ts b/src/bindings.test.ts new file mode 100644 index 0000000..53e49d9 --- /dev/null +++ b/src/bindings.test.ts @@ -0,0 +1,33 @@ +import { readFile } from 'node:fs/promises'; + +import { expect, test } from 'bun:test'; + +import { + createRuntimeApiOperationExecutor, + createRuntimeBindingOperationKey, + resolveRuntimeBindingValue, + validateRuntimeBindingOperationRef, +} from './bindings'; + +test('headless bindings entrypoint exposes canonical Runtime API helpers', () => { + expect(typeof createRuntimeApiOperationExecutor).toBe('function'); + expect(typeof createRuntimeBindingOperationKey).toBe('function'); + expect(typeof resolveRuntimeBindingValue).toBe('function'); + expect(typeof validateRuntimeBindingOperationRef).toBe('function'); +}); + +test('package exports headless bindings without renderer modules', async () => { + const packageJson = JSON.parse(await readFile('package.json', 'utf8')) as { + readonly exports?: Readonly>; + }; + const source = await readFile('src/bindings.ts', 'utf8'); + + expect(packageJson.exports?.['./bindings']).toEqual({ + types: './dist/bindings.d.ts', + import: './dist/bindings.js', + }); + expect(source).not.toContain('RuntimeRenderer'); + expect(source).not.toContain('RuntimeScreen'); + expect(source).not.toContain('react-native'); + expect(source).not.toContain("from 'react'"); +}); From 02c13891d473a4fe3488e5d2127ea93a15ed17de Mon Sep 17 00:00:00 2001 From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com> Date: Mon, 17 Aug 2026 08:30:19 +0200 Subject: [PATCH 4/5] chore: add headless bindings changeset --- .changeset/headless-runtime-bindings.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/headless-runtime-bindings.md diff --git a/.changeset/headless-runtime-bindings.md b/.changeset/headless-runtime-bindings.md new file mode 100644 index 0000000..f09cd89 --- /dev/null +++ b/.changeset/headless-runtime-bindings.md @@ -0,0 +1,5 @@ +--- +'@ankhorage/runtime': minor +--- + +Expose canonical API and binding execution through the package-neutral `@ankhorage/runtime/bindings` entrypoint so headless consumers do not load React Native renderer modules. From bd1a44070d8e78e6e6816b5b3c34124962fdee51 Mon Sep 17 00:00:00 2001 From: Fabio Gartenmann <137318798+artiphishle@users.noreply.github.com> Date: Mon, 17 Aug 2026 08:31:27 +0200 Subject: [PATCH 5/5] chore: register public Runtime entrypoints with Knip --- knip.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/knip.config.ts b/knip.config.ts index 24bd5a0..1a3ca91 100644 --- a/knip.config.ts +++ b/knip.config.ts @@ -1,6 +1,7 @@ import { createKnipConfig } from '@ankhorage/devtools/knip'; export default createKnipConfig({ + entry: ['src/index.ts', 'src/bindings.ts'], ignoreFiles: [ 'eslint.config.mjs', 'paradox.config.ts',