Skip to content

Commit

Permalink
docs: update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
giladgd committed Nov 22, 2023
1 parent 6ffaaa3 commit d9ed402
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 3 deletions.
12 changes: 12 additions & 0 deletions .run/test.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="test" type="JavaScriptTestRunnerVitest">
<node-interpreter value="project" />
<vitest-package value="$PROJECT_DIR$/node_modules/vitest" />
<working-dir value="$PROJECT_DIR$" />
<vitest-options value="--run" />
<envs />
<scope-kind value="DIRECTORY" />
<test-directory value="$PROJECT_DIR$/test" />
<method v="2" />
</configuration>
</component>
207 changes: 204 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ npm install --save lifecycle-utils
Calling `withLock` with the same `scope` and `key` will ensure that the callback inside cannot run in parallel to other calls with the same `scope` and `key`.

```typescript
import { withLock } from "lifecycle-utils";
import {withLock} from "lifecycle-utils";

const scope = {}; // can be reference to any object you like
const startTime = Date.now();
Expand Down Expand Up @@ -53,7 +53,7 @@ console.log(res); // [42, 42, 42]
Check whether a lock is currently active for the given `scope` and `key`.

```typescript
import { isLockActive } from "lifecycle-utils";
import {isLockActive} from "lifecycle-utils";

const scope = {}; // can be reference to any object you like

Expand All @@ -65,7 +65,7 @@ console.log(res); // false
Acquire a lock for the given `scope` and `key`.

```typescript
import { acquireLock } from "lifecycle-utils";
import {acquireLock} from "lifecycle-utils";

const scope = {}; // can be reference to any object you like

Expand All @@ -77,6 +77,207 @@ console.log("lock acquired");
activeLock.dispose();
```

### `EventRelay`
A simple event relay.

Create a listener with `createListener` and dispatch events with `dispatchEvent`.

For each supported event type, create a new instance of `EventRelay` and expose it as a property.

For example, this code:
```ts
import {EventRelay} from "lifecycle-utils";

class MyClass {
public readonly onSomethingHappened = new EventRelay<string>();

public doSomething(whatToDo: string) {
this.onSomethingHappened.dispatchEvent(whatToDo);
console.log("Done notifying listeners");
}
}

const myClass = new MyClass();
myClass.onSomethingHappened.createListener((whatHappened) => {
console.log(`Something happened: ${whatHappened}`);
});
myClass.doSomething("eat a cookie");
```

Will print this:
```
Something happened: eat a cookie
Done notifying listeners
```

### `DisposeAggregator`
`DisposeAggregator` is a utility class that allows you to add multiple items and then dispose them all at once.

You can add a function to call, an object with a `dispose` method, or an object with a `Symbol.dispose` method.

To dispose all the items, call `dispose` or use the `Symbol.dispose` symbol.

```typescript
import {DisposeAggregator, EventRelay} from "lifecycle-utils";

const disposeAggregator = new DisposeAggregator();

const eventRelay = new EventRelay<string>();
disposeAggregator.add(eventRelay);

const eventRelay2 = disposeAggregator.add(new EventRelay<string>());

disposeAggregator.dispose();
console.log(eventRelay.disposed === true); // true
console.log(eventRelay2.disposed === true); // true
```

### `AsyncDisposeAggregator`
`AsyncDisposeAggregator` is a utility class that allows you to add multiple items and then dispose them all at once.

The items are disposed one by one in the order they were added.

You can add a function to call, an object with a `dispose` method, an object with a `Symbol.dispose` method,

an object with a `Symbol.asyncDispose` method, or a Promise that resolves to one of the previous types.

To dispose all the items, call `dispose` or use the `Symbol.asyncDispose` symbol.

The difference between `AsyncDisposeAggregator` and `DisposeAggregator` is that `AsyncDisposeAggregator` can dispose async targets.

```typescript
import {AsyncDisposeAggregator, EventRelay} from "lifecycle-utils";

const disposeAggregator = new AsyncDisposeAggregator();

const eventRelay = new EventRelay<string>();
disposeAggregator.add(eventRelay);

disposeAggregator.add(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
// do some async work
});

disposeAggregator.dispose();
```

### `LongTimeout`
A timeout that can be set to a delay longer than the maximum timeout delay supported by a regular `setTimeout`.

```typescript
import {LongTimeout} from "lifecycle-utils";

const month = 1000 * 60 * 60 * 24 * 7 * 30;

const timeout = new LongTimeout(() => {
console.log("timeout");
}, month);

// to clear the timeout, call dispose
// timeout.dispose();
```

### `setLongTimeout`
Sets a timeout that can also be set to a delay longer than the maximum timeout delay supported by a regular `setTimeout`.

You can use `clearLongTimeout` to clear the timeout.

```typescript
import {setLongTimeout, clearLongTimeout} from "lifecycle-utils";

const month = 1000 * 60 * 60 * 24 * 7 * 30;

const timeout = setLongTimeout(() => {
console.log("timeout");
}, month);

// to clear the timeout, call clearLongTimeout
// clearLongTimeout(timeout);
```

### `clearLongTimeout`
Clears a timeout that was set with `setLongTimeout`.

You can also clear a regular timeout with this function.

```typescript
import {setLongTimeout, clearLongTimeout} from "lifecycle-utils";

const month = 1000 * 60 * 60 * 24 * 7 * 30;

const timeout = setLongTimeout(() => {
console.log("timeout");
}, month);
const timeout2 = setTimeout(() => {
console.log("timeout2");
}, 1000 * 60);

clearLongTimeout(timeout);
clearLongTimeout(timeout2);
```

### `State`
`State` is a utility class that allows you to hold a value and notify listeners when the value changes.

```typescript
import {State} from "lifecycle-utils";

const valueState = new State<number>(6);

const eventHandle = valueState.createChangeListener((newValue, previousValue) => {
console.log("new value:", newValue);
console.log("previous value:", previousValue);
});

valueState.state = 7;

// after a microtask, the listener will be called
// to make event fire immediately upon change, disable the `queueEvents` option on the constructor
await new Promise(resolve => setTimeout(resolve, 0));
// will print:
// new value: 7
// previous value: 6

eventHandle.dispose();
```

### `State.createCombinedChangeListener`
Create a listener that listens to multiple states and calls the callback when any of the states change.

```typescript
import {State} from "lifecycle-utils";

const valueState1 = new State<number>(6);
const valueState2 = new State<string>("hello");
const valueState3 = new State<boolean>(true);

const eventHandle = State.createCombinedChangeListener([valueState1, valueState2, valueState3], (newValues, previousValues) => {
console.log("new values:", newValues);
console.log("previous values:", previousValues);
});

valueState1.state = 7;
valueState2.state = "world";
valueState3.state = false;

// after a microtask, the listener will be called
// to make event fire immediately upon change, disable the `queueEvents` option on the constructor
await new Promise(resolve => setTimeout(resolve, 0));
// will print:
// new values: [7, "world", false]
// previous values: [6, "hello", true]

eventHandle.dispose();
```

### `splitText`
Split a text by multiple separators, and return a result of the text and separators.

```typescript
const parts = splitText("Hello <and> world [then] !", ["<and>", "[then]"]);
console.log(parts); // ["Hello ", new Separator("<and>"), " world ", new Separator("[then]"), " !"]
```

## Contributing
To contribute to `lifecycle-utils` see [CONTRIBUTING.md](https://github.com/giladgd/lifecycle-utils/blob/master/CONTRIBUTING.md).

Expand Down

0 comments on commit d9ed402

Please sign in to comment.