diff --git a/package-lock.json b/package-lock.json
index c652c3c5..44c4d739 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,17 +1,17 @@
{
"name": "solid-panes",
- "version": "4.4.2-4",
+ "version": "4.4.2-5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "solid-panes",
- "version": "4.4.2-4",
+ "version": "4.4.2-5",
"license": "MIT",
"dependencies": {
"@solid/better-simple-slideshow": "^0.1.0",
"activitystreams-pane": "1.0.3-4",
- "chat-pane": "3.0.4-2",
+ "chat-pane": "3.0.4-3",
"contacts-pane": "3.2.1-5",
"dompurify": "^3.4.4",
"folder-pane": "3.1.1-2",
@@ -21,12 +21,12 @@
"meeting-pane": "3.0.3-1",
"mime-types": "^3.0.2",
"pane-registry": "3.1.2-2",
- "profile-pane": "3.2.3-3",
+ "profile-pane": "3.2.3-4",
"rdflib": "2.4.0",
"solid-logic": "4.0.8-1",
"solid-namespace": "^0.5.4",
"solid-ui": "3.1.3-13",
- "source-pane": "3.1.1-4"
+ "source-pane": "3.1.1-5"
},
"devDependencies": {
"@iconify/json": "2.2.494",
@@ -2103,9 +2103,9 @@
}
},
"node_modules/@codemirror/view": {
- "version": "6.43.6",
- "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.6.tgz",
- "integrity": "sha512-EVunGSYN1wz1p75WY1s3Xg7t3i8Yol0kGZGizNdX9BUFgMFILYVe8/u6EVpo7Ff5PwbZuILb4QAq7IZoKzIEQA==",
+ "version": "6.43.7",
+ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.7.tgz",
+ "integrity": "sha512-FZsExxkoxnAN+d9TgqXLg5g4A1oQwzX9WlkOT5i2PKkcW7xx3Bmu0vs90g6fo9Mpdsb/l96dnAraQ8932aO4/g==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.7.0",
@@ -2325,30 +2325,30 @@
}
},
"node_modules/@digitalbazaar/http-client/node_modules/undici": {
- "version": "6.27.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz",
- "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==",
+ "version": "6.28.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz",
+ "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==",
"license": "MIT",
"engines": {
"node": ">=18.17"
}
},
"node_modules/@emnapi/core": {
- "version": "1.11.2",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz",
- "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==",
+ "version": "2.0.0-alpha.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-2.0.0-alpha.3.tgz",
+ "integrity": "sha512-AZypUeJ/yByuxyS7BlSNRDOMLMlROYtjYdIAuBmJssVz1UJDSeYxLrdizhXCFYhedC5bqd/ASy8EuNXbVVXp9g==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
- "@emnapi/wasi-threads": "1.2.2",
+ "@emnapi/wasi-threads": "2.0.1",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.11.2",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz",
- "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==",
+ "version": "2.0.0-alpha.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-2.0.0-alpha.3.tgz",
+ "integrity": "sha512-hFPAhMUjJD9BSyCANEISPOogeXC9Zo9ZQl7L6vKnaVsMkCtzznaW/naYypeyl0Gv5rYfWYsZbpixTMpjDJzQeA==",
"license": "MIT",
"optional": true,
"peer": true,
@@ -2357,11 +2357,12 @@
}
},
"node_modules/@emnapi/wasi-threads": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
- "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-2.0.1.tgz",
+ "integrity": "sha512-9DsSk+o5NBX0CCJT8s0EROGSGxjR/tKu6aBTaVyq+SjAEQH4XcdcRxPBRzsBLizTTJ49MJjF+jgu3qnO9GLQcQ==",
"license": "MIT",
"optional": true,
+ "peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
@@ -2441,9 +2442,9 @@
"license": "MIT"
},
"node_modules/@eslint/config-array/node_modules/brace-expansion": {
- "version": "1.1.16",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
- "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -2516,9 +2517,9 @@
"license": "MIT"
},
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
- "version": "1.1.16",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
- "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -2787,9 +2788,9 @@
}
},
"node_modules/@konnorr/qr-creator": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@konnorr/qr-creator/-/qr-creator-1.0.1.tgz",
- "integrity": "sha512-EmRR9rny1ENBtQy7TLOguO/79h1EpzXUmqIdMTGp2BW8NkZtRRPr5hmQcE+n9QXYo4T8NjcaJ14hnZg+s/+K+A==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@konnorr/qr-creator/-/qr-creator-1.1.0.tgz",
+ "integrity": "sha512-6Ae3AfG45MOqF9Qde+1YxIxKf/GUsRmcriV7iCb/HaR+Mk1YDFYP3RINDRMI8z8YMWW3BnSthOujX9RoOex/Kw==",
"license": "MIT"
},
"node_modules/@lezer/common": {
@@ -3002,21 +3003,24 @@
"license": "MIT"
},
"node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
- "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.1.tgz",
+ "integrity": "sha512-KjZdi8Q1wh89gsVmghvbrMgWl6ZWmRmHV6wjB7/g4Zf0dyO+hH3neZUtuDNPO00qq5YE5RITVWvrIZKRaAmzGQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"@tybys/wasm-util": "^0.10.3"
},
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
+ },
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
},
"peerDependencies": {
- "@emnapi/core": "^1.7.1",
- "@emnapi/runtime": "^1.7.1"
+ "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3",
+ "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3"
}
},
"node_modules/@noble/curves": {
@@ -3047,9 +3051,9 @@
}
},
"node_modules/@oxc-project/types": {
- "version": "0.140.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.140.0.tgz",
- "integrity": "sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ==",
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.142.0.tgz",
+ "integrity": "sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==",
"dev": true,
"license": "MIT",
"peer": true,
@@ -3100,9 +3104,9 @@
}
},
"node_modules/@rolldown/binding-android-arm64": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.0.tgz",
- "integrity": "sha512-9yB1l95IrJuNGDFdOYe79vdApdz6WWBCObE+rQ2LUliYUlcyFwSYIb2xb5/Ifw7dAtMy2ZqNyd8QTSOc7duAKw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.1.tgz",
+ "integrity": "sha512-02hOeOSryYxVrOIphmLAsqnCJWxwlzFk+pEt/N/i6OgT3lShHO7xGCU5cpgchRDHboAEbSjzgGh+O/u1GswQmA==",
"cpu": [
"arm64"
],
@@ -3118,9 +3122,9 @@
}
},
"node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.0.tgz",
- "integrity": "sha512-pexNaW9ACLUOaBITOpU6qVu4VrsOFIjTv6bzgu0YUATo4eUJx0V605PxwZfndpPOn0ilqGqvGQ0M8UW0IE24jg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.1.tgz",
+ "integrity": "sha512-fMsTOnN0OjFm3CyppWPitKnc8UlliVARUULW6cfU6AIqjdtgmSFWSk9vecHzZduv/yMWIHDlRhM1e8Iff9uAfA==",
"cpu": [
"arm64"
],
@@ -3136,9 +3140,9 @@
}
},
"node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.0.tgz",
- "integrity": "sha512-NqKYaq0355ZmNMG4QGpxtEDxsc7tGDhjhCm4PpE0cwnBW+5Il95LJyq414niEiaKLVjnVHBEjSo1wngKxJNiFw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.1.tgz",
+ "integrity": "sha512-1wjKdz/XLGKHaTNHjQveQ/B23TKx4ItAqm1JbyVuvNPc4Ze0Fb48s49TAd/2zcplPl8okE/UbTgmlVfwT7eFeQ==",
"cpu": [
"x64"
],
@@ -3154,9 +3158,9 @@
}
},
"node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.0.tgz",
- "integrity": "sha512-3vPoHzh6eBTz9IbB0/qZdSr0Qeks2echn+I4cHu2joV74VriPDdldswksEDzrl1mBB+oPRi+67+3Ib59paxIPQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.1.tgz",
+ "integrity": "sha512-Fa0jHR07E7YBN4vOEsbVf2briYNsuOowfLJaXULZM0ldMlaCaj2LJgLMbMe4iacRyZmvR8efFhgR9wKuGclQUg==",
"cpu": [
"x64"
],
@@ -3172,9 +3176,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.0.tgz",
- "integrity": "sha512-E6NNefZ1bUVmKJq2tJkf45J4Zyczj7qm9rUT7NY+Xo2474Y13qWAwc2tvBt0BAVbmtXR1llkxXg0Ou1jbDf2SQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.1.tgz",
+ "integrity": "sha512-pzkgu1SSHGgRRyRZ4fbmSgmajbVt+epaLP99NDjFft69v/ypfTi6swBMiVdh2EkQ0OSnHE1lZDM7DRGkyAzUpA==",
"cpu": [
"arm"
],
@@ -3190,9 +3194,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.0.tgz",
- "integrity": "sha512-D+TgkdgM1vu+7/Fpf8+v0ARW+RXEP9Ccazgm8zQ4JFFd9Q7SrYQ2TakU5S5ihazQDgpKyAgZDOcIFsvoHmTZ8w==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.1.tgz",
+ "integrity": "sha512-QI5SEDY8cbiYWHx0VO4vIc3UlS6a32vXHjU8Qy/17adEmZIPuByJg13UEvo9c/UCiUkdcVWY83C+b+JrwnNyUg==",
"cpu": [
"arm64"
],
@@ -3208,9 +3212,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.0.tgz",
- "integrity": "sha512-wUqdwJBbAv0APN87GecstdMUtLjjNTs0hBALpxETD73mccFxdmt/XeizXDtN5RAlBwNKmI+Tg+blect2G+8IeQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.1.tgz",
+ "integrity": "sha512-Sm41FyCeXqmYcERoYOCbGIL5hNfd8w9LQ7Y61Bev48HkcjaJqV/iiVOaiDxjVTRMS+QKrZmD8cfPt4uMVnvM+A==",
"cpu": [
"arm64"
],
@@ -3226,9 +3230,9 @@
}
},
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.0.tgz",
- "integrity": "sha512-9DtF35qR9/NrfhM4oxLplCzVVjE+KKm8Pjemi0i/sdhAWkUasjmSo8WTTubNJClhSHCfyk2yeyoXDQEDPtDAAw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.1.tgz",
+ "integrity": "sha512-2x+WhXTGl9yJYPbltW/BSEPTVz9OIWQyER4N+gJEDWkkn904eRcBzELqh/Hf7K0w/ubGbKNMv0ZC+94QK/IFEg==",
"cpu": [
"ppc64"
],
@@ -3244,9 +3248,9 @@
}
},
"node_modules/@rolldown/binding-linux-s390x-gnu": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.0.tgz",
- "integrity": "sha512-RzuHrBh8X8Hntd2N4VR02QGEciq/9JhcZoTpR/Cee6otRrlILGCf3cg2ygHuih+ZebUnWmMrDX6ITI85btO6rQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.1.tgz",
+ "integrity": "sha512-eEjmQpuRQayHPWWnywaWHkFT3ToPbP3RYy42VVd/B9aBGDA+Ol25EIWHxKQST3IiWJjikCWUF7KtbfqwZrzVwQ==",
"cpu": [
"s390x"
],
@@ -3262,9 +3266,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.0.tgz",
- "integrity": "sha512-MK7L0018jjh1jR3mh21G2j1zAVcpscJBlPo2z19pRjv2XOYGRhaV4LyiD8HO6nCDdZln9IFgCMIV5yt4E3klGQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.1.tgz",
+ "integrity": "sha512-/Orga1fZYkLc/56jBICcHrKchl8Z2UKdDSr3LG9ToWO1lQ6a4Livk9Xz+9WN91zsz5QR3XQz2NNoSDEvP6qadw==",
"cpu": [
"x64"
],
@@ -3280,9 +3284,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.0.tgz",
- "integrity": "sha512-gyrxLQ9NfGb/9LoVnC4kb9miUghw1mghnkfYvNHSnVIXriabnfgGPUP4RLcJm87q3KgYz4FYUG8IDiWUT+CpSw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.1.tgz",
+ "integrity": "sha512-xxBJRL+0q0Kce7orznGWLuylHDY65vuARXZRpX+hPdv+DqK2c3NlCsVA98tlWzWNEE7yPqA/1NQ5nnCrj49Y5A==",
"cpu": [
"x64"
],
@@ -3298,9 +3302,9 @@
}
},
"node_modules/@rolldown/binding-openharmony-arm64": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.0.tgz",
- "integrity": "sha512-/6VFMQGRmrhP77KXDC+StIxGzcNp5JOIyYtw0CQ8gPlzhpiIRucYfoM5FaFamHd5BJYIdH86yfP46l1p3WdrFA==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.1.tgz",
+ "integrity": "sha512-M6AdXIXw3s+/8XpKMzdGDEXGS1S7kwUsy+rcTIUIOx5Ge4nXKCtAFHFV9YKkXvGcC5WMoTjAteLzlsQROVI0Yw==",
"cpu": [
"arm64"
],
@@ -3316,29 +3320,26 @@
}
},
"node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.2.0.tgz",
- "integrity": "sha512-rwdbUL465kisF24WEJLvP3JrEG6E5GRuIHt5wpMwHGERtHe4Wm2CIvtf5gTBgr2tGOHKh5NdKEAFS2VkOPE91g==",
- "cpu": [
- "wasm32"
- ],
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.2.1.tgz",
+ "integrity": "sha512-/TX0SoRGojHzSAHpfVBbavRVSazg5U3h3Y3VXfcc0cdugq6kxdqw8LPGFiPr+/7gE/60zRcsOY2Vi9b9eT0jww==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
- "@emnapi/core": "1.11.2",
- "@emnapi/runtime": "1.11.2",
- "@napi-rs/wasm-runtime": "^1.1.6"
+ "@emnapi/core": "2.0.0-alpha.3",
+ "@emnapi/runtime": "2.0.0-alpha.3",
+ "@napi-rs/wasm-runtime": "^1.2.0"
},
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
}
},
"node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.0.tgz",
- "integrity": "sha512-+5suHwRiKGmhwyUaNT8a5QbrBvLFh2DbO910TEmGRH1aSxwrCezodvGQnulv4uiWEIv1Kq4ypRsJ5+O+ry1DiA==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.1.tgz",
+ "integrity": "sha512-EvRrivJieyHG+AO9lleZWgq+g0+S7oV2C51yuqlcyU/R9net+sI4Pj0F+lUoP2bEr6TWX3SqFaaS0SzfLxSzkw==",
"cpu": [
"arm64"
],
@@ -3354,9 +3355,9 @@
}
},
"node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.0.tgz",
- "integrity": "sha512-WfFv6/qGufotqBSBzBYwgpCkJBk8Nj7697LL9vTz/XWc67e0r3oewu8iMRwQj3AUL45GVD7wVsPjCsAAtW66Wg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.1.tgz",
+ "integrity": "sha512-Z4eCmn5QJ/5+azF9knpLWKfVd9aidn0mAe9TpJgvBLId9Ax3t0+JVxBmT25Bv7NBbVW1TZyKjQjQReouMeH5UQ==",
"cpu": [
"x64"
],
@@ -4105,9 +4106,9 @@
}
},
"node_modules/acorn": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
- "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
+ "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -4142,6 +4143,35 @@
"timeago.js": "^4.0.2"
}
},
+ "node_modules/activitystreams-pane/node_modules/solid-ui": {
+ "version": "3.1.3-9",
+ "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-9.tgz",
+ "integrity": "sha512-36as6RIBflm2gsIFnEPLH6hzykXxyc9yJlhJ+E0E6JSLOyjgENGxEj55hMH8lIXzBcR5tkym3Y61vgMm/LIU8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@awesome.me/webawesome": "^3.9.0",
+ "@lit/context": "^1.1.6",
+ "@noble/curves": "^2.2.0",
+ "@noble/hashes": "^2.2.0",
+ "escape-html": "^1.0.3",
+ "lit": "^3.3.3",
+ "mime-types": "^3.0.2",
+ "pane-registry": "3.1.2-1",
+ "rdflib": "2.4.0",
+ "solid-logic": "4.0.8-1",
+ "solid-namespace": "^0.5.4",
+ "uuid": "^14.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "*"
+ }
+ },
+ "node_modules/activitystreams-pane/node_modules/solid-ui/node_modules/pane-registry": {
+ "version": "3.1.2-1",
+ "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-1.tgz",
+ "integrity": "sha512-aibuyF8pAgHDnmywsMEKUddIcqC0oPF8fNx2TP7zRpRW9aYk2iv06td+br8wenbmu2V/l6Y6aJmCkckHWN/GpA==",
+ "license": "MIT"
+ },
"node_modules/agent-base": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
@@ -4490,9 +4520,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
- "version": "2.11.1",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.1.tgz",
- "integrity": "sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A==",
+ "version": "2.11.7",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.7.tgz",
+ "integrity": "sha512-APw5YuIQAg6L9w4sHDI6j26DGFJI6RpYOhnkMPdC9lWbkKvsyPHzDsve1yd73lk21yz7Y09Kci8B2Pp9FonzWA==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -4513,9 +4543,9 @@
}
},
"node_modules/brace-expansion": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
- "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
@@ -4727,15 +4757,19 @@
}
},
"node_modules/chat-pane": {
- "version": "3.0.4-2",
- "resolved": "https://registry.npmjs.org/chat-pane/-/chat-pane-3.0.4-2.tgz",
- "integrity": "sha512-KKIPG6KMcsbo3FKYiYqQ8PkHPUxAelak4GaCPAzI0WInkW5s2ms4QxfWwxELLOYqI0Aj6CICTe52w04Phl9DCQ==",
+ "version": "3.0.4-3",
+ "resolved": "https://registry.npmjs.org/chat-pane/-/chat-pane-3.0.4-3.tgz",
+ "integrity": "sha512-m099X1Lb1qaOtaYNAaJ+NfqD/TMRnhX3Gfx5Xgb2HoZYllaxn1xN3Y5Am4Un21k6tLoPaiq1OIkBe09/gHN/sw==",
"license": "MIT",
"dependencies": {
+ "pane-registry": "3.1.2-2",
"patch-package": "^8.0.1",
- "rdflib": "^2.4.0",
- "solid-logic": "^4.0.8-1",
- "solid-ui": "^3.1.3-9"
+ "rdflib": "^2.3.9",
+ "solid-logic": "^4.0.8-0",
+ "solid-ui": "3.1.3-13",
+ "vite": "^8.0.16",
+ "vitest": "^4.0.18",
+ "vitest-axe": "^0.1.0"
}
},
"node_modules/ci-info": {
@@ -5248,9 +5282,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.396",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.396.tgz",
- "integrity": "sha512-yHiw2Y3C3H9U6TMbOfoWK/BPreiOPXRfTWPBwQBoZG6/8TB6eOPnsy5oaRYuatR7Fw2SJ4kKforgufeo7fq0EQ==",
+ "version": "1.5.398",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.398.tgz",
+ "integrity": "sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ==",
"dev": true,
"license": "ISC"
},
@@ -5261,9 +5295,9 @@
"license": "MIT"
},
"node_modules/enhanced-resolve": {
- "version": "5.24.3",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.3.tgz",
- "integrity": "sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==",
+ "version": "5.24.5",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz",
+ "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -5731,9 +5765,9 @@
"license": "MIT"
},
"node_modules/eslint-plugin-react/node_modules/brace-expansion": {
- "version": "1.1.16",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
- "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5799,9 +5833,9 @@
"license": "MIT"
},
"node_modules/eslint/node_modules/brace-expansion": {
- "version": "1.1.16",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
- "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -5950,9 +5984,9 @@
}
},
"node_modules/exsolve": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.0.tgz",
- "integrity": "sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.1.tgz",
+ "integrity": "sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==",
"dev": true,
"license": "MIT"
},
@@ -6077,9 +6111,9 @@
}
},
"node_modules/flatted": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.3.tgz",
- "integrity": "sha512-/zipXxyO6rGvuNGDiULY9MvEGSkb2gaG4GGH4ygMi0ZZzyMHdUZBmntJmx5x1G2VuPytCwGN4xsJP6cw+sK+vQ==",
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz",
+ "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==",
"license": "ISC"
},
"node_modules/folder-pane": {
@@ -6096,6 +6130,30 @@
"vitest-axe": "^0.1.0"
}
},
+ "node_modules/folder-pane/node_modules/solid-ui": {
+ "version": "3.1.3-11",
+ "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-11.tgz",
+ "integrity": "sha512-VrGdKow2Xg6lmHLRJmRb2rqU2UA/kj75H0o9PYt9DRVBjTWXBfiXFnIqJqst49xBPKIxLPkKGvE0butzL1RwXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@awesome.me/webawesome": "^3.9.0",
+ "@lit/context": "^1.1.6",
+ "@lit/task": "^1.0.3",
+ "@noble/curves": "^2.2.0",
+ "@noble/hashes": "^2.2.0",
+ "escape-html": "^1.0.3",
+ "lit": "^3.3.3",
+ "mime-types": "^3.0.2",
+ "pane-registry": "3.1.2-2",
+ "rdflib": "2.4.0",
+ "solid-logic": "4.0.8-1",
+ "solid-namespace": "^0.5.4",
+ "uuid": "^14.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "*"
+ }
+ },
"node_modules/for-each": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
@@ -6371,9 +6429,9 @@
}
},
"node_modules/globals": {
- "version": "17.7.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz",
- "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==",
+ "version": "17.8.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-17.8.0.tgz",
+ "integrity": "sha512-Zz/LMDZScFmkakeL2cTHzf+PbWKdpU3uclqkZT7TjDG58j5WPt0PpA+n9uPI24fZtlw07q0OtEi84K+umsRzqQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8301,12 +8359,12 @@
}
},
"node_modules/minimatch": {
- "version": "10.2.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
- "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "version": "10.2.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
"license": "BlueOak-1.0.0",
"dependencies": {
- "brace-expansion": "^5.0.5"
+ "brace-expansion": "^5.0.8"
},
"engines": {
"node": "18 || 20 || >=22"
@@ -9178,9 +9236,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.22",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.22.tgz",
- "integrity": "sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==",
+ "version": "8.5.25",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz",
+ "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==",
"funding": [
{
"type": "opencollective",
@@ -9314,13 +9372,13 @@
"license": "MIT"
},
"node_modules/profile-pane": {
- "version": "3.2.3-3",
- "resolved": "https://registry.npmjs.org/profile-pane/-/profile-pane-3.2.3-3.tgz",
- "integrity": "sha512-sT/gcJInMlLTtLWrbmeoWFjIPKbfL6OWSVqASVYuBe6Nyb0x6GmVLkBNsBmDrdrJNqVyzVfE9KMAukXc4KEIaQ==",
+ "version": "3.2.3-4",
+ "resolved": "https://registry.npmjs.org/profile-pane/-/profile-pane-3.2.3-4.tgz",
+ "integrity": "sha512-mtbOfS37mFazMu+3h0YaUP4BMqVvzAB4Mvlt9jivl41XQIBxulKP+xhKw2GSI6A4wGs9SIMa8JB7ykQJqiC1bg==",
"license": "MIT",
"dependencies": {
"@solid-data-modules/contacts-rdflib": "^0.7.1",
- "chat-pane": "3.0.4-2",
+ "chat-pane": "3.0.4-3",
"lit-html": "^3.3.3",
"pane-registry": "3.1.2-2",
"patch-package": "^8.0.1",
@@ -9800,14 +9858,14 @@
}
},
"node_modules/rolldown": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.0.tgz",
- "integrity": "sha512-u7tgm5l4Yw1iTqUL4EcYOAt7fFvCgQMLeidrnD4GALlC6aOznCjezYajgxeyKw27u0Q5N7fwgCzjVyPIWzwuBA==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.1.tgz",
+ "integrity": "sha512-4FKJhg8d3OiyQOA6Q1Q0hoFFpW9/OoX+VsHzpECsdsIZoOArrAK90gl59YK/Z+gnDel45bgJZK03ozH/9bCqEw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
- "@oxc-project/types": "=0.140.0",
+ "@oxc-project/types": "=0.142.0",
"@rolldown/pluginutils": "^1.0.0"
},
"bin": {
@@ -9817,21 +9875,21 @@
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.2.0",
- "@rolldown/binding-darwin-arm64": "1.2.0",
- "@rolldown/binding-darwin-x64": "1.2.0",
- "@rolldown/binding-freebsd-x64": "1.2.0",
- "@rolldown/binding-linux-arm-gnueabihf": "1.2.0",
- "@rolldown/binding-linux-arm64-gnu": "1.2.0",
- "@rolldown/binding-linux-arm64-musl": "1.2.0",
- "@rolldown/binding-linux-ppc64-gnu": "1.2.0",
- "@rolldown/binding-linux-s390x-gnu": "1.2.0",
- "@rolldown/binding-linux-x64-gnu": "1.2.0",
- "@rolldown/binding-linux-x64-musl": "1.2.0",
- "@rolldown/binding-openharmony-arm64": "1.2.0",
- "@rolldown/binding-wasm32-wasi": "1.2.0",
- "@rolldown/binding-win32-arm64-msvc": "1.2.0",
- "@rolldown/binding-win32-x64-msvc": "1.2.0"
+ "@rolldown/binding-android-arm64": "1.2.1",
+ "@rolldown/binding-darwin-arm64": "1.2.1",
+ "@rolldown/binding-darwin-x64": "1.2.1",
+ "@rolldown/binding-freebsd-x64": "1.2.1",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.2.1",
+ "@rolldown/binding-linux-arm64-gnu": "1.2.1",
+ "@rolldown/binding-linux-arm64-musl": "1.2.1",
+ "@rolldown/binding-linux-ppc64-gnu": "1.2.1",
+ "@rolldown/binding-linux-s390x-gnu": "1.2.1",
+ "@rolldown/binding-linux-x64-gnu": "1.2.1",
+ "@rolldown/binding-linux-x64-musl": "1.2.1",
+ "@rolldown/binding-openharmony-arm64": "1.2.1",
+ "@rolldown/binding-wasm32-wasi": "1.2.1",
+ "@rolldown/binding-win32-arm64-msvc": "1.2.1",
+ "@rolldown/binding-win32-x64-msvc": "1.2.1"
}
},
"node_modules/safe-array-concat": {
@@ -10238,9 +10296,9 @@
}
},
"node_modules/source-pane": {
- "version": "3.1.1-4",
- "resolved": "https://registry.npmjs.org/source-pane/-/source-pane-3.1.1-4.tgz",
- "integrity": "sha512-MVl65r5eQKpzRdKZz3q2fGTo6vAsl4E3WAKJFOKk9Bu3NdkoLvVr6msvQzPlfhD52+978yfQjPLg/le3JgIhrA==",
+ "version": "3.1.1-5",
+ "resolved": "https://registry.npmjs.org/source-pane/-/source-pane-3.1.1-5.tgz",
+ "integrity": "sha512-pY0ieyRHpBjHRKHVKe7RL6Jv2f0grLuRe7VbiiIeV53FHKN7++dcTL6CKcWX1HYKygiWK7eg/04lRXwIwxYCiA==",
"license": "MIT",
"dependencies": {
"@codemirror/commands": "^6.10.0",
@@ -10261,7 +10319,7 @@
"pane-registry": "3.1.2-2",
"rdflib": "2.4.0",
"solid-logic": "4.0.8-1",
- "solid-ui": "3.1.3-11",
+ "solid-ui": "3.1.3-13",
"vite": "^8.0.16",
"vitest": "^4.0.18",
"vitest-axe": "^0.1.0"
@@ -10613,9 +10671,9 @@
}
},
"node_modules/tinyrainbow": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz",
- "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz",
+ "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
@@ -10903,9 +10961,9 @@
}
},
"node_modules/undici": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz",
- "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz",
+ "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==",
"devOptional": true,
"license": "MIT",
"engines": {
@@ -11308,6 +11366,16 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/vite/node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
+ "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/vite/node_modules/@oxc-project/types": {
"version": "0.139.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz",
diff --git a/package.json b/package.json
index 0488fe62..36967d3c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "solid-panes",
- "version": "4.4.2-4",
+ "version": "4.4.2-5",
"description": "Solid-compatible Panes: applets and views for the mashlib and databrowser",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts",
@@ -58,7 +58,7 @@
"dependencies": {
"@solid/better-simple-slideshow": "^0.1.0",
"activitystreams-pane": "1.0.3-4",
- "chat-pane": "3.0.4-2",
+ "chat-pane": "3.0.4-3",
"contacts-pane": "3.2.1-5",
"dompurify": "^3.4.4",
"folder-pane": "3.1.1-2",
@@ -68,18 +68,12 @@
"meeting-pane": "3.0.3-1",
"mime-types": "^3.0.2",
"pane-registry": "3.1.2-2",
- "profile-pane": "3.2.3-3",
+ "profile-pane": "3.2.3-4",
"rdflib": "2.4.0",
"solid-logic": "4.0.8-1",
"solid-namespace": "^0.5.4",
"solid-ui": "3.1.3-13",
- "source-pane": "3.1.1-4"
- },
- "overrides": {
- "rdflib": "$rdflib",
- "solid-logic": "$solid-logic",
- "solid-ui": "$solid-ui",
- "pane-registry": "$pane-registry"
+ "source-pane": "3.1.1-5"
},
"devDependencies": {
"@iconify/json": "2.2.494",
diff --git a/src/components/navbar/Navbar.styles.css b/src/components/navbar/Navbar.styles.css
new file mode 100644
index 00000000..faf67c84
--- /dev/null
+++ b/src/components/navbar/Navbar.styles.css
@@ -0,0 +1,36 @@
+:host {
+ display: block;
+}
+
+:host(.navbar--hidden) {
+ display: none !important;
+}
+
+.navbar {
+ border: 1px solid var(--color-border, #444);
+ border-radius: 5px;
+ display: flex;
+ background: var(--solid-ui-color-white, #fff);
+ overflow: hidden;
+}
+
+button {
+ padding: 10px 25px;
+ border-bottom: 2px solid transparent;
+ font-weight: 500;
+ font-size: 90%;
+ background: transparent;
+ color: inherit;
+ cursor: pointer;
+}
+
+button.selected,
+button:active,
+button:hover,
+button:focus {
+ border-bottom-color: var(--solid-ui-color-primary, #7C4DFF);
+ border-radius: 0;
+ color: var(--solid-ui-color-primary, #7C4DFF);
+ text-transform: capitalize;
+ background: color-mix(in srgb, currentColor 25%, transparent);
+}
diff --git a/src/components/navbar/Navbar.ts b/src/components/navbar/Navbar.ts
new file mode 100644
index 00000000..c4508171
--- /dev/null
+++ b/src/components/navbar/Navbar.ts
@@ -0,0 +1,51 @@
+import { customElement, WebComponent } from 'solid-ui'
+import { html, TemplateResult } from 'lit'
+import { property } from 'lit/decorators.js'
+
+import 'solid-ui/components/account'
+import 'solid-ui/components/button'
+import 'solid-ui/components/menu-item'
+import 'solid-ui/components/menu'
+import 'solid-ui/components/solid-emblem'
+import '~icons/lucide/help-circle'
+
+import styles from './Navbar.styles.css'
+
+export interface NavbarMenuItem {
+ label: string | TemplateResult
+ selected?: boolean
+ onSelected?(): void
+}
+
+@customElement('solid-panes-navbar')
+export default class Navbar extends WebComponent {
+ static styles = styles
+
+ @property({ type: Array })
+ accessor navbarItems: NavbarMenuItem[] = []
+
+ private selectItem (item: NavbarMenuItem) {
+ this.navbarItems = this.navbarItems.map(menuItem => ({
+ ...menuItem,
+ selected: menuItem === item
+ }))
+ item.onSelected?.()
+ }
+
+ render () {
+ return html`
+
+ `
+ }
+}
diff --git a/src/components/navbar/index.ts b/src/components/navbar/index.ts
new file mode 100644
index 00000000..ded2575b
--- /dev/null
+++ b/src/components/navbar/index.ts
@@ -0,0 +1,4 @@
+import Navbar from './Navbar'
+
+export { Navbar }
+export default Navbar
diff --git a/src/dashboard/homepage.ts b/src/dashboard/homepage.ts
index e52842bd..40e735b9 100644
--- a/src/dashboard/homepage.ts
+++ b/src/dashboard/homepage.ts
@@ -1,12 +1,12 @@
import { Fetcher, IndexedFormula, NamedNode } from 'rdflib'
-import { loadProfileFromURI, getName } from '../profileUtils/ownerProfile'
+import { loadProfileFromURI, getName } from '../utils/webIdUtils'
export async function generateHomepage (
uri: NamedNode,
store: IndexedFormula,
fetcher: Fetcher
): Promise {
- const ownersProfile = await loadProfileFromURI(uri, store, fetcher)
+ const ownersProfile = await loadProfileFromURI(uri)
const name = getName(store, ownersProfile)
const wrapper = document.createElement('div')
diff --git a/src/mainPage/header.ts b/src/mainPage/header.ts
index c2ac2ec8..4b45bb8e 100644
--- a/src/mainPage/header.ts
+++ b/src/mainPage/header.ts
@@ -9,6 +9,8 @@ import '~icons/lucide/folder-open'
import '~icons/lucide/layout-dashboard'
import '~icons/lucide/settings-2'
import '../components/header'
+import { getProfilePaneFromURI, getSocialPaneFromURI, getFolderPanesFromURI } from '../utils/paneUtils'
+import { sym } from 'rdflib'
export async function createHeader (outliner: OutlineManager) {
const existingHeader = document.querySelector('solid-panes-header')
@@ -17,56 +19,72 @@ export async function createHeader (outliner: OutlineManager) {
return existingHeader
}
+ const me = authn.currentUser()
+
const main = document.getElementById('MainContent')
+ const outlineView = document.getElementById('OutlineView')
const tmpContainer = document.createElement('div')
+
+ function hideNavbar () {
+ const navbar = document.querySelector('solid-panes-navbar')
+ if (navbar) {
+ navbar.classList.add('navbar--hidden')
+ }
+ }
+
+ const storagePanes = me ? await getFolderPanesFromURI(me) : []
+ const storageMenuItems: AccountMenuItem[] = storagePanes.map(pane => ({
+ label: html` ${pane.label()}`,
+ async onSelected () {
+ hideNavbar()
+ if (me) {
+ outliner.GotoSubject(sym(window.location.href), true, pane, true, undefined, outlineView, false)
+ }
+ }
+ }))
const menuItems: AccountMenuItem[] = [
{
label: html` Profile`,
- onSelected () {
- const currentUser = authn.currentUser()
-
- if (currentUser) {
- outliner.showDashboard(currentUser, { pane: 'profile' })
+ async onSelected () {
+ hideNavbar()
+ if (me) {
+ const profilePane = await getProfilePaneFromURI(me)
+ outliner.GotoSubject(sym(window.location.href), true, profilePane, true, undefined, outlineView, false)
}
}
},
{
label: html` Friends`,
- onSelected () {
- const currentUser = authn.currentUser()
-
- if (currentUser) {
- outliner.showDashboard(currentUser, { pane: 'social' })
- }
- }
- },
- {
- label: html` Storage`,
- onSelected () {
- const currentUser = authn.currentUser()
-
- if (currentUser) {
- outliner.showDashboard(currentUser, { pane: 'folder' })
+ async onSelected () {
+ hideNavbar()
+ if (me) {
+ const socialPane = await getSocialPaneFromURI(me)
+ outliner.GotoSubject(sym(window.location.href), true, socialPane, true, undefined, outlineView, false)
}
}
},
+ ...storageMenuItems,
{
label: html` Dashboard`,
onSelected () {
- const currentUser = authn.currentUser()
-
- if (currentUser) {
- outliner.showDashboard(currentUser, { pane: 'home' })
+ hideNavbar()
+ if (me) {
+ const pane = outliner.context.session.paneRegistry.byName('home')
+ if (pane) {
+ outliner.GotoSubject(sym(window.location.href), true, pane, true, undefined, outlineView, false)
+ }
}
}
},
{
label: html` Preferences`,
onSelected () {
- const currentUser = authn.currentUser()
-
- if (currentUser) {
- outliner.showDashboard(currentUser, { pane: 'basicPreferences' })
+ hideNavbar()
+ if (me) {
+ const pane = outliner.context.session.paneRegistry.byName('basicPreferences')
+ if (pane) {
+ outliner.GotoSubject(sym(window.location.href), true, pane, true, undefined, outlineView, false)
+ }
}
}
},
diff --git a/src/mainPage/index.ts b/src/mainPage/index.ts
index e19cd646..bf0030c5 100644
--- a/src/mainPage/index.ts
+++ b/src/mainPage/index.ts
@@ -7,6 +7,9 @@ import { LiveStore, NamedNode } from 'rdflib'
import type { RenderEnvironment } from 'pane-registry'
import { getOutliner, OutlineManager } from '../index'
import { createHeader } from './header'
+import { createNavbar } from './navbar'
+import { getProfilePaneFromURI } from '../utils/paneUtils'
+import { isWebIdUri } from '../utils/webIdUtils'
// Symbol used to stash the last render-relevant env snapshot on the outliner
// so refreshUI can skip a full GotoSubject re-render when nothing changed.
@@ -40,10 +43,16 @@ export async function initMainPage (
;(outliner as any)[LAST_RENDER_ENV_KEY] = renderEnvSignature(environment)
uri = uri || window.location.href
const subject: NamedNode = typeof uri === 'string' ? store.sym(uri) : uri
- outliner.GotoSubject(subject, true, undefined, true, undefined)
+ const historyPane = window.history.state?.paneName
+ const initialPane = !historyPane && isWebIdUri(subject)
+ ? await getProfilePaneFromURI(subject)
+ : undefined
+
+ outliner.GotoSubject(subject, true, initialPane, true, undefined)
const header = await createHeader(outliner)
- return Promise.all([header])
+ const navbar = await createNavbar(outliner)
+ return Promise.all([header, navbar])
}
export async function refreshUI (outliner: OutlineManager) {
diff --git a/src/mainPage/navbar.ts b/src/mainPage/navbar.ts
new file mode 100644
index 00000000..d04152f3
--- /dev/null
+++ b/src/mainPage/navbar.ts
@@ -0,0 +1,114 @@
+import { store } from 'solid-logic'
+import { NamedNode } from 'rdflib'
+import { getSocialPaneFromURI, getProfilePaneFromURI, getFolderPanesFromURI } from '../utils/paneUtils'
+import { html, render } from 'lit-html'
+import type { OutlineManager } from '../outline/manager'
+import { isWebIdUri, loadProfileFromURI } from '../utils/webIdUtils'
+
+import '~icons/lucide/user'
+import '~icons/lucide/users'
+import '~icons/lucide/folder-open'
+import '../components/navbar'
+
+import type { NavbarMenuItem } from '../components/navbar/Navbar'
+
+function showNavbar () {
+ const navbar = document.querySelector('solid-panes-navbar')
+ if (navbar) {
+ navbar.classList.remove('navbar--hidden')
+ }
+}
+
+function createNavItem (
+ label: string,
+ onSelected: () => void,
+ selected = false
+): NavbarMenuItem {
+ return {
+ label,
+ onSelected () {
+ showNavbar()
+ return onSelected()
+ },
+ selected
+ }
+}
+
+async function createNavbarMenuItems (
+ outliner: OutlineManager,
+ subject: NamedNode,
+ outlineView: HTMLElement | null,
+ selectedPaneName?: string
+): Promise {
+ const webId = await loadProfileFromURI(subject)
+ const selectedPane = selectedPaneName || (isWebIdUri(subject) ? 'profile' : undefined)
+
+ const menuItems: NavbarMenuItem[] = []
+
+ if (webId) {
+ menuItems.push(
+ createNavItem('Profile', async () => {
+ const profilePane = await getProfilePaneFromURI(webId)
+ outliner.GotoSubject(subject, true, profilePane, true, undefined, outlineView)
+ }, selectedPane === 'profile'),
+ createNavItem('Friends', async () => {
+ const socialPane = await getSocialPaneFromURI(webId)
+ outliner.GotoSubject(subject, true, socialPane, true, undefined, outlineView)
+ }, selectedPane === 'social')
+ )
+ }
+
+ const storagePanes = await getFolderPanesFromURI(subject)
+ storagePanes.forEach(pane => {
+ menuItems.push(
+ createNavItem(
+ pane.label(),
+ async () => {
+ outliner.GotoSubject(subject, true, pane, true, undefined, outlineView)
+ },
+ selectedPane === pane.paneName
+ )
+ )
+ })
+
+ return menuItems
+}
+
+export async function createNavbar (outliner: OutlineManager) {
+ const existingNavbar = document.querySelector('solid-panes-navbar')
+
+ if (existingNavbar) {
+ existingNavbar.classList.remove('navbar--hidden')
+ return existingNavbar
+ }
+
+ const OutlineView = document.getElementById('OutlineView')
+ const mainContent = document.getElementById('MainContent')
+ const tmpContainer = document.createElement('div')
+ const uri = window.location.href
+ const subject: NamedNode = typeof uri === 'string' ? store.sym(uri) : uri
+ const selectedPaneName = window.history.state?.paneName
+ const menuItems = await createNavbarMenuItems(outliner, subject, OutlineView, selectedPaneName).catch((err) => {
+ console.error('Failed to build navbar menu items:', err)
+ return []
+ })
+
+ render(
+ html``,
+ tmpContainer
+ )
+
+ const navbar = tmpContainer.firstElementChild as HTMLElement | null
+
+ if (!navbar) {
+ throw new Error('Failed to create nav bar')
+ }
+
+ if (mainContent) {
+ mainContent.insertBefore(navbar, mainContent.firstChild)
+ } else {
+ document.body.prepend(navbar)
+ }
+
+ return navbar
+}
diff --git a/src/outline/manager.css b/src/outline/manager.css
index c1da1ff7..8cfc5614 100644
--- a/src/outline/manager.css
+++ b/src/outline/manager.css
@@ -68,11 +68,12 @@
}
.tdFlex {
- margin: var(--spacing-xxxs, 0.2rem);
- border: none;
- padding: 0;
+ border: 1px solid var(--color-border, #444);
+ border-radius: 5px;
vertical-align: top;
display: flex;
justify-content: space-between;
flex-direction: row;
+ background: var(--solid-ui-color-white, #fff);
+ overflow: hidden;
}
diff --git a/src/outline/manager.js b/src/outline/manager.js
index 124de4ca..a764f190 100644
--- a/src/outline/manager.js
+++ b/src/outline/manager.js
@@ -6,26 +6,17 @@ import * as paneRegistry from 'pane-registry'
import './manager.css'
import * as $rdf from 'rdflib'
import * as UI from 'solid-ui'
-import { authn, authSession, store } from 'solid-logic'
+import { store } from 'solid-logic'
import { propertyViews } from './propertyViews'
import { outlineIcons } from './outlineIcons.js' // @@ chec
import { UserInput } from './userInput.js'
import * as queryByExample from './queryByExample.js'
-import { getNameOfPodOwner } from '../profileUtils/ownerProfile'
+import { loadContainerRepresentation } from '../utils/podUtils'
import personIcon from '../icons/person.svg'
import friendsIcon from '../icons/friends.svg'
-import folderIcon from '../icons/folder.svg'
-import dashboardIcon from '../icons/dashboard.svg'
const PERSON_ICON = personIcon
const FRIENDS_ICON = friendsIcon
-const FOLDER_ICON = folderIcon
-const DASHBOARD_ICON = dashboardIcon
-
-/* global alert XPathResult sourceWidget */
-// XPathResult?
-
-// const iconHeight = '24px'
export default function (context) {
const dom = context.dom
@@ -311,259 +302,19 @@ export default function (context) {
return predicateTD
} // outlinePredicateTD
- /**
- * Render Tabbed set of home app panes
- *
- * @param {Object} [options] A set of options you can provide
- * @param {string} [options.selectedTab] To open a specific dashboard pane
- * @param {Function} [options.onClose] If given, will present an X for the dashboard, and call this method when clicked
- * @returns Promise<{Element}> - the div that holds the dashboard
- */
- async function globalAppTabs (options = {}) {
- console.log('globalAppTabs @@')
- const div = dom.createElement('div')
- const me = authn.currentUser()
- if (!me) {
- alert('Must be logged in for this')
- throw new Error('Not logged in')
- }
- const items = await getDashboardItems()
-
- const selectedItem = options.selectedTab
- ? items.find(
- item => item.paneName === options.selectedTab || item.tabName === options.selectedTab
- )
- : items[0]
-
- if (!selectedItem) {
- return div
- }
-
- div.dataset.globalPaneName = selectedItem.tabName || selectedItem.paneName
-
- const content = div.appendChild(dom.createElement('div'))
- const pane = paneRegistry.byName(selectedItem.paneName) // 20190701
- const table = content.appendChild(dom.createElement('table'))
- thisOutline.GotoSubject(
- selectedItem.subject || me,
- true,
- pane,
- false,
- undefined,
- table
- )
-
- return div
- }
- this.getDashboard = globalAppTabs
-
- async function getDashboardItems () {
- const me = authn.currentUser()
- if (!me) return []
- const div = dom.createElement('div')
- const panes = [
- {
- paneName: 'profile',
- subject: me,
- label: 'Your profile',
- icon: PERSON_ICON
- },
- {
- paneName: 'social', // loads socialPane
- subject: me,
- label: 'Your friends',
- icon: FRIENDS_ICON
- }
- ]
-
- const [pods] = await Promise.all([getPods()])
-
- panes.push(...pods)
-
- panes.push(
- /* not in use since redesign of profile-pane
- {
- paneName: 'editProfile',
- label: 'Edit your Profile',
- icon: UI.icons.iconBase + 'noun_492246.svg'
- },
- */
- {
- paneName: 'home',
- label: 'Your dashboard',
- icon: DASHBOARD_ICON
- },
- {
- paneName: 'basicPreferences',
- label: 'Your preferences',
- icon: UI.icons.iconBase + 'noun_Sliders_341315_000000.svg'
- }
- )
-
- return panes
-
- async function getPods () {
- async function addPodStorage (pod) { // namedNode
- await loadContainerRepresentation(pod)
- if (kb.holds(pod, ns.rdf('type'), ns.space('Storage'), pod.doc())) {
- pods.push(pod)
- return true
- }
- return false
- }
- async function addPodStorageFromUrl (url) {
- const podStorage = new URL(url)
- // check for predicate pim:Storage in containers up the path tree
- let pathStorage = podStorage.pathname
- while (pathStorage.length) {
- pathStorage = pathStorage.substring(0, pathStorage.lastIndexOf('/'))
- if (await addPodStorage(kb.sym(`${podStorage.origin}${pathStorage}/`))) return
- }
- // TODO should url.origin be added to pods list when there are no pim:Storage ???
- }
-
- try {
- // need to make sure that profile is loaded
- await kb.fetcher.load(me.doc())
- } catch (err) {
- console.error('Unable to load profile', err)
- return []
- }
- // load pod's storages from profile
- let pods = kb.each(me, ns.space('storage'), null, me.doc())
- await Promise.all(
- pods.map(async (pod) => {
- // TODO use addPodStorageFromUrl(pod.uri) to check for pim:Storage ???
- await loadContainerRepresentation(pod)
- })
- )
-
- try {
- // if uri then SolidOS is a browse.html web app
- const uri = (new URL(window.location.href)).searchParams.get('uri')
- const podUrl = uri || window.location.href
- await addPodStorageFromUrl(podUrl)
- } catch (err) {
- console.error('cannot load container', err)
- }
- // remove namedNodes duplicates
- function uniques (nodes) {
- const uniqueNodes = []
- nodes.forEach(node => {
- if (!uniqueNodes.find(uniqueNode => uniqueNode.equals(node))) uniqueNodes.push(node)
- })
- return uniqueNodes
- }
- pods = uniques(pods)
- if (!pods.length) return []
- return Promise.all(
- pods.map(async (pod, index) => {
- function split (item) { return item.uri.split('//')[1].slice(0, -1) }
- const ownerName = (await getNameOfPodOwner(pod, kb, sf)) || ''
- const label = split(me).startsWith(split(pod))
- ? 'Your storage'
- : ownerName.trim() !== ''
- ? ownerName + '\'s storage'
- : split(pod)
- return {
- paneName: 'folder',
- tabName: `folder-${index}`,
- label,
- subject: pod,
- icon: FOLDER_ICON
- }
- })
- )
- }
-
- async function getAddressBooks () {
- try {
- const context = await UI.login.findAppInstances(
- { me, div, dom },
- ns.vcard('AddressBook')
- )
- return (context.instances || []).map((book, index) => ({
- paneName: 'contact',
- tabName: `contact-${index}`,
- label: 'Contacts',
- subject: book,
- icon: UI.icons.iconBase + 'noun_15695.svg'
- }))
- } catch (err) {
- console.error('oops in globalAppTabs AddressBook')
- }
- return []
- }
- }
- this.getDashboardItems = getDashboardItems
-
- /**
- * Call this method to show the global dashboard.
- *
- * @param {Object} [options] A set of options that can be passed
- * @param {string} [options.pane] To open a specific dashboard pane
- * @returns {Promise}
- */
- function closeDashboard () {
- const dashboardContainer = getDashboardContainer()
- const outlineContainer = getOutlineContainer()
- dashboardContainer.innerHTML = ''
- hideGlobalContainer(dashboardContainer)
- showGlobalContainer(outlineContainer)
- }
-
- // Register the closeDashboard listener only once
- authSession.events.on('logout', closeDashboard)
-
- function showGlobalContainer (container) {
- container.removeAttribute('hidden')
- container.style.display = ''
+ function getOutlineContainer () {
+ return getOrCreateContainer('OutlineView', 'Resource browser')
}
- function hideGlobalContainer (container) {
- container.setAttribute('hidden', '')
- container.style.display = 'none'
+ function getNavbarElement () {
+ return document.querySelector('solid-panes-navbar')
}
- async function showDashboard (subject, options = {}) {
- const dashboardContainer = getDashboardContainer()
- const outlineContainer = getOutlineContainer()
-
- // reuse existing dashboard if already rendered for the same pane and subject
- if (dashboardContainer.childNodes.length > 0) {
- const existingDashboard = dashboardContainer.firstElementChild
- if (
- existingDashboard &&
- options.pane &&
- existingDashboard.dataset.globalPaneName === options.pane &&
- existingDashboard.dataset.subject === ((subject && subject.value) || '')
- ) {
- hideGlobalContainer(outlineContainer)
- showGlobalContainer(dashboardContainer)
- return
- }
- dashboardContainer.innerHTML = ''
+ function showSolidPanesNavbar () {
+ const navbar = getNavbarElement()
+ if (navbar) {
+ navbar.classList.remove('navbar--hidden')
}
-
- // create a new dashboard if not already present
- const dashboard = await globalAppTabs({
- selectedTab: options.pane,
- // onClose: closeDashboard
- })
-
- // finally - switch to showing dashboard
- hideGlobalContainer(outlineContainer)
- showGlobalContainer(dashboardContainer)
- dashboardContainer.appendChild(dashboard)
- }
- this.showDashboard = showDashboard
-
- function getDashboardContainer () {
- return getOrCreateContainer('GlobalDashboard', 'Dashboard')
- }
-
- function getOutlineContainer () {
- return getOrCreateContainer('OutlineView', 'Resource browser')
}
/**
@@ -575,9 +326,7 @@ export default function (context) {
*/
function getOrCreateContainer (id) {
const containerHost =
- document.getElementById('app-view') ||
document.getElementById('MainContent') ||
- document.querySelector('[role="main"]') ||
document.body
// OutlineView is a table
@@ -587,6 +336,10 @@ export default function (context) {
return existingOutline
}
+ const containerHost =
+ document.getElementById('MainContent') ||
+ document.body
+
if (containerHost) {
const OutlineView = document.createElement('table')
OutlineView.id = 'OutlineView'
@@ -596,27 +349,6 @@ export default function (context) {
return OutlineView
}
}
-
- // or we deal with the section GlobalDashboard
- return (
- document.getElementById(id) ||
- (() => {
- const GlobalDashboard = document.createElement('section')
- GlobalDashboard.id = id
- GlobalDashboard.setAttribute('aria-label', 'Dashboard')
- GlobalDashboard.classList.add('global-dashboard')
- return containerHost.appendChild(GlobalDashboard)
- })()
- )
- }
-
- async function loadContainerRepresentation (subject) {
- // force reload for index.html with RDFa
- if (!kb.any(subject, ns.ldp('contains'), undefined, subject.doc())) {
- const response = await kb.fetcher.webOperation('GET', subject.uri, kb.fetcher.initFetchOptions(subject.uri, { headers: { accept: 'text/turtle' } }))
- const containerTurtle = response.responseText
- $rdf.parse(containerTurtle, kb, subject.uri, 'text/turtle')
- }
}
async function getRelevantPanes (subject, context) {
@@ -652,7 +384,17 @@ export default function (context) {
}
async function expandedHeaderTR (subject, requiredPane, options) {
+ async function determineFirstPane (options = {}) {
+ const relevantPanes = options.hideList
+ ? []
+ : await getRelevantPanes(subject, context)
+ tr.firstPane = requiredPane || getPane(relevantPanes, subject)
+ }
+
async function renderPaneIconTray (td, options = {}) {
+ // Icon tray removed: this UI is no longer needed.
+ // The tray previously populated pane selection buttons,
+ // but pane selection itself is retained via tr.firstPane.
const paneShownStyle =
'width: 24px; border-radius: 0.5em; border-top: solid #222 1px; border-left: solid #222 0.1em; border-bottom: solid #eee 0.1em; border-right: solid #eee 0.1em; margin-left: 1em; padding: 3px; background-color: #ffd;'
const paneHiddenStyle =
@@ -813,12 +555,7 @@ export default function (context) {
tr.setAttribute('class', 'hoverControl')
}
const td = tr.appendChild(dom.createElement('td'))
- td.setAttribute(
- 'style',
- 'margin: 0.2em; border: none; padding-top: 0; padding-bottom: 0; vertical-align: top;' +
- 'display:flex; justify-content: space-between; flex-direction: row;' +
- 'background-color: var(--color-background, #F8F9FB);'
- )
+ td.classList.add('tdFlex')
td.setAttribute('notSelectable', 'true')
td.setAttribute('about', subject.toNT())
td.setAttribute('colspan', '2')
@@ -847,21 +584,29 @@ export default function (context) {
'font-size: 150%; margin: 0 0.6em 0 0; padding: 0.1em 0.4em;' +
'background-color: var(--color-background, #F8F9FB);'
UI.widgets.makeDraggable(strong, subject)
+
+ header.appendChild(
+ await renderPaneIconTray(td, {
+ hideList: showHeader
+ })
+ )
}
- header.appendChild(
- await renderPaneIconTray(td, {
- hideList: showHeader
- })
- )
+ // Pane icon tray removed: preserve first-pane selection without rendering the tray.
+ await determineFirstPane({ hideList: showHeader })
- // set DOM methods
+ // Hide the header row when the header div has no rendered children.
+ if (header.childNodes.length === 0) {
+ tr.style.display = 'none'
+ }
+
+ /* // set DOM methods
tr.firstChild.tabulatorSelect = function () {
setSelected(this, true)
}
tr.firstChild.tabulatorDeselect = function () {
setSelected(this, false)
- }
+ } */
return tr
} // expandedHeaderTR
@@ -1261,64 +1006,6 @@ export default function (context) {
// Summarize a thing as a table cell
- /**********************
-
- query global vars
-
- ***********************/
-
- // const doesn't work in Opera
- // const BLANK_QUERY = { pat: kb.formula(), vars: [], orderBy: [] };
- // @ pat: the query pattern in an RDFIndexedFormula. Statements are in pat.statements
- // @ vars: the free variables in the query
- // @ orderBy: the variables to order the table
-
- function QueryObj () {
- this.pat = kb.formula()
- this.vars = []
- // this.orderBy = []
- }
-
- const queries = []
- queries[0] = new QueryObj()
- /*
- function querySave () {
- queries.push(queries[0])
- var choices = dom.getElementById('queryChoices')
- var next = dom.createElement('option')
- var box = dom.createElement('input')
- var index = queries.length - 1
- box.setAttribute('type', 'checkBox')
- box.setAttribute('value', index)
- choices.appendChild(box)
- choices.appendChild(dom.createTextNode('Saved query #' + index))
- choices.appendChild(dom.createElement('br'))
- next.setAttribute('value', index)
- next.appendChild(dom.createTextNode('Saved query #' + index))
- dom.getElementById('queryJump').appendChild(next)
- }
-*/
- /*
- function resetQuery () {
- function resetOutliner (pat) {
- var n = pat.statements.length
- var pattern, tr
- for (let i = 0; i < n; i++) {
- pattern = pat.statements[i]
- tr = pattern.tr
- // UI.log.debug('tr: ' + tr.AJAR_statement);
- if (typeof tr !== 'undefined') {
- delete tr.AJAR_pattern
- delete tr.AJAR_variable
- }
- }
- for (let x in pat.optional) { resetOutliner(pat.optional[x]) }
- }
- resetOutliner(myQuery.pat)
- UI.utils.clearVariableNames()
- queries[0] = myQuery = new QueryObj()
- }
-*/
function addButtonCallbacks (target, fireOn) {
UI.log.debug('Button callbacks for ' + fireOn + ' added')
const makeIconCallback = function (icon) {
@@ -1434,6 +1121,8 @@ export default function (context) {
}
}
+ /* global alert XPathResult sourceWidget */
+
this.showSource = function showSource () {
if (typeof sourceWidget === 'undefined') return
// deselect all before going on, this is necessary because you would switch tab,
@@ -1795,28 +1484,6 @@ export default function (context) {
} // end of switch
showURI(UI.utils.getAbout(kb, selection[0]))
- // alert(window);alert(doc);
- /*
- var wm = Components.classes['@mozilla.org/appshell/window-mediator;1']
- .getService(Components.interfaces.nsIWindowMediator);
- var gBrowser = wm.getMostRecentWindow('navigator:browser') */
- // gBrowser.addTab('http://www.w3.org/');
- // alert(gBrowser.addTab);alert(gBrowser.scroll);alert(gBrowser.scrollBy)
- // gBrowser.scrollBy(0,100);
-
- // var thisHtml=selection[0].owner
- if (selection[0]) {
- const PosY = UI.utils.findPos(selection[0])[1]
- if (
- PosY + selection[0].clientHeight >
- window.scrollY + window.innerHeight
- ) {
- UI.utils.getEyeFocus(selection[0], true, true, window)
- }
- if (PosY < window.scrollY + 54) {
- UI.utils.getEyeFocus(selection[0], true, undefined, window)
- }
- }
}
this.OutlinerMouseclickPanel = function (e) {
switch (thisOutline.UserInput._tabulatorMode) {
@@ -2352,15 +2019,21 @@ export default function (context) {
/** Display the subject in an outline view
- @param subject -- RDF term for teh thing to be presented
+ @param subject -- RDF term for the thing to be presented
@param expand -- flag -- open the subject rather than keep folded closed
@param pane -- optional -- pane to be used for expanded display
@param solo -- optional -- the window will be cleared out and only the subject displayed
@param referer -- optional -- where did we hear about this from anyway?
@param table -- option -- default is an HTML table element in which to put the outline.
+ @param showNavbar -- optional -- when false, suppress automatic navbar reveal
*/
- this.GotoSubject = function (subject, expand, pane, solo, referrer, table) {
- table = table || getOutlineContainer('OutlineView') // if does not exist create a compatible host in the current shell
+ this.GotoSubject = function (subject, expand, pane, solo, referrer, table, showNavbar = true) {
+ const outlineContainer = getOutlineContainer()
+ if (showNavbar && (!table || table === outlineContainer)) {
+ showSolidPanesNavbar()
+ }
+
+ table = table || outlineContainer // if does not exist create a compatible host in the current shell
if (solo) {
UI.utils.emptyNode(table)
table.style.width = '100%'
@@ -2420,8 +2093,6 @@ export default function (context) {
//
// / /////////////////////////////////////////////////////
- const ns = UI.ns
-
const views = propertyViews(dom)
// var thisOutline = this dup
diff --git a/src/profileUtils/ownerProfile.ts b/src/profileUtils/ownerProfile.ts
deleted file mode 100644
index 57c9c348..00000000
--- a/src/profileUtils/ownerProfile.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-* Utility functions to help load the profile
-* especially when I am not logged in
-*/
-
-import { Fetcher, IndexedFormula, NamedNode, sym } from 'rdflib'
-import { ns } from 'solid-ui'
-
-const DEFAULT_PROFILE_PATH = 'profile/card#me'
-
-export async function loadProfileFromURI (
- uri: NamedNode,
- store: IndexedFormula,
- fetcher: Fetcher
-): Promise {
- const pod = uri.site().uri
- // TODO: This is a hack - we cannot assume that the profile is at this document, but we will live with it for now
- const webId = sym(`${pod}${DEFAULT_PROFILE_PATH}`)
- try {
- await fetcher.load(webId)
- return webId
- } catch (err) {
- // continue
- }
-
- // we try a prefixed pod structure
- try {
- const uriUrl = new URL(uri.uri)
- const pathSegments = uriUrl.pathname.split('/').filter(Boolean)
- if (pathSegments.length > 0) {
- const derivedPod = `${uriUrl.origin}/${pathSegments[0]}/`
- const derivedWebId = sym(`${derivedPod}${DEFAULT_PROFILE_PATH}`)
- await fetcher.load(derivedWebId)
- return derivedWebId
- }
- } catch (err) {
- // continue
- }
-
- try {
- await fetcher.load(uri)
- } catch (err) {
- return uri
- }
-
- const primaryTopic = store.any(uri, ns.foaf('primaryTopic'), null, uri.doc())
- if (primaryTopic && primaryTopic.termType === 'NamedNode') {
- try {
- await fetcher.load(primaryTopic as NamedNode)
- return primaryTopic as NamedNode
- } catch (err) {
- return uri
- }
- }
-
- return uri
-}
-
-export async function getNameOfPodOwner (
- pod: NamedNode,
- store: IndexedFormula,
- fetcher: Fetcher
-): Promise {
- // TODO: This is a hack - we cannot assume that the profile is at this document, but we will live with it for now
- const webId = sym(`${pod.uri}${DEFAULT_PROFILE_PATH}`)
- try {
- await fetcher.load(webId)
- return getName(store, webId)
- } catch (err) {
- // continue
- }
-
- // we try a prefixed pod structure
- try {
- const uriUrl = new URL(pod.uri)
- const pathSegments = uriUrl.pathname.split('/').filter(Boolean)
- if (pathSegments.length > 0) {
- const derivedPod = `${uriUrl.origin}/${pathSegments[0]}/`
- const derivedWebId = sym(`${derivedPod}${DEFAULT_PROFILE_PATH}`)
- await fetcher.load(derivedWebId)
- return getName(store, derivedWebId)
- }
- } catch (err) {
- // continue
- }
-
- return ''
-}
-
-export function getName (store: IndexedFormula, ownersProfile: NamedNode): string {
- return (
- store.anyValue(ownersProfile, ns.vcard('fn'), null, ownersProfile.doc()) ||
- store.anyValue(ownersProfile, ns.foaf('name'), null, ownersProfile.doc()) ||
- new URL(ownersProfile.uri).host.split('.')[0]
- )
-}
diff --git a/src/social/socialPane.css b/src/social/socialPane.css
index 8a49b846..054dd9db 100644
--- a/src/social/socialPane.css
+++ b/src/social/socialPane.css
@@ -9,7 +9,7 @@
min-width: 100%;
box-sizing: border-box;
max-width: none;
- margin: 0;
+ margin-top: 20px;
}
.social-pane__header-content {
@@ -982,12 +982,6 @@
/* From tabbedtab.css */
/* ***************** Social Pane **********/
-div.social-pane {
- padding-top: 0;
- padding-bottom: 0;
- margin: 0;
-}
-
.social-pane a {
color: var(--color-primary, #7C4DFF);
text-decoration: none;
diff --git a/src/utils/paneUtils.ts b/src/utils/paneUtils.ts
new file mode 100644
index 00000000..6e23026b
--- /dev/null
+++ b/src/utils/paneUtils.ts
@@ -0,0 +1,95 @@
+import * as paneRegistry from 'pane-registry'
+import folderIcon from '../icons/folder.svg'
+import personIcon from '../icons/person.svg'
+import friendsIcon from '../icons/friends.svg'
+import { loadProfileFromURI } from './webIdUtils'
+import { getPodStorages } from './podUtils'
+import { NamedNode, sym } from 'rdflib'
+
+const FOLDER_ICON = folderIcon
+const PERSON_ICON = personIcon
+const FRIENDS_ICON = friendsIcon
+
+export type PaneItem = {
+ name: string
+ paneName: string
+ tabName?: string
+ label: () => string
+ render: (subject: NamedNode, context: any, options: any) => any
+ shouldGetFocus: () => boolean
+ requireQueryButton: boolean
+ subject: NamedNode
+ icon: string
+}
+
+export function createPaneItem (
+ pane: any,
+ subject: NamedNode,
+ paneName: string,
+ labelText: string,
+ icon: string,
+ tabName?: string
+): PaneItem {
+ return {
+ name: pane.name,
+ paneName,
+ tabName,
+ label: function () {
+ return labelText
+ },
+ render: function (_subject, context, options) {
+ return pane.render(subject, context, options)
+ },
+ shouldGetFocus: function () {
+ return false
+ },
+ requireQueryButton: !!pane.requireQueryButton,
+ subject,
+ icon
+ }
+}
+
+export async function getPaneItemFromURI (
+ paneName: string,
+ subject?: NamedNode,
+ labelText = 'Pane',
+ icon = ''
+): Promise {
+ const windowHref = new URL(window.location.href)
+ const finalURL = subject || sym(windowHref.toString())
+ const webId = await loadProfileFromURI(finalURL)
+ if (!webId || !webId.value) return null
+
+ const pane = paneRegistry.byName(paneName)
+ if (!pane) return null
+
+ return createPaneItem(pane, webId, paneName, labelText, icon)
+}
+
+export async function getProfilePaneFromURI (subject?: NamedNode) {
+ return getPaneItemFromURI('profile', subject, 'Profile', PERSON_ICON)
+}
+
+export async function getSocialPaneFromURI (subject?: NamedNode) {
+ return getPaneItemFromURI('social', subject, 'Social', FRIENDS_ICON)
+}
+
+export async function getFolderPaneforStorage (podUrl: NamedNode, label?: string): Promise {
+ const folderPane = paneRegistry.byName('folder')
+ if (!folderPane) return null
+
+ return createPaneItem(folderPane, podUrl, folderPane.name, label || 'Storage', FOLDER_ICON)
+}
+export async function getFolderPanesFromURI (subject: NamedNode): Promise {
+ const podStorages = await getPodStorages(subject)
+ if (podStorages.length === 0) return []
+
+ return Promise.all(
+ podStorages.map((pod, index) =>
+ getFolderPaneforStorage(
+ pod,
+ podStorages.length > 1 ? `Storage ${index + 1}` : 'Storage'
+ )
+ )
+ ).then(panes => panes.filter((pane): pane is PaneItem => pane !== null))
+}
diff --git a/src/utils/podUtils.ts b/src/utils/podUtils.ts
new file mode 100644
index 00000000..aa7b4aaa
--- /dev/null
+++ b/src/utils/podUtils.ts
@@ -0,0 +1,58 @@
+import { store } from 'solid-logic'
+import { ns } from 'solid-ui'
+import { NamedNode, parse } from 'rdflib'
+import { isWebIdUri } from './webIdUtils'
+
+export async function getPodStorages (url: NamedNode): Promise {
+ if (isWebIdUri(url)) {
+ try {
+ await store.fetcher.load(url.doc())
+ } catch (err) {
+ console.warn('Unable to load profile document for WebID', url.doc().uri, err)
+ }
+ const podStorages = store.each(url, ns.space('storage'))
+ const results = await Promise.all(podStorages.map(async pod => await isPodStorage(pod as NamedNode) ? pod as NamedNode : null))
+ return results.filter(pod => pod !== null) as NamedNode[]
+ }
+ try {
+ const storage = await findPodStorageFromUrl(url)
+ return storage ? [storage] : []
+ } catch (err) {
+ console.error('cannot load container', err)
+ return []
+ }
+}
+
+async function findPodStorageFromUrl (url: NamedNode): Promise {
+ const podStorage = new URL(url.value || url.uri)
+ let pathStorage = podStorage.pathname
+
+ while (pathStorage.length) {
+ pathStorage = pathStorage.substring(0, pathStorage.lastIndexOf('/'))
+ const candidate = store.sym(`${podStorage.origin}${pathStorage}/`)
+ if (await isPodStorage(candidate)) return candidate
+ }
+
+ // TODO should url.origin be added to pods list when there are no pim:Storage ???
+ return null
+}
+
+async function isPodStorage (pod: NamedNode): Promise {
+ await loadContainerRepresentation(pod)
+ return store.holds(pod, ns.rdf('type'), ns.space('Storage'), pod.doc())
+}
+
+export async function loadContainerRepresentation (subject) {
+ // force reload for index.html with RDFa
+ if (!store.any(subject, ns.ldp('contains'), undefined, subject.doc())) {
+ try {
+ const response = await store.fetcher.webOperation('GET', subject.uri, store.fetcher.initFetchOptions(subject.uri, { headers: { accept: 'text/turtle' } }))
+ const containerTurtle = response.responseText
+ if (subject.uri && containerTurtle) {
+ parse(containerTurtle, store, subject.uri, 'text/turtle')
+ }
+ } catch (err) {
+ console.warn('Unable to load container representation for', subject.uri, err)
+ }
+ }
+}
diff --git a/src/utils/webIdUtils.ts b/src/utils/webIdUtils.ts
new file mode 100644
index 00000000..a961dcb5
--- /dev/null
+++ b/src/utils/webIdUtils.ts
@@ -0,0 +1,117 @@
+/*
+* Utility functions to help load the profile
+* especially when I am not logged in
+*/
+
+import { IndexedFormula, NamedNode, sym } from 'rdflib'
+import { ns } from 'solid-ui'
+import { store } from 'solid-logic'
+
+const DEFAULT_PROFILE_PATH = 'profile/card#me'
+
+export async function loadProfileFromURI (
+ uri: NamedNode
+): Promise {
+ try {
+ const pod = uri.site().uri
+ // TODO: This is a hack - we cannot assume that the profile is at this document, but we will live with it for now
+ const webId = sym(`${pod}${DEFAULT_PROFILE_PATH}`)
+ try {
+ await store.fetcher.load(webId)
+ return webId
+ } catch (err) {
+ // ignore any failure and continue fallback lookup
+ }
+
+ // we try a prefixed pod structure
+ try {
+ const uriUrl = new URL(uri.uri)
+ const pathSegments = uriUrl.pathname.split('/').filter(Boolean)
+ if (pathSegments.length > 0) {
+ const derivedPod = `${uriUrl.origin}/${pathSegments[0]}/`
+ const derivedWebId = sym(`${derivedPod}${DEFAULT_PROFILE_PATH}`)
+ await store.fetcher.load(derivedWebId)
+ return derivedWebId
+ }
+ } catch (err) {
+ // ignore any failure and continue fallback lookup
+ }
+
+ try {
+ await store.fetcher.load(uri)
+ } catch (err) {
+ return uri
+ }
+
+ const primaryTopic = store.any(uri, ns.foaf('primaryTopic'), null, uri.doc())
+ if (primaryTopic && primaryTopic.termType === 'NamedNode') {
+ try {
+ await store.fetcher.load(primaryTopic as NamedNode)
+ return primaryTopic as NamedNode
+ } catch (err) {
+ return uri
+ }
+ }
+
+ return uri
+ } catch (err) {
+ return uri
+ }
+}
+
+export function isWebIdUri (uri: NamedNode): boolean {
+ try {
+ const parsedURL = new URL(uri.uri)
+ return parsedURL.hash === '#me'
+ } catch (err) {
+ return false
+ }
+}
+
+export async function getNameOfPodOwner (
+ pod: NamedNode
+): Promise {
+ // TODO: This is a hack - we cannot assume that the profile is at this document, but we will live with it for now
+ const webId = sym(`${pod.uri}${DEFAULT_PROFILE_PATH}`)
+ try {
+ await store.fetcher.load(webId)
+ return getName(store, webId)
+ } catch (err) {
+ if (!isFetchErrorStatus(err, 403)) {
+ console.error('getNameOfPodOwner failed on default profile:', err)
+ }
+ }
+
+ // we try a prefixed pod structure
+ try {
+ const uriUrl = new URL(pod.uri)
+ const pathSegments = uriUrl.pathname.split('/').filter(Boolean)
+ if (pathSegments.length > 0) {
+ const derivedPod = `${uriUrl.origin}/${pathSegments[0]}/`
+ const derivedWebId = sym(`${derivedPod}${DEFAULT_PROFILE_PATH}`)
+ await store.fetcher.load(derivedWebId)
+ return getName(store, derivedWebId)
+ }
+ } catch (err) {
+ if (!isFetchErrorStatus(err, 403)) {
+ console.error('getNameOfPodOwner failed on derived profile:', err)
+ }
+ }
+
+ return ''
+}
+
+export function getName (store: IndexedFormula, ownersProfile: NamedNode): string {
+ return (
+ store.anyValue(ownersProfile, ns.vcard('fn'), null, ownersProfile.doc()) ||
+ store.anyValue(ownersProfile, ns.foaf('name'), null, ownersProfile.doc()) ||
+ new URL(ownersProfile.uri).host.split('.')[0]
+ )
+}
+
+function isFetchErrorStatus (err: unknown, status: number): boolean {
+ if (!err || typeof err !== 'object') return false
+ const statusCode = (err as any)?.response?.status ?? (err as any)?.status
+ const parsedStatus = Number(statusCode)
+ return Number.isFinite(parsedStatus) && parsedStatus === status
+}
diff --git a/test/unit/outline/manager.test.ts b/test/unit/outline/manager.test.ts
index 36799e48..6224f5eb 100644
--- a/test/unit/outline/manager.test.ts
+++ b/test/unit/outline/manager.test.ts
@@ -1,9 +1,24 @@
-import { beforeAll, beforeEach, describe, expect, it } from 'vitest'
+import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
+
+vi.mock('solid-ui', async () => {
+ const actual = await vi.importActual('solid-ui')
+ return {
+ ...actual,
+ login: {
+ ...actual.login,
+ filterAvailablePanes: async panes => panes
+ }
+ }
+})
+
import OutlineManager from '../../../src/outline/manager'
import { lit, NamedNode, sym, blankNode } from 'rdflib'
import { findByText, getByText } from '@testing-library/dom'
const MockPane = {
+ name: 'mock',
+ icon: 'data:image/svg+xml,',
+ label: () => 'Mock Pane',
render: (subject: NamedNode) => {
const div = document.createElement('div')
div.appendChild(document.createTextNode(`Mock Pane for ${subject.uri}`))
@@ -12,10 +27,11 @@ const MockPane = {
}
const mockPaneRegistry = {
- list: [],
+ list: [MockPane],
byName: () => MockPane
}
+
describe('manager', () => {
describe('outline object td', () => {
describe('for a named node', () => {
diff --git a/vite.config.mts b/vite.config.mts
index b8ff98ea..03829748 100644
--- a/vite.config.mts
+++ b/vite.config.mts
@@ -1,11 +1,54 @@
import { fileURLToPath } from 'node:url'
+import type { PluginOption } from 'vite'
import { solidPane, buildConfig } from 'solidos-toolkit/vite'
import { defineConfig } from 'vitest/config'
-export default defineConfig({
- build: buildConfig({
- entry: "src/index.ts",
+// `vite build --watch` re-runs every plugin's generateBundle on each change.
+// solidos-toolkit's solidPane() bundles unplugin-dts (adds ~4-5s per rebuild)
+// and buildConfig() emits both ESM and CJS outputs (two rebuild cycles per
+// change — noisy for downstream watchers like mashlib/webpack). During watch
+// we strip both so the inner loop is fast and downstream sees a single wave
+// of file writes. Full builds (npm run build) are unaffected.
+const isWatch = process.argv.includes('--watch')
+
+const build = buildConfig({ entry: 'src/index.ts' })
+if (isWatch && build && Array.isArray(build.rolldownOptions?.output)) {
+ build.rolldownOptions.output = build.rolldownOptions.output.filter(
+ (o: { format?: string }) => o.format === 'es',
+ )
+}
+
+type ConcretePlugin = Extract
+
+// solidPane() returns a nested plugin array that includes an ASYNC plugin
+// factory (@rolldown/plugin-babel is a Promise). The previous flatten helper
+// dropped Promise entries, which silently removed the babel plugin — leaving
+// TC39 decorator / `accessor` syntax in the built output (Header.esm.js etc.)
+// and breaking downstream consumers (mashlib's babel-loader). Await Promises
+// before flattening so every plugin makes it into the final list.
+const flattenPlugins = async (input: unknown): Promise => {
+ if (!input) return []
+ const resolved = await input
+ if (!resolved) return []
+ if (Array.isArray(resolved)) {
+ const nested = await Promise.all(resolved.map(flattenPlugins))
+ return nested.flat()
+ }
+ return [resolved as ConcretePlugin]
+}
+
+const plugins = (await flattenPlugins(
+ solidPane({
+ litDecoratorPaths: ['src/components'],
+ sandbox: {
+ subject: 'https://testingsolidos.solidcommunity.net/profile/card#me',
+ entry: './src/dev.ts',
+ },
}),
+)).filter((p) => !(isWatch && /dts/i.test(p.name)))
+
+export default defineConfig({
+ build,
resolve: {
tsconfigPaths: true,
@@ -17,13 +60,7 @@ export default defineConfig({
UI: fileURLToPath(new URL('./node_modules/solid-ui/dist/index.esm.js', import.meta.url)),
},
},
- plugins: solidPane({
- litDecoratorPaths: ['src/components'],
- sandbox: {
- subject: "https://testingsolidos.solidcommunity.net/profile/card#me",
- entry: "./src/dev.ts",
- }
- }),
+ plugins,
test: {
environment: 'jsdom',
setupFiles: ['test/setup.ts'],