From d4272e0fd3476d49f96568cb77fc48fb8d266d32 Mon Sep 17 00:00:00 2001 From: Pierre Rousseau Date: Wed, 24 Sep 2025 08:42:46 +0200 Subject: [PATCH] [REF] *: Introduce o-spreadsheet-engine package This commit is the first step towards running the Spreadsheet Model without the need of a web environment. It introduces the o-spreadsheet-engine package (almost empty for now) to host the model and all its dependencies (plugins, functions, ...). It should not have any impact in the development workflow as the npm commands have been updated to build/test/lint the new package as well. Task: 4179627 Co-authored-by: Vincent Schippefilt Co-authored-by: Pierre Rousseau --- .husky/post-checkout | 12 ++ .husky/pre-commit | 15 ++ demo/minimalist.html | 2 +- package-lock.json | 183 +++++++++--------- package.json | 50 +++-- packages/o-spreadsheet-engine/package.json | 74 +++++++ .../o-spreadsheet-engine/rollup.config.js | 77 ++++++++ .../o-spreadsheet-engine/src/helpers/uuid.ts | 50 +++++ packages/o-spreadsheet-engine/src/index.ts | 1 + .../o-spreadsheet-engine/tests/index.test.ts | 5 + .../o-spreadsheet-engine/tsconfig.jest.json | 7 + packages/o-spreadsheet-engine/tsconfig.json | 8 + rollup.config.js | 44 ++++- src/helpers/uuid.ts | 51 +---- tsconfig.jest.json | 3 +- tsconfig.json | 5 +- 16 files changed, 420 insertions(+), 167 deletions(-) create mode 100644 packages/o-spreadsheet-engine/package.json create mode 100644 packages/o-spreadsheet-engine/rollup.config.js create mode 100644 packages/o-spreadsheet-engine/src/helpers/uuid.ts create mode 100644 packages/o-spreadsheet-engine/src/index.ts create mode 100644 packages/o-spreadsheet-engine/tests/index.test.ts create mode 100644 packages/o-spreadsheet-engine/tsconfig.jest.json create mode 100644 packages/o-spreadsheet-engine/tsconfig.json diff --git a/.husky/post-checkout b/.husky/post-checkout index 06336fb057..d53af76677 100755 --- a/.husky/post-checkout +++ b/.husky/post-checkout @@ -6,3 +6,15 @@ if [ "$HUSKY_POST_CHECKOUT" != 0 ]; then npm install >/dev/null 2>&1 fi fi + +if [ ! -d "build/js/src" ]; then + if [ -d "build" ]; then + if [ "$OSTYPE" = "msys" ]; then + # Windows (Git Bash/MSYS) + cmd.exe /C "rmdir /s /q build" + else + # POSIX + rm -rf build + fi + fi +fi diff --git a/.husky/pre-commit b/.husky/pre-commit index f9b68dec5b..7aa2a09d54 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -37,4 +37,19 @@ if [ "$HUSKY_PRE_COMMIT" != 0 ]; then # Css wrap check node .husky/css_check.js + + # Check that all package.json versions are the same as the root + root_version=$(node -p "require('./package.json').version") + mismatch=0 + for pkg in $(find packages -name package.json); do + pkg_version=$(node -p "require('./$pkg').version") + if [ "$pkg_version" != "$root_version" ]; then + echo "Version mismatch: $pkg ($pkg_version) != root ($root_version)" + mismatch=1 + fi + done + if [ $mismatch -ne 0 ]; then + echo "❌ All package.json versions must match the root version." + exit 1 + fi fi diff --git a/demo/minimalist.html b/demo/minimalist.html index 22acc6f821..113213e051 100644 --- a/demo/minimalist.html +++ b/demo/minimalist.html @@ -24,7 +24,7 @@ - + diff --git a/package-lock.json b/package-lock.json index f10a83c331..3bec71a72f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,11 @@ "name": "@odoo/o-spreadsheet", "version": "19.1.0-alpha.3", "license": "LGPL-3.0-or-later", + "workspaces": [ + "packages/o-spreadsheet-engine" + ], "dependencies": { + "@odoo/o-spreadsheet-engine": "*", "@odoo/owl": "2.5.1", "bootstrap": "^5.3.3", "font-awesome": "^4.7.0", @@ -16,6 +20,7 @@ }, "devDependencies": { "@prettier/plugin-xml": "^2.2.0", + "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-node-resolve": "^15.2.0", "@rollup/plugin-terser": "^0.4.3", "@swc/core": "1.6.7", @@ -1098,11 +1103,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@jest/core/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/@jest/core/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -1356,11 +1356,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@jest/reporters/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/@jest/reporters/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -1417,11 +1412,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/source-map/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/@jest/test-result": { "version": "29.6.1", "dev": true, @@ -1450,11 +1440,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/@jest/transform": { "version": "29.6.1", "dev": true, @@ -1530,11 +1515,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@jest/transform/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/@jest/transform/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -1735,6 +1715,10 @@ "node": ">= 8" } }, + "node_modules/@odoo/o-spreadsheet-engine": { + "resolved": "packages/o-spreadsheet-engine", + "link": true + }, "node_modules/@odoo/owl": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/@odoo/owl/-/owl-2.5.1.tgz", @@ -1748,6 +1732,7 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", "peer": true, "funding": { "type": "opencollective", @@ -1764,6 +1749,24 @@ "prettier": ">=2.4.0" } }, + "node_modules/@rollup/plugin-alias": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz", + "integrity": "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.2.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.0.tgz", @@ -2871,11 +2874,6 @@ "dev": true, "license": "MIT" }, - "node_modules/babel-jest/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -3115,9 +3113,9 @@ "license": "MIT" }, "node_modules/bootstrap": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", - "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", "funding": [ { "type": "github", @@ -3128,6 +3126,7 @@ "url": "https://opencollective.com/bootstrap" } ], + "license": "MIT", "peerDependencies": { "@popperjs/core": "^2.11.8" } @@ -5266,6 +5265,7 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==", + "license": "(OFL-1.1 AND MIT)", "engines": { "node": ">=0.10.3" } @@ -5429,11 +5429,6 @@ "node": ">=10" } }, - "node_modules/fs-extra/node_modules/graceful-fs": { - "version": "4.2.10", - "dev": true, - "license": "ISC" - }, "node_modules/fs-extra/node_modules/universalify": { "version": "2.0.0", "dev": true, @@ -5605,7 +5600,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.1.15", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "license": "ISC" }, @@ -6651,11 +6648,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jest-cli/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -6786,11 +6778,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-config/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-config/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -7143,11 +7130,6 @@ "fsevents": "^2.3.2" } }, - "node_modules/jest-haste-map/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-leak-detector": { "version": "29.6.1", "dev": true, @@ -7398,11 +7380,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jest-message-util/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-message-util/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -7564,11 +7541,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jest-resolve/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -7664,11 +7636,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jest-runner/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-runner/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -7816,11 +7783,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-runtime/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-runtime/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -7924,11 +7886,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-snapshot/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -8074,11 +8031,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jest-util/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/jest-util/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -10132,7 +10084,8 @@ "node_modules/quickselect": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", + "license": "ISC" }, "node_modules/random-bytes": { "version": "1.0.0", @@ -10176,6 +10129,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", + "license": "MIT", "dependencies": { "quickselect": "^2.0.0" } @@ -10581,11 +10535,6 @@ "node": ">=12" } }, - "node_modules/rollup-plugin-typescript2/node_modules/graceful-fs": { - "version": "4.2.10", - "dev": true, - "license": "ISC" - }, "node_modules/rollup-plugin-typescript2/node_modules/semver": { "version": "7.3.8", "dev": true, @@ -12325,6 +12274,60 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "packages/o-spreadsheet": { + "extraneous": true + }, + "packages/o-spreadsheet-engine": { + "name": "@odoo/o-spreadsheet-engine", + "version": "19.1.0-alpha.3", + "dependencies": { + "rbush": "^3.0.1" + }, + "devDependencies": { + "@prettier/plugin-xml": "^2.2.0", + "@rollup/plugin-alias": "^5.1.1", + "@rollup/plugin-node-resolve": "^15.2.0", + "@rollup/plugin-terser": "^0.4.3", + "@swc/core": "1.6.7", + "@swc/jest": "0.2.36", + "@types/jest": "^27.0.1", + "@types/node": "^20.17.24", + "@types/rbush": "^3.0.3", + "@typescript-eslint/eslint-plugin": "^8.30.1", + "babel-eslint": "^10.1.0", + "fs": "^0.0.1-security", + "glob": "^11.0.1", + "husky": "^7.0.4", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "mockdate": "^3.0.2", + "npm-run-all": "^4.1.5", + "prettier": "^2.8.0", + "prettier-plugin-organize-imports": "^3.2.2", + "rollup": "^3.28.0", + "rollup-plugin-dts": "^5.3.1", + "rollup-plugin-typescript2": "^0.35.0", + "seedrandom": "^3.0.5", + "typescript": "^5.8.2", + "typescript-eslint": "^8.30.1", + "xml-formatter": "^2.4.0" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "packages/o-spreadsheet-ui": { + "name": "@odoo/o-spreadsheet-ui", + "version": "19.1.0-alpha.3", + "extraneous": true, + "dependencies": { + "@odoo/o-spreadsheet-engine": "*", + "@odoo/owl": "2.5.1", + "bootstrap": "^5.3.3", + "font-awesome": "^4.7.0", + "rbush": "^3.0.1" + } } } } diff --git a/package.json b/package.json index 1d898a5b28..f46a0ea6f7 100644 --- a/package.json +++ b/package.json @@ -15,31 +15,38 @@ "engines": { "node": ">=22.0.0" }, + "workspaces": [ + "packages/o-spreadsheet-engine" + ], "scripts": { - "serve-static": "live-server --open=demo --watch=build/o_spreadsheet.iife.js,build/o_spreadsheet.xml,build/o_spreadsheet.css,main.css,demo", - "dev": "npm-run-all --print-label bundle:dev --parallel server serve-static watch", - "server": "node tools/server/main.cjs", + "prepare": "husky install", + "prettier": "prettier . --write", + "check-formatting": "prettier . --check && eslint", + "lint": "eslint --fix", + "dev": "npm-run-all --print-label build --parallel build:watch:engine build:watch server serve-static", + "prebuild": "npm run build --workspaces --if-present", + "build": "npm-run-all build:js bundle:esm bundle:iife \"bundle:xml -- --outDir build\" \"bundle:css -- --out build\"", + "build:watch": "npm-run-all --parallel build:watch:engine build:js:watch bundle:iife:watch bundle:xml:watch bundle:css:watch", + "build:watch:engine": "npm run build:watch --workspace=@odoo/o-spreadsheet-engine", "build:js": "tsc --module es6 --incremental", + "build:js:watch": "npm run build:js -- --watch", "bundle:iife": "rollup -c -m -- --format iife", + "bundle:iife:watch": "npm run bundle:iife -- --watch", "bundle:esm": "rollup -c -m -- --format esm", "bundle:xml": "node tools/bundle_xml/main.cjs", - "bundle:dev": "npm-run-all build:js bundle:iife \"bundle:xml -- --outDir build\" && node tools/bundle_css/main.cjs --out build", - "dist": "tsc --module es6 --declaration --declarationDir dist/types && rollup -c && npm run bundle:xml -- --outDir dist && node tools/bundle_css/main.cjs --out dist", - "monkey": "SPREADSHEET_MONKEY_COUNT=$npm_config_monkey_count jest 'tests/collaborative/collaborative_monkey_party.test.ts'", + "bundle:xml:watch": "node tools/bundle_xml/watch_xml_templates.cjs", + "bundle:css": "node tools/bundle_css/main.cjs", + "bundle:css:watch": "node tools/bundle_css/watch_css_files.cjs", + "serve-static": "live-server --open=demo --watch=build/o-spreadsheet.iife.js,build/o_spreadsheet.xml,build/o_spreadsheet.css,demo", + "server": "node tools/server/main.cjs", + "predist": "npm run dist --workspaces --if-present", + "dist": "tsc --module es6 --declaration --declarationDir dist/types && rollup -c", + "postdist": " npm run bundle:xml -- --outDir dist && npm run bundle:css -- --out dist", + "pretest": "npm run test --workspaces --if-present", "test": "tsc --noEmit --project tsconfig.jest.json && jest", - "test:watch": "jest --watch", - "prettier": "prettier . --write", - "check-formatting": "prettier . --check && eslint", - "prepare": "husky install", - "watch": "npm-run-all -p watch:*", - "watch:bundle": "npm run bundle:iife -- --watch", - "watch:ts": "npm run build:js -- --watch", - "watch:xml": "node tools/bundle_xml/watch_xml_templates.cjs", - "watch:css": "node tools/bundle_css/watch_css_files.cjs", - "unzipXlsx": "node tools/bundle_xlsx/unzip_xlsx_demo.cjs", + "monkey": "SPREADSHEET_MONKEY_COUNT=$npm_config_monkey_count jest 'tests/collaborative/collaborative_monkey_party.test.ts'", "zipXlsx": "node tools/bundle_xlsx/zip_xlsx_demo.cjs", - "build": "npm-run-all build:js bundle:esm \"bundle:xml -- --outDir build\" && node tools/bundle_css/main.cjs --out build", - "lint": "eslint --fix" + "unzipXlsx": "node tools/bundle_xlsx/unzip_xlsx_demo.cjs" }, "browserslist": [ "last 1 Chrome versions" @@ -62,6 +69,7 @@ "homepage": "https://github.com/odoo/o-spreadsheet#readme", "devDependencies": { "@prettier/plugin-xml": "^2.2.0", + "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-node-resolve": "^15.2.0", "@rollup/plugin-terser": "^0.4.3", "@swc/jest": "0.2.36", @@ -125,7 +133,8 @@ "@odoo/owl": "2.5.1", "bootstrap": "^5.3.3", "font-awesome": "^4.7.0", - "rbush": "^3.0.1" + "rbush": "^3.0.1", + "@odoo/o-spreadsheet-engine": "*" }, "jest": { "roots": [ @@ -137,6 +146,9 @@ "@swc/jest" ] }, + "moduleNameMapper": { + "^@odoo/o-spreadsheet-engine$": "/packages/o-spreadsheet-engine/src" + }, "verbose": false, "testEnvironment": "jsdom", "testRegex": "(/tests/.*(test|spec))\\.ts?$", diff --git a/packages/o-spreadsheet-engine/package.json b/packages/o-spreadsheet-engine/package.json new file mode 100644 index 0000000000..8b251e0442 --- /dev/null +++ b/packages/o-spreadsheet-engine/package.json @@ -0,0 +1,74 @@ +{ + "name": "@odoo/o-spreadsheet-engine", + "version": "19.1.0-alpha.3", + "type": "module", + "scripts": { + "build": "npm-run-all build:js bundle:iife", + "build:watch": "npm-run-all --parallel build:js:watch bundle:iife:watch", + "build:js": "tsc --module es6 --incremental", + "build:js:watch": "npm run build:js -- --watch", + "bundle:esm": "rollup -c -m -- --format esm", + "bundle:iife": "rollup -c -m -- --format iife", + "bundle:iife:watch": "npm run bundle:iife -- --watch", + "dist": "tsc --module es6 --declaration --declarationDir ../../dist/types/packages/o-spreadsheet-engine/ && rollup -c", + "test": "tsc --noEmit --project tsconfig.jest.json && jest" + }, + "engines": { + "node": ">=22.0.0" + }, + "dependencies": { + "rbush": "^3.0.1" + }, + "devDependencies": { + "@prettier/plugin-xml": "^2.2.0", + "@rollup/plugin-alias": "^5.1.1", + "@rollup/plugin-node-resolve": "^15.2.0", + "@rollup/plugin-terser": "^0.4.3", + "@swc/core": "1.6.7", + "@swc/jest": "0.2.36", + "@types/jest": "^27.0.1", + "@types/node": "^20.17.24", + "@types/rbush": "^3.0.3", + "@typescript-eslint/eslint-plugin": "^8.30.1", + "babel-eslint": "^10.1.0", + "fs": "^0.0.1-security", + "glob": "^11.0.1", + "husky": "^7.0.4", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "mockdate": "^3.0.2", + "npm-run-all": "^4.1.5", + "prettier": "^2.8.0", + "prettier-plugin-organize-imports": "^3.2.2", + "rollup": "^3.28.0", + "rollup-plugin-dts": "^5.3.1", + "rollup-plugin-typescript2": "^0.35.0", + "seedrandom": "^3.0.5", + "typescript": "^5.8.2", + "typescript-eslint": "^8.30.1", + "xml-formatter": "^2.4.0" + }, + "jest": { + "roots": [ + "/src", + "/tests" + ], + "transform": { + "^.+\\.ts?$": [ + "@swc/jest" + ] + }, + "verbose": false, + "testEnvironment": "jsdom", + "testRegex": "(/tests/.*(test|spec))\\.ts?$", + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "jsx", + "json", + "node" + ], + "workerIdleMemoryLimit": "800MB" + } +} diff --git a/packages/o-spreadsheet-engine/rollup.config.js b/packages/o-spreadsheet-engine/rollup.config.js new file mode 100644 index 0000000000..c10a2978c4 --- /dev/null +++ b/packages/o-spreadsheet-engine/rollup.config.js @@ -0,0 +1,77 @@ +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; +import dts from "rollup-plugin-dts"; +import typescript from "rollup-plugin-typescript2"; +import { bundle } from "../../tools/bundle.cjs"; + +const outro = bundle.outro(); + +/** + * Get the rollup config based on the arguments + * @param {"esm" | "cjs" | "iife"} format format of the bundle + * @param {string} generatedFileName generated file name + * @param {boolean} minified should it be minified + */ +function getConfigForFormat(format, minified = false) { + return { + file: minified + ? `../../dist/o-spreadsheet-engine.${format}.min.js` + : `../../dist/o-spreadsheet-engine.${format}.js`, + format, + name: "o_spreadsheet_engine", + extend: true, + outro, + banner: bundle.jsBanner(), + plugins: minified ? [terser()] : [], + }; +} + +export default (commandLineArgs) => { + let output = []; + let input = ""; + let plugins = [nodeResolve()]; + let config = {}; + + if (commandLineArgs.format) { + // Only build one version to improve speed + config = { + input: "build/js/o-spreadsheet-engine/src/index.js", + external: [], + output: [ + { + name: "o_spreadsheet_engine", + extend: true, + outro, + banner: bundle.jsBanner(), + file: `build/o-spreadsheet-engine.${commandLineArgs.format}.js`, + format: commandLineArgs.format, + }, + ], + plugins, + }; + } else { + input = "src/index.ts"; + output = [ + getConfigForFormat("esm"), + getConfigForFormat("cjs"), + getConfigForFormat("iife"), + getConfigForFormat("iife", true), + ]; + plugins.push(typescript({ useTsconfigDeclarationDir: true })); + config = [ + { + input, + external: [], + output, + plugins, + }, + { + input: "../../dist/types/packages/o-spreadsheet-engine/index.d.ts", + output: [{ file: "../../dist/o-spreadsheet-engine.d.ts", format: "es" }], + plugins: [dts(), nodeResolve()], + }, + ]; + } + + return config; +}; diff --git a/packages/o-spreadsheet-engine/src/helpers/uuid.ts b/packages/o-spreadsheet-engine/src/helpers/uuid.ts new file mode 100644 index 0000000000..85b6cb9fb9 --- /dev/null +++ b/packages/o-spreadsheet-engine/src/helpers/uuid.ts @@ -0,0 +1,50 @@ +/* + * https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript + * */ + +export class UuidGenerator { + /** + * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters) + * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4, + * it also has a smaller size, which is preferable to alleviate the overall data size. + * + * This method is preferable when generating uuids for the core data (sheetId, figureId, etc) + * as they will appear several times in the revisions and local history. + * + */ + smallUuid(): string { + if (window.crypto) { + return "10000000-1000".replace(/[01]/g, (c) => { + const n = Number(c); + return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16); + }); + } else { + // mainly for jest and other browsers that do not have the crypto functionality + return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) { + const r = (Math.random() * 16) | 0, + v = c === "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); + } + } + + /** + * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid. + * This method should be used when you need to avoid collisions at all costs, like the id of a revision. + */ + uuidv4(): string { + if (window.crypto) { + return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => { + const n = Number(c); + return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16); + }); + } else { + // mainly for jest and other browsers that do not have the crypto functionality + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { + const r = (Math.random() * 16) | 0, + v = c === "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); + } + } +} diff --git a/packages/o-spreadsheet-engine/src/index.ts b/packages/o-spreadsheet-engine/src/index.ts new file mode 100644 index 0000000000..3eead65b54 --- /dev/null +++ b/packages/o-spreadsheet-engine/src/index.ts @@ -0,0 +1 @@ +export { UuidGenerator } from "./helpers/uuid"; diff --git a/packages/o-spreadsheet-engine/tests/index.test.ts b/packages/o-spreadsheet-engine/tests/index.test.ts new file mode 100644 index 0000000000..3d2f415fe2 --- /dev/null +++ b/packages/o-spreadsheet-engine/tests/index.test.ts @@ -0,0 +1,5 @@ +describe("dummy", () => { + test("dummy", () => { + expect(true).toBe(true); + }); +}); diff --git a/packages/o-spreadsheet-engine/tsconfig.jest.json b/packages/o-spreadsheet-engine/tsconfig.jest.json new file mode 100644 index 0000000000..8bbe1edf31 --- /dev/null +++ b/packages/o-spreadsheet-engine/tsconfig.jest.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["src", "tests"] +} diff --git a/packages/o-spreadsheet-engine/tsconfig.json b/packages/o-spreadsheet-engine/tsconfig.json new file mode 100644 index 0000000000..7111e9b4e9 --- /dev/null +++ b/packages/o-spreadsheet-engine/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "build/js/o-spreadsheet-engine/src", + "preserveWatchOutput": true + }, + "include": ["src"] +} diff --git a/rollup.config.js b/rollup.config.js index 3585d20966..243f243a14 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,7 +1,10 @@ +import alias from "@rollup/plugin-alias"; import { nodeResolve } from "@rollup/plugin-node-resolve"; import terser from "@rollup/plugin-terser"; +import path from "path"; import dts from "rollup-plugin-dts"; import typescript from "rollup-plugin-typescript2"; +import { fileURLToPath } from "url"; import { bundle } from "./tools/bundle.cjs"; const outro = bundle.outro(); @@ -14,7 +17,7 @@ const outro = bundle.outro(); */ function getConfigForFormat(format, minified = false) { return { - file: minified ? `dist/o-spreadsheet.${format}.min.js` : `dist/o-spreadsheet.${format}.js`, + file: minified ? `dist/o_spreadsheet.${format}.min.js` : `dist/o_spreadsheet.${format}.js`, format, name: "o_spreadsheet", extend: true, @@ -24,17 +27,31 @@ function getConfigForFormat(format, minified = false) { plugins: minified ? [terser()] : [], }; } +const __dirname = fileURLToPath(new URL(".", import.meta.url)); export default (commandLineArgs) => { let output = []; let input = ""; - let plugins = [nodeResolve()]; + let plugins = [ + alias({ + entries: [ + { + find: "@odoo/o-spreadsheet-engine", + replacement: path.resolve( + __dirname, + "./packages/o-spreadsheet-engine/build/js/o-spreadsheet-engine/src/index.js" + ), + }, + ], + }), + nodeResolve(), + ]; let config = {}; if (commandLineArgs.format) { // Only build one version to improve speed config = { - input: "build/js/index.js", + input: "build/js/src/index.js", external: ["@odoo/owl"], output: [ { @@ -48,6 +65,9 @@ export default (commandLineArgs) => { }, ], plugins, + watch: { + include: ["src/**", "./packages/o-spreadsheet-engine/src/**"], + }, }; } else { input = "src/index.ts"; @@ -66,9 +86,23 @@ export default (commandLineArgs) => { plugins, }, { - input: "dist/types/index.d.ts", + input: "dist/types/src/index.d.ts", output: [{ file: "dist/o-spreadsheet.d.ts", format: "es" }], - plugins: [dts(), nodeResolve()], + plugins: [ + dts(), + nodeResolve(), + alias({ + entries: [ + { + find: "@odoo/o-spreadsheet-engine", + replacement: path.resolve( + __dirname, + "./dist/types/packages/o-spreadsheet-engine/index.d.ts" + ), + }, + ], + }), + ], }, ]; } diff --git a/src/helpers/uuid.ts b/src/helpers/uuid.ts index 85b6cb9fb9..eecad570ce 100644 --- a/src/helpers/uuid.ts +++ b/src/helpers/uuid.ts @@ -1,50 +1 @@ -/* - * https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript - * */ - -export class UuidGenerator { - /** - * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters) - * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4, - * it also has a smaller size, which is preferable to alleviate the overall data size. - * - * This method is preferable when generating uuids for the core data (sheetId, figureId, etc) - * as they will appear several times in the revisions and local history. - * - */ - smallUuid(): string { - if (window.crypto) { - return "10000000-1000".replace(/[01]/g, (c) => { - const n = Number(c); - return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16); - }); - } else { - // mainly for jest and other browsers that do not have the crypto functionality - return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) { - const r = (Math.random() * 16) | 0, - v = c === "x" ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); - } - } - - /** - * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid. - * This method should be used when you need to avoid collisions at all costs, like the id of a revision. - */ - uuidv4(): string { - if (window.crypto) { - return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => { - const n = Number(c); - return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16); - }); - } else { - // mainly for jest and other browsers that do not have the crypto functionality - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { - const r = (Math.random() * 16) | 0, - v = c === "x" ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); - } - } -} +export { UuidGenerator } from "@odoo/o-spreadsheet-engine"; diff --git a/tsconfig.jest.json b/tsconfig.jest.json index 05fe2c8c11..26bf4e6c97 100644 --- a/tsconfig.jest.json +++ b/tsconfig.jest.json @@ -1,8 +1,9 @@ { - "extends": "./tsconfig.base.json", + "extends": "./tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["src", "tests"], + "exclude": ["packages"], "files": ["global.d.ts"] } diff --git a/tsconfig.json b/tsconfig.json index e8195e9eae..f0015381ef 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,10 @@ "extends": "./tsconfig.base.json", "compilerOptions": { "outDir": "build/js", - "preserveWatchOutput": true + "preserveWatchOutput": true, + "paths": { + "@odoo/o-spreadsheet-engine": ["./packages/o-spreadsheet-engine/src/"] + } }, "include": ["src"] }