forked from dejakob/nodejs-mobile-react-native
-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
134 lines (114 loc) · 4.05 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { NativeModules, NativeAppEventEmitter } from 'react-native';
var EventEmitter = require('react-native/Libraries/vendor/emitter/EventEmitter').default;
const EVENT_CHANNEL = '_EVENTS_';
var channels = {};
/*
* This class is defined in rn-bridge/index.js as well.
* Any change made here should be ported to rn-bridge/index.js too.
* The MessageCodec class provides two static methods to serialize/deserialize
* the data sent through the events channel.
*/
class MessageCodec {
// This is a 'private' constructor, should only be used by this class
// static methods.
constructor(_event, ..._payload) {
this.event = _event;
this.payload = JSON.stringify(_payload);
};
// Serialize the message payload and the message.
static serialize(event, ...payload) {
const envelope = new MessageCodec(event, ...payload);
// Return the serialized message, that can be sent through a channel.
return JSON.stringify(envelope);
};
// Deserialize the message and the message payload.
static deserialize(message) {
var envelope = JSON.parse(message);
if (typeof envelope.payload !== 'undefined') {
envelope.payload = JSON.parse(envelope.payload);
}
return envelope;
};
};
/**
* Channel super class.
*/
class ChannelSuper extends EventEmitter {
constructor(name) {
super();
this.name = name;
// Renaming the 'emit' method to 'emitLocal' is not strictly needed, but
// it is useful to clarify that 'emitting' on this object has a local
// scope: it emits the event on the Node side only, it doesn't send
// the event to React Native.
this.emitLocal = this.emit;
delete this.emit;
};
};
const { RNNodeJsMobile } = NativeModules;
/**
* Events channel class that supports user defined event types with
* optional arguments. Allows to send any serializable
* JavaScript object supported by 'JSON.stringify()'.
* Sending functions is not currently supported.
* Includes the previously available 'send' method for 'message' events.
*/
class EventChannel extends ChannelSuper {
post(event, ...msg) {
RNNodeJsMobile.sendMessage(this.name, MessageCodec.serialize(event, ...msg));
};
// Posts a 'message' event, to be backward compatible with old code.
send(...msg) {
this.post('message', ...msg);
};
processData(data) {
// The data contains the serialized message envelope.
var envelope = MessageCodec.deserialize(data);
this.emitLocal(envelope.event, ...(envelope.payload));
};
};
const start=function(mainFileName, options) {
if (typeof mainFileName !== 'string') {
throw new Error('nodejs-mobile-react-native\'s start expects to receive the main .js entrypoint filename, e.g.: nodejs.start("main.js");');
}
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);
}
/*
* Dispatcher for all channels. This event is called by the plug-in
* native code to deliver events from Node.
* The channelName field is the channel name.
* The message field is the data.
*/
NativeAppEventEmitter.addListener("nodejs-mobile-react-native-message",
(e) => {
if (channels[e.channelName]) {
channels[e.channelName].processData(e.message);
} else {
throw new Error('Error: Channel not found:', e.channelName);
}
}
);
function registerChannel(channel) {
channels[channel.name] = channel;
};
const eventChannel = new EventChannel(EVENT_CHANNEL);
registerChannel(eventChannel);
const export_object = {
start: start,
startWithArgs: startWithArgs,
startWithScript: startWithScript,
channel: eventChannel
};
module.exports = export_object;