import { Libp2p, TypedEventEmitter } from "@libp2p/interface"; import type { SqlStorage } from "@cloudflare/workers-types"; import * as pg from "pg"; import { Contract } from "@canvas-js/core/contract"; import { Signature, Action, Message, Snapshot, SessionSigner, SignerCache, MessageType } from "@canvas-js/interfaces"; import { AbstractModelDB, Model } from "@canvas-js/modeldb"; import { AbstractGossipLog, GossipLogEvents, NetworkClient, SignedMessage } from "@canvas-js/gossiplog"; import type { ServiceMap, NetworkConfig } from "@canvas-js/gossiplog/libp2p"; import { JSValue } from "@canvas-js/utils"; import type { ContractAction, ModelSchema, DeriveModelTypes, ContractClass, GetActionsType } from "./types.js"; import { Runtime } from "./runtime/index.js"; import { CreateSnapshotArgs } from "./snapshot.js"; export type { Model } from "@canvas-js/modeldb"; export type { PeerId } from "@libp2p/interface"; export type Config = Contract & Record>> = { contract: string | { topic: string; models: ModelsT; } | ContractClass; /** constructor arguments for the contract class */ args?: JSValue[]; signers?: SessionSigner[]; /** data directory path (NodeJS/sqlite), postgres connection config (NodeJS/pg), or storage backend (Cloudflare DO) */ path?: string | pg.ConnectionConfig | SqlStorage | null; /** set a memory limit for the quickjs runtime, only used if `contract` is a string */ runtimeMemoryLimit?: number; /** clear all models and metadata before starting */ reset?: boolean; /** define additional tables in the local modeldb database */ schema?: ModelSchema; /** provide a snapshot to initialize the runtime database with, requires `reset: true` */ snapshot?: Snapshot | null; /** override the internal GossipLog topic */ topicOverride?: string; }; export interface CanvasEvents extends GossipLogEvents { stop: Event; } export type CanvasLogEvent = CustomEvent>; /** * Sync status, only available on the client. * - Offline is the initial status. * - Starting means the client has a WebSocket connection, but has not received heads to sync to. * - In progress means the client has started a Merkle sync, but has not run to completion. * - Complete means a sync has run to completion. *Not* debounced. The server may new actions during a sync. * - Error means an error occurred during Merkle sync, and the state of the log is unknown. */ export type ClientSyncStatus = "offline" | "starting" | "inProgress" | "complete" | "error"; export type ApplicationData = { peerId: string | null; connections: Record; networkConfig: { bootstrapList?: string[]; listen?: string[]; announce?: string[]; }; wsConfig: { listen?: number; connect?: string; }; root: string | null; heads: string[]; database: string; topic: string; models: Record; actions: string[]; signerKeys: string[]; lastMessage: number | null; }; export declare class Canvas = Contract & Record>> extends TypedEventEmitter { readonly signers: SignerCache; readonly messageLog: AbstractGossipLog; private readonly runtime; static namespace: string; static version: number; static initialize = Contract & Record>>(config: Config): Promise>; static buildContract(contract: string, config?: Record): Promise<{ build: string; originalContract: string; }>; static buildContractByLocation(location: string): Promise<{ build: string; originalContract: string; }>; readonly db: AbstractModelDB; readonly actions: GetActionsType; signerKeys: string[]; readonly as: (signer: SessionSigner) => GetActionsType; readonly create: (model: M, modelValue: Partial[M]>) => Promise & { result: unknown; }>; readonly update: (model: M, modelValue: Partial[M]>) => Promise & { result: unknown; }>; readonly delete: (model: string, primaryKey: string) => Promise & { result: unknown; }>; protected readonly controller: AbortController; protected readonly log: import("@libp2p/logger").Logger; private lastMessage; syncStatus: ClientSyncStatus; private libp2p; private networkConfig; private wsListen; private wsConnect; protected constructor(signers: SignerCache, messageLog: AbstractGossipLog, runtime: Runtime); get topic(): string; replay(): Promise; connect(url: string, options?: { signal?: AbortSignal; }): Promise>; listen(port: number, options?: { signal?: AbortSignal; }): Promise; startLibp2p(config: NetworkConfig): Promise>>; getContract(): string | null; getSchema(internal?: false): ModelSchema; /** * Get existing sessions in the signer cache or localStorage */ hasSession(did?: `did:${string}`): boolean; /** * Get existing sessions on the log */ getSessions(query: { did: string; publicKey: string; minExpiration?: number; }): Promise<{ id: string; did: string; publicKey: string; expiration: number | null; }[]>; updateSigners(signers: SessionSigner[]): void; getSigners(): SessionSigner[]; stop(): Promise; get closed(): boolean; getApplicationData(): Promise; /** * Insert an existing signed message into the log (ie received via PubSub) * Low-level utility method for internal and debugging use. * The normal way to apply actions is to use the `Canvas.actions[name](...)` functions. */ insert(signature: Signature, message: Message): Promise<{ id: string; }>; getMessage(id: string): Promise | null>; getMessages(lowerBound?: { id: string; inclusive: boolean; } | null, upperBound?: { id: string; inclusive: boolean; } | null, options?: { reverse?: boolean; }): AsyncIterable>; /** * Get an existing session */ getSession(query: { did: string; publicKey: string; }): Promise; createSnapshot(changes?: CreateSnapshotArgs): Promise; }