127 Commits

Author SHA1 Message Date
Adam Ernst
2ca6138852 Start exposing RCTWebSocketObserver using a protocol
Reviewed By: javache

Differential Revision: D4296387

fbshipit-source-id: 33f92c36168dcb18356d0ccdaf902a84634d94b7
2016-12-08 07:44:37 -08:00
Adam Ernst
574e3daf9f Clean up RCTWebSocketObserver
Summary: Avoid using properties where unnecessary; stick to only one way to modify the delegate.

Reviewed By: javache

Differential Revision: D4296351

fbshipit-source-id: 94d0e3c90904ed584f691a3f28a15a7ac450c3e1
2016-12-08 07:44:37 -08:00
Adam Ernst
28e2f64d07 Remove unused queue ivar from RCTWebSocketManager
Reviewed By: javache

Differential Revision: D4296309

fbshipit-source-id: feee004e24abdb4b3626c5304f662ec3d71118b5
2016-12-08 07:44:37 -08:00
Adam Ernst
ac489858f8 Clean up RCTWebSocketProxyDelegate a bit
Reviewed By: javache

Differential Revision: D4296294

fbshipit-source-id: b31e522c21ec490fdf98711655e5e8df22b32a12
2016-12-08 07:44:37 -08:00
Eming Kwok
40b84fa5f8 fix memory leak in Chrome debugging
Summary:
`RCTWebSocketExecutor` saves every WebSocket callback when sending message to chrome, but does not clear them in a debug session until the JS bridge is reloaded, and there may be thousands of blocks saved in the callback table. This PR removes them after they are called.
Closes https://github.com/facebook/react-native/pull/11341

Differential Revision: D4295710

Pulled By: javache

fbshipit-source-id: 29a02d1aba320115bbb97aee8981e34b89303c91
2016-12-07 17:13:42 -08:00
Pieter De Baets
59407f3660 Redo exported headers and include paths for opensource
Summary:
Xcode really sucks, per some discussion on e1577df1fd and https://developer.apple.com/library/content/technotes/tn2215/_index.html, if you use the headers phase, and mark headers in your static library as public, they will actually end up in the final package that's built and you can't submit to the app store! This changes our xcode setup to use a copy files phase instead.

I've also changed the header include path to be $(BUILT_PRODUCTS_DIR)/include, which is added to the include path by Xcode by default, so 3rd party libraries should not be impacted by these changes anymore.

Reviewed By: mkonicek

Differential Revision: D4291607

fbshipit-source-id: 969b9ebcbeb8161f85427f8c429e198d9d0fae30
2016-12-07 15:28:29 -08:00
Pieter De Baets
e1577df1fd Move all header imports to "<React/..>"
Summary:
To make React Native play nicely with our internal build infrastructure we need to properly namespace all of our header includes.

Where previously you could do `#import "RCTBridge.h"`, you must now write this as `#import <React/RCTBridge.h>`. If your xcode project still has a custom header include path, both variants will likely continue to work, but for new projects, we're defaulting the header include path to `$(BUILT_PRODUCTS_DIR)/usr/local/include`, where the React and CSSLayout targets will copy a subset of headers too. To make Xcode copy headers phase work properly, you may need to add React as an explicit dependency to your app's scheme and disable "parallelize build".

Reviewed By: mmmulani

Differential Revision: D4213120

fbshipit-source-id: 84a32a4b250c27699e6795f43584f13d594a9a82
2016-11-23 07:58:39 -08:00
Pieter De Baets
7c91f894ba Fix CSSLayout import hack, update podspec
Summary: Correct header import paths, update podspec so we point at the copy in ReactCommon (and can eventually remove the copy under React)

Reviewed By: astreet

Differential Revision: D4204501

fbshipit-source-id: e979a010092f025b2cdc289e1e5f22fc7b65a8d1
2016-11-21 09:13:36 -08:00
Pieter De Baets
f255bda51f Fix loop when websocket executor is used without packager present
Reviewed By: mhorowitz

Differential Revision: D4159911

fbshipit-source-id: db913704641daf055060f5fe4561479daf76cd5a
2016-11-21 07:13:28 -08:00
Omeid
54f48de48a ios:websocket:exectuor : Grab port from Bundle URL
Summary:
Grabbing the port from Bundle URL allows concurrent Remote JS Debugging using the same machine with running multiple instances of packager on different ports.

This improves the developer experience when developing and debugging cross-platform components.
Closes https://github.com/facebook/react-native/pull/10007

Differential Revision: D4008630

Pulled By: javache

fbshipit-source-id: fcf8495e564fd9ac7baf26a87ed3904898132aa0
2016-10-12 08:43:37 -07:00
Pieter De Baets
292cc82d0e Reorganize core JS files
Reviewed By: lexs

Differential Revision: D3987463

fbshipit-source-id: fa8f1d1bea7ed699120b9705ddc1c83767fcf8e4
2016-10-11 10:14:28 -07:00
Douglas Lowder
8622998335 Apple TV support 2: Xcode projects and CI (scripts/objc-test.sh)
Summary:
* Motivation *

Second PR for Apple TV support.

* Test plan *

Apple TV tests have been added to scripts/objc-test.sh
Closes https://github.com/facebook/react-native/pull/10227

Differential Revision: D3974064

Pulled By: javache

fbshipit-source-id: 36dffb4517efa489e40fa713a30655d1d76ef646
2016-10-05 07:28:44 -07:00
Douglas Lowder
d368ebfab2 Apple TV support 1: existing Objective C code should compile for tvOS
Summary:
First commit for Apple TV support: changes to existing Objective-C code so that it will compile correctly for tvOS.
Closes https://github.com/facebook/react-native/pull/9649

Differential Revision: D3916021

Pulled By: javache

fbshipit-source-id: 34acc9daf3efff835ffe38c43ba5d4098a02c830
2016-09-27 06:28:33 -07:00
Dmitry Petukhov
6b42d5c952 Updating Websocket readyState in case of websocketFailed event
Summary:
Fix for https://github.com/facebook/react-native/issues/9465

We are building a react-native based application which extensively uses WebSockets. The Android app crashes right after waking up being in suspended mode for a coupe of days and throws an exception:

"Cannot send a message. Unknown WebSocket id 1"

Before calling WebSocket.send(...) method from WebSocket.js we always check its readyState. I believe the problem is caused by not updating readyState if case of 'websocketFailed' event. this.close() cause the current used websocket ID to be removed from mWebSocketConnections HashMap (WebSocketModule.java), but readyState stays the same.
Closes https://github.com/facebook/react-native/pull/9487

Differential Revision: D3838675

Pulled By: mkonicek

fbshipit-source-id: e833cef9f1b94c6f7236077241cacf5a56f5824b
2016-09-08 17:13:45 -07:00
James Ide
ad24bcf7cc Remove guard that we used in iOS 7 to avoid a JS crash
Summary:
JSC on iOS 8 and above includes TypedArrays so there's no need for the guard statement anymore since React Native officially does not support iOS 7 moving forward.
Closes https://github.com/facebook/react-native/pull/9780

Differential Revision: D3834979

Pulled By: mkonicek

fbshipit-source-id: 6e28a47702d6e3d604fedb9d2d00fe1c539a6926
2016-09-08 07:43:52 -07:00
Pieter De Baets
07553d0f1c Update React Native minimum OS version to iOS8
Reviewed By: majak

Differential Revision: D3723143

fbshipit-source-id: 482f9820370b752d937e6df7f74c33d53a0a2e7d
2016-09-01 19:43:47 -07:00
Pieter De Baets
2f78852411 Fix warning on unused return values in RCTSRWebSocket
Summary:
Assert that the return value of these methods is sane.

Closes https://github.com/facebook/react-native/issues/8108

Reviewed By: majak

Differential Revision: D3722629

fbshipit-source-id: 2a67daae6dc380721e5dad27acd2ab67f71d0c6c
2016-08-16 07:28:28 -07:00
Pieter De Baets
7fa677f7c3 Add MessageQueue method for executing function and returning its result
Reviewed By: majak

Differential Revision: D3175793

fbshipit-source-id: e1e66e3dcde8b1fb35973340e12d947a0e955775
2016-07-18 07:13:32 -07:00
Skotch Vail
bcf4bb6edd Automated changes to remove implicit capture of self in blocks: Libraries/FBReactKit/BUCK
Reviewed By: javache

Differential Revision: D3442470

fbshipit-source-id: 584a2bb3df5f7122166778b8fd44fae45560491e
2016-07-07 12:44:14 -07:00
danielbasedow
4ac4f86bf5 Add ping to WebSocket
Summary:
Idle WebSocket connections get reset after a few minutes of inactivity. To prevent this, most WebSocket implementations offer sending special ping messages. This PR adds a method `sendPing()` to  WebSocket. Ping payloads are not supported.

Manual testing can be done by adding `connection.on('ping', _ => console.log('Received ping'));` to a ws connection or using a packet sniffer while sending pings.
Closes https://github.com/facebook/react-native/pull/8505

Differential Revision: D3516260

Pulled By: dmmiller

fbshipit-source-id: cfebf5899188ae53254d5be6b666a9075e0eed89
2016-07-05 05:58:23 -07:00
Alex Kotliarskyi
662ec705cb Reconnect RCTWebSocketManager when packager restarts
Reviewed By: bottledwalter

Differential Revision: D3434769

fbshipit-source-id: a0b165129b66d03403defb39a20c86ab982fc8b5
2016-06-20 10:58:32 -07:00
Nathan Azaria
9443bc5c3f Changed the host for RCTWebSocketExecutor to the one retrieved from the bridge.
Reviewed By: javache

Differential Revision: D3425043

fbshipit-source-id: 342d3dfede6a29197dedb68278ee088dcf009e16
2016-06-13 13:28:28 -07:00
Nick Lockwood
72b363d7fc Replaced isMainThread checks with a proper test for main queue
Summary:
As per https://twitter.com/olebegemann/status/738656134731599872, our use of "main thread" to mean "main queue" seems to be unsafe.

This diff replaces the `NSThread.isMainQueue` checks with dispatch_get_specific(), which is the recommended approach.

I've also replaced all use of "MainThread" terminology with "MainQueue", and taken the opportunity to deprecate the "sync" param of `RCTExecuteOnMainThread()`, which, while we do still use it in a few places, is incredibly unsafe and shouldn't be encouraged.

Reviewed By: javache

Differential Revision: D3384910

fbshipit-source-id: ea7c216013372267b82eb25a38db5eb4cd46a089
2016-06-06 07:58:36 -07:00
Ewan Mellor
03512fb721 Fix the Origin: header used in WebSocket requests.
Summary:
RFC 6454 section 7 defines the Origin: header syntax, and it's a
scheme, host, and optional port, not a URL.

Section 6 defines serialization of the header, including omission of the
port.

Therefore, we need to omit the trailing slash in all cases, and omit
the port if it matches the default port for the protocol.
Closes https://github.com/facebook/react-native/pull/7920

Differential Revision: D3387619

fbshipit-source-id: 552756e63ad41463af357a5073fae56c96e58958
2016-06-03 15:13:41 -07:00
Nick Lockwood
2525feb37f Updated Websocket to use new event system
Reviewed By: javache

Differential Revision: D3292473

fbshipit-source-id: f9a9e0a1b5a12f7fa8b36ebdba88405370f91c54
2016-05-12 08:30:24 -07:00
Christoph Pojer
d363b1f2e2 Update Jest APIs on fbsource
Reviewed By: javache

Differential Revision: D3229435

fb-gh-sync-id: b0e252d69e1f399a946fca6e98ef62ff44c2ef9c
fbshipit-source-id: b0e252d69e1f399a946fca6e98ef62ff44c2ef9c
2016-04-27 19:16:32 -07:00
Philipp von Weitershausen
8891f22f88 Fix WebSocket compatibility with event-target-shim ^1.0.5
Summary:
event-target-shim versions before 1.1.0 do not support taking an array for `EventTarget`. react-native requires `^1.0.5`, so this fixes compatibility with those earlier versions.

**Test Plan:** ran WebSocket UIExplorer example with earlier version of event-target-shim.
Closes https://github.com/facebook/react-native/pull/7261

Differential Revision: D3230881

Pulled By: martinbigio

fb-gh-sync-id: 6a22d58841a4b401a200fece64d13a70043fb09a
fbshipit-source-id: 6a22d58841a4b401a200fece64d13a70043fb09a
2016-04-27 12:26:23 -07:00
Philipp von Weitershausen
ed930b4710 Add support for sending binary data in websockets
Summary:This is a reprise of #6327, but with iOS 7.0 compatibility and less `package.json` changes.

**Test Plan:** Load WebSocketExample in UIExplorer app and start websocket test server script (both provided in #6889) and test sending binary data on both iOS and Android
Closes https://github.com/facebook/react-native/pull/6961

Differential Revision: D3202022

Pulled By: mkonicek

fb-gh-sync-id: 38843d0a9c0172971c5c70a5139ded04042b280a
fbshipit-source-id: 38843d0a9c0172971c5c70a5139ded04042b280a
2016-04-20 08:53:25 -07:00
Elliot Lynde
7e515f8d4a Wait longer for debugger proxy
Reviewed By: yuzhi

Differential Revision: D3198412

fb-gh-sync-id: fe11f74b2a019accc24b08162746ce4793a49b90
fbshipit-source-id: fe11f74b2a019accc24b08162746ce4793a49b90
2016-04-19 17:13:25 -07:00
Philipp von Weitershausen
ebb44d202b Clean up and simplify WebSocket implementation on the JS side
Summary:- Get rid of no longer necessary WebSocket.js v WebSocketBase.js split
- Use `EventTarget(list, of, events)` as base class to auto-generate `oneventname` getters/setters that get invoked along with other event handlers
- Type annotation `any` considered harmful, especially when we can easily spell out the actual type
- Throw in some `const` goodness for free

**Test Plan:** Launch UIExplorer example app, supplied `websocket_test_server` script, and try different combinations of sending and receiving text and binary data on both iOS and Android.
Closes https://github.com/facebook/react-native/pull/6889

Differential Revision: D3184835

Pulled By: mkonicek

fb-gh-sync-id: f21707f4e97aa5a79847f5157e0a9f132a1a01cd
fbshipit-source-id: f21707f4e97aa5a79847f5157e0a9f132a1a01cd
2016-04-18 15:43:25 -07:00
digeff
4c8a9f0d00 Added support for JavaScript third-party debuggers
Summary:* Add ability to configure the app that should open when starting debugging

axemclion discussed this feature with tadeuzagallo and martinbigio on: https://github.com/facebook/react-native/issues/5051
Closes https://github.com/facebook/react-native/pull/5683

Reviewed By: martinbigio

Differential Revision: D2971497

Pulled By: mkonicek

fb-gh-sync-id: 91c3ce68feed989658124bb96cb61d03dd032599
fbshipit-source-id: 91c3ce68feed989658124bb96cb61d03dd032599
2016-04-07 13:15:58 -07:00
Pieter De Baets
b00c77af80 Increase RN devtools retry timeout
Summary:The 200ms timeout was causing resource issues and causing a lot of overhead when you're not running the devtools, since it will basically create a new socket every 200ms.

Also clean up the way we do logging so it's completely compiled out in prod, and standardize all the names we use for threading to lowercase react.

Reviewed By: frantic

Differential Revision: D3115975

fb-gh-sync-id: e6e51c0621d8e9fc4eadb864acd678b8b5d322a1
fbshipit-source-id: e6e51c0621d8e9fc4eadb864acd678b8b5d322a1
2016-04-01 07:02:25 -07:00
Alexey Dodonov
cc2068e201 Backed out changeset 183744d2415b
Reviewed By: nicklockwood

Differential Revision: D3053067

fb-gh-sync-id: de20718b5bf82eae433637847143e32b7a4bb216
shipit-source-id: de20718b5bf82eae433637847143e32b7a4bb216
2016-03-15 11:49:28 -07:00
Christopher Dro
e674e45c2e Reverted commit D3040735
Summary:This is a follow up of 9b87e6c860.

- Allows custom headers on connection request
- Adds a default `origin` header to Android, just like iOS

**Introduces no breaking changes.**

I was working on something similar and would like to propose a few changes that make the API more consistent across both iOS and Android platforms and brings this closer to [spec](https://tools.ietf.org/html/rfc6455).

I believe aprock first implementation of adding custom `headers` was correct. It makes sense naming this argument `headers` since we have no other general options available, and the current `options` field is being used to pass in a header anyway.

My use case for custom headers was attaching a token to the `Authorization` header on the connection request. I have been testing this by passing a JWT inside the `Authorization` header and verifying it on the server before establishing a connection.
Closes https://github.com/facebook/react-native/pull/6016

Differential Revision: D3040735

fb-gh-sync-id: 183744d2415b895f9d9fd8ecf6023a546e18a546
shipit-source-id: 183744d2415b895f9d9fd8ecf6023a546e18a546
2016-03-15 07:20:26 -07:00
Christopher Dro
205b5d4732 Update options parameter to headers. Update to spec.
Summary:This is a follow up of 9b87e6c860.

- Allows custom headers on connection request
- Adds a default `origin` header to Android, just like iOS

**Introduces no breaking changes.**

I was working on something similar and would like to propose a few changes that make the API more consistent across both iOS and Android platforms and brings this closer to [spec](https://tools.ietf.org/html/rfc6455).

I believe aprock first implementation of adding custom `headers` was correct. It makes sense naming this argument `headers` since we have no other general options available, and the current `options` field is being used to pass in a header anyway.

My use case for custom headers was attaching a token to the `Authorization` header on the connection request. I have been testing this by passing a JWT inside the `Authorization` header and verifying it on the server before establishing a connection.
Closes https://github.com/facebook/react-native/pull/6016

Differential Revision: D3040735

Pulled By: nicklockwood

fb-gh-sync-id: f81bd14ccbdba36309b9d4b4850fb66fe4deae11
shipit-source-id: f81bd14ccbdba36309b9d4b4850fb66fe4deae11
2016-03-15 05:14:21 -07:00
Zack
025281230d WebSocket: call onclose before closing in event of error
Summary:Motivation: Developer expects `onclose` to be called before/during close of the websocket. The `websocketFailed` event triggers a close but does not invoke onclose.

Testplan: Connect to a websocket server from android, terminate the server, observe that onerror is called, the websocket is closed, but onclose is not called.

Note: the observed bug is in android only because in iOS the underlying websocket implementation fires the `websocketClosed` rather than `websocketFailed` event when the server terminates. Nevertheless, the justification for this change stands that regardless of the cause of the close, if `this.close` is called it is expected this.onclose should be called as well.
Closes https://github.com/facebook/react-native/pull/6307

Differential Revision: D3017458

fb-gh-sync-id: c9e2dfefa597b4e99ee85eaa991667c347f86d83
shipit-source-id: c9e2dfefa597b4e99ee85eaa991667c347f86d83
2016-03-06 15:02:27 -08:00
Pieter De Baets
f9e81d9bcc Fix OSS iOS build
Reviewed By: majak

Differential Revision: D2943923

fb-gh-sync-id: d0a827780ee93a1e702295198c65729b1a72f045
shipit-source-id: d0a827780ee93a1e702295198c65729b1a72f045
2016-02-17 07:38:33 -08:00
Walter Luh
dab24b4a6c Enable persistent socket between packager and bridge (1/N).
Reviewed By: javache

Differential Revision: D2920590

fb-gh-sync-id: 120d812d1e9bcb79b186d3e41e8f7e153ca34f8b
shipit-source-id: 120d812d1e9bcb79b186d3e41e8f7e153ca34f8b
2016-02-16 23:05:36 -08:00
Satyajit Sahoo
8f19f5bef4 Annotate WebSocket with Flow
Reviewed By: svcscm

Differential Revision: D2938267

fb-gh-sync-id: b67623b79327bb78b5fab2ea492925ed20b17c1a
shipit-source-id: b67623b79327bb78b5fab2ea492925ed20b17c1a
2016-02-16 03:29:52 -08:00
Alex Kotliarskyi
64d56f34b7 Improve Chrome debugger
Summary:
`debugger.html` contained a ton of hacky code that was needed to ensure we have a clean JS runtime every time a client RN app connects. That was needed because we used the page's global environment as runtime. Some time ago WebWorker support was added and now we run RN code inside an isolated WebWorker instance, and we can safely get rid of all these hacks.

This has a bunch of nice side-effects: debug reload works faster, `console.log`s are preserved, `debuggerWorker.js` selection doesn't change.

Made sure the debugging (breakpoints, etc.) still works as before.

Small demo
![](http://g.recordit.co/FPdVHLHPUW.gif)
Closes https://github.com/facebook/react-native/pull/5715

Reviewed By: svcscm

Differential Revision: D2906602

Pulled By: frantic

fb-gh-sync-id: 1a6ab9a5655d7c32ddd23619564e59c377b53a35
2016-02-05 15:17:33 -08:00
Jelle van den Hooff
debcac59d0 iOS websocket: include cookies with request
Summary:
This PR modifies the Websocket implementation on iOS to pass cookies to the server. Sending cookies is useful for clients that wish to access protected Websocket endpoints without creating a new authentication protocol.
Closes https://github.com/facebook/react-native/pull/5630

Reviewed By: svcscm

Differential Revision: D2881815

Pulled By: martinbigio

fb-gh-sync-id: 31c1640626cd15447bdb4f2058ae4e34dfa52f88
2016-02-01 14:19:32 -08:00
Andy Prock
9b87e6c860 Added an optional options parameter for WebSockets
Summary:
This enables overriding origin, and other request headers. Similar to the https://github.com/websockets/ws api.
Closes https://github.com/facebook/react-native/pull/4629

Reviewed By: svcscm

Differential Revision: D2839951

Pulled By: mkonicek

fb-gh-sync-id: 3578af4343f90572b8851ff28342a05945498ef6
2016-01-20 11:01:39 -08:00
Martín Bigio
4f37fe6f68 Improve error wording when packager dies and simulator was on debug mode
Reviewed By: jingc

Differential Revision: D2835719

fb-gh-sync-id: 694aac79cd9a76cfac32f7808c3f1bbb85d6bfb0
2016-01-19 16:37:34 -08:00
Philipp von Weitershausen
66158ab2bf Make the RCTSRWebSocketDelegate protocol part of RCTWebSocketModule public
Summary:
This allows consumers to subclass and extend `RCTWebSocketModule` and make use of the `RCTSRWebSocketDelegate` methods.

The use case here is to do some pre-processing of WebSocket data before handing it off to JS. Consumers could that in the following way:

```

interface MyWebSocketModule : RCTWebSocketModule
end

implementation MyWebSocketModule

// Don't use RCT_EXPORT_MODULE macro for this so we replace the existing RCTWebSocketModule.
+ (NSString *)moduleName { return @"RCTWebSocketModule"; }

RCT_EXTERN_METHOD(connect:(NSURL *)URL socketID:(nonnull NSNumber *)socketID)
RCT_EXTERN_METHOD(send:(NSString *)message socketID:(nonnull NSNumber *)socketID)
RCT_EXTERN_METHOD(close:(nonnull NSNumber *)socketID)

- (void)webSocket:(RCTSRWebSocket *)webSocket didReceiveMessage:(id)message
{
  [super webSocket:webSocket didReceiveMessage:[DoSomethingWith message]];
}

end
```

... and then returning a `MyWebSocketModule` ins
Closes https://github.com/facebook/react-native/pull/5321

Reviewed By: svcscm

Differential Revision: D2832374

Pulled By: nicklockwood

fb-gh-sync-id: f208516b2b2f76276223ffc972871d96afe87e27
2016-01-14 16:13:33 -08:00
Martín Bigio
469bb7fbfd Improve error wording when fail to launch debugger
Reviewed By: javache

Differential Revision: D2829484

fb-gh-sync-id: a3402ece1f5cd19e8408fa3ab89adf7a26c66de9
2016-01-14 10:02:34 -08:00
Pieter De Baets
0cfe76399c Improve red boxes coming from RCTWebSocketExecutor
Reviewed By: tadeuzagallo

Differential Revision: D2775452

fb-gh-sync-id: b709e0e725ab76468700466b804237eed9158bfd
2015-12-23 13:32:28 -08:00
Johan Lindskogen
afbff9bf88 Add support for binary type data (ArrayBuffer)
Summary:
Entirely based on https://github.com/facebook/react-native/pull/1829
I just updated the diff to be compatible with the current master branch.
Closes https://github.com/facebook/react-native/pull/4483

Reviewed By: svcscm

Differential Revision: D2783425

Pulled By: nicklockwood

fb-gh-sync-id: 1cc67c0741cff3b071530877d688f6b8c1061e3f
2015-12-23 10:07:37 -08:00
Sebastian Markbage
8d397b4cbc Decouple Module System from Native Calls
Summary:
The JavaScript ecosystem doesn't have the notion of a built-in native module loader. Even Node is decoupled from its module loader. The module loader system is just JS that runs on top of the global `process` object which has all the built-in goodies.

Additionally there is no such thing as a global require. That is something unique to our providesModule system. In other module systems such as node, every require is contextual. Even registered npm names are localized by version.

The only global namespace that is accessible to the host environment is the global object. Normally module systems attaches itself onto the hooks provided by the host environment on the global object.

Currently, we have two forms of dispatch that reaches directly into the module system. executeJSCall which reaches directly into require. Everything now calls through the BatchedBridge module (except one RCTLog edge case that I will fix). I propose that the executors calls directly onto `BatchedBridge` through an instance on the global so that everything is guaranteed to go through it. It becomes the main communication hub.

I also propose that we drop the dynamic requires inside of MessageQueue/BatchBridge and instead have the modules register themselves with the bridge.

executeJSCall was originally modeled after the XHP equivalent. The XHP equivalent was designed that way because the act of doing the call was the thing that defined a dependency on the module from the page. However, that is not how React Native works.

The JS side is driving the dependencies by virtue of requiring new modules and frameworks and the existence of dependencies is driven by the JS side, so this design doesn't make as much sense.

The main driver for this is to be able to introduce a new module system like Prepack's module system. However, it also unlocks the possibility to do dead module elimination even in our current module system. It is currently not possible because we don't know which module might be called from native.

Since the module system now becomes decoupled we could publish all our providesModule modules as npm/CommonJS modules using a rewrite script. That's what React Core does.

That way people could use any CommonJS bundler such as Webpack, Closure Compiler, Rollup or some new innovation to create a JS bundle.

This diff expands the executeJSCalls to the BatchedBridge's three individual pieces to make them first class instead of being dynamic. This removes one layer of abstraction. Hopefully we can also remove more of the things that register themselves with the BatchedBridge (various EventEmitters) and instead have everything go through the public protocol. ReactMethod/RCT_EXPORT_METHOD.

public

Reviewed By: vjeux

Differential Revision: D2717535

fb-gh-sync-id: 70114f05483124f5ac5c4570422bb91a60a727f6
2015-12-08 16:03:37 -08:00
Nick Lockwood
060664fd3d Refactored module access to allow for lazy loading
Summary: public

The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed.

This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead.

The rules are now as follows:

* Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created
* Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but  `constantsToExport:` will still be called on the main thread.
* All other modules will be initialized lazily when a method is first called on them.

These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily.

I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results:

Out of the 65 modules included in UIExplorer:

* 16 are initialized on the main thread when the bridge is created
* A further 8 are initialized when the config is exported to JS
* The remaining 41 will be initialized lazily on-demand

Reviewed By: jspahrsummers

Differential Revision: D2677695

fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 04:49:45 -08:00
Nick Lockwood
fa0b45c58b Replaced RCTSparseArray with NSDictionary
Reviewed By: jspahrsummers

Differential Revision: D2651920

fb-gh-sync-id: 953e2ea33abfc7a3a553da95b13e9ab2bccc5a1c
2015-11-14 10:28:28 -08:00