npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

weddell

v3.3.0

Published

A tiny, modular, nonopinionated front-end web framework.

Downloads

33

Readme

Classes

Typedefs

Weddell

Top-level Weddell class serving as an entrypoint to various APIs.

Kind: global abstract class

Weddell.plugin(pluginObj)

Extends the base Weddell class with additional functionality, as defined in a plugin object.

Kind: static method of Weddell

Example

const Weddell = require('weddell');

const WeddellWithPluginApplied = Weddell.plugin({
 id: 'my-plugin',
 require: ['my-other-plugin'], // will error if app is initialized without 'my-other-plugin' also applied
 classes: {
     Component: Component => class extends Component {

         onMount() {
             console.log(this.myNewComponentMethod());
         }

         myNewComponentMethod() {
             this.foo = 'bar';
         }
     }
 },

 // Every component mounted by this app will print 'bar' to logs.
 
})

Weddell~WeddellApp

An app, which owns and manages a root component in the DOM. The Weddell app object is the main entrypoint to your application.

Kind: inner class of Weddell

new WeddellApp(opts)

Example

const { App } = require('weddell');

var app = new App({
    el: '#app',
    Component: Component => class MyRootComponent extends Component {
        static get markup(locals, h) {
            return h('.foo', 'bar');
        }
    },
    styles: `
      #app {
        color: red;
      }
    `
});

app.init();

// Given HTML '<div id="app"></div>', after init finishes, 
// '<div id="app"><div class="foo">bar</div></div>' will be 
// rendered into the DOM

weddellApp.init(initObj) ⇒ Promise

Initializes the app, rendering the root component and mounting it into the specified DOM element.

Kind: instance method of WeddellApp
Returns: Promise - Promise that resolves once the app has fully initialized and rendered into the DOM.
Emits: Window#event:weddellinit Event fired on window object once initialization completes., WeddellApp#event:createcomponent Event fired on app object whenever its root component or any child components are created., WeddellApp#event:createrootcomponent Event fired on app object whenever its root component is created.

weddellApp.onPatch() ⇒ Promise

Hook method that may be overridden and will be executed at the end of every DOM patch.

Kind: instance method of WeddellApp
Returns: Promise - Subsequent patches may be deferred by returning a Promise in this method.

weddellApp.awaitComponentMount(id) ⇒ Promise.<WeddellComponent>

Returns a promise the resolves with a weddell component once the component with the specified id has been rendered and mounted (not necessarily patched to DOM yet). Note that if the component id does not match any current or future components, the returned promise will never resolve.

Kind: instance method of WeddellApp

weddellApp.awaitPatch() ⇒ Promise

Returns a promise that will resolve after pending patch completes, or immediately if no patch is currently queued or in progress.

Kind: instance method of WeddellApp

weddellApp.awaitNextPatch() ⇒ Promise

Returns a promise that will resolve after current pending patch or the next patch completes.

Kind: instance method of WeddellApp

weddellApp.renderSnapshot() ⇒ WeddellAppStateSnapshot

Dumps the current application state to a snapshot object, typically used for server-side rendering setups.

Kind: instance method of WeddellApp

Weddell~WeddellComponent

Class representing a Weddell component. A component encapsulates some combination of scripts, markup and/or styles into an instantiable custom tag.

Kind: inner class of Weddell

new WeddellComponent(opts)

Constructs a Weddell Component. One does not generally instantiate components directly, but rather includes them declaratively via markup tags. This information is available primarily for the purposes of plugin authorship. See the static markup, state, and styles properties for more typical component development entrypoints.

weddellComponent.onMount() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called whenever a component instance finishes rendering and mounting into a parent component.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer completion of the mount process.

weddellComponent.onFirstMount() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called whenever a component instance finishes rendering and mounting into a parent component, but only the first time it mounts. Subsequent unmounts and mounts will not call this method again.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer completion of the mount process.

weddellComponent.onUnmount() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called whenever a component instance is unmounted from its parent component.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer completion of the unmount process.

weddellComponent.onInit() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called whenever a component instance finishes initializing.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer completion of the init process.

weddellComponent.onRender() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called after the component finishes rendering.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer completion of the render process (not advised unless you know what you are doing).

weddellComponent.onFirstRender() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called the first time the component is ever rendered, but not on subsequent rerenders.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer rendering (not advised unless you know what you are doing).

weddellComponent.onRenderMarkup() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called after the component finishes rendering markup as part of its rendering process.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer completion of the markup render process, and thus the render process as a whole (not advised unless you know what you are doing).

weddellComponent.onRenderStyles() ⇒ Promise | void

Component lifecycle hook method that may be overridden. Called after the component finishes rendering styles as part of its rendering process.

Kind: instance method of WeddellComponent
Returns: Promise | void - Returning a promise will defer completion of the styles render process, and thus the render process as a whole (not advised unless you know what you are doing).

weddellComponent.onDOMCreate(evt) ⇒ void

Component lifecycle hook method that may be overridden. Called when a DOM element is created and set to this component's 'el' property.

Kind: instance method of WeddellComponent

weddellComponent.onDOMMove(evt) ⇒ void

Component lifecycle hook method that may be overridden. Called when the DOM element associated with this component moves to a new location in the DOM.

Kind: instance method of WeddellComponent

weddellComponent.onDOMChange(evt) ⇒ void

Component lifecycle hook method that may be overridden. Called when the DOM element associated with this component changes.

Kind: instance method of WeddellComponent

weddellComponent.onDOMCreateOrChange(evt) ⇒ void

Component lifecycle hook method that may be overridden. Called either when a new DOM element is created for this component, or when the DOM element associated with it changes.

Kind: instance method of WeddellComponent

weddellComponent.onDOMDestroy(evt) ⇒ void

Component lifecycle hook method that may be overridden. Called when a DOM element that was previously associated with this component is destroyed.

Kind: instance method of WeddellComponent

weddellComponent.bindEvent(funcText, opts)

Binds a function body string to the scope of this component. This string will then typically be used in a native DOM event handler attribute.

Kind: instance method of WeddellComponent

Example (Not a standard use case)


component.el.onclick = component.bindEvent('console.log(this.id)');
component.el.click();
console.log(component.id)

// myId
// myId

Example (This function is also proxied onto component state as '$bind')


class MyComponentClass {
 static get markup(locals, h) {
     return h('div', {
         attributes: {
             onclick: locals.$bind('console.log(this.id)')
         }
     });
 }
}

//Once a component instance has been mounted, assuming we have an reference to it...

myComponentInstance.el.click();

// myId

weddellComponent.bindEventValue(propName, opts)

Syntax sugar method very similar to bindEvent, but slightly less verbose for DOM elements with a value (inputs, etc) that you would like to bind to component state.

Kind: instance method of WeddellComponent

Example (As with bindEvent, bindEventValue is also proxied into component state object as '$bindValue'.)


class MyComponentClass {

 static get state() {
     return {
         myInputValue: null
     }
 }

 static get markup(locals, h) {
     return h('input', {
         attributes: {
             onchange: locals.$bindValue('myInputValue')
         }
     });
 }
}

//Once a component instance has been mounted, assuming we have an reference to it...

console.log(myComponentInstance.state.myInputValue);

// null

// The user enters the text 'Tiny Tigers' into the input field in browser...

console.log(myComponentInstance.state.myInputValue);

// Tiny Tigers

weddellComponent.walkComponents(callback, [filterFunc])

Calls the specified callback for this component and all child components.

Kind: instance method of WeddellComponent
Todo

  • Document callback param structure

weddellComponent.reduceComponents(callback, initialVal, [filterFunc]) ⇒ *

Calls the specified reducer for this component and all child components.

Kind: instance method of WeddellComponent
Todo

  • Document callback param structure

weddellComponent.reduceParents(callback, initialVal) ⇒ *

Calls the specified reducer recursively for all parent components upward from this one.

Kind: instance method of WeddellComponent

weddellComponent.collectComponentTree() ⇒ object

Performs a recursive scan upward from this component, to the application's root component.

Kind: instance method of WeddellComponent
Todo

  • Document this more thoroughly

weddellComponent.getMountedChildComponents() ⇒ Array.<WeddellComponent>

Queries the component tree for components that are currently mounted (rendered and typically in DOM or soon-to-be in DOM).

Kind: instance method of WeddellComponent

weddellComponent.queryDOM(query) ⇒ Promise.<(Element|null)>

Returns a promise that will resolve with the result of querying this component's DOM element using querySelector, once the component has a DOM element to query.

Kind: instance method of WeddellComponent

weddellComponent.queryDOMAll(query) ⇒ Promise.<NodeListOf.<Element>>

Returns a promise that will resolve with the result of querying this component's DOM element using querySelectorAll, once the component has a DOM element to query.

Kind: instance method of WeddellComponent

weddellComponent.awaitEvent(eventName) ⇒ Promise

Returns a promise that will resolve once this component fires a specific event.

Kind: instance method of WeddellComponent

weddellComponent.awaitPatch() ⇒ Promise

Returns a promise that will resolve once this component has finished rendering, and the next application patch has completed (which should mean all state changes have been propagated to the DOM).

Kind: instance method of WeddellComponent

weddellComponent.awaitMount() ⇒ Promise

Returns a promise that will resolve once this component mounts (or immediately, if it is already mounted). Note that mounting does not necessarily mean that application changes have been propagated to the DOM.

Kind: instance method of WeddellComponent

weddellComponent.awaitDom() ⇒ Promise.<Element>

Returns a promise that will resolve once a DOM element has been created for this component (or immediately, if it already has one). The promise is resolved with this component's DOM element.

Kind: instance method of WeddellComponent

weddellComponent.awaitRender() ⇒ Promise

Returns a promise that will resolve once the pending render promise has completed (or immediately, if there is no pending render promise).

Kind: instance method of WeddellComponent

WeddellComponent.markup : VirtualDomTemplate

Stub property. Typically, components will override the markup property to provide their components's virtual DOM template function. The template function is passed both component state and the application's hyperscript implementation ('h'). See the virtual-dom docs for more info about this syntax.

Kind: static property of WeddellComponent
Example

Component => class MyComponent extends Component {
 static get markup() {
     return (locals, h) =>
         h('.my-component', [
            h('div', {
             attributes: {
                 onclick: 'console.log("hello");'
             }
            }, 'Click Me')
         ])
 }
}

// Will render '<div class="my-component" onclick='console.log("hello");'>Click Me</div>' to DOM

Example (Hscript can be a bit clunky to work with when your display logic gets more complex. Development tools like pug-vdom can port other, perhaps more succinct syntaxes to return virtual-dom nodes.)


Component => class MyComponent extends Component {
 static get markup() {
     return require('./my-component.pug');
 }
}

// in './my-component.pug':
//
// .my-component
//   div(onclick="console.log('hello')") Click Me

// This example would require the use of the pug-vdom dev tool. weddell-dev-tools includes pug support 
// out of the box. Or you can write your own require hook to adapt your favorite template syntax to 
// return virtual dom nodes.

WeddellComponent.state : object

Stub property. Typically, components override this property, returning the keys and default state values. When a component is initialized, it will use this object when creating its own local transient state object. Once initialized, subsequent changes to any key in the WeddellComponent#state object will trigger component rerenders -> DOM patches.

Kind: static property of WeddellComponent
Example

Component => class MyComponent extends Component {
 static get state() {
     return {
         myContent: 'Foobar'
     }
 }
 static get markup() {
     return (locals, h) =>
         h('.my-component', [locals.myContent])
 }
}

// Will render '<div class="my-component">Foobar</div>' to DOM

Example (Values saved to state must be serializable (strings, numbers, plain objects, arrays, bools). Trying to save a complete data type to state will cause an error to be thrown. If you really need to save non-serializable objects to state, look at the Component.serializers and Component.deserializers properties.)


Component => class MyComponent extends Component {
 static get state() {
     return {
         myContent: new Foobar() //Don't do this!
     }
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', [locals.myContent])
 }
}

// Will throw an error. Instances of the Foobar class are not plain objects, and 
// thus are not serializable.

Example (There is, however, an exception allowing serializable data in state: state values declared as functions will be interpreted as 'computed values'. These functions are executed in the context of the component state object, and will be recomputed when referenced state values change. Note: functions may only be specified in the initial declaration - you can NOT set a state value to a new function at runtime (that will result in an error being thrown).)


Component => class MyComponent extends Component {
 static get state() {
     return {
         numbers: [1, 2],
         numbersDoubled: function(){
             return this.numbers.map(num => num * 2);
         }
     }
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', { attributes: { 
             onclick: locals.$bind('this.state.numbers = this.state.numbers.map(num => num + 1)') }
         }, locals.numbersDoubled)
 }
}

// '<div class="my-component">2 4</div>'
// * User clicks *
// '<div class="my-component">4 6</div>'

Example (When inheriting from a parent component class, the ES6 class spec's super keyword makes it easy to merge with parent state.)


Component => class MyComponent extends MyParentComponentMixin(Component) {
 static get state() {
     return Object.assign({}, super.state, { //Note argument order - we default to super state, override with our state.
         numbersDoubledMinus1: function(){
             return this.numbersDoubled.map(num => num - 1);
         }
     });
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', locals.numbersDoubledMinus1)
 }
}

// Assuming 'MyParentComponentMixin' is the mixin from the previous example...
// '<div class="my-component">1 3</div>'
// * User clicks *
// '<div class="my-component">3 5</div>'

Example (When working with objects and arrays in component state, be cognizant of the fact that you must set the state value itself in order for the necessary change events to fire, triggering DOM refresh. Getting this wrong can lead to hard-to-track-down bugs.)


Component => class MyComponent extends Component {
 static get state() {
     return {
         myObject: {
             myValue: 1
         }
     }
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', {
             attributes: {
                 onclick: locals.$bind('this.state.myObject.myValue += 1')
             }
         }, locals.myObject.myValue)
 }
}

// '<div class="my-component">1/div>'
// * User clicks *
// '<div class="my-component">1</div>'
// Even though our event handler was fired, the DOM did not get refreshed! Let's try this again...

Component => class MyComponent extends Component {
 static get state() {
     return {
         myObject: {
             myValue: 1
         }
     }
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', {
             attributes: {
                 onclick: locals.$bind('this.state.myObject = { ...this.state.myObject, myValue: this.state.myObject.myValue + 1 }')
             }
         }, locals.myObject.myValue)
 }
}
// '<div class="my-component">1/div>'
// * User clicks *
// '<div class="my-component">2</div>'
// There we go! Because we set this.state.myObject itself to a new value instead of just setting 
// a property on the existing value, the appropriate events got fired, and the DOM refreshed.

WeddellComponent.styles ⇒ Array.<(CssTemplate|CssString)> | CssString | CssTemplate

Stub property. Typically, components with custom CSS styles will override this property. Styles returned here will be dynamically inserted into style elements in the DOM's head when needed. Strings will be applied on a per-class basis (one copy for all component instances), while functions will be executed as a style template on a per-instance basis.

Kind: static property of WeddellComponent
Example

Component => class MyComponent extends Component {
 static get styles() {
     return `
         .my-component {
             color: red;
         }
     `
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', 'Foo bar')
 }
}

// Once mounted and patched, the element will be rendered in DOM with red text.

Example (You can also return a function instead of a string, in which case current component state is available for dynamic styling.)


Component => class MyComponent extends Component {
 static get state() {
     return {
         myImg: 'https://mywebsite.com/myimage.jpg'
     }
 }

 static get styles() {
     return (locals) => `
         .my-component {
             background-image: url(${locals.myImg});
         }
     `
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', 'Foo bar')
 }
}

// Once mounted and patched, the element will be rendered with 'myimage.jpg' in the background.

Example (Be careful with CSS template functions though! Unlike string values, template functions will be executed and rendered to DOM for every component instance, which can lead to performance issues. Ideally, static, class-level styles should be returned as strings, while styles making use of component instance state, if needed, should be returned as template functions. You can mix and match by returning an array of style values.)


Component => class MyComponent extends Component {
 static get state() {
     return {
         myImg: 'https://mywebsite.com/myimage.jpg'
     }
 }

 static get styles() {
     return [
     (locals) => `
           .my-component {
               background-image: url(${locals.myImg});
           }
       `,
       `
           .my-component {
               color: red;
           }
       `
     ]
 }

 static get markup() {
     return (locals, h) =>
         h('.my-component', 'Foo bar')
 }
}

// Once mounted and patched, the element will be rendered with 'myimage.jpg' in the background and 
// red text. Since the red text does not need component state, we return it as a string, separately 
// from the background-image style - it will be more performant that way.

Example (When inheriting from a parent component class, the ES6 class spec's super keyword makes it easy to extend the parent styles.)


Component => class MyChildComponent extends MyParentComponentMixin(MyComponent) {

 static get styles() {
     return [
        `
             .my-component {
                 border: 2px solid red;
            }
         `
     ].concat(super.styles);
 }
}

// Assuming 'MyParentComponentMixin' is the mixin from the previous example, we would get an element
// rendered to DOM with 'myimage.jpg' in the background, red text, and a 2px solid red border

WeddellComponent.components : Object.<string, WeddellComponentMixin>

Stub property. Typically, components with child components will override this property, supplying component mixins that can then be included in the component's markup template by the entry key.

Kind: static property of WeddellComponent
Todo

  • supply example demonstrating nested child tag scoping
  • example showing static parent -> child state binding
  • example showing custom event handlers

Example

Component => class MyComponent extends Component {
 static get markup(locals, h) {
     return h('.foo', [
         h('my-child-component')
     ]);
 }

 static get components() {
     return {
         'my-child-component': Component => class extends Component {
             static get markup(locals, h) {
                 return h('.bar', ['bar']);
             }
         }
     }
 }
}

// will render '<div class="foo"><div class="bar">bar</div></div>' into the DOM.

Example (You can pass markup down from the parent component to the child by placing the 'content' tag in the child.)


Component => class MyComponent extends Component {
 static get markup(locals, h) {
     return h('.foo', [
         h('my-child-component', [
             'This is my content'
         ])
     ]);
 }

 static get components() {
     return {
         'my-child-component': Component => class extends Component {
             static get markup(locals, h) {
                 return h('.bar', [
                     h('content')
                 ]);
             }
         }
     }
 }
}

// Will render as '<div class="foo"><div class="my-child-component">This is my content</div></div>'

WeddellComponent.inputs : Array.<String>

Stub property. Typically, components with inputs will override this property. The inputs property flags particular keys as being expected as input data from parent components.

Kind: static property of WeddellComponent
Todo

  • Clean up / fix object form of inputs, then document.

Example

Component => class MyComponent extends Component {
 static get state() {
     return {
         myParentData: 'foo'
     }
 }
 static get markup(locals, h) {
     return h('.foo', [
         h('my-child-component', {
             attributes: {
                 myChildData: locals.myParentData
             }
         }, [
             'This is my content'
         ])
     ]);
 }

 static get components() {
     return {
         'my-child-component': Component => class extends Component {
             static get inputs() {
                 return ['myChildData']
             }

             static get state() {
                 return {
                     myChildData: 'bar'
                 }
             }

             static get markup(locals, h) {
                 return h('.bar', [
                     locals.myChildData
                 ]);
             }
         }
     }
 }
}

// Component will render as '<div class="foo"><div class="my-child-component">foo</div></div>'
// But note that not that if the inputs property did not include 'myChildData', or if the parent
// component did not pass 'locals.myParentData' into the child component, then it would render
// '<div class="foo"><div class="my-child-component">bar</div></div>'

WeddellComponent.consts : object

Stub property. Typically, components with constant helper values will override this property. These values will be proxied onto the component instance's 'state' property.

Kind: static property of WeddellComponent
Todo

  • Example showing const availability on state object.

WeddellComponent.propertySets : Object.<string, (Object.<string, string>|Array.<String>)>

Stub property. Typically, components with property sets will override this property. Property sets group other state keys together into objects, making them more portable for passing down to components in a way that avoids unnecessary duplication.

Kind: static property of WeddellComponent
Example

Component => class MyComponent extends Component {

 static get state() {
     return {
         myProperty1: 'foo',
         myProperty2: 'bar',
         myUnrelatedProperty: 'whoosh'
     }
 }

 static get propertySets() {
     return {
         propertiesForChild: [
             'myProperty1',
             'myProperty2'
         ]
     }
 }

 static get markup(locals, h) {
     return h('.foo', [
         h('my-child-component', {
             attributes: locals.propertiesForChild
         })
     ]);
 }

 static get components() {
     return {
         'my-child-component': Component => class extends Component {
             static get inputs() {
                 return [
                     'myProperty1',
                     'myProperty2'
                 ]   
             }

             static get state() {
                 return {
                     myProperty1: 'whizz',
                     myProperty2: 'bang'
                 }
             }

             static get markup(locals, h) {
                 return h('.bar', [
                     locals.myProperty1,
                     locals.myProperty2
                 ]);
             }
         }
     }
 }
}

// Will render as '<div class="foo"><div class="my-child-component">foo bar</div></div>'

Example (You can also specify property sets as objects, if you need to proxy the value to a different key on the set object.)


Component => class MyComponent extends Component {

 static get state() {
     return {
         myProperty1: 'foo',
         myProperty2: 'bar',
         myUnrelatedProperty: 'whoosh'
     }
 }

 static get propertySets() {
     return {
         propertiesForChild: {
             myProperty1: 'myChildProperty1',
             myProperty2: 'myChildProperty2'
         }
     }
 }

 static get markup(locals, h) {
     return h('.foo', [
         h('my-child-component', {
             attributes: locals.propertiesForChild
         })
     ]);
 }

 static get components() {
     return {
         'my-child-component': Component => class extends Component {
             static get inputs() {
                 return [
                     'myChildProperty1',
                     'myChildProperty2'
                 ]   
             }

             static get state() {
                 return {
                     myChildProperty1: 'whizz',
                     myChildProperty2: 'bang'
                 }
             }

             static get markup(locals, h) {
                 return h('.bar', [
                     locals.myChildProperty1,
                     locals.myChildProperty2
                 ]);
             }
         }
     }
 }
}

// Will render as '<div class="foo"><div class="my-child-component">foo bar</div></div>'

WeddellComponent.deserializers : Object.<string, StateTransform>

Stub property. Typically, components needing non-serializable data in state will declare functions here for transforming specific keys from serialized data to complex data types at runtime.

Kind: static property of WeddellComponent
Example

class MyThing {
 constructor(num) {
     this.num = num;
 }
 repeat3() {
     return `${this.num}${this.num}${this.num}`
 }
}

Component => class MyComponent extends Component {

 static get deserializers() {
     return {
         myThing: function(key, value) {
             return new MyThing(value);
         }
     }
 }

 static get state() {
     return {
         myThing: 4
     }
 }

 static get markup(locals, h) {
     return h('.foo', [this.myThing.repeat3()]);
 }

// Will render as '<div class="foo">444</div>'

WeddellComponent.serializers : Object.<string, StateTransform>

Stub property. A companion property to deserializers - serialized values will be used when a value set directly to state is a complex data type, and will need to be serialized before committing it to state.

Kind: static property of WeddellComponent
Example

class MyThing {
 constructor(num) {
     this.num = num;
 }
 repeat3() {
     return `${this.num}${this.num}${this.num}`
 }
}

Component => class MyComponent extends Component {

 static get deserializers() {
     return {
         myThing: function(key, value) {
             return new MyThing(value);
         }
     }
 }
 static get serializers() {
     return {
         myThing: function(key, value) {
             return value.num
         }
     }
 }

 static get state() {
     return {
         myThing: new MyThing(4)
     }
 }

 static get markup(locals, h) {
     return h('.foo', [this.myThing.repeat3()]);
 }

// Will render as '<div class="foo">444</div>'. Note that with the serializer defined, the complex
// MyThing data type may be set directly to state.

WeddellComponent.watchers : Array.<StoreWatchArgs>

Stub property. Watch functions may be defined here, allowing for complex actions to be kicked off when component state changes. Watchers will be executed in component scope. Tip: if your watch function is really only setting other component state keys, you may be able to use a computed state propery instead (see example 3 here).

Kind: static property of WeddellComponent
Example

Component => class MyComponent extends Component {

 static get watchers() {
     return [
         ['watchedUrl', function (watchedUrl) {
             if (watchedUrl) {
                 this.fetchData(watchedUrl)
             }
         }]
     ]
 }

 async fetchData(url){
     return fetch(url)
         .then(res => res.json())
         .then(data => this.state.fetchedData = data)
 }

 static get state() {
     return {
         fetchedData: null,
         watchedUrl: null
     }
 }

 static get markup(locals, h) {
     return h('.foo', {
         attributes: {
             onclick: locals.$bind('this.state.watchedUrl = "https://mydataendpoint"')
         }
     }, locals.fetchedData ? 'Got data!' : 'No data yet.');
 }

// Will render as '<div class="foo">No data yet.</div>' initially.
// * User click *
// After the resource fetches, markup will rerender as 
// '<div class="foo">Got data!</div>'

Example (For finer-grained control over when the watcher fires, supply a validator function as well.)


Component => class MyComponent extends Component {

 static get watchers() {
     return [
         ['watchedUrl', function (watchedUrl) {
             fetch(watchedUrl)
                .then(res => res.json())
                .then(data => this.fetchedData = data)
         }, (watchedUrl) => watchedUrl && watchedUrl.match(/https:\/\//)]
     ]
 }

 static get state() {
     return {
         fetchedData: null,
         watchedUrl: null
     }
 }

 static get markup(locals, h) {
     return h('.foo', {
         attributes: {
             onclick: locals.$bind('this.state.watchedUrl = Math.random() ? "hey mom" : "https://mydataendpoint"')
         }
     }, locals.fetchedData ? 'Got data!' : 'No data yet.');
 }

// Will render as '<div class="foo">No data yet.</div>' initially.
// * User click *
// Depending on result of die roll, it may or may not fetch data, then render as:
// '<div class="foo">Got data!</div>' But the fetch call won't error!

WeddellComponent.isWeddellComponent

Kind: static property of WeddellComponent
Example

console.log(MyWeddellComponentClass.isWeddellComponent)
// true

Weddell~WeddellStore

Class representing a store of key/value pairs. The store class is primarily used to model application state.

Kind: inner class of Weddell

new WeddellStore(data, opts)

Constructs a store object. One does not generally require or implement the store module directly, but rather implicitly via the various store properties available on components.

weddellStore.watch(key, func, [validator], [invokeImmediately], [onlyFireOnce]) ⇒ RemoveEventListenerCallback

Watches a key or keys in the store, triggering a callback when values change.

Kind: instance method of WeddellStore

CssString : String

A string of valid CSS style declarations.

Kind: global typedef
See: https://developer.mozilla.org/en-US/docs/Web/CSS

HtmlString : String

A string of valid HTML.

Kind: global typedef
See: https://developer.mozilla.org/en-US/docs/Web/HTML

WeddellAppStateSnapshot : Object

A snapshot of a Weddell app. This value is ready for serialization, allowing for later rehydration of application state.

Kind: global typedef
Properties

StoreWatchArgs : Array

Arguments as passed into Store#watch (in the most basic use case, this will be an array with two items: a key and a callback function).

Kind: global typedef

StateTransform ⇒ *

Kind: global typedef

WeddellComponentMixin ⇒ function

Kind: global typedef
Returns: function - Extended class (typically the base class with extensions applied).

CssTemplate ⇒ CssString

Kind: global typedef

DomCreateEvtObj : object

Kind: global typedef
Properties