Skip to content

Commit 9ed92de

Browse files
author
Shane Osbourne
committed
support startup runners
1 parent 1f62a9a commit 9ed92de

File tree

4 files changed

+144
-113
lines changed

4 files changed

+144
-113
lines changed

packages/browser-sync/lib/async-tasks.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
var async = require("./async");
33

44
module.exports = [
5+
{
6+
step: "Execute any startup runners",
7+
fn: async.execStartupRunners
8+
},
59
{
610
step: "Finding an empty port",
711
fn: async.getEmptyPort

packages/browser-sync/lib/async.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,31 @@ var utils = require("./utils");
99
var pluginUtils = require("./plugins");
1010
var connectUtils = require("./connect-utils");
1111
var chalk = require("chalk");
12+
const { toRunnerOption } = require("./types");
13+
const { List } = require("immutable");
14+
const { execRunner } = require("./runner");
15+
const Rx = require("rx");
1216

1317
module.exports = {
18+
execStartupRunners: function(bs, done) {
19+
const runners = bs.options.get("runners", List([])).toJS();
20+
21+
/** @type {import("./types").RunnerOption[]} */
22+
const startupOnlyRunners = runners.filter(r => {
23+
const opt = toRunnerOption(r);
24+
return opt?.at === "startup";
25+
});
26+
27+
if (startupOnlyRunners.length === 0) return done();
28+
29+
Rx.Observable.concat(startupOnlyRunners.map(runner => execRunner(runner)))
30+
.catch(e => {
31+
done(e);
32+
})
33+
.subscribe(() => {
34+
done(null);
35+
});
36+
},
1437
/**
1538
* BrowserSync needs at least 1 free port.
1639
* It will check the one provided in config
@@ -163,7 +186,7 @@ module.exports = {
163186
* @param {Function} done
164187
*/
165188
setInternalEvents: function(bs, done) {
166-
require("./internal-events")(bs);
189+
require("./internal-events").default(bs);
167190
done();
168191
},
169192
/**

packages/browser-sync/lib/internal-events.js

Lines changed: 3 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// @ts-check
22
"use strict";
33

4+
import { execRunner } from "./runner";
5+
46
var utils = require("./utils");
57
var fileUtils = require("./file-utils");
68
var Rx = require("rx");
@@ -15,7 +17,7 @@ const {
1517
toReloadEvent
1618
} = require("./types");
1719

18-
module.exports = function(bs) {
20+
export default function internalEvents(bs) {
1921
var events = {
2022
/**
2123
* File reloads
@@ -205,115 +207,4 @@ module.exports = function(bs) {
205207
reloader.dispose();
206208
runnerHandler.dispose();
207209
});
208-
};
209-
210-
/**
211-
* @param {import("./types").RunnerOption} runner
212-
*/
213-
function execRunner(runner) {
214-
return Rx.Observable.concat(
215-
runner.run.map(r => {
216-
if ("bs" in r) {
217-
return bsRunner(r);
218-
}
219-
if ("sh" in r) {
220-
let cmd;
221-
if (typeof r.sh === "string") {
222-
cmd = r.sh;
223-
} else if ("cmd" in r.sh) {
224-
cmd = r.sh.cmd;
225-
} else {
226-
return Rx.Observable.throw(new Error("invalid `sh` config"));
227-
}
228-
return shRunner(r, {
229-
cmd: cmd
230-
});
231-
}
232-
if ("npm" in r) {
233-
return npmRunner(r);
234-
}
235-
throw new Error("unreachable");
236-
})
237-
);
238-
}
239-
240-
/**
241-
* @param {import("./types").Runner} runner
242-
*/
243-
function bsRunner(runner) {
244-
if (!("bs" in runner)) throw new Error("unreachable");
245-
/** @type {import("./types").BsSideEffect[]} */
246-
const effects = [];
247-
if (runner.bs === "inject") {
248-
effects.push({
249-
type: "inject",
250-
files: runner.files.map(f => {
251-
return {
252-
path: f,
253-
event: "bs-runner"
254-
};
255-
})
256-
});
257-
} else if (runner.bs === "reload") {
258-
effects.push({
259-
type: "reload",
260-
files: []
261-
});
262-
}
263-
return Rx.Observable.concat(
264-
Rx.Observable.just(
265-
toRunnerNotification({
266-
status: "start",
267-
effects: [],
268-
runner
269-
})
270-
),
271-
Rx.Observable.just(
272-
toRunnerNotification({
273-
status: "end",
274-
effects: effects,
275-
runner
276-
})
277-
)
278-
);
279-
}
280-
281-
/**
282-
* @param {import("./types").Runner} runner
283-
* @param {object} params
284-
* @param {string} params.cmd
285-
*/
286-
function shRunner(runner, params) {
287-
return Rx.Observable.concat(
288-
Rx.Observable.just(toRunnerNotification({ status: "start", effects: [], runner })),
289-
Rx.Observable.just(toRunnerNotification({ status: "end", effects: [], runner }))
290-
);
291-
}
292-
293-
/**
294-
* @param {import("./types").Runner} runner
295-
*/
296-
function npmRunner(runner) {
297-
if (!("npm" in runner)) throw new Error("unreachble");
298-
return Rx.Observable.just(runner).flatMap(runner => {
299-
try {
300-
const runAll = require("npm-run-all");
301-
const runAllRunner = runAll(runner.npm, {
302-
parallel: false,
303-
stdout: process.stdout,
304-
stdin: process.stdin,
305-
stderr: process.stderr
306-
});
307-
const p = runAllRunner.then(results => {
308-
if (results.some(r => r.code !== 0)) throw new Error("failed");
309-
return results;
310-
});
311-
return Rx.Observable.fromPromise(p).map(results => {
312-
return toRunnerNotification({ status: "end", effects: [], runner });
313-
});
314-
} catch (e) {
315-
console.log("e", e);
316-
return Rx.Observable.throw(e);
317-
}
318-
});
319210
}

packages/browser-sync/lib/runner.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
const Rx = require("rx");
2+
import { toRunnerNotification } from "./types";
3+
4+
/**
5+
* @param {import("./types").RunnerOption} runner
6+
*/
7+
export function execRunner(runner) {
8+
return Rx.Observable.concat(
9+
runner.run.map(r => {
10+
if ("bs" in r) {
11+
return bsRunner(r);
12+
}
13+
if ("sh" in r) {
14+
let cmd;
15+
if (typeof r.sh === "string") {
16+
cmd = r.sh;
17+
} else if ("cmd" in r.sh) {
18+
cmd = r.sh.cmd;
19+
} else {
20+
return Rx.Observable.throw(new Error("invalid `sh` config"));
21+
}
22+
return shRunner(r, {
23+
cmd: cmd
24+
});
25+
}
26+
if ("npm" in r) {
27+
return npmRunner(r);
28+
}
29+
throw new Error("unreachable");
30+
})
31+
);
32+
}
33+
34+
/**
35+
* @param {import("./types").Runner} runner
36+
*/
37+
export function bsRunner(runner) {
38+
if (!("bs" in runner)) throw new Error("unreachable");
39+
/** @type {import("./types").BsSideEffect[]} */
40+
const effects = [];
41+
if (runner.bs === "inject") {
42+
effects.push({
43+
type: "inject",
44+
files: runner.files.map(f => {
45+
return {
46+
path: f,
47+
event: "bs-runner"
48+
};
49+
})
50+
});
51+
} else if (runner.bs === "reload") {
52+
effects.push({
53+
type: "reload",
54+
files: []
55+
});
56+
}
57+
return Rx.Observable.concat(
58+
Rx.Observable.just(
59+
toRunnerNotification({
60+
status: "start",
61+
effects: [],
62+
runner
63+
})
64+
),
65+
Rx.Observable.just(
66+
toRunnerNotification({
67+
status: "end",
68+
effects: effects,
69+
runner
70+
})
71+
)
72+
);
73+
}
74+
75+
/**
76+
* @param {import("./types").Runner} runner
77+
* @param {object} params
78+
* @param {string} params.cmd
79+
*/
80+
export function shRunner(runner, params) {
81+
return Rx.Observable.concat(
82+
Rx.Observable.just(toRunnerNotification({ status: "start", effects: [], runner })),
83+
Rx.Observable.just(toRunnerNotification({ status: "end", effects: [], runner }))
84+
);
85+
}
86+
87+
/**
88+
* @param {import("./types").Runner} runner
89+
*/
90+
export function npmRunner(runner) {
91+
if (!("npm" in runner)) throw new Error("unreachble");
92+
return Rx.Observable.just(runner).flatMap(runner => {
93+
try {
94+
const runAll = require("npm-run-all");
95+
const runAllRunner = runAll(runner.npm, {
96+
parallel: false,
97+
stdout: process.stdout,
98+
stdin: process.stdin,
99+
stderr: process.stderr
100+
});
101+
const p = runAllRunner.then(results => {
102+
if (results.some(r => r.code !== 0)) throw new Error("failed");
103+
return results;
104+
});
105+
return Rx.Observable.fromPromise(p).map(results => {
106+
return toRunnerNotification({ status: "end", effects: [], runner });
107+
});
108+
} catch (e) {
109+
console.log("e", e);
110+
return Rx.Observable.throw(e);
111+
}
112+
});
113+
}

0 commit comments

Comments
 (0)