Break the main functionality into analytics, config, resources and site modules
[jst_server.git] / resources.js
1 let BuildCache = require('build_cache')
2 let fs = require('fs')
3 let jstemplate = require('jstemplate')
4 let less = require('less/lib/less-node')
5 var stream_buffers = require('stream-buffers')
6 let util = require('util')
7 let yauzl = require('yauzl')
8 let zetjs = require('zetjs')
9
10 let fs_readFile = util.promisify(fs.readFile)
11 let yauzl_open = util.promisify(yauzl.open)
12
13 let build_cache_js = new BuildCache()
14 let req_js = async path => {
15   let result = await build_cache_js.get(path)
16   if (result === undefined) {
17     console.log('compiling', path)
18     result = await jstemplate(path)
19     build_cache_js.set(path, result)
20   }
21   return result
22 }
23
24 let build_cache_json = new BuildCache()
25 let req_json = async path => {
26   let result = await build_cache_json.get(path)
27   if (result === undefined) {
28     console.log('parsing', path)
29     result = JSON.parse(await fs_readFile(path))
30     build_cache_json.set(path, result)
31   }
32   return result
33 }
34
35 let build_cache_less = new BuildCache()
36 let req_less = async (path, site_root, dir_name) => {
37   let result = await build_cache_less.get(path)
38   if (result === undefined) {
39     console.log('compiling', path)
40     let render = await less.render(
41       await fs_readFile(path, {encoding: 'utf-8'}),
42       {
43         //color: true,
44         //compress: false,
45         //depends: false,
46         filename: path,
47         //globalVars: null,
48         //ieCompat: false,
49         //insecure: false,
50         //javascriptEnabled: false,
51         //lint: false,
52         //math: 0,
53         //modifyVars: null,
54         paths: [site_root + dir_name],
55         //plugins: [],
56         //reUsePluginManager: true,
57         //rewriteUrls: false,
58         rootpath: site_root//,
59         //strictImports: false,
60         //strictUnits: false,
61         //urlArgs: ''
62       }
63     )
64     result = new Buffer(render.css, 'utf-8')
65     build_cache_less.set(path, result, render.imports)
66   }
67   return result
68 }
69
70 let build_cache_text = new BuildCache()
71 let req_text = async path => {
72   let result = await build_cache_text.get(path)
73   if (result === undefined) {
74     console.log('reading', path)
75     result = await fs_readFile(path, {encoding: 'utf-8'})
76     build_cache_text.set(path, result)
77   }
78   return result
79 }
80
81 let build_cache_zip = new BuildCache()
82 let req_zip = async path => {
83   let result = await build_cache_zip.get(path)
84   if (result === undefined) {
85     console.log('decompressing', path)
86     result = {}
87     let zipfile = await yauzl_open(path, {autoClose: false})
88     let entries = []
89     await new Promise(
90       (resolve, reject) => {
91         zipfile.
92         on('entry', entry => {entries.push(entry)}).
93         on('end', () => resolve())
94       }
95     )
96     for (let i = 0; i < entries.length; ++i) {
97       let read_stream = await new Promise(
98         (resolve, reject) => {
99           zipfile.openReadStream(
100             entries[i],
101             (err, stream) => {
102               if (err)
103                 reject(err)
104               resolve(stream)
105             }
106           )
107         }
108       )
109       let write_stream = new stream_buffers.WritableStreamBuffer()
110       let data = new Promise(
111         (resolve, reject) => {
112           write_stream.
113           on('finish', () => {resolve(write_stream.getContents())}).
114           on('error', () => {reject()})
115         }
116       )
117       read_stream.pipe(write_stream)
118       data = await data
119       console.log('entry path', entries[i].fileName, 'size', data.length)
120       result[entries[i].fileName] = data
121     }
122     await zipfile.close()
123     build_cache_zip.set(path, result)
124   }
125   return result
126 }
127
128 let build_cache_zet = new BuildCache()
129 let req_zet = async path => {
130   let result = await build_cache_zet.get(path)
131   if (result === undefined) {
132     console.log('opening', path)
133     result = new zetjs.Index(path)
134     build_cache_zet.set(
135       path,
136       result,
137       [
138         path + '.map.0',
139         path + '.param.0',
140         path + '.v.0',
141         path + '.vocab.0'
142       ]
143     )
144   }
145   return result
146 }
147
148 exports.req_js = req_js
149 exports.req_json = req_json
150 exports.req_less = req_less
151 exports.req_text = req_text
152 exports.req_zip = req_zip
153 exports.req_zet = req_zet