Skip to content

Commit 1bd3fac

Browse files
Fix/watchmode (#259)
* remove old config * scully(watch-mode): add more files * scully(watchMode): merge with master and fix double build * add files to test * fix(perfomrance metrics): reset metrics on rebuild * fix(remove stray folder): fox * more test * add more test * fix(watch): add fix for route import * feat(watch-mode): add the watchmode with the new config * fix * fix * feat(cahche geuss): cach the angular routes Co-authored-by: Sander Elias <SanderElias@users.noreply.github.com>
1 parent b4d619c commit 1bd3fac

8 files changed

Lines changed: 145 additions & 70 deletions

File tree

blog/page-1.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ publish date: 2019-11-26
55
slug: look at_my-urls Cool
66
slugs:
77
- 'page-1'
8+
- 'a slug'
89
description: This is the first demo page in this sample.
910
---
1011

@@ -14,6 +15,7 @@ description: This is the first demo page in this sample.
1415

1516
```typescript
1617
console.log('hello world');
18+
console.log('yah');
1719
```
1820

1921
Related information [page-2](/blog/page-2)

scully/scully.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {join} from 'path';
88
import * as yargs from 'yargs';
99
import './pluginManagement/systemPlugins';
1010
import {startBackgroundServer} from './startBackgroundServer';
11-
import {loadConfig} from './utils/config';
11+
import {loadConfig, scullyConfig} from './utils/config';
1212
import {moveDistAngular} from './utils/fsAngular';
1313
import {httpGetJson} from './utils/httpGetJson';
1414
import {isPortTaken} from './utils/isPortTaken';
@@ -20,16 +20,18 @@ import {bootServe, isBuildThere, watchMode} from './watchMode';
2020
/** the default of 10 is too shallow for generating pages. */
2121
require('events').defaultMaxListeners = 100;
2222

23-
let port;
24-
// tslint:disable-next-line:variable-name
25-
export let _options = {};
26-
2723
const {argv: options} = yargs.option('port', {
2824
alias: 'p',
2925
type: 'number',
3026
description: 'The port to run on',
3127
});
3228

29+
const {watch} = yargs
30+
.boolean('wm')
31+
.default('wm', false)
32+
.alias('wm', 'watch')
33+
.describe('wm', 'Use this flag for use the watch mode into scully').argv;
34+
3335
const {removeStaticDist} = yargs
3436
.boolean('RSD')
3537
.default('RSD', false)
@@ -74,14 +76,14 @@ if (process.argv.includes('version')) {
7476
logError('Could not connect to server');
7577
process.exit(15);
7678
}
77-
78-
console.log('servers available');
79-
await startScully();
80-
81-
if (process.argv.includes('watch')) {
82-
_options = options;
83-
watchMode();
79+
if (watch) {
80+
watchMode(
81+
join(scullyConfig.homeFolder, scullyConfig.distFolder) ||
82+
join(scullyConfig.homeFolder, './dist/browser')
83+
);
8484
} else {
85+
console.log('servers available');
86+
await startScully();
8587
if (!isTaken) {
8688
// kill serve ports
8789
await httpGetJson(`http://${scullyConfig.hostName}:${scullyConfig.appPort}/killMe`, {

scully/utils/defaultAction.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,33 @@ import {storeRoutes} from '../systemPlugins/storeRoutes';
99
import {writeToFs} from '../systemPlugins/writeToFs.plugin';
1010
import {asyncPool} from './asyncPool';
1111
import {chunk} from './chunk';
12-
import {loadConfig, updateScullyConfig} from './config';
13-
import {ScullyConfig} from './interfacesandenums';
12+
import {loadConfig} from './config';
1413
import {log, logWarn} from './log';
1514
import {performanceIds} from './performanceIds';
1615

17-
const {baseFilter} = yargs
16+
export const {baseFilter} = yargs
1817
.string('bf')
1918
.alias('bf', 'baseFilter')
2019
.default('bf', '')
2120
.describe('bf', 'provide a minimatch glob for the unhandled routes').argv;
2221

22+
const cache = new Set<string>();
23+
2324
console.log(baseFilter);
24-
export const generateAll = async (config?: Partial<ScullyConfig>, localBaseFilter = baseFilter) => {
25-
if (config) {
26-
await updateScullyConfig(config);
27-
}
25+
export const generateAll = async (localBaseFilter = baseFilter) => {
2826
await loadConfig;
2927
try {
30-
log('Finding all routes in application.');
31-
performance.mark('startTraverse');
32-
const unhandledRoutes = await traverseAppRoutes();
33-
performance.mark('stopTraverse');
34-
performanceIds.add('Traverse');
28+
let unhandledRoutes;
29+
if (cache.size == 0) {
30+
log('Finding all routes in application.');
31+
performance.mark('startTraverse');
32+
unhandledRoutes = await traverseAppRoutes();
33+
performance.mark('stopTraverse');
34+
performanceIds.add('Traverse');
35+
unhandledRoutes.forEach(r => cache.add(r));
36+
} else {
37+
unhandledRoutes = [...cache.keys()];
38+
}
3539

3640
if (unhandledRoutes.length < 1) {
3741
logWarn('No routes found in application, are you sure you installed the router? Terminating.');

scully/utils/fsAngular.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {restartStaticServer, startScullyWatchMode} from '../watchMode';
77
import {scullyConfig} from './config';
88
import {createFolderFor} from './createFolderFor';
99
import {green, log, logWarn} from './log';
10+
import {baseFilter} from './defaultAction';
1011

1112
export async function checkChangeAngular(
1213
folder = join(scullyConfig.homeFolder, scullyConfig.distFolder) ||
@@ -27,7 +28,7 @@ function reWatch(folder, reset = true, watch = false) {
2728
// TODO test on mac, figure out what's coming in.
2829
// only act upon changes of the actual folder I'm interested in.
2930
filter(r => r.fileName.includes(filename)),
30-
// tap(r => log(`debug only: filename:"${yellow(filename)}" changedName:"${yellow(r.fileName)}"`)),
31+
filter(r => !r.fileName.includes('scully-routes.json')),
3132
/** give the CLI some time to finnish */
3233
debounceTime(1000),
3334
// tap(console.log),
@@ -70,7 +71,7 @@ export async function moveDistAngular(src, dest, {reset = true, removeStaticDist
7071
if (reset) {
7172
restartStaticServer();
7273
} else if (watch) {
73-
startScullyWatchMode();
74+
startScullyWatchMode(baseFilter);
7475
}
7576
} catch (e) {
7677
/**

scully/utils/fsFolder.ts

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {log, red} from './log';
66
import {watch} from 'chokidar';
77
import {scullyConfig} from './config';
88
import {startScullyWatchMode} from '../watchMode';
9+
import * as fs from 'fs';
910

1011
// tslint:disable-next-line:no-shadowed-variable
1112
export async function checkStaticFolder() {
@@ -15,15 +16,19 @@ export async function checkStaticFolder() {
1516
// tslint:disable-next-line:forin
1617
for (const property in config) {
1718
if (config[property].type === 'contentFolder') {
18-
// @ts-ignore
19-
const fileName = config[property].slug.folder.replace('./', '');
20-
console.log(fileName);
21-
if (!folder.find(f => f === fileName)) {
22-
folder.push(fileName);
23-
if (existFolder(fileName)) {
24-
reWatch(fileName);
25-
} else {
26-
log(`${red(`${fileName} folder not found`)}.`);
19+
// tslint:disable-next-line:forin
20+
for (const slug in config[property]) {
21+
if (config[property][slug].folder !== undefined) {
22+
// @ts-ignore
23+
const fileName = config[property].slug.folder.replace('./', '');
24+
if (!folder.find(f => f === fileName)) {
25+
folder.push(fileName);
26+
if (existFolder(fileName)) {
27+
reWatch(fileName, property);
28+
} else {
29+
log(`${red(`${fileName} folder not found`)}.`);
30+
}
31+
}
2732
}
2833
}
2934
}
@@ -33,33 +38,29 @@ export async function checkStaticFolder() {
3338
}
3439
}
3540

36-
function reWatch(folder) {
41+
function reWatch(folder, url) {
3742
const filename = join(folder);
3843
watchFolder(filename)
39-
.pipe(
40-
// TODO test on mac, figure out what's coming in.
41-
// only act upon changes of the actual folder I'm interested in.
42-
filter(r => r.fileName.startsWith(folder)),
43-
throttleTime(3000)
44-
)
44+
.pipe(throttleTime(10000))
4545
.subscribe({
4646
next: v => {
47-
if (v.eventType !== 'addDir') {
48-
console.log('--------------------------------------------------');
49-
console.log(`New ${v.eventType} in ${v.fileName}, re run scully.`);
50-
console.log('--------------------------------------------------');
51-
startScullyWatchMode();
52-
}
47+
console.log('--------------------------------------------------');
48+
console.log(`New ${v.eventType} in ${v.fileName}, re run scully.`);
49+
console.log('--------------------------------------------------');
50+
startScullyWatchMode(url);
5351
},
5452
});
5553
}
5654

5755
function watchFolder(folder): Observable<{eventType: string; fileName: string}> {
56+
console.log('--------------------------------------------------');
57+
console.log(`Watching ${folder} for change.`);
58+
console.log('--------------------------------------------------');
5859
return new Observable(obs => {
5960
let watcher;
6061
try {
61-
watcher = watch(folder).on('all', (eventType, fileName) => {
62-
obs.next({eventType, fileName});
62+
watcher = fs.watch(folder, (event, fname) => {
63+
obs.next({eventType: event, fileName: fname});
6364
});
6465
} catch (e) {
6566
obs.error(e);

scully/utils/nodeFsFolder.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* NodeFsFolder
3+
* read directorys and files
4+
* reactive 100%
5+
* */
6+
import {existsSync} from 'fs';
7+
import {join} from 'path';
8+
import {log, red} from './log';
9+
import {BehaviorSubject, Observable} from 'rxjs';
10+
import * as fs from 'fs';
11+
import {throttleTime} from 'rxjs/operators';
12+
13+
// tslint:disable-next-line:no-shadowed-variable
14+
function readPath(folder: string) {
15+
// tslint:disable-next-line:variable-name
16+
const _path: string = join(__dirname, folder);
17+
if (existFolder(_path)) {
18+
return true;
19+
} else {
20+
log(`${red(`${folder} folder not found, directory ${_path}`)}.`);
21+
return false;
22+
}
23+
}
24+
25+
function existFolder(src) {
26+
try {
27+
return existsSync(src);
28+
} catch (e) {
29+
return false;
30+
}
31+
}
32+
33+
function watchFolder(folder): Observable<{eventType: string; fileName: string}> {
34+
return new Observable(obs => {
35+
let watcher;
36+
try {
37+
watcher = fs.watch(folder, (event, fname) => {
38+
console.log('--------------------------------------------------');
39+
console.log(`New ${event} in ${fname}, re run scully.`);
40+
console.log('--------------------------------------------------');
41+
obs.next({eventType: event, fileName: fname});
42+
});
43+
} catch (e) {
44+
obs.error(e);
45+
}
46+
return () => watcher.close();
47+
});
48+
}
49+
50+
export function startWatch(folder: string) {
51+
console.log('start process', folder);
52+
if (readPath(folder)) {
53+
const fxwatch = this.watchFolder(folder);
54+
fxwatch.pipe(throttleTime(3000)).subscribe(x => {
55+
console.log(x);
56+
});
57+
}
58+
}

scully/utils/startup.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
1-
import {generateAll} from './defaultAction';
2-
import {ScullyConfig} from './interfacesandenums';
31
import {performance, PerformanceObserver, PerformanceObserverCallback} from 'perf_hooks';
2+
import {generateAll} from './defaultAction';
43
import {log, yellow} from './log';
54
import {performanceIds} from './performanceIds';
65

76
/**
87
* Starts the entire process
98
* @param config:ScullyConfig
109
*/
11-
export const startScully = (config?: Partial<ScullyConfig>) => {
12-
let routeCount = 0;
10+
export const startScully = (url?: string) => {
1311
return new Promise(resolve => {
1412
performance.mark('startDuration');
1513
performanceIds.add('Duration');
1614
let innerResolve;
1715
const durationProm = new Promise(r => (innerResolve = r));
1816
const obs = new PerformanceObserver(measurePerformance(innerResolve));
1917
obs.observe({entryTypes: ['measure'], buffered: true});
20-
const numberOfRoutesProm = generateAll(config).then(routes => {
21-
performance.mark('stopDuration');
22-
/** measure all performance checks */
23-
[...performanceIds.values()].forEach(id => performance.measure(id, `start${id}`, `stop${id}`));
24-
return routes.length;
25-
});
18+
const numberOfRoutesProm = generateAll(url)
19+
.then(routes => {
20+
performance.mark('stopDuration');
21+
/** measure all performance checks */
22+
try {
23+
[...performanceIds.values()].forEach(id => performance.measure(id, `start${id}`, `stop${id}`));
24+
} catch (e) {
25+
console.error(e);
26+
}
27+
return routes.length;
28+
})
29+
.catch(() => 0);
2630
Promise.all([numberOfRoutesProm, durationProm]).then(([numberOfRoutes, durations]) =>
2731
resolve({numberOfRoutes, durations})
2832
);
@@ -53,6 +57,7 @@ function measurePerformance(resolve: (value?: unknown) => void): PerformanceObse
5357
// console.log(durations);
5458
performance.clearMarks();
5559
observer.disconnect();
60+
performanceIds.clear();
5661
resolve(durations);
5762
};
5863
}

scully/watchMode.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {existsSync} from 'fs-extra';
22
import {join} from 'path';
33
import * as yargs from 'yargs';
4-
import {ScullyConfig, startScully} from '.';
4+
import {scullyConfig, ScullyConfig, startScully} from '.';
55
import {checkChangeAngular} from './utils/fsAngular';
66
import {checkStaticFolder} from './utils/fsFolder';
77
import {httpGetJson} from './utils/httpGetJson';
@@ -35,12 +35,13 @@ export async function bootServe(scullyConfig: ScullyConfig) {
3535
}
3636

3737
// TODO : we need rewrite this to observables for don't have memory leaks
38-
export async function watchMode() {
38+
// tslint:disable-next-line:variable-name
39+
export async function watchMode(path: string) {
3940
await checkStaticFolder();
4041
// g for generate and the q for quit
4142
checkForManualRestart();
4243
// @ts-ignore
43-
await checkChangeAngular(_options.path, false, true);
44+
await checkChangeAngular(path, false, true);
4445
}
4546

4647
export function checkForManualRestart() {
@@ -49,21 +50,22 @@ export function checkForManualRestart() {
4950
output: process.stdout,
5051
});
5152

52-
readline.question(`Press g for manual regenerate, or q for close the server. \n`, command => {
53+
readline.question(`Press g for manual regenerate, or q for close the server.\n`, command => {
5354
if (command.toLowerCase() === 'g') {
54-
startScully().then(() => checkForManualRestart());
55+
startScully().then(() => {
56+
readline.close();
57+
checkForManualRestart();
58+
});
5559
} else if (command.toLowerCase() === 'q') {
56-
readline.close();
5760
process.exit(0);
5861
} else {
59-
readline.close();
60-
checkForManualRestart();
62+
console.log(`Press g for manual regenerate, or q for close the server.`);
6163
}
6264
});
6365
}
6466

65-
export function startScullyWatchMode() {
66-
startScully();
67+
export function startScullyWatchMode(url: string) {
68+
startScully(url);
6769
}
6870

6971
function startStaticServer() {

0 commit comments

Comments
 (0)