diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0eb3b05
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+###############
+# macOS
+###############
+.DS_Store
+
+###############
+# Xcode / SPM
+###############
+/.build
+/Packages
+/*.xcodeproj
+xcuserdata/
+
+###############
+# CocoaPods
+###############
+Pods/
+
+###############
+# Carthage
+##############
+Carthage
+Carthage/Checkouts
+Carthage/Build
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..706eede
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5f74fe1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Thibault Wittemberg (thibault.wittemberg@gmail.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..dd788c5
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,28 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "Spin.Swift",
+ products: [
+ // Products define the executables and libraries produced by a package, and make them visible to other packages.
+ .library(
+ name: "Spin.Swift",
+ targets: ["Spin.Swift"]),
+ ],
+ dependencies: [
+ // Dependencies declare other packages that this package depends on.
+ // .package(url: /* package url */, from: "1.0.0"),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+ // Targets can depend on other targets in this package, and on products in packages which this package depends on.
+ .target(
+ name: "Spin.Swift",
+ dependencies: []),
+ .testTarget(
+ name: "Spin.SwiftTests",
+ dependencies: ["Spin.Swift"]),
+ ]
+)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..155b7b2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# Spin.swift
+
+**Spin** aims to provide a versatile Feedback Loop implementation working with the three main reactive frameworks available in the Swift community:
+
+* Combine ([https://developer.apple.com/documentation/combine]())
+* RxSwift ([https://github.com/ReactiveX/RxSwift]())
+* ReactiveSwift ([https://github.com/ReactiveCocoa/ReactiveSwift]())
+
+**Spin** offers a unified syntax whatever the underlying reactive framework you choose to use.
+
+**Spin** allows to build a Feedback Loop very easily either using a builder pattern, or using a declarative "SwiftUI like" syntax.
+
+```swift
+Spinner
+ .from(initialState: State.loading(planet: planet))
+ .add(feedback: ReactiveFeedback(feedback: loadFeedback, on: QueueScheduler()))
+ .add(feedback: ReactiveFeedback(uiFeedbacks: renderStateFeedback, emitActionFeedback, on: UIScheduler()))
+ .reduce(with: ReactiveReducer(reducer: reducer))
+```
+
+or
+
+```swift
+var spin: ReactiveSpin {
+ ReactiveSpin(initialState: State.loading(planet: planet),
+ reducer: ReactiveReducer(reducer: reducer)) {
+ ReactiveFeedback(feedback: loadFeedback).execute(on: QueueScheduler())
+ ReactiveFeedback(uiFeedbacks: renderStateFeedback, emitActionFeedback).execute(on: UIScheduler())
+ }
+}
+```
+
+
\ No newline at end of file
diff --git a/Sources/Spin.Swift/Spin_Swift.swift b/Sources/Spin.Swift/Spin_Swift.swift
new file mode 100644
index 0000000..3a473a6
--- /dev/null
+++ b/Sources/Spin.Swift/Spin_Swift.swift
@@ -0,0 +1,3 @@
+struct Spin_Swift {
+ var text = "Hello, World!"
+}
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
new file mode 100644
index 0000000..ba137a0
--- /dev/null
+++ b/Tests/LinuxMain.swift
@@ -0,0 +1,7 @@
+import XCTest
+
+import Spin_SwiftTests
+
+var tests = [XCTestCaseEntry]()
+tests += Spin_SwiftTests.allTests()
+XCTMain(tests)
diff --git a/Tests/Spin.SwiftTests/Spin_SwiftTests.swift b/Tests/Spin.SwiftTests/Spin_SwiftTests.swift
new file mode 100644
index 0000000..70df113
--- /dev/null
+++ b/Tests/Spin.SwiftTests/Spin_SwiftTests.swift
@@ -0,0 +1,15 @@
+import XCTest
+@testable import Spin_Swift
+
+final class Spin_SwiftTests: XCTestCase {
+ func testExample() {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct
+ // results.
+ XCTAssertEqual(Spin_Swift().text, "Hello, World!")
+ }
+
+ static var allTests = [
+ ("testExample", testExample),
+ ]
+}
diff --git a/Tests/Spin.SwiftTests/XCTestManifests.swift b/Tests/Spin.SwiftTests/XCTestManifests.swift
new file mode 100644
index 0000000..9b40046
--- /dev/null
+++ b/Tests/Spin.SwiftTests/XCTestManifests.swift
@@ -0,0 +1,9 @@
+import XCTest
+
+#if !canImport(ObjectiveC)
+public func allTests() -> [XCTestCaseEntry] {
+ return [
+ testCase(Spin_SwiftTests.allTests),
+ ]
+}
+#endif