Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

satcheljs

Package Overview
Dependencies
Maintainers
3
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

satcheljs - npm Package Compare versions

Comparing version 2.14.1 to 3.0.0-beta2

lib/actionCreator.d.ts

5

lib/applyMiddleware.d.ts

@@ -1,5 +0,2 @@

import ActionContext from './ActionContext';
import ActionFunction from './ActionFunction';
import Middleware from './Middleware';
import Middleware from './interfaces/Middleware';
export default function applyMiddleware(...middleware: Middleware[]): void;
export declare function dispatchWithMiddleware(action: ActionFunction, actionType: string, args: IArguments, actionContext: ActionContext): void;

22

lib/applyMiddleware.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dispatcher_1 = require("./dispatcher");
var globalContext_1 = require("./globalContext");

@@ -8,23 +10,11 @@ function applyMiddleware() {

}
var next = finalDispatch;
var next = dispatcher_1.finalDispatch;
for (var i = middleware.length - 1; i >= 0; i--) {
next = applyMiddlewareInternal(middleware[i], next);
next = applyNextMiddleware(middleware[i], next);
}
globalContext_1.getGlobalContext().dispatchWithMiddleware = next;
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = applyMiddleware;
function applyMiddlewareInternal(middleware, next) {
return function (action, actionType, args, actionContext) { return middleware(next, action, actionType, args, actionContext); };
function applyNextMiddleware(middleware, next) {
return function (actionMessage) { return middleware(next, actionMessage); };
}
function dispatchWithMiddleware(action, actionType, args, actionContext) {
if (!globalContext_1.getGlobalContext().dispatchWithMiddleware) {
globalContext_1.getGlobalContext().dispatchWithMiddleware = finalDispatch;
}
globalContext_1.getGlobalContext().dispatchWithMiddleware(action, actionType, args, actionContext);
}
exports.dispatchWithMiddleware = dispatchWithMiddleware;
function finalDispatch(action, actionType, args, actionContext) {
return action();
}
//# sourceMappingURL=applyMiddleware.js.map

@@ -1,1 +0,1 @@

export default function createStore<T>(key: string, initialState: T): T;
export default function createStore<T>(key: string, initialState: T): () => T;
"use strict";
var rootStore_1 = require("./rootStore");
var action_1 = require("./action");
var internalCreateStore = function internalCreateStore(key, initialState) {
rootStore_1.default.set(key, initialState);
};
internalCreateStore = action_1.default("createStore")(internalCreateStore);
Object.defineProperty(exports, "__esModule", { value: true });
var mobx_1 = require("mobx");
var getRootStore_1 = require("./getRootStore");
var createStoreAction = mobx_1.action('createStore', function createStoreAction(key, initialState) {
getRootStore_1.default().set(key, initialState);
});
function createStore(key, initialState) {
internalCreateStore(key, initialState);
return rootStore_1.default.get(key);
createStoreAction(key, initialState);
return function () { return getRootStore_1.default().get(key); };
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = createStore;
;
//# sourceMappingURL=createStore.js.map
import { ObservableMap } from 'mobx';
import ActionContext from './ActionContext';
import ActionFunction from './ActionFunction';
import ActionMessage from './interfaces/ActionMessage';
import DispatchFunction from './interfaces/DispatchFunction';
import Subscriber from './interfaces/Subscriber';
import ActionContext from './legacy/ActionContext';
import ActionFunction from './legacy/ActionFunction';
export interface GlobalContext {
schemaVersion: number;
inDispatch: number;
rootStore: ObservableMap<any>;
dispatchWithMiddleware: (action: ActionFunction, actionType: string, args: IArguments, actionContext: ActionContext) => Promise<any> | void;
testMode: boolean;
strictMode: boolean;
nextActionId: number;
subscriptions: {
[key: string]: Subscriber<ActionMessage>[];
};
dispatchWithMiddleware: DispatchFunction;
legacyInDispatch: number;
legacyDispatchWithMiddleware: (action: ActionFunction, actionType: string, args: IArguments, actionContext: ActionContext) => Promise<any> | void;
legacyTestMode: boolean;
}

@@ -12,0 +19,0 @@ export declare function __resetGlobalContext(): void;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var mobx_1 = require("mobx");
var schemaVersion = 2;
// A reset global context function to be used INTERNALLY by SatchelJS tests and for initialization ONLY
var schemaVersion = 3;
function __resetGlobalContext() {
global.__satchelGlobalContext = {
schemaVersion: schemaVersion,
inDispatch: 0,
rootStore: mobx_1.map({}),
nextActionId: 0,
subscriptions: {},
dispatchWithMiddleware: null,
testMode: false,
strictMode: true
legacyInDispatch: 0,
legacyDispatchWithMiddleware: null,
legacyTestMode: false,
};

@@ -18,3 +20,3 @@ }

if (schemaVersion != global.__satchelGlobalContext.schemaVersion) {
throw new Error("Detected incompatible SatchelJS versions loaded.");
throw new Error('Detected incompatible SatchelJS versions loaded.');
}

@@ -27,4 +29,2 @@ }

exports.getGlobalContext = getGlobalContext;
;
// Side Effects: actually initialize the global context if it is undefined
if (!global.__satchelGlobalContext) {

@@ -36,2 +36,1 @@ __resetGlobalContext();

}
//# sourceMappingURL=globalContext.js.map

@@ -1,14 +0,16 @@

export { default as rootStore } from './rootStore';
export { default as initializeState } from './initializeState';
import { useStrict } from 'mobx';
export { default as ActionCreator } from './interfaces/ActionCreator';
export { default as ActionMessage } from './interfaces/ActionMessage';
export { default as DispatchFunction } from './interfaces/DispatchFunction';
export { default as Middleware } from './interfaces/Middleware';
export { default as Subscriber } from './interfaces/Subscriber';
export { actionCreator, boundActionCreator } from './actionCreator';
export { default as applyMiddleware } from './applyMiddleware';
export { default as Middleware } from './Middleware';
export { default as ActionFunction } from './ActionFunction';
export { default as ActionContext } from './ActionContext';
export { default as DispatchFunction } from './DispatchFunction';
export { default as createStore } from './createStore';
export { default as action } from './action';
export { default as select, SelectorFunction } from './select';
export { default as createUndo, UndoResult, CreateUndoReturnValue } from './createUndo';
export { getActionType } from './functionInternals';
export { initializeTestMode, resetTestMode } from './testMode';
export { useStrict } from './useStrict';
export { dispatch } from './dispatcher';
export { default as initializeState } from './initializeState';
export { default as mutator } from './mutator';
export { default as orchestrator } from './orchestrator';
export { default as getRootStore } from './getRootStore';
export { simpleMutator, simpleOrchestrator } from './simpleSubscribers';
export { useStrict };
"use strict";
var rootStore_1 = require("./rootStore");
exports.rootStore = rootStore_1.default;
var initializeState_1 = require("./initializeState");
exports.initializeState = initializeState_1.default;
Object.defineProperty(exports, "__esModule", { value: true });
var mobx_1 = require("mobx");
exports.useStrict = mobx_1.useStrict;
var actionCreator_1 = require("./actionCreator");
exports.actionCreator = actionCreator_1.actionCreator;
exports.boundActionCreator = actionCreator_1.boundActionCreator;
var applyMiddleware_1 = require("./applyMiddleware");

@@ -10,15 +12,15 @@ exports.applyMiddleware = applyMiddleware_1.default;

exports.createStore = createStore_1.default;
var action_1 = require("./action");
exports.action = action_1.default;
var select_1 = require("./select");
exports.select = select_1.default;
var createUndo_1 = require("./createUndo");
exports.createUndo = createUndo_1.default;
var functionInternals_1 = require("./functionInternals");
exports.getActionType = functionInternals_1.getActionType;
var testMode_1 = require("./testMode");
exports.initializeTestMode = testMode_1.initializeTestMode;
exports.resetTestMode = testMode_1.resetTestMode;
var useStrict_1 = require("./useStrict");
exports.useStrict = useStrict_1.useStrict;
//# sourceMappingURL=index.js.map
var dispatcher_1 = require("./dispatcher");
exports.dispatch = dispatcher_1.dispatch;
var initializeState_1 = require("./initializeState");
exports.initializeState = initializeState_1.default;
var mutator_1 = require("./mutator");
exports.mutator = mutator_1.default;
var orchestrator_1 = require("./orchestrator");
exports.orchestrator = orchestrator_1.default;
var getRootStore_1 = require("./getRootStore");
exports.getRootStore = getRootStore_1.default;
var simpleSubscribers_1 = require("./simpleSubscribers");
exports.simpleMutator = simpleSubscribers_1.simpleMutator;
exports.simpleOrchestrator = simpleSubscribers_1.simpleOrchestrator;
mobx_1.useStrict(true);

@@ -1,2 +0,4 @@

declare let initializeState: (initialState: any) => void;
export default initializeState;
declare const _default: (initialState: {
[key: string]: any;
}) => void;
export default _default;
"use strict";
var rootStore_1 = require("./rootStore");
var action_1 = require("./action");
// initializeState can be used to completely replace the existing state object, e.g. to restore
// the stores from a serialized value or to provide a clean starting state for test cases.
var initializeState = function initializeState(initialState) {
rootStore_1.default.clear();
rootStore_1.default.merge(initialState);
};
initializeState = action_1.default("initializeState")(initializeState);
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = initializeState;
//# sourceMappingURL=initializeState.js.map
var mobx_1 = require("mobx");
var getRootStore_1 = require("./getRootStore");
exports.default = mobx_1.action('initializeState', function initializeState(initialState) {
var rootStore = getRootStore_1.default();
rootStore.clear();
rootStore.merge(initialState);
});
{
"name": "satcheljs",
"version": "2.14.1",
"version": "3.0.0-beta2",
"description": "Store implementation for functional reactive flux.",
"main": "./lib/index.js",
"lint-staged": {
"*.{ts,tsx}": [
"prettier --tab-width 4 --print-width 100 --write --trailing-comma es5 --jsx-bracket-same-line --single-quote",
"git add"
]
},
"scripts": {
"copy-project-files": "node ../../tools/copy-project-files.js",
"build": "npm run copy-project-files && node ../../node_modules/typescript/lib/tsc.js",
"start": "npm run copy-project-files && node ../../node_modules/typescript/lib/tsc.js -w",
"test": "node ../../node_modules/jasmine/bin/jasmine.js JASMINE_CONFIG_PATH=jasmine.json --verbose"
"precommit": "lint-staged",
"clean": "rimraf build lib",
"lint": "tslint -t stylish --project tsconfig.json",
"build:source": "tsc -p tsconfig.release.json",
"watch": "tsc -w -p tsconfig.release.json",
"test:unit": "jest",
"build": "run-s clean build:source",
"start": "run-s clean watch",
"test": "run-s lint test:unit",
"test:start": "jest --watch"
},
"author": "Scott Mikula <smikula@microsoft.com>",
"license": "MIT",
"dependencies": {
"mobx": "~2.6.5"
},
"devDependencies": {
"jasmine": "~2.4.1",
"typescript": "~1.8.9"
"@types/enzyme": "2.8.1",
"@types/jasmine": "~2.5.53",
"@types/jsdom": "^11.0.1",
"@types/node": "~6.0.78",
"@types/react": "15.0.37",
"@types/react-addons-perf": "~0.14.18",
"@types/react-addons-test-utils": "~0.14.19",
"@types/react-dom": "~15.5.1",
"enzyme": "^2.9.1",
"husky": "~0.14.3",
"jasmine": "^2.6.0",
"jest": "20.0.4",
"lint-staged": "~4.0.1",
"npm-run-all": "^4.0.2",
"prettier": "~1.5.2",
"react-test-renderer": "^15.6.1",
"rimraf": "^2.5.4",
"tslint": "~5.5.0",
"tslint-eslint-rules": "~4.1.1",
"tslint-microsoft-contrib": "~5.0.1",
"typescript": "~2.3.4"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/satcheljs"
"dependencies": {
"mobx": "~2.6.5",
"mobx-react": "~4.0.3",
"mobx-react-devtools": "~4.2.10",
"react": "^15.6.1",
"react-addons-perf": "^15.4.2",
"react-dom": "^15.6.1"
},
"typings": "./lib/index.d.ts",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"publishConfig": {
"registry": "https://registry.npmjs.org/"
"registry": "https://registry.npmjs.org"
}
}
}

@@ -1,7 +0,6 @@

[![Build Status](https://travis-ci.org/Microsoft/satcheljs.svg?branch=master)](https://travis-ci.org/Microsoft/satcheljs)
# Satchel
Satchel is a data store based on the [Flux architecture](http://facebook.github.io/react/blog/2014/05/06/flux.html). It is characterized by exposing an observable state that makes view updates painless and efficient.
Satchel is a dataflow framework based on the [Flux architecture](http://facebook.github.io/react/blog/2014/05/06/flux.html). It is characterized by exposing an observable state that makes view updates painless and efficient.
[![Build Status](https://travis-ci.org/Microsoft/satcheljs.svg?branch=master)](https://travis-ci.org/Microsoft/satcheljs)

@@ -11,10 +10,10 @@ ## Influences

Satchel is an attempt to synthesize the best of several dataflow patterns typically used to drive a React-based UI. In particular:
* [Flux](http://facebook.github.io/react/blog/2014/05/06/flux.html) is not a library itself, but is a dataflow pattern conceived for use with React. In Flux, dataflow is unidirectional, and the only way to modify state is by dispatching actions through a central dispatcher.
* [Redux](http://redux.js.org/index.html) is an implementation of Flux that consolidates stores into a single state tree and attempts to simplify state changes by making all mutations via pure functions called reducers. Ultimately, however, we found that reducers and immutable state were difficult to reason about, particularly in a large, interconnected app.
* [Redux](http://redux.js.org/index.html) is an implementation of Flux that consolidates stores into a single state tree and attempts to simplify state changes by making all mutations via pure functions called reducers. Ultimately, however, we found reducers and immutable state cumbersome to deal with, particularly in a large, interconnected app.
* [MobX](http://mobxjs.github.io/mobx/index.html) provides a seamless way to make state observable, and allows React to listen to state changes and rerender in a very performant way. Satchel uses MobX under the covers to allow React components to observe the data they depend on.
## Advantages
There are a number of advantages to using Satchel to maintain your application state. (Each of the frameworks above has some, but not all, of these qualities.)
There are a number of advantages to using Satchel to maintain your application state:

@@ -24,6 +23,6 @@ * Satchel enables a very **performant UI**, only rerendering the minimal amount necessary. MobX makes UI updates very efficient by automatically detecting specifically what components need to rerender for a given state change.

* Satchel supports **middleware** that can act on each action that is dispatched. (For example, for tracing or performance instrumentation.)
* Satchel requires **minimal boilerplate** code.
* Satchel is **type-safe** out of the box, without any extra effort on the consumer's part.
## Installation
## Installation
Install via NPM:

@@ -39,18 +38,15 @@

## Usage
## Usage
The following examples assume you're developing in Typescript.
### Create a store with some initial state
```typescript
interface MyStoreSchema {
foo: number;
bar: string;
}
import { createStore } from 'satcheljs';
var myStore = createStore<MyStoreSchema>(
"mystore",
var store = createStore(
'scoreboardStore',
{
foo: 1,
bar: "baz"
score: 0
});

@@ -60,66 +56,118 @@ ```

### Create a component that consumes your state
Notice the @observer decorator on the component---this is what tells MobX to rerender the component if any of the data it relies on changes.
```typescript
Notice the `@observer` decorator on the component—this is what tells MobX to rerender the component whenever the data it relies on changes.
```javascript
@observer
class ApplicationComponent extends React.Component<any, any> {
render() {
return (<div>foo is {myStore.foo}</div>);
}
render() {
return (<div>Score = {store.score}</div>);
}
}
```
### Implement an action to update the store
### Implement an action creator
```typescript
let updateFoo =
function updateFoo(newFoo: number) {
myStore.foo = newFoo;
};
import { actionCreator } from 'satcheljs';
updateFoo = action("updateFoo")(updateFoo);
let addPoints = actionCreator('ADD_POINTS',
(points: number) => ({
points: points
}));
```
Note that the above is just syntactic sugar for applying an @action decorator. Typescript doesn't support decorators on function expressions yet, but it will in 2.0. At that point the syntax for creating an action will be simply:
### Implement a mutator
You specify what action a mutator subscribes to by providing the corresponding action creator.
If you're using TypeScript, the type of `actionMessage` is automatically inferred.
```typescript
let updateFoo =
@action("updateFoo")
function updateFoo(newFoo: number) {
myStore.foo = newFoo;
};
import { mutator } from 'satcheljs';
mutator(addPoints, (actionMessage) => {
store.score += actionMessage.points;
};
```
### Call the action
### Create and dispatch an action
It's just a function:
```typescript
import { dispatch } from 'satcheljs';
dispatch(addPoints(2));
```
### Bound action creators
Bound action creators create and dispatch the action in one call.
Also notice that if the action doesn't need any arguments then you don't need to supply an action creator function.
```typescript
updateFoo(2);
import { boundActionCreator } from 'satcheljs';
let resetScore = boundActionCreator('RESET_SCORE');
// This dispatches a RESET_SCORE action. Of course, you'd still need a mutator
// to subscribe to it to update the store.
resetScore();
```
### Asynchronous actions
### Orchestrators
Often actions will need to do some sort of asynchronous work (such as making a server request) and then update the state based on the result.
Since the asynchronous callback happens outside of the context of the original action the callback itself must be an action too.
(Again, this syntax will be simplified once Typescript 2.0 is available.)
Orchestrators are like mutators—they subscribe to actions—but they serve a different purpose.
While mutators modify the store, orchestrators are responsible for side effects.
Side effects might include making a server call or even dispatching further actions.
The following example shows how an orchestrator can persist a value to a server before updating the store.
```typescript
let updateFooAsync =
function updateFooAsync(newFoo: number) {
// You can modify the state in the original action
myStore.loading = true;
import { boundActionCreator, orchestrator } from 'satcheljs';
// doSomethingAsync returns a promise
doSomethingAsync().then(
action("doSomethingAsyncCallback")(
() => {
// Modify the state again in the callback
myStore.loading = false;
myStore.foo = newFoo;
}));
};
let requestAddPoints = boundActionCreator('REQUEST_ADD_POINTS',
(points: number) => ({
}));
updateFooAsync = action("updateFooAsync")(updateFooAsync);
orchestrator(requestAddPoints, (actionMessage) => {
updatePointsOnServer(store.score + actionMessage.points)
.then((response) => {
if (response.result == 200) {
addPoints(actionMessage.points);
}
});
};
```
### Simple mutators and orchestrators
In many cases a given action only needs to be handled by one mutator.
Satchel provides the concept of a simple mutator which ecapsulates action creation, dispatch, and handling in one simple function call.
The `addPoints` mutator above could be implemented as follows:
```typescript
let addPoints = simpleMutator(
'addPoints',
function addPoints(points: number) {
store.score += points;
});
```
Simple orchestrators can be created similarly:
```typescript
let requestAddPoints = simpleOrchestrator(
'requestAddPoints',
function requestAddPoints(points: number) {
.then((response) => {
if (response.result == 200) {
addPoints(points);
}
});
});
```
These simple mutators and orchestrators are succinct and easy to write, but they come with a restriction:
the action creator is not exposed, so no other mutators or orchestrators can subscribe to it.
If an action needs multiple handlers then it must use the full pattern with action creators and handlers implemented separately.
## License - MIT

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc