luvit-zed
=========

Zed is a library for all your luvit needs and is aimed to simplify many tasks including:

* __clienthttp.lua:__ Simplified http client
* __fs.lua:__ File system tasks (for example deleting a directory with content)
* __httperror.lua:__ Http error codes
* __json.lua:__ Less buggy JSON library ( use ZD.json:encode(), ZD.json:decode() )
* __math.lua:__ Math compatibility functions
* __simplehttp.lua:__ Simplified http server
* __string.lua:__ Extended String formatting
* __table.lua:__ Extended table functionality
* __utils.lua:__ Debug Table; URL parsing; Extended console output; Hashing tables
* __zedsocket.lua:__ Event-based Server-Browser communication in realtime using WebSocket [RFC 6455](http://tools.ietf.org/html/rfc6455) or AJAX.

How to install
========
luvit-zed is available using [npm](https://www.npmjs.org/package/luvit-zed).
to install zed just use
>npm install luvit-zed

Initialization
========
luvit-zed has 3 initialization methods.
The first one just returns the default zed as a local variable:
```lua
  local ZD = require('luvit-zed')()
```
The second one does the same, but also extends the given tables with more functionality:
```lua
  local string = require('string')
  local math = require('math')
  local fs = require('fs')
  local table = require('table')
  local ZD = require('luvit-zed')({
    string = string,
    math = math,
    fs = fs,
    table = table
  })
  -- the given tables now have more functions than before, see below for more information.
```
And the third one does the same as the other two, but puts every given table, including Zed, into the global variable.
```lua
  do
    local string = require('string')
    require('luvit-zed')({global = {string = string}})
  end
  string.split("This code will work, even though string is not defined in this scope", " ")
```


Examples/API:
=========
__clienthttp.lua:__
```lua
  local ZD = require('luvit-zed')()
  ZD.requestGET("example.com", 80, "/", function(html)  -- Gets html code from the given website
    print(html)
  end)
```

---
__fs.lua:__
```lua
  local fs = require('fs')
  local ZD = require('luvit-zed')({fs = fs})
  fs.rmsubdir("./delete/this/folder/with/content", function() -- Deletes the given folder including it's content
    print("Done")
  end)
```

---
__httperror.lua:__
```lua
  local ZD = require('luvit-zed')()
  local text = ZD.httpError(404) -- returns "Not found"
  local html = ZD.htmlError(404) -- returns the 404 page of ZED
```

---
__markdown.lua:__
```lua
  local ZD = require('luvit-zed')()
  local html = ZD.markdown([[
Test
------
]])
```

---
__math.lua:__
```lua
  local math = require('math')
  local ZD = require('luvit-zed')({math = math})
  local v = math.mod(7, 2) -- equals 7 % 2
```

---
__md5.lua:__
```lua
  local ZD = require('luvit-zed')()
  ZD.md5.sumhexa("Test") -- returns the md5 hash of "Test"
  -- not made by me, check the source file for credits  
```

---
__simplehttp.lua:__
```lua
  local fs = require('fs')
  local ZD = require('luvit-zed')()

  local sH = ZD.simpleHTTP(80, function(out)  -- out(data, [type, [code]]), eg: out("Test", "text/plain")
    out(nil, nil, 404)  -- default request handler, gets executed when no datatype has been found
  end)

  sH:addDataType("html", "text/html")  -- datatypes to handle like normal fileservers
  sH:addDataType("jpg", "image/jpeg")


  sH:addDataType("lua", function(url, req, cb)  -- script interpreter for lua files
    if fs.existsSync("." .. url.path) then
      local script = require("." .. url.path) or {}  -- loads lua file serverside on request
      if script.onRequest then
        script.onRequest(url, cb)  -- calls the onRequest function of that script
      end
    else
      cb(nil, nil, 404)  -- return 404 error
    end
  end)
```

---
__string.lua:__
```lua
  local string = require('string')
  local ZD = require('luvit-zed')({string = string})
  local tbl = string.split("Hello/World", "/") -- simply splits the first string by the second string and returns it as an indexed table
```

---
__table.lua:__
```lua
  local table = require('table')
  local ZD = require('luvit-zed')({table = table})
  local k = table.find(t, v) -- returns the key to the given value
  local t = table.reverse(t2) -- reverses indexed table
  local t = table.invert(t2) -- inverts table ( t2[v] = k )
```

---
__utils.lua:__
```lua
  local ZD = require('luvit-zed')()
  ZD.debugTable(tbl, 0, print) -- iterates through and prints out the give table in a readable form
  local hash = ZD.hashTable(t) -- hashes the given table using md5
  local url = ZD.parseURL("/index.lua?id=1234") -- parses the given url using the following syntax:
  -- {path = "/index.lua", ending = "lua", get={id="1234"}}
  -- allows easy access to get variables, for example: print(url.get.id)
```

---
__zedsocket.lua:__
```lua
  local ZD = require("luvit-zed")()

  local simpleHTTP = ZD.simpleHTTP(80, function(req, out)  -- creates http server to return the clientside code
      out([[
        <script type="text/javascript" src='/node_modules/luvit-zed/js/zedsocket.js'></script> // run the zedsocket.js
        <script>
          var socket = new ZedSocket("localhost", 1734, false); // create new zedsocket, third argument equals the second argument from the server

          socket.on("Foo", function(data){  // add listener for "Foo"
            console.log(data.msg);  // print out the received msg
          });

          socket.onConnection(function(){
            socket.send("Foo", {msg: "Bar"}); // send "Foo" packet with the msg "Bar"
          });
        </script>
      ]], "text/html")
  end)

  simpleHTTP:addDataType("js", "text/javascript") -- add DataType for js, so the clientside code can be retrieved

  local socket = ZD.ZedSocket(1734, false)	-- AJAX Server will be running on this port, Websocket Server on this port + 1, setting the second arguments to true will only use Websocket on the give port
  -- Be sure that in this case both ports must be open, 1734 and 1735, as WebSocket will be using the given port + 1

  socket:onConnection(function(client) -- listen for connections
    print("Client connected.")

    client:on("Foo", function(data) -- listen for "Foo" packets
      print(data.msg)  -- print out the received msg
      client:send("Foo", data) -- send the packet pack using the same name
    end)

    client:on("disconnect", function(data) -- listen for disconnections
      print("Client disconnected.")
    end)
  end)
```
