diff --git a/crates/loro-wasm/scripts/bundler_patch.js b/crates/loro-wasm/scripts/bundler_patch.js index 0ef3286be..b44d2ae0c 100644 --- a/crates/loro-wasm/scripts/bundler_patch.js +++ b/crates/loro-wasm/scripts/bundler_patch.js @@ -1,34 +1,69 @@ -// See https://github.com/loro-dev/loro/issues/440 -// Without this patch, Cloudflare Worker would raise issue like: "Uncaught TypeError: wasm2.__wbindgen_start is not a function" -import * as wasm from "./loro_wasm_bg.wasm"; -import * as imports from "./loro_wasm_bg.js"; +import * as rawWasm from './loro_wasm_bg.wasm'; +import * as imports from './loro_wasm_bg.js'; -if (wasm.__wbindgen_start) { - imports.__wbg_set_wasm(wasm); - wasm.__wbindgen_start(); -} else if ("Bun" in globalThis) { - const { instance } = await WebAssembly.instantiateStreaming( - fetch(Bun.pathToFileURL(wasm.default)), - { - "./loro_wasm_bg.js": imports, - }, - ); - imports.__wbg_set_wasm(instance.exports); +// Normalize how bundlers expose the wasm module/exports. +const toModuleOrExports = (wasm) => { + if (!wasm) return wasm; + if (wasm instanceof WebAssembly.Module) return wasm; + if (typeof wasm === 'object' && 'default' in wasm) { + return wasm.default ?? wasm; + } + // rsbuild doesn't provide a default export when importing wasm. + return wasm; +}; + +const wasmModuleOrExports = toModuleOrExports(rawWasm); +// Helper: ensure we end up with exports + optionally run externref init. +const finalize = (exports) => { + imports.__wbg_set_wasm(exports); + if (typeof imports.__wbindgen_init_externref_table === 'function') { + imports.__wbindgen_init_externref_table(); + } +}; + +if (wasmModuleOrExports && wasmModuleOrExports.__wbindgen_start) { + // See https://github.com/loro-dev/loro/issues/440 + // Without this patch, Cloudflare Worker would raise issue like: "Uncaught TypeError: wasm2.__wbindgen_start is not a function" + // Already the initialized exports object (Cloudflare Workers path). + finalize(wasmModuleOrExports); + wasmModuleOrExports.__wbindgen_start(); +} else if ('Bun' in globalThis) { // Bun's wasm runtime (1.3.0 as of Oct 2025) sometimes reads externref slot 1 // (reserved for booleans by wasm-bindgen) as the global object, causing APIs // like `LoroText.toDelta()` to return cyclic structures. Re-running the // wasm-bindgen externref table initializer after instantiation resets the // table so booleans stay primitives and avoids the infinite recursion seen in // Bun tests during `pnpm release-wasm`. - if (typeof imports.__wbindgen_init_externref_table === "function") { - imports.__wbindgen_init_externref_table(); + let instance; + if (wasmModuleOrExports instanceof WebAssembly.Module) { + ({ instance } = await WebAssembly.instantiate(wasmModuleOrExports, { + './loro_wasm_bg.js': imports, + })); + } else { + const url = Bun.pathToFileURL(wasmModuleOrExports); + ({ instance } = await WebAssembly.instantiateStreaming(fetch(url), { + './loro_wasm_bg.js': imports, + })); } + finalize(instance.exports); } else { - const wkmod = await import("./loro_wasm_bg.wasm"); - const instance = new WebAssembly.Instance(wkmod.default, { - "./loro_wasm_bg.js": imports, - }); - imports.__wbg_set_wasm(instance.exports); + // Browser/node-like bundlers: either we already have exports, or a Module/URL. + const wkmod = + wasmModuleOrExports instanceof WebAssembly.Module + ? wasmModuleOrExports + : await import('./loro_wasm_bg.wasm'); + const module = + wkmod instanceof WebAssembly.Module + ? wkmod + : (wkmod && wkmod.default) || wkmod; + const instance = + module instanceof WebAssembly.Instance + ? module + : new WebAssembly.Instance(module, { + './loro_wasm_bg.js': imports, + }); + finalize(instance.exports ?? instance); } -export * from "./loro_wasm_bg.js"; + +export * from './loro_wasm_bg.js'; diff --git a/crates/loro-wasm/scripts/post-rollup.ts b/crates/loro-wasm/scripts/post-rollup.ts index 931874c85..40ac24340 100644 --- a/crates/loro-wasm/scripts/post-rollup.ts +++ b/crates/loro-wasm/scripts/post-rollup.ts @@ -73,45 +73,40 @@ async function rollupBase64() { const base64IndexPath = "./base64/index.js"; const content = await Deno.readTextFile(base64IndexPath); + const nextContent = injectBase64WasmBranch(content, base64IndexPath); + await Deno.writeTextFile(base64IndexPath, nextContent); - const legacyPattern = - /\{\s*const wkmod = await import\('\.\/loro_wasm_bg-([^']+)\.js'\);\s*const instance = new WebAssembly\.Instance\(wkmod\.default, \{\s*"\.\/loro_wasm_bg\.js": imports,\s*\}\);\s*__wbg_set_wasm\(instance\.exports\);\s*\}/; - const legacyReplacement = (match: string, hash: string) => ` -import loro_wasm_bg_js from './loro_wasm_bg-${hash}.js'; -const instance = new WebAssembly.Instance(loro_wasm_bg_js(), { - "./loro_wasm_bg.js": imports, -}); -__wbg_set_wasm(instance.exports); -`; + await Deno.copyFile("./bundler/loro_wasm.d.ts", "./base64/loro_wasm.d.ts"); +} - const modernPattern = - /const wkmod = await Promise\.resolve\(\)\.then\(function \(\) { return wasm\$1; }\);\s*const instance = new WebAssembly\.Instance\(wkmod\.default, \{\s*"\.\/loro_wasm_bg\.js": imports,\s*\}\);\s*__wbg_set_wasm\(instance\.exports\);\s*/; - const modernReplacement = () => `const instance = loro_wasm_bg({ - "./loro_wasm_bg.js": imports, -}); -__wbg_set_wasm(instance.exports); -`; - - let nextContent = content; - let replaced = false; - - if (legacyPattern.test(nextContent)) { - nextContent = nextContent.replace(legacyPattern, legacyReplacement); - replaced = true; - } else if (modernPattern.test(nextContent)) { - nextContent = nextContent.replace(modernPattern, modernReplacement); - replaced = true; +function injectBase64WasmBranch(content: string, filePath: string): string { + const alreadyPatched = + content.includes("typeof wasmModuleOrExports === \"function\""); + if (alreadyPatched) { + return content; } - if (!replaced) { + const bunBranchPattern = /}\s*else if\s*\(\s*(['"])Bun\1\s+in\s+globalThis\s*\)\s*\{/; + if (!bunBranchPattern.test(content)) { throw new Error( - `Could not find string to replace in ${base64IndexPath}`, + `Could not locate Bun branch while patching ${filePath}`, ); } - await Deno.writeTextFile(base64IndexPath, nextContent); - - await Deno.copyFile("./bundler/loro_wasm.d.ts", "./base64/loro_wasm.d.ts"); + const base64Branch = `} else if (typeof wasmModuleOrExports === "function") { + const moduleOrInstance = wasmModuleOrExports({ + "./loro_wasm_bg.js": imports, + }); + const instance = + moduleOrInstance instanceof WebAssembly.Instance + ? moduleOrInstance + : new WebAssembly.Instance(moduleOrInstance, { + "./loro_wasm_bg.js": imports, + }); + finalize(instance.exports ?? instance); +} else if ("Bun" in globalThis) {`; + + return content.replace(bunBranchPattern, base64Branch); } async function main() { diff --git a/examples/test-rsbuild/.gitignore b/examples/test-rsbuild/.gitignore new file mode 100644 index 000000000..849ddff3b --- /dev/null +++ b/examples/test-rsbuild/.gitignore @@ -0,0 +1 @@ +dist/ diff --git a/examples/test-rsbuild/package.json b/examples/test-rsbuild/package.json new file mode 100644 index 000000000..d43f481c9 --- /dev/null +++ b/examples/test-rsbuild/package.json @@ -0,0 +1,23 @@ +{ + "name": "loro-test-rsbuild", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "rsbuild dev", + "build": "rsbuild build", + "preview": "rsbuild preview" + }, + "dependencies": { + "loro-crdt": "link:../../crates/loro-wasm", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@rsbuild/core": "^1.0.0", + "@rsbuild/plugin-react": "^1.0.0", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "typescript": "^5.6.3" + } +} diff --git a/examples/test-rsbuild/pnpm-lock.yaml b/examples/test-rsbuild/pnpm-lock.yaml new file mode 100644 index 000000000..33722e8ce --- /dev/null +++ b/examples/test-rsbuild/pnpm-lock.yaml @@ -0,0 +1,405 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + loro-crdt: + specifier: link:../../crates/loro-wasm + version: link:../../crates/loro-wasm + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@rsbuild/core': + specifier: ^1.0.0 + version: 1.6.3 + '@rsbuild/plugin-react': + specifier: ^1.0.0 + version: 1.4.2(@rsbuild/core@1.6.3) + '@types/react': + specifier: ^18.3.3 + version: 18.3.26 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.7(@types/react@18.3.26) + typescript: + specifier: ^5.6.3 + version: 5.9.3 + +packages: + + '@emnapi/core@1.7.0': + resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} + + '@emnapi/runtime@1.7.0': + resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@module-federation/error-codes@0.21.2': + resolution: {integrity: sha512-mGbPAAApgjmQUl4J7WAt20aV04a26TyS21GDEpOGXFEQG5FqmZnSJ6FqB8K19HgTKioBT1+fF/Ctl5bGGao/EA==} + + '@module-federation/runtime-core@0.21.2': + resolution: {integrity: sha512-LtDnccPxjR8Xqa3daRYr1cH/6vUzK3mQSzgvnfsUm1fXte5syX4ftWw3Eu55VdqNY3yREFRn77AXdu9PfPEZRw==} + + '@module-federation/runtime-tools@0.21.2': + resolution: {integrity: sha512-SgG9NWTYGNYcHSd5MepO3AXf6DNXriIo4sKKM4mu4RqfYhHyP+yNjnF/gvYJl52VD61g0nADmzLWzBqxOqk2tg==} + + '@module-federation/runtime@0.21.2': + resolution: {integrity: sha512-97jlOx4RAnAHMBTfgU5FBK6+V/pfT6GNX0YjSf8G+uJ3lFy74Y6kg/BevEkChTGw5waCLAkw/pw4LmntYcNN7g==} + + '@module-federation/sdk@0.21.2': + resolution: {integrity: sha512-t2vHSJ1a9zjg7LLJoEghcytNLzeFCqOat5TbXTav5dgU0xXw82Cf0EfLrxiJL6uUpgbtyvUdqqa2DVAvMPjiiA==} + + '@module-federation/webpack-bundler-runtime@0.21.2': + resolution: {integrity: sha512-06R/NDY6Uh5RBIaBOFwYWzJCf1dIiQd/DFHToBVhejUT3ZFG7GzHEPIIsAGqMzne/JSmVsvjlXiJu7UthQ6rFA==} + + '@napi-rs/wasm-runtime@1.0.7': + resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + + '@rsbuild/core@1.6.3': + resolution: {integrity: sha512-93/j5w+nyzfTjHfch2ram+Y6Og3NUcl46nsrKojD3scBR9nSjYHjJM27pQNi0Oq7Io7vQpTMvxwuSaG7AShfRw==} + engines: {node: '>=18.12.0'} + hasBin: true + + '@rsbuild/plugin-react@1.4.2': + resolution: {integrity: sha512-2rJb5mOuqVof2aDq4SbB1E65+0n1vjhAADipC88jvZRNuTOulg79fh7R4tsCiBMI4VWq46gSpwekiK8G5bq6jg==} + peerDependencies: + '@rsbuild/core': 1.x + + '@rspack/binding-darwin-arm64@1.6.1': + resolution: {integrity: sha512-am7gVsqicKY/FhDfNa/InHxrBd3wRt6rI7sFTaunKaPbPERjWSKr/sI47tB3t8uNYmLQFFhWFijomAhDyrlHMg==} + cpu: [arm64] + os: [darwin] + + '@rspack/binding-darwin-x64@1.6.1': + resolution: {integrity: sha512-uadcJOal5YTg191+kvi47I0b+U0sRKe8vKFjMXYOrSIcbXGVRdBxROt/HMlKnvg0u/A83f6AABiY6MA2fCs/gw==} + cpu: [x64] + os: [darwin] + + '@rspack/binding-linux-arm64-gnu@1.6.1': + resolution: {integrity: sha512-n7UGSBzv7PiX+V1Q2bY3S1XWyN3RCykCQUgfhZ+xWietCM/1349jgN7DoXKPllqlof1GPGBjziHU0sQZTC4tag==} + cpu: [arm64] + os: [linux] + + '@rspack/binding-linux-arm64-musl@1.6.1': + resolution: {integrity: sha512-P7nx0jsKxx7g3QAnH9UnJDGVgs1M2H7ZQl68SRyrs42TKOd9Md22ynoMIgCK1zoy+skssU6MhWptluSggXqSrA==} + cpu: [arm64] + os: [linux] + + '@rspack/binding-linux-x64-gnu@1.6.1': + resolution: {integrity: sha512-SdiurC1bV/QHnj7rmrBYJLdsat3uUDWl9KjkVjEbtc8kQV0Ri4/vZRH0nswgzx7hZNY2j0jYuCm5O8+3qeJEMg==} + cpu: [x64] + os: [linux] + + '@rspack/binding-linux-x64-musl@1.6.1': + resolution: {integrity: sha512-JoSJu29nV+auOePhe8x2Fzqxiga1YGNcOMWKJ5Uj8rHBZ8FPAiiE+CpLG8TwfpHsivojrY/sy6fE8JldYLV5TQ==} + cpu: [x64] + os: [linux] + + '@rspack/binding-wasm32-wasi@1.6.1': + resolution: {integrity: sha512-u5NiSHxM7LtIo4cebq/hQPJ9o39u127am3eVJHDzdmBVhTYYO5l7XVUnFmcU8hNHuj/4lJzkFviWFbf3SaRSYA==} + cpu: [wasm32] + + '@rspack/binding-win32-arm64-msvc@1.6.1': + resolution: {integrity: sha512-u2Lm4iyUstX/H4JavHnFLIlXQwMka6WVvG2XH8uRd6ziNTh0k/u9jlFADzhdZMvxj63L2hNXCs7TrMZTx2VObQ==} + cpu: [arm64] + os: [win32] + + '@rspack/binding-win32-ia32-msvc@1.6.1': + resolution: {integrity: sha512-/rMU4pjnQeYnkrXmlqeEPiUNT1wHfJ8GR5v2zqcHXBQkAtic3ZsLwjHpucJjrfRsN5CcVChxJl/T7ozlITfcYw==} + cpu: [ia32] + os: [win32] + + '@rspack/binding-win32-x64-msvc@1.6.1': + resolution: {integrity: sha512-8qsdb5COuZF5Trimo3HHz3N0KuRtrPtRCMK/wi7DOT1nR6CpUeUMPTjvtPl/O/QezQje+cpBFTa5BaQ1WKlHhw==} + cpu: [x64] + os: [win32] + + '@rspack/binding@1.6.1': + resolution: {integrity: sha512-6duvh3CbDA3c4HpNkzIOP9z1wn/mKY1Mrxj+AqgcNvsE0ppp1iKlMsJCDgl7SlUauus2AgtM1dIEU+0sRajmwQ==} + + '@rspack/core@1.6.1': + resolution: {integrity: sha512-hZVrmiZoBTchWUdh/XbeJ5z+GqHW5aPYeufBigmtUeyzul8uJtHlWKmQhpG+lplMf6o1RESTjjxl632TP/Cfhg==} + engines: {node: '>=18.12.0'} + peerDependencies: + '@swc/helpers': '>=0.5.1' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@rspack/lite-tapable@1.0.1': + resolution: {integrity: sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==} + engines: {node: '>=16.0.0'} + + '@rspack/plugin-react-refresh@1.5.2': + resolution: {integrity: sha512-uTbN6P01LPdQOnl5YNwHkN4hDsb9Sb5nIetQb55mPyFiJnu9MQetmBUm+tmh8JJg0QPv4Ew7tXgi4hjpHFY3Rw==} + peerDependencies: + react-refresh: '>=0.10.0 <1.0.0' + webpack-hot-middleware: 2.x + peerDependenciesMeta: + webpack-hot-middleware: + optional: true + + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react@18.3.26': + resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} + + core-js@3.46.0: + resolution: {integrity: sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + +snapshots: + + '@emnapi/core@1.7.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.7.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@module-federation/error-codes@0.21.2': {} + + '@module-federation/runtime-core@0.21.2': + dependencies: + '@module-federation/error-codes': 0.21.2 + '@module-federation/sdk': 0.21.2 + + '@module-federation/runtime-tools@0.21.2': + dependencies: + '@module-federation/runtime': 0.21.2 + '@module-federation/webpack-bundler-runtime': 0.21.2 + + '@module-federation/runtime@0.21.2': + dependencies: + '@module-federation/error-codes': 0.21.2 + '@module-federation/runtime-core': 0.21.2 + '@module-federation/sdk': 0.21.2 + + '@module-federation/sdk@0.21.2': {} + + '@module-federation/webpack-bundler-runtime@0.21.2': + dependencies: + '@module-federation/runtime': 0.21.2 + '@module-federation/sdk': 0.21.2 + + '@napi-rs/wasm-runtime@1.0.7': + dependencies: + '@emnapi/core': 1.7.0 + '@emnapi/runtime': 1.7.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@rsbuild/core@1.6.3': + dependencies: + '@rspack/core': 1.6.1(@swc/helpers@0.5.17) + '@rspack/lite-tapable': 1.0.1 + '@swc/helpers': 0.5.17 + core-js: 3.46.0 + jiti: 2.6.1 + + '@rsbuild/plugin-react@1.4.2(@rsbuild/core@1.6.3)': + dependencies: + '@rsbuild/core': 1.6.3 + '@rspack/plugin-react-refresh': 1.5.2(react-refresh@0.18.0) + react-refresh: 0.18.0 + transitivePeerDependencies: + - webpack-hot-middleware + + '@rspack/binding-darwin-arm64@1.6.1': + optional: true + + '@rspack/binding-darwin-x64@1.6.1': + optional: true + + '@rspack/binding-linux-arm64-gnu@1.6.1': + optional: true + + '@rspack/binding-linux-arm64-musl@1.6.1': + optional: true + + '@rspack/binding-linux-x64-gnu@1.6.1': + optional: true + + '@rspack/binding-linux-x64-musl@1.6.1': + optional: true + + '@rspack/binding-wasm32-wasi@1.6.1': + dependencies: + '@napi-rs/wasm-runtime': 1.0.7 + optional: true + + '@rspack/binding-win32-arm64-msvc@1.6.1': + optional: true + + '@rspack/binding-win32-ia32-msvc@1.6.1': + optional: true + + '@rspack/binding-win32-x64-msvc@1.6.1': + optional: true + + '@rspack/binding@1.6.1': + optionalDependencies: + '@rspack/binding-darwin-arm64': 1.6.1 + '@rspack/binding-darwin-x64': 1.6.1 + '@rspack/binding-linux-arm64-gnu': 1.6.1 + '@rspack/binding-linux-arm64-musl': 1.6.1 + '@rspack/binding-linux-x64-gnu': 1.6.1 + '@rspack/binding-linux-x64-musl': 1.6.1 + '@rspack/binding-wasm32-wasi': 1.6.1 + '@rspack/binding-win32-arm64-msvc': 1.6.1 + '@rspack/binding-win32-ia32-msvc': 1.6.1 + '@rspack/binding-win32-x64-msvc': 1.6.1 + + '@rspack/core@1.6.1(@swc/helpers@0.5.17)': + dependencies: + '@module-federation/runtime-tools': 0.21.2 + '@rspack/binding': 1.6.1 + '@rspack/lite-tapable': 1.0.1 + optionalDependencies: + '@swc/helpers': 0.5.17 + + '@rspack/lite-tapable@1.0.1': {} + + '@rspack/plugin-react-refresh@1.5.2(react-refresh@0.18.0)': + dependencies: + error-stack-parser: 2.1.4 + html-entities: 2.6.0 + react-refresh: 0.18.0 + + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/prop-types@15.7.15': {} + + '@types/react-dom@18.3.7(@types/react@18.3.26)': + dependencies: + '@types/react': 18.3.26 + + '@types/react@18.3.26': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.1.3 + + core-js@3.46.0: {} + + csstype@3.1.3: {} + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + html-entities@2.6.0: {} + + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-refresh@0.18.0: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + stackframe@1.3.4: {} + + tslib@2.8.1: {} + + typescript@5.9.3: {} diff --git a/examples/test-rsbuild/public/index.html b/examples/test-rsbuild/public/index.html new file mode 100644 index 000000000..9e482823d --- /dev/null +++ b/examples/test-rsbuild/public/index.html @@ -0,0 +1,11 @@ + + + + + + Loro + Rsbuild + + +
+ + diff --git a/examples/test-rsbuild/rsbuild.config.ts b/examples/test-rsbuild/rsbuild.config.ts new file mode 100644 index 000000000..91bc2375c --- /dev/null +++ b/examples/test-rsbuild/rsbuild.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; + +export default defineConfig({ + plugins: [pluginReact()], + html: { + template: './public/index.html' + } +}); diff --git a/examples/test-rsbuild/src/App.tsx b/examples/test-rsbuild/src/App.tsx new file mode 100644 index 000000000..8ab92f76b --- /dev/null +++ b/examples/test-rsbuild/src/App.tsx @@ -0,0 +1,41 @@ +import { useMemo, useState } from "react"; +import { LoroDoc } from "loro-crdt"; + +const containerId = "welcome"; + +function useLoroMessage() { + const doc = useMemo(() => { + const instance = new LoroDoc(); + const text = instance.getText(containerId); + if (text.length === 0) { + text.insert(0, "Hello from LoroDoc running inside Rsbuild!"); + } + return instance; + }, []); + + const [message, setMessage] = useState(() => doc.getText(containerId).toString()); + + const appendGreeting = () => { + const text = doc.getText(containerId); + text.insert(text.length, " 👋"); + setMessage(text.toString()); + }; + + return { message, appendGreeting }; +} + +export default function App() { + const { message, appendGreeting } = useLoroMessage(); + + return ( +
+

Rsbuild + Loro

+

+ Shared doc: {message} +

+ +
+ ); +} diff --git a/examples/test-rsbuild/src/index.tsx b/examples/test-rsbuild/src/index.tsx new file mode 100644 index 000000000..ba3bf5b9e --- /dev/null +++ b/examples/test-rsbuild/src/index.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App"; +import "./style.css"; + +const rootElement = document.getElementById("root"); + +if (!rootElement) { + throw new Error("Root element #root not found"); +} + +ReactDOM.createRoot(rootElement).render( + + + +); diff --git a/examples/test-rsbuild/src/style.css b/examples/test-rsbuild/src/style.css new file mode 100644 index 000000000..748d3cce7 --- /dev/null +++ b/examples/test-rsbuild/src/style.css @@ -0,0 +1,35 @@ +:root { + font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + line-height: 1.5; + color: #0f172a; + background-color: #f8fafc; +} + +body { + margin: 0; +} + +main { + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1rem; + padding: 2rem; + text-align: center; +} + +button { + border: none; + background: #2563eb; + color: white; + border-radius: 0.5rem; + padding: 0.75rem 1.5rem; + font-size: 1rem; + cursor: pointer; +} + +button:hover { + background: #1d4ed8; +} diff --git a/examples/test-rsbuild/tsconfig.json b/examples/test-rsbuild/tsconfig.json new file mode 100644 index 000000000..8fab11faf --- /dev/null +++ b/examples/test-rsbuild/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "jsx": "react-jsx", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "allowJs": false, + "types": ["node"] + }, + "include": ["src"], + "references": [] +} diff --git a/package.json b/package.json index 2acbb6895..afad3d1d3 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "ci-release-wasm-version": "pnpm changeset version && deno run -A ./scripts/sync-loro-version.ts", "ci-release-wasm-publish": "pnpm release-wasm && pnpm changeset publish --access public", "check": "cargo clippy --all-features -- -Dwarnings", + "rsbuild-check": "pnpm --dir examples/test-rsbuild install --ignore-workspace --prefer-offline && pnpm --filter loro-test-rsbuild build", "run-fuzz-corpus": "cd crates/fuzz && cargo +nightly fuzz run all -- -max_total_time=1", "fix": "cargo clippy --fix --features=test_utils", "vet": "cargo vet", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a1467a460..455895892 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,7 +82,7 @@ importers: version: 4.5.3 vite-plugin-top-level-await: specifier: ^1.2.2 - version: 1.4.1(rollup@3.29.4)(vite@4.5.3) + version: 1.4.1(@swc/helpers@0.5.17)(rollup@3.29.4)(vite@4.5.3) vite-plugin-wasm: specifier: ^3.1.0 version: 3.3.0(vite@4.5.3) @@ -121,7 +121,7 @@ importers: version: 4.5.3 vite-plugin-top-level-await: specifier: ^1.3.0 - version: 1.4.1(rollup@4.17.2)(vite@4.5.3) + version: 1.4.1(@swc/helpers@0.5.17)(rollup@4.17.2)(vite@4.5.3) vite-plugin-wasm: specifier: ^3.2.2 version: 3.3.0(vite@4.5.3) @@ -129,6 +129,34 @@ importers: specifier: ^1.4.2 version: 1.8.27(typescript@5.6.3) + examples/test-rsbuild: + dependencies: + loro-crdt: + specifier: link:../../crates/loro-wasm + version: link:../../crates/loro-wasm + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@rsbuild/core': + specifier: ^1.0.0 + version: 1.6.3 + '@rsbuild/plugin-react': + specifier: ^1.0.0 + version: 1.4.2(@rsbuild/core@1.6.3) + '@types/react': + specifier: ^18.3.3 + version: 18.3.26 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.7(@types/react@18.3.26) + typescript: + specifier: ^5.6.3 + version: 5.6.3 + packages: '@actions/core@1.11.1': @@ -227,9 +255,15 @@ packages: '@changesets/write@0.3.0': resolution: {integrity: sha512-slGLb21fxZVUYbyea+94uFiD6ntQW0M2hIKNznFizDhZPDgn2c/fv1UzzlW43RVzh1BEDuIqW6hzlJ1OflNmcw==} + '@emnapi/core@1.7.0': + resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} + '@emnapi/runtime@1.5.0': resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} engines: {node: '>=12'} @@ -674,6 +708,27 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@module-federation/error-codes@0.21.2': + resolution: {integrity: sha512-mGbPAAApgjmQUl4J7WAt20aV04a26TyS21GDEpOGXFEQG5FqmZnSJ6FqB8K19HgTKioBT1+fF/Ctl5bGGao/EA==} + + '@module-federation/runtime-core@0.21.2': + resolution: {integrity: sha512-LtDnccPxjR8Xqa3daRYr1cH/6vUzK3mQSzgvnfsUm1fXte5syX4ftWw3Eu55VdqNY3yREFRn77AXdu9PfPEZRw==} + + '@module-federation/runtime-tools@0.21.2': + resolution: {integrity: sha512-SgG9NWTYGNYcHSd5MepO3AXf6DNXriIo4sKKM4mu4RqfYhHyP+yNjnF/gvYJl52VD61g0nADmzLWzBqxOqk2tg==} + + '@module-federation/runtime@0.21.2': + resolution: {integrity: sha512-97jlOx4RAnAHMBTfgU5FBK6+V/pfT6GNX0YjSf8G+uJ3lFy74Y6kg/BevEkChTGw5waCLAkw/pw4LmntYcNN7g==} + + '@module-federation/sdk@0.21.2': + resolution: {integrity: sha512-t2vHSJ1a9zjg7LLJoEghcytNLzeFCqOat5TbXTav5dgU0xXw82Cf0EfLrxiJL6uUpgbtyvUdqqa2DVAvMPjiiA==} + + '@module-federation/webpack-bundler-runtime@0.21.2': + resolution: {integrity: sha512-06R/NDY6Uh5RBIaBOFwYWzJCf1dIiQd/DFHToBVhejUT3ZFG7GzHEPIIsAGqMzne/JSmVsvjlXiJu7UthQ6rFA==} + + '@napi-rs/wasm-runtime@1.0.7': + resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -878,6 +933,90 @@ packages: cpu: [x64] os: [win32] + '@rsbuild/core@1.6.3': + resolution: {integrity: sha512-93/j5w+nyzfTjHfch2ram+Y6Og3NUcl46nsrKojD3scBR9nSjYHjJM27pQNi0Oq7Io7vQpTMvxwuSaG7AShfRw==} + engines: {node: '>=18.12.0'} + hasBin: true + + '@rsbuild/plugin-react@1.4.2': + resolution: {integrity: sha512-2rJb5mOuqVof2aDq4SbB1E65+0n1vjhAADipC88jvZRNuTOulg79fh7R4tsCiBMI4VWq46gSpwekiK8G5bq6jg==} + peerDependencies: + '@rsbuild/core': 1.x + + '@rspack/binding-darwin-arm64@1.6.1': + resolution: {integrity: sha512-am7gVsqicKY/FhDfNa/InHxrBd3wRt6rI7sFTaunKaPbPERjWSKr/sI47tB3t8uNYmLQFFhWFijomAhDyrlHMg==} + cpu: [arm64] + os: [darwin] + + '@rspack/binding-darwin-x64@1.6.1': + resolution: {integrity: sha512-uadcJOal5YTg191+kvi47I0b+U0sRKe8vKFjMXYOrSIcbXGVRdBxROt/HMlKnvg0u/A83f6AABiY6MA2fCs/gw==} + cpu: [x64] + os: [darwin] + + '@rspack/binding-linux-arm64-gnu@1.6.1': + resolution: {integrity: sha512-n7UGSBzv7PiX+V1Q2bY3S1XWyN3RCykCQUgfhZ+xWietCM/1349jgN7DoXKPllqlof1GPGBjziHU0sQZTC4tag==} + cpu: [arm64] + os: [linux] + + '@rspack/binding-linux-arm64-musl@1.6.1': + resolution: {integrity: sha512-P7nx0jsKxx7g3QAnH9UnJDGVgs1M2H7ZQl68SRyrs42TKOd9Md22ynoMIgCK1zoy+skssU6MhWptluSggXqSrA==} + cpu: [arm64] + os: [linux] + + '@rspack/binding-linux-x64-gnu@1.6.1': + resolution: {integrity: sha512-SdiurC1bV/QHnj7rmrBYJLdsat3uUDWl9KjkVjEbtc8kQV0Ri4/vZRH0nswgzx7hZNY2j0jYuCm5O8+3qeJEMg==} + cpu: [x64] + os: [linux] + + '@rspack/binding-linux-x64-musl@1.6.1': + resolution: {integrity: sha512-JoSJu29nV+auOePhe8x2Fzqxiga1YGNcOMWKJ5Uj8rHBZ8FPAiiE+CpLG8TwfpHsivojrY/sy6fE8JldYLV5TQ==} + cpu: [x64] + os: [linux] + + '@rspack/binding-wasm32-wasi@1.6.1': + resolution: {integrity: sha512-u5NiSHxM7LtIo4cebq/hQPJ9o39u127am3eVJHDzdmBVhTYYO5l7XVUnFmcU8hNHuj/4lJzkFviWFbf3SaRSYA==} + cpu: [wasm32] + + '@rspack/binding-win32-arm64-msvc@1.6.1': + resolution: {integrity: sha512-u2Lm4iyUstX/H4JavHnFLIlXQwMka6WVvG2XH8uRd6ziNTh0k/u9jlFADzhdZMvxj63L2hNXCs7TrMZTx2VObQ==} + cpu: [arm64] + os: [win32] + + '@rspack/binding-win32-ia32-msvc@1.6.1': + resolution: {integrity: sha512-/rMU4pjnQeYnkrXmlqeEPiUNT1wHfJ8GR5v2zqcHXBQkAtic3ZsLwjHpucJjrfRsN5CcVChxJl/T7ozlITfcYw==} + cpu: [ia32] + os: [win32] + + '@rspack/binding-win32-x64-msvc@1.6.1': + resolution: {integrity: sha512-8qsdb5COuZF5Trimo3HHz3N0KuRtrPtRCMK/wi7DOT1nR6CpUeUMPTjvtPl/O/QezQje+cpBFTa5BaQ1WKlHhw==} + cpu: [x64] + os: [win32] + + '@rspack/binding@1.6.1': + resolution: {integrity: sha512-6duvh3CbDA3c4HpNkzIOP9z1wn/mKY1Mrxj+AqgcNvsE0ppp1iKlMsJCDgl7SlUauus2AgtM1dIEU+0sRajmwQ==} + + '@rspack/core@1.6.1': + resolution: {integrity: sha512-hZVrmiZoBTchWUdh/XbeJ5z+GqHW5aPYeufBigmtUeyzul8uJtHlWKmQhpG+lplMf6o1RESTjjxl632TP/Cfhg==} + engines: {node: '>=18.12.0'} + peerDependencies: + '@swc/helpers': '>=0.5.1' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@rspack/lite-tapable@1.0.1': + resolution: {integrity: sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==} + engines: {node: '>=16.0.0'} + + '@rspack/plugin-react-refresh@1.5.2': + resolution: {integrity: sha512-uTbN6P01LPdQOnl5YNwHkN4hDsb9Sb5nIetQb55mPyFiJnu9MQetmBUm+tmh8JJg0QPv4Ew7tXgi4hjpHFY3Rw==} + peerDependencies: + react-refresh: '>=0.10.0 <1.0.0' + webpack-hot-middleware: 2.x + peerDependenciesMeta: + webpack-hot-middleware: + optional: true + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -953,9 +1092,15 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@swc/types@0.1.6': resolution: {integrity: sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -968,9 +1113,20 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + '@types/quill@1.3.10': resolution: {integrity: sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==} + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react@18.3.26': + resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -1272,6 +1428,9 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + core-js@3.46.0: + resolution: {integrity: sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==} + cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} @@ -1400,6 +1559,9 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + es-abstract@1.23.3: resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} @@ -1690,6 +1852,9 @@ packages: hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} + human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} @@ -1880,6 +2045,10 @@ packages: resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -1956,6 +2125,10 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + loro-crdt@0.16.0: resolution: {integrity: sha512-U/fwXPfe3GjE96tP97qzIjGoDOz5K/zSNPs1QZ7ZO4pqOAkjkLhBifSYZWW2v1t7ufFgUa4XqXpS1pn7Hyze2A==} @@ -2249,9 +2422,22 @@ packages: quill@1.3.7: resolution: {integrity: sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==} + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -2345,6 +2531,9 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -2446,6 +2635,9 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} @@ -3047,11 +3239,22 @@ snapshots: human-id: 1.0.2 prettier: 2.8.8 + '@emnapi/core@1.7.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.0 + optional: true + '@emnapi/runtime@1.5.0': dependencies: tslib: 2.8.0 optional: true + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.0 + optional: true + '@esbuild/aix-ppc64@0.20.2': optional: true @@ -3334,6 +3537,38 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 + '@module-federation/error-codes@0.21.2': {} + + '@module-federation/runtime-core@0.21.2': + dependencies: + '@module-federation/error-codes': 0.21.2 + '@module-federation/sdk': 0.21.2 + + '@module-federation/runtime-tools@0.21.2': + dependencies: + '@module-federation/runtime': 0.21.2 + '@module-federation/webpack-bundler-runtime': 0.21.2 + + '@module-federation/runtime@0.21.2': + dependencies: + '@module-federation/error-codes': 0.21.2 + '@module-federation/runtime-core': 0.21.2 + '@module-federation/sdk': 0.21.2 + + '@module-federation/sdk@0.21.2': {} + + '@module-federation/webpack-bundler-runtime@0.21.2': + dependencies: + '@module-federation/runtime': 0.21.2 + '@module-federation/sdk': 0.21.2 + + '@napi-rs/wasm-runtime@1.0.7': + dependencies: + '@emnapi/core': 1.7.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3504,6 +3739,83 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.17.2': optional: true + '@rsbuild/core@1.6.3': + dependencies: + '@rspack/core': 1.6.1(@swc/helpers@0.5.17) + '@rspack/lite-tapable': 1.0.1 + '@swc/helpers': 0.5.17 + core-js: 3.46.0 + jiti: 2.6.1 + + '@rsbuild/plugin-react@1.4.2(@rsbuild/core@1.6.3)': + dependencies: + '@rsbuild/core': 1.6.3 + '@rspack/plugin-react-refresh': 1.5.2(react-refresh@0.18.0) + react-refresh: 0.18.0 + transitivePeerDependencies: + - webpack-hot-middleware + + '@rspack/binding-darwin-arm64@1.6.1': + optional: true + + '@rspack/binding-darwin-x64@1.6.1': + optional: true + + '@rspack/binding-linux-arm64-gnu@1.6.1': + optional: true + + '@rspack/binding-linux-arm64-musl@1.6.1': + optional: true + + '@rspack/binding-linux-x64-gnu@1.6.1': + optional: true + + '@rspack/binding-linux-x64-musl@1.6.1': + optional: true + + '@rspack/binding-wasm32-wasi@1.6.1': + dependencies: + '@napi-rs/wasm-runtime': 1.0.7 + optional: true + + '@rspack/binding-win32-arm64-msvc@1.6.1': + optional: true + + '@rspack/binding-win32-ia32-msvc@1.6.1': + optional: true + + '@rspack/binding-win32-x64-msvc@1.6.1': + optional: true + + '@rspack/binding@1.6.1': + optionalDependencies: + '@rspack/binding-darwin-arm64': 1.6.1 + '@rspack/binding-darwin-x64': 1.6.1 + '@rspack/binding-linux-arm64-gnu': 1.6.1 + '@rspack/binding-linux-arm64-musl': 1.6.1 + '@rspack/binding-linux-x64-gnu': 1.6.1 + '@rspack/binding-linux-x64-musl': 1.6.1 + '@rspack/binding-wasm32-wasi': 1.6.1 + '@rspack/binding-win32-arm64-msvc': 1.6.1 + '@rspack/binding-win32-ia32-msvc': 1.6.1 + '@rspack/binding-win32-x64-msvc': 1.6.1 + + '@rspack/core@1.6.1(@swc/helpers@0.5.17)': + dependencies: + '@module-federation/runtime-tools': 0.21.2 + '@rspack/binding': 1.6.1 + '@rspack/lite-tapable': 1.0.1 + optionalDependencies: + '@swc/helpers': 0.5.17 + + '@rspack/lite-tapable@1.0.1': {} + + '@rspack/plugin-react-refresh@1.5.2(react-refresh@0.18.0)': + dependencies: + error-stack-parser: 2.1.4 + html-entities: 2.6.0 + react-refresh: 0.18.0 + '@sinclair/typebox@0.27.8': {} '@swc/core-darwin-arm64@1.5.5': @@ -3536,7 +3848,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.5.5': optional: true - '@swc/core@1.5.5': + '@swc/core@1.5.5(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.6 @@ -3551,13 +3863,23 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.5.5 '@swc/core-win32-ia32-msvc': 1.5.5 '@swc/core-win32-x64-msvc': 1.5.5 + '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.0 + '@swc/types@0.1.6': dependencies: '@swc/counter': 0.1.3 + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.0 + optional: true + '@types/estree@1.0.5': {} '@types/minimist@1.2.5': {} @@ -3566,10 +3888,21 @@ snapshots: '@types/normalize-package-data@2.4.4': {} + '@types/prop-types@15.7.15': {} + '@types/quill@1.3.10': dependencies: parchment: 1.1.4 + '@types/react-dom@18.3.7(@types/react@18.3.26)': + dependencies: + '@types/react': 18.3.26 + + '@types/react@18.3.26': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.1.3 + '@types/resolve@1.20.2': {} '@types/semver@7.5.8': {} @@ -3925,6 +4258,8 @@ snapshots: consola@3.4.2: {} + core-js@3.46.0: {} + cross-spawn@5.1.0: dependencies: lru-cache: 4.1.5 @@ -4051,6 +4386,10 @@ snapshots: dependencies: is-arrayish: 0.2.1 + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + es-abstract@1.23.3: dependencies: array-buffer-byte-length: 1.0.1 @@ -4475,6 +4814,8 @@ snapshots: hosted-git-info@2.8.9: {} + html-entities@2.6.0: {} + human-id@1.0.2: {} human-signals@5.0.0: {} @@ -4659,6 +5000,8 @@ snapshots: jiti@2.5.1: {} + jiti@2.6.1: {} + joycon@3.1.1: {} js-tokens@4.0.0: {} @@ -4727,6 +5070,10 @@ snapshots: lodash.startcase@4.4.0: {} + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + loro-crdt@0.16.0: dependencies: loro-wasm: 0.16.0 @@ -5016,8 +5363,20 @@ snapshots: parchment: 1.1.4 quill-delta: 3.6.3 + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + react-is@18.3.1: {} + react-refresh@0.18.0: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + read-pkg-up@7.0.1: dependencies: find-up: 4.1.0 @@ -5147,6 +5506,10 @@ snapshots: safer-buffer@2.1.2: {} + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + semver@5.7.2: {} semver@7.6.2: {} @@ -5277,6 +5640,8 @@ snapshots: stackback@0.0.2: {} + stackframe@1.3.4: {} + std-env@3.7.0: {} stop-iteration-iterator@1.0.0: @@ -5484,20 +5849,20 @@ snapshots: - supports-color - terser - vite-plugin-top-level-await@1.4.1(rollup@3.29.4)(vite@4.5.3): + vite-plugin-top-level-await@1.4.1(@swc/helpers@0.5.17)(rollup@3.29.4)(vite@4.5.3): dependencies: '@rollup/plugin-virtual': 3.0.2(rollup@3.29.4) - '@swc/core': 1.5.5 + '@swc/core': 1.5.5(@swc/helpers@0.5.17) uuid: 9.0.1 vite: 4.5.3 transitivePeerDependencies: - '@swc/helpers' - rollup - vite-plugin-top-level-await@1.4.1(rollup@4.17.2)(vite@4.5.3): + vite-plugin-top-level-await@1.4.1(@swc/helpers@0.5.17)(rollup@4.17.2)(vite@4.5.3): dependencies: '@rollup/plugin-virtual': 3.0.2(rollup@4.17.2) - '@swc/core': 1.5.5 + '@swc/core': 1.5.5(@swc/helpers@0.5.17) uuid: 9.0.1 vite: 4.5.3 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c03e529e7..a4ee43f0f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,3 +3,4 @@ packages: - "crates/loro-wasm" - "crates/loro-wasm-map" - "examples/loro-quill" + - "examples/test-rsbuild"