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"