diff --git a/src/action/handlers/create-cross-association.js b/src/action/handlers/create-cross-association.js index 8862c93..17ef5f4 100644 --- a/src/action/handlers/create-cross-association.js +++ b/src/action/handlers/create-cross-association.js @@ -1,17 +1,19 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import Association from 'model/entities/Association'; + import getIdea from 'action/utils/get-idea'; import patchRootPaths from 'action/utils/patch-root-paths'; import normalizePatch from 'action/utils/normalize-patch'; import weighAssociation from 'model/utils/weigh-association'; -import Association from 'model/entities/Association'; - /** * Creates association between two existing ideas * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.headIdeaId * @param {string} data.tailIdeaId diff --git a/src/action/handlers/create-idea.js b/src/action/handlers/create-idea.js index 84af1a9..ea6bce9 100644 --- a/src/action/handlers/create-idea.js +++ b/src/action/handlers/create-idea.js @@ -1,6 +1,8 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import isValidPathWeight from 'utils/graph/is-valid-path-weight'; import getIdea from 'action/utils/get-idea'; @@ -13,9 +15,9 @@ import Point from 'model/entities/Point'; /** * Creates idea * - * @param {object} state + * @param {StateType} state * @param {object} data - * @param {string} [data.parentIdeaId] + * @param {string} data.parentIdeaId * @return {Patch} */ export default function createIdea(state, data) { diff --git a/src/action/handlers/init.js b/src/action/handlers/init.js index 3847da6..938427a 100644 --- a/src/action/handlers/init.js +++ b/src/action/handlers/init.js @@ -9,6 +9,8 @@ import Mindmap from 'model/entities/Mindmap'; import Idea from 'model/entities/Idea'; import Point from 'model/entities/Point'; +import StateType from 'boot/client/State'; + import MainVM from 'vm/main/Main'; import MindmapVM from 'vm/main/Mindmap'; @@ -21,7 +23,7 @@ import toGraph from 'vm/map/mappers/mindmap-to-graph'; /** * Inits state * - * @param {object} state + * @param {StateType} state * @param {object} data * @return {Promise.} */ diff --git a/src/action/handlers/remove-association.js b/src/action/handlers/remove-association.js index 4d309bd..d22ecb9 100644 --- a/src/action/handlers/remove-association.js +++ b/src/action/handlers/remove-association.js @@ -1,6 +1,8 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import withoutItem from 'utils/get-array-without-item'; import patchRootPaths from 'action/utils/patch-root-paths'; import normalizePatch from 'action/utils/normalize-patch'; @@ -9,7 +11,7 @@ import getAssociation from 'action/utils/get-association'; /** * Removes association * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.assocId * @return {Patch} diff --git a/src/action/handlers/remove-idea.js b/src/action/handlers/remove-idea.js index 7a73976..38992f0 100644 --- a/src/action/handlers/remove-idea.js +++ b/src/action/handlers/remove-idea.js @@ -1,6 +1,8 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import withoutItem from 'utils/get-array-without-item'; import normalizePatch from 'action/utils/normalize-patch'; import getIdea from 'action/utils/get-idea'; @@ -8,7 +10,7 @@ import getIdea from 'action/utils/get-idea'; /** * Removes idea with corresponding associations * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {object} data.ideaId * @return {Patch} diff --git a/src/action/handlers/set-association-value.js b/src/action/handlers/set-association-value.js index 0f70271..8a1a45c 100644 --- a/src/action/handlers/set-association-value.js +++ b/src/action/handlers/set-association-value.js @@ -1,12 +1,14 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import getAssociation from 'action/utils/get-association'; /** * Sets association value * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.assocId * @param {string} data.value diff --git a/src/action/handlers/set-idea-color.js b/src/action/handlers/set-idea-color.js index 0fdb042..f39fdf2 100644 --- a/src/action/handlers/set-idea-color.js +++ b/src/action/handlers/set-idea-color.js @@ -1,12 +1,14 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import getIdea from 'action/utils/get-idea'; /** * Sets idea color * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.ideaId * @param {string} data.color diff --git a/src/action/handlers/set-idea-position.js b/src/action/handlers/set-idea-position.js index bef4f60..44ea80b 100644 --- a/src/action/handlers/set-idea-position.js +++ b/src/action/handlers/set-idea-position.js @@ -1,6 +1,10 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + import getDescendants from 'utils/graph/get-descendants'; import weighAssociation from 'model/utils/weigh-association'; import isValidPosition from 'model/utils/is-valid-position'; @@ -11,10 +15,10 @@ import getIdea from 'action/utils/get-idea'; /** * Sets position of idea and its child-subtree * - * @param {object} state - * @param {object} data - * @param {string} data.ideaId - * @param {Point} data.pos + * @param {StateType} state + * @param {object} data + * @param {string} data.ideaId + * @param {PointType} data.posAbs * @return {Patch|undefined} */ export default function setIdeaPosition(state, data) { diff --git a/src/action/handlers/set-idea-value.js b/src/action/handlers/set-idea-value.js index 90e2139..082b737 100644 --- a/src/action/handlers/set-idea-value.js +++ b/src/action/handlers/set-idea-value.js @@ -1,12 +1,14 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import getIdea from 'action/utils/get-idea'; /** * Sets value for idea * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.ideaId * @param {string} data.value diff --git a/src/action/handlers/set-mindmap-position.js b/src/action/handlers/set-mindmap-position.js index e470bda..dfe8f1b 100644 --- a/src/action/handlers/set-mindmap-position.js +++ b/src/action/handlers/set-mindmap-position.js @@ -1,13 +1,17 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + /** * Sets mindmap position * - * @param {object} state - * @param {object} data - * @param {string} data.mindmapId - * @param {Point} data.pos - new position of viewbox on canvas + * @param {StateType} state + * @param {object} data + * @param {string} data.mindmapId + * @param {PointType} data.pos - new position of viewbox on canvas * @return {Patch} */ export default function setMindmapPosition(state, data) { diff --git a/src/action/handlers/set-mindmap-scale.js b/src/action/handlers/set-mindmap-scale.js index 2605443..61be86b 100644 --- a/src/action/handlers/set-mindmap-scale.js +++ b/src/action/handlers/set-mindmap-scale.js @@ -1,14 +1,18 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + /** * Sets mindmap scale * - * @param {object} state - * @param {object} data - * @param {string} data.mindmapId - * @param {number} data.scale - target scale - * @param {Point} data.pos - new position of viewbox on canvas + * @param {StateType} state + * @param {object} data + * @param {string} data.mindmapId + * @param {number} data.scale - target scale + * @param {PointType} data.pos - new position of viewbox on canvas * @return {Patch} */ export default function setMindmapScale(state, data) { diff --git a/src/action/utils/search-ideas.js b/src/action/utils/search-ideas.js index a3f3021..f09d567 100644 --- a/src/action/utils/search-ideas.js +++ b/src/action/utils/search-ideas.js @@ -1,4 +1,3 @@ -import required from 'utils/required-params'; import values from 'utils/get-map-values'; import IdeaType from 'model/entities/Idea'; @@ -13,8 +12,7 @@ import MindmapType from 'model/entities/Mindmap'; * @return {Array.} */ export default function searchIdeas(mindmap, opts) { - const {phrase} = required(opts); - const {excludeIds} = opts; + const {phrase, excludeIds} = opts; if (!phrase) { throw Error('Search string is empty'); diff --git a/src/boot/client/initial-state.js b/src/boot/client/State.js similarity index 59% rename from src/boot/client/initial-state.js rename to src/boot/client/State.js index fea6f7b..1a64496 100644 --- a/src/boot/client/initial-state.js +++ b/src/boot/client/State.js @@ -1,11 +1,12 @@ -// @ts-nocheck +import MindmapType from 'model/entities/Mindmap'; +import MainVMType from 'vm/main/Main'; /** * Application state structure */ -export default { +export default class State { - data: { + data = { /** @type {PouchDB.Database} */ ideas: undefined, @@ -15,24 +16,24 @@ export default { /** @type {PouchDB.Database} */ mindmaps: undefined - }, + } - model: { + model = { - /** @type {Mindmap} */ + /** @type {MindmapType} */ mindmap: undefined - }, + } - vm: { + vm = { - /** @type {Main} */ + /** @type {MainVMType} */ main: undefined - }, + } - view: { + view = { /** @type {Element} */ root: undefined } -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src/boot/client/client.js b/src/boot/client/client.js index e4d4d82..39ddf55 100644 --- a/src/boot/client/client.js +++ b/src/boot/client/client.js @@ -5,7 +5,7 @@ import Handler from 'utils/state/Handler'; import commonHandler from 'action/handler'; import vmHandler from 'vm/action/handler'; -import initialState from './initial-state'; +import State from './State'; import combine from 'utils/state/combine-mutators'; import logger from 'utils/state/middlewares/logger'; @@ -44,7 +44,7 @@ async function start() { mutateVM, mutateView ]), - initialState, + new State(), middlewares); const storeDispatch = store.dispatch.bind(store); diff --git a/src/data/mutators/index.js b/src/data/mutators/index.js index a4875a2..19830fd 100644 --- a/src/data/mutators/index.js +++ b/src/data/mutators/index.js @@ -1,6 +1,8 @@ import PatchType from 'utils/state/Patch'; import MutationType from 'utils/state/Mutation'; +import StateType from 'boot/client/State'; + import AsyncTaskQueue from 'utils/AsyncTaskQueue'; import * as ideaDB from '../db/ideas'; @@ -19,7 +21,7 @@ const _queue = new AsyncTaskQueue(); /** * Applies patch to data state - * @param {object} state + * @param {StateType} state * @param {PatchType} patch */ export default async function mutate(state, patch) { @@ -34,7 +36,7 @@ export default async function mutate(state, patch) { /** * Applies single mutation to state - * @param {object} state + * @param {StateType} state * @param {MutationType} mutation */ async function apply(state, mutation) { diff --git a/src/model/mutators/add-association.js b/src/model/mutators/add-association.js index 594bc50..23c7424 100644 --- a/src/model/mutators/add-association.js +++ b/src/model/mutators/add-association.js @@ -1,11 +1,15 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + +import AssociationType from 'model/entities/Association'; + /** * Adds association * - * @param {object} state - * @param {object} data - * @param {Association} data.assoc + * @param {StateType} state + * @param {object} data + * @param {AssociationType} data.assoc */ export default function addAssociation(state, data) { const {model: {mindmap}} = state; diff --git a/src/model/mutators/add-idea.js b/src/model/mutators/add-idea.js index c02d15f..c457ff1 100644 --- a/src/model/mutators/add-idea.js +++ b/src/model/mutators/add-idea.js @@ -1,11 +1,15 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + +import IdeaType from 'model/entities/Idea'; + /** * Adds idea * - * @param {object} state - * @param {object} data - * @param {Idea} data.idea + * @param {StateType} state + * @param {object} data + * @param {IdeaType} data.idea */ export default function addIdea(state, data) { const {model: {mindmap}} = state; diff --git a/src/model/mutators/index.js b/src/model/mutators/index.js index aaaec39..515b5d7 100644 --- a/src/model/mutators/index.js +++ b/src/model/mutators/index.js @@ -1,6 +1,8 @@ import regMutatorsFolder from 'utils/reg-mutators-folder'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + // eslint-disable-next-line no-undef const context = require.context('.', true, /\.js$/); const mutators = regMutatorsFolder(context); @@ -8,7 +10,7 @@ const mutators = regMutatorsFolder(context); /** * Applies patch to model state * - * @param {object} state + * @param {StateType} state * @param {PatchType} patch */ export default function mutate(state, patch) { diff --git a/src/model/mutators/init.js b/src/model/mutators/init.js index 82a9ae6..0c11c65 100644 --- a/src/model/mutators/init.js +++ b/src/model/mutators/init.js @@ -1,13 +1,13 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + /** * Inits model state * - * @param {object} state - * @param {object} data - * @param {PouchDB.Database} data.ideas - * @param {PouchDB.Database} data.associations - * @param {PouchDB.Database} data.mindmaps + * @param {StateType} state + * @param {object} data + * @param {object} data.model */ export default function init(state, data) { const {model} = state; diff --git a/src/model/mutators/remove-association.js b/src/model/mutators/remove-association.js index dc28a8e..30ef91f 100644 --- a/src/model/mutators/remove-association.js +++ b/src/model/mutators/remove-association.js @@ -1,9 +1,11 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + /** * Removes association * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.id */ diff --git a/src/model/mutators/remove-idea.js b/src/model/mutators/remove-idea.js index 8bc0daf..d9f226f 100644 --- a/src/model/mutators/remove-idea.js +++ b/src/model/mutators/remove-idea.js @@ -1,9 +1,11 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + /** * Removes idea * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.id */ diff --git a/src/model/mutators/update-association.js b/src/model/mutators/update-association.js index b9efb26..1a86c53 100644 --- a/src/model/mutators/update-association.js +++ b/src/model/mutators/update-association.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates association * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateAssociation(state, data) { diff --git a/src/model/mutators/update-idea.js b/src/model/mutators/update-idea.js index 3b9acd1..34bc976 100644 --- a/src/model/mutators/update-idea.js +++ b/src/model/mutators/update-idea.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates idea * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateIdea(state, data) { diff --git a/src/model/mutators/update-mindmap.js b/src/model/mutators/update-mindmap.js index 2d19bfa..31d9880 100644 --- a/src/model/mutators/update-mindmap.js +++ b/src/model/mutators/update-mindmap.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates mindmap * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateMindmap(state, data) { diff --git a/src/utils/graph/build-graph-from-matrix.js b/src/utils/graph/build-graph-from-matrix.js index 654abc7..d553d83 100644 --- a/src/utils/graph/build-graph-from-matrix.js +++ b/src/utils/graph/build-graph-from-matrix.js @@ -1,23 +1,33 @@ -import required from 'utils/required-params'; import isValidPathWeight from 'utils/graph//is-valid-path-weight'; +import IdeaType from 'model/entities/Idea'; +import AssocType from 'model/entities/Association'; + +import NodeType from 'vm/map/entities/Node'; +import LinkType from 'vm/map/entities/Link'; + const charCodeA = 65; const charCount = 26; +/** + * @typedef {{new(...args: any[]): IdeaType|NodeType}} VertexConstructorType + * @typedef {{new(...args: any[]): AssocType|LinkType}} EdgeConstructorType + */ + /** * Generic function for building object graph from adjacency matrix * * Q: Why input matrix is array of strings and not array of number arrays? * A: Because it is possible to align columns without violating lint rules. * - * @param {object} opts - * @param {Array.} opts.matrix - * @param {function} opts.VertexConstructor - * @param {function} opts.EdgeConstructor + * @param {object} opts + * @param {Array.} opts.matrix + * @param {VertexConstructorType} opts.VertexConstructor + * @param {EdgeConstructorType} opts.EdgeConstructor * @return {object} root vertex */ export default function buildGraphFromMatrix(opts) { - const {matrix: m, VertexConstructor, EdgeConstructor} = required(opts); + const {matrix: m, VertexConstructor, EdgeConstructor} = opts; // validate input const vertexCount = m.length; @@ -30,6 +40,7 @@ export default function buildGraphFromMatrix(opts) { const vertices = []; for (let i = 0; i < vertexCount; i++) { const id = String.fromCharCode(charCodeA + i); + const vertex = new VertexConstructor({id}); vertex.edgesIn = []; vertex.edgesOut = []; diff --git a/src/utils/graph/build-graph-from-objects.js b/src/utils/graph/build-graph-from-objects.js index 817b4e6..768e616 100644 --- a/src/utils/graph/build-graph-from-objects.js +++ b/src/utils/graph/build-graph-from-objects.js @@ -1,4 +1,3 @@ -import required from 'utils/required-params'; import traverseGraph from 'utils/graph/traverse-graph'; /** @@ -12,7 +11,7 @@ import traverseGraph from 'utils/graph/traverse-graph'; * @return {object} root vertex */ export default function buildGraph(opts) { - const {vertices, edges, isRootVertex} = required(opts); + const {vertices, edges, isRootVertex} = opts; let rootVertex = null; diff --git a/src/utils/graph/calc-root-paths.js b/src/utils/graph/calc-root-paths.js index 3aa41ec..5184560 100644 --- a/src/utils/graph/calc-root-paths.js +++ b/src/utils/graph/calc-root-paths.js @@ -1,4 +1,3 @@ -import required from 'utils/required-params'; import PriorityQueue from 'utils/PriorityQueue'; import isValidPathWeight from 'utils/graph/is-valid-path-weight'; @@ -40,8 +39,8 @@ import isValidPathWeight from 'utils/graph/is-valid-path-weight'; */ export default function calcRootPaths(opts) { - const {root} = required(opts); const { + root, ignoreEdges = [], replaceEdgesOut = [], replaceEdgeWeights = [] diff --git a/src/utils/graph/map-graph.js b/src/utils/graph/map-graph.js index 64448ed..7aa20e1 100644 --- a/src/utils/graph/map-graph.js +++ b/src/utils/graph/map-graph.js @@ -1,4 +1,3 @@ -import required from 'utils/required-params'; import WeightZone from 'utils/graph/WeightZone'; import isValidPathWeight from 'utils/graph/is-valid-path-weight'; @@ -93,7 +92,7 @@ export default function mapGraph(opts) { * @param {object} internalOpts * @param {Map} internalOpts.visitedOriginalVertices * @param {array} internalOpts.allVertices - * @param {array} internalOpts.allEdges + * @param {array} internalOpts.allEdges * @return {{rootVertex, vertices, edges}} */ function mapGraphInternal(opts, internalOpts) { @@ -104,13 +103,13 @@ function mapGraphInternal(opts, internalOpts) { mapEdge, focusZoneMax, shadeZoneAmount - } = required(opts); + } = opts; const { visitedOriginalVertices, allVertices, allEdges - } = required(internalOpts); + } = internalOpts; // check if vertex was already visited // to not fall into infinite loop in graph cycles diff --git a/src/utils/graph/traverse-graph.js b/src/utils/graph/traverse-graph.js index a3b7a4d..bcf0b52 100644 --- a/src/utils/graph/traverse-graph.js +++ b/src/utils/graph/traverse-graph.js @@ -1,5 +1,3 @@ -import required from 'utils/required-params'; - /** * Generic function for graph traversal * @@ -17,9 +15,12 @@ import required from 'utils/required-params'; */ export default function traverseGraph(opts) { - const {root, visit} = required(opts); - const alg = opts.alg || 'dfs-pre'; - const isTree = opts.isTree || false; + const { + root, + visit, + alg = 'dfs-pre', + isTree = false + } = opts; switch (alg) { case 'dfs-pre': diff --git a/src/utils/required-params.js b/src/utils/required-params.js index 03b8968..a977817 100644 --- a/src/utils/required-params.js +++ b/src/utils/required-params.js @@ -1,29 +1,44 @@ /** - * Wraps parameters object into proxy which throws error - * when someone tries to get param which does not exist + * Run-time checks for required function parameters * - * Why even need to check required params? - * Prefer to throw ASAP. Need more confidence on arguments. - * The language cannot currently afford that. + * NOTE: always prefer static type checks over run-time checks. + * use as last resort in case static analisys is not possible. * - * Why not just throw error with simple asserts? - * Too much noise. Looking for brevity. + * Current usecases: + * - Store action handlers (until #65 is fixed) + * - Store mutators + * - EventEmitter event handlers * - * Why not use Flow? - * Because it does not support type annotations inside destructuring - * https://github.com/facebook/flow/issues/235 + * Q: Why not use static type check system (eg. Typescript or Flow)? + * A: 1. It is not always possible to use static analisys, eg. + * a. you have a project which is not 100% type covered, and some of your + * functions not called directly but through another generic function + * which loose types info (eg. EventEmitter#emit) + * b. you write a library and should not expect all of its users to use + * static type check system. * - * Why not just throw error from default value getter? - * like, function(requiredParam = req()) - * Because: - * 1. It requires more space in param list, since added to each - * required parameter - * 2. It does not throw descriptive error with what param was - * exactly missed (or need to pass param name into req function, - * which is #1 again) + * 2. Flow does not support type annotations inside destructuring, + * which blocks passing params in 'option bag'-objects + * https://github.com/facebook/flow/issues/235 * - * BTW, all ways look nasty to me. - * Using this one until native spec is arrived. + * Q: Why even need to check required params? + * A: Prefer to throw ASAP. Need more confidence on arguments. + * The language cannot currently afford that natively. + * + * Q: Why not just throw error with simple asserts? + * A: Too much noise. Looking for brevity. + * + * Q: Why not just throw error from default value getter? + * like, function(requiredParam = req()) + * A: Because: + * 1. It requires more space in param list, since added to each + * required parameter + * 2. It does not throw descriptive error with what param was + * exactly missed (or need to pass param name into req function, + * which is #1 again) + * + * BTW, all run-time param check options look nasty to me. + * But this one looks least nasty :) * * @example required vs optional parameters * function(params) { @@ -31,10 +46,9 @@ * const {optionalParam} = params; * } * - * TODO: try typedef generic function function(T): T - * - * @param {object} params - * @return {object} + * @template T + * @param {T} params + * @return {T} */ export default function requiredParams(params) { @@ -48,6 +62,7 @@ export default function requiredParams(params) { return params; } + // @ts-ignore return new Proxy(params, { get: function(target, name) { if (!(name in target)) { diff --git a/src/utils/state/Handler.js b/src/utils/state/Handler.js index a87ded4..e2cc847 100644 --- a/src/utils/state/Handler.js +++ b/src/utils/state/Handler.js @@ -1,6 +1,7 @@ -import required from 'utils/required-params'; import Patch from './Patch'; +import ActionType from './Action'; + /** * Collection of registered action handlers * @@ -51,20 +52,21 @@ export default class Handler { [Symbol.iterator]() { return this._handlers[Symbol.iterator](); } - + /** * Executes registered handler for an action * * @param {object} state * @param {object} action + * @param {string} action.type + * @param {*} [action.data] * @param {function} [dispatch] * @param {function} [mutate] * @return {Promise|Patch} if handler is async - promise patch, - * if handler is sync - sync patch. + * if handler is sync - sync patch. */ handle(state, action, dispatch, mutate) { - const {type} = required(action); - const {data} = action; + const {type, data} = action; const handlerDescriptor = this._handlers .find(ah => ah.type === type); diff --git a/src/utils/state/middlewares/logger/LogEntry.js b/src/utils/state/middlewares/logger/LogEntry.js index e08b2b4..8e88566 100644 --- a/src/utils/state/middlewares/logger/LogEntry.js +++ b/src/utils/state/middlewares/logger/LogEntry.js @@ -3,6 +3,8 @@ import assert from 'utils/assert'; import PatchType from 'utils/state/Patch'; import ActionType from 'utils/state/Action'; +import StateType from 'boot/client/State'; + /** * Log entry for store action */ @@ -112,7 +114,7 @@ export default class LogEntry { /** * Gets state before action - * @return {object} + * @return {StateType} */ get prevState() { return this._prevState; @@ -120,7 +122,7 @@ export default class LogEntry { /** * Sets state before action - * @param {object} state + * @param {StateType} state */ set prevState(state) { this._prevState = { @@ -136,7 +138,7 @@ export default class LogEntry { /** * Gets state after action - * @return {object} + * @return {StateType} */ get nextState() { return this._nextState; @@ -144,7 +146,7 @@ export default class LogEntry { /** * Sets state after action - * @param {object} state + * @param {StateType} state */ set nextState(state) { this._nextState = { diff --git a/src/view/mutators/index.js b/src/view/mutators/index.js index c26d3ab..e439a30 100644 --- a/src/view/mutators/index.js +++ b/src/view/mutators/index.js @@ -5,12 +5,14 @@ import required from 'utils/required-params'; import MutationType from 'utils/state/Mutation'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import Main from 'view/main/Main'; import Provider from 'view/utils/connect/Provider'; /** * Applies patch to view state - * @param {object} state + * @param {StateType} state * @param {PatchType} patch */ export default function mutate(state, patch) { @@ -21,7 +23,7 @@ export default function mutate(state, patch) { /** * Applies single mutation to state - * @param {object} state + * @param {StateType} state * @param {MutationType} mutation */ function apply(state, mutation) { @@ -84,7 +86,7 @@ function apply(state, mutation) { /** * Mounts component tree - * @param {object} state + * @param {StateType} state */ function mount(state) { ReactDom.render( diff --git a/src/vm/action/handlers/animate-graph-zoom.js b/src/vm/action/handlers/animate-graph-zoom.js index d2d1eed..51453d8 100644 --- a/src/vm/action/handlers/animate-graph-zoom.js +++ b/src/vm/action/handlers/animate-graph-zoom.js @@ -1,6 +1,8 @@ import required from 'utils/required-params'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import view from 'vm/utils/view-patch'; import animate from 'vm/utils/animate'; import Point from 'model/entities/Point'; @@ -12,7 +14,7 @@ import toCanvasCoords from 'vm/map/utils/map-viewport-to-canvas-coords'; /** * Animates graph scale towards certain canvas position * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {object} data.up - scale up or down * @param {object} data.pos - target viewport position diff --git a/src/vm/action/handlers/animate-to-node.js b/src/vm/action/handlers/animate-to-node.js index 8a8989f..229be73 100644 --- a/src/vm/action/handlers/animate-to-node.js +++ b/src/vm/action/handlers/animate-to-node.js @@ -2,6 +2,8 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import clone from 'clone'; +import StateType from 'boot/client/State'; + import Point from 'model/entities/Point'; import NodeType from 'vm/map/entities/Node'; @@ -12,7 +14,7 @@ import getGraphScaleForNode from 'vm/map/utils/get-graph-scale-for-node-scale'; /** * Animates graph position and scale to target node * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {NodeType} data.node - target node * @param {function} dispatch diff --git a/src/vm/action/handlers/on-association-tails-lookup-keydown.js b/src/vm/action/handlers/on-association-tails-lookup-keydown.js index b5a26a9..0728cc7 100644 --- a/src/vm/action/handlers/on-association-tails-lookup-keydown.js +++ b/src/vm/action/handlers/on-association-tails-lookup-keydown.js @@ -2,12 +2,14 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import onKeyDown from 'vm/shared/Lookup/methods/on-keydown'; /** * Handles key down event on association tails lookup * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.key * @param {function} dispatch diff --git a/src/vm/action/handlers/on-association-tails-lookup-phrase-change.js b/src/vm/action/handlers/on-association-tails-lookup-phrase-change.js index cca3ff4..f37b57e 100644 --- a/src/vm/action/handlers/on-association-tails-lookup-phrase-change.js +++ b/src/vm/action/handlers/on-association-tails-lookup-phrase-change.js @@ -2,12 +2,14 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import onPhraseChange from 'vm/shared/Lookup/methods/on-phrase-change'; /** * Handles phrase change event on association tails lookup * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.phrase * @param {function} dispatch diff --git a/src/vm/action/handlers/on-association-tails-lookup-suggestion-select.js b/src/vm/action/handlers/on-association-tails-lookup-suggestion-select.js index e9a717d..5c0b651 100644 --- a/src/vm/action/handlers/on-association-tails-lookup-suggestion-select.js +++ b/src/vm/action/handlers/on-association-tails-lookup-suggestion-select.js @@ -2,13 +2,18 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import LookupSuggestionType from 'vm/shared/LookupSuggestion'; + /** * Handles suggestion select event of association tails lookup * - * @param {object} state - * @param {object} data - * @param {string} data.headIdeaId - * @param {string} data.tailIdeaId + * @param {StateType} state + * @param {object} data + * @param {string} data.headIdeaId + * @param {string} data.tailIdeaId + * @param {LookupSuggestionType} data.suggestion * @param {function} dispatch * @return {PatchType} */ diff --git a/src/vm/action/handlers/on-graph-click.js b/src/vm/action/handlers/on-graph-click.js index 59f3a22..64cbbea 100644 --- a/src/vm/action/handlers/on-graph-click.js +++ b/src/vm/action/handlers/on-graph-click.js @@ -1,10 +1,12 @@ import Patch from 'utils/state/Patch'; import view from 'vm/utils/view-mutation'; +import StateType from 'boot/client/State'; + /** * Handles graph click event * - * @param {object} state + * @param {StateType} state * @return {Patch} */ export default function(state) { diff --git a/src/vm/action/handlers/on-graph-key-press.js b/src/vm/action/handlers/on-graph-key-press.js index 3970d8d..3ad227a 100644 --- a/src/vm/action/handlers/on-graph-key-press.js +++ b/src/vm/action/handlers/on-graph-key-press.js @@ -1,11 +1,13 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + import Point from 'model/entities/Point'; /** * Handles key press event on graph * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.key * @param {function} dispatch diff --git a/src/vm/action/handlers/on-graph-mouse-leave.js b/src/vm/action/handlers/on-graph-mouse-leave.js index 51e875e..6ba8d95 100644 --- a/src/vm/action/handlers/on-graph-mouse-leave.js +++ b/src/vm/action/handlers/on-graph-mouse-leave.js @@ -1,5 +1,7 @@ import view from 'vm/utils/view-mutation'; +import StateType from 'boot/client/State'; + import Patch from 'utils/state/Patch'; import getNode from 'vm/action/utils/get-node'; import stopDrag from 'vm/map/entities/Graph/methods/stop-drag'; @@ -7,7 +9,7 @@ import stopDrag from 'vm/map/entities/Graph/methods/stop-drag'; /** * Handles mouse leave action on graph * - * @param {object} state + * @param {StateType} state * @return {Patch|undefined} */ export default function(state) { diff --git a/src/vm/action/handlers/on-graph-mouse-move.js b/src/vm/action/handlers/on-graph-mouse-move.js index 3f7b334..249a05a 100644 --- a/src/vm/action/handlers/on-graph-mouse-move.js +++ b/src/vm/action/handlers/on-graph-mouse-move.js @@ -1,16 +1,20 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + import view from 'vm/utils/view-mutation'; import toViewboxCoords from 'vm/map/utils/map-viewport-to-viewbox-coords'; /** * Handles mouse move on graph * - * @param {object} state - * @param {object} data - * @param {Point} data.viewportShift - * @param {string} data.pressedMouseButton - left or null + * @param {StateType} state + * @param {object} data + * @param {PointType} data.viewportShift + * @param {string} data.pressedMouseButton - left or null (TODO: or null?) * @return {Patch|undefined} */ export default function(state, data) { diff --git a/src/vm/action/handlers/on-graph-mouse-up.js b/src/vm/action/handlers/on-graph-mouse-up.js index 3d6ce8d..fc860a6 100644 --- a/src/vm/action/handlers/on-graph-mouse-up.js +++ b/src/vm/action/handlers/on-graph-mouse-up.js @@ -1,13 +1,15 @@ import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import Point from 'model/entities/Point'; import stopDrag from 'vm/map/entities/Graph/methods/stop-drag'; /** * Handles mouse up event on graph * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {function} dispatch * @return {PatchType|undefined} diff --git a/src/vm/action/handlers/on-graph-node-mouse-down.js b/src/vm/action/handlers/on-graph-node-mouse-down.js index 96bb276..ba24d49 100644 --- a/src/vm/action/handlers/on-graph-node-mouse-down.js +++ b/src/vm/action/handlers/on-graph-node-mouse-down.js @@ -2,15 +2,19 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import NodeType from 'vm/map/entities/Node'; + import getDescendants from 'utils/graph/get-descendants'; /** * Handles mouse down event on graph node * - * @param {object} state - * @param {object} data - * @param {Node} data.node - * @param {string} data.button + * @param {StateType} state + * @param {object} data + * @param {NodeType} data.node + * @param {string} data.button * @return {PatchType|undefined} */ export default function(state, data) { diff --git a/src/vm/action/handlers/on-graph-viewport-resize.js b/src/vm/action/handlers/on-graph-viewport-resize.js index a0e271d..ed22e7a 100644 --- a/src/vm/action/handlers/on-graph-viewport-resize.js +++ b/src/vm/action/handlers/on-graph-viewport-resize.js @@ -2,13 +2,15 @@ import clone from 'clone'; import required from 'utils/required-params'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import view from 'vm/utils/view-patch'; import computeViewbox from 'vm/map/entities/Graph/methods/compute-viewbox-size'; /** * Handlers graph viewport resize event * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {object} data.size * @param {number} data.size.width diff --git a/src/vm/action/handlers/on-graph-wheel.js b/src/vm/action/handlers/on-graph-wheel.js index 63a215d..e557de7 100644 --- a/src/vm/action/handlers/on-graph-wheel.js +++ b/src/vm/action/handlers/on-graph-wheel.js @@ -1,12 +1,16 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + /** * Handles graph mouse wheel event * - * @param {object} state - * @param {object} data - * @param {string} data.up - wheel up or down - * @param {Point} data.pos - target viewport position + * @param {StateType} state + * @param {object} data + * @param {string} data.up - wheel up or down + * @param {PointType} data.pos - target viewport position * @param {function} dispatch */ export default function onGraphWheel(state, data, dispatch) { diff --git a/src/vm/action/handlers/on-idea-color-selected.js b/src/vm/action/handlers/on-idea-color-selected.js index 9af28d5..6a0b03c 100644 --- a/src/vm/action/handlers/on-idea-color-selected.js +++ b/src/vm/action/handlers/on-idea-color-selected.js @@ -2,10 +2,12 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + /** * Handles idea color selected with color picker * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.ideaId * @param {string} data.color diff --git a/src/vm/action/handlers/on-link-click.js b/src/vm/action/handlers/on-link-click.js index f7141b7..9b6a32e 100644 --- a/src/vm/action/handlers/on-link-click.js +++ b/src/vm/action/handlers/on-link-click.js @@ -1,15 +1,19 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + import getDistance from 'utils/get-distance-between-points'; import toCanvasCoords from 'vm/map/utils/map-viewport-to-canvas-coords'; /** * Handles link click event * - * @param {object} state - * @param {object} data - * @param {string} data.linkId - * @param {string} data.viewportPos - mouse viewport position + * @param {StateType} state + * @param {object} data + * @param {string} data.linkId + * @param {PointType} data.viewportPos - mouse viewport position * @param {function} dispatch */ export default function(state, data, dispatch) { diff --git a/src/vm/action/handlers/on-link-mouse-leave.js b/src/vm/action/handlers/on-link-mouse-leave.js index 2b88890..5ed04a2 100644 --- a/src/vm/action/handlers/on-link-mouse-leave.js +++ b/src/vm/action/handlers/on-link-mouse-leave.js @@ -2,10 +2,12 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + /** * Handles link mouse leave event * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.linkId * @return {PatchType} diff --git a/src/vm/action/handlers/on-link-mouse-move.js b/src/vm/action/handlers/on-link-mouse-move.js index 8a66945..463c1eb 100644 --- a/src/vm/action/handlers/on-link-mouse-move.js +++ b/src/vm/action/handlers/on-link-mouse-move.js @@ -2,16 +2,20 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + import toCanvasCoords from 'vm/map/utils/map-viewport-to-canvas-coords'; import getDistance from 'utils/get-distance-between-points'; /** * Handles link mouse move event * - * @param {object} state - * @param {object} data - * @param {string} data.linkId - * @param {string} data.viewportPos - mouse viewport position + * @param {StateType} state + * @param {object} data + * @param {string} data.linkId + * @param {PointType} data.viewportPos - mouse viewport position * @return {PatchType} */ export default function onLinkMouseMove(state, data) { diff --git a/src/vm/action/handlers/on-node-title-blur.js b/src/vm/action/handlers/on-node-title-blur.js index 58bca95..bf66684 100644 --- a/src/vm/action/handlers/on-node-title-blur.js +++ b/src/vm/action/handlers/on-node-title-blur.js @@ -2,12 +2,14 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import getNode from 'vm/action/utils/get-node'; /** * Handles blur event on graph node title * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.nodeId * @return {PatchType|undefined} diff --git a/src/vm/action/handlers/on-node-title-change.js b/src/vm/action/handlers/on-node-title-change.js index 6ea7eb2..e0981b3 100644 --- a/src/vm/action/handlers/on-node-title-change.js +++ b/src/vm/action/handlers/on-node-title-change.js @@ -1,9 +1,11 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + /** * Handles change event on node title * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.nodeId * @param {string} data.title diff --git a/src/vm/action/handlers/on-node-title-double-click.js b/src/vm/action/handlers/on-node-title-double-click.js index 750ef00..32674d9 100644 --- a/src/vm/action/handlers/on-node-title-double-click.js +++ b/src/vm/action/handlers/on-node-title-double-click.js @@ -2,12 +2,14 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import getNode from 'vm/action/utils/get-node'; /** * Handles double click event on graph node title * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.nodeId * @return {PatchType|undefined} diff --git a/src/vm/action/handlers/search-association-tails-for-lookup.js b/src/vm/action/handlers/search-association-tails-for-lookup.js index 2d88cd0..683013d 100644 --- a/src/vm/action/handlers/search-association-tails-for-lookup.js +++ b/src/vm/action/handlers/search-association-tails-for-lookup.js @@ -2,6 +2,8 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import searchIdeas from 'action/utils/search-ideas'; import getIdea from 'action/utils/get-idea'; @@ -11,7 +13,7 @@ import LookupSuggestion from 'vm/shared/LookupSuggestion'; * Searches and sets suggesting ideas to lookup * which selects tail idea for cross-association * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.phrase * @param {string} data.headIdeaId diff --git a/src/vm/action/handlers/show-association-tails-lookup.js b/src/vm/action/handlers/show-association-tails-lookup.js index 7184b16..85325cc 100644 --- a/src/vm/action/handlers/show-association-tails-lookup.js +++ b/src/vm/action/handlers/show-association-tails-lookup.js @@ -2,16 +2,20 @@ import required from 'utils/required-params'; import Patch from 'utils/state/Patch'; import view from 'vm/utils/view-patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + import showLookup from 'vm/shared/Lookup/methods/show-lookup'; /** * Shows association tails lookup * which helps selecting tail idea for cross-association * - * @param {object} state - * @param {object} data - * @param {Point} data.pos - target canvas position for lookup - * @param {string} data.headIdeaId - ID of head idea + * @param {StateType} state + * @param {object} data + * @param {PointType} data.pos - target canvas position for lookup + * @param {string} data.headIdeaId - ID of head idea * @return {Patch} */ export default function(state, data) { diff --git a/src/vm/action/handlers/show-color-picker-for-idea.js b/src/vm/action/handlers/show-color-picker-for-idea.js index e6f7f00..261c973 100644 --- a/src/vm/action/handlers/show-color-picker-for-idea.js +++ b/src/vm/action/handlers/show-color-picker-for-idea.js @@ -2,10 +2,12 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + /** * Shows color picker * - * @param {object} state + * @param {StateType} state * @param {object} data * @param {string} data.ideaId - ID of target idea * @return {PatchType} diff --git a/src/vm/action/handlers/show-context-menu-for-association.js b/src/vm/action/handlers/show-context-menu-for-association.js index 16e2935..9f94d1e 100644 --- a/src/vm/action/handlers/show-context-menu-for-association.js +++ b/src/vm/action/handlers/show-context-menu-for-association.js @@ -2,17 +2,21 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + import getAssociation from 'action/utils/get-association'; import MenuItem from 'vm/shared/MenuItem'; /** * Shows context menu for association * - * @param {object} state - * @param {object} data - * @param {Point} data.pos - viewport position of mouse - * TODO: rename to viewportPos - * @param {string} data.associationId - ID of target association + * @param {StateType} state + * @param {object} data + * @param {PointType} data.pos - viewport position of mouse + * TODO: rename to viewportPos + * @param {string} data.associationId - ID of target association * @param {boolean} data.shaded - indicates target association is shaded * @return {PatchType|undefined} */ diff --git a/src/vm/action/handlers/show-context-menu-for-idea.js b/src/vm/action/handlers/show-context-menu-for-idea.js index 3d3f91a..4297e13 100644 --- a/src/vm/action/handlers/show-context-menu-for-idea.js +++ b/src/vm/action/handlers/show-context-menu-for-idea.js @@ -2,16 +2,20 @@ import required from 'utils/required-params'; import view from 'vm/utils/view-patch'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + +import PointType from 'model/entities/Point'; + import MenuItem from 'vm/shared/MenuItem'; /** * Shows context menu for idea * - * @param {object} state - * @param {object} data - * @param {Point} data.pos - viewport position of mouse + * @param {StateType} state + * @param {object} data + * @param {PointType} data.pos - viewport position of mouse * TODO: rename to viewportPos - * @param {string} data.ideaId - ID of target idea + * @param {string} data.ideaId - ID of target idea * @param {boolean} data.shaded - indicates target idea is shaded * @return {PatchType|undefined} */ diff --git a/src/vm/map/entities/Graph/methods/check-scale-limits.js b/src/vm/map/entities/Graph/methods/check-scale-limits.js index 70204d8..c7f1efb 100644 --- a/src/vm/map/entities/Graph/methods/check-scale-limits.js +++ b/src/vm/map/entities/Graph/methods/check-scale-limits.js @@ -1,5 +1,4 @@ import assert from 'utils/assert'; -import required from 'utils/required-params'; import isValidScale from 'model/utils/is-valid-scale'; /** @@ -11,7 +10,7 @@ import isValidScale from 'model/utils/is-valid-scale'; * @return {boolean} */ export default function checkGraphScaleLimits(opts) { - const {viewbox, up} = required(opts); + const {viewbox, up} = opts; const {scale, scaleMin, scaleMax} = viewbox; diff --git a/src/vm/map/entities/Graph/methods/compute-viewbox-size.js b/src/vm/map/entities/Graph/methods/compute-viewbox-size.js index 4dbc344..709079c 100644 --- a/src/vm/map/entities/Graph/methods/compute-viewbox-size.js +++ b/src/vm/map/entities/Graph/methods/compute-viewbox-size.js @@ -1,6 +1,5 @@ import clone from 'clone'; import assert from 'utils/assert'; -import required from 'utils/required-params'; /** * Computes viewbox size @@ -12,7 +11,7 @@ import required from 'utils/required-params'; * @return {object} */ export default function computeViewboxSize(opts) { - const {viewport, viewbox: vb} = required(opts); + const {viewport, viewbox: vb} = opts; assert(viewport.width > 0, `Invalid viewport width '${viewport.width}'`); assert(viewport.height > 0, `Invalid viewport height '${viewport.height}'`); diff --git a/src/vm/map/entities/Graph/methods/zoom.js b/src/vm/map/entities/Graph/methods/zoom.js index c443080..4ed9ab5 100644 --- a/src/vm/map/entities/Graph/methods/zoom.js +++ b/src/vm/map/entities/Graph/methods/zoom.js @@ -1,6 +1,7 @@ import assert from 'utils/assert'; import clone from 'clone'; -import required from 'utils/required-params'; + +import PointType from 'model/entities/Point'; import computeViewboxSize from './compute-viewbox-size'; import checkScaleLimits from './check-scale-limits'; @@ -8,15 +9,15 @@ import checkScaleLimits from './check-scale-limits'; /** * Changes graph scale towards certain canvas position * - * @param {object} opts - * @param {object} opts.viewbox - graph viewbox - * @param {object} opts.viewport - graph viewport - * @param {object} opts.scale - target scale - * @param {Point} opts.canvasPos - target canvas position + * @param {object} opts + * @param {object} opts.viewbox - graph viewbox + * @param {object} opts.viewport - graph viewport + * @param {object} opts.scale - target scale + * @param {PointType} opts.canvasPos - target canvas position * @return {object} viewbox */ export default function zoomGraph(opts) { - const {viewbox: vb, viewport, scale, canvasPos} = required(opts); + const {viewbox: vb, viewport, scale, canvasPos} = opts; if (!checkScaleLimits({viewbox: vb, up: scale > vb.scale})) { // do not scale out of limits diff --git a/src/vm/mutators/default.js b/src/vm/mutators/default.js index b834d06..f7ccaf3 100644 --- a/src/vm/mutators/default.js +++ b/src/vm/mutators/default.js @@ -1,9 +1,11 @@ import toGraph from 'vm/map/mappers/mindmap-to-graph'; import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Applies all mutations that do not have correspoding mutators - * @param {object} state + * @param {StateType} state */ export default function defaultMutator(state) { diff --git a/src/vm/mutators/index.js b/src/vm/mutators/index.js index de61c48..7c6f746 100644 --- a/src/vm/mutators/index.js +++ b/src/vm/mutators/index.js @@ -1,6 +1,8 @@ import regMutatorsFolder from 'utils/reg-mutators-folder'; import PatchType from 'utils/state/Patch'; +import StateType from 'boot/client/State'; + import defaultMutator from './default'; // eslint-disable-next-line no-undef @@ -9,7 +11,7 @@ const mutators = regMutatorsFolder(context); /** * Applies patch to vm state - * @param {object} state + * @param {StateType} state * @param {PatchType} patch */ export default function mutate(state, patch) { diff --git a/src/vm/mutators/init.js b/src/vm/mutators/init.js index bfb9bda..026df86 100644 --- a/src/vm/mutators/init.js +++ b/src/vm/mutators/init.js @@ -1,8 +1,10 @@ import required from 'utils/required-params'; +import StateType from 'boot/client/State'; + /** * Applies 'init' mutation - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function init(state, data) { diff --git a/src/vm/mutators/update-association-tails-lookup.js b/src/vm/mutators/update-association-tails-lookup.js index d76ff11..31af02a 100644 --- a/src/vm/mutators/update-association-tails-lookup.js +++ b/src/vm/mutators/update-association-tails-lookup.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates association tails lookup * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateAssociationTailsLookup(state, data) { diff --git a/src/vm/mutators/update-color-picker.js b/src/vm/mutators/update-color-picker.js index 604001b..0296d26 100644 --- a/src/vm/mutators/update-color-picker.js +++ b/src/vm/mutators/update-color-picker.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates color picker * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateColorPicker(state, data) { diff --git a/src/vm/mutators/update-context-menu.js b/src/vm/mutators/update-context-menu.js index f6d5576..d8a00a5 100644 --- a/src/vm/mutators/update-context-menu.js +++ b/src/vm/mutators/update-context-menu.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates context menu * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateContextMenu(state, data) { diff --git a/src/vm/mutators/update-graph.js b/src/vm/mutators/update-graph.js index 0b50264..2b58a9c 100644 --- a/src/vm/mutators/update-graph.js +++ b/src/vm/mutators/update-graph.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates graph * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateGraph(state, data) { diff --git a/src/vm/mutators/update-link.js b/src/vm/mutators/update-link.js index 8ef4c66..66acb05 100644 --- a/src/vm/mutators/update-link.js +++ b/src/vm/mutators/update-link.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates link * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateLink(state, data) { diff --git a/src/vm/mutators/update-node.js b/src/vm/mutators/update-node.js index 31163c5..02714f3 100644 --- a/src/vm/mutators/update-node.js +++ b/src/vm/mutators/update-node.js @@ -1,9 +1,11 @@ import update from 'utils/update-object'; +import StateType from 'boot/client/State'; + /** * Updates node * - * @param {object} state + * @param {StateType} state * @param {object} data */ export default function updateNode(state, data) { diff --git a/src/vm/shared/Lookup/methods/get-next-highlighted-suggestion-id.js b/src/vm/shared/Lookup/methods/get-next-highlighted-suggestion-id.js index ff255c7..3fa6320 100644 --- a/src/vm/shared/Lookup/methods/get-next-highlighted-suggestion-id.js +++ b/src/vm/shared/Lookup/methods/get-next-highlighted-suggestion-id.js @@ -1,5 +1,3 @@ -import required from 'utils/required-params'; - import LookupType from 'vm/shared/Lookup'; /** @@ -11,7 +9,7 @@ import LookupType from 'vm/shared/Lookup'; * @return {number|null} ID of next highlighted suggesion */ export default function getNextHighlightedSuggestionId(opts) { - const {lookup, forward} = required(opts); + const {lookup, forward} = opts; if (!lookup.suggestions.length) { // skip since no suggestions diff --git a/src/vm/shared/Lookup/methods/on-keydown.js b/src/vm/shared/Lookup/methods/on-keydown.js index 5c41c93..007bab5 100644 --- a/src/vm/shared/Lookup/methods/on-keydown.js +++ b/src/vm/shared/Lookup/methods/on-keydown.js @@ -1,5 +1,3 @@ -import required from 'utils/required-params'; - import LookupType from 'vm/shared/Lookup'; import clearLookup from './clear-lookup'; @@ -15,7 +13,7 @@ import getNextSuggestionId from './get-next-highlighted-suggestion-id'; * @return {object} lookup update object */ export default function onKeyDown(opts) { - const {key, lookup, onSuggestionSelect} = required(opts); + const {key, lookup, onSuggestionSelect} = opts; let update = {}; diff --git a/src/vm/shared/Lookup/methods/on-phrase-change.js b/src/vm/shared/Lookup/methods/on-phrase-change.js index b96eabb..b8f34cc 100644 --- a/src/vm/shared/Lookup/methods/on-phrase-change.js +++ b/src/vm/shared/Lookup/methods/on-phrase-change.js @@ -1,4 +1,3 @@ -import required from 'utils/required-params'; import debounce from 'debounce'; import LookupType from 'vm/shared/Lookup'; @@ -15,7 +14,7 @@ import clearLookup from './clear-lookup'; * @return {object} lookup update object */ export default function onPhraseChange(opts) { - const {phrase, lookup, onPhraseChangeAction} = required(opts); + const {phrase, lookup, onPhraseChangeAction} = opts; let update = null; diff --git a/src/vm/shared/Lookup/methods/show-lookup.js b/src/vm/shared/Lookup/methods/show-lookup.js index 5960a99..be006dc 100644 --- a/src/vm/shared/Lookup/methods/show-lookup.js +++ b/src/vm/shared/Lookup/methods/show-lookup.js @@ -1,4 +1,3 @@ -import required from 'utils/required-params'; import clearLookup from './clear-lookup'; /** @@ -10,7 +9,7 @@ import clearLookup from './clear-lookup'; * @return {object} lookup update object */ export default function show(opts) { - const {onSelectAction, onPhraseChangeAction} = required(opts); + const {onSelectAction, onPhraseChangeAction} = opts; return Object.assign( clearLookup(), diff --git a/src/vm/utils/animate.js b/src/vm/utils/animate.js index c8b2e07..7041d4e 100644 --- a/src/vm/utils/animate.js +++ b/src/vm/utils/animate.js @@ -1,4 +1,3 @@ -import required from 'utils/required-params'; import pms from 'utils/pms'; /** @@ -34,7 +33,7 @@ import pms from 'utils/pms'; * @return {Promise} */ export default function animate(opts) { - const {values, duration, onStep} = required(opts); + const {values, duration, onStep} = opts; let {scheduleAnimationStep} = opts; // made scheduler as optional parameter diff --git a/test/unit/tests/data/mutators.test.js b/test/unit/tests/data/mutators.test.js index c06aa45..020e099 100644 --- a/test/unit/tests/data/mutators.test.js +++ b/test/unit/tests/data/mutators.test.js @@ -2,6 +2,7 @@ import {expect, createDB} from 'test/utils'; import mutate from 'data/mutators'; +import State from 'src/boot/client/State'; import Patch from 'utils/state/Patch'; import Idea from 'model/entities/Idea'; import Association from 'model/entities/Association'; @@ -14,7 +15,7 @@ describe('mutators', () => { it('should init db', async () => { // setup - const state = {data: {}}; + const state = new State(); const patchData = { db: { @@ -52,7 +53,8 @@ describe('mutators', () => { it('should add idea', async () => { // setup - const state = {data: {ideas: createDB()}}; + const state = new State(); + state.data.ideas = createDB(); const patch = new Patch({ type: 'add-idea', @@ -90,7 +92,8 @@ describe('mutators', () => { const ideasDB = createDB(); ideasDB.put({_id: 'id', value: 'old', color: 'white'}); - const state = {data: {ideas: ideasDB}}; + const state = new State(); + state.data.ideas = ideasDB; const patch = new Patch({ type: 'update-idea', @@ -118,7 +121,8 @@ describe('mutators', () => { const ideasDB = createDB(); ideasDB.put({_id: 'id', value: 'old', color: 'white'}); - const state = {data: {ideas: ideasDB}}; + const state = new State(); + state.data.ideas = ideasDB; const patch1 = new Patch({ type: 'update-idea', @@ -162,7 +166,8 @@ describe('mutators', () => { ideasDB.put({_id: 'live'}); ideasDB.put({_id: 'die'}); - const state = {data: {ideas: ideasDB}}; + const state = new State(); + state.data.ideas = ideasDB; const patch = new Patch({ type: 'remove-idea', @@ -187,7 +192,8 @@ describe('mutators', () => { it('should add association', async () => { // setup - const state = {data: {associations: createDB()}}; + const state = new State(); + state.data.associations = createDB(); const patch = new Patch({ type: 'add-association', @@ -220,7 +226,8 @@ describe('mutators', () => { const assocDB = createDB(); assocDB.put({_id: 'id', value: 'old', from: 'from'}); - const state = {data: {associations: assocDB}}; + const state = new State(); + state.data.associations = assocDB; const patch = new Patch({ type: 'update-association', @@ -253,7 +260,8 @@ describe('mutators', () => { assocDB.put({_id: 'live'}); assocDB.put({_id: 'die'}); - const state = {data: {associations: assocDB}}; + const state = new State(); + state.data.associations = assocDB; const patch = new Patch({ type: 'remove-association', @@ -281,7 +289,8 @@ describe('mutators', () => { const mindmapDB = createDB(); mindmapDB.put({_id: 'id', scale: 1, x: 100}); - const state = {data: {mindmaps: mindmapDB}}; + const state = new State(); + state.data.mindmaps = mindmapDB; const patch = new Patch({ type: 'update-mindmap', diff --git a/test/unit/tests/model/mutators/add-association.test.js b/test/unit/tests/model/mutators/add-association.test.js index 35a405d..1788975 100644 --- a/test/unit/tests/model/mutators/add-association.test.js +++ b/test/unit/tests/model/mutators/add-association.test.js @@ -2,6 +2,7 @@ import {expect} from 'test/utils'; import values from 'src/utils/get-map-values'; +import State from 'src/boot/client/State'; import Patch from 'src/utils/state/Patch'; import Mindmap from 'src/model/entities/Mindmap'; import Association from 'src/model/entities/Association'; @@ -13,7 +14,8 @@ describe('add-association', () => { it('should add association to mindmap', () => { // setup - const state = {model: {mindmap: new Mindmap()}}; + const state = new State(); + state.model.mindmap = new Mindmap(); const patch = new Patch({ type: 'add-association', diff --git a/test/unit/tests/model/mutators/add-idea.test.js b/test/unit/tests/model/mutators/add-idea.test.js index 6abac5d..1bcee83 100644 --- a/test/unit/tests/model/mutators/add-idea.test.js +++ b/test/unit/tests/model/mutators/add-idea.test.js @@ -2,6 +2,7 @@ import {expect} from 'test/utils'; import values from 'src/utils/get-map-values'; +import State from 'src/boot/client/State'; import Patch from 'src/utils/state/Patch'; import Mindmap from 'src/model/entities/Mindmap'; import Idea from 'src/model/entities/Idea'; @@ -13,7 +14,8 @@ describe('add-idea', () => { it('should add idea to mindmap', () => { // setup - const state = {model: {mindmap: new Mindmap()}}; + const state = new State(); + state.model.mindmap = new Mindmap(); const patch = new Patch({ type: 'add-idea', diff --git a/test/unit/tests/model/mutators/remove-association.test.js b/test/unit/tests/model/mutators/remove-association.test.js index 9ec34a4..392d9c4 100644 --- a/test/unit/tests/model/mutators/remove-association.test.js +++ b/test/unit/tests/model/mutators/remove-association.test.js @@ -2,6 +2,7 @@ import {expect} from 'test/utils'; import values from 'src/utils/get-map-values'; +import State from 'src/boot/client/State'; import Patch from 'src/utils/state/Patch'; import Mindmap from 'src/model/entities/Mindmap'; import Association from 'src/model/entities/Association'; @@ -20,7 +21,8 @@ describe('remove-association', () => { value: 'old' })); - const state = {model: {mindmap}}; + const state = new State(); + state.model.mindmap = mindmap; const patch = new Patch({ type: 'remove-association', @@ -39,9 +41,8 @@ describe('remove-association', () => { it('should fail if target association was not found', () => { // setup - const mindmap = new Mindmap(); - - const state = {model: {mindmap}}; + const state = new State(); + state.model.mindmap = new Mindmap(); const patch = new Patch({ type: 'remove-association', diff --git a/test/unit/tests/model/mutators/remove-idea.test.js b/test/unit/tests/model/mutators/remove-idea.test.js index e49675f..9467220 100644 --- a/test/unit/tests/model/mutators/remove-idea.test.js +++ b/test/unit/tests/model/mutators/remove-idea.test.js @@ -2,6 +2,7 @@ import {expect} from 'test/utils'; import values from 'src/utils/get-map-values'; +import State from 'src/boot/client/State'; import Patch from 'src/utils/state/Patch'; import Mindmap from 'src/model/entities/Mindmap'; import Idea from 'src/model/entities/Idea'; @@ -21,7 +22,8 @@ describe('remove-idea', () => { color: 'white' })); - const state = {model: {mindmap}}; + const state = new State(); + state.model.mindmap = mindmap; const patch = new Patch({ type: 'remove-idea', @@ -40,7 +42,8 @@ describe('remove-idea', () => { it('should fail if target idea was not found', () => { // setup - const state = {model: {mindmap: new Mindmap()}}; + const state = new State(); + state.model.mindmap = new Mindmap(); const patch = new Patch({ type: 'remove-idea', diff --git a/test/unit/tests/model/mutators/update-association.test.js b/test/unit/tests/model/mutators/update-association.test.js index 684f245..ed2bf65 100644 --- a/test/unit/tests/model/mutators/update-association.test.js +++ b/test/unit/tests/model/mutators/update-association.test.js @@ -2,6 +2,7 @@ import {expect} from 'test/utils'; import values from 'src/utils/get-map-values'; +import State from 'src/boot/client/state'; import Patch from 'src/utils/state/Patch'; import Mindmap from 'src/model/entities/Mindmap'; import Association from 'src/model/entities/Association'; @@ -20,7 +21,8 @@ describe('update-association', () => { value: 'old' })); - const state = {model: {mindmap}}; + const state = new State(); + state.model.mindmap = mindmap; const patch = new Patch({ type: 'update-association', @@ -45,7 +47,8 @@ describe('update-association', () => { // setup const mindmap = new Mindmap(); - const state = {model: {mindmap}}; + const state = new State(); + state.model.mindmap = mindmap; const patch = new Patch({ type: 'update-association', diff --git a/test/unit/tests/model/mutators/update-idea.test.js b/test/unit/tests/model/mutators/update-idea.test.js index d885804..820539a 100644 --- a/test/unit/tests/model/mutators/update-idea.test.js +++ b/test/unit/tests/model/mutators/update-idea.test.js @@ -2,6 +2,7 @@ import {expect} from 'test/utils'; import values from 'src/utils/get-map-values'; +import State from 'src/boot/client/State'; import Patch from 'src/utils/state/Patch'; import Mindmap from 'src/model/entities/Mindmap'; import Idea from 'src/model/entities/Idea'; @@ -21,7 +22,8 @@ describe('update-idea', () => { color: 'white' })); - const state = {model: {mindmap}}; + const state = new State(); + state.model.mindmap = mindmap; const patch = new Patch({ type: 'update-idea', @@ -45,7 +47,8 @@ describe('update-idea', () => { it('should fail if target idea was not found', () => { // setup - const state = {model: {mindmap: new Mindmap()}}; + const state = new State(); + state.model.mindmap = new Mindmap(); const patch = new Patch({ type: 'update-idea', diff --git a/test/unit/tests/model/mutators/update-mindmap.test.js b/test/unit/tests/model/mutators/update-mindmap.test.js index dc0774d..2c33a54 100644 --- a/test/unit/tests/model/mutators/update-mindmap.test.js +++ b/test/unit/tests/model/mutators/update-mindmap.test.js @@ -2,6 +2,7 @@ import {expect} from 'test/utils'; import mutate from 'model/mutators'; +import State from 'src/boot/client/State'; import Patch from 'src/utils/state/Patch'; import Mindmap from 'src/model/entities/Mindmap'; import Point from 'src/model/entities/Point'; @@ -17,7 +18,8 @@ describe('update-mindmap', () => { pos: new Point({x: 100, y: 0}) }); - const state = {model: {mindmap}}; + const state = new State(); + state.model.mindmap = mindmap; const patch = new Patch({ type: 'update-mindmap', diff --git a/test/unit/tests/utils/required-params.test.js b/test/unit/tests/utils/required-params.test.js index 2cf581c..f8e5f61 100644 --- a/test/unit/tests/utils/required-params.test.js +++ b/test/unit/tests/utils/required-params.test.js @@ -96,6 +96,8 @@ describe('required-params', () => { const params = requiredParams({}); // check + + // @ts-ignore const result = () => params.X; expect(result).to.not.throw();