Show HN: WebBase-III – 在浏览器中重建的dBASE III及其自己的解释器
摘要
WebBase-III 是在浏览器中运行的dBASE III的完整重现,具有自己的W3Script解释器、BROWSE网格、表单引擎、索引以及通过SQLite实现持久存储。
暂无内容
查看缓存全文
缓存时间: 2026/06/26 14:18
DDecoene/WebBaseIII 来源:https://github.com/DDecoene/WebBaseIII # WebBase-III dBASE III 回来了。就在你的浏览器里。USE customers,仿佛回到 1984 年。 WebBase-III 演示 — USE、LIST、SEEK、BROWSE 还记得那个点提示符吗?在 SQL 获胜之前,在 ORM 出现之前,在有人说出“全栈”之前——就有了 dBASE III。你键入 USE customers,然后 LIST,数据就那么呈现在你眼前。 WebBase-III 把整个时代带回来了:终端、语言、BROWSE、@ SAY GET 表单、.prg 程序、索引、报表——全部用 TypeScript 从零重建为一个现代 Web 应用,后端基于 Node.js、WebSocket 和 SQLite。 一键试用,无需安装: 在 GitHub Codespaces 中打开(https://codespaces.new/DDecoene/WebBaseIII?quickstart=1) Codespace 会自动安装依赖并启动开发服务器。打开转发的端口 5173,你就回到了点提示符。 — ## 截图 ### 终端 REPL 命令界面——键入 W3Script 立即看到结果。 终端 REPL — ### LIST — 表格化记录显示 LIST 按当前激活索引的顺序打印所有记录。状态栏显示当前数据库和表。 LIST 输出 — ### 索引与 SEEK INDEX ON name TO BYNAME 创建一个 SQLite 索引并激活它——随后的 LIST 输出会按字母顺序排序。SEEK "Delta NV" 将记录指针跳转到第一个匹配项,时间复杂度 O(log n)。 索引和 SEEK — ### BROWSE — 可编辑网格 BROWSE 打开一个类似电子表格的网格。记录按激活索引顺序显示。按 Tab/Enter 编辑单元格,Ctrl+N 添加新行,Delete 删除行,Esc 返回终端。 BROWSE 网格 — ### 程序编辑器 EDIT 打开内置的 .prg 源码编辑器。程序支持完整的 W3Script 语言:DO CASE/ENDCASE、DO WHILE/ENDDO、IF/ENDIF、表单布局以及所有数据命令。Ctrl+S 保存,Esc 取消。 程序编辑器 — ### 表单引擎 — @ SAY GET / READ @ row,col SAY "标签" GET 变量 按字符单元格坐标布局表单字段。READ 将其渲染为活动表单并等待用户填写值并提交。 表单引擎 — ### 助手 — 侧边栏 常驻左侧边栏,包含分类选择器和操作按钮。 助手侧边栏 — ### 助手 — 新建表向导 向导在主区域打开,并带有实时 W3Script 预览。 新建表向导 — ## 功能特性 | 功能 | 详情 | |—|—| | W3Script 解释器 | dBASE III 命令方言:导航、过滤、变量、循环、条件、表单、程序 | | BROWSE 网格 | 内联单元格编辑、键盘导航、索引顺序显示 | | 表单引擎 | @ 行,列 SAY ... GET 字符单元格布局,配合 READ | | 索引 | INDEX ON、SEEK、FIND — 激活索引控制所有记录顺序 | | DO CASE | 多路分支条件,OTHERWISE 默认分支 | | 内置函数 | EOF()、BOF()、FOUND()、RECNO()、SUBSTR()、STR()、AT()、CTOD()、DTOC() 等 | | 程序文件 | 使用 DO / EDIT 保存、编辑和运行 .prg 脚本 | | 助手 | 常驻左侧边栏 — 打开数据库/表、浏览、过滤、索引、搜索、设计报表、运行程序,无需输入 | | 多用户 | 每个 WebSocket 连接拥有独立的解释器会话 | | 持久存储 | better-sqlite3 配合 WAL 模式 — 数据库在服务器重启后依然保留 | — ## 助手 左边的侧边栏无需输入即可驱动所有操作:打开或创建数据库和表、浏览和过滤数据、构建索引、搜索、设计和运行报表、运行程序、修改表结构。每次点击都会生成一条真实的 W3Script 命令并回显到终端——观察它即可学习语言。向导(新建表、过滤、修改结构、报表设计器等)在主区域打开,并显示它们将要执行的命令的实时预览。 — ## 快速开始 bash npm install npm run dev # http://localhost:5173 生产环境: bash npm run serve # 构建,然后在 http://localhost:3000 上提供所有服务 LAN / Tailscale:服务器绑定到 0.0.0.0,所以 http://<你的IP>:3000 可直接使用。 — ## 示例会话 USE DATABASE mydb CREATE TABLE customers (name CHAR(40), phone CHAR(20), country CHAR(30)) USE customers APPEND RECORD REPLACE name WITH "Acme Corp", phone WITH "555-1234", country WITH "BE" APPEND RECORD REPLACE name WITH "Zeta Ltd", phone WITH "555-5678", country WITH "NL" INDEX ON name TO BYNAME LIST * 排序 A→Z SEEK "Zeta Ltd" * 立即跳转到记录 BROWSE * 打开可编辑网格 SET FILTER TO country == "BE" LIST * 过滤视图 SET FILTER TO * 清除过滤 — ## W3Script 命令参考 ### 工作区 WebBase-III 支持无限个工作区——每个工作区独立持有表、记录指针、过滤器和索引。使用 SET RELATION TO 按关键字段链接工作区,实现关系数据访问。跨工作区字段访问使用 别名.字段 点号表示法。 > 注意: dBASE III 最多支持 10 个工作区(DOS 文件句柄限制)。WebBase-III 没有此限制。dBASE III 使用 别名->字段 箭头语法;WebBase-III 使用更现代的 别名.字段 点号表示法。 | 命令 | 功能 | |—|—| | SELECT | 激活(或创建)一个工作区 | | USE [ALIAS ] | 在激活区打开表;可选的别名覆盖 | | SET RELATION TO INTO | 链接激活区到另一个工作区;每次导航时自动执行 SEEK | | SET RELATION TO | 清除激活区的关系 | | LIST [列名, 别名.列名, ...] | 列出记录;可选的列列表,支持跨区字段 | | LIST AREAS | 显示所有打开的工作区、指针、索引和关系 | | CLOSE | 关闭激活区的表 | | CLOSE ALL | 关闭所有工作区,重置为单个空工作区 1 | 跨工作区字段访问:在任何接受表达式的地方使用 别名.字段 点号表示法——SET FILTER TO、IF、REPLACE、LIST、INDEX ON 等。 ### 数据与导航 | 命令 | 功能 | |—|—| | USE | 打开一个命名的 SQLite 数据库 | | LIST | 按激活索引顺序打印记录(最多 500 条) | | LIST STRUCTURE | 显示列结构 | | LIST TABLES | 显示所有表及其记录数 | | LIST DATABASES | 显示磁盘上所有数据库(别名:LIST DBS) | | BROWSE | 打开可编辑网格 | | CLEAR | 清除终端输出 | | CREATE TABLE (列名 类型, ...) | 创建表 | | DROP TABLE | 删除表 | | APPEND RECORD | 插入空行 | | DELETE / DELETE ALL | 删除当前记录或所有记录 | | PACK | 对 SQLite 文件执行 VACUUM | | GO TOP / GO BOTTOM / GO | 移动记录指针 | | SKIP | 前移/后移指针 | | REPLACE WITH , ... | 更新当前行的字段 | | REPLACE ALL WITH , ... | 更新所有(被过滤的)行 | | SET FILTER TO | 设置 WHERE 子句;空值清除过滤 | | MODIFY STRUCTURE | 打开修改结构向导(针对激活表) | | ALTER TABLE ADD | 向表添加列 | | ALTER TABLE DROP RENAME | 重命名列 | | ALTER TABLE ALTER | 更改列类型(通过复制表实现;数据保留) | > 可能使索引失效的列操作(DROP、RENAME、ALTER 类型)会删除该表的所有索引,并提示你用 INDEX ON 重建。 ### 索引与搜索 | 命令 | 功能 | |—|—| | INDEX ON TO | 基于表达式创建索引;立即设置为激活索引 | | SET INDEX TO | 激活先前创建的索引 | | SET INDEX TO | 清除激活索引——恢复自然插入顺序 | | REINDEX | 重建当前表的 SQLite 索引 | | LIST INDEXES | 打印当前表的所有索引,带 * 表示激活索引 | | SEEK | 将记录指针定位到第一个索引匹配项 | | FIND | SEEK 的别名(无引号字符串——dBASE III 遗留形式) | | SORT ON [/D] TO | 将表的排序副本写入新表;/D 表示降序;遵循激活过滤器 | ### 报表 | 命令 | 功能 | |—|—| | CREATE REPORT | 创建新的报表定义(打开 JSON 编辑器) | | MODIFY REPORT | 编辑现有报表定义 | | REPORT FORM | 运行报表——ASCII 输出到终端 + HTML 预览面板 | | LIST REPORTS | 列出所有已保存的报表定义 | | DELETE REPORT | 删除报表定义 | ### 程序 | 命令 | 功能 | |—|—| | DO | 运行已保存的 .prg 程序 | | EDIT | 打开 .prg 源码编辑器 | | LIST PROGRAMS | 显示所有已保存的程序 | > 演示程序位于 demos/*.prg,是唯一真相来源:每次服务器启动时,它们会被植入程序存储,覆盖任何已存储的副本。 > 尝试 DO inventory 以体验完整的交互演示(工作区、关系、索引、表单)。 ### 变量与 I/O | 命令 | 功能 | |—|—| | STORE TO | 赋值给变量 | | INPUT "提示" TO | 收集键盘输入 | | @ 行,列 SAY "文本" GET | 定义表单字段 | | READ | 显示表单并等待提交 | ### 控制流 | 命令 | 功能 | |—|—| | IF ... ENDIF | 条件块 | | DO WHILE ... ENDDO | 循环 | | DO CASE ... ENDCASE | 多路分支条件(CASE、OTHERWISE) | | HELP | 打印命令参考 | | QUIT | 退出 | ### 内置函数 函数可在任何接受表达式的地方使用——IF、DO WHILE、STORE、REPLACE、INDEX ON、SET FILTER TO 等。 | 函数 | 返回值 | |—|—| | EOF() | 如果记录指针超过最后一条记录,返回真 | | BOF() | 如果记录指针在第一条记录之前,返回真 | | FOUND() | 如果最后一次 SEEK / FIND 匹配成功,返回真 | | RECNO() | 当前记录号 | | RECCOUNT() | 当前表的总记录数 | | UPPER(字符串) | 大写 | | LOWER(字符串) | 小写 | | TRIM(字符串) | 去除首尾空格 | | LTRIM(字符串) | 仅去除前导空格 | | SUBSTR(字符串, 起始, 长度) | 子字符串——基于 1;长度 可选(到字符串尾) | | LEN(字符串) | 字符串长度 | | AT(针, 草堆) | 基于 1 的位置;未找到返回 0(区分大小写) | | STR(数字, 长度, 小数位) | 数字转换为右对齐字符串;默认长度=10,小数位=0 | | VAL(字符串) | 字符串转换为数字;非数字 → 0 | | INT(数字) | 向零取整 | | ABS(数字) | 绝对值 | | SPACE(数字) | 包含 n 个空格的字符串 | | REPLICATE(字符串, 次数) | 重复字符串 n 次 | | DATE() | 今天日期,格式 MM/DD/YY | | DTOC(日期) | 日期转换为显示字符串 MM/DD/YY | | CTOD(字符串) | 显示字符串 MM/DD/YY 转换为 ISO 日期 | ### 布尔字面量 W3Script 支持两种风格: | 语法 | 值 | |—|—| | TRUE / FALSE | 布尔真/假 | | .T. / .TRUE. | 布尔真(dBASE III 风格) | | .F. / .FALSE. | 布尔假(dBASE III 风格) | 布尔值在输出中显示为 .T. / .F.,以匹配 dBASE 惯例。逻辑运算符也接受两种风格:NOT / .NOT.、AND / .AND.、OR / .OR.(例如 DO WHILE .NOT. EOF())。 — ## BROWSE 网格键盘快捷键 | 键 | 动作 | |—|—| | 方向键 | 导航单元格 | | Enter / F2 | 编辑所选单元格 | | Tab / Shift+Tab | 右移 / 左移 | | Ctrl+N | 新行 | | Delete | 删除当前行 | | F5 | 从数据库刷新 | | Esc | 退出网格,返回终端 | — ## 架构 server/ index.ts Node.js HTTP + WebSocket 服务器(端口 3000) Session.ts 每个连接一个会话:解析命令,驱动执行器 SessionManager.ts 跟踪所有活动会话 ServerDatabaseBridge.ts 实现 IDatabaseBridge 包装 better-sqlite3 ProgramStore.ts .prg 程序存储于 data/system.sqlite3 IndexStore.ts 索引元数据 + 活动索引存储于 data/system.sqlite3 src/ interpreter/ Lexer.ts 词法分析 W3Script 输入(不区分大小写) Parser.ts 递归下降 AST 构建器 Executor.ts 异步 AST 执行器;管理 db/table/filter/vars/rowPtr/activeIndex Builtins.ts 无状态内置函数实现 terminal/ Terminal.ts REPL UI——命令历史、多行块累积 ui/ Grid.ts BROWSE 电子表格——内联单元格编辑、键盘导航 FormLayout.ts @ SAY GET 表单引擎——字符单元格坐标 ProgramEditor.ts .prg 源码编辑器 ws/ WsClient.ts 浏览器 WebSocket 客户端 — ## 运行测试 bash npm test # 单元 + 集成测试(Vitest) npx playwright test # 端到端浏览器测试(需要开发服务器运行中) Playwright 测试套件(tests/integration.spec.ts、tests/crm.spec.ts)在真实浏览器中驱动运行的应用,涵盖导航、过滤、索引、程序、表单和 BROWSE。 — ## 许可证 AGPL-3.0 — 参见 LICENSE.md。为何选择 AGPL?WebBase-III 是一个玩具,许可证保持了这一点:任何人都可以使用、分支并从中学习,但没有人可以将其闭源并作为托管服务出售而不归还修改。如果你想运行它、修改它,或者实现你记忆中 dBASE 的功能——这正是它的用途。
相似文章
完整的 ClickHouse OLAP 引擎,编译为 WebAssembly
chDB 是一个完整的 ClickHouse OLAP 引擎,编译为 WebAssembly,可通过 wasm.chdb.io 的 SQL 终端直接在浏览器中执行 SQL 查询。
Show HN: GETadb.com – 每个GET请求创建一个数据库
GETadb.com 提供一个即时后端,包含关系型数据库、同步引擎和认证,通过简单的GET请求即可访问,无需注册,允许像Claude或Codex这样的AI智能体无缝构建全栈应用。
@DeRonin_: 你明白 Browserbase 刚刚开源了什么吗???一个只需学习一次任何网站,就能以十分之一成本永久完成任务的智能体……
Browserbase 开源了 Autobrowse,这是一个智能网页浏览工具,通过迭代探索学习网站结构,并将发现的模式保存为可复用的 Markdown 技能文件,大幅减少重复网页自动化任务的时间和成本。
Show HN: CADara – 我开发了一个开源的浏览器内 CAD 工具
CADara 是一个开源的浏览器端 CAD 工具,让用户可以直接在网页浏览器中创建 3D 模型。
“Browser OS”由Qwen 3.6 35B实现:这是我从本地模型获得的最佳结果
一位用户报告称,通过Qwen 3.6 35B在本地运行'Browser OS'实现,取得了令人印象深刻的结果,凸显了该模型在不依赖云端的情况下执行复杂任务的能力。