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..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,29 +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[] | undefined | Promise, + update: MakePatchFn, options?: PatchOptions, ): Promise> => push(