@oeyoews/tiddlywiki-plugin-dev
Version:
[](https://github.com/tiddly-gittly)
141 lines (138 loc) • 4.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.runDev = void 0;
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _tiddlywiki = _interopRequireDefault(require("tiddlywiki"));
var _chokidar = _interopRequireDefault(require("chokidar"));
var _getPortPlease = require("get-port-please");
var _ws = require("ws");
var _packup = require("./packup");
var _utils = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// WebSocket with TiddlyWiki on broswer
const runServer = async () => {
const port = await (0, _getPortPlease.getPort)({
port: 8081
});
const server = new _ws.WebSocketServer({
port
});
const refreshHeartBeat = ws => {
ws.isAlive = true;
if (ws.heartBeatInterval) {
clearInterval(ws.heartBeatInterval);
}
// eslint-disable-next-line consistent-return
ws.heartBeatInterval = setInterval(() => {
if (ws.isAlive === false) {
clearInterval(ws.heartBeatInterval);
delete ws.heartBeatInterval;
return ws.terminate();
}
ws.isAlive = false;
ws.ping();
}, 5000);
};
server.on('connection', ws => {
refreshHeartBeat(ws);
ws.ping();
ws.on('pong', () => refreshHeartBeat(ws));
ws.on('close', () => {
if (ws.heartBeatInterval) {
clearInterval(ws.heartBeatInterval);
}
});
});
server.on('close', () => {
server.clients.forEach(ws => {
if (ws.heartBeatInterval) {
clearInterval(ws.heartBeatInterval);
}
ws.send('bye');
});
});
return {
server,
port
};
};
// Run refresh server
const runDev = async (wiki, src, excludeFilter) => {
const {
server,
port
} = await runServer();
const devWebListnerScript = _fs.default.readFileSync(_path.default.resolve(__dirname, 'src/devweb-listener.js'), 'utf-8').replace('$$$$port$$$$', `${port}`);
// Watch source files change
const $tw1 = (0, _utils.tiddlywiki)([], wiki);
let twServer;
const watcher = _chokidar.default.watch(src, {
ignoreInitial: true,
followSymlinks: true,
ignored: $tw1.boot.excludeRegExp,
awaitWriteFinish: {
stabilityThreshold: 1000,
pollInterval: 100
}
});
let updateFiles;
const refresh = async path => {
// 因为 build 是异步的,这里给 refresh 加一个资源锁,否则会出现奇怪的问题
if (updateFiles !== undefined) {
updateFiles.push(path);
return;
} else {
updateFiles = [path];
}
while ((_updateFiles = updateFiles) !== null && _updateFiles !== void 0 && _updateFiles.length) {
var _updateFiles;
let resolve;
const wait = new Promise(_resolve => resolve = _resolve);
const tmp = updateFiles;
updateFiles = [];
$tw1.wiki.deleteTiddler('$:/Modern.TiddlyDev/devWebsocket/listener');
const plugins = await (0, _packup.rebuild)($tw1, src, tmp, true, excludeFilter);
const $tw = _tiddlywiki.default.TiddlyWiki();
$tw.preloadTiddler({
title: '$:/Modern.TiddlyDev/devWebsocket/listener',
text: devWebListnerScript,
type: 'application/javascript',
'module-type': 'startup'
});
$tw.preloadTiddlerArray(plugins);
$tw.hooks.addHook('th-server-command-post-start',
// eslint-disable-next-line @typescript-eslint/no-loop-func
(_listenCommand, newTwServer) => {
newTwServer.on('listening', () => resolve());
twServer = newTwServer;
});
const serve = async () => {
const port = await (0, _getPortPlease.getPort)({
port: 8080
});
$tw.boot.argv = [wiki, '--listen', `port=${port}`];
$tw.boot.boot();
};
if (twServer) {
twServer.on('close', serve);
twServer.close();
} else {
serve();
}
await wait;
}
server.clients.forEach(ws => {
if (ws.readyState === _ws.WebSocket.OPEN) {
ws.send('refresh');
}
});
updateFiles = undefined;
};
watcher.on('ready', refresh);
watcher.on('add', refresh);
watcher.on('change', refresh);
};
exports.runDev = runDev;