Skip to content

Commit

Permalink
Add support for [method="morph"] for update and replace actions (#7)
Browse files Browse the repository at this point in the history
Close: #6
  • Loading branch information
tajakobsen authored Aug 12, 2024
1 parent 85db4ee commit fc8a100
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-kangaroos-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@item-enonic-types/lib-turbo-streams": minor
---

Add support for [method="morph"] for update and replace actions
45 changes: 41 additions & 4 deletions src/main/resources/lib/turbo-streams/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export type TurboStreamChangeAction = {
/**
* Action to perform
*/
readonly action: Exclude<(typeof actionNames)[number], "remove" | "refresh">;
readonly action: Exclude<(typeof actionNames)[number], "remove" | "refresh" | "replace" | "update">;

/**
* Dom ID to update
Expand All @@ -22,6 +22,33 @@ export type TurboStreamChangeAction = {
readonly content: string;
};

export type TurboStreamMorphableAction = {
/**
* Action to perform
*/
readonly action: "replace" | "update";

/**
* Dom ID to update
*/
readonly target?: string;

/**
* CSS Query selector to update
*/
readonly targets?: string;

/**
* The new content to insert into the dom
*/
readonly content: string;

/**
* Set to "morph" to only morph the children of the element designated by the target dom id.
*/
readonly method?: "morph";
};

export type TurboStreamRemoveAction = {
/**
* Action to perform
Expand Down Expand Up @@ -54,7 +81,11 @@ export type TurboStreamRefreshAction = {
/**
* Type that can be serialized into a turbo stream action frame
*/
export type TurboStreamAction = TurboStreamChangeAction | TurboStreamRemoveAction | TurboStreamRefreshAction;
export type TurboStreamAction =
| TurboStreamChangeAction
| TurboStreamRemoveAction
| TurboStreamRefreshAction
| TurboStreamMorphableAction;

/**
* Guard that verifies that an object is of type TurboStreamAction
Expand Down Expand Up @@ -100,13 +131,13 @@ function serializeOne(action: TurboStreamAction): string {
case "after":
return action.target
? `
<turbo-stream action="${action.action}" target="${action.target}">
<turbo-stream action="${action.action}" target="${action.target}${getMorphAttribute(action)}">
<template>
${action.content}
</template>
</turbo-stream>`.trim()
: `
<turbo-stream action="${action.action}" targets="${action.targets}">
<turbo-stream action="${action.action}" targets="${action.targets}${getMorphAttribute(action)}">
<template>
${action.content}
</template>
Expand All @@ -115,3 +146,9 @@ function serializeOne(action: TurboStreamAction): string {
return "";
}
}

function getMorphAttribute(action: TurboStreamAction): string {
return (action.action === "replace" || action.action === "update") && action.method === "morph"
? ` action="morph"`
: "";
}
25 changes: 21 additions & 4 deletions src/main/resources/lib/turbo-streams/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type TurboStreamChangeAction,
TurboStreamAction,
TurboStreamRefreshAction,
TurboStreamMorphableAction,
} from "./actions";
import type { Request, Response } from "@item-enonic-types/global/controller";

Expand Down Expand Up @@ -56,29 +57,31 @@ export function prepend(params: TurboStreamsParams): void {
/**
* Replace some markup at a target id in the dom over web socket
*/
export function replace(params: TurboStreamsParams): void {
export function replace(params: TypeStreamsMorhphableParams): void {
sendByWebSocket(
params,
serialize({
action: "replace",
content: params.content,
target: params.target,
targets: params.targets,
method: params.method,
}),
);
}

/**
* Updates some markup inside a target with the id in the dom over web socket
*/
export function update(params: TurboStreamsParams): void {
export function update(params: TypeStreamsMorhphableParams): void {
sendByWebSocket(
params,
serialize({
action: "update",
content: params.content,
target: params.target,
targets: params.targets,
method: params.method,
}),
);
}
Expand Down Expand Up @@ -167,14 +170,28 @@ export function createTurboStreamResponse(actions: TurboStreamAction | Array<Tur
export type TurboStreamsParams = Omit<TurboStreamChangeAction, "action"> & SendByWebSocketTarget;

/**
* Parameters for "remove". It takes either "socketId" or "groupId".
* Parameters for "replace" and "update". It takes either "socketId" or "groupId".
*
* If neither is specified it falls back to the default group. The default group has a name based on the session
* key from the request. If the "turbo-streams"-service was used this is the group registered with the web socket.
*/
export type TurboStreamsRemoveParams = Omit<TurboStreamRemoveAction, "action"> & SendByWebSocketTarget;
export type TypeStreamsMorhphableParams = Omit<TurboStreamMorphableAction, "action"> & SendByWebSocketTarget;

/**
* Parameters for "refresh". It takes either "socketId" or "groupId".
*
* If neither is specified it falls back to the default group. The default group has a name based on the session
* key from the request. If the "turbo-streams"-service was used this is the group registered with the web socket.
*/
export type TypeStreamsRefreshParams = Omit<TurboStreamRefreshAction, "action"> & SendByWebSocketTarget;

/**
* Parameters for "remove". It takes either "socketId" or "groupId".
*
* If neither is specified it falls back to the default group. The default group has a name based on the session
* key from the request. If the "turbo-streams"-service was used this is the group registered with the web socket.
*/
export type TurboStreamsRemoveParams = Omit<TurboStreamRemoveAction, "action"> & SendByWebSocketTarget;

export * from "./actions";
export { getUsersPersonalGroupName, getWebSocketUrl, SERVICE_NAME_TURBO_STREAMS } from "./websockets";

0 comments on commit fc8a100

Please sign in to comment.