Documentation
¶
Overview ¶
Package server implements the HTTP/JSON API for any-sync-sdk.
@title Any API @version 1.0 @description Local HTTP/JSON API wrapping any-sync-sdk. Localhost-only, no auth in v1. @servers.url http://127.0.0.1:7001/v1
Index ¶
- Constants
- func AccountID(ctx context.Context, p auth.Provider) (string, error)
- func NewIndexRegistry() *index.Registry
- func OpenIndexer(ctx context.Context, cfg config.Index, dataDir, modelsDir string, ...) (*indexer.Indexer, error)
- func OpenSDK(ctx context.Context, cfg config.Config, nodeconf []byte, dataDir string, ...) (*anysyncsdk.SDK, error)
- func OpenWallet(path, passkey, mnemonic string, index uint32) (provider *auth.FileProvider, firstRun bool, err error)
- func PrintMnemonic(phrase string)
- func Run(ctx context.Context, cfg config.Config) error
- func RunWith(ctx context.Context, cfg config.Config, opts RunOptions) error
- func StopRunning(r Running, wait time.Duration) error
- func ValidateCatalog(src []byte) catalog.Problems
- func ValidateLoopback(addr string) error
- type ErrLocked
- type ErrNetworkMismatch
- type ErrNoIdentity
- type Identity
- type Lock
- type RunOptions
- type Running
Constants ¶
const DefaultAccountSelector = "default"
DefaultAccountSelector names the legacy flat-root account to FindRunning's filter, which otherwise matches account dirs by id.
const DevicesDataset = "devices"
DevicesDataset is the tech-space system dataset holding the account's device registry: one row per device (peer), row id = peerId. Like the space list it lives on the tech-space index object and is system-owned — reads go through the endpoints below, writes only through the restricted self-row surface (never the generic modify path). See docs/23-devices.md.
const SpaceListDataset = "spaces"
SpaceListDataset is the default tech-space system dataset the space-list query/subscribe endpoints read. The profile dataset is reachable via the optional `dataset` body field.
Variables ¶
This section is empty.
Functions ¶
func AccountID ¶
AccountID returns the anytype account identifier derived from the provider's account key — the string health exposes as "account".
func NewIndexRegistry ¶
NewIndexRegistry builds the chunker registry — one chunker per indexed dataset, paralleling the Types list above. The indexer (internal/indexer) drives it.
Indexed: editor blocks (coalesced windows), chat messages, and object properties (name / description under "basic"; user values default-on under "props", meta.index overriding — see internal/index/prop.go). Deliberately NOT indexed: saved views (`dataviews` / `views` — navigation chrome, not knowledge) have no chunker. Agent data, enrichments, programs and mini apps are harness-declared runtime datasets: indexed via the schema chunker under their declared search scope, or not at all when the declaration carries no `search` mapping (program source and mini-app HTML are code, not knowledge — anybao ADR-010 §5).
func OpenIndexer ¶
func OpenIndexer(ctx context.Context, cfg config.Index, dataDir, modelsDir string, sdk *anysyncsdk.SDK, chunkers *index.Registry, onProcess func(indexer.ProcessUpdate), onLinks func(spaceId string, targets []string)) (*indexer.Indexer, error)
OpenIndexer builds the search indexer: embedder (per config), local index store under <dataDir>/index, and the service over the chunker registry. modelsDir is the shared (cross-account) model cache; a model already downloaded to the legacy <dataDir>/index/models keeps being used from there. There is no boot-time embedder probe: an unreachable embedder never blocks the boot or the FTS pipeline — text-bearing docs queue as pending and the embed loop picks them up once the embedder responds (the dimension is learned from the first successful batch unless index.vector.dim pins it). A misconfigured embedder (bad name, missing model) is still a hard error. onProcess (nil = off) receives indexing lifecycle updates (fts / embed / model download) for the process view — see deps.indexerProcess.
func OpenSDK ¶
func OpenSDK(ctx context.Context, cfg config.Config, nodeconf []byte, dataDir string, provider auth.Provider) (*anysyncsdk.SDK, error)
OpenSDK boots the SDK against the wallet provider and the project config, joining the network nodeconf names (resolved by the caller, which pins it). Storage lives under <dataDir>/sdk so the SDK's any-store and any-sync state are isolated from other process state in the data dir.
Topology defaults to Shared; only "shared" is supported in v1 (per-space topology is on the SDK side but not yet exercised here).
func OpenWallet ¶
func OpenWallet(path, passkey, mnemonic string, index uint32) (provider *auth.FileProvider, firstRun bool, err error)
OpenWallet loads or creates the file-backed wallet at path. A non-empty mnemonic seeds creation (restore / second-device path; the device key is always fresh) and must match an already-existing wallet; index is the account-derivation index applied on creation — fresh generation included — and read back from the file otherwise. On first generation the returned firstRun flag is true, and the caller is expected to display Mnemonic() once.
func PrintMnemonic ¶
func PrintMnemonic(phrase string)
PrintMnemonic writes the first-run warning and BIP-39 phrase to stderr. Stderr (not stdout) so it doesn't contaminate piped output, and only on the wallet's first generation.
func Run ¶
Run starts the HTTP server and blocks until ctx is cancelled or POST /v1/shutdown is called. Caller is responsible for installing signal handlers and cancelling ctx accordingly.
When the data dir resolves to an account (root wallet, sole per-account dir, or an explicit selector) its engine — wallet, SDK, indexer — boots before the listener binds, so failures surface before any request is accepted. With no account to boot the server starts UNAUTHORIZED: every /v1 route except health/shutdown/auth returns 401 auth.required until POST /v1/auth creates or selects an account and boots the engine in place.
func RunWith ¶
RunWith is Run plus a hook surface. Embedders (gomobile) use this to learn the bound address synchronously and surface bind / wallet / SDK errors before returning.
func StopRunning ¶
StopRunning asks the holder to exit (SIGTERM — the same graceful path Ctrl-C takes) and waits for its lock to be released. Windows has no signal to send; stopping there is the user's job.
func ValidateCatalog ¶
ValidateCatalog runs every check on a catalog source — the pure ones and the server-side gate — and returns every problem found. Nil means valid. Offline: nothing here touches a space or the SDK.
func ValidateLoopback ¶
ValidateLoopback rejects non-loopback bind addresses. v1 is loopback-only on purpose (see docs/02-server.md).
Types ¶
type ErrLocked ¶
ErrLocked is returned when Acquire finds another process holding the lock. PID is 0 when the holder's pid file is missing or unreadable — the holder writes it just after acquiring, so a racing Acquire can arrive first.
type ErrNetworkMismatch ¶
ErrNetworkMismatch refuses a boot whose configured network is not the one the account dir is pinned to.
func (*ErrNetworkMismatch) Error ¶
func (e *ErrNetworkMismatch) Error() string
type ErrNoIdentity ¶
type ErrNoIdentity struct {
// Accounts lists the per-account dirs found (empty = fresh root).
Accounts []string
}
ErrNoIdentity is the resolution outcome "nothing to boot": no wallet selected and none unambiguously present. `run` starts unauthorized and waits for POST /v1/auth; CLI paths print the hint instead.
func (*ErrNoIdentity) Error ¶
func (e *ErrNoIdentity) Error() string
type Identity ¶
type Identity struct {
// Account is the expected account id. Empty when it can only be
// learned by opening the wallet (root wallet / explicit override);
// when non-empty the caller verifies the derived id against it.
Account string
// Dir holds this account's server.pid, sdk/ and index/ — and, under
// managed custody, the cached device.key.
Dir string
// WalletPath is the wallet file to open. Empty under managed
// custody, where the account key never touches disk.
WalletPath string
}
Identity names the wallet a server boots with and where that account's data lives. Dir is the per-account data dir (the root itself for the legacy flat layout and for an explicit walletPath override).
func ResolveIdentity ¶
ResolveIdentity decides which wallet to boot for the given root:
- auth.walletPath / --wallet override → that wallet, data flat at the root (manual mode, no per-account nesting).
- --account / ANY_ACCOUNT / account: selector → <root>/<id>/ if it exists, else the root wallet (verified against the selector after opening), else an error.
- No selector: root wallet.key → the default flat account; else a sole per-account dir; else *ErrNoIdentity (none or several).
type Lock ¶
type Lock struct {
// contains filtered or unexported fields
}
Lock is the single-instance lock on an account dir: an exclusive OS file lock on <dir>/server.lock (flock(2) on unix, LockFileEx with LOCKFILE_FAIL_IMMEDIATELY on Windows), plus <dir>/server.pid naming the holder for error messages.
The kernel releases the lock when the process exits by any means, so there is no stale-lock reclaim and no liveness probe: a crashed holder blocks nobody. server.pid is advisory — it never decides who holds the lock, and it can name a dead process whenever the lock is free.
Neither file is removed, on release or on crash. Unlinking a file under an OS lock lets the next process create a fresh inode and lock THAT, so both would hold "the" lock.
The lock file is opened only here: on aix/solaris/illumos gofrs/flock falls back to POSIX fcntl records, which any close of any descriptor to the file drops. Those aren't platforms we ship, but a second opener would be a trap on the ones that are, too.
type RunOptions ¶
type RunOptions struct {
// Ready, if non-nil, is invoked once the TCP listener has bound but
// before Echo starts serving. It receives the actually-bound address
// (resolving "127.0.0.1:0" to the OS-picked host:port) so embedders
// like the gomobile wrapper can hand the real port back to the
// caller. The hook runs on the goroutine that called Run, so keep it
// quick — long work blocks server startup.
Ready func(addr string)
// ControlToken is the managed-mode control token an in-process host
// supplies. Empty on a managed server means "mint one and announce
// it on stdout" (the CLI / sidecar path). Ignored in standalone.
ControlToken string
}
RunOptions tweaks server.Run behaviour without bloating its signature. All fields are optional and zero-valued by default.
type Running ¶
type Running struct {
// Account is the dir name (the account id); "" for the legacy
// flat-root account.
Account string
Dir string
// PID is the holder's pid from server.pid; 0 when unknown.
PID int
// Addr is the holder's bound address from server.addr; "" when
// unknown (a server older than the file, or one that never bound).
Addr string
}
Running describes a server process holding an account's instance lock under a root. Found by probing the lock itself, so it is proof of life: a crashed holder's lock is released by the kernel and the dir reads as not running, whatever server.pid says.
func FindRunning ¶
FindRunning lists the servers currently serving accounts under root: the root itself (legacy layout) and every account dir, filtered to account when non-empty (DefaultAccountSelector picks the root). Neither a wallet nor a device key is consulted — only a held server.lock counts — so it finds standalone and managed servers alike, and never an unauthorized one (an engine that has not booted holds no lock). The probe takes and releases each lock for microseconds; Acquire retries briefly so a booting server never mistakes a probe for a holder.
Source Files
¶
- catalog.go
- control.go
- derivedsetup.go
- derivedspaces.go
- descriptor.go
- devicekey.go
- doc.go
- engine.go
- errors.go
- events_bridge.go
- events_hub.go
- events_topics.go
- files_mime.go
- gate.go
- handlers_access.go
- handlers_account.go
- handlers_acl.go
- handlers_acl_common.go
- handlers_aggregate.go
- handlers_auth.go
- handlers_backlinks.go
- handlers_blocks.go
- handlers_bundles.go
- handlers_catalog.go
- handlers_chat.go
- handlers_collections.go
- handlers_common.go
- handlers_datasets.go
- handlers_debug.go
- handlers_derived_spaces.go
- handlers_devices.go
- handlers_editor.go
- handlers_events.go
- handlers_files.go
- handlers_history.go
- handlers_identities.go
- handlers_invites.go
- handlers_local.go
- handlers_markdown.go
- handlers_members.go
- handlers_meta.go
- handlers_modify.go
- handlers_objects.go
- handlers_processes.go
- handlers_properties.go
- handlers_push.go
- handlers_query.go
- handlers_query_subscribe.go
- handlers_search.go
- handlers_settings.go
- handlers_spaces.go
- handlers_spaces_query.go
- handlers_subscribe.go
- handlers_sync_status.go
- handlers_typedatasets.go
- handlers_typeparts.go
- handlers_types.go
- handlers_unimplemented.go
- identity.go
- identitykeys_fence.go
- jsonpool.go
- listen.go
- local_discovery.go
- logger_echo.go
- mnemonic.go
- networkpin.go
- openapi.go
- pidlock.go
- pidlock_acquire.go
- processes.go
- projection.go
- projection_shape.go
- reserved_carrier.go
- routes.go
- running.go
- sdk.go
- server.go
- techspace.go
- wallet.go
- web.go