react-use-action-cable-ts
Advanced tools
Comparing version 2.0.1 to 2.0.2
import { ChannelNameWithParams, Consumer, Subscription } from "@rails/actioncable"; | ||
type Action = Parameters<Subscription["perform"]>[0]; | ||
type Payload = Parameters<Subscription["perform"]>[1]; | ||
export declare function useActionCable(url: string, { verbose }?: { | ||
verbose: boolean; | ||
}): { | ||
export type ActionCableOptions = { | ||
verbose?: boolean; | ||
}; | ||
export declare function useActionCable(url: string, { verbose }?: ActionCableOptions): { | ||
actionCable: Consumer; | ||
}; | ||
export type ChannelOptions = { | ||
verbose?: boolean; | ||
incomingTransformer?: <T extends Payload | ChannelNameWithParams>(incomingData: T) => T extends ChannelNameWithParams ? ChannelNameWithParams : Payload; | ||
outgoingTransformer?: <T extends Payload | ChannelNameWithParams>(outgoingData: T) => T extends ChannelNameWithParams ? ChannelNameWithParams : Payload; | ||
verbose: boolean; | ||
receiveCamelCase: boolean; | ||
sendSnakeCase: boolean; | ||
}; | ||
export declare function useChannel<T>(actionCable: Consumer, { verbose, incomingTransformer, outgoingTransformer }?: ChannelOptions): { | ||
export declare function useChannel<T>(actionCable: Consumer, { verbose, receiveCamelCase, sendSnakeCase }?: ChannelOptions): { | ||
subscribe: (data: ChannelNameWithParams, callbacks: { | ||
@@ -16,0 +17,0 @@ received?: (x: T) => void; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useChannel = exports.useActionCable = void 0; | ||
const actioncable_1 = require("@rails/actioncable"); | ||
const camelcase_keys_1 = __importDefault(require("camelcase-keys")); | ||
const react_1 = require("react"); | ||
const log = (x) => { | ||
if (x.verbose) | ||
console[x.type](`useActionCable: ${x.message}`); | ||
}; | ||
function useActionCable(url, { verbose } = { verbose: false }) { | ||
const snakecase_keys_1 = __importDefault(require("snakecase-keys")); | ||
function useActionCable(url, { verbose } = {}) { | ||
const actionCable = (0, react_1.useMemo)(() => (0, actioncable_1.createConsumer)(url), []); | ||
(0, react_1.useEffect)(() => { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: "Created Action Cable" | ||
}); | ||
verbose && console.info("useActionCable: Created Action Cable"); | ||
return () => { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: "Disconnected Action Cable" | ||
}); | ||
verbose && console.info("useActionCable: Disconnected Action Cable"); | ||
actionCable.disconnect(); | ||
@@ -32,3 +25,7 @@ }; | ||
exports.useActionCable = useActionCable; | ||
function useChannel(actionCable, { verbose, incomingTransformer, outgoingTransformer } = {}) { | ||
function useChannel(actionCable, { verbose, receiveCamelCase, sendSnakeCase } = { | ||
verbose: false, | ||
receiveCamelCase: true, | ||
sendSnakeCase: true | ||
}) { | ||
const [queue, setQueue] = (0, react_1.useState)([]); | ||
@@ -44,16 +41,8 @@ const [connected, setConnected] = (0, react_1.useState)(false); | ||
const subscribe = (data, callbacks) => { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Connecting to ${data.channel}` | ||
}); | ||
const channel = actionCable.subscriptions.create(outgoingTransformer?.(data) || data, { | ||
verbose && console.info(`useChannel: Connecting to ${data.channel}`); | ||
const channel = actionCable.subscriptions.create((sendSnakeCase && (0, snakecase_keys_1.default)(data)) || data, { | ||
received: (x) => { | ||
log({ | ||
verbose, | ||
type: "info", | ||
message: `Received ${JSON.stringify(x)}` | ||
}); | ||
if (incomingTransformer && x) { | ||
x = incomingTransformer(x); | ||
verbose && console.info(`useChannel: Received ${JSON.stringify(x)}`); | ||
if (receiveCamelCase && x) { | ||
x = (0, camelcase_keys_1.default)(x); | ||
} | ||
@@ -63,7 +52,3 @@ callbacks.received?.(x); | ||
initialized: () => { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Init ${data.channel}` | ||
}); | ||
verbose && console.info(`useChannel: Init ${data.channel}`); | ||
setSubscribed(true); | ||
@@ -73,7 +58,3 @@ callbacks.initialized?.(); | ||
connected: () => { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Connected to ${data.channel}` | ||
}); | ||
verbose && console.info(`useChannel: Connected to ${data.channel}`); | ||
setConnected(true); | ||
@@ -83,7 +64,3 @@ callbacks.connected?.(); | ||
disconnected: () => { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Disconnected` | ||
}); | ||
verbose && console.info(`useChannel: Disconnected`); | ||
setConnected(false); | ||
@@ -98,7 +75,4 @@ callbacks.disconnected?.(); | ||
if (channelRef.current) { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Unsubscribing from ${channelRef.current.identifier}` | ||
}); | ||
verbose && | ||
console.info(`useChannel: Unsubscribing from ${channelRef.current.identifier}`); | ||
// @ts-ignore | ||
@@ -114,7 +88,4 @@ actionCable.subscriptions.remove(channelRef.current); | ||
else if ((!subscribed || !connected) && queue.length > 0) { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Queue paused. Subscribed: ${subscribed}. Connected: ${connected}. Queue length: ${queue.length}` | ||
}); | ||
verbose && | ||
console.info(`useChannel: Queue paused. Subscribed: ${subscribed}. Connected: ${connected}. Queue length: ${queue.length}`); | ||
} | ||
@@ -133,15 +104,9 @@ }, [queue[0], connected, subscribed]); | ||
catch { | ||
log({ | ||
verbose: verbose, | ||
type: "warn", | ||
message: `Unable to perform action '${action.action}'. It will stay at the front of the queue.` | ||
}); | ||
verbose && | ||
console.warn(`useChannel: Unable to perform action '${action.action}'. It will stay at the front of the queue.`); | ||
} | ||
}; | ||
const enqueue = (action, payload) => { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Adding action to queue - ${action}: ${JSON.stringify(payload)}` | ||
}); | ||
verbose && | ||
console.info(`useChannel: Adding action to queue - ${action}: ${JSON.stringify(payload)}`); | ||
setQueue((prevState) => [ | ||
@@ -157,19 +122,18 @@ ...prevState, | ||
if (subscribed && !connected) | ||
throw Error("useActionCable: not connected"); | ||
throw Error("useChannel: not connected"); | ||
if (!subscribed) | ||
throw Error("useActionCable: not subscribed"); | ||
throw Error("useChannel: not subscribed"); | ||
try { | ||
log({ | ||
verbose: verbose, | ||
type: "info", | ||
message: `Sending ${action} with payload ${JSON.stringify(payload)}` | ||
}); | ||
verbose && | ||
console.info(`useChannel: Sending ${action} with payload ${JSON.stringify(payload)}`); | ||
channelRef.current?.perform(action, payload); | ||
} | ||
catch { | ||
throw Error("useActionCable: Unknown error"); | ||
throw Error("useChannel: Unknown error"); | ||
} | ||
}; | ||
const send = ({ action, payload, useQueue }) => { | ||
const formattedPayload = outgoingTransformer && payload ? outgoingTransformer(payload) : payload; | ||
const formattedPayload = sendSnakeCase && payload | ||
? (0, snakecase_keys_1.default)(payload) | ||
: payload; | ||
if (useQueue) { | ||
@@ -176,0 +140,0 @@ enqueue(action, formattedPayload); |
{ | ||
"name": "react-use-action-cable-ts", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"description": "Hooks to easily use Rails Action Cable in your React application", | ||
@@ -27,3 +27,5 @@ "main": "./dist/index.js", | ||
"dependencies": { | ||
"@rails/actioncable": "7.1.3" | ||
"@rails/actioncable": "7.1.3", | ||
"camelcase-keys": "7.0.2", | ||
"snakecase-keys": "6.0.0" | ||
}, | ||
@@ -30,0 +32,0 @@ "devDependencies": { |
10200
4
172
+ Addedcamelcase-keys@7.0.2
+ Addedsnakecase-keys@6.0.0
+ Addedcamelcase@6.3.0(transitive)
+ Addedcamelcase-keys@7.0.2(transitive)
+ Addeddot-case@3.0.4(transitive)
+ Addedlower-case@2.0.2(transitive)
+ Addedmap-obj@4.3.0(transitive)
+ Addedno-case@3.0.4(transitive)
+ Addedquick-lru@5.1.1(transitive)
+ Addedsnake-case@3.0.4(transitive)
+ Addedsnakecase-keys@6.0.0(transitive)
+ Addedtslib@2.8.1(transitive)
+ Addedtype-fest@1.4.03.13.1(transitive)