js-on-sx: object computed keys + insertion-order tracking
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s

This commit is contained in:
2026-05-08 18:16:32 +00:00
parent a8d0dfb38a
commit 0d99b5dfe8
4 changed files with 192 additions and 19 deletions

View File

@@ -1293,6 +1293,16 @@
(define js-args (fn (&rest args) args))
(define
js-make-list
(fn
(&rest args)
(let
((r (list)))
(begin
(for-each (fn (x) (append! r x)) args)
r))))
(define js-trim (fn (s) (js-trim-left (js-trim-right s))))
(define
@@ -2993,6 +3003,46 @@
(define dict-has? (fn (d k) (contains? (keys d) k)))
(define
js-make-obj
(fn () (let ((d (dict))) (begin (dict-set! d "__js_order__" (list)) d))))
(define
js-obj-order-add!
(fn
(obj k)
(cond
((not (dict? obj)) nil)
((not (contains? (keys obj) "__js_order__")) nil)
(else
(let
((order (get obj "__js_order__")))
(if (contains? order k) nil (append! order k)))))))
(define
js-obj-order-remove!
(fn
(obj k)
(cond
((not (dict? obj)) nil)
((not (contains? (keys obj) "__js_order__")) nil)
(else
(dict-set!
obj
"__js_order__"
(filter (fn (x) (not (= x k))) (get obj "__js_order__")))))))
(define
js-obj-set!
(fn
(obj key val)
(let
((sk (js-to-string key)))
(begin
(if (not (contains? (keys obj) sk)) (js-obj-order-add! obj sk) nil)
(dict-set! obj sk val)
val))))
(begin
(define
js-set-prop
@@ -3001,7 +3051,12 @@
(cond
((js-undefined? obj) (error "js-set-prop: cannot set on undefined"))
((= (type-of obj) "dict")
(do (dict-set! obj (js-to-string key) val) val))
(let
((sk (js-to-string key)))
(begin
(if (not (contains? (keys obj) sk)) (js-obj-order-add! obj sk) nil)
(dict-set! obj sk val)
val)))
((= (type-of obj) "list") (do (js-list-set! obj key val) val))
(else val))))
(define
@@ -3428,16 +3483,35 @@
(append! acc (char-at s i))
(js-string-to-list s (+ i 1) acc)))))
(define
js-key-internal?
(fn
(k)
(or (= k "__js_order__") (= k "__proto__"))))
(define
js-object-keys
(fn
(o)
(cond
((dict? o)
(let
((result (list)))
(for-each (fn (k) (append! result k)) (keys o))
result))
(cond
((contains? (keys o) "__js_order__")
(let
((result (list)))
(begin
(for-each
(fn (k) (if (js-key-internal? k) nil (append! result k)))
(get o "__js_order__"))
result)))
(else
(let
((result (list)))
(begin
(for-each
(fn (k) (if (js-key-internal? k) nil (append! result k)))
(keys o))
result)))))
(else (list)))))
(define
@@ -3563,9 +3637,85 @@
(cond
((list? o)
(let ((r (list))) (begin (js-list-keys-loop o 0 r) r)))
((dict? o) (js-object-keys o))
((dict? o) (js-own-property-names-ordered o))
(else (list)))))
(define
js-own-property-names-ordered
(fn
(o)
(let
((all (js-object-keys o))
(ints (list))
(rest (list)))
(begin
(for-each
(fn
(k)
(if (js-int-key? k) (append! ints k) (append! rest k)))
all)
(append (js-sort-int-keys ints) rest)))))
(define
js-int-key?
(fn
(k)
(cond
((not (= (type-of k) "string")) false)
((= (len k) 0) false)
(else (js-int-key-loop? k 0 (len k))))))
(define
js-int-key-loop?
(fn
(s i n)
(cond
((>= i n) true)
((let ((c (char-code-at s i))) (and (>= c 48) (<= c 57)))
(js-int-key-loop? s (+ i 1) n))
(else false))))
(define
js-sort-int-keys
(fn
(lst)
(let
((nums (map js-string-to-number lst)))
(begin
(js-sort-numbers! nums)
(map (fn (n) (str (js-num-to-int n))) nums)))))
(define
js-sort-numbers!
(fn
(lst)
(let ((n (len lst)))
(js-bubble-sort! lst 0 n))))
(define
js-bubble-sort!
(fn
(lst i n)
(cond
((>= i n) nil)
(else
(begin (js-bubble-sort-inner! lst 0 (- n i 1)) (js-bubble-sort! lst (+ i 1) n))))))
(define
js-bubble-sort-inner!
(fn
(lst j stop)
(cond
((>= j stop) nil)
((> (nth lst j) (nth lst (+ j 1)))
(let
((a (nth lst j)) (b (nth lst (+ j 1))))
(begin
(set-nth! lst j b)
(set-nth! lst (+ j 1) a)
(js-bubble-sort-inner! lst (+ j 1) stop))))
(else (js-bubble-sort-inner! lst (+ j 1) stop)))))
(define
js-object-get-own-property-descriptor
(fn
@@ -3656,7 +3806,12 @@
(obj key)
(cond
((dict? obj)
(begin (dict-delete! obj (js-to-string key)) true))
(let
((sk (js-to-string key)))
(begin
(js-obj-order-remove! obj sk)
(dict-delete! obj sk)
true)))
(else true))))
(define
@@ -4135,14 +4290,17 @@
(for-each
(fn
(k)
(let
((val (get v k)))
(if
(js-key-internal? k)
nil
(let
((vs (js-json-stringify-value val)))
(if
(not (js-undefined? vs))
(append! parts (str (js-json-escape-string k) ":" vs))))))
(keys v))
((val (get v k)))
(let
((vs (js-json-stringify-value val)))
(if
(not (js-undefined? vs))
(append! parts (str (js-json-escape-string k) ":" vs)))))))
(js-object-keys v))
(str "{" (join "," parts) "}")))
(else "null"))))