Skip to content

Commit 44494df

Browse files
committed
feat(agents-core): add React Native support with platform-specific shims
1 parent bedc491 commit 44494df

File tree

3 files changed

+2054
-70
lines changed

3 files changed

+2054
-70
lines changed

packages/agents-core/package.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
"types": "./dist/shims/shims-node.d.ts",
7070
"default": "./dist/shims/shims-node.mjs"
7171
},
72+
"react-native": {
73+
"require": "./dist/shims/shims-react-native.js",
74+
"types": "./dist/shims/shims-react-native.d.ts",
75+
"default": "./dist/shims/shims-react-native.mjs"
76+
},
7277
"require": {
7378
"types": "./dist/shims/shims-node.d.ts",
7479
"default": "./dist/shims/shims-node.js"
@@ -89,8 +94,12 @@
8994
},
9095
"dependencies": {
9196
"@openai/zod": "npm:zod@^3.25.40",
97+
"@ungap/structured-clone": "^1.3.0",
9298
"debug": "^4.4.0",
93-
"openai": "^5.0.1"
99+
"event-target-shim": "^6.0.2",
100+
"events": "^3.3.0",
101+
"openai": "^5.0.1",
102+
"react-native-uuid": "^2.0.3"
94103
},
95104
"peerDependencies": {
96105
"zod": "^3.25.40"
@@ -121,6 +130,7 @@
121130
},
122131
"devDependencies": {
123132
"@types/debug": "^4.1.12",
133+
"@types/ungap__structured-clone": "^1.2.0",
124134
"zod": "^3.25.40"
125135
},
126136
"files": [
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/// <reference lib="dom" />
2+
export { EventEmitter, EventEmitterEvents } from './interface';
3+
import type { EventEmitterEvents, Timeout, Timer } from './interface';
4+
5+
import { EventEmitter as NodeEventEmitter } from 'events';
6+
import 'event-target-shim';
7+
import structuredClone from '@ungap/structured-clone';
8+
import uuid from 'react-native-uuid';
9+
10+
if (!('structuredClone' in globalThis)) {
11+
// @ts-expect-error - This is the recommended approach from ungap/structured-clone
12+
globalThis.structuredClone = structuredClone;
13+
}
14+
export const randomUUID = (): string => uuid.v4();
15+
16+
export function loadEnv(): Record<string, string | undefined> {
17+
return {};
18+
}
19+
20+
export class ReactNativeEventEmitter<
21+
Events extends EventEmitterEvents = Record<string, any[]>,
22+
> extends NodeEventEmitter {
23+
override on<K extends keyof Events & (string | symbol)>(
24+
type: K,
25+
listener: (...args: Events[K]) => void,
26+
): this {
27+
// Node's typings accept string | symbol; cast is safe.
28+
return super.on(type as string | symbol, listener);
29+
}
30+
31+
override off<K extends keyof Events & (string | symbol)>(
32+
type: K,
33+
listener: (...args: Events[K]) => void,
34+
): this {
35+
return super.off(type as string | symbol, listener);
36+
}
37+
38+
override emit<K extends keyof Events & (string | symbol)>(
39+
type: K,
40+
...args: Events[K]
41+
): boolean {
42+
return super.emit(type as string | symbol, ...args);
43+
}
44+
45+
override once<K extends keyof Events & (string | symbol)>(
46+
type: K,
47+
listener: (...args: Events[K]) => void,
48+
): this {
49+
return super.once(type as string | symbol, listener);
50+
}
51+
}
52+
53+
export { ReactNativeEventEmitter as RuntimeEventEmitter };
54+
55+
// Streams – placeholders (unused by the SDK on RN)
56+
export const Readable = class {};
57+
export const ReadableStream = globalThis.ReadableStream;
58+
export const ReadableStreamController =
59+
globalThis.ReadableStreamDefaultController;
60+
export const TransformStream = globalThis.TransformStream;
61+
62+
export class AsyncLocalStorage {
63+
#ctx: unknown = null;
64+
65+
run<T>(store: T, fn: () => unknown) {
66+
this.#ctx = store;
67+
return fn();
68+
}
69+
getStore<T>() {
70+
return this.#ctx as T;
71+
}
72+
enterWith<T>(store: T) {
73+
this.#ctx = store;
74+
}
75+
}
76+
77+
export function isBrowserEnvironment(): boolean {
78+
return true;
79+
}
80+
81+
export function isTracingLoopRunningByDefault(): boolean {
82+
return false;
83+
}
84+
85+
/* MCP not supported on mobile; export browser stubs */
86+
export { MCPServerStdio, MCPServerStreamableHttp } from './mcp-server/browser';
87+
88+
class RNTimer implements Timer {
89+
setTimeout(cb: () => void, ms: number): Timeout {
90+
const id: any = setTimeout(cb, ms);
91+
// RN timers don’t expose ref/unref; shim them
92+
id.ref ??= () => id;
93+
id.unref ??= () => id;
94+
id.hasRef ??= () => true;
95+
id.refresh ??= () => id;
96+
return id;
97+
}
98+
99+
clearTimeout(id: Timeout | string | number | undefined) {
100+
clearTimeout(id as number);
101+
}
102+
}
103+
104+
const timer = new RNTimer();
105+
export { timer };

0 commit comments

Comments
 (0)