clone

a self-hosted sync node for lofi apps: jazz sync over iroh, ticket-gated, with no static ip or cloud needed

feat/write-verdict-foundations
lofi-node / mod.ts
mod.ts 1.6K
1/**2 * Self-hostable sync node for lofi apps: one daemon embedding a Jazz 2.03 * sync server, iroh node-to-node transport, and a ticket-gated access layer.4 *5 * Create a node, issue an app-connect ticket, and point a lofi app's6 * `JAZZ_SERVER_URL` at the ticket URL:7 *8 * ```ts9 * import { createSyncNode } from "@nzip/lofi-node";10 *11 * const node = await createSyncNode({12 * appId: crypto.randomUUID(),13 * backendSecret: "...",14 * adminSecret: "...",15 * dataDir: "./data",16 * access: "ticket",17 * });18 * const { ticket } = await node.issueTicket({ label: "phone" });19 * // the app seals `ticket` at rest and uses its URL as serverUrl20 * ```21 *22 * The CLI lives at the `./cli` export (`dx -A jsr:@nzip/lofi-node/cli`), and23 * in-process test helpers at `./testing`.24 *25 * @module26 */2728export { createSyncNode } from "./src/node.ts";29export type {30 AppTicketInfo,31 MeshStatus,32 SyncNode,33 SyncNodeOptions,34 SyncNodeStatus,35} from "./src/node.ts";36export {37 initConfig,38 loadConfig,39 saveConfig,40 validateRelay,41 validateStorage,42} from "./src/config.ts";43export type { NodeConfig, RelayConfig, StorageConfig, UpstreamConfig } from "./src/config.ts";44export { looksLikeTicket } from "./src/ticket.ts";45export { decodeAppTicket, encodeAppTicket, looksLikeAppTicket } from "./src/appticket.ts";46export type { AppTicket } from "./src/appticket.ts";47export { CLOSE_TICKET_REVOKED } from "./src/gate.ts";48export { MeshUnavailableError } from "./src/errors.ts";49export {50 classifyMutationError,51 isPermanentMutationError,52 MUTATION_ERROR_CLASSES,53} from "./src/verdict.ts";54export type { MutationErrorClass } from "./src/verdict.ts";