@@ -11,13 +11,16 @@ import { invokeCallbacks } from "@/actions/helpers/invokeCallbacks";
1111import type { ContributionState } from "@/types/state/contribution" ;
1212import type { HostStore } from "@/types/state/host" ;
1313import { store } from "@/store" ;
14+ import { shallowEqualArrays } from "@/utils/compare" ;
1415
1516/**
1617 * A reference to a property of an input of a callback of a contribution.
1718 */
1819export interface PropertyRef extends ContribRef , CallbackRef , InputRef {
1920 /** The property. */
2021 property : string ;
22+ /** Property ID for memoization */
23+ id : string ;
2124}
2225
2326export function handleHostStoreChange ( ) {
@@ -44,16 +47,23 @@ export function handleHostStoreChange() {
4447 hostStore ,
4548 ) ;
4649
47- if ( callbackRequests && callbackRequests . length > 0 ) {
48- invokeCallbacks ( callbackRequests ) ;
50+ const filteredCallbackRequests = callbackRequests . filter (
51+ ( callbackRequest ) : callbackRequest is CallbackRequest =>
52+ callbackRequest !== undefined ,
53+ ) ;
54+ if ( filteredCallbackRequests && filteredCallbackRequests . length > 0 ) {
55+ invokeCallbacks ( filteredCallbackRequests ) ;
4956 }
5057}
5158
52- function getCallbackRequests (
59+ // Exporting for testing only
60+ export function getCallbackRequests (
5361 propertyRefs : PropertyRef [ ] ,
5462 contributionsRecord : Record < string , ContributionState [ ] > ,
5563 hostStore : HostStore ,
56- ) : CallbackRequest [ ] {
64+ ) : ( CallbackRequest | undefined ) [ ] {
65+ const { configuration, lastInputValues } = store . getState ( ) ;
66+ const { logging } = configuration ;
5767 return propertyRefs . map ( ( propertyRef ) => {
5868 const contributions = contributionsRecord [ propertyRef . contribPoint ] ;
5969 const contribution = contributions [ propertyRef . contribIndex ] ;
@@ -63,6 +73,27 @@ function getCallbackRequests(
6373 contribution ,
6474 hostStore ,
6575 ) ;
76+ const propRefId = propertyRef . id ;
77+ if (
78+ lastInputValues ?. [ propRefId ] &&
79+ shallowEqualArrays ( lastInputValues ?. [ propRefId ] , inputValues )
80+ ) {
81+ // Skip adding the inputValues if memoized values are returned.
82+ if ( logging ?. enabled ) {
83+ console . groupCollapsed ( "Skipping callback request" ) ;
84+ console . log ( "inputValues" , inputValues ) ;
85+ console . groupEnd ( ) ;
86+ }
87+ return ;
88+ }
89+ if ( lastInputValues ) {
90+ lastInputValues [ propRefId ] = inputValues ;
91+ store . setState ( {
92+ lastInputValues : { ...lastInputValues } ,
93+ } ) ;
94+ } else {
95+ store . setState ( { lastInputValues : { [ propRefId ] : inputValues } } ) ;
96+ }
6697 return { ...propertyRef , inputValues } ;
6798 } ) ;
6899}
@@ -92,6 +123,7 @@ function getHostStorePropertyRefs(): PropertyRef[] {
92123 callbackIndex,
93124 inputIndex,
94125 property : formatObjPath ( input . property ) ,
126+ id : `${ contribPoint } -${ contribIndex } -${ callbackIndex } -${ inputIndex } ` ,
95127 } ) ;
96128 }
97129 } ) ,
0 commit comments