;; Ordered JS object construction.
;;
;; `js-obj` / `#js {}` preserves literal key order only up to EIGHT pairs; at
;; nine or more it routes through a PersistentHashMap and emits in HASH order,
;; at every optimization level, with no warning (dev/docs/CLJS.md — it has
;; already bitten id-kit's IdRecord, the bot's config defaults and game3's
;; snapshot frame). Every key still ends up on the object, so a wide object
;; that is only ever read by name is functionally fine — but anything whose key
;; order reaches the wire, storage, or a consumer's Object.keys must be built
;; with sequential sets.
;;
;; `oset*` does exactly that: one `unchecked-set` per pair, in argument order,
;; so the order is whatever the source says. Use it for any object wider than
;; eight pairs, and pin the result with a golden vector.
(ns ardegazu.peer.obj)
(defn oset*
"Set `kvs` (k1 v1 k2 v2 …) on `o` in order, then return `o`."
[o & kvs]
(loop [kv kvs]
(when (seq kv)
(unchecked-set o (first kv) (second kv))
(recur (nnext kv))))
o)
(defn ordered
"A fresh JS object with `kvs` set in order — the wide-object replacement for
`js-obj`."
[& kvs]
(apply oset* (js-obj) kvs))