Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(websocket): Enhance patch functionality to support pinning operations #223

Merged
merged 1 commit into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions websocket/patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { push, type PushError, type PushOptions } from "./push.ts";
import { suggestUnDupTitle } from "./suggestUnDupTitle.ts";
import type { Result } from "option-t/plain_result";
import type { Socket } from "socket.io-client";
import { pinNumber } from "./pin.ts";

export interface PatchMetadata extends Page {
/** Number of retry attempts for page modification
Expand All @@ -25,17 +26,27 @@ export interface PatchMetadata extends Page {
* @param lines - Current page lines
* @param metadata - Current page metadata
* @returns one of the following or a {@linkcode Promise} resolving to one:
* - `(string | { text: string; })[]`: New page content
* - `NewPageContent["lines"]`: New page lines
* - `NewPageContent`: New page content with optional pinning operation
* - `[]`: Delete the page
* - `undefined`: Abort modification
*/
export type MakePatchFn = (
lines: BaseLine[],
metadata: PatchMetadata,
) =>
| (string | { text: string })[]
| NewPageContent["lines"]
| NewPageContent
| undefined
| Promise<(string | { text: string })[] | undefined>;
| Promise<NewPageContent["lines"] | NewPageContent | undefined>;

export interface NewPageContent {
/** New page lines */
lines: (string | { text: string })[];

/** Whether to pin the page */
pin?: boolean;
}

export type PatchOptions = PushOptions;

Expand All @@ -48,6 +59,8 @@ export type PatchOptions = PushOptions;
* 4. Handles errors (e.g., duplicate titles)
* 5. Retries on conflicts
*
* This function also can pin/unpin pages by setting the `pin` property in the return of `update`.
*
* @param project Project ID containing the target page
* @param title Title of the page to modify
* @param update Function to generate new content
Expand Down Expand Up @@ -76,10 +89,23 @@ export const patch = (
}) as Change[] | [DeletePageChange];
}
const pending = update(page.lines, { ...page, attempts });
const newLines = pending instanceof Promise ? await pending : pending;
if (newLines === undefined) return [];
const newContent = pending instanceof Promise ? await pending : pending;
if (newContent === undefined) return [];
const [newLines, pin] = Array.isArray(newContent)
? ([newContent, undefined] as const)
: ([newContent.lines, newContent.pin] as const);

if (newLines.length === 0) return [{ deleted: true }];
return [...makeChanges(page, newLines, page.userId)];

const changes = page.lines === newLines
? []
: [...makeChanges(page, newLines, page.userId)];
if (
pin !== undefined && ((pin && page.pin === 0) || (!pin && page.pin > 0))
) {
changes.push({ pin: pin ? pinNumber() : 0 });
}
return changes;
},
options,
);
6 changes: 6 additions & 0 deletions websocket/pin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export interface PinOptions extends PushOptions {
* based on the current timestamp to maintain a stable order.
* Higher pin numbers appear first in the list.
*
* > [!NOTE]
* > If you want to modify the page content while pinning it, {@linkcode patch} is more suitable.
*
* @param project - Project containing the target page
* @param title - Title of the page to pin
* @param options - Optional settings:
Expand Down Expand Up @@ -58,6 +61,9 @@ export interface UnPinOptions extends PushOptions {}
*
* This sets the page's pin number to `0`, which effectively unpins it.
*
* > [!NOTE]
* > If you want to modify the page content while unpinning it, {@linkcode patch} is more suitable.
*
* @param project - Project containing the target page
* @param title - Title of the page to unpin
* @returns A {@linkcode Promise} that resolves to a {@linkcode Result} containing:
Expand Down
Loading