Skip to content

Commit 34f8676

Browse files
committed
feat: performance improvements
1 parent 5eb2c28 commit 34f8676

File tree

1 file changed

+99
-85
lines changed

1 file changed

+99
-85
lines changed

src/index.ts

Lines changed: 99 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -210,85 +210,89 @@ const normalize = <T extends Settings>(
210210

211211
interface LocalState<T extends Settings> {
212212
records: Array<Required<Plugin<Types<T>, T>>>
213+
reducers: Array<Required<Plugin<Types<T>, T>>[Options.Reducer]>
213214
initialState: {}
214215
state: {}
215216
log: Action[]
216217
}
217218

218-
class Lens<T extends Settings> {
219-
private readonly state: LocalState<T> = {
220-
records: [],
221-
initialState: {},
222-
state: {},
223-
log: []
224-
}
219+
const normalizeRecords = <T extends Settings>(
220+
value: Plugin<Types<T>, T>[]
221+
): Required<Plugin<Types<T>, T>>[] => {
222+
const records: Required<Plugin<Types<T>, T>>[] = normalize(value)
225223

226-
// tslint:disable-next-line: function-name
227-
public static normalizeRecords<T extends Settings>(
228-
value: Plugin<Types<T>, T>[]
229-
): Required<Plugin<Types<T>, T>>[] {
230-
const records: Required<Plugin<Types<T>, T>>[] = normalize(value)
224+
records.forEach(record => {
225+
if (!isType(record[Options.Type])) {
226+
throw new Error('Not valid [Options.Type]')
227+
}
231228

232-
records.forEach(record => {
233-
if (!isType(record[Options.Type])) {
234-
throw new Error('Not valid [Options.Type]')
235-
}
229+
if (!isBoolean(record[Options.Once])) {
230+
throw new Error(
231+
`Not valid [Options.Once] in the ${String(
232+
record[Options.Type]
233+
)} specification`
234+
)
235+
}
236236

237-
if (!isBoolean(record[Options.Once])) {
238-
throw new Error(
239-
`Not valid [Options.Once] in the ${String(
240-
record[Options.Type]
241-
)} specification`
242-
)
243-
}
237+
if (!every(record[Options.Dependencies], isType)) {
238+
throw new Error(
239+
`Not valid [Options.Dependencies] in the ${String(
240+
record[Options.Type]
241+
)} specification`
242+
)
243+
}
244244

245-
if (!every(record[Options.Dependencies], isType)) {
246-
throw new Error(
247-
`Not valid [Options.Dependencies] in the ${String(
248-
record[Options.Type]
249-
)} specification`
250-
)
251-
}
245+
if (!every(record[Options.Conflicts], isType)) {
246+
throw new Error(
247+
`Not valid [Options.Conflicts] in the ${String(
248+
record[Options.Type]
249+
)} specification`
250+
)
251+
}
252252

253-
if (!every(record[Options.Conflicts], isType)) {
254-
throw new Error(
255-
`Not valid [Options.Conflicts] in the ${String(
256-
record[Options.Type]
257-
)} specification`
258-
)
259-
}
253+
if (!isFunction(record[Options.Enabled])) {
254+
throw new Error(
255+
`Not valid [Options.Enabled] in the ${String(
256+
record[Options.Type]
257+
)} specification`
258+
)
259+
}
260260

261-
if (!isFunction(record[Options.Enabled])) {
262-
throw new Error(
263-
`Not valid [Options.Enabled] in the ${String(
264-
record[Options.Type]
265-
)} specification`
266-
)
267-
}
261+
if (!isFunction(record[Options.Reducer])) {
262+
throw new Error(
263+
`Not valid [Options.Reducer] in the ${String(
264+
record[Options.Type]
265+
)} specification`
266+
)
267+
}
268268

269-
if (!isFunction(record[Options.Reducer])) {
270-
throw new Error(
271-
`Not valid [Options.Reducer] in the ${String(
272-
record[Options.Type]
273-
)} specification`
274-
)
275-
}
269+
if (!isPlainObject(record[Options.InitialState])) {
270+
throw new Error(
271+
`Not valid [Options.InitialState] in the ${String(
272+
record[Options.Type]
273+
)} specification`
274+
)
275+
}
276+
})
276277

277-
if (!isPlainObject(record[Options.InitialState])) {
278-
throw new Error(
279-
`Not valid [Options.InitialState] in the ${String(
280-
record[Options.Type]
281-
)} specification`
282-
)
283-
}
284-
})
278+
return records
279+
}
285280

286-
return records
281+
class Lens<T extends Settings> {
282+
private readonly state: LocalState<T> = {
283+
records: [],
284+
reducers: [],
285+
initialState: {},
286+
state: {},
287+
log: []
287288
}
288289

289-
public dispatch(action?: Action, ...plugins: Plugin<Types<T>, T>[]) {
290+
public readonly dispatch = (
291+
action?: Action,
292+
...plugins: Plugin<Types<T>, T>[]
293+
) => {
290294
if (plugins.length !== 0) {
291-
this.register(Lens.normalizeRecords(plugins))
295+
this.register(normalizeRecords(plugins))
292296
}
293297

294298
if (!isUndefined(action)) {
@@ -304,7 +308,7 @@ class Lens<T extends Settings> {
304308
return this.interfaces()
305309
}
306310

307-
public register(records: Required<Plugin<Types<T>, T>>[]) {
311+
public readonly register = (records: Required<Plugin<Types<T>, T>>[]) => {
308312
this.setRecords(records)
309313

310314
this.state.initialState = Object.assign(
@@ -313,34 +317,40 @@ class Lens<T extends Settings> {
313317
)
314318
}
315319

320+
private readonly tests = (
321+
record: Required<Plugin<Types<T>, T>>
322+
): Array<() => boolean> => [
323+
() =>
324+
every(record[Options.Dependencies], type =>
325+
some(this.state.log, action => action.type === type)
326+
),
327+
() => record[Options.Enabled](this.state.log, this.state.state),
328+
() =>
329+
record[Options.Once]
330+
? !some(this.state.log, action => action.type === record[Options.Type])
331+
: true,
332+
() =>
333+
!some(record[Options.Conflicts], type =>
334+
some(this.state.log, action => action.type === type)
335+
)
336+
]
337+
316338
private setState() {
317339
this.state.state = Object.assign(
318340
{},
319341
this.state.initialState,
320-
...this.state.records.map(record =>
321-
record[Options.Reducer](this.state.log)
322-
)
342+
...this.state.reducers.map(reducer => reducer(this.state.log))
323343
)
324344
}
325345

326346
private disabled(): Array<Required<Plugin<Types<T>, T>>> {
327-
return this.state.records.filter(record => {
328-
const once = record[Options.Once]
329-
? !some(this.state.log, action => action.type === record[Options.Type])
330-
: true
331-
332-
const enabled = record[Options.Enabled](this.state.log, this.state.state)
333-
334-
const conflicts = !some(record[Options.Conflicts], type =>
335-
some(this.state.log, action => action.type === type)
336-
)
337-
338-
const dependencies = every(record[Options.Dependencies], type =>
339-
some(this.state.log, action => action.type === type)
340-
)
341-
342-
return !(enabled && conflicts && dependencies && once)
343-
})
347+
return this.state.records.filter(
348+
record =>
349+
!this.tests(record).reduce(
350+
(prev, curr) => (prev ? curr() : false),
351+
true as boolean
352+
)
353+
)
344354
}
345355

346356
// private enabled(): Array<Required<Plugin<Types<T>, T>>> {
@@ -363,7 +373,7 @@ class Lens<T extends Settings> {
363373
[SYMBOL_STATE]: this.state.state
364374
},
365375
...this.state.records.map(record =>
366-
record[Options.Interface](this.dispatch.bind(this), this.state.state)
376+
record[Options.Interface](this.dispatch, this.state.state)
367377
)
368378
)
369379

@@ -378,6 +388,10 @@ class Lens<T extends Settings> {
378388
private setRecords(records: Required<Plugin<Types<T>, T>>[]) {
379389
records.forEach(record => {
380390
this.state.records.push(record)
391+
392+
if (this.state.reducers.indexOf(record[Options.Reducer]) === -1) {
393+
this.state.reducers.push(record[Options.Reducer])
394+
}
381395
})
382396
}
383397
}
@@ -386,7 +400,7 @@ class Lens<T extends Settings> {
386400
export const builder = <T extends Settings>(
387401
value: Plugin<Types<T>, T>[]
388402
): (() => Next<T>) => {
389-
const normalized = Lens.normalizeRecords(value)
403+
const normalized = normalizeRecords(value)
390404

391405
return () => {
392406
const lens = new Lens<T>()

0 commit comments

Comments
 (0)