> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dairy.foundation/llms.txt
> Use this file to discover all available pages before exploring further.

# Observability

`Observable`s support the ability to bind `Observer`s to them. `Observer`s receive an
update when the contents of the cell change. `Observerable`s are both
`Observable`s `Observer`s.

Cells are `Observerable`, which means you can chain them to each other to
publish and receive updates about changes in cell content.

Lets take a quick look:

<CodeGroup>
  ```java Java theme={null}
  RefCell<String> c1 = new RefCell<>("start");
  RefCell<String> c2 = new RefCell<>("");
  // c2 will now receive updates about changes to c1
  // immediately after binding, c1 will update c2
  c1.bind(c2);
  // now c2 will contain "start"
  c1.accept("end");
  // now c2 will contain "end"
  ```

  ```kt Kotlin theme={null}
  val c1 = RefCell("start")
  val c2 = RefCell("")
  // c2 will now receive updates about changes to c1
  // immediately after binding, c1 will update c2
  c1.bind(c2)
  // now c2 will contain "start"
  c1.accept("end")
  // now c2 will contain "end"
  ```
</CodeGroup>

Two-way binds are also supported for `Observerable`s (which cells are):

<CodeGroup>
  ```java Java theme={null}
  RefCell<String> c1 = new RefCell<>("start");
  RefCell<String> c2 = new RefCell<>("");
  // c2 will now receive updates about changes to c1
  // and c1 will now receive updates about changes to c2
  // c1 will bind c2 first
  // so c1 will update c2 first
  c1.bindBoth(c2);
  // now c2 will contain "start"
  c1.accept("end");
  // now c2 will contain "end"
  c2.accept("");
  // now c1 will contain ""
  ```

  ```kt Kotlin theme={null}
  val c1 = RefCell("start")
  val c2 = RefCell("")
  // c2 will now receive updates about changes to c1
  // and c1 will now receive updates about changes to c2
  // c1 will bind c2 first
  // so c1 will update c2 first
  c1.bindBoth(c2)
  // now c2 will contain "start"
  c1.accept("end")
  // now c2 will contain "end"
  c2.accept("")
  // now c1 will contain ""
  ```
</CodeGroup>

Lets look at what `Observer`s actually are:

<CodeGroup>
  ```java Java theme={null}
  RefCell<String> c1 = new RefCell<>("start");
  c1.bind(incoming -> {
  	System.out.println(incoming);
  })
  // "start" will be printed
  c1.accept("end");
  // now "end" will be printed
  ```

  ```kt Kotlin theme={null}
  val c1 = RefCell("start")
  c1.bind {
  	println(it)
  }
  // "start" will be printed
  c1.accept("end")
  // now "end" will be printed
  ```
</CodeGroup>

They're just a functional interface, this means you can use them for whatever
you'd like, not just binding cells together.

Bindings involving LateInitCells and derivatives are fine between each-other,
but bindings between LateInitCells and RefCells of a *non*-nullable type get
complex.

Knowing that `Observer`s are just functional interfaces, lets solve the issues
that arise when binding nullable to non-nullable cells.

<CodeGroup>
  ```java Java theme={null}
  RefCell<String> c1 = new RefCell<>("start");
  LateInitCell<String> c2 = new LateInitCell<>();

  c1.bind(c2);
  // now c2 contains "start"

  // this bind won't run if the arg is null
  c2.bind(incoming -> {
  	// don't update if the incoming data is null
  	if (incoming == null) return;
  	// update is like accept for observers
  	c1.update(incoming);
  });

  c2.accept("end");
  // now c1 contains "end"

  c2.invalidate();
  // now c2 contains null, while c1 still contains "end"
  ```

  ```kt Kotlin theme={null}
  val c1 = RefCell("start")
  val c2 = LateInitCell<String>()

  c1.bind(c2)
  // now c2 contains "start"

  // this bind won't run if the arg is null
  c2.bind {
  	// update is like accept for observers
  	// don't update if the incoming data is null
  	c1.update(it ?: return@bind)
  }

  c2.accept("end")
  // now c1 contains "end"

  c2.invalidate()
  // now c2 contains null, while c1 still contains "end"
  ```
</CodeGroup>

`Observers` can also be unbound:

<CodeGroup>
  ```java Java theme={null}
  RefCell<String> c1 = new RefCell<>("start");
  RefCell<String> c2 = new RefCell<>("");
  // c2 will now receive updates about changes to c1
  // immediately after binding, c1 will update c2
  c1.bind(c2);

  // undoes that
  // returns true if c2 was bound to c1
  c1.unbind(c2);

  c1.bindBoth(c2);

  // unbindBoth also exists,
  // unbinds both c2 from c1,
  // and c1 from c2.
  // returns true if either c2 was bound to c1, or c1 was bound to c2
  c1.unbindBoth(c2);
  ```

  ```kt Kotlin theme={null}
  val c1 = RefCell("start")
  val c2 = RefCell("")
  // c2 will now receive updates about changes to c1
  // immediately after binding, c1 will update c2
  c1.bind(c2)

  // undoes that
  // returns true if c2 was bound to c1
  c1.unbind(c2)

  c1.bindBoth(c2)

  // unbindBoth also exists,
  // unbinds both c2 from c1,
  // and c1 from c2.
  // returns true if either c2 was bound to c1, or c1 was bound to c2
  c1.unbindBoth(c2)
  ```
</CodeGroup>

Cool, that's all for observability for now.
