add more flow annotations

This commit is contained in:
Andy Prock 2015-12-23 10:56:33 -08:00
parent 0ea4912a3a
commit 5ce0b901d9
18 changed files with 221 additions and 275 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
interfaces

View File

@ -6,7 +6,7 @@
[include] [include]
[libs] [libs]
interfaces/react-native-interface.js interfaces/
[options] [options]
module.system=haste module.system=haste
@ -25,4 +25,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-9]\\|[0-9]\\).[0-9
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version] [version]
^0.19.0 0.20.1

95
TcpServer.js Normal file
View File

@ -0,0 +1,95 @@
/**
* Copyright (c) 2015-present, Peel Technologies, Inc.
* All rights reserved.
*
* @providesModule TcpServer
* @flow
*/
'use strict';
var inherits = require('inherits');
var EventEmitter = require('events').EventEmitter;
var {
NativeModules
} = require('react-native');
var Sockets = NativeModules.TcpSockets;
var Socket = require('./TcpSocket');
function TcpServer(connectionListener: (socket: Socket) => void) {
if (!(this instanceof TcpServer)) {
return new TcpServer(connectionListener);
}
// $FlowFixMe: suppressing this error flow doesn't like EventEmitter
EventEmitter.call(this);
var self = this;
this._socket = new Socket();
// $FlowFixMe: suppressing this error flow doesn't like EventEmitter
this._socket.on('connect', function() {
self.emit('listening');
});
// $FlowFixMe: suppressing this error flow doesn't like EventEmitter
this._socket.on('error', function(error) {
self.emit('error', error);
self._socket.destroy();
});
// $FlowFixMe: suppressing this error flow doesn't like EventEmitter
this._socket.on('close', function() {
self.emit('close');
});
// $FlowFixMe: suppressing this error flow doesn't like EventEmitter
this._socket.on('connection', function(socketId) {
self._connections++;
var socket = new Socket({ _id: socketId });
self.emit('connection', socket);
});
if (connectionListener === typeof 'function') {
self.on('connection', connectionListener);
}
this._connections = 0;
}
inherits(TcpServer, EventEmitter);
TcpServer.prototype._debug = function() {
if (__DEV__) {
var args = [].slice.call(arguments);
console.log.apply(console, args);
}
};
TcpServer.prototype.listen = function(options: { port: number, hostname: ?string }, callback: ?() => void) : TcpServer {
var port = Number(options.port);
var hostname = options.hostname || 'localhost';
if (callback) {
this.on('listening', callback);
}
Sockets.listen(this._socket._id, hostname, port);
return this;
};
TcpServer.prototype.getConnections = function(callback: (err: ?any, count: number) => void) {
if (typeof callback === 'function') {
callback.invoke(null, this._connections);
}
};
TcpServer.prototype.close = function(callback: ?() => void) {
if (callback) {
this.on('close', callback);
}
this._socket.end();
};
module.exports = TcpServer;

View File

@ -1,11 +1,7 @@
//
// react-native-tcp
//
// Created by Andy Prock on 12/14/15.
// Copyright (c) 2015 Peel, Inc. All rights reserved.
//
/** /**
* Copyright (c) 2015-present, Peel Technologies, Inc.
* All rights reserved.
*
* @providesModule TcpSocket * @providesModule TcpSocket
* @flow * @flow
*/ */
@ -30,9 +26,8 @@ var STATE = {
CONNECTED: 2 CONNECTED: 2
}; };
exports.Socket = TcpSocket; function TcpSocket(options: ?any) {
// $FlowFixMe: suppressing this error flow doesn't like EventEmitter
function TcpSocket(options) {
EventEmitter.call(this); EventEmitter.call(this);
options = options || {}; options = options || {};
@ -53,20 +48,8 @@ function TcpSocket(options) {
usedIds.push(this._id); usedIds.push(this._id);
this._state = nativeSocket ? STATE.CONNECTED : STATE.DISCONNECTED; this._state = nativeSocket ? STATE.CONNECTED : STATE.DISCONNECTED;
this._connecting = false;
this._hadError = false;
this._host = null; this._host = null;
if (typeof options === 'number') {
options = { fd: options };
} else if (options === undefined) {
options = {};
}
if (options.fd) {
throw new Error('file descriptors are unsupoprted at this time.');
}
// these will be set once there is a connection // these will be set once there is a connection
this.readable = this.writable = false; this.readable = this.writable = false;
@ -94,7 +77,7 @@ TcpSocket.prototype._debug = function() {
} }
}; };
TcpSocket.prototype.connect = function(options, callback) { TcpSocket.prototype.connect = function(options: { port: number, host: ?string, localAddress: ?string, localPort: ?number, family: ?number }, callback: ?() => void) {
if (this._state !== STATE.DISCONNECTED) { if (this._state !== STATE.DISCONNECTED) {
throw new Error('Socket is already bound'); throw new Error('Socket is already bound');
} }
@ -127,7 +110,6 @@ TcpSocket.prototype.connect = function(options, callback) {
port |= port; port |= port;
this._state = STATE.CONNECTING; this._state = STATE.CONNECTING;
this._connecting = true;
this._debug('connecting, host:', host, 'port:', port); this._debug('connecting, host:', host, 'port:', port);
Sockets.connect(this._id, host, Number(port), options); Sockets.connect(this._id, host, Number(port), options);
@ -135,14 +117,14 @@ TcpSocket.prototype.connect = function(options, callback) {
// Check that the port number is not NaN when coerced to a number, // Check that the port number is not NaN when coerced to a number,
// is an integer and that it falls within the legal range of port numbers. // is an integer and that it falls within the legal range of port numbers.
function isLegalPort(port) { function isLegalPort(port: number) : boolean {
if (typeof port === 'string' && port.trim() === '') { if (typeof port === 'string' && port.trim() === '') {
return false; return false;
} }
return +port === (port >>> 0) && port >= 0 && port <= 0xFFFF; return +port === (port >>> 0) && port >= 0 && port <= 0xFFFF;
} }
TcpSocket.prototype.setTimeout = function(msecs, callback) { TcpSocket.prototype.setTimeout = function(msecs: number, callback: () => void) {
var self = this; var self = this;
if (this._timeout) { if (this._timeout) {
@ -156,11 +138,11 @@ TcpSocket.prototype.setTimeout = function(msecs, callback) {
} }
var self = this; var self = this;
this._timeout = setTimeout(msecs, function() { this._timeout = setTimeout(function() {
self.emit('timeout'); self.emit('timeout');
self._timeout = null; self._timeout = null;
self.destroy(); self.destroy();
}); }, msecs);
} }
}; };
@ -222,13 +204,12 @@ TcpSocket.prototype.destroy = function() {
} }
}; };
TcpSocket.prototype._onEvent = function(info) { TcpSocket.prototype._onEvent = function(info: { event: string, data: ?any }) {
this._debug('received', info.event); this._debug('received', info.event);
if (info.event === 'connect') { if (info.event === 'connect') {
this.writable = this.readable = true; this.writable = this.readable = true;
this._state = STATE.CONNECTED; this._state = STATE.CONNECTED;
this._connecting = false;
} else if (info.event === 'data') { } else if (info.event === 'data') {
if (this._timeout) { if (this._timeout) {
clearTimeout(this._timeout); clearTimeout(this._timeout);
@ -291,7 +272,7 @@ TcpSocket.prototype.write = function(buffer, encoding, callback) {
}); });
}; };
function normalizeError (err) { function normalizeError(err) {
if (err) { if (err) {
if (typeof err === 'string') { if (typeof err === 'string') {
err = new Error(err); err = new Error(err);
@ -301,74 +282,4 @@ function normalizeError (err) {
} }
} }
exports.Server = TcpServer; module.exports = TcpSocket;
function TcpServer(options, connectionListener) {
if (!(this instanceof TcpServer)) {
return new TcpServer(options, connectionListener);
}
EventEmitter.call(this);
var self = this;
this._socket = new exports.Socket(options);
this._socket.on('connect', function() {
self.emit('listening');
});
this._socket.on('error', function(error) {
self.emit('error', error);
self._socket.destroy();
});
this._socket.on('close', function() {
self.emit('close');
});
this._socket.on('connection', function(socketId) {
var socket = new exports.Socket({_id : socketId });
self.emit('connection', socket);
});
if (typeof options === 'function') {
connectionListener = options;
options = {};
self.on('connection', connectionListener);
} else {
options = options || {};
if (typeof connectionListener === 'function') {
self.on('connection', connectionListener);
}
}
// this._connections = 0;
// this.allowHalfOpen = options.allowHalfOpen || false;
// this.pauseOnConnect = !!options.pauseOnConnect;
}
inherits(TcpServer, EventEmitter);
TcpServer.prototype.listen = function(options, callback) {
var port = Number(options.port);
var hostname = options.hostname || 'localhost';
if (callback) {
this.on('listening', callback);
}
Sockets.listen(this._socket._id, hostname, port);
return this;
};
TcpServer.prototype.getConnections = function(callback) {
/* nop */
};
TcpServer.prototype.close = function(callback) {
if (callback) {
this.on('close', callback);
}
this._socket.end();
};

View File

@ -1,62 +1,23 @@
/** /**
* Copyright (c) 2015-present, Peel Technologies, Inc.
* All rights reserved.
*
* @providesModule TcpSockets * @providesModule TcpSockets
* @flow * @flow
*/ */
'use strict'; 'use strict';
var ipRegex = require('ip-regex'); var ipRegex = require('ip-regex');
var Socket = require('./TcpSocket').Socket; var Socket = require('./TcpSocket');
var Server = require('./TcpSocket').Server; var Server = require('./TcpServer');
exports.createServer = function(options, connectionListener) { exports.createServer = function(connectionListener: (socket: Socket) => void) : Server {
return new Server(options, connectionListener); return new Server(connectionListener);
}; };
exports.connect = exports.createConnection = function(options: { port: number, host: ?string, localAddress: ?string, localPort: ?number, family: ?number }, callback: ?() => void) : Socket {
// Target API:
//
// var s = net.connect({port: 80, host: 'google.com'}, function() {
// ...
// });
//
// There are various forms:
//
// connect(options, [cb])
// connect(port, [host], [cb])
// connect(path, [cb]);
//
// exports.connect = exports.createConnection = function() {
// var args = normalizeConnectArgs(arguments);
// Socket._debug('createConnection', args);
// var s = new Socket(args[0]);
// return Socket.prototype.connect.apply(s, args);
// };
//
// // Returns an array [options] or [options, cb]
// // It is the same as the argument of Socket.prototype.connect().
// function normalizeConnectArgs(args) {
// var options = {};
//
// if (args[0] !== null && typeof args[0] === 'object') {
// // connect(options, [cb])
// options = args[0];
// }/* else if (isPipeName(args[0])) {
// // connect(path, [cb]);
// options.path = args[0];
// }*/ else {
// // connect(port, [host], [cb])
// options.port = args[0];
// if (typeof args[1] === 'string') {
// options.host = args[1];
// }
// }
//
// var cb = args[args.length - 1];
// return typeof cb === 'function' ? [options, cb] : [options];
// }
exports.connect = exports.createConnection = function(options: { port: number, host: ?string, localAddress: ?string, localPort: ?number, family: ?number }, callback : ?any) : Socket {
var tcpSocket = new Socket(); var tcpSocket = new Socket();
tcpSocket.connect(options, callback); tcpSocket.connect(options, callback);
return tcpSocket; return tcpSocket;

View File

@ -27,5 +27,5 @@ android {
dependencies { dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.facebook.react:react-native:0.11.+' compile 'com.facebook.react:react-native:0.17.+'
} }

View File

@ -1,8 +1,6 @@
/** /**
* TcpSockets.java * Copyright (c) 2015-present, Peel Technologies, Inc.
* react-native-tcp * All rights reserved.
*
* Created by Andy Prock on 12/21/15.
*/ */
package com.peel.react; package com.peel.react;
@ -129,4 +127,23 @@ public final class TcpSockets extends ReactContextBaseJavaModule {
} }
}.execute(); }.execute();
} }
@ReactMethod
public void listen(final Integer cId, final String host, final Integer port) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
protected void doInBackgroundGuarded(Void... params) {
FLog.e(TAG, "TcpSockets.listen unimplemented.");
WritableMap eventParams = Arguments.createMap();
eventParams.putString("event", "error");
eventParams.putString("data", "TcpSockets.connect unimplemented");
ReactContext reactContext = TcpSockets.this.getReactApplicationContext();
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tcp-" + cId + "-event", eventParams);
}
}.execute();
}
} }

View File

@ -1,8 +1,6 @@
/** /**
* TcpSocketsModule.java * Copyright (c) 2015-present, Peel Technologies, Inc.
* react-native-tcp * All rights reserved.
*
* Created by Andy Prock on 12/21/15.
*/ */
package com.peel.react; package com.peel.react;

View File

@ -1,5 +1,8 @@
/** /**
* Source: https://gist.github.com/ncerminara/11257943 * @providesModule base64-js
* @noflow
*
* Original Source: https://gist.github.com/ncerminara/11257943
*/ */
'use strict'; 'use strict';

View File

@ -1,3 +1,8 @@
/**
* Copyright (c) 2015-present, Peel Technologies, Inc.
* All rights reserved.
*/
'use strict'; 'use strict';
var React = require('react-native'); var React = require('react-native');
@ -21,13 +26,6 @@ var aPort = randomPort();
var a = net.createServer({}, function(socket) { var a = net.createServer({}, function(socket) {
console.log('server connected'); console.log('server connected');
// socket.on('data', function (data) {
// var str = String.fromCharCode.apply(null, new Uint8Array(data));
// console.log('a received', str);
// a.close();
// b.end();
// });
socket.on('data', function (data) { socket.on('data', function (data) {
console.log('Server Received: ' + data); console.log('Server Received: ' + data);
socket.write('Echo server\r\n'); socket.write('Echo server\r\n');
@ -38,14 +36,6 @@ var a = net.createServer({}, function(socket) {
}); });
}).listen({ port: aPort }); }).listen({ port: aPort });
// a.on('listening', function() {
// console.log('listening');
// });
//
// a.on('error', function(error) {
// console.log('error ' + error);
// });
var b = net.createConnection({ port: aPort }, function(err) { var b = net.createConnection({ port: aPort }, function(err) {
if (err) { if (err) {
throw err; throw err;

13
interfaces/interface.js Normal file
View File

@ -0,0 +1,13 @@
/**
* Copyright (c) 2015-present, Peel Technologies, Inc.
* All rights reserved.
*
* @flow
*/
declare var __DEV__: boolean;
declare module 'react-native' {
declare var NativeModules: any;
declare var DeviceEventEmitter: any;
}

View File

@ -1,26 +0,0 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/
// see also react-native.js
declare var __DEV__: boolean;
declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: any; /*?{
inject: ?((stuff: Object) => void)
};*/
declare var fetch: any;
declare var Headers: any;
declare var Request: any;
declare var Response: any;
declare module requestAnimationFrame {
declare var exports: (callback: any) => any;
}

View File

@ -1,10 +1,7 @@
// /**
// TcpSocketClient.h * Copyright (c) 2015-present, Peel Technologies, Inc.
// react-native-tcp * All rights reserved.
// */
// Created by Andy Prock on 12/14/15.
// Copyright (c) 2015 Peel, Inc. All rights reserved.
//
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "RCTBridgeModule.h" #import "RCTBridgeModule.h"

View File

@ -1,10 +1,7 @@
// /**
// TcpSocketClient.m * Copyright (c) 2015-present, Peel Technologies, Inc.
// react-native-tcp * All rights reserved.
// */
// Created by Andy Prock on 12/14/15.
// Copyright (c) 2015 peel, Inc. All rights reserved.
//
#import <netinet/in.h> #import <netinet/in.h>
#import <arpa/inet.h> #import <arpa/inet.h>

View File

@ -1,10 +1,7 @@
// /**
// TcpSockets.h * Copyright (c) 2015-present, Peel Technologies, Inc.
// react-native-tcp * All rights reserved.
// */
// Created by Andy Prock on 12/14/15.
// Copyright (c) 2015 Peel, Inc. All rights reserved.
//
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <Availability.h> #import <Availability.h>

View File

@ -1,10 +1,7 @@
// /**
// TcpSockets.m * Copyright (c) 2015-present, Peel Technologies, Inc.
// react-native-tcp * All rights reserved.
// */
// Created by Andy Prock on 12/14/15.
// Copyright (c) 2015 Peel, Inc. All rights reserved.
//
#import "RCTAssert.h" #import "RCTAssert.h"
#import "RCTBridge.h" #import "RCTBridge.h"

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'react-native-tcp' s.name = 'react-native-tcp'
s.version = '1.1.1' s.version = '0.0.3'
s.summary = 'node\'s net API in React Native.' s.summary = 'node\'s net API in React Native.'
s.description = <<-DESC s.description = <<-DESC
Enables accessing tcp sockets in React Native. Enables accessing tcp sockets in React Native.
@ -9,16 +9,10 @@ Pod::Spec.new do |s|
s.license = { :type => 'MIT' } s.license = { :type => 'MIT' }
s.authors = { 'Andy Prock' => 'aprock@gmail.com' } s.authors = { 'Andy Prock' => 'aprock@gmail.com' }
s.source = { :git => 'https://github.com/PeelTechnologies/react-native-tcp.git' } s.source = { :git => 'https://github.com/PeelTechnologies/react-native-tcp.git' }
s.default_subspec = 'Core'
s.requires_arc = true s.requires_arc = true
s.platform = :ios, '7.0' s.platform = :ios, '7.0'
s.prepare_command = 'npm install --production' s.prepare_command = 'npm install --production'
s.source_files = '*.{c,h,m}', 'CocoaAsyncSocket/*.{h,m}'
s.preserve_paths = 'node_modules', '**/*.js', 'package.json' s.preserve_paths = 'node_modules', '**/*.js', 'package.json'
s.header_mappings_dir = '.' s.header_mappings_dir = '.'
# s.dependency 'React'
s.subspec 'Core' do |ss|
ss.source_files = '*.{c,h,m}', 'CocoaAsyncSocket/*.{h,m}'
ss.preserve_paths = '*.js'
end
end end

View File

@ -1,7 +1,7 @@
{ {
"name": "react-native-tcp", "name": "react-native-tcp",
"version": "0.0.2", "version": "0.0.2",
"description": "node's dgram API for react-native", "description": "node's net API for react-native",
"main": "TcpSockets.js", "main": "TcpSockets.js",
"scripts": { "scripts": {
"start": "exit 1" "start": "exit 1"
@ -27,7 +27,8 @@
"name": "Andy Prock", "name": "Andy Prock",
"email": "aprock@gmail.com" "email": "aprock@gmail.com"
}, },
"license": "MIT", "license": "UNLICENSED",
"private": true,
"bugs": { "bugs": {
"url": "https://github.com/PeelTechnologies/react-native-tcp/issues" "url": "https://github.com/PeelTechnologies/react-native-tcp/issues"
}, },