VanJS 1.0 has landed !!!
Tags: vanjs
Published: 2023-08-03 20:40:36

The little library that can, has reached the 1.0 release, thanks to TAO :-)
Among the new features, there is the awaited 'derived' state, and the simplification of state binding for complex objects.

Here is the 1.0 version of the new way of binding complex objects: 
[Demo](https://flems.io/#0=N4IgZglgNgpgziAXAbVAOwIYFsZJAOgAsAXLKEAGhAGMB7NYmBvEAXwvW10RADcM0+AFYIqdBk2J4A9NIAEAFUIQ4cyLDni4KxgygBPOQFc48OQANYxc3IDWMfQHdaAJwAmciGjiMMH2mAWWtZqrnIuMG5G1F4A5nLEhDByAEZGaG4a2gBeMPgAOmiFsnIAglAQGNpo8XC0OKlG0MRecnD6WCm0UKrEtOGR0cmJyWkZWRC5BWhWcgDyKUJyALzzizDUxBRyAPrpbjCQaJHbAA4utH1zgasLQvixMMQAChd9xPqnMNfbbrTUKzkf2oRhwDEKhVmfjcpQyAGVqEkorA5mgAGIQFw+QEAClMWza2zA6Wo20cGAgxAAsnAAJQrAB8hTkcjxTzkAH4Oaz8QoIDhaEZiDjiWhSXJyZSabTtsdHHI4U9abT8NC8bSITN2YiBI83HDiBhGHBtiCXAARGCnOCa2YudKwtwAYQwp2IRgilutuLAvytJrkGBcsXpywZcmAzLks3OMF4XtUqzNCajyf9gIO1qjxBchkjaBZLIi7pcBbAOKDIajrE0RsRrJg9Pzhc09DqsHwMBcFxcOMbUaLTw9Bcr1bUXgwUAMEYHmg9CcBsfj-urhVYtvZ6kYLgAQl43HFE21GW18DsUvvD4C4GeLxlD-gt12cSkTykz38sBz8ConfRjpskQakUWrEG0hqMK8lz9KszZyI8YH8FAOJNrOabWt+aqJCowEtsWw4JMoN47Eh1YUJqLIIXI3RuAAapOKEzgWhboXAmFuG4OLYXSs74aWhEqGeNH0VAZEUW07JITivCocxLIlOUlTVPE5jcTYfQDFE1DDEkjTjMkOR5LOsxHtxs4QIE0lyAAhMsqzEUhsktiyDmToCvCziysxdPsBpGmYqxygqTyeaELisrMUDUYEyD4HFxEVD4TBdnAAC6uHOSyBwuBAvAwDiUCPtshV0sVZ4wAAHhsQqRICACMZU7JmN5gK4ACiGCIi+grwhB8Cqhx2w+b1-k8XJhateFBXsjsqgBKkPX6n1dK7AlOjJVigKzWeiW6Clj7NM+UVhjZhU7JV1WMG4GUtsRd4HjUN6wDUiScqFLI6jUkR+cagLQo6CJIkYKLopiPg4p9eo-fA2wBkYpxuP55r1CtiDvaeOzCW5qweeN67Mewa6aiUPj+VBGkqIGcinFAFIFrQ6ybIRJjU28tDXHifXk7Q9KU0IJhgXcGzEPg5zQR8XzTCUYtXOWpOQWzvOqDAACOTRIZICT9DL7PlsArD0mkYFwBgeWqHVqT6IwngFiMchYF4FkQLVYyZEZoHUYs3OLmzHPyzA3MymoJLe6sOsc-aaCOi6boejACbAZC7L+4CjvECJJ44nBOw7DrOeIOBZNs+RzEkZOBdpyJJcspjUB0eXNuUlXUbnpej0F8gqXV7su0bXAHdd2uiceyo0PXie4dy5y3IAAyhnZhcK9BG6Idjx4naPfXqpyp5IXIBc2h7WPHev4ab-52-cjex-720K-wdQTr6NQsAAJJoDS9Uz9-SfG8tCi0AAOLUHvvdH0vx6ihnDHBWYzVARBUVASe6cRATADAOwOQcpkZYEBJHaOroSzx39CKP01oIFYAypNCK7J-CBGak5Qs-s4AAOAX9DiANESDBBhiLEwomEsPFG4buLZGInU5qNARj52qdUICKQ6u426xFKoveAAitr7EOF4ICwjCyxEfs-N+H8xotjcLeRRN5TgmFkcgmoGV8aDhLAWGxsQPz1FxFgtxXIgT-BVGgWgBwFCfGSNyDxOCC5BQUJVYUoTgL41-kCLsuVkirBIevFRKEoFMS8jQ9MgUYDykQcVdaxxwqwV9LsZqBdmqw3sbvNeeCMgx0IQmVJ9CoxUOmmBWhCTrT0lMTsXuJSLFWIKsUrsGU+IFkPnEj20JcSfm2HFfAiJoBuAiGgTJcEOmzABPNFZdd1mPlpsKd+RxKT6GVFkwsMZfZgCdD7aCHMAReLnsZbUyg64PNlvcuy9kuZsx3vdHEojwzUHwI5feoVJ4-IXqKag3tuRAuoPSAuIDxoWVZPsjwtldgaKOEBbxWBVSnC+BkCGHzrqrmYpMwlRMQKzB2ICG44YRRnhUHue8NQ0QknqkSYeNzaCnEQduF0nDUEzNmIaJRAA5OE8DEzhiClBCq+hgWYBwIsuKlYVonRgeyZAYsyFyCWVi9ZqUvm6wrMGOAyAZ7mpefPVYDMhAIsDNa2+qAMFLO1alKMsC3GBVUNyYEyyIj+TarAMExBZU4m8LKLgKLvFguoGGxgEaYBRtjQm9pYROlyGQLYbYvBzXzTuJ2BgOV4A4kNXSBh2SwIISgqcS0cAU0QDdGEMOAKTo6zeuNFkZaEJzEcGgJtXYPgtrbR23sOtti2HpF4xtFxm3wCnX0Gdtzq2KxRaFPYGRNHHDcG8sC1AZEwAANIOHgVwOQABqOQ+RKCPrvXYY9rNBXCq7A8oVTwRVnuQKezhl79D2o5KFLdH7f1dlFUkADZ7gPmtWEuwVk6crTog7LHEn5lTfnxNPOQrzxomSg6U99P7iDbh3oaz9Lh8BAuw7fT8+B8SlAozlI2eR6P1DnTdTwllz6MGkpcoFIKeQkekuCycQdsO8ZgD0ZIGKMOWt4PhueKxYUhwBQAMi06yaythmOGhcMQOAAB1SksjH30EffSAAPrZuQvA2VwA5Q9WI3KxTKlCiJzJbIKPPl4Bk8hXnxpydMBJfzvYZJUocQRNUCzjVxVNUwWJ2xgAIQLlxDAsR404EyVKuj+4cR7oOPioRmCE0G3vvDRGjBsFHlE3qk9hBdTfWWqUbsGBDCrFikllrX0lqjVSgdKA248QnlclFWy9khJ1xEhlSGbXRrqP3WVnNU1vLRUwfk4KwpFuDeNB1lwXWjlGipK6ORo2uyucPMqOt0YaEBtSK4rAsp8nYMBEC985TsOznfE1J7JWD2RHMpZUJNkF4MfBzioHZWd5MYiDTTqMBzOJFje9yBjH6j4AiFgWgeUUIxbCtQ42W39vQzgEdrr9JiI3xm2XUSaAZnBEcwIVB0Jtg7G2FK-uCRstwBjUHHnsrYZ9SLZObYx8-Q5TyjMyqpxXBgWAKzgsMzNSUBAKYWAmwIBtjwHVAALDPRAM82AcBAOq7gBARAa-ELoKQPB+QK+MxGFXcgaxgAuDgx9+BpD8EECIR9moWfK4PLwIaLhtjAyKe79yAh8A8+7rVjAcfBD+yzovEwBdH0AFU0BgCeJwo9IB3cyijB6E+j6SDEGtIgWQx2Mj1BMF2fAOBpCuggByCIcBgYmeWAAVkfQAbmD22MCAAleACvvDfFsICAATN-EfIEWenNoD9FmsEoyPrRIX5QNQ5A59MFiZ9BdgBYDgLEbPIBd-EBWQf5vJ-KDgX0LAa-dAoCuALhENwQ-QgMAAFpDJEB58DdTgKpn0MFt8QAj8Uo5Bb8i9T8IwL8r8H0YDj9VAC878kRH1RdX8YB39ugv94IIgmA-9WpADgDQDwDIDthoC88sDECS8z8UDr9zMpw1A99jAMCJQLNWh58bRn8fB8DCDP8XAC4UgoAjAYByD6BiAgDJgCDqCICS8oDmJH02puxXAkDz9L9r9YQ5AuwexqJqAzQQchCPg380CP9iDJDpDZDKDFCQCwCVD3c6CmdR9vA-58DYDSNH0KD5CqCXDh9NQ4UWh6BD9j8AAZHQHER-BhGlHEWcYGVkUKCoVkCMYQt-LImAXwmsKPY-fAS3A6XhekQsKMELGZMI3XKZWAK0VkC-BIocfiJVL3FQZIYFbvTZWcXkfkGAQUYUbvbYRo6sWJUIkkcIqZJ4TQnsc0I0FPRiOCLKeYyTE+ZXeWLPNAmY7Q5-EQegSfHvUbD1c1GsFkOlB9MUMfTg7AuYw0P6doMUVkbo5iZPVY1BTPXnHfPfFBXwwQ93ZfetAYOAafcLWCVgAEhIXMK5QsbvEE5IQEQMSUMCRg2RCvOxVMOsQgBsbse7fEbYi0eYp4onRTA4uEuYedV3C4lsFnPYtAA43vP6JEoEuE4QOoNAQncaV4veWCD46-X4+Avfcw7YWk+ko404zKCUyUonMLZIJYiLfE24hYsoqlKoiYmosoElJ4q5FnXgZ2eUVYLU3VM48aFnUKR-I8LkycVk-Y+AXvb8bvXvINbkTuHRFkLwVqQENfDfG1S0kqCCEwVKCE2LfiMPVI-tIEXKVkYAHIiufPWgQzfAjBd0+MlAiPILCUs0jA1vV0VkXwmInwZU8aekInGlXU-JOlQof3AaDwLDf4UESQOjfxfQbYUoTUxiYeOAOo04HERfb+FUEYdklExUso8okCDXLXYWGohAHgY3GeAAgANgAE4TczdOAcA8Blk4BRAaA5DJAWBWAu4LcuA8AqRaIc96I0AAApOENgIAA)

```js
import { van } from "./van.js"

const { div, br, ul, li } = van.tags,
  data = van.state({ status: "Unfetched" }),
  url = "https://randomuser.me/api?results=5";

const ResponseOk = 200;

const InfoStatus = {
  "Fetching Users" : {msg: "Fetching users", style: "color: red; font-size:24px" }, 
  "Users Fetched" : {msg: "Users fetched", style: "color: green; font-size:24px" }, 
  "Unfetched" : {msg: "Will fetch users within 2s", style: "color: blue; font-size:24px" }, 
  "Error" : {msg: "An error occured", style: "color: blue; font-size:24px" }, 
}

const styleUser = "font-size:24px";

function UserList(user) {
  return (
    ul (
      li ( {style:styleUser} , user.name.first)    
  ))
}

function sleep (ms) {
  return new Promise ((res) => {
    setTimeout(res, ms)
  })
}

function setErrorData () {
    data.val = { status: "Error", jsonResult : [] }   
}
 
const fetchData = async () => {
  data.val = { status: "Fetching Users" };
  let response = {};
  try {
     response  =  await fetch(url)
  }
  catch (err) {
    setErrorData ()
  }
  if (ResponseOk) {  
    const jsonResult = await response.json()
    data.val = { status: "Users Fetched", jsonResult }                       
  }
  else {
    setErrorData ()  
  }
}

function App () {
  const view =  () => {  
    const 
      users = data.val.jsonResult?.results ?? [],
      info = InfoStatus[data.val.status];
    return div (
      div ({style: info.style}, info.msg, br()),       
      users.map (UserList)  
    ) 
  }
  return view
}

van.add (document.body, App () )

sleep(2000).then(fetchData)     
```