# `Slap.Yjs.Docs`
[🔗](https://github.com/mjrusso/slap/blob/slap_yjs-v0.4.0/slap_yjs/lib/slap/yjs/docs.ex#L1)

The document servers of this node, one per `{module, doc_id}`, started on
the first `join/3` and stopped after `:idle_timeout` without subscribers.
Each node that has clients for a document runs its own server; the
servers share the document through its `.updates` stream and presence
through a `:pg` group (see `Slap.Yjs.DocServer`).

Invalid control options and unknown option names raise `ArgumentError`.

Start it after the Streams cluster, so document servers can store their
buffers during shutdown. `:name` and `:prefix` select a document-server
instance on the built-in Streams cluster:

    children = [Slap.Streams.Cluster, Slap.Yjs.Docs]
    children = [Slap.Streams.Cluster,
                {Slap.Yjs.Docs, name: MyDocs, prefix: "/my/streams"}]
    Slap.Yjs.Docs.join(MyDocServer, {"service", "document"}, docs: MyDocs)

For an application-owned Streams cluster defined with
`use Slap.Streams.Cluster`, pass `cluster: MyApp.StreamsCluster` when
starting Docs. Run one Streams cluster per VM.

# `child_spec`

```elixir
@spec child_spec(keyword()) :: Supervisor.child_spec()
```

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `delete`

```elixir
@spec delete(Slap.Yjs.Store.doc(), keyword()) :: :ok | {:error, term()}
```

Deletes the document for good (`Slap.Yjs.Store.delete_doc/1`), then stops
its servers on every node with `{:shutdown, :deleted}`, waiting up to
`:timeout` ms (default 5 s) for them. `:docs` selects a named instance.
Joins return `{:error, :deleted}` from then on, so a deleted document's
id cannot be reused. A
server that does not stop in time (on a node that cannot be reached)
stops once its follower finds the document deleted, and cannot store
anything meanwhile.

# `join`

```elixir
@spec join(module(), Slap.Yjs.Store.doc(), keyword()) ::
  {:ok, pid()} | {:error, term()}
```

Subscribes the caller to the document's server on this node, starting it
with `opts` (`Slap.Yjs.DocServer` options; `:idle_timeout` defaults to 30 s)
if it is not running. Server options, and `:assigns` (a map of the
server's initial assigns), apply only when the server starts. The caller
then gets the messages described in `Slap.Yjs.DocServer`, and should
monitor the returned pid: if the server stops, join again and
resynchronise. `{:error, :deleted}` if the document was deleted
(`delete/2`). `:docs` selects a named Docs instance; `:timeout` bounds
loading and subscribing (default 5 s).

# `leave`

```elixir
@spec leave(pid(), keyword()) :: :ok | {:error, term()}
```

Unsubscribes the caller. `:timeout` defaults to 5,000 ms.

# `start_link`

Starts a document server supervisor. `:name` selects the instance name;
`:cluster` selects its Streams cluster (see `Slap.Streams.Cluster`);
`:prefix` prefixes stored paths.

# `whereis`

```elixir
@spec whereis(module(), Slap.Yjs.Store.doc(), keyword()) :: pid() | nil
```

The document's server on this node, if it has finished loading.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
