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

samjs

v0.4.0

Published

Created to connect **S**ocket.io, **A**ngularJS and **M**ongoDB.

Downloads

19

Readme

SAM.js

Created to connect Socket.io, AngularJS and MongoDB.

Now it is database and view framework agnostic, leaving a socket.io framework.

Browser client: samjs-client

Features

  • only websockets
  • plugable
  • useful defaults
  • multiple databases simultaniously

data modeling

  • options
    source-code-based / kept-in-memory data. Used to set low-level options of the app, can only be changed by restarting. Not accessible due websockets.

  • configs
    file-based / kept-in-memory data For structural data specific for your app, should be only changed sparsely by few persons.

  • models
    Can be custom in-memory models or plugable database-based models. Should be used for all data which changes on regular basis.

Getting Started

npm install --save samjs
npm install --save-dev samjs-client

Simple example with koa server

samjs = require "samjs"
koa = require("koa")()

server = require("http").createServer(koa.callback())

samjs
.plugins()
.options()
.configs({name:"item"})
.models()
.startup(server)

server.listen(3000)
#to close
#samjs.shutdown()

// in browser with e.g. webpack
samjs = require("samjs-client")()
samjs.config.set("item", "value")
.then(function(){
  //success
})
.catch(function(){
  //failure
})
// some other client  
samjs.config.on("item",function(){
  //item changed
  samjs.config.get("item")
  .then(function(response){
    response == "value" // true
  })
  .catch(function(){
    //failure
  })
}

Available plugins

Name | Description ---: | --- samjs-auth | adds a configs-based user management, authentification mechanismen and authorization system for configs. samjs-files | adds a model and interface for file/folder interaction samjs-files-auth | adds authorization for samjs-files samjs-mongo | adds a model and interface for mongodb interaction samjs-mongo-auth | adds authorization for samjs-mongo samjs-auth-mongo | moves user management to mongodb. Adds groups. samjs-mongo-isOwner | Plugin for managing user owned documents in samjs-mongo.

docs

Samjs is configured by several functions which must be called in order. Startup order:

samjs.plugins().options().configs().models().startup().io.listen(8080)

Function: plugins

takes one or more plugin objects or an array of plugin objects. Returns samjs.

samjs.plugins(require("samjs-files"),require("samjs-auth"))
// or
samjs.plugins([require("samjs-files"),require("samjs-auth")])

See plugin api for detailed information to write your own plugin

Function: options

takes a options object to overwrite the default values. Returns samjs.

// only default in core is samjs.options.config == "config.json"
// to overwrite:
samjs.options({config:"settings.json"})

Function: configs

takes one or more config objects or an array of config objects. Returns samjs.

samjs.configs({name:"paths"},{name:"users"})
// or
samjs.configs([{name:"paths"},{name:"users"}])

Props of a config object:

| Name | type | default | description | | ---:| --- | ---| --- | | name | String | - | (required) name of the config object. To access the config object after setup :samjs.configs[name]| | access | Object | {read:false,write:false} | allowes to access this config value by client | | test | Function | - | Function to test values for validity. Must return a promise which resolves on success and rejects on error. | | isRequired | Boolean | false | includes this config object in configuration phase. (see lifecycle) | | hooks | Object | - | functions to get called on specific interactions with this config object. |

actions:

After setup, each config object has 3 available actions: set,get,test. Each has a server-side version: _set,_get,_test, which are not checking for authentification.

hooks:

hooks are functions which are called on specific actions. They always have to return their arguments.

| Name | arguments | description | | ---:| ---| --- | | beforeCreate | options | manipulate the options object before creation | | afterCreate | options | manipulate the options object after creation | | beforeSet | {data, socket} | used to authenticate a set request | | before_Set | {data, oldData} | used to manipulate a set request | | afterSet | {data, oldData, socket} | called after a successfull set request from client | | after_Set | {data, oldData} | called after each successfull set request | | beforeGet | {socket} | used to authenticate a get request | | after_Get | data | called after a successfull _get request | | afterGet | {data, socket} | called after a successfull get request from client | | beforeTest | {data, socket} | used to authenticate a test request | | afterTest | {data, socket} | called after a successfull test request from client |

example (how samjs-auth basically works):

samjs.configs({name:"paths", hooks: {
  beforeSet: function(obj) {
    if (obj.client.auth != null
      && obj.client.auth.user != null
      && obj.client.auth.user.username == "root") {
        return obj
    }
    throw new Error "no permission"
  }}
})

Function: models

takes one or more model objects or an array of model objects. Returns samjs.

samjs.models(model1,model2)
// or
samjs.models([model1,model2])

Props of a model object:

| Name | type | default | description | | ---:| --- | ---| --- | | name | String | - | (required) name of the model object. To access the model object after setup :samjs.models[name]| | interfaces | Object or array| - | see below. | | isRequired | Boolean | false | includes this model object in installation phase. (see lifecycle) | | installInterface | Function | - | a socket.io interface which is used in installation phase if isRequired is true (see installInterface) | | test | Function | - | a function to test if installation requirement is met, if isRequired is true | | db | String | - | use a model-structure and interface from a plugin|

interfaces

Interfaces can be either a array or a key-value store

// all interfaces in an array will listen one the "someModel" socket.io namespace
samjs.models({
  name: "someModel"
  value: "someValue"
  interfaces: [
    // will be in the "someModel" socket.io namespace
    function(socket){
      var model = this
      // model.name == "someModel" // true
      socket.on("get",function(request){
        if (request.token != null){
          socket.emit("get."+.request.token,{success:true, content:model.value})
        }
      })
    }
  ]
  })
// if you need to use another namespace use an object instead
samjs.models({
  name: "someModel"
  interfaces: {
    // either provide a single interface or a array of interfaces
    // will be in the "someOtherNamespace" socket.io namespace
    someOtherNamespace: function(socket){ //doSomething }
  }
  })

installInterface

samjs.models({
  name: "someModel"
  installInterface: function(socket){
    var model = this # will be bound to model instance
    # will be in the 'install' socket-io namespace, specific listeners are required
    socket.on "someModel.set", function(request) =>
      if (request.token != null && request.content != null){
        # no authentification, will be only accessible in install mode
        model.test(request.content)
        .then(function(value){model.value = value})
        .then(function(value){return {success:true, content: value}}
        .catch(function(e){return {success:false, content: e.message}}
        .then(function(response){
          socket.emit("boilerplate.set."+request.token, response)
          if(response.success){
            samjs.state.checkInstalled() # will trigger a check if installation is finished
            }
          }
        }
    # must return a dispose function
    return function(){socket.removeAllListeners("someModel.set")}
  }
})

Function: startup

takes a optional httpServer, returns samjs.

samjs.startup(someServer)
someServer.listen(8080)
// or
samjs.startup()
samjs.io.listen(8080)

Function: shutdown

returns samjs. Shuts samjs and socket.io down.

Function reset

returns samjs. Resets samjs instance. Useful for unit testing.

Lifecycle

samjs emits several events during its lifecycle:

example:

samjs.once("options",function(){console.log("options got called")})

Synchronous (configuration / after startup)

Name | Description ---: | --- beforePlugins | emitted before samjs.plugins() is executed plugins | emitted after samjs.plugins() is executed beforeOptions | emitted before samjs.options() is executed options | emitted after samjs.options() is executed beforeConfigs | emitted before samjs.configs() is executed configs | emitted after samjs.configs() is executed beforeModels | emitted before samjs.models() is executed models | emitted after samjs.models() is executed beforeStartup | emitted before samjs.startup() is executed startup | emitted after samjs.startup() is executed beforeShutdown | emitted before samjs.shutdown() is executed shutdown | emitted after samjs.shutdown() is executed beforeReset | emitted before samjs.reset() is executed reset | emitted after samjs.reset() is executed

Asynchronous (startup)

samjs.startup works like this:

Is samjs configured? (all configs with `isRequired` are set properly)
- start configuration if not
Execute all `startup` functions of all plugins
Execute all `startup` functions of all models
Is samjs installed? (all models with `isRequired` are set properly)
- start installation if not
expose all socket.io interfaces

Events:

Name | Description ---: | --- beforeConfigure | emitted before configuration is set up and ready configure | emitted after configuration is set up and ready configured | emitted after configuration is done or when no configuration was necessary beforeInstall | emitted before installation is set up and ready install | emitted after installation is set up and ready installed | emitted after installation is done or when no installation was necessary started | emitted when samjs is properly started up

There are additional state promises which will fullfill once a state is reached:

Name | Description ---: | --- onceConfigure | fullfilled once in configuration mode onceConfigured | fullfilled once configuration is finished onceInstall | fullfilled once in installation mode onceInstalled | fullfilled once installation is finished onceStarted | fullfilled once samjs is properly started up onceConfigureOrInstall | fullfilled once in configuration or installation mode

example

samjs.state.onceStarted.then(function(){
  // do something
  })

Plugin api

see source code of samjs-plugin-boilerplate for a complete plugin api