wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
{"version":3,"file":"operation.js","sourceRoot":"","sources":["../../../src/poller/operation.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n  LroError,\n  InnerError,\n  Operation,\n  OperationStatus,\n  RestorableOperationState,\n  StateProxy,\n} from \"./models.js\";\nimport { logger } from \"../logger.js\";\nimport { terminalStates } from \"./constants.js\";\n\n/**\n * Deserializes the state\n */\nexport function deserializeState<TState>(\n  serializedState: string,\n): RestorableOperationState<TState> {\n  try {\n    return JSON.parse(serializedState).state;\n  } catch (e) {\n    throw new Error(`Unable to deserialize input state: ${serializedState}`);\n  }\n}\n\nfunction setStateError<TState, TResult>(inputs: {\n  state: TState;\n  stateProxy: StateProxy<TState, TResult>;\n  isOperationError: (error: Error) => boolean;\n}): (error: Error) => never {\n  const { state, stateProxy, isOperationError } = inputs;\n  return (error: Error) => {\n    if (isOperationError(error)) {\n      stateProxy.setError(state, error);\n      stateProxy.setFailed(state);\n    }\n    throw error;\n  };\n}\n\nfunction appendReadableErrorMessage(currentMessage: string, innerMessage: string): string {\n  let message = currentMessage;\n  if (message.slice(-1) !== \".\") {\n    message = message + \".\";\n  }\n  return message + \" \" + innerMessage;\n}\n\nfunction simplifyError(err: LroError): {\n  code: string;\n  message: string;\n} {\n  let message = err.message;\n  let code = err.code;\n  let curErr = err as InnerError;\n  while (curErr.innererror) {\n    curErr = curErr.innererror;\n    code = curErr.code;\n    message = appendReadableErrorMessage(message, curErr.message);\n  }\n  return {\n    code,\n    message,\n  };\n}\n\nfunction processOperationStatus<TState, TResult, TResponse>(result: {\n  status: OperationStatus;\n  response: TResponse;\n  state: RestorableOperationState<TState>;\n  stateProxy: StateProxy<TState, TResult>;\n  processResult?: (result: TResponse, state: TState) => TResult;\n  getError?: (response: TResponse) => LroError | undefined;\n  isDone?: (lastResponse: TResponse, state: TState) => boolean;\n  setErrorAsResult: boolean;\n}): void {\n  const { state, stateProxy, status, isDone, processResult, getError, response, setErrorAsResult } =\n    result;\n  switch (status) {\n    case \"succeeded\": {\n      stateProxy.setSucceeded(state);\n      break;\n    }\n    case \"failed\": {\n      const err = getError?.(response);\n      let postfix = \"\";\n      if (err) {\n        const { code, message } = simplifyError(err);\n        postfix = `. ${code}. ${message}`;\n      }\n      const errStr = `The long-running operation has failed${postfix}`;\n      stateProxy.setError(state, new Error(errStr));\n      stateProxy.setFailed(state);\n      logger.warning(errStr);\n      break;\n    }\n    case \"canceled\": {\n      stateProxy.setCanceled(state);\n      break;\n    }\n  }\n  if (\n    isDone?.(response, state) ||\n    (isDone === undefined &&\n      [\"succeeded\", \"canceled\"].concat(setErrorAsResult ? [] : [\"failed\"]).includes(status))\n  ) {\n    stateProxy.setResult(\n      state,\n      buildResult({\n        response,\n        state,\n        processResult,\n      }),\n    );\n  }\n}\n\nfunction buildResult<TResponse, TResult, TState>(inputs: {\n  response: TResponse;\n  state: TState;\n  processResult?: (result: TResponse, state: TState) => TResult;\n}): TResult {\n  const { processResult, response, state } = inputs;\n  return processResult ? processResult(response, state) : (response as unknown as TResult);\n}\n\n/**\n * Initiates the long-running operation.\n */\nexport async function initOperation<TResponse, TResult, TState>(inputs: {\n  init: Operation<TResponse, unknown>[\"init\"];\n  stateProxy: StateProxy<TState, TResult>;\n  getOperationStatus: (inputs: {\n    response: TResponse;\n    state: RestorableOperationState<TState>;\n    operationLocation?: string;\n  }) => OperationStatus;\n  processResult?: (result: TResponse, state: TState) => TResult;\n  withOperationLocation?: (operationLocation: string, isUpdated: boolean) => void;\n  setErrorAsResult: boolean;\n}): Promise<RestorableOperationState<TState>> {\n  const {\n    init,\n    stateProxy,\n    processResult,\n    getOperationStatus,\n    withOperationLocation,\n    setErrorAsResult,\n  } = inputs;\n  const { operationLocation, resourceLocation, metadata, response } = await init();\n  if (operationLocation) withOperationLocation?.(operationLocation, false);\n  const config = {\n    metadata,\n    operationLocation,\n    resourceLocation,\n  };\n  logger.verbose(`LRO: Operation description:`, config);\n  const state = stateProxy.initState(config);\n  const status = getOperationStatus({ response, state, operationLocation });\n  processOperationStatus({ state, status, stateProxy, response, setErrorAsResult, processResult });\n  return state;\n}\n\nasync function pollOperationHelper<TResponse, TState, TResult, TOptions>(inputs: {\n  poll: Operation<TResponse, TOptions>[\"poll\"];\n  stateProxy: StateProxy<TState, TResult>;\n  state: RestorableOperationState<TState>;\n  operationLocation: string;\n  getOperationStatus: (\n    response: TResponse,\n    state: RestorableOperationState<TState>,\n  ) => OperationStatus;\n  getResourceLocation: (\n    response: TResponse,\n    state: RestorableOperationState<TState>,\n  ) => string | undefined;\n  isOperationError: (error: Error) => boolean;\n  options?: TOptions;\n}): Promise<{\n  status: OperationStatus;\n  response: TResponse;\n}> {\n  const {\n    poll,\n    state,\n    stateProxy,\n    operationLocation,\n    getOperationStatus,\n    getResourceLocation,\n    isOperationError,\n    options,\n  } = inputs;\n  const response = await poll(operationLocation, options).catch(\n    setStateError({\n      state,\n      stateProxy,\n      isOperationError,\n    }),\n  );\n  const status = getOperationStatus(response, state);\n  logger.verbose(\n    `LRO: Status:\\n\\tPolling from: ${\n      state.config.operationLocation\n    }\\n\\tOperation status: ${status}\\n\\tPolling status: ${\n      terminalStates.includes(status) ? \"Stopped\" : \"Running\"\n    }`,\n  );\n  if (status === \"succeeded\") {\n    const resourceLocation = getResourceLocation(response, state);\n    if (resourceLocation !== undefined) {\n      return {\n        response: await poll(resourceLocation).catch(\n          setStateError({ state, stateProxy, isOperationError }),\n        ),\n        status,\n      };\n    }\n  }\n  return { response, status };\n}\n\n/** Polls the long-running operation. */\nexport async function pollOperation<TResponse, TState, TResult, TOptions>(inputs: {\n  poll: Operation<TResponse, TOptions>[\"poll\"];\n  stateProxy: StateProxy<TState, TResult>;\n  state: RestorableOperationState<TState>;\n  getOperationStatus: (\n    response: TResponse,\n    state: RestorableOperationState<TState>,\n  ) => OperationStatus;\n  getResourceLocation: (\n    response: TResponse,\n    state: RestorableOperationState<TState>,\n  ) => string | undefined;\n  isOperationError: (error: Error) => boolean;\n  getPollingInterval?: (response: TResponse) => number | undefined;\n  setDelay: (intervalInMs: number) => void;\n  getOperationLocation?: (\n    response: TResponse,\n    state: RestorableOperationState<TState>,\n  ) => string | undefined;\n  withOperationLocation?: (operationLocation: string, isUpdated: boolean) => void;\n  processResult?: (result: TResponse, state: TState) => TResult;\n  getError?: (response: TResponse) => LroError | undefined;\n  updateState?: (state: TState, lastResponse: TResponse) => void;\n  isDone?: (lastResponse: TResponse, state: TState) => boolean;\n  setErrorAsResult: boolean;\n  options?: TOptions;\n}): Promise<void> {\n  const {\n    poll,\n    state,\n    stateProxy,\n    options,\n    getOperationStatus,\n    getResourceLocation,\n    getOperationLocation,\n    isOperationError,\n    withOperationLocation,\n    getPollingInterval,\n    processResult,\n    getError,\n    updateState,\n    setDelay,\n    isDone,\n    setErrorAsResult,\n  } = inputs;\n  const { operationLocation } = state.config;\n  if (operationLocation !== undefined) {\n    const { response, status } = await pollOperationHelper({\n      poll,\n      getOperationStatus,\n      state,\n      stateProxy,\n      operationLocation,\n      getResourceLocation,\n      isOperationError,\n      options,\n    });\n    processOperationStatus({\n      status,\n      response,\n      state,\n      stateProxy,\n      isDone,\n      processResult,\n      getError,\n      setErrorAsResult,\n    });\n\n    if (!terminalStates.includes(status)) {\n      const intervalInMs = getPollingInterval?.(response);\n      if (intervalInMs) setDelay(intervalInMs);\n      const location = getOperationLocation?.(response, state);\n      if (location !== undefined) {\n        const isUpdated = operationLocation !== location;\n        state.config.operationLocation = location;\n        withOperationLocation?.(location, isUpdated);\n      } else withOperationLocation?.(operationLocation, false);\n    }\n    updateState?.(state, response);\n  }\n}\n"]}