New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

fxapp

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fxapp - npm Package Compare versions

Comparing version 0.4.0 to 0.5.0

0

LICENSE.md

@@ -0,0 +0,0 @@ Copyright © 2018-present Wolfgang

21

package.json
{
"name": "fxapp",
"description": "Build JavaScript server apps using effects as data",
"version": "0.4.0",
"version": "0.5.0",
"main": "./src/index.js",

@@ -10,9 +10,9 @@ "files": [

"devDependencies": {
"eslint": "=6.7.2",
"jest": "=24.9.0",
"nodemon": "=2.0.2",
"prettier": "=1.19.1"
"eslint": "=7.3.0",
"jest": "=26.0.1",
"nodemon": "=2.0.4",
"prettier": "=2.0.5"
},
"scripts": {
"clean": "npx rimraf coverage dist node_modules",
"clean": "npx --ignore-existing --quiet rimraf coverage dist node_modules",
"format": "prettier --ignore-path .gitignore --write \"**/*.js\"",

@@ -24,5 +24,10 @@ "format:check": "prettier --ignore-path .gitignore --list-different \"**/*.js\"",

"check": "npm run format:check && npm run lint && npm t",
"prepare": "npm run check",
"release": "./pre-flight-tests && npm run clean && git pull && npm i && git tag $npm_package_version && git push && git push --tags && npm publish"
"release:dry": "npm run clean && npm i && npm run check",
"release": "node pre-flight-tests && npm run release:dry && git tag $npm_package_version && git push && git push --tags && npm publish"
},
"prettier": {
"endOfLine": "auto",
"trailingComma": "none",
"arrowParens": "avoid"
},
"eslintConfig": {

@@ -29,0 +34,0 @@ "extends": "eslint:recommended",

@@ -67,2 +67,3 @@ # FX App

// GET /path/other/123
// { request: { params: { id: "123" } } }
$id: otherAction

@@ -184,4 +185,6 @@ }

```js
StateUpdate = function(state: Object) => newState: Object
StateUpdate = function(state: Object, props: Object) => newState: Object
StateUpdateWithProps = [StateUpdate, props: Object]
ReservedProps = {

@@ -205,3 +208,5 @@ concurrent: boolean? = false,

Dispatchable = StateUpdate | FX | [Dispatchable]
FXWithProps = [FX, props: Object]
Dispatchable = StateUpdate | StateUpdateWithProps | FX | FXWithProps | [Dispatchable]
```

@@ -211,11 +216,11 @@

Perform an immutable state update by receiving the current state as a parameter and returning the new state. Automatically shallow merges root properties in addition to one level under `request` and `response`.
Perform an immutable state update by receiving the current state as a parameter and returning the new state. Automatically shallow merges root properties in addition to one level under `request` and `response`. Optional `props` may be passed at the time of dispatch using a tuple represented as an array of `[stateMapping, props]`.
### FX
_FX as data_ are represented with an object containing a `run` function and additional properties that will be passed to that function.
_FX as data_ are represented with an object containing a `run` function and properties that will be passed to that function. Props may also optionally be passed at the time of dispatch using a tuple represented as an array of `[fx, props]`, which will be merged with the props defined on the FX object. Props passed during dispatch will override those defined on the FX when the same key is used.
The `run` function returns a `Promise` if the effect is async. Async FX are considered still running until resolved or rejected. Otherwise FX are considered sync and done once the `run` function returns.
Some `props` are reserved and have special meaning:
Some props are reserved and have special meaning:

@@ -222,0 +227,0 @@ #### `concurrent`

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

const { isFn, isArray, isFx, isObj, assign } = require("./utils");
const { isFn, isArray, isFx, isObj, isPropsTuple, assign } = require("./utils");

@@ -15,31 +15,33 @@ const makeQueue = (queue = []) => ({

} = {}) => {
const concurrentFxWaiting = new Set();
const concurrentFxWithPropsWaiting = new Set();
const concurrentFxRunning = new Set();
const serialFxQueue = makeQueue();
const afterFxQueue = makeQueue();
const serialFxWithPropsQueue = makeQueue();
const afterFxWithPropsQueue = makeQueue();
const runningFx = new Set();
let state = initialState;
const runFx = fx => {
const runFxWithProps = ([fx, dispatchProps]) => {
if (isFn(fx)) {
dispatch(fx(state));
dispatch(fx(state, dispatchProps));
process.nextTick(fxLoop);
return Promise.resolve();
}
const props = mapProps(fx);
runningFx.add(fx);
const dispatchProxy = dispatched => {
const dispatchProxy = (dispatched, props) => {
if (runningFx.has(fx)) {
dispatch(dispatched);
dispatch(dispatched, props);
}
};
const fxPromise =
fx.run(assign(props, { dispatch: dispatchProxy })) || Promise.resolve();
const runtimeProps = mapProps(
assign(fx, dispatchProps, { dispatch: dispatchProxy })
);
runningFx.add(fx);
const fxPromise = fx.run(runtimeProps) || Promise.resolve();
return new Promise(resolve => {
const done = () => {
runningFx.delete(fx);
if (props.cancel) {
if (runtimeProps.cancel) {
runningFx.clear();
concurrentFxWaiting.clear();
serialFxQueue.clear();
concurrentFxWithPropsWaiting.clear();
serialFxWithPropsQueue.clear();
}

@@ -54,14 +56,15 @@ process.nextTick(fxLoop);

const fxLoop = () => {
for (const fx of concurrentFxWaiting) {
concurrentFxWaiting.delete(fx);
runFx(fx).then(() => {
concurrentFxRunning.delete(fx);
for (const fxWithProps of concurrentFxWithPropsWaiting) {
const [concurrentFx] = fxWithProps;
concurrentFxWithPropsWaiting.delete(fxWithProps);
runFxWithProps(fxWithProps).then(() => {
concurrentFxRunning.delete(concurrentFx);
});
concurrentFxRunning.add(fx);
concurrentFxRunning.add(concurrentFx);
}
if (concurrentFxRunning.size === 0 && runningFx.size === 0) {
if (serialFxQueue.notEmpty()) {
runFx(serialFxQueue.dequeue());
} else if (afterFxQueue.notEmpty()) {
runFx(afterFxQueue.dequeue());
if (serialFxWithPropsQueue.notEmpty()) {
runFxWithProps(serialFxWithPropsQueue.dequeue());
} else if (afterFxWithPropsQueue.notEmpty()) {
runFxWithProps(afterFxWithPropsQueue.dequeue());
}

@@ -71,17 +74,21 @@ }

const dispatch = dispatched => {
const dispatch = (dispatched, props) => {
if (isFn(dispatched)) {
serialFxQueue.enqueue(dispatched);
serialFxWithPropsQueue.enqueue([dispatched, props]);
process.nextTick(fxLoop);
} else if (isArray(dispatched)) {
dispatched.forEach(dispatch);
if (isPropsTuple(dispatched)) {
dispatch(dispatched[0], dispatched[1]);
} else {
dispatched.forEach(dispatch);
}
} else if (isFx(dispatched)) {
if (dispatched.cancel) {
runFx(dispatched);
runFxWithProps([dispatched, props]);
} else if (dispatched.concurrent) {
concurrentFxWaiting.add(dispatched);
concurrentFxWithPropsWaiting.add([dispatched, props]);
} else if (dispatched.after) {
afterFxQueue.enqueue(dispatched);
afterFxWithPropsQueue.enqueue([dispatched, props]);
} else {
serialFxQueue.enqueue(dispatched);
serialFxWithPropsQueue.enqueue([dispatched, props]);
}

@@ -88,0 +95,0 @@ process.nextTick(fxLoop);

const makeServer = ({ httpApi, port, serverRuntime }) =>
new Promise((resolve, reject) =>
httpApi(serverRuntime)
.listen({ port }, resolve)
.on("error", reject)
httpApi(serverRuntime).listen({ port }, resolve).on("error", reject)
);
module.exports = makeServer;
const isArray = Array.isArray;
const isFn = value => typeof value === "function";
const isObj = value => value && typeof value === "object" && !isArray(value);
const isPropsTuple = value =>
value.length === 2 &&
(isFn(value[0]) || isFx(value[0])) &&
isObj(value[1]) &&
!isFx(value[1]);
const isFx = value => isObj(value) && isFn(value.run);

@@ -12,4 +17,5 @@

isObj,
isPropsTuple,
isFx,
assign
};
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