Skip to content

Commit

Permalink
Add support for Refresh Action
Browse files Browse the repository at this point in the history
Closes: #3
  • Loading branch information
tajakobsen committed Aug 12, 2024
1 parent c315201 commit e821e88
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/two-seals-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@item-enonic-types/lib-turbo-streams": minor
---

Add Turbo Stream support for Refresh Action
60 changes: 45 additions & 15 deletions src/main/resources/lib/turbo-streams/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export interface TurboStreamChangeAction {
export const actionNames = ["append", "prepend", "replace", "update", "before", "after", "remove", "refresh"] as const;

export type TurboStreamChangeAction = {
/**
* Action to perform
*/
Expand All @@ -18,9 +20,9 @@ export interface TurboStreamChangeAction {
* The new content to insert into the dom
*/
readonly content: string;
}
};

export interface TurboStreamRemoveAction {
export type TurboStreamRemoveAction = {
/**
* Action to perform
*/
Expand All @@ -35,12 +37,24 @@ export interface TurboStreamRemoveAction {
* CSS Query selector to update
*/
readonly targets?: string;
}
};

export type TurboStreamRefreshAction = {
/**
* Action to perform
*/
readonly action: "refresh";

/**
* Dom ID to update
*/
readonly requestId?: string;
};

/**
* Type that can be serialized into a turbo stream action frame
*/
export type TurboStreamAction = TurboStreamChangeAction | TurboStreamRemoveAction;
export type TurboStreamAction = TurboStreamChangeAction | TurboStreamRemoveAction | TurboStreamRefreshAction;

/**
* Guard that verifies that an object is of type TurboStreamAction
Expand All @@ -51,8 +65,8 @@ export function isTurboStreamAction(v: unknown): v is TurboStreamAction {
return (
v !== undefined &&
v !== null &&
["append", "prepend", "replace", "update", "remove", "before", "after"].indexOf(value.action) !== -1 &&
typeof value.target === "string"
actionNames.indexOf(value.action) !== -1 &&
(value.action === "refresh" || typeof value.target === "string")
);
}

Expand All @@ -63,25 +77,41 @@ export function serialize(action: TurboStreamAction): string;
export function serialize(actions: ReadonlyArray<TurboStreamAction>): string;
export function serialize(actions: TurboStreamAction | ReadonlyArray<TurboStreamAction>): string;
export function serialize(actions: TurboStreamAction | ReadonlyArray<TurboStreamAction>): string {
return actions instanceof Array ? actions.map(serializeOne).join("\n") : serializeOne(actions);
return Array.isArray(actions) ? actions.map(serializeOne).join("\n") : serializeOne(actions);
}

function serializeOne(action: TurboStreamAction): string {
return action.action === "remove"
? action.target
? `<turbo-stream action="remove" target="${action.target}"></turbo-stream>`
: `<turbo-stream action="remove" targets="${action.targets}"></turbo-stream>`
: action.target
? `
switch (action.action) {
case "remove":
return action.target
? `<turbo-stream action="remove" target="${action.target}"></turbo-stream>`
: `<turbo-stream action="remove" targets="${action.targets}"></turbo-stream>`;

case "refresh":
return action.requestId
? `<turbo-stream action="refresh" request-id="${action.requestId}"></turbo-stream>`
: `<turbo-stream action="refresh"></turbo-stream>`;

case "append":
case "prepend":
case "replace":
case "update":
case "before":
case "after":
return action.target
? `
<turbo-stream action="${action.action}" target="${action.target}">
<template>
${action.content}
</template>
</turbo-stream>`.trim()
: `
: `
<turbo-stream action="${action.action}" targets="${action.targets}">
<template>
${action.content}
</template>
</turbo-stream>`.trim();
default:
return "";
}
}
23 changes: 22 additions & 1 deletion src/main/resources/lib/turbo-streams/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { sendByWebSocket, type SendByWebSocketTarget } from "./websockets";
import { serialize, type TurboStreamRemoveAction, type TurboStreamChangeAction, TurboStreamAction } from "./actions";
import {
serialize,
type TurboStreamRemoveAction,
type TurboStreamChangeAction,
TurboStreamAction,
TurboStreamRefreshAction,
} from "./actions";
import type { Request, Response } from "@item-enonic-types/global/controller";

/**
Expand Down Expand Up @@ -121,6 +127,19 @@ export function after(params: TurboStreamsParams): void {
);
}

/**
* Initiates a Page Refresh to render new content with morphing.
*/
export function refresh(params: TypeStreamsRefreshParams): void {
sendByWebSocket(
params,
serialize({
action: "refresh",
requestId: params.requestId,
}),
);
}

/**
* Checks the request header if the response can be of mime type "text/vnd.turbo-stream.html"
*/
Expand Down Expand Up @@ -155,5 +174,7 @@ export type TurboStreamsParams = Omit<TurboStreamChangeAction, "action"> & SendB
*/
export type TurboStreamsRemoveParams = Omit<TurboStreamRemoveAction, "action"> & SendByWebSocketTarget;

export type TypeStreamsRefreshParams = Omit<TurboStreamRefreshAction, "action"> & SendByWebSocketTarget;

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

0 comments on commit e821e88

Please sign in to comment.