@zappdev/cli 0.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 (209) hide show
  1. package/README.md +55 -0
  2. package/dist/zapp-cli.js +9471 -0
  3. package/native/src/app/app.zc +490 -0
  4. package/native/src/event/event.zc +24 -0
  5. package/native/src/event/events.zc +70 -0
  6. package/native/src/platform/darwin/backend.zc +923 -0
  7. package/native/src/platform/darwin/backend_bootstrap.zc +9 -0
  8. package/native/src/platform/darwin/bootstrap.zc +9 -0
  9. package/native/src/platform/darwin/engine_jsc.zc +86 -0
  10. package/native/src/platform/darwin/engine_qjs.zc +92 -0
  11. package/native/src/platform/darwin/platform.zc +156 -0
  12. package/native/src/platform/darwin/webview.zc +550 -0
  13. package/native/src/platform/darwin/webview_bootstrap.zc +9 -0
  14. package/native/src/platform/darwin/window.zc +1223 -0
  15. package/native/src/platform/darwin/worker/common.zc +223 -0
  16. package/native/src/platform/darwin/worker/core/base64_core.zc +29 -0
  17. package/native/src/platform/darwin/worker/core/crypto_core.zc +19 -0
  18. package/native/src/platform/darwin/worker/core/encoding_core.zc +32 -0
  19. package/native/src/platform/darwin/worker/core/fetch_core.zc +145 -0
  20. package/native/src/platform/darwin/worker/core/url_core.zc +69 -0
  21. package/native/src/platform/darwin/worker/core/websocket_core.zc +179 -0
  22. package/native/src/platform/darwin/worker/dispatch.zc +55 -0
  23. package/native/src/platform/darwin/worker/jsc/base64_jsc.zc +39 -0
  24. package/native/src/platform/darwin/worker/jsc/crypto_jsc.zc +49 -0
  25. package/native/src/platform/darwin/worker/jsc/encoding_jsc.zc +86 -0
  26. package/native/src/platform/darwin/worker/jsc/fetch_jsc.zc +149 -0
  27. package/native/src/platform/darwin/worker/jsc/url_jsc.zc +54 -0
  28. package/native/src/platform/darwin/worker/jsc/websocket_jsc.zc +127 -0
  29. package/native/src/platform/darwin/worker/jsc.zc +670 -0
  30. package/native/src/platform/darwin/worker/mod.zc +30 -0
  31. package/native/src/platform/darwin/worker/qjs/fetch_qjs.zc +233 -0
  32. package/native/src/platform/darwin/worker/qjs/qjs_macros.zc +23 -0
  33. package/native/src/platform/darwin/worker/qjs/websocket_qjs.zc +223 -0
  34. package/native/src/platform/darwin/worker/qjs.zc +1053 -0
  35. package/native/src/platform/darwin/worker/timers.zc +149 -0
  36. package/native/src/platform/darwin/worker/timers_qjs.zc +209 -0
  37. package/native/src/platform/platform.zc +64 -0
  38. package/native/src/platform/shared/log.zc +156 -0
  39. package/native/src/platform/shared/worker/qjs/base64_qjs.zc +38 -0
  40. package/native/src/platform/shared/worker/qjs/crypto_qjs.zc +44 -0
  41. package/native/src/platform/shared/worker/qjs/encoding_qjs.zc +95 -0
  42. package/native/src/platform/shared/worker/qjs/url_qjs.zc +65 -0
  43. package/native/src/platform/shared/worker_registry.zc +206 -0
  44. package/native/src/platform/window.zc +446 -0
  45. package/native/src/platform/windows/backend.zc +452 -0
  46. package/native/src/platform/windows/backend_bootstrap.zc +9 -0
  47. package/native/src/platform/windows/bootstrap.zc +9 -0
  48. package/native/src/platform/windows/engine_qjs.zc +60 -0
  49. package/native/src/platform/windows/platform.zc +387 -0
  50. package/native/src/platform/windows/webview.zc +1175 -0
  51. package/native/src/platform/windows/webview_bootstrap.zc +9 -0
  52. package/native/src/platform/windows/window.zc +1271 -0
  53. package/native/src/platform/windows/worker/common.zc +409 -0
  54. package/native/src/platform/windows/worker/core/base64_core.zc +52 -0
  55. package/native/src/platform/windows/worker/core/crypto_core.zc +34 -0
  56. package/native/src/platform/windows/worker/core/encoding_core.zc +60 -0
  57. package/native/src/platform/windows/worker/core/fetch_core.zc +274 -0
  58. package/native/src/platform/windows/worker/core/url_core.zc +216 -0
  59. package/native/src/platform/windows/worker/core/websocket_core.zc +343 -0
  60. package/native/src/platform/windows/worker/dispatch.zc +34 -0
  61. package/native/src/platform/windows/worker/mod.zc +46 -0
  62. package/native/src/platform/windows/worker/qjs/fetch_qjs.zc +255 -0
  63. package/native/src/platform/windows/worker/qjs/websocket_qjs.zc +263 -0
  64. package/native/src/platform/windows/worker/qjs.zc +1049 -0
  65. package/native/src/platform/windows/worker/timers_qjs.zc +288 -0
  66. package/native/src/platform/worker.zc +8 -0
  67. package/native/src/service/service.zc +228 -0
  68. package/native/vendor/quickjs-ng/.gitattributes +4 -0
  69. package/native/vendor/quickjs-ng/.github/dependabot.yml +7 -0
  70. package/native/vendor/quickjs-ng/.github/workflows/ci.yml +812 -0
  71. package/native/vendor/quickjs-ng/.github/workflows/docs.yml +49 -0
  72. package/native/vendor/quickjs-ng/.github/workflows/release.yml +162 -0
  73. package/native/vendor/quickjs-ng/.github/workflows/test-docs.yml +23 -0
  74. package/native/vendor/quickjs-ng/.github/workflows/tsan.yml +32 -0
  75. package/native/vendor/quickjs-ng/.github/workflows/valgrind.yml +33 -0
  76. package/native/vendor/quickjs-ng/.gitmodules +5 -0
  77. package/native/vendor/quickjs-ng/CMakeLists.txt +553 -0
  78. package/native/vendor/quickjs-ng/LICENSE +24 -0
  79. package/native/vendor/quickjs-ng/Makefile +149 -0
  80. package/native/vendor/quickjs-ng/amalgam.js +53 -0
  81. package/native/vendor/quickjs-ng/api-test.c +927 -0
  82. package/native/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
  83. package/native/vendor/quickjs-ng/builtin-array-fromasync.js +36 -0
  84. package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
  85. package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.js +194 -0
  86. package/native/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
  87. package/native/vendor/quickjs-ng/builtin-iterator-zip.js +210 -0
  88. package/native/vendor/quickjs-ng/ctest.c +17 -0
  89. package/native/vendor/quickjs-ng/cutils.h +2013 -0
  90. package/native/vendor/quickjs-ng/cxxtest.cc +2 -0
  91. package/native/vendor/quickjs-ng/dtoa.c +1619 -0
  92. package/native/vendor/quickjs-ng/dtoa.h +87 -0
  93. package/native/vendor/quickjs-ng/examples/fib.c +67 -0
  94. package/native/vendor/quickjs-ng/examples/fib_module.js +10 -0
  95. package/native/vendor/quickjs-ng/examples/hello.js +1 -0
  96. package/native/vendor/quickjs-ng/examples/hello_module.js +6 -0
  97. package/native/vendor/quickjs-ng/examples/meson.build +17 -0
  98. package/native/vendor/quickjs-ng/examples/pi_bigint.js +118 -0
  99. package/native/vendor/quickjs-ng/examples/point.c +154 -0
  100. package/native/vendor/quickjs-ng/examples/test_fib.js +8 -0
  101. package/native/vendor/quickjs-ng/examples/test_point.js +43 -0
  102. package/native/vendor/quickjs-ng/fuzz.c +51 -0
  103. package/native/vendor/quickjs-ng/gen/function_source.c +81 -0
  104. package/native/vendor/quickjs-ng/gen/hello.c +53 -0
  105. package/native/vendor/quickjs-ng/gen/hello_module.c +106 -0
  106. package/native/vendor/quickjs-ng/gen/repl.c +3053 -0
  107. package/native/vendor/quickjs-ng/gen/standalone.c +324 -0
  108. package/native/vendor/quickjs-ng/gen/test_fib.c +81 -0
  109. package/native/vendor/quickjs-ng/libregexp-opcode.h +58 -0
  110. package/native/vendor/quickjs-ng/libregexp.c +2687 -0
  111. package/native/vendor/quickjs-ng/libregexp.h +98 -0
  112. package/native/vendor/quickjs-ng/libunicode-table.h +4707 -0
  113. package/native/vendor/quickjs-ng/libunicode.c +1746 -0
  114. package/native/vendor/quickjs-ng/libunicode.h +126 -0
  115. package/native/vendor/quickjs-ng/list.h +107 -0
  116. package/native/vendor/quickjs-ng/lre-test.c +73 -0
  117. package/native/vendor/quickjs-ng/meson.build +684 -0
  118. package/native/vendor/quickjs-ng/meson_options.txt +6 -0
  119. package/native/vendor/quickjs-ng/qjs-wasi-reactor.c +208 -0
  120. package/native/vendor/quickjs-ng/qjs.c +748 -0
  121. package/native/vendor/quickjs-ng/qjsc.c +673 -0
  122. package/native/vendor/quickjs-ng/quickjs-atom.h +267 -0
  123. package/native/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
  124. package/native/vendor/quickjs-ng/quickjs-libc.c +4986 -0
  125. package/native/vendor/quickjs-ng/quickjs-libc.h +79 -0
  126. package/native/vendor/quickjs-ng/quickjs-opcode.h +369 -0
  127. package/native/vendor/quickjs-ng/quickjs.c +60259 -0
  128. package/native/vendor/quickjs-ng/quickjs.h +1419 -0
  129. package/native/vendor/quickjs-ng/repl.js +1927 -0
  130. package/native/vendor/quickjs-ng/run-test262.c +2417 -0
  131. package/native/vendor/quickjs-ng/standalone.js +129 -0
  132. package/native/vendor/quickjs-ng/tests/assert.js +49 -0
  133. package/native/vendor/quickjs-ng/tests/bug1221.js +16 -0
  134. package/native/vendor/quickjs-ng/tests/bug1296.js +12 -0
  135. package/native/vendor/quickjs-ng/tests/bug1297.js +22 -0
  136. package/native/vendor/quickjs-ng/tests/bug1301.js +21 -0
  137. package/native/vendor/quickjs-ng/tests/bug1302.js +24 -0
  138. package/native/vendor/quickjs-ng/tests/bug1305.js +26 -0
  139. package/native/vendor/quickjs-ng/tests/bug1318.js +54 -0
  140. package/native/vendor/quickjs-ng/tests/bug1352.js +8 -0
  141. package/native/vendor/quickjs-ng/tests/bug1354.js +6 -0
  142. package/native/vendor/quickjs-ng/tests/bug1355.js +58 -0
  143. package/native/vendor/quickjs-ng/tests/bug1368.js +9 -0
  144. package/native/vendor/quickjs-ng/tests/bug39/1.js +6 -0
  145. package/native/vendor/quickjs-ng/tests/bug39/2.js +6 -0
  146. package/native/vendor/quickjs-ng/tests/bug39/3.js +7 -0
  147. package/native/vendor/quickjs-ng/tests/bug488-upstream.js +7 -0
  148. package/native/vendor/quickjs-ng/tests/bug633/0.js +7 -0
  149. package/native/vendor/quickjs-ng/tests/bug633/1.js +4 -0
  150. package/native/vendor/quickjs-ng/tests/bug633/2.js +4 -0
  151. package/native/vendor/quickjs-ng/tests/bug633/3.js +4 -0
  152. package/native/vendor/quickjs-ng/tests/bug645/0.js +4 -0
  153. package/native/vendor/quickjs-ng/tests/bug645/1.js +9 -0
  154. package/native/vendor/quickjs-ng/tests/bug645/2.js +7 -0
  155. package/native/vendor/quickjs-ng/tests/bug648.js +13 -0
  156. package/native/vendor/quickjs-ng/tests/bug652.js +4 -0
  157. package/native/vendor/quickjs-ng/tests/bug741.js +19 -0
  158. package/native/vendor/quickjs-ng/tests/bug775.js +7 -0
  159. package/native/vendor/quickjs-ng/tests/bug776.js +7 -0
  160. package/native/vendor/quickjs-ng/tests/bug832.js +2 -0
  161. package/native/vendor/quickjs-ng/tests/bug858.js +26 -0
  162. package/native/vendor/quickjs-ng/tests/bug904.js +6 -0
  163. package/native/vendor/quickjs-ng/tests/bug988.js +7 -0
  164. package/native/vendor/quickjs-ng/tests/bug999.js +3 -0
  165. package/native/vendor/quickjs-ng/tests/destructured-export.js +8 -0
  166. package/native/vendor/quickjs-ng/tests/detect_module/0.js +1 -0
  167. package/native/vendor/quickjs-ng/tests/detect_module/1.js +2 -0
  168. package/native/vendor/quickjs-ng/tests/detect_module/2.js +1 -0
  169. package/native/vendor/quickjs-ng/tests/detect_module/3.js +8 -0
  170. package/native/vendor/quickjs-ng/tests/detect_module/4.js +3 -0
  171. package/native/vendor/quickjs-ng/tests/empty.js +0 -0
  172. package/native/vendor/quickjs-ng/tests/fixture_cyclic_import.js +2 -0
  173. package/native/vendor/quickjs-ng/tests/fixture_string_exports.js +12 -0
  174. package/native/vendor/quickjs-ng/tests/function_source.js +14 -0
  175. package/native/vendor/quickjs-ng/tests/microbench.js +1267 -0
  176. package/native/vendor/quickjs-ng/tests/null_or_undefined.js +38 -0
  177. package/native/vendor/quickjs-ng/tests/str-pad-leak.js +5 -0
  178. package/native/vendor/quickjs-ng/tests/test_bigint.js +107 -0
  179. package/native/vendor/quickjs-ng/tests/test_bjson.js +366 -0
  180. package/native/vendor/quickjs-ng/tests/test_builtin.js +1314 -0
  181. package/native/vendor/quickjs-ng/tests/test_closure.js +220 -0
  182. package/native/vendor/quickjs-ng/tests/test_cyclic_import.js +12 -0
  183. package/native/vendor/quickjs-ng/tests/test_domexception.js +35 -0
  184. package/native/vendor/quickjs-ng/tests/test_language.js +755 -0
  185. package/native/vendor/quickjs-ng/tests/test_loop.js +367 -0
  186. package/native/vendor/quickjs-ng/tests/test_queue_microtask.js +39 -0
  187. package/native/vendor/quickjs-ng/tests/test_std.js +340 -0
  188. package/native/vendor/quickjs-ng/tests/test_string_exports.js +25 -0
  189. package/native/vendor/quickjs-ng/tests/test_worker.js +43 -0
  190. package/native/vendor/quickjs-ng/tests/test_worker_module.js +30 -0
  191. package/native/vendor/quickjs-ng/tests.conf +14 -0
  192. package/native/vendor/quickjs-ng/unicode_download.sh +19 -0
  193. package/native/vendor/quickjs-ng/unicode_gen.c +3108 -0
  194. package/native/vendor/quickjs-ng/unicode_gen_def.h +310 -0
  195. package/native/vendor/quickjs-ng/update-version.sh +32 -0
  196. package/native/vendor/webview2/include/WebView2.h +60636 -0
  197. package/native/vendor/webview2/include/WebView2EnvironmentOptions.h +406 -0
  198. package/package.json +33 -0
  199. package/src/backend.ts +139 -0
  200. package/src/build-config.ts +87 -0
  201. package/src/build.ts +276 -0
  202. package/src/common.ts +195 -0
  203. package/src/config.ts +89 -0
  204. package/src/dev.ts +164 -0
  205. package/src/generate.ts +200 -0
  206. package/src/icons.ts +116 -0
  207. package/src/init.ts +190 -0
  208. package/src/package.ts +150 -0
  209. package/src/zapp-cli.ts +263 -0
@@ -0,0 +1,409 @@
1
+ raw {
2
+ #ifdef _WIN32
3
+ #include <windows.h>
4
+ #include <winhttp.h>
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ extern const char* zapp_build_asset_root(void);
9
+ extern int zapp_build_use_embedded_assets(void);
10
+ extern int zapp_build_is_dev_mode(void);
11
+ extern void zapp_dispatch_worker_to_webviews(const char* kind, const char* worker_id, const char* payload_json);
12
+
13
+ // -----------------------------------------------------------------------
14
+ // Simple string -> void* map (fixed-size, linear scan)
15
+ // -----------------------------------------------------------------------
16
+
17
+ #define ZAPP_MAP_MAX 512
18
+
19
+ typedef struct {
20
+ char key[128];
21
+ void* val;
22
+ } ZappMapEntry;
23
+
24
+ typedef struct {
25
+ ZappMapEntry entries[ZAPP_MAP_MAX];
26
+ } ZappStringMap;
27
+
28
+ static void zapp_map_init(ZappStringMap* m) {
29
+ memset(m, 0, sizeof(ZappStringMap));
30
+ }
31
+
32
+ static void* zapp_map_get(ZappStringMap* m, const char* key) {
33
+ if (!m || !key) return NULL;
34
+ for (int i = 0; i < ZAPP_MAP_MAX; i++) {
35
+ if (m->entries[i].key[0] != '\0' && strcmp(m->entries[i].key, key) == 0) {
36
+ return m->entries[i].val;
37
+ }
38
+ }
39
+ return NULL;
40
+ }
41
+
42
+ static void zapp_map_set(ZappStringMap* m, const char* key, void* val) {
43
+ if (!m || !key) return;
44
+ for (int i = 0; i < ZAPP_MAP_MAX; i++) {
45
+ if (m->entries[i].key[0] != '\0' && strcmp(m->entries[i].key, key) == 0) {
46
+ m->entries[i].val = val;
47
+ return;
48
+ }
49
+ }
50
+ for (int i = 0; i < ZAPP_MAP_MAX; i++) {
51
+ if (m->entries[i].key[0] == '\0') {
52
+ strncpy(m->entries[i].key, key, sizeof(m->entries[i].key) - 1);
53
+ m->entries[i].key[sizeof(m->entries[i].key) - 1] = '\0';
54
+ m->entries[i].val = val;
55
+ return;
56
+ }
57
+ }
58
+ }
59
+
60
+ static void zapp_map_remove(ZappStringMap* m, const char* key) {
61
+ if (!m || !key) return;
62
+ for (int i = 0; i < ZAPP_MAP_MAX; i++) {
63
+ if (m->entries[i].key[0] != '\0' && strcmp(m->entries[i].key, key) == 0) {
64
+ m->entries[i].key[0] = '\0';
65
+ m->entries[i].val = NULL;
66
+ return;
67
+ }
68
+ }
69
+ }
70
+
71
+ static void zapp_map_clear(ZappStringMap* m) {
72
+ if (m) memset(m, 0, sizeof(ZappStringMap));
73
+ }
74
+
75
+ typedef void (*zapp_map_iter_fn)(const char* key, void* val, void* userdata);
76
+
77
+ static void zapp_map_foreach(ZappStringMap* m, zapp_map_iter_fn fn, void* userdata) {
78
+ if (!m || !fn) return;
79
+ for (int i = 0; i < ZAPP_MAP_MAX; i++) {
80
+ if (m->entries[i].key[0] != '\0') {
81
+ fn(m->entries[i].key, m->entries[i].val, userdata);
82
+ }
83
+ }
84
+ }
85
+
86
+ static int zapp_map_count_unique_ptrs(ZappStringMap* m) {
87
+ if (!m) return 0;
88
+ void* seen[ZAPP_MAP_MAX];
89
+ int seen_count = 0;
90
+ for (int i = 0; i < ZAPP_MAP_MAX; i++) {
91
+ if (m->entries[i].key[0] == '\0' || m->entries[i].val == NULL) continue;
92
+ int found = 0;
93
+ for (int j = 0; j < seen_count; j++) {
94
+ if (seen[j] == m->entries[i].val) { found = 1; break; }
95
+ }
96
+ if (!found && seen_count < ZAPP_MAP_MAX) {
97
+ seen[seen_count++] = m->entries[i].val;
98
+ }
99
+ }
100
+ return seen_count;
101
+ }
102
+
103
+ // -----------------------------------------------------------------------
104
+ // Minimal JSON field extraction (avoids needing a JSON parser library)
105
+ // -----------------------------------------------------------------------
106
+
107
+ char* zapp_json_get_string(const char* json, const char* key) {
108
+ if (!json || !key) return NULL;
109
+ char pattern[256];
110
+ snprintf(pattern, sizeof(pattern), "\"%s\":\"", key);
111
+ const char* start = strstr(json, pattern);
112
+ if (!start) return NULL;
113
+ start += strlen(pattern);
114
+ const char* end = start;
115
+ while (*end && *end != '"') {
116
+ if (*end == '\\' && *(end + 1)) end++;
117
+ end++;
118
+ }
119
+ size_t len = (size_t)(end - start);
120
+ char* result = (char*)malloc(len + 1);
121
+ memcpy(result, start, len);
122
+ result[len] = '\0';
123
+ return result;
124
+ }
125
+
126
+ int zapp_json_get_bool(const char* json, const char* key, int default_val) {
127
+ if (!json || !key) return default_val;
128
+ char pattern[256];
129
+ snprintf(pattern, sizeof(pattern), "\"%s\":", key);
130
+ const char* start = strstr(json, pattern);
131
+ if (!start) return default_val;
132
+ start += strlen(pattern);
133
+ while (*start == ' ') start++;
134
+ if (*start == 't') return 1;
135
+ if (*start == 'f') return 0;
136
+ return default_val;
137
+ }
138
+
139
+ int zapp_json_get_int(const char* json, const char* key, int default_val) {
140
+ if (!json || !key) return default_val;
141
+ char pattern[256];
142
+ snprintf(pattern, sizeof(pattern), "\"%s\":", key);
143
+ const char* start = strstr(json, pattern);
144
+ if (!start) return default_val;
145
+ start += strlen(pattern);
146
+ while (*start == ' ') start++;
147
+ if (*start == '-' || (*start >= '0' && *start <= '9')) return atoi(start);
148
+ return default_val;
149
+ }
150
+
151
+ char* zapp_json_get_raw(const char* json, const char* key) {
152
+ if (!json || !key) return NULL;
153
+ char pattern[256];
154
+ snprintf(pattern, sizeof(pattern), "\"%s\":", key);
155
+ const char* start = strstr(json, pattern);
156
+ if (!start) return NULL;
157
+ start += strlen(pattern);
158
+ while (*start == ' ') start++;
159
+
160
+ if (*start == '"') {
161
+ const char* end = start + 1;
162
+ while (*end && *end != '"') {
163
+ if (*end == '\\' && *(end + 1)) end++;
164
+ end++;
165
+ }
166
+ if (*end == '"') end++;
167
+ size_t len = (size_t)(end - start);
168
+ char* result = (char*)malloc(len + 1);
169
+ memcpy(result, start, len);
170
+ result[len] = '\0';
171
+ return result;
172
+ }
173
+
174
+ if (*start == '{' || *start == '[') {
175
+ int depth = 0;
176
+ const char* end = start;
177
+ char open = *start;
178
+ char close = (open == '{') ? '}' : ']';
179
+ while (*end) {
180
+ if (*end == open) depth++;
181
+ else if (*end == close) { depth--; if (depth == 0) { end++; break; } }
182
+ else if (*end == '"') {
183
+ end++;
184
+ while (*end && *end != '"') {
185
+ if (*end == '\\' && *(end + 1)) end++;
186
+ end++;
187
+ }
188
+ }
189
+ end++;
190
+ }
191
+ size_t len = (size_t)(end - start);
192
+ char* result = (char*)malloc(len + 1);
193
+ memcpy(result, start, len);
194
+ result[len] = '\0';
195
+ return result;
196
+ }
197
+
198
+ const char* end = start;
199
+ while (*end && *end != ',' && *end != '}' && *end != ']') end++;
200
+ size_t len = (size_t)(end - start);
201
+ char* result = (char*)malloc(len + 1);
202
+ memcpy(result, start, len);
203
+ result[len] = '\0';
204
+ return result;
205
+ }
206
+
207
+ // -----------------------------------------------------------------------
208
+ // Worker error dispatch helpers
209
+ // -----------------------------------------------------------------------
210
+
211
+ static void zapp_worker_dispatch_error_message(const char* workerId, const char* message) {
212
+ if (!workerId) return;
213
+ const char* safeMsg = (message && message[0]) ? message : "Worker error";
214
+ char payload[1024];
215
+ snprintf(payload, sizeof(payload), "{\"message\":\"%s\"}", safeMsg);
216
+ zapp_dispatch_worker_to_webviews("error", workerId, payload);
217
+ }
218
+
219
+ static void zapp_worker_dispatch_max_workers_error(const char* workerId, int maxWorkers) {
220
+ char msg[256];
221
+ snprintf(msg, sizeof(msg), "Max worker limit (%d) exceeded.", maxWorkers);
222
+ zapp_worker_dispatch_error_message(workerId, msg);
223
+ }
224
+
225
+ // -----------------------------------------------------------------------
226
+ // Asset / script loading
227
+ // -----------------------------------------------------------------------
228
+
229
+ #ifndef ZAPP_EMBEDDED_ASSET_STRUCT_DEFINED
230
+ #define ZAPP_EMBEDDED_ASSET_STRUCT_DEFINED 1
231
+ struct ZappEmbeddedAsset {
232
+ char* path;
233
+ unsigned char* data;
234
+ int len;
235
+ int is_brotli;
236
+ int uncompressed_len;
237
+ };
238
+ #endif
239
+
240
+ extern struct ZappEmbeddedAsset zapp_embedded_assets[];
241
+ extern int zapp_embedded_assets_count;
242
+
243
+ static const char* zapp_worker_asset_root(void) {
244
+ const char* configuredRoot = zapp_build_asset_root();
245
+ if (configuredRoot != NULL && configuredRoot[0] != '\0') {
246
+ return configuredRoot;
247
+ }
248
+ return "example\\frontend\\dist";
249
+ }
250
+
251
+ #define ZAPP_WORKER_LOCALHOST_PREFIX "https://app.localhost/"
252
+ #define ZAPP_WORKER_LOCALHOST_PREFIX_LEN 22
253
+
254
+ static char* zapp_worker_resolve_rel_path(const char* scriptUrl) {
255
+ if (!scriptUrl) return NULL;
256
+
257
+ const char* rel = NULL;
258
+
259
+ if (strncmp(scriptUrl, ZAPP_WORKER_LOCALHOST_PREFIX, ZAPP_WORKER_LOCALHOST_PREFIX_LEN) == 0) {
260
+ rel = scriptUrl + ZAPP_WORKER_LOCALHOST_PREFIX_LEN;
261
+ } else if (strncmp(scriptUrl, "zapp://", 7) == 0) {
262
+ const char* after_scheme = scriptUrl + 7;
263
+ const char* slash = strchr(after_scheme, '/');
264
+ rel = slash ? slash + 1 : after_scheme;
265
+ } else {
266
+ return NULL;
267
+ }
268
+
269
+ while (*rel == '/') rel++;
270
+ if (strncmp(rel, "app/", 4) == 0) rel += 4;
271
+ if (strncmp(rel, "index.html/", 11) == 0) rel += 11;
272
+
273
+ if (!*rel) return NULL;
274
+ return _strdup(rel);
275
+ }
276
+
277
+ // Synchronous HTTP GET using WinHTTP (used in dev mode to fetch worker scripts)
278
+ static char* zapp_worker_http_get(const char* url) {
279
+ if (!url) return NULL;
280
+
281
+ // Parse host, port, path from http://host:port/path
282
+ const char* hostStart = url;
283
+ if (strncmp(url, "http://", 7) == 0) hostStart = url + 7;
284
+ else if (strncmp(url, "https://", 8) == 0) hostStart = url + 8;
285
+ else return NULL;
286
+
287
+ char host[256] = {0};
288
+ INTERNET_PORT port = (url[4] == 's') ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;
289
+ const char* slash = strchr(hostStart, '/');
290
+ const char* colon = strchr(hostStart, ':');
291
+ if (colon && (!slash || colon < slash)) {
292
+ size_t hlen = (size_t)(colon - hostStart);
293
+ if (hlen >= sizeof(host)) return NULL;
294
+ memcpy(host, hostStart, hlen);
295
+ port = (INTERNET_PORT)atoi(colon + 1);
296
+ } else if (slash) {
297
+ size_t hlen = (size_t)(slash - hostStart);
298
+ if (hlen >= sizeof(host)) return NULL;
299
+ memcpy(host, hostStart, hlen);
300
+ } else {
301
+ strncpy(host, hostStart, sizeof(host) - 1);
302
+ }
303
+
304
+ const char* pathStr = slash ? slash : "/";
305
+ wchar_t wHost[256], wPath[1024];
306
+ MultiByteToWideChar(CP_UTF8, 0, host, -1, wHost, 256);
307
+ MultiByteToWideChar(CP_UTF8, 0, pathStr, -1, wPath, 1024);
308
+
309
+ HINTERNET session = WinHttpOpen(L"Zapp/1.0", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
310
+ if (!session) return NULL;
311
+
312
+ HINTERNET connection = WinHttpConnect(session, wHost, port, 0);
313
+ if (!connection) { WinHttpCloseHandle(session); return NULL; }
314
+
315
+ DWORD flags = (url[4] == 's') ? WINHTTP_FLAG_SECURE : 0;
316
+ HINTERNET request = WinHttpOpenRequest(connection, L"GET", wPath, NULL, NULL, NULL, flags);
317
+ if (!request) { WinHttpCloseHandle(connection); WinHttpCloseHandle(session); return NULL; }
318
+
319
+ if (!WinHttpSendRequest(request, NULL, 0, NULL, 0, 0, 0) ||
320
+ !WinHttpReceiveResponse(request, NULL)) {
321
+ WinHttpCloseHandle(request); WinHttpCloseHandle(connection); WinHttpCloseHandle(session);
322
+ return NULL;
323
+ }
324
+
325
+ size_t totalLen = 0, cap = 4096;
326
+ char* buf = (char*)malloc(cap);
327
+ DWORD bytesRead = 0;
328
+ while (WinHttpReadData(request, buf + totalLen, (DWORD)(cap - totalLen - 1), &bytesRead) && bytesRead > 0) {
329
+ totalLen += bytesRead;
330
+ if (totalLen + 1 >= cap) { cap *= 2; buf = (char*)realloc(buf, cap); }
331
+ bytesRead = 0;
332
+ }
333
+ buf[totalLen] = '\0';
334
+
335
+ WinHttpCloseHandle(request);
336
+ WinHttpCloseHandle(connection);
337
+ WinHttpCloseHandle(session);
338
+ return (totalLen > 0) ? buf : (free(buf), (char*)NULL);
339
+ }
340
+
341
+ static char* zapp_worker_read_source(const char* scriptUrl) {
342
+ if (!scriptUrl || !*scriptUrl) return NULL;
343
+
344
+ char* rel = zapp_worker_resolve_rel_path(scriptUrl);
345
+ if (rel) {
346
+ // Try embedded assets first
347
+ if (zapp_build_use_embedded_assets() && zapp_embedded_assets_count > 0) {
348
+ char lookupPath[512];
349
+ snprintf(lookupPath, sizeof(lookupPath), "/%s", rel);
350
+ for (int i = 0; i < zapp_embedded_assets_count; i++) {
351
+ if (strcmp(zapp_embedded_assets[i].path, lookupPath) == 0) {
352
+ char* result = (char*)malloc(zapp_embedded_assets[i].len + 1);
353
+ memcpy(result, zapp_embedded_assets[i].data, zapp_embedded_assets[i].len);
354
+ result[zapp_embedded_assets[i].len] = '\0';
355
+ free(rel);
356
+ return result;
357
+ }
358
+ }
359
+ }
360
+
361
+ // Try local filesystem
362
+ const char* root = zapp_worker_asset_root();
363
+ char fullPath[1024];
364
+ snprintf(fullPath, sizeof(fullPath), "%s\\%s", root, rel);
365
+ // Normalize slashes
366
+ for (char* p = fullPath; *p; p++) { if (*p == '/') *p = '\\'; }
367
+
368
+ FILE* f = fopen(fullPath, "rb");
369
+ if (f) {
370
+ fseek(f, 0, SEEK_END);
371
+ long len = ftell(f);
372
+ fseek(f, 0, SEEK_SET);
373
+ if (len > 0) {
374
+ char* result = (char*)malloc((size_t)len + 1);
375
+ fread(result, 1, (size_t)len, f);
376
+ result[len] = '\0';
377
+ fclose(f);
378
+ free(rel);
379
+ return result;
380
+ }
381
+ fclose(f);
382
+ }
383
+ free(rel);
384
+ }
385
+
386
+ // HTTP(S) URLs: fetch from dev server or remote
387
+ if (strncmp(scriptUrl, "http://", 7) == 0 || strncmp(scriptUrl, "https://", 8) == 0) {
388
+ return zapp_worker_http_get(scriptUrl);
389
+ }
390
+
391
+ FILE* f = fopen(scriptUrl, "rb");
392
+ if (f) {
393
+ fseek(f, 0, SEEK_END);
394
+ long len = ftell(f);
395
+ fseek(f, 0, SEEK_SET);
396
+ if (len > 0) {
397
+ char* result = (char*)malloc((size_t)len + 1);
398
+ fread(result, 1, (size_t)len, f);
399
+ result[len] = '\0';
400
+ fclose(f);
401
+ return result;
402
+ }
403
+ fclose(f);
404
+ }
405
+
406
+ return NULL;
407
+ }
408
+ #endif
409
+ }
@@ -0,0 +1,52 @@
1
+ // Win32-native base64 encoding/decoding.
2
+
3
+ raw {
4
+ #ifdef _WIN32
5
+ #include <windows.h>
6
+ #include <wincrypt.h>
7
+ #include <stdlib.h>
8
+ #include <string.h>
9
+
10
+ char* zapp_core_btoa(const char* input) {
11
+ if (input == NULL || input[0] == '\0') return _strdup("");
12
+ DWORD inputLen = (DWORD)strlen(input);
13
+ DWORD b64Len = 0;
14
+
15
+ CryptBinaryToStringA((const BYTE*)input, inputLen,
16
+ CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &b64Len);
17
+ if (b64Len == 0) return _strdup("");
18
+
19
+ char* b64 = (char*)malloc(b64Len + 1);
20
+ if (!CryptBinaryToStringA((const BYTE*)input, inputLen,
21
+ CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, b64, &b64Len)) {
22
+ free(b64);
23
+ return _strdup("");
24
+ }
25
+ b64[b64Len] = '\0';
26
+ // Trim trailing whitespace
27
+ while (b64Len > 0 && (b64[b64Len - 1] == '\n' || b64[b64Len - 1] == '\r' || b64[b64Len - 1] == ' ')) {
28
+ b64[--b64Len] = '\0';
29
+ }
30
+ return b64;
31
+ }
32
+
33
+ char* zapp_core_atob(const char* input) {
34
+ if (input == NULL || input[0] == '\0') return _strdup("");
35
+ DWORD inputLen = (DWORD)strlen(input);
36
+ DWORD binLen = 0;
37
+
38
+ CryptStringToBinaryA(input, inputLen,
39
+ CRYPT_STRING_BASE64, NULL, &binLen, NULL, NULL);
40
+ if (binLen == 0) return _strdup("");
41
+
42
+ BYTE* bin = (BYTE*)malloc(binLen + 1);
43
+ if (!CryptStringToBinaryA(input, inputLen,
44
+ CRYPT_STRING_BASE64, bin, &binLen, NULL, NULL)) {
45
+ free(bin);
46
+ return _strdup("");
47
+ }
48
+ bin[binLen] = '\0';
49
+ return (char*)bin;
50
+ }
51
+ #endif
52
+ }
@@ -0,0 +1,34 @@
1
+ // Win32-native crypto: random bytes (BCryptGenRandom) and UUID (UuidCreate).
2
+
3
+ //> windows: link: -lbcrypt -lrpcrt4
4
+
5
+ raw {
6
+ #ifdef _WIN32
7
+ #include <windows.h>
8
+ #include <bcrypt.h>
9
+ #include <rpc.h>
10
+ #include <stdio.h>
11
+ #include <stdlib.h>
12
+ #include <string.h>
13
+
14
+ void zapp_core_crypto_random_bytes(unsigned char* buf, size_t len) {
15
+ if (buf && len > 0) {
16
+ BCryptGenRandom(NULL, buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
17
+ }
18
+ }
19
+
20
+ char* zapp_core_crypto_random_uuid(void) {
21
+ UUID uuid;
22
+ UuidCreate(&uuid);
23
+ RPC_CSTR uuidStr = NULL;
24
+ UuidToStringA(&uuid, &uuidStr);
25
+ char* result = _strdup((char*)uuidStr);
26
+ RpcStringFreeA(&uuidStr);
27
+ // Lowercase to match web standard
28
+ for (char* p = result; *p; p++) {
29
+ if (*p >= 'A' && *p <= 'F') *p += 32;
30
+ }
31
+ return result;
32
+ }
33
+ #endif
34
+ }
@@ -0,0 +1,60 @@
1
+ // Win32-native text encoding/decoding with proper UTF-8 validation.
2
+
3
+ raw {
4
+ #ifdef _WIN32
5
+ #include <windows.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+
9
+ // TextEncoder.encode(): converts a UTF-8 string to its byte representation.
10
+ unsigned char* zapp_core_text_encode(const char* input, size_t* out_len) {
11
+ if (out_len) *out_len = 0;
12
+ if (input == NULL) return NULL;
13
+ size_t len = strlen(input);
14
+ if (len == 0) return NULL;
15
+ unsigned char* copy = (unsigned char*)malloc(len);
16
+ if (!copy) return NULL;
17
+ memcpy(copy, input, len);
18
+ if (out_len) *out_len = len;
19
+ return copy;
20
+ }
21
+
22
+ // TextDecoder.decode(): validates the byte sequence as UTF-8 via
23
+ // MultiByteToWideChar round-trip, returning a valid UTF-8 C string.
24
+ // Invalid sequences are replaced with U+FFFD.
25
+ char* zapp_core_text_decode(const unsigned char* bytes, size_t len) {
26
+ if (bytes == NULL || len == 0) return _strdup("");
27
+
28
+ // First pass: determine required wide-char buffer size.
29
+ int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (const char*)bytes, (int)len, NULL, 0);
30
+ if (wlen > 0) {
31
+ // Valid UTF-8 — fast path: just copy as-is.
32
+ char* result = (char*)malloc(len + 1);
33
+ if (!result) return _strdup("");
34
+ memcpy(result, bytes, len);
35
+ result[len] = '\0';
36
+ return result;
37
+ }
38
+
39
+ // Invalid UTF-8 detected. Use the lenient flag (0) which replaces
40
+ // bad sequences, then round-trip back to UTF-8.
41
+ wlen = MultiByteToWideChar(CP_UTF8, 0, (const char*)bytes, (int)len, NULL, 0);
42
+ if (wlen <= 0) return _strdup("");
43
+
44
+ wchar_t* wbuf = (wchar_t*)malloc((size_t)wlen * sizeof(wchar_t));
45
+ if (!wbuf) return _strdup("");
46
+ MultiByteToWideChar(CP_UTF8, 0, (const char*)bytes, (int)len, wbuf, wlen);
47
+
48
+ // Convert back to UTF-8
49
+ int ulen = WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, NULL, 0, NULL, NULL);
50
+ if (ulen <= 0) { free(wbuf); return _strdup(""); }
51
+
52
+ char* result = (char*)malloc((size_t)ulen + 1);
53
+ if (!result) { free(wbuf); return _strdup(""); }
54
+ WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, result, ulen, NULL, NULL);
55
+ result[ulen] = '\0';
56
+ free(wbuf);
57
+ return result;
58
+ }
59
+ #endif
60
+ }