Scala standard library implementation for Scala.js, providing core library functionality for Scala code compiled to JavaScript
—
General-purpose utility classes for common programming tasks, adapted for JavaScript environment constraints while maintaining full Scala API compatibility.
Thread-local-like variable support adapted for JavaScript's single-threaded environment, providing scoped value binding for functional programming patterns.
/**
* Variable with dynamic scope binding
* In JavaScript, provides stack-based scoping without true thread-local storage
* Values are scoped to execution context rather than threads
*/
class DynamicVariable[T](init: T) {
/** Get current value */
def value: T
/** Set new value */
def value_=(newval: T): Unit
/** Execute block with temporarily bound value */
def withValue[S](newval: T)(thunk: => S): S
/** String representation */
override def toString: String = s"DynamicVariable($value)"
}
object DynamicVariable {
/** Create DynamicVariable with initial value */
def apply[T](init: T): DynamicVariable[T] = new DynamicVariable(init)
}Usage Examples:
import scala.util.DynamicVariable
// Configuration context
val currentUser = new DynamicVariable[String]("anonymous")
def getGreeting(): String = s"Hello, ${currentUser.value}!"
// Default behavior
println(getGreeting()) // "Hello, anonymous!"
// Scoped value binding
currentUser.withValue("Alice") {
println(getGreeting()) // "Hello, Alice!"
// Nested scoping
currentUser.withValue("Bob") {
println(getGreeting()) // "Hello, Bob!"
}
println(getGreeting()) // "Hello, Alice!" (restored)
}
println(getGreeting()) // "Hello, anonymous!" (original value)
// Logging context example
val logLevel = new DynamicVariable[String]("INFO")
def log(message: String): Unit = {
println(s"[${logLevel.value}] $message")
}
def processData(): Unit = {
log("Starting data processing")
logLevel.withValue("DEBUG") {
log("Detailed processing steps")
log("More debug information")
}
log("Data processing complete")
}
processData()
// Output:
// [INFO] Starting data processing
// [DEBUG] Detailed processing steps
// [DEBUG] More debug information
// [INFO] Data processing complete
// Database transaction context
val transactionId = new DynamicVariable[Option[String]](None)
def executeQuery(sql: String): Unit = {
val txId = transactionId.value.getOrElse("no-transaction")
println(s"[$txId] Executing: $sql")
}
def withTransaction[T](block: => T): T = {
val txId = java.util.UUID.randomUUID().toString.take(8)
transactionId.withValue(Some(txId)) {
println(s"[$txId] Starting transaction")
val result = block
println(s"[$txId] Committing transaction")
result
}
}
withTransaction {
executeQuery("SELECT * FROM users")
executeQuery("UPDATE users SET active = true")
}Advanced enumeration functionality with custom values, ordering, and serialization support.
/**
* Extended enumeration with additional utility methods
*/
abstract class Enumeration {
/** Type alias for enumeration values */
type Value = EnumerationValue
/** Set containing all enumeration values */
def values: ValueSet
/** Get value by ID */
def apply(x: Int): Value
/** Try to get value by name */
def withName(s: String): Value
/** Iterator over all values */
def iterator: Iterator[Value]
/** Maximum ID used */
def maxId: Int
/** Next available ID */
protected var nextId: Int = 0
/** Create value with auto-assigned ID */
protected final def Value: Value = Value(nextId)
/** Create value with specific ID */
protected final def Value(i: Int): Value = Value(i, null)
/** Create value with name and auto-assigned ID */
protected final def Value(name: String): Value = Value(nextId, name)
/** Create value with specific ID and name */
protected final def Value(i: Int, name: String): Value
/**
* Individual enumeration value
*/
protected class Val(i: Int, name: String) extends EnumerationValue {
def id: Int = i
override def toString(): String = if (name != null) name else s"$$name"
}
/**
* Set of enumeration values with efficient operations
*/
class ValueSet extends Set[Value] {
def contains(elem: Value): Boolean
def +(elem: Value): ValueSet
def -(elem: Value): ValueSet
def iterator: Iterator[Value]
def size: Int
}
}Usage Examples:
// HTTP Status enumeration
object HttpStatus extends Enumeration {
type HttpStatus = Value
val Ok = Value(200, "OK")
val Created = Value(201, "Created")
val BadRequest = Value(400, "Bad Request")
val NotFound = Value(404, "Not Found")
val InternalServerError = Value(500, "Internal Server Error")
}
// Using HTTP status
def handleResponse(status: HttpStatus.Value): String = status match {
case HttpStatus.Ok => "Request successful"
case HttpStatus.Created => "Resource created"
case HttpStatus.BadRequest => "Invalid request"
case HttpStatus.NotFound => "Resource not found"
case HttpStatus.InternalServerError => "Server error"
case _ => s"Unknown status: $status"
}
// Lookup by name and ID
val status1 = HttpStatus.withName("OK")
val status2 = HttpStatus(404)
println(s"Status: ${status1.id} - ${status1}")
println(s"Status: ${status2.id} - ${status2}")
// Iterate over all values
println("All HTTP statuses:")
for (status <- HttpStatus.values) {
println(s" ${status.id}: $status")
}
// Priority enumeration with ordering
object Priority extends Enumeration {
type Priority = Value
val Low = Value(1, "Low")
val Medium = Value(5, "Medium")
val High = Value(10, "High")
val Critical = Value(20, "Critical")
implicit val ordering: Ordering[Priority] = Ordering.by(_.id)
}
// Using priority with ordering
val tasks = List(
("Fix bug", Priority.High),
("Write docs", Priority.Low),
("Security patch", Priority.Critical),
("Refactor", Priority.Medium)
)
val sortedTasks = tasks.sortBy(_._2)
println("Tasks by priority:")
sortedTasks.foreach { case (task, priority) =>
println(s" [$priority] $task")
}
// State machine enumeration
object ConnectionState extends Enumeration {
type State = Value
val Disconnected, Connecting, Connected, Reconnecting, Failed = Value
def canTransitionTo(from: State, to: State): Boolean = (from, to) match {
case (Disconnected, Connecting) => true
case (Connecting, Connected | Failed) => true
case (Connected, Disconnected | Reconnecting) => true
case (Reconnecting, Connected | Failed) => true
case (Failed, Connecting) => true
case _ => false
}
}
// State transition validation
def changeState(current: ConnectionState.State, next: ConnectionState.State): Unit = {
if (ConnectionState.canTransitionTo(current, next)) {
println(s"State changed: $current -> $next")
} else {
println(s"Invalid transition: $current -> $next")
}
}
changeState(ConnectionState.Disconnected, ConnectionState.Connecting) // Valid
changeState(ConnectionState.Connected, ConnectionState.Failed) // InvalidException handling and control flow abstractions for robust error management.
/**
* Utility object for control flow operations
*/
object control {
/**
* Exception for non-local returns and control flow
*/
class ControlThrowable extends Throwable {
override def fillInStackTrace(): Throwable = this
}
/**
* Break exception for loop control
*/
class BreakControl extends ControlThrowable
/**
* Provides break functionality for loops
*/
object Breaks {
private val breakException = new BreakControl
/** Execute block with break support */
def breakable(op: => Unit): Unit = {
try {
op
} catch {
case _: BreakControl => // Expected break
}
}
/** Break out of enclosing breakable block */
def break(): Nothing = throw breakException
}
/**
* Exception handling utilities
*/
object Exception {
/** Catch exceptions and convert to Option */
def allCatch[T]: Catch[T] = new Catch[T](classOf[Throwable])
/** Catch specific exception types */
def catching[T](exceptions: Class[_]*): Catch[T] =
new Catch[T](exceptions: _*)
/** Ignore specific exceptions */
def ignoring(exceptions: Class[_]*): Catch[Unit] =
catching(exceptions: _*).opt.map(_ => ())
}
/**
* Exception catching utility
*/
class Catch[+T](exceptions: Class[_]*) {
/** Convert exceptions to Option */
def opt[U >: T](body: => U): Option[U] = {
try Some(body)
catch { case ex if exceptions.exists(_.isInstance(ex)) => None }
}
/** Provide default value on exception */
def either[U >: T](body: => U): Either[Throwable, U] = {
try Right(body)
catch { case ex if exceptions.exists(_.isInstance(ex)) => Left(ex) }
}
/** Apply recovery function on exception */
def recover[U >: T](pf: PartialFunction[Throwable, U])(body: => U): U = {
try body
catch {
case ex if exceptions.exists(_.isInstance(ex)) && pf.isDefinedAt(ex) => pf(ex)
}
}
}
}Usage Examples:
import scala.util.control._
// Break support for loops
import Breaks._
def findFirstNegative(numbers: List[Int]): Option[Int] = {
var result: Option[Int] = None
breakable {
for (num <- numbers) {
if (num < 0) {
result = Some(num)
break() // Exit loop early
}
}
}
result
}
val numbers = List(1, 2, 3, -4, 5, -6)
println(findFirstNegative(numbers)) // Some(-4)
// Exception handling with allCatch
def parseNumber(s: String): Option[Int] = {
Exception.allCatch.opt(s.toInt)
}
println(parseNumber("123")) // Some(123)
println(parseNumber("invalid")) // None
// Specific exception catching
def safeDivide(a: Int, b: Int): Either[String, Int] = {
Exception.catching(classOf[ArithmeticException]).either(a / b) match {
case Left(ex) => Left(s"Division error: ${ex.getMessage}")
case Right(result) => Right(result)
}
}
println(safeDivide(10, 2)) // Right(5)
println(safeDivide(10, 0)) // Left("Division error: / by zero")
// Recovery with partial function
def robustOperation(input: String): String = {
Exception.allCatch.recover {
case _: NumberFormatException => "Invalid number format"
case _: NullPointerException => "Null input"
case ex => s"Unexpected error: ${ex.getMessage}"
} {
val number = input.toInt
(number * 2).toString
}
}
println(robustOperation("5")) // "10"
println(robustOperation("invalid")) // "Invalid number format"
println(robustOperation(null)) // "Null input"
// Ignoring specific exceptions
def attemptRiskyOperation(): Unit = {
Exception.ignoring(classOf[RuntimeException]) {
// This might throw RuntimeException, but we'll ignore it
if (scala.util.Random.nextBoolean()) {
throw new RuntimeException("Random failure")
}
println("Operation succeeded")
}
}
// Resource management pattern
def withResource[R <: { def close(): Unit }, T](resource: R)(block: R => T): T = {
try {
block(resource)
} finally {
Exception.ignoring(classOf[Exception]) {
resource.close()
}
}
}
// Usage with file-like resource
case class MockFile(name: String) {
def read(): String = s"Contents of $name"
def close(): Unit = println(s"Closed $name")
}
val result = withResource(MockFile("test.txt")) { file =>
file.read()
}
println(result) // "Contents of test.txt"
// Automatically prints: "Closed test.txt"Install with Tessl CLI
npx tessl i tessl/maven-org-scala-js--scalajs-scalalib-2-13