Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WASM generation test #15

Merged
merged 4 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: CI
on:
pull_request:
push:
branches: [main]
branches: ["**"]
release:
types:
- published
Expand Down Expand Up @@ -38,7 +38,7 @@ jobs:
runs-on: ubuntu-latest

needs: [test]
if: github.event_name != 'pull_request'
if: github.ref == 'refs/heads/main' || github.event_name == 'release'
steps:
- uses: actions/checkout@v4
with:
Expand Down
1 change: 0 additions & 1 deletion project/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ object Settings {
import xerial.sbt.Sonatype
import xerial.sbt.Sonatype.SonatypeKeys.*


project.settings(
inThisBuild(
List(
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/cloud/golem/WasmComponentPluginInternal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private[golem] object WasmComponentPluginInternal {
)
def checkCommandOrFail(command: String)(error: => String): Unit = {
import scala.sys.process.*
val commandExists = Seq("bash", "-xc", s"which $command").! == 0
val commandExists = Seq("sh", "-xc", s"which $command").! == 0
if (!commandExists) sys.error(error)
}
Def.settings(
Expand Down Expand Up @@ -46,7 +46,7 @@ private[golem] object WasmComponentPluginInternal {
""".stripMargin
}
val output = Seq(
"bash",
"sh",
"-xc",
s"$bindGenCommand -w ${wasmComponentWitFullPath.value} -p ${wasmComponentPackageName.value}"
).!!
Expand All @@ -66,8 +66,8 @@ private[golem] object WasmComponentPluginInternal {
""".stripMargin
}

Seq("bash", "-xc", s"$npmCommand install").!!
Seq("bash", "-xc", s"$npmCommand run build").!!
Seq("sh", "-xc", s"$npmCommand install").!!
Seq("sh", "-xc", s"$npmCommand run build").!!
},
wasmComponent := (wasmComponent dependsOn (Compile / fullLinkJS)).value,
Compile / sourceGenerators += Def.taskIf {
Expand Down
4 changes: 0 additions & 4 deletions src/sbt-test/scala-js/example1/test
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
> +fullLinkJS
$ exists target/dist/main.js
$ exists target/dist/main.js.map
$ exists target/dist/main.js
$ exists target/dist/main.js.map
> +clean
> +fastLinkJS
$ exists target/dist/main.js
$ exists target/dist/main.js.map
$ exists target/dist/main.js
$ exists target/dist/main.js.map
4 changes: 0 additions & 4 deletions src/sbt-test/scala-js/example2/test
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
> +fullLinkJS
$ exists target/dist/main.js
$ exists target/dist/main.js.map
$ exists target/dist/main.js
$ exists target/dist/main.js.map
> +clean
> +fastLinkJS
$ exists target/dist/main.js
$ exists target/dist/main.js.map
$ exists target/dist/main.js
$ exists target/dist/main.js.map
7 changes: 7 additions & 0 deletions src/sbt-test/wasm/shopping-cart/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ThisBuild / version := "0.1"
ThisBuild / scalaVersion := "2.13.13"
ThisBuild / crossScalaVersions += "2.12.19"

lazy val root = (project in file("."))
.enablePlugins(WasmComponentPlugin)
.settings(wasmComponentPackageName := "example")
10 changes: 10 additions & 0 deletions src/sbt-test/wasm/shopping-cart/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scripts": {
"build": "jco componentize -w wit -o target/dist/main.wasm target/dist/main.js",
"componentize": "npm run build"
},
"devDependencies": {
"@bytecodealliance/componentize-js": "0.10.2",
"@bytecodealliance/jco": "1.4.0"
}
}
1 change: 1 addition & 0 deletions src/sbt-test/wasm/shopping-cart/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.9.9
7 changes: 7 additions & 0 deletions src/sbt-test/wasm/shopping-cart/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sys.props.get("plugin.version") match {
case Some(version) =>
addSbtPlugin("cloud.golem" % "sbt-wasm-component" % version)
case _ =>
sys.error("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package example

final case class State(userId: String, items: List[ProductItem]) { self =>
def withUserId(userId: String): State = self.copy(userId = userId)

def addItem(item: ProductItem): State = self.copy(items = self.items :+ item)

def removeItem(productId: String): State = self.copy(items = self.items.filterNot(_.productId == productId))

def updateItemQuantity(productId: String, quantity: Integer): State =
self.copy(items = self.items.map { item =>
if (item.productId == productId) ProductItem(item.productId, item.name, item.price, quantity)
else item
})

def clear: State = self.copy(items = List.empty)
}
object State {
val empty = State(userId = "", items = List.empty)
}

@cloud.golem.WitExport
object ShoppingCart extends Api { self =>
private var state = State.empty

def initializeCart(userId: String): WitResult[String, String] = {
println(s"Initializing cart for user $userId")
if (math.random() > 0.1) {
state = state.withUserId(userId)
WitResult.ok(userId)
} else WitResult.err("Error while initializing cart")
}

def addItem(item: ProductItem): Unit = {
println(s"Adding item to the cart of user ${state.userId}")
state = state.addItem(item)
}

def removeItem(productId: String): Unit = {
println(s"Removing item with product ID $productId from the cart of user ${state.userId}")
state = state.removeItem(productId)
}

def updateItemQuantity(productId: String, quantity: Integer): Unit = {
println(s"Updating quantity of item with product ID $productId to $quantity in the cart of user ${state.userId}")

state = state.updateItemQuantity(productId, quantity)
}

def checkout(): CheckoutResult = {
def reserveInventory(): Either[String, Unit] =
if (math.random() < 0.1) Left("Inventory not available") else Right(())

def chargeCreditCard(): Either[String, Unit] = Right(())

def generateOrder(): String = "238738674"

def dispatchOrder(): Either[String, Unit] = Right(())

def clearState(): Unit = state = state.clear

val result =
for {
_ <- reserveInventory()
_ <- chargeCreditCard()
orderId = generateOrder()
_ <- dispatchOrder()
_ = clearState()
_ = println(s"Checkout for order $orderId")
} yield OrderConfirmation(orderId)

result match {
case Right(orderConfirmation) => CheckoutResult.success(orderConfirmation)
case Left(error) => CheckoutResult.error(error)
}
}

def getCartContents(): WitList[ProductItem] = {
println(s"Getting cart contents for user ${state.userId}")
WitList.fromList(state.items)
}

def getFirstItem(): WitOption[ProductItem] = {
println(s"Getting first item for user ${state.userId}")
WitOption.fromOption(state.items.headOption)
}
}
6 changes: 6 additions & 0 deletions src/sbt-test/wasm/shopping-cart/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
> +clean
$ exec cargo install golem-scalajs-wit-bindgen
> +wasmComponent
$ exists target/dist/main.js
$ exists target/dist/main.js.map
$ exists target/dist/main.wasm
37 changes: 37 additions & 0 deletions src/sbt-test/wasm/shopping-cart/wit/example.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package pack:name;

interface api {
record product-item {
product-id: string,
name: string,
price: float32,
quantity: u32,
}

record order-confirmation {
order-id: string,
}

variant checkout-result {
error(string),
success(order-confirmation),
}

initialize-cart: func(user-id: string) -> result<string, string>;

add-item: func(item: product-item) -> ();

remove-item: func(product-id: string) -> ();

update-item-quantity: func(product-id: string, quantity: u32) -> ();

checkout: func() -> checkout-result;

get-cart-contents: func() -> list<product-item>;

get-first-item: func() -> option<product-item>;
}

world main {
export api;
}