Skip to content

Commit 3f3532d

Browse files
authored
Merge pull request #20 from zeative/staging
Enhance session management, refactor media processing, and improve docs
2 parents bc8023d + c9ff0de commit 3f3532d

84 files changed

Lines changed: 2226 additions & 1793 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ index.js
1414
.temp
1515
.github
1616

17-
test*
17+
test*
18+
zaileys

.gsd/DEBUG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Debug Session: WhatsApp Desktop Interactive Buttons
2+
3+
## Symptom
4+
Interactive and List buttons fail to display on WhatsApp Desktop. Instead of rendering, they show standard deprecation/incompatibility placeholders: "This message couldn't load. Open the message on your phone to view it."
5+
6+
**When:** Whenever the bot sends an interactive button or list message (powered by native `wa.button()`) and the receiver attempts to view it specifically on the WhatsApp Web or Desktop application.
7+
**Expected:** The buttons should render uniformly across all devices natively, including desktop clients.
8+
**Actual:** They render perfectly on Android and iOS (as tested and observed before) but fail and block rendering on the Desktop client.
9+
10+
## Hypotheses
11+
12+
| # | Hypothesis | Likelihood | Status |
13+
|---|------------|------------|--------|
14+
| 1 | WhatsApp Desktop no longer parses old Baileys button payloads and strictly expects the newer 'interactiveMessage' Node structures wrapped in viewOnce. | 80% | ELIMINATED (Broke on both Mobile & Desktop) |
15+
| 2 | WhatsApp Desktop requires specific `biz` / `bot` binary nodes alongside the `interactiveMessage` payload to whitelist rendering. | 60% | UNTESTED |
16+
| 3 | Baileys natively supports it but we are structuring the proto JSON incorrectly based on current Baileys version. | 40% | UNTESTED |
17+
18+
---
19+
20+
## Attempts
21+
22+
### Attempt 1
23+
**Testing:** H1 — Wrap interactiveMessage tightly inside viewOnceMessage.
24+
**Action:** Modified `src/Classes/button.ts` to push `{ viewOnceMessage: { message: { interactiveMessage: content } } }` instead of bare `interactiveMessage`.
25+
**Result:** Buttons broke entirely on both Mobile ("Terdeteksi viewonce") and Desktop ("This message couldn't load").
26+
**Conclusion:** ELIMINATED

.gsd/ROADMAP.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# ROADMAP.md
2+
3+
> **Current Phase**: 1
4+
> **Milestone**: v1.0
5+
6+
## Must-Haves (from SPEC)
7+
- [ ] Replace jetdb with lmdb
8+
- [ ] Ensure project compiles successfully
9+
10+
## Phases
11+
12+
### Phase 1: Database Migration
13+
**Status**: ✅ Completed
14+
**Objective**: Drop jetdb entirely and replace with direct LMDB integration across Config, Auth, Client, Health, and Listeners.
15+
16+
### Phase 2: Utility Modernization (Radashi Migration)
17+
**Status**: ✅ Completed
18+
**Objective**: Replace `lodash` completely and refactor complex native javascript abstractions (chunking, deep nesting, validation) into elegant `radashi` utility functional equivalents to reduce boilerplate and complexity.
19+
20+
### Phase 3: Unorm Elimination
21+
**Status**: ✅ Completed
22+
**Objective**: Remove the heavy `unorm` library dependency and replace all Unicode formatting functionalities (e.g., `unorm.nfkc`) with modern Native V8 equivalents like `String.prototype.normalize()`.
23+
24+
### Phase 4: Validation Migration (Zod -> Valibot)
25+
**Status**: ✅ Completed
26+
**Objective**: Drop `zod` and `zod-validation-error` completely. Migrate the entire codebase schema definition and validation engine to `valibot` for a drastically smaller bundle size and purely functional APIs.
27+
28+
### Phase 5: Media Processing Mega Refactor (FFmpeg Core)
29+
**Status**: ✅ Completed
30+
**Objective**: Overhaul `audio.ts`, `video.ts`, `document.ts`, `core.ts`, and `index.ts` to implement best-practice WhatsApp media processing, strict format conversions (Opus OGGs, H264 MP4s), and improve error handling/efficiency.
31+
32+
### Phase 6: Media Processing DX Overhaul
33+
**Status**: ✅ Completed
34+
**Objective**: Redesign the structural export logic and Developer Experience (DX) for `media-modifier.ts` and underlying FFmpeg wrappers. Abstract everything into a seamless, unified Builder/Facade API that simplifies end-user code and encapsulates buffer streams smoothly.
35+
36+
### Phase 7: Extracting Media Handler to NPM
37+
**Status**: ✅ Completed
38+
**Objective**: Extract the `ffmpeg` library and `media-modifier.ts` to a standalone local NPM package `@zaadevofc/media-process` using `pnpm` workspaces. This uncouples heavy media bindings from the core WhatsApp connector matrix.

.gsd/SPEC.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# SPEC.md — Project Specification
2+
3+
> **Status**: `FINALIZED`
4+
5+
## Vision
6+
Replace `jetdb` with `lmdb` across the zaileys codebase to ensure a more efficient, powerful, fast, and reliable database system without relying on abstract wrappers.
7+
8+
## Goals
9+
1. Remove `jetdb` dependency completely.
10+
2. Integrate `lmdb` natively into the configuration.
11+
3. Rewrite consumers (Auth, Health, Client, Listeners) to leverage native key-value API and range operations.
12+
13+
## Success Criteria
14+
- [ ] `jetdb` is removed from `package.json`
15+
- [ ] `lmdb` is added to `package.json`
16+
- [ ] Project builds successfully without type errors (`npm run build`).

.gsd/STATE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## Current Position
2+
- **Phase**: 7 (completed)
3+
- **Task**: All tasks complete
4+
- **Status**: Verified
5+
6+
## Last Session Summary
7+
Phase 7 executed successfully. 1 plans, 3 tasks completed.
8+
9+
## Next Steps
10+
All phases complete. The Milestone is attained!

.gsd/phases/1/1-PLAN.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
phase: 1
3+
plan: 1
4+
wave: 1
5+
---
6+
7+
# Plan 1.1: Database Configuration & Auth State
8+
9+
## Objective
10+
Migrate fundamental DB configuration handling and authentication module to LMDB.
11+
12+
## Context
13+
- src/Config/database.ts
14+
- src/Auth/state.ts
15+
16+
## Tasks
17+
18+
<task type="auto">
19+
<name>Configure Native LMDB</name>
20+
<files>src/Config/database.ts</files>
21+
<action>
22+
- Import `open` from `lmdb`.
23+
- Change `CredsDatabase`, `KeysDatabase`, and `WaDatabase` to return native `lmdb` instances calling `open({ path: ..., compression: true/false })` natively.
24+
- Remove JetDB-specific configurations like flushMode, hotThreshold that don't apply directly.
25+
</action>
26+
<verify>npm run build</verify>
27+
<done>database.ts is updated to use solely lmdb.</done>
28+
</task>
29+
30+
<task type="auto">
31+
<name>Migrate Auth State to LMDB</name>
32+
<files>src/Auth/state.ts</files>
33+
<action>
34+
- Update type handling for `credsDb` and `keysDb`.
35+
- Replace `keysDb.batchSet(operations)` and `keysDb.batchDelete(deleteKeys)` with a single native LMDB `transaction(() => { ... })` combining `put` and `remove` calls.
36+
- Remove `.flush()` if unnecessary (LMDB auto-syncs), or ignore as it's safe to drop.
37+
</action>
38+
<verify>npm run build</verify>
39+
<done>Authentication state reads and writes natively using lmdb.</done>
40+
</task>
41+
42+
## Success Criteria
43+
- [ ] database.ts returns LMDB instances.
44+
- [ ] state.ts successfully manipulates those instances directly.

.gsd/phases/1/2-PLAN.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
phase: 1
3+
plan: 2
4+
wave: 1
5+
---
6+
7+
# Plan 1.2: Refactor Health, Client and Cleanup Logic
8+
9+
## Objective
10+
Migrate secondary database consumers (Health Manager, Background Cleanup, Client API) to LMDB.
11+
12+
## Context
13+
- src/Classes/client.ts
14+
- src/Library/health-manager.ts
15+
- src/Library/cleanup-manager.ts
16+
17+
## Tasks
18+
19+
<task type="auto">
20+
<name>Update Client Database Return Type</name>
21+
<files>src/Classes/client.ts</files>
22+
<action>
23+
- Update the return type of the `db(scope)` to `RootDatabase` from `lmdb` instead of `JetDB`.
24+
- Drop `JetDB` import.
25+
</action>
26+
<verify>npx tsc --noEmit</verify>
27+
<done>Client TS types reflect LMDB Database instance correctly.</done>
28+
</task>
29+
30+
<task type="auto">
31+
<name>Migrate Health Manager Session Repairs</name>
32+
<files>src/Library/health-manager.ts</files>
33+
<action>
34+
- Replace JetDB `.batchDelete(keys)` with LMDB `transaction(() => ...)` deleting the keys via `.remove()`.
35+
- Delete the `keysDb.flush()` call.
36+
</action>
37+
<verify>npx tsc --noEmit</verify>
38+
<done>Health manager appropriately issues deletes using LMDB's API.</done>
39+
</task>
40+
41+
<task type="auto">
42+
<name>Migrate Cleanup Manager Queries</name>
43+
<files>src/Library/cleanup-manager.ts</files>
44+
<action>
45+
- Convert complex `.query().where().get()` filter to a fast LMDB `.getRange()` filtering values or scanning keys that contain timestamps.
46+
- Because LMDB items might have different schemas, ensure iteration only fetches values parsing their timestamps cleanly, or implement secondary indexes later if too slow.
47+
- Alternatively, migrate to storing time-sorted keys if necessary. Keep it simple: loop through keys and check JSON value timestamp.
48+
</action>
49+
<verify>npx tsc --noEmit</verify>
50+
<done>Cleanup manager safely scans and bulk deletes old elements using LMDB directly.</done>
51+
</task>
52+
53+
## Success Criteria
54+
- [ ] Classes correctly access LMDB native methods.

.gsd/phases/1/3-PLAN.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
phase: 1
3+
plan: 3
4+
wave: 2
5+
---
6+
7+
# Plan 1.3: Refactor Listener Messages & Socket
8+
9+
## Objective
10+
Migrate complex message parsing queries from JetDB's API structure to LMDB.
11+
12+
## Context
13+
- src/Listener/messages.ts
14+
- src/Listener/index.ts
15+
- src/Config/socket.ts
16+
17+
## Tasks
18+
19+
<task type="auto">
20+
<name>Migrate Message Upserts & Indexes</name>
21+
<files>src/Listener/index.ts</files>
22+
<action>
23+
- Instead of `db.batchUpsert('messages', messages, 'key.id')`, use an LMDB transaction to iterate over models and `.put(item.key.id, item)`.
24+
- Drop `.createIndex()` as LMDB doesn't natively use that wrapper technique. We can rely on primary key lookups if `key.id` is the main PK.
25+
</action>
26+
<verify>npx tsc --noEmit</verify>
27+
<done>Listener correctly transaction-saves batch array payloads into LMDB.</done>
28+
</task>
29+
30+
<task type="auto">
31+
<name>Rewrite Message Retrieve Queries</name>
32+
<files>
33+
src/Listener/messages.ts
34+
src/Config/socket.ts
35+
</files>
36+
<action>
37+
- Replace JetDB `.getByIndex('messages', 'key.id', key.id)` and `.query(output.roomId).where('key.id', '=', universalId).first()` with simple native DB operations like `.get(key.id)` since we will model the DB to be keyed by `key.id`.
38+
- Update schema logic: `put(item.key.id, item)` natively provides instant `.get(item.key.id)` without index lookups.
39+
</action>
40+
<verify>npx tsc --noEmit</verify>
41+
<done>Message handlers directly retrieve and decode items from LMDB database nodes using direct `.get()` operations.</done>
42+
</task>
43+
44+
## Success Criteria
45+
- [ ] No `.query(...)` calls remain in the Listeners codebase.
46+
- [ ] Batch transactions successfully execute insertions.

.gsd/phases/1/4-PLAN.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
phase: 1
3+
plan: 4
4+
wave: 3
5+
---
6+
7+
# Plan 1.4: Dependencies & Final Build Verification
8+
9+
## Objective
10+
Finalize the dependency manifest and perform a complete TypeScript build to catch any lingering `jetdb` interfaces.
11+
12+
## Context
13+
- package.json
14+
15+
## Tasks
16+
17+
<task type="auto">
18+
<name>Update Package Dependencies</name>
19+
<files>package.json</files>
20+
<action>
21+
- Drop `jetdb` completely from `dependencies`/`devDependencies`.
22+
- Ensure `lmdb` is present in dependencies.
23+
</action>
24+
<verify>npm list jetdb --depth=0 || true</verify>
25+
<done>package.json correctly declares lmdb.</done>
26+
</task>
27+
28+
<task type="auto">
29+
<name>Verify Production Build</name>
30+
<files>src/*</files>
31+
<action>
32+
- Run `pnpm run build` or `npm run build` to verify standard TSC emissions succeed without syntax or structural property errors concerning missing jetdb functionality across the workspace.
33+
</action>
34+
<verify>npm run build</verify>
35+
<done>Build finishes successfully with exit code 0.</done>
36+
</task>
37+
38+
## Success Criteria
39+
- [ ] Build verifies entirely.

.gsd/phases/2/2-1-SUMMARY.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Plan 2.1 Summary
2+
3+
## What was done
4+
- **Refactor Object Helpers**: Eliminated the bulky custom 15-line nested path retrieval algorithm in `src/Utils/helper.ts` -> `pickKeysFromArray`. Simplified the empty check parameters logic utilizing `radashi.get` and `radashi.isEmpty`.
5+
- **Refactor Chunking Integrations**: Safely migrated the `500` index slicing array mechanism spanning across Database operations in both `src/Library/cleanup-manager.ts` and `src/Auth/state.ts`. Utilized the concise `radashi.cluster(array, size)` iterator.
6+
7+
## Verification
8+
- `pnpm tsc --noEmit` returned exactly `0` errors, proving the native drop-in typings provided by `.cluster` match natively with the codebase iteration loops.

0 commit comments

Comments
 (0)