timotheecour / Nim

Nim is a compiled, garbage-collected systems programming language with a design that focuses on efficiency, expressiveness, and elegance (in that order of priority).
http://nim-lang.org/
Other
2 stars 0 forks source link

0 Size JavaScript POC #480

Open juancarlospaco opened 3 years ago

juancarlospaco commented 3 years ago

Poor Of Concept

IQ 2000 secret hi tecc

Server-side:

Client-Side:

Example

import strutils

proc js2css*(js: openArray[char], css: var openArray[char]) =
  ## Encode JavaScript on CSS, without increasing CSS size.
  var i: int  # I can confirm this proc works ok.
  var temp = newStringOfCap(8)
  for c in css.mitems:
    if c in {'a'..'z', 'A'..'Z'}:
      temp = $ord(js[i]).toBin(8) # Can it be 6?
      for bc in temp:
        c = if bc == '1': toUpperAscii(c) else: toLowerAscii(c)
        if js.high == i: return
        else: inc i

proc css2js*(css: openArray[char]): string =
  ## TODO: The reverse of js2css
  var temp = newStringOfCap(8)
  for c in css:
    if c in {'a'..'z', 'A'..'Z'}:
      var x = ' '
      if c in {'A'..'Z'}: 
        x = '1' 
      elif c in {'a'..'z'}: 
        x = '0' 
      temp.add(x)
      if temp.len == 8:
        # TODO: How to binary to ASCII?
        # result.add decodedChar
        temp = "" # temp back to empty string?

var stile = readFile("example.css")   # Use a Bootstrap.css
js2css(readFile("example.js"), stile) # console.log("hello world")
writeFile("output.css", stile)        # "BaCKgroUNnd-cOLOr:DARkblUE  ... "

I can embed the JS on the CSS, I can not get it back, needs css2js.

More storage

Can you help me with css2js @xflywind ?.

ringabout commented 3 years ago

Make a simple working one

import strutils, parseutils

proc js2css*(js: openArray[char], css: var openArray[char]) =
  ## Encode JavaScript on CSS, without increasing CSS size.
  var i: int  # I can confirm this proc works ok.
  var j: int
  var temp = newStringOfCap(8)

  while true:
    temp = $ord(js[i]).toBin(8) # Can it be 6?
    for bc in temp:
      while true:
        let c = css[j]
        if c in {'a'..'z', 'A'..'Z'}:
          css[j] = if bc == '1': toUpperAscii(c) else: toLowerAscii(c)
          inc j
          break
        inc j

    if js.high == i: return
    else: inc i

var ix = 0
proc css2js*(css: openArray[char]): string =
  var temp = newStringOfCap(8)
  for c in css:
    if c in {'a'..'z', 'A'..'Z'}:
      var x = ' '
      if c in {'A'..'Z'}: 
        x = '1' 
      elif c in {'a'..'z'}: 
        x = '0'

      temp.add(x)
      if temp.len == 8:
        var num: int
        discard parseBin(temp, num)
        result.add chr(num)
        temp = "" # temp back to empty string?
        inc ix
        if ix == 20:
          break

var stile = readFile("test.css")   # Use a Bootstrap.css
js2css(readFile("test.js"), stile) # console.log("hello world")
echo css2js(stile)
juancarlospaco commented 3 years ago

TODO:

Client-Side:

Basically move css2js to the client-side.

timotheecour commented 3 years ago

Interesting idea but not specific to nim, so I'd suspect this would be used (eg alongside minifiers) if this worked in practice.

Bootstrap CSS is 145 kilobytes, is like ~25 Kb of JS, for free, for the "core" of a simple Nim app should do, lazy load the rest.

but if some site causes bootstrap (with same version before encoding) to be cached, a site using this trick would cause that cache to be invalidated and the modified bootstrap would have to be re-downloaded.