Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f127603
initial implementation of WebSocket client with error handling and bu…
Gorniaky Jun 24, 2025
b2ba755
refactor: rename event handlers for clarity and update event types
Gorniaky Jun 24, 2025
f7399d2
feat: add unauthorized event handling and corresponding constant
Gorniaky Jun 24, 2025
aa36d8b
fix: reorder close event definition in SocketEventsMap for consistency
Gorniaky Jun 24, 2025
27c83c5
feat: add configurable chunk size to SocketClient and BufferOverflowE…
Gorniaky Jun 24, 2025
e9640d8
fix: update documentation for chunkSize to clarify potential issues w…
Gorniaky Jun 24, 2025
840323a
fix: update default chunk size to 256KB in constants and types
Gorniaky Jun 24, 2025
59f7321
fix: ensure close event is emitted correctly in SocketClient and clar…
Gorniaky Jun 24, 2025
b556326
fix: ensure chunkSize is validated as a number and improve connection…
Gorniaky Jun 24, 2025
c207ba1
fix: update default chunk size in documentation to 256KB for clarity
Gorniaky Jun 24, 2025
7ee8c15
fix: update sendJSON method to use ProgressData type and enhance type…
Gorniaky Jun 24, 2025
78da649
fix: add offset to ProgressData and update chunk processing in sendBu…
Gorniaky Jun 24, 2025
c0ec27d
Merge branch 'main' into feat/create-websocket-package
Gorniaky Jun 24, 2025
218ad57
feat: add custom error classes for network issues and unauthorized ac…
Gorniaky Jun 25, 2025
c96a62e
fix: rename variable for clarity in sendBuffer method
Gorniaky Jun 25, 2025
c400e50
feat: add SOCKET_ABNORMAL_CLOSURE constant and handle abnormal closur…
Gorniaky Jun 25, 2025
b845176
fix: improve connection state handling on abnormal closure
Gorniaky Jun 25, 2025
4dc94b9
feat: add README file with documentation link for ws package
Gorniaky Jun 25, 2025
56e0f7a
feat: export version constant in index file
Gorniaky Jun 25, 2025
59848d9
fix: add missing dependency for @discloudapp/api-types in package.json
Gorniaky Jun 25, 2025
877976e
feat: introduce SocketEvents enum and refactor SocketClient to use it
Gorniaky Jun 25, 2025
a7c1d52
chore: update ws package to version 8.18.2 in yarn.lock
Gorniaky Jun 25, 2025
16e0c7f
Bump deps
Gorniaky Jun 28, 2025
e7738f4
fix: correct function name in documentation and implementation for bu…
Gorniaky Jun 28, 2025
a68df88
Merge branch 'main' into feat/create-websocket-package
Gorniaky Jun 28, 2025
3e34d83
fix: resolve headers in WebSocket connection options
Gorniaky Jun 28, 2025
a38b8bd
Merge branch 'main' into feat/create-websocket-package
Gorniaky Jun 28, 2025
1efff8f
refactor: remove disposeOnClose option from SocketOptions and update …
Gorniaky Jun 28, 2025
1907504
feat: implement uploadAction and integrate with SocketClient for file…
Gorniaky Jun 30, 2025
83e08b5
Merge branch 'main' into feat/create-websocket-package
Gorniaky Sep 28, 2025
23edb36
finalize upload action
Gorniaky Sep 28, 2025
e397eb3
feat: add user and team commit by socket
Gorniaky Sep 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/ws/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__test__/
out/**
src/**
1 change: 1 addition & 0 deletions packages/ws/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# [View the documentation here.](https://discloud.github.io/discloud.app/modules/_discloudapp_ws.html)
35 changes: 35 additions & 0 deletions packages/ws/esbuild.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { context } from "esbuild";
import { esbuildDefaultPlugins } from "../../esbuild.mjs";

async function main() {
const production = process.argv.includes("--production");
const watch = process.argv.includes("--watch");

const ctx = await context({
entryPoints: ["src/index.ts"],
bundle: true,
format: "cjs",
minify: production,
sourcemap: "inline",
sourcesContent: false,
platform: "node",
outdir: "dist",
logLevel: "warning",
packages: "external",
plugins: esbuildDefaultPlugins,
});

if (watch) {
await ctx.watch();
} else {
await ctx.rebuild();
await ctx.dispose();
}
}

try {
await main();
} catch (error) {
console.error(error);
process.exit(1);
}
33 changes: 33 additions & 0 deletions packages/ws/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@discloudapp/ws",
"version": "0.1.0",
"description": "A WebSocket for discloud.app",
"main": "dist",
"types": "dist/index.d.ts",
"scripts": {
"watch": "npm-run-all -p watch:*",
"watch:esbuild": "node esbuild.mjs --watch",
"watch:tsc": "tsc --noEmit --watch",
"prepublish": "node esbuild.mjs --production && tsc --emitDeclarationOnly --outDir dist",
"release:pre": "npm version pre --legacy-peer-deps --no-git-tag-version && npm run prepublish && npm publish --tag=beta",
"release": "npm run prepublish && npm publish",
"test": "tsc --noEmit && tsc && npm run test:node",
"test:node": "node --test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/discloud/discloud.app.git"
},
"keywords": [
"discloud",
"discloud.app"
],
"license": "Apache-2.0",
"dependencies": {
"@discloudapp/api-types": "^1.0.2",
"ws": "^8.18.2"
},
"publishConfig": {
"access": "public"
}
}
50 changes: 50 additions & 0 deletions packages/ws/src/actions/commit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { type SocketClient } from "../client";
import { SocketEvents } from "../enum";
import type { SocketCommitActionOptions, SocketEventCommitData } from "../types";

/** *Note* Setting the `options.onError` property prevents promise rejection */
export function commitAction(
socket: SocketClient<SocketEventCommitData>,
buffer: Buffer,
options: SocketCommitActionOptions = {},
) {
return new Promise<boolean>((resolve, reject) => {
let success = false;

function onError(error: any) {
if (typeof options.onError === "function") return options.onError(error);
socket.dispose();
reject(error);
}

socket
.on(SocketEvents.close, (code, reason) => {
if (typeof options.onClose === "function") options.onClose(code, reason);
resolve(success);
})
.on(SocketEvents.error, onError)
.on(SocketEvents.connecting, () => {
if (typeof options.onConnecting === "function") options.onConnecting();
})
.on(SocketEvents.connected, async () => {
if (typeof options.onConnected === "function") options.onConnected();

try {
await socket.sendBuffer(buffer, options.onProgress);
} catch (error: any) {
onError(error);
}
})
.on(SocketEvents.data, (data) => {
if (typeof options.onData === "function") options.onData(data);

switch (data.statusCode) {
case 200:
success = true;
break;
}
})
.connect()
.catch(onError);
});
}
49 changes: 49 additions & 0 deletions packages/ws/src/actions/upload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { type ApiApp } from "@discloudapp/api-types/v2";
import { type SocketClient } from "../client";
import { SocketEvents } from "../enum";
import type { SocketEventUploadData, SocketUploadActionOptions } from "../types";

/** *Note* Setting the `options.onError` property prevents promise rejection */
export function uploadAction(socket: SocketClient<SocketEventUploadData>, buffer: Buffer, options?: SocketUploadActionOptions): Promise<ApiApp | void>
export function uploadAction(socket: SocketClient, buffer: Buffer, options?: SocketUploadActionOptions): Promise<ApiApp | void>
export function uploadAction(socket: SocketClient<SocketEventUploadData>, buffer: Buffer, options: SocketUploadActionOptions = {}) {
return new Promise<ApiApp | void>((resolve, reject) => {
let app: ApiApp;

function onError(error: any) {
if (typeof options.onError === "function") return options.onError(error);
socket.dispose();
reject(error);
}

socket
.on(SocketEvents.close, (code, reason) => {
if (typeof options.onClose === "function") options.onClose(code, reason);
resolve(app);
})
.on(SocketEvents.error, onError)
.on(SocketEvents.connecting, () => {
if (typeof options.onConnecting === "function") options.onConnecting();
})
.on(SocketEvents.connected, async () => {
if (typeof options.onConnected === "function") options.onConnected();

try {
await socket.sendBuffer(buffer, options.onProgress);
} catch (error: any) {
onError(error);
}
})
.on(SocketEvents.data, (data) => {
switch (data.statusCode) {
case 102:
if (typeof options.onData === "function") options.onData(data);
break;
}

if (data.app) app = data.app;
})
.connect()
.catch(onError);
});
}
Loading
Loading