codex/async-sqlite-node24
11
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7c0519f75f | lint | ||
|
|
c16064d7e3 |
refactor(packages): rename @snowluma/bridge → @snowluma/protocol
The package previously named "bridge" houses the protocol-byte layer (OIDB cmds, msg-push decoders, highway uploaders, element-builder, event bus). The name "bridge" suggested transport/lifecycle, which it isn't — that role lives in core/hook and core/bridge/manager. Rename to match what's actually inside. This is a pure rename: zero logic changes, all 73 import sites updated mechanically and TS-verified. core/onebot dependencies key updated. ESLint override path adjusted for the moved oidb-services directory. Rename detection threshold: git log --find-renames=20% recommended when following history across this commit — content-replacement (@snowluma/bridge → @snowluma/protocol) dropped per-file similarity below git's default 50% on import-heavy files. |
||
|
|
58e8081420 |
refactor(oidb): migrate misc.ts OIDB cmds to namespaces
3 OIDB cmds migrated; the 1 non-OIDB cmd (getMiniAppArk via
LightAppSvc) stays on the facade unchanged.
- TranslateEnToZh (0x990_2)
- ClickInlineKeyboardButton (0x112E_1)
- SendGroupSign (0xEB7_1) — preserves historic UPPERCASE
EB7 wire name via the new
`wireName` override (the only
cmd in the codebase with this
quirk; every other cmd uses
the default lowercase).
Tests:
- misc.test.ts moved to bridge.sendRawPacket assertion model
- 18 new namespace-level tests covering serialize, deserialize edge
cases, magic constants, BigInt widening, and the EB7 case quirk
Verification:
- typecheck green
- @snowluma/bridge: 18 files / 153 tests
- @snowluma/core: 302 tests
Wire bytes unchanged.
|
||
|
|
f7a03ca05a |
refactor(bridge): extract protocol layer into @snowluma/bridge package
Phase 2 of the 4-package split (RoadMap #3). Moves ~35 files — events / event-bus / identity-service / packet-pipeline / element- builder / bridge-oidb / qq-info / msg-push/* / highway/* / web/* + the bridge-side formatters — out of `packages/core/src/bridge/` into the new `@snowluma/bridge` workspace package. Everything that translates QQ wire bytes ↔ typed events/elements now lives there. Why --- - `packages/core/src/bridge/` was actually two layers: a low-level "protocol decoder + I/O" set (msg-push, highway, packet-pipeline, identity, element-builder) AND the Api-class host (bridge.ts + apis/*). The Api layer can't move without the protocol layer moving first, but the two had grown into one directory. - Bridge-internal consumers (highway uploaders, OIDB envelope helper, element-builder, msg-push parsers) only ever needed `bridge.identity` + `bridge.sendRawPacket` + the upload-metadata cache. Splitting them out lets that minimal surface live in the bridge package as `BridgeContext` while the api-layer's extended context (with `apis: ApiHub`) stays in @snowluma/core. What stays in @snowluma/core (apis layer): - bridge.ts ── the god-class that composes the protocol building blocks + mounts apis - bridge-interface.ts ── public façade for OneBot consumers - manager.ts ── per-uin BridgeManager hub - apis/* ── the 13 typed Api classes - bridge-context.ts (NEW) ── extends @snowluma/bridge's slim BridgeContext with `apis: ApiHub` so the 13 Api classes keep their typed `this.ctx.apis.X.method()` access. Layout ------ Moved via `git mv` (history preserved): events / event-bus / identity-service / packet-pipeline / element-builder / bridge-oidb / qq-info / msg-push/* / highway/* / web/* → @snowluma/bridge/<sub> utils/event-format.ts → @snowluma/bridge/format.ts (the last one renamed because the destination directory only has bridge-related files; `format.ts` reads cleaner than `event-format`. Listed as a rename in git's `RM` output — content unchanged.) Layering fixes (functionality preserved, just type signatures) -------------------------------------------------------------- - `element-builder.SendContext.bridge` → typed as `BridgeContext` instead of `Bridge`. Reads only `bridge.identity` and the upload-cache (both on BridgeContext); the concrete `Bridge` instance still passes via free upcast. - `bridge-oidb.runOidb` signature widened from `Bridge` to `BridgeContext` — same reason. - `highway/{highway-client,pipeline,image-upload,ptt-upload, video-upload}.ts` — same. - `format.ts::formatReply` parameter typed as a new local `ReplyEventLookup` structural type (`{ findEvent(id): JsonObject | null }`) instead of `MessageStore` from @snowluma/onebot. The OneBot `MessageStore` is a structural superset; consumers pass it through unchanged. - JSON value types moved to a new `@snowluma/common/json` subpath (consumed by format.ts) — `onebot/types.ts` re-exports them so external `import { JsonValue } from '<…>/onebot/types'` paths keep working. - `UploadedFileMeta` interface moved from `core/src/bridge/bridge.ts` into `@snowluma/bridge/bridge-context.ts` — element-builder + the forward-builder both read the upload cache through BridgeContext, so the type has to live in @snowluma/bridge. `bridge.ts` keeps its re-export for back-compat. Changes ------- - New package `packages/bridge/` (package.json with per-file subpath exports mirroring legacy `core/src/bridge/<x>` layout 1:1, tsconfig.json, typecheck script). - 35 `.ts` files moved via `git mv` (3 files counted by git as RM — rename + modify because Bridge → BridgeContext type swap). - 150+ import sites rewritten across `packages/core/src` and `packages/core/tests`: `'../bridge/<x>'`, `'../../bridge/<x>'`, `'../src/bridge/<x>'`, `'@/bridge/web/<x>'`, and vitest `vi.mock(...)` literals all collapse to `@snowluma/bridge/<x>`. - `@snowluma/core` depends on `@snowluma/bridge` (workspace:*). - `@snowluma/bridge` depends on `@snowluma/common`, `@snowluma/proto-defs`, `@snowluma/proton`. - `packages/core/src/utils/` directory removed (empty). Verification ------------ - Full workspace `pnpm -r typecheck`: all 10 projects clean. - core test suite: 552 passed / 552 total (pre-existing websocket-darwin-arm64.node addon failure unchanged — same baseline as the previous refactor commits). - Vite build (with stubbed native binary): clean — 143 modules, 2.84 MB bundle / 224 KB gzip, identical envelope to the pre-split build. Phase 3 (next): OneBot + WebUI move into @snowluma/onebot. The runnable `index.ts` stays in @snowluma/core as the application entry, importing `OneBotManager` from `@snowluma/onebot`. |
||
|
|
e5ac2a61b1 |
refactor(api): move 4 misc methods to MiscApi (#6 commit 10/13)
Inlines `actions/misc.ts` into `apis/misc.ts::MiscApi`. The Api holds the methods that didn't naturally group into any other area: translation, mini-app ARK card builder, inline-keyboard callback, group sign-in. No renaming — these names are already descriptive at the call site under `apis.misc.X`. Callers updated: `actions/extended.ts` (4 sites). Tests rewritten to use `new MiscApi(bridge as any).method(...)`. 587/587 tests pass. |
||
|
|
6c7e56d5a1 |
refactor(proto-defs): extract wire-protobuf definitions into standalone package
Move `packages/core/src/bridge/proto/proton/*.ts` (13 files, ~3.3k LOC) into a new `@snowluma/proto-defs` workspace package. The proton spike landed in the previous commit means bare-specifier imports (`@snowluma/proto-defs/oidb`, `…/message`, …) now resolve correctly through proton's vite plugin, so call-site replacement still fires. Why --- - Lets downstream consumers share the same wire definitions without copy-pasting them — multiple workspace packages can now depend on `@snowluma/proto-defs` directly. - Trims `@snowluma/core`'s surface: the bridge no longer owns the protocol schema, only its consumers. - Sets up future #5 (`message-parsing perf`) and #6 (`Api-on-ctx refactor`) — both want a thinner core. Layout ------ Per-file subpath exports (mirrors the legacy `proto/proton/<sub>` shape 1:1). The barrel `index.ts` intentionally skips `highway` and `oidb-actions/media` because the two files share six NTV2-prefixed type names — `export *` would silently drop one side. Subpath imports are unambiguous, which is also why every call site in core uses them. Changes ------- - New package `packages/proto-defs/` (package.json, tsconfig.json, src/index.ts). - 13 `.ts` files moved via `git mv` to preserve history. - 44 import sites across 26 source files + 15 tests rewritten via sed from `./[…/]proto/proton/<sub>` → `@snowluma/proto-defs/<sub>`. - `@snowluma/core` depends on `@snowluma/proto-defs` (workspace:*). Verification ------------ - proto-defs typecheck: clean - core typecheck: clean - core test suite: 587 passed (same baseline as before the refactor; one failure is the pre-existing websocket native addon, unrelated) - proton test suite: 99 passed (8 files including the new cross-package.test.ts from the spike) - Full workspace `pnpm -r typecheck`: all 8 projects clean Note: proton's `dist/index.js` MUST be rebuilt for the vite plugin to pick up the bare-specifier resolution. The previous commit's source change is only effective after `pnpm -F @snowluma/proton build`. |
||
|
|
5ea1c3a961 |
Remove bridge proto schemas and parity test
Delete proto schema modules under packages/core/src/bridge/proto (action.ts, element.ts, highway.ts, longmsg.ts, message.ts, notify.ts, oidb-action.ts, oidb.ts) and the related test packages/core/tests/proton-parity.test.ts. These files contained protobuf schema definitions for the bridge layer; remove them as part of a cleanup/refactor. Update any imports or references to these modules to their new locations or replacements. |
||
|
|
5802812392 |
feat(proton): finish OIDB migration — runOidb on protobuf_encode<OidbBase<T>>
Closes the OIDB phase of the proton migration. Every consumer that
talked to the OIDB service through the old runtime
`makeOidbBaseSchema()` factory now goes through the compile-time
generic `OidbBase<T>` instead — proton monomorphizes the codec per
call-site instantiation.
@snowluma/proton — two analyzer fixes uncovered by the migration:
1. Skip queuing call-site type-args that reference an *enclosing
generic function's* type parameter for monomorphization. Before
this, a wrapper like
export function encodeOidbEnv<T>(env: OidbBase<T>): Uint8Array {
return protobuf_encode<OidbBase<T>>(env);
}
would cause the analyzer to mint a literal `OidbBase__T` registry
entry with `body.typeName = 'T'`, which the post-walk wire-type
guard then tripped on. The enclosing-scope type params are tracked
on a stack as the walker descends into FunctionDeclaration,
FunctionExpression, ArrowFunction, MethodDeclaration nodes; matching
call sites are skipped (the wrapper-binding path is still
responsible for materialising concrete codecs at downstream call
sites).
2. Register *explicitly* empty interfaces (`interface X {}`) as
zero-field proto messages. OIDB has a handful of these
('this call has no meaningful response body' placeholders —
Oidb0xeb7Resp, Oidb0xcd4Resp, Oidb0x112aResp, Oidb0x8a0Resp,
Oidb0xf16Resp, OidbClientKeyReq). Proto3 wire allows zero-field
messages, and downstream code does `protobuf_decode<OidbBase<X>>`
where X is one of these — the wire-type guard would otherwise trip
on the missing `X` registration. Interfaces that have members but
no pb-marked fields are still NOT registered.
@snowluma/core — the OIDB-layer refactor itself:
bridge-oidb.ts ditches the runtime ProtoSchema factory and exposes:
- makeOidbEnvelope<T>(oidbCmd, subCmd, body, isUid) pure helper
- encodeOidbEnv<T>(env) pass-through
- decodeOidbEnv<T>(bytes) pass-through
- runOidb(bridge, cmd, envelopeBytes) non-generic raw
`encodeOidbEnv` / `decodeOidbEnv` are pure pass-through generic
wrappers — proton wrapper-binds them and substitutes every call site
with the inlined `protobuf_encode_OidbBase__X` / `protobuf_decode_…`
function. `runOidb` is non-generic (proton leaves it alone) so it can
be mocked in tests. `makeOidbEnvelope` is plain TS — also mockable for
introspection.
56 `runOidb` call sites across 11 files migrated to the new API:
- bridge-contacts.ts, actions/extras.ts, actions/friend.ts,
actions/group-admin.ts, actions/group-file.ts,
actions/group-message.ts, actions/interaction.ts,
actions/misc.ts, actions/profile.ts, web-actions/cookies.ts,
highway/pipeline.ts
pipeline.ts also drops `makeOidbBaseSchema(NTV2UploadRichMediaReqSchema)`
and the residual `protoEncode({...}, EncodableMediaMsgInfoSchema)` —
both go through proton now.
Tests:
- 8 test files migrated from `vi.mocked(decodeOidbEnv).mockReturnValueOnce`
to `vi.mocked(runOidb).mockResolvedValueOnce(protobuf_encode<OidbBase<X>>({body: …}))`
— the proton substitution means the old mock layer is bypassed at
build time, so the only mockable point is the bytes layer at `runOidb`.
- 2 new parity tests pinning `OidbBase<T>` ↔ legacy
`makeOidbBaseSchema(InnerSchema)` byte equivalence.
Verification:
- @snowluma/proton: 95/95 tests pass, tsc --noEmit clean
- @snowluma/core: 605/605 tests pass (network-manager.test.ts
fails to load due to a missing darwin-arm64 native binary in this
environment — pre-existing), tsc --noEmit clean
|
||
|
|
59cdfa98a2 |
refactor(oidb): replace 3 positional helpers with one named runOidb
bridge-oidb.ts used to expose three thin functions —
makeOidbRequest / sendOidbAndCheck / sendOidbAndDecode — and every
action file repeated the same five-step envelope assembly with long
positional argument lists. Collapse them into one `runOidb(bridge,
call)` taking an OidbCall object: cmd / oidbCmd / subCmd / request
{ schema, value, isUid? } / response? { schema }.
Behavioural contract is preserved:
- No `response`: verify success + gotResponse, peek envelope retCode
iff response data is present (fire-and-check semantics).
- With `response`: require responseData, decode through the base
schema, validate retCode, return the inner body typed as TResp.
Migration touches 51 call sites across 9 source files (bridge-contacts,
actions/{group-file, group-admin, profile, group-message, friend,
interaction, misc}, web-actions/cookies) plus 9 test files that used
to assert on positional `.mock.calls[0]![4]` indices and now read
through `.mock.calls[0]![1].request.value` / `.cmd` / `.oidbCmd`.
Net effect: callers now name what each piece is for, and adding
cross-cutting OIDB behaviour (retry / timeout / per-cmd logging) is a
single-site change inside runOidb instead of a sweep across 9 files.
|
||
|
|
030336a25c |
refactor(identity): consolidate UID resolution behind IdentityService
Pull the cache→DB→network-fetch fallback cascade for UIN→UID translation into a single async `resolveUid` on IdentityService, and drop the duplicated `resolveUserUid` helper that used to live in bridge-oidb. Bridge injects itself as the IdentityFetcher post-construction so the network fallback runs through the same OIDB profile fetch the helper used. Each action module's `resolveUserUid(bridge, uin, groupId?)` call becomes `bridge.resolveUserUid(uin, groupId?)` — same signature on Bridge, but internally it now goes through `identity.resolveUid` so future changes (retry, coalescing, alternative resolvers) only need to land in one place. This is part 1 of the IdentityService deepening (RoadMap item 1). The QQInfo bypass in msg-push-handler and the broader QQInfo absorption land in the follow-up commit. |
||
|
|
8506b60d07 |
refactor(core): split bridge-actions.ts (1814 lines) into themed action modules
bridge-actions.ts was a single 1814-line file holding 55 unrelated exported functions — admin/file/forward/interaction/recall/profile/ status/translate/sign/avatar all jumbled together. Each function already takes `bridge: Bridge` as its first parameter, so the "deepening" target (per-UIN state object threaded into themed action functions) was structurally there — what was missing was a coherent file-level grouping that AI tools and humans could navigate. This commit is candidate #2 from the deepening list, A-only variant: pure file split, no facade change, no caller change outside the bridge module. New layout under packages/core/src/bridge/actions/ : shared.ts 82 private helpers (toInt, ensureRetCodeZero, resolveSelfUid) and the MediaIndexNode type. group-admin.ts 153 mute/kick/leave + setGroup{Admin/Card/Name/ SpecialTitle/AddOption/Search/Remark/AddRequest} + getGroupAtAllRemain. (14 fns) group-file.ts 821 upload/list/url/delete/move/folder ops, both group + private files, media-URL fetchers for ptt/video, fetchGroupFileCount. Owns file- specific helpers (normalizeDirectory, buildGroupFileUploadExt, normalizeMediaNode, fetchNtv2DownloadUrl, ...). (15 fns) group-message 101 recall* / markRead* / setGroupEssence. (5 fns) interaction.ts 61 poke / like / reaction / emoji-likes. (4 fns) forward.ts 197 uploadForwardNodes, fetchForwardNodes + in-memory resId cache. (2 fns) friend.ts 53 setFriendAddRequest, deleteFriend, setFriendRemark. (3 fns) profile.ts 269 setOnlineStatus, setProfile, setSelfLongNick, setInputStatus, setAvatar, fetchCustomFace, getProfileLike, getUnidirectionalFriendList. (8 fns) misc.ts 173 translateEn2Zh, getMiniAppArk, clickInlineKeyboardButton, sendGroupSign. (4 fns) bridge.ts updates its imports — one themed import block per action module instead of one giant block from bridge-actions.ts. GroupFilesResult and MediaIndexNode type imports now point at actions/group-file and actions/shared. Public Bridge facade API is unchanged: every caller outside `bridge/` keeps the same `bridge.X(...)` surface and the delegated function it points at. bridge-actions.ts is deleted. The new shared.ts holds the three helpers that span themes; everything else lives co-located with the functions that use it. Adds 60 happy-path tests across tests/actions/ — one .test.ts per themed file plus a shared `_helpers.ts` (mockBridge fixture): group-admin 10 command + payload dispatch, UID resolution, flag-driven sub-command selection (mute on/off, add-request filtered/unfiltered). group-file 13 fetchGroupFileCount, upload happy path with and without highway, OIDB error bubbling, file listing pagination + folder/file split, URL builder shape, delete/move/folder dispatch, NTV2 URL assembly. group-message 5 recall (group/private), markRead, essence on/off, transport failure propagation. interaction 6 poke (group vs friend payload), like, reaction on/off, emoji-likes cookie/isLast logic. forward 5 empty-array rejection, dispatch + res_id return, transport failure, cache reuse after upload. friend 5 numeric flag → UID resolution path, opaque flag passthrough, delete + best-effort cache refresh. profile 9 status dispatch, setProfile no-op when undefined, setAvatar highway cmd 90, getProfileLike + getUnidirectionalFriendList JSON parsing. misc 6 translate, mini-app type guard, click + sign dispatch. Tests use vi.mock on `bridge-oidb` (and `highway-client`/`highway-utils` where relevant) so each action runs against a tiny fake Bridge, no native pipe / real OIDB exchange needed. Previously these 55 functions had zero unit-test coverage. 244 tests pass (was 184); only failing suite remains the pre-existing macOS-arm64 missing websocket native addon, unrelated. |