UNPKG

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