Skip to content

Commit 307b7de

Browse files
Merge pull request cerebral#42 from cerebral/devtoolsPortsManagement
Devtools ports management
2 parents 6a077b3 + 94a3930 commit 307b7de

File tree

27 files changed

+243
-194
lines changed

27 files changed

+243
-194
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/action-chain/src/ActionChain.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export type OperatorExecution = {
3636
}
3737

3838
export interface ActionChainEvents {
39-
provider: Execution & {
39+
effect: Execution & {
4040
name: string
4141
method: string | number | symbol
4242
result: any
@@ -77,7 +77,7 @@ export class ActionChain<Effects> extends EventEmitter<ActionChainEvents> {
7777
const result = target[prop](...args)
7878
if (result instanceof Promise) {
7979
result.then((promisedResult) => {
80-
instance.emitAsync('provider', {
80+
instance.emitAsync('effect', {
8181
...execution,
8282
name: path,
8383
method: prop,
@@ -86,7 +86,7 @@ export class ActionChain<Effects> extends EventEmitter<ActionChainEvents> {
8686
})
8787
})
8888
} else {
89-
instance.emitAsync('provider', {
89+
instance.emitAsync('effect', {
9090
...execution,
9191
name: path,
9292
method: prop,

packages/node_modules/action-chain/src/index.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ type Context = typeof context
7373

7474
const actionChain = new ActionChain<Context>(context)
7575

76+
// FORCE SYNC EVENTS
77+
actionChain.emitAsync = actionChain.emit.bind(actionChain)
78+
7679
const action: <InitialValue = void>() => InitialValue extends void
7780
? INoValueAction<Context, InitialValue>
7881
: IAction<Context, InitialValue> = () => {
@@ -124,14 +127,14 @@ describe('CONTEXT', () => {
124127
})
125128
})
126129

127-
describe('PROVIDER', () => {
130+
describe('EFFECTS', () => {
128131
test('should track execution of effects', () => {
129132
expect.assertions(2)
130133
const fn = action().test(({ foo }) => {
131134
expect(foo.bar()).toBe('baz')
132135
})
133136

134-
actionChain.once('provider', (task) => {
137+
actionChain.once('effect', (task) => {
135138
expect(task).toEqual({
136139
operatorId: 0,
137140
actionId: 0,
@@ -150,7 +153,7 @@ describe('PROVIDER', () => {
150153
expect(foo.nestedProvider.bar()).toBe('baz')
151154
})
152155

153-
actionChain.once('provider', (task) => {
156+
actionChain.once('effect', (task) => {
154157
expect(task).toEqual({
155158
operatorId: 0,
156159
actionId: 0,
@@ -169,7 +172,7 @@ describe('PROVIDER', () => {
169172
expect(test.foo()).toBe('bar')
170173
})
171174

172-
actionChain.once('provider', (task) => {
175+
actionChain.once('effect', (task) => {
173176
expect(task).toEqual({
174177
operatorId: 0,
175178
actionId: 0,

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 = {

0 commit comments

Comments
 (0)