@geastack/apple 0.2.8

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 (113) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +54 -0
  3. package/dist/index.d.ts +127 -0
  4. package/dist/index.js +3076 -0
  5. package/generated/AVFoundation.d.ts +112 -0
  6. package/generated/ActivityKit.d.ts +7 -0
  7. package/generated/AppKit.d.ts +268 -0
  8. package/generated/CoreGraphics.d.ts +18 -0
  9. package/generated/CoreLocation.d.ts +28 -0
  10. package/generated/CoreMedia.d.ts +8 -0
  11. package/generated/Dispatch.d.ts +2 -0
  12. package/generated/Foundation.d.ts +13 -0
  13. package/generated/MapKit.d.ts +28 -0
  14. package/generated/Metal.d.ts +91 -0
  15. package/generated/MetalKit.d.ts +22 -0
  16. package/generated/Photos.d.ts +5 -0
  17. package/generated/QuartzCore.d.ts +12 -0
  18. package/generated/SwiftData.d.ts +11 -0
  19. package/generated/UIKit.d.ts +187 -0
  20. package/package.json +123 -0
  21. package/runtime/AVFoundation.js +136 -0
  22. package/runtime/ActivityKit.js +18 -0
  23. package/runtime/AppKit.js +313 -0
  24. package/runtime/CoreGraphics.js +15 -0
  25. package/runtime/CoreLocation.js +30 -0
  26. package/runtime/CoreMedia.js +7 -0
  27. package/runtime/Dispatch.js +11 -0
  28. package/runtime/Foundation.js +21 -0
  29. package/runtime/MapKit.js +22 -0
  30. package/runtime/Metal.js +126 -0
  31. package/runtime/MetalKit.js +15 -0
  32. package/runtime/Photos.js +9 -0
  33. package/runtime/QuartzCore.js +9 -0
  34. package/runtime/SwiftData.js +29 -0
  35. package/runtime/UIKit.js +242 -0
  36. package/runtime/empty.js +1 -0
  37. package/targets/ios/Info.plist.in +25 -0
  38. package/targets/ios/README.md +46 -0
  39. package/targets/ios/build-ios.sh +395 -0
  40. package/targets/ios/detect-development-team.mjs +109 -0
  41. package/targets/ios/generate-resident-entry.mjs +67 -0
  42. package/targets/ios/generate-resident-registry.mjs +162 -0
  43. package/targets/ios/generate-xcode-project.mjs +520 -0
  44. package/targets/ios/main/canvas_view.h +7 -0
  45. package/targets/ios/main/canvas_view.mm +94 -0
  46. package/targets/ios/main/font_registry.h +17 -0
  47. package/targets/ios/main/font_registry.mm +129 -0
  48. package/targets/ios/main/image_bridge.h +13 -0
  49. package/targets/ios/main/image_bridge.mm +53 -0
  50. package/targets/ios/main/ios_apps.c +28 -0
  51. package/targets/ios/main/ios_camera.mm +446 -0
  52. package/targets/ios/main/ios_display.mm +344 -0
  53. package/targets/ios/main/ios_main.mm +811 -0
  54. package/targets/ios/main/ios_memory.cpp +55 -0
  55. package/targets/ios/main/ios_renderer.h +20 -0
  56. package/targets/ios/main/ios_renderer.mm +27 -0
  57. package/targets/ios/main/ios_root_background.cpp +20 -0
  58. package/targets/ios/main/ios_root_background.h +11 -0
  59. package/targets/ios/main/ios_sensors.mm +244 -0
  60. package/targets/ios/main/ios_timers.mm +53 -0
  61. package/targets/ios/main/renderer/ios_renderer_internal.h +65 -0
  62. package/targets/ios/main/renderer/ios_renderer_support.mm +111 -0
  63. package/targets/ios/main/renderer/native_button.mm +179 -0
  64. package/targets/ios/main/renderer/native_label.mm +161 -0
  65. package/targets/ios/main/renderer/native_scroll_container.mm +279 -0
  66. package/targets/ios/main/renderer/view_reconciler.mm +274 -0
  67. package/targets/macos/Info.plist.in +26 -0
  68. package/targets/macos/README.md +131 -0
  69. package/targets/macos/build-child-lifecycle.sh +119 -0
  70. package/targets/macos/build-macos.sh +2156 -0
  71. package/targets/macos/check-module-graph-freshness.mjs +82 -0
  72. package/targets/macos/compiler-input-fingerprint.mjs +32 -0
  73. package/targets/macos/finalize-apple-native-output.mjs +77 -0
  74. package/targets/macos/generate-resident-entry.mjs +80 -0
  75. package/targets/macos/generate-resident-registry.mjs +141 -0
  76. package/targets/macos/heavy-build-lock.sh +176 -0
  77. package/targets/macos/main/canvas_view.h +9 -0
  78. package/targets/macos/main/canvas_view.mm +176 -0
  79. package/targets/macos/main/color_convert.h +18 -0
  80. package/targets/macos/main/color_convert.mm +39 -0
  81. package/targets/macos/main/font_registry.h +35 -0
  82. package/targets/macos/main/font_registry.mm +350 -0
  83. package/targets/macos/main/image_bridge.h +16 -0
  84. package/targets/macos/main/image_bridge.mm +52 -0
  85. package/targets/macos/main/macos_app_platform.mm +95 -0
  86. package/targets/macos/main/macos_apps.c +31 -0
  87. package/targets/macos/main/macos_device_control.mm +56 -0
  88. package/targets/macos/main/macos_display.mm +484 -0
  89. package/targets/macos/main/macos_host_device_control.mm +95 -0
  90. package/targets/macos/main/macos_main.mm +839 -0
  91. package/targets/macos/main/macos_memory.cpp +31 -0
  92. package/targets/macos/main/macos_native_shell.h +31 -0
  93. package/targets/macos/main/macos_native_shell.mm +396 -0
  94. package/targets/macos/main/macos_network.mm +253 -0
  95. package/targets/macos/main/macos_renderer.h +39 -0
  96. package/targets/macos/main/macos_renderer.mm +1969 -0
  97. package/targets/macos/main/macos_sensors.cpp +148 -0
  98. package/targets/macos/main/macos_smoke_app.cpp +65 -0
  99. package/targets/macos/main/macos_timers.mm +52 -0
  100. package/targets/macos/main/press_bridge.h +21 -0
  101. package/targets/macos/main/press_bridge.mm +72 -0
  102. package/targets/macos/main/thermalright_hid_display.h +14 -0
  103. package/targets/macos/main/thermalright_hid_display.mm +995 -0
  104. package/targets/macos/native-artifact-provenance.mjs +421 -0
  105. package/targets/macos/order-compile-edges.mjs +64 -0
  106. package/targets/macos/preflight-hard-muted-artifact.mjs +93 -0
  107. package/targets/macos/prune-generated-modules.mjs +147 -0
  108. package/targets/macos/sync-resources.mjs +153 -0
  109. package/targets/shared/analyze-audio-capture.mjs +131 -0
  110. package/targets/shared/apple_audio.mm +1194 -0
  111. package/targets/shared/apple_audio_selftest.mm +602 -0
  112. package/targets/shared/apple_audio_testing.h +34 -0
  113. package/targets/shared/build-audio-selftest.sh +50 -0
@@ -0,0 +1,253 @@
1
+ /* targets/macos/main/macos_network.mm
2
+ * Real HTTP(S) for the framework's fetch facade, via NSURLSession.
3
+ *
4
+ * core's host/host/fetch.cpp has three arms: browser (emscripten), ESP-IDF,
5
+ * and a desktop fallback that calls two WEAK hooks —
6
+ * test_record_request(url, init) then test_canned_response(url)
7
+ * — and returns whatever the latter produces (empty by default). The Android
8
+ * and Raspberry Pi OS targets strong-override that seam to inject real
9
+ * responses; this file does the same with NSURLSession, the canonical macOS
10
+ * networking stack (system proxy/PAC settings, HTTP/2, TLS session reuse,
11
+ * and connection keep-alive all come from the shared session's pool).
12
+ *
13
+ * The fetch seam is synchronous, so each request parks its calling thread on
14
+ * a semaphore until the session's completion handler fires — the callers are
15
+ * tile-loader workers, detached fetchAsync threads, or the frame thread for
16
+ * a synchronous app fetch, and the session's delegate queue is its own, so
17
+ * the wait cannot deadlock. test_canned_response only receives the URL, so
18
+ * test_record_request stashes the request init in a thread_local for it to
19
+ * pick up (both hooks run back-to-back on the same thread).
20
+ */
21
+
22
+ #import <Foundation/Foundation.h>
23
+
24
+ #include "host/fetch.h"
25
+ #include "wifi.h"
26
+
27
+ #include <cstdio>
28
+ #include <mutex>
29
+ #include <string>
30
+ #include <vector>
31
+
32
+ #include <CoreFoundation/CoreFoundation.h>
33
+ #include <SystemConfiguration/SystemConfiguration.h>
34
+
35
+ #include <arpa/inet.h>
36
+ #include <ifaddrs.h>
37
+ #include <net/if_dl.h>
38
+ #include <netinet/in.h>
39
+
40
+ namespace {
41
+
42
+ thread_local gea::host::FetchRequestInit t_pending_init;
43
+ thread_local bool t_has_pending_init = false;
44
+
45
+ // One shared session for every caller: NSURLSession is thread-safe and pools
46
+ // keep-alive connections per host across threads, so sequential tile fetches
47
+ // pay the TCP + TLS handshake once (same effect the ESP backend gets from its
48
+ // per-task esp_http_client) while worker threads still fetch in parallel.
49
+ NSURLSession *sharedSession()
50
+ {
51
+ static NSURLSession *session;
52
+ static dispatch_once_t once;
53
+ dispatch_once(&once, ^{
54
+ NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
55
+ config.HTTPAdditionalHeaders = @{ @"User-Agent": @"gea-macos/1.0" };
56
+ config.timeoutIntervalForRequest = 30.0;
57
+ session = [NSURLSession sessionWithConfiguration:config];
58
+ });
59
+ return session;
60
+ }
61
+
62
+ gea::host::FetchResponse sessionFetch(const std::string &url, const gea::host::FetchRequestInit &init)
63
+ {
64
+ gea::host::FetchResponse response;
65
+ NSURL *requestUrl = [NSURL URLWithString:[NSString stringWithUTF8String:url.c_str()] ?: @""];
66
+ if (!requestUrl) {
67
+ std::fprintf(stderr, "[macos net] fetch rejected malformed url %s\n", url.c_str());
68
+ return response;
69
+ }
70
+
71
+ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestUrl];
72
+ const std::string method = init.method.empty() ? "GET" : init.method;
73
+ request.HTTPMethod = [NSString stringWithUTF8String:method.c_str()] ?: @"GET";
74
+ if (init.timeout_ms > 0) request.timeoutInterval = init.timeout_ms / 1000.0;
75
+ for (const auto &kv : init.headers) {
76
+ NSString *name = [NSString stringWithUTF8String:kv.first.c_str()];
77
+ NSString *value = [NSString stringWithUTF8String:kv.second.c_str()];
78
+ if (name && value) [request setValue:value forHTTPHeaderField:name];
79
+ }
80
+ if (!init.body.empty() && method != "GET" && method != "HEAD") {
81
+ request.HTTPBody = [NSData dataWithBytes:init.body.data() length:init.body.size()];
82
+ }
83
+
84
+ // Park this thread until the completion handler fires on the session's own
85
+ // delegate queue. Redirects are followed and gzip/deflate bodies decoded by
86
+ // the session before the handler runs.
87
+ dispatch_semaphore_t done = dispatch_semaphore_create(0);
88
+ __block NSData *body = nil;
89
+ __block NSHTTPURLResponse *httpResponse = nil;
90
+ __block NSError *error = nil;
91
+ NSURLSessionDataTask *task = [sharedSession()
92
+ dataTaskWithRequest:request
93
+ completionHandler:^(NSData *taskData, NSURLResponse *taskResponse, NSError *taskError) {
94
+ body = taskData;
95
+ if ([taskResponse isKindOfClass:[NSHTTPURLResponse class]]) {
96
+ httpResponse = (NSHTTPURLResponse *)taskResponse;
97
+ }
98
+ error = taskError;
99
+ dispatch_semaphore_signal(done);
100
+ }];
101
+ [task resume];
102
+ dispatch_semaphore_wait(done, DISPATCH_TIME_FOREVER);
103
+
104
+ if (error) {
105
+ std::fprintf(stderr, "[macos net] fetch %s failed: %s\n", url.c_str(),
106
+ error.localizedDescription.UTF8String ?: "unknown error");
107
+ return response;
108
+ }
109
+ if (httpResponse) {
110
+ const NSInteger code = httpResponse.statusCode;
111
+ response.status = static_cast<double>(code);
112
+ response.ok = code >= 200 && code < 300;
113
+ response.status_text = std::string([NSHTTPURLResponse localizedStringForStatusCode:code].UTF8String ?: "");
114
+ NSDictionary *headerFields = httpResponse.allHeaderFields;
115
+ for (id name in headerFields) {
116
+ id value = headerFields[name];
117
+ if ([name isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) {
118
+ response.headers[std::string([(NSString *)name UTF8String] ?: "")] =
119
+ std::string([(NSString *)value UTF8String] ?: "");
120
+ }
121
+ }
122
+ }
123
+ if (body.length > 0) {
124
+ const auto *bytes = static_cast<const std::uint8_t *>(body.bytes);
125
+ response.body.assign(bytes, bytes + body.length);
126
+ }
127
+ return response;
128
+ }
129
+
130
+ } // namespace
131
+
132
+ namespace gea::framework::host {
133
+
134
+ // Strong overrides of the weak desktop-fallback hooks in host/host/fetch.cpp.
135
+ void test_record_request(const std::string &, const gea::host::FetchRequestInit &init)
136
+ {
137
+ t_pending_init = init;
138
+ t_has_pending_init = true;
139
+ }
140
+
141
+ gea::host::FetchResponse test_canned_response(const std::string &url)
142
+ {
143
+ gea::host::FetchRequestInit init;
144
+ if (t_has_pending_init) {
145
+ init = std::move(t_pending_init);
146
+ t_pending_init = {};
147
+ t_has_pending_init = false;
148
+ }
149
+ return sessionFetch(url, init);
150
+ }
151
+
152
+ } // namespace gea::framework::host
153
+
154
+ namespace {
155
+
156
+ // WiFi *status* driver. Several apps gate remote fetches on
157
+ // `wifi().connected()` (e.g. maps skips tile downloads without it), so the
158
+ // desktop must report its real link state even though fetch itself just uses
159
+ // the host TCP stack. "Connected" = configd has a primary (default-route)
160
+ // IPv4 interface — true for wired Ethernet too, which is the honest answer
161
+ // to "can I reach the network". Scanning/configuration are desktop no-ops
162
+ // (the system owns the link).
163
+ class MacWifiDriver final : public gea::framework::network::WifiDriver {
164
+ public:
165
+ bool init() override { return true; }
166
+ bool enabled() const override { return true; }
167
+ void setEnabled(bool) override {}
168
+ bool connected() const override { return !primaryInterface().empty(); }
169
+ int rssi() override { return connected() ? -50 : 0; }
170
+ std::string ssid() override { return primaryInterface(); }
171
+ std::string ip() const override
172
+ {
173
+ const std::string iface = primaryInterface();
174
+ if (iface.empty()) return "";
175
+ std::string result;
176
+ struct ifaddrs *addrs = nullptr;
177
+ if (getifaddrs(&addrs) != 0) return "";
178
+ for (struct ifaddrs *a = addrs; a; a = a->ifa_next) {
179
+ if (!a->ifa_addr || a->ifa_addr->sa_family != AF_INET) continue;
180
+ if (iface != a->ifa_name) continue;
181
+ char buf[INET_ADDRSTRLEN] = {0};
182
+ const auto *sin = reinterpret_cast<const struct sockaddr_in *>(a->ifa_addr);
183
+ if (inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf))) result = buf;
184
+ break;
185
+ }
186
+ freeifaddrs(addrs);
187
+ return result;
188
+ }
189
+ std::string mac() override
190
+ {
191
+ const std::string iface = primaryInterface();
192
+ if (iface.empty()) return "";
193
+ std::string result;
194
+ struct ifaddrs *addrs = nullptr;
195
+ if (getifaddrs(&addrs) != 0) return "";
196
+ for (struct ifaddrs *a = addrs; a; a = a->ifa_next) {
197
+ if (!a->ifa_addr || a->ifa_addr->sa_family != AF_LINK) continue;
198
+ if (iface != a->ifa_name) continue;
199
+ const auto *sdl = reinterpret_cast<const struct sockaddr_dl *>(a->ifa_addr);
200
+ if (sdl->sdl_alen == 6) {
201
+ const auto *ll = reinterpret_cast<const unsigned char *>(LLADDR(sdl));
202
+ char buf[18];
203
+ std::snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
204
+ ll[0], ll[1], ll[2], ll[3], ll[4], ll[5]);
205
+ result = buf;
206
+ }
207
+ break;
208
+ }
209
+ freeifaddrs(addrs);
210
+ return result;
211
+ }
212
+ void configure(const std::string &, const std::string &) override {}
213
+ void scan() override {}
214
+ bool scanning() const override { return false; }
215
+ int scanCount() const override { return 0; }
216
+ gea::framework::network::WifiNetwork networkAt(int) const override { return {}; }
217
+ std::vector<gea::framework::network::WifiNetwork> scanResults() const override { return {}; }
218
+
219
+ private:
220
+ // Interface of the system default route: configd publishes it as
221
+ // State:/Network/Global/IPv4 → PrimaryInterface (absent while offline).
222
+ static std::string primaryInterface()
223
+ {
224
+ SCDynamicStoreRef store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("gea-macos-network"), nullptr, nullptr);
225
+ if (!store) return "";
226
+ std::string result;
227
+ CFPropertyListRef value = SCDynamicStoreCopyValue(store, CFSTR("State:/Network/Global/IPv4"));
228
+ if (value) {
229
+ if (CFGetTypeID(value) == CFDictionaryGetTypeID()) {
230
+ const void *iface = CFDictionaryGetValue((CFDictionaryRef)value, CFSTR("PrimaryInterface"));
231
+ if (iface && CFGetTypeID((CFTypeRef)iface) == CFStringGetTypeID()) {
232
+ char buf[64] = {0};
233
+ if (CFStringGetCString((CFStringRef)iface, buf, sizeof(buf), kCFStringEncodingUTF8)) result = buf;
234
+ }
235
+ }
236
+ CFRelease(value);
237
+ }
238
+ CFRelease(store);
239
+ return result;
240
+ }
241
+ };
242
+
243
+ } // namespace
244
+
245
+ namespace gea::macos {
246
+
247
+ void installWifiDriver()
248
+ {
249
+ static MacWifiDriver driver;
250
+ gea::framework::network::WifiAdapter::setDriver(&driver);
251
+ }
252
+
253
+ } // namespace gea::macos
@@ -0,0 +1,39 @@
1
+ #pragma once
2
+
3
+ #ifdef __OBJC__
4
+ @class NSView;
5
+ @class NSArray;
6
+ #else
7
+ struct NSView;
8
+ struct NSArray;
9
+ #endif
10
+
11
+ namespace gea::macos {
12
+
13
+ class MacosRenderer {
14
+ public:
15
+ static MacosRenderer &instance();
16
+
17
+ // Walks the laid-out node tree rooted at rootNodeId and updates a
18
+ // parallel NSView tree under parentForRoot: creating views for new
19
+ // nodes, removing views for nodes that disappeared, reparenting where
20
+ // the tree shape changed, and applying frame/style.
21
+ void sync(NSView *parentForRoot, int rootNodeId);
22
+
23
+ // Multi-root variant for the native split shell: each pane is its own
24
+ // layout root rendered into its own container view. paneViews[i] hosts
25
+ // the subtree rooted at rootNodeIds[i]. A single combined unseen-sweep
26
+ // runs across ALL panes so per-pane syncing never evicts another pane's
27
+ // views (which a naive loop of sync() calls would, since each sync()
28
+ // sweeps every map entry it didn't touch).
29
+ void syncPanes(NSArray *paneViews, const int *rootNodeIds);
30
+
31
+ // Drop all NSView associations and detach them from their parents.
32
+ // Called on app teardown / tree clear.
33
+ void teardown();
34
+
35
+ private:
36
+ MacosRenderer() = default;
37
+ };
38
+
39
+ } // namespace gea::macos