Skip to content

Commit

Permalink
plugin: new JS API startWithArgs()
Browse files Browse the repository at this point in the history
From PR #9

* Added methods for starting project with custom arguments
* Provide arguments in inline command
* Fix passing args on iOS
* Updated documentation for startWithArgs feature
  • Loading branch information
siepra committed Mar 16, 2022
1 parent 8686371 commit 2edd052
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ import nodejs from 'nodejs-mobile-react-native';
```

- `nodejs.start`
- `nodejs.startWithArgs`
- `nodejs.startWithScript`
- `nodejs.channel.addListener`
- `nodejs.channel.post`
Expand All @@ -138,6 +139,15 @@ import nodejs from 'nodejs-mobile-react-native';

Starts the nodejs-mobile runtime thread with a file inside the `nodejs-project` directory.

### nodejs.startWithArgs(command [, options])

| Param | Type |
| --- | --- |
| command | <code>string</code> |
| options | <code>[StartupOptions](#ReactNative.StartupOptions)</code> |

Starts the nodejs-mobile runtime thread with a file inside the `nodejs-project` directory and passes provided arguments down to it.

### nodejs.startWithScript(scriptBody [, options])

| Param | Type |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,43 @@ public void run() {
}
}

@ReactMethod
public void startNodeProjectWithArgs(final String input, ReadableMap options) throws Exception {
// A New module instance may have been created due to hot reload.
_instance = this;
if(!_startedNodeAlready) {
_startedNodeAlready = true;

List<String> args = new ArrayList<String>(Arrays.asList(input.split(" ")));

String absoluteScriptPath = nodeJsProjectPath + "/" + args.get(0);

// Remove script file name from arguments list
args.remove(0);

final List<String> command = new ArrayList<String>();

command.add("node");
command.add(absoluteScriptPath);

command.addAll(args);

final boolean redirectOutputToLogcat = extractRedirectOutputToLogcatOption(options);

new Thread(new Runnable() {
@Override
public void run() {
waitForInit();
startNodeWithArguments(
command.toArray(new String[0]),
nodeJsProjectPath + ":" + builtinModulesPath,
redirectOutputToLogcat
);
}
}).start();
}
}

@ReactMethod
public void sendMessage(String channel, String msg) {
sendMessageToNodeChannel(channel, msg);
Expand Down
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ declare module "nodejs-mobile-react-native" {
* @param options
*/
start: (scriptFileName: string, options?: StartupOptions) => void
/**
* Starts the nodejs-mobile runtime thread with provided arguments
* @param command
* @param options
*/
startWithArgs: (command: string, options?: StartupOptions) => void
/**
* Starts the nodejs-mobile runtime thread with a script body
* @param scriptBody
Expand Down
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ const start=function(mainFileName, options) {
options = options || {};
RNNodeJsMobile.startNodeProject(mainFileName, options);
};

const startWithArgs=function(command, options) {
if (typeof command !== 'string') {
throw new Error('nodejs-mobile-react-native\'s startWithArgs expects to receive the main .js entrypoint filename with optional arguments, e.g.: nodejs.startWithArgs("main.js -c custom");');
}
options = options || {};
RNNodeJsMobile.startNodeProjectWithArgs(command, options);
};

const startWithScript=function(script, options) {
options = options || {};
RNNodeJsMobile.startNodeWithScript(script, options);
Expand Down Expand Up @@ -117,6 +126,7 @@ registerChannel(eventChannel);

const export_object = {
start: start,
startWithArgs: startWithArgs,
startWithScript: startWithScript,
channel: eventChannel
};
Expand Down
53 changes: 53 additions & 0 deletions ios/RNNodeJsMobile.m
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,42 @@ -(void)callStartNodeProject:(NSString *)mainFileName
[[NodeRunner sharedInstance] startEngineWithArguments:nodeArguments:nodePath];
}

-(void)callStartNodeProjectWithArgs:(NSString *)input
{
NSArray* command = [input componentsSeparatedByString: @" "];
NSString* script = [command objectAtIndex:0];

NSMutableArray* args = [command mutableCopy];
[args removeObject:[args objectAtIndex:0]];

NSString* srcPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@/%@", NODEJS_PROJECT_RESOURCE_PATH, script] ofType:@""];

NSMutableArray* nodeArguments = nil;

NSString* dlopenoverridePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@/%@", NODEJS_PROJECT_RESOURCE_PATH, NODEJS_DLOPEN_OVERRIDE_FILENAME] ofType:@""];
// Check if the file to override dlopen lookup exists, for loading native modules from the Frameworks.
if(!dlopenoverridePath)
{
nodeArguments = [NSMutableArray arrayWithObjects:
@"node",
srcPath,
nil
];

[nodeArguments addObjectsFromArray:args];
} else {
nodeArguments = [NSMutableArray arrayWithObjects:
@"node",
@"-r",
dlopenoverridePath,
srcPath,
nil
];

[nodeArguments addObjectsFromArray:args];
}
[[NodeRunner sharedInstance] startEngineWithArguments:nodeArguments:nodePath];
}

RCT_EXPORT_METHOD(startNodeWithScript:(NSString *)script options:(NSDictionary *)options)
{
Expand Down Expand Up @@ -136,6 +172,23 @@ -(void)callStartNodeProject:(NSString *)mainFileName
}
}

RCT_EXPORT_METHOD(startNodeProjectWithArgs:(NSString *)command options:(NSDictionary *)options)
{
if(![NodeRunner sharedInstance].startedNodeAlready)
{
[NodeRunner sharedInstance].startedNodeAlready=true;
NSThread* nodejsThread = nil;
nodejsThread = [[NSThread alloc]
initWithTarget:self
selector:@selector(callStartNodeProjectWithArgs:)
object:command
];
// Set 2MB of stack space for the Node.js thread.
[nodejsThread setStackSize:2*1024*1024];
[nodejsThread start];
}
}

-(void) sendMessageBackToReact:(NSString*)channelName:(NSString*)message
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
Expand Down

0 comments on commit 2edd052

Please sign in to comment.