xbintsc 0.3.25 → 0.3.35

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 (154) hide show
  1. package/README.md +33 -0
  2. package/dist/src/cli/main.js +124 -30
  3. package/dist/src/cli/main.js.map +1 -1
  4. package/dist/src/codegen/generator/calls/access.js +8 -1
  5. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  6. package/dist/src/codegen/generator/state.js +20 -0
  7. package/dist/src/codegen/generator/state.js.map +1 -1
  8. package/dist/src/codegen/generator/tables.d.ts +6 -0
  9. package/dist/src/codegen/generator/tables.js +38 -0
  10. package/dist/src/codegen/generator/tables.js.map +1 -1
  11. package/dist/src/driver/bundler/commonjs.d.ts +52 -0
  12. package/dist/src/driver/bundler/commonjs.js +493 -0
  13. package/dist/src/driver/bundler/commonjs.js.map +1 -0
  14. package/dist/src/driver/bundler/graph.js +14 -0
  15. package/dist/src/driver/bundler/graph.js.map +1 -1
  16. package/dist/src/driver/bundler/merge.js +14 -0
  17. package/dist/src/driver/bundler/merge.js.map +1 -1
  18. package/dist/src/driver/bundler/types.d.ts +8 -0
  19. package/dist/src/driver/compiler.d.ts +8 -1
  20. package/dist/src/driver/compiler.js +73 -5
  21. package/dist/src/driver/compiler.js.map +1 -1
  22. package/dist/src/driver/config.d.ts +53 -0
  23. package/dist/src/driver/config.js +141 -0
  24. package/dist/src/driver/config.js.map +1 -0
  25. package/dist/src/driver/icon.d.ts +62 -0
  26. package/dist/src/driver/icon.js +151 -0
  27. package/dist/src/driver/icon.js.map +1 -0
  28. package/dist/src/driver/index.d.ts +4 -0
  29. package/dist/src/driver/index.js +4 -0
  30. package/dist/src/driver/index.js.map +1 -1
  31. package/dist/src/driver/mac-bundle.d.ts +41 -0
  32. package/dist/src/driver/mac-bundle.js +123 -0
  33. package/dist/src/driver/mac-bundle.js.map +1 -0
  34. package/dist/src/driver/win-icon.d.ts +27 -0
  35. package/dist/src/driver/win-icon.js +80 -0
  36. package/dist/src/driver/win-icon.js.map +1 -0
  37. package/dist/src/parser/statements.js +17 -4
  38. package/dist/src/parser/statements.js.map +1 -1
  39. package/dist/tests/cli/main.test.js +46 -1
  40. package/dist/tests/cli/main.test.js.map +1 -1
  41. package/dist/tests/driver/config.test.d.ts +1 -0
  42. package/dist/tests/driver/config.test.js +124 -0
  43. package/dist/tests/driver/config.test.js.map +1 -0
  44. package/dist/tests/driver/icon.test.d.ts +1 -0
  45. package/dist/tests/driver/icon.test.js +421 -0
  46. package/dist/tests/driver/icon.test.js.map +1 -0
  47. package/dist/tests/driver/modules.test.js +109 -0
  48. package/dist/tests/driver/modules.test.js.map +1 -1
  49. package/dist/tests/e2e/fetch.test.d.ts +12 -0
  50. package/dist/tests/e2e/fetch.test.js +272 -0
  51. package/dist/tests/e2e/fetch.test.js.map +1 -0
  52. package/dist/tests/e2e/gui-dom.test.d.ts +5 -0
  53. package/dist/tests/e2e/gui-dom.test.js +102 -0
  54. package/dist/tests/e2e/gui-dom.test.js.map +1 -0
  55. package/dist/tests/e2e/gui-events.test.d.ts +5 -0
  56. package/dist/tests/e2e/gui-events.test.js +60 -0
  57. package/dist/tests/e2e/gui-events.test.js.map +1 -0
  58. package/dist/tests/e2e/gui-helpers.d.ts +31 -0
  59. package/dist/tests/e2e/gui-helpers.js +74 -0
  60. package/dist/tests/e2e/gui-helpers.js.map +1 -0
  61. package/dist/tests/e2e/gui-layout.test.d.ts +4 -0
  62. package/dist/tests/e2e/gui-layout.test.js +88 -0
  63. package/dist/tests/e2e/gui-layout.test.js.map +1 -0
  64. package/dist/tests/e2e/gui-lifecycle.test.d.ts +5 -0
  65. package/dist/tests/e2e/gui-lifecycle.test.js +58 -0
  66. package/dist/tests/e2e/gui-lifecycle.test.js.map +1 -0
  67. package/dist/tests/e2e/gui-paint.test.d.ts +5 -0
  68. package/dist/tests/e2e/gui-paint.test.js +111 -0
  69. package/dist/tests/e2e/gui-paint.test.js.map +1 -0
  70. package/dist/tests/e2e/gui-script.test.d.ts +5 -0
  71. package/dist/tests/e2e/gui-script.test.js +78 -0
  72. package/dist/tests/e2e/gui-script.test.js.map +1 -0
  73. package/dist/tests/e2e/gui-style.test.d.ts +5 -0
  74. package/dist/tests/e2e/gui-style.test.js +175 -0
  75. package/dist/tests/e2e/gui-style.test.js.map +1 -0
  76. package/dist/tests/e2e/icon.test.d.ts +7 -0
  77. package/dist/tests/e2e/icon.test.js +80 -0
  78. package/dist/tests/e2e/icon.test.js.map +1 -0
  79. package/dist/tests/e2e/npm-modules.test.d.ts +4 -1
  80. package/dist/tests/e2e/npm-modules.test.js +47 -1
  81. package/dist/tests/e2e/npm-modules.test.js.map +1 -1
  82. package/dist/tests/e2e/runtime-coverage-typed-array.test.d.ts +9 -0
  83. package/dist/tests/e2e/runtime-coverage-typed-array.test.js +140 -0
  84. package/dist/tests/e2e/runtime-coverage-typed-array.test.js.map +1 -0
  85. package/dist/tests/parser/statements.test.js +11 -0
  86. package/dist/tests/parser/statements.test.js.map +1 -1
  87. package/package.json +1 -1
  88. package/runtime/ext_gui/css.cpp +4 -517
  89. package/runtime/ext_gui/css_internal.h +27 -0
  90. package/runtime/ext_gui/css_match.cpp +195 -0
  91. package/runtime/ext_gui/css_selector.cpp +207 -0
  92. package/runtime/ext_gui/css_sheet.cpp +129 -0
  93. package/runtime/ext_gui/dom.cpp +7 -403
  94. package/runtime/ext_gui/dom_api.cpp +63 -1146
  95. package/runtime/ext_gui/dom_api_document.cpp +96 -0
  96. package/runtime/ext_gui/dom_api_events.cpp +123 -0
  97. package/runtime/ext_gui/dom_api_internal.h +135 -0
  98. package/runtime/ext_gui/dom_api_node.cpp +329 -0
  99. package/runtime/ext_gui/dom_api_node_read.cpp +294 -0
  100. package/runtime/ext_gui/dom_api_proto.cpp +130 -0
  101. package/runtime/ext_gui/dom_api_style.cpp +192 -0
  102. package/runtime/ext_gui/dom_internal.h +39 -0
  103. package/runtime/ext_gui/dom_parse.cpp +348 -0
  104. package/runtime/ext_gui/dom_serialize.cpp +54 -0
  105. package/runtime/ext_gui/gui.cpp +56 -286
  106. package/runtime/ext_gui/gui_events.cpp +294 -0
  107. package/runtime/ext_gui/gui_internal.h +29 -0
  108. package/runtime/ext_gui/layout.cpp +6 -597
  109. package/runtime/ext_gui/layout_flex.cpp +200 -0
  110. package/runtime/ext_gui/layout_flow.cpp +191 -0
  111. package/runtime/ext_gui/layout_flow_internal.h +149 -0
  112. package/runtime/ext_gui/layout_inline.cpp +181 -0
  113. package/runtime/ext_gui/layout_internal.h +20 -0
  114. package/runtime/ext_gui/renderer.cpp +15 -679
  115. package/runtime/ext_gui/renderer_image.cpp +233 -0
  116. package/runtime/ext_gui/renderer_internal.h +112 -0
  117. package/runtime/ext_gui/renderer_shaders.h +108 -0
  118. package/runtime/ext_gui/renderer_text.cpp +342 -0
  119. package/runtime/ext_gui/style.cpp +12 -660
  120. package/runtime/ext_gui/style_internal.h +33 -0
  121. package/runtime/ext_gui/style_print.cpp +113 -0
  122. package/runtime/ext_gui/style_ua.cpp +98 -0
  123. package/runtime/ext_gui/style_values.cpp +468 -0
  124. package/runtime/rt.h +6 -0
  125. package/runtime/rt_internal.h +4 -0
  126. package/runtime/xt_builtins.c +1 -0
  127. package/runtime/xt_containers/access.inc +32 -1
  128. package/runtime/xt_fetch/buffer.inc +64 -0
  129. package/runtime/xt_fetch/headers.inc +312 -0
  130. package/runtime/xt_fetch/request.inc +386 -0
  131. package/runtime/xt_fetch/response.inc +107 -0
  132. package/runtime/xt_fetch/socket.inc +72 -0
  133. package/runtime/xt_fetch/url.inc +108 -0
  134. package/runtime/xt_fetch.c +39 -0
  135. package/runtime/xt_stdlib2/set.inc +1 -1
  136. package/runtime/xt_typed_array.c +614 -0
  137. package/src/cli/main.ts +137 -29
  138. package/src/codegen/generator/calls/access.ts +9 -1
  139. package/src/codegen/generator/state.ts +20 -0
  140. package/src/codegen/generator/tables.ts +40 -0
  141. package/src/driver/bundler/commonjs.ts +553 -0
  142. package/src/driver/bundler/graph.ts +14 -0
  143. package/src/driver/bundler/merge.ts +15 -0
  144. package/src/driver/bundler/types.ts +8 -0
  145. package/src/driver/compiler.ts +83 -5
  146. package/src/driver/config.ts +173 -0
  147. package/src/driver/icon.ts +184 -0
  148. package/src/driver/index.ts +30 -0
  149. package/src/driver/mac-bundle.ts +156 -0
  150. package/src/driver/win-icon.ts +96 -0
  151. package/src/parser/statements.ts +17 -4
  152. package/dist/tests/e2e/gui.test.d.ts +0 -12
  153. package/dist/tests/e2e/gui.test.js +0 -702
  154. package/dist/tests/e2e/gui.test.js.map +0 -1
@@ -0,0 +1,107 @@
1
+ /* -- Response ------------------------------------------------------------- */
2
+
3
+ /*
4
+ * `fetch` resolves with a plain object shaped like a `Response`: the status
5
+ * fields are own properties, `headers` is a Headers object, and the body is
6
+ * kept verbatim under `__body`. The body consumers (`text` / `json` /
7
+ * `arrayBuffer` / `bytes`) return promises, matching the platform API even
8
+ * though the value is already available.
9
+ */
10
+
11
+ static void *xt_response_method_impl(xt_value name);
12
+ static xt_value xt_method_value_for_response(xt_value name);
13
+
14
+ static xt_value xt_response_body(xt_value response) {
15
+ xt_value body = xt_object_get_cstr(response, "__body");
16
+ return XT_IS_STRING(body) ? body : xt_string_from_cstr("");
17
+ }
18
+
19
+ static xt_value xt_response_method_text(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
20
+ (void)env;
21
+ (void)argc;
22
+ (void)argv;
23
+ return xt_promise_resolve(xt_response_body(thisValue));
24
+ }
25
+
26
+ static xt_value xt_response_method_json(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
27
+ (void)env;
28
+ (void)argc;
29
+ (void)argv;
30
+ xt_value body = xt_response_body(thisValue);
31
+ return xt_promise_resolve(xt_json_parse(1, &body));
32
+ }
33
+
34
+ static xt_value xt_response_method_array_buffer(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
35
+ (void)env;
36
+ (void)argc;
37
+ (void)argv;
38
+ xt_value body = xt_response_body(thisValue);
39
+ const char *data = xt_string_data(body);
40
+ int32_t length = xt_string_length_value(body);
41
+ if (!data || length < 0) length = 0;
42
+ xt_value bytes = xt_array_new(0, NULL);
43
+ for (int32_t i = 0; i < length; i++) {
44
+ xt_array_push(bytes, xt_number((double)(unsigned char)data[i]));
45
+ }
46
+ return xt_promise_resolve(bytes);
47
+ }
48
+
49
+ static xt_value xt_response_method_clone(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
50
+ (void)env;
51
+ (void)argc;
52
+ (void)argv;
53
+ xt_value clone = xt_object_new();
54
+ xt_value keys = xt_object_keys(thisValue);
55
+ int32_t count = (int32_t)xt_to_number(xt_array_length(keys));
56
+ for (int32_t i = 0; i < count; i++) {
57
+ xt_value key = xt_array_get(keys, xt_number((double)i));
58
+ xt_value value = xt_object_get(thisValue, key);
59
+ if (XT_IS_FUNCTION(value)) {
60
+ /* Re-use the method implementation with the new receiver. */
61
+ xt_value name = key;
62
+ xt_object_set(clone, name, xt_method_value_for_response(name));
63
+ } else {
64
+ xt_object_set(clone, key, value);
65
+ }
66
+ }
67
+ return clone;
68
+ }
69
+
70
+ /* Map a Response method name back to its implementation so `clone()` can copy
71
+ * the methods without duplicating the dispatch table. */
72
+ static void *xt_response_method_impl(xt_value name) {
73
+ const char *method = xt_string_data(name);
74
+ if (!method) return NULL;
75
+ if (strcmp(method, "text") == 0) return (void *)xt_response_method_text;
76
+ if (strcmp(method, "json") == 0) return (void *)xt_response_method_json;
77
+ if (strcmp(method, "arrayBuffer") == 0) return (void *)xt_response_method_array_buffer;
78
+ if (strcmp(method, "bytes") == 0) return (void *)xt_response_method_array_buffer;
79
+ if (strcmp(method, "clone") == 0) return (void *)xt_response_method_clone;
80
+ return NULL;
81
+ }
82
+
83
+ static xt_value xt_method_value_for_response(xt_value name) {
84
+ void *impl = xt_response_method_impl(name);
85
+ return impl ? xt_closure_new(impl, 0, NULL) : XT_UNDEFINED;
86
+ }
87
+
88
+ static xt_value xt_response_new(xt_value headers, int status, const char *statusText, const char *url,
89
+ const char *body, size_t bodyLength) {
90
+ xt_value response = xt_object_new();
91
+ xt_object_set(response, xt_string_from_cstr("ok"),
92
+ (status >= 200 && status < 300) ? XT_TRUE : XT_FALSE);
93
+ xt_object_set(response, xt_string_from_cstr("status"), xt_number((double)status));
94
+ xt_object_set(response, xt_string_from_cstr("statusText"), xt_string_from_cstr(statusText ? statusText : ""));
95
+ xt_object_set(response, xt_string_from_cstr("url"), xt_string_from_cstr(url ? url : ""));
96
+ xt_object_set(response, xt_string_from_cstr("redirected"), XT_FALSE);
97
+ xt_object_set(response, xt_string_from_cstr("type"), xt_string_from_cstr("basic"));
98
+ xt_object_set(response, xt_string_from_cstr("bodyUsed"), XT_FALSE);
99
+ xt_object_set(response, xt_string_from_cstr("headers"), headers);
100
+ xt_object_set(response, xt_string_from_cstr("__body"), xt_string_new(body ? body : "", bodyLength));
101
+ xt_fetch_set_method(response, "text", (void *)xt_response_method_text);
102
+ xt_fetch_set_method(response, "json", (void *)xt_response_method_json);
103
+ xt_fetch_set_method(response, "arrayBuffer", (void *)xt_response_method_array_buffer);
104
+ xt_fetch_set_method(response, "bytes", (void *)xt_response_method_array_buffer);
105
+ xt_fetch_set_method(response, "clone", (void *)xt_response_method_clone);
106
+ return response;
107
+ }
@@ -0,0 +1,72 @@
1
+ /* -- TCP socket helpers --------------------------------------------------- */
2
+
3
+ /*
4
+ * `fetch` performs a conventional blocking request/response exchange: connect,
5
+ * write the request, read until the response is complete (or the peer closes).
6
+ * The socket carries a receive timeout so a stalled server cannot hang the
7
+ * program forever; the timeout surfaces as a rejected promise.
8
+ */
9
+ #define XT_FETCH_TIMEOUT_SECONDS 30
10
+
11
+ static void xt_fetch_set_timeouts(int fd) {
12
+ #if defined(_WIN32)
13
+ DWORD ms = (DWORD)XT_FETCH_TIMEOUT_SECONDS * 1000;
14
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&ms, (int)sizeof(ms));
15
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&ms, (int)sizeof(ms));
16
+ #else
17
+ struct timeval timeout;
18
+ timeout.tv_sec = XT_FETCH_TIMEOUT_SECONDS;
19
+ timeout.tv_usec = 0;
20
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
21
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
22
+ #endif
23
+ }
24
+
25
+ static int xt_fetch_connect(const xt_fetch_url *url) {
26
+ struct addrinfo hints;
27
+ memset(&hints, 0, sizeof(hints));
28
+ hints.ai_family = AF_UNSPEC;
29
+ hints.ai_socktype = SOCK_STREAM;
30
+ struct addrinfo *result = NULL;
31
+ if (getaddrinfo(url->host, url->port, &hints, &result) != 0) return -1;
32
+ int fd = -1;
33
+ for (struct addrinfo *info = result; info; info = info->ai_next) {
34
+ int candidate = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
35
+ if (candidate < 0) continue;
36
+ if (connect(candidate, info->ai_addr, (xt_fetch_socklen_t)info->ai_addrlen) == 0) {
37
+ fd = candidate;
38
+ break;
39
+ }
40
+ xt_fetch_close_socket(candidate);
41
+ }
42
+ freeaddrinfo(result);
43
+ if (fd >= 0) xt_fetch_set_timeouts(fd);
44
+ return fd;
45
+ }
46
+
47
+ static int xt_fetch_send_all(int fd, const char *data, size_t length) {
48
+ size_t sent = 0;
49
+ while (sent < length) {
50
+ #if defined(_WIN32)
51
+ int written = send(fd, data + sent, (int)(length - sent), 0);
52
+ #else
53
+ ssize_t written = send(fd, data + sent, length - sent, 0);
54
+ #endif
55
+ if (written > 0) {
56
+ sent += (size_t)written;
57
+ continue;
58
+ }
59
+ return -1;
60
+ }
61
+ return 0;
62
+ }
63
+
64
+ /** Receive one chunk; returns the byte count, `0` on close, `-1` on error. */
65
+ static int xt_fetch_recv(int fd, char *buffer, size_t capacity) {
66
+ #if defined(_WIN32)
67
+ return recv(fd, buffer, (int)capacity, 0);
68
+ #else
69
+ ssize_t count = recv(fd, buffer, capacity, 0);
70
+ return count > 2147483647 ? 2147483647 : (int)count;
71
+ #endif
72
+ }
@@ -0,0 +1,108 @@
1
+ /* -- URL parsing ---------------------------------------------------------- */
2
+
3
+ /*
4
+ * `fetch` accepts absolute `http://` / `https://` URLs (there is no document
5
+ * base to resolve relative ones against). The parsed pieces are kept in a
6
+ * fixed-size struct because `fetch` hands them straight to `getaddrinfo`.
7
+ */
8
+ typedef struct {
9
+ int secure;
10
+ char host[256];
11
+ char port[8];
12
+ char path[4096];
13
+ } xt_fetch_url;
14
+
15
+ /** Parse `url` into `out`. Returns 0 on success, -1 on a malformed URL. */
16
+ static int xt_fetch_parse_url(const char *url, xt_fetch_url *out) {
17
+ if (!url) return -1;
18
+ out->secure = 0;
19
+ const char *cursor = url;
20
+ if (strncmp(cursor, "http://", 7) == 0) {
21
+ cursor += 7;
22
+ snprintf(out->port, sizeof(out->port), "80");
23
+ } else if (strncmp(cursor, "https://", 8) == 0) {
24
+ cursor += 8;
25
+ out->secure = 1;
26
+ snprintf(out->port, sizeof(out->port), "443");
27
+ } else {
28
+ return -1;
29
+ }
30
+
31
+ /* The authority ends at the first `/`, `?` or `#` (or the end of the URL). */
32
+ const char *authorityEnd = cursor;
33
+ while (*authorityEnd && *authorityEnd != '/' && *authorityEnd != '?' && *authorityEnd != '#') authorityEnd++;
34
+
35
+ /* Drop any `user:password@` prefix. */
36
+ const char *hostStart = cursor;
37
+ for (const char *p = cursor; p < authorityEnd; p++) {
38
+ if (*p == '@') hostStart = p + 1;
39
+ }
40
+
41
+ const char *hostEnd = authorityEnd;
42
+ const char *portStart = NULL;
43
+ if (hostStart < authorityEnd && *hostStart == '[') {
44
+ /* IPv6 literal: `[::1]:8080`. */
45
+ const char *close = (const char *)memchr(hostStart, ']', (size_t)(authorityEnd - hostStart));
46
+ if (!close) return -1;
47
+ hostEnd = close;
48
+ if (close + 1 < authorityEnd && close[1] == ':') portStart = close + 2;
49
+ hostStart++;
50
+ } else {
51
+ const char *colon = (const char *)memchr(hostStart, ':', (size_t)(authorityEnd - hostStart));
52
+ if (colon) {
53
+ hostEnd = colon;
54
+ portStart = colon + 1;
55
+ }
56
+ }
57
+
58
+ size_t hostLength = (size_t)(hostEnd - hostStart);
59
+ if (hostLength == 0 || hostLength >= sizeof(out->host)) return -1;
60
+ memcpy(out->host, hostStart, hostLength);
61
+ out->host[hostLength] = '\0';
62
+
63
+ if (portStart && portStart < authorityEnd) {
64
+ size_t portLength = (size_t)(authorityEnd - portStart);
65
+ if (portLength >= sizeof(out->port)) return -1;
66
+ memcpy(out->port, portStart, portLength);
67
+ out->port[portLength] = '\0';
68
+ for (const char *p = out->port; *p; p++) {
69
+ if (*p < '0' || *p > '9') return -1;
70
+ }
71
+ }
72
+
73
+ /* The request target keeps the query string but drops the fragment. */
74
+ if (*authorityEnd == '\0' || *authorityEnd == '#') {
75
+ snprintf(out->path, sizeof(out->path), "/");
76
+ } else {
77
+ const char *pathEnd = authorityEnd;
78
+ while (*pathEnd && *pathEnd != '#') pathEnd++;
79
+ size_t pathLength = (size_t)(pathEnd - authorityEnd);
80
+ if (pathLength >= sizeof(out->path)) return -1;
81
+ memcpy(out->path, authorityEnd, pathLength);
82
+ out->path[pathLength] = '\0';
83
+ }
84
+ return 0;
85
+ }
86
+
87
+ /*
88
+ * Resolve a `Location` header against the URL just requested. Only absolute
89
+ * URLs and root-relative paths are supported; anything else is reported as a
90
+ * failure so the caller can return the 3xx response unchanged.
91
+ */
92
+ static int xt_fetch_resolve_location(const xt_fetch_url *base, const char *location, char *out, size_t size) {
93
+ if (strncmp(location, "http://", 7) == 0 || strncmp(location, "https://", 8) == 0) {
94
+ snprintf(out, size, "%s", location);
95
+ return 0;
96
+ }
97
+ const char *scheme = base->secure ? "https" : "http";
98
+ if (location[0] == '/') {
99
+ int defaultPort = base->secure ? 443 : 80;
100
+ if (atoi(base->port) == defaultPort) {
101
+ snprintf(out, size, "%s://%s%s", scheme, base->host, location);
102
+ } else {
103
+ snprintf(out, size, "%s://%s:%s%s", scheme, base->host, base->port, location);
104
+ }
105
+ return 0;
106
+ }
107
+ return -1;
108
+ }
@@ -0,0 +1,39 @@
1
+ /*
2
+ * xbintsc runtime — the global `fetch` API.
3
+ *
4
+ * This is a small, dependency-free HTTP/1.1 client exposed as the platform
5
+ * `fetch` global. The runtime has no event loop (promises are drained
6
+ * synchronously by `await`), so the request is performed with blocking sockets
7
+ * and the returned promise is already settled. TLS is not implemented, so only
8
+ * `http://` URLs are accepted; `https://` rejects with a `TypeError`.
9
+ *
10
+ * The implementation is grouped by concern under `xt_fetch/` and `#include`d
11
+ * here as a single translation unit, following the other runtime modules.
12
+ */
13
+
14
+ #include "rt_internal.h"
15
+
16
+ #include <stdio.h>
17
+ #include <stdlib.h>
18
+ #include <string.h>
19
+
20
+ #if defined(_WIN32)
21
+ #include <winsock2.h>
22
+ #include <ws2tcpip.h>
23
+ typedef int xt_fetch_socklen_t;
24
+ #define xt_fetch_close_socket closesocket
25
+ #else
26
+ #include <netdb.h>
27
+ #include <sys/socket.h>
28
+ #include <sys/time.h>
29
+ #include <unistd.h>
30
+ typedef socklen_t xt_fetch_socklen_t;
31
+ #define xt_fetch_close_socket close
32
+ #endif
33
+
34
+ #include "xt_fetch/buffer.inc"
35
+ #include "xt_fetch/url.inc"
36
+ #include "xt_fetch/socket.inc"
37
+ #include "xt_fetch/headers.inc"
38
+ #include "xt_fetch/response.inc"
39
+ #include "xt_fetch/request.inc"
@@ -39,7 +39,7 @@ static int xt_is_iterator_state(xt_value value) {
39
39
  * any other object with a `Symbol.iterator` method is wrapped. */
40
40
  xt_value xt_iter_open(xt_value value) {
41
41
  if (XT_IS_ARRAY(value) || XT_IS_STRING(value) || xt_is_map(value) || xt_is_set(value) ||
42
- xt_is_generator(value))
42
+ xt_is_generator(value) || xt_typed_array_kind_of(value) >= 0)
43
43
  return value;
44
44
  if (XT_IS_OBJECT(value)) {
45
45
  xt_value method = xt_object_get(value, xt_symbol_well_known("iterator"));