@dvai-bridge/capacitor-mediapipe 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,108 +1,108 @@
1
- package co.deepvoiceai.bridge.mediapipe
2
-
3
- import co.deepvoiceai.bridge.mediapipe.core.PluginState
4
- import com.getcapacitor.JSObject
5
- import com.getcapacitor.Plugin
6
- import com.getcapacitor.PluginCall
7
- import com.getcapacitor.PluginMethod
8
- import com.getcapacitor.annotation.CapacitorPlugin
9
- import kotlinx.coroutines.CoroutineScope
10
- import kotlinx.coroutines.Dispatchers
11
- import kotlinx.coroutines.SupervisorJob
12
- import kotlinx.coroutines.cancel
13
- import kotlinx.coroutines.launch
14
-
15
- @CapacitorPlugin(name = "DVAIBridgeMediaPipe")
16
- class DVAIBridgeMediaPipePlugin : Plugin() {
17
- private val state = PluginState()
18
- private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
19
-
20
- override fun handleOnDestroy() {
21
- super.handleOnDestroy()
22
- scope.cancel()
23
- }
24
-
25
- @PluginMethod
26
- fun start(call: PluginCall) {
27
- scope.launch {
28
- notifyListeners("progress", JSObject().apply { put("phase", "load") })
29
- try {
30
- val result = state.start(call.data.toAnyMap(), context)
31
- notifyListeners("progress", JSObject().apply { put("phase", "ready") })
32
- call.resolve(result.toJSObject())
33
- } catch (e: Exception) {
34
- notifyListeners("progress", JSObject().apply {
35
- put("phase", "error")
36
- put("message", e.message ?: "Start failed")
37
- })
38
- call.reject(e.message ?: "Start failed", e)
39
- }
40
- }
41
- }
42
-
43
- @PluginMethod
44
- fun stop(call: PluginCall) {
45
- scope.launch {
46
- try {
47
- state.stop()
48
- call.resolve()
49
- } catch (e: Exception) {
50
- call.reject(e.message ?: "Stop failed", e)
51
- }
52
- }
53
- }
54
-
55
- @PluginMethod
56
- fun status(call: PluginCall) {
57
- call.resolve(state.statusInfo().toJSObject())
58
- }
59
-
60
- // For the MediaPipe backend, model lifecycle is the user's job (we don't
61
- // ship a downloader in Phase 1). These methods reject. A thin downloader
62
- // wrapper may land later.
63
-
64
- @PluginMethod
65
- fun downloadModel(call: PluginCall) {
66
- call.reject(
67
- "downloadModel is not implemented for MediaPipe backend in Phase 1. " +
68
- "Place .task files in the app's filesDir manually."
69
- )
70
- }
71
-
72
- @PluginMethod
73
- fun listCachedModels(call: PluginCall) {
74
- val ret = JSObject()
75
- ret.put("models", emptyList<Any>())
76
- call.resolve(ret)
77
- }
78
-
79
- @PluginMethod
80
- fun deleteCachedModel(call: PluginCall) {
81
- call.reject("deleteCachedModel is not implemented for MediaPipe backend in Phase 1.")
82
- }
83
-
84
- @PluginMethod
85
- fun cacheDir(call: PluginCall) {
86
- call.reject("cacheDir is not implemented for MediaPipe backend in Phase 1.")
87
- }
88
-
89
- // ---- JSObject <-> Map translation helpers ----
90
-
91
- private fun JSObject.toAnyMap(): Map<String, Any?> {
92
- val out = mutableMapOf<String, Any?>()
93
- val it = keys()
94
- while (it.hasNext()) {
95
- val k = it.next()
96
- out[k] = this.opt(k)
97
- }
98
- return out
99
- }
100
-
101
- private fun Map<String, Any?>.toJSObject(): JSObject {
102
- val obj = JSObject()
103
- for ((k, v) in this) {
104
- if (v != null) obj.put(k, v)
105
- }
106
- return obj
107
- }
108
- }
1
+ package co.deepvoiceai.bridge.mediapipe
2
+
3
+ import co.deepvoiceai.bridge.mediapipe.core.PluginState
4
+ import com.getcapacitor.JSObject
5
+ import com.getcapacitor.Plugin
6
+ import com.getcapacitor.PluginCall
7
+ import com.getcapacitor.PluginMethod
8
+ import com.getcapacitor.annotation.CapacitorPlugin
9
+ import kotlinx.coroutines.CoroutineScope
10
+ import kotlinx.coroutines.Dispatchers
11
+ import kotlinx.coroutines.SupervisorJob
12
+ import kotlinx.coroutines.cancel
13
+ import kotlinx.coroutines.launch
14
+
15
+ @CapacitorPlugin(name = "DVAIBridgeMediaPipe")
16
+ class DVAIBridgeMediaPipePlugin : Plugin() {
17
+ private val state = PluginState()
18
+ private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
19
+
20
+ override fun handleOnDestroy() {
21
+ super.handleOnDestroy()
22
+ scope.cancel()
23
+ }
24
+
25
+ @PluginMethod
26
+ fun start(call: PluginCall) {
27
+ scope.launch {
28
+ notifyListeners("progress", JSObject().apply { put("phase", "load") })
29
+ try {
30
+ val result = state.start(call.data.toAnyMap(), context)
31
+ notifyListeners("progress", JSObject().apply { put("phase", "ready") })
32
+ call.resolve(result.toJSObject())
33
+ } catch (e: Exception) {
34
+ notifyListeners("progress", JSObject().apply {
35
+ put("phase", "error")
36
+ put("message", e.message ?: "Start failed")
37
+ })
38
+ call.reject(e.message ?: "Start failed", e)
39
+ }
40
+ }
41
+ }
42
+
43
+ @PluginMethod
44
+ fun stop(call: PluginCall) {
45
+ scope.launch {
46
+ try {
47
+ state.stop()
48
+ call.resolve()
49
+ } catch (e: Exception) {
50
+ call.reject(e.message ?: "Stop failed", e)
51
+ }
52
+ }
53
+ }
54
+
55
+ @PluginMethod
56
+ fun status(call: PluginCall) {
57
+ call.resolve(state.statusInfo().toJSObject())
58
+ }
59
+
60
+ // For the MediaPipe backend, model lifecycle is the user's job (we don't
61
+ // ship a downloader in Phase 1). These methods reject. A thin downloader
62
+ // wrapper may land later.
63
+
64
+ @PluginMethod
65
+ fun downloadModel(call: PluginCall) {
66
+ call.reject(
67
+ "downloadModel is not implemented for MediaPipe backend in Phase 1. " +
68
+ "Place .task files in the app's filesDir manually."
69
+ )
70
+ }
71
+
72
+ @PluginMethod
73
+ fun listCachedModels(call: PluginCall) {
74
+ val ret = JSObject()
75
+ ret.put("models", emptyList<Any>())
76
+ call.resolve(ret)
77
+ }
78
+
79
+ @PluginMethod
80
+ fun deleteCachedModel(call: PluginCall) {
81
+ call.reject("deleteCachedModel is not implemented for MediaPipe backend in Phase 1.")
82
+ }
83
+
84
+ @PluginMethod
85
+ fun cacheDir(call: PluginCall) {
86
+ call.reject("cacheDir is not implemented for MediaPipe backend in Phase 1.")
87
+ }
88
+
89
+ // ---- JSObject <-> Map translation helpers ----
90
+
91
+ private fun JSObject.toAnyMap(): Map<String, Any?> {
92
+ val out = mutableMapOf<String, Any?>()
93
+ val it = keys()
94
+ while (it.hasNext()) {
95
+ val k = it.next()
96
+ out[k] = this.opt(k)
97
+ }
98
+ return out
99
+ }
100
+
101
+ private fun Map<String, Any?>.toJSObject(): JSObject {
102
+ val obj = JSObject()
103
+ for ((k, v) in this) {
104
+ if (v != null) obj.put(k, v)
105
+ }
106
+ return obj
107
+ }
108
+ }
@@ -1,21 +1,21 @@
1
- package co.deepvoiceai.bridge.mediapipe
2
-
3
- import co.deepvoiceai.bridge.shared.core.HandlerContext
4
- import org.junit.Assert.assertNotNull
5
- import org.junit.Test
6
-
7
- class SmokeTest {
8
- @Test
9
- fun pluginClassExists() {
10
- assertNotNull(DVAIBridgeMediaPipePlugin::class.java)
11
- }
12
-
13
- @Test
14
- fun handlerContextDataClassExists() {
15
- // HandlerContext now lives in shared-core (Phase 3D Task 2); this
16
- // confirms the wrapper still resolves it transitively through the
17
- // mediapipe-core project dependency.
18
- val ctx = HandlerContext(modelId = "test", backendName = "mediapipe")
19
- assertNotNull(ctx)
20
- }
21
- }
1
+ package co.deepvoiceai.bridge.mediapipe
2
+
3
+ import co.deepvoiceai.bridge.shared.core.HandlerContext
4
+ import org.junit.Assert.assertNotNull
5
+ import org.junit.Test
6
+
7
+ class SmokeTest {
8
+ @Test
9
+ fun pluginClassExists() {
10
+ assertNotNull(DVAIBridgeMediaPipePlugin::class.java)
11
+ }
12
+
13
+ @Test
14
+ fun handlerContextDataClassExists() {
15
+ // HandlerContext now lives in shared-core (Phase 3D Task 2); this
16
+ // confirms the wrapper still resolves it transitively through the
17
+ // mediapipe-core project dependency.
18
+ val ctx = HandlerContext(modelId = "test", backendName = "mediapipe")
19
+ assertNotNull(ctx)
20
+ }
21
+ }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\r\nimport type { NativePluginInterface } from \"@dvai-bridge/capacitor\";\r\n\r\nconst DVAIBridgeMediaPipe = registerPlugin<NativePluginInterface>(\"DVAIBridgeMediaPipe\");\r\n\r\nexport default DVAIBridgeMediaPipe;\r\nexport { DVAIBridgeMediaPipe };\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA+B;AAG/B,IAAM,0BAAsB,4BAAsC,qBAAqB;AAEvF,IAAO,gBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\nimport type { NativePluginInterface } from \"@dvai-bridge/capacitor\";\n\nconst DVAIBridgeMediaPipe = registerPlugin<NativePluginInterface>(\"DVAIBridgeMediaPipe\");\n\nexport default DVAIBridgeMediaPipe;\nexport { DVAIBridgeMediaPipe };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA+B;AAG/B,IAAM,0BAAsB,4BAAsC,qBAAqB;AAEvF,IAAO,gBAAQ;","names":[]}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\r\nimport type { NativePluginInterface } from \"@dvai-bridge/capacitor\";\r\n\r\nconst DVAIBridgeMediaPipe = registerPlugin<NativePluginInterface>(\"DVAIBridgeMediaPipe\");\r\n\r\nexport default DVAIBridgeMediaPipe;\r\nexport { DVAIBridgeMediaPipe };\r\n"],"mappings":";AAAA,SAAS,sBAAsB;AAG/B,IAAM,sBAAsB,eAAsC,qBAAqB;AAEvF,IAAO,gBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\nimport type { NativePluginInterface } from \"@dvai-bridge/capacitor\";\n\nconst DVAIBridgeMediaPipe = registerPlugin<NativePluginInterface>(\"DVAIBridgeMediaPipe\");\n\nexport default DVAIBridgeMediaPipe;\nexport { DVAIBridgeMediaPipe };\n"],"mappings":";AAAA,SAAS,sBAAsB;AAG/B,IAAM,sBAAsB,eAAsC,qBAAqB;AAEvF,IAAO,gBAAQ;","names":[]}
package/ios/Package.swift CHANGED
@@ -1,33 +1,38 @@
1
- // swift-tools-version: 5.9
2
- import PackageDescription
3
-
4
- // NOTE: capacitor-mediapipe is Android-only at runtime. The iOS plugin in
5
- // `Sources/DVAICapacitorMediaPipe` is a stub that rejects every method
6
- // with "MediaPipe LLM is Android-only." It exists so app builds that
7
- // happen to include the package on the iOS side still link cleanly.
8
- // Telegraph stays as a dependency for parity with the other capacitor-*
9
- // packages (the stub itself doesn't reach for it, but Internal/* files
10
- // that may land later — e.g. a reusable HttpServer wrapper — would).
11
- let package = Package(
12
- name: "DVAICapacitorMediaPipe",
13
- platforms: [.iOS(.v14), .macOS(.v12)],
14
- products: [
15
- .library(name: "DVAICapacitorMediaPipe", targets: ["DVAICapacitorMediaPipe"]),
16
- ],
17
- dependencies: [
18
- .package(url: "https://github.com/Building42/Telegraph.git", from: "0.40.0"),
19
- ],
20
- targets: [
21
- .target(
22
- name: "DVAICapacitorMediaPipe",
23
- dependencies: ["Telegraph"],
24
- path: "Sources/DVAICapacitorMediaPipe",
25
- exclude: ["PluginProxy.m"]
26
- ),
27
- .testTarget(
28
- name: "DVAICapacitorMediaPipeTests",
29
- dependencies: ["DVAICapacitorMediaPipe"],
30
- path: "Tests/DVAICapacitorMediaPipeTests"
31
- ),
32
- ]
33
- )
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ // NOTE: capacitor-mediapipe is Android-only at runtime. The iOS plugin in
5
+ // `Sources/DVAICapacitorMediaPipe` is a stub that rejects every method
6
+ // with "MediaPipe LLM is Android-only." It exists so app builds that
7
+ // happen to include the package on the iOS side still link cleanly.
8
+ // Telegraph stays as a dependency for parity with the other capacitor-*
9
+ // packages (the stub itself doesn't reach for it, but Internal/* files
10
+ // that may land later — e.g. a reusable HttpServer wrapper — would).
11
+ let package = Package(
12
+ name: "DVAICapacitorMediaPipe",
13
+ // iOS 17 / macOS 14 — bumped from .v14/.v12 to match the shared-core
14
+ // floor that v3.2.0 raised when migrating off Telegraph onto
15
+ // Hummingbird. capacitor-foundation already declares .iOS("18.1");
16
+ // capacitor-mlx already .iOS(.v17); capacitor-llama bumped in the
17
+ // same commit. mediapipe was the lone laggard.
18
+ platforms: [.iOS(.v17), .macOS(.v14)],
19
+ products: [
20
+ .library(name: "DVAICapacitorMediaPipe", targets: ["DVAICapacitorMediaPipe"]),
21
+ ],
22
+ dependencies: [
23
+ .package(url: "https://github.com/Building42/Telegraph.git", from: "0.40.0"),
24
+ ],
25
+ targets: [
26
+ .target(
27
+ name: "DVAICapacitorMediaPipe",
28
+ dependencies: ["Telegraph"],
29
+ path: "Sources/DVAICapacitorMediaPipe",
30
+ exclude: ["PluginProxy.m"]
31
+ ),
32
+ .testTarget(
33
+ name: "DVAICapacitorMediaPipeTests",
34
+ dependencies: ["DVAICapacitorMediaPipe"],
35
+ path: "Tests/DVAICapacitorMediaPipeTests"
36
+ ),
37
+ ]
38
+ )
@@ -1,31 +1,31 @@
1
- import Foundation
2
-
3
- #if canImport(Capacitor)
4
- import Capacitor
5
-
6
- /// Stub iOS plugin — MediaPipe LLM is Android-only.
7
- ///
8
- /// Apps that bundle `@dvai-bridge/capacitor-mediapipe` on iOS link this
9
- /// rejection-only surface so the build succeeds, but every method
10
- /// returns the Android-only message. Task 47 fills out the surface with
11
- /// any remaining methods (status currently resolves with `running:false`,
12
- /// `backend:"mediapipe"`, the rest reject).
13
- @objc(DVAIBridgeMediaPipePlugin)
14
- public class DVAIBridgeMediaPipePlugin: CAPPlugin {
15
- @objc func start(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
16
- @objc func stop(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
17
-
18
- @objc func status(_ call: CAPPluginCall) {
19
- call.resolve(["running": false, "backend": "mediapipe"])
20
- }
21
-
22
- @objc func downloadModel(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
23
- @objc func listCachedModels(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
24
- @objc func deleteCachedModel(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
25
- @objc func cacheDir(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
26
-
27
- private func rejectAndroidOnly(_ call: CAPPluginCall) {
28
- call.reject("MediaPipe LLM is Android-only. Use a different backend on iOS.")
29
- }
30
- }
31
- #endif
1
+ import Foundation
2
+
3
+ #if canImport(Capacitor)
4
+ import Capacitor
5
+
6
+ /// Stub iOS plugin — MediaPipe LLM is Android-only.
7
+ ///
8
+ /// Apps that bundle `@dvai-bridge/capacitor-mediapipe` on iOS link this
9
+ /// rejection-only surface so the build succeeds, but every method
10
+ /// returns the Android-only message. Task 47 fills out the surface with
11
+ /// any remaining methods (status currently resolves with `running:false`,
12
+ /// `backend:"mediapipe"`, the rest reject).
13
+ @objc(DVAIBridgeMediaPipePlugin)
14
+ public class DVAIBridgeMediaPipePlugin: CAPPlugin {
15
+ @objc func start(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
16
+ @objc func stop(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
17
+
18
+ @objc func status(_ call: CAPPluginCall) {
19
+ call.resolve(["running": false, "backend": "mediapipe"])
20
+ }
21
+
22
+ @objc func downloadModel(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
23
+ @objc func listCachedModels(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
24
+ @objc func deleteCachedModel(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
25
+ @objc func cacheDir(_ call: CAPPluginCall) { rejectAndroidOnly(call) }
26
+
27
+ private func rejectAndroidOnly(_ call: CAPPluginCall) {
28
+ call.reject("MediaPipe LLM is Android-only. Use a different backend on iOS.")
29
+ }
30
+ }
31
+ #endif
@@ -1,15 +1,15 @@
1
- #import <Foundation/Foundation.h>
2
-
3
- #if __has_include(<Capacitor/Capacitor.h>)
4
- #import <Capacitor/Capacitor.h>
5
-
6
- CAP_PLUGIN(DVAIBridgeMediaPipePlugin, "DVAIBridgeMediaPipe",
7
- CAP_PLUGIN_METHOD(start, CAPPluginReturnPromise);
8
- CAP_PLUGIN_METHOD(stop, CAPPluginReturnPromise);
9
- CAP_PLUGIN_METHOD(status, CAPPluginReturnPromise);
10
- CAP_PLUGIN_METHOD(downloadModel, CAPPluginReturnPromise);
11
- CAP_PLUGIN_METHOD(listCachedModels, CAPPluginReturnPromise);
12
- CAP_PLUGIN_METHOD(deleteCachedModel, CAPPluginReturnPromise);
13
- CAP_PLUGIN_METHOD(cacheDir, CAPPluginReturnPromise);
14
- )
15
- #endif
1
+ #import <Foundation/Foundation.h>
2
+
3
+ #if __has_include(<Capacitor/Capacitor.h>)
4
+ #import <Capacitor/Capacitor.h>
5
+
6
+ CAP_PLUGIN(DVAIBridgeMediaPipePlugin, "DVAIBridgeMediaPipe",
7
+ CAP_PLUGIN_METHOD(start, CAPPluginReturnPromise);
8
+ CAP_PLUGIN_METHOD(stop, CAPPluginReturnPromise);
9
+ CAP_PLUGIN_METHOD(status, CAPPluginReturnPromise);
10
+ CAP_PLUGIN_METHOD(downloadModel, CAPPluginReturnPromise);
11
+ CAP_PLUGIN_METHOD(listCachedModels, CAPPluginReturnPromise);
12
+ CAP_PLUGIN_METHOD(deleteCachedModel, CAPPluginReturnPromise);
13
+ CAP_PLUGIN_METHOD(cacheDir, CAPPluginReturnPromise);
14
+ )
15
+ #endif
@@ -1,10 +1,10 @@
1
- import XCTest
2
- @testable import DVAICapacitorMediaPipe
3
-
4
- final class SmokeTest: XCTestCase {
5
- func testPackageLoads() {
6
- // The iOS plugin is a stub — this just confirms the module imports
7
- // and the bundle loads cleanly under `xcodebuild test`.
8
- XCTAssertTrue(true)
9
- }
10
- }
1
+ import XCTest
2
+ @testable import DVAICapacitorMediaPipe
3
+
4
+ final class SmokeTest: XCTestCase {
5
+ func testPackageLoads() {
6
+ // The iOS plugin is a stub — this just confirms the module imports
7
+ // and the bundle loads cleanly under `xcodebuild test`.
8
+ XCTAssertTrue(true)
9
+ }
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvai-bridge/capacitor-mediapipe",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -41,15 +41,15 @@
41
41
  "license": "Custom (See LICENSE)",
42
42
  "repository": {
43
43
  "type": "git",
44
- "url": "https://github.com/westenets/dvai-bridge.git"
44
+ "url": "https://github.com/dvai-global/dvai-bridge.git"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@capacitor/core": "^6.0.0 || ^7.0.0 || ^8.0.0",
48
- "@dvai-bridge/android-mediapipe-core": "4.0.0",
49
- "@dvai-bridge/capacitor": "4.0.0"
48
+ "@dvai-bridge/android-mediapipe-core": "4.0.2",
49
+ "@dvai-bridge/capacitor": "4.0.2"
50
50
  },
51
51
  "devDependencies": {
52
- "@dvai-bridge/capacitor": "4.0.0"
52
+ "@dvai-bridge/capacitor": "4.0.2"
53
53
  },
54
54
  "capacitor": {
55
55
  "ios": {