From 22d91dd483c03d433d82a04308e413bc1921c683 Mon Sep 17 00:00:00 2001 From: takker99 <37929109+takker99@users.noreply.github.com> Date: Thu, 23 Jan 2025 09:05:04 +0900 Subject: [PATCH] feat(websocket): Enable to run functions in `/websocket` on the server side and make the `/websocket` submodule `/browser/websocket` will be deprecated --- browser/mod.ts | 2 +- deno.jsonc | 104 +++++++++--------- rest/getCodeBlocks.ts | 2 +- .../__snapshots__/_codeBlock.test.ts.snap | 0 .../__snapshots__/findMetadata.test.ts.snap | 0 .../_codeBlock.test.ts | 0 .../websocket => websocket}/_codeBlock.ts | 2 +- .../websocket => websocket}/applyCommit.ts | 0 {browser/websocket => websocket}/change.ts | 0 .../websocket => websocket}/deletePage.ts | 0 .../diffToChanges.test.ts | 0 .../websocket => websocket}/diffToChanges.ts | 2 +- .../websocket => websocket}/emit-events.ts | 0 {browser/websocket => websocket}/emit.ts | 0 {browser/websocket => websocket}/error.ts | 0 .../findMetadata.test.ts | 0 .../websocket => websocket}/findMetadata.ts | 4 +- {browser/websocket => websocket}/id.ts | 0 .../isSameArray.test.ts | 0 .../websocket => websocket}/isSameArray.ts | 0 .../isSimpleCodeFile.test.ts | 0 .../isSimpleCodeFile.ts | 0 .../websocket => websocket}/listen-events.ts | 0 {browser/websocket => websocket}/listen.ts | 4 +- .../websocket => websocket}/makeChanges.ts | 0 {browser/websocket => websocket}/mod.ts | 0 {browser/websocket => websocket}/patch.ts | 0 {browser/websocket => websocket}/pin.ts | 0 {browser/websocket => websocket}/pull.ts | 12 +- {browser/websocket => websocket}/push.ts | 15 +-- {browser/websocket => websocket}/socket.ts | 14 ++- .../suggestUnDupTitle.test.ts | 0 .../suggestUnDupTitle.ts | 0 .../updateCodeBlock.ts | 2 +- .../websocket => websocket}/updateCodeFile.ts | 9 +- 35 files changed, 95 insertions(+), 77 deletions(-) rename {browser/websocket => websocket}/__snapshots__/_codeBlock.test.ts.snap (100%) rename {browser/websocket => websocket}/__snapshots__/findMetadata.test.ts.snap (100%) rename {browser/websocket => websocket}/_codeBlock.test.ts (100%) rename {browser/websocket => websocket}/_codeBlock.ts (97%) rename {browser/websocket => websocket}/applyCommit.ts (100%) rename {browser/websocket => websocket}/change.ts (100%) rename {browser/websocket => websocket}/deletePage.ts (100%) rename {browser/websocket => websocket}/diffToChanges.test.ts (100%) rename {browser/websocket => websocket}/diffToChanges.ts (94%) rename {browser/websocket => websocket}/emit-events.ts (100%) rename {browser/websocket => websocket}/emit.ts (100%) rename {browser/websocket => websocket}/error.ts (100%) rename {browser/websocket => websocket}/findMetadata.test.ts (100%) rename {browser/websocket => websocket}/findMetadata.ts (98%) rename {browser/websocket => websocket}/id.ts (100%) rename {browser/websocket => websocket}/isSameArray.test.ts (100%) rename {browser/websocket => websocket}/isSameArray.ts (100%) rename {browser/websocket => websocket}/isSimpleCodeFile.test.ts (100%) rename {browser/websocket => websocket}/isSimpleCodeFile.ts (100%) rename {browser/websocket => websocket}/listen-events.ts (100%) rename {browser/websocket => websocket}/listen.ts (93%) rename {browser/websocket => websocket}/makeChanges.ts (100%) rename {browser/websocket => websocket}/mod.ts (100%) rename {browser/websocket => websocket}/patch.ts (100%) rename {browser/websocket => websocket}/pin.ts (100%) rename {browser/websocket => websocket}/pull.ts (94%) rename {browser/websocket => websocket}/push.ts (94%) rename {browser/websocket => websocket}/socket.ts (83%) rename {browser/websocket => websocket}/suggestUnDupTitle.test.ts (100%) rename {browser/websocket => websocket}/suggestUnDupTitle.ts (100%) rename {browser/websocket => websocket}/updateCodeBlock.ts (99%) rename {browser/websocket => websocket}/updateCodeFile.ts (97%) diff --git a/browser/mod.ts b/browser/mod.ts index c06bf68..610860f 100644 --- a/browser/mod.ts +++ b/browser/mod.ts @@ -1,2 +1,2 @@ export * from "./dom/mod.ts"; -export * from "./websocket/mod.ts"; +export * from "../websocket/mod.ts"; diff --git a/deno.jsonc b/deno.jsonc index f456699..a3a183e 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,33 +1,32 @@ { - "name": "@cosense/std", - "version": "0.0.0", - "tasks": { - "fix": { - "command": "deno fmt && deno lint --fix && deno publish --dry-run --allow-dirty", - "dependencies": [ - "type-check", - "test" - ] - }, - "check": { - "command": "deno fmt --check && deno lint && deno publish --dry-run", - "dependencies": [ - "type-check", - "test" - ] - }, - "type-check": "deno check --remote **/*.ts", - "test": "deno test --allow-read=./ --doc --parallel --shuffle --no-check", - "coverage": "deno test --allow-read=./ --parallel --shuffle --coverage --no-check && deno coverage --html", - "doc": "deno doc --html mod.ts", - // from https://github.com/jsr-core/unknownutil/blob/v4.2.2/deno.jsonc#L84-L85 - "update": "deno outdated --update", - "update:commit": "deno task -q update --commit --prefix deps: --pre-commit=fix" + "compilerOptions": { + "lib": [ + "esnext", + "dom", + "dom.iterable", + "deno.ns" + ] + }, + "exclude": [ + "coverage/", + "docs/" + ], + "exports": { + ".": "./mod.ts", + "./browser": "./browser/mod.ts", + "./browser/dom": "./browser/dom/mod.ts", + "./browser/websocket": "./websocket/mod.ts", + "./parseAbsoluteLink": "./parseAbsoluteLink.ts", + "./rest": "./rest/mod.ts", + "./text": "./text.ts", + "./title": "./title.ts", + "./websocket": "./websocket/mod.ts" }, "imports": { - "@cosense/std/rest": "./rest/mod.ts", - "@cosense/std/browser/websocket": "./browser/websocket/mod.ts", "@core/unknownutil": "jsr:@core/unknownutil@^4.0.0", + "@cosense/std/browser/websocket": "./websocket/mod.ts", + "@cosense/std/rest": "./rest/mod.ts", + "@cosense/std/websocket": "./websocket/mod.ts", "@cosense/types": "jsr:@cosense/types@^0.10.4", "@cosense/types/rest": "jsr:@cosense/types@0.10/rest", "@cosense/types/userscript": "jsr:@cosense/types@0.10/userscript", @@ -42,38 +41,40 @@ "option-t": "npm:option-t@^51.0.0", "socket.io-client": "npm:socket.io-client@^4.7.5" }, - "exports": { - ".": "./mod.ts", - "./rest": "./rest/mod.ts", - "./browser": "./browser/mod.ts", - "./browser/dom": "./browser/dom/mod.ts", - "./browser/websocket": "./browser/websocket/mod.ts", - "./parseAbsoluteLink": "./parseAbsoluteLink.ts", - "./title": "./title.ts", - "./text": "./text.ts" - }, - "compilerOptions": { - "lib": [ - "esnext", - "dom", - "dom.iterable", - "deno.ns" - ] - }, - "exclude": [ - "coverage/", - "docs/" - ], "lint": { "exclude": [ "vendor/" ] }, + "name": "@cosense/std", + "tasks": { + "check": { + "command": "deno fmt --check && deno lint && deno publish --dry-run", + "dependencies": [ + "type-check", + "test" + ] + }, + "coverage": "deno test --allow-read=./ --parallel --shuffle --coverage --no-check && deno coverage --html", + "doc": "deno doc --html mod.ts", + "fix": { + "command": "deno fmt && deno lint --fix && deno publish --dry-run --allow-dirty", + "dependencies": [ + "type-check", + "test" + ] + }, + "test": "deno test --allow-read=./ --doc --parallel --shuffle --no-check", + "type-check": "deno check --remote **/*.ts", + // from https://github.com/jsr-core/unknownutil/blob/v4.2.2/deno.jsonc#L84-L85 + "update": "deno outdated --update", + "update:commit": "deno task -q update --commit --prefix deps: --pre-commit=fix" + }, "test": { "exclude": [ "README.md", - "./browser/websocket/listen.ts", - "./browser/websocket/updateCodeFile.ts", + "./websocket/listen.ts", + "./websocket/updateCodeFile.ts", "./rest/getCachedAt.ts", "./rest/getCodeBlocks.ts", "./rest/getGyazoToken.ts", @@ -81,5 +82,6 @@ "./rest/getWebPageTitle.ts", "./rest/link.ts" ] - } + }, + "version": "0.0.0" } diff --git a/rest/getCodeBlocks.ts b/rest/getCodeBlocks.ts index 55ccd78..89ec789 100644 --- a/rest/getCodeBlocks.ts +++ b/rest/getCodeBlocks.ts @@ -2,7 +2,7 @@ import type { BaseLine } from "@cosense/types/rest"; import { type CodeTitle, extractFromCodeTitle, -} from "../browser/websocket/_codeBlock.ts"; +} from "../websocket/_codeBlock.ts"; /** Minimal information about a code block that can be extracted from pull() response * diff --git a/browser/websocket/__snapshots__/_codeBlock.test.ts.snap b/websocket/__snapshots__/_codeBlock.test.ts.snap similarity index 100% rename from browser/websocket/__snapshots__/_codeBlock.test.ts.snap rename to websocket/__snapshots__/_codeBlock.test.ts.snap diff --git a/browser/websocket/__snapshots__/findMetadata.test.ts.snap b/websocket/__snapshots__/findMetadata.test.ts.snap similarity index 100% rename from browser/websocket/__snapshots__/findMetadata.test.ts.snap rename to websocket/__snapshots__/findMetadata.test.ts.snap diff --git a/browser/websocket/_codeBlock.test.ts b/websocket/_codeBlock.test.ts similarity index 100% rename from browser/websocket/_codeBlock.test.ts rename to websocket/_codeBlock.test.ts diff --git a/browser/websocket/_codeBlock.ts b/websocket/_codeBlock.ts similarity index 97% rename from browser/websocket/_codeBlock.ts rename to websocket/_codeBlock.ts index ea75aec..a1b3eb8 100644 --- a/browser/websocket/_codeBlock.ts +++ b/websocket/_codeBlock.ts @@ -1,4 +1,4 @@ -import type { TinyCodeBlock } from "../../rest/getCodeBlocks.ts"; +import type { TinyCodeBlock } from "../rest/getCodeBlocks.ts"; /** Interface for storing code block title line information * diff --git a/browser/websocket/applyCommit.ts b/websocket/applyCommit.ts similarity index 100% rename from browser/websocket/applyCommit.ts rename to websocket/applyCommit.ts diff --git a/browser/websocket/change.ts b/websocket/change.ts similarity index 100% rename from browser/websocket/change.ts rename to websocket/change.ts diff --git a/browser/websocket/deletePage.ts b/websocket/deletePage.ts similarity index 100% rename from browser/websocket/deletePage.ts rename to websocket/deletePage.ts diff --git a/browser/websocket/diffToChanges.test.ts b/websocket/diffToChanges.test.ts similarity index 100% rename from browser/websocket/diffToChanges.test.ts rename to websocket/diffToChanges.test.ts diff --git a/browser/websocket/diffToChanges.ts b/websocket/diffToChanges.ts similarity index 94% rename from browser/websocket/diffToChanges.ts rename to websocket/diffToChanges.ts index dffa82b..1a585d5 100644 --- a/browser/websocket/diffToChanges.ts +++ b/websocket/diffToChanges.ts @@ -1,4 +1,4 @@ -import { diff, toExtendedChanges } from "../../deps/onp.ts"; +import { diff, toExtendedChanges } from "../deps/onp.ts"; import type { Line } from "@cosense/types/userscript"; import type { DeleteChange, InsertChange, UpdateChange } from "./change.ts"; import { createNewLineId } from "./id.ts"; diff --git a/browser/websocket/emit-events.ts b/websocket/emit-events.ts similarity index 100% rename from browser/websocket/emit-events.ts rename to websocket/emit-events.ts diff --git a/browser/websocket/emit.ts b/websocket/emit.ts similarity index 100% rename from browser/websocket/emit.ts rename to websocket/emit.ts diff --git a/browser/websocket/error.ts b/websocket/error.ts similarity index 100% rename from browser/websocket/error.ts rename to websocket/error.ts diff --git a/browser/websocket/findMetadata.test.ts b/websocket/findMetadata.test.ts similarity index 100% rename from browser/websocket/findMetadata.test.ts rename to websocket/findMetadata.test.ts diff --git a/browser/websocket/findMetadata.ts b/websocket/findMetadata.ts similarity index 98% rename from browser/websocket/findMetadata.ts rename to websocket/findMetadata.ts index 21ca1b7..d5cb57a 100644 --- a/browser/websocket/findMetadata.ts +++ b/websocket/findMetadata.ts @@ -1,7 +1,7 @@ import { type Node, parse } from "@progfay/scrapbox-parser"; import type { BaseLine } from "@cosense/types/userscript"; -import { toTitleLc } from "../../title.ts"; -import { parseYoutube } from "../../parser/youtube.ts"; +import { toTitleLc } from "../title.ts"; +import { parseYoutube } from "../parser/youtube.ts"; /** Extract metadata from Scrapbox page text * diff --git a/browser/websocket/id.ts b/websocket/id.ts similarity index 100% rename from browser/websocket/id.ts rename to websocket/id.ts diff --git a/browser/websocket/isSameArray.test.ts b/websocket/isSameArray.test.ts similarity index 100% rename from browser/websocket/isSameArray.test.ts rename to websocket/isSameArray.test.ts diff --git a/browser/websocket/isSameArray.ts b/websocket/isSameArray.ts similarity index 100% rename from browser/websocket/isSameArray.ts rename to websocket/isSameArray.ts diff --git a/browser/websocket/isSimpleCodeFile.test.ts b/websocket/isSimpleCodeFile.test.ts similarity index 100% rename from browser/websocket/isSimpleCodeFile.test.ts rename to websocket/isSimpleCodeFile.test.ts diff --git a/browser/websocket/isSimpleCodeFile.ts b/websocket/isSimpleCodeFile.ts similarity index 100% rename from browser/websocket/isSimpleCodeFile.ts rename to websocket/isSimpleCodeFile.ts diff --git a/browser/websocket/listen-events.ts b/websocket/listen-events.ts similarity index 100% rename from browser/websocket/listen-events.ts rename to websocket/listen-events.ts diff --git a/browser/websocket/listen.ts b/websocket/listen.ts similarity index 93% rename from browser/websocket/listen.ts rename to websocket/listen.ts index 583f0d2..5e3f37d 100644 --- a/browser/websocket/listen.ts +++ b/websocket/listen.ts @@ -3,8 +3,8 @@ import type { NotLoggedInError, NotMemberError, } from "@cosense/types/rest"; -import type { HTTPError } from "../../rest/responseIntoResult.ts"; -import type { AbortError, NetworkError } from "../../rest/robustFetch.ts"; +import type { HTTPError } from "../rest/responseIntoResult.ts"; +import type { AbortError, NetworkError } from "../rest/robustFetch.ts"; import type { ScrapboxSocket } from "./socket.ts"; import type { ListenEvents } from "./listen-events.ts"; diff --git a/browser/websocket/makeChanges.ts b/websocket/makeChanges.ts similarity index 100% rename from browser/websocket/makeChanges.ts rename to websocket/makeChanges.ts diff --git a/browser/websocket/mod.ts b/websocket/mod.ts similarity index 100% rename from browser/websocket/mod.ts rename to websocket/mod.ts diff --git a/browser/websocket/patch.ts b/websocket/patch.ts similarity index 100% rename from browser/websocket/patch.ts rename to websocket/patch.ts diff --git a/browser/websocket/pin.ts b/websocket/pin.ts similarity index 100% rename from browser/websocket/pin.ts rename to websocket/pin.ts diff --git a/browser/websocket/pull.ts b/websocket/pull.ts similarity index 94% rename from browser/websocket/pull.ts rename to websocket/pull.ts index 44497c0..fb77a40 100644 --- a/browser/websocket/pull.ts +++ b/websocket/pull.ts @@ -16,12 +16,12 @@ import { getPage, type GetPageOption, type TooLongURIError, -} from "../../rest/pages.ts"; -import { getProfile } from "../../rest/profile.ts"; -import { getProject } from "../../rest/project.ts"; -import type { HTTPError } from "../../rest/responseIntoResult.ts"; -import type { AbortError, NetworkError } from "../../rest/robustFetch.ts"; -import type { BaseOptions } from "../../rest/options.ts"; +} from "../rest/pages.ts"; +import { getProfile } from "../rest/profile.ts"; +import { getProject } from "../rest/project.ts"; +import type { HTTPError } from "../rest/responseIntoResult.ts"; +import type { AbortError, NetworkError } from "../rest/robustFetch.ts"; +import type { BaseOptions } from "../rest/options.ts"; /** Extended page metadata required for WebSocket operations * diff --git a/browser/websocket/push.ts b/websocket/push.ts similarity index 94% rename from browser/websocket/push.ts rename to websocket/push.ts index ab32561..5aa68de 100644 --- a/browser/websocket/push.ts +++ b/websocket/push.ts @@ -21,16 +21,17 @@ import { unwrapErr, unwrapOk, } from "option-t/plain_result"; -import type { HTTPError } from "../../rest/responseIntoResult.ts"; -import type { AbortError, NetworkError } from "../../rest/robustFetch.ts"; -import type { TooLongURIError } from "../../rest/pages.ts"; +import type { HTTPError } from "../rest/responseIntoResult.ts"; +import type { AbortError, NetworkError } from "../rest/robustFetch.ts"; +import type { TooLongURIError } from "../rest/pages.ts"; import type { SocketIOServerDisconnectError, UnexpectedRequestError, } from "./error.ts"; +import type { BaseOptions } from "../rest/options.ts"; /** Configuration options for the push operation */ -export interface PushOptions { +export interface PushOptions extends BaseOptions { /** Optional Socket instance for external WebSocket connection control * * This allows providing an existing Socket instance instead of creating @@ -159,7 +160,7 @@ export const push = async ( makeCommit: CommitMakeHandler, options?: PushOptions, ): Promise> => { - const result = await connect(options?.socket); + const result = await connect(options?.socket, options?.sid); if (isErr(result)) { return createErr({ name: "UnexpectedRequestError", @@ -167,7 +168,7 @@ export const push = async ( }); } const socket = unwrapOk(result); - const pullResult = await pull(project, title); + const pullResult = await pull(project, title, options); if (isErr(pullResult)) return pullResult; let metadata = unwrapOk(pullResult); @@ -239,7 +240,7 @@ export const push = async ( if (name === "NotFastForwardError") { await delay(1000); // Brief delay to avoid rapid retries // Fetch latest page state - const pullResult = await pull(project, title); + const pullResult = await pull(project, title, options); if (isErr(pullResult)) return pullResult; metadata = unwrapOk(pullResult); } diff --git a/browser/websocket/socket.ts b/websocket/socket.ts similarity index 83% rename from browser/websocket/socket.ts rename to websocket/socket.ts index 34cbfff..aaa46d9 100644 --- a/browser/websocket/socket.ts +++ b/websocket/socket.ts @@ -2,6 +2,7 @@ import { io, type Socket } from "socket.io-client"; import { createErr, createOk, type Result } from "option-t/plain_result"; import type { ListenEvents } from "./listen-events.ts"; import type { EmitEvents } from "./emit-events.ts"; +import { cookie } from "../rest/auth.ts"; /** A pre-configured {@linkcode Socket} type for Scrapbox */ export type ScrapboxSocket = Socket; @@ -9,15 +10,26 @@ export type ScrapboxSocket = Socket; /** connect to websocket * * @param socket - The {@linkcode Socket} to be connected. If not provided, a new socket will be created + * @param sid - Scrapbox session ID (connect.sid). This is only required in Deno/Node.js environment. * @returns A {@linkcode Promise}<{@linkcode Socket}> that resolves to a {@linkcode Socket} if connected successfully, or an {@linkcode Error} if failed */ -export const connect = (socket?: ScrapboxSocket): Promise< +export const connect = (socket?: ScrapboxSocket, sid?: string): Promise< Result > => { if (socket?.connected) return Promise.resolve(createOk(socket)); socket ??= io("https://scrapbox.io", { reconnectionDelay: 5000, transports: ["websocket"], + ...(sid + ? { + rejectUnauthorized: false, + extraHeaders: { + Cookie: cookie(sid), + Host: "scrapbox.io", + Referer: "https://scrapbox.io/", + }, + } + : {}), }); const promise = new Promise< diff --git a/browser/websocket/suggestUnDupTitle.test.ts b/websocket/suggestUnDupTitle.test.ts similarity index 100% rename from browser/websocket/suggestUnDupTitle.test.ts rename to websocket/suggestUnDupTitle.test.ts diff --git a/browser/websocket/suggestUnDupTitle.ts b/websocket/suggestUnDupTitle.ts similarity index 100% rename from browser/websocket/suggestUnDupTitle.ts rename to websocket/suggestUnDupTitle.ts diff --git a/browser/websocket/updateCodeBlock.ts b/websocket/updateCodeBlock.ts similarity index 99% rename from browser/websocket/updateCodeBlock.ts rename to websocket/updateCodeBlock.ts index 2489f7d..22db25b 100644 --- a/browser/websocket/updateCodeBlock.ts +++ b/websocket/updateCodeBlock.ts @@ -1,6 +1,6 @@ import type { BaseLine } from "@cosense/types/rest"; import type { DeleteChange, InsertChange, UpdateChange } from "./change.ts"; -import type { TinyCodeBlock } from "../../rest/getCodeBlocks.ts"; +import type { TinyCodeBlock } from "../rest/getCodeBlocks.ts"; import { diffToChanges } from "./diffToChanges.ts"; import { isSimpleCodeFile } from "./isSimpleCodeFile.ts"; import type { SimpleCodeFile } from "./updateCodeFile.ts"; diff --git a/browser/websocket/updateCodeFile.ts b/websocket/updateCodeFile.ts similarity index 97% rename from browser/websocket/updateCodeFile.ts rename to websocket/updateCodeFile.ts index 384bf91..851f89b 100644 --- a/browser/websocket/updateCodeFile.ts +++ b/websocket/updateCodeFile.ts @@ -1,8 +1,8 @@ import type { BaseLine } from "@cosense/types/rest"; import type { DeleteChange, InsertChange, UpdateChange } from "./change.ts"; -import { getCodeBlocks, type TinyCodeBlock } from "../../rest/getCodeBlocks.ts"; +import { getCodeBlocks, type TinyCodeBlock } from "../rest/getCodeBlocks.ts"; import { createNewLineId } from "./id.ts"; -import { diff, toExtendedChanges } from "../../deps/onp.ts"; +import { diff, toExtendedChanges } from "../deps/onp.ts"; import { countBodyIndent } from "./_codeBlock.ts"; import { push, type PushError, type PushOptions } from "./push.ts"; import type { Result } from "option-t/plain_result"; @@ -127,7 +127,10 @@ export const updateCodeFile = ( ): Promise> => { /** Set default values for options here */ const defaultOptions: Required< - Omit + Pick< + UpdateCodeFileOptions, + "insertPositionIfNotExist" | "isInsertEmptyLineInTail" | "debug" + > > = { insertPositionIfNotExist: "notInsert", isInsertEmptyLineInTail: true,