From ecc537e324ba34895a0cda798b242387a2b42f03 Mon Sep 17 00:00:00 2001 From: Harald Schilly Date: Thu, 9 Jan 2025 12:23:29 +0100 Subject: [PATCH 1/3] npm: updating to typescript 5.7.3 --- src/compute/compute/package.json | 2 +- src/packages/backend/sha1.ts | 18 ++- .../backend/tcp/enable-messaging-protocol.ts | 52 +++---- .../frontend/account/ssh-keys/fingerprint.ts | 8 +- src/packages/package.json | 2 +- src/packages/pnpm-lock.yaml | 141 +++++++++++------- .../sync/editor/generic/ipywidgets-state.ts | 2 +- src/packages/util/base64.ts | 7 +- 8 files changed, 139 insertions(+), 93 deletions(-) diff --git a/src/compute/compute/package.json b/src/compute/compute/package.json index 48cfd57b35..0d48bc9cf1 100644 --- a/src/compute/compute/package.json +++ b/src/compute/compute/package.json @@ -52,6 +52,6 @@ "devDependencies": { "@types/cookie": "^0.6.0", "@types/node": "^18.16.14", - "typescript": "^5.6.3" + "typescript": "^5.7.3" } } diff --git a/src/packages/backend/sha1.ts b/src/packages/backend/sha1.ts index 5182009e0b..c3863c1c78 100644 --- a/src/packages/backend/sha1.ts +++ b/src/packages/backend/sha1.ts @@ -6,14 +6,20 @@ import { createHash } from "crypto"; // compute sha1 hash of data in hex export function sha1(data: Buffer | string): string { + const sha1sum = createHash("sha1"); + if (typeof data === "string") { - // CRITICAL: Code below assumes data is a Buffer; it will seem to work on a string, but give - // the wrong result where wrong means that it doesn't agree with the frontend version defined - // in misc. - data = Buffer.from(data); + sha1sum.update(data, "utf8"); + } else { + // Convert Buffer to Uint8Array + const uint8Array = new Uint8Array( + data.buffer, + data.byteOffset, + data.byteLength, + ); + sha1sum.update(uint8Array); } - const sha1sum = createHash("sha1"); - sha1sum.update(data); + return sha1sum.digest("hex"); } diff --git a/src/packages/backend/tcp/enable-messaging-protocol.ts b/src/packages/backend/tcp/enable-messaging-protocol.ts index 65428e3aae..80c0e8d24c 100644 --- a/src/packages/backend/tcp/enable-messaging-protocol.ts +++ b/src/packages/backend/tcp/enable-messaging-protocol.ts @@ -43,7 +43,7 @@ export interface CoCalcSocket extends Socket { write_mesg: ( type: Type, mesg: Message, - cb?: (err?: string | Error) => void + cb?: (err?: string | Error) => void, ) => void; recv_mesg: (opts: RecvMesgOpts) => void; } @@ -51,16 +51,18 @@ export interface CoCalcSocket extends Socket { export default function enable(socket: CoCalcSocket, desc: string = "") { socket.setMaxListeners(500); // we use a lot of listeners for listening for messages - let buf: Buffer | null = null; + let buf: Uint8Array | null = null; let bufTargetLength = -1; - const listenForMesg = (data: Buffer) => { - buf = buf == null ? data : Buffer.concat([buf, data]); + const listenForMesg = (data: Uint8Array) => { + buf = buf == null ? data : new Uint8Array([...buf, ...data]); + while (true) { if (bufTargetLength === -1) { // starting to read a new message if (buf.length >= 4) { - bufTargetLength = buf.readUInt32BE(0) + 4; + bufTargetLength = + new DataView(buf.buffer, buf.byteOffset, 4).getUint32(0) + 4; } else { return; // have to wait for more data to find out message length } @@ -80,8 +82,8 @@ export default function enable(socket: CoCalcSocket, desc: string = "") { winston.debug( `WARNING: failed to parse JSON message='${trunc( s, - 512 - )}' on socket ${desc} - ${err}` + 512, + )}' on socket ${desc} - ${err}`, ); // skip it. return; @@ -117,7 +119,7 @@ export default function enable(socket: CoCalcSocket, desc: string = "") { socket.write_mesg = ( type: Type, data: Message, - cb?: (err?: string | Error) => void + cb?: (err?: string | Error) => void, ): void => { if (data == null) { // uncomment this to get a traceback to see what might be causing this... @@ -125,28 +127,24 @@ export default function enable(socket: CoCalcSocket, desc: string = "") { cb?.(`write_mesg(type='${type}': data must be defined`); return; } - const send = function (s: string | Buffer): void { - const buf = Buffer.alloc(4); + + const send = function (s: string | ArrayBuffer): void { // This line was 4 hours of work. It is absolutely // *critical* to change the (possibly a string) s into a // buffer before computing its length and sending it!! // Otherwise unicode characters will cause trouble. - if (typeof s === "string") { - s = Buffer.from(s); - } - buf.writeInt32BE(s.length, 0); - if (!socket.writable) { - cb?.("socket not writable"); - return; - } else { - socket.write(buf); - } + const lengthBuffer = Buffer.alloc(4); + const dataBuffer: Buffer = + typeof s === "string" ? Buffer.from(s) : Buffer.from(s); + + lengthBuffer.writeInt32BE(dataBuffer.length, 0); if (!socket.writable) { cb?.("socket not writable"); return; } else { - socket.write(s, cb); + socket.write(new Uint8Array(lengthBuffer)); + socket.write(new Uint8Array(dataBuffer), cb); } }; @@ -164,11 +162,13 @@ export default function enable(socket: CoCalcSocket, desc: string = "") { return; } send( - Buffer.concat([ - Buffer.from("b"), - Buffer.from(data.uuid), - Buffer.from(data.blob), - ]) + new Uint8Array([ + ...Buffer.from("b"), + ...Buffer.from(data.uuid), + ...(Buffer.isBuffer(data.blob) + ? data.blob + : Buffer.from(data.blob)), + ]).buffer, ); return; default: diff --git a/src/packages/frontend/account/ssh-keys/fingerprint.ts b/src/packages/frontend/account/ssh-keys/fingerprint.ts index 949d88fa18..f444b627b1 100644 --- a/src/packages/frontend/account/ssh-keys/fingerprint.ts +++ b/src/packages/frontend/account/ssh-keys/fingerprint.ts @@ -15,6 +15,12 @@ export function compute_fingerprint(pub: string | undefined): string { throw new Error("No valid SSH key value"); } const pubbuffer = Buffer.from(pub, "base64"); - const key = md5(pubbuffer); + const key = md5( + new Uint8Array( + pubbuffer.buffer, + pubbuffer.byteOffset, + pubbuffer.byteLength, + ), + ); return colons(key); } diff --git a/src/packages/package.json b/src/packages/package.json index a3282945ac..111bd71425 100644 --- a/src/packages/package.json +++ b/src/packages/package.json @@ -7,7 +7,7 @@ "@types/jest": "^29.5.12", "jest": "^29.7.0", "ts-jest": "^29.2.3", - "typescript": "^5.6.3" + "typescript": "^5.7.3" }, "dependencies": { "encoding": "^0.1.13" diff --git a/src/packages/pnpm-lock.yaml b/src/packages/pnpm-lock.yaml index 59f8215b45..4cf51355a5 100644 --- a/src/packages/pnpm-lock.yaml +++ b/src/packages/pnpm-lock.yaml @@ -31,10 +31,10 @@ importers: version: 29.7.0(@types/node@18.19.55) ts-jest: specifier: ^29.2.3 - version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@18.19.55))(typescript@5.6.3) + version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@18.19.55))(typescript@5.7.3) typescript: - specifier: ^5.6.3 - version: 5.6.3 + specifier: ^5.7.3 + version: 5.7.3 api-client: dependencies: @@ -573,7 +573,7 @@ importers: version: 1.1.4(react@18.3.1) react-intl: specifier: ^6.7.0 - version: 6.7.0(react@18.3.1)(typescript@5.6.3) + version: 6.7.0(react@18.3.1)(typescript@5.7.3) react-plotly.js: specifier: ^2.6.0 version: 2.6.0(plotly.js@2.35.2(@rspack/core@1.1.1(@swc/helpers@0.5.15))(mapbox-gl@3.8.0)(webpack@5.96.1))(react@18.3.1) @@ -826,7 +826,7 @@ importers: version: 2.1.2 next: specifier: 14.2.22 - version: 14.2.22(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.81.0) + version: 14.2.22(@babel/core@7.25.8)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.81.0) nyc: specifier: ^15.1.0 version: 15.1.0 @@ -1125,7 +1125,7 @@ importers: version: 1.10.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-intl: specifier: ^6.7.0 - version: 6.7.0(react@18.3.1)(typescript@5.6.3) + version: 6.7.0(react@18.3.1)(typescript@5.7.3) serve-index: specifier: ^1.9.1 version: 1.9.1 @@ -1373,7 +1373,7 @@ importers: version: 0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13) '@langchain/community': specifier: ^0.3.11 - version: 0.3.11(@google-ai/generativelanguage@2.7.0(encoding@0.1.13))(@google-cloud/storage@7.13.0(encoding@0.1.13))(@ibm-cloud/watsonx-ai@1.1.3)(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@qdrant/js-client-rest@1.12.0(typescript@5.6.3))(axios@1.7.7)(better-sqlite3@8.7.0)(cheerio@1.0.0-rc.10)(d3-dsv@3.0.1)(encoding@0.1.13)(fast-xml-parser@4.5.0)(google-auth-library@9.14.1(encoding@0.1.13))(googleapis@137.1.0(encoding@0.1.13))(handlebars@4.7.8)(ibm-cloud-sdk-core@5.1.0)(ignore@5.3.1)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(pg@8.13.1)(ws@8.18.0) + version: 0.3.11(@google-ai/generativelanguage@2.7.0(encoding@0.1.13))(@google-cloud/storage@7.13.0(encoding@0.1.13))(@ibm-cloud/watsonx-ai@1.1.3)(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@qdrant/js-client-rest@1.12.0(typescript@5.7.3))(axios@1.7.7)(encoding@0.1.13)(fast-xml-parser@4.5.0)(google-auth-library@9.14.1(encoding@0.1.13))(googleapis@137.1.0(encoding@0.1.13))(handlebars@4.7.8)(ibm-cloud-sdk-core@5.1.0)(ignore@5.3.1)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(pg@8.13.1)(ws@8.18.0) '@langchain/core': specifier: ^0.3.17 version: 0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)) @@ -1633,10 +1633,10 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) '@typescript-eslint/parser': specifier: ^6.21.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.6.3) + version: 6.21.0(eslint@8.57.1)(typescript@5.7.3) assert: specifier: ^2.0.0 version: 2.1.0 @@ -1777,7 +1777,7 @@ importers: version: 1.6.7 ts-jest: specifier: ^29.2.3 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@18.19.50))(typescript@5.6.3) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@18.19.50))(typescript@5.7.3) tsd: specifier: ^0.22.0 version: 0.22.0 @@ -1835,7 +1835,7 @@ importers: version: 18.19.50 ts-jest: specifier: ^29.2.3 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@18.19.50))(typescript@5.6.3) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@18.19.50))(typescript@5.7.3) sync-client: dependencies: @@ -2024,7 +2024,7 @@ importers: version: 15.8.1 react-intl: specifier: ^6.7.0 - version: 6.7.0(react@18.3.1)(typescript@5.6.3) + version: 6.7.0(react@18.3.1)(typescript@5.7.3) redux: specifier: ^4.2.1 version: 4.2.1 @@ -11445,8 +11445,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} engines: {node: '>=14.17'} hasBin: true @@ -13021,7 +13021,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@formatjs/intl@2.10.5(typescript@5.6.3)': + '@formatjs/intl@2.10.5(typescript@5.7.3)': dependencies: '@formatjs/ecma402-abstract': 2.0.0 '@formatjs/fast-memoize': 2.2.0 @@ -13031,7 +13031,7 @@ snapshots: intl-messageformat: 10.5.14 tslib: 2.7.0 optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.3 '@google-ai/generativelanguage@2.7.0(encoding@0.1.13)': dependencies: @@ -13559,7 +13559,7 @@ snapshots: transitivePeerDependencies: - encoding - '@langchain/community@0.3.11(@google-ai/generativelanguage@2.7.0(encoding@0.1.13))(@google-cloud/storage@7.13.0(encoding@0.1.13))(@ibm-cloud/watsonx-ai@1.1.3)(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@qdrant/js-client-rest@1.12.0(typescript@5.6.3))(axios@1.7.7)(better-sqlite3@8.7.0)(cheerio@1.0.0-rc.10)(d3-dsv@3.0.1)(encoding@0.1.13)(fast-xml-parser@4.5.0)(google-auth-library@9.14.1(encoding@0.1.13))(googleapis@137.1.0(encoding@0.1.13))(handlebars@4.7.8)(ibm-cloud-sdk-core@5.1.0)(ignore@5.3.1)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(pg@8.13.1)(ws@8.18.0)': + '@langchain/community@0.3.11(@google-ai/generativelanguage@2.7.0(encoding@0.1.13))(@google-cloud/storage@7.13.0(encoding@0.1.13))(@ibm-cloud/watsonx-ai@1.1.3)(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@qdrant/js-client-rest@1.12.0(typescript@5.7.3))(axios@1.7.7)(encoding@0.1.13)(fast-xml-parser@4.5.0)(google-auth-library@9.14.1(encoding@0.1.13))(googleapis@137.1.0(encoding@0.1.13))(handlebars@4.7.8)(ibm-cloud-sdk-core@5.1.0)(ignore@5.3.1)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(pg@8.13.1)(ws@8.18.0)': dependencies: '@ibm-cloud/watsonx-ai': 1.1.3 '@langchain/core': 0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)) @@ -13569,7 +13569,7 @@ snapshots: flat: 5.0.2 ibm-cloud-sdk-core: 5.1.0 js-yaml: 4.1.0 - langchain: 0.2.20(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(axios@1.7.7)(cheerio@1.0.0-rc.10)(d3-dsv@3.0.1)(encoding@0.1.13)(fast-xml-parser@4.5.0)(handlebars@4.7.8)(ignore@5.3.1)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(ws@8.18.0) + langchain: 0.2.20(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(axios@1.7.7)(encoding@0.1.13)(fast-xml-parser@4.5.0)(handlebars@4.7.8)(ignore@5.3.1)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(ws@8.18.0) langsmith: 0.2.3(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)) uuid: 10.0.0 zod: 3.23.8 @@ -13577,10 +13577,7 @@ snapshots: optionalDependencies: '@google-ai/generativelanguage': 2.7.0(encoding@0.1.13) '@google-cloud/storage': 7.13.0(encoding@0.1.13) - '@qdrant/js-client-rest': 1.12.0(typescript@5.6.3) - better-sqlite3: 8.7.0 - cheerio: 1.0.0-rc.10 - d3-dsv: 3.0.1 + '@qdrant/js-client-rest': 1.12.0(typescript@5.7.3) google-auth-library: 9.14.1(encoding@0.1.13) googleapis: 137.1.0(encoding@0.1.13) ignore: 5.3.1 @@ -14219,11 +14216,11 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@qdrant/js-client-rest@1.12.0(typescript@5.6.3)': + '@qdrant/js-client-rest@1.12.0(typescript@5.7.3)': dependencies: '@qdrant/openapi-typescript-fetch': 1.2.6 '@sevinf/maybe': 0.5.0 - typescript: 5.6.3 + typescript: 5.7.3 undici: 5.28.4 optional: true @@ -14971,13 +14968,13 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.0 - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@eslint-community/regexpp': 4.11.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.7.3) '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.7.3) '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.7(supports-color@8.1.1) eslint: 8.57.1 @@ -14985,22 +14982,22 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.3.0(typescript@5.7.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.3) '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.7(supports-color@8.1.1) eslint: 8.57.1 optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -15009,21 +15006,21 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.7.3)': dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.7.3) debug: 4.3.7(supports-color@8.1.1) eslint: 8.57.1 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.3.0(typescript@5.7.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@6.21.0': {} - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.7.3)': dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 @@ -15032,20 +15029,20 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.3.0(typescript@5.7.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.3) eslint: 8.57.1 semver: 7.6.3 transitivePeerDependencies: @@ -19627,7 +19624,7 @@ snapshots: lambda-cloud-node-api@1.0.1: {} - langchain@0.2.20(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(axios@1.7.7)(cheerio@1.0.0-rc.10)(d3-dsv@3.0.1)(encoding@0.1.13)(fast-xml-parser@4.5.0)(handlebars@4.7.8)(ignore@5.3.1)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(ws@8.18.0): + langchain@0.2.20(@langchain/anthropic@0.3.3(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(@langchain/google-genai@0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8))(@langchain/mistralai@0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13))(axios@1.7.7)(encoding@0.1.13)(fast-xml-parser@4.5.0)(handlebars@4.7.8)(ignore@5.3.1)(openai@4.63.0(encoding@0.1.13)(zod@3.23.8))(ws@8.18.0): dependencies: '@langchain/core': 0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)) '@langchain/openai': 0.2.11(encoding@0.1.13) @@ -19648,8 +19645,6 @@ snapshots: '@langchain/google-genai': 0.1.0(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8) '@langchain/mistralai': 0.1.1(@langchain/core@0.3.17(openai@4.63.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13) axios: 1.7.7 - cheerio: 1.0.0-rc.10 - d3-dsv: 3.0.1 fast-xml-parser: 4.5.0 handlebars: 4.7.8 ignore: 5.3.1 @@ -20353,6 +20348,33 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@14.2.22(@babel/core@7.25.8)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.81.0): + dependencies: + '@next/env': 14.2.22 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001680 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.1(@babel/core@7.25.8)(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.22 + '@next/swc-darwin-x64': 14.2.22 + '@next/swc-linux-arm64-gnu': 14.2.22 + '@next/swc-linux-arm64-musl': 14.2.22 + '@next/swc-linux-x64-gnu': 14.2.22 + '@next/swc-linux-x64-musl': 14.2.22 + '@next/swc-win32-arm64-msvc': 14.2.22 + '@next/swc-win32-ia32-msvc': 14.2.22 + '@next/swc-win32-x64-msvc': 14.2.22 + '@opentelemetry/api': 1.9.0 + sass: 1.81.0 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nise@1.5.3: dependencies: '@sinonjs/formatio': 3.2.2 @@ -21930,11 +21952,11 @@ snapshots: dependencies: react: 18.3.1 - react-intl@6.7.0(react@18.3.1)(typescript@5.6.3): + react-intl@6.7.0(react@18.3.1)(typescript@5.7.3): dependencies: '@formatjs/ecma402-abstract': 2.0.0 '@formatjs/icu-messageformat-parser': 2.7.8 - '@formatjs/intl': 2.10.5(typescript@5.6.3) + '@formatjs/intl': 2.10.5(typescript@5.7.3) '@formatjs/intl-displaynames': 6.6.8 '@formatjs/intl-listformat': 7.5.7 '@types/hoist-non-react-statics': 3.3.1 @@ -21944,7 +21966,7 @@ snapshots: react: 18.3.1 tslib: 2.7.0 optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.3 react-is@16.13.1: {} @@ -22928,6 +22950,13 @@ snapshots: optionalDependencies: '@babel/core': 7.25.2 + styled-jsx@5.1.1(@babel/core@7.25.8)(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + optionalDependencies: + '@babel/core': 7.25.8 + stylis@4.3.4: {} superb@3.0.0: @@ -23202,13 +23231,13 @@ snapshots: trough@2.2.0: {} - ts-api-utils@1.3.0(typescript@5.6.3): + ts-api-utils@1.3.0(typescript@5.7.3): dependencies: - typescript: 5.6.3 + typescript: 5.7.3 ts-dedent@2.2.0: {} - ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@18.19.55))(typescript@5.6.3): + ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@18.19.55))(typescript@5.7.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -23219,7 +23248,7 @@ snapshots: lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.6.3 - typescript: 5.6.3 + typescript: 5.7.3 yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.25.8 @@ -23227,7 +23256,7 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.8) - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@18.19.50))(typescript@5.6.3): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@18.19.50))(typescript@5.7.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -23238,7 +23267,7 @@ snapshots: lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.6.3 - typescript: 5.6.3 + typescript: 5.7.3 yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.26.0 @@ -23343,7 +23372,7 @@ snapshots: typedarray@0.0.6: {} - typescript@5.6.3: {} + typescript@5.7.3: {} typewise-core@1.2.0: {} diff --git a/src/packages/sync/editor/generic/ipywidgets-state.ts b/src/packages/sync/editor/generic/ipywidgets-state.ts index ebddd7e629..3db5c132b3 100644 --- a/src/packages/sync/editor/generic/ipywidgets-state.ts +++ b/src/packages/sync/editor/generic/ipywidgets-state.ts @@ -302,7 +302,7 @@ export class IpywidgetsState extends EventEmitter { const cur = this.buffers[model_id][path]; if (cur?.hash == hash) { buffer_paths.push(JSON.parse(path)); - buffers.push(cur.buffer); + buffers.push(new Uint8Array(cur.buffer).buffer); return; } }; diff --git a/src/packages/util/base64.ts b/src/packages/util/base64.ts index 3f086b4f7a..15a7140fed 100644 --- a/src/packages/util/base64.ts +++ b/src/packages/util/base64.ts @@ -24,5 +24,10 @@ export function bufferToBase64(buffer: ArrayBuffer | ArrayBufferView): string { // Convert a base64 string to an ArrayBuffer. export function base64ToBuffer(base64: string): ArrayBuffer { - return toUint8Array(base64).buffer; + const buffer = toUint8Array(base64).buffer; + // Typescript 5.7 related: https://devblogs.microsoft.com/typescript/announcing-typescript-5-7/ + if (buffer instanceof SharedArrayBuffer) { + throw new Error("SharedArrayBuffer is not supported"); + } + return buffer; } From 62109338ff2bf28e2d11e6900ea1e52b08fe6028 Mon Sep 17 00:00:00 2001 From: Harald Schilly Date: Thu, 9 Jan 2025 19:24:41 +0100 Subject: [PATCH 2/3] static/rspack: type getConfig and retain the JSDoc documentation, to make importing it in the hub work (via rspack.config.js) --- src/packages/static/src/module-rules.ts | 278 ++++++++++++----------- src/packages/static/src/rspack.config.ts | 36 ++- 2 files changed, 166 insertions(+), 148 deletions(-) diff --git a/src/packages/static/src/module-rules.ts b/src/packages/static/src/module-rules.ts index 61166a64b2..2231b3c7c7 100644 --- a/src/packages/static/src/module-rules.ts +++ b/src/packages/static/src/module-rules.ts @@ -11,146 +11,152 @@ and weird surprises can pop up. We have to exclude transpiling jquery since oth we get an infinite recursion on startup, but of course jquery is fine. */ -export default function moduleRules(devServer?: boolean) { - return [ - { - test: /\.(js|jsx|ts|tsx|mjs|cjs)$/, - // the swc-loader absolutely mangles some upstream libraries so they - // are totally broken! Examples include: jquery and react-virtuoso. - // We could exclude just those two via "/.*node_modules\/(jquery.*|react-virtuoso.*)/", - // but instead we just exclude *all* of node_modules, since any - // random module or upgraded could get broken at any time and that - // is very painful and confusing. - exclude: /.*node_modules\/.*/, - use: [ - { - loader: "builtin:swc-loader", - options: devServer - ? { - jsc: { - transform: { - react: { - development: true, - refresh: true, +import { Configuration } from "@rspack/cli"; + +export default function moduleRules( + devServer?: boolean, +): Configuration["module"] { + return { + rules: [ + { + test: /\.(js|jsx|ts|tsx|mjs|cjs)$/, + // the swc-loader absolutely mangles some upstream libraries so they + // are totally broken! Examples include: jquery and react-virtuoso. + // We could exclude just those two via "/.*node_modules\/(jquery.*|react-virtuoso.*)/", + // but instead we just exclude *all* of node_modules, since any + // random module or upgraded could get broken at any time and that + // is very painful and confusing. + exclude: /.*node_modules\/.*/, + use: [ + { + loader: "builtin:swc-loader", + options: devServer + ? { + jsc: { + transform: { + react: { + development: true, + refresh: true, + }, }, }, - }, - } - : undefined, - }, - ], - }, - { test: /\.coffee$/, loader: "coffee-loader" }, - { - test: /\.cjsx$/, - use: [{ loader: "coffee-loader" }, { loader: "cjsx-loader" }], - }, - { - test: /\.less$/, - use: [ - "style-loader", - { - loader: "css-loader", - options: { - importLoaders: 2, + } + : undefined, + }, + ], + }, + { test: /\.coffee$/, loader: "coffee-loader" }, + { + test: /\.cjsx$/, + use: [{ loader: "coffee-loader" }, { loader: "cjsx-loader" }], + }, + { + test: /\.less$/, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 2, + }, }, - }, - { - loader: "less-loader", - options: { lessOptions: { javascriptEnabled: true } }, - }, // javascriptEnabled needed for antd. - ], - }, - { - test: /\.scss$/i, - use: [ - "style-loader", - { - loader: "css-loader", - options: { - importLoaders: 2, + { + loader: "less-loader", + options: { lessOptions: { javascriptEnabled: true } }, + }, // javascriptEnabled needed for antd. + ], + }, + { + test: /\.scss$/i, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 2, + }, }, - }, - "sass-loader", - ], - }, - { - test: /\.sass$/i, - use: [ - "style-loader", - { - loader: "css-loader", - options: { - importLoaders: 2, + "sass-loader", + ], + }, + { + test: /\.sass$/i, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 2, + }, }, - }, - "sass-loader", - ], - }, - { - test: /\.png$/, - type: "asset/resource", - }, - { - test: /\.ico$/, - type: "asset/resource", - }, - { - test: /\.svg(\?[a-z0-9\.-=]+)?$/, - type: "asset/resource", - }, - { - test: /\.(jpg|jpeg|gif)$/, - type: "asset/resource", - }, - { - test: /\.html$/i, - type: "asset/resource", - }, - { test: /\.hbs$/, loader: "handlebars-loader" }, - { - test: /\.svg?$/, - type: "asset/resource", - }, - { - test: /\.woff(2)?(\?[a-z0-9\.-=]+)?$/, - type: "asset/resource", - }, - { - test: /\.ttf(\?[a-z0-9\.-=]+)?$/, - type: "asset/resource", - }, - { - test: /\.eot(\?[a-z0-9\.-=]+)?$/, - type: "asset/resource", - }, - { - test: /\.css$/i, - use: [ - "style-loader", - { - loader: "css-loader", - options: { - importLoaders: 1, + "sass-loader", + ], + }, + { + test: /\.png$/, + type: "asset/resource", + }, + { + test: /\.ico$/, + type: "asset/resource", + }, + { + test: /\.svg(\?[a-z0-9\.-=]+)?$/, + type: "asset/resource", + }, + { + test: /\.(jpg|jpeg|gif)$/, + type: "asset/resource", + }, + { + test: /\.html$/i, + type: "asset/resource", + }, + { test: /\.hbs$/, loader: "handlebars-loader" }, + { + test: /\.svg?$/, + type: "asset/resource", + }, + { + test: /\.woff(2)?(\?[a-z0-9\.-=]+)?$/, + type: "asset/resource", + }, + { + test: /\.ttf(\?[a-z0-9\.-=]+)?$/, + type: "asset/resource", + }, + { + test: /\.eot(\?[a-z0-9\.-=]+)?$/, + type: "asset/resource", + }, + { + test: /\.css$/i, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 1, + }, }, - }, - ], - }, - { - // This rule makes source maps compatible with other cocalc included modules like @cocalc/util. Without this, you - // get lots of warnings in the console, and lots of source maps don't work at all. - // https://stackoverflow.com/questions/61767538/devtools-failed-to-load-sourcemap-for-webpack-node-modules-js-map-http-e - test: /\.(j|t)s$/, - enforce: "pre" as "pre", - use: ["source-map-loader"], - }, - { - resourceQuery: /raw/, - type: "asset/source", - }, - { - test: /\.(glsl|txt)/, - type: "asset/source", - }, - ] as const; + ], + }, + { + // This rule makes source maps compatible with other cocalc included modules like @cocalc/util. Without this, you + // get lots of warnings in the console, and lots of source maps don't work at all. + // https://stackoverflow.com/questions/61767538/devtools-failed-to-load-sourcemap-for-webpack-node-modules-js-map-http-e + test: /\.(j|t)s$/, + enforce: "pre" as "pre", + use: ["source-map-loader"], + }, + { + resourceQuery: /raw/, + type: "asset/source", + }, + { + test: /\.(glsl|txt)/, + type: "asset/source", + }, + ], + } as const; } diff --git a/src/packages/static/src/rspack.config.ts b/src/packages/static/src/rspack.config.ts index bc02ddf428..c79f2282ba 100644 --- a/src/packages/static/src/rspack.config.ts +++ b/src/packages/static/src/rspack.config.ts @@ -34,20 +34,22 @@ webpack website. Differences include: "use strict"; -import { ProvidePlugin, SwcJsMinimizerRspackPlugin } from "@rspack/core"; +import { Configuration } from "@rspack/cli"; import type { WebpackPluginInstance } from "@rspack/core"; -import { resolve as path_resolve } from "path"; +import { ProvidePlugin, SwcJsMinimizerRspackPlugin } from "@rspack/core"; import { execSync } from "child_process"; +import { resolve as path_resolve } from "path"; + +import getLogger from "@cocalc/backend/logger"; +import { versions as CDN_VERSIONS } from "@cocalc/cdn"; import { version as SMC_VERSION } from "@cocalc/util/smc-version"; import { SITE_NAME as TITLE } from "@cocalc/util/theme"; -import { versions as CDN_VERSIONS } from "@cocalc/cdn"; +import moduleRules from "./module-rules"; +import appLoaderPlugin from "./plugins/app-loader"; import bannerPlugin from "./plugins/banner"; import cleanPlugin from "./plugins/clean"; -import appLoaderPlugin from "./plugins/app-loader"; import defineConstantsPlugin from "./plugins/define-constants"; import hotModuleReplacementPlugin, { getHotMiddlewareUrl } from "./plugins/hot"; -import moduleRules from "./module-rules"; -import getLogger from "@cocalc/backend/logger"; const logger = getLogger("rspack.config"); @@ -61,7 +63,19 @@ interface Options { middleware?: boolean; } -export default function getConfig({ middleware }: Options = {}): any { +// NOTE: the JSDoc below is necessary, because otherwise the import in rspack.config.js causes +// TS2742: The inferred type of 'getConfig' cannot be named without a reference to +// '.pnpm/@rspack+binding@1.1.1/node_modules/@rspack/binding'. +// This is likely not portable. A type annotation is necessary. + +/** + * Gets the configuration for RSPack. + * + * @param {Object} [options={}] - The options for configuring RSPack. + * @param {boolean} [options.middleware] - Indicates whether to enable middleware. + * @returns {Configuration} The RSPack configuration object. + */ +export default function getConfig({ middleware }: Options = {}): Configuration { // Determine the git revision hash: const COCALC_GIT_REVISION = execSync("git rev-parse HEAD").toString().trim(); const COCALC_GITHUB_REPO = "https://github.com/sagemathinc/cocalc"; @@ -86,7 +100,7 @@ export default function getConfig({ middleware }: Options = {}): any { console.log(`MEASURE = ${MEASURE}`); console.log(`OUTPUT = ${OUTPUT}`); console.log(`COCALC_NOCLEAN = ${COCALC_NOCLEAN}`); - console.log(`RSPACK_DEV_SERVER = ${RSPACK_DEV_SERVER}`); + console.log(`RSPACK_DEV_SERVER = ${RSPACK_DEV_SERVER}`); const plugins: WebpackPluginInstance[] = []; function registerPlugin( @@ -151,7 +165,7 @@ export default function getConfig({ middleware }: Options = {}): any { return v; } - const config = { + const config: Configuration = { // this makes things 10x slower: //cache: RSPACK_DEV_SERVER || PRODMODE ? false : true, ignoreWarnings: [/Failed to parse source map/], @@ -183,9 +197,7 @@ export default function getConfig({ middleware }: Options = {}): any { filename: PRODMODE ? "[name]-[chunkhash].js" : "[id]-[chunkhash].js", chunkFilename: PRODMODE ? "[chunkhash].js" : "[id]-[chunkhash].js", }, - module: { - rules: moduleRules(RSPACK_DEV_SERVER), - }, + module: moduleRules(RSPACK_DEV_SERVER), resolve: { alias: { // @cocalc/frontend alias so we can write `import "@cocalc/frontend/..."` From d5c687287ff5fa509b77e856d495c5ffaa256a4b Mon Sep 17 00:00:00 2001 From: Harald Schilly Date: Fri, 10 Jan 2025 13:52:23 +0100 Subject: [PATCH 3/3] TS 5.7: 2nd try fixing ArrayBuffer --- .../backend/tcp/enable-messaging-protocol.ts | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/packages/backend/tcp/enable-messaging-protocol.ts b/src/packages/backend/tcp/enable-messaging-protocol.ts index 80c0e8d24c..c8e2e4546d 100644 --- a/src/packages/backend/tcp/enable-messaging-protocol.ts +++ b/src/packages/backend/tcp/enable-messaging-protocol.ts @@ -9,6 +9,7 @@ Enable two new functions write_mesg and recv_mesg on a TCP socket. */ +import { Buffer } from "node:buffer"; import { Socket } from "node:net"; import getLogger from "@cocalc/backend/logger"; @@ -56,28 +57,29 @@ export default function enable(socket: CoCalcSocket, desc: string = "") { const listenForMesg = (data: Uint8Array) => { buf = buf == null ? data : new Uint8Array([...buf, ...data]); - while (true) { if (bufTargetLength === -1) { // starting to read a new message if (buf.length >= 4) { - bufTargetLength = - new DataView(buf.buffer, buf.byteOffset, 4).getUint32(0) + 4; + const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); + bufTargetLength = dv.getUint32(0) + 4; } else { return; // have to wait for more data to find out message length } } if (bufTargetLength <= buf.length) { // read a new message from our buffer - const type = buf.slice(4, 5).toString(); + const type = String.fromCharCode(buf[4]); const mesg = buf.slice(5, bufTargetLength); + + const textDecoder = new TextDecoder(); switch (type) { case "j": // JSON - const s = mesg.toString(); - let obj; + const s = textDecoder.decode(mesg); try { // Do not use "obj = JSON.parse(s)" - obj = from_json_socket(s); // this properly parses Date objects + const obj = from_json_socket(s); // this properly parses Date objects + socket.emit("mesg", "json", obj); } catch (err) { winston.debug( `WARNING: failed to parse JSON message='${trunc( @@ -88,11 +90,10 @@ export default function enable(socket: CoCalcSocket, desc: string = "") { // skip it. return; } - socket.emit("mesg", "json", obj); break; case "b": // BLOB (tagged by a uuid) socket.emit("mesg", "blob", { - uuid: mesg.slice(0, 36).toString(), + uuid: textDecoder.decode(mesg.slice(0, 36)), blob: mesg.slice(36), }); break; @@ -127,24 +128,26 @@ export default function enable(socket: CoCalcSocket, desc: string = "") { cb?.(`write_mesg(type='${type}': data must be defined`); return; } - const send = function (s: string | ArrayBuffer): void { + const length: Uint8Array = new Uint8Array(4); // This line was 4 hours of work. It is absolutely // *critical* to change the (possibly a string) s into a // buffer before computing its length and sending it!! // Otherwise unicode characters will cause trouble. - const lengthBuffer = Buffer.alloc(4); - const dataBuffer: Buffer = - typeof s === "string" ? Buffer.from(s) : Buffer.from(s); + const data: Uint8Array = new Uint8Array( + typeof s === "string" ? Buffer.from(s) : s, + ); - lengthBuffer.writeInt32BE(dataBuffer.length, 0); + const lengthView = new DataView(length.buffer); + // this was buf.writeInt32BE, i.e. big endian + lengthView.setInt32(0, data.byteLength, false); // false for big-endian if (!socket.writable) { cb?.("socket not writable"); return; } else { - socket.write(new Uint8Array(lengthBuffer)); - socket.write(new Uint8Array(dataBuffer), cb); + socket.write(length); + socket.write(data, cb); } };