Merge branch 'TriliumNext:develop' into develop

This commit is contained in:
Joel Shprentz 2025-06-15 22:12:08 -04:00 committed by GitHub
commit f2e4dad318
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
78 changed files with 3089 additions and 964 deletions

1
.env
View File

@ -1 +0,0 @@
NODE_OPTIONS=--max_old_space_size=4096

View File

@ -39,7 +39,7 @@ jobs:
- uses: nrwl/nx-set-shas@v4 - uses: nrwl/nx-set-shas@v4
- name: Check affected - name: Check affected
run: pnpm nx affected --verbose -t typecheck build rebuild-deps run: pnpm nx affected --verbose -t typecheck build rebuild-deps test-build
test_dev: test_dev:
name: Test development name: Test development

1
.gitignore vendored
View File

@ -52,3 +52,4 @@ upload
*.tsbuildinfo *.tsbuildinfo
/result /result
.svelte-kit

View File

@ -1,7 +1,2 @@
_regroup _regroup
_regroup_monorepo _regroup_monorepo
# Asset copying respects .gitignore / .nxignore for some reason.
# See https://github.com/nrwl/nx/issues/20309
!dist
!node_modules

View File

@ -9,6 +9,8 @@
"redhat.vscode-yaml", "redhat.vscode-yaml",
"tobermory.es6-string-html", "tobermory.es6-string-html",
"vitest.explorer", "vitest.explorer",
"yzhang.markdown-all-in-one" "yzhang.markdown-all-in-one",
"svelte.svelte-vscode",
"bradlc.vscode-tailwindcss"
] ]
} }

View File

@ -22,7 +22,7 @@ See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for q
* Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions) * Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions)
* Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts) * Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts)
* UI available in English, German, Spanish, French, Romanian, and Chinese (simplified and traditional) * UI available in English, German, Spanish, French, Romanian, and Chinese (simplified and traditional)
* Direct [OpenID and TOTP integration](.docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md") for more secure login * Direct [OpenID and TOTP integration](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md) for more secure login
* [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server * [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server
* there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting) * there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting)
* [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet * [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet

View File

@ -44,7 +44,6 @@ export default tseslint.config(
"dist/*", "dist/*",
"docs/*", "docs/*",
"demo/*", "demo/*",
"libraries/*",
"src/public/app-dist/*", "src/public/app-dist/*",
"src/public/app/doc_notes/*" "src/public/app/doc_notes/*"
] ]

View File

@ -38,7 +38,6 @@ export default [
"dist/*", "dist/*",
"docs/*", "docs/*",
"demo/*", "demo/*",
"libraries/*",
// TriliumNextTODO: check if we want to format packages here as well - for now skipping it // TriliumNextTODO: check if we want to format packages here as well - for now skipping it
"packages/*", "packages/*",
"src/public/app-dist/*", "src/public/app-dist/*",

View File

@ -41,7 +41,7 @@
"@types/node": "22.15.31", "@types/node": "22.15.31",
"@types/yargs": "17.0.33", "@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.2.3", "@vitest/coverage-v8": "3.2.3",
"eslint": "9.28.0", "eslint": "9.29.0",
"eslint-plugin-simple-import-sort": "12.1.1", "eslint-plugin-simple-import-sort": "12.1.1",
"esm": "3.2.25", "esm": "3.2.25",
"jsdoc": "4.0.4", "jsdoc": "4.0.4",

View File

@ -1,6 +1,6 @@
{ {
"name": "@triliumnext/client", "name": "@triliumnext/client",
"version": "0.94.1", "version": "0.95.0",
"description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)", "description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)",
"private": true, "private": true,
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
@ -10,7 +10,7 @@
"url": "https://github.com/TriliumNext/Notes" "url": "https://github.com/TriliumNext/Notes"
}, },
"dependencies": { "dependencies": {
"@eslint/js": "9.28.0", "@eslint/js": "9.29.0",
"@excalidraw/excalidraw": "0.18.0", "@excalidraw/excalidraw": "0.18.0",
"@fullcalendar/core": "6.1.17", "@fullcalendar/core": "6.1.17",
"@fullcalendar/daygrid": "6.1.17", "@fullcalendar/daygrid": "6.1.17",
@ -66,7 +66,7 @@
"copy-webpack-plugin": "13.0.0", "copy-webpack-plugin": "13.0.0",
"happy-dom": "18.0.1", "happy-dom": "18.0.1",
"script-loader": "0.7.2", "script-loader": "0.7.2",
"vite-plugin-static-copy": "3.0.0" "vite-plugin-static-copy": "3.0.2"
}, },
"nx": { "nx": {
"name": "client", "name": "client",

View File

@ -1,204 +0,0 @@
// Source: https://github.com/codemirror/codemirror5/pull/7080/files
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function (mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function (CodeMirror) {
"use strict";
CodeMirror.defineMode("hcl", function (config) {
var indentUnit = config.indentUnit;
var keywords = {
"resource": true,
"variable": true,
"output": true,
"module": true,
"provider": true,
"data": true,
"locals": true,
"terraform": true,
"if": true,
"else": true,
"for": true,
"foreach": true,
"in": true,
"true": true,
"false": true,
"null": true,
};
var atoms = {
"true": true,
"false": true,
"null": true,
};
var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
var curPunc;
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'" || ch == "`") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\d\.]/.test(ch)) {
if (ch == ".") {
stream.match(/^[0-9_]+([eE][\-+]?[0-9_]+)?/);
} else {
stream.match(/^[0-9_]*\.?[0-9_]*([eE][\-+]?[0-9_]+)?/);
}
return "number";
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
return "keyword";
}
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function (stream, state) {
var escaped = false,
next,
end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {
end = true;
break;
}
escaped = !escaped && quote != "`" && next == "\\";
}
if (end || !(escaped || quote == "`"))
state.tokenize = tokenBase;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false,
ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
return state.context = new Context(state.indented, col, type, null, state.context);
}
function popContext(state) {
if (!state.context.prev) return;
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
// Interface
return {
startState: function (basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},
token: function (stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment") return style;
if (ctx.align == null) ctx.align = true;
if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}" && ctx.type == "}") popContext(state);
else if (curPunc == ctx.type) popContext(state);
state.startOfLine = false;
return style;
},
indent: function (state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (firstChar == "#" || firstChar == ";") return 0;
if (stream.sol()) {
if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
state.context.type = "}";
return ctx.indented;
}
var closing = firstChar == ctx.type;
if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
}
},
electricChars: "{}):",
closeBrackets: "()[]{}''\"\"``",
fold: "brace",
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//"
};
});
CodeMirror.defineMIME("text/x-hcl", "hcl");
CodeMirror.modeInfo.push({
ext: [ "hcl " ],
mime: "text/x-hcl",
mode: "hcl",
name: "Terraform (HCL)"
});
});

View File

@ -5,7 +5,7 @@ import { viteStaticCopy } from 'vite-plugin-static-copy'
import asset_path from './src/asset_path'; import asset_path from './src/asset_path';
import webpackStatsPlugin from 'rollup-plugin-webpack-stats'; import webpackStatsPlugin from 'rollup-plugin-webpack-stats';
const assets = [ "assets", "stylesheets", "libraries", "fonts", "translations" ]; const assets = [ "assets", "stylesheets", "fonts", "translations" ];
export default defineConfig(() => ({ export default defineConfig(() => ({
root: __dirname, root: __dirname,
@ -84,7 +84,10 @@ export default defineConfig(() => ({
output: { output: {
entryFileNames: "src/[name].js", entryFileNames: "src/[name].js",
chunkFileNames: "src/[name].js", chunkFileNames: "src/[name].js",
assetFileNames: "src/[name].[ext]" assetFileNames: "src/[name].[ext]",
manualChunks: {
"ckeditor5": [ "@triliumnext/ckeditor5" ]
},
}, },
onwarn(warning, rollupWarn) { onwarn(warning, rollupWarn) {
if (warning.code === "MODULE_LEVEL_DIRECTIVE") { if (warning.code === "MODULE_LEVEL_DIRECTIVE") {

View File

@ -144,30 +144,71 @@ module.exports = {
hooks: { hooks: {
// Remove unused locales from the packaged app to save some space. // Remove unused locales from the packaged app to save some space.
postPackage(_, packageResult) { postPackage(_, packageResult) {
const localesToKeep = LOCALES const isMac = (process.platform === "darwin");
let localesToKeep = LOCALES
.filter(locale => !locale.contentOnly) .filter(locale => !locale.contentOnly)
.map(locale => locale.electronLocale.replace("_", "-")); .map(locale => locale.electronLocale);
if (!isMac) {
for (const outputPath of packageResult.outputPaths) { localesToKeep = localesToKeep.map(locale => locale.replace("_", "-"))
const localesDir = path.join(outputPath, 'locales');
if (!fs.existsSync(localesDir)) {
console.log('No locales directory found. Skipping cleanup.');
return;
} }
const files = fs.readdirSync(localesDir); const keptLocales = new Set();
const removedLocales = [];
const extension = (isMac ? ".lproj" : ".pak");
for (const outputPath of packageResult.outputPaths) {
const localeDirs = isMac
? [
path.join(outputPath, "TriliumNext Notes.app/Contents/Resources"),
path.join(outputPath, "TriliumNext Notes.app/Contents/Frameworks/Electron Framework.framework/Resources")
]
: [ path.join(outputPath, 'locales') ];
for (const localeDir of localeDirs) {
if (!fs.existsSync(localeDir)) {
console.log(`No locales directory found in '${localeDir}'.`);
process.exit(2);
}
const files = fs.readdirSync(localeDir);
for (const file of files) { for (const file of files) {
const localeName = path.basename(file, ".pak"); if (!file.endsWith(extension)) {
if (localesToKeep.includes(localeName)) {
continue; continue;
} }
console.log(`Removing unused locale file: ${file}`); let localeName = path.basename(file, extension);
const filePath = path.join(localesDir, file); if (localeName === "en-US" && !isMac) {
// If the locale is "en-US" on Windows, we treat it as "en".
// This is because the Windows version of Electron uses "en-US.pak" instead of "en.pak".
localeName = "en";
}
if (localesToKeep.includes(localeName)) {
keptLocales.add(localeName);
continue;
}
const filePath = path.join(localeDir, file);
if (isMac) {
fs.rm(filePath, { recursive: true });
} else {
fs.unlinkSync(filePath); fs.unlinkSync(filePath);
} }
removedLocales.push(file);
}
}
}
console.log(`Removed unused locale files: ${removedLocales.join(", ")}`);
// Ensure all locales that should be kept are actually present.
for (const locale of localesToKeep) {
if (!keptLocales.has(locale)) {
console.error(`Locale ${locale} was not found in the packaged app.`);
process.exit(1);
}
} }
}, },
// Gather all the artifacts produced by the makers and copy them to a common upload directory. // Gather all the artifacts produced by the makers and copy them to a common upload directory.

View File

@ -1,6 +1,6 @@
{ {
"name": "@triliumnext/desktop", "name": "@triliumnext/desktop",
"version": "0.94.1", "version": "0.95.0",
"description": "Build your personal knowledge base with TriliumNext Notes", "description": "Build your personal knowledge base with TriliumNext Notes",
"private": true, "private": true,
"main": "main.cjs", "main": "main.cjs",

View File

@ -1,6 +1,6 @@
{ {
"name": "@triliumnext/server", "name": "@triliumnext/server",
"version": "0.94.1", "version": "0.95.0",
"description": "The server-side component of TriliumNext, which exposes the client via the web, allows for sync and provides a REST API for both internal and external use.", "description": "The server-side component of TriliumNext, which exposes the client via the web, allows for sync and provides a REST API for both internal and external use.",
"private": true, "private": true,
"dependencies": { "dependencies": {
@ -46,7 +46,7 @@
"@triliumnext/turndown-plugin-gfm": "workspace:*", "@triliumnext/turndown-plugin-gfm": "workspace:*",
"archiver": "7.0.1", "archiver": "7.0.1",
"async-mutex": "0.5.0", "async-mutex": "0.5.0",
"axios": "1.9.0", "axios": "1.10.0",
"bindings": "1.5.0", "bindings": "1.5.0",
"chardet": "2.1.0", "chardet": "2.1.0",
"cheerio": "1.1.0", "cheerio": "1.1.0",
@ -348,6 +348,12 @@
} }
] ]
} }
},
"test-build": {
"dependsOn": [
"build"
],
"command": "vitest --config {projectRoot}/vitest.build.config.mts"
} }
} }
}, },

View File

@ -0,0 +1,46 @@
import { globSync } from "fs";
import { join } from "path";
import { it, describe, expect } from "vitest";
describe("Check artifacts are present", () => {
const distPath = join(__dirname, "../../dist");
it("has the necessary node modules", async () => {
const paths = [
"node_modules/better-sqlite3",
"node_modules/bindings",
"node_modules/file-uri-to-path"
];
ensurePathsExist(paths);
});
it("includes the client", async () => {
const paths = [
"public/assets",
"public/fonts",
"public/node_modules",
"public/src",
"public/stylesheets",
"public/translations"
];
ensurePathsExist(paths);
});
it("includes necessary assets", async () => {
const paths = [
"assets",
"share-theme"
];
ensurePathsExist(paths);
});
function ensurePathsExist(paths: string[]) {
for (const path of paths) {
const result = globSync(join(distPath, path, "**"));
expect(result, path).not.toHaveLength(0);
}
}
});

View File

@ -1,6 +1,174 @@
<p>Trilium allows you to share selected notes as <strong>publicly accessible</strong> read-only <p>Trilium allows you to share selected notes as <strong>publicly accessible</strong> read-only
documents. This feature is particularly useful for publishing content directly documents. This feature is particularly useful for publishing content directly
from your Trilium notes, making it accessible to others online.</p> from your Trilium notes, making it accessible to others online.</p>
<figure
class="image">
<img style="aspect-ratio:1144/660;" src="Sharing_image.png" width="1144"
height="660">
</figure>
<h2>Features, interaction and limitations</h2>
<ul>
<li>Searching by note title.</li>
<li>Automatic dark/light mode based on the user's browser settings.</li>
<li>Mobile-friendly layout, with sidebar.</li>
<li>Collapsible tree with the same note icons as the application.</li>
<li>Customizable logo.</li>
<li>Toggle button for dark/light mode, which also stores the user preferences.</li>
<li>Quick navigation buttons (previous and next note).</li>
<li>Displaying the date of the last update of the note.</li>
</ul>
<h3>By note type</h3>
<figure class="table" style="width:100%;">
<table class="ck-table-resized">
<colgroup>
<col style="width:19.92%;">
<col style="width:41.66%;">
<col style="width:38.42%;">
</colgroup>
<thead>
<tr>
<th>&nbsp;</th>
<th>Supported features</th>
<th>Limitations</th>
</tr>
</thead>
<tbody>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iPIMuisry3hd">Text</a>
</th>
<td>
<ul>
<li>Table of contents.</li>
<li>Syntax highlight of code blocks, provided a language is selected (does
not work if “Auto-detected” is enabled).</li>
<li>Rendering for math equations.</li>
</ul>
</td>
<td>
<ul>
<li>Including notes is not supported.</li>
<li>Inline Mermaid diagrams are not rendered.</li>
</ul>
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_6f9hih2hXXZk">Code</a>
</th>
<td>
<ul>
<li>Basic support (displaying the contents of the note in a monospace font).</li>
</ul>
</td>
<td>
<ul>
<li>No syntax highlight.</li>
</ul>
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_m523cpzocqaD">Saved Search</a>
</th>
<td colspan="2">Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iRwzGnHPzonm">Relation Map</a>
</th>
<td colspan="2">Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_bdUJEHsAPYQR">Note Map</a>
</th>
<td colspan="2">Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>
</th>
<td colspan="2">Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_GTwFsgaA0lCt">Book</a>
</th>
<td>
<ul>
<li>The child notes are displayed in a fixed format.&nbsp;</li>
</ul>
</td>
<td>
<ul>
<li>More advanced view types such as the calendar view are not supported.</li>
</ul>
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_s1aBHPd79XYj">Mermaid Diagrams</a>
</th>
<td>
<ul>
<li>The diagram is displayed as a vector image.</li>
</ul>
</td>
<td>
<ul>
<li>No further interaction supported.</li>
</ul>
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_grjYqerjn243">Canvas</a>
</th>
<td>
<ul>
<li>The diagram is displayed as a vector image.</li>
</ul>
</td>
<td>
<ul>
<li>No further interaction supported.</li>
</ul>
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_1vHRoWCEjj0L">Web View</a>
</th>
<td colspan="2">Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_gBbsAeiuUxI5">Mind Map</a>
</th>
<td>The diagram is displayed as a vector image.</td>
<td>
<ul>
<li>No further interaction supported.</li>
</ul>
</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_81SGnPGMk7Xc">Geo Map</a>
</th>
<td colspan="2">Not supported.</td>
</tr>
<tr>
<th><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_W8vYD3Q1zjCR">File</a>
</th>
<td>Basic interaction (downloading the file).</td>
<td>
<ul>
<li>No further interaction supported.</li>
</ul>
</td>
</tr>
</tbody>
</table>
</figure>
<p>While the sharing feature is powerful, it has some limitations:</p>
<ul>
<li><strong>Code Notes</strong>: No syntax highlighting.</li>
<li><strong>Static Note Tree</strong>
</li>
<li><strong>Protected Notes</strong>: Cannot be shared.</li>
<li><strong>Include Notes</strong>: Not supported.</li>
</ul>
<p>Some of these limitations may be addressed in future updates.</p>
<h2>Prerequisites</h2> <h2>Prerequisites</h2>
<p>To use the sharing feature, you must have a&nbsp;<a class="reference-link" <p>To use the sharing feature, you must have a&nbsp;<a class="reference-link"
href="#root/_help_WOcw2SLH6tbX">Server Installation</a>&nbsp;of Trilium. href="#root/_help_WOcw2SLH6tbX">Server Installation</a>&nbsp;of Trilium.
@ -15,14 +183,9 @@
<img src="Sharing_share-single-note.png" alt="Share Note"> <img src="Sharing_share-single-note.png" alt="Share Note">
</p> </p>
</li> </li>
<li> <li><strong>Access the Shared Note</strong>: The link provided will open the
<p><strong>Access the Shared Note</strong>: The link provided will open the
note in your browser. If your server is not configured with a public IP, note in your browser. If your server is not configured with a public IP,
the URL will refer to <code>localhost (127.0.0.1)</code>.</p> the URL will refer to <code>localhost (127.0.0.1)</code>.</li>
<p>
<img src="Sharing_share-single-note-.png" alt="Shared Note Example">
</p>
</li>
</ol> </ol>
<h2>Sharing a Note Subtree</h2> <h2>Sharing a Note Subtree</h2>
<p>When you share a note, you actually share the entire subtree of notes <p>When you share a note, you actually share the entire subtree of notes
@ -30,9 +193,6 @@
the shared content. For example, sharing the "Formatting" subtree will the shared content. For example, sharing the "Formatting" subtree will
display a page with basic navigation for exploring all the notes within display a page with basic navigation for exploring all the notes within
that subtree.</p> that subtree.</p>
<p>
<img src="Sharing_share-multiple-not.png" alt="Shared Subtree Example">
</p>
<h2>Viewing All Shared Notes</h2> <h2>Viewing All Shared Notes</h2>
<p>You can view a list of all shared notes by clicking on "Show Shared Notes <p>You can view a list of all shared notes by clicking on "Show Shared Notes
Subtree." This allows you to manage and navigate through all the notes Subtree." This allows you to manage and navigate through all the notes
@ -47,8 +207,8 @@
To protect an entire subtree, make sure the label is <a href="#root/_help_bwZpz2ajCEwO">inheritable</a>.</p> To protect an entire subtree, make sure the label is <a href="#root/_help_bwZpz2ajCEwO">inheritable</a>.</p>
<h2>Advanced Sharing Options</h2> <h2>Advanced Sharing Options</h2>
<h3>Customizing the Appearance of Shared Notes</h3> <h3>Customizing the Appearance of Shared Notes</h3>
<p>The default shared page is basic in design, but you can customize it using <p>The default design should be a good starting point, but you can customize
your own CSS:</p> it using your own CSS:</p>
<ul> <ul>
<li><strong>Custom CSS</strong>: Link a CSS&nbsp;<a class="reference-link" <li><strong>Custom CSS</strong>: Link a CSS&nbsp;<a class="reference-link"
href="#root/_help_6f9hih2hXXZk">Code</a>&nbsp;note to the shared page by href="#root/_help_6f9hih2hXXZk">Code</a>&nbsp;note to the shared page by
@ -99,19 +259,6 @@ for (const attr of parentNote.attributes) {
making it easier to use Trilium as a fully-fledged website. Consider combining making it easier to use Trilium as a fully-fledged website. Consider combining
this with the <code>#shareIndex</code> label, which will display a list of this with the <code>#shareIndex</code> label, which will display a list of
all shared notes.</p> all shared notes.</p>
<h2>Limitations</h2>
<p>While the sharing feature is powerful, it has some limitations:</p>
<ul>
<li><strong>No Relation Map Support</strong>
</li>
<li><strong>Book Notes</strong>: Only show a list of child notes.</li>
<li><strong>Code Notes</strong>: No syntax highlighting.</li>
<li><strong>Static Note Tree</strong>
</li>
<li><strong>Protected Notes</strong>: Cannot be shared.</li>
<li><strong>Include Notes</strong>: Not supported.</li>
</ul>
<p>Some of these limitations may be addressed in future updates.</p>
<h2>Attribute reference</h2> <h2>Attribute reference</h2>
<figure class="table"> <figure class="table">
<table> <table>
@ -190,3 +337,10 @@ for (const attr of parentNote.attributes) {
</tbody> </tbody>
</table> </table>
</figure> </figure>
<h2>Credits</h2>
<p>Since v0.95.0, a new theme was introduced (and enabled by default) which
greatly improves the visual aspect of the Share feature, as well as its
functionality (such as mobile support, dark/light mode, collapsible tree,
etc.). This theme is an adaptation of the <a href="https://github.com/zerebos/trilium.rocks">Trilium Rocks!</a> by
<a
href="https://github.com/zerebos">zerebos</a>.</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,6 +1,7 @@
<p>When accessing a shared note, Trilium will render it as a web page. Sometimes <p>When accessing a shared note, Trilium will render it as a web page. Sometimes
it's desirable to serve the content directly so that it can be used in it's desirable to serve the content directly so that it can be used in
a script or downloaded by the user.</p> a script or downloaded by the user.</p>
<figure class="table">
<table> <table>
<thead> <thead>
<tr> <tr>
@ -11,7 +12,10 @@
<tbody> <tbody>
<tr> <tr>
<td> <td>
<img src="1_Serving directly the conte.png"> <figure class="image">
<img style="aspect-ratio:738/275;" src="1_Serving directly the conte.png"
width="738" height="275">
</figure>
</td> </td>
<td> <td>
<img src="Serving directly the conte.png"> <img src="Serving directly the conte.png">
@ -19,7 +23,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</figure>
<h2>By adding an attribute to the note</h2> <h2>By adding an attribute to the note</h2>
<p>Simply add the <code>#shareRaw</code> attribute and the note will always <p>Simply add the <code>#shareRaw</code> attribute and the note will always
be rendered <em>raw</em> when accessed from the share URL.</p> be rendered <em>raw</em> when accessed from the share URL.</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@ -36,7 +36,6 @@ async function register(app: express.Application) {
app.use(`/${assetUrlFragment}/src`, persistentCacheStatic(path.join(publicDir, "src"))); app.use(`/${assetUrlFragment}/src`, persistentCacheStatic(path.join(publicDir, "src")));
app.use(`/${assetUrlFragment}/stylesheets`, persistentCacheStatic(path.join(publicDir, "stylesheets"))); app.use(`/${assetUrlFragment}/stylesheets`, persistentCacheStatic(path.join(publicDir, "stylesheets")));
app.use(`/${assetUrlFragment}/libraries`, persistentCacheStatic(path.join(publicDir, "libraries")));
app.use(`/${assetUrlFragment}/fonts`, persistentCacheStatic(path.join(publicDir, "fonts"))); app.use(`/${assetUrlFragment}/fonts`, persistentCacheStatic(path.join(publicDir, "fonts")));
app.use(`/${assetUrlFragment}/translations/`, persistentCacheStatic(path.join(publicDir, "translations"))); app.use(`/${assetUrlFragment}/translations/`, persistentCacheStatic(path.join(publicDir, "translations")));
app.use(`/node_modules/`, persistentCacheStatic(path.join(publicDir, "node_modules"))); app.use(`/node_modules/`, persistentCacheStatic(path.join(publicDir, "node_modules")));
@ -46,8 +45,6 @@ async function register(app: express.Application) {
app.use(`/assets/vX/fonts`, express.static(path.join(srcRoot, "public/fonts"))); app.use(`/assets/vX/fonts`, express.static(path.join(srcRoot, "public/fonts")));
app.use(`/assets/vX/images`, express.static(path.join(srcRoot, "..", "images"))); app.use(`/assets/vX/images`, express.static(path.join(srcRoot, "..", "images")));
app.use(`/assets/vX/stylesheets`, express.static(path.join(srcRoot, "public/stylesheets"))); app.use(`/assets/vX/stylesheets`, express.static(path.join(srcRoot, "public/stylesheets")));
app.use(`/${assetUrlFragment}/libraries`, persistentCacheStatic(path.join(srcRoot, "public/libraries")));
app.use(`/assets/vX/libraries`, express.static(path.join(srcRoot, "..", "libraries")));
} }
export default { export default {

View File

@ -11,7 +11,7 @@ vi.mock('../../log.js', () => ({
} }
})); }));
describe('Provider Streaming Integration Tests', () => { describe.skip('Provider Streaming Integration Tests', () => {
let mockProviderOptions: ProviderStreamOptions; let mockProviderOptions: ProviderStreamOptions;
beforeEach(() => { beforeEach(() => {
@ -479,9 +479,9 @@ describe('Provider Streaming Integration Tests', () => {
}); });
describe('Memory Management', () => { describe('Memory Management', () => {
it('should not leak memory during long streaming sessions', async () => { it.skip('should not leak memory during long streaming sessions', async () => {
// Reduced chunk count for CI stability - still tests memory management // Reduced chunk count for CI stability - still tests memory management
const chunkCount = 1000; // Reduced from 10000 const chunkCount = 500; // Reduced from 10000
const longSessionIterator = { const longSessionIterator = {
async *[Symbol.asyncIterator]() { async *[Symbol.asyncIterator]() {
for (let i = 0; i < chunkCount; i++) { for (let i = 0; i < chunkCount; i++) {

View File

@ -73,7 +73,7 @@ function error(message: string | Error | unknown) {
log(`ERROR: ${message}`); log(`ERROR: ${message}`);
} }
const requestBlacklist = ["/libraries", "/app", "/images", "/stylesheets", "/api/recent-notes"]; const requestBlacklist = ["/app", "/images", "/stylesheets", "/api/recent-notes"];
function request(req: Request, res: Response, timeMs: number, responseLength: number | string = "?") { function request(req: Request, res: Response, timeMs: number, responseLength: number | string = "?") {
for (const bl of requestBlacklist) { for (const bl of requestBlacklist) {

View File

@ -11,10 +11,17 @@ export default defineConfig(() => ({
setupFiles: ["./spec/setup.ts"], setupFiles: ["./spec/setup.ts"],
environment: "node", environment: "node",
include: ['{src,spec}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], include: ['{src,spec}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
exclude: [
"spec/build-checks/**",
],
reporters: [
"verbose"
],
coverage: { coverage: {
reportsDirectory: './test-output/vitest/coverage', reportsDirectory: './test-output/vitest/coverage',
provider: 'v8' as const, provider: 'v8' as const,
reporter: [ "text", "html" ] reporter: [ "text", "html" ]
} },
pool: "threads"
}, },
})); }));

View File

@ -0,0 +1,18 @@
/// <reference types='vitest' />
import { defineConfig } from 'vite';
export default defineConfig(() => ({
root: __dirname,
cacheDir: '../../node_modules/.vite/apps/server',
plugins: [],
test: {
watch: false,
globals: true,
setupFiles: ["./spec/setup.ts"],
environment: "node",
include: ['spec/build-checks/**'],
reporters: [
"verbose"
]
},
}));

28
apps/website/.gitignore vendored Normal file
View File

@ -0,0 +1,28 @@
node_modules
# Output
.output
.vercel
.netlify
.wrangler
/.svelte-kit
/build
# OS
.DS_Store
Thumbs.db
# Env
.env
.env.*
!.env.example
!.env.test
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
# Paraglide
src/lib/paraglide
project.inlang/cache

1
apps/website/.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict=true

38
apps/website/README.md Normal file
View File

@ -0,0 +1,38 @@
# sv
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npx sv create
# create a new project in my-app
npx sv create my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.

View File

@ -0,0 +1,39 @@
import js from '@eslint/js';
import { includeIgnoreFile } from '@eslint/compat';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import { fileURLToPath } from 'node:url';
import ts from 'typescript-eslint';
import svelteConfig from './svelte.config.js';
const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
export default ts.config(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,
{
languageOptions: {
globals: { ...globals.browser, ...globals.node }
},
rules: { // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
"no-undef": 'off' }
},
{
files: [
'**/*.svelte',
'**/*.svelte.ts',
'**/*.svelte.js'
],
languageOptions: {
parserOptions: {
projectService: true,
extraFileExtensions: ['.svelte'],
parser: ts.parser,
svelteConfig
}
}
}
);

View File

@ -0,0 +1,4 @@
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"hello_world": "Hello, {name} from en!"
}

44
apps/website/package.json Normal file
View File

@ -0,0 +1,44 @@
{
"name": "website",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "eslint ."
},
"devDependencies": {
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",
"@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
"eslint": "^9.18.0",
"eslint-plugin-svelte": "^3.0.0",
"globals": "^16.0.0",
"mdsvex": "^0.12.3",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.0.0",
"typescript": "^5.0.0",
"typescript-eslint": "^8.20.0",
"vite": "^6.2.6"
},
"dependencies": {
"@inlang/paraglide-js": "^2.0.0"
},
"nx": {
"typecheck": {
"dependsOn": [
"build"
]
}
}
}

View File

@ -0,0 +1 @@
dv1iXGpHP2mMvuQQo4

View File

@ -0,0 +1,14 @@
{
"$schema": "https://inlang.com/schema/project-settings",
"modules": [
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js"
],
"plugin.inlang.messageFormat": {
"pathPattern": "./messages/{locale}.json"
},
"baseLocale": "en",
"locales": [
"en"
]
}

2
apps/website/src/app.css Normal file
View File

@ -0,0 +1,2 @@
@import 'tailwindcss';
@plugin '@tailwindcss/typography';

13
apps/website/src/app.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
export {};

12
apps/website/src/app.html Normal file
View File

@ -0,0 +1,12 @@
<!doctype html>
<html lang="%paraglide.lang%">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@ -0,0 +1,12 @@
import type { Handle } from '@sveltejs/kit';
import { paraglideMiddleware } from '$lib/paraglide/server';
const handleParaglide: Handle = ({ event, resolve }) => paraglideMiddleware(event.request, ({ request, locale }) => {
event.request = request;
return resolve(event, {
transformPageChunk: ({ html }) => html.replace('%paraglide.lang%', locale)
});
});
export const handle: Handle = handleParaglide;

View File

@ -0,0 +1,6 @@
import { deLocalizeUrl } from '$lib/paraglide/runtime';
export const reroute = (request: {
url: URL;
fetch: typeof fetch;
}) => deLocalizeUrl(request.url).pathname;

View File

@ -0,0 +1,174 @@
import rootPackageJson from '../../../../package.json';
export type App = "desktop" | "server";
export type Architecture = 'x64' | 'arm64';
export type Platform = "macos" | "windows" | "linux" | "pikapod";
const version = rootPackageJson.version;
export interface DownloadInfo {
recommended?: boolean;
name: string;
url?: string;
}
export interface DownloadMatrixEntry {
title: Record<Architecture, string> | string;
description: Record<Architecture, string> | string;
downloads: Record<string, DownloadInfo>;
}
type DownloadMatrix = Record<App, { [ P in Platform ]?: DownloadMatrixEntry }>;
// Keep compatibility info inline with https://github.com/electron/electron/blob/main/README.md#platform-support.
export const downloadMatrix: DownloadMatrix = {
desktop: {
windows: {
title: {
x64: "Windows 64-bit",
arm64: "Windows on ARM"
},
description: {
x64: "Compatible with Intel or AMD devices running Windows 10 and 11.",
arm64: "Compatible with ARM devices (e.g. with Qualcomm Snapdragon).",
},
downloads: {
exe: {
recommended: true,
name: "Download Installer (.exe)"
},
zip: {
name: "Portable (.zip)"
}
}
},
linux: {
title: {
x64: "Linux 64-bit",
arm64: "Linux on ARM"
},
description: {
x64: "For most Linux distributions, compatible with x86_64 architecture.",
arm64: "For ARM-based Linux distributions, compatible with aarch64 architecture.",
},
downloads: {
deb: {
recommended: true,
name: "Download .deb"
},
rpm: {
name: ".rpm"
},
flatpak: {
name: ".flatpak"
},
zip: {
name: "Portable (.zip)"
}
}
},
macos: {
title: {
x64: "macOS for Intel",
arm64: "macOS for Apple Silicon"
},
description: {
x64: "For Intel-based Macs running macOS Big Sur or later.",
arm64: "For Apple Silicon Macs such as those with M1 and M2 chips.",
},
downloads: {
dmg: {
recommended: true,
name: "Download Installer (.dmg)"
},
zip: {
name: "Portable (.zip)"
}
}
}
},
server: {
linux: {
title: "Self-hosted (Linux)",
description: "Deploy Trilium Notes on your own server or VPS, compatible with most Linux distributions.",
downloads: {
docker: {
recommended: true,
name: "View on Docker Hub",
url: "https://hub.docker.com/r/triliumnext/notes"
},
tarX64: {
name: "x86 (.tar.xz)",
url: `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-Server-v${version}-linux-x64.tar.xz`
},
tarArm64: {
name: "ARM (.tar.xz)",
url: `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-Server-v${version}-linux-arm64.tar.xz`
},
}
},
pikapod: {
title: "Paid hosting",
description: "Trilium Notes hosted on PikaPods, a paid service for easy access and management.",
downloads: {
pikapod: {
recommended: true,
name: "Set up on PikaPods",
url: "https://www.pikapods.com/pods?run=trilium-next"
},
triliumcc: {
name: "Alternatively see trilium.cc",
url: "https://trilium.cc/"
}
}
}
}
};
export function buildDownloadUrl(app: App, platform: Platform, format: string, architecture: Architecture): string {
if (app === "desktop") {
return `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-v${version}-${platform}-${architecture}.${format}`;
} else if (app === "server") {
return downloadMatrix.server[platform]?.downloads[format].url ?? "#";
} else {
return "#";
}
}
export function getArchitecture(): Architecture {
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.includes('arm64') || userAgent.includes('aarch64')) {
return 'arm64';
}
return "x64";
}
function getPlatform(): Platform {
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.includes('macintosh') || userAgent.includes('mac os x')) {
return "macos";
} else if (userAgent.includes('windows') || userAgent.includes('win32')) {
return "windows";
} else {
return "linux";
}
}
export function getRecommendedDownload() {
const architecture = getArchitecture();
const platform = getPlatform();
const downloadInfo = downloadMatrix.desktop[platform]?.downloads;
const recommendedDownload = Object.entries(downloadInfo || {}).find(d => d[1].recommended);
const format = recommendedDownload?.[0];
const url = buildDownloadUrl("desktop", platform, format || 'zip', architecture);
return {
architecture,
platform,
url
}
}

View File

@ -0,0 +1 @@
// place files you want to import through the `$lib` alias in this folder.

View File

@ -0,0 +1,14 @@
<script lang="ts">
import '../app.css';
import Header from './header.svelte';
let { children } = $props();
</script>
<Header />
{@render children()}
<footer class="container mx-auto bg-white mt-2 py-6 text-sm text-center text-gray-500">
&copy; 2024-2025 <a href="https://github.com/eliandoran" class="text-blue-500 hover:underline">Elian Doran</a> and the <a href="https://github.com/TriliumNext/Notes/graphs/contributors" class="text-blue-500 hover:underline">team</a>. <br/> &copy; 2017-2024 <a href="https://github.com/zadam" class="text-blue-500 hover:underline">Adam Zivner</a>.
</footer>

View File

@ -0,0 +1,145 @@
<script>
import DownloadNow from "./download-now.svelte";
</script>
<section class="relative overflow-hidden bg-gradient-to-br from-white to-violet-50">
<!-- Bokeh background circles -->
<div class="absolute inset-0 pointer-events-none z-0">
<div class="absolute w-72 h-72 bg-violet-300 opacity-30 rounded-full blur-3xl top-[-50px] left-[-80px]"></div>
<div class="absolute w-96 h-96 bg-pink-200 opacity-20 rounded-full blur-3xl bottom-[-100px] right-[-60px]"></div>
<div class="absolute w-64 h-64 bg-indigo-200 opacity-20 rounded-full blur-2xl top-[200px] left-[50%] transform -translate-x-1/2"></div>
</div>
<div class="relative z-10 container mx-auto pt-24 pb-24 px-4">
<div class="flex flex-col md:flex-row items-center md:justify-between gap-12">
<!-- Left: Text Content -->
<div class="md:w-1/3">
<h2 class="text-4xl font-bold mb-4 text-gray-900">Organize Your Thoughts.<br/> Build Your Knowledge.</h2>
<p class="text-lg mb-6 text-gray-700">
Trilium Notes helps you build and organize complex personal knowledge bases effortlessly.
Its unique tree structure, rich editing tools, and powerful search features make managing your information intuitive and flexible.
</p>
<div class="flex items-center gap-6">
<DownloadNow big />
<a href="/download" class="font-medium text-violet-700 hover:underline">
More platforms
</a>
</div>
</div>
<!-- Right: Screenshot -->
<div class="md:w-2/3">
<img src="screenshots/desktop-win.png" alt="Screenshot of the app on desktop Windows" class="w-full rounded-xl shadow-lg">
</div>
</div>
</div>
</section>
<section class="mt-20 max-w-6xl mx-auto px-4">
<h2 class="text-3xl font-bold text-center mb-12">Beyond Text: Smarter Note Types</h2>
<div class="grid md:grid-cols-2 gap-10">
<!-- Canvas Notes -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/canvas.png" alt="Canvas Note Screenshot" class="w-full h-56 object-cover object-top">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Canvas Notes</h3>
<p class="text-gray-600">Draw and arrange elements freely using an Excalidraw-powered canvas — ideal for diagrams, sketches, and visual planning.</p>
</div>
</div>
<!-- Mermaid Diagrams -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/mermaid.png" alt="Mermaid Diagram Screenshot" class="w-full h-56 object-cover object-top">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Mermaid Diagrams</h3>
<p class="text-gray-600">Render flowcharts, Gantt charts, and sequence diagrams with Mermaid markdown syntax directly in your notes.</p>
</div>
</div>
<!-- Geo Maps -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/geo-map.png" alt="Geo Map Screenshot" class="w-full h-56 object-cover">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Geo Maps</h3>
<p class="text-gray-600">Plot locations and GPX tracks to visualize geography-linked notes and movement patterns on interactive maps.</p>
</div>
</div>
<!-- Mind Maps -->
<div class="bg-white rounded-xl shadow overflow-hidden">
<img src="/note-types/mind-map.png" alt="Mind Map Screenshot" class="w-full h-56 object-cover">
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">Mind Maps</h3>
<p class="text-gray-600">Organize ideas visually using a drag-and-drop mind map editor powered by Mind Elixir.</p>
</div>
</div>
</div>
</section>
<section class="mt-20 max-w-6xl mx-auto px-4">
<h2 class="text-3xl font-bold text-center mb-12">Feature Highlights</h2>
<div class="grid gap-12 md:grid-cols-2 max-w-4xl mx-auto text-gray-700">
<!-- Organization & Navigation -->
<div>
<h3 class="flex items-center text-xl font-semibold mb-6 text-violet-700">Organization & Navigation</h3>
<ul class="list-disc list-inside space-y-3">
<li>Arbitrarily deep note tree with cloning support.</li>
<li>Fast navigation, full-text search, and note hoisting.</li>
<li>Note attributes for organization, querying, and scripting.</li>
<li>Seamless note versioning.</li>
</ul>
</div>
<!-- Editing & Content -->
<div>
<h3 class="flex items-center text-xl font-semibold mb-6 text-violet-700">Editing & Content</h3>
<ul class="list-disc list-inside space-y-3">
<li>Rich WYSIWYG editor with tables, images, math, and markdown autoformat.</li>
<li>Source code editing with syntax highlighting.</li>
<li>Evernote and Markdown import/export.</li>
<li>Web Clipper for easy saving of web content.</li>
</ul>
</div>
<!-- Security & Sync -->
<div>
<h3 class="flex items-center text-xl font-semibold mb-6 text-violet-700">Security & Sync</h3>
<ul class="list-disc list-inside space-y-3">
<li>Direct OpenID and TOTP integration for secure login.</li>
<li>Synchronization with self-hosted and third-party servers.</li>
<li>Strong note encryption with per-note granularity.</li>
<li>Sharing notes publicly on the internet.</li>
</ul>
</div>
<!-- Advanced & Customization -->
<div>
<h3 class="flex items-center text-xl font-semibold mb-6 text-violet-700">Advanced & Customization</h3>
<ul class="list-disc list-inside space-y-3">
<li>Relation maps and link maps to visualize notes.</li>
<li>Scripting support and REST API for automation.</li>
<li>Touch-optimized mobile frontend and dark/user themes.</li>
<li>Customizable UI with sidebar buttons and user widgets.</li>
<li>Metrics with Grafana dashboard integration.</li>
<li>Scales efficiently beyond 100,000 notes.</li>
</ul>
</div>
</div>
</section>
<section class="bg-violet-50 py-16 mt-24">
<div class="container mx-auto text-center px-4">
<h2 class="text-3xl font-bold mb-4">Ready to get started with Trilium Notes?</h2>
<p class="text-lg text-gray-700 mb-8">Build your personal knowledge base with powerful features and full privacy.</p>
<div class="flex justify-center gap-6">
<a href="#" class="py-3 px-6 bg-violet-600 text-white font-semibold rounded-full shadow hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75">
Download Now
</a>
</div>
</div>
</section>

View File

@ -0,0 +1 @@
<a href="/demo/paraglide">paraglide</a>

View File

@ -0,0 +1,15 @@
<script lang="ts">
import { setLocale } from '$lib/paraglide/runtime';
import { page } from '$app/state';
import { goto } from '$app/navigation';
import { m } from '$lib/paraglide/messages.js';
</script>
<h1>{m.hello_world({ name: 'SvelteKit User' })}</h1>
<div>
<button onclick={() => setLocale('en')}>en</button>
</div><p>
If you use VSCode, install the <a href="https://marketplace.visualstudio.com/items?itemName=inlang.vs-code-extension" target="_blank">Sherlock i18n extension</a> for a better i18n experience.
</p>

View File

@ -0,0 +1,18 @@
<script>
import { getRecommendedDownload } from "$lib/download-helper";
export let big = false;
const { url, platform, architecture } = getRecommendedDownload();
</script>
{#if url}
<a href="{url}"
class:text-xl={big}
class:py-4={big}
class="py-2 px-5 bg-violet-600 text-white font-semibold rounded-xl shadow-md hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75">
Download now
<span class="text-sm text-gray-300">
({platform} {architecture})
</span>
</a>
{/if}

View File

@ -0,0 +1,56 @@
<script lang="ts">
import type { Platform } from "$lib/download-helper";
import { downloadMatrix, getArchitecture } from "$lib/download-helper";
import DownloadCard from "./download-card.svelte";
let architectures = ["x64", "arm64"] as const;
let architecture = getArchitecture();
</script>
<div class="bg-gray-50 py-20">
<section class="max-w-6xl mx-auto px-4">
<h2 class="text-4xl font-bold text-center text-gray-900 mb-12">Download the desktop application</h2>
<!-- Architecture pill selector -->
<div class="col-span-3 flex justify-center items-center gap-3 mb-6">
<span class="text-gray-600 font-medium mr-2">Architecture:</span>
<div class="inline-flex bg-violet-100 rounded-full shadow p-1">
{#each architectures as arch}
<button class="py-2 px-6 rounded-full font-semibold focus:outline-none transition
text-violet-700 border-violet-700
aria-pressed:bg-violet-700 aria-pressed:text-violet-100
" aria-pressed={architecture === arch} on:click={() => architecture = arch}>
{arch}
</button>
{/each}
</div>
</div>
<div class="grid md:grid-cols-3 gap-10">
{#each Object.entries(downloadMatrix.desktop) as [platformId, platform]}
{@const textColor = (platformId === "windows" ? "text-blue-600" : platformId === "linux" ? "text-violet-600" : "text-gray-800")}
{@const bgColor = (platformId === "windows" ? "bg-blue-600" : platformId === "linux" ? "bg-violet-600" : "bg-gray-800")}
{@const hoverColor = (platformId === "windows" ? "hover:bg-blue-700" : platformId === "linux" ? "hover:bg-violet-700" : "hover:bg-gray-900")}
<DownloadCard app="desktop"
{textColor} {bgColor} {hoverColor}
{platform} {architecture} platformId={platformId as Platform} />
{/each}
</div>
</section>
<section class="max-w-4xl mx-auto px-4 mt-10">
<h2 class="text-3xl font-bold text-center text-gray-900 mb-8">Set up a server for access on multiple devices</h2>
<div class="grid md:grid-cols-2 gap-10">
{#each Object.entries(downloadMatrix.server) as [platformId, platform]}
{@const textColor = (platformId === "linux" ? "text-violet-600" : "text-gray-800")}
{@const bgColor = (platformId === "linux" ? "bg-violet-600" : "bg-gray-800")}
{@const hoverColor = (platformId === "linux" ? "hover:bg-violet-700" : "hover:bg-gray-900")}
<DownloadCard app="server"
{textColor} {bgColor} {hoverColor}
{platform} {architecture} platformId={platformId as Platform} />
{/each}
</div>
</section>
</div>

View File

@ -0,0 +1,31 @@
<script lang="ts">
import { buildDownloadUrl, type Architecture, type DownloadMatrixEntry, type Platform, type App } from "$lib/download-helper";
export let app: App = "desktop";
export let platformId: Platform;
export let platform: DownloadMatrixEntry;
export let textColor: string;
export let bgColor: string;
export let hoverColor: string;
export let architecture: Architecture | null = null;
const recommended = Object.entries(platform.downloads).find((e) => e[1].recommended);
</script>
<div class="bg-white border border-gray-200 rounded-2xl shadow-lg p-8 flex flex-col items-start">
<h3 class="text-2xl font-semibold {textColor} mb-2">{typeof platform.title === "object" ? platform.title[architecture] : platform.title}</h3>
<p class="text-gray-700 mb-12">{typeof platform.title === "object" ? platform.description[architecture] : platform.description}</p>
<div class="space-y-2 mt-auto w-full">
{#if recommended}
<a href={buildDownloadUrl(app, platformId as Platform, recommended[0], architecture)} class="mt-auto block text-center {bgColor} {hoverColor} text-white font-medium py-2 px-5 rounded-full shadow transition">
{recommended[1].name}
</a>
{/if}
<div class="flex justify-center gap-4 text-sm {textColor} mt-2">
{#each Object.entries(platform.downloads).filter((e) => !e[1].recommended) as [format, download]}
<a href={buildDownloadUrl(app, platformId as Platform, format, architecture)} class="hover:underline block">
{download.name}
</a>
{/each}
</div>
</div>
</div>

View File

@ -0,0 +1,23 @@
<script>
import DownloadNow from "./download-now.svelte";
</script>
<header class="header bg-white sticky top-0 z-50 shadow">
<div class="container mx-auto flex items-center py-4">
<a href="/" class="flex items-center gap-x-2 w-100">
<img src="icon-color.svg" alt="Trilium Notes Logo" class="w-12 h-12">
<span class="text-2xl">Trilium Notes</span>
</a>
<div class="group w-full">
<nav class="header-nav">
<ul class="flex items-center justify-end gap-4">
<li><a href="/">User Guide</a></li>
<li><a href="/">Technical Guide</a></li>
<li><a href="/" class="text-violet-500">Support us</a></li>
<li><DownloadNow /></li>
</ul>
</nav>
</div>
</div>
</header>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>TriliumNext Notes</title>
<style type="text/css">
.st0{fill:#95C980;}
.st1{fill:#72B755;}
.st2{fill:#4FA52B;}
.st3{fill:#EE8C89;}
.st4{fill:#E96562;}
.st5{fill:#E33F3B;}
.st6{fill:#EFB075;}
.st7{fill:#E99547;}
.st8{fill:#E47B19;}
</style>
<g>
<path class="st0" d="m202.9 112.7c-22.5 16.1-54.5 12.8-74.9 6.3l14.8-11.8 14.1-11.3 49.1-39.3-51.2 35.9-14.3 10-14.9 10.5c0.7-21.2 7-49.9 28.6-65.4 1.8-1.3 3.9-2.6 6.1-3.8 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.4 2.8-4.9 5.4-7.4 7.8-3.4 3.5-6.8 6.4-10.1 8.8z"/>
<path class="st1" d="m213.1 104c-22.2 12.6-51.4 9.3-70.3 3.2l14.1-11.3 49.1-39.3-51.2 35.9-14.3 10c0.5-18.1 4.9-42.1 19.7-58.6 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.3 2.8-4.8 5.4-7.2 7.8z"/>
<path class="st2" d="m220.5 96.2c-21.1 8.6-46.6 5.3-63.7-0.2l49.2-39.4-51.2 35.9c0.3-15.8 3.5-36.6 14.3-52.8 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.8 66z"/>
<path class="st3" d="m106.7 179c-5.8-21 5.2-43.8 15.5-57.2l4.8 14.2 4.5 13.4 15.9 47-12.8-47.6-3.6-13.2-3.7-13.9c15.5 6.2 35.1 18.6 40.7 38.8 0.5 1.7 0.9 3.6 1.2 5.5 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.1-3.8-7.6-1.6-3.5-2.9-6.8-3.8-10z"/>
<path class="st4" d="m110.4 188.9c-3.4-19.8 6.9-40.5 16.6-52.9l4.5 13.4 15.9 47-12.8-47.6-3.6-13.2c13.3 5.2 29.9 15 38.1 30.4 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.2-3.8-7.7z"/>
<path class="st5" d="m114.2 196.5c-0.7-18 8.6-35.9 17.3-47.1l15.9 47-12.8-47.6c11.6 4.4 26.1 12.4 35.2 24.8 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8z"/>
<path class="st6" d="m86.3 59.1c21.7 10.9 32.4 36.6 35.8 54.9l-15.2-6.6-14.5-6.3-50.6-22 48.8 24.9 13.6 6.9 14.3 7.3c-16.6 7.9-41.3 14.5-62.1 4.1-1.8-0.9-3.6-1.9-5.4-3.2-2.3-1.5-4.5-3.2-6.8-5.1-19.9-16.4-40.3-46.4-42.7-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.2 0.8 6.2 1.6 9.1 2.5 4 1.3 7.6 2.8 10.9 4.4z"/>
<path class="st7" d="m75.4 54.8c18.9 12 28.4 35.6 31.6 52.6l-14.5-6.3-50.6-22 48.7 24.9 13.6 6.9c-14.1 6.8-34.5 13-53.3 8.2-2.3-1.5-4.5-3.2-6.8-5.1-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.1 0.8 6.2 1.6 9.1 2.6z"/>
<path class="st8" d="m66.3 52.2c15.3 12.8 23.3 33.6 26.1 48.9l-50.6-22 48.8 24.9c-12.2 6-29.6 11.8-46.5 10-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -0,0 +1,11 @@
import { mdsvex } from 'mdsvex';
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
preprocess: [vitePreprocess(), mdsvex()],
kit: { adapter: adapter() },
extensions: ['.svelte', '.svx']
};
export default config;

View File

@ -0,0 +1,20 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler",
"composite": true
}
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

View File

@ -0,0 +1,24 @@
import tailwindcss from '@tailwindcss/vite';
import { paraglideVitePlugin } from '@inlang/paraglide-js';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default () => {
// See https://github.com/nrwl/nx/issues/28978.
const cwd = process.cwd();
process.chdir(__dirname); // Temporarily change the working directory
const config = defineConfig({
plugins: [
tailwindcss(),
sveltekit(),
paraglideVitePlugin({
project: './project.inlang',
outdir: './src/lib/paraglide'
})
]
});
process.chdir(cwd); // Restore the original working directory
return config;
};

View File

@ -61,6 +61,32 @@
"attachments": [], "attachments": [],
"dirFileName": "Release Notes", "dirFileName": "Release Notes",
"children": [ "children": [
{
"isClone": false,
"noteId": "jthwbL0FdaeU",
"notePath": [
"hD3V4hiu2VW4",
"jthwbL0FdaeU"
],
"title": "v0.95.0",
"notePosition": 10,
"prefix": null,
"isExpanded": false,
"type": "text",
"mime": "text/html",
"attributes": [
{
"type": "relation",
"name": "template",
"value": "wyurrlcDl416",
"isInheritable": false,
"position": 60
}
],
"format": "markdown",
"dataFileName": "v0.95.0.md",
"attachments": []
},
{ {
"isClone": false, "isClone": false,
"noteId": "7HGYsJbLuhnv", "noteId": "7HGYsJbLuhnv",
@ -69,7 +95,7 @@
"7HGYsJbLuhnv" "7HGYsJbLuhnv"
], ],
"title": "v0.94.1", "title": "v0.94.1",
"notePosition": 10, "notePosition": 20,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -95,7 +121,7 @@
"Neq53ujRGBqv" "Neq53ujRGBqv"
], ],
"title": "v0.94.0", "title": "v0.94.0",
"notePosition": 20, "notePosition": 30,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -121,7 +147,7 @@
"VN3xnce1vLkX" "VN3xnce1vLkX"
], ],
"title": "v0.93.0", "title": "v0.93.0",
"notePosition": 30, "notePosition": 40,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -139,7 +165,7 @@
"WRaBfQqPr6qo" "WRaBfQqPr6qo"
], ],
"title": "v0.92.7", "title": "v0.92.7",
"notePosition": 40, "notePosition": 50,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -165,7 +191,7 @@
"a2rwfKNmUFU1" "a2rwfKNmUFU1"
], ],
"title": "v0.92.6", "title": "v0.92.6",
"notePosition": 50, "notePosition": 60,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -183,7 +209,7 @@
"fEJ8qErr0BKL" "fEJ8qErr0BKL"
], ],
"title": "v0.92.5-beta", "title": "v0.92.5-beta",
"notePosition": 60, "notePosition": 70,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -201,7 +227,7 @@
"kkkZQQGSXjwy" "kkkZQQGSXjwy"
], ],
"title": "v0.92.4", "title": "v0.92.4",
"notePosition": 70, "notePosition": 80,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -219,7 +245,7 @@
"vAroNixiezaH" "vAroNixiezaH"
], ],
"title": "v0.92.3-beta", "title": "v0.92.3-beta",
"notePosition": 80, "notePosition": 90,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -237,7 +263,7 @@
"mHEq1wxAKNZd" "mHEq1wxAKNZd"
], ],
"title": "v0.92.2-beta", "title": "v0.92.2-beta",
"notePosition": 90, "notePosition": 100,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -255,7 +281,7 @@
"IykjoAmBpc61" "IykjoAmBpc61"
], ],
"title": "v0.92.1-beta", "title": "v0.92.1-beta",
"notePosition": 100, "notePosition": 110,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -273,7 +299,7 @@
"dq2AJ9vSBX4Y" "dq2AJ9vSBX4Y"
], ],
"title": "v0.92.0-beta", "title": "v0.92.0-beta",
"notePosition": 110, "notePosition": 120,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -291,7 +317,7 @@
"3a8aMe4jz4yM" "3a8aMe4jz4yM"
], ],
"title": "v0.91.6", "title": "v0.91.6",
"notePosition": 120, "notePosition": 130,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -309,7 +335,7 @@
"8djQjkiDGESe" "8djQjkiDGESe"
], ],
"title": "v0.91.5", "title": "v0.91.5",
"notePosition": 130, "notePosition": 140,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -327,7 +353,7 @@
"OylxVoVJqNmr" "OylxVoVJqNmr"
], ],
"title": "v0.91.4-beta", "title": "v0.91.4-beta",
"notePosition": 140, "notePosition": 150,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -345,7 +371,7 @@
"tANGQDvnyhrj" "tANGQDvnyhrj"
], ],
"title": "v0.91.3-beta", "title": "v0.91.3-beta",
"notePosition": 150, "notePosition": 160,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -363,7 +389,7 @@
"hMoBfwSoj1SC" "hMoBfwSoj1SC"
], ],
"title": "v0.91.2-beta", "title": "v0.91.2-beta",
"notePosition": 160, "notePosition": 170,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -381,7 +407,7 @@
"a2XMSKROCl9z" "a2XMSKROCl9z"
], ],
"title": "v0.91.1-beta", "title": "v0.91.1-beta",
"notePosition": 170, "notePosition": 180,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -399,7 +425,7 @@
"yqXFvWbLkuMD" "yqXFvWbLkuMD"
], ],
"title": "v0.90.12", "title": "v0.90.12",
"notePosition": 180, "notePosition": 190,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -417,7 +443,7 @@
"veS7pg311yJP" "veS7pg311yJP"
], ],
"title": "v0.90.11-beta", "title": "v0.90.11-beta",
"notePosition": 190, "notePosition": 200,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -435,7 +461,7 @@
"sq5W9TQxRqMq" "sq5W9TQxRqMq"
], ],
"title": "v0.90.10-beta", "title": "v0.90.10-beta",
"notePosition": 200, "notePosition": 210,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -453,7 +479,7 @@
"yFEGVCUM9tPx" "yFEGVCUM9tPx"
], ],
"title": "v0.90.9-beta", "title": "v0.90.9-beta",
"notePosition": 210, "notePosition": 220,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -471,7 +497,7 @@
"o4wAGqOQuJtV" "o4wAGqOQuJtV"
], ],
"title": "v0.90.8", "title": "v0.90.8",
"notePosition": 220, "notePosition": 230,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -504,7 +530,7 @@
"i4A5g9iOg9I0" "i4A5g9iOg9I0"
], ],
"title": "v0.90.7-beta", "title": "v0.90.7-beta",
"notePosition": 230, "notePosition": 240,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -522,7 +548,7 @@
"ThNf2GaKgXUs" "ThNf2GaKgXUs"
], ],
"title": "v0.90.6-beta", "title": "v0.90.6-beta",
"notePosition": 240, "notePosition": 250,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -540,7 +566,7 @@
"G4PAi554kQUr" "G4PAi554kQUr"
], ],
"title": "v0.90.5-beta", "title": "v0.90.5-beta",
"notePosition": 250, "notePosition": 260,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -567,7 +593,7 @@
"zATRobGRCmBn" "zATRobGRCmBn"
], ],
"title": "v0.90.4", "title": "v0.90.4",
"notePosition": 260, "notePosition": 270,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -585,7 +611,7 @@
"sCDLf8IKn3Iz" "sCDLf8IKn3Iz"
], ],
"title": "v0.90.3", "title": "v0.90.3",
"notePosition": 270, "notePosition": 280,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -603,7 +629,7 @@
"VqqyBu4AuTjC" "VqqyBu4AuTjC"
], ],
"title": "v0.90.2-beta", "title": "v0.90.2-beta",
"notePosition": 280, "notePosition": 290,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -621,7 +647,7 @@
"RX3Nl7wInLsA" "RX3Nl7wInLsA"
], ],
"title": "v0.90.1-beta", "title": "v0.90.1-beta",
"notePosition": 290, "notePosition": 300,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -639,7 +665,7 @@
"GyueACukPWjk" "GyueACukPWjk"
], ],
"title": "v0.90.0-beta", "title": "v0.90.0-beta",
"notePosition": 300, "notePosition": 310,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",
@ -657,7 +683,7 @@
"wyurrlcDl416" "wyurrlcDl416"
], ],
"title": "Release Template", "title": "Release Template",
"notePosition": 310, "notePosition": 320,
"prefix": null, "prefix": null,
"isExpanded": false, "isExpanded": false,
"type": "text", "type": "text",

View File

@ -0,0 +1,61 @@
# v0.95.0
> [!IMPORTANT]
> If you enjoyed this release, consider showing a token of appreciation by:
>
> * Pressing the “Star” button on [GitHub](https://github.com/TriliumNext/Notes) (top-right).
> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran).
> [!CAUTION]
> Sync version has been increased, so update of both the client and server are necessary.
> [!IMPORTANT]
> For canvas notes, the “Mermaid to Excalidraw” feature is no longer functional for now since it relies on an old version of Mermaid diagrams. To avoid having a large library duplicated, we had to let go of this feature. If it's an important feature to you, let us know.
## 💡 Key highlights
* Improvements to the shared notes functionality:
* A new default theme was introduced called Trilium.Rocks (original development by @zerebos)and adapted to our project. New features from this theme include: search, collapsible tree, light/dark mode, mobile mobile.
* Basic syntax highlighting for code blocks has been added, but only if the language is explicitly specified.
* Note icons are now displayed in the share tree.
* Math equations are now rendered in text notes.
## 🐞 Bugfixes
* Text notes stability if the editor crashes:
* Data loss if the editor crashed while it was saving (causing an empty note)
* Blank screen if editor crashes more than once
* [Zen Mode: text formatting commands are missing from UI](https://github.com/TriliumNext/Notes/issues/1370) by @SiriusXT
* [Links: Unable to open notes in a new window](https://github.com/TriliumNext/Notes/pull/2243) by @SiriusXT
* [desktop syncing issues with the app](https://github.com/TriliumNext/Notes/issues/2268)
* LLM bugfixes by @perfectra1n:
* LLM could sometimes save the response in the wrong note
* [Llama3.1 doesn't work](https://github.com/TriliumNext/Notes/issues/2200)
* Text notes:
* [Selection gets incomplete when moving multiple lines up/down](https://github.com/TriliumNext/Notes/issues/2191) by @SiriusXT and @herrkami
* [Markdown import: restore focus after importing markdown](https://github.com/TriliumNext/Notes/pull/2304) by @SiriusXT
* [Ensure images opened in a new tab can be activated](https://github.com/TriliumNext/Notes/pull/2303) by @SiriusXT
* [Unexpected collapse after hoisting a note](https://github.com/TriliumNext/Notes/pull/2293) by @SiriusXT
## ✨ Improvements
* [Tab bar: ensure similar behavior between horizontal/vertical scrolling](https://github.com/TriliumNext/Notes/pull/2177) by @SiriusXT and @rom1dep
* [Two factor: support custom OIDC server](https://github.com/TriliumNext/Notes/pull/2198) by @koderx and @JYC333
* LLM improvements by @perfectra1n
* [Clarify experimental state](https://github.com/TriliumNext/Notes/pull/2217)
* [Simplify (remove embedding system) in order to improve its stability](https://github.com/TriliumNext/Notes/pull/2205)
* Simplify provider selection
* Text editor improvements
* [Relocate link icon in floating toolbar](https://github.com/TriliumNext/Notes/pull/2231) by @SiriusXT
* [Add text alignment options](https://github.com/TriliumNext/Notes/pull/2232) by @SiriusXT
* [Display a warning when using the the x86 build on ARM](https://github.com/TriliumNext/Notes/pull/2281) by @perfectra1n
## 📖 Documentation
* Clarify custom paths for non-root and improve nginx configuration by @hulmgulm
* Multi-factor authentication clarifications by @JYC333
## 🛠️ Technical updates
* Express was updated to the newest major version (5).
* The canvas (Excalidraw) was refactored to use Preact instead of React.
* Desktop version: remove unnecessary locale information to save some space.

View File

@ -9190,6 +9190,90 @@
"value": "bx bx-share-alt", "value": "bx bx-share-alt",
"isInheritable": false, "isInheritable": false,
"position": 30 "position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "iPIMuisry3hd",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "m523cpzocqaD",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
"value": "iRwzGnHPzonm",
"isInheritable": false,
"position": 80
},
{
"type": "relation",
"name": "internalLink",
"value": "bdUJEHsAPYQR",
"isInheritable": false,
"position": 90
},
{
"type": "relation",
"name": "internalLink",
"value": "HcABDtFCkbFN",
"isInheritable": false,
"position": 100
},
{
"type": "relation",
"name": "internalLink",
"value": "GTwFsgaA0lCt",
"isInheritable": false,
"position": 110
},
{
"type": "relation",
"name": "internalLink",
"value": "s1aBHPd79XYj",
"isInheritable": false,
"position": 120
},
{
"type": "relation",
"name": "internalLink",
"value": "grjYqerjn243",
"isInheritable": false,
"position": 130
},
{
"type": "relation",
"name": "internalLink",
"value": "1vHRoWCEjj0L",
"isInheritable": false,
"position": 140
},
{
"type": "relation",
"name": "internalLink",
"value": "gBbsAeiuUxI5",
"isInheritable": false,
"position": 150
},
{
"type": "relation",
"name": "internalLink",
"value": "81SGnPGMk7Xc",
"isInheritable": false,
"position": 160
},
{
"type": "relation",
"name": "internalLink",
"value": "W8vYD3Q1zjCR",
"isInheritable": false,
"position": 170
} }
], ],
"format": "markdown", "format": "markdown",
@ -9204,20 +9288,12 @@
"dataFileName": "Sharing_shared-list.png" "dataFileName": "Sharing_shared-list.png"
}, },
{ {
"attachmentId": "DFUCyGDOpqOt", "attachmentId": "ibqWQUOCMhIE",
"title": "share-multiple-notes-web.png", "title": "image.png",
"role": "image", "role": "image",
"mime": "image/png", "mime": "image/png",
"position": 10, "position": 10,
"dataFileName": "Sharing_share-multiple-not.png" "dataFileName": "Sharing_image.png"
},
{
"attachmentId": "Il8udowRLald",
"title": "share-single-note-web.png",
"role": "image",
"mime": "image/png",
"position": 10,
"dataFileName": "Sharing_share-single-note-.png"
}, },
{ {
"attachmentId": "ShhsPSZVMQKx", "attachmentId": "ShhsPSZVMQKx",
@ -9258,10 +9334,10 @@
"dataFileName": "Serving directly the conte.png" "dataFileName": "Serving directly the conte.png"
}, },
{ {
"attachmentId": "xicVjsf2Kmaz", "attachmentId": "ixkXFTSSkdpL",
"title": "image.png", "title": "image.png",
"role": "image", "role": "image",
"mime": "image/jpg", "mime": "image/png",
"position": 10, "position": 10,
"dataFileName": "1_Serving directly the conte.png" "dataFileName": "1_Serving directly the conte.png"
} }

View File

@ -1,6 +1,32 @@
# Sharing # Sharing
Trilium allows you to share selected notes as **publicly accessible** read-only documents. This feature is particularly useful for publishing content directly from your Trilium notes, making it accessible to others online. Trilium allows you to share selected notes as **publicly accessible** read-only documents. This feature is particularly useful for publishing content directly from your Trilium notes, making it accessible to others online.
<figure class="image"><img style="aspect-ratio:1144/660;" src="Sharing_image.png" width="1144" height="660"></figure>
## Features, interaction and limitations
* Searching by note title.
* Automatic dark/light mode based on the user's browser settings.
* Mobile-friendly layout, with sidebar.
* Collapsible tree with the same note icons as the application.
* Customizable logo.
* Toggle button for dark/light mode, which also stores the user preferences.
* Quick navigation buttons (previous and next note).
* Displaying the date of the last update of the note.
### By note type
<figure class="table" style="width:100%;"><table class="ck-table-resized"><colgroup><col style="width:19.92%;"><col style="width:41.66%;"><col style="width:38.42%;"></colgroup><thead><tr><th>&nbsp;</th><th>Supported features</th><th>Limitations</th></tr></thead><tbody><tr><th><a class="reference-link" href="../Note%20Types/Text.md">Text</a></th><td><ul><li>Table of contents.</li><li>Syntax highlight of code blocks, provided a language is selected (does not work if “Auto-detected” is enabled).</li><li>Rendering for math equations.</li></ul></td><td><ul><li>Including notes is not supported.</li><li>Inline Mermaid diagrams are not rendered.</li></ul></td></tr><tr><th><a class="reference-link" href="../Note%20Types/Code.md">Code</a></th><td><ul><li>Basic support (displaying the contents of the note in a monospace font).</li></ul></td><td><ul><li>No syntax highlight.</li></ul></td></tr><tr><th><a class="reference-link" href="../Note%20Types/Saved%20Search.md">Saved Search</a></th><td colspan="2">Not supported.</td></tr><tr><th><a class="reference-link" href="../Note%20Types/Relation%20Map.md">Relation Map</a></th><td colspan="2">Not supported.</td></tr><tr><th><a class="reference-link" href="../Note%20Types/Note%20Map.md">Note Map</a></th><td colspan="2">Not supported.</td></tr><tr><th><a class="reference-link" href="../Note%20Types/Render%20Note.md">Render Note</a></th><td colspan="2">Not supported.</td></tr><tr><th><a class="reference-link" href="../Note%20Types/Book.md">Book</a></th><td><ul><li>The child notes are displayed in a fixed format.&nbsp;</li></ul></td><td><ul><li>More advanced view types such as the calendar view are not supported.</li></ul></td></tr><tr><th><a class="reference-link" href="../Note%20Types/Mermaid%20Diagrams.md">Mermaid Diagrams</a></th><td><ul><li>The diagram is displayed as a vector image.</li></ul></td><td><ul><li>No further interaction supported.</li></ul></td></tr><tr><th><a class="reference-link" href="../Note%20Types/Canvas.md">Canvas</a></th><td><ul><li>The diagram is displayed as a vector image.</li></ul></td><td><ul><li>No further interaction supported.</li></ul></td></tr><tr><th><a class="reference-link" href="../Note%20Types/Web%20View.md">Web View</a></th><td colspan="2">Not supported.</td></tr><tr><th><a class="reference-link" href="../Note%20Types/Mind%20Map.md">Mind Map</a></th><td>The diagram is displayed as a vector image.</td><td><ul><li>No further interaction supported.</li></ul></td></tr><tr><th><a class="reference-link" href="../Note%20Types/Geo%20Map.md">Geo Map</a></th><td colspan="2">Not supported.</td></tr><tr><th><a class="reference-link" href="../Note%20Types/File.md">File</a></th><td>Basic interaction (downloading the file).</td><td><ul><li>No further interaction supported.</li></ul></td></tr></tbody></table></figure>
While the sharing feature is powerful, it has some limitations:
* **Code Notes**: No syntax highlighting.
* **Static Note Tree**
* **Protected Notes**: Cannot be shared.
* **Include Notes**: Not supported.
Some of these limitations may be addressed in future updates.
## Prerequisites ## Prerequisites
To use the sharing feature, you must have a <a class="reference-link" href="../Installation%20%26%20Setup/Server%20Installation.md">Server Installation</a> of Trilium. This is necessary because the notes will be hosted from the server. To use the sharing feature, you must have a <a class="reference-link" href="../Installation%20%26%20Setup/Server%20Installation.md">Server Installation</a> of Trilium. This is necessary because the notes will be hosted from the server.
@ -12,14 +38,10 @@ To use the sharing feature, you must have a <a class="reference-link" href="../
![Share Note](Sharing_share-single-note.png) ![Share Note](Sharing_share-single-note.png)
2. **Access the Shared Note**: The link provided will open the note in your browser. If your server is not configured with a public IP, the URL will refer to `localhost (127.0.0.1)`. 2. **Access the Shared Note**: The link provided will open the note in your browser. If your server is not configured with a public IP, the URL will refer to `localhost (127.0.0.1)`.
![Shared Note Example](Sharing_share-single-note-.png)
## Sharing a Note Subtree ## Sharing a Note Subtree
When you share a note, you actually share the entire subtree of notes beneath it. If the note has child notes, they will also be included in the shared content. For example, sharing the "Formatting" subtree will display a page with basic navigation for exploring all the notes within that subtree. When you share a note, you actually share the entire subtree of notes beneath it. If the note has child notes, they will also be included in the shared content. For example, sharing the "Formatting" subtree will display a page with basic navigation for exploring all the notes within that subtree.
![Shared Subtree Example](Sharing_share-multiple-not.png)
## Viewing All Shared Notes ## Viewing All Shared Notes
You can view a list of all shared notes by clicking on "Show Shared Notes Subtree." This allows you to manage and navigate through all the notes you have made public. You can view a list of all shared notes by clicking on "Show Shared Notes Subtree." This allows you to manage and navigate through all the notes you have made public.
@ -36,7 +58,7 @@ To protect shared notes with a username and password, you can use the `#shareCre
### Customizing the Appearance of Shared Notes ### Customizing the Appearance of Shared Notes
The default shared page is basic in design, but you can customize it using your own CSS: The default design should be a good starting point, but you can customize it using your own CSS:
* **Custom CSS**: Link a CSS <a class="reference-link" href="../Note%20Types/Code.md">Code</a> note to the shared page by adding a `~shareCss` relation to the note. If you want this style to apply to the entire subtree, make the label inheritable. You can hide the CSS code note from the tree navigation by adding the `#shareHiddenFromTree` label. * **Custom CSS**: Link a CSS <a class="reference-link" href="../Note%20Types/Code.md">Code</a> note to the shared page by adding a `~shareCss` relation to the note. If you want this style to apply to the entire subtree, make the label inheritable. You can hide the CSS code note from the tree navigation by adding the `#shareHiddenFromTree` label.
* **Omitting Default CSS**: For extensive styling changes, use the `#shareOmitDefaultCss` label to avoid conflicts with Trilium's [default stylesheet](../Basic%20Concepts%20and%20Features/Themes.md). * **Omitting Default CSS**: For extensive styling changes, use the `#shareOmitDefaultCss` label to avoid conflicts with Trilium's [default stylesheet](../Basic%20Concepts%20and%20Features/Themes.md).
@ -79,19 +101,10 @@ To customize the favicon for your shared pages, create a relation `~shareFavicon
You can designate a specific note or folder as the root of your shared content by adding the `#shareRoot` label. This note will be linked when visiting `[http://domain.tld/share](http://domain/share)`, making it easier to use Trilium as a fully-fledged website. Consider combining this with the `#shareIndex` label, which will display a list of all shared notes. You can designate a specific note or folder as the root of your shared content by adding the `#shareRoot` label. This note will be linked when visiting `[http://domain.tld/share](http://domain/share)`, making it easier to use Trilium as a fully-fledged website. Consider combining this with the `#shareIndex` label, which will display a list of all shared notes.
## Limitations
While the sharing feature is powerful, it has some limitations:
* **No Relation Map Support**
* **Book Notes**: Only show a list of child notes.
* **Code Notes**: No syntax highlighting.
* **Static Note Tree**
* **Protected Notes**: Cannot be shared.
* **Include Notes**: Not supported.
Some of these limitations may be addressed in future updates.
## Attribute reference ## Attribute reference
<figure class="table"><table><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>shareHiddenFromTree</code></td><td>this note is hidden from left navigation tree, but still accessible with its URL</td></tr><tr><td><code>shareExternalLink</code></td><td>note will act as a link to an external website in the share tree</td></tr><tr><td><code>shareAlias</code></td><td>define an alias using which the note will be available under <code>https://your_trilium_host/share/[your_alias]</code></td></tr><tr><td><code>shareOmitDefaultCss</code></td><td>default share page CSS will be omitted. Use when you make extensive styling changes.</td></tr><tr><td><code>shareRoot</code></td><td>marks note which is served on /share root.</td></tr><tr><td><code>shareDescription</code></td><td>define text to be added to the HTML meta tag for description</td></tr><tr><td><code>shareRaw</code></td><td>Note will be served in its raw format, without HTML wrapper. See also&nbsp;<a class="reference-link" href="Sharing/Serving%20directly%20the%20content%20o.md">Serving directly the content of a note</a>&nbsp;for an alternative method without setting an attribute.</td></tr><tr><td><code>shareDisallowRobotIndexing</code></td><td><p>Indicates to web crawlers that the page should not be indexed of this note by:</p><ul><li>Setting the <code>X-Robots-Tag: noindex</code> HTTP header.</li><li>Setting the <code>noindex, follow</code> meta tag.</li></ul></td></tr><tr><td><code>shareCredentials</code></td><td>require credentials to access this shared note. Value is expected to be in format <code>username:password</code>. Don't forget to make this inheritable to apply to child-notes/images.</td></tr><tr><td><code>shareIndex</code></td><td>Note with this label will list all roots of shared notes.</td></tr></tbody></table></figure> <figure class="table"><table><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>shareHiddenFromTree</code></td><td>this note is hidden from left navigation tree, but still accessible with its URL</td></tr><tr><td><code>shareExternalLink</code></td><td>note will act as a link to an external website in the share tree</td></tr><tr><td><code>shareAlias</code></td><td>define an alias using which the note will be available under <code>https://your_trilium_host/share/[your_alias]</code></td></tr><tr><td><code>shareOmitDefaultCss</code></td><td>default share page CSS will be omitted. Use when you make extensive styling changes.</td></tr><tr><td><code>shareRoot</code></td><td>marks note which is served on /share root.</td></tr><tr><td><code>shareDescription</code></td><td>define text to be added to the HTML meta tag for description</td></tr><tr><td><code>shareRaw</code></td><td>Note will be served in its raw format, without HTML wrapper. See also&nbsp;<a class="reference-link" href="Sharing/Serving%20directly%20the%20content%20o.md">Serving directly the content of a note</a>&nbsp;for an alternative method without setting an attribute.</td></tr><tr><td><code>shareDisallowRobotIndexing</code></td><td><p>Indicates to web crawlers that the page should not be indexed of this note by:</p><ul><li>Setting the <code>X-Robots-Tag: noindex</code> HTTP header.</li><li>Setting the <code>noindex, follow</code> meta tag.</li></ul></td></tr><tr><td><code>shareCredentials</code></td><td>require credentials to access this shared note. Value is expected to be in format <code>username:password</code>. Don't forget to make this inheritable to apply to child-notes/images.</td></tr><tr><td><code>shareIndex</code></td><td>Note with this label will list all roots of shared notes.</td></tr></tbody></table></figure>
## Credits
Since v0.95.0, a new theme was introduced (and enabled by default) which greatly improves the visual aspect of the Share feature, as well as its functionality (such as mobile support, dark/light mode, collapsible tree, etc.). This theme is an adaptation of the [Trilium Rocks!](https://github.com/zerebos/trilium.rocks) by [zerebos](https://github.com/zerebos).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,9 +1,7 @@
# Serving directly the content of a note # Serving directly the content of a note
When accessing a shared note, Trilium will render it as a web page. Sometimes it's desirable to serve the content directly so that it can be used in a script or downloaded by the user. When accessing a shared note, Trilium will render it as a web page. Sometimes it's desirable to serve the content directly so that it can be used in a script or downloaded by the user.
| A note displayed as a web page (HTML) | A note displayed as a raw format | <figure class="table"><table><thead><tr><th>A note displayed as a web page (HTML)</th><th>A note displayed as a raw format</th></tr></thead><tbody><tr><td><figure class="image"><img style="aspect-ratio:738/275;" src="1_Serving directly the conte.png" width="738" height="275"></figure></td><td><img src="Serving directly the conte.png"></td></tr></tbody></table></figure>
| --- | --- |
| ![](1_Serving%20directly%20the%20conte.png) | ![](Serving%20directly%20the%20conte.png) |
## By adding an attribute to the note ## By adding an attribute to the note

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@ -1,6 +1,6 @@
{ {
"name": "@triliumnext/source", "name": "@triliumnext/source",
"version": "0.94.1", "version": "0.95.0",
"description": "Build your personal knowledge base with TriliumNext Notes", "description": "Build your personal knowledge base with TriliumNext Notes",
"directories": { "directories": {
"doc": "docs" "doc": "docs"
@ -20,23 +20,23 @@
"chore:update-build-info": "tsx ./scripts/update-build-info.ts", "chore:update-build-info": "tsx ./scripts/update-build-info.ts",
"chore:update-version": "tsx ./scripts/update-version.ts", "chore:update-version": "tsx ./scripts/update-version.ts",
"test:all": "pnpm test:parallel && pnpm test:sequential", "test:all": "pnpm test:parallel && pnpm test:sequential",
"test:parallel": "pnpm nx run-many -t test --all --exclude=ckeditor5-mermaid,ckeditor5-math --parallel", "test:parallel": "pnpm nx run-many -t test --all --exclude=server,ckeditor5-mermaid,ckeditor5-math --parallel",
"test:sequential": "pnpm nx run-many -t test --projects=ckeditor5-mermaid,ckeditor5-math --parallel=1", "test:sequential": "pnpm nx run-many -t test --projects=server,ckeditor5-mermaid,ckeditor5-math --parallel=1",
"coverage": "pnpm nx run-many -t coverage" "coverage": "pnpm nx run-many -t coverage"
}, },
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"@electron/rebuild": "4.0.1", "@electron/rebuild": "4.0.1",
"@nx/devkit": "21.1.3", "@nx/devkit": "21.2.0",
"@nx/esbuild": "21.1.3", "@nx/esbuild": "21.2.0",
"@nx/eslint": "21.1.3", "@nx/eslint": "21.2.0",
"@nx/eslint-plugin": "21.1.3", "@nx/eslint-plugin": "21.2.0",
"@nx/express": "21.1.3", "@nx/express": "21.2.0",
"@nx/js": "21.1.3", "@nx/js": "21.2.0",
"@nx/node": "21.1.3", "@nx/node": "21.2.0",
"@nx/playwright": "21.1.3", "@nx/playwright": "21.2.0",
"@nx/vite": "21.1.3", "@nx/vite": "21.2.0",
"@nx/web": "21.1.3", "@nx/web": "21.2.0",
"@playwright/test": "^1.36.0", "@playwright/test": "^1.36.0",
"@triliumnext/server": "workspace:*", "@triliumnext/server": "workspace:*",
"@types/express": "^5.0.0", "@types/express": "^5.0.0",
@ -53,7 +53,7 @@
"jiti": "2.4.2", "jiti": "2.4.2",
"jsdom": "~26.1.0", "jsdom": "~26.1.0",
"jsonc-eslint-parser": "^2.1.0", "jsonc-eslint-parser": "^2.1.0",
"nx": "21.1.3", "nx": "21.2.0",
"react-refresh": "^0.17.0", "react-refresh": "^0.17.0",
"rollup-plugin-webpack-stats": "2.0.7", "rollup-plugin-webpack-stats": "2.0.7",
"tslib": "^2.3.0", "tslib": "^2.3.0",
@ -79,16 +79,13 @@
"url": "https://github.com/TriliumNext/Notes/issues" "url": "https://github.com/TriliumNext/Notes/issues"
}, },
"homepage": "https://github.com/TriliumNext/Notes#readme", "homepage": "https://github.com/TriliumNext/Notes#readme",
"dependencies": {
"axios": "^1.6.0",
"express": "^5.0.0"
},
"packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac", "packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac",
"pnpm": { "pnpm": {
"patchedDependencies": { "patchedDependencies": {
"@ckeditor/ckeditor5-mention": "patches/@ckeditor__ckeditor5-mention.patch", "@ckeditor/ckeditor5-mention": "patches/@ckeditor__ckeditor5-mention.patch",
"@ckeditor/ckeditor5-code-block": "patches/@ckeditor__ckeditor5-code-block.patch", "@ckeditor/ckeditor5-code-block": "patches/@ckeditor__ckeditor5-code-block.patch",
"ckeditor5": "patches/ckeditor5.patch" "ckeditor5": "patches/ckeditor5.patch",
"@nx/js": "patches/@nx__js.patch"
}, },
"overrides": { "overrides": {
"node-abi": "4.9.0", "node-abi": "4.9.0",
@ -102,7 +99,24 @@
"nanoid@>=4.0.0 <5.0.9": ">=5.0.9", "nanoid@>=4.0.0 <5.0.9": ">=5.0.9",
"dompurify@<3.2.4": ">=3.2.4", "dompurify@<3.2.4": ">=3.2.4",
"esbuild@<=0.24.2": ">=0.25.0" "esbuild@<=0.24.2": ">=0.25.0"
} },
"ignoredBuiltDependencies": [
"sqlite3"
],
"onlyBuiltDependencies": [
"@parcel/watcher",
"@scarf/scarf",
"better-sqlite3",
"bufferutil",
"core-js-pure",
"electron",
"electron-winstaller",
"esbuild",
"fs-xattr",
"macos-alias",
"nx",
"utf-8-validate"
]
}, },
"nx": { "nx": {
"name": "triliumnext" "name": "triliumnext"

View File

@ -24,13 +24,13 @@
"@codemirror/lang-html": "6.4.9", "@codemirror/lang-html": "6.4.9",
"@codemirror/lang-javascript": "6.2.4", "@codemirror/lang-javascript": "6.2.4",
"@codemirror/lang-json": "6.0.1", "@codemirror/lang-json": "6.0.1",
"@codemirror/lang-markdown": "6.3.2", "@codemirror/lang-markdown": "6.3.3",
"@codemirror/lang-php": "6.0.1", "@codemirror/lang-php": "6.0.1",
"@codemirror/lang-vue": "0.1.3", "@codemirror/lang-vue": "0.1.3",
"@codemirror/lang-xml": "6.1.0", "@codemirror/lang-xml": "6.1.0",
"@codemirror/legacy-modes": "6.5.1", "@codemirror/legacy-modes": "6.5.1",
"@codemirror/search": "6.5.11", "@codemirror/search": "6.5.11",
"@codemirror/view": "6.37.1", "@codemirror/view": "6.37.2",
"@fsegurai/codemirror-theme-abcdef": "6.2.0", "@fsegurai/codemirror-theme-abcdef": "6.2.0",
"@fsegurai/codemirror-theme-abyss": "6.2.0", "@fsegurai/codemirror-theme-abyss": "6.2.0",
"@fsegurai/codemirror-theme-android-studio": "6.2.0", "@fsegurai/codemirror-theme-android-studio": "6.2.0",
@ -61,6 +61,6 @@
"@ssddanbrown/codemirror-lang-twig": "1.0.0", "@ssddanbrown/codemirror-lang-twig": "1.0.0",
"codemirror-lang-hcl": "0.1.0", "codemirror-lang-hcl": "0.1.0",
"codemirror-lang-mermaid": "0.5.0", "codemirror-lang-mermaid": "0.5.0",
"eslint-linter-browserify": "9.28.0" "eslint-linter-browserify": "9.29.0"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@triliumnext/commons", "name": "@triliumnext/commons",
"version": "0.94.1", "version": "0.95.0",
"description": "Shared library between the clients (e.g. browser, Electron) and the server, mostly for type definitions and utility methods.", "description": "Shared library between the clients (e.g. browser, Electron) and the server, mostly for type definitions and utility methods.",
"private": true, "private": true,
"type": "module", "type": "module",

View File

@ -9,8 +9,6 @@ export interface MimeTypeDefinition {
mime: string; mime: string;
/** The name of the language/mime type as defined by highlight.js (or one of the aliases), in order to be used for syntax highlighting such as inside code blocks. */ /** The name of the language/mime type as defined by highlight.js (or one of the aliases), in order to be used for syntax highlighting such as inside code blocks. */
mdLanguageCode?: string; mdLanguageCode?: string;
/** If specified, will load the corresponding highlight file from the given path instead of `node_modules`. */
codeMirrorSource?: string;
} }
export interface MimeType extends MimeTypeDefinition { export interface MimeType extends MimeTypeDefinition {
@ -43,7 +41,7 @@ export const MIME_TYPES_DICT: readonly MimeTypeDefinition[] = Object.freeze([
{ title: "ASN.1", mime: "text/x-ttcn-asn" }, { title: "ASN.1", mime: "text/x-ttcn-asn" },
{ title: "ASP.NET", mime: "application/x-aspx" }, { title: "ASP.NET", mime: "application/x-aspx" },
{ title: "Asterisk", mime: "text/x-asterisk" }, { title: "Asterisk", mime: "text/x-asterisk" },
{ title: "Batch file (DOS)", mime: "application/x-bat", highlightJs: "dos", codeMirrorSource: "libraries/codemirror/batch.js" }, { title: "Batch file (DOS)", mime: "application/x-bat", highlightJs: "dos" },
{ title: "Brainfuck", mime: "text/x-brainfuck", mdLanguageCode: "brainfuck" }, { title: "Brainfuck", mime: "text/x-brainfuck", mdLanguageCode: "brainfuck" },
{ title: "C", mime: "text/x-csrc", mdLanguageCode: "c", default: true }, { title: "C", mime: "text/x-csrc", mdLanguageCode: "c", default: true },
{ title: "C#", mime: "text/x-csharp", mdLanguageCode: "csharp", default: true }, { title: "C#", mime: "text/x-csharp", mdLanguageCode: "csharp", default: true },
@ -175,7 +173,7 @@ export const MIME_TYPES_DICT: readonly MimeTypeDefinition[] = Object.freeze([
{ title: "Swift", mime: "text/x-swift", default: true }, { title: "Swift", mime: "text/x-swift", default: true },
{ title: "SystemVerilog", mime: "text/x-systemverilog" }, { title: "SystemVerilog", mime: "text/x-systemverilog" },
{ title: "Tcl", mime: "text/x-tcl", mdLanguageCode: "tcl" }, { title: "Tcl", mime: "text/x-tcl", mdLanguageCode: "tcl" },
{ title: "Terraform (HCL)", mime: "text/x-hcl", highlightJs: "terraform", highlightJsSource: "libraries", codeMirrorSource: "libraries/codemirror/hcl.js" }, { title: "Terraform (HCL)", mime: "text/x-hcl", highlightJs: "terraform" },
{ title: "Textile", mime: "text/x-textile" }, { title: "Textile", mime: "text/x-textile" },
{ title: "TiddlyWiki ", mime: "text/x-tiddlywiki" }, { title: "TiddlyWiki ", mime: "text/x-tiddlywiki" },
{ title: "Tiki wiki", mime: "text/tiki" }, { title: "Tiki wiki", mime: "text/tiki" },

17
patches/@nx__js.patch Normal file
View File

@ -0,0 +1,17 @@
diff --git a/src/utils/assets/copy-assets-handler.js b/src/utils/assets/copy-assets-handler.js
index 6b68205d833ce9e8277283ac31230c020d2921ec..2f0a7f018b03eae3b8f3ce1a4cf4790aaafed677 100644
--- a/src/utils/assets/copy-assets-handler.js
+++ b/src/utils/assets/copy-assets-handler.js
@@ -39,12 +39,6 @@ class CopyAssetsHandler {
this.callback = opts.callback ?? exports.defaultFileEventHandler;
// TODO(jack): Should handle nested .gitignore files
this.ignore = (0, ignore_1.default)();
- const gitignore = pathPosix.join(opts.rootDir, '.gitignore');
- const nxignore = pathPosix.join(opts.rootDir, '.nxignore');
- if ((0, node_fs_1.existsSync)(gitignore))
- this.ignore.add((0, node_fs_1.readFileSync)(gitignore).toString());
- if ((0, node_fs_1.existsSync)(nxignore))
- this.ignore.add((0, node_fs_1.readFileSync)(nxignore).toString());
this.assetGlobs = opts.assets.map((f) => {
let isGlob = false;
let pattern;

1856
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -2,22 +2,5 @@ packages:
- packages/* - packages/*
- apps/* - apps/*
ignoredBuiltDependencies:
- sqlite3
onlyBuiltDependencies:
- '@parcel/watcher'
- '@scarf/scarf'
- bufferutil
- core-js-pure
- esbuild
- nx
- utf-8-validate
- better-sqlite3
- electron
- electron-winstaller
- fs-xattr
- macos-alias
shamefullyHoist: true shamefullyHoist: true
nodeLinker: isolated nodeLinker: isolated

View File

@ -6,10 +6,26 @@
"prHourlyLimit": 0, "prHourlyLimit": 0,
"prConcurrentLimit": 0, "prConcurrentLimit": 0,
"branchConcurrentLimit": 0, "branchConcurrentLimit": 0,
"ignorePaths": [
"**/node_modules/**",
"apps/edit-docs/demo/**",
"apps/server/src/assets/doc_notes/**",
"docs/**"
],
"html": {
"enabled": false
},
"bun": {
"enabled": false
},
"packageRules": [ "packageRules": [
{ {
"matchPackageNames": "@fsegurai/codemirror-theme-**", "matchPackageNames": "@fsegurai/codemirror-theme-**",
"groupName": "codemirror themes" "groupName": "codemirror themes"
},
{
"matchPackageNames": "**-config-ckeditor5",
"groupName": "ckeditor5 config packages"
} }
] ]
} }

View File

@ -59,6 +59,9 @@
}, },
{ {
"path": "./packages/share-theme" "path": "./packages/share-theme"
},
{
"path": "./apps/website"
} }
] ]
} }