Skip to content

Commit 643f8af

Browse files
committed
Merge remote-tracking branch 'origin/main' into sync-progress
2 parents 290b306 + 664596b commit 643f8af

File tree

39 files changed

+568
-74
lines changed

39 files changed

+568
-74
lines changed

.github/workflows/docs-deploy.yml

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Deploy Docs
2+
3+
on:
4+
push:
5+
branches: [ 'main' ]
6+
7+
permissions:
8+
contents: read
9+
pages: write
10+
id-token: write
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Validate Gradle Wrapper
18+
uses: gradle/wrapper-validation-action@v1
19+
- uses: actions/cache@v3
20+
with:
21+
path: ~/.konan
22+
key: ${{ runner.os }}-${{ hashFiles('**/.lock') }}
23+
- name: Set up JDK 17
24+
uses: actions/setup-java@v3
25+
with:
26+
java-version: '17'
27+
distribution: 'temurin'
28+
- name: Set up Gradle
29+
uses: gradle/actions/setup-gradle@v4
30+
- name: Build Docs
31+
run: |
32+
./gradlew \
33+
-PGITHUB_PUBLISH_TOKEN=${{ secrets.GITHUB_TOKEN }} \
34+
dokkaGenerate
35+
shell: bash
36+
- name: Upload static files as artifact
37+
id: deployment
38+
uses: actions/upload-pages-artifact@v3
39+
with:
40+
path: build/dokka/html
41+
42+
# Deployment job
43+
deploy:
44+
environment:
45+
name: github-pages
46+
url: ${{ steps.deployment.outputs.page_url }}
47+
runs-on: ubuntu-latest
48+
needs: build
49+
steps:
50+
- name: Deploy to GitHub Pages
51+
id: deployment
52+
uses: actions/deploy-pages@v4

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
* Report real-time progress information about downloads through `SyncStatus.downloadProgress`.
66
* Compose: Add `composeState()` extension method on `SyncStatus`.
77

8+
## 1.0.0-BETA32
9+
10+
* Added `onChange` method to the PowerSync client. This allows for observing table changes.
11+
* Removed unnecessary `User-Id` header from internal PowerSync service requests.
12+
* Fix loading native PowerSync extension for Java targets.
13+
814
## 1.0.0-BETA31
915

1016
* Added helpers for Attachment syncing.

README.md

-3
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@ Current limitations:
4747

4848
- Integration with SQLDelight schema and API generation (ORM) is not yet supported.
4949

50-
Future work/ideas:
51-
- Attachments helper package.
52-
5350
## Installation
5451

5552
Add the PowerSync Kotlin Multiplatform SDK to your project by adding the following to your `build.gradle.kts` file:

build.gradle.kts

+61-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import com.sun.net.httpserver.HttpExchange
2+
import com.sun.net.httpserver.HttpServer
3+
import java.net.InetSocketAddress
4+
import java.net.URLDecoder
5+
import java.nio.file.Files
6+
17
plugins {
28
alias(libs.plugins.jetbrainsCompose) apply false
39
alias(libs.plugins.compose.compiler) apply false
@@ -16,6 +22,8 @@ plugins {
1622
alias(libs.plugins.kotlinter) apply false
1723
alias(libs.plugins.keeper) apply false
1824
alias(libs.plugins.kotlin.atomicfu) apply false
25+
id("org.jetbrains.dokka") version libs.versions.dokkaBase
26+
id("dokka-convention")
1927
}
2028

2129
allprojects {
@@ -54,6 +62,58 @@ subprojects {
5462
version = LIBRARY_VERSION
5563
}
5664

57-
tasks.register<Delete>("clean") {
65+
tasks.getByName<Delete>("clean") {
5866
delete(rootProject.layout.buildDirectory)
5967
}
68+
69+
// Merges individual module docs into a single HTML output
70+
dependencies {
71+
dokka(project(":core:"))
72+
dokka(project(":connectors:supabase"))
73+
dokka(project(":compose:"))
74+
}
75+
76+
dokka {
77+
moduleName.set("PowerSync Kotlin")
78+
}
79+
80+
// Serve the generated Dokka documentation using a simple HTTP server
81+
// File changes are not watched here
82+
tasks.register("serveDokka") {
83+
group = "dokka"
84+
dependsOn("dokkaGenerate")
85+
doLast {
86+
val server = HttpServer.create(InetSocketAddress(0), 0)
87+
val root = file("build/dokka/html")
88+
89+
val handler =
90+
com.sun.net.httpserver.HttpHandler { exchange: HttpExchange ->
91+
val rawPath = exchange.requestURI.path
92+
val cleanPath = URLDecoder.decode(rawPath.removePrefix("/"), "UTF-8")
93+
val requestedFile = File(root, cleanPath)
94+
95+
val file =
96+
when {
97+
requestedFile.exists() && !requestedFile.isDirectory -> requestedFile
98+
else -> File(root, "index.html") // fallback
99+
}
100+
101+
val contentType =
102+
Files.probeContentType(file.toPath()) ?: "application/octet-stream"
103+
val bytes = file.readBytes()
104+
exchange.responseHeaders.add("Content-Type", contentType)
105+
exchange.sendResponseHeaders(200, bytes.size.toLong())
106+
exchange.responseBody.use { it.write(bytes) }
107+
}
108+
109+
server.createContext("/", handler)
110+
server.executor = null
111+
server.start()
112+
113+
println("📘 Serving Dokka docs at http://localhost:${server.address.port}/")
114+
println("Press Ctrl+C to stop.")
115+
116+
// Keep the task alive
117+
Thread.currentThread().join()
118+
}
119+
}

compose/build.gradle.kts

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ plugins {
88
alias(libs.plugins.compose.compiler)
99
alias(libs.plugins.kotlinter)
1010
id("com.powersync.plugins.sonatype")
11+
id("dokka-convention")
1112
}
1213

1314
kotlin {
@@ -45,3 +46,7 @@ android {
4546
}
4647

4748
setupGithubRepository()
49+
50+
dokka {
51+
moduleName.set("PowerSync Compose")
52+
}

connectors/supabase/build.gradle.kts

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ plugins {
88
alias(libs.plugins.androidLibrary)
99
alias(libs.plugins.kotlinter)
1010
id("com.powersync.plugins.sonatype")
11+
id("dokka-convention")
1112
}
1213

1314
kotlin {
@@ -51,3 +52,7 @@ android {
5152
}
5253

5354
setupGithubRepository()
55+
56+
dokka {
57+
moduleName.set("PowerSync Supabase Connector")
58+
}

connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt

-2
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,9 @@ public class SupabaseConnector(
164164

165165
check(session.user != null) { "No user data" }
166166

167-
// userId is for debugging purposes only
168167
PowerSyncCredentials(
169168
endpoint = powerSyncEndpoint,
170169
token = session.accessToken, // Use the access token to authenticate against PowerSync
171-
userId = session.user!!.id,
172170
)
173171
}
174172

core/build.gradle.kts

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ plugins {
1919
id("com.powersync.plugins.sharedbuild")
2020
alias(libs.plugins.mokkery)
2121
alias(libs.plugins.kotlin.atomicfu)
22+
id("dokka-convention")
2223
}
2324

2425
val binariesFolder = project.layout.buildDirectory.dir("binaries/desktop")
@@ -298,3 +299,7 @@ tasks.withType<KotlinTest> {
298299
}
299300
}
300301
setupGithubRepository()
302+
303+
dokka {
304+
moduleName.set("PowerSync Core")
305+
}
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
2-
public actual object BuildConfig {
3-
public actual val isDebug: Boolean
2+
internal actual object BuildConfig {
3+
actual val isDebug: Boolean
44
get() = com.powersync.BuildConfig.DEBUG
55
}

core/src/appleMain/kotlin/BuildConfig.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import kotlin.experimental.ExperimentalNativeApi
22
import kotlin.native.Platform
33

44
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
5-
public actual object BuildConfig {
5+
internal actual object BuildConfig {
66
@OptIn(ExperimentalNativeApi::class)
7-
public actual val isDebug: Boolean = Platform.isDebugBinary
7+
actual val isDebug: Boolean = Platform.isDebugBinary
88
}

core/src/commonIntegrationTest/kotlin/com/powersync/DatabaseTest.kt

+31-3
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,25 @@ class DatabaseTest {
183183
}
184184
}
185185

186+
@Test
187+
fun testTableChangesUpdates() =
188+
databaseTest {
189+
turbineScope {
190+
val query = database.onChange(tables = setOf("users")).testIn(this)
191+
192+
database.execute(
193+
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
194+
listOf("Test", "test@example.org"),
195+
)
196+
197+
val changeSet = query.awaitItem()
198+
changeSet.count() shouldBe 1
199+
changeSet.contains("users") shouldBe true
200+
201+
query.cancel()
202+
}
203+
}
204+
186205
@Test
187206
fun testClosingReadPool() =
188207
databaseTest {
@@ -373,11 +392,20 @@ class DatabaseTest {
373392
@Test
374393
fun testCrudTransaction() =
375394
databaseTest {
376-
database.execute("INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)", listOf("a", "a@example.org"))
395+
database.execute(
396+
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
397+
listOf("a", "a@example.org"),
398+
)
377399

378400
database.writeTransaction {
379-
it.execute("INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)", listOf("b", "b@example.org"))
380-
it.execute("INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)", listOf("c", "c@example.org"))
401+
it.execute(
402+
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
403+
listOf("b", "b@example.org"),
404+
)
405+
it.execute(
406+
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
407+
listOf("c", "c@example.org"),
408+
)
381409
}
382410

383411
var transaction = database.getNextCrudTransaction()

core/src/commonIntegrationTest/kotlin/com/powersync/testutils/TestUtils.kt

-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ internal class ActiveDatabaseTest(
100100
everySuspend { getCredentialsCached() } returns
101101
PowerSyncCredentials(
102102
token = "test-token",
103-
userId = "test-user",
104103
endpoint = "https://test.com",
105104
)
106105

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
2-
public expect object BuildConfig {
3-
public val isDebug: Boolean
2+
internal expect object BuildConfig {
3+
val isDebug: Boolean
44
}

core/src/commonMain/kotlin/com/powersync/connectors/PowerSyncCredentials.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ public data class PowerSyncCredentials(
1919
/**
2020
* User ID.
2121
*/
22-
@SerialName("user_id") val userId: String?,
22+
@Deprecated(
23+
message = "This property is no longer used and should be removed.",
24+
level = DeprecationLevel.WARNING,
25+
)
26+
@SerialName("user_id")
27+
val userId: String? = null,
2328
) {
2429
override fun toString(): String = "PowerSyncCredentials<endpoint: $endpoint userId: $userId>"
2530

core/src/commonMain/kotlin/com/powersync/db/PowerSyncDatabaseImpl.kt

+12-1
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,21 @@ internal class PowerSyncDatabaseImpl(
335335
return internalDb.getOptional(sql, parameters, mapper)
336336
}
337337

338+
override fun onChange(
339+
tables: Set<String>,
340+
throttleMs: Long,
341+
): Flow<Set<String>> =
342+
flow {
343+
waitReady()
344+
emitAll(
345+
internalDb.onChange(tables, throttleMs),
346+
)
347+
}
348+
338349
override fun <RowType : Any> watch(
339350
sql: String,
340351
parameters: List<Any?>?,
341-
throttleMs: Long?,
352+
throttleMs: Long,
342353
mapper: (SqlCursor) -> RowType,
343354
): Flow<List<RowType>> =
344355
flow {

0 commit comments

Comments
 (0)