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

immutable-core-model-view

v0.7.0

Published

Model views for use with immutable-core-model

Downloads

31

Readme

immutable-core-model-view

ImmutableCoreModelView provides a class for creating and managing Model Views for use with Immutable Core Model.

Simple model views allow model results to be formatted or summarized for further processing or display.

ImmutableCoreModelView provides only the methods for creating and managing model views and is dependent on the execution engine provided by immutable-core-model for applying model view operations to models.

Native async/await

Immutable Core Model View requires Node.js v7.6.0 or greater with native async/await support.

Creating a simple model view

// create model view constuctor
var FooModelView = new ImmutableCoreModelView({
    each: function (modelView, record) {
        record.foo = true
    },
    name: 'foo',
    type: 'record',
})

// create model view instance
var fooModelView = FooModelView()

Calling new ImmutableCoreModelView returns a function that can then be called to created individual model view instances.

More complex model views will have options, such as properties to apply to, which can differ between instances.

In this simple example FooModelView has no options so every instance will be the same.

When the fooModelView instance is applied to an immutable-core-model result set the each function will be execute for every record in the result set.

Model views are synchronous by default and asynchronous model views have a different interface.

This example is a synchronous model view and so the arguments for the each function are: the model view instance, the record object to operate on, the number of the object in the result set, and the context object provided by the result set iterator which is shared between all invocations of each.

For synchronous model views the each function must make any desired changes to the record object that is passed to it and any return value will be ignored.

By default when a synchronous model view is created the each function, and optional post and pre functions, will be created as immutable-core functions. This can be disabled by setting the immutable: false option.

Creating an asynchronous model view

var FooModelView = new ImmutableCoreModelView({
    each: function (args) {
        var modelView = args.modelView
        var record = args.record

        return {
            foo: true,
        }
    },
    name: 'foo',
    synchronous: false,
    type: 'record',
})

Asynchronous model views are created as immutable-core modules by default and follow immutable-core semantics.

All of the same arguments that are passed to the each function with a synchronous model view will be passed as named properties to a single args object for asynchronous model views.

Because the args to an immutable-core method are immutable the record passed to an an asynchronous each function cannot be modified.

For type: 'record' asynchronous model views the value returned by the each function will be merged over the original record value.

If multiple asynchronous model views are applied to a single result set then their each methods will be applied concurrently while operating on the same record.

Type: collection vs. record

There are two fundamental types of model views: collection views and record views.

Record views can modify each record in a result set but each modified record will be returned.

Collection views are applied to each record in a result set but only a single object with the summary results is returned at the end.

Collection views can perform summaries of large record sets or format record sets - e.g. transform an array of records into object keyed by property.

Record view functions can be executed in parallel and out-of-order by default while collection view functions are executed sequentially by default.

Collection views have access to a context object and a number that identifies the position of the record in the result set. Record views do not.

Collection views have optional post and pre functions that can be used to initialize and finalize the context. Record views do not.

Creating a collection model view to sum values

// create model view constuctor
var SumModelView = new ImmutableCoreModelView({
    each: function (modelView, record, number, context) {
        // add value for each property to sum
        _.each(modelView.properties, property => {
            // skip non-numbers
            if (typeof record[property] !== 'number') {
                return
            }
            // add value to sum
            context.sum[property] += record[property]
        })
    },
    name: 'sum',
    pre: function (modelView) {
        // create context
        var context = {
            sum: {}
        }
        // get the properties that model view applies to which were
        // passed as arguments to the constuctor (e.g. foo, bar)
        _.each(modelView.properties, property => {
            // initalize sum for each property to zero
            context.sum[property] = 0
        })
        // return context which will be passed to each
        return context
    },
    type: 'record',
})

Creating a sum model view instance

var sumModelView = SumModelView('foo', 'bar')

In this example the pre function will be executed before applying the each function to any records. The object returned by the pre function will be used as the context that is passed to the each function for each record.

The result of the sum model view is the context object which contains a sum object with the sums for each property.

Creating another sum model view instance

var sumModelView = SumModelView('bam', 'baz')

Different instances of the sum model view can be created depending on which columns need to be summed.

Creating a model view to sum values in parallel

// create model view constuctor
var SumModelView = new ImmutableCoreModelView({
    each: function (modelView, record, number, context) {
        ...
    },
    name: 'sum',
    post: function (modelView, contexts) {
        // create result object that will be returned with final sum
        var result = {
            sum: {}
        }
        // initalize sum for each property to zero
        _.each(modelView.properties, property => {
            result.sum[property] = 0
        })
        // sum values from all contexts
        _.each(contexts, context => {
            _.each(context.sum, (val, property) => {
                result.sum[property] += val
            })
        })
        // return result which is sum of sums from multiple contexts
        return result
    },
    pre: function (modelView) {
        ...
    },
    sequential: false,
    type: 'record',
})

In this example the each and pre functions are the same as the example above but with the sequential: false option set the execution engine can execute each functions out-of-order and in parallel.

When sequential: false is set the return value for the view will be an array of one or more contexts unless a post function is specified.

The post function takes an array of contexts and performs additional operations, in this case to create a single object return value with the sums for all contexts.

Model View Options

Option Name | Type | Description | --------------|---------|--------------------------------------------| allowOverride | boolean | allow redefining model view with same name | cache | boolean | set to false to disable view caching | immutable | boolean | create immutable function/module/methods | meta | boolean | each function gets record with meta data | name | string | name of model view | register | boolean | add model view to global register by name | sequential | boolean | execute each functions in order | synchronous | boolean | each function is async | type | string | collection | record |

Model View Functions

Function Name | Description | --------------|---------------------------------------------------------| each | called once for each record in result set | post | called once after all each calls (collection view only) | pre | called once before each calls (collection view only) |