Skip to content

Commit 94a3930

Browse files
feat(overmind-devtools): add and remove ports
1 parent d3564aa commit 94a3930

File tree

20 files changed

+220
-174
lines changed

20 files changed

+220
-174
lines changed

packages/demos/todomvc/src/app/state.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { derived, computed } from 'overmind'
1+
import { derive, compute } from 'overmind'
22

33
export type Todo = {
44
id: string
@@ -15,9 +15,9 @@ export type State = {
1515

1616
const state: State = {
1717
todos: [],
18-
count: derived((state: State) => state.todos.length),
18+
count: derive((state: State) => state.todos.length),
1919
newTodoTitle: '',
20-
testCount: computed((foo: number) => (state: State) => state.count + foo),
20+
testCount: compute((foo: number) => (state: State) => state.count + foo),
2121
}
2222

2323
export default state

packages/node_modules/overmind-devtools/backend/ConnectionManager.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@ class ConnectionManager {
1010
this.onRemovePort = this.onRemovePort.bind(this)
1111
}
1212
addClient(port, client) {
13+
const onConnection = this.onConnection.bind(this, port)
14+
const onError = this.onError.bind(this, port)
15+
1316
this.clients[port] = {
1417
wss: client,
18+
dispose() {
19+
client.removeListener('connection', onConnection)
20+
client.removeListener('error', onError)
21+
client.close()
22+
},
1523
}
1624

17-
this.clients[port].wss.on('connection', this.onConnection.bind(this, port))
18-
this.clients[port].wss.on('error', this.onError.bind(this, port))
25+
this.clients[port].wss.on('connection', onConnection)
26+
this.clients[port].wss.on('error', onError)
1927
this.mainWindow.webContents.send('port:added', port)
2028
}
2129
onError(port) {
@@ -48,7 +56,7 @@ class ConnectionManager {
4856
this.addClient(port, new WebSocketServer({ port: Number(port) }))
4957
}
5058
onRemovePort(_, port) {
51-
this.clients[port].wss.close()
59+
this.clients[port].dispose()
5260

5361
delete this.clients[port]
5462
}

packages/node_modules/overmind-devtools/src/BackendConnector.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,18 @@ class Port {
5959

6060
this.messageCallback(message)
6161
}
62+
destroy() {
63+
ipcRenderer.removeListener('port:added', this.onPortAdded)
64+
ipcRenderer.removeListener('port:exists', this.onPortExists)
65+
ipcRenderer.removeListener('message', this.onMessage)
66+
}
6267
}
6368

6469
class BackendConnector {
6570
addedPorts: Port[] = []
71+
getPort(port: string) {
72+
return this.addedPorts.find((portInstance) => portInstance.port === port)
73+
}
6674
sendMessage(port: string, eventName: string, payload: object = null) {
6775
ipcRenderer.send('message', {
6876
port,
@@ -71,18 +79,20 @@ class BackendConnector {
7179
})
7280
}
7381
addPort(port: string, messageCallback: MessageCallback) {
74-
if (
75-
this.addedPorts.filter((portInstance) => portInstance.equals(port)).length
76-
) {
77-
throw new Error('This port already exists')
82+
if (this.addedPorts.find((portInstance) => portInstance.port === port)) {
83+
return
7884
}
85+
7986
const portInstance = new Port(this, port, messageCallback)
8087

8188
portInstance.connect()
8289
this.addedPorts.push(portInstance)
8390
}
84-
removePort(port: string) {
85-
ipcRenderer.send('port:remove', port)
91+
removePort(portToRemove: string) {
92+
const port = this.getPort(portToRemove)
93+
port.destroy()
94+
this.addedPorts.splice(this.addedPorts.indexOf(port), 1)
95+
ipcRenderer.send('port:remove', portToRemove)
8696
}
8797
relaunch() {
8898
ipcRenderer.send('relaunch')

packages/node_modules/overmind-devtools/src/app/actions.ts

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,54 +8,58 @@ export default (action: Action) => {
88
.mutation(mutations.performMutationsByMessageType)
99
.mutation(mutations.addMessagesFromClient)
1010

11-
const loadDevtools = action()
12-
// .do(({ storage }) => storage.clear())
13-
// Do a check if the current app matches the keys of the ???
14-
.map(helpers.getAppsFromStorage)
15-
.mutation(mutations.setApps)
16-
.map(helpers.getCurrentPortFromStorage)
17-
.mutation(mutations.setCurrentPort)
18-
.mutation(mutations.setAppLoaded)
19-
.map(helpers.connectCurrentPort(onMessage))
11+
return {
12+
loadDevtools: action()
13+
// .do(({ storage }) => storage.clear())
14+
// Do a check if the current app matches the keys of the ???
15+
.map(helpers.getAppsFromStorage)
16+
.mutation(mutations.setApps)
17+
.map(helpers.getCurrentPortFromStorage)
18+
.mutation(mutations.setCurrentPort)
19+
.mutation(mutations.setAppLoaded)
20+
.do(helpers.connectCurrentPort(onMessage)),
2021

21-
const setError = action<string>().mutation(mutations.setError)
22+
setError: action<string>().mutation(mutations.setError),
2223

23-
const changeNewPortValue = action<string>()
24-
.map(helpers.toNumber)
25-
.mutation(mutations.setNewPortValue)
24+
changeNewPortValue: action<string>()
25+
.map(helpers.toNumber)
26+
.mutation(mutations.setNewPortValue),
2627

27-
const addPort = action()
28-
.map(helpers.getNewPortFromState)
29-
.mutation(mutations.setCurrentPort)
30-
.mutation(mutations.addNewApp)
31-
.mutation(mutations.resetNewPortValue)
32-
.do(helpers.storeApps)
28+
addPort: action()
29+
.map(helpers.getNewPortFromState)
30+
.mutation(mutations.setCurrentPort)
31+
.mutation(mutations.addNewApp)
32+
.mutation(mutations.resetNewPortValue)
33+
.do(helpers.storeApps)
34+
.do(helpers.connectCurrentPort(onMessage)),
3335

34-
const changeTab = action<Tab>().mutation(mutations.changeTab)
36+
changeTab: action<Tab>().mutation(mutations.changeTab),
3537

36-
const openApp = action<string>()
38+
toggleExpandState: action<string[]>().mutation(
39+
mutations.toggleExpandStatePath
40+
),
3741

38-
const toggleExpandState = action<string[]>().mutation(
39-
mutations.toggleExpandStatePath
40-
)
42+
selectAction: action<string>()
43+
.mutation(mutations.toggleActionItemCollapse)
44+
.mutation(mutations.selectAction),
4145

42-
const selectAction = action<string>()
43-
.mutation(mutations.toggleActionItemCollapse)
44-
.mutation(mutations.selectAction)
46+
toggleCollapsed: action<{ isCollapsed: boolean }>().mutation(
47+
mutations.toggleCollapsed
48+
),
4549

46-
const toggleCollapsed = action<{ isCollapsed: boolean }>().mutation(
47-
mutations.toggleCollapsed
48-
)
50+
configurePort: action().mutation(mutations.configurePort),
4951

50-
return {
51-
loadDevtools,
52-
setError,
53-
changeNewPortValue,
54-
addPort,
55-
changeTab,
56-
openApp,
57-
toggleExpandState,
58-
selectAction,
59-
toggleCollapsed,
52+
cancelConfigurePort: action().mutation(mutations.cancelConfigurePort),
53+
54+
removeApp: action()
55+
.filter(helpers.confirm('Are you sure you want to remove the app?'))
56+
.do(helpers.removeCurrentPort)
57+
.mutation(mutations.removeApp)
58+
.do(helpers.storeApps)
59+
.do(helpers.connectCurrentPort(onMessage)),
60+
61+
selectPort: action<string>()
62+
.mutation(mutations.selectPort)
63+
.do(helpers.connectCurrentPort(onMessage)),
6064
}
6165
}
Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
import { derived } from 'overmind'
21
import { State, Component } from './state'
32

4-
export const currentApp = derived(
5-
(state: State) => state.apps[state.currentPort]
6-
)
3+
export const currentApp = (state: State) => state.apps[state.currentPort]
74

8-
export const componentsMounted = derived((state: State) =>
5+
export const componentsMounted = (state: State) =>
96
Object.keys(state.currentApp.components).reduce(
107
(aggr, key) => {
118
if (state.currentApp.components[key].isMounted) {
@@ -16,47 +13,39 @@ export const componentsMounted = derived((state: State) =>
1613
},
1714
[] as Component[]
1815
)
19-
)
2016

21-
export const componentsUpdateCount = derived((state: State) =>
17+
export const componentsUpdateCount = (state: State) =>
2218
state.componentsMounted.reduce(
2319
(aggr, component) => aggr + component.updateCount,
2420
0
2521
)
26-
)
2722

28-
export const componentsStatePathCount = derived((state: State) =>
23+
export const componentsStatePathCount = (state: State) =>
2924
state.componentsMounted.reduce(
3025
(aggr, component) => aggr + component.paths.length,
3126
0
3227
)
33-
)
3428

35-
export const flushes = derived((state: State) =>
29+
export const flushes = (state: State) =>
3630
Object.keys(state.currentApp.flushes)
3731
.sort(
3832
(idA, idB) =>
3933
state.currentApp.flushes[idB].flushId -
4034
state.currentApp.flushes[idA].flushId
4135
)
4236
.map((id) => state.currentApp.flushes[id])
43-
)
4437

45-
export const flushesMutationsCount = derived((state: State) =>
38+
export const flushesMutationsCount = (state: State) =>
4639
state.flushes.reduce((aggr, flush) => aggr + flush.mutations.length, 0)
47-
)
48-
49-
export const flushesStatePathCount = derived(
50-
(state: State) =>
51-
state.flushes.reduce((aggr, flush) => {
52-
return flush.mutations.reduce(
53-
(aggr, mutation) =>
54-
aggr.includes(mutation.path) ? aggr : aggr.concat(mutation.path),
55-
aggr
56-
)
57-
}, []).length
58-
)
59-
60-
export const currentAction = derived(
61-
(state: State) => state.currentApp.actions[state.currentApp.currentActionId]
62-
)
40+
41+
export const flushesStatePathCount = (state: State) =>
42+
state.flushes.reduce((aggr, flush) => {
43+
return flush.mutations.reduce(
44+
(aggr, mutation) =>
45+
aggr.includes(mutation.path) ? aggr : aggr.concat(mutation.path),
46+
aggr
47+
)
48+
}, []).length
49+
50+
export const currentAction = (state: State) =>
51+
state.currentApp.actions[state.currentApp.currentActionId]

packages/node_modules/overmind-devtools/src/app/effects.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
import * as jsonStorage from 'electron-json-storage'
22
import BackendConnector from '../BackendConnector'
33

4-
const backendConnector = new BackendConnector()
4+
export const connector = new BackendConnector()
55

6-
export const connector: {
7-
addPort: typeof backendConnector.addPort
8-
removePort: typeof backendConnector.removePort
9-
sendMessage: typeof backendConnector.sendMessage
10-
relaunch: typeof backendConnector.relaunch
11-
} = {
12-
addPort: backendConnector.addPort.bind(backendConnector),
13-
removePort: backendConnector.removePort.bind(backendConnector),
14-
sendMessage: backendConnector.sendMessage.bind(backendConnector),
15-
relaunch: backendConnector.relaunch.bind(backendConnector),
6+
export const utils = {
7+
confirmDialog(text) {
8+
return window.confirm(text)
9+
},
1610
}
1711

1812
export const storage = {
Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
import { Context } from './'
1+
import { Effects } from './'
22

3-
export function getAppsFromStorage({ storage }: Context) {
3+
export function getAppsFromStorage({ storage }: Effects) {
44
return storage.get('apps')
55
}
66

7-
export function getCurrentPortFromStorage({ storage }: Context) {
7+
export function confirm(text) {
8+
return function confirm({ utils }: Effects) {
9+
return utils.confirmDialog(text)
10+
}
11+
}
12+
13+
export function getCurrentPortFromStorage({ storage }: Effects) {
814
return storage.get('currentPort')
915
}
1016

11-
export function getNewPortFromState({ state }: Context) {
17+
export function getNewPortFromState({ state }: Effects) {
1218
return state.newPortValue
1319
}
1420

15-
export function storeApps({ storage, state }: Context) {
21+
export function storeApps({ storage, state }: Effects) {
1622
storage.set('apps', state.apps)
1723
}
1824

@@ -21,7 +27,15 @@ export function toNumber(_, value: string) {
2127
}
2228

2329
export function connectCurrentPort(action: (message: any) => void) {
24-
return function connectCurrentPort({ state, connector }: Context) {
30+
return function connectCurrentPort({ state, connector }: Effects) {
31+
if (!state.currentPort) {
32+
return
33+
}
34+
2535
connector.addPort(state.currentPort, action)
2636
}
2737
}
38+
39+
export function removeCurrentPort({ state, connector }: Effects) {
40+
connector.removePort(state.currentPort)
41+
}

packages/node_modules/overmind-devtools/src/app/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import * as effects from './effects'
33
import actions from './actions'
44
import state from './state'
55

6-
export type Context = TEffects<typeof state, typeof effects>
6+
export type Effects = TEffects<typeof state, typeof effects>
77

8-
export type Action = TAction<typeof state, Context>
8+
export type Action = TAction<typeof state, Effects>
99

1010
const app = new App({
1111
state,

0 commit comments

Comments
 (0)