diff --git a/R/Field.R b/R/Field.R
index 2f68952..5d1e86e 100644
--- a/R/Field.R
+++ b/R/Field.R
@@ -1,13 +1,15 @@
#' @title Field
#'
-#' @noRd
-#'
#' @description
#' A field in a registry.
Field <- R6::R6Class( # nolint object_name_linter
"Field",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param type The type of the field. Can be one of:
#' "IntegerField", "JSONField", "OneToOneField", "SmallIntegerField",
#' "BigIntegerField", "AutoField", "BigAutoField", "BooleanField", "TextField",
@@ -94,47 +96,58 @@ Field <- R6::R6Class( # nolint object_name_linter
.related_module_name = NULL
),
active = list(
- #' @return The type of the field.
+ #' @field type (`character(1)`)\cr
+ #' The type of the field.
type = function() {
private$.type
},
- #' @return The through value of the field.
+ #' @field through (`list()` or `NULL`)\cr
+ #' The through value of the field.
through = function() {
private$.through
},
- #' @return The field name.
+ #' @field field_name (`character(1)`)\cr
+ #' The field name.
field_name = function() {
private$.field_name
},
- #' @return The registry name.
+ #' @field registry_name (`character(1)`)\cr
+ #' The registry name.
registry_name = function() {
private$.registry_name
},
- #' @return The column name.
+ #' @field column_name (`character(1)`)\cr
+ #' The column name.
column_name = function() {
private$.column_name
},
- #' @return The module name.
+ #' @field module_name (`character(1)`)\cr
+ #' The module name.
module_name = function() {
private$.module_name
},
- #' @return Whether the field is a link table.
+ #' @field is_link_table (`logical(1)`)\cr
+ #' Whether the field is a link table.
is_link_table = function() {
private$.is_link_table
},
- #' @return The relation type.
+ #' @field relation_type (`character(1)` or `NULL`)\cr
+ #' The relation type. Can be one of: "one-to-many", "many-to-one", "many-to-many".
relation_type = function() {
private$.relation_type
},
- #' @return The related field name.
+ #' @field related_field_name (`character(1)` or `NULL`)\cr
+ #' The related field name.
related_field_name = function() {
private$.related_field_name
},
- #' @return The related registry name.
+ #' @field related_registry_name (`character(1)` or `NULL`)\cr
+ #' The related registry name.
related_registry_name = function() {
private$.related_registry_name
},
- #' @return The related module name.
+ #' @field related_module_name (`character(1)` or `NULL`)\cr
+ #' The related module name.
related_module_name = function() {
private$.related_module_name
}
diff --git a/R/Instance.R b/R/Instance.R
index e10cdcb..59dbc75 100644
--- a/R/Instance.R
+++ b/R/Instance.R
@@ -63,14 +63,43 @@ create_instance <- function(instance_settings) {
#' @title Instance
#'
-#' @noRd
-#'
#' @description
-#' A LaminDB instance.
+#' Connect to a LaminDB instance using the [connect()] function.
+#' The instance object provides access to the modules and registries
+#' of the instance.
+#'
+#' @details
+#' Note that by connecting to an instance via [connect()], you receive
+#' a "richer" version of the Instance class documented here, providing
+#' direct access to all core registries and additional modules.
+#' See the vignette on "Package Architecture" for more information:
+#' `vignette("architecture", package = "laminr")`.
+#'
+#' @examples
+#' \dontrun{
+#' # Connect to an instance
+#' db <- connect("laminlabs/cellxgene")
+#'
+#' # fetch an artifact
+#' artifact <- db$Artifact$get("KBW89Mf7IGcekja2hADu")
+#'
+#' # describe the artifact
+#' artifact$describe()
+#'
+#' # view field
+#' artifact$id
+#'
+#' # load dataset
+#' artifact$load()
+#' }
Instance <- R6::R6Class( # nolint object_name_linter
"Instance",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param settings The settings for the instance
#' @param api The API for the instance
#' @param schema The schema for the instance
@@ -92,24 +121,40 @@ Instance <- R6::R6Class( # nolint object_name_linter
) |>
set_names(names(schema))
},
- #' Get the modules for the instance.
+ #' @description Get the modules for the instance.
+ #'
+ #' @return A list of [Module] objects.
get_modules = function() {
private$.module_classes
},
- #' Get a module by name.
+ #' @description Get a module by name.
+ #'
+ #' @param module_name The name of the module.
+ #'
+ #' @return The [Module] object.
get_module = function(module_name) {
# todo: assert module exists
private$.module_classes[[module_name]]
},
- #' Get the names of the modules. Example: `c("core", "bionty")`.
+ #' @description Get the names of the modules. Example: `c("core", "bionty")`.
+ #'
+ #' @return A character vector of module names.
get_module_names = function() {
names(private$.module_classes)
},
- #' Get instance settings.
+ #' @description Get instance settings.
+ #'
+ #' Note: This method is intended for internal use only and may be removed in the future.
+ #'
+ #' @return The settings for the instance.
get_settings = function() {
private$.settings
},
- #' Get instance API.
+ #' @description Get instance API.
+ #'
+ #' Note: This method is intended for internal use only and may be removed in the future.
+ #'
+ #' @return The API for the instance.
get_api = function() {
private$.api
},
@@ -118,7 +163,6 @@ Instance <- R6::R6Class( # nolint object_name_linter
#'
#' @param style Logical, whether the output is styled using ANSI codes
print = function(style = TRUE) {
-
registries <- self$get_module("core")$get_registries()
is_link_table <- purrr::map(registries, "is_link_table") |>
@@ -206,11 +250,13 @@ Instance <- R6::R6Class( # nolint object_name_linter
}
key_value_strings <- make_key_value_strings(
- mapping, quote_strings = FALSE
+ mapping,
+ quote_strings = FALSE
)
make_class_string(
- private$.settings$name, key_value_strings, style = style
+ private$.settings$name, key_value_strings,
+ style = style
)
}
),
diff --git a/R/InstanceAPI.R b/R/InstanceAPI.R
index b6bbb99..3c8914a 100644
--- a/R/InstanceAPI.R
+++ b/R/InstanceAPI.R
@@ -8,6 +8,10 @@ InstanceAPI <- R6::R6Class( # nolint object_name_linter
"API",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param instance_settings The settings for the instance
#' Should have the following fields:
#' - id: The ID of the instance
diff --git a/R/InstanceSettings.R b/R/InstanceSettings.R
index 65cb296..00f9b7e 100644
--- a/R/InstanceSettings.R
+++ b/R/InstanceSettings.R
@@ -9,6 +9,10 @@ InstanceSettings <- R6::R6Class( # nolint object_name_linter
"InstanceSettings",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param settings A named list of settings for the instance
initialize = function(settings) {
expected_keys <- c(
diff --git a/R/Module.R b/R/Module.R
index a2a6cb0..4f27e1e 100644
--- a/R/Module.R
+++ b/R/Module.R
@@ -44,17 +44,20 @@ create_module <- function(instance, api, module_name, module_schema) {
#' @title Module
#'
-#' @noRd
-#'
#' @description
#' A LaminDB module containing one or more registries.
Module <- R6::R6Class( # nolint object_name_linter
"Module",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param instance The instance the module belongs to.
#' @param api The API for the instance.
#' @param module_name The name of the module.
+ #' @param module_schema The schema of the module.
initialize = function(instance, api, module_name, module_schema) {
private$.instance <- instance
private$.api <- api
@@ -74,25 +77,29 @@ Module <- R6::R6Class( # nolint object_name_linter
) |>
set_names(names(module_schema))
},
- #' @description
- #' Get the registries in the module.
+ #' @description Get the registries in the module.
+ #'
+ #' @return A list of [Registry] objects.
get_registries = function() {
private$.registry_classes
},
- #' @description
- #' Get a registry by name.
+ #' @description Get a registry by name.
+ #'
+ #' @param registry_name The name of the registry.
+ #'
+ #' @return A [Registry] object.
get_registry = function(registry_name) {
private$.registry_classes[[registry_name]]
},
- #' @description
- #' Get the names of the registries in the module. E.g. `c("User", "Artifact")`.
+ #' @description Get the names of the registries in the module. E.g. `c("User", "Artifact")`.
+ #'
+ #' @return A character vector of registry names.
get_registry_names = function() {
names(private$.registry_classes)
},
- #' @description
- #' Print a `Module`
+ #' @description Print a `Module`
#'
- #' @param style Logical, whether the output is styled using ANSI codes
+ #' @param style Logical, whether the output is styled using ANSI codes.
print = function(style = TRUE) {
registries <- self$get_registries()
@@ -171,6 +178,7 @@ Module <- R6::R6Class( # nolint object_name_linter
.registry_classes = NULL
),
active = list(
+ #' @field name (`character(1)`)\cr
#' Get the name of the module.
name = function() {
private$.module_name
diff --git a/R/Record.R b/R/Record.R
index e893db6..daa486b 100644
--- a/R/Record.R
+++ b/R/Record.R
@@ -47,14 +47,16 @@ create_record_class <- function(instance, registry, api) {
#' @title Record
#'
-#' @noRd
-#'
#' @description
#' A record from a registry.
Record <- R6::R6Class( # nolint object_name_linter
"Record",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param instance The instance the record belongs to.
#' @param registry The registry the record belongs to.
#' @param api The API for the instance.
diff --git a/R/Registry.R b/R/Registry.R
index 9286898..6f55ad5 100644
--- a/R/Registry.R
+++ b/R/Registry.R
@@ -1,13 +1,15 @@
#' @title Registry
#'
-#' @noRd
-#'
#' @description
#' A registry in a module.
Registry <- R6::R6Class( # nolint object_name_linter
"Registry",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param instance The instance the registry belongs to.
#' @param module The module the registry belongs to.
#' @param api The API for the instance.
@@ -50,6 +52,12 @@ Registry <- R6::R6Class( # nolint object_name_linter
},
#' @description
#' Get a record by ID or UID.
+ #'
+ #' @param id_or_uid The ID or UID of the record.
+ #' @param include_foreign_keys Logical, whether to include foreign keys in the record.
+ #' @param verbose Logical, whether to print verbose output.
+ #'
+ #' @return A [Record] object.
get = function(id_or_uid, include_foreign_keys = FALSE, verbose = FALSE) {
data <- private$.api$get_record(
module_name = private$.module$name,
@@ -63,21 +71,33 @@ Registry <- R6::R6Class( # nolint object_name_linter
},
#' @description
#' Get the fields in the registry.
+ #'
+ #' @return A list of [Field] objects.
get_fields = function() {
private$.fields
},
#' @description
#' Get a field by name.
+ #'
+ #' @param field_name The name of the field.
+ #'
+ #' @return A [Field] object.
get_field = function(field_name) {
private$.fields[[field_name]]
},
#' @description
#' Get the field names in the registry.
+ #'
+ #' @return A character vector of field names.
get_field_names = function() {
names(private$.fields)
},
#' @description
#' Get the record class for the registry.
+ #'
+ #' Note: This method is intended for internal use only and may be removed in the future.
+ #'
+ #' @return A [Record] class.
get_record_class = function() {
private$.record_class
},
@@ -85,6 +105,8 @@ Registry <- R6::R6Class( # nolint object_name_linter
#' Print a `Registry`
#'
#' @param style Logical, whether the output is styled using ANSI codes
+ #'
+ #' @return A character vector
print = function(style = TRUE) {
fields <- self$get_fields()
# Remove hidden fields
@@ -178,19 +200,23 @@ Registry <- R6::R6Class( # nolint object_name_linter
.record_class = NULL
),
active = list(
- #' @return The instance the registry belongs to.
+ #' @field module ([Module])\cr
+ #' The instance the registry belongs to.
module = function() {
private$.module
},
- #' @return The API for the instance.
+ #' @field name (`character(1)`)\cr
+ #' The API for the instance.
name = function() {
private$.registry_name
},
- #' @return The class name for the registry.
+ #' @field class_name (`character(1)`)\cr
+ #' The class name for the registry.
class_name = function() {
private$.class_name
},
- #' @return Whether the registry is a link table.
+ #' @field is_link_table (`logical(1)`)\cr
+ #' Whether the registry is a link table.
is_link_table = function() {
private$.is_link_table
}
diff --git a/R/UserSettings.R b/R/UserSettings.R
index a0c474b..071b712 100644
--- a/R/UserSettings.R
+++ b/R/UserSettings.R
@@ -9,6 +9,10 @@ UserSettings <- R6::R6Class( # nolint object_name_linter
"UserSettings",
cloneable = FALSE,
public = list(
+ #' @description
+ #' Creates an instance of this R6 class. This class should not be instantiated directly,
+ #' but rather by connecting to a LaminDB instance using the [connect()] function.
+ #'
#' @param settings A named list of settings for the user
initialize = function(settings) {
expected_keys <- c(
diff --git a/man/Field.Rd b/man/Field.Rd
new file mode 100644
index 0000000..0a41589
--- /dev/null
+++ b/man/Field.Rd
@@ -0,0 +1,146 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/Field.R
+\name{Field}
+\alias{Field}
+\title{Field}
+\description{
+A field in a registry.
+}
+\section{Active bindings}{
+\if{html}{\out{
}}
+\describe{
+\item{\code{type}}{(\code{character(1)})\cr
+The type of the field.}
+
+\item{\code{through}}{(\code{list()} or \code{NULL})\cr
+The through value of the field.}
+
+\item{\code{field_name}}{(\code{character(1)})\cr
+The field name.}
+
+\item{\code{registry_name}}{(\code{character(1)})\cr
+The registry name.}
+
+\item{\code{column_name}}{(\code{character(1)})\cr
+The column name.}
+
+\item{\code{module_name}}{(\code{character(1)})\cr
+The module name.}
+
+\item{\code{is_link_table}}{(\code{logical(1)})\cr
+Whether the field is a link table.}
+
+\item{\code{relation_type}}{(\code{character(1)} or \code{NULL})\cr
+The relation type. Can be one of: "one-to-many", "many-to-one", "many-to-many".}
+
+\item{\code{related_field_name}}{(\code{character(1)} or \code{NULL})\cr
+The related field name.}
+
+\item{\code{related_registry_name}}{(\code{character(1)} or \code{NULL})\cr
+The related registry name.}
+
+\item{\code{related_module_name}}{(\code{character(1)} or \code{NULL})\cr
+The related module name.}
+}
+\if{html}{\out{
}}
+}
+\section{Methods}{
+\subsection{Public methods}{
+\itemize{
+\item \href{#method-Field-new}{\code{Field$new()}}
+\item \href{#method-Field-print}{\code{Field$print()}}
+\item \href{#method-Field-to_string}{\code{Field$to_string()}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Field-new}{}}}
+\subsection{Method \code{new()}}{
+Creates an instance of this R6 class. This class should not be instantiated directly,
+but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Field$new(
+ type,
+ through,
+ field_name,
+ registry_name,
+ column_name,
+ module_name,
+ is_link_table,
+ relation_type,
+ related_field_name,
+ related_registry_name,
+ related_module_name
+)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{type}}{The type of the field. Can be one of:
+"IntegerField", "JSONField", "OneToOneField", "SmallIntegerField",
+"BigIntegerField", "AutoField", "BigAutoField", "BooleanField", "TextField",
+"DateTimeField", "ManyToManyField", "CharField", "ForeignKey"}
+
+\item{\code{through}}{If the relation type is one-to-many, many-to-one, or many-to-many,
+This value will be a named list with keys 'left_key', 'right_key', 'link_table_name'.}
+
+\item{\code{field_name}}{The name of the field in the registry. Example: \code{"name"}.}
+
+\item{\code{registry_name}}{The name of the registry. Example: \code{"user"}.}
+
+\item{\code{column_name}}{The name of the column in the database. Example: \code{"name"}.}
+
+\item{\code{module_name}}{The name of the module. Example: \code{"core"}.}
+
+\item{\code{is_link_table}}{Whether the field is a link table.}
+
+\item{\code{relation_type}}{The type of relation. Can be NULL or one of: "one-to-one", "many-to-one", "many-to-many".}
+
+\item{\code{related_field_name}}{The name of the related field in the related registry. Example: \code{"name"}.}
+
+\item{\code{related_registry_name}}{The name of the related registry. Example: \code{"user"}.}
+
+\item{\code{related_module_name}}{The name of the related module. Example: \code{"core"}.}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Field-print}{}}}
+\subsection{Method \code{print()}}{
+Print a \code{Field}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Field$print(style = TRUE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Field-to_string}{}}}
+\subsection{Method \code{to_string()}}{
+Create a string representation of a \code{Field}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Field$to_string(style = FALSE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector
+}
+}
+}
diff --git a/man/Instance.Rd b/man/Instance.Rd
new file mode 100644
index 0000000..2d1e7c6
--- /dev/null
+++ b/man/Instance.Rd
@@ -0,0 +1,184 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/Instance.R
+\name{Instance}
+\alias{Instance}
+\title{Instance}
+\description{
+Connect to a LaminDB instance using the \code{\link[=connect]{connect()}} function.
+The instance object provides access to the modules and registries
+of the instance.
+}
+\details{
+Note that by connecting to an instance via \code{\link[=connect]{connect()}}, you receive
+a "richer" version of the Instance class documented here, providing
+direct access to all core registries and additional modules.
+See the vignette on "Package Architecture" for more information:
+\code{vignette("architecture", package = "laminr")}.
+}
+\examples{
+\dontrun{
+# Connect to an instance
+db <- connect("laminlabs/cellxgene")
+
+# fetch an artifact
+artifact <- db$Artifact$get("KBW89Mf7IGcekja2hADu")
+
+# describe the artifact
+artifact$describe()
+
+# view field
+artifact$id
+
+# load dataset
+artifact$load()
+}
+}
+\section{Methods}{
+\subsection{Public methods}{
+\itemize{
+\item \href{#method-Instance-new}{\code{Instance$new()}}
+\item \href{#method-Instance-get_modules}{\code{Instance$get_modules()}}
+\item \href{#method-Instance-get_module}{\code{Instance$get_module()}}
+\item \href{#method-Instance-get_module_names}{\code{Instance$get_module_names()}}
+\item \href{#method-Instance-get_settings}{\code{Instance$get_settings()}}
+\item \href{#method-Instance-get_api}{\code{Instance$get_api()}}
+\item \href{#method-Instance-print}{\code{Instance$print()}}
+\item \href{#method-Instance-to_string}{\code{Instance$to_string()}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-new}{}}}
+\subsection{Method \code{new()}}{
+Creates an instance of this R6 class. This class should not be instantiated directly,
+but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$new(settings, api, schema)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{settings}}{The settings for the instance}
+
+\item{\code{api}}{The API for the instance}
+
+\item{\code{schema}}{The schema for the instance}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-get_modules}{}}}
+\subsection{Method \code{get_modules()}}{
+Get the modules for the instance.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$get_modules()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+A list of \link{Module} objects.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-get_module}{}}}
+\subsection{Method \code{get_module()}}{
+Get a module by name.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$get_module(module_name)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{module_name}}{The name of the module.}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+The \link{Module} object.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-get_module_names}{}}}
+\subsection{Method \code{get_module_names()}}{
+Get the names of the modules. Example: \code{c("core", "bionty")}.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$get_module_names()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+A character vector of module names.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-get_settings}{}}}
+\subsection{Method \code{get_settings()}}{
+Get instance settings.
+
+Note: This method is intended for internal use only and may be removed in the future.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$get_settings()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+The settings for the instance.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-get_api}{}}}
+\subsection{Method \code{get_api()}}{
+Get instance API.
+
+Note: This method is intended for internal use only and may be removed in the future.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$get_api()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+The API for the instance.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-print}{}}}
+\subsection{Method \code{print()}}{
+Print an \code{Instance}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$print(style = TRUE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Instance-to_string}{}}}
+\subsection{Method \code{to_string()}}{
+Create a string representation of an \code{Instance}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Instance$to_string(style = FALSE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector
+}
+}
+}
diff --git a/man/Module.Rd b/man/Module.Rd
new file mode 100644
index 0000000..f55ba7e
--- /dev/null
+++ b/man/Module.Rd
@@ -0,0 +1,135 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/Module.R
+\name{Module}
+\alias{Module}
+\title{Module}
+\description{
+A LaminDB module containing one or more registries.
+}
+\section{Active bindings}{
+\if{html}{\out{}}
+\describe{
+\item{\code{name}}{(\code{character(1)})\cr
+Get the name of the module.}
+}
+\if{html}{\out{
}}
+}
+\section{Methods}{
+\subsection{Public methods}{
+\itemize{
+\item \href{#method-Module-new}{\code{Module$new()}}
+\item \href{#method-Module-get_registries}{\code{Module$get_registries()}}
+\item \href{#method-Module-get_registry}{\code{Module$get_registry()}}
+\item \href{#method-Module-get_registry_names}{\code{Module$get_registry_names()}}
+\item \href{#method-Module-print}{\code{Module$print()}}
+\item \href{#method-Module-to_string}{\code{Module$to_string()}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Module-new}{}}}
+\subsection{Method \code{new()}}{
+Creates an instance of this R6 class. This class should not be instantiated directly,
+but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Module$new(instance, api, module_name, module_schema)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{instance}}{The instance the module belongs to.}
+
+\item{\code{api}}{The API for the instance.}
+
+\item{\code{module_name}}{The name of the module.}
+
+\item{\code{module_schema}}{The schema of the module.}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Module-get_registries}{}}}
+\subsection{Method \code{get_registries()}}{
+Get the registries in the module.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Module$get_registries()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+A list of \link{Registry} objects.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Module-get_registry}{}}}
+\subsection{Method \code{get_registry()}}{
+Get a registry by name.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Module$get_registry(registry_name)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{registry_name}}{The name of the registry.}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \link{Registry} object.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Module-get_registry_names}{}}}
+\subsection{Method \code{get_registry_names()}}{
+Get the names of the registries in the module. E.g. \code{c("User", "Artifact")}.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Module$get_registry_names()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+A character vector of registry names.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Module-print}{}}}
+\subsection{Method \code{print()}}{
+Print a \code{Module}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Module$print(style = TRUE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes.}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Module-to_string}{}}}
+\subsection{Method \code{to_string()}}{
+Create a string representation of a \code{Module}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Module$to_string(style = FALSE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector
+}
+}
+}
diff --git a/man/Record.Rd b/man/Record.Rd
new file mode 100644
index 0000000..133a9a1
--- /dev/null
+++ b/man/Record.Rd
@@ -0,0 +1,78 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/Record.R
+\name{Record}
+\alias{Record}
+\title{Record}
+\description{
+A record from a registry.
+}
+\section{Methods}{
+\subsection{Public methods}{
+\itemize{
+\item \href{#method-Record-new}{\code{Record$new()}}
+\item \href{#method-Record-print}{\code{Record$print()}}
+\item \href{#method-Record-to_string}{\code{Record$to_string()}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Record-new}{}}}
+\subsection{Method \code{new()}}{
+Creates an instance of this R6 class. This class should not be instantiated directly,
+but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Record$new(instance, registry, api, data)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{instance}}{The instance the record belongs to.}
+
+\item{\code{registry}}{The registry the record belongs to.}
+
+\item{\code{api}}{The API for the instance.}
+
+\item{\code{data}}{The data for the record.}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Record-print}{}}}
+\subsection{Method \code{print()}}{
+Print a \code{Record}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Record$print(style = TRUE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Record-to_string}{}}}
+\subsection{Method \code{to_string()}}{
+Create a string representation of a \code{Record}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Record$to_string(style = FALSE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector
+}
+}
+}
diff --git a/man/Registry.Rd b/man/Registry.Rd
new file mode 100644
index 0000000..e6afefc
--- /dev/null
+++ b/man/Registry.Rd
@@ -0,0 +1,190 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/Registry.R
+\name{Registry}
+\alias{Registry}
+\title{Registry}
+\description{
+A registry in a module.
+}
+\section{Active bindings}{
+\if{html}{\out{}}
+\describe{
+\item{\code{module}}{(\link{Module})\cr
+The instance the registry belongs to.}
+
+\item{\code{name}}{(\code{character(1)})\cr
+The API for the instance.}
+
+\item{\code{class_name}}{(\code{character(1)})\cr
+The class name for the registry.}
+
+\item{\code{is_link_table}}{(\code{logical(1)})\cr
+Whether the registry is a link table.}
+}
+\if{html}{\out{
}}
+}
+\section{Methods}{
+\subsection{Public methods}{
+\itemize{
+\item \href{#method-Registry-new}{\code{Registry$new()}}
+\item \href{#method-Registry-get}{\code{Registry$get()}}
+\item \href{#method-Registry-get_fields}{\code{Registry$get_fields()}}
+\item \href{#method-Registry-get_field}{\code{Registry$get_field()}}
+\item \href{#method-Registry-get_field_names}{\code{Registry$get_field_names()}}
+\item \href{#method-Registry-get_record_class}{\code{Registry$get_record_class()}}
+\item \href{#method-Registry-print}{\code{Registry$print()}}
+\item \href{#method-Registry-to_string}{\code{Registry$to_string()}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-new}{}}}
+\subsection{Method \code{new()}}{
+Creates an instance of this R6 class. This class should not be instantiated directly,
+but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$new(instance, module, api, registry_name, registry_schema)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{instance}}{The instance the registry belongs to.}
+
+\item{\code{module}}{The module the registry belongs to.}
+
+\item{\code{api}}{The API for the instance.}
+
+\item{\code{registry_name}}{The name of the registry.}
+
+\item{\code{registry_schema}}{The schema for the registry.}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-get}{}}}
+\subsection{Method \code{get()}}{
+Get a record by ID or UID.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$get(id_or_uid, include_foreign_keys = FALSE, verbose = FALSE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{id_or_uid}}{The ID or UID of the record.}
+
+\item{\code{include_foreign_keys}}{Logical, whether to include foreign keys in the record.}
+
+\item{\code{verbose}}{Logical, whether to print verbose output.}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \link{Record} object.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-get_fields}{}}}
+\subsection{Method \code{get_fields()}}{
+Get the fields in the registry.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$get_fields()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+A list of \link{Field} objects.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-get_field}{}}}
+\subsection{Method \code{get_field()}}{
+Get a field by name.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$get_field(field_name)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{field_name}}{The name of the field.}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \link{Field} object.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-get_field_names}{}}}
+\subsection{Method \code{get_field_names()}}{
+Get the field names in the registry.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$get_field_names()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+A character vector of field names.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-get_record_class}{}}}
+\subsection{Method \code{get_record_class()}}{
+Get the record class for the registry.
+
+Note: This method is intended for internal use only and may be removed in the future.
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$get_record_class()}\if{html}{\out{
}}
+}
+
+\subsection{Returns}{
+A \link{Record} class.
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-print}{}}}
+\subsection{Method \code{print()}}{
+Print a \code{Registry}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$print(style = TRUE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A character vector
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-Registry-to_string}{}}}
+\subsection{Method \code{to_string()}}{
+Create a string representation of a \code{Registry}
+\subsection{Usage}{
+\if{html}{\out{}}\preformatted{Registry$to_string(style = FALSE)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{}}
+\describe{
+\item{\code{style}}{Logical, whether the output is styled using ANSI codes}
+}
+\if{html}{\out{
}}
+}
+\subsection{Returns}{
+A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector
+}
+}
+}
diff --git a/tests/testthat/test-instance_api.R b/tests/testthat/test-instance_api.R
index 433c0cc..a5d49cd 100644
--- a/tests/testthat/test-instance_api.R
+++ b/tests/testthat/test-instance_api.R
@@ -94,7 +94,7 @@ test_that("get_record fails gracefully", {
# nolint start: commented_code
# TODO: improve error messages for these cases
expect_error(
- api$get_record("core", "artifact", "foobar")#,
+ api$get_record("core", "artifact", "foobar") # ,
# regexp = "Error getting record: list index out of range"
)
expect_error(
diff --git a/vignettes/structure.qmd b/vignettes/architecture.qmd
similarity index 96%
rename from vignettes/structure.qmd
rename to vignettes/architecture.qmd
index 88b8cd5..e3e0142 100644
--- a/vignettes/structure.qmd
+++ b/vignettes/architecture.qmd
@@ -1,7 +1,7 @@
---
-title: "Package structure"
+title: "Architecture"
vignette: >
- %\VignetteIndexEntry{Package structure}
+ %\VignetteIndexEntry{Architecture}
%\VignetteEncoding{UTF-8}
%\VignetteEngine{quarto::html}
knitr:
@@ -104,7 +104,7 @@ classDiagram
## Sugar syntax
-The `laminr` package adds some sugar syntax to the `Instance` and `Registry` classes. This allows to directly access an instance's registies and a record's fields.
+The `laminr` package adds some sugar syntax to the `Instance`, `Module`, and `Record` classes. This allows to directly access an instance's and module's registries and a record's fields.
For instance, instead of writing: