cj-tauri 1.1.2 → 2.1.0

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.
Files changed (162) hide show
  1. package/README.md +137 -77
  2. package/bin/cj-tauri.js +287 -287
  3. package/cjpm.toml +13 -2
  4. package/cli/cjpm.toml +22 -13
  5. package/cli/src/doctor.cj +308 -304
  6. package/cli/src/main.cj +129 -121
  7. package/cli/src/manifest.cj +632 -0
  8. package/cli/src/manifest_test.cj +87 -0
  9. package/cli/src/project.cj +770 -754
  10. package/cli/src/resolve.cj +348 -348
  11. package/cli/src/scaffold.cj +46 -38
  12. package/cli/src/sync.cj +526 -0
  13. package/cli/src/util.cj +9 -0
  14. package/cli/templates/app/README.md +30 -59
  15. package/cli/templates/app/{ui → assets/ui}/index.html +2 -0
  16. package/cli/templates/app/cj-tauri.toml +32 -0
  17. package/cli/templates/app/cjpm.toml +21 -4
  18. package/cli/templates/app/src/main.cj +29 -16
  19. package/cli/templates/app-react/README.md +34 -45
  20. package/cli/templates/app-react/{ui → assets/ui}/index.html +25 -25
  21. package/cli/templates/app-react/{ui → assets/ui}/src/App.css +67 -67
  22. package/cli/templates/app-react/{ui → assets/ui}/src/App.jsx +124 -124
  23. package/cli/templates/app-react/cj-tauri.toml +33 -0
  24. package/cli/templates/app-react/cjpm.toml +21 -4
  25. package/cli/templates/app-react/src/main.cj +18 -29
  26. package/cli/templates/app-vue/README.md +34 -38
  27. package/cli/templates/app-vue/{ui → assets/ui}/index.html +25 -25
  28. package/cli/templates/app-vue/{ui → assets/ui}/src/App.vue +176 -176
  29. package/cli/templates/app-vue/cj-tauri.toml +33 -0
  30. package/cli/templates/app-vue/cjpm.toml +21 -4
  31. package/cli/templates/app-vue/src/main.cj +18 -29
  32. package/cli/templates/{ohos-pc → ohos-skeleton}/README.md +5 -0
  33. package/cli/templates/{ohos-pc → ohos-skeleton}/build-hap.sh +15 -0
  34. package/cli/templates/{ohos-pc → ohos-skeleton}/entry/cjpm.toml +8 -0
  35. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/dialog_host.cj +217 -0
  36. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/index.cj +527 -0
  37. package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/module.json5 +8 -0
  38. package/native/build_win.bat +62 -62
  39. package/native/core/bridge_core.c +1681 -1626
  40. package/native/core/bridge_core.h +675 -618
  41. package/native/core/bridge_js.h +108 -108
  42. package/native/platforms/harmonyos/README.md +115 -6
  43. package/native/platforms/linux/bridge_linux.c +2787 -2485
  44. package/native/platforms/windows/bridge_win.c +3740 -3248
  45. package/native/tests/gtk_threading_probe.c +143 -143
  46. package/native/tests/test_bridge_core.c +1339 -1228
  47. package/package.json +53 -51
  48. package/prebuilt/linux-x64/cj-tauri +0 -0
  49. package/src/api_system.cj +67 -67
  50. package/src/app.cj +325 -940
  51. package/src/app_events.cj +166 -0
  52. package/src/app_host_ops.cj +287 -0
  53. package/src/app_run.cj +283 -0
  54. package/src/app_spec.cj +76 -0
  55. package/src/arkweb_menu.cj +216 -0
  56. package/src/arkweb_script.cj +0 -12
  57. package/src/capability.cj +409 -409
  58. package/src/clipboard_bridge.cj +178 -0
  59. package/src/dialog_spec.cj +79 -0
  60. package/src/dragdrop.cj +26 -26
  61. package/src/embedded_assets.cj +98 -98
  62. package/src/host.cj +752 -604
  63. package/src/host_arkweb.cj +201 -17
  64. package/src/host_webkit.cj +663 -548
  65. package/src/host_webview2.cj +663 -548
  66. package/src/hotkey.cj +66 -66
  67. package/src/ipc_hub.cj +337 -337
  68. package/src/ipc_message.cj +286 -286
  69. package/src/launch.cj +62 -0
  70. package/src/logging.cj +127 -127
  71. package/src/menu.cj +197 -197
  72. package/src/platform/platform_app_context.cj +77 -0
  73. package/src/platform/platform_assets.cj +33 -0
  74. package/src/platform/platform_discover.cj +176 -0
  75. package/src/platform/platform_env.cj +29 -0
  76. package/src/platform/platform_feature.cj +31 -0
  77. package/src/platform/platform_page_source.cj +87 -0
  78. package/src/platform/platform_target_info.cj +32 -0
  79. package/src/platform_host_provider.cj +87 -0
  80. package/src/plugin.cj +333 -299
  81. package/src/plugins/clipboard/plugin_clipboard.cj +152 -144
  82. package/src/plugins/dialog/plugin_dialog.cj +209 -209
  83. package/src/plugins/fs/plugin_fs.cj +105 -1
  84. package/src/plugins/http/http_backend.cj +131 -0
  85. package/src/plugins/http/http_desktop.cj +195 -0
  86. package/src/plugins/http/http_ohos.cj +204 -0
  87. package/src/plugins/http/plugin_http.cj +310 -459
  88. package/src/plugins/log/plugin_log.cj +105 -105
  89. package/src/plugins/menu/plugin_menu.cj +8 -0
  90. package/src/plugins/notification/plugin_notification.cj +154 -146
  91. package/src/plugins/serial/plugin_serial.cj +17 -1
  92. package/src/plugins/serial/serial_bridge.cj +9 -1
  93. package/src/plugins/serial/serial_manager_ohos.cj +92 -0
  94. package/src/plugins/serial/serial_ohos.cj +529 -0
  95. package/src/plugins/shell/plugin_shell.cj +29 -1
  96. package/src/plugins/sqlite/plugin_sqlite.cj +8 -0
  97. package/src/plugins/ws/plugin_ws.cj +488 -470
  98. package/src/process_hidden.cj +174 -174
  99. package/src/scope.cj +391 -391
  100. package/src/shell_event.cj +69 -69
  101. package/src/tests/app_spec_test.cj +126 -0
  102. package/src/tests/capability_test.cj +243 -243
  103. package/src/tests/dialog_spec_test.cj +73 -0
  104. package/src/tests/fake_host.cj +201 -186
  105. package/src/tests/ipc_hub_test.cj +487 -487
  106. package/src/tests/logging_test.cj +62 -62
  107. package/src/tests/platform_contract_test.cj +251 -0
  108. package/src/tests/plugin_clipboard_test.cj +222 -222
  109. package/src/tests/plugin_dialog_test.cj +237 -237
  110. package/src/tests/plugin_fs_test.cj +207 -0
  111. package/src/tests/plugin_http_test.cj +124 -124
  112. package/src/tests/plugin_notification_test.cj +205 -205
  113. package/src/tests/plugin_serial_test.cj +48 -0
  114. package/src/tests/plugin_test.cj +66 -3
  115. package/src/tests/plugin_ws_test.cj +40 -40
  116. package/src/tests/process_hidden_test.cj +129 -129
  117. package/src/tests/scope_test.cj +350 -350
  118. package/src/tests/system_host_test.cj +99 -81
  119. package/src/tests/urlutil_test.cj +53 -53
  120. package/src/tests/version_test.cj +75 -75
  121. package/src/tests/window_registry_test.cj +123 -123
  122. package/src/tray.cj +90 -90
  123. package/src/urlutil.cj +159 -159
  124. package/src/version.cj +44 -44
  125. package/src/window.cj +51 -51
  126. package/src/window_registry.cj +116 -116
  127. package/cli/templates/ohos-pc/entry/src/main/cangjie/index.cj +0 -167
  128. package/prebuilt/win32-x64/cj-tauri.exe +0 -0
  129. package/src/host_factory.cj +0 -48
  130. /package/cli/templates/app/{capabilities → assets/capabilities}/default.json +0 -0
  131. /package/cli/templates/app-react/{capabilities → assets/capabilities}/default.json +0 -0
  132. /package/cli/templates/app-react/{ui → assets/ui}/package.json +0 -0
  133. /package/cli/templates/app-react/{ui → assets/ui}/src/main.jsx +0 -0
  134. /package/cli/templates/app-react/{ui → assets/ui}/vite.config.js +0 -0
  135. /package/cli/templates/app-vue/{capabilities → assets/capabilities}/default.json +0 -0
  136. /package/cli/templates/app-vue/{ui → assets/ui}/package.json +0 -0
  137. /package/cli/templates/app-vue/{ui → assets/ui}/src/main.js +0 -0
  138. /package/cli/templates/app-vue/{ui → assets/ui}/vite.config.js +0 -0
  139. /package/cli/templates/{ohos-pc → ohos-skeleton}/AppScope/app.json5 +0 -0
  140. /package/cli/templates/{ohos-pc → ohos-skeleton}/AppScope/resources/base/element/string.json +0 -0
  141. /package/cli/templates/{ohos-pc → ohos-skeleton}/AppScope/resources/base/media/background.png +0 -0
  142. /package/cli/templates/{ohos-pc → ohos-skeleton}/AppScope/resources/base/media/foreground.png +0 -0
  143. /package/cli/templates/{ohos-pc → ohos-skeleton}/AppScope/resources/base/media/layered_image.json +0 -0
  144. /package/cli/templates/{ohos-pc → ohos-skeleton}/build-profile.json5 +0 -0
  145. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/build-profile.json5 +0 -0
  146. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/hvigorfile.ts +0 -0
  147. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/oh-package.json5 +0 -0
  148. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/cangjie/ability_stage.cj +0 -0
  149. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/cangjie/app_host.cj +0 -0
  150. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/cangjie/main_ability.cj +0 -0
  151. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/base/element/color.json +0 -0
  152. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/base/element/string.json +0 -0
  153. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/base/media/background.png +0 -0
  154. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/base/media/foreground.png +0 -0
  155. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/base/media/layered_image.json +0 -0
  156. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/base/media/startIcon.png +0 -0
  157. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/base/profile/main_pages.json +0 -0
  158. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/rawfile/capabilities.json +0 -0
  159. /package/cli/templates/{ohos-pc → ohos-skeleton}/entry/src/main/resources/rawfile/index.html +0 -0
  160. /package/cli/templates/{ohos-pc → ohos-skeleton}/hvigor/hvigor-config.json5 +0 -0
  161. /package/cli/templates/{ohos-pc → ohos-skeleton}/hvigorfile.ts +0 -0
  162. /package/cli/templates/{ohos-pc → ohos-skeleton}/oh-package.json5 +0 -0
@@ -1,69 +1,69 @@
1
- package cjTauri
2
-
3
- import stdx.encoding.json.*
4
-
5
- /**
6
- * shell 事件信封(C 桥 → 仓颉)的解析与语义映射:RFC-002 §5.5 / §5.6
7
- *
8
- * 信封形状(当前定稿,菜单):`{"kind":"menu","id":"file.save","enabled":true,"checked":false}`
9
- * 托盘 / 拖放落地后各带自己的 kind(`tray` / `drop`),kind 决定投给前端哪个事件名。
10
- *
11
- * 为什么单独成文件:这里是**纯函数**(不进窗口、不碰线程),能脱离宿主在单测里直接验。
12
- * 信封格式坏掉的表现是「事件静默不到」——没有纯函数边界时,只能靠实机点击去猜。
13
- */
14
-
15
- /** `kind` → 前端事件名;不认识的 kind 返回 None(调用方提示一句后丢弃,不抛异常) */
16
- public func shellEventNameFor(kind: String): Option<String> {
17
- match (kind) {
18
- case "menu" => return Some("menu:click")
19
- case "tray" => return Some("tray:click")
20
- case "drop" => return Some("dragdrop:files")
21
- case "hotkey" => return Some("hotkey:press")
22
- case _ => return None
23
- }
24
- }
25
-
26
- /**
27
- * 解析信封成对象;不是合法 JSON 对象就返回 None
28
- *
29
- * 不抛异常:数据从 C 桥来(**不是**页面可控输入),格式坏了宁可丢一条事件 + 留一行日志,
30
- * 也不要让异常穿到 FFI 边界——仓颉异常穿过 C 侧回调,进程状态就说不清了。
31
- */
32
- public func parseShellEnvelope(json: String): Option<JsonObject> {
33
- try {
34
- let v = JsonValue.fromStr(json)
35
- match (v.kind()) {
36
- case JsonKind.JsObject => return Some(v.asObject())
37
- case _ => return None
38
- }
39
- } catch (e: Exception) {
40
- return None
41
- }
42
- }
43
-
44
- /** 取信封里的字符串字段(缺失 / 类型不对都给 None) */
45
- public func shellString(obj: JsonObject, key: String): Option<String> {
46
- match (obj.get(key)) {
47
- case Some(v) => match (v.kind()) {
48
- case JsonKind.JsString => return Some(v.asString().getValue())
49
- case _ => return None
50
- }
51
- case None => return None
52
- }
53
- }
54
-
55
- /**
56
- * 取信封里的布尔字段(缺失 / 类型不对都给 None)
57
- *
58
- * 缺字段**不能**当 false 用:这两个值要回写到应用层菜单模型(见 `TauriApp` 的模型同步),
59
- * 拿默认值顶等于把「用户刚点出来的勾选」按默认值改掉——宁可不写。
60
- */
61
- public func shellBool(obj: JsonObject, key: String): Option<Bool> {
62
- match (obj.get(key)) {
63
- case Some(v) => match (v.kind()) {
64
- case JsonKind.JsBool => return Some(v.asBool().getValue())
65
- case _ => return None
66
- }
67
- case None => return None
68
- }
69
- }
1
+ package cjTauri
2
+
3
+ import stdx.encoding.json.*
4
+
5
+ /**
6
+ * shell 事件信封(C 桥 → 仓颉)的解析与语义映射:RFC-002 §5.5 / §5.6
7
+ *
8
+ * 信封形状(当前定稿,菜单):`{"kind":"menu","id":"file.save","enabled":true,"checked":false}`
9
+ * 托盘 / 拖放落地后各带自己的 kind(`tray` / `drop`),kind 决定投给前端哪个事件名。
10
+ *
11
+ * 为什么单独成文件:这里是**纯函数**(不进窗口、不碰线程),能脱离宿主在单测里直接验。
12
+ * 信封格式坏掉的表现是「事件静默不到」——没有纯函数边界时,只能靠实机点击去猜。
13
+ */
14
+
15
+ /** `kind` → 前端事件名;不认识的 kind 返回 None(调用方提示一句后丢弃,不抛异常) */
16
+ public func shellEventNameFor(kind: String): Option<String> {
17
+ match (kind) {
18
+ case "menu" => return Some("menu:click")
19
+ case "tray" => return Some("tray:click")
20
+ case "drop" => return Some("dragdrop:files")
21
+ case "hotkey" => return Some("hotkey:press")
22
+ case _ => return None
23
+ }
24
+ }
25
+
26
+ /**
27
+ * 解析信封成对象;不是合法 JSON 对象就返回 None
28
+ *
29
+ * 不抛异常:数据从 C 桥来(**不是**页面可控输入),格式坏了宁可丢一条事件 + 留一行日志,
30
+ * 也不要让异常穿到 FFI 边界——仓颉异常穿过 C 侧回调,进程状态就说不清了。
31
+ */
32
+ public func parseShellEnvelope(json: String): Option<JsonObject> {
33
+ try {
34
+ let v = JsonValue.fromStr(json)
35
+ match (v.kind()) {
36
+ case JsonKind.JsObject => return Some(v.asObject())
37
+ case _ => return None
38
+ }
39
+ } catch (e: Exception) {
40
+ return None
41
+ }
42
+ }
43
+
44
+ /** 取信封里的字符串字段(缺失 / 类型不对都给 None) */
45
+ public func shellString(obj: JsonObject, key: String): Option<String> {
46
+ match (obj.get(key)) {
47
+ case Some(v) => match (v.kind()) {
48
+ case JsonKind.JsString => return Some(v.asString().getValue())
49
+ case _ => return None
50
+ }
51
+ case None => return None
52
+ }
53
+ }
54
+
55
+ /**
56
+ * 取信封里的布尔字段(缺失 / 类型不对都给 None)
57
+ *
58
+ * 缺字段**不能**当 false 用:这两个值要回写到应用层菜单模型(见 `TauriApp` 的模型同步),
59
+ * 拿默认值顶等于把「用户刚点出来的勾选」按默认值改掉——宁可不写。
60
+ */
61
+ public func shellBool(obj: JsonObject, key: String): Option<Bool> {
62
+ match (obj.get(key)) {
63
+ case Some(v) => match (v.kind()) {
64
+ case JsonKind.JsBool => return Some(v.asBool().getValue())
65
+ case _ => return None
66
+ }
67
+ case None => return None
68
+ }
69
+ }
@@ -0,0 +1,126 @@
1
+ package cjTauri.tests
2
+
3
+ import cjTauri.*
4
+ import cjTauri.platform.*
5
+ import cjTauri.plugins.store.*
6
+ import std.collection.*
7
+ import std.unittest.*
8
+ import std.unittest.testmacro.*
9
+
10
+ // ---- 批次 3-PR1:AppSpec 构造器链与 assemble 装配 ----
11
+
12
+ @Test
13
+ func appSpecBuilderChain(): Unit {
14
+ let spec = AppSpec()
15
+ .page(PageSource.Inline("<p/>"))
16
+ .window(WindowConfig("t", 800, 600))
17
+ .capabilities("assets/capabilities")
18
+ .capabilityJson("{\"identifier\":\"default\"}")
19
+ @Expect(spec.appId, "")
20
+ @Expect(spec.capabilitiesDir, "assets/capabilities")
21
+ @Expect(spec.capabilityJsons.size, 1)
22
+ @Expect(spec.windowConfig.title, "t")
23
+ @Expect(spec.windowConfig.width, 800)
24
+ @Expect(spec.assetResolver.isSome(), false)
25
+ @Expect(spec.wireFn.isSome(), false)
26
+ @Expect(spec.plugins.size, 0)
27
+ match (spec.pageSource) {
28
+ case Inline(html) => @Expect(html, "<p/>")
29
+ case _ => @Expect(false, true)
30
+ }
31
+ }
32
+
33
+ /** wire 闭包执行标记(仓颉闭包捕获 var 的语义不冒风险,用对象装状态) */
34
+ class WireBox {
35
+ public var on: Bool = false
36
+ }
37
+
38
+ /** 高优先级假宿主:TauriApp 字段初始化就调 resolveHost,无显示环境必须用注册表桩 */
39
+ class AppSpecProbeProvider <: HostProvider {
40
+ public var last: FakeHost = FakeHost("seed")
41
+
42
+ public func priority(target: TargetInfo): Int64 {
43
+ return 100
44
+ }
45
+
46
+ public func create(label: String, target: TargetInfo): WebViewHost {
47
+ this.last = FakeHost(label)
48
+ return this.last
49
+ }
50
+ }
51
+
52
+ @Test
53
+ func appSpecAssembleWiresApp(): Unit {
54
+ let prov = AppSpecProbeProvider()
55
+ registerHost(prov)
56
+ let box = WireBox()
57
+ let spec = AppSpec()
58
+ .page(PageSource.Inline("<p/>"))
59
+ .window(WindowConfig("spec窗", 640, 480))
60
+ .plugin(StorePlugin())
61
+ .wire({ app =>
62
+ box.on = true
63
+ })
64
+ let app = assemble(spec)
65
+ @Expect(box.on, true)
66
+ @Expect(app.hostOf("main").isSome(), true)
67
+ @Expect(prov.last.label(), "main")
68
+ }
69
+
70
+ // ---- 批次 3-PR3:load(source) 收敛——装配层把 PageSource 原样交给宿主,resolver 随装配进宿主 ----
71
+
72
+ @Test
73
+ func fakeHostLoadDispatchesPageSource(): Unit {
74
+ let h = FakeHost("main")
75
+ h.load(PageSource.Inline("<p>hi</p>"))
76
+ @Expect(h.shownHtml, "<p>hi</p>")
77
+ @Expect(h.startedUrl, "")
78
+ h.load(PageSource.Url("https://example.com"))
79
+ @Expect(h.startedUrl, "https://example.com")
80
+ h.load(PageSource.DevServer("http://127.0.0.1:5173"))
81
+ @Expect(h.startedUrl, "http://127.0.0.1:5173")
82
+ h.load(PageSource.Asset("ui/index.html"))
83
+ @Expect(h.loadedSource, "asset:ui/index.html")
84
+ }
85
+
86
+ /** run 路径探针:优先级压过既有注册表里的桩,保证本用例拿到的是自己造的宿主 */
87
+ class RunProbeProvider <: HostProvider {
88
+ public var last: FakeHost = FakeHost("seed")
89
+
90
+ public func priority(target: TargetInfo): Int64 {
91
+ return 200
92
+ }
93
+
94
+ public func create(label: String, target: TargetInfo): WebViewHost {
95
+ this.last = FakeHost(label)
96
+ return this.last
97
+ }
98
+ }
99
+
100
+ /**
101
+ * run() 路径:resolver 注入与页面来源交接发生在同一次装配(runWith)里。
102
+ * 宿主用 FakeHost 桩(不建窗口);run() 放后台线程,观测到交接后置 quitNow 让它返回。
103
+ */
104
+ @Test
105
+ func runHandsResolverAndSourceToHost(): Unit {
106
+ let prov = RunProbeProvider()
107
+ let provIdx = registerHost(prov)
108
+ let spec = AppSpec()
109
+ .page(PageSource.Asset("ui/index.html"))
110
+ .window(WindowConfig("t", 640, 480))
111
+ .assets(StubResolver(HashMap()))
112
+ spawn {
113
+ let app = assemble(spec)
114
+ app.run(spec.pageSource)
115
+ }
116
+ var polls = 0
117
+ while (polls < 1000 && prov.last.loadedSource != "asset:ui/index.html") {
118
+ sleep(Duration.millisecond * 2)
119
+ polls += 1
120
+ }
121
+ @Expect(prov.last.loadedSource, "asset:ui/index.html")
122
+ @Expect(prov.last.resolverInjected.isSome(), true)
123
+ prov.last.quitNow = true
124
+ // 探针宿主清出全局注册表,免得压过后续用例自己的桩
125
+ unregisterHost(provIdx)
126
+ }