Skip to content

Commit baf997b

Browse files
feat: text input handling and fetch() HTTP API
1 parent 3da2f08 commit baf997b

8 files changed

Lines changed: 608 additions & 2 deletions

File tree

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ else ifeq ($(UNAME_S),Darwin)
3737
LDFLAGS = -framework Metal -framework MetalKit -framework Cocoa -framework QuartzCore
3838
SRCS_PLATFORM = src/main.m src/platform_darwin.m src/gpu_metal.m \
3939
src/api_clipboard_darwin.m src/api_shell_darwin.m \
40-
src/api_dialog_darwin.m src/api_menu_darwin.m
40+
src/api_dialog_darwin.m src/api_menu_darwin.m \
41+
src/api_fetch_darwin.m
4142
SRCS_C = src/image.c src/text.c src/glyph_atlas.c src/api_fs.c src/api_sysinfo.c \
4243
src/api_window.c src/api_app.c src/api_console.c src/api_timers.c \
43-
src/api_db.c
44+
src/api_db.c src/input_text.c
4445
SRCS_MAIN =
4546
endif
4647

src/api.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ void ls_api_timers_init(R8EContext *ctx);
4646
/* Database API (stowDB) */
4747
void ls_api_db_init(R8EContext *ctx);
4848

49+
/* fetch() HTTP API (macOS) */
50+
void ls_api_fetch_init(R8EContext *ctx);
51+
4952
/* Tick timers — call each frame from event loop */
5053
void ls_timers_tick(R8EContext *ctx);
5154

src/api_fetch_darwin.m

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* api_fetch_darwin.m - LightShell fetch() HTTP API (macOS)
3+
*
4+
* Provides a global fetch(url) function that performs a synchronous HTTP GET
5+
* and returns the response body as a string.
6+
*
7+
* This is a simplified v1 implementation. A full implementation would return
8+
* a Response object with .json(), .text() methods and be async/Promise-based.
9+
*/
10+
11+
#import <Foundation/Foundation.h>
12+
#include "api.h"
13+
14+
/* fetch(url) → string (synchronous, v1) */
15+
static R8EValue api_fetch(R8EContext *ctx, R8EValue this_val,
16+
int argc, const R8EValue *argv) {
17+
(void)this_val;
18+
19+
if (argc < 1 || !r8e_is_string(argv[0])) {
20+
r8e_throw_type_error(ctx, "fetch: url must be a string");
21+
return R8E_UNDEFINED;
22+
}
23+
24+
/* Extract URL string */
25+
char url_buf[2048];
26+
size_t url_len;
27+
const char *url_raw = r8e_get_cstring(argv[0], url_buf, &url_len);
28+
29+
/* Make a null-terminated copy */
30+
char url_str[2048];
31+
if (url_len >= sizeof(url_str)) url_len = sizeof(url_str) - 1;
32+
memcpy(url_str, url_raw, url_len);
33+
url_str[url_len] = '\0';
34+
35+
/* Build NSURL */
36+
NSURL *nsurl = [NSURL URLWithString:[NSString stringWithUTF8String:url_str]];
37+
if (!nsurl) {
38+
r8e_throw_error(ctx, "fetch: invalid URL '%s'", url_str);
39+
return R8E_UNDEFINED;
40+
}
41+
42+
/* Synchronous request using NSURLSession semaphore pattern */
43+
__block NSData *responseData = nil;
44+
__block NSError *responseError = nil;
45+
__block NSHTTPURLResponse *httpResponse = nil;
46+
47+
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
48+
NSURLSession *session = [NSURLSession sharedSession];
49+
NSURLRequest *request = [NSURLRequest requestWithURL:nsurl
50+
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
51+
timeoutInterval:30.0];
52+
53+
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
54+
completionHandler:^(NSData *data,
55+
NSURLResponse *response,
56+
NSError *error) {
57+
responseData = data;
58+
responseError = error;
59+
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
60+
httpResponse = (NSHTTPURLResponse *)response;
61+
}
62+
dispatch_semaphore_signal(sem);
63+
}];
64+
65+
[task resume];
66+
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
67+
68+
if (responseError || !responseData) {
69+
const char *errMsg = responseError
70+
? [[responseError localizedDescription] UTF8String]
71+
: "unknown error";
72+
r8e_throw_error(ctx, "fetch: request failed: %s", errMsg);
73+
return R8E_UNDEFINED;
74+
}
75+
76+
/* Convert response body to string */
77+
NSString *body = [[NSString alloc] initWithData:responseData
78+
encoding:NSUTF8StringEncoding];
79+
if (!body) {
80+
/* Try Latin-1 as fallback */
81+
body = [[NSString alloc] initWithData:responseData
82+
encoding:NSISOLatin1StringEncoding];
83+
}
84+
if (!body) {
85+
r8e_throw_error(ctx, "fetch: could not decode response as text");
86+
return R8E_UNDEFINED;
87+
}
88+
89+
return r8e_make_cstring(ctx, [body UTF8String]);
90+
}
91+
92+
void ls_api_fetch_init(R8EContext *ctx) {
93+
r8e_set_global_func(ctx, "fetch", api_fetch, 1);
94+
}

0 commit comments

Comments
 (0)