Generate SSD truth seeding async flow from typed Jerboa

ober

5fe8031abcfe90bdac6181294498250665838995

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 2a77b7f..cacac5a 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4873,6 +4873,7 @@
                 truthStoreImportZipArchive
                 truthStoreSyncTreeCounts
                 truthStorePullRemoteTruthCount
+                truthStoreSeedBundledTruthAsync
                 truthStoreLoadTruthForSession
                 ssdBrowserResumeReady focusChangeShouldShowDropdown
                 dialogReadyToShowDropdown focusedDialogReadyToShowDropdown
@@ -5252,10 +5253,16 @@
           (kotlin-member-call appendEvent))
         (extern (truthStoreStorageSummaryRaw (store : TruthStore)) : String
           (kotlin-member-call storageSummary))
-        (extern (truthStoreSeedBundledTruthAsyncRaw
+        (extern (truthStoreSeedStartedRaw
+                  (store : TruthStore)) : Bool
+          (kotlin-member-get seedStarted))
+        (extern (truthStoreSeedStartedSetRaw
                   (store : TruthStore)
-                  (done : (-> Int32 Unit))) : Unit
-          (kotlin-member-call seedBundledTruthAsync))
+                  (started : Bool)) : Unit
+          (kotlin-member-set seedStarted))
+        (extern (truthStoreSeedBundledTruthRaw
+                  (store : TruthStore)) : Int32
+          (kotlin-member-call seedBundledTruth))
         (extern (truthStoreSaveTruthSnapshot
                   (store : TruthStore)
                   (truth : JSONObject)) : File
@@ -6473,7 +6480,7 @@
         (def (mainActivitySeedBundledTruthAsync
                (activity : MainActivity)
                (store : TruthStore)) : Unit
-          (truthStoreSeedBundledTruthAsyncRaw
+          (truthStoreSeedBundledTruthAsync
             store
             (lambda ((imported : Int32))
               (if (positiveCount imported)
@@ -6570,6 +6577,18 @@
                (store : TruthStore)
                (session : SsdSession)) : Int32
           (truthStorePullRemoteTruthRaw store session))
+        (def (truthStoreSeedBundledTruthAsync
+               (store : TruthStore)
+               (done : (-> Int32 Unit))) : Unit
+          (if (truthStoreSeedStartedRaw store)
+              (begin)
+              (begin
+                (truthStoreSeedStartedSetRaw store #t)
+                (runBackground
+                  (lambda ()
+                    (let ((imported
+                            (truthStoreSeedBundledTruthRaw store)))
+                      (invoke done imported)))))))
         (def (truthStoreLoadTruthForSession
                (store : TruthStore)
                (session : SsdSession)) : (Nullable JSONObject)
@@ -11311,7 +11330,7 @@
        "    private val eventsDir = File(root, \"events\")"
        "    private val reviewsDir = File(root, \"reviews\")"
        "    private val remoteConfig: RemoteConfig? by lazy { loadRemoteConfig() }"
-       "    @Volatile private var seedStarted = false"
+       "    @Volatile internal var seedStarted = false"
        "    @Volatile private var truthIndexCacheLoaded = false"
        "    @Volatile private var truthIndexCache: List<TruthIndexEntry> = emptyList()"
        ""
@@ -11909,12 +11928,7 @@
        "    }"
        ""
        "    fun seedBundledTruthAsync(done: (Int) -> Unit) {"
-       "        if (seedStarted) return"
-       "        seedStarted = true"
-       "        thread(name = \"sfb-seed-truth\") {"
-       "            val imported = seedBundledTruth()"
-       "            done(imported)"
-       "        }"
+       "        truthStoreSeedBundledTruthAsync(this, done)"
        "    }"
        ""
        "    private fun rebuildLearnedExamples() {"
@@ -11938,7 +11952,7 @@
        "        atomicWriteText(containedLeaf(learnedDir, learnedExamplesFileName()), learned.toString(2))"
        "    }"
        ""
-       "    private fun seedBundledTruth(): Int {"
+       "    internal fun seedBundledTruth(): Int {"
        "        return try {"
        "            context.assets.open(\"seed_ssd_review.zip\").use { importZip(it) }"
        "        } catch (_: Exception) {"