docs: def asjsonld(
      inst,
      recurse=True,
      filter=None,
      dict_factory=dict,
      retain_collection_types=False,
      export_context=True,
      basedir=None,
  ):
      """Dump a JSON-LD class to the JSON with generated ``@context`` field."""
      jsonld_fields = inst.__class__._jsonld_fields
      attrs = tuple(
          field
          for field in fields(inst.__class__) if field.name in jsonld_fields
      )
      rv = dict_factory()
  
      def convert_value(v):
          """Convert special types."""
          if isinstance(v, Path):
              v = str(v)
              return os.path.relpath(v, str(basedir)) if basedir else v
          return v
  
      for a in attrs:
          v = getattr(inst, a.name)
  
          # skip proxies
          if isinstance(v, weakref.ReferenceType):
              continue
  
          # do not export context for containers
          ec = export_context and KEY_CLS not in a.metadata
  
          if filter is not None and not filter(a, v):
              continue
          if recurse is True:
              if has(v.__class__):
                  rv[a.name] = asjsonld(
                      v,
                      recurse=True,
                      filter=filter,
                      dict_factory=dict_factory,
                      basedir=basedir,
                  )
              elif isinstance(v, (tuple, list, set)):
                  cf = v.__class__ if retain_collection_types is True else list
                  rv[a.name] = cf([
                      asjsonld(
                          i,
                          recurse=True,
                          filter=filter,
                          dict_factory=dict_factory,
                          export_context=ec,
                          basedir=basedir,
                      ) if has(i.__class__) else i for i in v
                  ])
              elif isinstance(v, dict):
                  df = dict_factory
                  rv[a.name] = df((
                      asjsonld(
                          kk,
                          dict_factory=df,
                          basedir=basedir,
                      ) if has(kk.__class__) else convert_value(kk),
                      asjsonld(
                          vv,
                          dict_factory=df,
                          export_context=ec,
                          basedir=basedir,
                      ) if has(vv.__class__) else vv
                  ) for kk, vv in iteritems(v))
              else:
                  rv[a.name] = convert_value(v)
          else:
              rv[a.name] = convert_value(v)
  
      inst_cls = type(inst)
  
      if export_context:
          rv['@context'] = deepcopy(inst_cls._jsonld_context)
  
      if inst_cls._jsonld_type:
          rv['@type'] = inst_cls._jsonld_type
      return rv