Skip to content

Commit 8b33b5f

Browse files
committed
Initial commit
0 parents  commit 8b33b5f

File tree

20 files changed

+2234
-0
lines changed

20 files changed

+2234
-0
lines changed

.gitattributes

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# https://help.github.com/articles/dealing-with-line-endings/
3+
#
4+
# Linux start script should use lf
5+
/gradlew text eol=lf
6+
7+
# These are Windows script files and should use crlf
8+
*.bat text eol=crlf
9+
10+
# Binary files should be left untouched
11+
*.jar binary
12+

.github/workflows/build.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- synchronize
8+
- reopened
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/setup-go@v5
16+
with:
17+
go-version: '1.25.0'
18+
cache: false
19+
- uses: actions/setup-java@v4
20+
with:
21+
distribution: 'temurin'
22+
java-version: 21
23+
- uses: gradle/actions/setup-gradle@v4
24+
- run: ./gradlew build
25+
- uses: actions/upload-artifact@v4
26+
if: failure()
27+
with:
28+
name: build-reports
29+
path: '**/build/reports/**/*'

.github/workflows/publish.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Publish to Maven Central
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
env:
12+
GROUP_ID: dev.datastar.kotlin
13+
ARTIFACT_ID: kotlin-sdk
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-java@v4
18+
with:
19+
distribution: 'temurin'
20+
java-version: 21
21+
- uses: gradle/actions/setup-gradle@v4
22+
23+
- name: Set version from release
24+
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
25+
26+
- name: Package
27+
run: >
28+
./gradlew clean build -x check
29+
-PgroupId=${{ env.GROUP_ID }}
30+
-PartifactId=${{ env.ARTIFACT_ID }}
31+
-Pversion=${{ env.VERSION }}
32+
33+
- name: Stage Artifacts
34+
run: >
35+
./gradlew publish --no-configuration-cache
36+
-PgroupId=${{ env.GROUP_ID }}
37+
-PartifactId=${{ env.ARTIFACT_ID }}
38+
-Pversion=${{ env.VERSION }}
39+
40+
- name: Publish to Maven Central
41+
run: >
42+
./gradlew jreleaserDeploy --no-configuration-cache
43+
-PgroupId=${{ env.GROUP_ID }}
44+
-PartifactId=${{ env.ARTIFACT_ID }}
45+
-Pversion=${{ env.VERSION }}
46+
47+
env:
48+
JRELEASER_MAVENCENTRAL_USERNAME: ${{ secrets.MAVEN_USERNAME }}
49+
JRELEASER_MAVENCENTRAL_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
50+
JRELEASER_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
51+
JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
52+
JRELEASER_GPG_SECRET_KEY: ${{ secrets.GPG_PRIVATE_KEY }}

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Ignore Gradle project-specific cache directory
2+
.gradle
3+
4+
# Ignore Gradle build output directory
5+
build
6+
7+
.idea
8+
9+
out
10+
11+
.kotlin

LICENSE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright © Star Federation
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Datastar Kotlin SDK
2+
3+
A Kotlin SDK for Datastar!
4+
5+
- No dependencies, just the standard Kotlin library!
6+
- 100% Kotlin, no Java dependencies!
7+
- Multiplatform!
8+
- Framework-agnostic, adapt to your own context and framework!
9+
10+
## Getting Started
11+
12+
### Minimum Requirements
13+
14+
The minimum JVM version compatible is **Java 21**.
15+
16+
### Add the dependency
17+
18+
#### Gradle
19+
20+
```kotlin
21+
dependencies {
22+
implementation("dev.datastar.kotlin:kotlin-sdk:...")
23+
}
24+
```
25+
26+
#### Maven
27+
28+
```xml
29+
30+
<dependency>
31+
<groupId>dev.datastar.kotlin</groupId>
32+
<artifactId>kotlin-sdk</artifactId>
33+
<version>...</version>
34+
</dependency>
35+
```
36+
37+
### Usage
38+
39+
The SDK offers APIs to abstract the Datastar protocol while allowing you to adapt it to your own context and framework.
40+
41+
The following shows a simple implementation base of the Java `HttpServer`.
42+
43+
```kotlin
44+
45+
val server = HttpServer.create(
46+
InetSocketAddress(8080), // Port used
47+
0, // Backlog, 0 means default
48+
"/", // Path
49+
{ exchange -> // Exchange handler
50+
51+
// The `readSignals` method extracts the signals from the request.
52+
// If you use a web framework, you likely don't need this since the framework probably already handles this in its own way.
53+
// However, this method in the SDK allows you to provide your own unmarshalling strategy so you can adapt it to your preferred technology!
54+
val request: Request = adaptRequest(exchange)
55+
val signals = readSignals<EventsWrapper>(request, jsonUnmarshaller)
56+
57+
// Connect a Datastar SSE generator to the response.
58+
val response: Response = adaptResponse(exchange)
59+
val generator = ServerSentEventGenerator(response)
60+
61+
62+
// Below are some simple examples of how to use the generator.
63+
generator.patchElements(
64+
elements = "<div>Merge</div>",
65+
)
66+
67+
generator.patchSignals(
68+
signals =
69+
"""
70+
{
71+
"one":1,
72+
"two":2
73+
}
74+
""".trimIndent(),
75+
)
76+
77+
generator.executeScript(
78+
script = "alert('Hello World!')",
79+
)
80+
81+
exchange.close()
82+
}
83+
)
84+
85+
fun adaptRequest(exchange: HttpExchange): Request = object : Request {
86+
override fun bodyString() = exchange.requestBody.use { it.readAllBytes().decodeToString() }
87+
88+
override fun isGet() = exchange.requestMethod == "GET"
89+
90+
override fun readParam(string: String) =
91+
exchange.requestURI.query
92+
?.let { URLDecoder.decode(it, Charsets.UTF_8) }
93+
?.split("&")
94+
?.find { it.startsWith("$string=") }
95+
?.substringAfter("=")!!
96+
}
97+
98+
fun adaptResponse(exchange: HttpExchange): Response = object : Response {
99+
100+
override fun sendConnectionHeaders(
101+
status: Int,
102+
headers: Map<String, List<String>>,
103+
) {
104+
exchange.responseHeaders.putAll(headers)
105+
exchange.sendResponseHeaders(status, 0)
106+
}
107+
108+
override fun write(text: String) {
109+
exchange.responseBody.write(text.toByteArray())
110+
}
111+
112+
override fun flush() {
113+
exchange.responseBody.flush()
114+
}
115+
116+
}
117+
```

gradle.properties

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
org.gradle.configuration-cache=true
2+
org.gradle.caching=true
3+
# Datastar
4+
datastar.test-suite.version=a7adbacbc9c1a3b27707d7cceba3c02a3f81a86c
5+
groupId=dev.datastar.kotlin
6+
artifactId=kotlin-sdk
7+
version=1.0.0-SNAPSHOT

gradle/libs.versions.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[versions]
2+
junit-jupiter = "5.12.1"
3+
kotlin = "2.2.0"
4+
kotest = "5.9.1"
5+
ktlint = "1.7.1"
6+
7+
[libraries]
8+
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }
9+
kotlin-serialization-jvm = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.9.0" }
10+
kotest-assertions = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
11+
12+
[plugins]
13+
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
14+
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
15+
spotless = { id = "com.diffplug.spotless", version = "7.2.1" }
16+
kover = { id = "org.jetbrains.kotlinx.kover", version = "0.9.1" }
17+
jreleaser = { id = "org.jreleaser", version = "1.19.0" }
18+
19+
[bundles]
20+
kotest = ["kotest-assertions"]

gradle/wrapper/gradle-wrapper.jar

44.4 KB
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
6+
zipStoreBase=GRADLE_USER_HOME
7+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)