UNPKG

3.94 kBJavaScriptView Raw
1var debug = require('debug')('bankai.graph-service-worker')
2var assert = require('assert')
3var path = require('path')
4
5var browserify = require('browserify')
6var watchify = require('watchify')
7var tinyify = require('tinyify')
8var brfs = require('brfs')
9
10var ttyError = require('./tty-error')
11var exorcise = require('./exorcise')
12var utils = require('./utils')
13
14var filenames = [
15 'service-worker.js',
16 'sw.js'
17]
18
19module.exports = node
20
21function node (state, createEdge) {
22 var entry = state.metadata.entry
23 var self = this
24 var unwatch
25
26 assert.strictEqual(typeof entry, 'string', 'bankai.service-worker: state.metadata.entries should be type string')
27
28 var basedir = state.metadata.dirname
29
30 if (state.metadata.watch && !state.metadata.watchers.serviceWorker) {
31 state.metadata.watchers.serviceWorker = true
32 debug('watching ' + basedir + ' for ' + filenames.join(', '))
33 unwatch = utils.watch(basedir, filenames, parse)
34 this.on('close', function () {
35 debug('closing file watcher')
36 if (unwatch) unwatch()
37 })
38 }
39
40 parse()
41
42 function parse () {
43 utils.find(basedir, filenames, function (err, filename) {
44 if (err) {
45 state.metadata.serviceWorker = 'service-worker.js'
46 return createEdge('bundle', Buffer.from(''), {
47 mime: 'application/javascript'
48 })
49 }
50
51 // Expose what the original file name of the service worker was
52 state.metadata.serviceWorker = path.basename(filename)
53
54 var b = browserify(browserifyOpts([ filename ]))
55
56 if (state.metadata.watch && !state.metadata.watchers.serviceWorker) {
57 if (unwatch) unwatch() // File now exists, no need to have double watchers
58 state.metadata.watchers.serviceWorker = true
59 debug('watchify: watching ' + filename)
60 b = watchify(b)
61 b.on('update', function () {
62 debug('watchify: update detected in ' + filename)
63 bundleScripts()
64 })
65 self.on('close', function () {
66 debug('closing file watcher')
67 b.close()
68 })
69 }
70
71 var env = Object.assign({}, process.env, fileEnv(state))
72 b.transform(brfs)
73 if (!state.metadata.watch) b.plugin(tinyify, { env: env })
74
75 bundleScripts()
76
77 function bundleScripts () {
78 b.bundle(function (err, bundle) {
79 if (err) {
80 delete err.stream
81 err = ttyError('service-worker', 'browserify.bundle', err)
82 return self.emit('error', 'scripts', 'browserify.bundle', err)
83 }
84 var mapName = 'bankai-service-worker.js.map'
85 exorcise(bundle, mapName, function (err, bundle, map) {
86 if (err) return self.emit('error', 'service-worker', 'exorcise', err)
87 createEdge(mapName, map, {
88 mime: 'application/json'
89 })
90 createEdge('bundle', bundle, {
91 mime: 'application/javascript'
92 })
93 })
94 })
95 }
96 })
97 }
98}
99
100function browserifyOpts (entries) {
101 assert.ok(Array.isArray(entries), 'browserifyOpts: entries should be an array')
102 return {
103 debug: true,
104 entries: entries,
105 packageCache: {},
106 cache: {}
107 }
108}
109
110function fileEnv (state) {
111 var script = [
112 `${state.scripts.bundle.hash.toString('hex').slice(0, 16)}/bundle.js`
113 ]
114 var style = [`${state.styles.bundle.hash.toString('hex').slice(0, 16)}/bundle.css`]
115 var assets = split(state.assets.list.buffer)
116 var doc = split(state.documents.list.buffer).map(function (url) {
117 return url.slice(1)
118 })
119 var manifest = ['manifest.json']
120
121 var files = [].concat(script, style, assets, doc, manifest)
122 files = files.filter(function (file) {
123 return file
124 })
125
126 return {
127 STYLE_LIST: style,
128 SCRIPT_LIST: script,
129 ASSET_LIST: assets,
130 DOCUMENT_LIST: doc,
131 MANIFEST_LIST: manifest,
132 FILE_LIST: files
133 }
134
135 function split (buf) {
136 var str = String(buf)
137 return str.split(',')
138 }
139}