Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ function HostApp() {
<View>
<Button onPress={sendMessageToSandbox} title="Send to Sandbox" />
<SandboxReactNativeView ref={sandboxRef}
moduleName={"ModuleName"} // The name of your JS module
jsBundleSource={"sandbox"} // The JS bundle: file name or URL
componentName={"SandboxApp"} // The name of your JS component from jsBundleSource
onMessage={handleMessage}
onError={handleError}
/>
Expand All @@ -108,7 +108,7 @@ function HostApp() {
import React, { useState, useEffect, useCallback } from 'react';
import { View, Button, Text } from 'react-native';

// No import required API available through global
// No import required, API available through global
declare global {
var postMessage: (message: object) => void;
var setOnMessage: (handler: (payload: object) => void) => void;
Expand Down
4 changes: 2 additions & 2 deletions apps/demo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const SideBySideDemo: React.FC = () => {
<Text style={styles.header}>Sandboxed</Text>
<SandboxReactNativeView
style={styles.sandboxView}
jsBundleSource={'sandbox'}
moduleName={'CrashIfYouCanDemo'}
jsBundleSource={'sandbox'} // bundle name for query from metro
componentName={'SandboxedDemo'} // componentName from sandbox.js
onError={error => {
const message = `Got ${error.isFatal ? 'fatal' : 'non-fatal'} error from sandbox`
console.warn(message, error)
Expand Down
3 changes: 2 additions & 1 deletion apps/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start"
"start": "react-native start",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "19.1.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/demo/sandbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import CrashIfYouCanDemo from './CrashIfYouCanDemo'

LogBox.uninstall()

AppRegistry.registerComponent('CrashIfYouCanDemo', () => CrashIfYouCanDemo)
AppRegistry.registerComponent('SandboxedDemo', () => CrashIfYouCanDemo)
8 changes: 4 additions & 4 deletions apps/fs-experiment/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ function App(): React.JSX.Element {
styles.sandbox,
{backgroundColor: theme.background, borderColor: theme.border},
]}
moduleName={'AppFS'}
jsBundleSource="sandbox-fs"
componentName={'AppFS'} // componentName from sandbox-fs.js
jsBundleSource="sandbox-fs" // bundle name for query from metro
allowedTurboModules={['RNFSManager', 'FileReaderModule']}
onMessage={message => {
console.log('Host received message from sandbox:', message)
Expand Down Expand Up @@ -207,9 +207,9 @@ function App(): React.JSX.Element {
styles.sandbox,
{backgroundColor: theme.background, borderColor: theme.border},
]}
moduleName={'AppFileAccess'}
componentName={'AppFileAccess'} // componentName from sandbox-file-access.js
allowedTurboModules={['FileAccess']}
jsBundleSource="sandbox-file-access"
jsBundleSource="sandbox-file-access" // bundle name for query from metro
onMessage={message => {
console.log('Host received message from sandbox:', message)
}}
Expand Down
3 changes: 2 additions & 1 deletion apps/fs-experiment/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"start": "react-native start",
"bundle:sandbox": "bun run bundle:sandbox-fs && bun run bundle:sandbox-file-access",
"bundle:sandbox-fs": "npx react-native bundle --platform ios --dev false --entry-file sandbox-fs.js --bundle-output ios/sandbox-fs.jsbundle --assets-dest ios/",
"bundle:sandbox-file-access": "npx react-native bundle --platform ios --dev false --entry-file sandbox-file-access.js --bundle-output ios/sandbox-file-access.jsbundle --assets-dest ios/"
"bundle:sandbox-file-access": "npx react-native bundle --platform ios --dev false --entry-file sandbox-file-access.js --bundle-output ios/sandbox-file-access.jsbundle --assets-dest ios/",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "19.1.0",
Expand Down
4 changes: 2 additions & 2 deletions apps/recursive/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ function App({depth = 1}: AppProps): React.JSX.Element {
</Text>
<SandboxReactNativeView
style={styles.recursiveSandbox}
jsBundleSource="index"
moduleName="App" // Recursively load App itself
jsBundleSource="index" // bundle name for query from metro
componentName="App" // Recursively load App component from index.js
initialProperties={{depth: depth + 1}}
onMessage={msg => console.log('message', msg)}
onError={e => console.error('error', e)}
Expand Down
2 changes: 1 addition & 1 deletion apps/recursive/RecursiveDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const RecursiveDisplay = ({depth}: Props) => {
{depth < MAX_DEPTH ? (
<SandboxReactNativeView
style={styles.flex}
moduleName="RecursiveDisplay"
componentName="RecursiveDisplay"
initialProperties={{depth: depth + 1}}
/>
) : (
Expand Down
3 changes: 2 additions & 1 deletion apps/recursive/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start"
"start": "react-native start",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "19.1.0",
Expand Down
4 changes: 2 additions & 2 deletions apps/side-by-side/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ function SandboxDemoView({initialProperties}: {initialProperties: any}) {
{isVisible ? (
<SandboxReactNativeView
ref={sandboxRef}
jsBundleSource={'sandbox'}
moduleName={'SandboxApp'}
jsBundleSource={'sandbox'} // bundle name for query from metro
componentName={'SandboxApp'} // componentName registered in sandbox.js
style={styles.sandboxView}
initialProperties={initialProperties}
onMessage={msg => {
Expand Down
3 changes: 2 additions & 1 deletion apps/side-by-side/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start"
"start": "react-native start",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "19.1.0",
Expand Down
2 changes: 1 addition & 1 deletion bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
},
"packages/react-native-sandbox": {
"name": "@callstack/react-native-sandbox",
"version": "0.1.0",
"version": "0.2.0",
"devDependencies": {
"react": "19.1.0",
"react-native": "0.80.1",
Expand Down
4 changes: 2 additions & 2 deletions docs/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ On API level you will deal with `SandboxReactNativeView` component in your JSX:
<SandboxReactNativeView
style={styles.sandboxContainer}
jsBundleSource={'my-plugin'}
moduleName={'PluginComponent'}
componentName={'PluginComponent'}
onMessage={(message) => {
console.log(`Message: ${message} received through safe API`)
}}
Expand Down Expand Up @@ -105,7 +105,7 @@ On the left, you'll see the "Main App" column running a component directly in th
<SandboxReactNativeView
style={styles.sandboxView}
jsBundleSource={'sandbox'}
moduleName={'CrashIfYouCanDemo'}
componentName={'CrashIfYouCanDemo'}
onError={error => {
Toast.show({...})
return false
Expand Down
4 changes: 2 additions & 2 deletions docs/presentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function App() {
...
<SandboxReactNativeView ref={sandbox1Ref}
jsBundleSource={"sandbox"}
moduleName={"SandboxApp"}
componentName={"SandboxApp"}
onMessage={onMessage}
onError={onError}
initialProperties={...} launchOptions={...} />
Expand Down Expand Up @@ -179,7 +179,7 @@ function App() {
...
<SandboxReactNativeView ref={sandbox1Ref}
jsBundleSource={"sandbox"}
moduleName={"SandboxApp"}
componentName={"SandboxApp"}
onMessage={onMessage}
onError={onError}
initialProperties={...} launchOptions={...} />
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"android": "bun run android --filter=@apps/side-by-side",
"lint": "eslint . && bun --filter=@callstack/react-native-sandbox lint",
"format": "eslint . --fix && bun --filter=@callstack/react-native-sandbox format",
"typecheck": "bun --filter=@callstack/react-native-sandbox typecheck",
"test": "jest"
},
"devDependencies": {
Expand Down
9 changes: 5 additions & 4 deletions packages/react-native-sandbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The package uses **autolinking** and supports the **React Native New Architectur
import SandboxReactNativeView from '@callstack/react-native-sandbox';

<SandboxReactNativeView
moduleName="YourSandboxModule"
componentName="YourSandboxComponent"
jsBundleSource="sandbox" // bundle file name
onMessage={(data) => console.log('From sandbox:', data)}
onError={(error) => console.error('Sandbox error:', error)}
Expand All @@ -46,7 +46,8 @@ import SandboxReactNativeView from '@callstack/react-native-sandbox';

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `moduleName` | `string` | :ballot_box_with_check: | - | Name of the registered component to load from bundle specified in `jsBundleSource` |
| `componentName` | `string` | :ballot_box_with_check: | - | Name of the component registered through `AppRegistry.registerComponent` call inside the bundle file specified in `jsBundleSource` |
| `moduleName` | `string` | :white_large_square: | - | **⚠️ Deprecated**: Use `componentName` instead. Will be removed in a future version. |
| `jsBundleSource` | `string` | :ballot_box_with_check: | - | Name on file storage or URL to the JavaScript bundle to load |
| `initialProperties` | `object` | :white_large_square: | `{}` | Initial props for the sandboxed app |
| `launchOptions` | `object` | :white_large_square: | `{}` | Launch configuration options |
Expand Down Expand Up @@ -157,7 +158,7 @@ useEffect(() => {

return (
<SandboxReactNativeView
moduleName="DynamicApp"
componentName="DynamicApp"
jsBundleSource={bundleUrl}
initialProperties={{
userId: currentUser.id,
Expand Down Expand Up @@ -262,7 +263,7 @@ Enable additional logging:
const isDebug = __DEV__;

<SandboxReactNativeView
moduleName="DebugApp"
componentName="DebugApp"
launchOptions={{ debug: isDebug }}
onError={(error) => {
if (isDebug) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &

bool shouldReload = false;

if (oldViewProps.moduleName != newViewProps.moduleName ||
if (oldViewProps.componentName != newViewProps.componentName ||
oldViewProps.jsBundleSource != newViewProps.jsBundleSource ||
oldViewProps.initialProperties != newViewProps.initialProperties ||
oldViewProps.launchOptions != newViewProps.launchOptions ||
Expand Down Expand Up @@ -93,10 +93,10 @@ - (void)loadReactNativeView
{
const auto &props = *std::static_pointer_cast<const SandboxReactNativeViewProps>(_props);

NSString *moduleName = RCTNSStringFromString(props.moduleName);
NSString *componentName = RCTNSStringFromString(props.componentName);
NSString *jsBundleSource = RCTNSStringFromString(props.jsBundleSource);

if (moduleName.length == 0 || jsBundleSource.length == 0) {
if (componentName.length == 0 || jsBundleSource.length == 0) {
return;
}

Expand Down Expand Up @@ -131,7 +131,7 @@ - (void)loadReactNativeView
delegate.hasOnErrorHandler = props.hasOnErrorHandler;

RCTReactNativeFactory *factory = [[RCTReactNativeFactory alloc] initWithDelegate:delegate];
UIView *rnView = [factory.rootViewFactory viewWithModuleName:moduleName
UIView *rnView = [factory.rootViewFactory viewWithModuleName:componentName
initialProperties:initialProperties
launchOptions:launchOptions];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ export interface MessageEvent {
*/
export interface NativeProps extends ViewProps {
/**
* The name of the React Native module to load in the sandbox.
* The name of the React Native component to load in the sandbox.
* Must match with the registered component name from the JavaScript bundle
*/
moduleName: string
componentName: string

/** Name on file storage or URL to the JavaScript bundle to load */
jsBundleSource: string
Expand Down
Loading
Loading