@dvai-bridge/capacitor-llama 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,154 +1,154 @@
1
- import Foundation
2
- import DVAILlamaCore
3
-
4
- #if canImport(Capacitor)
5
- import Capacitor
6
-
7
- @objc(DVAIBridgeLlamaPlugin)
8
- public class DVAIBridgeLlamaPlugin: CAPPlugin {
9
- private let state = PluginState()
10
- private let downloader = ModelDownloader()
11
-
12
- public override func load() {
13
- super.load()
14
- }
15
-
16
- @objc func start(_ call: CAPPluginCall) {
17
- let opts: [String: Any] = (call.options as? [String: Any]) ?? [:]
18
- Task { [weak self] in
19
- guard let self else { return }
20
- self.notifyListeners("progress", data: ["phase": "load"])
21
- do {
22
- let result = try await self.state.start(opts: opts)
23
- self.notifyListeners("progress", data: ["phase": "ready"])
24
- call.resolve(result)
25
- } catch {
26
- self.notifyListeners("progress", data: [
27
- "phase": "error",
28
- "message": error.localizedDescription,
29
- ])
30
- call.reject(error.localizedDescription)
31
- }
32
- }
33
- }
34
-
35
- @objc func stop(_ call: CAPPluginCall) {
36
- Task {
37
- do {
38
- try await state.stop()
39
- call.resolve()
40
- } catch {
41
- call.reject(error.localizedDescription)
42
- }
43
- }
44
- }
45
-
46
- @objc func status(_ call: CAPPluginCall) {
47
- Task {
48
- let info = await state.statusInfo()
49
- call.resolve(info)
50
- }
51
- }
52
-
53
- @objc func downloadModel(_ call: CAPPluginCall) {
54
- guard let urlStr = call.getString("url"), let url = URL(string: urlStr) else {
55
- call.reject("url is required")
56
- return
57
- }
58
- guard let sha = call.getString("sha256"), !sha.isEmpty else {
59
- call.reject("sha256 is required")
60
- return
61
- }
62
- let destFilename = call.getString("destFilename") ?? url.lastPathComponent
63
- // Capacitor's JSObject is `[String: Any]`, so an `as? [String: String]`
64
- // cast returns nil whenever any value isn't already typed as String,
65
- // silently dropping ALL headers. Mirror Android's per-key extraction.
66
- var headers: [String: String] = [:]
67
- if let raw = call.getObject("headers") {
68
- for (k, v) in raw {
69
- if let s = v as? String { headers[k] = s }
70
- }
71
- }
72
-
73
- Task { [weak self] in
74
- guard let self else { return }
75
- do {
76
- let result = try await self.downloader.downloadModel(
77
- url: url,
78
- expectedSha256: sha.lowercased(),
79
- destFilename: destFilename,
80
- headers: headers,
81
- onProgress: { [weak self] bytesDone, bytesTotal in
82
- guard let self else { return }
83
- var payload: [String: Any] = [
84
- "phase": "download",
85
- "bytesReceived": bytesDone,
86
- ]
87
- if let total = bytesTotal {
88
- payload["bytesTotal"] = total
89
- if total > 0 {
90
- payload["percent"] = Double(bytesDone) / Double(total) * 100.0
91
- }
92
- }
93
- self.notifyListeners("progress", data: payload)
94
- }
95
- )
96
- call.resolve([
97
- "path": result.path,
98
- "cached": result.cached,
99
- ])
100
- } catch {
101
- call.reject(error.localizedDescription)
102
- }
103
- }
104
- }
105
-
106
- @objc func listCachedModels(_ call: CAPPluginCall) {
107
- Task { [weak self] in
108
- guard let self else { return }
109
- do {
110
- let infos = try await self.downloader.listCachedModels()
111
- let models: [[String: Any]] = infos.map {
112
- [
113
- "filename": $0.filename,
114
- "path": $0.path,
115
- "bytes": $0.bytes,
116
- "sha256": $0.sha256,
117
- ]
118
- }
119
- call.resolve(["models": models])
120
- } catch {
121
- call.reject(error.localizedDescription)
122
- }
123
- }
124
- }
125
-
126
- @objc func deleteCachedModel(_ call: CAPPluginCall) {
127
- guard let filename = call.getString("filename"), !filename.isEmpty else {
128
- call.reject("filename is required")
129
- return
130
- }
131
- Task { [weak self] in
132
- guard let self else { return }
133
- do {
134
- try await self.downloader.deleteCachedModel(filename: filename)
135
- call.resolve()
136
- } catch {
137
- call.reject(error.localizedDescription)
138
- }
139
- }
140
- }
141
-
142
- @objc func cacheDir(_ call: CAPPluginCall) {
143
- Task { [weak self] in
144
- guard let self else { return }
145
- do {
146
- let path = try await self.downloader.cacheDirPath()
147
- call.resolve(["path": path])
148
- } catch {
149
- call.reject(error.localizedDescription)
150
- }
151
- }
152
- }
153
- }
154
- #endif
1
+ import Foundation
2
+ import DVAILlamaCore
3
+
4
+ #if canImport(Capacitor)
5
+ import Capacitor
6
+
7
+ @objc(DVAIBridgeLlamaPlugin)
8
+ public class DVAIBridgeLlamaPlugin: CAPPlugin {
9
+ private let state = PluginState()
10
+ private let downloader = ModelDownloader()
11
+
12
+ public override func load() {
13
+ super.load()
14
+ }
15
+
16
+ @objc func start(_ call: CAPPluginCall) {
17
+ let opts: [String: Any] = (call.options as? [String: Any]) ?? [:]
18
+ Task { [weak self] in
19
+ guard let self else { return }
20
+ self.notifyListeners("progress", data: ["phase": "load"])
21
+ do {
22
+ let result = try await self.state.start(opts: opts)
23
+ self.notifyListeners("progress", data: ["phase": "ready"])
24
+ call.resolve(result)
25
+ } catch {
26
+ self.notifyListeners("progress", data: [
27
+ "phase": "error",
28
+ "message": error.localizedDescription,
29
+ ])
30
+ call.reject(error.localizedDescription)
31
+ }
32
+ }
33
+ }
34
+
35
+ @objc func stop(_ call: CAPPluginCall) {
36
+ Task {
37
+ do {
38
+ try await state.stop()
39
+ call.resolve()
40
+ } catch {
41
+ call.reject(error.localizedDescription)
42
+ }
43
+ }
44
+ }
45
+
46
+ @objc func status(_ call: CAPPluginCall) {
47
+ Task {
48
+ let info = await state.statusInfo()
49
+ call.resolve(info)
50
+ }
51
+ }
52
+
53
+ @objc func downloadModel(_ call: CAPPluginCall) {
54
+ guard let urlStr = call.getString("url"), let url = URL(string: urlStr) else {
55
+ call.reject("url is required")
56
+ return
57
+ }
58
+ guard let sha = call.getString("sha256"), !sha.isEmpty else {
59
+ call.reject("sha256 is required")
60
+ return
61
+ }
62
+ let destFilename = call.getString("destFilename") ?? url.lastPathComponent
63
+ // Capacitor's JSObject is `[String: Any]`, so an `as? [String: String]`
64
+ // cast returns nil whenever any value isn't already typed as String,
65
+ // silently dropping ALL headers. Mirror Android's per-key extraction.
66
+ var headers: [String: String] = [:]
67
+ if let raw = call.getObject("headers") {
68
+ for (k, v) in raw {
69
+ if let s = v as? String { headers[k] = s }
70
+ }
71
+ }
72
+
73
+ Task { [weak self] in
74
+ guard let self else { return }
75
+ do {
76
+ let result = try await self.downloader.downloadModel(
77
+ url: url,
78
+ expectedSha256: sha.lowercased(),
79
+ destFilename: destFilename,
80
+ headers: headers,
81
+ onProgress: { [weak self] bytesDone, bytesTotal in
82
+ guard let self else { return }
83
+ var payload: [String: Any] = [
84
+ "phase": "download",
85
+ "bytesReceived": bytesDone,
86
+ ]
87
+ if let total = bytesTotal {
88
+ payload["bytesTotal"] = total
89
+ if total > 0 {
90
+ payload["percent"] = Double(bytesDone) / Double(total) * 100.0
91
+ }
92
+ }
93
+ self.notifyListeners("progress", data: payload)
94
+ }
95
+ )
96
+ call.resolve([
97
+ "path": result.path,
98
+ "cached": result.cached,
99
+ ])
100
+ } catch {
101
+ call.reject(error.localizedDescription)
102
+ }
103
+ }
104
+ }
105
+
106
+ @objc func listCachedModels(_ call: CAPPluginCall) {
107
+ Task { [weak self] in
108
+ guard let self else { return }
109
+ do {
110
+ let infos = try await self.downloader.listCachedModels()
111
+ let models: [[String: Any]] = infos.map {
112
+ [
113
+ "filename": $0.filename,
114
+ "path": $0.path,
115
+ "bytes": $0.bytes,
116
+ "sha256": $0.sha256,
117
+ ]
118
+ }
119
+ call.resolve(["models": models])
120
+ } catch {
121
+ call.reject(error.localizedDescription)
122
+ }
123
+ }
124
+ }
125
+
126
+ @objc func deleteCachedModel(_ call: CAPPluginCall) {
127
+ guard let filename = call.getString("filename"), !filename.isEmpty else {
128
+ call.reject("filename is required")
129
+ return
130
+ }
131
+ Task { [weak self] in
132
+ guard let self else { return }
133
+ do {
134
+ try await self.downloader.deleteCachedModel(filename: filename)
135
+ call.resolve()
136
+ } catch {
137
+ call.reject(error.localizedDescription)
138
+ }
139
+ }
140
+ }
141
+
142
+ @objc func cacheDir(_ call: CAPPluginCall) {
143
+ Task { [weak self] in
144
+ guard let self else { return }
145
+ do {
146
+ let path = try await self.downloader.cacheDirPath()
147
+ call.resolve(["path": path])
148
+ } catch {
149
+ call.reject(error.localizedDescription)
150
+ }
151
+ }
152
+ }
153
+ }
154
+ #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(DVAIBridgeLlamaPlugin, "DVAIBridgeLlama",
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(DVAIBridgeLlamaPlugin, "DVAIBridgeLlama",
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