Skip to content

Commit c939089

Browse files
authored
Merge pull request #217 from takker99:server-side-websocket
feat(websocket): Enable to run functions in `/websocket` on the server side and make the `/websocket` submodule
2 parents c6561a0 + 22d91dd commit c939089

35 files changed

+95
-77
lines changed

browser/mod.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export * from "./dom/mod.ts";
2-
export * from "./websocket/mod.ts";
2+
export * from "../websocket/mod.ts";

deno.jsonc

+53-51
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,32 @@
11
{
2-
"name": "@cosense/std",
3-
"version": "0.0.0",
4-
"tasks": {
5-
"fix": {
6-
"command": "deno fmt && deno lint --fix && deno publish --dry-run --allow-dirty",
7-
"dependencies": [
8-
"type-check",
9-
"test"
10-
]
11-
},
12-
"check": {
13-
"command": "deno fmt --check && deno lint && deno publish --dry-run",
14-
"dependencies": [
15-
"type-check",
16-
"test"
17-
]
18-
},
19-
"type-check": "deno check --remote **/*.ts",
20-
"test": "deno test --allow-read=./ --doc --parallel --shuffle --no-check",
21-
"coverage": "deno test --allow-read=./ --parallel --shuffle --coverage --no-check && deno coverage --html",
22-
"doc": "deno doc --html mod.ts",
23-
// from https://github.com/jsr-core/unknownutil/blob/v4.2.2/deno.jsonc#L84-L85
24-
"update": "deno outdated --update",
25-
"update:commit": "deno task -q update --commit --prefix deps: --pre-commit=fix"
2+
"compilerOptions": {
3+
"lib": [
4+
"esnext",
5+
"dom",
6+
"dom.iterable",
7+
"deno.ns"
8+
]
9+
},
10+
"exclude": [
11+
"coverage/",
12+
"docs/"
13+
],
14+
"exports": {
15+
".": "./mod.ts",
16+
"./browser": "./browser/mod.ts",
17+
"./browser/dom": "./browser/dom/mod.ts",
18+
"./browser/websocket": "./websocket/mod.ts",
19+
"./parseAbsoluteLink": "./parseAbsoluteLink.ts",
20+
"./rest": "./rest/mod.ts",
21+
"./text": "./text.ts",
22+
"./title": "./title.ts",
23+
"./websocket": "./websocket/mod.ts"
2624
},
2725
"imports": {
28-
"@cosense/std/rest": "./rest/mod.ts",
29-
"@cosense/std/browser/websocket": "./browser/websocket/mod.ts",
3026
"@core/unknownutil": "jsr:@core/unknownutil@^4.0.0",
27+
"@cosense/std/browser/websocket": "./websocket/mod.ts",
28+
"@cosense/std/rest": "./rest/mod.ts",
29+
"@cosense/std/websocket": "./websocket/mod.ts",
3130
"@cosense/types": "jsr:@cosense/types@^0.10.4",
3231
"@cosense/types/rest": "jsr:@cosense/types@0.10/rest",
3332
"@cosense/types/userscript": "jsr:@cosense/types@0.10/userscript",
@@ -42,44 +41,47 @@
4241
"option-t": "npm:option-t@^51.0.0",
4342
"socket.io-client": "npm:socket.io-client@^4.7.5"
4443
},
45-
"exports": {
46-
".": "./mod.ts",
47-
"./rest": "./rest/mod.ts",
48-
"./browser": "./browser/mod.ts",
49-
"./browser/dom": "./browser/dom/mod.ts",
50-
"./browser/websocket": "./browser/websocket/mod.ts",
51-
"./parseAbsoluteLink": "./parseAbsoluteLink.ts",
52-
"./title": "./title.ts",
53-
"./text": "./text.ts"
54-
},
55-
"compilerOptions": {
56-
"lib": [
57-
"esnext",
58-
"dom",
59-
"dom.iterable",
60-
"deno.ns"
61-
]
62-
},
63-
"exclude": [
64-
"coverage/",
65-
"docs/"
66-
],
6744
"lint": {
6845
"exclude": [
6946
"vendor/"
7047
]
7148
},
49+
"name": "@cosense/std",
50+
"tasks": {
51+
"check": {
52+
"command": "deno fmt --check && deno lint && deno publish --dry-run",
53+
"dependencies": [
54+
"type-check",
55+
"test"
56+
]
57+
},
58+
"coverage": "deno test --allow-read=./ --parallel --shuffle --coverage --no-check && deno coverage --html",
59+
"doc": "deno doc --html mod.ts",
60+
"fix": {
61+
"command": "deno fmt && deno lint --fix && deno publish --dry-run --allow-dirty",
62+
"dependencies": [
63+
"type-check",
64+
"test"
65+
]
66+
},
67+
"test": "deno test --allow-read=./ --doc --parallel --shuffle --no-check",
68+
"type-check": "deno check --remote **/*.ts",
69+
// from https://github.com/jsr-core/unknownutil/blob/v4.2.2/deno.jsonc#L84-L85
70+
"update": "deno outdated --update",
71+
"update:commit": "deno task -q update --commit --prefix deps: --pre-commit=fix"
72+
},
7273
"test": {
7374
"exclude": [
7475
"README.md",
75-
"./browser/websocket/listen.ts",
76-
"./browser/websocket/updateCodeFile.ts",
76+
"./websocket/listen.ts",
77+
"./websocket/updateCodeFile.ts",
7778
"./rest/getCachedAt.ts",
7879
"./rest/getCodeBlocks.ts",
7980
"./rest/getGyazoToken.ts",
8081
"./rest/getTweetInfo.ts",
8182
"./rest/getWebPageTitle.ts",
8283
"./rest/link.ts"
8384
]
84-
}
85+
},
86+
"version": "0.0.0"
8587
}

rest/getCodeBlocks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { BaseLine } from "@cosense/types/rest";
22
import {
33
type CodeTitle,
44
extractFromCodeTitle,
5-
} from "../browser/websocket/_codeBlock.ts";
5+
} from "../websocket/_codeBlock.ts";
66

77
/** Minimal information about a code block that can be extracted from pull() response
88
*
File renamed without changes.

browser/websocket/_codeBlock.ts renamed to websocket/_codeBlock.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { TinyCodeBlock } from "../../rest/getCodeBlocks.ts";
1+
import type { TinyCodeBlock } from "../rest/getCodeBlocks.ts";
22

33
/** Interface for storing code block title line information
44
*
File renamed without changes.
File renamed without changes.
File renamed without changes.

browser/websocket/diffToChanges.ts renamed to websocket/diffToChanges.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { diff, toExtendedChanges } from "../../deps/onp.ts";
1+
import { diff, toExtendedChanges } from "../deps/onp.ts";
22
import type { Line } from "@cosense/types/userscript";
33
import type { DeleteChange, InsertChange, UpdateChange } from "./change.ts";
44
import { createNewLineId } from "./id.ts";
File renamed without changes.
File renamed without changes.
File renamed without changes.

browser/websocket/findMetadata.ts renamed to websocket/findMetadata.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { type Node, parse } from "@progfay/scrapbox-parser";
22
import type { BaseLine } from "@cosense/types/userscript";
3-
import { toTitleLc } from "../../title.ts";
4-
import { parseYoutube } from "../../parser/youtube.ts";
3+
import { toTitleLc } from "../title.ts";
4+
import { parseYoutube } from "../parser/youtube.ts";
55

66
/** Extract metadata from Scrapbox page text
77
*
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

browser/websocket/listen.ts renamed to websocket/listen.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import type {
33
NotLoggedInError,
44
NotMemberError,
55
} from "@cosense/types/rest";
6-
import type { HTTPError } from "../../rest/responseIntoResult.ts";
7-
import type { AbortError, NetworkError } from "../../rest/robustFetch.ts";
6+
import type { HTTPError } from "../rest/responseIntoResult.ts";
7+
import type { AbortError, NetworkError } from "../rest/robustFetch.ts";
88
import type { ScrapboxSocket } from "./socket.ts";
99
import type { ListenEvents } from "./listen-events.ts";
1010

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

browser/websocket/pull.ts renamed to websocket/pull.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ import {
1616
getPage,
1717
type GetPageOption,
1818
type TooLongURIError,
19-
} from "../../rest/pages.ts";
20-
import { getProfile } from "../../rest/profile.ts";
21-
import { getProject } from "../../rest/project.ts";
22-
import type { HTTPError } from "../../rest/responseIntoResult.ts";
23-
import type { AbortError, NetworkError } from "../../rest/robustFetch.ts";
24-
import type { BaseOptions } from "../../rest/options.ts";
19+
} from "../rest/pages.ts";
20+
import { getProfile } from "../rest/profile.ts";
21+
import { getProject } from "../rest/project.ts";
22+
import type { HTTPError } from "../rest/responseIntoResult.ts";
23+
import type { AbortError, NetworkError } from "../rest/robustFetch.ts";
24+
import type { BaseOptions } from "../rest/options.ts";
2525

2626
/** Extended page metadata required for WebSocket operations
2727
*

browser/websocket/push.ts renamed to websocket/push.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ import {
2121
unwrapErr,
2222
unwrapOk,
2323
} from "option-t/plain_result";
24-
import type { HTTPError } from "../../rest/responseIntoResult.ts";
25-
import type { AbortError, NetworkError } from "../../rest/robustFetch.ts";
26-
import type { TooLongURIError } from "../../rest/pages.ts";
24+
import type { HTTPError } from "../rest/responseIntoResult.ts";
25+
import type { AbortError, NetworkError } from "../rest/robustFetch.ts";
26+
import type { TooLongURIError } from "../rest/pages.ts";
2727
import type {
2828
SocketIOServerDisconnectError,
2929
UnexpectedRequestError,
3030
} from "./error.ts";
31+
import type { BaseOptions } from "../rest/options.ts";
3132

3233
/** Configuration options for the push operation */
33-
export interface PushOptions {
34+
export interface PushOptions extends BaseOptions {
3435
/** Optional Socket instance for external WebSocket connection control
3536
*
3637
* This allows providing an existing Socket instance instead of creating
@@ -159,15 +160,15 @@ export const push = async (
159160
makeCommit: CommitMakeHandler,
160161
options?: PushOptions,
161162
): Promise<Result<string, PushError>> => {
162-
const result = await connect(options?.socket);
163+
const result = await connect(options?.socket, options?.sid);
163164
if (isErr(result)) {
164165
return createErr({
165166
name: "UnexpectedRequestError",
166167
error: unwrapErr(result),
167168
});
168169
}
169170
const socket = unwrapOk(result);
170-
const pullResult = await pull(project, title);
171+
const pullResult = await pull(project, title, options);
171172
if (isErr(pullResult)) return pullResult;
172173
let metadata = unwrapOk(pullResult);
173174

@@ -239,7 +240,7 @@ export const push = async (
239240
if (name === "NotFastForwardError") {
240241
await delay(1000); // Brief delay to avoid rapid retries
241242
// Fetch latest page state
242-
const pullResult = await pull(project, title);
243+
const pullResult = await pull(project, title, options);
243244
if (isErr(pullResult)) return pullResult;
244245
metadata = unwrapOk(pullResult);
245246
}

browser/websocket/socket.ts renamed to websocket/socket.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,34 @@ import { io, type Socket } from "socket.io-client";
22
import { createErr, createOk, type Result } from "option-t/plain_result";
33
import type { ListenEvents } from "./listen-events.ts";
44
import type { EmitEvents } from "./emit-events.ts";
5+
import { cookie } from "../rest/auth.ts";
56

67
/** A pre-configured {@linkcode Socket} type for Scrapbox */
78
export type ScrapboxSocket = Socket<ListenEvents, EmitEvents>;
89

910
/** connect to websocket
1011
*
1112
* @param socket - The {@linkcode Socket} to be connected. If not provided, a new socket will be created
13+
* @param sid - Scrapbox session ID (connect.sid). This is only required in Deno/Node.js environment.
1214
* @returns A {@linkcode Promise}<{@linkcode Socket}> that resolves to a {@linkcode Socket} if connected successfully, or an {@linkcode Error} if failed
1315
*/
14-
export const connect = (socket?: ScrapboxSocket): Promise<
16+
export const connect = (socket?: ScrapboxSocket, sid?: string): Promise<
1517
Result<ScrapboxSocket, Socket.DisconnectReason>
1618
> => {
1719
if (socket?.connected) return Promise.resolve(createOk(socket));
1820
socket ??= io("https://scrapbox.io", {
1921
reconnectionDelay: 5000,
2022
transports: ["websocket"],
23+
...(sid
24+
? {
25+
rejectUnauthorized: false,
26+
extraHeaders: {
27+
Cookie: cookie(sid),
28+
Host: "scrapbox.io",
29+
Referer: "https://scrapbox.io/",
30+
},
31+
}
32+
: {}),
2133
});
2234

2335
const promise = new Promise<

browser/websocket/updateCodeBlock.ts renamed to websocket/updateCodeBlock.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { BaseLine } from "@cosense/types/rest";
22
import type { DeleteChange, InsertChange, UpdateChange } from "./change.ts";
3-
import type { TinyCodeBlock } from "../../rest/getCodeBlocks.ts";
3+
import type { TinyCodeBlock } from "../rest/getCodeBlocks.ts";
44
import { diffToChanges } from "./diffToChanges.ts";
55
import { isSimpleCodeFile } from "./isSimpleCodeFile.ts";
66
import type { SimpleCodeFile } from "./updateCodeFile.ts";

browser/websocket/updateCodeFile.ts renamed to websocket/updateCodeFile.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { BaseLine } from "@cosense/types/rest";
22
import type { DeleteChange, InsertChange, UpdateChange } from "./change.ts";
3-
import { getCodeBlocks, type TinyCodeBlock } from "../../rest/getCodeBlocks.ts";
3+
import { getCodeBlocks, type TinyCodeBlock } from "../rest/getCodeBlocks.ts";
44
import { createNewLineId } from "./id.ts";
5-
import { diff, toExtendedChanges } from "../../deps/onp.ts";
5+
import { diff, toExtendedChanges } from "../deps/onp.ts";
66
import { countBodyIndent } from "./_codeBlock.ts";
77
import { push, type PushError, type PushOptions } from "./push.ts";
88
import type { Result } from "option-t/plain_result";
@@ -127,7 +127,10 @@ export const updateCodeFile = (
127127
): Promise<Result<string, PushError>> => {
128128
/** Set default values for options here */
129129
const defaultOptions: Required<
130-
Omit<UpdateCodeFileOptions, "maxAttempts" | "socket">
130+
Pick<
131+
UpdateCodeFileOptions,
132+
"insertPositionIfNotExist" | "isInsertEmptyLineInTail" | "debug"
133+
>
131134
> = {
132135
insertPositionIfNotExist: "notInsert",
133136
isInsertEmptyLineInTail: true,

0 commit comments

Comments
 (0)