This repository has been archived by the owner on Jan 24, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(docz-core): split data server into actions
- Loading branch information
1 parent
8fbd173
commit 69d6c9a
Showing
6 changed files
with
135 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,117 +1,40 @@ | ||
import { load, finds } from 'load-cfg' | ||
import chokidar from 'chokidar' | ||
import WS from 'ws' | ||
|
||
import { Config } from './commands/args' | ||
import { Entries, EntryMap } from './Entries' | ||
export type Send = (type: string, payload: any) => void | ||
|
||
const isSocketOpened = (socket: WS) => socket.readyState === WS.OPEN | ||
const send = (socket: WS) => (type: string, payload: any) => { | ||
socket.send(JSON.stringify({ type, payload })) | ||
} | ||
|
||
export interface DataServerOpts { | ||
server: any | ||
config: Config | ||
interface Action { | ||
onStart: (send: Send, socket: WS) => void | ||
onClose?: () => void | ||
onError?: () => void | ||
} | ||
|
||
export class DataServer { | ||
private server: WS.Server | ||
private config: Config | ||
|
||
constructor({ server, config }: DataServerOpts) { | ||
this.config = config | ||
this.server = new WS.Server({ | ||
server, | ||
port: config.websocketPort, | ||
host: config.websocketHost, | ||
}) | ||
} | ||
|
||
public async processEntries(entries: Entries): Promise<void> { | ||
const watcher = chokidar.watch(this.config.files, { | ||
ignored: /(^|[\/\\])\../, | ||
}) | ||
|
||
const handleConnection = async (socket: WS) => { | ||
const update = this.updateEntries(entries, socket) | ||
const map = await entries.get() | ||
|
||
watcher.on('change', async () => update(this.config)) | ||
watcher.on('unlink', async () => update(this.config)) | ||
watcher.on('raw', async (event: string, path: string, details: any) => { | ||
if (details.event === 'moved' && details.type === 'directory') { | ||
await update(this.config) | ||
} | ||
}) | ||
|
||
socket.send(this.entriesData(map)) | ||
await Entries.writeImports(map) | ||
} | ||
|
||
this.server.on('connection', handleConnection) | ||
this.server.on('close', () => watcher.close()) | ||
} | ||
private actions: Set<Action> | ||
|
||
public async processThemeConfig(): Promise<void> { | ||
const watcher = chokidar.watch(finds('docz')) | ||
|
||
const handleConnection = async (socket: WS) => { | ||
const update = this.updateConfig(socket) | ||
|
||
watcher.on('add', () => update()) | ||
watcher.on('change', () => update()) | ||
watcher.on('unlink', () => update()) | ||
|
||
update() | ||
} | ||
|
||
this.server.on('connection', handleConnection) | ||
this.server.on('close', () => watcher.close()) | ||
constructor(server: any, port: number, host: string) { | ||
this.actions = new Set() | ||
this.server = new WS.Server({ server, port, host }) | ||
} | ||
|
||
private dataObj(type: string, data: any): string { | ||
return JSON.stringify({ type, data }) | ||
public dispatch(action: Action): void { | ||
this.actions.add(action) | ||
} | ||
|
||
private entriesData(entries: EntryMap): string { | ||
return this.dataObj('docz.entries', entries) | ||
public init(): void { | ||
this.server.on('connection', socket => this.handleConnection(socket)) | ||
this.server.on('close', () => this.handleClose()) | ||
} | ||
|
||
private configData(config: Config): string { | ||
return this.dataObj('docz.config', { | ||
...config.themeConfig, | ||
title: config.title, | ||
description: config.description, | ||
ordering: config.ordering, | ||
}) | ||
private async handleConnection(socket: WS): Promise<void> { | ||
this.actions.forEach(async ({ onStart }) => onStart(send(socket), socket)) | ||
} | ||
|
||
private updateEntries( | ||
entries: Entries, | ||
socket: WS | ||
): (config: Config) => Promise<void> { | ||
return async config => { | ||
if (isSocketOpened(socket)) { | ||
const map = await entries.get() | ||
|
||
await Entries.writeImports(map) | ||
socket.send(this.entriesData(map)) | ||
} | ||
} | ||
} | ||
|
||
private updateConfig(socket: WS): () => void { | ||
const initialConfig = { | ||
title: this.config.title, | ||
description: this.config.description, | ||
themeConfig: this.config.themeConfig, | ||
ordering: this.config.ordering, | ||
} | ||
|
||
return () => { | ||
const config = load('docz', initialConfig, true) | ||
|
||
if (isSocketOpened(socket)) { | ||
socket.send(this.configData(config)) | ||
} | ||
} | ||
private async handleClose(): Promise<void> { | ||
this.actions.forEach(async ({ onClose }) => onClose && onClose()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { parseEntries } from './parse-entries' | ||
export { parseConfig } from './parse-config' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { load, finds } from 'load-cfg' | ||
import chokidar from 'chokidar' | ||
import WS from 'ws' | ||
|
||
import { Send } from '../DataServer' | ||
import { Config, ThemeConfig } from '../commands/args' | ||
|
||
const PARSE_CONFIG = 'PARSE_CONFIG' | ||
|
||
const isSocketOpened = (socket: WS) => socket.readyState === WS.OPEN | ||
|
||
interface Payload { | ||
title: string | ||
description: string | ||
ordering: string | ||
themeConfig: ThemeConfig | ||
} | ||
|
||
const getInitialConfig = (config: Config): Payload => ({ | ||
title: config.title, | ||
description: config.description, | ||
themeConfig: config.themeConfig, | ||
ordering: config.ordering, | ||
}) | ||
|
||
const updateConfig = (initial: Payload, send: Send, socket: WS) => () => { | ||
const config = load('docz', initial, true) | ||
if (isSocketOpened(socket)) send(PARSE_CONFIG, config) | ||
} | ||
|
||
export const parseConfig = (config: Config) => { | ||
const watcher = chokidar.watch(finds('docz')) | ||
|
||
return { | ||
onClose: () => watcher.close(), | ||
onStart: async (send: Send, socket: WS) => { | ||
const initialConfig = getInitialConfig(config) | ||
const update = updateConfig(initialConfig, send, socket) | ||
|
||
watcher.on('add', () => update()) | ||
watcher.on('change', () => update()) | ||
watcher.on('unlink', () => update()) | ||
|
||
update() | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import chokidar from 'chokidar' | ||
import WS from 'ws' | ||
|
||
import { Send } from '../DataServer' | ||
import { Entries } from '../Entries' | ||
import { Config } from '../commands/args' | ||
|
||
const LOADING = 'LOADING' | ||
const PARSE_ENTRIES = 'PARSE_ENTRIES' | ||
|
||
const isSocketOpened = (socket: WS) => socket.readyState === WS.OPEN | ||
|
||
const updateEntries = ( | ||
entries: Entries, | ||
send: Send, | ||
socket: WS | ||
) => async () => { | ||
if (isSocketOpened(socket)) { | ||
const map = await entries.get() | ||
|
||
await Entries.writeImports(map) | ||
send(PARSE_ENTRIES, map) | ||
} | ||
} | ||
|
||
export const parseEntries = (entries: Entries, config: Config) => { | ||
const watcher = chokidar.watch(config.files, { | ||
ignored: /(^|[\/\\])\../, | ||
}) | ||
|
||
return { | ||
onClose: () => watcher.close(), | ||
onStart: async (send: Send, socket: WS) => { | ||
send(LOADING, true) | ||
|
||
const update = updateEntries(entries, send, socket) | ||
|
||
watcher.on('change', async () => update()) | ||
watcher.on('unlink', async () => update()) | ||
watcher.on('raw', async (event: string, path: string, details: any) => { | ||
if (details.event === 'moved' && details.type === 'directory') { | ||
await update() | ||
} | ||
}) | ||
|
||
update() | ||
send(LOADING, false) | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters