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

forgo-state

Package Overview
Dependencies
Maintainers
1
Versions
96
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

forgo-state - npm Package Compare versions

Comparing version 0.0.12 to 0.0.13

90

dist/index.js

@@ -40,69 +40,35 @@ "use strict";

// concat latest updates with pending updates.
const argsToUpdatePlusPendingArgs = argsListToUpdate.concat(argsToRenderInTheNextCycle);
// make a map, of node => all args attached to node
const argsListMap = new Map();
for (const args of argsToUpdatePlusPendingArgs) {
if (args.element.node) {
const state = forgo_1.getForgoState(args.element.node);
if (state) {
const componentState = state.components[args.element.componentIndex];
if (componentState.numNodes === 1) {
let entry = argsListMap.get(args.element.node);
if (!entry) {
entry = [];
argsListMap.set(args.element.node, entry);
}
entry.push(args);
}
// This component rendered a fragment or an array
else {
const parentElement = args.element.node
.parentElement;
const childNodes = Array.from(parentElement.childNodes);
const nodeIndex = childNodes.findIndex((x) => x === args.element.node);
const nodes = childNodes.slice(nodeIndex, nodeIndex + componentState.numNodes);
for (const node of nodes) {
let entry = argsListMap.get(node);
if (!entry) {
entry = [];
argsListMap.set(node, entry);
}
entry.push(args);
}
}
const argsToUpdatePlusPendingArgs = argsToRenderInTheNextCycle.concat(argsListToUpdate.filter((x) => !argsToRenderInTheNextCycle.includes(x)));
const componentStatesAndArgs = argsToUpdatePlusPendingArgs.map((x) => {
const state = forgo_1.getForgoState(x.element.node);
if (!state) {
throw new Error("Missing state on node.");
}
else {
return [state.components[x.element.componentIndex], x];
}
});
// If a parent component is already rerendering,
// don't queue the child rerender.
const componentsToUpdate = componentStatesAndArgs.filter((item) => {
const [componentState, args] = item;
let node = args.element.node;
let state = forgo_1.getForgoState(node);
let parentStates = state.components.slice(0, args.element.componentIndex);
while (node && state) {
if (parentStates.some((x) => componentStatesAndArgs.some(([compStateInArray]) => compStateInArray.component === x.component))) {
return false;
}
}
}
// Now for each node, find the args with the lowest componentIndex
// Rendering the component with the lowest componentIndex
// The higher up components get rendered automatically.
const argsListWithMinComponentIndex = [];
for (const entries of argsListMap) {
let argsWithMinComponentIndex = undefined;
const [node, argsList] = entries;
for (const args of argsList) {
if (argsWithMinComponentIndex) {
if (args.element.componentIndex <
argsWithMinComponentIndex.element.componentIndex) {
argsWithMinComponentIndex = args;
node = node.parentElement;
if (node) {
state = forgo_1.getForgoState(node);
if (state) {
parentStates = state.components.filter((x) => x !== componentState);
}
}
else {
argsWithMinComponentIndex = args;
}
}
if (argsWithMinComponentIndex) {
argsListWithMinComponentIndex.push([node, argsWithMinComponentIndex]);
}
}
// 1. We gotta find if a node is a child of another node pending rerender
// If so, there's no need to render the descendant node.
// 2. Also, if a component renders multiple nodes, include only the root node.
const justTheNodes = argsListWithMinComponentIndex
.map(([node]) => node)
.filter((x) => x);
const argsListOfParentNodes = argsListWithMinComponentIndex.filter(([node, args]) => !justTheNodes.some((x) => x !== node && x.contains(node)) &&
node === args.element.node);
return true;
});
argsToRenderInTheNextCycle.length = 0;
for (const [node, args] of argsListOfParentNodes) {
for (const [, args] of componentsToUpdate) {
argsToRenderInTheNextCycle.push(args);

@@ -109,0 +75,0 @@ }

{
"name": "forgo-state",
"version": "0.0.12",
"version": "0.0.13",
"main": "./dist",

@@ -11,3 +11,3 @@ "author": "Jeswin Kumar<jeswinpk@agilehead.com>",

"dependencies": {
"forgo": "^0.0.36"
"forgo": "^0.0.39"
},

@@ -14,0 +14,0 @@ "devDependencies": {

@@ -7,2 +7,4 @@ import {

getForgoState,
NodeAttachedComponentState,
NodeAttachedState,
} from "forgo";

@@ -69,88 +71,55 @@

// concat latest updates with pending updates.
const argsToUpdatePlusPendingArgs = argsListToUpdate.concat(
argsToRenderInTheNextCycle
const argsToUpdatePlusPendingArgs = argsToRenderInTheNextCycle.concat(
argsListToUpdate.filter((x) => !argsToRenderInTheNextCycle.includes(x))
);
// make a map, of node => all args attached to node
const argsListMap = new Map<ChildNode, ForgoRenderArgs[]>();
for (const args of argsToUpdatePlusPendingArgs) {
if (args.element.node) {
const state = getForgoState(args.element.node);
if (state) {
const componentState =
state.components[args.element.componentIndex];
if (componentState.numNodes === 1) {
let entry = argsListMap.get(args.element.node);
if (!entry) {
entry = [];
argsListMap.set(args.element.node, entry);
}
entry.push(args);
}
// This component rendered a fragment or an array
else {
const parentElement: HTMLElement = args.element.node
.parentElement as HTMLElement;
const childNodes = Array.from(parentElement.childNodes);
const nodeIndex = childNodes.findIndex(
(x) => x === args.element.node
);
const nodes = childNodes.slice(
nodeIndex,
nodeIndex + componentState.numNodes
);
for (const node of nodes) {
let entry = argsListMap.get(node);
if (!entry) {
entry = [];
argsListMap.set(node, entry);
}
entry.push(args);
}
}
}
const componentStatesAndArgs: [
NodeAttachedComponentState<any>,
ForgoRenderArgs
][] = argsToUpdatePlusPendingArgs.map((x) => {
const state = getForgoState(x.element.node as ChildNode);
if (!state) {
throw new Error("Missing state on node.");
} else {
return [state.components[x.element.componentIndex], x];
}
}
});
// Now for each node, find the args with the lowest componentIndex
// Rendering the component with the lowest componentIndex
// The higher up components get rendered automatically.
const argsListWithMinComponentIndex: [ChildNode, ForgoRenderArgs][] = [];
// If a parent component is already rerendering,
// don't queue the child rerender.
const componentsToUpdate = componentStatesAndArgs.filter((item) => {
const [componentState, args] = item;
for (const entries of argsListMap) {
let argsWithMinComponentIndex: ForgoRenderArgs | undefined = undefined;
const [node, argsList] = entries;
for (const args of argsList) {
if (argsWithMinComponentIndex) {
if (
args.element.componentIndex <
argsWithMinComponentIndex.element.componentIndex
) {
argsWithMinComponentIndex = args;
let node: ChildNode | null = args.element.node as ChildNode;
let state: NodeAttachedState | undefined = getForgoState(node);
let parentStates = (state as NodeAttachedState).components.slice(
0,
args.element.componentIndex
);
while (node && state) {
if (
parentStates.some((x) =>
componentStatesAndArgs.some(
([compStateInArray]) =>
compStateInArray.component === x.component
)
)
) {
return false;
}
node = node.parentElement;
if (node) {
state = getForgoState(node);
if (state) {
parentStates = state.components.filter(
(x) => x !== componentState
);
}
} else {
argsWithMinComponentIndex = args;
}
}
if (argsWithMinComponentIndex) {
argsListWithMinComponentIndex.push([node, argsWithMinComponentIndex]);
}
}
return true;
});
// 1. We gotta find if a node is a child of another node pending rerender
// If so, there's no need to render the descendant node.
// 2. Also, if a component renders multiple nodes, include only the root node.
const justTheNodes = argsListWithMinComponentIndex
.map(([node]) => node)
.filter((x) => x) as ChildNode[];
const argsListOfParentNodes = argsListWithMinComponentIndex.filter(
([node, args]) =>
!justTheNodes.some((x) => x !== node && x.contains(node)) &&
node === args.element.node
);
argsToRenderInTheNextCycle.length = 0;
for (const [node, args] of argsListOfParentNodes) {
for (const [, args] of componentsToUpdate) {
argsToRenderInTheNextCycle.push(args);

@@ -157,0 +126,0 @@ }

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