思源笔记 v2.11.0 版本深度解析查询嵌入块执行 JavaScript 与数据同步冲突合并改进【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan本文基于思源笔记SiYuan仓库内的 v2.11.0 版本发布记录另有中文版本与繁体中文版本并结合当前仓库内核与前端源码系统梳理该版本的核心新特性、编辑器与只读模式改进、Docker 鉴权环境变量、开发者 API 与数据库表格视图相关变更。读完本文你将掌握查询嵌入块//!js脚本的编写与底层执行链路、Docker 部署跳过授权码检查的配置方法以及该版本在同步、历史、移动端等维度的全部行为调整。一、版本概览v2.11.0 是该系列版本中承上启下的一次重要发布两个核心方向分别是查询嵌入块Query Embed Block支持执行 JavaScript此前嵌入块只能依赖固定 SQL 语句进行查询展示本版本起可在嵌入块内编写 JavaScript动态决定要展示哪些区块显著增强了查询展示的灵活性数据同步冲突合并改进优化了数据合并场景下的同步感知与冲突处理降低多端编辑时的数据不一致风险。与此同时该版本还围绕编辑器只读模式、HTML 块解析规则、历史文件列表、设置窗口交互、Docker 鉴权环境变量等做了大量增强与缺陷修复并为开发者新增了内核 API 与插件 API。下文逐项展开。二、核心新特性查询嵌入块支持执行 JavaScript1. 查询嵌入块原本的工作方式思源笔记中的“嵌入块”NodeBlockQueryEmbed数据库类型标记为query_embed用于通过一段 SQL 在文档中动态展示命中的区块。内核侧这一能力由三条 HTTP API 支撑见 kernel/api/router.go 的路由注册POST /api/search/searchEmbedBlock // 按 SQL 语句搜索区块并回填嵌入块 POST /api/search/getEmbedBlock // 按指定的 includeIDs 列表获取区块 POST /api/search/updateEmbedBlock // 更新嵌入块内容v2.11.0 新增的内部 API其中searchEmbedBlock会把嵌入块内容当作 SQL 语句交给内核执行查询对应实现位于 kernel/api/search.go 与 kernel/model/search.go。值得注意的一个细节是查询结果中的query_embed类型块会被显式跳过避免“嵌入块再嵌入嵌入块”造成递归展示这一点在 kernel/model/search.go 的buildEmbedBlock中有明确注释。2. 新增的//!js脚本模式v2.11.0 之后若嵌入块内容以//!js开头前端将不再把它当作 SQL而是当作一段 JavaScript 脚本执行。其渲染入口与判定逻辑位于 app/src/protyle/render/blockRender.tsconst content Lute.UnEscapeHTMLStr(item.getAttribute(data-content)); ... if (content.startsWith(//!js)) { const includeIDs new Function( fetchSyncPost, item, protyle, top, content)(fetchSyncPost, item, protyle, top); if (includeIDs instanceof Promise) { includeIDs.then((promiseIds) { if (Array.isArray(promiseIds)) { fetchPost(/api/search/getEmbedBlock, { ... }, renderEmbed); } }); } else if (Array.isArray(includeIDs)) { ... } }从源码结构可以提炼出该机制的三层含义脚本载体//!js之后的内容被包装进new Function执行因此脚本体内应通过return语句返回结果注入参数执行时内核会注入四个可用变量——fetchSyncPost同步调用内核 API 的函数、item当前嵌入块 DOM 元素、protyle当前编辑器实例与top滚动位置相关参数返回值约定脚本既可以直接返回一个区块 ID 字符串数组也可以返回一个Promise例如内部使用await/.then异步拉取数据只要该 Promise 最终 resolve 成一个数组即可。数组中的区块 ID 会随后被提交给/api/search/getEmbedBlock由内核按 ID 精确取块并渲染getEmbedBlock的实现在 kernel/model/search.go。3. 脚本编写示例一个典型的//!js查询嵌入块可写成下面这种“先查询 SQL、再返回 ID 列表”的形态示意代码//!js return (async () { const r await fetchSyncPost(/api/query/sql, { stmt: SELECT id FROM blocks WHERE type d AND content LIKE %SiYuan% LIMIT 20 }); return r.data.map((item) item.id); })();也可以同步遍历、直接返回 ID 数组//!js return [20240101000000-abc, 20240101000000-def];脚本中还可按需读取注入的item.getAttribute(custom-heading-mode)决定标题块展示模式其取值0/1/2与编辑器全局配置headingEmbedMode的映射关系同样可见于 blockRender.ts从而实现“同样的嵌入块在不同文档中展示不同细节粒度”的动态效果。4. 配套的内部 API/api/search/updateEmbedBlock为了让“脚本嵌入块”的更新与回写具备完整链路v2.11.0 还新增了内部内核 API/api/search/updateEmbedBlock见 kernel/api/search.go。其底层实现 kernel/model/search.go 首先通过区块树校验目标块确实存在且类型为query_embed随后将传入的新内容写回嵌入块否则返回ErrBlockNotFound或 “not query embed block” 错误。需要说明的是当前仓库已迭代至 v3.x上述 API 与//!js渲染机制在后续版本中被持续完善例如结果排序稳定性等但其“脚本决定 ID 集合 → getEmbedBlock 精确取块 → 渲染回填”的核心链路自 v2.11.0 起便已确立。三、数据同步冲突合并与合并感知改进该版本对多端数据同步的可靠性做了针对性增强对应两条改进项改进存在数据合并时的数据同步感知当云端与其他端发生数据合并时本地同步状态能更及时、准确地反馈给用户改进数据同步冲突合并优化冲突场景下的合并策略降低丢失改动或产生重复内容的概率。从代码组织上看思源的数据同步核心逻辑集中在 kernel/model/sync.go 以及配套的 kernel/model/push_queue.go、kernel/model/push_reload.go 等文件中由同步队列、冲突合并与推送重载等流程构成v2.11.0 的冲突合并调整即落在这条链路上。对普通用户而言升级到该版本后建议关注同步后是否出现“合并冲突”提示并核对被合并文档的最终内容。四、编辑器与只读模式可用性全面增强1. 只读模式改进只读模式Read-only Mode在本版本获得多处打磨改进编辑器只读模式整体表现交互与状态一致性只读模式下支持使用AltO、AltB与AltG这三个快捷键分别对应大纲Outline、反向链接Backlinks与关系图Graph的呼出能力。此前这些快捷键在只读模式下被禁用本版本放开后在分享或纯阅读场景下也能快速调起相关面板。2. 输入与编辑相关的缺陷修复#输入标题块后无法触发斜杠菜单修复在行首输入#形成标题块后、紧接着呼出/斜杠菜单失效的问题内容以foo开头时 Enter 无法新建块此前一段以类 HTML 标签文本开头的内容会干扰“回车拆块”的判定现已在解析层面修正包含转义符的纯文本复制粘贴改进了粘贴含\等转义字符的纯文本时的处理避免内容被意外转义或截断代码块最后一行三击无法选中修复三击选择整行时对代码块末行命中失效的问题Windows 自定义插入代码块快捷键异常修复 Windows 端为“插入代码块”绑定自定义快捷键后行为异常的问题兼容百度输入法双引号自动补全针对百度输入法在中文输入状态下自动补全成对双引号与思源自带引号配对逻辑冲突的情况做了适配。3. HTML 块解析规则收紧版本明确了一条规则只有使用div包裹的 HTML 代码才会被解析为 HTML 块。换言之粘贴或编写span、p等单独标签时不再一律生成 HTML 块只有外层为div的内容才会走 HTML 块解析路径这有利于降低误判率、保持块类型可控。若你的文档此前依赖非div包裹的 HTML 生成 HTML 块升级后需按新规则改写。五、Docker 部署通过SIYUAN_ACCESS_AUTH_CODE_BYPASStrue跳过授权码检查1. 背景Docker 强制要求访问授权码自更早版本起思源在 Docker 容器中部署时要求必须显式设置访问授权码--accessAuthCode命令行参数或SIYUAN_ACCESS_AUTH_CODE环境变量否则内核会直接终止启动。这一安全约束在 kernel/util/working.go 的BootWithFlags中有完整实现Container ContainerStd if RunInContainer { Container ContainerDocker if AccessAuthCode { // Still empty? interruptBoot : true if SiYuanAccessAuthCodeBypass { interruptBoot false fmt.Println(bypass access auth code check since the env [SIYUAN_ACCESS_AUTH_CODE_BYPASS] is set to [true]) } if interruptBoot { fmt.Printf(the access authorization code command line parameter (--accessAuthCode) must be set when deploying via Docker\n) os.Exit(logging.ExitCodeSecurityRisk) } } }2. 新增的旁路开关v2.11.0 增加了一个例外当设置环境变量SIYUAN_ACCESS_AUTH_CODE_BYPASStrue时跳过“空授权码”的强制检查。该环境变量在启动早期被读取并解析为布尔值见 kernel/util/working.goSiYuanAccessAuthCodeBypass false // 是否跳过空锁屏密码检查 ... if SiYuanAccessAuthCodeBypass, err strconv.ParseBool(os.Getenv(SIYUAN_ACCESS_AUTH_CODE_BYPASS)); err ! nil { SiYuanAccessAuthCodeBypass false }典型 Docker 部署示例docker run -d -p 6806:6806 \ -v /opt/siyuan:/siyuan/workspace \ -e SIYUAN_ACCESS_AUTH_CODE_BYPASStrue \ b3log/siyuan:latest需要注意的安全边界是该开关只作用于“未设置授权码”的情形即 AccessAuthCode分支其语义是“允许容器在未配置访问授权码时照常启动”而不是绕过已设置的授权码校验。若你在公网直接暴露 6806 端口仍建议配置强授权码而非依赖该旁路变量避免未授权访问风险。从内核常量可知容器场景下服务端口的默认值固定为6806见 kernel/util/working.go 的FixedPort 6806。六、界面、历史与移动端体验调整1. 桌面端界面交互拖拽菜单中的文本输入区大小时自动调整菜单大小部分菜单内含可拖拽缩放的文本域此前缩放文本域不会带动菜单整体尺寸现已联动设置窗口支持拖拽允许通过拖拽窗口标题区域移动设置窗口此前在部分主题下设置窗口无法被拖动新增移动到新窗口快捷键可将当前页签文档、数据库等移动到新窗口打开便于多窗口分屏工作修复底部停靠栏悬浮层遮挡点击底部停靠栏悬浮窗口展开时会遮挡文档树最后一项与“提及”入口导致无法点击本版本修复了命中区域问题改进索引校验任务栏推送消息索引校验任务完成后的系统通知文案与时机更准确。2. 历史与文件历史列出文件历史时遵循编辑器历史保留天数设置此前文件历史File History列表可能超出“编辑器历史保留天数”的约束本版本统一了两者的保留口径避免列出已被清理策略淘汰的更早历史版本。3. 移动端与多端适配改进移动端浏览器窗口标题优化 PWA / 浏览器方式打开时页面的窗口标题展示便于多标签切换识别Android 小窗模式软键盘黑色遮挡修复 Android 分屏小窗模式下软键盘弹出导致输入区域被黑色遮挡的问题移动端未打开文档时无法退出应用修复移动端在未打开任何文档时 “退出应用”入口不可用的问题。4. 搜索与内容行级备注Inline Memos无法被搜索到修复行级备注块未进入索引、在搜索中无法命中的缺陷。七、数据库表格视图交互、历史与渲染性能v2.11.0 在“属性视图/数据库”方向上的改动集中在表格视图Table View多数归类在开发者Development条目下但同样影响日常使用体验变更说明文档/快照历史支持数据库表格视图数据库表格视图所在文档现在可以参与“文档历史 / 快照历史”的回滚查看多选列选项去重修复编辑多选列选项时出现重复选项的问题Tab/ShiftTab切换单元格表格视图中可用 Tab 跳转到下一个单元格、ShiftTab 跳转到上一个键盘流操作更顺畅更新时间列渲染性能优化“更新时间”列在数据量较大时的渲染开销排序状态下的插入行位置表格按某列排序后新增行时输入光标定位更符合预期表格视图交互与文案统一并优化了右键菜单、列头操作等交互细节与界面文案八、开发者相关内核 API 鉴权与文件访问控制该版本在安全与 API 层面做了两件对插件、社区集成有直接影响的事改进内核 API 鉴权内核 HTTP API 的鉴权流程得到加固统一了鉴权判定路径降低被绕过或误判的概率为部分内核 API 添加文件访问控制部分能够触及工作空间文件系统的内核 API 新增了访问范围校验防止越权读取/写入工作空间之外的文件。此外为配合前面提到的脚本嵌入块能力新增了内部内核 API/api/search/updateEmbedBlock上文已述同时新增插件 APIopenMobileFileById允许插件在移动端通过文档 ID 直接打开文件其调用入口在当前仓库前端可参见 app/src/plugin/API.ts 中的对应注册与封装。九、底层升级Electron v27.1.2本版本将桌面端外壳从旧版 Electron 升级到v27.1.2改动分类为 Refactor。这属于 Chromium / Node.js 底层运行时升级主要影响桌面端的渲染性能、系统级稳定性与安全补丁覆盖。若你在 Linux/macOS/Windows 桌面端使用升级后若发现旧的快捷键或窗口行为差异属于 Electron 版本带来的正常范围变化。十、升级建议与小结v2.11.0 的完整改动可按类别归纳如下引入特性Feature查询嵌入块支持执行 JavaScript改进功能Enhancement只读模式、图片导出、输入法兼容、移动端标题、Docker 鉴权旁路环境变量、菜单自适应、文件历史口径、代理请求稳定性、转义符粘贴、云端设置 UI、索引校验推送、同步合并感知与冲突合并、只读模式快捷键、停靠栏悬浮点击、设置窗口拖拽、移动到新窗口快捷键、用户指南数据重置警告、HTML 块解析规则修复缺陷Bugfix#标题后斜杠菜单、行级备注搜索、代码块三击、移动端退出应用、Android 小窗键盘遮挡、Windows 快捷键异常、foo开头回车拆块开发重构Refactor升级 Electron v27.1.2开发者Development数据库表格视图文档历史、内核 API 鉴权加固、多选列去重、Tab 键单元格切换、更新时间列渲染优化、排序后插入行定位、表格视图交互文案、内核 API 文件访问控制、/api/search/updateEmbedBlock、插件 APIopenMobileFileById。对于使用查询嵌入块做动态内容聚合的用户建议优先体验//!js脚本模式将原先需要维护多条 SQL 的展示逻辑收敛为一段可按需编程的脚本对于 Docker 自托管用户可结合SIYUAN_ACCESS_AUTH_CODE_BYPASStrue简化内网部署对于涉及多端频繁编辑的重度用户升级后可重点验证同步冲突合并场景是否得到改善。【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考