forked from JaneaSystems/nodejs-mobile-react-native
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
124 lines (106 loc) · 3.64 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
import { NativeModules, NativeAppEventEmitter } from 'react-native';
var EventEmitter = require('react-native/Libraries/vendor/emitter/EventEmitter');
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 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,
startWithScript: startWithScript,
channel: eventChannel
};
module.exports = export_object;