• Stars
    star
    578
  • Rank 77,250 (Top 2 %)
  • Language
    JavaScript
  • Created almost 9 years ago
  • Updated about 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Small (8kb), batteries-included redux store to reduce boilerplate and promote good habits.

socrates

Small (8kb), batteries-included redux store to reduce boilerplate and promote good habits.

Example

var Store = require('socrates')

// create a store
var store = Store(reducer)

// subscribe to updates
store.subscribe(listener)

// dispatch an action
store('change:user.name', { name: 'an' })

// supports implicit set for the 90% usecase
store('set:user.age', 27)

Installation

npm install socrates

Context

Redux pushed us forward in 2 key ways:

I. Promoting a single state architecture

II. Using an action dispatcher to update that state

The state management in Redux is verbose, but fantastic. Socrates aims to supplement Redux's state management to reduce keystokes and transparently combine a few confusing concepts together. Namely, combineReducer, FSA, redux-actions, and updeep.

Principles

I. State should be separate from the action log (redux middleware)

Socrates is only used to update state. Action dispatching is actually a much bigger part of application architecture than just state. Unfortunately, if you're new to Redux or just reading tutorials, you'll assume that actions are only used to update state.

You should be dispatching actions for all side effects. To make HTTP requests, setup Websockets, and set cookies. While you can do this in Redux's middleware, it's flow is mind-bending because Redux's middleware is synchronous, so you need to internally re-dispatch to achieve asynchronous behavior.

I have a version of middleware inspired by Koa's middleware done on the server that I'll be releasing soon to help you out with this.

II. Changes are always synchronous

Leave the the asynchrony to the action log (redux middleware). State changes that are rejected will throw errors.

III. Enforce a standard action object

Additionally, Socrates enforces that the returned result is a Flux Standard Action, so our actions all have the same format.

This greatly slight constraint goes a long ways towards better interoperability.

IV. All state is frozen (in development)

Wherever you can access state in Socrates it is frozen, or in other words, read-only. This eliminates any possibility of modified references causing unexpected changes to our state.

By freezing state only in development, it steers our code towards the immutable direction without handicapping performance in production.

V. Reducers do not replace state, they update state

In normal redux, reducers replace state. In socrates, they update state.

So instead of replacing your state like this:

function reducer (state, action) {
  return Object.assign({}, state, action.payload)
}

You can simply return a diff:

function reducer (state, action) {
  return { phone: 8675309 }
}

And Socrates will efficiently update the state using code inspired by updeep. To remove a field, you can pass null as the value.

VI. Use reducer trees for modular and efficient reducer functions

Socrates includes an opinionated way to setup reducers, called a reducer tree.

Reducer trees make it very easy to zero in on the reducers you want to operate on the dispatched action. For those of you familiar with redux and it's ecosystem, it's basically as if combineReducers and handleActions had a child, where the functions are the actions and the objects are the state's shape.

Here's an example:

var store = Socrates({
  // run with type: "boot"
  boot(state, action) {
    return action
  },
  user: {
    // run with type: "update user"
    update(state, action) {
      return action
    },
    settings: {
      // run with type: "change user.settings"
      change(state, action) {
        // state & action only contain the relevate data
        // you only need to return an action, because socrates
        // updates, doesn't replace.
        // 3. state = { theme: "red" }
        // 4. action = { theme: "blue" }
        return action
      }
    }
  }
})

// 1. boot up socrates with our initial state
// 2. change the user settings
store(
  {
    type: 'boot',
    payload: {
      user: {
        name: 'matt',
        age: 26,
        settings: {
          theme: 'red'
        }
      }
    }
  },
  {
    type: 'change:user:settings',
    payload: { theme: 'blue' }
  }
})

If you don't like this approach, you can always just pass your custom reducer function into Socrates.

API

store = Socrates(reducer: object|function)

Create a store instance with an optional middleware array and a reducer. If the reducer is an object, it will create a reducer tree.

store(action: mixed, ...): state

Dispatches an action. Dispatching can take on many forms:

// simple object dispatch
socrates({ type: 'name:change', payload: { name: 'an' }})

// using an event emitter style
socrates('change:name', { name: 'an' })

// dispatch multiple object in series
socrates(
  { type: 'change:name', payload: { name: 'an' }},
  { type: 'change:age', payload: { age: 26 }}
)

// dispatch multiple object in parallel
socrates([
  { type: 'change:name', payload: { name: 'an' }},
  { type: 'change:age', payload: { age: 26 }}
])

// using a function to dispatch an action
socrates(function (state) {
  return { type: 'change:age', payload: { age: 26 }}
})

store(): Object

Getting our state. This will be frozen in development

store.subscribe(listener: function)

Subscribe to changes in our store

socrates.subscribe(function (new_state) {
  // ... do something with the new state
})

Test

npm install
make test

License

MIT

More Repositories

1

x-ray

The next web scraper. See through the <html> noise.
JavaScript
5,866
star
2

date

Date() for humans
JavaScript
1,474
star
3

joy

A delightful Go to Javascript compiler (ON HOLD)
Go
1,325
star
4

array

A better array for the browser and node.js. Supports events & many functional goodies.
JavaScript
709
star
5

graph.ql

Faster and simpler way to create GraphQL servers
JavaScript
638
star
6

dots

WIP bootstrapping library for osx & ubuntu (and maybe others!)
Shell
545
star
7

next-cookies

Tiny little function for getting cookies on both client & server with next.js.
JavaScript
369
star
8

coderunner

Run server-side code quickly and securely in the browser.
JavaScript
327
star
9

28kb-react-redux-routing

React + Redux + Routing Stack for just 28kb
JavaScript
245
star
10

vo

Minimalist, yet complete control flow library.
JavaScript
235
star
11

roo

Jump-start your front-end server
JavaScript
104
star
12

component-test

Minimal configuration component test runner supporting browser testing, phantomjs, and saucelabs.
JavaScript
98
star
13

mini-html-parser

Mini HTML parser for webworkers / node. Intended for well-formed HTML.
JavaScript
83
star
14

node-nom

Dead simple site scrapper for Node.js
JavaScript
74
star
15

outliers

Find outliers in a dataset.
JavaScript
56
star
16

next-redirect

Redirect for next.js. Works on both the client and server
JavaScript
52
star
17

try-again

Generic, simple retry module with exponential backoff.
JavaScript
52
star
18

PHPUnit-Test-Report

Browser testing with PHPUnit
PHP
45
star
19

x-ray-crawler

Friendly web crawler for x-ray
JavaScript
44
star
20

pg-bridge

Simple service connecting PostgreSQL notifications to Amazon SNS.
Go
44
star
21

go-datadog

Easily send structured logs to Datadog over TCP.
Go
39
star
22

svg

low-level svg helper
JavaScript
37
star
23

preact-head

Standalone, declarative <Head /> for Preact.
JavaScript
37
star
24

adjust

Position elements next to each other. A light-weight version of HubSpot/tether.
JavaScript
36
star
25

wrap-fn

Low-level wrapper to easily support sync, async, and generator functions.
JavaScript
34
star
26

dom-iterator

Feature-rich, well-tested Iterator for traversing DOM nodes.
JavaScript
34
star
27

normalize-contenteditable

All text in a content-editable block should be wrapped in <p> tag.
JavaScript
34
star
28

ppi

Find the PPI (pixels per inch) of an image.
JavaScript
33
star
29

next-route

Simplified custom routing for next.js.
JavaScript
33
star
30

tipp

Tool tips that just work.
JavaScript
31
star
31

combine-errors

Simple way to combine multiple errors into one.
JavaScript
31
star
32

poss

Slightly better-looking error handling for async/await & generators
JavaScript
28
star
33

autocomplete

Flexible autocomplete component
JavaScript
26
star
34

envobj

Tiny environment variable helper, that I'll use in all my apps.
TypeScript
25
star
35

qr-code

Create QR codes
JavaScript
25
star
36

vcom

Everything you need to create virtual Preact Components with CSS, HTML, and JS.
JavaScript
21
star
37

tiny-store

Tiny immutable store for any value
JavaScript
21
star
38

blocktree

Back to the basics, Hickey-inspired, generic text parser
JavaScript
21
star
39

unmatrix

Parse and normalize the individual values of a css transform
JavaScript
21
star
40

enqueue

seamlessly queue up asynchronous function calls. supports concurrency and timeouts.
JavaScript
20
star
41

string-scanner

scan through strings. supports forwards and backwards scanning.
JavaScript
19
star
42

step.js

My kind of step library. no dependencies. 120 lines of code. 383 lines of tests.
JavaScript
18
star
43

every

human-friendly intervals using http://github.com/matthewmueller/date
JavaScript
17
star
44

json-to-dom

Fill in DOM nodes with JSON. Supports arrays and attributes.
JavaScript
17
star
45

pretty-html

HTML logging that's easy on the eyes.
JavaScript
17
star
46

preact-socrates

preact plugin for socrates.
JavaScript
16
star
47

time-series

simple streaming time series graphs. automatic rescaling as data streams in.
JavaScript
16
star
48

event-debugger

step through events! must be initialized at the top of your scripts.
JavaScript
16
star
49

sun

Simple little virtual DOM node builder for Preact.
JavaScript
15
star
50

x-ray-parse

x-ray's selector parser.
JavaScript
15
star
51

file-pipe

Use gulp plugins on individual files
JavaScript
14
star
52

title-capitalization

Properly capitalize English titles.
JavaScript
14
star
53

atom-standard

An on-save linter and formatter for atom using standard. Supports all the options that standard supports.
JavaScript
14
star
54

express-graph.ql

Express middleware for querying our graphql server built with graph.ql
JavaScript
13
star
55

murmur.js

Small murmur hash implementation.
JavaScript
13
star
56

mergin

Merges files together using a best-effort merge
JavaScript
13
star
57

next-flash

Flash messages for next.js. Works on both the client and the server.
JavaScript
13
star
58

image-search

Pluggable image search
JavaScript
13
star
59

redux-routes

Simple redux history middleware.
JavaScript
13
star
60

io

higher-level engine.io client.
JavaScript
12
star
61

stripe-checkout

Open Stripe Checkout programmatically
JavaScript
12
star
62

remember

Use localstorage to remember input values. Supports textareas and inputs including radio buttons and checkboxes.
JavaScript
12
star
63

internal-old

Internal queue for your public libraries and APIs
JavaScript
11
star
64

preact-rc

Remote control your Preact components
JavaScript
11
star
65

subs

tiny string substitution
JavaScript
10
star
66

lambda-serve

Use koa or express on lambda!
JavaScript
10
star
67

grow

Grow textareas without using a clone or ghost element.
JavaScript
10
star
68

better-error

easier, more colorful, sprintf-style errors
JavaScript
10
star
69

spreadsheet

NOTE: this project is quite old. I won't be maintaining it anymore, but it should still work :-)
JavaScript
10
star
70

debounce

Underscore's debounce method as a component.
JavaScript
10
star
71

typewriter

Animated typing
JavaScript
9
star
72

async-script-promise

Asynchronously load scripts
JavaScript
9
star
73

reverse-regex

flip a regular expression. allows you to efficiently search backwards.
JavaScript
9
star
74

gist

Fluent gist API for node.js.
JavaScript
9
star
75

unyield

allow generators functions to accept callbacks
JavaScript
9
star
76

cheerio-select

Tiny wrapper around FB55's excellent CSSselect library.
JavaScript
9
star
77

terraform-provider-url

Simple little Terraform data source for parsing URLs.
Go
9
star
78

mdb

In-memory key/value store designed for concurrent use
Go
9
star
79

cursors

Collection of Mac's native cursor elements
8
star
80

increment

increment strings. good for keeping slugs unique.
JavaScript
8
star
81

wrapped

Low-level wrapper to provide a consistent interface for sync, async, promises, and generator functions.
JavaScript
8
star
82

yieldly

Conditionally make functions yieldable
JavaScript
8
star
83

events

Stand-alone event bindings as a component based on how Backbone's views handle events.
JavaScript
8
star
84

color

Extremely basic color tinting component
JavaScript
8
star
85

vscode-proofie

Proofie is an experimental proof-reader for VSCode that helps you write better.
TypeScript
8
star
86

plumbing

Pluggable plumbing for your Javascript libraries.
JavaScript
7
star
87

clock

Create a swiss railway inspired clock.
HTML
7
star
88

routematch

simple, functional route matcher for node.js and the browser.
JavaScript
7
star
89

character-iterator

Iterate through text characters in the DOM tree. Handles parent & sibling relationships.
JavaScript
7
star
90

sns.js

Simple publish and parse module for AWS SNS
JavaScript
7
star
91

hex-to-color-name

Tiny module to map hex colors to color names of your choice.
JavaScript
7
star
92

hackernews

Go
7
star
93

css-to-js-object

Experimental: convert css to a JS object.
JavaScript
7
star
94

number-to-letter

Simple utility to convert an arbitrary number to a letter
JavaScript
7
star
95

rework-count

Rework plugin to style elements based on the sibling count.
JavaScript
6
star
96

arg-deps

Statically inspect a function to get the properties of its arguments. Works with minified code.
JavaScript
6
star
97

extend.js

extend objects. extend(obj, obj2, ...)
JavaScript
6
star
98

invisibles

make spaces visible
JavaScript
6
star
99

email

fluent email using sendmail
JavaScript
6
star
100

coderunner-api

API for coderunner
JavaScript
6
star