このライブラリは、Kotlin/JVM および Kotlin/Native プログラムからの Kotlin/JS ライブラリの使用を合理化します。これにより、データをフェッチするのと同じくらい簡単にコードをフェッチできるようになります。
Zipline は、Kotlin/JVM または Kotlin/Native プログラムに QuickJS JavaScript エンジンを埋め込むことで機能します。これは、アプリケーションへの埋め込みに適した、小型で高速な JavaScript エンジンです。
(Duktape Android をお探しですか?)
ユーザーがアプリを更新しなくても、毎日新鮮な質問が出るトリビア ゲームを作りましょう。 Kotlin/JVM から呼び出して Kotlin/JS に実装できるように、 commonMain
でインターフェイスを定義します。
interface TriviaService : ZiplineService {
fun games (): List < TriviaGame >
fun answer ( questionId : String , answer : String ): AnswerResult
}
次に、これをjsMain
に実装します。
class RealTriviaService : TriviaService {
// ...
}
Kotlin/JS で実行されている実装を Kotlin/JVM で実行されているインターフェイスに接続しましょう。 jsMain
では、実装をバインドするエクスポート関数を定義します。
@JsExport
fun launchZipline () {
val zipline = Zipline .get()
zipline.bind< TriviaService >( " triviaService " , RealTriviaService ())
}
これで、開発サーバーを起動して、JavaScript を要求する実行中のアプリケーションに JavaScript を提供できるようになります。
$ ./gradlew -p samples trivia:trivia-js:serveDevelopmentZipline --info --continuous
この Gradle は 100% に達しないことに注意してください。それは予想通りです。開発サーバーは稼働し続けたいと考えています。また、 --continuous
フラグは、コードが変更されるたびに再コンパイルをトリガーすることにも注意してください。
提供されるアプリケーションのマニフェストは、localhost:8080/manifest.zipline.json で確認できます。アプリケーションのすべてのコード モジュールを参照します。
jvmMain
では、Kotlin/JS コードをダウンロードして呼び出すプログラムを作成する必要があります。コードのダウンロード、キャッシュ、ロードを処理するZiplineLoader
を使用します。 Kotlin/JS を実行するDispatcher
を作成します。各 Zipline インスタンスは単一のスレッドに制限される必要があるため、これはシングルスレッドのディスパッチャーである必要があります。
suspend fun launchZipline ( dispatcher : CoroutineDispatcher ): Zipline {
val manifestUrl = " http://localhost:8080/manifest.zipline.json "
val loader = ZiplineLoader (
dispatcher,
ManifestVerifier . NO_SIGNATURE_CHECKS ,
OkHttpClient (),
)
return loader.loadOnce( " trivia " , manifestUrl)
}
次に、JVM プログラムをビルドして実行して、すべてをまとめます。これは開発サーバーとは別のターミナルで実行してください。
$ ./gradlew -p samples trivia:trivia-host:shadowJar
java -jar samples/trivia/trivia-host/build/libs/trivia-host-all.jar
Zipline を使用すると、Kotlin/JS とのインターフェイスを簡単に共有できます。 commonMain
でインターフェースを定義し、Kotlin/JS で実装して、ホスト プラットフォームから呼び出します。または、その逆を行います。ホスト プラットフォームに実装し、Kotlin/JS から呼び出します。
ブリッジ インターフェイスは、保持されているリソースを解放する単一のclose()
メソッドを定義するZiplineService
を拡張する必要があります。
デフォルトでは、引数と戻り値は値渡しです。 Zipline は、kotlinx.serialization を使用して、境界を越えて渡される値をエンコードおよびデコードします。
ZiplineService
から拡張されたインターフェイス タイプは参照渡しです。受信側はライブ インスタンスのメソッドを呼び出すことができます。
インターフェース機能が停止している可能性があります。 Zipline は内部的にsetTimeout()
を実装し、Kotlin/JS で想定されているとおりに非同期コードを動作させます。
Zipline は、パラメーターまたは戻り値の型としてFlow<T>
もサポートします。これにより、リアクティブ システムの構築が容易になります。
JavaScript を埋め込む際の潜在的なボトルネックの 1 つは、エンジンが入力ソース コードをコンパイルするのを待機していることです。 Zipline は、JavaScript を効率的な QuickJS バイトコードにプリコンパイルして、このパフォーマンス上のペナルティを排除します。
もう 1 つのボトルネックは、コードのダウンロードを待機していることです。 Zipline は、モジュラー アプリケーションのサポートによりこの問題に対処します。各入力モジュール (Kotlin の標準ライブラリ、シリアル化ライブラリ、コルーチン ライブラリなど) は同時にダウンロードされます。ダウンロードされた各モジュールはキャッシュされます。モジュールをホスト アプリケーションに埋め込んで、ネットワークにアクセスできない場合のダウンロードを回避することもできます。アプリケーション モジュールがライブラリよりも頻繁に変更される場合、ユーザーは変更されたもののみをダウンロードします。
QuickJS ランタイムでパフォーマンスの問題が発生した場合、Zipline にはサンプリング プロファイラーが含まれています。これを使用して、アプリケーションが CPU 時間をどのように費やしたかの内訳を取得できます。
Zipline は、ホスト プラットフォームにメッセージを転送することでconsole.log
を実装します。 Android ではandroid.util.Log
、JVM ではjava.util.logging
、Kotlin/Native ではstdout
使用します。
Zipline は、Kotlin ソース マップを QuickJS バイトコードに統合します。プロセスがクラッシュすると、スタックトレースは.kt
ファイルと行番号を出力します。その下に JavaScript があっても、開発者は.js
ファイルを操作する必要はありません。
ブリッジ インターフェイスを使用した後は、ピア オブジェクトをガベージ コレクションできるように、ブリッジ インターフェイスを閉じる必要があります。これを正しく理解するのは難しいため、Zipline は LeakCanary からアイデアを借用し、 close()
呼び出しが失敗したことを積極的に検出します。
Zipline は、ダウンロードされたライブラリを認証するための EdDSA Ed25519 および ECDSA P-256 署名をサポートしています。
セットアップは簡単です。 EdDSA キー ペアを生成します。このためのタスクは、Zipline Gradle プラグインとともにインストールされます。
$ ./gradlew :generateZiplineManifestKeyPairEd25519
...
---------------- ----------------------------------------------------------------
ALGORITHM: Ed25519
PUBLIC KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PRIVATE KEY: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
---------------- ----------------------------------------------------------------
...
秘密キーをビルド サーバーに置き、ビルドに署名するように構成します。
zipline {
signingKeys {
create( " key1 " ) {
privateKeyHex.set( .. .)
algorithmId.set(app.cash.zipline.loader. SignatureAlgorithmId . Ed25519 )
}
}
}
各ホスト アプリケーションに公開キーを配置し、署名を検証するように構成します。
val manifestVerifier = ManifestVerifier . Builder ()
.addEd25519( " key1 " , .. .)
.build()
val loader = ZiplineLoader (
manifestVerifier = manifestVerifier,
.. .
)
署名と検証の両方で、キーのローテーションをサポートするために複数のキーを受け入れます。
Zipline は、組織のコードをいつでもどこでも実行できるように設計されています。サンドボックスやプロセス分離は提供されないため、信頼できないコードの実行には使用しないでください。
この設計では以下に暗黙の信頼が置かれることに留意することが重要です。
上記のいかなる種類の侵害からも保護するものではありません。
また、既知の問題がある古い (署名された) バージョンの実行可能コードを禁止するメカニズムもまだ提供されていません。
ホットリロードが可能な限り高速に実行されるようにするには、いくつかの方法があります。
kotlin.incremental.js.ir=true
を追加して、Kotlin/JS インクリメンタル コンパイルを有効にします。org.gradle.unsafe.configuration-cache=true
を追加して、Gradle 構成キャッシュを有効にします。tasks.withType(DukatTask::class) { enabled = false }
を追加して Dukat タスクをオフにします。Zipline は、Android 4.3 以降 (API レベル 18 以降)、Java 8 以降、Kotlin/ネイティブで動作します。
Zipline は実装に不安定な API を使用しており、これらのコンポーネントのバージョン更新に敏感です。
成分 | サポートされているバージョン | 注意事項 |
---|---|---|
Kotlin コンパイラ | 2.0.0 | Kotlin コンパイラ プラグインにはまだ安定した API がありません。 |
Kotlin のシリアル化 | 1.6.3 | decodeFromDynamic() 、 encodeToDynamic() 、およびContextualSerializer の場合。 |
Kotlin コルーチン | 1.8.1 | transformLatest() 、 Deferred.getCompleted() 、およびCoroutineStart.ATOMIC の場合。 |
安定した API が利用可能になり次第、使用する予定です。
私たちは、Zipline ホストとランタイム リリースの相互運用性を維持し、それぞれを個別にアップグレードできるようにする予定です。
ホスト ジップライン バージョン | サポートされているランタイム ジップラインのバージョン |
---|---|
0.x | ホストとまったく同じ 0.x バージョン。 |
1.x | 任意の 1.x バージョン。 |
Copyright 2015 Square, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
このプロジェクトは以前は Duktape-Android として知られており、Android 用の Duktape JavaScript エンジンをパッケージ化していました。 Duktape の履歴は、リリース タグと同様にこのリポジトリにまだ存在しています。利用可能なバージョンは Maven Central にリストされています。