Skip to content

Commit 830354d

Browse files
authored
Merge pull request #223 from takker99:pin-patch
feat(websocket): Enhance `patch` functionality to support pinning operations
2 parents bb5cafd + 39e5556 commit 830354d

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

websocket/patch.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { push, type PushError, type PushOptions } from "./push.ts";
55
import { suggestUnDupTitle } from "./suggestUnDupTitle.ts";
66
import type { Result } from "option-t/plain_result";
77
import type { Socket } from "socket.io-client";
8+
import { pinNumber } from "./pin.ts";
89

910
export 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
*/
3234
export 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

4051
export 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
);

websocket/pin.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ export interface PinOptions extends PushOptions {
2222
* based on the current timestamp to maintain a stable order.
2323
* Higher pin numbers appear first in the list.
2424
*
25+
* > [!NOTE]
26+
* > If you want to modify the page content while pinning it, {@linkcode patch} is more suitable.
27+
*
2528
* @param project - Project containing the target page
2629
* @param title - Title of the page to pin
2730
* @param options - Optional settings:
@@ -58,6 +61,9 @@ export interface UnPinOptions extends PushOptions {}
5861
*
5962
* This sets the page's pin number to `0`, which effectively unpins it.
6063
*
64+
* > [!NOTE]
65+
* > If you want to modify the page content while unpinning it, {@linkcode patch} is more suitable.
66+
*
6167
* @param project - Project containing the target page
6268
* @param title - Title of the page to unpin
6369
* @returns A {@linkcode Promise} that resolves to a {@linkcode Result} containing:

0 commit comments

Comments
 (0)