Socket
Socket
Sign inDemoInstall

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 1.0.33 to 1.0.34

1

dist/index.d.ts
import { ForgoComponent, ForgoElementProps } from "forgo";
export declare type ForgoProxyState = {};
export declare function defineState<TState extends Record<string, any>>(state: TState): TState;
export declare function bindToStates<TState, TProps extends ForgoElementProps>(states: TState[], component: ForgoComponent<TProps>): ForgoComponent<TProps>;
export declare function bindToStateProps<TState, TProps extends ForgoElementProps>(stateBindings: [state: TState, propGetter?: (state: TState) => any[]][], component: ForgoComponent<TProps>): ForgoComponent<TProps>;

58

dist/index.js

@@ -0,9 +1,16 @@

/*
How it works:
- Users create JS proxies using the defineState() function.
- They bind this state (the proxy object) to various components via bindToStates() and bindToStateProps() functions.
- Since the proxy let's us capture changes to itself, we trigger component rerenders (on bound components) when that happens.
*/
import { rerender, getForgoState, } from "forgo";
const stateMap = new Map();
const stateToComponentsMap = new Map();
export function defineState(state) {
const handlers = {
set(target, prop, value) {
const entries = stateMap.get(proxy);
const entries = stateToComponentsMap.get(proxy);
// if bound to the state directly, add for updation on any state change.
const argsForUncheckedUpdation = entries
const stateBoundComponentArgs = entries
? entries

@@ -13,23 +20,20 @@ .filter((x) => !x.propGetter)

: [];
const propBoundComponents = entries
? entries.filter((x) => x.propGetter)
: [];
// Get the props before update
let propsToCompare = entries
? entries
.filter((x) => x.propGetter)
.map((x) => ({
args: x.args,
props: x.propGetter(target),
}))
: [];
let propBoundComponentArgs = propBoundComponents.map((x) => ({
args: x.args,
props: x.propGetter(target),
}));
target[prop] = value;
// Get the props after update
let updatedProps = entries
? entries
.filter((x) => x.propGetter)
.map((x) => ({
args: x.args,
props: x.propGetter(target),
}))
: [];
// concat state based updates and props based updates
const argsListToUpdate = argsForUncheckedUpdation.concat(propsToCompare
let updatedProps = propBoundComponents.map((x) => ({
args: x.args,
props: x.propGetter(target),
}));
// State bound components (a) need to be rerendered anyway.
// Prop bound components (b) are rendendered if changed.
// So concat (a) and (b)
const argsListToUpdate = stateBoundComponentArgs.concat(propBoundComponentArgs
.filter((oldProp, i) => oldProp.props.some((p, j) => p !== updatedProps[i].props[j]))

@@ -49,3 +53,3 @@ .map((x) => x.args));

// If a parent component is already rerendering,
// don't queue the child rerender.
// don't queue the child rerender.
const componentsToUpdate = componentStatesAndArgs.filter((item) => {

@@ -87,3 +91,3 @@ const [componentState, args] = item;

for (const args of argsToRenderInTheNextCycle) {
if (args.element.node) {
if (args.element.node && args.element.node.isConnected) {
rerender(args.element);

@@ -101,6 +105,6 @@ }

for (const [state, propGetter] of stateBindings) {
let entries = stateMap.get(state);
let entries = stateToComponentsMap.get(state);
if (!entries) {
entries = [];
stateMap.set(state, entries);
stateToComponentsMap.set(state, entries);
}

@@ -129,5 +133,5 @@ if (propGetter) {

for (const [state] of stateBindings) {
let entry = stateMap.get(state);
let entry = stateToComponentsMap.get(state);
if (entry) {
stateMap.set(state, entry.filter((x) => x.component !== wrappedComponent));
stateToComponentsMap.set(state, entry.filter((x) => x.component !== wrappedComponent));
}

@@ -134,0 +138,0 @@ else {

{
"name": "forgo-state",
"version": "1.0.33",
"version": "1.0.34",
"type": "module",

@@ -29,2 +29,3 @@ "main": "./dist/index.js",

"build": "npm run clean && mkdir -p dist && npx tsc",
"build-dev": "npx tsc",
"test": "mocha dist/test/test.js"

@@ -31,0 +32,0 @@ },

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

/*
How it works:
- Users create JS proxies using the defineState() function.
- They bind this state (the proxy object) to various components via bindToStates() and bindToStateProps() functions.
- Since the proxy let's us capture changes to itself, we trigger component rerenders (on bound components) when that happens.
*/
import {

@@ -11,5 +19,3 @@ ForgoRenderArgs,

export type ForgoProxyState = {};
type StateMapEntry<TProps extends ForgoElementProps> = {
type StateBoundComponentInfo<TProps extends ForgoElementProps> = {
component: ForgoComponent<TProps>;

@@ -19,7 +25,8 @@ args: ForgoRenderArgs;

type RerenderOnAnyChange<TState, TProps extends ForgoElementProps> = {
type PropertyBoundComponentInfo<TState, TProps extends ForgoElementProps> = {
propGetter: (state: TState) => any[];
} & StateMapEntry<TProps>;
} & StateBoundComponentInfo<TProps>;
const stateMap: Map<any, StateMapEntry<any>[]> = new Map();
const stateToComponentsMap: Map<any, StateBoundComponentInfo<any>[]> =
new Map();

@@ -31,36 +38,42 @@ export function defineState<TState extends Record<string, any>>(

set(target: TState, prop: string & keyof TState, value: any) {
const entries = stateMap.get(proxy);
const entries = stateToComponentsMap.get(proxy);
// if bound to the state directly, add for updation on any state change.
const argsForUncheckedUpdation: ForgoRenderArgs[] = entries
const stateBoundComponentArgs: ForgoRenderArgs[] = entries
? entries
.filter((x) => !(x as RerenderOnAnyChange<TState, any>).propGetter)
.filter(
(x) => !(x as PropertyBoundComponentInfo<TState, any>).propGetter
)
.map((x) => x.args)
: [];
// Get the props before update
let propsToCompare = entries
? entries
.filter((x) => (x as RerenderOnAnyChange<TState, any>).propGetter)
.map((x) => ({
args: x.args,
props: (x as RerenderOnAnyChange<TState, any>).propGetter(target),
}))
const propBoundComponents = entries
? entries.filter(
(x) => (x as PropertyBoundComponentInfo<TState, any>).propGetter
)
: [];
// Get the props before update
let propBoundComponentArgs = propBoundComponents.map((x) => ({
args: x.args,
props: (x as PropertyBoundComponentInfo<TState, any>).propGetter(
target
),
}));
target[prop] = value;
// Get the props after update
let updatedProps = entries
? entries
.filter((x) => (x as RerenderOnAnyChange<TState, any>).propGetter)
.map((x) => ({
args: x.args,
props: (x as RerenderOnAnyChange<TState, any>).propGetter(target),
}))
: [];
let updatedProps = propBoundComponents.map((x) => ({
args: x.args,
props: (x as PropertyBoundComponentInfo<TState, any>).propGetter(
target
),
}));
// concat state based updates and props based updates
const argsListToUpdate = argsForUncheckedUpdation.concat(
propsToCompare
// State bound components (a) need to be rerendered anyway.
// Prop bound components (b) are rendendered if changed.
// So concat (a) and (b)
const argsListToUpdate = stateBoundComponentArgs.concat(
propBoundComponentArgs
.filter((oldProp, i) =>

@@ -90,3 +103,3 @@ oldProp.props.some((p, j) => p !== updatedProps[i].props[j])

// If a parent component is already rerendering,
// don't queue the child rerender.
// don't queue the child rerender.
const componentsToUpdate = componentStatesAndArgs.filter((item) => {

@@ -148,3 +161,3 @@ const [componentState, args] = item;

for (const args of argsToRenderInTheNextCycle) {
if (args.element.node) {
if (args.element.node && args.element.node.isConnected) {
rerender(args.element);

@@ -175,11 +188,11 @@ }

for (const [state, propGetter] of stateBindings) {
let entries = stateMap.get(state);
let entries = stateToComponentsMap.get(state);
if (!entries) {
entries = [];
stateMap.set(state, entries);
stateToComponentsMap.set(state, entries);
}
if (propGetter) {
const newEntry: RerenderOnAnyChange<TState, TProps> = {
const newEntry: PropertyBoundComponentInfo<TState, TProps> = {
component: wrappedComponent,

@@ -192,3 +205,3 @@ propGetter,

} else {
const newEntry: StateMapEntry<TProps> = {
const newEntry: StateBoundComponentInfo<TProps> = {
component: wrappedComponent,

@@ -208,6 +221,6 @@ args,

for (const [state] of stateBindings) {
let entry = stateMap.get(state);
let entry = stateToComponentsMap.get(state);
if (entry) {
stateMap.set(
stateToComponentsMap.set(
state,

@@ -214,0 +227,0 @@ entry.filter((x) => x.component !== wrappedComponent)

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