Skip to content

Commit

Permalink
Merge d6fe395 into afbb28b
Browse files Browse the repository at this point in the history
  • Loading branch information
TrySound committed Nov 18, 2017
2 parents afbb28b + d6fe395 commit 279467a
Showing 1 changed file with 310 additions and 0 deletions.
310 changes: 310 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
## API

### Atom

Atoms are simple mutable references to immutable values. They represent the
ground truth from which all else is derived.

#### atom(value: mixed): Atom

#### .set(value: mixed): void

#### .get(): mixed

#### .update(mixed => mixed): void

#### .proxy(descriptor): Proxy

#### .derive(mixed => mixed): Derivation

#### .maybeDerive(mixed => mixed): Derivation

#### .orDefault(mixed | Atom | Derivation | Proxy): Derivation

#### .react(mixed => void, opts: Lifecycle): void

See [Reactions](#reactions).

#### .maybeReact(mixed => void, opts: Lifecycle): void

See [Reactions](#reactions).

### Derivation

Derivations are declarative transformations of values held in atoms. Unlike
atoms, derivations cannot be modified in-place with a '.set' method. Their
values change only when one or more of the values that they depend upon change.

#### derive(() => mixed): Derivation

#### .derive(mixed => mixed): Derivation

#### .maybeDerive(mixed => mixed): Derivation

#### .orDefault(mixed | Atom | Derivation | Proxy): Derivation

#### .react(mixed => void, opts: Lifecycle): void

See [Reactions](#reactions).

#### .maybeReact(mixed => void, opts: Lifecycle): void

See [Reactions](#reactions).

### Proxy

```
type CompositeProxy<T> = {
get(): T;
set(value: T): void;
};
proxy(descriptor: Proxy): CompositeProxy
type Proxy<ParentType, ChildType> = {
get(source: ParentType): ChildType;
set(source: ParentType, value: ChildType): ParentType;
};
```

#### proxy(descriptor): Proxy

#### .set(value: mixed): void

#### .get(): mixed

#### .update(mixed => mixed): void

#### .proxy(descriptor): Proxy

#### .derive(mixed => mixed): Derivation

#### .maybeDerive(mixed => mixed): Derivation

#### .orDefault(mixed | Atom | Derivation | Proxy): Derivation

#### .react(mixed => void, opts: Lifecycle): void

See [Reactions](#reactions).

#### .maybeReact(mixed => void, opts: Lifecycle): void

See [Reactions](#reactions).

### Reactions

Reaction allows you to react on changes happend in any derivable item (atom,
derivation or proxy). Reaction method accepts callback and lifecycle options

#### Lifecycle

**from: Derivable<boolean> | (Derivable => boolean)**

Used to determine the start of the reactor's lifecycle. When it becomes truthy,
the reactor is initialized. After which point this property is not used.

**when: Derivable<boolean> | (Derivable => boolean)**

Causes the reactor to be started and stopped based on the truthiness of the
given condition.

**until: Derivable<boolean> | (Derivable => boolean)**

Used to determine the end of a reactor's lifecycle. When it becomes truthy the
reactor is killed, after which point the reactor will never be used again and is
eligible for garbage collection.

**skipFirst: boolean**

Causes the first invocation (and only the first invocation) of the reactor to be
ingored.

**once: boolean**

Causes the reactor to be killed immediately following its first invocation (not
counting the skipped invocation, if `skipFirst` is set to true).

#### .react(mixed => void, opts: Lifecycle): void

Accept callback with current derivable value and [Lifecycle](#lifecycle).

#### .maybeReact(mixed => void, opts: Lifecycle): void

Accept callback which is called with current derivable value if the value is not
null or undefined and [Lifecycle](#lifecycle).

### Transaction

#### transact(() => void): void

Executes passed function in the context of a transaction.

In a transactional context, changes to atoms do not have side effects. All
changes made during the transaction are propagated for side effects when the
transaction commits.

```js
const firstName = `Joe`,
lastName = `Schmoe`;

derive`My name is ${firstName} ${lastName}`.react(
x => console.log(x);
);
// $> My name is Joe Schmoe
```

All good, but now we want to change the name to Tigran Hamasayan.

```js
firstName.set(`Tigran`);
// $> My name is Tigran Schmoe
```

Doh! Tigran Schmoe isn't a person! We certainly don't want reactors to think he
is, that could be totally confusing for someone.

`transact` to the rescue! Let's abort the previous mission and try changing the
name to William Blake without ever having a William Schmoe.

```js
transact(() => {
firstName.set(`William`);
lastName.set(`Blake`);
});
// $> My name is William Blake
```

#### transaction((...args) => void): (...args) => void

Wraps passed function such that its body is executed in a transaction. Preserves
its input and output semantics.

```js
const firstName = `Joe`,
lastName = `Schmoe`;

derive`My name is ${firstName} ${lastName}`.react(
x => console.log(x);
);
// $> My name is Joe Schmoe

setTimeout(transaction(() => {
firstName.set(`William`);
lastName.set(`Blake`);
}), 1000);

// ... 1 second later ...
// $> My name is William Blake
```

#### atomically(() => void): void

As `transact` but will not create a (nested) transaction if already in a
transaction.

#### atomic((...args) => void): (...args) => void

As `transaction` but will not create a (nested) transaction if the returned
function is invoked within a transaction.

#### ticker(): t

Creates a new ticker

**t.tick(): void**

Runs all pending reactions

**t.release(): void**

Releases this ticker, rendering it useless

### Utils

#### setDebugMode(debugMode: boolean): void

Enable or disable debug mode.

This causes Errors to be created (but not thrown) alongside derivations in order
to capture the stack trace at their point of instantiation. In case a derivation
throws an error itself when being computed, its instantiation stack trace is
logged such that it becomes easy to determine exactly which derivation is
throwing. Creating errors is quite slow, so you probably should not keep this
enabled for production.

#### isAtom(value: mixed): boolean

Returns true if passed value is an Atom.

#### isDerivation(value: mixed): boolean

Returns true if passed value is a derivation, i.e. a derivable which is not an
atom.

#### isProxy(value: mixed): boolean

Returns true if passed value is a proxy of atoms.

#### isDerivable(value: mixed): boolean

Returns true if passed value is any of atoms or derivations.

#### struct(value: Object | Array): Derivable

Given some plain JavaScript `Object` or `Array` (or some nested combination
thereof) containing one or more derivable things, returns a new derivable
representing the input collection with unpacked values. e.g.

```js
const a = atom(`Andrew`),
b = atom(`Bernice`),
c = atom(`Charlie`);

const together = struct({ a: a, bandc: [b, c] });

together.react(names => {
console.log(`A stands for ${names.a}`);
console.log(`B stands for ${names.bandc[0]}`);
console.log(`C stands for ${names.bandc[1]}`);
});
// $> A stands for Andrew
// $> B stands for Bernice
// $> C stands for Charlie

c.set(`Chris`);
// $> A stands for Andrew
// $> B stands for Bernice
// $> C stands for Chris
```

#### unpack(value: Derivable | mixed): mixed

If passed value is derivable, returns value.get(), otherwise returns value.

#### captureDereferences(() => void): Array

<Derivable>

Returns array of all changed derivables with reactions inside passed function.
e.g.

```js
const captured = captureDereferences(() => {
const a = atom(1);
const b = atom(2);
const sum = derive(() => a.get() + b.get());

sum.react(d => {
console.log(d);
});

a.react(d => {
console.log(d);
});
});
/*
Atom(1)
Derivation(3)
and a few internal derivations
*/
```

0 comments on commit 279467a

Please sign in to comment.