code: def _add_frame(
      self,
      frame_type: FrameType,
      page: Optional[int] = None,
      page_data: Optional[bytes] = None,
  ):
      if frame_type is FrameType.PAGE and (not page or not page_data):
          raise ValueError("PAGE frame without page data")
      if page_data and len(page_data) != self._page_size:
          raise ValueError("Page data is different from page size")
      if not page:
          page = 0
      if frame_type is not FrameType.PAGE:
          page_data = b""
      data = (
          frame_type.value.to_bytes(FRAME_TYPE_BYTES, ENDIAN)
          + page.to_bytes(PAGE_REFERENCE_BYTES, ENDIAN)
          + page_data
      )
      self._fd.seek(0, io.SEEK_END)
      write_to_file(
          self._fd,
          self._dir_fd,
          data,
          fsync=frame_type != FrameType.PAGE,
      )
      self._index_frame(
          frame_type, page, self._fd.tell() - self._page_size
      )
  
imports: import enum
  import io
  from logging import getLogger
  import os
  import platform
  from typing import Union, Tuple, Optional
  import cachetools
  import rwlock
  from .node import Node, FreelistNode
  from .const import ENDIAN, PAGE_REFERENCE_BYTES, OTHERS_BYTES, TreeConf, FRAME_TYPE_BYTES
label_desc: Use image node_id 7 for calling the WAL obj's underlying member method code with example usage: obj._add_frame(frame_type, page, page_data) without return types