机器翻译,未经母语人士审校。以英文版为准。

入门在GitHub上编辑来源:web/README.md

kshana.dev网站

web/是GitHub Pages以https://kshana.dev提供服务的目录树:包括各页面(index.html、missions.html、capabilities.html、evidence.html、developers.html、editions.html)、docs/之下的文档,以及studio/之下的Kshana Studio(位于https://kshana.dev/studio/),它是在浏览器中以WebAssembly(WASM)运行引擎的应用,没有服务器端计算,也不上传任何内容。Studio对同一个引擎有两种视图:简单视图(studio/index.html,先用平实的语言给出答案)和高级视图(studio/advanced/index.html,完整仪表板),后者通过<base href="../">共用简单视图的引擎、worker、模块和数据。

自0.35.0起,Studio又增加了四个视图,每个都是单独的页面,带有<base href="../">、不做搜索索引,并有一个存放合成样本的文件夹供其测试读取:

  • studio/trust/:船舶信任度视图,为船舶位置流给出接收机信任度,演示航迹位于trust/demo/。
  • studio/training/:船员训练复盘,回放含有压制干扰、拖离、授时欺骗或重放事件的合成NMEA(training/demo/)。
  • studio/interference/:干扰地图和航线暴露(interference/demo/)。
  • studio/tools/:一个工具卡片页面,附示例(tools/examples/、tools/samples/),包括带签名的证据包(#evidence)、测试bench导出(#bench)、compliance对应(#compliance)、Galileo OSNMA验证(#osnma)和AI助手通道(#ai)。

文件从何而来#

这里有三类文件,修改方式也各有三种。

  1. 移植的文件。各页面、docs/、css/、js/、assets/、data/中的站点数据(land.json、search.json、series.json)以及studio/之下的一切,都由web/tools/port_site.py根据站点构建和Studio的源码写出。PORT-MANIFEST.json列出每一个及其SHA-256(安全散列算法,256位)校验和。请勿在此处编辑它们:site.test.mjs会因手工编辑而失败。请修改源码并重新运行移植:

    python3 web/tools/port_site.py --site <built site folder> --studio <Studio folder>
    python3 web/tools/port_site.py --site <built site folder> --studio <Studio folder> --check

    移植是确定性的:第二次运行不写入任何内容,并且当web/与移植所要写入的内容不一致时,--check以1退出。它原样带过站点构建的抓取文件(每个页面的canonical、社交卡片和schema.org标签,robots.txt、sitemap.xml、llms.txt、llms-full.txt),对其进行检查,写出legacy-redirects.js、404.html以及Studio旧地址处的转发页面(playground/index.html,转至/studio/),并使每个页面指向本地字体和脚本库(见下文)。

  2. web/自己拥有的文件。这些本身就是源文件,移植从不触碰它们:

    • capabilities.json是能力卡片和标准网格的结构化来源。请编辑它,而不是HTML。
    • data/verification-matrix.json是生成的(cargo run --bin gen_validation_artifacts),并由tests/verification_artifacts_doc_sync.rs固定;请勿手工编辑。data/card-matrix-map.json、data/oracle-references.json和data/standards-matrix-map.json是手工维护的对应关系,同一测试会对照生成的矩阵加以检查。Studio在studio/data/之下的副本与这些文件逐字节一致。
    • og-card.svg、og-card.png和og-card.rendered-from.json是社交卡片(python3 tools/gen_og_card.py)。
    • CNAME, .well-known/security.txt, favicon.svg.
    • fonts/和vendor/:页面使用的字体文件和脚本库,由tools/fetch_third_party.py一次性获取并提交(见“无第三方请求”)。
    • build.sh、smoke.mjs、site.test.mjs、legacy-urls.test.mjs和tools/。
  3. 构建产物,被git忽略,由build.sh生成:pkg/(即wasm-pack包,npm包也由它构建)、studio/pkg/(Studio导入它的位置上的同一个包)和scenarios/(每个参考场景,位于早先的单页站点提供它们的地址)。

在本地构建和提供服务#

./web/build.sh                     # compiles the WASM module and stages it for the Studio
python3 -m http.server -d web 8000 # serve over HTTP (required for WASM)
# open http://localhost:8000/

没有WASM工具链时,KSHANA_WASM_PKG=<a built pkg folder> ./web/build.sh会放置一个现成的包,而不是编译一个。Pages工作流从不使用这种方式。

测试#

node web/smoke.mjs                 # the WASM bindings (needs web/pkg)
node web/site.test.mjs             # the ported tree: manifest, version, counts, links, inline JSON
node web/tools/inline-json.test.mjs  # the guard for corrupt inline page data (an unescaped version bump)
node web/legacy-urls.test.mjs      # every old kshana.dev address still resolves
for f in web/studio/lib/*.test.mjs; do node "$f"; done   # the Studio's modules

studio/lib/中的每个模块都是纯逻辑,并带有对应的*.test.mjs;Studio的DOM(文档对象模型,页面的元素树)驱动为studio/app.js(简单视图)和studio/advanced.js(高级视图)。持续集成把其中每一个作为独立步骤运行,并在web/之下有测试文件没有对应步骤时失败。

无第三方请求#

kshana.dev自行提供字体、样式和脚本。页面不会向字体主机或脚本主机发出任何请求,因此访问者的地址不会被交给它们。

站点和Studio原本是针对Google Fonts和一个脚本主机编写的。移植用fonts/中对应的样式表替换每个页面的Google Fonts链接(相同的@font-face规则和相同的字体文件,包含每个子集,因此文字渲染与之前一样),并用vendor/之下的文件替换每个脚本主机地址。fonts/FONTS.json和vendor/VENDOR.json记录每个文件的来源及其校验和;字体采用SIL Open Font License(fonts/OFL-*.txt),three.js采用MIT许可(vendor/three@…/LICENSE)。

tools/fetch_third_party.py --from <site folder> --from <Studio folder>是唯一使用网络的步骤。仅当页面要求这里没有的字体集或库版本时才再次运行它:此时移植会拒绝并说明原因。如果任何已移植的页面、样式表或脚本指名某个字体主机,或从其他主机加载任何内容,site.test.mjs就会失败。

404页面#

GitHub Pages对不存在的地址以/404.html和状态404作答。移植用首页自身的外壳(导航、页脚、搜索)围绕一条简短消息生成该页面,消息中有指向首页、文档和Studio的链接。其中每个地址都从站点根目录写起,因为它在任意深度都会被提供。

旧地址#

直到v0.28.0,网站都是单个页面,一切都放在/上的片段标识之后(/#playground、/#ledger、形如/#s=…的分享链接、形如/?embed=1&…的嵌入;嵌入链接的旧标签页名称,例如tab=fom,会打开取代它的Studio标签页)。tools/legacy-urls.json列出已发布材料所用的每一个此类地址及其如今的落点;首页加载由该列表生成的legacy-redirects.js,将访问者送往那里。在停用任何地址之前,请先往该列表中添加一个用例。

部署#

pages GitHub Actions工作流部署的是发布标签,而不是main:发布一经完成,release.yml就触发它,手动触发则重新部署指定的标签。它运行build.sh,放置不含测试、构建脚本、tools/、清单和本文件的web/,并将结果发布到GitHub Pages。