Eidos

基于 Eidos File 1.0 构建

Eidos 1.0 包含四个可互操作层:

File Format → Runtime → Adapter → UI

大多数应用应该组合已发布的 Runtime 与 UI package,而不是重新实现全部层。只有在构建符合规范的替代实现时,才需要自行实现某一层。

以下冻结英文规范是 normative,中文文件是逐项参考:

选择接入层

你正在构建建议从这里开始
Node 服务或 headless 数据工具@eidos.space/eidos-file 与 Node ConnectionPort
浏览器应用Dedicated Worker 中的 Runtime、浏览器 Adapter 与 @eidos.space/eidos-file-ui
React 可视化 viewer 或编辑器符合规范的 Host 与 Runtime,加上 @eidos.space/eidos-file-ui
Storage 或 UI 的替代实现对应的 1.0 规范与互操作测试
Agent 工作流或脚本eidos CLI 与 Eidos Skill

安装参考 package

pnpm add @eidos.space/eidos-file@1.0.0 \
  @eidos.space/eidos-file-ui@1.0.0 react react-dom

应用只需引入一次 @eidos.space/eidos-file-ui/styles.css

如果你不是把 package 嵌入应用,而是为 Agent 或自动化构建工作流,请改用 CLI 与 Skill 配置指南

Runtime 与 Adapter

下面的代码是组合结构示意,不是可独立运行的 quickstart。connectionenvironmentcancellation 由你的 Adapter 或 Host 提供。

把 EA-Connection-1.0 ConnectionPort 传给 Runtime.openRuntime.create。Browser 参考实现是 SQLiteWasmConnectionPort,Desktop 参考实现是 BetterSqlite3ConnectionPort

import { Runtime, type ConnectionPort } from "@eidos.space/eidos-file"

const { service, hostBridge } = await Runtime.open(
  connection satisfies ConnectionPort,
  environment,
  "readwrite",
  { cancellation, deadlineMilliseconds: 30_000 }
)

只有 service 可以作为 RuntimeClient 暴露。hostBridge 必须留在可信 Adapter / product composition 内。浏览器中,Connection 与 Runtime 位于 Dedicated Worker,并通过 AdapterTransportRuntimeClient 提供给 Window;不能把 SQLite 或原始文件 handle 发送给 UI。

产品实现 HostServices,负责 opaque source/destination token、权限、保存/CAS、 冲突、恢复与资产。Host 可以持有 trusted bridge,UI 不可以。

React viewer

import { useEffect, useMemo, type ReactNode } from "react"
import type { HostServices } from "@eidos.space/eidos-file"
import {
  EidosFileUIProvider,
  type AssetPresenter,
} from "@eidos.space/eidos-file-ui"
import { EidosUIKernel } from "@eidos.space/eidos-file-ui/kernel"
import {
  EidosStandardView,
  EidosUIRuntimeProvider,
} from "@eidos.space/eidos-file-ui/runtime-platform"

function Viewer({
  host,
  sourceToken,
  assetPresenter,
}: {
  host: HostServices
  sourceToken: string
  assetPresenter: AssetPresenter<ReactNode>
}) {
  const kernel = useMemo(() => new EidosUIKernel(host), [host])
  useEffect(() => {
    void kernel.openSource({ sourceToken, access: "read" })
    return () => {
      void kernel.close()
    }
  }, [kernel, sourceToken])
  return (
    <EidosFileUIProvider locale="zh">
      <EidosUIRuntimeProvider kernel={kernel} assetPresenter={assetPresenter}>
        <EidosStandardView />
      </EidosUIRuntimeProvider>
    </EidosFileUIProvider>
  )
}

Kernel 先协商 Host 与 Runtime,再加载 snapshot 和与 revision 绑定的 schema。 Grid、Gallery 与 Kanban 只消费 Runtime 的 columnar 结果;它们不会在本地重做 File filter、Formula、Lookup、Relation、aggregate 或 group 语义。

EidosFileUIProvider 支持 locale="en"locale="zh",Host 也可以通过 messagestranslate 覆盖文本。Locale 只改变 UI copy、accessibility label、 input affordance 与 formatting;canonical option name 以及用户创建的 Table、Field、 View name 始终是 File data,绝不会被翻译。

EidosStandardView 是参考只读 viewer 组合。完整编辑器使用共享的 EidosFileEditorShell 与编辑器组件,让 Browser 与 Desktop 保持同一套交互层级。编辑器组合接口见 @eidos.space/eidos-file-ui package 指南

File-entry URI 不是 presentation URL。relative、https: 与 canonical inline image Data URL 全部通过 HostServices.resolveAsset;只有注入的 AssetPresenter 可以消费 lease token。没有 session-scoped relative root 的 Host 必须省略该 capability。打开/下载是显式 lease action;普通 URL 字段不会 自动 fetch。

必需的互操作验证

  • Browser WASM 与 Desktop better-sqlite3 跑同一 Runtime contract;
  • Connection 层验证 tagged value、嵌套事务、snapshot、取消与错误映射;
  • transported mutation 必须在 COMMIT 前完成 prepared-commit receipt;
  • UI 验证 snapshot/schema/page cursor binding 与 revision invalidation;
  • optional capability 为 false 时,对应 optional method 必须不存在,不能用 stub 伪装。
  • 覆盖 invalid Base64/media/size、1 MiB inline 边界、missing relative root、 lease expiry/fallback,以及 zero direct URI fetch/navigation。