Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
stephencelis committed Aug 26, 2024
1 parent 0a293a7 commit c0bdf61
Show file tree
Hide file tree
Showing 23 changed files with 1,301 additions and 0 deletions.
8 changes: 8 additions & 0 deletions 0292-cross-platform-pt3/Counter/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
1 change: 1 addition & 0 deletions 0292-cross-platform-pt3/Counter/.swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wasm-DEVELOPMENT-SNAPSHOT-2024-07-16-a
44 changes: 44 additions & 0 deletions 0292-cross-platform-pt3/Counter/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// swift-tools-version: 6.0

import PackageDescription

let package = Package(
name: "Counter",
platforms: [.iOS(.v16), .macOS(.v14)],
products: [
.library(
name: "Counter",
targets: ["Counter"]
),
],
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.0.0"),
.package(url: "https://github.com/pointfreeco/swift-navigation", from: "2.0.0"),
.package(url: "https://github.com/pointfreeco/swift-perception", from: "1.0.0"),
.package(url: "https://github.com/swiftwasm/carton", from: "1.0.0"),
.package(url: "https://github.com/swiftwasm/JavaScriptKit", exact: "0.19.2"),
],
targets: [
.executableTarget(
name: "WasmApp",
dependencies: [
"Counter",
.product(name: "SwiftNavigation", package: "swift-navigation"),
.product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
.product(name: "JavaScriptKit", package: "JavaScriptKit"),
]
),
.target(
name: "Counter",
dependencies: [
.product(name: "JavaScriptKit", package: "JavaScriptKit", condition: .when(platforms: [.wasi])),
.product(name: "JavaScriptEventLoop", package: "JavaScriptKit", condition: .when(platforms: [.wasi])),
.product(name: "Dependencies", package: "swift-dependencies"),
.product(name: "DependenciesMacros", package: "swift-dependencies"),
.product(name: "SwiftNavigation", package: "swift-navigation"),
.product(name: "Perception", package: "swift-perception")
]
),
],
swiftLanguageVersions: [.v6]
)
53 changes: 53 additions & 0 deletions 0292-cross-platform-pt3/Counter/Sources/Counter/CounterModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Dependencies
import Foundation
import Perception
import SwiftNavigation

@MainActor
@Perceptible
public class CounterModel: HashableObject {
@PerceptionIgnored
@Dependency(FactClient.self) var factClient

public var count = 0 {
didSet {
isTextFocused = !count.isMultiple(of: 3)
}
}
public var fact: Fact?
public var factIsLoading = false
public var isTextFocused = false
public var text = ""

public struct Fact: Identifiable {
public var value: String
public var id: String { value }
}

public init() {}

public func incrementButtonTapped() {
count += 1
fact = nil
}

public func decrementButtonTapped() {
count -= 1
fact = nil
}

public func factButtonTapped() async {
fact = nil
factIsLoading = true
defer { factIsLoading = false }

do {
try await Task.sleep(for: .seconds(1))

var count = count
fact = Fact(value: try await factClient.fetch(count))
} catch {
// TODO: error handling
}
}
}
36 changes: 36 additions & 0 deletions 0292-cross-platform-pt3/Counter/Sources/Counter/FactClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Dependencies
import DependenciesMacros
#if canImport(JavaScriptKit)
@preconcurrency import JavaScriptKit
#endif
#if canImport(JavaScriptEventLoop)
import JavaScriptEventLoop
#endif

@DependencyClient
struct FactClient: Sendable {
var fetch: @Sendable (Int) async throws -> String
}

extension FactClient: TestDependencyKey {
static let testValue = FactClient()
}

extension FactClient: DependencyKey {
static let liveValue = FactClient { number in
#if canImport(JavaScriptKit) && canImport(JavaScriptEventLoop)
let response = try await JSPromise(
JSObject.global.fetch!("http://www.numberapi.com/\(number)").object!
)!.value
return try await JSPromise(response.text().object!)!.value.string!
#else
return try await String(
decoding: URLSession.shared
.data(
from: URL(string: "http://www.numberapi.com/\(number)")!
).0,
as: UTF8.self
)
#endif
}
}
68 changes: 68 additions & 0 deletions 0292-cross-platform-pt3/Counter/Sources/WasmApp/App.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import Counter
import JavaScriptEventLoop
import JavaScriptKit
import SwiftNavigation

@main
@MainActor
struct App {
static var tokens: Set<ObservationToken> = []

static func main() {
JavaScriptEventLoop.installGlobalExecutor()

let model = CounterModel()

let document = JSObject.global.document

var countLabel = document.createElement("span")
_ = document.body.appendChild(countLabel)

var decrementButton = document.createElement("button")
decrementButton.innerText = "-"
decrementButton.onclick = .object(
JSClosure { _ in
model.decrementButtonTapped()
return .undefined
}
)
_ = document.body.appendChild(decrementButton)

var incrementButton = document.createElement("button")
incrementButton.innerText = "+"
incrementButton.onclick = .object(
JSClosure { _ in
model.incrementButtonTapped()
return .undefined
}
)
_ = document.body.appendChild(incrementButton)

var factButton = document.createElement("button")
factButton.innerText = "Get fact"
factButton.onclick = .object(
JSClosure { _ in
Task { await model.factButtonTapped() }
return .undefined
}
)
_ = document.body.appendChild(factButton)


var factLabel = document.createElement("div")
_ = document.body.appendChild(factLabel)

observe {
countLabel.innerText = .string("Count: \(model.count)")

if let fact = model.fact?.value {
factLabel.innerText = .string(fact)
} else if model.factIsLoading {
factLabel.innerText = "Fact is loading..."
} else {
factLabel.innerText = ""
}
}
.store(in: &tokens)
}
}
Loading

0 comments on commit c0bdf61

Please sign in to comment.