@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.
- package/README.md +55 -0
- package/dist/zapp-cli.js +9471 -0
- package/native/src/app/app.zc +490 -0
- package/native/src/event/event.zc +24 -0
- package/native/src/event/events.zc +70 -0
- package/native/src/platform/darwin/backend.zc +923 -0
- package/native/src/platform/darwin/backend_bootstrap.zc +9 -0
- package/native/src/platform/darwin/bootstrap.zc +9 -0
- package/native/src/platform/darwin/engine_jsc.zc +86 -0
- package/native/src/platform/darwin/engine_qjs.zc +92 -0
- package/native/src/platform/darwin/platform.zc +156 -0
- package/native/src/platform/darwin/webview.zc +550 -0
- package/native/src/platform/darwin/webview_bootstrap.zc +9 -0
- package/native/src/platform/darwin/window.zc +1223 -0
- package/native/src/platform/darwin/worker/common.zc +223 -0
- package/native/src/platform/darwin/worker/core/base64_core.zc +29 -0
- package/native/src/platform/darwin/worker/core/crypto_core.zc +19 -0
- package/native/src/platform/darwin/worker/core/encoding_core.zc +32 -0
- package/native/src/platform/darwin/worker/core/fetch_core.zc +145 -0
- package/native/src/platform/darwin/worker/core/url_core.zc +69 -0
- package/native/src/platform/darwin/worker/core/websocket_core.zc +179 -0
- package/native/src/platform/darwin/worker/dispatch.zc +55 -0
- package/native/src/platform/darwin/worker/jsc/base64_jsc.zc +39 -0
- package/native/src/platform/darwin/worker/jsc/crypto_jsc.zc +49 -0
- package/native/src/platform/darwin/worker/jsc/encoding_jsc.zc +86 -0
- package/native/src/platform/darwin/worker/jsc/fetch_jsc.zc +149 -0
- package/native/src/platform/darwin/worker/jsc/url_jsc.zc +54 -0
- package/native/src/platform/darwin/worker/jsc/websocket_jsc.zc +127 -0
- package/native/src/platform/darwin/worker/jsc.zc +670 -0
- package/native/src/platform/darwin/worker/mod.zc +30 -0
- package/native/src/platform/darwin/worker/qjs/fetch_qjs.zc +233 -0
- package/native/src/platform/darwin/worker/qjs/qjs_macros.zc +23 -0
- package/native/src/platform/darwin/worker/qjs/websocket_qjs.zc +223 -0
- package/native/src/platform/darwin/worker/qjs.zc +1053 -0
- package/native/src/platform/darwin/worker/timers.zc +149 -0
- package/native/src/platform/darwin/worker/timers_qjs.zc +209 -0
- package/native/src/platform/platform.zc +64 -0
- package/native/src/platform/shared/log.zc +156 -0
- package/native/src/platform/shared/worker/qjs/base64_qjs.zc +38 -0
- package/native/src/platform/shared/worker/qjs/crypto_qjs.zc +44 -0
- package/native/src/platform/shared/worker/qjs/encoding_qjs.zc +95 -0
- package/native/src/platform/shared/worker/qjs/url_qjs.zc +65 -0
- package/native/src/platform/shared/worker_registry.zc +206 -0
- package/native/src/platform/window.zc +446 -0
- package/native/src/platform/windows/backend.zc +452 -0
- package/native/src/platform/windows/backend_bootstrap.zc +9 -0
- package/native/src/platform/windows/bootstrap.zc +9 -0
- package/native/src/platform/windows/engine_qjs.zc +60 -0
- package/native/src/platform/windows/platform.zc +387 -0
- package/native/src/platform/windows/webview.zc +1175 -0
- package/native/src/platform/windows/webview_bootstrap.zc +9 -0
- package/native/src/platform/windows/window.zc +1271 -0
- package/native/src/platform/windows/worker/common.zc +409 -0
- package/native/src/platform/windows/worker/core/base64_core.zc +52 -0
- package/native/src/platform/windows/worker/core/crypto_core.zc +34 -0
- package/native/src/platform/windows/worker/core/encoding_core.zc +60 -0
- package/native/src/platform/windows/worker/core/fetch_core.zc +274 -0
- package/native/src/platform/windows/worker/core/url_core.zc +216 -0
- package/native/src/platform/windows/worker/core/websocket_core.zc +343 -0
- package/native/src/platform/windows/worker/dispatch.zc +34 -0
- package/native/src/platform/windows/worker/mod.zc +46 -0
- package/native/src/platform/windows/worker/qjs/fetch_qjs.zc +255 -0
- package/native/src/platform/windows/worker/qjs/websocket_qjs.zc +263 -0
- package/native/src/platform/windows/worker/qjs.zc +1049 -0
- package/native/src/platform/windows/worker/timers_qjs.zc +288 -0
- package/native/src/platform/worker.zc +8 -0
- package/native/src/service/service.zc +228 -0
- package/native/vendor/quickjs-ng/.gitattributes +4 -0
- package/native/vendor/quickjs-ng/.github/dependabot.yml +7 -0
- package/native/vendor/quickjs-ng/.github/workflows/ci.yml +812 -0
- package/native/vendor/quickjs-ng/.github/workflows/docs.yml +49 -0
- package/native/vendor/quickjs-ng/.github/workflows/release.yml +162 -0
- package/native/vendor/quickjs-ng/.github/workflows/test-docs.yml +23 -0
- package/native/vendor/quickjs-ng/.github/workflows/tsan.yml +32 -0
- package/native/vendor/quickjs-ng/.github/workflows/valgrind.yml +33 -0
- package/native/vendor/quickjs-ng/.gitmodules +5 -0
- package/native/vendor/quickjs-ng/CMakeLists.txt +553 -0
- package/native/vendor/quickjs-ng/LICENSE +24 -0
- package/native/vendor/quickjs-ng/Makefile +149 -0
- package/native/vendor/quickjs-ng/amalgam.js +53 -0
- package/native/vendor/quickjs-ng/api-test.c +927 -0
- package/native/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
- package/native/vendor/quickjs-ng/builtin-array-fromasync.js +36 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.js +194 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip.js +210 -0
- package/native/vendor/quickjs-ng/ctest.c +17 -0
- package/native/vendor/quickjs-ng/cutils.h +2013 -0
- package/native/vendor/quickjs-ng/cxxtest.cc +2 -0
- package/native/vendor/quickjs-ng/dtoa.c +1619 -0
- package/native/vendor/quickjs-ng/dtoa.h +87 -0
- package/native/vendor/quickjs-ng/examples/fib.c +67 -0
- package/native/vendor/quickjs-ng/examples/fib_module.js +10 -0
- package/native/vendor/quickjs-ng/examples/hello.js +1 -0
- package/native/vendor/quickjs-ng/examples/hello_module.js +6 -0
- package/native/vendor/quickjs-ng/examples/meson.build +17 -0
- package/native/vendor/quickjs-ng/examples/pi_bigint.js +118 -0
- package/native/vendor/quickjs-ng/examples/point.c +154 -0
- package/native/vendor/quickjs-ng/examples/test_fib.js +8 -0
- package/native/vendor/quickjs-ng/examples/test_point.js +43 -0
- package/native/vendor/quickjs-ng/fuzz.c +51 -0
- package/native/vendor/quickjs-ng/gen/function_source.c +81 -0
- package/native/vendor/quickjs-ng/gen/hello.c +53 -0
- package/native/vendor/quickjs-ng/gen/hello_module.c +106 -0
- package/native/vendor/quickjs-ng/gen/repl.c +3053 -0
- package/native/vendor/quickjs-ng/gen/standalone.c +324 -0
- package/native/vendor/quickjs-ng/gen/test_fib.c +81 -0
- package/native/vendor/quickjs-ng/libregexp-opcode.h +58 -0
- package/native/vendor/quickjs-ng/libregexp.c +2687 -0
- package/native/vendor/quickjs-ng/libregexp.h +98 -0
- package/native/vendor/quickjs-ng/libunicode-table.h +4707 -0
- package/native/vendor/quickjs-ng/libunicode.c +1746 -0
- package/native/vendor/quickjs-ng/libunicode.h +126 -0
- package/native/vendor/quickjs-ng/list.h +107 -0
- package/native/vendor/quickjs-ng/lre-test.c +73 -0
- package/native/vendor/quickjs-ng/meson.build +684 -0
- package/native/vendor/quickjs-ng/meson_options.txt +6 -0
- package/native/vendor/quickjs-ng/qjs-wasi-reactor.c +208 -0
- package/native/vendor/quickjs-ng/qjs.c +748 -0
- package/native/vendor/quickjs-ng/qjsc.c +673 -0
- package/native/vendor/quickjs-ng/quickjs-atom.h +267 -0
- package/native/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
- package/native/vendor/quickjs-ng/quickjs-libc.c +4986 -0
- package/native/vendor/quickjs-ng/quickjs-libc.h +79 -0
- package/native/vendor/quickjs-ng/quickjs-opcode.h +369 -0
- package/native/vendor/quickjs-ng/quickjs.c +60259 -0
- package/native/vendor/quickjs-ng/quickjs.h +1419 -0
- package/native/vendor/quickjs-ng/repl.js +1927 -0
- package/native/vendor/quickjs-ng/run-test262.c +2417 -0
- package/native/vendor/quickjs-ng/standalone.js +129 -0
- package/native/vendor/quickjs-ng/tests/assert.js +49 -0
- package/native/vendor/quickjs-ng/tests/bug1221.js +16 -0
- package/native/vendor/quickjs-ng/tests/bug1296.js +12 -0
- package/native/vendor/quickjs-ng/tests/bug1297.js +22 -0
- package/native/vendor/quickjs-ng/tests/bug1301.js +21 -0
- package/native/vendor/quickjs-ng/tests/bug1302.js +24 -0
- package/native/vendor/quickjs-ng/tests/bug1305.js +26 -0
- package/native/vendor/quickjs-ng/tests/bug1318.js +54 -0
- package/native/vendor/quickjs-ng/tests/bug1352.js +8 -0
- package/native/vendor/quickjs-ng/tests/bug1354.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug1355.js +58 -0
- package/native/vendor/quickjs-ng/tests/bug1368.js +9 -0
- package/native/vendor/quickjs-ng/tests/bug39/1.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug39/2.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug39/3.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug488-upstream.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug633/0.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug633/1.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug633/2.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug633/3.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug645/0.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug645/1.js +9 -0
- package/native/vendor/quickjs-ng/tests/bug645/2.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug648.js +13 -0
- package/native/vendor/quickjs-ng/tests/bug652.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug741.js +19 -0
- package/native/vendor/quickjs-ng/tests/bug775.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug776.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug832.js +2 -0
- package/native/vendor/quickjs-ng/tests/bug858.js +26 -0
- package/native/vendor/quickjs-ng/tests/bug904.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug988.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug999.js +3 -0
- package/native/vendor/quickjs-ng/tests/destructured-export.js +8 -0
- package/native/vendor/quickjs-ng/tests/detect_module/0.js +1 -0
- package/native/vendor/quickjs-ng/tests/detect_module/1.js +2 -0
- package/native/vendor/quickjs-ng/tests/detect_module/2.js +1 -0
- package/native/vendor/quickjs-ng/tests/detect_module/3.js +8 -0
- package/native/vendor/quickjs-ng/tests/detect_module/4.js +3 -0
- package/native/vendor/quickjs-ng/tests/empty.js +0 -0
- package/native/vendor/quickjs-ng/tests/fixture_cyclic_import.js +2 -0
- package/native/vendor/quickjs-ng/tests/fixture_string_exports.js +12 -0
- package/native/vendor/quickjs-ng/tests/function_source.js +14 -0
- package/native/vendor/quickjs-ng/tests/microbench.js +1267 -0
- package/native/vendor/quickjs-ng/tests/null_or_undefined.js +38 -0
- package/native/vendor/quickjs-ng/tests/str-pad-leak.js +5 -0
- package/native/vendor/quickjs-ng/tests/test_bigint.js +107 -0
- package/native/vendor/quickjs-ng/tests/test_bjson.js +366 -0
- package/native/vendor/quickjs-ng/tests/test_builtin.js +1314 -0
- package/native/vendor/quickjs-ng/tests/test_closure.js +220 -0
- package/native/vendor/quickjs-ng/tests/test_cyclic_import.js +12 -0
- package/native/vendor/quickjs-ng/tests/test_domexception.js +35 -0
- package/native/vendor/quickjs-ng/tests/test_language.js +755 -0
- package/native/vendor/quickjs-ng/tests/test_loop.js +367 -0
- package/native/vendor/quickjs-ng/tests/test_queue_microtask.js +39 -0
- package/native/vendor/quickjs-ng/tests/test_std.js +340 -0
- package/native/vendor/quickjs-ng/tests/test_string_exports.js +25 -0
- package/native/vendor/quickjs-ng/tests/test_worker.js +43 -0
- package/native/vendor/quickjs-ng/tests/test_worker_module.js +30 -0
- package/native/vendor/quickjs-ng/tests.conf +14 -0
- package/native/vendor/quickjs-ng/unicode_download.sh +19 -0
- package/native/vendor/quickjs-ng/unicode_gen.c +3108 -0
- package/native/vendor/quickjs-ng/unicode_gen_def.h +310 -0
- package/native/vendor/quickjs-ng/update-version.sh +32 -0
- package/native/vendor/webview2/include/WebView2.h +60636 -0
- package/native/vendor/webview2/include/WebView2EnvironmentOptions.h +406 -0
- package/package.json +33 -0
- package/src/backend.ts +139 -0
- package/src/build-config.ts +87 -0
- package/src/build.ts +276 -0
- package/src/common.ts +195 -0
- package/src/config.ts +89 -0
- package/src/dev.ts +164 -0
- package/src/generate.ts +200 -0
- package/src/icons.ts +116 -0
- package/src/init.ts +190 -0
- package/src/package.ts +150 -0
- package/src/zapp-cli.ts +263 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// Shared worker bridge helpers used by the Darwin backends.
|
|
2
|
+
// This keeps request parsing and standard error payloads engine-agnostic so
|
|
3
|
+
// additional engines do not need to reimplement the same bridge boilerplate.
|
|
4
|
+
|
|
5
|
+
include <stdlib.h>
|
|
6
|
+
include <stdbool.h>
|
|
7
|
+
|
|
8
|
+
raw {
|
|
9
|
+
#ifdef __APPLE__
|
|
10
|
+
#include <Foundation/Foundation.h>
|
|
11
|
+
#include <compression.h>
|
|
12
|
+
#ifndef ZAPP_URL_PARSED_DEFINED
|
|
13
|
+
#define ZAPP_URL_PARSED_DEFINED 1
|
|
14
|
+
typedef struct zapp_url_parsed {
|
|
15
|
+
char* href;
|
|
16
|
+
char* protocol;
|
|
17
|
+
char* host;
|
|
18
|
+
char* hostname;
|
|
19
|
+
char* port;
|
|
20
|
+
char* pathname;
|
|
21
|
+
char* search;
|
|
22
|
+
char* hash;
|
|
23
|
+
char* origin;
|
|
24
|
+
char* username;
|
|
25
|
+
char* password;
|
|
26
|
+
} zapp_url_parsed_t;
|
|
27
|
+
|
|
28
|
+
typedef void (*zapp_ws_event_fn)(
|
|
29
|
+
const char* ws_id,
|
|
30
|
+
const char* event_type,
|
|
31
|
+
const char* json_payload,
|
|
32
|
+
void* user_data
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
typedef struct {
|
|
36
|
+
int status;
|
|
37
|
+
char* status_text;
|
|
38
|
+
char** header_keys;
|
|
39
|
+
char** header_values;
|
|
40
|
+
int header_count;
|
|
41
|
+
char* body;
|
|
42
|
+
char* body_base64;
|
|
43
|
+
} zapp_fetch_response_t;
|
|
44
|
+
|
|
45
|
+
typedef void (^zapp_fetch_completion_t)(zapp_fetch_response_t* response, NSString* error);
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
#ifndef ZAPP_EMBEDDED_ASSET_STRUCT_DEFINED
|
|
49
|
+
#define ZAPP_EMBEDDED_ASSET_STRUCT_DEFINED 1
|
|
50
|
+
struct ZappEmbeddedAsset {
|
|
51
|
+
char* path;
|
|
52
|
+
uint8_t* data;
|
|
53
|
+
int len;
|
|
54
|
+
bool is_brotli;
|
|
55
|
+
int uncompressed_len;
|
|
56
|
+
};
|
|
57
|
+
#endif
|
|
58
|
+
|
|
59
|
+
extern struct ZappEmbeddedAsset zapp_embedded_assets[];
|
|
60
|
+
extern int zapp_embedded_assets_count;
|
|
61
|
+
extern const char* zapp_build_asset_root(void);
|
|
62
|
+
extern int zapp_build_use_embedded_assets(void);
|
|
63
|
+
extern void zapp_dispatch_worker_to_webviews(const char* kind, const char* worker_id, const char* payload_json);
|
|
64
|
+
|
|
65
|
+
static NSDictionary* zapp_worker_parse_bridge_payload(const char* payload_c) {
|
|
66
|
+
if (payload_c == NULL) return nil;
|
|
67
|
+
NSString* payload = [NSString stringWithUTF8String:payload_c];
|
|
68
|
+
if (payload == nil) return nil;
|
|
69
|
+
NSData* jsonData = [payload dataUsingEncoding:NSUTF8StringEncoding];
|
|
70
|
+
if (jsonData == nil) return nil;
|
|
71
|
+
NSDictionary* body = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
|
|
72
|
+
return [body isKindOfClass:[NSDictionary class]] ? body : nil;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static NSString* zapp_worker_body_owner_id(NSDictionary* body) {
|
|
76
|
+
NSString* ownerId = body[@"ownerId"];
|
|
77
|
+
return [ownerId isKindOfClass:[NSString class]] ? ownerId : nil;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static NSString* zapp_worker_body_worker_id(NSDictionary* body) {
|
|
81
|
+
NSString* workerId = body[@"id"];
|
|
82
|
+
if (![workerId isKindOfClass:[NSString class]] || [workerId length] == 0) return nil;
|
|
83
|
+
return workerId;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static NSString* zapp_worker_body_script_url(NSDictionary* body) {
|
|
87
|
+
NSString* scriptUrl = body[@"scriptUrl"];
|
|
88
|
+
return [scriptUrl isKindOfClass:[NSString class]] ? scriptUrl : nil;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static BOOL zapp_worker_body_shared(NSDictionary* body) {
|
|
92
|
+
id sharedObj = body[@"shared"];
|
|
93
|
+
if ([sharedObj respondsToSelector:@selector(boolValue)]) {
|
|
94
|
+
return [sharedObj boolValue] ? YES : NO;
|
|
95
|
+
}
|
|
96
|
+
return NO;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static void zapp_worker_dispatch_error_json(NSString* workerId, NSString* payloadJson) {
|
|
100
|
+
if (![workerId isKindOfClass:[NSString class]] || [workerId length] == 0) return;
|
|
101
|
+
NSString* json = ([payloadJson isKindOfClass:[NSString class]] && [payloadJson length] > 0)
|
|
102
|
+
? payloadJson
|
|
103
|
+
: @"{\"message\":\"Worker error\"}";
|
|
104
|
+
zapp_dispatch_worker_to_webviews("error", [workerId UTF8String], [json UTF8String]);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static void zapp_worker_dispatch_error_message(NSString* workerId, NSString* message) {
|
|
108
|
+
NSString* safeMessage = ([message isKindOfClass:[NSString class]] && [message length] > 0)
|
|
109
|
+
? message
|
|
110
|
+
: @"Worker error";
|
|
111
|
+
NSString* payloadJson = [NSString stringWithFormat:@"{\"message\":\"%@\"}", safeMessage];
|
|
112
|
+
zapp_worker_dispatch_error_json(workerId, payloadJson);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static void zapp_worker_dispatch_max_workers_error(NSString* workerId, int maxWorkers) {
|
|
116
|
+
NSString* errMsg = [NSString stringWithFormat:@"Max worker limit (%d) exceeded.", maxWorkers];
|
|
117
|
+
zapp_worker_dispatch_error_message(workerId, errMsg);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static NSString* zapp_worker_asset_root(void) {
|
|
121
|
+
const char* configuredRoot = zapp_build_asset_root();
|
|
122
|
+
if (configuredRoot != NULL && configuredRoot[0] != '\0') {
|
|
123
|
+
return [NSString stringWithUTF8String:configuredRoot];
|
|
124
|
+
}
|
|
125
|
+
return [[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent:@"example/frontend/dist"];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static NSString* zapp_worker_resolve_rel_path(NSURL* url) {
|
|
129
|
+
if (url == nil) return nil;
|
|
130
|
+
NSString* scheme = [[url scheme] lowercaseString];
|
|
131
|
+
if (![scheme isEqualToString:@"zapp"]) return nil;
|
|
132
|
+
|
|
133
|
+
NSString* host = url.host ?: @"";
|
|
134
|
+
NSString* path = url.path ?: @"";
|
|
135
|
+
NSString* rel = path;
|
|
136
|
+
|
|
137
|
+
if ((rel.length == 0 || [rel isEqualToString:@"/"]) && host.length > 0) {
|
|
138
|
+
rel = [@"/" stringByAppendingString:host];
|
|
139
|
+
}
|
|
140
|
+
if ([rel hasPrefix:@"/zapp-workers/"]) {
|
|
141
|
+
// already normalized
|
|
142
|
+
} else if ([rel hasPrefix:@"/assets/"]) {
|
|
143
|
+
// keep assets path if used in workers
|
|
144
|
+
} else if ([rel hasPrefix:@"/index.html/"]) {
|
|
145
|
+
rel = [rel substringFromIndex:[@"/index.html/" length] - 1];
|
|
146
|
+
} else if ([rel hasPrefix:@"/app/"]) {
|
|
147
|
+
rel = [rel substringFromIndex:[@"/app/" length] - 1];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
while ([rel hasPrefix:@"/"]) {
|
|
151
|
+
rel = [rel substringFromIndex:1];
|
|
152
|
+
}
|
|
153
|
+
if (rel.length == 0) return nil;
|
|
154
|
+
|
|
155
|
+
return rel;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static NSString* zapp_worker_resolve_local_path(NSURL* url) {
|
|
159
|
+
NSString* rel = zapp_worker_resolve_rel_path(url);
|
|
160
|
+
if (rel == nil) return nil;
|
|
161
|
+
return [zapp_worker_asset_root() stringByAppendingPathComponent:rel];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static NSData* zapp_worker_read_embedded_asset(NSString* logicalPath) {
|
|
165
|
+
if (![logicalPath isKindOfClass:[NSString class]] || [logicalPath length] == 0) return nil;
|
|
166
|
+
if (zapp_build_use_embedded_assets() == 0) return nil;
|
|
167
|
+
if (zapp_embedded_assets_count <= 0) return nil;
|
|
168
|
+
|
|
169
|
+
for (int i = 0; i < zapp_embedded_assets_count; i++) {
|
|
170
|
+
NSString* assetPath = [NSString stringWithUTF8String:zapp_embedded_assets[i].path];
|
|
171
|
+
if (![assetPath isEqualToString:logicalPath]) continue;
|
|
172
|
+
|
|
173
|
+
if (zapp_embedded_assets[i].is_brotli) {
|
|
174
|
+
uint8_t* outBuf = malloc(zapp_embedded_assets[i].uncompressed_len);
|
|
175
|
+
size_t decodedSize = compression_decode_buffer(outBuf, zapp_embedded_assets[i].uncompressed_len,
|
|
176
|
+
zapp_embedded_assets[i].data, zapp_embedded_assets[i].len,
|
|
177
|
+
NULL, COMPRESSION_BROTLI);
|
|
178
|
+
if (decodedSize > 0) {
|
|
179
|
+
return [NSData dataWithBytesNoCopy:outBuf length:decodedSize freeWhenDone:YES];
|
|
180
|
+
}
|
|
181
|
+
free(outBuf);
|
|
182
|
+
return nil;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return [NSData dataWithBytesNoCopy:(void*)zapp_embedded_assets[i].data
|
|
186
|
+
length:zapp_embedded_assets[i].len
|
|
187
|
+
freeWhenDone:NO];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return nil;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
static NSString* zapp_worker_read_source(NSString* scriptUrl, NSError** outErr) {
|
|
194
|
+
if (![scriptUrl isKindOfClass:[NSString class]] || [scriptUrl length] == 0) return nil;
|
|
195
|
+
NSURL* url = [NSURL URLWithString:scriptUrl];
|
|
196
|
+
if (url == nil) return nil;
|
|
197
|
+
|
|
198
|
+
NSString* rel = zapp_worker_resolve_rel_path(url);
|
|
199
|
+
if (rel != nil) {
|
|
200
|
+
NSString* logicalPath = [@"/" stringByAppendingString:rel];
|
|
201
|
+
NSData* embeddedData = zapp_worker_read_embedded_asset(logicalPath);
|
|
202
|
+
if (embeddedData != nil) {
|
|
203
|
+
return [[NSString alloc] initWithData:embeddedData encoding:NSUTF8StringEncoding];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
NSString* localPath = zapp_worker_resolve_local_path(url);
|
|
208
|
+
if (localPath != nil) {
|
|
209
|
+
if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
|
|
210
|
+
if (outErr) {
|
|
211
|
+
*outErr = [NSError errorWithDomain:@"zapp.worker" code:404 userInfo:nil];
|
|
212
|
+
}
|
|
213
|
+
return nil;
|
|
214
|
+
}
|
|
215
|
+
return [NSString stringWithContentsOfFile:localPath encoding:NSUTF8StringEncoding error:outErr];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:outErr];
|
|
219
|
+
}
|
|
220
|
+
#endif
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
struct WorkerCommon {}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Engine-agnostic btoa/atob implementation using Foundation.
|
|
2
|
+
|
|
3
|
+
raw {
|
|
4
|
+
#ifdef __APPLE__
|
|
5
|
+
#include <Foundation/Foundation.h>
|
|
6
|
+
|
|
7
|
+
// btoa: encode Latin-1 string to base64. Caller must free() the result.
|
|
8
|
+
static char* zapp_core_btoa(const char* input) {
|
|
9
|
+
if (input == NULL || input[0] == '\0') return strdup("");
|
|
10
|
+
NSString* str = [NSString stringWithUTF8String:input];
|
|
11
|
+
if (str == nil) return strdup("");
|
|
12
|
+
NSData* data = [str dataUsingEncoding:NSISOLatin1StringEncoding];
|
|
13
|
+
if (data == nil) return strdup("");
|
|
14
|
+
NSString* b64 = [data base64EncodedStringWithOptions:0];
|
|
15
|
+
return b64 ? strdup([b64 UTF8String]) : strdup("");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// atob: decode base64 to Latin-1 string. Caller must free() the result.
|
|
19
|
+
static char* zapp_core_atob(const char* input) {
|
|
20
|
+
if (input == NULL || input[0] == '\0') return strdup("");
|
|
21
|
+
NSString* str = [NSString stringWithUTF8String:input];
|
|
22
|
+
if (str == nil) return strdup("");
|
|
23
|
+
NSData* data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
|
|
24
|
+
if (data == nil) return strdup("");
|
|
25
|
+
NSString* result = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
|
|
26
|
+
return result ? strdup([result UTF8String]) : strdup("");
|
|
27
|
+
}
|
|
28
|
+
#endif
|
|
29
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Engine-agnostic crypto: random bytes and UUID generation.
|
|
2
|
+
|
|
3
|
+
//> macos: framework: Security
|
|
4
|
+
|
|
5
|
+
raw {
|
|
6
|
+
#ifdef __APPLE__
|
|
7
|
+
#include <Foundation/Foundation.h>
|
|
8
|
+
#include <Security/Security.h>
|
|
9
|
+
|
|
10
|
+
static void zapp_core_crypto_random_bytes(uint8_t* buf, size_t len) {
|
|
11
|
+
if (buf && len > 0) SecRandomCopyBytes(kSecRandomDefault, len, buf);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Returns a new UUID string. Caller must free().
|
|
15
|
+
static char* zapp_core_crypto_random_uuid(void) {
|
|
16
|
+
return strdup([[[NSUUID UUID] UUIDString] UTF8String]);
|
|
17
|
+
}
|
|
18
|
+
#endif
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Engine-agnostic TextEncoder/TextDecoder implementation using Foundation.
|
|
2
|
+
|
|
3
|
+
include <string.h>
|
|
4
|
+
|
|
5
|
+
raw {
|
|
6
|
+
#ifdef __APPLE__
|
|
7
|
+
#include <Foundation/Foundation.h>
|
|
8
|
+
|
|
9
|
+
// Encode a UTF-8 C string into raw bytes. Caller must free() the result.
|
|
10
|
+
// Returns NULL on failure; *out_len is set to the byte count.
|
|
11
|
+
static uint8_t* zapp_core_text_encode(const char* input, size_t* out_len) {
|
|
12
|
+
if (out_len) *out_len = 0;
|
|
13
|
+
if (input == NULL) return NULL;
|
|
14
|
+
size_t len = strlen(input);
|
|
15
|
+
if (len == 0) return NULL;
|
|
16
|
+
uint8_t* copy = (uint8_t*)malloc(len);
|
|
17
|
+
if (!copy) return NULL;
|
|
18
|
+
memcpy(copy, input, len);
|
|
19
|
+
if (out_len) *out_len = len;
|
|
20
|
+
return copy;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Decode raw bytes into a UTF-8 C string. Caller must free() the result.
|
|
24
|
+
// Returns empty string (strdup("")) on failure, never NULL.
|
|
25
|
+
static char* zapp_core_text_decode(const uint8_t* bytes, size_t len) {
|
|
26
|
+
if (bytes == NULL || len == 0) return strdup("");
|
|
27
|
+
NSString* str = [[NSString alloc] initWithBytes:bytes length:len encoding:NSUTF8StringEncoding];
|
|
28
|
+
if (str == nil) return strdup("");
|
|
29
|
+
return strdup([str UTF8String]);
|
|
30
|
+
}
|
|
31
|
+
#endif
|
|
32
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Engine-agnostic HTTP fetch: request building, response handling, task tracking.
|
|
2
|
+
|
|
3
|
+
raw {
|
|
4
|
+
#ifdef __APPLE__
|
|
5
|
+
#include <Foundation/Foundation.h>
|
|
6
|
+
|
|
7
|
+
// zapp_fetch_response_t and zapp_fetch_completion_t are defined in common.zc
|
|
8
|
+
|
|
9
|
+
static void zapp_core_fetch_response_free(zapp_fetch_response_t* r) {
|
|
10
|
+
if (!r) return;
|
|
11
|
+
free(r->status_text);
|
|
12
|
+
for (int i = 0; i < r->header_count; i++) {
|
|
13
|
+
free(r->header_keys[i]);
|
|
14
|
+
free(r->header_values[i]);
|
|
15
|
+
}
|
|
16
|
+
free(r->header_keys);
|
|
17
|
+
free(r->header_values);
|
|
18
|
+
free(r->body);
|
|
19
|
+
free(r->body_base64);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static zapp_fetch_response_t zapp_core_fetch_build_response(NSHTTPURLResponse* httpResponse, NSData* data) {
|
|
23
|
+
zapp_fetch_response_t r;
|
|
24
|
+
memset(&r, 0, sizeof(r));
|
|
25
|
+
|
|
26
|
+
r.status = (int)[httpResponse statusCode];
|
|
27
|
+
NSString* statusText = [NSHTTPURLResponse localizedStringForStatusCode:[httpResponse statusCode]];
|
|
28
|
+
r.status_text = strdup([statusText UTF8String]);
|
|
29
|
+
|
|
30
|
+
NSDictionary* headers = [httpResponse allHeaderFields];
|
|
31
|
+
r.header_count = (int)[headers count];
|
|
32
|
+
if (r.header_count > 0) {
|
|
33
|
+
r.header_keys = (char**)calloc(r.header_count, sizeof(char*));
|
|
34
|
+
r.header_values = (char**)calloc(r.header_count, sizeof(char*));
|
|
35
|
+
int i = 0;
|
|
36
|
+
for (NSString* key in headers) {
|
|
37
|
+
r.header_keys[i] = strdup([key UTF8String]);
|
|
38
|
+
r.header_values[i] = strdup([[NSString stringWithFormat:@"%@", headers[key]] UTF8String]);
|
|
39
|
+
i++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (data != nil && [data length] > 0) {
|
|
44
|
+
NSString* dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
45
|
+
if (dataStr) {
|
|
46
|
+
r.body = strdup([dataStr UTF8String]);
|
|
47
|
+
} else {
|
|
48
|
+
r.body_base64 = strdup([[data base64EncodedStringWithOptions:0] UTF8String]);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
r.body = strdup("");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return r;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// --- Request builder ---
|
|
58
|
+
static NSMutableURLRequest* zapp_core_fetch_build_request(
|
|
59
|
+
const char* url_str,
|
|
60
|
+
const char* method,
|
|
61
|
+
const char** header_keys, const char** header_values, int header_count,
|
|
62
|
+
const char* body, size_t body_len
|
|
63
|
+
) {
|
|
64
|
+
if (!url_str) return nil;
|
|
65
|
+
NSURL* url = [NSURL URLWithString:[NSString stringWithUTF8String:url_str]];
|
|
66
|
+
if (!url) return nil;
|
|
67
|
+
|
|
68
|
+
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
|
|
69
|
+
if (method) [request setHTTPMethod:[NSString stringWithUTF8String:method]];
|
|
70
|
+
|
|
71
|
+
for (int i = 0; i < header_count; i++) {
|
|
72
|
+
if (header_keys[i] && header_values[i]) {
|
|
73
|
+
[request setValue:[NSString stringWithUTF8String:header_values[i]]
|
|
74
|
+
forHTTPHeaderField:[NSString stringWithUTF8String:header_keys[i]]];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (body && body_len > 0) {
|
|
79
|
+
[request setHTTPBody:[NSData dataWithBytes:body length:body_len]];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return request;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// --- Task tracking ---
|
|
86
|
+
static NSMutableDictionary<NSString*, NSMutableDictionary<NSNumber*, NSURLSessionDataTask*>*>* zapp_fetch_tasks = nil;
|
|
87
|
+
static NSInteger zapp_fetch_next_id = 1;
|
|
88
|
+
|
|
89
|
+
static void zapp_core_fetch_ensure_init(void) {
|
|
90
|
+
if (!zapp_fetch_tasks) zapp_fetch_tasks = [NSMutableDictionary dictionary];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Execute a fetch and track the task. Completion is called on the NSURLSession callback queue.
|
|
94
|
+
static void zapp_core_fetch_execute(
|
|
95
|
+
NSMutableURLRequest* request, NSString* worker_id,
|
|
96
|
+
zapp_fetch_completion_t completion
|
|
97
|
+
) {
|
|
98
|
+
zapp_core_fetch_ensure_init();
|
|
99
|
+
if (!request || !worker_id) return;
|
|
100
|
+
|
|
101
|
+
NSMutableDictionary<NSNumber*, NSURLSessionDataTask*>* tasks = zapp_fetch_tasks[worker_id];
|
|
102
|
+
if (!tasks) { tasks = [NSMutableDictionary dictionary]; zapp_fetch_tasks[worker_id] = tasks; }
|
|
103
|
+
|
|
104
|
+
NSInteger taskId = zapp_fetch_next_id++;
|
|
105
|
+
NSNumber* taskKey = @(taskId);
|
|
106
|
+
|
|
107
|
+
NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithRequest:request
|
|
108
|
+
completionHandler:^(NSData* data, NSURLResponse* response, NSError* error) {
|
|
109
|
+
NSMutableDictionary<NSNumber*, NSURLSessionDataTask*>* t = zapp_fetch_tasks[worker_id];
|
|
110
|
+
if (t) [t removeObjectForKey:taskKey];
|
|
111
|
+
|
|
112
|
+
if (error) {
|
|
113
|
+
if (completion) completion(NULL, [error localizedDescription]);
|
|
114
|
+
} else {
|
|
115
|
+
zapp_fetch_response_t r = zapp_core_fetch_build_response((NSHTTPURLResponse*)response, data);
|
|
116
|
+
if (completion) completion(&r, nil);
|
|
117
|
+
zapp_core_fetch_response_free(&r);
|
|
118
|
+
}
|
|
119
|
+
}];
|
|
120
|
+
|
|
121
|
+
tasks[taskKey] = task;
|
|
122
|
+
[task resume];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static void zapp_core_fetch_cancel(NSString* workerId) {
|
|
126
|
+
if (!workerId || !zapp_fetch_tasks) return;
|
|
127
|
+
NSMutableDictionary<NSNumber*, NSURLSessionDataTask*>* tasks = zapp_fetch_tasks[workerId];
|
|
128
|
+
if (!tasks) return;
|
|
129
|
+
for (NSNumber* key in [tasks allKeys]) {
|
|
130
|
+
NSURLSessionDataTask* task = tasks[key];
|
|
131
|
+
if (task) [task cancel];
|
|
132
|
+
}
|
|
133
|
+
[tasks removeAllObjects];
|
|
134
|
+
[zapp_fetch_tasks removeObjectForKey:workerId];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static void zapp_core_fetch_cancel_all(void) {
|
|
138
|
+
if (!zapp_fetch_tasks) return;
|
|
139
|
+
for (NSString* wId in [zapp_fetch_tasks allKeys]) {
|
|
140
|
+
zapp_core_fetch_cancel(wId);
|
|
141
|
+
}
|
|
142
|
+
[zapp_fetch_tasks removeAllObjects];
|
|
143
|
+
}
|
|
144
|
+
#endif
|
|
145
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Engine-agnostic URL parsing using NSURL.
|
|
2
|
+
|
|
3
|
+
raw {
|
|
4
|
+
#ifdef __APPLE__
|
|
5
|
+
#include <Foundation/Foundation.h>
|
|
6
|
+
|
|
7
|
+
static void zapp_core_url_free(zapp_url_parsed_t* c) {
|
|
8
|
+
if (!c) return;
|
|
9
|
+
free(c->href); free(c->protocol); free(c->host);
|
|
10
|
+
free(c->hostname); free(c->port); free(c->pathname);
|
|
11
|
+
free(c->search); free(c->hash); free(c->origin);
|
|
12
|
+
free(c->username); free(c->password);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static int zapp_core_url_parse(const char* url_str, const char* base_str, zapp_url_parsed_t* out) {
|
|
16
|
+
if (!url_str || !out) return -1;
|
|
17
|
+
memset(out, 0, sizeof(zapp_url_parsed_t));
|
|
18
|
+
|
|
19
|
+
NSString* urlNS = [NSString stringWithUTF8String:url_str];
|
|
20
|
+
NSURL* url = nil;
|
|
21
|
+
|
|
22
|
+
if (base_str && base_str[0] != '\0') {
|
|
23
|
+
NSURL* baseURL = [NSURL URLWithString:[NSString stringWithUTF8String:base_str]];
|
|
24
|
+
if (baseURL) url = [NSURL URLWithString:urlNS relativeToURL:baseURL];
|
|
25
|
+
}
|
|
26
|
+
if (url == nil) url = [NSURL URLWithString:urlNS];
|
|
27
|
+
if (url == nil) return -1;
|
|
28
|
+
|
|
29
|
+
NSString* scheme = [url scheme] ?: @"";
|
|
30
|
+
NSString* host = [url host] ?: @"";
|
|
31
|
+
NSNumber* portNum = [url port];
|
|
32
|
+
NSString* portStr = portNum ? [portNum stringValue] : @"";
|
|
33
|
+
NSString* path = [url path] ?: @"";
|
|
34
|
+
NSString* query = [url query];
|
|
35
|
+
NSString* fragment = [url fragment];
|
|
36
|
+
NSString* user = [url user] ?: @"";
|
|
37
|
+
NSString* pass = [url password] ?: @"";
|
|
38
|
+
|
|
39
|
+
NSString* protocol = [scheme length] > 0 ? [NSString stringWithFormat:@"%@:", scheme] : @"";
|
|
40
|
+
NSString* search = query ? [NSString stringWithFormat:@"?%@", query] : @"";
|
|
41
|
+
NSString* hash = fragment ? [NSString stringWithFormat:@"#%@", fragment] : @"";
|
|
42
|
+
NSString* hostPort = [portStr length] > 0 ? [NSString stringWithFormat:@"%@:%@", host, portStr] : host;
|
|
43
|
+
|
|
44
|
+
NSString* origin = @"null";
|
|
45
|
+
if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"] ||
|
|
46
|
+
[scheme isEqualToString:@"ws"] || [scheme isEqualToString:@"wss"] ||
|
|
47
|
+
[scheme isEqualToString:@"ftp"]) {
|
|
48
|
+
origin = [portStr length] > 0
|
|
49
|
+
? [NSString stringWithFormat:@"%@://%@:%@", scheme, host, portStr]
|
|
50
|
+
: [NSString stringWithFormat:@"%@://%@", scheme, host];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
NSString* href = [url absoluteString] ?: @"";
|
|
54
|
+
|
|
55
|
+
out->href = strdup([href UTF8String]);
|
|
56
|
+
out->protocol = strdup([protocol UTF8String]);
|
|
57
|
+
out->host = strdup([hostPort UTF8String]);
|
|
58
|
+
out->hostname = strdup([host UTF8String]);
|
|
59
|
+
out->port = strdup([portStr UTF8String]);
|
|
60
|
+
out->pathname = strdup([path UTF8String]);
|
|
61
|
+
out->search = strdup([search UTF8String]);
|
|
62
|
+
out->hash = strdup([hash UTF8String]);
|
|
63
|
+
out->origin = strdup([origin UTF8String]);
|
|
64
|
+
out->username = strdup([user UTF8String]);
|
|
65
|
+
out->password = strdup([pass UTF8String]);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
#endif
|
|
69
|
+
}
|