Skip to content

Commit

Permalink
0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Jdyn authored Feb 15, 2024
2 parents 2481302 + 84cc2e1 commit 8ca2574
Show file tree
Hide file tree
Showing 21 changed files with 574 additions and 481 deletions.
71 changes: 32 additions & 39 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,41 +1,34 @@
{
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
"react-hooks",
"simple-import-sort"
],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {},
"overrides": [
{
"files": [
"*.test.ts",
"*.test.tsx"
],
"rules": {
// Allow testing runtime errors to suppress TS errors
"@typescript-eslint/ban-ts-comment": "off"
}
}
],
"settings": {
"react": {
"pragma": "React",
"version": "detect"
}
}
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "react-hooks", "simple-import-sort"],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {},
"overrides": [
{
"files": ["*.test.ts", "*.test.tsx"],
"rules": {
// Allow testing runtime errors to suppress TS errors
"@typescript-eslint/ban-ts-comment": "off"
}
}
],
"settings": {
"react": {
"pragma": "React",
"version": "detect"
}
}
}
13 changes: 13 additions & 0 deletions .prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* {@type require('prettier').Config}
*/
module.exports = {
useTabs: false,
printWidth: 100,
singleQuote: true,
trailingComma: 'none',
bracketSameLine: false,
semi: true,
tabWidth: 2,
quoteProps: 'consistent'
};
13 changes: 0 additions & 13 deletions .prettierrc.js

This file was deleted.

51 changes: 38 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# 0.0.1

2024-2-15

I have been using this version enough in a few complex projects and has been performing very well. I'd like to move away from alpha version and just iterate versions normally. I feel the API is pretty stable at this point and I am not anticipating much more deviation except for `usePresence`. The `usePresence` hook will need to be looked at in more depth to understand the most common access patterns and provide an API that applies to the most people. Currently it deviates quite a bit from the vanilla SDK in terms of the outputted data.

### Breaking changes

- Completely remove calling `useEvent` with a `string` channel topic.
- The benefit was reusing existing channels but `useChannel` now does it inherently by default. Additionally you usually want access to important channel metadata and functions like `push` and `leave` which you simply did not get if you used a channel `string`. It is possible I reintroduce it in the future but it adds some more complexity and was not working consistently.

### Additional changes

- Calling `useChannel` on the same channel topic across any number of components should just work, and keep all components connected and listening. Additionally, the state object should be consistent across all `useChannel` topics across components.

- expose an `isConnected` boolean inside `usePhoenix` to know when the socket has officially connected. This is useful for example, in cases when you want to request data with push right when the socket connects, and you dont want to specify the socket itself as a dependency to the useEffect since it would trigger the useEffect many times.
# 0.0.1-alpha.8

2023-1-05
Expand All @@ -13,27 +29,34 @@ None
2023-12-27

### Breaking changes

None

### Additional changes
* Fix buggy behavior where the reference to `useChannel` functions would be changing on every render. This would cause your useEffects to run even if there should be no change.

- Fix buggy behavior where the reference to `useChannel` functions would be changing on every render. This would cause your useEffects to run even if there should be no change.

# 0.0.1-alpha.6

2023-12-23

### Breaking changes

None

### Additional changes
* Fixed a bug where if you successfully connected to a channel, but then later on the topic supplied to `useChannel` had changed to `null` and then back to the valid topic, the `useChannel` hook functions like `push` would no longer be holding a valid reference to the channel. Now, the hook will successfully update the reference and the functions will work as if the channel topic never changed.
* Use the internel channel `ref` when using `useChannel`'s `leave`

- Fixed a bug where if you successfully connected to a channel, but then later on the topic supplied to `useChannel` had changed to `null` and then back to the valid topic, the `useChannel` hook functions like `push` would no longer be holding a valid reference to the channel. Now, the hook will successfully update the reference and the functions will work as if the channel topic never changed.
- Use the internel channel `ref` when using `useChannel`'s `leave`

# 0.0.1-alpha.5

2023-12-17

### Breaking changes
* The typescript type for `useChannel`'s `PushEvent` now aligns with the rest of the types

- The typescript type for `useChannel`'s `PushEvent` now aligns with the rest of the types

```jsx
type PushEvent = {
- type: string;
Expand All @@ -45,12 +68,14 @@ type PushEvent = {
```

### Additional changes
* Added rollup build tooling which should reduce bundle size slightly
* Phoenix.js is now marked as a peer dependency
* `useChannel` can now accept a short circuit operation to delay connecting to the channel until the condition is met.

```jsx
// Delay connecting until id is defined
const [channel] = useChannel(id && `room:${id}`)
```
* The `push` function type has been improved to catch more potential errors.

- Added rollup build tooling which should reduce bundle size slightly
- Phoenix.js is now marked as a peer dependency
- `useChannel` can now accept a short circuit operation to delay connecting to the channel until the condition is met.

```jsx
// Delay connecting until id is defined
const [channel] = useChannel(id && `room:${id}`);
```

- The `push` function type has been improved to catch more potential errors.
81 changes: 46 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
# use-phoenix

## Connecting to your Phoenix Socket
Wrap the intended part of your application with `PhoenixProvider`.

Wrap the intended part of your application with a `PhoenixProvider`.

```tsx
// App.tsx
import { PhoenixProvider } from 'use-phoenix';

const Application = () => {
return <PhoenixProvider>...</PhoenixProvider>;
return <PhoenixProvider>...</PhoenixProvider>;
};
```

Passing a `url` and params to your `PhoenixProvder` will connect to your socket instantly **on mount**:

```tsx
return (
<PhoenixProvider
url="ws://localhost:4000/socket"
options={{
params: { token: 'xyz' }
}}
>
...
</PhoenixProvider>
<PhoenixProvider
url="ws://localhost:4000/socket"
options={{
params: { token: 'xyz' }
}}
>
...
</PhoenixProvider>
);
```
Using the `usePhoenix` hook to connect lazily using `connect`:

You could instead use the `usePhoenix` hook to connect lazily using `connect`:

To use this option **do not pass a `url`** into `PhoenixProvider`:

```tsx
// App.tsx
return <PhoenixProvider>...</PhoenixProvider>;
Expand All @@ -39,17 +44,20 @@ Later on when you would like to connect the socket:
import { usePhoenix } from 'use-phoenix';

const Component = () => {
const { socket, connect } = usePhoenix();
const { socket, connect } = usePhoenix();

useEffect(() => {
connect('ws://localhost:4000/socket', {
params: { token: 'xyz' }
});
}, [connect]);
useEffect(() => {
connect('ws://localhost:4000/socket', {
params: { token: 'xyz' }
});
}, [connect]);
};
```

## Listening for events - `useEvent` & `useChannel`
`usePhoenix` also provides `isConnected` which becomes `true` when the socket has successfully connected.

## Quick Start - `useEvent` & `useChannel`

You can pass a short circuit expression to delay connection to an event or channel. If for example you are waiting to recieve an id to use from some network request, `useEvent` and `useChannel` will not connect until it is defined. Below is a contrived example:

```jsx
Expand All @@ -67,16 +75,24 @@ interface PongEvent {
};
}

interface JoinPayload {
secret: string;
}

interface PingResponse {
ok: boolean;
}

// Channel will not connect until id is defined
const [channel, { push }] = useChannel(id && `chat:${id}`);
const [channel, { push, data }] = useChannel<JoinPayload>(id && `chat:${id}`);
// ^^^^
// data is typed according to `JoinPayload`

const { data } = useEvent<PongEvent>(channel, 'pong');
// Events will not be listened to until data.secret is defined
const { data } = useEvent<PongEvent>(channel, data?.secret && `pong:${data.secret}`);

const handleClick = () => {
// ok is typed according to PingResponse
const { ok } = await push<PingEvent, PingResponse>('ping', { body: 'Hello World' })
}

Expand All @@ -92,7 +108,7 @@ interface PingResponse {
# useEvent
`useEvent` is a hook that allows you to succinctly listen in on a channel and receive responses.
`useEvent` is a hook that allows you to succinctly listen in on channel events.
### Example Usage
Expand All @@ -111,18 +127,15 @@ const [channel, { isSuccess, isError, ...rest }] = useChannel('chat:lobby')
// pass in a channel directly
const { data } = useEvent<JoinEvent>(channel, 'join')

// OR pass in a channel topic and let the hook create the channel internally
const { data } = useEvent<JoinEvent>('chat:lobby', 'join');

// typed
console.log(data.members)
```
Optionally, if you would rather capture the response in a callback you can:
Optionally, if you would rather capture the response in a callback you can (or both):
```tsx
useEvent<JoinEvent>('chat:lobby', 'join', (response) => {
console.log(response);
```ts
const { data } = useEvent<JoinEvent>(channel, 'join', (data) => {
console.log(response);
});
```
Expand All @@ -131,7 +144,7 @@ useEvent<JoinEvent>('chat:lobby', 'join', (response) => {
`useChannel` gives you important functions and information about the state of the channel. The following properties are available for `useChannel`
```ts
data: TJoinResponse | null; // the join response from the server
data: JoinPayload | null; // the join response from the server
status: ChannelStatus;
isSuccess: boolean;
isLoading: boolean;
Expand Down Expand Up @@ -196,16 +209,14 @@ users[0].metas.lastSeen;
## Notes
- If a channel recieves a `phx_error` event, meaning there was some internal server error, `useChannel` will leave the associated channel to avoid infinite error looping.

- Currently, `useChannel` does not automatically `leave` when the hook unmounts so the socket will continue to listen in on the channel. It is best to handle leaving the channel explicitly using `leave`:
- `useChannel` does not automatically `leave` the channel when the hook unmounts. That is, the socket will continue to listen in on the channel. It is best to handle leaving the channel explicitly using `leave` if you would like to leave the channel on component unmounts:
```ts
const [channel, { leave }] = useChannel('chat:lobby');

useEffect(() => {
return () => {
leave();
};
return () => {
leave();
};
}, [leave]);
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "use-phoenix",
"version": "0.0.1-alpha.8",
"version": "0.0.1",
"description": "React hooks for the Phoenix Framework",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand Down
Loading

0 comments on commit 8ca2574

Please sign in to comment.