1.6.3 • Published 2 years ago

state-switch v1.6.3

Weekly downloads
848
License
Apache-2.0
Repository
github
Last release
2 years ago

STATE-SWITCH

State Switch is a Monitor/Guard for Managing Your Async Operations.

Build Status npm version TypeScript definitions on DefinitelyTyped Greenkeeper badge

State Switch Logo

EXAMPLE

Talk is cheap, show me the code!

Code

import { StateSwitch } from '../src/state-switch'

function doSlowConnect() {
  console.log('> doSlowConnect() started')
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('> doSlowConnect() done')
      resolve()
    }, 1000)
  })
}

function doSlowDisconnect() {
  console.log('> doSlowDisconnect() started')
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('> doSlowDisconnect() done')
      resolve()
    }, 1000)
  })
}

class MyConnection {
  private state = new StateSwitch('MyConnection')

  constructor() {
    /* */
  }

  public connect() {
    /**
     * This is the only 1 Right State
     */
    if (this.state.off() === true) {
      this.state.on('pending')

      doSlowConnect().then(() => {
        this.state.on(true)
        console.log(`> I'm now opened`)
      })

      console.log(`> I'm opening`)
      return
    }

    /**
     * These are the other 3 Error States
     */
    if (this.state.off() === 'pending') {
      console.error(`> I'm closing, please wait`)
    } else if (this.state.on() === true) {
      console.error(`> I'm already open. no need to connect again`)
    } else if (this.state.on() === 'pending') {
      console.error(`> I'm opening, please wait`)
    }
  }

  public disconnect() {
    /**
     * This is the only one Right State
     */
    if (this.state.on() === true) {
      this.state.off('pending')

      doSlowDisconnect().then(() => {
        this.state.off(true)
        console.log(`> I'm closed.`)
      })

      console.log(`> I'm closing`)
      return
    }

    /**
     * These are the other 3 Error States
     */
    if (this.state.on() === 'pending') {
      console.error(`> I'm opening, please wait`)
    } else if (this.state.off() === true) {
      console.error(`> I'm already close. no need to disconnect again`)
    } else if (this.state.off() === 'pending') {
      console.error(`> I'm closing, please wait`)
    }
  }
}

const conn = new MyConnection()

console.log('CALL: conn.connect(): should start to opening')
conn.connect()

console.log('CALL: conn.connect(): should not connect again while opening')
conn.connect()

console.log('CALL: conn.disconnect(): can not disconnect while opening')
conn.disconnect()

setTimeout(() => {
  console.log('... 2 seconds later, should be already open  ...')

  console.log('CALL: conn.connect(): should not connect again if we are open')
  conn.connect()

  console.log('CALL: conn.disconnect(): should start to closing')
  conn.disconnect()

  console.log('CALL: conn.disconnect(): should not disconnect again while we are closing')
  conn.disconnect()

  console.log('CALL: conn.connect(): can not do connect while we are closing')
  conn.connect()

  setTimeout(() => {
    console.log('... 2 seconds later, should be already closed ...')

    console.log('CALL: conn.disconnect(): should not disconnect again if we are close')
    conn.disconnect()
  }, 2000)

}, 2000)

Diagram

What's the meaning of the above code?

StateSwitch helps you manage the following four states easy:

State Switch Diagram

Run

$ npm run demo

> state-switch@0.1.3 demo /home/zixia/git/state-switch
> ts-node example/demo

CALL: conn.connect(): should start to opening
> doSlowConnect() started
> I'm opening
CALL: conn.connect(): should not connect again while opening
> I'm opening, please wait
CALL: conn.disconnect(): can not disconnect while opening
> I'm opening, please wait
> doSlowConnect() done
> I'm now opened
... 2 seconds later, should be already open  ...
CALL: conn.connect(): should not connect again if we are open
> I'm already open. no need to connect again
CALL: conn.disconnect(): should start to closing
> doSlowDisconnect() started
> I'm closing
CALL: conn.disconnect(): should not disconnect again while we are closing
> I'm closing, please wait
CALL: conn.connect(): can not do connect while we are closing
> I'm closing, please wait
> doSlowDisconnect() done
> I'm closed.
... 2 seconds later, should be already closed ...
CALL: conn.disconnect(): should not disconnect again if we are close
> I'm already close. no need to disconnect again

That's the idea: we should always be able to know the state of our async operation.

API REFERENCE

Class StateSwitch

constructor(clientName?: string)

Create a new StateSwitch instance.

private state = new StateSwitch('MyConn')

on(): boolean | 'pending'

Get the state for ON: true for ON(stable), pending for ON(in-process). false for not ON.

on(state: true | 'pending'): void

Set the state for ON: true for ON(stable), pending for ON(in-process).

off(): boolean | 'pending'

Get the state for OFF: true for OFF(stable), pending for OFF(in-process). false for not OFF.

off(state: true | 'pending'): void

Set the state for OFF: true for OFF(stable), pending for OFF(in-process).

pending(): boolean

Check if the state is pending.

true means there's some async operations we need to wait. false means no async on fly.

ready(expectedState='on', noCross=false): Promise

  1. expectedState: 'on' | 'off', default is on
  2. noCross: boolean, default is false

Wait the expected state to be ready.

If set noCross to true, then ready() will throw if you are wait a state from it's opposite site, for example: you can expect an Exception when you call ready('on', true) when the on() === 'off'.

name(): string

Get the name from the constructor.

setLog(log: Brolog | Npmlog)

Enable log by set log to a Npmlog compatible instance.

Personaly I use Brolog, which is writen by my self, the same API with Npmlog but can also run inside Browser with Angular supported.

const log = Brolog.instance()
StateSwitch.setLog(log)

CHANGELOG

v0.6 master (Jun 2018)

  1. DevOps for publishing to NPM@next for odd minor versions.
  2. Add State Diagram for easy understanding what state-switch do

v0.4 master (Apr 2018)

BREAKING CHANGE: Change the ready() parameter to the opposite side.

  • Before: ready(state, crossWait=false)
  • AFTER: ready(state, noCross=false)

v0.3 (Apr 2018)

  1. add new method ready() to let user wait until the expected state is on(true).

v0.2 (Oct 2017)

BREAKING CHANGES: redesigned all APIs.

  1. delete all old APIs.
  2. add 4 new APIs: on() / off() / pending() / name()

v0.1.0 (May 2017)

Rename to StateSwitch because the name StateMonitor on npmjs.com is taken.

  1. Make it a solo NPM Module. (#466)

v0.0.0 (Oct 2016)

Orignal name is StateMonitor

  1. Part of the Wechaty project

AUTHOR

Huan LI zixia@zixia.net (http://linkedin.com/in/zixia)

COPYRIGHT & LICENSE

  • Code & Docs 2016-2017© zixia
  • Code released under the Apache-2.0 license
  • Docs released under Creative Commons
1.6.3

2 years ago

1.7.1

2 years ago

1.6.2

2 years ago

1.6.1

2 years ago

1.3.6

2 years ago

1.3.5

2 years ago

1.5.1

2 years ago

1.3.1

2 years ago

1.0.16

3 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.2.1

3 years ago

1.1.9

3 years ago

1.1.8

3 years ago

1.1.7

3 years ago

1.1.6

3 years ago

1.1.5

3 years ago

1.1.4

3 years ago

1.1.3

3 years ago

1.1.2

3 years ago

1.1.12

3 years ago

1.1.11

3 years ago

1.1.10

3 years ago

1.1.16

3 years ago

1.1.15

3 years ago

1.1.14

3 years ago

1.1.13

3 years ago

1.0.15

3 years ago

1.0.14

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.2

3 years ago

0.17.1

3 years ago

0.18.1

3 years ago

0.15.7

3 years ago

0.15.8

3 years ago

0.15.9

3 years ago

0.13.1

3 years ago

0.14.1

3 years ago

0.15.10

3 years ago

0.11.5

3 years ago

0.11.3

3 years ago

0.11.4

3 years ago

0.9.9

4 years ago

0.9.8

4 years ago

0.9.7

4 years ago

0.7.2

5 years ago

0.6.18

5 years ago

0.6.17

5 years ago

0.6.16

5 years ago

0.6.15

5 years ago

0.6.14

5 years ago

0.6.12

5 years ago

0.6.11

5 years ago

0.6.10

6 years ago

0.6.6

6 years ago

0.6.5

6 years ago

0.6.4

6 years ago

0.6.3

6 years ago

0.6.2

6 years ago

0.4.5

6 years ago

0.4.4

6 years ago

0.4.3

6 years ago

0.4.2

6 years ago

0.4.1

6 years ago

0.3.2

6 years ago

0.3.1

6 years ago

0.3.0

6 years ago

0.2.4

7 years ago

0.2.3

7 years ago

0.2.2

7 years ago

0.2.1

7 years ago

0.1.21

7 years ago

0.1.20

7 years ago

0.1.19

7 years ago

0.1.15

7 years ago

0.1.14

7 years ago

0.1.13

7 years ago

0.1.11

7 years ago

0.1.10

7 years ago

0.1.9

7 years ago

0.1.8

7 years ago

0.1.7

7 years ago

0.1.6

7 years ago

0.1.5

7 years ago

0.1.4

7 years ago

0.1.3

7 years ago