reactivecocoa / reactiveswift Goto Github PK
View Code? Open in Web Editor NEWStreams of values over time
License: MIT License
Streams of values over time
License: MIT License
Currently, a producer returned from Action.apply()
first sends an event on its observer, then it sends the same event on the action's .events
signal. I wonder if this is by design and if there are any arguments against reversing the order in which the events are sent.
Consider the following example:
class RegisterViewModel {
lazy private(set) var isRegistered: Property<Bool> = {
Property(initial: false, then: self.register.events
.filter { $0 == .completed }
.take(first: 1)
.map { _ in true })
}()
lazy private(set) var login: Action<(),(),NoError> = {
Action(enabledIf: self.isRegistered) {
.empty //login request
}
}()
lazy private(set) var registerAndLogin: Action<(),(),NoError> = Action { [weak self] in
guard let `self` = self else { assertionFailure(); return .empty }
return SignalProducer<(),NoError>.empty //register request
.then(self.login.apply()
.flatMapError { _ in
assertionFailure("we are registered by now, so login should be enabled")
return SignalProducer { observer, _ in observer.sendInterrupted() }
}
)
}
}
//...
//clientCode
viewModel.registerAndLogin.apply().start()
The above code fails on the assertion, because login
is still disabled by the time we start the producer from login.apply()
. This can be remedied by making isRegistered a MutableProperty and setting its value from .on(completed:)
of the register request. However, this approach includes sideeffects and reduces the declarativeness of the code. Reversing the order in which events are sent would fix this code.
Let me know what you think about my example and also any counter examples you can think of. I wonder if it would cause trouble for other people and the way they use Actions. Thanks.
NOTE: I just want to start a discussion, I will gladly create a PR in the future.
A while ago, @andersio shared a gist with me that implemented a replacement for RACSubject
. In essence, it just wraps the tuple returned by Signal<T,E>.pipe()
, but works much nicer in practice.
Here's the gist containing his implementation: https://gist.github.com/andersio/3b4889176d6632bbb637ffd177795815/
Is there a reason that we don't offer this useful construct that we have available in ReactiveObjC? I've never loved the name, personally—calling it a Pipe
would make far more sense—but since I integrated this code into a project I'm working on, life got a lot easier.
Thoughts?
I'm dependent on ReactiveSwift
through Moya
, and I've noticed that carthage update
s hang on Checking out ReactiveSwift
for much longer than expected (1 minute+), it seems as if it's doing something with git-remote-https
? Maybe checking out submodules or something?
I wanted to bring this to the maintainer's attention at the very least, and I was wondering if the checkout process for ReactiveSwift
could be optimized for the next release?
Thanks!
I'm using Xcode version 8.1, Reactive Swift pre-release version 1.0.0 alpha 3, Carthage version 0.11.0, and I don't think this matters but macOS Sierra version 10.12.1.
I have successfully added ReactiveSwift.framework
and Result.framework
to my project as specified in the Getting Started
section. However, when following the first code example on the README of this project, that is:
let searchStrings = textField.rac_textSignal()
.toSignalProducer()
.map { text in text as! String }
I am getting an error on the first line. The error reads:
Value of type 'UITextField' has no member 'rac_textSignal'
When right-clicking on rac_textSignal()
, I am not taken anywhere and thus, I assume that this function has been removed. My implementation is as follows:
let textField = UITextField()
let textSignal = textField.rac_textSignal() {
.toSignalProducer()
.map { text in text as! String }
}
It concerns me that the first example in the README of this project doesn't work so I am hoping that I am just doing something wrong here. Any help would be greatly appreciated, thanks!
I'm reading through the source code, and it looks like the only way to break the retain cycle for a Signal is to remove all of it's observers. So it seems strange to me that the method observe
would be decorated with @discardableResult
. It seems as though if any one of the returned ActionDisposable
results was discarded, a retain cycle would be guaranteed (since there would be no way to remove it from the Bag
of observers). I just wanted to ask if someone might be able to help me understand what's going on here.
Super excited about this project! I was wondering when you're thinking of tagging a release, even an prerelease version. Cheers!
I'm migrating a project from RAC to ReactiveSwift and one of the changes that boggles me a bit is why ScopedDisposable was turned into a generic, I'm just wondering the real world use case where anyone actually needs to explicitly ensure a ScopedDisposable only contains a disposable of X type?
My use case is maybe the outlier but I use ScopeDisposable to make for easy interrupts:
var requestDisposable: ScopedDisposable? = nil
...
func run() {
self.requestDisposable = producer.start()
}
It's frustrating to have to now double wrap these ScopedDisposable(AnyDisposable(producer.start()))
to get the same effect and I'm just struggling to see the use case where anyone is going to grab the innerDisposable
and care what type it is?
Hi,
I am running into a deadlock issue. I’m not entirely sure why it is happening yet. Here is my setup (dumbed down as this is the only part breaking, can provide more if needed).
class ActionController {
var delay: NSTimeInterval = 0.0
let undoable = MutableProperty<Bool>(false)
func start() {
if delay > 0.0 {
undoable.value = true
}
// More stuff
// Eventually will commit once delay is hit
// Can provide more if needed.
}
func undo() {
guard undoable.value else {
return
}
// Do some stuff
/***** DEADLOCK HAPPENS ON LINE BELOW *******/
undoable.value = false
/********************************************/
}
}
class MyViewModel {
private let currentAction = MutableProperty<ActionController?>(nil)
let undoEnabled = MutableProperty<Bool>(false)
init() {
undoEnabled <~ currentAction.producer
.flatMap(.Concat) { action in
guard let action = action else {
return SignalProducer<Bool, NoError>(value: false)
}
return action.undoable.producer
}
.skipRepeats()
}
func commitAction() {
let action = ActionController()
action.delay = 10
action.start()
}
func undoCurrentAction() {
currentAction.value?.undo()
}
func onActionCompleted() {
// Method gets called when ActionController completes
currentAction.value = nil
}
}
Both commitAction()
and undoCurrentAction()
get called from a UIViewController
that the MyViewModel
is powering and has subscribers to undoEnabled
.
Example for testing:
viewModel.undoEnabled.producer.startWithNext { [unowned self] enabled in
if enabled {
self.viewModel.undoCurrentAction()
}
}
The deadlock seems to be happening when calling undo
and setting undoable
’s value
to false
.
I'm probably doing something wrong, but I keep getting build warnings such as "/Path/To/ReactiveCocoa-master/Carthage/Checkouts/ReactiveSwift/ReactiveSwift.xcodeproj The file “iOS-Framework.xcconfig” couldn’t be opened. (/Path/To/ReactiveCocoa-master/Carthage/Checkouts/ReactiveSwift/Carthage/Checkouts/xcconfigs/xcconfigs/iOS/iOS-Framework.xcconfig)"
Before, it was saying that it couldn't be opened because it couldn't resolve the path. I've since resolved those paths in the navigator, and now it just says it doesn't want to open them. I'm getting these in iOS-Framework.xcconfig, Debug.xcconfig, and Release.xcconfig.
Anyone know more than me about these?
Hey there!
I've been struggling for the past few hours to figure this out. I have 2 UITextFields(username and password) and 1 UIButton to login. How do I make it so that if textfields are empty, the button is disabled. And if either 1 of the textfields has some text in it, the button is enabled.
This is as far as I've got:
let textFieldSignals = Signal.merge(
textFieldUserName.reactive.continuousTextValues,
textFieldPassword.reactive.continuousTextValues
)
SignalProducer(signal: textFieldSignals).start() { [weak self] result in
guard let this = self else { return }
let isEnabled = this.textFieldUserName.text!.characters.count > 0 && this.textFieldPassword.text!.characters.count > 0
this.navigationItem.rightBarButtonItem?.isEnabled = isEnabled
}
However, I don't get a signal right away in the block. It only happens when textfields values are changed.
I'm trying to work with the latest 5.0.x version of the ReactiveSwift.
With the new signal lifetime semantics, we can safely express it as a Signal<Notification, NoError>
. Any thoughts on changing it?
The current TimeInterval
APIs are fragile and dangerous for many reasons:
But with Swift 3
we can do better: using DispatchTimeInterval
solves all these problems :)
So I'm proposing deprecating current APIs that use TimeInterval
to point users to use new DispatchTimeInterval
versions.
I noticed that CocoaAction
was removed from ReactiveSwift
. I'm trying to find a way to replace this functionality:
signUpButton.addTarget(viewModel.signUpButtonAction, action: CocoaAction.selector, for: .touchUpInside)
I'm thinking it'd be best to just handle in an @IBAction
and call apply(_:).start()
on the action, but wanted to ask to see if there was a prescribed way to achieve it.
Benchmark Source
#106 + #112 + #107 + #113
SignalProducer
starting & disposing performance.Signal.observers
using read-copy-update. This removes a lock from the critical path of a Signal
, at a cost of more expensive observer insertion.// -Owholemodule
// `signal-state-patch` + `disposable-lockfree` + `lift-fix` + `minor-signal-refactor`
One Observer: 0.026 12%
Eight Observers: 0.042 8%
Producer: 0.326 3%
Producer 2 obv: 0.632 2%
Producer Mixed: 2.038 2%
Start Producer: 1.582 2%
Start & Dispose: 1.581 2%
// `master`
One Observer: 0.018 10%
Eight Observers: 0.053 5%
Producer: 0.223 3%
Producer 2 obv: 0.422 2%
Producer Mixed: 2.090 2%
Start Producer: 1.663 2%
Start & Dispose: 1.683 2%
// Speedup
One Observer: 0.692x ***
Eight Observers: 1.262x
Producer: 0.684x ***
Producer 2 obv: 0.668x ***
Producer Mixed: 1.025x
Start Producer: 1.051x
Start & Dispose: 1.065x
Would it be possible to provide some sort of guidance on when/how to use various aspects of the framework?
Examples on Action
, Lifetime
etc would be helpful a lot for someone who is at the process of learning the framework
Just wonder if we can conform DispatchQueue
(or even OperationQueue
) to the scheduler protocols directly.
These loosen the requirement of serial execution in the Scheduler contract. But then DispatchQueue
is by default serial, and the users should have been aware of any issue should they own the queue.
Hi, i'm getting an infinite loop when doing the following:
let disposable = someProducer.startWithNext ...
let scoped = ScopedDisposable(disposable)
It loops on ScopedDisposable's extensions' init(_ disposable: Disposable)
, which is here: https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Sources/Disposable.swift#L230
This init has the same signature as ScopedDisposable's non-extension init (i'm not sure how this compiles without error), and when the extension calls self.init
it calls the extension init instead of the non-extension init, which causes infinite recursion.
Recommend changing the signature of the extension init to have a named argument, or even remove it? I'm not sure what the need for the extension init is, given that the normal init is fully generic already.
For reference for anyone else having this issue, you can workaround for now with: let scoped = ScopedDisposable(AnyDisposable(disposable))
Thanks
I'm seeing some leaks with ReactiveSwift. I'm using the alpha so wondering if this is known, or if I'm missing something.
Using ReactiveCocoa (5.0.0-alpha.3)
Using ReactiveSwift (1.0.0-alpha.3)
Using Result (3.0.0)
Why does this code leak a Signal?
var disposable = CompositeDisposable()
deinit {
disposable.dispose()
}
@IBAction func load(_ sender: Any) {
disposable += SignalProducer<Void, NSError> { sink, disposable in
disposable.add {
print("dispose")
}
sink.send(value: ())
sink.sendCompleted()
}.startWithCompleted {
print("completed")
}
}
Also a similar example with a Disposable
var disposable: Disposable?
deinit {
disposable?.dispose()
}
disposable = SignalProducer<Void, NSError> { sink, disposable in
sink.send(value: ())
sink.sendCompleted()
}.startWithCompleted {
print("completed")
}
It seems that unsafeCocoaAction
was removed for the obvious reasons, but now it is unclear what to do with the programming of UI. Is there other sub-project with an extension of Action
with unsafeCocoaAction
that should be used for this purpose?
Hi, recently I'm digging around the sources and found these comments in Signal.swift
// Normally we disallow recursive events, but `interrupted` is
// kind of a special snowflake, since it can inadvertently be
// sent by downstream consumers.
//
// So we'll flag Interrupted events specially, and if it
// happened to occur while we're sending something else, we'll
// wait to deliver it.
I understood that .interrupted
is special and doing this prevents undesired deadlocks under certain conditions.
However, these certain conditions, aka when it can inadvertently be sent by downstream consumers
, still remains vague to me.
Can you please provide some actual scenes or explain these comments a little further to help clarifying?
Sorry if the question is naive or the answer to it is obvious.
Thanks.
Hi,
Currently working on a swift 3 migration - when you go to version 1 of RAC5, would you please consider using warnings instead of compile-time errors for deprecated usage such as startWithNext ?
At least until, say, version 5.1 ?
It would make the migration of large codebases to swift 3 much easier.
Thanks a lot.
Should it be made a singleton instead? Say UIScheduler.shared
.
Hi,
RxSwift seems to have a defer
function which is quite useful for implementing backpressure.
So, I was wondering whether ReactiveSwift has any plan to support something similar?
This is just a matter of taste, but observer.sendFailed()
has been renamed to observer.send(error:)
, so I think Event.failed
should be renamed to Event.error
as well (and also other methods like on(failed:)
).
Or, renaming observer.send(error:)
to observer.send(failed:)
improves consistency too.
(I prefer send(error:)
though)
(Ref: ReactiveCocoa/ReactiveCocoa#2959)
Below gist (SignalProducerSpec's "disposal") passed the test in ReactiveCocoa v4.2.2
but not in current ReactiveSwift 1.0.0-alpha.3
.
https://gist.github.com/inamiy/925644779adbfca621ea716770d3865e
It seems innerSignal.on().observe()
is disposed first before on()
receives .interrupted
.
This could be a NEW correct behavior as discussed in ReactiveCocoa/ReactiveCocoa#3075, but if I want to know the interruption of innerSignal
, what should I do?
@andersio and I (with some @sharplet thrown in) had a discussion recently about the ability to bind to an Action
in ReactiveSwift.
My distaste for this feature started when I saw the following code in a test case:
presented.rac.dismissAnimated <~ Property(value: false)
Frankly I don't feel that it's a good idea to enable this sort of use through the API, and I think that the ability to bind an Action to an arbitrary signal seems like a solution looking for a problem.
I'm not against the pattern of an <~
operator showing up in the UI code, but rather I think that it should be limited to binding only "action outlets" to "action inlets", so to speak. To paraphrase a comment from @andersio: "it should work more like IB".
It's possible that I'm in need of some education and examples of where this is useful in practice. I don't use actions all that much in practice outside of the UI case, where controls are being bridged to actions. And in all these cases, I think that my uses may be a bit of a stretch.
So, I say we either pull it, or come with some compelling real-world cases outside of UI code where this holds value.
With SE-0071 in place, catch
and try
can be referenced as members without backticks.
Perhaps times
can also be renamed as repeat
too.
Would it make sense to replace the <~
operator with bind(with:)
, then the api would become
mutableProperty.bind(with: someProducer)
That way the functionality will be discoverable from within Xcode and the user won't have to keep in mind that an operator exists.
Good morning! Lovely library, I see that ReactiveCocoa's new Swift 3 work depends on this project, neat. Would you consider adding CocoaPods support to ReactiveSwift? I would be happy to send a pull request, but wanted to check first. Thanks!
I have some signals. Some from a textfield, and others I have coerced from valuesForKeyPath.
let sig1: Signal<Any?, NoError> = specialBtn.reactive.values(forKeyPath: "isSelected").startSignal()
let sig2: Signal<String, NoError> = textField.reactive.continuousTextValues
wherestartSignal
is really just the internal func startAndRetrieveSignal()
:
extension SignalProducer {
func startSignal() -> Signal<Value, Error> {
var result: Signal<Value, Error>!
startWithSignal { signal, _ in
result = signal
}
return result
}
}
I try to put the above 2 signals into an array, but it complains about the types matching. I know String
conforms to Any
though.
let sigs: [Signal<Any?, NoError>] = [sig1, sig2]
Cannot convert value of type 'Signal<String, NoError>' to expected element type 'Signal<Optional<Any>, NoError>'
How should I aggregate signals that have different types?
@available(*, unavailable, renamed:"SignalProducer.combineLatest")
public func combineLatest<S: Sequence, Value, Error>(producers: S) -> SignalProducer<[Value], Error> where S.Iterator.Element == SignalProducer<Value, Error> { fatalError() }
Should have (_ producers: S)
instead of (producers: S)
, otherwise instead of 'combineLatest' has been renamed to 'SignalProducer.combineLatest'
Xcode shows confusing Argument labels '(_:)' do not match any available overloads
.
Probably there are other cases like this.
Pre-Swift 3 a func like skipWhile(_ condition: () -> Bool)
would be, well.. that. And thus usage would be .skipWhile { ... }
– terse yet clear at call site.
Now it's skip(while condition: () -> Bool)
per Swift 3 naming practices, rendering usage either .skip(while: { .. })
(losing crispness of trailing closure) or .skip { .. }
(losing info). The latter wouldn't even be usable if a skip(until condition: () -> Bool)
func were introduced because of the ambiguity.
Is anyone else concerned?
Hi,
Does the DynamicProperty be removed? My Xcode shows Use of unresolved identifier 'DynamicProperty'
for all lines with DynamicProperty.
I wonder how to observe the value change and bind with view model now? Thanks
searchResults.observe { event in
switch event {
case let .value(results):
print("Search results: \(results)")
case let .error(error):
print("Search error: \(error)")
case .completed, .interrupted:
break
}
}
Notice the case let .error have been change to case let .failed, please update the README.md.
"Extensible enum" based API.
producer.start(.all) { event in }
producer.start(.values) { value in }
producer.start(.results) { result in }
producer.start(.completed) {}
producer.start(.interrupted) {}
producer.start(.failed) { error in }
// default value: .all
producer.start { event in }
Signal
for With
being wiped from SignalProducer.start
.Well probably keeping things as is would be better, heh. But similar tricks using static members can be considered too, e.g.
// Static method on `Observer`.
producer.start(.values { value in })
Unless the default value is anything but .all
, the existing observe*
and start*
can be marked as deprecated and gracefully fade out without name clashes.
Hi, I'm porting a project using ReactiveCocoa to ReactiveSwift. I can't find rac_textSignal, what should be used instead?
Just got inspired from ReactiveCocoa/ReactiveObjC#51, I think we can add FlattenStrategy.first
where multiple producers race and winner forwards all the events after they get flatten
ed.
Diagram: http://reactivex.io/documentation/operators/amb.html
I think this can be useful in some scenario (though I have never used it before).
I have a very simple object that performs network requests and lazily replays them. What I would love to do is expire the underlying cache/buffer after a certain time so it will perform the work again on next start
. Is there a RACy way of doing this? Currently I manage the expiry using state in my object by comparing to a stored date and recreating the lazily replayed SignalProducer
again, but would love to do away with this state entirely if possible!
Thanks
This has all spawned from @sharplet's #22.
Action
is based on RAC 2's RACCommand
, which is itself based on ReactiveUI's ReactiveCommand
. The model was originally created to model UI actions—which are serial and occur on the main thread. But Action
was meant to be decoupled from this dependency. The RAC 3 changelog says:
Unlike commands, actions are not bound to or dependent upon the main thread, making it easier to reason about when they can be executed and when they will generate notifications.
I think this is incomplete: Action
s aren't truly thread safe.
The enabledIf
property is one of the key features of actions. However, that property is inherently racey with the body of the action itself. If the property is altered on a different thread/scheduler, it can switch to false
after Action
checks the value but before the body of the action executes. You can't trust that the world hasn't changed in the execute closure.
RACCommand
and ReactiveUI's ReactiveCommand
don't suffer from this issue because they're tied to the main thread. Altering the world on a background thread is prohibited.
I think we should do something to address this: either explicitly document this limitation or modify Action
so that it's truly thread safe and reactive.
One we could achieve the later would be to base Action
's inputs on signals. Currently, Action
s often read external properties (i.e. state), rather than relying solely on their input. In the typical login example, the login action would read the username and password properties directly from the view model:
class LoginViewModel {
let username = Property<String>()
let password = Property<String>()
let action: Action<(), (), LoginError>
init() {
let enabled = Property
.combineLatest(username, password)
.map { !$0.isEmpty && !$1.isEmpty }
action = Action(enabledIf: enabled) { _ in
let username = self.username // These could be empty, even though they should be disabled
let password = self.password // The perils of reading state
…
}
}
}
// elsewhere
loginViewModel.action.apply(())
But actions could be restructured like so:
class LoginViewModel {
let username = Property<String>()
let password = Property<String>()
let action: Action<(), LoginError> // input type isn't part of the type
init() {
let input = Property.combineLatest(username, password)
action = Action(input, enabledIf: { !$0.isEmpty && !$1.isEmpty }) { (username, password) in
…
}
}
}
// elsewhere
loginViewModel.action.apply()
This would have a few benefits that I see:
enabledIf
and execute
apply()
can easily be bound to a trigger signalAction
s become usable only in the reactive modelBut this does require (1) removing the input type from Action
and (2) removing the input parameter from apply()
. (2) could be especially problematic, depending on how people are currently using Action
. But in the standard bind-this-action-to-a-button case, this model seems like it would be simpler.
I'm curious what people think. @ReactiveCocoa/reactiveswift
“Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choose a Swift version or use the Build Settings editor to configure the build setting directly.
After converting to Swift 3 Build Failed and additional 58 errors are coming see below image.
Also mention is there any thing to import after pod install to use this library.
I have the following snippet of code:
SignalProducer<Int, NSError>(value: 15)
.on(starting: {
print("starting")
})
.on(started: {
print("started")
})
.on(value: { _ in
print("value")
})
.on(failed: { _ in
print("failed")
})
.on(completed: {
print("completed")
})
.start()
That prints the following results on the console
starting
value
completed
started
Shouldn't the output be
starting
started
value
completed
instead?
The same thing happens when the producer
fails.
Hi, I'm trying to figure out the best way to model behavior similar to
class Object {
private(set) var property: Type
func sideEffects() {
property = newValue()
}
}
when a function has side effects changing the value of the property
.
The main goal of this exercise is to expose a readonly property that is modified from within the object using ReactiveSwift. My current setup looks like this:
class Object {
let property: MutableProperty<Type>
func sideEffects() {
property.value = newValue()
}
}
but that also allows changing property value from the outside of the object, e.g. object.property.value = newUnexpectedValue()
which is what I want to avoid.
Thank you!
I use Carthage,but only has two files.
ReactiveSwift-Swift.h
@import Foundation;
@interface NSNotificationCenter (SWIFT_EXTENSION(ReactiveSwift))
@EnD
@interface NSURLSession (SWIFT_EXTENSION(ReactiveSwift))
@EnD
ReactiveSwift.h
//! Project version number for ReactiveSwift.
FOUNDATION_EXPORT double ReactiveSwiftVersionNumber;
//! Project version string for ReactiveSwift.
FOUNDATION_EXPORT const unsigned char ReactiveSwiftVersionString[];
I'm seeing a deadlock in a binding from a signal to a mutable property. Here's the relevant part of the stack trace:
(2) and (19) are the same signal, hitting the recursive send. Here's the current implementation of <~
:
public static func <~ <Source: SignalProtocol>(target: Self, signal: Source) -> Disposable? where Source.Value == Value, Source.Error == NoError {
return signal
.take(during: target.lifetime)
.observeValues { [weak target] value in
target?.consume(value)
}
}
I think what's happening is:
observeValues
block is called with the valuetarget
, which has gone out of scope, the target's deinit
gets calledlifetime.ended
to completetake(during:)
, the signal immediately tries to complete (lifetime has ended)Unfortunately I haven't been able to write a test case that reproduces this.
It would be nice to be able to add custom reactive
extensions to types that are outside the scope of ReactiveSwift. The only way to achieve that currently is to declare an accessible initializer in the consuming module that can assign base
since the current initializer is marked as fileprivate
.
What do you think about adding deferred
(from Rex) to SignalProducer
?
In my current project I have a 3-step process where the output of each signal producer becomes the input of the next. This process should externally behave like a single atomic operation, essentially a state machine. If any step fails, then retrying the process should start again from the failed step, but use the cached output from previously successful steps.
I'd really like to use replayLazily()
for this, but can't because it will also replay failures. I haven't been able to work out a way to compose existing operators to get the semantics I'm looking for.
Is this something that could use a new operator? Is there a way I can get this with existing operators?
I kind of want replayLazily
, only failure events should invalidate the cache instead of being replayed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.