@@ -5,6 +5,7 @@ import { push, type PushError, type PushOptions } from "./push.ts";
55import { suggestUnDupTitle } from "./suggestUnDupTitle.ts" ;
66import type { Result } from "option-t/plain_result" ;
77import type { Socket } from "socket.io-client" ;
8+ import { pinNumber } from "./pin.ts" ;
89
910export interface PatchMetadata extends Page {
1011 /** Number of retry attempts for page modification
@@ -25,17 +26,27 @@ export interface PatchMetadata extends Page {
2526 * @param lines - Current page lines
2627 * @param metadata - Current page metadata
2728 * @returns one of the following or a {@linkcode Promise} resolving to one:
28- * - `(string | { text: string; })[]`: New page content
29+ * - `NewPageContent["lines"]`: New page lines
30+ * - `NewPageContent`: New page content with optional pinning operation
2931 * - `[]`: Delete the page
3032 * - `undefined`: Abort modification
3133 */
3234export type MakePatchFn = (
3335 lines : BaseLine [ ] ,
3436 metadata : PatchMetadata ,
3537) =>
36- | ( string | { text : string } ) [ ]
38+ | NewPageContent [ "lines" ]
39+ | NewPageContent
3740 | undefined
38- | Promise < ( string | { text : string } ) [ ] | undefined > ;
41+ | Promise < NewPageContent [ "lines" ] | NewPageContent | undefined > ;
42+
43+ export interface NewPageContent {
44+ /** New page lines */
45+ lines : ( string | { text : string } ) [ ] ;
46+
47+ /** Whether to pin the page */
48+ pin ?: boolean ;
49+ }
3950
4051export type PatchOptions = PushOptions ;
4152
@@ -48,6 +59,8 @@ export type PatchOptions = PushOptions;
4859 * 4. Handles errors (e.g., duplicate titles)
4960 * 5. Retries on conflicts
5061 *
62+ * This function also can pin/unpin pages by setting the `pin` property in the return of `update`.
63+ *
5164 * @param project Project ID containing the target page
5265 * @param title Title of the page to modify
5366 * @param update Function to generate new content
@@ -76,10 +89,23 @@ export const patch = (
7689 } ) as Change [ ] | [ DeletePageChange ] ;
7790 }
7891 const pending = update ( page . lines , { ...page , attempts } ) ;
79- const newLines = pending instanceof Promise ? await pending : pending ;
80- if ( newLines === undefined ) return [ ] ;
92+ const newContent = pending instanceof Promise ? await pending : pending ;
93+ if ( newContent === undefined ) return [ ] ;
94+ const [ newLines , pin ] = Array . isArray ( newContent )
95+ ? ( [ newContent , undefined ] as const )
96+ : ( [ newContent . lines , newContent . pin ] as const ) ;
97+
8198 if ( newLines . length === 0 ) return [ { deleted : true } ] ;
82- return [ ...makeChanges ( page , newLines , page . userId ) ] ;
99+
100+ const changes = page . lines === newLines
101+ ? [ ]
102+ : [ ...makeChanges ( page , newLines , page . userId ) ] ;
103+ if (
104+ pin !== undefined && ( ( pin && page . pin === 0 ) || ( ! pin && page . pin > 0 ) )
105+ ) {
106+ changes . push ( { pin : pin ? pinNumber ( ) : 0 } ) ;
107+ }
108+ return changes ;
83109 } ,
84110 options ,
85111 ) ;
0 commit comments