You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- If you must comment, explain *why*, not *what* — the code shows what
127
+
128
+
### Error Handling
129
+
- Use exceptions rather than return codes
130
+
- Write try-catch-finally statements first when writing code that could throw
131
+
- Use unchecked exceptions; checked exceptions violate the Open/Closed Principle
132
+
- Provide context with exceptions: include operation attempted and failure type
133
+
- Define exception classes by how they're caught, not by their source
134
+
- Don't return null — throw an exception or return a Special Case object instead
135
+
- Don't pass null as arguments unless the API explicitly expects it
136
+
137
+
### Classes
138
+
- Classes should be small, measured by responsibilities (Single Responsibility Principle)
139
+
- A class should have only one reason to change
140
+
- High cohesion: methods and variables should be closely related
141
+
- Organize for change: isolate code that's likely to change from code that's stable
142
+
- Depend on abstractions, not concretions (Dependency Inversion)
143
+
- Classes should be open for extension but closed for modification (Open/Closed Principle)
144
+
145
+
### Code Smells and Heuristics
146
+
- Avoid comments that could be replaced by better naming or structure
147
+
- Eliminate dead code, duplicate code, and code at wrong levels of abstraction
148
+
- Keep configuration data at high levels; don't bury magic numbers
149
+
- Follow the Law of Demeter: modules shouldn't know about the innards of objects they manipulate
150
+
- Make logical dependencies physical: if one module depends on another, make that explicit
151
+
- Prefer polymorphism to if/else or switch/case chains
152
+
- Follow standard conventions for the project and language
153
+
- Replace magic numbers with named constants
154
+
- Be precise: don't be lazy about decisions — if you decide to use a list, be sure you need one
155
+
- Encapsulate conditionals: extract complex boolean expressions into well-named methods
156
+
- Avoid negative conditionals: `if (buffer.shouldCompact())` is clearer than `if (!buffer.shouldNotCompact())`
157
+
- Functions should descend one level of abstraction
158
+
159
+
### SOLID Design Principles
160
+
161
+
**Single Responsibility Principle (SRP)**
162
+
A module should have one, and only one, reason to change. Each class serves one actor or stakeholder. When requirements change for one actor, only the relevant module changes.
163
+
164
+
**Open/Closed Principle (OCP)**
165
+
Software entities should be open for extension but closed for modification. Achieve this through abstraction and polymorphism — add new behavior by adding new code, not changing existing code.
166
+
167
+
**Liskov Substitution Principle (LSP)**
168
+
Subtypes must be substitutable for their base types without altering program correctness. If S is a subtype of T, objects of type T may be replaced with objects of type S without breaking the program.
169
+
170
+
**Interface Segregation Principle (ISP)**
171
+
Clients should not be forced to depend on interfaces they don't use. Prefer many small, client-specific interfaces over one general-purpose interface.
172
+
173
+
**Dependency Inversion Principle (DIP)**
174
+
High-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details; details should depend on abstractions.
175
+
176
+
### Component Principles
177
+
178
+
**Cohesion Principles:**
179
+
-**REP (Reuse/Release Equivalence)**: The granule of reuse is the granule of release — classes in a component should be releasable together
180
+
-**CCP (Common Closure)**: Gather classes that change for the same reasons at the same times; separate classes that change at different times for different reasons
181
+
-**CRP (Common Reuse)**: Don't force users to depend on things they don't need — classes in a component should be used together
182
+
183
+
**Coupling Principles:**
184
+
-**ADP (Acyclic Dependencies)**: No cycles in the component dependency graph; use Dependency Inversion to break cycles
185
+
-**SDP (Stable Dependencies)**: Depend in the direction of stability — volatile components should depend on stable ones
186
+
-**SAP (Stable Abstractions)**: Stable components should be abstract; instability should be concrete
Copy file name to clipboardExpand all lines: CHANGELOG.md
+25Lines changed: 25 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,31 @@ The format is inspired by Keep a Changelog, and this project adheres to semantic
8
8
9
9
No unreleased changes yet.
10
10
11
+
## [1.2.1] - 2026-01-21
12
+
13
+
### Fixed
14
+
- NIP-44 now correctly uses HKDF-Extract for conversation key derivation, ensuring proper cryptographic key generation.
15
+
- WebSocket client now correctly accumulates all relay responses (EVENT messages) before completing, waiting for termination signals (EOSE, OK, NOTICE, CLOSED) instead of returning after the first message.
16
+
- WebSocket client thread-safety improved by encapsulating pending request state, preventing potential race conditions when multiple threads call send() concurrently.
17
+
- WebSocket client now rejects concurrent send() calls with IllegalStateException instead of silently orphaning the previous request's future.
18
+
- KindFilter and ClassifiedListingEventDeserializer now use Kind.valueOfStrict() for fail-fast deserialization of unknown kind values.
19
+
20
+
### Changed
21
+
- Kind.valueOf(int) now returns null for unknown kind values instead of throwing, allowing graceful handling of custom or future NIP kinds during JSON deserialization.
22
+
- Added Kind.valueOfStrict(int) for callers who need fail-fast behavior on unknown kinds.
23
+
- Added Kind.findByValue(int) returning Optional<Kind> for safe, explicit handling of unknown kinds.
24
+
25
+
## [1.2.0] - 2025-12-26
26
+
27
+
### Fixed
28
+
- NIP-44 encryption now correctly uses HKDF instead of PBKDF2 for key derivation, as required by the specification. This fix enables DM interoperability between Java backend and JavaScript frontend implementations (e.g., nostr-tools).
29
+
30
+
### Changed
31
+
- Switched integration tests to use strfry relay for improved robustness.
32
+
33
+
### Removed
34
+
- Removed AGENTS.md and CLAUDE.md documentation files from the repository.
0 commit comments