flipchain

2019-05-27 admin

flipchain是什么

什么是flipchain,core chaining library, heavily based on webpack-chain

flipchain使用教程帮助文档

<g-emoji class=“g-emoji” alias=“chains” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/26d3.png”>⛓</g-emoji> flipchain

NPM version MIT License fliphub flipfam fluent

core chaining library, heavily based on webpack-chain, but not webpack-specific.

<g-emoji class=“g-emoji” alias=“european_castle” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f3f0.png”>🏰</g-emoji> benefits

writing an api using flipchain means writing a single fluent api, but getting 3 apis as a result!

  • <g-emoji class=“g-emoji” alias=“watermelon” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f349.png”>🍉</g-emoji> rehydratable configurations
  • <g-emoji class=“g-emoji” alias=“chains” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/26d3.png”>⛓</g-emoji> fluent chainable api
  • <g-emoji class=“g-emoji” alias=“icecream” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f366.png”>🍦</g-emoji> object configs that are easily merged deep

<g-emoji class=“g-emoji” alias=“ocean” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f30a.png”>🌊</g-emoji> what?

fluent

imagine there are 2 people by the water, & the goal is to make 10 splashes.

as with most skills, you get better at skipping rocks the more that you do it. a lot of people cannot skip rocks, or they do not like to skip rocks, but they can still throw rocks and make a splash. think of this like non-fluent/vanilla-calls

Chain.prop()
Chain.longer()
Chain.intoSomeShapes()

or throwing a really huge rock into the water, and getting the splashes to make more splashes.

Chain.from({
  prop: null,
  longer: null,
  intoSomeShapes: null,
})

pebbles using method chaining looks similar to skipping rocks

Chain
  .prop()
  .longer()
  .intoSomeShapes()

writing an application with a fluent interface allows people to use it all three ways, and you only have to write it one way.

<g-emoji class=“g-emoji” alias=“blue_book” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f4d8.png”>📘</g-emoji> examples

<g-emoji class=“g-emoji” alias=“wave” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f44b.png”>👋</g-emoji> intro

const ChainedMap = require('./ChainedMapExtendable')

class EasyFluent extends ChainedMap {
  constructor(parent) {
    super(parent)

    // extend a list of strings for easy chainable methods
    this.extend(['eh'])

    // same as .extend,
    // but when called with no arguments,
    // default is used (`true` in this case)
    // third param is optionally a prefix for inversified
    // for example, `no` => `noCanada()` for inverse value
    this.extendPrefixed(['canada'], true, 'no')
  }

  // if more advanced data changes are needed
  // or if the syntax is preferred for use with typescript or flowtype
  // .set, .get, .has are available
  igloo(igloo) {
    this.set('igloo', igloo)
    return this
  }

  toConfig() {
    return this.entries()
  }
}

// {igloo: 'fire', canada: false, eh: 'moose'}
const config = new EasyFluent()
  .igloo('fire')
  .noCanada()
  .eh('moose')
  .toConfig()

// this is == config
const hydrated = new EasyFluent()
  .from(config)
  .toConfig()

// canada is now true
const merged = new EasyFluent()
  .merge(config)
  .merge({canada: true})
  .toConfig()

<g-emoji class=“g-emoji” alias=“hole” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f573.png”>🕳</g-emoji><g-emoji class=“g-emoji” alias=“swimming_man” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f3ca.png”>🏊</g-emoji> advanced

const ChainedMap = require('./ChainedMapExtendable')
const ChainedSet = require('./ChainedSet')

class Advanced extends ChainedMap {
  static init(parent) {
    return new Advanced(parent)
  }
  constructor(parent) {
    super(parent)
    this.list = new ChainedSet(this)
    this.extend(['eh'])
    this.extendWith(['canada'], true)
  }

  addName(name) {
    this.list.add(name)
    return this
  }

  igloo(igloo) {
    this.set('igloo', igloo)
    return this
  }

  toConfig() {
    return Object.assign(this.entries(), {
      list: this.list.values().map(name => name),
    })
  }

  // since we have additional data that is not simple key value
  // we do additional (albeit easy) steps to rehydrate
  from(obj) {
    super.from(obj)

    Object
      .keys(obj)
      .forEach(key => {
        const val = obj[key]
        switch (key) {
          case 'list': return val
            .filter(name => name)
            .forEach(name => this.addName(name))
        }
      })

    return this
  }

  // same with `from`
  // we do additional simple steps to merge in lists
  merge(obj) {
    Object
      .keys(obj)
      .filter(key => obj[key])
      .forEach(key => {
        const val = obj[key]
        switch (key) {
          case 'list': return val
            .filter(name => name)
            .forEach(v => this.addName(v))
        }
      })

    // built-in merging
    // can use `.mergeReal` to merge only `real` values
    // and `.merge` to merge any
    super.merge(obj)

    return this
  }
}

const chain = Advanced
  .init()
  .igloo('brr')
  .canada()
  .eh('eh!')
  .addName('thing one')
  .addName('thing two')

// true, `eh!`
chain.has('igloo')
chain.get('eh')

const result = chain.toConfig()

const hydrated = Advanced
  .init()
  .from(result)
  .toConfig()

const merged = Advanced
  .init()
  .merge(hydrated)
  .merge({igloo: 'whaaaat'})

// can use toConfig,
// and safely continue editing `merged`
// with a snapshot of the object data saved as `mergedResult`
const mergedResult = merged.toConfig()

// hydrated === result === {
//   igloo: 'brr',
//   canada: 'canada',
//   eh: 'eh!',
//   list: [ 'thing one', 'thing two' ]
// }

// merged === {
//   igloo: 'whaaaat',
//   canada: 'canada',
//   eh: 'eh!',
//   list: [ 'thing one', 'thing two' ]
// }

<g-emoji class=“g-emoji” alias=“ocean” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f30a.png”>🌊</g-emoji> types

<g-emoji class=“g-emoji” alias=“globe_with_meridians” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f310.png”>🌐</g-emoji> api

ChainedSet

  • Set
  • prepend => this
  • clear => this
  • delete => this
  • values => array of entries
  • has => boolean
  • merge => merge an object into the chain
  • when => conditional instance callback

ChainedMap

extendAlias

  • (methodsToAlias: Array<string>, methodToAlias: string, [thisArg])
  • alias a list of methods
  • @returns this

from

  • (obj: Object)
  • checks each property of the object
  • calls the chains accordingly
  • rehydrates a chain from an object

other

  • decorateParent (using childparent)
  • clear() => this // clearsAll
  • delete(key) => this
  • entries => {keysAndValues}
  • values => Object.values
  • get(key) => entry
  • has(key) => boolean
  • set(key, val) => this
if key is an array, merge in the value,
usually should use ChainedSet for this
  • concat(key, val) => this
  • append(key, val) => this
merging
  • mergeReal(obj) => this // only merges non-undefined values
  • merge(obj) => this
  • clean => this
  • when => conditional instance callback

<g-emoji class=“g-emoji” alias=“link” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f517.png”>🔗</g-emoji> links & more

chainMapTill

lets you chain until the required keys are set via chains, or if they are passed in, then it auto returns parent

chainedMapExtendable

  • has chains with .extends able to use default values when calling it
  • also can add prefixes (default no) so if you use cache default true, it can add noCache which does the inverse
  • set up for being chains of chains when you add a few decorating chains dynamically

<g-emoji class=“g-emoji” alias=“memo” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f4dd.png”>📝</g-emoji><g-emoji class=“g-emoji” alias=“ocean” fallback-src=“https://github.githubassets.com/images/icons/emoji/unicode/1f30a.png”>🌊</g-emoji> TODO

  // using `izz` to validate types when setting
  this.extendType(['str'], 'string')

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-65794.html

文章标题:flipchain

回到顶部