Switch to acorn-based JS templates with classes, ids, scripts, template strings
[jst_server.git] / resources.js
1 let BuildCache = require('build_cache')
2 let emailjs = require('emailjs')
3 let fs = require('fs')
4 let JSONCache = require('json_cache')
5 let less = require('less/lib/less-node')
6 var stream_buffers = require('stream-buffers')
7 let util = require('util')
8 let yauzl = require('yauzl')
9 let zetjs = require('zetjs')
10
11 let fs_mkdir = util.promisify(fs.mkdir)
12 let fs_readFile = util.promisify(fs.readFile)
13 let yauzl_open = util.promisify(yauzl.open)
14
15 let build_cache_email = new BuildCache()
16 let get_email = path => build_cache_email.get(
17   path,
18   async result => {
19     console.log('parsing', path)
20     result.value = emailjs.server.connect(
21       JSON.parse(await fs_readFile(path))
22     )
23   }
24 )
25
26 // this is for read-only JSON files
27 // they will be reloaded from disk if modified
28 let build_cache_json = new BuildCache()
29 let get_json = path => build_cache_json.get(
30   path,
31   async result => {
32     console.log('parsing', path)
33     result.value = JSON.parse(await fs_readFile(path))
34   }
35 )
36
37 let build_cache_less = new BuildCache()
38 let get_less = (path, site_root, dir_name) => build_cache_less.get(
39   path,
40   async result => {
41     console.log('compiling', path)
42     let render = await less.render(
43       await fs_readFile(path, {encoding: 'utf-8'}),
44       {
45         //color: true,
46         //compress: false,
47         //depends: false,
48         filename: path,
49         //globalVars: null,
50         //ieCompat: false,
51         //insecure: false,
52         //javascriptEnabled: false,
53         //lint: false,
54         //math: 0,
55         //modifyVars: null,
56         paths: [site_root + dir_name],
57         //plugins: [],
58         //reUsePluginManager: true,
59         //rewriteUrls: false,
60         rootpath: site_root//,
61         //strictImports: false,
62         //strictUnits: false,
63         //urlArgs: ''
64       }
65     )
66     result.deps.concat(render.imports)
67     result.value = Buffer.from(render.css)
68   }
69 )
70
71 let build_cache_text = new BuildCache()
72 let get_text = path => build_cache_text.get(
73   path,
74   async result => {
75     console.log('reading', path)
76     result.value = await fs_readFile(path, {encoding: 'utf-8'})
77   }
78 )
79
80 let build_cache_zip = new BuildCache()
81 let get_zip = path => build_cache_zip.get(
82   path,
83   async result => {
84     console.log('decompressing', path)
85     result.value = {}
86     let zipfile = await yauzl_open(path, {autoClose: false})
87     let entries = []
88     await new Promise(
89       (resolve, reject) => {
90         zipfile.
91         on('entry', entry => {entries.push(entry)}).
92         on('end', () => resolve())
93       }
94     )
95     for (let i = 0; i < entries.length; ++i) {
96       let read_stream = await new Promise(
97         (resolve, reject) => {
98           zipfile.openReadStream(
99             entries[i],
100             (err, stream) => {
101               if (err)
102                 reject(err)
103               resolve(stream)
104             }
105           )
106         }
107       )
108       let write_stream = new stream_buffers.WritableStreamBuffer()
109       let data = new Promise(
110         (resolve, reject) => {
111           write_stream.
112           on('finish', () => {resolve(write_stream.getContents())}).
113           on('error', () => {reject()})
114         }
115       )
116       read_stream.pipe(write_stream)
117       let path = '/' + entries[i].fileName
118       data = await data
119       console.log('entry path', path, 'size', data.length)
120       result.value[path] = data
121     }
122     await zipfile.close()
123   }
124 )
125
126 let build_cache_zet = new BuildCache()
127 let get_zet = path => build_cache_zet.get(
128   path,
129   async result => {
130     console.log('opening', path)
131     result.deps = [
132       path + '.map.0',
133       path + '.param.0',
134       path + '.v.0',
135       path + '.vocab.0'
136     ]
137     result.value = new zetjs.Index(path)
138   }
139 )
140
141 // this is for read/write JSON files
142 // they will not be reloaded from disk if modified
143 let try_mkdir = async path => {
144   try {
145     await fs_mkdir(path)
146   }
147   catch (err) {
148     if (err.code !== 'EEXIST') // should check error type
149       throw err
150   }
151 }
152 let json_cache = new JSONCache()
153 json_cache.diag = true
154
155 exports.get_email = get_email
156 exports.get_json = get_json
157 exports.get_less = get_less
158 exports.get_text = get_text
159 exports.get_zip = get_zip
160 exports.get_zet = get_zet
161 exports.try_mkdir = try_mkdir
162 exports.json_cache = json_cache