From bc214681f0de5a09823772e3e6a0ef70f971d86c Mon Sep 17 00:00:00 2001 From: takker99 <37929109+takker99@users.noreply.github.com> Date: Mon, 27 Jan 2025 09:58:27 +0900 Subject: [PATCH 1/2] feat(websocket): Allow to return `{ text: string; }` style lines from `update` --- websocket/makeChanges.ts | 7 +++++-- websocket/patch.ts | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/websocket/makeChanges.ts b/websocket/makeChanges.ts index 9a7e1fd..a738ca6 100644 --- a/websocket/makeChanges.ts +++ b/websocket/makeChanges.ts @@ -3,15 +3,18 @@ import type { Page } from "@cosense/types/rest"; import type { Change } from "./change.ts"; import { findMetadata, getHelpfeels } from "./findMetadata.ts"; import { isSameArray } from "./isSameArray.ts"; +import { isString } from "@core/unknownutil/is/string"; export function* makeChanges( before: Page, - after: string[], + after: (string | { text: string })[], userId: string, ): Generator { // Prevent newline characters from being included in the text // This ensures consistent line handling across different platforms - const after_ = after.flatMap((text) => text.split("\n")); + const after_ = after.flatMap((text) => + (isString(text) ? text : text.text).split("\n") + ); // First, yield changes in the main content // Content changes must be processed before metadata to maintain consistency diff --git a/websocket/patch.ts b/websocket/patch.ts index 88c0dd0..a66cb61 100644 --- a/websocket/patch.ts +++ b/websocket/patch.ts @@ -48,7 +48,10 @@ export const patch = ( update: ( lines: BaseLine[], metadata: PatchMetadata, - ) => string[] | undefined | Promise, + ) => + | (string | { text: string })[] + | undefined + | Promise<(string | { text: string })[] | undefined>, options?: PatchOptions, ): Promise> => push( From 71e36fdec19252f908cccc954bd78172f41fd49d Mon Sep 17 00:00:00 2001 From: takker99 <37929109+takker99@users.noreply.github.com> Date: Mon, 27 Jan 2025 10:06:13 +0900 Subject: [PATCH 2/2] refactor(websocket): Extract `MakePatchFn` type --- websocket/patch.ts | 52 +++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/websocket/patch.ts b/websocket/patch.ts index a66cb61..090dc06 100644 --- a/websocket/patch.ts +++ b/websocket/patch.ts @@ -6,8 +6,6 @@ import { suggestUnDupTitle } from "./suggestUnDupTitle.ts"; import type { Result } from "option-t/plain_result"; import type { Socket } from "socket.io-client"; -export type PatchOptions = PushOptions; - export interface PatchMetadata extends Page { /** Number of retry attempts for page modification * @@ -17,6 +15,30 @@ export interface PatchMetadata extends Page { attempts: number; } +/** + * Function used in {@linkcode patch} to generate a patch from the current page state + * + * This function is used to generate a patch from the current page state. + * It receives the current page lines and metadata and returns the new page content. + * The function can be synchronous or asynchronous. + * + * @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 + * - `[]`: Delete the page + * - `undefined`: Abort modification + */ +export type MakePatchFn = ( + lines: BaseLine[], + metadata: PatchMetadata, +) => + | (string | { text: string })[] + | undefined + | Promise<(string | { text: string })[] | undefined>; + +export type PatchOptions = PushOptions; + /** Modify an entire Scrapbox page by computing and sending only the differences * * This function handles the entire page modification process: @@ -26,32 +48,20 @@ export interface PatchMetadata extends Page { * 4. Handles errors (e.g., duplicate titles) * 5. Retries on conflicts * - * @param project - Project ID containing the target page - * @param title - Title of the page to modify - * @param update - Function to generate new content: - * - Input: Current page lines and metadata - * - Return values: - * - `string[]`: New page content - * - `undefined`: Abort modification - * - `[]`: Delete the page - * Can be async (returns `Promise`) - * @param options - Optional WebSocket configuration + * @param project Project ID containing the target page + * @param title Title of the page to modify + * @param update Function to generate new content + * @param options Optional WebSocket configuration * * Special cases: - * - If update returns undefined: Operation is cancelled - * - If update returns []: Page is deleted + * - If `update` returns `undefined`: Operation is cancelled + * - If `update` returns `[]`: Page is deleted * - On duplicate title: Automatically suggests non-conflicting title */ export const patch = ( project: string, title: string, - update: ( - lines: BaseLine[], - metadata: PatchMetadata, - ) => - | (string | { text: string })[] - | undefined - | Promise<(string | { text: string })[] | undefined>, + update: MakePatchFn, options?: PatchOptions, ): Promise> => push(