Skip to content

Commit

Permalink
Merge pull request #10 from cesarParra/event-bus-store
Browse files Browse the repository at this point in the history
Event bus store
  • Loading branch information
cesarParra authored Nov 1, 2024
2 parents fdd6844 + 27ec701 commit 7fa4019
Show file tree
Hide file tree
Showing 24 changed files with 593 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ $RECYCLE.BIN/

IlluminatedCloud/
.idea/
/.localdev/
64 changes: 63 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@ The following storage helpers are available by default:
- `useEventListener(eventName: string)`: Dispatches a CustomEvent to the `window` object with the given event name
whenever the signal changes. It also listens for events with the given name and updates the signal when the event is
received. This is useful for when you want to communicate changes to components that for some reason don't
have access to the signal (for example, a component that cannot import the signal because it lives in a different namespace).
have access to the signal (for example, a component that cannot import the signal because it lives in a different
namespace).

The event sent and expected to be received has the following format:

Expand Down Expand Up @@ -754,6 +755,67 @@ The following storage helpers are available by default:
}
```

- `useEventBus(channel: string, toValue: (response?: object) => T, options: object)`: Subscribes to the event bus
channel (e.g. platform event, change data capture, etc.).

- The `channel` parameter is the event bus channel to subscribe to.
- The `toValue` function is used to convert the response from the event bus to the desired value.

```javascript
import { $signal, useEventBus } from "c/signals";
export const receivedEvent = $signal(undefined, {
storage: useEventBus("/event/PlatEvent__e", ({ data }) => ({
message: data.payload.Message__c,
sender: data.payload.Sender__c,
time: data.payload.Time__c
}))
});
```

The passed in argument will be the message received from the event bus, which
is of the following shape:

```javascript
{
channel: string;
data: {
event: {
replayId: number;
},
payload: object,
};
}
```

The `payload` key will contain the actual data of the event. For example,
if using a platform event, this will contain the fields of the platform event.

- The `options` (optional) parameter is an object that can contain the following properties (all of them optional):
- `replayId` The replay ID to start from, defaults to -1. When -2 is passed, it will replay from the last saved event.
- `onSubscribe` A callback function called when the subscription is successful.
- `onError` A callback function called when an error response is received from the server for
handshake, connect, subscribe, and unsubscribe meta channels.

**Unsubscribing from the event bus**

When using the `useEventBus` storage, the signal will hold a special function called `unsubscribe` that you can call
to unsubscribe from the event bus.

```javascript
import { $signal, useEventBus } from "c/signals";

const receivedEvent = $signal(undefined, {
storage: useEventBus("/event/PlatEvent__e", ({ data }) => ({
message: data.payload.Message__c,
sender: data.payload.Sender__c,
time: data.payload.Time__c
}))
});

// Unsubscribe from the event bus
receivedEvent.unsubscribe();
```

### Creating a custom storage

The `storage` option receives a function that defines the behavior for where the data should be stored.
Expand Down
4 changes: 3 additions & 1 deletion examples/counter/lwc/countChanger/countChanger.js-meta.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@
<targets>
<target>lightningCommunity__Default</target>
<target>lightningCommunity__Page</target>
<target>lightning__HomePage</target>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
</LightningComponentBundle>
3 changes: 2 additions & 1 deletion examples/counter/lwc/countTracker/countTracker.js-meta.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
<targets>
<target>lightningCommunity__Default</target>
<target>lightningCommunity__Page</target>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
</LightningComponentBundle>
16 changes: 16 additions & 0 deletions examples/demo-signals/lwc/demoSignals/chat-data-source.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { $signal, useEventBus } from "c/signals";

export const messageEvent = $signal(undefined, {
storage: useEventBus(
"/event/ChatMessage__e",
({ data }) => ({
message: data.payload.Message__c,
sender: data.payload.Sender__c,
time: data.payload.Time__c
}),
{
replayId: -2,
onSubscribe: (message) => console.log("Subscribed to message", message)
}
)
});
2 changes: 1 addition & 1 deletion examples/demo-signals/lwc/demoSignals/counter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { $signal, $effect, $computed, useLocalStorage, useEventListener } from "c/signals";
import { $signal, $effect, $computed, useEventListener } from "c/signals";

// EXAMPLE OF DEFAULT COUNTER

Expand Down
1 change: 1 addition & 0 deletions examples/demo-signals/lwc/demoSignals/demoSignals.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from "./counter";
export * from "./contact-info";
export * from "./apex-fetcher";
export * from "./shopping-cart";
export * from "./chat-data-source";
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<deploymentStatus>Deployed</deploymentStatus>
<eventType>HighVolume</eventType>
<label>ChatMessage</label>
<pluralLabel>ChatMessages</pluralLabel>
<publishBehavior>PublishImmediately</publishBehavior>
</CustomObject>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Message__c</fullName>
<externalId>false</externalId>
<isFilteringDisabled>false</isFilteringDisabled>
<isNameField>false</isNameField>
<isSortingDisabled>false</isSortingDisabled>
<label>Message</label>
<length>255</length>
<required>true</required>
<type>Text</type>
<unique>false</unique>
</CustomField>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Sender__c</fullName>
<externalId>false</externalId>
<isFilteringDisabled>false</isFilteringDisabled>
<isNameField>false</isNameField>
<isSortingDisabled>false</isSortingDisabled>
<label>Sender</label>
<length>255</length>
<required>true</required>
<type>Text</type>
<unique>false</unique>
</CustomField>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Time__c</fullName>
<defaultValue>NOW()</defaultValue>
<externalId>false</externalId>
<isFilteringDisabled>false</isFilteringDisabled>
<isNameField>false</isNameField>
<isSortingDisabled>false</isSortingDisabled>
<label>Time</label>
<required>true</required>
<type>DateTime</type>
</CustomField>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public with sharing class ChatController {
@AuraEnabled
public static void sendMessage(String message, String sender) {
EventBus.publish(new ChatMessage__e(
Message__c = message,
Sender__c = sender
));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>60.0</apiVersion>
<status>Active</status>
</ApexClass>
49 changes: 49 additions & 0 deletions examples/real-time-through-event-bus/lwc/chat/chat.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<lightning-card title="Signals Chat">
<div class="slds-p-horizontal_small">
<div class="slds-p-around_medium lgc-bg">
<lightning-input
type="text"
label="Your name"
value={sender}
onchange={handleNameChange}
></lightning-input>
</div>
<section role="log" class="slds-chat">
<ul class="slds-chat-list">
<template for:each={formattedMessages} for:item="message">
<li key={message.message} class={message.listClasses}>
<div class="slds-chat-message">
<div class="slds-chat-message__body">
<div class={message.messageClasses}>
<span>{message.message}</span>
</div>
<div class="slds-chat-message__meta" aria-label="the message">
{message.sender} • {message.time}
</div>
</div>
</div>
</li>
</template>
</ul>
</section>
<div class="slds-p-around_medium lgc-bg">
<lightning-input
type="text"
label="Enter your message"
onchange={handleMessageChange}
disabled={isMessageBoxDisabled}
></lightning-input>
<lightning-button
label="Send"
onclick={sendMessage}
disabled={isSendDisabled}
stretch="true"
></lightning-button>
</div>
</div>
<div slot="footer">
<lightning-button label="Unsubscribe" onclick={unsub}></lightning-button>
</div>
</lightning-card>
</template>
65 changes: 65 additions & 0 deletions examples/real-time-through-event-bus/lwc/chat/chat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { LightningElement } from "lwc";
import { $effect } from "c/signals";
import { messageEvent } from "c/demoSignals";
import sendMessage from "@salesforce/apex/ChatController.sendMessage";

export default class Chat extends LightningElement {
sender = "User";
message = "";

messages = [];

connectedCallback() {
$effect(() => {
if (messageEvent.value) {
console.log("Message received in the component", messageEvent.value);
this.messages = [...this.messages, messageEvent.value];
}
});
}

get formattedMessages() {
return this.messages.map((message) => {
return {
...message,
listClasses:
message.sender === this.sender
? "slds-chat-listitem slds-chat-listitem_outbound"
: "slds-chat-listitem slds-chat-listitem_inbound",
messageClasses:
message.sender === this.sender
? "slds-chat-message__text slds-chat-message__text_outbound"
: "slds-chat-message__text slds-chat-message__text_inbound"
};
});
}

handleNameChange(event) {
this.sender = event.detail.value;
}

handleMessageChange(event) {
this.message = event.detail.value;
}

get isMessageBoxDisabled() {
return !this.sender;
}

get isSendDisabled() {
return !this.message || !this.sender;
}

sendMessage() {
sendMessage({
message: this.message,
sender: this.sender
});
}

unsub() {
messageEvent.unsubscribe((res) =>
console.log("Unsubscribed from message channel", res)
);
}
}
10 changes: 10 additions & 0 deletions examples/real-time-through-event-bus/lwc/chat/chat.js-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>60.0</apiVersion>
<description>Chat</description>
<isExposed>true</isExposed>
<masterLabel>Chat</masterLabel>
<targets>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import { fetchContacts } from "c/demoSignals";

export default class ServerFetcher extends LightningElement {
contacts = $computed(() => (this.contacts = fetchContacts.value)).value;
}
}
Loading

0 comments on commit 7fa4019

Please sign in to comment.