@oj-bin/oj-aarch64-apple-darwin 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # @oj-bin/oj
2
+
3
+ Prebuilt binaries for **only-js** (`oj`) — a low-code backend framework that embeds a
4
+ JavaScript/TypeScript runtime (V8, via `deno_core`) into Rust. Write business logic as
5
+ JS/TS handlers; Rust serves them over HTTP with injected globals (`db`, `kv`, `blob`,
6
+ `bus`, `es`, `fetch`, `WebSocket`, …).
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm i @oj-bin/oj
12
+ ```
13
+
14
+ A postinstall script copies the binaries for your platform into **`./bin/`** of the
15
+ directory where you ran `npm i`:
16
+
17
+ ```
18
+ bin/oj # main CLI (oj.exe on Windows)
19
+ bin/plugins/<triple>/ # backend plugin cdylibs (db/kv/blob/bus/es/auth)
20
+ bin/devkit/ # API manual + global.d.ts
21
+ ```
22
+
23
+ ```bash
24
+ ./bin/oj server -c config.yaml --api-path src
25
+ ```
26
+
27
+ ## Supported platforms
28
+
29
+ | platform | triple |
30
+ |---|---|
31
+ | linux x64 (glibc) | `x86_64-unknown-linux-gnu` |
32
+ | macOS arm64 | `aarch64-apple-darwin` |
33
+ | windows x64 (msvc) | `x86_64-pc-windows-msvc` |
34
+
35
+ Other platforms: download from
36
+ [GitHub Releases](https://github.com/everpan/only-js/releases) or build from source.
37
+
38
+ ## Notes
39
+
40
+ - **pnpm ≥ 10** does not run dependency lifecycle scripts by default; add to
41
+ `pnpm-workspace.yaml`:
42
+ ```yaml
43
+ onlyBuiltDependencies: ["@oj-bin/oj"]
44
+ ```
45
+ - If you install with `--ignore-scripts`, run the installer manually:
46
+ `node node_modules/@oj-bin/oj/postinstall.js`
47
+ - Global install (`npm i -g`) is **not** supported (binaries land in `./bin/` of the
48
+ current project). Use a project-local install or the GitHub Release archives.
49
+ - China mirrors: npmmirror syncs this package automatically —
50
+ `npm i @oj-bin/oj --registry=https://registry.npmmirror.com`
51
+
52
+ Repo & docs: <https://github.com/everpan/only-js>
@@ -0,0 +1,29 @@
1
+ # oj DevKit——TS API 开发手册 + agent skill
2
+
3
+ 面向用 oj 框架开发业务项目的开发者与 AI agent。本目录是发布交付物
4
+ (`oj-v<version>-<triple>.tar.gz` / `.zip` 内 `devkit/`),由仓库 `docs/devkit/` 经
5
+ `cargo xtask build` 归置到 `bin/devkit/` 产出。
6
+
7
+ | 文件 | 用途 |
8
+ |---|---|
9
+ | `api-manual.md` | 完备开发手册(13 章):模块开发、全局对象 API(含 §6 命名 MQ 客户端 Kafka/RabbitMQ 与长任务池、ext_boot.js 运行时扩展)、鉴权租户、测试、配置、构建发布、运维、安全红线 |
10
+ | `SKILL.md` | Claude Code 等 agent 的 skill 入口:工作流、红线、checklist、陷阱速查,按章节号引用手册 |
11
+ | `global.d.ts` | handler 全局对象(json/http/db/kv/blob/bus/es/Kafka/RabbitMQ/tasks…)的 TS 类型声明;拷进项目源码根即获得编辑器/agent 类型提示。来源为 `sample/global.d.ts`,经 `cargo xtask build` 与本目录文档一同归置到 `bin/devkit/` |
12
+
13
+ ## 安装(业务项目)
14
+
15
+ ```sh
16
+ # agent 用:拷入项目的 Claude Code skill 目录
17
+ mkdir -p .claude/skills/oj-api-dev
18
+ cp devkit/SKILL.md devkit/api-manual.md .claude/skills/oj-api-dev/
19
+
20
+ # 类型提示:拷进项目源码根(与 src/ 平级即可)
21
+ cp devkit/global.d.ts .
22
+ ```
23
+
24
+ 安装后 agent 里说"用 oj-api-dev 开发 xxx 模块",或 Claude Code 里 `/oj-api-dev` 触发。
25
+
26
+ ## 更新
27
+
28
+ 手册与 skill 随 oj 版本一起发布;升级 oj 后用新包内 `devkit/` 覆盖旧拷贝。
29
+ 源文件与反馈入口在仓库 `docs/devkit/`。
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: oj-api-dev
3
+ description: 在 oj (only-js) 框架业务项目中开发 API 模块时使用——新增或修改 api.ts / ws.ts handler、manifest.yaml、模块测试,或排查路由/信封/鉴权/租户行为时。触发场景:写 handler、建模块、目录镜像路由、.route 参数路由、json 信封、db 查询、Kafka/RabbitMQ 消费任务、tasks 长任务、oj test。
4
+ ---
5
+
6
+ # oj API 模块开发
7
+
8
+ 本 skill 与参考手册 `api-manual.md` 同目录。**按章节号按需读章,不要盲读全文。**
9
+
10
+ ## 工作流
11
+
12
+ 1. **读章**:新项目/新模块 → 手册 §2;写 handler → §4 + §6;用鉴权/租户 → §8;
13
+ 写测试 → §9;配置问题 → §10;构建发布 → §11。**要扩展全局对象(`json.page()`
14
+ 之类)→ §6 末「ext_boot.js」,不要去改 handler。**
15
+ **接 Kafka/RabbitMQ 或写长任务 → §6「命名 MQ 客户端与长任务」**(任务文件放
16
+ `src/tasks/`,命名 `task_{name}.*` / `{name}_task.*`)。
17
+ 2. **脚手架**:模块 = `src/<模块名>/`(首层子目录),内放 `manifest.yaml`
18
+ (`name` 必须等于目录名,违反启动失败)+ 子目录 `api.ts`。
19
+ 3. **写 handler**:遵守下方红线;响应一律 `json.ok` / `json.fail` 收口。
20
+ 4. **测试**:先 L2 vitest 测逻辑(快),再 L1 `oj test` 测端到端(真)。两层都绿才算完(§9)。
21
+ 5. **发布检查**:`oj build` → 确认 `dist/manifests.yaml` 锁与版本目录产物(§11)。
22
+
23
+ ## 红线(不可违反)
24
+
25
+ - **SQL 注入**:动态标识符(表名/列名)**只**来自 `db.table()` 查询构造器(白名单),
26
+ 绝不来自 JS 字符串拼接;值**只**通过绑定参数(`db.query("... where id = ?", [id])`)。
27
+ - **方法名**:DELETE 的方法名是 `del`,不是 `delete`(`get/post/put/del/patch/head/options`)。
28
+ - **信封**:业务响应只经 `json.ok(data)` / `json.fail(code, msg, data?)` 写回,
29
+ HTTP 状态 = `code`(0→200);标准协议端点(对外契约 JSON)可用 `json.raw(data)`
30
+ 出裸 JSON 200(§6)。
31
+ - 路径参数(`http.param`)已 percent-decode,仅用于参数化查询与类型转换,
32
+ **勿拼接文件路径 / URL**。
33
+ - **消费门禁**:MQ 消费方法(`poll/commit/ack/nack`)**只在 `src/tasks/` 任务文件里
34
+ 用**;HTTP/WS handler 里调用直接报错——HTTP 侧发消息用 `send`/`publish`。
35
+ - **任务等待**:运行时无 timer 全局,`setTimeout/setInterval` 不可用;任务里等待
36
+ 一律 `await tasks.sleep(ms)`,循环退出条件一律 `!tasks.stopping()`。
37
+
38
+ ## 新模块 checklist
39
+
40
+ - [ ] `src/<模块>/manifest.yaml` 存在且 `name` = 目录名
41
+ - [ ] 目录映射核对:`src/<模块>/<路径>/api.ts` ↔ `GET {base}/<模块>/<路径>/`
42
+ - [ ] 方法名映射核对(特别是 `del`)
43
+ - [ ] 用了 `.route`?→ 确认镜像路径已按替换语义放弃;确认 build 会剥 `.route`
44
+ - [ ] 响应全部走 `json.ok`/`json.fail`;错误码符合 §7 场景表
45
+ - [ ] SQL 全部参数化;动态标识符全部走构造器
46
+ - [ ] L2 + L1 测试跑过并全绿
47
+
48
+ ## 常见陷阱速查
49
+
50
+ | 症状 | 原因 |
51
+ |---|---|
52
+ | DELETE 返回 405 | 方法名写成了 `delete`,应为 `del` |
53
+ | release 下参数路由 404 | build 剥了 `.route`,路由以 routes.js 为准——确认先 `oj build` |
54
+ | 启动失败 manifest | `name` 与目录名不一致 |
55
+ | postgres 占位符报错 | 该方言用 `$1`,不是 `?`(sqlite/mysql 才是 `?`) |
56
+ | 启动即退出 | 证书两路径缺一(必配不可绕过)或 redis 连不上(fail-fast) |
57
+ | 启动报 `neither api path … specified` / `api path not found` / `static site dir not found` | 准入门三态:`--api-path` 与静态站点(`server.app_path` / `--app-path`)至少显式指定其一,皆指定则两者都必须存在;CLI 路径相对 CWD,config 路径相对 config 目录 |
58
+ | seed 没生效/语法错 | `seed.sql` 按 `;` 切分,语句内不得含分号字面量 |
59
+ | 上传 413 | 超 `max_upload_bytes`(axum 2x 兜底 + handle 双闸) |
60
+ | `{id}.json` 路由没建 | matchit 参数段不得混字面,拆成静态多段 |
61
+ | es/blob 调用报错 | config 未配置 `es.endpoint` / `blob:` 段,配置即启用 |
62
+ | WS 连上但收不到广播 | 订阅只在 WS 会话内有效(`bus.subscribe` 在 HTTP 路径报错);release 下 URL 含版本段 |
63
+ | 改了 `ext_boot.js` 没生效 | 不做热重载,装配期已冻结 spec——必须重启进程 |
64
+ | `ext_boot.js` 里 `await` 报 SyntaxError | 文件无 import/export,被 CJS 启发式包进非 async 函数——加一句 `export {};` |
65
+ | `ext_boot.js` 副作用被放大成百上千次 | boot 每个新建 runtime 都跑(模块数 + `pool_size` + WS Worker 数,每路由 `ws.workers_per_route` 个)——只做全局装配,别写库/发广播/打外部接口 |
66
+ | `Kafka("x")` / `RabbitMQ("x")` 是 undefined | config `kafkas:`/`rabbits:` 段没配该实例名(或对应插件未装配) |
67
+ | poll 报 "requires a task context" | 消费方法只能在 `src/tasks/` 任务文件里用;HTTP/WS 侧发消息用 `send`/`publish` |
68
+ | 任务里 `setTimeout` 报 not defined | 运行时无 timer 全局——用 `await tasks.sleep(ms)` |
69
+ | poll 报 "instance busy" | 同一实例已有活跃 poller(任务上下文单 poller)——别并发 poll |
70
+ | 任务收不到消息就退了/killed | `timeoutMs` 应远小于 `stop_grace_secs`;被 killed = 宽限到期看门狗强杀(不响应 `tasks.stopping()`) |
71
+ | 重启后整段消息重复消费 | commit 按 offset+1 推进该分区——多分区主题按分区各 commit 一次(at-least-once,处理须幂等) |
72
+ | 改了任务文件没生效 | 任务无热重载——重启进程(转译缓存按 mtime 自动失效) |
73
+ | WS 路由 404(文件明明在) | 文件名必须小写 `ws.ts`/`ws.js`——`WS.ts` 无效(v0.1.5 约定) |
74
+ | (v0.1.9 已消除)旧帧循环的 const 重复声明 | 新契约为生命周期钩子:模块每 Worker 预载一次——无需处理;可变跨帧状态放 `sess.state`(模块作用域只是只读缓存),见 api-manual §ws.ts |
75
+ | WS 帧内 `bus.publish` 自己也收到 | 自回声语义:fan-out 不排除本连接——按字段客户端过滤或发布到别的 topic |
76
+
77
+ ## 手册
78
+
79
+ `api-manual.md`(同目录)共 13 章:1 快速开始 / 2 项目结构与模块约定 / 3 模块数据层 /
80
+ 4 编写 api.ts / 5 导入解析 / 6 全局对象 API 参考 / 7 响应信封与错误码 / 8 鉴权与多租户 / 9 测试 /
81
+ 10 配置 config.yaml / 11 构建与发布 / 12 运维要点 / 13 安全红线与已知限制。
82
+
83
+ 类型提示:把同目录 `global.d.ts` 拷进业务项目源码根,编辑器/agent 即获得全局对象
84
+ (json/http/db/kv/blob/bus/es/Kafka/RabbitMQ/tasks…)的完整类型。