git ssb

0+

dangerousbeans / web-bootloader



forked from Dominic / web-bootloader

Tree: ef1a2eaa163709173d29cc9f3fc446695e466fe7

Files: ef1a2eaa163709173d29cc9f3fc446695e466fe7 / bootloader.js

4692 bytesRaw
1var SecureUrl = require('./fetch')
2var u = require('./util')
3
4module.exports = function (prefix, store, log) {
5 var appname = prefix
6 var wb, running = false
7
8 //destroy everything
9 function scorchedEarth () {
10 for(var k in localStorage) {
11 delete localStorage[k]
12 }
13 }
14 function onProgress (ev) {
15 wb.onprogress && wb.onprogress(ev)
16 }
17
18 var init = '#'+appname+'_INIT'
19
20 return wb = {
21 scorchedEarth: scorchedEarth,
22 isInit: function () {
23 return location.hash.substring(0, init.length) === init
24 },
25 setup: function () {
26 if(!wb.isInit())
27 location.hash = init + location.hash
28 location.reload()
29 },
30 reinitialize: function (cb) {
31 delete localStorage[appname+'_current']
32 store.destroy(cb)
33 },
34 install: function (url, cb) {
35 onProgress('installing from:'+url)
36 var id = SecureUrl.isSecureUrl(url)
37 if(!id) return cb(new Error('not a secure url:'+url))
38 //check whether we already have this
39 //before downloading anything
40 store.get(id, function (err, data) {
41 if(!err) return cb(null, data, id)
42 SecureUrl(url, function (err, data, id) {
43 if(err) cb(err)
44 else store.add(data, id, function (err) {
45 cb(err, data, id)
46 })
47 })
48 })
49 },
50 installAndRun(url, cb) {
51 wb.install(url, function (err, _, id) {
52 if(err) cb(err)
53 else wb.run(id, cb)
54 })
55 },
56 add: store.add,
57 run: function (id, cb) {
58 if(!id) return cb(new Error('WebBoot.run: id must be provided'))
59 var _id
60 //if we are already running, restart
61 //clear out init code, if we are in setup mode
62 if(wb.isInit())
63 location.hash = location.hash.substring(init.length)
64
65 log.head(function (err, data) {
66 if(err) return cb(err)
67 if(data) _id = data.value
68 if(_id === id)
69 run(id)
70 else
71 log.append(id, function (err) {
72 if(err) return cb(err)
73 run(id)
74 })
75 })
76
77 function run (id) {
78 if(running) {
79 //reload, and then the current version will trigger.
80 cb()
81 location.reload()
82 }
83 else
84 store.get(id, function (err, data) {
85 if(err) return cb(err)
86 var script = document.createElement('script')
87 running = true
88 document.body.innerHTML = ''
89 script.textContent = u.toUtf8(data)
90 document.head.appendChild(script) //run javascript.
91 cb()
92 })
93 }
94 },
95 size: function (cb) {
96 store.ls(function (err, ls) {
97 if(err) cb(err)
98 else cb(null, ls.reduce(function (total, item) {
99 return total + item.size
100 }, 0))
101 })
102 },
103 //clear target amount of space.
104 prune: function (target, cb) {
105 if(!target) return cb(new Error('WebBoot.prune: size to clear must be provided'))
106 var cleared = 0, remove = []
107
108 function clear () {
109 var n = remove.length
110 while(remove.length) store.rm(remove.shift(), function () {
111 if(--n) return
112 if(cleared < target)
113 cb(new Error('could not clear requested space'), cleared)
114 else
115 cb(null, cleared)
116 })
117 }
118
119 store.ls(function (err, ls) {
120 if(err) return cb(err)
121 log.unfiltered(function (err, unfiltered) {
122 var stored = unfiltered.reverse()
123 for(var i = 0; i < stored.length; i++) {
124 var id = stored[i].value
125 var item = ls.find(function (e) {
126 return e.id === id
127 })
128
129 if(item) {
130 cleared += item.size
131 remove.push(id)
132 if(cleared >= target) return clear()
133 }
134 }
135 clear()
136 })
137 })
138 },
139
140 version: require('./package.json').version,
141 remove: store.rm,
142 has: store.has,
143 versions: function (cb) {
144 log.filtered(function (err, ls) {
145 if(err) return cb(err)
146 else if(ls.length) cb(null, ls)
147 else {
148 console.log('restore from legacy log...')
149 var versions = u.parse(localStorage[appname+'_versions'])
150 if(!versions) return cb(null, [])
151 var n = Object.keys(versions).length
152 for(var ts in versions) {
153 log.append(versions[ts], function () {
154 if(--n) return
155 //try again
156 log.filtered(cb)
157 })
158 }
159 }
160 })
161 },
162 history: log.unfiltered,
163 current: log.head,
164 append: log.append,
165 revert: log.revert,
166 onprogress: null
167 }
168}
169
170

Built with git-ssb-web