File tree Expand file tree Collapse file tree 4 files changed +58
-4
lines changed
Expand file tree Collapse file tree 4 files changed +58
-4
lines changed Original file line number Diff line number Diff line change @@ -223,6 +223,7 @@ export function listenerFactory(
223223 case "context.replace" :
224224 case "context.refresh" :
225225 case "context.load" :
226+ case "context.set" :
226227 handleContextAction (
227228 event ,
228229 method ,
@@ -236,6 +237,7 @@ export function listenerFactory(
236237 case "state.update" :
237238 case "state.refresh" :
238239 case "state.load" :
240+ case "state.set" :
239241 handleTplStateAction (
240242 event ,
241243 method ,
@@ -687,7 +689,7 @@ function batchUpdate(
687689
688690function handleContextAction (
689691 event : Event ,
690- method : "assign" | "replace" ,
692+ method : "assign" | "replace" | "refresh" | "load" | "set" ,
691693 args : unknown [ ] | undefined ,
692694 batch : boolean ,
693695 callback : BrickEventHandlerCallback | undefined ,
@@ -717,7 +719,7 @@ function handleContextAction(
717719
718720function handleTplStateAction (
719721 event : Event ,
720- method : "update" | "refresh" | "load" ,
722+ method : "update" | "refresh" | "load" | "set" ,
721723 args : unknown [ ] | undefined ,
722724 batch : boolean ,
723725 callback : BrickEventHandlerCallback | undefined ,
Original file line number Diff line number Diff line change @@ -378,6 +378,43 @@ describe("DataStore", () => {
378378 expect ( mockCallRealTimeDataInspectHooks ) . toHaveBeenCalledTimes ( 2 ) ;
379379 } ) ;
380380
381+ test ( "context.set" , async ( ) => {
382+ setRealTimeDataInspectRoot ( { } ) ;
383+ const ctxStore = new DataStore ( "CTX" ) ;
384+ const runtimeContext = {
385+ ctxStore,
386+ } as Partial < RuntimeContext > as RuntimeContext ;
387+ ctxStore . define (
388+ [
389+ {
390+ name : "primitive" ,
391+ value : "any" ,
392+ onChange : {
393+ action : "context.set" ,
394+ args : [ "count" , "<% (count) => count + 1 %>" ] ,
395+ } ,
396+ } ,
397+ {
398+ name : "count" ,
399+ value : 0 ,
400+ } ,
401+ ] ,
402+ runtimeContext
403+ ) ;
404+ await ctxStore . waitForAll ( ) ;
405+ expect ( ctxStore . getValue ( "primitive" ) ) . toEqual ( "any" ) ;
406+ expect ( ctxStore . getValue ( "count" ) ) . toBe ( 0 ) ;
407+
408+ const newValue = { amount : 42 } ;
409+ ctxStore . updateValue ( "primitive" , newValue , "set" ) ;
410+ expect ( ctxStore . getValue ( "primitive" ) ) . toEqual ( { amount : 42 } ) ;
411+ expect ( ctxStore . getValue ( "count" ) ) . toBe ( 1 ) ;
412+
413+ ctxStore . updateValue ( "primitive" , newValue , "set" ) ;
414+ expect ( ctxStore . getValue ( "primitive" ) ) . toEqual ( { amount : 42 } ) ;
415+ expect ( ctxStore . getValue ( "count" ) ) . toBe ( 1 ) ;
416+ } ) ;
417+
381418 test ( "state and onChange" , async ( ) => {
382419 jest . useFakeTimers ( ) ;
383420 const tplStateStoreId = "tpl-state-1" ;
Original file line number Diff line number Diff line change @@ -193,7 +193,7 @@ export class DataStore<T extends DataStoreType = "CTX"> {
193193 updateValue (
194194 name : string ,
195195 value : unknown ,
196- method : "assign" | "replace" | "refresh" | "load" ,
196+ method : "assign" | "replace" | "refresh" | "load" | "set" ,
197197 callback ?: BrickEventHandlerCallback ,
198198 callbackRuntimeContext ?: RuntimeContext
199199 ) : void {
@@ -276,7 +276,7 @@ export class DataStore<T extends DataStoreType = "CTX"> {
276276
277277 if ( method === "replace" ) {
278278 item . value = value ;
279- } else {
279+ } else if ( method === "assign" ) {
280280 if ( isObject ( item . value ) ) {
281281 Object . assign ( item . value , value ) ;
282282 } else {
@@ -286,6 +286,19 @@ export class DataStore<T extends DataStoreType = "CTX"> {
286286 ) ;
287287 item . value = value ;
288288 }
289+ } else {
290+ // method === "set"
291+ // `context.set` and `state.set` is similar to React's setState,
292+ // which accepts either a value or an updater function.
293+ // And if the new value is the same as the current one, do nothing.
294+ let nextValue = value ;
295+ if ( typeof value === "function" ) {
296+ nextValue = ( value as ( prevState : unknown ) => unknown ) ( item . value ) ;
297+ }
298+ if ( Object . is ( item . value , nextValue ) ) {
299+ return ;
300+ }
301+ item . value = nextValue ;
289302 }
290303
291304 if ( this . batchUpdate ) return ;
Original file line number Diff line number Diff line change @@ -980,11 +980,13 @@ export interface BuiltinBrickEventHandler {
980980 | "context.replace"
981981 | "context.refresh"
982982 | "context.load"
983+ | "context.set"
983984
984985 // Update template state
985986 | "state.update"
986987 | "state.refresh"
987988 | "state.load"
989+ | "state.set"
988990
989991 // Find related tpl and dispatch event.
990992 | "tpl.dispatchEvent"
You can’t perform that action at this time.
0 commit comments