Commitaee36189Recorded6 May 2026Repositorysigil-websocket
Add WASM WebSocket bridge branch
Message
Add sigil-wasm-net as a dependency and make the connection module select a browser/WASM path with cond-expand. The WASM branch imports (sigil wasm net) and opens browser WebSocket handles while preserving the existing TCP/TLS implementation for native builds.
Verification: XDGCACHEHOME=/tmp/sigil-cache SIGIL_FEATURES=wasm /home/daviwil/Projects/Code/sigil/sigil/build/dev/bin/sigil -L /home/daviwil/Projects/Code/sigil/sigil/build/web/lib -L /home/daviwil/Projects/Code/sigil/sigil-websocket/src eval '(import (sigil websocket connection)) (display "ok") (newline)'; native eval tests 9/9 and 14/14.
Changed
dev-redirects.sgl | 3 +++
package.sgl | 1 +
src/sigil/websocket/connection.sgl | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------
3 files changed, 82 insertions(+), 45 deletions(-)Diff
dev-redirects.sglmodified
@@ -1,6 +1,9 @@
1
;; Development redirects — point dependencies at local sibling checkouts. 2
(redirects 3
repos: (list+4
(for-repo+5
url: "codeberg:sigil/sigil"+6
use: (from-path dir: "../sigil")) 7
(for-repo 8
url: "codeberg:sigil/sigil-lang" 9
use: (from-path dir: "../sigil-lang"))package.sglmodified
@@ -29,6 +29,7 @@
29
30
dependencies: (list 31
(from-git url: "codeberg:sigil/sigil" package: "sigil-stdlib" version: "^0.15")+32
(from-git url: "codeberg:sigil/sigil" package: "sigil-wasm-net" version: "^0.15") 33
(from-git url: "codeberg:sigil/sigil-socket" version: "^0.14.0") 34
(from-git url: "codeberg:sigil/sigil-tls" version: "^0.14.1") 35
(from-git url: "codeberg:sigil/sigil-crypto" version: "^0.15.0"))src/sigil/websocket/connection.sglmodified
@@ -13,6 +13,10 @@
13
(sigil crypto) 14
(sigil async) 15
(sigil websocket frame))+16
(cond-expand+17
(wasm+18
(import (sigil wasm net)))+19
(else)) 20
21
(export 22
;; Connection record@@ -197,9 +201,13 @@
201
202
;;; Write to socket (handles both TCP and TLS) 203
(define (conn-write sock data)−200
(if (tls-connection? sock)−201
(tls-write sock data)−202
(socket-write sock data)))+204
(cond-expand+205
(wasm+206
(wasm-websocket-send sock data))+207
(else+208
(if (tls-connection? sock)+209
(tls-write sock data)+210
(socket-write sock data))))) 211
212
;;; Read from socket (handles both TCP and TLS). 213
;;;@@ -210,21 +218,33 @@
218
;;; particular). TLS still goes through `tls-read` which handles 219
;;; raw bytes natively. 220
(define (conn-read sock max-bytes)−213
(if (tls-connection? sock)−214
(tls-read sock max-bytes)−215
(socket-read-bytevector sock max-bytes)))+221
(cond-expand+222
(wasm+223
(wasm-websocket-receive sock))+224
(else+225
(if (tls-connection? sock)+226
(tls-read sock max-bytes)+227
(socket-read-bytevector sock max-bytes))))) 228
229
;;; Close socket (handles both TCP and TLS) 230
(define (conn-close sock)−219
(if (tls-connection? sock)−220
(tls-close sock)−221
(socket-close sock)))+231
(cond-expand+232
(wasm+233
(wasm-websocket-close sock 1000 ""))+234
(else+235
(if (tls-connection? sock)+236
(tls-close sock)+237
(socket-close sock))))) 238
239
;;; Set socket to non-blocking mode (handles both TCP and TLS) 240
(define (conn-set-non-blocking! sock enable)−225
(if (tls-connection? sock)−226
(tls-set-non-blocking! sock enable)−227
(socket-set-non-blocking! sock enable)))+241
(cond-expand+242
(wasm+243
#t)+244
(else+245
(if (tls-connection? sock)+246
(tls-set-non-blocking! sock enable)+247
(socket-set-non-blocking! sock enable))))) 248
249
;; ============================================================ 250
;; Public API@@ -238,39 +258,52 @@
258
(let ((parsed (parse-ws-url url))) 259
(if (not parsed) 260
#f−241
(let* ((scheme (car parsed))−242
(host (cadr parsed))−243
(port (caddr parsed))−244
(path (cadddr parsed))−245
;; Connect using TLS for wss://−246
(socket (if (string=? scheme "wss")−247
(tls-connect host port)−248
(tcp-connect host port))))−249
(if (not socket)−250
#f−251
(let* ((conn (ws-connection−252
socket: socket−253
state: 'connecting−254
url: url−255
host: host−256
buffer: (make-bytevector 0)−257
fragments: '()))−258
(key (generate-ws-key))−259
(expected-accept (calculate-accept-key key))−260
(request (build-handshake-request host path key)))−261
;; Send handshake request−262
(conn-write socket request)−263
;; Validate response−264
(if (validate-handshake conn expected-accept)−265
(begin−266
(set-ws-connection-state! conn 'open)−267
;; Set to non-blocking for async I/O when in scheduler−268
(when (current-scheduler)−269
(conn-set-non-blocking! socket #t))−270
conn)−271
(begin−272
(conn-close socket)−273
#f))))))))+261
(cond-expand+262
(wasm+263
(let* ((host (cadr parsed))+264
(socket (wasm-websocket-open url "")))+265
(and socket+266
(ws-connection+267
socket: socket+268
state: 'open+269
url: url+270
host: host+271
buffer: (make-bytevector 0)+272
fragments: '()))))+273
(else+274
(let* ((scheme (car parsed))+275
(host (cadr parsed))+276
(port (caddr parsed))+277
(path (cadddr parsed))+278
;; Connect using TLS for wss://+279
(socket (if (string=? scheme "wss")+280
(tls-connect host port)+281
(tcp-connect host port))))+282
(if (not socket)+283
#f+284
(let* ((conn (ws-connection+285
socket: socket+286
state: 'connecting+287
url: url+288
host: host+289
buffer: (make-bytevector 0)+290
fragments: '()))+291
(key (generate-ws-key))+292
(expected-accept (calculate-accept-key key))+293
(request (build-handshake-request host path key)))+294
;; Send handshake request+295
(conn-write socket request)+296
;; Validate response+297
(if (validate-handshake conn expected-accept)+298
(begin+299
(set-ws-connection-state! conn 'open)+300
;; Set to non-blocking for async I/O when in scheduler+301
(when (current-scheduler)+302
(conn-set-non-blocking! socket #t))+303
conn)+304
(begin+305
(conn-close socket)+306
#f)))))))))) 307
308
;;; Check if connection is open 309
(define (ws-connected? conn)