basic idb storage working

This commit is contained in:
Julian 2025-06-27 01:36:17 -07:00
parent b32a3f7862
commit f74a0aa4c1
7 changed files with 4470 additions and 133 deletions

View file

@ -2,13 +2,27 @@ import org.scalajs.linker.interface.ModuleSplitStyle
lazy val fahrtenbuch = project
.in(file("."))
.enablePlugins(ScalaJSPlugin) // Enable the Scala.js plugin in this project
.enablePlugins(
ScalaJSPlugin,
ScalablyTypedConverterExternalNpmPlugin
)
.settings(
scalaVersion := "3.7.1",
// Tell Scala.js that this is an application with a main method
scalaJSUseMainModuleInitializer := true,
// scalably typed config
// Ignore several Trystero dependencies in ScalablyTyped to avoid `stImport` errors
stIgnore := List(
"libp2p",
"firebase",
"@supabase/supabase-js",
"@mdi/font",
"bulma"
),
externalNpm := baseDirectory.value,
/* Configure Scala.js to emit modules in the optimal way to
* connect to Vite's incremental reload.
* - emit ECMAScript modules
@ -28,5 +42,6 @@ lazy val fahrtenbuch = project
*/
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.8.0",
libraryDependencies += "com.raquo" %%% "laminar" % "17.2.1",
libraryDependencies += "de.tu-darmstadt.stg" %%% "rdts" % "0.37.0"
libraryDependencies += "de.tu-darmstadt.stg" %%% "rdts" % "0.37.0",
libraryDependencies += "org.getshaka" %%% "native-converter" % "0.9.0"
)

4506
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -10,10 +10,13 @@
},
"devDependencies": {
"@scala-js/vite-plugin-scalajs": "^1.0.0",
"vite": "^4.1.0"
"typescript": "^4.9.5",
"vite": "^6.2.3"
},
"dependencies": {
"@mdi/font": "^7.4.47",
"bulma": "^1.0.4"
"bulma": "^1.0.4",
"dexie": "^4.0.10",
"trystero": "^0.21.0-beta.1"
}
}

View file

@ -1 +1,2 @@
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.19.0")
addSbtPlugin("org.scalablytyped.converter" % "sbt-converter" % "1.0.0-beta44")

View file

@ -0,0 +1,44 @@
package fahrtenbuch
import org.scalablytyped.runtime.StringDictionary
import typings.dexie.mod.Dexie
import scala.concurrent.Future
import typings.dexie.mod.{Table, liveQuery}
import scala.scalajs.js
import org.getshaka.nativeconverter.NativeConverter
import scala.concurrent.ExecutionContext.Implicits.global
import typings.dexie.mod.Observable
object DexieDB {
private val schemaVersion = 1.0
private val dexieDB: Dexie = new Dexie.^("fahrtenbuch")
dexieDB
.version(schemaVersion)
.stores(
StringDictionary(
("entries", "id")
)
)
private val entriesTable: Table[js.Any, String, js.Any] =
dexieDB.table("entries")
val entriesObservable: Observable[Future[Seq[Entry]]] =
liveQuery(() => getAllEntries())
def insertEntry(entry: Entry): Future[Any] = {
println(s"inserting Entry $entry")
entriesTable.put(entry.toNative).toFuture
}
def getAllEntries(): Future[Seq[Entry]] = {
entriesTable.toArray().toFuture.map { entriesJsArray =>
entriesJsArray
.map(
NativeConverter[Entry].fromNative(_)
)
.toSeq
}
}
}

View file

@ -9,6 +9,10 @@ import com.raquo.laminar.nodes.ReactiveHtmlElement
import fahrtenbuch.Main.editClickBus
import scala.annotation.threadUnsafe
import fahrtenbuch.Main.entryEditBus
import org.getshaka.nativeconverter.NativeConverter
import fahrtenbuch.Main.entryPrinter
import org.getshaka.nativeconverter.ParseState
import scala.scalajs.js
case class EntryComponent(
entry: Entry,
@ -49,6 +53,7 @@ case class EntryComponent(
)
)
},
entryEditBus.stream --> entryPrinter,
span(
cls := "icon edit",
i(cls := "mdi mdi-18px mdi-check-bold")
@ -84,10 +89,19 @@ case class Entry(
paid: Boolean,
driver: String,
date: Option[Date] = None
):
) derives NativeConverter:
val distance = endKm - startKm
// 13 cent pro km, 5 cent Abnutzung
def costGas: Double = distance * 0.13
def costWear: Double = distance * 0.05
def costTotal: Double = costGas + costWear
object Entry:
given NativeConverter[Uid] with {
extension (a: Uid)
override def toNative: js.Any =
a.delegate
override def fromNative(ps: ParseState): Uid =
Uid.predefined(ps.json.asInstanceOf[String])
}

View file

@ -32,10 +32,20 @@ object Main {
// track changes to entries
val entryEditBus = new EventBus[Entry]
val entryObserver =
Observer[Entry](onNext = DexieDB.insertEntry(_))
val entryPrinter =
Observer[Entry](onNext = entry => println(entry))
// entryEditBus --> entryObserver
// entryEditBus --> entryPrinter
entryEditBus.stream.tapEach(_ => println("lalilu"))
println("test")
val allEntries = entryEditBus.stream.foldLeft(Map.empty[Uid, Entry]) {
case (acc, entry) =>
acc + (entry.id -> entry)
}
entryEditBus.stream.addObserver(entryObserver)(using unsafeWindowOwner)
val entryComponents: Signal[List[EntryComponent]] =
allEntries