Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapper? #5

Open
jongacnik opened this issue Apr 19, 2018 · 4 comments
Open

Wrapper? #5

jongacnik opened this issue Apr 19, 2018 · 4 comments

Comments

@jongacnik
Copy link
Collaborator

Curious if we need the wrapper function, instead of just directly exporting the class. Doing this would allow for easy extending:

var Nanopage = require('nanopage')

class Page extends Nanopage {
  formattedDate (state, value) {
    try {
      return someDateFormattingFunction('y-m-d', state.date)
    } catch (err) {
      return false
    }
  }
}

function view (state, emit) {
  var page = new Page(state)
  return html`<div>${page().formattedDate().value()}</div>`
}
@jondashkyle
Copy link
Owner

yeah 100%! current structure is sort of left over b/c i’m a dummy who can’t architect something without doing it first.

@jongacnik
Copy link
Collaborator Author

This is actually a little bit of a tricky one since we're wanting to return a callable from the constructor. I think we can pull it off though, I'm gonna test something out later today.

@jongacnik
Copy link
Collaborator Author

Took me a sec to track down the pattern I was thinking of. It'd look something like this:

function inherits (ctor, superCtor) {
  ctor.super_ = superCtor
  Object.setPrototypeOf(ctor.prototype, superCtor.prototype)
}

function Nanopage () {
  var instance = function () {
    return instance.__default.apply(instance, arguments)
  }
  instance.__proto__ = Nanopage.prototype
  instance.__ctor.apply(instance, arguments)
  return instance
}

inherits(Nanopage, Function)

// Used to init new Nanopage instance
Nanopage.prototype.__ctor = function (state) {
  this._state = state.content
}

// Used when Nanopage instance is invoked
Nanopage.prototype.__default = function (key) {
  key = key || '/'
  this._value = this._state[key]
  return this
}

// Example method
Nanopage.prototype.value = function (key) {
  return this._value 
}

Usage:

var page = new Nanopage(state)
console.log(page('/').value())

"Extending" Nanopage happens with prototype:

Nanopage.prototype.whatever = function () {
  return 'whatever'
}

This all said, another approach would be to keep Nanopage structure similar how it already is, and to enable a way to pass custom methods into the constructor via opts:

var page = new Nanopage(state, opts)

Or finally, do we even need to worry about extending Nanopage?

@jondashkyle
Copy link
Owner

jondashkyle commented Apr 20, 2018

oh shit, this is some dark magic. definitely interesting. i like the cleanness of it simply being a class/prototype, but one reason to possibly accept opts like your last example is it plays nicely with the choo plugin, too. for example:

app.use(require('nanopage/choo', opts))

going to think more about the raw class version. ideally we can do something in between the two.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants