packages/db/src/index.ts
/**
* # @truffle/db API documentation
*
* ## Introduction
*
* **@truffle/db** tracks information about smart contracts and their
* development histories. It organizes this information almost entirely in the
* form of **content-addressed, immutable resources** and seeks to serve as a
* **complete system of record**, suitable to perfectly reproduce prior builds
* and to act as a single source of truth.
*
* This system of record covers the full gamut of concepts related to smart
* contract development, from source code to deployment. Among other features,
* it includes mechanisms for tracking the continuity of a smart contract as it
* is implemented and even as the network to which it's deployed experiences
* a hard-fork. **Blockchain data is not forgotten — neither should blockchain
* metadata.**
*
* At a high-level, this package provides a
* [GraphQL](https://graphql.org/) interface and stores data via one of
* several persistence backends thanks to [PouchDB](https://pouchdb.com/).
* Use of this package directly is intended mostly for other tools – end users
* can find interfaces to @truffle/db by way of Truffle itself, e.g. with the
* `truffle db serve` command that starts a GraphQL Playground HTTP server.
*
* This documentation serves to organize the modules and namespaces included
* in the package, both for tool developer reference and for continued work
* on @truffle/db itself. (Disclaimer: as a result, this API documentation
* may serve neither of these purposes well. Please reach out with questions
* and/or to suggest helpful clarifications!)
*
* Continue reading below for an overview and full index of this package's
* exports.
*
* ---
*
* <figure style="text-align: center">
* <img
* src="media://images/example-query.png"
* alt="Example query"
* style="width: 85%" />
* <figcaption style="font-size: small; font-style: italic">
* <strong>Figure</strong>:
* Example query for a project's <code>MagicSquare</code> contract
* </figcaption>
* </figure>
*
* ---
*
* ## Contents
*
* For quick reference, this documentation summary contains the following
* headings:
*
* - [Introduction](#introduction)
*
* - [Contents](#contents)
*
* - [Core library interface](#core-library-interface)
* - [Instantiating @truffle/db](#instantiating-truffledb)
* - [GraphQL schema](#graphql-schema)
*
* - [Data model](#data-model)
* - [Structure](#structure)
* - [List of collections](#list-of-collections)
*
* - [Other interfaces](#other-interfaces)
* - [JavaScript / TypeScript interface](#javascript---typescript-interface)
* - [Network abstraction](#network-abstraction)
* - [Truffle project abstraction](#truffle-project-abstraction)
* - [HTTP interface](#http-interface)
*
* - [Additional materials](#additional-materials)
*
* ## Core library interface
*
* ### Instantiating @truffle/db
*
* This package defines the primary [[connect | `connect()`]] function, which
* returns an object adhering to the [[Db]] interface for given
* [ConnectOptions](#connectoptions).
* This [[Db]] interface defines the `async`
* [[Meta.Db.execute | `db.execute()`]]
* method that accepts a GraphQL request and returns a GraphQL response.
*
* ### GraphQL schema
*
* \@truffle/db makes its GraphQL schema available as the exported
* [[Graph.schema | `Graph.schema`]] variable, or view the SDL
* details in the [[Graph]] namespace description.
*
* ## Data model
*
* ### Structure
*
* Data is organized as collections of representations of key
* concepts related to smart contract development. Each collection specifies:
* - A collection name
* - A complete resource type (exported as
* [[Resources.Resource | `Resources.Resource<"<collectionName>">`]]; for
* retrieved records)
* - An input type (exported as
* [[Resources.Input | `Resources.Input<"<collectionName>">`]]; for
* new records)
* - A subset list of fields from its input type whose values strictly
* compose to form a resource's content-addressable ID.
* - Whether its resources are mutable (**note**: currently, only
* `"projectNames"` resources are mutable)
* - Whether its resources are named (meaning that resources of the same
* and collection will be tracked by name, for continuity and easy lookup)
*
* ### List of collections
*
* \@truffle/db defines the following collections:
* - `"bytecodes"`
* [_resource_: [[DataModel.Bytecode | Bytecode]];
* _input_: [[DataModel.BytecodeInput | BytecodeInput]]]
* - `"compilations"`
* [_resource_: [[DataModel.Compilation | Compilation]];
* _input_: [[DataModel.CompilationInput | CompilationInput]]]
* - `"contracts"`
* [_**named**_; _resource_: [[DataModel.Contract | Contract]];
* _input_: [[DataModel.ContractInput | ContractInput]]]
* - `"contractInstances"`
* [_resource_: [[DataModel.ContractInstance | ContractInstance]];
* _input_: [[DataModel.ContractInstanceInput | ContractInstanceInput]]]
* - `"nameRecords"`
* [_resource_: [[DataModel.NameRecord | NameRecord]];
* _input_: [[DataModel.NameRecordInput | NameRecordInput]]]
* - `"networks"`
* [_**named**_; _resource_: [[DataModel.Network | Network]];
* _input_: [[DataModel.NetworkInput | NetworkInput]]]
* - `"networkGenealogies"`
* [_resource_: [[DataModel.NetworkGenealogy | NetworkGenealogy]];
* _input_: [[DataModel.NetworkGenealogyInput | NetworkGenealogyInput]]]
* - `"projectNames"`
* [_**mutable**_; _resource_: [[DataModel.ProjectName | ProjectName]];
* _input_: [[DataModel.ProjectNameInput | ProjectNameInput]]]
* - `"projects"`
* [_resource_: [[DataModel.Project | Project]];
* _input_: [[DataModel.ProjectInput | ProjectInput]]]
* - `"sources"`
* [_resource_: [[DataModel.Source | Source]];
* _input_: [[DataModel.SourceInput | SourceInput]]]
*
* This list is not intended to be static; since @truffle/db is in early
* release, it may make sense to add new collections / change relationships
* between existing collections. Backwards compatibility is planned but not yet
* guaranteed.
*
* ## Other interfaces
*
* ### JavaScript / TypeScript interface
*
* This package exposes programmatic interfaces for working with
* the resources listed above:
* - [[Process.resources]], a set of four generator functions that encode
* logic for storing and retrieving resources for a given `collectionName`.
*
* - [[Process.Run.forDb()]], to construct an `async` helper that facilitates
* requests/responses from/to the above generator functions against a given
* [[Db]] instance.
*
* - [[generateId | generateId()]], to predict the ID for a given resource
* input. This can be useful for determining how to query for additional
* information about entities with known properties.
*
* In addition, please see the [[Resources]] module for handy helper types for
* dealing with @truffle/db entities.
*
* ### Network abstraction
*
* Keeping track of blockchain networks is nontrivial if you want to handle
* network forks/re-orgs. To accommodate this, @truffle/db models
* blockchain networks as individual point-in-time slices at various historic
* blocks. As a result, a single blockchain network (e.g., "mainnet") can and
* will comprise many disparate [[DataModel.Network]] resources, one for each
* block previously added.
*
* This approach preserves immutability but requires additional record-keeping
* in order to provide the commonly-understood continuous view of a blockchain.
* To maintain this continuity, @truffle/db defines the
* [[DataModel.NetworkGenealogy]] resource, each of which links two
* [[DataModel.Network]] resources, stating that a given network is ancestor
* to another. This collection of genealogy pairs is then used to compute a
* sparse list of past historic blocks for a given latest network.
*
* The process to populate @truffle/db with correct network data involves
* alternately querying GraphQL and the underlying blockchain JSON-RPC.
*
* This package provides the [[Network]] abstraction to simplify this process.
*
* <details>
* <summary>Example usage</summary>
*
* ```typescript
* import type { Provider } from "web3/providers";
* declare const provider: Provider;
*
* import { connect, Network } from "@truffle/db";
*
* const db = connect({
* // ...
* });
*
* const network = await Network.initialize({
* provider,
* db: connect({
* // ...
* }),
* network: { name: "mainnet" }
* });
*
* await network.includeBlocks([
* { height: 10000000, hash: "0x..." },
* // ...
* ]);
*
* const { historicBlock } = network.knownLatest;
* ```
*
* </details>
*
* ### Truffle project abstraction
*
* This package also provides an abstraction to interface with other
* Truffle data formats, namely `WorkflowCompileResult`, returned by
* \@truffle/workflow-compile, and the Truffle contract artifacts format,
* defined by @truffle/contract-schema. This abstraction covers two classes:
* - [[Project.Project]] for operations that **do not** require a network
* connection. Use function [[Project.initialize | `Project.initialize()`]]
* to create.
* - [[Project.ConnectedProject]] for operations that **do** require a
* blockchain network. Use existing project abstraction's
* [[Project.connect | `project.connect()`]] method to create.
*
* ### HTTP interface
*
* This package exposes the [[serve | `serve()`]] function, which returns an
* [Apollo Server](https://www.apollographql.com/docs/apollo-server/)
* instance, adherent to the
* [Node.js `http.Server`](https://nodejs.org/api/http.html#http_class_http_server)
* interface. This server runs
* [GraphQL Playground](https://github.com/graphql/graphql-playground) for the
* browser and also accepts plain GraphQL requests.
*
* _(This is a handy way to explore @truffle/db, since it offers schema-aware
* auto-completion and the ability to explore relationships between entities.)_
*
* ## Additional materials
*
* This package listing contains other namespaces not mentioned above.
* These are for internal use and not to be considered part of @truffle/db's
* public interface.
*
* For those curious about these internals, of particular note is the [[Meta]]
* namespace, which houses underlying collections-agnostic logic for
* integrating GraphQL and PouchDB.
*
* @packageDocumentation
*/ /** */
import debugModule from "debug";
const debug = debugModule("db");
import * as Network from "./network";
export { Network };
export { DataModel, Db } from "./resources";
import * as Project from "./project";
export { Project };
import * as Resources from "./resources";
export { Resources };
export { ConnectOptions } from "./system";
import * as _System from "./system";
/**
* Instantiate @truffle/db for given [[ConnectOptions]]
*/
export const connect = _System.connect;
/**
* Create an Apollo GraphQL server for @truffle/db for given [[ConnectOptions]]
*
* See
* [Apollo Server documentation](https://www.apollographql.com/docs/apollo-server/)
* for more information.
*/
export const serve = _System.serve;
/**
* Compute an ID for a given collection name and input. This accepts either
* a full [[Resources.Input | `Resources.Input<"<collectionName>">`]]
* representation or an object containing only the relevant subset of
* [[Resources.IdFields | `Resources.IdFields<"<collectionName>">`]].
*/
export const generateId = _System.generateId;
/**
* # GraphQL-related exports for @truffle/db
*
* ## SDL
*
* <details>
* <summary>@truffle/db SDL</summary>
*
* ```graphql
* [[include:schema.sdl]]
* ```
*
* </details>
*
* @category Primary
*/
export namespace Graph {
export const schema = _System.schema;
}
/**
* @category Internal
*/
export namespace Pouch {
export const attach = _System.attach;
}
import * as Process from "./process";
export { Process };
import * as Meta from "./meta";
export { Meta };