1 | var debug = require('debug')('bankai.graph-service-worker')
|
2 | var assert = require('assert')
|
3 | var findup = require('findup')
|
4 | var path = require('path')
|
5 |
|
6 | var browserify = require('browserify')
|
7 | var watchify = require('watchify')
|
8 | var tinyify = require('tinyify')
|
9 | var brfs = require('brfs')
|
10 |
|
11 | var ttyError = require('./tty-error')
|
12 | var exorcise = require('./exorcise')
|
13 | var utils = require('./utils')
|
14 |
|
15 | var filenames = [
|
16 | 'service-worker.js',
|
17 | 'sw.js'
|
18 | ]
|
19 |
|
20 | module.exports = node
|
21 |
|
22 | function 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 |
|
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()
|
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 |
|
101 | function 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 |
|
111 | function 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 |
|
121 | function 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 | }
|