import { proxyActivities , WorkflowInterceptors , setHandler , defineQuery , condition } from '@temporalio/workflow' ; import { createDraft , enablePatches , finishDraft } from 'immer' ; import type { createActivities } from '../activities' ; const { publish } = proxyActivities < ReturnType < typeof createActivities > > ( { startToCloseTimeout : '30 minutes' , } ) ; export interface DurableObjectState < T > { state : T ; } export interface Versioned < T > { version : number ; value : T ; } enablePatches ( ) ; returns export function subscribableState < T > ( initialValue ) { state . draft . value = initialValue ; state . current . value = initialValue ; setHandler ( defineQuery < Versioned < T > > ( 'getValue' ) , ( ) => ( { value : state . current . value , version : state . version , } ) ) ; const proxy = { } ; Object . defineProperty ( proxy , 'value' , { get : ( ) => { return state . draft . value ; } , set : ( value ) => { state . draft . value = value ; } , } ) ; return proxy as { value : T ; } ; } const state = { version : 0 , current : { } as any , draft : undefined as any , lastPublishPromise : Promise . resolve ( ) , syncComplete : false , workflowComplete : false , } ; export const interceptors = ( ) : WorkflowInterceptors => ( { internals : [ { /**
             * When the Workflow is "activated" create a new draft of the state
             */ activate ( input , next ) { if ( input . batchIndex === 0 ) { state . draft = createDraft ( state . current ) ; } return next ( input ) ; } , /**
             * Right before the Workflow activation is concluded, finish the draft
             * and publish a new version with the patches
             */ concludeActivation ( { commands } , next ) { state . current = finishDraft ( state . draft , ( patches ) => { if ( patches . length === 0 ) return ; state . version ++ ; const { lastPublishPromise } = state ; state . lastPublishPromise = lastPublishPromise . then ( ( ) => publish ( state . version , patches ) . catch ( ( ) => undefined ) ) ; } ) ; if ( state . workflowComplete ) { state . lastPublishPromise . then ( ( ) => ( state . syncComplete = true ) , ( ) => undefined ) ; } try { return next ( { commands } ) ; } finally { state . draft = undefined ; } } , } , ] , inbound : [ { /**
             * Intercept Workflow execution and prevent it from completing until all
             * of the patches have been published.
             */ async execute ( input , next ) { try { return await next ( input ) ; } finally { state . workflowComplete = true ; await condition ( ( ) => state . syncComplete ) ; } } , } , ] , outbound : [ ] , } ) ;