forgo-state
Advanced tools
Comparing version 2.0.0-alpha.0 to 2.0.0
@@ -1,4 +0,4 @@ | ||
import { Component } from "forgo"; | ||
import { Component, ForgoComponent } from "forgo"; | ||
export declare function defineState<TState extends Record<string, any>>(state: TState): TState; | ||
export declare function bindToStates<TState>(states: TState[], component: Component<any>): void; | ||
export declare function bindToStateProps<TState>(stateBindings: [state: TState, propGetter?: (state: TState) => any[]][], component: Component<any>): void; | ||
export declare function bindToStates<TState, TProps extends object>(states: TState[], component: Component<TProps>): Component<TProps>; | ||
export declare function bindToStateProps<TState, TProps extends object>(stateBindings: [state: TState, propGetter?: (state: TState) => any[]][], suppliedComponent: Component<TProps> | ForgoComponent<TProps>): Component<TProps>; |
@@ -8,3 +8,3 @@ /* | ||
*/ | ||
import { rerender, getForgoState, } from "forgo"; | ||
import { Component, getForgoState, legacyComponentSyntaxCompat, } from "forgo"; | ||
const stateToComponentsMap = new Map(); | ||
@@ -43,3 +43,3 @@ export function defineState(state) { | ||
])); | ||
const componentStatesAndArgs = argsToUpdatePlusPendingArgs.map((component) => { | ||
const componentStatesAndArgs = argsToUpdatePlusPendingArgs.map((component, index) => { | ||
const state = getForgoState(component.__internal.element.node); | ||
@@ -49,8 +49,7 @@ if (!state) { | ||
} | ||
else { | ||
return [ | ||
state.components[component.__internal.element.componentIndex], | ||
component, | ||
]; | ||
const componentState = state.components[component.__internal.element.componentIndex]; | ||
if (!componentState) { | ||
throw new Error("Attempted to update a component that doesn't exist anymore"); | ||
} | ||
return [componentState, component]; | ||
}); | ||
@@ -94,19 +93,17 @@ // If a parent component is already rerendering, | ||
function doRender() { | ||
if (componentsToRenderInTheNextCycle.size > 0) { | ||
for (const component of componentsToRenderInTheNextCycle) { | ||
if (component.__internal.element.node && | ||
component.__internal.element.node.isConnected) { | ||
// Dequeue the component before the render, so that if the component | ||
// triggers more renders of itself they don't get no-op'd | ||
componentsToRenderInTheNextCycle.delete(component); | ||
rerender(component.__internal.element); | ||
} | ||
} | ||
} | ||
Array.from(componentsToRenderInTheNextCycle).forEach((component) => { | ||
// Dequeue the component before the render, so that if the component | ||
// triggers more renders of itself they don't get no-op'd | ||
componentsToRenderInTheNextCycle.delete(component); | ||
component.update(); | ||
}); | ||
} | ||
export function bindToStates(states, component) { | ||
bindToStateProps(states.map((state) => [state, undefined]), component); | ||
return bindToStateProps(states.map((state) => [state, undefined]), component); | ||
} | ||
export function bindToStateProps(stateBindings, component) { | ||
component.addEventListener("mount", () => { | ||
export function bindToStateProps(stateBindings, suppliedComponent) { | ||
const component = suppliedComponent instanceof Component | ||
? suppliedComponent | ||
: legacyComponentSyntaxCompat(suppliedComponent); | ||
component.mount(() => { | ||
for (const [state, propGetter] of stateBindings) { | ||
@@ -133,7 +130,9 @@ let entries = stateToComponentsMap.get(state); | ||
}); | ||
component.addEventListener("unmount", () => { | ||
component.unmount(() => { | ||
for (const [state] of stateBindings) { | ||
let entry = stateToComponentsMap.get(state); | ||
if (entry) { | ||
stateToComponentsMap.set(state, entry.filter((x) => x.component !== component)); | ||
entry.splice(entry.findIndex((x) => x.component === component), 1); | ||
// This could be optimized into an unshift / pop at the specific index | ||
componentsToRenderInTheNextCycle.delete(component); | ||
} | ||
@@ -145,3 +144,6 @@ else { | ||
}); | ||
// TODO: We only do this to avoid breaking compat with the legacy component | ||
// syntax, but with Forgo v4 it won't be necessary. | ||
return component; | ||
} | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "forgo-state", | ||
"version": "2.0.0-alpha.0", | ||
"version": "2.0.0", | ||
"type": "module", | ||
@@ -13,14 +13,16 @@ "main": "./dist/index.js", | ||
"peerDependencies": { | ||
"forgo": "^4.0.0-alpha.0" | ||
"forgo": "^4.0.4" | ||
}, | ||
"devDependencies": { | ||
"@types/jsdom": "^16.2.14", | ||
"@types/mocha": "^9.1.0", | ||
"@types/jsdom": "^20.0.1", | ||
"@types/mocha": "^10.0.1", | ||
"@types/should": "^13.0.0", | ||
"@types/source-map-support": "^0.5.6", | ||
"esm": "^3.2.25", | ||
"jsdom": "^19.0.0", | ||
"mocha": "^9.2.2", | ||
"rimraf": "^3.0.2", | ||
"jsdom": "^21.1.0", | ||
"mocha": "^10.2.0", | ||
"rimraf": "^4.1.2", | ||
"should": "^13.2.3", | ||
"typescript": "^4.6.3" | ||
"source-map-support": "^0.5.21", | ||
"typescript": "^4.9.5" | ||
}, | ||
@@ -27,0 +29,0 @@ "scripts": { |
@@ -11,6 +11,6 @@ /* | ||
Component, | ||
ForgoElementProps, | ||
rerender, | ||
ComponentState, | ||
getForgoState, | ||
NodeAttachedComponentState, | ||
legacyComponentSyntaxCompat, | ||
ForgoComponent, | ||
NodeAttachedState, | ||
@@ -20,3 +20,3 @@ } from "forgo"; | ||
interface StateBoundComponentInfo { | ||
component: Component; | ||
component: Component<any>; | ||
} | ||
@@ -84,5 +84,5 @@ | ||
const componentStatesAndArgs: [ | ||
NodeAttachedComponentState<any>, | ||
ComponentState<any>, | ||
Component | ||
][] = argsToUpdatePlusPendingArgs.map((component) => { | ||
][] = argsToUpdatePlusPendingArgs.map((component, index) => { | ||
const state = getForgoState( | ||
@@ -93,8 +93,12 @@ component.__internal.element.node as ChildNode | ||
throw new Error("Missing state on node."); | ||
} else { | ||
return [ | ||
state.components[component.__internal.element.componentIndex], | ||
component, | ||
]; | ||
} | ||
const componentState: ComponentState<any> = | ||
state.components[component.__internal.element.componentIndex]; | ||
if (!componentState) { | ||
throw new Error( | ||
"Attempted to update a component that doesn't exist anymore" | ||
); | ||
} | ||
return [componentState, component]; | ||
}); | ||
@@ -160,26 +164,19 @@ | ||
// had queued, plus everything the subrender enqueues | ||
const componentsToRenderInTheNextCycle = new Set<Component>(); | ||
const componentsToRenderInTheNextCycle = new Set<Component<any>>(); | ||
function doRender() { | ||
if (componentsToRenderInTheNextCycle.size > 0) { | ||
for (const component of componentsToRenderInTheNextCycle) { | ||
if ( | ||
component.__internal.element.node && | ||
component.__internal.element.node.isConnected | ||
) { | ||
// Dequeue the component before the render, so that if the component | ||
// triggers more renders of itself they don't get no-op'd | ||
componentsToRenderInTheNextCycle.delete(component); | ||
Array.from(componentsToRenderInTheNextCycle).forEach((component) => { | ||
// Dequeue the component before the render, so that if the component | ||
// triggers more renders of itself they don't get no-op'd | ||
componentsToRenderInTheNextCycle.delete(component); | ||
rerender(component.__internal.element); | ||
} | ||
} | ||
} | ||
component.update(); | ||
}); | ||
} | ||
export function bindToStates<TState>( | ||
export function bindToStates<TState, TProps extends object>( | ||
states: TState[], | ||
component: Component<any> | ||
): void { | ||
bindToStateProps( | ||
component: Component<TProps> | ||
): Component<TProps> { | ||
return bindToStateProps( | ||
states.map((state) => [state, undefined]), | ||
@@ -190,7 +187,12 @@ component | ||
export function bindToStateProps<TState>( | ||
export function bindToStateProps<TState, TProps extends object>( | ||
stateBindings: [state: TState, propGetter?: (state: TState) => any[]][], | ||
component: Component<any> | ||
): void { | ||
component.addEventListener("mount", () => { | ||
suppliedComponent: Component<TProps> | ForgoComponent<TProps> | ||
): Component<TProps> { | ||
const component = | ||
suppliedComponent instanceof Component | ||
? suppliedComponent | ||
: legacyComponentSyntaxCompat(suppliedComponent); | ||
component.mount(() => { | ||
for (const [state, propGetter] of stateBindings) { | ||
@@ -221,3 +223,3 @@ let entries = stateToComponentsMap.get(state); | ||
component.addEventListener("unmount", () => { | ||
component.unmount(() => { | ||
for (const [state] of stateBindings) { | ||
@@ -227,6 +229,8 @@ let entry = stateToComponentsMap.get(state); | ||
if (entry) { | ||
stateToComponentsMap.set( | ||
state, | ||
entry.filter((x) => x.component !== component) | ||
entry.splice( | ||
entry.findIndex((x) => x.component === component), | ||
1 | ||
); | ||
// This could be optimized into an unshift / pop at the specific index | ||
componentsToRenderInTheNextCycle.delete(component); | ||
} else { | ||
@@ -237,2 +241,6 @@ throw new Error("Component entry missing in state map."); | ||
}); | ||
// TODO: We only do this to avoid breaking compat with the legacy component | ||
// syntax, but with Forgo v4 it won't be necessary. | ||
return component; | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
24371
365
1
0
11